@@ -157,9 +157,10 @@ pub struct TemplateField {
157
157
}
158
158
159
159
fn set_entperprise_field ( field_type : IPFixField , enterprise_number : Option < u32 > ) -> IPFixField {
160
- match enterprise_number {
161
- Some ( _) => IPFixField :: Enterprise ,
162
- None => field_type,
160
+ if enterprise_number. is_some ( ) {
161
+ IPFixField :: Enterprise
162
+ } else {
163
+ field_type
163
164
}
164
165
}
165
166
@@ -170,9 +171,7 @@ fn parse_options_template(i: &[u8], length: u16) -> IResult<&[u8], OptionsTempla
170
171
Ok ( ( remaining, option_template) )
171
172
}
172
173
173
- // Hacky way when using Template as generic T to cast to a common field type.
174
- // We use OptionsTemplateField as it is the same as type Template Field but
175
- // with enterprise_field. In TemplateField tpe enterprise_field is just None.
174
+ // Common trait for both templates. Mainly for fetching fields.
176
175
trait CommonTemplate {
177
176
fn get_fields ( & self ) -> & Vec < TemplateField > ;
178
177
}
@@ -196,47 +195,48 @@ fn parse_fields<'a, T: CommonTemplate>(
196
195
i : & ' a [ u8 ] ,
197
196
template : Option < & T > ,
198
197
) -> IResult < & ' a [ u8 ] , Vec < BTreeMap < IPFixField , FieldValue > > > {
199
- let template = match template {
200
- Some ( t) => t,
201
- None => {
202
- // dbg!("Could not fetch any v10 templates!");
203
- return Err ( NomErr :: Error ( NomError :: new ( i, ErrorKind :: Fail ) ) ) ;
198
+ fn parse_field < ' a > (
199
+ i : & ' a [ u8 ] ,
200
+ template_field : & TemplateField ,
201
+ ) -> IResult < & ' a [ u8 ] , FieldValue > {
202
+ // Enterprise Number
203
+ if template_field. enterprise_number . is_some ( ) {
204
+ let ( remaining, data_number) = DataNumber :: parse ( i, 4 , false ) ?;
205
+ Ok ( ( remaining, FieldValue :: DataNumber ( data_number) ) )
206
+ // Type matching
207
+ } else {
208
+ Ok ( DataNumber :: from_field_type (
209
+ i,
210
+ template_field. field_type . into ( ) ,
211
+ template_field. field_length ,
212
+ ) ) ?
204
213
}
205
- } ;
206
- let template_fields = template. get_fields ( ) ;
207
- // If no fields there are no fields to parse
214
+ }
215
+
216
+ // If no fields there are no fields to parse, return an error.
217
+ let template_fields = template
218
+ . ok_or ( NomErr :: Error ( NomError :: new ( i, ErrorKind :: Fail ) ) ) ?
219
+ . get_fields ( ) ;
220
+
208
221
if template_fields. is_empty ( ) {
209
222
// dbg!("Template without fields!");
210
223
return Err ( NomErr :: Error ( NomError :: new ( i, ErrorKind :: Fail ) ) ) ;
211
224
} ;
225
+
212
226
let mut fields = vec ! [ ] ;
213
227
let mut remaining = i;
228
+
229
+ // While we have bytes remaining
214
230
while !remaining. is_empty ( ) {
215
231
let mut data_field = BTreeMap :: new ( ) ;
216
232
for template_field in template_fields. iter ( ) {
217
- let field_type: FieldDataType = template_field. field_type . into ( ) ;
218
- // Enterprise Number
219
- if template_field. enterprise_number . is_some ( ) {
220
- let ( i, data_number) = DataNumber :: parse ( remaining, 4 , false ) ?;
221
- remaining = i;
222
- data_field. insert (
223
- template_field. field_type ,
224
- FieldValue :: DataNumber ( data_number) ,
225
- ) ;
226
- continue ;
227
- }
228
- // Type matching
229
- let ( i, field_value) = DataNumber :: from_field_type (
230
- remaining,
231
- field_type,
232
- template_field. field_length ,
233
- ) ?;
233
+ let ( i, field_value) = parse_field ( remaining, template_field) ?;
234
234
remaining = i;
235
235
data_field. insert ( template_field. field_type , field_value) ;
236
236
}
237
237
fields. push ( data_field) ;
238
238
}
239
- Ok ( ( remaining , fields) )
239
+ Ok ( ( & [ ] , fields) )
240
240
}
241
241
242
242
impl NetflowByteParserVariable for IPFixParser {
0 commit comments