1/* 2 * Copyright (c) 1998-2007 The TCPDUMP project 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that: (1) source code 6 * distributions retain the above copyright notice and this paragraph 7 * in its entirety, and (2) distributions including binary code include 8 * the above copyright notice and this paragraph in its entirety in 9 * the documentation or other materials provided with the distribution. 10 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND 11 * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT 12 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 13 * FOR A PARTICULAR PURPOSE. 14 * 15 * The SFLOW protocol as per http://www.sflow.org/developers/specifications.php 16 * 17 * Original code by Carles Kishimoto <carles.kishimoto@gmail.com> 18 */ 19 20#include <sys/cdefs.h> 21#ifndef lint 22#if 0 23static const char rcsid[] _U_ = 24"@(#) Header: /tcpdump/master/tcpdump/print-sflow.c,v 1.1 2007-08-08 17:20:58 hannes Exp"; 25#else 26__RCSID("$NetBSD$"); 27#endif 28#endif 29 30#ifdef HAVE_CONFIG_H 31#include "config.h" 32#endif 33 34#include <tcpdump-stdinc.h> 35 36#include <stdio.h> 37#include <stdlib.h> 38#include <string.h> 39 40#include "interface.h" 41#include "extract.h" 42#include "addrtoname.h" 43 44/* 45 * sFlow datagram 46 * 47 * 0 1 2 3 48 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 49 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 50 * | Sflow version (2,4,5) | 51 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 52 * | IP version (1 for IPv4 | 2 for IPv6) | 53 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 54 * | IP Address AGENT (4 or 16 bytes) | 55 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 56 * | Sub agent ID | 57 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 58 * | Datagram sequence number | 59 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 60 * | Switch uptime in ms | 61 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 62 * | num samples in datagram | 63 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 64 * 65 */ 66 67struct sflow_datagram_t { 68 u_int8_t version[4]; 69 u_int8_t ip_version[4]; 70 u_int8_t agent[4]; 71 u_int8_t agent_id[4]; 72 u_int8_t seqnum[4]; 73 u_int8_t uptime[4]; 74 u_int8_t samples[4]; 75}; 76 77struct sflow_sample_header { 78 u_int8_t format[4]; 79 u_int8_t len[4]; 80}; 81 82#define SFLOW_FLOW_SAMPLE 1 83#define SFLOW_COUNTER_SAMPLE 2 84#define SFLOW_EXPANDED_FLOW_SAMPLE 3 85#define SFLOW_EXPANDED_COUNTER_SAMPLE 4 86 87static const struct tok sflow_format_values[] = { 88 { SFLOW_FLOW_SAMPLE, "flow sample" }, 89 { SFLOW_COUNTER_SAMPLE, "counter sample" }, 90 { SFLOW_EXPANDED_FLOW_SAMPLE, "expanded flow sample" }, 91 { SFLOW_EXPANDED_COUNTER_SAMPLE, "expanded counter sample" }, 92 { 0, NULL} 93}; 94 95struct sflow_expanded_flow_sample_t { 96 u_int8_t seqnum[4]; 97 u_int8_t type[4]; 98 u_int8_t index[4]; 99 u_int8_t rate[4]; 100 u_int8_t pool[4]; 101 u_int8_t drops[4]; 102 u_int8_t in_interface_format[4]; 103 u_int8_t in_interface_value[4]; 104 u_int8_t out_interface_format[4]; 105 u_int8_t out_interface_value[4]; 106 u_int8_t records[4]; 107}; 108 109#define SFLOW_FLOW_RAW_PACKET 1 110#define SFLOW_FLOW_ETHERNET_FRAME 2 111#define SFLOW_FLOW_IPV4_DATA 3 112#define SFLOW_FLOW_IPV6_DATA 4 113#define SFLOW_FLOW_EXTENDED_SWITCH_DATA 1001 114#define SFLOW_FLOW_EXTENDED_ROUTER_DATA 1002 115#define SFLOW_FLOW_EXTENDED_GATEWAY_DATA 1003 116#define SFLOW_FLOW_EXTENDED_USER_DATA 1004 117#define SFLOW_FLOW_EXTENDED_URL_DATA 1005 118#define SFLOW_FLOW_EXTENDED_MPLS_DATA 1006 119#define SFLOW_FLOW_EXTENDED_NAT_DATA 1007 120#define SFLOW_FLOW_EXTENDED_MPLS_TUNNEL 1008 121#define SFLOW_FLOW_EXTENDED_MPLS_VC 1009 122#define SFLOW_FLOW_EXTENDED_MPLS_FEC 1010 123#define SFLOW_FLOW_EXTENDED_MPLS_LVP_FEC 1011 124#define SFLOW_FLOW_EXTENDED_VLAN_TUNNEL 1012 125 126static const struct tok sflow_flow_type_values[] = { 127 { SFLOW_FLOW_RAW_PACKET, "Raw packet"}, 128 { SFLOW_FLOW_ETHERNET_FRAME, "Ethernet frame"}, 129 { SFLOW_FLOW_IPV4_DATA, "IPv4 Data"}, 130 { SFLOW_FLOW_IPV6_DATA, "IPv6 Data"}, 131 { SFLOW_FLOW_EXTENDED_SWITCH_DATA, "Extended Switch data"}, 132 { SFLOW_FLOW_EXTENDED_ROUTER_DATA, "Extended Router data"}, 133 { SFLOW_FLOW_EXTENDED_GATEWAY_DATA, "Extended Gateway data"}, 134 { SFLOW_FLOW_EXTENDED_USER_DATA, "Extended User data"}, 135 { SFLOW_FLOW_EXTENDED_URL_DATA, "Extended URL data"}, 136 { SFLOW_FLOW_EXTENDED_MPLS_DATA, "Extended MPLS data"}, 137 { SFLOW_FLOW_EXTENDED_NAT_DATA, "Extended NAT data"}, 138 { SFLOW_FLOW_EXTENDED_MPLS_TUNNEL, "Extended MPLS tunnel"}, 139 { SFLOW_FLOW_EXTENDED_MPLS_VC, "Extended MPLS VC"}, 140 { SFLOW_FLOW_EXTENDED_MPLS_FEC, "Extended MPLS FEC"}, 141 { SFLOW_FLOW_EXTENDED_MPLS_LVP_FEC, "Extended MPLS LVP FEC"}, 142 { SFLOW_FLOW_EXTENDED_VLAN_TUNNEL, "Extended VLAN Tunnel"}, 143 { 0, NULL} 144}; 145 146#define SFLOW_HEADER_PROTOCOL_ETHERNET 1 147#define SFLOW_HEADER_PROTOCOL_IPV4 11 148#define SFLOW_HEADER_PROTOCOL_IPV6 12 149 150static const struct tok sflow_flow_raw_protocol_values[] = { 151 { SFLOW_HEADER_PROTOCOL_ETHERNET, "Ethernet"}, 152 { SFLOW_HEADER_PROTOCOL_IPV4, "IPv4"}, 153 { SFLOW_HEADER_PROTOCOL_IPV6, "IPv6"}, 154 { 0, NULL} 155}; 156 157struct sflow_expanded_flow_raw_t { 158 u_int8_t protocol[4]; 159 u_int8_t length[4]; 160 u_int8_t stripped_bytes[4]; 161 u_int8_t header_size[4]; 162}; 163 164struct sflow_expanded_counter_sample_t { 165 u_int8_t seqnum[4]; 166 u_int8_t type[4]; 167 u_int8_t index[4]; 168 u_int8_t records[4]; 169}; 170 171#define SFLOW_COUNTER_GENERIC 1 172#define SFLOW_COUNTER_ETHERNET 2 173#define SFLOW_COUNTER_TOKEN_RING 3 174#define SFLOW_COUNTER_BASEVG 4 175#define SFLOW_COUNTER_VLAN 5 176#define SFLOW_COUNTER_PROCESSOR 1001 177 178static const struct tok sflow_counter_type_values[] = { 179 { SFLOW_COUNTER_GENERIC, "Generic counter"}, 180 { SFLOW_COUNTER_ETHERNET, "Ethernet counter"}, 181 { SFLOW_COUNTER_TOKEN_RING, "Token ring counter"}, 182 { SFLOW_COUNTER_BASEVG, "100 BaseVG counter"}, 183 { SFLOW_COUNTER_VLAN, "Vlan counter"}, 184 { SFLOW_COUNTER_PROCESSOR, "Processor counter"}, 185 { 0, NULL} 186}; 187 188#define SFLOW_IFACE_DIRECTION_UNKNOWN 0 189#define SFLOW_IFACE_DIRECTION_FULLDUPLEX 1 190#define SFLOW_IFACE_DIRECTION_HALFDUPLEX 2 191#define SFLOW_IFACE_DIRECTION_IN 3 192#define SFLOW_IFACE_DIRECTION_OUT 4 193 194static const struct tok sflow_iface_direction_values[] = { 195 { SFLOW_IFACE_DIRECTION_UNKNOWN, "unknown"}, 196 { SFLOW_IFACE_DIRECTION_FULLDUPLEX, "full-duplex"}, 197 { SFLOW_IFACE_DIRECTION_HALFDUPLEX, "half-duplex"}, 198 { SFLOW_IFACE_DIRECTION_IN, "in"}, 199 { SFLOW_IFACE_DIRECTION_OUT, "out"}, 200 { 0, NULL} 201}; 202 203struct sflow_generic_counter_t { 204 u_int8_t ifindex[4]; 205 u_int8_t iftype[4]; 206 u_int8_t ifspeed[8]; 207 u_int8_t ifdirection[4]; 208 u_int8_t ifstatus[4]; 209 u_int8_t ifinoctets[8]; 210 u_int8_t ifinunicastpkts[4]; 211 u_int8_t ifinmulticastpkts[4]; 212 u_int8_t ifinbroadcastpkts[4]; 213 u_int8_t ifindiscards[4]; 214 u_int8_t ifinerrors[4]; 215 u_int8_t ifinunkownprotos[4]; 216 u_int8_t ifoutoctets[8]; 217 u_int8_t ifoutunicastpkts[4]; 218 u_int8_t ifoutmulticastpkts[4]; 219 u_int8_t ifoutbroadcastpkts[4]; 220 u_int8_t ifoutdiscards[4]; 221 u_int8_t ifouterrors[4]; 222 u_int8_t ifpromiscmode[4]; 223}; 224 225struct sflow_ethernet_counter_t { 226 u_int8_t alignerrors[4]; 227 u_int8_t fcserrors[4]; 228 u_int8_t single_collision_frames[4]; 229 u_int8_t multiple_collision_frames[4]; 230 u_int8_t test_errors[4]; 231 u_int8_t deferred_transmissions[4]; 232 u_int8_t late_collisions[4]; 233 u_int8_t excessive_collisions[4]; 234 u_int8_t mac_transmit_errors[4]; 235 u_int8_t carrier_sense_errors[4]; 236 u_int8_t frame_too_longs[4]; 237 u_int8_t mac_receive_errors[4]; 238 u_int8_t symbol_errors[4]; 239}; 240 241struct sflow_100basevg_counter_t { 242 u_int8_t in_highpriority_frames[4]; 243 u_int8_t in_highpriority_octets[8]; 244 u_int8_t in_normpriority_frames[4]; 245 u_int8_t in_normpriority_octets[8]; 246 u_int8_t in_ipmerrors[4]; 247 u_int8_t in_oversized[4]; 248 u_int8_t in_data_errors[4]; 249 u_int8_t in_null_addressed_frames[4]; 250 u_int8_t out_highpriority_frames[4]; 251 u_int8_t out_highpriority_octets[8]; 252 u_int8_t transitioninto_frames[4]; 253 u_int8_t hc_in_highpriority_octets[8]; 254 u_int8_t hc_in_normpriority_octets[8]; 255 u_int8_t hc_out_highpriority_octets[8]; 256}; 257 258struct sflow_vlan_counter_t { 259 u_int8_t vlan_id[4]; 260 u_int8_t octets[8]; 261 u_int8_t unicast_pkt[4]; 262 u_int8_t multicast_pkt[4]; 263 u_int8_t broadcast_pkt[4]; 264 u_int8_t discards[4]; 265}; 266 267void 268sflow_print(const u_char *pptr, u_int len) { 269 270 const struct sflow_datagram_t *sflow_datagram; 271 const struct sflow_sample_header *sflow_sample; 272 const struct sflow_expanded_flow_sample_t *sflow_expanded_flow_sample; 273 const struct sflow_expanded_flow_raw_t *sflow_flow_raw; 274 const struct sflow_expanded_counter_sample_t *sflow_expanded_counter_sample; 275 const struct sflow_generic_counter_t *sflow_gen_counter; 276 const struct sflow_ethernet_counter_t *sflow_eth_counter; 277 const struct sflow_100basevg_counter_t *sflow_100basevg_counter; 278 const struct sflow_vlan_counter_t *sflow_vlan_counter; 279 const u_char *tptr; 280 int tlen; 281 u_int32_t sflow_sample_type, sflow_sample_len; 282 int nsamples, nrecords, counter_len, counter_type, flow_len, flow_type; 283 284 tptr=pptr; 285 tlen = len; 286 sflow_datagram = (const struct sflow_datagram_t *)pptr; 287 TCHECK(*sflow_datagram); 288 289 /* 290 * Sanity checking of the header. 291 */ 292 if (EXTRACT_32BITS(sflow_datagram->version) != 5) { 293 printf("sFlow version %u packet not supported", 294 EXTRACT_32BITS(sflow_datagram->version)); 295 return; 296 } 297 298 if (vflag < 1) { 299 printf("sFlowv%u, %s agent %s, agent-id %u, length %u", 300 EXTRACT_32BITS(sflow_datagram->version), 301 EXTRACT_32BITS(sflow_datagram->ip_version) == 1 ? "IPv4" : "IPv6", 302 ipaddr_string(sflow_datagram->agent), 303 EXTRACT_32BITS(sflow_datagram->samples), 304 len); 305 return; 306 } 307 308 /* ok they seem to want to know everything - lets fully decode it */ 309 nsamples=EXTRACT_32BITS(sflow_datagram->samples); 310 printf("sFlowv%u, %s agent %s, agent-id %u, seqnum %u, uptime %u, samples %u, length %u", 311 EXTRACT_32BITS(sflow_datagram->version), 312 EXTRACT_32BITS(sflow_datagram->ip_version) == 1 ? "IPv4" : "IPv6", 313 ipaddr_string(sflow_datagram->agent), 314 EXTRACT_32BITS(sflow_datagram->agent_id), 315 EXTRACT_32BITS(sflow_datagram->seqnum), 316 EXTRACT_32BITS(sflow_datagram->uptime), 317 nsamples, 318 len); 319 320 /* skip Common header */ 321 tptr+=sizeof(const struct sflow_datagram_t); 322 tlen-=sizeof(const struct sflow_datagram_t); 323 324 while (nsamples > 0 && tlen > 0) { 325 sflow_sample = (const struct sflow_sample_header *)tptr; 326 sflow_sample_type = (EXTRACT_32BITS(sflow_sample->format)&0x0FFF); 327 sflow_sample_len = EXTRACT_32BITS(sflow_sample->len); 328 329 tptr+=sizeof(struct sflow_sample_header); 330 tlen-=sizeof(struct sflow_sample_header); 331 332 printf("\n\t%s (%u), length %u,", 333 tok2str(sflow_format_values, "Unknown", sflow_sample_type), 334 sflow_sample_type, 335 sflow_sample_len); 336 337 /* basic sanity check */ 338 if (sflow_sample_type == 0 || sflow_sample_len ==0) { 339 return; 340 } 341 342 /* did we capture enough for fully decoding the sample ? */ 343 if (!TTEST2(*tptr, sflow_sample_len)) 344 goto trunc; 345 346 switch(sflow_sample_type) { 347 case SFLOW_FLOW_SAMPLE: /* XXX */ 348 break; 349 350 case SFLOW_COUNTER_SAMPLE: /* XXX */ 351 break; 352 353 case SFLOW_EXPANDED_FLOW_SAMPLE: 354 sflow_expanded_flow_sample = (const struct sflow_expanded_flow_sample_t *)tptr; 355 nrecords = EXTRACT_32BITS(sflow_expanded_flow_sample->records); 356 357 printf(" seqnum %u, type %u, idx %u, rate %u, pool %u, drops %u, records %u", 358 EXTRACT_32BITS(sflow_expanded_flow_sample->seqnum), 359 EXTRACT_32BITS(sflow_expanded_flow_sample->type), 360 EXTRACT_32BITS(sflow_expanded_flow_sample->index), 361 EXTRACT_32BITS(sflow_expanded_flow_sample->rate), 362 EXTRACT_32BITS(sflow_expanded_flow_sample->pool), 363 EXTRACT_32BITS(sflow_expanded_flow_sample->drops), 364 EXTRACT_32BITS(sflow_expanded_flow_sample->records)); 365 366 tptr+= sizeof(struct sflow_expanded_flow_sample_t); 367 tlen-= sizeof(struct sflow_expanded_flow_sample_t); 368 369 while ( nrecords > 0 && tlen > 0) { 370 371 /* decode Flow record - 2 bytes */ 372 flow_type = EXTRACT_32BITS(tptr)&0x0FFF; 373 flow_len = EXTRACT_32BITS(tptr+4); 374 printf("\n\t %s (%u) length %u", 375 tok2str(sflow_flow_type_values,"Unknown",flow_type), 376 flow_type, 377 flow_len); 378 379 tptr += 8; 380 tlen -= 8; 381 382 /* did we capture enough for fully decoding the flow ? */ 383 if (!TTEST2(*tptr, flow_len)) 384 goto trunc; 385 386 switch(flow_type) { 387 case SFLOW_FLOW_RAW_PACKET: 388 sflow_flow_raw = (const struct sflow_expanded_flow_raw_t *)tptr; 389 printf("\n\t protocol %s (%u), length %u, stripped bytes %u, header_size %u", 390 tok2str(sflow_flow_raw_protocol_values,"Unknown",EXTRACT_32BITS(sflow_flow_raw->protocol)), 391 EXTRACT_32BITS(sflow_flow_raw->protocol), 392 EXTRACT_32BITS(sflow_flow_raw->length), 393 EXTRACT_32BITS(sflow_flow_raw->stripped_bytes), 394 EXTRACT_32BITS(sflow_flow_raw->header_size)); 395 break; 396 397 /* 398 * FIXME those are the defined flow types that lack a decoder 399 */ 400 case SFLOW_FLOW_ETHERNET_FRAME: 401 case SFLOW_FLOW_IPV4_DATA: 402 case SFLOW_FLOW_IPV6_DATA: 403 case SFLOW_FLOW_EXTENDED_SWITCH_DATA: 404 case SFLOW_FLOW_EXTENDED_ROUTER_DATA: 405 case SFLOW_FLOW_EXTENDED_GATEWAY_DATA: 406 case SFLOW_FLOW_EXTENDED_USER_DATA: 407 case SFLOW_FLOW_EXTENDED_URL_DATA: 408 case SFLOW_FLOW_EXTENDED_MPLS_DATA: 409 case SFLOW_FLOW_EXTENDED_NAT_DATA: 410 case SFLOW_FLOW_EXTENDED_MPLS_TUNNEL: 411 case SFLOW_FLOW_EXTENDED_MPLS_VC: 412 case SFLOW_FLOW_EXTENDED_MPLS_FEC: 413 case SFLOW_FLOW_EXTENDED_MPLS_LVP_FEC: 414 case SFLOW_FLOW_EXTENDED_VLAN_TUNNEL: 415 break; 416 default: 417 if (vflag <= 1) 418 print_unknown_data(tptr, "\n\t ", flow_len); 419 break; 420 421 } 422 tptr += flow_len; 423 tlen -= flow_len; 424 nrecords--; 425 } 426 break; 427 428 case SFLOW_EXPANDED_COUNTER_SAMPLE: 429 sflow_expanded_counter_sample = (const struct sflow_expanded_counter_sample_t *)tptr; 430 nrecords = EXTRACT_32BITS(sflow_expanded_counter_sample->records); 431 432 printf(" seqnum %u, type %u, idx %u, records %u", 433 EXTRACT_32BITS(sflow_expanded_counter_sample->seqnum), 434 EXTRACT_32BITS(sflow_expanded_counter_sample->type), 435 EXTRACT_32BITS(sflow_expanded_counter_sample->index), 436 nrecords); 437 438 tptr+= sizeof(struct sflow_expanded_counter_sample_t); 439 tlen-= sizeof(struct sflow_expanded_counter_sample_t); 440 441 while ( nrecords > 0 && tlen > 0) { 442 443 /* decode counter record - 2 bytes */ 444 counter_type = EXTRACT_32BITS(tptr)&0x0FFF; 445 counter_len = EXTRACT_32BITS(tptr+4); 446 printf("\n\t %s (%u) length %u", 447 tok2str(sflow_counter_type_values,"Unknown",counter_type), 448 counter_type, 449 counter_len); 450 451 tptr += 8; 452 tlen -= 8; 453 454 /* did we capture enough for fully decoding the counter ? */ 455 if (!TTEST2(*tptr, counter_len)) 456 goto trunc; 457 458 switch(counter_type) { 459 case SFLOW_COUNTER_GENERIC: 460 sflow_gen_counter = (const struct sflow_generic_counter_t *)tptr; 461 printf("\n\t ifindex %u, iftype %u, ifspeed %u, ifdirection %u (%s)", 462 EXTRACT_32BITS(sflow_gen_counter->ifindex), 463 EXTRACT_32BITS(sflow_gen_counter->iftype), 464 EXTRACT_32BITS(sflow_gen_counter->ifspeed), 465 EXTRACT_32BITS(sflow_gen_counter->ifdirection), 466 tok2str(sflow_iface_direction_values, "Unknown", 467 EXTRACT_32BITS(sflow_gen_counter->ifdirection))); 468 printf("\n\t ifstatus %u, adminstatus: %s, operstatus: %s", 469 EXTRACT_32BITS(sflow_gen_counter->ifstatus), 470 EXTRACT_32BITS(sflow_gen_counter->ifstatus)&1 ? "up" : "down", 471 (EXTRACT_32BITS(sflow_gen_counter->ifstatus)>>1)&1 ? "up" : "down"); 472 printf("\n\t In octets %" PRIu64 473 ", unicast pkts %u, multicast pkts %u, broadcast pkts %u, discards %u", 474 EXTRACT_64BITS(sflow_gen_counter->ifinoctets), 475 EXTRACT_32BITS(sflow_gen_counter->ifinunicastpkts), 476 EXTRACT_32BITS(sflow_gen_counter->ifinmulticastpkts), 477 EXTRACT_32BITS(sflow_gen_counter->ifinbroadcastpkts), 478 EXTRACT_32BITS(sflow_gen_counter->ifindiscards)); 479 printf("\n\t In errors %u, unknown protos %u", 480 EXTRACT_32BITS(sflow_gen_counter->ifinerrors), 481 EXTRACT_32BITS(sflow_gen_counter->ifinunkownprotos)); 482 printf("\n\t Out octets %" PRIu64 483 ", unicast pkts %u, multicast pkts %u, broadcast pkts %u, discards %u", 484 EXTRACT_64BITS(sflow_gen_counter->ifoutoctets), 485 EXTRACT_32BITS(sflow_gen_counter->ifoutunicastpkts), 486 EXTRACT_32BITS(sflow_gen_counter->ifoutmulticastpkts), 487 EXTRACT_32BITS(sflow_gen_counter->ifoutbroadcastpkts), 488 EXTRACT_32BITS(sflow_gen_counter->ifoutdiscards)); 489 printf("\n\t Out errors %u, promisc mode %u", 490 EXTRACT_32BITS(sflow_gen_counter->ifouterrors), 491 EXTRACT_32BITS(sflow_gen_counter->ifpromiscmode)); 492 break; 493 case SFLOW_COUNTER_ETHERNET: 494 sflow_eth_counter = (const struct sflow_ethernet_counter_t *)tptr; 495 printf("\n\t align errors %u, fcs errors %u, single collision %u, multiple collision %u, test error %u", 496 EXTRACT_32BITS(sflow_eth_counter->alignerrors), 497 EXTRACT_32BITS(sflow_eth_counter->fcserrors), 498 EXTRACT_32BITS(sflow_eth_counter->single_collision_frames), 499 EXTRACT_32BITS(sflow_eth_counter->multiple_collision_frames), 500 EXTRACT_32BITS(sflow_eth_counter->test_errors)); 501 printf("\n\t deferred %u, late collision %u, excessive collision %u, mac trans error %u", 502 EXTRACT_32BITS(sflow_eth_counter->deferred_transmissions), 503 EXTRACT_32BITS(sflow_eth_counter->late_collisions), 504 EXTRACT_32BITS(sflow_eth_counter->excessive_collisions), 505 EXTRACT_32BITS(sflow_eth_counter->mac_transmit_errors)); 506 printf("\n\t carrier error %u, frames too long %u, mac receive errors %u, symbol errors %u", 507 EXTRACT_32BITS(sflow_eth_counter->carrier_sense_errors), 508 EXTRACT_32BITS(sflow_eth_counter->frame_too_longs), 509 EXTRACT_32BITS(sflow_eth_counter->mac_receive_errors), 510 EXTRACT_32BITS(sflow_eth_counter->symbol_errors)); 511 break; 512 case SFLOW_COUNTER_TOKEN_RING: /* XXX */ 513 break; 514 case SFLOW_COUNTER_BASEVG: 515 sflow_100basevg_counter = (const struct sflow_100basevg_counter_t *)tptr; 516 printf("\n\t in high prio frames %u, in high prio octets %" PRIu64, 517 EXTRACT_32BITS(sflow_100basevg_counter->in_highpriority_frames), 518 EXTRACT_64BITS(sflow_100basevg_counter->in_highpriority_octets)); 519 printf("\n\t in norm prio frames %u, in norm prio octets %" PRIu64, 520 EXTRACT_32BITS(sflow_100basevg_counter->in_normpriority_frames), 521 EXTRACT_64BITS(sflow_100basevg_counter->in_normpriority_octets)); 522 printf("\n\t in ipm errors %u, oversized %u, in data errors %u, null addressed frames %u", 523 EXTRACT_32BITS(sflow_100basevg_counter->in_ipmerrors), 524 EXTRACT_32BITS(sflow_100basevg_counter->in_oversized), 525 EXTRACT_32BITS(sflow_100basevg_counter->in_data_errors), 526 EXTRACT_32BITS(sflow_100basevg_counter->in_null_addressed_frames)); 527 printf("\n\t out high prio frames %u, out high prio octets %" PRIu64 528 ", trans into frames %u", 529 EXTRACT_32BITS(sflow_100basevg_counter->out_highpriority_frames), 530 EXTRACT_64BITS(sflow_100basevg_counter->out_highpriority_octets), 531 EXTRACT_32BITS(sflow_100basevg_counter->transitioninto_frames)); 532 printf("\n\t in hc high prio octets %" PRIu64 533 ", in hc norm prio octets %" PRIu64 534 ", out hc high prio octets %" PRIu64, 535 EXTRACT_64BITS(sflow_100basevg_counter->hc_in_highpriority_octets), 536 EXTRACT_64BITS(sflow_100basevg_counter->hc_in_normpriority_octets), 537 EXTRACT_64BITS(sflow_100basevg_counter->hc_out_highpriority_octets)); 538 break; 539 case SFLOW_COUNTER_VLAN: 540 sflow_vlan_counter = (const struct sflow_vlan_counter_t *)tptr; 541 printf("\n\t vlan_id %u, octets %" PRIu64 542 ", unicast_pkt %u, multicast_pkt %u, broadcast_pkt %u, discards %u", 543 EXTRACT_32BITS(sflow_vlan_counter->vlan_id), 544 EXTRACT_64BITS(sflow_vlan_counter->octets), 545 EXTRACT_32BITS(sflow_vlan_counter->unicast_pkt), 546 EXTRACT_32BITS(sflow_vlan_counter->multicast_pkt), 547 EXTRACT_32BITS(sflow_vlan_counter->broadcast_pkt), 548 EXTRACT_32BITS(sflow_vlan_counter->discards)); 549 break; 550 case SFLOW_COUNTER_PROCESSOR: /* XXX */ 551 break; 552 default: 553 if (vflag <= 1) 554 print_unknown_data(tptr, "\n\t\t", counter_len); 555 break; 556 } 557 tptr += counter_len; 558 tlen -= counter_len; 559 nrecords--; 560 } 561 break; 562 default: 563 if (vflag <= 1) 564 print_unknown_data(tptr, "\n\t ", sflow_sample_len); 565 break; 566 } 567 tptr += sflow_sample_len; 568 tlen -= sflow_sample_len; 569 nsamples--; 570 } 571 return; 572 573 trunc: 574 printf("[|SFLOW]"); 575} 576 577/* 578 * Local Variables: 579 * c-style: whitesmith 580 * c-basic-offset: 4 581 * End: 582 */ 583