c - 如何使用 C 在没有互联网连接、没有 eth0 且没有任何硬编码常量的情况下获取我的外部 ip(主接口(interface))

标签 c linux networking

大多数示例使用例如互联网连接例如谷歌域名。这是各种不好的方式,因为如果本地网络中没有互联网,这将无法工作。

还有一些示例使用了不好的方法,例如分析“eth0”。对于这样的硬编码字符串来说,这是非常糟糕的方式。例如。在我的电脑中,这不起作用,因为我的适配器名称是“ens160”而不是“eth0”:

ens160    Link encap:Ethernet  HWaddr 00:50:56:ba:75:ea  
          inet addr:192.168.0.237  Bcast:192.168.1.255  Mask:255.255.254.0
          inet6 addr: ... Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:205280 errors:0 dropped:1 overruns:0 frame:0
          TX packets:68958 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:266539618 (266.5 MB)  TX bytes:4771936 (4.7 MB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:825 errors:0 dropped:0 overruns:0 frame:0
          TX packets:825 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1 
          RX bytes:74843 (74.8 KB)  TX bytes:74843 (74.8 KB)

我在本地网络中的地址是“192.168.0.237”,这是ens160。这是当某些库创建套接字(例如 microhttpd 或任何其他库)时在系统中使用的默认接口(interface)和 IP。如何使用标准 Linux 库/函数检索它?

提前谢谢

最佳答案

如果您只想发现默认适配器分配的 IP 地址,例如192.168.0.237,调用getifaddrs并枚举每个地址。这与 ifconfig 通常显示的适配器列表以及网关和网络掩码的相关信息相同。过滤掉标记为 IFF_LOOPBACK 或没有 IFF_UP 的内容。一些示例代码here .

如果您有多个这样的地址,那么您需要检查路由表并找到默认路由(目标 IP 地址为 0.0.0.0 的路由)。

jselbie@ubuntu:~$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.254.2   0.0.0.0         UG    100    0        0 ens33
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 ens33
192.168.254.0   0.0.0.0         255.255.255.0   U     100    0        0 ens33

第一个条目(目标路由为 0.0.0.0)是您的默认路由,并通过 ens33 适配器发送。如果有多个默认路由,您将使用具有较低 metric 字段的路由。就我而言,0.0.0.0 路由的接口(interface)是 ens33。如上所述,可以通过调用 getifaddrs 来发现 ens33 的 IP 地址。 (引用 ifaddrs 枚举列表中的 ifa_name 字段。)

至于在C中以编程方式枚举路由表,我实际上不记得如何做到这一点。快速的互联网搜索表明您可以使用 NETLINK socket 。我也会查阅路由命令的源代码。

关于c - 如何使用 C 在没有互联网连接、没有 eth0 且没有任何硬编码常量的情况下获取我的外部 ip(主接口(interface)),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45377937/

相关文章:

networking - 值为 0 的前缀长度

c - Ruby 客户端无法从 C 服务器读取 : socket. 挂起

linux - KornShell (ksh) 重定向

linux - 无密码 SSH 最佳实践

c - yylineno 给出错误报告的意外结果

c - C 编程中从单词列表中生成随机单词

linux - 关于 bash 脚本的说明

c - 协议(protocol)不支持地址族?发给

c - 如何在 C 中检查两个设备文件是否相等?

c - ANSI C,没有可变参数函数的整数到字符串