aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--packet-netflow.c487
-rw-r--r--packet-netflow.h53
2 files changed, 381 insertions, 159 deletions
diff --git a/packet-netflow.c b/packet-netflow.c
index 4370d85813..f50875297a 100644
--- a/packet-netflow.c
+++ b/packet-netflow.c
@@ -2,7 +2,7 @@
* Routines for Cisco NetFlow packet disassembly
* Matthew Smart <smart@monkey.org>
*
- * $Id: packet-netflow.c,v 1.3 2002/09/07 00:08:02 jmayer Exp $
+ * $Id: packet-netflow.c,v 1.4 2002/09/09 20:22:51 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -41,13 +41,147 @@ static int hf_netflow_count = -1;
static int hf_netflow_sys_uptime = -1;
static int hf_netflow_unix_sec = -1;
static int hf_netflow_unix_nsec = -1;
-static int hf_netflow_sample_rate = -1;
-static int hf_netflow_flow_sequence = -1;
+static int hf_netflow_sequence = -1;
+static int hf_netflow_engine_type = -1;
+static int hf_netflow_engine_id = -1;
+static int hf_netflow_aggregation = -1;
+static int hf_netflow_agg_version = -1;
+static int hf_netflow_sample_rate = -1;
static int hf_netflow_record = -1;
+static int hf_netflow_src_addr = -1;
+static int hf_netflow_dst_addr = -1;
+static int hf_netflow_next_hop = -1;
+static int hf_netflow_input_iface = -1;
+static int hf_netflow_output_iface = -1;
+static int hf_netflow_packets = -1;
+static int hf_netflow_bytes = -1;
+static int hf_netflow_start_time = -1;
+static int hf_netflow_end_time = -1;
+static int hf_netflow_src_port = -1;
+static int hf_netflow_dst_port = -1;
+static int hf_netflow_v7_flags = -1;
+static int hf_netflow_tcp_flags = -1;
+static int hf_netflow_ip_prot = -1;
+static int hf_netflow_tos = -1;
+static int hf_netflow_src_as = -1;
+static int hf_netflow_dst_as = -1;
+static int hf_netflow_src_mask = -1;
+static int hf_netflow_dst_mask = -1;
+static int hf_netflow_router_sc = -1;
+
static gint ett_netflow = -1;
static gint ett_netflow_rec = -1;
+static void
+dissect_netflow_157(tvbuff_t *tvb, proto_tree *tree, guint16 version,
+ guint offset)
+{
+ guint32 addr;
+
+ tvb_memcpy(tvb, (guint8 *)&addr, offset, 4);
+ proto_tree_add_ipv4(tree, hf_netflow_src_addr, tvb, offset, 4, addr);
+ offset += 4;
+
+ tvb_memcpy(tvb, (guint8 *)&addr, offset, 4);
+ proto_tree_add_ipv4(tree, hf_netflow_dst_addr, tvb, offset, 4, addr);
+ offset += 4;
+
+ tvb_memcpy(tvb, (guint8 *)&addr, offset, 4);
+ proto_tree_add_ipv4(tree, hf_netflow_next_hop, tvb, offset, 4, addr);
+ offset += 4;
+
+ proto_tree_add_item(tree, hf_netflow_input_iface,
+ tvb, offset, 2, FALSE);
+ offset += 2;
+
+ proto_tree_add_item(tree, hf_netflow_output_iface,
+ tvb, offset, 2, FALSE);
+ offset += 2;
+
+ proto_tree_add_item(tree, hf_netflow_packets,
+ tvb, offset, 4, FALSE);
+ offset += 4;
+
+ proto_tree_add_item(tree, hf_netflow_bytes,
+ tvb, offset, 4, FALSE);
+ offset += 4;
+
+ proto_tree_add_item(tree, hf_netflow_start_time,
+ tvb, offset, 4, FALSE);
+ offset += 4;
+
+ proto_tree_add_item(tree, hf_netflow_end_time,
+ tvb, offset, 4, FALSE);
+ offset += 4;
+
+ proto_tree_add_item(tree, hf_netflow_src_port,
+ tvb, offset, 2, FALSE);
+ offset += 2;
+
+ proto_tree_add_item(tree, hf_netflow_dst_port,
+ tvb, offset, 2, FALSE);
+ offset += 2;
+
+ if (version == 1) {
+ offset += 2; /* Skip pad bytes */
+
+ proto_tree_add_item(tree, hf_netflow_ip_prot,
+ tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(tree, hf_netflow_tos,
+ tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(tree, hf_netflow_tcp_flags,
+ tvb, offset, 1, FALSE);
+ offset += 1;
+ } else {
+ if (version == 7) {
+ proto_tree_add_item(tree, hf_netflow_v7_flags,
+ tvb, offset, 1, FALSE);
+ }
+ offset += 1; /* v5 pad byte, v7 flags */
+
+ proto_tree_add_item(tree, hf_netflow_tcp_flags,
+ tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(tree, hf_netflow_ip_prot,
+ tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(tree, hf_netflow_tos,
+ tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(tree, hf_netflow_src_as,
+ tvb, offset, 2, FALSE);
+ offset += 2;
+
+ proto_tree_add_item(tree, hf_netflow_dst_as,
+ tvb, offset, 2, FALSE);
+ offset += 2;
+
+ proto_tree_add_item(tree, hf_netflow_src_mask,
+ tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(tree, hf_netflow_dst_mask,
+ tvb, offset, 1, FALSE);
+ offset += 1;
+
+ offset += 2; /* Skip pad bytes */
+
+ if (version == 7) {
+ proto_tree_add_item(tree, hf_netflow_router_sc,
+ tvb, offset, 4, FALSE);
+ offset += 4;
+ }
+ }
+}
+
static void
dissect_netflow(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
@@ -55,11 +189,9 @@ dissect_netflow(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree *netflow_rec_tree = NULL;
proto_item *ti = NULL, *tf = NULL;
gint offset = 0;
- struct netflow5_hdr nfh;
- struct netflow5_rec nfr;
- guint16 nfh_version, nfh_count, nfh_sample_rate;
- guint32 nfh_sys_uptime, nfh_unix_sec, nfh_unix_nsec;
- guint32 nfh_sequence;
+ guint16 nf_version, nf_count, nf_sample_rate;
+ guint32 nf_sequence;
+ gint header_size, record_size;
int i;
if (check_col(pinfo->cinfo, COL_PROTOCOL))
@@ -68,133 +200,167 @@ dissect_netflow(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
col_clear(pinfo->cinfo, COL_INFO);
/* Determine NetFlow version and number of records */
- tvb_memcpy(tvb, (guint8 *)&nfh, offset, sizeof(nfh));
- nfh_version = g_ntohs(nfh.version);
- nfh_count = g_ntohs(nfh.count);
- nfh_sys_uptime = g_ntohl(nfh.sys_uptime);
- nfh_unix_sec = g_ntohl(nfh.unix_sec);
- nfh_unix_nsec = g_ntohl(nfh.unix_nsec);
- nfh_sample_rate = g_ntohs(nfh.sample_rate);
- nfh_sequence = g_ntohl(nfh.flow_sequence);
+ nf_version = tvb_get_ntohs(tvb, offset);
+ offset += sizeof(nf_version);
+
+ nf_count = tvb_get_ntohs(tvb, offset);
+ offset += sizeof(nf_count);
if (check_col(pinfo->cinfo, COL_INFO))
col_add_fstr(pinfo->cinfo, COL_INFO,
- "Netflow v%u, %u records, sequence number %u",
- nfh_version, nfh_count, nfh_sequence);
+ "v%u, %u records", nf_version, nf_count);
+ /* Handle version-specific issues */
+ switch (nf_version) {
+ case 1:
+ header_size = NETFLOW_V1_HDR;
+ record_size = NETFLOW_V1_REC;
+ break;
+ case 5:
+ header_size = NETFLOW_V5_HDR;
+ record_size = NETFLOW_V5_REC;
+ break;
+ case 7:
+ header_size = NETFLOW_V7_HDR;
+ record_size = NETFLOW_V7_REC;
+ break;
+ case 8:
+ header_size = NETFLOW_V8_HDR;
+ record_size = NETFLOW_V8_REC;
+ case 9:
+ default:
+ return;
+ }
+
+ /* Add NetFlow to the tree */
if (tree != NULL) {
- /* Add NetFlow to to the tree */
ti = proto_tree_add_protocol_format(tree, proto_netflow, tvb,
- offset, sizeof(nfh.version) + sizeof(nfh.count)*sizeof(nfr),
- "Netflow v%u, %u records, sequence number %u",
- nfh_version, nfh_count, nfh_sequence);
+ 0, header_size, "NetFlow, v%u, %u records",
+ nf_version, nf_count);
netflow_tree = proto_item_add_subtree(ti, ett_netflow);
+ } else {
+ return;
+ }
+
+ /* Start adding header information */
+ offset = 0;
+
+ proto_tree_add_uint(netflow_tree, hf_netflow_version,
+ tvb, offset, sizeof(nf_version), nf_version);
+ offset += sizeof(nf_version);
- /* Version */
- proto_tree_add_uint(netflow_tree, hf_netflow_version,
- tvb, offset, sizeof(nfh.version), nfh_version);
-
- /* Number of records */
- proto_tree_add_uint(netflow_tree, hf_netflow_count,
- tvb, offset + 2, sizeof(nfh.count), nfh_count);
-
- /* XXX only support version 5 right now */
- if (nfh_version != 5)
- return;
-
- /* System (router) uptime */
- proto_tree_add_uint_format(netflow_tree, hf_netflow_sys_uptime,
- tvb, offset + 4, sizeof(nfh.sys_uptime), nfh_sys_uptime,
- "System uptime: %u msec", nfh_sys_uptime);
-
- /* Unix time in seconds */
- proto_tree_add_uint_format(netflow_tree, hf_netflow_unix_sec,
- tvb, offset + 8, sizeof(nfh.unix_sec), nfh_unix_sec,
- "Unix time: %u seconds", nfh_unix_sec);
-
- /* Unix time in seconds */
- proto_tree_add_uint_format(netflow_tree, hf_netflow_unix_nsec,
- tvb, offset + 12, sizeof(nfh.unix_nsec), nfh_unix_nsec,
- "Residual: %u nanoseconds", nfh_unix_nsec);
-
- /* On high-speed interfaces often just statistical sample records are produced */
- proto_tree_add_uint_format(netflow_tree, hf_netflow_sample_rate,
- tvb, offset + 22, sizeof(nfh.sample_rate), nfh_sample_rate,
- "Sample Rate: 1/%u", nfh_sample_rate);
-
- for (i = 0; i < nfh_count; i++) {
- guint rec_offset = sizeof(nfh) + i * sizeof(nfr);
-
- tf = proto_tree_add_uint_format(netflow_tree,
- hf_netflow_record, tvb, rec_offset, sizeof(nfr),
- i, "Record %d: %u packets, %u bytes", i+1,
- tvb_get_ntohl(tvb, rec_offset + 16),
- tvb_get_ntohl(tvb, rec_offset + 20));
- netflow_rec_tree = proto_item_add_subtree(tf,
- ett_netflow_rec);
-
- proto_tree_add_text(netflow_rec_tree, tvb,
- rec_offset + 0, 4, "Src Addr: %s",
- ip_to_str(tvb_get_ptr(tvb, rec_offset + 0, 4)));
- proto_tree_add_text(netflow_rec_tree, tvb,
- rec_offset + 4, 4, "Dst Addr: %s",
- ip_to_str(tvb_get_ptr(tvb, rec_offset + 4, 4)));
- proto_tree_add_text(netflow_rec_tree, tvb,
- rec_offset + 8, 4, "Next Hop: %s",
- ip_to_str(tvb_get_ptr(tvb, rec_offset + 8, 4)));
- proto_tree_add_text(netflow_rec_tree, tvb,
- rec_offset + 12, 2, "Input Interface: %u",
- tvb_get_ntohs(tvb, rec_offset + 12));
- proto_tree_add_text(netflow_rec_tree, tvb,
- rec_offset + 14, 2, "Output Interface: %u",
- tvb_get_ntohs(tvb, rec_offset + 14));
- proto_tree_add_text(netflow_rec_tree, tvb,
- rec_offset + 16, 4, "Packets: %u",
- tvb_get_ntohl(tvb, rec_offset + 16));
- proto_tree_add_text(netflow_rec_tree, tvb,
- rec_offset + 20, 4, "Bytes: %u",
- tvb_get_ntohl(tvb, rec_offset + 20));
- proto_tree_add_text(netflow_rec_tree, tvb,
- rec_offset + 24, 4, "Start Time: %u",
- tvb_get_ntohl(tvb, rec_offset + 24));
- proto_tree_add_text(netflow_rec_tree, tvb,
- rec_offset + 28, 4, "End Time: %u",
- tvb_get_ntohl(tvb, rec_offset + 28));
- proto_tree_add_text(netflow_rec_tree, tvb,
- rec_offset + 32, 2, "Source Port: %u",
- tvb_get_ntohs(tvb, rec_offset + 32));
- proto_tree_add_text(netflow_rec_tree, tvb,
- rec_offset + 34, 2, "Dest Port: %u",
- tvb_get_ntohs(tvb, rec_offset + 34));
- proto_tree_add_text(netflow_rec_tree, tvb,
- rec_offset + 37, 1, "TCP Flags: 0x%0x",
- tvb_get_guint8(tvb, rec_offset + 37));
- proto_tree_add_text(netflow_rec_tree, tvb,
- rec_offset + 38, 1, "IP Protocol: %u",
- tvb_get_guint8(tvb, rec_offset + 38));
- proto_tree_add_text(netflow_rec_tree, tvb,
- rec_offset + 39, 1, "Type of service: 0x%02x",
- tvb_get_guint8(tvb, rec_offset + 39));
- proto_tree_add_text(netflow_rec_tree, tvb,
- rec_offset + 40, 2, "Source AS: %u",
- tvb_get_ntohs(tvb, rec_offset + 40));
- proto_tree_add_text(netflow_rec_tree, tvb,
- rec_offset + 42, 2, "Dest AS: %u",
- tvb_get_ntohs(tvb, rec_offset + 42));
- proto_tree_add_text(netflow_rec_tree, tvb,
- rec_offset + 44, 1, "Source Mask: %u",
- tvb_get_guint8(tvb, rec_offset + 44));
- proto_tree_add_text(netflow_rec_tree, tvb,
- rec_offset + 45, 1, "Dest Mask: %u",
- tvb_get_guint8(tvb, rec_offset + 45));
+ proto_tree_add_uint(netflow_tree, hf_netflow_count,
+ tvb, offset, sizeof(nf_count), nf_count);
+ offset += sizeof(nf_count);
+
+ proto_tree_add_item(netflow_tree, hf_netflow_sys_uptime,
+ tvb, offset, 4, FALSE);
+ offset += 4;
+
+ proto_tree_add_item(netflow_tree, hf_netflow_unix_sec,
+ tvb, offset, 4, FALSE);
+ offset += 4;
+
+ proto_tree_add_item(netflow_tree, hf_netflow_unix_nsec,
+ tvb, offset, 4, FALSE);
+ offset += 4;
+
+ /* No more version 1 header */
+
+ if (nf_version != 1) {
+ nf_sequence = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_uint(netflow_tree, hf_netflow_sequence,
+ tvb, offset, sizeof(nf_sequence), nf_sequence);
+ offset += sizeof(nf_sequence);
+
+ /* Add the sequence number */
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_clear(pinfo->cinfo, COL_INFO);
+ col_add_fstr(pinfo->cinfo, COL_INFO,
+ "v%u, %u records, sequence # %u",
+ nf_version, nf_count, nf_sequence);
+ }
+
+ /* No more version 7 header */
+
+ if (nf_version != 7) {
+ /* Engine type and ID */
+ proto_tree_add_item(netflow_tree,
+ hf_netflow_engine_type, tvb, offset,
+ 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(netflow_tree,
+ hf_netflow_engine_id, tvb, offset,
+ 1, FALSE);
+ offset += 1;
+
+ if (nf_version == 8) {
+ /* Engine type and ID */
+ proto_tree_add_item(netflow_tree,
+ hf_netflow_aggregation, tvb, offset,
+ 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(netflow_tree,
+ hf_netflow_agg_version, tvb, offset,
+ 1, FALSE);
+ offset += 1;
+ }
+
+ /*
+ * On high-speed interfaces often just
+ * statistical sample records are produced.
+ */
+ nf_sample_rate = tvb_get_ntohs(tvb, offset);
+ if (nf_version == 5) {
+ /*
+ * Sample rate. Junipers and some Ciscos
+ * include sampling rate in the reserved
+ * header field. Not all the bits are used,
+ * however.
+ */
+ if ((nf_sample_rate & 0xc000) == 0x4000) {
+ nf_sample_rate &= 0x3fff;
+ if (nf_sample_rate == 0)
+ nf_sample_rate = 1;
+ } else
+ nf_sample_rate = 1;
+ }
+ proto_tree_add_uint_format(netflow_tree,
+ hf_netflow_sample_rate, tvb, offset,
+ sizeof(nf_sample_rate), nf_sample_rate,
+ "Sample_rate: 1/%u", nf_sample_rate);
+ offset += sizeof(nf_sample_rate);
}
}
+
+ /* XXX Doesn't support v8 records, yet */
+ if (nf_version == 8)
+ return;
+
+ /* Handle the flow records */
+ for (i = 0; i < nf_count; i++) {
+ guint rec_offset = header_size + i * record_size;
+
+ tf = proto_tree_add_uint_format(netflow_tree,
+ hf_netflow_record, tvb, rec_offset, record_size,
+ i, "Record %d: %u packets, %u bytes", i + 1,
+ tvb_get_ntohl(tvb, rec_offset + 16),
+ tvb_get_ntohl(tvb, rec_offset + 20));
+ netflow_rec_tree = proto_item_add_subtree(tf,
+ ett_netflow_rec);
+
+ dissect_netflow_157(tvb, netflow_rec_tree,
+ nf_version, rec_offset);
+ }
}
void
proto_register_netflow(void)
{
static hf_register_info hf[] = {
+ /* Header */
{ &hf_netflow_version,
{ "Version", "netflow.version", FT_UINT16,
BASE_DEC, NULL, 0x0, "", HFILL }},
@@ -210,15 +376,88 @@ proto_register_netflow(void)
{ &hf_netflow_unix_nsec,
{ "Unix nanonseconds", "netflow.unix_nsec", FT_UINT32,
BASE_DEC, NULL, 0x0, "", HFILL }},
- { &hf_netflow_sample_rate,
- { "Sample Rate", "netflow.sample_rate", FT_UINT16,
+ { &hf_netflow_sequence,
+ { "Sequence number", "netflow.sequence", FT_UINT32,
BASE_DEC, NULL, 0x0, "", HFILL }},
- { &hf_netflow_flow_sequence,
- { "Sequence number", "netflow.flow_sequence", FT_UINT32,
+ { &hf_netflow_engine_type,
+ { "Engine type", "netflow.engine_type", FT_UINT8,
+ BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_engine_id,
+ { "Engine ID", "netflow.engine_id", FT_UINT8,
+ BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_aggregation,
+ { "Aggregation method", "netflow.aggregation", FT_UINT8,
+ BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_agg_version,
+ { "Aggregation version", "netflow.agg_version", FT_UINT8,
+ BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_sample_rate,
+ { "Sample rate", "netflow.sample_rate", FT_UINT16,
BASE_DEC, NULL, 0x0, "", HFILL }},
{ &hf_netflow_record,
{ "Record", "netflow.record", FT_UINT32,
BASE_DEC, NULL, 0x0, "", HFILL }},
+ /* Record */
+ { &hf_netflow_src_addr,
+ { "Source address", "netflow.src_addr", FT_IPv4,
+ BASE_NONE, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_dst_addr,
+ { "Destination address", "netflow.dst_addr", FT_IPv4,
+ BASE_NONE, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_next_hop,
+ { "Next hop", "netflow.next_hop", FT_IPv4,
+ BASE_NONE, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_input_iface,
+ { "Input interface", "netflow.input_iface", FT_UINT16,
+ BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_output_iface,
+ { "Output interface", "netflow.output_iface", FT_UINT16,
+ BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_packets,
+ { "Packets sent", "netflow.packets", FT_UINT32,
+ BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_bytes,
+ { "Bytes sent", "netflow.bytes", FT_UINT32,
+ BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_start_time,
+ { "Start time", "netflow.start_time", FT_UINT32,
+ BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_end_time,
+ { "End time", "netflow.end_time", FT_UINT32,
+ BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_src_port,
+ { "Source port", "netflow.src_port", FT_UINT16,
+ BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_dst_port,
+ { "Destination port", "netflow.dst_port", FT_UINT16,
+ BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_v7_flags,
+ { "Valid flags", "netflow.flags", FT_UINT8,
+ BASE_HEX, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_tcp_flags,
+ { "TCP flags", "netflow.tcp_flags", FT_UINT8,
+ BASE_HEX, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_ip_prot,
+ { "IP protocol", "netflow.ip_prot", FT_UINT8,
+ BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_tos,
+ { "Type of service", "netflow.tos", FT_UINT8,
+ BASE_HEX, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_src_as,
+ { "Source AS", "netflow.src_as", FT_UINT16,
+ BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_dst_as,
+ { "Destination AS", "netflow.dst_as", FT_UINT16,
+ BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_src_mask,
+ { "Source mask", "netflow.src_mask", FT_UINT8,
+ BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_dst_mask,
+ { "Destination mask", "netflow.dst_mask", FT_UINT8,
+ BASE_DEC, NULL, 0x0, "", HFILL }},
+ { &hf_netflow_router_sc,
+ { "Router bypass", "netflow.router_sc", FT_IPv4,
+ BASE_NONE, NULL, 0x0, "", HFILL }},
};
static gint *ett[] = {
@@ -226,7 +465,7 @@ proto_register_netflow(void)
&ett_netflow_rec
};
- proto_netflow = proto_register_protocol("Cisco NetFlow",
+ proto_netflow = proto_register_protocol("NetFlow",
"NetFlow", "netflow");
proto_register_field_array(proto_netflow, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
diff --git a/packet-netflow.h b/packet-netflow.h
index e9f344b9f0..9ec9897206 100644
--- a/packet-netflow.h
+++ b/packet-netflow.h
@@ -2,7 +2,16 @@
* Routines for Cisco NetFlow packet disassembly
* Matthew Smart <smart@monkey.org>
*
- * $Id: packet-netflow.h,v 1.2 2002/09/06 21:22:37 guy Exp $
+ * Cisco links:
+ * http://www.cisco.com/warp/public/cc/pd/iosw/ioft/neflct/tech/napps_wp.htm
+ * http://www.cisco.com/univercd/cc/td/doc/product/rtrmgmt/nfc/nfc_3_0/nfc_ug/nfcform.htm#18955
+ *
+ * ICMP type is stored in the top byte of the destination port and the ICMP
+ * code is stored in the bottom byte.
+ * icmp_type = ntohs(dst_port) >> 8;
+ * icmp_code = ntohs(dst_port) & 0xff;
+ *
+ * $Id: packet-netflow.h,v 1.3 2002/09/09 20:22:51 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -30,39 +39,13 @@
#define UDP_PORT_NETFLOW 5000 /* XXX */
-struct netflow5_hdr {
- guint16 version;
- guint16 count; /* Number of records */
- guint32 sys_uptime; /* Time in msec since router booted */
- guint32 unix_sec; /* Seconds since 0000 UTC 1970 */
- guint32 unix_nsec; /* Residual nsec since 0000 UTC 1970 */
- guint32 flow_sequence; /* Sequence num of flows seen */
- guint8 engine_type; /* Type of flow switching engine */
- guint8 engine_id; /* Slot number of switching engine */
- guint16 sample_rate; /* sample 1/sample_rate packets */
-};
-
-struct netflow5_rec {
- guint32 src_addr;
- guint32 dst_addr;
- guint32 next_hop;
- guint16 input_iface;
- guint16 output_iface;
- guint32 pkts_sent; /* Between start_time and end_time */
- guint32 bytes_sent; /* Between start_time and end_time */
- guint32 start_time; /* Milliseconds since sys_uptime */
- guint32 end_time; /* Milliseconds since sys_uptime */
- guint16 src_port;
- guint16 dst_port;
- guint8 pad1;
- guint8 tcp_flags;
- guint8 ip_prot;
- guint8 tos;
- guint16 src_as;
- guint16 dst_as;
- guint8 src_mask;
- guint8 dst_mask;
- guint16 pad2;
-};
+#define NETFLOW_V1_HDR (4 * 4)
+#define NETFLOW_V1_REC (4 * 13)
+#define NETFLOW_V5_HDR (4 * 6)
+#define NETFLOW_V5_REC (4 * 12)
+#define NETFLOW_V7_HDR (4 * 6)
+#define NETFLOW_V7_REC (4 * 13)
+#define NETFLOW_V8_HDR (4 * 7)
+#define NETFLOW_V8_REC (-1) /* There are many record sizes for v8 */
#endif