Как отправить необработанный кадр Ethernet в Python?

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

Сначала я попытался привязать его к интерфейсу 'en1', но он продолжает выдавать ошибку nodename not known. Когда я привязываю его к своему локальному IP-адресу, он работает нормально. После этого я создал необработанный класс пакета, все в шестнадцатеричном формате. Затем я позвонил на sendto, чтобы отправить его по телеграфу.

Проблема в том, что когда я захватываю пакет с помощью wirehark, он отображается как полезная нагрузка пакета ipv4. Я не хочу, чтобы заголовки делались автоматически, в любом случае это то, для чего был мой класс сырых пакетов. Вы знаете, как я могу удалить эти заголовки?

Вот мой код - только необработанная функция:

def raw():
    HOST = gethostbyname('192.168.1.10')

    s = socket(AF_INET, SOCK_RAW, IPPROTO_IP)
    s.bind((HOST, 0))

    s.setsockopt(IPPROTO_IP, IP_HDRINCL, 0) #no headers - it wont work!!

    pckt = packet("\x68\x65\x6c\x6c\x6f")
    netpacket = pckt.getpacket()

    print "Sending.. "
    print ""

    s.sendto(netpacket, ('192.168.1.1', 80))
    data = s.recv(4096)
    print data

А вот захваченный пакет с hello в конце:

007f 2809 6da2 28cf daee 2156 0800 4500 004d 1bfc 0000 4000 db59 c0a8 010a c0a8 0101* 007f     

2809 6da2 28cf daee 2156 0800 4500 0036 2352 4000 4006 0000 c0a8 010a c0a8 0101 15c0 0050 

0000 0000 0000 0000 8010 813b 0000 68656c6c6f -hello

* Это (0101) - начало полезной нагрузки, даже если это должно было быть началом пакета. Также я не собираюсь использовать какие-либо другие модули, я должен использовать сокет.


person Noah Koster    schedule 01.09.2012    source источник
comment
Интересный вопрос, ничем не могу помочь, но, возможно, этот вопрос актуален: stackoverflow.com/questions/6329583/   -  person Daniel Figueroa    schedule 01.09.2012
comment
Терпение - это добродетель. Также имейте в виду, что чем легче вы сделаете свой вопрос для чтения, тем больше вероятность, что кто-то сможет быстро понять природу вашей проблемы и предложить полезное решение (подсказка: правильное использование заглавных букв и разрывы абзацев очень помогают)   -  person talonmies    schedule 01.09.2012
comment
В других примерах используется AF_PACKET вместо AF_INET, вы можете попробовать его, если вы работаете в Linux, поскольку он, похоже, специфичен для Linux.   -  person Roland Smith    schedule 01.09.2012
comment
спасибо, ребята, я еще не пробовал это на Linux, но думаю, что смогу. Я вернусь к вам, если он работает на Linux. У меня Mac OSX, кстати, с Windows 7, XP и Debian. Я добавляю Linux прямо сейчас ... и извиняюсь за то, что не проявил терпения.   -  person Noah Koster    schedule 01.09.2012
comment
@NoahKoster: Если вы действительно пытаетесь отправить необработанный кадр Ethernet, как вы говорите в заголовке, почему вы используете сокет AF_INET, привязанный к IP-адресу? Разве вы не должны использовать AF_PACKET, привязанный к интерфейсу?   -  person talonmies    schedule 02.09.2012
comment
это потому, что Mac OSX не поддерживает af_packet, у меня есть ядро ​​Linux, хотя я должен загрузиться и поддерживает его. это плохой компьютер, хотя ... так что я думаю, что я получу Linux в виртуальной машине на моем Mac OSX. я слишком ленив ...   -  person Noah Koster    schedule 03.09.2012
comment
Отвечает ли это на ваш вопрос? Как использовать Raw Socket в Python?   -  person Rok Povsic    schedule 24.06.2020


Ответы (2)


Благодаря комментариям к этому вопросу мне удалось установить соединение с сервером. все, что потребовалось, - это изменить семейство адресов на af_packet в Linux. Затем я привязал его к своему нику и отправил. это сработало. спасибо за помощь народ! вот пример кода:

s = socket(AF_PACKET, SOCK_RAW)
s.bind(("en1", 0))
pckt = packet() #my class that initializes the raw hex
data = pckt.getpacket()
s.send(data)
message = s.recv(4096)
print s
print s.decode('hex')

Это должно быть в Linux или Debian. насколько мне известно, он не работает в Mac OSX. не знаю насчет окон. если у вас есть Mac, используйте pycap или scapy, они работают нормально.

person Noah Koster    schedule 03.09.2012
comment
Спасибо, что поделился! Можете ли вы опубликовать пример, который отправляет строку или что-то в этом роде? Неясно, сколько магии абстрагируется вашим классом пакета. - person Andrew Wagner; 13.05.2014
comment
Я не мог разместить здесь код, поэтому см. Ниже фрагменты данных, которые сработали для меня. - person CyberFonic; 31.10.2016

Отвечая на ваш вопрос, Эндрю, вот пример:

Этот ответ помог мне заставить WoL работать. В этом случае данные:

preamble = bytearray((0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF))
MAC = bytearray((0x00, 0x14, 0x85, 0xa4, 0x73, 0xce))
data = PREAMBLE + 16*MAC
person CyberFonic    schedule 31.10.2016