Introduction

The crate Logo

Packet Parser is a Rust library designed for parsing network frames.
This book explains how I developed it and its internal architecture, so you can contribute.

Key Features

  • Multi-layer support: parses the data link, internet, transport and application layers.
  • Zero-copy: the result, PacketFlow, borrows the input buffer. No payload is copied.
  • Fail-closed on the link layer: the LINKTYPE is given by the caller, never guessed from the bytes. An unsupported LINKTYPE is an error.
  • Fail-soft above it: an unknown or malformed upper layer does not fail the whole parse. The layer stays None, and a recognized-but-invalid layer is reported in corrupted.
  • Data validation: every protocol struct is built through TryFrom, with its checks in a dedicated module.
  • Precise error management: each layer and each protocol has its own error type, built with thiserror.
  • No panic on hostile bytes: unwrap, expect and panic! are denied by lints in production code, and the parsers are fuzzed.
  • Tunnels: CAPWAP, GRE, IP-in-IP, VXLAN and Geneve are peeled, and the inner packet is parsed recursively.
  • Extensibility: a modular architecture that makes adding a protocol a mechanical job.

Purpose of this crate

The goal of this crate is to provide a function that transforms a packet, or a list of bytes to be more precise, into a typed structure, or into an error if you are getting fooled and receive incoherent bytes.

  • You can provide a full network packet with its LINKTYPE, and parse returns a PacketFlow: a structured representation containing the data link, internet, transport and application layers.
  • It is not restricted to a specific layer: every protocol struct implements TryFrom<&[u8]>. You can pass a TCP payload to TlsPacket::try_from, DnsPacket::try_from, NtpPacket::try_from... and get the detailed structure of that protocol.

To explain how I made this crate, let's dive into packet parsing, my passion.

  1. First we get started with the public API.
  2. Then we have to know what I call a packet, because that is what we are starting from, and what the PacketFlow struct looks like once the packet is parsed.
  3. Then we'll see the data validation procedure I use for every struct in this crate: TryFrom.
  4. Then we go down layer by layer: data link, internet, transport, application and tunnels.
  5. And finally, how to add a new protocol.