summaryrefslogtreecommitdiff
path: root/src/user/app/ethdump/ether.c
diff options
context:
space:
mode:
authordzwdz2022-08-17 21:26:29 +0200
committerdzwdz2022-08-17 21:26:29 +0200
commit6ffb06af70faa5657f2c6091fe23500007e2bd44 (patch)
tree8228cdda29cda0c44ff6a09d5a76314fa9760ce9 /src/user/app/ethdump/ether.c
parent5abcc66cb6e83f02b5218802d3eca74c0d29bebf (diff)
user/ethdump: file per protocol, ethernet frame functions
Diffstat (limited to 'src/user/app/ethdump/ether.c')
-rw-r--r--src/user/app/ethdump/ether.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/user/app/ethdump/ether.c b/src/user/app/ethdump/ether.c
new file mode 100644
index 0000000..da21b49
--- /dev/null
+++ b/src/user/app/ethdump/ether.c
@@ -0,0 +1,62 @@
+#include <camellia/syscalls.h>
+#include <stdlib.h>
+#include <string.h>
+#include "proto.h"
+#include "util.h"
+
+enum {
+ DstMAC = 0,
+ SrcMAC = 6,
+ EtherType = 12,
+ Payload = 14,
+};
+
+void ether_parse(const uint8_t *buf, size_t len) {
+ uint8_t dmac[6], smac[6];
+
+ if (len < 60) return;
+ for (int i = 0; i < 6; i++) dmac[i] = buf[i + DstMAC];
+ for (int i = 0; i < 6; i++) smac[i] = buf[i + SrcMAC];
+ printf("from %02x:%02x:%02x:%02x:%02x:%02x\n",
+ smac[0], smac[1], smac[2], smac[3], smac[4], smac[5]);
+ printf("to %02x:%02x:%02x:%02x:%02x:%02x\n",
+ dmac[0], dmac[1], dmac[2], dmac[3], dmac[4], dmac[5]);
+
+ uint16_t ethertype = nget16(buf + EtherType);
+ printf("ethertype %u\n", ethertype);
+ switch (ethertype) {
+ case ET_IPv4:
+ ipv4_parse(buf + Payload, len - Payload);
+ break;
+ case ET_ARP:
+ arp_parse(buf + Payload, len - Payload);
+ break;
+ default:
+ printf("(unknown)\n");
+ 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;
+ printf("sending:\n");
+ hexdump(buf + fhoff, len);
+ _syscall_write(state.raw_h, buf + fhoff, len, 0, 0);
+ free(buf);
+}