Назад | Перейти на главную страницу

Получение широковещательных UDP-пакетов в Linux

У меня аналогичная проблема с Ядро Linux не проходит через многоадресные UDP-пакеты только широковещательная передача, а не многоадресная передача, и ничего из того, что я пробовал, не помогло.

У меня есть устройство на 192.168.0.1, извергающее широковещательные UDP-пакеты, подключенное напрямую к eth1 (192.168.0.2). eth0 - моя настоящая сеть. ifconfig сообщает мне широковещательный адрес, как и ожидалось, 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 подтверждает, что данные попадают в порт.

$ 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

Но из всего, что я пытался собрать эти пакеты, у меня есть радиомолчание, независимо от того, запускаю я их как пользователь или root.

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

Также пробовал писать свой собственный C и свой собственный Python. Нада. Что-то во всем этом крадет мои пакеты. Есть идеи о чем? Ubuntu 14.04.

Отредактируйте, чтобы добавить: брандмауэр не запущен. ufw сообщает о неактивности, а iptables сообщает обо всех трех таблицах как о пустом ACCEPT.

Я также попытался привязать netcat и socat к общему широковещательному адресу 255.255.255.255 или к локальному адресу eth1 192.168.0.2. Ни при каких попытках не было получено пакетов.

Таблицы маршрутизации не показывают ничего необычного:

$ 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

Знаю, что сетевой интерфейс работает правильно. Если я отключу это устройство и подключу другой тип (который является пытается использовать DHCP) он успешно подключается к экземпляру dnsmasq и получает правильную аренду.

Интересно, что просьба к socat предоставить мне необработанные IP-пакеты дает их нормально:

$ 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

ОКОНЧАТЕЛЬНОЕ РЕДАКТИРОВАНИЕ:

Если заглянуть в пакеты и посмотреть более внимательно, похоже, что у них неправильные контрольные суммы. Я думаю, что из-за этого они не проходят через стек UDP. У меня также не хватило времени на элегантные решения этой проблемы, и я решил применить грубую силу, открыв сокет для необработанных IP-пакетов и отфильтровав их самостоятельно. Спасибо всем за вашу помощь.

Вот скрипт на Python для тестирования UDP-соединений, который я использовал в прошлом:

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

В приглашении оболочки можно ввести следующее, чтобы проверить отправку сообщения

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

Тестирование его с локального хоста на локальный будет первым шагом по устранению неполадок, а затем с другого компьютера на соответствующий компьютер.

У меня были аналогичные проблемы, когда я вручную настраивал вторичный сетевой интерфейс и неправильно настраивал маршрутизацию для этого интерфейса.

Попробуйте запустить: route -n и посмотрите, какая конфигурация маршрутизации для eth1.