原文地址:http://blog.chinaunix.net/uid-17188120-id-2820866.html
1.通过已经连接的socket文件获取
1 int getpeermac( int sockfd, char *buf ) 2 { 3 int ret =0; 4 struct arpreq arpreq; 5 struct sockaddr_in dstadd_in; 6 socklen_t len = sizeof( struct sockaddr_in ); 7 memset( &arpreq, 0, sizeof( struct arpreq )); 8 memset( &dstadd_in, 0, sizeof( struct sockaddr_in )); 9 if( getpeername( sockfd, (struct sockaddr*)&dstadd_in, &len ) < 0 ) 10 err_err("getpeername()"); 11 else 12 { 13 memcpy( &arpreq.arp_pa, &dstadd_in, sizeof( struct sockaddr_in )); 14 strcpy(arpreq.arp_dev, "eth1"); 15 arpreq.arp_pa.sa_family = AF_INET; 16 arpreq.arp_ha.sa_family = AF_UNSPEC; 17 if( ioctl( sockfd, SIOCGARP, &arpreq ) < 0 ) 18 err_err("ioctl SIOCGARP"); 19 else 20 { 21 unsigned char* ptr = (unsigned char *)arpreq.arp_ha.sa_data; 22 ret = sprintf(buf, "%02x%02x%02x%02x%02x%02x", *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)); 23 } 24 } 25 return ret; 26 }
2. 通过IP获取:
1 /** 2 * @send_arp.c 3 * @This software is intended to be used as a example to show how to send and receive arp request with Linux * PF_PACKET interface 4 * @Author:xuelei 5 **/ 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <errno.h> 10 #include <unistd.h> 11 #include <netdb.h> 12 #include <sys/socket.h> 13 #include <sys/un.h> 14 #include <sys/ioctl.h> 15 #include <netinet/in.h> 16 #include <net/if.h> 17 #include <sys/types.h> 18 #include <asm/types.h> 19 #include <features.h> /* 需要里面的 glibc 版本号 */ 20 #if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1 21 #include <netpacket/packet.h> 22 #include <net/ethernet.h> /* 链路层(L2)协议 */ 23 #else 24 #include <asm/types.h> 25 #include <linux/if_packet.h> 26 #include <linux/if_ether.h> /* 链路层协议 */ 27 #endif 28 #include <netinet/if_ether.h> 29 30 #define INLEN 4 31 #define MAC_BCAST_ADDR (uint8_t *) "\xff\xff\xff\xff\xff\xff" 32 33 void usage_quit(char *arg0); 34 int get_ifi(char *dev, char *mac, int macln, struct in_addr *lc_addr, int ipln); 35 void prmac(u_char *ptr); 36 37 int main(int argc, char **argv) 38 { 39 if(argc != 2) 40 usage_quit(argv[0]); 41 42 int fd, salen, n; 43 u_char *mac; 44 char recv_buf[120], rep_addr[16]; 45 struct in_addr lc_addr, req_addr; 46 struct sockaddr_ll reqsa, repsa; 47 struct arp_pkt { 48 struct ether_header eh; 49 struct ether_arp ea; 50 u_char padding[18]; 51 } req; 52 53 bzero(&reqsa, sizeof(reqsa)); 54 reqsa.sll_family = PF_PACKET; 55 reqsa.sll_ifindex = if_nametoindex("eth0"); 56 57 if((fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ARP))) < 0) { 58 perror("Socket error"); 59 exit(1); 60 } 61 62 mac = (char *)malloc(ETH_ALEN); 63 bzero(&req, sizeof(req)); 64 65 if(get_ifi("eth0", mac, ETH_ALEN, &lc_addr, INLEN)) { 66 fprintf(stderr, "Error: Get host’s information failed\n"); 67 exit(0); 68 } 69 printf(" Host MAC is: %02x:%02x:%02x:%02x:%02x:%02x\n",*mac,*(mac+1),*(mac+2),*(mac+3),*(mac+4),*(mac+5)); 70 printf(" Host IP is: %s\n", inet_ntop(AF_INET, &lc_addr, rep_addr, 1024)); 71 /* 填写以太网头部*/ 72 memcpy(req.eh.ether_dhost, MAC_BCAST_ADDR, ETH_ALEN); 73 memcpy(req.eh.ether_shost, mac, ETH_ALEN); 74 req.eh.ether_type = htons(ETHERTYPE_ARP); 75 76 /* 填写arp数据 */ 77 req.ea.arp_hrd = htons(ARPHRD_ETHER); 78 req.ea.arp_pro = htons(ETHERTYPE_IP); 79 req.ea.arp_hln = ETH_ALEN; 80 req.ea.arp_pln = INLEN; 81 req.ea.arp_op = htons(ARPOP_REQUEST); 82 memcpy(req.ea.arp_sha, mac, ETH_ALEN); 83 memcpy(req.ea.arp_spa, &lc_addr, INLEN); 84 inet_aton(argv[1], req.ea.arp_tpa); 85 86 bzero(recv_buf, sizeof(recv_buf)); 87 bzero(&repsa, sizeof(repsa)); 88 salen = sizeof(struct sockaddr_ll); 89 90 if((n = sendto(fd, &req, sizeof(req), 0, (struct sockaddr *)&reqsa, sizeof(reqsa))) <= 0) { 91 perror("Sendto error"); 92 exit(1); 93 } 94 printf("Broadcast arp request of %s, %d bytes be sent\n\n", argv[1], n); 95 96 97 98 while(1) { 99 if((n = recvfrom(fd, recv_buf, sizeof(req), 0, (struct sockaddr *)&repsa, &salen)) <= 0) { 100 perror("Recvfrom error"); 101 exit(1); 102 } 103 if(ntohs(*(__be16 *)(recv_buf + 20))==2 && !memcmp(req.ea.arp_tpa, recv_buf + 28, 4)) { 104 printf("Response from %s, %d bytes received\n", argv[1], n); 105 printf(" Peer IP is: %s\n", inet_ntop(AF_INET, (struct in_addr *)(recv_buf + 28), rep_addr, 1024)); 106 prmac( (u_char *)(recv_buf + 22) ); //prmac( (u_char *)(recv_buf + 6) ); 107 break; 108 } 109 else 110 { 111 printf("Have recive data\n"); 112 break; 113 } 114 } 115 116 free(mac); 117 } 118 119 int get_ifi(char *dev, char * mac, int macln, struct in_addr *lc_addr, int ipln) 120 { 121 int reqfd, n; 122 struct ifreq macreq; 123 124 reqfd = socket(AF_INET, SOCK_DGRAM, 0); 125 strcpy(macreq.ifr_name, dev); 126 127 /* 获取本地接口MAC地址*/ 128 if(ioctl(reqfd, SIOCGIFHWADDR, ¯eq) != 0) 129 return 1; 130 memcpy(mac, macreq.ifr_hwaddr.sa_data, macln); 131 132 /* 获取本地接口IP地址*/ 133 if(ioctl(reqfd, SIOCGIFADDR, ¯eq) != 0) 134 return 1; 135 memcpy(lc_addr, &((struct sockaddr_in *)(¯eq.ifr_addr))->sin_addr, ipln); 136 137 return 0; 138 } 139 140 void prmac(u_char *ptr) 141 { 142 printf(" Peer MAC is: %02x:%02x:%02x:%02x:%02x:%02x\n",*ptr,*(ptr+1),*(ptr+2),*(ptr+3),*(ptr+4),*(ptr+5)); 143 } 144 145 void usage_quit(char *arg0) 146 { 147 fprintf(stderr, "Usage: %s <query_IP>\n", arg0); 148 exit(1); 149 }