@@ -7,9 +7,12 @@ use etherparse::{
77use pcap:: Address ;
88
99use crate :: Protocol ;
10+ use crate :: networking:: parse_packets:: AddressesResolutionState ;
1011use crate :: networking:: types:: address_port_pair:: AddressPortPair ;
1112use crate :: networking:: types:: arp_type:: ArpType ;
1213use crate :: networking:: types:: bogon:: is_bogon;
14+ use crate :: networking:: types:: data_info:: DataInfo ;
15+ use crate :: networking:: types:: data_info_host:: DataInfoHost ;
1316use crate :: networking:: types:: icmp_type:: { IcmpType , IcmpTypeV4 , IcmpTypeV6 } ;
1417use crate :: networking:: types:: info_address_port_pair:: InfoAddressPortPair ;
1518use crate :: networking:: types:: info_traffic:: InfoTraffic ;
@@ -356,6 +359,119 @@ pub fn modify_or_insert_in_map(
356359 ( new_info. traffic_direction , new_info. service )
357360}
358361
362+ /// Accounts an already-classified flow against the totals, the rDNS resolution
363+ /// state, the per-host map, and the per-service map.
364+ ///
365+ /// Shared by both capture backends: the pcap pipeline calls it once per packet
366+ /// (`packets` = 1), the IPFIX collector once per flow record (`packets` = the
367+ /// record's packet count).
368+ #[ allow( clippy:: too_many_arguments) ]
369+ pub fn account_flow (
370+ info_traffic_msg : & mut InfoTraffic ,
371+ resolutions_state : & mut AddressesResolutionState ,
372+ key : & AddressPortPair ,
373+ my_interface_addresses : & [ Address ] ,
374+ bytes : u128 ,
375+ packets : u128 ,
376+ direction : TrafficDirection ,
377+ service : Service ,
378+ ) {
379+ let now = Instant :: now ( ) ;
380+
381+ info_traffic_msg
382+ . tot_data_info
383+ . add_packets ( packets, bytes, direction, now) ;
384+
385+ // check the rDNS status of this address and act accordingly
386+ let address_to_lookup = get_address_to_lookup ( key, direction) ;
387+ let mut r_dns_waiting_resolution = false ;
388+ let r_dns_already_resolved = resolutions_state
389+ . addresses_resolved
390+ . contains_key ( & address_to_lookup) ;
391+ if !r_dns_already_resolved {
392+ r_dns_waiting_resolution = resolutions_state
393+ . addresses_waiting_resolution
394+ . contains_key ( & address_to_lookup) ;
395+ }
396+
397+ match ( r_dns_waiting_resolution, r_dns_already_resolved) {
398+ ( false , false ) => {
399+ // rDNS not requested yet (first occurrence of this address to lookup)
400+
401+ // Add this address to the map of addresses waiting for a resolution
402+ // Useful to NOT perform again a rDNS lookup for this entry
403+ let mut data_info = DataInfo :: default ( ) ;
404+ data_info. add_packets ( packets, bytes, direction, now) ;
405+ resolutions_state
406+ . addresses_waiting_resolution
407+ . insert ( address_to_lookup, data_info) ;
408+
409+ // send the rDNS lookup request to the thread pool
410+ let _ = resolutions_state. lookup_request_tx . try_send ( (
411+ * key,
412+ direction,
413+ my_interface_addresses. to_vec ( ) ,
414+ ) ) ;
415+ }
416+ ( true , false ) => {
417+ // waiting for a previously requested rDNS resolution
418+ // update the corresponding waiting address data
419+ resolutions_state
420+ . addresses_waiting_resolution
421+ . entry ( address_to_lookup)
422+ . and_modify ( |data_info| {
423+ data_info. add_packets ( packets, bytes, direction, now) ;
424+ } ) ;
425+ }
426+ ( _, true ) => {
427+ // rDNS already resolved
428+ // update the corresponding host's data info
429+ let host = resolutions_state
430+ . addresses_resolved
431+ . get ( & address_to_lookup)
432+ . cloned ( )
433+ . unwrap_or_default ( ) ;
434+ info_traffic_msg
435+ . hosts
436+ . entry ( host)
437+ . and_modify ( |data_info_host| {
438+ data_info_host
439+ . data_info
440+ . add_packets ( packets, bytes, direction, now) ;
441+ } )
442+ . or_insert_with ( || {
443+ let traffic_type =
444+ get_traffic_type ( & address_to_lookup, my_interface_addresses, direction) ;
445+ let is_loopback = address_to_lookup. is_loopback ( ) ;
446+ let is_local = is_local_connection ( & address_to_lookup, my_interface_addresses) ;
447+ let is_bogon = is_bogon ( & address_to_lookup) ;
448+ let mut data_info = DataInfo :: default ( ) ;
449+ data_info. add_packets ( packets, bytes, direction, now) ;
450+ DataInfoHost {
451+ data_info,
452+ is_loopback,
453+ is_local,
454+ is_bogon,
455+ traffic_type,
456+ }
457+ } ) ;
458+ }
459+ }
460+
461+ //increment the packet count for the sniffed service
462+ info_traffic_msg
463+ . services
464+ . entry ( service)
465+ . and_modify ( |data_info| {
466+ data_info. add_packets ( packets, bytes, direction, now) ;
467+ } )
468+ . or_insert_with ( || {
469+ let mut data_info = DataInfo :: default ( ) ;
470+ data_info. add_packets ( packets, bytes, direction, now) ;
471+ data_info
472+ } ) ;
473+ }
474+
359475/// Returns the traffic direction observed (incoming or outgoing)
360476fn get_traffic_direction (
361477 source_ip : & IpAddr ,
0 commit comments