使用ARP发包获取目的IP的mac地址

 //发送端
1
#include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <unistd.h> 5 #include <errno.h> 6 #include <sys/socket.h> 7 #include <sys/ioctl.h> 8 #include <sys/types.h> 9 #include <netinet/in.h> 10 #include <netinet/ip.h> 11 #include <netinet/if_ether.h> 12 #include <net/if_arp.h> 13 #include <netpacket/packet.h> 14 #include <net/if.h> 15 #include <net/ethernet.h> 16 17 #define BUFLEN 42 18 19 int main(int argc,char** argv){ 20 int skfd,n; 21 char buf[BUFLEN]={0}; 22 struct ether_header *eth; 23 struct ether_arp *arp; 24 struct sockaddr_ll toaddr; 25 struct in_addr targetIP,srcIP; 26 struct ifreq ifr; 27 28 unsigned char src_mac[ETH_ALEN]={0}; 29 unsigned char dst_mac[ETH_ALEN]={0xff,0xff,0xff,0xff,0xff,0xff}; //全网广播ARP请求 30 if(3 != argc){ 31 printf("Usage: %s netdevName dstIP\n",argv[0]); 32 exit(1); 33 } 34 35 if(0>(skfd=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL)))){ 36 perror("Create Error"); 37 exit(1); 38 } 39 40 bzero(&toaddr,sizeof(toaddr)); 41 bzero(&ifr,sizeof(ifr)); 42 strcpy(ifr.ifr_name,argv[1]); 43 44 //获取接口索引 45 if(-1 == ioctl(skfd,SIOCGIFINDEX,&ifr)){ 46 perror("get dev index error:"); 47 exit(1); 48 } 49 toaddr.sll_ifindex = ifr.ifr_ifindex; 50 printf("interface Index:%d\n",ifr.ifr_ifindex); 51 //获取接口IP地址 52 if(-1 == ioctl(skfd,SIOCGIFADDR,&ifr)){ 53 perror("get IP addr error:"); 54 exit(1); 55 } 56 srcIP.s_addr = ((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr.s_addr; 57 char IP2[64]; 58 inet_ntop(AF_INET, (struct in_addr *)&srcIP, IP2, 64); 59 printf("IP addr:%s\n",IP2); 60 61 //获取接口的MAC地址 62 if(-1 == ioctl(skfd,SIOCGIFHWADDR,&ifr)){ 63 perror("get dev MAC addr error:"); 64 exit(1); 65 } 66 67 memcpy(src_mac,ifr.ifr_hwaddr.sa_data,ETH_ALEN); 68 printf("MAC :%02X-%02X-%02X-%02X-%02X-%02X\n",src_mac[0],src_mac[1],src_mac[2],src_mac[3],src_mac[4],src_mac[5]); 69 70 71 //开始填充,构造以太头部 72 eth=(struct ether_header*)buf; 73 memcpy(eth->ether_dhost,dst_mac,ETH_ALEN); 74 memcpy(eth->ether_shost,src_mac,ETH_ALEN); 75 eth->ether_type = htons(ETHERTYPE_ARP); 76 77 //手动开始填充用ARP报文首部 78 arp=(struct arphdr*)(buf+sizeof(struct ether_header)); 79 arp->arp_hrd = htons(ARPHRD_ETHER); //硬件类型为以太 80 arp->arp_pro = htons(ETHERTYPE_IP); //硬件类型为以太 81 82 //硬件地址长度和IPV4地址长度分别是6字节和4字节 83 arp->arp_hln = ETH_ALEN; 84 arp->arp_pln = 4; 85 86 //操作码,这里我们发送ARP请求 87 arp->arp_op = htons(ARPOP_REQUEST); 88 89 //填充发送端的MAC和IP地址 90 memcpy(arp->arp_sha,src_mac,ETH_ALEN); 91 memcpy(arp->arp_spa,&srcIP,4); 92 93 //填充目的端的IP地址,MAC地址不用管 94 inet_pton(AF_INET,argv[2],&targetIP); 95 memcpy(arp->arp_tpa,&targetIP,4); 96 97 toaddr.sll_family = PF_PACKET; 98 n=sendto(skfd,buf,BUFLEN,0,(struct sockaddr*)&toaddr,sizeof(toaddr)); 99 100 close(skfd); 101 return 0; 102 }

 

//接收端
1
#include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <unistd.h> 5 #include <errno.h> 6 #include <sys/socket.h> 7 #include <sys/ioctl.h> 8 #include <sys/types.h> 9 #include <netinet/in.h> 10 #include <netinet/ip.h> 11 #include <netinet/if_ether.h> 12 #include <net/if_arp.h> 13 #include <netpacket/packet.h> 14 #include <net/if.h> 15 #define BUFLEN 60 16 17 int main(int argc,char** argv){ 18 int i,skfd,n; 19 char buf[ETH_FRAME_LEN]={0}; 20 struct ethhdr *eth; 21 struct ether_arp *arp; 22 struct sockaddr_ll fromaddr; 23 struct ifreq ifr; 24 25 unsigned char src_mac[ETH_ALEN]={0}; 26 27 if(2 != argc){ 28 printf("Usage: %s netdevName\n",argv[0]); 29 exit(1); 30 } 31 32 //只接收发给本机的ARP报文 33 if(0>(skfd=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ARP)))){ 34 perror("Create Error"); 35 exit(1); 36 } 37 38 bzero(&fromaddr,sizeof(fromaddr)); 39 bzero(&ifr,sizeof(ifr)); 40 strcpy(ifr.ifr_name,argv[1]); 41 42 //获取接口索引 43 if(-1 == ioctl(skfd,SIOCGIFINDEX,&ifr)){ 44 perror("get dev index error:"); 45 exit(1); 46 } 47 fromaddr.sll_ifindex = ifr.ifr_ifindex; 48 printf("interface Index:%d\n",ifr.ifr_ifindex); 49 50 //获取接口的MAC地址 51 if(-1 == ioctl(skfd,SIOCGIFHWADDR,&ifr)){ 52 perror("get dev MAC addr error:"); 53 exit(1); 54 } 55 56 memcpy(src_mac,ifr.ifr_hwaddr.sa_data,ETH_ALEN); 57 printf("MAC :%02X-%02X-%02X-%02X-%02X-%02X\n",src_mac[0],src_mac[1],src_mac[2],src_mac[3],src_mac[4],src_mac[5]); 58 59 fromaddr.sll_family = PF_PACKET; 60 fromaddr.sll_protocol=htons(ETH_P_ARP); 61 fromaddr.sll_hatype=ARPHRD_ETHER; 62 fromaddr.sll_pkttype=PACKET_HOST; 63 fromaddr.sll_halen=ETH_ALEN; 64 memcpy(fromaddr.sll_addr,src_mac,ETH_ALEN); 65 66 bind(skfd,(struct sockaddr*)&fromaddr,sizeof(struct sockaddr)); 67 68 while(1){ 69 memset(buf,0,ETH_FRAME_LEN); 70 n=recvfrom(skfd,buf,ETH_FRAME_LEN,0,NULL,NULL); 71 72 eth=(struct ethhdr*)buf; 73 arp=(struct ether_arp*)(buf+14); 74 75 if(ntohs(arp->arp_op)==2){ 76 printf("Get an ARP replay!\n"); 77 printf("Dest MAC:"); 78 for(i=0;i<ETH_ALEN;i++){ 79 printf("%02X-",eth->h_dest[i]); 80 } 81 printf("Sender MAC:"); 82 for(i=0;i<ETH_ALEN;i++){ 83 printf("%02X-",eth->h_source[i]); 84 } 85 86 printf("\n"); 87 printf("Frame type:%0X\n",ntohs(eth->h_proto)); 88 } 89 } 90 close(skfd); 91 return 0; 92 }

 

posted @ 2014-03-14 09:21  T_Mac不忧伤  阅读(2031)  评论(0编辑  收藏  举报