1 /* Copyright (c) 2002-2011 InMon Corp. Licensed under the terms of the InMon sFlow licence: */
2 /* http://www.inmon.com/technology/sflowlicense.txt */
3 
4 /////////////////////////////////////////////////////////////////////////////////
5 /////////////////////// sFlow Sampling Packet Data Types ////////////////////////
6 /////////////////////////////////////////////////////////////////////////////////
7 
8 #ifndef SFLOW_H
9 #define SFLOW_H 1
10 
11 #if defined(__cplusplus)
12 extern "C" {
13 #endif
14 
15 typedef struct {
16     uint32_t addr;
17 } SFLIPv4;
18 
19 typedef struct {
20     u_char addr[16];
21 } SFLIPv6;
22 
23 typedef union _SFLAddress_value {
24     SFLIPv4 ip_v4;
25     SFLIPv6 ip_v6;
26 } SFLAddress_value;
27 
28 enum SFLAddress_type {
29   SFLADDRESSTYPE_UNDEFINED = 0,
30   SFLADDRESSTYPE_IP_V4 = 1,
31   SFLADDRESSTYPE_IP_V6 = 2
32 };
33 
34 typedef struct _SFLAddress {
35   uint32_t type;           /* enum SFLAddress_type */
36   SFLAddress_value address;
37 } SFLAddress;
38 
39 /* Packet header data */
40 
41 #define SFL_DEFAULT_HEADER_SIZE 128
42 #define SFL_DEFAULT_COLLECTOR_PORT 6343
43 #define SFL_DEFAULT_SAMPLING_RATE 400
44 
45 /* The header protocol describes the format of the sampled header */
46 enum SFLHeader_protocol {
47   SFLHEADER_ETHERNET_ISO8023     = 1,
48   SFLHEADER_ISO88024_TOKENBUS    = 2,
49   SFLHEADER_ISO88025_TOKENRING   = 3,
50   SFLHEADER_FDDI                 = 4,
51   SFLHEADER_FRAME_RELAY          = 5,
52   SFLHEADER_X25                  = 6,
53   SFLHEADER_PPP                  = 7,
54   SFLHEADER_SMDS                 = 8,
55   SFLHEADER_AAL5                 = 9,
56   SFLHEADER_AAL5_IP              = 10, /* e.g. Cisco AAL5 mux */
57   SFLHEADER_IPv4                 = 11,
58   SFLHEADER_IPv6                 = 12,
59   SFLHEADER_MPLS                 = 13,
60   SFLHEADER_POS                  = 14,
61   SFLHEADER_IEEE80211MAC         = 15,
62   SFLHEADER_IEEE80211_AMPDU      = 16,
63   SFLHEADER_IEEE80211_AMSDU_SUBFRAME = 17
64 };
65 
66 /* raw sampled header */
67 
68 typedef struct _SFLSampled_header {
69   uint32_t header_protocol;            /* (enum SFLHeader_protocol) */
70   uint32_t frame_length;               /* Original length of packet before sampling */
71   uint32_t stripped;                   /* header/trailer bytes stripped by sender */
72   uint32_t header_length;              /* length of sampled header bytes to follow */
73   uint8_t *header_bytes;               /* Header bytes */
74 } SFLSampled_header;
75 
76 /* decoded ethernet header */
77 
78 typedef struct _SFLSampled_ethernet {
79   uint32_t eth_len;       /* The length of the MAC packet excluding
80                              lower layer encapsulations */
81   uint8_t src_mac[8];    /* 6 bytes + 2 pad */
82   uint8_t dst_mac[8];
83   uint32_t eth_type;
84 } SFLSampled_ethernet;
85 
86 /* decoded IP version 4 header */
87 
88 typedef struct _SFLSampled_ipv4 {
89   uint32_t length;      /* The length of the IP packet
90 			    excluding lower layer encapsulations */
91   uint32_t protocol;    /* IP Protocol type (for example, TCP = 6, UDP = 17) */
92   SFLIPv4 src_ip; /* Source IP Address */
93   SFLIPv4 dst_ip; /* Destination IP Address */
94   uint32_t src_port;    /* TCP/UDP source port number or equivalent */
95   uint32_t dst_port;    /* TCP/UDP destination port number or equivalent */
96   uint32_t tcp_flags;   /* TCP flags */
97   uint32_t tos;         /* IP type of service */
98 } SFLSampled_ipv4;
99 
100 /* decoded IP version 6 data */
101 
102 typedef struct _SFLSampled_ipv6 {
103   uint32_t length;       /* The length of the IP packet
104 			     excluding lower layer encapsulations */
105   uint32_t protocol;     /* IP Protocol type (for example, TCP = 6, UDP = 17) */
106   SFLIPv6 src_ip; /* Source IP Address */
107   SFLIPv6 dst_ip; /* Destination IP Address */
108   uint32_t src_port;     /* TCP/UDP source port number or equivalent */
109   uint32_t dst_port;     /* TCP/UDP destination port number or equivalent */
110   uint32_t tcp_flags;    /* TCP flags */
111   uint32_t priority;     /* IP priority */
112 } SFLSampled_ipv6;
113 
114 /* Extended data types */
115 
116 /* Extended switch data */
117 
118 typedef struct _SFLExtended_switch {
119   uint32_t src_vlan;       /* The 802.1Q VLAN id of incomming frame */
120   uint32_t src_priority;   /* The 802.1p priority */
121   uint32_t dst_vlan;       /* The 802.1Q VLAN id of outgoing frame */
122   uint32_t dst_priority;   /* The 802.1p priority */
123 } SFLExtended_switch;
124 
125 /* Extended router data */
126 
127 typedef struct _SFLExtended_router {
128   SFLAddress nexthop;               /* IP address of next hop router */
129   uint32_t src_mask;               /* Source address prefix mask bits */
130   uint32_t dst_mask;               /* Destination address prefix mask bits */
131 } SFLExtended_router;
132 
133 /* Extended gateway data */
134 enum SFLExtended_as_path_segment_type {
135   SFLEXTENDED_AS_SET = 1,      /* Unordered set of ASs */
136   SFLEXTENDED_AS_SEQUENCE = 2  /* Ordered sequence of ASs */
137 };
138 
139 typedef struct _SFLExtended_as_path_segment {
140   uint32_t type;   /* enum SFLExtended_as_path_segment_type */
141   uint32_t length; /* number of AS numbers in set/sequence */
142   union {
143     uint32_t *set;
144     uint32_t *seq;
145   } as;
146 } SFLExtended_as_path_segment;
147 
148 typedef struct _SFLExtended_gateway {
149   SFLAddress nexthop;                       /* Address of the border router that should
150                                                be used for the destination network */
151   uint32_t as;                             /* AS number for this gateway */
152   uint32_t src_as;                         /* AS number of source (origin) */
153   uint32_t src_peer_as;                    /* AS number of source peer */
154   uint32_t dst_as_path_segments;           /* number of segments in path */
155   SFLExtended_as_path_segment *dst_as_path; /* list of seqs or sets */
156   uint32_t communities_length;             /* number of communities */
157   uint32_t *communities;                   /* set of communities */
158   uint32_t localpref;                      /* LocalPref associated with this route */
159 } SFLExtended_gateway;
160 
161 typedef struct _SFLString {
162   uint32_t len;
163   char *str;
164 } SFLString;
165 
166 /* Extended user data */
167 
168 typedef struct _SFLExtended_user {
169   uint32_t src_charset;  /* MIBEnum value of character set used to encode a string - See RFC 2978
170 			     Where possible UTF-8 encoding (MIBEnum=106) should be used. A value
171 			     of zero indicates an unknown encoding. */
172   SFLString src_user;
173   uint32_t dst_charset;
174   SFLString dst_user;
175 } SFLExtended_user;
176 
177 /* Extended URL data */
178 
179 enum SFLExtended_url_direction {
180   SFLEXTENDED_URL_SRC = 1, /* URL is associated with source address */
181   SFLEXTENDED_URL_DST = 2  /* URL is associated with destination address */
182 };
183 
184 typedef struct _SFLExtended_url {
185   uint32_t direction;   /* enum SFLExtended_url_direction */
186   SFLString url;         /* URL associated with the packet flow.
187 			    Must be URL encoded */
188   SFLString host;        /* The host field from the HTTP header */
189 } SFLExtended_url;
190 
191 /* Extended MPLS data */
192 
193 typedef struct _SFLLabelStack {
194   uint32_t depth;
195   uint32_t *stack; /* first entry is top of stack - see RFC 3032 for encoding */
196 } SFLLabelStack;
197 
198 typedef struct _SFLExtended_mpls {
199   SFLAddress nextHop;        /* Address of the next hop */
200   SFLLabelStack in_stack;
201   SFLLabelStack out_stack;
202 } SFLExtended_mpls;
203 
204   /* Extended NAT data
205      Packet header records report addresses as seen at the sFlowDataSource.
206      The extended_nat structure reports on translated source and/or destination
207      addesses for this packet. If an address was not translated it should
208      be equal to that reported for the header. */
209 
210 typedef struct _SFLExtended_nat {
211   SFLAddress src;    /* Source address */
212   SFLAddress dst;    /* Destination address */
213 } SFLExtended_nat;
214 
215   /* additional Extended MPLS stucts */
216 
217 typedef struct _SFLExtended_mpls_tunnel {
218    SFLString tunnel_lsp_name;  /* Tunnel name */
219    uint32_t tunnel_id;        /* Tunnel ID */
220    uint32_t tunnel_cos;       /* Tunnel COS value */
221 } SFLExtended_mpls_tunnel;
222 
223 typedef struct _SFLExtended_mpls_vc {
224    SFLString vc_instance_name; /* VC instance name */
225    uint32_t vll_vc_id;        /* VLL/VC instance ID */
226    uint32_t vc_label_cos;     /* VC Label COS value */
227 } SFLExtended_mpls_vc;
228 
229 /* Extended MPLS FEC
230     - Definitions from MPLS-FTN-STD-MIB mplsFTNTable */
231 
232 typedef struct _SFLExtended_mpls_FTN {
233    SFLString mplsFTNDescr;
234    uint32_t mplsFTNMask;
235 } SFLExtended_mpls_FTN;
236 
237 /* Extended MPLS LVP FEC
238     - Definition from MPLS-LDP-STD-MIB mplsFecTable
239     Note: mplsFecAddrType, mplsFecAddr information available
240           from packet header */
241 
242 typedef struct _SFLExtended_mpls_LDP_FEC {
243    uint32_t mplsFecAddrPrefixLength;
244 } SFLExtended_mpls_LDP_FEC;
245 
246 /* Extended VLAN tunnel information
247    Record outer VLAN encapsulations that have
248    been stripped. extended_vlantunnel information
249    should only be reported if all the following conditions are satisfied:
250      1. The packet has nested vlan tags, AND
251      2. The reporting device is VLAN aware, AND
252      3. One or more VLAN tags have been stripped, either
253         because they represent proprietary encapsulations, or
254         because switch hardware automatically strips the outer VLAN
255         encapsulation.
256    Reporting extended_vlantunnel information is not a substitute for
257    reporting extended_switch information. extended_switch data must
258    always be reported to describe the ingress/egress VLAN information
259    for the packet. The extended_vlantunnel information only applies to
260    nested VLAN tags, and then only when one or more tags has been
261    stripped. */
262 
263 typedef SFLLabelStack SFLVlanStack;
264 typedef struct _SFLExtended_vlan_tunnel {
265   SFLVlanStack stack;  /* List of stripped 802.1Q TPID/TCI layers. Each
266 			  TPID,TCI pair is represented as a single 32 bit
267 			  integer. Layers listed from outermost to
268 			  innermost. */
269 } SFLExtended_vlan_tunnel;
270 
271   ////////////////// IEEE 802.11 Extension structs ////////////////////
272 
273 /* The 4-byte cipher_suite identifier follows the format of the cipher suite
274    selector value from the 802.11i (TKIP/CCMP amendment to 802.11i)
275    The most significant three bytes contain the OUI and the least significant
276    byte contains the Suite Type.
277 
278    The currently assigned values are:
279 
280    OUI        |Suite type  |Meaning
281    ----------------------------------------------------
282    00-0F-AC   | 0          | Use group cipher suite
283    00-0F-AC   | 1          | WEP-40
284    00-0F-AC   | 2          | TKIP
285    00-0F-AC   | 3          | Reserved
286    00-0F-AC   | 4          | CCMP
287    00-0F-AC   | 5          | WEP-104
288    00-0F-AC   | 6-255      | Reserved
289    Vendor OUI | Other      | Vendor specific
290    Other      | Any        | Reserved
291    ----------------------------------------------------
292 */
293 
294 typedef uint32_t SFLCipherSuite;
295 
296 /* Extended wifi Payload
297    Used to provide unencrypted version of 802.11 MAC data. If the
298    MAC data is not encrypted then the agent must not include an
299    extended_wifi_payload structure.
300    If 802.11 MAC data is encrypted then the sampled_header structure
301    should only contain the MAC header (since encrypted data cannot
302    be decoded by the sFlow receiver). If the sFlow agent has access to
303    the unencrypted payload, it should add an extended_wifi_payload
304    structure containing the unencrypted data bytes from the sampled
305    packet header, starting at the beginning of the 802.2 LLC and not
306    including any trailing encryption footers.  */
307 /* opaque = flow_data; enterprise = 0; format = 1013 */
308 
309 typedef struct _SFLExtended_wifi_payload {
310   SFLCipherSuite cipherSuite;
311   SFLSampled_header header;
312 } SFLExtended_wifi_payload;
313 
314 typedef enum  {
315   IEEE80211_A=1,
316   IEEE80211_B=2,
317   IEEE80211_G=3,
318   IEEE80211_N=4,
319 } SFL_IEEE80211_version;
320 
321 /* opaque = flow_data; enterprise = 0; format = 1014 */
322 
323 #define SFL_MAX_SSID_LEN 256
324 
325 typedef struct _SFLExtended_wifi_rx {
326   uint32_t ssid_len;
327   char *ssid;
328   char bssid[6];    /* BSSID */
329   SFL_IEEE80211_version version;  /* version */
330   uint32_t channel;       /* channel number */
331   uint64_t speed;
332   uint32_t rsni;          /* received signal to noise ratio, see dot11FrameRprtRSNI */
333   uint32_t rcpi;          /* received channel power, see dot11FrameRprtLastRCPI */
334   uint32_t packet_duration_us; /* amount of time that the successfully received pkt occupied RF medium.*/
335 } SFLExtended_wifi_rx;
336 
337 /* opaque = flow_data; enterprise = 0; format = 1015 */
338 
339 typedef struct _SFLExtended_wifi_tx {
340   uint32_t ssid_len;
341   char *ssid;              /* SSID string */
342   char  bssid[6];             /* BSSID */
343   SFL_IEEE80211_version version;    /* version */
344   uint32_t transmissions;   /* number of transmissions for sampled
345 				packet.
346 				0 = unkown
347 				1 = packet was successfully transmitted
348 				on first attempt
349 				n > 1 = n - 1 retransmissions */
350   uint32_t packet_duration_us;  /* amount of time that the successfully
351                                     transmitted packet occupied the
352                                     RF medium */
353   uint32_t retrans_duration_us; /* amount of time that failed transmission
354                                     attempts occupied the RF medium */
355   uint32_t channel;         /* channel number */
356   uint64_t speed;
357   uint32_t power_mw;           /* transmit power in mW. */
358 } SFLExtended_wifi_tx;
359 
360 /* Extended 802.11 Aggregation Data */
361 /* A flow_sample of an aggregated frame would consist of a packet
362    header for the whole frame + any other extended structures that
363    apply (e.g. 80211_tx/rx etc.) + an extended_wifi_aggregation
364    structure which would contain an array of pdu structures (one
365    for each PDU in the aggregate). A pdu is simply an array of
366    flow records, in the simplest case a packet header for each PDU,
367    but extended structures could be included as well. */
368 
369 /* opaque = flow_data; enterprise = 0; format = 1016 */
370 
371 struct _SFLFlow_Pdu; // forward decl
372 
373 typedef struct _SFLExtended_aggregation {
374   uint32_t num_pdus;
375   struct _SFFlow_Pdu *pdus;
376 } SFLExtended_aggregation;
377 
378 /* Extended socket information,
379    Must be filled in for all application transactions associated with a network socket
380    Omit if transaction associated with non-network IPC  */
381 
382 /* IPv4 Socket */
383 /* opaque = flow_data; enterprise = 0; format = 2100 */
384 typedef struct _SFLExtended_socket_ipv4 {
385    uint32_t protocol;     /* IP Protocol (e.g. TCP = 6, UDP = 17) */
386    SFLIPv4 local_ip;      /* local IP address */
387    SFLIPv4 remote_ip;     /* remote IP address */
388    uint32_t local_port;   /* TCP/UDP local port number or equivalent */
389    uint32_t remote_port;  /* TCP/UDP remote port number of equivalent */
390 } SFLExtended_socket_ipv4;
391 
392 #define XDRSIZ_SFLEXTENDED_SOCKET4 20
393 
394 /* IPv6 Socket */
395 /* opaque = flow_data; enterprise = 0; format = 2101 */
396 typedef struct _SFLExtended_socket_ipv6 {
397   uint32_t protocol;     /* IP Protocol (e.g. TCP = 6, UDP = 17) */
398   SFLIPv6 local_ip;      /* local IP address */
399   SFLIPv6 remote_ip;     /* remote IP address */
400   uint32_t local_port;   /* TCP/UDP local port number or equivalent */
401   uint32_t remote_port;  /* TCP/UDP remote port number of equivalent */
402 } SFLExtended_socket_ipv6;
403 
404 #define XDRSIZ_SFLEXTENDED_SOCKET6 44
405 
406 typedef enum  {
407   MEMCACHE_PROT_OTHER   = 0,
408   MEMCACHE_PROT_ASCII   = 1,
409   MEMCACHE_PROT_BINARY  = 2,
410 } SFLMemcache_prot;
411 
412 typedef enum  {
413   MEMCACHE_CMD_OTHER    = 0,
414   MEMCACHE_CMD_SET      = 1,
415   MEMCACHE_CMD_ADD      = 2,
416   MEMCACHE_CMD_REPLACE  = 3,
417   MEMCACHE_CMD_APPEND   = 4,
418   MEMCACHE_CMD_PREPEND  = 5,
419   MEMCACHE_CMD_CAS      = 6,
420   MEMCACHE_CMD_GET      = 7,
421   MEMCACHE_CMD_GETS     = 8,
422 } SFLMemcache_cmd;
423 
424 enum SFLMemcache_operation_status {
425   MEMCACHE_OP_UNKNOWN      = 0,
426   MEMCACHE_OP_OK           = 1,
427   MEMCACHE_OP_ERROR        = 2,
428   MEMCACHE_OP_CLIENT_ERROR = 3,
429   MEMCACHE_OP_SERVER_ERROR = 4,
430   MEMCACHE_OP_STORED       = 5,
431   MEMCACHE_OP_NOT_STORED   = 6,
432   MEMCACHE_OP_EXISTS       = 7,
433   MEMCACHE_OP_NOT_FOUND    = 8,
434   MEMCACHE_OP_DELETED      = 9,
435 };
436 
437 #define SFL_MAX_MEMCACHE_KEY 255
438 
439 typedef struct _SFLSampled_memcache {
440   uint32_t protocol;    /* SFLMemcache_prot */
441   uint32_t command;     /* SFLMemcache_cmd */
442   SFLString key;        /* up to 255 chars */
443   uint32_t nkeys;
444   uint32_t value_bytes;
445   uint32_t duration_uS;
446   uint32_t status;      /* SFLMemcache_operation_status */
447 } SFLSampled_memcache;
448 
449 typedef enum {
450   SFHTTP_OTHER    = 0,
451   SFHTTP_OPTIONS  = 1,
452   SFHTTP_GET      = 2,
453   SFHTTP_HEAD     = 3,
454   SFHTTP_POST     = 4,
455   SFHTTP_PUT      = 5,
456   SFHTTP_DELETE   = 6,
457   SFHTTP_TRACE    = 7,
458   SFHTTP_CONNECT  = 8,
459 } SFLHTTP_method;
460 
461 #define SFL_MAX_HTTP_URI 255
462 #define SFL_MAX_HTTP_HOST 32
463 #define SFL_MAX_HTTP_REFERRER 255
464 #define SFL_MAX_HTTP_USERAGENT 64
465 #define SFL_MAX_HTTP_AUTHUSER 32
466 #define SFL_MAX_HTTP_MIMETYPE 32
467 
468 typedef struct _SFLSampled_http {
469   SFLHTTP_method method;
470   uint32_t protocol;      /* 1.1=1001 */
471   SFLString uri;           /* URI exactly as it came from the client (up to 255 bytes) */
472   SFLString host;          /* Host value from request header (<= 32 bytes) */
473   SFLString referrer;      /* Referer value from request header (<=255 bytes) */
474   SFLString useragent;     /* User-Agent value from request header (<= 64 bytes)*/
475   SFLString authuser;      /* RFC 1413 identity of user (<=32 bytes)*/
476   SFLString mimetype;      /* Mime-Type (<=32 bytes) */
477   uint64_t bytes;          /* Content-Length of document transferred */
478   uint32_t uS;             /* duration of the operation (microseconds) */
479   uint32_t status;         /* HTTP status code */
480 } SFLSampled_http;
481 
482 
483 typedef enum {
484   SFLOW_CAL_TRANSACTION_OTHER=0,
485   SFLOW_CAL_TRANSACTION_START,
486   SFLOW_CAL_TRANSACTION_END,
487   SFLOW_CAL_TRANSACTION_ATOMIC,
488   SFLOW_CAL_TRANSACTION_EVENT,
489   SFLOW_CAL_NUM_TRANSACTION_TYPES
490 }  EnumSFLCALTransaction;
491 
492 //static const char *CALTransactionNames[] = {"OTHER", "START", "END","ATOMIC", "EVENT" };
493 
494 typedef struct _SFLSampled_CAL {
495   EnumSFLCALTransaction type;
496   uint32_t depth;
497   SFLString pool;
498   SFLString transaction;
499   SFLString operation;
500   SFLString status;
501   uint64_t duration_uS;
502 } SFLSampled_CAL;
503 
504 #define SFLCAL_MAX_POOL_LEN 32
505 #define SFLCAL_MAX_TRANSACTION_LEN 128
506 #define SFLCAL_MAX_OPERATION_LEN 128
507 #define SFLCAL_MAX_STATUS_LEN 64
508 
509 enum SFLFlow_type_tag {
510   /* enterprise = 0, format = ... */
511   SFLFLOW_HEADER    = 1,      /* Packet headers are sampled */
512   SFLFLOW_ETHERNET  = 2,      /* MAC layer information */
513   SFLFLOW_IPV4      = 3,      /* IP version 4 data */
514   SFLFLOW_IPV6      = 4,      /* IP version 6 data */
515   SFLFLOW_EX_SWITCH    = 1001,      /* Extended switch information */
516   SFLFLOW_EX_ROUTER    = 1002,      /* Extended router information */
517   SFLFLOW_EX_GATEWAY   = 1003,      /* Extended gateway router information */
518   SFLFLOW_EX_USER      = 1004,      /* Extended TACAS/RADIUS user information */
519   SFLFLOW_EX_URL       = 1005,      /* Extended URL information */
520   SFLFLOW_EX_MPLS      = 1006,      /* Extended MPLS information */
521   SFLFLOW_EX_NAT       = 1007,      /* Extended NAT information */
522   SFLFLOW_EX_MPLS_TUNNEL  = 1008,   /* additional MPLS information */
523   SFLFLOW_EX_MPLS_VC      = 1009,
524   SFLFLOW_EX_MPLS_FTN     = 1010,
525   SFLFLOW_EX_MPLS_LDP_FEC = 1011,
526   SFLFLOW_EX_VLAN_TUNNEL  = 1012,   /* VLAN stack */
527   SFLFLOW_EX_80211_PAYLOAD = 1013,
528   SFLFLOW_EX_80211_RX      = 1014,
529   SFLFLOW_EX_80211_TX      = 1015,
530   SFLFLOW_EX_AGGREGATION   = 1016,
531   SFLFLOW_EX_SOCKET4       = 2100,
532   SFLFLOW_EX_SOCKET6       = 2101,
533   SFLFLOW_MEMCACHE         = 2200,
534   SFLFLOW_HTTP             = 2201,
535   SFLFLOW_CAL             = (4300 << 12) + 5,  /* 4300 is InMon enterprise no. */
536 };
537 
538 typedef union _SFLFlow_type {
539   SFLSampled_header header;
540   SFLSampled_ethernet ethernet;
541   SFLSampled_ipv4 ipv4;
542   SFLSampled_ipv6 ipv6;
543   SFLSampled_memcache memcache;
544   SFLSampled_http http;
545   SFLSampled_CAL cal;
546   SFLExtended_switch sw;
547   SFLExtended_router router;
548   SFLExtended_gateway gateway;
549   SFLExtended_user user;
550   SFLExtended_url url;
551   SFLExtended_mpls mpls;
552   SFLExtended_nat nat;
553   SFLExtended_mpls_tunnel mpls_tunnel;
554   SFLExtended_mpls_vc mpls_vc;
555   SFLExtended_mpls_FTN mpls_ftn;
556   SFLExtended_mpls_LDP_FEC mpls_ldp_fec;
557   SFLExtended_vlan_tunnel vlan_tunnel;
558   SFLExtended_wifi_payload wifi_payload;
559   SFLExtended_wifi_rx wifi_rx;
560   SFLExtended_wifi_tx wifi_tx;
561   SFLExtended_aggregation aggregation;
562   SFLExtended_socket_ipv4 socket4;
563   SFLExtended_socket_ipv6 socket6;
564 } SFLFlow_type;
565 
566 typedef struct _SFLFlow_sample_element {
567   struct _SFLFlow_sample_element *nxt;
568   uint32_t tag;  /* SFLFlow_type_tag */
569   uint32_t length;
570   SFLFlow_type flowType;
571 } SFLFlow_sample_element;
572 
573 enum SFL_sample_tag {
574   SFLFLOW_SAMPLE = 1,              /* enterprise = 0 : format = 1 */
575   SFLCOUNTERS_SAMPLE = 2,          /* enterprise = 0 : format = 2 */
576   SFLFLOW_SAMPLE_EXPANDED = 3,     /* enterprise = 0 : format = 3 */
577   SFLCOUNTERS_SAMPLE_EXPANDED = 4  /* enterprise = 0 : format = 4 */
578 };
579 
580 typedef struct _SFLFlow_Pdu {
581   struct _SFLFlow_Pdu *nxt;
582   uint32_t num_elements;
583   SFLFlow_sample_element *elements;
584 } SFLFlow_Pdu;
585 
586 
587 /* Format of a single flow sample */
588 
589 typedef struct _SFLFlow_sample {
590   /* uint32_t tag;    */         /* SFL_sample_tag -- enterprise = 0 : format = 1 */
591   /* uint32_t length; */
592   uint32_t sequence_number;      /* Incremented with each flow sample
593 				     generated */
594   uint32_t source_id;            /* fsSourceId */
595   uint32_t sampling_rate;        /* fsPacketSamplingRate */
596   uint32_t sample_pool;          /* Total number of packets that could have been
597 				     sampled (i.e. packets skipped by sampling
598 				     process + total number of samples) */
599   uint32_t drops;                /* Number of times a packet was dropped due to
600 				     lack of resources */
601   uint32_t input;                /* SNMP ifIndex of input interface.
602 				     0 if interface is not known. */
603   uint32_t output;               /* SNMP ifIndex of output interface,
604 				     0 if interface is not known.
605 				     Set most significant bit to indicate
606 				     multiple destination interfaces
607 				     (i.e. in case of broadcast or multicast)
608 				     and set lower order bits to indicate
609 				     number of destination interfaces.
610 				     Examples:
611 				     0x00000002  indicates ifIndex = 2
612 				     0x00000000  ifIndex unknown.
613 				     0x80000007  indicates a packet sent
614 				     to 7 interfaces.
615 				     0x80000000  indicates a packet sent to
616 				     an unknown number of
617 				     interfaces greater than 1.*/
618   uint32_t num_elements;
619   SFLFlow_sample_element *elements;
620 } SFLFlow_sample;
621 
622   /* same thing, but the expanded version (for full 32-bit ifIndex numbers) */
623 
624 typedef struct _SFLFlow_sample_expanded {
625   /* uint32_t tag;    */         /* SFL_sample_tag -- enterprise = 0 : format = 1 */
626   /* uint32_t length; */
627   uint32_t sequence_number;      /* Incremented with each flow sample
628 				     generated */
629   uint32_t ds_class;             /* EXPANDED */
630   uint32_t ds_index;             /* EXPANDED */
631   uint32_t sampling_rate;        /* fsPacketSamplingRate */
632   uint32_t sample_pool;          /* Total number of packets that could have been
633 				     sampled (i.e. packets skipped by sampling
634 				     process + total number of samples) */
635   uint32_t drops;                /* Number of times a packet was dropped due to
636 				     lack of resources */
637   uint32_t inputFormat;          /* EXPANDED */
638   uint32_t input;                /* SNMP ifIndex of input interface.
639 				     0 if interface is not known. */
640   uint32_t outputFormat;         /* EXPANDED */
641   uint32_t output;               /* SNMP ifIndex of output interface,
642 				     0 if interface is not known. */
643   uint32_t num_elements;
644   SFLFlow_sample_element *elements;
645 } SFLFlow_sample_expanded;
646 
647 /* Counter types */
648 
649 /* Generic interface counters - see RFC 1573, 2233 */
650 
651 typedef struct _SFLIf_counters {
652   uint32_t ifIndex;
653   uint32_t ifType;
654   uint64_t ifSpeed;
655   uint32_t ifDirection;        /* Derived from MAU MIB (RFC 2668)
656 				   0 = unknown, 1 = full-duplex,
657 				   2 = half-duplex, 3 = in, 4 = out */
658   uint32_t ifStatus;           /* bit field with the following bits assigned:
659 				   bit 0 = ifAdminStatus (0 = down, 1 = up)
660 				   bit 1 = ifOperStatus (0 = down, 1 = up) */
661   uint64_t ifInOctets;
662   uint32_t ifInUcastPkts;
663   uint32_t ifInMulticastPkts;
664   uint32_t ifInBroadcastPkts;
665   uint32_t ifInDiscards;
666   uint32_t ifInErrors;
667   uint32_t ifInUnknownProtos;
668   uint64_t ifOutOctets;
669   uint32_t ifOutUcastPkts;
670   uint32_t ifOutMulticastPkts;
671   uint32_t ifOutBroadcastPkts;
672   uint32_t ifOutDiscards;
673   uint32_t ifOutErrors;
674   uint32_t ifPromiscuousMode;
675 } SFLIf_counters;
676 
677 /* Ethernet interface counters - see RFC 2358 */
678 typedef struct _SFLEthernet_counters {
679   uint32_t dot3StatsAlignmentErrors;
680   uint32_t dot3StatsFCSErrors;
681   uint32_t dot3StatsSingleCollisionFrames;
682   uint32_t dot3StatsMultipleCollisionFrames;
683   uint32_t dot3StatsSQETestErrors;
684   uint32_t dot3StatsDeferredTransmissions;
685   uint32_t dot3StatsLateCollisions;
686   uint32_t dot3StatsExcessiveCollisions;
687   uint32_t dot3StatsInternalMacTransmitErrors;
688   uint32_t dot3StatsCarrierSenseErrors;
689   uint32_t dot3StatsFrameTooLongs;
690   uint32_t dot3StatsInternalMacReceiveErrors;
691   uint32_t dot3StatsSymbolErrors;
692 } SFLEthernet_counters;
693 
694 /* Token ring counters - see RFC 1748 */
695 
696 typedef struct _SFLTokenring_counters {
697   uint32_t dot5StatsLineErrors;
698   uint32_t dot5StatsBurstErrors;
699   uint32_t dot5StatsACErrors;
700   uint32_t dot5StatsAbortTransErrors;
701   uint32_t dot5StatsInternalErrors;
702   uint32_t dot5StatsLostFrameErrors;
703   uint32_t dot5StatsReceiveCongestions;
704   uint32_t dot5StatsFrameCopiedErrors;
705   uint32_t dot5StatsTokenErrors;
706   uint32_t dot5StatsSoftErrors;
707   uint32_t dot5StatsHardErrors;
708   uint32_t dot5StatsSignalLoss;
709   uint32_t dot5StatsTransmitBeacons;
710   uint32_t dot5StatsRecoverys;
711   uint32_t dot5StatsLobeWires;
712   uint32_t dot5StatsRemoves;
713   uint32_t dot5StatsSingles;
714   uint32_t dot5StatsFreqErrors;
715 } SFLTokenring_counters;
716 
717 /* 100 BaseVG interface counters - see RFC 2020 */
718 
719 typedef struct _SFLVg_counters {
720   uint32_t dot12InHighPriorityFrames;
721   uint64_t dot12InHighPriorityOctets;
722   uint32_t dot12InNormPriorityFrames;
723   uint64_t dot12InNormPriorityOctets;
724   uint32_t dot12InIPMErrors;
725   uint32_t dot12InOversizeFrameErrors;
726   uint32_t dot12InDataErrors;
727   uint32_t dot12InNullAddressedFrames;
728   uint32_t dot12OutHighPriorityFrames;
729   uint64_t dot12OutHighPriorityOctets;
730   uint32_t dot12TransitionIntoTrainings;
731   uint64_t dot12HCInHighPriorityOctets;
732   uint64_t dot12HCInNormPriorityOctets;
733   uint64_t dot12HCOutHighPriorityOctets;
734 } SFLVg_counters;
735 
736 typedef struct _SFLVlan_counters {
737   uint32_t vlan_id;
738   uint64_t octets;
739   uint32_t ucastPkts;
740   uint32_t multicastPkts;
741   uint32_t broadcastPkts;
742   uint32_t discards;
743 } SFLVlan_counters;
744 
745 typedef struct _SFLWifi_counters {
746   uint32_t dot11TransmittedFragmentCount;
747   uint32_t dot11MulticastTransmittedFrameCount;
748   uint32_t dot11FailedCount;
749   uint32_t dot11RetryCount;
750   uint32_t dot11MultipleRetryCount;
751   uint32_t dot11FrameDuplicateCount;
752   uint32_t dot11RTSSuccessCount;
753   uint32_t dot11RTSFailureCount;
754   uint32_t dot11ACKFailureCount;
755   uint32_t dot11ReceivedFragmentCount;
756   uint32_t dot11MulticastReceivedFrameCount;
757   uint32_t dot11FCSErrorCount;
758   uint32_t dot11TransmittedFrameCount;
759   uint32_t dot11WEPUndecryptableCount;
760   uint32_t dot11QoSDiscardedFragmentCount;
761   uint32_t dot11AssociatedStationCount;
762   uint32_t dot11QoSCFPollsReceivedCount;
763   uint32_t dot11QoSCFPollsUnusedCount;
764   uint32_t dot11QoSCFPollsUnusableCount;
765   uint32_t dot11QoSCFPollsLostCount;
766 } SFLWifi_counters;
767 
768 /* Processor Information */
769 /* opaque = counter_data; enterprise = 0; format = 1001 */
770 
771 typedef struct _SFLProcessor_counters {
772    uint32_t five_sec_cpu;  /* 5 second average CPU utilization */
773    uint32_t one_min_cpu;   /* 1 minute average CPU utilization */
774    uint32_t five_min_cpu;  /* 5 minute average CPU utilization */
775    uint64_t total_memory;  /* total memory (in bytes) */
776    uint64_t free_memory;   /* free memory (in bytes) */
777 } SFLProcessor_counters;
778 
779 typedef struct _SFLRadio_counters {
780   uint32_t elapsed_time;         /* elapsed time in ms */
781   uint32_t on_channel_time;      /* time in ms spent on channel */
782   uint32_t on_channel_busy_time; /* time in ms spent on channel and busy */
783 } SFLRadio_counters;
784 
785   /* host sflow */
786 
787 enum SFLMachine_type {
788   SFLMT_unknown = 0,
789   SFLMT_other   = 1,
790   SFLMT_x86     = 2,
791   SFLMT_x86_64  = 3,
792   SFLMT_ia64    = 4,
793   SFLMT_sparc   = 5,
794   SFLMT_alpha   = 6,
795   SFLMT_powerpc = 7,
796   SFLMT_m68k    = 8,
797   SFLMT_mips    = 9,
798   SFLMT_arm     = 10,
799   SFLMT_hppa    = 11,
800   SFLMT_s390    = 12
801 };
802 
803 enum SFLOS_name {
804   SFLOS_unknown   = 0,
805   SFLOS_other     = 1,
806   SFLOS_linux     = 2,
807   SFLOS_windows   = 3,
808   SFLOS_darwin    = 4,
809   SFLOS_hpux      = 5,
810   SFLOS_aix       = 6,
811   SFLOS_dragonfly = 7,
812   SFLOS_freebsd   = 8,
813   SFLOS_netbsd    = 9,
814   SFLOS_openbsd   = 10,
815   SFLOS_osf       = 11,
816   SFLOS_solaris   = 12
817 };
818 
819 typedef struct _SFLMacAddress {
820   uint8_t mac[8];
821 } SFLMacAddress;
822 
823 typedef struct _SFLAdaptor {
824   uint32_t ifIndex;
825   uint32_t num_macs;
826   SFLMacAddress macs[1];
827 } SFLAdaptor;
828 
829 typedef struct _SFLAdaptorList {
830   uint32_t capacity;
831   uint32_t num_adaptors;
832   SFLAdaptor **adaptors;
833 } SFLAdaptorList;
834 
835 typedef struct _SFLHost_parent {
836   uint32_t dsClass;       /* sFlowDataSource class */
837   uint32_t dsIndex;       /* sFlowDataSource index */
838 } SFLHost_parent;
839 
840 
841 #define SFL_MAX_HOSTNAME_LEN 64
842 #define SFL_MAX_OSRELEASE_LEN 32
843 
844 typedef struct _SFLHostId {
845   SFLString hostname;
846   u_char uuid[16];
847   uint32_t machine_type; /* enum SFLMachine_type */
848   uint32_t os_name;      /* enum SFLOS_name */
849   SFLString os_release;  /* max len 32 bytes */
850 } SFLHostId;
851 
852 typedef struct _SFLHost_nio_counters {
853   uint64_t bytes_in;
854   uint32_t pkts_in;
855   uint32_t errs_in;
856   uint32_t drops_in;
857   uint64_t bytes_out;
858   uint32_t pkts_out;
859   uint32_t errs_out;
860   uint32_t drops_out;
861 } SFLHost_nio_counters;
862 
863 typedef struct _SFLHost_cpu_counters {
864   float load_one;      /* 1 minute load avg. */
865   float load_five;     /* 5 minute load avg. */
866   float load_fifteen;  /* 15 minute load avg. */
867   uint32_t proc_run;   /* running threads */
868   uint32_t proc_total; /* total threads */
869   uint32_t cpu_num;    /* # CPU cores */
870   uint32_t cpu_speed;  /* speed in MHz of CPU */
871   uint32_t uptime;     /* seconds since last reboot */
872   uint32_t cpu_user;   /* time executing in user mode processes (ms) */
873   uint32_t cpu_nice;   /* time executing niced processs (ms) */
874   uint32_t cpu_system; /* time executing kernel mode processes (ms) */
875   uint32_t cpu_idle;   /* idle time (ms) */
876   uint32_t cpu_wio;    /* time waiting for I/O to complete (ms) */
877   uint32_t cpu_intr;   /* time servicing interrupts (ms) */
878   uint32_t cpu_sintr;  /* time servicing softirqs (ms) */
879   uint32_t interrupts; /* interrupt count */
880   uint32_t contexts;   /* context switch count */
881 } SFLHost_cpu_counters;
882 
883 typedef struct _SFLHost_mem_counters {
884   uint64_t mem_total;    /* total bytes */
885   uint64_t mem_free;     /* free bytes */
886   uint64_t mem_shared;   /* shared bytes */
887   uint64_t mem_buffers;  /* buffers bytes */
888   uint64_t mem_cached;   /* cached bytes */
889   uint64_t swap_total;   /* swap total bytes */
890   uint64_t swap_free;    /* swap free bytes */
891   uint32_t page_in;      /* page in count */
892   uint32_t page_out;     /* page out count */
893   uint32_t swap_in;      /* swap in count */
894   uint32_t swap_out;     /* swap out count */
895 } SFLHost_mem_counters;
896 
897 typedef struct _SFLHost_dsk_counters {
898   uint64_t disk_total;
899   uint64_t disk_free;
900   uint32_t part_max_used;   /* as percent * 100, so 100==1% */
901   uint32_t reads;           /* reads issued */
902   uint64_t bytes_read;      /* bytes read */
903   uint32_t read_time;       /* read time (ms) */
904   uint32_t writes;          /* writes completed */
905   uint64_t bytes_written;   /* bytes written */
906   uint32_t write_time;      /* write time (ms) */
907 } SFLHost_dsk_counters;
908 
909 /* Virtual Node Statistics */
910 /* opaque = counter_data; enterprise = 0; format = 2100 */
911 
912 typedef struct _SFLHost_vrt_node_counters {
913    uint32_t mhz;           /* expected CPU frequency */
914    uint32_t cpus;          /* the number of active CPUs */
915    uint64_t memory;        /* memory size in bytes */
916    uint64_t memory_free;   /* unassigned memory in bytes */
917    uint32_t num_domains;   /* number of active domains */
918 } SFLHost_vrt_node_counters;
919 
920 /* Virtual Domain Statistics */
921 /* opaque = counter_data; enterprise = 0; format = 2101 */
922 
923 /* virDomainState imported from libvirt.h */
924 enum SFLVirDomainState {
925      SFL_VIR_DOMAIN_NOSTATE = 0, /* no state */
926      SFL_VIR_DOMAIN_RUNNING = 1, /* the domain is running */
927      SFL_VIR_DOMAIN_BLOCKED = 2, /* the domain is blocked on resource */
928      SFL_VIR_DOMAIN_PAUSED  = 3, /* the domain is paused by user */
929      SFL_VIR_DOMAIN_SHUTDOWN= 4, /* the domain is being shut down */
930      SFL_VIR_DOMAIN_SHUTOFF = 5, /* the domain is shut off */
931      SFL_VIR_DOMAIN_CRASHED = 6  /* the domain is crashed */
932 };
933 
934 typedef struct _SFLHost_vrt_cpu_counters {
935    uint32_t state;       /* virtDomainState */
936    uint32_t cpuTime;     /* the CPU time used in mS */
937    uint32_t cpuCount;    /* number of virtual CPUs for the domain */
938 } SFLHost_vrt_cpu_counters;
939 
940 /* Virtual Domain Memory statistics */
941 /* opaque = counter_data; enterprise = 0; format = 2102 */
942 
943 typedef struct _SFLHost_vrt_mem_counters {
944   uint64_t memory;      /* memory in bytes used by domain */
945   uint64_t maxMemory;   /* memory in bytes allowed */
946 } SFLHost_vrt_mem_counters;
947 
948 /* Virtual Domain Disk statistics */
949 /* opaque = counter_data; enterprise = 0; format = 2103 */
950 
951 typedef struct _SFLHost_vrt_dsk_counters {
952   uint64_t capacity;   /* logical size in bytes */
953   uint64_t allocation; /* current allocation in bytes */
954   uint64_t available;  /* remaining free bytes */
955   uint32_t rd_req;     /* number of read requests */
956   uint64_t rd_bytes;   /* number of read bytes */
957   uint32_t wr_req;     /* number of write requests */
958   uint64_t wr_bytes;   /* number of  written bytes */
959   uint32_t errs;        /* read/write errors */
960 } SFLHost_vrt_dsk_counters;
961 
962 /* Virtual Domain Network statistics */
963 /* opaque = counter_data; enterprise = 0; format = 2104 */
964 
965 typedef struct _SFLHost_vrt_nio_counters {
966   uint64_t bytes_in;
967   uint32_t pkts_in;
968   uint32_t errs_in;
969   uint32_t drops_in;
970   uint64_t bytes_out;
971   uint32_t pkts_out;
972   uint32_t errs_out;
973   uint32_t drops_out;
974 } SFLHost_vrt_nio_counters;
975 
976 typedef struct _SFLMemcache_counters {
977    uint32_t uptime;     /* Number of seconds this server has been running */
978    uint32_t rusage_user;    /* Accumulated user time for this process (ms)*/
979    uint32_t rusage_system;  /* Accumulated system time for this process (ms)*/
980    uint32_t curr_connections; /* Number of open connections */
981    uint32_t total_connections; /* Total number of connections opened since
982                                       the server started running */
983    uint32_t connection_structures; /* Number of connection structures
984                                           allocated by the server */
985    uint32_t cmd_get;        /* Cumulative number of retrieval requests */
986    uint32_t cmd_set;        /* Cumulative number of storage requests */
987    uint32_t cmd_flush;      /* */
988    uint32_t get_hits;       /* Number of keys that have been requested and
989                                      found present */
990    uint32_t get_misses;     /* Number of items that have been requested
991                                      and not found */
992    uint32_t delete_misses;
993    uint32_t delete_hits;
994    uint32_t incr_misses;
995    uint32_t incr_hits;
996    uint32_t decr_misses;
997    uint32_t decr_hits;
998    uint32_t cas_misses;
999    uint32_t cas_hits;
1000    uint32_t cas_badval;
1001    uint32_t auth_cmds;
1002    uint32_t auth_errors;
1003    uint64_t bytes_read;
1004    uint64_t bytes_written;
1005    uint32_t limit_maxbytes;
1006    uint32_t accepting_conns;
1007    uint32_t listen_disabled_num;
1008    uint32_t threads;
1009    uint32_t conn_yields;
1010    uint64_t bytes;
1011    uint32_t curr_items;
1012    uint32_t total_items;
1013    uint32_t evictions;
1014 } SFLMemcache_counters;
1015 
1016 typedef struct _SFLHTTP_counters {
1017   uint32_t method_option_count;
1018   uint32_t method_get_count;
1019   uint32_t method_head_count;
1020   uint32_t method_post_count;
1021   uint32_t method_put_count;
1022   uint32_t method_delete_count;
1023   uint32_t method_trace_count;
1024   uint32_t methd_connect_count;
1025   uint32_t method_other_count;
1026   uint32_t status_1XX_count;
1027   uint32_t status_2XX_count;
1028   uint32_t status_3XX_count;
1029   uint32_t status_4XX_count;
1030   uint32_t status_5XX_count;
1031   uint32_t status_other_count;
1032 } SFLHTTP_counters;
1033 
1034 
1035 typedef struct _SFLCAL_counters {
1036   uint32_t transactions;
1037   uint32_t errors;
1038   uint64_t duration_uS;
1039 } SFLCAL_counters;
1040 
1041 /* Counters data */
1042 
1043 enum SFLCounters_type_tag {
1044   /* enterprise = 0, format = ... */
1045   SFLCOUNTERS_GENERIC      = 1,
1046   SFLCOUNTERS_ETHERNET     = 2,
1047   SFLCOUNTERS_TOKENRING    = 3,
1048   SFLCOUNTERS_VG           = 4,
1049   SFLCOUNTERS_VLAN         = 5,
1050   SFLCOUNTERS_80211        = 6,
1051   SFLCOUNTERS_PROCESSOR    = 1001,
1052   SFLCOUNTERS_RADIO        = 1002,
1053   SFLCOUNTERS_HOST_HID     = 2000, /* host id */
1054   SFLCOUNTERS_ADAPTORS     = 2001, /* host adaptors */
1055   SFLCOUNTERS_HOST_PAR     = 2002, /* host parent */
1056   SFLCOUNTERS_HOST_CPU     = 2003, /* host cpu  */
1057   SFLCOUNTERS_HOST_MEM     = 2004, /* host memory  */
1058   SFLCOUNTERS_HOST_DSK     = 2005, /* host storage I/O  */
1059   SFLCOUNTERS_HOST_NIO     = 2006, /* host network I/O */
1060   SFLCOUNTERS_HOST_VRT_NODE = 2100, /* host virt node */
1061   SFLCOUNTERS_HOST_VRT_CPU  = 2101, /* host virt cpu */
1062   SFLCOUNTERS_HOST_VRT_MEM  = 2102, /* host virt mem */
1063   SFLCOUNTERS_HOST_VRT_DSK  = 2103, /* host virt storage */
1064   SFLCOUNTERS_HOST_VRT_NIO  = 2104, /* host virt network I/O */
1065   SFLCOUNTERS_MEMCACHE      = 2200, /* memcached */
1066   SFLCOUNTERS_HTTP          = 2201, /* http */
1067   SFLCOUNTERS_CAL          = (4300 << 12) + 5,
1068 };
1069 
1070 typedef union _SFLCounters_type {
1071   SFLIf_counters generic;
1072   SFLEthernet_counters ethernet;
1073   SFLTokenring_counters tokenring;
1074   SFLVg_counters vg;
1075   SFLVlan_counters vlan;
1076   SFLWifi_counters wifi;
1077   SFLProcessor_counters processor;
1078   SFLRadio_counters radio;
1079   SFLHostId hostId;
1080   SFLAdaptorList *adaptors;
1081   SFLHost_parent host_par;
1082   SFLHost_cpu_counters host_cpu;
1083   SFLHost_mem_counters host_mem;
1084   SFLHost_dsk_counters host_dsk;
1085   SFLHost_nio_counters host_nio;
1086   SFLHost_vrt_node_counters host_vrt_node;
1087   SFLHost_vrt_cpu_counters host_vrt_cpu;
1088   SFLHost_vrt_mem_counters host_vrt_mem;
1089   SFLHost_vrt_dsk_counters host_vrt_dsk;
1090   SFLHost_vrt_nio_counters host_vrt_nio;
1091   SFLMemcache_counters memcache;
1092   SFLHTTP_counters http;
1093   SFLCAL_counters cal;
1094 } SFLCounters_type;
1095 
1096 typedef struct _SFLCounters_sample_element {
1097   struct _SFLCounters_sample_element *nxt; /* linked list */
1098   uint32_t tag; /* SFLCounters_type_tag */
1099   uint32_t length;
1100   SFLCounters_type counterBlock;
1101 } SFLCounters_sample_element;
1102 
1103 typedef struct _SFLCounters_sample {
1104   /* uint32_t tag;    */       /* SFL_sample_tag -- enterprise = 0 : format = 2 */
1105   /* uint32_t length; */
1106   uint32_t sequence_number;    /* Incremented with each counters sample
1107 				   generated by this source_id */
1108   uint32_t source_id;          /* fsSourceId */
1109   uint32_t num_elements;
1110   SFLCounters_sample_element *elements;
1111 } SFLCounters_sample;
1112 
1113 /* same thing, but the expanded version, so ds_index can be a full 32 bits */
1114 typedef struct _SFLCounters_sample_expanded {
1115   /* uint32_t tag;    */       /* SFL_sample_tag -- enterprise = 0 : format = 2 */
1116   /* uint32_t length; */
1117   uint32_t sequence_number;    /* Incremented with each counters sample
1118 				   generated by this source_id */
1119   uint32_t ds_class;           /* EXPANDED */
1120   uint32_t ds_index;           /* EXPANDED */
1121   uint32_t num_elements;
1122   SFLCounters_sample_element *elements;
1123 } SFLCounters_sample_expanded;
1124 
1125 #define SFLADD_ELEMENT(_sm, _el) do { (_el)->nxt = (_sm)->elements; (_sm)->elements = (_el); } while(0)
1126 
1127 /* Format of a sample datagram */
1128 
1129 enum SFLDatagram_version {
1130   SFLDATAGRAM_VERSION2 = 2,
1131   SFLDATAGRAM_VERSION4 = 4,
1132   SFLDATAGRAM_VERSION5 = 5
1133 };
1134 
1135 typedef struct _SFLSample_datagram_hdr {
1136   uint32_t datagram_version;      /* (enum SFLDatagram_version) = VERSION5 = 5 */
1137   SFLAddress agent_address;        /* IP address of sampling agent */
1138   uint32_t sub_agent_id;          /* Used to distinguishing between datagram
1139                                       streams from separate agent sub entities
1140                                       within an device. */
1141   uint32_t sequence_number;       /* Incremented with each sample datagram
1142 				      generated */
1143   uint32_t uptime;                /* Current time (in milliseconds since device
1144 				      last booted). Should be set as close to
1145 				      datagram transmission time as possible.*/
1146   uint32_t num_records;           /* Number of tag-len-val flow/counter records to follow */
1147 } SFLSample_datagram_hdr;
1148 
1149 #define SFL_MAX_DATAGRAM_SIZE 1500
1150 #define SFL_MIN_DATAGRAM_SIZE 200
1151 #define SFL_DEFAULT_DATAGRAM_SIZE 1400
1152 
1153 #define SFL_DATA_PAD 400
1154 
1155 #if defined(__cplusplus)
1156 }  /* extern "C" */
1157 #endif
1158 
1159 #endif /* SFLOW_H */
1160 
1161 
1162 /* Copyright (c) 2002-2011 InMon Corp. Licensed under the terms of the InMon sFlow licence: */
1163 /* http://www.inmon.com/technology/sflowlicense.txt */
1164 
1165 #ifndef SFLOWTOOL_H
1166 #define SFLOWTOOL_H 1
1167 
1168 #if defined(__cplusplus)
1169 extern "C" {
1170 #endif
1171 
1172 enum INMAddress_type {
1173   INMADDRESSTYPE_IP_V4 = 1,
1174   INMADDRESSTYPE_IP_V6 = 2
1175 };
1176 
1177 typedef union _INMAddress_value {
1178   SFLIPv4 ip_v4;
1179   SFLIPv6 ip_v6;
1180 } INMAddress_value;
1181 
1182 typedef struct _INMAddress {
1183   uint32_t type;           /* enum INMAddress_type */
1184   INMAddress_value address;
1185 } INMAddress;
1186 
1187 /* Packet header data */
1188 
1189 #define INM_MAX_HEADER_SIZE 256   /* The maximum sampled header size. */
1190 #define INM_DEFAULT_HEADER_SIZE 128
1191 #define INM_DEFAULT_COLLECTOR_PORT 6343
1192 #define INM_DEFAULT_SAMPLING_RATE 400
1193 
1194 /* The header protocol describes the format of the sampled header */
1195 enum INMHeader_protocol {
1196   INMHEADER_ETHERNET_ISO8023     = 1,
1197   INMHEADER_ISO88024_TOKENBUS    = 2,
1198   INMHEADER_ISO88025_TOKENRING   = 3,
1199   INMHEADER_FDDI                 = 4,
1200   INMHEADER_FRAME_RELAY          = 5,
1201   INMHEADER_X25                  = 6,
1202   INMHEADER_PPP                  = 7,
1203   INMHEADER_SMDS                 = 8,
1204   INMHEADER_AAL5                 = 9,
1205   INMHEADER_AAL5_IP              = 10, /* e.g. Cisco AAL5 mux */
1206   INMHEADER_IPv4                 = 11,
1207   INMHEADER_IPv6                 = 12
1208 };
1209 
1210 typedef struct _INMSampled_header {
1211   uint32_t header_protocol;            /* (enum INMHeader_protocol) */
1212   uint32_t frame_length;               /* Original length of packet before sampling */
1213   uint32_t header_length;              /* length of sampled header bytes to follow */
1214   uint8_t header[INM_MAX_HEADER_SIZE]; /* Header bytes */
1215 } INMSampled_header;
1216 
1217 /* Packet IP version 4 data */
1218 
1219 typedef struct _INMSampled_ipv4 {
1220   uint32_t length;      /* The length of the IP packet
1221 			    excluding lower layer encapsulations */
1222   uint32_t protocol;    /* IP Protocol type (for example, TCP = 6, UDP = 17) */
1223   SFLIPv4 src_ip; /* Source IP Address */
1224   SFLIPv4 dst_ip; /* Destination IP Address */
1225   uint32_t src_port;    /* TCP/UDP source port number or equivalent */
1226   uint32_t dst_port;    /* TCP/UDP destination port number or equivalent */
1227   uint32_t tcp_flags;   /* TCP flags */
1228   uint32_t tos;         /* IP type of service */
1229 } INMSampled_ipv4;
1230 
1231 /* Packet IP version 6 data */
1232 
1233 typedef struct _INMSampled_ipv6 {
1234   uint32_t length;       /* The length of the IP packet
1235 			     excluding lower layer encapsulations */
1236   uint32_t protocol;     /* IP Protocol type (for example, TCP = 6, UDP = 17) */
1237   SFLIPv6 src_ip; /* Source IP Address */
1238   SFLIPv6 dst_ip; /* Destination IP Address */
1239   uint32_t src_port;     /* TCP/UDP source port number or equivalent */
1240   uint32_t dst_port;     /* TCP/UDP destination port number or equivalent */
1241   uint32_t tcp_flags;    /* TCP flags */
1242   uint32_t tos;          /* IP type of service */
1243 } INMSampled_ipv6;
1244 
1245 
1246 /* Packet data */
1247 
1248 enum INMPacket_information_type {
1249   INMPACKETTYPE_HEADER  = 1,      /* Packet headers are sampled */
1250   INMPACKETTYPE_IPV4    = 2,      /* IP version 4 data */
1251   INMPACKETTYPE_IPV6    = 3       /* IP version 4 data */
1252 };
1253 
1254 typedef union _INMPacket_data_type {
1255   INMSampled_header header;
1256   INMSampled_ipv4 ipv4;
1257   INMSampled_ipv6 ipv6;
1258 } INMPacket_data_type;
1259 
1260 /* Extended data types */
1261 
1262 /* Extended switch data */
1263 
1264 typedef struct _INMExtended_switch {
1265   uint32_t src_vlan;       /* The 802.1Q VLAN id of incomming frame */
1266   uint32_t src_priority;   /* The 802.1p priority */
1267   uint32_t dst_vlan;       /* The 802.1Q VLAN id of outgoing frame */
1268   uint32_t dst_priority;   /* The 802.1p priority */
1269 } INMExtended_switch;
1270 
1271 /* Extended router data */
1272 
1273 typedef struct _INMExtended_router {
1274   INMAddress nexthop;               /* IP address of next hop router */
1275   uint32_t src_mask;               /* Source address prefix mask bits */
1276   uint32_t dst_mask;               /* Destination address prefix mask bits */
1277 } INMExtended_router;
1278 
1279 /* Extended gateway data */
1280 
1281 enum INMExtended_as_path_segment_type {
1282   INMEXTENDED_AS_SET = 1,      /* Unordered set of ASs */
1283   INMEXTENDED_AS_SEQUENCE = 2  /* Ordered sequence of ASs */
1284 };
1285 
1286 typedef struct _INMExtended_as_path_segment {
1287   uint32_t type;   /* enum INMExtended_as_path_segment_type */
1288   uint32_t length; /* number of AS numbers in set/sequence */
1289   union {
1290     uint32_t *set;
1291     uint32_t *seq;
1292   } as;
1293 } INMExtended_as_path_segment;
1294 
1295 /* note: the INMExtended_gateway structure has changed between v2 and v4.
1296    Here is the old version first... */
1297 
1298 typedef struct _INMExtended_gateway_v2 {
1299   uint32_t as;                             /* AS number for this gateway */
1300   uint32_t src_as;                         /* AS number of source (origin) */
1301   uint32_t src_peer_as;                    /* AS number of source peer */
1302   uint32_t dst_as_path_length;             /* number of AS numbers in path */
1303   uint32_t *dst_as_path;
1304 } INMExtended_gateway_v2;
1305 
1306 /* now here is the new version... */
1307 
1308 typedef struct _INMExtended_gateway_v4 {
1309   uint32_t as;                             /* AS number for this gateway */
1310   uint32_t src_as;                         /* AS number of source (origin) */
1311   uint32_t src_peer_as;                    /* AS number of source peer */
1312   uint32_t dst_as_path_segments;           /* number of segments in path */
1313   INMExtended_as_path_segment *dst_as_path; /* list of seqs or sets */
1314   uint32_t communities_length;             /* number of communities */
1315   uint32_t *communities;                   /* set of communities */
1316   uint32_t localpref;                      /* LocalPref associated with this route */
1317 } INMExtended_gateway_v4;
1318 
1319 /* Extended user data */
1320 typedef struct _INMExtended_user {
1321   uint32_t src_user_len;
1322   char *src_user;
1323   uint32_t dst_user_len;
1324   char *dst_user;
1325 } INMExtended_user;
1326 enum INMExtended_url_direction {
1327   INMEXTENDED_URL_SRC = 1, /* URL is associated with source address */
1328   INMEXTENDED_URL_DST = 2  /* URL is associated with destination address */
1329 };
1330 
1331 typedef struct _INMExtended_url {
1332   uint32_t direction; /* enum INMExtended_url_direction */
1333   uint32_t url_len;
1334   char *url;
1335 } INMExtended_url;
1336 
1337 /* Extended data */
1338 
1339 enum INMExtended_information_type {
1340   INMEXTENDED_SWITCH    = 1,      /* Extended switch information */
1341   INMEXTENDED_ROUTER    = 2,      /* Extended router information */
1342   INMEXTENDED_GATEWAY   = 3,      /* Extended gateway router information */
1343   INMEXTENDED_USER      = 4,      /* Extended TACAS/RADIUS user information */
1344   INMEXTENDED_URL       = 5       /* Extended URL information */
1345 };
1346 
1347 /* Format of a single sample */
1348 
1349 typedef struct _INMFlow_sample {
1350   uint32_t sequence_number;      /* Incremented with each flow sample
1351 				     generated */
1352   uint32_t source_id;            /* fsSourceId */
1353   uint32_t sampling_rate;        /* fsPacketSamplingRate */
1354   uint32_t sample_pool;          /* Total number of packets that could have been
1355 				     sampled (i.e. packets skipped by sampling
1356 				     process + total number of samples) */
1357   uint32_t drops;                /* Number of times a packet was dropped due to
1358 				     lack of resources */
1359   uint32_t input;                /* SNMP ifIndex of input interface.
1360 				     0 if interface is not known. */
1361   uint32_t output;               /* SNMP ifIndex of output interface,
1362 				     0 if interface is not known.
1363 				     Set most significant bit to indicate
1364 				     multiple destination interfaces
1365 				     (i.e. in case of broadcast or multicast)
1366 				     and set lower order bits to indicate
1367 				     number of destination interfaces.
1368 				     Examples:
1369 				     0x00000002  indicates ifIndex = 2
1370 				     0x00000000  ifIndex unknown.
1371 				     0x80000007  indicates a packet sent
1372 				     to 7 interfaces.
1373 				     0x80000000  indicates a packet sent to
1374 				     an unknown number of
1375 				     interfaces greater than 1.*/
1376   uint32_t packet_data_tag;       /* enum INMPacket_information_type */
1377   INMPacket_data_type packet_data; /* Information about sampled packet */
1378 
1379   /* in the sFlow packet spec the next field is the number of extended objects
1380      followed by the data for each one (tagged with the type).  Here we just
1381      provide space for each one, and flags to enable them.  The correct format
1382      is then put together by the serialization code */
1383   int gotSwitch;
1384   INMExtended_switch switchDevice;
1385   int gotRouter;
1386   INMExtended_router router;
1387   int gotGateway;
1388   union {
1389     INMExtended_gateway_v2 v2;  /* make the version explicit so that there is */
1390     INMExtended_gateway_v4 v4;  /* less danger of mistakes when upgrading code */
1391   } gateway;
1392   int gotUser;
1393   INMExtended_user user;
1394   int gotUrl;
1395   INMExtended_url url;
1396 } INMFlow_sample;
1397 
1398 /* Counter types */
1399 
1400 /* Generic interface counters - see RFC 1573, 2233 */
1401 
1402 typedef struct _INMIf_counters {
1403   uint32_t ifIndex;
1404   uint32_t ifType;
1405   uint64_t ifSpeed;
1406   uint32_t ifDirection;        /* Derived from MAU MIB (RFC 2239)
1407 				   0 = unknown, 1 = full-duplex,
1408 				   2 = half-duplex, 3 = in, 4 = out */
1409   uint32_t ifStatus;           /* bit field with the following bits assigned:
1410 				   bit 0 = ifAdminStatus (0 = down, 1 = up)
1411 				   bit 1 = ifOperStatus (0 = down, 1 = up) */
1412   uint64_t ifInOctets;
1413   uint32_t ifInUcastPkts;
1414   uint32_t ifInMulticastPkts;
1415   uint32_t ifInBroadcastPkts;
1416   uint32_t ifInDiscards;
1417   uint32_t ifInErrors;
1418   uint32_t ifInUnknownProtos;
1419   uint64_t ifOutOctets;
1420   uint32_t ifOutUcastPkts;
1421   uint32_t ifOutMulticastPkts;
1422   uint32_t ifOutBroadcastPkts;
1423   uint32_t ifOutDiscards;
1424   uint32_t ifOutErrors;
1425   uint32_t ifPromiscuousMode;
1426 } INMIf_counters;
1427 
1428 /* Ethernet interface counters - see RFC 2358 */
1429 typedef struct _INMEthernet_specific_counters {
1430   uint32_t dot3StatsAlignmentErrors;
1431   uint32_t dot3StatsFCSErrors;
1432   uint32_t dot3StatsSingleCollisionFrames;
1433   uint32_t dot3StatsMultipleCollisionFrames;
1434   uint32_t dot3StatsSQETestErrors;
1435   uint32_t dot3StatsDeferredTransmissions;
1436   uint32_t dot3StatsLateCollisions;
1437   uint32_t dot3StatsExcessiveCollisions;
1438   uint32_t dot3StatsInternalMacTransmitErrors;
1439   uint32_t dot3StatsCarrierSenseErrors;
1440   uint32_t dot3StatsFrameTooLongs;
1441   uint32_t dot3StatsInternalMacReceiveErrors;
1442   uint32_t dot3StatsSymbolErrors;
1443 } INMEthernet_specific_counters;
1444 
1445 typedef struct _INMEthernet_counters {
1446   INMIf_counters generic;
1447   INMEthernet_specific_counters ethernet;
1448 } INMEthernet_counters;
1449 
1450 /* FDDI interface counters - see RFC 1512 */
1451 typedef struct _INMFddi_counters {
1452   INMIf_counters generic;
1453 } INMFddi_counters;
1454 
1455 /* Token ring counters - see RFC 1748 */
1456 
1457 typedef struct _INMTokenring_specific_counters {
1458   uint32_t dot5StatsLineErrors;
1459   uint32_t dot5StatsBurstErrors;
1460   uint32_t dot5StatsACErrors;
1461   uint32_t dot5StatsAbortTransErrors;
1462   uint32_t dot5StatsInternalErrors;
1463   uint32_t dot5StatsLostFrameErrors;
1464   uint32_t dot5StatsReceiveCongestions;
1465   uint32_t dot5StatsFrameCopiedErrors;
1466   uint32_t dot5StatsTokenErrors;
1467   uint32_t dot5StatsSoftErrors;
1468   uint32_t dot5StatsHardErrors;
1469   uint32_t dot5StatsSignalLoss;
1470   uint32_t dot5StatsTransmitBeacons;
1471   uint32_t dot5StatsRecoverys;
1472   uint32_t dot5StatsLobeWires;
1473   uint32_t dot5StatsRemoves;
1474   uint32_t dot5StatsSingles;
1475   uint32_t dot5StatsFreqErrors;
1476 } INMTokenring_specific_counters;
1477 
1478 typedef struct _INMTokenring_counters {
1479   INMIf_counters generic;
1480   INMTokenring_specific_counters tokenring;
1481 } INMTokenring_counters;
1482 
1483 /* 100 BaseVG interface counters - see RFC 2020 */
1484 
1485 typedef struct _INMVg_specific_counters {
1486   uint32_t dot12InHighPriorityFrames;
1487   uint64_t dot12InHighPriorityOctets;
1488   uint32_t dot12InNormPriorityFrames;
1489   uint64_t dot12InNormPriorityOctets;
1490   uint32_t dot12InIPMErrors;
1491   uint32_t dot12InOversizeFrameErrors;
1492   uint32_t dot12InDataErrors;
1493   uint32_t dot12InNullAddressedFrames;
1494   uint32_t dot12OutHighPriorityFrames;
1495   uint64_t dot12OutHighPriorityOctets;
1496   uint32_t dot12TransitionIntoTrainings;
1497   uint64_t dot12HCInHighPriorityOctets;
1498   uint64_t dot12HCInNormPriorityOctets;
1499   uint64_t dot12HCOutHighPriorityOctets;
1500 } INMVg_specific_counters;
1501 
1502 typedef struct _INMVg_counters {
1503   INMIf_counters generic;
1504   INMVg_specific_counters vg;
1505 } INMVg_counters;
1506 
1507 /* WAN counters */
1508 
1509 typedef struct _INMWan_counters {
1510   INMIf_counters generic;
1511 } INMWan_counters;
1512 
1513 typedef struct _INMVlan_counters {
1514   uint32_t vlan_id;
1515   uint64_t octets;
1516   uint32_t ucastPkts;
1517   uint32_t multicastPkts;
1518   uint32_t broadcastPkts;
1519   uint32_t discards;
1520 } INMVlan_counters;
1521 
1522 /* Counters data */
1523 
1524 enum INMCounters_version {
1525   INMCOUNTERSVERSION_GENERIC      = 1,
1526   INMCOUNTERSVERSION_ETHERNET     = 2,
1527   INMCOUNTERSVERSION_TOKENRING    = 3,
1528   INMCOUNTERSVERSION_FDDI         = 4,
1529   INMCOUNTERSVERSION_VG           = 5,
1530   INMCOUNTERSVERSION_WAN          = 6,
1531   INMCOUNTERSVERSION_VLAN         = 7
1532 };
1533 
1534 typedef union _INMCounters_type {
1535   INMIf_counters generic;
1536   INMEthernet_counters ethernet;
1537   INMTokenring_counters tokenring;
1538   INMFddi_counters fddi;
1539   INMVg_counters vg;
1540   INMWan_counters wan;
1541   INMVlan_counters vlan;
1542 } INMCounters_type;
1543 
1544 typedef struct _INMCounters_sample_hdr {
1545   uint32_t sequence_number;    /* Incremented with each counters sample
1546 				   generated by this source_id */
1547   uint32_t source_id;          /* fsSourceId */
1548   uint32_t sampling_interval;  /* fsCounterSamplingInterval */
1549 } INMCounters_sample_hdr;
1550 
1551 typedef struct _INMCounters_sample {
1552   INMCounters_sample_hdr hdr;
1553   uint32_t counters_type_tag;  /* Enum INMCounters_version */
1554   INMCounters_type counters;    /* Counter set for this interface type */
1555 } INMCounters_sample;
1556 
1557 /* when I turn on optimisation with the Microsoft compiler it seems to change
1558    the values of these enumerated types and break the program - not sure why */
1559 enum INMSample_types {
1560    FLOWSAMPLE  = 1,
1561    COUNTERSSAMPLE = 2
1562 };
1563 
1564 typedef union _INMSample_type {
1565   INMFlow_sample flowsample;
1566   INMCounters_sample counterssample;
1567 } INMSample_type;
1568 
1569 /* Format of a sample datagram */
1570 
1571 enum INMDatagram_version {
1572   INMDATAGRAM_VERSION2 = 2,
1573   INMDATAGRAM_VERSION4 = 4
1574 };
1575 
1576 typedef struct _INMSample_datagram_hdr {
1577   uint32_t datagram_version;      /* (enum INMDatagram_version) = VERSION4 */
1578   INMAddress agent_address;        /* IP address of sampling agent */
1579   uint32_t sequence_number;       /* Incremented with each sample datagram
1580 				      generated */
1581   uint32_t uptime;                /* Current time (in milliseconds since device
1582 				      last booted). Should be set as close to
1583 				      datagram transmission time as possible.*/
1584   uint32_t num_samples;           /* Number of flow and counters samples to follow */
1585 } INMSample_datagram_hdr;
1586 
1587 #define INM_MAX_DATAGRAM_SIZE 1500
1588 #define INM_MIN_DATAGRAM_SIZE 200
1589 #define INM_DEFAULT_DATAGRAM_SIZE 1400
1590 
1591 #define INM_DATA_PAD 400
1592 
1593 #if defined(__cplusplus)
1594 }  /* extern "C" */
1595 #endif
1596 
1597 #endif /* SFLOWTOOL_H */
1598 
1599 
1600 typedef struct _SFSample {
1601   struct in_addr sourceIP;
1602   SFLAddress agent_addr;
1603   uint32_t agentSubId;
1604 
1605   /* the raw pdu */
1606   u_char *rawSample;
1607   uint32_t rawSampleLen;
1608   u_char *endp;
1609   time_t pcapTimestamp;
1610 
1611   /* decode cursor */
1612   uint32_t *datap;
1613 
1614   uint32_t datagramVersion;
1615   uint32_t sampleType;
1616   uint32_t ds_class;
1617   uint32_t ds_index;
1618 
1619   /* generic interface counter sample */
1620   SFLIf_counters ifCounters;
1621 
1622   /* sample stream info */
1623   uint32_t sysUpTime;
1624   uint32_t sequenceNo;
1625   uint32_t sampledPacketSize;
1626   uint32_t samplesGenerated;
1627   uint32_t meanSkipCount;
1628   uint32_t samplePool;
1629   uint32_t dropEvents;
1630 
1631   /* the sampled header */
1632   uint32_t packet_data_tag;
1633   uint32_t headerProtocol;
1634   u_char *header;
1635   int headerLen;
1636   uint32_t stripped;
1637 
1638   /* header decode */
1639   int gotIPV4;
1640   int gotIPV4Struct;
1641   int offsetToIPV4;
1642   int gotIPV6;
1643   int gotIPV6Struct;
1644   int offsetToIPV6;
1645   int offsetToPayload;
1646   SFLAddress ipsrc;
1647   SFLAddress ipdst;
1648   uint32_t dcd_ipProtocol;
1649   uint32_t dcd_ipTos;
1650   uint32_t dcd_ipTTL;
1651   uint32_t dcd_sport;
1652   uint32_t dcd_dport;
1653   uint32_t dcd_tcpFlags;
1654   uint32_t ip_fragmentOffset;
1655   uint32_t udp_pduLen;
1656 
1657   /* ports */
1658   uint32_t inputPortFormat;
1659   uint32_t outputPortFormat;
1660   uint32_t inputPort;
1661   uint32_t outputPort;
1662 
1663   /* ethernet */
1664   uint32_t eth_type;
1665   uint32_t eth_len;
1666   u_char eth_src[8];
1667   u_char eth_dst[8];
1668 
1669   /* vlan */
1670   uint32_t in_vlan;
1671   uint32_t in_priority;
1672   uint32_t internalPriority;
1673   uint32_t out_vlan;
1674   uint32_t out_priority;
1675   int vlanFilterReject;
1676 
1677   /* extended data fields */
1678   uint32_t num_extended;
1679   uint32_t extended_data_tag;
1680 #define SASAMPLE_EXTENDED_DATA_SWITCH 1
1681 #define SASAMPLE_EXTENDED_DATA_ROUTER 4
1682 #define SASAMPLE_EXTENDED_DATA_GATEWAY 8
1683 #define SASAMPLE_EXTENDED_DATA_USER 16
1684 #define SASAMPLE_EXTENDED_DATA_URL 32
1685 #define SASAMPLE_EXTENDED_DATA_MPLS 64
1686 #define SASAMPLE_EXTENDED_DATA_NAT 128
1687 #define SASAMPLE_EXTENDED_DATA_MPLS_TUNNEL 256
1688 #define SASAMPLE_EXTENDED_DATA_MPLS_VC 512
1689 #define SASAMPLE_EXTENDED_DATA_MPLS_FTN 1024
1690 #define SASAMPLE_EXTENDED_DATA_MPLS_LDP_FEC 2048
1691 #define SASAMPLE_EXTENDED_DATA_VLAN_TUNNEL 4096
1692 
1693   /* IP forwarding info */
1694   SFLAddress nextHop;
1695   uint32_t srcMask;
1696   uint32_t dstMask;
1697 
1698   /* BGP info */
1699   SFLAddress bgp_nextHop;
1700   uint32_t my_as;
1701   uint32_t src_as;
1702   uint32_t src_peer_as;
1703   uint32_t dst_as_path_len;
1704   uint32_t *dst_as_path;
1705   /* note: version 4 dst as path segments just get printed, not stored here, however
1706    * the dst_peer and dst_as are filled in, since those are used for netflow encoding
1707    */
1708   uint32_t dst_peer_as;
1709   uint32_t dst_as;
1710 
1711   uint32_t communities_len;
1712   uint32_t *communities;
1713   uint32_t localpref;
1714 
1715   /* user id */
1716 #define SA_MAX_EXTENDED_USER_LEN 200
1717   uint32_t src_user_charset;
1718   uint32_t src_user_len;
1719   char src_user[SA_MAX_EXTENDED_USER_LEN+1];
1720   uint32_t dst_user_charset;
1721   uint32_t dst_user_len;
1722   char dst_user[SA_MAX_EXTENDED_USER_LEN+1];
1723 
1724   /* url */
1725 #define SA_MAX_EXTENDED_URL_LEN 200
1726 #define SA_MAX_EXTENDED_HOST_LEN 200
1727   uint32_t url_direction;
1728   uint32_t url_len;
1729   char url[SA_MAX_EXTENDED_URL_LEN+1];
1730   uint32_t host_len;
1731   char host[SA_MAX_EXTENDED_HOST_LEN+1];
1732 
1733   /* mpls */
1734   SFLAddress mpls_nextHop;
1735 
1736   /* nat */
1737   SFLAddress nat_src;
1738   SFLAddress nat_dst;
1739 
1740   /* counter blocks */
1741   uint32_t statsSamplingInterval;
1742   uint32_t counterBlockVersion;
1743 
1744 # define SFABORT(s, r) abort()
1745 
1746 } SFSample;
1747 
SFGetData32_nobswap(SFSample * sample)1748 static uint32_t SFGetData32_nobswap(SFSample *sample) {
1749   uint32_t ans = *(sample->datap)++;
1750 
1751   if((u_char *)sample->datap > sample->endp) {
1752     SFABORT(sample, SF_ABORT_EOS);
1753   }
1754   return ans;
1755 }
1756 
SFGetData32(SFSample * sample)1757 static uint32_t SFGetData32(SFSample *sample) {
1758   return ntohl(SFGetData32_nobswap(sample));
1759 }
1760 
SFGetFloat(SFSample * sample)1761 static float SFGetFloat(SFSample *sample) {
1762   float fl;
1763   uint32_t reg = SFGetData32(sample);
1764   memcpy(&fl, &reg, 4);
1765   return fl;
1766 }
1767 
SFGetData64(SFSample * sample)1768 static uint64_t SFGetData64(SFSample *sample) {
1769   uint64_t tmpLo, tmpHi;
1770   tmpHi = SFGetData32(sample);
1771   tmpLo = SFGetData32(sample);
1772   return (tmpHi << 32) + tmpLo;
1773 }
1774 
SFSkipBytes(SFSample * sample,uint32_t skip)1775 static void SFSkipBytes(SFSample *sample, uint32_t skip) {
1776   int quads = (skip + 3) / 4;
1777   sample->datap += quads;
1778   if(skip > sample->rawSampleLen || (u_char *)sample->datap > sample->endp) {
1779     SFABORT(sample, SF_ABORT_EOS);
1780   }
1781 }
1782 
SFGetString(SFSample * sample,char * buf,uint32_t bufLen)1783 static uint32_t SFGetString(SFSample *sample, char *buf, uint32_t bufLen) {
1784   uint32_t len, read_len;
1785   len = SFGetData32(sample);
1786   // truncate if too long
1787   read_len = (len >= bufLen) ? (bufLen - 1) : len;
1788   memcpy(buf, sample->datap, read_len);
1789   buf[read_len] = '\0';   // null terminate
1790   SFSkipBytes(sample, len);
1791   return len;
1792 }
1793 
1794 
SFGetAddress(SFSample * sample,SFLAddress * address)1795 static uint32_t SFGetAddress(SFSample *sample, SFLAddress *address) {
1796   address->type = SFGetData32(sample);
1797   if(address->type == SFLADDRESSTYPE_IP_V4)
1798     address->address.ip_v4.addr = SFGetData32_nobswap(sample);
1799   else {
1800     memcpy(&address->address.ip_v6.addr, sample->datap, 16);
1801     SFSkipBytes(sample, 16);
1802   }
1803   return address->type;
1804 }
1805