如何在 linux 中使用 ioctl 获取网关 ip 和名称服务器 ip

Posted

技术标签:

【中文标题】如何在 linux 中使用 ioctl 获取网关 ip 和名称服务器 ip【英文标题】:How to get gateway ip and nameserver ip using ioctl in linux 【发布时间】:2015-03-25 07:20:21 【问题描述】:

我使用 ioctl 调用获得了 ip、子网和广播地址。 但不知道如何获取默认网关和名称服务器 ip。 如果我从/etc/resolv.conf 中选择名称服务器,那么它可靠吗?

这是我的代码:

int main(void)

char buf[1024];
struct ifconf ifc;
struct ifreq *ifr;
int sck, nInterfaces;
int i;
unsigned char mac[6];

sck = socket(AF_INET, SOCK_DGRAM, 0);
if(sck < 0)

    perror("socket");
    return 1;


ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = buf;
if(ioctl(sck, SIOCGIFCONF, &ifc) < 0)

    perror("ioctl(SIOCGIFCONF)");
    return 1;


ifr = ifc.ifc_req;
nInterfaces = ifc.ifc_len / sizeof(struct ifreq);
for(i = 0; i < nInterfaces; i++)

    struct ifreq *item = &ifr[i];
    printf("Interface Name = %s\nIP = %s\n",
           item->ifr_name,
           inet_ntoa(((struct sockaddr_in *)&item->ifr_addr)->sin_addr));

    ioctl(sck, SIOCGIFNETMASK, item);
    printf("SubNet Mask = %s\n", inet_ntoa(((struct sockaddr_in *)&item->ifr_netmask)->sin_addr));

    ioctl(sck, SIOCGIFBRDADDR, item);
    printf("BroadCat Address = %s\n", inet_ntoa(((struct sockaddr_in *)&item->ifr_broadaddr)->sin_addr));

    ioctl(sck, SIOCGIFHWADDR, item);
    memcpy(mac, item->ifr_hwaddr.sa_data, 6);
    printf("MAC:%02X:%02X:%02X:%02X:%02X:%02X\n",mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]); 

 return 0;

【问题讨论】:

您无法使用 ioctl 获取名称服务器,因为名称解析不是由内核处理的。它存在于 glibc 库的深处。 @myaut :但是网关呢?那么我从哪里获得名称服务器 IP?你能帮我吗?? 检查以下代码 - link 【参考方案1】:

要获取默认网关,您可以解析/proc/net/route

# cat /proc/net/route
Iface   Destination     Gateway         Flags   RefCnt  Use     Metric  Mask   MTU      Window  IRTT
eth0    00000000        010110AC        0003    0       0       0       000000000       0       0

如果您需要域名服务器地址,解析 /etc/resolv.conf 对我来说似乎是一个可靠的选择。

【讨论】:

在使用/etc/resolv.conf 时请小心,在我的情况下,DHCPCD 会覆盖/etc/resolv.conf 中列出的名称服务器(执行resolvconf -l)而不更新该文件。因此,实际使用的名称服务器与配置中列出的不同。 @Yeti 您可能在 DHCPCD 配置中设置了 nohook resolv.conf。该选项会阻止 DHCPCD 更新文件。【参考方案2】:

你可以使用

struct rtentry route;
(...)
ioctl(sck, SIOCADDRT, &route)

更多信息她:

How to change default gateway vie C

Linux how to set default route from C

【讨论】:

以上是关于如何在 linux 中使用 ioctl 获取网关 ip 和名称服务器 ip的主要内容,如果未能解决你的问题,请参考以下文章

linux ioctl 方法

IOCTL Linux 设备驱动程序 [关闭]

在给定目的地的情况下,如何在 LINUX 中获取默认网关?

Linux:尝试通过 ioctl 获取游戏杆供应商和产品 ID,改为获取 EINVAL

Linux下利用ioctl函数获取网卡信息

在 AIX 上使用 ioctl 的网络接口的硬件地址