diff --git a/ethertype-dump.c b/ethertype-dump.c index eb97788..4e9b528 100644 --- a/ethertype-dump.c +++ b/ethertype-dump.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -12,6 +13,21 @@ #include #include +char hexify(int nybble) { + assert(0 <= nybble && nybble <= 16); + return "0123456789abcdef"[nybble]; +} + +void format_mac(const unsigned char binary_address[6], char formatted[18]) { + for (size_t i = 0; i < 6; i++) { + unsigned char byte = binary_address[i]; + formatted[3*i] = hexify(byte >> 4); + formatted[3*i + 1] = hexify(byte & 0xf); + formatted[3*i + 2] = ':'; + } + formatted[17] = '\0'; +} + int main(void) { // Create a packet socket errno = 0; @@ -47,13 +63,25 @@ int main(void) { err(1, "recv"); } + if (frame_length < 64) { + errno = 0; + if (printf("Runt frame (%zdB)\n", frame_length) == -1) { + err(1, "printf"); + } + continue; + } + + // Extract the MACs + // 012345 012345 + // dest source + char destination_mac[18], source_mac[18]; + format_mac(&frame[0], destination_mac); + format_mac(&frame[6], source_mac); + // Extract EtherType / length field // 012345 012345 01 // dest source ^^ // It is stored in the network byte order, that is, high byte 1st - if (frame_length < 14) { - errx(1, "Very weird frame of only %zdB???", frame_length); - } uint16_t ethertype = (frame[12] << 8) | frame[13]; const char *ethertype_meaning = NULL; @@ -69,13 +97,18 @@ int main(void) { ethertype_meaning = "IPv6"; } + errno = 0; + if(printf("%s -> %s ethertype: %02x%02x", source_mac, destination_mac, ethertype >> 8, ethertype & 0xff) == -1) { + err(1, "printf"); + } + errno = 0; if (ethertype_meaning == NULL) { - if (printf("ethertype: %02x%02x, length: %zd\n", ethertype >> 8, ethertype & 0xff, frame_length) == -1) { + if (printf(", length: %zd\n", frame_length) == -1) { err(1, "printf"); } } else { - if (printf("ethertype: %02x%02x (%s), length: %zd\n", ethertype >> 8, ethertype & 0xff, ethertype_meaning, frame_length) == -1) { + if (printf("(%s), length: %zd\n", ethertype_meaning, frame_length) == -1) { err(1, "printf"); } }