Skip to content

Commit

Permalink
Added parse_bytes_as_netflow_common_flowsets and readme info. (#85)
Browse files Browse the repository at this point in the history
* Added parse_bytes_as_netflow_common_flowsets and readme info.

---------

Co-authored-by: mikemiles-dev <michaelmileusnich@Michaels-MacBook-Air-2.local>
  • Loading branch information
mikemiles-dev and mikemiles-dev authored Sep 20, 2024
1 parent 606e8bf commit d3f2c2c
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 32 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "netflow_parser"
description = "Parser for Netflow Cisco V5, V7, V9, IPFIX"
version = "0.4.5"
version = "0.4.6"
edition = "2021"
author = "michael.mileusnich@gmail.com"
license = "MIT OR Apache-2.0"
Expand Down
55 changes: 42 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,37 @@ let v5_parsed: Vec<NetflowPacket> = parsed.into_iter().filter(|p| p.is_v5()).col

## Netflow Common

For convenience we have included a `NetflowCommon` structure. This will allow you to use common
Netflow fields without unpacking specific versions (fields like `src_port`, `dst_port`, etc.). If the
packet flow does not have the matching field it will simply be left as `None`.
For convenience we have included a `NetflowCommon` and `NetflowCommonFlowSet` structure.
This will allow you to use common fields without unpacking values from specific versions.
If the packet flow does not have the matching field it will simply be left as `None`.

### Netflow Common fields:
```
src_addr: Option<IpAddr>,
dst_addr: Option<IpAddr>,
src_port: Option<u16>,
dst_port: Option<u16>,
protocol_number: Option<u8>,
protocol_type: Option<ProtocolTypes>,
first_seen: Option<u32>,
last_seen: Option<u32>,
### NetflowCommon and NetflowCommonFlowSet Struct:
```rust
use std::net::IpAddr;
use netflow_parser::protocol::ProtocolTypes;

#[derive(Debug, Default)]
pub struct NetflowCommon {
pub version: u16,
pub timestamp: u32,
pub flowsets: Vec<NetflowCommonFlowSet>,
}

#[derive(Debug, Default)]
struct NetflowCommonFlowSet {
src_addr: Option<IpAddr>,
dst_addr: Option<IpAddr>,
src_port: Option<u16>,
dst_port: Option<u16>,
protocol_number: Option<u8>,
protocol_type: Option<ProtocolTypes>,
first_seen: Option<u32>,
last_seen: Option<u32>,
}
```

### Converting NetflowPacket to NetflowCommon

```rust
use netflow_parser::{NetflowParser, NetflowPacket};

Expand All @@ -84,6 +99,20 @@ for common_flow in netflow_common.flowsets.iter() {
}
```

### Alternative if you just want to gather all flowsets from all packets into a flattened vector of NetflowCommonFlowSet:

```rust
use netflow_parser::{NetflowParser, NetflowPacket};

let v5_packet = [0, 5, 0, 1, 3, 0, 4, 0, 5, 0, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3,
4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7];
let netflow_common_flowsets = NetflowParser::default()
.parse_bytes_as_netflow_common_flowsets(&v5_packet);

println!("Flowsets: {:?}", netflow_common_flowsets);
```

## Re-Exporting flows

Netflow Parser now supports parsed V5, V7, V9, IPFix can be re-exported back into bytes.
Expand Down
4 changes: 4 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 0.4.6
* Added `NetflowParser` function `parse_bytes_as_netflow_common_flowsets`. Will allow the caller
to gather all flowsets from all `NetflowPacket` into a single `Vec` of `NetflowCommonFlowSet`.

# 0.4.5
* Fixed bug with NetflowCommon V9 where Src and Dst IP where Ipv6 wasn't being checked.

Expand Down
73 changes: 57 additions & 16 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,37 @@
//!
//! ## Netflow Common
//!
//! For convenience we have included a `NetflowCommon` structure. This will allow you to use common
//! Netflow fields without unpacking specific versions (fields like `src_port`, `dst_port`, etc.). If the
//! packet flow does not have the matching field it will simply be left as `None`.
//!
//! ### Netflow Common fields:
//! ```ignore
//! src_addr: Option<IpAddr>,
//! dst_addr: Option<IpAddr>,
//! src_port: Option<u16>,
//! dst_port: Option<u16>,
//! protocol_number: Option<u8>,
//! protocol_type: Option<ProtocolTypes>,
//! first_seen: Option<u32>,
//! last_seen: Option<u32>,
//! For convenience we have included a `NetflowCommon` and `NetflowCommonFlowSet` structure.
//! This will allow you to use common fields without unpacking values from specific versions.
//! If the packet flow does not have the matching field it will simply be left as `None`.
//!
//! ### NetflowCommon and NetflowCommonFlowSet Struct:
//! ```rust
//! use std::net::IpAddr;
//! use netflow_parser::protocol::ProtocolTypes;
//!
//! #[derive(Debug, Default)]
//! pub struct NetflowCommon {
//! pub version: u16,
//! pub timestamp: u32,
//! pub flowsets: Vec<NetflowCommonFlowSet>,
//! }
//!
//! #[derive(Debug, Default)]
//! struct NetflowCommonFlowSet {
//! src_addr: Option<IpAddr>,
//! dst_addr: Option<IpAddr>,
//! src_port: Option<u16>,
//! dst_port: Option<u16>,
//! protocol_number: Option<u8>,
//! protocol_type: Option<ProtocolTypes>,
//! first_seen: Option<u32>,
//! last_seen: Option<u32>,
//! }
//! ```
//!
//! ### Converting NetflowPacket to NetflowCommon
//!
//! ```rust
//! use netflow_parser::{NetflowParser, NetflowPacket};
//!
Expand All @@ -84,6 +99,20 @@
//! }
//! ```
//!
//! ### Alternative if you just want to gather all flowsets from all packets into a flattened vector of NetflowCommonFlowSet:
//!
//! ```rust
//! use netflow_parser::{NetflowParser, NetflowPacket};
//!
//! let v5_packet = [0, 5, 0, 1, 3, 0, 4, 0, 5, 0, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3,
//! 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
//! 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7];
//! let netflow_common_flowsets = NetflowParser::default()
//! .parse_bytes_as_netflow_common_flowsets(&v5_packet);
//!
//! println!("Flowsets: {:?}", netflow_common_flowsets);
//! ```
//!
//! ## Re-Exporting flows
//! Netflow Parser now supports parsed V5, V7, V9, IPFix can be re-exported back into bytes.
//! ```rust
Expand Down Expand Up @@ -139,7 +168,7 @@ pub mod static_versions;
mod tests;
pub mod variable_versions;

use crate::netflow_common::{NetflowCommon, NetflowCommonError};
use crate::netflow_common::{NetflowCommon, NetflowCommonError, NetflowCommonFlowSet};

use static_versions::{v5::V5, v7::V7};
use variable_versions::ipfix::{IPFix, IPFixParser};
Expand Down Expand Up @@ -184,7 +213,6 @@ impl NetflowPacket {
pub fn is_error(&self) -> bool {
matches!(self, Self::Error(_v))
}

pub fn as_netflow_common(&self) -> Result<NetflowCommon, NetflowCommonError> {
self.try_into()
}
Expand Down Expand Up @@ -277,6 +305,19 @@ impl NetflowParser {
})
}

/// Takes a Netflow packet slice and returns a vector of Parsed NetflowCommonFlowSet
#[inline]
pub fn parse_bytes_as_netflow_common_flowsets(
&mut self,
packet: &[u8],
) -> Vec<NetflowCommonFlowSet> {
let netflow_packets = self.parse_bytes(packet);
netflow_packets
.iter()
.flat_map(|n| n.as_netflow_common().unwrap_or_default().flowsets)
.collect()
}

/// Checks the first u16 of the packet to determine the version. Parses the packet based on the version.
/// If the version is unknown it returns an error. If the packet is incomplete it returns an error.
/// If the packet is parsed successfully it returns the parsed Netflow packet and the remaining bytes.
Expand Down
4 changes: 2 additions & 2 deletions src/netflow_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub enum NetflowCommonError {
UnknownVersion(NetflowPacket),
}

#[derive(Debug)]
#[derive(Debug, Default)]
/// Common structure for Netflow
pub struct NetflowCommon {
pub version: u16,
Expand All @@ -36,7 +36,7 @@ impl TryFrom<&NetflowPacket> for NetflowCommon {
}
}

#[derive(Debug)]
#[derive(Debug, Default)]
/// Common flow set structure for Netflow
pub struct NetflowCommonFlowSet {
/// Source IP address
Expand Down

0 comments on commit d3f2c2c

Please sign in to comment.