#include #include #include #include #include #include #include #include #include #include #include #include #include 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(;;) { char frame[1522]; // 1522 is the largest a 802.3 frame can be 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_length = (frame[12] << 8) | frame[13]; errno = 0; if(printf("ethertype: %02x%02x, length: %zd\n", ethertype_length >> 8, ethertype_length & 0xff, frame_length) == -1) { err(1, "printf"); } } return 0; }