pcap-frame-parser 0.1.0

Zero-copy parser for legacy PCAP and PCAPng capture files, plus Ethernet/VLAN/IP/UDP/TCP frame dissection. No libpcap dependency.
Documentation
  • Coverage
  • 46.15%
    18 out of 39 items documented1 out of 15 items with examples
  • Size
  • Source code size: 44.43 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 649.46 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 7s Average build duration of successful builds.
  • all releases: 6s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • casablanque-code/pcap-frame-parser
    1 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • casablanque-code

pcap-frame-parser

A small, dependency-light Rust parser for network capture files and the frames inside them — no libpcap/npcap linkage, no unsafe.

It handles two things:

  1. Capture containers — legacy PCAP and PCAPng, extracting the raw captured frames and their timestamps.
  2. Frame dissection — Ethernet II, an optional single 802.1Q VLAN tag, optional double-tagged 802.1ad "Q-in-Q" framing, IPv4, and UDP/TCP, down to the transport-layer payload.

It stops at the transport payload on purpose: this crate doesn't know or care whether that payload is DNS, DHCP, OSPF, or something else — that's for a protocol-specific parser built on top.

Extracted from a series of protocol-forensics tools (dns-postmortem, ospf-postmortem, dhcp-postmortem, stp-postmortem) where this exact parsing logic had been duplicated four times.

Scope

Supported Not supported
Legacy PCAP Live capture
PCAPng (SHB/IDB/EPB/OPB/SPB blocks) Writing capture files
Ethernet II IPv6
Untagged / 802.1Q / 802.1ad Q-in-Q Other link-layer types (only LINKTYPE_ETHERNET is handled)
IPv4, UDP, TCP IP fragmentation reassembly

If you need any of the "not supported" column, this crate isn't the right layer for it — pair it with something like pnet or etherparse instead, or reassemble fragments before handing frames to this crate.

Example

use pcap_frame_parser::{pcap, ethernet};

let capture_bytes: &[u8] = /* contents of a .pcap file */
    # &[0xd4,0xc3,0xb2,0xa1,2,0,4,0,0,0,0,0,0,0,0,0,0xff,0xff,0,0,1,0,0,0];

let (_header, packets) = pcap::iter_packets(capture_bytes)?;

for packet in &packets {
    let Some((ip_header, ip_payload)) = ethernet::extract_ip(packet.data) else { continue };

    if ip_header.protocol == ethernet::PROTO_UDP {
        if let Some((src_port, dst_port, payload)) = ethernet::extract_udp(ip_payload) {
            println!("{} -> {}: {} bytes", src_port, dst_port, payload.len());
        }
    }
}
# Ok::<(), String>(())

For PCAPng files, use pcapng::parse_pcapng(bytes) instead, which returns Vec<(ts_sec, ts_usec, frame_bytes)>.

Why not pcap-parser / pnet / etc.?

Those are fine, more complete crates if you need broader protocol coverage or live capture. This crate is intentionally narrow: it's the exact slice of parsing — PCAP/PCAPng container plus Ethernet/VLAN/IP/UDP/TCP dissection — that a forensics or analysis tool typically needs before handing off to its own protocol-specific logic, with no unnecessary dependencies pulled in.

License

MIT