Skip to content

Renamed NetflowPacket to NetflowPacketResult. #20

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.1.6"
version = "0.1.7"
edition = "2021"
author = "[email protected]"
license = "MIT OR Apache-2.0"
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ See: <https://en.wikipedia.org/wiki/NetFlow>
## V5:

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

let v5_packet = [0, 5, 2, 0, 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,];
match NetflowParser::default().parse_bytes(&v5_packet).first() {
Some(NetflowPacket::V5(v5)) => assert_eq!(v5.header.version, 5),
Some(NetflowPacketResult::V5(v5)) => assert_eq!(v5.header.version, 5),
Some(NetflowPacketResult::Error(e)) => println!("{:?}", e),
_ => (),
}
```
Expand All @@ -39,12 +40,12 @@ println!("{}", json!(NetflowParser::default().parse_bytes(&v5_packet)).to_string
## Filtering for a specific version

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

let v5_packet = [0, 5, 2, 0, 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 parsed = NetflowParser::default().parse_bytes(&v5_packet);

let v5_parsed: Vec<NetflowPacket> = parsed.iter().filter(|p| p.is_v5()).map(|p| p.clone()).collect();
let v5_parsed: Vec<NetflowPacketResult> = parsed.iter().filter(|p| p.is_v5()).map(|p| p.clone()).collect();
```

## V9/IPFix notes:
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.1.7
* Renamed NetflowPacket to NetflowPacketResult.
* Created an Error Type on NetflowPacketResult. Contains the error message and bytes that was trying to be parsed.

# 0.1.6
* Fixed bug when parsing empty byte arrays or empty remaining slices.

Expand Down
41 changes: 31 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@
//! ## V5:
//!
//! ```rust
//! use netflow_parser::{NetflowParser, NetflowPacket};
//! use netflow_parser::{NetflowParser, NetflowPacketResult};
//!
//! let v5_packet = [0, 5, 2, 0, 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,];
//! match NetflowParser::default().parse_bytes(&v5_packet).first() {
//! Some(NetflowPacket::V5(v5)) => assert_eq!(v5.header.version, 5),
//! Some(NetflowPacketResult::V5(v5)) => assert_eq!(v5.header.version, 5),
//! Some(NetflowPacketResult::Error(e)) => println!("{:?}", e),
//! _ => (),
//! }
//! ```
Expand All @@ -39,12 +40,12 @@
//! ## Filtering for a specific version
//!
//! ```rust
//! use netflow_parser::{NetflowParser, NetflowPacket};
//! use netflow_parser::{NetflowParser, NetflowPacketResult};
//!
//! let v5_packet = [0, 5, 2, 0, 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 parsed = NetflowParser::default().parse_bytes(&v5_packet);
//!
//! let v5_parsed: Vec<NetflowPacket> = parsed.iter().filter(|p| p.is_v5()).map(|p| p.clone()).collect();
//! let v5_parsed: Vec<NetflowPacketResult> = parsed.iter().filter(|p| p.is_v5()).map(|p| p.clone()).collect();
//! ```
//!
//! ## V9/IPFix notes:
Expand Down Expand Up @@ -80,9 +81,15 @@ use variable_versions::v9::{V9Parser, V9};

use nom_derive::{Nom, Parse};

#[derive(Debug, Clone, Serialize)]
pub struct NetflowPacketError {
pub error_message: String,
pub bytes: Vec<u8>,
}

/// Enum of supported Netflow Versions
#[derive(Debug, Clone, Serialize)]
pub enum NetflowPacket {
pub enum NetflowPacketResult {
/// Version 5
V5(V5),
/// Version 7
Expand All @@ -91,9 +98,11 @@ pub enum NetflowPacket {
V9(V9),
/// IPFix
IPFix(IPFix),
/// Error
Error(NetflowPacketError),
}

impl NetflowPacket {
impl NetflowPacketResult {
pub fn is_v5(&self) -> bool {
matches!(self, Self::V5(_v))
}
Expand All @@ -106,13 +115,16 @@ impl NetflowPacket {
pub fn is_ipfix(&self) -> bool {
matches!(self, Self::IPFix(_v))
}
pub fn is_error(&self) -> bool {
matches!(self, Self::Error(_v))
}
}

#[derive(Debug, Clone)]
struct ParsedNetflow {
remaining: Vec<u8>,
/// Parsed Netflow Packet
netflow_packet: NetflowPacket,
netflow_packet: NetflowPacketResult,
}

/// Struct is used simply to match how to handle the result of the packet
Expand Down Expand Up @@ -180,7 +192,7 @@ impl NetflowParser {
/// ```
///
#[inline]
pub fn parse_bytes(&mut self, packet: &[u8]) -> Vec<NetflowPacket> {
pub fn parse_bytes(&mut self, packet: &[u8]) -> Vec<NetflowPacketResult> {
if packet.is_empty() {
return vec![];
}
Expand All @@ -193,8 +205,11 @@ impl NetflowParser {
parsed
}
Err(parsed_error) => {
dbg!("{parsed_error}", parsed_error);
vec![]
let netflow_packet_error = NetflowPacketError {
error_message: parsed_error.to_string(),
bytes: packet.to_vec(),
};
vec![NetflowPacketResult::Error(netflow_packet_error)]
}
}
}
Expand Down Expand Up @@ -222,6 +237,12 @@ mod tests {
assert_yaml_snapshot!(NetflowParser::default().parse_bytes(&packet));
}

#[test]
fn it_creates_error() {
let packet = [12, 13, 14];
assert_yaml_snapshot!(NetflowParser::default().parse_bytes(&packet));
}

#[test]
fn it_parses_v7() {
let packet = [
Expand Down
11 changes: 11 additions & 0 deletions src/snapshots/netflow_parser__tests__it_creates_error.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
source: src/lib.rs
expression: "NetflowParser::default().parse_bytes(&packet)"
---
- Error:
error_message: Not Supported
bytes:
- 12
- 13
- 14

4 changes: 2 additions & 2 deletions src/static_versions/v5.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! - <https://www.cisco.com/en/US/technologies/tk648/tk362/technologies_white_paper09186a00800a3db9.html>

use crate::protocol::ProtocolTypes;
use crate::{NetflowByteParserStatic, NetflowPacket, ParsedNetflow};
use crate::{NetflowByteParserStatic, NetflowPacketResult, ParsedNetflow};

use nom::number::complete::be_u32;
use nom_derive::*;
Expand All @@ -28,7 +28,7 @@ impl NetflowByteParserStatic for V5 {
let parsed_packet = V5::parse_be(packet).map_err(|e| format!("{e}"))?;
Ok(ParsedNetflow {
remaining: parsed_packet.0.to_vec(),
netflow_packet: NetflowPacket::V5(parsed_packet.1),
netflow_packet: NetflowPacketResult::V5(parsed_packet.1),
})
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/static_versions/v7.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! - <https://www.cisco.com/en/US/technologies/tk648/tk362/technologies_white_paper09186a00800a3db9.html>

use crate::protocol::ProtocolTypes;
use crate::{NetflowByteParserStatic, NetflowPacket, ParsedNetflow};
use crate::{NetflowByteParserStatic, NetflowPacketResult, ParsedNetflow};

use nom::number::complete::be_u32;
use nom_derive::*;
Expand All @@ -28,7 +28,7 @@ impl NetflowByteParserStatic for V7 {
let parsed_packet = V7::parse_be(packet).map_err(|e| format!("{e}"))?;
Ok(ParsedNetflow {
remaining: parsed_packet.0.to_vec(),
netflow_packet: NetflowPacket::V7(parsed_packet.1),
netflow_packet: NetflowPacketResult::V7(parsed_packet.1),
})
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/variable_versions/ipfix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use super::common::*;
use crate::protocol::ProtocolTypes;
use crate::variable_versions::ipfix_lookup::*;
use crate::{NetflowByteParserVariable, NetflowPacket, ParsedNetflow};
use crate::{NetflowByteParserVariable, NetflowPacketResult, ParsedNetflow};

use nom::bytes::complete::take;
use nom::error::{Error as NomError, ErrorKind};
Expand Down Expand Up @@ -354,7 +354,7 @@ impl NetflowByteParserVariable for IPFixParser {

Ok(ParsedNetflow {
remaining: remaining.to_vec(),
netflow_packet: NetflowPacket::IPFix(v10_parsed),
netflow_packet: NetflowPacketResult::IPFix(v10_parsed),
})
}
}
4 changes: 2 additions & 2 deletions src/variable_versions/v9.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use super::common::*;
use crate::protocol::ProtocolTypes;
use crate::variable_versions::v9_lookup::*;
use crate::{NetflowByteParserVariable, NetflowPacket, ParsedNetflow};
use crate::{NetflowByteParserVariable, NetflowPacketResult, ParsedNetflow};

use nom::bytes::complete::take;
use nom::error::{Error as NomError, ErrorKind};
Expand Down Expand Up @@ -463,7 +463,7 @@ impl NetflowByteParserVariable for V9Parser {

Ok(ParsedNetflow {
remaining: remaining.to_vec(),
netflow_packet: NetflowPacket::V9(v9_parsed),
netflow_packet: NetflowPacketResult::V9(v9_parsed),
})
}
}