A MAC address is the unique identifier that is assigned to a network interface to communicate on your physical network. A MAC address consists of 48 bits and is usually displayed as 6 octets. I won’t get into all the grimy details of network topology and the 7 layer OSI model, that’s what Wikipedia is for! Instead I will give you a few examples of how to display your MAC address in Linux, in Windows, and from a C program using ioctl calls.
In Linux we can use the ifconfig command and grep for HW.
Display MAC Address In Linux
To grab the MAC address of an interface in Linux, simply execute your ifconfig command and do a grep for HW.
$ /sbin/ifconfig | grep HW
eth0 Link encap:Ethernet HWaddr 00:1a:92:1d:dc:9b
eth1 Link encap:Ethernet HWaddr 00:1b:21:0a:d2:cf
In this case my MAC address for eth0 is 00:1a:92:1d:dc:9b and for eth1 is 00:1b:21:0a:d2:cf.
Voila, if you wanted to find it for eth0 specifically, just do a “ifconfig eth0 | grep HW”.
Display MAC Address In Windows
In Windows to quickly find the MAC address of your interface, you can bring up a console Windows. Start > Type “cmd” In the Search programs and Files. This will bring up a the command prompt. Enter the command ipconfig /all This will display ethernet information for all interfaces on your windows machine.
C:\Users\Erik> ipconfig /all
Ethernet adapter Local Area Connection:
Connection-specific DNS Suffix . : localdomain
Description . . . . . . . . . . . : VMware Accelerated AMD PCNet Adapter
Physical Address. . . . . . . . . : 00-0C-29-2B-3E-6D
Dhcp Enabled. . . . . . . . . . . : Yes
Autoconfiguration Enabled . . . . : Yes
IP Address. . . . . . . . . . . . : 192.168.2.104
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.2.1
As shown in the third line, the MAC / Physical address of my virtual interface.
Retrieve MAC Address In C Using A Socket And Ioctl Call
There are a few methods to grab the MAC address of an interface in C. You could actually just do a system or popen call and execute the command I mentioned above (ifconfig | grep HW) and parse the reply. But that’s too easy…and less efficient. Here is a function that takes two parameters as input, the first is the interface name we want to retrieve the MAC address for, and the second is the buffer where we will store the data.
/**
* get_mac_str()
* interface_name the name of the interface we want the MAC of
* mac_str the buffer we will store the result in
* RETURNS: 0 on success; -1 on error.
*/
int get_mac_str(const char *interface_name, char *mac_str)
{
int ioctl_data = 0;
struct ifreq ifr;
// If either pointer is NULL
if (!ifName || !macAddrStr) return(-1);
// Setup our socket
if ( (ioctl_data = socket(PF_INET, SOCK_STREAM, 0)) == -1 ){
fprintf(stderr, "Could not setup socket.\n");
return(-1);
}
// Clear the IFREQ structure
memset(&ifr, 0, sizeof(ifr));
// Store our interface name in the structure for lookup
strncpy(ifr.ifr_name, interface_name, sizeof(ifr.ifr_name));
if ( ioctl(ioctl_sid, SIOCGIFHWADDR, &ifr) < 0)
{
fprintf(stderr, "Could not execute ioctl call.\n");
close(ioctl_data);
return(-1);
}
close(ioctl_data);
// Ensure we are dealing with an Ethernet device
if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER)
{
fprintf(stderr, "Not an ethernet device.\n");
return(-1);
}
// C function to convert address to octet colon form
ether_ntoa_r((const struct ether_addr *)&(ifr.ifr_hwaddr.sa_data),
mac_str);
return(0);
}
This last example is much more efficient than executing a system or popen call. A drawback is you must know what the interface name is you are looking for.
Comments