winpcapy
Python的winpcapy库可以简单地实现收发Layer2层(数据链路层,以太网)数据。
winpcapy主页:https://github.com/orweis/winpcapy
安装
pip install winpcapy
发送数据
from winpcapy import WinPcapUtils # Build a packet buffer # This example-code is built for tutorial purposes, for actual packet crafting use modules like dpkt arp_request_hex_template = "%(dst_mac)s%(src_mac)s08060001080006040001" "%(sender_mac)s%(sender_ip)s%(target_mac)s%(target_ip)s" + "00" * 18 packet = arp_request_hex_template % { "dst_mac": "aa"*6, "src_mac": "bb"*6, "sender_mac": "bb"*6, "target_mac": "cc"*6, # 192.168.0.1 "sender_ip": "c0a80001", # 192.168.0.2 "target_ip": "c0a80002" } # Send the packet (ethernet frame with an arp request) on the interface WinPcapUtils.send_packet("*Ethernet*", packet.decode("hex"))
不过注意上面的Sample是Python2的,Python3如下:
WinPcapUtils.send_packet("*Ethernet*", bytes.fromhex(packet)) # for Python3
捕获数据
from winpcapy import WinPcapUtils # Example Callback function to parse IP packets def packet_callback(win_pcap, param, header, pkt_data): # Assuming IP (for real parsing use modules like dpkt) ip_frame = pkt_data[14:] # Parse ips src_ip = ".".join([str(ord(b)) for b in ip_frame[0xc:0x10]]) dst_ip = ".".join([str(ord(b)) for b in ip_frame[0x10:0x14]]) print("%s -> %s" % (src_ip, dst_ip)) WinPcapUtils.capture_on("*Ethernet*", packet_callback)
WinPcapUtils类提供的API接口是指定网卡的设备描述(device description),一般场合是够用的。
不过也有特别的时候,使用双口的光通信模块时,两个光纤网卡的设备描述是相同的,这时需要指定设备名称(device name)
from winpcapy import WinPcap device_name = '\Device\NPF_{AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE}' with WinPcap(device_name) as capture: capture.send(bytes.fromhex('ff'*6))