6 ** (c) 2002 bill fumerola <fumerola@yahoo-inc.com>
7 ** (C) 2005-06 Luca Deri <deri@ntop.org>
9 ** All rights reserved.
11 ** Wireshark - Network traffic analyzer
12 ** By Gerald Combs <gerald@wireshark.org>
13 ** Copyright 1998 Gerald Combs
15 ** This program is free software; you can redistribute it and/or
16 ** modify it under the terms of the GNU General Public License
17 ** as published by the Free Software Foundation; either version 2
18 ** of the License, or (at your option) any later version.
20 ** This program is distributed in the hope that it will be useful,
21 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
22 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 ** GNU General Public License for more details.
25 ** You should have received a copy of the GNU General Public License
26 ** along with this program; if not, write to the Free Software
27 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 *****************************************************************************
30 ** Previous NetFlow dissector written by Matthew Smart <smart@monkey.org>
31 ** NetFlow v9 support added by same.
33 ** NetFlow v9 patches by Luca Deri <deri@ntop.org>
37 ** http://www.cisco.com/warp/public/cc/pd/iosw/prodlit/tflow_wp.htm
39 ** for NetFlow v9 information.
41 ** http://www.ietf.org/internet-drafts/draft-ietf-ipfix-info-11.txt
42 ** http://www.ietf.org/internet-drafts/draft-ietf-ipfix-protocol-19.txt
45 *****************************************************************************
47 ** this code was written from the following documentation:
49 ** http://www.cisco.com/univercd/cc/td/doc/product/rtrmgmt/nfc/nfc_3_6/iug/format.pdf
50 ** http://www.caida.org/tools/measurement/cflowd/configuration/configuration-9.html
52 ** some documentation is more accurate then others. in some cases, live data and
53 ** information contained in responses from vendors were also used. some fields
54 ** are dissected as vendor specific fields.
58 ** http://www.cisco.com/univercd/cc/td/doc/cisintwk/intsolns/netflsol/nfwhite.htm
60 ** $Yahoo: //depot/fumerola/packet-netflow/packet-netflow.c#14 $
68 #include <epan/packet.h>
71 #include <epan/prefs.h>
73 #define UDP_PORT_NETFLOW 2055
75 #define UDP_PORT_IPFIX 4739
77 static guint global_netflow_udp_port = UDP_PORT_NETFLOW;
78 static guint netflow_udp_port = 0;
79 static guint global_ipfix_port = UDP_PORT_IPFIX;
80 static guint ipfix_port = 0;
83 * pdu identifiers & sizes
86 #define V1PDU_SIZE (4 * 12)
87 #define V5PDU_SIZE (4 * 12)
88 #define V7PDU_SIZE (4 * 13)
89 #define V8PDU_AS_SIZE (4 * 7)
90 #define V8PDU_PROTO_SIZE (4 * 7)
91 #define V8PDU_SPREFIX_SIZE (4 * 8)
92 #define V8PDU_DPREFIX_SIZE (4 * 8)
93 #define V8PDU_MATRIX_SIZE (4 * 10)
94 #define V8PDU_DESTONLY_SIZE (4 * 8)
95 #define V8PDU_SRCDEST_SIZE (4 * 10)
96 #define V8PDU_FULL_SIZE (4 * 11)
97 #define V8PDU_TOSAS_SIZE (V8PDU_AS_SIZE + 4)
98 #define V8PDU_TOSPROTOPORT_SIZE (V8PDU_PROTO_SIZE + 4)
99 #define V8PDU_TOSSRCPREFIX_SIZE V8PDU_SPREFIX_SIZE
100 #define V8PDU_TOSDSTPREFIX_SIZE V8PDU_DPREFIX_SIZE
101 #define V8PDU_TOSMATRIX_SIZE V8PDU_MATRIX_SIZE
102 #define V8PDU_PREPORTPROTOCOL_SIZE (4 * 10)
104 static const value_string v5_sampling_mode[] = {
105 {0, "No sampling mode configured"},
106 {1, "Packet Interval sampling mode configured"},
114 V8PDU_SPREFIX_METHOD,
115 V8PDU_DPREFIX_METHOD,
117 V8PDU_DESTONLY_METHOD,
118 V8PDU_SRCDEST_METHOD,
121 V8PDU_TOSPROTOPORT_METHOD,
122 V8PDU_TOSSRCPREFIX_METHOD,
123 V8PDU_TOSDSTPREFIX_METHOD,
124 V8PDU_TOSMATRIX_METHOD,
125 V8PDU_PREPORTPROTOCOL_METHOD
128 static const value_string v8_agg[] = {
129 {V8PDU_AS_METHOD, "V8 AS aggregation"},
130 {V8PDU_PROTO_METHOD, "V8 Proto/Port aggregation"},
131 {V8PDU_SPREFIX_METHOD, "V8 Source Prefix aggregation"},
132 {V8PDU_DPREFIX_METHOD, "V8 Destination Prefix aggregation"},
133 {V8PDU_MATRIX_METHOD, "V8 Network Matrix aggregation"},
134 {V8PDU_DESTONLY_METHOD, "V8 Destination aggregation (Cisco Catalyst)"},
135 {V8PDU_SRCDEST_METHOD, "V8 Src/Dest aggregation (Cisco Catalyst)"},
136 {V8PDU_FULL_METHOD, "V8 Full aggregation (Cisco Catalyst)"},
137 {V8PDU_TOSAS_METHOD, "V8 TOS+AS aggregation aggregation"},
138 {V8PDU_TOSPROTOPORT_METHOD, "V8 TOS+Protocol aggregation"},
139 {V8PDU_TOSSRCPREFIX_METHOD, "V8 TOS+Source Prefix aggregation"},
140 {V8PDU_TOSDSTPREFIX_METHOD, "V8 TOS+Destination Prefix aggregation"},
141 {V8PDU_TOSMATRIX_METHOD, "V8 TOS+Prefix Matrix aggregation"},
142 {V8PDU_PREPORTPROTOCOL_METHOD, "V8 Port+Protocol aggregation"},
146 /* Version 9 template cache structures */
147 #define V9TEMPLATE_CACHE_MAX_ENTRIES 100
149 struct v9_template_entry {
160 guint16 option_template; /* 0=data template, 1=option template */
161 guint16 count_scopes;
162 struct v9_template_entry *scopes;
163 struct v9_template_entry *entries;
166 static struct v9_template v9_template_cache[V9TEMPLATE_CACHE_MAX_ENTRIES];
169 * wireshark tree identifiers
172 static int proto_netflow = -1;
173 static int ett_netflow = -1;
174 static int ett_unixtime = -1;
175 static int ett_flow = -1;
176 static int ett_flowtime = -1;
177 static int ett_template = -1;
178 static int ett_field = -1;
179 static int ett_dataflowset = -1;
185 static int hf_cflow_version = -1;
186 static int hf_cflow_count = -1;
187 static int hf_cflow_len = -1;
188 static int hf_cflow_sysuptime = -1;
189 static int hf_cflow_exporttime = -1;
190 static int hf_cflow_unix_secs = -1;
191 static int hf_cflow_unix_nsecs = -1;
192 static int hf_cflow_timestamp = -1;
193 static int hf_cflow_samplingmode = -1;
194 static int hf_cflow_samplerate = -1;
197 * cflow version specific info
199 static int hf_cflow_sequence = -1;
200 static int hf_cflow_engine_type = -1;
201 static int hf_cflow_engine_id = -1;
202 static int hf_cflow_source_id = -1;
204 static int hf_cflow_aggmethod = -1;
205 static int hf_cflow_aggversion = -1;
209 static int hf_cflow_template_flowset_id = -1;
210 static int hf_cflow_data_flowset_id = -1;
211 static int hf_cflow_data_datarecord_id = -1;
212 static int hf_cflow_options_flowset_id = -1;
213 static int hf_cflow_flowset_id = -1;
214 static int hf_cflow_flowset_length = -1;
215 static int hf_cflow_datarecord_length = -1;
216 static int hf_cflow_template_id = -1;
217 static int hf_cflow_template_field_count = -1;
218 static int hf_cflow_template_field_type = -1;
219 static int hf_cflow_template_field_length = -1;
220 static int hf_cflow_option_scope_length = -1;
221 static int hf_cflow_option_length = -1;
222 static int hf_cflow_template_scope_field_type = -1;
223 static int hf_cflow_template_scope_field_length = -1;
225 static int hf_cflow_scope_system = -1;
226 static int hf_cflow_scope_interface = -1;
227 static int hf_cflow_scope_linecard = -1;
228 static int hf_cflow_scope_cache = -1;
229 static int hf_cflow_scope_template = -1;
230 static int hf_cflow_scope_unknown = -1;
235 static int hf_cflow_srcaddr = -1;
236 static int hf_cflow_srcaddr_v6 = -1;
237 static int hf_cflow_srcnet = -1;
238 static int hf_cflow_dstaddr = -1;
239 static int hf_cflow_dstaddr_v6 = -1;
240 static int hf_cflow_dstnet = -1;
241 static int hf_cflow_nexthop = -1;
242 static int hf_cflow_nexthop_v6 = -1;
243 static int hf_cflow_bgpnexthop = -1;
244 static int hf_cflow_bgpnexthop_v6 = -1;
245 static int hf_cflow_inputint = -1;
246 static int hf_cflow_outputint = -1;
247 static int hf_cflow_flows = -1;
248 static int hf_cflow_packets = -1;
249 static int hf_cflow_packets64 = -1;
250 static int hf_cflow_packetsout = -1;
251 static int hf_cflow_octets = -1;
252 static int hf_cflow_octets64 = -1;
253 static int hf_cflow_length_min = -1;
254 static int hf_cflow_length_max = -1;
255 static int hf_cflow_timedelta = -1;
256 static int hf_cflow_timestart = -1;
257 static int hf_cflow_timeend = -1;
258 static int hf_cflow_srcport = -1;
259 static int hf_cflow_dstport = -1;
260 static int hf_cflow_prot = -1;
261 static int hf_cflow_tos = -1;
262 static int hf_cflow_flags = -1;
263 static int hf_cflow_tcpflags = -1;
264 static int hf_cflow_dstas = -1;
265 static int hf_cflow_srcas = -1;
266 static int hf_cflow_dstmask = -1;
267 static int hf_cflow_dstmask_v6 = -1;
268 static int hf_cflow_srcmask = -1;
269 static int hf_cflow_srcmask_v6 = -1;
270 static int hf_cflow_routersc = -1;
271 static int hf_cflow_mulpackets = -1;
272 static int hf_cflow_muloctets = -1;
273 static int hf_cflow_octets_exp = -1;
274 static int hf_cflow_octets_exp64 = -1;
275 static int hf_cflow_packets_exp = -1;
276 static int hf_cflow_packets_exp64 = -1;
277 static int hf_cflow_flows_exp = -1;
278 static int hf_cflow_flows_exp64 = -1;
279 static int hf_cflow_srcprefix = -1;
280 static int hf_cflow_dstprefix = -1;
281 static int hf_cflow_flow_class = -1;
282 static int hf_cflow_ttl_minimum = -1;
283 static int hf_cflow_ttl_maximum = -1;
284 static int hf_cflow_ipv4_id = -1;
285 static int hf_cflow_ip_version = -1;
286 static int hf_cflow_icmp_type = -1;
287 static int hf_cflow_igmp_type = -1;
288 static int hf_cflow_sampling_interval = -1;
289 static int hf_cflow_sampling_algorithm = -1;
290 static int hf_cflow_flow_active_timeout = -1;
291 static int hf_cflow_flow_inactive_timeout = -1;
292 static int hf_cflow_mpls_top_label_type = -1;
293 static int hf_cflow_mpls_pe_addr = -1;
294 static int hf_cflow_sampler_mode = -1;
295 static int hf_cflow_sampler_random_interval = -1;
296 static int hf_cflow_direction = -1;
297 static int hf_cflow_if_name = -1;
298 static int hf_cflow_if_descr = -1;
299 static int hf_cflow_sampler_name = -1;
300 static int hf_cflow_forwarding_status = -1;
301 static int hf_cflow_forwarding_code = -1;
302 static int hf_cflow_peer_srcas = -1;
303 static int hf_cflow_peer_dstas = -1;
304 static int hf_cflow_flow_exporter = -1;
305 static int hf_cflow_icmp_ipv4_type = -1;
306 static int hf_cflow_icmp_ipv4_code = -1;
307 static int hf_cflow_icmp_ipv6_type = -1;
308 static int hf_cflow_icmp_ipv6_code = -1;
309 static int hf_cflow_tcp_window_size = -1;
310 static int hf_cflow_ip_total_length = -1;
311 static int hf_cflow_ip_ttl = -1;
312 static int hf_cflow_ip_tos = -1;
313 static int hf_cflow_ip_dscp = -1;
314 static int hf_cflow_octets_squared64 = -1;
315 static int hf_cflow_udp_length = -1;
316 static int hf_cflow_is_multicast = -1;
317 static int hf_cflow_ip_header_words = -1;
318 static int hf_cflow_option_map = -1;
319 static int hf_cflow_section_header = -1;
320 static int hf_cflow_section_payload = -1;
322 const value_string special_mpls_top_label_type[] = {
333 proto_tree_add_mpls_label(proto_tree * pdutree, tvbuff_t * tvb, int offset, int length, int level)
336 guint8 b0 = tvb_get_guint8(tvb, offset);
337 guint8 b1 = tvb_get_guint8(tvb, offset + 1);
338 guint8 b2 = tvb_get_guint8(tvb, offset + 2);
339 proto_tree_add_text(pdutree, tvb, offset, length,
340 "MPLS-Label%d: %u exp-bits: %u %s", level,
341 ((b0<<12)+(b1<<4)+(b2>>4)),
343 ((b2&0x1)?"top-of-stack":""));
345 proto_tree_add_text(pdutree, tvb, offset, length,
346 "MPLS-Label%d: bad lengh %d", level, length);
350 void proto_reg_handoff_netflow(void);
352 typedef struct _hdrinfo_t {
354 guint32 src_id; /* SourceID in NetFlow V9, Observation Domain ID in IPFIX */
358 typedef int dissect_pdu_t(proto_tree * pdutree, tvbuff_t * tvb, int offset,
359 hdrinfo_t * hdrinfo);
361 static int dissect_pdu(proto_tree * tree, tvbuff_t * tvb, int offset,
362 hdrinfo_t * hdrinfo);
363 static int dissect_v8_aggpdu(proto_tree * pdutree, tvbuff_t * tvb,
364 int offset, hdrinfo_t * hdrinfo);
365 static int dissect_v8_flowpdu(proto_tree * pdutree, tvbuff_t * tvb,
366 int offset, hdrinfo_t * hdrinfo);
367 static int dissect_v9_flowset(proto_tree * pdutree, tvbuff_t * tvb,
368 int offset, hdrinfo_t * hdrinfo);
369 static int dissect_v9_data(proto_tree * pdutree, tvbuff_t * tvb,
370 int offset, guint16 id, guint length, hdrinfo_t * hdrinfo);
371 static void dissect_v9_pdu(proto_tree * pdutree, tvbuff_t * tvb,
372 int offset, struct v9_template * template);
373 static int dissect_v9_options(proto_tree * pdutree, tvbuff_t * tvb,
374 int offset, hdrinfo_t * hdrinfo);
375 static int dissect_v9_template(proto_tree * pdutree, tvbuff_t * tvb,
376 int offset, int len, hdrinfo_t * hdrinfo);
377 static int v9_template_hash(guint16 id, const address * net_src,
379 static void v9_template_add(struct v9_template * template);
380 static struct v9_template *v9_template_get(guint16 id, address * net_src,
382 static const char * decode_v9_template_types(int type);
384 static gchar *getprefix(const guint32 * address, int prefix);
385 static void dissect_netflow(tvbuff_t * tvb, packet_info * pinfo,
388 static int flow_process_ints(proto_tree * pdutree, tvbuff_t * tvb,
390 static int flow_process_ports(proto_tree * pdutree, tvbuff_t * tvb,
392 static int flow_process_timeperiod(proto_tree * pdutree, tvbuff_t * tvb,
394 static int flow_process_aspair(proto_tree * pdutree, tvbuff_t * tvb,
396 static int flow_process_sizecount(proto_tree * pdutree, tvbuff_t * tvb,
398 static int flow_process_textfield(proto_tree * pdutree, tvbuff_t * tvb,
399 int offset, int bytes,
404 dissect_netflow(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
406 proto_tree *netflow_tree = NULL;
408 proto_item *timeitem, *pduitem;
409 proto_tree *timetree, *pdutree;
410 unsigned int pduret, ver = 0, pdus = 0, x = 1;
413 size_t available, pdusize, offset = 0;
415 dissect_pdu_t *pduptr;
417 if (check_col(pinfo->cinfo, COL_PROTOCOL))
418 col_set_str(pinfo->cinfo, COL_PROTOCOL, "CFLOW");
419 if (check_col(pinfo->cinfo, COL_INFO))
420 col_clear(pinfo->cinfo, COL_INFO);
423 ti = proto_tree_add_item(tree, proto_netflow, tvb,
425 netflow_tree = proto_item_add_subtree(ti, ett_netflow);
428 ver = tvb_get_ntohs(tvb, offset);
432 SET_ADDRESS(&hdrinfo.net_src, pinfo->net_src.type, pinfo->net_src.len,
433 pinfo->net_src.data);
438 pdusize = V1PDU_SIZE;
439 pduptr = &dissect_pdu;
442 pdusize = V5PDU_SIZE;
443 pduptr = &dissect_pdu;
446 pdusize = V7PDU_SIZE;
447 pduptr = &dissect_pdu;
450 pdusize = -1; /* deferred */
451 pduptr = &dissect_v8_aggpdu;
455 pdusize = -1; /* deferred */
456 pduptr = &dissect_v9_flowset;
463 proto_tree_add_uint(netflow_tree, hf_cflow_version, tvb,
467 pdus = tvb_get_ntohs(tvb, offset);
470 proto_tree_add_uint(netflow_tree, hf_cflow_len, tvb,
474 proto_tree_add_uint(netflow_tree, hf_cflow_count, tvb,
482 * set something interesting in the display now that we have info
484 if (check_col(pinfo->cinfo, COL_INFO)) {
486 col_add_fstr(pinfo->cinfo, COL_INFO,
487 "total: %u (v%u) record%s", pdus, ver,
488 plurality(pdus, "", "s"));
489 } else if (ver == 10) {
490 gint remaining = tvb_length_remaining(tvb, offset)+4;
492 if(remaining == flow_len)
493 col_add_fstr(pinfo->cinfo, COL_INFO, "IPFIX flow (%d bytes)", flow_len);
495 col_add_fstr(pinfo->cinfo, COL_INFO,
496 "IPFIX partial flow (%u/%u bytes)",
497 remaining, flow_len);
499 col_add_fstr(pinfo->cinfo, COL_INFO,
500 "total: %u (v%u) flow%s", pdus, ver,
501 plurality(pdus, "", "s"));
506 * the rest is only interesting if we're displaying/searching the
513 proto_tree_add_item(netflow_tree, hf_cflow_exporttime, tvb,
517 proto_tree_add_item(netflow_tree, hf_cflow_sysuptime, tvb,
521 ts.secs = tvb_get_ntohl(tvb, offset);
522 if ((ver != 9) && (ver != 10)) {
523 ts.nsecs = tvb_get_ntohl(tvb, offset + 4);
524 timeitem = proto_tree_add_time(netflow_tree,
525 hf_cflow_timestamp, tvb, offset,
529 timeitem = proto_tree_add_time(netflow_tree,
530 hf_cflow_timestamp, tvb, offset,
534 timetree = proto_item_add_subtree(timeitem, ett_unixtime);
536 proto_tree_add_item(timetree, hf_cflow_unix_secs, tvb,
541 proto_tree_add_item(timetree, hf_cflow_unix_nsecs, tvb,
548 * version specific header
550 if (ver == 5 || ver == 7 || ver == 8 || ver == 9 || ver == 10) {
551 proto_tree_add_item(netflow_tree, hf_cflow_sequence,
552 tvb, offset, 4, FALSE);
555 if (ver == 5 || ver == 8) {
556 proto_tree_add_item(netflow_tree, hf_cflow_engine_type,
557 tvb, offset++, 1, FALSE);
558 proto_tree_add_item(netflow_tree, hf_cflow_engine_id,
559 tvb, offset++, 1, FALSE);
560 } else if ((ver == 9) || (ver == 10)) {
561 proto_tree_add_item(netflow_tree, hf_cflow_source_id,
562 tvb, offset, 4, FALSE);
563 hdrinfo.src_id = tvb_get_ntohl(tvb, offset);
567 hdrinfo.vspec = tvb_get_guint8(tvb, offset);
568 switch (hdrinfo.vspec) {
569 case V8PDU_AS_METHOD:
570 pdusize = V8PDU_AS_SIZE;
572 case V8PDU_PROTO_METHOD:
573 pdusize = V8PDU_PROTO_SIZE;
575 case V8PDU_SPREFIX_METHOD:
576 pdusize = V8PDU_SPREFIX_SIZE;
578 case V8PDU_DPREFIX_METHOD:
579 pdusize = V8PDU_DPREFIX_SIZE;
581 case V8PDU_MATRIX_METHOD:
582 pdusize = V8PDU_MATRIX_SIZE;
584 case V8PDU_DESTONLY_METHOD:
585 pdusize = V8PDU_DESTONLY_SIZE;
586 pduptr = &dissect_v8_flowpdu;
588 case V8PDU_SRCDEST_METHOD:
589 pdusize = V8PDU_SRCDEST_SIZE;
590 pduptr = &dissect_v8_flowpdu;
592 case V8PDU_FULL_METHOD:
593 pdusize = V8PDU_FULL_SIZE;
594 pduptr = &dissect_v8_flowpdu;
596 case V8PDU_TOSAS_METHOD:
597 pdusize = V8PDU_TOSAS_SIZE;
599 case V8PDU_TOSPROTOPORT_METHOD:
600 pdusize = V8PDU_TOSPROTOPORT_SIZE;
602 case V8PDU_TOSSRCPREFIX_METHOD:
603 pdusize = V8PDU_TOSSRCPREFIX_SIZE;
605 case V8PDU_TOSDSTPREFIX_METHOD:
606 pdusize = V8PDU_TOSDSTPREFIX_SIZE;
608 case V8PDU_TOSMATRIX_METHOD:
609 pdusize = V8PDU_TOSMATRIX_SIZE;
611 case V8PDU_PREPORTPROTOCOL_METHOD:
612 pdusize = V8PDU_PREPORTPROTOCOL_SIZE;
619 proto_tree_add_uint(netflow_tree, hf_cflow_aggmethod,
620 tvb, offset++, 1, hdrinfo.vspec);
621 proto_tree_add_item(netflow_tree, hf_cflow_aggversion,
622 tvb, offset++, 1, FALSE);
624 if (ver == 7 || ver == 8)
625 offset = flow_process_textfield(netflow_tree, tvb, offset, 4,
628 proto_tree_add_item(netflow_tree, hf_cflow_samplingmode,
629 tvb, offset, 2, FALSE);
630 proto_tree_add_item(netflow_tree, hf_cflow_samplerate,
631 tvb, offset, 2, FALSE);
635 if (pdus <= 0) { /* no payload to decode - in theory */
636 /* This is absurd, but does happens in practice. */
637 proto_tree_add_text(netflow_tree, tvb, offset, tvb_length_remaining(tvb, offset),
638 "FlowSets impossibles - PDU Count is %d", pdus);
642 * everything below here should be payload
644 for (x = 1; x < pdus + 1; x++) {
646 * make sure we have a pdu's worth of data
648 available = tvb_length_remaining(tvb, offset);
649 if(((ver == 9) || (ver == 10)) && available >= 4) {
650 /* pdusize can be different for each v9 flowset */
651 pdusize = tvb_get_ntohs(tvb, offset + 2);
654 if (available < pdusize)
657 if ((ver == 9) || (ver == 10)) {
658 pduitem = proto_tree_add_text(netflow_tree, tvb,
660 (ver == 9) ? "FlowSet %u" : "DataRecord %u", x);
662 pduitem = proto_tree_add_text(netflow_tree, tvb,
663 offset, pdusize, "pdu %u/%u", x, pdus);
665 pdutree = proto_item_add_subtree(pduitem, ett_flow);
667 pduret = pduptr(pdutree, tvb, offset, &hdrinfo);
669 if (pduret < pdusize) pduret = pdusize; /* padding */
672 * if we came up short, stop processing
674 if (pduret == pdusize)
682 * flow_process_* == common groups of fields, probably could be inline
686 flow_process_ints(proto_tree * pdutree, tvbuff_t * tvb, int offset)
688 proto_tree_add_item(pdutree, hf_cflow_inputint, tvb, offset, 2, FALSE);
691 proto_tree_add_item(pdutree, hf_cflow_outputint, tvb, offset, 2,
699 flow_process_ports(proto_tree * pdutree, tvbuff_t * tvb, int offset)
701 proto_tree_add_item(pdutree, hf_cflow_srcport, tvb, offset, 2, FALSE);
704 proto_tree_add_item(pdutree, hf_cflow_dstport, tvb, offset, 2, FALSE);
711 flow_process_timeperiod(proto_tree * pdutree, tvbuff_t * tvb, int offset)
713 nstime_t ts_start, ts_end;
714 int offset_s, offset_e;
716 guint32 msec_start, msec_end;
718 proto_tree * timetree = 0;
719 proto_item * timeitem = 0;
722 msec_start = tvb_get_ntohl(tvb, offset);
723 ts_start.secs = msec_start / 1000;
724 ts_start.nsecs = (msec_start % 1000) * 1000000;
728 msec_end = tvb_get_ntohl(tvb, offset);
729 ts_end.secs = msec_end / 1000;
730 ts_end.nsecs = (msec_end % 1000) * 1000000;
734 msec_delta = msec_end - msec_start;
735 ts_delta.secs = msec_delta / 1000;
736 ts_delta.nsecs = (msec_delta % 1000) * 1000000;
739 timeitem = proto_tree_add_time(pdutree, hf_cflow_timedelta, tvb,
740 offset_s, 8, &ts_delta);
741 timetree = proto_item_add_subtree(timeitem, ett_flowtime);
743 proto_tree_add_time(timetree, hf_cflow_timestart, tvb, offset_s, 4,
745 proto_tree_add_time(timetree, hf_cflow_timeend, tvb, offset_e, 4,
753 flow_process_aspair(proto_tree * pdutree, tvbuff_t * tvb, int offset)
755 proto_tree_add_item(pdutree, hf_cflow_srcas, tvb, offset, 2, FALSE);
758 proto_tree_add_item(pdutree, hf_cflow_dstas, tvb, offset, 2, FALSE);
765 flow_process_sizecount(proto_tree * pdutree, tvbuff_t * tvb, int offset)
767 proto_tree_add_item(pdutree, hf_cflow_packets, tvb, offset, 4, FALSE);
770 proto_tree_add_item(pdutree, hf_cflow_octets, tvb, offset, 4, FALSE);
777 flow_process_textfield(proto_tree * pdutree, tvbuff_t * tvb, int offset,
778 int bytes, const char *text)
780 proto_tree_add_text(pdutree, tvb, offset, bytes, text);
787 dissect_v8_flowpdu(proto_tree * pdutree, tvbuff_t * tvb, int offset,
790 int startoffset = offset;
793 proto_tree_add_item(pdutree, hf_cflow_dstaddr, tvb, offset, 4, FALSE);
796 verspec = hdrinfo->vspec;
798 if (verspec != V8PDU_DESTONLY_METHOD) {
799 proto_tree_add_item(pdutree, hf_cflow_srcaddr, tvb, offset, 4,
803 if (verspec == V8PDU_FULL_METHOD) {
804 proto_tree_add_item(pdutree, hf_cflow_dstport, tvb, offset, 2,
807 proto_tree_add_item(pdutree, hf_cflow_srcport, tvb, offset, 2,
812 offset = flow_process_sizecount(pdutree, tvb, offset);
813 offset = flow_process_timeperiod(pdutree, tvb, offset);
815 proto_tree_add_item(pdutree, hf_cflow_outputint, tvb, offset, 2,
819 if (verspec != V8PDU_DESTONLY_METHOD) {
820 proto_tree_add_item(pdutree, hf_cflow_inputint, tvb, offset, 2,
825 proto_tree_add_item(pdutree, hf_cflow_tos, tvb, offset++, 1, FALSE);
826 if (verspec == V8PDU_FULL_METHOD)
827 proto_tree_add_item(pdutree, hf_cflow_prot, tvb, offset++, 1,
829 offset = flow_process_textfield(pdutree, tvb, offset, 1, "marked tos");
831 if (verspec == V8PDU_SRCDEST_METHOD)
833 flow_process_textfield(pdutree, tvb, offset, 2,
835 else if (verspec == V8PDU_FULL_METHOD)
837 flow_process_textfield(pdutree, tvb, offset, 1, "padding");
840 flow_process_textfield(pdutree, tvb, offset, 4, "extra packets");
842 proto_tree_add_item(pdutree, hf_cflow_routersc, tvb, offset, 4, FALSE);
845 return (offset - startoffset);
849 * dissect a version 8 pdu, returning the length of the pdu processed
853 dissect_v8_aggpdu(proto_tree * pdutree, tvbuff_t * tvb, int offset,
856 int startoffset = offset;
859 proto_tree_add_item(pdutree, hf_cflow_flows, tvb, offset, 4, FALSE);
862 offset = flow_process_sizecount(pdutree, tvb, offset);
863 offset = flow_process_timeperiod(pdutree, tvb, offset);
865 verspec = hdrinfo->vspec;
868 case V8PDU_AS_METHOD:
869 case V8PDU_TOSAS_METHOD:
870 offset = flow_process_aspair(pdutree, tvb, offset);
872 if (verspec == V8PDU_TOSAS_METHOD) {
873 proto_tree_add_item(pdutree, hf_cflow_tos, tvb,
876 flow_process_textfield(pdutree, tvb, offset, 1,
879 flow_process_textfield(pdutree, tvb, offset, 2,
883 case V8PDU_PROTO_METHOD:
884 case V8PDU_TOSPROTOPORT_METHOD:
885 proto_tree_add_item(pdutree, hf_cflow_prot, tvb, offset++, 1,
888 if (verspec == V8PDU_PROTO_METHOD)
890 flow_process_textfield(pdutree, tvb, offset, 1,
892 else if (verspec == V8PDU_TOSPROTOPORT_METHOD)
893 proto_tree_add_item(pdutree, hf_cflow_tos, tvb,
897 flow_process_textfield(pdutree, tvb, offset, 2,
899 offset = flow_process_ports(pdutree, tvb, offset);
901 if (verspec == V8PDU_TOSPROTOPORT_METHOD)
902 offset = flow_process_ints(pdutree, tvb, offset);
904 case V8PDU_SPREFIX_METHOD:
905 case V8PDU_DPREFIX_METHOD:
906 case V8PDU_TOSSRCPREFIX_METHOD:
907 case V8PDU_TOSDSTPREFIX_METHOD:
908 proto_tree_add_item(pdutree,
910 V8PDU_SPREFIX_METHOD ?
911 hf_cflow_srcnet : hf_cflow_dstnet, tvb,
915 proto_tree_add_item(pdutree,
917 V8PDU_SPREFIX_METHOD ?
918 hf_cflow_srcmask : hf_cflow_dstmask, tvb,
921 if (verspec == V8PDU_SPREFIX_METHOD
922 || verspec == V8PDU_DPREFIX_METHOD)
924 flow_process_textfield(pdutree, tvb, offset, 1,
926 else if (verspec == V8PDU_TOSSRCPREFIX_METHOD
927 || verspec == V8PDU_TOSDSTPREFIX_METHOD)
928 proto_tree_add_item(pdutree, hf_cflow_tos, tvb,
931 proto_tree_add_item(pdutree,
933 V8PDU_SPREFIX_METHOD ? hf_cflow_srcas
934 : hf_cflow_dstas, tvb, offset, 2, FALSE);
937 proto_tree_add_item(pdutree,
939 V8PDU_SPREFIX_METHOD ?
940 hf_cflow_inputint : hf_cflow_outputint,
941 tvb, offset, 2, FALSE);
945 flow_process_textfield(pdutree, tvb, offset, 2,
948 case V8PDU_MATRIX_METHOD:
949 case V8PDU_TOSMATRIX_METHOD:
950 case V8PDU_PREPORTPROTOCOL_METHOD:
951 proto_tree_add_item(pdutree, hf_cflow_srcnet, tvb, offset, 4,
955 proto_tree_add_item(pdutree, hf_cflow_dstnet, tvb, offset, 4,
959 proto_tree_add_item(pdutree, hf_cflow_srcmask, tvb, offset++,
962 proto_tree_add_item(pdutree, hf_cflow_dstmask, tvb, offset++,
965 if (verspec == V8PDU_TOSMATRIX_METHOD ||
966 verspec == V8PDU_PREPORTPROTOCOL_METHOD) {
967 proto_tree_add_item(pdutree, hf_cflow_tos, tvb,
969 if (verspec == V8PDU_TOSMATRIX_METHOD) {
971 flow_process_textfield(pdutree, tvb,
974 } else if (verspec == V8PDU_PREPORTPROTOCOL_METHOD) {
975 proto_tree_add_item(pdutree, hf_cflow_prot,
976 tvb, offset++, 1, FALSE);
980 flow_process_textfield(pdutree, tvb, offset, 2,
984 if (verspec == V8PDU_MATRIX_METHOD
985 || verspec == V8PDU_TOSMATRIX_METHOD) {
986 offset = flow_process_aspair(pdutree, tvb, offset);
987 } else if (verspec == V8PDU_PREPORTPROTOCOL_METHOD) {
988 offset = flow_process_ports(pdutree, tvb, offset);
991 offset = flow_process_ints(pdutree, tvb, offset);
996 return (offset - startoffset);
999 /* Dissect a version 9 FlowSet and return the length we processed. */
1002 dissect_v9_flowset(proto_tree * pdutree, tvbuff_t * tvb, int offset, hdrinfo_t * hdrinfo)
1008 ver = hdrinfo->vspec;
1010 if ((ver != 9) && (ver != 10))
1013 flowset_id = tvb_get_ntohs(tvb, offset);
1014 if ((flowset_id == 0) || (flowset_id == 2)) {
1016 proto_tree_add_item(pdutree, hf_cflow_template_flowset_id, tvb,
1020 length = tvb_get_ntohs(tvb, offset);
1021 proto_tree_add_item(pdutree, hf_cflow_flowset_length, tvb,
1025 dissect_v9_template(pdutree, tvb, offset, length - 4, hdrinfo);
1026 } else if ((flowset_id == 1) || (flowset_id == 3)) {
1028 proto_tree_add_item(pdutree, hf_cflow_options_flowset_id, tvb,
1032 length = tvb_get_ntohs(tvb, offset);
1033 proto_tree_add_item(pdutree, hf_cflow_flowset_length, tvb,
1037 dissect_v9_options(pdutree, tvb, offset, hdrinfo);
1038 } else if (flowset_id >= 4 && flowset_id <= 255) {
1040 proto_tree_add_item(pdutree, hf_cflow_flowset_id, tvb,
1044 length = tvb_get_ntohs(tvb, offset);
1045 proto_tree_add_item(pdutree, hf_cflow_flowset_length, tvb,
1050 proto_tree_add_item(pdutree, (ver == 9) ? hf_cflow_data_flowset_id : hf_cflow_data_datarecord_id, tvb,
1054 length = tvb_get_ntohs(tvb, offset);
1055 proto_tree_add_item(pdutree, (ver == 9) ? hf_cflow_flowset_length : hf_cflow_datarecord_length, tvb,
1060 * The length includes the length of the FlowSet ID and
1061 * the length field itself.
1065 dissect_v9_data(pdutree, tvb, offset, flowset_id,
1066 (guint)length, hdrinfo);
1074 dissect_v9_data(proto_tree * pdutree, tvbuff_t * tvb, int offset,
1075 guint16 id, guint length, hdrinfo_t * hdrinfo)
1077 struct v9_template *template;
1078 proto_tree *data_tree;
1079 proto_item *data_item;
1081 template = v9_template_get(id, &hdrinfo->net_src, hdrinfo->src_id);
1082 if (template != NULL && template->length != 0) {
1085 while (length >= template->length) {
1086 data_item = proto_tree_add_text(pdutree, tvb,
1087 offset, template->length, "Flow %d", count++);
1088 data_tree = proto_item_add_subtree(data_item,
1091 dissect_v9_pdu(data_tree, tvb, offset, template);
1093 offset += template->length;
1094 length -= template->length;
1097 proto_tree_add_text(pdutree, tvb, offset, length,
1098 "Padding (%u byte%s)",
1099 length, plurality(length, "", "s"));
1102 proto_tree_add_text(pdutree, tvb, offset, length,
1103 "Data (%u byte%s), no template found",
1104 length, plurality(length, "", "s"));
1111 dissect_v9_pdu(proto_tree * pdutree, tvbuff_t * tvb, int offset,
1112 struct v9_template * template)
1115 nstime_t ts_start, ts_end;
1116 int offset_s = 0, offset_e = 0;
1118 guint32 msec_start = 0, msec_end = 0;
1120 proto_tree * timetree = 0;
1121 proto_item * timeitem = 0;
1123 if( (template->count_scopes > 0) && (template->scopes != NULL)) {
1124 for(i = 0; i < template->count_scopes; i++) {
1125 guint16 type = template->scopes[i].type;
1126 guint16 length = template->scopes[i].length;
1128 case 1: /* system */
1130 proto_tree_add_item(pdutree, hf_cflow_scope_system,
1131 tvb, offset, length, FALSE);
1133 proto_tree_add_text(pdutree,
1134 tvb, offset, length,
1135 "ScopeSystem: invalid size %d", length );
1138 case 2: /* interface */
1140 proto_tree_add_item(pdutree, hf_cflow_scope_interface,
1141 tvb, offset, length, FALSE);
1143 proto_tree_add_text(pdutree,
1144 tvb, offset, length,
1145 "ScopeInterface: invalid size %d", length );
1148 case 3: /* linecard */
1149 proto_tree_add_item(pdutree, hf_cflow_scope_linecard,
1150 tvb, offset, length, FALSE);
1152 case 4: /* netflow cache */
1153 proto_tree_add_item(pdutree, hf_cflow_scope_cache,
1154 tvb, offset, length, FALSE);
1156 case 5: /* template */
1157 proto_tree_add_item(pdutree, hf_cflow_scope_template,
1158 tvb, offset, length, FALSE);
1160 default: /* unknown */
1161 proto_tree_add_item(pdutree, hf_cflow_scope_unknown,
1162 tvb, offset, length, FALSE);
1169 for (i = 0; i < template->count; i++) {
1170 guint16 type, length;
1172 type = template->entries[i].type;
1173 length = template->entries[i].length;
1177 case 85: /* BYTES_PERMANENT */
1180 proto_tree_add_item(pdutree, hf_cflow_octets,
1181 tvb, offset, length, FALSE);
1182 } else if (length == 8) {
1183 proto_tree_add_item(pdutree, hf_cflow_octets64,
1184 tvb, offset, length, FALSE);
1186 proto_tree_add_text(pdutree,
1187 tvb, offset, length,
1188 "Octets: length %u", length);
1192 case 86: /* PACKETS_PERMANENT */
1193 case 2: /* packets */
1195 proto_tree_add_item(pdutree, hf_cflow_packets,
1196 tvb, offset, length, FALSE);
1197 } else if (length == 8) {
1198 proto_tree_add_item(pdutree, hf_cflow_packets64,
1199 tvb, offset, length, FALSE);
1201 proto_tree_add_text(pdutree,
1202 tvb, offset, length,
1203 "Packets: length %u", length);
1209 proto_tree_add_item(pdutree, hf_cflow_flows,
1210 tvb, offset, length, FALSE);
1212 proto_tree_add_text(pdutree,
1213 tvb, offset, length,
1214 "Flows: length %u", length);
1219 proto_tree_add_item(pdutree, hf_cflow_prot,
1220 tvb, offset, length, FALSE);
1224 proto_tree_add_item(pdutree, hf_cflow_tos,
1225 tvb, offset, length, FALSE);
1228 case 6: /* TCP flags */
1229 proto_tree_add_item(pdutree, hf_cflow_tcpflags,
1230 tvb, offset, length, FALSE);
1233 case 7: /* source port */
1234 proto_tree_add_item(pdutree, hf_cflow_srcport,
1235 tvb, offset, length, FALSE);
1238 case 8: /* source IP */
1240 proto_tree_add_item(pdutree, hf_cflow_srcaddr,
1241 tvb, offset, length, FALSE);
1242 } else if (length == 16) {
1243 proto_tree_add_item(pdutree, hf_cflow_srcaddr_v6,
1244 tvb, offset, length, FALSE);
1246 proto_tree_add_text(pdutree,
1247 tvb, offset, length,
1248 "SrcAddr: length %u", length);
1252 case 9: /* source mask */
1253 proto_tree_add_item(pdutree, hf_cflow_srcmask,
1254 tvb, offset, length, FALSE);
1257 case 10: /* input SNMP */
1258 proto_tree_add_item(pdutree, hf_cflow_inputint,
1259 tvb, offset, length, FALSE);
1262 case 11: /* dest port */
1263 proto_tree_add_item(pdutree, hf_cflow_dstport,
1264 tvb, offset, length, FALSE);
1267 case 12: /* dest IP */
1269 proto_tree_add_item(pdutree, hf_cflow_dstaddr,
1270 tvb, offset, length, FALSE);
1271 } else if (length == 16) {
1272 proto_tree_add_item(pdutree, hf_cflow_dstaddr_v6,
1273 tvb, offset, length, FALSE);
1275 proto_tree_add_text(pdutree,
1276 tvb, offset, length,
1277 "DstAddr: length %u", length);
1281 case 13: /* dest mask */
1282 proto_tree_add_item(pdutree, hf_cflow_dstmask,
1283 tvb, offset, length, FALSE);
1286 case 14: /* output SNMP */
1287 proto_tree_add_item(pdutree, hf_cflow_outputint,
1288 tvb, offset, length, FALSE);
1291 case 15: /* nexthop IP */
1293 proto_tree_add_item(pdutree, hf_cflow_nexthop,
1294 tvb, offset, length, FALSE);
1295 } else if (length == 16) {
1296 proto_tree_add_item(pdutree, hf_cflow_nexthop_v6,
1297 tvb, offset, length, FALSE);
1299 proto_tree_add_text(pdutree,
1300 tvb, offset, length,
1301 "NextHop: length %u", length);
1305 case 16: /* source AS */
1306 proto_tree_add_item(pdutree, hf_cflow_srcas,
1307 tvb, offset, length, FALSE);
1310 case 17: /* dest AS */
1311 proto_tree_add_item(pdutree, hf_cflow_dstas,
1312 tvb, offset, length, FALSE);
1315 case 18: /* BGP nexthop IP */
1317 proto_tree_add_item(pdutree, hf_cflow_bgpnexthop,
1318 tvb, offset, length, FALSE);
1319 } else if (length == 16) {
1320 proto_tree_add_item(pdutree, hf_cflow_bgpnexthop_v6,
1321 tvb, offset, length, FALSE);
1323 proto_tree_add_text(pdutree,
1324 tvb, offset, length,
1325 "BGPNextHop: length %u", length);
1329 case 19: /* multicast packets */
1330 proto_tree_add_item(pdutree, hf_cflow_mulpackets,
1331 tvb, offset, length, FALSE);
1334 case 20: /* multicast octets */
1335 proto_tree_add_item(pdutree, hf_cflow_muloctets,
1336 tvb, offset, length, FALSE);
1339 case 22: /* first switched */
1340 case 21: /* last switched */
1343 msec_start = tvb_get_ntohl(tvb, offset);
1344 ts_start.secs = msec_start / 1000;
1345 ts_start.nsecs = (msec_start % 1000) * 1000000;
1348 msec_end = tvb_get_ntohl(tvb, offset);
1349 ts_end.secs = msec_end / 1000;
1350 ts_end.nsecs = (msec_end % 1000) * 1000000;
1352 if(offset_s && offset_e) {
1353 msec_delta = msec_end - msec_start;
1354 ts_delta.secs = msec_delta / 1000;
1355 ts_delta.nsecs = (msec_delta % 1000) * 1000000;
1358 proto_tree_add_time(pdutree, hf_cflow_timedelta, tvb,
1359 offset_s, 0, &ts_delta);
1360 timetree = proto_item_add_subtree(timeitem, ett_flowtime);
1362 proto_tree_add_time(timetree, hf_cflow_timestart, tvb,
1363 offset_s, 4, &ts_start);
1364 proto_tree_add_time(timetree, hf_cflow_timeend, tvb,
1365 offset_e, 4, &ts_end);
1369 case 25: /* length_min */
1370 proto_tree_add_item(pdutree, hf_cflow_length_min,
1371 tvb, offset, length, FALSE);
1374 case 26: /* length_max */
1375 proto_tree_add_item(pdutree, hf_cflow_length_max,
1376 tvb, offset, length, FALSE);
1379 case 27: /* IPv6 src addr */
1380 proto_tree_add_item(pdutree, hf_cflow_srcaddr_v6,
1381 tvb, offset, length, FALSE);
1384 case 28: /* IPv6 dst addr */
1385 proto_tree_add_item(pdutree, hf_cflow_dstaddr_v6,
1386 tvb, offset, length, FALSE);
1389 case 29: /* IPv6 src addr mask */
1390 proto_tree_add_item(pdutree, hf_cflow_srcmask_v6,
1391 tvb, offset, length, FALSE);
1394 case 30: /* IPv6 dst addr mask */
1395 proto_tree_add_item(pdutree, hf_cflow_dstmask_v6,
1396 tvb, offset, length, FALSE);
1399 case 32: /* ICMP_TYPE */
1400 proto_tree_add_item(pdutree, hf_cflow_icmp_type,
1401 tvb, offset, length, FALSE);
1404 case 33: /* IGMP_TYPE */
1405 proto_tree_add_item(pdutree, hf_cflow_igmp_type,
1406 tvb, offset, length, FALSE);
1409 case 34: /* sampling interval */
1410 proto_tree_add_item(pdutree, hf_cflow_sampling_interval,
1411 tvb, offset, length, FALSE);
1414 case 35: /* sampling algorithm */
1415 proto_tree_add_item(pdutree, hf_cflow_sampling_algorithm,
1416 tvb, offset, length, FALSE);
1419 case 36: /* flow active timeout */
1420 proto_tree_add_item(pdutree, hf_cflow_flow_active_timeout,
1421 tvb, offset, length, FALSE);
1424 case 37: /* flow inactive timeout */
1425 proto_tree_add_item(pdutree, hf_cflow_flow_inactive_timeout,
1426 tvb, offset, length, FALSE);
1429 case 40: /* bytes exported */
1431 proto_tree_add_item(pdutree, hf_cflow_octets_exp64,
1432 tvb, offset, length, FALSE);
1434 proto_tree_add_item(pdutree, hf_cflow_octets_exp,
1435 tvb, offset, length, FALSE);
1439 case 41: /* packets exported */
1441 proto_tree_add_item(pdutree, hf_cflow_packets_exp64,
1442 tvb, offset, length, FALSE);
1444 proto_tree_add_item(pdutree, hf_cflow_packets_exp,
1445 tvb, offset, length, FALSE);
1449 case 42: /* flows exported */
1451 proto_tree_add_item(pdutree, hf_cflow_flows_exp64,
1452 tvb, offset, length, FALSE);
1454 proto_tree_add_item(pdutree, hf_cflow_flows_exp,
1455 tvb, offset, length, FALSE);
1459 case 44: /* IP source prefix */
1461 proto_tree_add_item(pdutree, hf_cflow_srcprefix,
1462 tvb, offset, length, FALSE);
1464 proto_tree_add_text(pdutree, tvb, offset, length,
1465 "SrcPrefix: length %u", length);
1469 case 45: /* IP destination prefix */
1471 proto_tree_add_item(pdutree, hf_cflow_dstprefix,
1472 tvb, offset, length, FALSE);
1474 proto_tree_add_text(pdutree, tvb, offset, length,
1475 "DstPrefix: length %u", length);
1479 case 46: /* top MPLS label type*/
1480 proto_tree_add_item(pdutree, hf_cflow_mpls_top_label_type,
1481 tvb, offset, length, FALSE);
1484 case 47: /* top MPLS label PE address*/
1485 proto_tree_add_item(pdutree, hf_cflow_mpls_pe_addr,
1486 tvb, offset, length, FALSE);
1489 case 48: /* Flow Sampler ID */
1490 proto_tree_add_text(pdutree, tvb, offset, length,
1491 "FlowSamplerID: %d", tvb_get_guint8(tvb, offset));
1494 case 49: /* FLOW_SAMPLER_MODE */
1495 proto_tree_add_item(pdutree, hf_cflow_sampler_mode,
1496 tvb, offset, length, FALSE);
1499 case 50: /* FLOW_SAMPLER_RANDOM_INTERVAL */
1500 proto_tree_add_item(pdutree, hf_cflow_sampler_random_interval,
1501 tvb, offset, length, FALSE);
1504 case 51: /* FLOW_CLASS */
1505 proto_tree_add_item(pdutree, hf_cflow_flow_class,
1506 tvb, offset, length, FALSE);
1509 case 52: /* TTL_MINIMUM */
1510 proto_tree_add_item(pdutree, hf_cflow_ttl_minimum,
1511 tvb, offset, length, FALSE);
1514 case 53: /* TTL_MAXIMUM */
1515 proto_tree_add_item(pdutree, hf_cflow_ttl_maximum,
1516 tvb, offset, length, FALSE);
1519 case 54: /* IPV4_ID */
1520 proto_tree_add_item(pdutree, hf_cflow_ipv4_id,
1521 tvb, offset, length, FALSE);
1524 case 60: /* IP_VERSION */
1525 proto_tree_add_item(pdutree, hf_cflow_ip_version,
1526 tvb, offset, length, FALSE);
1529 case 61: /* DIRECTION */
1530 proto_tree_add_item(pdutree, hf_cflow_direction,
1531 tvb, offset, length, FALSE);
1534 case 62: /* IPv6 BGP nexthop */
1535 proto_tree_add_item(pdutree, hf_cflow_bgpnexthop_v6,
1536 tvb, offset, length, FALSE);
1539 case 70: /* MPLS label1*/
1540 proto_tree_add_mpls_label(pdutree, tvb, offset, length, 1);
1543 case 71: /* MPLS label2*/
1544 proto_tree_add_mpls_label(pdutree, tvb, offset, length, 2);
1547 case 72: /* MPLS label3*/
1548 proto_tree_add_mpls_label(pdutree, tvb, offset, length, 3);
1551 case 73: /* MPLS label4*/
1552 proto_tree_add_mpls_label(pdutree, tvb, offset, length, 4);
1555 case 82: /* IF_NAME */
1556 proto_tree_add_item(pdutree, hf_cflow_if_name,
1557 tvb, offset, length, FALSE);
1560 case 83: /* IF_DESCR */
1561 proto_tree_add_item(pdutree, hf_cflow_if_descr,
1562 tvb, offset, length, FALSE);
1565 case 84: /* SAMPLER_NAME */
1566 proto_tree_add_item(pdutree, hf_cflow_sampler_name,
1567 tvb, offset, length, FALSE);
1570 case 89: /* FORWARDING_STATUS */
1571 proto_tree_add_item(pdutree, hf_cflow_forwarding_status,
1572 tvb, offset, length, FALSE);
1573 proto_tree_add_item(pdutree, hf_cflow_forwarding_code,
1574 tvb, offset, length, FALSE);
1577 case 128: /* source AS Peer */
1578 proto_tree_add_item(pdutree, hf_cflow_peer_srcas,
1579 tvb, offset, length, FALSE);
1582 case 129: /* dest AS Peer*/
1583 proto_tree_add_item(pdutree, hf_cflow_peer_dstas,
1584 tvb, offset, length, FALSE);
1587 case 144: /* FLOW EXPORTER */
1588 proto_tree_add_item(pdutree, hf_cflow_flow_exporter,
1589 tvb, offset, length, FALSE);
1592 case 176: /* ICMP_IPv4_TYPE */
1593 proto_tree_add_item(pdutree, hf_cflow_icmp_ipv4_type,
1594 tvb, offset, length, FALSE);
1597 case 177: /* ICMP_IPv4_CODE */
1598 proto_tree_add_item(pdutree, hf_cflow_icmp_ipv4_code,
1599 tvb, offset, length, FALSE);
1602 case 178: /* ICMP_IPv6_TYPE */
1603 proto_tree_add_item(pdutree, hf_cflow_icmp_ipv6_type,
1604 tvb, offset, length, FALSE);
1607 case 179: /* ICMP_IPv6_CODE */
1608 proto_tree_add_item(pdutree, hf_cflow_icmp_ipv6_code,
1609 tvb, offset, length, FALSE);
1612 case 186: /* TCP_WINDOWS_SIZE */
1613 proto_tree_add_item(pdutree, hf_cflow_tcp_window_size,
1614 tvb, offset, length, FALSE);
1617 case 190: /* IP_TOTAL_LENGTH */
1618 proto_tree_add_item(pdutree, hf_cflow_ip_total_length,
1619 tvb, offset, length, FALSE);
1622 case 192: /* IP_TTL */
1623 proto_tree_add_item(pdutree, hf_cflow_ip_ttl,
1624 tvb, offset, length, FALSE);
1627 case 194: /* IP_TOS */
1628 proto_tree_add_item(pdutree, hf_cflow_ip_tos,
1629 tvb, offset, length, FALSE);
1632 case 195: /* IP_DSCP */
1633 proto_tree_add_item(pdutree, hf_cflow_ip_dscp,
1634 tvb, offset, length, FALSE);
1637 case 198: /* BYTES_SQUARED */
1638 case 199: /* BYTES_SQUARED_PERMANENT */
1640 proto_tree_add_item(pdutree, hf_cflow_octets_squared64,
1641 tvb, offset, length, FALSE);
1643 proto_tree_add_text(pdutree, tvb, offset, length,
1644 "Bytes Squared: length %u", length);
1648 case 205: /* UDP_LENGTH */
1649 proto_tree_add_item(pdutree, hf_cflow_udp_length,
1650 tvb, offset, length, FALSE);
1653 case 206: /* IS_MULTICAST */
1654 proto_tree_add_item(pdutree, hf_cflow_is_multicast,
1655 tvb, offset, length, FALSE);
1658 case 207: /* IP_HEADER_WORDS */
1659 proto_tree_add_item(pdutree, hf_cflow_ip_header_words,
1660 tvb, offset, length, FALSE);
1663 case 208: /* OPTION_MAP */
1664 proto_tree_add_item(pdutree, hf_cflow_option_map,
1665 tvb, offset, length, FALSE);
1668 case 313: /* SECTION_HEADER */
1669 proto_tree_add_item(pdutree, hf_cflow_section_header,
1670 tvb, offset, length, FALSE);
1673 case 314: /* SECTION_PAYLOAD */
1674 proto_tree_add_item(pdutree, hf_cflow_section_payload,
1675 tvb, offset, length, FALSE);
1679 proto_tree_add_text(pdutree, tvb, offset, length,
1680 "Type %u %s", type, decode_v9_template_types(type));
1686 if (!(offset_s && offset_e)) {
1688 proto_tree_add_time(pdutree, hf_cflow_timestart, tvb,
1689 offset_s, 4, &ts_start);
1692 proto_tree_add_time(pdutree, hf_cflow_timeend, tvb,
1693 offset_e, 4, &ts_end);
1700 dissect_v9_options(proto_tree * pdutree, tvbuff_t * tvb, int offset, hdrinfo_t * hdrinfo)
1702 guint16 length, option_scope_len, option_len, i, id, size;
1703 struct v9_template template;
1704 int template_offset;
1707 id = tvb_get_ntohs(tvb, offset);
1708 proto_tree_add_item(pdutree, hf_cflow_template_id, tvb,
1712 option_scope_len = length = tvb_get_ntohs(tvb, offset);
1713 proto_tree_add_item(pdutree, hf_cflow_option_scope_length, tvb,
1717 option_len = length = tvb_get_ntohs(tvb, offset);
1718 proto_tree_add_item(pdutree, hf_cflow_option_length, tvb,
1722 scopes_offset = offset;
1724 for(i=0; i<option_scope_len; i++) {
1725 length = tvb_get_ntohs(tvb, offset);
1726 proto_tree_add_item(pdutree, hf_cflow_template_scope_field_type, tvb,
1728 offset += 2; i += 2;
1730 length = tvb_get_ntohs(tvb, offset);
1731 proto_tree_add_item(pdutree, hf_cflow_template_scope_field_length, tvb,
1733 offset += 2; i += 2;
1736 template_offset = offset;
1738 for(i=0; i<option_len;) {
1739 length = tvb_get_ntohs(tvb, offset);
1740 proto_tree_add_item(pdutree, hf_cflow_template_field_type, tvb,
1742 offset += 2; i += 2;
1744 length = tvb_get_ntohs(tvb, offset);
1745 proto_tree_add_item(pdutree, hf_cflow_template_field_length, tvb,
1747 offset += 2; i += 2;
1750 /* Cache template */
1751 memset(&template, 0, sizeof(template));
1753 template.count = option_len/4;
1754 SE_COPY_ADDRESS(&template.source_addr, &hdrinfo->net_src);
1755 template.source_id = hdrinfo->src_id;
1757 template.count_scopes = option_scope_len/4;
1758 size = template.count_scopes * sizeof(struct v9_template_entry);
1759 template.scopes = g_malloc( size );
1760 tvb_memcpy(tvb, (guint8 *)template.scopes, scopes_offset, size);
1762 template.option_template = 1; /* Option template */
1763 size = template.count * sizeof(struct v9_template_entry);
1764 template.entries = g_malloc(size);
1765 tvb_memcpy(tvb, (guint8 *)template.entries, template_offset, size);
1767 v9_template_add(&template);
1773 dissect_v9_template(proto_tree * pdutree, tvbuff_t * tvb, int offset, int len, hdrinfo_t * hdrinfo)
1775 struct v9_template template;
1776 proto_tree *template_tree;
1777 proto_item *template_item;
1778 proto_tree *field_tree;
1779 proto_item *field_item;
1781 int remaining = len;
1784 while (remaining > 0) {
1786 id = tvb_get_ntohs(tvb, offset);
1787 count = tvb_get_ntohs(tvb, offset + 2);
1789 template_item = proto_tree_add_text(pdutree, tvb, offset,
1790 4 + sizeof(struct v9_template_entry) * count,
1791 "Template (Id = %u, Count = %u)", id, count);
1792 template_tree = proto_item_add_subtree(template_item, ett_template);
1794 proto_tree_add_item(template_tree, hf_cflow_template_id, tvb,
1798 proto_tree_add_item(template_tree, hf_cflow_template_field_count,
1799 tvb, offset, 2, FALSE);
1802 /* Cache template */
1803 memset(&template, 0, sizeof(template));
1805 template.count = count;
1806 SE_COPY_ADDRESS(&template.source_addr, &hdrinfo->net_src);
1807 template.source_id = hdrinfo->src_id;
1808 template.count_scopes = 0;
1809 template.scopes = NULL;
1810 template.option_template = 0; /* Data template */
1811 template.entries = g_malloc(count * sizeof(struct v9_template_entry));
1812 tvb_memcpy(tvb, (guint8 *)template.entries, offset,
1813 count * sizeof(struct v9_template_entry));
1814 v9_template_add(&template);
1816 for (i = 1; i <= count; i++) {
1817 guint16 type, length;
1819 type = tvb_get_ntohs(tvb, offset);
1820 length = tvb_get_ntohs(tvb, offset + 2);
1822 field_item = proto_tree_add_text(template_tree, tvb,
1823 offset, 4, "Field (%u/%u)", i, count);
1824 field_tree = proto_item_add_subtree(field_item, ett_field);
1826 proto_tree_add_item(field_tree,
1827 hf_cflow_template_field_type, tvb, offset, 2, FALSE);
1830 proto_tree_add_item(field_tree,
1831 hf_cflow_template_field_length, tvb, offset, 2, FALSE);
1834 remaining -= 4 + sizeof(struct v9_template_entry) * count;
1840 static value_string v9_template_types[] = {
1847 { 7, "L4_SRC_PORT" },
1848 { 8, "IP_SRC_ADDR" },
1850 { 10, "INPUT_SNMP" },
1851 { 11, "L4_DST_PORT" },
1852 { 12, "IP_DST_ADDR" },
1854 { 14, "OUTPUT_SNMP" },
1855 { 15, "IP_NEXT_HOP" },
1858 { 18, "BGP_NEXT_HOP" },
1859 { 19, "MUL_DPKTS" },
1860 { 20, "MUL_DOCTETS" },
1861 { 21, "LAST_SWITCHED" },
1862 { 22, "FIRST_SWITCHED" },
1863 { 23, "OUT_BYTES" },
1865 { 25, "IP LENGTH MINIMUM" },
1866 { 26, "IP LENGTH MAXIMUM" },
1867 { 27, "IPV6_SRC_ADDR" },
1868 { 28, "IPV6_DST_ADDR" },
1869 { 29, "IPV6_SRC_MASK" },
1870 { 30, "IPV6_DST_MASK" },
1871 { 31, "FLOW_LABEL" },
1872 { 32, "ICMP_TYPE" },
1873 { 33, "IGMP_TYPE" },
1874 { 34, "SAMPLING_INTERVAL" },
1875 { 35, "SAMPLING_ALGORITHM" },
1876 { 36, "FLOW_ACTIVE_TIMEOUT" },
1877 { 37, "FLOW_INACTIVE_TIMEOUT" },
1878 { 38, "ENGINE_TYPE" },
1879 { 39, "ENGINE_ID" },
1880 { 40, "TOTAL_BYTES_EXP" },
1881 { 41, "TOTAL_PKTS_EXP" },
1882 { 42, "TOTAL_FLOWS_EXP" },
1883 { 44, "IP_SRC_PREFIX" },
1884 { 45, "IP_DST_PREFIX" },
1885 { 46, "MPLS_TOP_LABEL_TYPE" },
1886 { 47, "MPLS_TOP_LABEL_ADDR" },
1887 { 48, "FLOW_SAMPLER_ID" },
1888 { 49, "FLOW_SAMPLER_MODE" },
1889 { 50, "FLOW_SAMPLER_RANDOM_INTERVAL" },
1890 { 51, "FLOW_CLASS" },
1891 { 52, "IP TTL MINIMUM" },
1892 { 53, "IP TTL MAXIMUM" },
1899 { 60, "IP_PROTOCOL_VERSION" },
1900 { 61, "DIRECTION" },
1901 { 62, "IPV6_NEXT_HOP" },
1902 { 63, "BPG_IPV6_NEXT_HOP" },
1903 { 64, "IPV6_OPTION_HEADERS" },
1904 { 70, "MPLS_LABEL_1" },
1905 { 71, "MPLS_LABEL_2" },
1906 { 72, "MPLS_LABEL_3" },
1907 { 73, "MPLS_LABEL_4" },
1908 { 74, "MPLS_LABEL_5" },
1909 { 75, "MPLS_LABEL_6" },
1910 { 76, "MPLS_LABEL_7" },
1911 { 77, "MPLS_LABEL_8" },
1912 { 78, "MPLS_LABEL_9" },
1913 { 79, "MPLS_LABEL_10" },
1914 { 80, "DESTINATION_MAC" },
1915 { 81, "SOURCE_MAC" },
1918 { 84, "SAMPLER_NAME" },
1919 { 85, "BYTES_TOTAL" },
1920 { 86, "PACKETS_TOTAL" },
1921 { 88, "FRAGMENT_OFFSET" },
1922 { 89, "FORWARDING_STATUS" },
1923 { 90, "VPN_ROUTE_DISTINGUISHER" },
1924 { 92, "SRC_TRAFFIC_INDEX" },
1925 { 93, "DST_TRAFFIC_INDEX" },
1926 { 128, "SRC_AS_PEER" },
1927 { 129, "DST_AS_PEER" },
1928 { 130, "DROPPED_BYTES" },
1929 { 131, "DROPPED_PACKETS" },
1930 { 132, "DROPPED_BYTES_TOTAL" },
1931 { 133, "DROPPED_PACKETS_TOTAL" },
1932 { 140, "MPLS_TOP_LABEL_IPv6_ADDRESS" },
1933 { 144, "FLOW_EXPORTER" },
1934 { 176, "ICMP_IPv4_TYPE" },
1935 { 177, "ICMP_IPv4_CODE" },
1936 { 178, "ICMP_IPv6_TYPE" },
1937 { 179, "ICMP_IPv6_CODE" },
1938 { 180, "UDP_SRC_PORT" },
1939 { 181, "UDP_DST_PORT" },
1940 { 182, "TCP_SRC_PORT" },
1941 { 183, "TCP_DST_PORT" },
1942 { 184, "TCP_SEQ_NUM" },
1943 { 184, "TCP_ACK_NUM" },
1944 { 186, "TCP_WINDOW_SIZE" },
1945 { 187, "TCP_URGENT_PTR" },
1946 { 188, "TCP_HEADER_LEN" },
1947 { 189, "IP_HEADER_LEN" },
1948 { 190, "IP_TOTAL_LEN" },
1952 { 196, "IP_PRECEDENCE" },
1953 { 196, "IP_FRAGMENT_FLAGS" },
1954 { 198, "BYTES_SQUARED" },
1955 { 199, "BYTES_SQUARED_PERMANENT" },
1956 { 200, "MPLS_TOP_LABEL_TTL" },
1957 { 201, "MPLS_LABEL_STACK_OCTETS" },
1958 { 202, "MPLS_LABEL_STACK_DEPTH" },
1959 { 203, "MPLS_TOP_LABEL_EXP" },
1960 { 204, "IP_PAYLOAD_LENGTH" },
1961 { 205, "UDP_LENGTH" },
1962 { 206, "IS_MULTICAST" },
1963 { 207, "IP_HEADER_WORDS" },
1964 { 208, "IP_OPTION_MAP" },
1965 { 208, "TPC_OPTION_MAP" },
1966 { 313, "IP_SECTION HEADER" },
1967 { 314, "IP_SECTION PAYLOAD" },
1971 static value_string v9_scope_field_types[] = {
1975 { 4, "NetFlow Cache" },
1981 decode_v9_template_types(int type) {
1982 const char *v = match_strval(type, v9_template_types);
1983 return ((v==NULL)?"Unknown" : v);
1986 static value_string v9_sampler_mode[] = {
1987 { 0, "Determinist" },
1992 static value_string v9_direction[] = {
1997 static value_string v9_forwarding_status[] = {
1998 { 0, "Unknown"}, /* Observed on IOS-XR 3.2 */
1999 { 1, "Forward"}, /* Observed on 7200 12.4(9)T */
2000 { 2, "Drop"}, /* Observed on 7200 12.4(9)T */
2001 { 3, "Consume"}, /* Observed on 7200 12.4(9)T */
2006 v9_template_hash(guint16 id, const address * net_src, guint32 src_id)
2012 p = (guint32 *)net_src->data;
2016 if (net_src->type == AT_IPv4) {
2018 } else if (net_src->type == AT_IPv6) {
2019 for (i=0; i < 4; i++) {
2026 return val % V9TEMPLATE_CACHE_MAX_ENTRIES;
2030 v9_template_add(struct v9_template *template)
2034 /* Add up the actual length of the data and store in proper byte order */
2035 template->length = 0;
2037 for(i = 0; i < template->count_scopes; i++) {
2038 template->scopes[i].type = g_ntohs(template->scopes[i].type);
2039 template->scopes[i].length = g_ntohs(template->scopes[i].length);
2040 template->length += template->scopes[i].length;
2043 for (i = 0; i < template->count; i++) {
2044 template->entries[i].type = g_ntohs(template->entries[i].type);
2045 template->entries[i].length = g_ntohs(template->entries[i].length);
2046 template->length += template->entries[i].length;
2049 memcpy(&v9_template_cache[v9_template_hash(template->id,
2050 &template->source_addr, template->source_id)],
2051 template, sizeof(*template));
2054 static struct v9_template *
2055 v9_template_get(guint16 id, address * net_src, guint32 src_id)
2057 struct v9_template *template;
2059 template = &v9_template_cache[v9_template_hash(id, net_src, src_id)];
2061 if (template->id != id ||
2062 !ADDRESSES_EQUAL(&template->source_addr, net_src) ||
2063 template->source_id != src_id) {
2071 * dissect a version 1, 5, or 7 pdu and return the length of the pdu we
2076 dissect_pdu(proto_tree * pdutree, tvbuff_t * tvb, int offset, hdrinfo_t * hdrinfo)
2078 int startoffset = offset;
2079 guint32 srcaddr, dstaddr;
2084 memset(&ts, '\0', sizeof(ts));
2087 * memcpy so we can use the values later to calculate a prefix
2089 srcaddr = tvb_get_ipv4(tvb, offset);
2090 proto_tree_add_ipv4(pdutree, hf_cflow_srcaddr, tvb, offset, 4,
2094 dstaddr = tvb_get_ipv4(tvb, offset);
2095 proto_tree_add_ipv4(pdutree, hf_cflow_dstaddr, tvb, offset, 4,
2099 proto_tree_add_item(pdutree, hf_cflow_nexthop, tvb, offset, 4, FALSE);
2102 offset = flow_process_ints(pdutree, tvb, offset);
2103 offset = flow_process_sizecount(pdutree, tvb, offset);
2104 offset = flow_process_timeperiod(pdutree, tvb, offset);
2105 offset = flow_process_ports(pdutree, tvb, offset);
2108 * and the similarities end here
2111 ver = hdrinfo->vspec;
2115 flow_process_textfield(pdutree, tvb, offset, 2, "padding");
2117 proto_tree_add_item(pdutree, hf_cflow_prot, tvb, offset++, 1,
2120 proto_tree_add_item(pdutree, hf_cflow_tos, tvb, offset++, 1,
2123 proto_tree_add_item(pdutree, hf_cflow_tcpflags, tvb, offset++,
2127 flow_process_textfield(pdutree, tvb, offset, 3, "padding");
2130 flow_process_textfield(pdutree, tvb, offset, 4,
2135 flow_process_textfield(pdutree, tvb, offset, 1,
2138 proto_tree_add_item(pdutree, hf_cflow_flags, tvb,
2139 offset++, 1, FALSE);
2142 proto_tree_add_item(pdutree, hf_cflow_tcpflags, tvb, offset++,
2145 proto_tree_add_item(pdutree, hf_cflow_prot, tvb, offset++, 1,
2148 proto_tree_add_item(pdutree, hf_cflow_tos, tvb, offset++, 1,
2151 offset = flow_process_aspair(pdutree, tvb, offset);
2153 mask = tvb_get_guint8(tvb, offset);
2154 proto_tree_add_text(pdutree, tvb, offset, 1,
2155 "SrcMask: %u (prefix: %s/%u)",
2156 mask, getprefix(&srcaddr, mask),
2157 mask != 0 ? mask : 32);
2158 proto_tree_add_uint_hidden(pdutree, hf_cflow_srcmask, tvb,
2161 mask = tvb_get_guint8(tvb, offset);
2162 proto_tree_add_text(pdutree, tvb, offset, 1,
2163 "DstMask: %u (prefix: %s/%u)",
2164 mask, getprefix(&dstaddr, mask),
2165 mask != 0 ? mask : 32);
2166 proto_tree_add_uint_hidden(pdutree, hf_cflow_dstmask, tvb,
2170 flow_process_textfield(pdutree, tvb, offset, 2, "padding");
2173 proto_tree_add_item(pdutree, hf_cflow_routersc, tvb,
2179 return (offset - startoffset);
2183 getprefix(const guint32 * address, int prefix)
2187 gprefix = *address & g_htonl((0xffffffff << (32 - prefix)));
2189 return (ip_to_str((const guint8 *)&gprefix));
2194 netflow_reinit(void)
2199 * Clear out the template cache.
2200 * Free the table of fields for each entry, and then zero out
2203 for (i = 0; i < V9TEMPLATE_CACHE_MAX_ENTRIES; i++)
2205 if (v9_template_cache[i].scopes)
2206 g_free(v9_template_cache[i].scopes);
2207 g_free(v9_template_cache[i].entries);
2209 memset(v9_template_cache, 0, sizeof v9_template_cache);
2213 proto_register_netflow(void)
2215 static hf_register_info hf[] = {
2220 {"Version", "cflow.version",
2221 FT_UINT16, BASE_DEC, NULL, 0x0,
2222 "NetFlow Version", HFILL}
2225 {"Length", "cflow.len",
2226 FT_UINT16, BASE_DEC, NULL, 0x0,
2227 "Length of PDUs", HFILL}
2230 {"Count", "cflow.count",
2231 FT_UINT16, BASE_DEC, NULL, 0x0,
2232 "Count of PDUs", HFILL}
2234 {&hf_cflow_sysuptime,
2235 {"SysUptime", "cflow.sysuptime",
2236 FT_UINT32, BASE_DEC, NULL, 0x0,
2237 "Time since router booted (in milliseconds)", HFILL}
2239 {&hf_cflow_exporttime,
2240 {"ExportTime", "cflow.exporttime",
2241 FT_UINT32, BASE_DEC, NULL, 0x0,
2242 "Time when the flow has been exported", HFILL}
2246 {&hf_cflow_timestamp,
2247 {"Timestamp", "cflow.timestamp",
2248 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
2249 "Current seconds since epoch", HFILL}
2251 {&hf_cflow_unix_secs,
2252 {"CurrentSecs", "cflow.unix_secs",
2253 FT_UINT32, BASE_DEC, NULL, 0x0,
2254 "Current seconds since epoch", HFILL}
2256 {&hf_cflow_unix_nsecs,
2257 {"CurrentNSecs", "cflow.unix_nsecs",
2258 FT_UINT32, BASE_DEC, NULL, 0x0,
2259 "Residual nanoseconds since epoch", HFILL}
2261 {&hf_cflow_samplingmode,
2262 {"SamplingMode", "cflow.samplingmode",
2263 FT_UINT16, BASE_DEC, VALS(v5_sampling_mode), 0xC000,
2264 "Sampling Mode of exporter", HFILL}
2266 {&hf_cflow_samplerate,
2267 {"SampleRate", "cflow.samplerate",
2268 FT_UINT16, BASE_DEC, NULL, 0x3FFF,
2269 "Sample Frequency of exporter", HFILL}
2273 * end version-agnostic header
2274 * version-specific flow header
2276 {&hf_cflow_sequence,
2277 {"FlowSequence", "cflow.sequence",
2278 FT_UINT32, BASE_DEC, NULL, 0x0,
2279 "Sequence number of flows seen", HFILL}
2281 {&hf_cflow_engine_type,
2282 {"EngineType", "cflow.engine_type",
2283 FT_UINT8, BASE_DEC, NULL, 0x0,
2284 "Flow switching engine type", HFILL}
2286 {&hf_cflow_engine_id,
2287 {"EngineId", "cflow.engine_id",
2288 FT_UINT8, BASE_DEC, NULL, 0x0,
2289 "Slot number of switching engine", HFILL}
2291 {&hf_cflow_source_id,
2292 {"SourceId", "cflow.source_id",
2293 FT_UINT32, BASE_DEC, NULL, 0x0,
2294 "Identifier for export device", HFILL}
2296 {&hf_cflow_aggmethod,
2297 {"AggMethod", "cflow.aggmethod",
2298 FT_UINT8, BASE_DEC, VALS(v8_agg), 0x0,
2299 "CFlow V8 Aggregation Method", HFILL}
2301 {&hf_cflow_aggversion,
2302 {"AggVersion", "cflow.aggversion",
2303 FT_UINT8, BASE_DEC, NULL, 0x0,
2304 "CFlow V8 Aggregation Version", HFILL}
2307 * end version specific header storage
2312 {&hf_cflow_flowset_id,
2313 {"FlowSet Id", "cflow.flowset_id",
2314 FT_UINT16, BASE_DEC, NULL, 0x0,
2315 "FlowSet Id", HFILL}
2317 {&hf_cflow_data_flowset_id,
2318 {"Data FlowSet (Template Id)", "cflow.data_flowset_id",
2319 FT_UINT16, BASE_DEC, NULL, 0x0,
2320 "Data FlowSet with corresponding to a template Id", HFILL}
2322 {&hf_cflow_data_datarecord_id,
2323 {"DataRecord (Template Id)", "cflow.data_datarecord_id",
2324 FT_UINT16, BASE_DEC, NULL, 0x0,
2325 "DataRecord with corresponding to a template Id", HFILL}
2327 {&hf_cflow_options_flowset_id,
2328 {"Options FlowSet", "cflow.options_flowset_id",
2329 FT_UINT16, BASE_DEC, NULL, 0x0,
2330 "Options FlowSet", HFILL}
2332 {&hf_cflow_template_flowset_id,
2333 {"Template FlowSet", "cflow.template_flowset_id",
2334 FT_UINT16, BASE_DEC, NULL, 0x0,
2335 "Template FlowSet", HFILL}
2337 {&hf_cflow_flowset_length,
2338 {"FlowSet Length", "cflow.flowset_length",
2339 FT_UINT16, BASE_DEC, NULL, 0x0,
2340 "FlowSet length", HFILL}
2342 {&hf_cflow_template_id,
2343 {"Template Id", "cflow.template_id",
2344 FT_UINT16, BASE_DEC, NULL, 0x0,
2345 "Template Id", HFILL}
2347 {&hf_cflow_template_field_count,
2348 {"Field Count", "cflow.template_field_count",
2349 FT_UINT16, BASE_DEC, NULL, 0x0,
2350 "Template field count", HFILL}
2352 {&hf_cflow_template_field_type,
2353 {"Type", "cflow.template_field_type",
2354 FT_UINT16, BASE_DEC, VALS(v9_template_types), 0x0,
2355 "Template field type", HFILL}
2357 {&hf_cflow_template_field_length,
2358 {"Length", "cflow.template_field_length",
2359 FT_UINT16, BASE_DEC, NULL, 0x0,
2360 "Template field length", HFILL}
2364 {&hf_cflow_option_scope_length,
2365 {"Option Scope Length", "cflow.option_scope_length",
2366 FT_UINT16, BASE_DEC, NULL, 0x0,
2367 "Option scope length", HFILL}
2369 {&hf_cflow_option_length,
2370 {"Option Length", "cflow.option_length",
2371 FT_UINT16, BASE_DEC, NULL, 0x0,
2372 "Option length", HFILL}
2374 {&hf_cflow_template_scope_field_type,
2375 {"Scope Type", "cflow.scope_field_type",
2376 FT_UINT16, BASE_DEC, VALS(v9_scope_field_types), 0x0,
2377 "Scope field type", HFILL}
2379 {&hf_cflow_template_scope_field_length,
2380 {"Scope Field Length", "cflow.scope_field_length",
2381 FT_UINT16, BASE_DEC, NULL, 0x0,
2382 "Scope field length", HFILL}
2384 {&hf_cflow_icmp_type,
2385 {"ICMP Type", "cflow.icmp_type",
2386 FT_UINT8, BASE_DEC, NULL, 0x0,
2389 {&hf_cflow_igmp_type,
2390 {"IGMP Type", "cflow.igmp_type",
2391 FT_UINT8, BASE_DEC, NULL, 0x0,
2394 {&hf_cflow_sampling_interval,
2395 {"Sampling interval", "cflow.sampling_interval",
2396 FT_UINT32, BASE_DEC, NULL, 0x0,
2397 "Sampling interval", HFILL}
2399 {&hf_cflow_sampling_algorithm,
2400 {"Sampling algorithm", "cflow.sampling_algorithm",
2401 FT_UINT8, BASE_DEC, NULL, 0x0,
2402 "Sampling algorithm", HFILL}
2404 {&hf_cflow_flow_active_timeout,
2405 {"Flow active timeout", "cflow.flow_active_timeout",
2406 FT_UINT16, BASE_DEC, NULL, 0x0,
2407 "Flow active timeout", HFILL}
2409 {&hf_cflow_flow_inactive_timeout,
2410 {"Flow inactive timeout", "cflow.flow_inactive_timeout",
2411 FT_UINT16, BASE_DEC, NULL, 0x0,
2412 "Flow inactive timeout", HFILL}
2416 * begin pdu content storage
2419 {"SrcAddr", "cflow.srcaddr",
2420 FT_IPv4, BASE_NONE, NULL, 0x0,
2421 "Flow Source Address", HFILL}
2423 {&hf_cflow_srcaddr_v6,
2424 {"SrcAddr", "cflow.srcaddrv6",
2425 FT_IPv6, BASE_NONE, NULL, 0x0,
2426 "Flow Source Address", HFILL}
2429 {"SrcNet", "cflow.srcnet",
2430 FT_IPv4, BASE_NONE, NULL, 0x0,
2431 "Flow Source Network", HFILL}
2434 {"DstAddr", "cflow.dstaddr",
2435 FT_IPv4, BASE_NONE, NULL, 0x0,
2436 "Flow Destination Address", HFILL}
2438 {&hf_cflow_dstaddr_v6,
2439 {"DstAddr", "cflow.dstaddrv6",
2440 FT_IPv6, BASE_NONE, NULL, 0x0,
2441 "Flow Destination Address", HFILL}
2444 {"DstNet", "cflow.dstaddr",
2445 FT_IPv4, BASE_NONE, NULL, 0x0,
2446 "Flow Destination Network", HFILL}
2449 {"NextHop", "cflow.nexthop",
2450 FT_IPv4, BASE_NONE, NULL, 0x0,
2451 "Router nexthop", HFILL}
2453 {&hf_cflow_nexthop_v6,
2454 {"NextHop", "cflow.nexthopv6",
2455 FT_IPv6, BASE_NONE, NULL, 0x0,
2456 "Router nexthop", HFILL}
2458 {&hf_cflow_bgpnexthop,
2459 {"BGPNextHop", "cflow.bgpnexthop",
2460 FT_IPv4, BASE_NONE, NULL, 0x0,
2461 "BGP Router Nexthop", HFILL}
2463 {&hf_cflow_bgpnexthop_v6,
2464 {"BGPNextHop", "cflow.bgpnexthopv6",
2465 FT_IPv6, BASE_NONE, NULL, 0x0,
2466 "BGP Router Nexthop", HFILL}
2468 {&hf_cflow_inputint,
2469 {"InputInt", "cflow.inputint",
2470 FT_UINT16, BASE_DEC, NULL, 0x0,
2471 "Flow Input Interface", HFILL}
2473 {&hf_cflow_outputint,
2474 {"OutputInt", "cflow.outputint",
2475 FT_UINT16, BASE_DEC, NULL, 0x0,
2476 "Flow Output Interface", HFILL}
2479 {"Flows", "cflow.flows",
2480 FT_UINT32, BASE_DEC, NULL, 0x0,
2481 "Flows Aggregated in PDU", HFILL}
2484 {"Packets", "cflow.packets",
2485 FT_UINT32, BASE_DEC, NULL, 0x0,
2486 "Count of packets", HFILL}
2488 {&hf_cflow_packets64,
2489 {"Packets", "cflow.packets64",
2490 FT_UINT64, BASE_DEC, NULL, 0x0,
2491 "Count of packets", HFILL}
2493 {&hf_cflow_packetsout,
2494 {"PacketsOut", "cflow.packetsout",
2495 FT_UINT64, BASE_DEC, NULL, 0x0,
2496 "Count of packets going out", HFILL}
2499 {"Octets", "cflow.octets",
2500 FT_UINT32, BASE_DEC, NULL, 0x0,
2501 "Count of bytes", HFILL}
2503 {&hf_cflow_octets64,
2504 {"Octets", "cflow.octets64",
2505 FT_UINT64, BASE_DEC, NULL, 0x0,
2506 "Count of bytes", HFILL}
2508 {&hf_cflow_length_min,
2509 {"MinLength", "cflow.length_min",
2510 FT_UINT16, BASE_DEC, NULL, 0x0,
2511 "Packet Length Min", HFILL}
2513 {&hf_cflow_length_max,
2514 {"MaxLength", "cflow.length_max",
2515 FT_UINT16, BASE_DEC, NULL, 0x0,
2516 "Packet Length Max", HFILL}
2518 {&hf_cflow_timedelta,
2519 {"Duration", "cflow.timedelta",
2520 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
2521 "Duration of flow sample (end - start)", HFILL}
2523 {&hf_cflow_timestart,
2524 {"StartTime", "cflow.timestart",
2525 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
2526 "Uptime at start of flow", HFILL}
2529 {"EndTime", "cflow.timeend",
2530 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
2531 "Uptime at end of flow", HFILL}
2534 {"SrcPort", "cflow.srcport",
2535 FT_UINT16, BASE_DEC, NULL, 0x0,
2536 "Flow Source Port", HFILL}
2539 {"DstPort", "cflow.dstport",
2540 FT_UINT16, BASE_DEC, NULL, 0x0,
2541 "Flow Destination Port", HFILL}
2544 {"Protocol", "cflow.protocol",
2545 FT_UINT8, BASE_DEC, NULL, 0x0,
2546 "IP Protocol", HFILL}
2549 {"IP ToS", "cflow.tos",
2550 FT_UINT8, BASE_HEX, NULL, 0x0,
2551 "IP Type of Service", HFILL}
2554 {"Export Flags", "cflow.flags",
2555 FT_UINT8, BASE_HEX, NULL, 0x0,
2556 "CFlow Flags", HFILL}
2558 {&hf_cflow_tcpflags,
2559 {"TCP Flags", "cflow.tcpflags",
2560 FT_UINT8, BASE_HEX, NULL, 0x0,
2564 {"SrcAS", "cflow.srcas",
2565 FT_UINT16, BASE_DEC, NULL, 0x0,
2569 {"DstAS", "cflow.dstas",
2570 FT_UINT16, BASE_DEC, NULL, 0x0,
2571 "Destination AS", HFILL}
2574 {"SrcMask", "cflow.srcmask",
2575 FT_UINT8, BASE_DEC, NULL, 0x0,
2576 "Source Prefix Mask", HFILL}
2578 {&hf_cflow_srcmask_v6,
2579 {"SrcMask", "cflow.srcmaskv6",
2580 FT_UINT8, BASE_DEC, NULL, 0x0,
2581 "IPv6 Source Prefix Mask", HFILL}
2584 {"DstMask", "cflow.dstmask",
2585 FT_UINT8, BASE_DEC, NULL, 0x0,
2586 "Destination Prefix Mask", HFILL}
2588 {&hf_cflow_dstmask_v6,
2589 {"DstMask", "cflow.dstmaskv6",
2590 FT_UINT8, BASE_DEC, NULL, 0x0,
2591 "IPv6 Destination Prefix Mask", HFILL}
2593 {&hf_cflow_routersc,
2594 {"Router Shortcut", "cflow.routersc",
2595 FT_IPv4, BASE_NONE, NULL, 0x0,
2596 "Router shortcut by switch", HFILL}
2598 {&hf_cflow_mulpackets,
2599 {"MulticastPackets", "cflow.mulpackets",
2600 FT_UINT32, BASE_DEC, NULL, 0x0,
2601 "Count of multicast packets", HFILL}
2603 {&hf_cflow_muloctets,
2604 {"MulticastOctets", "cflow.muloctets",
2605 FT_UINT32, BASE_DEC, NULL, 0x0,
2606 "Count of multicast octets", HFILL}
2608 {&hf_cflow_octets_exp,
2609 {"OctetsExp", "cflow.octetsexp",
2610 FT_UINT32, BASE_DEC, NULL, 0x0,
2611 "Octets exported", HFILL}
2613 {&hf_cflow_octets_exp64,
2614 {"OctetsExp ", "cflow.octetsexp",
2615 FT_UINT64, BASE_DEC, NULL, 0x0,
2616 "Octets exported", HFILL}
2618 {&hf_cflow_packets_exp,
2619 {"PacketsExp", "cflow.packetsexp",
2620 FT_UINT32, BASE_DEC, NULL, 0x0,
2621 "Packets exported", HFILL}
2623 {&hf_cflow_packets_exp64,
2624 {"PacketsExp", "cflow.packetsexp",
2625 FT_UINT64, BASE_DEC, NULL, 0x0,
2626 "Packets exported", HFILL}
2628 {&hf_cflow_flows_exp,
2629 {"FlowsExp ", "cflow.flowsexp",
2630 FT_UINT32, BASE_DEC, NULL, 0x0,
2631 "Flows exported", HFILL}
2633 {&hf_cflow_flows_exp64,
2634 {"FlowsExp ", "cflow.flowsexp",
2635 FT_UINT64, BASE_DEC, NULL, 0x0,
2636 "Flows exported", HFILL}
2638 {&hf_cflow_srcprefix,
2639 {"SrcPrefix", "cflow.srcprefix",
2640 FT_IPv4, BASE_NONE, NULL, 0x0,
2641 "Flow Source Prefix", HFILL}
2643 {&hf_cflow_dstprefix,
2644 {"DstPrefix", "cflow.dstprefix",
2645 FT_IPv4, BASE_NONE, NULL, 0x0,
2646 "Flow Destination Prefix", HFILL}
2648 {&hf_cflow_mpls_top_label_type,
2649 {"TopLabelType", "cflow.toplabeltype",
2650 FT_UINT8, BASE_DEC, VALS(special_mpls_top_label_type), 0x0,
2651 "Top MPLS label Type", HFILL}
2653 {&hf_cflow_mpls_pe_addr,
2654 {"TopLabelAddr", "cflow.toplabeladdr",
2655 FT_IPv4, BASE_NONE, NULL, 0x0,
2656 "Top MPLS label PE address", HFILL}
2658 {&hf_cflow_sampler_mode ,
2659 {"SamplerMode", "cflow.sampler_mode",
2660 FT_UINT8, BASE_DEC, VALS(v9_sampler_mode), 0x0,
2661 "Flow Sampler Mode", HFILL}
2663 {&hf_cflow_sampler_random_interval ,
2664 {"SamplerRandomInterval", "cflow.sampler_random_interval",
2665 FT_UINT32, BASE_DEC, NULL, 0x0,
2666 "Flow Sampler Random Interval", HFILL}
2668 {&hf_cflow_flow_class ,
2669 {"FlowClass", "cflow.flow_class",
2670 FT_UINT8, BASE_DEC, NULL, 0x0,
2671 "Flow Class", HFILL}
2673 {&hf_cflow_ttl_minimum ,
2674 {"MinTTL", "cflow.ttl_min",
2675 FT_UINT8, BASE_DEC, NULL, 0x0,
2676 "TTL minimum", HFILL}
2678 {&hf_cflow_ttl_maximum ,
2679 {"MaxTTL", "cflow.ttl_max",
2680 FT_UINT8, BASE_DEC, NULL, 0x0,
2681 "TTL maximum", HFILL}
2683 {&hf_cflow_ipv4_id ,
2684 {"IPv4Ident", "cflow.ipv4_ident",
2685 FT_UINT16, BASE_DEC, NULL, 0x0,
2686 "IPv4 Identifier", HFILL}
2688 {&hf_cflow_ip_version ,
2689 {"IPVersion", "cflow.ip_version",
2690 FT_BYTES, BASE_HEX, NULL, 0x0,
2691 "IP Version", HFILL}
2693 {&hf_cflow_direction ,
2694 {"Direction", "cflow.direction",
2695 FT_UINT8, BASE_DEC, VALS(v9_direction), 0x0,
2698 {&hf_cflow_if_name ,
2699 {"IfName", "cflow.if_name",
2700 FT_STRINGZ/*FT_BYTES*/, BASE_HEX, NULL, 0x0,
2701 "SNMP Interface Name", HFILL}
2703 {&hf_cflow_if_descr ,
2704 {"IfDescr", "cflow.if_descr",
2705 FT_STRINGZ/*FT_BYTES*/, BASE_HEX, NULL, 0x0,
2706 "SNMP Interface Description", HFILL}
2708 {&hf_cflow_sampler_name ,
2709 {"SamplerName", "cflow.sampler_name",
2710 FT_STRINGZ/*FT_BYTES*/, BASE_HEX, NULL, 0x0,
2711 "Sampler Name", HFILL}
2713 {&hf_cflow_forwarding_status ,
2714 {"ForwdStat", "cflow.forwarding_status",
2715 FT_UINT8, BASE_DEC, VALS(v9_forwarding_status), 0xC0,
2716 "Forwarding Status", HFILL}
2718 {&hf_cflow_forwarding_code ,
2719 {"ForwdCode", "cflow.forwarding_code",
2720 FT_UINT8, BASE_DEC, NULL, 0x3F,
2721 "Forwarding Code", HFILL}
2723 {&hf_cflow_peer_srcas,
2724 {"PeerSrcAS", "cflow.peer_srcas",
2725 FT_UINT16, BASE_DEC, NULL, 0x0,
2726 "Peer Source AS", HFILL}
2728 {&hf_cflow_peer_dstas,
2729 {"PeerDstAS", "cflow.peer_dstas",
2730 FT_UINT16, BASE_DEC, NULL, 0x0,
2731 "Peer Destination AS", HFILL}
2733 {&hf_cflow_flow_exporter,
2734 {"FlowExporter", "cflow.flow_exporter",
2735 FT_BYTES/*FT_IPv4*/, BASE_HEX, NULL, 0x0,
2736 "Flow Exporter", HFILL}
2738 {&hf_cflow_icmp_ipv4_type,
2739 {"IPv4 ICMP Type", "cflow.icmp_ipv4_type",
2740 FT_UINT8, BASE_DEC, NULL, 0x0,
2741 "IPv4 ICMP type", HFILL}
2743 {&hf_cflow_icmp_ipv4_code,
2744 {"IPv4 ICMP Code", "cflow.icmp_ipv4_code",
2745 FT_UINT8, BASE_DEC, NULL, 0x0,
2746 "IPv4 ICMP code", HFILL}
2748 {&hf_cflow_icmp_ipv6_type,
2749 {"IPv6 ICMP Type", "cflow.icmp_ipv6_type",
2750 FT_UINT8, BASE_DEC, NULL, 0x0,
2751 "IPv6 ICMP type", HFILL}
2753 {&hf_cflow_icmp_ipv6_code,
2754 {"IPv6 ICMP Code", "cflow.icmp_ipv6_code",
2755 FT_UINT8, BASE_DEC, NULL, 0x0,
2756 "IPv6 ICMP code", HFILL}
2758 {&hf_cflow_tcp_window_size,
2759 {"TCP Windows Size", "cflow.tcp_windows_size",
2760 FT_UINT16, BASE_DEC, NULL, 0x0,
2761 "TCP Windows size", HFILL}
2763 {&hf_cflow_ip_total_length,
2764 {"IP Total Length", "cflow.ip_total_length",
2765 FT_UINT8, BASE_DEC, NULL, 0x0,
2766 "IP total length", HFILL}
2769 {"IP TTL", "cflow.ip_ttl",
2770 FT_UINT8, BASE_DEC, NULL, 0x0,
2771 "IP time to live", HFILL}
2774 {"IP TOS", "cflow.ip_tos",
2775 FT_UINT8, BASE_DEC, NULL, 0x0,
2776 "IP type of service", HFILL}
2779 {"DSCP", "cflow.ip_dscp",
2780 FT_UINT8, BASE_DEC, NULL, 0x0,
2783 {&hf_cflow_octets_squared64,
2784 {"OctetsSquared ", "cflow.octets_squared",
2785 FT_UINT64, BASE_DEC, NULL, 0x0,
2786 "Octets Squared", HFILL}
2788 {&hf_cflow_udp_length,
2789 {"UDP Length", "cflow.udp_length",
2790 FT_UINT16, BASE_DEC, NULL, 0x0,
2791 "UDP length", HFILL}
2793 {&hf_cflow_is_multicast,
2794 {"IsMulticast", "cflow.is_multicast",
2795 FT_UINT8, BASE_DEC, NULL, 0x0,
2796 "Is Multicast", HFILL}
2798 {&hf_cflow_ip_header_words,
2799 {"IPHeaderLen", "cflow.ip_header_words",
2800 FT_UINT8, BASE_DEC, NULL, 0x0,
2801 "IPHeaderLen", HFILL}
2803 {&hf_cflow_option_map,
2804 {"OptionMap", "cflow.option_map",
2805 FT_BYTES, BASE_HEX, NULL, 0x0,
2806 "Option Map", HFILL}
2808 {&hf_cflow_section_header ,
2809 {"SectionHeader", "cflow.section_header",
2810 FT_BYTES, BASE_HEX, NULL, 0x0,
2811 "Header of Packet", HFILL}
2813 {&hf_cflow_section_payload ,
2814 {"SectionPayload", "cflow.section_payload",
2815 FT_BYTES, BASE_HEX, NULL, 0x0,
2816 "Payload of Packet", HFILL}
2819 * end pdu content storage
2821 {&hf_cflow_scope_system ,
2822 {"ScopeSystem", "cflow.scope_system",
2823 FT_IPv4, BASE_HEX, NULL, 0x0,
2824 "Option Scope System", HFILL}
2826 {&hf_cflow_scope_interface ,
2827 {"ScopeInterface", "cflow.scope_interface",
2828 FT_UINT32, BASE_DEC, NULL, 0x0,
2829 "Option Scope Interface", HFILL}
2831 {&hf_cflow_scope_linecard ,
2832 {"ScopeLinecard", "cflow.scope_linecard",
2833 FT_BYTES, BASE_HEX, NULL, 0x0,
2834 "Option Scope Linecard", HFILL}
2836 {&hf_cflow_scope_cache ,
2837 {"ScopeCache", "cflow.scope_cache",
2838 FT_BYTES, BASE_HEX, NULL, 0x0,
2839 "Option Scope Cache", HFILL}
2841 {&hf_cflow_scope_template ,
2842 {"ScopeTemplate", "cflow.scope_template",
2843 FT_BYTES, BASE_HEX, NULL, 0x0,
2844 "Option Scope Template", HFILL}
2846 {&hf_cflow_scope_unknown ,
2847 {"Scope Unknown", "cflow.scope",
2848 FT_BYTES, BASE_HEX, NULL, 0x0,
2849 "Option Scope Unknown", HFILL}
2853 static gint *ett[] = {
2863 module_t *netflow_module;
2865 proto_netflow = proto_register_protocol("Cisco NetFlow/IPFIX", "CFLOW",
2868 proto_register_field_array(proto_netflow, hf, array_length(hf));
2869 proto_register_subtree_array(ett, array_length(ett));
2871 /* Register our configuration options for NetFlow */
2872 netflow_module = prefs_register_protocol(proto_netflow,
2873 proto_reg_handoff_netflow);
2875 prefs_register_uint_preference(netflow_module, "udp.port",
2876 "NetFlow UDP Port", "Set the port for NetFlow messages",
2877 10, &global_netflow_udp_port);
2879 register_init_routine(&netflow_reinit);
2884 * protocol/port association
2887 proto_reg_handoff_netflow(void)
2889 static int netflow_prefs_initialized = FALSE;
2890 static dissector_handle_t netflow_handle;
2892 if (!netflow_prefs_initialized) {
2893 netflow_handle = create_dissector_handle(dissect_netflow,
2895 netflow_prefs_initialized = TRUE;
2897 dissector_delete("udp.port", netflow_udp_port, netflow_handle);
2898 dissector_delete("udp.port", ipfix_port, netflow_handle);
2899 dissector_delete("tcp.port", ipfix_port, netflow_handle);
2900 dissector_delete("sctp.port", ipfix_port, netflow_handle);
2903 /* Set out port number for future use */
2904 netflow_udp_port = global_netflow_udp_port;
2906 dissector_add("udp.port", netflow_udp_port, netflow_handle);
2908 ipfix_port = global_ipfix_port;
2909 dissector_add("udp.port", ipfix_port, netflow_handle);
2910 dissector_add("tcp.port", ipfix_port, netflow_handle);
2911 dissector_add("sctp.port", ipfix_port, netflow_handle);