2016-06-04 7 views
1

Я хочу сделать сниффер пакетов в Python 3.5, который захватывает UDP, TCP и ICMP. Это короткий пример этого:Пакет сниффер в Python

import socket 
import struct 

# the public network interface 
HOST = socket.gethostbyname(socket.gethostname()) 
# create a raw socket and bind it to the public interface 
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP) 

s.bind((HOST,0)) 

# Include IP headers 
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) 

# receive all packages 
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON) 

# receive a package 
n=1 
while(n<=400): 
    print('Number ', n) 
    data=s.recvfrom(65565) 
    packet=data[0] 
    address= data[1] 
    header=struct.unpack('!BBHHHBBHBBBBBBBB', packet[:20]) 
    if(header[6]==6): #header[6] is the field of the Protocol 
     print("Protocol = TCP") 
    elif(header[6]==17): 
     print("Protocol = UDP") 
    elif(header[5]==1): 
     print("Protocol = ICMP") 
    n=n+1 

Проблема заключается в том, что он захватывает только UDP-пакеты :( Выход:

Number 1 Protocol = UDP Number 2 Protocol = UDP Number 3 Protocol = UDP Number 4 Protocol = UDP Number 5 Protocol = UDP Number 6 Protocol = UDP Number 7 

Есть 2 варианта:

  • сниффер может только фиксируют пакеты UDP.
  • Я просто получаю UDP-пакеты.

Я думаю, что самый логичный ответ - мой снифер работает неправильно, и он просто захватывает UDP. Есть идеи?

+1

Держу пари Scapy лучше для этой работы, чем модуль гнезда. Это намного удобнее для обнюхивания пакетов. –

+0

Какую платформу вы используете? В Unix/Linux вам обычно нужно быть root для захвата каждого пакета. –

+0

@HughFisher Я нахожусь в Windows 7, с PyDev и Eclipse. Я выполняю затмение как администратор. –

ответ

1

Я сам нахожусь в стадии создания парсера/сниффера пакетов python, и в своем исследовании я обнаружил, что для возможности синтаксического анализа всех входящих пакетов, таких как TCP, ICMP, UDP, ARP ..etc., Вы не должны используйте ниже тип сокета, поскольку socket.IPPROTO_IP выдает только IP-пакеты и фиктивный протокол

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

, а вы должны использовать это и лучше всего работает с системами Linux

s = socket.socket(socket.AF_PACKET , socket.SOCK_RAW , socket.ntohs(0x0003)) 
+0

@E. Уильямс Возможно, будет немного обыденной коррекцией, но я думаю, вы должны использовать PF_PACKET (семейство протоколов) вместо AF_PACKET (семейство адресов), потому что вы пытаетесь управлять сокетом, а не типом адреса. Это также может уменьшить проблемы при создании пакетов для альтернативных операционных систем. Просто предложение. – NationWidePants