Linux下接收广播UDP数据包

Linux下接收广播UDP数据包

我遇到了类似的问题Linux 内核不传递多播 UDP 数据包仅广播而不是多播,而且我尝试过的任何方法都没有帮助。

我有一个位于 192.168.0.1 的设备,它发出广播 UDP 数据包,直接连接到 eth1(192.168.0.2)。eth0 是我真正的网络。ifconfig 告诉我,正如预期的那样,广播地址是 192.168.255.255

$ sudo ifconfig
eth0  Link encap:Ethernet  HWaddr 54:04:a6:64:b5:a6  
      inet addr:172.16.128.1  Bcast:172.16.255.255  Mask:255.255.0.0
      inet6 addr: fe80::5604:a6ff:fe64:b5a6/64 Scope:Link
      UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
      RX packets:1526809 errors:0 dropped:0 overruns:0 frame:0
      TX packets:986480 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:1000 
      RX bytes:807179430 (807.1 MB)  TX bytes:747692150 (747.6 MB)

eth1  Link encap:Ethernet  HWaddr 00:50:b6:15:6e:9a  
      inet addr:192.168.0.2  Bcast:192.168.255.255  Mask:255.255.0.0
      inet6 addr: fe80::250:b6ff:fe15:6e9a/64 Scope:Link
      UP BROADCAST RUNNING PROMISC MULTICAST  MTU:1500  Metric:1
      RX packets:544315 errors:0 dropped:0 overruns:0 frame:0
      TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:1000 
      RX bytes:572619380 (572.6 MB)  TX bytes:77544 (77.5 KB)

tcpdump 确认我有数据到达端口。

$ sudo tcpdump -c 4 -l -n -i eth1 'udp and port 61440'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
09:24:51.101619 IP 192.168.0.1.0 > 255.255.255.255.61440: UDP, length 1024
09:24:51.103980 IP 192.168.0.1.0 > 255.255.255.255.61440: UDP, length 1024
09:24:51.106205 IP 192.168.0.1.0 > 255.255.255.255.61440: UDP, length 1024
09:24:51.108584 IP 192.168.0.1.0 > 255.255.255.255.61440: UDP, length 1024
4 packets captured
114 packets received by filter
0 packets dropped by kernel

但从我实际尝试获取这些数据包的任何方法来看,无论我以用户身份还是 root 身份运行它们,都没有得到任何回应。

$ nc -lu 192.168.255.255 61440
$ socat UDP4-RECV:61440,reuseaddr,bind=192.168.255.255 STDOUT,nonblock=1

还尝试编写自己的 C 和 Python。没有。所有这些中都有一些东西在窃取我的数据包。有什么想法吗?Ubuntu 14.04。

编辑以添加:没有防火墙运行。ufw 报告不活动,并且 iptables 将所有 3 个表报告为裸接受。

我还尝试让 netcat 和 socat 绑定总体广播地址 255.255.255.255,或 eth1 本地地址 192.168.0.2。任何尝试均未收到任何数据包。

路由表没有显示任何异常:

$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.16.0.1      0.0.0.0         UG    0      0        0 eth0
172.16.0.0      0.0.0.0         255.255.0.0     U     1      0        0 eth0
192.168.0.0     0.0.0.0         255.255.0.0     U     0      0        0 eth1

我知道网络接口工作正常。如果我断开此设备并连接其他类型的设备(这尝试 DHCP) 它成功连接到 dnsmasq 实例并正确分配租约。

有趣的是,当我要求 socat 给我原始 IP 数据包时,结果显示一切正常:

$ sudo socat IP4-RECVFROM:17 STDOUT | hexdump 
0000000 0000 00f0 0804 4bb1 6463 6665 6867 6a69
0000010 6c6b 6e6d 606f 6261 6463 6665 6867 6a69
*
0000408

最终编辑:

深入研究这些数据包后,我发现它们的校验和似乎不正确。我认为它们之所以没有通过 UDP 堆栈,就是因为这个原因。我也没有时间找到解决这个问题的优雅方法,因此决定通过打开原始 IP 数据包上的套接字并自行过滤来强制解决这个问题。谢谢大家的帮助。

答案1

下面是我以前使用过的用于测试 UDP 连接的 Python 脚本:

import socket
#---socket creation
connexion = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

#---Bind
try:
    connexion.bind(('', 10015))
except socket.error:
    print "connexion failed"
    connexion.close()
    sys.exit()

#---testing
while 1:
    data, addr = connexion.recvfrom(1024)
    print "messages : ",addr , data

可以在 shell 提示符下输入以下内容来测试发送消息

echo -n "TEST MESSAGE" >/dev/udp/127.0.0.1/10015

从本地主机到本地主机进行测试是第一步故障排除,然后从另一台计算机到有问题的计算机进行测试。

答案2

当我手动设置辅助网络接口且没有为该接口正确设置路由时,我也遇到了类似的问题。

尝试运行:route -n并查看 eth1 的路由配置是什么。

相关内容