Do the "follow TCP stream" stuff before calling the subdissector, so
[obnox/wireshark/wip.git] / packet-clnp.c
index ac1cc1ca232761d5cf336d75e4ac2a979a07d88a..c17f4a929fec629cc2b28f7648f0a1eb1cc14deb 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-clnp.c
  * Routines for ISO/OSI network and transport protocol packet disassembly
  *
- * $Id: packet-clnp.c,v 1.45 2002/01/17 06:29:16 guy Exp $
+ * $Id: packet-clnp.c,v 1.53 2002/04/07 21:54:48 guy Exp $
  * Laurent Deniel <deniel@worldnet.fr>
  * Ralf Schneider <Ralf.Schneider@t-online.de>
  *
@@ -37,7 +37,7 @@
 #include <ctype.h>
 #include <glib.h>
 #include "prefs.h"
-#include "packet.h"
+#include <epan/packet.h>
 #include "reassemble.h"
 #include "packet-osi.h"
 #include "packet-osi-options.h"
@@ -1405,8 +1405,7 @@ static int osi_decode_ER(tvbuff_t *tvb, int offset,
 } /* osi_decode_ER */
 
 static int osi_decode_UD(tvbuff_t *tvb, int offset, 
-                        packet_info *pinfo, proto_tree *tree,
-                        gboolean *subdissector_found)
+                        packet_info *pinfo, proto_tree *tree)
 {
   proto_item *ti;
   proto_tree *cltp_tree = NULL;
@@ -1522,8 +1521,7 @@ static gboolean dissect_ositp_internal(tvbuff_t *tvb, packet_info *pinfo,
         new_offset = osi_decode_ER(tvb, offset, pinfo, tree);
         break;
       case UD_TPDU :
-        new_offset = osi_decode_UD(tvb, offset, pinfo, tree,
-                                  &subdissector_found);
+        new_offset = osi_decode_UD(tvb, offset, pinfo, tree);
         is_cltp = TRUE;
         break;
       default      :
@@ -1587,12 +1585,12 @@ static void dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
   gint        len;
   guint       next_length;
   proto_tree *discpdu_tree;
-  address     save_dl_src;
-  address     save_dl_dst;
-  address     save_net_src;
-  address     save_net_dst;
-  address     save_src;
-  address     save_dst;
+  volatile address save_dl_src;
+  volatile address save_dl_dst;
+  volatile address save_net_src;
+  volatile address save_net_dst;
+  volatile address save_src;
+  volatile address save_dst;
   gboolean    save_in_error_pkt;
   fragment_data *fd_head;
   tvbuff_t   *volatile next_tvb;
@@ -1806,7 +1804,7 @@ static void dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 
     dissect_osi_options( 0xff, 
                          opt_len,
-                         tvb, offset, pinfo, clnp_tree ); 
+                         tvb, offset, clnp_tree ); 
   }
 
   /* Length of CLNP datagram plus headers above it. */
@@ -1814,39 +1812,43 @@ static void dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 
   offset = cnf_hdr_len;
 
-  /* For now, dissect the payload of segments other than the initial
-     segment as data, rather than handing them off to the transport
-     protocol, just as we do with fragments other than the first
-     fragment in a fragmented IP datagram; in the future, we will
-     probably reassemble fragments for IP, and may reassemble segments
-     for CLNP. */
-  /* If clnp_reassemble is on and this is a segment, then just add the segment
-   * to the hashtable.
+  /* If clnp_reassemble is on, and this is a segment, we have all the
+   * data in the segment, and the checksum is valid, then just add the
+   * segment to the hashtable.
    */
   save_fragmented = pinfo->fragmented;
   if (clnp_reassemble && (cnf_type & CNF_SEG_OK) &&
-       ((cnf_type & CNF_MORE_SEGS) || segment_offset != 0)) {
-    /* We're reassembling, and this is part of a segmented datagram.
-       Add the segment to the hash table if the checksum is ok
-       and the frame isn't truncated. */
-    if (cksum_status != CKSUM_NOT_OK &&
-       (tvb_reported_length(tvb) <= tvb_length(tvb))) {
-      fd_head = fragment_add(tvb, offset, pinfo, du_id, clnp_segment_table,
-                            segment_offset, segment_length - cnf_hdr_len,
-                            cnf_type & CNF_MORE_SEGS);
-    } else {
-      fd_head=NULL;
-    }
+       ((cnf_type & CNF_MORE_SEGS) || segment_offset != 0) &&
+       (tvb_reported_length(tvb) <= tvb_length(tvb)) &&
+       cksum_status != CKSUM_NOT_OK) {
+    fd_head = fragment_add(tvb, offset, pinfo, du_id, clnp_segment_table,
+                          segment_offset, segment_length - cnf_hdr_len,
+                          cnf_type & CNF_MORE_SEGS);
 
     if (fd_head != NULL) {
       fragment_data *fd;
       proto_tree *ft=NULL;
       proto_item *fi=NULL;
 
-      /* OK, we have the complete reassembled payload. */
+      /* OK, we have the complete reassembled payload.
+         Allocate a new tvbuff, referring to the reassembled payload. */
+      next_tvb = tvb_new_real_data(fd_head->data, fd_head->datalen,
+       fd_head->datalen);
+
+      /* Add the tvbuff to the list of tvbuffs to which the tvbuff we
+         were handed refers, so it'll get cleaned up when that tvbuff
+         is cleaned up. */
+      tvb_set_child_real_data_tvbuff(tvb, next_tvb);
+
+      /* Add the defragmented data to the data source list. */
+      add_new_data_source(pinfo->fd, next_tvb, "Reassembled CLNP");
+
+      /* It's not fragmented. */
+      pinfo->fragmented = FALSE;
+
       /* show all segments */
       fi = proto_tree_add_item(clnp_tree, hf_clnp_segments, 
-                tvb, 0, 0, FALSE);
+                next_tvb, 0, -1, FALSE);
       ft = proto_item_add_subtree(fi, ett_clnp_segments);
       for (fd = fd_head->next; fd != NULL; fd = fd->next){
         if (fd->flags & (FD_OVERLAP|FD_OVERLAPCONFLICT
@@ -1865,7 +1867,7 @@ static void dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
             hf = hf_clnp_segment;
           }
           fei = proto_tree_add_none_format(ft, hf, 
-                   tvb, 0, 0,
+                   next_tvb, fd->offset, fd->len,
                    "Frame:%u payload:%u-%u",
                    fd->frame,
                    fd->offset,
@@ -1874,28 +1876,28 @@ static void dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
           fet = proto_item_add_subtree(fei, ett_clnp_segment);
           if (fd->flags&FD_OVERLAP) {
             proto_tree_add_boolean(fet, 
-                 hf_clnp_segment_overlap, tvb, 0, 0, 
+                 hf_clnp_segment_overlap, next_tvb, 0, 0, 
                  TRUE);
           }
           if (fd->flags&FD_OVERLAPCONFLICT) {
             proto_tree_add_boolean(fet, 
-                 hf_clnp_segment_overlap_conflict, tvb, 0, 0, 
+                 hf_clnp_segment_overlap_conflict, next_tvb, 0, 0, 
                  TRUE);
           }
           if (fd->flags&FD_MULTIPLETAILS) {
             proto_tree_add_boolean(fet, 
-                 hf_clnp_segment_multiple_tails, tvb, 0, 0, 
+                 hf_clnp_segment_multiple_tails, next_tvb, 0, 0, 
                  TRUE);
           }
           if (fd->flags&FD_TOOLONGFRAGMENT) {
             proto_tree_add_boolean(fet, 
-                 hf_clnp_segment_too_long_segment, tvb, 0, 0, 
+                 hf_clnp_segment_too_long_segment, next_tvb, 0, 0, 
                  TRUE);
           }
         } else {
           /* nothing of interest for this segment */
           proto_tree_add_none_format(ft, hf_clnp_segment, 
-                   tvb, 0, 0,
+                   next_tvb, fd->offset, fd->len,
                    "Frame:%u payload:%u-%u",
                    fd->frame,
                    fd->offset,
@@ -1910,21 +1912,6 @@ static void dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
           update_col_info = FALSE;
         }
       }
-
-      /* Allocate a new tvbuff, referring to the reassembled payload. */
-      next_tvb = tvb_new_real_data(fd_head->data, fd_head->datalen,
-       fd_head->datalen, "Reassembled");
-
-      /* Add the tvbuff to the list of tvbuffs to which the tvbuff we
-         were handed refers, so it'll get cleaned up when that tvbuff
-         is cleaned up. */
-      tvb_set_child_real_data_tvbuff(tvb, next_tvb);
-
-      /* Add the defragmented data to the data source list. */
-      pinfo->fd->data_src = g_slist_append(pinfo->fd->data_src, next_tvb);
-
-      /* It's not fragmented. */
-      pinfo->fragmented = FALSE;
     } else {
       /* We don't have the complete reassembled payload. */
       next_tvb = NULL;