mod common;
use common::{local_ipv4, print_help_if_requested, remote_ipv4, ExampleResult};
use crafter::prelude::*;
fn main() -> ExampleResult<()> {
if print_help_if_requested(
"usage: cargo run --example custom_registry --\n\nDecode generated bytes with a local ProtocolRegistry binding.",
) {
return Ok(());
}
let packet = Ipv4::new()
.src(local_ipv4())
.dst(remote_ipv4())
.ipv4_protocol(Ipv4Protocol::Udp)
/ Udp::new().sport(53000).dport(DNS_PORT)
/ Dns::a_query("example.com.").id(0x4242);
let bytes = packet.compile()?;
let default_decoded = Packet::decode_from_l3(NetworkLayer::Ipv4, bytes.as_bytes())?;
let mut registry = ProtocolRegistry::new();
registry.bind_udp_port(DNS_PORT, |packet, payload| {
Ok(packet.push(Raw::from_bytes(payload)))
});
let custom_decoded =
Packet::decode_from_l3_with_registry(®istry, NetworkLayer::Ipv4, bytes.as_bytes())?;
let raw = custom_decoded
.layer::<Raw>()
.expect("custom DNS port binding should preserve payload as Raw");
assert!(default_decoded.layer::<Dns>().is_some());
assert!(custom_decoded.layer::<Dns>().is_none());
println!("mode: offline");
println!("default registry summary: {}", default_decoded.summary());
println!("custom registry summary: {}", custom_decoded.summary());
println!("custom raw bytes: {}", raw.len());
println!("hexdump:\n{}", bytes.hexdump());
Ok(())
}