Как отправить IP-пакет с заданной шестнадцатеричной полезной нагрузкой в ​​Python?

Я обнюхал IGMP-пакет и теперь хочу отправить его с помощью python. Есть ли способ просто отправить пакет вроде

0x0000   01 00 5E 00 43 67 00 02-B3 C8 7F 44 81 00 00 DE   ..^.Cg..іИD?..Ю
0x0010   08 00 46 00 00 20 00 01-00 00 01 02 36 4C C0 A8   ..F.. ......6LАЁ
0x0020   00 7B EA 00 43 67 94 04-00 00 16 00 BC 97 EA 00   .{к.Cg”.....ј—к.
0x0030   43 67                                             Cg

без каких-либо генераторов пакетов вроде impacket?

UPD Хорошо, попробовал использовать сырые сокеты, вот так:

dst = '234.0.67.103'

# Open a raw socket.
s = socket.socket(socket.AF_INET, socket.SOCK_RAW,2)

res=''

temp='01 00 5E 00 43 67 00 02 B3 C8 7F 44 81 00 00 DE 08 00 46 00 00 20 00 01 00 00 01 02 36 4C C0 A8 00 7B EA 00 43 67 94 04 00 00 16 00 BC 97 EA 00 43 67'
for i in temp.split(' '):
    res+=chr(int(i, 16))
print res
s.sendto(res, (dst, 0))

Все в порядке, кроме одной мелочи ... Если нюхать этот пакет, он выглядит так:

0x0000   01 00 5E 00 43 67 00 02-B3 C8 7F 44 08 00 45 00   ..^.Cg..іИD..E.
0x0010   00 46 07 06 00 00 01 02-C4 25 C0 A8 00 7B EA 00   .F......Д%АЁ.{к.
0x0020   43 67 01 00 5E 00 43 67-00 02 B3 C8 7F 44 81 00   Cg..^.Cg..іИDЃ.
0x0030   00 DE 08 00 46 00 00 20-00 01 00 00 01 02 36 4C   .Ю..F.. ......6L
0x0040   C0 A8 00 7B EA 00 43 67-94 04 00 00 16 00 BC 97   АЁ.{к.Cg”.....ј—
0x0050   EA 00 43 67                                       к.Cg

Как видите, по какой-то причине python игнорирует мои заголовки и создает свои собственные. Как я могу это исправить?


person yegorov-p    schedule 30.11.2010    source источник
comment
Это может помочь: stackoverflow.com/questions/316866/ping-a-site-in-python (там чистый python ping - я полагаю, вы могли бы его адаптировать)   -  person sje397    schedule 30.11.2010
comment
Вы пробовали необработанные сокеты?   -  person kichik    schedule 30.11.2010
comment
@ sje397 Спасибо за ответ. Что ж, в этом примере они все еще вычисляют контрольную сумму, создают заголовки и т.д. Но у меня уже есть готовый пакет, и я просто хотел бы отправить его, не перестраивая его.   -  person yegorov-p    schedule 30.11.2010
comment
Не может ли проблема быть связана с тем, что базовая ОС может не позволять вам это делать?   -  person Bruno    schedule 30.11.2010


Ответы (3)


Благодаря сетевому программированию Unix (3-е изд):

sockfd = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
# inform os about that program are compose ip header
sockfd.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, True)
person denis4inet    schedule 06.03.2014

Насколько я понимаю, единственный способ сделать это - использовать scapy вот так:

from scapy.all import *
a=Ether(import_hexcap())
<some dumped hex>
sendp(a)
person yegorov-p    schedule 03.12.2010

Ниже приводится модификация вашего кода, который будет отправлять необработанный пакет:

import socket

s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, 0x8100)
s.bind(('eth0', 0x8100))

res=''
temp='01 00 5E 00 43 67 00 02 B3 C8 7F 44 81 00 00 DE 08 00 46 00 00 20 00 01 00 00 01 02 36 4C C0 A8 00 7B EA 00 43 67 94 04 00 00 16 00 BC 97 EA 00 43 67'
for i in temp.split(' '):
    res+=chr(int(i, 16))
s.send(res)
person Paweł Nadolski    schedule 01.12.2010
comment
Спасибо за ответ. Этот код отлично работает в Ubuntu, но в Windows AF_PACKET считается неопределенным. = (Я попытался заменить его на AF_INET, но теперь python сообщает мне, что этот протокол (0x8100) не поддерживается. 0x8100 - это IEEE 802.1Q, и я просто не понимаю, почему он не поддерживается. Я могу сгенерировать пакет с Тег VLAN внутри и отправить его, например, с помощью pierf, и все в порядке. На самом деле, я могу сгенерировать и отправить пакет из моего примера с помощью pierf, и он работает нормально. =) Означает ли это, что Windows не поддерживает сырые сокеты так, как это делает Linux? - person yegorov-p; 01.12.2010