2

I'm having a similar problem to Linux Kernel not passing through multicast UDP packets only broadcast rather than multicast, and nothing I've tried has helped.

I've got a device at 192.168.0.1 spewing out broadcast UDP packets, connected directly to eth1 (192.168.0.2). eth0 is my real network. ifconfig tells me the broadcast address, as expected, is 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 confirms I've got data hitting the port.

$ 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

But from anything I've tried to actually pick those packets up, I've got radio silence, whether I run them as user or root.

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

Also tried writing my own C and my own Python. Nada. Something in all this is stealing my packets. Any ideas on what? Ubuntu 14.04.

Edit to add: No firewall running. ufw reports inactive, and iptables reports all 3 tables as a bare ACCEPT.

I also tried having netcat and socat bind the overall broadcast address of 255.255.255.255, or the eth1 local address 192.168.0.2. No packets received on any attempt.

Routing tables show nothing out of the ordinary:

$ 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

I know that the network interface is working correctly. If I disconnect this device and attach a different type (which is trying to DHCP) it successfully connects with the dnsmasq instance and gets assigned a lease properly.

Interestingly, asking socat to give me raw IP packets turns them up just fine:

$ 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

FINAL EDIT:

Going in and looking more deeply at the packets, it looks like they've got bad checksums. I think they're not getting passed along through the UDP stack because of that. I've also run out of time for elegant solutions to this problem, and have decided to brute force it by opening a socket on raw IP packets and filtering them myself. Thanks, everyone, for your help.

Rgaddi
  • 153
  • 1
  • 1
  • 5
  • Shouldn't the application be sending to 192.168.255.255 rather than 255.255.255.255? Also, you cannot bind to a broadcast address - you need the receiving application to bind to a local unicast address for the interface which will be receiving the broadcast packets; they will then be directed to the listening socket (of your application) via the system network stack as normal. – parkamark Jun 01 '16 at 16:51
  • Why the device broadcast ? Update the firmware of it ? – yagmoth555 Jun 01 '16 at 16:54
  • No go on changing the device; it is what it is. but broadcasting to 255.255.255.255 is entirely legal; it's how a DHCP DISCOVER goes out. – Rgaddi Jun 01 '16 at 18:01
  • @parkamark I tried binding to the unicast address 192.168.0.2, i.e. the eth1 local address. No luck. And any other addresses, 192.168.0.3 for instance, give me `Cannot assign requested address`. – Rgaddi Jun 01 '16 at 18:04
  • I know that, but the answer is a broadcast too. Why no answer in your broadcast packet log ? Your dhcp server dont follow the RFC ? – yagmoth555 Jun 01 '16 at 18:08
  • I would add, please let us know your firewall config as the packet capture can show packet not filtered by the firewall. (http://superuser.com/questions/925286/does-tcpdump-bypass-iptables) – yagmoth555 Jun 01 '16 at 18:17
  • @yagmoth555 Because the device isn't doing DHCP, it's doing a proprietary thing on port 61440. It's not even expecting responses, nor would know what to do with them. I wonder whether the face that the datagrams have a source port of 0 has anything to do with it. – Rgaddi Jun 01 '16 at 20:12
  • Maybe the thing work then, as it's a proprietary protocol. In industry I often create VLAN for those special device, as to prevent to see those broadcast in the LAN. – yagmoth555 Jun 01 '16 at 20:34
  • I will agree with the fact that source port 0 is mighty suspicious. Linux may well drop such packets on the floor. Are you able to change the source port? – Per von Zweigbergk Jun 03 '16 at 16:24
  • @PervonZweigbergk Nope. The sending device is hooked to an FPGA furnished by a customer; getting them to change anything is like pulling sabreteeth. I may just suck it up and work privileged on raw sockets rather than being all clean and user-level about it. I was just hoping there was a more elegant solution somewhere. – Rgaddi Jun 03 '16 at 16:36
  • According to RFC768 source port 0 is valid though. Have you tried sending from source port 0 from some other device? What about dissecting the pcap with wireshark? Maybe theres something else that's off about those packets. – Per von Zweigbergk Jun 03 '16 at 16:43
  • You need to bind to 0.0.0.0 or 255.255.255.255 to receive those (but maybe a raw Socket is more useful as you can see with socat) – eckes Mar 24 '18 at 03:15

2 Answers2

1

Here is a python script for testing UDP connections that I have used in the past:

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

The following can be entered into shell prompt to test sending a message

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

Testing it from localhost to localhost would be the first troubleshooting step, and then from another computer to the computer in question.

0

I have had similar problems when I set up a secondary network interface by hand, and didn't set up routing properly for that interface.

Try running: route -n and see what what the routing configuration is for eth1.

  • Nothing unexpected. 172.16.*.* and the gateway on eth0. 192.168.*.* on eth1. – Rgaddi Jun 03 '16 at 16:13
  • Sorry that didn't help. In that case, I recommend trying the answer by @CaffeineAddiction. – Epictitus Jun 06 '16 at 18:27
  • Oh, I just noticed your edit where you said that your device is generating packets with bad checksums, and you're switching to a brute-force approach reading raw packets. Good luck! – Epictitus Jun 06 '16 at 18:35