2016-12-26 3 views
0

Я пытаюсь читать входящие/исходящие пакеты TCP через интерфейс на хосте для проекта, над которым я работаю , Я действительно хочу, чтобы это было сделано с использованием сокетов вместо использования библиотеки, например scapy или pypcap. Чтобы лучше понять, что происходит, а также больше контроля над тем, что происходит. Это в системе Windows10.Python socket.bind() для хоста не отображает входящие пакеты с SIO_RCVALL при обнюхивании для трафика на интерфейсе

import socket 
import threading 
from PacketParse import PacketParse 

host = socket.gethostbyname(socket.gethostname()) 

sniff = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP) 
sniff.bind((host, 0)) 

#include ip headers - IP PROTOCOL, IP HEADER INCLUDE 
sniff.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) 

#receive all packages - INPUT OUTPUT CONTROL 
sniff.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON) 

def start_sniffing(): 
    while True: 
     raw_packet = sniff.recvfrom(2000) 
     packet = PacketParse(raw_packet) 
     if packet: 
      print(packet.src_addr + ":" + str(packet.src_port) + " --> " + packet.dst_addr + ":" + str(packet.dst_port) + " Protocol: " + packet.ip_prot + "(" + str(packet.ip_prot_raw) + ")") 
      print("Data(" + str(packet.data_size) + "): " + str(packet.data)) 
      #file.write(packet.src_addr + ":" + str(packet.src_port) + " --> " + packet.dst_addr + ":" + str(packet.dst_port) + " Protocol: " + packet.ip_prot + "(" + str(packet.ip_prot_raw) + ")") 
      #file.write("Data(" + str(packet.data_size) + "): " + str(packet.data))''' 

file = open("dump.txt", "a") 
t = threading.Thread(target=start_sniffing) 
t.start() 
t.join() 

file.close() 
sniff.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF) 

PacketParse - класс, который я сделал, чтобы «распаковать» пакет. Я использую документацию Python для большей части этого скрипта и учебников для обнюхивания пакетов из многих источников.

from struct import unpack 

class PacketParse: 
    def __init__(self, packet): 
     self.extract(packet) 

    def extract(self, packet): 
     # extract ip header 
     packet = packet[0] 
     self.packet_raw = packet 
     ''' 
     eth_raw = packet[:14] 
     eth_hdr = unpack('!6s6sH', eth_raw) 
     self.eth_prot = socket.ntohs(eth_hdr[2]) 
     self.src_mac = 
     ''' 
     ip_raw = packet[0:20] 
     ip_hdr = unpack('!BBHHHBBH4s4s', ip_raw) 
     #self.ip_length = ip_hdr[5] 
     self.ip_prot_raw = ip_hdr[6] 
     self.ip_prot = self.ip_prot_parse(ip_hdr[6]) 
     self.src_addr = socket.inet_ntoa(ip_hdr[8]) 
     self.dst_addr = socket.inet_ntoa(ip_hdr[9]) 
     version = ip_hdr[0] >> 4 
     ihl_length = version & 0xF 
     iph_len = ihl_length * 4 

     tcp_raw = packet[20:40] 
     tcp_hdr = unpack('!HHLLBBHHH', tcp_raw) 
     self.src_port = tcp_hdr[0] 
     self.dst_port = tcp_hdr[1] 
     self.seq_num = tcp_hdr[2] 
     self.ack_num = tcp_hdr[3] 
     doff_reserved = tcp_hdr[4] 
     tcp_length = doff_reserved >> 4 

     header_size = (iph_len) + (tcp_length * 4) 
     self.data_size = len(packet) - header_size 

     self.data = packet[header_size:] 

    def ip_prot_parse(self, num): 
     return { 
     1: 'ICMP', 
     6: 'TCP', 
     17: 'UDP', 
     }.get(num, "Unknown") 

Проблема заключается только в том, что пакеты отправляются с этого хоста. Входящие пакеты не отображаются. Другой скрипт, который я пытался использовать scapy, также способен отображать входящие пакеты. Почему это происходит? SIO_RCVALL должен разрешать доступ ко всем пакетам с помощью интерфейса, который нужно увидеть. Я не пробовал эквивалент Linux этого скрипта ... поэтому я не знаю, является ли проблема конкретной для Windows. Большинство скриптов чтения TCP, которые я нашел, были специфичными для Linux.

+0

какое значение имеет 'host'? если 127.0.0.1, то вы получаете только локальные пакеты. Возможно, используйте стандартный '0.0.0.0' для получения от всех сетевых карт (Netwok Cinterface Cards). Как я знаю, программа нуждается в библиотеке 'pcap', чтобы тегировать все пакеты, даже не добавляемые на этот компьютер (если только коммутатор посылает вопросы на ваш компьютер) – furas

+0

Значение хоста - 192.168.2.110': локальный адрес моего компьютера. Изменение хоста на «0.0.0.0» или '' '' не отображает никаких пакетов ... но по какой-то причине я получаю сообщение об ошибке с 'sniff.ioctl' при использовании' 0.0.0.0'. 'sniff.ioctl (socket.SIO_RCVALL, socket.RCVALL_ON) OSError: [WinError 10022] Был указан недопустимый аргумент' – David

ответ

0

Хорошо ... так что проблема была в моем брандмауэре. Когда я отключу его, я вижу все входящие пакеты в порядке. Это было немного раздражающе. Я считаю, что есть библиотека python, которая позволяет редактировать настройки брандмауэра.

https://github.com/austin-taylor/bluewall

я не играл с ним еще ... это может быть интересно. Я еще недостаточно читал в нем, чтобы понять, так ли это. Я считаю, что он дает вам только конфигурацию на Windows, ничего не меняя. Это может быть интересно в системе Linux.

 Смежные вопросы

  • Нет связанных вопросов^_^