#[non_exhaustive]pub struct FlowRecord {Show 31 fields
pub protocol_identifier: u8,
pub source_ipv4_address: Option<Ipv4Addr>,
pub destination_ipv4_address: Option<Ipv4Addr>,
pub source_ipv6_address: Option<Ipv6Addr>,
pub destination_ipv6_address: Option<Ipv6Addr>,
pub source_transport_port: u16,
pub destination_transport_port: u16,
pub octet_delta_count_initiator: u64,
pub octet_delta_count_responder: u64,
pub packet_delta_count_initiator: u64,
pub packet_delta_count_responder: u64,
pub octet_total_count: u64,
pub packet_total_count: u64,
pub flow_start_milliseconds: u64,
pub flow_end_milliseconds: u64,
pub tcp_control_bits_initiator: Option<u16>,
pub tcp_control_bits_responder: Option<u16>,
pub flow_end_reason: Option<FlowEndReason>,
pub source_mac_address: Option<[u8; 6]>,
pub destination_mac_address: Option<[u8; 6]>,
pub ingress_interface: Option<u32>,
pub egress_interface: Option<u32>,
pub application_id: Option<Vec<u8>>,
pub application_name: Option<String>,
pub vlan_id: Option<u16>,
pub layer2_segment_id: Option<u64>,
pub ip_class_of_service: Option<u8>,
pub retransmits_initiator: u64,
pub retransmits_responder: u64,
pub original_end_reason: Option<EndReason>,
pub community_id: Option<String>,
}ipfix only.Expand description
One canonical per-flow record. Field set covers the
IPFIX IEs that mainstream tools (Suricata flow event,
goflow2, nProbe, Zeek conn.log) consume + the
commonly-missing fields called out in #16’s body
(flowEndReason, tcpControlBits).
#[non_exhaustive] — fields land additively as new IEs
become operationally important.
§Per-direction vs. totals
Per RFC 5103 (biflow), flowscope is a biflow analyzer:
every flow has an initiator and responder direction.
FlowRecord carries *_initiator + *_responder
counters (per IPFIX octet/packetTotalCount IEs 85/86
in their reverse-PEN form) PLUS the convenience union
bytes_total / packets_total (IEs 85/86 in the
non-reverse form).
§Construction
Build via FlowRecord::from_parts (the typical path —
from (stats, key, end_reason)) or via Self::default
- mutate.
Issue #16 scoped sub-piece.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.protocol_identifier: u8IANA IE 4 — protocolIdentifier (IP protocol number;
6=TCP, 17=UDP, 1=ICMP, etc.).
source_ipv4_address: Option<Ipv4Addr>IANA IE 8 — sourceIPv4Address. None when the flow
is IPv6 (use Self::source_ipv6_address).
destination_ipv4_address: Option<Ipv4Addr>IANA IE 12 — destinationIPv4Address.
source_ipv6_address: Option<Ipv6Addr>IANA IE 27 — sourceIPv6Address. None when IPv4.
destination_ipv6_address: Option<Ipv6Addr>IANA IE 28 — destinationIPv6Address.
source_transport_port: u16IANA IE 7 — sourceTransportPort.
destination_transport_port: u16IANA IE 11 — destinationTransportPort.
octet_delta_count_initiator: u64IANA IE 1 — octetDeltaCount initiator → responder
direction. Per RFC 5103 biflow this is the forward-
direction byte count.
octet_delta_count_responder: u64IANA IE 1 reverse — responder → initiator octets.
packet_delta_count_initiator: u64IANA IE 2 — packetDeltaCount initiator direction.
packet_delta_count_responder: u64IANA IE 2 reverse — responder direction.
octet_total_count: u64IANA IE 85 — octetTotalCount (both directions
summed). Convenience, populated by Self::from_parts.
packet_total_count: u64IANA IE 86 — packetTotalCount.
flow_start_milliseconds: u64IANA IE 152 — flowStartMilliseconds (absolute time
of the first packet, ms since Unix epoch).
flow_end_milliseconds: u64IANA IE 153 — flowEndMilliseconds.
tcp_control_bits_initiator: Option<u16>IANA IE 6 — tcpControlBits. Cumulative OR of all
observed TCP flags across the flow (initiator
direction). None for non-TCP.
tcp_control_bits_responder: Option<u16>IE 6 reverse — responder-direction cumulative flags.
flow_end_reason: Option<FlowEndReason>IANA IE 136 — flowEndReason. Mapped from
flowscope’s EndReason per the IPFIX-canonical
5-state vocabulary; see FlowEndReason.
source_mac_address: Option<[u8; 6]>IANA IE 56 — sourceMacAddress. None when the
capture point didn’t surface an L2 address (raw-IP
captures, encap stripping).
destination_mac_address: Option<[u8; 6]>IANA IE 80 — destinationMacAddress.
ingress_interface: Option<u32>IANA IE 10 — ingressInterface (capture-point /
NIC-queue index). None when not surfaced.
egress_interface: Option<u32>IANA IE 14 — egressInterface. Almost always None
for a passive observer — included for emitter-shape
completeness.
application_id: Option<Vec<u8>>IANA IE 95 — applicationId. The “type:value” byte
shape Cisco / Palo Alto exporters use; flowscope
leaves the encoding to the consumer.
application_name: Option<String>IANA IE 96 — applicationName. Human-readable app
name. flowscope populates this from
FiveTupleKey::app_label() when Self::from_parts
is used.
vlan_id: Option<u16>IANA IE 58 — vlanId (802.1Q on ingress).
layer2_segment_id: Option<u64>IANA IE 351 — layer2SegmentId (VxLAN VNI / NVGRE
VSID per RFC 7637).
ip_class_of_service: Option<u8>IANA IE 5 — ipClassOfService (IPv4 TOS byte or IPv6
Traffic Class).
retransmits_initiator: u64flowscope ext — TCP retransmit count on the initiator
side. Populated from FlowStats::retransmits_initiator
by Self::from_parts.
retransmits_responder: u64flowscope ext — TCP retransmit count on the responder side.
original_end_reason: Option<EndReason>tracker only.flowscope ext — the unmapped, 8-variant
crate::EndReason as observed by the tracker.
IPFIX Self::flow_end_reason (IE 136) is by design
limited to 5 RFC 7011 standard values, so it cannot
distinguish e.g. Fin from Rst or
BufferOverflow from ParseError —
both pairs collapse to EndOfFlowDetected /
ForcedEnd respectively. Internal flowscope
consumers (CSV / Zeek / NDJSON writers) prefer this
field when present to preserve the 8-variant
fidelity; pure-IPFIX consumers continue to read
flow_end_reason.
None only when the record was constructed without
a lifecycle reason (e.g. a from_parts call with
end_reason = None for a mid-flight snapshot).
Issue #16 close.
community_id: Option<String>flowscope ext — Corelight Community ID v1 (the canonical,
cross-tool flow identifier: Zeek / Suricata / Security Onion all
pivot on it). "1:"-prefixed SHA-1 + base64 over the canonical
5-tuple. Populated by Self::from_parts only when the
community-id feature is enabled (it requires SHA-1 + base64);
None otherwise. The NDJSON / CSV / EVE FlowRecord writers emit
this field as the portable flow id.
Issue #88.
Implementations§
Source§impl FlowRecord
impl FlowRecord
Sourcepub fn from_parts(
stats: &FlowStats,
key: &FiveTupleKey,
end_reason: Option<EndReason>,
) -> Self
Available on crate feature tracker only.
pub fn from_parts( stats: &FlowStats, key: &FiveTupleKey, end_reason: Option<EndReason>, ) -> Self
tracker only.Build a FlowRecord from flowscope’s existing
per-flow state — the FlowStats counters, the
FiveTupleKey, and the lifecycle EndReason.
Thin wrapper around Self::from_key_fields kept
for the FiveTupleKey-specialised call site. Both
produce identical FlowRecords.
The conversion handles:
- IPv4 / IPv6 routing (which IE fields populate
based on
key). - Per-direction → total roll-up (IEs 85 / 86).
flow_start/end_millisecondsconversion fromcrate::Timestamp.EndReason→FlowEndReasonmapping (IE 136).- Protocol identifier from
key.proto.
Fields the per-flow state doesn’t carry (mgmt
interface, application id, VLAN, segment id, CoS)
stay None; consumers populate them themselves
from per-packet metadata.
Sourcepub fn from_key_fields<K>(
stats: &FlowStats,
key: &K,
end_reason: Option<EndReason>,
) -> Self
Available on crate feature tracker only.
pub fn from_key_fields<K>( stats: &FlowStats, key: &K, end_reason: Option<EndReason>, ) -> Self
tracker only.Generic constructor — build a FlowRecord from any
K: KeyFields. Used by every emit writer’s
write_event(Ended) path so the IE-keyed FlowRecord
is the single canonical record shape; emit writers are
pure views over it.
Defaults:
- IPv4 / IPv6 addresses populate from
K::src_ip/K::dest_ip; absent → fields stayNone. - Ports from
K::src_port/K::dest_port; absent →0. protocol_identifierfromK::protocol_identifier; absent →0(IPFIX IE 4 = 0 is reserved for HOPOPT but commonly used as “unspecified” in tracking systems).application_namefromK::app_proto_strwhen present.
Issue #16.
Sourcepub fn observe_tcp_flags(
&mut self,
from_initiator: bool,
fin: bool,
syn: bool,
rst: bool,
psh: bool,
ack: bool,
urg: bool,
ece: bool,
cwr: bool,
)
pub fn observe_tcp_flags( &mut self, from_initiator: bool, fin: bool, syn: bool, rst: bool, psh: bool, ack: bool, urg: bool, ece: bool, cwr: bool, )
Fold the TCP-flags-observed bitmask into the record’s
tcp_control_bits_* field for the given direction.
Bitwise-OR with any prior value — IE 6 is cumulative
per RFC 7125.
Convenience wrapper around encode_tcp_control_bits.
Sourcepub fn sockets(&self) -> Option<(SocketAddr, SocketAddr)>
pub fn sockets(&self) -> Option<(SocketAddr, SocketAddr)>
Returns the canonical (SocketAddr, SocketAddr) pair
for the flow, reconstructed from whichever of the v4
/ v6 fields are populated. Useful for consumers that
stored a record and need to recover the key.
Trait Implementations§
Source§impl Clone for FlowRecord
impl Clone for FlowRecord
Source§fn clone(&self) -> FlowRecord
fn clone(&self) -> FlowRecord
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for FlowRecord
impl Debug for FlowRecord
Source§impl Default for FlowRecord
impl Default for FlowRecord
Source§fn default() -> FlowRecord
fn default() -> FlowRecord
Source§impl<'de> Deserialize<'de> for FlowRecord
impl<'de> Deserialize<'de> for FlowRecord
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl Eq for FlowRecord
Source§impl PartialEq for FlowRecord
impl PartialEq for FlowRecord
Source§impl Serialize for FlowRecord
impl Serialize for FlowRecord
impl StructuralPartialEq for FlowRecord
Auto Trait Implementations§
impl Freeze for FlowRecord
impl RefUnwindSafe for FlowRecord
impl Send for FlowRecord
impl Sync for FlowRecord
impl Unpin for FlowRecord
impl UnsafeUnpin for FlowRecord
impl UnwindSafe for FlowRecord
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.