Coverage Report

Created: 2026-02-14 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ntopng/third-party/sflow_collect.c
Line
Count
Source
1
/*
2
 *
3
 * (C) 2013-24 - ntop.org
4
 *
5
 *
6
 * This program is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software Foundation,
18
 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
 *
20
 */
21
22
/*
23
 *  ntop includes sFlow(TM), freely available from http://www.inmon.com/".
24
 *
25
 * Some code has been copied from the InMon sflowtool
26
 */
27
28
/* #define DEBUG_FLOWS     1 */
29
/* #define DEBUG_UPSCALING 1 */
30
31
32
/* sFlow Counter Fields (keep this in sync with ntopng */
33
#define SFLOW_DEVICE_IP                 0
34
#define SFLOW_SAMPLES_GENERATED         1
35
#define SFLOW_IF_INDEX                  2
36
#define SFLOW_IF_NAME                   3
37
#define SFLOW_IF_TYPE                   4
38
#define SFLOW_IF_SPEED                  5
39
#define SFLOW_IF_DIRECTION              6
40
#define SFLOW_IF_ADMIN_STATUS           7
41
#define SFLOW_IF_OPER_STATUS            8
42
#define SFLOW_IF_IN_OCTETS              9
43
#define SFLOW_IF_IN_PACKETS             10
44
#define SFLOW_IF_IN_ERRORS              11
45
#define SFLOW_IF_OUT_OCTETS             12
46
#define SFLOW_IF_OUT_PACKETS            13
47
#define SFLOW_IF_OUT_ERRORS             14
48
#define SFLOW_IF_PROMISCUOUS_MODE       15
49
50
#ifndef INET6
51
#define INET6 1
52
#endif
53
54
#define MAX_NUM_SFLOW_POOLMAP_ENTRIES  32768
55
56
u_int32_t numsFlowsV2Rcvd = 0, numsFlowsV4Rcvd = 0, numsFlowsV5Rcvd = 0, numBadsFlowsVersionsRcvd = 0;
57
58
typedef struct {
59
  u_int32_t addr;
60
} SFLIPv4;
61
62
typedef struct {
63
  u_char addr[16];
64
} SFLIPv6;
65
66
typedef union _SFLAddress_value {
67
  SFLIPv4 ip_v4;
68
  SFLIPv6 ip_v6;
69
} SFLAddress_value;
70
71
enum SFLAddress_type {
72
  SFLADDRESSTYPE_UNDEFINED = 0,
73
  SFLADDRESSTYPE_IP_V4 = 1,
74
  SFLADDRESSTYPE_IP_V6 = 2
75
};
76
77
typedef struct _SFLAddress {
78
  u_int32_t type;           /* enum SFLAddress_type */
79
  SFLAddress_value address;
80
} SFLAddress;
81
82
/* Packet header data */
83
84
#define SFL_DEFAULT_HEADER_SIZE 128
85
#define SFL_DEFAULT_COLLECTOR_PORT 6343
86
#define SFL_DEFAULT_SAMPLING_RATE 400
87
88
/* The header protocol describes the format of the sampled header */
89
enum SFLHeader_protocol {
90
  SFLHEADER_ETHERNET_ISO8023     = 1,
91
  SFLHEADER_ISO88024_TOKENBUS    = 2,
92
  SFLHEADER_ISO88025_TOKENRING   = 3,
93
  SFLHEADER_FDDI                 = 4,
94
  SFLHEADER_FRAME_RELAY          = 5,
95
  SFLHEADER_X25                  = 6,
96
  SFLHEADER_PPP                  = 7,
97
  SFLHEADER_SMDS                 = 8,
98
  SFLHEADER_AAL5                 = 9,
99
  SFLHEADER_AAL5_IP              = 10, /* e.g. Cisco AAL5 mux */
100
  SFLHEADER_IPv4                 = 11,
101
  SFLHEADER_IPv6                 = 12,
102
  SFLHEADER_MPLS                 = 13,
103
  SFLHEADER_POS                  = 14,
104
  SFLHEADER_IEEE80211MAC         = 15,
105
  SFLHEADER_IEEE80211_AMPDU      = 16,
106
  SFLHEADER_IEEE80211_AMSDU_SUBFRAME = 17
107
};
108
109
/* raw sampled header */
110
111
typedef struct _SFLSampled_header {
112
  u_int32_t header_protocol;            /* (enum SFLHeader_protocol) */
113
  u_int32_t frame_length;               /* Original length of packet before sampling */
114
  u_int32_t stripped;                   /* header/trailer bytes stripped by sender */
115
  u_int32_t header_length;              /* length of sampled header bytes to follow */
116
  u_int8_t *header_bytes;               /* Header bytes */
117
} SFLSampled_header;
118
119
/* decoded ethernet header */
120
121
typedef struct _SFLSampled_ethernet {
122
  u_int32_t eth_len;       /* The length of the MAC packet excluding
123
            lower layer encapsulations */
124
  u_int8_t src_mac[8];    /* 6 bytes + 2 pad */
125
  u_int8_t dst_mac[8];
126
  u_int32_t eth_type;
127
} SFLSampled_ethernet;
128
129
/* decoded IP version 4 header */
130
131
typedef struct _SFLSampled_ipv4 {
132
  u_int32_t length;      /* The length of the IP packet
133
          excluding lower layer encapsulations */
134
  u_int32_t protocol;    /* IP Protocol type (for example, TCP = 6, UDP = 17) */
135
  SFLIPv4 src_ip; /* Source IP Address */
136
  SFLIPv4 dst_ip; /* Destination IP Address */
137
  u_int32_t src_port;    /* TCP/UDP source port number or equivalent */
138
  u_int32_t dst_port;    /* TCP/UDP destination port number or equivalent */
139
  u_int32_t tcp_flags;   /* TCP flags */
140
  u_int32_t tos;         /* IP type of service */
141
} SFLSampled_ipv4;
142
143
/* decoded IP version 6 data */
144
145
typedef struct _SFLSampled_ipv6 {
146
  u_int32_t length;       /* The length of the IP packet
147
           excluding lower layer encapsulations */
148
  u_int32_t protocol;     /* IP Protocol type (for example, TCP = 6, UDP = 17) */
149
  SFLIPv6 src_ip; /* Source IP Address */
150
  SFLIPv6 dst_ip; /* Destination IP Address */
151
  u_int32_t src_port;     /* TCP/UDP source port number or equivalent */
152
  u_int32_t dst_port;     /* TCP/UDP destination port number or equivalent */
153
  u_int32_t tcp_flags;    /* TCP flags */
154
  u_int32_t priority;     /* IP priority */
155
} SFLSampled_ipv6;
156
157
/* Extended data types */
158
159
/* Extended switch data */
160
161
typedef struct _SFLExtended_switch {
162
  u_int32_t src_vlan;       /* The 802.1Q VLAN id of incomming frame */
163
  u_int32_t src_priority;   /* The 802.1p priority */
164
  u_int32_t dst_vlan;       /* The 802.1Q VLAN id of outgoing frame */
165
  u_int32_t dst_priority;   /* The 802.1p priority */
166
} SFLExtended_switch;
167
168
/* Extended router data */
169
170
typedef struct _SFLExtended_router {
171
  SFLAddress nexthop;               /* IP address of next hop router */
172
  u_int32_t src_mask;               /* Source address prefix mask bits */
173
  u_int32_t dst_mask;               /* Destination address prefix mask bits */
174
} SFLExtended_router;
175
176
/* Extended gateway data */
177
enum SFLExtended_as_path_segment_type {
178
  SFLEXTENDED_AS_SET = 1,      /* Unordered set of ASs */
179
  SFLEXTENDED_AS_SEQUENCE = 2  /* Ordered sequence of ASs */
180
};
181
182
typedef struct _SFLExtended_as_path_segment {
183
  u_int32_t type;   /* enum SFLExtended_as_path_segment_type */
184
  u_int32_t length; /* number of AS numbers in set/sequence */
185
  union {
186
    u_int32_t *set;
187
    u_int32_t *seq;
188
  } as;
189
} SFLExtended_as_path_segment;
190
191
typedef struct _SFLExtended_gateway {
192
  SFLAddress nexthop;                       /* Address of the border router that should
193
                                               be used for the destination network */
194
  u_int32_t as;                             /* AS number for this gateway */
195
  u_int32_t src_as;                         /* AS number of source (origin) */
196
  u_int32_t src_peer_as;                    /* AS number of source peer */
197
  u_int32_t dst_as_path_segments;           /* number of segments in path */
198
  SFLExtended_as_path_segment *dst_as_path; /* list of seqs or sets */
199
  u_int32_t communities_length;             /* number of communities */
200
  u_int32_t *communities;                   /* set of communities */
201
  u_int32_t localpref;                      /* LocalPref associated with this route */
202
} SFLExtended_gateway;
203
204
typedef struct _SFLString {
205
  u_int32_t len;
206
  char *str;
207
} SFLString;
208
209
/* Extended user data */
210
211
typedef struct _SFLExtended_user {
212
  u_int32_t src_charset;  /* MIBEnum value of character set used to encode a string - See RFC 2978
213
           Where possible UTF-8 encoding (MIBEnum=106) should be used. A value
214
           of zero indicates an unknown encoding. */
215
  SFLString src_user;
216
  u_int32_t dst_charset;
217
  SFLString dst_user;
218
} SFLExtended_user;
219
220
/* Extended URL data */
221
222
enum SFLExtended_url_direction {
223
  SFLEXTENDED_URL_SRC = 1, /* URL is associated with source address */
224
  SFLEXTENDED_URL_DST = 2  /* URL is associated with destination address */
225
};
226
227
typedef struct _SFLExtended_url {
228
  u_int32_t direction;   /* enum SFLExtended_url_direction */
229
  SFLString url;         /* URL associated with the packet flow.
230
          Must be URL encoded */
231
  SFLString host;        /* The host field from the HTTP header */
232
} SFLExtended_url;
233
234
/* Extended MPLS data */
235
236
typedef struct _SFLLabelStack {
237
  u_int32_t depth;
238
  u_int32_t *stack; /* first entry is top of stack - see RFC 3032 for encoding */
239
} SFLLabelStack;
240
241
typedef struct _SFLExtended_mpls {
242
  SFLAddress nextHop;        /* Address of the next hop */
243
  SFLLabelStack in_stack;
244
  SFLLabelStack out_stack;
245
} SFLExtended_mpls;
246
247
/* Extended NAT data
248
   Packet header records report addresses as seen at the sFlowDataSource.
249
   The extended_nat structure reports on translated source and/or destination
250
   addesses for this packet. If an address was not translated it should
251
   be equal to that reported for the header. */
252
253
typedef struct _SFLExtended_nat {
254
  SFLAddress src;    /* Source address */
255
  SFLAddress dst;    /* Destination address */
256
} SFLExtended_nat;
257
258
/* additional Extended MPLS stucts */
259
260
typedef struct _SFLExtended_mpls_tunnel {
261
  SFLString tunnel_lsp_name;  /* Tunnel name */
262
  u_int32_t tunnel_id;        /* Tunnel ID */
263
  u_int32_t tunnel_cos;       /* Tunnel COS value */
264
} SFLExtended_mpls_tunnel;
265
266
typedef struct _SFLExtended_mpls_vc {
267
  SFLString vc_instance_name; /* VC instance name */
268
  u_int32_t vll_vc_id;        /* VLL/VC instance ID */
269
  u_int32_t vc_label_cos;     /* VC Label COS value */
270
} SFLExtended_mpls_vc;
271
272
/* Extended MPLS FEC
273
   - Definitions from MPLS-FTN-STD-MIB mplsFTNTable */
274
275
typedef struct _SFLExtended_mpls_FTN {
276
  SFLString mplsFTNDescr;
277
  u_int32_t mplsFTNMask;
278
} SFLExtended_mpls_FTN;
279
280
/* Extended MPLS LVP FEC
281
   - Definition from MPLS-LDP-STD-MIB mplsFecTable
282
   Note: mplsFecAddrType, mplsFecAddr information available
283
   from packet header */
284
285
typedef struct _SFLExtended_mpls_LDP_FEC {
286
  u_int32_t mplsFecAddrPrefixLength;
287
} SFLExtended_mpls_LDP_FEC;
288
289
/* Extended VLAN tunnel information
290
   Record outer VLAN encapsulations that have
291
   been stripped. extended_vlantunnel information
292
   should only be reported if all the following conditions are satisfied:
293
   1. The packet has nested vlan tags, AND
294
   2. The reporting device is VLAN aware, AND
295
   3. One or more VLAN tags have been stripped, either
296
   because they represent proprietary encapsulations, or
297
   because switch hardware automatically strips the outer VLAN
298
   encapsulation.
299
   Reporting extended_vlantunnel information is not a substitute for
300
   reporting extended_switch information. extended_switch data must
301
   always be reported to describe the ingress/egress VLAN information
302
   for the packet. The extended_vlantunnel information only applies to
303
   nested VLAN tags, and then only when one or more tags has been
304
   stripped. */
305
306
typedef SFLLabelStack SFLVlanStack;
307
typedef struct _SFLExtended_vlan_tunnel {
308
  SFLVlanStack stack;  /* List of stripped 802.1Q TPID/TCI layers. Each
309
        TPID,TCI pair is represented as a single 32 bit
310
        integer. Layers listed from outermost to
311
        innermost. */
312
} SFLExtended_vlan_tunnel;
313
314
////////////////// IEEE 802.11 Extension structs ////////////////////
315
316
/* The 4-byte cipher_suite identifier follows the format of the cipher suite
317
   selector value from the 802.11i (TKIP/CCMP amendment to 802.11i)
318
   The most significant three bytes contain the OUI and the least significant
319
   byte contains the Suite Type.
320
321
   The currently assigned values are:
322
323
   OUI        |Suite type  |Meaning
324
   ----------------------------------------------------
325
   00-0F-AC   | 0          | Use group cipher suite
326
   00-0F-AC   | 1          | WEP-40
327
   00-0F-AC   | 2          | TKIP
328
   00-0F-AC   | 3          | Reserved
329
   00-0F-AC   | 4          | CCMP
330
   00-0F-AC   | 5          | WEP-104
331
   00-0F-AC   | 6-255      | Reserved
332
   Vendor OUI | Other      | Vendor specific
333
   Other      | Any        | Reserved
334
   ----------------------------------------------------
335
*/
336
337
typedef u_int32_t SFLCipherSuite;
338
339
/* Extended wifi Payload
340
   Used to provide unencrypted version of 802.11 MAC data. If the
341
   MAC data is not encrypted then the agent must not include an
342
   extended_wifi_payload structure.
343
   If 802.11 MAC data is encrypted then the sampled_header structure
344
   should only contain the MAC header (since encrypted data cannot
345
   be decoded by the sFlow receiver). If the sFlow agent has access to
346
   the unencrypted payload, it should add an extended_wifi_payload
347
   structure containing the unencrypted data bytes from the sampled
348
   packet header, starting at the beginning of the 802.2 LLC and not
349
   including any trailing encryption footers.  */
350
/* opaque = flow_data; enterprise = 0; format = 1013 */
351
352
typedef struct _SFLExtended_wifi_payload {
353
  SFLCipherSuite cipherSuite;
354
  SFLSampled_header header;
355
} SFLExtended_wifi_payload;
356
357
typedef enum  {
358
  IEEE80211_A=1,
359
  IEEE80211_B=2,
360
  IEEE80211_G=3,
361
  IEEE80211_N=4,
362
} SFL_IEEE80211_version;
363
364
/* opaque = flow_data; enterprise = 0; format = 1014 */
365
366
0
#define SFL_MAX_SSID_LEN 256
367
368
typedef struct _SFLExtended_wifi_rx {
369
  u_int32_t ssid_len;
370
  char *ssid;
371
  char bssid[6];    /* BSSID */
372
  SFL_IEEE80211_version version;  /* version */
373
  u_int32_t channel;       /* channel number */
374
  u_int64_t speed;
375
  u_int32_t rsni;          /* received signal to noise ratio, see dot11FrameRprtRSNI */
376
  u_int32_t rcpi;          /* received channel power, see dot11FrameRprtLastRCPI */
377
  u_int32_t packet_duration_us; /* amount of time that the successfully received pkt occupied RF medium.*/
378
} SFLExtended_wifi_rx;
379
380
/* opaque = flow_data; enterprise = 0; format = 1015 */
381
382
typedef struct _SFLExtended_wifi_tx {
383
  u_int32_t ssid_len;
384
  char *ssid;              /* SSID string */
385
  char  bssid[6];             /* BSSID */
386
  SFL_IEEE80211_version version;    /* version */
387
  u_int32_t transmissions;   /* number of transmissions for sampled
388
        packet.
389
        0 = unkown
390
        1 = packet was successfully transmitted
391
        on first attempt
392
        n > 1 = n - 1 retransmissions */
393
  u_int32_t packet_duration_us;  /* amount of time that the successfully
394
                                    transmitted packet occupied the
395
                                    RF medium */
396
  u_int32_t retrans_duration_us; /* amount of time that failed transmission
397
                                    attempts occupied the RF medium */
398
  u_int32_t channel;         /* channel number */
399
  u_int64_t speed;
400
  u_int32_t power_mw;           /* transmit power in mW. */
401
} SFLExtended_wifi_tx;
402
403
/* Extended 802.11 Aggregation Data */
404
/* A flow_sample of an aggregated frame would consist of a packet
405
   header for the whole frame + any other extended structures that
406
   apply (e.g. 80211_tx/rx etc.) + an extended_wifi_aggregation
407
   structure which would contain an array of pdu structures (one
408
   for each PDU in the aggregate). A pdu is simply an array of
409
   flow records, in the simplest case a packet header for each PDU,
410
   but extended structures could be included as well. */
411
412
/* opaque = flow_data; enterprise = 0; format = 1016 */
413
414
struct _SFLFlow_Pdu; // forward decl
415
416
typedef struct _SFLExtended_aggregation {
417
  u_int32_t num_pdus;
418
  struct _SFFlow_Pdu *pdus;
419
} SFLExtended_aggregation;
420
421
/* Extended socket information,
422
   Must be filled in for all application transactions associated with a network socket
423
   Omit if transaction associated with non-network IPC  */
424
425
/* IPv4 Socket */
426
/* opaque = flow_data; enterprise = 0; format = 2100 */
427
typedef struct _SFLExtended_socket_ipv4 {
428
  u_int32_t protocol;     /* IP Protocol (e.g. TCP = 6, UDP = 17) */
429
  SFLIPv4 local_ip;      /* local IP address */
430
  SFLIPv4 remote_ip;     /* remote IP address */
431
  u_int32_t local_port;   /* TCP/UDP local port number or equivalent */
432
  u_int32_t remote_port;  /* TCP/UDP remote port number of equivalent */
433
} SFLExtended_socket_ipv4;
434
435
#define XDRSIZ_SFLEXTENDED_SOCKET4 20
436
437
/* IPv6 Socket */
438
/* opaque = flow_data; enterprise = 0; format = 2101 */
439
typedef struct _SFLExtended_socket_ipv6 {
440
  u_int32_t protocol;     /* IP Protocol (e.g. TCP = 6, UDP = 17) */
441
  SFLIPv6 local_ip;      /* local IP address */
442
  SFLIPv6 remote_ip;     /* remote IP address */
443
  u_int32_t local_port;   /* TCP/UDP local port number or equivalent */
444
  u_int32_t remote_port;  /* TCP/UDP remote port number of equivalent */
445
} SFLExtended_socket_ipv6;
446
447
#define XDRSIZ_SFLEXTENDED_SOCKET6 44
448
449
typedef enum  {
450
  MEMCACHE_PROT_OTHER   = 0,
451
  MEMCACHE_PROT_ASCII   = 1,
452
  MEMCACHE_PROT_BINARY  = 2,
453
} SFLMemcache_prot;
454
455
typedef enum  {
456
  MEMCACHE_CMD_OTHER    = 0,
457
  MEMCACHE_CMD_SET      = 1,
458
  MEMCACHE_CMD_ADD      = 2,
459
  MEMCACHE_CMD_REPLACE  = 3,
460
  MEMCACHE_CMD_APPEND   = 4,
461
  MEMCACHE_CMD_PREPEND  = 5,
462
  MEMCACHE_CMD_CAS      = 6,
463
  MEMCACHE_CMD_GET      = 7,
464
  MEMCACHE_CMD_GETS     = 8,
465
} SFLMemcache_cmd;
466
467
enum SFLMemcache_operation_status {
468
  MEMCACHE_OP_UNKNOWN      = 0,
469
  MEMCACHE_OP_OK           = 1,
470
  MEMCACHE_OP_ERROR        = 2,
471
  MEMCACHE_OP_CLIENT_ERROR = 3,
472
  MEMCACHE_OP_SERVER_ERROR = 4,
473
  MEMCACHE_OP_STORED       = 5,
474
  MEMCACHE_OP_NOT_STORED   = 6,
475
  MEMCACHE_OP_EXISTS       = 7,
476
  MEMCACHE_OP_NOT_FOUND    = 8,
477
  MEMCACHE_OP_DELETED      = 9,
478
};
479
480
#define SFL_MAX_MEMCACHE_KEY 255
481
482
typedef struct _SFLSampled_memcache {
483
  u_int32_t protocol;    /* SFLMemcache_prot */
484
  u_int32_t command;     /* SFLMemcache_cmd */
485
  SFLString key;        /* up to 255 chars */
486
  u_int32_t nkeys;
487
  u_int32_t value_bytes;
488
  u_int32_t duration_uS;
489
  u_int32_t status;      /* SFLMemcache_operation_status */
490
} SFLSampled_memcache;
491
492
typedef enum {
493
  SFHTTP_OTHER    = 0,
494
  SFHTTP_OPTIONS  = 1,
495
  SFHTTP_GET      = 2,
496
  SFHTTP_HEAD     = 3,
497
  SFHTTP_POST     = 4,
498
  SFHTTP_PUT      = 5,
499
  SFHTTP_DELETE   = 6,
500
  SFHTTP_TRACE    = 7,
501
  SFHTTP_CONNECT  = 8,
502
} SFLHTTP_method;
503
504
0
#define SFL_MAX_HTTP_URI 255
505
0
#define SFL_MAX_HTTP_HOST 32
506
0
#define SFL_MAX_HTTP_REFERRER 255
507
0
#define SFL_MAX_HTTP_USERAGENT 64
508
0
#define SFL_MAX_HTTP_AUTHUSER 32
509
0
#define SFL_MAX_HTTP_MIMETYPE 32
510
511
typedef struct _SFLSampled_http {
512
  SFLHTTP_method method;
513
  u_int32_t protocol;      /* 1.1=1001 */
514
  SFLString uri;           /* URI exactly as it came from the client (up to 255 bytes) */
515
  SFLString host;          /* Host value from request header (<= 32 bytes) */
516
  SFLString referrer;      /* Referer value from request header (<=255 bytes) */
517
  SFLString useragent;     /* User-Agent value from request header (<= 64 bytes)*/
518
  SFLString authuser;      /* RFC 1413 identity of user (<=32 bytes)*/
519
  SFLString mimetype;      /* Mime-Type (<=32 bytes) */
520
  u_int64_t bytes;          /* Content-Length of document transferred */
521
  u_int32_t uS;             /* duration of the operation (microseconds) */
522
  u_int32_t status;         /* HTTP status code */
523
} SFLSampled_http;
524
525
526
typedef enum {
527
  SFLOW_CAL_TRANSACTION_OTHER=0,
528
  SFLOW_CAL_TRANSACTION_START,
529
  SFLOW_CAL_TRANSACTION_END,
530
  SFLOW_CAL_TRANSACTION_ATOMIC,
531
  SFLOW_CAL_TRANSACTION_EVENT,
532
  SFLOW_CAL_NUM_TRANSACTION_TYPES
533
}  EnumSFLCALTransaction;
534
535
static const char *CALTransactionNames[] = {"OTHER", "START", "END","ATOMIC", "EVENT" };
536
537
typedef struct _SFLSampled_CAL {
538
  EnumSFLCALTransaction type;
539
  u_int32_t depth;
540
  SFLString pool;
541
  SFLString transaction;
542
  SFLString operation;
543
  SFLString status;
544
  u_int64_t duration_uS;
545
} SFLSampled_CAL;
546
547
0
#define SFLCAL_MAX_POOL_LEN 32
548
0
#define SFLCAL_MAX_TRANSACTION_LEN 128
549
0
#define SFLCAL_MAX_OPERATION_LEN 128
550
0
#define SFLCAL_MAX_STATUS_LEN 64
551
552
enum SFLFlow_type_tag {
553
  /* enterprise = 0, format = ... */
554
  SFLFLOW_HEADER    = 1,      /* Packet headers are sampled */
555
  SFLFLOW_ETHERNET  = 2,      /* MAC layer information */
556
  SFLFLOW_IPV4      = 3,      /* IP version 4 data */
557
  SFLFLOW_IPV6      = 4,      /* IP version 6 data */
558
  SFLFLOW_EX_SWITCH    = 1001,      /* Extended switch information */
559
  SFLFLOW_EX_ROUTER    = 1002,      /* Extended router information */
560
  SFLFLOW_EX_GATEWAY   = 1003,      /* Extended gateway router information */
561
  SFLFLOW_EX_USER      = 1004,      /* Extended TACAS/RADIUS user information */
562
  SFLFLOW_EX_URL       = 1005,      /* Extended URL information */
563
  SFLFLOW_EX_MPLS      = 1006,      /* Extended MPLS information */
564
  SFLFLOW_EX_NAT       = 1007,      /* Extended NAT information */
565
  SFLFLOW_EX_MPLS_TUNNEL  = 1008,   /* additional MPLS information */
566
  SFLFLOW_EX_MPLS_VC      = 1009,
567
  SFLFLOW_EX_MPLS_FTN     = 1010,
568
  SFLFLOW_EX_MPLS_LDP_FEC = 1011,
569
  SFLFLOW_EX_VLAN_TUNNEL  = 1012,   /* VLAN stack */
570
  SFLFLOW_EX_80211_PAYLOAD = 1013,
571
  SFLFLOW_EX_80211_RX      = 1014,
572
  SFLFLOW_EX_80211_TX      = 1015,
573
  SFLFLOW_EX_AGGREGATION   = 1016,
574
  SFLFLOW_EX_SOCKET4       = 2100,
575
  SFLFLOW_EX_SOCKET6       = 2101,
576
  SFLFLOW_MEMCACHE         = 2200,
577
  SFLFLOW_HTTP             = 2201,
578
  SFLFLOW_CAL             = (4300 << 12) + 5,  /* 4300 is InMon enterprise no. */
579
};
580
581
typedef union _SFLFlow_type {
582
  SFLSampled_header header;
583
  SFLSampled_ethernet ethernet;
584
  SFLSampled_ipv4 ipv4;
585
  SFLSampled_ipv6 ipv6;
586
  SFLSampled_memcache memcache;
587
  SFLSampled_http http;
588
  SFLSampled_CAL cal;
589
  SFLExtended_switch sw;
590
  SFLExtended_router router;
591
  SFLExtended_gateway gateway;
592
  SFLExtended_user user;
593
  SFLExtended_url url;
594
  SFLExtended_mpls mpls;
595
  SFLExtended_nat nat;
596
  SFLExtended_mpls_tunnel mpls_tunnel;
597
  SFLExtended_mpls_vc mpls_vc;
598
  SFLExtended_mpls_FTN mpls_ftn;
599
  SFLExtended_mpls_LDP_FEC mpls_ldp_fec;
600
  SFLExtended_vlan_tunnel vlan_tunnel;
601
  SFLExtended_wifi_payload wifi_payload;
602
  SFLExtended_wifi_rx wifi_rx;
603
  SFLExtended_wifi_tx wifi_tx;
604
  SFLExtended_aggregation aggregation;
605
  SFLExtended_socket_ipv4 socket4;
606
  SFLExtended_socket_ipv6 socket6;
607
} SFLFlow_type;
608
609
typedef struct _SFLFlow_sample_element {
610
  struct _SFLFlow_sample_element *nxt;
611
  u_int32_t tag;  /* SFLFlow_type_tag */
612
  u_int32_t length;
613
  SFLFlow_type flowType;
614
} SFLFlow_sample_element;
615
616
enum SFL_sample_tag {
617
  SFLFLOW_SAMPLE = 1,              /* enterprise = 0 : format = 1 */
618
  SFLCOUNTERS_SAMPLE = 2,          /* enterprise = 0 : format = 2 */
619
  SFLFLOW_SAMPLE_EXPANDED = 3,     /* enterprise = 0 : format = 3 */
620
  SFLCOUNTERS_SAMPLE_EXPANDED = 4  /* enterprise = 0 : format = 4 */
621
};
622
623
typedef struct _SFLFlow_Pdu {
624
  struct _SFLFlow_Pdu *nxt;
625
  u_int32_t num_elements;
626
  SFLFlow_sample_element *elements;
627
} SFLFlow_Pdu;
628
629
630
/* Format of a single flow sample */
631
632
typedef struct _SFLFlow_sample {
633
  /* u_int32_t tag;    */         /* SFL_sample_tag -- enterprise = 0 : format = 1 */
634
  /* u_int32_t length; */
635
  u_int32_t sequence_number;      /* Incremented with each flow sample
636
             generated */
637
  u_int32_t source_id;            /* fsSourceId */
638
  u_int32_t sampling_rate;        /* fsPacketSamplingRate */
639
  u_int32_t sample_pool;          /* Total number of packets that could have been
640
             sampled (i.e. packets skipped by sampling
641
             process + total number of samples) */
642
  u_int32_t drops;                /* Number of times a packet was dropped due to
643
             lack of resources */
644
  u_int32_t input;                /* SNMP ifIndex of input interface.
645
             0 if interface is not known. */
646
  u_int32_t output;               /* SNMP ifIndex of output interface,
647
             0 if interface is not known.
648
             Set most significant bit to indicate
649
             multiple destination interfaces
650
             (i.e. in case of broadcast or multicast)
651
             and set lower order bits to indicate
652
             number of destination interfaces.
653
             Examples:
654
             0x00000002  indicates ifIndex = 2
655
             0x00000000  ifIndex unknown.
656
             0x80000007  indicates a packet sent
657
             to 7 interfaces.
658
             0x80000000  indicates a packet sent to
659
             an unknown number of
660
             interfaces greater than 1.*/
661
  u_int32_t num_elements;
662
  SFLFlow_sample_element *elements;
663
} SFLFlow_sample;
664
665
/* same thing, but the expanded version (for full 32-bit ifIndex numbers) */
666
667
typedef struct _SFLFlow_sample_expanded {
668
  /* u_int32_t tag;    */         /* SFL_sample_tag -- enterprise = 0 : format = 1 */
669
  /* u_int32_t length; */
670
  u_int32_t sequence_number;      /* Incremented with each flow sample
671
             generated */
672
  u_int32_t ds_class;             /* EXPANDED */
673
  u_int32_t ds_index;             /* EXPANDED */
674
  u_int32_t sampling_rate;        /* fsPacketSamplingRate */
675
  u_int32_t sample_pool;          /* Total number of packets that could have been
676
             sampled (i.e. packets skipped by sampling
677
             process + total number of samples) */
678
  u_int32_t drops;                /* Number of times a packet was dropped due to
679
             lack of resources */
680
  u_int32_t inputFormat;          /* EXPANDED */
681
  u_int32_t input;                /* SNMP ifIndex of input interface.
682
             0 if interface is not known. */
683
  u_int32_t outputFormat;         /* EXPANDED */
684
  u_int32_t output;               /* SNMP ifIndex of output interface,
685
             0 if interface is not known. */
686
  u_int32_t num_elements;
687
  SFLFlow_sample_element *elements;
688
} SFLFlow_sample_expanded;
689
690
/* Counter types */
691
692
/* Generic interface counters - see RFC 1573, 2233 */
693
694
typedef struct _SFLIf_counters {
695
  u_int32_t ifIndex;
696
  u_int32_t ifType;
697
  u_int64_t ifSpeed;
698
  u_int32_t ifDirection;        /* Derived from MAU MIB (RFC 2668)
699
           0 = unknown, 1 = full-duplex,
700
           2 = half-duplex, 3 = in, 4 = out */
701
  u_int32_t ifStatus;           /* bit field with the following bits assigned:
702
           bit 0 = ifAdminStatus (0 = down, 1 = up)
703
           bit 1 = ifOperStatus (0 = down, 1 = up) */
704
  u_int64_t ifInOctets;
705
  u_int32_t ifInUcastPkts;
706
  u_int32_t ifInMulticastPkts;
707
  u_int32_t ifInBroadcastPkts;
708
  u_int32_t ifInDiscards;
709
  u_int32_t ifInErrors;
710
  u_int32_t ifInUnknownProtos;
711
  u_int64_t ifOutOctets;
712
  u_int32_t ifOutUcastPkts;
713
  u_int32_t ifOutMulticastPkts;
714
  u_int32_t ifOutBroadcastPkts;
715
  u_int32_t ifOutDiscards;
716
  u_int32_t ifOutErrors;
717
  u_int32_t ifPromiscuousMode;
718
} SFLIf_counters;
719
720
/* Ethernet interface counters - see RFC 2358 */
721
typedef struct _SFLEthernet_counters {
722
  u_int32_t dot3StatsAlignmentErrors;
723
  u_int32_t dot3StatsFCSErrors;
724
  u_int32_t dot3StatsSingleCollisionFrames;
725
  u_int32_t dot3StatsMultipleCollisionFrames;
726
  u_int32_t dot3StatsSQETestErrors;
727
  u_int32_t dot3StatsDeferredTransmissions;
728
  u_int32_t dot3StatsLateCollisions;
729
  u_int32_t dot3StatsExcessiveCollisions;
730
  u_int32_t dot3StatsInternalMacTransmitErrors;
731
  u_int32_t dot3StatsCarrierSenseErrors;
732
  u_int32_t dot3StatsFrameTooLongs;
733
  u_int32_t dot3StatsInternalMacReceiveErrors;
734
  u_int32_t dot3StatsSymbolErrors;
735
} SFLEthernet_counters;
736
737
/* Token ring counters - see RFC 1748 */
738
739
typedef struct _SFLTokenring_counters {
740
  u_int32_t dot5StatsLineErrors;
741
  u_int32_t dot5StatsBurstErrors;
742
  u_int32_t dot5StatsACErrors;
743
  u_int32_t dot5StatsAbortTransErrors;
744
  u_int32_t dot5StatsInternalErrors;
745
  u_int32_t dot5StatsLostFrameErrors;
746
  u_int32_t dot5StatsReceiveCongestions;
747
  u_int32_t dot5StatsFrameCopiedErrors;
748
  u_int32_t dot5StatsTokenErrors;
749
  u_int32_t dot5StatsSoftErrors;
750
  u_int32_t dot5StatsHardErrors;
751
  u_int32_t dot5StatsSignalLoss;
752
  u_int32_t dot5StatsTransmitBeacons;
753
  u_int32_t dot5StatsRecoverys;
754
  u_int32_t dot5StatsLobeWires;
755
  u_int32_t dot5StatsRemoves;
756
  u_int32_t dot5StatsSingles;
757
  u_int32_t dot5StatsFreqErrors;
758
} SFLTokenring_counters;
759
760
/* 100 BaseVG interface counters - see RFC 2020 */
761
762
typedef struct _SFLVg_counters {
763
  u_int32_t dot12InHighPriorityFrames;
764
  u_int64_t dot12InHighPriorityOctets;
765
  u_int32_t dot12InNormPriorityFrames;
766
  u_int64_t dot12InNormPriorityOctets;
767
  u_int32_t dot12InIPMErrors;
768
  u_int32_t dot12InOversizeFrameErrors;
769
  u_int32_t dot12InDataErrors;
770
  u_int32_t dot12InNullAddressedFrames;
771
  u_int32_t dot12OutHighPriorityFrames;
772
  u_int64_t dot12OutHighPriorityOctets;
773
  u_int32_t dot12TransitionIntoTrainings;
774
  u_int64_t dot12HCInHighPriorityOctets;
775
  u_int64_t dot12HCInNormPriorityOctets;
776
  u_int64_t dot12HCOutHighPriorityOctets;
777
} SFLVg_counters;
778
779
typedef struct _SFLVlan_counters {
780
  u_int32_t vlan_id;
781
  u_int64_t octets;
782
  u_int32_t ucastPkts;
783
  u_int32_t multicastPkts;
784
  u_int32_t broadcastPkts;
785
  u_int32_t discards;
786
} SFLVlan_counters;
787
788
typedef struct _SFLWifi_counters {
789
  u_int32_t dot11TransmittedFragmentCount;
790
  u_int32_t dot11MulticastTransmittedFrameCount;
791
  u_int32_t dot11FailedCount;
792
  u_int32_t dot11RetryCount;
793
  u_int32_t dot11MultipleRetryCount;
794
  u_int32_t dot11FrameDuplicateCount;
795
  u_int32_t dot11RTSSuccessCount;
796
  u_int32_t dot11RTSFailureCount;
797
  u_int32_t dot11ACKFailureCount;
798
  u_int32_t dot11ReceivedFragmentCount;
799
  u_int32_t dot11MulticastReceivedFrameCount;
800
  u_int32_t dot11FCSErrorCount;
801
  u_int32_t dot11TransmittedFrameCount;
802
  u_int32_t dot11WEPUndecryptableCount;
803
  u_int32_t dot11QoSDiscardedFragmentCount;
804
  u_int32_t dot11AssociatedStationCount;
805
  u_int32_t dot11QoSCFPollsReceivedCount;
806
  u_int32_t dot11QoSCFPollsUnusedCount;
807
  u_int32_t dot11QoSCFPollsUnusableCount;
808
  u_int32_t dot11QoSCFPollsLostCount;
809
} SFLWifi_counters;
810
811
/* Processor Information */
812
/* opaque = counter_data; enterprise = 0; format = 1001 */
813
814
typedef struct _SFLProcessor_counters {
815
  u_int32_t five_sec_cpu;  /* 5 second average CPU utilization */
816
  u_int32_t one_min_cpu;   /* 1 minute average CPU utilization */
817
  u_int32_t five_min_cpu;  /* 5 minute average CPU utilization */
818
  u_int64_t total_memory;  /* total memory (in bytes) */
819
  u_int64_t free_memory;   /* free memory (in bytes) */
820
} SFLProcessor_counters;
821
822
typedef struct _SFLRadio_counters {
823
  u_int32_t elapsed_time;         /* elapsed time in ms */
824
  u_int32_t on_channel_time;      /* time in ms spent on channel */
825
  u_int32_t on_channel_busy_time; /* time in ms spent on channel and busy */
826
} SFLRadio_counters;
827
828
/* host sflow */
829
830
enum SFLMachine_type {
831
  SFLMT_unknown = 0,
832
  SFLMT_other   = 1,
833
  SFLMT_x86     = 2,
834
  SFLMT_x86_64  = 3,
835
  SFLMT_ia64    = 4,
836
  SFLMT_sparc   = 5,
837
  SFLMT_alpha   = 6,
838
  SFLMT_powerpc = 7,
839
  SFLMT_m68k    = 8,
840
  SFLMT_mips    = 9,
841
  SFLMT_arm     = 10,
842
  SFLMT_hppa    = 11,
843
  SFLMT_s390    = 12
844
};
845
846
enum SFLOS_name {
847
  SFLOS_unknown   = 0,
848
  SFLOS_other     = 1,
849
  SFLOS_linux     = 2,
850
  SFLOS_windows   = 3,
851
  SFLOS_darwin    = 4,
852
  SFLOS_hpux      = 5,
853
  SFLOS_aix       = 6,
854
  SFLOS_dragonfly = 7,
855
  SFLOS_freebsd   = 8,
856
  SFLOS_netbsd    = 9,
857
  SFLOS_openbsd   = 10,
858
  SFLOS_osf       = 11,
859
  SFLOS_solaris   = 12
860
};
861
862
typedef struct _SFLMacAddress {
863
  u_int8_t mac[8];
864
} SFLMacAddress;
865
866
typedef struct _SFLAdaptor {
867
  u_int32_t ifIndex;
868
  u_int32_t num_macs;
869
  SFLMacAddress macs[1];
870
} SFLAdaptor;
871
872
typedef struct _SFLAdaptorList {
873
  u_int32_t capacity;
874
  u_int32_t num_adaptors;
875
  SFLAdaptor **adaptors;
876
} SFLAdaptorList;
877
878
typedef struct _SFLHost_parent {
879
  u_int32_t dsClass;       /* sFlowDataSource class */
880
  u_int32_t dsIndex;       /* sFlowDataSource index */
881
} SFLHost_parent;
882
883
884
0
#define SFL_MAX_HOSTNAME_LEN 64
885
0
#define SFL_MAX_OSRELEASE_LEN 32
886
887
typedef struct _SFLHostId {
888
  SFLString hostname;
889
  u_char uuid[16];
890
  u_int32_t machine_type; /* enum SFLMachine_type */
891
  u_int32_t os_name;      /* enum SFLOS_name */
892
  SFLString os_release;  /* max len 32 bytes */
893
} SFLHostId;
894
895
typedef struct _SFLHost_nio_counters {
896
  u_int64_t bytes_in;
897
  u_int32_t pkts_in;
898
  u_int32_t errs_in;
899
  u_int32_t drops_in;
900
  u_int64_t bytes_out;
901
  u_int32_t pkts_out;
902
  u_int32_t errs_out;
903
  u_int32_t drops_out;
904
} SFLHost_nio_counters;
905
906
typedef struct _SFLHost_cpu_counters {
907
  float load_one;      /* 1 minute load avg. */
908
  float load_five;     /* 5 minute load avg. */
909
  float load_fifteen;  /* 15 minute load avg. */
910
  u_int32_t proc_run;   /* running threads */
911
  u_int32_t proc_total; /* total threads */
912
  u_int32_t cpu_num;    /* # CPU cores */
913
  u_int32_t cpu_speed;  /* speed in MHz of CPU */
914
  u_int32_t uptime;     /* seconds since last reboot */
915
  u_int32_t cpu_user;   /* time executing in user mode processes (ms) */
916
  u_int32_t cpu_nice;   /* time executing niced processs (ms) */
917
  u_int32_t cpu_system; /* time executing kernel mode processes (ms) */
918
  u_int32_t cpu_idle;   /* idle time (ms) */
919
  u_int32_t cpu_wio;    /* time waiting for I/O to complete (ms) */
920
  u_int32_t cpu_intr;   /* time servicing interrupts (ms) */
921
  u_int32_t cpu_sintr;  /* time servicing softirqs (ms) */
922
  u_int32_t interrupts; /* interrupt count */
923
  u_int32_t contexts;   /* context switch count */
924
} SFLHost_cpu_counters;
925
926
typedef struct _SFLHost_mem_counters {
927
  u_int64_t mem_total;    /* total bytes */
928
  u_int64_t mem_free;     /* free bytes */
929
  u_int64_t mem_shared;   /* shared bytes */
930
  u_int64_t mem_buffers;  /* buffers bytes */
931
  u_int64_t mem_cached;   /* cached bytes */
932
  u_int64_t swap_total;   /* swap total bytes */
933
  u_int64_t swap_free;    /* swap free bytes */
934
  u_int32_t page_in;      /* page in count */
935
  u_int32_t page_out;     /* page out count */
936
  u_int32_t swap_in;      /* swap in count */
937
  u_int32_t swap_out;     /* swap out count */
938
} SFLHost_mem_counters;
939
940
typedef struct _SFLHost_dsk_counters {
941
  u_int64_t disk_total;
942
  u_int64_t disk_free;
943
  u_int32_t part_max_used;   /* as percent * 100, so 100==1% */
944
  u_int32_t reads;           /* reads issued */
945
  u_int64_t bytes_read;      /* bytes read */
946
  u_int32_t read_time;       /* read time (ms) */
947
  u_int32_t writes;          /* writes completed */
948
  u_int64_t bytes_written;   /* bytes written */
949
  u_int32_t write_time;      /* write time (ms) */
950
} SFLHost_dsk_counters;
951
952
/* Virtual Node Statistics */
953
/* opaque = counter_data; enterprise = 0; format = 2100 */
954
955
typedef struct _SFLHost_vrt_node_counters {
956
  u_int32_t mhz;           /* expected CPU frequency */
957
  u_int32_t cpus;          /* the number of active CPUs */
958
  u_int64_t memory;        /* memory size in bytes */
959
  u_int64_t memory_free;   /* unassigned memory in bytes */
960
  u_int32_t num_domains;   /* number of active domains */
961
} SFLHost_vrt_node_counters;
962
963
/* Virtual Domain Statistics */
964
/* opaque = counter_data; enterprise = 0; format = 2101 */
965
966
/* virDomainState imported from libvirt.h */
967
enum SFLVirDomainState {
968
  SFL_VIR_DOMAIN_NOSTATE = 0, /* no state */
969
  SFL_VIR_DOMAIN_RUNNING = 1, /* the domain is running */
970
  SFL_VIR_DOMAIN_BLOCKED = 2, /* the domain is blocked on resource */
971
  SFL_VIR_DOMAIN_PAUSED  = 3, /* the domain is paused by user */
972
  SFL_VIR_DOMAIN_SHUTDOWN= 4, /* the domain is being shut down */
973
  SFL_VIR_DOMAIN_SHUTOFF = 5, /* the domain is shut off */
974
  SFL_VIR_DOMAIN_CRASHED = 6  /* the domain is crashed */
975
};
976
977
typedef struct _SFLHost_vrt_cpu_counters {
978
  u_int32_t state;       /* virtDomainState */
979
  u_int32_t cpuTime;     /* the CPU time used in mS */
980
  u_int32_t cpuCount;    /* number of virtual CPUs for the domain */
981
} SFLHost_vrt_cpu_counters;
982
983
/* Virtual Domain Memory statistics */
984
/* opaque = counter_data; enterprise = 0; format = 2102 */
985
986
typedef struct _SFLHost_vrt_mem_counters {
987
  u_int64_t memory;      /* memory in bytes used by domain */
988
  u_int64_t maxMemory;   /* memory in bytes allowed */
989
} SFLHost_vrt_mem_counters;
990
991
/* Virtual Domain Disk statistics */
992
/* opaque = counter_data; enterprise = 0; format = 2103 */
993
994
typedef struct _SFLHost_vrt_dsk_counters {
995
  u_int64_t capacity;   /* logical size in bytes */
996
  u_int64_t allocation; /* current allocation in bytes */
997
  u_int64_t available;  /* remaining free bytes */
998
  u_int32_t rd_req;     /* number of read requests */
999
  u_int64_t rd_bytes;   /* number of read bytes */
1000
  u_int32_t wr_req;     /* number of write requests */
1001
  u_int64_t wr_bytes;   /* number of  written bytes */
1002
  u_int32_t errs;        /* read/write errors */
1003
} SFLHost_vrt_dsk_counters;
1004
1005
/* Virtual Domain Network statistics */
1006
/* opaque = counter_data; enterprise = 0; format = 2104 */
1007
1008
typedef struct _SFLHost_vrt_nio_counters {
1009
  u_int64_t bytes_in;
1010
  u_int32_t pkts_in;
1011
  u_int32_t errs_in;
1012
  u_int32_t drops_in;
1013
  u_int64_t bytes_out;
1014
  u_int32_t pkts_out;
1015
  u_int32_t errs_out;
1016
  u_int32_t drops_out;
1017
} SFLHost_vrt_nio_counters;
1018
1019
typedef struct _SFLMemcache_counters {
1020
  u_int32_t uptime;     /* Number of seconds this server has been running */
1021
  u_int32_t rusage_user;    /* Accumulated user time for this process (ms)*/
1022
  u_int32_t rusage_system;  /* Accumulated system time for this process (ms)*/
1023
  u_int32_t curr_connections; /* Number of open connections */
1024
  u_int32_t total_connections; /* Total number of connections opened since
1025
          the server started running */
1026
  u_int32_t connection_structures; /* Number of connection structures
1027
              allocated by the server */
1028
  u_int32_t cmd_get;        /* Cumulative number of retrieval requests */
1029
  u_int32_t cmd_set;        /* Cumulative number of storage requests */
1030
  u_int32_t cmd_flush;      /* */
1031
  u_int32_t get_hits;       /* Number of keys that have been requested and
1032
             found present */
1033
  u_int32_t get_misses;     /* Number of items that have been requested
1034
             and not found */
1035
  u_int32_t delete_misses;
1036
  u_int32_t delete_hits;
1037
  u_int32_t incr_misses;
1038
  u_int32_t incr_hits;
1039
  u_int32_t decr_misses;
1040
  u_int32_t decr_hits;
1041
  u_int32_t cas_misses;
1042
  u_int32_t cas_hits;
1043
  u_int32_t cas_badval;
1044
  u_int32_t auth_cmds;
1045
  u_int32_t auth_errors;
1046
  u_int64_t bytes_read;
1047
  u_int64_t bytes_written;
1048
  u_int32_t limit_maxbytes;
1049
  u_int32_t accepting_conns;
1050
  u_int32_t listen_disabled_num;
1051
  u_int32_t threads;
1052
  u_int32_t conn_yields;
1053
  u_int64_t bytes;
1054
  u_int32_t curr_items;
1055
  u_int32_t total_items;
1056
  u_int32_t evictions;
1057
} SFLMemcache_counters;
1058
1059
typedef struct _SFLHTTP_counters {
1060
  u_int32_t method_option_count;
1061
  u_int32_t method_get_count;
1062
  u_int32_t method_head_count;
1063
  u_int32_t method_post_count;
1064
  u_int32_t method_put_count;
1065
  u_int32_t method_delete_count;
1066
  u_int32_t method_trace_count;
1067
  u_int32_t methd_connect_count;
1068
  u_int32_t method_other_count;
1069
  u_int32_t status_1XX_count;
1070
  u_int32_t status_2XX_count;
1071
  u_int32_t status_3XX_count;
1072
  u_int32_t status_4XX_count;
1073
  u_int32_t status_5XX_count;
1074
  u_int32_t status_other_count;
1075
} SFLHTTP_counters;
1076
1077
1078
typedef struct _SFLCAL_counters {
1079
  u_int32_t transactions;
1080
  u_int32_t errors;
1081
  u_int64_t duration_uS;
1082
} SFLCAL_counters;
1083
1084
/* Counters data */
1085
1086
enum SFLCounters_type_tag {
1087
  /* enterprise = 0, format = ... */
1088
  SFLCOUNTERS_GENERIC      = 1,
1089
  SFLCOUNTERS_ETHERNET     = 2,
1090
  SFLCOUNTERS_TOKENRING    = 3,
1091
  SFLCOUNTERS_VG           = 4,
1092
  SFLCOUNTERS_VLAN         = 5,
1093
  SFLCOUNTERS_80211        = 6,
1094
  SFLCOUNTERS_PROCESSOR    = 1001,
1095
  SFLCOUNTERS_RADIO        = 1002,
1096
  SFLCOUNTERS_HOST_HID     = 2000, /* host id */
1097
  SFLCOUNTERS_ADAPTORS     = 2001, /* host adaptors */
1098
  SFLCOUNTERS_HOST_PAR     = 2002, /* host parent */
1099
  SFLCOUNTERS_HOST_CPU     = 2003, /* host cpu  */
1100
  SFLCOUNTERS_HOST_MEM     = 2004, /* host memory  */
1101
  SFLCOUNTERS_HOST_DSK     = 2005, /* host storage I/O  */
1102
  SFLCOUNTERS_HOST_NIO     = 2006, /* host network I/O */
1103
  SFLCOUNTERS_HOST_VRT_NODE = 2100, /* host virt node */
1104
  SFLCOUNTERS_HOST_VRT_CPU  = 2101, /* host virt cpu */
1105
  SFLCOUNTERS_HOST_VRT_MEM  = 2102, /* host virt mem */
1106
  SFLCOUNTERS_HOST_VRT_DSK  = 2103, /* host virt storage */
1107
  SFLCOUNTERS_HOST_VRT_NIO  = 2104, /* host virt network I/O */
1108
  SFLCOUNTERS_MEMCACHE      = 2200, /* memcached */
1109
  SFLCOUNTERS_HTTP          = 2201, /* http */
1110
  SFLCOUNTERS_CAL          = (4300 << 12) + 5,
1111
};
1112
1113
typedef union _SFLCounters_type {
1114
  SFLIf_counters generic;
1115
  SFLEthernet_counters ethernet;
1116
  SFLTokenring_counters tokenring;
1117
  SFLVg_counters vg;
1118
  SFLVlan_counters vlan;
1119
  SFLWifi_counters wifi;
1120
  SFLProcessor_counters processor;
1121
  SFLRadio_counters radio;
1122
  SFLHostId hostId;
1123
  SFLAdaptorList *adaptors;
1124
  SFLHost_parent host_par;
1125
  SFLHost_cpu_counters host_cpu;
1126
  SFLHost_mem_counters host_mem;
1127
  SFLHost_dsk_counters host_dsk;
1128
  SFLHost_nio_counters host_nio;
1129
  SFLHost_vrt_node_counters host_vrt_node;
1130
  SFLHost_vrt_cpu_counters host_vrt_cpu;
1131
  SFLHost_vrt_mem_counters host_vrt_mem;
1132
  SFLHost_vrt_dsk_counters host_vrt_dsk;
1133
  SFLHost_vrt_nio_counters host_vrt_nio;
1134
  SFLMemcache_counters memcache;
1135
  SFLHTTP_counters http;
1136
  SFLCAL_counters cal;
1137
} SFLCounters_type;
1138
1139
typedef struct _SFLCounters_sample_element {
1140
  struct _SFLCounters_sample_element *nxt; /* linked list */
1141
  u_int32_t tag; /* SFLCounters_type_tag */
1142
  u_int32_t length;
1143
  SFLCounters_type counterBlock;
1144
} SFLCounters_sample_element;
1145
1146
typedef struct _SFLCounters_sample {
1147
  /* u_int32_t tag;    */       /* SFL_sample_tag -- enterprise = 0 : format = 2 */
1148
  /* u_int32_t length; */
1149
  u_int32_t sequence_number;    /* Incremented with each counters sample
1150
           generated by this source_id */
1151
  u_int32_t source_id;          /* fsSourceId */
1152
  u_int32_t num_elements;
1153
  SFLCounters_sample_element *elements;
1154
} SFLCounters_sample;
1155
1156
/* same thing, but the expanded version, so ds_index can be a full 32 bits */
1157
typedef struct _SFLCounters_sample_expanded {
1158
  /* u_int32_t tag;    */       /* SFL_sample_tag -- enterprise = 0 : format = 2 */
1159
  /* u_int32_t length; */
1160
  u_int32_t sequence_number;    /* Incremented with each counters sample
1161
           generated by this source_id */
1162
  u_int32_t ds_class;           /* EXPANDED */
1163
  u_int32_t ds_index;           /* EXPANDED */
1164
  u_int32_t num_elements;
1165
  SFLCounters_sample_element *elements;
1166
} SFLCounters_sample_expanded;
1167
1168
#define SFLADD_ELEMENT(_sm, _el) do { (_el)->nxt = (_sm)->elements; (_sm)->elements = (_el); } while(0)
1169
1170
/* Format of a sample datagram */
1171
1172
enum SFLDatagram_version {
1173
  SFLDATAGRAM_VERSION2 = 2,
1174
  SFLDATAGRAM_VERSION4 = 4,
1175
  SFLDATAGRAM_VERSION5 = 5
1176
};
1177
1178
typedef struct _SFLSample_datagram_hdr {
1179
  u_int32_t datagram_version;      /* (enum SFLDatagram_version) = VERSION5 = 5 */
1180
  SFLAddress agent_address;        /* IP address of sampling agent */
1181
  u_int32_t sub_agent_id;          /* Used to distinguishing between datagram
1182
                                      streams from separate agent sub entities
1183
                                      within an device. */
1184
  u_int32_t sequence_number;       /* Incremented with each sample datagram
1185
              generated */
1186
  u_int32_t uptime;                /* Current time (in milliseconds since device
1187
              last booted). Should be set as close to
1188
              datagram transmission time as possible.*/
1189
  u_int32_t num_records;           /* Number of tag-len-val flow/counter records to follow */
1190
} SFLSample_datagram_hdr;
1191
1192
#define SFL_MAX_DATAGRAM_SIZE 1500
1193
#define SFL_MIN_DATAGRAM_SIZE 200
1194
#define SFL_DEFAULT_DATAGRAM_SIZE 1400
1195
1196
#define SFL_DATA_PAD 400
1197
1198
enum INMAddress_type {
1199
  INMADDRESSTYPE_IP_V4 = 1,
1200
  INMADDRESSTYPE_IP_V6 = 2
1201
};
1202
1203
typedef union _INMAddress_value {
1204
  SFLIPv4 ip_v4;
1205
  SFLIPv6 ip_v6;
1206
} INMAddress_value;
1207
1208
typedef struct _INMAddress {
1209
  u_int32_t type;           /* enum INMAddress_type */
1210
  INMAddress_value address;
1211
} INMAddress;
1212
1213
/* Packet header data */
1214
1215
#define INM_MAX_HEADER_SIZE 256   /* The maximum sampled header size. */
1216
#define INM_DEFAULT_HEADER_SIZE 128
1217
#define INM_DEFAULT_COLLECTOR_PORT 6343
1218
#define INM_DEFAULT_SAMPLING_RATE 400
1219
1220
/* The header protocol describes the format of the sampled header */
1221
enum INMHeader_protocol {
1222
  INMHEADER_ETHERNET_ISO8023     = 1,
1223
  INMHEADER_ISO88024_TOKENBUS    = 2,
1224
  INMHEADER_ISO88025_TOKENRING   = 3,
1225
  INMHEADER_FDDI                 = 4,
1226
  INMHEADER_FRAME_RELAY          = 5,
1227
  INMHEADER_X25                  = 6,
1228
  INMHEADER_PPP                  = 7,
1229
  INMHEADER_SMDS                 = 8,
1230
  INMHEADER_AAL5                 = 9,
1231
  INMHEADER_AAL5_IP              = 10, /* e.g. Cisco AAL5 mux */
1232
  INMHEADER_IPv4                 = 11,
1233
  INMHEADER_IPv6                 = 12
1234
};
1235
1236
typedef struct _INMSampled_header {
1237
  u_int32_t header_protocol;            /* (enum INMHeader_protocol) */
1238
  u_int32_t frame_length;               /* Original length of packet before sampling */
1239
  u_int32_t header_length;              /* length of sampled header bytes to follow */
1240
  u_int8_t header[INM_MAX_HEADER_SIZE]; /* Header bytes */
1241
} INMSampled_header;
1242
1243
/* Packet IP version 4 data */
1244
1245
typedef struct _INMSampled_ipv4 {
1246
  u_int32_t length;      /* The length of the IP packet
1247
          excluding lower layer encapsulations */
1248
  u_int32_t protocol;    /* IP Protocol type (for example, TCP = 6, UDP = 17) */
1249
  SFLIPv4 src_ip; /* Source IP Address */
1250
  SFLIPv4 dst_ip; /* Destination IP Address */
1251
  u_int32_t src_port;    /* TCP/UDP source port number or equivalent */
1252
  u_int32_t dst_port;    /* TCP/UDP destination port number or equivalent */
1253
  u_int32_t tcp_flags;   /* TCP flags */
1254
  u_int32_t tos;         /* IP type of service */
1255
} INMSampled_ipv4;
1256
1257
/* Packet IP version 6 data */
1258
1259
typedef struct _INMSampled_ipv6 {
1260
  u_int32_t length;       /* The length of the IP packet
1261
           excluding lower layer encapsulations */
1262
  u_int32_t protocol;     /* IP Protocol type (for example, TCP = 6, UDP = 17) */
1263
  SFLIPv6 src_ip; /* Source IP Address */
1264
  SFLIPv6 dst_ip; /* Destination IP Address */
1265
  u_int32_t src_port;     /* TCP/UDP source port number or equivalent */
1266
  u_int32_t dst_port;     /* TCP/UDP destination port number or equivalent */
1267
  u_int32_t tcp_flags;    /* TCP flags */
1268
  u_int32_t tos;          /* IP type of service */
1269
} INMSampled_ipv6;
1270
1271
1272
/* Packet data */
1273
1274
enum INMPacket_information_type {
1275
  INMPACKETTYPE_HEADER  = 1,      /* Packet headers are sampled */
1276
  INMPACKETTYPE_IPV4    = 2,      /* IP version 4 data */
1277
  INMPACKETTYPE_IPV6    = 3       /* IP version 4 data */
1278
};
1279
1280
typedef union _INMPacket_data_type {
1281
  INMSampled_header header;
1282
  INMSampled_ipv4 ipv4;
1283
  INMSampled_ipv6 ipv6;
1284
} INMPacket_data_type;
1285
1286
/* Extended data types */
1287
1288
/* Extended switch data */
1289
1290
typedef struct _INMExtended_switch {
1291
  u_int32_t src_vlan;       /* The 802.1Q VLAN id of incomming frame */
1292
  u_int32_t src_priority;   /* The 802.1p priority */
1293
  u_int32_t dst_vlan;       /* The 802.1Q VLAN id of outgoing frame */
1294
  u_int32_t dst_priority;   /* The 802.1p priority */
1295
} INMExtended_switch;
1296
1297
/* Extended router data */
1298
1299
typedef struct _INMExtended_router {
1300
  INMAddress nexthop;               /* IP address of next hop router */
1301
  u_int32_t src_mask;               /* Source address prefix mask bits */
1302
  u_int32_t dst_mask;               /* Destination address prefix mask bits */
1303
} INMExtended_router;
1304
1305
/* Extended gateway data */
1306
1307
enum INMExtended_as_path_segment_type {
1308
  INMEXTENDED_AS_SET = 1,      /* Unordered set of ASs */
1309
  INMEXTENDED_AS_SEQUENCE = 2  /* Ordered sequence of ASs */
1310
};
1311
1312
typedef struct _INMExtended_as_path_segment {
1313
  u_int32_t type;   /* enum INMExtended_as_path_segment_type */
1314
  u_int32_t length; /* number of AS numbers in set/sequence */
1315
  union {
1316
    u_int32_t *set;
1317
    u_int32_t *seq;
1318
  } as;
1319
} INMExtended_as_path_segment;
1320
1321
/* note: the INMExtended_gateway structure has changed between v2 and v4.
1322
   Here is the old version first... */
1323
1324
typedef struct _INMExtended_gateway_v2 {
1325
  u_int32_t as;                             /* AS number for this gateway */
1326
  u_int32_t src_as;                         /* AS number of source (origin) */
1327
  u_int32_t src_peer_as;                    /* AS number of source peer */
1328
  u_int32_t dst_as_path_length;             /* number of AS numbers in path */
1329
  u_int32_t *dst_as_path;
1330
} INMExtended_gateway_v2;
1331
1332
/* now here is the new version... */
1333
1334
typedef struct _INMExtended_gateway_v4 {
1335
  u_int32_t as;                             /* AS number for this gateway */
1336
  u_int32_t src_as;                         /* AS number of source (origin) */
1337
  u_int32_t src_peer_as;                    /* AS number of source peer */
1338
  u_int32_t dst_as_path_segments;           /* number of segments in path */
1339
  INMExtended_as_path_segment *dst_as_path; /* list of seqs or sets */
1340
  u_int32_t communities_length;             /* number of communities */
1341
  u_int32_t *communities;                   /* set of communities */
1342
  u_int32_t localpref;                      /* LocalPref associated with this route */
1343
} INMExtended_gateway_v4;
1344
1345
/* Extended user data */
1346
typedef struct _INMExtended_user {
1347
  u_int32_t src_user_len;
1348
  char *src_user;
1349
  u_int32_t dst_user_len;
1350
  char *dst_user;
1351
} INMExtended_user;
1352
enum INMExtended_url_direction {
1353
  INMEXTENDED_URL_SRC = 1, /* URL is associated with source address */
1354
  INMEXTENDED_URL_DST = 2  /* URL is associated with destination address */
1355
};
1356
1357
typedef struct _INMExtended_url {
1358
  u_int32_t direction; /* enum INMExtended_url_direction */
1359
  u_int32_t url_len;
1360
  char *url;
1361
} INMExtended_url;
1362
1363
/* Extended data */
1364
1365
enum INMExtended_information_type {
1366
  INMEXTENDED_SWITCH    = 1,      /* Extended switch information */
1367
  INMEXTENDED_ROUTER    = 2,      /* Extended router information */
1368
  INMEXTENDED_GATEWAY   = 3,      /* Extended gateway router information */
1369
  INMEXTENDED_USER      = 4,      /* Extended TACAS/RADIUS user information */
1370
  INMEXTENDED_URL       = 5       /* Extended URL information */
1371
};
1372
1373
/* Format of a single sample */
1374
1375
typedef struct _INMFlow_sample {
1376
  u_int32_t sequence_number;      /* Incremented with each flow sample
1377
             generated */
1378
  u_int32_t source_id;            /* fsSourceId */
1379
  u_int32_t sampling_rate;        /* fsPacketSamplingRate */
1380
  u_int32_t sample_pool;          /* Total number of packets that could have been
1381
             sampled (i.e. packets skipped by sampling
1382
             process + total number of samples) */
1383
  u_int32_t drops;                /* Number of times a packet was dropped due to
1384
             lack of resources */
1385
  u_int32_t input;                /* SNMP ifIndex of input interface.
1386
             0 if interface is not known. */
1387
  u_int32_t output;               /* SNMP ifIndex of output interface,
1388
             0 if interface is not known.
1389
             Set most significant bit to indicate
1390
             multiple destination interfaces
1391
             (i.e. in case of broadcast or multicast)
1392
             and set lower order bits to indicate
1393
             number of destination interfaces.
1394
             Examples:
1395
             0x00000002  indicates ifIndex = 2
1396
             0x00000000  ifIndex unknown.
1397
             0x80000007  indicates a packet sent
1398
             to 7 interfaces.
1399
             0x80000000  indicates a packet sent to
1400
             an unknown number of
1401
             interfaces greater than 1.*/
1402
  u_int32_t packet_data_tag;       /* enum INMPacket_information_type */
1403
  INMPacket_data_type packet_data; /* Information about sampled packet */
1404
1405
  /* in the sFlow packet spec the next field is the number of extended objects
1406
     followed by the data for each one (tagged with the type).  Here we just
1407
     provide space for each one, and flags to enable them.  The correct format
1408
     is then put together by the serialization code */
1409
  int gotSwitch;
1410
  INMExtended_switch switchDevice;
1411
  int gotRouter;
1412
  INMExtended_router router;
1413
  int gotGateway;
1414
  union {
1415
    INMExtended_gateway_v2 v2;  /* make the version explicit so that there is */
1416
    INMExtended_gateway_v4 v4;  /* less danger of mistakes when upgrading code */
1417
  } gateway;
1418
  int gotUser;
1419
  INMExtended_user user;
1420
  int gotUrl;
1421
  INMExtended_url url;
1422
} INMFlow_sample;
1423
1424
/* Counter types */
1425
1426
/* Generic interface counters - see RFC 1573, 2233 */
1427
1428
typedef struct _INMIf_counters {
1429
  u_int32_t ifIndex;
1430
  u_int32_t ifType;
1431
  u_int64_t ifSpeed;
1432
  u_int32_t ifDirection;        /* Derived from MAU MIB (RFC 2239)
1433
           0 = unknown, 1 = full-duplex,
1434
           2 = half-duplex, 3 = in, 4 = out */
1435
  u_int32_t ifStatus;           /* bit field with the following bits assigned:
1436
           bit 0 = ifAdminStatus (0 = down, 1 = up)
1437
           bit 1 = ifOperStatus (0 = down, 1 = up) */
1438
  u_int64_t ifInOctets;
1439
  u_int32_t ifInUcastPkts;
1440
  u_int32_t ifInMulticastPkts;
1441
  u_int32_t ifInBroadcastPkts;
1442
  u_int32_t ifInDiscards;
1443
  u_int32_t ifInErrors;
1444
  u_int32_t ifInUnknownProtos;
1445
  u_int64_t ifOutOctets;
1446
  u_int32_t ifOutUcastPkts;
1447
  u_int32_t ifOutMulticastPkts;
1448
  u_int32_t ifOutBroadcastPkts;
1449
  u_int32_t ifOutDiscards;
1450
  u_int32_t ifOutErrors;
1451
  u_int32_t ifPromiscuousMode;
1452
} INMIf_counters;
1453
1454
/* Ethernet interface counters - see RFC 2358 */
1455
typedef struct _INMEthernet_specific_counters {
1456
  u_int32_t dot3StatsAlignmentErrors;
1457
  u_int32_t dot3StatsFCSErrors;
1458
  u_int32_t dot3StatsSingleCollisionFrames;
1459
  u_int32_t dot3StatsMultipleCollisionFrames;
1460
  u_int32_t dot3StatsSQETestErrors;
1461
  u_int32_t dot3StatsDeferredTransmissions;
1462
  u_int32_t dot3StatsLateCollisions;
1463
  u_int32_t dot3StatsExcessiveCollisions;
1464
  u_int32_t dot3StatsInternalMacTransmitErrors;
1465
  u_int32_t dot3StatsCarrierSenseErrors;
1466
  u_int32_t dot3StatsFrameTooLongs;
1467
  u_int32_t dot3StatsInternalMacReceiveErrors;
1468
  u_int32_t dot3StatsSymbolErrors;
1469
} INMEthernet_specific_counters;
1470
1471
typedef struct _INMEthernet_counters {
1472
  INMIf_counters generic;
1473
  INMEthernet_specific_counters ethernet;
1474
} INMEthernet_counters;
1475
1476
/* FDDI interface counters - see RFC 1512 */
1477
typedef struct _INMFddi_counters {
1478
  INMIf_counters generic;
1479
} INMFddi_counters;
1480
1481
/* Token ring counters - see RFC 1748 */
1482
1483
typedef struct _INMTokenring_specific_counters {
1484
  u_int32_t dot5StatsLineErrors;
1485
  u_int32_t dot5StatsBurstErrors;
1486
  u_int32_t dot5StatsACErrors;
1487
  u_int32_t dot5StatsAbortTransErrors;
1488
  u_int32_t dot5StatsInternalErrors;
1489
  u_int32_t dot5StatsLostFrameErrors;
1490
  u_int32_t dot5StatsReceiveCongestions;
1491
  u_int32_t dot5StatsFrameCopiedErrors;
1492
  u_int32_t dot5StatsTokenErrors;
1493
  u_int32_t dot5StatsSoftErrors;
1494
  u_int32_t dot5StatsHardErrors;
1495
  u_int32_t dot5StatsSignalLoss;
1496
  u_int32_t dot5StatsTransmitBeacons;
1497
  u_int32_t dot5StatsRecoverys;
1498
  u_int32_t dot5StatsLobeWires;
1499
  u_int32_t dot5StatsRemoves;
1500
  u_int32_t dot5StatsSingles;
1501
  u_int32_t dot5StatsFreqErrors;
1502
} INMTokenring_specific_counters;
1503
1504
typedef struct _INMTokenring_counters {
1505
  INMIf_counters generic;
1506
  INMTokenring_specific_counters tokenring;
1507
} INMTokenring_counters;
1508
1509
/* 100 BaseVG interface counters - see RFC 2020 */
1510
1511
typedef struct _INMVg_specific_counters {
1512
  u_int32_t dot12InHighPriorityFrames;
1513
  u_int64_t dot12InHighPriorityOctets;
1514
  u_int32_t dot12InNormPriorityFrames;
1515
  u_int64_t dot12InNormPriorityOctets;
1516
  u_int32_t dot12InIPMErrors;
1517
  u_int32_t dot12InOversizeFrameErrors;
1518
  u_int32_t dot12InDataErrors;
1519
  u_int32_t dot12InNullAddressedFrames;
1520
  u_int32_t dot12OutHighPriorityFrames;
1521
  u_int64_t dot12OutHighPriorityOctets;
1522
  u_int32_t dot12TransitionIntoTrainings;
1523
  u_int64_t dot12HCInHighPriorityOctets;
1524
  u_int64_t dot12HCInNormPriorityOctets;
1525
  u_int64_t dot12HCOutHighPriorityOctets;
1526
} INMVg_specific_counters;
1527
1528
typedef struct _INMVg_counters {
1529
  INMIf_counters generic;
1530
  INMVg_specific_counters vg;
1531
} INMVg_counters;
1532
1533
/* WAN counters */
1534
1535
typedef struct _INMWan_counters {
1536
  INMIf_counters generic;
1537
} INMWan_counters;
1538
1539
typedef struct _INMVlan_counters {
1540
  u_int32_t vlan_id;
1541
  u_int64_t octets;
1542
  u_int32_t ucastPkts;
1543
  u_int32_t multicastPkts;
1544
  u_int32_t broadcastPkts;
1545
  u_int32_t discards;
1546
} INMVlan_counters;
1547
1548
/* Counters data */
1549
1550
enum INMCounters_version {
1551
  INMCOUNTERSVERSION_GENERIC      = 1,
1552
  INMCOUNTERSVERSION_ETHERNET     = 2,
1553
  INMCOUNTERSVERSION_TOKENRING    = 3,
1554
  INMCOUNTERSVERSION_FDDI         = 4,
1555
  INMCOUNTERSVERSION_VG           = 5,
1556
  INMCOUNTERSVERSION_WAN          = 6,
1557
  INMCOUNTERSVERSION_VLAN         = 7
1558
};
1559
1560
typedef union _INMCounters_type {
1561
  INMIf_counters generic;
1562
  INMEthernet_counters ethernet;
1563
  INMTokenring_counters tokenring;
1564
  INMFddi_counters fddi;
1565
  INMVg_counters vg;
1566
  INMWan_counters wan;
1567
  INMVlan_counters vlan;
1568
} INMCounters_type;
1569
1570
typedef struct _INMCounters_sample_hdr {
1571
  u_int32_t sequence_number;    /* Incremented with each counters sample
1572
           generated by this source_id */
1573
  u_int32_t source_id;          /* fsSourceId */
1574
  u_int32_t sampling_interval;  /* fsCounterSamplingInterval */
1575
} INMCounters_sample_hdr;
1576
1577
typedef struct _INMCounters_sample {
1578
  INMCounters_sample_hdr hdr;
1579
  u_int32_t counters_type_tag;  /* Enum INMCounters_version */
1580
  INMCounters_type counters;    /* Counter set for this interface type */
1581
} INMCounters_sample;
1582
1583
/* when I turn on optimisation with the Microsoft compiler it seems to change
1584
   the values of these enumerated types and break the program - not sure why */
1585
enum INMSample_types {
1586
  FLOWSAMPLE  = 1,
1587
  COUNTERSSAMPLE = 2
1588
};
1589
1590
typedef union _INMSample_type {
1591
  INMFlow_sample flowsample;
1592
  INMCounters_sample counterssample;
1593
} INMSample_type;
1594
1595
/* Format of a sample datagram */
1596
1597
enum INMDatagram_version {
1598
  INMDATAGRAM_VERSION2 = 2,
1599
  INMDATAGRAM_VERSION4 = 4
1600
};
1601
1602
typedef struct _INMSample_datagram_hdr {
1603
  u_int32_t datagram_version;      /* (enum INMDatagram_version) = VERSION4 */
1604
  INMAddress agent_address;        /* IP address of sampling agent */
1605
  u_int32_t sequence_number;       /* Incremented with each sample datagram
1606
              generated */
1607
  u_int32_t uptime;                /* Current time (in milliseconds since device
1608
              last booted). Should be set as close to
1609
              datagram transmission time as possible.*/
1610
  u_int32_t num_samples;           /* Number of flow and counters samples to follow */
1611
} INMSample_datagram_hdr;
1612
1613
#define INM_MAX_DATAGRAM_SIZE 1500
1614
#define INM_MIN_DATAGRAM_SIZE 200
1615
#define INM_DEFAULT_DATAGRAM_SIZE 1400
1616
1617
#define INM_DATA_PAD 400
1618
1619
#if 0
1620
/* just do it in a portable way... */
1621
static u_int32_t MyByteSwap32(u_int32_t n) {
1622
  return (((n & 0x000000FF)<<24) +
1623
    ((n & 0x0000FF00)<<8) +
1624
    ((n & 0x00FF0000)>>8) +
1625
    ((n & 0xFF000000)>>24));
1626
}
1627
static u_int16_t MyByteSwap16(u_int16_t n) {
1628
  return ((n >> 8) | (n << 8));
1629
}
1630
#endif
1631
1632
#ifndef PRIu64
1633
# ifdef WIN32
1634
#  define PRIu64 "I64u"
1635
# else
1636
#  define PRIu64 "llu"
1637
# endif
1638
#endif
1639
1640
0
#define YES 1
1641
0
#define NO 0
1642
1643
/* define my own IP header struct - to ease portability */
1644
struct myiphdr
1645
{
1646
  u_int8_t version_and_headerLen;
1647
  u_int8_t tos;
1648
  u_int16_t tot_len;
1649
  u_int16_t id;
1650
  u_int16_t frag_off;
1651
  u_int8_t ttl;
1652
  u_int8_t protocol;
1653
  u_int16_t check;
1654
  u_int32_t saddr;
1655
  u_int32_t daddr;
1656
};
1657
1658
/* same for tcp */
1659
struct mytcphdr
1660
{
1661
  u_int16_t th_sport;   /* source port */
1662
  u_int16_t th_dport;   /* destination port */
1663
  u_int32_t th_seq;   /* sequence number */
1664
  u_int32_t th_ack;   /* acknowledgement number */
1665
  u_int8_t th_off_and_unused;
1666
  u_int8_t th_flags;
1667
  u_int16_t th_win;   /* window */
1668
  u_int16_t th_sum;   /* checksum */
1669
  u_int16_t th_urp;   /* urgent pointer */
1670
};
1671
1672
/* and UDP */
1673
struct myudphdr {
1674
  u_int16_t uh_sport;           /* source port */
1675
  u_int16_t uh_dport;           /* destination port */
1676
  u_int16_t uh_ulen;            /* udp length */
1677
  u_int16_t uh_sum;             /* udp checksum */
1678
};
1679
1680
/* and ICMP */
1681
struct myicmphdr
1682
{
1683
  u_int8_t type;    /* message type */
1684
  u_int8_t code;    /* type sub-code */
1685
  /* ignore the rest */
1686
};
1687
1688
#ifdef SPOOFSOURCE
1689
#define SPOOFSOURCE_SENDPACKET_SIZE 2000
1690
struct mySendPacket {
1691
  struct myiphdr ip;
1692
  struct myudphdr udp;
1693
  u_char data[SPOOFSOURCE_SENDPACKET_SIZE];
1694
};
1695
#endif
1696
1697
typedef struct _SFForwardingTarget {
1698
  struct _SFForwardingTarget *nxt;
1699
  struct in_addr host;
1700
  u_int32_t port;
1701
  struct sockaddr_in addr;
1702
  int sock;
1703
} SFForwardingTarget;
1704
1705
typedef enum { SFLFMT_FULL=0, SFLFMT_PCAP, SFLFMT_LINE, SFLFMT_NETFLOW, SFLFMT_FWD, SFLFMT_CLF } EnumSFLFormat;
1706
1707
typedef struct _SFConfig {
1708
  /* sflow(R) options */
1709
  u_int16_t sFlowInputPort;
1710
  /* netflow(TM) options */
1711
  u_int16_t netFlowOutputPort;
1712
  struct in_addr netFlowOutputIP;
1713
  int netFlowOutputSocket;
1714
  u_int16_t netFlowPeerAS;
1715
  int disableNetFlowScale;
1716
1717
  EnumSFLFormat outputFormat;
1718
  u_int32_t tcpdumpHdrPad;
1719
  u_char zeroPad[100];
1720
  int pcapSwap;
1721
1722
  SFForwardingTarget *forwardingTargets;
1723
1724
  /* vlan filtering */
1725
  int gotVlanFilter;
1726
#define FILTER_MAX_VLAN 4096
1727
  u_char vlanFilter[FILTER_MAX_VLAN + 1];
1728
1729
  /* content stripping */
1730
  int removeContent;
1731
1732
  /* options to restrict IP socket / bind */
1733
  int listen4;
1734
  int listen6;
1735
  int listenControlled;
1736
} SFConfig;
1737
1738
/* define a separate global we can use to construct the common-log-file format */
1739
typedef struct _SFCommonLogFormat {
1740
#define SFLFMT_CLF_MAX_LINE 2000
1741
  int valid;
1742
  char client[64];
1743
  char http_log[SFLFMT_CLF_MAX_LINE];
1744
} SFCommonLogFormat;
1745
1746
static SFCommonLogFormat sfCLF;
1747
#if 0
1748
static const char *SFHTTP_method_names[] = { "-", "OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "CONNECT" };
1749
#endif
1750
1751
typedef struct _SFSample {
1752
  struct in_addr sourceIP;
1753
  struct in6_addr sourceIP6;
1754
  SFLAddress agent_addr;
1755
  u_int32_t agentSubId;
1756
1757
  /* the raw pdu */
1758
  u_char *rawSample;
1759
  u_int32_t rawSampleLen;
1760
  u_char *endp;
1761
  time_t pcapTimestamp;
1762
1763
  /* decode cursor */
1764
  u_char  *datap;
1765
1766
  u_int32_t datagramVersion;
1767
  u_int32_t sampleType;
1768
  u_int32_t ds_class;
1769
  u_int32_t ds_index;
1770
1771
  /* generic interface counter sample */
1772
  SFLIf_counters ifCounters;
1773
1774
  /* sample stream info */
1775
  u_int32_t sysUpTime;
1776
  u_int32_t sequenceNo;
1777
  u_int32_t sampledPacketSize;
1778
  u_int32_t samplesGenerated;
1779
  u_int32_t meanSkipCount;
1780
  u_int32_t samplePool;
1781
  u_int32_t dropEvents;
1782
1783
  /* the sampled header */
1784
  u_int32_t packet_data_tag;
1785
  u_int32_t headerProtocol;
1786
  u_char *header;
1787
  int headerLen;
1788
  u_int32_t stripped;
1789
1790
  /* NTOP */
1791
  u_char *pkt_header;
1792
  int pkt_headerLen;
1793
1794
1795
  /* header decode */
1796
  int gotIPV4;
1797
  int gotIPV4Struct;
1798
  int offsetToIPV4;
1799
  int gotIPV6;
1800
  int gotIPV6Struct;
1801
  int offsetToIPV6;
1802
  int offsetToPayload;
1803
  SFLAddress ipsrc;
1804
  SFLAddress ipdst;
1805
  u_int32_t dcd_ipProtocol;
1806
  u_int32_t dcd_ipTos;
1807
  u_int32_t dcd_ipTTL;
1808
  u_int32_t dcd_sport;
1809
  u_int32_t dcd_dport;
1810
  u_int32_t dcd_tcpFlags;
1811
  u_int32_t ip_fragmentOffset;
1812
  u_int32_t udp_pduLen;
1813
1814
  /* ports */
1815
  u_int32_t inputPortFormat;
1816
  u_int32_t outputPortFormat;
1817
  u_int32_t inputPort;
1818
  u_int32_t outputPort;
1819
1820
  /* ethernet */
1821
  u_int32_t eth_type;
1822
  u_int32_t eth_len;
1823
  u_char eth_src[8];
1824
  u_char eth_dst[8];
1825
1826
  /* vlan */
1827
  u_int32_t in_vlan;
1828
  u_int32_t in_priority;
1829
  u_int32_t internalPriority;
1830
  u_int32_t out_vlan;
1831
  u_int32_t out_priority;
1832
  int vlanFilterReject;
1833
1834
  /* extended data fields */
1835
  u_int32_t num_extended;
1836
  u_int32_t extended_data_tag;
1837
0
#define SASAMPLE_EXTENDED_DATA_SWITCH 1
1838
0
#define SASAMPLE_EXTENDED_DATA_ROUTER 4
1839
0
#define SASAMPLE_EXTENDED_DATA_GATEWAY 8
1840
0
#define SASAMPLE_EXTENDED_DATA_USER 16
1841
0
#define SASAMPLE_EXTENDED_DATA_URL 32
1842
0
#define SASAMPLE_EXTENDED_DATA_MPLS 64
1843
0
#define SASAMPLE_EXTENDED_DATA_NAT 128
1844
0
#define SASAMPLE_EXTENDED_DATA_MPLS_TUNNEL 256
1845
0
#define SASAMPLE_EXTENDED_DATA_MPLS_VC 512
1846
0
#define SASAMPLE_EXTENDED_DATA_MPLS_FTN 1024
1847
0
#define SASAMPLE_EXTENDED_DATA_MPLS_LDP_FEC 2048
1848
0
#define SASAMPLE_EXTENDED_DATA_VLAN_TUNNEL 4096
1849
1850
  /* IP forwarding info */
1851
  SFLAddress nextHop;
1852
  u_int32_t srcMask;
1853
  u_int32_t dstMask;
1854
1855
  /* BGP info */
1856
  SFLAddress bgp_nextHop;
1857
  u_int32_t my_as;
1858
  u_int32_t src_as;
1859
  u_int32_t src_peer_as;
1860
  u_int32_t dst_as_path_len;
1861
  u_int32_t *dst_as_path;
1862
  /* note: version 4 dst as path segments just get printed, not stored here, however
1863
   * the dst_peer and dst_as are filled in, since those are used for netflow encoding
1864
   */
1865
  u_int32_t dst_peer_as;
1866
  u_int32_t dst_as;
1867
1868
  u_int32_t communities_len;
1869
  u_int32_t *communities;
1870
  u_int32_t localpref;
1871
1872
  /* user id */
1873
0
#define SA_MAX_EXTENDED_USER_LEN 200
1874
  u_int32_t src_user_charset;
1875
  u_int32_t src_user_len;
1876
  char src_user[SA_MAX_EXTENDED_USER_LEN+1];
1877
  u_int32_t dst_user_charset;
1878
  u_int32_t dst_user_len;
1879
  char dst_user[SA_MAX_EXTENDED_USER_LEN+1];
1880
1881
  /* url */
1882
0
#define SA_MAX_EXTENDED_URL_LEN 200
1883
0
#define SA_MAX_EXTENDED_HOST_LEN 200
1884
  u_int32_t url_direction;
1885
  u_int32_t url_len;
1886
  char url[SA_MAX_EXTENDED_URL_LEN+1];
1887
  u_int32_t host_len;
1888
  char host[SA_MAX_EXTENDED_HOST_LEN+1];
1889
1890
  /* mpls */
1891
  SFLAddress mpls_nextHop;
1892
1893
  /* nat */
1894
  SFLAddress nat_src;
1895
  SFLAddress nat_dst;
1896
1897
  /* counter blocks */
1898
  u_int32_t statsSamplingInterval;
1899
  u_int32_t counterBlockVersion;
1900
1901
0
# define SFABORT(s, r) ;
1902
1903
#define SF_ABORT_EOS 1
1904
#define SF_ABORT_DECODE_ERROR 2
1905
#define SF_ABORT_LENGTH_ERROR 3
1906
1907
} SFSample;
1908
1909
/*_________________---------------------------__________________
1910
  _________________   read data fns           __________________
1911
  -----------------___________________________------------------
1912
*/
1913
1914
/* Function modified by Luca */
1915
0
static u_int32_t getData32_nobswap(SFSample *sample) {
1916
0
  u_int32_t *ans = (u_int32_t*)sample->datap;
1917
0
  u_int32_t val;
1918
1919
0
  memcpy(&val, ans, 4);
1920
1921
0
  sample->datap += 4;
1922
  // make sure we didn't run off the end of the datagram.  Thanks to
1923
  // Sven Eschenberg for spotting a bug/overrun-vulnerabilty that was here before.
1924
0
  if((u_char *)sample->datap > sample->endp) {
1925
0
    SFABORT(sample, SF_ABORT_EOS);
1926
0
  }
1927
0
  return val;
1928
0
}
1929
1930
0
static u_int32_t getData32(SFSample *sample) {
1931
0
  return ntohl(getData32_nobswap(sample));
1932
0
}
1933
1934
0
static float getFloat(SFSample *sample) {
1935
0
  float fl;
1936
0
  u_int32_t reg = getData32(sample);
1937
0
  memcpy(&fl, &reg, 4);
1938
0
  return fl;
1939
0
}
1940
1941
0
static u_int64_t getData64(SFSample *sample) {
1942
0
  u_int64_t tmpLo, tmpHi;
1943
0
  tmpHi = getData32(sample);
1944
0
  tmpLo = getData32(sample);
1945
0
  return (tmpHi << 32) + tmpLo;
1946
0
}
1947
1948
/* Function modified by Luca */
1949
0
static void skipBytes(SFSample *sample, u_int32_t skip) {
1950
1951
  /* Luca: align to 4 bytes */
1952
0
  skip = (skip + 3) & ~3; /* Align */
1953
1954
  /* ntop->getTrace()->traceEvent(TRACE_WARNING, "===>> skipBytes(%d)", skip); */
1955
1956
0
  sample->datap += skip;
1957
0
  if(skip > sample->rawSampleLen || (u_char *)sample->datap > sample->endp) {
1958
0
    SFABORT(sample, SF_ABORT_EOS);
1959
0
  }
1960
0
}
1961
1962
void sf_log(const char *fmt, ...)
1963
0
{
1964
#ifdef DEBUG_FLOWS
1965
  va_list args;
1966
  
1967
  va_start(args, fmt);
1968
  vprintf(fmt, args);
1969
#endif
1970
0
}
1971
1972
0
static u_int32_t sf_log_next32(SFSample *sample, const char *fieldName) {
1973
0
  u_int32_t val = getData32(sample);
1974
0
  sf_log("%s %u\n", fieldName, val);
1975
0
  return val;
1976
0
}
1977
1978
0
static u_int64_t sf_log_next64(SFSample *sample, const char *fieldName) {
1979
0
  u_int64_t val64 = getData64(sample);
1980
0
  sf_log("%s %" PRIu64 "\n", fieldName, val64);
1981
0
  return val64;
1982
0
}
1983
1984
void sf_log_percentage(SFSample *sample, const char *fieldName)
1985
0
{
1986
0
  u_int32_t hundredths = getData32(sample);
1987
0
  if(hundredths == (u_int32_t)-1) sf_log("%s unknown\n", fieldName);
1988
0
  else {
1989
0
    float percent = (float)hundredths / (float)100.0;
1990
0
    sf_log("%s %.1f\n", fieldName, percent);
1991
0
  }
1992
0
}
1993
1994
0
static float sf_log_nextFloat(SFSample *sample, const char *fieldName) {
1995
0
  float val = getFloat(sample);
1996
0
  sf_log("%s %.3f\n", fieldName, val);
1997
0
  return val;
1998
0
}
1999
2000
0
static u_int32_t getString(SFSample *sample, char *buf, u_int32_t bufLen) {
2001
0
  u_int32_t len, read_len;
2002
0
  len = getData32(sample);
2003
  // truncate if too long
2004
0
  read_len = (len >= bufLen) ? (bufLen - 1) : len;
2005
0
  memcpy(buf, sample->datap, read_len);
2006
0
  buf[read_len] = '\0';   // null terminate
2007
0
  skipBytes(sample, len);
2008
0
  return len;
2009
0
}
2010
2011
0
static u_int32_t getAddress(SFSample *sample, SFLAddress *address) {
2012
0
  address->type = getData32(sample);
2013
0
  if(address->type == SFLADDRESSTYPE_IP_V4)
2014
0
    address->address.ip_v4.addr = getData32_nobswap(sample);
2015
0
  else {
2016
0
    memcpy(&address->address.ip_v6.addr, sample->datap, 16);
2017
0
    skipBytes(sample, 16);
2018
0
  }
2019
0
  return address->type;
2020
0
}
2021
2022
0
static char *printTag(u_int32_t tag, char *buf, int bufLen) {
2023
  // should really be: snprintf(buf, buflen,...) but snprintf() is not always available
2024
0
  snprintf(buf, bufLen, "%u:%u", (tag >> 12), (tag & 0x00000FFF));
2025
0
  return buf;
2026
0
}
2027
2028
0
static void skipTLVRecord(SFSample *sample, u_int32_t tag, u_int32_t len, const char *description) {
2029
0
  char buf[51];
2030
0
  sf_log("skipping unknown %s: %s len=%d\n", description, printTag(tag, buf, 50), len);
2031
0
  skipBytes(sample, len);
2032
0
}
2033
2034
/*_________________---------------------------__________________
2035
  _________________    readExtendedSwitch     __________________
2036
  -----------------___________________________------------------
2037
*/
2038
2039
static void readExtendedSwitch(SFSample *sample)
2040
0
{
2041
0
  sf_log("extendedType SWITCH\n");
2042
0
  sample->in_vlan = getData32(sample);
2043
0
  sample->in_priority = getData32(sample);
2044
0
  sample->out_vlan = getData32(sample);
2045
0
  sample->out_priority = getData32(sample);
2046
2047
  /* Validate vlan_ids */
2048
0
  if(sample->in_vlan  > 4095) sample->in_vlan = 0;
2049
0
  if(sample->out_vlan > 4095) sample->out_vlan = 0;
2050
  
2051
0
  sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_SWITCH;
2052
2053
0
  sf_log("in_vlan %u\n", sample->in_vlan);
2054
0
  sf_log("in_priority %u\n", sample->in_priority);
2055
0
  sf_log("out_vlan %u\n", sample->out_vlan);
2056
0
  sf_log("out_priority %u\n", sample->out_priority);
2057
0
}
2058
2059
/*_________________---------------------------__________________
2060
  _________________        printHex           __________________
2061
  -----------------___________________________------------------
2062
*/
2063
2064
0
static u_char bin2hex(int nib) { return (nib < 10) ? ('0' + nib) : ('A' - 10 + nib); }
2065
2066
int printHex(const u_char *a, int len, u_char *buf, int bufLen, int marker, int bytesPerOutputLine)
2067
0
{
2068
0
  int b = 0, i = 0;
2069
0
  for(; i < len; i++) {
2070
0
    u_char byte;
2071
0
    if(b > (bufLen - 10)) break;
2072
0
    if(marker > 0 && i == marker) {
2073
0
      buf[b++] = '<';
2074
0
      buf[b++] = '*';
2075
0
      buf[b++] = '>';
2076
0
      buf[b++] = '-';
2077
0
    }
2078
0
    byte = a[i];
2079
0
    buf[b++] = bin2hex(byte >> 4);
2080
0
    buf[b++] = bin2hex(byte & 0x0f);
2081
0
    if(i > 0 && (i % bytesPerOutputLine) == 0) buf[b++] = '\n';
2082
0
    else {
2083
      // separate the bytes with a dash
2084
0
      if(i < (len - 1)) buf[b++] = '-';
2085
0
    }
2086
0
  }
2087
0
  buf[b] = '\0';
2088
0
  return b;
2089
0
}
2090
2091
/*_________________---------------------------__________________
2092
  _________________      IP_to_a              __________________
2093
  -----------------___________________________------------------
2094
*/
2095
2096
char *IP_to_a(u_int32_t ipaddr, char *buf, int bufLen)
2097
0
{
2098
0
  u_char *ip = (u_char *)&ipaddr;
2099
0
  snprintf(buf, bufLen, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
2100
0
  return buf;
2101
0
}
2102
2103
0
static char *printAddress(SFLAddress *address, char *buf, int bufLen) {
2104
0
  if(address->type == SFLADDRESSTYPE_IP_V4)
2105
0
    IP_to_a(address->address.ip_v4.addr, buf, bufLen);
2106
0
  else {
2107
0
    u_char *b = address->address.ip_v6.addr;
2108
    // should really be: snprintf(buf, buflen,...) but snprintf() is not always available
2109
0
    snprintf(buf, bufLen,
2110
0
       "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
2111
0
       b[0],b[1],b[2],b[3],b[4],b[5],b[6],b[7],b[8],b[9],b[10],b[11],b[12],b[13],b[14],b[15]);
2112
0
  }
2113
0
  return buf;
2114
0
}
2115
2116
/*_________________---------------------------__________________
2117
  _________________    readExtendedRouter     __________________
2118
  -----------------___________________________------------------
2119
*/
2120
2121
static void readExtendedRouter(SFSample *sample)
2122
0
{
2123
0
  char buf[51];
2124
0
  sf_log("extendedType ROUTER\n");
2125
0
  getAddress(sample, &sample->nextHop);
2126
0
  sample->srcMask = getData32(sample);
2127
0
  sample->dstMask = getData32(sample);
2128
2129
0
  sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_ROUTER;
2130
2131
0
  sf_log("nextHop %s\n", printAddress(&sample->nextHop, buf, 50));
2132
0
  sf_log("srcSubnetMask %u\n", sample->srcMask);
2133
0
  sf_log("dstSubnetMask %u\n", sample->dstMask);
2134
0
}
2135
2136
/*_________________---------------------------__________________
2137
  _________________  readExtendedGateway_v2   __________________
2138
  -----------------___________________________------------------
2139
*/
2140
2141
static void readExtendedGateway_v2(SFSample *sample)
2142
0
{
2143
0
  sf_log("extendedType GATEWAY\n");
2144
2145
0
  sample->my_as = getData32(sample);
2146
0
  sample->src_as = getData32(sample);
2147
0
  sample->src_peer_as = getData32(sample);
2148
2149
  // clear dst_peer_as and dst_as to make sure we are not
2150
  // remembering values from a previous sample - (thanks Marc Lavine)
2151
0
  sample->dst_peer_as = 0;
2152
0
  sample->dst_as = 0;
2153
2154
0
  sample->dst_as_path_len = getData32(sample);
2155
  /* just point at the dst_as_path array */
2156
0
  if(sample->dst_as_path_len > 0) {
2157
0
    sample->dst_as_path = (u_int32_t*)sample->datap;
2158
    /* and skip over it in the input */
2159
0
    skipBytes(sample, sample->dst_as_path_len * 4);
2160
    // fill in the dst and dst_peer fields too
2161
0
    sample->dst_peer_as = ntohl(sample->dst_as_path[0]);
2162
0
    sample->dst_as = ntohl(sample->dst_as_path[sample->dst_as_path_len - 1]);
2163
0
  }
2164
2165
0
  sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_GATEWAY;
2166
2167
0
  sf_log("my_as %u\n", sample->my_as);
2168
0
  sf_log("src_as %u\n", sample->src_as);
2169
0
  sf_log("src_peer_as %u\n", sample->src_peer_as);
2170
0
  sf_log("dst_as %u\n", sample->dst_as);
2171
0
  sf_log("dst_peer_as %u\n", sample->dst_peer_as);
2172
0
  sf_log("dst_as_path_len %u\n", sample->dst_as_path_len);
2173
0
  if(sample->dst_as_path_len > 0) {
2174
0
    u_int32_t i = 0;
2175
0
    for(; i < sample->dst_as_path_len; i++) {
2176
0
      if(i == 0) sf_log("dst_as_path ");
2177
0
      else sf_log("-");
2178
0
      sf_log("%u", ntohl(sample->dst_as_path[i]));
2179
0
    }
2180
0
    sf_log("\n");
2181
0
  }
2182
0
}
2183
2184
/*_________________---------------------------__________________
2185
  _________________  readExtendedGateway      __________________
2186
  -----------------___________________________------------------
2187
*/
2188
2189
static void readExtendedGateway(SFSample *sample)
2190
0
{
2191
0
  u_int32_t segments;
2192
0
  u_int32_t seg;
2193
0
  char buf[51];
2194
2195
0
  sf_log("extendedType GATEWAY\n");
2196
2197
0
  if(sample->datagramVersion >= 5) {
2198
0
    getAddress(sample, &sample->bgp_nextHop);
2199
0
    sf_log("bgp_nexthop %s\n", printAddress(&sample->bgp_nextHop, buf, 50));
2200
0
  }
2201
2202
0
  sample->my_as = getData32(sample);
2203
0
  sample->src_as = getData32(sample);
2204
0
  sample->src_peer_as = getData32(sample);
2205
0
  sf_log("my_as %u\n", sample->my_as);
2206
0
  sf_log("src_as %u\n", sample->src_as);
2207
0
  sf_log("src_peer_as %u\n", sample->src_peer_as);
2208
0
  segments = getData32(sample);
2209
2210
  // clear dst_peer_as and dst_as to make sure we are not
2211
  // remembering values from a previous sample - (thanks Marc Lavine)
2212
0
  sample->dst_peer_as = 0;
2213
0
  sample->dst_as = 0;
2214
2215
0
  if(segments > 0) {
2216
0
    sf_log("dst_as_path ");
2217
0
    for(seg = 0; seg < segments; seg++) {
2218
0
      u_int32_t seg_type;
2219
0
      u_int32_t seg_len;
2220
0
      u_int32_t i;
2221
0
      seg_type = getData32(sample);
2222
0
      seg_len = getData32(sample);
2223
0
      for(i = 0; i < seg_len; i++) {
2224
0
  u_int32_t asNumber;
2225
0
  asNumber = getData32(sample);
2226
  /* mark the first one as the dst_peer_as */
2227
0
  if(i == 0 && seg == 0) sample->dst_peer_as = asNumber;
2228
0
  else sf_log("-");
2229
  /* make sure the AS sets are in parentheses */
2230
0
  if(i == 0 && seg_type == SFLEXTENDED_AS_SET) sf_log("(");
2231
0
  sf_log("%u", asNumber);
2232
  /* mark the last one as the dst_as */
2233
0
  if(seg == (segments - 1) && i == (seg_len - 1)) sample->dst_as = asNumber;
2234
0
      }
2235
0
      if(seg_type == SFLEXTENDED_AS_SET) sf_log(")");
2236
0
    }
2237
0
    sf_log("\n");
2238
0
  }
2239
0
  sf_log("dst_as %u\n", sample->dst_as);
2240
0
  sf_log("dst_peer_as %u\n", sample->dst_peer_as);
2241
2242
0
  sample->communities_len = getData32(sample);
2243
  /* just point at the communities array */
2244
0
  if(sample->communities_len > 0) sample->communities = (u_int32_t*)sample->datap;
2245
  /* and skip over it in the input */
2246
0
  skipBytes(sample, sample->communities_len * 4);
2247
2248
0
  sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_GATEWAY;
2249
0
  if(sample->communities_len > 0) {
2250
0
    u_int32_t j = 0;
2251
0
    for(; j < sample->communities_len; j++) {
2252
0
      if(j == 0) sf_log("BGP_communities ");
2253
0
      else sf_log("-");
2254
0
      sf_log("%u", ntohl(sample->communities[j]));
2255
0
    }
2256
0
    sf_log("\n");
2257
0
  }
2258
2259
0
  sample->localpref = getData32(sample);
2260
0
  sf_log("BGP_localpref %u\n", sample->localpref);
2261
2262
0
}
2263
2264
/*_________________---------------------------__________________
2265
  _________________    readExtendedUser       __________________
2266
  -----------------___________________________------------------
2267
*/
2268
2269
static void readExtendedUser(SFSample *sample)
2270
0
{
2271
0
  sf_log("extendedType USER\n");
2272
2273
0
  if(sample->datagramVersion >= 5) {
2274
0
    sample->src_user_charset = getData32(sample);
2275
0
    sf_log("src_user_charset %d\n", sample->src_user_charset);
2276
0
  }
2277
2278
0
  sample->src_user_len = getString(sample, sample->src_user, SA_MAX_EXTENDED_USER_LEN);
2279
2280
0
  if(sample->datagramVersion >= 5) {
2281
0
    sample->dst_user_charset = getData32(sample);
2282
0
    sf_log("dst_user_charset %d\n", sample->dst_user_charset);
2283
0
  }
2284
2285
0
  sample->dst_user_len = getString(sample, sample->dst_user, SA_MAX_EXTENDED_USER_LEN);
2286
2287
0
  sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_USER;
2288
2289
0
  sf_log("src_user %s\n", sample->src_user);
2290
0
  sf_log("dst_user %s\n", sample->dst_user);
2291
0
}
2292
2293
/*_________________---------------------------__________________
2294
  _________________    readExtendedUrl        __________________
2295
  -----------------___________________________------------------
2296
*/
2297
2298
static void readExtendedUrl(SFSample *sample)
2299
0
{
2300
0
  sf_log("extendedType URL\n");
2301
2302
0
  sample->url_direction = getData32(sample);
2303
0
  sf_log("url_direction %u\n", sample->url_direction);
2304
0
  sample->url_len = getString(sample, sample->url, SA_MAX_EXTENDED_URL_LEN);
2305
0
  sf_log("url %s\n", sample->url);
2306
0
  if(sample->datagramVersion >= 5) {
2307
0
    sample->host_len = getString(sample, sample->host, SA_MAX_EXTENDED_HOST_LEN);
2308
0
    sf_log("host %s\n", sample->host);
2309
0
  }
2310
0
  sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_URL;
2311
0
}
2312
2313
2314
/*_________________---------------------------__________________
2315
  _________________       mplsLabelStack      __________________
2316
  -----------------___________________________------------------
2317
*/
2318
2319
static void mplsLabelStack(SFSample *sample, const char *fieldName)
2320
0
{
2321
0
  SFLLabelStack lstk;
2322
0
  u_int32_t lab;
2323
0
  lstk.depth = getData32(sample);
2324
  /* just point at the lablelstack array */
2325
0
  if(lstk.depth > 0) lstk.stack = (u_int32_t *)sample->datap;
2326
  /* and skip over it in the input */
2327
0
  skipBytes(sample, lstk.depth * 4);
2328
2329
0
  if(lstk.depth > 0) {
2330
0
    u_int32_t j = 0;
2331
0
    for(; j < lstk.depth; j++) {
2332
0
      if(j == 0) sf_log("%s ", fieldName);
2333
0
      else sf_log("-");
2334
0
      lab = ntohl(lstk.stack[j]);
2335
0
      sf_log("%u.%u.%u.%u",
2336
0
       (lab >> 12),     // label
2337
0
       (lab >> 9) & 7,  // experimental
2338
0
       (lab >> 8) & 1,  // bottom of stack
2339
0
       (lab &  255));   // TTL
2340
0
    }
2341
0
    sf_log("\n");
2342
0
  }
2343
0
}
2344
2345
/*_________________---------------------------__________________
2346
  _________________    readExtendedMpls       __________________
2347
  -----------------___________________________------------------
2348
*/
2349
2350
static void readExtendedMpls(SFSample *sample)
2351
0
{
2352
0
  char buf[51];
2353
0
  sf_log("extendedType MPLS\n");
2354
0
  getAddress(sample, &sample->mpls_nextHop);
2355
0
  sf_log("mpls_nexthop %s\n", printAddress(&sample->mpls_nextHop, buf, 50));
2356
2357
0
  mplsLabelStack(sample, "mpls_input_stack");
2358
0
  mplsLabelStack(sample, "mpls_output_stack");
2359
2360
0
  sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_MPLS;
2361
0
}
2362
2363
/*_________________---------------------------__________________
2364
  _________________    readExtendedNat        __________________
2365
  -----------------___________________________------------------
2366
*/
2367
2368
static void readExtendedNat(SFSample *sample)
2369
0
{
2370
0
  char buf[51];
2371
0
  sf_log("extendedType NAT\n");
2372
0
  getAddress(sample, &sample->nat_src);
2373
0
  sf_log("nat_src %s\n", printAddress(&sample->nat_src, buf, 50));
2374
0
  getAddress(sample, &sample->nat_dst);
2375
0
  sf_log("nat_dst %s\n", printAddress(&sample->nat_dst, buf, 50));
2376
0
  sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_NAT;
2377
0
}
2378
2379
2380
/*_________________---------------------------__________________
2381
  _________________    readExtendedMplsTunnel __________________
2382
  -----------------___________________________------------------
2383
*/
2384
2385
static void readExtendedMplsTunnel(SFSample *sample)
2386
0
{
2387
0
#define SA_MAX_TUNNELNAME_LEN 100
2388
0
  char tunnel_name[SA_MAX_TUNNELNAME_LEN+1];
2389
0
  u_int32_t tunnel_id, tunnel_cos;
2390
2391
0
  if(getString(sample, tunnel_name, SA_MAX_TUNNELNAME_LEN) > 0)
2392
0
    sf_log("mpls_tunnel_lsp_name %s\n", tunnel_name);
2393
0
  tunnel_id = getData32(sample);
2394
0
  sf_log("mpls_tunnel_id %u\n", tunnel_id);
2395
0
  tunnel_cos = getData32(sample);
2396
0
  sf_log("mpls_tunnel_cos %u\n", tunnel_cos);
2397
0
  sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_MPLS_TUNNEL;
2398
0
}
2399
2400
/*_________________---------------------------__________________
2401
  _________________    readExtendedMplsVC     __________________
2402
  -----------------___________________________------------------
2403
*/
2404
2405
static void readExtendedMplsVC(SFSample *sample)
2406
0
{
2407
0
#define SA_MAX_VCNAME_LEN 100
2408
0
  char vc_name[SA_MAX_VCNAME_LEN+1];
2409
0
  u_int32_t vll_vc_id, vc_cos;
2410
0
  if(getString(sample, vc_name, SA_MAX_VCNAME_LEN) > 0)
2411
0
    sf_log("mpls_vc_name %s\n", vc_name);
2412
0
  vll_vc_id = getData32(sample);
2413
0
  sf_log("mpls_vll_vc_id %u\n", vll_vc_id);
2414
0
  vc_cos = getData32(sample);
2415
0
  sf_log("mpls_vc_cos %u\n", vc_cos);
2416
0
  sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_MPLS_VC;
2417
0
}
2418
2419
/*_________________---------------------------__________________
2420
  _________________    readExtendedMplsFTN    __________________
2421
  -----------------___________________________------------------
2422
*/
2423
2424
static void readExtendedMplsFTN(SFSample *sample)
2425
0
{
2426
0
#define SA_MAX_FTN_LEN 100
2427
0
  char ftn_descr[SA_MAX_FTN_LEN+1];
2428
0
  u_int32_t ftn_mask;
2429
0
  if(getString(sample, ftn_descr, SA_MAX_FTN_LEN) > 0)
2430
0
    sf_log("mpls_ftn_descr %s\n", ftn_descr);
2431
0
  ftn_mask = getData32(sample);
2432
0
  sf_log("mpls_ftn_mask %u\n", ftn_mask);
2433
0
  sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_MPLS_FTN;
2434
0
}
2435
2436
/*_________________---------------------------__________________
2437
  _________________  readExtendedMplsLDP_FEC  __________________
2438
  -----------------___________________________------------------
2439
*/
2440
2441
static void readExtendedMplsLDP_FEC(SFSample *sample)
2442
0
{
2443
0
  u_int32_t fec_addr_prefix_len = getData32(sample);
2444
0
  sf_log("mpls_fec_addr_prefix_len %u\n", fec_addr_prefix_len);
2445
0
  sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_MPLS_LDP_FEC;
2446
0
}
2447
2448
/*_________________---------------------------__________________
2449
  _________________  readExtendedVlanTunnel   __________________
2450
  -----------------___________________________------------------
2451
*/
2452
2453
static void readExtendedVlanTunnel(SFSample *sample)
2454
0
{
2455
0
  u_int32_t lab;
2456
0
  SFLLabelStack lstk;
2457
0
  lstk.depth = getData32(sample);
2458
  /* just point at the lablelstack array */
2459
0
  if(lstk.depth > 0) lstk.stack = (u_int32_t *)sample->datap;
2460
  /* and skip over it in the input */
2461
0
  skipBytes(sample, lstk.depth * 4);
2462
2463
0
  if(lstk.depth > 0) {
2464
0
    u_int32_t j = 0;
2465
0
    for(; j < lstk.depth; j++) {
2466
0
      if(j == 0) sf_log("vlan_tunnel ");
2467
0
      else sf_log("-");
2468
0
      lab = ntohl(lstk.stack[j]);
2469
0
      sf_log("0x%04x.%u.%u.%u",
2470
0
       (lab >> 16),       // TPI
2471
0
       (lab >> 13) & 7,   // priority
2472
0
       (lab >> 12) & 1,   // CFI
2473
0
       (lab & 4095));     // VLAN
2474
0
    }
2475
0
    sf_log("\n");
2476
0
  }
2477
0
  sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_VLAN_TUNNEL;
2478
0
}
2479
2480
static void readFlowSample_header(SFSample *sample);
2481
static int readFlowSample(SFSample *sample, int expanded);
2482
2483
/*_________________---------------------------__________________
2484
  _________________  readExtendedWifiPayload  __________________
2485
  -----------------___________________________------------------
2486
*/
2487
2488
static void readExtendedWifiPayload(SFSample *sample)
2489
0
{
2490
0
  sf_log_next32(sample, "cipher_suite");
2491
0
  readFlowSample_header(sample);
2492
0
}
2493
2494
/*_________________---------------------------__________________
2495
  _________________  readExtendedWifiRx       __________________
2496
  -----------------___________________________------------------
2497
*/
2498
2499
static void readExtendedWifiRx(SFSample *sample)
2500
0
{
2501
0
  u_int32_t i;
2502
0
  u_char *bssid;
2503
0
  char ssid[SFL_MAX_SSID_LEN+1];
2504
0
  if(getString(sample, ssid, SFL_MAX_SSID_LEN) > 0) {
2505
0
    sf_log("rx_SSID %s\n", ssid);
2506
0
  }
2507
2508
0
  bssid = (u_char *)sample->datap;
2509
0
  sf_log("rx_BSSID ");
2510
0
  for(i = 0; i < 6; i++) sf_log("%02x", bssid[i]);
2511
0
  sf_log("\n");
2512
0
  skipBytes(sample, 6);
2513
2514
0
  sf_log_next32(sample, "rx_version");
2515
0
  sf_log_next32(sample, "rx_channel");
2516
0
  sf_log_next64(sample, "rx_speed");
2517
0
  sf_log_next32(sample, "rx_rsni");
2518
0
  sf_log_next32(sample, "rx_rcpi");
2519
0
  sf_log_next32(sample, "rx_packet_uS");
2520
0
}
2521
2522
/*_________________---------------------------__________________
2523
  _________________  readExtendedWifiTx       __________________
2524
  -----------------___________________________------------------
2525
*/
2526
2527
static void readExtendedWifiTx(SFSample *sample)
2528
0
{
2529
0
  u_int32_t i;
2530
0
  u_char *bssid;
2531
0
  char ssid[SFL_MAX_SSID_LEN+1];
2532
0
  if(getString(sample, ssid, SFL_MAX_SSID_LEN) > 0) {
2533
0
    sf_log("tx_SSID %s\n", ssid);
2534
0
  }
2535
2536
0
  bssid = (u_char *)sample->datap;
2537
0
  sf_log("tx_BSSID ");
2538
0
  for(i = 0; i < 6; i++) sf_log("%02x", bssid[i]);
2539
0
  sf_log("\n");
2540
0
  skipBytes(sample, 6);
2541
2542
0
  sf_log_next32(sample, "tx_version");
2543
0
  sf_log_next32(sample, "tx_transmissions");
2544
0
  sf_log_next32(sample, "tx_packet_uS");
2545
0
  sf_log_next32(sample, "tx_retrans_uS");
2546
0
  sf_log_next32(sample, "tx_channel");
2547
0
  sf_log_next64(sample, "tx_speed");
2548
0
  sf_log_next32(sample, "tx_power_mW");
2549
0
}
2550
2551
/*_________________---------------------------__________________
2552
  _________________  readExtendedAggregation  __________________
2553
  -----------------___________________________------------------
2554
*/
2555
2556
#if 0
2557
/* No more used */
2558
static void readExtendedAggregation(SFSample *sample)
2559
{
2560
  u_int32_t i, num_pdus = getData32(sample);
2561
  sf_log("aggregation_num_pdus %u\n", num_pdus);
2562
  for(i = 0; i < num_pdus; i++) {
2563
    sf_log("aggregation_pdu %u\n", i);
2564
    readFlowSample(sample, NO); // not sure if this the right one here $$$
2565
  }
2566
}
2567
#endif
2568
2569
/*_________________---------------------------__________________
2570
  _________________  readFlowSample_header    __________________
2571
  -----------------___________________________------------------
2572
*/
2573
2574
static void readFlowSample_header(SFSample *sample)
2575
0
{
2576
0
  sf_log("flowSampleType HEADER\n");
2577
0
  sample->headerProtocol = getData32(sample);
2578
0
  sf_log("headerProtocol %u\n", sample->headerProtocol);
2579
0
  sample->sampledPacketSize = getData32(sample);
2580
0
  sf_log("sampledPacketSize %u\n", sample->sampledPacketSize);
2581
0
  if(sample->datagramVersion > 4) {
2582
    // stripped count introduced in sFlow version 5
2583
0
    sample->stripped = getData32(sample);
2584
0
    sf_log("strippedBytes %u\n", sample->stripped);
2585
0
  }
2586
0
  sample->pkt_headerLen = sample->headerLen = getData32(sample);
2587
0
  sf_log("headerLen %u\n", sample->headerLen);
2588
2589
0
  sample->pkt_header = sample->header = (u_char *)sample->datap; /* just point at the header */
2590
0
  skipBytes(sample, sample->headerLen);
2591
0
  {
2592
0
    char scratch[2000];
2593
0
    printHex(sample->header, sample->headerLen, (u_char *)scratch, 2000, 0, 2000);
2594
0
    sf_log("headerBytes %s\n", scratch);
2595
0
  }
2596
2597
0
  switch(sample->headerProtocol) {
2598
    /* the header protocol tells us where to jump into the decode */
2599
0
  case SFLHEADER_ETHERNET_ISO8023:
2600
    // decodeLinkLayer(sample);
2601
0
    break;
2602
0
  case SFLHEADER_IPv4:
2603
0
    sample->gotIPV4 = YES;
2604
0
    sample->offsetToIPV4 = 0;
2605
0
    break;
2606
0
  case SFLHEADER_IPv6:
2607
0
    sample->gotIPV6 = YES;
2608
0
    sample->offsetToIPV6 = 0;
2609
0
    break;
2610
0
  case SFLHEADER_IEEE80211MAC:
2611
    // decode80211MAC(sample);
2612
0
    break;
2613
0
  case SFLHEADER_ISO88024_TOKENBUS:
2614
0
  case SFLHEADER_ISO88025_TOKENRING:
2615
0
  case SFLHEADER_FDDI:
2616
0
  case SFLHEADER_FRAME_RELAY:
2617
0
  case SFLHEADER_X25:
2618
0
  case SFLHEADER_PPP:
2619
0
  case SFLHEADER_SMDS:
2620
0
  case SFLHEADER_AAL5:
2621
0
  case SFLHEADER_AAL5_IP:
2622
0
  case SFLHEADER_MPLS:
2623
0
  case SFLHEADER_POS:
2624
0
  case SFLHEADER_IEEE80211_AMPDU:
2625
0
  case SFLHEADER_IEEE80211_AMSDU_SUBFRAME:
2626
0
    sf_log("NO_DECODE headerProtocol=%d\n", sample->headerProtocol);
2627
0
    break;
2628
0
  default:
2629
0
    fprintf(stderr, "undefined headerProtocol = %u\n", sample->headerProtocol);
2630
    // exit(-13);
2631
0
    return;
2632
0
  }
2633
2634
#if 0
2635
  if(sample->gotIPV4) {
2636
    // report the size of the original IPPdu (including the IP header)
2637
    sf_log("IPSize %d\n",  sample->sampledPacketSize - sample->stripped - sample->offsetToIPV4);
2638
    decodeIPV4(sample);
2639
  }
2640
  else if(sample->gotIPV6) {
2641
    // report the size of the original IPPdu (including the IP header)
2642
    sf_log("IPSize %d\n",  sample->sampledPacketSize - sample->stripped - sample->offsetToIPV6);
2643
    decodeIPV6(sample);
2644
  }
2645
#endif
2646
0
}
2647
2648
/*_________________---------------------------__________________
2649
  _________________  readFlowSample_ethernet  __________________
2650
  -----------------___________________________------------------
2651
*/
2652
2653
static void readFlowSample_ethernet(SFSample *sample)
2654
0
{
2655
0
  u_char *p;
2656
0
  sf_log("flowSampleType ETHERNET\n");
2657
0
  sample->eth_len = getData32(sample);
2658
0
  memcpy(sample->eth_src, sample->datap, 6);
2659
0
  skipBytes(sample, 6);
2660
0
  memcpy(sample->eth_dst, sample->datap, 6);
2661
0
  skipBytes(sample, 6);
2662
0
  sample->eth_type = getData32(sample);
2663
0
  sf_log("ethernet_type %u\n", sample->eth_type);
2664
0
  sf_log("ethernet_len %u\n", sample->eth_len);
2665
0
  p = sample->eth_src;
2666
0
  sf_log("ethernet_src %02x%02x%02x%02x%02x%02x\n", p[0], p[1], p[2], p[3], p[4], p[5]);
2667
0
  p = sample->eth_dst;
2668
0
  sf_log("ethernet_dst %02x%02x%02x%02x%02x%02x\n", p[0], p[1], p[2], p[3], p[4], p[5]);
2669
0
}
2670
2671
2672
/*_________________---------------------------__________________
2673
  _________________    readFlowSample_IPv4    __________________
2674
  -----------------___________________________------------------
2675
*/
2676
2677
static void readFlowSample_IPv4(SFSample *sample)
2678
0
{
2679
0
  sf_log("flowSampleType IPV4\n");
2680
0
  sample->headerLen = sizeof(SFLSampled_ipv4);
2681
0
  sample->header = (u_char *)sample->datap; /* just point at the header */
2682
0
  skipBytes(sample, sample->headerLen);
2683
0
  {
2684
0
    char buf[51];
2685
0
    SFLSampled_ipv4 nfKey;
2686
0
    memcpy(&nfKey, sample->header, sizeof(nfKey));
2687
0
    sample->sampledPacketSize = ntohl(nfKey.length);
2688
0
    sf_log("sampledPacketSize %u\n", sample->sampledPacketSize);
2689
0
    sf_log("IPSize %u\n",  sample->sampledPacketSize);
2690
0
    sample->ipsrc.type = SFLADDRESSTYPE_IP_V4;
2691
0
    sample->ipsrc.address.ip_v4 = nfKey.src_ip;
2692
0
    sample->ipdst.type = SFLADDRESSTYPE_IP_V4;
2693
0
    sample->ipdst.address.ip_v4 = nfKey.dst_ip;
2694
0
    sample->dcd_ipProtocol = ntohl(nfKey.protocol);
2695
0
    sample->dcd_ipTos = ntohl(nfKey.tos);
2696
0
    sf_log("srcIP %s\n", printAddress(&sample->ipsrc, buf, 50));
2697
0
    sf_log("dstIP %s\n", printAddress(&sample->ipdst, buf, 50));
2698
0
    sf_log("IPProtocol %u\n", sample->dcd_ipProtocol);
2699
0
    sf_log("IPTOS %u\n", sample->dcd_ipTos);
2700
0
    sample->dcd_sport = ntohl(nfKey.src_port);
2701
0
    sample->dcd_dport = ntohl(nfKey.dst_port);
2702
0
    switch(sample->dcd_ipProtocol) {
2703
0
    case 1: /* ICMP */
2704
0
      sf_log("ICMPType %u\n", sample->dcd_dport);
2705
      /* not sure about the dest port being icmp type
2706
   - might be that src port is icmp type and dest
2707
   port is icmp code.  Still, have seen some
2708
   implementations where src port is 0 and dst
2709
   port is the type, so it may be safer to
2710
   assume that the destination port has the type */
2711
0
      break;
2712
0
    case 6: /* TCP */
2713
0
      sf_log("TCPSrcPort %u\n", sample->dcd_sport);
2714
0
      sf_log("TCPDstPort %u\n", sample->dcd_dport);
2715
0
      sample->dcd_tcpFlags = ntohl(nfKey.tcp_flags);
2716
0
      sf_log("TCPFlags %u\n", sample->dcd_tcpFlags);
2717
0
      break;
2718
0
    case 17: /* UDP */
2719
0
      sf_log("UDPSrcPort %u\n", sample->dcd_sport);
2720
0
      sf_log("UDPDstPort %u\n", sample->dcd_dport);
2721
0
      break;
2722
0
    default: /* some other protcol */
2723
0
      break;
2724
0
    }
2725
0
  }
2726
0
}
2727
2728
/*_________________---------------------------__________________
2729
  _________________    readFlowSample_IPv6    __________________
2730
  -----------------___________________________------------------
2731
*/
2732
2733
static void readFlowSample_IPv6(SFSample *sample)
2734
0
{
2735
0
  sf_log("flowSampleType IPV6\n");
2736
0
  sample->header = (u_char *)sample->datap; /* just point at the header */
2737
0
  sample->headerLen = sizeof(SFLSampled_ipv6);
2738
0
  skipBytes(sample, sample->headerLen);
2739
0
  {
2740
0
    char buf[51];
2741
0
    SFLSampled_ipv6 nfKey6;
2742
0
    memcpy(&nfKey6, sample->header, sizeof(nfKey6));
2743
0
    sample->sampledPacketSize = ntohl(nfKey6.length);
2744
0
    sf_log("sampledPacketSize %u\n", sample->sampledPacketSize);
2745
0
    sf_log("IPSize %u\n", sample->sampledPacketSize);
2746
0
    sample->ipsrc.type = SFLADDRESSTYPE_IP_V6;
2747
0
    memcpy(&sample->ipsrc.address.ip_v6, &nfKey6.src_ip, 16);
2748
0
    sample->ipdst.type = SFLADDRESSTYPE_IP_V6;
2749
0
    memcpy(&sample->ipdst.address.ip_v6, &nfKey6.dst_ip, 16);
2750
0
    sample->dcd_ipProtocol = ntohl(nfKey6.protocol);
2751
0
    sf_log("srcIP6 %s\n", printAddress(&sample->ipsrc, buf, 50));
2752
0
    sf_log("dstIP6 %s\n", printAddress(&sample->ipdst, buf, 50));
2753
0
    sf_log("IPProtocol %u\n", sample->dcd_ipProtocol);
2754
0
    sf_log("priority %u\n", ntohl(nfKey6.priority));
2755
0
    sample->dcd_sport = ntohl(nfKey6.src_port);
2756
0
    sample->dcd_dport = ntohl(nfKey6.dst_port);
2757
0
    switch(sample->dcd_ipProtocol) {
2758
0
    case 1: /* ICMP */
2759
0
      sf_log("ICMPType %u\n", sample->dcd_dport);
2760
      /* not sure about the dest port being icmp type
2761
   - might be that src port is icmp type and dest
2762
   port is icmp code.  Still, have seen some
2763
   implementations where src port is 0 and dst
2764
   port is the type, so it may be safer to
2765
   assume that the destination port has the type */
2766
0
      break;
2767
0
    case 6: /* TCP */
2768
0
      sf_log("TCPSrcPort %u\n", sample->dcd_sport);
2769
0
      sf_log("TCPDstPort %u\n", sample->dcd_dport);
2770
0
      sample->dcd_tcpFlags = ntohl(nfKey6.tcp_flags);
2771
0
      sf_log("TCPFlags %u\n", sample->dcd_tcpFlags);
2772
0
      break;
2773
0
    case 17: /* UDP */
2774
0
      sf_log("UDPSrcPort %u\n", sample->dcd_sport);
2775
0
      sf_log("UDPDstPort %u\n", sample->dcd_dport);
2776
0
      break;
2777
0
    default: /* some other protcol */
2778
0
      break;
2779
0
    }
2780
0
  }
2781
0
}
2782
2783
/*_________________----------------------------__________________
2784
  _________________  readFlowSample_memcache   __________________
2785
  -----------------____________________________------------------
2786
*/
2787
2788
static void readFlowSample_memcache(SFSample *sample)
2789
0
{
2790
//  char key[SFL_MAX_MEMCACHE_KEY+1];
2791
0
#define ENC_KEY_BYTES (SFL_MAX_MEMCACHE_KEY * 3) + 1
2792
//  char enc_key[ENC_KEY_BYTES];
2793
0
  sf_log("flowSampleType memcache\n");
2794
0
  sf_log_next32(sample, "memcache_op_protocol");
2795
0
  sf_log_next32(sample, "memcache_op_cmd");
2796
#if 0
2797
  if(getString(sample, key, SFL_MAX_MEMCACHE_KEY) > 0) {
2798
    sf_log("memcache_op_key %s\n", URLEncode(key, enc_key, ENC_KEY_BYTES));
2799
  }
2800
#endif
2801
0
  sf_log_next32(sample, "memcache_op_nkeys");
2802
0
  sf_log_next32(sample, "memcache_op_value_bytes");
2803
0
  sf_log_next32(sample, "memcache_op_duration_uS");
2804
0
  sf_log_next32(sample, "memcache_op_status");
2805
0
}
2806
2807
/*_________________----------------------------__________________
2808
  _________________  readFlowSample_http       __________________
2809
  -----------------____________________________------------------
2810
*/
2811
2812
static void readFlowSample_http(SFSample *sample)
2813
0
{
2814
0
  char uri[SFL_MAX_HTTP_URI+1];
2815
0
  char host[SFL_MAX_HTTP_HOST+1];
2816
0
  char referrer[SFL_MAX_HTTP_REFERRER+1];
2817
0
  char useragent[SFL_MAX_HTTP_USERAGENT+1];
2818
0
  char authuser[SFL_MAX_HTTP_AUTHUSER+1];
2819
0
  char mimetype[SFL_MAX_HTTP_MIMETYPE+1];
2820
2821
0
  sf_log("flowSampleType http\n");
2822
0
  sf_log_next32(sample, "http_method");
2823
0
  sf_log_next32(sample, "http_protocol");
2824
0
  if(getString(sample, uri, SFL_MAX_HTTP_URI) > 0) {
2825
0
    sf_log("http_uri %s\n", uri);
2826
0
  }
2827
0
  if(getString(sample, host, SFL_MAX_HTTP_HOST) > 0) {
2828
0
    sf_log("http_host %s\n", host);
2829
0
  }
2830
0
  if(getString(sample, referrer, SFL_MAX_HTTP_REFERRER) > 0) {
2831
0
    sf_log("http_referrer %s\n", referrer);
2832
0
  }
2833
0
  if(getString(sample, useragent, SFL_MAX_HTTP_USERAGENT) > 0) {
2834
0
    sf_log("http_useragent %s\n", useragent);
2835
0
  }
2836
0
  if(getString(sample, authuser, SFL_MAX_HTTP_AUTHUSER) > 0) {
2837
0
    sf_log("http_authuser %s\n", authuser);
2838
0
  }
2839
0
  if(getString(sample, mimetype, SFL_MAX_HTTP_MIMETYPE) > 0) {
2840
0
    sf_log("http_mimetype %s\n", mimetype);
2841
0
  }
2842
0
  sf_log_next64(sample, "http_bytes");
2843
0
  sf_log_next32(sample, "http_duration_uS");
2844
0
  sf_log_next32(sample, "http_status");
2845
0
}
2846
2847
/*_________________----------------------------__________________
2848
  _________________  readFlowSample_memcache   __________________
2849
  -----------------____________________________------------------
2850
*/
2851
2852
static void readFlowSample_CAL(SFSample *sample)
2853
0
{
2854
0
  char pool[SFLCAL_MAX_POOL_LEN];
2855
0
  char transaction[SFLCAL_MAX_TRANSACTION_LEN];
2856
0
  char operation[SFLCAL_MAX_OPERATION_LEN];
2857
0
  char status[SFLCAL_MAX_STATUS_LEN];
2858
2859
  // sf_log("flowSampleType CAL\n");
2860
2861
0
  u_int32_t ttype = getData32(sample);
2862
0
  if(ttype < SFLOW_CAL_NUM_TRANSACTION_TYPES) {
2863
0
    sf_log("transaction_type %s\n", CALTransactionNames[ttype]);
2864
0
  }
2865
0
  else {
2866
0
    sf_log("transaction_type %u\n", ttype);
2867
0
  }
2868
2869
0
  sf_log_next32(sample, "depth");
2870
0
  if(getString(sample, pool, SFLCAL_MAX_POOL_LEN) > 0) {
2871
0
    sf_log("pool %s\n", pool);
2872
0
  }
2873
0
  if(getString(sample, transaction, SFLCAL_MAX_TRANSACTION_LEN) > 0) {
2874
0
    sf_log("transaction %s\n", transaction);
2875
0
  }
2876
0
  if(getString(sample, operation, SFLCAL_MAX_OPERATION_LEN) > 0) {
2877
0
    sf_log("operation %s\n", operation);
2878
0
  }
2879
0
  if(getString(sample, status, SFLCAL_MAX_STATUS_LEN) > 0) {
2880
0
    sf_log("status %s\n", status);
2881
0
  }
2882
0
  sf_log_next64(sample, "duration_uS");
2883
0
}
2884
2885
/*_________________----------------------------__________________
2886
  _________________   readExtendedSocket4      __________________
2887
  -----------------____________________________------------------
2888
*/
2889
2890
static void readExtendedSocket4(SFSample *sample)
2891
0
{
2892
0
  char buf[51];
2893
0
  sf_log("extendedType socket4\n");
2894
0
  sf_log_next32(sample, "socket4_ip_protocol");
2895
0
  sample->ipsrc.type = SFLADDRESSTYPE_IP_V4;
2896
0
  sample->ipsrc.address.ip_v4.addr = getData32_nobswap(sample);
2897
0
  sample->ipdst.type = SFLADDRESSTYPE_IP_V4;
2898
0
  sample->ipdst.address.ip_v4.addr = getData32_nobswap(sample);
2899
0
  sf_log("socket4_local_ip %s\n", printAddress(&sample->ipsrc, buf, 50));
2900
0
  sf_log("socket4_remote_ip %s\n", printAddress(&sample->ipdst, buf, 50));
2901
0
  sf_log_next32(sample, "socket4_local_port");
2902
0
  sf_log_next32(sample, "socket4_remote_port");
2903
0
}
2904
2905
/*_________________----------------------------__________________
2906
  _________________  readExtendedSocket6       __________________
2907
  -----------------____________________________------------------
2908
*/
2909
2910
static void readExtendedSocket6(SFSample *sample)
2911
0
{
2912
0
  char buf[51];
2913
0
  sf_log("extendedType socket6\n");
2914
0
  sf_log_next32(sample, "socket6_ip_protocol");
2915
0
  sample->ipsrc.type = SFLADDRESSTYPE_IP_V6;
2916
0
  memcpy(&sample->ipsrc.address.ip_v6, sample->datap, 16);
2917
0
  skipBytes(sample, 16);
2918
0
  sample->ipdst.type = SFLADDRESSTYPE_IP_V6;
2919
0
  memcpy(&sample->ipdst.address.ip_v6, sample->datap, 16);
2920
0
  skipBytes(sample, 16);
2921
0
  sf_log("socket6_local_ip %s\n", printAddress(&sample->ipsrc, buf, 50));
2922
0
  sf_log("socket6_remote_ip %s\n", printAddress(&sample->ipdst, buf, 50));
2923
0
  sf_log_next32(sample, "socket6_local_port");
2924
0
  sf_log_next32(sample, "socket6_remote_port");
2925
2926
0
}
2927
2928
/*_________________---------------------------__________________
2929
  _________________    receiveError           __________________
2930
  -----------------___________________________------------------
2931
*/
2932
2933
static void receiveError(SFSample *sample, const char *errm, int hexdump)
2934
0
{
2935
//  char ipbuf[51];
2936
0
  char scratch[6000];
2937
#if(0)
2938
  char *msg = "";
2939
  char *hex = "";
2940
#endif
2941
0
  u_int32_t markOffset = (u_char *)sample->datap - sample->rawSample;
2942
#if(0)
2943
  if(errm) msg = errm;
2944
#endif
2945
0
  if(hexdump) {
2946
0
    printHex(sample->rawSample, sample->rawSampleLen, (u_char *)scratch, 6000, markOffset, 16);
2947
#if(0)
2948
    hex = scratch;
2949
#endif
2950
0
  }
2951
2952
0
  SFABORT(sample, SF_ABORT_DECODE_ERROR);
2953
0
}
2954
2955
/*_________________---------------------------__________________
2956
  _________________    readFlowSample_v2v4    __________________
2957
  -----------------___________________________------------------
2958
*/
2959
2960
static int readFlowSample_v2v4(SFSample *sample)
2961
0
{
2962
0
  sf_log("sampleType FLOWSAMPLE\n");
2963
2964
0
  sample->samplesGenerated = getData32(sample);
2965
0
  sf_log("sampleSequenceNo %u\n", sample->samplesGenerated);
2966
0
  {
2967
0
    u_int32_t samplerId = getData32(sample);
2968
0
    sample->ds_class = samplerId >> 24;
2969
0
    sample->ds_index = samplerId & 0x00ffffff;
2970
0
    sf_log("sourceId %u:%u\n", sample->ds_class, sample->ds_index);
2971
0
  }
2972
2973
0
  sample->meanSkipCount = getData32(sample);
2974
0
  sample->samplePool = getData32(sample);
2975
0
  sample->dropEvents = getData32(sample);
2976
0
  sample->inputPort = getData32(sample);
2977
0
  sample->outputPort = getData32(sample);
2978
0
  sf_log("meanSkipCount %u\n", sample->meanSkipCount);
2979
0
  sf_log("samplePool %u\n", sample->samplePool);
2980
0
  sf_log("dropEvents %u\n", sample->dropEvents);
2981
0
  sf_log("inputPort %u\n", sample->inputPort);
2982
0
  if(sample->outputPort & 0x80000000) {
2983
0
    u_int32_t numOutputs = sample->outputPort & 0x7fffffff;
2984
0
    if(numOutputs > 0) sf_log("outputPort multiple %d\n", numOutputs);
2985
0
    else sf_log("outputPort multiple >1\n");
2986
0
  }
2987
0
  else sf_log("outputPort %u\n", sample->outputPort);
2988
2989
0
  sample->packet_data_tag = getData32(sample);
2990
2991
0
  switch(sample->packet_data_tag) {
2992
2993
0
  case INMPACKETTYPE_HEADER: readFlowSample_header(sample); break;
2994
0
  case INMPACKETTYPE_IPV4:
2995
0
    sample->gotIPV4Struct = YES;
2996
0
    readFlowSample_IPv4(sample);
2997
0
    break;
2998
0
  case INMPACKETTYPE_IPV6:
2999
0
    sample->gotIPV6Struct = YES;
3000
0
    readFlowSample_IPv6(sample);
3001
0
    break;
3002
0
  default:
3003
0
    return(0);
3004
0
  }
3005
3006
0
  sample->extended_data_tag = 0;
3007
0
  {
3008
0
    u_int32_t x;
3009
0
    sample->num_extended = getData32(sample);
3010
0
    for(x = 0; x < sample->num_extended; x++) {
3011
0
      u_int32_t extended_tag;
3012
0
      extended_tag = getData32(sample);
3013
0
      switch(extended_tag) {
3014
0
      case INMEXTENDED_SWITCH: readExtendedSwitch(sample); break;
3015
0
      case INMEXTENDED_ROUTER: readExtendedRouter(sample); break;
3016
0
      case INMEXTENDED_GATEWAY:
3017
0
  if(sample->datagramVersion == 2) readExtendedGateway_v2(sample);
3018
0
  else readExtendedGateway(sample);
3019
0
  break;
3020
0
      case INMEXTENDED_USER: readExtendedUser(sample); break;
3021
0
      case INMEXTENDED_URL: readExtendedUrl(sample); break;
3022
0
      default:
3023
0
  receiveError(sample, "unrecognized extended data tag", YES);
3024
0
  return(-1);
3025
0
  break;
3026
0
      }
3027
0
    }
3028
0
  }
3029
3030
0
  return(0);
3031
0
}
3032
3033
/*_________________---------------------------__________________
3034
  _________________    lengthCheck            __________________
3035
  -----------------___________________________------------------
3036
*/
3037
3038
0
static int lengthCheck(SFSample *sample, const char *description, u_char *start, u_int32_t len) {
3039
0
  u_int32_t actualLen = (u_char *)sample->datap - start;
3040
3041
0
  if(actualLen != len)
3042
0
  {
3043
    /* Alignement helper by L.Deri as some sflow implementations are broken */
3044
0
    int diff = actualLen-len;
3045
3046
0
    if((diff > 0) && (diff < 4)) {
3047
0
      sample->datap -= diff, actualLen -= diff;
3048
0
    }
3049
3050
0
    if(actualLen != len) {
3051
0
      SFABORT(sample, SF_ABORT_LENGTH_ERROR);
3052
0
      return(-1);
3053
0
    }
3054
0
  }
3055
3056
0
  return(0);
3057
0
}
3058
3059
/*_________________---------------------------__________________
3060
  _________________    readFlowSample         __________________
3061
  -----------------___________________________------------------
3062
*/
3063
3064
static int readFlowSample(SFSample *sample, int expanded)
3065
0
{
3066
0
  u_int32_t num_elements, sampleLength;
3067
0
  u_char *sampleStart;
3068
3069
0
  sf_log("sampleType FLOWSAMPLE\n");
3070
0
  sampleLength = getData32(sample);
3071
0
  sampleStart = (u_char *)sample->datap;
3072
0
  sample->samplesGenerated = getData32(sample);
3073
0
  sf_log("sampleSequenceNo %u\n", sample->samplesGenerated);
3074
0
  if(expanded) {
3075
0
    sample->ds_class = getData32(sample);
3076
0
    sample->ds_index = getData32(sample);
3077
0
  }
3078
0
  else {
3079
0
    u_int32_t samplerId = getData32(sample);
3080
0
    sample->ds_class = samplerId >> 24;
3081
0
    sample->ds_index = samplerId & 0x00ffffff;
3082
0
  }
3083
0
  sf_log("sourceId %u:%u\n", sample->ds_class, sample->ds_index);
3084
3085
0
  sample->meanSkipCount = getData32(sample);
3086
0
  sample->samplePool = getData32(sample);
3087
0
  sample->dropEvents = getData32(sample);
3088
0
  sf_log("meanSkipCount %u\n", sample->meanSkipCount);
3089
0
  sf_log("samplePool %u\n", sample->samplePool);
3090
0
  sf_log("dropEvents %u\n", sample->dropEvents);
3091
0
  if(expanded) {
3092
0
    sample->inputPortFormat = getData32(sample);
3093
0
    sample->inputPort = getData32(sample);
3094
0
    sample->outputPortFormat = getData32(sample);
3095
0
    sample->outputPort = getData32(sample);
3096
0
  }
3097
0
  else {
3098
0
    u_int32_t inp, outp;
3099
0
    inp = getData32(sample);
3100
0
    outp = getData32(sample);
3101
0
    sample->inputPortFormat = inp >> 30;
3102
0
    sample->outputPortFormat = outp >> 30;
3103
0
    sample->inputPort = inp & 0x3fffffff;
3104
0
    sample->outputPort = outp & 0x3fffffff;
3105
0
  }
3106
3107
0
  switch(sample->inputPortFormat) {
3108
0
  case 3: sf_log("inputPort format==3 %u\n", sample->inputPort); break;
3109
0
  case 2: sf_log("inputPort multiple %u\n", sample->inputPort); break;
3110
0
  case 1: sf_log("inputPort dropCode %u\n", sample->inputPort); break;
3111
0
  case 0: sf_log("inputPort %u\n", sample->inputPort); break;
3112
0
  }
3113
3114
0
  switch(sample->outputPortFormat) {
3115
0
  case 3: sf_log("outputPort format==3 %u\n", sample->outputPort); break;
3116
0
  case 2: sf_log("outputPort multiple %u\n", sample->outputPort); break;
3117
0
  case 1: sf_log("outputPort dropCode %u\n", sample->outputPort); break;
3118
0
  case 0: sf_log("outputPort %u\n", sample->outputPort); break;
3119
0
  }
3120
3121
  // clear the CLF record
3122
0
  sfCLF.valid = NO;
3123
0
  sfCLF.client[0] = '\0';
3124
3125
0
  num_elements = getData32(sample);
3126
0
  {
3127
0
    u_int32_t el;
3128
0
    for(el = 0; el < num_elements; el++) {
3129
0
      u_int32_t tag, length;
3130
0
      u_char *start;
3131
0
      char buf[51];
3132
0
      tag = getData32(sample);
3133
0
      sf_log("flowBlock_tag %s\n", printTag(tag, buf, 50));
3134
0
      length = getData32(sample);
3135
0
      start = (u_char *)sample->datap;
3136
3137
0
      switch(tag) {
3138
0
      case SFLFLOW_HEADER:     readFlowSample_header(sample); break;
3139
0
      case SFLFLOW_ETHERNET:   readFlowSample_ethernet(sample); break;
3140
0
      case SFLFLOW_IPV4:       readFlowSample_IPv4(sample); break;
3141
0
      case SFLFLOW_IPV6:       readFlowSample_IPv6(sample); break;
3142
0
      case SFLFLOW_MEMCACHE:   readFlowSample_memcache(sample); break;
3143
0
      case SFLFLOW_HTTP:       readFlowSample_http(sample); break;
3144
0
      case SFLFLOW_CAL:       readFlowSample_CAL(sample); break;
3145
0
      case SFLFLOW_EX_SWITCH:  readExtendedSwitch(sample); break;
3146
0
      case SFLFLOW_EX_ROUTER:  readExtendedRouter(sample); break;
3147
0
      case SFLFLOW_EX_GATEWAY: readExtendedGateway(sample); break;
3148
0
      case SFLFLOW_EX_USER:    readExtendedUser(sample); break;
3149
0
      case SFLFLOW_EX_URL:     readExtendedUrl(sample); break;
3150
0
      case SFLFLOW_EX_MPLS:    readExtendedMpls(sample); break;
3151
0
      case SFLFLOW_EX_NAT:     readExtendedNat(sample); break;
3152
0
      case SFLFLOW_EX_MPLS_TUNNEL:  readExtendedMplsTunnel(sample); break;
3153
0
      case SFLFLOW_EX_MPLS_VC:      readExtendedMplsVC(sample); break;
3154
0
      case SFLFLOW_EX_MPLS_FTN:     readExtendedMplsFTN(sample); break;
3155
0
      case SFLFLOW_EX_MPLS_LDP_FEC: readExtendedMplsLDP_FEC(sample); break;
3156
0
      case SFLFLOW_EX_VLAN_TUNNEL:  readExtendedVlanTunnel(sample); break;
3157
0
      case SFLFLOW_EX_80211_PAYLOAD: readExtendedWifiPayload(sample); break;
3158
0
      case SFLFLOW_EX_80211_RX: readExtendedWifiRx(sample); break;
3159
0
      case SFLFLOW_EX_80211_TX: readExtendedWifiTx(sample); break;
3160
  /* case SFLFLOW_EX_AGGREGATION: readExtendedAggregation(sample); break; */
3161
0
      case SFLFLOW_EX_SOCKET4: readExtendedSocket4(sample); break;
3162
0
      case SFLFLOW_EX_SOCKET6: readExtendedSocket6(sample); break;
3163
0
      default: skipTLVRecord(sample, tag, length, "flow_sample_element"); break;
3164
0
      }
3165
3166
0
      if(lengthCheck(sample, "flow_sample_element", start, length) != 0)
3167
0
  return(-1);
3168
0
    }
3169
0
  }
3170
0
  if(lengthCheck(sample, "flow_sample", sampleStart, sampleLength) != 0)
3171
0
    return(-1);
3172
3173
0
  return(0);
3174
0
}
3175
3176
/*_________________---------------------------__________________
3177
  _________________  readCounters_generic     __________________
3178
  -----------------___________________________------------------
3179
*/
3180
3181
static void readCounters_generic(SFSample *sample)
3182
0
{
3183
  /* the first part of the generic counters block is really just more info about the interface. */
3184
0
  sample->ifCounters.ifIndex = sf_log_next32(sample, "ifIndex");
3185
0
  sample->ifCounters.ifType = sf_log_next32(sample, "networkType");
3186
0
  sample->ifCounters.ifSpeed = sf_log_next64(sample, "ifSpeed");
3187
0
  sample->ifCounters.ifDirection = sf_log_next32(sample, "ifDirection");
3188
0
  sample->ifCounters.ifStatus = sf_log_next32(sample, "ifStatus");
3189
  /* the generic counters always come first */
3190
0
  sample->ifCounters.ifInOctets = sf_log_next64(sample, "ifInOctets");
3191
0
  sample->ifCounters.ifInUcastPkts = sf_log_next32(sample, "ifInUcastPkts");
3192
0
  sample->ifCounters.ifInMulticastPkts = sf_log_next32(sample, "ifInMulticastPkts");
3193
0
  sample->ifCounters.ifInBroadcastPkts = sf_log_next32(sample, "ifInBroadcastPkts");
3194
0
  sample->ifCounters.ifInDiscards = sf_log_next32(sample, "ifInDiscards");
3195
0
  sample->ifCounters.ifInErrors = sf_log_next32(sample, "ifInErrors");
3196
0
  sample->ifCounters.ifInUnknownProtos = sf_log_next32(sample, "ifInUnknownProtos");
3197
0
  sample->ifCounters.ifOutOctets = sf_log_next64(sample, "ifOutOctets");
3198
0
  sample->ifCounters.ifOutUcastPkts = sf_log_next32(sample, "ifOutUcastPkts");
3199
0
  sample->ifCounters.ifOutMulticastPkts = sf_log_next32(sample, "ifOutMulticastPkts");
3200
0
  sample->ifCounters.ifOutBroadcastPkts = sf_log_next32(sample, "ifOutBroadcastPkts");
3201
0
  sample->ifCounters.ifOutDiscards = sf_log_next32(sample, "ifOutDiscards");
3202
0
  sample->ifCounters.ifOutErrors = sf_log_next32(sample, "ifOutErrors");
3203
0
  sample->ifCounters.ifPromiscuousMode = sf_log_next32(sample, "ifPromiscuousMode");
3204
0
}
3205
3206
/*_________________---------------------------__________________
3207
  _________________  readCounters_ethernet    __________________
3208
  -----------------___________________________------------------
3209
*/
3210
3211
static  void readCounters_ethernet(SFSample *sample)
3212
0
{
3213
0
  sf_log_next32(sample, "dot3StatsAlignmentErrors");
3214
0
  sf_log_next32(sample, "dot3StatsFCSErrors");
3215
0
  sf_log_next32(sample, "dot3StatsSingleCollisionFrames");
3216
0
  sf_log_next32(sample, "dot3StatsMultipleCollisionFrames");
3217
0
  sf_log_next32(sample, "dot3StatsSQETestErrors");
3218
0
  sf_log_next32(sample, "dot3StatsDeferredTransmissions");
3219
0
  sf_log_next32(sample, "dot3StatsLateCollisions");
3220
0
  sf_log_next32(sample, "dot3StatsExcessiveCollisions");
3221
0
  sf_log_next32(sample, "dot3StatsInternalMacTransmitErrors");
3222
0
  sf_log_next32(sample, "dot3StatsCarrierSenseErrors");
3223
0
  sf_log_next32(sample, "dot3StatsFrameTooLongs");
3224
0
  sf_log_next32(sample, "dot3StatsInternalMacReceiveErrors");
3225
0
  sf_log_next32(sample, "dot3StatsSymbolErrors");
3226
0
}
3227
3228
3229
/*_________________---------------------------__________________
3230
  _________________  readCounters_tokenring   __________________
3231
  -----------------___________________________------------------
3232
*/
3233
3234
static void readCounters_tokenring(SFSample *sample)
3235
0
{
3236
0
  sf_log_next32(sample, "dot5StatsLineErrors");
3237
0
  sf_log_next32(sample, "dot5StatsBurstErrors");
3238
0
  sf_log_next32(sample, "dot5StatsACErrors");
3239
0
  sf_log_next32(sample, "dot5StatsAbortTransErrors");
3240
0
  sf_log_next32(sample, "dot5StatsInternalErrors");
3241
0
  sf_log_next32(sample, "dot5StatsLostFrameErrors");
3242
0
  sf_log_next32(sample, "dot5StatsReceiveCongestions");
3243
0
  sf_log_next32(sample, "dot5StatsFrameCopiedErrors");
3244
0
  sf_log_next32(sample, "dot5StatsTokenErrors");
3245
0
  sf_log_next32(sample, "dot5StatsSoftErrors");
3246
0
  sf_log_next32(sample, "dot5StatsHardErrors");
3247
0
  sf_log_next32(sample, "dot5StatsSignalLoss");
3248
0
  sf_log_next32(sample, "dot5StatsTransmitBeacons");
3249
0
  sf_log_next32(sample, "dot5StatsRecoverys");
3250
0
  sf_log_next32(sample, "dot5StatsLobeWires");
3251
0
  sf_log_next32(sample, "dot5StatsRemoves");
3252
0
  sf_log_next32(sample, "dot5StatsSingles");
3253
0
  sf_log_next32(sample, "dot5StatsFreqErrors");
3254
0
}
3255
3256
3257
/*_________________---------------------------__________________
3258
  _________________  readCounters_vg          __________________
3259
  -----------------___________________________------------------
3260
*/
3261
3262
static void readCounters_vg(SFSample *sample)
3263
0
{
3264
0
  sf_log_next32(sample, "dot12InHighPriorityFrames");
3265
0
  sf_log_next64(sample, "dot12InHighPriorityOctets");
3266
0
  sf_log_next32(sample, "dot12InNormPriorityFrames");
3267
0
  sf_log_next64(sample, "dot12InNormPriorityOctets");
3268
0
  sf_log_next32(sample, "dot12InIPMErrors");
3269
0
  sf_log_next32(sample, "dot12InOversizeFrameErrors");
3270
0
  sf_log_next32(sample, "dot12InDataErrors");
3271
0
  sf_log_next32(sample, "dot12InNullAddressedFrames");
3272
0
  sf_log_next32(sample, "dot12OutHighPriorityFrames");
3273
0
  sf_log_next64(sample, "dot12OutHighPriorityOctets");
3274
0
  sf_log_next32(sample, "dot12TransitionIntoTrainings");
3275
0
  sf_log_next64(sample, "dot12HCInHighPriorityOctets");
3276
0
  sf_log_next64(sample, "dot12HCInNormPriorityOctets");
3277
0
  sf_log_next64(sample, "dot12HCOutHighPriorityOctets");
3278
0
}
3279
3280
3281
3282
/*_________________---------------------------__________________
3283
  _________________  readCounters_vlan        __________________
3284
  -----------------___________________________------------------
3285
*/
3286
3287
static void readCounters_vlan(SFSample *sample)
3288
0
{
3289
0
  sample->in_vlan = getData32(sample);
3290
0
  sf_log("in_vlan %u\n", sample->in_vlan);
3291
0
  sf_log_next64(sample, "octets");
3292
0
  sf_log_next32(sample, "ucastPkts");
3293
0
  sf_log_next32(sample, "multicastPkts");
3294
0
  sf_log_next32(sample, "broadcastPkts");
3295
0
  sf_log_next32(sample, "discards");
3296
0
}
3297
3298
/*_________________---------------------------__________________
3299
  _________________  readCounters_80211       __________________
3300
  -----------------___________________________------------------
3301
*/
3302
3303
static void readCounters_80211(SFSample *sample)
3304
0
{
3305
0
  sf_log_next32(sample, "dot11TransmittedFragmentCount");
3306
0
  sf_log_next32(sample, "dot11MulticastTransmittedFrameCount");
3307
0
  sf_log_next32(sample, "dot11FailedCount");
3308
0
  sf_log_next32(sample, "dot11RetryCount");
3309
0
  sf_log_next32(sample, "dot11MultipleRetryCount");
3310
0
  sf_log_next32(sample, "dot11FrameDuplicateCount");
3311
0
  sf_log_next32(sample, "dot11RTSSuccessCount");
3312
0
  sf_log_next32(sample, "dot11RTSFailureCount");
3313
0
  sf_log_next32(sample, "dot11ACKFailureCount");
3314
0
  sf_log_next32(sample, "dot11ReceivedFragmentCount");
3315
0
  sf_log_next32(sample, "dot11MulticastReceivedFrameCount");
3316
0
  sf_log_next32(sample, "dot11FCSErrorCount");
3317
0
  sf_log_next32(sample, "dot11TransmittedFrameCount");
3318
0
  sf_log_next32(sample, "dot11WEPUndecryptableCount");
3319
0
  sf_log_next32(sample, "dot11QoSDiscardedFragmentCount");
3320
0
  sf_log_next32(sample, "dot11AssociatedStationCount");
3321
0
  sf_log_next32(sample, "dot11QoSCFPollsReceivedCount");
3322
0
  sf_log_next32(sample, "dot11QoSCFPollsUnusedCount");
3323
0
  sf_log_next32(sample, "dot11QoSCFPollsUnusableCount");
3324
0
  sf_log_next32(sample, "dot11QoSCFPollsLostCount");
3325
0
}
3326
3327
/*_________________---------------------------__________________
3328
  _________________  readCounters_processor   __________________
3329
  -----------------___________________________------------------
3330
*/
3331
3332
static void readCounters_processor(SFSample *sample)
3333
0
{
3334
0
  sf_log_percentage(sample, "5s_cpu");
3335
0
  sf_log_percentage(sample, "1m_cpu");
3336
0
  sf_log_percentage(sample, "5m_cpu");
3337
0
  sf_log_next64(sample, "total_memory_bytes");
3338
0
  sf_log_next64(sample, "free_memory_bytes");
3339
0
}
3340
3341
/*_________________---------------------------__________________
3342
  _________________  readCounters_radio       __________________
3343
  -----------------___________________________------------------
3344
*/
3345
3346
static void readCounters_radio(SFSample *sample)
3347
0
{
3348
0
  sf_log_next32(sample, "radio_elapsed_time");
3349
0
  sf_log_next32(sample, "radio_on_channel_time");
3350
0
  sf_log_next32(sample, "radio_on_channel_busy_time");
3351
0
}
3352
3353
/*_________________---------------------------__________________
3354
  _________________  readCounters_host_hid    __________________
3355
  -----------------___________________________------------------
3356
*/
3357
3358
static void readCounters_host_hid(SFSample *sample)
3359
0
{
3360
0
  u_int32_t i;
3361
0
  u_char *uuid;
3362
0
  char hostname[SFL_MAX_HOSTNAME_LEN+1];
3363
0
  char os_release[SFL_MAX_OSRELEASE_LEN+1];
3364
0
  if(getString(sample, hostname, SFL_MAX_HOSTNAME_LEN) > 0) {
3365
0
    sf_log("hostname %s\n", hostname);
3366
0
  }
3367
0
  uuid = (u_char *)sample->datap;
3368
0
  sf_log("UUID ");
3369
0
  for(i = 0; i < 16; i++) sf_log("%02x", uuid[i]);
3370
0
  sf_log("\n");
3371
0
  skipBytes(sample, 16);
3372
0
  sf_log_next32(sample, "machine_type");
3373
0
  sf_log_next32(sample, "os_name");
3374
0
  if(getString(sample, os_release, SFL_MAX_OSRELEASE_LEN) > 0) {
3375
0
    sf_log("os_release %s\n", os_release);
3376
0
  }
3377
0
}
3378
3379
/*_________________---------------------------__________________
3380
  _________________  readCounters_adaptors    __________________
3381
  -----------------___________________________------------------
3382
*/
3383
3384
static void readCounters_adaptors(SFSample *sample)
3385
0
{
3386
0
  u_char *mac;
3387
0
  u_int32_t i, j, ifindex, num_macs, num_adaptors = getData32(sample);
3388
0
  for(i = 0; i < num_adaptors; i++) {
3389
0
    ifindex = getData32(sample);
3390
0
    sf_log("adaptor_%u_ifIndex %u\n", i, ifindex);
3391
0
    num_macs = getData32(sample);
3392
0
    sf_log("adaptor_%u_MACs %u\n", i, num_macs);
3393
0
    for(j = 0; j < num_macs; j++) {
3394
0
      mac = (u_char *)sample->datap;
3395
0
      sf_log("adaptor_%u_MAC_%u %02x%02x%02x%02x%02x%02x\n",
3396
0
       i, j,
3397
0
       mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
3398
0
      skipBytes(sample, 8);
3399
0
    }
3400
0
  }
3401
0
}
3402
3403
3404
/*_________________----------------------------__________________
3405
  _________________  readCounters_host_parent  __________________
3406
  -----------------____________________________------------------
3407
*/
3408
3409
static void readCounters_host_parent(SFSample *sample)
3410
0
{
3411
0
  sf_log_next32(sample, "parent_dsClass");
3412
0
  sf_log_next32(sample, "parent_dsIndex");
3413
0
}
3414
3415
/*_________________---------------------------__________________
3416
  _________________  readCounters_host_cpu    __________________
3417
  -----------------___________________________------------------
3418
*/
3419
3420
static void readCounters_host_cpu(SFSample *sample)
3421
0
{
3422
0
  sf_log_nextFloat(sample, "cpu_load_one");
3423
0
  sf_log_nextFloat(sample, "cpu_load_five");
3424
0
  sf_log_nextFloat(sample, "cpu_load_fifteen");
3425
0
  sf_log_next32(sample, "cpu_proc_run");
3426
0
  sf_log_next32(sample, "cpu_proc_total");
3427
0
  sf_log_next32(sample, "cpu_num");
3428
0
  sf_log_next32(sample, "cpu_speed");
3429
0
  sf_log_next32(sample, "cpu_uptime");
3430
0
  sf_log_next32(sample, "cpu_user");
3431
0
  sf_log_next32(sample, "cpu_nice");
3432
0
  sf_log_next32(sample, "cpu_system");
3433
0
  sf_log_next32(sample, "cpu_idle");
3434
0
  sf_log_next32(sample, "cpu_wio");
3435
0
  sf_log_next32(sample, "cpuintr");
3436
0
  sf_log_next32(sample, "cpu_sintr");
3437
0
  sf_log_next32(sample, "cpuinterrupts");
3438
0
  sf_log_next32(sample, "cpu_contexts");
3439
0
}
3440
3441
/*_________________---------------------------__________________
3442
  _________________  readCounters_host_mem    __________________
3443
  -----------------___________________________------------------
3444
*/
3445
3446
static void readCounters_host_mem(SFSample *sample)
3447
0
{
3448
0
  sf_log_next64(sample, "mem_total");
3449
0
  sf_log_next64(sample, "mem_free");
3450
0
  sf_log_next64(sample, "mem_shared");
3451
0
  sf_log_next64(sample, "mem_buffers");
3452
0
  sf_log_next64(sample, "mem_cached");
3453
0
  sf_log_next64(sample, "swap_total");
3454
0
  sf_log_next64(sample, "swap_free");
3455
0
  sf_log_next32(sample, "page_in");
3456
0
  sf_log_next32(sample, "page_out");
3457
0
  sf_log_next32(sample, "swap_in");
3458
0
  sf_log_next32(sample, "swap_out");
3459
0
}
3460
3461
3462
/*_________________---------------------------__________________
3463
  _________________  readCounters_host_dsk    __________________
3464
  -----------------___________________________------------------
3465
*/
3466
3467
static void readCounters_host_dsk(SFSample *sample)
3468
0
{
3469
0
  sf_log_next64(sample, "disk_total");
3470
0
  sf_log_next64(sample, "disk_free");
3471
0
  sf_log_next32(sample, "disk_partition_max_used");
3472
0
  sf_log_next32(sample, "disk_reads");
3473
0
  sf_log_next64(sample, "disk_bytes_read");
3474
0
  sf_log_next32(sample, "disk_read_time");
3475
0
  sf_log_next32(sample, "disk_writes");
3476
0
  sf_log_next64(sample, "disk_bytes_written");
3477
0
  sf_log_next32(sample, "disk_write_time");
3478
0
}
3479
3480
/*_________________---------------------------__________________
3481
  _________________  readCounters_host_nio    __________________
3482
  -----------------___________________________------------------
3483
*/
3484
3485
static void readCounters_host_nio(SFSample *sample)
3486
0
{
3487
0
  sf_log_next64(sample, "nio_bytes_in");
3488
0
  sf_log_next32(sample, "nio_pkts_in");
3489
0
  sf_log_next32(sample, "nio_errs_in");
3490
0
  sf_log_next32(sample, "nio_drops_in");
3491
0
  sf_log_next64(sample, "nio_bytes_out");
3492
0
  sf_log_next32(sample, "nio_pkts_out");
3493
0
  sf_log_next32(sample, "nio_errs_out");
3494
0
  sf_log_next32(sample, "nio_drops_out");
3495
0
}
3496
3497
/*_________________-----------------------------__________________
3498
  _________________  readCounters_host_vnode    __________________
3499
  -----------------_____________________________------------------
3500
*/
3501
3502
static void readCounters_host_vnode(SFSample *sample)
3503
0
{
3504
0
  sf_log_next32(sample, "vnode_mhz");
3505
0
  sf_log_next32(sample, "vnode_cpus");
3506
0
  sf_log_next64(sample, "vnode_memory");
3507
0
  sf_log_next64(sample, "vnode_memory_free");
3508
0
  sf_log_next32(sample, "vnode_num_domains");
3509
0
}
3510
3511
/*_________________----------------------------__________________
3512
  _________________  readCounters_host_vcpu    __________________
3513
  -----------------____________________________------------------
3514
*/
3515
3516
static void readCounters_host_vcpu(SFSample *sample)
3517
0
{
3518
0
  sf_log_next32(sample, "vcpu_state");
3519
0
  sf_log_next32(sample, "vcpu_cpu_mS");
3520
0
  sf_log_next32(sample, "vcpu_cpuCount");
3521
0
}
3522
3523
/*_________________----------------------------__________________
3524
  _________________  readCounters_host_vmem    __________________
3525
  -----------------____________________________------------------
3526
*/
3527
3528
static void readCounters_host_vmem(SFSample *sample)
3529
0
{
3530
0
  sf_log_next64(sample, "vmem_memory");
3531
0
  sf_log_next64(sample, "vmem_maxMemory");
3532
0
}
3533
3534
/*_________________----------------------------__________________
3535
  _________________  readCounters_host_vdsk    __________________
3536
  -----------------____________________________------------------
3537
*/
3538
3539
static void readCounters_host_vdsk(SFSample *sample)
3540
0
{
3541
0
  sf_log_next64(sample, "vdsk_capacity");
3542
0
  sf_log_next64(sample, "vdsk_allocation");
3543
0
  sf_log_next64(sample, "vdsk_available");
3544
0
  sf_log_next32(sample, "vdsk_rd_req");
3545
0
  sf_log_next64(sample, "vdsk_rd_bytes");
3546
0
  sf_log_next32(sample, "vdsk_wr_req");
3547
0
  sf_log_next64(sample, "vdsk_wr_bytes");
3548
0
  sf_log_next32(sample, "vdsk_errs");
3549
0
}
3550
3551
/*_________________----------------------------__________________
3552
  _________________  readCounters_host_vnio    __________________
3553
  -----------------____________________________------------------
3554
*/
3555
3556
static void readCounters_host_vnio(SFSample *sample)
3557
0
{
3558
0
  sf_log_next64(sample, "vnio_bytes_in");
3559
0
  sf_log_next32(sample, "vnio_pkts_in");
3560
0
  sf_log_next32(sample, "vnio_errs_in");
3561
0
  sf_log_next32(sample, "vnio_drops_in");
3562
0
  sf_log_next64(sample, "vnio_bytes_out");
3563
0
  sf_log_next32(sample, "vnio_pkts_out");
3564
0
  sf_log_next32(sample, "vnio_errs_out");
3565
0
  sf_log_next32(sample, "vnio_drops_out");
3566
0
}
3567
3568
/*_________________----------------------------__________________
3569
  _________________  readCounters_memcache     __________________
3570
  -----------------____________________________------------------
3571
*/
3572
3573
static void readCounters_memcache(SFSample *sample)
3574
0
{
3575
0
  sf_log_next32(sample, "memcache_uptime");
3576
0
  sf_log_next32(sample, "memcache_rusage_user");
3577
0
  sf_log_next32(sample, "memcache_rusage_system");
3578
0
  sf_log_next32(sample, "memcache_curr_connections");
3579
0
  sf_log_next32(sample, "memcache_total_connections");
3580
0
  sf_log_next32(sample, "memcache_connection_structures");
3581
0
  sf_log_next32(sample, "memcache_cmd_get");
3582
0
  sf_log_next32(sample, "memcache_cmd_set");
3583
0
  sf_log_next32(sample, "memcache_cmd_flush");
3584
0
  sf_log_next32(sample, "memcache_get_hits");
3585
0
  sf_log_next32(sample, "memcache_get_misses");
3586
0
  sf_log_next32(sample, "memcache_delete_misses");
3587
0
  sf_log_next32(sample, "memcache_delete_hits");
3588
0
  sf_log_next32(sample, "memcache_incr_misses");
3589
0
  sf_log_next32(sample, "memcache_incr_hits");
3590
0
  sf_log_next32(sample, "memcache_decr_misses");
3591
0
  sf_log_next32(sample, "memcache_decr_hits");
3592
0
  sf_log_next32(sample, "memcache_cas_misses");
3593
0
  sf_log_next32(sample, "memcache_cas_hits");
3594
0
  sf_log_next32(sample, "memcache_cas_badval");
3595
0
  sf_log_next32(sample, "memcache_auth_cmds");
3596
0
  sf_log_next32(sample, "memcache_auth_errors");
3597
0
  sf_log_next64(sample, "memcache_bytes_read");
3598
0
  sf_log_next64(sample, "memcache_bytes_written");
3599
0
  sf_log_next32(sample, "memcache_limit_maxbytes");
3600
0
  sf_log_next32(sample, "memcache_accepting_conns");
3601
0
  sf_log_next32(sample, "memcache_listen_disabled_num");
3602
0
  sf_log_next32(sample, "memcache_threads");
3603
0
  sf_log_next32(sample, "memcache_conn_yields");
3604
0
  sf_log_next64(sample, "memcache_bytes");
3605
0
  sf_log_next32(sample, "memcache_curr_items");
3606
0
  sf_log_next32(sample, "memcache_total_items");
3607
0
  sf_log_next32(sample, "memcache_evictions");
3608
0
}
3609
3610
/*_________________----------------------------__________________
3611
  _________________  readCounters_http         __________________
3612
  -----------------____________________________------------------
3613
*/
3614
3615
static void readCounters_http(SFSample *sample)
3616
0
{
3617
0
  sf_log_next32(sample, "http_method_option_count");
3618
0
  sf_log_next32(sample, "http_method_get_count");
3619
0
  sf_log_next32(sample, "http_method_head_count");
3620
0
  sf_log_next32(sample, "http_method_post_count");
3621
0
  sf_log_next32(sample, "http_method_put_count");
3622
0
  sf_log_next32(sample, "http_method_delete_count");
3623
0
  sf_log_next32(sample, "http_method_trace_count");
3624
0
  sf_log_next32(sample, "http_methd_connect_count");
3625
0
  sf_log_next32(sample, "http_method_other_count");
3626
0
  sf_log_next32(sample, "http_status_1XX_count");
3627
0
  sf_log_next32(sample, "http_status_2XX_count");
3628
0
  sf_log_next32(sample, "http_status_3XX_count");
3629
0
  sf_log_next32(sample, "http_status_4XX_count");
3630
0
  sf_log_next32(sample, "http_status_5XX_count");
3631
0
  sf_log_next32(sample, "http_status_other_count");
3632
0
}
3633
3634
/*_________________----------------------------__________________
3635
  _________________  readCounters_CAL          __________________
3636
  -----------------____________________________------------------
3637
*/
3638
3639
static void readCounters_CAL(SFSample *sample)
3640
0
{
3641
0
  sf_log_next32(sample, "transactions");
3642
0
  sf_log_next32(sample, "errors");
3643
0
  sf_log_next64(sample, "duration_uS");
3644
0
}
3645
3646
/*_________________---------------------------__________________
3647
  _________________  readCountersSample_v2v4  __________________
3648
  -----------------___________________________------------------
3649
*/
3650
3651
static void readCountersSample_v2v4(SFSample *sample)
3652
0
{
3653
0
  sf_log("sampleType COUNTERSSAMPLE\n");
3654
0
  sample->samplesGenerated = getData32(sample);
3655
0
  sf_log("sampleSequenceNo %u\n", sample->samplesGenerated);
3656
0
  {
3657
0
    u_int32_t samplerId = getData32(sample);
3658
0
    sample->ds_class = samplerId >> 24;
3659
0
    sample->ds_index = samplerId & 0x00ffffff;
3660
0
  }
3661
0
  sf_log("sourceId %u:%u\n", sample->ds_class, sample->ds_index);
3662
3663
3664
0
  sample->statsSamplingInterval = getData32(sample);
3665
0
  sf_log("statsSamplingInterval %u\n", sample->statsSamplingInterval);
3666
  /* now find out what sort of counter blocks we have here... */
3667
0
  sample->counterBlockVersion = getData32(sample);
3668
0
  sf_log("counterBlockVersion %u\n", sample->counterBlockVersion);
3669
3670
  /* first see if we should read the generic stats */
3671
0
  switch(sample->counterBlockVersion) {
3672
0
  case INMCOUNTERSVERSION_GENERIC:
3673
0
  case INMCOUNTERSVERSION_ETHERNET:
3674
0
  case INMCOUNTERSVERSION_TOKENRING:
3675
0
  case INMCOUNTERSVERSION_FDDI:
3676
0
  case INMCOUNTERSVERSION_VG:
3677
0
  case INMCOUNTERSVERSION_WAN: readCounters_generic(sample); break;
3678
0
  case INMCOUNTERSVERSION_VLAN: break;
3679
0
  default: receiveError(sample, "unknown stats version", YES); break;
3680
0
  }
3681
3682
  /* now see if there are any specific counter blocks to add */
3683
0
  switch(sample->counterBlockVersion) {
3684
0
  case INMCOUNTERSVERSION_GENERIC: /* nothing more */ break;
3685
0
  case INMCOUNTERSVERSION_ETHERNET: readCounters_ethernet(sample); break;
3686
0
  case INMCOUNTERSVERSION_TOKENRING:readCounters_tokenring(sample); break;
3687
0
  case INMCOUNTERSVERSION_FDDI: break;
3688
0
  case INMCOUNTERSVERSION_VG: readCounters_vg(sample); break;
3689
0
  case INMCOUNTERSVERSION_WAN: break;
3690
0
  case INMCOUNTERSVERSION_VLAN: readCounters_vlan(sample); break;
3691
0
  default: receiveError(sample, "unknown INMCOUNTERSVERSION", YES); break;
3692
0
  }
3693
  /* line-by-line output... */
3694
0
}
3695
3696
/*_________________---------------------------__________________
3697
  _________________   readCountersSample      __________________
3698
  -----------------___________________________------------------
3699
*/
3700
3701
static void readCountersSample(SFSample *sample, int expanded)
3702
0
{
3703
0
  u_int32_t sampleLength;
3704
0
  u_int32_t num_elements;
3705
0
  u_char *sampleStart;
3706
0
  sf_log("sampleType COUNTERSSAMPLE\n");
3707
0
  sampleLength = getData32(sample);
3708
0
  sampleStart = (u_char *)sample->datap;
3709
0
  sample->samplesGenerated = getData32(sample);
3710
3711
0
  sf_log("sampleSequenceNo %u\n", sample->samplesGenerated);
3712
0
  if(expanded) {
3713
0
    sample->ds_class = getData32(sample);
3714
0
    sample->ds_index = getData32(sample);
3715
0
  }
3716
0
  else {
3717
0
    u_int32_t samplerId = getData32(sample);
3718
0
    sample->ds_class = samplerId >> 24;
3719
0
    sample->ds_index = samplerId & 0x00ffffff;
3720
0
  }
3721
0
  sf_log("sourceId %u:%u\n", sample->ds_class, sample->ds_index);
3722
3723
0
  num_elements = getData32(sample);
3724
0
  {
3725
0
    u_int32_t el;
3726
0
    for(el = 0; el < num_elements; el++) {
3727
0
      u_int32_t tag, length;
3728
0
      u_char *start;
3729
0
      char buf[51];
3730
0
      tag = getData32(sample);
3731
0
      sf_log("counterBlock_tag %s\n", printTag(tag, buf, 50));
3732
0
      length = getData32(sample);
3733
0
      start = (u_char *)sample->datap;
3734
3735
0
      switch(tag) {
3736
0
      case SFLCOUNTERS_GENERIC: readCounters_generic(sample); break;
3737
0
      case SFLCOUNTERS_ETHERNET: readCounters_ethernet(sample); break;
3738
0
      case SFLCOUNTERS_TOKENRING:readCounters_tokenring(sample); break;
3739
0
      case SFLCOUNTERS_VG: readCounters_vg(sample); break;
3740
0
      case SFLCOUNTERS_VLAN: readCounters_vlan(sample); break;
3741
0
      case SFLCOUNTERS_80211: readCounters_80211(sample); break;
3742
0
      case SFLCOUNTERS_PROCESSOR: readCounters_processor(sample); break;
3743
0
      case SFLCOUNTERS_RADIO: readCounters_radio(sample); break;
3744
0
      case SFLCOUNTERS_HOST_HID: readCounters_host_hid(sample); break;
3745
0
      case SFLCOUNTERS_ADAPTORS: readCounters_adaptors(sample); break;
3746
0
      case SFLCOUNTERS_HOST_PAR: readCounters_host_parent(sample); break;
3747
0
      case SFLCOUNTERS_HOST_CPU: readCounters_host_cpu(sample); break;
3748
0
      case SFLCOUNTERS_HOST_MEM: readCounters_host_mem(sample); break;
3749
0
      case SFLCOUNTERS_HOST_DSK: readCounters_host_dsk(sample); break;
3750
0
      case SFLCOUNTERS_HOST_NIO: readCounters_host_nio(sample); break;
3751
0
      case SFLCOUNTERS_HOST_VRT_NODE: readCounters_host_vnode(sample); break;
3752
0
      case SFLCOUNTERS_HOST_VRT_CPU: readCounters_host_vcpu(sample); break;
3753
0
      case SFLCOUNTERS_HOST_VRT_MEM: readCounters_host_vmem(sample); break;
3754
0
      case SFLCOUNTERS_HOST_VRT_DSK: readCounters_host_vdsk(sample); break;
3755
0
      case SFLCOUNTERS_HOST_VRT_NIO: readCounters_host_vnio(sample); break;
3756
0
      case SFLCOUNTERS_MEMCACHE: readCounters_memcache(sample); break;
3757
0
      case SFLCOUNTERS_HTTP: readCounters_http(sample); break;
3758
0
      case SFLCOUNTERS_CAL: readCounters_CAL(sample); break;
3759
0
      default: skipTLVRecord(sample, tag, length, "counters_sample_element"); break;
3760
0
      }
3761
0
      lengthCheck(sample, "counters_sample_element", start, length);
3762
0
    }
3763
0
  }
3764
0
  lengthCheck(sample, "counters_sample", sampleStart, sampleLength);
3765
  /* line-by-line output... */
3766
0
}
3767
3768
/* =============================================================== */
3769
3770
/* Handles Counters samples as found inside sFlow datagrams once the sample has been properly parsed and put into `sample` */
3771
0
static void handleSflowCountersSample(SFSample *sample) {
3772
3773
0
}
3774
3775
/* =============================================================== */
3776
3777
static void handleSflowSample(sFlowPktInterface *iface,
3778
0
            SFSample *sample, int deviceId) {
3779
0
  struct pcap_pkthdr pkthdr;
3780
0
  u_int32_t msk = 0;
3781
  
3782
0
  msk = sample->meanSkipCount;
3783
3784
0
  if(msk == 0) msk = 1;
3785
3786
#ifdef DEBUG_UPSCALING
3787
  ntop->getTrace()->traceEvent(TRACE_NORMAL, "[SAMPLING] [sample->samplePool: %u][sample->samplesGenerated: %u]",
3788
             sample->samplePool,
3789
             sample->samplesGenerated);
3790
  ntop->getTrace()->traceEvent(TRACE_NORMAL, "[SAMPLING] MeanSkipCount [computed: %u][expected: %u][average: %u]",
3791
             msk, sample->meanSkipCount, averageMsk);
3792
#endif
3793
3794
0
  pkthdr.ts.tv_sec = (long)time(NULL), pkthdr.ts.tv_usec = 0;
3795
0
  pkthdr.caplen = sample->pkt_headerLen;
3796
  /* Always upscale the traffic */
3797
0
  pkthdr.len = sample->sampledPacketSize * msk /* Scale data */;
3798
3799
#ifdef DEBUG_UPSCALING
3800
  ntop->getTrace()->traceEvent(TRACE_NORMAL,
3801
             "[SAMPLING] [portIndex: %u][key: %u]"
3802
             "[sample->sampledPacketSize: %u]"
3803
             "[msk: %u][pkthdr.len: %u]",
3804
             sample->ds_index, key, sample->sampledPacketSize,
3805
             msk, pkthdr.len);
3806
#endif
3807
3808
#ifdef DEBUG_FLOWS
3809
  ntop->getTrace()->traceEvent(TRACE_INFO, "decodePacket(len=%d/%d)", pkthdr.caplen, pkthdr.len);
3810
#endif
3811
3812
0
  u_int16_t p;
3813
0
  Host *srcHost = NULL, *dstHost = NULL;
3814
0
  Flow *flow = NULL;
3815
0
  int datalink_type;
3816
  
3817
0
  switch(sample->headerProtocol) {
3818
0
  case SFLHEADER_IPv4:
3819
0
  case SFLHEADER_IPv6:
3820
0
    datalink_type = DLT_RAW;
3821
0
    break;
3822
3823
0
  default:
3824
0
    datalink_type = DLT_EN10MB;
3825
0
    break;
3826
0
  }
3827
3828
0
  iface->dissectPacket(-1 /* unknown input idx */,
3829
0
           DUMMY_BRIDGE_INTERFACE_ID,
3830
0
           datalink_type,
3831
0
           true, /* ingress - TODO: see if we pass the real packet direction */   
3832
0
           NULL, &pkthdr, sample->pkt_header, &p,
3833
0
           &srcHost, &dstHost, &flow);
3834
0
}  
3835
3836
/*_________________---------------------------__________________
3837
  _________________      readSFlowDatagram    __________________
3838
  -----------------___________________________------------------
3839
*/
3840
3841
0
static void readSFlowDatagram(sFlowPktInterface *iface, SFSample *sample, int deviceId) {
3842
0
  u_int32_t samplesInPacket;
3843
0
  struct timeval now;
3844
0
  char buf[51];
3845
3846
  /* log some datagram info */
3847
0
  now.tv_sec = (long)time(NULL);
3848
0
  now.tv_usec = 0;
3849
0
  sf_log("datagramSourceIP %s\n", IP_to_a(ntohl(sample->sourceIP.s_addr), buf, sizeof(buf)));
3850
0
  sf_log("datagramSize %u\n", sample->rawSampleLen);
3851
0
  sf_log("unixSecondsUTC %u\n", now.tv_sec);
3852
0
  if(sample->pcapTimestamp) sf_log("pcapTimestamp %s\n", ctime(&sample->pcapTimestamp)); // thanks to Richard Clayton for this bugfix
3853
3854
  /* check the version */
3855
0
  sample->datagramVersion = getData32(sample);
3856
0
  sf_log("datagramVersion %d\n", sample->datagramVersion);
3857
3858
0
  switch(sample->datagramVersion) {
3859
0
  case 2:
3860
0
    numsFlowsV2Rcvd++;
3861
0
    break;
3862
0
  case 4:
3863
0
    numsFlowsV4Rcvd++;
3864
0
    break;
3865
0
  case 5:
3866
0
    numsFlowsV5Rcvd++;
3867
0
    break;
3868
0
  default:
3869
0
    numBadsFlowsVersionsRcvd++;
3870
0
    break;
3871
0
  }
3872
3873
0
  if(sample->datagramVersion != 2 &&
3874
0
     sample->datagramVersion != 4 &&
3875
0
     sample->datagramVersion != 5) {
3876
0
    receiveError(sample,  "unexpected datagram version number\n", YES);
3877
0
  }
3878
3879
0
  u_int32_t original_ip = sample->agent_addr.address.ip_v4.addr; /* Save the original IPv4 */
3880
  
3881
  /* get the agent address */
3882
0
  getAddress(sample, &sample->agent_addr);
3883
3884
0
  if((sample->agent_addr.type == 1 /* IPv4 */) && (original_ip != 0)) {
3885
    /* Restore the riginal IP as it might have been reforged via --collector-nf-reforge c*/
3886
0
    sample->agent_addr.address.ip_v4.addr = original_ip;
3887
0
  }
3888
  
3889
  /* version 5 has an agent sub-id as well */
3890
0
  if(sample->datagramVersion >= 5) {
3891
0
    sample->agentSubId = getData32(sample);
3892
0
    sf_log("agentSubId %u\n", sample->agentSubId);
3893
0
  }
3894
3895
0
  sample->sequenceNo = getData32(sample);  /* this is the packet sequence number */
3896
0
  sample->sysUpTime = getData32(sample);
3897
0
  samplesInPacket = getData32(sample);
3898
0
  sf_log("agent %s\n", printAddress(&sample->agent_addr, buf, 50));
3899
0
  sf_log("packetSequenceNo %u\n", sample->sequenceNo);
3900
0
  sf_log("sysUpTime %u\n", sample->sysUpTime);
3901
0
  sf_log("samplesInPacket %u\n", samplesInPacket);
3902
3903
  /* now iterate and pull out the flows and counters samples */
3904
0
  {
3905
0
    u_int32_t samp = 0, rc;
3906
3907
0
    for(; samp < samplesInPacket; samp++) {
3908
0
      if((u_char *)sample->datap >= sample->endp) {
3909
0
  fprintf(stderr, "unexpected end of datagram after sample %u of %u\n", samp, samplesInPacket);
3910
0
  SFABORT(sample, SF_ABORT_EOS);
3911
0
  break;
3912
0
      }
3913
      // just read the tag, then call the approriate decode fn
3914
0
      rc = 0;
3915
0
      sample->sampleType = getData32(sample);
3916
0
      sf_log("startSample ----------------------\n");
3917
0
      sf_log("sampleType_tag %s\n", printTag(sample->sampleType, buf, 50));
3918
0
      if(sample->datagramVersion >= 5) {
3919
0
  switch(sample->sampleType) {
3920
0
  case SFLFLOW_SAMPLE: rc = readFlowSample(sample, NO); break;
3921
0
  case SFLCOUNTERS_SAMPLE: readCountersSample(sample, NO); handleSflowCountersSample(sample); break;
3922
0
  case SFLFLOW_SAMPLE_EXPANDED: readFlowSample(sample, YES); break;
3923
0
  case SFLCOUNTERS_SAMPLE_EXPANDED: readCountersSample(sample, YES); handleSflowCountersSample(sample); break;
3924
0
  default:
3925
0
    skipTLVRecord(sample, sample->sampleType, getData32(sample), "sample"); break;
3926
0
  }
3927
0
      }
3928
0
      else {
3929
0
  switch(sample->sampleType) {
3930
0
  case FLOWSAMPLE: rc = readFlowSample_v2v4(sample); break;
3931
0
  case COUNTERSSAMPLE: readCountersSample_v2v4(sample); handleSflowCountersSample(sample); break;
3932
0
  default: receiveError(sample, "unexpected sample type", YES); break;
3933
0
  }
3934
0
      }
3935
0
      sf_log("endSample   ----------------------\n");
3936
3937
0
      if((sample->sampleType == SFLFLOW_SAMPLE) || (sample->sampleType == SFLFLOW_SAMPLE_EXPANDED)) {
3938
3939
0
  if(rc == 0)
3940
0
    handleSflowSample(iface, sample, deviceId);
3941
0
  else
3942
0
    break;
3943
0
      }
3944
0
    }
3945
0
  }
3946
0
}
3947
3948
/* ****************************************** */
3949
3950
void dissectSflow(sFlowPktInterface *iface,
3951
      u_char *buffer, uint buffer_len,
3952
0
      struct sockaddr_in *fromHost) {
3953
0
  SFSample sample;
3954
  
3955
0
  memset(&sample, 0, sizeof(sample));
3956
0
  sample.rawSample = buffer;
3957
0
  sample.rawSampleLen = buffer_len;
3958
3959
  /* Read the IPv4 address from sFlow */
3960
0
  if(sample.rawSample[3] == 0x5 /* sFlow v5 */)
3961
0
    sample.sourceIP.s_addr = *((u_int32_t*)&sample.rawSample[8]);
3962
0
  else {
3963
0
    if(fromHost != NULL)
3964
0
      sample.sourceIP = fromHost->sin_addr;
3965
0
    else
3966
0
      sample.sourceIP.s_addr = 0;
3967
0
  }
3968
  
3969
0
  sample.datap = (u_char *)sample.rawSample;
3970
0
  sample.endp = (u_char *)sample.rawSample + sample.rawSampleLen;
3971
3972
0
  readSFlowDatagram(iface, &sample, 0 /* deviceId */);
3973
0
}