Linux-app 未从 169.254.xx(本地链接)获取 UDP 消息

发布于 2024-11-02 11:24:31 字数 390 浏览 1 评论 0原文

我的应用程序(用 C++ 编写,在 Ubuntu 9.10 上运行)正在 UDP 套接字上侦听来自外部设备的广播消息。 这些设备可以拥有任何 IP 地址,因为其目的是在 IP 范围之外进行通信。

当设备的 IP 地址为 99.99.1.2、1.2.3.4、0.0.0.1、192.168.2.77 等时,它可以正常工作(PC 本身是 192.168.1.110)。 但是:当设备具有169.254.xx(本地链接块)时,它不起作用,应用程序不会收到消息。没有运行防火墙,并且 Wireshark 确实 显示该消息,因此连接正常。我假设问题在 IP 堆栈中的某个地方(我打开设备 /dev/eth2 并获取套接字,所以没有什么特别的)。

有什么原因或解决方案吗?多谢。

My application (written in C++, running on Ubuntu 9.10) is listening on a UDP socket for broadcast messages from external devices.
Those devices can have any IP address, since the idea is to communicate beyond IP ranges.

When the devices have IP addresses such as 99.99.1.2, 1.2.3.4, 0.0.0.1, 192.168.2.77 etc, it works fine (the PC itself is 192.168.1.110).
But: it does not work when the device has 169.254.x.x (the local link block), the application doesn't get the message. There is no firewall running, and Wireshark does show the message, so the connection is OK. I assume the problem somewhere in the IP stack (I open device /dev/eth2 and get the socket, so nothing special).

Any idea for a reason or a solution? Thanks a lot.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

贵在坚持 2024-11-09 11:24:31

确保 eth2 具有 IP 地址和网络掩码,并且该 IP 地址和网络掩码将其置于与设备相同的 IP 网络上。使用命令 ifconfig 查看这些详细信息。

Ensure that eth2 has an IP address and netmask and that that IP address and netmask puts it on the same IP network as the device. Use the command ifconfig to see these details.

阿楠 2024-11-09 11:24:31

看来我找到了原因。无论如何,感谢那些提出解决方案的人。

我没有提到我的 Ubuntu 正在虚拟机中运行(这基本上不是问题,因为 Wireshark 收到了消息)

接口是:
eth2 是我上面讨论的接口(因此,它通过广播进行外部通信)。这是一个“桥接”的方式。

此外,我还实现了一个内部“仅主机”网络接口 eth4 来与其他虚拟机进行通信。

我还为 eth2 添加了一条“默认”路由,否则广播通信根本无法工作。

然而,我没有注意到自动插入的“link-local”路由指向eth4。因此我得出结论,系统使用此消息来处理所有 169.254.xx 消息,而我的应用程序不再获取它们。

有两种方法解决了我的问题:

  • 完全禁用 eth4 或
  • 删除“link-local”路由

    route del -net 169.254.0.0 netmask 255.255.0.0 dev eth4

这是删除路由之前的路由表:

Ziel            Router          Genmask         Flags Metric Ref    Use Iface
192.168.230.0   *               255.255.255.0   U     1      0        0 eth4
192.168.1.0     *               255.255.255.0   U     1      0        0 eth2
link-local      *               255.255.0.0     U     1000   0        0 eth4
default         *               0.0.0.0         U     10     0        0 eth2

现在我可以愉快地接收来自我想要的设备的所有数据包。

it seems that I found the reason. Anyway, thanks to those who suggested solutions.

I didn't mention that my Ubuntu is running in a VM (which is basically not the problem since Wireshark got the messages)

The interfaces are:
eth2 is the interface I was talking about above (thus, which does the external communication via broadcasts). It is a "bridged" one.

Additionally, I had implemented an internal "host-only" network interface eth4 to communicate with other VMs.

I had also added a "default" route for eth2, otherwise the broadcast communication wouldn't have worked at all.

However, what I did not notice was the automatically inserted "link-local" route which pointed to eth4. So I conclude that the system uses this one to handle all 169.254.x.x messages and my application doesn't get them any more.

Two ways solved my problem:

  • Disabling eth4 at all or
  • removing the "link-local" route with

    route del -net 169.254.0.0 netmask 255.255.0.0 dev eth4

Here's the routing table before removing the route:

Ziel            Router          Genmask         Flags Metric Ref    Use Iface
192.168.230.0   *               255.255.255.0   U     1      0        0 eth4
192.168.1.0     *               255.255.255.0   U     1      0        0 eth2
link-local      *               255.255.0.0     U     1000   0        0 eth4
default         *               0.0.0.0         U     10     0        0 eth2

Now I can happily receive all packets from the devices I want.

饮惑 2024-11-09 11:24:31

确保当您的 ip 为 169.254.xx 时,在您想要接收广播 UDP 的所有接口上关闭 rp_filter

# sysctl -A | grep '\.rp_filter'
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.lo.rp_filter = 0
net.ipv4.conf.eth0.rp_filter = 0
net.ipv4.conf.eth1.rp_filter = 0

要设置 rp_filter 使用

# sysctl -w net.ipv4.conf.eth0.rp_filter=0

Make sure that rp_filter is turned off on all interfaces that you want to receive broadcast UDP when your ip is 169.254.x.x

# sysctl -A | grep '\.rp_filter'
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.lo.rp_filter = 0
net.ipv4.conf.eth0.rp_filter = 0
net.ipv4.conf.eth1.rp_filter = 0

To set the rp_filter use

# sysctl -w net.ipv4.conf.eth0.rp_filter=0
陌路黄昏 2024-11-09 11:24:31

您需要仔细检查是否有防火墙阻止它们。
在 Linux 上,您可能正在使用 iptables。使用该命令列出
你的规则。许多发行版使用 iptables 实现防火墙但隐藏
来自你的事实。

路由器不应转发来自 192...* 的数据包,因为这不是“可路由”子网。它应该仅用于内部/本地使用。
如果源和目标之间存在路由器或网桥,则可能是问题所在。
如果您在侦听数据包的同一台计算机上有wireshark,则可以
看到他们那么这不是问题。

您可以使用 netstat 来确保您的程序实际上正在监听。
键入“netstat -an -p UDP”以查看正在侦听 udp 数据包的所有程序。


You'll want to double check if you have a firewall blocking them.
On linux you're probably using iptables. Use that command to list
your rules. Many distros implement firewalls using iptables but hide
that fact from you.

Routers aren't supposed to forward packets from 192...* because that's not a "routable" subnet. It's supposed to only be used for internal/local use.
If there's a router or bridge between the source and destination that may be the problem.
If you have wireshark on the same machine that's listening for the packets and you can
see them then this is NOT the issue.

You might use netstat to ensure your program is actually listening.
Type 'netstat -an -p UDP" to see all the programs that are listening for udp packets.


~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文