我正在尝试通过主机上的接口读取传入/传出的TCP数据包,以用于我正在处理的项目。我真的希望使用套接字而不是像scapy或pypcap这样的库来完成。更好地了解正在发生的事情以及对正在发生的事情的更多控制。这是在Windows10系统上。
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 :(得分:1)
好吧......所以问题似乎是我的防火墙。当我关闭它时,我可以看到所有传入的数据包都很好。这有点烦人。我相信有一个python库可以让你编辑防火墙设置。
https://github.com/austin-taylor/bluewall
我还没有玩过它......它可能很有趣。我还没有充分阅读它,以了解它是否是它看起来的样子。我相信它只会在Windows上进行配置而不会改变任何内容。它在Linux系统上很有趣。