在linux下检测arp冲突

app 在linux下检测arp冲突
/* 得到本机的mac地址和ip地址 */
    int GetLocalMac ( const char *device,char *mac,char *ip )
    {
     	int sockfd;
    	struct ifreq req;
     	struct sockaddr_in * sin;
     	if ( ( sockfd = socket ( PF_INET,SOCK_DGRAM,0 ) ) ==-1 )
     	{
     		fprintf ( stderr,"Sock Error:%s\n\a",strerror ( errno ) );
    		 return ( -1 );
     	}
    	memset ( &req,0,sizeof ( req ) );
     	strcpy ( req.ifr_name,device );
     	if ( ioctl ( sockfd,SIOCGIFHWADDR, ( char * ) &req ) ==-1 )
     	{
     		fprintf ( stderr,"ioctl SIOCGIFHWADDR:%s\n\a",strerror ( errno ) );
     		close ( sockfd );
    		 return ( -1 );
     	}
     	memcpy ( mac,req.ifr_hwaddr.sa_data,6 );
    	 req.ifr_addr.sa_family = PF_INET;
     	if ( ioctl ( sockfd,SIOCGIFADDR, ( char * ) &req ) ==-1 )
     	{
     		fprintf ( stderr,"ioctl SIOCGIFADDR:%s\n\a",strerror ( errno ) );
     		close ( sockfd );
     		return ( -1 );
     	}
     		sin = ( struct sockaddr_in * ) &req.ifr_addr;
    		 memcpy ( ip, ( char * ) &sin->sin_addr,4 );
     		return ( 0 );
    }



char *mac_ntoa ( const unsigned char *mac )
{
     /* Linux 下有 ether_ntoa(),不过我们重新写一个也很简单 */
     static char buffer[18];
     memset ( buffer,0,sizeof ( buffer ) );
     sprintf ( buffer,"%02X:%02X:%02X:%02X:%02X:%02X",
     mac[0],mac[1],mac[2],mac[3],mac[4],mac[5] );
     return ( buffer );
}


 /* 根据 RFC 0826 修改*/
 typedef struct _Ether_pkg Ether_pkg;
 struct _Ether_pkg
 {
     /* 前面是ethernet头 */
     unsigned char ether_dhost[6]; /* 目地硬件地址 */
     unsigned char ether_shost[6]; /* 源硬件地址 */
     unsigned short int ether_type; /* 网络类型 */
     /* 下面是arp协议 */
     unsigned short int ar_hrd; /* 硬件地址格式 */
     unsigned short int ar_pro; /* 协议地址格式 */
     unsigned char ar_hln; /* 硬件地址长度(字节) */
     unsigned char ar_pln; /* 协议地址长度(字节) */
     unsigned short int ar_op; /* 操作代码 */
     unsigned char arp_sha[6]; /* 源硬件地址 */
     unsigned char arp_spa[4]; /* 源协议地址 */
     unsigned char arp_tha[6]; /* 目地硬件地址 */
     unsigned char arp_tpa[4]; /* 目地协议地址 */
  };

 void parse_ether_package ( const Ether_pkg *pkg )
{
     printf ( "源 IP=[%s] MAC=[%s]\n",inet_ntoa ( * ( struct in_addr * ) pkg->arp_spa ),mac_ntoa ( pkg->arp_sha ) );
     printf ( "目地 IP=[%s] MAC=[%s]\n",inet_ntoa ( * ( struct in_addr * ) pkg->arp_tpa ),mac_ntoa ( pkg->arp_tha ) );
}

 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];
     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 ( ip,0,sizeof ( ip ) );
     if ( inet_aton ( dest, ( struct in_addr * ) ip ) ==0 )
     {
    	 if ( ( host = gethostbyname ( dest ) ) ==NULL )
   	  {
    		 fprintf ( stderr,"Fail! %s\n\a",hstrerror ( h_errno ) );
    		 return ( -1 );
     	  }
   	  memcpy ( ( char * ) ip,host->h_addr,4 );
     }
     //printf ( " Done!\n" );
     memcpy ( ( char * ) pkg.arp_tpa, ( char * ) 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 ) );
    	 return ( 0 );
     }
     Ether_pkg *parse;
     parse = ( Ether_pkg * ) buffer;
     fd_set readfds;
     struct timeval tv;
     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 );
    		 }
  	   }
     }
     return 1;
 }

    int main ( int argc,char **argv )
    {
     struct timeval tvafter,tvpre;
     struct timezone tz;
     gettimeofday ( &tvpre , &tz );
     unsigned char mac[7];
     unsigned char ip[5];
     char dest[16]={0};
     unsigned char broad_mac[7]={0xff,0xff,0xff,0xff,0xff,0xff,0x00};
     memset ( mac,0,sizeof ( mac ) );
     memset ( ip,0,sizeof ( ip ) );
     if ( GetLocalMac ( "eth0",mac,ip ) ==-1 )
     	return ( -1 );
     printf ( "本地 Mac=[%s] Ip=[%s]\n", mac_ntoa ( mac ),inet_ntoa ( * ( struct in_addr * ) ip ) );
     //if ( argc==1 ) return ( -1 );
     sprintf ( dest,"192.168.1.%d",199 );
     uint32_t dip= inet_addr("192.168.1.161");
     sendpkg ( mac,broad_mac,(char * )&dip,dest );
     //int i=0;
     //for(i=1;i<256;i++){
     //sprintf ( dest,"192.168.1.%d",i );
     //sendpkg ( mac,broad_mac,ip,dest );
     //}
     gettimeofday ( &tvafter , &tz );
     printf ( "\n程序执行完毕:%d毫秒\n", ( tvafter.tv_sec-tvpre.tv_sec ) *1000+ ( tvafter.tv_usec-tvpre.tv_usec ) /1000 );
     return 0;
    }

你可能感兴趣的:(网路基础)