DF-2253 / arp_inject.c
/* * arp_inject.c -- DF-2253 end-to-end: inject an ARP frame with an unknown * hardware address format (ar_hrd = 0x1234) into the kernel receive path * via tap(4), exactly as a LAN peer could. Stock kernel is expected to log * * arp: unknown hardware address format (0x1) <- buggy: 1 digit * * (full 2-byte hrd = 0x1234 should print 0x1234). Root, guest-only rig. */ #include <sys/types.h> #include <sys/fcntl.h> #include <sys/uio.h> #include <stdio.h> #include <string.h> #include <unistd.h> int main(void) { unsigned char frame[14 + 28]; /* eth hdr + minimal arp */ unsigned char *p; int fd; ssize_t n; memset(frame, 0, sizeof(frame)); /* dst = broadcast */ frame[0] = frame[1] = frame[2] = 0xff; frame[3] = frame[4] = frame[5] = 0xff; /* src = 02:03:04:05:06:07 */ frame[6] = 0x02; frame[7] = 0x03; frame[8] = 0x04; frame[9] = 0x05; frame[10] = 0x06; frame[11] = 0x07; /* ethertype = ARP */ frame[12] = 0x08; frame[13] = 0x06; p = frame + 14; p[0] = 0x12; p[1] = 0x34; /* ar_hrd = 0x1234 (unknown format) */ p[2] = 0x08; p[3] = 0x00; /* ar_pro = ETHERTYPE_IP */ p[4] = 6; p[5] = 4; /* ar_hln, ar_pln */ p[6] = 0; p[7] = 1; /* ar_op = ARPOP_REQUEST */ /* sha = 02:03:04:05:06:07 */ p[8] = 0x02; p[9] = 0x03; p[10] = 0x04; p[11] = 0x05; p[12] = 0x06; p[13] = 0x07; /* spa = 10.66.66.66 */ p[14] = 10; p[15] = 66; p[16] = 66; p[17] = 66; /* tha, tpa left zero */ fd = open("/dev/tap0", O_RDWR); if (fd < 0) { perror("open /dev/tap0"); return (1); } n = write(fd, frame, sizeof(frame)); printf("arp_inject: wrote %zd bytes to /dev/tap0 (ar_hrd=0x1234)\n", n); close(fd); return (n == (ssize_t)sizeof(frame) ? 0 : 1); } |