c - 如何找到默认网关的地址和面向它的本地地址?

标签 c linux routes network-programming ip-address

我正在实现一个在 Linux 中工作的端口控制协议(protocol) (PCP) 客户端,用 C 实现。它需要连接到默认网关才能打开端口。 PCP 需要将本地 IP 地址嵌入到消息本身中,而不仅仅是 IP header 中(大概这是为了检测路径中是否存在不需要的 NAT,但对我来说,机器本身之间如何存在 NAT 是个谜)及其默认网关)。 PCP 还需要连接到默认网关,需要其地址。

这提出了两个问题:

  1. 如何查找默认网关的IP地址?
  2. 即使存在多个接口(interface)和 IP 地址,如何查找通往默认网关的计算机的 IP 地址?

最佳答案

问题答案如下:

  1. 可以从 /proc/net/route 轻松找到默认网关。它是掩码为零、目的地为零的路线。所有十六进制值均采用网络字节顺序,因此如果需要漂亮地打印 IP 地址或与主机字节顺序的地址进行比较,则可能需要 ntohl
  2. 查找默认网关的 IP 地址的最简单方法是创建一个 UDP 套接字,而不是 bind() 它,connect() 它到默认网关,然后使用 getsockname() 查找它自动绑定(bind)到的 IP 地址。

有了这些功能,我的 PCP 客户端完全不需要任何手动 IP 地址配置。它会自动检测默认网关和默认网关的 IP 地址。

对于 (1),替代方案可以是 NETLINK 套接字,但解析 /proc/net/route 更容易。第二种替代方案可能是 forkexec netstat 在其输出上带有 pipe ,并解析其输出,但这将使程序依赖于外部二进制文件。

(2) 的替代方案也可以使用 NETLINK 套接字查找本地 IP 地址,然后尝试推断哪个地址将用于连接到默认网关,但让 Linux 内核执行要容易得多自动推导并使用getsockname()读取结果。第二种选择是使用 forkexec ipifconfig 以及 pipe其输出,并解析其输出并推断将使用哪个 IP 地址(/proc/net/route 的第一个字段给出默认路由的接口(interface),因此接口(interface)名称是已知的) ,但这也会使程序依赖于外部二进制文件,并且ifconfig可能并不总是安装,而且这需要在用户空间进行推导过程。

关于c - 如何找到默认网关的地址和面向它的本地地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51113830/

相关文章:

c - 为什么 C 中的数组会衰减为指针?

linux - Linux ISR 入口点在哪里

angular - 防止在 Angular 中的单个 router.navigate 调用上滚动到顶部

ruby-on-rails - 没有路由匹配 [GET]/users

c - 为什么在从 gcc 编译的 C "Hello World"程序调用 printf x86 程序集之前修改 %al 寄存器和堆栈

c - date 和 strftime 的时区从何而来?

linux - 接受可选参数的 Shell 脚本

Linux内核硬件断点

c# - Web Api路由问题

c - 打印结构中的项目