Tvbuffify the IP, ICMP, TCP, UDP, OSI CLNP, OSI COTP, OSI CLTP, and OSI
authorGuy Harris <guy@alum.mit.edu>
Sat, 18 Nov 2000 10:38:33 +0000 (10:38 -0000)
committerGuy Harris <guy@alum.mit.edu>
Sat, 18 Nov 2000 10:38:33 +0000 (10:38 -0000)
ESIS dissectors.

Register the IP dissector and have dissectors that call it directly
(rather than through a port table) call it through a handle.

Add a routine "tvb_set_reported_length()" which a dissector can use if
it was handed a tvbuff that contains more data than is actually in its
part of the packet - for example, handing a padded Ethernet frame to IP;
the routine sets the reported length of the tvbuff (and also adjusts the
actual length, as appropriate).  Then use it in IP.

Given that, "ethertype()" can determine how much of the Ethernet frame
was actually part of an IP datagram (and can do the same for other
protocols under Ethernet that use "tvb_set_reported_length()"; have it
return the actual length, and have "dissect_eth()" and "dissect_vlan()"
use that to mark trailer data in Ethernet II frames as well as in 802.3
frames.

svn path=/trunk/; revision=2658

29 files changed:
epan/packet.h
epan/tvbuff.c
epan/tvbuff.h
packet-clip.c
packet-clnp.c
packet-clnp.h
packet-esis.c
packet-esis.h
packet-eth.c
packet-ethertype.c
packet-gre.c
packet-ip.c
packet-ip.h
packet-mpls.c
packet-msproxy.c
packet-osi-options.c
packet-osi-options.h
packet-osi.c
packet-osi.h
packet-pim.c
packet-ppp.c
packet-raw.c
packet-socks.c
packet-tcp.c
packet-tcp.h
packet-udp.c
packet-udp.h
packet-vlan.c
packet-x25.c

index e73245a79cf100e4ce54d0341b7ee5c75699b2d6..59fe569b956f16f674c9573f3eb690e4859ae614 100644 (file)
@@ -1,7 +1,7 @@
 /* packet.h
  * Definitions for packet disassembly structures and routines
  *
- * $Id: packet.h,v 1.6 2000/11/16 07:35:42 guy Exp $
+ * $Id: packet.h,v 1.7 2000/11/18 10:38:33 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -333,7 +333,7 @@ void dissect_data(tvbuff_t *tvb, int, packet_info *pinfo, proto_tree *tree);
 /* These functions are in ethertype.c */
 void capture_ethertype(guint16 etype, int offset,
                const u_char *pd, packet_counts *ld);
-void ethertype(guint16 etype, tvbuff_t*, int offset_after_ethertype,
+guint ethertype(guint16 etype, tvbuff_t*, int offset_after_ethertype,
                packet_info *pinfo, proto_tree *tree,
                proto_tree *fh_tree, int item_id);
 extern const value_string etype_vals[];
index 4b3ab60bd8211acb28be69503ee16da53dfa47ff..114ab545a1c52f2e007c03634657b4fbbc032b5e 100644 (file)
@@ -9,7 +9,7 @@
  *             the data of a backing tvbuff, or can be a composite of
  *             other tvbuffs.
  *
- * $Id: tvbuff.c,v 1.9 2000/11/14 04:33:34 gram Exp $
+ * $Id: tvbuff.c,v 1.10 2000/11/18 10:38:33 guy Exp $
  *
  * Copyright (c) 2000 by Gilbert Ramirez <gram@xiexie.org>
  *
@@ -632,7 +632,22 @@ tvb_reported_length(tvbuff_t* tvb)
        return tvb->reported_length;
 }
 
+/* Set the reported length of a tvbuff to a given value; used for protocols
+   whose headers contain an explicit length and where the calling
+   dissector's payload may include padding as well as the packet for
+   this protocol.
 
+   Also adjusts the data length. */
+void
+tvb_set_reported_length(tvbuff_t* tvb, guint reported_length)
+{
+       g_assert(tvb->initialized);
+       g_assert(reported_length <= tvb->reported_length);
+
+       tvb->reported_length = reported_length;
+       if (reported_length < tvb->length)
+               tvb->length = reported_length;
+}
 
 
 static guint8*
index 3093ee3c43e79910c74f8d7550b33fc7345a2397..ca24ee4bf4ab234be901c6e4606329164b753874 100644 (file)
@@ -9,7 +9,7 @@
  *             the data of a backing tvbuff, or can be a composite of
  *             other tvbuffs.
  *
- * $Id: tvbuff.h,v 1.7 2000/11/14 04:33:34 gram Exp $
+ * $Id: tvbuff.h,v 1.8 2000/11/18 10:38:33 guy Exp $
  *
  * Copyright (c) 2000 by Gilbert Ramirez <gram@xiexie.org>
  *
@@ -201,6 +201,14 @@ gboolean tvb_offset_exists(tvbuff_t*, gint offset);
 /* Get reported length of buffer */
 guint tvb_reported_length(tvbuff_t*);
 
+/* Set the reported length of a tvbuff to a given value; used for protocols
+   whose headers contain an explicit length and where the calling
+   dissector's payload may include padding as well as the packet for
+   this protocol.
+
+   Also adjusts the data length. */
+void tvb_set_reported_length(tvbuff_t*, guint);
+
 /* Returns the offset from the first byte of real data. This is
  * the same value as 'offset' in tvb_compat() */
 gint tvb_raw_offset(tvbuff_t*);
index 7a86713a89d4063388deca90c769b6f0d197291f..856342a90cb0708f370e73653257e29bf65a243e 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-clip.c
  * Routines for clip packet disassembly
  *
- * $Id: packet-clip.c,v 1.10 2000/05/25 18:32:06 oabad Exp $
+ * $Id: packet-clip.c,v 1.11 2000/11/18 10:38:23 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -40,6 +40,8 @@
 
 static gint ett_clip = -1;
 
+static dissector_handle_t ip_handle;
+
 void
 capture_clip( const u_char *pd, packet_counts *ld ) {
 
@@ -51,8 +53,6 @@ dissect_clip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
   proto_tree   *fh_tree;
   proto_item   *ti;
-  const guint8 *this_pd;
-  int          this_offset;
 
   pinfo->current_proto = "CLIP";
 
@@ -82,8 +82,7 @@ dissect_clip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     fh_tree = proto_item_add_subtree(ti, ett_clip);
     proto_tree_add_text(fh_tree, tvb, 0, 0, "No link information available");
   }
-  tvb_compat(tvb, &this_pd, &this_offset);
-  dissect_ip(this_pd, this_offset, pinfo->fd, tree);
+  call_dissector(ip_handle, tvb, pinfo, tree);
 }
 
 void
@@ -95,3 +94,12 @@ proto_register_clip(void)
 
   proto_register_subtree_array(ett, array_length(ett));
 }
+
+void
+proto_reg_handoff_clip(void)
+{
+  /*
+   * Get a handle for the IP dissector.
+   */
+  ip_handle = find_dissector("ip");
+}
index 27e452ef815d221770831d0681ffb19d308637be..5153a18fb0ad21b8870a28a01549cf8db8267bd8 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.13 2000/08/13 14:08:05 deniel Exp $
+ * $Id: packet-clnp.c,v 1.14 2000/11/18 10:38:24 guy Exp $
  * Laurent Deniel <deniel@worldnet.fr>
  * Ralf Schneider <Ralf.Schneider@t-online.de>
  *
@@ -88,18 +88,6 @@ static int hf_clnp_src         = -1;
 
 /* Fixed part */
 
-struct clnp_header {
-  u_char       cnf_proto_id;   /* network layer protocol identifier */
-  u_char       cnf_hdr_len;    /* length indicator (octets) */
-  u_char       cnf_vers;       /* version/protocol identifier extension */
-  u_char       cnf_ttl;        /* lifetime (500 milliseconds) */
-  u_char       cnf_type;       /* type code */
-  u_char       cnf_seglen_msb; /* pdu segment length (octets) high byte */
-  u_char       cnf_seglen_lsb; /* pdu segment length (octets) low byte */
-  u_char       cnf_cksum_msb;  /* checksum high byte */
-  u_char       cnf_cksum_lsb;  /* checksum low byte */
-};
-
 #define CNF_TYPE               0x1f
 #define CNF_ERR_OK             0x20
 #define CNF_MORE_SEGS          0x40
@@ -122,7 +110,14 @@ static const value_string npdu_type_vals[] = {
 
 /* field position */
 
-#define P_ADDRESS_PART         9
+#define P_CLNP_PROTO_ID                0
+#define P_CLNP_HDR_LEN         1
+#define P_CLNP_VERS            2
+#define P_CLNP_TTL             3
+#define P_CLNP_TYPE            4
+#define P_CLNP_SEGLEN          5
+#define P_CLNP_CKSUM           7
+#define P_CLNP_ADDRESS_PART    9
 
 /* Segmentation part */
 
@@ -314,7 +309,7 @@ static gchar *print_tsap(const u_char *tsap, int length)
 
 } /* print_tsap */
 
-static gboolean osi_decode_tp_var_part(const u_char *pd, int offset,
+static gboolean osi_decode_tp_var_part(tvbuff_t *tvb, int offset,
                                      int vp_length, int class_option,
                                      proto_tree *tree)
 {
@@ -325,10 +320,8 @@ static gboolean osi_decode_tp_var_part(const u_char *pd, int offset,
   guint32 pref_max_tpdu_size;
 
   while (vp_length != 0) {
-    if (!BYTES_ARE_IN_FRAME(offset, 1))
-      return FALSE;
-    code = pd[offset];
-    proto_tree_add_text(tree, NullTVB, offset, 1,
+    code = tvb_get_guint8(tvb, offset);
+    proto_tree_add_text(tree, tvb, offset, 1,
                "Parameter code:   0x%02x (%s)",
                            code,
                            val_to_str(code, tp_vpart_type_vals, "Unknown"));
@@ -337,10 +330,8 @@ static gboolean osi_decode_tp_var_part(const u_char *pd, int offset,
 
     if (vp_length == 0)
       break;
-    if (!BYTES_ARE_IN_FRAME(offset, 1))
-      return FALSE;
-    length = pd[offset];
-    proto_tree_add_text(tree, NullTVB, offset, 1,
+    length = tvb_get_guint8(tvb, offset);
+    proto_tree_add_text(tree, tvb, offset, 1,
                "Parameter length: %u", length);
     offset += 1;
     vp_length -= 1;
@@ -348,29 +339,32 @@ static gboolean osi_decode_tp_var_part(const u_char *pd, int offset,
     switch (code) {
 
     case VP_ACK_TIME:
-      s = EXTRACT_SHORT(&pd[offset]);
-      proto_tree_add_text(tree, NullTVB, offset, length, 
+      s = tvb_get_ntohs(tvb, offset);
+      proto_tree_add_text(tree, tvb, offset, length, 
                              "Ack time (ms): %u", s);
       offset += length;
       vp_length -= length;
       break;
 
     case VP_RES_ERROR:
-      proto_tree_add_text(tree, NullTVB, offset, 1,
-               "Residual error rate, target value: 10^%u", pd[offset]);
+      proto_tree_add_text(tree, tvb, offset, 1,
+               "Residual error rate, target value: 10^%u",
+               tvb_get_guint8(tvb, offset));
       offset += 1;
       length -= 1;
       vp_length -= 1;
 
-      proto_tree_add_text(tree, NullTVB, offset, 1,
-               "Residual error rate, minimum acceptable: 10^%u", pd[offset]);
+      proto_tree_add_text(tree, tvb, offset, 1,
+               "Residual error rate, minimum acceptable: 10^%u",
+               tvb_get_guint8(tvb, offset));
       offset += 1;
       length -= 1;
       vp_length -= 1;
 
 
-      proto_tree_add_text(tree, NullTVB, offset, 1,
-               "Residual error rate, TSDU size of interest: %u", 1<<pd[offset]);
+      proto_tree_add_text(tree, tvb, offset, 1,
+               "Residual error rate, TSDU size of interest: %u",
+               1<<tvb_get_guint8(tvb, offset));
       offset += 1;
       length -= 1;
       vp_length -= 1;
@@ -378,37 +372,37 @@ static gboolean osi_decode_tp_var_part(const u_char *pd, int offset,
       break;
 
     case VP_PRIORITY:
-      s = EXTRACT_SHORT(&pd[offset]);
-      proto_tree_add_text(tree, NullTVB, offset, length,
+      s = tvb_get_ntohs(tvb, offset);
+      proto_tree_add_text(tree, tvb, offset, length,
                "Priority: %u", s);
       offset += length;
       vp_length -= length;
       break;
        
     case VP_TRANSIT_DEL:
-      s1 = EXTRACT_SHORT(&pd[offset]);
-      proto_tree_add_text(tree, NullTVB, offset, 2,
+      s1 = tvb_get_ntohs(tvb, offset);
+      proto_tree_add_text(tree, tvb, offset, 2,
                "Transit delay, target value, calling-called: %u ms", s1);
       offset += 2;
       length -= 2;
       vp_length -= 2;
 
-      s2 = EXTRACT_SHORT(&pd[offset]);
-      proto_tree_add_text(tree, NullTVB, offset, 2,
+      s2 = tvb_get_ntohs(tvb, offset);
+      proto_tree_add_text(tree, tvb, offset, 2,
                "Transit delay, maximum acceptable, calling-called: %u ms", s2);
       offset += 2;
       length -= 2;
       vp_length -= 2;
 
-      s3 = EXTRACT_SHORT(&pd[offset]);
-      proto_tree_add_text(tree, NullTVB, offset, 2,
+      s3 = tvb_get_ntohs(tvb, offset);
+      proto_tree_add_text(tree, tvb, offset, 2,
                "Transit delay, target value, called-calling: %u ms", s3);
       offset += 2;
       length -= 2;
       vp_length -= 2;
 
-      s4 = EXTRACT_SHORT(&pd[offset]);
-      proto_tree_add_text(tree, NullTVB, offset, 2,
+      s4 = tvb_get_ntohs(tvb, offset);
+      proto_tree_add_text(tree, tvb, offset, 2,
                "Transit delay, maximum acceptable, called-calling: %u ms", s4);
       offset += 2;
       length -= 2;
@@ -416,58 +410,58 @@ static gboolean osi_decode_tp_var_part(const u_char *pd, int offset,
       break;
 
     case VP_THROUGHPUT:
-      t1 = pd[offset+0] << 16 | pd[offset+1] << 8 | pd[offset+2];
-      proto_tree_add_text(tree, NullTVB, offset, 3,
+      t1 = tvb_get_ntoh24(tvb, offset);
+      proto_tree_add_text(tree, tvb, offset, 3,
                "Maximum throughput, target value, calling-called:       %u o/s", t1);
       offset += 3;
       length -= 3;
       vp_length -= 3;
 
-      t2 = pd[offset+0] << 16 | pd[offset+1] << 8 | pd[offset+2];
-      proto_tree_add_text(tree, NullTVB, offset, 3,
+      t2 = tvb_get_ntoh24(tvb, offset);
+      proto_tree_add_text(tree, tvb, offset, 3,
                "Maximum throughput, minimum acceptable, calling-called: %u o/s", t2);
       offset += 3;
       length -= 3;
       vp_length -= 3;
 
-      t3 = pd[offset+0] << 16 | pd[offset+1] << 8 | pd[offset+2];
-      proto_tree_add_text(tree, NullTVB, offset, 3,
+      t3 = tvb_get_ntoh24(tvb, offset);
+      proto_tree_add_text(tree, tvb, offset, 3,
                "Maximum throughput, target value, called-calling:       %u o/s", t3);
       offset += 3;
       length -= 3;
       vp_length -= 3;
 
-      t4 = pd[offset+0] << 16 | pd[offset+1] << 8 | pd[offset+2];
-      proto_tree_add_text(tree, NullTVB, offset, 3,
+      t4 = tvb_get_ntoh24(tvb, offset);
+      proto_tree_add_text(tree, tvb, offset, 3,
                "Maximum throughput, minimum acceptable, called-calling: %u o/s", t4);
       offset += 3;
       length -= 3;
       vp_length -= 3;
 
       if (length != 0) {       /* XXX - should be 0 or 12 */
-       t1 = pd[offset+0] << 16 | pd[offset+1] << 8 | pd[offset+2];
-       proto_tree_add_text(tree, NullTVB, offset, 3,
+       t1 = tvb_get_ntoh24(tvb, offset);
+       proto_tree_add_text(tree, tvb, offset, 3,
                "Average throughput, target value, calling-called:       %u o/s", t1);
        offset += 3;
        length -= 3;
        vp_length -= 3;
 
-       t2 = pd[offset+0] << 16 | pd[offset+1] << 8 | pd[offset+2];
-       proto_tree_add_text(tree, NullTVB, offset, 3,
+       t2 = tvb_get_ntoh24(tvb, offset);
+       proto_tree_add_text(tree, tvb, offset, 3,
                "Average throughput, minimum acceptable, calling-called: %u o/s", t2);
        offset += 3;
        length -= 3;
        vp_length -= 3;
 
-       t3 = pd[offset+0] << 16 | pd[offset+1] << 8 | pd[offset+2];
-       proto_tree_add_text(tree, NullTVB, offset, 3,
+       t3 = tvb_get_ntoh24(tvb, offset);
+       proto_tree_add_text(tree, tvb, offset, 3,
                "Average throughput, target value, called-calling:       %u o/s", t3);
        offset += 3;
        length -= 3;
        vp_length -= 3;
 
-       t4 = pd[offset+0] << 16 | pd[offset+1] << 8 | pd[offset+2];
-       proto_tree_add_text(tree, NullTVB, offset, 3,
+       t4 = tvb_get_ntoh24(tvb, offset);
+       proto_tree_add_text(tree, tvb, offset, 3,
                "Average throughput, minimum acceptable, called-calling: %u o/s", t4);
        offset += 3;
        length -= 3;
@@ -476,34 +470,34 @@ static gboolean osi_decode_tp_var_part(const u_char *pd, int offset,
       break;
 
     case VP_SEQ_NR:
-      proto_tree_add_text(tree, NullTVB, offset, 2,
-               "Sequence number: 0x%04x", EXTRACT_SHORT(&pd[offset]));
+      proto_tree_add_text(tree, tvb, offset, 2,
+               "Sequence number: 0x%04x", tvb_get_ntohs(tvb, offset));
       offset += length;
       vp_length -= length;
       break;
 
     case VP_REASSIGNMENT: 
-      proto_tree_add_text(tree, NullTVB, offset, 2,
-               "Reassignment time: %u secs", EXTRACT_SHORT(&pd[offset]));
+      proto_tree_add_text(tree, tvb, offset, 2,
+               "Reassignment time: %u secs", tvb_get_ntohs(tvb, offset));
       offset += length;
       vp_length -= length;
       break;
 
     case VP_FLOW_CNTL:
-      proto_tree_add_text(tree, NullTVB, offset, 4,
-               "Lower window edge: 0x%08x", EXTRACT_LONG(&pd[offset]));
+      proto_tree_add_text(tree, tvb, offset, 4,
+               "Lower window edge: 0x%08x", tvb_get_ntohl(tvb, offset));
       offset += 4;
       length -= 4;
       vp_length -= 4;
 
-      proto_tree_add_text(tree, NullTVB, offset, 2,
-               "Sequence number: 0x%04x", EXTRACT_SHORT(&pd[offset]));
+      proto_tree_add_text(tree, tvb, offset, 2,
+               "Sequence number: 0x%04x", tvb_get_ntohs(tvb, offset));
       offset += 2;
       length -= 2;
       vp_length -= 2;
 
-      proto_tree_add_text(tree, NullTVB, offset, 2,
-               "Credit: 0x%04x", EXTRACT_SHORT(&pd[offset]));
+      proto_tree_add_text(tree, tvb, offset, 2,
+               "Credit: 0x%04x", tvb_get_ntohs(tvb, offset));
       offset += 2;
       length -= 2;
       vp_length -= 2;
@@ -511,75 +505,77 @@ static gboolean osi_decode_tp_var_part(const u_char *pd, int offset,
       break;
 
     case VP_TPDU_SIZE:
-      c1 = pd[offset] & 0x0F;
-      proto_tree_add_text(tree, NullTVB, offset, length, 
+      c1 = tvb_get_guint8(tvb, offset) & 0x0F;
+      proto_tree_add_text(tree, tvb, offset, length, 
                "TPDU size: %u", 2 << c1);
       offset += length;
       vp_length -= length;
       break;
 
     case VP_SRC_TSAP:
-      proto_tree_add_text(tree, NullTVB, offset, length,
-               "Calling TSAP: %s", print_tsap(&pd[offset], length));
+      proto_tree_add_text(tree, tvb, offset, length,
+               "Calling TSAP: %s",
+               print_tsap(tvb_get_ptr(tvb, offset, length), length));
       offset += length;
       vp_length -= length;
       break;
 
     case VP_DST_TSAP:
-      proto_tree_add_text(tree, NullTVB, offset, length,
-               "Called TSAP: %s", print_tsap(&pd[offset], length));
+      proto_tree_add_text(tree, tvb, offset, length,
+               "Called TSAP: %s",
+               print_tsap(tvb_get_ptr(tvb, offset, length), length));
       offset += length;
       vp_length -= length;
       break;
 
     case VP_CHECKSUM:
-      proto_tree_add_text(tree, NullTVB, offset, length,
-               "Checksum: 0x%04x", EXTRACT_SHORT(&pd[offset]));
+      proto_tree_add_text(tree, tvb, offset, length,
+               "Checksum: 0x%04x", tvb_get_ntohs(tvb, offset));
       offset += length;
       vp_length -= length;
       break;
 
     case VP_VERSION_NR:
-      c1 = pd[offset];
-      proto_tree_add_text(tree, NullTVB, offset, length,
+      c1 = tvb_get_guint8(tvb, offset);
+      proto_tree_add_text(tree, tvb, offset, length,
                "Version: %u", c1);
       offset += length;
       vp_length -= length;
       break;
 
     case VP_OPT_SEL:
-      c1 = pd[offset] & 0x0F;
+      c1 = tvb_get_guint8(tvb, offset) & 0x0F;
       switch (class_option) {
 
       case 1:
        if (c1 & 0x8)
-         proto_tree_add_text(tree, NullTVB, offset, 1,
+         proto_tree_add_text(tree, tvb, offset, 1,
                                  "Use of network expedited data");
        else
-         proto_tree_add_text(tree, NullTVB, offset, 1,
+         proto_tree_add_text(tree, tvb, offset, 1,
                                  "Non use of network expedited data");
        if (c1 & 0x4)
-         proto_tree_add_text(tree, NullTVB, offset, 1,
+         proto_tree_add_text(tree, tvb, offset, 1,
                                  "Use of Receipt confirmation");
        else
-         proto_tree_add_text(tree, NullTVB, offset, 1,
+         proto_tree_add_text(tree, tvb, offset, 1,
                                  "Use of explicit AK variant");
        break;
 
       case 4:
        if (c1 & 0x2)
-         proto_tree_add_text(tree, NullTVB, offset, 1,
+         proto_tree_add_text(tree, tvb, offset, 1,
                                  "Non-use 16 bit checksum in class 4");
        else
-         proto_tree_add_text(tree, NullTVB, offset, 1,
+         proto_tree_add_text(tree, tvb, offset, 1,
                                  "Use 16 bit checksum ");
        break;
       }
       if (c1 & 0x1)
-       proto_tree_add_text(tree, NullTVB, offset, 1,
+       proto_tree_add_text(tree, tvb, offset, 1,
                                "Use of transport expedited data transfer\n");
       else
-       proto_tree_add_text(tree, NullTVB, offset, 1,
+       proto_tree_add_text(tree, tvb, offset, 1,
                                "Non-use of transport expedited data transfer");
       offset += length;
       vp_length -= length;
@@ -589,36 +585,36 @@ static gboolean osi_decode_tp_var_part(const u_char *pd, int offset,
       switch (length) {
 
       case 1:
-        pref_max_tpdu_size = pd[offset];
+        pref_max_tpdu_size = tvb_get_guint8(tvb, offset);
         break;
 
       case 2:
-        pref_max_tpdu_size = EXTRACT_SHORT(&pd[offset]);
+        pref_max_tpdu_size = tvb_get_ntohs(tvb, offset);
         break;
 
       case 3:
-       pref_max_tpdu_size = pd[offset+0] << 16 | pd[offset+1] << 8 | pd[offset+2];
+       pref_max_tpdu_size = tvb_get_ntoh24(tvb, offset);
        break;
 
       case 4:
-        pref_max_tpdu_size = EXTRACT_LONG(&pd[offset]);
+        pref_max_tpdu_size = tvb_get_ntohl(tvb, offset);
         break;
 
       default:
-        proto_tree_add_text(tree, NullTVB, offset, length,
+        proto_tree_add_text(tree, tvb, offset, length,
                "Preferred maximum TPDU size: bogus length %u (not 1, 2, 3, or 4)",
                length);
        return FALSE;
       }
-      proto_tree_add_text(tree, NullTVB, offset, length,
+      proto_tree_add_text(tree, tvb, offset, length,
                "Preferred maximum TPDU size: %u", pref_max_tpdu_size*128);
       offset += length;
       vp_length -= length;
       break; 
 
     case VP_INACTIVITY_TIMER:
-      proto_tree_add_text(tree, NullTVB, offset, length,
-               "Inactivity timer: %u ms", EXTRACT_LONG(&pd[offset]));
+      proto_tree_add_text(tree, tvb, offset, length,
+               "Inactivity timer: %u ms", tvb_get_ntohl(tvb, offset));
       offset += length;
       vp_length -= length;
       break;
@@ -626,7 +622,7 @@ static gboolean osi_decode_tp_var_part(const u_char *pd, int offset,
     case VP_PROTECTION:           /* user-defined */
     case VP_PROTO_CLASS:          /* todo */
     default:                     /* unknown, no decoding */
-      proto_tree_add_text(tree, NullTVB, offset, length,
+      proto_tree_add_text(tree, tvb, offset, length,
                              "Parameter value: <not shown>");
       offset += length;
       vp_length -= length;
@@ -637,8 +633,8 @@ static gboolean osi_decode_tp_var_part(const u_char *pd, int offset,
   return TRUE;
 }
 
-static int osi_decode_DR(const u_char *pd, int offset, 
-                        frame_data *fd, proto_tree *tree) 
+static int osi_decode_DR(tvbuff_t *tvb, int offset, 
+                        packet_info *pinfo, proto_tree *tree) 
 {
   proto_tree *cotp_tree;
   proto_item *ti;
@@ -649,8 +645,8 @@ static int osi_decode_DR(const u_char *pd, int offset,
   if (li < LI_MIN_DR) 
     return -1;
   
-  src_ref = EXTRACT_SHORT(&pd[offset + P_SRC_REF]);
-  reason  = pd[offset + P_REASON_IN_DR];
+  src_ref = tvb_get_ntohs(tvb, offset + P_SRC_REF);
+  reason  = tvb_get_guint8(tvb, offset + P_REASON_IN_DR);
 
   switch(reason) {
     case (128+0): str = "Normal Disconnect"; break;
@@ -671,36 +667,41 @@ static int osi_decode_DR(const u_char *pd, int offset,
       break;
   }
 
-  if (check_col(fd, COL_INFO))
-    col_append_fstr(fd, COL_INFO, "DR TPDU src-ref: 0x%04x dst-ref: 0x%04x",
+  if (check_col(pinfo->fd, COL_INFO))
+    col_append_fstr(pinfo->fd, COL_INFO,
+               "DR TPDU src-ref: 0x%04x dst-ref: 0x%04x",
                 src_ref, dst_ref);
 
   if (tree) {
-    ti = proto_tree_add_item(tree, proto_cotp, NullTVB, offset, li + 1, FALSE);
+    ti = proto_tree_add_item(tree, proto_cotp, tvb, offset, li + 1, FALSE);
     cotp_tree = proto_item_add_subtree(ti, ett_cotp);
-    proto_tree_add_text(cotp_tree, NullTVB, offset,      1,
+    proto_tree_add_text(cotp_tree, tvb, offset,      1,
                        "Length indicator: %u", li);
-    proto_tree_add_text(cotp_tree, NullTVB, offset +  1, 1, 
+    proto_tree_add_text(cotp_tree, tvb, offset +  1, 1, 
                        "TPDU code: 0x%x (DR)", tpdu); 
-    proto_tree_add_text(cotp_tree, NullTVB, offset +  2, 2, 
+    proto_tree_add_text(cotp_tree, tvb, offset +  2, 2, 
                        "Destination reference: 0x%04x", dst_ref);
-    proto_tree_add_text(cotp_tree, NullTVB, offset +  4, 2, 
+    proto_tree_add_text(cotp_tree, tvb, offset +  4, 2, 
                        "Source reference: 0x%04x", src_ref);
-    proto_tree_add_text(cotp_tree, NullTVB, offset +  6, 1, 
+    proto_tree_add_text(cotp_tree, tvb, offset +  6, 1, 
                        "Cause: %s", str);
   }
 
   offset += li + 1;
-  old_dissect_data(pd, offset, fd, tree);
 
-  return pi.captured_len;      /* we dissected all of the containing PDU */
+  /* User data */
+  dissect_data(tvb, offset, pinfo, tree);
+  offset += tvb_length_remaining(tvb, offset);
+     /* we dissected all of the containing PDU */
+
+  return offset;
 
 } /* osi_decode_DR */
 
-/* Returns TRUE if we called a sub-dissector, FALSE if not. */
-static gboolean osi_decode_DT(const u_char *pd, int offset, 
-                        frame_data *fd, proto_tree *tree,
-                        gboolean uses_inactive_subset)
+static int osi_decode_DT(tvbuff_t *tvb, int offset, 
+                        packet_info *pinfo, proto_tree *tree,
+                        gboolean uses_inactive_subset,
+                        gboolean *subdissector_found)
 {
   proto_tree *cotp_tree = NULL;
   proto_item *ti;
@@ -708,6 +709,7 @@ static gboolean osi_decode_DT(const u_char *pd, int offset,
   gboolean is_class_234;
   u_int    tpdu_nr ;
   u_int    fragment = 0;
+  tvbuff_t *next_tvb;
     
   /* VP_CHECKSUM is the only parameter allowed in the variable part.
      (This means we may misdissect this if the packet is bad and
@@ -715,12 +717,12 @@ static gboolean osi_decode_DT(const u_char *pd, int offset,
   switch (li) {
 
     case LI_NORMAL_DT_WITH_CHECKSUM      :
-      if (pd[offset + P_VAR_PART_NDT] != VP_CHECKSUM)
+      if (tvb_get_guint8(tvb, offset + P_VAR_PART_NDT) != VP_CHECKSUM)
        return -1;
       /* FALLTHROUGH */
 
     case LI_NORMAL_DT_WITHOUT_CHECKSUM   :
-      tpdu_nr = pd[offset + P_TPDU_NR_234];
+      tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
       if ( tpdu_nr & 0x80 )
        tpdu_nr = tpdu_nr & 0x7F;
       else
@@ -730,12 +732,12 @@ static gboolean osi_decode_DT(const u_char *pd, int offset,
       break;
 
     case LI_EXTENDED_DT_WITH_CHECKSUM    :
-      if (pd[offset + P_VAR_PART_EDT] != VP_CHECKSUM)
+      if (tvb_get_guint8(tvb, offset + P_VAR_PART_EDT) != VP_CHECKSUM)
        return -1;
       /* FALLTHROUGH */
 
     case LI_EXTENDED_DT_WITHOUT_CHECKSUM :
-      tpdu_nr = EXTRACT_LONG(&pd[offset + P_TPDU_NR_234]);
+      tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
       if ( tpdu_nr & 0x80000000 )
        tpdu_nr = tpdu_nr & 0x7FFFFFFF;
       else
@@ -745,7 +747,7 @@ static gboolean osi_decode_DT(const u_char *pd, int offset,
       break;
 
     case LI_NORMAL_DT_CLASS_01           :
-      tpdu_nr = pd[offset + P_TPDU_NR_0_1];
+      tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_0_1);
       if ( tpdu_nr & 0x80 )
        tpdu_nr = tpdu_nr & 0x7F;
       else
@@ -760,22 +762,22 @@ static gboolean osi_decode_DT(const u_char *pd, int offset,
       break;
   }
 
-  if (check_col(fd, COL_INFO))
-    col_append_fstr(fd, COL_INFO, "DT TPDU (%u) dst-ref: 0x%04x %s", 
+  if (check_col(pinfo->fd, COL_INFO))
+    col_append_fstr(pinfo->fd, COL_INFO, "DT TPDU (%u) dst-ref: 0x%04x %s", 
                 tpdu_nr,
                 dst_ref,
                 (fragment)? "(fragment)" : "");
 
   if (tree) {
-    ti = proto_tree_add_item(tree, proto_cotp, NullTVB, offset, li + 1, FALSE);
+    ti = proto_tree_add_item(tree, proto_cotp, tvb, offset, li + 1, FALSE);
     cotp_tree = proto_item_add_subtree(ti, ett_cotp);
-    proto_tree_add_text(cotp_tree, NullTVB, offset, 1,
+    proto_tree_add_text(cotp_tree, tvb, offset, 1,
                        "Length indicator: %u", li);
   }
   offset += 1;
 
   if (tree) {
-    proto_tree_add_text(cotp_tree, NullTVB, offset, 1,
+    proto_tree_add_text(cotp_tree, tvb, offset, 1,
                        "TPDU code: 0x%x (DT)", tpdu); 
 
   }
@@ -784,7 +786,7 @@ static gboolean osi_decode_DT(const u_char *pd, int offset,
 
   if (is_class_234) {
     if (tree) {
-      proto_tree_add_text(cotp_tree, NullTVB, offset, 2,
+      proto_tree_add_text(cotp_tree, tvb, offset, 2,
                          "Destination reference: 0x%04x", dst_ref);
     }
     offset += 2;
@@ -793,7 +795,7 @@ static gboolean osi_decode_DT(const u_char *pd, int offset,
 
   if (is_extended) {
     if (tree) {
-      proto_tree_add_text(cotp_tree, NullTVB, offset, 4, 
+      proto_tree_add_text(cotp_tree, tvb, offset, 4, 
                            "TPDU number: 0x%08x (%s)", 
                            tpdu_nr,
                            (fragment)? "fragment":"complete");
@@ -802,7 +804,7 @@ static gboolean osi_decode_DT(const u_char *pd, int offset,
     li -= 4;
   } else {
     if (tree) {
-      proto_tree_add_text(cotp_tree, NullTVB, offset, 1,
+      proto_tree_add_text(cotp_tree, tvb, offset, 1,
                            "TPDU number: 0x%02x (%s)", 
                            tpdu_nr,
                            (fragment)? "fragment":"complete");
@@ -812,31 +814,35 @@ static gboolean osi_decode_DT(const u_char *pd, int offset,
   }
 
   if (tree)
-    osi_decode_tp_var_part(pd, offset, li, 4, cotp_tree);
+    osi_decode_tp_var_part(tvb, offset, li, 4, cotp_tree);
   offset += li;
 
+  next_tvb = tvb_new_subset(tvb, offset, -1, -1);
   if (uses_inactive_subset){
-       if (old_dissector_try_heuristic(cotp_is_heur_subdissector_list, pd, offset,
-                                       fd, tree)) {
-               return TRUE;
-               }
-       /* Fill in other Dissectors using inactive subset here */
-       old_dissect_data(pd, offset, fd, tree);
-       return FALSE;
-       }
-  else {
-       old_dissect_data(pd, offset, fd, tree);
-       return FALSE;
+       if (dissector_try_heuristic(cotp_is_heur_subdissector_list, next_tvb,
+                                       pinfo, tree)) {
+               *subdissector_found = TRUE;
+       } else {
+         /* Fill in other Dissectors using inactive subset here */
+         dissect_data(next_tvb, 0, pinfo, tree);
        }
+  } else
+       dissect_data(next_tvb, 0, pinfo, tree);
+  offset += tvb_length_remaining(tvb, offset);
+     /* we dissected all of the containing PDU */
+
+  return offset;
+
 } /* osi_decode_DT */
 
-static int osi_decode_ED(const u_char *pd, int offset, 
-                        frame_data *fd, proto_tree *tree)
+static int osi_decode_ED(tvbuff_t *tvb, int offset, 
+                        packet_info *pinfo, proto_tree *tree)
 {
   proto_tree *cotp_tree = NULL;
   proto_item *ti;
   gboolean is_extended;
   u_int    tpdu_nr ;
+  tvbuff_t *next_tvb;
 
   /* ED TPDUs are never fragmented */
 
@@ -846,12 +852,12 @@ static int osi_decode_ED(const u_char *pd, int offset,
   switch (li) {
 
     case LI_NORMAL_DT_WITH_CHECKSUM      :
-      if (pd[offset + P_VAR_PART_NDT] != VP_CHECKSUM)
+      if (tvb_get_guint8(tvb, offset + P_VAR_PART_NDT) != VP_CHECKSUM)
        return -1;
       /* FALLTHROUGH */
 
     case LI_NORMAL_DT_WITHOUT_CHECKSUM   :
-      tpdu_nr = pd[offset + P_TPDU_NR_234];
+      tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
       if ( tpdu_nr & 0x80 )
        tpdu_nr = tpdu_nr & 0x7F;
       else
@@ -860,12 +866,12 @@ static int osi_decode_ED(const u_char *pd, int offset,
       break;
 
     case LI_EXTENDED_DT_WITH_CHECKSUM    :
-      if (pd[offset + P_VAR_PART_EDT] != VP_CHECKSUM)
+      if (tvb_get_guint8(tvb, offset + P_VAR_PART_EDT) != VP_CHECKSUM)
        return -1;
       /* FALLTHROUGH */
 
     case LI_EXTENDED_DT_WITHOUT_CHECKSUM :
-      tpdu_nr = EXTRACT_LONG(&pd[offset + P_TPDU_NR_234]);
+      tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
       if ( tpdu_nr & 0x80000000 )
        tpdu_nr = tpdu_nr & 0x7FFFFFFF;
       else
@@ -879,27 +885,27 @@ static int osi_decode_ED(const u_char *pd, int offset,
       break;
   } /* li */
 
-  if (check_col(fd, COL_INFO))
-    col_append_fstr(fd, COL_INFO, "ED TPDU (%u) dst-ref: 0x%04x", 
+  if (check_col(pinfo->fd, COL_INFO))
+    col_append_fstr(pinfo->fd, COL_INFO, "ED TPDU (%u) dst-ref: 0x%04x", 
                 tpdu_nr, dst_ref);
 
   if (tree) {
-    ti = proto_tree_add_item(tree, proto_cotp, NullTVB, offset, li + 1, FALSE);
+    ti = proto_tree_add_item(tree, proto_cotp, tvb, offset, li + 1, FALSE);
     cotp_tree = proto_item_add_subtree(ti, ett_cotp);
-    proto_tree_add_text(cotp_tree, NullTVB, offset, 1,
+    proto_tree_add_text(cotp_tree, tvb, offset, 1,
                        "Length indicator: %u", li);
   }
   offset += 1;
 
   if (tree) {
-    proto_tree_add_text(cotp_tree, NullTVB, offset, 1, 
+    proto_tree_add_text(cotp_tree, tvb, offset, 1, 
                        "TPDU code: 0x%x (ED)", tpdu);
   }
   offset += 1;
   li -= 1;
 
   if (tree) {
-    proto_tree_add_text(cotp_tree, NullTVB, offset, 2,
+    proto_tree_add_text(cotp_tree, tvb, offset, 2,
                        "Destination reference: 0x%04x", dst_ref);
   }
   offset += 2;
@@ -907,14 +913,14 @@ static int osi_decode_ED(const u_char *pd, int offset,
 
   if (is_extended) {
     if (tree) {
-      proto_tree_add_text(cotp_tree, NullTVB, offset, 4,
+      proto_tree_add_text(cotp_tree, tvb, offset, 4,
                            "TPDU number: 0x%02x", tpdu_nr);
     }
     offset += 4;
     li -= 4;
   } else {
     if (tree) {
-      proto_tree_add_text(cotp_tree, NullTVB, offset, 1,
+      proto_tree_add_text(cotp_tree, tvb, offset, 1,
                            "TPDU number: 0x%02x", tpdu_nr);    
     }
     offset += 1;
@@ -922,17 +928,21 @@ static int osi_decode_ED(const u_char *pd, int offset,
   }
 
   if (tree)
-    osi_decode_tp_var_part(pd, offset, li, 4, cotp_tree);
+    osi_decode_tp_var_part(tvb, offset, li, 4, cotp_tree);
   offset += li;
 
-  old_dissect_data(pd, offset, fd, tree);
+  next_tvb = tvb_new_subset(tvb, offset, -1, -1);
+  dissect_data(next_tvb, 0, pinfo, tree);
+
+  offset += tvb_length_remaining(tvb, offset);
+     /* we dissected all of the containing PDU */
 
-  return pi.captured_len;      /* we dissected all of the containing PDU */
+  return offset;
 
 } /* osi_decode_ED */
 
-static int osi_decode_RJ(const u_char *pd, int offset, 
-                        frame_data *fd, proto_tree *tree)
+static int osi_decode_RJ(tvbuff_t *tvb, int offset, 
+                        packet_info *pinfo, proto_tree *tree)
 {
   proto_tree *cotp_tree;
   proto_item *ti;
@@ -941,11 +951,11 @@ static int osi_decode_RJ(const u_char *pd, int offset,
 
   switch(li) {
     case LI_NORMAL_RJ   :
-      tpdu_nr = pd[offset + P_TPDU_NR_234];
+      tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
       break;
     case LI_EXTENDED_RJ :
-      tpdu_nr = EXTRACT_LONG(&pd[offset + P_TPDU_NR_234]);
-      credit = EXTRACT_SHORT(&pd[offset + P_CDT_IN_RJ]);
+      tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
+      credit = tvb_get_ntohs(tvb, offset + P_CDT_IN_RJ);
       break;
     default :
       return -1;
@@ -953,29 +963,29 @@ static int osi_decode_RJ(const u_char *pd, int offset,
       break;
   }
 
-  if (check_col(fd, COL_INFO))
-    col_append_fstr(fd, COL_INFO, "RJ TPDU (%u) dst-ref: 0x%04x", 
+  if (check_col(pinfo->fd, COL_INFO))
+    col_append_fstr(pinfo->fd, COL_INFO, "RJ TPDU (%u) dst-ref: 0x%04x", 
                 tpdu_nr, dst_ref);
 
   if (tree) {
-    ti = proto_tree_add_item(tree, proto_cotp, NullTVB, offset, li + 1, FALSE);
+    ti = proto_tree_add_item(tree, proto_cotp, tvb, offset, li + 1, FALSE);
     cotp_tree = proto_item_add_subtree(ti, ett_cotp);
-    proto_tree_add_text(cotp_tree, NullTVB, offset,      1,
+    proto_tree_add_text(cotp_tree, tvb, offset,      1,
                        "Length indicator: %u", li);
-    proto_tree_add_text(cotp_tree, NullTVB, offset +  1, 1, 
+    proto_tree_add_text(cotp_tree, tvb, offset +  1, 1, 
                        "TPDU code: 0x%x (RJ)", tpdu); 
     if (li == LI_NORMAL_RJ)
-      proto_tree_add_text(cotp_tree, NullTVB, offset +  1, 1, 
+      proto_tree_add_text(cotp_tree, tvb, offset +  1, 1, 
                          "Credit: %u", cdt);
-    proto_tree_add_text(cotp_tree, NullTVB, offset +  2, 2, 
+    proto_tree_add_text(cotp_tree, tvb, offset +  2, 2, 
                        "Destination reference: 0x%04x", dst_ref);
     if (li == LI_NORMAL_RJ)
-      proto_tree_add_text(cotp_tree, NullTVB, offset +  4, 1, 
+      proto_tree_add_text(cotp_tree, tvb, offset +  4, 1, 
                          "Your TPDU number: 0x%02x", tpdu_nr);
     else {
-      proto_tree_add_text(cotp_tree, NullTVB, offset +  4, 4, 
+      proto_tree_add_text(cotp_tree, tvb, offset +  4, 4, 
                          "Your TPDU number: 0x%02x", tpdu_nr);
-      proto_tree_add_text(cotp_tree, NullTVB, offset +  8, 2, 
+      proto_tree_add_text(cotp_tree, tvb, offset +  8, 2, 
                          "Credit: 0x%02x", credit);
     }
   }
@@ -986,8 +996,8 @@ static int osi_decode_RJ(const u_char *pd, int offset,
 
 } /* osi_decode_RJ */
 
-static int osi_decode_CC(const u_char *pd, int offset, 
-                        frame_data *fd, proto_tree *tree)
+static int osi_decode_CC(tvbuff_t *tvb, int offset, 
+                        packet_info *pinfo, proto_tree *tree)
 {
 
   /* CC & CR decoding in the same function */
@@ -997,27 +1007,28 @@ static int osi_decode_CC(const u_char *pd, int offset,
   u_short src_ref;
   u_char  class_option;
 
-  src_ref = EXTRACT_SHORT(&pd[offset + P_SRC_REF]);
-  class_option = (pd[offset + P_CLASS_OPTION] >> 4 ) & 0x0F;
+  src_ref = tvb_get_ntohs(tvb, offset + P_SRC_REF);
+  class_option = (tvb_get_guint8(tvb, offset + P_CLASS_OPTION) >> 4 ) & 0x0F;
   if (class_option > 4)
     return -1;
 
-  if (check_col(fd, COL_INFO))
-    col_append_fstr(fd, COL_INFO, "%s TPDU src-ref: 0x%04x dst-ref: 0x%04x",
+  if (check_col(pinfo->fd, COL_INFO))
+    col_append_fstr(pinfo->fd, COL_INFO,
+                "%s TPDU src-ref: 0x%04x dst-ref: 0x%04x",
                 (tpdu == CR_TPDU) ? "CR" : "CC",
                 src_ref,
                 dst_ref);
 
   if (tree) {
-    ti = proto_tree_add_item(tree, proto_cotp, NullTVB, offset, li + 1, FALSE);
+    ti = proto_tree_add_item(tree, proto_cotp, tvb, offset, li + 1, FALSE);
     cotp_tree = proto_item_add_subtree(ti, ett_cotp);
-    proto_tree_add_text(cotp_tree, NullTVB, offset, 1,
+    proto_tree_add_text(cotp_tree, tvb, offset, 1,
                        "Length indicator: %u", li);
   }
   offset += 1;
 
   if (tree) {
-    proto_tree_add_text(cotp_tree, NullTVB, offset, 1,
+    proto_tree_add_text(cotp_tree, tvb, offset, 1,
                        "TPDU code: 0x%x (%s)", tpdu,
                        (tpdu == CR_TPDU) ? "CR" : "CC");
   }
@@ -1025,38 +1036,41 @@ static int osi_decode_CC(const u_char *pd, int offset,
   li -= 1;
 
   if (tree) {
-    proto_tree_add_text(cotp_tree, NullTVB, offset, 2,
+    proto_tree_add_text(cotp_tree, tvb, offset, 2,
                        "Destination reference: 0x%04x", dst_ref);
   }
   offset += 2;
   li -= 2;
 
   if (tree) {
-    proto_tree_add_text(cotp_tree, NullTVB, offset, 2,
+    proto_tree_add_text(cotp_tree, tvb, offset, 2,
                        "Source reference: 0x%04x", src_ref);
   }
   offset += 2;
   li -= 2;
 
   if (tree) {
-    proto_tree_add_text(cotp_tree, NullTVB, offset, 1,
+    proto_tree_add_text(cotp_tree, tvb, offset, 1,
                        "Class option: 0x%02x", class_option);
   }
   offset += 1;
   li -= 1;
 
   if (tree)
-    osi_decode_tp_var_part(pd, offset, li, class_option, cotp_tree);
+    osi_decode_tp_var_part(tvb, offset, li, class_option, cotp_tree);
   offset += li;
 
-  old_dissect_data(pd, offset, fd, tree);
+  /* User data */
+  dissect_data(tvb, offset, pinfo, tree);
+  offset += tvb_length_remaining(tvb, offset);
+     /* we dissected all of the containing PDU */
 
-  return pi.captured_len;      /* we dissected all of the containing PDU */
+  return offset;
 
 } /* osi_decode_CC */
 
-static int osi_decode_DC(const u_char *pd, int offset, 
-                        frame_data *fd, proto_tree *tree)
+static int osi_decode_DC(tvbuff_t *tvb, int offset, 
+                        packet_info *pinfo, proto_tree *tree)
 {
   proto_tree *cotp_tree = NULL;
   proto_item *ti;
@@ -1065,52 +1079,53 @@ static int osi_decode_DC(const u_char *pd, int offset,
   if (li > LI_MAX_DC) 
     return -1;
 
-  src_ref = EXTRACT_SHORT(&pd[offset + P_SRC_REF]);
+  src_ref = tvb_get_ntohs(tvb, offset + P_SRC_REF);
 
-  if (check_col(fd, COL_INFO))
-    col_append_fstr(fd, COL_INFO, "DC TPDU src-ref: 0x%04x dst-ref: 0x%04x", 
+  if (check_col(pinfo->fd, COL_INFO))
+    col_append_fstr(pinfo->fd, COL_INFO,
+                "DC TPDU src-ref: 0x%04x dst-ref: 0x%04x", 
                 src_ref,
                 dst_ref);
 
   if (tree) {
-    ti = proto_tree_add_item(tree, proto_cotp, NullTVB, offset, li + 1, FALSE);
+    ti = proto_tree_add_item(tree, proto_cotp, tvb, offset, li + 1, FALSE);
     cotp_tree = proto_item_add_subtree(ti, ett_cotp);
-    proto_tree_add_text(cotp_tree, NullTVB, offset, 1,
+    proto_tree_add_text(cotp_tree, tvb, offset, 1,
                        "Length indicator: %u", li);
   }
   offset += 1;
 
   if (tree) {
-    proto_tree_add_text(cotp_tree, NullTVB, offset, 1,
+    proto_tree_add_text(cotp_tree, tvb, offset, 1,
                        "TPDU code: 0x%x (DC)", tpdu);
   }
   offset += 1;
   li -= 1;
 
   if (tree) {
-    proto_tree_add_text(cotp_tree, NullTVB, offset, 2,
+    proto_tree_add_text(cotp_tree, tvb, offset, 2,
                        "Destination reference: 0x%04x", dst_ref);
   }
   offset += 2;
   li -= 2;
 
   if (tree) {
-    proto_tree_add_text(cotp_tree, NullTVB, offset, 2,
+    proto_tree_add_text(cotp_tree, tvb, offset, 2,
                        "Source reference: 0x%04x", src_ref);
   }
   offset += 2;
   li -= 2;
 
   if (tree)
-    osi_decode_tp_var_part(pd, offset, li, 4, cotp_tree);
+    osi_decode_tp_var_part(tvb, offset, li, 4, cotp_tree);
   offset += li;
 
   return offset;
 
 } /* osi_decode_DC */
 
-static int osi_decode_AK(const u_char *pd, int offset, 
-                        frame_data *fd, proto_tree *tree)
+static int osi_decode_AK(tvbuff_t *tvb, int offset, 
+                        packet_info *pinfo, proto_tree *tree)
 {
   proto_tree *cotp_tree = NULL;
   proto_item *ti;
@@ -1122,94 +1137,94 @@ static int osi_decode_AK(const u_char *pd, int offset,
 
   if (is_LI_NORMAL_AK(li)) {
 
-    tpdu_nr = pd[offset + P_TPDU_NR_234];
+    tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
 
-    if (check_col(fd, COL_INFO))
-      col_append_fstr(fd, COL_INFO, "AK TPDU (%u) dst-ref: 0x%04x", 
+    if (check_col(pinfo->fd, COL_INFO))
+      col_append_fstr(pinfo->fd, COL_INFO, "AK TPDU (%u) dst-ref: 0x%04x", 
                   tpdu_nr, dst_ref);
 
     if (tree) {
-      ti = proto_tree_add_item(tree, proto_cotp, NullTVB, offset, li + 1, FALSE);
+      ti = proto_tree_add_item(tree, proto_cotp, tvb, offset, li + 1, FALSE);
       cotp_tree = proto_item_add_subtree(ti, ett_cotp);
-      proto_tree_add_text(cotp_tree, NullTVB, offset, 1,
+      proto_tree_add_text(cotp_tree, tvb, offset, 1,
                          "Length indicator: %u", li);
     }
     offset += 1;
 
     if (tree) {
-      proto_tree_add_text(cotp_tree, NullTVB, offset, 1,
+      proto_tree_add_text(cotp_tree, tvb, offset, 1,
                          "TPDU code: 0x%x (AK)", tpdu);
-      proto_tree_add_text(cotp_tree, NullTVB, offset, 1,
+      proto_tree_add_text(cotp_tree, tvb, offset, 1,
                          "Credit: %u", cdt);
     }
     offset += 1;
     li -= 1;
 
     if (tree) {
-      proto_tree_add_text(cotp_tree, NullTVB, offset, 2,
+      proto_tree_add_text(cotp_tree, tvb, offset, 2,
                          "Destination reference: 0x%04x", dst_ref);
     }
     offset += 2;
     li -= 2;
 
     if (tree) {
-      proto_tree_add_text(cotp_tree, NullTVB, offset, 1,
+      proto_tree_add_text(cotp_tree, tvb, offset, 1,
                          "Your TPDU number: 0x%02x", tpdu_nr);
     }
     offset += 1;
     li -= 1;
 
     if (tree)
-      osi_decode_tp_var_part(pd, offset, li, 4, cotp_tree);
+      osi_decode_tp_var_part(tvb, offset, li, 4, cotp_tree);
     offset += li;
 
   } else { /* extended format */
     
-    tpdu_nr   = EXTRACT_LONG(&pd[offset + P_TPDU_NR_234]);
-    cdt_in_ak = EXTRACT_SHORT(&pd[offset + P_CDT_IN_AK]);
+    tpdu_nr   = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
+    cdt_in_ak = tvb_get_ntohs(tvb, offset + P_CDT_IN_AK);
 
-    if (check_col(fd, COL_INFO))
-      col_append_fstr(fd, COL_INFO, "AK TPDU (%u) dst-ref: 0x%04x", 
+    if (check_col(pinfo->fd, COL_INFO))
+      col_append_fstr(pinfo->fd, COL_INFO, "AK TPDU (%u) dst-ref: 0x%04x", 
                   tpdu_nr, dst_ref);
     
     if (tree) {
-      ti = proto_tree_add_item(tree, proto_cotp, NullTVB, offset, li + 1, FALSE);
+      ti = proto_tree_add_item(tree, proto_cotp, tvb, offset, li + 1, FALSE);
       cotp_tree = proto_item_add_subtree(ti, ett_cotp);
-      proto_tree_add_text(cotp_tree, NullTVB, offset, 1,
+      proto_tree_add_text(cotp_tree, tvb, offset, 1,
                          "Length indicator: %u", li);
     }
     offset += 1;
 
     if (tree) {
-      proto_tree_add_text(cotp_tree, NullTVB, offset, 1,
+      proto_tree_add_text(cotp_tree, tvb, offset, 1,
                          "TPDU code: 0x%x (AK)", tpdu);
     }
     offset += 1;
     li -= 1;
 
     if (tree) {
-      proto_tree_add_text(cotp_tree, NullTVB, offset, 2,
+      proto_tree_add_text(cotp_tree, tvb, offset, 2,
                          "Destination reference: 0x%04x", dst_ref);
     }
     offset += 2;
     li -= 2;
 
     if (tree) {
-      proto_tree_add_text(cotp_tree, NullTVB, offset, 4,
+      proto_tree_add_text(cotp_tree, tvb, offset, 4,
                          "Your TPDU number: 0x%08x", tpdu_nr);
     }
     offset += 4;
     li -= 4;
 
     if (tree) {
-      proto_tree_add_text(cotp_tree, NullTVB, offset, 2,
+      proto_tree_add_text(cotp_tree, tvb, offset, 2,
                          "Credit: 0x%04x", cdt_in_ak);
     }
     offset += 2;
     li -= 2;
     
     if (tree)
-      osi_decode_tp_var_part(pd, offset, li, 4, cotp_tree);
+      osi_decode_tp_var_part(tvb, offset, li, 4, cotp_tree);
     offset += li;
 
   } /* is_LI_NORMAL_AK */
@@ -1218,8 +1233,8 @@ static int osi_decode_AK(const u_char *pd, int offset,
 
 } /* osi_decode_AK */
 
-static int osi_decode_EA(const u_char *pd, int offset, 
-                        frame_data *fd, proto_tree *tree)
+static int osi_decode_EA(tvbuff_t *tvb, int offset, 
+                        packet_info *pinfo, proto_tree *tree)
 {
   proto_tree *cotp_tree = NULL;
   proto_item *ti;
@@ -1235,24 +1250,24 @@ static int osi_decode_EA(const u_char *pd, int offset,
   switch (li) {
 
     case LI_NORMAL_EA_WITH_CHECKSUM      :
-      if (pd[offset + P_VAR_PART_NDT] != VP_CHECKSUM ||
-               pd[offset + P_VAR_PART_NDT + 1] != 2)
+      if (tvb_get_guint8(tvb, offset + P_VAR_PART_NDT) != VP_CHECKSUM ||
+               tvb_get_guint8(tvb, offset + P_VAR_PART_NDT + 1) != 2)
        return -1;
       /* FALLTHROUGH */
 
     case LI_NORMAL_EA_WITHOUT_CHECKSUM   :
-      tpdu_nr = pd[offset + P_TPDU_NR_234];
+      tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234);
       is_extended = FALSE;
       break;
 
     case LI_EXTENDED_EA_WITH_CHECKSUM    :
-      if (pd[offset + P_VAR_PART_EDT] != VP_CHECKSUM ||
-               pd[offset + P_VAR_PART_EDT + 1] != 2)
+      if (tvb_get_guint8(tvb, offset + P_VAR_PART_EDT) != VP_CHECKSUM ||
+               tvb_get_guint8(tvb, offset + P_VAR_PART_EDT + 1) != 2)
        return -1;
       /* FALLTHROUGH */
 
     case LI_EXTENDED_EA_WITHOUT_CHECKSUM :
-      tpdu_nr = EXTRACT_LONG(&pd[offset + P_TPDU_NR_234]);
+      tpdu_nr = tvb_get_ntohl(tvb, offset + P_TPDU_NR_234);
       is_extended = TRUE;
       break;
 
@@ -1262,27 +1277,27 @@ static int osi_decode_EA(const u_char *pd, int offset,
       break;
   } /* li */
 
-  if (check_col(fd, COL_INFO))
-    col_append_fstr(fd, COL_INFO, 
+  if (check_col(pinfo->fd, COL_INFO))
+    col_append_fstr(pinfo->fd, COL_INFO, 
                 "EA TPDU (%u) dst-ref: 0x%04x", tpdu_nr, dst_ref);
 
   if (tree) {
-    ti = proto_tree_add_item(tree, proto_cotp, NullTVB, offset, li + 1, FALSE);
+    ti = proto_tree_add_item(tree, proto_cotp, tvb, offset, li + 1, FALSE);
     cotp_tree = proto_item_add_subtree(ti, ett_cotp);
-    proto_tree_add_text(cotp_tree, NullTVB, offset, 1,
+    proto_tree_add_text(cotp_tree, tvb, offset, 1,
                        "Length indicator: %u", li);
   }
   offset += 1;
 
   if (tree) {
-    proto_tree_add_text(cotp_tree, NullTVB, offset, 1,
+    proto_tree_add_text(cotp_tree, tvb, offset, 1,
                        "TPDU code: 0x%x (EA)", tpdu);
   }
   offset += 1;
   li -= 1;
 
   if (tree) {
-    proto_tree_add_text(cotp_tree, NullTVB, offset, 2,
+    proto_tree_add_text(cotp_tree, tvb, offset, 2,
                        "Destination reference: 0x%04x", dst_ref);
   }
   offset += 2;
@@ -1290,14 +1305,14 @@ static int osi_decode_EA(const u_char *pd, int offset,
 
   if (is_extended) {
     if (tree) {
-      proto_tree_add_text(cotp_tree, NullTVB, offset, 4,
+      proto_tree_add_text(cotp_tree, tvb, offset, 4,
                            "Your TPDU number: 0x%08x", tpdu_nr);
     }
     offset += 4;
     li -= 4;
   } else {
     if (tree) {
-      proto_tree_add_text(cotp_tree, NullTVB, offset, 1,
+      proto_tree_add_text(cotp_tree, tvb, offset, 1,
                            "Your TPDU number: 0x%02x", tpdu_nr);
     }
     offset += 1;
@@ -1305,15 +1320,15 @@ static int osi_decode_EA(const u_char *pd, int offset,
   }
 
   if (tree)
-    osi_decode_tp_var_part(pd, offset, li, 4, cotp_tree);
+    osi_decode_tp_var_part(tvb, offset, li, 4, cotp_tree);
   offset += li;
 
   return offset;
 
 } /* osi_decode_EA */
 
-static int osi_decode_ER(const u_char *pd, int offset, 
-                        frame_data *fd, proto_tree *tree)
+static int osi_decode_ER(tvbuff_t *tvb, int offset, 
+                        packet_info *pinfo, proto_tree *tree)
 {
   proto_tree *cotp_tree;
   proto_item *ti;
@@ -1322,7 +1337,7 @@ static int osi_decode_ER(const u_char *pd, int offset,
   if (li > LI_MAX_ER) 
     return -1;
 
-  switch(pd[offset + P_REJECT_ER]) {
+  switch(tvb_get_guint8(tvb, offset + P_REJECT_ER)) {
     case 0 :
       str = "Reason not specified";
       break;
@@ -1341,19 +1356,19 @@ static int osi_decode_ER(const u_char *pd, int offset,
       break;
   }
 
-  if (check_col(fd, COL_INFO))
-    col_append_fstr(fd, COL_INFO, "ER TPDU dst-ref: 0x%04x", dst_ref);
+  if (check_col(pinfo->fd, COL_INFO))
+    col_append_fstr(pinfo->fd, COL_INFO, "ER TPDU dst-ref: 0x%04x", dst_ref);
 
   if (tree) {
-    ti = proto_tree_add_item(tree, proto_cotp, NullTVB, offset, li + 1, FALSE);
+    ti = proto_tree_add_item(tree, proto_cotp, tvb, offset, li + 1, FALSE);
     cotp_tree = proto_item_add_subtree(ti, ett_cotp);
-    proto_tree_add_text(cotp_tree, NullTVB, offset,      1,
+    proto_tree_add_text(cotp_tree, tvb, offset,      1,
                        "Length indicator: %u", li);
-    proto_tree_add_text(cotp_tree, NullTVB, offset +  1, 1, 
+    proto_tree_add_text(cotp_tree, tvb, offset +  1, 1, 
                        "TPDU code: 0x%x (ER)", tpdu); 
-    proto_tree_add_text(cotp_tree, NullTVB, offset +  2, 2, 
+    proto_tree_add_text(cotp_tree, tvb, offset +  2, 2, 
                        "Destination reference: 0x%04x", dst_ref);
-    proto_tree_add_text(cotp_tree, NullTVB, offset +  4, 1, 
+    proto_tree_add_text(cotp_tree, tvb, offset +  4, 1, 
                        "Reject cause: %s", str);
   }
 
@@ -1363,37 +1378,43 @@ static int osi_decode_ER(const u_char *pd, int offset,
 
 } /* osi_decode_ER */
 
-/* Returns TRUE if we called a sub-dissector, FALSE if not. */
-static gboolean osi_decode_UD(const u_char *pd, int offset, 
-                        frame_data *fd, proto_tree *tree)
+static int osi_decode_UD(tvbuff_t *tvb, int offset, 
+                        packet_info *pinfo, proto_tree *tree,
+                        gboolean *subdissector_found)
 {
   proto_item *ti;
   proto_tree *cltp_tree = NULL;
+  tvbuff_t   *next_tvb;
 
-  if (check_col(fd, COL_INFO))
-    col_append_str(fd, COL_INFO, "UD TPDU");
+  if (check_col(pinfo->fd, COL_INFO))
+    col_append_str(pinfo->fd, COL_INFO, "UD TPDU");
 
   if (tree) {
-    ti = proto_tree_add_item(tree, proto_cltp, NullTVB, offset, li + 1, FALSE);
+    ti = proto_tree_add_item(tree, proto_cltp, tvb, offset, li + 1, FALSE);
     cltp_tree = proto_item_add_subtree(ti, ett_cltp);
-    proto_tree_add_text(cltp_tree, NullTVB, offset, 1,
+    proto_tree_add_text(cltp_tree, tvb, offset, 1,
                        "Length indicator: %u", li);
   }
   offset += 1;
 
   if (tree) {
-    proto_tree_add_text(cltp_tree, NullTVB, offset, 1, 
+    proto_tree_add_text(cltp_tree, tvb, offset, 1, 
                        "TPDU code: 0x%x (UD)", tpdu);
   }
   offset += 1;
   li -= 1;
 
   if (tree)
-    osi_decode_tp_var_part(pd, offset, li, 0, cltp_tree);
+    osi_decode_tp_var_part(tvb, offset, li, 0, cltp_tree);
   offset += li;
 
-  old_dissect_data(pd, offset, fd, tree);
-  return FALSE;
+  next_tvb = tvb_new_subset(tvb, offset, -1, -1);
+  dissect_data(next_tvb, 0, pinfo, tree);
+  offset += tvb_length_remaining(tvb, offset);
+     /* we dissected all of the containing PDU */
+
+  return offset;
+
 } /* osi_decode_UD */
 
 /* Returns TRUE if we found at least one valid COTP or CLTP PDU, FALSE
@@ -1404,100 +1425,99 @@ static gboolean osi_decode_UD(const u_char *pd, int offset,
    protocols' headers mean the same thing - length and PDU type - and the
    only valid CLTP PDU type is not a valid COTP PDU type, so we'll handle
    both of them here. */
-static gboolean dissect_ositp_internal(const u_char *pd, int offset,
-                 frame_data *fd, proto_tree *tree,
-                 gboolean uses_inactive_subset) 
+static gboolean dissect_ositp_internal(tvbuff_t *tvb, packet_info *pinfo,
+                 proto_tree *tree, gboolean uses_inactive_subset) 
 {
+  int offset = 0;
   gboolean first_tpdu = TRUE;
   int new_offset;
   gboolean found_ositp = FALSE;
   gboolean is_cltp = FALSE;
   gboolean subdissector_found = FALSE;
 
+  if (!proto_is_protocol_enabled(proto_cotp))
+    return FALSE;      /* COTP has been disabled */
+  /* XXX - what about CLTP? */
+
+  pinfo->current_proto = "COTP";
+
   /* Initialize the COL_INFO field; each of the TPDUs will have its
      information appended. */
-  if (check_col(fd, COL_INFO))
-    col_add_str(fd, COL_INFO, "");
+  if (check_col(pinfo->fd, COL_INFO))
+    col_add_str(pinfo->fd, COL_INFO, "");
 
-  while (IS_DATA_IN_FRAME(offset)) {
+  while (tvb_offset_exists(tvb, offset)) {
     if (!first_tpdu) {
-      if (check_col(fd, COL_INFO))
-        col_append_str(fd, COL_INFO, ", ");
+      if (check_col(pinfo->fd, COL_INFO))
+        col_append_str(pinfo->fd, COL_INFO, ", ");
     }
-    if ((li = pd[offset + P_LI]) == 0) {
-      if (check_col(fd, COL_INFO))
-        col_append_str(fd, COL_INFO, "Length indicator is zero");
+    if ((li = tvb_get_guint8(tvb, offset + P_LI)) == 0) {
+      if (check_col(pinfo->fd, COL_INFO))
+        col_append_str(pinfo->fd, COL_INFO, "Length indicator is zero");
       if (!first_tpdu)
-        old_dissect_data(pd, offset, fd, tree);
-      return found_ositp;
-    }
-    if (!BYTES_ARE_IN_FRAME(offset, P_LI + li + 1)) {
-      if (check_col(fd, COL_INFO))
-        col_append_str(fd, COL_INFO, "Captured data in frame doesn't include entire frame");
-      if (!first_tpdu)
-        old_dissect_data(pd, offset, fd, tree);
+        dissect_data(tvb, offset, pinfo, tree);
       return found_ositp;
     }
 
-    tpdu    = (pd[offset + P_TPDU] >> 4) & 0x0F;
-    cdt     = pd[offset + P_CDT] & 0x0F;
-    dst_ref = EXTRACT_SHORT(&pd[offset + P_DST_REF]);
+    tpdu    = (tvb_get_guint8(tvb, offset + P_TPDU) >> 4) & 0x0F;
+    if (tpdu == UD_TPDU)
+      pinfo->current_proto = "CLTP";   /* connectionless transport */
+    cdt     = tvb_get_guint8(tvb, offset + P_CDT) & 0x0F;
+    dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF);
 
     switch (tpdu) {
       case CC_TPDU :
       case CR_TPDU :
-        new_offset = osi_decode_CC(pd, offset, fd, tree);
+        new_offset = osi_decode_CC(tvb, offset, pinfo, tree);
         break;
       case DR_TPDU :
-        new_offset = osi_decode_DR(pd, offset, fd, tree);
+        new_offset = osi_decode_DR(tvb, offset, pinfo, tree);
         break;
       case DT_TPDU :
-        if (osi_decode_DT(pd, offset, fd, tree, uses_inactive_subset))
-          subdissector_found = TRUE;
-        new_offset = pi.captured_len;  /* DT PDUs run to the end of the packet */
+        new_offset = osi_decode_DT(tvb, offset, pinfo, tree,
+                                  uses_inactive_subset, &subdissector_found);
         break;
       case ED_TPDU :
-        new_offset = osi_decode_ED(pd, offset, fd, tree);
+        new_offset = osi_decode_ED(tvb, offset, pinfo, tree);
         break;
       case RJ_TPDU :
-        new_offset = osi_decode_RJ(pd, offset, fd, tree);
+        new_offset = osi_decode_RJ(tvb, offset, pinfo, tree);
         break;
       case DC_TPDU :
-        new_offset = osi_decode_DC(pd, offset, fd, tree);
+        new_offset = osi_decode_DC(tvb, offset, pinfo, tree);
         break;
       case AK_TPDU :
-        new_offset = osi_decode_AK(pd, offset, fd, tree);
+        new_offset = osi_decode_AK(tvb, offset, pinfo, tree);
         break;
       case EA_TPDU :
-        new_offset = osi_decode_EA(pd, offset, fd, tree);
+        new_offset = osi_decode_EA(tvb, offset, pinfo, tree);
         break;
       case ER_TPDU :
-        new_offset = osi_decode_ER(pd, offset, fd, tree);
+        new_offset = osi_decode_ER(tvb, offset, pinfo, tree);
         break;
       case UD_TPDU :
-        if (osi_decode_UD(pd, offset, fd, tree))
-          subdissector_found = TRUE;
-        new_offset = pi.captured_len;  /* UD PDUs run to the end of the packet */
+        new_offset = osi_decode_UD(tvb, offset, pinfo, tree,
+                                  &subdissector_found);
         is_cltp = TRUE;
         break;
       default      :
-        if (first_tpdu && check_col(fd, COL_INFO))
-          col_append_fstr(fd, COL_INFO, "Unknown TPDU type (0x%x)", tpdu);
+        if (first_tpdu && check_col(pinfo->fd, COL_INFO))
+          col_append_fstr(pinfo->fd, COL_INFO, "Unknown TPDU type (0x%x)", tpdu);
         new_offset = -1;       /* bad PDU type */
         break;
     }
 
     if (new_offset == -1) { /* incorrect TPDU */
       if (!first_tpdu)
-        old_dissect_data(pd, offset, fd, tree);
+        dissect_data(tvb, offset, pinfo, tree);
       break;
     }
 
     if (first_tpdu) {
       /* Well, we found at least one valid COTP or CLTP PDU, so I guess this
          is either COTP or CLTP. */
-      if (!subdissector_found && check_col(fd, COL_PROTOCOL))
-        col_add_str(fd, COL_PROTOCOL, is_cltp ? "CLTP" : "COTP");
+      if (!subdissector_found && check_col(pinfo->fd, COL_PROTOCOL))
+        col_add_str(pinfo->fd, COL_PROTOCOL, is_cltp ? "CLTP" : "COTP");
       found_ositp = TRUE;
     }
 
@@ -1507,12 +1527,10 @@ static gboolean dissect_ositp_internal(const u_char *pd, int offset,
   return found_ositp;
 } /* dissect_ositp_internal */
 
-void dissect_ositp(const u_char *pd, int offset, frame_data *fd,
-                 proto_tree *tree) 
+void dissect_ositp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) 
 {
-  OLD_CHECK_DISPLAY_AS_DATA(proto_cotp, pd, offset, fd, tree);
-  if (!dissect_ositp_internal(pd, offset, fd, tree, FALSE))
-    old_dissect_data(pd, offset, fd, tree);
+  if (!dissect_ositp_internal(tvb, pinfo, tree, FALSE))
+    dissect_data(tvb, 0, pinfo, tree);
 }
 
 
@@ -1520,155 +1538,168 @@ void dissect_ositp(const u_char *pd, int offset, frame_data *fd,
  *  CLNP part / main entry point 
 */
 
-static void dissect_clnp(const u_char *pd, int offset, frame_data *fd,
-                 proto_tree *tree) 
+static void dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
-
-  struct clnp_header clnp;
   proto_tree *clnp_tree = NULL;
   proto_item *ti;
+  guint8      cnf_proto_id;
+  guint8      cnf_hdr_len;
+  guint8      cnf_vers;
+  guint8      cnf_ttl;
+  guint8      cnf_type;
+  char        flag_string[6+1];
+  char       *pdu_type_string;
+  guint16     segment_length;
+  guint16     segment_offset = 0;
+  guint16     cnf_cksum;
+  int         offset;
   u_char      src_len, dst_len, nsel, opt_len = 0;
-  u_int       first_offset = offset;
-  char flag_string[6+1];
-  char *pdu_type_string;
-  guint16 segment_length;
-  guint16 segment_offset = 0;
-  guint len;
+  guint8     *dst_addr, *src_addr;
+  guint       len;
+  tvbuff_t   *next_tvb;
 
-  OLD_CHECK_DISPLAY_AS_DATA(proto_clnp, pd, offset, fd, tree);
+  CHECK_DISPLAY_AS_DATA(proto_clnp, tvb, pinfo, tree);
 
-  if (check_col(fd, COL_PROTOCOL))
-    col_add_str(fd, COL_PROTOCOL, "CLNP");
+  pinfo->current_proto = "CLNP";
 
-  /* avoid alignment problem */
-  memcpy(&clnp, &pd[offset], sizeof(clnp));
+  if (check_col(pinfo->fd, COL_PROTOCOL))
+    col_add_str(pinfo->fd, COL_PROTOCOL, "CLNP");
 
-  if (clnp.cnf_proto_id == NLPID_NULL) {
-    if (check_col(fd, COL_INFO))
-      col_add_str(fd, COL_INFO, "Inactive subset");
+  cnf_proto_id = tvb_get_guint8(tvb, P_CLNP_PROTO_ID);
+  if (cnf_proto_id == NLPID_NULL) {
+    if (check_col(pinfo->fd, COL_INFO))
+      col_add_str(pinfo->fd, COL_INFO, "Inactive subset");
     if (tree) {
-      ti = proto_tree_add_item(tree, proto_clnp, NullTVB, offset, 1, FALSE);
+      ti = proto_tree_add_item(tree, proto_clnp, tvb, P_CLNP_PROTO_ID, 1, FALSE);
       clnp_tree = proto_item_add_subtree(ti, ett_clnp);
-      proto_tree_add_uint_format(clnp_tree, hf_clnp_id, NullTVB, offset, 1, 
-                                clnp.cnf_proto_id,
+      proto_tree_add_uint_format(clnp_tree, hf_clnp_id, tvb, P_CLNP_PROTO_ID, 1, 
+                                cnf_proto_id,
                                 "Inactive subset");
     } 
-    dissect_ositp_internal(pd, offset+1, fd, tree, TRUE);
+    next_tvb = tvb_new_subset(tvb, 1, -1, -1);
+    dissect_ositp_internal(next_tvb, pinfo, tree, TRUE);
     return;
   } 
  
-  if (!BYTES_ARE_IN_FRAME(offset, sizeof(clnp))) {
-    old_dissect_data(pd, offset, fd, tree);
-    return;
-  }
-
   /* return if version not known */
-  if (clnp.cnf_vers != ISO8473_V1) {
-    old_dissect_data(pd, offset, fd, tree);
+  cnf_vers = tvb_get_guint8(tvb, P_CLNP_VERS);
+  if (cnf_vers != ISO8473_V1) {
+    dissect_data(tvb, 0, pinfo, tree);
     return;
   }
 
   /* fixed part decoding */
-  opt_len = clnp.cnf_hdr_len;
+  cnf_hdr_len = tvb_get_guint8(tvb, P_CLNP_HDR_LEN);
+  opt_len = cnf_hdr_len;
 
-  segment_length = EXTRACT_SHORT(&clnp.cnf_seglen_msb);
+  if (tree) {
+    ti = proto_tree_add_item(tree, proto_clnp, tvb, 0, cnf_hdr_len, FALSE);
+    clnp_tree = proto_item_add_subtree(ti, ett_clnp);
+    proto_tree_add_uint(clnp_tree, hf_clnp_id, tvb, P_CLNP_PROTO_ID, 1, 
+                              cnf_proto_id);
+    proto_tree_add_uint(clnp_tree, hf_clnp_length, tvb, P_CLNP_HDR_LEN, 1, 
+                       cnf_hdr_len); 
+    proto_tree_add_uint(clnp_tree, hf_clnp_version, tvb, P_CLNP_VERS, 1, 
+                       cnf_vers);
+    cnf_ttl = tvb_get_guint8(tvb, P_CLNP_TTL);
+    proto_tree_add_uint_format(clnp_tree, hf_clnp_ttl, tvb, P_CLNP_TTL, 1, 
+                              cnf_ttl,
+                              "Holding Time : %u (%u secs)", 
+                              cnf_ttl, cnf_ttl / 2);
+  }
+
+  cnf_type = tvb_get_guint8(tvb, P_CLNP_TYPE);
+  pdu_type_string = val_to_str(cnf_type & CNF_TYPE, npdu_type_vals,
+                               "Unknown (0x%02x)");
   flag_string[0] = '\0';
-  if (clnp.cnf_type & CNF_SEG_OK)
+  if (cnf_type & CNF_SEG_OK)
     strcat(flag_string, "S ");
-  if (clnp.cnf_type & CNF_MORE_SEGS)
+  if (cnf_type & CNF_MORE_SEGS)
     strcat(flag_string, "M ");
-  if (clnp.cnf_type & CNF_ERR_OK)
+  if (cnf_type & CNF_ERR_OK)
     strcat(flag_string, "E ");
-  pdu_type_string = val_to_str(clnp.cnf_type & CNF_TYPE, npdu_type_vals,
-                               "Unknown (0x%02x)");
   if (tree) {
-    ti = proto_tree_add_item(tree, proto_clnp, NullTVB, offset, clnp.cnf_hdr_len, FALSE);
-    clnp_tree = proto_item_add_subtree(ti, ett_clnp);
-    proto_tree_add_uint(clnp_tree, hf_clnp_id, NullTVB, offset, 1, 
-                              clnp.cnf_proto_id);
-    proto_tree_add_uint(clnp_tree, hf_clnp_length, NullTVB, offset +  1, 1, 
-                       clnp.cnf_hdr_len); 
-    proto_tree_add_uint(clnp_tree, hf_clnp_version, NullTVB, offset +  2, 1, 
-                       clnp.cnf_vers);
-    proto_tree_add_uint_format(clnp_tree, hf_clnp_ttl, NullTVB, offset +  3, 1, 
-                              clnp.cnf_ttl,
-                              "Holding Time : %u (%u secs)", 
-                              clnp.cnf_ttl, clnp.cnf_ttl / 2);
-    proto_tree_add_uint_format(clnp_tree, hf_clnp_type, NullTVB, offset +  4, 1, 
-                              clnp.cnf_type,
+    proto_tree_add_uint_format(clnp_tree, hf_clnp_type, tvb, P_CLNP_TYPE, 1,
+                              cnf_type,
                               "PDU Type     : 0x%02x (%s%s)",
-                              clnp.cnf_type,
+                              cnf_type,
                               flag_string,
                               pdu_type_string);
-    proto_tree_add_uint(clnp_tree, hf_clnp_pdu_length, NullTVB, offset +  5, 2, 
+  }
+
+  /* If we don't have the full header - i.e., not enough to see the
+     segmentation part and determine whether this datagram is segmented
+     or not - set the Info column now; we'll get an exception before
+     we set it otherwise. */
+
+  if (!tvb_bytes_exist(tvb, 0, cnf_hdr_len)) {
+    if (check_col(pinfo->fd, COL_INFO))
+      col_add_fstr(pinfo->fd, COL_INFO, "%s NPDU %s", pdu_type_string, flag_string);
+  }
+
+  segment_length = tvb_get_ntohs(tvb, P_CLNP_SEGLEN);
+  if (tree) {
+    proto_tree_add_uint(clnp_tree, hf_clnp_pdu_length, tvb, P_CLNP_SEGLEN, 2,
                        segment_length);
-    proto_tree_add_uint_format(clnp_tree, hf_clnp_checksum, NullTVB, offset +  7, 2,
-                              EXTRACT_SHORT(&clnp.cnf_cksum_msb),
+    cnf_cksum = tvb_get_ntohs(tvb, P_CLNP_CKSUM);
+    proto_tree_add_uint_format(clnp_tree, hf_clnp_checksum, tvb, P_CLNP_CKSUM, 2,
+                              cnf_cksum,
                               "Checksum     : 0x%04x",
-                              EXTRACT_SHORT(&clnp.cnf_cksum_msb));
+                              cnf_cksum);
     opt_len -= 9; /* Fixed part of Hesder */
   } /* tree */
 
-  /* stop here if header is not complete */
-
-  if (!BYTES_ARE_IN_FRAME(offset, clnp.cnf_hdr_len)) {
-    if (check_col(fd, COL_INFO))
-      col_add_fstr(fd, COL_INFO, "%s NPDU %s", pdu_type_string, flag_string);
-    old_dissect_data(pd, offset, fd, tree);
-    return;
-  }
-
   /* address part */
   
-  offset += P_ADDRESS_PART;
-  dst_len = pd[offset];
-  nsel    = pd[offset + dst_len];
-  src_len = pd[offset + dst_len + 1];
+  offset = P_CLNP_ADDRESS_PART;
+  dst_len  = tvb_get_guint8(tvb, offset);
+  dst_addr = tvb_get_ptr(tvb, offset + 1, dst_len);
+  nsel     = tvb_get_guint8(tvb, offset + dst_len);
+  src_len  = tvb_get_guint8(tvb, offset + dst_len + 1);
+  src_addr = tvb_get_ptr(tvb, offset + dst_len + 2, src_len);
 
   if (tree) {
-    proto_tree_add_uint(clnp_tree, hf_clnp_dest_length, NullTVB, offset, 1, 
+    proto_tree_add_uint(clnp_tree, hf_clnp_dest_length, tvb, offset, 1, 
                        dst_len);
-    proto_tree_add_bytes_format(clnp_tree, hf_clnp_dest, NullTVB, offset + 1 , dst_len, 
-                              &pd[offset + 1],
+    proto_tree_add_bytes_format(clnp_tree, hf_clnp_dest, tvb, offset + 1 , dst_len, 
+                              dst_addr,
                               " DA : %s", 
-                              print_nsap_net(&pd[offset + 1], dst_len));
-    proto_tree_add_uint(clnp_tree, hf_clnp_src_length, NullTVB
+                              print_nsap_net(dst_addr, dst_len));
+    proto_tree_add_uint(clnp_tree, hf_clnp_src_length, tvb
                        offset + 1 + dst_len, 1, src_len);
-    proto_tree_add_bytes_format(clnp_tree, hf_clnp_src, NullTVB
+    proto_tree_add_bytes_format(clnp_tree, hf_clnp_src, tvb
                               offset + dst_len + 2, src_len,
-                              &pd[offset + dst_len + 2],
+                              src_addr,
                               " SA : %s", 
-                              print_nsap_net(&pd[offset + dst_len + 2], src_len));
+                              print_nsap_net(src_addr, src_len));
 
     opt_len -= dst_len + src_len +2;
   }
 
-  if (check_col(fd, COL_RES_NET_SRC))
-    col_add_fstr(fd, COL_RES_NET_SRC, "%s", 
-                print_nsap_net(&pd[offset + dst_len + 2], src_len));
-  if (check_col(fd, COL_RES_NET_DST))
-    col_add_fstr(fd, COL_RES_NET_DST, "%s", 
-                print_nsap_net(&pd[offset + 1], dst_len));
+  if (check_col(pinfo->fd, COL_RES_NET_SRC))
+    col_add_fstr(pinfo->fd, COL_RES_NET_SRC, "%s", print_nsap_net(src_addr, src_len));
+  if (check_col(pinfo->fd, COL_RES_NET_DST))
+    col_add_fstr(pinfo->fd, COL_RES_NET_DST, "%s", print_nsap_net(dst_addr, dst_len));
 
   /* Segmentation Part */
 
   offset += dst_len + src_len + 2;
 
-  if (clnp.cnf_type & CNF_SEG_OK) {
+  if (cnf_type & CNF_SEG_OK) {
     struct clnp_segment seg;                   /* XXX - not used */
-    memcpy(&seg, &pd[offset], sizeof(seg));    /* XXX - not used */
+    tvb_memcpy(tvb, (guint8 *)&seg, offset, sizeof(seg));      /* XXX - not used */
     
-    segment_offset = EXTRACT_SHORT(&pd[offset + 2]);
+    segment_offset = tvb_get_ntohs(tvb, offset + 2);
     if (tree) {
-      proto_tree_add_text(clnp_tree, NullTVB, offset, 2, 
+      proto_tree_add_text(clnp_tree, tvb, offset, 2, 
                        "Data unit identifier: %06u",
-                       EXTRACT_SHORT(&pd[offset]));
-      proto_tree_add_text(clnp_tree, NullTVB, offset + 2 , 2,
+                       tvb_get_ntohs(tvb, offset));
+      proto_tree_add_text(clnp_tree, tvb, offset + 2 , 2,
                        "Segment offset      : %6u", 
                        segment_offset);
-      proto_tree_add_text(clnp_tree, NullTVB, offset + 4 , 2,
+      proto_tree_add_text(clnp_tree, tvb, offset + 4 , 2,
                        "Total length        : %6u", 
-                       EXTRACT_SHORT(&pd[offset + 4]));
+                       tvb_get_ntohs(tvb, offset + 4));
     }
     
     offset  += 6;
@@ -1678,29 +1709,29 @@ static void dissect_clnp(const u_char *pd, int offset, frame_data *fd,
   if (tree) {
     /* To do : decode options  */
 /*
-    proto_tree_add_text(clnp_tree, NullTVB, offset, 
-                       clnp.cnf_hdr_len + first_offset - offset,
+    proto_tree_add_text(clnp_tree, tvb, offset, 
+                       cnf_hdr_len - offset,
                        "Options/Data: <not shown>");
 */
 /* QUICK HACK Option Len:= PDU_Hd_length-( FixedPart+AddresPart+SegmentPart )*/
 
     dissect_osi_options( 0xff, 
                          opt_len,
-                         pd, offset, fd, clnp_tree ); 
+                         tvb, offset, pinfo, clnp_tree ); 
   }
 
   /* Length of CLNP datagram plus headers above it. */
-  len = segment_length + first_offset;
+  len = segment_length;
 
   /* Set the payload and captured-payload lengths to the minima of (the
      datagram length plus the length of the headers above it) and the
      frame lengths. */
-  if (pi.len > len)
-    pi.len = len;
-  if (pi.captured_len > len)
-    pi.captured_len = len;
+  if (pinfo->len > len)
+    pinfo->len = len;
+  if (pinfo->captured_len > len)
+    pinfo->captured_len = len;
 
-  offset = first_offset + clnp.cnf_hdr_len;
+  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
@@ -1708,16 +1739,16 @@ static void dissect_clnp(const u_char *pd, int offset, frame_data *fd,
      fragment in a fragmented IP datagram; in the future, we will
      probably reassemble fragments for IP, and may reassemble segments
      for CLNP. */
-  if ((clnp.cnf_type & CNF_SEG_OK) && segment_offset != 0) {
-    if (check_col(fd, COL_INFO))
-      col_add_fstr(fd, COL_INFO, "Fragmented %s NPDU %s(off=%u)",
+  if ((cnf_type & CNF_SEG_OK) && segment_offset != 0) {
+    if (check_col(pinfo->fd, COL_INFO))
+      col_add_fstr(pinfo->fd, COL_INFO, "Fragmented %s NPDU %s(off=%u)",
                pdu_type_string, flag_string, segment_offset);
-    old_dissect_data(pd, offset, fd, tree);
+    dissect_data(tvb, offset, pinfo, tree);
     return;
   }
 
-  if (IS_DATA_IN_FRAME(offset)) {
-    switch (clnp.cnf_type & CNF_TYPE) {
+  if (tvb_offset_exists(tvb, offset)) {
+    switch (cnf_type & CNF_TYPE) {
 
     case DT_NPDU:
     case MD_NPDU:
@@ -1726,7 +1757,8 @@ static void dissect_clnp(const u_char *pd, int offset, frame_data *fd,
          PDU, skip that? */
 
       if (nsel == (char)tp_nsap_selector || always_decode_transport) { 
-        if (dissect_ositp_internal(pd, offset, fd, tree, FALSE))
+        next_tvb = tvb_new_subset(tvb, offset, -1, -1);
+        if (dissect_ositp_internal(next_tvb, pinfo, tree, FALSE))
           return;      /* yes, it appears to be COTP or CLTP */
       }
       break;
@@ -1745,9 +1777,10 @@ static void dissect_clnp(const u_char *pd, int offset, frame_data *fd,
       break;
     }
   }
-  if (check_col(fd, COL_INFO))
-    col_add_fstr(fd, COL_INFO, "%s NPDU %s", pdu_type_string, flag_string);
-  old_dissect_data(pd, offset, fd, tree);
+  if (check_col(pinfo->fd, COL_INFO))
+    col_add_fstr(pinfo->fd, COL_INFO, "%s NPDU %s", pdu_type_string, flag_string);
+  next_tvb = tvb_new_subset(tvb, offset, -1, -1);
+  dissect_data(next_tvb, 0, pinfo, tree);
 
 } /* dissect_clnp */
 
@@ -1847,6 +1880,6 @@ void proto_register_cltp(void)
 void
 proto_reg_handoff_clnp(void)
 {
-       old_dissector_add("osinl", NLPID_ISO8473_CLNP, dissect_clnp);
-       old_dissector_add("osinl", NLPID_NULL, dissect_clnp);   /* Inactive subset */
+       dissector_add("osinl", NLPID_ISO8473_CLNP, dissect_clnp);
+       dissector_add("osinl", NLPID_NULL, dissect_clnp);       /* Inactive subset */
 }
index 2aee4c45691e37b6ca95d6399f0b0a3a97b0d8f5..f4688286113ef4cf3b3b776b392a63cb7c8ba56e 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-clnp.h
  * Defines and such for CLNP (and COTP) protocol decode.
  *
- * $Id: packet-clnp.h,v 1.3 2000/07/01 08:55:27 guy Exp $
+ * $Id: packet-clnp.h,v 1.4 2000/11/18 10:38:24 guy Exp $
  * Ralf Schneider <Ralf.Schneider@t-online.de>
  *
  * Ethereal - Network traffic analyzer
@@ -34,6 +34,6 @@
  */
 
 extern
-void dissect_ositp(const u_char *, int, frame_data *, proto_tree *);
+void dissect_ositp(tvbuff_t *, packet_info *, proto_tree *);
 
 #endif /* _PACKET_CLNP_H */
index b38450313ce9a8a17a94a4e70bc3462ec5c04fc2..f6d47733adcab0c5e4d540bd40c1a315c544721c 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for ISO/OSI End System to Intermediate System  
  * Routeing Exchange Protocol ISO 9542.
  *
- * $Id: packet-esis.c,v 1.7 2000/08/13 14:08:09 deniel Exp $
+ * $Id: packet-esis.c,v 1.8 2000/11/18 10:38:24 guy Exp $
  * Ralf Schneider <Ralf.Schneider@t-online.de>
  *
  * Ethereal - Network traffic analyzer
@@ -67,12 +67,12 @@ static const value_string esis_vals[] = {
 
 /* internal prototypes */
 
-void esis_dissect_esh_pdu( u_char len, const u_char *pd, int offset,
-                           frame_data *fd, proto_tree *treepd);
-void esis_dissect_ish_pdu( u_char len, const u_char *pd, int offset,
-                           frame_data *fd, proto_tree *tree);
-void esis_dissect_redirect_pdu( u_char len, const u_char *pd, int offset,
-                                frame_data *fd, proto_tree *tree);
+static void esis_dissect_esh_pdu( u_char len, tvbuff_t *tvb,
+                           packet_info *pinfo, proto_tree *treepd);
+static void esis_dissect_ish_pdu( u_char len, tvbuff_t *tvb,
+                           packet_info *pinfo, proto_tree *tree);
+static void esis_dissect_redirect_pdu( u_char len, tvbuff_t *tvb,
+                           packet_info *pinfo, proto_tree *tree);
 
 /* ################## Descriptions ###########################################*/
 /* Parameters for the ESH PDU
@@ -146,35 +146,22 @@ void esis_dissect_redirect_pdu( u_char len, const u_char *pd, int offset,
  * Output:
  *   void (may modify proto tree)
  */
-void
-esis_dissect_unknown(int offset,guint length,proto_tree *tree,frame_data *fd,
-                     char *fmat, ...){
+static void
+esis_dissect_unknown( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+                      char *fmat, ...){
   va_list ap;
 
-  if ( !IS_DATA_IN_FRAME(offset) ) {
-    /* 
-     * big oops   They were off the end of the packet already.
-     * Just ignore this one.
-    */
-    return;
-  }
-  if ( !BYTES_ARE_IN_FRAME(offset, length) ) {
-    /* 
-     * length will take us past eop.  Truncate length.
-    */
-    length = END_OF_FRAME;
-  }
-
   va_start(ap, fmat);
-  proto_tree_add_text_valist(tree, NullTVB, offset, length, fmat, ap);
+  proto_tree_add_text_valist(tree, tvb, 0, tvb_length(tvb), fmat, ap);
   va_end(ap);
 }
 
 
-void
-esis_dissect_esh_pdu( u_char len, const u_char *pd, int offset, 
-                      frame_data *fd, proto_tree *tree) {
+static void
+esis_dissect_esh_pdu( u_char len, tvbuff_t *tvb, packet_info *pinfo,
+                     proto_tree *tree) {
   proto_tree *esis_area_tree;
+  int         offset  = 0;
   int         no_sa   = 0;
   int         sal     = 0;
   
@@ -183,91 +170,100 @@ esis_dissect_esh_pdu( u_char len, const u_char *pd, int offset,
   if (tree) {
     offset += ESIS_HDR_FIXED_LENGTH;
 
-    no_sa  = pd[offset];
+    no_sa  = tvb_get_guint8(tvb, offset);
     len   -= 1;
 
-    ti = proto_tree_add_text( tree, NullTVB, offset++, END_OF_FRAME, 
+    ti = proto_tree_add_text( tree, tvb, offset, tvb_length_remaining(tvb, offset),
             "Number of Source Addresses (SA, Format: NSAP) : %u", no_sa );
+    offset++;
     
     esis_area_tree = proto_item_add_subtree( ti, ett_esis_area_addr );
     while ( no_sa-- > 0 ) {
-       sal = (int) pd[offset++];
-       proto_tree_add_text(esis_area_tree, NullTVB, offset, 1, "SAL: %2u Octets", sal);
-       proto_tree_add_text(esis_area_tree, NullTVB, offset + 1, sal,
-                           " SA: %s", print_nsap_net( &pd[offset], sal ) );
+       sal = (int) tvb_get_guint8(tvb, offset);
+       offset++;
+       proto_tree_add_text(esis_area_tree, tvb, offset, 1, "SAL: %2u Octets", sal);
+       proto_tree_add_text(esis_area_tree, tvb, offset + 1, sal,
+                           " SA: %s",
+                          print_nsap_net( tvb_get_ptr(tvb, offset, sal), sal ) );
        offset += sal;
        len    -= ( sal + 1 );
     }
-    dissect_osi_options( PDU_TYPE_ESIS_ESH, len, pd, offset, fd, tree );
+    dissect_osi_options( PDU_TYPE_ESIS_ESH, len, tvb, offset, pinfo, tree );
   }  
 } /* esis_dissect_esh_pdu */ ;
 
-void
-esis_dissect_ish_pdu( u_char len, const u_char *pd, int offset,
-                      frame_data *fd, proto_tree *tree) {
+static void
+esis_dissect_ish_pdu( u_char len, tvbuff_t *tvb, packet_info *pinfo,
+                     proto_tree *tree) {
   
+  int   offset  = 0;
   int   netl    = 0;
 
   if (tree) {
     offset += ESIS_HDR_FIXED_LENGTH;
 
-    netl = (int) pd[ offset ];
-    proto_tree_add_text( tree, NullTVB, offset, netl + 1, 
+    netl = (int) tvb_get_guint8(tvb, offset);
+    proto_tree_add_text( tree, tvb, offset, netl + 1, 
                          "### Network Entity Titel Section ###");
-    proto_tree_add_text( tree, NullTVB, offset++, 1, "NETL: %2u Octets", netl);
-    proto_tree_add_text( tree, NullTVB, offset, netl,
-                           " NET: %s", print_nsap_net( &pd[offset], netl ) );
+    proto_tree_add_text( tree, tvb, offset++, 1, "NETL: %2u Octets", netl);
+    proto_tree_add_text( tree, tvb, offset, netl,
+                           " NET: %s",
+                          print_nsap_net( tvb_get_ptr(tvb, offset, netl), netl ) );
     offset += netl;
     len    -= ( netl + 1 );
 
-    dissect_osi_options( PDU_TYPE_ESIS_ISH, len, pd, offset, fd, tree );
+    dissect_osi_options( PDU_TYPE_ESIS_ISH, len, tvb, offset, pinfo, tree );
   }
 };
 
-void
-esis_dissect_redirect_pdu( u_char len, const u_char *pd, int offset,
-                           frame_data *fd, proto_tree *tree) {
+static void
+esis_dissect_redirect_pdu( u_char len, tvbuff_t *tvb, packet_info *pinfo,
+                          proto_tree *tree) {
 
+  int   offset  = 0;
   int   tmpl    = 0;
 
   if (tree) {
     offset += ESIS_HDR_FIXED_LENGTH;
 
-    tmpl = (int) pd[ offset ];
-    proto_tree_add_text( tree, NullTVB, offset, tmpl + 1, 
+    tmpl = (int) tvb_get_guint8(tvb, offset);
+    proto_tree_add_text( tree, tvb, offset, tmpl + 1, 
                          "### Destination Address Section ###" );
-    proto_tree_add_text( tree, NullTVB, offset++, 1, "DAL: %2u Octets", tmpl);
-    proto_tree_add_text( tree, NullTVB, offset, tmpl,
-                         " DA : %s", print_nsap_net( &pd[offset], tmpl ) );
+    proto_tree_add_text( tree, tvb, offset++, 1, "DAL: %2u Octets", tmpl);
+    proto_tree_add_text( tree, tvb, offset, tmpl,
+                         " DA : %s",
+                        print_nsap_net( tvb_get_ptr(tvb, offset, tmpl), tmpl ) );
     offset += tmpl;
     len    -= ( tmpl + 1 );
-    tmpl    = (int) pd[ offset ];
+    tmpl    = (int) tvb_get_guint8(tvb, offset);
 
-    proto_tree_add_text( tree, NullTVB, offset, tmpl + 1, 
+    proto_tree_add_text( tree, tvb, offset, tmpl + 1, 
                          "###  Subnetwork Address Section ###");
-    proto_tree_add_text( tree, NullTVB, offset++, 1, "BSNPAL: %2u Octets", tmpl);
-    proto_tree_add_text( tree, NullTVB, offset, tmpl,
-                           " BSNPA: %s", print_system_id( &pd[offset], tmpl ) );
+    proto_tree_add_text( tree, tvb, offset++, 1, "BSNPAL: %2u Octets", tmpl);
+    proto_tree_add_text( tree, tvb, offset, tmpl,
+                           " BSNPA: %s",
+                          print_system_id( tvb_get_ptr(tvb, offset, tmpl), tmpl ) );
     offset += tmpl;
     len    -= ( tmpl + 1 );
-    tmpl    = (int) pd[ offset ];
+    tmpl    = (int) tvb_get_guint8(tvb, offset);
 
     if ( 0 == tmpl ) {
-      proto_tree_add_text( tree, NullTVB, offset, 1, 
+      proto_tree_add_text( tree, tvb, offset, 1, 
                            "### No Network Entity Title Section ###" );
       offset++;
       len--;
     }
     else {
-      proto_tree_add_text( tree, NullTVB, offset, 1,
+      proto_tree_add_text( tree, tvb, offset, 1,
                            "### Network Entity Title Section ###" );
-      proto_tree_add_text( tree, NullTVB, offset++, 1, "NETL: %2u Octets", tmpl );
-      proto_tree_add_text( tree, NullTVB, offset, tmpl,
-                           " NET: %s", print_nsap_net( &pd[offset], tmpl ) );
+      proto_tree_add_text( tree, tvb, offset++, 1, "NETL: %2u Octets", tmpl );
+      proto_tree_add_text( tree, tvb, offset, tmpl,
+                           " NET: %s",
+                          print_nsap_net( tvb_get_ptr(tvb, offset, tmpl), tmpl ) );
       offset += tmpl;
       len    -= ( tmpl + 1 );
     }
-    dissect_osi_options( PDU_TYPE_ESIS_RD, len, pd, offset, fd, tree );
+    dissect_osi_options( PDU_TYPE_ESIS_RD, len, tvb, offset, pinfo, tree );
   }
 }
 
@@ -280,9 +276,7 @@ esis_dissect_redirect_pdu( u_char len, const u_char *pd, int offset,
  *   main esis tree data and call the sub-protocols as needed.
  *
  * Input:
- *   u_char *     : packet data
- *   int          : offset into packet where we are (packet_data[offset]== start
- *                  of what we care about)
+ *   tvbuff *     : tvbuff referring to packet data
  *   frame_data * : frame data (whole packet with extra info)
  *   proto_tree * : tree of display data.  May be NULL.
  *
@@ -290,70 +284,65 @@ esis_dissect_redirect_pdu( u_char len, const u_char *pd, int offset,
  *   void, but we will add to the proto_tree if it is not NULL.
  */
 static void
-dissect_esis(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+dissect_esis(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
    char       *pdu_type_string        = NULL;
    char       *pdu_type_format_string = "PDU Type      : %s (R:%s%s%s)";   
-   esis_hdr_t *ehdr;
+   esis_hdr_t  ehdr;
    proto_item *ti;
    proto_tree *esis_tree    = NULL;
    int         variable_len = 0;
    u_int       tmp_uint     = 0;
 
-   OLD_CHECK_DISPLAY_AS_DATA(proto_esis, pd, offset, fd, tree);
+   CHECK_DISPLAY_AS_DATA(proto_esis, tvb, pinfo, tree);
 
-   if (check_col(fd, COL_PROTOCOL))
-     col_add_str(fd, COL_PROTOCOL, "ESIS");
+   pinfo->current_proto = "ESIS";
 
-   if (!BYTES_ARE_IN_FRAME(offset, sizeof(*ehdr))) {
-     esis_dissect_unknown(offset, sizeof(*ehdr), tree, fd,
-                          "Not enough capture data for header (%d vs %d)",
-                         sizeof(*ehdr), END_OF_FRAME);
-     return;
-   }
+   if (check_col(pinfo->fd, COL_PROTOCOL))
+     col_add_str(pinfo->fd, COL_PROTOCOL, "ESIS");
 
-   ehdr = (esis_hdr_t *) &pd[offset];
+   tvb_memcpy(tvb, (guint8 *)&ehdr, 0, sizeof ehdr);
    
-   if (ehdr->esis_version != ESIS_REQUIRED_VERSION){
-     esis_dissect_unknown(offset, END_OF_FRAME, tree, fd,
-                          "Unknown ESIS version (%d vs %d)",
-                           ehdr->esis_version, ESIS_REQUIRED_VERSION );
-     return;
-   }
-
    if (tree) {
-     ti = proto_tree_add_item(tree, proto_esis, NullTVB, offset, END_OF_FRAME, FALSE);
+     ti = proto_tree_add_item(tree, proto_esis, tvb, 0, tvb_length(tvb), FALSE);
      esis_tree = proto_item_add_subtree(ti, ett_esis);
 
-     proto_tree_add_uint( esis_tree, hf_esis_nlpi, NullTVB, offset, 1, ehdr->esis_nlpi );
-     proto_tree_add_uint( esis_tree, hf_esis_length, NullTVB,
-                          offset + 1, 1, ehdr->esis_length );
-     proto_tree_add_uint( esis_tree, hf_esis_version, NullTVB, offset + 2, 1, 
-                          ehdr->esis_version );
-     proto_tree_add_uint( esis_tree, hf_esis_reserved, NullTVB, offset + 3, 1, 
-                          ehdr->esis_reserved );
-
-     pdu_type_string = val_to_str(ehdr->esis_type&OSI_PDU_TYPE_MASK,
+     if (ehdr.esis_version != ESIS_REQUIRED_VERSION){
+       esis_dissect_unknown(tvb, pinfo, esis_tree,
+                          "Unknown ESIS version (%u vs %u)",
+                           ehdr.esis_version, ESIS_REQUIRED_VERSION );
+       return;
+     }
+
+     proto_tree_add_uint( esis_tree, hf_esis_nlpi, tvb, 0, 1, ehdr.esis_nlpi );
+     proto_tree_add_uint( esis_tree, hf_esis_length, tvb,
+                          1, 1, ehdr.esis_length );
+     proto_tree_add_uint( esis_tree, hf_esis_version, tvb, 2, 1, 
+                          ehdr.esis_version );
+     proto_tree_add_uint( esis_tree, hf_esis_reserved, tvb, 3, 1, 
+                          ehdr.esis_reserved );
+
+     pdu_type_string = val_to_str(ehdr.esis_type&OSI_PDU_TYPE_MASK,
                                   esis_vals, "Unknown (0x%x)");
 
-     proto_tree_add_uint_format( esis_tree, hf_esis_type, NullTVB, offset + 4, 1, 
-                                 ehdr->esis_type, 
+     proto_tree_add_uint_format( esis_tree, hf_esis_type, tvb, 4, 1, 
+                                 ehdr.esis_type, 
                                  pdu_type_format_string,
                                  pdu_type_string,
-                                 (ehdr->esis_type&BIT_8) ? "1" : "0",
-                                 (ehdr->esis_type&BIT_7) ? "1" : "0",
-                                 (ehdr->esis_type&BIT_6) ? "1" : "0");
+                                 (ehdr.esis_type&BIT_8) ? "1" : "0",
+                                 (ehdr.esis_type&BIT_7) ? "1" : "0",
+                                 (ehdr.esis_type&BIT_6) ? "1" : "0");
 
-     tmp_uint = pntohs( ehdr->esis_holdtime );
-     proto_tree_add_uint_format(esis_tree, hf_esis_holdtime, NullTVB, offset + 5, 2, 
+     tmp_uint = pntohs( ehdr.esis_holdtime );
+     proto_tree_add_uint_format(esis_tree, hf_esis_holdtime, tvb, 5, 2, 
                                 tmp_uint, "Holding Time  : %u seconds",
                                 tmp_uint );
 
-     tmp_uint = pntohs( ehdr->esis_checksum );
+     tmp_uint = pntohs( ehdr.esis_checksum );
      
-     proto_tree_add_uint_format( esis_tree, hf_esis_checksum, NullTVB, offset + 7, 2,
+     proto_tree_add_uint_format( esis_tree, hf_esis_checksum, tvb, 7, 2,
                                  tmp_uint, "Checksum      : 0x%x ( %s )", 
-                                 tmp_uint, calc_checksum( &pd[offset], 
-                                                          ehdr->esis_length ,
+                                 tmp_uint, calc_checksum( tvb, 0,
+                                                          ehdr.esis_length ,
                                                           tmp_uint ) );
    }
 
@@ -363,34 +352,35 @@ dissect_esis(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
     * here.  First, dump the name into info column, and THEN
     * dispatch the sub-type.
     */
-   if (check_col(fd, COL_INFO)) {
-     col_add_str(fd, COL_INFO, 
-                 val_to_str( ehdr->esis_type&OSI_PDU_TYPE_MASK, esis_vals,
+   if (check_col(pinfo->fd, COL_INFO)) {
+     col_add_str(pinfo->fd, COL_INFO, 
+                 val_to_str( ehdr.esis_type&OSI_PDU_TYPE_MASK, esis_vals,
                              "Unknown (0x%x)" ) );
    } 
 
-   variable_len = ehdr->esis_length - ESIS_HDR_FIXED_LENGTH;
+   variable_len = ehdr.esis_length - ESIS_HDR_FIXED_LENGTH;
 
-   switch (ehdr->esis_type) {
+   switch (ehdr.esis_type & OSI_PDU_TYPE_MASK) {
      case ESIS_ESH_PDU:
-          esis_dissect_esh_pdu( variable_len, pd, offset, fd, esis_tree);
+          esis_dissect_esh_pdu( variable_len, tvb, pinfo, esis_tree);
      break;
      case ESIS_ISH_PDU:
-          esis_dissect_ish_pdu( variable_len, pd, offset, fd, esis_tree);
+          esis_dissect_ish_pdu( variable_len, tvb, pinfo, esis_tree);
      break;
      case ESIS_RD_PDU:
-          esis_dissect_redirect_pdu( variable_len, pd, offset, fd
+          esis_dissect_redirect_pdu( variable_len, tvb, pinfo
                                      esis_tree);
      break;
      default:
-         esis_dissect_unknown(offset, END_OF_FRAME, tree, fd,
-                               "unknown esis packet type" );
+         esis_dissect_unknown(tvb, pinfo, esis_tree,
+                             "Unknown ESIS packet type 0x%x",
+                             ehdr.esis_type & OSI_PDU_TYPE_MASK );
    }
 } /* dissect_esis */
 
 
 /*
- * Name: proto_register_esisesis()
+ * Name: proto_register_esis()
  *
  * Description:
  *     main register for esis protocol set.  We register some display
@@ -442,5 +432,5 @@ proto_register_esis(void) {
 void
 proto_reg_handoff_esis(void)
 {
-  old_dissector_add("osinl", NLPID_ISO9542_ESIS, dissect_esis);
+  dissector_add("osinl", NLPID_ISO9542_ESIS, dissect_esis);
 }
index cc145b7d7bb0167388685f12d1348f0c5e3f938a..e60276be92d22fdeff591a42a1bc931bbe0c9242 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-esis.h
  * Defines and such for ESIS protocol decode.
  *
- * $Id: packet-esis.h,v 1.2 2000/04/17 01:36:30 guy Exp $
+ * $Id: packet-esis.h,v 1.3 2000/11/18 10:38:24 guy Exp $
  * Ralf Schneider <Ralf.Schneider@t-online.de>
  *
  * Ethereal - Network traffic analyzer
@@ -57,10 +57,4 @@ typedef struct {
   guint8 esis_checksum[2];    /* Computed on whole PDU Header, 0 means ignore */
 } esis_hdr_t;
 
-/*
- * published API functions
- */ 
-extern void esis_dissect_unknown(int offset,guint length, proto_tree *tree,
-                                 frame_data *fd, char *fmat, ...);
-
 #endif /* _PACKET_ESIS_H */
index 1f343ed732c202325e7cf9e59141002b9f759194..1c0b1c0fcfc17ea8f9487041d011fc6028477a9b 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-eth.c
  * Routines for ethernet packet disassembly
  *
- * $Id: packet-eth.c,v 1.46 2000/11/13 05:28:00 guy Exp $
+ * $Id: packet-eth.c,v 1.47 2000/11/18 10:38:24 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -153,6 +153,7 @@ dissect_eth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
   tvbuff_t             *volatile next_tvb;
   tvbuff_t             *volatile trailer_tvb;
   proto_tree           *volatile fh_tree;
+  guint                        length_before;
 
   CHECK_DISPLAY_AS_DATA(proto_eth, tvb, pinfo, tree);
 
@@ -235,10 +236,10 @@ dissect_eth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        and set the payload and captured-payload lengths to the minima
        of the total length and the frame lengths. */
     length += eth_offset + ETH_HEADER_SIZE;
-    if (pi.len > length)
-      pi.len = length;
-    if (pi.captured_len > length)
-      pi.captured_len = length;
+    if (pinfo->len > length)
+      pinfo->len = length;
+    if (pinfo->captured_len > length)
+      pinfo->captured_len = length;
   } else {
     ethhdr_type = ETHERNET_II;
     if (check_col(pinfo->fd, COL_INFO))
@@ -259,32 +260,32 @@ dissect_eth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
   }
   eth_offset += ETH_HEADER_SIZE;
 
-  /* Give the next dissector only 'length' number of bytes */
   if (etype <= IEEE_802_3_MAX_LEN) {
+         /* Give the next dissector only 'length' number of bytes */
          TRY {
-            next_tvb = tvb_new_subset(tvb, ETH_HEADER_SIZE, etype, etype);
-            trailer_tvb = tvb_new_subset(tvb, ETH_HEADER_SIZE + etype, -1, -1);
+           next_tvb = tvb_new_subset(tvb, ETH_HEADER_SIZE, etype, etype);
+           trailer_tvb = tvb_new_subset(tvb, ETH_HEADER_SIZE + etype, -1, -1);
          }
          CATCH2(BoundsError, ReportedBoundsError) {
-            /* Either:
+           /* Either:
 
-                 the packet doesn't have "etype" bytes worth of
-                 captured data left in it - or it may not even have
-                 "etype" bytes worth of data in it, period -
-                 so the "tvb_new_subset()" creating "next_tvb"
-                 threw an exception
+                the packet doesn't have "etype" bytes worth of
+                captured data left in it - or it may not even have
+                "etype" bytes worth of data in it, period -
+                so the "tvb_new_subset()" creating "next_tvb"
+                threw an exception
 
-               or
+              or
 
-                 the packet has exactly "etype" bytes worth of
-                 captured data left in it, so the "tvb_new_subset()"
-                 creating "trailer_tvb" threw an exception.
+                the packet has exactly "etype" bytes worth of
+                captured data left in it, so the "tvb_new_subset()"
+                creating "trailer_tvb" threw an exception.
 
-               In either case, this means that all the data in the frame
-               is within the length value, so we give all the data to the
-               next protocol and have no trailer. */
-            next_tvb = tvb_new_subset(tvb, ETH_HEADER_SIZE, -1, etype);
-            trailer_tvb = NULL;
+             In either case, this means that all the data in the frame
+             is within the length value, so we give all the data to the
+             next protocol and have no trailer. */
+           next_tvb = tvb_new_subset(tvb, ETH_HEADER_SIZE, -1, etype);
+           trailer_tvb = NULL;
          }
          ENDTRY;
   }
@@ -301,20 +302,34 @@ dissect_eth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
       dissect_llc(next_tvb, pinfo, tree);
       break;
     case ETHERNET_II:
-      ethertype(etype, tvb, ETH_HEADER_SIZE, pinfo, tree, fh_tree, hf_eth_type);
+      length_before = tvb_reported_length(tvb);
+      length = ethertype(etype, tvb, ETH_HEADER_SIZE, pinfo, tree, fh_tree,
+          hf_eth_type) + ETH_HEADER_SIZE;
+      if (length < length_before) {
+       /*
+        * Create a tvbuff for the padding.
+        */
+       TRY {
+         trailer_tvb = tvb_new_subset(tvb, length, -1, -1);
+       }
+       CATCH2(BoundsError, ReportedBoundsError) {
+         /* The packet doesn't have "length" bytes worth of captured
+            data left in it.  No trailer to display. */
+         trailer_tvb = NULL;
+       }
+       ENDTRY;
+      }
       break;
   }
 
   /* If there's some bytes left over, mark them. */
   if (trailer_tvb && tree) {
-         int             trailer_length;
-         const guint8    *ptr;
+         guint           trailer_length;
 
          trailer_length = tvb_length(trailer_tvb);
-         if (trailer_length > 0) {
-                 ptr = tvb_get_ptr(trailer_tvb, 0, trailer_length);
-                 proto_tree_add_bytes(fh_tree, hf_eth_trailer, tvb, ETH_HEADER_SIZE + etype,
-                         trailer_length, ptr);
+         if (trailer_length != 0) {
+                 proto_tree_add_item(fh_tree, hf_eth_trailer, trailer_tvb, 0,
+                         trailer_length, FALSE);
          }
   }
 
index 3ffcd0e2c328d042767ebe40aea06800a8e5baa1..454c58fbfab4e5975aa634bdb014941d21c31535 100644 (file)
@@ -1,7 +1,7 @@
 /* ethertype.c
  * Routines for calling the right protocol for the ethertype.
  *
- * $Id: packet-ethertype.c,v 1.8 2000/11/16 07:35:37 guy Exp $
+ * $Id: packet-ethertype.c,v 1.9 2000/11/18 10:38:24 guy Exp $
  *
  * Gilbert Ramirez <gram@xiexie.org>
  *
@@ -95,7 +95,7 @@ capture_ethertype(guint16 etype, int offset,
   }
 }
 
-void
+guint
 ethertype(guint16 etype, tvbuff_t *tvb, int offset_after_etype, packet_info *pinfo,
                proto_tree *tree, proto_tree *fh_tree, int item_id)
 {
@@ -107,6 +107,7 @@ ethertype(guint16 etype, tvbuff_t *tvb, int offset_after_etype, packet_info *pin
                proto_tree_add_uint(fh_tree, item_id, tvb, offset_after_etype - 2, 2, etype);
        }
 
+       /* Tvbuff for the payload after the Ethernet type. */
        next_tvb = tvb_new_subset(tvb, offset_after_etype, -1, -1);
 
        /* Look for sub-dissector */
@@ -137,6 +138,11 @@ ethertype(guint16 etype, tvbuff_t *tvb, int offset_after_etype, packet_info *pin
                        }
                }
        }
+
+       /* Return the length of that tvbuff; the subdissector may have
+          reduced the length to a value specified by a length field
+          in its header, meaning what remains is padding. */
+       return tvb_reported_length(next_tvb);
 }
 
 
index 2af23462a8a7cf0784cbfd8bfc1410b9b2391a8c..bcfc58b26941769eadf9829ef364ee3405888c26 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for the Generic Routing Encapsulation (GRE) protocol
  * Brad Robel-Forrest <brad.robel-forrest@watchguard.com>
  *
- * $Id: packet-gre.c,v 1.26 2000/11/16 07:35:37 guy Exp $
+ * $Id: packet-gre.c,v 1.27 2000/11/18 10:38:24 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -74,6 +74,8 @@ static const value_string typevals[] = {
        { 0,        NULL  }
 };
 
+static dissector_handle_t ip_handle;
+
 static void
 dissect_gre(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
   
@@ -212,14 +214,14 @@ dissect_gre(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
         dissect_ppp(next_tvb, &pi, tree);
        break;
       case GRE_IP:
-        dissect_ip(pd, offset, fd, tree);
+        old_call_dissector(ip_handle, pd, offset, fd, tree);
         break;
       case GRE_WCCP:
         if (is_wccp2) {
           proto_tree_add_text(gre_tree, NullTVB, offset, sizeof(guint32), "WCCPv2 Data");
           offset += 4;
         }
-        dissect_ip(pd, offset, fd, tree);
+        old_call_dissector(ip_handle, pd, offset, fd, tree);
         break;
       case GRE_IPX:
        next_tvb = tvb_create_from_top(offset);
@@ -304,4 +306,9 @@ void
 proto_reg_handoff_gre(void)
 {
        old_dissector_add("ip.proto", IP_PROTO_GRE, dissect_gre);
+
+       /*
+        * Get a handle for the IP dissector.
+        */
+       ip_handle = find_dissector("ip");
 }
index 324c9b710cffd28f2f86fc911eb9c17bab57b2b9..20f3fed8650bcf98b8306007514864d137e2d743 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-ip.c
  * Routines for IP and miscellaneous IP protocol packet disassembly
  *
- * $Id: packet-ip.c,v 1.105 2000/11/17 06:02:20 guy Exp $
+ * $Id: packet-ip.c,v 1.106 2000/11/18 10:38:24 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -53,7 +53,7 @@
 #include "packet-ip.h"
 #include "packet-ipsec.h"
 
-static void dissect_icmp(const u_char *, int, frame_data *, proto_tree *);
+static void dissect_icmp(tvbuff_t *, packet_info *, proto_tree *);
 static void dissect_igmp(tvbuff_t *, packet_info *, proto_tree *);
 
 /* Decode the old IPv4 TOS field as the DiffServ DS Field */
@@ -113,27 +113,7 @@ static int hf_icmp_checksum = -1;
 
 static gint ett_icmp = -1;
 
-/* ICMP structs and definitions */
-typedef struct _e_icmp {
-  guint8  icmp_type;
-  guint8  icmp_code;
-  guint16 icmp_cksum;
-  union {
-    struct {  /* Address mask request/reply */
-      guint16 id;
-      guint16 seq;
-      guint32 sn_mask;
-    } am;
-    struct {  /* Timestap request/reply */
-      guint16 id;
-      guint16 seq;
-      guint32 orig;
-      guint32 recv;
-      guint32 xmit;
-    } ts;
-    guint32 zero;  /* Unreachable */
-  } opt;
-} e_icmp;
+/* ICMP definitions */
 
 #define ICMP_ECHOREPLY     0
 #define ICMP_UNREACH       3
@@ -358,7 +338,7 @@ capture_ip(const u_char *pd, int offset, packet_counts *ld) {
 }
 
 static void
-dissect_ipopt_security(const ip_tcp_opt *optp, const u_char *opd, int offset,
+dissect_ipopt_security(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
                        guint optlen, proto_tree *opt_tree)
 {
   proto_tree *field_tree = NULL;
@@ -382,33 +362,35 @@ dissect_ipopt_security(const ip_tcp_opt *optp, const u_char *opd, int offset,
     {IPSEC_RESERVED8,    "Reserved"    },
     {0,                  NULL          } };
 
-  tf = proto_tree_add_text(opt_tree, NullTVB, offset,      optlen, "%s:", optp->name);
+  tf = proto_tree_add_text(opt_tree, tvb, offset,      optlen, "%s:", optp->name);
   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
   offset += 2;
 
-  val = pntohs(opd);
-  proto_tree_add_text(field_tree, NullTVB, offset,       2,
+  val = tvb_get_ntohs(tvb, offset);
+  proto_tree_add_text(field_tree, tvb, offset,       2,
               "Security: %s", val_to_str(val, secl_vals, "Unknown (0x%x)"));
   offset += 2;
-  opd += 2;
 
-  val = pntohs(opd);
-  proto_tree_add_text(field_tree, NullTVB, offset,         2,
+  val = tvb_get_ntohs(tvb, offset);
+  proto_tree_add_text(field_tree, tvb, offset,         2,
               "Compartments: %u", val);
   offset += 2;
-  opd += 2;
 
-  proto_tree_add_text(field_tree, NullTVB, offset,         2,
-              "Handling restrictions: %c%c", opd[0], opd[1]);
+  proto_tree_add_text(field_tree, tvb, offset,         2,
+              "Handling restrictions: %c%c",
+             tvb_get_guint8(tvb, offset),
+             tvb_get_guint8(tvb, offset + 1));
   offset += 2;
-  opd += 2;
 
-  proto_tree_add_text(field_tree, NullTVB, offset,         3,
-              "Transmission control code: %c%c%c", opd[0], opd[1], opd[2]);
+  proto_tree_add_text(field_tree, tvb, offset,         3,
+              "Transmission control code: %c%c%c",
+             tvb_get_guint8(tvb, offset),
+             tvb_get_guint8(tvb, offset + 1),
+             tvb_get_guint8(tvb, offset + 2));
 }
 
 static void
-dissect_ipopt_route(const ip_tcp_opt *optp, const u_char *opd, int offset,
+dissect_ipopt_route(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
                        guint optlen, proto_tree *opt_tree)
 {
   proto_tree *field_tree = NULL;
@@ -417,54 +399,52 @@ dissect_ipopt_route(const ip_tcp_opt *optp, const u_char *opd, int offset,
   int optoffset = 0;
   struct in_addr addr;
 
-  tf = proto_tree_add_text(opt_tree, NullTVB, offset,      optlen, "%s (%u bytes)",
+  tf = proto_tree_add_text(opt_tree, tvb, offset,      optlen, "%s (%u bytes)",
                                optp->name, optlen);
   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
 
   optoffset += 2;      /* skip past type and length */
   optlen -= 2;         /* subtract size of type and length */
 
-  ptr = *opd;
-  proto_tree_add_text(field_tree, NullTVB, offset + optoffset, 1,
+  ptr = tvb_get_guint8(tvb, offset + optoffset);
+  proto_tree_add_text(field_tree, tvb, offset + optoffset, 1,
               "Pointer: %d%s", ptr,
               ((ptr < 4) ? " (points before first address)" :
                ((ptr & 3) ? " (points to middle of address)" : "")));
   optoffset++;
-  opd++;
   optlen--;
   ptr--;       /* ptr is 1-origin */
 
   while (optlen > 0) {
     if (optlen < 4) {
-      proto_tree_add_text(field_tree, NullTVB, offset,      optlen,
+      proto_tree_add_text(field_tree, tvb, offset,      optlen,
         "(suboption would go past end of option)");
       break;
     }
 
     /* Avoids alignment problems on many architectures. */
-    memcpy((char *)&addr, (char *)opd, sizeof(addr));
+    tvb_memcpy(tvb, (guint8 *)&addr, offset + optoffset, sizeof(addr));
 
-    proto_tree_add_text(field_tree, NullTVB, offset + optoffset, 4,
+    proto_tree_add_text(field_tree, tvb, offset + optoffset, 4,
               "%s%s",
               ((addr.s_addr == 0) ? "-" : (char *)get_hostname(addr.s_addr)),
               ((optoffset == ptr) ? " <- (current)" : ""));
     optoffset += 4;
-    opd += 4;
     optlen -= 4;
   }
 }
 
 static void
-dissect_ipopt_sid(const ip_tcp_opt *optp, const u_char *opd, int offset,
+dissect_ipopt_sid(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
                        guint optlen, proto_tree *opt_tree)
 {
-  proto_tree_add_text(opt_tree, NullTVB, offset,      optlen,
-    "%s: %d", optp->name, pntohs(opd));
+  proto_tree_add_text(opt_tree, tvb, offset,      optlen,
+    "%s: %u", optp->name, tvb_get_ntohs(tvb, offset + 2));
   return;
 }
 
 static void
-dissect_ipopt_timestamp(const ip_tcp_opt *optp, const u_char *opd,
+dissect_ipopt_timestamp(const ip_tcp_opt *optp, tvbuff_t *tvb,
     int offset, guint optlen, proto_tree *opt_tree)
 {
   proto_tree *field_tree = NULL;
@@ -480,61 +460,54 @@ dissect_ipopt_timestamp(const ip_tcp_opt *optp, const u_char *opd,
   struct in_addr addr;
   guint ts;
 
-  tf = proto_tree_add_text(opt_tree, NullTVB, offset,      optlen, "%s:", optp->name);
+  tf = proto_tree_add_text(opt_tree, tvb, offset,      optlen, "%s:", optp->name);
   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
 
   optoffset += 2;      /* skip past type and length */
   optlen -= 2;         /* subtract size of type and length */
 
-  ptr = *opd;
-  proto_tree_add_text(field_tree, NullTVB, offset + optoffset, 1,
+  ptr = tvb_get_guint8(tvb, offset + optoffset);
+  proto_tree_add_text(field_tree, tvb, offset + optoffset, 1,
               "Pointer: %d%s", ptr,
               ((ptr < 5) ? " (points before first address)" :
                (((ptr - 1) & 3) ? " (points to middle of address)" : "")));
   optoffset++;
-  opd++;
   optlen--;
   ptr--;       /* ptr is 1-origin */
 
-  flg = *opd;
-  proto_tree_add_text(field_tree, NullTVB, offset + optoffset,   1,
-        "Overflow: %d", flg >> 4);
+  flg = tvb_get_guint8(tvb, offset + optoffset);
+  proto_tree_add_text(field_tree, tvb, offset + optoffset,   1,
+        "Overflow: %u", flg >> 4);
   flg &= 0xF;
-  proto_tree_add_text(field_tree, NullTVB, offset + optoffset, 1,
+  proto_tree_add_text(field_tree, tvb, offset + optoffset, 1,
         "Flag: %s", val_to_str(flg, flag_vals, "Unknown (0x%x)"));
   optoffset++;
-  opd++;
   optlen--;
 
   while (optlen > 0) {
     if (flg == IPOPT_TS_TSANDADDR) {
-      /* XXX - check whether it goes past end of packet */
       if (optlen < 8) {
-        proto_tree_add_text(field_tree, NullTVB, offset + optoffset, optlen,
+        proto_tree_add_text(field_tree, tvb, offset + optoffset, optlen,
           "(suboption would go past end of option)");
         break;
       }
-      memcpy((char *)&addr, (char *)opd, sizeof(addr));
-      opd += 4;
-      ts = pntohl(opd);
-      opd += 4;
+      tvb_memcpy(tvb, (char *)&addr, offset + optoffset, sizeof(addr));
+      ts = tvb_get_ntohl(tvb, offset + optoffset + 4);
       optlen -= 8;
-      proto_tree_add_text(field_tree, NullTVB, offset + optoffset,      8,
+      proto_tree_add_text(field_tree, tvb, offset + optoffset,      8,
           "Address = %s, time stamp = %u",
           ((addr.s_addr == 0) ? "-" :  (char *)get_hostname(addr.s_addr)),
           ts);
       optoffset += 8;
     } else {
       if (optlen < 4) {
-        proto_tree_add_text(field_tree, NullTVB, offset + optoffset, optlen,
+        proto_tree_add_text(field_tree, tvb, offset + optoffset, optlen,
           "(suboption would go past end of option)");
         break;
       }
-      /* XXX - check whether it goes past end of packet */
-      ts = pntohl(opd);
-      opd += 4;
+      ts = tvb_get_ntohl(tvb, offset + optoffset);
       optlen -= 4;
-      proto_tree_add_text(field_tree, NullTVB, offset + optoffset, 4,
+      proto_tree_add_text(field_tree, tvb, offset + optoffset, 4,
           "Time stamp = %u", ts);
       optoffset += 4;
     }
@@ -612,7 +585,7 @@ static const ip_tcp_opt ipopts[] = {
 
 /* Dissect the IP or TCP options in a packet. */
 void
-dissect_ip_tcp_options(const u_char *opd, int offset, guint length,
+dissect_ip_tcp_options(tvbuff_t *tvb, int offset, guint length,
                        const ip_tcp_opt *opttab, int nopts, int eol,
                        proto_tree *opt_tree)
 {
@@ -622,12 +595,12 @@ dissect_ip_tcp_options(const u_char *opd, int offset, guint length,
   int               optlen;
   char             *name;
   char              name_str[7+1+1+2+2+1+1];   /* "Unknown (0x%02x)" */
-  void            (*dissect)(const struct ip_tcp_opt *, const u_char *,
+  void            (*dissect)(const struct ip_tcp_opt *, tvbuff_t *,
                                int, guint, proto_tree *);
   guint             len;
 
   while (length > 0) {
-    opt = *opd++;
+    opt = tvb_get_guint8(tvb, offset);
     for (optp = &opttab[0]; optp < &opttab[nopts]; optp++) {
       if (optp->optcode == opt)
         break;
@@ -655,59 +628,58 @@ dissect_ip_tcp_options(const u_char *opd, int offset, guint length,
       if (length == 0) {
         /* Bogus - packet must at least include option code byte and
            length byte! */
-        proto_tree_add_text(opt_tree, NullTVB, offset,      1,
+        proto_tree_add_text(opt_tree, tvb, offset,      1,
               "%s (length byte past end of options)", name);
         return;
       }
-      len = *opd++;  /* total including type, len */
+      len = tvb_get_guint8(tvb, offset + 1);  /* total including type, len */
       --length;    /* account for length byte */
       if (len < 2) {
         /* Bogus - option length is too short to include option code and
            option length. */
-        proto_tree_add_text(opt_tree, NullTVB, offset,      2,
+        proto_tree_add_text(opt_tree, tvb, offset,      2,
               "%s (with too-short option length = %u byte%s)", name,
               len, plurality(len, "", "s"));
         return;
       } else if (len - 2 > length) {
         /* Bogus - option goes past the end of the header. */
-        proto_tree_add_text(opt_tree, NullTVB, offset,      length,
+        proto_tree_add_text(opt_tree, tvb, offset,      length,
               "%s (option length = %u byte%s says option goes past end of options)",
              name, len, plurality(len, "", "s"));
         return;
       } else if (len_type == FIXED_LENGTH && len != optlen) {
         /* Bogus - option length isn't what it's supposed to be for this
            option. */
-        proto_tree_add_text(opt_tree, NullTVB, offset,      len,
+        proto_tree_add_text(opt_tree, tvb, offset,      len,
               "%s (with option length = %u byte%s; should be %u)", name,
               len, plurality(len, "", "s"), optlen);
         return;
       } else if (len_type == VARIABLE_LENGTH && len < optlen) {
         /* Bogus - option length is less than what it's supposed to be for
            this option. */
-        proto_tree_add_text(opt_tree, NullTVB, offset,      len,
+        proto_tree_add_text(opt_tree, tvb, offset,      len,
               "%s (with option length = %u byte%s; should be >= %u)", name,
               len, plurality(len, "", "s"), optlen);
         return;
       } else {
         if (optp == NULL) {
-          proto_tree_add_text(opt_tree, NullTVB, offset,    len, "%s (%u byte%s)",
+          proto_tree_add_text(opt_tree, tvb, offset,    len, "%s (%u byte%s)",
                                name, len, plurality(len, "", "s"));
         } else {
           if (dissect != NULL) {
             /* Option has a dissector. */
-            (*dissect)(optp, opd, offset,          len, opt_tree);
+            (*dissect)(optp, tvb, offset,          len, opt_tree);
           } else {
             /* Option has no data, hence no dissector. */
-            proto_tree_add_text(opt_tree, NullTVB, offset,  len, "%s", name);
+            proto_tree_add_text(opt_tree, tvb, offset,  len, "%s", name);
           }
         }
         len -= 2;      /* subtract size of type and length */
         offset += 2 + len;
       }
-      opd += len;
       length -= len;
     } else {
-      proto_tree_add_text(opt_tree, NullTVB, offset,      1, "%s", name);
+      proto_tree_add_text(opt_tree, tvb, offset,      1, "%s", name);
       offset += 1;
     }
     if (opt == eol)
@@ -823,148 +795,171 @@ static guint16 ip_checksum_shouldbe(guint16 sum, guint16 computed_sum)
 }
 
 void
-dissect_ip(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+dissect_ip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
   e_ip       iph;
   proto_tree *ip_tree, *field_tree;
   proto_item *ti, *tf;
-  guint      hlen, optlen, len;
+  int        offset = 0;
+  guint      hlen, optlen, len, payload_len, reported_payload_len, padding;
   guint16    flags;
   guint8     nxt;
   guint16    ipsum;
+  tvbuff_t   *next_tvb;
 
-  OLD_CHECK_DISPLAY_AS_DATA(proto_ip, pd, offset, fd, tree);
+  CHECK_DISPLAY_AS_DATA(proto_ip, tvb, pinfo, tree);
 
-  /* To do: check for errs, etc. */
-  if (!BYTES_ARE_IN_FRAME(offset, IPH_MIN_LEN)) {
-    old_dissect_data(pd, offset, fd, tree);
-    return;
-  }
+  pinfo->current_proto = "IP";
 
   /* Avoids alignment problems on many architectures. */
-  memcpy(&iph, &pd[offset], sizeof(e_ip));
+  tvb_memcpy(tvb, (guint8 *)&iph, offset, sizeof(e_ip));
   iph.ip_len = ntohs(iph.ip_len);
   iph.ip_id  = ntohs(iph.ip_id);
   iph.ip_off = ntohs(iph.ip_off);
   iph.ip_sum = ntohs(iph.ip_sum);
 
-  /* Length of IP datagram plus headers above it. */
-  len = iph.ip_len + offset;
-
-  /* Set the payload and captured-payload lengths to the minima of (the
-     IP length plus the length of the headers above it) and the frame
-     lengths. */
-  if (pi.len > len)
-    pi.len = len;
-  if (pi.captured_len > len)
-    pi.captured_len = len;
+  /* Length of payload handed to us. */
+  reported_payload_len = tvb_reported_length(tvb);
+  payload_len = tvb_length(tvb);
+
+  /* Length of IP datagram. */
+  len = iph.ip_len;
+
+  if (len < reported_payload_len) {
+    /* Adjust the length of this tvbuff to include only the IP datagram.
+       Our caller may use that to determine how much of its packet
+       was padding. */
+    tvb_set_reported_length(tvb, len);
+
+    /* Shrink the total payload by the amount of padding. */
+    padding = reported_payload_len - len;
+    if (pinfo->len >= padding)
+      pinfo->len -= padding;
+
+    /* Shrink the captured payload by the amount of padding in the
+       captured payload (which may be less than the amount of padding,
+       as the padding may not have been captured). */
+    if (len < payload_len) {
+      padding = payload_len - len;
+      if (pinfo->captured_len >= padding)
+        pinfo->captured_len -= padding;
+    }
+  }
 
   /* XXX - check to make sure this is at least IPH_MIN_LEN. */
   hlen = lo_nibble(iph.ip_v_hl) * 4;   /* IP header length, in bytes */
   
   if (tree) {
-    ti = proto_tree_add_item(tree, proto_ip, NullTVB, offset, hlen, FALSE);
+    ti = proto_tree_add_item(tree, proto_ip, tvb, offset, hlen, FALSE);
     ip_tree = proto_item_add_subtree(ti, ett_ip);
 
-    proto_tree_add_uint(ip_tree, hf_ip_version, NullTVB, offset, 1, hi_nibble(iph.ip_v_hl));
-    proto_tree_add_uint_format(ip_tree, hf_ip_hdr_len, NullTVB, offset, 1, hlen,
+    proto_tree_add_uint(ip_tree, hf_ip_version, tvb, offset, 1, hi_nibble(iph.ip_v_hl));
+    proto_tree_add_uint_format(ip_tree, hf_ip_hdr_len, tvb, offset, 1, hlen,
        "Header length: %u bytes", hlen);
 
     if (g_ip_dscp_actif) {
-      tf = proto_tree_add_uint_format(ip_tree, hf_ip_dsfield, NullTVB, offset + 1, 1, iph.ip_tos,
+      tf = proto_tree_add_uint_format(ip_tree, hf_ip_dsfield, tvb, offset + 1, 1, iph.ip_tos,
           "Differentiated Services Field: 0x%02x (DSCP 0x%02x: %s; ECN: 0x%02x)", iph.ip_tos,
           IPDSFIELD_DSCP(iph.ip_tos), val_to_str(IPDSFIELD_DSCP(iph.ip_tos), dscp_vals,
           "Unknown DSCP"),IPDSFIELD_ECN(iph.ip_tos));
 
       field_tree = proto_item_add_subtree(tf, ett_ip_dsfield);
-      proto_tree_add_uint(field_tree, hf_ip_dsfield_dscp, NullTVB, offset + 1, 1, iph.ip_tos);
-      proto_tree_add_uint(field_tree, hf_ip_dsfield_ect, NullTVB, offset + 1, 1, iph.ip_tos);
-      proto_tree_add_uint(field_tree, hf_ip_dsfield_ce, NullTVB, offset + 1, 1, iph.ip_tos);
+      proto_tree_add_uint(field_tree, hf_ip_dsfield_dscp, tvb, offset + 1, 1, iph.ip_tos);
+      proto_tree_add_uint(field_tree, hf_ip_dsfield_ect, tvb, offset + 1, 1, iph.ip_tos);
+      proto_tree_add_uint(field_tree, hf_ip_dsfield_ce, tvb, offset + 1, 1, iph.ip_tos);
     } else {
-      tf = proto_tree_add_uint_format(ip_tree, hf_ip_tos, NullTVB, offset + 1, 1, iph.ip_tos,
+      tf = proto_tree_add_uint_format(ip_tree, hf_ip_tos, tvb, offset + 1, 1, iph.ip_tos,
          "Type of service: 0x%02x (%s)", iph.ip_tos,
          val_to_str( IPTOS_TOS(iph.ip_tos), iptos_vals, "Unknown") );
 
       field_tree = proto_item_add_subtree(tf, ett_ip_tos);
-      proto_tree_add_uint(field_tree, hf_ip_tos_precedence, NullTVB, offset + 1, 1, iph.ip_tos);
-      proto_tree_add_boolean(field_tree, hf_ip_tos_delay, NullTVB, offset + 1, 1, iph.ip_tos);
-      proto_tree_add_boolean(field_tree, hf_ip_tos_throughput, NullTVB, offset + 1, 1, iph.ip_tos);
-      proto_tree_add_boolean(field_tree, hf_ip_tos_reliability, NullTVB, offset + 1, 1, iph.ip_tos);
-      proto_tree_add_boolean(field_tree, hf_ip_tos_cost, NullTVB, offset + 1, 1, iph.ip_tos);
+      proto_tree_add_uint(field_tree, hf_ip_tos_precedence, tvb, offset + 1, 1, iph.ip_tos);
+      proto_tree_add_boolean(field_tree, hf_ip_tos_delay, tvb, offset + 1, 1, iph.ip_tos);
+      proto_tree_add_boolean(field_tree, hf_ip_tos_throughput, tvb, offset + 1, 1, iph.ip_tos);
+      proto_tree_add_boolean(field_tree, hf_ip_tos_reliability, tvb, offset + 1, 1, iph.ip_tos);
+      proto_tree_add_boolean(field_tree, hf_ip_tos_cost, tvb, offset + 1, 1, iph.ip_tos);
     }
-    proto_tree_add_uint(ip_tree, hf_ip_len, NullTVB, offset +  2, 2, iph.ip_len);
-    proto_tree_add_uint(ip_tree, hf_ip_id, NullTVB, offset +  4, 2, iph.ip_id);
+    proto_tree_add_uint(ip_tree, hf_ip_len, tvb, offset +  2, 2, iph.ip_len);
+    proto_tree_add_uint(ip_tree, hf_ip_id, tvb, offset +  4, 2, iph.ip_id);
 
     flags = (iph.ip_off & (IP_DF|IP_MF)) >> 12;
-    tf = proto_tree_add_uint(ip_tree, hf_ip_flags, NullTVB, offset +  6, 1, flags);
+    tf = proto_tree_add_uint(ip_tree, hf_ip_flags, tvb, offset +  6, 1, flags);
     field_tree = proto_item_add_subtree(tf, ett_ip_off);
-    proto_tree_add_boolean(field_tree, hf_ip_flags_df, NullTVB, offset + 6, 1, flags),
-    proto_tree_add_boolean(field_tree, hf_ip_flags_mf, NullTVB, offset + 6, 1, flags),
+    proto_tree_add_boolean(field_tree, hf_ip_flags_df, tvb, offset + 6, 1, flags),
+    proto_tree_add_boolean(field_tree, hf_ip_flags_mf, tvb, offset + 6, 1, flags),
 
-    proto_tree_add_uint(ip_tree, hf_ip_frag_offset, NullTVB, offset +  6, 2,
+    proto_tree_add_uint(ip_tree, hf_ip_frag_offset, tvb, offset +  6, 2,
       (iph.ip_off & IP_OFFSET)*8);
-    proto_tree_add_uint(ip_tree, hf_ip_ttl, NullTVB, offset +  8, 1, iph.ip_ttl);
-    proto_tree_add_uint_format(ip_tree, hf_ip_proto, NullTVB, offset +  9, 1, iph.ip_p,
+    proto_tree_add_uint(ip_tree, hf_ip_ttl, tvb, offset +  8, 1, iph.ip_ttl);
+    proto_tree_add_uint_format(ip_tree, hf_ip_proto, tvb, offset +  9, 1, iph.ip_p,
        "Protocol: %s (0x%02x)", ipprotostr(iph.ip_p), iph.ip_p);
 
-    ipsum = ip_checksum(&pd[offset], hlen);
+    ipsum = ip_checksum(tvb_get_ptr(tvb, offset, hlen), hlen);
     if (ipsum == 0) {
-       proto_tree_add_uint_format(ip_tree, hf_ip_checksum, NullTVB, offset + 10, 2, iph.ip_sum,
+       proto_tree_add_uint_format(ip_tree, hf_ip_checksum, tvb, offset + 10, 2, iph.ip_sum,
             "Header checksum: 0x%04x (correct)", iph.ip_sum);
     }
     else {
-       proto_tree_add_uint_format(ip_tree, hf_ip_checksum, NullTVB, offset + 10, 2, iph.ip_sum,
+       proto_tree_add_uint_format(ip_tree, hf_ip_checksum, tvb, offset + 10, 2, iph.ip_sum,
             "Header checksum: 0x%04x (incorrect, should be 0x%04x)", iph.ip_sum,
            ip_checksum_shouldbe(iph.ip_sum, ipsum));
     }
 
-    proto_tree_add_ipv4(ip_tree, hf_ip_src, NullTVB, offset + 12, 4, iph.ip_src);
-    proto_tree_add_ipv4(ip_tree, hf_ip_dst, NullTVB, offset + 16, 4, iph.ip_dst);
-    proto_tree_add_ipv4_hidden(ip_tree, hf_ip_addr, NullTVB, offset + 12, 4, iph.ip_src);
-    proto_tree_add_ipv4_hidden(ip_tree, hf_ip_addr, NullTVB, offset + 16, 4, iph.ip_dst);
+    proto_tree_add_ipv4(ip_tree, hf_ip_src, tvb, offset + 12, 4, iph.ip_src);
+    proto_tree_add_ipv4(ip_tree, hf_ip_dst, tvb, offset + 16, 4, iph.ip_dst);
+    proto_tree_add_ipv4_hidden(ip_tree, hf_ip_addr, tvb, offset + 12, 4, iph.ip_src);
+    proto_tree_add_ipv4_hidden(ip_tree, hf_ip_addr, tvb, offset + 16, 4, iph.ip_dst);
 
     /* Decode IP options, if any. */
     if (hlen > sizeof (e_ip)) {
       /* There's more than just the fixed-length header.  Decode the
          options. */
       optlen = hlen - sizeof (e_ip);   /* length of options, in bytes */
-      tf = proto_tree_add_text(ip_tree, NullTVB, offset +  20, optlen,
+      tf = proto_tree_add_text(ip_tree, tvb, offset +  20, optlen,
         "Options: (%u bytes)", optlen);
       field_tree = proto_item_add_subtree(tf, ett_ip_options);
-      dissect_ip_tcp_options(&pd[offset + 20], offset + 20, optlen,
+      dissect_ip_tcp_options(tvb, offset + 20, optlen,
          ipopts, N_IP_OPTS, IPOPT_END, field_tree);
     }
   }
 
-  pi.ipproto = iph.ip_p;
-  pi.iplen = iph.ip_len;
-  pi.iphdrlen = lo_nibble(iph.ip_v_hl);
-  SET_ADDRESS(&pi.net_src, AT_IPv4, 4, &pd[offset + IPH_SRC]);
-  SET_ADDRESS(&pi.src, AT_IPv4, 4, &pd[offset + IPH_SRC]);
-  SET_ADDRESS(&pi.net_dst, AT_IPv4, 4, &pd[offset + IPH_DST]);
-  SET_ADDRESS(&pi.dst, AT_IPv4, 4, &pd[offset + IPH_DST]);
+  pinfo->ipproto = iph.ip_p;
+  pinfo->iplen = iph.ip_len;
+  pinfo->iphdrlen = lo_nibble(iph.ip_v_hl);
+  SET_ADDRESS(&pinfo->net_src, AT_IPv4, 4, tvb_get_ptr(tvb, offset + IPH_SRC, 4));
+  SET_ADDRESS(&pinfo->src, AT_IPv4, 4, tvb_get_ptr(tvb, offset + IPH_SRC, 4));
+  SET_ADDRESS(&pinfo->net_dst, AT_IPv4, 4, tvb_get_ptr(tvb, offset + IPH_DST, 4));
+  SET_ADDRESS(&pinfo->dst, AT_IPv4, 4, tvb_get_ptr(tvb, offset + IPH_DST, 4));
 
   /* Skip over header + options */
   offset += hlen;
   nxt = iph.ip_p;
   if (iph.ip_off & IP_OFFSET) {
     /* fragmented */
-    if (check_col(fd, COL_PROTOCOL))
-      col_add_str(fd, COL_PROTOCOL, "IP");
-    if (check_col(fd, COL_INFO))
-      col_add_fstr(fd, COL_INFO, "Fragmented IP protocol (proto=%s 0x%02x, off=%u)",
+    if (check_col(pinfo->fd, COL_PROTOCOL))
+      col_add_str(pinfo->fd, COL_PROTOCOL, "IP");
+    if (check_col(pinfo->fd, COL_INFO))
+      col_add_fstr(pinfo->fd, COL_INFO, "Fragmented IP protocol (proto=%s 0x%02x, off=%u)",
        ipprotostr(iph.ip_p), iph.ip_p, (iph.ip_off & IP_OFFSET) * 8);
-    old_dissect_data(pd, offset, fd, tree);
+    dissect_data(tvb, offset, pinfo, tree);
     return;
   }
 
-  /* do lookup with the subdissector table */
-  if (!old_dissector_try_port(ip_dissector_table, nxt, pd, offset, fd, tree)) {
+  /* Hand off to the next protocol.
+
+     XXX - setting the columns only after trying various dissectors means
+     that if one of those dissectors throws an exception, the frame won't
+     even be labelled as an IP frame; ideally, if a frame being dissected
+     throws an exception, it'll be labelled as a mangled frame of the
+     type in question. */
+  next_tvb = tvb_new_subset(tvb, offset, -1, -1);
+  if (!dissector_try_port(ip_dissector_table, nxt, next_tvb, pinfo, tree)) {
     /* Unknown protocol */
-    if (check_col(fd, COL_PROTOCOL))
-      col_add_str(fd, COL_PROTOCOL, "IP");
-    if (check_col(fd, COL_INFO))
-      col_add_fstr(fd, COL_INFO, "%s (0x%02x)", ipprotostr(iph.ip_p), iph.ip_p);
-    old_dissect_data(pd, offset, fd, tree);
+    if (check_col(pinfo->fd, COL_PROTOCOL))
+      col_add_str(pinfo->fd, COL_PROTOCOL, "IP");
+    if (check_col(pinfo->fd, COL_INFO))
+      col_add_fstr(pinfo->fd, COL_INFO, "%s (0x%02x)", ipprotostr(iph.ip_p), iph.ip_p);
+    dissect_data(next_tvb, 0, pinfo, tree);
   }
 }
 
@@ -1005,31 +1000,36 @@ static const gchar *par_str[] = {"IP header bad", "Required option missing"};
 #define        N_PARAMPROB     (sizeof par_str / sizeof par_str[0])
 
 static void
-dissect_icmp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
-  e_icmp     ih;
+dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
   proto_tree *icmp_tree;
   proto_item *ti;
+  guint8     icmp_type;
+  guint8     icmp_code;
+  guint      length, reported_length;
   guint16    cksum, computed_cksum;
   gchar      type_str[64], code_str[64] = "";
   guint8     num_addrs = 0;
   guint8     addr_entry_size = 0;
   int        i;
 
-  OLD_CHECK_DISPLAY_AS_DATA(proto_icmp, pd, offset, fd, tree);
+  CHECK_DISPLAY_AS_DATA(proto_icmp, tvb, pinfo, tree);
+
+  pinfo->current_proto = "ICMP";
 
-  /* Avoids alignment problems on many architectures. */
-  memcpy(&ih, &pd[offset], sizeof(e_icmp));
   /* To do: check for runts, errs, etc. */
-  cksum = ntohs(ih.icmp_cksum);
+  icmp_type = tvb_get_guint8(tvb, 0);
+  icmp_code = tvb_get_guint8(tvb, 1);
+  cksum = tvb_get_ntohs(tvb, 2);
 
-  switch (ih.icmp_type) {
+  switch (icmp_type) {
     case ICMP_ECHOREPLY:
       strcpy(type_str, "Echo (ping) reply");
       break;
     case ICMP_UNREACH:
       strcpy(type_str, "Destination unreachable");
-      if (ih.icmp_code < N_UNREACH) {
-        sprintf(code_str, "(%s)", unreach_str[ih.icmp_code]);
+      if (icmp_code < N_UNREACH) {
+        sprintf(code_str, "(%s)", unreach_str[icmp_code]);
       } else {
         strcpy(code_str, "(Unknown - error?)");
       }
@@ -1039,8 +1039,8 @@ dissect_icmp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
       break;
     case ICMP_REDIRECT:
       strcpy(type_str, "Redirect");
-      if (ih.icmp_code < N_REDIRECT) {
-        sprintf(code_str, "(%s)", redir_str[ih.icmp_code]);
+      if (icmp_code < N_REDIRECT) {
+        sprintf(code_str, "(%s)", redir_str[icmp_code]);
       } else {
         strcpy(code_str, "(Unknown - error?)");
       }
@@ -1056,16 +1056,16 @@ dissect_icmp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
       break;
     case ICMP_TIMXCEED:
       strcpy(type_str, "Time-to-live exceeded");
-      if (ih.icmp_code < N_TIMXCEED) {
-        sprintf(code_str, "(%s)", ttl_str[ih.icmp_code]);
+      if (icmp_code < N_TIMXCEED) {
+        sprintf(code_str, "(%s)", ttl_str[icmp_code]);
       } else {
         strcpy(code_str, "(Unknown - error?)");
       }
       break;
     case ICMP_PARAMPROB:
       strcpy(type_str, "Parameter problem");
-      if (ih.icmp_code < N_PARAMPROB) {
-        sprintf(code_str, "(%s)", par_str[ih.icmp_code]);
+      if (icmp_code < N_PARAMPROB) {
+        sprintf(code_str, "(%s)", par_str[icmp_code]);
       } else {
         strcpy(code_str, "(Unknown - error?)");
       }
@@ -1092,49 +1092,48 @@ dissect_icmp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
       strcpy(type_str, "Unknown ICMP (obsolete or malformed?)");
   }
 
-  if (check_col(fd, COL_PROTOCOL))
-    col_add_str(fd, COL_PROTOCOL, "ICMP");
-  if (check_col(fd, COL_INFO))
-    col_add_str(fd, COL_INFO, type_str);
+  if (check_col(pinfo->fd, COL_PROTOCOL))
+    col_add_str(pinfo->fd, COL_PROTOCOL, "ICMP");
+  if (check_col(pinfo->fd, COL_INFO))
+    col_add_str(pinfo->fd, COL_INFO, type_str);
 
   if (tree) {
-    ti = proto_tree_add_item(tree, proto_icmp, NullTVB, offset, END_OF_FRAME, FALSE);
+    length = tvb_length(tvb);
+    reported_length = tvb_reported_length(tvb);
+    ti = proto_tree_add_item(tree, proto_icmp, tvb, 0, length, FALSE);
     icmp_tree = proto_item_add_subtree(ti, ett_icmp);
-    proto_tree_add_uint_format(icmp_tree, hf_icmp_type, NullTVB, offset,      1, 
-                              ih.icmp_type,
+    proto_tree_add_uint_format(icmp_tree, hf_icmp_type, tvb, 0, 1, 
+                              icmp_type,
                               "Type: %u (%s)",
-                              ih.icmp_type, type_str);
-    proto_tree_add_uint_format(icmp_tree, hf_icmp_code, NullTVB,       offset +  1, 1, 
-                              ih.icmp_code,
+                              icmp_type, type_str);
+    proto_tree_add_uint_format(icmp_tree, hf_icmp_code, tvb, 1, 1, 
+                              icmp_code,
                               "Code: %u %s",
-                              ih.icmp_code, code_str);
+                              icmp_code, code_str);
 
-    if (pi.captured_len >= pi.len) {
+    if (length >= reported_length) {
       /* The packet isn't truncated, so we can checksum it.
          XXX - we have to check whether this is part of a fragmented
         IP datagram, too.... */
 
-      computed_cksum = ip_checksum(&pd[offset], END_OF_FRAME);
+      computed_cksum = ip_checksum(tvb_get_ptr(tvb, 0, reported_length),
+                                  reported_length);
       if (computed_cksum == 0) {
-        proto_tree_add_uint_format(icmp_tree, hf_icmp_checksum, NullTVB,
-                       offset + 2, 2,
+        proto_tree_add_uint_format(icmp_tree, hf_icmp_checksum, tvb, 2, 2,
                        cksum,
                        "Checksum: 0x%04x (correct)", cksum);
       } else {
-        proto_tree_add_uint_format(icmp_tree, hf_icmp_checksum, NullTVB,
-                       offset + 2, 2,
+        proto_tree_add_uint_format(icmp_tree, hf_icmp_checksum, tvb, 2, 2,
                        cksum,
                        "Checksum: 0x%04x (incorrect, should be 0x%04x)",
                        cksum, ip_checksum_shouldbe(cksum, computed_cksum));
       }
     } else {
-      proto_tree_add_uint(icmp_tree, hf_icmp_checksum, NullTVB,
-                       offset +  2, 2,
-                       cksum);
+      proto_tree_add_uint(icmp_tree, hf_icmp_checksum, tvb, 2, 2, cksum);
     }
 
     /* Decode the second 4 bytes of the packet. */
-    switch (ih.icmp_type) {
+    switch (icmp_type) {
       case ICMP_ECHOREPLY:
       case ICMP_ECHO:
       case ICMP_TSTAMP:
@@ -1143,45 +1142,45 @@ dissect_icmp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
       case ICMP_IREQREPLY:
       case ICMP_MASKREQ:
       case ICMP_MASKREPLY:
-       proto_tree_add_text(icmp_tree, NullTVB, offset +  4, 2, "Identifier: 0x%04x",
-         pntohs(&pd[offset +  4]));
-       proto_tree_add_text(icmp_tree, NullTVB, offset +  6, 2, "Sequence number: %02x:%02x",
-         pd[offset+6], pd[offset+7]);
+       proto_tree_add_text(icmp_tree, tvb, 4, 2, "Identifier: 0x%04x",
+         tvb_get_ntohs(tvb, 4));
+       proto_tree_add_text(icmp_tree, tvb, 6, 2, "Sequence number: %02x:%02x",
+         tvb_get_guint8(tvb, 6), tvb_get_guint8(tvb, 7));
        break;
 
        case ICMP_UNREACH:
-         switch (ih.icmp_code) {
+         switch (icmp_code) {
            case ICMP_FRAG_NEEDED:
-                 proto_tree_add_text(icmp_tree, NullTVB, offset +  6, 2, "MTU of next hop: %u",
-                   pntohs(&pd[offset + 6]));
+                 proto_tree_add_text(icmp_tree, tvb, 6, 2, "MTU of next hop: %u",
+                   tvb_get_ntohs(tvb, 6));
                  break;
            }
          break;
 
       case ICMP_RTRADVERT:
-        num_addrs = pd[offset + 4];
-       proto_tree_add_text(icmp_tree, NullTVB, offset +  4, 1, "Number of addresses: %u",
+        num_addrs = tvb_get_guint8(tvb, 4);
+       proto_tree_add_text(icmp_tree, tvb, 4, 1, "Number of addresses: %u",
          num_addrs);
-       addr_entry_size = pd[offset + 5];
-       proto_tree_add_text(icmp_tree, NullTVB, offset +  5, 1, "Address entry size: %u",
+       addr_entry_size = tvb_get_guint8(tvb, 5);
+       proto_tree_add_text(icmp_tree, tvb, 5, 1, "Address entry size: %u",
          addr_entry_size);
-       proto_tree_add_text(icmp_tree, NullTVB, offset +  6, 2, "Lifetime: %s",
-         time_secs_to_str(pntohs(&pd[offset +  6])));
+       proto_tree_add_text(icmp_tree, tvb, 6, 2, "Lifetime: %s",
+         time_secs_to_str(tvb_get_ntohs(tvb, 6)));
        break;
 
       case ICMP_PARAMPROB:
-       proto_tree_add_text(icmp_tree, NullTVB, offset +  4, 1, "Pointer: %u",
-         pd[offset +  4]);
+       proto_tree_add_text(icmp_tree, tvb, 4, 1, "Pointer: %u",
+         tvb_get_guint8(tvb, 4));
        break;
 
       case ICMP_REDIRECT:
-       proto_tree_add_text(icmp_tree, NullTVB, offset +  4, 4, "Gateway address: %s",
-         ip_to_str((guint8 *)&pd[offset +  4]));
+       proto_tree_add_text(icmp_tree, tvb, 4, 4, "Gateway address: %s",
+         ip_to_str(tvb_get_ptr(tvb, 4, 4)));
        break;
     }
 
     /* Decode the additional information in the packet.  */
-    switch (ih.icmp_type) {
+    switch (icmp_type) {
       case ICMP_UNREACH:
       case ICMP_TIMXCEED:
       case ICMP_PARAMPROB:
@@ -1192,41 +1191,41 @@ dissect_icmp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
 
           XXX - for now, just display it as data; not all dissection
           routines can handle a short packet without exploding. */
-       old_dissect_data(pd, offset + 8, fd, icmp_tree);
+       dissect_data(tvb, 8, pinfo, icmp_tree);
        break;
 
       case ICMP_ECHOREPLY:
       case ICMP_ECHO:
-       old_dissect_data(pd, offset + 8, fd, icmp_tree);
+       dissect_data(tvb, 8, pinfo, icmp_tree);
        break;
 
       case ICMP_RTRADVERT:
         if (addr_entry_size == 2) {
          for (i = 0; i < num_addrs; i++) {
-           proto_tree_add_text(icmp_tree, NullTVB, offset + 8 + (i*8), 4,
+           proto_tree_add_text(icmp_tree, tvb, 8 + (i*8), 4,
              "Router address: %s",
-             ip_to_str((guint8 *)&pd[offset +  8 + (i*8)]));
-           proto_tree_add_text(icmp_tree, NullTVB, offset + 12 + (i*8), 4,
-             "Preference level: %u", pntohl(&pd[offset + 12 + (i*8)]));
+             ip_to_str(tvb_get_ptr(tvb, 8 + (i*8), 4)));
+           proto_tree_add_text(icmp_tree, tvb, 12 + (i*8), 4,
+             "Preference level: %u", tvb_get_ntohl(tvb, 12 + (i*8)));
          }
        } else
-         old_dissect_data(pd, offset + 8, fd, icmp_tree);
+         dissect_data(tvb, 8, pinfo, icmp_tree);
        break;
 
       case ICMP_TSTAMP:
       case ICMP_TSTAMPREPLY:
-       proto_tree_add_text(icmp_tree, NullTVB, offset +  8, 4, "Originate timestamp: %u",
-         pntohl(&pd[offset +  8]));
-       proto_tree_add_text(icmp_tree, NullTVB, offset + 12, 4, "Receive timestamp: %u",
-         pntohl(&pd[offset + 12]));
-       proto_tree_add_text(icmp_tree, NullTVB, offset + 16, 4, "Transmit timestamp: %u",
-         pntohl(&pd[offset + 16]));
+       proto_tree_add_text(icmp_tree, tvb, 8, 4, "Originate timestamp: %u",
+         tvb_get_ntohl(tvb, 8));
+       proto_tree_add_text(icmp_tree, tvb, 12, 4, "Receive timestamp: %u",
+         tvb_get_ntohl(tvb, 12));
+       proto_tree_add_text(icmp_tree, tvb, 16, 4, "Transmit timestamp: %u",
+         tvb_get_ntohl(tvb, 16));
        break;
 
     case ICMP_MASKREQ:
     case ICMP_MASKREPLY:
-       proto_tree_add_text(icmp_tree, NullTVB, offset +  8, 4, "Address mask: %s (0x%8x)",
-         ip_to_str((guint8 *)&pd[offset +  8]), pntohl(&pd[offset +  8]));
+       proto_tree_add_text(icmp_tree, tvb, 8, 4, "Address mask: %s (0x%8x)",
+         ip_to_str(tvb_get_ptr(tvb, 8, 4)), tvb_get_ntohl(tvb, 8));
        break;
     }
   }
@@ -1469,17 +1468,19 @@ proto_register_ip(void)
            "Decode IPv4 TOS field as DiffServ field",
 "Whether the IPv4 type-of-service field should be decoded as a Differentiated Services field",
            &g_ip_dscp_actif);
+
+       register_dissector("ip", dissect_ip);
 }
 
 void
 proto_reg_handoff_ip(void)
 {
-       old_dissector_add("ethertype", ETHERTYPE_IP, dissect_ip);
-       old_dissector_add("ppp.protocol", PPP_IP, dissect_ip);
-       old_dissector_add("llc.dsap", SAP_IP, dissect_ip);
-       old_dissector_add("ip.proto", IP_PROTO_IPV4, dissect_ip);
-       old_dissector_add("ip.proto", IP_PROTO_IPIP, dissect_ip);
-       old_dissector_add("null.type", BSD_AF_INET, dissect_ip);
+       dissector_add("ethertype", ETHERTYPE_IP, dissect_ip);
+       dissector_add("ppp.protocol", PPP_IP, dissect_ip);
+       dissector_add("llc.dsap", SAP_IP, dissect_ip);
+       dissector_add("ip.proto", IP_PROTO_IPV4, dissect_ip);
+       dissector_add("ip.proto", IP_PROTO_IPIP, dissect_ip);
+       dissector_add("null.type", BSD_AF_INET, dissect_ip);
 }
 
 void
@@ -1512,5 +1513,5 @@ proto_register_icmp(void)
 void
 proto_reg_handoff_icmp(void)
 {
-       old_dissector_add("ip.proto", IP_PROTO_ICMP, dissect_icmp);
+  dissector_add("ip.proto", IP_PROTO_ICMP, dissect_icmp);
 }
index ac4485f4b95dec81142e59eac4d8325ef4fa2ceb..aa6324d055be9065cc2fd4780df957f6bd45c85c 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-ip.h
  * Definitions for IP packet disassembly structures and routines
  *
- * $Id: packet-ip.h,v 1.14 2000/05/26 21:54:50 guy Exp $
+ * $Id: packet-ip.h,v 1.15 2000/11/18 10:38:24 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -28,7 +28,7 @@
 #define __PACKET_IP_H__
 
 void capture_ip(const u_char *, int, packet_counts *);
-void dissect_ip(const u_char *, int, frame_data *, proto_tree *);
+void dissect_ip(tvbuff_t *, packet_info *, proto_tree *);
 
 #define IP_PROTO_IP            0               /* dummy for IP */
 #define IP_PROTO_HOPOPTS       0               /* IP6 hop-by-hop options */
@@ -76,12 +76,12 @@ typedef struct ip_tcp_opt {
   int   *subtree_index;        /* pointer to subtree index for option */
   opt_len_type len_type; /* type of option length field */
   int  optlen;         /* value length should be (minimum if VARIABLE) */
-  void (*dissect)(const struct ip_tcp_opt *, const u_char *, int, guint, proto_tree *);
+  void (*dissect)(const struct ip_tcp_opt *, tvbuff_t *, int, guint, proto_tree *);
                        /* routine to dissect option */
 } ip_tcp_opt;
 
 /* Routine to dissect IP or TCP options. */
-void       dissect_ip_tcp_options(const u_char *, int, guint,
+void       dissect_ip_tcp_options(tvbuff_t *, int, guint,
     const ip_tcp_opt *, int, int, proto_tree *);
 
 /* Dissector table for "ip.proto"; used by IPv6 as well as IPv4 */
index b1e1ca3d706c5099f77316507ff349c927e0b2fe..719d26f11d07f00034ac46c52d65393952cbdb74 100644 (file)
@@ -3,7 +3,7 @@
  * 
  * (c) Copyright Ashok Narayanan <ashokn@cisco.com>
  *
- * $Id: packet-mpls.c,v 1.9 2000/08/13 14:08:29 deniel Exp $
+ * $Id: packet-mpls.c,v 1.10 2000/11/18 10:38:24 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -45,7 +45,6 @@
 #include <glib.h>
 #include "etypes.h"
 #include "packet.h"
-#include "packet-ip.h"
 
 static gint proto_mpls = -1;
 
@@ -108,6 +107,8 @@ static hf_register_info mplsf_info[] = {
       "" }},
 };
 
+static dissector_handle_t ip_handle;
+
 /*
  * Given a 4-byte MPLS label starting at "start", decode this.
  * Return the label in "label", EXP bits in "exp",
@@ -177,7 +178,7 @@ dissect_mpls(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
        offset += 4;
        if (bos) break;
     }
-    dissect_ip(pd, offset, fd, tree);
+    old_call_dissector(ip_handle, pd, offset, fd, tree);
 }
 
 void
@@ -196,4 +197,9 @@ void
 proto_reg_handoff_mpls(void)
 {
        old_dissector_add("ethertype", ETHERTYPE_MPLS, dissect_mpls);
+
+       /*
+        * Get a handle for the IP dissector.
+        */
+       ip_handle = find_dissector("ip");
 }
index 1f4506919bd75f3282d738ebe657e08017d7037c..1a94a76d41486c0c437af5db82113e4ef48f2025 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for Microsoft Proxy packet dissection
  * Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
  *
- * $Id: packet-msproxy.c,v 1.12 2000/10/21 05:52:21 guy Exp $
+ * $Id: packet-msproxy.c,v 1.13 2000/11/18 10:38:24 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -220,6 +220,7 @@ static void msproxy_sub_dissector( const u_char *pd, int offset, frame_data *fd,
        conversation_t *conversation;
        proto_tree      *msp_tree;
        proto_item      *ti;
+       tvbuff_t        *tvb;
        
        conversation = find_conversation( &pi.src, &pi.dst, pi.ptype,
                pi.srcport, pi.destport, 0);
@@ -259,10 +260,11 @@ static void msproxy_sub_dissector( const u_char *pd, int offset, frame_data *fd,
 
         *ptr = redirect_info->remote_port;
        
+       tvb = tvb_create_from_top(0);
        if ( redirect_info->proto == PT_TCP)
-               decode_tcp_ports( pd, offset, fd, tree, pi.srcport, pi.destport);
+               decode_tcp_ports( tvb, offset, &pi, tree, pi.srcport, pi.destport);
        else
-               decode_udp_ports( pd, offset, fd, tree, pi.srcport, pi.destport);
+               decode_udp_ports( tvb, offset, &pi, tree, pi.srcport, pi.destport);
  
         *ptr = redirect_info->server_int_port;
 }
index 5b9f1c1e8811d8256334ceb6b333e46a941e8781..5010fd38aa8da4af5c1bf1fb84074ed114041905 100644 (file)
@@ -5,7 +5,7 @@
  * ISO 10589 ISIS (Intradomain Routeing Information Exchange Protocol)
  * ISO  9542 ESIS (End System To Intermediate System Routeing Exchange Protocol)
  *
- * $Id: packet-osi-options.c,v 1.2 2000/05/11 08:15:31 gram Exp $
+ * $Id: packet-osi-options.c,v 1.3 2000/11/18 10:38:24 guy Exp $
  * Ralf Schneider <Ralf.Schneider@t-online.de>
  *
  * Ethereal - Network traffic analyzer
@@ -171,7 +171,7 @@ static const value_string osi_opt_rfd_reassembly[] = {
 
 void
 dissect_option_qos( const u_char type, const u_char sub_type, u_char offset,
-                    u_char len, const u_char *pd, proto_tree *tree ) {
+                    u_char len, tvbuff_t *tvb, proto_tree *tree ) {
 
   u_char      tmp_type = 0;
   proto_item *ti;
@@ -221,7 +221,7 @@ dissect_option_qos( const u_char type, const u_char sub_type, u_char offset,
 };
 void
 dissect_option_route( u_char parm_type, u_char offset, u_char parm_len, 
-                      const u_char *pd, proto_tree *tree ) {
+                      tvbuff_t *tvb, proto_tree *tree ) {
 
   u_char      next_hop = 0;
   u_char      this_hop = 0;
@@ -238,23 +238,25 @@ dissect_option_route( u_char parm_type, u_char offset, u_char parm_len,
         { 0,    NULL} };
 
   if ( parm_type == OSI_OPT_SOURCE_ROUTING ) {
-    next_hop = pd[offset + 1 ];
-    netl     = pd[next_hop + 2 ];
+    next_hop = tvb_get_guint8(tvb, offset + 1 );
+    netl     = tvb_get_guint8(tvb, next_hop + 2 );
     this_hop = offset + 3;         /* points to first netl */
 
-    ti = proto_tree_add_text( tree, NullTVB, offset + next_hop, netl, 
+    ti = proto_tree_add_text( tree, tvb, offset + next_hop, netl, 
             "Source Routing: %s   ( Next Hop Highlighted In Data Buffer )",
-            (pd[offset] == 0) ? "Partial Source Routeing" :
-                                "Complete Source Routeing"  ); 
+            (tvb_get_guint8(tvb, offset) == 0) ? "Partial Source Routeing" :
+                                                 "Complete Source Routeing"  ); 
   }
   else {
-    last_hop = pd[offset + 1 ];  /* points to the end of the list */
-    netl     = pd[ last_hop ];   /* mis-used to highlight buffer */
+    last_hop = tvb_get_guint8(tvb, offset + 1 );
+        /* points to the end of the list */
+    netl     = tvb_get_guint8(tvb, last_hop );
+        /* mis-used to highlight buffer */
 
-    ti = proto_tree_add_text( tree, NullTVB, offset + next_hop, netl,
+    ti = proto_tree_add_text( tree, tvb, offset + next_hop, netl,
             "Record of Route: %s : %s",
-            (pd[offset] == 0) ? "Partial Source Routeing" :
-                                "Complete Source Routeing" ,
+            (tvb_get_guint8(tvb, offset) == 0) ? "Partial Source Routeing" :
+                                                 "Complete Source Routeing" ,
             val_to_str( last_hop, osi_opt_route, "Unknown (0x%x" ) );
     if ( 255 == last_hop ) 
       this_hop = parm_len + 1;   /* recording terminated, nothing to show */
@@ -264,12 +266,12 @@ dissect_option_route( u_char parm_type, u_char offset, u_char parm_len,
   osi_route_tree = proto_item_add_subtree( ti, ott_osi_route );
   
   while ( this_hop < parm_len ) {
-    netl = pd[this_hop + 1];
-    proto_tree_add_text( osi_route_tree, NullTVB, offset + this_hop, netl,
+    netl = tvb_get_guint8(tvb, this_hop + 1);
+    proto_tree_add_text( osi_route_tree, tvb, offset + this_hop, netl,
                   "Hop #%3u NETL: %2u, NET: %s",
                   cnt_hops++,
                   netl,
-                  print_nsap_net( &pd[this_hop + 1], netl ) );
+                  print_nsap_net( tvb_get_ptr(tvb, this_hop + 1, netl), netl ) );
     this_hop += 1 + netl;
   }
 };
@@ -280,7 +282,7 @@ dissect_option_route( u_char parm_type, u_char offset, u_char parm_len,
 
 void
 dissect_option_rfd( const u_char error, const u_char field, u_char offset,
-                          u_char len, const u_char *pd, proto_tree *tree ) {
+                          u_char len, tvbuff_t *tvb, proto_tree *tree ) {
   u_char error_class = 0;
   char   *format_string[] = 
              { "Reason for discard {General}        : %s, in field %u",
@@ -294,37 +296,37 @@ dissect_option_rfd( const u_char error, const u_char field, u_char offset,
   error_class = error & OSI_OPT_RFD_MASK;
 
   if ( OSI_OPT_RFD_GENERAL == error_class ) {
-    proto_tree_add_text( tree, NullTVB, offset + field, 1, format_string[0],
+    proto_tree_add_text( tree, tvb, offset + field, 1, format_string[0],
                          val_to_str( error & OSI_OPT_RFD_SUB_MASK,
                                osi_opt_rfd_general, "Unknown (0x%x)"), field );
   }
   else if ( OSI_OPT_RFD_ADDRESS == error_class ) {
-    proto_tree_add_text( tree, NullTVB, offset + field, 1, format_string[1],
+    proto_tree_add_text( tree, tvb, offset + field, 1, format_string[1],
                          val_to_str( error & OSI_OPT_RFD_SUB_MASK,
                                osi_opt_rfd_address, "Unknown (0x%x)"), field );
   }
   else if ( OSI_OPT_RFD_SOURCE_ROUTEING == error_class ) {
-    proto_tree_add_text( tree, NullTVB, offset + field, 1, format_string[2],
+    proto_tree_add_text( tree, tvb, offset + field, 1, format_string[2],
                          val_to_str( error & OSI_OPT_RFD_SUB_MASK,
                              osi_opt_rfd_src_route, "Unknown (0x%x)"), field );
   }
   else if ( OSI_OPT_RFD_LIFETIME == error_class ) {
-    proto_tree_add_text( tree, NullTVB, offset + field, 1, format_string[3],
+    proto_tree_add_text( tree, tvb, offset + field, 1, format_string[3],
                          val_to_str( error & OSI_OPT_RFD_SUB_MASK,
                               osi_opt_rfd_lifetime, "Unknown (0x%x)"), field );
   }
   else if ( OSI_OPT_RFD_PDU_DISCARDED == error_class ) {
-    proto_tree_add_text( tree, NullTVB, offset + field, 1, format_string[4],
+    proto_tree_add_text( tree, tvb, offset + field, 1, format_string[4],
                          val_to_str( error & OSI_OPT_RFD_SUB_MASK,
                              osi_opt_rfd_discarded, "Unknown (0x%x)"), field );
   }
   else if ( OSI_OPT_RFD_REASSEMBLY == error_class ) {
-    proto_tree_add_text( tree, NullTVB, offset + field, 1, format_string[5],
+    proto_tree_add_text( tree, tvb, offset + field, 1, format_string[5],
                          val_to_str( error & OSI_OPT_RFD_SUB_MASK,
                             osi_opt_rfd_reassembly, "Unknown (0x%x)"), field );
   }
   else {
-    proto_tree_add_text( tree, NullTVB, offset, len,
+    proto_tree_add_text( tree, tvb, offset, len,
                          "Reason for discard: UNKNOWN Error Class" );
   } 
 };
@@ -351,82 +353,90 @@ dissect_option_rfd( const u_char error, const u_char field, u_char offset,
  *   void, but we will add to the proto_tree if it is not NULL.
  */
 void
-dissect_osi_options( u_char pdu_type, u_char opt_len, const u_char *pd
-                     int offset, frame_data *fd, proto_tree *tree) {
+dissect_osi_options( u_char pdu_type, u_char opt_len, tvbuff_t *tvb
+                     int offset, packet_info *pinfo, proto_tree *tree) {
    proto_item *ti;
    proto_tree *osi_option_tree = NULL;
    u_char      parm_len        = 0;
    u_char      parm_type       = 0;
+   guint8      octet;
 
    if (tree) {
      if ( 0 == opt_len ) {
-       proto_tree_add_text( tree, NullTVB, offset, 0, 
+       proto_tree_add_text( tree, tvb, offset, 0, 
                             "### No Options for this PDU ###" );
        return;
      }
      
      if ( opt_len > END_OF_FRAME ) {
-       proto_tree_add_text( tree, NullTVB, offset, END_OF_FRAME, 
+       proto_tree_add_text( tree, tvb, offset, END_OF_FRAME, 
            "### Options go past the end of the captured data in this PDU ###" );
        return;
      }
 
-     ti = proto_tree_add_text( tree, NullTVB, offset, opt_len,
+     ti = proto_tree_add_text( tree, tvb, offset, opt_len,
                                "### Option Section ###" );
      osi_option_tree = proto_item_add_subtree( ti, ott_osi_options );
 
      while ( 0 < opt_len ) {
-        parm_type   = (int) pd[offset++];
-        parm_len    = (int) pd[offset++];
+        parm_type   = (int) tvb_get_guint8(tvb, offset);
+        offset++;
+        parm_len    = (int) tvb_get_guint8(tvb, offset);
+        offset++;
          
         switch ( parm_type ) {
           case   OSI_OPT_QOS_MAINTANANCE:
-                 dissect_option_qos( pd[offset]&OSI_OPT_QOS_MASK,
-                                     pd[offset]&OSI_OPT_QOS_SUB_MASK,
-                                     offset, parm_len, pd, osi_option_tree );
+                 octet = tvb_get_guint8(tvb, offset);
+                 dissect_option_qos( octet&OSI_OPT_QOS_MASK,
+                                     octet&OSI_OPT_QOS_SUB_MASK,
+                                     offset, parm_len, tvb, osi_option_tree );
           break;
           case   OSI_OPT_SECURITY:
-                 proto_tree_add_text( osi_option_tree, NullTVB, offset, parm_len,
+                 octet = tvb_get_guint8(tvb, offset);
+                 proto_tree_add_text( osi_option_tree, tvb, offset, parm_len,
                   "Security type: %s",
-                  val_to_str( pd[offset]&OSI_OPT_SEC_MASK,
+                  val_to_str( octet&OSI_OPT_SEC_MASK,
                               osi_opt_sec_vals, "Unknown (0x%x)")  );
           break;
           case   OSI_OPT_PRIORITY:
-                 if ( OSI_OPT_MAX_PRIORITY >= pd[offset] ) { 
-                   proto_tree_add_text( osi_option_tree, NullTVB, offset, parm_len,
-                                        "Priority    : %u", pd[offset] );
+                 octet = tvb_get_guint8(tvb, offset);
+                 if ( OSI_OPT_MAX_PRIORITY >= octet ) { 
+                   proto_tree_add_text( osi_option_tree, tvb, offset, parm_len,
+                                        "Priority    : %u", octet );
                  }
                  else {
-                   proto_tree_add_text( osi_option_tree, NullTVB, offset, parm_len,
+                   proto_tree_add_text( osi_option_tree, tvb, offset, parm_len,
                                         "Priority    : %u ( Invalid )", 
-                                        pd[offset] );
+                                        octet );
                  } 
           break;
           case   OSI_OPT_ADDRESS_MASK:
-                 proto_tree_add_text( osi_option_tree, NullTVB, offset, parm_len,
-                  "Address Mask: %s", print_area( &pd[offset], parm_len ) );
+                 proto_tree_add_text( osi_option_tree, tvb, offset, parm_len,
+                  "Address Mask: %s",
+                 print_area( tvb_get_ptr(tvb, offset, parm_len), parm_len ) );
           break;
           case   OSI_OPT_SNPA_MASK:
-                 proto_tree_add_text( osi_option_tree, NullTVB, offset, parm_len,
-                  "SNPA Mask   : %s", print_system_id( &pd[offset], parm_len ));
+                 proto_tree_add_text( osi_option_tree, tvb, offset, parm_len,
+                  "SNPA Mask   : %s",
+                 print_system_id( tvb_get_ptr(tvb, offset, parm_len), parm_len ));
           break;
           case   OSI_OPT_ES_CONFIG_TIMER:
-                 proto_tree_add_text( osi_option_tree, NullTVB, offset, parm_len,
-                  "ESCT     : %u seconds", pntohs( &pd[offset] ) ); 
+                 proto_tree_add_text( osi_option_tree, tvb, offset, parm_len,
+                  "ESCT     : %u seconds", tvb_get_ntohs( tvb, offset ) ); 
           break;
           case   OSI_OPT_PADDING:
-                 proto_tree_add_text( osi_option_tree, NullTVB, offset, parm_len,
+                 proto_tree_add_text( osi_option_tree, tvb, offset, parm_len,
                   "Padding  : %u Octets", parm_len ) ;
           break;
           case   OSI_OPT_SOURCE_ROUTING:
           case   OSI_OPT_RECORD_OF_ROUTE:
                  dissect_option_route( parm_type,
-                                       offset, parm_len, pd, osi_option_tree );
+                                       offset, parm_len, tvb, osi_option_tree );
           break;
           case   OSI_OPT_REASON_OF_DISCARD:
-                 dissect_option_rfd( pd[offset],
-                                     pd[offset + 1],
-                                     offset, parm_len, pd, osi_option_tree );
+                 dissect_option_rfd( tvb_get_guint8(tvb, offset),
+                                     tvb_get_guint8(tvb, offset + 1),
+                                     offset, parm_len, tvb, osi_option_tree );
           break;
         }
         opt_len -= parm_len + 2;
index fdd54d8368a5d2329bd06dee8523056508190128..d3b760d8008a402093ac69b3c6d46523c9a9c3e8 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-osi-options.h
  * Defines for OSI options part decode 
  *
- * $Id: packet-osi-options.h,v 1.1 2000/04/15 22:11:12 guy Exp $
+ * $Id: packet-osi-options.h,v 1.2 2000/11/18 10:38:24 guy Exp $
  * Ralf Schneider <Ralf.Schneider@t-online.de>
  *
  * Ethereal - Network traffic analyzer
@@ -32,8 +32,8 @@
 /*
  * published API functions
  */ 
-extern void dissect_osi_options( u_char, u_char, const u_char *, int,
-                                 frame_data *, proto_tree *);
+extern void dissect_osi_options( u_char, u_char, tvbuff_t *, int,
+                                 packet_info *, proto_tree *);
 extern void proto_register_osi_options(void);
 
 #endif /* _PACKET_OSI_OPTIONS_H */
index e2a9c8c5e300cde72f69430635244c9cf92a900d..0a39f27a94d17dae7de98bf531980c8624082622 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for ISO/OSI network and transport protocol packet disassembly
  * Main entrance point and common functions
  *
- * $Id: packet-osi.c,v 1.35 2000/11/17 06:02:21 guy Exp $
+ * $Id: packet-osi.c,v 1.36 2000/11/18 10:38:24 guy Exp $
  * Laurent Deniel <deniel@worldnet.fr>
  * Ralf Schneider <Ralf.Schneider@t-online.de>
  *
@@ -176,25 +176,29 @@ gchar *print_nsap_net( const u_char *buffer, int length)
 } /* print_nsap */
 
 
-gchar *calc_checksum( const u_char *buffer, u_int len, u_int checksum) {
+gchar *calc_checksum( tvbuff_t *tvb, int offset, u_int len, u_int checksum) {
   u_int   calc_sum = 0;
   u_int   count    = 0;
+  const gchar *buffer;
+  guint   available_len;
 
-  static char *checksum_string[] = { "Not Used", 
-                                     "Is good",
-                                     "Is wrong" }; 
   if ( 0 == checksum )
-    return( checksum_string[0] );
+    return( "Not Used" );
 
+  available_len = tvb_length_remaining( tvb, offset );
+  if ( available_len < len )
+    return( "Not checkable - not all of packet was captured" );
+
+  buffer = tvb_get_ptr( tvb, offset, len );
   for ( count = 0; count < len; count++ ) {
     calc_sum += (u_int) buffer[count];
   }
   calc_sum %= 255;  /* modulo 255 divison */
   
   if ( 0 == calc_sum )
-    return( checksum_string[1] );
+    return( "Is good" );
   else
-    return( checksum_string[2] );
+    return( "Is wrong" );      /* XXX - what should the checksum be? */
 }
 
 
@@ -222,37 +226,42 @@ const value_string nlpid_vals[] = {
 
 static dissector_table_t subdissector_table;
 
-void dissect_osi(const u_char *pd, int offset, frame_data *fd, 
-                proto_tree *tree) 
+void dissect_osi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) 
 {
+  guint8 nlpid;
+
+  pinfo->current_proto = "OSI";
+
+  nlpid = tvb_get_guint8(tvb, 0);
+
   /* do lookup with the subdissector table */
-  if (old_dissector_try_port(subdissector_table, pd[offset], pd, offset, fd, tree))
+  if (dissector_try_port(subdissector_table, nlpid, tvb, pinfo, tree))
       return;
 
-  switch (pd[offset]) {
+  switch (nlpid) {
 
     /* ESIS (X.25) is not currently decoded */
 
     case NLPID_ISO9542X25_ESIS:
-      if (check_col(fd, COL_PROTOCOL)) {
-       col_add_str(fd, COL_PROTOCOL, "ESIS (X.25)");
+      if (check_col(pinfo->fd, COL_PROTOCOL)) {
+       col_add_str(pinfo->fd, COL_PROTOCOL, "ESIS (X.25)");
       }
-      old_dissect_data(pd, offset, fd, tree);
+      dissect_data(tvb, 0, pinfo, tree);
       break;
     case NLPID_ISO10747_IDRP:
-      if (check_col(fd, COL_PROTOCOL)) {
-        col_add_str(fd, COL_PROTOCOL, "IDRP");
+      if (check_col(pinfo->fd, COL_PROTOCOL)) {
+        col_add_str(pinfo->fd, COL_PROTOCOL, "IDRP");
       }
-      old_dissect_data(pd, offset, fd, tree);
+      dissect_data(tvb, 0, pinfo, tree);
       break;
     default:
-      if (check_col(fd, COL_PROTOCOL)) {
-       col_add_str(fd, COL_PROTOCOL, "ISO");
+      if (check_col(pinfo->fd, COL_PROTOCOL)) {
+       col_add_str(pinfo->fd, COL_PROTOCOL, "ISO");
       }
-      if (check_col(fd, COL_INFO)) {
-       col_add_fstr(fd, COL_INFO, "Unknown ISO protocol (%02x)", pd[offset]);
+      if (check_col(pinfo->fd, COL_INFO)) {
+       col_add_fstr(pinfo->fd, COL_INFO, "Unknown ISO protocol (%02x)", nlpid);
       }
-      old_dissect_data(pd, offset, fd, tree);
+      dissect_data(tvb, 0, pinfo, tree);
       break;
   }
 } /* dissect_osi */
@@ -269,6 +278,6 @@ proto_register_osi(void)
 void
 proto_reg_handoff_osi(void)
 {
-       old_dissector_add("llc.dsap", SAP_OSINL, dissect_osi);
-       old_dissector_add("null.type", BSD_AF_ISO, dissect_osi);
+       dissector_add("llc.dsap", SAP_OSINL, dissect_osi);
+       dissector_add("null.type", BSD_AF_ISO, dissect_osi);
 }
index 04e310cacc51e35878961795a390d3e348a9dff1..b5c759228b09cb10b8abdbbe82b0a192968877af 100644 (file)
@@ -1,6 +1,6 @@
 /* packet-osi.h
  *
- * $Id: packet-osi.h,v 1.4 2000/07/01 08:55:28 guy Exp $
+ * $Id: packet-osi.h,v 1.5 2000/11/18 10:38:25 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
  * published API functions
  */
 
-extern void   dissect_osi( const u_char *, int, frame_data *, proto_tree *);
+extern void   dissect_osi( tvbuff_t *, packet_info *, proto_tree *);
 extern gchar *print_nsap_net ( const u_char *, int );
 extern gchar *print_area     ( const u_char *, int );
 extern gchar *print_system_id( const u_char *, int );
-extern gchar *calc_checksum  ( const u_char *, u_int, u_int );
+extern gchar *calc_checksum  ( tvbuff_t *, int, u_int, u_int );
 
 #endif /* _PACKET_OSI_H */
 
index 753acbbbd2889a37bbed3d16b1d0f7fff2462220..86a31cf4d757abac2c8e555e2919e81e6c35fe75 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for PIM disassembly
  * (c) Copyright Jun-ichiro itojun Hagino <itojun@itojun.org>
  *
- * $Id: packet-pim.c,v 1.18 2000/11/17 21:00:35 gram Exp $
+ * $Id: packet-pim.c,v 1.19 2000/11/18 10:38:25 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -70,6 +70,8 @@ static int hf_pim_cksum = -1;
 
 static gint ett_pim = -1;
 
+static dissector_handle_t ip_handle;
+
 static const char *
 dissect_pim_addr(const u_char *bp, const u_char *ep, enum pimv2_addrtype at,
        int *advance) {
@@ -284,9 +286,9 @@ dissect_pim(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
            switch((*ip & 0xf0) >> 4) {
            case 4:     /* IPv4 */
 #if 0
-                   dissect_ip(pd, ip - pd, fd, tree);
+                   old_call_dissector(ip_handle, pd, ip - pd, fd, tree);
 #else
-                   dissect_ip(pd, ip - pd, fd, pimopt_tree);
+                   old_call_dissector(ip_handle, pd, ip - pd, fd, pimopt_tree);
 #endif
                    break;
            case 6:     /* IPv6 */
@@ -607,5 +609,9 @@ void
 proto_reg_handoff_pim(void)
 {
     old_dissector_add("ip.proto", IP_PROTO_PIM, dissect_pim);
-}
 
+    /*
+     * Get a handle for the IP dissector.
+     */
+    ip_handle = find_dissector("ip");
+}
index 06f97d33d63ae00a6dc868f2e1a9296edc367ba5..7b4c167dbef81178324b33cf13b48d285872ed49 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-ppp.c
  * Routines for ppp packet disassembly
  *
- * $Id: packet-ppp.c,v 1.40 2000/11/16 07:35:38 guy Exp $
+ * $Id: packet-ppp.c,v 1.41 2000/11/18 10:38:25 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -184,37 +184,37 @@ static const value_string lcp_vals[] = {
 #define CI_INTERNATIONALIZATION        28      /* Internationalization (RFC 2484) */
 #define        CI_SDL_ON_SONET_SDH     29      /* Simple Data Link on SONET/SDH */
 
-static void dissect_lcp_mru_opt(const ip_tcp_opt *optp, const u_char *opd,
+static void dissect_lcp_mru_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
                        int offset, guint length, proto_tree *tree);
-static void dissect_lcp_async_map_opt(const ip_tcp_opt *optp, const u_char *opd,
+static void dissect_lcp_async_map_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
                        int offset, guint length, proto_tree *tree);
-static void dissect_lcp_protocol_opt(const ip_tcp_opt *optp, const u_char *opd,
+static void dissect_lcp_protocol_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
                        int offset, guint length, proto_tree *tree);
 static void dissect_lcp_magicnumber_opt(const ip_tcp_opt *optp,
-                       const u_char *opd, int offset, guint length,
+                       tvbuff_t *tvb, int offset, guint length,
                        proto_tree *tree);
 static void dissect_lcp_fcs_alternatives_opt(const ip_tcp_opt *optp,
-                       const u_char *opd, int offset, guint length,
+                       tvbuff_t *tvb, int offset, guint length,
                        proto_tree *tree);
 static void dissect_lcp_numbered_mode_opt(const ip_tcp_opt *optp,
-                       const u_char *opd, int offset, guint length,
+                       tvbuff_t *tvb, int offset, guint length,
                        proto_tree *tree);
 static void dissect_lcp_self_describing_pad_opt(const ip_tcp_opt *optp,
-                       const u_char *opd, int offset, guint length,
+                       tvbuff_t *tvb, int offset, guint length,
                        proto_tree *tree);
-static void dissect_lcp_callback_opt(const ip_tcp_opt *optp, const u_char *opd,
+static void dissect_lcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
                        int offset, guint length, proto_tree *tree);
 static void dissect_lcp_multilink_mrru_opt(const ip_tcp_opt *optp,
-                       const u_char *opd, int offset, guint length,
+                       tvbuff_t *tvb, int offset, guint length,
                        proto_tree *tree);
 static void dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp,
-                       const u_char *opd, int offset, guint length,
+                       tvbuff_t *tvb, int offset, guint length,
                        proto_tree *tree);
 static void dissect_lcp_bap_link_discriminator_opt(const ip_tcp_opt *optp,
-                       const u_char *opd, int offset, guint length,
+                       tvbuff_t *tvb, int offset, guint length,
                        proto_tree *tree);
 static void dissect_lcp_internationalization_opt(const ip_tcp_opt *optp,
-                       const u_char *opd, int offset, guint length,
+                       tvbuff_t *tvb, int offset, guint length,
                        proto_tree *tree);
 static void dissect_mp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
 
@@ -427,9 +427,9 @@ static const ip_tcp_opt lcp_opts[] = {
 #define CI_MS_DNS2     131     /* Secondary DNS value (RFC 1877) */
 #define CI_MS_WINS2    132     /* Secondary WINS value (RFC 1877) */
 
-static void dissect_ipcp_addrs_opt(const ip_tcp_opt *optp, const u_char *opd,
+static void dissect_ipcp_addrs_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
                        int offset, guint length, proto_tree *tree);
-static void dissect_ipcp_addr_opt(const ip_tcp_opt *optp, const u_char *opd,
+static void dissect_ipcp_addr_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
                        int offset, guint length, proto_tree *tree);
 
 static const ip_tcp_opt ipcp_opts[] = {
@@ -520,103 +520,103 @@ capture_ppp( const u_char *pd, int offset, packet_counts *ld ) {
 }
 
 static void
-dissect_lcp_mru_opt(const ip_tcp_opt *optp, const u_char *opd, int offset,
+dissect_lcp_mru_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
                        guint length, proto_tree *tree)
 {
-  proto_tree_add_text(tree, NullTVB, offset, length, "MRU: %u", pntohs(opd));
+  proto_tree_add_text(tree, tvb, offset, length, "MRU: %u",
+                       tvb_get_ntohs(tvb, offset + 2));
 }
 
 static void
-dissect_lcp_async_map_opt(const ip_tcp_opt *optp, const u_char *opd, int offset,
+dissect_lcp_async_map_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
                        guint length, proto_tree *tree)
 {
-  proto_tree_add_text(tree, NullTVB, offset, length, "Async characters to map: 0x%08x",
-                       pntohl(opd));
+  proto_tree_add_text(tree, tvb, offset, length, "Async characters to map: 0x%08x",
+                       tvb_get_ntohl(tvb, offset + 2));
 }
 
 static void
-dissect_lcp_protocol_opt(const ip_tcp_opt *optp, const u_char *opd, int offset,
+dissect_lcp_protocol_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
                        guint length, proto_tree *tree)
 {
   guint16 protocol;
   proto_item *tf;
   proto_tree *field_tree = NULL;
   
-  tf = proto_tree_add_text(tree, NullTVB, offset, length, "%s: %u byte%s",
+  tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s",
          optp->name, length, plurality(length, "", "s"));
   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
   offset += 2;
   length -= 2;
-  protocol = pntohs(opd);
-  proto_tree_add_text(field_tree, NullTVB, offset, 2, "%s: %s (0x%02x)", optp->name,
+  protocol = tvb_get_ntohs(tvb, offset);
+  proto_tree_add_text(field_tree, tvb, offset, 2, "%s: %s (0x%02x)", optp->name,
                val_to_str(protocol, ppp_vals, "Unknown"), protocol);
   offset += 2;
-  opd += 2;
   length -= 2;
   if (length > 0)
-    proto_tree_add_text(field_tree, NullTVB, offset, length, "Data (%d byte%s)", length,
+    proto_tree_add_text(field_tree, tvb, offset, length, "Data (%d byte%s)", length,
                        plurality(length, "", "s"));
 }
 
 static void
-dissect_lcp_magicnumber_opt(const ip_tcp_opt *optp, const u_char *opd,
+dissect_lcp_magicnumber_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
                        int offset, guint length, proto_tree *tree)
 {
-  proto_tree_add_text(tree, NullTVB, offset, length, "Magic number: 0x%08x",
-                       pntohl(opd));
+  proto_tree_add_text(tree, tvb, offset, length, "Magic number: 0x%08x",
+                       tvb_get_ntohl(tvb, offset + 2));
 }
 
 static void
-dissect_lcp_fcs_alternatives_opt(const ip_tcp_opt *optp, const u_char *opd,
+dissect_lcp_fcs_alternatives_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
                        int offset, guint length, proto_tree *tree)
 {
   proto_item *tf;
   proto_tree *field_tree = NULL;
   guint8 alternatives;
   
-  alternatives = *opd;
-  tf = proto_tree_add_text(tree, NullTVB, offset, length, "%s: 0x%02x",
+  alternatives = tvb_get_guint8(tvb, offset + 2);
+  tf = proto_tree_add_text(tree, tvb, offset, length, "%s: 0x%02x",
          optp->name, alternatives);
   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
   offset += 2;
   if (alternatives & 0x1)
-    proto_tree_add_text(field_tree, NullTVB, offset + 2, 1, "%s",
+    proto_tree_add_text(field_tree, tvb, offset + 2, 1, "%s",
        decode_boolean_bitfield(alternatives, 0x1, 8, "Null FCS", NULL));
   if (alternatives & 0x2)
-    proto_tree_add_text(field_tree, NullTVB, offset + 2, 1, "%s",
+    proto_tree_add_text(field_tree, tvb, offset + 2, 1, "%s",
        decode_boolean_bitfield(alternatives, 0x2, 8, "CCITT 16-bit FCS", NULL));
   if (alternatives & 0x4)
-    proto_tree_add_text(field_tree, NullTVB, offset + 2, 1, "%s",
+    proto_tree_add_text(field_tree, tvb, offset + 2, 1, "%s",
        decode_boolean_bitfield(alternatives, 0x4, 8, "CCITT 32-bit FCS", NULL));
 }
 
 static void
-dissect_lcp_self_describing_pad_opt(const ip_tcp_opt *optp, const u_char *opd,
+dissect_lcp_self_describing_pad_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
                        int offset, guint length, proto_tree *tree)
 {
-  proto_tree_add_text(tree, NullTVB, offset, length,
+  proto_tree_add_text(tree, tvb, offset, length,
                        "Maximum octets of self-describing padding: %u",
-                       *opd);
+                       tvb_get_guint8(tvb, offset + 2));
 }
 
 static void
-dissect_lcp_numbered_mode_opt(const ip_tcp_opt *optp, const u_char *opd,
+dissect_lcp_numbered_mode_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
                        int offset, guint length, proto_tree *tree)
 {
   proto_item *tf;
   proto_tree *field_tree = NULL;
   
-  tf = proto_tree_add_text(tree, NullTVB, offset, length, "%s: %u byte%s",
+  tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s",
          optp->name, length, plurality(length, "", "s"));
   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
   offset += 2;
   length -= 2;
-  proto_tree_add_text(field_tree, NullTVB, offset, 1, "Window: %u", *opd);
+  proto_tree_add_text(field_tree, tvb, offset, 1, "Window: %u",
+                       tvb_get_guint8(tvb, offset));
   offset += 1;
-  opd += 1;
   length -= 1;
   if (length > 0)
-    proto_tree_add_text(field_tree, NullTVB, offset, length, "Address (%d byte%s)",
+    proto_tree_add_text(field_tree, tvb, offset, length, "Address (%d byte%s)",
                        length, plurality(length, "", "s"));
 }
 
@@ -630,34 +630,35 @@ static const value_string callback_op_vals[] = {
 };
 
 static void
-dissect_lcp_callback_opt(const ip_tcp_opt *optp, const u_char *opd, int offset,
+dissect_lcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
                        guint length, proto_tree *tree)
 {
   proto_item *tf;
   proto_tree *field_tree = NULL;
+  guint8 operation;
   
-  tf = proto_tree_add_text(tree, NullTVB, offset, length, "%s: %u byte%s",
+  tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s",
          optp->name, length, plurality(length, "", "s"));
   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
   offset += 2;
   length -= 2;
-  proto_tree_add_text(field_tree, NullTVB, offset, 1, "Operation: %s (0x%02x)",
-               val_to_str(*opd, callback_op_vals, "Unknown"),
-               *opd);
+  operation = tvb_get_guint8(tvb, offset);
+  proto_tree_add_text(field_tree, tvb, offset, 1, "Operation: %s (0x%02x)",
+               val_to_str(operation, callback_op_vals, "Unknown"),
+               operation);
   offset += 1;
-  opd += 1;
   length -= 1;
   if (length > 0)
-    proto_tree_add_text(field_tree, NullTVB, offset, length, "Message (%d byte%s)",
+    proto_tree_add_text(field_tree, tvb, offset, length, "Message (%d byte%s)",
                        length, plurality(length, "", "s"));
 }
 
 static void
-dissect_lcp_multilink_mrru_opt(const ip_tcp_opt *optp, const u_char *opd,
+dissect_lcp_multilink_mrru_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
                        int offset, guint length, proto_tree *tree)
 {
-  proto_tree_add_text(tree, NullTVB, offset, length, "Multilink MRRU: %u",
-                       pntohs(opd));
+  proto_tree_add_text(tree, tvb, offset, length, "Multilink MRRU: %u",
+                       tvb_get_ntohs(tvb, offset + 2));
 }
 
 #define CLASS_NULL                     0
@@ -678,41 +679,40 @@ static const value_string multilink_ep_disc_class_vals[] = {
 };
 
 static void
-dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp, const u_char *opd,
+dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
                        int offset, guint length, proto_tree *tree)
 {
   proto_item *tf;
   proto_tree *field_tree = NULL;
   guint8 ep_disc_class;
 
-  tf = proto_tree_add_text(tree, NullTVB, offset, length, "%s: %u byte%s",
+  tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s",
          optp->name, length, plurality(length, "", "s"));
   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
   offset += 2;
   length -= 2;
-  ep_disc_class = *opd;
-  proto_tree_add_text(field_tree, NullTVB, offset, 1, "Class: %s (%u)",
+  ep_disc_class = tvb_get_guint8(tvb, offset);
+  proto_tree_add_text(field_tree, tvb, offset, 1, "Class: %s (%u)",
                val_to_str(ep_disc_class, multilink_ep_disc_class_vals, "Unknown"),
                ep_disc_class);
   offset += 1;
-  opd += 1;
   length -= 1;
   if (length > 0) {
     switch (ep_disc_class) {
 
     case CLASS_NULL:
-      proto_tree_add_text(field_tree, NullTVB, offset, length,
+      proto_tree_add_text(field_tree, tvb, offset, length,
                        "Address (%d byte%s), should have been empty",
                        length, plurality(length, "", "s"));
       break;
 
     case CLASS_LOCAL:
       if (length > 20) {
-        proto_tree_add_text(field_tree, NullTVB, offset, length,
+        proto_tree_add_text(field_tree, tvb, offset, length,
                        "Address (%d byte%s), should have been <20",
                        length, plurality(length, "", "s"));
       } else {
-        proto_tree_add_text(field_tree, NullTVB, offset, length,
+        proto_tree_add_text(field_tree, tvb, offset, length,
                        "Address (%d byte%s)",
                        length, plurality(length, "", "s"));
       }
@@ -720,34 +720,34 @@ dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp, const u_char *opd,
 
     case CLASS_IP:
       if (length != 4) {
-        proto_tree_add_text(field_tree, NullTVB, offset, length,
+        proto_tree_add_text(field_tree, tvb, offset, length,
                        "Address (%d byte%s), should have been 4",
                        length, plurality(length, "", "s"));
       } else {
-        proto_tree_add_text(field_tree, NullTVB, offset, length,
-                       "Address: %s", ip_to_str(opd));
+        proto_tree_add_text(field_tree, tvb, offset, length,
+                       "Address: %s", ip_to_str(tvb_get_ptr(tvb, offset, 4)));
       }
       break;
 
     case CLASS_IEEE_802_1:
       if (length != 6) {
-        proto_tree_add_text(field_tree, NullTVB, offset, length,
+        proto_tree_add_text(field_tree, tvb, offset, length,
                        "Address (%d byte%s), should have been 6",
                        length, plurality(length, "", "s"));
       } else {
-        proto_tree_add_text(field_tree, NullTVB, offset, length,
-                       "Address: %s", ether_to_str(opd));
+        proto_tree_add_text(field_tree, tvb, offset, length,
+                       "Address: %s", ether_to_str(tvb_get_ptr(tvb, offset, 6)));
       }
       break;
 
     case CLASS_PPP_MAGIC_NUMBER:
       /* XXX - dissect as 32-bit magic numbers */
       if (length > 20) {
-        proto_tree_add_text(field_tree, NullTVB, offset, length,
+        proto_tree_add_text(field_tree, tvb, offset, length,
                        "Address (%d byte%s), should have been <20",
                        length, plurality(length, "", "s"));
       } else {
-        proto_tree_add_text(field_tree, NullTVB, offset, length,
+        proto_tree_add_text(field_tree, tvb, offset, length,
                        "Address (%d byte%s)",
                        length, plurality(length, "", "s"));
       }
@@ -755,18 +755,18 @@ dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp, const u_char *opd,
 
     case CLASS_PSDN_DIRECTORY_NUMBER:
       if (length > 15) {
-        proto_tree_add_text(field_tree, NullTVB, offset, length,
+        proto_tree_add_text(field_tree, tvb, offset, length,
                        "Address (%d byte%s), should have been <20",
                        length, plurality(length, "", "s"));
       } else {
-        proto_tree_add_text(field_tree, NullTVB, offset, length,
+        proto_tree_add_text(field_tree, tvb, offset, length,
                        "Address (%d byte%s)",
                        length, plurality(length, "", "s"));
       }
       break;
 
     default:
-      proto_tree_add_text(field_tree, NullTVB, offset, length,
+      proto_tree_add_text(field_tree, tvb, offset, length,
                        "Address (%d byte%s)",
                        length, plurality(length, "", "s"));
       break;
@@ -775,12 +775,12 @@ dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp, const u_char *opd,
 }
 
 static void
-dissect_lcp_bap_link_discriminator_opt(const ip_tcp_opt *optp, const u_char *opd,
+dissect_lcp_bap_link_discriminator_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
                        int offset, guint length, proto_tree *tree)
 {
-  proto_tree_add_text(tree, NullTVB, offset, length,
+  proto_tree_add_text(tree, tvb, offset, length,
                        "Link discriminator for BAP: 0x%04x",
-                       pntohs(opd));
+                       tvb_get_ntohs(tvb, offset + 2));
 }
 
 /* Character set numbers from the IANA charset registry. */
@@ -790,56 +790,58 @@ static const value_string charset_num_vals[] = {
 };
 
 static void
-dissect_lcp_internationalization_opt(const ip_tcp_opt *optp, const u_char *opd,
+dissect_lcp_internationalization_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
                        int offset, guint length, proto_tree *tree)
 {
   proto_item *tf;
   proto_tree *field_tree = NULL;
+  guint32 charset;
   
-  tf = proto_tree_add_text(tree, NullTVB, offset, length, "%s: %u byte%s",
+  tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s",
          optp->name, length, plurality(length, "", "s"));
   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
   offset += 2;
   length -= 2;
-  proto_tree_add_text(field_tree, NullTVB, offset, 4, "Character set: %s (0x%04x)",
-               val_to_str(pntohl(opd), charset_num_vals, "Unknown"),
-               pntohl(opd));
+  charset = tvb_get_ntohl(tvb, offset);
+  proto_tree_add_text(field_tree, tvb, offset, 4, "Character set: %s (0x%04x)",
+               val_to_str(charset, charset_num_vals, "Unknown"),
+               charset);
   offset += 4;
-  opd += 4;
   length -= 4;
   if (length > 0) {
     /* XXX - should be displayed as an ASCII string */
-    proto_tree_add_text(field_tree, NullTVB, offset, length, "Language tag (%d byte%s)",
+    proto_tree_add_text(field_tree, tvb, offset, length, "Language tag (%d byte%s)",
                        length, plurality(length, "", "s"));
   }
 }
 
 static void
-dissect_ipcp_addrs_opt(const ip_tcp_opt *optp, const u_char *opd,
+dissect_ipcp_addrs_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
                        int offset, guint length, proto_tree *tree)
 {
   proto_item *tf;
   proto_tree *field_tree = NULL;
   
-  tf = proto_tree_add_text(tree, NullTVB, offset, length, "%s: %u byte%s",
+  tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s",
          optp->name, length, plurality(length, "", "s"));
   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
   offset += 2;
   length -= 2;
-  proto_tree_add_text(field_tree, NullTVB, offset, 4,
-                       "Source IP address: %s", ip_to_str(opd));
+  proto_tree_add_text(field_tree, tvb, offset, 4,
+                       "Source IP address: %s",
+                       ip_to_str(tvb_get_ptr(tvb, offset, 4)));
   offset += 4;
-  opd += 4;
   length -= 4;
-  proto_tree_add_text(field_tree, NullTVB, offset, 4,
-                       "Destination IP address: %s", ip_to_str(opd));
+  proto_tree_add_text(field_tree, tvb, offset, 4,
+                       "Destination IP address: %s",
+                       ip_to_str(tvb_get_ptr(tvb, offset, 4)));
 }
 
-static void dissect_ipcp_addr_opt(const ip_tcp_opt *optp, const u_char *opd,
+static void dissect_ipcp_addr_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
                        int offset, guint length, proto_tree *tree)
 {
-  proto_tree_add_text(tree, NullTVB, offset, length, "%s: %s", optp->name,
-                       ip_to_str((guint8 *)opd));
+  proto_tree_add_text(tree, tvb, offset, length, "%s: %s", optp->name,
+                       ip_to_str(tvb_get_ptr(tvb, offset + 2, 4)));
 }
 
 static void
@@ -886,16 +888,11 @@ dissect_cp( tvbuff_t *tvb, const char *proto_short_name,
     case CONFREJ:
       if(tree) {
         if (length > 0) {
-         const guint8  *this_pd;
-         int           this_offset;
-
-         tvb_compat(tvb, &this_pd, &this_offset);
-
           tf = proto_tree_add_text(fh_tree, tvb, offset, length,
             "Options: (%d byte%s)", length, plurality(length, "", "s"));
           field_tree = proto_item_add_subtree(tf, options_subtree_index);
-          dissect_ip_tcp_options(&this_pd[this_offset + offset],this_offset + offset,
-                         length, opts, nopts, -1, field_tree);
+          dissect_ip_tcp_options(tvb, offset, length, opts, nopts, -1,
+                                field_tree);
         }
       }
       break;
index cad834baa175ec3971ac0399a54652c1652e0c4c..edb145565f90a86257efa0435cd78c791a17b0a7 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-raw.c
  * Routines for raw packet disassembly
  *
- * $Id: packet-raw.c,v 1.19 2000/11/17 21:00:35 gram Exp $
+ * $Id: packet-raw.c,v 1.20 2000/11/18 10:38:25 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -43,6 +43,8 @@ static gint ett_raw = -1;
 
 static const char zeroes[10];
 
+static dissector_handle_t ip_handle;
+
 void
 capture_raw(const u_char *pd, packet_counts *ld)
 {
@@ -82,8 +84,6 @@ dissect_raw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
   proto_tree   *fh_tree;
   proto_item   *ti;
   tvbuff_t     *next_tvb;
-  const guint8 *next_pd;
-  int          next_offset;
 
   /* load the top pane info. This should be overwritten by
      the next protocol in the stack */
@@ -132,13 +132,13 @@ dissect_raw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
   /* ...and if the connection is currently down, it sends 10 bytes of zeroes
    * instead of a fake MAC address and PPP header. */
   else if (memcmp(tvb_get_ptr(tvb, 0, 10), zeroes, 10) == 0) {
-       tvb_compat(tvb, &next_pd, &next_offset);
-       dissect_ip(next_pd, next_offset + 10, pinfo->fd, tree);
+       next_tvb = tvb_new_subset(tvb, 10, -1, -1);
+       call_dissector(ip_handle, next_tvb, pinfo, tree);
        return;
   }
   else {
-       tvb_compat(tvb, &next_pd, &next_offset);
-       dissect_ip(next_pd, next_offset, pinfo->fd, tree);
+       next_tvb = tvb_new_subset(tvb, 0, -1, -1);
+       call_dissector(ip_handle, next_tvb, pinfo, tree);
        return;
   }
   g_assert_not_reached();
@@ -153,3 +153,12 @@ proto_register_raw(void)
 
   proto_register_subtree_array(ett, array_length(ett));
 }
+
+void
+proto_reg_handoff_raw(void)
+{
+  /*
+   * Get a handle for the IP dissector.
+   */
+  ip_handle = find_dissector("ip");
+}
index add97af74f8d4283fbd47aa7c55d0828ee30958d..2387ac2fca7d913645d2f7c9f64728953db5c47e 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for socks versions 4 &5  packet dissection
  * Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
  *
- * $Id: packet-socks.c,v 1.13 2000/10/21 05:52:23 guy Exp $
+ * $Id: packet-socks.c,v 1.14 2000/11/18 10:38:25 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -366,6 +366,7 @@ static void socks_udp_dissector( const u_char *pd, int offset, frame_data *fd,
        conversation_t *conversation;
        proto_tree      *socks_tree;
        proto_item      *ti;
+       tvbuff_t        *tvb;
        
        conversation = find_conversation( &pi.src, &pi.dst, pi.ptype,
                pi.srcport, pi.destport, 0);
@@ -420,7 +421,8 @@ static void socks_udp_dissector( const u_char *pd, int offset, frame_data *fd,
 
         *ptr = hash_info->udp_remote_port;
        
-       decode_udp_ports( pd, offset, fd, tree, pi.srcport, pi.destport);
+       tvb = tvb_create_from_top(0);
+       decode_udp_ports( tvb, offset, &pi, tree, pi.srcport, pi.destport);
  
         *ptr = hash_info->udp_port;
 
@@ -923,6 +925,7 @@ static void call_next_dissector( const u_char *pd, int offset, frame_data *fd,
 /* payload, and restore the pi port after that is done.                        */
 
        guint32 *ptr;
+       tvbuff_t *tvb;
  
        if (( hash_info->command  == PING_COMMAND) ||
            ( hash_info->command  == TRACERT_COMMAND))
@@ -939,7 +942,8 @@ static void call_next_dissector( const u_char *pd, int offset, frame_data *fd,
                        ptr = &pi.srcport;
 
                *ptr = hash_info->port;
-               decode_tcp_ports( pd, offset, fd, tree, pi.srcport, pi.destport);
+               tvb = tvb_create_from_top(0);
+               decode_tcp_ports( tvb, offset, &pi, tree, pi.srcport, pi.destport);
                *ptr = TCP_PORT_SOCKS;
        }
 }                
index a7e82a8d1f945abc50352ede7d094dd9c7bb330c..d37600cad651eb43b441f1a901c5ed98fb0ef333 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-tcp.c
  * Routines for TCP packet disassembly
  *
- * $Id: packet-tcp.c,v 1.87 2000/11/05 09:26:47 oabad Exp $
+ * $Id: packet-tcp.c,v 1.88 2000/11/18 10:38:25 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -163,32 +163,38 @@ tcp_info_append_uint(const char *abbrev, guint32 val) {
 }
 
 static void
-dissect_tcpopt_maxseg(const ip_tcp_opt *optp, const u_char *opd,
+dissect_tcpopt_maxseg(const ip_tcp_opt *optp, tvbuff_t *tvb,
     int offset, guint optlen, proto_tree *opt_tree)
 {
-  proto_tree_add_text(opt_tree, NullTVB, offset,      optlen,
-                       "%s: %u bytes", optp->name, pntohs(opd));
-  tcp_info_append_uint("MSS", pntohs(opd));
+  guint16 mss;
+
+  mss = tvb_get_ntohs(tvb, offset + 2);
+  proto_tree_add_text(opt_tree, tvb, offset,      optlen,
+                       "%s: %u bytes", optp->name, mss);
+  tcp_info_append_uint("MSS", mss);
 }
 
 static void
-dissect_tcpopt_wscale(const ip_tcp_opt *optp, const u_char *opd,
+dissect_tcpopt_wscale(const ip_tcp_opt *optp, tvbuff_t *tvb,
     int offset, guint optlen, proto_tree *opt_tree)
 {
-  proto_tree_add_text(opt_tree, NullTVB, offset,      optlen,
-                       "%s: %u bytes", optp->name, *opd);
-  tcp_info_append_uint("WS", *opd);
+  guint8 ws;
+
+  ws = tvb_get_guint8(tvb, offset + 2);
+  proto_tree_add_text(opt_tree, tvb, offset,      optlen,
+                       "%s: %u bytes", optp->name, ws);
+  tcp_info_append_uint("WS", ws);
 }
 
 static void
-dissect_tcpopt_sack(const ip_tcp_opt *optp, const u_char *opd,
+dissect_tcpopt_sack(const ip_tcp_opt *optp, tvbuff_t *tvb,
     int offset, guint optlen, proto_tree *opt_tree)
 {
   proto_tree *field_tree = NULL;
   proto_item *tf;
   guint leftedge, rightedge;
 
-  tf = proto_tree_add_text(opt_tree, NullTVB, offset,      optlen, "%s:", optp->name);
+  tf = proto_tree_add_text(opt_tree, tvb, offset,      optlen, "%s:", optp->name);
   offset += 2; /* skip past type and length */
   optlen -= 2; /* subtract size of type and length */
   while (optlen > 0) {
@@ -197,24 +203,21 @@ dissect_tcpopt_sack(const ip_tcp_opt *optp, const u_char *opd,
       field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
     }
     if (optlen < 4) {
-      proto_tree_add_text(field_tree, NullTVB, offset,      optlen,
+      proto_tree_add_text(field_tree, tvb, offset,      optlen,
         "(suboption would go past end of option)");
       break;
     }
-    /* XXX - check whether it goes past end of packet */
-    leftedge = pntohl(opd);
-    opd += 4;
+    leftedge = tvb_get_ntohl(tvb, offset);
     optlen -= 4;
     if (optlen < 4) {
-      proto_tree_add_text(field_tree, NullTVB, offset,      optlen,
+      proto_tree_add_text(field_tree, tvb, offset,      optlen,
         "(suboption would go past end of option)");
       break;
     }
     /* XXX - check whether it goes past end of packet */
-    rightedge = pntohl(opd);
-    opd += 4;
+    rightedge = tvb_get_ntohl(tvb, offset + 4);
     optlen -= 4;
-    proto_tree_add_text(field_tree, NullTVB, offset,      8,
+    proto_tree_add_text(field_tree, tvb, offset,      8,
         "left edge = %u, right edge = %u", leftedge, rightedge);
     tcp_info_append_uint("SLE", leftedge);
     tcp_info_append_uint("SRE", rightedge);
@@ -223,31 +226,41 @@ dissect_tcpopt_sack(const ip_tcp_opt *optp, const u_char *opd,
 }
 
 static void
-dissect_tcpopt_echo(const ip_tcp_opt *optp, const u_char *opd,
+dissect_tcpopt_echo(const ip_tcp_opt *optp, tvbuff_t *tvb,
     int offset, guint optlen, proto_tree *opt_tree)
 {
-  proto_tree_add_text(opt_tree, NullTVB, offset,      optlen,
-                       "%s: %u", optp->name, pntohl(opd));
-  tcp_info_append_uint("ECHO", pntohl(opd));
+  guint32 echo;
+
+  echo = tvb_get_ntohl(tvb, offset + 2);
+  proto_tree_add_text(opt_tree, tvb, offset,      optlen,
+                       "%s: %u", optp->name, echo);
+  tcp_info_append_uint("ECHO", echo);
 }
 
 static void
-dissect_tcpopt_timestamp(const ip_tcp_opt *optp, const u_char *opd,
+dissect_tcpopt_timestamp(const ip_tcp_opt *optp, tvbuff_t *tvb,
     int offset, guint optlen, proto_tree *opt_tree)
 {
-  proto_tree_add_text(opt_tree, NullTVB, offset,      optlen,
-    "%s: tsval %u, tsecr %u", optp->name, pntohl(opd), pntohl(opd + 4));
-  tcp_info_append_uint("TSV", pntohl(opd));
-  tcp_info_append_uint("TSER", pntohl(opd + 4));
+  guint32 tsv, tser;
+
+  tsv = tvb_get_ntohl(tvb, offset + 2);
+  tser = tvb_get_ntohl(tvb, offset + 6);
+  proto_tree_add_text(opt_tree, tvb, offset,      optlen,
+    "%s: tsval %u, tsecr %u", optp->name, tsv, tser);
+  tcp_info_append_uint("TSV", tsv);
+  tcp_info_append_uint("TSER", tser);
 }
 
 static void
-dissect_tcpopt_cc(const ip_tcp_opt *optp, const u_char *opd,
+dissect_tcpopt_cc(const ip_tcp_opt *optp, tvbuff_t *tvb,
     int offset, guint optlen, proto_tree *opt_tree)
 {
-  proto_tree_add_text(opt_tree, NullTVB, offset,      optlen,
-                       "%s: %u", optp->name, pntohl(opd));
-  tcp_info_append_uint("CC", pntohl(opd));
+  guint32 cc;
+
+  cc = tvb_get_ntohl(tvb, offset + 2);
+  proto_tree_add_text(opt_tree, tvb, offset,      optlen,
+                       "%s: %u", optp->name, cc);
+  tcp_info_append_uint("CC", cc);
 }
 
 static const ip_tcp_opt tcpopts[] = {
@@ -363,14 +376,20 @@ static const true_false_string flags_set_truth = {
 /* can call to it, ie. socks   */
 
 void
-decode_tcp_ports(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
-       int src_port, int dst_port)
+decode_tcp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
+       proto_tree *tree, int src_port, int dst_port)
 {
+  tvbuff_t *next_tvb;
+  const u_char *next_pd;
+  int next_offset;
+
+  next_tvb = tvb_new_subset(tvb, offset, -1, -1);
+
 /* determine if this packet is part of a conversation and call dissector */
 /* for the conversation if available */
 
-  if (old_try_conversation_dissector(&pi.src, &pi.dst, PT_TCP,
-               src_port, dst_port, pd, offset, fd, tree))
+  if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_TCP,
+               src_port, dst_port, next_tvb, pinfo, tree))
        return;
 
   /* try to apply the plugins */
@@ -379,10 +398,11 @@ decode_tcp_ports(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
     plugin *pt_plug = plugin_list;
 
     if (enabled_plugins_number > 0) {
+      tvb_compat(next_tvb, &next_pd, &next_offset);
       while (pt_plug) {
        if (pt_plug->enabled && strstr(pt_plug->protocol, "tcp") &&
-           tree && dfilter_apply(pt_plug->filter, tree, pd, fd->cap_len)) {
-         pt_plug->dissector(pd, offset, fd, tree);
+           tree && dfilter_apply(pt_plug->filter, tree, next_pd, pinfo->fd->cap_len)) {
+         pt_plug->dissector(next_pd, next_offset, pinfo->fd, tree);
          return;
        }
        pt_plug = pt_plug->next;
@@ -392,39 +412,42 @@ decode_tcp_ports(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
 #endif
 
   /* do lookup with the subdissector table */
-  if (old_dissector_try_port(subdissector_table, src_port, pd, offset, fd, tree) ||
-      old_dissector_try_port(subdissector_table, dst_port, pd, offset, fd, tree))
+  if (dissector_try_port(subdissector_table, src_port, next_tvb, pinfo, tree) ||
+      dissector_try_port(subdissector_table, dst_port, next_tvb, pinfo, tree))
     return;
 
   /* do lookup with the heuristic subdissector table */
-  if (old_dissector_try_heuristic(heur_subdissector_list, pd, offset, fd, tree))
+  if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree))
     return;
 
   /* Oh, well, we don't know this; dissect it as data. */
-  old_dissect_data(pd, offset, fd, tree);
+  dissect_data(next_tvb, 0, pinfo, tree);
 }
 
 
 static void
-dissect_tcp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
   e_tcphdr   th;
   proto_tree *tcp_tree = NULL, *field_tree = NULL;
   proto_item *ti, *tf;
+  int        offset = 0;
   gchar      flags[64] = "<None>";
   gchar     *fstr[] = {"FIN", "SYN", "RST", "PSH", "ACK", "URG", "ECN", "CWR" };
   gint       fpos = 0, i;
   guint      bpos;
   guint      hlen;
   guint      optlen;
-  guint      packet_max = pi.len;
   guint32    seglen;
   guint32    nxtseq;
+  guint      length_remaining;
+
+  CHECK_DISPLAY_AS_DATA(proto_tcp, tvb, pinfo, tree);
 
-  OLD_CHECK_DISPLAY_AS_DATA(proto_tcp, pd, offset, fd, tree);
+  pinfo->current_proto = "TCP";
 
-  /* To do: Check for {cap len,pkt len} < struct len */
   /* Avoids alignment problems on many architectures. */
-  memcpy(&th, &pd[offset], sizeof(e_tcphdr));
+  tvb_memcpy(tvb, (guint8 *)&th, offset, sizeof(e_tcphdr));
   th.th_sport = ntohs(th.th_sport);
   th.th_dport = ntohs(th.th_dport);
   th.th_win   = ntohs(th.th_win);
@@ -439,7 +462,7 @@ dissect_tcp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
  
   info_len = 0;
 
-  if (check_col(fd, COL_INFO) || tree) {  
+  if (check_col(pinfo->fd, COL_INFO) || tree) {  
     for (i = 0; i < 8; i++) {
       bpos = 1 << i;
       if (th.th_flags & bpos) {
@@ -457,14 +480,14 @@ dissect_tcp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
   hlen = hi_nibble(th.th_off_x2) * 4;  /* TCP header length, in bytes */
 
   /* Compute the length of data in this segment. */
-  seglen = pi.len - (offset + hlen);
+  seglen = tvb_reported_length(tvb) - hlen;
 
   /* Compute the sequence number of next octet after this segment. */
   nxtseq = th.th_seq + seglen;
 
-  if (check_col(fd, COL_PROTOCOL))
-    col_add_str(fd, COL_PROTOCOL, "TCP");
-  if (check_col(fd, COL_INFO)) {
+  if (check_col(pinfo->fd, COL_PROTOCOL))
+    col_add_str(pinfo->fd, COL_PROTOCOL, "TCP");
+  if (check_col(pinfo->fd, COL_INFO)) {
     /* Copy the data into info_str in case one of the option handling
        routines needs to append to it. */
     if (th.th_flags & TH_URG)
@@ -480,40 +503,40 @@ dissect_tcp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
   
   if (tree) {
     if (g_tcp_summary_in_tree) {
-           ti = proto_tree_add_protocol_format(tree, proto_tcp, NullTVB, offset, hlen, "Transmission Control Protocol, Src Port: %s (%u), Dst Port: %s (%u), Seq: %u, Ack: %u", get_tcp_port(th.th_sport), th.th_sport, get_tcp_port(th.th_dport), th.th_dport, th.th_seq, th.th_ack);
+           ti = proto_tree_add_protocol_format(tree, proto_tcp, tvb, offset, hlen, "Transmission Control Protocol, Src Port: %s (%u), Dst Port: %s (%u), Seq: %u, Ack: %u", get_tcp_port(th.th_sport), th.th_sport, get_tcp_port(th.th_dport), th.th_dport, th.th_seq, th.th_ack);
     }
     else {
-           ti = proto_tree_add_item(tree, proto_tcp, NullTVB, offset, hlen, FALSE);
+           ti = proto_tree_add_item(tree, proto_tcp, tvb, offset, hlen, FALSE);
     }
     tcp_tree = proto_item_add_subtree(ti, ett_tcp);
-    proto_tree_add_uint_format(tcp_tree, hf_tcp_srcport, NullTVB, offset, 2, th.th_sport,
+    proto_tree_add_uint_format(tcp_tree, hf_tcp_srcport, tvb, offset, 2, th.th_sport,
        "Source port: %s (%u)", get_tcp_port(th.th_sport), th.th_sport);
-    proto_tree_add_uint_format(tcp_tree, hf_tcp_dstport, NullTVB, offset + 2, 2, th.th_dport,
+    proto_tree_add_uint_format(tcp_tree, hf_tcp_dstport, tvb, offset + 2, 2, th.th_dport,
        "Destination port: %s (%u)", get_tcp_port(th.th_dport), th.th_dport);
-    proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, NullTVB, offset, 2, th.th_sport);
-    proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, NullTVB, offset + 2, 2, th.th_dport);
-    proto_tree_add_uint(tcp_tree, hf_tcp_seq, NullTVB, offset + 4, 4, th.th_seq);
+    proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset, 2, th.th_sport);
+    proto_tree_add_uint_hidden(tcp_tree, hf_tcp_port, tvb, offset + 2, 2, th.th_dport);
+    proto_tree_add_uint(tcp_tree, hf_tcp_seq, tvb, offset + 4, 4, th.th_seq);
     if (nxtseq != th.th_seq)
-      proto_tree_add_uint(tcp_tree, hf_tcp_nxtseq, NullTVB, offset, 0, nxtseq);
+      proto_tree_add_uint(tcp_tree, hf_tcp_nxtseq, tvb, offset, 0, nxtseq);
     if (th.th_flags & TH_ACK)
-      proto_tree_add_uint(tcp_tree, hf_tcp_ack, NullTVB, offset + 8, 4, th.th_ack);
-    proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, NullTVB, offset + 12, 1, hlen,
+      proto_tree_add_uint(tcp_tree, hf_tcp_ack, tvb, offset + 8, 4, th.th_ack);
+    proto_tree_add_uint_format(tcp_tree, hf_tcp_hdr_len, tvb, offset + 12, 1, hlen,
        "Header length: %u bytes", hlen);
-    tf = proto_tree_add_uint_format(tcp_tree, hf_tcp_flags, NullTVB, offset + 13, 1,
+    tf = proto_tree_add_uint_format(tcp_tree, hf_tcp_flags, tvb, offset + 13, 1,
        th.th_flags, "Flags: 0x%04x (%s)", th.th_flags, flags);
     field_tree = proto_item_add_subtree(tf, ett_tcp_flags);
-    proto_tree_add_boolean(field_tree, hf_tcp_flags_cwr, NullTVB, offset + 13, 1, th.th_flags);
-    proto_tree_add_boolean(field_tree, hf_tcp_flags_ecn, NullTVB, offset + 13, 1, th.th_flags);
-    proto_tree_add_boolean(field_tree, hf_tcp_flags_urg, NullTVB, offset + 13, 1, th.th_flags);
-    proto_tree_add_boolean(field_tree, hf_tcp_flags_ack, NullTVB, offset + 13, 1, th.th_flags);
-    proto_tree_add_boolean(field_tree, hf_tcp_flags_push, NullTVB, offset + 13, 1, th.th_flags);
-    proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, NullTVB, offset + 13, 1, th.th_flags);
-    proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, NullTVB, offset + 13, 1, th.th_flags);
-    proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, NullTVB, offset + 13, 1, th.th_flags);
-    proto_tree_add_uint(tcp_tree, hf_tcp_window_size, NullTVB, offset + 14, 2, th.th_win);
-    proto_tree_add_uint(tcp_tree, hf_tcp_checksum, NullTVB, offset + 16, 2, th.th_sum);
+    proto_tree_add_boolean(field_tree, hf_tcp_flags_cwr, tvb, offset + 13, 1, th.th_flags);
+    proto_tree_add_boolean(field_tree, hf_tcp_flags_ecn, tvb, offset + 13, 1, th.th_flags);
+    proto_tree_add_boolean(field_tree, hf_tcp_flags_urg, tvb, offset + 13, 1, th.th_flags);
+    proto_tree_add_boolean(field_tree, hf_tcp_flags_ack, tvb, offset + 13, 1, th.th_flags);
+    proto_tree_add_boolean(field_tree, hf_tcp_flags_push, tvb, offset + 13, 1, th.th_flags);
+    proto_tree_add_boolean(field_tree, hf_tcp_flags_reset, tvb, offset + 13, 1, th.th_flags);
+    proto_tree_add_boolean(field_tree, hf_tcp_flags_syn, tvb, offset + 13, 1, th.th_flags);
+    proto_tree_add_boolean(field_tree, hf_tcp_flags_fin, tvb, offset + 13, 1, th.th_flags);
+    proto_tree_add_uint(tcp_tree, hf_tcp_window_size, tvb, offset + 14, 2, th.th_win);
+    proto_tree_add_uint(tcp_tree, hf_tcp_checksum, tvb, offset + 16, 2, th.th_sum);
     if (th.th_flags & TH_URG)
-      proto_tree_add_uint(tcp_tree, hf_tcp_urgent_pointer, NullTVB, offset + 18, 2, th.th_urp);
+      proto_tree_add_uint(tcp_tree, hf_tcp_urgent_pointer, tvb, offset + 18, 2, th.th_urp);
   }
 
   /* Decode TCP options, if any. */
@@ -521,26 +544,27 @@ dissect_tcp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
     /* There's more than just the fixed-length header.  Decode the
        options. */
     optlen = hlen - sizeof (e_tcphdr); /* length of options, in bytes */
-    tf = proto_tree_add_text(tcp_tree, NullTVB, offset +  20, optlen,
+    tf = proto_tree_add_text(tcp_tree, tvb, offset +  20, optlen,
       "Options: (%d bytes)", optlen);
     field_tree = proto_item_add_subtree(tf, ett_tcp_options);
-    dissect_ip_tcp_options(&pd[offset + 20], offset + 20, optlen,
+    dissect_ip_tcp_options(tvb, offset + 20, optlen,
       tcpopts, N_TCP_OPTS, TCPOPT_EOL, field_tree);
   }
 
-  if (check_col(fd, COL_INFO))
-    col_add_str(fd, COL_INFO, info_str);
+  if (check_col(pinfo->fd, COL_INFO))
+    col_add_str(pinfo->fd, COL_INFO, info_str);
 
   /* Skip over header + options */
   offset += hlen;
 
-  pi.ptype = PT_TCP;
-  pi.srcport = th.th_sport;
-  pi.destport = th.th_dport;
+  pinfo->ptype = PT_TCP;
+  pinfo->srcport = th.th_sport;
+  pinfo->destport = th.th_dport;
   
   /* Check the packet length to see if there's more data
      (it could be an ACK-only packet) */
-  if (packet_max > offset) {
+  length_remaining = tvb_length_remaining(tvb, offset);
+  if (length_remaining != 0) {
     if (th.th_flags & TH_RST) {
       /*
        * RFC1122 says:
@@ -557,23 +581,23 @@ dissect_tcp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
        *
        * so for segments with RST we just display the data as text.
        */
-      proto_tree_add_text(tcp_tree, NullTVB, offset, END_OF_FRAME,
+      proto_tree_add_text(tcp_tree, tvb, offset, length_remaining,
                            "Reset cause: %s",
-                           format_text(&pd[offset], END_OF_FRAME));
+                           tvb_format_text(tvb, offset, length_remaining));
     } else
-      decode_tcp_ports( pd, offset, fd, tree, th.th_sport, th.th_dport);
+      decode_tcp_ports( tvb, offset, pinfo, tree, th.th_sport, th.th_dport);
   }
  
   if( data_out_file ) {
     reassemble_tcp( th.th_seq,         /* sequence number */
         seglen,                                /* data length */
-        ( pd+offset ),                 /* data */
-        ( pi.captured_len - offset ),  /* captured data length */
+        tvb_get_ptr(tvb, offset, length_remaining),    /* data */
+        length_remaining,              /* captured data length */
         ( th.th_flags & TH_SYN ),      /* is syn set? */
-        &pi.net_src,
-       &pi.net_dst,
-       pi.srcport,
-       pi.destport);
+        &pinfo->net_src,
+       &pinfo->net_dst,
+       pinfo->srcport,
+       pinfo->destport);
   }
 }
 
@@ -685,5 +709,5 @@ proto_register_tcp(void)
 void
 proto_reg_handoff_tcp(void)
 {
-       old_dissector_add("ip.proto", IP_PROTO_TCP, dissect_tcp);
+       dissector_add("ip.proto", IP_PROTO_TCP, dissect_tcp);
 }
index 69045dead612bfeb050cc4352cccad2f40cbe52e..6cdba3dfe8f28796b5c7fc0f6cb1a5e1617e13e0 100644 (file)
@@ -1,6 +1,6 @@
 /* packet-tcp.h
  *
- * $Id: packet-tcp.h,v 1.5 2000/08/11 13:33:59 deniel Exp $
+ * $Id: packet-tcp.h,v 1.6 2000/11/18 10:38:25 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -28,7 +28,7 @@
 /* Urgent pointer value for the current packet. */
 extern guint16   tcp_urgent_pointer;
 
-extern void decode_tcp_ports(const u_char *, int, frame_data *,
+extern void decode_tcp_ports(tvbuff_t *, int, packet_info *,
        proto_tree *, int, int);
 
 #endif
index 2ccf2f175c423a56291f58f7f57611ca6971100f..cd39e75914953d3711500fea4ad97b0f2dd88221 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-udp.c
  * Routines for UDP packet disassembly
  *
- * $Id: packet-udp.c,v 1.77 2000/11/05 09:26:47 oabad Exp $
+ * $Id: packet-udp.c,v 1.78 2000/11/18 10:38:25 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -82,14 +82,20 @@ static heur_dissector_list_t heur_subdissector_list;
 /* can call to it, ie. socks   */
 
 void
-decode_udp_ports(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
-       int uh_sport, int uh_dport)
+decode_udp_ports(tvbuff_t *tvb, int offset, packet_info *pinfo,
+       proto_tree *tree, int uh_sport, int uh_dport)
 {
+  tvbuff_t *next_tvb;
+  const u_char *next_pd;
+  int next_offset;
+
+  next_tvb = tvb_new_subset(tvb, offset, -1, -1);
+
 /* determine if this packet is part of a conversation and call dissector */
 /* for the conversation if available */
 
-  if (old_try_conversation_dissector(&pi.src, &pi.dst, PT_UDP,
-               uh_sport, uh_dport, pd, offset, fd, tree))
+  if (try_conversation_dissector(&pinfo->src, &pinfo->dst, PT_UDP,
+               uh_sport, uh_dport, next_tvb, pinfo, tree))
        return;
 
   /* try to apply the plugins */
@@ -98,10 +104,11 @@ decode_udp_ports(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
       plugin *pt_plug = plugin_list;
 
       if (enabled_plugins_number > 0) {
+         tvb_compat(next_tvb, &next_pd, &next_offset);
          while (pt_plug) {
              if (pt_plug->enabled && strstr(pt_plug->protocol, "udp") &&
-                 tree && dfilter_apply(pt_plug->filter, tree, pd, fd->cap_len)) {
-                 pt_plug->dissector(pd, offset, fd, tree);
+                 tree && dfilter_apply(pt_plug->filter, tree, next_pd, pinfo->fd->cap_len)) {
+                 pt_plug->dissector(next_pd, next_offset, pinfo->fd, tree);
                  return;
              }
              pt_plug = pt_plug->next;
@@ -111,77 +118,77 @@ decode_udp_ports(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
 #endif
 
   /* do lookup with the subdissector table */
-  if (old_dissector_try_port(udp_dissector_table, uh_sport, pd, offset, fd, tree) ||
-      old_dissector_try_port(udp_dissector_table, uh_dport, pd, offset, fd, tree))
+  if (dissector_try_port(udp_dissector_table, uh_sport, next_tvb, pinfo, tree) ||
+      dissector_try_port(udp_dissector_table, uh_dport, next_tvb, pinfo, tree))
     return;
 
   /* do lookup with the heuristic subdissector table */
-  if (old_dissector_try_heuristic(heur_subdissector_list, pd, offset, fd, tree))
+  if (dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree))
     return;
 
   /* XXX - we should do these with the subdissector table as well. */
 #define PORT_IS(port)  (uh_sport == port || uh_dport == port)
   if (PORT_IS(UDP_PORT_VINES)) {
     /* FIXME: AFAIK, src and dst port must be the same */
-    dissect_vines_frp(pd, offset, fd, tree);
+    tvb_compat(next_tvb, &next_pd, &next_offset);
+    dissect_vines_frp(next_pd, next_offset, pinfo->fd, tree);
   } else
-    old_dissect_data(pd, offset, fd, tree);
+    dissect_data(next_tvb, 0, pinfo, tree);
 }
 
 
 static void
-dissect_udp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
+dissect_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
   e_udphdr  uh;
   guint16    uh_sport, uh_dport, uh_ulen, uh_sum;
   proto_tree *udp_tree;
   proto_item *ti;
+  int        offset = 0;
 
-  OLD_CHECK_DISPLAY_AS_DATA(proto_udp, pd, offset, fd, tree);
+  CHECK_DISPLAY_AS_DATA(proto_udp, tvb, pinfo, tree);
 
-  if (!BYTES_ARE_IN_FRAME(offset, sizeof(e_udphdr))) {
-    old_dissect_data(pd, offset, fd, tree);
-    return;
-  }
+  pinfo->current_proto = "UDP";
 
   /* Avoids alignment problems on many architectures. */
-  memcpy(&uh, &pd[offset], sizeof(e_udphdr));
+  tvb_memcpy(tvb, (guint8 *)&uh, offset, sizeof(e_udphdr));
   uh_sport = ntohs(uh.uh_sport);
   uh_dport = ntohs(uh.uh_dport);
   uh_ulen  = ntohs(uh.uh_ulen);
   uh_sum   = ntohs(uh.uh_sum);
   
-  if (check_col(fd, COL_PROTOCOL))
-    col_add_str(fd, COL_PROTOCOL, "UDP");
-  if (check_col(fd, COL_INFO))
-    col_add_fstr(fd, COL_INFO, "Source port: %s  Destination port: %s",
+  if (check_col(pinfo->fd, COL_PROTOCOL))
+    col_add_str(pinfo->fd, COL_PROTOCOL, "UDP");
+  if (check_col(pinfo->fd, COL_INFO))
+    col_add_fstr(pinfo->fd, COL_INFO, "Source port: %s  Destination port: %s",
            get_udp_port(uh_sport), get_udp_port(uh_dport));
     
   if (tree) {
-    ti = proto_tree_add_item(tree, proto_udp, NullTVB, offset, 8, FALSE);
+    ti = proto_tree_add_item(tree, proto_udp, tvb, offset, 8, FALSE);
     udp_tree = proto_item_add_subtree(ti, ett_udp);
 
-    proto_tree_add_uint_format(udp_tree, hf_udp_srcport, NullTVB, offset, 2, uh_sport,
+    proto_tree_add_uint_format(udp_tree, hf_udp_srcport, tvb, offset, 2, uh_sport,
        "Source port: %s (%u)", get_udp_port(uh_sport), uh_sport);
-    proto_tree_add_uint_format(udp_tree, hf_udp_dstport, NullTVB, offset + 2, 2, uh_dport,
+    proto_tree_add_uint_format(udp_tree, hf_udp_dstport, tvb, offset + 2, 2, uh_dport,
        "Destination port: %s (%u)", get_udp_port(uh_dport), uh_dport);
 
-    proto_tree_add_uint_hidden(udp_tree, hf_udp_port, NullTVB, offset, 2, uh_sport);
-    proto_tree_add_uint_hidden(udp_tree, hf_udp_port, NullTVB, offset+2, 2, uh_dport);
+    proto_tree_add_uint_hidden(udp_tree, hf_udp_port, tvb, offset, 2, uh_sport);
+    proto_tree_add_uint_hidden(udp_tree, hf_udp_port, tvb, offset+2, 2, uh_dport);
 
-    proto_tree_add_uint(udp_tree, hf_udp_length, NullTVB, offset + 4, 2,  uh_ulen);
-    proto_tree_add_uint_format(udp_tree, hf_udp_checksum, NullTVB, offset + 6, 2, uh_sum,
+    proto_tree_add_uint(udp_tree, hf_udp_length, tvb, offset + 4, 2,  uh_ulen);
+    proto_tree_add_uint_format(udp_tree, hf_udp_checksum, tvb, offset + 6, 2, uh_sum,
        "Checksum: 0x%04x", uh_sum);
   }
 
   /* Skip over header */
   offset += 8;
 
-  pi.ptype = PT_UDP;
-  pi.srcport = uh_sport;
-  pi.destport = uh_dport;
+  pinfo->ptype = PT_UDP;
+  pinfo->srcport = uh_sport;
+  pinfo->destport = uh_dport;
 
 /* call sub-dissectors */
-  decode_udp_ports( pd, offset, fd, tree, uh_sport, uh_dport);
+  decode_udp_ports( tvb, offset, pinfo, tree, uh_sport, uh_dport);
 
 }
 
@@ -225,5 +232,5 @@ proto_register_udp(void)
 void
 proto_reg_handoff_udp(void)
 {
-       old_dissector_add("ip.proto", IP_PROTO_UDP, dissect_udp);
+       dissector_add("ip.proto", IP_PROTO_UDP, dissect_udp);
 }
index 9521d4a0fcaaa0da42fb82c209842494531da5cc..c8192690e3e6d942134bb47ab0ef3d69c6520969 100644 (file)
@@ -1,6 +1,6 @@
 /* packet-udp.h
  *
- * $Id: packet-udp.h,v 1.4 2000/08/11 13:33:58 deniel Exp $
+ * $Id: packet-udp.h,v 1.5 2000/11/18 10:38:25 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -25,7 +25,7 @@
 #ifndef __PACKET_UDP_H__
 #define __PACKET_UDP_H__
 
-extern void decode_udp_ports(const u_char *, int, frame_data *,
+extern void decode_udp_ports(tvbuff_t *, int, packet_info *,
        proto_tree *, int, int);
 
 #endif
index adcbfdb96d542ef914c1afd591d5eabb1ad463cd..c0ffdcff7bf853ff6a9c5a519ea6cdf1ac892d6a 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-vlan.c
  * Routines for VLAN 802.1Q ethernet header disassembly
  *
- * $Id: packet-vlan.c,v 1.23 2000/11/13 05:22:58 guy Exp $
+ * $Id: packet-vlan.c,v 1.24 2000/11/18 10:38:25 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -79,6 +79,7 @@ dissect_vlan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
   tvbuff_t *volatile next_tvb;
   tvbuff_t *volatile trailer_tvb;
   proto_tree *volatile vlan_tree;
+  guint        length_before, length;
 
   CHECK_DISPLAY_AS_DATA(proto_vlan, tvb, pinfo, tree);
 
@@ -107,7 +108,7 @@ dissect_vlan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
   }
 
   if ( encap_proto <= IEEE_802_3_MAX_LEN) {
-    /* Give the next dissector only 'length' number of bytes */
+    /* Give the next dissector only 'encap_proto' number of bytes */
     proto_tree_add_uint(vlan_tree, hf_vlan_len, tvb, 2, 2, encap_proto);
     TRY {
        next_tvb = tvb_new_subset(tvb, 4, encap_proto, encap_proto);
@@ -160,21 +161,40 @@ dissect_vlan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     } else {
       dissect_ipx(next_tvb, pinfo, tree);
     }
+  } else {
+    length_before = tvb_reported_length(tvb);
+    length = ethertype(encap_proto, tvb, 4, pinfo, tree, vlan_tree,
+                      hf_vlan_etype) + 4;
+    if (length < length_before) {
+      /*
+       * Create a tvbuff for the padding.
+       */
+      TRY {
+       trailer_tvb = tvb_new_subset(tvb, length, -1, -1);
+      }
+      CATCH2(BoundsError, ReportedBoundsError) {
+       /* The packet doesn't have "length" bytes worth of captured
+          data left in it.  No trailer to display. */
+       trailer_tvb = NULL;
+      }
+      ENDTRY;
+    } else {
+      /* No padding. */
+      trailer_tvb = NULL;
+    }
+  }
 
-    /* If there's some bytes left over, mark them. */
-    if (trailer_tvb && tree) {
-      int trailer_length;
-      const guint8    *ptr;
+  /* If there's some bytes left over, mark them. */
+  if (trailer_tvb && tree) {
+    int trailer_length;
+    const guint8    *ptr;
 
-      trailer_length = tvb_length(trailer_tvb);
-      if (trailer_length > 0) {
-        ptr = tvb_get_ptr(trailer_tvb, 0, trailer_length);
-       proto_tree_add_bytes(vlan_tree, hf_vlan_trailer, tvb, 4 + encap_proto,
-                         trailer_length, ptr);
-      }
+    trailer_length = tvb_length(trailer_tvb);
+    if (trailer_length > 0) {
+      ptr = tvb_get_ptr(trailer_tvb, 0, trailer_length);
+      proto_tree_add_bytes(vlan_tree, hf_vlan_trailer, trailer_tvb, 0,
+                          trailer_length, ptr);
     }
-  } else {
-    ethertype(encap_proto, tvb, 4, pinfo, tree, vlan_tree, hf_vlan_etype);
   }
 }
 
index 5cfee0201a7a79271044a0d4d522dd69b45a09d8..694a830393b4018aff7fd676eec5313aa041beec 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for x25 packet disassembly
  * Olivier Abad <oabad@cybercable.fr>
  *
- * $Id: packet-x25.c,v 1.36 2000/11/16 07:35:38 guy Exp $
+ * $Id: packet-x25.c,v 1.37 2000/11/18 10:38:26 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -173,7 +173,7 @@ static const value_string vals_x25_type[] = {
 typedef struct _vc_info {
        guint32 first_frame_secs, first_frame_usecs;
        guint32 last_frame_secs, last_frame_usecs;
-       void (*dissect)(const u_char *, int, frame_data *, proto_tree *);
+       dissector_t dissect;
        struct _vc_info *next;
 } vc_info;
 
@@ -191,7 +191,7 @@ typedef struct _global_vc_info {
 
 static global_vc_info *hash_table[64];
 
-void
+static void
 free_vc_info(vc_info *pt)
 {
   vc_info *vci = pt;
@@ -225,10 +225,9 @@ reinit_x25_hashtable(void)
   }
 }
 
-void
+static void
 x25_hash_add_proto_start(guint16 vc, guint32 frame_secs, guint32 frame_usecs,
-                        void (*dissect)(const u_char *, int, frame_data *,
-                                      proto_tree *))
+                        dissector_t dissect)
 {
   int idx = vc % 64;
   global_vc_info *hash_ent;
@@ -308,7 +307,7 @@ x25_hash_add_proto_start(guint16 vc, guint32 frame_secs, guint32 frame_usecs,
   }
 }
 
-void
+static void
 x25_hash_add_proto_end(guint16 vc, guint32 frame_secs, guint32 frame_usecs)
 {
   global_vc_info *hash_ent = hash_table[vc%64];
@@ -324,7 +323,8 @@ x25_hash_add_proto_end(guint16 vc, guint32 frame_secs, guint32 frame_usecs)
   vci->last_frame_usecs = frame_usecs;
 }
 
-void (*x25_hash_get_dissect(guint32 frame_secs, guint32 frame_usecs, guint16 vc))(const u_char *, int, frame_data *, proto_tree *)
+static dissector_t
+x25_hash_get_dissect(guint32 frame_secs, guint32 frame_usecs, guint16 vc)
 {
   global_vc_info *hash_ent = hash_table[vc%64];
   vc_info *vci;
@@ -621,7 +621,7 @@ static char *registration_code(unsigned char code)
     return buffer;
 }
 
-void
+static void
 dump_facilities(proto_tree *tree, int *offset, tvbuff_t *tvb)
 {
     guint8 fac, byte1, byte2, byte3;
@@ -1200,7 +1200,7 @@ dump_facilities(proto_tree *tree, int *offset, tvbuff_t *tvb)
     }
 }
 
-void
+static void
 x25_ntoa(proto_tree *tree, int *offset, tvbuff_t *tvb,
         frame_data *fd, gboolean toa)
 {
@@ -1289,7 +1289,7 @@ x25_ntoa(proto_tree *tree, int *offset, tvbuff_t *tvb,
     (*offset) += ((len1 + len2 + 1) / 2);
 }
 
-int
+static int
 get_x25_pkt_len(tvbuff_t *tvb)
 {
     int length, called_len, calling_len, dte_len, dce_len;
@@ -1394,13 +1394,11 @@ dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     int x25_pkt_len;
     int modulo;
     guint16 vc;
-    void (*dissect)(const u_char *, int, frame_data *, proto_tree *);
+    dissector_t dissect;
     gboolean toa;         /* TOA/NPI address format */
     guint16 bytes0_1;
     guint8 pkt_type;
     tvbuff_t *next_tvb;
-    const guint8 *next_pd;
-    int next_offset;
 
     pinfo->current_proto = "X.25";
 
@@ -1921,16 +1919,15 @@ dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     if (localoffset >= tvb_reported_length(tvb)) return;
 
     next_tvb = tvb_new_subset(tvb, localoffset, -1, -1);
-    tvb_compat(next_tvb, &next_pd, &next_offset);
     /* search the dissector in the hash table */
     if ((dissect = x25_hash_get_dissect(pinfo->fd->abs_secs, pinfo->fd->abs_usecs, vc)))
-       (*dissect)(next_pd, next_offset, pinfo->fd, tree);
+       (*dissect)(next_tvb, pinfo, tree);
     else {
        /* If the Call Req. has not been captured, assume these packets carry IP */
        if (tvb_get_guint8(tvb, localoffset) == 0x45) {
            x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
                    pinfo->fd->abs_usecs, dissect_ip);
-           dissect_ip(next_pd, next_offset, pinfo->fd, tree);
+           dissect_ip(next_tvb, pinfo, tree);
        }
        else {
            dissect_data(next_tvb, 0, pinfo, tree);