From Sven Eckelmann: Remove recursion for aggregated packets in batman dissector
authorwmeier <wmeier@f5534014-38df-0310-8fa8-9805f1628bb7>
Fri, 4 Jun 2010 01:32:21 +0000 (01:32 +0000)
committerwmeier <wmeier@f5534014-38df-0310-8fa8-9805f1628bb7>
Fri, 4 Jun 2010 01:32:21 +0000 (01:32 +0000)
"Different developers wanted to have the recursive dissector for aggregated
 packets changed to a iterative approach."

See Bug #4836: https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=4836

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

epan/dissectors/packet-bat.c

index d6741deffd5169f5af6d8396c42c693cbea8d877..fafd7d2fd3a337efd551e1e0b6dfd560f5d69a37 100644 (file)
@@ -1,6 +1,6 @@
 /* packet-bat.c
  * Routines for B.A.T.M.A.N. Layer 3 dissection
- * Copyright 2008-2009 Sven Eckelmann <sven.eckelmann@gmx.de>
+ * Copyright 2008-2010 Sven Eckelmann <sven.eckelmann@gmx.de>
  *
  * $Id$
  *
@@ -162,7 +162,7 @@ void proto_reg_handoff_bat(void);
 
 /* supported packet dissectors */
 static void dissect_bat_batman(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
-static void dissect_bat_batman_v5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+static int dissect_bat_batman_v5(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
 
 static void dissect_bat_gw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
 
@@ -194,6 +194,7 @@ static guint global_bat_vis_udp_port = BAT_VIS_PORT;
 static void dissect_bat_batman(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
        guint8 version;
+       int offset = 0;
 
        /* set protocol name */
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "BAT_BATMAN");
@@ -202,7 +203,9 @@ static void dissect_bat_batman(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
        version = tvb_get_guint8(tvb, 0);
        switch (version) {
        case 5:
-               dissect_bat_batman_v5(tvb, pinfo, tree);
+               while (tvb_reported_length_remaining(tvb, offset)) {
+                       offset = dissect_bat_batman_v5(tvb, offset, pinfo, tree);
+               }
                break;
        default:
                col_add_fstr(pinfo->cinfo, COL_INFO, "Unsupported Version %d", version);
@@ -228,115 +231,102 @@ static void dissect_bat_gwflags(tvbuff_t *tvb, guint8 gwflags, int offset, proto
 
 }
 
-static void dissect_bat_batman_v5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+static int dissect_bat_batman_v5(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
 {
+       proto_item *tf, *tgw;
+       proto_tree *bat_batman_tree = NULL, *flag_tree;
        struct batman_packet_v5 *batman_packeth;
        const guint8  *old_orig_addr, *orig_addr;
        guint32 old_orig, orig;
        gint i;
 
        tvbuff_t *next_tvb;
-       guint length_remaining;
-       int offset = 0;
 
        batman_packeth = ep_alloc(sizeof(struct batman_packet_v5));
 
-       batman_packeth->version = tvb_get_guint8(tvb, 0);
-       batman_packeth->flags = tvb_get_guint8(tvb, 1);
-       batman_packeth->ttl = tvb_get_guint8(tvb, 2);
-       batman_packeth->gwflags = tvb_get_guint8(tvb, 3);
-       batman_packeth->seqno = tvb_get_ntohs(tvb, 4);
-       batman_packeth->gwport = tvb_get_ntohs(tvb, 6);
-       orig_addr = tvb_get_ptr(tvb, 8, 4);
-       orig = tvb_get_ipv4(tvb, 8);
+       batman_packeth->version = tvb_get_guint8(tvb, offset+0);
+       batman_packeth->flags = tvb_get_guint8(tvb, offset+1);
+       batman_packeth->ttl = tvb_get_guint8(tvb, offset+2);
+       batman_packeth->gwflags = tvb_get_guint8(tvb, offset+3);
+       batman_packeth->seqno = tvb_get_ntohs(tvb, offset+4);
+       batman_packeth->gwport = tvb_get_ntohs(tvb, offset+6);
+       orig_addr = tvb_get_ptr(tvb, offset+8, 4);
+       orig = tvb_get_ipv4(tvb, offset+8);
        SET_ADDRESS(&batman_packeth->orig, AT_IPv4, 4, orig_addr);
-       old_orig_addr = tvb_get_ptr(tvb, 12, 4);
-       old_orig = tvb_get_ipv4(tvb, 12);
+       old_orig_addr = tvb_get_ptr(tvb, offset+12, 4);
+       old_orig = tvb_get_ipv4(tvb, offset+12);
        SET_ADDRESS(&batman_packeth->old_orig, AT_IPv4, 4, old_orig_addr);
-       batman_packeth->tq = tvb_get_guint8(tvb, 16);
-       batman_packeth->hna_len = tvb_get_guint8(tvb, 17);
+       batman_packeth->tq = tvb_get_guint8(tvb, offset+16);
+       batman_packeth->hna_len = tvb_get_guint8(tvb, offset+17);
 
        /* Set info column */
        col_add_fstr(pinfo->cinfo, COL_INFO, "Seq=%u", batman_packeth->seqno);
 
        /* Set tree info */
        if (tree) {
-               proto_item *ti, *tf, *tgw;
-               proto_tree *bat_batman_tree, *flag_tree;
+               proto_item *ti;
 
                if (PTREE_DATA(tree)->visible) {
-                       ti = proto_tree_add_protocol_format(tree, proto_bat_plugin, tvb, 0, BATMAN_PACKET_V5_SIZE,
+                       ti = proto_tree_add_protocol_format(tree, proto_bat_plugin, tvb, offset, BATMAN_PACKET_V5_SIZE,
                                                            "B.A.T.M.A.N., Orig: %s (%s)",
                                                            get_hostname(orig), ip_to_str(batman_packeth->orig.data));
                } else {
-                       ti = proto_tree_add_item(tree, proto_bat_plugin, tvb, 0, BATMAN_PACKET_V5_SIZE, FALSE);
+                       ti = proto_tree_add_item(tree, proto_bat_plugin, tvb, offset, BATMAN_PACKET_V5_SIZE, FALSE);
                }
                bat_batman_tree = proto_item_add_subtree(ti, ett_bat_batman);
+       }
 
-               /* items */
-               proto_tree_add_item(bat_batman_tree, hf_bat_batman_version, tvb, offset, 1, FALSE);
-               offset += 1;
-
-               tf = proto_tree_add_item(bat_batman_tree, hf_bat_batman_flags, tvb, offset, 1, FALSE);
-               /* <flags> */
-               flag_tree =  proto_item_add_subtree(tf, ett_bat_batman_flags);
-               proto_tree_add_boolean(flag_tree, hf_bat_batman_flags_unidirectional, tvb, offset, 1, batman_packeth->flags);
-               proto_tree_add_boolean(flag_tree, hf_bat_batman_flags_directlink, tvb, offset, 1, batman_packeth->flags);
-               /* </flags> */
-               offset += 1;
-
-               proto_tree_add_item(bat_batman_tree, hf_bat_batman_ttl, tvb, offset, 1, FALSE);
-               offset += 1;
-
-               tgw = proto_tree_add_item(bat_batman_tree, hf_bat_batman_gwflags, tvb, offset, 1, FALSE);
-               dissect_bat_gwflags(tvb, batman_packeth->gwflags, offset, tgw);
-               offset += 1;
-
-               proto_tree_add_item(bat_batman_tree, hf_bat_batman_seqno, tvb, offset, 2, FALSE);
-               offset += 2;
+       /* items */
+       proto_tree_add_item(bat_batman_tree, hf_bat_batman_version, tvb, offset, 1, FALSE);
+       offset += 1;
 
-               proto_tree_add_item(bat_batman_tree, hf_bat_batman_gwport, tvb, offset, 2, FALSE);
-               offset += 2;
+       tf = proto_tree_add_item(bat_batman_tree, hf_bat_batman_flags, tvb, offset, 1, FALSE);
+       /* <flags> */
+       flag_tree =  proto_item_add_subtree(tf, ett_bat_batman_flags);
+       proto_tree_add_boolean(flag_tree, hf_bat_batman_flags_unidirectional, tvb, offset, 1, batman_packeth->flags);
+       proto_tree_add_boolean(flag_tree, hf_bat_batman_flags_directlink, tvb, offset, 1, batman_packeth->flags);
+       /* </flags> */
+       offset += 1;
 
-               proto_tree_add_ipv4(bat_batman_tree, hf_bat_batman_orig, tvb, offset, 4, orig);
-               offset += 4;
+       proto_tree_add_item(bat_batman_tree, hf_bat_batman_ttl, tvb, offset, 1, FALSE);
+       offset += 1;
 
-               proto_tree_add_ipv4(bat_batman_tree, hf_bat_batman_old_orig, tvb, offset, 4,  old_orig);
-               offset += 4;
+       tgw = proto_tree_add_item(bat_batman_tree, hf_bat_batman_gwflags, tvb, offset, 1, FALSE);
+       dissect_bat_gwflags(tvb, batman_packeth->gwflags, offset, tgw);
+       offset += 1;
 
-               proto_tree_add_item(bat_batman_tree, hf_bat_batman_tq, tvb, offset, 1, FALSE);
-               offset += 1;
+       proto_tree_add_item(bat_batman_tree, hf_bat_batman_seqno, tvb, offset, 2, FALSE);
+       offset += 2;
 
-               proto_tree_add_item(bat_batman_tree, hf_bat_batman_hna_len, tvb, offset, 1, FALSE);
-               offset += 1;
+       proto_tree_add_item(bat_batman_tree, hf_bat_batman_gwport, tvb, offset, 2, FALSE);
+       offset += 2;
 
-               tap_queue_packet(bat_tap, pinfo, batman_packeth);
+       proto_tree_add_ipv4(bat_batman_tree, hf_bat_batman_orig, tvb, offset, 4, orig);
+       offset += 4;
 
-               for (i = 0; i < batman_packeth->hna_len; i++) {
-                       next_tvb = tvb_new_subset(tvb, offset, 5, 5);
+       proto_tree_add_ipv4(bat_batman_tree, hf_bat_batman_old_orig, tvb, offset, 4,  old_orig);
+       offset += 4;
 
-                       if (have_tap_listener(bat_follow_tap)) {
-                               tap_queue_packet(bat_follow_tap, pinfo, next_tvb);
-                       }
+       proto_tree_add_item(bat_batman_tree, hf_bat_batman_tq, tvb, offset, 1, FALSE);
+       offset += 1;
 
-                       dissect_bat_hna(next_tvb, pinfo, bat_batman_tree);
-                       offset += 5;
-               }
-       }
+       proto_tree_add_item(bat_batman_tree, hf_bat_batman_hna_len, tvb, offset, 1, FALSE);
+       offset += 1;
 
-       /* Calculate offset even when we got no tree */
-       offset = BATMAN_PACKET_V5_SIZE + batman_packeth->hna_len * 5;
+       tap_queue_packet(bat_tap, pinfo, batman_packeth);
 
-       length_remaining = tvb_reported_length_remaining(tvb, offset);
-       if (length_remaining != 0) {
-               next_tvb = tvb_new_subset_remaining(tvb, offset);
+       for (i = 0; i < batman_packeth->hna_len; i++) {
+               next_tvb = tvb_new_subset(tvb, offset, 5, 5);
 
                if (have_tap_listener(bat_follow_tap)) {
                        tap_queue_packet(bat_follow_tap, pinfo, next_tvb);
                }
 
-               dissect_bat_batman(next_tvb, pinfo, tree);
+               dissect_bat_hna(next_tvb, pinfo, bat_batman_tree);
+               offset += 5;
        }
+
+       return offset;
 }
 
 static void dissect_bat_hna(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)