#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define BPF_PATH "/dev/bpf" static void send_arp(int fd) { char buf[128]; struct ether_header *eh; struct arphdr *ah; struct in_addr sip, tip; int len, ret; memset(buf, 0, sizeof(buf)); eh = (struct ether_header *)buf; ah = (struct arphdr *)(eh + 1); eh->ether_type = htons(ETHERTYPE_ARP); memcpy(eh->ether_shost, ether_aton("00:01:00:02:00:03"), sizeof(eh->ether_shost)); memcpy(eh->ether_dhost, ether_aton("00:02:00:04:00:04"), sizeof(eh->ether_dhost)); inet_pton(AF_INET, "1.2.3.4", &sip); inet_pton(AF_INET, "2.3.4.5", &tip); ah->ar_hrd = ARPHRD_ETHER; ah->ar_pro = htons(ETHERTYPE_IP); ah->ar_hln = 6; ah->ar_pln = sizeof(struct in_addr); ah->ar_op = htons(ARPOP_REQUEST); bcopy(eh->ether_shost, ar_sha(ah), ah->ar_hln); bcopy(&sip, ar_spa(ah), ah->ar_pln); bcopy(&tip, ar_tpa(ah), ah->ar_pln); len = sizeof(*eh) + sizeof(*ah) + 2 * sizeof(struct in_addr) + 2 * 6; if ((ret = write(fd, buf, len)) != len) warn("write() error"); } int main(int ac, char **av) { int fd; struct ifreq ifr; u_int val; if (ac < 2) errx(EX_USAGE, "usage: %s iface [hdrcmplt]", av[0]); if ((fd = open(BPF_PATH, O_RDWR)) == -1) err(EX_OSFILE, "failed to open %s\n", BPF_PATH); memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, av[1], sizeof(ifr.ifr_name)); if (ioctl(fd, BIOCSETIF, &ifr) != 0) err(EX_DATAERR, "failed to bind to interface %s", av[1]); if (ac > 2) { val = 1; if (ioctl(fd, BIOCSHDRCMPLT, &val) != 0) err(EX_OSERR, "failed to set BIOCSHDRCMPLT"); } send_arp(fd); return (0); }