Get mac address from ip in winsock

Mac address or hardware address is a 48bit (6 character) wide address assigned to a network interface. It is important for the packet delivery between 2 devices like your computer and the router. Ethernet protocol uses the mac address to deliver it to the right network node. It looks like this 00-1E-58-B8-D4-69 ( the dash is not relevant). Mac address of any interface can also be changed ( called mac spoofing ) .



Any network packet that needs to travel from a certain ip address to another needs to know the destination ip's mac address. On windows there is a iphlpapi.dll file which has a function called SendARP which can be used to get the mac address of a given ip address.

Code

In Vc++ 6.0 , where iphlpapi.h and iphlpapi.lib are not available , we can create necessary structures and pointers to functions inside iphlpapi.dll file and use them.

/*
	Author: Silver Moon ( m00n.silv3r@gmail.com )
	
	Find mac address of a given IP address using iphlpapi
*/

#include "winsock2.h"
#include "windows.h"
#include "time.h"
#include "stdio.h"

#pragma comment(lib,"ws2_32.lib") //For winsock

#define MAX_ADAPTER_NAME_LENGTH 256
#define MAX_ADAPTER_DESCRIPTION_LENGTH 128
#define MAX_ADAPTER_ADDRESS_LENGTH 8

//Necessary Structs
typedef struct 
{
	char String[4 * 4];
} IP_ADDRESS_STRING, *PIP_ADDRESS_STRING, IP_MASK_STRING, *PIP_MASK_STRING;

typedef struct _IP_ADDR_STRING 
{
	struct _IP_ADDR_STRING* Next;
	IP_ADDRESS_STRING IpAddress;
	IP_MASK_STRING IpMask;
	DWORD Context;
} IP_ADDR_STRING , *PIP_ADDR_STRING;

typedef struct _IP_ADAPTER_INFO 
{ 
    struct _IP_ADAPTER_INFO* Next; 
    DWORD           ComboIndex; 
    char            AdapterName[MAX_ADAPTER_NAME_LENGTH + 4]; 
    char            Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4]; 
    UINT            AddressLength; 
    BYTE            Address[MAX_ADAPTER_ADDRESS_LENGTH]; 
    DWORD           Index; 
    UINT            Type; 
    UINT            DhcpEnabled; 
    PIP_ADDR_STRING CurrentIpAddress; 
    IP_ADDR_STRING  IpAddressList; 
    IP_ADDR_STRING  GatewayList; 
    IP_ADDR_STRING  DhcpServer; 
    BOOL            HaveWins; 
    IP_ADDR_STRING  PrimaryWinsServer; 
    IP_ADDR_STRING  SecondaryWinsServer; 
    time_t          LeaseObtained; 
    time_t          LeaseExpires; 
} IP_ADAPTER_INFO, *PIP_ADAPTER_INFO;


//Functions
void loadiphlpapi();
void GetMacAddress(unsigned char * , struct in_addr );

//Loads from Iphlpapi.dll
typedef DWORD (WINAPI* psendarp)(struct in_addr DestIP, struct in_addr SrcIP, PULONG pMacAddr, PULONG PhyAddrLen );
typedef DWORD (WINAPI* pgetadaptersinfo)(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen );

int main() 
{
	unsigned char mac[6];
	struct in_addr srcip;
	char ip_address[32];

	WSADATA firstsock;
	
	if (WSAStartup(MAKEWORD(2,2),&firstsock) != 0) 
	{
		printf("\nFailed to initialise winsock.");
		printf("\nError Code : %d",WSAGetLastError());
		return 1;	//Return 1 on error
	}
	
	loadiphlpapi();
	
	//Ask user to select the device he wants to use
	printf("Enter the ip address : ");
	scanf("%s",ip_address);
	srcip.s_addr = inet_addr(ip_address);

	//Get mac addresses of the ip
	GetMacAddress(mac , srcip);
	printf("Selected device has mac address : %.2X-%.2X-%.2X-%.2X-%.2X-%.2X",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
	printf("\n");
			
	return 0;
}

//2 functions
psendarp SendArp;
pgetadaptersinfo GetAdaptersInfo;

void loadiphlpapi() 
{
	HINSTANCE hDll = LoadLibrary("iphlpapi.dll");
		
	GetAdaptersInfo = (pgetadaptersinfo)GetProcAddress(hDll,"GetAdaptersInfo");
	if(GetAdaptersInfo==NULL)
	{
		printf("Error in iphlpapi.dll%d",GetLastError());
	}

	SendArp = (psendarp)GetProcAddress(hDll,"SendARP");
	
	if(SendArp==NULL)
	{
		printf("Error in iphlpapi.dll%d",GetLastError());
	}
}

/*
	Get the mac address of a given ip
*/
void GetMacAddress(unsigned char *mac , struct in_addr destip)
{
	DWORD ret;
	struct in_addr srcip;
	ULONG MacAddr[2];
	ULONG PhyAddrLen = 6;  /* default to length of six bytes */
	int i;

	srcip.s_addr=0;

	//Send an arp packet
	ret = SendArp(destip , srcip , MacAddr , &PhyAddrLen);
	
	//Prepare the mac address
	if(PhyAddrLen)
	{
		BYTE *bMacAddr = (BYTE *) & MacAddr;
		for (i = 0; i < (int) PhyAddrLen; i++)
		{
			mac[i] = (char)bMacAddr[i];
		}
	}
}



Output

Enter the ip address : 192.168.0.1
Selected device has mac address : 00-1E-58-B8-D4-69
Press any key to continue

On Visual C++ 2010 Express Edition , the iphlpapi.lib and iphlpapi.h files are available so the code is much simpler and shorter.

/*
Author: Silver Moon ( m00n.silv3r@gmail.com )
Find mac address of a given IP address using iphlpapi
*/

#include "winsock2.h"
#include "iphlpapi.h"	//For SendARP
#include "stdio.h"
#include "conio.h"

#pragma comment(lib , "iphlpapi.lib") //For iphlpapi
#pragma comment(lib , "ws2_32.lib") //For winsock

void GetMacAddress(unsigned char * , struct in_addr );

int main() 
{
	unsigned char mac[6];
	struct in_addr srcip;
	char ip_address[32];

	WSADATA firstsock;
	
	if (WSAStartup(MAKEWORD(2,2),&firstsock) != 0) 
	{
		printf("\nFailed to initialise winsock.");
		printf("\nError Code : %d" , WSAGetLastError() );
		return 1;
	}
	
	//Ask user to select the device he wants to use
	printf("Enter the ip address : ");
	scanf_s("%s",ip_address);
	srcip.s_addr = inet_addr(ip_address);

	//Get mac addresses of the ip
	GetMacAddress(mac , srcip);
	printf("Selected device has mac address : %.2X-%.2X-%.2X-%.2X-%.2X-%.2X",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);
	printf("\n");
	
	_getch();
	return 0;
}

/*
	Get the mac address of a given ip
*/
void GetMacAddress(unsigned char *mac , struct in_addr destip)
{
	DWORD ret;
	IPAddr srcip;
	ULONG MacAddr[2];
	ULONG PhyAddrLen = 6;  /* default to length of six bytes */
	int i;

	srcip = 0;

	//Send an arp packet
	ret = SendARP((IPAddr) destip.S_un.S_addr , srcip , MacAddr , &PhyAddrLen);
	
	//Prepare the mac address
	if(PhyAddrLen)
	{
		BYTE *bMacAddr = (BYTE *) & MacAddr;
		for (i = 0; i < (int) PhyAddrLen; i++)
		{
			mac[i] = (char)bMacAddr[i];
		}
	}
}

Output

Enter the ip address : 192.168.0.101
Selected device has mac address : 02-10-0C-98-E9-E2
Last Updated On : 11th September 2012

Related Posts

About the Author: Silver Moon

Php developer, blogger and Linux enthusiast. He can be reached at m00n.silv3r[at]gmail[dot]com
Click to know more.

  • ashish

    can you please provide a code of above program in linux .