crafter 0.3.2

Packet-level network interaction for Rust tools and agents.
Documentation
mod common;

use common::{
    arg_or, live_mode, local_ipv4, parse_ipv4_arg, parse_u16_arg, print_help_if_requested,
    remote_ipv4, send_recv_options, ExampleResult, ADVANCED_LIVE_ACK_FLAG, EXAMPLE_IFACE,
    LIVE_WIRE_ENV,
};
use crafter::prelude::*;

fn main() -> ExampleResult<()> {
    if print_help_if_requested(&format!(
        "usage: cargo run -p crafter --example network_ping -- [--live] [--iface IFACE] [--src IP] [--dst IP] [--id ID] [--seq SEQ]\n\nSend one IPv4 ICMP echo request with network-layer send/receive. Live traffic requires --live, {ADVANCED_LIVE_ACK_FLAG}, and {LIVE_WIRE_ENV}=1."
    )) {
        return Ok(());
    }

    let live = live_mode("network_ping")?;
    let iface = arg_or("--iface", EXAMPLE_IFACE);
    let src = parse_ipv4_arg("--src", local_ipv4())?;
    let dst = parse_ipv4_arg("--dst", remote_ipv4())?;
    let icmp_id = parse_u16_arg("--id", 0x4242)?;
    let icmp_seq = parse_u16_arg("--seq", 1)?;

    let packet = Ipv4::new().src(src).dst(dst).id(0x4001).dont_fragment(true)
        / Icmpv4::echo_request().id(icmp_id).seq(icmp_seq)
        / Raw::from("network-ping");
    let report = packet.send_recv_report(send_recv_options(&iface, live, false))?;

    println!("iface={iface}");
    println!("src={src}");
    println!("dst={dst}");
    println!("icmp_id={icmp_id}");
    println!("icmp_seq={icmp_seq}");
    println!("attempts: {}", report.attempts());
    println!("timed out: {}", report.timed_out());
    println!(
        "effective filter: {}",
        report.effective_filter().unwrap_or("")
    );
    match report.reply() {
        Some(reply) => println!("reply: {}", reply.summary()),
        None => println!("reply: none"),
    }

    Ok(())
}