crafter 0.3.2

Packet-level network interaction for Rust tools and agents.
Documentation
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 reply_matching --\n\nBuild synthetic request/reply pairs and test offline reply matching.",
    ) {
        return Ok(());
    }

    let icmp_request = Ipv4::new().src(local_ipv4()).dst(remote_ipv4()).id(0x4001)
        / Icmpv4::echo_request().id(0x4242).seq(1)
        / Raw::from("icmp");
    let icmp_reply = Ipv4::new().src(remote_ipv4()).dst(local_ipv4()).id(0x4002)
        / Icmpv4::echo_reply().id(0x4242).seq(1)
        / Raw::from("icmp");

    let tcp_request = Ipv4::new().src(local_ipv4()).dst(remote_ipv4()).id(0x4003)
        / Tcp::new()
            .sport(49152)
            .dport(443)
            .seq(100)
            .flags(TCP_FLAG_SYN);
    let tcp_reply = Ipv4::new().src(remote_ipv4()).dst(local_ipv4()).id(0x4004)
        / Tcp::new()
            .sport(443)
            .dport(49152)
            .seq(200)
            .ack(101)
            .flags(TCP_FLAG_SYN | TCP_FLAG_ACK);

    println!("example: reply_matching");
    println!("mode: offline");
    print_match("icmp", &icmp_request, &icmp_reply);
    print_match("tcp", &tcp_request, &tcp_reply);

    Ok(())
}

fn print_match(label: &str, request: &Packet, reply: &Packet) {
    println!("{label} request: {}", request.summary());
    println!(
        "{label} reply filter: {}",
        reply_filter(request).unwrap_or_default()
    );
    println!("{label} reply: {}", reply.summary());
    println!("{label} reply matches: {}", reply_matches(request, reply));
}