From Hitoshi Irino:
authorjake <jake@f5534014-38df-0310-8fa8-9805f1628bb7>
Sun, 2 May 2010 12:50:54 +0000 (12:50 +0000)
committerjake <jake@f5534014-38df-0310-8fa8-9805f1628bb7>
Sun, 2 May 2010 12:50:54 +0000 (12:50 +0000)
The function "dissect_v9_pdu" of "epan/dissectors/packet-netflow.c" decodes
NetFlow v9 packets and IPFIX packets with same logic. But, the "scope field" is
different between NetFlow v9 and IPFIX. NetFlow v9 has only 5 kind of scopes.
On the other hand, many Information Elements can be used as scope fields in
IPFIX packets.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@32627 f5534014-38df-0310-8fa8-9805f1628bb7

epan/dissectors/packet-netflow.c

index b3974634c5775d0889676ff40ce47fdf9a213d83..f722a635f56eab188e634f1fc02a7a65d3545035 100644 (file)
@@ -588,6 +588,10 @@ static int dissect_v9_data(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdu
                                int offset, guint16 id, guint length, hdrinfo_t * hdrinfo);
 static guint   dissect_v9_pdu(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree,
                               int offset, struct v9_template * tplt, hdrinfo_t * hdrinfo);
+static guint   dissect_v9_pdu_scope(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree,
+                              int offset, struct v9_template * tplt);
+static guint   dissect_v9_pdu_data(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree,
+                                   int offset, struct v9_template * tplt, hdrinfo_t * hdrinfo, guint8 ipfix_scope_flag);
 static int     dissect_v9_options_template(tvbuff_t *tvb, packet_info *pinfo, proto_tree *pdutree,
                                   int offset, hdrinfo_t *hdrinfo, guint16 flowset_id);
 static int     dissect_v9_template(proto_tree * pdutree, tvbuff_t * tvb, packet_info *pinfo,
@@ -1352,40 +1356,32 @@ static guint
 dissect_v9_pdu(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree, int offset,
     struct v9_template * tplt, hdrinfo_t * hdrinfo)
 {
-        int             orig_offset = offset;
-       int             i;
-       int             rev;
-       nstime_t        ts_start[2], ts_end[2];
-       int             offset_s[2], offset_e[2];
-       nstime_t        ts_delta;
-       nstime_t        ts;
-       guint32         msec_start[2], msec_end[2];
-       guint32         msec_delta;
-       proto_tree *    timetree = 0;
-       proto_item *    timeitem = 0;
-        address         local_addr, remote_addr;
-        guint16         local_port = 0, remote_port = 0, ipv4_id = 0, icmp_id = 0;
-        guint32         uid = 0, pid = 0;
-        int             uname_len;
-        gchar *         uname_str = NULL;
-        int             cmd_len;
-        gchar *         cmd_str = NULL;
-        guint16         got_flags = 0;
-       proto_item *    ti;
-       const guint8 *reftime;
-
-       offset_s[0] = offset_s[1] = offset_e[0] = offset_e[1] = 0;
-       msec_start[0] = msec_start[1] = msec_end[0] = msec_end[1] = 0;
+       int             orig_offset = offset;
+       if (hdrinfo->vspec == 10) {
+               offset += dissect_v9_pdu_data(tvb, pinfo, pdutree, offset, tplt, hdrinfo, 1);
+       } else  {
+               offset += dissect_v9_pdu_scope(tvb, pinfo, pdutree, offset, tplt);
+       }
+       offset += dissect_v9_pdu_data(tvb, pinfo, pdutree, offset, tplt, hdrinfo, 0);
+       return (guint) (offset - orig_offset);
+}
 
+static guint
+dissect_v9_pdu_scope(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree, int offset,
+    struct v9_template * tplt)
+{
+       int             orig_offset = offset;
+       proto_item *    ti;
        if(tplt->scopes != NULL) {
+               int             i;
                for(i = 0; i < tplt->count_scopes; i++) {
                        guint16 type = tplt->scopes[i].type;
-                       guint16 length = tplt->scopes[i].length;
+                       guint16 length = tplt->scopes[i].length;
                        if (!length) {
                                continue;
                        }
-                       switch( type ) {
-                       case 1: /* system */
+                       switch( type ) {
+                       case 1: /* system */
                                ti = proto_tree_add_item(pdutree, hf_cflow_scope_system,
                                       tvb, offset, length, FALSE);
                                if (length > 0 && length != 4) {
@@ -1393,7 +1389,7 @@ dissect_v9_pdu(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree, int of
                                                               "ScopeSystem: invalid size %u", length);
                                } /* zero-length system scope is valid */
                                break;
-                       case 2: /* interface */
+                       case 2: /* interface */
                                ti = proto_tree_add_item(pdutree, hf_cflow_scope_interface,
                                       tvb, offset, length, FALSE);
                                if (length != 4) {
@@ -1401,37 +1397,74 @@ dissect_v9_pdu(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree, int of
                                                               "ScopeInterface: invalid size %u", length);
                                }
                                break;
-                       case 3: /* linecard */
+                       case 3: /* linecard */
                                proto_tree_add_item(pdutree, hf_cflow_scope_linecard,
                                                tvb, offset, length, FALSE);
                                break;
-                       case 4: /* netflow cache */
+                       case 4: /* netflow cache */
                                proto_tree_add_item(pdutree, hf_cflow_scope_cache,
                                                tvb, offset, length, FALSE);
                                break;
-                       case 5: /* tplt */
+                       case 5: /* tplt */
                                proto_tree_add_item(pdutree, hf_cflow_scope_template,
                                                tvb, offset, length, FALSE);
                                break;
-                       default: /* unknown */
+                       default: /* unknown */
                                proto_tree_add_item(pdutree, hf_cflow_scope_unknown,
                                                tvb, offset, length, FALSE);
                                break;
                        }
                        offset += length;
-               }
+               }
        }
+        return (guint) (offset - orig_offset);
+}
 
-       for (i = 0; i < tplt->count; i++) {
-                guint64 pen_type;
+static guint
+dissect_v9_pdu_data(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree, int offset,
+                   struct v9_template * tplt, hdrinfo_t * hdrinfo, guint8 ipfix_scope_flag)
+{
+       int             orig_offset = offset;
+       int             i;
+       int             rev;
+       nstime_t        ts_start[2], ts_end[2];
+       int             offset_s[2], offset_e[2];
+       nstime_t        ts_delta;
+       nstime_t        ts;
+       guint32         msec_start[2], msec_end[2];
+       guint32         msec_delta;
+       proto_tree *    timetree = 0;
+       proto_item *    timeitem = 0;
+       address         local_addr, remote_addr;
+       guint16         local_port = 0, remote_port = 0, ipv4_id = 0, icmp_id = 0;
+       guint32         uid = 0, pid = 0;
+       int             uname_len;
+       gchar *         uname_str = NULL;
+       int             cmd_len;
+       gchar *         cmd_str = NULL;
+       guint16         got_flags = 0;
+       proto_item *    ti;
+       const guint8 *reftime;
+       guint16 count = ipfix_scope_flag ? tplt->count_scopes : tplt->count;
+       struct v9_template_entry *entries = ipfix_scope_flag ? tplt->scopes : tplt->entries;
+       
+       if (entries == NULL) {
+               return 0;
+       }
+
+       offset_s[0] = offset_s[1] = offset_e[0] = offset_e[1] = 0;
+       msec_start[0] = msec_start[1] = msec_end[0] = msec_end[1] = 0;
+
+       for (i = 0; i < count; i++) {
+               guint64 pen_type;
                guint16 type, length;
                guint32 pen = 0;
 
                rev = 0;
-               type = tplt->entries[i].type;
-               length = tplt->entries[i].length;
+               type = entries[i].type;
+               length = entries[i].length;
                if (hdrinfo->vspec == 10 && type & 0x8000) {
-                  pen = tplt->entries[i].pen;
+                 pen = entries[i].pen;
                  if (pen == REVPEN) { /* reverse PEN */
                    type &= 0x7fff;
                    rev = 1;
@@ -1455,7 +1488,7 @@ dissect_v9_pdu(tvbuff_t * tvb, packet_info * pinfo, proto_tree * pdutree, int of
                                    tvb, offset, length,
                                    "Octets: length %u", length);
                        }
-                 break;
+                       break;
 
                case 86: /* PACKETS_PERMANENT */
                case 2: /* packets */