Linux 如何从接口ip地址获取接口索引

Linux 如何从接口ip地址获取接口索引,linux,networking,tcp,Linux,Networking,Tcp,谁能告诉我如何从接口ip地址获取接口索引? e、 如果接口ip地址是192.168.23.25,那么它的接口索引是什么 $ cat /proc/net/if_inet6 00000000000000000000000000000001 01 80 10 80 lo fe800000000000000a0027fffe1a2a32 03 40 20 80 eth1 fe800000000000000a0027fffe08b9ca 02 40 20 80 eth0 我

谁能告诉我如何从接口ip地址获取接口索引? e、 如果接口ip地址是192.168.23.25,那么它的接口索引是什么

$ cat /proc/net/if_inet6 
00000000000000000000000000000001 01 80 10 80       lo
fe800000000000000a0027fffe1a2a32 03 40 20 80     eth1
fe800000000000000a0027fffe08b9ca 02 40 20 80     eth0
我想补充一点,我需要在一个用c编写的代码中使用它,所以如果有任何函数 有了一些选项,我可以根据
接口ip地址。

您可以使用以下地址:。它将列出Linux机箱上的网络接口

    #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;
}
#包括
#包括
#包括
#包括

#include.

您不能这样做,您必须查看所有接口,然后遍历所有IP地址,直到找到所需的IP地址。我认为这个代码符合你的要求

#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.s_addr == ia) {
            return i;
        }
    }

    return -1;
}
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
地址:;
int-id;
ia=inet_addr(argv[1]);
id=do_查找(ia);
}
int do_查找(in_addr_t ia){
char-buf[1024];
结构ifconf-ifc;
结构ifreq*ifr;
int-sck;
int-nInterfaces;
int i;
/*拿一个插座手柄*/
sck=插座(AF INET,SOCK DGRAM,0);
如果(sck<0)
{
佩罗(“插座”);
返回-1;
}
/*查询可用接口*/
ifc.ifc_len=sizeof(buf);
ifc.ifc_buf=buf;
如果(ioctl(sck、SIOCGIFCONF和ifc)<0)
{
perror(“ioctl(SIOCGIFCONF)”;
返回-1;
}
/*遍历接口列表*/
ifr=ifc.ifc_要求;
nInterfaces=ifc.ifc\u len/sizeof(结构ifreq);
对于(i=0;iifr\u addr)->sin\u addr.s\u addr==ia){
返回i;
}
}
返回-1;
}

SIOCGIFCONF不会对使用

ip addr add 192.168.25.23/24 dev eth1

如果您真的需要这样做,那么看看“ip addr sh”使用的是什么-可能是netlink套接字操作(涉及非常奇怪的宏)

您应该可以使用它来完成。这应该解释MarkR对次要地址的担忧。作为检验,

添加如下内容后:

ip addr add 192.168.25.23/24 dev eth0
编译和运行手册页上的示例程序应显示如下内容:

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>
lo地址系列:17(AF\u数据包)
eth0地址系列:17(AF_数据包)
lo地址系列:2(AF_INET)
地址:
eth0地址系列:2(AF_INET)
地址:
eth0地址系列:2(AF_INET)
地址:
lo地址系列:10(AF_INET6)
地址:
eth0地址系列:10(AF_INET6)
地址:
您应该能够在遍历列表时获取索引,但还可以查看、和函数。由于您可以将地址与接口名称相关联,因此可以根据需要调用这些名称。

以编程方式,使用。我已经在Ubuntu 12.04(内核3.11.0-15-generic)上验证了这一点

下面是示例代码片段

#include <net/if.h>
#include <stdio.h>
#include <errno.h>
int main(int argc, char *argv[])
{
    for (int ix=1; ix<argc; ix++)
    {
        unsigned int rc = if_nametoindex(argv[ix]);
        if (rc) {
            printf("interface [%s] has index : %d\n", argv[ix], rc);
        }
        else {
            perror("if_nametoindex");
        }
    }
}
此外,非编程方法是读取/proc/net/if_inet6条目。第二列是对应的接口索引

$ cat /proc/net/if_inet6 
00000000000000000000000000000001 01 80 10 80       lo
fe800000000000000a0027fffe1a2a32 03 40 20 80     eth1
fe800000000000000a0027fffe08b9ca 02 40 20 80     eth0

上次我检查时,SIOCGIFCONF只提供每个接口的主地址;因此,大于1的接口将丢失其第2个和后续地址。您是正确的。他没有指明第二个地址,每个设备有多个地址也不常见。嘿,保罗,你的编辑要更改什么?API有变化吗?可能是重复的