如何使用dpkt解析802.11协议的pcap?eth类无法处理该协议
Ah, I’ve been in your shoes—dpkt’s eth.Ethernet class is built exclusively for wired Ethernet frames, so it’s totally expected that it can’t handle 802.11 wireless packets. The good news is dpkt does have dedicated support for 802.11 frames; you just need to use the right classes instead. Let’s walk through the solution step by step.
Key Background
Wireless captures often come with an extra layer: the Radiotap header, which includes metadata like signal strength, channel, and data rate. Even if your capture doesn’t have this, you’ll need to use dpkt’s IEEE 802.11 parsing class instead of the Ethernet one.
Step 1: Use the Correct Parsing Classes
Instead of dpkt.eth.Ethernet, use:
dpkt.radiotap.Radiotap(if your capture includes radiotap headers—most do)dpkt.ieee80211.IEEE80211(the core 802.11 frame parser)
Step 2: Full Code Example
Here’s a practical script that handles both radiotap and non-radiotap captures, and processes different 802.11 frame types (management, control, data):
import dpkt def parse_wireless_pcap(pcap_file_path): with open(pcap_file_path, 'rb') as pcap_file: pcap_reader = dpkt.pcap.Reader(pcap_file) for timestamp, packet_buffer in pcap_reader: # First, check for a Radiotap header (common in wireless captures) try: radiotap_header = dpkt.radiotap.Radiotap(packet_buffer) # Extract the raw 802.11 frame from the Radiotap payload ieee_frame = dpkt.ieee80211.IEEE80211(radiotap_header.data) except dpkt.dpkt.NeedData: # No Radiotap header—parse directly as an 802.11 frame ieee_frame = dpkt.ieee80211.IEEE80211(packet_buffer) # Classify and process the frame type if ieee_frame.type == dpkt.ieee80211.MGMT_TYPE: print(f"[{timestamp}] Management Frame (subtype: {ieee_frame.subtype})") # Access management-specific fields via ieee_frame.mgmt (e.g., beacons, probes) elif ieee_frame.type == dpkt.ieee80211.CTRL_TYPE: print(f"[{timestamp}] Control Frame (subtype: {ieee_frame.subtype})") elif ieee_frame.type == dpkt.ieee80211.DATA_TYPE: print(f"[{timestamp}] Data Frame (subtype: {ieee_frame.subtype})") # Many data frames use LLC/SNAP encapsulation for IP traffic try: llc_layer = dpkt.llc.LLC(ieee_frame.data) # Check for SNAP encapsulation (AA/AA DSAP/SSAP) if llc_layer.dsap == 0xaa and llc_layer.ssap == 0xaa: snap_layer = dpkt.snap.SNAP(llc_layer.data) # If it's an IP packet, parse it if snap_layer.oui == 0 and snap_layer.type == dpkt.ethernet.ETH_TYPE_IP: ip_packet = dpkt.ip.IP(snap_layer.data) print(f" -> IP Traffic: {ip_packet.src} -> {ip_packet.dst}") except dpkt.dpkt.NeedData: # No LLC/SNAP—raw data payload, handle as needed pass if __name__ == "__main__": parse_wireless_pcap("your_wireless_capture.pcap")
Step 3: Handle Common Edge Cases
- Radiotap Header Variations: Some captures might have malformed or truncated Radiotap headers. The try/except block in the example handles this gracefully by falling back to direct 802.11 parsing.
- LLC/SNAP Encapsulation: Most IP-over-802.11 traffic uses LLC/SNAP, so the code checks for that to extract IP packets. If you’re dealing with raw 802.11 data frames (no encapsulation), you can skip this part.
- Upgrade dpkt: Make sure you’re on the latest version of dpkt—older versions might have incomplete 802.11 support. Run
pip install --upgrade dpktto update.
Final Checks
Before running the script, confirm your pcap is a valid wireless capture:
- Use
tcpdump -r your_capture.pcapand look for the line starting withLink-type IEEE802_11 (802.11)—this confirms it’s an 802.11 capture, not Ethernet.
内容的提问来源于stack exchange,提问作者Mengqi Wang

