Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have a system with a virtual network interface eth0:1, and I want to send multicast packets that have a source IP of that interface. However, my packets end up with the source IP for eth0. How do I get the correct source IP in my multicast packets?

The commands used to create the iface/route

sudo ifconfig eth0:1 plumb
sudo ifconfig eth0:1 192.168.123.123 netmask 255.255.255.0 up
sudo ip route add 224.1.1.0/24 dev eth0:1 src 192.168.123.123

After which the interfaces look like this;

eth0   Link encap:Ethernet  HWaddr fa:16:3e:9d:94:c2
       inet addr:14.0.0.2  Bcast:14.0.0.255  Mask:255.255.255.0
       UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

eth0:1 Link encap:Ethernet  HWaddr fa:16:3e:9d:94:c2
       inet addr:192.168.123.123  Bcast:192.168.123.255  Mask:255.255.255.0
       UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

routes look like this;

default via 14.0.0.1  metric 100
14.0.0.0/24  proto kernel  scope link  src 14.0.0.2
192.168.123.0/24  proto kernel  scope link  src 192.168.123.123
224.1.1.0/24 dev eth0 scope link  src 192.168.123.123

A directed udp packet sent to 192.168.123.123:5007 gets the correct source IP of 192.168.123.123, but a multicast packet to 224.1.1.1:5007 gets a source IP of 14.0.0.2.

The python script I'm using to generate the packets is this;

MCAST_GRP = '224.1.1.1'
MCAST_PORT = 5007

MY_IP = '192.168.123.123'

def send_mcast():
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    try:
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
    except AttributeError:
        pass # Some systems don't support SO_REUSEPORT

    sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, 2)
    sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1)

    sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(MY_IP))

    print "Sending: robot"
    sock.sendto("robot", (MCAST_GRP, MCAST_PORT))

def send_direct():
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    try:
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
    except AttributeError:
        pass # Some systems don't support SO_REUSEPORT

    print "Sending: robot"
    sock.sendto("robot", (MY_IP, MCAST_PORT))
share|improve this question
add comment

2 Answers 2

I believe you need to use the socket.bind(address) without the port.

docs.python.org/2/library/socket.html

Also, I recommend not using an address on eth0 when youre using sub-interfaces. Move it to 0:0

Also, unless you're using SSM, the source interface is irrelevant with multicast.

Hope that helps!

share|improve this answer
    
thanks. bind is not needed at all - will edit question. Not using SSM, but the receiver is checking the source IP. –  CAB Mar 25 at 19:35
add comment
up vote 0 down vote accepted

After trying several variations on 'ip route add' and none of them working, I stumbled on mac vlan which works exactly as desired. Here are the commands for setting it up;

sudo ip link add link eth0 mac0 type macvlan
sudo ifconfig mac0 plumb
sudo ifconfig mac0 192.168.123.123 netmask 255.255.255.0 up
sudo ip route add 224.1.1.0/24 dev mac0

this gives an interface;

eth0  Link encap:Ethernet  HWaddr fa:16:3e:9d:94:c2
      inet addr:14.0.0.2  Bcast:14.0.0.255  Mask:255.255.255.0

mac0  Link encap:Ethernet  HWaddr 62:c8:10:38:dc:9a
      inet addr:192.168.123.123  Bcast:192.168.123.255  Mask:255.255.255.0

and a route;

224.1.1.0/24 dev mac0  scope link
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.