summaryrefslogtreecommitdiff
path: root/src/user/app/ethdump
diff options
context:
space:
mode:
Diffstat (limited to 'src/user/app/ethdump')
-rw-r--r--src/user/app/ethdump/arp.c48
-rw-r--r--src/user/app/ethdump/ethdump.c41
-rw-r--r--src/user/app/ethdump/ether.c59
-rw-r--r--src/user/app/ethdump/fs.c154
-rw-r--r--src/user/app/ethdump/icmp.c34
-rw-r--r--src/user/app/ethdump/ipv4.c215
-rw-r--r--src/user/app/ethdump/proto.h70
-rw-r--r--src/user/app/ethdump/udp.c98
-rw-r--r--src/user/app/ethdump/util.c31
-rw-r--r--src/user/app/ethdump/util.h38
10 files changed, 0 insertions, 788 deletions
diff --git a/src/user/app/ethdump/arp.c b/src/user/app/ethdump/arp.c
deleted file mode 100644
index cfb1e04..0000000
--- a/src/user/app/ethdump/arp.c
+++ /dev/null
@@ -1,48 +0,0 @@
-#include "proto.h"
-#include "util.h"
-#include <string.h>
-
-enum {
- HdrType = 0,
- HdrTypeEther = 1,
- ProtoType = 2,
- HdrALen = 4,
- ProtoALen = 5,
- Operation = 6,
- OpReq = 1,
- OpReply = 2,
-};
-
-void arp_parse(const uint8_t *buf, size_t len) {
- // TODO no bound checks
- uint16_t htype = nget16(buf + HdrType);
- uint16_t ptype = nget16(buf + ProtoType);
- uint16_t op = nget16(buf + Operation);
-
- if (!(htype == HdrTypeEther && ptype == ET_IPv4)) return;
- enum { /* only valid for this combination of header + proto */
- SrcMAC = 8,
- SrcIP = 14,
- DstMAC = 18,
- DstIP = 24,
- };
-
- if (op == OpReq) {
- uint32_t daddr = nget32(buf + DstIP);
- if (daddr == state.ip) {
- uint8_t *pkt = ether_start(30, (struct ethernet){
- .dst = buf + SrcMAC,
- .type = ET_ARP,
- });
- nput16(pkt + HdrType, 1);
- nput16(pkt + ProtoType, ET_IPv4);
- pkt[HdrALen] = 6;
- pkt[ProtoALen] = 4;
- nput16(pkt + Operation, OpReply);
- memcpy(pkt + SrcMAC, state.mac, 6);
- nput32(pkt + SrcIP, state.ip);
- memcpy(pkt + DstMAC, buf + SrcMAC, 10); /* sender's MAC and IP */
- ether_finish(pkt);
- }
- }
-}
diff --git a/src/user/app/ethdump/ethdump.c b/src/user/app/ethdump/ethdump.c
deleted file mode 100644
index 17592a1..0000000
--- a/src/user/app/ethdump/ethdump.c
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "proto.h"
-#include "util.h"
-#include <camellia/syscalls.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <user/lib/thread.h>
-
-struct net_state state = {
- // TODO dynamically get mac
- .mac = {0x52, 0x54, 0x00, 0xCA, 0x77, 0x1A},
- .ip = (192 << 24) + (168 << 16) + 11,
-};
-
-void network_thread(void *arg) { (void)arg;
- const size_t buflen = 4096;
- char *buf = malloc(buflen);
- for (;;) {
- long ret = _syscall_read(state.raw_h, buf, buflen, -1);
- if (ret < 0) break;
- ether_parse((void*)buf, ret);
- }
- free(buf);
-}
-
-void fs_thread(void *arg);
-
-int main(void) {
- const char *path = "/kdev/eth";
- state.raw_h = _syscall_open(path, strlen(path), 0);
- if (state.raw_h < 0) {
- eprintf("couldn't open %s", path);
- return 1;
- }
-
- thread_create(0, network_thread, NULL);
- thread_create(0, fs_thread, NULL);
- _syscall_await();
- return 0;
-}
diff --git a/src/user/app/ethdump/ether.c b/src/user/app/ethdump/ether.c
deleted file mode 100644
index 5893632..0000000
--- a/src/user/app/ethdump/ether.c
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <camellia/syscalls.h>
-#include "proto.h"
-#include "util.h"
-
-enum {
- DstMAC = 0,
- SrcMAC = 6,
- EtherType = 12,
- Payload = 14,
-};
-struct ethq *ether_queue;
-
-void ether_parse(const uint8_t *buf, size_t len) {
- struct ethernet ether = (struct ethernet){
- .src = buf + SrcMAC,
- .dst = buf + DstMAC,
- .type = nget16(buf + EtherType),
- };
-
- for (struct ethq **iter = &ether_queue; iter && *iter; ) {
- struct ethq *qe = *iter;
- _syscall_fs_respond(qe->h, buf, len, 0);
- /* remove entry */
- /* yes, doing it this way here doesn't make sense. i'm preparing for filtering */
- *iter = qe->next;
- free(qe);
- }
-
- switch (ether.type) {
- case ET_IPv4:
- ipv4_parse(buf + Payload, len - Payload, ether);
- break;
- case ET_ARP:
- arp_parse(buf + Payload, len - Payload);
- break;
- }
-}
-
-static const size_t fhoff = sizeof(size_t);
-uint8_t *ether_start(size_t len, struct ethernet ether) {
- if (len < 60 - Payload) len = 60 - Payload;
-
- if (!ether.dst) eprintf("NULL ether.dst!"); // TODO arp? i guess?
- if (!ether.src) ether.src = &state.mac;
-
- uint8_t *buf = malloc(fhoff + Payload + len);
- memset(buf, 0, fhoff + Payload + len);
- *(size_t*)buf = len + Payload;
- memcpy(buf + fhoff + DstMAC, ether.dst, 6);
- memcpy(buf + fhoff + SrcMAC, ether.src, 6);
- nput16(buf + fhoff + EtherType, ether.type);
- return buf + fhoff + Payload;
-}
-void ether_finish(uint8_t *pkt) {
- uint8_t *buf = pkt - Payload - fhoff;
- size_t len = *(size_t*)buf;
- _syscall_write(state.raw_h, buf + fhoff, len, 0, 0);
- free(buf);
-}
diff --git a/src/user/app/ethdump/fs.c b/src/user/app/ethdump/fs.c
deleted file mode 100644
index b8c2f7b..0000000
--- a/src/user/app/ethdump/fs.c
+++ /dev/null
@@ -1,154 +0,0 @@
-#include "proto.h"
-#include <camellia/syscalls.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <user/lib/fs/dir.h>
-
-enum handle_type {
- H_ROOT,
- H_ETHER,
- H_UDP,
-};
-
-struct strqueue {
- struct strqueue *next;
- size_t len;
- char buf[];
-};
-
-struct handle {
- enum handle_type type;
- struct {
- struct udp_conn *c;
- struct strqueue *rx, *rxlast;
- } udp;
- handle_t reqh;
-};
-
-
-static void udp_listen_callback(struct udp_conn *c, void *arg) {
- struct handle *h = arg;
- h->udp.c = c;
- h->udp.rx = NULL;
- h->udp.rxlast = NULL;
- _syscall_fs_respond(h->reqh, h, 0, 0);
- h->reqh = -1;
-}
-
-static void udp_recv_callback(const void *buf, size_t len, void *arg) {
- struct handle *h = arg;
- if (h->reqh >= 0) {
- _syscall_fs_respond(h->reqh, buf, len, 0);
- h->reqh = -1;
- return;
- }
- // TODO don't malloc on the network thread, dumbass
- struct strqueue *sq = malloc(sizeof(*sq) + len);
- sq->next = NULL;
- sq->len = len;
- memcpy(sq->buf, buf, len);
- if (h->udp.rx) {
- h->udp.rxlast->next = sq;
- h->udp.rxlast = sq;
- } else {
- h->udp.rx = sq;
- h->udp.rxlast = sq;
- }
-}
-
-static void udp_recv_enqueue(struct handle *h, handle_t reqh) {
- if (h->reqh > 0) {
- // TODO queue
- _syscall_fs_respond(reqh, NULL, -1, 0);
- } else if (h->udp.rx) {
- _syscall_fs_respond(reqh, h->udp.rx->buf, h->udp.rx->len, 0);
- h->udp.rx = h->udp.rx->next;
- free(h->udp.rx);
- } else {
- h->reqh = reqh;
- }
-}
-
-void fs_thread(void *arg) { (void)arg;
- const size_t buflen = 4096;
- char *buf = malloc(buflen);
- for (;;) {
- struct fs_wait_response res;
- handle_t reqh = _syscall_fs_wait(buf, buflen, &res);
- if (reqh < 0) break;
- struct handle *h = res.id;
- long ret;
- switch (res.op) {
- case VFSOP_OPEN:
- if (res.len == 1 && !memcmp("/", buf, 1)) {
- h = malloc(sizeof *h);
- h->type = H_ROOT;
- _syscall_fs_respond(reqh, h, 0, 0);
- } else if (res.len == 4 && !memcmp("/raw", buf, 4)) {
- h = malloc(sizeof *h);
- h->type = H_ETHER;
- _syscall_fs_respond(reqh, h, 0, 0);
- } else if (res.len > 6 && !memcmp("/udpl/", buf, 6)) {
- uint16_t port = strtol(buf + 6, NULL, 0);
- h = malloc(sizeof *h);
- h->type = H_UDP;
- h->udp.c = NULL;
- h->reqh = reqh;
- udp_listen(port, udp_listen_callback, udp_recv_callback, h);
- } else {
- _syscall_fs_respond(reqh, NULL, -1, 0);
- }
- break;
- case VFSOP_READ:
- switch (h->type) {
- case H_ROOT: {
- struct dirbuild db;
- dir_start(&db, res.offset, buf, sizeof buf);
- dir_append(&db, "raw");
- dir_append(&db, "udpl/");
- _syscall_fs_respond(reqh, buf, dir_finish(&db), 0);
- break;}
- case H_ETHER: {
- struct ethq *qe;
- qe = malloc(sizeof *qe);
- qe->h = reqh;
- qe->next = ether_queue;
- ether_queue = qe;
- break;}
- case H_UDP:
- udp_recv_enqueue(h, reqh);
- break;
- default:
- _syscall_fs_respond(reqh, NULL, -1, 0);
- }
- break;
- case VFSOP_WRITE:
- switch (h->type) {
- case H_ETHER:
- ret = _syscall_write(state.raw_h, buf, res.len, 0, 0);
- _syscall_fs_respond(reqh, NULL, ret, 0);
- break;
- case H_UDP:
- udpc_send(h->udp.c, buf, res.len);
- _syscall_fs_respond(reqh, NULL, res.len, 0);
- break;
- default:
- _syscall_fs_respond(reqh, NULL, -1, 0);
- }
- break;
- case VFSOP_CLOSE:
- // TODO remove entries in queue
- // TODO why does close even have _syscall_fs_respond?
- if (h->type == H_UDP)
- udpc_close(h->udp.c);
- free(h);
- _syscall_fs_respond(reqh, NULL, -1, 0);
- break;
- default:
- _syscall_fs_respond(reqh, NULL, -1, 0);
- break;
- }
- }
- free(buf);
-}
diff --git a/src/user/app/ethdump/icmp.c b/src/user/app/ethdump/icmp.c
deleted file mode 100644
index 0c6a502..0000000
--- a/src/user/app/ethdump/icmp.c
+++ /dev/null
@@ -1,34 +0,0 @@
-#include "proto.h"
-#include "util.h"
-
-enum {
- Type = 0,
- Code = 1,
- Checksum = 2,
- Payload = 4,
-};
-
-void icmp_parse(const uint8_t *buf, size_t len, struct ipv4 ip) {
- if (len < Payload) return;
- uint8_t type = buf[Type];
- if (type == 8 && ip.dst == state.ip) {
- /* echo reply */
- icmp_send(buf + Payload, len - Payload, (struct icmp){
- .type = 0,
- .ip.dst = ip.src,
- .ip.e.dst = ip.e.src,
- });
- }
-}
-
-void icmp_send(const void *payload, size_t len, struct icmp i) {
- i.ip.proto = 1;
- uint8_t *pkt = malloc(Payload + len);
- pkt[Type] = i.type;
- pkt[Code] = i.code;
- memcpy(pkt + Payload, payload, len);
- nput16(pkt + Checksum, 0);
- nput16(pkt + Checksum, ip_checksum(pkt, Payload + len));
- ipv4_send(pkt, Payload + len, i.ip);
- free(pkt);
-}
diff --git a/src/user/app/ethdump/ipv4.c b/src/user/app/ethdump/ipv4.c
deleted file mode 100644
index 3243d3c..0000000
--- a/src/user/app/ethdump/ipv4.c
+++ /dev/null
@@ -1,215 +0,0 @@
-#include "proto.h"
-#include "util.h"
-#include <assert.h>
-#include <stdlib.h>
-
-enum {
- Version = 0,
- HdrLen = 0,
- TotalLen = 2,
- Id = 4,
- FragInfo = 6,
- EvilBit = 0x8000,
- DontFrag = 0x4000,
- MoreFrags = 0x2000,
- FragOff = 0x1FFF,
- TTL = 8,
- Proto = 9,
- Checksum = 10,
- SrcIP = 12,
- DstIP = 16,
-};
-static void ipv4_dispatch(const uint8_t *buf, size_t len, struct ipv4 ip);
-
-struct fragment {
- struct fragment *next; /* sorted */
- size_t len, offset;
- bool last;
- uint8_t buf[];
-};
-struct fragmented {
- /* src, dst, proto, id come from the first arrived packet
- * and are used to tell fragmenteds apart.
- * the rest comes from the sequentially first packet.
- * ip.h.header points to a malloc'd buffer*/
- struct ipv4 h;
-
- struct fragment *first;
- struct fragmented *next, **prev; /* *(inc->prev) == inc */
- // TODO timer
-};
-struct fragmented *fragmenteds;
-static struct fragmented *fragmented_find(struct ipv4 fraghdr);
-static void fragmented_tryinsert(const uint8_t *payload, size_t plen, struct ipv4 ip);
-static void fragmented_tryfinish(struct fragmented *inc);
-static void fragmented_free(struct fragmented *inc);
-
-static struct fragmented *fragmented_find(struct ipv4 fraghdr) {
- struct fragmented *inc;
- for (inc = fragmenteds; inc; inc = inc->next) {
- if (inc->h.src == fraghdr.src &&
- inc->h.dst == fraghdr.dst &&
- inc->h.proto == fraghdr.proto &&
- inc->h.id == fraghdr.id)
- {
- return inc;
- }
- }
- inc = malloc(sizeof *inc);
- memset(inc, 0, sizeof *inc);
- inc->h.src = fraghdr.src;
- inc->h.dst = fraghdr.dst;
- inc->h.proto = fraghdr.proto;
- inc->h.id = fraghdr.id;
-
- inc->next = fragmenteds;
- if (inc->next) inc->next->prev = &inc->next;
- inc->prev = &fragmenteds;
- *inc->prev = inc;
- return inc;
-}
-
-static void fragmented_tryinsert(const uint8_t *payload, size_t plen, struct ipv4 ip) {
- struct fragmented *inc = fragmented_find(ip);
- size_t off = (ip.fraginfo & FragOff) * 8;
- bool last = !(ip.fraginfo & MoreFrags);
- // eprintf("fragmented packet, %u + %u, part of 0x%x", off, plen, inc);
-
- /* find the first fragment at a bigger offset, and insert before it */
- struct fragment **insert = &inc->first;
- for (; *insert; insert = &(*insert)->next) {
- if ((*insert)->offset > off) break;
- if ((*insert)->offset == off) return; /* duplicate packet */
- }
- /* later on: frag->next = *insert;
- * if we're the last fragment, frag->next must == NULL */
- if (last && *insert != NULL) return;
-
- struct fragment *frag = malloc(sizeof(struct fragment) + plen);
- frag->next = *insert;
- *insert = frag;
- frag->len = plen;
- frag->offset = off;
- frag->last = last;
- memcpy(frag->buf, payload, plen);
-
- if (off == 0) { /* save header */
- assert(!inc->h.header);
- void *headercpy = malloc(ip.hlen);
- memcpy(headercpy, ip.header, ip.hlen);
- inc->h = ip;
- inc->h.header = headercpy;
- }
-
- fragmented_tryfinish(inc);
-}
-
-static void fragmented_tryfinish(struct fragmented *inc) {
- if (inc->first->offset != 0) return;
- for (struct fragment *iter = inc->first; iter; iter = iter->next) {
- size_t iterend = iter->offset + iter->len;
- struct fragment *next = iter->next;
- if (next) {
- if (iterend < next->offset) return; /* incomplete */
- if (iterend > next->offset) {
- fragmented_free(inc);
- return;
- }
- } else if (iter->last) {
- void *buf = malloc(iterend);
- for (struct fragment *iter = inc->first; iter; iter = iter->next) {
- assert(iter->offset + iter->len <= iterend);
- memcpy(buf + iter->offset, iter->buf, iter->len);
- }
- ipv4_dispatch(buf, iterend, inc->h);
- free(buf);
- fragmented_free(inc);
- }
- }
-}
-
-static void fragmented_free(struct fragmented *inc) {
- if (inc->next) {
- inc->next->prev = inc->prev;
- *inc->next->prev = inc->next;
- } else {
- *inc->prev = NULL;
- }
-
- for (struct fragment *next, *iter = inc->first; iter; iter = next) {
- next = iter->next;
- free(iter);
- }
- free((void*)inc->h.header);
- free(inc);
-}
-
-
-static void ipv4_dispatch(const uint8_t *buf, size_t len, struct ipv4 ip) {
- switch (ip.proto) {
- case 0x01: icmp_parse(buf, len, ip); break;
- case 0x11: udp_parse(buf, len, ip); break;
- }
-}
-
-void ipv4_parse(const uint8_t *buf, size_t len, struct ethernet ether) {
- uint8_t version, headerlen;
- uint16_t totallen;
-
- version = buf[Version] >> 4;
- if (version != 4) return;
- headerlen = (buf[HdrLen] & 0xf) * 4;
- totallen = nget16(buf + TotalLen);
- if (totallen < headerlen) return;
-
- /* ignores checksum. TODO? */
-
- struct ipv4 ip = (struct ipv4){
- .e = ether,
- .src = nget32(buf + SrcIP),
- .dst = nget32(buf + DstIP),
- .id = nget16(buf + Id),
- .fraginfo = nget16(buf + FragInfo),
- .proto = buf[Proto],
- .header = buf,
- .hlen = headerlen,
- };
-
- if (ip.fraginfo & ~(EvilBit | DontFrag)) {
- fragmented_tryinsert(buf + headerlen, totallen - headerlen, ip);
- } else {
- if (totallen > len) return;
- ipv4_dispatch(buf + headerlen, totallen - headerlen, ip);
- }
-}
-
-static uint16_t next_id = 0;
-void ipv4_send(const void *payload, size_t len, struct ipv4 ip) {
- const size_t mtu = 1500;
- const size_t hdrlen = 20;
-
- ip.e.type = ET_IPv4;
- if (!ip.src) ip.src = state.ip;
- if (!ip.e.dst && ip.dst == 0xFFFFFFFF)
- ip.e.dst = &MAC_BROADCAST;
-
- uint16_t id = next_id++;
- for (size_t off = 0, fraglen = mtu - hdrlen; off < len; off += fraglen) {
- if (fraglen > len - off)
- fraglen = len - off;
- bool last = off + fraglen >= len;
- uint8_t *pkt = ether_start(hdrlen + fraglen, ip.e);
- pkt[Version] = 0x40;
- pkt[HdrLen] |= hdrlen / 4;
- nput16(pkt + TotalLen, hdrlen + fraglen);
- nput16(pkt + Id, id);
- nput16(pkt + FragInfo, (off >> 3) | (last ? 0 : MoreFrags));
- pkt[TTL] = 0xFF;
- pkt[Proto] = ip.proto;
- nput32(pkt + SrcIP, ip.src);
- nput32(pkt + DstIP, ip.dst);
- nput16(pkt + Checksum, ip_checksum(pkt, hdrlen));
- memcpy(pkt + hdrlen, payload + off, fraglen);
- ether_finish(pkt);
- }
-}
diff --git a/src/user/app/ethdump/proto.h b/src/user/app/ethdump/proto.h
deleted file mode 100644
index 106f286..0000000
--- a/src/user/app/ethdump/proto.h
+++ /dev/null
@@ -1,70 +0,0 @@
-#pragma once
-#include <camellia/types.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-typedef uint8_t mac_t[6];
-static const mac_t MAC_BROADCAST = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
-
-extern struct net_state {
- mac_t mac;
- uint32_t ip;
-
- handle_t raw_h;
-} state;
-
-enum { /* ethertype */
- ET_IPv4 = 0x800,
- ET_ARP = 0x806,
-};
-
-struct ethernet {
- const mac_t *src, *dst;
- uint16_t type;
-};
-
-struct ipv4 {
- struct ethernet e;
- uint32_t src, dst;
- uint16_t id, fraginfo;
- uint8_t proto;
- const uint8_t *header; size_t hlen;
-};
-
-struct icmp {
- struct ipv4 ip;
- uint8_t type, code;
-};
-
-
-/* NOT THREADSAFE, YET USED FROM CONCURRENT THREADS
- * will break if i implement a scheduler*/
-struct ethq {
- struct ethq *next;
- handle_t h;
-};
-extern struct ethq *ether_queue;
-
-void arp_parse(const uint8_t *buf, size_t len);
-
-void icmp_parse(const uint8_t *buf, size_t len, struct ipv4 ip);
-void icmp_send(const void *payload, size_t len, struct icmp i);
-
-void ipv4_parse(const uint8_t *buf, size_t len, struct ethernet ether);
-void ipv4_send(const void *payload, size_t len, struct ipv4 ip);
-
-void ether_parse(const uint8_t *buf, size_t len);
-uint8_t *ether_start(size_t len, struct ethernet ether);
-void ether_finish(uint8_t *pkt);
-
-struct udp_conn;
-void udp_parse(const uint8_t *buf, size_t len, struct ipv4 ip);
-/* calls callback once, after a client connects. */
-void udp_listen(uint16_t port,
- void (*on_conn)(struct udp_conn *, void *carg),
- void (*on_recv)(const void *, size_t, void *carg),
- void *carg);
-// TODO udp_onclosed
-void udpc_send(struct udp_conn *, const void *buf, size_t len);
-/* frees */
-void udpc_close(struct udp_conn *);
diff --git a/src/user/app/ethdump/udp.c b/src/user/app/ethdump/udp.c
deleted file mode 100644
index 8129a48..0000000
--- a/src/user/app/ethdump/udp.c
+++ /dev/null
@@ -1,98 +0,0 @@
-#include "proto.h"
-#include "util.h"
-
-enum {
- SrcPort = 0,
- DstPort = 2,
- Length = 4,
- Checksum = 6,
- Payload = 8,
-};
-
-
-struct udp_conn {
- uint32_t lip, rip;
- uint16_t lport, rport;
- mac_t rmac;
- void (*on_conn)(struct udp_conn *, void *); /* if non-NULL - listening, if NULL - estabilished */
- void (*on_recv)(const void *, size_t, void *);
- void *carg;
- struct udp_conn *next, **prev;
-};
-struct udp_conn *conns;
-void udp_listen(uint16_t port,
- void (*on_conn)(struct udp_conn *, void *carg),
- void (*on_recv)(const void *, size_t, void *carg),
- void *carg)
-{
- if (!on_conn) return;
- struct udp_conn *c = malloc(sizeof *c);
- c->lport = port;
- c->lip = state.ip;
- c->on_conn = on_conn;
- c->on_recv = on_recv;
- c->carg = carg;
-
- c->next = conns;
- if (c->next) *(c->next->prev) = c;
- c->prev = &conns;
- *c->prev = c;
-}
-void udpc_close(struct udp_conn *c) {
- if (c->next) c->next->prev = c->prev;
- *(c->prev) = c->next;
- free(c);
-}
-void udpc_send(struct udp_conn *c, const void *buf, size_t len) {
- uint8_t *pkt = malloc(Payload + len);
- nput16(pkt + SrcPort, c->lport);
- nput16(pkt + DstPort, c->rport);
- nput16(pkt + Length, Payload + len);
- nput16(pkt + Checksum, 0);
- memcpy(pkt + Payload, buf, len);
- ipv4_send(pkt, Payload + len, (struct ipv4){
- .proto = 0x11,
- .src = c->lip,
- .dst = c->rip,
- .e.dst = c->rmac,
- });
- free(pkt);
-}
-
-
-void udp_parse(const uint8_t *buf, size_t len, struct ipv4 ip) {
- uint16_t srcport = nget16(buf + SrcPort);
- uint16_t dstport = nget16(buf + DstPort);
- bool active = false;
-
- for (struct udp_conn *iter = conns; iter; iter = iter->next) {
- if (iter->on_conn && dstport == iter->lport) {
- iter->on_conn(iter, iter->carg);
- iter->on_conn = NULL;
- iter->rport = srcport;
- memcpy(&iter->rmac, ip.e.src, sizeof(mac_t));
- iter->rip = ip.src;
- }
- if (iter->rip == ip.src
- && iter->rport == srcport
- && iter->lport == dstport
- && iter->on_recv)
- {
- active = true;
- iter->on_recv(buf + Payload, len - Payload, iter->carg);
- }
- }
-
- if (!active) {
- uint8_t *pkt = malloc(4 + ip.hlen + 8);
- nput32(pkt, 0);
- memcpy(pkt + 4, ip.header, ip.hlen + 8);
- icmp_send(pkt, 4 + ip.hlen + 8, (struct icmp){
- .type = 3, /* destination unreachable */
- .code = 3, /* port unreachable */
- .ip.dst = ip.src,
- .ip.e.dst = ip.e.src,
- });
- free(pkt);
- }
-}
diff --git a/src/user/app/ethdump/util.c b/src/user/app/ethdump/util.c
deleted file mode 100644
index 7c484f3..0000000
--- a/src/user/app/ethdump/util.c
+++ /dev/null
@@ -1,31 +0,0 @@
-#include "util.h"
-
-/* https://www.w3.org/TR/PNG/#D-CRCAppendix */
-static uint32_t crc_table[256];
-uint32_t crc32(const uint8_t *buf, size_t len) {
- if (!crc_table[1]) {
- for (int i = 0; i < 256; i++) {
- uint32_t c = i;
- for (int j = 0; j < 8; j++)
- c = ((c&1) ? 0xedb88320 : 0) ^ (c >> 1);
- crc_table[i] = c;
- }
- }
-
- uint32_t c = 0xFFFFFFFF;
- for (size_t i = 0; i < len; i++)
- c = crc_table[(c ^ buf[i]) & 0xff] ^ (c >> 8);
- return ~c;
-}
-
-uint16_t ip_checksum(const uint8_t *buf, size_t len) {
- uint32_t c = 0;
- while (len >= 2) {
- c += nget16(buf);
- buf += 2; len -= 2;
- }
- if (len) c += (*buf) << 8;
- while (c >= 0xFFFF)
- c = (c & 0xFFFF) + (c >> 16);
- return ~c;
-}
diff --git a/src/user/app/ethdump/util.h b/src/user/app/ethdump/util.h
deleted file mode 100644
index bfff6e3..0000000
--- a/src/user/app/ethdump/util.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma once
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define eprintf(fmt, ...) fprintf(stderr, "ethdump: "fmt"\n" __VA_OPT__(,) __VA_ARGS__)
-
-uint32_t crc32(const uint8_t *buf, size_t len);
-uint16_t ip_checksum(const uint8_t *buf, size_t len);
-
-static inline void nput16(void *vbuf, uint16_t n) {
- uint8_t *b = vbuf;
- b[0] = n >> 8;
- b[1] = n >> 0;
-}
-
-static inline void nput32(void *vbuf, uint32_t n) {
- uint8_t *b = vbuf;
- b[0] = n >> 24;
- b[1] = n >> 16;
- b[2] = n >> 8;
- b[3] = n >> 0;
-}
-
-static inline uint16_t nget16(const void *vbuf) {
- const uint8_t *b = vbuf;
- return (b[0] << 8)
- | (b[1] << 0);
-}
-
-static inline uint32_t nget32(const void *vbuf) {
- const uint8_t *b = vbuf;
- return (b[0] << 24)
- | (b[1] << 16)
- | (b[2] << 8)
- | (b[3] << 0);
-}