Get interface list and MAC addresses on Solaris
For CA Nimsoft Monitor, I had to implement the ability to get a list of ethernet interfaces and corresponding MAC addresses on Solaris. The basic process is:
- Create a socket to be used for
ioctl()
calls - Use
SIOCGIFCONF
ioctl()
call to get list of interfaces - For each interface, get name and IP address from the
SIOCGIFCONF
result - For each interface, use
SIOCGARP
ioctl()
call to get the MAC address
Here’s the result:
void get_interfaces() { char buf[8192] = {0}; struct ifconf ifc = {0}; struct ifreq *ifr = NULL; int sck = 0; int nInterfaces = 0; int i, j; char ip[INET6_ADDRSTRLEN] = {0}; char macp[19]; struct ifreq *item; struct sockaddr *addr; struct arpreq arpreq; /* Get a socket handle. */ if ( sck = socket(AF_INET, SOCK_DGRAM, 0) ) { /* Query available interfaces. */ ifc.ifc_len = sizeof(buf); ifc.ifc_buf = buf; if( ioctl(sck, SIOCGIFCONF, &ifc) == 0 ) { /* Iterate through the list of interfaces. */ ifr = ifc.ifc_req; nInterfaces = ifc.ifc_len / sizeof(struct ifreq); for(i = 0; i < nInterfaces; i++) { item = &ifr[i]; addr = &(item->ifr_addr); /* The interface name: .... = strdup(item->ifr_name); */ /* Get the IP address */ if( ioctl(sck, SIOCGIFADDR, item) >= 0 ) { if (inet_ntop(AF_INET, &(((struct sockaddr_in *)addr)->sin_addr), ip, sizeof ip) == NULL) continue; /* The IP address: .... = strdup(ip); */ /* Get the MAC address */ memcpy(&arpreq.arp_pa,addr,sizeof(struct sockaddr)); if (ioctl(sck,SIOCGARP,(char*)&arpreq) == 0) { sprintf(macp, "%02x:%02x:%02x:%02x:%02x:%02x", (unsigned char)arpreq.arp_ha.sa_data[0], (unsigned char)arpreq.arp_ha.sa_data[1], (unsigned char)arpreq.arp_ha.sa_data[2], (unsigned char)arpreq.arp_ha.sa_data[3], (unsigned char)arpreq.arp_ha.sa_data[4], (unsigned char)arpreq.arp_ha.sa_data[5]); /* The formatted MAC address: .... = strdup(macp); */ } } } } close(sck); } }