libnet和pcap模拟ARP 1 #include <libnet.h> 2 #include <pcap.h> 3 #include <sys/types.h> 4 #include <netinet/in.h> 5 #include <unistd.h> 6 #include <stdio.h> 7 #include <string.h> 8 #include <stdlib.h> 9 #include <ctype.h> 10 #include <errno.h> 11 #include <arpa/inet.h> 12 13 /* default snap length (maximum bytes per packet to capture) */ 14 #define SNAP_LEN 1518 15 16 /* ethernet headers are always exactly 14 bytes [1] */ 17 #define SIZE_ETHERNET 14 18 19 /* Ethernet addresses are 6 bytes */ 20 #define ETHER_ADDR_LEN 6 21 22 /* Ethernet header */ 23 struct sniff_ethernet { 24 u_char ether_dhost[ETHER_ADDR_LEN]; /* destination host address */ 25 u_char ether_shost[ETHER_ADDR_LEN]; /* source host address */ 26 u_short ether_type; /* IP? ARP? RARP? etc */ 27 }; 28 29 /* ARP header */ 30 struct sniff_arp { 31 u_short ar_hrd; /* format of hardware address */ 32 u_short ar_pro; /* format of protocol address */ 33 u_char ar_hln; /* length of hardware address */ 34 u_char ar_pln; /* length of protocol address */ 35 u_short ar_op; /* ARP opcode */ 36 u_char ar_sha[6]; /* sender hardware address */ 37 u_char ar_sip[4]; /* sender IP address */ 38 u_char ar_tha[6]; /* target hardware address */ 39 u_char ar_tip[4]; /* target IP address */ 40 41 }; 42 43 void /* the next three function from http://www.tcpdump.org/pcap.htm 3x */ 44 got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet); 45 46 void 47 print_payload(const u_char *payload, int len); 48 49 void 50 print_hex_ascii_line(const u_char *payload, int len, int offset); 51 52 /* 53 * dissect/print packet 54 */ 55 void 56 got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) 57 { 58 59 static int count = 1; /* packet counter */ 60 61 /* declare pointers to packet headers */ 62 const struct sniff_ethernet *ethernet; /* The ethernet header [1] */ 63 const struct sniff_arp *arp; /* The ARP packet */ 64 65 printf("/nPacket number %d:/n", count); 66 count++; 67 68 /* define ethernet header */ 69 ethernet = (struct sniff_ethernet*)(packet); 70 71 72 /* define/compute ip header offset */ 73 arp = (struct sniff_arp*)(packet + SIZE_ETHERNET); 74 75 print_payload(ethernet, (SIZE_ETHERNET+sizeof(struct sniff_arp))); 76 printf("ethernet.dst:"); 77 print_payload(ethernet->ether_dhost, 6); 78 printf("ethernet.src:"); 79 print_payload(ethernet->ether_shost, 6); 80 printf("arp.opcode:%x/n",arp->ar_op); 81 printf("arp.sha:"); 82 print_payload(arp->ar_sha, 6); 83 printf("arp.sip:%d.%d.%d.%d/n", arp->ar_sip[0],arp->ar_sip[1],arp->ar_sip[2],arp->ar_sip[3]); 84 printf("arp.tha:"); 85 print_payload(arp->ar_tha, 6); 86 printf("arp.tip:%d.%d.%d.%d/n", arp->ar_tip[0],arp->ar_tip[1],arp->ar_tip[2],arp->ar_tip[3]); 87 88 return; 89 }//end_got_packet 90 91 // 92 void usage(char * exename){ 93 printf(" tell dstip with dstmac that srcip is at srcmac. /n"); 94 printf(" usage: %s -d dstip -s srcip -D dstmac -S srcmac /n",exename); 95 return ; 96 } 97 //user input: args 98 u_char ip_src[4],ip_dst[4]; 99 u_char enet_src[6],enet_dst[6]; 100 101 int mac_strtochar6(char * macstr, u_char * enet);//see inet_mton(): convert MAC address to u_char[6] 102 int get_cmdline(int argc,char *argv[]);//process the args 103 104 int main(int argc, char *argv[]){ 105 /* src MAC addr */ 106 mac_strtochar6("00:40:D0:3A:04:35", enet_src); 107 mac_strtochar6("FF:FF:FF:FF:FF:FF", enet_dst); 108 *((unsigned int*)ip_dst)=(unsigned int)inet_addr("192.168.7.3"); 109 *((unsigned int*)ip_src)=(unsigned int)inet_addr("0.0.0.0"); 110 libnet_t *l; 111 libnet_ptag_t t; 112 u_char *packet; 113 u_long packet_s; 114 char errbuf[LIBNET_ERRBUF_SIZE]; 115 char filter_str[100]=""; 116 struct bpf_program fp; /* hold compiled program */ 117 char *dev; 118 pcap_t* descr; 119 bpf_u_int32 maskp; /* subnet mask */ 120 bpf_u_int32 netp; /* ip */ 121 int promisc=0; /* set to promisc mode? */ 122 int pcap_time_out=5; 123 int c, ret; 124 int num_packets = 2; /* number of packets to capture */ 125 if(get_cmdline(argc,argv)<=0){ 126 usage(argv[0]); 127 exit(0); 128 } 129 130 dev = pcap_lookupdev(errbuf); 131 if(dev == NULL){ 132 fprintf(stderr,"%s/n",errbuf); 133 return -1; 134 } 135 ret=pcap_lookupnet(dev,&netp,&maskp,errbuf); 136 if(ret==-1){ 137 fprintf(stderr,"%s/n",errbuf); 138 return -1; 139 } 140 descr = pcap_open_live(dev,BUFSIZ,promisc,pcap_time_out,errbuf); 141 if(descr == NULL){ 142 printf("pcap_open_live(): %s/n",errbuf); 143 return -1; 144 } 145 //sprintf(filter_str,"arp and (src net %d.%d.%d.%d)",ip_dst[0],ip_dst[1],ip_dst[2],ip_dst[3]); 146 if(pcap_compile(descr,&fp,filter_str,0,netp) == -1){ 147 printf("Error calling pcap_compile/n"); 148 return -1; 149 } 150 if(pcap_setfilter(descr,&fp) == -1){ 151 printf("Error setting filter/n"); 152 return -1; 153 } 154 /// 155 156 157 l = libnet_init(LIBNET_LINK_ADV,dev,errbuf); 158 if (l == NULL){ 159 fprintf(stderr, "libnet_init() failed: %s", errbuf); 160 exit(EXIT_FAILURE); 161 } 162 t = libnet_build_arp( 163 ARPHRD_ETHER, /* hardware addr */ 164 ETHERTYPE_IP, /* protocol addr */ 165 6, /* hardware addr size */ 166 4, /* protocol addr size */ 167 ARPOP_REQUEST, /* operation type */ 168 enet_src, /* sender hardware addr */ 169 ip_src, /* sender protocol addr */ 170 enet_dst, /* target hardware addr */ 171 ip_dst, /* target protocol addr */ 172 NULL, /* payload */ 173 0, /* payload size */ 174 l, /* libnet handle */ 175 0); /* libnet id */ 176 if (t == -1){ 177 fprintf(stderr, "Can't build ARP header: %s/n", libnet_geterror(l)); 178 goto bad; 179 } 180 t = libnet_autobuild_ethernet( 181 enet_dst, /* ethernet destination */ 182 ETHERTYPE_ARP, /* protocol type */ 183 l); /* libnet handle */ 184 if (t == -1){ 185 fprintf(stderr, "Can't build ethernet header: %s/n", libnet_geterror(l)); 186 goto bad; 187 } 188 c = libnet_adv_cull_packet(l, &packet, &packet_s); 189 if (c == -1){ 190 fprintf(stderr, "libnet_adv_cull_packet: %s/n", libnet_geterror(l)); 191 goto bad; 192 } 193 c = libnet_write(l); 194 if (c == -1){ 195 fprintf(stderr, "Write error: %s/n", libnet_geterror(l)); 196 goto bad; 197 } 198 199 200 201 printf("wait packet:filter:%s/n",filter_str); 202 /* now we can set our callback function */ 203 pcap_loop(descr, num_packets, got_packet, NULL); 204 205 /* cleanup */ 206 pcap_freecode(&fp); 207 pcap_close(descr); 208 209 printf("/nCapture complete./n"); 210 211 bad: 212 libnet_destroy(l); 213 return (EXIT_FAILURE); 214 215 }