查找网络设备

在新闻组上看到有人问如何通过名字查找某个网络设备,其实不难,首先想到的就是通过ioctl,示例代码见下:

[c]
int get_interface(const char interface)
{
int sock = socket(PF_INET, SOCK_STREAM, 0);
struct ifconf ifc;
struct ifreq
ifr;
int ret = -1;

if (sock < 0)
    return -1;

ifc.ifc_len = 0;
ifc.ifc_req = NULL;
if (ioctl(sock, SIOCGIFCONF, &ifc)  0) {
    ifc.ifc_req = malloc(ifc.ifc_len);
    if (ifc.ifc_req) {
        if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
            free(ifc.ifc_req);
            goto close;
        } else
            for (ifr = ifc.ifc_req;
                 (char *)ifr ifr_name);*/
                if (!strcmp(ifr->ifr_name, interface)) {
                    ret = 0;
                    break;
                }
            }
    } else
        return -1;

    free(ifc.ifc_req);
}

close:
close(sock);
return ret;
}
[/c]

然后有人说POSIX其实还有个if_nameindex(),它明显要比ioctl可移植性要高,用它重写上面的代码如下:
[c]
int get_interf(const char *interf)
{

int ret = -1;
struct if_nameindex *ifp, *ifpsave;
ifpsave = ifp = if_nameindex();

if (!ifp)
    return -1;

while (ifp->if_index) {
    if (strcmp(ifp->if_name, interf) == 0) {
        ret = 0;
        break;
    }
    ifp++;
}

if_freenameindex(ifpsave);
return ret;

}
[/c]

我查了一下glibc中的实现,发现在linux上其实如果不用netlink的话,if_nameindex()也就是对ioctl(…SIOCGIFCONF…)的一个包装,具体可参考sysdeps/unix/sysv/linux/if_index.c。netlink这个东西够奇怪的,在这里居然也能派上用场,有机会要研究研究~