2016-07-11 3 views
0

Я создал простой сниффер пакетов с использованием raw-сокета в Python.Python TCP raw socket не прослушивается на lo (localhost/127.0.0.1)

import socket 

s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP) 

while True: 
    print s.recvfrom(1600) 

Интернет-трафик показывается. Но когда я перехожу к основному сетевому интерфейсу и отправляю syn-пакеты с помощью scapy через интерфейс lo (источник и пункт назначения 127.0.0.1), ничего печататься не будет.

В основном я создаю и отправляю 10 пакетов syn, используя scapy, чей источник и назначение 127.0.0.1, что видно в wirehark. Но не в этом сниффер. Я думал, что может быть проблема длины. Поэтому я установил размер буфера на размер пакета syn, т. Е. 74 (s.recvfrom(74)), но все равно ничего. Как только я снова включу основной сетевой интерфейс, он отобразит весь трафик TCP.

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

Где я ошибаюсь?

+1

Поскольку ваш уровень равен «0x000», необходимо создать сокет '0x003' (ETH_ALL). Но вопрос: «Как получить пакет без данных?» И вам нужно прослушивать «loopback», но весь пакет не принадлежит вам. Автоматически игнорировать другие пакеты в интернет-интерфейсе, если входящий пакет не принадлежит вам! – dsgdfg

+0

С ETH_ALL в ответ на @ dsgdfg он получит заголовок Ethernet, и он будет обнюхивать все UDP, ICMP, TCP-пакеты. То, что я отправляю в loopback, - только TCP. Итак, если я хочу послушать, что мне делать? – RatDon

ответ

1

В Linux:

soc = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(3)) 
soc.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30) 
soc.bind(("eth0",0x0003)) 

нужно открыть RAW не TCP.

Edit для комментариев:

a = soc.recvform(65565)[0] 
h = binascii.hexlify(a) 
if h[24:30] == "080045" and h[46:48] == "06": 
# h[24:30] == "080045" Means IP (Type field of Ethernet Header 
#    combined with IP Version and IP header length) 
# h[46:48] == "06" Means TCP (Ip Protocol field of IP Header) 

    #do something with TCP packet 

"080045" означают:

0800 = IP
4 = IP версии (IPv4)
5 = длина заголовка (5 слов по 4 байта каждый)

+0

Он будет захватывать все UDP, ICMP, TCP-пакеты. Который я не хочу, поскольку там я должен разбирать пакет и добавлять фильтр, чтобы получить только TCP. Возможно ли прослушивать только TCP-пакеты во всех интерфейсах или конкретном интерфейсе, что я упоминаю. – RatDon

+0

@ RatDon обновленный ответ! – dsgdfg

+0

Вы можете почитать числовые элементы: '08004500'? Обычно байтом '24' является поле« IP Protocol », а для TCP оно должно быть« 06 ». Это один байт, поэтому он не будет зависеть от порядка байтов сети. Не могли бы вы объяснить? – RatDon