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)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub enum HeaderProtocol {
12    EthernetIso88023 = 1,
13    Iso88024TokenBus = 2,
14    Iso88025TokenRing = 3,
15    Fddi = 4,
16    FrameRelay = 5,
17    X25 = 6,
18    Ppp = 7,
19    Smds = 8,
20    Aal5 = 9,
21    Aal5Ip = 10,
22    Ipv4 = 11,
23    Ipv6 = 12,
24    Mpls = 13,
25    Pos = 14,
26    Ieee80211Mac = 15,
27    Ieee80211Ampdu = 16,
28    Ieee80211Amsdu = 17,
29}
30
31impl HeaderProtocol {
32    /// Convert from u32 value to HeaderProtocol enum
33    pub fn from_u32(value: u32) -> Option<Self> {
34        match value {
35            1 => Some(HeaderProtocol::EthernetIso88023),
36            2 => Some(HeaderProtocol::Iso88024TokenBus),
37            3 => Some(HeaderProtocol::Iso88025TokenRing),
38            4 => Some(HeaderProtocol::Fddi),
39            5 => Some(HeaderProtocol::FrameRelay),
40            6 => Some(HeaderProtocol::X25),
41            7 => Some(HeaderProtocol::Ppp),
42            8 => Some(HeaderProtocol::Smds),
43            9 => Some(HeaderProtocol::Aal5),
44            10 => Some(HeaderProtocol::Aal5Ip),
45            11 => Some(HeaderProtocol::Ipv4),
46            12 => Some(HeaderProtocol::Ipv6),
47            13 => Some(HeaderProtocol::Mpls),
48            14 => Some(HeaderProtocol::Pos),
49            15 => Some(HeaderProtocol::Ieee80211Mac),
50            16 => Some(HeaderProtocol::Ieee80211Ampdu),
51            17 => Some(HeaderProtocol::Ieee80211Amsdu),
52            _ => None,
53        }
54    }
55}
56
57impl std::fmt::Display for HeaderProtocol {
58    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59        match self {
60            HeaderProtocol::EthernetIso88023 => write!(f, "Ethernet (ISO 802.3)"),
61            HeaderProtocol::Iso88024TokenBus => write!(f, "ISO 802.4 Token Bus"),
62            HeaderProtocol::Iso88025TokenRing => write!(f, "ISO 802.5 Token Ring"),
63            HeaderProtocol::Fddi => write!(f, "FDDI"),
64            HeaderProtocol::FrameRelay => write!(f, "Frame Relay"),
65            HeaderProtocol::X25 => write!(f, "X.25"),
66            HeaderProtocol::Ppp => write!(f, "PPP"),
67            HeaderProtocol::Smds => write!(f, "SMDS"),
68            HeaderProtocol::Aal5 => write!(f, "AAL5"),
69            HeaderProtocol::Aal5Ip => write!(f, "AAL5 IP"),
70            HeaderProtocol::Ipv4 => write!(f, "IPv4"),
71            HeaderProtocol::Ipv6 => write!(f, "IPv6"),
72            HeaderProtocol::Mpls => write!(f, "MPLS"),
73            HeaderProtocol::Pos => write!(f, "POS"),
74            HeaderProtocol::Ieee80211Mac => write!(f, "IEEE 802.11 MAC"),
75            HeaderProtocol::Ieee80211Ampdu => write!(f, "IEEE 802.11 A-MPDU"),
76            HeaderProtocol::Ieee80211Amsdu => write!(f, "IEEE 802.11 A-MSDU"),
77        }
78    }
79}
80
81/// Sampled Header - Format (0,1)
82///
83/// Raw packet header captured from the wire
84///
85/// # XDR Definition (sFlow v5)
86///
87/// ```text
88/// /* Raw Packet Header */
89/// /* opaque = flow_data; enterprise = 0; format = 1 */
90///
91/// struct sampled_header {
92///     header_protocol protocol;  /* Format of sampled header */
93///     unsigned int frame_length; /* Original length of packet before sampling */
94///     unsigned int stripped;     /* Number of octets removed from packet */
95///     opaque header<>;           /* Header bytes */
96/// }
97/// ```
98#[derive(Debug, Clone, PartialEq, Eq)]
99#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
100pub struct SampledHeader {
101    /// Protocol of the sampled packet
102    pub protocol: HeaderProtocol,
103
104    /// Original length of the packet (before sampling)
105    pub frame_length: u32,
106
107    /// Number of bytes stripped from the packet before sampling
108    pub stripped: u32,
109
110    /// Raw header bytes
111    pub header: Vec<u8>,
112}
113
114/// Sampled Ethernet Frame - Format (0,2)
115///
116/// Ethernet frame header information
117///
118/// # XDR Definition (sFlow v5)
119///
120/// ```text
121/// /* Ethernet Frame Data */
122/// /* opaque = flow_data; enterprise = 0; format = 2 */
123///
124/// struct sampled_ethernet {
125///     unsigned int length;   /* The length of the MAC packet received on the
126///                               network, excluding lower layer encapsulations
127///                               and framing bits but including FCS octets */
128///     mac src_mac;           /* Source MAC address */
129///     mac dst_mac;           /* Destination MAC address */
130///     unsigned int type;     /* Ethernet packet type */
131/// }
132/// ```
133#[derive(Debug, Clone, PartialEq, Eq)]
134#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
135pub struct SampledEthernet {
136    /// Length of MAC packet in bytes
137    pub length: u32,
138
139    /// Source MAC address
140    pub src_mac: crate::models::MacAddress,
141
142    /// Destination MAC address
143    pub dst_mac: crate::models::MacAddress,
144
145    /// Ethernet type (spec: type)
146    pub eth_type: u32,
147}
148
149/// Sampled IPv4 - Format (0,3)
150///
151/// IPv4 packet header information
152///
153/// # XDR Definition (sFlow v5)
154///
155/// ```text
156/// /* Packet IP version 4 data */
157/// /* opaque = flow_data; enterprise = 0; format = 3 */
158///
159/// struct sampled_ipv4 {
160///     unsigned int length;     /* Length of IP packet excluding lower layer encapsulations */
161///     unsigned int protocol;   /* IP Protocol type (e.g., TCP = 6, UDP = 17) */
162///     ip_v4 src_ip;            /* Source IP Address */
163///     ip_v4 dst_ip;            /* Destination IP Address */
164///     unsigned int src_port;   /* TCP/UDP source port number or equivalent */
165///     unsigned int dst_port;   /* TCP/UDP destination port number or equivalent */
166///     unsigned int tcp_flags;  /* TCP flags */
167///     unsigned int tos;        /* IP type of service */
168/// }
169/// ```
170#[derive(Debug, Clone, PartialEq, Eq)]
171#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
172pub struct SampledIpv4 {
173    /// Length of IP packet in bytes
174    pub length: u32,
175
176    /// IP Protocol (TCP=6, UDP=17, etc.)
177    pub protocol: u32,
178
179    /// Source IP address
180    pub src_ip: Ipv4Addr,
181
182    /// Destination IP address
183    pub dst_ip: Ipv4Addr,
184
185    /// Source port (for TCP/UDP)
186    pub src_port: u32,
187
188    /// Destination port (for TCP/UDP)
189    pub dst_port: u32,
190
191    /// TCP flags
192    pub tcp_flags: u32,
193
194    /// Type of Service
195    pub tos: u32,
196}
197
198/// Sampled IPv6 - Format (0,4)
199///
200/// IPv6 packet header information
201///
202/// # XDR Definition (sFlow v5)
203///
204/// ```text
205/// /* Packet IP Version 6 Data */
206/// /* opaque = flow_data; enterprise = 0; format = 4 */
207///
208/// struct sampled_ipv6 {
209///     unsigned int length;     /* Length of IP packet excluding lower layer encapsulations */
210///     unsigned int protocol;   /* IP next header (e.g., TCP = 6, UDP = 17) */
211///     ip_v6 src_ip;            /* Source IP Address */
212///     ip_v6 dst_ip;            /* Destination IP Address */
213///     unsigned int src_port;   /* TCP/UDP source port number or equivalent */
214///     unsigned int dst_port;   /* TCP/UDP destination port number or equivalent */
215///     unsigned int tcp_flags;  /* TCP flags */
216///     unsigned int priority;   /* IP priority */
217/// }
218/// ```
219#[derive(Debug, Clone, PartialEq, Eq)]
220#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
221pub struct SampledIpv6 {
222    /// Length of IP packet in bytes
223    pub length: u32,
224
225    /// IP Protocol (TCP=6, UDP=17, etc.)
226    pub protocol: u32,
227
228    /// Source IP address
229    pub src_ip: Ipv6Addr,
230
231    /// Destination IP address
232    pub dst_ip: Ipv6Addr,
233
234    /// Source port (for TCP/UDP)
235    pub src_port: u32,
236
237    /// Destination port (for TCP/UDP)
238    pub dst_port: u32,
239
240    /// TCP flags
241    pub tcp_flags: u32,
242
243    /// Priority (traffic class)
244    pub priority: u32,
245}
246
247/// Extended Switch Data - Format (0,1001)
248///
249/// Layer 2 switching information
250///
251/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
252///
253/// ```text
254/// /* Extended Switch Data */
255/// /* opaque = flow_data; enterprise = 0; format = 1001 */
256///
257/// struct extended_switch {
258///     unsigned int src_vlan;     /* The 802.1Q VLAN id of incoming frame,
259///                                   0xffffffff if unknown */
260///     unsigned int src_priority; /* The 802.1p priority of incoming frame,
261///                                   0xffffffff if unknown */
262///     unsigned int dst_vlan;     /* The 802.1Q VLAN id of outgoing frame,
263///                                   0xffffffff if unknown */
264///     unsigned int dst_priority; /* The 802.1p priority of outgoing frame,
265///                                   0xffffffff if unknown */
266/// }
267/// ```
268///
269/// **ERRATUM:** The specification was updated to clarify that 0xffffffff indicates unknown values.
270#[derive(Debug, Clone, PartialEq, Eq)]
271#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
272pub struct ExtendedSwitch {
273    /// Source VLAN ID
274    /// **ERRATUM:** 0xffffffff if unknown
275    pub src_vlan: u32,
276
277    /// Source priority (802.1p)
278    /// **ERRATUM:** 0xffffffff if unknown
279    pub src_priority: u32,
280
281    /// Destination VLAN ID
282    /// **ERRATUM:** 0xffffffff if unknown
283    pub dst_vlan: u32,
284
285    /// Destination priority (802.1p)
286    /// **ERRATUM:** 0xffffffff if unknown
287    pub dst_priority: u32,
288}
289
290/// Extended Router Data - Format (0,1002)
291///
292/// Layer 3 routing information
293///
294/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
295///
296/// ```text
297/// /* Extended Router Data */
298/// /* opaque = flow_data; enterprise = 0; format = 1002 */
299///
300/// struct extended_router {
301///     next_hop nexthop;          /* IP address of immediate next hop router */
302///     unsigned int src_mask_len; /* Source address prefix mask (number of bits) */
303///     unsigned int dst_mask_len; /* Destination address prefix mask (number of bits) */
304/// }
305/// ```
306///
307/// **ERRATUM:** The specification was clarified to specify "immediate" next hop router.
308#[derive(Debug, Clone, PartialEq, Eq)]
309#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
310pub struct ExtendedRouter {
311    /// IP address of immediate next hop router (spec: nexthop)
312    /// **ERRATUM:** Clarified as "immediate" next hop router
313    pub next_hop: crate::models::core::Address,
314
315    /// Source subnet mask bits
316    pub src_mask_len: u32,
317
318    /// Destination subnet mask bits
319    pub dst_mask_len: u32,
320}
321
322/// AS Path Type
323#[derive(Debug, Clone, Copy, PartialEq, Eq)]
324#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
325pub enum AsPathType {
326    AsSet = 1,
327    AsSequence = 2,
328}
329
330/// AS Path Segment
331#[derive(Debug, Clone, PartialEq, Eq)]
332#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
333pub struct AsPathSegment {
334    pub path_type: u32,
335    pub path_length: u32,
336    pub path: Vec<u32>,
337}
338
339/// Extended Gateway Data - Format (0,1003)
340///
341/// BGP routing information
342///
343/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
344///
345/// ```text
346/// /* Extended Gateway Data */
347/// /* opaque = flow_data; enterprise = 0; format = 1003 */
348///
349/// struct extended_gateway {
350///     next_hop nexthop;           /* Address of the border router */
351///     unsigned int as;            /* Autonomous system number of router */
352///     unsigned int src_as;        /* Autonomous system number of source */
353///     unsigned int src_peer_as;   /* Autonomous system number of source peer */
354///     as_path_type dst_as_path<>; /* AS path to the destination */
355///     unsigned int communities<>; /* Communities associated with this route */
356///     unsigned int localpref;     /* LocalPref associated with this route */
357/// }
358/// ```
359#[derive(Debug, Clone, PartialEq, Eq)]
360#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
361pub struct ExtendedGateway {
362    /// IP address of the border router (spec: nexthop)
363    pub next_hop: crate::models::core::Address,
364
365    /// Autonomous system number (spec: as)
366    pub as_number: u32,
367
368    /// Source AS
369    pub src_as: u32,
370
371    /// Source peer AS
372    pub src_peer_as: u32,
373
374    /// Autonomous system path to the destination
375    pub dst_as_path: Vec<AsPathSegment>,
376
377    /// Communities associated with this route
378    pub communities: Vec<u32>,
379
380    /// Local preference (spec: localpref)
381    pub local_pref: u32,
382}
383
384/// Extended User Data - Format (0,1004)
385///
386/// Application-level user information
387///
388/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
389///
390/// ```text
391/// /* Extended User Data */
392/// /* opaque = flow_data; enterprise = 0; format = 1004 */
393///
394/// struct extended_user {
395///     charset src_charset;   /* Character set for src_user */
396///     opaque src_user<>;     /* User ID associated with packet source */
397///     charset dst_charset;   /* Character set for dst_user */
398///     opaque dst_user<>;     /* User ID associated with packet destination */
399/// }
400/// ```
401#[derive(Debug, Clone, PartialEq, Eq)]
402#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
403pub struct ExtendedUser {
404    /// Source character set (MIBEnum)
405    pub src_charset: u32,
406
407    /// Source user ID
408    pub src_user: String,
409
410    /// Destination character set (MIBEnum)
411    pub dst_charset: u32,
412
413    /// Destination user ID
414    pub dst_user: String,
415}
416
417/// URL Direction
418#[derive(Debug, Clone, Copy, PartialEq, Eq)]
419#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
420pub enum UrlDirection {
421    Source = 1,
422    Destination = 2,
423}
424
425/// Extended URL Data - Format (0,1005)
426///
427/// HTTP request information
428///
429/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
430///
431/// ```text
432/// /* Extended URL Data */
433/// /* opaque = flow_data; enterprise = 0; format = 1005 */
434///
435/// struct extended_url {
436///     url_direction direction; /* Direction of connection */
437///     string url<>;            /* The HTTP request-line (see RFC 2616) */
438///     string host<>;           /* The host field from the HTTP header */
439/// }
440/// ```
441#[derive(Debug, Clone, PartialEq, Eq)]
442#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
443pub struct ExtendedUrl {
444    /// Direction (source or destination)
445    pub direction: u32,
446
447    /// URL string (HTTP request-line)
448    pub url: String,
449
450    /// Host header from HTTP request
451    pub host: String,
452}
453
454/// Extended MPLS Data - Format (0,1006)
455///
456/// MPLS label stack information
457///
458/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
459///
460/// ```text
461/// /* Extended MPLS Data */
462/// /* opaque = flow_data; enterprise = 0; format = 1006 */
463///
464/// struct extended_mpls {
465///     next_hop nexthop;     /* Address of the next hop */
466///     label_stack in_stack; /* Label stack of received packet */
467///     label_stack out_stack;/* Label stack for transmitted packet */
468/// }
469/// ```
470#[derive(Debug, Clone, PartialEq, Eq)]
471#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
472pub struct ExtendedMpls {
473    /// Next hop address (spec: nexthop)
474    pub next_hop: crate::models::core::Address,
475
476    /// Input label stack
477    pub in_stack: Vec<u32>,
478
479    /// Output label stack
480    pub out_stack: Vec<u32>,
481}
482
483/// Extended NAT Data - Format (0,1007)
484///
485/// Network Address Translation information
486///
487/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
488///
489/// ```text
490/// /* Extended NAT Data */
491/// /* opaque = flow_data; enterprise = 0; format = 1007 */
492///
493/// struct extended_nat {
494///     address src_address; /* Source address */
495///     address dst_address; /* Destination address */
496/// }
497/// ```
498#[derive(Debug, Clone, PartialEq, Eq)]
499#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
500pub struct ExtendedNat {
501    /// Source address type
502    pub src_address: crate::models::core::Address,
503
504    /// Destination address type
505    pub dst_address: crate::models::core::Address,
506}
507
508/// Extended NAT Port Data - Format (0,1020)
509///
510/// Layer 4 port translation information for NAT
511///
512/// # XDR Definition ([sFlow Port NAT](https://sflow.org/sflow_pnat.txt))
513///
514/// ```text
515/// /* Extended NAT L4 Port Data
516///    Packet header reports ports as seen at the sFlowDataSource.
517///    The extended_nat_port structure reports on translated source and/or
518///    destination layer 4 (TCP/UDP) ports for this packet. If port was not
519///    translated it should be equal to that reported for the header. */
520/// /* opaque = flow_data; enterprise = 0; format = 1020 */
521///
522/// struct extended_nat_port {
523///      unsigned int src_port;            /* Source port */
524///      unsigned int dst_port;            /* Destination port */
525/// }
526/// ```
527#[derive(Debug, Clone, PartialEq, Eq)]
528#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
529pub struct ExtendedNatPort {
530    /// Translated source port
531    pub src_port: u32,
532
533    /// Translated destination port
534    pub dst_port: u32,
535}
536
537/// Extended InfiniBand LRH - Format (0,1031)
538///
539/// InfiniBand Local Routing Header information
540///
541/// # XDR Definition ([sFlow InfiniBand](https://sflow.org/draft_sflow_infiniband_2.txt))
542///
543/// ```text
544/// /* Extended IB LRH Data
545///    - Local Routing Header definition from InfiniBand Architecture
546///      Specification */
547///
548/// /* opaque = flow_data; enterprise = 0; format = 1031 */
549///
550/// struct extended_ib_lrh {
551///    unsigned int src_vl;       /* source virtual lane               */
552///    unsigned int src_sl;       /* source service level              */
553///    unsigned int src_dlid;     /* source destination-local-ID       */
554///    unsigned int src_slid;     /* source source-local-ID            */
555///    unsigned int src_lnh;      /* source link next header           */
556///    unsigned int dst_vl;       /* Destination virtual lane          */
557///    unsigned int dst_sl;       /* Destination service level         */
558///    unsigned int dst_dlid;     /* Destination destination-local-ID  */
559///    unsigned int dst_slid;     /* Destination source-local-ID       */
560///    unsigned int dst_lnh;      /* Destination link next header      */
561/// }
562/// ```
563///
564/// **ERRATUM:** The specification uses non-standard data type `ib_lrh_data` instead of `flow_data`.
565/// The corrected version is shown above.
566#[derive(Debug, Clone, PartialEq, Eq)]
567#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
568pub struct ExtendedInfiniBandLrh {
569    /// Source virtual lane
570    pub src_vl: u32,
571    /// Source service level
572    pub src_sl: u32,
573    /// Source destination-local-ID
574    pub src_dlid: u32,
575    /// Source source-local-ID
576    pub src_slid: u32,
577    /// Source link next header
578    pub src_lnh: u32,
579    /// Destination virtual lane
580    pub dst_vl: u32,
581    /// Destination service level
582    pub dst_sl: u32,
583    /// Destination destination-local-ID
584    pub dst_dlid: u32,
585    /// Destination source-local-ID
586    pub dst_slid: u32,
587    /// Destination link next header
588    pub dst_lnh: u32,
589}
590
591/// Extended InfiniBand GRH - Format (0,1032)
592///
593/// InfiniBand Global Routing Header information
594///
595/// # XDR Definition ([sFlow InfiniBand](https://sflow.org/draft_sflow_infiniband_2.txt))
596///
597/// ```text
598/// /* GID type  16 bytes long */
599/// typedef opaque gid[16];
600///
601/// /* Extended IB GRH Data
602///    - Global Routing Header definition from InfiniBand Architecture
603///      Specification */
604///
605/// /* opaque = flow_data; enterprise = 0; format = 1032 */
606///
607/// struct extended_ib_grh {
608///    unsigned int flow_label; /* flow label          */
609///    unsigned int tc;         /* Traffic Class       */
610///    gid s_gid;               /* source GID          */
611///    gid d_gid;               /* destination GID     */
612///    unsigned int next_header; /* next header type    */
613///    unsigned int length;      /* payload length      */
614/// }
615/// ```
616///
617/// **ERRATUM:** The specification is missing semicolons after `next_header` and `length`,
618/// violating RFC 4506 XDR syntax requirements. Additionally, the specification uses
619/// non-standard data type `ib_grh_data` instead of `flow_data`. The corrected version is shown above.
620#[derive(Debug, Clone, PartialEq, Eq)]
621#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
622pub struct ExtendedInfiniBandGrh {
623    /// Flow label
624    pub flow_label: u32,
625    /// Traffic class
626    pub tc: u32,
627    /// Source GID (16 bytes)
628    pub s_gid: [u8; 16],
629    /// Destination GID (16 bytes)
630    pub d_gid: [u8; 16],
631    /// Next header type
632    pub next_header: u32,
633    /// Payload length
634    pub length: u32,
635}
636
637/// Extended InfiniBand BTH - Format (0,1033)
638///
639/// InfiniBand Base Transport Header information
640///
641/// # XDR Definition ([sFlow InfiniBand](https://sflow.org/draft_sflow_infiniband_2.txt))
642///
643/// ```text
644/// /* Extended IB BTH Data
645///    - Base Transport Header definition from InfiniBand Architecture
646///      Specification */
647///
648/// /* opaque = flow_data; enterprise = 0; format = 1033 */
649///
650/// struct extended_ib_bth {
651///    unsigned int pkey;   /* Partition key                */
652///    unsigned int dst_qp; /* Destination Queue Pair       */
653///    unsigned int opcode; /* IBA packet type              */
654/// }
655/// ```
656///
657/// **ERRATUM:** The specification uses non-standard data type `ib_bth_data` instead of `flow_data`.
658/// The corrected version is shown above.
659#[derive(Debug, Clone, PartialEq, Eq)]
660#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
661pub struct ExtendedInfiniBandBth {
662    /// Partition key
663    pub pkey: u32,
664    /// Destination Queue Pair
665    pub dst_qp: u32,
666    /// IBA packet type (opcode)
667    pub opcode: u32,
668}
669
670/// Extended MPLS Tunnel - Format (0,1008)
671///
672/// MPLS tunnel information
673///
674/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
675///
676/// ```text
677/// /* Extended MPLS Tunnel */
678/// /* opaque = flow_data; enterprise = 0; format = 1008 */
679///
680/// struct extended_mpls_tunnel {
681///     string tunnel_lsp_name<>; /* Tunnel name */
682///     unsigned int tunnel_id;   /* Tunnel ID */
683///     unsigned int tunnel_cos;  /* Tunnel COS value */
684/// }
685/// ```
686#[derive(Debug, Clone, PartialEq, Eq)]
687#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
688pub struct ExtendedMplsTunnel {
689    /// Tunnel LSP name
690    pub tunnel_lsp_name: String,
691
692    /// Tunnel ID
693    pub tunnel_id: u32,
694
695    /// Tunnel COS value
696    pub tunnel_cos: u32,
697}
698
699/// Extended MPLS VC - Format (0,1009)
700///
701/// MPLS Virtual Circuit information
702///
703/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
704///
705/// ```text
706/// /* Extended MPLS VC */
707/// /* opaque = flow_data; enterprise = 0; format = 1009 */
708///
709/// struct extended_mpls_vc {
710///     string vc_instance_name<>; /* VC instance name */
711///     unsigned int vll_vc_id;    /* VLL/VC instance ID */
712///     unsigned int vc_label_cos; /* VC Label COS value */
713/// }
714/// ```
715#[derive(Debug, Clone, PartialEq, Eq)]
716#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
717pub struct ExtendedMplsVc {
718    /// VC instance name
719    pub vc_instance_name: String,
720
721    /// VC ID
722    pub vll_vc_id: u32,
723
724    /// VC label
725    pub vc_label: u32,
726
727    /// VC COS
728    pub vc_cos: u32,
729}
730
731/// Extended MPLS FEC - Format (0,1010)
732///
733/// MPLS Forwarding Equivalence Class information
734///
735/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
736///
737/// ```text
738/// /* Extended MPLS FEC */
739/// /* opaque = flow_data; enterprise = 0; format = 1010 */
740///
741/// struct extended_mpls_FTN {
742///     string mplsFTNDescr<>;  /* FEC description */
743///     unsigned int mplsFTNMask; /* FEC mask */
744/// }
745/// ```
746#[derive(Debug, Clone, PartialEq, Eq)]
747#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
748pub struct ExtendedMplsFec {
749    /// FEC address prefix
750    pub fec_addr_prefix: crate::models::core::Address,
751
752    /// FEC prefix length
753    pub fec_prefix_len: u32,
754}
755
756/// Extended MPLS LVP FEC - Format (0,1011)
757///
758/// MPLS LDP FEC information
759///
760/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
761///
762/// ```text
763/// /* Extended MPLS LVP FEC */
764/// /* opaque = flow_data; enterprise = 0; format = 1011 */
765///
766/// struct extended_mpls_LDP_FEC {
767///     unsigned int mplsFecAddrPrefixLength; /* FEC address prefix length */
768/// }
769/// ```
770#[derive(Debug, Clone, PartialEq, Eq)]
771#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
772pub struct ExtendedMplsLvpFec {
773    /// FEC address prefix length
774    pub mpls_fec_addr_prefix_length: u32,
775}
776
777/// Extended VLAN Tunnel - Format (0,1012)
778///
779/// VLAN tunnel information for nested VLAN tags
780///
781/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
782///
783/// ```text
784/// /* Extended VLAN tunnel information */
785/// /* opaque = flow_data; enterprise = 0; format = 1012 */
786///
787/// struct extended_vlantunnel {
788///     unsigned int stack<>; /* List of stripped 802.1Q TPID/TCI layers */
789/// }
790/// ```
791#[derive(Debug, Clone, PartialEq, Eq)]
792#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
793pub struct ExtendedVlanTunnel {
794    /// List of stripped 802.1Q TPID/TCI layers
795    pub stack: Vec<u32>,
796}
797
798/// Extended 802.11 Payload - Format (0,1013)
799///
800/// Unencrypted 802.11 payload data
801///
802/// # XDR Definition ([sFlow 802.11](https://sflow.org/sflow_80211.txt))
803///
804/// ```text
805/// /* Extended 80211 Payload */
806/// /* opaque = flow_data; enterprise = 0; format = 1013 */
807///
808/// struct extended_80211_payload {
809///     cipher_suite ciphersuite; /* encryption scheme used for this packet */
810///     opaque data<>;            /* unencrypted bytes from the payload */
811/// }
812/// ```
813#[derive(Debug, Clone, PartialEq, Eq)]
814#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
815pub struct Extended80211Payload {
816    /// Cipher suite (OUI + Suite Type) (spec: ciphersuite)
817    pub cipher_suite: u32,
818
819    /// Unencrypted payload data
820    pub data: Vec<u8>,
821}
822
823/// Extended 802.11 RX - Format (0,1014)
824///
825/// 802.11 receive information
826///
827/// # XDR Definition ([sFlow 802.11](https://sflow.org/sflow_80211.txt))
828///
829/// ```text
830/// /* Extended 802.11 RX */
831/// /* opaque = flow_data; enterprise = 0; format = 1014 */
832///
833/// struct extended_80211_rx {
834///     string ssid<32>;             /* SSID string */
835///     mac bssid;                   /* BSSID */
836///     ieee80211_version version;   /* version */
837///     unsigned int channel;        /* channel number */
838///     unsigned hyper speed;        /* speed */
839///     unsigned int rsni;           /* received signal to noise ratio */
840///     unsigned int rcpi;           /* received channel power */
841///     duration_us packet_duration; /* time packet occupied RF medium */
842/// }
843/// ```
844///
845/// **ERRATUM:** The specification is missing a semicolon after `packet_duration`,
846/// violating RFC 4506 XDR syntax requirements. The corrected version is shown above.
847#[derive(Debug, Clone, PartialEq, Eq)]
848#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
849pub struct Extended80211Rx {
850    /// SSID string (max 32 bytes)
851    pub ssid: String,
852
853    /// BSSID (MAC address)
854    pub bssid: crate::models::MacAddress,
855
856    /// IEEE 802.11 version (a=1, b=2, g=3, n=4)
857    pub version: u32,
858
859    /// Channel number
860    pub channel: u32,
861
862    /// Speed in bits per second
863    pub speed: u64,
864
865    /// Received signal to noise ratio (RSNI)
866    pub rsni: u32,
867
868    /// Received channel power indicator (RCPI)
869    pub rcpi: u32,
870
871    /// Packet duration in microseconds
872    pub packet_duration: u32,
873}
874
875/// Extended 802.11 TX - Format (0,1015)
876///
877/// 802.11 transmit information
878///
879/// # XDR Definition ([sFlow 802.11](https://sflow.org/sflow_80211.txt))
880///
881/// ```text
882/// /* Extended 802.11 TX */
883/// /* opaque = flow_data; enterprise = 0; format = 1015 */
884///
885/// struct extended_80211_tx {
886///     string ssid<32>;             /* SSID string */
887///     mac bssid;                   /* BSSID */
888///     ieee80211_version version;   /* version */
889///     unsigned int transmissions;  /* number of transmissions */
890///     duration_us packet_duration; /* time packet occupied RF medium */
891///     duration_us retrans_duration;/* time failed attempts occupied RF */
892///     unsigned int channel;        /* channel number */
893///     unsigned hyper speed;        /* speed */
894///     unsigned int power;          /* transmit power in mW */
895/// }
896/// ```
897#[derive(Debug, Clone, PartialEq, Eq)]
898#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
899pub struct Extended80211Tx {
900    /// SSID string (max 32 bytes)
901    pub ssid: String,
902
903    /// BSSID (MAC address)
904    pub bssid: crate::models::MacAddress,
905
906    /// IEEE 802.11 version (a=1, b=2, g=3, n=4)
907    pub version: u32,
908
909    /// Number of transmissions (0=unknown, 1=success on first attempt, n>1 = n-1 retransmissions)
910    pub transmissions: u32,
911
912    /// Packet duration in microseconds (successful transmission)
913    pub packet_duration: u32,
914
915    /// Retransmission duration in microseconds (failed attempts)
916    pub retrans_duration: u32,
917
918    /// Channel number
919    pub channel: u32,
920
921    /// Speed in bits per second
922    pub speed: u64,
923
924    /// Transmit power in milliwatts
925    pub power: u32,
926}
927
928/// PDU (Protocol Data Unit) in 802.11 aggregation
929///
930/// # XDR Definition ([sFlow 802.11](https://sflow.org/sflow_80211.txt))
931///
932/// ```text
933/// struct pdu {
934///     flow_record flow_records<>;
935/// }
936/// ```
937#[derive(Debug, Clone, PartialEq, Eq)]
938#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
939pub struct Pdu {
940    /// Flow records for this PDU
941    pub flow_records: Vec<crate::models::FlowRecord>,
942}
943
944/// Extended 802.11 Aggregation - Format (0,1016)
945///
946/// 802.11 frame aggregation information
947///
948/// # XDR Definition ([sFlow 802.11](https://sflow.org/sflow_80211.txt))
949///
950/// ```text
951/// /* Extended 802.11 Aggregation Data */
952/// /* opaque = flow_data; enterprise = 0; format = 1016 */
953///
954/// struct extended_80211_aggregation {
955///     pdu pdus<>; /* Array of PDUs in the aggregation */
956/// }
957/// ```
958#[derive(Debug, Clone, PartialEq, Eq)]
959#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
960pub struct Extended80211Aggregation {
961    /// Array of PDUs in the aggregation
962    pub pdus: Vec<Pdu>,
963}
964
965/// Extended OpenFlow v1 - Format (0,1017) - **DEPRECATED**
966///
967/// OpenFlow 1.0 forwarding information
968///
969/// **Note:** This format was defined in an early draft of the sFlow OpenFlow specification
970/// but was deprecated and removed from the final specification. It is included here for
971/// backward compatibility with legacy implementations.
972///
973/// # XDR Definition ([sFlow OpenFlow Draft](https://sflow.org/draft-sflow-openflow.txt))
974///
975/// ```text
976/// /* Extended OpenFlow 1.0 Data */
977/// /* opaque = flow_data; enterprise = 0; format = 1017 */
978///
979/// struct extended_openflow_v1 {
980///     unsigned hyper flow_cookie;  /* Flow cookie set by controller */
981///     wildcards flow_match;        /* Bit array of wildcarded fields */
982///     actions flow_actions;        /* Bit array of actions applied */
983/// }
984/// ```
985#[derive(Debug, Clone, PartialEq, Eq)]
986#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
987pub struct ExtendedOpenFlowV1 {
988    /// Flow cookie set by the OpenFlow controller
989    pub flow_cookie: u64,
990
991    /// Bit array describing the fields in the packet header that are used to form the flow key
992    /// See OpenFlow 1.0 ofp_match for the definition of wildcards
993    pub flow_match: u32,
994
995    /// Bit array describing fields that may have been altered by the flow action
996    /// The ofp_action_type enum is used to determine the bit positions
997    pub flow_actions: u32,
998}
999
1000/// Extended L2 Tunnel Egress - Format (0,1021)
1001///
1002/// Layer 2 tunnel egress information - reports outer Ethernet headers
1003/// that will be added on egress when encapsulating packets
1004///
1005/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
1006///
1007/// ```text
1008/// /* opaque = flow_data; enterprise = 0; format = 1021 */
1009/// struct extended_L2_tunnel_egress {
1010///     sampled_ethernet header;
1011/// }
1012/// ```
1013#[derive(Debug, Clone, PartialEq, Eq)]
1014#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1015pub struct ExtendedL2TunnelEgress {
1016    /// Outer Ethernet header that will be added on egress
1017    pub header: SampledEthernet,
1018}
1019
1020/// Extended L2 Tunnel Ingress - Format (0,1022)
1021///
1022/// Layer 2 tunnel ingress information - reports outer Ethernet headers
1023/// that were present on ingress and removed during decapsulation
1024///
1025/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
1026///
1027/// ```text
1028/// /* opaque = flow_data; enterprise = 0; format = 1022 */
1029/// struct extended_L2_tunnel_ingress {
1030///     sampled_ethernet header;
1031/// }
1032/// ```
1033#[derive(Debug, Clone, PartialEq, Eq)]
1034#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1035pub struct ExtendedL2TunnelIngress {
1036    /// Outer Ethernet header that was present on ingress
1037    pub header: SampledEthernet,
1038}
1039
1040/// Extended IPv4 Tunnel Egress - Format (0,1023)
1041///
1042/// IPv4 tunnel egress information - reports outer IPv4 headers
1043/// that will be added on egress when encapsulating packets
1044///
1045/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
1046///
1047/// ```text
1048/// /* opaque = flow_data; enterprise = 0; format = 1023 */
1049/// struct extended_ipv4_tunnel_egress {
1050///     sampled_ipv4 header;
1051/// }
1052/// ```
1053#[derive(Debug, Clone, PartialEq, Eq)]
1054#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1055pub struct ExtendedIpv4TunnelEgress {
1056    /// Outer IPv4 header that will be added on egress
1057    pub header: SampledIpv4,
1058}
1059
1060/// Extended IPv4 Tunnel Ingress - Format (0,1024)
1061///
1062/// IPv4 tunnel ingress information - reports outer IPv4 headers
1063/// that were present on ingress and removed during decapsulation
1064///
1065/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
1066///
1067/// ```text
1068/// /* opaque = flow_data; enterprise = 0; format = 1024 */
1069/// struct extended_ipv4_tunnel_ingress {
1070///     sampled_ipv4 header;
1071/// }
1072/// ```
1073#[derive(Debug, Clone, PartialEq, Eq)]
1074#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1075pub struct ExtendedIpv4TunnelIngress {
1076    /// Outer IPv4 header that was present on ingress
1077    pub header: SampledIpv4,
1078}
1079
1080/// Extended IPv6 Tunnel Egress - Format (0,1025)
1081///
1082/// IPv6 tunnel egress information - reports outer IPv6 headers
1083/// that will be added on egress when encapsulating packets
1084///
1085/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
1086///
1087/// ```text
1088/// /* opaque = flow_data; enterprise = 0; format = 1025 */
1089/// struct extended_ipv6_tunnel_egress {
1090///     sampled_ipv6 header;
1091/// }
1092/// ```
1093#[derive(Debug, Clone, PartialEq, Eq)]
1094#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1095pub struct ExtendedIpv6TunnelEgress {
1096    /// Outer IPv6 header that will be added on egress
1097    pub header: SampledIpv6,
1098}
1099
1100/// Extended IPv6 Tunnel Ingress - Format (0,1026)
1101///
1102/// IPv6 tunnel ingress information - reports outer IPv6 headers
1103/// that were present on ingress and removed during decapsulation
1104///
1105/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
1106///
1107/// ```text
1108/// /* opaque = flow_data; enterprise = 0; format = 1026 */
1109/// struct extended_ipv6_tunnel_ingress {
1110///     sampled_ipv6 header;
1111/// }
1112/// ```
1113#[derive(Debug, Clone, PartialEq, Eq)]
1114#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1115pub struct ExtendedIpv6TunnelIngress {
1116    /// Outer IPv6 header that was present on ingress
1117    pub header: SampledIpv6,
1118}
1119
1120/// Extended Decapsulate Egress - Format (0,1027)
1121///
1122/// Indicates the end of a tunnel and points to the start of the inner header
1123/// Used when a packet is sampled before decapsulation on ingress
1124///
1125/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
1126///
1127/// ```text
1128/// /* opaque = flow_data; enterprise = 0; format = 1027 */
1129/// struct extended_decapsulate_egress {
1130///     unsigned int inner_header_offset;
1131/// }
1132/// ```
1133#[derive(Debug, Clone, PartialEq, Eq)]
1134#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1135pub struct ExtendedDecapsulateEgress {
1136    /// Offset in bytes to the inner header within the sampled packet header
1137    pub inner_header_offset: u32,
1138}
1139
1140/// Extended Decapsulate Ingress - Format (0,1028)
1141///
1142/// Indicates the start of a tunnel
1143/// Used when a packet is sampled after encapsulation on egress
1144///
1145/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
1146///
1147/// ```text
1148/// /* opaque = flow_data; enterprise = 0; format = 1028 */
1149/// struct extended_decapsulate_ingress {
1150///     unsigned int inner_header_offset;
1151/// }
1152/// ```
1153#[derive(Debug, Clone, PartialEq, Eq)]
1154#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1155pub struct ExtendedDecapsulateIngress {
1156    /// Offset in bytes to the inner header within the sampled packet header
1157    pub inner_header_offset: u32,
1158}
1159
1160/// Extended VNI Egress - Format (0,1029)
1161///
1162/// Virtual Network Identifier for egress traffic
1163/// The VNI may be explicitly included in the tunneling protocol or implicit
1164///
1165/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
1166///
1167/// ```text
1168/// /* opaque_flow_data; enterprise = 0; format = 1029 */
1169/// struct extended_vni_egress {
1170///     unsigned int vni;
1171/// }
1172/// ```
1173#[derive(Debug, Clone, PartialEq, Eq)]
1174#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1175pub struct ExtendedVniEgress {
1176    /// Virtual Network Identifier
1177    pub vni: u32,
1178}
1179
1180/// Extended VNI Ingress - Format (0,1030)
1181///
1182/// Virtual Network Identifier for ingress traffic
1183/// The VNI may be explicitly included in the tunneling protocol or implicit
1184/// in the encapsulation (e.g., VXLAN uses UDP port 4789).
1185///
1186/// # XDR Definition ([sFlow Tunnel](https://sflow.org/sflow_tunnels.txt))
1187///
1188/// ```text
1189/// /* VNI ingress */
1190/// /* opaque = flow_data; enterprise = 0; format = 1030 */
1191///
1192/// struct extended_vni_ingress {
1193///     unsigned int vni;  /* VNI associated with ingress packet */
1194/// }
1195/// ```
1196#[derive(Debug, Clone, PartialEq, Eq)]
1197#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1198pub struct ExtendedVniIngress {
1199    /// Virtual Network Identifier
1200    pub vni: u32,
1201}
1202
1203/// Drop reason codes for discarded packets
1204///
1205/// # XDR Definition ([sFlow Drops](https://sflow.org/sflow_drops.txt))
1206///
1207/// ```text
1208/// /* The drop_reason enumeration may be expanded over time.
1209///    sFlow collectors must be prepared to receive discard_packet
1210///    structures with unrecognized drop_reason values.
1211///
1212///    This document expands on the discard reason codes 0-262 defined
1213///    in the sFlow Version 5 [1] interface typedef and this expanded list
1214///    should be regarded as an expansion of the reason codes in the
1215///    interface typdef and are valid anywhere the typedef is referenced.
1216///
1217///    Codes 263-288 are defined in Devlink Trap [2]. Drop reason / group
1218///    names from the Devlink Trap document are preserved where they define
1219///    new reason codes, or referenced as comments where they map to existing
1220///    codes.
1221///
1222///    Codes 289-303 are reasons that have yet to be upstreamed to Devlink Trap,
1223///    but the intent is that they will eventually be upstreamed and documented as
1224///    part of the Linux API [2], and so they have been reserved.
1225///
1226///    The authoritative list of drop reasons will be maintained
1227///    at sflow.org */
1228///
1229/// enum drop_reason {
1230///    net_unreachable      = 0,
1231///    host_unreachable     = 1,
1232///    protocol_unreachable = 2,
1233///    port_unreachable     = 3,
1234///    frag_needed          = 4,
1235///    src_route_failed     = 5,
1236///    dst_net_unknown      = 6, /* ipv4_lpm_miss, ipv6_lpm_miss */
1237///    dst_host_unknown     = 7,
1238///    src_host_isolated    = 8,
1239///    dst_net_prohibited   = 9, /* reject_route */
1240///    dst_host_prohibited  = 10,
1241///    dst_net_tos_unreachable  = 11,
1242///    dst_host_tos_unreacheable = 12,
1243///    comm_admin_prohibited = 13,
1244///    host_precedence_violation = 14,
1245///    precedence_cutoff    = 15,
1246///    unknown              = 256,
1247///    ttl_exceeded         = 257, /* ttl_value_is_too_small */
1248///    acl                  = 258, /* ingress_flow_action_drop,
1249///                                   egress_flow_action_drop
1250///                                   group acl_drops */
1251///    no_buffer_space      = 259, /* tail_drop */
1252///    red                  = 260, /* early_drop */
1253///    traffic_shaping      = 261,
1254///    pkt_too_big          = 262, /* mtu_value_is_too_small */
1255///    src_mac_is_multicast = 263,
1256///    vlan_tag_mismatch    = 264,
1257///    ingress_vlan_filter  = 265,
1258///    ingress_spanning_tree_filter = 266,
1259///    port_list_is_empty   = 267,
1260///    port_loopback_filter = 268,
1261///    blackhole_route      = 269,
1262///    non_ip               = 270,
1263///    uc_dip_over_mc_dmac  = 271,
1264///    dip_is_loopback_address = 272,
1265///    sip_is_mc            = 273,
1266///    sip_is_loopback_address = 274,
1267///    ip_header_corrupted  = 275,
1268///    ipv4_sip_is_limited_bc = 276,
1269///    ipv6_mc_dip_reserved_scope = 277,
1270///    ipv6_mc_dip_interface_local_scope = 278,
1271///    unresolved_neigh     = 279,
1272///    mc_reverse_path_forwarding = 280,
1273///    non_routable_packet  = 281,
1274///    decap_error          = 282,
1275///    overlay_smac_is_mc   = 283,
1276///    unknown_l2           = 284, /* group l2_drops */
1277///    unknown_l3           = 285, /* group l3_drops */
1278///    unknown_l3_exception = 286, /* group l3_exceptions */
1279///    unknown_buffer       = 287, /* group buffer_drops */
1280///    unknown_tunnel       = 288, /* group tunnel_drops */
1281///    unknown_l4           = 289,
1282///    sip_is_unspecified   = 290,
1283///    mlag_port_isolation  = 291,
1284///    blackhole_arp_neigh  = 292,
1285///    src_mac_is_dmac      = 293,
1286///    dmac_is_reserved     = 294,
1287///    sip_is_class_e       = 295,
1288///    mc_dmac_mismatch     = 296,
1289///    sip_is_dip           = 297,
1290///    dip_is_local_network = 298,
1291///    dip_is_link_local    = 299,
1292///    overlay_smac_is_dmac = 300,
1293///    egress_vlan_filter   = 301,
1294///    uc_reverse_path_forwarding = 302,
1295///    split_horizon        = 303
1296/// }
1297/// ```
1298#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1299#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1300#[repr(u32)]
1301pub enum DropReason {
1302    NetUnreachable = 0,
1303    HostUnreachable = 1,
1304    ProtocolUnreachable = 2,
1305    PortUnreachable = 3,
1306    FragNeeded = 4,
1307    SrcRouteFailed = 5,
1308    DstNetUnknown = 6,
1309    DstHostUnknown = 7,
1310    SrcHostIsolated = 8,
1311    DstNetProhibited = 9,
1312    DstHostProhibited = 10,
1313    DstNetTosUnreachable = 11,
1314    DstHostTosUnreachable = 12,
1315    CommAdminProhibited = 13,
1316    HostPrecedenceViolation = 14,
1317    PrecedenceCutoff = 15,
1318    Unknown = 256,
1319    TtlExceeded = 257,
1320    Acl = 258,
1321    NoBufferSpace = 259,
1322    Red = 260,
1323    TrafficShaping = 261,
1324    PktTooBig = 262,
1325    SrcMacIsMulticast = 263,
1326    VlanTagMismatch = 264,
1327    IngressVlanFilter = 265,
1328    IngressSpanningTreeFilter = 266,
1329    PortListIsEmpty = 267,
1330    PortLoopbackFilter = 268,
1331    BlackholeRoute = 269,
1332    NonIp = 270,
1333    UcDipOverMcDmac = 271,
1334    DipIsLoopbackAddress = 272,
1335    SipIsMc = 273,
1336    SipIsLoopbackAddress = 274,
1337    IpHeaderCorrupted = 275,
1338    Ipv4SipIsLimitedBc = 276,
1339    Ipv6McDipReservedScope = 277,
1340    Ipv6McDipInterfaceLocalScope = 278,
1341    UnresolvedNeigh = 279,
1342    McReversePathForwarding = 280,
1343    NonRoutablePacket = 281,
1344    DecapError = 282,
1345    OverlaySmacIsMc = 283,
1346    UnknownL2 = 284,
1347    UnknownL3 = 285,
1348    UnknownL3Exception = 286,
1349    UnknownBuffer = 287,
1350    UnknownTunnel = 288,
1351    UnknownL4 = 289,
1352    SipIsUnspecified = 290,
1353    MlagPortIsolation = 291,
1354    BlackholeArpNeigh = 292,
1355    SrcMacIsDmac = 293,
1356    DmacIsReserved = 294,
1357    SipIsClassE = 295,
1358    McDmacMismatch = 296,
1359    SipIsDip = 297,
1360    DipIsLocalNetwork = 298,
1361    DipIsLinkLocal = 299,
1362    OverlaySmacIsDmac = 300,
1363    EgressVlanFilter = 301,
1364    UcReversePathForwarding = 302,
1365    SplitHorizon = 303,
1366}
1367
1368impl DropReason {
1369    /// Convert from u32 value to DropReason enum
1370    ///
1371    /// This is a mechanical mapping of u32 values to enum variants
1372    /// defined in the sFlow specification. The function is tested
1373    /// with representative samples rather than exhaustively.
1374    pub fn from_u32(value: u32) -> Option<Self> {
1375        match value {
1376            0 => Some(DropReason::NetUnreachable),
1377            1 => Some(DropReason::HostUnreachable),
1378            2 => Some(DropReason::ProtocolUnreachable),
1379            3 => Some(DropReason::PortUnreachable),
1380            4 => Some(DropReason::FragNeeded),
1381            5 => Some(DropReason::SrcRouteFailed),
1382            6 => Some(DropReason::DstNetUnknown),
1383            7 => Some(DropReason::DstHostUnknown),
1384            8 => Some(DropReason::SrcHostIsolated),
1385            9 => Some(DropReason::DstNetProhibited),
1386            10 => Some(DropReason::DstHostProhibited),
1387            11 => Some(DropReason::DstNetTosUnreachable),
1388            12 => Some(DropReason::DstHostTosUnreachable),
1389            13 => Some(DropReason::CommAdminProhibited),
1390            14 => Some(DropReason::HostPrecedenceViolation),
1391            15 => Some(DropReason::PrecedenceCutoff),
1392            256 => Some(DropReason::Unknown),
1393            257 => Some(DropReason::TtlExceeded),
1394            258 => Some(DropReason::Acl),
1395            259 => Some(DropReason::NoBufferSpace),
1396            260 => Some(DropReason::Red),
1397            261 => Some(DropReason::TrafficShaping),
1398            262 => Some(DropReason::PktTooBig),
1399            263 => Some(DropReason::SrcMacIsMulticast),
1400            264 => Some(DropReason::VlanTagMismatch),
1401            265 => Some(DropReason::IngressVlanFilter),
1402            266 => Some(DropReason::IngressSpanningTreeFilter),
1403            267 => Some(DropReason::PortListIsEmpty),
1404            268 => Some(DropReason::PortLoopbackFilter),
1405            269 => Some(DropReason::BlackholeRoute),
1406            270 => Some(DropReason::NonIp),
1407            271 => Some(DropReason::UcDipOverMcDmac),
1408            272 => Some(DropReason::DipIsLoopbackAddress),
1409            273 => Some(DropReason::SipIsMc),
1410            274 => Some(DropReason::SipIsLoopbackAddress),
1411            275 => Some(DropReason::IpHeaderCorrupted),
1412            276 => Some(DropReason::Ipv4SipIsLimitedBc),
1413            277 => Some(DropReason::Ipv6McDipReservedScope),
1414            278 => Some(DropReason::Ipv6McDipInterfaceLocalScope),
1415            279 => Some(DropReason::UnresolvedNeigh),
1416            280 => Some(DropReason::McReversePathForwarding),
1417            281 => Some(DropReason::NonRoutablePacket),
1418            282 => Some(DropReason::DecapError),
1419            283 => Some(DropReason::OverlaySmacIsMc),
1420            284 => Some(DropReason::UnknownL2),
1421            285 => Some(DropReason::UnknownL3),
1422            286 => Some(DropReason::UnknownL3Exception),
1423            287 => Some(DropReason::UnknownBuffer),
1424            288 => Some(DropReason::UnknownTunnel),
1425            289 => Some(DropReason::UnknownL4),
1426            290 => Some(DropReason::SipIsUnspecified),
1427            291 => Some(DropReason::MlagPortIsolation),
1428            292 => Some(DropReason::BlackholeArpNeigh),
1429            293 => Some(DropReason::SrcMacIsDmac),
1430            294 => Some(DropReason::DmacIsReserved),
1431            295 => Some(DropReason::SipIsClassE),
1432            296 => Some(DropReason::McDmacMismatch),
1433            297 => Some(DropReason::SipIsDip),
1434            298 => Some(DropReason::DipIsLocalNetwork),
1435            299 => Some(DropReason::DipIsLinkLocal),
1436            300 => Some(DropReason::OverlaySmacIsDmac),
1437            301 => Some(DropReason::EgressVlanFilter),
1438            302 => Some(DropReason::UcReversePathForwarding),
1439            303 => Some(DropReason::SplitHorizon),
1440            _ => None,
1441        }
1442    }
1443}
1444
1445/// Extended Egress Queue - Format (0,1036)
1446///
1447/// Selected egress queue for the sampled packet
1448///
1449/// # XDR Definition ([sFlow Drops](https://sflow.org/sflow_drops.txt))
1450///
1451/// ```text
1452/// /* Selected egress queue */
1453/// /* Output port number must be provided in enclosing structure */
1454/// /* opaque = flow_data; enterprise = 0; format = 1036 */
1455/// struct extended_egress_queue {
1456///   unsigned int queue;  /* eqress queue number selected for sampled packet */
1457/// }
1458/// ```
1459#[derive(Debug, Clone, PartialEq, Eq)]
1460#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1461pub struct ExtendedEgressQueue {
1462    /// Egress queue number selected for sampled packet
1463    pub queue: u32,
1464}
1465
1466/// Extended ACL - Format (0,1037)
1467///
1468/// ACL information about the rule that matched this packet
1469///
1470/// # XDR Definition ([sFlow Drops](https://sflow.org/sflow_drops.txt))
1471///
1472/// ```text
1473/// /* ACL information */
1474/// /* Information about ACL rule that matched this packet
1475/// /* opaque = flow_data; enterprise = 0; format = 1037 */
1476/// struct extended_acl {
1477///   unsigned int number; /* access list number */
1478///   string name<>; /* access list name */
1479///   unsigned int direction; /* unknown = 0, ingress = 1, egress = 2 */
1480/// }
1481/// ```
1482#[derive(Debug, Clone, PartialEq, Eq)]
1483#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1484pub struct ExtendedAcl {
1485    /// Access list number
1486    pub number: u32,
1487
1488    /// Access list name
1489    pub name: String,
1490
1491    /// Direction: unknown = 0, ingress = 1, egress = 2
1492    pub direction: u32,
1493}
1494
1495/// Extended Function - Format (0,1038)
1496///
1497/// Name of the function in software network stack that discarded the packet
1498///
1499/// # XDR Definition ([sFlow Drops](https://sflow.org/sflow_drops.txt))
1500///
1501/// ```text
1502/// /* Software function */
1503/// /* Name of the function in software network stack that discarded the packet */
1504/// /* opaque = flow_data; enterprise = 0; format = 1038 */
1505/// struct extended_function {
1506///   string symbol<>;
1507/// }
1508/// ```
1509#[derive(Debug, Clone, PartialEq, Eq)]
1510#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1511pub struct ExtendedFunction {
1512    /// Function symbol name
1513    pub symbol: String,
1514}
1515
1516/// Extended Transit - Format (0,1039)
1517///
1518/// Delay for sampled packet traversing switch
1519///
1520/// # XDR Definition ([sFlow Transit](https://sflow.org/sflow_transit.txt))
1521///
1522/// ```text
1523/// /* Delay for sampled packet traversing switch */
1524/// /* opaque = flow_data; enterprise = 0; format = 1039 */
1525/// struct extended_transit {
1526///   unsigned int delay; /* transit delay in nanoseconds
1527///                          0xffffffff indicates value >= 0xffffffff */
1528/// }
1529/// ```
1530#[derive(Debug, Clone, PartialEq, Eq)]
1531#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1532pub struct ExtendedTransit {
1533    /// Transit delay in nanoseconds (0xffffffff indicates value >= 0xffffffff)
1534    pub delay: u32,
1535}
1536
1537/// Extended Queue - Format (0,1040)
1538///
1539/// Queue depth for sampled packet traversing switch
1540///
1541/// # XDR Definition ([sFlow Transit](https://sflow.org/sflow_transit.txt))
1542///
1543/// ```text
1544/// /* Queue depth for sampled packet traversing switch */
1545/// /* extended_egress_queue structure must be included */
1546/// /* opaque = flow_data; enterprise = 0; format = 1040 */
1547/// struct extended_queue {
1548///   unsigned int depth;   /* queue depth in bytes */
1549/// }
1550/// ```
1551#[derive(Debug, Clone, PartialEq, Eq)]
1552#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1553pub struct ExtendedQueue {
1554    /// Queue depth in bytes
1555    pub depth: u32,
1556}
1557
1558/// Extended HW Trap - Format (0,1041)
1559///
1560/// Devlink Trap Name information from Linux kernel
1561///
1562/// # XDR Definition ([host-sflow](https://github.com/sflow/host-sflow/blob/v2.0.50-3/src/sflow/sflow.h))
1563///
1564/// ```text
1565/// /* Devlink Trap Name */
1566/// /* opaque = flow_data; enterprise = 0; format = 1041 */
1567/// /* https://www.kernel.org/doc/html/latest/networking/devlink/devlink-trap.html */
1568/// /* XDR spec: */
1569/// /*  struct extended_hw_trap { */
1570/// /*    string group<>; */ /* NET_DM_ATTR_HW_TRAP_GROUP_NAME */
1571/// /*    string trap<>; */ /* NET_DM_ATTR_HW_TRAP_NAME */
1572/// /*  } */
1573/// ```
1574#[derive(Debug, Clone, PartialEq, Eq)]
1575#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1576pub struct ExtendedHwTrap {
1577    /// Hardware trap group name (NET_DM_ATTR_HW_TRAP_GROUP_NAME)
1578    pub group: String,
1579
1580    /// Hardware trap name (NET_DM_ATTR_HW_TRAP_NAME)
1581    pub trap: String,
1582}
1583
1584/// Extended Linux Drop Reason - Format (0,1042)
1585///
1586/// Linux drop_monitor reason information
1587///
1588/// # XDR Definition ([host-sflow](https://github.com/sflow/host-sflow/blob/v2.0.50-3/src/sflow/sflow.h))
1589///
1590/// ```text
1591/// /* Linux drop_monitor reason */
1592/// /* opaque = flow_data; enterprise = 0; format = 1042 */
1593/// /* https://github.com/torvalds/linux/blob/master/include/net/dropreason.h */
1594/// /* XDR spec: */
1595/// /*  struct extended_linux_drop_reason { */
1596/// /*    string reason<>; */ /* NET_DM_ATTR_REASON */
1597/// /*  } */
1598/// ```
1599#[derive(Debug, Clone, PartialEq, Eq)]
1600#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1601pub struct ExtendedLinuxDropReason {
1602    /// Drop reason string (NET_DM_ATTR_REASON)
1603    pub reason: String,
1604}
1605
1606/// Extended Socket IPv4 - Format (0,2100)
1607///
1608/// IPv4 socket information for application transactions
1609///
1610/// # XDR Definition ([sFlow Host](https://sflow.org/sflow_host.txt))
1611///
1612/// ```text
1613/// /* IPv4 Socket */
1614/// /* opaque = flow_data; enterprise = 0; format = 2100 */
1615///
1616/// struct extended_socket_ipv4 {
1617///     unsigned int protocol;     /* IP Protocol type (e.g., TCP = 6, UDP = 17) */
1618///     ip_v4 local_ip;            /* local IP address */
1619///     ip_v4 remote_ip;           /* remote IP address */
1620///     unsigned int local_port;   /* TCP/UDP local port number or equivalent */
1621///     unsigned int remote_port;  /* TCP/UDP remote port number or equivalent */
1622/// }
1623/// ```
1624#[derive(Debug, Clone, PartialEq, Eq)]
1625#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1626pub struct ExtendedSocketIpv4 {
1627    /// IP Protocol type (e.g., TCP = 6, UDP = 17)
1628    pub protocol: u32,
1629
1630    /// Local IP address
1631    pub local_ip: std::net::Ipv4Addr,
1632
1633    /// Remote IP address
1634    pub remote_ip: std::net::Ipv4Addr,
1635
1636    /// TCP/UDP local port number
1637    pub local_port: u32,
1638
1639    /// TCP/UDP remote port number
1640    pub remote_port: u32,
1641}
1642
1643/// Extended Socket IPv6 - Format (0,2101)
1644///
1645/// IPv6 socket information for application transactions
1646///
1647/// # XDR Definition ([sFlow Host](https://sflow.org/sflow_host.txt))
1648///
1649/// ```text
1650/// /* IPv6 Socket */
1651/// /* opaque = flow_data; enterprise = 0; format = 2101 */
1652///
1653/// struct extended_socket_ipv6 {
1654///     unsigned int protocol;     /* IP Protocol type (e.g., TCP = 6, UDP = 17) */
1655///     ip_v6 local_ip;            /* local IP address */
1656///     ip_v6 remote_ip;           /* remote IP address */
1657///     unsigned int local_port;   /* TCP/UDP local port number or equivalent */
1658///     unsigned int remote_port;  /* TCP/UDP remote port number or equivalent */
1659/// }
1660/// ```
1661#[derive(Debug, Clone, PartialEq, Eq)]
1662#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1663pub struct ExtendedSocketIpv6 {
1664    /// IP Protocol type (e.g., TCP = 6, UDP = 17)
1665    pub protocol: u32,
1666
1667    /// Local IP address
1668    pub local_ip: std::net::Ipv6Addr,
1669
1670    /// Remote IP address
1671    pub remote_ip: std::net::Ipv6Addr,
1672
1673    /// TCP/UDP local port number
1674    pub local_port: u32,
1675
1676    /// TCP/UDP remote port number
1677    pub remote_port: u32,
1678}
1679
1680/// HTTP method enumeration
1681///
1682/// # XDR Definition ([sFlow HTTP](https://sflow.org/sflow_http.txt))
1683///
1684/// ```text
1685/// /* The http_method enumeration may be expanded over time.
1686///    Applications receiving sFlow must be prepared to receive
1687///    http_request structures with unknown http_method values */
1688///
1689/// enum http_method {
1690///   OTHER    = 0;
1691///   OPTIONS  = 1;
1692///   GET      = 2;
1693///   HEAD     = 3;
1694///   POST     = 4;
1695///   PUT      = 5;
1696///   DELETE   = 6;
1697///   TRACE    = 7;
1698///   CONNECT  = 8;
1699/// }
1700/// ```
1701#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1702#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1703#[repr(u32)]
1704pub enum HttpMethod {
1705    Other = 0,
1706    Options = 1,
1707    Get = 2,
1708    Head = 3,
1709    Post = 4,
1710    Put = 5,
1711    Delete = 6,
1712    Trace = 7,
1713    Connect = 8,
1714}
1715
1716impl From<u32> for HttpMethod {
1717    fn from(value: u32) -> Self {
1718        match value {
1719            1 => HttpMethod::Options,
1720            2 => HttpMethod::Get,
1721            3 => HttpMethod::Head,
1722            4 => HttpMethod::Post,
1723            5 => HttpMethod::Put,
1724            6 => HttpMethod::Delete,
1725            7 => HttpMethod::Trace,
1726            8 => HttpMethod::Connect,
1727            _ => HttpMethod::Other,
1728        }
1729    }
1730}
1731
1732impl std::fmt::Display for HttpMethod {
1733    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1734        match self {
1735            HttpMethod::Other => write!(f, "OTHER"),
1736            HttpMethod::Options => write!(f, "OPTIONS"),
1737            HttpMethod::Get => write!(f, "GET"),
1738            HttpMethod::Head => write!(f, "HEAD"),
1739            HttpMethod::Post => write!(f, "POST"),
1740            HttpMethod::Put => write!(f, "PUT"),
1741            HttpMethod::Delete => write!(f, "DELETE"),
1742            HttpMethod::Trace => write!(f, "TRACE"),
1743            HttpMethod::Connect => write!(f, "CONNECT"),
1744        }
1745    }
1746}
1747
1748/// Extended Proxy Socket IPv4 - Format (0,2102)
1749///
1750/// IPv4 socket information for proxy connections
1751///
1752/// # XDR Definition ([sFlow HTTP](https://sflow.org/sflow_http.txt))
1753///
1754/// ```text
1755/// /* Proxy socket IPv4 */
1756/// /* opaque = flow_data; enterprise=0; format=2102 */
1757/// struct extended_proxy_socket_ipv4 {
1758///   extended_socket_ipv4 socket;
1759/// }
1760/// ```
1761#[derive(Debug, Clone, PartialEq, Eq)]
1762#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1763pub struct ExtendedProxySocketIpv4 {
1764    /// Socket information
1765    pub socket: ExtendedSocketIpv4,
1766}
1767
1768/// Extended Proxy Socket IPv6 - Format (0,2103)
1769///
1770/// IPv6 socket information for proxy connections
1771///
1772/// # XDR Definition ([sFlow HTTP](https://sflow.org/sflow_http.txt))
1773///
1774/// ```text
1775/// /* Proxy socket IPv6 */
1776/// /* opaque = flow_data; enterprise=0; format=2103 */
1777/// struct extended_proxy_socket_ipv6 {
1778///   extended_socket_ipv6 socket;
1779/// }
1780/// ```
1781#[derive(Debug, Clone, PartialEq, Eq)]
1782#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1783pub struct ExtendedProxySocketIpv6 {
1784    /// Socket information
1785    pub socket: ExtendedSocketIpv6,
1786}
1787
1788/// Application operation context
1789///
1790/// # XDR Definition ([sFlow Application](https://sflow.org/sflow_application.txt))
1791///
1792/// ```text
1793/// struct context {
1794///     application application;
1795///     operation operation;
1796///     attributes attributes;
1797/// }
1798/// ```
1799#[derive(Debug, Clone, PartialEq, Eq)]
1800#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1801pub struct AppContext {
1802    /// Application name (e.g., "payment", "mail.smtp", "db.oracle")
1803    pub application: String,
1804
1805    /// Operation name (e.g., "get.customer.name", "upload.photo")
1806    pub operation: String,
1807
1808    /// Operation attributes as name=value pairs (e.g., "cc=visa&loc=mobile")
1809    pub attributes: String,
1810}
1811
1812/// Application operation status
1813///
1814/// # XDR Definition ([sFlow Application](https://sflow.org/sflow_application.txt))
1815#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1816#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1817#[repr(u32)]
1818pub enum AppStatus {
1819    Success = 0,
1820    Other = 1,
1821    Timeout = 2,
1822    InternalError = 3,
1823    BadRequest = 4,
1824    Forbidden = 5,
1825    TooLarge = 6,
1826    NotImplemented = 7,
1827    NotFound = 8,
1828    Unavailable = 9,
1829    Unauthorized = 10,
1830}
1831
1832impl From<u32> for AppStatus {
1833    fn from(value: u32) -> Self {
1834        match value {
1835            0 => AppStatus::Success,
1836            1 => AppStatus::Other,
1837            2 => AppStatus::Timeout,
1838            3 => AppStatus::InternalError,
1839            4 => AppStatus::BadRequest,
1840            5 => AppStatus::Forbidden,
1841            6 => AppStatus::TooLarge,
1842            7 => AppStatus::NotImplemented,
1843            8 => AppStatus::NotFound,
1844            9 => AppStatus::Unavailable,
1845            10 => AppStatus::Unauthorized,
1846            _ => AppStatus::Other,
1847        }
1848    }
1849}
1850
1851/// Memcache Protocol
1852///
1853/// # XDR Definition ([sFlow Memcache](https://sflow.org/sflow_memcache.txt))
1854///
1855/// ```text
1856/// enum memcache_protocol {
1857///   OTHER  = 0;
1858///   ASCII  = 1;
1859///   BINARY = 2;
1860/// }
1861/// ```
1862#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1863#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1864#[repr(u32)]
1865pub enum MemcacheProtocol {
1866    Other = 0,
1867    Ascii = 1,
1868    Binary = 2,
1869}
1870
1871impl MemcacheProtocol {
1872    /// Convert from u32 value to MemcacheProtocol enum
1873    pub fn from_u32(value: u32) -> Self {
1874        match value {
1875            1 => MemcacheProtocol::Ascii,
1876            2 => MemcacheProtocol::Binary,
1877            _ => MemcacheProtocol::Other,
1878        }
1879    }
1880}
1881
1882/// Memcache Command
1883///
1884/// # XDR Definition ([sFlow Memcache](https://sflow.org/sflow_memcache.txt))
1885///
1886/// ```text
1887/// enum memcache_cmd {
1888///   OTHER    = 0;
1889///   SET      = 1;
1890///   ADD      = 2;
1891///   REPLACE  = 3;
1892///   APPEND   = 4;
1893///   PREPEND  = 5;
1894///   CAS      = 6;
1895///   GET      = 7;
1896///   GETS     = 8;
1897///   INCR     = 9;
1898///   DECR     = 10;
1899///   DELETE   = 11;
1900///   STATS    = 12;
1901///   FLUSH    = 13;
1902///   VERSION  = 14;
1903///   QUIT     = 15;
1904///   TOUCH    = 16;
1905/// }
1906/// ```
1907#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1908#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1909#[repr(u32)]
1910pub enum MemcacheCommand {
1911    Other = 0,
1912    Set = 1,
1913    Add = 2,
1914    Replace = 3,
1915    Append = 4,
1916    Prepend = 5,
1917    Cas = 6,
1918    Get = 7,
1919    Gets = 8,
1920    Incr = 9,
1921    Decr = 10,
1922    Delete = 11,
1923    Stats = 12,
1924    Flush = 13,
1925    Version = 14,
1926    Quit = 15,
1927    Touch = 16,
1928}
1929
1930impl MemcacheCommand {
1931    /// Convert from u32 value to MemcacheCommand enum
1932    pub fn from_u32(value: u32) -> Self {
1933        match value {
1934            1 => MemcacheCommand::Set,
1935            2 => MemcacheCommand::Add,
1936            3 => MemcacheCommand::Replace,
1937            4 => MemcacheCommand::Append,
1938            5 => MemcacheCommand::Prepend,
1939            6 => MemcacheCommand::Cas,
1940            7 => MemcacheCommand::Get,
1941            8 => MemcacheCommand::Gets,
1942            9 => MemcacheCommand::Incr,
1943            10 => MemcacheCommand::Decr,
1944            11 => MemcacheCommand::Delete,
1945            12 => MemcacheCommand::Stats,
1946            13 => MemcacheCommand::Flush,
1947            14 => MemcacheCommand::Version,
1948            15 => MemcacheCommand::Quit,
1949            16 => MemcacheCommand::Touch,
1950            _ => MemcacheCommand::Other,
1951        }
1952    }
1953}
1954
1955/// Memcache Status
1956///
1957/// # XDR Definition ([sFlow Memcache](https://sflow.org/sflow_memcache.txt))
1958///
1959/// ```text
1960/// enum memcache_status {
1961///   UNKNOWN      = 0;
1962///   OK           = 1;
1963///   ERROR        = 2;
1964///   CLIENT_ERROR = 3;
1965///   SERVER_ERROR = 4;
1966///   STORED       = 5;
1967///   NOT_STORED   = 6;
1968///   EXISTS       = 7;
1969///   NOT_FOUND    = 8;
1970///   DELETED      = 9;
1971/// }
1972/// ```
1973#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1974#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1975#[repr(u32)]
1976pub enum MemcacheStatus {
1977    Unknown = 0,
1978    Ok = 1,
1979    Error = 2,
1980    ClientError = 3,
1981    ServerError = 4,
1982    Stored = 5,
1983    NotStored = 6,
1984    Exists = 7,
1985    NotFound = 8,
1986    Deleted = 9,
1987}
1988
1989impl MemcacheStatus {
1990    /// Convert from u32 value to MemcacheStatus enum
1991    pub fn from_u32(value: u32) -> Self {
1992        match value {
1993            1 => MemcacheStatus::Ok,
1994            2 => MemcacheStatus::Error,
1995            3 => MemcacheStatus::ClientError,
1996            4 => MemcacheStatus::ServerError,
1997            5 => MemcacheStatus::Stored,
1998            6 => MemcacheStatus::NotStored,
1999            7 => MemcacheStatus::Exists,
2000            8 => MemcacheStatus::NotFound,
2001            9 => MemcacheStatus::Deleted,
2002            _ => MemcacheStatus::Unknown,
2003        }
2004    }
2005}
2006
2007/// Memcache Operation - Format (0,2200)
2008///
2009/// Sampled memcache operation
2010///
2011/// # XDR Definition ([sFlow Memcache](https://sflow.org/sflow_memcache.txt))
2012///
2013/// ```text
2014/// /* Memcache operation */
2015/// /* opaque = flow_data; enterprise = 0; format = 2200 */
2016///
2017/// struct memcache_operation {
2018///   memcache_protocol protocol;  /* protocol */
2019///   memcache_cmd cmd;            /* command */
2020///   string<255> key;             /* key used to store/retrieve data */
2021///   unsigned int nkeys;          /* number of keys
2022///                                   (including sampled key) */
2023///   unsigned int value_bytes;    /* size of the value (in bytes) */
2024///   unsigned int uS;             /* duration of the operation
2025///                                   (in microseconds) */
2026///   memcache_status status;      /* status of command */
2027/// }
2028/// ```
2029#[derive(Debug, Clone, PartialEq, Eq)]
2030#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2031pub struct MemcacheOperation {
2032    /// Protocol (ASCII or Binary)
2033    pub protocol: MemcacheProtocol,
2034
2035    /// Command type
2036    pub cmd: MemcacheCommand,
2037
2038    /// Key used to store/retrieve data
2039    pub key: String,
2040
2041    /// Number of keys (including sampled key)
2042    pub nkeys: u32,
2043
2044    /// Size of the value in bytes
2045    pub value_bytes: u32,
2046
2047    /// Duration of the operation in microseconds
2048    pub duration_us: u32,
2049
2050    /// Status of the command
2051    pub status: MemcacheStatus,
2052}
2053
2054/// HTTP Request - Format (0,2201) - **DEPRECATED**
2055///
2056/// Legacy HTTP request information
2057///
2058/// **Note:** This format was defined in an early sFlow HTTP discussion
2059/// but was deprecated and replaced by format 2206. It is included here for
2060/// backward compatibility with legacy implementations.
2061///
2062/// # XDR Definition ([sFlow Discussion](https://groups.google.com/g/sflow/c/iKzLK61ZTR0))
2063///
2064/// ```text
2065/// /* HTTP request */
2066/// /* opaque = flow_data; enterprise = 0; format = 2201 */
2067/// struct http_request {
2068///   http_method method;        /* method */
2069///   string<255> uri;           /* URI exactly as it came from the client */
2070///   string<32> host;           /* Host value from request header */
2071///   string<255> referer;       /* Referer value from request header */
2072///   string<64> useragent;      /* User-Agent value from request header */
2073///   string<64> xff;            /* X-Forwarded-For value from request header */
2074///   string<32> authuser;       /* RFC 1413 identity of user*/
2075///   string<32> mime_type;      /* Mime-Type */
2076///   unsigned hyper req_bytes;  /* Content-Length of request */
2077///   unsigned hyper resp_bytes; /* Content-Length of response */
2078///   unsigned int uS;           /* duration of the operation (microseconds) */
2079///   int status;                /* HTTP status code */
2080/// }
2081/// ```
2082#[derive(Debug, Clone, PartialEq, Eq)]
2083#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2084pub struct HttpRequestDeprecated {
2085    /// HTTP method
2086    pub method: HttpMethod,
2087
2088    /// URI exactly as it came from the client
2089    pub uri: String,
2090
2091    /// Host value from request header
2092    pub host: String,
2093
2094    /// Referer value from request header
2095    pub referer: String,
2096
2097    /// User-Agent value from request header
2098    pub useragent: String,
2099
2100    /// X-Forwarded-For value from request header
2101    pub xff: String,
2102
2103    /// RFC 1413 identity of user
2104    pub authuser: String,
2105
2106    /// Mime-Type
2107    pub mime_type: String,
2108
2109    /// Content-Length of request
2110    pub req_bytes: u64,
2111
2112    /// Content-Length of response
2113    pub resp_bytes: u64,
2114
2115    /// Duration of the operation in microseconds
2116    pub duration_us: u32,
2117
2118    /// HTTP status code
2119    pub status: i32,
2120}
2121
2122/// Application Operation - Format (0,2202)
2123///
2124/// Sampled application operation information
2125///
2126/// # XDR Definition ([sFlow Application](https://sflow.org/sflow_application.txt))
2127///
2128/// ```text
2129/// /* Sampled Application Operation */
2130/// /* opaque = flow_data; enterprise = 0; format = 2202 */
2131///
2132/// struct app_operation {
2133///     context context;             /* attributes describing the operation */
2134///     utf8string<64> status_descr; /* additional text describing status */
2135///     unsigned hyper req_bytes;    /* size of request body (exclude headers) */
2136///     unsigned hyper resp_bytes;   /* size of response body (exclude headers) */
2137///     unsigned int uS;             /* duration of the operation (microseconds) */
2138///     status status;               /* status code */
2139/// }
2140/// ```
2141#[derive(Debug, Clone, PartialEq, Eq)]
2142#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2143pub struct AppOperation {
2144    /// Operation context
2145    pub context: AppContext,
2146
2147    /// Additional status description
2148    pub status_descr: String,
2149
2150    /// Size of request body in bytes (excluding headers)
2151    pub req_bytes: u64,
2152
2153    /// Size of response body in bytes (excluding headers)
2154    pub resp_bytes: u64,
2155
2156    /// Duration of the operation in microseconds
2157    pub duration_us: u32,
2158
2159    /// Operation status code
2160    pub status: AppStatus,
2161}
2162
2163/// Application Parent Context - Format (0,2203)
2164///
2165/// Parent context for sampled client operations
2166///
2167/// # XDR Definition ([sFlow Application](https://sflow.org/sflow_application.txt))
2168///
2169/// ```text
2170/// /* Optional parent context information for sampled client operation */
2171/// /* opaque = flow_data; enterprise = 0; format = 2203 */
2172///
2173/// struct app_parent_context {
2174///     context context;
2175/// }
2176/// ```
2177#[derive(Debug, Clone, PartialEq, Eq)]
2178#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2179pub struct AppParentContext {
2180    /// Parent operation context
2181    pub context: AppContext,
2182}
2183
2184/// Application Initiator - Format (0,2204)
2185///
2186/// Actor initiating the request (e.g., customer sending a payment)
2187///
2188/// # XDR Definition ([sFlow Application](https://sflow.org/sflow_application.txt))
2189///
2190/// ```text
2191/// /* Actor initiating the request */
2192/// /* e.g. customer sending a payment */
2193/// /* opaque = flow_data; enterprise = 0; format = 2204 */
2194///
2195/// struct app_initiator {
2196///    actor actor;
2197/// }
2198/// ```
2199///
2200/// **ERRATUM:** The specification is missing the `struct` keyword before the structure name,
2201/// which is inconsistent with XDR syntax conventions. The corrected version is shown above.
2202#[derive(Debug, Clone, PartialEq, Eq)]
2203#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2204pub struct AppInitiator {
2205    /// Business level identifier (e.g., customer id, vendor id)
2206    pub actor: String,
2207}
2208
2209/// Application Target - Format (0,2205)
2210///
2211/// Actor targeted by the request (e.g., recipient of payment)
2212///
2213/// # XDR Definition ([sFlow Application](https://sflow.org/sflow_application.txt))
2214///
2215/// ```text
2216/// /* Actor targetted by the request */
2217/// /* e.g. recipient of payment */
2218/// /* opaque = flow_data; enterprise = 0; format = 2205 */
2219///
2220/// struct app_target {
2221///    actor actor;
2222/// }
2223/// ```
2224///
2225/// **ERRATUM:** The specification is missing the `struct` keyword before the structure name,
2226/// which is inconsistent with XDR syntax conventions. The corrected version is shown above.
2227#[derive(Debug, Clone, PartialEq, Eq)]
2228#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2229pub struct AppTarget {
2230    /// Business level identifier (e.g., customer id, vendor id)
2231    pub actor: String,
2232}
2233
2234/// HTTP Request - Format (0,2206)
2235///
2236/// HTTP request information
2237///
2238/// # XDR Definition ([sFlow HTTP](https://sflow.org/sflow_http.txt))
2239///
2240/// ```text
2241/// /* HTTP protocol version number */
2242/// /* Encoded as major_number * 1000 + minor_number */
2243/// /* e.g. HTTP1.1 is encoded as 1001 */
2244/// typedef unsigned int version;
2245///
2246/// /* HTTP request */
2247/// /* opaque = flow_data; enterprise = 0; format = 2206 */
2248/// struct http_request {
2249///   http_method method;        /* method */
2250///   version protocol;          /* HTTP protocol version */
2251///   string<255> uri;           /* URI exactly as it came from the client */
2252///   string<64> host;           /* Host value from request header */
2253///   string<255> referer;       /* Referer value from request header */
2254///   string<128> useragent;     /* User-Agent value from request header */
2255///   string<64> xff;            /* X-Forwarded-For value
2256///                                 from request header */
2257///   string<32> authuser;       /* RFC 1413 identity of user*/
2258///   string<64> mime-type;      /* Mime-Type of response */
2259///   unsigned hyper req_bytes;  /* Content-Length of request */
2260///   unsigned hyper resp_bytes; /* Content-Length of response */
2261///   unsigned int uS;           /* duration of the operation
2262///                                 (in microseconds) */
2263///   int status;                /* HTTP status code */
2264/// }
2265/// ```
2266#[derive(Debug, Clone, PartialEq, Eq)]
2267#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2268pub struct HttpRequest {
2269    /// HTTP method
2270    pub method: HttpMethod,
2271
2272    /// HTTP protocol version (major * 1000 + minor, e.g., HTTP/1.1 = 1001)
2273    pub protocol: u32,
2274
2275    /// URI exactly as it came from the client
2276    pub uri: String,
2277
2278    /// Host value from request header
2279    pub host: String,
2280
2281    /// Referer value from request header
2282    pub referer: String,
2283
2284    /// User-Agent value from request header
2285    pub useragent: String,
2286
2287    /// X-Forwarded-For value from request header
2288    pub xff: String,
2289
2290    /// RFC 1413 identity of user
2291    pub authuser: String,
2292
2293    /// MIME type of response
2294    pub mime_type: String,
2295
2296    /// Content-Length of request
2297    pub req_bytes: u64,
2298
2299    /// Content-Length of response
2300    pub resp_bytes: u64,
2301
2302    /// Duration of the operation in microseconds
2303    pub duration_us: u32,
2304
2305    /// HTTP status code
2306    pub status: i32,
2307}
2308
2309/// Extended Proxy Request - Format (0,2207)
2310///
2311/// Rewritten URI for proxy requests
2312///
2313/// # XDR Definition ([sFlow HTTP](https://sflow.org/sflow_http.txt))
2314///
2315/// ```text
2316/// /* Rewritten URI */
2317/// /* Only include if host or uri are modified */
2318/// /* opaque = flow_data; enterprise = 0; format = 2207 */
2319/// struct extended_proxy_request {
2320///   string<255> uri;           /* URI in request to downstream server */
2321///   string<64>  host;          /* Host in request to downstream server */
2322/// }
2323/// ```
2324#[derive(Debug, Clone, PartialEq, Eq)]
2325#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2326pub struct ExtendedProxyRequest {
2327    /// URI in request to downstream server
2328    pub uri: String,
2329
2330    /// Host in request to downstream server
2331    pub host: String,
2332}
2333
2334/// Extended BST Egress Queue - Format (4413,1)
2335///
2336/// Selected egress queue for sampled packet from Broadcom switch ASIC
2337///
2338/// # XDR Definition ([sFlow Broadcom Buffers](https://sflow.org/bv-sflow.txt))
2339///
2340/// ```text
2341/// /* Selected egress queue */
2342/// /* opaque = flow_data; enterprise = 4413; format = 1 */
2343/// struct extended_bst_egress_queue {
2344///   unsigned int queue;  /* eqress queue number selected for sampled packet */
2345/// }
2346/// ```
2347#[derive(Debug, Clone, PartialEq, Eq)]
2348#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2349pub struct ExtendedBstEgressQueue {
2350    /// Egress queue number selected for sampled packet
2351    pub queue: u32,
2352}