diff options
author | dzwdz | 2022-08-17 21:26:29 +0200 |
---|---|---|
committer | dzwdz | 2022-08-17 21:26:29 +0200 |
commit | 6ffb06af70faa5657f2c6091fe23500007e2bd44 (patch) | |
tree | 8228cdda29cda0c44ff6a09d5a76314fa9760ce9 /src/user/app/ethdump/ether.c | |
parent | 5abcc66cb6e83f02b5218802d3eca74c0d29bebf (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.c | 62 |
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); +} |