sflow_parser/models/
record_flows.rs

1//! Flow record data structures
2//!
3//! These represent the actual packet data captured in flow samples.
4//! Enterprise = 0 (sFlow.org standard formats)
5
6use std::net::{Ipv4Addr, Ipv6Addr};
7
8/// Header protocol types for sampled headers
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum HeaderProtocol {
11    EthernetIso88023 = 1,
12    Iso88024TokenBus = 2,
13    Iso88025TokenRing = 3,
14    Fddi = 4,
15    FrameRelay = 5,
16    X25 = 6,
17    Ppp = 7,
18    Smds = 8,
19    Aal5 = 9,
20    Aal5Ip = 10,
21    Ipv4 = 11,
22    Ipv6 = 12,
23    Mpls = 13,
24    Pos = 14,
25    Ieee80211Mac = 15,
26    Ieee80211Ampdu = 16,
27    Ieee80211Amsdu = 17,
28}
29
30impl HeaderProtocol {
31    /// Convert from u32 value to HeaderProtocol enum
32    pub fn from_u32(value: u32) -> Option<Self> {
33        match value {
34            1 => Some(HeaderProtocol::EthernetIso88023),
35            2 => Some(HeaderProtocol::Iso88024TokenBus),
36            3 => Some(HeaderProtocol::Iso88025TokenRing),
37            4 => Some(HeaderProtocol::Fddi),
38            5 => Some(HeaderProtocol::FrameRelay),
39            6 => Some(HeaderProtocol::X25),
40            7 => Some(HeaderProtocol::Ppp),
41            8 => Some(HeaderProtocol::Smds),
42            9 => Some(HeaderProtocol::Aal5),
43            10 => Some(HeaderProtocol::Aal5Ip),
44            11 => Some(HeaderProtocol::Ipv4),
45            12 => Some(HeaderProtocol::Ipv6),
46            13 => Some(HeaderProtocol::Mpls),
47            14 => Some(HeaderProtocol::Pos),
48            15 => Some(HeaderProtocol::Ieee80211Mac),
49            16 => Some(HeaderProtocol::Ieee80211Ampdu),
50            17 => Some(HeaderProtocol::Ieee80211Amsdu),
51            _ => None,
52        }
53    }
54}
55
56impl std::fmt::Display for HeaderProtocol {
57    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58        match self {
59            HeaderProtocol::EthernetIso88023 => write!(f, "Ethernet (ISO 802.3)"),
60            HeaderProtocol::Iso88024TokenBus => write!(f, "ISO 802.4 Token Bus"),
61            HeaderProtocol::Iso88025TokenRing => write!(f, "ISO 802.5 Token Ring"),
62            HeaderProtocol::Fddi => write!(f, "FDDI"),
63            HeaderProtocol::FrameRelay => write!(f, "Frame Relay"),
64            HeaderProtocol::X25 => write!(f, "X.25"),
65            HeaderProtocol::Ppp => write!(f, "PPP"),
66            HeaderProtocol::Smds => write!(f, "SMDS"),
67            HeaderProtocol::Aal5 => write!(f, "AAL5"),
68            HeaderProtocol::Aal5Ip => write!(f, "AAL5 IP"),
69            HeaderProtocol::Ipv4 => write!(f, "IPv4"),
70            HeaderProtocol::Ipv6 => write!(f, "IPv6"),
71            HeaderProtocol::Mpls => write!(f, "MPLS"),
72            HeaderProtocol::Pos => write!(f, "POS"),
73            HeaderProtocol::Ieee80211Mac => write!(f, "IEEE 802.11 MAC"),
74            HeaderProtocol::Ieee80211Ampdu => write!(f, "IEEE 802.11 A-MPDU"),
75            HeaderProtocol::Ieee80211Amsdu => write!(f, "IEEE 802.11 A-MSDU"),
76        }
77    }
78}
79
80/// Sampled Header - Format (0,1)
81///
82/// Raw packet header captured from the wire
83///
84/// # XDR Definition (sFlow v5)
85///
86/// ```text
87/// /* Raw Packet Header */
88/// /* opaque = flow_data; enterprise = 0; format = 1 */
89///
90/// struct sampled_header {
91///     header_protocol protocol;  /* Format of sampled header */
92///     unsigned int frame_length; /* Original length of packet before sampling */
93///     unsigned int stripped;     /* Number of octets removed from packet */
94///     opaque header<>;           /* Header bytes */
95/// }
96/// ```
97#[derive(Debug, Clone, PartialEq, Eq)]
98pub struct SampledHeader {
99    /// Protocol of the sampled packet
100    pub protocol: HeaderProtocol,
101
102    /// Original length of the packet (before sampling)
103    pub frame_length: u32,
104
105    /// Number of bytes stripped from the packet before sampling
106    pub stripped: u32,
107
108    /// Raw header bytes
109    pub header: Vec<u8>,
110}
111
112/// Sampled Ethernet Frame - Format (0,2)
113///
114/// Ethernet frame header information
115///
116/// # XDR Definition (sFlow v5)
117///
118/// ```text
119/// /* Ethernet Frame Data */
120/// /* opaque = flow_data; enterprise = 0; format = 2 */
121///
122/// struct sampled_ethernet {
123///     unsigned int length;   /* The length of the MAC packet received on the
124///                               network, excluding lower layer encapsulations
125///                               and framing bits but including FCS octets */
126///     mac src_mac;           /* Source MAC address */
127///     mac dst_mac;           /* Destination MAC address */
128///     unsigned int type;     /* Ethernet packet type */
129/// }
130/// ```
131#[derive(Debug, Clone, PartialEq, Eq)]
132pub struct SampledEthernet {
133    /// Length of MAC packet in bytes
134    pub length: u32,
135
136    /// Source MAC address
137    pub src_mac: crate::models::MacAddress,
138
139    /// Destination MAC address
140    pub dst_mac: crate::models::MacAddress,
141
142    /// Ethernet type
143    pub eth_type: u32,
144}
145
146/// Sampled IPv4 - Format (0,3)
147///
148/// IPv4 packet header information
149///
150/// # XDR Definition (sFlow v5)
151///
152/// ```text
153/// /* Packet IP version 4 data */
154/// /* opaque = flow_data; enterprise = 0; format = 3 */
155///
156/// struct sampled_ipv4 {
157///     unsigned int length;     /* Length of IP packet excluding lower layer encapsulations */
158///     unsigned int protocol;   /* IP Protocol type (e.g., TCP = 6, UDP = 17) */
159///     ip_v4 src_ip;            /* Source IP Address */
160///     ip_v4 dst_ip;            /* Destination IP Address */
161///     unsigned int src_port;   /* TCP/UDP source port number or equivalent */
162///     unsigned int dst_port;   /* TCP/UDP destination port number or equivalent */
163///     unsigned int tcp_flags;  /* TCP flags */
164///     unsigned int tos;        /* IP type of service */
165/// }
166/// ```
167#[derive(Debug, Clone, PartialEq, Eq)]
168pub struct SampledIpv4 {
169    /// Length of IP packet in bytes
170    pub length: u32,
171
172    /// IP Protocol (TCP=6, UDP=17, etc.)
173    pub protocol: u32,
174
175    /// Source IP address
176    pub src_ip: Ipv4Addr,
177
178    /// Destination IP address
179    pub dst_ip: Ipv4Addr,
180
181    /// Source port (for TCP/UDP)
182    pub src_port: u32,
183
184    /// Destination port (for TCP/UDP)
185    pub dst_port: u32,
186
187    /// TCP flags
188    pub tcp_flags: u32,
189
190    /// Type of Service
191    pub tos: u32,
192}
193
194/// Sampled IPv6 - Format (0,4)
195///
196/// IPv6 packet header information
197///
198/// # XDR Definition (sFlow v5)
199///
200/// ```text
201/// /* Packet IP Version 6 Data */
202/// /* opaque = flow_data; enterprise = 0; format = 4 */
203///
204/// struct sampled_ipv6 {
205///     unsigned int length;     /* Length of IP packet excluding lower layer encapsulations */
206///     unsigned int protocol;   /* IP next header (e.g., TCP = 6, UDP = 17) */
207///     ip_v6 src_ip;            /* Source IP Address */
208///     ip_v6 dst_ip;            /* Destination IP Address */
209///     unsigned int src_port;   /* TCP/UDP source port number or equivalent */
210///     unsigned int dst_port;   /* TCP/UDP destination port number or equivalent */
211///     unsigned int tcp_flags;  /* TCP flags */
212///     unsigned int priority;   /* IP priority */
213/// }
214/// ```
215#[derive(Debug, Clone, PartialEq, Eq)]
216pub struct SampledIpv6 {
217    /// Length of IP packet in bytes
218    pub length: u32,
219
220    /// IP Protocol (TCP=6, UDP=17, etc.)
221    pub protocol: u32,
222
223    /// Source IP address
224    pub src_ip: Ipv6Addr,
225
226    /// Destination IP address
227    pub dst_ip: Ipv6Addr,
228
229    /// Source port (for TCP/UDP)
230    pub src_port: u32,
231
232    /// Destination port (for TCP/UDP)
233    pub dst_port: u32,
234
235    /// TCP flags
236    pub tcp_flags: u32,
237
238    /// Priority (traffic class)
239    pub priority: u32,
240}
241
242/// Extended Switch Data - Format (0,1001)
243///
244/// Layer 2 switching information
245///
246/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
247///
248/// ```text
249/// /* Extended Switch Data */
250/// /* opaque = flow_data; enterprise = 0; format = 1001 */
251///
252/// struct extended_switch {
253///     unsigned int src_vlan;     /* The 802.1Q VLAN id of incoming frame */
254///     unsigned int src_priority; /* The 802.1p priority of incoming frame */
255///     unsigned int dst_vlan;     /* The 802.1Q VLAN id of outgoing frame */
256///     unsigned int dst_priority; /* The 802.1p priority of outgoing frame */
257/// }
258/// ```
259#[derive(Debug, Clone, PartialEq, Eq)]
260pub struct ExtendedSwitch {
261    /// Source VLAN ID
262    pub src_vlan: u32,
263
264    /// Source priority (802.1p)
265    pub src_priority: u32,
266
267    /// Destination VLAN ID
268    pub dst_vlan: u32,
269
270    /// Destination priority (802.1p)
271    pub dst_priority: u32,
272}
273
274/// Extended Router Data - Format (0,1002)
275///
276/// Layer 3 routing information
277///
278/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
279///
280/// ```text
281/// /* Extended Router Data */
282/// /* opaque = flow_data; enterprise = 0; format = 1002 */
283///
284/// struct extended_router {
285///     next_hop nexthop;          /* IP address of next hop router */
286///     unsigned int src_mask_len; /* Source address prefix mask (number of bits) */
287///     unsigned int dst_mask_len; /* Destination address prefix mask (number of bits) */
288/// }
289/// ```
290#[derive(Debug, Clone, PartialEq, Eq)]
291pub struct ExtendedRouter {
292    /// IP address of next hop router
293    pub next_hop: crate::models::core::Address,
294
295    /// Source subnet mask bits
296    pub src_mask_len: u32,
297
298    /// Destination subnet mask bits
299    pub dst_mask_len: u32,
300}
301
302/// AS Path Type
303#[derive(Debug, Clone, Copy, PartialEq, Eq)]
304pub enum AsPathType {
305    AsSet = 1,
306    AsSequence = 2,
307}
308
309/// AS Path Segment
310#[derive(Debug, Clone, PartialEq, Eq)]
311pub struct AsPathSegment {
312    pub path_type: u32,
313    pub path_length: u32,
314    pub path: Vec<u32>,
315}
316
317/// Extended Gateway Data - Format (0,1003)
318///
319/// BGP routing information
320///
321/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
322///
323/// ```text
324/// /* Extended Gateway Data */
325/// /* opaque = flow_data; enterprise = 0; format = 1003 */
326///
327/// struct extended_gateway {
328///     next_hop nexthop;           /* Address of the border router */
329///     unsigned int as;            /* Autonomous system number of router */
330///     unsigned int src_as;        /* Autonomous system number of source */
331///     unsigned int src_peer_as;   /* Autonomous system number of source peer */
332///     as_path_type dst_as_path<>; /* AS path to the destination */
333///     unsigned int communities<>; /* Communities associated with this route */
334///     unsigned int localpref;     /* LocalPref associated with this route */
335/// }
336/// ```
337#[derive(Debug, Clone, PartialEq, Eq)]
338pub struct ExtendedGateway {
339    /// IP address of the border router
340    pub next_hop: crate::models::core::Address,
341
342    /// Autonomous system number
343    pub as_number: u32,
344
345    /// Source AS
346    pub src_as: u32,
347
348    /// Source peer AS
349    pub src_peer_as: u32,
350
351    /// Autonomous system path to the destination
352    pub dst_as_path: Vec<AsPathSegment>,
353
354    /// BGP communities
355    pub communities: Vec<u32>,
356
357    /// Local preference
358    pub local_pref: u32,
359}
360
361/// Extended User Data - Format (0,1004)
362///
363/// Application-level user information
364///
365/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
366///
367/// ```text
368/// /* Extended User Data */
369/// /* opaque = flow_data; enterprise = 0; format = 1004 */
370///
371/// struct extended_user {
372///     charset src_charset;   /* Character set for src_user */
373///     opaque src_user<>;     /* User ID associated with packet source */
374///     charset dst_charset;   /* Character set for dst_user */
375///     opaque dst_user<>;     /* User ID associated with packet destination */
376/// }
377/// ```
378#[derive(Debug, Clone, PartialEq, Eq)]
379pub struct ExtendedUser {
380    /// Source character set (MIBEnum)
381    pub src_charset: u32,
382
383    /// Source user ID
384    pub src_user: String,
385
386    /// Destination character set (MIBEnum)
387    pub dst_charset: u32,
388
389    /// Destination user ID
390    pub dst_user: String,
391}
392
393/// URL Direction
394#[derive(Debug, Clone, Copy, PartialEq, Eq)]
395pub enum UrlDirection {
396    Source = 1,
397    Destination = 2,
398}
399
400/// Extended URL Data - Format (0,1005)
401///
402/// HTTP request information
403///
404/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
405///
406/// ```text
407/// /* Extended URL Data */
408/// /* opaque = flow_data; enterprise = 0; format = 1005 */
409///
410/// struct extended_url {
411///     url_direction direction; /* Direction of connection */
412///     string url<>;            /* The HTTP request-line (see RFC 2616) */
413///     string host<>;           /* The host field from the HTTP header */
414/// }
415/// ```
416#[derive(Debug, Clone, PartialEq, Eq)]
417pub struct ExtendedUrl {
418    /// Direction (source or destination)
419    pub direction: u32,
420
421    /// URL string (HTTP request-line)
422    pub url: String,
423
424    /// Host header from HTTP request
425    pub host: String,
426}
427
428/// Extended MPLS Data - Format (0,1006)
429///
430/// MPLS label stack information
431///
432/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
433///
434/// ```text
435/// /* Extended MPLS Data */
436/// /* opaque = flow_data; enterprise = 0; format = 1006 */
437///
438/// struct extended_mpls {
439///     next_hop nexthop;     /* Address of the next hop */
440///     label_stack in_stack; /* Label stack of received packet */
441///     label_stack out_stack;/* Label stack for transmitted packet */
442/// }
443/// ```
444#[derive(Debug, Clone, PartialEq, Eq)]
445pub struct ExtendedMpls {
446    /// Next hop address
447    pub next_hop: crate::models::core::Address,
448
449    /// Input label stack
450    pub in_stack: Vec<u32>,
451
452    /// Output label stack
453    pub out_stack: Vec<u32>,
454}
455
456/// Extended NAT Data - Format (0,1007)
457///
458/// Network Address Translation information
459///
460/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
461///
462/// ```text
463/// /* Extended NAT Data */
464/// /* opaque = flow_data; enterprise = 0; format = 1007 */
465///
466/// struct extended_nat {
467///     address src_address; /* Source address */
468///     address dst_address; /* Destination address */
469/// }
470/// ```
471#[derive(Debug, Clone, PartialEq, Eq)]
472pub struct ExtendedNat {
473    /// Source address type
474    pub src_address: crate::models::core::Address,
475
476    /// Destination address type
477    pub dst_address: crate::models::core::Address,
478}
479
480/// Extended MPLS Tunnel - Format (0,1008)
481///
482/// MPLS tunnel information
483///
484/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
485///
486/// ```text
487/// /* Extended MPLS Tunnel */
488/// /* opaque = flow_data; enterprise = 0; format = 1008 */
489///
490/// struct extended_mpls_tunnel {
491///     string tunnel_lsp_name<>; /* Tunnel name */
492///     unsigned int tunnel_id;   /* Tunnel ID */
493///     unsigned int tunnel_cos;  /* Tunnel COS value */
494/// }
495/// ```
496#[derive(Debug, Clone, PartialEq, Eq)]
497pub struct ExtendedMplsTunnel {
498    /// Tunnel LSP name
499    pub tunnel_lsp_name: String,
500
501    /// Tunnel ID
502    pub tunnel_id: u32,
503
504    /// Tunnel COS value
505    pub tunnel_cos: u32,
506}
507
508/// Extended MPLS VC - Format (0,1009)
509///
510/// MPLS Virtual Circuit information
511///
512/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
513///
514/// ```text
515/// /* Extended MPLS VC */
516/// /* opaque = flow_data; enterprise = 0; format = 1009 */
517///
518/// struct extended_mpls_vc {
519///     string vc_instance_name<>; /* VC instance name */
520///     unsigned int vll_vc_id;    /* VLL/VC instance ID */
521///     unsigned int vc_label_cos; /* VC Label COS value */
522/// }
523/// ```
524#[derive(Debug, Clone, PartialEq, Eq)]
525pub struct ExtendedMplsVc {
526    /// VC instance name
527    pub vc_instance_name: String,
528
529    /// VC ID
530    pub vll_vc_id: u32,
531
532    /// VC label
533    pub vc_label: u32,
534
535    /// VC COS
536    pub vc_cos: u32,
537}
538
539/// Extended MPLS FEC - Format (0,1010)
540///
541/// MPLS Forwarding Equivalence Class information
542///
543/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
544///
545/// ```text
546/// /* Extended MPLS FEC */
547/// /* opaque = flow_data; enterprise = 0; format = 1010 */
548///
549/// struct extended_mpls_FTN {
550///     string mplsFTNDescr<>;  /* FEC description */
551///     unsigned int mplsFTNMask; /* FEC mask */
552/// }
553/// ```
554#[derive(Debug, Clone, PartialEq, Eq)]
555pub struct ExtendedMplsFec {
556    /// FEC address prefix
557    pub fec_addr_prefix: crate::models::core::Address,
558
559    /// FEC prefix length
560    pub fec_prefix_len: u32,
561}
562
563/// Extended MPLS LVP FEC - Format (0,1011)
564///
565/// MPLS LDP FEC information
566///
567/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
568///
569/// ```text
570/// /* Extended MPLS LVP FEC */
571/// /* opaque = flow_data; enterprise = 0; format = 1011 */
572///
573/// struct extended_mpls_LDP_FEC {
574///     unsigned int mplsFecAddrPrefixLength; /* FEC address prefix length */
575/// }
576/// ```
577#[derive(Debug, Clone, PartialEq, Eq)]
578pub struct ExtendedMplsLvpFec {
579    /// FEC address prefix length
580    pub mpls_fec_addr_prefix_length: u32,
581}
582
583/// Extended VLAN Tunnel - Format (0,1012)
584///
585/// VLAN tunnel information for nested VLAN tags
586///
587/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
588///
589/// ```text
590/// /* Extended VLAN tunnel information */
591/// /* opaque = flow_data; enterprise = 0; format = 1012 */
592///
593/// struct extended_vlantunnel {
594///     unsigned int stack<>; /* List of stripped 802.1Q TPID/TCI layers */
595/// }
596/// ```
597#[derive(Debug, Clone, PartialEq, Eq)]
598pub struct ExtendedVlanTunnel {
599    /// List of stripped 802.1Q TPID/TCI layers
600    pub stack: Vec<u32>,
601}
602
603/// Extended 802.11 Payload - Format (0,1013)
604///
605/// Unencrypted 802.11 payload data
606///
607/// # XDR Definition ([sFlow 802.11](https://sflow.org/sflow_80211.txt))
608///
609/// ```text
610/// /* Extended 80211 Payload */
611/// /* opaque = flow_data; enterprise = 0; format = 1013 */
612///
613/// struct extended_80211_payload {
614///     cipher_suite ciphersuite; /* encryption scheme used for this packet */
615///     opaque data<>;            /* unencrypted bytes from the payload */
616/// }
617/// ```
618#[derive(Debug, Clone, PartialEq, Eq)]
619pub struct Extended80211Payload {
620    /// Cipher suite (OUI + Suite Type)
621    pub cipher_suite: u32,
622
623    /// Unencrypted payload data
624    pub data: Vec<u8>,
625}
626
627/// Extended 802.11 RX - Format (0,1014)
628///
629/// 802.11 receive information
630///
631/// # XDR Definition ([sFlow 802.11](https://sflow.org/sflow_80211.txt))
632///
633/// ```text
634/// /* Extended 802.11 RX */
635/// /* opaque = flow_data; enterprise = 0; format = 1014 */
636///
637/// struct extended_80211_rx {
638///     string ssid<32>;           /* SSID string */
639///     mac bssid;                 /* BSSID */
640///     ieee80211_version version; /* version */
641///     unsigned int channel;      /* channel number */
642///     unsigned hyper speed;      /* speed */
643///     unsigned int rsni;         /* received signal to noise ratio */
644///     unsigned int rcpi;         /* received channel power */
645///     duration_us packet_duration; /* time packet occupied RF medium */
646/// }
647/// ```
648#[derive(Debug, Clone, PartialEq, Eq)]
649pub struct Extended80211Rx {
650    /// SSID string (max 32 bytes)
651    pub ssid: String,
652
653    /// BSSID (MAC address)
654    pub bssid: crate::models::MacAddress,
655
656    /// IEEE 802.11 version (a=1, b=2, g=3, n=4)
657    pub version: u32,
658
659    /// Channel number
660    pub channel: u32,
661
662    /// Speed in bits per second
663    pub speed: u64,
664
665    /// Received signal to noise ratio (RSNI)
666    pub rsni: u32,
667
668    /// Received channel power indicator (RCPI)
669    pub rcpi: u32,
670
671    /// Packet duration in microseconds
672    pub packet_duration: u32,
673}
674
675/// Extended 802.11 TX - Format (0,1015)
676///
677/// 802.11 transmit information
678///
679/// # XDR Definition ([sFlow 802.11](https://sflow.org/sflow_80211.txt))
680///
681/// ```text
682/// /* Extended 802.11 TX */
683/// /* opaque = flow_data; enterprise = 0; format = 1015 */
684///
685/// struct extended_80211_tx {
686///     string ssid<32>;             /* SSID string */
687///     mac bssid;                   /* BSSID */
688///     ieee80211_version version;   /* version */
689///     unsigned int transmissions;  /* number of transmissions */
690///     duration_us packet_duration; /* time packet occupied RF medium */
691///     duration_us retrans_duration;/* time failed attempts occupied RF */
692///     unsigned int channel;        /* channel number */
693///     unsigned hyper speed;        /* speed */
694///     unsigned int power;          /* transmit power in mW */
695/// }
696/// ```
697#[derive(Debug, Clone, PartialEq, Eq)]
698pub struct Extended80211Tx {
699    /// SSID string (max 32 bytes)
700    pub ssid: String,
701
702    /// BSSID (MAC address)
703    pub bssid: crate::models::MacAddress,
704
705    /// IEEE 802.11 version (a=1, b=2, g=3, n=4)
706    pub version: u32,
707
708    /// Number of transmissions (0=unknown, 1=success on first attempt, n>1 = n-1 retransmissions)
709    pub transmissions: u32,
710
711    /// Packet duration in microseconds (successful transmission)
712    pub packet_duration: u32,
713
714    /// Retransmission duration in microseconds (failed attempts)
715    pub retrans_duration: u32,
716
717    /// Channel number
718    pub channel: u32,
719
720    /// Speed in bits per second
721    pub speed: u64,
722
723    /// Transmit power in milliwatts
724    pub power: u32,
725}
726
727/// PDU (Protocol Data Unit) in 802.11 aggregation
728///
729/// # XDR Definition ([sFlow 802.11](https://sflow.org/sflow_80211.txt))
730///
731/// ```text
732/// struct pdu {
733///     flow_record flow_records<>;
734/// }
735/// ```
736#[derive(Debug, Clone, PartialEq, Eq)]
737pub struct Pdu {
738    /// Flow records for this PDU
739    pub flow_records: Vec<crate::models::FlowRecord>,
740}
741
742/// Extended 802.11 Aggregation - Format (0,1016)
743///
744/// 802.11 frame aggregation information
745///
746/// # XDR Definition ([sFlow 802.11](https://sflow.org/sflow_80211.txt))
747///
748/// ```text
749/// /* Extended 802.11 Aggregation Data */
750/// /* opaque = flow_data; enterprise = 0; format = 1016 */
751///
752/// struct extended_80211_aggregation {
753///     pdu pdus<>; /* Array of PDUs in the aggregation */
754/// }
755/// ```
756#[derive(Debug, Clone, PartialEq, Eq)]
757pub struct Extended80211Aggregation {
758    /// Array of PDUs in the aggregation
759    pub pdus: Vec<Pdu>,
760}
761
762/// Extended OpenFlow v1 - Format (0,1017) - **DEPRECATED**
763///
764/// OpenFlow 1.0 forwarding information
765///
766/// **Note:** This format was defined in an early draft of the sFlow OpenFlow specification
767/// but was deprecated and removed from the final specification. It is included here for
768/// backward compatibility with legacy implementations.
769///
770/// # XDR Definition ([sFlow OpenFlow Draft](https://sflow.org/draft-sflow-openflow.txt))
771///
772/// ```text
773/// /* Extended OpenFlow 1.0 Data */
774/// /* opaque = flow_data; enterprise = 0; format = 1017 */
775///
776/// struct extended_openflow_v1 {
777///     unsigned hyper flow_cookie;  /* Flow cookie set by controller */
778///     wildcards flow_match;        /* Bit array of wildcarded fields */
779///     actions flow_actions;        /* Bit array of actions applied */
780/// }
781/// ```
782#[derive(Debug, Clone, PartialEq, Eq)]
783pub struct ExtendedOpenFlowV1 {
784    /// Flow cookie set by the OpenFlow controller
785    pub flow_cookie: u64,
786
787    /// Bit array describing the fields in the packet header that are used to form the flow key
788    /// See OpenFlow 1.0 ofp_match for the definition of wildcards
789    pub flow_match: u32,
790
791    /// Bit array describing fields that may have been altered by the flow action
792    /// The ofp_action_type enum is used to determine the bit positions
793    pub flow_actions: u32,
794}
795
796/// Extended L2 Tunnel Egress - Format (0,1021)
797///
798/// Layer 2 tunnel egress information - reports outer Ethernet headers
799/// that will be added on egress when encapsulating packets
800///
801/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
802///
803/// ```text
804/// /* opaque = flow_data; enterprise = 0; format = 1021 */
805/// struct extended_L2_tunnel_egress {
806///     sampled_ethernet header;
807/// }
808/// ```
809#[derive(Debug, Clone, PartialEq, Eq)]
810pub struct ExtendedL2TunnelEgress {
811    /// Outer Ethernet header that will be added on egress
812    pub header: SampledEthernet,
813}
814
815/// Extended L2 Tunnel Ingress - Format (0,1022)
816///
817/// Layer 2 tunnel ingress information - reports outer Ethernet headers
818/// that were present on ingress and removed during decapsulation
819///
820/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
821///
822/// ```text
823/// /* opaque = flow_data; enterprise = 0; format = 1022 */
824/// struct extended_L2_tunnel_ingress {
825///     sampled_ethernet header;
826/// }
827/// ```
828#[derive(Debug, Clone, PartialEq, Eq)]
829pub struct ExtendedL2TunnelIngress {
830    /// Outer Ethernet header that was present on ingress
831    pub header: SampledEthernet,
832}
833
834/// Extended IPv4 Tunnel Egress - Format (0,1023)
835///
836/// IPv4 tunnel egress information - reports outer IPv4 headers
837/// that will be added on egress when encapsulating packets
838///
839/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
840///
841/// ```text
842/// /* opaque = flow_data; enterprise = 0; format = 1023 */
843/// struct extended_ipv4_tunnel_egress {
844///     sampled_ipv4 header;
845/// }
846/// ```
847#[derive(Debug, Clone, PartialEq, Eq)]
848pub struct ExtendedIpv4TunnelEgress {
849    /// Outer IPv4 header that will be added on egress
850    pub header: SampledIpv4,
851}
852
853/// Extended IPv4 Tunnel Ingress - Format (0,1024)
854///
855/// IPv4 tunnel ingress information - reports outer IPv4 headers
856/// that were present on ingress and removed during decapsulation
857///
858/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
859///
860/// ```text
861/// /* opaque = flow_data; enterprise = 0; format = 1024 */
862/// struct extended_ipv4_tunnel_ingress {
863///     sampled_ipv4 header;
864/// }
865/// ```
866#[derive(Debug, Clone, PartialEq, Eq)]
867pub struct ExtendedIpv4TunnelIngress {
868    /// Outer IPv4 header that was present on ingress
869    pub header: SampledIpv4,
870}
871
872/// Extended IPv6 Tunnel Egress - Format (0,1025)
873///
874/// IPv6 tunnel egress information - reports outer IPv6 headers
875/// that will be added on egress when encapsulating packets
876///
877/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
878///
879/// ```text
880/// /* opaque = flow_data; enterprise = 0; format = 1025 */
881/// struct extended_ipv6_tunnel_egress {
882///     sampled_ipv6 header;
883/// }
884/// ```
885#[derive(Debug, Clone, PartialEq, Eq)]
886pub struct ExtendedIpv6TunnelEgress {
887    /// Outer IPv6 header that will be added on egress
888    pub header: SampledIpv6,
889}
890
891/// Extended IPv6 Tunnel Ingress - Format (0,1026)
892///
893/// IPv6 tunnel ingress information - reports outer IPv6 headers
894/// that were present on ingress and removed during decapsulation
895///
896/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
897///
898/// ```text
899/// /* opaque = flow_data; enterprise = 0; format = 1026 */
900/// struct extended_ipv6_tunnel_ingress {
901///     sampled_ipv6 header;
902/// }
903/// ```
904#[derive(Debug, Clone, PartialEq, Eq)]
905pub struct ExtendedIpv6TunnelIngress {
906    /// Outer IPv6 header that was present on ingress
907    pub header: SampledIpv6,
908}
909
910/// Extended Decapsulate Egress - Format (0,1027)
911///
912/// Indicates the end of a tunnel and points to the start of the inner header
913/// Used when a packet is sampled before decapsulation on ingress
914///
915/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
916///
917/// ```text
918/// /* opaque = flow_data; enterprise = 0; format = 1027 */
919/// struct extended_decapsulate_egress {
920///     unsigned int inner_header_offset;
921/// }
922/// ```
923#[derive(Debug, Clone, PartialEq, Eq)]
924pub struct ExtendedDecapsulateEgress {
925    /// Offset in bytes to the inner header within the sampled packet header
926    pub inner_header_offset: u32,
927}
928
929/// Extended Decapsulate Ingress - Format (0,1028)
930///
931/// Indicates the start of a tunnel
932/// Used when a packet is sampled after encapsulation on egress
933///
934/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
935///
936/// ```text
937/// /* opaque = flow_data; enterprise = 0; format = 1028 */
938/// struct extended_decapsulate_ingress {
939///     unsigned int inner_header_offset;
940/// }
941/// ```
942#[derive(Debug, Clone, PartialEq, Eq)]
943pub struct ExtendedDecapsulateIngress {
944    /// Offset in bytes to the inner header within the sampled packet header
945    pub inner_header_offset: u32,
946}
947
948/// Extended VNI Egress - Format (0,1029)
949///
950/// Virtual Network Identifier for egress traffic
951/// The VNI may be explicitly included in the tunneling protocol or implicit
952///
953/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
954///
955/// ```text
956/// /* opaque_flow_data; enterprise = 0; format = 1029 */
957/// struct extended_vni_egress {
958///     unsigned int vni;
959/// }
960/// ```
961#[derive(Debug, Clone, PartialEq, Eq)]
962pub struct ExtendedVniEgress {
963    /// Virtual Network Identifier
964    pub vni: u32,
965}
966
967/// Extended VNI Ingress - Format (0,1030)
968///
969/// Virtual Network Identifier for ingress traffic
970/// The VNI may be explicitly included in the tunneling protocol or implicit
971/// in the encapsulation (e.g., VXLAN uses UDP port 4789).
972///
973/// # XDR Definition ([sFlow Tunnel](https://sflow.org/sflow_tunnels.txt))
974///
975/// ```text
976/// /* VNI ingress */
977/// /* opaque = flow_data; enterprise = 0; format = 1030 */
978///
979/// struct extended_vni_ingress {
980///     unsigned int vni;  /* VNI associated with ingress packet */
981/// }
982/// ```
983#[derive(Debug, Clone, PartialEq, Eq)]
984pub struct ExtendedVniIngress {
985    /// Virtual Network Identifier
986    pub vni: u32,
987}
988
989/// Drop reason codes for discarded packets
990///
991/// # XDR Definition ([sFlow Drops](https://sflow.org/sflow_drops.txt))
992///
993/// ```text
994/// /* The drop_reason enumeration may be expanded over time.
995///    sFlow collectors must be prepared to receive discard_packet
996///    structures with unrecognized drop_reason values.
997///
998///    This document expands on the discard reason codes 0-262 defined
999///    in the sFlow Version 5 [1] interface typedef and this expanded list
1000///    should be regarded as an expansion of the reason codes in the
1001///    interface typdef and are valid anywhere the typedef is referenced.
1002///
1003///    Codes 263-288 are defined in Devlink Trap [2]. Drop reason / group
1004///    names from the Devlink Trap document are preserved where they define
1005///    new reason codes, or referenced as comments where they map to existing
1006///    codes.
1007///
1008///    Codes 289-303 are reasons that have yet to be upstreamed to Devlink Trap,
1009///    but the intent is that they will eventually be upstreamed and documented as
1010///    part of the Linux API [2], and so they have been reserved.
1011///
1012///    The authoritative list of drop reasons will be maintained
1013///    at sflow.org */
1014///
1015/// enum drop_reason {
1016///    net_unreachable      = 0,
1017///    host_unreachable     = 1,
1018///    protocol_unreachable = 2,
1019///    port_unreachable     = 3,
1020///    frag_needed          = 4,
1021///    src_route_failed     = 5,
1022///    dst_net_unknown      = 6, /* ipv4_lpm_miss, ipv6_lpm_miss */
1023///    dst_host_unknown     = 7,
1024///    src_host_isolated    = 8,
1025///    dst_net_prohibited   = 9, /* reject_route */
1026///    dst_host_prohibited  = 10,
1027///    dst_net_tos_unreachable  = 11,
1028///    dst_host_tos_unreacheable = 12,
1029///    comm_admin_prohibited = 13,
1030///    host_precedence_violation = 14,
1031///    precedence_cutoff    = 15,
1032///    unknown              = 256,
1033///    ttl_exceeded         = 257, /* ttl_value_is_too_small */
1034///    acl                  = 258, /* ingress_flow_action_drop,
1035///                                   egress_flow_action_drop
1036///                                   group acl_drops */
1037///    no_buffer_space      = 259, /* tail_drop */
1038///    red                  = 260, /* early_drop */
1039///    traffic_shaping      = 261,
1040///    pkt_too_big          = 262, /* mtu_value_is_too_small */
1041///    src_mac_is_multicast = 263,
1042///    vlan_tag_mismatch    = 264,
1043///    ingress_vlan_filter  = 265,
1044///    ingress_spanning_tree_filter = 266,
1045///    port_list_is_empty   = 267,
1046///    port_loopback_filter = 268,
1047///    blackhole_route      = 269,
1048///    non_ip               = 270,
1049///    uc_dip_over_mc_dmac  = 271,
1050///    dip_is_loopback_address = 272,
1051///    sip_is_mc            = 273,
1052///    sip_is_loopback_address = 274,
1053///    ip_header_corrupted  = 275,
1054///    ipv4_sip_is_limited_bc = 276,
1055///    ipv6_mc_dip_reserved_scope = 277,
1056///    ipv6_mc_dip_interface_local_scope = 278,
1057///    unresolved_neigh     = 279,
1058///    mc_reverse_path_forwarding = 280,
1059///    non_routable_packet  = 281,
1060///    decap_error          = 282,
1061///    overlay_smac_is_mc   = 283,
1062///    unknown_l2           = 284, /* group l2_drops */
1063///    unknown_l3           = 285, /* group l3_drops */
1064///    unknown_l3_exception = 286, /* group l3_exceptions */
1065///    unknown_buffer       = 287, /* group buffer_drops */
1066///    unknown_tunnel       = 288, /* group tunnel_drops */
1067///    unknown_l4           = 289,
1068///    sip_is_unspecified   = 290,
1069///    mlag_port_isolation  = 291,
1070///    blackhole_arp_neigh  = 292,
1071///    src_mac_is_dmac      = 293,
1072///    dmac_is_reserved     = 294,
1073///    sip_is_class_e       = 295,
1074///    mc_dmac_mismatch     = 296,
1075///    sip_is_dip           = 297,
1076///    dip_is_local_network = 298,
1077///    dip_is_link_local    = 299,
1078///    overlay_smac_is_dmac = 300,
1079///    egress_vlan_filter   = 301,
1080///    uc_reverse_path_forwarding = 302,
1081///    split_horizon        = 303
1082/// }
1083/// ```
1084#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1085#[repr(u32)]
1086pub enum DropReason {
1087    NetUnreachable = 0,
1088    HostUnreachable = 1,
1089    ProtocolUnreachable = 2,
1090    PortUnreachable = 3,
1091    FragNeeded = 4,
1092    SrcRouteFailed = 5,
1093    DstNetUnknown = 6,
1094    DstHostUnknown = 7,
1095    SrcHostIsolated = 8,
1096    DstNetProhibited = 9,
1097    DstHostProhibited = 10,
1098    DstNetTosUnreachable = 11,
1099    DstHostTosUnreachable = 12,
1100    CommAdminProhibited = 13,
1101    HostPrecedenceViolation = 14,
1102    PrecedenceCutoff = 15,
1103    Unknown = 256,
1104    TtlExceeded = 257,
1105    Acl = 258,
1106    NoBufferSpace = 259,
1107    Red = 260,
1108    TrafficShaping = 261,
1109    PktTooBig = 262,
1110    SrcMacIsMulticast = 263,
1111    VlanTagMismatch = 264,
1112    IngressVlanFilter = 265,
1113    IngressSpanningTreeFilter = 266,
1114    PortListIsEmpty = 267,
1115    PortLoopbackFilter = 268,
1116    BlackholeRoute = 269,
1117    NonIp = 270,
1118    UcDipOverMcDmac = 271,
1119    DipIsLoopbackAddress = 272,
1120    SipIsMc = 273,
1121    SipIsLoopbackAddress = 274,
1122    IpHeaderCorrupted = 275,
1123    Ipv4SipIsLimitedBc = 276,
1124    Ipv6McDipReservedScope = 277,
1125    Ipv6McDipInterfaceLocalScope = 278,
1126    UnresolvedNeigh = 279,
1127    McReversePathForwarding = 280,
1128    NonRoutablePacket = 281,
1129    DecapError = 282,
1130    OverlaySmacIsMc = 283,
1131    UnknownL2 = 284,
1132    UnknownL3 = 285,
1133    UnknownL3Exception = 286,
1134    UnknownBuffer = 287,
1135    UnknownTunnel = 288,
1136    UnknownL4 = 289,
1137    SipIsUnspecified = 290,
1138    MlagPortIsolation = 291,
1139    BlackholeArpNeigh = 292,
1140    SrcMacIsDmac = 293,
1141    DmacIsReserved = 294,
1142    SipIsClassE = 295,
1143    McDmacMismatch = 296,
1144    SipIsDip = 297,
1145    DipIsLocalNetwork = 298,
1146    DipIsLinkLocal = 299,
1147    OverlaySmacIsDmac = 300,
1148    EgressVlanFilter = 301,
1149    UcReversePathForwarding = 302,
1150    SplitHorizon = 303,
1151}
1152
1153impl DropReason {
1154    /// Convert from u32 value to DropReason enum
1155    ///
1156    /// This is a mechanical mapping of u32 values to enum variants
1157    /// defined in the sFlow specification. The function is tested
1158    /// with representative samples rather than exhaustively.
1159    pub fn from_u32(value: u32) -> Option<Self> {
1160        match value {
1161            0 => Some(DropReason::NetUnreachable),
1162            1 => Some(DropReason::HostUnreachable),
1163            2 => Some(DropReason::ProtocolUnreachable),
1164            3 => Some(DropReason::PortUnreachable),
1165            4 => Some(DropReason::FragNeeded),
1166            5 => Some(DropReason::SrcRouteFailed),
1167            6 => Some(DropReason::DstNetUnknown),
1168            7 => Some(DropReason::DstHostUnknown),
1169            8 => Some(DropReason::SrcHostIsolated),
1170            9 => Some(DropReason::DstNetProhibited),
1171            10 => Some(DropReason::DstHostProhibited),
1172            11 => Some(DropReason::DstNetTosUnreachable),
1173            12 => Some(DropReason::DstHostTosUnreachable),
1174            13 => Some(DropReason::CommAdminProhibited),
1175            14 => Some(DropReason::HostPrecedenceViolation),
1176            15 => Some(DropReason::PrecedenceCutoff),
1177            256 => Some(DropReason::Unknown),
1178            257 => Some(DropReason::TtlExceeded),
1179            258 => Some(DropReason::Acl),
1180            259 => Some(DropReason::NoBufferSpace),
1181            260 => Some(DropReason::Red),
1182            261 => Some(DropReason::TrafficShaping),
1183            262 => Some(DropReason::PktTooBig),
1184            263 => Some(DropReason::SrcMacIsMulticast),
1185            264 => Some(DropReason::VlanTagMismatch),
1186            265 => Some(DropReason::IngressVlanFilter),
1187            266 => Some(DropReason::IngressSpanningTreeFilter),
1188            267 => Some(DropReason::PortListIsEmpty),
1189            268 => Some(DropReason::PortLoopbackFilter),
1190            269 => Some(DropReason::BlackholeRoute),
1191            270 => Some(DropReason::NonIp),
1192            271 => Some(DropReason::UcDipOverMcDmac),
1193            272 => Some(DropReason::DipIsLoopbackAddress),
1194            273 => Some(DropReason::SipIsMc),
1195            274 => Some(DropReason::SipIsLoopbackAddress),
1196            275 => Some(DropReason::IpHeaderCorrupted),
1197            276 => Some(DropReason::Ipv4SipIsLimitedBc),
1198            277 => Some(DropReason::Ipv6McDipReservedScope),
1199            278 => Some(DropReason::Ipv6McDipInterfaceLocalScope),
1200            279 => Some(DropReason::UnresolvedNeigh),
1201            280 => Some(DropReason::McReversePathForwarding),
1202            281 => Some(DropReason::NonRoutablePacket),
1203            282 => Some(DropReason::DecapError),
1204            283 => Some(DropReason::OverlaySmacIsMc),
1205            284 => Some(DropReason::UnknownL2),
1206            285 => Some(DropReason::UnknownL3),
1207            286 => Some(DropReason::UnknownL3Exception),
1208            287 => Some(DropReason::UnknownBuffer),
1209            288 => Some(DropReason::UnknownTunnel),
1210            289 => Some(DropReason::UnknownL4),
1211            290 => Some(DropReason::SipIsUnspecified),
1212            291 => Some(DropReason::MlagPortIsolation),
1213            292 => Some(DropReason::BlackholeArpNeigh),
1214            293 => Some(DropReason::SrcMacIsDmac),
1215            294 => Some(DropReason::DmacIsReserved),
1216            295 => Some(DropReason::SipIsClassE),
1217            296 => Some(DropReason::McDmacMismatch),
1218            297 => Some(DropReason::SipIsDip),
1219            298 => Some(DropReason::DipIsLocalNetwork),
1220            299 => Some(DropReason::DipIsLinkLocal),
1221            300 => Some(DropReason::OverlaySmacIsDmac),
1222            301 => Some(DropReason::EgressVlanFilter),
1223            302 => Some(DropReason::UcReversePathForwarding),
1224            303 => Some(DropReason::SplitHorizon),
1225            _ => None,
1226        }
1227    }
1228}
1229
1230/// Extended Egress Queue - Format (0,1036)
1231///
1232/// Selected egress queue for the sampled packet
1233///
1234/// # XDR Definition ([sFlow Drops](https://sflow.org/sflow_drops.txt))
1235///
1236/// ```text
1237/// /* Selected egress queue */
1238/// /* Output port number must be provided in enclosing structure */
1239/// /* opaque = flow_data; enterprise = 0; format = 1036 */
1240/// struct extended_egress_queue {
1241///   unsigned int queue;  /* eqress queue number selected for sampled packet */
1242/// }
1243/// ```
1244#[derive(Debug, Clone, PartialEq, Eq)]
1245pub struct ExtendedEgressQueue {
1246    /// Egress queue number selected for sampled packet
1247    pub queue: u32,
1248}
1249
1250/// Extended ACL - Format (0,1037)
1251///
1252/// ACL information about the rule that matched this packet
1253///
1254/// # XDR Definition ([sFlow Drops](https://sflow.org/sflow_drops.txt))
1255///
1256/// ```text
1257/// /* ACL information */
1258/// /* Information about ACL rule that matched this packet
1259/// /* opaque = flow_data; enterprise = 0; format = 1037 */
1260/// struct extended_acl {
1261///   unsigned int number; /* access list number */
1262///   string name<>; /* access list name */
1263///   unsigned int direction; /* unknown = 0, ingress = 1, egress = 2 */
1264/// }
1265/// ```
1266#[derive(Debug, Clone, PartialEq, Eq)]
1267pub struct ExtendedAcl {
1268    /// Access list number
1269    pub number: u32,
1270
1271    /// Access list name
1272    pub name: String,
1273
1274    /// Direction: unknown = 0, ingress = 1, egress = 2
1275    pub direction: u32,
1276}
1277
1278/// Extended Function - Format (0,1038)
1279///
1280/// Name of the function in software network stack that discarded the packet
1281///
1282/// # XDR Definition ([sFlow Drops](https://sflow.org/sflow_drops.txt))
1283///
1284/// ```text
1285/// /* Software function */
1286/// /* Name of the function in software network stack that discarded the packet */
1287/// /* opaque = flow_data; enterprise = 0; format = 1038 */
1288/// struct extended_function {
1289///   string symbol<>;
1290/// }
1291/// ```
1292#[derive(Debug, Clone, PartialEq, Eq)]
1293pub struct ExtendedFunction {
1294    /// Function symbol name
1295    pub symbol: String,
1296}
1297
1298/// Extended Transit - Format (0,1039)
1299///
1300/// Delay for sampled packet traversing switch
1301///
1302/// # XDR Definition ([sFlow Transit](https://sflow.org/sflow_transit.txt))
1303///
1304/// ```text
1305/// /* Delay for sampled packet traversing switch */
1306/// /* opaque = flow_data; enterprise = 0; format = 1039 */
1307/// struct extended_transit {
1308///   unsigned int delay; /* transit delay in nanoseconds
1309///                          0xffffffff indicates value >= 0xffffffff */
1310/// }
1311/// ```
1312#[derive(Debug, Clone, PartialEq, Eq)]
1313pub struct ExtendedTransit {
1314    /// Transit delay in nanoseconds (0xffffffff indicates value >= 0xffffffff)
1315    pub delay: u32,
1316}
1317
1318/// Extended Queue - Format (0,1040)
1319///
1320/// Queue depth for sampled packet traversing switch
1321///
1322/// # XDR Definition ([sFlow Transit](https://sflow.org/sflow_transit.txt))
1323///
1324/// ```text
1325/// /* Queue depth for sampled packet traversing switch */
1326/// /* extended_egress_queue structure must be included */
1327/// /* opaque = flow_data; enterprise = 0; format = 1040 */
1328/// struct extended_queue {
1329///   unsigned int depth;   /* queue depth in bytes */
1330/// }
1331/// ```
1332#[derive(Debug, Clone, PartialEq, Eq)]
1333pub struct ExtendedQueue {
1334    /// Queue depth in bytes
1335    pub depth: u32,
1336}
1337
1338/// Extended Socket IPv4 - Format (0,2100)
1339///
1340/// IPv4 socket information for application transactions
1341///
1342/// # XDR Definition ([sFlow Host](https://sflow.org/sflow_host.txt))
1343///
1344/// ```text
1345/// /* IPv4 Socket */
1346/// /* opaque = flow_data; enterprise = 0; format = 2100 */
1347///
1348/// struct extended_socket_ipv4 {
1349///     unsigned int protocol;     /* IP Protocol type (e.g., TCP = 6, UDP = 17) */
1350///     ip_v4 local_ip;            /* local IP address */
1351///     ip_v4 remote_ip;           /* remote IP address */
1352///     unsigned int local_port;   /* TCP/UDP local port number or equivalent */
1353///     unsigned int remote_port;  /* TCP/UDP remote port number or equivalent */
1354/// }
1355/// ```
1356#[derive(Debug, Clone, PartialEq, Eq)]
1357pub struct ExtendedSocketIpv4 {
1358    /// IP Protocol type (e.g., TCP = 6, UDP = 17)
1359    pub protocol: u32,
1360
1361    /// Local IP address
1362    pub local_ip: std::net::Ipv4Addr,
1363
1364    /// Remote IP address
1365    pub remote_ip: std::net::Ipv4Addr,
1366
1367    /// TCP/UDP local port number
1368    pub local_port: u32,
1369
1370    /// TCP/UDP remote port number
1371    pub remote_port: u32,
1372}
1373
1374/// Extended Socket IPv6 - Format (0,2101)
1375///
1376/// IPv6 socket information for application transactions
1377///
1378/// # XDR Definition ([sFlow Host](https://sflow.org/sflow_host.txt))
1379///
1380/// ```text
1381/// /* IPv6 Socket */
1382/// /* opaque = flow_data; enterprise = 0; format = 2101 */
1383///
1384/// struct extended_socket_ipv6 {
1385///     unsigned int protocol;     /* IP Protocol type (e.g., TCP = 6, UDP = 17) */
1386///     ip_v6 local_ip;            /* local IP address */
1387///     ip_v6 remote_ip;           /* remote IP address */
1388///     unsigned int local_port;   /* TCP/UDP local port number or equivalent */
1389///     unsigned int remote_port;  /* TCP/UDP remote port number or equivalent */
1390/// }
1391/// ```
1392#[derive(Debug, Clone, PartialEq, Eq)]
1393pub struct ExtendedSocketIpv6 {
1394    /// IP Protocol type (e.g., TCP = 6, UDP = 17)
1395    pub protocol: u32,
1396
1397    /// Local IP address
1398    pub local_ip: std::net::Ipv6Addr,
1399
1400    /// Remote IP address
1401    pub remote_ip: std::net::Ipv6Addr,
1402
1403    /// TCP/UDP local port number
1404    pub local_port: u32,
1405
1406    /// TCP/UDP remote port number
1407    pub remote_port: u32,
1408}
1409
1410/// Application operation context
1411///
1412/// # XDR Definition ([sFlow Application](https://sflow.org/sflow_application.txt))
1413///
1414/// ```text
1415/// struct context {
1416///     application application;
1417///     operation operation;
1418///     attributes attributes;
1419/// }
1420/// ```
1421#[derive(Debug, Clone, PartialEq, Eq)]
1422pub struct AppContext {
1423    /// Application name (e.g., "payment", "mail.smtp", "db.oracle")
1424    pub application: String,
1425
1426    /// Operation name (e.g., "get.customer.name", "upload.photo")
1427    pub operation: String,
1428
1429    /// Operation attributes as name=value pairs (e.g., "cc=visa&loc=mobile")
1430    pub attributes: String,
1431}
1432
1433/// Application operation status
1434///
1435/// # XDR Definition ([sFlow Application](https://sflow.org/sflow_application.txt))
1436#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1437#[repr(u32)]
1438pub enum AppStatus {
1439    Success = 0,
1440    Other = 1,
1441    Timeout = 2,
1442    InternalError = 3,
1443    BadRequest = 4,
1444    Forbidden = 5,
1445    TooLarge = 6,
1446    NotImplemented = 7,
1447    NotFound = 8,
1448    Unavailable = 9,
1449    Unauthorized = 10,
1450}
1451
1452impl From<u32> for AppStatus {
1453    fn from(value: u32) -> Self {
1454        match value {
1455            0 => AppStatus::Success,
1456            1 => AppStatus::Other,
1457            2 => AppStatus::Timeout,
1458            3 => AppStatus::InternalError,
1459            4 => AppStatus::BadRequest,
1460            5 => AppStatus::Forbidden,
1461            6 => AppStatus::TooLarge,
1462            7 => AppStatus::NotImplemented,
1463            8 => AppStatus::NotFound,
1464            9 => AppStatus::Unavailable,
1465            10 => AppStatus::Unauthorized,
1466            _ => AppStatus::Other,
1467        }
1468    }
1469}
1470
1471/// Application Operation - Format (0,2202)
1472///
1473/// Sampled application operation information
1474///
1475/// # XDR Definition ([sFlow Application](https://sflow.org/sflow_application.txt))
1476///
1477/// ```text
1478/// /* Sampled Application Operation */
1479/// /* opaque = flow_data; enterprise = 0; format = 2202 */
1480///
1481/// struct app_operation {
1482///     context context;             /* attributes describing the operation */
1483///     utf8string<64> status_descr; /* additional text describing status */
1484///     unsigned hyper req_bytes;    /* size of request body (exclude headers) */
1485///     unsigned hyper resp_bytes;   /* size of response body (exclude headers) */
1486///     unsigned int uS;             /* duration of the operation (microseconds) */
1487///     status status;               /* status code */
1488/// }
1489/// ```
1490#[derive(Debug, Clone, PartialEq, Eq)]
1491pub struct AppOperation {
1492    /// Operation context
1493    pub context: AppContext,
1494
1495    /// Additional status description
1496    pub status_descr: String,
1497
1498    /// Size of request body in bytes (excluding headers)
1499    pub req_bytes: u64,
1500
1501    /// Size of response body in bytes (excluding headers)
1502    pub resp_bytes: u64,
1503
1504    /// Duration of the operation in microseconds
1505    pub duration_us: u32,
1506
1507    /// Operation status code
1508    pub status: AppStatus,
1509}
1510
1511/// Application Parent Context - Format (0,2203)
1512///
1513/// Parent context for sampled client operations
1514///
1515/// # XDR Definition ([sFlow Application](https://sflow.org/sflow_application.txt))
1516///
1517/// ```text
1518/// /* Optional parent context information for sampled client operation */
1519/// /* opaque = flow_data; enterprise = 0; format = 2203 */
1520///
1521/// struct app_parent_context {
1522///     context context;
1523/// }
1524/// ```
1525#[derive(Debug, Clone, PartialEq, Eq)]
1526pub struct AppParentContext {
1527    /// Parent operation context
1528    pub context: AppContext,
1529}
1530
1531/// Application Initiator - Format (0,2204)
1532///
1533/// Actor initiating the request (e.g., customer sending a payment)
1534///
1535/// # XDR Definition ([sFlow Application](https://sflow.org/sflow_application.txt))
1536///
1537/// ```text
1538/// /* Actor initiating the request */
1539/// /* e.g. customer sending a payment */
1540/// /* opaque = flow_data; enterprise = 0; format = 2204 */
1541///
1542/// app_initiator {
1543///    actor actor;
1544/// }
1545/// ```
1546#[derive(Debug, Clone, PartialEq, Eq)]
1547pub struct AppInitiator {
1548    /// Business level identifier (e.g., customer id, vendor id)
1549    pub actor: String,
1550}
1551
1552/// Application Target - Format (0,2205)
1553///
1554/// Actor targeted by the request (e.g., recipient of payment)
1555///
1556/// # XDR Definition ([sFlow Application](https://sflow.org/sflow_application.txt))
1557///
1558/// ```text
1559/// /* Actor targetted by the request */
1560/// /* e.g. recipient of payment */
1561/// /* opaque = flow_data; enterprise = 0; format = 2205 */
1562///
1563/// app_target {
1564///    actor actor;
1565/// }
1566/// ```
1567#[derive(Debug, Clone, PartialEq, Eq)]
1568pub struct AppTarget {
1569    /// Business level identifier (e.g., customer id, vendor id)
1570    pub actor: String,
1571}