// All. h // 2005/06/20, A.M. wenxy # Ifndef _ all_h # DEFINE _ all_h # Include <memory. h> # Include <stdio. h> # Include <stdlib. h> # Include <sys/IOCTL. h> # Include <sys/types. h> # Include <sys/Socket. H> # Include <net/If. h> # Include <string. h> # Include <errno. h> //--------------------- // Create the ARP packet header file # Include <netinet/in. h> # Include <ARPA/inet. h> /* # Include <Linux/if_ether.h> */ # Include <ctype. h> # Include <fcntl. h> //--------------------- # Include <unistd. h> # Include <string> # Include <iostream> Using namespace STD; # Define max_mac_len 24 // Maximum length of the Mac string buffer (byte) # Define compart_mac ":" // delimiter of the Mac string. warnning: modify this macro. You must modify the source program !!! # Endif/* end _ all_h */ // End file // Configure //------------------------------------------------------------------------------------------------------------- // Main. cpp // 2005/06/20, A.M. wenxy # Include "all. H" // Function declare Static string getlocalmac (string & Streth); // get loacl Nic's Mac Void set_ip_addr (char *, char *); // fill in the IP address Void set_hw_addr (char Buf [], char * Str); // fill in Mac Static string getmacbyip (string strsrcip, string strsrcmac, string strdesip, string strnic); // obtain the MAC address of the specified IP Address /* # Define src_ip "10.0.1.77" // source IP address # Define des_ip "10.0.1.35" // target IP Address # Define local_hw "00: C0: 4C: 39: 0d: 6f" // MAC address of eth0 in 10.0.1.77 # Define device "eth0" // Interface */ # Define padd_mac "00: 00: 00: 00: 00: 00" // filled Mac # Define des_mac "FF: FF" // broadcast MAC # Define arp_send_count 3 // Number of ARP packets that send ARP requests Struct ether_header { Unsigned char ether_dhost [6];/* destination eth addr */ Unsigned char ether_shost [6];/* Source ether ADDR */ Unsigned short ether_type;/* packet type Id field */ }; Struct arp_header { Unsigned short int ar_hrd;/* Format of hardware address .*/ Unsigned short int ar_pro;/* Format of Protocol address .*/ Unsigned char ar_hln;/* length of hardware address .*/ Unsigned char ar_pln;/* length of Protocol address .*/ //------------------------- Unsigned short int ar_op;/* ARP opcode (command ).*/ Unsigned char _ ar_sha [6];/* sender hardware address .*/ Unsigned char _ ar_sip [4];/* sender IP address .*/ Unsigned char _ ar_tha [6];/* target hardware address .*/ Unsigned char _ ar_tip [4];/* Target IP address .*/ //------------------------- }; Struct arp_packet { Struct ether_header ethhdr; Struct arp_header arphdr; Unsigned char padding [18];/* Filled with 0 */ }; /* ARP reply: * Op = 2 * Ethhdr. ether_dhost = arphdr. _ ar_tha = switch hard ADDR * Ethhdr. ether_shost = arphdr. _ ar_sha = local hard ADDR * Arphdr. _ ar_tip = switch IP * Arphdr. _ ar_sip = victim IP */ # Define frame_type 0x0806/* ARP = 0x0806, RARP = 0x8035 */ # Define hard_type 1/* Ethernet is 1 */ # Define proto_type 0x0800/* IP is 0x0800 */ # Define op_code 1/* ARP = 1/2, 1 is the request, 2 is the response, RARP = 3/4 */
// Obtain the MAC address of the NIC with the specified IP address in the LAN in Linux // In: argv [1]: local IP address, argv [2]: Destination IP address // Out: Int main (INT argc, char * argv []) { String Streth; // local Nic name String strlocalmac; // local Mac String strsrcip; // local IP Address String strdesmac; // target Mac String strdesip; // destination IP address // Check parameters If (argc! = 4) { Printf ("useage: get_mac [Interface Name of the IP] [IP] [arp ip]/n "); Return 0; } Streth = argv [1]; // "eth0 "; Strsrcip = argv [2]; // "10.0.1.77 "; Strdesip = argv [3]; // "10.0.1.69 "; Printf ("Run.../N "); Printf ("get Mac of % s interface.../N", Streth. c_str ()); // Obtain the MAC address of the specified Nic name Strlocalmac = getlocalmac (Streth ); # If 0 Printf ("NOTE: % s [% s]/n", Streth. c_str (), strlocalmac. c_str ()); # Endif // Obtain the MAC address of the specified Interface If (0 = strcmp (const char *) strlocalmac. c_str (), (const char *)"")) { Printf ("error: Call strcmp () failed/N "); Printf ("--------------------------------/n "); Return-1; } Else { Printf ("Mac interface obtained successfully: % s [% s]/n", Streth. c_str (), strlocalmac. c_str ()); } // Obtain the MAC address of the specified IP Nic Strdesmac = getmacbyip (strsrcip, strlocalmac, strdesip, Streth ); Printf ("strdesmac = % s/n", strdesmac. c_str ()); // Return 0; } // Obtain the MAC address of a local Nic // In: Streth // Out: if the request succeeds, the Mac string is returned. If the request fails, the return value is "" (empty string) Static string getlocalmac (string & Streth) { String strlocalmac; Int S; Struct ifreq buffer; Char chbuff [max_mac_len]; Memset (chbuff, 0x0, sizeof (chbuff )); // Arp_process (null ); S =Socket(Pf_inet, sock_dgram, 0 ); If (-1 = s) { Printf ("error: CreateSocketFailture/N "); Printf ("--------------------------------/n "); Return ""; } Memset (& buffer, 0x00, sizeof (buffer )); Strcpy (buffer. ifr_name, Streth. c_str (); // "eth0" If (-1 = IOCTL (S, siocgifhwaddr, & buffer )) { Printf ("error: Get interface % s Mac failed/N", Streth. c_str ()); Printf ("--------------------------------/n "); Return ""; } Close (s );
For (S = 0; S <6; s ++) { Memset (chbuff, 0x0, sizeof (chbuff )); Sprintf (chbuff, "%. 2x", (unsigned char) buffer. ifr_hwaddr.sa_data [s]); Strlocalmac ++ = chbuff;
// Printf ("%. 2x", (unsigned char) buffer. ifr_hwaddr.sa_data [s]); If (S <5) { Memset (chbuff, 0x0, sizeof (chbuff )); Sprintf (chbuff, "% s", compart_mac ); Strlocalmac ++ = chbuff; // Printf (":"); } } // Printf ("/N ");
Return strlocalmac; } //------------------------------------------------------- // Send the ARP packet, receive the ARP response packet, and retrieve the Mac // In: strsrcip: local IP address, strsrcmac: MAC address of the local IP address, strdesip: IP address of the MAC address requested to respond, strnic: Local interface Name // Out: if the request succeeds, Mac is returned. If the request fails, "" (empty string) is returned) Static string getmacbyip (string strsrcip, string strsrcmac, string strdesip, string strnic) { Int sockfd ;//SocketHandle Struct arp_packet ARP; // ARP request packet Struct arp_packet arpres; // ARP application answer Packet Struct sockaddr SA; // ETH Char chsrcip [24]; Char chdesip [24]; Char chsrcmac [24]; Char chnic [8]; Memset (chsrcip, 0x00, sizeof (chsrcip )); Memset (chdesip, 0x00, sizeof (chdesip )); Memset (chsrcmac, 0x00, sizeof (chsrcmac )); Memset (chnic, 0x00, sizeof (chnic )); Sprintf (chsrcip, "% s", strsrcip. c_str ()); Sprintf (chdesip, "% s", strdesip. c_str ()); Sprintf (chsrcmac, "% s", strsrcmac. c_str ()); Sprintf (chnic, "% s", strnic. c_str ()); # Define src_ip chsrcip // Source IP # Define des_ip chdesip // target IP Address # Define local_hw chsrcmac // MAC of eth0 # Define device chnic // local Interface Name
Memset (& ARP, 0x00, sizeof (ARP )); Memset (& arpres, 0x00, sizeof (arpres )); # If 1 Printf ("Source IP [% s] source MAC [% s] Destination IP [% s]/n ",/ Strsrcip. c_str (), strsrcmac. c_str (), strdesip. c_str ()); # Endif Sockfd =Socket(Af_inet,Sock_packet, Htons (0x0806 )); If (sockfd <0) { Printf ("error: CreateSocketFailed/N "); Printf ("--------------------------------/n "); Return ""; } /* // SetSocketNon-Blocking Mode If (-1! = Fcntl (sockfd, f_setfl, o_nonblock )) { Printf ("SettingsSocketNon-blocking mode success/N "); } Else { Printf ("Warning: SetSocketFailed in non-blocking mode [errno = % d]/n ", errno ); } */ // SetSocketReceiving timeout Struct timeval TV; TV. TV _sec = 0; TV. TV _usec = 100; If (0 = setsockopt (sockfd, Sol _Socket, So_rcvtimeo, & TV, sizeof (TV ))) { Printf ("SettingsSocketReceiving timeout successful/N "); } Else { Printf ("Warning: SetSocketFailed to receive timeout [errno = % d]/n ", errno ); } # If 1 Printf ("createSocket Sock_packetSuccess/N "); Printf ("NOTE: Create an ARP request package.../N "); Printf ("--------------------------------/n "); # Endif // Create an ARP request packet /* Init ARP packet header */ Arp. ethhdr. ether_type = htons (frame_type ); Set_hw_addr (char *) arp. ethhdr. ether_dhost, des_mac ); Set_hw_addr (char *) arp. ethhdr. ether_shost, local_hw ); # If 1 Printf ("% x |", ARP. ethhdr. ether_type ); For (INT I = 0; I <6; I ++) { Printf ("% d _", ARP. ethhdr. ether_dhost [I]); } Printf ("| "); For (INT I = 0; I <6; I ++) { Printf ("% d _", ARP. ethhdr. ether_shost [I]); } Printf ("/n --------------------------------/N "); Printf ("the ARP packet frame header (Ethernet header) is initialized successfully/n "); # Endif
/* Init ARP packet data */ Printf ("initialize ARP packet frame data (ARP request group) ....../N "); Printf ("--------------------------------/N "); Arp. arphdr. ar_hrd = htons (hard_type); // 1 Arp. arphdr. ar_pro = htons (proto_type); // 0x0800 Arp. arphdr. ar_op = htons (op_code); // 1 Arp. arphdr. ar_hln = (unsigned char) (6 ); Arp. arphdr. ar_pln = (unsigned char) (4 ); # If 1 Printf ("% d |/N", ARP. arphdr. ar_hrd, ARP. arphdr. ar_pro ,/ Arp. arphdr. ar_op, ARP. arphdr. ar_hln, ARP. arphdr. ar_pln ); Printf ("--------------------------------/N "); # Endif Set_hw_addr (char *) arp. arphdr. _ ar_tha, des_mac); // MAC of the Request IP Address Set_hw_addr (char *) arp. arphdr. _ ar_sha, local_hw); // the MAC address of the sender Set_ip_addr (char *) arp. arphdr. _ ar_tip, des_ip); // request the mac ip Address Set_ip_addr (char *) arp. arphdr. _ ar_sip, src_ip); // source IP address Bzero (arp. padding, 18); // fill in 18 bytes # If 1 For (INT I = 0; I <6; I ++) { Printf ("% d _", ARP. arphdr. _ ar_sha [I]); } Printf ("| "); For (INT I = 0; I <6; I ++) { Printf ("% d _", ARP. arphdr. _ ar_sip [I]); } Printf ("| "); For (INT I = 0; I <6; I ++) { Printf ("% d _", ARP. arphdr. _ ar_tha [I]); } Printf ("| "); For (INT I = 0; I <6; I ++) { Printf ("% d _", ARP. arphdr. _ ar_tip [I]); } Printf ("| "); Printf ("/n --------------------------------/N "); # Endif
/* Send ARP reply packet */ Memset (& SA, 0x00, sizeof (SA )); Strcpy (SA. sa_data, device ); // Send the ARP packet Int nsendcount = arp_send_count; While (nsendcount --)> 0) { Printf ("send ARP request packet [% d bytes] ...... [% d]/n", sizeof (ARP), nsendcount ); If (sendto (sockfd, & ARP, sizeof (ARP), 0, (struct sockaddr *) & SA, sizeof (SA) <0) { Printf ("error: failed to send ARP packet [errno = % d]/n", errno ); Return ""; } } // Receives the ARP response packet Printf ("NOTE: receive ARP response.../N "); Int ntrycount = 5; Int nrecvbyte = 0; Int naddrlen = sizeof (SA ); Do { Nrecvbyte = recvfrom (sockfd, & arpres, sizeof (arpres), 0, (struct sockaddr *) & SA, (socklen_t *) & naddrlen );
// If the ARP response packet of the requested IP address, exit the while String strtarip;/* Target IP Address */ If (nrecvbyte> = 60 & 2 = ntohs (arpres. arphdr. ar_op )) { Char chbuff [max_mac_len]; String strtarip;/* Target IP Address */ // Format the IP address For (int s = 0; S <4; s ++) { Memset (chbuff, 0x00, sizeof (chbuff )); Sprintf (char *) chbuff, "% d", (unsigned char) arpres. arphdr. _ ar_sip [s]); Strtarip + = chbuff; If (S <3) { Memset (chbuff, 0x00, sizeof (chbuff )); Sprintf (char *) chbuff, "% s ","."); Strtarip + = chbuff; } } If (! Strcmp (strtarip. c_str (), strdesip. c_str ())) { Printf ("/n request IP [% s] = Response IP [% s]/n", strdesip. c_str (), strtarip. c_str ()); Break; } } } While (ntrycount --); // Number of ARP response packets received Printf ("received ARP response packet [% d bytes]/n", nrecvbyte ); // Receiving timeout or error If (nrecvbyte =-1) { Printf ("Warning: receiving timeout, or the computer [% s] has no response/N", strdesip. c_str ()); Close (sockfd ); Return ""; } Printf ("analyze ARP response packets.../N "); Char chbuff [max_mac_len]; String strtarip;/* Target IP Address */ String strtarmac;/* target hardware address */ Memset (chbuff, 0x00, sizeof (chbuff )); // Format the IP address For (int s = 0; S <4; s ++) { Memset (chbuff, 0x00, sizeof (chbuff )); Sprintf (char *) chbuff, "% d", (unsigned char) arpres. arphdr. _ ar_sip [s]); Strtarip + = chbuff; If (S <3) { Memset (chbuff, 0x00, sizeof (chbuff )); Sprintf (char *) chbuff, "% s ","."); Strtarip + = chbuff; } } // Format Mac Memset (chbuff, 0x00, sizeof (chbuff )); For (int s = 0; S <6; s ++) { Memset (chbuff, 0x00, sizeof (chbuff )); Sprintf (char *) chbuff, "% 02x", (unsigned char) arpres. arphdr. _ ar_sha [s]); Strtarmac + = chbuff; If (S <5) { Memset (chbuff, 0x00, sizeof (chbuff )); Sprintf (char *) chbuff, "% s", compart_mac ); Strtarmac + = chbuff; } } // Output destination IP address, destination MAC Printf ("Mac [% s]/n", strtarip. c_str (), strtarmac. c_str ()); Printf ("/n --------------------------------/n "); Close (sockfd ); // Return the requested Mac Return strtarmac; /* Return */ }
// Fill in Mac Void set_hw_addr (char Buf [], char * Str) { Int I; Char C, Val; For (I = 0; I <6; I ++) { If (! (C = tolower (* STR ++ ))) Perror ("invalid hardware address"), exit (1 ); If (isdigit (c )) Val = C-'0 '; Else if (C> = 'A' & C <= 'F ') Val = C-'A' + 10; Else Perror ("invalid hardware address"), exit (1 ); Buf [I] = Val <4; If (! (C = tolower (* STR ++ ))) Perror ("invalid hardware address"), exit (1 ); If (isdigit (c )) Val = C-'0 '; Else if (C> = 'A' & C <= 'F ') Val = C-'A' + 10; Else Perror ("invalid hardware address"), exit (1 ); Buf [I] | = val; If (* STR = ':') STR ++; } } // Fill in the IP address Void set_ip_addr (char * Buf, char * Str) { Struct in_addr ADDR; Memset (& ADDR, 0x00, sizeof (ADDR )); ADDR. s_addr = inet_addr (STR ); Memcpy (BUF, & ADDR, 4 ); } //------------------------------------------------------- // End file // Configure //-------------------------------------------------------------------------------------------------------------- # Makefile Bin = get_mac Objets = Main. o Rubbish = $ (objets) $ (BIN) $ (BIN): Main. o G ++-o $ (BIN) Main. o Main. O: Main. cpp all. h G ++-C main. cpp . Phony: clean Clean: -RM $ (rubbish) # End makefile |