libnet создает UDP-пакеты с неверными контрольными суммами - PullRequest
1 голос
/ 15 декабря 2009

Я использую pylibnet для создания и отправки пакетов UDP. Кажется, что все UDP-пакеты, которые я создаю таким образом, имеют недопустимые контрольные суммы. Пример:

# python
Python 2.4.3 (#1, Sep  3 2009, 15:37:12)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-46)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> import libnet
>>> from libnet.constants import *
>>> 
>>> net = libnet.context(RAW4, 'venet0:0')
>>> ip = net.name2addr4('www.stackoverflow.com', RESOLVE)
>>> data = 'This is my payload.'
>>> udptag = net.build_udp(sp=54321, dp=54321, payload=data)
>>> packetlen = IPV4_H + UDP_H + len(data)
>>> iptag = net.autobuild_ipv4(len=packetlen, prot=IPPROTO_UDP, dst=ip)
>>> 
>>> net.write() 

При захвате вышеуказанного пакета на отправляющем хосте обнаруживается неверная контрольная сумма:

# tcpdump -i venet0:0 -n -v -v port 54321
tcpdump: WARNING: arptype 65535 not supported by libpcap - falling back to cooked socket
tcpdump: listening on venet0:0, link-type LINUX_SLL (Linux cooked), capture size 96 bytes
08:16:10.303719 IP (tos 0x0, ttl  64, id 1, offset 0, flags [none], proto: UDP (17), length: 47) 192.168.55.10.54321 > 69.59.196.211.54321: [bad udp cksum 50c3!] UDP, length 0

Я что-то здесь не так делаю?

Ответы [ 3 ]

3 голосов
/ 15 января 2010

Это не имеет ничего общего с ошибками tcpdump или разгрузкой контрольной суммы. Libnet также вычисляет контрольную сумму в режиме пользователя (FYI). Проблема связана с тем, что вы не указали длину для заголовка UDP. Это не рассчитывается автоматически в pylibnet или libnet, поэтому вы должны указать его на данный момент. Ниже приведена исправленная версия вашего кода. Я применю патч к pylibnet для автоматического определения длины заголовка в rc6. Следите за обновлениями до http://sourceforge.net/projects/pylibnet. Я буду выдвигать новую версию, исправляющую эту проблему. Кстати, пожалуйста, не стесняйтесь связаться со мной через страницу pylibnet на sourceforge, если у вас есть ошибки или пожелания. Мне нравится слышать от разработчиков, использующих мое программное обеспечение:)


import libnet
from libnet.constants import *

net = libnet.context(RAW4, 'venet0:0')
ip = net.name2addr4('www.stackoverflow.com', RESOLVE)
data = 'This is my payload.'
udptag = net.build_udp(len=UDP_H+len(data), sp=54321, dp=54321, payload=data)
packetlen = IPV4_H + UDP_H + len(data)
iptag = net.autobuild_ipv4(len=packetlen, prot=IPPROTO_UDP, dst=ip)

net.write()
1 голос
/ 22 января 2010

Я обновил pylibnet для включения автоматического определения размера для полей длины в большинстве заголовков. Таким образом, если вы забудете указать длину заголовка для любого из заголовков, которые этого требуют, он попытается автоматически определить его. Избавляет от головной боли выяснения, почему ваша контрольная сумма плоха;)

1 голос
/ 15 декабря 2009

Задание вычисления контрольных сумм обычно выполняется не в библиотеке пользовательского пространства, а в драйвере устройства или в аппаратном обеспечении. Я полагаю, что вы видите результат «разгрузки контрольной суммы», когда физическое устройство вычисляет контрольные суммы для исходящих пакетов, сохраняя циклы ЦП на хосте. Многие (если не все) современные адаптеры Ethernet делают это, и драйверы не вычисляют контрольную сумму. Так как tcpdump захватывает пакеты в драйвере, прежде чем они попадают на физическое устройство, он просто получает мусор в поле контрольной суммы (вероятно, то, что осталось в буфере) и жалуется.

Было несколько «ошибок», связанных с Wireshark за период 2005-2008 гг., Покрывающих это, и Wireshark (который является просто оболочкой GUI для tcpdump или его эквивалентом Windoze) теперь имеет возможность отключить проверку контрольной суммы для случая разгрузки.

http://wiki.wireshark.org/TCP_Checksum_Verification

В любом случае я бы не ожидал, что pylibnet (или libnet) будет отвечать за контрольные суммы.

См. Также http://www.wireshark.org/docs/wsug_html_chunked/ChAdvChecksums.html#id4744523

...