Skip to content

Commit d3f2c2c

Browse files
mikemiles-devmikemiles-dev
and
mikemiles-dev
authored
Added parse_bytes_as_netflow_common_flowsets and readme info. (#85)
* Added parse_bytes_as_netflow_common_flowsets and readme info. --------- Co-authored-by: mikemiles-dev <[email protected]>
1 parent 606e8bf commit d3f2c2c

File tree

5 files changed

+106
-32
lines changed

5 files changed

+106
-32
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "netflow_parser"
33
description = "Parser for Netflow Cisco V5, V7, V9, IPFIX"
4-
version = "0.4.5"
4+
version = "0.4.6"
55
edition = "2021"
66
77
license = "MIT OR Apache-2.0"

README.md

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,37 @@ let v5_parsed: Vec<NetflowPacket> = parsed.into_iter().filter(|p| p.is_v5()).col
5050

5151
## Netflow Common
5252

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

57-
### Netflow Common fields:
58-
```
59-
src_addr: Option<IpAddr>,
60-
dst_addr: Option<IpAddr>,
61-
src_port: Option<u16>,
62-
dst_port: Option<u16>,
63-
protocol_number: Option<u8>,
64-
protocol_type: Option<ProtocolTypes>,
65-
first_seen: Option<u32>,
66-
last_seen: Option<u32>,
57+
### NetflowCommon and NetflowCommonFlowSet Struct:
58+
```rust
59+
use std::net::IpAddr;
60+
use netflow_parser::protocol::ProtocolTypes;
61+
62+
#[derive(Debug, Default)]
63+
pub struct NetflowCommon {
64+
pub version: u16,
65+
pub timestamp: u32,
66+
pub flowsets: Vec<NetflowCommonFlowSet>,
67+
}
68+
69+
#[derive(Debug, Default)]
70+
struct NetflowCommonFlowSet {
71+
src_addr: Option<IpAddr>,
72+
dst_addr: Option<IpAddr>,
73+
src_port: Option<u16>,
74+
dst_port: Option<u16>,
75+
protocol_number: Option<u8>,
76+
protocol_type: Option<ProtocolTypes>,
77+
first_seen: Option<u32>,
78+
last_seen: Option<u32>,
79+
}
6780
```
6881

82+
### Converting NetflowPacket to NetflowCommon
83+
6984
```rust
7085
use netflow_parser::{NetflowParser, NetflowPacket};
7186

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

102+
### Alternative if you just want to gather all flowsets from all packets into a flattened vector of NetflowCommonFlowSet:
103+
104+
```rust
105+
use netflow_parser::{NetflowParser, NetflowPacket};
106+
107+
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,
108+
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,
109+
2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7];
110+
let netflow_common_flowsets = NetflowParser::default()
111+
.parse_bytes_as_netflow_common_flowsets(&v5_packet);
112+
113+
println!("Flowsets: {:?}", netflow_common_flowsets);
114+
```
115+
87116
## Re-Exporting flows
88117

89118
Netflow Parser now supports parsed V5, V7, V9, IPFix can be re-exported back into bytes.

RELEASES.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# 0.4.6
2+
* Added `NetflowParser` function `parse_bytes_as_netflow_common_flowsets`. Will allow the caller
3+
to gather all flowsets from all `NetflowPacket` into a single `Vec` of `NetflowCommonFlowSet`.
4+
15
# 0.4.5
26
* Fixed bug with NetflowCommon V9 where Src and Dst IP where Ipv6 wasn't being checked.
37

src/lib.rs

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,37 @@
5050
//!
5151
//! ## Netflow Common
5252
//!
53-
//! For convenience we have included a `NetflowCommon` structure. This will allow you to use common
54-
//! Netflow fields without unpacking specific versions (fields like `src_port`, `dst_port`, etc.). If the
55-
//! packet flow does not have the matching field it will simply be left as `None`.
56-
//!
57-
//! ### Netflow Common fields:
58-
//! ```ignore
59-
//! src_addr: Option<IpAddr>,
60-
//! dst_addr: Option<IpAddr>,
61-
//! src_port: Option<u16>,
62-
//! dst_port: Option<u16>,
63-
//! protocol_number: Option<u8>,
64-
//! protocol_type: Option<ProtocolTypes>,
65-
//! first_seen: Option<u32>,
66-
//! last_seen: Option<u32>,
53+
//! For convenience we have included a `NetflowCommon` and `NetflowCommonFlowSet` structure.
54+
//! This will allow you to use common fields without unpacking values from specific versions.
55+
//! If the packet flow does not have the matching field it will simply be left as `None`.
56+
//!
57+
//! ### NetflowCommon and NetflowCommonFlowSet Struct:
58+
//! ```rust
59+
//! use std::net::IpAddr;
60+
//! use netflow_parser::protocol::ProtocolTypes;
61+
//!
62+
//! #[derive(Debug, Default)]
63+
//! pub struct NetflowCommon {
64+
//! pub version: u16,
65+
//! pub timestamp: u32,
66+
//! pub flowsets: Vec<NetflowCommonFlowSet>,
67+
//! }
68+
//!
69+
//! #[derive(Debug, Default)]
70+
//! struct NetflowCommonFlowSet {
71+
//! src_addr: Option<IpAddr>,
72+
//! dst_addr: Option<IpAddr>,
73+
//! src_port: Option<u16>,
74+
//! dst_port: Option<u16>,
75+
//! protocol_number: Option<u8>,
76+
//! protocol_type: Option<ProtocolTypes>,
77+
//! first_seen: Option<u32>,
78+
//! last_seen: Option<u32>,
79+
//! }
6780
//! ```
6881
//!
82+
//! ### Converting NetflowPacket to NetflowCommon
83+
//!
6984
//! ```rust
7085
//! use netflow_parser::{NetflowParser, NetflowPacket};
7186
//!
@@ -84,6 +99,20 @@
8499
//! }
85100
//! ```
86101
//!
102+
//! ### Alternative if you just want to gather all flowsets from all packets into a flattened vector of NetflowCommonFlowSet:
103+
//!
104+
//! ```rust
105+
//! use netflow_parser::{NetflowParser, NetflowPacket};
106+
//!
107+
//! 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,
108+
//! 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,
109+
//! 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7];
110+
//! let netflow_common_flowsets = NetflowParser::default()
111+
//! .parse_bytes_as_netflow_common_flowsets(&v5_packet);
112+
//!
113+
//! println!("Flowsets: {:?}", netflow_common_flowsets);
114+
//! ```
115+
//!
87116
//! ## Re-Exporting flows
88117
//! Netflow Parser now supports parsed V5, V7, V9, IPFix can be re-exported back into bytes.
89118
//! ```rust
@@ -139,7 +168,7 @@ pub mod static_versions;
139168
mod tests;
140169
pub mod variable_versions;
141170

142-
use crate::netflow_common::{NetflowCommon, NetflowCommonError};
171+
use crate::netflow_common::{NetflowCommon, NetflowCommonError, NetflowCommonFlowSet};
143172

144173
use static_versions::{v5::V5, v7::V7};
145174
use variable_versions::ipfix::{IPFix, IPFixParser};
@@ -184,7 +213,6 @@ impl NetflowPacket {
184213
pub fn is_error(&self) -> bool {
185214
matches!(self, Self::Error(_v))
186215
}
187-
188216
pub fn as_netflow_common(&self) -> Result<NetflowCommon, NetflowCommonError> {
189217
self.try_into()
190218
}
@@ -277,6 +305,19 @@ impl NetflowParser {
277305
})
278306
}
279307

308+
/// Takes a Netflow packet slice and returns a vector of Parsed NetflowCommonFlowSet
309+
#[inline]
310+
pub fn parse_bytes_as_netflow_common_flowsets(
311+
&mut self,
312+
packet: &[u8],
313+
) -> Vec<NetflowCommonFlowSet> {
314+
let netflow_packets = self.parse_bytes(packet);
315+
netflow_packets
316+
.iter()
317+
.flat_map(|n| n.as_netflow_common().unwrap_or_default().flowsets)
318+
.collect()
319+
}
320+
280321
/// Checks the first u16 of the packet to determine the version. Parses the packet based on the version.
281322
/// If the version is unknown it returns an error. If the packet is incomplete it returns an error.
282323
/// If the packet is parsed successfully it returns the parsed Netflow packet and the remaining bytes.

src/netflow_common.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub enum NetflowCommonError {
1414
UnknownVersion(NetflowPacket),
1515
}
1616

17-
#[derive(Debug)]
17+
#[derive(Debug, Default)]
1818
/// Common structure for Netflow
1919
pub struct NetflowCommon {
2020
pub version: u16,
@@ -36,7 +36,7 @@ impl TryFrom<&NetflowPacket> for NetflowCommon {
3636
}
3737
}
3838

39-
#[derive(Debug)]
39+
#[derive(Debug, Default)]
4040
/// Common flow set structure for Netflow
4141
pub struct NetflowCommonFlowSet {
4242
/// Source IP address

0 commit comments

Comments
 (0)