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 snmp_get --\n\nBuild SNMPv1 and SNMPv2c GetRequest packets, then decode them offline.",
    ) {
        return Ok(());
    }

    inspect_get(
        "snmpv1 get-request",
        49_161,
        Snmp::v1_get_request(b"doc-community".to_vec(), 1, sys_descr_request()?)?,
    )?;
    inspect_get(
        "snmpv2c get-request",
        49_162,
        Snmp::v2c_get_request(b"doc-community".to_vec(), 2, sys_descr_request()?)?,
    )?;

    Ok(())
}

fn sys_descr_request() -> crafter::Result<SnmpVarBindList> {
    Ok(SnmpVarBindList::new(vec![SnmpVarBind::null(
        SnmpOid::from_dotted("1.3.6.1.2.1.1.1.0")?,
    )]))
}

fn inspect_get(label: &str, sport: u16, snmp: Snmp) -> ExampleResult<()> {
    let packet = Ipv4::new()
        .src(local_ipv4())
        .dst(remote_ipv4())
        .id(sport)
        .ipv4_protocol(Ipv4Protocol::Udp)
        / Udp::new().sport(sport).dport(SNMP_PORT)
        / snmp;
    let bytes = packet.compile()?;
    let decoded = Packet::decode_from_l3(NetworkLayer::Ipv4, bytes.as_bytes())?;

    println!("packet: {label}");
    println!("mode: offline");
    println!("constructed summary: {}", packet.summary());
    println!("decoded summary: {}", decoded.summary());
    println!("decoded show:\n{}", decoded.show());
    println!("hexdump:\n{}", bytes.hexdump());

    Ok(())
}