【问题标题】:How to send a UDP packet from a specific interface under Linux?Linux下如何从特定接口发送UDP数据包?
【发布时间】:2018-05-18 09:25:13
【问题描述】:

我有几个带有 IPv4 链路本地地址的以太网接口,这意味着我在不同的接口上有多个到 169.254.0.0/16 的路由。 (这些接口不一定在同一个二层网络,所以这个范围内的同一个IP可以被不同的系统在不同的接口上使用。)

当向169.254.0.0/16 中的地址发送UDP 数据包时,我无法使用Rust 的标准库UdpSocket 选择将使用哪个接口发送数据包,但如果不指定接口很可能会使用错误一个。

如何从特定接口发送 UDP 数据包?

(IPv6 Link-Local fe80::/64也有类似的问题,但是SocketAddrV6有一个scope_id可以用来设置要使用的接口的索引)。

【问题讨论】:

  • 所以我不能选择哪个——为什么从逻辑上讲,它们具有相同的掩码/路由/广播地址这一事实?如果不是这样,你会怎么做?
  • 我认为 Rust 不应该处理这个问题,您必须配置您的操作系统以将特定 IP 路由到特定接口。
  • 在 C 套接字 API 中,您可以指定套接字的接口,所以我认为这就是 OP 想要做的。
  • @starblue 你的意思是SO_BINDTODEVICEsocket(7) 将其描述为“仅处理从该特定接口接收的数据包”,但我不清楚它是否也适用于发送。或者IP_UNICAST_IF(来自windows,但我读到一些声称它被移植到linux for wine)?
  • @Stefan SO_BINDTODEVICE,如果我没记错的话,它也可以用于发送(它是在一个商业项目中,我无法再访问代码了)。快速浏览一下 Linux 内核似乎可以证实这一点,尽管很难确定,因为网络堆栈中的一切都是如此间接的。

标签: linux networking rust


【解决方案1】:

假设您知道哪个本地 IP 地址属于哪个网络,您可以使用bind 将套接字绑定到该 IP 地址。

【讨论】:

  • 这是一个好主意,只要您不会碰巧在多个接口上使用相同的 IP :) IIRC 选择地址的“随机生成器”是用 MAC 地址播种的,所以使用不同的 MAC 地址应该会降低几率,但该网络中仍然只有 2^16 IP。
  • bind 仅适用于接收数据包。对于发送 UDP(数据报)数据包,您不需要绑定到套接字。
猜你喜欢
  • 2011-06-02
  • 1970-01-01
  • 1970-01-01
  • 2015-04-20
  • 2012-05-17
  • 2011-10-11
  • 1970-01-01
  • 2019-08-19
  • 1970-01-01
相关资源
最近更新 更多