Linux-app does not get UDP messages from 169.254.x.x (local link)
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 add开发者_开发百科resses 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.
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.
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.
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
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.
精彩评论