{"id":15031601,"url":"https://github.com/alexforster/pdu","last_synced_at":"2025-11-08T14:05:13.575Z","repository":{"id":45560983,"uuid":"226204366","full_name":"alexforster/pdu","owner":"alexforster","description":"Small, fast, and correct L2/L3/L4 packet parser.","archived":false,"fork":false,"pushed_at":"2023-10-27T15:52:13.000Z","size":115,"stargazers_count":59,"open_issues_count":5,"forks_count":9,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-29T15:05:21.616Z","etag":null,"topics":["parser","rust","rustlang"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/pdu","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/alexforster.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2019-12-05T23:03:21.000Z","updated_at":"2025-01-13T13:54:20.000Z","dependencies_parsed_at":"2025-01-09T15:47:32.494Z","dependency_job_id":"5a9fa10e-79d2-462e-b19d-8199c3107b72","html_url":"https://github.com/alexforster/pdu","commit_stats":{"total_commits":38,"total_committers":2,"mean_commits":19.0,"dds":"0.42105263157894735","last_synced_commit":"bc7092583f10c648d93fc5fd905b985982faa990"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexforster%2Fpdu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexforster%2Fpdu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexforster%2Fpdu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexforster%2Fpdu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexforster","download_url":"https://codeload.github.com/alexforster/pdu/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252902676,"owners_count":21822274,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["parser","rust","rustlang"],"created_at":"2024-09-24T20:16:09.697Z","updated_at":"2025-11-08T14:05:13.535Z","avatar_url":"https://github.com/alexforster.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pdu\n\nSmall, fast, and correct L2/L3/L4 packet parser.\n\n**Author:** Alex Forster \\\u003calex@alexforster.com\\\u003e\u003cbr/\u003e\n**License:** Apache-2.0\n\n[![build status](https://travis-ci.org/alexforster/pdu.svg?branch=master)](https://travis-ci.org/alexforster/pdu)\n[![crates.io version](https://img.shields.io/crates/v/pdu.svg)](https://crates.io/crates/pdu)\n[![docs.rs](https://docs.rs/pdu/badge.svg)](https://docs.rs/pdu)\n\n#### Small\n\n * Fully-featured `no_std` support\n * No Crate dependencies and no macros\n * Internet protocols only: application-layer protocols are out of scope\n\n#### Fast\n\n * Lazy parsing: only the fields that you access are parsed\n * Zero-copy construction: no heap allocations are performed\n\n#### Correct\n\n * Tested against [Wireshark](https://www.wireshark.org/docs/man-pages/tshark.html) to ensure all packet fields are parsed correctly\n * Fuzzed using [Honggfuzz](https://github.com/google/honggfuzz) to ensure invalid input does not cause panics\n * Does not use any `unsafe` code\n\n## Supported Protocols\n\nThe following protocol hierarchy can be parsed with this library:\n\n * Ethernet (including vlan)\n   * ARP\n   * IPv4 (including options)\n     * TCP (including options)\n     * UDP\n     * ICMP\n     * GREv0\n       * ...Ethernet, IPv4, IPv6...\n   * IPv6 (including extension headers)\n     * TCP (including options)\n     * UDP\n     * ICMPv6\n     * GREv0\n       * ...Ethernet, IPv4, IPv6...\n\nIn addition, unrecognized upper protocols are accessible as bytes via `Raw`\nenum variants.\n\n## Getting Started\n\n#### `Cargo.toml`\n\n```toml\n[dependencies]\npdu = \"1.1\"\n```\n\n#### Examples\n\n```rust\nuse pdu::*;\n\n// parse a layer 2 (Ethernet) packet using EthernetPdu::new()\n\nfn main() {\n    let packet: \u0026[u8] = \u0026[\n        0x68, 0x5b, 0x35, 0xc0, 0x61, 0xb6, 0x00, 0x1d, 0x09, 0x94, 0x65, 0x38, 0x08, 0x00, 0x45, 0x00, 0x00,\n        0x3b, 0x2d, 0xfd, 0x00, 0x00, 0x40, 0x11, 0xbc, 0x43, 0x83, 0xb3, 0xc4, 0x2e, 0x83, 0xb3, 0xc4, 0xdc,\n        0x18, 0xdb, 0x18, 0xdb, 0x00, 0x27, 0xe0, 0x3e, 0x05, 0x1d, 0x07, 0x15, 0x08, 0x07, 0x65, 0x78, 0x61,\n        0x6d, 0x70, 0x6c, 0x65, 0x08, 0x07, 0x74, 0x65, 0x73, 0x74, 0x41, 0x70, 0x70, 0x08, 0x01, 0x31, 0x0a,\n        0x04, 0x1e, 0xcc, 0xe2, 0x51,\n    ];\n    \n    match EthernetPdu::new(\u0026packet) {\n        Ok(ethernet_pdu) =\u003e {\n            println!(\"[ethernet] destination_address: {:x?}\", ethernet_pdu.destination_address().as_ref());\n            println!(\"[ethernet] source_address: {:x?}\", ethernet_pdu.source_address().as_ref());\n            println!(\"[ethernet] ethertype: 0x{:04x}\", ethernet_pdu.ethertype());\n            if let Some(vlan) = ethernet_pdu.vlan() {\n                println!(\"[ethernet] vlan: 0x{:04x}\", vlan);\n            }\n            // upper-layer protocols can be accessed via the inner() method\n            match ethernet_pdu.inner() {\n                Ok(Ethernet::Ipv4(ipv4_pdu)) =\u003e {\n                    println!(\"[ipv4] source_address: {:x?}\", ipv4_pdu.source_address().as_ref());\n                    println!(\"[ipv4] destination_address: {:x?}\", ipv4_pdu.destination_address().as_ref());\n                    println!(\"[ipv4] protocol: 0x{:02x}\", ipv4_pdu.protocol());\n                    // upper-layer protocols can be accessed via the inner() method (not shown)\n                }\n                Ok(Ethernet::Ipv6(ipv6_pdu)) =\u003e {\n                    println!(\"[ipv6] source_address: {:x?}\", ipv6_pdu.source_address().as_ref());\n                    println!(\"[ipv6] destination_address: {:x?}\", ipv6_pdu.destination_address().as_ref());\n                    println!(\"[ipv6] protocol: 0x{:02x}\", ipv6_pdu.computed_protocol());\n                    // upper-layer protocols can be accessed via the inner() method (not shown)\n                }\n                Ok(other) =\u003e {\n                    panic!(\"Unexpected protocol {:?}\", other);\n                }\n                Err(e) =\u003e {\n                    panic!(\"EthernetPdu::inner() parser failure: {:?}\", e);\n                }\n            }\n        }\n        Err(e) =\u003e {\n            panic!(\"EthernetPdu::new() parser failure: {:?}\", e);\n        }\n    }\n}\n```\n\n```rust\nuse pdu::*;\n\n// parse a layer 3 (IP) packet using Ip::new()\n\nfn main() {\n    let packet: \u0026[u8] = \u0026[\n        0x45, 0x00, 0x00, 0x3b, 0x2d, 0xfd, 0x00, 0x00, 0x40, 0x11, 0xbc, 0x43, 0x83, 0xb3, 0xc4, 0x2e, 0x83, 0xb3,\n        0xc4, 0xdc, 0x18, 0xdb, 0x18, 0xdb, 0x00, 0x27, 0xe0, 0x3e, 0x05, 0x1d, 0x07, 0x15, 0x08, 0x07, 0x65, 0x78,\n        0x61, 0x6d, 0x70, 0x6c, 0x65, 0x08, 0x07, 0x74, 0x65, 0x73, 0x74, 0x41, 0x70, 0x70, 0x08, 0x01, 0x31, 0x0a,\n        0x04, 0x1e, 0xcc, 0xe2, 0x51,\n    ];\n\n    match Ip::new(\u0026packet) {\n        Ok(Ip::Ipv4(ipv4_pdu)) =\u003e {\n            println!(\"[ipv4] source_address: {:x?}\", ipv4_pdu.source_address().as_ref());\n            println!(\"[ipv4] destination_address: {:x?}\", ipv4_pdu.destination_address().as_ref());\n            println!(\"[ipv4] protocol: 0x{:02x}\", ipv4_pdu.protocol());\n            // upper-layer protocols can be accessed via the inner() method (not shown)\n        }\n        Ok(Ip::Ipv6(ipv6_pdu)) =\u003e {\n            println!(\"[ipv6] source_address: {:x?}\", ipv6_pdu.source_address().as_ref());\n            println!(\"[ipv6] destination_address: {:x?}\", ipv6_pdu.destination_address().as_ref());\n            println!(\"[ipv6] protocol: 0x{:02x}\", ipv6_pdu.computed_protocol());\n            // upper-layer protocols can be accessed via the inner() method (not shown)\n        }\n        Err(e) =\u003e {\n            panic!(\"Ip::new() parser failure: {:?}\", e);\n        }\n    }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexforster%2Fpdu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexforster%2Fpdu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexforster%2Fpdu/lists"}