1

У меня есть система с виртуальным сетевым интерфейсом eth0:1, и я хочу отправлять многоадресные пакеты с исходным IP-адресом этого интерфейса. Тем не менее, мои пакеты в конечном итоге с исходным IP для eth0. Как получить правильный исходный IP-адрес в моих многоадресных пакетах?

Команды, используемые для создания 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

После чего интерфейсы выглядят так:

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

маршруты выглядят так;

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

Направленный пакет udp, отправленный на 192.168.123.123:5007, получает правильный исходный IP-адрес 192.168.123.123, но многоадресный пакет на 224.1.1.1:5007 получает исходный IP-адрес 14.0.0.2.

Сценарий Python, который я использую для генерации пакетов, таков;

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))

2 ответа2

1

Попробовав несколько вариантов «ip route add» и ни один из них не работает, я наткнулся на Mac VLAN, который работает точно так, как нужно. Вот команды для его настройки;

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

это дает интерфейс;

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

и маршрут;

224.1.1.0/24 dev mac0  scope link
0

Я считаю, что вам нужно использовать socket.bind(адрес) без порта.

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

Кроме того, я рекомендую не использовать адрес на eth0, когда вы используете подчиненные интерфейсы. Переместить его в 0:0

Кроме того, если вы не используете SSM, интерфейс источника не имеет отношения к многоадресной рассылке.

Надеюсь, это поможет!

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .