Skip to main content

Crate flowparser_sflow

Crate flowparser_sflow 

Source
Expand description

§flowparser-sflow

Rust License: MIT OR Apache-2.0

An sFlow v5 parser library written in Rust. Parses sFlow v5 datagrams (sFlow v5 specification) including flow samples, counter samples, and all standard record types.

§Features

  • sFlow v5 datagram parsing with IPv4 and IPv6 agent addresses
  • All four sample types: Flow Sample, Counter Sample, Expanded Flow Sample, Expanded Counter Sample
  • Flow record types: Raw Packet Header, Sampled Ethernet, Sampled IPv4/IPv6, Extended Switch, Extended Router, Extended Gateway, Extended User, Extended URL
  • Counter record types: Generic Interface, Ethernet Interface, Token Ring, VLAN, Processor
  • Unknown record handling: Unrecognized records captured as raw bytes for forward compatibility
  • Serde support: All types serialize/deserialize to JSON and other formats
  • Builder pattern: Optional configuration (e.g., max samples limit for DoS protection)

§Usage

Add to your Cargo.toml:

[dependencies]
flowparser-sflow = "0.1.0"

§Basic Parsing

use flowparser_sflow::{SflowParser, SflowSample};

let parser = SflowParser::default();

// Parse sFlow datagram bytes (e.g., received from UDP socket)
let result = parser.parse_bytes(&datagram_bytes);

for datagram in &result.datagrams {
    println!(
        "Agent: {:?}, Seq: {}, Samples: {}",
        datagram.agent_address,
        datagram.sequence_number,
        datagram.samples.len()
    );

    for sample in &datagram.samples {
        match sample {
            SflowSample::Flow(fs) => {
                println!("  Flow sample: {} records", fs.records.len());
            }
            SflowSample::Counter(cs) => {
                println!("  Counter sample: {} records", cs.records.len());
            }
            _ => {}
        }
    }
}

if let Some(err) = &result.error {
    eprintln!("Parse error: {}", err);
}

§JSON Serialization

use flowparser_sflow::SflowParser;

let parser = SflowParser::default();
let result = parser.parse_bytes(&datagram_bytes);

// Serialize to JSON
let json = serde_json::to_string_pretty(&result.datagrams).unwrap();
println!("{}", json);

§Builder Configuration

use flowparser_sflow::SflowParser;

// Limit max samples per datagram (DoS protection)
let parser = SflowParser::builder()
    .with_max_samples(100)
    .build();

§UDP Listener Example

use flowparser_sflow::SflowParser;
use std::net::UdpSocket;

let socket = UdpSocket::bind("0.0.0.0:6343").unwrap();
let parser = SflowParser::default();
let mut buf = [0u8; 65535];

loop {
    let (size, src) = socket.recv_from(&mut buf).unwrap();
    let result = parser.parse_bytes(&buf[..size]);
    for datagram in &result.datagrams {
        println!("From {}: {} samples", src, datagram.samples.len());
    }
}

§sFlow v5 Protocol Structure

Datagram
├── Header (version, agent address, sub-agent ID, sequence, uptime)
└── Samples[]
    ├── Flow Sample (enterprise=0, format=1)
    │   └── Flow Records[]
    │       ├── Raw Packet Header (0:1)
    │       ├── Sampled Ethernet (0:2)
    │       ├── Sampled IPv4 (0:3)
    │       ├── Sampled IPv6 (0:4)
    │       ├── Extended Switch (0:1001)
    │       ├── Extended Router (0:1002)
    │       ├── Extended Gateway (0:1003)
    │       ├── Extended User (0:1004)
    │       └── Extended URL (0:1005)
    ├── Counter Sample (enterprise=0, format=2)
    │   └── Counter Records[]
    │       ├── Generic Interface (0:1)
    │       ├── Ethernet Interface (0:2)
    │       ├── Token Ring (0:3)
    │       ├── VLAN (0:5)
    │       └── Processor (0:1001)
    ├── Expanded Flow Sample (enterprise=0, format=3)
    └── Expanded Counter Sample (enterprise=0, format=4)

§Types

TypeDescription
SflowParserMain parser with optional configuration
SflowDatagramParsed datagram with header fields and samples
SflowSampleEnum: Flow, Counter, ExpandedFlow, ExpandedCounter, Unknown
FlowRecordEnum of all flow record types
CounterRecordEnum of all counter record types
AddressTypeIPv4 or IPv6 agent address
ParseResultContains parsed datagrams and optional error
SflowErrorError variants: Incomplete, UnsupportedVersion, ParseError, TooManySamples

§Examples

Run the included examples:

# Single-threaded UDP listener
cargo run --example sflow_udp_listener_single_threaded

# Multi-threaded UDP listener
cargo run --example sflow_udp_listener_multi_threaded

# Async (tokio) UDP listener
cargo run --example sflow_udp_listener_tokio

# Parse from pcap file
cargo run --example sflow_pcap -- <file.pcap>

§Benchmarks

cargo bench

§License

Licensed under either of:

  • Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
  • MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)

at your option.

Re-exports§

pub use counter_records::CounterRecord;
pub use datagram::AddressType;
pub use datagram::SflowDatagram;
pub use error::SflowError;
pub use flow_records::FlowRecord;
pub use samples::SflowSample;

Modules§

counter_records
datagram
error
flow_records
samples

Structs§

ParseResult
Result of parsing one or more sFlow datagrams from a byte buffer.
SflowParser
Stateless sFlow v5 datagram parser.
SflowParserBuilder
Builder for configuring an SflowParser.