1 /*
2 * Copyright (c) 2017-2020, Peter Haag
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the author nor the names of its contributors may be
14 * used to endorse or promote products derived from this software without
15 * specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 */
30
31 /*
32 * sfcapd makes use of code originated from sflowtool by InMon Corp.
33 * Those parts of the code are distributed under the InMon Public License below.
34 * All other/additional code is pubblished under BSD license.
35 */
36
37 // include sflow functions
38 // based on sflowtool https://github.com/sflow/sflowtool
39 // commit 7322984 on Jul 21 2017
40
41 /* Copyright (c) 2002-2011 InMon Corp. Licensed under the terms of the InMon sFlow licence: */
42 /* http://www.inmon.com/technology/sflowlicense.txt */
43
44 #include "config.h"
45
46 #include <stdio.h>
47 #include <stdarg.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <errno.h>
51 #include <sys/types.h>
52 #include <time.h>
53 #include <ctype.h>
54 #include <setjmp.h>
55
56 #include <unistd.h>
57 #include <netdb.h>
58 #include <sys/socket.h>
59 #include <netinet/in.h>
60 #include <arpa/inet.h>
61 #include <sys/time.h>
62
63 #ifdef HAVE_STDINT_H
64 #include <stdint.h>
65 #endif
66
67 #include "nfdump.h"
68 #include "sflow.h" /* sFlow v5 */
69 #include "sflow_v2v4.h" /* sFlow v2/4 */
70 #include "util.h"
71 #include "sflow_process.h"
72 #include "sflow_nfdump.h"
73
74 static uint8_t bin2hex(int nib);
75 static int printHex(const uint8_t *a, int len, char *buf, int bufLen, int marker, int bytesPerOutputLine);
76 static char *IP_to_a(uint32_t ipaddr, char *buf, int buflen);
77 static char *printAddress(SFLAddress *address, char *buf, int bufLen);
78 static void writeFlowLine(SFSample *sample);
79 static void receiveError(SFSample *sample, char *errm, int hexdump);
80 static void lengthCheck(SFSample *sample, char *description, u_char *start, int len);
81 static void decodeLinkLayer(SFSample *sample);
82 static void decode80211MAC(SFSample *sample);
83 static void decodeIPLayer4(SFSample *sample, uint8_t *ptr);
84 static void decodeIPV4(SFSample *sample);
85 static void decodeIPV6(SFSample *sample);
86 static inline uint32_t getData32_nobswap(SFSample *sample);
87 static inline uint32_t getData32(SFSample *sample);
88 static inline uint64_t getData64(SFSample *sample);
89 static inline void skipBytes(SFSample *sample, uint32_t skip);
90 static uint32_t sf_log_next32(SFSample *sample, char *fieldName);
91 static uint64_t sf_log_next64(SFSample *sample, char *fieldName);
92 static inline uint32_t getString(SFSample *sample, char *buf, uint32_t bufLen);
93 static uint32_t getAddress(SFSample *sample, SFLAddress *address);
94 static void skipTLVRecord(SFSample *sample, uint32_t tag, uint32_t len, char *description);
95 static void readExtendedSwitch(SFSample *sample);
96 static void readExtendedRouter(SFSample *sample);;
97 static void readExtendedGateway_v2(SFSample *sample);
98 static void readExtendedGateway(SFSample *sample);
99 static void readExtendedUser(SFSample *sample);
100 static void readExtendedUrl(SFSample *sample);
101 static void mplsLabelStack(SFSample *sample, char *fieldName);
102 static void readExtendedMpls(SFSample *sample);
103 static void readExtendedNat(SFSample *sample);
104 static void readExtendedNatPort(SFSample *sample);
105 static void readExtendedMplsTunnel(SFSample *sample);
106 static void readExtendedMplsVC(SFSample *sample);
107 static void readExtendedMplsFTN(SFSample *sample);
108 static void readExtendedMplsLDP_FEC(SFSample *sample);
109 static void readExtendedVlanTunnel(SFSample *sample);
110 static void readExtendedWifiPayload(SFSample *sample);
111 static void readExtendedWifiRx(SFSample *sample);
112 static void readExtendedWifiTx(SFSample *sample);
113 static void readFlowSample_header(SFSample *sample);
114 static void readFlowSample_ethernet(SFSample *sample, char *prefix);
115 static void readFlowSample_IPv4(SFSample *sample, char *prefix);
116 static void readFlowSample_IPv6(SFSample *sample, char *prefix);
117 static void readFlowSample_memcache(SFSample *sample);
118 static void readFlowSample_http(SFSample *sample, uint32_t tag);
119 static void readFlowSample_APP(SFSample *sample);
120 static void readFlowSample_APP_CTXT(SFSample *sample);
121 static void readFlowSample_APP_ACTOR_INIT(SFSample *sample);
122 static void readFlowSample_APP_ACTOR_TGT(SFSample *sample);
123 static void readExtendedSocket4(SFSample *sample);
124 static void readExtendedProxySocket4(SFSample *sample);
125 static void readExtendedSocket6(SFSample *sample);
126 static void readExtendedProxySocket6(SFSample *sample);
127 static void readExtendedDecap(SFSample *sample, char *prefix);
128 static void readExtendedVNI(SFSample *sample, char *prefix);
129 static void readExtendedTCPInfo(SFSample *sample);
130 static void readFlowSample_v2v4(SFSample *sample, FlowSource_t *fs, int verbose);
131 static void readFlowSample(SFSample *sample, int expanded, FlowSource_t *fs, int verbose);
132
133 #ifdef DEVEL
134 static inline char *printTag(uint32_t tag, char *buf, int bufLen);
135 static char *URLEncode(char *in, char *out, int outlen);
136 static int printUUID(const uint8_t *a, char *buf, int bufLen);
137 static void sf_log_percentage(SFSample *sample, char *fieldName);
138 static float sf_log_nextFloat(SFSample *sample, char *fieldName);
139 static void sf_log_nextMAC(SFSample *sample, char *fieldName);
140 static inline double getDouble(SFSample *sample);
141 static inline float getFloat(SFSample *sample);
142 static void writeCountersLine(SFSample *sample);
143 static void readCounters_generic(SFSample *sample);
144 static void readCounters_ethernet(SFSample *sample);
145 static void readCounters_tokenring(SFSample *sample);
146 static void readCounters_vg(SFSample *sample);
147 static void readCounters_vlan(SFSample *sample);
148 static void readCounters_80211(SFSample *sample);
149 static void readCounters_processor(SFSample *sample);
150 static void readCounters_radio(SFSample *sample);
151 static void readCounters_OFPort(SFSample *sample);
152 static void readCounters_portName(SFSample *sample);
153 static void readCounters_OVSDP(SFSample *sample);
154 static void readCounters_host_hid(SFSample *sample);
155 static void readCounters_adaptors(SFSample *sample);
156 static void readCounters_host_parent(SFSample *sample);
157 static void readCounters_host_cpu(SFSample *sample, uint32_t length);
158 static void readCounters_host_mem(SFSample *sample);
159 static void readCounters_host_dsk(SFSample *sample);
160 static void readCounters_host_nio(SFSample *sample);
161 static void readCounters_host_ip(SFSample *sample);
162 static void readCounters_host_icmp(SFSample *sample);
163 static void readCounters_host_tcp(SFSample *sample);
164 static void readCounters_host_udp(SFSample *sample);
165 static void readCounters_host_vnode(SFSample *sample);
166 static void readCounters_host_vcpu(SFSample *sample);
167 static void readCounters_host_vmem(SFSample *sample);
168 static void readCounters_host_vdsk(SFSample *sample);
169 static void readCounters_host_vnio(SFSample *sample);
170 static void readCounters_host_gpu_nvml(SFSample *sample);
171 static void readCounters_bcm_tables(SFSample *sample);
172 static void readCounters_memcache(SFSample *sample);
173 static void readCounters_memcache2(SFSample *sample);
174 static void readCounters_http(SFSample *sample);
175 static void readCounters_JVM(SFSample *sample);
176 static void readCounters_JMX(SFSample *sample, uint32_t length);
177 static void readCounters_APP(SFSample *sample);
178 static void readCounters_APP_RESOURCE(SFSample *sample);
179 static void readCounters_APP_WORKERS(SFSample *sample);
180 static void readCounters_VDI(SFSample *sample);
181 static void readCounters_LACP(SFSample *sample);
182 static void readCounters_SFP(SFSample *sample);
183 static void readCountersSample_v2v4(SFSample *sample, FlowSource_t *fs, int verbose);
184 static void readCountersSample(SFSample *sample, int expanded, FlowSource_t *fs, int verbose);
185 static void readRTMetric(SFSample *sample, FlowSource_t *fs, int verbose);
186 static void readRTFlow(SFSample *sample, FlowSource_t *fs, int verbose);
187
printTag(uint32_t tag,char * buf,int bufLen)188 static inline char *printTag(uint32_t tag, char *buf, int bufLen) {
189 snprintf(buf, bufLen, "%u:%u", (tag >> 12), (tag & 0x00000FFF));
190 return buf;
191 } // End of printTag
192
193 /*_________________---------------------------__________________
194 _________________ URLEncode __________________
195 -----------------___________________________------------------
196 */
197
URLEncode(char * in,char * out,int outlen)198 char *URLEncode(char *in, char *out, int outlen) {
199 register char c, *r = in, *w = out;
200 int maxlen = (strlen(in) * 3) + 1;
201
202 if(outlen < maxlen)
203 return "URLEncode: not enough space";
204
205 while ((c = *r++)) {
206 if(isalnum(c))
207 *w++ = c;
208 else if(isspace(c))
209 *w++ = '+';
210 else {
211 *w++ = '%';
212 *w++ = bin2hex(c >> 4);
213 *w++ = bin2hex(c & 0x0f);
214 }
215 }
216 *w++ = '\0';
217 return out;
218 } // End of URLEncode
219
220 /*_________________---------------------------__________________
221 _________________ printUUID __________________
222 -----------------___________________________------------------
223 */
224
printUUID(const uint8_t * a,char * buf,int bufLen)225 static int printUUID(const uint8_t *a, char *buf, int bufLen) {
226 int i, b = 0;
227
228 b += printHex(a, 4, buf, bufLen, 0, 100);
229 buf[b++] = '-';
230 b += printHex(a + 4, 2, buf + b, bufLen - b, 0, 100);
231 buf[b++] = '-';
232 b += printHex(a + 6, 2, buf + b, bufLen - b, 0, 100);
233 buf[b++] = '-';
234 b += printHex(a + 8, 2, buf + b, bufLen - b, 0, 100);
235 buf[b++] = '-';
236 b += printHex(a + 10, 6, buf + b, bufLen - b, 0, 100);
237
238 /* should really be lowercase hex - fix that here */
239 for(i = 0; i < b; i++) buf[i] = tolower(buf[i]);
240
241 /* add NUL termination */
242 buf[b] = '\0';
243
244 return b;
245 }
246
247 #endif
248
249
250 /*_________________---------------------------__________________
251 _________________ printHex __________________
252 -----------------___________________________------------------
253 */
254
bin2hex(int nib)255 static uint8_t bin2hex(int nib) { return (nib < 10) ? ('0' + nib) : ('A' - 10 + nib); }
256
printHex(const uint8_t * a,int len,char * buf,int bufLen,int marker,int bytesPerOutputLine)257 static int printHex(const uint8_t *a, int len, char *buf, int bufLen, int marker, int bytesPerOutputLine) {
258 int b = 0, i;
259
260 for(i = 0; i < len; i++) {
261 uint8_t byte;
262 if(b > (bufLen - 10))
263 break;
264 if(marker > 0 && i == marker) {
265 buf[b++] = '<';
266 buf[b++] = '*';
267 buf[b++] = '>';
268 buf[b++] = '-';
269 }
270 byte = a[i];
271 buf[b++] = bin2hex(byte >> 4);
272 buf[b++] = bin2hex(byte & 0x0f);
273 if (i > 0 && (i % bytesPerOutputLine) == 0) {
274 buf[b++] = '\n';
275 } else {
276 /* separate the bytes with a dash */
277 if (i < (len - 1))
278 buf[b++] = '-';
279 }
280 }
281 buf[b] = '\0';
282 return b;
283 } // End of printHex
284
285
286 /*_________________---------------------------__________________
287 _________________ IP_to_a __________________
288 -----------------___________________________------------------
289 */
290
IP_to_a(uint32_t ipaddr,char * buf,int buflen)291 static char *IP_to_a(uint32_t ipaddr, char *buf, int buflen) {
292 uint8_t *ip = (uint8_t *)&ipaddr;
293
294 snprintf(buf, buflen, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
295 buf[buflen-1] = '\0';
296 return buf;
297 } // End of IP_to_a
298
printAddress(SFLAddress * address,char * buf,int bufLen)299 static char *printAddress(SFLAddress *address, char *buf, int bufLen) {
300
301 switch(address->type) {
302 case SFLADDRESSTYPE_IP_V4:
303 IP_to_a(address->address.ip_v4.addr, buf, bufLen);
304 break;
305 case SFLADDRESSTYPE_IP_V6: {
306 uint8_t *b = address->address.ip_v6.addr;
307 snprintf(buf, bufLen, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
308 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]);
309 } break;
310 default:
311 sprintf(buf, "-");
312 }
313 return buf;
314 } // End of printAddress
315
316 /*_________________---------------------------__________________
317 _________________ writeFlowLine __________________
318 -----------------___________________________------------------
319 */
320
writeFlowLine(SFSample * sample)321 static void writeFlowLine(SFSample *sample) {
322 char agentIP[51], srcIP[51], dstIP[51];
323
324 // source
325 printf("FLOW,%s,%d,%d,", printAddress(&sample->agent_addr, agentIP, 50),
326 sample->inputPort, sample->outputPort);
327
328 // layer 2
329 printf("%02x%02x%02x%02x%02x%02x,%02x%02x%02x%02x%02x%02x,0x%04x,%d,%d",
330 sample->eth_src[0], sample->eth_src[1], sample->eth_src[2],
331 sample->eth_src[3], sample->eth_src[4], sample->eth_src[5],
332 sample->eth_dst[0], sample->eth_dst[1], sample->eth_dst[2],
333 sample->eth_dst[3], sample->eth_dst[4], sample->eth_dst[5],
334 sample->eth_type, sample->in_vlan, sample->out_vlan);
335
336 // layer 3/4
337 printf(",IP: %s,%s,%d,0x%02x,%d,%d,%d,0x%02x",
338 IP_to_a(sample->dcd_srcIP.s_addr, srcIP, 51), IP_to_a(sample->dcd_dstIP.s_addr, dstIP, 51),
339 sample->dcd_ipProtocol, sample->dcd_ipTos, sample->dcd_ipTTL,
340 sample->dcd_sport, sample->dcd_dport, sample->dcd_tcpFlags);
341
342 // bytes
343 printf(",%d,%d,%d\n", sample->sampledPacketSize,
344 sample->sampledPacketSize - sample->stripped - sample->offsetToIPV4, sample->meanSkipCount);
345 } // End of writeFlowLine
346
347 #ifdef DEVEL
348 /*_________________---------------------------__________________
349 _________________ writeCountersLine __________________
350 -----------------___________________________------------------
351 */
352
writeCountersLine(SFSample * sample)353 static void writeCountersLine(SFSample *sample) {
354 char agentIP[51];
355
356 // source
357 printf("CNTR,%s,", printAddress(&sample->agent_addr, agentIP, 50));
358 printf("%u,%u,%llu,%u,%u,%llu,%u,%u,%u,%u,%u,%u,%llu,%u,%u,%u,%u,%u,%u\n",
359 sample->ifCounters.ifIndex, sample->ifCounters.ifType,
360 (unsigned long long)sample->ifCounters.ifSpeed, sample->ifCounters.ifDirection,
361 sample->ifCounters.ifStatus, (unsigned long long)sample->ifCounters.ifInOctets,
362 sample->ifCounters.ifInUcastPkts, sample->ifCounters.ifInMulticastPkts,
363 sample->ifCounters.ifInBroadcastPkts, sample->ifCounters.ifInDiscards,
364 sample->ifCounters.ifInErrors, sample->ifCounters.ifInUnknownProtos,
365 (unsigned long long)sample->ifCounters.ifOutOctets, sample->ifCounters.ifOutUcastPkts,
366 sample->ifCounters.ifOutMulticastPkts, sample->ifCounters.ifOutBroadcastPkts,
367 sample->ifCounters.ifOutDiscards, sample->ifCounters.ifOutErrors,
368 sample->ifCounters.ifPromiscuousMode);
369 } // End of writeCountersLine
370
371 #endif
372
373 /*_________________---------------------------__________________
374 _________________ receiveError __________________
375 -----------------___________________________------------------
376 */
377
receiveError(SFSample * sample,char * errm,int hexdump)378 static void receiveError(SFSample *sample, char *errm, int hexdump) {
379 char ipbuf[51];
380 char scratch[6000];
381 char *msg = "";
382 char *hex = "";
383 uint32_t markOffset = (u_char *)sample->datap - sample->rawSample;
384
385 if(errm)
386 msg = errm;
387
388 if(hexdump) {
389 printHex(sample->rawSample, sample->rawSampleLen, scratch, 6000, markOffset, 16);
390 hex = scratch;
391 }
392 LogError("SFLOW: %s (source IP = %s) %s", msg, IP_to_a(sample->sourceIP.s_addr, ipbuf, 51), hex);
393
394 // return instead of SFABORT receive functions return as well
395
396 } // End of receiveError
397
398 /*_________________---------------------------__________________
399 _________________ lengthCheck __________________
400 -----------------___________________________------------------
401 */
402
lengthCheck(SFSample * sample,char * description,u_char * start,int len)403 static void lengthCheck(SFSample *sample, char *description, u_char *start, int len) {
404 uint32_t actualLen = (uint8_t *)sample->datap - start;
405 uint32_t adjustedLen = ((len + 3) >> 2) << 2;
406
407 if(actualLen != adjustedLen) {
408 dbg_printf("%s length error (expected %d, found %d)\n", description, len, actualLen);
409 LogError("SFLOW: %s length error (expected %d, found %d)", description, len, actualLen);
410 SFABORT(sample, SF_ABORT_LENGTH_ERROR);
411 }
412 } // End of lengthCheck
413
414 /*_________________---------------------------__________________
415 _________________ decodeLinkLayer __________________
416 -----------------___________________________------------------
417 store the offset to the start of the ipv4 header in the sequence_number field
418 or -1 if not found. Decode the 802.1d if it's there.
419 */
420
421 #define NFT_ETHHDR_SIZ 14
422 #define NFT_8022_SIZ 3
423 #define NFT_MAX_8023_LEN 1500
424
425 #define NFT_MIN_SIZ (NFT_ETHHDR_SIZ + sizeof(struct myiphdr))
426
decodeLinkLayer(SFSample * sample)427 static void decodeLinkLayer(SFSample *sample) {
428 uint8_t *start = sample->header;
429 uint8_t *end = start + sample->headerLen;
430 uint8_t *ptr = start;
431 uint16_t type_len;
432
433 /* assume not found */
434 sample->gotIPV4 = NO;
435 sample->gotIPV6 = NO;
436
437 if((end - ptr) < NFT_ETHHDR_SIZ)
438 /* not enough for an Ethernet header */
439 return;
440
441 dbg_printf("dstMAC %02x%02x%02x%02x%02x%02x\n", ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
442 memcpy(sample->eth_dst, ptr, 6);
443 ptr += 6;
444 dbg_printf("srcMAC %02x%02x%02x%02x%02x%02x\n", ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
445 memcpy(sample->eth_src, ptr, 6);
446 ptr += 6;
447 type_len = (ptr[0] << 8) + ptr[1];
448 ptr += 2;
449
450 if(type_len == 0x8100) {
451 if((end - ptr) < 4)
452 /* not enough for an 802.1Q header */
453 return;
454
455 /* VLAN - next two bytes */
456 uint32_t vlanData = (ptr[0] << 8) + ptr[1];
457 uint32_t vlan = vlanData & 0x0fff;
458 #ifdef DEVEL
459 uint32_t priority = vlanData >> 13;
460 #endif
461 ptr += 2;
462
463 /* _____________________________________ */
464 /* | pri | c | vlan-id | */
465 /* ------------------------------------- */
466 /* [priority = 3bits] [Canonical Format Flag = 1bit] [vlan-id = 12 bits] */
467 dbg_printf("decodedVLAN %u\n", vlan);
468 dbg_printf("decodedPriority %u\n", priority);
469 sample->in_vlan = vlan;
470 /* now get the type_len again (next two bytes) */
471 type_len = (ptr[0] << 8) + ptr[1];
472 ptr += 2;
473 }
474
475 /* now we're just looking for IP */
476 if((end - start) < sizeof(struct myiphdr)) return; /* not enough for an IPv4 header (or IPX, or SNAP) */
477
478 /* peek for IPX */
479 if(type_len == 0x0200 || type_len == 0x0201 || type_len == 0x0600) {
480 #define IPX_HDR_LEN 30
481 #define IPX_MAX_DATA 546
482 int ipxChecksum = (ptr[0] == 0xff && ptr[1] == 0xff);
483 int ipxLen = (ptr[2] << 8) + ptr[3];
484 if(ipxChecksum && ipxLen >= IPX_HDR_LEN && ipxLen <= (IPX_HDR_LEN + IPX_MAX_DATA))
485 /* we don't do anything with IPX here */
486 return;
487 }
488
489 if(type_len <= NFT_MAX_8023_LEN) {
490 /* assume 802.3+802.2 header */
491 /* check for SNAP */
492 if(ptr[0] == 0xAA && ptr[1] == 0xAA && ptr[2] == 0x03) {
493 ptr += 3;
494 if(ptr[0] != 0 || ptr[1] != 0 || ptr[2] != 0) {
495 dbg_printf("VSNAP_OUI %02X-%02X-%02X\n", ptr[0], ptr[1], ptr[2]);
496 /* no further decode for vendor-specific protocol */
497 return;
498 }
499 ptr += 3;
500 /* OUI == 00-00-00 means the next two bytes are the ethernet type (RFC 2895) */
501 type_len = (ptr[0] << 8) + ptr[1];
502 ptr += 2;
503 } else {
504 if (ptr[0] == 0x06 && ptr[1] == 0x06 && (ptr[2] & 0x01)) {
505 /* IP over 8022 */
506 ptr += 3;
507 /* force the type_len to be IP so we can inline the IP decode below */
508 type_len = 0x0800;
509 } else
510 return;
511 }
512 }
513
514 /* assume type_len is an ethernet-type now */
515 sample->eth_type = type_len;
516
517 if(type_len == 0x0800) {
518 /* IPV4 - check again that we have enough header bytes */
519 if((end - ptr) < sizeof(struct myiphdr))
520 return;
521 /* look at first byte of header.... */
522 /* ___________________________ */
523 /* | version | hdrlen | */
524 /* --------------------------- */
525 if((*ptr >> 4) != 4)
526 /* not version 4 */
527 return;
528 if((*ptr & 15) < 5)
529 /* not IP (hdr len must be 5 quads or more) */
530 return;
531 /* survived all the tests - store the offset to the start of the ip header */
532 sample->gotIPV4 = YES;
533 sample->offsetToIPV4 = (ptr - start);
534 }
535
536 if(type_len == 0x86DD) {
537 /* IPV6 */
538 /* look at first byte of header.... */
539 if((*ptr >> 4) != 6)
540 /* not version 6 */
541 return;
542 /* survived all the tests - store the offset to the start of the ip6 header */
543 sample->gotIPV6 = YES;
544 sample->offsetToIPV6 = (ptr - start);
545 }
546 } // End of decodeLinkLayer
547
548 #define WIFI_MIN_HDR_SIZ 24
549
550 // uncomment unused variables to keep compiler happy
decode80211MAC(SFSample * sample)551 static void decode80211MAC(SFSample *sample) {
552 uint8_t *start = sample->header;
553 // uint8_t *end = start + sample->headerLen;
554 uint8_t *ptr = start;
555
556 /* assume not found */
557 sample->gotIPV4 = NO;
558 sample->gotIPV6 = NO;
559
560 if(sample->headerLen < WIFI_MIN_HDR_SIZ)
561 /* not enough for an 80211 MAC header */
562 return;
563
564 uint32_t fc = (ptr[1] << 8) + ptr[0]; /* [b7..b0][b15..b8] */
565 uint32_t control = (fc >> 2) & 3;
566 uint32_t toDS = (fc >> 8) & 1;
567 uint32_t fromDS = (fc >> 9) & 1;
568
569 /* not used
570 uint32_t protocolVersion = fc & 3;
571 uint32_t subType = (fc >> 4) & 15;
572 uint32_t moreFrag = (fc >> 10) & 1;
573 uint32_t retry = (fc >> 11) & 1;
574 uint32_t pwrMgt = (fc >> 12) & 1;
575 uint32_t moreData = (fc >> 13) & 1;
576 uint32_t encrypted = (fc >> 14) & 1;
577 uint32_t order = fc >> 15;
578 */
579 ptr += 2;
580
581 // uint32_t duration_id = (ptr[1] << 8) + ptr[0]; /* not in network byte order either? */
582 ptr += 2;
583
584 switch(control) {
585 case 0: /* mgmt */
586 case 1: /* ctrl */
587 case 3: /* rsvd */
588 break;
589 case 2: { /* data */
590 uint8_t *macAddr1 = ptr;
591 ptr += 6;
592 uint8_t *macAddr2 = ptr;
593 ptr += 6;
594 uint8_t *macAddr3 = ptr;
595 ptr += 6;
596 // uint32_t sequence = (ptr[0] << 8) + ptr[1];
597 ptr += 2;
598
599 /* ToDS FromDS Addr1 Addr2 Addr3 Addr4
600 0 0 DA SA BSSID N/A (ad-hoc)
601 0 1 DA BSSID SA N/A
602 1 0 BSSID SA DA N/A
603 1 1 RA TA DA SA (wireless bridge) */
604
605 uint8_t *rxMAC = macAddr1;
606 uint8_t *txMAC = macAddr2;
607 uint8_t *srcMAC = NULL;
608 uint8_t *dstMAC = NULL;
609
610 if(toDS) {
611 dstMAC = macAddr3;
612 if(fromDS) {
613 srcMAC = ptr; /* macAddr4. 1,1 => (wireless bridge) */
614 ptr += 6;
615 } else
616 srcMAC = macAddr2; /* 1,0 */
617 } else {
618 dstMAC = macAddr1;
619 if(fromDS)
620 srcMAC = macAddr3; /* 0,1 */
621 else
622 srcMAC = macAddr2; /* 0,0 */
623 }
624
625 if(srcMAC) {
626 dbg_printf("srcMAC %02x%02x%02x%02x%02x%02x\n", srcMAC[0], srcMAC[1], srcMAC[2], srcMAC[3], srcMAC[4], srcMAC[5]);
627 memcpy(sample->eth_src, srcMAC, 6);
628 }
629 if(dstMAC) {
630 dbg_printf("dstMAC %02x%02x%02x%02x%02x%02x\n", dstMAC[0], dstMAC[1], dstMAC[2], dstMAC[3], dstMAC[4], dstMAC[5]);
631 memcpy(sample->eth_dst, dstMAC, 6);
632 }
633 if(txMAC)
634 dbg_printf("txMAC %02x%02x%02x%02x%02x%02x\n", txMAC[0], txMAC[1], txMAC[2], txMAC[3], txMAC[4], txMAC[5]);
635 if(rxMAC)
636 dbg_printf("rxMAC %02x%02x%02x%02x%02x%02x\n", rxMAC[0], rxMAC[1], rxMAC[2], rxMAC[3], rxMAC[4], rxMAC[5]);
637 } break;
638 }
639 } // End of decode80211MAC
640
641
642 /*_________________---------------------------__________________
643 _________________ decodeIPLayer4 __________________
644 -----------------___________________________------------------
645 */
646
decodeIPLayer4(SFSample * sample,uint8_t * ptr)647 static void decodeIPLayer4(SFSample *sample, uint8_t *ptr) {
648 uint8_t *end = sample->header + sample->headerLen;
649
650 if(ptr > (end - 8)) {
651 /* not enough header bytes left */
652 return;
653 }
654
655 switch(sample->dcd_ipProtocol) {
656 case 1: { /* ICMP */
657 struct myicmphdr icmp;
658 memcpy(&icmp, ptr, sizeof(icmp));
659 dbg_printf("ICMPType %u\n", icmp.type);
660 dbg_printf("ICMPCode %u\n", icmp.code);
661 sample->dcd_sport = icmp.type;
662 sample->dcd_dport = icmp.code;
663 sample->offsetToPayload = ptr + sizeof(icmp) - sample->header;
664 } break;
665 case 6: {/* TCP */
666 struct mytcphdr tcp;
667 int headerBytes;
668 memcpy(&tcp, ptr, sizeof(tcp));
669 sample->dcd_sport = ntohs(tcp.th_sport);
670 sample->dcd_dport = ntohs(tcp.th_dport);
671 sample->dcd_tcpFlags = tcp.th_flags;
672 dbg_printf("TCPSrcPort %u\n", sample->dcd_sport);
673 dbg_printf("TCPDstPort %u\n",sample->dcd_dport);
674 dbg_printf("TCPFlags %u\n", sample->dcd_tcpFlags);
675 headerBytes = (tcp.th_off_and_unused >> 4) * 4;
676 ptr += headerBytes;
677 sample->offsetToPayload = ptr - sample->header;
678 } break;
679 case 17: { /* UDP */
680 struct myudphdr udp;
681 memcpy(&udp, ptr, sizeof(udp));
682 sample->dcd_sport = ntohs(udp.uh_sport);
683 sample->dcd_dport = ntohs(udp.uh_dport);
684 sample->udp_pduLen = ntohs(udp.uh_ulen);
685 dbg_printf("UDPSrcPort %u\n", sample->dcd_sport);
686 dbg_printf("UDPDstPort %u\n", sample->dcd_dport);
687 dbg_printf("UDPBytes %u\n", sample->udp_pduLen);
688 sample->offsetToPayload = ptr + sizeof(udp) - sample->header;
689 } break;
690 default: /* some other protcol */
691 sample->offsetToPayload = ptr - sample->header;
692 break;
693 }
694 } // End of decodeIPLayer4
695
696
697 /*_________________---------------------------__________________
698 _________________ decodeIPV4 __________________
699 -----------------___________________________------------------
700 */
701
decodeIPV4(SFSample * sample)702 static void decodeIPV4(SFSample *sample) {
703
704 if(sample->gotIPV4) {
705 #ifdef DEVEL
706 char buf[51];
707 #endif
708 uint8_t *end = sample->header + sample->headerLen;
709 uint8_t *start = sample->header + sample->offsetToIPV4;
710 uint8_t *ptr = start;
711 if((end - ptr) < sizeof(struct myiphdr))
712 return;
713
714 /* Create a local copy of the IP header (cannot overlay structure in case it is not quad-aligned...some
715 platforms would core-dump if we tried that). It's OK coz this probably performs just as well anyway. */
716 struct myiphdr ip;
717 memcpy(&ip, ptr, sizeof(ip));
718 /* Value copy all ip elements into sample */
719 sample->ipsrc.type = SFLADDRESSTYPE_IP_V4;
720 sample->ipsrc.address.ip_v4.addr = ip.saddr;
721 sample->ipdst.type = SFLADDRESSTYPE_IP_V4;
722 sample->ipdst.address.ip_v4.addr = ip.daddr;
723 sample->dcd_srcIP.s_addr = ip.saddr;
724 sample->dcd_dstIP.s_addr = ip.daddr;
725 sample->dcd_ipProtocol = ip.protocol;
726 sample->dcd_ipTos = ip.tos;
727 sample->dcd_ipTTL = ip.ttl;
728 dbg_printf("ip.tot_len %d\n", ntohs(ip.tot_len));
729 /* Log out the decoded IP fields */
730 dbg_printf("srcIP %s\n", IP_to_a(sample->dcd_srcIP.s_addr, buf, 51));
731 dbg_printf("dstIP %s\n", IP_to_a(sample->dcd_dstIP.s_addr, buf, 51));
732 dbg_printf("IPProtocol %u\n", sample->dcd_ipProtocol);
733 dbg_printf("IPTOS %u\n", sample->dcd_ipTos);
734 dbg_printf("IPTTL %u\n", sample->dcd_ipTTL);
735 /* check for fragments */
736 sample->ip_fragmentOffset = ntohs(ip.frag_off) & 0x1FFF;
737 if(sample->ip_fragmentOffset > 0) {
738 dbg_printf("IPFragmentOffset %u\n", sample->ip_fragmentOffset);
739 } else {
740 dbg_printf("Unfragmented\n");
741 /* advance the pointer to the next protocol layer */
742 /* ip headerLen is expressed as a number of quads */
743 uint32_t headerBytes = (ip.version_and_headerLen & 0x0f) * 4;
744 if((end - ptr) < headerBytes) return;
745 ptr += headerBytes;
746 decodeIPLayer4(sample, ptr);
747 }
748 }
749 } // End of decodeIPV4
750
751 /*_________________---------------------------__________________
752 _________________ decodeIPV6 __________________
753 -----------------___________________________------------------
754 */
755
decodeIPV6(SFSample * sample)756 static void decodeIPV6(SFSample *sample) {
757 uint16_t payloadLen;
758 uint32_t label;
759 uint32_t nextHeader;
760
761 uint8_t *end = sample->header + sample->headerLen;
762 uint8_t *start = sample->header + sample->offsetToIPV6;
763 uint8_t *ptr = start;
764
765 if((end - ptr) < sizeof(struct myip6hdr))
766 return;
767
768 if(sample->gotIPV6) {
769 int ipVersion = (*ptr >> 4);
770 if(ipVersion != 6) {
771 LogError("SFLOW: decodeIPV6() header decode error: unexpected IP version: %d\n", ipVersion);
772 return;
773 }
774
775 // get the tos (priority)
776 sample->dcd_ipTos = *ptr++ & 15;
777 dbg_printf("IPTOS %u\n", sample->dcd_ipTos);
778
779 // 24-bit label
780 label = *ptr++;
781 label <<= 8;
782 label += *ptr++;
783 label <<= 8;
784 label += *ptr++;
785 dbg_printf("IP6_label 0x%x\n", label);
786
787 // payload
788 payloadLen = (ptr[0] << 8) + ptr[1];
789 ptr += 2;
790
791 // if payload is zero, that implies a jumbo payload
792 if(payloadLen == 0)
793 dbg_printf("IPV6_payloadLen <jumbo>\n");
794 else
795 dbg_printf("IPV6_payloadLen %u\n", payloadLen);
796
797 // next header
798 nextHeader = *ptr++;
799
800 // TTL
801 sample->dcd_ipTTL = *ptr++;
802 dbg_printf("IPTTL %u\n", sample->dcd_ipTTL);
803
804 {// src and dst address
805 #ifdef DEVEL
806 char buf[101];
807 #endif
808 sample->ipsrc.type = SFLADDRESSTYPE_IP_V6;
809 memcpy(&sample->ipsrc.address, ptr, 16);
810 ptr +=16;
811 dbg_printf("srcIP6 %s\n", printAddress(&sample->ipsrc, buf, 100));
812 sample->ipdst.type = SFLADDRESSTYPE_IP_V6;
813 memcpy(&sample->ipdst.address, ptr, 16);
814 ptr +=16;
815 dbg_printf("dstIP6 %s\n", printAddress(&sample->ipdst, buf, 100));
816 }
817
818 // skip over some common header extensions...
819 // http://searchnetworking.techtarget.com/originalContent/0,289142,sid7_gci870277,00.html
820 while(nextHeader == 0 || // hop
821 nextHeader == 43 || // routing
822 nextHeader == 44 || // fragment
823 // nextHeader == 50 || // encryption - don't bother coz we'll not be able to read any further
824 nextHeader == 51 || // auth
825 nextHeader == 60) { // destination options
826 uint32_t optionLen, skip;
827 dbg_printf("IP6HeaderExtension: %d\n", nextHeader);
828 nextHeader = ptr[0];
829 optionLen = 8 * (ptr[1] + 1); // second byte gives option len in 8-byte chunks, not counting first 8
830 skip = optionLen - 2;
831 ptr += skip;
832 if(ptr > end)
833 return; // ran off the end of the header
834 }
835
836 // now that we have eliminated the extension headers, nextHeader should have what we want to
837 // remember as the ip protocol...
838 sample->dcd_ipProtocol = nextHeader;
839 dbg_printf("IPProtocol %u\n", sample->dcd_ipProtocol);
840 decodeIPLayer4(sample, ptr);
841 }
842 } // End of decodeIPV6
843
844
845 /*_________________---------------------------__________________
846 _________________ read data fns __________________
847 -----------------___________________________------------------
848 */
849
getData32_nobswap(SFSample * sample)850 static inline uint32_t getData32_nobswap(SFSample *sample) {
851 uint32_t ans = *(sample->datap)++;
852 /* make sure we didn't run off the end of the datagram. Thanks to
853 Sven Eschenberg for spotting a bug/overrun-vulnerabilty that was here before. */
854 if((uint8_t *)sample->datap > sample->endp) {
855 SFABORT(sample, SF_ABORT_EOS);
856 }
857 return ans;
858 } // End of getData32_nobswap
859
getData32(SFSample * sample)860 static inline uint32_t getData32(SFSample *sample) {
861 return ntohl(getData32_nobswap(sample));
862 } // End of getData32
863
getData64(SFSample * sample)864 static inline uint64_t getData64(SFSample *sample) {
865 uint64_t tmpLo, tmpHi;
866
867 tmpHi = getData32(sample);
868 tmpLo = getData32(sample);
869 return (tmpHi << 32) + tmpLo;
870 } // End of getData64
871
872 #ifdef DEVEL
getFloat(SFSample * sample)873 static inline float getFloat(SFSample *sample) {
874 float fl;
875 uint32_t reg = getData32(sample);
876
877 memcpy(&fl, ®, 4);
878 return fl;
879 } // End of getFloat
880
881
getDouble(SFSample * sample)882 static inline double getDouble(SFSample *sample) {
883 double dbl;
884 uint64_t reg = getData64(sample);
885
886 memcpy(&dbl, ®, 8);
887 return dbl;
888 } // End of getDouble
889 #endif
890
skipBytes(SFSample * sample,uint32_t skip)891 static inline void skipBytes(SFSample *sample, uint32_t skip) {
892 int quads = (skip + 3) / 4;
893
894 sample->datap += quads;
895 if(skip > sample->rawSampleLen || (uint8_t *)sample->datap > sample->endp) {
896 SFABORT(sample, SF_ABORT_EOS);
897 }
898 } // End of skipBytes
899
sf_log_next32(SFSample * sample,char * fieldName)900 static uint32_t sf_log_next32(SFSample *sample, char *fieldName) {
901 uint32_t val = getData32(sample);
902
903 dbg_printf("%s %u\n", fieldName, val);
904 return val;
905 } // End of sf_log_next32
906
sf_log_next64(SFSample * sample,char * fieldName)907 static uint64_t sf_log_next64(SFSample *sample, char *fieldName) {
908 uint64_t val64 = getData64(sample);
909
910 dbg_printf("%s %llu\n", fieldName, (unsigned long long)val64);
911 return val64;
912 } // End of sf_log_next64
913
914 #ifdef DEVEL
sf_log_percentage(SFSample * sample,char * fieldName)915 static void sf_log_percentage(SFSample *sample, char *fieldName) {
916
917 uint32_t hundredths = getData32(sample);
918 if(hundredths == (uint32_t)-1)
919 printf("%s unknown\n", fieldName);
920 else {
921 float percent = (float)hundredths / (float)100.0;
922 printf("%s %.2f\n", fieldName, percent);
923 }
924 } // End of sf_log_percentage
925
926
sf_log_nextFloat(SFSample * sample,char * fieldName)927 static float sf_log_nextFloat(SFSample *sample, char *fieldName) {
928 float val = getFloat(sample);
929
930 dbg_printf("%s %.3f\n", fieldName, val);
931 return val;
932 } // End of sf_log_nextFloat
933
sf_log_nextMAC(SFSample * sample,char * fieldName)934 static void sf_log_nextMAC(SFSample *sample, char *fieldName) {
935 uint8_t *mac = (uint8_t *)sample->datap;
936 printf("%s %02x%02x%02x%02x%02x%02x\n", fieldName, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
937
938 skipBytes(sample, 6);
939 } // End of sf_log_nextMAC
940
941 #endif
942
getString(SFSample * sample,char * buf,uint32_t bufLen)943 static inline uint32_t getString(SFSample *sample, char *buf, uint32_t bufLen) {
944 uint32_t len, read_len;
945
946 len = getData32(sample);
947
948 /* check the bytes are there first */
949 uint32_t *dp = sample->datap;
950 skipBytes(sample, len);
951
952 /* truncate if too long */
953 read_len = (len >= bufLen) ? (bufLen - 1) : len;
954 memcpy(buf, dp, read_len);
955 buf[read_len] = '\0'; /* null terminate */
956 return len;
957 } // End of getString
958
getAddress(SFSample * sample,SFLAddress * address)959 static uint32_t getAddress(SFSample *sample, SFLAddress *address) {
960 address->type = getData32(sample);
961
962 switch(address->type) {
963 case SFLADDRESSTYPE_IP_V4:
964 address->address.ip_v4.addr = getData32_nobswap(sample);
965 break;
966 case SFLADDRESSTYPE_IP_V6: {
967 /* make sure the data is there before we memcpy */
968 uint32_t *dp = sample->datap;
969 skipBytes(sample, 16);
970 memcpy(&address->address.ip_v6.addr, dp, 16);
971 } break;
972 default:
973 /* undefined address type - bail out */
974 LogError("SFLOW: getAddress() unknown address type = %d\n", address->type);
975 SFABORT(sample, SF_ABORT_EOS);
976 }
977 return address->type;
978 } // End of getAddress
979
skipTLVRecord(SFSample * sample,uint32_t tag,uint32_t len,char * description)980 static void skipTLVRecord(SFSample *sample, uint32_t tag, uint32_t len, char *description) {
981 #ifdef DEVEL
982 char buf[51];
983 printf("skipping unknown %s: %s len=%d\n", description, printTag(tag, buf, 50), len);
984 #endif
985
986 skipBytes(sample, len);
987 } // End of skipTLVRecord
988
989 /*_________________---------------------------__________________
990 _________________ readExtendedSwitch __________________
991 -----------------___________________________------------------
992 */
993
readExtendedSwitch(SFSample * sample)994 static void readExtendedSwitch(SFSample *sample) {
995
996 dbg_printf("extendedType SWITCH\n");
997 sample->in_vlan = getData32(sample);
998 sample->in_priority = getData32(sample);
999 sample->out_vlan = getData32(sample);
1000 sample->out_priority = getData32(sample);
1001
1002 sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_SWITCH;
1003
1004 dbg_printf("in_vlan %u\n", sample->in_vlan);
1005 dbg_printf("in_priority %u\n", sample->in_priority);
1006 dbg_printf("out_vlan %u\n", sample->out_vlan);
1007 dbg_printf("out_priority %u\n", sample->out_priority);
1008 } // End of readExtendedSwitch
1009
1010 /*_________________---------------------------__________________
1011 _________________ readExtendedRouter __________________
1012 -----------------___________________________------------------
1013 */
1014
readExtendedRouter(SFSample * sample)1015 static void readExtendedRouter(SFSample *sample) {
1016 #ifdef DEVEL
1017 char buf[51];
1018 #endif
1019
1020 dbg_printf("extendedType ROUTER\n");
1021 getAddress(sample, &sample->nextHop);
1022 sample->srcMask = getData32(sample);
1023 sample->dstMask = getData32(sample);
1024
1025 sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_ROUTER;
1026
1027 dbg_printf("nextHop %s\n", printAddress(&sample->nextHop, buf, 50));
1028 dbg_printf("srcSubnetMask %u\n", sample->srcMask);
1029 dbg_printf("dstSubnetMask %u\n", sample->dstMask);
1030
1031 } // End of readExtendedRouter
1032
1033 /*_________________---------------------------__________________
1034 _________________ readExtendedGateway_v2 __________________
1035 -----------------___________________________------------------
1036 */
1037
readExtendedGateway_v2(SFSample * sample)1038 static void readExtendedGateway_v2(SFSample *sample)
1039 {
1040 dbg_printf("extendedType GATEWAY\n");
1041
1042 sample->my_as = getData32(sample);
1043 sample->src_as = getData32(sample);
1044 sample->src_peer_as = getData32(sample);
1045
1046 /* clear dst_peer_as and dst_as to make sure we are not
1047 remembering values from a previous sample - (thanks Marc Lavine) */
1048 sample->dst_peer_as = 0;
1049 sample->dst_as = 0;
1050
1051 sample->dst_as_path_len = getData32(sample);
1052 /* just point at the dst_as_path array */
1053 if(sample->dst_as_path_len > 0) {
1054 sample->dst_as_path = sample->datap;
1055 /* and skip over it in the input */
1056 skipBytes(sample, sample->dst_as_path_len * 4);
1057 /* fill in the dst and dst_peer fields too */
1058 sample->dst_peer_as = ntohl(sample->dst_as_path[0]);
1059 sample->dst_as = ntohl(sample->dst_as_path[sample->dst_as_path_len - 1]);
1060 }
1061
1062 sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_GATEWAY;
1063
1064 dbg_printf("my_as %u\n", sample->my_as);
1065 dbg_printf("src_as %u\n", sample->src_as);
1066 dbg_printf("src_peer_as %u\n", sample->src_peer_as);
1067 dbg_printf("dst_as %u\n", sample->dst_as);
1068 dbg_printf("dst_peer_as %u\n", sample->dst_peer_as);
1069 dbg_printf("dst_as_path_len %u\n", sample->dst_as_path_len);
1070 if(sample->dst_as_path_len > 0) {
1071 uint32_t i = 0;
1072 for(; i < sample->dst_as_path_len; i++) {
1073 if(i == 0) dbg_printf("dst_as_path ");
1074 else dbg_printf("-");
1075 dbg_printf("%u", ntohl(sample->dst_as_path[i]));
1076 }
1077 dbg_printf("\n");
1078 }
1079 }
1080
1081 /*_________________---------------------------__________________
1082 _________________ readExtendedGateway __________________
1083 -----------------___________________________------------------
1084 */
1085
readExtendedGateway(SFSample * sample)1086 static void readExtendedGateway(SFSample *sample)
1087 {
1088 uint32_t segments;
1089 uint32_t seg;
1090 #ifdef DEVEL
1091 char buf[51];
1092 #endif
1093
1094 dbg_printf("extendedType GATEWAY\n");
1095
1096 if(sample->datagramVersion >= 5) {
1097 getAddress(sample, &sample->bgp_nextHop);
1098 dbg_printf("bgp_nexthop %s\n", printAddress(&sample->bgp_nextHop, buf, 50));
1099 }
1100
1101 sample->my_as = getData32(sample);
1102 sample->src_as = getData32(sample);
1103 sample->src_peer_as = getData32(sample);
1104 dbg_printf("my_as %u\n", sample->my_as);
1105 dbg_printf("src_as %u\n", sample->src_as);
1106 dbg_printf("src_peer_as %u\n", sample->src_peer_as);
1107 segments = getData32(sample);
1108
1109 /* clear dst_peer_as and dst_as to make sure we are not
1110 remembering values from a previous sample - (thanks Marc Lavine) */
1111 sample->dst_peer_as = 0;
1112 sample->dst_as = 0;
1113
1114 if(segments > 0) {
1115 dbg_printf("dst_as_path ");
1116 for(seg = 0; seg < segments; seg++) {
1117 uint32_t seg_type;
1118 uint32_t seg_len;
1119 uint32_t i;
1120 seg_type = getData32(sample);
1121 seg_len = getData32(sample);
1122 for(i = 0; i < seg_len; i++) {
1123 uint32_t asNumber;
1124 asNumber = getData32(sample);
1125 /* mark the first one as the dst_peer_as */
1126 if(i == 0 && seg == 0) sample->dst_peer_as = asNumber;
1127 else dbg_printf("-");
1128 /* make sure the AS sets are in parentheses */
1129 if(i == 0 && seg_type == SFLEXTENDED_AS_SET) dbg_printf("(");
1130 dbg_printf("%u", asNumber);
1131 /* mark the last one as the dst_as */
1132 if(seg == (segments - 1) && i == (seg_len - 1)) sample->dst_as = asNumber;
1133 }
1134 if(seg_type == SFLEXTENDED_AS_SET) dbg_printf(")");
1135 }
1136 dbg_printf("\n");
1137 }
1138 dbg_printf("dst_as %u\n", sample->dst_as);
1139 dbg_printf("dst_peer_as %u\n", sample->dst_peer_as);
1140
1141 sample->communities_len = getData32(sample);
1142 /* just point at the communities array */
1143 if(sample->communities_len > 0) sample->communities = sample->datap;
1144 /* and skip over it in the input */
1145 skipBytes(sample, sample->communities_len * 4);
1146
1147 sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_GATEWAY;
1148 if(sample->communities_len > 0) {
1149 uint32_t j = 0;
1150 for(; j < sample->communities_len; j++) {
1151 if(j == 0) dbg_printf("BGP_communities ");
1152 else dbg_printf("-");
1153 dbg_printf("%u", ntohl(sample->communities[j]));
1154 }
1155 dbg_printf("\n");
1156 }
1157
1158 sample->localpref = getData32(sample);
1159 dbg_printf("BGP_localpref %u\n", sample->localpref);
1160
1161 }
1162
1163 /*_________________---------------------------__________________
1164 _________________ readExtendedUser __________________
1165 -----------------___________________________------------------
1166 */
1167
readExtendedUser(SFSample * sample)1168 static void readExtendedUser(SFSample *sample)
1169 {
1170 dbg_printf("extendedType USER\n");
1171
1172 if(sample->datagramVersion >= 5) {
1173 sample->src_user_charset = getData32(sample);
1174 dbg_printf("src_user_charset %d\n", sample->src_user_charset);
1175 }
1176
1177 sample->src_user_len = getString(sample, sample->src_user, SA_MAX_EXTENDED_USER_LEN);
1178
1179 if(sample->datagramVersion >= 5) {
1180 sample->dst_user_charset = getData32(sample);
1181 dbg_printf("dst_user_charset %d\n", sample->dst_user_charset);
1182 }
1183
1184 sample->dst_user_len = getString(sample, sample->dst_user, SA_MAX_EXTENDED_USER_LEN);
1185
1186 sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_USER;
1187
1188 dbg_printf("src_user %s\n", sample->src_user);
1189 dbg_printf("dst_user %s\n", sample->dst_user);
1190 }
1191
1192 /*_________________---------------------------__________________
1193 _________________ readExtendedUrl __________________
1194 -----------------___________________________------------------
1195 */
1196
readExtendedUrl(SFSample * sample)1197 static void readExtendedUrl(SFSample *sample)
1198 {
1199 dbg_printf("extendedType URL\n");
1200
1201 sample->url_direction = getData32(sample);
1202 dbg_printf("url_direction %u\n", sample->url_direction);
1203 sample->url_len = getString(sample, sample->url, SA_MAX_EXTENDED_URL_LEN);
1204 dbg_printf("url %s\n", sample->url);
1205 if(sample->datagramVersion >= 5) {
1206 sample->host_len = getString(sample, sample->host, SA_MAX_EXTENDED_HOST_LEN);
1207 dbg_printf("host %s\n", sample->host);
1208 }
1209 sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_URL;
1210 }
1211
1212
1213 /*_________________---------------------------__________________
1214 _________________ mplsLabelStack __________________
1215 -----------------___________________________------------------
1216 */
1217
mplsLabelStack(SFSample * sample,char * fieldName)1218 static void mplsLabelStack(SFSample *sample, char *fieldName)
1219 {
1220 SFLLabelStack lstk;
1221 lstk.depth = getData32(sample);
1222 /* just point at the lablelstack array */
1223 if(lstk.depth > 0) lstk.stack = (uint32_t *)sample->datap;
1224 /* and skip over it in the input */
1225 skipBytes(sample, lstk.depth * 4);
1226
1227 #ifdef DEVEL
1228 if(lstk.depth > 0) {
1229 uint32_t lab;
1230 uint32_t j = 0;
1231 for(; j < lstk.depth; j++) {
1232 if(j == 0) printf("%s ", fieldName);
1233 else printf("-");
1234 lab = ntohl(lstk.stack[j]);
1235 printf("%u.%u.%u.%u",
1236 (lab >> 12), /* label */
1237 (lab >> 9) & 7, /* experimental */
1238 (lab >> 8) & 1, /* bottom of stack */
1239 (lab & 255)); /* TTL */
1240 }
1241 printf("\n");
1242 }
1243 #endif
1244 }
1245
1246 /*_________________---------------------------__________________
1247 _________________ readExtendedMpls __________________
1248 -----------------___________________________------------------
1249 */
1250
readExtendedMpls(SFSample * sample)1251 static void readExtendedMpls(SFSample *sample)
1252 {
1253 #ifdef DEVEL
1254 char buf[51];
1255 #endif
1256 dbg_printf("extendedType MPLS\n");
1257 getAddress(sample, &sample->mpls_nextHop);
1258 dbg_printf("mpls_nexthop %s\n", printAddress(&sample->mpls_nextHop, buf, 50));
1259
1260 mplsLabelStack(sample, "mpls_input_stack");
1261 mplsLabelStack(sample, "mpls_output_stack");
1262
1263 sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_MPLS;
1264 }
1265
1266 /*_________________---------------------------__________________
1267 _________________ readExtendedNat __________________
1268 -----------------___________________________------------------
1269 */
1270
readExtendedNat(SFSample * sample)1271 static void readExtendedNat(SFSample *sample)
1272 {
1273 #ifdef DEVEL
1274 char buf[51];
1275 #endif
1276 dbg_printf("extendedType NAT\n");
1277 getAddress(sample, &sample->nat_src);
1278 dbg_printf("nat_src %s\n", printAddress(&sample->nat_src, buf, 50));
1279 getAddress(sample, &sample->nat_dst);
1280 dbg_printf("nat_dst %s\n", printAddress(&sample->nat_dst, buf, 50));
1281 sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_NAT;
1282 }
1283
1284 /*_________________---------------------------__________________
1285 _________________ readExtendedNatPort __________________
1286 -----------------___________________________------------------
1287 */
1288
readExtendedNatPort(SFSample * sample)1289 static void readExtendedNatPort(SFSample *sample)
1290 {
1291 dbg_printf("extendedType NAT PORT\n");
1292 sf_log_next32(sample, "nat_src_port");
1293 sf_log_next32(sample, "nat_dst_port");
1294 }
1295
1296
1297 /*_________________---------------------------__________________
1298 _________________ readExtendedMplsTunnel __________________
1299 -----------------___________________________------------------
1300 */
1301
readExtendedMplsTunnel(SFSample * sample)1302 static void readExtendedMplsTunnel(SFSample *sample)
1303 {
1304 #ifdef DEVEL
1305 #define SA_MAX_TUNNELNAME_LEN 100
1306 char tunnel_name[SA_MAX_TUNNELNAME_LEN+1];
1307
1308 uint32_t tunnel_id, tunnel_cos;
1309
1310 if(getString(sample, tunnel_name, SA_MAX_TUNNELNAME_LEN) > 0)
1311 dbg_printf("mpls_tunnel_lsp_name %s\n", tunnel_name);
1312 tunnel_id = getData32(sample);
1313 dbg_printf("mpls_tunnel_id %u\n", tunnel_id);
1314 tunnel_cos = getData32(sample);
1315 dbg_printf("mpls_tunnel_cos %u\n", tunnel_cos);
1316 #endif
1317
1318 sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_MPLS_TUNNEL;
1319 }
1320
1321 /*_________________---------------------------__________________
1322 _________________ readExtendedMplsVC __________________
1323 -----------------___________________________------------------
1324 */
1325
readExtendedMplsVC(SFSample * sample)1326 static void readExtendedMplsVC(SFSample *sample)
1327 {
1328 #ifdef DEVEL
1329 #define SA_MAX_VCNAME_LEN 100
1330 char vc_name[SA_MAX_VCNAME_LEN+1];
1331 uint32_t vll_vc_id, vc_cos;
1332 if(getString(sample, vc_name, SA_MAX_VCNAME_LEN) > 0)
1333 dbg_printf("mpls_vc_name %s\n", vc_name);
1334 vll_vc_id = getData32(sample);
1335 dbg_printf("mpls_vll_vc_id %u\n", vll_vc_id);
1336 vc_cos = getData32(sample);
1337 dbg_printf("mpls_vc_cos %u\n", vc_cos);
1338 #endif
1339 sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_MPLS_VC;
1340 }
1341
1342 /*_________________---------------------------__________________
1343 _________________ readExtendedMplsFTN __________________
1344 -----------------___________________________------------------
1345 */
1346
readExtendedMplsFTN(SFSample * sample)1347 static void readExtendedMplsFTN(SFSample *sample)
1348 {
1349 #ifdef DEVEL
1350 #define SA_MAX_FTN_LEN 100
1351 char ftn_descr[SA_MAX_FTN_LEN+1];
1352 uint32_t ftn_mask;
1353 if(getString(sample, ftn_descr, SA_MAX_FTN_LEN) > 0)
1354 dbg_printf("mpls_ftn_descr %s\n", ftn_descr);
1355 ftn_mask = getData32(sample);
1356 dbg_printf("mpls_ftn_mask %u\n", ftn_mask);
1357 #endif
1358
1359 sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_MPLS_FTN;
1360 }
1361
1362 /*_________________---------------------------__________________
1363 _________________ readExtendedMplsLDP_FEC __________________
1364 -----------------___________________________------------------
1365 */
1366
readExtendedMplsLDP_FEC(SFSample * sample)1367 static void readExtendedMplsLDP_FEC(SFSample *sample)
1368 {
1369 #ifdef DEVEL
1370 uint32_t fec_addr_prefix_len = getData32(sample);
1371 dbg_printf("mpls_fec_addr_prefix_len %u\n", fec_addr_prefix_len);
1372 #endif
1373 sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_MPLS_LDP_FEC;
1374 }
1375
1376 /*_________________---------------------------__________________
1377 _________________ readExtendedVlanTunnel __________________
1378 -----------------___________________________------------------
1379 */
1380
readExtendedVlanTunnel(SFSample * sample)1381 static void readExtendedVlanTunnel(SFSample *sample)
1382 {
1383 SFLLabelStack lstk;
1384 lstk.depth = getData32(sample);
1385 /* just point at the lablelstack array */
1386 if(lstk.depth > 0) lstk.stack = (uint32_t *)sample->datap;
1387 /* and skip over it in the input */
1388 skipBytes(sample, lstk.depth * 4);
1389
1390 #ifdef DEVEL
1391 if(lstk.depth > 0) {
1392 uint32_t lab;
1393 uint32_t j = 0;
1394 for(; j < lstk.depth; j++) {
1395 if(j == 0) printf("vlan_tunnel ");
1396 else printf("-");
1397 lab = ntohl(lstk.stack[j]);
1398 dbg_printf("0x%04x.%u.%u.%u",
1399 (lab >> 16), /* TPI */
1400 (lab >> 13) & 7, /* priority */
1401 (lab >> 12) & 1, /* CFI */
1402 (lab & 4095)); /* VLAN */
1403 }
1404 dbg_printf("\n");
1405 }
1406 #endif
1407
1408 sample->extended_data_tag |= SASAMPLE_EXTENDED_DATA_VLAN_TUNNEL;
1409 }
1410
1411 /*_________________---------------------------__________________
1412 _________________ readExtendedWifiPayload __________________
1413 -----------------___________________________------------------
1414 */
1415
readExtendedWifiPayload(SFSample * sample)1416 static void readExtendedWifiPayload(SFSample *sample)
1417 {
1418 sf_log_next32(sample, "cipher_suite");
1419 readFlowSample_header(sample);
1420 }
1421
1422 /*_________________---------------------------__________________
1423 _________________ readExtendedWifiRx __________________
1424 -----------------___________________________------------------
1425 */
1426
readExtendedWifiRx(SFSample * sample)1427 static void readExtendedWifiRx(SFSample *sample)
1428 {
1429
1430 #ifdef DEVEL
1431 uint32_t i;
1432 uint8_t *bssid;
1433 char ssid[SFL_MAX_SSID_LEN+1];
1434 if(getString(sample, ssid, SFL_MAX_SSID_LEN) > 0) {
1435 printf("rx_SSID %s\n", ssid);
1436 }
1437
1438 bssid = (uint8_t *)sample->datap;
1439 printf("rx_BSSID ");
1440 for(i = 0; i < 6; i++) dbg_printf("%02x", bssid[i]);
1441 printf("\n");
1442 #endif
1443
1444 skipBytes(sample, 6);
1445
1446 sf_log_next32(sample, "rx_version");
1447 sf_log_next32(sample, "rx_channel");
1448 sf_log_next64(sample, "rx_speed");
1449 sf_log_next32(sample, "rx_rsni");
1450 sf_log_next32(sample, "rx_rcpi");
1451 sf_log_next32(sample, "rx_packet_uS");
1452 }
1453
1454 /*_________________---------------------------__________________
1455 _________________ readExtendedWifiTx __________________
1456 -----------------___________________________------------------
1457 */
1458
readExtendedWifiTx(SFSample * sample)1459 static void readExtendedWifiTx(SFSample *sample)
1460 {
1461 #ifdef DEVEL
1462 uint32_t i;
1463 uint8_t *bssid;
1464 char ssid[SFL_MAX_SSID_LEN+1];
1465 if(getString(sample, ssid, SFL_MAX_SSID_LEN) > 0) {
1466 printf("tx_SSID %s\n", ssid);
1467 }
1468
1469 bssid = (uint8_t *)sample->datap;
1470 printf("tx_BSSID ");
1471 for(i = 0; i < 6; i++) dbg_printf("%02x", bssid[i]);
1472 printf("\n");
1473 #endif
1474 skipBytes(sample, 6);
1475
1476 sf_log_next32(sample, "tx_version");
1477 sf_log_next32(sample, "tx_transmissions");
1478 sf_log_next32(sample, "tx_packet_uS");
1479 sf_log_next32(sample, "tx_retrans_uS");
1480 sf_log_next32(sample, "tx_channel");
1481 sf_log_next64(sample, "tx_speed");
1482 sf_log_next32(sample, "tx_power_mW");
1483 }
1484
1485 /*_________________---------------------------__________________
1486 _________________ readFlowSample_header __________________
1487 -----------------___________________________------------------
1488 */
1489
readFlowSample_header(SFSample * sample)1490 static void readFlowSample_header(SFSample *sample)
1491 {
1492 dbg_printf("flowSampleType HEADER\n");
1493 sample->headerProtocol = getData32(sample);
1494 dbg_printf("headerProtocol %u\n", sample->headerProtocol);
1495 sample->sampledPacketSize = getData32(sample);
1496 dbg_printf("sampledPacketSize %u\n", sample->sampledPacketSize);
1497 if(sample->datagramVersion > 4) {
1498 /* stripped count introduced in sFlow version 5 */
1499 sample->stripped = getData32(sample);
1500 dbg_printf("strippedBytes %u\n", sample->stripped);
1501 }
1502 sample->headerLen = getData32(sample);
1503 dbg_printf("headerLen %u\n", sample->headerLen);
1504
1505 sample->header = (uint8_t *)sample->datap; /* just point at the header */
1506 skipBytes(sample, sample->headerLen);
1507 {
1508 char scratch[2000];
1509 printHex(sample->header, sample->headerLen, scratch, 2000, 0, 2000);
1510 dbg_printf("headerBytes %s\n", scratch);
1511 }
1512
1513 switch(sample->headerProtocol) {
1514 /* the header protocol tells us where to jump into the decode */
1515 case SFLHEADER_ETHERNET_ISO8023:
1516 decodeLinkLayer(sample);
1517 break;
1518 case SFLHEADER_IPv4:
1519 sample->gotIPV4 = YES;
1520 sample->offsetToIPV4 = 0;
1521 break;
1522 case SFLHEADER_IPv6:
1523 sample->gotIPV6 = YES;
1524 sample->offsetToIPV6 = 0;
1525 break;
1526 case SFLHEADER_IEEE80211MAC:
1527 decode80211MAC(sample);
1528 break;
1529 case SFLHEADER_ISO88024_TOKENBUS:
1530 case SFLHEADER_ISO88025_TOKENRING:
1531 case SFLHEADER_FDDI:
1532 case SFLHEADER_FRAME_RELAY:
1533 case SFLHEADER_X25:
1534 case SFLHEADER_PPP:
1535 case SFLHEADER_SMDS:
1536 case SFLHEADER_AAL5:
1537 case SFLHEADER_AAL5_IP:
1538 case SFLHEADER_MPLS:
1539 case SFLHEADER_POS:
1540 case SFLHEADER_IEEE80211_AMPDU:
1541 case SFLHEADER_IEEE80211_AMSDU_SUBFRAME:
1542 dbg_printf("NO_DECODE headerProtocol=%d\n", sample->headerProtocol);
1543 break;
1544 default:
1545 LogError("SFLOW: readFlowSample_header() undefined headerProtocol = %d\n", sample->headerProtocol);
1546 SFABORT(sample, -12);
1547 }
1548
1549 if(sample->gotIPV4) {
1550 /* report the size of the original IPPdu (including the IP header) */
1551 dbg_printf("IPSize %d\n", sample->sampledPacketSize - sample->stripped - sample->offsetToIPV4);
1552 decodeIPV4(sample);
1553 }
1554 else if(sample->gotIPV6) {
1555 /* report the size of the original IPPdu (including the IP header) */
1556 dbg_printf("IPSize %d\n", sample->sampledPacketSize - sample->stripped - sample->offsetToIPV6);
1557 decodeIPV6(sample);
1558 }
1559
1560 }
1561
1562 /*_________________---------------------------__________________
1563 _________________ readFlowSample_ethernet __________________
1564 -----------------___________________________------------------
1565 */
1566
readFlowSample_ethernet(SFSample * sample,char * prefix)1567 static void readFlowSample_ethernet(SFSample *sample, char *prefix)
1568 {
1569 #ifdef DEVEL
1570 uint8_t *p;
1571 printf("flowSampleType %sETHERNET\n", prefix);
1572 #endif
1573
1574 sample->eth_len = getData32(sample);
1575 memcpy(sample->eth_src, sample->datap, 6);
1576 skipBytes(sample, 6);
1577 memcpy(sample->eth_dst, sample->datap, 6);
1578 skipBytes(sample, 6);
1579 sample->eth_type = getData32(sample);
1580
1581 #ifdef DEVEL
1582 printf("%s ethernet_type %u\n", prefix, sample->eth_type);
1583 printf("%s ethernet_len %u\n", prefix, sample->eth_len);
1584 p = sample->eth_src;
1585 printf("%s ethernet_src %02x%02x%02x%02x%02x%02x\n", prefix, p[0], p[1], p[2], p[3], p[4], p[5]);
1586 p = sample->eth_dst;
1587 printf("%s ethernet_dst %02x%02x%02x%02x%02x%02x\n", prefix, p[0], p[1], p[2], p[3], p[4], p[5]);
1588 #endif
1589 }
1590
1591
1592 /*_________________---------------------------__________________
1593 _________________ readFlowSample_IPv4 __________________
1594 -----------------___________________________------------------
1595 */
1596
readFlowSample_IPv4(SFSample * sample,char * prefix)1597 static void readFlowSample_IPv4(SFSample *sample, char *prefix)
1598 {
1599 dbg_printf("flowSampleType %sIPV4\n", prefix);
1600 sample->headerLen = sizeof(SFLSampled_ipv4);
1601 sample->header = (uint8_t *)sample->datap; /* just point at the header */
1602 skipBytes(sample, sample->headerLen);
1603 {
1604 #ifdef DEVEL
1605 char buf[51];
1606 #endif
1607 SFLSampled_ipv4 nfKey;
1608 memcpy(&nfKey, sample->header, sizeof(nfKey));
1609 sample->sampledPacketSize = ntohl(nfKey.length);
1610 dbg_printf("%s sampledPacketSize %u\n", prefix, sample->sampledPacketSize);
1611 dbg_printf("%s IPSize %u\n", prefix, sample->sampledPacketSize);
1612 sample->ipsrc.type = SFLADDRESSTYPE_IP_V4;
1613 sample->ipsrc.address.ip_v4 = nfKey.src_ip;
1614 sample->ipdst.type = SFLADDRESSTYPE_IP_V4;
1615 sample->ipdst.address.ip_v4 = nfKey.dst_ip;
1616 sample->dcd_ipProtocol = ntohl(nfKey.protocol);
1617 sample->dcd_ipTos = ntohl(nfKey.tos);
1618 dbg_printf("%s srcIP %s\n", prefix, printAddress(&sample->ipsrc, buf, 50));
1619 dbg_printf("%s dstIP %s\n", prefix, printAddress(&sample->ipdst, buf, 50));
1620 dbg_printf("%s IPProtocol %u\n", prefix, sample->dcd_ipProtocol);
1621 dbg_printf("%s IPTOS %u\n", prefix, sample->dcd_ipTos);
1622 sample->dcd_sport = ntohl(nfKey.src_port);
1623 sample->dcd_dport = ntohl(nfKey.dst_port);
1624 switch(sample->dcd_ipProtocol) {
1625 case 1: /* ICMP */
1626 dbg_printf("%sICMPType %u\n", prefix, sample->dcd_dport);
1627 /* not sure about the dest port being icmp type
1628 - might be that src port is icmp type and dest
1629 port is icmp code. Still, have seen some
1630 implementations where src port is 0 and dst
1631 port is the type, so it may be safer to
1632 assume that the destination port has the type */
1633 break;
1634 case 6: /* TCP */
1635 dbg_printf("%s TCPSrcPort %u\n", prefix, sample->dcd_sport);
1636 dbg_printf("%s TCPDstPort %u\n", prefix, sample->dcd_dport);
1637 sample->dcd_tcpFlags = ntohl(nfKey.tcp_flags);
1638 dbg_printf("%s TCPFlags %u\n", prefix, sample->dcd_tcpFlags);
1639 break;
1640 case 17: /* UDP */
1641 dbg_printf("%s UDPSrcPort %u\n", prefix, sample->dcd_sport);
1642 dbg_printf("%s UDPDstPort %u\n", prefix, sample->dcd_dport);
1643 break;
1644 default: /* some other protcol */
1645 break;
1646 }
1647 }
1648 }
1649
1650 /*_________________---------------------------__________________
1651 _________________ readFlowSample_IPv6 __________________
1652 -----------------___________________________------------------
1653 */
1654
readFlowSample_IPv6(SFSample * sample,char * prefix)1655 static void readFlowSample_IPv6(SFSample *sample, char *prefix)
1656 {
1657 dbg_printf("flowSampleType %sIPV6\n", prefix);
1658 sample->header = (uint8_t *)sample->datap; /* just point at the header */
1659 sample->headerLen = sizeof(SFLSampled_ipv6);
1660 skipBytes(sample, sample->headerLen);
1661 {
1662 #ifdef DEVEL
1663 char buf[51];
1664 #endif
1665 SFLSampled_ipv6 nfKey6;
1666 memcpy(&nfKey6, sample->header, sizeof(nfKey6));
1667 sample->sampledPacketSize = ntohl(nfKey6.length);
1668 dbg_printf("%s sampledPacketSize %u\n", prefix, sample->sampledPacketSize);
1669 dbg_printf("%s IPSize %u\n", prefix, sample->sampledPacketSize);
1670 sample->ipsrc.type = SFLADDRESSTYPE_IP_V6;
1671 memcpy(&sample->ipsrc.address.ip_v6, &nfKey6.src_ip, 16);
1672 sample->ipdst.type = SFLADDRESSTYPE_IP_V6;
1673 memcpy(&sample->ipdst.address.ip_v6, &nfKey6.dst_ip, 16);
1674 sample->dcd_ipProtocol = ntohl(nfKey6.protocol);
1675 dbg_printf("%s srcIP6 %s\n", prefix, printAddress(&sample->ipsrc, buf, 50));
1676 dbg_printf("%s dstIP6 %s\n", prefix, printAddress(&sample->ipdst, buf, 50));
1677 dbg_printf("%s IPProtocol %u\n", prefix, sample->dcd_ipProtocol);
1678 dbg_printf("%s priority %u\n", prefix, ntohl(nfKey6.priority));
1679 sample->dcd_sport = ntohl(nfKey6.src_port);
1680 sample->dcd_dport = ntohl(nfKey6.dst_port);
1681 switch(sample->dcd_ipProtocol) {
1682 case 1: /* ICMP */
1683 dbg_printf("%s ICMPType %u\n", prefix, sample->dcd_dport);
1684 /* not sure about the dest port being icmp type
1685 - might be that src port is icmp type and dest
1686 port is icmp code. Still, have seen some
1687 implementations where src port is 0 and dst
1688 port is the type, so it may be safer to
1689 assume that the destination port has the type */
1690 break;
1691 case 6: /* TCP */
1692 dbg_printf("%s TCPSrcPort %u\n", prefix, sample->dcd_sport);
1693 dbg_printf("%s TCPDstPort %u\n", prefix, sample->dcd_dport);
1694 sample->dcd_tcpFlags = ntohl(nfKey6.tcp_flags);
1695 dbg_printf("%s TCPFlags %u\n", prefix, sample->dcd_tcpFlags);
1696 break;
1697 case 17: /* UDP */
1698 dbg_printf("%s UDPSrcPort %u\n", prefix, sample->dcd_sport);
1699 dbg_printf("%s UDPDstPort %u\n", prefix, sample->dcd_dport);
1700 break;
1701 default: /* some other protcol */
1702 break;
1703 }
1704 }
1705 }
1706
1707 /*_________________----------------------------__________________
1708 _________________ readFlowSample_memcache __________________
1709 -----------------____________________________------------------
1710 */
1711
readFlowSample_memcache(SFSample * sample)1712 static void readFlowSample_memcache(SFSample *sample)
1713 {
1714 char key[SFL_MAX_MEMCACHE_KEY+1];
1715 #define ENC_KEY_BYTES (SFL_MAX_MEMCACHE_KEY * 3) + 1
1716 dbg_printf("flowSampleType memcache\n");
1717 sf_log_next32(sample, "memcache_op_protocol");
1718 sf_log_next32(sample, "memcache_op_cmd");
1719 if(getString(sample, key, SFL_MAX_MEMCACHE_KEY) > 0) {
1720 #ifdef DEVEL
1721 char enc_key[ENC_KEY_BYTES];
1722 dbg_printf("memcache_op_key %s\n", URLEncode(key, enc_key, ENC_KEY_BYTES));
1723 #endif
1724 }
1725 sf_log_next32(sample, "memcache_op_nkeys");
1726 sf_log_next32(sample, "memcache_op_value_bytes");
1727 sf_log_next32(sample, "memcache_op_duration_uS");
1728 sf_log_next32(sample, "memcache_op_status");
1729 }
1730
1731 /*_________________----------------------------__________________
1732 _________________ readFlowSample_http __________________
1733 -----------------____________________________------------------
1734 */
1735
1736 /* absorb compiler warning about strftime printing */
1737 #pragma GCC diagnostic push
1738 #pragma GCC diagnostic ignored "-Wformat"
1739
readFlowSample_http(SFSample * sample,uint32_t tag)1740 static void readFlowSample_http(SFSample *sample, uint32_t tag)
1741 {
1742 char uri[SFL_MAX_HTTP_URI+1];
1743 char host[SFL_MAX_HTTP_HOST+1];
1744 char referrer[SFL_MAX_HTTP_REFERRER+1];
1745 char useragent[SFL_MAX_HTTP_USERAGENT+1];
1746 char xff[SFL_MAX_HTTP_XFF+1];
1747 char authuser[SFL_MAX_HTTP_AUTHUSER+1];
1748 char mimetype[SFL_MAX_HTTP_MIMETYPE+1];
1749 uint32_t method;
1750 uint32_t protocol;
1751 uint32_t status;
1752 uint64_t resp_bytes;
1753
1754 // keep compiler happy
1755 UNUSED(method);
1756 UNUSED(protocol);
1757 UNUSED(status);
1758 UNUSED(resp_bytes);
1759
1760 dbg_printf("flowSampleType http\n");
1761 method = sf_log_next32(sample, "http_method");
1762 protocol = sf_log_next32(sample, "http_protocol");
1763 if(getString(sample, uri, SFL_MAX_HTTP_URI) > 0) {
1764 dbg_printf("http_uri %s\n", uri);
1765 }
1766 if(getString(sample, host, SFL_MAX_HTTP_HOST) > 0) {
1767 dbg_printf("http_host %s\n", host);
1768 }
1769 if(getString(sample, referrer, SFL_MAX_HTTP_REFERRER) > 0) {
1770 dbg_printf("http_referrer %s\n", referrer);
1771 }
1772 if(getString(sample, useragent, SFL_MAX_HTTP_USERAGENT) > 0) {
1773 dbg_printf("http_useragent %s\n", useragent);
1774 }
1775 if(tag == SFLFLOW_HTTP2) {
1776 if(getString(sample, xff, SFL_MAX_HTTP_XFF) > 0) {
1777 dbg_printf("http_xff %s\n", xff);
1778 }
1779 }
1780 if(getString(sample, authuser, SFL_MAX_HTTP_AUTHUSER) > 0) {
1781 dbg_printf("http_authuser %s\n", authuser);
1782 }
1783 if(getString(sample, mimetype, SFL_MAX_HTTP_MIMETYPE) > 0) {
1784 dbg_printf("http_mimetype %s\n", mimetype);
1785 }
1786 if(tag == SFLFLOW_HTTP2) {
1787 sf_log_next64(sample, "http_request_bytes");
1788 }
1789 resp_bytes = sf_log_next64(sample, "http_bytes");
1790 sf_log_next32(sample, "http_duration_uS");
1791 status = sf_log_next32(sample, "http_status");
1792
1793 #ifdef DEVEL
1794 {
1795 static const char *SFHTTP_method_names[] = { "-", "OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "CONNECT" };
1796
1797 time_t now = time(NULL);
1798 char nowstr[200];
1799 strftime(nowstr, 200, "%d/%b/%Y:%H:%M:%S %z", localtime(&now)); /* there seems to be no simple portable equivalent to %z */
1800 /* should really be: snprintf(sfCLF.http_log, SFLFMT_CLF_MAX_LINE,...) but snprintf() is not always available */
1801 printf("- %s [%s] \"%s %s HTTP/%u.%u\" %u %llu \"%s\" \"%s\"",
1802 authuser[0] ? authuser : "-",
1803 nowstr,
1804 SFHTTP_method_names[method],
1805 uri[0] ? uri : "-",
1806 protocol / 1000,
1807 protocol % 1000,
1808 status,
1809 resp_bytes,
1810 referrer[0] ? referrer : "-",
1811 useragent[0] ? useragent : "-");
1812 }
1813 #endif
1814 }
1815
1816 #pragma GCC diagnostic pop
1817
1818 /*_________________----------------------------__________________
1819 _________________ readFlowSample_APP __________________
1820 -----------------____________________________------------------
1821 */
1822
readFlowSample_APP(SFSample * sample)1823 static void readFlowSample_APP(SFSample *sample)
1824 {
1825 char application[SFLAPP_MAX_APPLICATION_LEN];
1826 char operation[SFLAPP_MAX_OPERATION_LEN];
1827 char attributes[SFLAPP_MAX_ATTRIBUTES_LEN];
1828 char status[SFLAPP_MAX_STATUS_LEN];
1829 uint32_t status32;
1830
1831 dbg_printf("flowSampleType applicationOperation\n");
1832
1833 if(getString(sample, application, SFLAPP_MAX_APPLICATION_LEN) > 0) {
1834 dbg_printf("application %s\n", application);
1835 }
1836 if(getString(sample, operation, SFLAPP_MAX_OPERATION_LEN) > 0) {
1837 dbg_printf("operation %s\n", operation);
1838 }
1839 if(getString(sample, attributes, SFLAPP_MAX_ATTRIBUTES_LEN) > 0) {
1840 dbg_printf("attributes %s\n", attributes);
1841 }
1842 if(getString(sample, status, SFLAPP_MAX_STATUS_LEN) > 0) {
1843 dbg_printf("status_descr %s\n", status);
1844 }
1845 sf_log_next64(sample, "request_bytes");
1846 sf_log_next64(sample, "response_bytes");
1847 sf_log_next32(sample, "duration_uS");
1848 status32 = getData32(sample);
1849 if(status32 >= SFLAPP_NUM_STATUS_CODES)
1850 dbg_printf("status <out-of-range=%u>\n", status32);
1851 else
1852 dbg_printf("status %s\n", SFL_APP_STATUS_names[status32]);
1853 }
1854
1855
1856 /*_________________----------------------------__________________
1857 _________________ readFlowSample_APP_CTXT __________________
1858 -----------------____________________________------------------
1859 */
1860
readFlowSample_APP_CTXT(SFSample * sample)1861 static void readFlowSample_APP_CTXT(SFSample *sample)
1862 {
1863 char application[SFLAPP_MAX_APPLICATION_LEN];
1864 char operation[SFLAPP_MAX_OPERATION_LEN];
1865 char attributes[SFLAPP_MAX_ATTRIBUTES_LEN];
1866 if(getString(sample, application, SFLAPP_MAX_APPLICATION_LEN) > 0) {
1867 dbg_printf("server_context_application %s\n", application);
1868 }
1869 if(getString(sample, operation, SFLAPP_MAX_OPERATION_LEN) > 0) {
1870 dbg_printf("server_context_operation %s\n", operation);
1871 }
1872 if(getString(sample, attributes, SFLAPP_MAX_ATTRIBUTES_LEN) > 0) {
1873 dbg_printf("server_context_attributes %s\n", attributes);
1874 }
1875 }
1876
1877 /*_________________---------------------------------__________________
1878 _________________ readFlowSample_APP_ACTOR_INIT __________________
1879 -----------------_________________________________------------------
1880 */
1881
readFlowSample_APP_ACTOR_INIT(SFSample * sample)1882 static void readFlowSample_APP_ACTOR_INIT(SFSample *sample)
1883 {
1884 char actor[SFLAPP_MAX_ACTOR_LEN];
1885 if(getString(sample, actor, SFLAPP_MAX_ACTOR_LEN) > 0) {
1886 dbg_printf("actor_initiator %s\n", actor);
1887 }
1888 }
1889
1890 /*_________________---------------------------------__________________
1891 _________________ readFlowSample_APP_ACTOR_TGT __________________
1892 -----------------_________________________________------------------
1893 */
1894
readFlowSample_APP_ACTOR_TGT(SFSample * sample)1895 static void readFlowSample_APP_ACTOR_TGT(SFSample *sample)
1896 {
1897 char actor[SFLAPP_MAX_ACTOR_LEN];
1898 if(getString(sample, actor, SFLAPP_MAX_ACTOR_LEN) > 0) {
1899 dbg_printf("actor_target %s\n", actor);
1900 }
1901 }
1902
1903 /*_________________----------------------------__________________
1904 _________________ readExtendedSocket4 __________________
1905 -----------------____________________________------------------
1906 */
1907
readExtendedSocket4(SFSample * sample)1908 static void readExtendedSocket4(SFSample *sample)
1909 {
1910 #ifdef DEVEL
1911 char buf[51];
1912 #endif
1913 dbg_printf("extendedType socket4\n");
1914 sf_log_next32(sample, "socket4_ip_protocol");
1915 sample->ipsrc.type = SFLADDRESSTYPE_IP_V4;
1916 sample->ipsrc.address.ip_v4.addr = getData32_nobswap(sample);
1917 sample->ipdst.type = SFLADDRESSTYPE_IP_V4;
1918 sample->ipdst.address.ip_v4.addr = getData32_nobswap(sample);
1919 dbg_printf("socket4_local_ip %s\n", printAddress(&sample->ipsrc, buf, 50));
1920 dbg_printf("socket4_remote_ip %s\n", printAddress(&sample->ipdst, buf, 50));
1921 sf_log_next32(sample, "socket4_local_port");
1922 sf_log_next32(sample, "socket4_remote_port");
1923
1924 }
1925
1926 /*_________________----------------------------__________________
1927 _________________ readExtendedProxySocket4 __________________
1928 -----------------____________________________------------------
1929 */
1930
readExtendedProxySocket4(SFSample * sample)1931 static void readExtendedProxySocket4(SFSample *sample)
1932 {
1933 #ifdef DEVEL
1934 char buf[51];
1935 #endif
1936 SFLAddress ipsrc,ipdst;
1937 // keep compiler happy
1938 UNUSED(ipsrc);
1939 UNUSED(ipdst);
1940 dbg_printf("extendedType proxy_socket4\n");
1941 sf_log_next32(sample, "proxy_socket4_ip_protocol");
1942 ipsrc.type = SFLADDRESSTYPE_IP_V4;
1943 ipsrc.address.ip_v4.addr = getData32_nobswap(sample);
1944 ipdst.type = SFLADDRESSTYPE_IP_V4;
1945 ipdst.address.ip_v4.addr = getData32_nobswap(sample);
1946 dbg_printf("proxy_socket4_local_ip %s\n", printAddress(&ipsrc, buf, 50));
1947 dbg_printf("proxy_socket4_remote_ip %s\n", printAddress(&ipdst, buf, 50));
1948 sf_log_next32(sample, "proxy_socket4_local_port");
1949 sf_log_next32(sample, "proxy_socket4_remote_port");
1950 }
1951
1952 /*_________________----------------------------__________________
1953 _________________ readExtendedSocket6 __________________
1954 -----------------____________________________------------------
1955 */
1956
readExtendedSocket6(SFSample * sample)1957 static void readExtendedSocket6(SFSample *sample)
1958 {
1959 #ifdef DEVEL
1960 char buf[51];
1961 #endif
1962 dbg_printf("extendedType socket6\n");
1963 sf_log_next32(sample, "socket6_ip_protocol");
1964 sample->ipsrc.type = SFLADDRESSTYPE_IP_V6;
1965 memcpy(&sample->ipsrc.address.ip_v6, sample->datap, 16);
1966 skipBytes(sample, 16);
1967 sample->ipdst.type = SFLADDRESSTYPE_IP_V6;
1968 memcpy(&sample->ipdst.address.ip_v6, sample->datap, 16);
1969 skipBytes(sample, 16);
1970 dbg_printf("socket6_local_ip %s\n", printAddress(&sample->ipsrc, buf, 50));
1971 dbg_printf("socket6_remote_ip %s\n", printAddress(&sample->ipdst, buf, 50));
1972 sf_log_next32(sample, "socket6_local_port");
1973 sf_log_next32(sample, "socket6_remote_port");
1974
1975 }
1976
1977 /*_________________----------------------------__________________
1978 _________________ readExtendedProxySocket6 __________________
1979 -----------------____________________________------------------
1980 */
1981
readExtendedProxySocket6(SFSample * sample)1982 static void readExtendedProxySocket6(SFSample *sample)
1983 {
1984 #ifdef DEVEL
1985 char buf[51];
1986 #endif
1987 SFLAddress ipsrc, ipdst;
1988 dbg_printf("extendedType proxy_socket6\n");
1989 sf_log_next32(sample, "proxy_socket6_ip_protocol");
1990 ipsrc.type = SFLADDRESSTYPE_IP_V6;
1991 memcpy(&ipsrc.address.ip_v6, sample->datap, 16);
1992 skipBytes(sample, 16);
1993 ipdst.type = SFLADDRESSTYPE_IP_V6;
1994 memcpy(&ipdst.address.ip_v6, sample->datap, 16);
1995 skipBytes(sample, 16);
1996 dbg_printf("proxy_socket6_local_ip %s\n", printAddress(&ipsrc, buf, 50));
1997 dbg_printf("proxy_socket6_remote_ip %s\n", printAddress(&ipdst, buf, 50));
1998 sf_log_next32(sample, "proxy_socket6_local_port");
1999 sf_log_next32(sample, "proxy_socket6_remote_port");
2000 }
2001
2002 /*_________________----------------------------__________________
2003 _________________ readExtendedDecap __________________
2004 -----------------____________________________------------------
2005 */
2006
readExtendedDecap(SFSample * sample,char * prefix)2007 static void readExtendedDecap(SFSample *sample, char *prefix)
2008 {
2009 #ifdef DEVEL
2010 uint32_t offset = getData32(sample);
2011 dbg_printf("extendedType %sdecap\n", prefix);
2012 dbg_printf("%sdecap_inner_header_offset %u\n", prefix, offset);
2013 #endif
2014 }
2015
2016 /*_________________----------------------------__________________
2017 _________________ readExtendedVNI __________________
2018 -----------------____________________________------------------
2019 */
2020
readExtendedVNI(SFSample * sample,char * prefix)2021 static void readExtendedVNI(SFSample *sample, char *prefix)
2022 {
2023 #ifdef DEVEL
2024 uint32_t vni = getData32(sample);
2025 dbg_printf("extendedType %sVNI\n", prefix);
2026 dbg_printf("%sVNI %u\n", prefix, vni);
2027 #endif
2028 }
2029
2030 /*_________________----------------------------__________________
2031 _________________ readExtendedTCPInfo __________________
2032 -----------------____________________________------------------
2033 */
2034
readExtendedTCPInfo(SFSample * sample)2035 static void readExtendedTCPInfo(SFSample *sample)
2036 {
2037 EnumPktDirection dirn = getData32(sample);
2038 UNUSED(dirn); // keep compiler happy
2039 #ifdef DEVEL
2040 char *direction;
2041 switch(dirn) {
2042 case PKTDIR_unknown: direction = "unknown"; break;
2043 case PKTDIR_received: direction = "received"; break;
2044 case PKTDIR_sent: direction = "sent"; break;
2045 default: direction = "<bad value>"; break;
2046 }
2047 printf( "tcpinfo_direction %s\n", direction);
2048 #endif
2049
2050 sf_log_next32(sample, "tcpinfo_send_mss");
2051 sf_log_next32(sample, "tcpinfo_receive_mss");
2052 sf_log_next32(sample, "tcpinfo_unacked_pkts");
2053 sf_log_next32(sample, "tcpinfo_lost_pkts");
2054 sf_log_next32(sample, "tcpinfo_retrans_pkts");
2055 sf_log_next32(sample, "tcpinfo_path_mtu");
2056 sf_log_next32(sample, "tcpinfo_rtt_uS");
2057 sf_log_next32(sample, "tcpinfo_rtt_uS_var");
2058 sf_log_next32(sample, "tcpinfo_send_congestion_win");
2059 sf_log_next32(sample, "tcpinfo_reordering");
2060 sf_log_next32(sample, "tcpinfo_rtt_uS_min");
2061 }
2062
2063 #ifdef DEVEL
2064 /*_________________---------------------------__________________
2065 _________________ readCounters_generic __________________
2066 -----------------___________________________------------------
2067 */
2068
readCounters_generic(SFSample * sample)2069 static void readCounters_generic(SFSample *sample)
2070 {
2071 /* the first part of the generic counters block is really just more info about the interface. */
2072 sample->ifCounters.ifIndex = sf_log_next32(sample, "ifIndex");
2073 sample->ifCounters.ifType = sf_log_next32(sample, "networkType");
2074 sample->ifCounters.ifSpeed = sf_log_next64(sample, "ifSpeed");
2075 sample->ifCounters.ifDirection = sf_log_next32(sample, "ifDirection");
2076 sample->ifCounters.ifStatus = sf_log_next32(sample, "ifStatus");
2077 /* the generic counters always come first */
2078 sample->ifCounters.ifInOctets = sf_log_next64(sample, "ifInOctets");
2079 sample->ifCounters.ifInUcastPkts = sf_log_next32(sample, "ifInUcastPkts");
2080 sample->ifCounters.ifInMulticastPkts = sf_log_next32(sample, "ifInMulticastPkts");
2081 sample->ifCounters.ifInBroadcastPkts = sf_log_next32(sample, "ifInBroadcastPkts");
2082 sample->ifCounters.ifInDiscards = sf_log_next32(sample, "ifInDiscards");
2083 sample->ifCounters.ifInErrors = sf_log_next32(sample, "ifInErrors");
2084 sample->ifCounters.ifInUnknownProtos = sf_log_next32(sample, "ifInUnknownProtos");
2085 sample->ifCounters.ifOutOctets = sf_log_next64(sample, "ifOutOctets");
2086 sample->ifCounters.ifOutUcastPkts = sf_log_next32(sample, "ifOutUcastPkts");
2087 sample->ifCounters.ifOutMulticastPkts = sf_log_next32(sample, "ifOutMulticastPkts");
2088 sample->ifCounters.ifOutBroadcastPkts = sf_log_next32(sample, "ifOutBroadcastPkts");
2089 sample->ifCounters.ifOutDiscards = sf_log_next32(sample, "ifOutDiscards");
2090 sample->ifCounters.ifOutErrors = sf_log_next32(sample, "ifOutErrors");
2091 sample->ifCounters.ifPromiscuousMode = sf_log_next32(sample, "ifPromiscuousMode");
2092 }
2093
2094 /*_________________---------------------------__________________
2095 _________________ readCounters_ethernet __________________
2096 -----------------___________________________------------------
2097 */
2098
readCounters_ethernet(SFSample * sample)2099 static void readCounters_ethernet(SFSample *sample)
2100 {
2101 sf_log_next32(sample, "dot3StatsAlignmentErrors");
2102 sf_log_next32(sample, "dot3StatsFCSErrors");
2103 sf_log_next32(sample, "dot3StatsSingleCollisionFrames");
2104 sf_log_next32(sample, "dot3StatsMultipleCollisionFrames");
2105 sf_log_next32(sample, "dot3StatsSQETestErrors");
2106 sf_log_next32(sample, "dot3StatsDeferredTransmissions");
2107 sf_log_next32(sample, "dot3StatsLateCollisions");
2108 sf_log_next32(sample, "dot3StatsExcessiveCollisions");
2109 sf_log_next32(sample, "dot3StatsInternalMacTransmitErrors");
2110 sf_log_next32(sample, "dot3StatsCarrierSenseErrors");
2111 sf_log_next32(sample, "dot3StatsFrameTooLongs");
2112 sf_log_next32(sample, "dot3StatsInternalMacReceiveErrors");
2113 sf_log_next32(sample, "dot3StatsSymbolErrors");
2114 }
2115
2116
2117 /*_________________---------------------------__________________
2118 _________________ readCounters_tokenring __________________
2119 -----------------___________________________------------------
2120 */
2121
readCounters_tokenring(SFSample * sample)2122 static void readCounters_tokenring(SFSample *sample)
2123 {
2124 sf_log_next32(sample, "dot5StatsLineErrors");
2125 sf_log_next32(sample, "dot5StatsBurstErrors");
2126 sf_log_next32(sample, "dot5StatsACErrors");
2127 sf_log_next32(sample, "dot5StatsAbortTransErrors");
2128 sf_log_next32(sample, "dot5StatsInternalErrors");
2129 sf_log_next32(sample, "dot5StatsLostFrameErrors");
2130 sf_log_next32(sample, "dot5StatsReceiveCongestions");
2131 sf_log_next32(sample, "dot5StatsFrameCopiedErrors");
2132 sf_log_next32(sample, "dot5StatsTokenErrors");
2133 sf_log_next32(sample, "dot5StatsSoftErrors");
2134 sf_log_next32(sample, "dot5StatsHardErrors");
2135 sf_log_next32(sample, "dot5StatsSignalLoss");
2136 sf_log_next32(sample, "dot5StatsTransmitBeacons");
2137 sf_log_next32(sample, "dot5StatsRecoverys");
2138 sf_log_next32(sample, "dot5StatsLobeWires");
2139 sf_log_next32(sample, "dot5StatsRemoves");
2140 sf_log_next32(sample, "dot5StatsSingles");
2141 sf_log_next32(sample, "dot5StatsFreqErrors");
2142 }
2143
2144
2145
2146 /*_________________---------------------------__________________
2147 _________________ readCounters_vg __________________
2148 -----------------___________________________------------------
2149 */
2150
readCounters_vg(SFSample * sample)2151 static void readCounters_vg(SFSample *sample)
2152 {
2153 sf_log_next32(sample, "dot12InHighPriorityFrames");
2154 sf_log_next64(sample, "dot12InHighPriorityOctets");
2155 sf_log_next32(sample, "dot12InNormPriorityFrames");
2156 sf_log_next64(sample, "dot12InNormPriorityOctets");
2157 sf_log_next32(sample, "dot12InIPMErrors");
2158 sf_log_next32(sample, "dot12InOversizeFrameErrors");
2159 sf_log_next32(sample, "dot12InDataErrors");
2160 sf_log_next32(sample, "dot12InNullAddressedFrames");
2161 sf_log_next32(sample, "dot12OutHighPriorityFrames");
2162 sf_log_next64(sample, "dot12OutHighPriorityOctets");
2163 sf_log_next32(sample, "dot12TransitionIntoTrainings");
2164 sf_log_next64(sample, "dot12HCInHighPriorityOctets");
2165 sf_log_next64(sample, "dot12HCInNormPriorityOctets");
2166 sf_log_next64(sample, "dot12HCOutHighPriorityOctets");
2167 }
2168
2169 /*_________________---------------------------__________________
2170 _________________ readCounters_vlan __________________
2171 -----------------___________________________------------------
2172 */
2173
readCounters_vlan(SFSample * sample)2174 static void readCounters_vlan(SFSample *sample)
2175 {
2176 sample->in_vlan = getData32(sample);
2177 dbg_printf("in_vlan %u\n", sample->in_vlan);
2178 sf_log_next64(sample, "octets");
2179 sf_log_next32(sample, "ucastPkts");
2180 sf_log_next32(sample, "multicastPkts");
2181 sf_log_next32(sample, "broadcastPkts");
2182 sf_log_next32(sample, "discards");
2183 }
2184
2185
2186 /*_________________---------------------------__________________
2187 _________________ readCounters_80211 __________________
2188 -----------------___________________________------------------
2189 */
2190
readCounters_80211(SFSample * sample)2191 static void readCounters_80211(SFSample *sample)
2192 {
2193 sf_log_next32(sample, "dot11TransmittedFragmentCount");
2194 sf_log_next32(sample, "dot11MulticastTransmittedFrameCount");
2195 sf_log_next32(sample, "dot11FailedCount");
2196 sf_log_next32(sample, "dot11RetryCount");
2197 sf_log_next32(sample, "dot11MultipleRetryCount");
2198 sf_log_next32(sample, "dot11FrameDuplicateCount");
2199 sf_log_next32(sample, "dot11RTSSuccessCount");
2200 sf_log_next32(sample, "dot11RTSFailureCount");
2201 sf_log_next32(sample, "dot11ACKFailureCount");
2202 sf_log_next32(sample, "dot11ReceivedFragmentCount");
2203 sf_log_next32(sample, "dot11MulticastReceivedFrameCount");
2204 sf_log_next32(sample, "dot11FCSErrorCount");
2205 sf_log_next32(sample, "dot11TransmittedFrameCount");
2206 sf_log_next32(sample, "dot11WEPUndecryptableCount");
2207 sf_log_next32(sample, "dot11QoSDiscardedFragmentCount");
2208 sf_log_next32(sample, "dot11AssociatedStationCount");
2209 sf_log_next32(sample, "dot11QoSCFPollsReceivedCount");
2210 sf_log_next32(sample, "dot11QoSCFPollsUnusedCount");
2211 sf_log_next32(sample, "dot11QoSCFPollsUnusableCount");
2212 sf_log_next32(sample, "dot11QoSCFPollsLostCount");
2213 }
2214
2215
2216 /*_________________---------------------------__________________
2217 _________________ readCounters_processor __________________
2218 -----------------___________________________------------------
2219 */
2220
readCounters_processor(SFSample * sample)2221 static void readCounters_processor(SFSample *sample)
2222 {
2223 sf_log_percentage(sample, "5s_cpu");
2224 sf_log_percentage(sample, "1m_cpu");
2225 sf_log_percentage(sample, "5m_cpu");
2226 sf_log_next64(sample, "total_memory_bytes");
2227 sf_log_next64(sample, "free_memory_bytes");
2228 }
2229
2230
2231 /*_________________---------------------------__________________
2232 _________________ readCounters_radio __________________
2233 -----------------___________________________------------------
2234 */
2235
readCounters_radio(SFSample * sample)2236 static void readCounters_radio(SFSample *sample)
2237 {
2238 sf_log_next32(sample, "radio_elapsed_time");
2239 sf_log_next32(sample, "radio_on_channel_time");
2240 sf_log_next32(sample, "radio_on_channel_busy_time");
2241 }
2242
2243 /*_________________---------------------------__________________
2244 _________________ readCounters_OFPort __________________
2245 -----------------___________________________------------------
2246 */
2247
readCounters_OFPort(SFSample * sample)2248 static void readCounters_OFPort(SFSample *sample)
2249 {
2250 uint64_t dpid = getData64(sample);
2251 dbg_printf( "openflow_datapath_id %llx\n", dpid);
2252 sf_log_next32(sample, "openflow_port");
2253 }
2254
2255
2256 /*_________________---------------------------__________________
2257 _________________ readCounters_portName __________________
2258 -----------------___________________________------------------
2259 */
2260
readCounters_portName(SFSample * sample)2261 static void readCounters_portName(SFSample *sample)
2262 {
2263 char ifname[SFL_MAX_PORTNAME_LEN+1];
2264 if(getString(sample, ifname, SFL_MAX_PORTNAME_LEN) > 0) {
2265 dbg_printf("ifName %s\n", ifname);
2266 }
2267 }
2268
2269
2270 /*_________________---------------------------__________________
2271 _________________ readCounters_OVSDP __________________
2272 -----------------___________________________------------------
2273 */
2274
readCounters_OVSDP(SFSample * sample)2275 static void readCounters_OVSDP(SFSample *sample)
2276 {
2277 sf_log_next32(sample, "OVS_dp_hits");
2278 sf_log_next32(sample, "OVS_dp_misses");
2279 sf_log_next32(sample, "OVS_dp_lost");
2280 sf_log_next32(sample, "OVS_dp_mask_hits");
2281 sf_log_next32(sample, "OVS_dp_flows");
2282 sf_log_next32(sample, "OVS_dp_masks");
2283 }
2284
2285
2286 /*_________________---------------------------__________________
2287 _________________ readCounters_host_hid __________________
2288 -----------------___________________________------------------
2289 */
2290
readCounters_host_hid(SFSample * sample)2291 static void readCounters_host_hid(SFSample *sample)
2292 {
2293 uint8_t *uuid;
2294 char hostname[SFL_MAX_HOSTNAME_LEN+1];
2295 char os_release[SFL_MAX_OSRELEASE_LEN+1];
2296 char uuidStr[100];
2297 if(getString(sample, hostname, SFL_MAX_HOSTNAME_LEN) > 0) {
2298 dbg_printf("hostname %s\n", hostname);
2299 }
2300 uuid = (uint8_t *)sample->datap;
2301 printUUID(uuid, uuidStr, 100);
2302 dbg_printf("UUID %s\n", uuidStr);
2303 skipBytes(sample, 16);
2304 sf_log_next32(sample, "machine_type");
2305 sf_log_next32(sample, "os_name");
2306 if(getString(sample, os_release, SFL_MAX_OSRELEASE_LEN) > 0) {
2307 dbg_printf("os_release %s\n", os_release);
2308 }
2309 }
2310
2311
2312 /*_________________---------------------------__________________
2313 _________________ readCounters_adaptors __________________
2314 -----------------___________________________------------------
2315 */
2316
readCounters_adaptors(SFSample * sample)2317 static void readCounters_adaptors(SFSample *sample)
2318 {
2319 uint8_t *mac;
2320 uint32_t i, j, ifindex, num_macs, num_adaptors = getData32(sample);
2321 for(i = 0; i < num_adaptors; i++) {
2322 ifindex = getData32(sample);
2323 dbg_printf("adaptor_%u_ifIndex %u\n", i, ifindex);
2324 num_macs = getData32(sample);
2325 dbg_printf("adaptor_%u_MACs %u\n", i, num_macs);
2326 for(j = 0; j < num_macs; j++) {
2327 mac = (uint8_t *)sample->datap;
2328 dbg_printf("adaptor_%u_MAC_%u %02x%02x%02x%02x%02x%02x\n",
2329 i, j,
2330 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
2331 skipBytes(sample, 8);
2332 }
2333 }
2334 }
2335
2336
2337 /*_________________----------------------------__________________
2338 _________________ readCounters_host_parent __________________
2339 -----------------____________________________------------------
2340 */
2341
readCounters_host_parent(SFSample * sample)2342 static void readCounters_host_parent(SFSample *sample)
2343 {
2344 sf_log_next32(sample, "parent_dsClass");
2345 sf_log_next32(sample, "parent_dsIndex");
2346 }
2347
2348
2349 /*_________________---------------------------__________________
2350 _________________ readCounters_host_cpu __________________
2351 -----------------___________________________------------------
2352 */
2353
readCounters_host_cpu(SFSample * sample,uint32_t length)2354 static void readCounters_host_cpu(SFSample *sample, uint32_t length)
2355 {
2356 sf_log_nextFloat(sample, "cpu_load_one");
2357 sf_log_nextFloat(sample, "cpu_load_five");
2358 sf_log_nextFloat(sample, "cpu_load_fifteen");
2359 sf_log_next32(sample, "cpu_proc_run");
2360 sf_log_next32(sample, "cpu_proc_total");
2361 sf_log_next32(sample, "cpu_num");
2362 sf_log_next32(sample, "cpu_speed");
2363 sf_log_next32(sample, "cpu_uptime");
2364 sf_log_next32(sample, "cpu_user");
2365 sf_log_next32(sample, "cpu_nice");
2366 sf_log_next32(sample, "cpu_system");
2367 sf_log_next32(sample, "cpu_idle");
2368 sf_log_next32(sample, "cpu_wio");
2369 sf_log_next32(sample, "cpuintr");
2370 sf_log_next32(sample, "cpu_sintr");
2371 sf_log_next32(sample, "cpuinterrupts");
2372 sf_log_next32(sample, "cpu_contexts");
2373 if(length > 68) {
2374 /* these three fields were added in December 2014 */
2375 sf_log_next32(sample, "cpu_steal");
2376 sf_log_next32(sample, "cpu_guest");
2377 sf_log_next32(sample, "cpu_guest_nice");
2378 }
2379 }
2380
2381
2382 /*_________________---------------------------__________________
2383 _________________ readCounters_host_mem __________________
2384 -----------------___________________________------------------
2385 */
2386
readCounters_host_mem(SFSample * sample)2387 static void readCounters_host_mem(SFSample *sample)
2388 {
2389 sf_log_next64(sample, "mem_total");
2390 sf_log_next64(sample, "mem_free");
2391 sf_log_next64(sample, "mem_shared");
2392 sf_log_next64(sample, "mem_buffers");
2393 sf_log_next64(sample, "mem_cached");
2394 sf_log_next64(sample, "swap_total");
2395 sf_log_next64(sample, "swap_free");
2396 sf_log_next32(sample, "page_in");
2397 sf_log_next32(sample, "page_out");
2398 sf_log_next32(sample, "swap_in");
2399 sf_log_next32(sample, "swap_out");
2400 }
2401
2402
2403 /*_________________---------------------------__________________
2404 _________________ readCounters_host_dsk __________________
2405 -----------------___________________________------------------
2406 */
2407
readCounters_host_dsk(SFSample * sample)2408 static void readCounters_host_dsk(SFSample *sample)
2409 {
2410 sf_log_next64(sample, "disk_total");
2411 sf_log_next64(sample, "disk_free");
2412 sf_log_percentage(sample, "disk_partition_max_used");
2413 sf_log_next32(sample, "disk_reads");
2414 sf_log_next64(sample, "disk_bytes_read");
2415 sf_log_next32(sample, "disk_read_time");
2416 sf_log_next32(sample, "disk_writes");
2417 sf_log_next64(sample, "disk_bytes_written");
2418 sf_log_next32(sample, "disk_write_time");
2419 }
2420
2421 /*_________________---------------------------__________________
2422 _________________ readCounters_host_nio __________________
2423 -----------------___________________________------------------
2424 */
2425
readCounters_host_nio(SFSample * sample)2426 static void readCounters_host_nio(SFSample *sample)
2427 {
2428 sf_log_next64(sample, "nio_bytes_in");
2429 sf_log_next32(sample, "nio_pkts_in");
2430 sf_log_next32(sample, "nio_errs_in");
2431 sf_log_next32(sample, "nio_drops_in");
2432 sf_log_next64(sample, "nio_bytes_out");
2433 sf_log_next32(sample, "nio_pkts_out");
2434 sf_log_next32(sample, "nio_errs_out");
2435 sf_log_next32(sample, "nio_drops_out");
2436 }
2437
2438 /*_________________---------------------------__________________
2439 _________________ readCounters_host_ip __________________
2440 -----------------___________________________------------------
2441 */
2442
readCounters_host_ip(SFSample * sample)2443 static void readCounters_host_ip(SFSample *sample)
2444 {
2445 sf_log_next32(sample, "ipForwarding");
2446 sf_log_next32(sample, "ipDefaultTTL");
2447 sf_log_next32(sample, "ipInReceives");
2448 sf_log_next32(sample, "ipInHdrErrors");
2449 sf_log_next32(sample, "ipInAddrErrors");
2450 sf_log_next32(sample, "ipForwDatagrams");
2451 sf_log_next32(sample, "ipInUnknownProtos");
2452 sf_log_next32(sample, "ipInDiscards");
2453 sf_log_next32(sample, "ipInDelivers");
2454 sf_log_next32(sample, "ipOutRequests");
2455 sf_log_next32(sample, "ipOutDiscards");
2456 sf_log_next32(sample, "ipOutNoRoutes");
2457 sf_log_next32(sample, "ipReasmTimeout");
2458 sf_log_next32(sample, "ipReasmReqds");
2459 sf_log_next32(sample, "ipReasmOKs");
2460 sf_log_next32(sample, "ipReasmFails");
2461 sf_log_next32(sample, "ipFragOKs");
2462 sf_log_next32(sample, "ipFragFails");
2463 sf_log_next32(sample, "ipFragCreates");
2464 }
2465
2466 /*_________________---------------------------__________________
2467 _________________ readCounters_host_icmp __________________
2468 -----------------___________________________------------------
2469 */
2470
readCounters_host_icmp(SFSample * sample)2471 static void readCounters_host_icmp(SFSample *sample)
2472 {
2473 sf_log_next32(sample, "icmpInMsgs");
2474 sf_log_next32(sample, "icmpInErrors");
2475 sf_log_next32(sample, "icmpInDestUnreachs");
2476 sf_log_next32(sample, "icmpInTimeExcds");
2477 sf_log_next32(sample, "icmpInParamProbs");
2478 sf_log_next32(sample, "icmpInSrcQuenchs");
2479 sf_log_next32(sample, "icmpInRedirects");
2480 sf_log_next32(sample, "icmpInEchos");
2481 sf_log_next32(sample, "icmpInEchoReps");
2482 sf_log_next32(sample, "icmpInTimestamps");
2483 sf_log_next32(sample, "icmpInAddrMasks");
2484 sf_log_next32(sample, "icmpInAddrMaskReps");
2485 sf_log_next32(sample, "icmpOutMsgs");
2486 sf_log_next32(sample, "icmpOutErrors");
2487 sf_log_next32(sample, "icmpOutDestUnreachs");
2488 sf_log_next32(sample, "icmpOutTimeExcds");
2489 sf_log_next32(sample, "icmpOutParamProbs");
2490 sf_log_next32(sample, "icmpOutSrcQuenchs");
2491 sf_log_next32(sample, "icmpOutRedirects");
2492 sf_log_next32(sample, "icmpOutEchos");
2493 sf_log_next32(sample, "icmpOutEchoReps");
2494 sf_log_next32(sample, "icmpOutTimestamps");
2495 sf_log_next32(sample, "icmpOutTimestampReps");
2496 sf_log_next32(sample, "icmpOutAddrMasks");
2497 sf_log_next32(sample, "icmpOutAddrMaskReps");
2498 }
2499
2500 /*_________________---------------------------__________________
2501 _________________ readCounters_host_tcp __________________
2502 -----------------___________________________------------------
2503 */
2504
readCounters_host_tcp(SFSample * sample)2505 static void readCounters_host_tcp(SFSample *sample)
2506 {
2507 sf_log_next32(sample, "tcpRtoAlgorithm");
2508 sf_log_next32(sample, "tcpRtoMin");
2509 sf_log_next32(sample, "tcpRtoMax");
2510 sf_log_next32(sample, "tcpMaxConn");
2511 sf_log_next32(sample, "tcpActiveOpens");
2512 sf_log_next32(sample, "tcpPassiveOpens");
2513 sf_log_next32(sample, "tcpAttemptFails");
2514 sf_log_next32(sample, "tcpEstabResets");
2515 sf_log_next32(sample, "tcpCurrEstab");
2516 sf_log_next32(sample, "tcpInSegs");
2517 sf_log_next32(sample, "tcpOutSegs");
2518 sf_log_next32(sample, "tcpRetransSegs");
2519 sf_log_next32(sample, "tcpInErrs");
2520 sf_log_next32(sample, "tcpOutRsts");
2521 sf_log_next32(sample, "tcpInCsumErrors");
2522 }
2523
2524 /*_________________---------------------------__________________
2525 _________________ readCounters_host_udp __________________
2526 -----------------___________________________------------------
2527 */
2528
readCounters_host_udp(SFSample * sample)2529 static void readCounters_host_udp(SFSample *sample)
2530 {
2531 sf_log_next32(sample, "udpInDatagrams");
2532 sf_log_next32(sample, "udpNoPorts");
2533 sf_log_next32(sample, "udpInErrors");
2534 sf_log_next32(sample, "udpOutDatagrams");
2535 sf_log_next32(sample, "udpRcvbufErrors");
2536 sf_log_next32(sample, "udpSndbufErrors");
2537 sf_log_next32(sample, "udpInCsumErrors");
2538 }
2539
2540 /*_________________-----------------------------__________________
2541 _________________ readCounters_host_vnode __________________
2542 -----------------_____________________________------------------
2543 */
2544
readCounters_host_vnode(SFSample * sample)2545 static void readCounters_host_vnode(SFSample *sample)
2546 {
2547 sf_log_next32(sample, "vnode_mhz");
2548 sf_log_next32(sample, "vnode_cpus");
2549 sf_log_next64(sample, "vnode_memory");
2550 sf_log_next64(sample, "vnode_memory_free");
2551 sf_log_next32(sample, "vnode_num_domains");
2552 }
2553
2554 /*_________________----------------------------__________________
2555 _________________ readCounters_host_vcpu __________________
2556 -----------------____________________________------------------
2557 */
2558
readCounters_host_vcpu(SFSample * sample)2559 static void readCounters_host_vcpu(SFSample *sample)
2560 {
2561 sf_log_next32(sample, "vcpu_state");
2562 sf_log_next32(sample, "vcpu_cpu_mS");
2563 sf_log_next32(sample, "vcpu_cpuCount");
2564 }
2565
2566 /*_________________----------------------------__________________
2567 _________________ readCounters_host_vmem __________________
2568 -----------------____________________________------------------
2569 */
2570
readCounters_host_vmem(SFSample * sample)2571 static void readCounters_host_vmem(SFSample *sample)
2572 {
2573 sf_log_next64(sample, "vmem_memory");
2574 sf_log_next64(sample, "vmem_maxMemory");
2575 }
2576
2577 /*_________________----------------------------__________________
2578 _________________ readCounters_host_vdsk __________________
2579 -----------------____________________________------------------
2580 */
2581
readCounters_host_vdsk(SFSample * sample)2582 static void readCounters_host_vdsk(SFSample *sample)
2583 {
2584 sf_log_next64(sample, "vdsk_capacity");
2585 sf_log_next64(sample, "vdsk_allocation");
2586 sf_log_next64(sample, "vdsk_available");
2587 sf_log_next32(sample, "vdsk_rd_req");
2588 sf_log_next64(sample, "vdsk_rd_bytes");
2589 sf_log_next32(sample, "vdsk_wr_req");
2590 sf_log_next64(sample, "vdsk_wr_bytes");
2591 sf_log_next32(sample, "vdsk_errs");
2592 }
2593
2594 /*_________________----------------------------__________________
2595 _________________ readCounters_host_vnio __________________
2596 -----------------____________________________------------------
2597 */
2598
readCounters_host_vnio(SFSample * sample)2599 static void readCounters_host_vnio(SFSample *sample)
2600 {
2601 sf_log_next64(sample, "vnio_bytes_in");
2602 sf_log_next32(sample, "vnio_pkts_in");
2603 sf_log_next32(sample, "vnio_errs_in");
2604 sf_log_next32(sample, "vnio_drops_in");
2605 sf_log_next64(sample, "vnio_bytes_out");
2606 sf_log_next32(sample, "vnio_pkts_out");
2607 sf_log_next32(sample, "vnio_errs_out");
2608 sf_log_next32(sample, "vnio_drops_out");
2609 }
2610
2611
2612 /*_________________------------------------------__________________
2613 _________________ readCounters_host_gpu_nvml __________________
2614 -----------------______________________________------------------
2615 */
2616
readCounters_host_gpu_nvml(SFSample * sample)2617 static void readCounters_host_gpu_nvml(SFSample *sample)
2618 {
2619 sf_log_next32(sample, "nvml_device_count");
2620 sf_log_next32(sample, "nvml_processes");
2621 sf_log_next32(sample, "nvml_gpu_mS");
2622 sf_log_next32(sample, "nvml_mem_mS");
2623 sf_log_next64(sample, "nvml_mem_bytes_total");
2624 sf_log_next64(sample, "nvml_mem_bytes_free");
2625 sf_log_next32(sample, "nvml_ecc_errors");
2626 sf_log_next32(sample, "nvml_energy_mJ");
2627 sf_log_next32(sample, "nvml_temperature_C");
2628 sf_log_next32(sample, "nvml_fan_speed_pc");
2629 }
2630
2631 /*_________________------------------------------__________________
2632 _________________ readCounters_bcm_tables __________________
2633 -----------------______________________________------------------
2634 */
2635
readCounters_bcm_tables(SFSample * sample)2636 static void readCounters_bcm_tables(SFSample *sample)
2637 {
2638 sf_log_next32(sample, "bcm_asic_host_entries");
2639 sf_log_next32(sample, "bcm_host_entries_max");
2640 sf_log_next32(sample, "bcm_ipv4_entries");
2641 sf_log_next32(sample, "bcm_ipv4_entries_max");
2642 sf_log_next32(sample, "bcm_ipv6_entries");
2643 sf_log_next32(sample, "bcm_ipv6_entries_max");
2644 sf_log_next32(sample, "bcm_ipv4_ipv6_entries");
2645 sf_log_next32(sample, "bcm_ipv4_ipv6_entries_max");
2646 sf_log_next32(sample, "bcm_long_ipv6_entries");
2647 sf_log_next32(sample, "bcm_long_ipv6_entries_max");
2648 sf_log_next32(sample, "bcm_total_routes");
2649 sf_log_next32(sample, "bcm_total_routes_max");
2650 sf_log_next32(sample, "bcm_ecmp_nexthops");
2651 sf_log_next32(sample, "bcm_ecmp_nexthops_max");
2652 sf_log_next32(sample, "bcm_mac_entries");
2653 sf_log_next32(sample, "bcm_mac_entries_max");
2654 sf_log_next32(sample, "bcm_ipv4_neighbors");
2655 sf_log_next32(sample, "bcm_ipv6_neighbors");
2656 sf_log_next32(sample, "bcm_ipv4_routes");
2657 sf_log_next32(sample, "bcm_ipv6_routes");
2658 sf_log_next32(sample, "bcm_acl_ingress_entries");
2659 sf_log_next32(sample, "bcm_acl_ingress_entries_max");
2660 sf_log_next32(sample, "bcm_acl_ingress_counters");
2661 sf_log_next32(sample, "bcm_acl_ingress_counters_max");
2662 sf_log_next32(sample, "bcm_acl_ingress_meters");
2663 sf_log_next32(sample, "bcm_acl_ingress_meters_max");
2664 sf_log_next32(sample, "bcm_acl_ingress_slices");
2665 sf_log_next32(sample, "bcm_acl_ingress_slices_max");
2666 sf_log_next32(sample, "bcm_acl_egress_entries");
2667 sf_log_next32(sample, "bcm_acl_egress_entries_max");
2668 sf_log_next32(sample, "bcm_acl_egress_counters");
2669 sf_log_next32(sample, "bcm_acl_egress_counters_max");
2670 sf_log_next32(sample, "bcm_acl_egress_meters");
2671 sf_log_next32(sample, "bcm_acl_egress_meters_max");
2672 sf_log_next32(sample, "bcm_acl_egress_slices");
2673 sf_log_next32(sample, "bcm_acl_egress_slices_max");
2674 }
2675
2676 /*_________________----------------------------__________________
2677 _________________ readCounters_memcache __________________
2678 -----------------____________________________------------------
2679 for structure 2200 (deprecated)
2680 */
2681
readCounters_memcache(SFSample * sample)2682 static void readCounters_memcache(SFSample *sample)
2683 {
2684 sf_log_next32(sample, "memcache_uptime");
2685 sf_log_next32(sample, "memcache_rusage_user");
2686 sf_log_next32(sample, "memcache_rusage_system");
2687 sf_log_next32(sample, "memcache_curr_connections");
2688 sf_log_next32(sample, "memcache_total_connections");
2689 sf_log_next32(sample, "memcache_connection_structures");
2690 sf_log_next32(sample, "memcache_cmd_get");
2691 sf_log_next32(sample, "memcache_cmd_set");
2692 sf_log_next32(sample, "memcache_cmd_flush");
2693 sf_log_next32(sample, "memcache_get_hits");
2694 sf_log_next32(sample, "memcache_get_misses");
2695 sf_log_next32(sample, "memcache_delete_misses");
2696 sf_log_next32(sample, "memcache_delete_hits");
2697 sf_log_next32(sample, "memcache_incr_misses");
2698 sf_log_next32(sample, "memcache_incr_hits");
2699 sf_log_next32(sample, "memcache_decr_misses");
2700 sf_log_next32(sample, "memcache_decr_hits");
2701 sf_log_next32(sample, "memcache_cas_misses");
2702 sf_log_next32(sample, "memcache_cas_hits");
2703 sf_log_next32(sample, "memcache_cas_badval");
2704 sf_log_next32(sample, "memcache_auth_cmds");
2705 sf_log_next32(sample, "memcache_auth_errors");
2706 sf_log_next64(sample, "memcache_bytes_read");
2707 sf_log_next64(sample, "memcache_bytes_written");
2708 sf_log_next32(sample, "memcache_limit_maxbytes");
2709 sf_log_next32(sample, "memcache_accepting_conns");
2710 sf_log_next32(sample, "memcache_listen_disabled_num");
2711 sf_log_next32(sample, "memcache_threads");
2712 sf_log_next32(sample, "memcache_conn_yields");
2713 sf_log_next64(sample, "memcache_bytes");
2714 sf_log_next32(sample, "memcache_curr_items");
2715 sf_log_next32(sample, "memcache_total_items");
2716 sf_log_next32(sample, "memcache_evictions");
2717 }
2718
2719 /*_________________----------------------------__________________
2720 _________________ readCounters_memcache2 __________________
2721 -----------------____________________________------------------
2722 for structure 2204
2723 */
2724
readCounters_memcache2(SFSample * sample)2725 static void readCounters_memcache2(SFSample *sample)
2726 {
2727 sf_log_next32(sample, "memcache_cmd_set");
2728 sf_log_next32(sample, "memcache_cmd_touch");
2729 sf_log_next32(sample, "memcache_cmd_flush");
2730 sf_log_next32(sample, "memcache_get_hits");
2731 sf_log_next32(sample, "memcache_get_misses");
2732 sf_log_next32(sample, "memcache_delete_hits");
2733 sf_log_next32(sample, "memcache_delete_misses");
2734 sf_log_next32(sample, "memcache_incr_hits");
2735 sf_log_next32(sample, "memcache_incr_misses");
2736 sf_log_next32(sample, "memcache_decr_hits");
2737 sf_log_next32(sample, "memcache_decr_misses");
2738 sf_log_next32(sample, "memcache_cas_hits");
2739 sf_log_next32(sample, "memcache_cas_misses");
2740 sf_log_next32(sample, "memcache_cas_badval");
2741 sf_log_next32(sample, "memcache_auth_cmds");
2742 sf_log_next32(sample, "memcache_auth_errors");
2743 sf_log_next32(sample, "memcache_threads");
2744 sf_log_next32(sample, "memcache_conn_yields");
2745 sf_log_next32(sample, "memcache_listen_disabled_num");
2746 sf_log_next32(sample, "memcache_curr_connections");
2747 sf_log_next32(sample, "memcache_rejected_connections");
2748 sf_log_next32(sample, "memcache_total_connections");
2749 sf_log_next32(sample, "memcache_connection_structures");
2750 sf_log_next32(sample, "memcache_evictions");
2751 sf_log_next32(sample, "memcache_reclaimed");
2752 sf_log_next32(sample, "memcache_curr_items");
2753 sf_log_next32(sample, "memcache_total_items");
2754 sf_log_next64(sample, "memcache_bytes_read");
2755 sf_log_next64(sample, "memcache_bytes_written");
2756 sf_log_next64(sample, "memcache_bytes");
2757 sf_log_next64(sample, "memcache_limit_maxbytes");
2758 }
2759
2760 /*_________________----------------------------__________________
2761 _________________ readCounters_http __________________
2762 -----------------____________________________------------------
2763 */
2764
readCounters_http(SFSample * sample)2765 static void readCounters_http(SFSample *sample)
2766 {
2767 sf_log_next32(sample, "http_method_option_count");
2768 sf_log_next32(sample, "http_method_get_count");
2769 sf_log_next32(sample, "http_method_head_count");
2770 sf_log_next32(sample, "http_method_post_count");
2771 sf_log_next32(sample, "http_method_put_count");
2772 sf_log_next32(sample, "http_method_delete_count");
2773 sf_log_next32(sample, "http_method_trace_count");
2774 sf_log_next32(sample, "http_methd_connect_count");
2775 sf_log_next32(sample, "http_method_other_count");
2776 sf_log_next32(sample, "http_status_1XX_count");
2777 sf_log_next32(sample, "http_status_2XX_count");
2778 sf_log_next32(sample, "http_status_3XX_count");
2779 sf_log_next32(sample, "http_status_4XX_count");
2780 sf_log_next32(sample, "http_status_5XX_count");
2781 sf_log_next32(sample, "http_status_other_count");
2782 }
2783
2784 /*_________________----------------------------__________________
2785 _________________ readCounters_JVM __________________
2786 -----------------____________________________------------------
2787 */
2788
readCounters_JVM(SFSample * sample)2789 static void readCounters_JVM(SFSample *sample)
2790 {
2791 char vm_name[SFLJVM_MAX_VMNAME_LEN];
2792 char vendor[SFLJVM_MAX_VENDOR_LEN];
2793 char version[SFLJVM_MAX_VERSION_LEN];
2794 if(getString(sample, vm_name, SFLJVM_MAX_VMNAME_LEN) > 0) {
2795 dbg_printf("jvm_name %s\n", vm_name);
2796 }
2797 if(getString(sample, vendor, SFLJVM_MAX_VENDOR_LEN) > 0) {
2798 dbg_printf("jvm_vendor %s\n", vendor);
2799 }
2800 if(getString(sample, version, SFLJVM_MAX_VERSION_LEN) > 0) {
2801 dbg_printf("jvm_version %s\n", version);
2802 }
2803 }
2804
2805 /*_________________----------------------------__________________
2806 _________________ readCounters_JMX __________________
2807 -----------------____________________________------------------
2808 */
2809
readCounters_JMX(SFSample * sample,uint32_t length)2810 static void readCounters_JMX(SFSample *sample, uint32_t length)
2811 {
2812 sf_log_next64(sample, "heap_mem_initial");
2813 sf_log_next64(sample, "heap_mem_used");
2814 sf_log_next64(sample, "heap_mem_committed");
2815 sf_log_next64(sample, "heap_mem_max");
2816 sf_log_next64(sample, "non_heap_mem_initial");
2817 sf_log_next64(sample, "non_heap_mem_used");
2818 sf_log_next64(sample, "non_heap_mem_committed");
2819 sf_log_next64(sample, "non_heap_mem_max");
2820 sf_log_next32(sample, "gc_count");
2821 sf_log_next32(sample, "gc_mS");
2822 sf_log_next32(sample, "classes_loaded");
2823 sf_log_next32(sample, "classes_total");
2824 sf_log_next32(sample, "classes_unloaded");
2825 sf_log_next32(sample, "compilation_mS");
2826 sf_log_next32(sample, "threads_live");
2827 sf_log_next32(sample, "threads_daemon");
2828 sf_log_next32(sample, "threads_started");
2829 if(length > 100) {
2830 sf_log_next32(sample, "fds_open");
2831 sf_log_next32(sample, "fds_max");
2832 }
2833 }
2834
2835 /*_________________----------------------------__________________
2836 _________________ readCounters_APP __________________
2837 -----------------____________________________------------------
2838 */
2839
readCounters_APP(SFSample * sample)2840 static void readCounters_APP(SFSample *sample)
2841 {
2842 char application[SFLAPP_MAX_APPLICATION_LEN];
2843 if(getString(sample, application, SFLAPP_MAX_APPLICATION_LEN) > 0) {
2844 dbg_printf("application %s\n", application);
2845 }
2846 sf_log_next32(sample, "status_OK");
2847 sf_log_next32(sample, "errors_OTHER");
2848 sf_log_next32(sample, "errors_TIMEOUT");
2849 sf_log_next32(sample, "errors_INTERNAL_ERROR");
2850 sf_log_next32(sample, "errors_BAD_REQUEST");
2851 sf_log_next32(sample, "errors_FORBIDDEN");
2852 sf_log_next32(sample, "errors_TOO_LARGE");
2853 sf_log_next32(sample, "errors_NOT_IMPLEMENTED");
2854 sf_log_next32(sample, "errors_NOT_FOUND");
2855 sf_log_next32(sample, "errors_UNAVAILABLE");
2856 sf_log_next32(sample, "errors_UNAUTHORIZED");
2857 }
2858
2859 /*_________________----------------------------__________________
2860 _________________ readCounters_APP_RESOURCE __________________
2861 -----------------____________________________------------------
2862 */
2863
readCounters_APP_RESOURCE(SFSample * sample)2864 static void readCounters_APP_RESOURCE(SFSample *sample)
2865 {
2866 sf_log_next32(sample, "user_time");
2867 sf_log_next32(sample, "system_time");
2868 sf_log_next64(sample, "memory_used");
2869 sf_log_next64(sample, "memory_max");
2870 sf_log_next32(sample, "files_open");
2871 sf_log_next32(sample, "files_max");
2872 sf_log_next32(sample, "connections_open");
2873 sf_log_next32(sample, "connections_max");
2874 }
2875
2876 /*_________________----------------------------__________________
2877 _________________ readCounters_APP_WORKERS __________________
2878 -----------------____________________________------------------
2879 */
2880
readCounters_APP_WORKERS(SFSample * sample)2881 static void readCounters_APP_WORKERS(SFSample *sample)
2882 {
2883 sf_log_next32(sample, "workers_active");
2884 sf_log_next32(sample, "workers_idle");
2885 sf_log_next32(sample, "workers_max");
2886 sf_log_next32(sample, "requests_delayed");
2887 sf_log_next32(sample, "requests_dropped");
2888 }
2889
2890 /*_________________----------------------------__________________
2891 _________________ readCounters_VDI __________________
2892 -----------------____________________________------------------
2893 */
2894
readCounters_VDI(SFSample * sample)2895 static void readCounters_VDI(SFSample *sample)
2896 {
2897 sf_log_next32(sample, "vdi_sessions_current");
2898 sf_log_next32(sample, "vdi_sessions_total");
2899 sf_log_next32(sample, "vdi_sessions_duration");
2900 sf_log_next32(sample, "vdi_rx_bytes");
2901 sf_log_next32(sample, "vdi_tx_bytes");
2902 sf_log_next32(sample, "vdi_rx_packets");
2903 sf_log_next32(sample, "vdi_tx_packets");
2904 sf_log_next32(sample, "vdi_rx_packets_lost");
2905 sf_log_next32(sample, "vdi_tx_packets_lost");
2906 sf_log_next32(sample, "vdi_rtt_min_ms");
2907 sf_log_next32(sample, "vdi_rtt_max_ms");
2908 sf_log_next32(sample, "vdi_rtt_avg_ms");
2909 sf_log_next32(sample, "vdi_audio_rx_bytes");
2910 sf_log_next32(sample, "vdi_audio_tx_bytes");
2911 sf_log_next32(sample, "vdi_audio_tx_limit");
2912 sf_log_next32(sample, "vdi_img_rx_bytes");
2913 sf_log_next32(sample, "vdi_img_tx_bytes");
2914 sf_log_next32(sample, "vdi_img_frames");
2915 sf_log_next32(sample, "vdi_img_qual_min");
2916 sf_log_next32(sample, "vdi_img_qual_max");
2917 sf_log_next32(sample, "vdi_img_qual_avg");
2918 sf_log_next32(sample, "vdi_usb_rx_bytes");
2919 sf_log_next32(sample, "vdi_usb_tx_bytes");
2920 }
2921
2922 /*_________________------------------------------__________________
2923 _________________ readCounters_LACP __________________
2924 -----------------______________________________------------------
2925 */
2926
readCounters_LACP(SFSample * sample)2927 static void readCounters_LACP(SFSample *sample)
2928 {
2929 SFLLACP_portState portState;
2930 sf_log_nextMAC(sample, "actorSystemID");
2931 sf_log_nextMAC(sample, "partnerSystemID");
2932 sf_log_next32(sample, "attachedAggID");
2933 portState.all = getData32_nobswap(sample);
2934 dbg_printf("actorAdminPortState %u\n", portState.v.actorAdmin);
2935 dbg_printf("actorOperPortState %u\n", portState.v.actorOper);
2936 dbg_printf("partnerAdminPortState %u\n", portState.v.partnerAdmin);
2937 dbg_printf("partnerOperPortState %u\n", portState.v.partnerOper);
2938 sf_log_next32(sample, "LACPDUsRx");
2939 sf_log_next32(sample, "markerPDUsRx");
2940 sf_log_next32(sample, "markerResponsePDUsRx");
2941 sf_log_next32(sample, "unknownRx");
2942 sf_log_next32(sample, "illegalRx");
2943 sf_log_next32(sample, "LACPDUsTx");
2944 sf_log_next32(sample, "markerPDUsTx");
2945 sf_log_next32(sample, "markerResponsePDUsTx");
2946 }
2947
2948 /*_________________----------------------------__________________
2949 _________________ readCounters_SFP __________________
2950 -----------------____________________________------------------
2951 */
2952
readCounters_SFP(SFSample * sample)2953 static void readCounters_SFP(SFSample *sample)
2954 {
2955 uint32_t num_lanes,ll;
2956 sf_log_next32(sample, "sfp_module_id");
2957 sf_log_next32(sample, "sfp_module_total_lanes");
2958 sf_log_next32(sample, "sfp_module_supply_voltage");
2959 sf_log_next32(sample, "sfp_module_temperature");
2960 num_lanes = getData32(sample);
2961 dbg_printf( "sfp_module_active_lanes %u\n", num_lanes);
2962 for(ll=0; ll < num_lanes; ll++) {
2963 dbg_printf( "sfp_lane_index.%u %u\n", ll, getData32(sample));
2964 dbg_printf( "sfp_lane_tx_bias_current_uA.%u %u\n", ll, getData32(sample));
2965 dbg_printf( "sfp_lane_tx_power_uW.%u %u\n", ll, getData32(sample));
2966 dbg_printf( "sfp_lane_tx_power_min_uW.%u %u\n", ll, getData32(sample));
2967 dbg_printf( "sfp_lane_tx_power_max_uW.%u %u\n", ll, getData32(sample));
2968 dbg_printf( "sfp_lane_tx_wavelength_nM.%u %u\n", ll, getData32(sample));
2969 dbg_printf( "sfp_lane_rx_power_uW.%u %u\n", ll, getData32(sample));
2970 dbg_printf( "sfp_lane_rx_power_min_uW.%u %u\n", ll, getData32(sample));
2971 dbg_printf( "sfp_lane_rx_power_max_uW.%u %u\n", ll, getData32(sample));
2972 dbg_printf( "sfp_lane_rx_wavelength_nM.%u %u\n", ll, getData32(sample));
2973 }
2974 }
2975
2976 /*_________________---------------------------__________________
2977 _________________ readCountersSample_v2v4 __________________
2978 -----------------___________________________------------------
2979 */
2980
readCountersSample_v2v4(SFSample * sample,FlowSource_t * fs,int verbose)2981 static void readCountersSample_v2v4(SFSample *sample, FlowSource_t *fs, int verbose)
2982 {
2983 dbg_printf("sampleType COUNTERSSAMPLE\n");
2984 sample->samplesGenerated = getData32(sample);
2985 dbg_printf("sampleSequenceNo %u\n", sample->samplesGenerated);
2986 {
2987 uint32_t samplerId = getData32(sample);
2988 sample->ds_class = samplerId >> 24;
2989 sample->ds_index = samplerId & 0x00ffffff;
2990 }
2991 dbg_printf("sourceId %u:%u\n", sample->ds_class, sample->ds_index);
2992
2993
2994 sample->statsSamplingInterval = getData32(sample);
2995 dbg_printf("statsSamplingInterval %u\n", sample->statsSamplingInterval);
2996 /* now find out what sort of counter blocks we have here... */
2997 sample->counterBlockVersion = getData32(sample);
2998 dbg_printf("counterBlockVersion %u\n", sample->counterBlockVersion);
2999
3000 /* first see if we should read the generic stats */
3001 switch(sample->counterBlockVersion) {
3002 case INMCOUNTERSVERSION_GENERIC:
3003 case INMCOUNTERSVERSION_ETHERNET:
3004 case INMCOUNTERSVERSION_TOKENRING:
3005 case INMCOUNTERSVERSION_FDDI:
3006 case INMCOUNTERSVERSION_VG:
3007 case INMCOUNTERSVERSION_WAN: readCounters_generic(sample); break;
3008 case INMCOUNTERSVERSION_VLAN: break;
3009 default: receiveError(sample, "unknown stats version", YES); break;
3010 }
3011
3012 /* now see if there are any specific counter blocks to add */
3013 switch(sample->counterBlockVersion) {
3014 case INMCOUNTERSVERSION_GENERIC: /* nothing more */ break;
3015 case INMCOUNTERSVERSION_ETHERNET: readCounters_ethernet(sample); break;
3016 case INMCOUNTERSVERSION_TOKENRING:readCounters_tokenring(sample); break;
3017 case INMCOUNTERSVERSION_FDDI: break;
3018 case INMCOUNTERSVERSION_VG: readCounters_vg(sample); break;
3019 case INMCOUNTERSVERSION_WAN: break;
3020 case INMCOUNTERSVERSION_VLAN: readCounters_vlan(sample); break;
3021 default: receiveError(sample, "unknown INMCOUNTERSVERSION", YES); break;
3022 }
3023 /* line-by-line output... */
3024 if ( verbose )
3025 writeCountersLine(sample);
3026 }
3027
3028 /*_________________---------------------------__________________
3029 _________________ readCountersSample __________________
3030 -----------------___________________________------------------
3031 */
3032
readCountersSample(SFSample * sample,int expanded,FlowSource_t * fs,int verbose)3033 static void readCountersSample(SFSample *sample, int expanded, FlowSource_t *fs, int verbose)
3034 {
3035 uint32_t sampleLength;
3036 uint32_t num_elements;
3037 uint8_t *sampleStart;
3038 dbg_printf("sampleType COUNTERSSAMPLE\n");
3039 sampleLength = getData32(sample);
3040 sampleStart = (uint8_t *)sample->datap;
3041 sample->samplesGenerated = getData32(sample);
3042
3043 dbg_printf("sampleSequenceNo %u\n", sample->samplesGenerated);
3044 if(expanded) {
3045 sample->ds_class = getData32(sample);
3046 sample->ds_index = getData32(sample);
3047 }
3048 else {
3049 uint32_t samplerId = getData32(sample);
3050 sample->ds_class = samplerId >> 24;
3051 sample->ds_index = samplerId & 0x00ffffff;
3052 }
3053 dbg_printf("sourceId %u:%u\n", sample->ds_class, sample->ds_index);
3054
3055 num_elements = getData32(sample);
3056 {
3057 uint32_t el;
3058 for(el = 0; el < num_elements; el++) {
3059 uint32_t tag, length;
3060 uint8_t *start;
3061 char buf[51];
3062 tag = sample->elementType = getData32(sample);
3063 dbg_printf("counterBlock_tag %s\n", printTag(tag, buf, 50));
3064 length = getData32(sample);
3065 start = (uint8_t *)sample->datap;
3066
3067 switch(tag) {
3068 case SFLCOUNTERS_GENERIC: readCounters_generic(sample); break;
3069 case SFLCOUNTERS_ETHERNET: readCounters_ethernet(sample); break;
3070 case SFLCOUNTERS_TOKENRING:readCounters_tokenring(sample); break;
3071 case SFLCOUNTERS_VG: readCounters_vg(sample); break;
3072 case SFLCOUNTERS_VLAN: readCounters_vlan(sample); break;
3073 case SFLCOUNTERS_80211: readCounters_80211(sample); break;
3074 case SFLCOUNTERS_LACP: readCounters_LACP(sample); break;
3075 case SFLCOUNTERS_SFP: readCounters_SFP(sample); break;
3076 case SFLCOUNTERS_PROCESSOR: readCounters_processor(sample); break;
3077 case SFLCOUNTERS_RADIO: readCounters_radio(sample); break;
3078 case SFLCOUNTERS_OFPORT: readCounters_OFPort(sample); break;
3079 case SFLCOUNTERS_PORTNAME: readCounters_portName(sample); break;
3080 case SFLCOUNTERS_HOST_HID: readCounters_host_hid(sample); break;
3081 case SFLCOUNTERS_ADAPTORS: readCounters_adaptors(sample); break;
3082 case SFLCOUNTERS_HOST_PAR: readCounters_host_parent(sample); break;
3083 case SFLCOUNTERS_HOST_CPU: readCounters_host_cpu(sample, length); break;
3084 case SFLCOUNTERS_HOST_MEM: readCounters_host_mem(sample); break;
3085 case SFLCOUNTERS_HOST_DSK: readCounters_host_dsk(sample); break;
3086 case SFLCOUNTERS_HOST_NIO: readCounters_host_nio(sample); break;
3087 case SFLCOUNTERS_HOST_IP: readCounters_host_ip(sample); break;
3088 case SFLCOUNTERS_HOST_ICMP: readCounters_host_icmp(sample); break;
3089 case SFLCOUNTERS_HOST_TCP: readCounters_host_tcp(sample); break;
3090 case SFLCOUNTERS_HOST_UDP: readCounters_host_udp(sample); break;
3091 case SFLCOUNTERS_HOST_VRT_NODE: readCounters_host_vnode(sample); break;
3092 case SFLCOUNTERS_HOST_VRT_CPU: readCounters_host_vcpu(sample); break;
3093 case SFLCOUNTERS_HOST_VRT_MEM: readCounters_host_vmem(sample); break;
3094 case SFLCOUNTERS_HOST_VRT_DSK: readCounters_host_vdsk(sample); break;
3095 case SFLCOUNTERS_HOST_VRT_NIO: readCounters_host_vnio(sample); break;
3096 case SFLCOUNTERS_HOST_GPU_NVML: readCounters_host_gpu_nvml(sample); break;
3097 case SFLCOUNTERS_BCM_TABLES: readCounters_bcm_tables(sample); break;
3098 case SFLCOUNTERS_MEMCACHE: readCounters_memcache(sample); break;
3099 case SFLCOUNTERS_MEMCACHE2: readCounters_memcache2(sample); break;
3100 case SFLCOUNTERS_HTTP: readCounters_http(sample); break;
3101 case SFLCOUNTERS_JVM: readCounters_JVM(sample); break;
3102 case SFLCOUNTERS_JMX: readCounters_JMX(sample, length); break;
3103 case SFLCOUNTERS_APP: readCounters_APP(sample); break;
3104 case SFLCOUNTERS_APP_RESOURCE: readCounters_APP_RESOURCE(sample); break;
3105 case SFLCOUNTERS_APP_WORKERS: readCounters_APP_WORKERS(sample); break;
3106 case SFLCOUNTERS_VDI: readCounters_VDI(sample); break;
3107 case SFLCOUNTERS_OVSDP: readCounters_OVSDP(sample); break;
3108 default: skipTLVRecord(sample, tag, length, "counters_sample_element"); break;
3109 }
3110 lengthCheck(sample, "counters_sample_element", start, length);
3111 }
3112 }
3113 lengthCheck(sample, "counters_sample", sampleStart, sampleLength);
3114 /* line-by-line output... */
3115 if ( verbose )
3116 writeCountersLine(sample);
3117 }
3118
3119
3120 /*_________________---------------------------__________________
3121 _________________ readRTMetric __________________
3122 -----------------___________________________------------------
3123 */
3124
readRTMetric(SFSample * sample,FlowSource_t * fs,int verbose)3125 static void readRTMetric(SFSample *sample, FlowSource_t *fs, int verbose)
3126 {
3127 #define SFL_MAX_RTMETRIC_KEY_LEN 64
3128 #define SFL_MAX_RTMETRIC_VAL_LEN 255
3129 char dsName[SFL_MAX_RTMETRIC_KEY_LEN];
3130 uint32_t sampleLength;
3131 uint32_t num_elements;
3132 uint8_t *sampleStart;
3133 dbg_printf("sampleType RTMETRIC\n");
3134 sampleLength = getData32(sample);
3135 sampleStart = (uint8_t *)sample->datap;
3136 if(getString(sample, dsName, SFL_MAX_RTMETRIC_KEY_LEN) > 0) {
3137 dbg_printf( "rtmetric_datasource_name %s\n", dsName);
3138 }
3139 num_elements = getData32(sample);
3140 {
3141 uint32_t el;
3142 for(el = 0; el < num_elements; el++) {
3143 char mname[SFL_MAX_RTMETRIC_KEY_LEN];
3144 uint32_t mtype;
3145 char mvalstr[SFL_MAX_RTMETRIC_VAL_LEN];
3146 uint32_t mvali32;
3147 uint64_t mvali64;
3148 float mvalfloat;
3149 double mvaldouble;
3150 getString(sample, mname, SFL_MAX_RTMETRIC_KEY_LEN);
3151 mtype = getData32(sample);
3152 switch(mtype) {
3153 case 0:
3154 getString(sample, mvalstr, SFL_MAX_RTMETRIC_VAL_LEN);
3155 dbg_printf( "rtmetric %s = (string) \"%s\"\n", mname, mvalstr);
3156 break;
3157 case 1:
3158 mvali32 = getData32(sample);
3159 dbg_printf( "rtmetric %s = (counter32) %u\n", mname, mvali32);
3160 break;
3161 case 2:
3162 mvali64 = getData64(sample);
3163 dbg_printf( "rtmetric %s = (counter64) %llu\n", mname, mvali64);
3164 break;
3165 case 3:
3166 mvali32 = getData32(sample);
3167 dbg_printf( "rtmetric %s = (gauge32) %u\n", mname, mvali32);
3168 break;
3169 case 4:
3170 mvali64 = getData64(sample);
3171 dbg_printf( "rtmetric %s = (gauge64) %llu\n", mname, mvali64);
3172 break;
3173 case 5:
3174 mvalfloat = getFloat(sample);
3175 dbg_printf( "rtmetric %s = (gaugefloat) %.3f\n", mname, mvalfloat);
3176 break;
3177 case 6:
3178 mvaldouble = getDouble(sample);
3179 dbg_printf( "rtmetric %s = (gaugefloat) %.3f\n", mname, mvaldouble);
3180 break;
3181 default:
3182 dbg_printf( "rtmetric unknown_type %u\n", mtype);
3183 SFABORT(sample, SF_ABORT_DECODE_ERROR);
3184 break;
3185 }
3186 }
3187 }
3188 lengthCheck(sample, "rtmetric_sample", sampleStart, sampleLength);
3189
3190 if ( verbose )
3191 writeCountersLine(sample);
3192
3193 }
3194
3195 /*_________________---------------------------__________________
3196 _________________ readRTFlow __________________
3197 -----------------___________________________------------------
3198 */
3199
readRTFlow(SFSample * sample,FlowSource_t * fs,int verbose)3200 static void readRTFlow(SFSample *sample, FlowSource_t *fs, int verbose)
3201 {
3202 char dsName[SFL_MAX_RTMETRIC_KEY_LEN];
3203 uint32_t sampleLength;
3204 uint32_t num_elements;
3205 uint8_t *sampleStart;
3206 dbg_printf("sampleType RTFLOW\n");
3207 sampleLength = getData32(sample);
3208 sampleStart = (uint8_t *)sample->datap;
3209 if(getString(sample, dsName, SFL_MAX_RTMETRIC_KEY_LEN) > 0) {
3210 dbg_printf( "rtflow_datasource_name %s\n", dsName);
3211 }
3212 sf_log_next32(sample, "rtflow_sampling_rate");
3213 sf_log_next32(sample, "rtflow_sample_pool");
3214 num_elements = getData32(sample);
3215 {
3216 uint32_t el;
3217 for(el = 0; el < num_elements; el++) {
3218 char fname[SFL_MAX_RTMETRIC_KEY_LEN];
3219 uint32_t ftype;
3220 char fvalstr[SFL_MAX_RTMETRIC_VAL_LEN];
3221 uint32_t fvali32;
3222 uint64_t fvali64;
3223 float fvalfloat;
3224 double fvaldouble;
3225 SFLAddress fvaladdr;
3226 char fvaladdrstr[64];
3227 u_char fvalmac[6];
3228 char fvalmacstr[32];
3229 getString(sample, fname, SFL_MAX_RTMETRIC_KEY_LEN);
3230 ftype = getData32(sample);
3231 switch(ftype) {
3232 case 0:
3233 getString(sample, fvalstr, SFL_MAX_RTMETRIC_VAL_LEN);
3234 dbg_printf( "rtflow %s = (string) \"%s\"\n", fname, fvalstr);
3235 break;
3236 case 1:
3237 memcpy(fvalmac, sample->datap, 6);
3238 skipBytes(sample, 6);
3239 printHex(fvalmac, 6, fvalmacstr, 32, 0, 100);
3240 dbg_printf( "rtflow %s = (mac) %s\n", fname, fvalmacstr);
3241 break;
3242 case 2:
3243 fvaladdr.type = SFLADDRESSTYPE_IP_V4;
3244 fvaladdr.address.ip_v4.addr = getData32_nobswap(sample);
3245 dbg_printf( "rtflow %s = (ip) %s\n",
3246 fname,
3247 printAddress(&fvaladdr,fvaladdrstr, 63));
3248 break;
3249 case 3:
3250 fvaladdr.type = SFLADDRESSTYPE_IP_V6;
3251 memcpy(fvaladdr.address.ip_v6.addr, sample->datap, 16);
3252 skipBytes(sample, 16);
3253 dbg_printf( "rtflow %s = (ip6) %s\n",
3254 fname,
3255 printAddress(&fvaladdr,fvaladdrstr, 63));
3256 break;
3257 case 4:
3258 fvali32 = getData32(sample);
3259 dbg_printf( "rtflow %s = (int32) %u\n", fname, fvali32);
3260 break;
3261 case 5:
3262 fvali64 = getData64(sample);
3263 dbg_printf( "rtflow %s = (int64) %llu\n", fname, fvali64);
3264 break;
3265 case 6:
3266 fvalfloat = getFloat(sample);
3267 dbg_printf( "rtflow %s = (gaugefloat) %.3f\n", fname, fvalfloat);
3268 break;
3269 case 7:
3270 fvaldouble = getDouble(sample);
3271 dbg_printf( "rtflow %s = (gaugefloat) %.3f\n", fname, fvaldouble);
3272 break;
3273 default:
3274 dbg_printf( "rtflow unknown_type %u\n", ftype);
3275 SFABORT(sample, SF_ABORT_DECODE_ERROR);
3276 break;
3277 }
3278 }
3279 }
3280 lengthCheck(sample, "rtflow_sample", sampleStart, sampleLength);
3281
3282 if ( verbose )
3283 writeCountersLine(sample);
3284 }
3285
3286 #endif
3287
3288 /*_________________---------------------------__________________
3289 _________________ readFlowSample_v2v4 __________________
3290 -----------------___________________________------------------
3291 */
3292
readFlowSample_v2v4(SFSample * sample,FlowSource_t * fs,int verbose)3293 static void readFlowSample_v2v4(SFSample *sample, FlowSource_t *fs, int verbose) {
3294
3295 dbg_printf("sampleType FLOWSAMPLE\n");
3296
3297 sample->samplesGenerated = getData32(sample);
3298 dbg_printf("sampleSequenceNo %u\n", sample->samplesGenerated);
3299 {
3300 uint32_t samplerId = getData32(sample);
3301 sample->ds_class = samplerId >> 24;
3302 sample->ds_index = samplerId & 0x00ffffff;
3303 dbg_printf("sourceId %u:%u\n", sample->ds_class, sample->ds_index);
3304 }
3305
3306 sample->meanSkipCount = getData32(sample);
3307 sample->samplePool = getData32(sample);
3308 sample->dropEvents = getData32(sample);
3309 sample->inputPort = getData32(sample);
3310 sample->outputPort = getData32(sample);
3311
3312 #ifdef DEVEL
3313 printf("meanSkipCount %u\n", sample->meanSkipCount);
3314 printf("samplePool %u\n", sample->samplePool);
3315 printf("dropEvents %u\n", sample->dropEvents);
3316 printf("inputPort %u\n", sample->inputPort);
3317
3318 if(sample->outputPort & 0x80000000) {
3319 uint32_t numOutputs = sample->outputPort & 0x7fffffff;
3320 if(numOutputs > 0)
3321 printf("outputPort multiple %d\n", numOutputs);
3322 else
3323 printf("outputPort multiple >1\n");
3324 } else
3325 printf("outputPort %u\n", sample->outputPort);
3326 #endif
3327
3328 sample->packet_data_tag = getData32(sample);
3329
3330 switch(sample->packet_data_tag) {
3331 case INMPACKETTYPE_HEADER:
3332 readFlowSample_header(sample);
3333 break;
3334 case INMPACKETTYPE_IPV4:
3335 sample->gotIPV4Struct = YES;
3336 readFlowSample_IPv4(sample, "");
3337 break;
3338 case INMPACKETTYPE_IPV6:
3339 sample->gotIPV6Struct = YES;
3340 readFlowSample_IPv6(sample, "");
3341 break;
3342 default:
3343 receiveError(sample, "unexpected packet_data_tag", YES);
3344 return;
3345 break;
3346 }
3347
3348 sample->extended_data_tag = 0;
3349 {
3350 uint32_t x;
3351 sample->num_extended = getData32(sample);
3352 for(x = 0; x < sample->num_extended; x++) {
3353 uint32_t extended_tag;
3354 extended_tag = getData32(sample);
3355 switch(extended_tag) {
3356 case INMEXTENDED_SWITCH: readExtendedSwitch(sample);
3357 break;
3358 case INMEXTENDED_ROUTER: readExtendedRouter(sample);
3359 break;
3360 case INMEXTENDED_GATEWAY:
3361 if(sample->datagramVersion == 2)
3362 readExtendedGateway_v2(sample);
3363 else
3364 readExtendedGateway(sample);
3365 break;
3366 case INMEXTENDED_USER: readExtendedUser(sample);
3367 break;
3368 case INMEXTENDED_URL: readExtendedUrl(sample);
3369 break;
3370 default:
3371 receiveError(sample, "unrecognized extended data tag", YES);
3372 return;
3373 break;
3374 }
3375 }
3376 }
3377
3378 StoreSflowRecord(sample, fs);
3379
3380 if ( verbose )
3381 writeFlowLine(sample);
3382
3383 } // End of readFlowSample_v2v4
3384
3385 /*_________________---------------------------__________________
3386 _________________ readFlowSample __________________
3387 -----------------___________________________------------------
3388 */
3389
readFlowSample(SFSample * sample,int expanded,FlowSource_t * fs,int verbose)3390 static void readFlowSample(SFSample *sample, int expanded, FlowSource_t *fs, int verbose) {
3391 uint32_t num_elements, sampleLength;
3392 uint8_t *sampleStart;
3393
3394 dbg_printf("sampleType FLOWSAMPLE\n");
3395 sampleLength = getData32(sample);
3396 sampleStart = (uint8_t *)sample->datap;
3397 sample->samplesGenerated = getData32(sample);
3398 dbg_printf("sampleSequenceNo %u\n", sample->samplesGenerated);
3399
3400 if(expanded) {
3401 sample->ds_class = getData32(sample);
3402 sample->ds_index = getData32(sample);
3403 } else {
3404 uint32_t samplerId = getData32(sample);
3405 sample->ds_class = samplerId >> 24;
3406 sample->ds_index = samplerId & 0x00ffffff;
3407 }
3408 dbg_printf("sourceId %u:%u\n", sample->ds_class, sample->ds_index);
3409
3410 sample->meanSkipCount = getData32(sample);
3411 sample->samplePool = getData32(sample);
3412 sample->dropEvents = getData32(sample);
3413 dbg_printf("meanSkipCount %u\n", sample->meanSkipCount);
3414 dbg_printf("samplePool %u\n", sample->samplePool);
3415 dbg_printf("dropEvents %u\n", sample->dropEvents);
3416 if(expanded) {
3417 sample->inputPortFormat = getData32(sample);
3418 sample->inputPort = getData32(sample);
3419 sample->outputPortFormat = getData32(sample);
3420 sample->outputPort = getData32(sample);
3421 } else {
3422 uint32_t inp, outp;
3423 inp = getData32(sample);
3424 outp = getData32(sample);
3425 sample->inputPortFormat = inp >> 30;
3426 sample->outputPortFormat = outp >> 30;
3427 sample->inputPort = inp & 0x3fffffff;
3428 sample->outputPort = outp & 0x3fffffff;
3429 }
3430
3431 switch(sample->inputPortFormat) {
3432 case 3: dbg_printf("inputPort format==3 %u\n", sample->inputPort);
3433 break;
3434 case 2: dbg_printf("inputPort multiple %u\n", sample->inputPort);
3435 break;
3436 case 1: dbg_printf("inputPort dropCode %u\n", sample->inputPort);
3437 break;
3438 case 0: dbg_printf("inputPort %u\n", sample->inputPort);
3439 break;
3440 }
3441
3442 switch(sample->outputPortFormat) {
3443 case 3: dbg_printf("outputPort format==3 %u\n", sample->outputPort);
3444 break;
3445 case 2: dbg_printf("outputPort multiple %u\n", sample->outputPort);
3446 break;
3447 case 1: dbg_printf("outputPort dropCode %u\n", sample->outputPort);
3448 break;
3449 case 0: dbg_printf("outputPort %u\n", sample->outputPort);
3450 break;
3451 }
3452
3453 num_elements = getData32(sample);
3454 {
3455 uint32_t el;
3456 for(el = 0; el < num_elements; el++) {
3457 uint32_t tag, length;
3458 uint8_t *start;
3459 #ifdef DEVEL
3460 char buf[51];
3461 #endif
3462 tag = sample->elementType = getData32(sample);
3463 dbg_printf("flowBlock_tag %s\n", printTag(tag, buf, 50));
3464 length = getData32(sample);
3465 start = (uint8_t *)sample->datap;
3466
3467 switch(tag) {
3468 case SFLFLOW_HEADER: readFlowSample_header(sample); break;
3469 case SFLFLOW_ETHERNET: readFlowSample_ethernet(sample, ""); break;
3470 case SFLFLOW_IPV4: readFlowSample_IPv4(sample, ""); break;
3471 case SFLFLOW_IPV6: readFlowSample_IPv6(sample, ""); break;
3472 case SFLFLOW_MEMCACHE: readFlowSample_memcache(sample); break;
3473 case SFLFLOW_HTTP: readFlowSample_http(sample, tag); break;
3474 case SFLFLOW_HTTP2: readFlowSample_http(sample, tag); break;
3475 case SFLFLOW_APP: readFlowSample_APP(sample); break;
3476 case SFLFLOW_APP_CTXT: readFlowSample_APP_CTXT(sample); break;
3477 case SFLFLOW_APP_ACTOR_INIT: readFlowSample_APP_ACTOR_INIT(sample); break;
3478 case SFLFLOW_APP_ACTOR_TGT: readFlowSample_APP_ACTOR_TGT(sample); break;
3479 case SFLFLOW_EX_SWITCH: readExtendedSwitch(sample); break;
3480 case SFLFLOW_EX_ROUTER: readExtendedRouter(sample); break;
3481 case SFLFLOW_EX_GATEWAY: readExtendedGateway(sample); break;
3482 case SFLFLOW_EX_USER: readExtendedUser(sample); break;
3483 case SFLFLOW_EX_URL: readExtendedUrl(sample); break;
3484 case SFLFLOW_EX_MPLS: readExtendedMpls(sample); break;
3485 case SFLFLOW_EX_NAT: readExtendedNat(sample); break;
3486 case SFLFLOW_EX_NAT_PORT: readExtendedNatPort(sample); break;
3487 case SFLFLOW_EX_MPLS_TUNNEL: readExtendedMplsTunnel(sample); break;
3488 case SFLFLOW_EX_MPLS_VC: readExtendedMplsVC(sample); break;
3489 case SFLFLOW_EX_MPLS_FTN: readExtendedMplsFTN(sample); break;
3490 case SFLFLOW_EX_MPLS_LDP_FEC: readExtendedMplsLDP_FEC(sample); break;
3491 case SFLFLOW_EX_VLAN_TUNNEL: readExtendedVlanTunnel(sample); break;
3492 case SFLFLOW_EX_80211_PAYLOAD: readExtendedWifiPayload(sample); break;
3493 case SFLFLOW_EX_80211_RX: readExtendedWifiRx(sample); break;
3494 case SFLFLOW_EX_80211_TX: readExtendedWifiTx(sample); break;
3495 case SFLFLOW_EX_SOCKET4: readExtendedSocket4(sample); break;
3496 case SFLFLOW_EX_SOCKET6: readExtendedSocket6(sample); break;
3497 case SFLFLOW_EX_PROXYSOCKET4: readExtendedProxySocket4(sample); break;
3498 case SFLFLOW_EX_PROXYSOCKET6: readExtendedProxySocket6(sample); break;
3499 case SFLFLOW_EX_L2_TUNNEL_OUT: readFlowSample_ethernet(sample, "tunnel_l2_out_"); break;
3500 case SFLFLOW_EX_L2_TUNNEL_IN: readFlowSample_ethernet(sample, "tunnel_l2_in_"); break;
3501 case SFLFLOW_EX_IPV4_TUNNEL_OUT: readFlowSample_IPv4(sample, "tunnel_ipv4_out_"); break;
3502 case SFLFLOW_EX_IPV4_TUNNEL_IN: readFlowSample_IPv4(sample, "tunnel_ipv4_in_"); break;
3503 case SFLFLOW_EX_IPV6_TUNNEL_OUT: readFlowSample_IPv6(sample, "tunnel_ipv6_out_"); break;
3504 case SFLFLOW_EX_IPV6_TUNNEL_IN: readFlowSample_IPv6(sample, "tunnel_ipv6_in_"); break;
3505 case SFLFLOW_EX_DECAP_OUT: readExtendedDecap(sample, "out_"); break;
3506 case SFLFLOW_EX_DECAP_IN: readExtendedDecap(sample, "in_"); break;
3507 case SFLFLOW_EX_VNI_OUT: readExtendedVNI(sample, "out_"); break;
3508 case SFLFLOW_EX_VNI_IN: readExtendedVNI(sample, "in_"); break;
3509 case SFLFLOW_EX_TCP_INFO: readExtendedTCPInfo(sample); break;
3510 default: skipTLVRecord(sample, tag, length, "flow_sample_element"); break;
3511 }
3512 lengthCheck(sample, "flow_sample_element", start, length);
3513 }
3514 }
3515 lengthCheck(sample, "flow_sample", sampleStart, sampleLength);
3516
3517 StoreSflowRecord(sample, fs);
3518
3519 /* or line-by-line output... */
3520 if ( verbose )
3521 writeFlowLine(sample);
3522
3523 } // End of readFlowSample
3524
3525 // process sflow datagram
readSFlowDatagram(SFSample * sample,FlowSource_t * fs,int verbose)3526 void readSFlowDatagram(SFSample *sample, FlowSource_t *fs, int verbose) {
3527 uint32_t samplesInPacket, samp;
3528 #ifdef DEVEL
3529 char buf[51];
3530 #endif
3531
3532 /* log some datagram info */
3533 dbg_printf("datagramSourceIP %s\n", IP_to_a(sample->sourceIP.s_addr, buf, 51));
3534 dbg_printf("datagramSize %u\n", sample->rawSampleLen);
3535 dbg_printf("unixSecondsUTC %llu\n", (unsigned long long)sample->readTimestamp);
3536
3537 /* check the version */
3538 sample->datagramVersion = getData32(sample);
3539 dbg_printf("datagramVersion %d\n", sample->datagramVersion);
3540 if(sample->datagramVersion != 2 &&
3541 sample->datagramVersion != 4 &&
3542 sample->datagramVersion != 5) {
3543 receiveError(sample, "unexpected datagram version number\n", YES);
3544 return;
3545 }
3546
3547 /* get the agent address */
3548 getAddress(sample, &sample->agent_addr);
3549
3550 /* version 5 has an agent sub-id as well */
3551 if(sample->datagramVersion >= 5) {
3552 sample->agentSubId = getData32(sample);
3553 dbg_printf("agentSubId %u\n", sample->agentSubId);
3554 }
3555
3556 sample->sequenceNo = getData32(sample); /* this is the packet sequence number */
3557 sample->sysUpTime = getData32(sample);
3558 samplesInPacket = getData32(sample);
3559 dbg_printf("agent %s\n", printAddress(&sample->agent_addr, buf, 50));
3560 dbg_printf("packetSequenceNo %u\n", sample->sequenceNo);
3561 dbg_printf("sysUpTime %u\n", sample->sysUpTime);
3562 dbg_printf("samplesInPacket %u\n", samplesInPacket);
3563
3564 /* now iterate and pull out the flows and counters samples */
3565 for(samp = 0; samp < samplesInPacket; samp++) {
3566 if((uint8_t *)sample->datap >= sample->endp) {
3567 LogError("SFLOW: readSFlowDatagram() unexpected end of datagram after sample %d of %d\n", samp, samplesInPacket);
3568 return;
3569 }
3570 /* just read the tag, then call the approriate decode fn */
3571 sample->elementType = 0;
3572 sample->sampleType = getData32(sample);
3573 dbg_printf("startSample ----------------------\n");
3574 dbg_printf("sampleType_tag %s\n", printTag(sample->sampleType, buf, 50));
3575
3576 // just process sfcapd relevant samples - skip others unless in DEVEL
3577 if(sample->datagramVersion >= 5) {
3578 switch(sample->sampleType) {
3579 case SFLFLOW_SAMPLE:
3580 readFlowSample(sample, NO, fs, verbose);
3581 break;
3582 case SFLFLOW_SAMPLE_EXPANDED:
3583 readFlowSample(sample, YES, fs, verbose);
3584 break;
3585 #ifdef DEVEL
3586 case SFLCOUNTERS_SAMPLE:
3587 readCountersSample(sample, NO, fs, verbose);
3588 break;
3589 case SFLCOUNTERS_SAMPLE_EXPANDED:
3590 readCountersSample(sample, YES, fs, verbose);
3591 break;
3592 case SFLRTMETRIC:
3593 readRTMetric(sample, fs, verbose);
3594 break;
3595 case SFLRTFLOW:
3596 readRTFlow(sample, fs, verbose);
3597 break;
3598 #endif
3599 default:
3600 skipTLVRecord(sample, sample->sampleType, getData32(sample), "sample");
3601 break;
3602 }
3603 } else {
3604 // just process sfcapd relevant samples - skip others unless in DEVEL
3605 switch(sample->sampleType) {
3606 case FLOWSAMPLE:
3607 readFlowSample_v2v4(sample, fs, verbose);
3608 break;
3609 #ifdef DEVEL
3610 case COUNTERSSAMPLE:
3611 readCountersSample_v2v4(sample, fs, verbose);
3612 break;
3613 #endif
3614 default:
3615 skipTLVRecord(sample, sample->sampleType, getData32(sample), "sample");
3616 // receiveError(sample, "unexpected sample type", YES);
3617 return;
3618 break;
3619 }
3620 }
3621 dbg_printf("endSample ----------------------\n");
3622 }
3623 } // End of readSFlowDatagram
3624