Obtain the MAC (physical address) of the NIC with the specified IP address in the LAN in Linux)

Source: Internet
Author: User
 

// 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

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.