Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Receiving multicast data on specific interface

tcmpdump can view all the multicast traffic to specific group and port on eth2, but my Python program cannot. The Python program, running on Ubuntu 12.04:

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# Multicast port is 52122
sock.bind(('', 52122))

# Interface eth2 IP is 1.2.3.4, multicast group is 6.7.8.9
mreq = socket.inet_aton('6.7.8.9')+socket.inet_aton('1.2.3.4')
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)

while True:
    print '\nwaiting to receive message'
    data, address = sock.recvfrom(1024)
    print data

When I use another program to send a multicast packet to eth2, it works and prints the packet. But it fails to see all the current multicast traffic. If I run tcpdump on eth2 on the same port and group as the above program:

sudo tcpdump -i eth2 host 6.7.8.9 and port 52122

it sees both the packets I send from another program AND all the current multicast traffic. It's output looks likes this...

# Packet sent from my other program
09:52:51.952714 IP 1.2.3.4.57940 > 6.7.8.9.52122: UDP, length 19
# Packet send from the outside world
09:52:52.143339 IP 9.9.9.9.39295 > 6.7.8.9.52122: UDP, length 62

Why can't my program see the packets from the outside world? How can I modify it (or something else) to fix this?

Edit:

I should have mentioned, the interface this going over is not eth2 but eth2.200 a VLAN. (The local IP and the tcpdump commands are all run with eth2.200, I just changed that in this question to make it simpler.) Based on this answer that could be the problem?

Edit #2:

netstat -ng when the program is running shows eth2.200 subscribed to 224.0.0.1 and 6.7.8.9`.

tshark -i eth2.200 igmp shows three repeated 1.2.3.4 -> 6.7.8.9 IGMP 46 V2 Membership Report / Join group 6.7.8.9 when the program first starts. When the program process is killed, it shows 1.2.3.4 -> 224.0.0.2 IGMP 46 V2 Leave group 6.7.8.9. There is also an infrequent 1.2.3.1 -> 224.0.0.1 IGMP 60 V2 Membership Query, general, where 1.2.3.1 is 1.2.3.4's gateway.

Not sure if it will help, but the routing table looks like:

Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         1.2.5.6         0.0.0.0         UG        0 0          0 eth1
1.2.3.0         0.0.0.0         255.255.255.240 U         0 0          0 eth2.200

Thank you!

like image 955
Albeit Avatar asked Dec 12 '12 17:12

Albeit


People also ask

How do I receive multicast messages?

To receive multicast datagrams sent to a particular port, bind to the local port, leaving the local address unspecified, such as INADDR_ANY. In this case, every incoming multicast or broadcast UDP datagram destined for the shared port is delivered to all sockets bound to the port.

Does Port matter for multicast?

@Ryan, a port number is an address of a layer-4 protocol, and it really has nothing to do with a multicast (IP, layer-3) address. If the layer-4 protocol you use for multicast is UDP (common), then UDP requires a port number. UDP has no idea if you are using unicast, broadcast, or multicast.

What is multicast interface?

IP multicast is a method of sending Internet Protocol (IP) datagrams to a group of interested receivers in a single transmission. It is the IP-specific form of multicast and is used for streaming media and other network applications. It uses specially reserved multicast address blocks in IPv4 and IPv6.

Does multicast work across subnets?

Yes you can have multiple casters (actors) on a subnet using the same multicast address. Sometimes this is how actors find their neighbors. The receiving party can not respond to the sending party directly (using a unicast message) but they can reply by sending their own multicast message.


1 Answers

Finally! Found this question on ServerFault that addresses the same thing. Basically the kernel was not forwarding on / was filtering out the packets because it thought the sourced address was spoofed.

Changed the settings in /etc/sysctl.conf to match:

net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.all.rp_filter = 0
net.ipv4.ip_forward = 1

Rebooted and everything works.

like image 92
Albeit Avatar answered Oct 23 '22 07:10

Albeit