Python的winpcapy庫能夠簡單地實現收發Layer2層(數據鏈路層,以太網)數據。git
winpcapy主頁:https://github.com/orweis/winpcapygithub
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以下:ui
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)spa
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))