1ea7b4bf5SPeter Avalos /*
2ea7b4bf5SPeter Avalos * Copyright (c) 1998-2007 The TCPDUMP project
3ea7b4bf5SPeter Avalos *
4ea7b4bf5SPeter Avalos * Redistribution and use in source and binary forms, with or without
5ea7b4bf5SPeter Avalos * modification, are permitted provided that: (1) source code
6ea7b4bf5SPeter Avalos * distributions retain the above copyright notice and this paragraph
7ea7b4bf5SPeter Avalos * in its entirety, and (2) distributions including binary code include
8ea7b4bf5SPeter Avalos * the above copyright notice and this paragraph in its entirety in
9ea7b4bf5SPeter Avalos * the documentation or other materials provided with the distribution.
10ea7b4bf5SPeter Avalos * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
11ea7b4bf5SPeter Avalos * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
12ea7b4bf5SPeter Avalos * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
13ea7b4bf5SPeter Avalos * FOR A PARTICULAR PURPOSE.
14ea7b4bf5SPeter Avalos *
15ea7b4bf5SPeter Avalos * Original code by Carles Kishimoto <carles.kishimoto@gmail.com>
1627bfbee1SPeter Avalos *
1727bfbee1SPeter Avalos * Expansion and refactoring by Rick Jones <rick.jones2@hp.com>
18ea7b4bf5SPeter Avalos */
19ea7b4bf5SPeter Avalos
20411677aeSAaron LI /* \summary: sFlow protocol printer */
21411677aeSAaron LI
22*ed775ee7SAntonio Huete Jimenez /* specification: https://sflow.org/developers/specifications.php */
23ea7b4bf5SPeter Avalos
24ea7b4bf5SPeter Avalos #ifdef HAVE_CONFIG_H
25*ed775ee7SAntonio Huete Jimenez #include <config.h>
26ea7b4bf5SPeter Avalos #endif
27ea7b4bf5SPeter Avalos
28*ed775ee7SAntonio Huete Jimenez #include "netdissect-stdinc.h"
29ea7b4bf5SPeter Avalos
30*ed775ee7SAntonio Huete Jimenez #define ND_LONGJMP_FROM_TCHECK
31411677aeSAaron LI #include "netdissect.h"
32ea7b4bf5SPeter Avalos #include "extract.h"
33ea7b4bf5SPeter Avalos #include "addrtoname.h"
34ea7b4bf5SPeter Avalos
35ea7b4bf5SPeter Avalos /*
36ea7b4bf5SPeter Avalos * sFlow datagram
37ea7b4bf5SPeter Avalos *
38ea7b4bf5SPeter Avalos * 0 1 2 3
39ea7b4bf5SPeter Avalos * 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
40ea7b4bf5SPeter Avalos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41ea7b4bf5SPeter Avalos * | Sflow version (2,4,5) |
42ea7b4bf5SPeter Avalos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43ea7b4bf5SPeter Avalos * | IP version (1 for IPv4 | 2 for IPv6) |
44ea7b4bf5SPeter Avalos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45ea7b4bf5SPeter Avalos * | IP Address AGENT (4 or 16 bytes) |
46ea7b4bf5SPeter Avalos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47ea7b4bf5SPeter Avalos * | Sub agent ID |
48ea7b4bf5SPeter Avalos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49ea7b4bf5SPeter Avalos * | Datagram sequence number |
50ea7b4bf5SPeter Avalos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
51ea7b4bf5SPeter Avalos * | Switch uptime in ms |
52ea7b4bf5SPeter Avalos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53ea7b4bf5SPeter Avalos * | num samples in datagram |
54ea7b4bf5SPeter Avalos * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55ea7b4bf5SPeter Avalos *
56ea7b4bf5SPeter Avalos */
57ea7b4bf5SPeter Avalos
58ea7b4bf5SPeter Avalos struct sflow_datagram_t {
59*ed775ee7SAntonio Huete Jimenez nd_uint32_t version;
60*ed775ee7SAntonio Huete Jimenez nd_uint32_t ip_version;
61*ed775ee7SAntonio Huete Jimenez nd_ipv4 agent;
62*ed775ee7SAntonio Huete Jimenez nd_uint32_t agent_id;
63*ed775ee7SAntonio Huete Jimenez nd_uint32_t seqnum;
64*ed775ee7SAntonio Huete Jimenez nd_uint32_t uptime;
65*ed775ee7SAntonio Huete Jimenez nd_uint32_t samples;
66ea7b4bf5SPeter Avalos };
67ea7b4bf5SPeter Avalos
68ea7b4bf5SPeter Avalos struct sflow_sample_header {
69*ed775ee7SAntonio Huete Jimenez nd_uint32_t format;
70*ed775ee7SAntonio Huete Jimenez nd_uint32_t len;
71ea7b4bf5SPeter Avalos };
72ea7b4bf5SPeter Avalos
73ea7b4bf5SPeter Avalos #define SFLOW_FLOW_SAMPLE 1
74ea7b4bf5SPeter Avalos #define SFLOW_COUNTER_SAMPLE 2
75ea7b4bf5SPeter Avalos #define SFLOW_EXPANDED_FLOW_SAMPLE 3
76ea7b4bf5SPeter Avalos #define SFLOW_EXPANDED_COUNTER_SAMPLE 4
77ea7b4bf5SPeter Avalos
78ea7b4bf5SPeter Avalos static const struct tok sflow_format_values[] = {
79ea7b4bf5SPeter Avalos { SFLOW_FLOW_SAMPLE, "flow sample" },
80ea7b4bf5SPeter Avalos { SFLOW_COUNTER_SAMPLE, "counter sample" },
81ea7b4bf5SPeter Avalos { SFLOW_EXPANDED_FLOW_SAMPLE, "expanded flow sample" },
82ea7b4bf5SPeter Avalos { SFLOW_EXPANDED_COUNTER_SAMPLE, "expanded counter sample" },
83ea7b4bf5SPeter Avalos { 0, NULL}
84ea7b4bf5SPeter Avalos };
85ea7b4bf5SPeter Avalos
8627bfbee1SPeter Avalos struct sflow_flow_sample_t {
87*ed775ee7SAntonio Huete Jimenez nd_uint32_t seqnum;
88*ed775ee7SAntonio Huete Jimenez nd_uint8_t type;
89*ed775ee7SAntonio Huete Jimenez nd_uint24_t index;
90*ed775ee7SAntonio Huete Jimenez nd_uint32_t rate;
91*ed775ee7SAntonio Huete Jimenez nd_uint32_t pool;
92*ed775ee7SAntonio Huete Jimenez nd_uint32_t drops;
93*ed775ee7SAntonio Huete Jimenez nd_uint32_t in_interface;
94*ed775ee7SAntonio Huete Jimenez nd_uint32_t out_interface;
95*ed775ee7SAntonio Huete Jimenez nd_uint32_t records;
9627bfbee1SPeter Avalos
9727bfbee1SPeter Avalos };
9827bfbee1SPeter Avalos
99ea7b4bf5SPeter Avalos struct sflow_expanded_flow_sample_t {
100*ed775ee7SAntonio Huete Jimenez nd_uint32_t seqnum;
101*ed775ee7SAntonio Huete Jimenez nd_uint32_t type;
102*ed775ee7SAntonio Huete Jimenez nd_uint32_t index;
103*ed775ee7SAntonio Huete Jimenez nd_uint32_t rate;
104*ed775ee7SAntonio Huete Jimenez nd_uint32_t pool;
105*ed775ee7SAntonio Huete Jimenez nd_uint32_t drops;
106*ed775ee7SAntonio Huete Jimenez nd_uint32_t in_interface_format;
107*ed775ee7SAntonio Huete Jimenez nd_uint32_t in_interface_value;
108*ed775ee7SAntonio Huete Jimenez nd_uint32_t out_interface_format;
109*ed775ee7SAntonio Huete Jimenez nd_uint32_t out_interface_value;
110*ed775ee7SAntonio Huete Jimenez nd_uint32_t records;
111ea7b4bf5SPeter Avalos };
112ea7b4bf5SPeter Avalos
113ea7b4bf5SPeter Avalos #define SFLOW_FLOW_RAW_PACKET 1
114ea7b4bf5SPeter Avalos #define SFLOW_FLOW_ETHERNET_FRAME 2
115ea7b4bf5SPeter Avalos #define SFLOW_FLOW_IPV4_DATA 3
116ea7b4bf5SPeter Avalos #define SFLOW_FLOW_IPV6_DATA 4
117ea7b4bf5SPeter Avalos #define SFLOW_FLOW_EXTENDED_SWITCH_DATA 1001
118ea7b4bf5SPeter Avalos #define SFLOW_FLOW_EXTENDED_ROUTER_DATA 1002
119ea7b4bf5SPeter Avalos #define SFLOW_FLOW_EXTENDED_GATEWAY_DATA 1003
120ea7b4bf5SPeter Avalos #define SFLOW_FLOW_EXTENDED_USER_DATA 1004
121ea7b4bf5SPeter Avalos #define SFLOW_FLOW_EXTENDED_URL_DATA 1005
122ea7b4bf5SPeter Avalos #define SFLOW_FLOW_EXTENDED_MPLS_DATA 1006
123ea7b4bf5SPeter Avalos #define SFLOW_FLOW_EXTENDED_NAT_DATA 1007
124ea7b4bf5SPeter Avalos #define SFLOW_FLOW_EXTENDED_MPLS_TUNNEL 1008
125ea7b4bf5SPeter Avalos #define SFLOW_FLOW_EXTENDED_MPLS_VC 1009
126ea7b4bf5SPeter Avalos #define SFLOW_FLOW_EXTENDED_MPLS_FEC 1010
127ea7b4bf5SPeter Avalos #define SFLOW_FLOW_EXTENDED_MPLS_LVP_FEC 1011
128ea7b4bf5SPeter Avalos #define SFLOW_FLOW_EXTENDED_VLAN_TUNNEL 1012
129ea7b4bf5SPeter Avalos
130ea7b4bf5SPeter Avalos static const struct tok sflow_flow_type_values[] = {
131ea7b4bf5SPeter Avalos { SFLOW_FLOW_RAW_PACKET, "Raw packet"},
132ea7b4bf5SPeter Avalos { SFLOW_FLOW_ETHERNET_FRAME, "Ethernet frame"},
133ea7b4bf5SPeter Avalos { SFLOW_FLOW_IPV4_DATA, "IPv4 Data"},
134ea7b4bf5SPeter Avalos { SFLOW_FLOW_IPV6_DATA, "IPv6 Data"},
135ea7b4bf5SPeter Avalos { SFLOW_FLOW_EXTENDED_SWITCH_DATA, "Extended Switch data"},
136ea7b4bf5SPeter Avalos { SFLOW_FLOW_EXTENDED_ROUTER_DATA, "Extended Router data"},
137ea7b4bf5SPeter Avalos { SFLOW_FLOW_EXTENDED_GATEWAY_DATA, "Extended Gateway data"},
138ea7b4bf5SPeter Avalos { SFLOW_FLOW_EXTENDED_USER_DATA, "Extended User data"},
139ea7b4bf5SPeter Avalos { SFLOW_FLOW_EXTENDED_URL_DATA, "Extended URL data"},
140ea7b4bf5SPeter Avalos { SFLOW_FLOW_EXTENDED_MPLS_DATA, "Extended MPLS data"},
141ea7b4bf5SPeter Avalos { SFLOW_FLOW_EXTENDED_NAT_DATA, "Extended NAT data"},
142ea7b4bf5SPeter Avalos { SFLOW_FLOW_EXTENDED_MPLS_TUNNEL, "Extended MPLS tunnel"},
143ea7b4bf5SPeter Avalos { SFLOW_FLOW_EXTENDED_MPLS_VC, "Extended MPLS VC"},
144ea7b4bf5SPeter Avalos { SFLOW_FLOW_EXTENDED_MPLS_FEC, "Extended MPLS FEC"},
145ea7b4bf5SPeter Avalos { SFLOW_FLOW_EXTENDED_MPLS_LVP_FEC, "Extended MPLS LVP FEC"},
146ea7b4bf5SPeter Avalos { SFLOW_FLOW_EXTENDED_VLAN_TUNNEL, "Extended VLAN Tunnel"},
147ea7b4bf5SPeter Avalos { 0, NULL}
148ea7b4bf5SPeter Avalos };
149ea7b4bf5SPeter Avalos
150ea7b4bf5SPeter Avalos #define SFLOW_HEADER_PROTOCOL_ETHERNET 1
151ea7b4bf5SPeter Avalos #define SFLOW_HEADER_PROTOCOL_IPV4 11
152ea7b4bf5SPeter Avalos #define SFLOW_HEADER_PROTOCOL_IPV6 12
153ea7b4bf5SPeter Avalos
154ea7b4bf5SPeter Avalos static const struct tok sflow_flow_raw_protocol_values[] = {
155ea7b4bf5SPeter Avalos { SFLOW_HEADER_PROTOCOL_ETHERNET, "Ethernet"},
156ea7b4bf5SPeter Avalos { SFLOW_HEADER_PROTOCOL_IPV4, "IPv4"},
157ea7b4bf5SPeter Avalos { SFLOW_HEADER_PROTOCOL_IPV6, "IPv6"},
158ea7b4bf5SPeter Avalos { 0, NULL}
159ea7b4bf5SPeter Avalos };
160ea7b4bf5SPeter Avalos
161ea7b4bf5SPeter Avalos struct sflow_expanded_flow_raw_t {
162*ed775ee7SAntonio Huete Jimenez nd_uint32_t protocol;
163*ed775ee7SAntonio Huete Jimenez nd_uint32_t length;
164*ed775ee7SAntonio Huete Jimenez nd_uint32_t stripped_bytes;
165*ed775ee7SAntonio Huete Jimenez nd_uint32_t header_size;
166ea7b4bf5SPeter Avalos };
167ea7b4bf5SPeter Avalos
16827bfbee1SPeter Avalos struct sflow_ethernet_frame_t {
169*ed775ee7SAntonio Huete Jimenez nd_uint32_t length;
170*ed775ee7SAntonio Huete Jimenez nd_byte src_mac[8];
171*ed775ee7SAntonio Huete Jimenez nd_byte dst_mac[8];
172*ed775ee7SAntonio Huete Jimenez nd_uint32_t type;
17327bfbee1SPeter Avalos };
17427bfbee1SPeter Avalos
17527bfbee1SPeter Avalos struct sflow_extended_switch_data_t {
176*ed775ee7SAntonio Huete Jimenez nd_uint32_t src_vlan;
177*ed775ee7SAntonio Huete Jimenez nd_uint32_t src_pri;
178*ed775ee7SAntonio Huete Jimenez nd_uint32_t dst_vlan;
179*ed775ee7SAntonio Huete Jimenez nd_uint32_t dst_pri;
18027bfbee1SPeter Avalos };
18127bfbee1SPeter Avalos
18227bfbee1SPeter Avalos struct sflow_counter_record_t {
183*ed775ee7SAntonio Huete Jimenez nd_uint32_t format;
184*ed775ee7SAntonio Huete Jimenez nd_uint32_t length;
18527bfbee1SPeter Avalos };
18627bfbee1SPeter Avalos
18727bfbee1SPeter Avalos struct sflow_flow_record_t {
188*ed775ee7SAntonio Huete Jimenez nd_uint32_t format;
189*ed775ee7SAntonio Huete Jimenez nd_uint32_t length;
19027bfbee1SPeter Avalos };
19127bfbee1SPeter Avalos
19227bfbee1SPeter Avalos struct sflow_counter_sample_t {
193*ed775ee7SAntonio Huete Jimenez nd_uint32_t seqnum;
194*ed775ee7SAntonio Huete Jimenez nd_uint8_t type;
195*ed775ee7SAntonio Huete Jimenez nd_uint24_t index;
196*ed775ee7SAntonio Huete Jimenez nd_uint32_t records;
19727bfbee1SPeter Avalos };
19827bfbee1SPeter Avalos
199ea7b4bf5SPeter Avalos struct sflow_expanded_counter_sample_t {
200*ed775ee7SAntonio Huete Jimenez nd_uint32_t seqnum;
201*ed775ee7SAntonio Huete Jimenez nd_uint32_t type;
202*ed775ee7SAntonio Huete Jimenez nd_uint32_t index;
203*ed775ee7SAntonio Huete Jimenez nd_uint32_t records;
204ea7b4bf5SPeter Avalos };
205ea7b4bf5SPeter Avalos
206ea7b4bf5SPeter Avalos #define SFLOW_COUNTER_GENERIC 1
207ea7b4bf5SPeter Avalos #define SFLOW_COUNTER_ETHERNET 2
208ea7b4bf5SPeter Avalos #define SFLOW_COUNTER_TOKEN_RING 3
209ea7b4bf5SPeter Avalos #define SFLOW_COUNTER_BASEVG 4
210ea7b4bf5SPeter Avalos #define SFLOW_COUNTER_VLAN 5
211ea7b4bf5SPeter Avalos #define SFLOW_COUNTER_PROCESSOR 1001
212ea7b4bf5SPeter Avalos
213ea7b4bf5SPeter Avalos static const struct tok sflow_counter_type_values[] = {
214ea7b4bf5SPeter Avalos { SFLOW_COUNTER_GENERIC, "Generic counter"},
215ea7b4bf5SPeter Avalos { SFLOW_COUNTER_ETHERNET, "Ethernet counter"},
216ea7b4bf5SPeter Avalos { SFLOW_COUNTER_TOKEN_RING, "Token ring counter"},
217ea7b4bf5SPeter Avalos { SFLOW_COUNTER_BASEVG, "100 BaseVG counter"},
218ea7b4bf5SPeter Avalos { SFLOW_COUNTER_VLAN, "Vlan counter"},
219ea7b4bf5SPeter Avalos { SFLOW_COUNTER_PROCESSOR, "Processor counter"},
220ea7b4bf5SPeter Avalos { 0, NULL}
221ea7b4bf5SPeter Avalos };
222ea7b4bf5SPeter Avalos
223ea7b4bf5SPeter Avalos #define SFLOW_IFACE_DIRECTION_UNKNOWN 0
224ea7b4bf5SPeter Avalos #define SFLOW_IFACE_DIRECTION_FULLDUPLEX 1
225ea7b4bf5SPeter Avalos #define SFLOW_IFACE_DIRECTION_HALFDUPLEX 2
226ea7b4bf5SPeter Avalos #define SFLOW_IFACE_DIRECTION_IN 3
227ea7b4bf5SPeter Avalos #define SFLOW_IFACE_DIRECTION_OUT 4
228ea7b4bf5SPeter Avalos
229ea7b4bf5SPeter Avalos static const struct tok sflow_iface_direction_values[] = {
230ea7b4bf5SPeter Avalos { SFLOW_IFACE_DIRECTION_UNKNOWN, "unknown"},
231ea7b4bf5SPeter Avalos { SFLOW_IFACE_DIRECTION_FULLDUPLEX, "full-duplex"},
232ea7b4bf5SPeter Avalos { SFLOW_IFACE_DIRECTION_HALFDUPLEX, "half-duplex"},
233ea7b4bf5SPeter Avalos { SFLOW_IFACE_DIRECTION_IN, "in"},
234ea7b4bf5SPeter Avalos { SFLOW_IFACE_DIRECTION_OUT, "out"},
235ea7b4bf5SPeter Avalos { 0, NULL}
236ea7b4bf5SPeter Avalos };
237ea7b4bf5SPeter Avalos
238ea7b4bf5SPeter Avalos struct sflow_generic_counter_t {
239*ed775ee7SAntonio Huete Jimenez nd_uint32_t ifindex;
240*ed775ee7SAntonio Huete Jimenez nd_uint32_t iftype;
241*ed775ee7SAntonio Huete Jimenez nd_uint64_t ifspeed;
242*ed775ee7SAntonio Huete Jimenez nd_uint32_t ifdirection;
243*ed775ee7SAntonio Huete Jimenez nd_uint32_t ifstatus;
244*ed775ee7SAntonio Huete Jimenez nd_uint64_t ifinoctets;
245*ed775ee7SAntonio Huete Jimenez nd_uint32_t ifinunicastpkts;
246*ed775ee7SAntonio Huete Jimenez nd_uint32_t ifinmulticastpkts;
247*ed775ee7SAntonio Huete Jimenez nd_uint32_t ifinbroadcastpkts;
248*ed775ee7SAntonio Huete Jimenez nd_uint32_t ifindiscards;
249*ed775ee7SAntonio Huete Jimenez nd_uint32_t ifinerrors;
250*ed775ee7SAntonio Huete Jimenez nd_uint32_t ifinunkownprotos;
251*ed775ee7SAntonio Huete Jimenez nd_uint64_t ifoutoctets;
252*ed775ee7SAntonio Huete Jimenez nd_uint32_t ifoutunicastpkts;
253*ed775ee7SAntonio Huete Jimenez nd_uint32_t ifoutmulticastpkts;
254*ed775ee7SAntonio Huete Jimenez nd_uint32_t ifoutbroadcastpkts;
255*ed775ee7SAntonio Huete Jimenez nd_uint32_t ifoutdiscards;
256*ed775ee7SAntonio Huete Jimenez nd_uint32_t ifouterrors;
257*ed775ee7SAntonio Huete Jimenez nd_uint32_t ifpromiscmode;
258ea7b4bf5SPeter Avalos };
259ea7b4bf5SPeter Avalos
260ea7b4bf5SPeter Avalos struct sflow_ethernet_counter_t {
261*ed775ee7SAntonio Huete Jimenez nd_uint32_t alignerrors;
262*ed775ee7SAntonio Huete Jimenez nd_uint32_t fcserrors;
263*ed775ee7SAntonio Huete Jimenez nd_uint32_t single_collision_frames;
264*ed775ee7SAntonio Huete Jimenez nd_uint32_t multiple_collision_frames;
265*ed775ee7SAntonio Huete Jimenez nd_uint32_t test_errors;
266*ed775ee7SAntonio Huete Jimenez nd_uint32_t deferred_transmissions;
267*ed775ee7SAntonio Huete Jimenez nd_uint32_t late_collisions;
268*ed775ee7SAntonio Huete Jimenez nd_uint32_t excessive_collisions;
269*ed775ee7SAntonio Huete Jimenez nd_uint32_t mac_transmit_errors;
270*ed775ee7SAntonio Huete Jimenez nd_uint32_t carrier_sense_errors;
271*ed775ee7SAntonio Huete Jimenez nd_uint32_t frame_too_longs;
272*ed775ee7SAntonio Huete Jimenez nd_uint32_t mac_receive_errors;
273*ed775ee7SAntonio Huete Jimenez nd_uint32_t symbol_errors;
274ea7b4bf5SPeter Avalos };
275ea7b4bf5SPeter Avalos
276ea7b4bf5SPeter Avalos struct sflow_100basevg_counter_t {
277*ed775ee7SAntonio Huete Jimenez nd_uint32_t in_highpriority_frames;
278*ed775ee7SAntonio Huete Jimenez nd_uint64_t in_highpriority_octets;
279*ed775ee7SAntonio Huete Jimenez nd_uint32_t in_normpriority_frames;
280*ed775ee7SAntonio Huete Jimenez nd_uint64_t in_normpriority_octets;
281*ed775ee7SAntonio Huete Jimenez nd_uint32_t in_ipmerrors;
282*ed775ee7SAntonio Huete Jimenez nd_uint32_t in_oversized;
283*ed775ee7SAntonio Huete Jimenez nd_uint32_t in_data_errors;
284*ed775ee7SAntonio Huete Jimenez nd_uint32_t in_null_addressed_frames;
285*ed775ee7SAntonio Huete Jimenez nd_uint32_t out_highpriority_frames;
286*ed775ee7SAntonio Huete Jimenez nd_uint64_t out_highpriority_octets;
287*ed775ee7SAntonio Huete Jimenez nd_uint32_t transitioninto_frames;
288*ed775ee7SAntonio Huete Jimenez nd_uint64_t hc_in_highpriority_octets;
289*ed775ee7SAntonio Huete Jimenez nd_uint64_t hc_in_normpriority_octets;
290*ed775ee7SAntonio Huete Jimenez nd_uint64_t hc_out_highpriority_octets;
291ea7b4bf5SPeter Avalos };
292ea7b4bf5SPeter Avalos
293ea7b4bf5SPeter Avalos struct sflow_vlan_counter_t {
294*ed775ee7SAntonio Huete Jimenez nd_uint32_t vlan_id;
295*ed775ee7SAntonio Huete Jimenez nd_uint64_t octets;
296*ed775ee7SAntonio Huete Jimenez nd_uint32_t unicast_pkt;
297*ed775ee7SAntonio Huete Jimenez nd_uint32_t multicast_pkt;
298*ed775ee7SAntonio Huete Jimenez nd_uint32_t broadcast_pkt;
299*ed775ee7SAntonio Huete Jimenez nd_uint32_t discards;
300ea7b4bf5SPeter Avalos };
301ea7b4bf5SPeter Avalos
30227bfbee1SPeter Avalos static int
print_sflow_counter_generic(netdissect_options * ndo,const u_char * pointer,u_int len)303411677aeSAaron LI print_sflow_counter_generic(netdissect_options *ndo,
304411677aeSAaron LI const u_char *pointer, u_int len)
305411677aeSAaron LI {
30627bfbee1SPeter Avalos const struct sflow_generic_counter_t *sflow_gen_counter;
30727bfbee1SPeter Avalos
30827bfbee1SPeter Avalos if (len < sizeof(struct sflow_generic_counter_t))
30927bfbee1SPeter Avalos return 1;
31027bfbee1SPeter Avalos
31127bfbee1SPeter Avalos sflow_gen_counter = (const struct sflow_generic_counter_t *)pointer;
312*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t ifindex %u, iftype %u, ifspeed %" PRIu64 ", ifdirection %u (%s)",
313*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_gen_counter->ifindex),
314*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_gen_counter->iftype),
315*ed775ee7SAntonio Huete Jimenez GET_BE_U_8(sflow_gen_counter->ifspeed),
316*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_gen_counter->ifdirection),
31727bfbee1SPeter Avalos tok2str(sflow_iface_direction_values, "Unknown",
318*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_gen_counter->ifdirection)));
319*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t ifstatus %u, adminstatus: %s, operstatus: %s",
320*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_gen_counter->ifstatus),
321*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_gen_counter->ifstatus)&1 ? "up" : "down",
322*ed775ee7SAntonio Huete Jimenez (GET_BE_U_4(sflow_gen_counter->ifstatus)>>1)&1 ? "up" : "down");
323*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t In octets %" PRIu64
32427bfbee1SPeter Avalos ", unicast pkts %u, multicast pkts %u, broadcast pkts %u, discards %u",
325*ed775ee7SAntonio Huete Jimenez GET_BE_U_8(sflow_gen_counter->ifinoctets),
326*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_gen_counter->ifinunicastpkts),
327*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_gen_counter->ifinmulticastpkts),
328*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_gen_counter->ifinbroadcastpkts),
329*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_gen_counter->ifindiscards));
330*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t In errors %u, unknown protos %u",
331*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_gen_counter->ifinerrors),
332*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_gen_counter->ifinunkownprotos));
333*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Out octets %" PRIu64
33427bfbee1SPeter Avalos ", unicast pkts %u, multicast pkts %u, broadcast pkts %u, discards %u",
335*ed775ee7SAntonio Huete Jimenez GET_BE_U_8(sflow_gen_counter->ifoutoctets),
336*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_gen_counter->ifoutunicastpkts),
337*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_gen_counter->ifoutmulticastpkts),
338*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_gen_counter->ifoutbroadcastpkts),
339*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_gen_counter->ifoutdiscards));
340*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t Out errors %u, promisc mode %u",
341*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_gen_counter->ifouterrors),
342*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_gen_counter->ifpromiscmode));
34327bfbee1SPeter Avalos
34427bfbee1SPeter Avalos return 0;
34527bfbee1SPeter Avalos }
34627bfbee1SPeter Avalos
34727bfbee1SPeter Avalos static int
print_sflow_counter_ethernet(netdissect_options * ndo,const u_char * pointer,u_int len)348411677aeSAaron LI print_sflow_counter_ethernet(netdissect_options *ndo,
349411677aeSAaron LI const u_char *pointer, u_int len)
350411677aeSAaron LI {
35127bfbee1SPeter Avalos const struct sflow_ethernet_counter_t *sflow_eth_counter;
35227bfbee1SPeter Avalos
35327bfbee1SPeter Avalos if (len < sizeof(struct sflow_ethernet_counter_t))
35427bfbee1SPeter Avalos return 1;
35527bfbee1SPeter Avalos
35627bfbee1SPeter Avalos sflow_eth_counter = (const struct sflow_ethernet_counter_t *)pointer;
357*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t align errors %u, fcs errors %u, single collision %u, multiple collision %u, test error %u",
358*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_eth_counter->alignerrors),
359*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_eth_counter->fcserrors),
360*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_eth_counter->single_collision_frames),
361*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_eth_counter->multiple_collision_frames),
362*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_eth_counter->test_errors));
363*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t deferred %u, late collision %u, excessive collision %u, mac trans error %u",
364*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_eth_counter->deferred_transmissions),
365*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_eth_counter->late_collisions),
366*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_eth_counter->excessive_collisions),
367*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_eth_counter->mac_transmit_errors));
368*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t carrier error %u, frames too long %u, mac receive errors %u, symbol errors %u",
369*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_eth_counter->carrier_sense_errors),
370*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_eth_counter->frame_too_longs),
371*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_eth_counter->mac_receive_errors),
372*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_eth_counter->symbol_errors));
37327bfbee1SPeter Avalos
37427bfbee1SPeter Avalos return 0;
375411677aeSAaron LI }
376411677aeSAaron LI
377411677aeSAaron LI static int
print_sflow_counter_token_ring(netdissect_options * ndo _U_,const u_char * pointer _U_,u_int len _U_)378411677aeSAaron LI print_sflow_counter_token_ring(netdissect_options *ndo _U_,
379411677aeSAaron LI const u_char *pointer _U_, u_int len _U_)
380411677aeSAaron LI {
381411677aeSAaron LI return 0;
38227bfbee1SPeter Avalos }
38327bfbee1SPeter Avalos
38427bfbee1SPeter Avalos static int
print_sflow_counter_basevg(netdissect_options * ndo,const u_char * pointer,u_int len)385411677aeSAaron LI print_sflow_counter_basevg(netdissect_options *ndo,
386411677aeSAaron LI const u_char *pointer, u_int len)
387411677aeSAaron LI {
38827bfbee1SPeter Avalos const struct sflow_100basevg_counter_t *sflow_100basevg_counter;
38927bfbee1SPeter Avalos
39027bfbee1SPeter Avalos if (len < sizeof(struct sflow_100basevg_counter_t))
39127bfbee1SPeter Avalos return 1;
39227bfbee1SPeter Avalos
39327bfbee1SPeter Avalos sflow_100basevg_counter = (const struct sflow_100basevg_counter_t *)pointer;
394*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t in high prio frames %u, in high prio octets %" PRIu64,
395*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_100basevg_counter->in_highpriority_frames),
396*ed775ee7SAntonio Huete Jimenez GET_BE_U_8(sflow_100basevg_counter->in_highpriority_octets));
397*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t in norm prio frames %u, in norm prio octets %" PRIu64,
398*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_100basevg_counter->in_normpriority_frames),
399*ed775ee7SAntonio Huete Jimenez GET_BE_U_8(sflow_100basevg_counter->in_normpriority_octets));
400*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t in ipm errors %u, oversized %u, in data errors %u, null addressed frames %u",
401*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_100basevg_counter->in_ipmerrors),
402*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_100basevg_counter->in_oversized),
403*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_100basevg_counter->in_data_errors),
404*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_100basevg_counter->in_null_addressed_frames));
405*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t out high prio frames %u, out high prio octets %" PRIu64
40627bfbee1SPeter Avalos ", trans into frames %u",
407*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_100basevg_counter->out_highpriority_frames),
408*ed775ee7SAntonio Huete Jimenez GET_BE_U_8(sflow_100basevg_counter->out_highpriority_octets),
409*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_100basevg_counter->transitioninto_frames));
410*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t in hc high prio octets %" PRIu64
41127bfbee1SPeter Avalos ", in hc norm prio octets %" PRIu64
41227bfbee1SPeter Avalos ", out hc high prio octets %" PRIu64,
413*ed775ee7SAntonio Huete Jimenez GET_BE_U_8(sflow_100basevg_counter->hc_in_highpriority_octets),
414*ed775ee7SAntonio Huete Jimenez GET_BE_U_8(sflow_100basevg_counter->hc_in_normpriority_octets),
415*ed775ee7SAntonio Huete Jimenez GET_BE_U_8(sflow_100basevg_counter->hc_out_highpriority_octets));
41627bfbee1SPeter Avalos
41727bfbee1SPeter Avalos return 0;
41827bfbee1SPeter Avalos }
41927bfbee1SPeter Avalos
42027bfbee1SPeter Avalos static int
print_sflow_counter_vlan(netdissect_options * ndo,const u_char * pointer,u_int len)421411677aeSAaron LI print_sflow_counter_vlan(netdissect_options *ndo,
422411677aeSAaron LI const u_char *pointer, u_int len)
423411677aeSAaron LI {
42427bfbee1SPeter Avalos const struct sflow_vlan_counter_t *sflow_vlan_counter;
42527bfbee1SPeter Avalos
42627bfbee1SPeter Avalos if (len < sizeof(struct sflow_vlan_counter_t))
42727bfbee1SPeter Avalos return 1;
42827bfbee1SPeter Avalos
42927bfbee1SPeter Avalos sflow_vlan_counter = (const struct sflow_vlan_counter_t *)pointer;
430*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t vlan_id %u, octets %" PRIu64
43127bfbee1SPeter Avalos ", unicast_pkt %u, multicast_pkt %u, broadcast_pkt %u, discards %u",
432*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_vlan_counter->vlan_id),
433*ed775ee7SAntonio Huete Jimenez GET_BE_U_8(sflow_vlan_counter->octets),
434*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_vlan_counter->unicast_pkt),
435*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_vlan_counter->multicast_pkt),
436*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_vlan_counter->broadcast_pkt),
437*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_vlan_counter->discards));
43827bfbee1SPeter Avalos
43927bfbee1SPeter Avalos return 0;
44027bfbee1SPeter Avalos }
44127bfbee1SPeter Avalos
44227bfbee1SPeter Avalos struct sflow_processor_counter_t {
443*ed775ee7SAntonio Huete Jimenez nd_uint32_t five_sec_util;
444*ed775ee7SAntonio Huete Jimenez nd_uint32_t one_min_util;
445*ed775ee7SAntonio Huete Jimenez nd_uint32_t five_min_util;
446*ed775ee7SAntonio Huete Jimenez nd_uint64_t total_memory;
447*ed775ee7SAntonio Huete Jimenez nd_uint64_t free_memory;
44827bfbee1SPeter Avalos };
44927bfbee1SPeter Avalos
45027bfbee1SPeter Avalos static int
print_sflow_counter_processor(netdissect_options * ndo,const u_char * pointer,u_int len)451411677aeSAaron LI print_sflow_counter_processor(netdissect_options *ndo,
452411677aeSAaron LI const u_char *pointer, u_int len)
453411677aeSAaron LI {
45427bfbee1SPeter Avalos const struct sflow_processor_counter_t *sflow_processor_counter;
45527bfbee1SPeter Avalos
45627bfbee1SPeter Avalos if (len < sizeof(struct sflow_processor_counter_t))
45727bfbee1SPeter Avalos return 1;
45827bfbee1SPeter Avalos
45927bfbee1SPeter Avalos sflow_processor_counter = (const struct sflow_processor_counter_t *)pointer;
460*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t 5sec %u, 1min %u, 5min %u, total_mem %" PRIu64
46127bfbee1SPeter Avalos ", total_mem %" PRIu64,
462*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_processor_counter->five_sec_util),
463*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_processor_counter->one_min_util),
464*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_processor_counter->five_min_util),
465*ed775ee7SAntonio Huete Jimenez GET_BE_U_8(sflow_processor_counter->total_memory),
466*ed775ee7SAntonio Huete Jimenez GET_BE_U_8(sflow_processor_counter->free_memory));
46727bfbee1SPeter Avalos
46827bfbee1SPeter Avalos return 0;
46927bfbee1SPeter Avalos }
47027bfbee1SPeter Avalos
47127bfbee1SPeter Avalos static int
sflow_print_counter_records(netdissect_options * ndo,const u_char * pointer,u_int len,u_int records)472411677aeSAaron LI sflow_print_counter_records(netdissect_options *ndo,
473411677aeSAaron LI const u_char *pointer, u_int len, u_int records)
474411677aeSAaron LI {
47527bfbee1SPeter Avalos u_int nrecords;
47627bfbee1SPeter Avalos const u_char *tptr;
47727bfbee1SPeter Avalos u_int tlen;
47827bfbee1SPeter Avalos u_int counter_type;
47927bfbee1SPeter Avalos u_int counter_len;
48027bfbee1SPeter Avalos u_int enterprise;
48127bfbee1SPeter Avalos const struct sflow_counter_record_t *sflow_counter_record;
48227bfbee1SPeter Avalos
48327bfbee1SPeter Avalos nrecords = records;
48427bfbee1SPeter Avalos tptr = pointer;
48527bfbee1SPeter Avalos tlen = len;
48627bfbee1SPeter Avalos
48727bfbee1SPeter Avalos while (nrecords > 0) {
48827bfbee1SPeter Avalos /* do we have the "header?" */
48927bfbee1SPeter Avalos if (tlen < sizeof(struct sflow_counter_record_t))
49027bfbee1SPeter Avalos return 1;
49127bfbee1SPeter Avalos sflow_counter_record = (const struct sflow_counter_record_t *)tptr;
49227bfbee1SPeter Avalos
493*ed775ee7SAntonio Huete Jimenez enterprise = GET_BE_U_4(sflow_counter_record->format);
49427bfbee1SPeter Avalos counter_type = enterprise & 0x0FFF;
49527bfbee1SPeter Avalos enterprise = enterprise >> 20;
496*ed775ee7SAntonio Huete Jimenez counter_len = GET_BE_U_4(sflow_counter_record->length);
497*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t enterprise %u, %s (%u) length %u",
49827bfbee1SPeter Avalos enterprise,
49927bfbee1SPeter Avalos (enterprise == 0) ? tok2str(sflow_counter_type_values,"Unknown",counter_type) : "Unknown",
50027bfbee1SPeter Avalos counter_type,
501*ed775ee7SAntonio Huete Jimenez counter_len);
50227bfbee1SPeter Avalos
50327bfbee1SPeter Avalos tptr += sizeof(struct sflow_counter_record_t);
50427bfbee1SPeter Avalos tlen -= sizeof(struct sflow_counter_record_t);
50527bfbee1SPeter Avalos
50627bfbee1SPeter Avalos if (tlen < counter_len)
50727bfbee1SPeter Avalos return 1;
50827bfbee1SPeter Avalos if (enterprise == 0) {
50927bfbee1SPeter Avalos switch (counter_type) {
51027bfbee1SPeter Avalos case SFLOW_COUNTER_GENERIC:
511411677aeSAaron LI if (print_sflow_counter_generic(ndo, tptr, tlen))
51227bfbee1SPeter Avalos return 1;
51327bfbee1SPeter Avalos break;
51427bfbee1SPeter Avalos case SFLOW_COUNTER_ETHERNET:
515411677aeSAaron LI if (print_sflow_counter_ethernet(ndo, tptr, tlen))
51627bfbee1SPeter Avalos return 1;
51727bfbee1SPeter Avalos break;
51827bfbee1SPeter Avalos case SFLOW_COUNTER_TOKEN_RING:
519411677aeSAaron LI if (print_sflow_counter_token_ring(ndo, tptr,tlen))
52027bfbee1SPeter Avalos return 1;
52127bfbee1SPeter Avalos break;
52227bfbee1SPeter Avalos case SFLOW_COUNTER_BASEVG:
523411677aeSAaron LI if (print_sflow_counter_basevg(ndo, tptr, tlen))
52427bfbee1SPeter Avalos return 1;
52527bfbee1SPeter Avalos break;
52627bfbee1SPeter Avalos case SFLOW_COUNTER_VLAN:
527411677aeSAaron LI if (print_sflow_counter_vlan(ndo, tptr, tlen))
52827bfbee1SPeter Avalos return 1;
52927bfbee1SPeter Avalos break;
53027bfbee1SPeter Avalos case SFLOW_COUNTER_PROCESSOR:
531411677aeSAaron LI if (print_sflow_counter_processor(ndo, tptr, tlen))
53227bfbee1SPeter Avalos return 1;
53327bfbee1SPeter Avalos break;
53427bfbee1SPeter Avalos default:
535411677aeSAaron LI if (ndo->ndo_vflag <= 1)
536411677aeSAaron LI print_unknown_data(ndo, tptr, "\n\t\t", counter_len);
53727bfbee1SPeter Avalos break;
53827bfbee1SPeter Avalos }
53927bfbee1SPeter Avalos }
54027bfbee1SPeter Avalos tptr += counter_len;
54127bfbee1SPeter Avalos tlen -= counter_len;
54227bfbee1SPeter Avalos nrecords--;
54327bfbee1SPeter Avalos
54427bfbee1SPeter Avalos }
54527bfbee1SPeter Avalos
54627bfbee1SPeter Avalos return 0;
54727bfbee1SPeter Avalos }
54827bfbee1SPeter Avalos
54927bfbee1SPeter Avalos static int
sflow_print_counter_sample(netdissect_options * ndo,const u_char * pointer,u_int len)550411677aeSAaron LI sflow_print_counter_sample(netdissect_options *ndo,
551411677aeSAaron LI const u_char *pointer, u_int len)
552411677aeSAaron LI {
55327bfbee1SPeter Avalos const struct sflow_counter_sample_t *sflow_counter_sample;
55427bfbee1SPeter Avalos u_int nrecords;
55527bfbee1SPeter Avalos
55627bfbee1SPeter Avalos if (len < sizeof(struct sflow_counter_sample_t))
55727bfbee1SPeter Avalos return 1;
55827bfbee1SPeter Avalos
55927bfbee1SPeter Avalos sflow_counter_sample = (const struct sflow_counter_sample_t *)pointer;
56027bfbee1SPeter Avalos
561*ed775ee7SAntonio Huete Jimenez nrecords = GET_BE_U_4(sflow_counter_sample->records);
56227bfbee1SPeter Avalos
563*ed775ee7SAntonio Huete Jimenez ND_PRINT(" seqnum %u, type %u, idx %u, records %u",
564*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_counter_sample->seqnum),
565*ed775ee7SAntonio Huete Jimenez GET_U_1(sflow_counter_sample->type),
566*ed775ee7SAntonio Huete Jimenez GET_BE_U_3(sflow_counter_sample->index),
567*ed775ee7SAntonio Huete Jimenez nrecords);
56827bfbee1SPeter Avalos
569411677aeSAaron LI return sflow_print_counter_records(ndo, pointer + sizeof(struct sflow_counter_sample_t),
57027bfbee1SPeter Avalos len - sizeof(struct sflow_counter_sample_t),
57127bfbee1SPeter Avalos nrecords);
57227bfbee1SPeter Avalos }
57327bfbee1SPeter Avalos
57427bfbee1SPeter Avalos static int
sflow_print_expanded_counter_sample(netdissect_options * ndo,const u_char * pointer,u_int len)575411677aeSAaron LI sflow_print_expanded_counter_sample(netdissect_options *ndo,
576411677aeSAaron LI const u_char *pointer, u_int len)
577411677aeSAaron LI {
57827bfbee1SPeter Avalos const struct sflow_expanded_counter_sample_t *sflow_expanded_counter_sample;
57927bfbee1SPeter Avalos u_int nrecords;
58027bfbee1SPeter Avalos
58127bfbee1SPeter Avalos
58227bfbee1SPeter Avalos if (len < sizeof(struct sflow_expanded_counter_sample_t))
58327bfbee1SPeter Avalos return 1;
58427bfbee1SPeter Avalos
58527bfbee1SPeter Avalos sflow_expanded_counter_sample = (const struct sflow_expanded_counter_sample_t *)pointer;
58627bfbee1SPeter Avalos
587*ed775ee7SAntonio Huete Jimenez nrecords = GET_BE_U_4(sflow_expanded_counter_sample->records);
58827bfbee1SPeter Avalos
589*ed775ee7SAntonio Huete Jimenez ND_PRINT(" seqnum %u, type %u, idx %u, records %u",
590*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_expanded_counter_sample->seqnum),
591*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_expanded_counter_sample->type),
592*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_expanded_counter_sample->index),
593*ed775ee7SAntonio Huete Jimenez nrecords);
59427bfbee1SPeter Avalos
595411677aeSAaron LI return sflow_print_counter_records(ndo, pointer + sizeof(struct sflow_expanded_counter_sample_t),
59627bfbee1SPeter Avalos len - sizeof(struct sflow_expanded_counter_sample_t),
59727bfbee1SPeter Avalos nrecords);
59827bfbee1SPeter Avalos }
59927bfbee1SPeter Avalos
60027bfbee1SPeter Avalos static int
print_sflow_raw_packet(netdissect_options * ndo,const u_char * pointer,u_int len)601411677aeSAaron LI print_sflow_raw_packet(netdissect_options *ndo,
602411677aeSAaron LI const u_char *pointer, u_int len)
603411677aeSAaron LI {
60427bfbee1SPeter Avalos const struct sflow_expanded_flow_raw_t *sflow_flow_raw;
60527bfbee1SPeter Avalos
60627bfbee1SPeter Avalos if (len < sizeof(struct sflow_expanded_flow_raw_t))
60727bfbee1SPeter Avalos return 1;
60827bfbee1SPeter Avalos
60927bfbee1SPeter Avalos sflow_flow_raw = (const struct sflow_expanded_flow_raw_t *)pointer;
610*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t protocol %s (%u), length %u, stripped bytes %u, header_size %u",
611*ed775ee7SAntonio Huete Jimenez tok2str(sflow_flow_raw_protocol_values,"Unknown",GET_BE_U_4(sflow_flow_raw->protocol)),
612*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_flow_raw->protocol),
613*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_flow_raw->length),
614*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_flow_raw->stripped_bytes),
615*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_flow_raw->header_size));
61627bfbee1SPeter Avalos
61727bfbee1SPeter Avalos /* QUESTION - should we attempt to print the raw header itself?
618*ed775ee7SAntonio Huete Jimenez assuming of course there is enough data present to do so... */
61927bfbee1SPeter Avalos
62027bfbee1SPeter Avalos return 0;
62127bfbee1SPeter Avalos }
62227bfbee1SPeter Avalos
62327bfbee1SPeter Avalos static int
print_sflow_ethernet_frame(netdissect_options * ndo,const u_char * pointer,u_int len)624411677aeSAaron LI print_sflow_ethernet_frame(netdissect_options *ndo,
625411677aeSAaron LI const u_char *pointer, u_int len)
626411677aeSAaron LI {
62727bfbee1SPeter Avalos const struct sflow_ethernet_frame_t *sflow_ethernet_frame;
62827bfbee1SPeter Avalos
62927bfbee1SPeter Avalos if (len < sizeof(struct sflow_ethernet_frame_t))
63027bfbee1SPeter Avalos return 1;
63127bfbee1SPeter Avalos
63227bfbee1SPeter Avalos sflow_ethernet_frame = (const struct sflow_ethernet_frame_t *)pointer;
63327bfbee1SPeter Avalos
634*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t frame len %u, type %u",
635*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_ethernet_frame->length),
636*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_ethernet_frame->type));
63727bfbee1SPeter Avalos
63827bfbee1SPeter Avalos return 0;
63927bfbee1SPeter Avalos }
64027bfbee1SPeter Avalos
64127bfbee1SPeter Avalos static int
print_sflow_extended_switch_data(netdissect_options * ndo,const u_char * pointer,u_int len)642411677aeSAaron LI print_sflow_extended_switch_data(netdissect_options *ndo,
643411677aeSAaron LI const u_char *pointer, u_int len)
644411677aeSAaron LI {
64527bfbee1SPeter Avalos const struct sflow_extended_switch_data_t *sflow_extended_sw_data;
64627bfbee1SPeter Avalos
64727bfbee1SPeter Avalos if (len < sizeof(struct sflow_extended_switch_data_t))
64827bfbee1SPeter Avalos return 1;
64927bfbee1SPeter Avalos
65027bfbee1SPeter Avalos sflow_extended_sw_data = (const struct sflow_extended_switch_data_t *)pointer;
651*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t src vlan %u, src pri %u, dst vlan %u, dst pri %u",
652*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_extended_sw_data->src_vlan),
653*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_extended_sw_data->src_pri),
654*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_extended_sw_data->dst_vlan),
655*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_extended_sw_data->dst_pri));
65627bfbee1SPeter Avalos
65727bfbee1SPeter Avalos return 0;
65827bfbee1SPeter Avalos }
65927bfbee1SPeter Avalos
66027bfbee1SPeter Avalos static int
sflow_print_flow_records(netdissect_options * ndo,const u_char * pointer,u_int len,u_int records)661411677aeSAaron LI sflow_print_flow_records(netdissect_options *ndo,
662411677aeSAaron LI const u_char *pointer, u_int len, u_int records)
663411677aeSAaron LI {
66427bfbee1SPeter Avalos u_int nrecords;
66527bfbee1SPeter Avalos const u_char *tptr;
66627bfbee1SPeter Avalos u_int tlen;
66727bfbee1SPeter Avalos u_int flow_type;
66827bfbee1SPeter Avalos u_int enterprise;
66927bfbee1SPeter Avalos u_int flow_len;
67027bfbee1SPeter Avalos const struct sflow_flow_record_t *sflow_flow_record;
67127bfbee1SPeter Avalos
67227bfbee1SPeter Avalos nrecords = records;
67327bfbee1SPeter Avalos tptr = pointer;
67427bfbee1SPeter Avalos tlen = len;
67527bfbee1SPeter Avalos
67627bfbee1SPeter Avalos while (nrecords > 0) {
67727bfbee1SPeter Avalos /* do we have the "header?" */
67827bfbee1SPeter Avalos if (tlen < sizeof(struct sflow_flow_record_t))
67927bfbee1SPeter Avalos return 1;
68027bfbee1SPeter Avalos
68127bfbee1SPeter Avalos sflow_flow_record = (const struct sflow_flow_record_t *)tptr;
68227bfbee1SPeter Avalos
68327bfbee1SPeter Avalos /* so, the funky encoding means we cannot blythly mask-off
68427bfbee1SPeter Avalos bits, we must also check the enterprise. */
68527bfbee1SPeter Avalos
686*ed775ee7SAntonio Huete Jimenez enterprise = GET_BE_U_4(sflow_flow_record->format);
68727bfbee1SPeter Avalos flow_type = enterprise & 0x0FFF;
68827bfbee1SPeter Avalos enterprise = enterprise >> 12;
689*ed775ee7SAntonio Huete Jimenez flow_len = GET_BE_U_4(sflow_flow_record->length);
690*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t enterprise %u %s (%u) length %u",
69127bfbee1SPeter Avalos enterprise,
69227bfbee1SPeter Avalos (enterprise == 0) ? tok2str(sflow_flow_type_values,"Unknown",flow_type) : "Unknown",
69327bfbee1SPeter Avalos flow_type,
694*ed775ee7SAntonio Huete Jimenez flow_len);
69527bfbee1SPeter Avalos
69627bfbee1SPeter Avalos tptr += sizeof(struct sflow_flow_record_t);
69727bfbee1SPeter Avalos tlen -= sizeof(struct sflow_flow_record_t);
69827bfbee1SPeter Avalos
69927bfbee1SPeter Avalos if (tlen < flow_len)
70027bfbee1SPeter Avalos return 1;
70127bfbee1SPeter Avalos
70227bfbee1SPeter Avalos if (enterprise == 0) {
70327bfbee1SPeter Avalos switch (flow_type) {
70427bfbee1SPeter Avalos case SFLOW_FLOW_RAW_PACKET:
705411677aeSAaron LI if (print_sflow_raw_packet(ndo, tptr, tlen))
70627bfbee1SPeter Avalos return 1;
70727bfbee1SPeter Avalos break;
70827bfbee1SPeter Avalos case SFLOW_FLOW_EXTENDED_SWITCH_DATA:
709411677aeSAaron LI if (print_sflow_extended_switch_data(ndo, tptr, tlen))
71027bfbee1SPeter Avalos return 1;
71127bfbee1SPeter Avalos break;
71227bfbee1SPeter Avalos case SFLOW_FLOW_ETHERNET_FRAME:
713411677aeSAaron LI if (print_sflow_ethernet_frame(ndo, tptr, tlen))
71427bfbee1SPeter Avalos return 1;
71527bfbee1SPeter Avalos break;
71627bfbee1SPeter Avalos /* FIXME these need a decoder */
71727bfbee1SPeter Avalos case SFLOW_FLOW_IPV4_DATA:
71827bfbee1SPeter Avalos case SFLOW_FLOW_IPV6_DATA:
71927bfbee1SPeter Avalos case SFLOW_FLOW_EXTENDED_ROUTER_DATA:
72027bfbee1SPeter Avalos case SFLOW_FLOW_EXTENDED_GATEWAY_DATA:
72127bfbee1SPeter Avalos case SFLOW_FLOW_EXTENDED_USER_DATA:
72227bfbee1SPeter Avalos case SFLOW_FLOW_EXTENDED_URL_DATA:
72327bfbee1SPeter Avalos case SFLOW_FLOW_EXTENDED_MPLS_DATA:
72427bfbee1SPeter Avalos case SFLOW_FLOW_EXTENDED_NAT_DATA:
72527bfbee1SPeter Avalos case SFLOW_FLOW_EXTENDED_MPLS_TUNNEL:
72627bfbee1SPeter Avalos case SFLOW_FLOW_EXTENDED_MPLS_VC:
72727bfbee1SPeter Avalos case SFLOW_FLOW_EXTENDED_MPLS_FEC:
72827bfbee1SPeter Avalos case SFLOW_FLOW_EXTENDED_MPLS_LVP_FEC:
72927bfbee1SPeter Avalos case SFLOW_FLOW_EXTENDED_VLAN_TUNNEL:
73027bfbee1SPeter Avalos break;
73127bfbee1SPeter Avalos default:
732411677aeSAaron LI if (ndo->ndo_vflag <= 1)
733411677aeSAaron LI print_unknown_data(ndo, tptr, "\n\t\t", flow_len);
73427bfbee1SPeter Avalos break;
73527bfbee1SPeter Avalos }
73627bfbee1SPeter Avalos }
73727bfbee1SPeter Avalos tptr += flow_len;
73827bfbee1SPeter Avalos tlen -= flow_len;
73927bfbee1SPeter Avalos nrecords--;
74027bfbee1SPeter Avalos
74127bfbee1SPeter Avalos }
74227bfbee1SPeter Avalos
74327bfbee1SPeter Avalos return 0;
74427bfbee1SPeter Avalos }
74527bfbee1SPeter Avalos
74627bfbee1SPeter Avalos static int
sflow_print_flow_sample(netdissect_options * ndo,const u_char * pointer,u_int len)747411677aeSAaron LI sflow_print_flow_sample(netdissect_options *ndo,
748411677aeSAaron LI const u_char *pointer, u_int len)
749411677aeSAaron LI {
75027bfbee1SPeter Avalos const struct sflow_flow_sample_t *sflow_flow_sample;
75127bfbee1SPeter Avalos u_int nrecords;
75227bfbee1SPeter Avalos
75327bfbee1SPeter Avalos if (len < sizeof(struct sflow_flow_sample_t))
75427bfbee1SPeter Avalos return 1;
75527bfbee1SPeter Avalos
756411677aeSAaron LI sflow_flow_sample = (const struct sflow_flow_sample_t *)pointer;
75727bfbee1SPeter Avalos
758*ed775ee7SAntonio Huete Jimenez nrecords = GET_BE_U_4(sflow_flow_sample->records);
75927bfbee1SPeter Avalos
760*ed775ee7SAntonio Huete Jimenez ND_PRINT(" seqnum %u, type %u, idx %u, rate %u, pool %u, drops %u, input %u output %u records %u",
761*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_flow_sample->seqnum),
762*ed775ee7SAntonio Huete Jimenez GET_U_1(sflow_flow_sample->type),
763*ed775ee7SAntonio Huete Jimenez GET_BE_U_3(sflow_flow_sample->index),
764*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_flow_sample->rate),
765*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_flow_sample->pool),
766*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_flow_sample->drops),
767*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_flow_sample->in_interface),
768*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_flow_sample->out_interface),
769*ed775ee7SAntonio Huete Jimenez nrecords);
77027bfbee1SPeter Avalos
771411677aeSAaron LI return sflow_print_flow_records(ndo, pointer + sizeof(struct sflow_flow_sample_t),
77227bfbee1SPeter Avalos len - sizeof(struct sflow_flow_sample_t),
77327bfbee1SPeter Avalos nrecords);
77427bfbee1SPeter Avalos }
77527bfbee1SPeter Avalos
77627bfbee1SPeter Avalos static int
sflow_print_expanded_flow_sample(netdissect_options * ndo,const u_char * pointer,u_int len)777411677aeSAaron LI sflow_print_expanded_flow_sample(netdissect_options *ndo,
778411677aeSAaron LI const u_char *pointer, u_int len)
779411677aeSAaron LI {
78027bfbee1SPeter Avalos const struct sflow_expanded_flow_sample_t *sflow_expanded_flow_sample;
78127bfbee1SPeter Avalos u_int nrecords;
78227bfbee1SPeter Avalos
78327bfbee1SPeter Avalos if (len < sizeof(struct sflow_expanded_flow_sample_t))
78427bfbee1SPeter Avalos return 1;
78527bfbee1SPeter Avalos
78627bfbee1SPeter Avalos sflow_expanded_flow_sample = (const struct sflow_expanded_flow_sample_t *)pointer;
78727bfbee1SPeter Avalos
788*ed775ee7SAntonio Huete Jimenez nrecords = GET_BE_U_4(sflow_expanded_flow_sample->records);
78927bfbee1SPeter Avalos
790*ed775ee7SAntonio Huete Jimenez ND_PRINT(" seqnum %u, type %u, idx %u, rate %u, pool %u, drops %u, records %u",
791*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_expanded_flow_sample->seqnum),
792*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_expanded_flow_sample->type),
793*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_expanded_flow_sample->index),
794*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_expanded_flow_sample->rate),
795*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_expanded_flow_sample->pool),
796*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_expanded_flow_sample->drops),
797*ed775ee7SAntonio Huete Jimenez nrecords);
79827bfbee1SPeter Avalos
799411677aeSAaron LI return sflow_print_flow_records(ndo, pointer + sizeof(struct sflow_expanded_flow_sample_t),
80027bfbee1SPeter Avalos len - sizeof(struct sflow_expanded_flow_sample_t),
80127bfbee1SPeter Avalos nrecords);
80227bfbee1SPeter Avalos }
80327bfbee1SPeter Avalos
804ea7b4bf5SPeter Avalos void
sflow_print(netdissect_options * ndo,const u_char * pptr,u_int len)805411677aeSAaron LI sflow_print(netdissect_options *ndo,
806411677aeSAaron LI const u_char *pptr, u_int len)
807411677aeSAaron LI {
808ea7b4bf5SPeter Avalos const struct sflow_datagram_t *sflow_datagram;
809ea7b4bf5SPeter Avalos const struct sflow_sample_header *sflow_sample;
81027bfbee1SPeter Avalos
811ea7b4bf5SPeter Avalos const u_char *tptr;
81227bfbee1SPeter Avalos u_int tlen;
813411677aeSAaron LI uint32_t sflow_sample_type, sflow_sample_len;
814411677aeSAaron LI uint32_t nsamples;
815ea7b4bf5SPeter Avalos
816*ed775ee7SAntonio Huete Jimenez ndo->ndo_protocol = "sflow";
817ea7b4bf5SPeter Avalos tptr = pptr;
818ea7b4bf5SPeter Avalos tlen = len;
819ea7b4bf5SPeter Avalos sflow_datagram = (const struct sflow_datagram_t *)pptr;
820411677aeSAaron LI if (len < sizeof(struct sflow_datagram_t)) {
821*ed775ee7SAntonio Huete Jimenez ND_PRINT("sFlowv%u", GET_BE_U_4(sflow_datagram->version));
822*ed775ee7SAntonio Huete Jimenez ND_PRINT(" [length %u < %zu]", len, sizeof(struct sflow_datagram_t));
823*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
824411677aeSAaron LI return;
825411677aeSAaron LI }
826*ed775ee7SAntonio Huete Jimenez ND_TCHECK_SIZE(sflow_datagram);
827ea7b4bf5SPeter Avalos
828ea7b4bf5SPeter Avalos /*
829ea7b4bf5SPeter Avalos * Sanity checking of the header.
830ea7b4bf5SPeter Avalos */
831*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_4(sflow_datagram->version) != 5) {
832*ed775ee7SAntonio Huete Jimenez ND_PRINT("sFlow version %u packet not supported",
833*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_datagram->version));
834ea7b4bf5SPeter Avalos return;
835ea7b4bf5SPeter Avalos }
836ea7b4bf5SPeter Avalos
837411677aeSAaron LI if (ndo->ndo_vflag < 1) {
838*ed775ee7SAntonio Huete Jimenez ND_PRINT("sFlowv%u, %s agent %s, agent-id %u, length %u",
839*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_datagram->version),
840*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_datagram->ip_version) == 1 ? "IPv4" : "IPv6",
841*ed775ee7SAntonio Huete Jimenez GET_IPADDR_STRING(sflow_datagram->agent),
842*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_datagram->agent_id),
843*ed775ee7SAntonio Huete Jimenez len);
844ea7b4bf5SPeter Avalos return;
845ea7b4bf5SPeter Avalos }
846ea7b4bf5SPeter Avalos
847ea7b4bf5SPeter Avalos /* ok they seem to want to know everything - lets fully decode it */
848*ed775ee7SAntonio Huete Jimenez nsamples=GET_BE_U_4(sflow_datagram->samples);
849*ed775ee7SAntonio Huete Jimenez ND_PRINT("sFlowv%u, %s agent %s, agent-id %u, seqnum %u, uptime %u, samples %u, length %u",
850*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_datagram->version),
851*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_datagram->ip_version) == 1 ? "IPv4" : "IPv6",
852*ed775ee7SAntonio Huete Jimenez GET_IPADDR_STRING(sflow_datagram->agent),
853*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_datagram->agent_id),
854*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_datagram->seqnum),
855*ed775ee7SAntonio Huete Jimenez GET_BE_U_4(sflow_datagram->uptime),
856ea7b4bf5SPeter Avalos nsamples,
857*ed775ee7SAntonio Huete Jimenez len);
858ea7b4bf5SPeter Avalos
859ea7b4bf5SPeter Avalos /* skip Common header */
860*ed775ee7SAntonio Huete Jimenez tptr += sizeof(struct sflow_datagram_t);
861*ed775ee7SAntonio Huete Jimenez tlen -= sizeof(struct sflow_datagram_t);
862ea7b4bf5SPeter Avalos
863ea7b4bf5SPeter Avalos while (nsamples > 0 && tlen > 0) {
864ea7b4bf5SPeter Avalos sflow_sample = (const struct sflow_sample_header *)tptr;
86527bfbee1SPeter Avalos
866*ed775ee7SAntonio Huete Jimenez sflow_sample_type = (GET_BE_U_4(sflow_sample->format)&0x0FFF);
867*ed775ee7SAntonio Huete Jimenez sflow_sample_len = GET_BE_U_4(sflow_sample->len);
868ea7b4bf5SPeter Avalos
86927bfbee1SPeter Avalos if (tlen < sizeof(struct sflow_sample_header))
870*ed775ee7SAntonio Huete Jimenez goto invalid;
87127bfbee1SPeter Avalos
872ea7b4bf5SPeter Avalos tptr += sizeof(struct sflow_sample_header);
873ea7b4bf5SPeter Avalos tlen -= sizeof(struct sflow_sample_header);
874ea7b4bf5SPeter Avalos
875*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t%s (%u), length %u,",
876ea7b4bf5SPeter Avalos tok2str(sflow_format_values, "Unknown", sflow_sample_type),
877ea7b4bf5SPeter Avalos sflow_sample_type,
878*ed775ee7SAntonio Huete Jimenez sflow_sample_len);
879ea7b4bf5SPeter Avalos
880ea7b4bf5SPeter Avalos /* basic sanity check */
881ea7b4bf5SPeter Avalos if (sflow_sample_type == 0 || sflow_sample_len ==0) {
882ea7b4bf5SPeter Avalos return;
883ea7b4bf5SPeter Avalos }
884ea7b4bf5SPeter Avalos
88527bfbee1SPeter Avalos if (tlen < sflow_sample_len)
886*ed775ee7SAntonio Huete Jimenez goto invalid;
887ea7b4bf5SPeter Avalos
88827bfbee1SPeter Avalos /* did we capture enough for fully decoding the sample ? */
889*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(tptr, sflow_sample_len);
89027bfbee1SPeter Avalos
891ea7b4bf5SPeter Avalos switch(sflow_sample_type) {
89227bfbee1SPeter Avalos case SFLOW_FLOW_SAMPLE:
893411677aeSAaron LI if (sflow_print_flow_sample(ndo, tptr, tlen))
894*ed775ee7SAntonio Huete Jimenez goto invalid;
895ea7b4bf5SPeter Avalos break;
896ea7b4bf5SPeter Avalos
89727bfbee1SPeter Avalos case SFLOW_COUNTER_SAMPLE:
898411677aeSAaron LI if (sflow_print_counter_sample(ndo, tptr,tlen))
899*ed775ee7SAntonio Huete Jimenez goto invalid;
900ea7b4bf5SPeter Avalos break;
901ea7b4bf5SPeter Avalos
902ea7b4bf5SPeter Avalos case SFLOW_EXPANDED_FLOW_SAMPLE:
903411677aeSAaron LI if (sflow_print_expanded_flow_sample(ndo, tptr, tlen))
904*ed775ee7SAntonio Huete Jimenez goto invalid;
905ea7b4bf5SPeter Avalos break;
906ea7b4bf5SPeter Avalos
907ea7b4bf5SPeter Avalos case SFLOW_EXPANDED_COUNTER_SAMPLE:
908411677aeSAaron LI if (sflow_print_expanded_counter_sample(ndo, tptr,tlen))
909*ed775ee7SAntonio Huete Jimenez goto invalid;
91027bfbee1SPeter Avalos break;
911ea7b4bf5SPeter Avalos
912ea7b4bf5SPeter Avalos default:
913411677aeSAaron LI if (ndo->ndo_vflag <= 1)
914411677aeSAaron LI print_unknown_data(ndo, tptr, "\n\t ", sflow_sample_len);
915ea7b4bf5SPeter Avalos break;
916ea7b4bf5SPeter Avalos }
917ea7b4bf5SPeter Avalos tptr += sflow_sample_len;
918ea7b4bf5SPeter Avalos tlen -= sflow_sample_len;
919ea7b4bf5SPeter Avalos nsamples--;
920ea7b4bf5SPeter Avalos }
921ea7b4bf5SPeter Avalos return;
922ea7b4bf5SPeter Avalos
923*ed775ee7SAntonio Huete Jimenez invalid:
924*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
925*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(tptr, tlen);
926ea7b4bf5SPeter Avalos }
927