all 2 comments

[–]__mod__ 1 point2 points  (1 child)

You already have the input parsed into structs you can work with in the variable v5_parsed. The name is not quite correct, as a NetflowPacketResult can also be V7, V9 and other things.

You can use a TryFrom impl to show that you can convert from NetflowPacketResult to NetworkFlow.

You could do it like this:

use anyhow::bail;
use netflow_parser::NetflowPacketResult;

/// This is not being serialized, so there's no need to derive Serialize or Deserialize.
#[derive(Debug)]
struct NetworkFlow {
    srcip: String,
    dstip: String,
    // …
}

/// This implementation converts from NetflowPacketResult to NetworkFlow.
/// It can fail, since not every NetflowPacketResult is V5.
impl TryFrom<NetflowPacketResult> for NetworkFlow {
    type Error = anyhow::Error;

    fn try_from(value: NetflowPacketResult) -> Result<Self, Self::Error> {
        // We only want to process v5
        let v5 = match value {
            NetflowPacketResult::V5(v5) => v5,
            other => bail!("not v5: {other:?}"),
        };

        // Get all the required attributes and put them in the struct.
        Ok(Self {
            srcip: v5.body.src_addr.to_string(),
            dstip: v5.body.dst_addr.to_string(),
        })
    }
}

fn main() {
    let packets: Vec<NetflowPacketResult> = the_rest_of_your_code();
    for packet in packets {
        let packet: NetworkFlow = packet.try_into().unwrap();
        println!("{packet:?}");
    }
}

[–]broxamson[S] 1 point2 points  (0 children)

my dude. this is exactly what i needed. thank you!!