int sendpkg ( char * mac, char * broad_mac, char * ip, char * dest ) { Ether_pkg pkg; struct hostent *host = NULL; struct sockaddr sa; int sockfd, len; char buffer[255]; unsigned char temp_ip[5]; memset ( ( char * ) &pkg, '\0', sizeof ( pkg ) ); /* 填充ethernet包文 */ memcpy ( ( char * ) pkg.ether_shost, ( char * ) mac, 6 ); memcpy ( ( char * ) pkg.ether_dhost, ( char * ) broad_mac, 6 ); pkg.ether_type = htons ( ETHERTYPE_ARP ); /* 下面填充arp包文 */ pkg.ar_hrd = htons ( ARPHRD_ETHER ); pkg.ar_pro = htons ( ETHERTYPE_IP ); pkg.ar_hln = 6; pkg.ar_pln = 4; pkg.ar_op = htons ( ARPOP_REQUEST ); memcpy ( ( char * ) pkg.arp_sha, ( char * ) mac, 6 ); memcpy ( ( char * ) pkg.arp_spa, ( char * ) ip, 4 ); memcpy ( ( char * ) pkg.arp_tha, ( char * ) broad_mac, 6 ); //printf ( "Resolve [%s],Please Waiting...",dest ); fflush ( stdout ); memset ( temp_ip, 0, sizeof ( temp_ip ) ); if ( inet_aton ( dest, ( struct in_addr * ) temp_ip ) == 0 ) { if ( ( host = gethostbyname ( dest ) ) == NULL ) { fprintf ( stderr, "Fail! %s\n\a", hstrerror ( h_errno ) ); return ( -1 ); } memcpy ( ( char * ) temp_ip, host->h_addr, 4 ); } //printf ( " Done!\n" ); memcpy ( ( char * ) pkg.arp_tpa, ( char * ) temp_ip, 4 ); /* 实际应该使用PF_PACKET */ if ( ( sockfd = socket ( PF_INET, SOCK_PACKET, htons ( ETH_P_ALL ) ) ) == -1 ) { fprintf ( stderr, "Socket Error:%s\n\a", strerror ( errno ) ); return ( 0 ); } memset ( &sa, '\0', sizeof ( sa ) ); strcpy ( sa.sa_data, "eth0" ); len = sendto ( sockfd, &pkg, sizeof ( pkg ), 0, &sa, sizeof ( sa ) ); if ( len != sizeof ( pkg ) ) { fprintf ( stderr, "Sendto Error:%s\n\a", strerror ( errno ) ); close ( sockfd ); return ( 0 ); } Ether_pkg *parse; parse = ( Ether_pkg * ) buffer; fd_set readfds; struct timeval tv; while ( 1 ) { tv.tv_sec = 0; tv.tv_usec = 500000; //500毫秒 FD_ZERO ( &readfds ); FD_SET ( sockfd, &readfds ); len = select ( sockfd + 1, &readfds, 0, 0, &tv ); if ( len > -1 ) { if ( FD_ISSET ( sockfd, &readfds ) ) { memset ( buffer, 0, sizeof ( buffer ) ); len = recvfrom ( sockfd, buffer, sizeof ( buffer ), 0, NULL, &len ); if ( ( ntohs ( parse->ether_type ) == ETHERTYPE_ARP ) && ( ntohs ( parse->ar_op ) == ARPOP_REPLY ) ) { parse_ether_package ( parse ); } } } break; } close ( sockfd ); return 1; }
/* 源mac * 目的mac * 源ip * 目的ip,字符串形式 */ int sendpkg ( char * mac,char * broad_mac,char * src_ip,char * dest_ip ) { Ether_pkg pkg; struct hostent *host =NULL; int sockfd,len; char buffer[255]; char dest_ip_n[4]; unsigned char *pchar; memset ( ( char * ) &pkg,'\0',sizeof ( pkg ) ); // struct sockaddr sa; struct sockaddr_ll toaddr; struct sockaddr_ll fromaddr; struct ifreq ifr; memset(&toaddr, 0x00, sizeof(toaddr)); memset(&fromaddr, 0x00, sizeof(fromaddr)); memset(&ifr, 0x00, sizeof(ifr)); /* 填充ethernet包文 */ memcpy ( ( char * ) pkg.ether_shost, ( char * ) mac,6 ); memcpy ( ( char * ) pkg.ether_dhost, ( char * ) broad_mac,6 ); pkg.ether_type = htons ( ETHERTYPE_ARP ); /* 下面填充arp包文 */ pkg.ar_hrd = htons ( ARPHRD_ETHER ); pkg.ar_pro = htons ( ETHERTYPE_IP ); pkg.ar_hln = 6; pkg.ar_pln = 4; pkg.ar_op = htons ( ARPOP_REQUEST ); memcpy ( ( char * ) pkg.arp_sha, ( char * ) mac,6 ); memcpy ( ( char * ) pkg.arp_spa, ( char * ) src_ip,4 ); memcpy ( ( char * ) pkg.arp_tha, ( char * ) broad_mac,6 ); fflush ( stdout ); memset ( dest_ip_n,0,sizeof ( dest_ip_n ) ); #if 1 /* 把目的ip地址字符串转换为ip地址 * 返回0表示转换失败 */ if ( inet_aton ( dest_ip, ( struct in_addr * ) dest_ip_n ) ==0 ) { /* 把目的主机名转换成ip地址 */ if ( ( host = gethostbyname ( dest_ip ) ) ==NULL ) { fprintf ( stderr,"Fail! %s\n\a",hstrerror ( h_errno ) ); return ( -1 ); } /* 获取目的ip到dest_ip_n */ memcpy ( ( char * ) dest_ip_n,host->h_addr,4 ); } #endif memcpy ( ( char * ) pkg.arp_tpa, ( char * ) dest_ip_n,4 ); /* 把本次的目的IP,作为下一次的源IP,会造成IP冲突 */ // memcpy ( ( char * ) src_ip,pkg.arp_tpa,4 ); // printf ( "src_ip =[%s]\n", inet_ntoa ( * ( struct in_addr * ) src_ip )); pchar = (unsigned char *)pkg.arp_tpa; // printf ( "send dst MAC=[%s] IP=[%d.%d.%d.%d]\n",mac_ntoa ( pkg.arp_tha ), pchar[0], pchar[1], pchar[2], pchar[3]); pchar = (unsigned char *)pkg.arp_spa; // printf ( "send src MAC=[%s] IP=[%d.%d.%d.%d]\n",mac_ntoa ( pkg.arp_sha ), pchar[0], pchar[1], pchar[2], pchar[3]); // printf ( "send src MAC=[%s] IP=[%s]\n",mac_ntoa ( pkg.arp_sha ), inet_ntoa ( * ( struct in_addr * ) pkg.arp_spa )); if(0>(sockfd=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ARP)))) { fprintf ( stderr,"Socket Error:%s\n\a",strerror ( errno ) ); return ( 0 ); } strcpy(ifr.ifr_name,ETH_DEVICE); //获取接口索引 if(-1 == ioctl(sockfd,SIOCGIFINDEX,&ifr)){ printf("get dev index error:"); return -1; } toaddr.sll_ifindex = ifr.ifr_ifindex; fromaddr.sll_ifindex = ifr.ifr_ifindex; // printf("interface Index:%d\n",ifr.ifr_ifindex); fromaddr.sll_family = PF_PACKET; fromaddr.sll_protocol=htons(ETH_P_ARP); fromaddr.sll_hatype=ARPHRD_ETHER; fromaddr.sll_pkttype=PACKET_HOST; fromaddr.sll_halen=ETH_ALEN; memcpy(fromaddr.sll_addr,mac,ETH_ALEN); bind(sockfd,(struct sockaddr*)&fromaddr,sizeof(struct sockaddr)); toaddr.sll_family = PF_PACKET; len = sendto(sockfd, &pkg, sizeof (pkg), 0,(struct sockaddr*)&toaddr,sizeof(toaddr)); if ( len != sizeof ( pkg ) ) { fprintf ( stderr,"Sendto Error:%s\n\a",strerror ( errno ) ); return ( 0 ); } Ether_pkg *parse; parse = ( Ether_pkg * ) buffer; fd_set readfds; struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 100000; /*100毫秒*/ FD_ZERO ( &readfds ); FD_SET ( sockfd, &readfds ); while(1) { len = select ( sockfd+1, &readfds, 0, 0, &tv ); if ( len == 0 ) { // printf("time out\n"); // printf("\n"); break; } else if(len < 0) { printf("select error\n"); break; } else { if ( FD_ISSET ( sockfd,&readfds ) ) { // printf("get response\n"); memset ( buffer,0,sizeof ( buffer ) ); len=recvfrom ( sockfd,buffer,sizeof ( buffer ),0,NULL,&len ); if ( ( ntohs ( parse->ether_type ) ==ETHERTYPE_ARP ) && ( ntohs ( parse->ar_op ) == ARPOP_REPLY ) ) { // printf("get ARP replay\n"); parse_ether_package ( parse ); break; } else { // printf("parse->ether_type = 0x%04x, parse->ar_op = 0x%04x, parse->arp_spa[0-3] = %s\n", ntohs(parse->ether_type), ntohs(parse->ar_op), inet_ntoa (*(struct in_addr *)parse->arp_spa)); } } { tv.tv_sec = 0; tv.tv_usec = 100000; /*100毫秒*/ } } } return 1; }