From 6784097ee2279c88ccac115bc184fbef9bf445f6 Mon Sep 17 00:00:00 2001 From: Michael Mileusnich <467735+mikemiles-dev@users.noreply.github.com> Date: Sun, 16 Jun 2024 23:46:09 -0500 Subject: [PATCH] Added 3 byte DataNumber support (#70) * Added 3 byte DataNumber support * Removed debug line --------- Co-authored-by: mikemiles-dev --- Cargo.toml | 2 +- RELEASES.md | 3 + SECURITY.md | 1 + ...ase_tests__it_parses_v9_ipv6flowlabel.snap | 495 ++++++++++++++++++ src/tests.rs | 9 + src/variable_versions/common.rs | 3 + 6 files changed, 512 insertions(+), 1 deletion(-) create mode 100644 src/snapshots/netflow_parser__tests__base_tests__it_parses_v9_ipv6flowlabel.snap diff --git a/Cargo.toml b/Cargo.toml index e9827ef..aaff480 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "netflow_parser" description = "Parser for Netflow Cisco V5, V7, V9, IPFIX" -version = "0.3.3" +version = "0.3.4" edition = "2021" author = "michael.mileusnich@gmail.com" license = "MIT OR Apache-2.0" diff --git a/RELEASES.md b/RELEASES.md index fef4cb7..51c569a 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,6 @@ +# 0.3.4 + * Added 3 byte DataNumber support. + # 0.3.3 * Renamed Sets to FlowSets for IPFIX for consistency. * Concrete error type for parsing diff --git a/SECURITY.md b/SECURITY.md index 7f85182..8c006b9 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,6 +4,7 @@ | Version | Supported | | ------- | ------------------ | +| 0.3.4 | :white_check_mark: | | 0.3.3 | :white_check_mark: | | 0.3.2 | :white_check_mark: | | 0.3.1 | :white_check_mark: | diff --git a/src/snapshots/netflow_parser__tests__base_tests__it_parses_v9_ipv6flowlabel.snap b/src/snapshots/netflow_parser__tests__base_tests__it_parses_v9_ipv6flowlabel.snap new file mode 100644 index 0000000..933e9e1 --- /dev/null +++ b/src/snapshots/netflow_parser__tests__base_tests__it_parses_v9_ipv6flowlabel.snap @@ -0,0 +1,495 @@ +--- +source: src/tests.rs +expression: "NetflowParser::default().parse_bytes(&packets)" +--- +- V9: + header: + version: 9 + count: 4 + sys_up_time: 10624535 + unix_secs: 1717095238 + sequence_number: 341 + source_id: 8 + flowsets: + - header: + flow_set_id: 0 + length: 76 + body: + templates: + - template_id: 258 + field_count: 17 + fields: + - field_type_number: 8 + field_type: Ipv4SrcAddr + field_length: 4 + - field_type_number: 12 + field_type: Ipv4DstAddr + field_length: 4 + - field_type_number: 15 + field_type: Ipv4NextHop + field_length: 4 + - field_type_number: 7 + field_type: L4SrcPort + field_length: 2 + - field_type_number: 11 + field_type: L4DstPort + field_length: 2 + - field_type_number: 10 + field_type: InputSnmp + field_length: 2 + - field_type_number: 14 + field_type: OutputSnmp + field_length: 2 + - field_type_number: 252 + field_type: Unknown + field_length: 4 + - field_type_number: 253 + field_type: Unknown + field_length: 4 + - field_type_number: 2 + field_type: InPkts + field_length: 4 + - field_type_number: 1 + field_type: InBytes + field_length: 4 + - field_type_number: 22 + field_type: FirstSwitched + field_length: 4 + - field_type_number: 21 + field_type: LastSwitched + field_length: 4 + - field_type_number: 4 + field_type: Protocol + field_length: 1 + - field_type_number: 5 + field_type: SrcTos + field_length: 1 + - field_type_number: 256 + field_type: Unknown + field_length: 2 + - field_type_number: 61 + field_type: Direction + field_length: 1 + - header: + flow_set_id: 0 + length: 84 + body: + templates: + - template_id: 259 + field_count: 19 + fields: + - field_type_number: 8 + field_type: Ipv4SrcAddr + field_length: 4 + - field_type_number: 12 + field_type: Ipv4DstAddr + field_length: 4 + - field_type_number: 15 + field_type: Ipv4NextHop + field_length: 4 + - field_type_number: 7 + field_type: L4SrcPort + field_length: 2 + - field_type_number: 11 + field_type: L4DstPort + field_length: 2 + - field_type_number: 6 + field_type: TcpFlags + field_length: 1 + - field_type_number: 10 + field_type: InputSnmp + field_length: 2 + - field_type_number: 14 + field_type: OutputSnmp + field_length: 2 + - field_type_number: 252 + field_type: Unknown + field_length: 4 + - field_type_number: 253 + field_type: Unknown + field_length: 4 + - field_type_number: 2 + field_type: InPkts + field_length: 4 + - field_type_number: 1 + field_type: InBytes + field_length: 4 + - field_type_number: 22 + field_type: FirstSwitched + field_length: 4 + - field_type_number: 21 + field_type: LastSwitched + field_length: 4 + - field_type_number: 4 + field_type: Protocol + field_length: 1 + - field_type_number: 5 + field_type: SrcTos + field_length: 1 + - field_type_number: 209 + field_type: Unknown + field_length: 8 + - field_type_number: 256 + field_type: Unknown + field_length: 2 + - field_type_number: 61 + field_type: Direction + field_length: 1 + - header: + flow_set_id: 0 + length: 84 + body: + templates: + - template_id: 261 + field_count: 19 + fields: + - field_type_number: 27 + field_type: Ipv6SrcAddr + field_length: 16 + - field_type_number: 28 + field_type: Ipv6DstAddr + field_length: 16 + - field_type_number: 62 + field_type: Ipv6NextHop + field_length: 16 + - field_type_number: 7 + field_type: L4SrcPort + field_length: 2 + - field_type_number: 11 + field_type: L4DstPort + field_length: 2 + - field_type_number: 6 + field_type: TcpFlags + field_length: 1 + - field_type_number: 10 + field_type: InputSnmp + field_length: 2 + - field_type_number: 14 + field_type: OutputSnmp + field_length: 2 + - field_type_number: 252 + field_type: Unknown + field_length: 4 + - field_type_number: 253 + field_type: Unknown + field_length: 4 + - field_type_number: 2 + field_type: InPkts + field_length: 4 + - field_type_number: 1 + field_type: InBytes + field_length: 4 + - field_type_number: 22 + field_type: FirstSwitched + field_length: 4 + - field_type_number: 21 + field_type: LastSwitched + field_length: 4 + - field_type_number: 4 + field_type: Protocol + field_length: 1 + - field_type_number: 5 + field_type: SrcTos + field_length: 1 + - field_type_number: 80 + field_type: InDstMac + field_length: 6 + - field_type_number: 256 + field_type: Unknown + field_length: 2 + - field_type_number: 61 + field_type: Direction + field_length: 1 + - header: + flow_set_id: 0 + length: 88 + body: + templates: + - template_id: 262 + field_count: 20 + fields: + - field_type_number: 27 + field_type: Ipv6SrcAddr + field_length: 16 + - field_type_number: 28 + field_type: Ipv6DstAddr + field_length: 16 + - field_type_number: 62 + field_type: Ipv6NextHop + field_length: 16 + - field_type_number: 31 + field_type: Ipv6FlowLabel + field_length: 3 + - field_type_number: 7 + field_type: L4SrcPort + field_length: 2 + - field_type_number: 11 + field_type: L4DstPort + field_length: 2 + - field_type_number: 6 + field_type: TcpFlags + field_length: 1 + - field_type_number: 10 + field_type: InputSnmp + field_length: 2 + - field_type_number: 14 + field_type: OutputSnmp + field_length: 2 + - field_type_number: 252 + field_type: Unknown + field_length: 4 + - field_type_number: 253 + field_type: Unknown + field_length: 4 + - field_type_number: 2 + field_type: InPkts + field_length: 4 + - field_type_number: 1 + field_type: InBytes + field_length: 4 + - field_type_number: 22 + field_type: FirstSwitched + field_length: 4 + - field_type_number: 21 + field_type: LastSwitched + field_length: 4 + - field_type_number: 4 + field_type: Protocol + field_length: 1 + - field_type_number: 5 + field_type: SrcTos + field_length: 1 + - field_type_number: 80 + field_type: InDstMac + field_length: 6 + - field_type_number: 256 + field_type: Unknown + field_length: 2 + - field_type_number: 61 + field_type: Direction + field_length: 1 +- V9: + header: + version: 9 + count: 2 + sys_up_time: 10724622 + unix_secs: 1717095339 + sequence_number: 356 + source_id: 8 + flowsets: + - header: + flow_set_id: 258 + length: 102 + body: + data: + data_fields: + - 0: + - Ipv4SrcAddr + - Ip4Addr: 192.168.18.10 + 1: + - Ipv4DstAddr + - Ip4Addr: 141.24.12.2 + 2: + - Ipv4NextHop + - Ip4Addr: 0.0.0.0 + 3: + - L4SrcPort + - DataNumber: 49856 + 4: + - L4DstPort + - DataNumber: 53 + 5: + - InputSnmp + - DataNumber: 2 + 6: + - OutputSnmp + - DataNumber: 0 + 7: + - Unknown + - Vec: + - 0 + - 0 + - 0 + - 0 + 8: + - Unknown + - Vec: + - 0 + - 0 + - 0 + - 0 + 9: + - InPkts + - DataNumber: 1 + 10: + - InBytes + - DataNumber: 82 + 11: + - FirstSwitched + - Duration: + secs: 10690 + nanos: 167000000 + 12: + - LastSwitched + - Duration: + secs: 10690 + nanos: 167000000 + 13: + - Protocol + - ProtocolType: Udp + 14: + - SrcTos + - DataNumber: 0 + 15: + - Unknown + - Vec: + - 8 + - 0 + 16: + - Direction + - DataNumber: 1 + - 0: + - Ipv4SrcAddr + - Ip4Addr: 192.168.18.10 + 1: + - Ipv4DstAddr + - Ip4Addr: 141.24.12.2 + 2: + - Ipv4NextHop + - Ip4Addr: 0.0.0.0 + 3: + - L4SrcPort + - DataNumber: 40483 + 4: + - L4DstPort + - DataNumber: 53 + 5: + - InputSnmp + - DataNumber: 2 + 6: + - OutputSnmp + - DataNumber: 0 + 7: + - Unknown + - Vec: + - 0 + - 0 + - 0 + - 0 + 8: + - Unknown + - Vec: + - 0 + - 0 + - 0 + - 0 + 9: + - InPkts + - DataNumber: 1 + 10: + - InBytes + - DataNumber: 82 + 11: + - FirstSwitched + - Duration: + secs: 10688 + nanos: 891000000 + 12: + - LastSwitched + - Duration: + secs: 10688 + nanos: 891000000 + 13: + - Protocol + - ProtocolType: Udp + 14: + - SrcTos + - DataNumber: 0 + 15: + - Unknown + - Vec: + - 8 + - 0 + 16: + - Direction + - DataNumber: 1 + - header: + flow_set_id: 262 + length: 99 + body: + data: + data_fields: + - 0: + - Ipv6SrcAddr + - Ip6Addr: "fd01:8::2a20:235f:1f7b:9379" + 1: + - Ipv6DstAddr + - Ip6Addr: "fd00::b2f2:8ff:fe20:1180" + 2: + - Ipv6NextHop + - Ip6Addr: "::" + 3: + - Ipv6FlowLabel + - DataNumber: 128630 + 4: + - L4SrcPort + - DataNumber: 58037 + 5: + - L4DstPort + - DataNumber: 53 + 6: + - TcpFlags + - DataNumber: 0 + 7: + - InputSnmp + - DataNumber: 2 + 8: + - OutputSnmp + - DataNumber: 0 + 9: + - Unknown + - Vec: + - 0 + - 0 + - 0 + - 0 + 10: + - Unknown + - Vec: + - 0 + - 0 + - 0 + - 0 + 11: + - InPkts + - DataNumber: 1 + 12: + - InBytes + - DataNumber: 102 + 13: + - FirstSwitched + - Duration: + secs: 10688 + nanos: 891000000 + 14: + - LastSwitched + - Duration: + secs: 10688 + nanos: 891000000 + 15: + - Protocol + - ProtocolType: Udp + 16: + - SrcTos + - DataNumber: 0 + 17: + - InDstMac + - MacAddr: "10:90:27:E0:43:6D" + 18: + - Unknown + - Vec: + - 134 + - 221 + 19: + - Direction + - DataNumber: 1 diff --git a/src/tests.rs b/src/tests.rs index 95431f2..f187499 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -107,6 +107,15 @@ mod base_tests { assert_yaml_snapshot!(NetflowParser::default().parse_bytes(&packet)); } + #[test] + fn it_parses_v9_ipv6flowlabel() { + let templates_hex = r#"0009000400a21e176658cb4600000155000000080000004c0102001100080004000c0004000f000400070002000b0002000a0002000e000200fc000400fd000400020004000100040016000400150004000400010005000101000002003d0001000000540103001300080004000c0004000f000400070002000b000200060001000a0002000e000200fc000400fd000400020004000100040016000400150004000400010005000100d1000801000002003d00010000005401050013001b0010001c0010003e001000070002000b000200060001000a0002000e000200fc000400fd00040002000400010004001600040015000400040001000500010050000601000002003d00010000005801060014001b0010001c0010003e0010001f000300070002000b000200060001000a0002000e000200fc000400fd00040002000400010004001600040015000400040001000500010050000601000002003d0001"#; + let packets_hex = r#"0009000200a3a50e6658cbab000001640000000801020066c0a8120a8d180c0200000000c2c00035000200000000000000000000000000010000005200a31e7700a31e771100080001c0a8120a8d180c02000000009e230035000200000000000000000000000000010000005200a3197b00a3197b110008000101060063fd010008000000002a20235f1f7b9379fd00000000000000b2f208fffe2011800000000000000000000000000000000001f676e2b5003500000200000000000000000000000000010000006600a3197b00a3197b1100109027e0436d86dd01"#; + let combined = format!("{}{}", templates_hex, packets_hex); + let packets = hex::decode(combined).unwrap(); + assert_yaml_snapshot!(NetflowParser::default().parse_bytes(&packets)); + } + #[test] fn it_parses_v9_and_re_exports() { let packet = [ diff --git a/src/variable_versions/common.rs b/src/variable_versions/common.rs index 2845ab1..3590f22 100644 --- a/src/variable_versions/common.rs +++ b/src/variable_versions/common.rs @@ -2,6 +2,7 @@ use crate::protocol::ProtocolTypes; use nom::bytes::complete::take; use nom::error::{Error as NomError, ErrorKind}; +use nom::number::complete::{be_i24, be_u24}; use nom::number::complete::{be_u128, be_u32}; use nom::Err as NomErr; use nom::IResult; @@ -46,6 +47,8 @@ impl DataNumber { match field_length { 1 if !signed => Ok(u8::parse(i)?).map(|(i, j)| (i, Self::U8(j))), 2 if !signed => Ok(u16::parse(i)?).map(|(i, j)| (i, Self::U16(j))), + 3 if !signed => Ok(be_u24(i).map(|(i, j)| (i, Self::U32(j)))?), + 3 if signed => Ok(be_i24(i).map(|(i, j)| (i, Self::I32(j)))?), 4 if signed => Ok(i32::parse(i)?).map(|(i, j)| (i, Self::I32(j))), 4 if !signed => Ok(u32::parse(i)?).map(|(i, j)| (i, Self::U32(j))), 8 if !signed => Ok(u64::parse(i)?).map(|(i, j)| (i, Self::U64(j))),