Skip to content

Commit 959e597

Browse files
Fix parsing flowsets (#23)
* Fix parsing flowsets * Fix fmt
1 parent 8a9faca commit 959e597

File tree

3 files changed

+76
-1
lines changed

3 files changed

+76
-1
lines changed

src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,16 @@ mod tests {
312312
assert_yaml_snapshot!(NetflowParser::default().parse_bytes(&packet));
313313
}
314314

315+
#[test]
316+
fn it_parses_v9_many_flows() {
317+
let packet = [
318+
0, 9, 0, 3, 0, 0, 9, 9, 0, 1, 2, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 16, 1, 2, 0,
319+
2, 0, 1, 0, 4, 0, 8, 0, 4, 1, 2, 0, 12, 9, 2, 3, 4, 9, 9, 9, 8, 9, 2, 3, 4, 9, 9,
320+
9, 8,
321+
];
322+
assert_yaml_snapshot!(NetflowParser::default().parse_bytes(&packet));
323+
}
324+
315325
#[test]
316326
fn it_parses_v9_options_template() {
317327
let packet = [
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
source: src/lib.rs
3+
expression: "NetflowParser::default().parse_bytes(&packet)"
4+
---
5+
- V9:
6+
header:
7+
version: 9
8+
count: 3
9+
sys_up_time: 2313
10+
unix_secs: 66051
11+
sequence_number: 1
12+
source_id: 1
13+
flowsets:
14+
- flow_set_id: 0
15+
template:
16+
length: 16
17+
template_id: 258
18+
field_count: 2
19+
fields:
20+
- field_type_number: 1
21+
field_type: InBytes
22+
field_length: 4
23+
- field_type_number: 8
24+
field_type: Ipv4SrcAddr
25+
field_length: 4
26+
- flow_set_id: 258
27+
data:
28+
length: 12
29+
data_fields:
30+
- InBytes:
31+
DataNumber: 151126788
32+
Ipv4SrcAddr:
33+
Ip4Addr: 9.9.9.8
34+
- InBytes:
35+
DataNumber: 151126788
36+
Ipv4SrcAddr:
37+
Ip4Addr: 9.9.9.8
38+

src/variable_versions/v9.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,37 @@ pub struct V9 {
4141
/// V9 Header
4242
pub header: Header,
4343
/// Flowsets
44-
#[nom(Count = "header.count", Parse = "{ |i| FlowSet::parse(i, parser) }")]
44+
#[nom(Parse = "{ |i| parse_flowsets(i, parser, header.count as usize) }")]
4545
pub flowsets: Vec<FlowSet>,
4646
}
4747

48+
fn parse_flowsets<'a, 'b>(
49+
i: &'a [u8],
50+
parser: &'b mut V9Parser,
51+
mut count: usize,
52+
) -> IResult<&'a [u8], Vec<FlowSet>> {
53+
let mut flowsets = vec![];
54+
let mut remaining = i;
55+
56+
// Header.count represents total number of records in data + records in templates
57+
while count > 0 {
58+
let (i, flowset) = FlowSet::parse(remaining, parser)?;
59+
remaining = i;
60+
61+
if flowset.template.is_some() || flowset.options_template.is_some() {
62+
count = count.saturating_sub(1);
63+
} else if let Some(data) = flowset.data.as_ref() {
64+
count = count.saturating_sub(data.data_fields.len());
65+
} else if let Some(_) = flowset.options_data.as_ref() {
66+
count = count.saturating_sub(1);
67+
}
68+
69+
flowsets.push(flowset)
70+
}
71+
72+
Ok((remaining, flowsets))
73+
}
74+
4875
#[derive(Debug, PartialEq, Clone, Copy, Serialize, Nom)]
4976
pub struct Header {
5077
/// The version of NetFlow records exported in this packet; for Version 9, this value is 9

0 commit comments

Comments
 (0)