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