{"id":48755328,"url":"https://github.com/higebu/packet-dissector","last_synced_at":"2026-06-12T01:01:44.746Z","repository":{"id":348286979,"uuid":"1197378560","full_name":"higebu/packet-dissector","owner":"higebu","description":"A Rust crate for layered network packet parsing with registry-based protocol chaining.","archived":false,"fork":false,"pushed_at":"2026-06-05T05:46:16.000Z","size":1168,"stargazers_count":2,"open_issues_count":11,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-05T07:35:05.713Z","etag":null,"topics":["networking","packet-analysis","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/higebu.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-31T14:34:03.000Z","updated_at":"2026-04-29T23:15:36.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/higebu/packet-dissector","commit_stats":null,"previous_names":["higebu/packet-dissector"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/higebu/packet-dissector","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/higebu%2Fpacket-dissector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/higebu%2Fpacket-dissector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/higebu%2Fpacket-dissector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/higebu%2Fpacket-dissector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/higebu","download_url":"https://codeload.github.com/higebu/packet-dissector/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/higebu%2Fpacket-dissector/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34224103,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-11T02:00:06.485Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["networking","packet-analysis","rust"],"created_at":"2026-04-13T01:30:42.950Z","updated_at":"2026-06-12T01:01:44.699Z","avatar_url":"https://github.com/higebu.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# packet-dissector\n\nA Rust crate for layered network packet parsing with registry-based protocol chaining.\n\n[![CI](https://github.com/higebu/packet-dissector/actions/workflows/ci.yml/badge.svg)](https://github.com/higebu/packet-dissector/actions/workflows/ci.yml)\n[![Crates.io](https://img.shields.io/crates/v/packet-dissector.svg)](https://crates.io/crates/packet-dissector)\n[![docs.rs](https://docs.rs/packet-dissector/badge.svg)](https://docs.rs/packet-dissector)\n\n## Installation\n\nAdd to your `Cargo.toml`:\n\n```toml\n[dependencies]\npacket-dissector = \"0.3\"\n```\n\n## Features\n\n- **Zero-copy on the normal path** — dissectors borrow directly from `\u0026[u8]` slices when parsing a single packet; TCP reassembly and decrypted-payload paths copy into auxiliary storage\n- **Extensible** — add new protocols by implementing the `Dissector` trait\n- **Layered dissection** — automatic chaining from Ethernet through IP, TCP/UDP, to application protocols\n- **Safe Rust** — minimal `unsafe` in the registry only, documented with `// SAFETY:` comments\n- **Modular** — enable only the protocols you need via feature flags\n\n## Supported Protocols\n\nThe set of built-in dissectors is feature-gated and keeps growing. Representative\nprotocols include:\n\n| Category | Protocols |\n|----------|-----------|\n| L2 | Ethernet II, Linux SLL, Linux SLL2, 802.1Q VLAN, 802.1ad QinQ (up to 2 VLAN tags), ARP, LACP, LLDP, STP |\n| L3 / routing | IPv4, IPv6, IPv6 extension headers (Hop-by-Hop, Routing, Fragment, Destination Options, Mobility), ICMP, ICMPv6, IGMP, OSPF, VRRP, IS-IS, AH, ESP, SRv6, GRE, MPLS |\n| L4 / tunneling | TCP, UDP, SCTP, L2TP, L2TPv3, GENEVE, VXLAN |\n| Application / control | DNS, mDNS, DHCP, DHCPv6, HTTP/1.1, HTTP/2, SIP, Diameter, NTP, BFD, BGP, TLS, PPP, RADIUS, RTP, QUIC, STUN |\n| 3GPP | GTPv1-U, GTPv2-C, PFCP, NAS5G, NGAP |\n\nSee `crates/packet-dissector/Cargo.toml` and `crates/packet-dissector/src/lib.rs`\nfor the current feature-gated protocol list.\n\n## Feature Flags\n\nAll built-in dissectors are enabled by default. Disable `default-features` to\nselect only what you need:\n\n```toml\n# All protocols (default)\npacket-dissector = \"0.3\"\n\n# Only Ethernet + IPv4 + TCP\npacket-dissector = { version = \"0.3\", default-features = false, features = [\"ethernet\", \"ipv4\", \"tcp\"] }\n\n# Convenience groups\npacket-dissector = { version = \"0.3\", default-features = false, features = [\"layer2\", \"layer3\", \"layer4\"] }\n```\n\nRepresentative feature flags:\n\n- Link layer: `ethernet`, `linux_sll`, `linux_sll2`, `arp`, `lacp`, `lldp`, `stp`\n- Network / routing: `ipv4`, `ipv6`, `icmp`, `icmpv6`, `igmp`, `ospf`, `vrrp`, `isis`, `ah`, `esp`, `ike`, `srv6`, `gre`, `mpls`\n- Transport / tunneling: `tcp`, `udp`, `sctp`, `l2tp`, `l2tpv3`, `geneve`, `vxlan`\n- Application / control: `dns`, `mdns`, `dhcp`, `dhcpv6`, `http`, `http2`, `sip`, `diameter`, `ntp`, `bfd`, `bgp`, `tls`, `ppp`, `radius`, `rtp`, `quic`, `stun`\n- 3GPP: `gtpv1u`, `gtpv2c`, `pfcp`, `nas5g`, `ngap`\n- `esp-decrypt` enables ESP payload decryption support\n\nConvenience groups:\n\n- `layer2 = [\"ethernet\", \"linux_sll\", \"linux_sll2\", \"arp\", \"lacp\", \"lldp\", \"stp\", \"ppp\"]`\n- `layer3 = [\"ipv4\", \"ipv6\", \"icmp\", \"icmpv6\", \"igmp\", \"srv6\"]`\n- `layer4 = [\"tcp\", \"udp\", \"sctp\"]`\n- `application = [\"dns\", \"mdns\", \"dhcp\", \"dhcpv6\", \"http\", \"http2\", \"sip\", \"diameter\", \"ntp\", \"radius\", \"rtp\", \"tls\", \"quic\", \"stun\"]`\n- `tunneling = [\"gre\", \"geneve\", \"vxlan\", \"l2tp\", \"l2tpv3\", \"mpls\"]`\n- `routing = [\"ospf\", \"isis\", \"bgp\", \"bfd\", \"vrrp\"]`\n- `ipsec = [\"ah\", \"esp\", \"ike\"]`\n- `3gpp = [\"gtpv1u\", \"gtpv2c\", \"pfcp\", \"nas5g\", \"ngap\"]`\n\nFor the authoritative, exhaustive list, see\n`crates/packet-dissector/Cargo.toml`.\n\n## Quick Start\n\n```rust\nuse packet_dissector::registry::DissectorRegistry;\nuse packet_dissector::packet::DissectBuffer;\nuse packet_dissector::field::FieldValue;\n\n// Build a registry with all built-in dissectors\nlet registry = DissectorRegistry::default();\n\n// An Ethernet + IPv4 + UDP packet (minimal example)\nlet packet_bytes: \u0026[u8] = \u0026[\n    // Ethernet header (14 bytes)\n    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // dst MAC\n    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // src MAC\n    0x08, 0x00,                         // EtherType: IPv4\n    // IPv4 header (20 bytes)\n    0x45, 0x00, 0x00, 0x1c,             // ver, ihl, len=28\n    0x00, 0x00, 0x00, 0x00,             // id, flags, frag\n    0x40, 0x11, 0x00, 0x00,             // ttl=64, proto=UDP, checksum\n    0x0a, 0x00, 0x00, 0x01,             // src: 10.0.0.1\n    0x0a, 0x00, 0x00, 0x02,             // dst: 10.0.0.2\n    // UDP header (8 bytes)\n    0x30, 0x39, 0x00, 0x50,             // src=12345, dst=80\n    0x00, 0x08, 0x00, 0x00,             // len=8, checksum\n];\n\nlet mut buf = DissectBuffer::new();\nregistry.dissect(packet_bytes, \u0026mut buf).unwrap();\n\nassert_eq!(buf.layers.len(), 3); // Ethernet, IPv4, UDP\nassert_eq!(buf.layers[0].name, \"Ethernet\");\nassert_eq!(buf.layers[1].name, \"IPv4\");\nassert_eq!(buf.layers[2].name, \"UDP\");\n\nlet udp = buf.layer_by_name(\"UDP\").unwrap();\nlet src_port = buf.field_by_name(udp, \"src_port\").unwrap();\nassert_eq!(src_port.value, FieldValue::U16(12345));\n```\n\n## Adding a Custom Dissector\n\nImplement the `Dissector` trait and register it. For external crates, depend on\n`packet-dissector-core` for the trait and types:\n\n```rust\nuse packet_dissector_core::dissector::{Dissector, DissectResult, DispatchHint};\nuse packet_dissector_core::error::PacketError;\nuse packet_dissector_core::field::FieldDescriptor;\nuse packet_dissector_core::packet::DissectBuffer;\n\nstruct MyProtocol;\n\nimpl Dissector for MyProtocol {\n    fn name(\u0026self) -\u003e \u0026'static str { \"MyProtocol\" }\n    fn short_name(\u0026self) -\u003e \u0026'static str { \"myproto\" }\n    fn field_descriptors(\u0026self) -\u003e \u0026'static [FieldDescriptor] { \u0026[] }\n\n    fn dissect\u003c'pkt\u003e(\n        \u0026self,\n        data: \u0026'pkt [u8],\n        buf: \u0026mut DissectBuffer\u003c'pkt\u003e,\n        offset: usize,\n    ) -\u003e Result\u003cDissectResult, PacketError\u003e {\n        let _ = (buf, offset);\n        Ok(DissectResult::new(data.len(), DispatchHint::End))\n    }\n}\n```\n\n## Testing\n\nFour complementary test layers run in CI:\n\n- **Unit tests** — per-protocol example-based tests inside each\n  `packet-dissector-\u003cprotocol\u003e` crate.\n- **Integration tests** — multi-layer dissection through `DissectorRegistry`\n  in `crates/packet-dissector/tests/`.\n- **Allocation tests** — `packet-dissector-test-alloc` verifies zero heap\n  allocations during dissection.\n- **Property-based tests** — `packet-dissector-pbt` uses `proptest` to check\n  universal parser invariants (no panic, `bytes_consumed ≤ data.len()`,\n  `Truncated.actual == data.len()`, determinism) across arbitrary and\n  structured inputs. Run with `cargo test -p packet-dissector-pbt`, or\n  `PROPTEST_CASES=10000 cargo test -p packet-dissector-pbt` for long runs.\n  Shrunk counter-examples are written to `proptest-regressions/` and\n  committed for reproducibility.\n\n## Documentation\n\nFull API documentation is available on [docs.rs](https://docs.rs/packet-dissector).\n\nSee `crates/packet-dissector/examples/` for runnable examples:\n\n- **parse_packet** — parse a raw packet and inspect layers/fields\n- **custom_dissector** — implement and register a custom protocol dissector\n\n## License\n\nLicensed under either of\n\n- [Apache License, Version 2.0](LICENSE-APACHE)\n- [MIT License](LICENSE-MIT)\n\nat your option.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhigebu%2Fpacket-dissector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhigebu%2Fpacket-dissector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhigebu%2Fpacket-dissector/lists"}