Skip to content

Commit b095c9d

Browse files
mikemiles-devMichael Mileusnich
and
Michael Mileusnich
authored
Concrete error type (#67)
Co-authored-by: Michael Mileusnich <[email protected]>
1 parent a0ea15c commit b095c9d

6 files changed

+42
-31
lines changed

RELEASES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# 0.3.3
22
* Renamed Sets to FlowSets for IPFIX for consistency.
3+
* Concrete error type for parsing
34

45
# 0.3.2
56
* Readme changes

src/lib.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ pub mod static_versions;
8181
mod tests;
8282
pub mod variable_versions;
8383

84-
use parser::Parser;
84+
use parser::NetflowParseError;
8585
use static_versions::{v5::V5, v7::V7};
8686
use variable_versions::ipfix::{IPFix, IPFixParser};
8787
use variable_versions::v9::{V9Parser, V9};
@@ -123,8 +123,8 @@ impl NetflowPacketResult {
123123

124124
#[derive(Debug, Clone, Serialize)]
125125
pub struct NetflowPacketError {
126-
pub error_message: String,
127-
pub bytes: Vec<u8>,
126+
pub error: NetflowParseError,
127+
pub remaining: Vec<u8>,
128128
}
129129

130130
#[derive(Default, Debug)]
@@ -160,14 +160,14 @@ impl NetflowParser {
160160
}
161161
self.parse(packet)
162162
.map(|parsed_netflow| {
163-
let mut parsed = vec![parsed_netflow.netflow_packet];
163+
let mut parsed = vec![parsed_netflow.result];
164164
parsed.append(&mut self.parse_bytes(parsed_netflow.remaining.as_slice()));
165165
parsed
166166
})
167167
.unwrap_or_else(|e| {
168168
vec![NetflowPacketResult::Error(NetflowPacketError {
169-
error_message: e.to_string(),
170-
bytes: packet.to_vec(),
169+
error: e,
170+
remaining: packet.to_vec(),
171171
})]
172172
})
173173
}

src/parser.rs

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use crate::variable_versions::ipfix::IPFix;
55
use crate::variable_versions::v9::V9;
66
use crate::{NetflowPacketResult, NetflowParser};
77

8+
use serde::Serialize;
9+
810
/// Struct is used simply to match how to handle the result of the packet
911
#[derive(Nom)]
1012
pub struct NetflowHeader {
@@ -20,15 +22,13 @@ pub enum NetflowHeaderResult<'a> {
2022
}
2123

2224
impl NetflowHeader {
23-
pub fn parse_header(
24-
packet: &[u8],
25-
) -> Result<NetflowHeaderResult, Box<dyn std::error::Error>> {
25+
pub fn parse_header(packet: &[u8]) -> Result<NetflowHeaderResult, NetflowParseError> {
2626
match NetflowHeader::parse_be(packet) {
2727
Ok((i, header)) if header.version == 5 => Ok(NetflowHeaderResult::V5(i)),
2828
Ok((i, header)) if header.version == 7 => Ok(NetflowHeaderResult::V7(i)),
2929
Ok((i, header)) if header.version == 9 => Ok(NetflowHeaderResult::V9(i)),
3030
Ok((i, header)) if header.version == 10 => Ok(NetflowHeaderResult::IPFix(i)),
31-
_ => Err(("Unsupported Version").into()),
31+
_ => Err(NetflowParseError::UnknownVersion(packet.to_vec())),
3232
}
3333
}
3434
}
@@ -66,45 +66,48 @@ impl<'a> From<IPFixParsedResult<'a>> for ParsedNetflow {
6666
pub struct ParsedNetflow {
6767
pub remaining: Vec<u8>,
6868
/// Parsed Netflow Packet
69-
pub netflow_packet: NetflowPacketResult,
69+
pub result: NetflowPacketResult,
7070
}
7171

7272
impl ParsedNetflow {
73-
fn new(remaining: &[u8], netflow_packet: NetflowPacketResult) -> Self {
73+
fn new(remaining: &[u8], result: NetflowPacketResult) -> Self {
7474
Self {
7575
remaining: remaining.to_vec(),
76-
netflow_packet,
76+
result,
7777
}
7878
}
7979
}
8080

81-
pub trait Parser {
82-
fn parse<'a>(
83-
&'a mut self,
84-
packet: &'a [u8],
85-
) -> Result<ParsedNetflow, Box<dyn std::error::Error>>;
81+
#[derive(Debug, Clone, Serialize)]
82+
pub enum NetflowParseError {
83+
V5(String),
84+
V7(String),
85+
V9(String),
86+
IPFix(String),
87+
UnknownVersion(Vec<u8>),
88+
Unknown(String),
8689
}
8790

88-
impl Parser for NetflowParser {
91+
impl NetflowParser {
8992
/// Parses a Netflow by version packet and returns a Parsed Netflow.
90-
fn parse<'a>(
93+
pub fn parse<'a>(
9194
&'a mut self,
9295
packet: &'a [u8],
93-
) -> Result<ParsedNetflow, Box<dyn std::error::Error>> {
96+
) -> Result<ParsedNetflow, NetflowParseError> {
9497
match NetflowHeader::parse_header(packet) {
9598
Ok(NetflowHeaderResult::V5(v5_packet)) => V5::parse(v5_packet)
9699
.map(|r: V5ParsedResult| r.into())
97-
.map_err(|e| format!("Could not parse V5 packet: {e}").into()),
100+
.map_err(|e| NetflowParseError::V5(e.to_string())),
98101
Ok(NetflowHeaderResult::V7(v7_packet)) => V7::parse(v7_packet)
99102
.map(|r: V7ParsedResult| r.into())
100-
.map_err(|e| format!("Could not parse V7 packet: {e}").into()),
103+
.map_err(|e| NetflowParseError::V7(e.to_string())),
101104
Ok(NetflowHeaderResult::V9(v9_packet)) => V9::parse(v9_packet, &mut self.v9_parser)
102105
.map(|r: V9ParsedResult| r.into())
103-
.map_err(|e| format!("Could not parse V9 packet: {e}").into()),
106+
.map_err(|e| NetflowParseError::V9(e.to_string())),
104107
Ok(NetflowHeaderResult::IPFix(ipfix_packet)) => {
105108
IPFix::parse(ipfix_packet, &mut self.ipfix_parser)
106109
.map(|r: IPFixParsedResult| r.into())
107-
.map_err(|e| format!("Could not parse v10 packet: {e}").into())
110+
.map_err(|e| NetflowParseError::IPFix(e.to_string()))
108111
}
109112
Err(e) => Err(e),
110113
}

src/snapshots/netflow_parser__tests__base_tests__it_creates_error.snap

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@ source: src/tests.rs
33
expression: "NetflowParser::default().parse_bytes(&packet)"
44
---
55
- Error:
6-
error_message: Unsupported Version
7-
bytes:
6+
error:
7+
UnknownVersion:
8+
- 12
9+
- 13
10+
- 14
11+
remaining:
812
- 12
913
- 13
1014
- 14
15+

src/snapshots/netflow_parser__tests__base_tests__it_doesnt_parse_0_length_fields_ipfix.snap

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ source: src/tests.rs
33
expression: "NetflowParser::default().parse_bytes(&packet)"
44
---
55
- Error:
6-
error_message: "Could not parse v10 packet: Parsing Error: Error { input: [], code: Fail }"
7-
bytes:
6+
error:
7+
IPFix: "Parsing Error: Error { input: [], code: Fail }"
8+
remaining:
89
- 0
910
- 10
1011
- 0

src/snapshots/netflow_parser__tests__base_tests__it_parses_ipfix_with_no_template_fields_raises_error.snap

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ source: src/tests.rs
33
expression: parser.parse_bytes(&packet)
44
---
55
- Error:
6-
error_message: "Could not parse v10 packet: Parsing Error: Error { input: [0, 8, 0, 0, 1, 1], code: Fail }"
7-
bytes:
6+
error:
7+
IPFix: "Parsing Error: Error { input: [0, 8, 0, 0, 1, 1], code: Fail }"
8+
remaining:
89
- 0
910
- 10
1011
- 0

0 commit comments

Comments
 (0)