views:

139

answers:

5

Can anyone tell me how to get interface index from interface ip address? e.g. If interface ip address is 192.168.23.25 then what is it's interface index.

I want to add on that i need to use it in one code written in c so if any function with some option can give me the interface index number on the base of the interface ip address.

A: 

Why dont you use netstat command?

Chathuranga Chandrasekara
i want to use in the c program. If any function with some option canprovide me interface index number then i can use it in the code.
bhavin
A: 

You could use this:. It will list the network interfaces on your Linux box.

    #include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <stdio.h>
#include <arpa/inet.h>

int main(void)
{
    char          buf[1024];
    struct ifconf ifc;
    struct ifreq *ifr;
    int           sck;
    int           nInterfaces;
    int           i;

/* Get a socket handle. */
    sck = socket(AF_INET, SOCK_DGRAM, 0);
    if(sck < 0)
    {
        perror("socket");
        return 1;
    }

/* Query available interfaces. */
    ifc.ifc_len = sizeof(buf);
    ifc.ifc_buf = buf;
    if(ioctl(sck, SIOCGIFCONF, &ifc) < 0)
    {
        perror("ioctl(SIOCGIFCONF)");
        return 1;
    }

/* Iterate through the list of interfaces. */
    ifr         = ifc.ifc_req;
    nInterfaces = ifc.ifc_len / sizeof(struct ifreq);
    for(i = 0; i < nInterfaces; i++)
    {
        struct ifreq *item = &ifr[i];

    /* Show the device name and IP address */
        printf("%s: IP %s",
               item->ifr_name,
               inet_ntoa(((struct sockaddr_in *)&item->ifr_addr)->sin_addr));

    /* Get the MAC address */
        if(ioctl(sck, SIOCGIFHWADDR, item) < 0)
        {
            perror("ioctl(SIOCGIFHWADDR)");
            return 1;
        }

    /* Get the broadcast address (added by Eric) */
        if(ioctl(sck, SIOCGIFBRDADDR, item) >= 0)
            printf(", BROADCAST %s", inet_ntoa(((struct sockaddr_in *)&item->ifr_broadaddr)->sin_addr));
        printf("\n");
    }

        return 0;
}

I got it from here.

Mark Lewis
Thanks for your reply.
bhavin
A: 

You can't do that, you have to look at all interfaces, then loop through all IP addresses until you find the one you want. I think this code does what you want.

#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <stdio.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
    in_addr_t ia;
    int id;

    ia = inet_addr(argv[1]);

    id = do_lookup(ia);
}

int do_lookup(in_addr_t ia) {
    char          buf[1024];
    struct ifconf ifc;
    struct ifreq *ifr;
    int           sck;
    int           nInterfaces;
    int           i;

/* Get a socket handle. */
    sck = socket(AF_INET, SOCK_DGRAM, 0);
    if(sck < 0)
    {
        perror("socket");
        return -1;
    }

/* Query available interfaces. */
    ifc.ifc_len = sizeof(buf);
    ifc.ifc_buf = buf;
    if(ioctl(sck, SIOCGIFCONF, &ifc) < 0)
    {
        perror("ioctl(SIOCGIFCONF)");
        return -1;
    }

/* Iterate through the list of interfaces. */
    ifr         = ifc.ifc_req;
    nInterfaces = ifc.ifc_len / sizeof(struct ifreq);
    for(i = 0; i < nInterfaces; i++)
    {
        struct ifreq *item = &ifr[i];
        if(((struct sockaddr_in *)&item->ifr_addr)->sin_addr == ia) {
            return i;
        }
    }

    return -1;
}
Richard June
Last time I checked, SIOCGIFCONF only gives you the primary address for each interface; interfaces with >1 will therefore be have their 2nd and subsequent addresses missed.
MarkR
You are correct. He didn't indicate a secondary address, and it's not that common to have multiple addresses per device.
Richard June
Thanks for your reply it worked for me.
bhavin
A: 

SIOCGIFCONF won't cut it for secondary IP addresses added using

ip addr add 192.168.25.23/24 dev eth1

If you really need to do this, then look at whatever "ip addr sh" uses - probably a netlink socket operation (which involves really strange macros)

MarkR
+2  A: 

You should be able to do this with getifaddrs(). It should account for MarkR's concern about secondary addresses. As a test,

After adding something like this:

ip addr add 192.168.25.23/24 dev eth0

compiling and running the example program on the man page should show something like:

lo  address family: 17 (AF_PACKET)
eth0  address family: 17 (AF_PACKET)
lo  address family: 2 (AF_INET)
        address: <127.0.0.1>
eth0  address family: 2 (AF_INET)
        address: <192.168.1.105>
eth0  address family: 2 (AF_INET)
        address: <192.168.25.23>
lo  address family: 10 (AF_INET6)
        address: <::1>
eth0  address family: 10 (AF_INET6)
        address: <fe84::82d6:baaf:fe14:4c22%eth0>

You should be able to get the index as you traverse the list but you can also additionally look at the if_nametoindex(), if_indextoname(), and if_nameindex() functions. Since you will be able to associate an address with an interface name you could just call these as appropriate.

Duck
Thanks and it has solved the problem.
bhavin