crafter 0.3.2

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

use common::{
    arg_or, live_mode, local_ipv4, local_mac, print_advanced_safety, print_help_if_requested,
    print_send_report, remote_ipv4, remote_mac, ExampleResult, EXAMPLE_IFACE,
};
use crafter::prelude::*;

fn main() -> ExampleResult<()> {
    if print_help_if_requested(
        "usage: cargo run --example send_packet -- [--live] [--iface IFACE]\n\nBuild network-layer and link-layer packets and send them in dry-run mode by default.",
    ) {
        return Ok(());
    }

    let live = live_mode("send_packet")?;
    let iface = arg_or("--iface", EXAMPLE_IFACE);
    let network_packet = Ipv4::new().src(local_ipv4()).dst(remote_ipv4()).id(0x2001)
        / Udp::new().sport(49152).dport(33434)
        / Raw::from("network-layer");
    let link_packet = Ethernet::new()
        .src(local_mac())
        .dst(remote_mac())
        .ethertype(ETHERTYPE_IPV4)
        / Ipv4::new().src(local_ipv4()).dst(remote_ipv4()).id(0x2002)
        / Tcp::new()
            .sport(49153)
            .dport(80)
            .seq(0x0102_0304)
            .flags(TCP_FLAG_SYN)
        / Raw::from("link-layer");

    print_advanced_safety("send_packet", live);

    let network_options = if live {
        SendOptions::new().iface(&iface).network_layer().live()
    } else {
        SendOptions::new().iface(&iface).network_layer().dry_run()
    };
    let network_report = send_packet(&network_packet, network_options)?;
    print_send_report(
        "send_packet network-layer",
        &network_packet,
        &network_report,
    );

    let link_options = if live {
        SendOptions::new().iface(&iface).link_layer().live()
    } else {
        SendOptions::new().iface(&iface).link_layer().dry_run()
    };
    let link_report = send_packet(&link_packet, link_options)?;
    print_send_report("send_packet link-layer", &link_packet, &link_report);

    Ok(())
}