Find Your Interface Index In C

Upon system boot, the kernel will assign an interface index to each new device added. There are various ways to get the interface index, including an ioctl call, using the C function if_nametoindex(), as well as the “/sys/class/net/eth0/ifindex”. I will explore these three options with examples here.

Get Interface Index Using An ioctl Call

To retrieve the interface index using an ioctl call we must create a socket and populate the ifreq structure, as I showed in my previous What Is My Interfaces MAC Address?. For example:

// Headers needed
#include <net/if.h>
#include<netinet/if_ether.h>
#include <net/if_arp.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>     /* the L2 protocols */
#include <asm/types.h>
#include <linux/sockios.h>
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
 
int get_interface_index(const char *interface_name)
{
      struct ifreq ifr;
      int fd;
 
      memset(&ifr, 0, sizeof(ifr));
 
      // setup ifr for ioctl 
      strncpy (ifr.ifr_name, interfaceName, sizeof(ifr.ifr_name) - 1);
      ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0';
 
      // create socket
      fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
      if ( fd == -1) {
             fprintf(stderr," Could not create raw socket:  %s \n", strerror(errno));
             return -1;
      }
 
      // get index 
      if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1)
      {
              close(fd);
              return (-1);
      }
      // close socket if created locally
      close(fd);
 
      return ifr.ifr_ifindex;
}

To create the raw socket you have to run this binary as root. The output from using this function on my system is:

# ./get_index eth0
eth0
3
# ./get_index eth1
eth1
2

So on my system, eth0 is actually indexed at 3 and eth1 is indexed at 2. This may seem counter-intuitive but it is just based on how the kernel registers the devices, for instance eth1 may be an on board network card while eth0 is a PCI network card.

Get Interface Index Using ‘if_nametoindex()’

If you know the name of the interface you are trying to retrieve the index from, you can make a C call to if_nametoindex() and get that value. The functions definition is:

unsigned if_nametoindex(const char *ifname);

It is defined in <net/if.h>. It needs the name of the interface as a parameter and returns the index, or 0 upon failure.

Retrieve Index Using /sys/

The /sys/ or sysFS filesystem is a virtual filesystem that provides information about system devices and drivers to userspace. Some of that information is interface information, including the index. If you head over to “/sys/class/net/” you will see a directory containing all interfaces on your system. On my system:

/sys/class/net$ ls
eth0  eth1  lo  vmnet1  vmnet8

I have five interfaces including the loopback. Within each of these directories is the unique information related to that interface. For example:

$ ls -l eth0/
total 0
-r--r--r-- 1 root root 4096 2011-03-24 16:15 address
-r--r--r-- 1 root root 4096 2011-03-24 16:15 addr_len
-r--r--r-- 1 root root 4096 2011-03-24 16:15 broadcast
-r--r--r-- 1 root root 4096 2011-03-24 16:15 carrier
lrwxrwxrwx 1 root root    0 2011-03-24 16:15 device -> ../../../0000:00:14.0
-r--r--r-- 1 root root 4096 2011-03-24 16:15 dev_id
-r--r--r-- 1 root root 4096 2011-03-24 16:15 dormant
-r--r--r-- 1 root root 4096 2011-03-24 16:15 features
-rw-r--r-- 1 root root 4096 2011-03-24 16:15 flags
-rw-r--r-- 1 root root 4096 2011-03-24 16:15 ifalias
-r--r--r-- 1 root root 4096 2011-03-24 16:15 ifindex
-r--r--r-- 1 root root 4096 2011-03-24 16:15 iflink
-r--r--r-- 1 root root 4096 2011-03-24 16:15 link_mode
-rw-r--r-- 1 root root 4096 2011-03-24 16:15 mtu
-r--r--r-- 1 root root 4096 2011-03-24 16:15 operstate
drwxr-xr-x 2 root root    0 2011-03-24 16:15 power
drwxr-xr-x 2 root root    0 2011-03-24 16:15 statistics
lrwxrwxrwx 1 root root    0 2011-03-24 16:15 subsystem -> ../../../../../class/net
-rw-r--r-- 1 root root 4096 2011-03-24 16:15 tx_queue_len
-r--r--r-- 1 root root 4096 2011-03-24 16:15 type
-rw-r--r-- 1 root root 4096 2011-03-24 16:15 uevent

Hey! There is a file called ifindex! I wonder what that is for? Lets output its values:

$ cat eth0/ifindex 
3

Well look at that, it matches our earlier output from the ioctl call. What are the odds?! You will also notice files such as ‘broadcast’, ‘address’, that provide the broadcast address and MAC address respectively.