#include #include #include #include #include #include #include #include #include #include #include void die(char *errstr, ...) { va_list ap; va_start(ap, errstr); vdprintf(2, errstr, ap); va_end(ap); exit(1); } #define NELEMS(x) (sizeof x / sizeof *x) /* tcpdump -dd udp portrange 67-68 or udp portrange 546-547 or icmp6 */ struct sock_filter filter[] = { { 0x28, 0, 0, 0x0000000c }, { 0x15, 0, 17, 0x000086dd }, { 0x30, 0, 0, 0x00000014 }, { 0x15, 0, 11, 0x00000011 }, { 0x28, 0, 0, 0x00000036 }, { 0x35, 0, 1, 0x00000043 }, { 0x25, 0, 30, 0x00000044 }, { 0x28, 0, 0, 0x00000038 }, { 0x35, 0, 1, 0x00000043 }, { 0x25, 0, 27, 0x00000044 }, { 0x28, 0, 0, 0x00000036 }, { 0x35, 0, 1, 0x00000222 }, { 0x25, 0, 24, 0x00000223 }, { 0x28, 0, 0, 0x00000038 }, { 0x35, 21, 23, 0x00000222 }, { 0x15, 21, 0, 0x0000003a }, { 0x15, 0, 21, 0x0000002c }, { 0x30, 0, 0, 0x00000036 }, { 0x15, 18, 19, 0x0000003a }, { 0x15, 0, 18, 0x00000800 }, { 0x30, 0, 0, 0x00000017 }, { 0x15, 0, 16, 0x00000011 }, { 0x28, 0, 0, 0x00000014 }, { 0x45, 14, 0, 0x00001fff }, { 0xb1, 0, 0, 0x0000000e }, { 0x48, 0, 0, 0x0000000e }, { 0x35, 0, 1, 0x00000043 }, { 0x25, 0, 9, 0x00000044 }, { 0x48, 0, 0, 0x00000010 }, { 0x35, 0, 1, 0x00000043 }, { 0x25, 0, 6, 0x00000044 }, { 0x48, 0, 0, 0x0000000e }, { 0x35, 0, 1, 0x00000222 }, { 0x25, 0, 3, 0x00000223 }, { 0x48, 0, 0, 0x00000010 }, { 0x35, 0, 2, 0x00000222 }, { 0x25, 1, 0, 0x00000223 }, { 0x6, 0, 0, 0x00040000 }, { 0x6, 0, 0, 0x00000000 }, }; int main(int argc, char **argv) { int sock; int one = 1; struct msghdr msg; struct sockaddr_ll link; struct packet_mreq mr; struct iovec iov; struct sock_fprog bpf; sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (sock < 0) die("socket: %s\n", strerror(errno)); bpf.len = NELEMS(filter); bpf.filter = filter; if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof bpf) < 0) die("SO_ATTACH_FILTER: %s\n", strerror(errno)); if (setsockopt(sock, SOL_SOCKET, SO_LOCK_FILTER, &one, sizeof one) < 0) die("SO_LOCK_FILTER: %s\n", strerror(errno)); memset(&msg, 0, sizeof msg); iov.iov_base = malloc(1500); iov.iov_len = 1500; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_name = calloc(1, sizeof (struct sockaddr_ll)); msg.msg_namelen = sizeof (struct sockaddr_ll); while(1) { if (recvmsg(sock, &msg, 0) < 0) die("recvmsg: %s\n", strerror(errno)); memmove(&link, msg.msg_name, sizeof link); fprintf(stderr, "link index %d pkttype %d\n", link.sll_ifindex, link.sll_pkttype); if (writev(1, msg.msg_iov, msg.msg_iovlen) < 0) die("writev: %s\n", strerror(errno)); msg.msg_iov = &iov; msg.msg_iovlen = 1; } return 0; }