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, &reg, 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, &reg, 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