Search code examples
pythonscapy

Read/capture packets larger than 65535 bytes with scapy


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?


Solution

  • 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:

    1. class scapy.utils.PcapReader(filename)
    2. class scapy.utils.PcapNgReader(filename)
    3. class scapy.utils.RawPcapReader(filename)
    4. 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.