类似于古老的glibc版本上的getifaddrs

时间:2012-04-16 11:42:27

标签: c linux unix networking glibc

有一个非常有用的函数调用getifaddrs,可以检索所有机器网络地址。问题是我使用的旧glibc版本没有这个功能。它有替代品吗?我正在查找并找到getipnodebyname,但是当地址未映射到/ etc / hosts文件中时,它是无用的。

2 个答案:

答案 0 :(得分:2)

执行等效操作的传统方法是使用SIOCGIFCONF操作ioctl。任何套接字都可用于操作。它并不像单个函数调用那么容易。

答案 1 :(得分:2)

要添加到上一个答案,以下是SIOCGIFCONF - 方法的示例。你必须做这样的事情:

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

int fd;

int get_iface_list(struct ifconf *ifconf)
{
    int rval;
    if((rval = ioctl(fd, SIOCGIFCONF , (char*) ifconf  )) < 0 )
        perror("ioctl(SIOGIFCONF)");

    return rval;
}

int main()
{
    static struct ifreq ifreqs[100];
    static struct ifconf ifc;
    char *ptr;

    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd < 0)
        return 1;

    ifc.ifc_buf = (char*) (ifreqs);
    ifc.ifc_len = sizeof(ifreqs);

    if(get_iface_list(&ifc) < 0) return -1;

    /* Go through the list of interfaces */
    for (ptr = ifc.ifc_buf; ptr < ifc.ifc_buf + ifc.ifc_len;)
    {
        struct ifreq *ifr = (struct ifreq*)ptr;
        int len = (sizeof(struct sockaddr) > ifr->ifr_addr.sa_len) ?
                sizeof(struct sockaddr) : ifr->ifr_addr.sa_len;

        ptr += sizeof(ifr->ifr_name) + len;

            /* Do what you need with the ifr-structure.
             * ifr->ifr_addr contains either sockaddr_dl,
             * sockaddr_in or sockaddr_in6 depending on
             * what addresses and L2 protocols the interface
             * has associated in it.
             */
    }

    close(fd);
    return 0;
}

当然有一些陷阱。根据Unix网络编程第17.6章ioctl(fd, SIOCGIFCONF, array)如果参数中指向的数组太小,可能不会在某些平台上返回错误。然后将数据连接起来。解决此问题的唯一方法是在循环中调用ioctl(),直到两次获得相同的结果长度,同时增加数组的大小。当然,由于这是2012年,我不确定这是多么相关。

在这种情况下,ifreqs数组的大小纯粹是猜测。请记住,对于与接口关联的每个L2和L3地址,阵列将包含一个struct ifreq。例如,假设您还有IPv6地址,对于lo-interface,您将获得三个条目:以太网,IPv4和IPv6。因此,保留足够的空间或使用kludge。

要获取广播地址和其他附加信息,您需要在循环中进行其他ioctl()次呼叫。当然,所有可能的选项取决于您的操作系统提供的内容。

有关更多信息,我建议阅读W. Richard Stevens的Unix网络编程。这是关于这个主题的最具吸引力的书。