#include #include #include #define log_error(...) fprintf(stderr, __VA_ARGS__) #define log_info(...) fprintf(stdout, __VA_ARGS__) #define FALSE (0==1) #define TRUE (1==1) typedef struct arp_joke { char *ifi; } arp_joke_t; typedef struct arphdr { u_int16_t htype; /* Hardware Type */ u_int16_t ptype; /* Protocol Type */ u_char hlen; /* Hardware Address Length */ u_char plen; /* Protocol Address Length */ u_int16_t oper; /* Operation Code */ u_char sha[6]; /* Sender hardware address */ u_char spa[4]; /* Sender IP address */ u_char tha[6]; /* Target hardware address */ u_char tpa[4]; /* Target IP address */ } arphdr_t; int response_arp(char *device, struct libnet_ethernet_hdr *eth_hdr, arphdr_t *arp_hdr, char *errbuf) { libnet_t *net = libnet_init(LIBNET_LINK, device, errbuf); if (net == NULL) { return FALSE; } struct libnet_ether_addr *mac_addr = libnet_get_hwaddr(net); if (memcmp(mac_addr->ether_addr_octet, arp_hdr->tha, 6) || memcmp(mac_addr->ether_addr_octet, arp_hdr->sha, 6)) { return FALSE; } libnet_ptag_t t = libnet_autobuild_arp( ARPOP_REPLY, /* operation type */ (const uint8_t *) mac_addr, /* sender hardware addr */ (uint8_t *) &arp_hdr->tpa, /* sender protocol addr */ eth_hdr->ether_shost, /* target hardware addr */ (uint8_t *) &arp_hdr->spa, /* target protocol addr */ net); /* libnet id */ if (t == -1) { snprintf(errbuf, BUFSIZ, "Can't build ARP header: %s\n", libnet_geterror(net)); libnet_destroy(net); return EXIT_FAILURE; } t = libnet_build_ethernet( arp_hdr->sha, /* ethernet destination */ (const uint8_t *) mac_addr, ETHERTYPE_ARP, /* protocol type */ NULL, 0, net, /* libnet handle */ 0); if (t == -1) { snprintf(errbuf, BUFSIZ, "Can't build ethernet header: %s\n", libnet_geterror(net)); libnet_destroy(net); return EXIT_FAILURE; } int write_size = libnet_write(net); if (write_size == -1) { snprintf(errbuf, BUFSIZ, "Writer error %s", libnet_geterror(net)); libnet_destroy(net); return EXIT_FAILURE; } libnet_destroy(net); return EXIT_SUCCESS; } void on_packet(u_char *arg, const struct pcap_pkthdr *pkthdr, const u_char *packet) { arp_joke_t *arp_joke = (arp_joke_t *) arg; char errbuf[BUFSIZ]; struct libnet_ethernet_hdr *ether_hdr = (struct libnet_ethernet_hdr *) packet; if (ntohs(ether_hdr->ether_type) == ETHERTYPE_ARP) { arphdr_t *arp_hdr = (arphdr_t *) (packet + LIBNET_ETH_H); if (ntohs(arp_hdr->oper) == ARPOP_REQUEST) { log_info("received arp query\n"); //收到ARP response_arp(arp_joke->ifi, ether_hdr, arp_hdr, errbuf); log_info("send response\n"); } return; } } pcap_t *init_pcap(const char *dev, const char *filter_exp, char *errbuf) { bpf_u_int32 netp; bpf_u_int32 maskp; if (pcap_lookupnet(dev, &netp, &maskp, errbuf) == -1) { snprintf(errbuf, BUFSIZ, "lookup %s failed", dev); return NULL; } pcap_t *pcap = pcap_open_live(dev, 1500, 1, 0, errbuf); if (pcap == NULL) { return NULL; } if (filter_exp != NULL) { struct bpf_program fp; if (pcap_compile(pcap, &fp, filter_exp, 1, netp) == -1) { snprintf(errbuf, BUFSIZ, "Compile filter expression failed %s cause: %s", filter_exp, pcap_geterr(pcap)); pcap_close(pcap); return NULL; } if (pcap_setfilter(pcap, &fp) == -1) { snprintf(errbuf, BUFSIZ, "Install filter failed %s", pcap_geterr(pcap)); pcap_close(pcap); return NULL; } } return pcap; } pcap_t *pcap = NULL; arp_joke_t *arp_joke = NULL; void on_exit(int sig) { if (arp_joke != NULL) { free(arp_joke); } if (pcap != NULL) { pcap_close(pcap); } } int main(int argc, char **argv) { if (argc != 2) { printf("usage arp_joke \n"); return EXIT_FAILURE; } char errbuf[BUFSIZ]; pcap = init_pcap(argv[1], NULL, errbuf); if (pcap == NULL) { log_error("init pcap failed %s\n", errbuf); return EXIT_FAILURE; } //获取mac地址 log_info("Start Success\n"); arp_joke = (arp_joke_t *) malloc(sizeof(arp_joke_t)); arp_joke->ifi = argv[1]; signal(SIGINT, on_exit); pcap_loop(pcap, -1, on_packet, (u_char *) arp_joke); return 0; }