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 ( [email protected] )
	
	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 ( [email protected] )
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

Subscribe to get updates delivered to your inbox

4 Comments + Add Comment

  • Can you help for me how to convert the mac to string or char*?

  • when I input ip address like 59.69.123.13(WHICH IS MY FRIENDS’ PC’S IP),the mac address output is CC-CC-CC-CC-CC-CC.

    • Are you sure that their devices are open? ARP socket packet can’t get response data, thus no information containing the MAC address will be sent to your machine. There’s another reason why you can’t get the true MAC address, that is the router will only send the MAC of itself but not the MAC of your friends’ devices’ MAC addresses.

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

Leave a comment