ethermess/ethertype-dump.c

86 lines
2.2 KiB
C
Raw Normal View History

2019-07-03 19:20:25 +00:00
#include <arpa/inet.h>
#include <err.h>
#include <errno.h>
#include <linux/if_packet.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
int main(void) {
// Create a packet socket
errno = 0;
int packet_socket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (packet_socket == -1) {
err(1, "socket");
}
// Find the index of the network interface
struct ifreq ifr;
strncpy(ifr.ifr_name, "wlan0", IFNAMSIZ);
errno = 0;
if (ioctl(packet_socket, SIOCGIFINDEX, &ifr) == -1) {
err(1, "ioctl");
}
// Bind to the network interface
struct sockaddr_ll sll;
sll.sll_family = AF_PACKET;
sll.sll_protocol = htons(ETH_P_ALL);
sll.sll_ifindex = ifr.ifr_ifindex;
errno = 0;
if (bind(packet_socket, (const struct sockaddr*)&sll, sizeof(sll)) == -1) {
err(1, "bind");
}
for(;;) {
unsigned char frame[1522]; // 1522 is the largest a 802.3 frame can be
2019-07-03 19:20:25 +00:00
errno = 0;
ssize_t frame_length = recv(packet_socket, frame, sizeof(frame), MSG_TRUNC);
if (frame_length == -1) {
err(1, "recv");
}
// 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;
if (ethertype <= 1500) {
ethertype_meaning = "packet length";
} else if (ethertype < 0x0600) {
ethertype_meaning = "undefined";
} else if (ethertype == 0x0800) {
ethertype_meaning = "IPv4";
} else if (ethertype == 0x0806) {
ethertype_meaning = "ARP";
} else if (ethertype == 0x86dd) {
ethertype_meaning = "IPv6";
}
2019-07-03 19:20:25 +00:00
errno = 0;
if (ethertype_meaning == NULL) {
if (printf("ethertype: %02x%02x, length: %zd\n", ethertype >> 8, ethertype & 0xff, 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) {
err(1, "printf");
}
2019-07-03 19:20:25 +00:00
}
}
return 0;
}