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 = ib_lrh_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#[derive(Debug, Clone, PartialEq, Eq)]
564#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
565pub struct ExtendedInfiniBandLrh {
566    /// Source virtual lane
567    pub src_vl: u32,
568    /// Source service level
569    pub src_sl: u32,
570    /// Source destination-local-ID
571    pub src_dlid: u32,
572    /// Source source-local-ID
573    pub src_slid: u32,
574    /// Source link next header
575    pub src_lnh: u32,
576    /// Destination virtual lane
577    pub dst_vl: u32,
578    /// Destination service level
579    pub dst_sl: u32,
580    /// Destination destination-local-ID
581    pub dst_dlid: u32,
582    /// Destination source-local-ID
583    pub dst_slid: u32,
584    /// Destination link next header
585    pub dst_lnh: u32,
586}
587
588/// Extended InfiniBand GRH - Format (0,1032)
589///
590/// InfiniBand Global Routing Header information
591///
592/// # XDR Definition ([sFlow InfiniBand](https://sflow.org/draft_sflow_infiniband_2.txt))
593///
594/// ```text
595/// /* GID type  16 bytes long */
596/// typedef opaque gid[16];
597///
598/// /* Extended IB GRH Data
599///    - Global Routing Header definition from InfiniBand Architecture
600///      Specification */
601///
602/// /* opaque = ib_grh_data; enterprise = 0; format = 1032 */
603///
604/// struct extended_ib_grh {
605///    unsigned int flow_label; /* flow label          */
606///    unsigned int tc;         /* Traffic Class       */
607///    gid s_gid;               /* source GID          */
608///    gid d_gid;               /* destination GID     */
609///    unsigned int next_header /* next header type    */
610///    unsigned int length      /* payload length      */
611/// }
612/// ```
613#[derive(Debug, Clone, PartialEq, Eq)]
614#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
615pub struct ExtendedInfiniBandGrh {
616    /// Flow label
617    pub flow_label: u32,
618    /// Traffic class
619    pub tc: u32,
620    /// Source GID (16 bytes)
621    pub s_gid: [u8; 16],
622    /// Destination GID (16 bytes)
623    pub d_gid: [u8; 16],
624    /// Next header type
625    pub next_header: u32,
626    /// Payload length
627    pub length: u32,
628}
629
630/// Extended InfiniBand BTH - Format (0,1033)
631///
632/// InfiniBand Base Transport Header information
633///
634/// # XDR Definition ([sFlow InfiniBand](https://sflow.org/draft_sflow_infiniband_2.txt))
635///
636/// ```text
637/// /* Extended IB BTH Data
638///    - Base Transport Header definition from InfiniBand Architecture
639///      Specification */
640///
641/// /* opaque = ib_bth_data; enterprise = 0; format = 1033 */
642///
643/// struct extended_ib_bth {
644///    unsigned int pkey;   /* Partition key                */
645///    unsigned int dst_qp; /* Destination Queue Pair       */
646///    unsigned int opcode; /* IBA packet type              */
647/// }
648/// ```
649#[derive(Debug, Clone, PartialEq, Eq)]
650#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
651pub struct ExtendedInfiniBandBth {
652    /// Partition key
653    pub pkey: u32,
654    /// Destination Queue Pair
655    pub dst_qp: u32,
656    /// IBA packet type (opcode)
657    pub opcode: u32,
658}
659
660/// Extended MPLS Tunnel - Format (0,1008)
661///
662/// MPLS tunnel information
663///
664/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
665///
666/// ```text
667/// /* Extended MPLS Tunnel */
668/// /* opaque = flow_data; enterprise = 0; format = 1008 */
669///
670/// struct extended_mpls_tunnel {
671///     string tunnel_lsp_name<>; /* Tunnel name */
672///     unsigned int tunnel_id;   /* Tunnel ID */
673///     unsigned int tunnel_cos;  /* Tunnel COS value */
674/// }
675/// ```
676#[derive(Debug, Clone, PartialEq, Eq)]
677#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
678pub struct ExtendedMplsTunnel {
679    /// Tunnel LSP name
680    pub tunnel_lsp_name: String,
681
682    /// Tunnel ID
683    pub tunnel_id: u32,
684
685    /// Tunnel COS value
686    pub tunnel_cos: u32,
687}
688
689/// Extended MPLS VC - Format (0,1009)
690///
691/// MPLS Virtual Circuit information
692///
693/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
694///
695/// ```text
696/// /* Extended MPLS VC */
697/// /* opaque = flow_data; enterprise = 0; format = 1009 */
698///
699/// struct extended_mpls_vc {
700///     string vc_instance_name<>; /* VC instance name */
701///     unsigned int vll_vc_id;    /* VLL/VC instance ID */
702///     unsigned int vc_label_cos; /* VC Label COS value */
703/// }
704/// ```
705#[derive(Debug, Clone, PartialEq, Eq)]
706#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
707pub struct ExtendedMplsVc {
708    /// VC instance name
709    pub vc_instance_name: String,
710
711    /// VC ID
712    pub vll_vc_id: u32,
713
714    /// VC label
715    pub vc_label: u32,
716
717    /// VC COS
718    pub vc_cos: u32,
719}
720
721/// Extended MPLS FEC - Format (0,1010)
722///
723/// MPLS Forwarding Equivalence Class information
724///
725/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
726///
727/// ```text
728/// /* Extended MPLS FEC */
729/// /* opaque = flow_data; enterprise = 0; format = 1010 */
730///
731/// struct extended_mpls_FTN {
732///     string mplsFTNDescr<>;  /* FEC description */
733///     unsigned int mplsFTNMask; /* FEC mask */
734/// }
735/// ```
736#[derive(Debug, Clone, PartialEq, Eq)]
737#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
738pub struct ExtendedMplsFec {
739    /// FEC address prefix
740    pub fec_addr_prefix: crate::models::core::Address,
741
742    /// FEC prefix length
743    pub fec_prefix_len: u32,
744}
745
746/// Extended MPLS LVP FEC - Format (0,1011)
747///
748/// MPLS LDP FEC information
749///
750/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
751///
752/// ```text
753/// /* Extended MPLS LVP FEC */
754/// /* opaque = flow_data; enterprise = 0; format = 1011 */
755///
756/// struct extended_mpls_LDP_FEC {
757///     unsigned int mplsFecAddrPrefixLength; /* FEC address prefix length */
758/// }
759/// ```
760#[derive(Debug, Clone, PartialEq, Eq)]
761#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
762pub struct ExtendedMplsLvpFec {
763    /// FEC address prefix length
764    pub mpls_fec_addr_prefix_length: u32,
765}
766
767/// Extended VLAN Tunnel - Format (0,1012)
768///
769/// VLAN tunnel information for nested VLAN tags
770///
771/// # XDR Definition ([sFlow v5](https://sflow.org/sflow_version_5.txt))
772///
773/// ```text
774/// /* Extended VLAN tunnel information */
775/// /* opaque = flow_data; enterprise = 0; format = 1012 */
776///
777/// struct extended_vlantunnel {
778///     unsigned int stack<>; /* List of stripped 802.1Q TPID/TCI layers */
779/// }
780/// ```
781#[derive(Debug, Clone, PartialEq, Eq)]
782#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
783pub struct ExtendedVlanTunnel {
784    /// List of stripped 802.1Q TPID/TCI layers
785    pub stack: Vec<u32>,
786}
787
788/// Extended 802.11 Payload - Format (0,1013)
789///
790/// Unencrypted 802.11 payload data
791///
792/// # XDR Definition ([sFlow 802.11](https://sflow.org/sflow_80211.txt))
793///
794/// ```text
795/// /* Extended 80211 Payload */
796/// /* opaque = flow_data; enterprise = 0; format = 1013 */
797///
798/// struct extended_80211_payload {
799///     cipher_suite ciphersuite; /* encryption scheme used for this packet */
800///     opaque data<>;            /* unencrypted bytes from the payload */
801/// }
802/// ```
803#[derive(Debug, Clone, PartialEq, Eq)]
804#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
805pub struct Extended80211Payload {
806    /// Cipher suite (OUI + Suite Type) (spec: ciphersuite)
807    pub cipher_suite: u32,
808
809    /// Unencrypted payload data
810    pub data: Vec<u8>,
811}
812
813/// Extended 802.11 RX - Format (0,1014)
814///
815/// 802.11 receive information
816///
817/// # XDR Definition ([sFlow 802.11](https://sflow.org/sflow_80211.txt))
818///
819/// ```text
820/// /* Extended 802.11 RX */
821/// /* opaque = flow_data; enterprise = 0; format = 1014 */
822///
823/// struct extended_80211_rx {
824///     string ssid<32>;           /* SSID string */
825///     mac bssid;                 /* BSSID */
826///     ieee80211_version version; /* version */
827///     unsigned int channel;      /* channel number */
828///     unsigned hyper speed;      /* speed */
829///     unsigned int rsni;         /* received signal to noise ratio */
830///     unsigned int rcpi;         /* received channel power */
831///     duration_us packet_duration; /* time packet occupied RF medium */
832/// }
833/// ```
834#[derive(Debug, Clone, PartialEq, Eq)]
835#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
836pub struct Extended80211Rx {
837    /// SSID string (max 32 bytes)
838    pub ssid: String,
839
840    /// BSSID (MAC address)
841    pub bssid: crate::models::MacAddress,
842
843    /// IEEE 802.11 version (a=1, b=2, g=3, n=4)
844    pub version: u32,
845
846    /// Channel number
847    pub channel: u32,
848
849    /// Speed in bits per second
850    pub speed: u64,
851
852    /// Received signal to noise ratio (RSNI)
853    pub rsni: u32,
854
855    /// Received channel power indicator (RCPI)
856    pub rcpi: u32,
857
858    /// Packet duration in microseconds
859    pub packet_duration: u32,
860}
861
862/// Extended 802.11 TX - Format (0,1015)
863///
864/// 802.11 transmit information
865///
866/// # XDR Definition ([sFlow 802.11](https://sflow.org/sflow_80211.txt))
867///
868/// ```text
869/// /* Extended 802.11 TX */
870/// /* opaque = flow_data; enterprise = 0; format = 1015 */
871///
872/// struct extended_80211_tx {
873///     string ssid<32>;             /* SSID string */
874///     mac bssid;                   /* BSSID */
875///     ieee80211_version version;   /* version */
876///     unsigned int transmissions;  /* number of transmissions */
877///     duration_us packet_duration; /* time packet occupied RF medium */
878///     duration_us retrans_duration;/* time failed attempts occupied RF */
879///     unsigned int channel;        /* channel number */
880///     unsigned hyper speed;        /* speed */
881///     unsigned int power;          /* transmit power in mW */
882/// }
883/// ```
884#[derive(Debug, Clone, PartialEq, Eq)]
885#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
886pub struct Extended80211Tx {
887    /// SSID string (max 32 bytes)
888    pub ssid: String,
889
890    /// BSSID (MAC address)
891    pub bssid: crate::models::MacAddress,
892
893    /// IEEE 802.11 version (a=1, b=2, g=3, n=4)
894    pub version: u32,
895
896    /// Number of transmissions (0=unknown, 1=success on first attempt, n>1 = n-1 retransmissions)
897    pub transmissions: u32,
898
899    /// Packet duration in microseconds (successful transmission)
900    pub packet_duration: u32,
901
902    /// Retransmission duration in microseconds (failed attempts)
903    pub retrans_duration: u32,
904
905    /// Channel number
906    pub channel: u32,
907
908    /// Speed in bits per second
909    pub speed: u64,
910
911    /// Transmit power in milliwatts
912    pub power: u32,
913}
914
915/// PDU (Protocol Data Unit) in 802.11 aggregation
916///
917/// # XDR Definition ([sFlow 802.11](https://sflow.org/sflow_80211.txt))
918///
919/// ```text
920/// struct pdu {
921///     flow_record flow_records<>;
922/// }
923/// ```
924#[derive(Debug, Clone, PartialEq, Eq)]
925#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
926pub struct Pdu {
927    /// Flow records for this PDU
928    pub flow_records: Vec<crate::models::FlowRecord>,
929}
930
931/// Extended 802.11 Aggregation - Format (0,1016)
932///
933/// 802.11 frame aggregation information
934///
935/// # XDR Definition ([sFlow 802.11](https://sflow.org/sflow_80211.txt))
936///
937/// ```text
938/// /* Extended 802.11 Aggregation Data */
939/// /* opaque = flow_data; enterprise = 0; format = 1016 */
940///
941/// struct extended_80211_aggregation {
942///     pdu pdus<>; /* Array of PDUs in the aggregation */
943/// }
944/// ```
945#[derive(Debug, Clone, PartialEq, Eq)]
946#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
947pub struct Extended80211Aggregation {
948    /// Array of PDUs in the aggregation
949    pub pdus: Vec<Pdu>,
950}
951
952/// Extended OpenFlow v1 - Format (0,1017) - **DEPRECATED**
953///
954/// OpenFlow 1.0 forwarding information
955///
956/// **Note:** This format was defined in an early draft of the sFlow OpenFlow specification
957/// but was deprecated and removed from the final specification. It is included here for
958/// backward compatibility with legacy implementations.
959///
960/// # XDR Definition ([sFlow OpenFlow Draft](https://sflow.org/draft-sflow-openflow.txt))
961///
962/// ```text
963/// /* Extended OpenFlow 1.0 Data */
964/// /* opaque = flow_data; enterprise = 0; format = 1017 */
965///
966/// struct extended_openflow_v1 {
967///     unsigned hyper flow_cookie;  /* Flow cookie set by controller */
968///     wildcards flow_match;        /* Bit array of wildcarded fields */
969///     actions flow_actions;        /* Bit array of actions applied */
970/// }
971/// ```
972#[derive(Debug, Clone, PartialEq, Eq)]
973#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
974pub struct ExtendedOpenFlowV1 {
975    /// Flow cookie set by the OpenFlow controller
976    pub flow_cookie: u64,
977
978    /// Bit array describing the fields in the packet header that are used to form the flow key
979    /// See OpenFlow 1.0 ofp_match for the definition of wildcards
980    pub flow_match: u32,
981
982    /// Bit array describing fields that may have been altered by the flow action
983    /// The ofp_action_type enum is used to determine the bit positions
984    pub flow_actions: u32,
985}
986
987/// Extended L2 Tunnel Egress - Format (0,1021)
988///
989/// Layer 2 tunnel egress information - reports outer Ethernet headers
990/// that will be added on egress when encapsulating packets
991///
992/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
993///
994/// ```text
995/// /* opaque = flow_data; enterprise = 0; format = 1021 */
996/// struct extended_L2_tunnel_egress {
997///     sampled_ethernet header;
998/// }
999/// ```
1000#[derive(Debug, Clone, PartialEq, Eq)]
1001#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1002pub struct ExtendedL2TunnelEgress {
1003    /// Outer Ethernet header that will be added on egress
1004    pub header: SampledEthernet,
1005}
1006
1007/// Extended L2 Tunnel Ingress - Format (0,1022)
1008///
1009/// Layer 2 tunnel ingress information - reports outer Ethernet headers
1010/// that were present on ingress and removed during decapsulation
1011///
1012/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
1013///
1014/// ```text
1015/// /* opaque = flow_data; enterprise = 0; format = 1022 */
1016/// struct extended_L2_tunnel_ingress {
1017///     sampled_ethernet header;
1018/// }
1019/// ```
1020#[derive(Debug, Clone, PartialEq, Eq)]
1021#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1022pub struct ExtendedL2TunnelIngress {
1023    /// Outer Ethernet header that was present on ingress
1024    pub header: SampledEthernet,
1025}
1026
1027/// Extended IPv4 Tunnel Egress - Format (0,1023)
1028///
1029/// IPv4 tunnel egress information - reports outer IPv4 headers
1030/// that will be added on egress when encapsulating packets
1031///
1032/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
1033///
1034/// ```text
1035/// /* opaque = flow_data; enterprise = 0; format = 1023 */
1036/// struct extended_ipv4_tunnel_egress {
1037///     sampled_ipv4 header;
1038/// }
1039/// ```
1040#[derive(Debug, Clone, PartialEq, Eq)]
1041#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1042pub struct ExtendedIpv4TunnelEgress {
1043    /// Outer IPv4 header that will be added on egress
1044    pub header: SampledIpv4,
1045}
1046
1047/// Extended IPv4 Tunnel Ingress - Format (0,1024)
1048///
1049/// IPv4 tunnel ingress information - reports outer IPv4 headers
1050/// that were present on ingress and removed during decapsulation
1051///
1052/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
1053///
1054/// ```text
1055/// /* opaque = flow_data; enterprise = 0; format = 1024 */
1056/// struct extended_ipv4_tunnel_ingress {
1057///     sampled_ipv4 header;
1058/// }
1059/// ```
1060#[derive(Debug, Clone, PartialEq, Eq)]
1061#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1062pub struct ExtendedIpv4TunnelIngress {
1063    /// Outer IPv4 header that was present on ingress
1064    pub header: SampledIpv4,
1065}
1066
1067/// Extended IPv6 Tunnel Egress - Format (0,1025)
1068///
1069/// IPv6 tunnel egress information - reports outer IPv6 headers
1070/// that will be added on egress when encapsulating packets
1071///
1072/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
1073///
1074/// ```text
1075/// /* opaque = flow_data; enterprise = 0; format = 1025 */
1076/// struct extended_ipv6_tunnel_egress {
1077///     sampled_ipv6 header;
1078/// }
1079/// ```
1080#[derive(Debug, Clone, PartialEq, Eq)]
1081#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1082pub struct ExtendedIpv6TunnelEgress {
1083    /// Outer IPv6 header that will be added on egress
1084    pub header: SampledIpv6,
1085}
1086
1087/// Extended IPv6 Tunnel Ingress - Format (0,1026)
1088///
1089/// IPv6 tunnel ingress information - reports outer IPv6 headers
1090/// that were present on ingress and removed during decapsulation
1091///
1092/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
1093///
1094/// ```text
1095/// /* opaque = flow_data; enterprise = 0; format = 1026 */
1096/// struct extended_ipv6_tunnel_ingress {
1097///     sampled_ipv6 header;
1098/// }
1099/// ```
1100#[derive(Debug, Clone, PartialEq, Eq)]
1101#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1102pub struct ExtendedIpv6TunnelIngress {
1103    /// Outer IPv6 header that was present on ingress
1104    pub header: SampledIpv6,
1105}
1106
1107/// Extended Decapsulate Egress - Format (0,1027)
1108///
1109/// Indicates the end of a tunnel and points to the start of the inner header
1110/// Used when a packet is sampled before decapsulation on ingress
1111///
1112/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
1113///
1114/// ```text
1115/// /* opaque = flow_data; enterprise = 0; format = 1027 */
1116/// struct extended_decapsulate_egress {
1117///     unsigned int inner_header_offset;
1118/// }
1119/// ```
1120#[derive(Debug, Clone, PartialEq, Eq)]
1121#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1122pub struct ExtendedDecapsulateEgress {
1123    /// Offset in bytes to the inner header within the sampled packet header
1124    pub inner_header_offset: u32,
1125}
1126
1127/// Extended Decapsulate Ingress - Format (0,1028)
1128///
1129/// Indicates the start of a tunnel
1130/// Used when a packet is sampled after encapsulation on egress
1131///
1132/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
1133///
1134/// ```text
1135/// /* opaque = flow_data; enterprise = 0; format = 1028 */
1136/// struct extended_decapsulate_ingress {
1137///     unsigned int inner_header_offset;
1138/// }
1139/// ```
1140#[derive(Debug, Clone, PartialEq, Eq)]
1141#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1142pub struct ExtendedDecapsulateIngress {
1143    /// Offset in bytes to the inner header within the sampled packet header
1144    pub inner_header_offset: u32,
1145}
1146
1147/// Extended VNI Egress - Format (0,1029)
1148///
1149/// Virtual Network Identifier for egress traffic
1150/// The VNI may be explicitly included in the tunneling protocol or implicit
1151///
1152/// # XDR Definition ([sFlow Tunnels](https://sflow.org/sflow_tunnels.txt))
1153///
1154/// ```text
1155/// /* opaque_flow_data; enterprise = 0; format = 1029 */
1156/// struct extended_vni_egress {
1157///     unsigned int vni;
1158/// }
1159/// ```
1160#[derive(Debug, Clone, PartialEq, Eq)]
1161#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1162pub struct ExtendedVniEgress {
1163    /// Virtual Network Identifier
1164    pub vni: u32,
1165}
1166
1167/// Extended VNI Ingress - Format (0,1030)
1168///
1169/// Virtual Network Identifier for ingress traffic
1170/// The VNI may be explicitly included in the tunneling protocol or implicit
1171/// in the encapsulation (e.g., VXLAN uses UDP port 4789).
1172///
1173/// # XDR Definition ([sFlow Tunnel](https://sflow.org/sflow_tunnels.txt))
1174///
1175/// ```text
1176/// /* VNI ingress */
1177/// /* opaque = flow_data; enterprise = 0; format = 1030 */
1178///
1179/// struct extended_vni_ingress {
1180///     unsigned int vni;  /* VNI associated with ingress packet */
1181/// }
1182/// ```
1183#[derive(Debug, Clone, PartialEq, Eq)]
1184#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1185pub struct ExtendedVniIngress {
1186    /// Virtual Network Identifier
1187    pub vni: u32,
1188}
1189
1190/// Drop reason codes for discarded packets
1191///
1192/// # XDR Definition ([sFlow Drops](https://sflow.org/sflow_drops.txt))
1193///
1194/// ```text
1195/// /* The drop_reason enumeration may be expanded over time.
1196///    sFlow collectors must be prepared to receive discard_packet
1197///    structures with unrecognized drop_reason values.
1198///
1199///    This document expands on the discard reason codes 0-262 defined
1200///    in the sFlow Version 5 [1] interface typedef and this expanded list
1201///    should be regarded as an expansion of the reason codes in the
1202///    interface typdef and are valid anywhere the typedef is referenced.
1203///
1204///    Codes 263-288 are defined in Devlink Trap [2]. Drop reason / group
1205///    names from the Devlink Trap document are preserved where they define
1206///    new reason codes, or referenced as comments where they map to existing
1207///    codes.
1208///
1209///    Codes 289-303 are reasons that have yet to be upstreamed to Devlink Trap,
1210///    but the intent is that they will eventually be upstreamed and documented as
1211///    part of the Linux API [2], and so they have been reserved.
1212///
1213///    The authoritative list of drop reasons will be maintained
1214///    at sflow.org */
1215///
1216/// enum drop_reason {
1217///    net_unreachable      = 0,
1218///    host_unreachable     = 1,
1219///    protocol_unreachable = 2,
1220///    port_unreachable     = 3,
1221///    frag_needed          = 4,
1222///    src_route_failed     = 5,
1223///    dst_net_unknown      = 6, /* ipv4_lpm_miss, ipv6_lpm_miss */
1224///    dst_host_unknown     = 7,
1225///    src_host_isolated    = 8,
1226///    dst_net_prohibited   = 9, /* reject_route */
1227///    dst_host_prohibited  = 10,
1228///    dst_net_tos_unreachable  = 11,
1229///    dst_host_tos_unreacheable = 12,
1230///    comm_admin_prohibited = 13,
1231///    host_precedence_violation = 14,
1232///    precedence_cutoff    = 15,
1233///    unknown              = 256,
1234///    ttl_exceeded         = 257, /* ttl_value_is_too_small */
1235///    acl                  = 258, /* ingress_flow_action_drop,
1236///                                   egress_flow_action_drop
1237///                                   group acl_drops */
1238///    no_buffer_space      = 259, /* tail_drop */
1239///    red                  = 260, /* early_drop */
1240///    traffic_shaping      = 261,
1241///    pkt_too_big          = 262, /* mtu_value_is_too_small */
1242///    src_mac_is_multicast = 263,
1243///    vlan_tag_mismatch    = 264,
1244///    ingress_vlan_filter  = 265,
1245///    ingress_spanning_tree_filter = 266,
1246///    port_list_is_empty   = 267,
1247///    port_loopback_filter = 268,
1248///    blackhole_route      = 269,
1249///    non_ip               = 270,
1250///    uc_dip_over_mc_dmac  = 271,
1251///    dip_is_loopback_address = 272,
1252///    sip_is_mc            = 273,
1253///    sip_is_loopback_address = 274,
1254///    ip_header_corrupted  = 275,
1255///    ipv4_sip_is_limited_bc = 276,
1256///    ipv6_mc_dip_reserved_scope = 277,
1257///    ipv6_mc_dip_interface_local_scope = 278,
1258///    unresolved_neigh     = 279,
1259///    mc_reverse_path_forwarding = 280,
1260///    non_routable_packet  = 281,
1261///    decap_error          = 282,
1262///    overlay_smac_is_mc   = 283,
1263///    unknown_l2           = 284, /* group l2_drops */
1264///    unknown_l3           = 285, /* group l3_drops */
1265///    unknown_l3_exception = 286, /* group l3_exceptions */
1266///    unknown_buffer       = 287, /* group buffer_drops */
1267///    unknown_tunnel       = 288, /* group tunnel_drops */
1268///    unknown_l4           = 289,
1269///    sip_is_unspecified   = 290,
1270///    mlag_port_isolation  = 291,
1271///    blackhole_arp_neigh  = 292,
1272///    src_mac_is_dmac      = 293,
1273///    dmac_is_reserved     = 294,
1274///    sip_is_class_e       = 295,
1275///    mc_dmac_mismatch     = 296,
1276///    sip_is_dip           = 297,
1277///    dip_is_local_network = 298,
1278///    dip_is_link_local    = 299,
1279///    overlay_smac_is_dmac = 300,
1280///    egress_vlan_filter   = 301,
1281///    uc_reverse_path_forwarding = 302,
1282///    split_horizon        = 303
1283/// }
1284/// ```
1285#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1286#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1287#[repr(u32)]
1288pub enum DropReason {
1289    NetUnreachable = 0,
1290    HostUnreachable = 1,
1291    ProtocolUnreachable = 2,
1292    PortUnreachable = 3,
1293    FragNeeded = 4,
1294    SrcRouteFailed = 5,
1295    DstNetUnknown = 6,
1296    DstHostUnknown = 7,
1297    SrcHostIsolated = 8,
1298    DstNetProhibited = 9,
1299    DstHostProhibited = 10,
1300    DstNetTosUnreachable = 11,
1301    DstHostTosUnreachable = 12,
1302    CommAdminProhibited = 13,
1303    HostPrecedenceViolation = 14,
1304    PrecedenceCutoff = 15,
1305    Unknown = 256,
1306    TtlExceeded = 257,
1307    Acl = 258,
1308    NoBufferSpace = 259,
1309    Red = 260,
1310    TrafficShaping = 261,
1311    PktTooBig = 262,
1312    SrcMacIsMulticast = 263,
1313    VlanTagMismatch = 264,
1314    IngressVlanFilter = 265,
1315    IngressSpanningTreeFilter = 266,
1316    PortListIsEmpty = 267,
1317    PortLoopbackFilter = 268,
1318    BlackholeRoute = 269,
1319    NonIp = 270,
1320    UcDipOverMcDmac = 271,
1321    DipIsLoopbackAddress = 272,
1322    SipIsMc = 273,
1323    SipIsLoopbackAddress = 274,
1324    IpHeaderCorrupted = 275,
1325    Ipv4SipIsLimitedBc = 276,
1326    Ipv6McDipReservedScope = 277,
1327    Ipv6McDipInterfaceLocalScope = 278,
1328    UnresolvedNeigh = 279,
1329    McReversePathForwarding = 280,
1330    NonRoutablePacket = 281,
1331    DecapError = 282,
1332    OverlaySmacIsMc = 283,
1333    UnknownL2 = 284,
1334    UnknownL3 = 285,
1335    UnknownL3Exception = 286,
1336    UnknownBuffer = 287,
1337    UnknownTunnel = 288,
1338    UnknownL4 = 289,
1339    SipIsUnspecified = 290,
1340    MlagPortIsolation = 291,
1341    BlackholeArpNeigh = 292,
1342    SrcMacIsDmac = 293,
1343    DmacIsReserved = 294,
1344    SipIsClassE = 295,
1345    McDmacMismatch = 296,
1346    SipIsDip = 297,
1347    DipIsLocalNetwork = 298,
1348    DipIsLinkLocal = 299,
1349    OverlaySmacIsDmac = 300,
1350    EgressVlanFilter = 301,
1351    UcReversePathForwarding = 302,
1352    SplitHorizon = 303,
1353}
1354
1355impl DropReason {
1356    /// Convert from u32 value to DropReason enum
1357    ///
1358    /// This is a mechanical mapping of u32 values to enum variants
1359    /// defined in the sFlow specification. The function is tested
1360    /// with representative samples rather than exhaustively.
1361    pub fn from_u32(value: u32) -> Option<Self> {
1362        match value {
1363            0 => Some(DropReason::NetUnreachable),
1364            1 => Some(DropReason::HostUnreachable),
1365            2 => Some(DropReason::ProtocolUnreachable),
1366            3 => Some(DropReason::PortUnreachable),
1367            4 => Some(DropReason::FragNeeded),
1368            5 => Some(DropReason::SrcRouteFailed),
1369            6 => Some(DropReason::DstNetUnknown),
1370            7 => Some(DropReason::DstHostUnknown),
1371            8 => Some(DropReason::SrcHostIsolated),
1372            9 => Some(DropReason::DstNetProhibited),
1373            10 => Some(DropReason::DstHostProhibited),
1374            11 => Some(DropReason::DstNetTosUnreachable),
1375            12 => Some(DropReason::DstHostTosUnreachable),
1376            13 => Some(DropReason::CommAdminProhibited),
1377            14 => Some(DropReason::HostPrecedenceViolation),
1378            15 => Some(DropReason::PrecedenceCutoff),
1379            256 => Some(DropReason::Unknown),
1380            257 => Some(DropReason::TtlExceeded),
1381            258 => Some(DropReason::Acl),
1382            259 => Some(DropReason::NoBufferSpace),
1383            260 => Some(DropReason::Red),
1384            261 => Some(DropReason::TrafficShaping),
1385            262 => Some(DropReason::PktTooBig),
1386            263 => Some(DropReason::SrcMacIsMulticast),
1387            264 => Some(DropReason::VlanTagMismatch),
1388            265 => Some(DropReason::IngressVlanFilter),
1389            266 => Some(DropReason::IngressSpanningTreeFilter),
1390            267 => Some(DropReason::PortListIsEmpty),
1391            268 => Some(DropReason::PortLoopbackFilter),
1392            269 => Some(DropReason::BlackholeRoute),
1393            270 => Some(DropReason::NonIp),
1394            271 => Some(DropReason::UcDipOverMcDmac),
1395            272 => Some(DropReason::DipIsLoopbackAddress),
1396            273 => Some(DropReason::SipIsMc),
1397            274 => Some(DropReason::SipIsLoopbackAddress),
1398            275 => Some(DropReason::IpHeaderCorrupted),
1399            276 => Some(DropReason::Ipv4SipIsLimitedBc),
1400            277 => Some(DropReason::Ipv6McDipReservedScope),
1401            278 => Some(DropReason::Ipv6McDipInterfaceLocalScope),
1402            279 => Some(DropReason::UnresolvedNeigh),
1403            280 => Some(DropReason::McReversePathForwarding),
1404            281 => Some(DropReason::NonRoutablePacket),
1405            282 => Some(DropReason::DecapError),
1406            283 => Some(DropReason::OverlaySmacIsMc),
1407            284 => Some(DropReason::UnknownL2),
1408            285 => Some(DropReason::UnknownL3),
1409            286 => Some(DropReason::UnknownL3Exception),
1410            287 => Some(DropReason::UnknownBuffer),
1411            288 => Some(DropReason::UnknownTunnel),
1412            289 => Some(DropReason::UnknownL4),
1413            290 => Some(DropReason::SipIsUnspecified),
1414            291 => Some(DropReason::MlagPortIsolation),
1415            292 => Some(DropReason::BlackholeArpNeigh),
1416            293 => Some(DropReason::SrcMacIsDmac),
1417            294 => Some(DropReason::DmacIsReserved),
1418            295 => Some(DropReason::SipIsClassE),
1419            296 => Some(DropReason::McDmacMismatch),
1420            297 => Some(DropReason::SipIsDip),
1421            298 => Some(DropReason::DipIsLocalNetwork),
1422            299 => Some(DropReason::DipIsLinkLocal),
1423            300 => Some(DropReason::OverlaySmacIsDmac),
1424            301 => Some(DropReason::EgressVlanFilter),
1425            302 => Some(DropReason::UcReversePathForwarding),
1426            303 => Some(DropReason::SplitHorizon),
1427            _ => None,
1428        }
1429    }
1430}
1431
1432/// Extended Egress Queue - Format (0,1036)
1433///
1434/// Selected egress queue for the sampled packet
1435///
1436/// # XDR Definition ([sFlow Drops](https://sflow.org/sflow_drops.txt))
1437///
1438/// ```text
1439/// /* Selected egress queue */
1440/// /* Output port number must be provided in enclosing structure */
1441/// /* opaque = flow_data; enterprise = 0; format = 1036 */
1442/// struct extended_egress_queue {
1443///   unsigned int queue;  /* eqress queue number selected for sampled packet */
1444/// }
1445/// ```
1446#[derive(Debug, Clone, PartialEq, Eq)]
1447#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1448pub struct ExtendedEgressQueue {
1449    /// Egress queue number selected for sampled packet
1450    pub queue: u32,
1451}
1452
1453/// Extended ACL - Format (0,1037)
1454///
1455/// ACL information about the rule that matched this packet
1456///
1457/// # XDR Definition ([sFlow Drops](https://sflow.org/sflow_drops.txt))
1458///
1459/// ```text
1460/// /* ACL information */
1461/// /* Information about ACL rule that matched this packet
1462/// /* opaque = flow_data; enterprise = 0; format = 1037 */
1463/// struct extended_acl {
1464///   unsigned int number; /* access list number */
1465///   string name<>; /* access list name */
1466///   unsigned int direction; /* unknown = 0, ingress = 1, egress = 2 */
1467/// }
1468/// ```
1469#[derive(Debug, Clone, PartialEq, Eq)]
1470#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1471pub struct ExtendedAcl {
1472    /// Access list number
1473    pub number: u32,
1474
1475    /// Access list name
1476    pub name: String,
1477
1478    /// Direction: unknown = 0, ingress = 1, egress = 2
1479    pub direction: u32,
1480}
1481
1482/// Extended Function - Format (0,1038)
1483///
1484/// Name of the function in software network stack that discarded the packet
1485///
1486/// # XDR Definition ([sFlow Drops](https://sflow.org/sflow_drops.txt))
1487///
1488/// ```text
1489/// /* Software function */
1490/// /* Name of the function in software network stack that discarded the packet */
1491/// /* opaque = flow_data; enterprise = 0; format = 1038 */
1492/// struct extended_function {
1493///   string symbol<>;
1494/// }
1495/// ```
1496#[derive(Debug, Clone, PartialEq, Eq)]
1497#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1498pub struct ExtendedFunction {
1499    /// Function symbol name
1500    pub symbol: String,
1501}
1502
1503/// Extended Transit - Format (0,1039)
1504///
1505/// Delay for sampled packet traversing switch
1506///
1507/// # XDR Definition ([sFlow Transit](https://sflow.org/sflow_transit.txt))
1508///
1509/// ```text
1510/// /* Delay for sampled packet traversing switch */
1511/// /* opaque = flow_data; enterprise = 0; format = 1039 */
1512/// struct extended_transit {
1513///   unsigned int delay; /* transit delay in nanoseconds
1514///                          0xffffffff indicates value >= 0xffffffff */
1515/// }
1516/// ```
1517#[derive(Debug, Clone, PartialEq, Eq)]
1518#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1519pub struct ExtendedTransit {
1520    /// Transit delay in nanoseconds (0xffffffff indicates value >= 0xffffffff)
1521    pub delay: u32,
1522}
1523
1524/// Extended Queue - Format (0,1040)
1525///
1526/// Queue depth for sampled packet traversing switch
1527///
1528/// # XDR Definition ([sFlow Transit](https://sflow.org/sflow_transit.txt))
1529///
1530/// ```text
1531/// /* Queue depth for sampled packet traversing switch */
1532/// /* extended_egress_queue structure must be included */
1533/// /* opaque = flow_data; enterprise = 0; format = 1040 */
1534/// struct extended_queue {
1535///   unsigned int depth;   /* queue depth in bytes */
1536/// }
1537/// ```
1538#[derive(Debug, Clone, PartialEq, Eq)]
1539#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1540pub struct ExtendedQueue {
1541    /// Queue depth in bytes
1542    pub depth: u32,
1543}
1544
1545/// Extended Socket IPv4 - Format (0,2100)
1546///
1547/// IPv4 socket information for application transactions
1548///
1549/// # XDR Definition ([sFlow Host](https://sflow.org/sflow_host.txt))
1550///
1551/// ```text
1552/// /* IPv4 Socket */
1553/// /* opaque = flow_data; enterprise = 0; format = 2100 */
1554///
1555/// struct extended_socket_ipv4 {
1556///     unsigned int protocol;     /* IP Protocol type (e.g., TCP = 6, UDP = 17) */
1557///     ip_v4 local_ip;            /* local IP address */
1558///     ip_v4 remote_ip;           /* remote IP address */
1559///     unsigned int local_port;   /* TCP/UDP local port number or equivalent */
1560///     unsigned int remote_port;  /* TCP/UDP remote port number or equivalent */
1561/// }
1562/// ```
1563#[derive(Debug, Clone, PartialEq, Eq)]
1564#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1565pub struct ExtendedSocketIpv4 {
1566    /// IP Protocol type (e.g., TCP = 6, UDP = 17)
1567    pub protocol: u32,
1568
1569    /// Local IP address
1570    pub local_ip: std::net::Ipv4Addr,
1571
1572    /// Remote IP address
1573    pub remote_ip: std::net::Ipv4Addr,
1574
1575    /// TCP/UDP local port number
1576    pub local_port: u32,
1577
1578    /// TCP/UDP remote port number
1579    pub remote_port: u32,
1580}
1581
1582/// Extended Socket IPv6 - Format (0,2101)
1583///
1584/// IPv6 socket information for application transactions
1585///
1586/// # XDR Definition ([sFlow Host](https://sflow.org/sflow_host.txt))
1587///
1588/// ```text
1589/// /* IPv6 Socket */
1590/// /* opaque = flow_data; enterprise = 0; format = 2101 */
1591///
1592/// struct extended_socket_ipv6 {
1593///     unsigned int protocol;     /* IP Protocol type (e.g., TCP = 6, UDP = 17) */
1594///     ip_v6 local_ip;            /* local IP address */
1595///     ip_v6 remote_ip;           /* remote IP address */
1596///     unsigned int local_port;   /* TCP/UDP local port number or equivalent */
1597///     unsigned int remote_port;  /* TCP/UDP remote port number or equivalent */
1598/// }
1599/// ```
1600#[derive(Debug, Clone, PartialEq, Eq)]
1601#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1602pub struct ExtendedSocketIpv6 {
1603    /// IP Protocol type (e.g., TCP = 6, UDP = 17)
1604    pub protocol: u32,
1605
1606    /// Local IP address
1607    pub local_ip: std::net::Ipv6Addr,
1608
1609    /// Remote IP address
1610    pub remote_ip: std::net::Ipv6Addr,
1611
1612    /// TCP/UDP local port number
1613    pub local_port: u32,
1614
1615    /// TCP/UDP remote port number
1616    pub remote_port: u32,
1617}
1618
1619/// HTTP method enumeration
1620///
1621/// # XDR Definition ([sFlow HTTP](https://sflow.org/sflow_http.txt))
1622///
1623/// ```text
1624/// /* The http_method enumeration may be expanded over time.
1625///    Applications receiving sFlow must be prepared to receive
1626///    http_request structures with unknown http_method values */
1627///
1628/// enum http_method {
1629///   OTHER    = 0;
1630///   OPTIONS  = 1;
1631///   GET      = 2;
1632///   HEAD     = 3;
1633///   POST     = 4;
1634///   PUT      = 5;
1635///   DELETE   = 6;
1636///   TRACE    = 7;
1637///   CONNECT  = 8;
1638/// }
1639/// ```
1640#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1641#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1642#[repr(u32)]
1643pub enum HttpMethod {
1644    Other = 0,
1645    Options = 1,
1646    Get = 2,
1647    Head = 3,
1648    Post = 4,
1649    Put = 5,
1650    Delete = 6,
1651    Trace = 7,
1652    Connect = 8,
1653}
1654
1655impl From<u32> for HttpMethod {
1656    fn from(value: u32) -> Self {
1657        match value {
1658            1 => HttpMethod::Options,
1659            2 => HttpMethod::Get,
1660            3 => HttpMethod::Head,
1661            4 => HttpMethod::Post,
1662            5 => HttpMethod::Put,
1663            6 => HttpMethod::Delete,
1664            7 => HttpMethod::Trace,
1665            8 => HttpMethod::Connect,
1666            _ => HttpMethod::Other,
1667        }
1668    }
1669}
1670
1671impl std::fmt::Display for HttpMethod {
1672    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1673        match self {
1674            HttpMethod::Other => write!(f, "OTHER"),
1675            HttpMethod::Options => write!(f, "OPTIONS"),
1676            HttpMethod::Get => write!(f, "GET"),
1677            HttpMethod::Head => write!(f, "HEAD"),
1678            HttpMethod::Post => write!(f, "POST"),
1679            HttpMethod::Put => write!(f, "PUT"),
1680            HttpMethod::Delete => write!(f, "DELETE"),
1681            HttpMethod::Trace => write!(f, "TRACE"),
1682            HttpMethod::Connect => write!(f, "CONNECT"),
1683        }
1684    }
1685}
1686
1687/// Extended Proxy Socket IPv4 - Format (0,2102)
1688///
1689/// IPv4 socket information for proxy connections
1690///
1691/// # XDR Definition ([sFlow HTTP](https://sflow.org/sflow_http.txt))
1692///
1693/// ```text
1694/// /* Proxy socket IPv4 */
1695/// /* opaque = flow_data; enterprise=0; format=2102 */
1696/// struct extended_proxy_socket_ipv4 {
1697///   extended_socket_ipv4 socket;
1698/// }
1699/// ```
1700#[derive(Debug, Clone, PartialEq, Eq)]
1701#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1702pub struct ExtendedProxySocketIpv4 {
1703    /// Socket information
1704    pub socket: ExtendedSocketIpv4,
1705}
1706
1707/// Extended Proxy Socket IPv6 - Format (0,2103)
1708///
1709/// IPv6 socket information for proxy connections
1710///
1711/// # XDR Definition ([sFlow HTTP](https://sflow.org/sflow_http.txt))
1712///
1713/// ```text
1714/// /* Proxy socket IPv6 */
1715/// /* opaque = flow_data; enterprise=0; format=2103 */
1716/// struct extended_proxy_socket_ipv6 {
1717///   extended_socket_ipv6 socket;
1718/// }
1719/// ```
1720#[derive(Debug, Clone, PartialEq, Eq)]
1721#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1722pub struct ExtendedProxySocketIpv6 {
1723    /// Socket information
1724    pub socket: ExtendedSocketIpv6,
1725}
1726
1727/// Application operation context
1728///
1729/// # XDR Definition ([sFlow Application](https://sflow.org/sflow_application.txt))
1730///
1731/// ```text
1732/// struct context {
1733///     application application;
1734///     operation operation;
1735///     attributes attributes;
1736/// }
1737/// ```
1738#[derive(Debug, Clone, PartialEq, Eq)]
1739#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1740pub struct AppContext {
1741    /// Application name (e.g., "payment", "mail.smtp", "db.oracle")
1742    pub application: String,
1743
1744    /// Operation name (e.g., "get.customer.name", "upload.photo")
1745    pub operation: String,
1746
1747    /// Operation attributes as name=value pairs (e.g., "cc=visa&loc=mobile")
1748    pub attributes: String,
1749}
1750
1751/// Application operation status
1752///
1753/// # XDR Definition ([sFlow Application](https://sflow.org/sflow_application.txt))
1754#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1755#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1756#[repr(u32)]
1757pub enum AppStatus {
1758    Success = 0,
1759    Other = 1,
1760    Timeout = 2,
1761    InternalError = 3,
1762    BadRequest = 4,
1763    Forbidden = 5,
1764    TooLarge = 6,
1765    NotImplemented = 7,
1766    NotFound = 8,
1767    Unavailable = 9,
1768    Unauthorized = 10,
1769}
1770
1771impl From<u32> for AppStatus {
1772    fn from(value: u32) -> Self {
1773        match value {
1774            0 => AppStatus::Success,
1775            1 => AppStatus::Other,
1776            2 => AppStatus::Timeout,
1777            3 => AppStatus::InternalError,
1778            4 => AppStatus::BadRequest,
1779            5 => AppStatus::Forbidden,
1780            6 => AppStatus::TooLarge,
1781            7 => AppStatus::NotImplemented,
1782            8 => AppStatus::NotFound,
1783            9 => AppStatus::Unavailable,
1784            10 => AppStatus::Unauthorized,
1785            _ => AppStatus::Other,
1786        }
1787    }
1788}
1789
1790/// Memcache Protocol
1791///
1792/// # XDR Definition ([sFlow Memcache](https://sflow.org/sflow_memcache.txt))
1793///
1794/// ```text
1795/// enum memcache_protocol {
1796///   OTHER  = 0;
1797///   ASCII  = 1;
1798///   BINARY = 2;
1799/// }
1800/// ```
1801#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1802#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1803#[repr(u32)]
1804pub enum MemcacheProtocol {
1805    Other = 0,
1806    Ascii = 1,
1807    Binary = 2,
1808}
1809
1810impl MemcacheProtocol {
1811    /// Convert from u32 value to MemcacheProtocol enum
1812    pub fn from_u32(value: u32) -> Self {
1813        match value {
1814            1 => MemcacheProtocol::Ascii,
1815            2 => MemcacheProtocol::Binary,
1816            _ => MemcacheProtocol::Other,
1817        }
1818    }
1819}
1820
1821/// Memcache Command
1822///
1823/// # XDR Definition ([sFlow Memcache](https://sflow.org/sflow_memcache.txt))
1824///
1825/// ```text
1826/// enum memcache_cmd {
1827///   OTHER    = 0;
1828///   SET      = 1;
1829///   ADD      = 2;
1830///   REPLACE  = 3;
1831///   APPEND   = 4;
1832///   PREPEND  = 5;
1833///   CAS      = 6;
1834///   GET      = 7;
1835///   GETS     = 8;
1836///   INCR     = 9;
1837///   DECR     = 10;
1838///   DELETE   = 11;
1839///   STATS    = 12;
1840///   FLUSH    = 13;
1841///   VERSION  = 14;
1842///   QUIT     = 15;
1843///   TOUCH    = 16;
1844/// }
1845/// ```
1846#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1847#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1848#[repr(u32)]
1849pub enum MemcacheCommand {
1850    Other = 0,
1851    Set = 1,
1852    Add = 2,
1853    Replace = 3,
1854    Append = 4,
1855    Prepend = 5,
1856    Cas = 6,
1857    Get = 7,
1858    Gets = 8,
1859    Incr = 9,
1860    Decr = 10,
1861    Delete = 11,
1862    Stats = 12,
1863    Flush = 13,
1864    Version = 14,
1865    Quit = 15,
1866    Touch = 16,
1867}
1868
1869impl MemcacheCommand {
1870    /// Convert from u32 value to MemcacheCommand enum
1871    pub fn from_u32(value: u32) -> Self {
1872        match value {
1873            1 => MemcacheCommand::Set,
1874            2 => MemcacheCommand::Add,
1875            3 => MemcacheCommand::Replace,
1876            4 => MemcacheCommand::Append,
1877            5 => MemcacheCommand::Prepend,
1878            6 => MemcacheCommand::Cas,
1879            7 => MemcacheCommand::Get,
1880            8 => MemcacheCommand::Gets,
1881            9 => MemcacheCommand::Incr,
1882            10 => MemcacheCommand::Decr,
1883            11 => MemcacheCommand::Delete,
1884            12 => MemcacheCommand::Stats,
1885            13 => MemcacheCommand::Flush,
1886            14 => MemcacheCommand::Version,
1887            15 => MemcacheCommand::Quit,
1888            16 => MemcacheCommand::Touch,
1889            _ => MemcacheCommand::Other,
1890        }
1891    }
1892}
1893
1894/// Memcache Status
1895///
1896/// # XDR Definition ([sFlow Memcache](https://sflow.org/sflow_memcache.txt))
1897///
1898/// ```text
1899/// enum memcache_status {
1900///   UNKNOWN      = 0;
1901///   OK           = 1;
1902///   ERROR        = 2;
1903///   CLIENT_ERROR = 3;
1904///   SERVER_ERROR = 4;
1905///   STORED       = 5;
1906///   NOT_STORED   = 6;
1907///   EXISTS       = 7;
1908///   NOT_FOUND    = 8;
1909///   DELETED      = 9;
1910/// }
1911/// ```
1912#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1913#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1914#[repr(u32)]
1915pub enum MemcacheStatus {
1916    Unknown = 0,
1917    Ok = 1,
1918    Error = 2,
1919    ClientError = 3,
1920    ServerError = 4,
1921    Stored = 5,
1922    NotStored = 6,
1923    Exists = 7,
1924    NotFound = 8,
1925    Deleted = 9,
1926}
1927
1928impl MemcacheStatus {
1929    /// Convert from u32 value to MemcacheStatus enum
1930    pub fn from_u32(value: u32) -> Self {
1931        match value {
1932            1 => MemcacheStatus::Ok,
1933            2 => MemcacheStatus::Error,
1934            3 => MemcacheStatus::ClientError,
1935            4 => MemcacheStatus::ServerError,
1936            5 => MemcacheStatus::Stored,
1937            6 => MemcacheStatus::NotStored,
1938            7 => MemcacheStatus::Exists,
1939            8 => MemcacheStatus::NotFound,
1940            9 => MemcacheStatus::Deleted,
1941            _ => MemcacheStatus::Unknown,
1942        }
1943    }
1944}
1945
1946/// Memcache Operation - Format (0,2200)
1947///
1948/// Sampled memcache operation
1949///
1950/// # XDR Definition ([sFlow Memcache](https://sflow.org/sflow_memcache.txt))
1951///
1952/// ```text
1953/// /* Memcache operation */
1954/// /* opaque = flow_data; enterprise = 0; format = 2200 */
1955///
1956/// struct memcache_operation {
1957///   memcache_protocol protocol;  /* protocol */
1958///   memcache_cmd cmd;            /* command */
1959///   string<255> key;             /* key used to store/retrieve data */
1960///   unsigned int nkeys;          /* number of keys
1961///                                   (including sampled key) */
1962///   unsigned int value_bytes;    /* size of the value (in bytes) */
1963///   unsigned int uS;             /* duration of the operation
1964///                                   (in microseconds) */
1965///   memcache_status status;      /* status of command */
1966/// }
1967/// ```
1968#[derive(Debug, Clone, PartialEq, Eq)]
1969#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1970pub struct MemcacheOperation {
1971    /// Protocol (ASCII or Binary)
1972    pub protocol: MemcacheProtocol,
1973
1974    /// Command type
1975    pub cmd: MemcacheCommand,
1976
1977    /// Key used to store/retrieve data
1978    pub key: String,
1979
1980    /// Number of keys (including sampled key)
1981    pub nkeys: u32,
1982
1983    /// Size of the value in bytes
1984    pub value_bytes: u32,
1985
1986    /// Duration of the operation in microseconds
1987    pub duration_us: u32,
1988
1989    /// Status of the command
1990    pub status: MemcacheStatus,
1991}
1992
1993/// Application Operation - Format (0,2202)
1994///
1995/// Sampled application operation information
1996///
1997/// # XDR Definition ([sFlow Application](https://sflow.org/sflow_application.txt))
1998///
1999/// ```text
2000/// /* Sampled Application Operation */
2001/// /* opaque = flow_data; enterprise = 0; format = 2202 */
2002///
2003/// struct app_operation {
2004///     context context;             /* attributes describing the operation */
2005///     utf8string<64> status_descr; /* additional text describing status */
2006///     unsigned hyper req_bytes;    /* size of request body (exclude headers) */
2007///     unsigned hyper resp_bytes;   /* size of response body (exclude headers) */
2008///     unsigned int uS;             /* duration of the operation (microseconds) */
2009///     status status;               /* status code */
2010/// }
2011/// ```
2012#[derive(Debug, Clone, PartialEq, Eq)]
2013#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2014pub struct AppOperation {
2015    /// Operation context
2016    pub context: AppContext,
2017
2018    /// Additional status description
2019    pub status_descr: String,
2020
2021    /// Size of request body in bytes (excluding headers)
2022    pub req_bytes: u64,
2023
2024    /// Size of response body in bytes (excluding headers)
2025    pub resp_bytes: u64,
2026
2027    /// Duration of the operation in microseconds
2028    pub duration_us: u32,
2029
2030    /// Operation status code
2031    pub status: AppStatus,
2032}
2033
2034/// Application Parent Context - Format (0,2203)
2035///
2036/// Parent context for sampled client operations
2037///
2038/// # XDR Definition ([sFlow Application](https://sflow.org/sflow_application.txt))
2039///
2040/// ```text
2041/// /* Optional parent context information for sampled client operation */
2042/// /* opaque = flow_data; enterprise = 0; format = 2203 */
2043///
2044/// struct app_parent_context {
2045///     context context;
2046/// }
2047/// ```
2048#[derive(Debug, Clone, PartialEq, Eq)]
2049#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2050pub struct AppParentContext {
2051    /// Parent operation context
2052    pub context: AppContext,
2053}
2054
2055/// Application Initiator - Format (0,2204)
2056///
2057/// Actor initiating the request (e.g., customer sending a payment)
2058///
2059/// # XDR Definition ([sFlow Application](https://sflow.org/sflow_application.txt))
2060///
2061/// ```text
2062/// /* Actor initiating the request */
2063/// /* e.g. customer sending a payment */
2064/// /* opaque = flow_data; enterprise = 0; format = 2204 */
2065///
2066/// app_initiator {
2067///    actor actor;
2068/// }
2069/// ```
2070#[derive(Debug, Clone, PartialEq, Eq)]
2071#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2072pub struct AppInitiator {
2073    /// Business level identifier (e.g., customer id, vendor id)
2074    pub actor: String,
2075}
2076
2077/// Application Target - Format (0,2205)
2078///
2079/// Actor targeted by the request (e.g., recipient of payment)
2080///
2081/// # XDR Definition ([sFlow Application](https://sflow.org/sflow_application.txt))
2082///
2083/// ```text
2084/// /* Actor targetted by the request */
2085/// /* e.g. recipient of payment */
2086/// /* opaque = flow_data; enterprise = 0; format = 2205 */
2087///
2088/// app_target {
2089///    actor actor;
2090/// }
2091/// ```
2092#[derive(Debug, Clone, PartialEq, Eq)]
2093#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2094pub struct AppTarget {
2095    /// Business level identifier (e.g., customer id, vendor id)
2096    pub actor: String,
2097}
2098
2099/// HTTP Request - Format (0,2206)
2100///
2101/// HTTP request information
2102///
2103/// # XDR Definition ([sFlow HTTP](https://sflow.org/sflow_http.txt))
2104///
2105/// ```text
2106/// /* HTTP protocol version number */
2107/// /* Encoded as major_number * 1000 + minor_number */
2108/// /* e.g. HTTP1.1 is encoded as 1001 */
2109/// typedef unsigned int version;
2110///
2111/// /* HTTP request */
2112/// /* opaque = flow_data; enterprise = 0; format = 2206 */
2113/// struct http_request {
2114///   http_method method;        /* method */
2115///   version protocol;          /* HTTP protocol version */
2116///   string<255> uri;           /* URI exactly as it came from the client */
2117///   string<64> host;           /* Host value from request header */
2118///   string<255> referer;       /* Referer value from request header */
2119///   string<128> useragent;     /* User-Agent value from request header */
2120///   string<64> xff;            /* X-Forwarded-For value
2121///                                 from request header */
2122///   string<32> authuser;       /* RFC 1413 identity of user*/
2123///   string<64> mime-type;      /* Mime-Type of response */
2124///   unsigned hyper req_bytes;  /* Content-Length of request */
2125///   unsigned hyper resp_bytes; /* Content-Length of response */
2126///   unsigned int uS;           /* duration of the operation
2127///                                 (in microseconds) */
2128///   int status;                /* HTTP status code */
2129/// }
2130/// ```
2131#[derive(Debug, Clone, PartialEq, Eq)]
2132#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2133pub struct HttpRequest {
2134    /// HTTP method
2135    pub method: HttpMethod,
2136
2137    /// HTTP protocol version (major * 1000 + minor, e.g., HTTP/1.1 = 1001)
2138    pub protocol: u32,
2139
2140    /// URI exactly as it came from the client
2141    pub uri: String,
2142
2143    /// Host value from request header
2144    pub host: String,
2145
2146    /// Referer value from request header
2147    pub referer: String,
2148
2149    /// User-Agent value from request header
2150    pub useragent: String,
2151
2152    /// X-Forwarded-For value from request header
2153    pub xff: String,
2154
2155    /// RFC 1413 identity of user
2156    pub authuser: String,
2157
2158    /// MIME type of response
2159    pub mime_type: String,
2160
2161    /// Content-Length of request
2162    pub req_bytes: u64,
2163
2164    /// Content-Length of response
2165    pub resp_bytes: u64,
2166
2167    /// Duration of the operation in microseconds
2168    pub duration_us: u32,
2169
2170    /// HTTP status code
2171    pub status: i32,
2172}
2173
2174/// Extended Proxy Request - Format (0,2207)
2175///
2176/// Rewritten URI for proxy requests
2177///
2178/// # XDR Definition ([sFlow HTTP](https://sflow.org/sflow_http.txt))
2179///
2180/// ```text
2181/// /* Rewritten URI */
2182/// /* Only include if host or uri are modified */
2183/// /* opaque = flow_data; enterprise = 0; format = 2207 */
2184/// struct extended_proxy_request {
2185///   string<255> uri;           /* URI in request to downstream server */
2186///   string<64>  host;          /* Host in request to downstream server */
2187/// }
2188/// ```
2189#[derive(Debug, Clone, PartialEq, Eq)]
2190#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2191pub struct ExtendedProxyRequest {
2192    /// URI in request to downstream server
2193    pub uri: String,
2194
2195    /// Host in request to downstream server
2196    pub host: String,
2197}
2198
2199/// Extended BST Egress Queue - Format (4413,1)
2200///
2201/// Selected egress queue for sampled packet from Broadcom switch ASIC
2202///
2203/// # XDR Definition ([sFlow Broadcom Buffers](https://sflow.org/bv-sflow.txt))
2204///
2205/// ```text
2206/// /* Selected egress queue */
2207/// /* opaque = flow_data; enterprise = 4413; format = 1 */
2208/// struct extended_bst_egress_queue {
2209///   unsigned int queue;  /* eqress queue number selected for sampled packet */
2210/// }
2211/// ```
2212#[derive(Debug, Clone, PartialEq, Eq)]
2213#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2214pub struct ExtendedBstEgressQueue {
2215    /// Egress queue number selected for sampled packet
2216    pub queue: u32,
2217}