I am reading USBPcap files created in Wireshark with large, isochronous packets up to 494439 bytes. I am then trying to parse the packets in python with scapy. Unfortunately, scapy 2.4.3 defaults to ignoring bytes past the 65535th byte for packets greater than 65535 bytes.
Is there a way to read packets larger than 65535 bytes?
In order to instruct scapy to read packets larger than 65535 bytes, you must read packets one at a time off the many pcap reading generators found in scapy.utils API. Specifically, the following classes within scapy.utils
support reading large packets from a pcap or pcapng file:
class scapy.utils.PcapReader(filename)
class scapy.utils.PcapNgReader(filename)
class scapy.utils.RawPcapReader(filename)
class scapy.utils.RawPcapNgReader(filename)
Note that scapy.utils.rdpcap(filename, count=- 1)
does not support this functionality.
My solution:
from scapy.all import *
packet_reader = RawPcapNgReader('my_pcapng_file.pcapng')
while True:
try:
# created my own usb_packet class to parse packet header on __init__
p = usb_packet(packet_reader.read_packet(size=500000)) # read packet up to 500 kB large
if p.filter(): # filter packets based on usb_packet custom filter method
print(len(p.hex_str), len(p.data_packets)) # do stuff to the filtered packets
except EOFError:
break
For capturing packets via sniff
or similar, one might set the buffer size via class scapy.config.Conf.bufsize
which defaults to 65536 to allow a 65535 byte packet to be captured (see docs). For pragmatic programming, one may set this configuration when reading pcaps as well rather than maintaining the size
argument wherever read_packet()
is called on a generator.
An interesting note: This default appears to be due to IPv4 packet structure in which the packet length is represented by a 16 bit number. In other words, the largest packet this header value can depict is 1111111111111111
bytes, or 2^16=65536. Counting from zero, we have the largest IPv4 packet being 65535 bytes. For USB, as in my case, larger packets are possible.