Tvbuffify the ASN.1 code and the Kerberos, LDAP, and SNMP dissectors.
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Sun, 15 Apr 2001 07:30:03 +0000 (07:30 +0000)
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>
Sun, 15 Apr 2001 07:30:03 +0000 (07:30 +0000)
Clean up some problems that revealed.

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

asn1.c
asn1.h
packet-atm.c
packet-kerberos.c
packet-ldap.c
packet-snmp.c
packet-snmp.h

diff --git a/asn1.c b/asn1.c
index fbec5445e327c464427cdddc3d0a49469c3f3313..f9696d1853c5456eb48335ee35feeba85648aafe 100644 (file)
--- a/asn1.c
+++ b/asn1.c
@@ -1,7 +1,7 @@
 /* asn1.c
  * Routines for ASN.1 BER dissection
  *
- * $Id: asn1.c,v 1.6 2000/12/24 09:10:11 guy Exp $
+ * $Id: asn1.c,v 1.7 2001/04/15 07:30:02 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
  *
  *              To decode this we must do:
  *
- *              asn1_open (asn1, buf_start, buf_len);
+ *              asn1_open (asn1, tvb, offset);
  *              asn1_header_decode (asn1, &end_of_seq, cls, con, tag, def, len);
  *              asn1_header_decode (asn1, &end_of_octs, cls, con, tag, def, len);
  *              asn1_octets_decode (asn1, end_of_octs, str, len);
  *              asn1_header_decode (asn1, &end_of_int, cls, con, tag);
  *              asn1_int_decode (asn1, end_of_int, &integer);
  *              asn1_eoc_decode (asn1, end_of_seq);
- *              asn1_close (asn1, &buf_start, &buf_len);
+ *              asn1_close (asn1, &offset);
  *              
  *              For indefinite encoding end_of_seq and &end_of_seq in the
  *              example above should be replaced by NULL.
 #endif
 
 #include <glib.h>
+#include "tvbuff.h"
 #include "asn1.h"
 
 /*
  * NAME:        asn1_open                                   [API]
  * SYNOPSIS:    void asn1_open
  *                  (
- *                      ASN1_SCK     *asn1,
- *                      const guchar *buf,
- *                      guint        len,
+ *                      ASN1_SCK *asn1,
+ *                      tvbuff_t *tvb,
+ *                      int       offset
  *                  )
  * DESCRIPTION: Opens an ASN1 socket.
  *              Parameters:
- *              asn1: pointer to ASN1 socket.
- *              buf:  Character buffer for encoding.
- *              len:  Length of character buffer.
+ *              asn1:   pointer to ASN1 socket.
+ *              tvb:    Tvbuff for encoding.
+ *              offset: Current offset in tvbuff.
  *              Encoding starts at the end of the buffer, and
  *              proceeds to the beginning.
  * RETURNS:     void
  */
 
 void
-asn1_open(ASN1_SCK *asn1, const guchar *buf, guint len)
+asn1_open(ASN1_SCK *asn1, tvbuff_t *tvb, int offset)
 {
-    asn1->begin = buf;
-    asn1->end = buf + len;
-    asn1->pointer = buf;
+    asn1->tvb = tvb;
+    asn1->offset = offset;
 }
 
 /*
@@ -103,22 +103,20 @@ asn1_open(ASN1_SCK *asn1, const guchar *buf, guint len)
  * SYNOPSIS:    void asn1_close
  *                  (
  *                      ASN1_SCK   *asn1,
- *                      guchar    **buf,
- *                      guint      *len
+ *                      int        *offset
  *                  )
  * DESCRIPTION: Closes an ASN1 socket.
  *              Parameters:
- *              asn1: pointer to ASN1 socket.
- *              buf: pointer to beginning of encoding.
- *              len: Length of encoding.
+ *              asn1:   pointer to ASN1 socket.
+ *              offset: pointer to variable into which current offset is
+ *              to be put.
  * RETURNS:     void
  */
 
 void 
-asn1_close(ASN1_SCK *asn1, const guchar **buf, guint *len)
+asn1_close(ASN1_SCK *asn1, int *offset)
 {
-    *buf   = asn1->pointer;
-    *len   = asn1->end - asn1->pointer;
+    *offset = asn1->offset;
 }
 
 /*
@@ -134,9 +132,8 @@ asn1_close(ASN1_SCK *asn1, const guchar **buf, guint *len)
 int
 asn1_octet_decode(ASN1_SCK *asn1, guchar *ch)
 {
-    if (asn1->pointer >= asn1->end)
-       return ASN1_ERR_EMPTY;
-    *ch = *(asn1->pointer)++;
+    *ch = tvb_get_guint8(asn1->tvb, asn1->offset);
+    asn1->offset++;
     return ASN1_ERR_NOERROR;
 }
 
@@ -291,22 +288,22 @@ asn1_header_decode(ASN1_SCK *asn1, guint *cls, guint *con, guint *tag,
  * SYNOPSIS:    gboolean asn1_eoc
  *                  (
  *                      ASN1_SCK *asn1,
- *                      guchar   *eoc
+ *                      int       eoc
  *                  )
  * DESCRIPTION: Checks if decoding is at End Of Contents.
  *              Parameters:
  *              asn1: pointer to ASN1 socket.
- *              eoc: pointer to end of encoding or 0 if
- *                   indefinite.
+ *              eoc: offset of end of encoding, or -1 if indefinite.
  * RETURNS:     gboolean success
  */
 gboolean
-asn1_eoc ( ASN1_SCK *asn1, const guchar *eoc)
+asn1_eoc ( ASN1_SCK *asn1, int eoc)
 {
-    if (eoc == 0)
-        return (asn1->pointer [0] == 0x00 && asn1->pointer [1] == 0x00);
+    if (eoc == -1)
+        return (tvb_get_guint8(asn1->tvb, asn1->offset) == 0x00
+               && tvb_get_guint8(asn1->tvb, asn1->offset + 1) == 0x00);
     else
-        return (asn1->pointer >= eoc);
+        return (asn1->offset >= eoc);
 }
 
 /*
@@ -314,31 +311,29 @@ asn1_eoc ( ASN1_SCK *asn1, const guchar *eoc)
  * SYNOPSIS:    int asn1_eoc_decode
  *                  (
  *                      ASN1_SCK  *asn1,
- *                      guchar    *eoc
+ *                      int       eoc
  *                  )
  * DESCRIPTION: Decodes End Of Contents.
  *              Parameters:
  *              asn1: pointer to ASN1 socket.
- *              eoc: pointer to end of encoding or 0 if
- *                   indefinite.
- *              If eoc is 0 it decodes an ASN1 End Of
+ *              eoc: offset of end of encoding, or -1 if indefinite.
+ *              If eoc is -1 it decodes an ASN1 End Of
  *              Contents (0x00 0x00), so it has to be an
- *              indefinite length encoding. If eoc is a
- *              character pointer, it probably was filled by
- *              asn1_header_decode, and should point to the octet
- *              after the last of the encoding. It is checked
- *              if this pointer points to the octet to be
+ *              indefinite length encoding. If eoc is a non-negative
+ *              integer, it probably was filled by asn1_header_decode,
+ *              and should refer to the octet after the last of the encoding.
+ *              It is checked if this offset refers to the octet to be
  *              decoded. This only takes place in decoding a
  *              definite length encoding.
  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
  */
 int
-asn1_eoc_decode (ASN1_SCK *asn1, const guchar *eoc)
+asn1_eoc_decode (ASN1_SCK *asn1, int eoc)
 {
     int    ret;
     guchar ch;
     
-    if (eoc == 0) {
+    if (eoc == -1) {
         ret = asn1_octet_decode (asn1, &ch);
         if (ret != ASN1_ERR_NOERROR)
            return ret;
@@ -351,7 +346,7 @@ asn1_eoc_decode (ASN1_SCK *asn1, const guchar *eoc)
        return ASN1_ERR_EOC_MISMATCH;
       return ASN1_ERR_NOERROR;
   } else {
-      if (asn1->pointer != eoc)
+      if (asn1->offset != eoc)
        return ASN1_ERR_LENGTH_MISMATCH;
       return ASN1_ERR_NOERROR;
     }
@@ -373,7 +368,7 @@ asn1_eoc_decode (ASN1_SCK *asn1, const guchar *eoc)
 int
 asn1_null_decode ( ASN1_SCK *asn1, int enc_len)
 {
-    asn1->pointer += enc_len;
+    asn1->offset += enc_len;
     return ASN1_ERR_NOERROR;
 }
 
@@ -427,17 +422,17 @@ int
 asn1_int32_value_decode ( ASN1_SCK *asn1, int enc_len, gint32 *integer)
 {
     int          ret;
-    const guchar *eoc;
+    int          eoc;
     guchar       ch;
     guint        len;
 
-    eoc = asn1->pointer + enc_len;
+    eoc = asn1->offset + enc_len;
     ret = asn1_octet_decode (asn1, &ch);
     if (ret != ASN1_ERR_NOERROR)
         return ret;
     *integer = (gint) ch;
     len = 1;
-    while (asn1->pointer < eoc) {
+    while (asn1->offset < eoc) {
         if (++len > sizeof (gint32))
            return ASN1_ERR_WRONG_LENGTH_FOR_TYPE;
         ret = asn1_octet_decode (asn1, &ch);
@@ -468,14 +463,14 @@ int
 asn1_int32_decode ( ASN1_SCK *asn1, gint32 *integer, guint *nbytes)
 {
     int          ret;
-    const guchar *start;
+    int          start;
     guint        cls;
     guint        con;
     guint        tag;
     gboolean     def;
     guint        enc_len;
 
-    start = asn1->pointer;
+    start = asn1->offset;
     ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
     if (ret != ASN1_ERR_NOERROR)
        goto done;
@@ -490,7 +485,7 @@ asn1_int32_decode ( ASN1_SCK *asn1, gint32 *integer, guint *nbytes)
     ret = asn1_int32_value_decode (asn1, enc_len, integer);
 
 done:
-    *nbytes = asn1->pointer - start;
+    *nbytes = asn1->offset - start;
     return ret;
 }
 
@@ -514,11 +509,11 @@ int
 asn1_uint32_value_decode ( ASN1_SCK *asn1, int enc_len, guint *integer)
 {
     int          ret;
-    const guchar *eoc;
+    int          eoc;
     guchar       ch;
     guint        len;
 
-    eoc = asn1->pointer + enc_len;
+    eoc = asn1->offset + enc_len;
     ret = asn1_octet_decode (asn1, &ch);
     if (ret != ASN1_ERR_NOERROR)
         return ret;
@@ -527,7 +522,7 @@ asn1_uint32_value_decode ( ASN1_SCK *asn1, int enc_len, guint *integer)
        len = 0;
     else
        len = 1;
-    while (asn1->pointer < eoc) {
+    while (asn1->offset < eoc) {
         if (++len > sizeof (guint32))
            return ASN1_ERR_WRONG_LENGTH_FOR_TYPE;
         ret = asn1_octet_decode (asn1, &ch);
@@ -558,14 +553,14 @@ int
 asn1_uint32_decode ( ASN1_SCK *asn1, guint32 *integer, guint *nbytes)
 {
     int          ret;
-    const guchar *start;
+    int          start;
     guint        cls;
     guint        con;
     guint        tag;
     gboolean     def;
     guint        enc_len;
 
-    start = asn1->pointer;
+    start = asn1->offset;
     ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
     if (ret != ASN1_ERR_NOERROR)
        goto done;
@@ -580,7 +575,7 @@ asn1_uint32_decode ( ASN1_SCK *asn1, guint32 *integer, guint *nbytes)
     ret = asn1_uint32_value_decode (asn1, enc_len, integer);
 
 done:
-    *nbytes = asn1->pointer - start;
+    *nbytes = asn1->offset - start;
     return ret;
 }
 
@@ -589,7 +584,7 @@ done:
  * SYNOPSIS:    int asn1_bits_decode
  *                  (
  *                      ASN1_SCK  *asn1,
- *                      guchar    *eoc,
+ *                      int        eoc,
  *                      guchar    *bits,
  *                      guint      size,
  *                      guint      len,
@@ -598,8 +593,7 @@ done:
  * DESCRIPTION: Decodes Bit String.
  *              Parameters:
  *              asn1:   pointer to ASN1 socket.
- *              eoc:    pointer to end of encoding or 0 if
- *                      indefinite.
+ *              eoc: offset of end of encoding, or -1 if indefinite.
  *              bits:   pointer to begin of Bit String.
  *              size:   Size of Bit String in characters.
  *              len:    Length of Bit String in characters.
@@ -607,7 +601,7 @@ done:
  * RETURNS:     ASN1_ERR value (ASN1_ERR_NOERROR on success)
  */
 int
-asn1_bits_decode ( ASN1_SCK *asn1, const guchar *eoc, guchar **bits,
+asn1_bits_decode ( ASN1_SCK *asn1, int eoc, guchar **bits,
                     guint *len, guchar *unused)
 
 {
@@ -618,8 +612,8 @@ asn1_bits_decode ( ASN1_SCK *asn1, const guchar *eoc, guchar **bits,
     if (ret != ASN1_ERR_NOERROR)
         return ret;
     *len = 0;
-    *bits = g_malloc(eoc - asn1->pointer);
-    while (asn1->pointer < eoc) {
+    *bits = g_malloc(eoc - asn1->offset);
+    while (asn1->offset < eoc) {
         ret = asn1_octet_decode (asn1, (guchar *)bits++);
         if (ret != ASN1_ERR_NOERROR) {
             g_free(*bits);
@@ -650,13 +644,13 @@ int
 asn1_string_value_decode ( ASN1_SCK *asn1, int enc_len, guchar **octets)
 {
     int          ret;
-    const guchar *eoc;
+    int          eoc;
     guchar       *ptr;
 
-    eoc = asn1->pointer + enc_len;
+    eoc = asn1->offset + enc_len;
     *octets = g_malloc (enc_len);
     ptr = *octets;
-    while (asn1->pointer < eoc) {
+    while (asn1->offset < eoc) {
        ret = asn1_octet_decode (asn1, (guchar *)ptr++);
        if (ret != ASN1_ERR_NOERROR) {
            g_free(*octets);
@@ -692,14 +686,14 @@ asn1_string_decode ( ASN1_SCK *asn1, guchar **octets, guint *str_len,
                        guint *nbytes, guint expected_tag)
 {
     int          ret;
-    const guchar *start;
+    int          start;
     int          enc_len;
     guint        cls;
     guint        con;
     guint        tag;
     gboolean     def;
 
-    start = asn1->pointer;
+    start = asn1->offset;
     ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
     if (ret != ASN1_ERR_NOERROR)
        goto done;
@@ -717,7 +711,7 @@ asn1_string_decode ( ASN1_SCK *asn1, guchar **octets, guint *str_len,
     *str_len = enc_len;
 
 done:
-    *nbytes = asn1->pointer - start;
+    *nbytes = asn1->offset - start;
     return ret;
 }
 
@@ -796,12 +790,12 @@ int
 asn1_oid_value_decode ( ASN1_SCK *asn1, int enc_len, subid_t **oid, guint *len)
 {
     int          ret;
-    const guchar *eoc;
+    int          eoc;
     subid_t      subid;
     guint        size;
     subid_t      *optr;
 
-    eoc = asn1->pointer + enc_len;
+    eoc = asn1->offset + enc_len;
     size = enc_len + 1;
     *oid = g_malloc(size * sizeof(gulong));
     optr = *oid;
@@ -824,7 +818,7 @@ asn1_oid_value_decode ( ASN1_SCK *asn1, int enc_len, subid_t **oid, guint *len)
     }
     *len = 2;
     optr += 2;
-    while (asn1->pointer < eoc) {
+    while (asn1->offset < eoc) {
        if (++(*len) > size) {
             g_free(*oid);
             *oid = NULL;
@@ -861,14 +855,14 @@ int
 asn1_oid_decode ( ASN1_SCK *asn1, subid_t **oid, guint *len, guint *nbytes)
 {
     int          ret;
-    const guchar *start;
+    int          start;
     guint        cls;
     guint        con;
     guint        tag;
     gboolean     def;
     guint        enc_len;
 
-    start = asn1->pointer;
+    start = asn1->offset;
     ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &enc_len);
     if (ret != ASN1_ERR_NOERROR)
        goto done;
@@ -884,7 +878,7 @@ asn1_oid_decode ( ASN1_SCK *asn1, subid_t **oid, guint *len, guint *nbytes)
     ret = asn1_oid_value_decode (asn1, enc_len, oid, len);
 
 done:
-    *nbytes = asn1->pointer - start;
+    *nbytes = asn1->offset - start;
     return ret;
 }
 
@@ -907,13 +901,13 @@ int
 asn1_sequence_decode ( ASN1_SCK *asn1, guint *seq_len, guint *nbytes)
 {
     int          ret;
-    const guchar *start;
+    int          start;
     guint        cls;
     guint        con;
     guint        tag;
     gboolean     def;
 
-    start = asn1->pointer;
+    start = asn1->offset;
     ret = asn1_header_decode(asn1, &cls, &con, &tag,
            &def, seq_len);
     if (ret != ASN1_ERR_NOERROR)
@@ -930,6 +924,6 @@ asn1_sequence_decode ( ASN1_SCK *asn1, guint *seq_len, guint *nbytes)
     ret = ASN1_ERR_NOERROR;
 
 done:
-    *nbytes = asn1->pointer - start;
+    *nbytes = asn1->offset - start;
     return ret;
 }
diff --git a/asn1.h b/asn1.h
index d10818711089aab4c21a148de691bd2f3cb71ca1..1befdfc9c706dd7abd5ca1778d61e6b150a7d410 100644 (file)
--- a/asn1.h
+++ b/asn1.h
@@ -1,7 +1,7 @@
 /* asn1.h
  * Definitions for ASN.1 BER dissection
  *
- * $Id: asn1.h,v 1.4 2000/12/24 09:10:11 guy Exp $
+ * $Id: asn1.h,v 1.5 2001/04/15 07:30:02 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -97,39 +97,37 @@ typedef u_int       subid_t;        /* CMU SNMP, libsmi, or nothing */
 #endif
 
 #define ASN1_ERR_NOERROR               0       /* no error */
-#define ASN1_ERR_EMPTY                 1       /* ran out of data */
-#define ASN1_ERR_EOC_MISMATCH          2
-#define ASN1_ERR_WRONG_TYPE            3       /* type not right */
-#define ASN1_ERR_LENGTH_NOT_DEFINITE   4       /* length should be definite */
-#define ASN1_ERR_LENGTH_MISMATCH       5
-#define ASN1_ERR_WRONG_LENGTH_FOR_TYPE 6       /* length wrong for type */
+#define ASN1_ERR_EOC_MISMATCH          1
+#define ASN1_ERR_WRONG_TYPE            2       /* type not right */
+#define ASN1_ERR_LENGTH_NOT_DEFINITE   3       /* length should be definite */
+#define ASN1_ERR_LENGTH_MISMATCH       4
+#define ASN1_ERR_WRONG_LENGTH_FOR_TYPE 5       /* length wrong for type */
 
 typedef struct _ASN1_SCK ASN1_SCK;
 
 struct _ASN1_SCK
 {                           /* ASN1 socket                         */
-    const guchar *pointer;  /* Octet just encoded or to be decoded */
-    const guchar *begin;    /* First octet                         */
-    const guchar *end;      /* Octet after last octet              */
+    tvbuff_t *tvb;          /* Tvbuff whence the data comes        */
+    int offset;             /* Current offset in tvbuff            */
 };
 
-void asn1_open (ASN1_SCK *asn1, const guchar *buf, guint len);
-void asn1_close (ASN1_SCK *asn1, const guchar **buf, guint *len);
+void asn1_open (ASN1_SCK *asn1, tvbuff_t *tvb, int offset);
+void asn1_close (ASN1_SCK *asn1, int *offset);
 int asn1_octet_decode (ASN1_SCK *asn1, guchar *ch);
 int asn1_tag_decode (ASN1_SCK *asn1, guint *tag);
 int asn1_id_decode (ASN1_SCK *asn1, guint *cls, guint *con, guint *tag);
 int asn1_length_decode (ASN1_SCK *asn1, gboolean *def, guint *len);
 int asn1_header_decode(ASN1_SCK *asn1, guint *cls, guint *con, guint *tag,
                        gboolean *defp, guint *lenp);
-int asn1_eoc (ASN1_SCK *asn1, const guchar *eoc);
-int asn1_eoc_decode (ASN1_SCK *asn1, const guchar *eoc);
+int asn1_eoc (ASN1_SCK *asn1, int eoc);
+int asn1_eoc_decode (ASN1_SCK *asn1, int eoc);
 int asn1_null_decode (ASN1_SCK *asn1, int enc_len);
 int asn1_bool_decode (ASN1_SCK *asn1, int enc_len, gboolean *bool);
 int asn1_int32_value_decode (ASN1_SCK *asn1, int enc_len, gint32 *integer);
 int asn1_int32_decode (ASN1_SCK *asn1, gint32 *integer, guint *nbytes);
 int asn1_uint32_value_decode (ASN1_SCK *asn1, int enc_len, guint *integer);
 int asn1_uint32_decode (ASN1_SCK *asn1, guint32 *integer, guint *nbytes);
-int asn1_bits_decode (ASN1_SCK *asn1, const guchar *eoc, guchar **bits, 
+int asn1_bits_decode (ASN1_SCK *asn1, int eoc, guchar **bits, 
                              guint *len, guchar *unused);
 int asn1_string_value_decode (ASN1_SCK *asn1, int enc_len,
                        guchar **octets);
index 4df151c7f254194d310d4a1cbf7be797adbede63..1ba40260c79485d79c264aa7fd009ec9f632c274 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-atm.c
  * Routines for ATM packet disassembly
  *
- * $Id: packet-atm.c,v 1.32 2001/01/21 20:16:01 guy Exp $
+ * $Id: packet-atm.c,v 1.33 2001/04/15 07:30:02 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -563,12 +563,6 @@ dissect_atm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
   proto_item   *ti;
   guint         aal_type;
   guint         hl_type;
-  const guint8 *pd;
-  int           offset;
-
-  CHECK_DISPLAY_AS_DATA(proto_atm, tvb, pinfo, tree);
-
-  pinfo->current_proto = "ATM";
 
   aal_type = pinfo->pseudo_header->ngsniffer_atm.AppTrafType & ATT_AALTYPE;
   hl_type = pinfo->pseudo_header->ngsniffer_atm.AppTrafType & ATT_HLTYPE;
@@ -741,8 +735,7 @@ dissect_atm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 
     case ATT_HL_ILMI:
       CHECK_DISPLAY_AS_DATA(proto_ilmi, tvb, pinfo, tree);
-      tvb_compat(tvb, &pd, &offset);
-      dissect_snmp_pdu(pd, offset, pinfo->fd, tree, "ILMI", proto_ilmi, ett_ilmi);
+      dissect_snmp_pdu(tvb, 0, pinfo, tree, "ILMI", proto_ilmi, ett_ilmi);
       break;
 
     default:
index 0e7b2c4b9d9d514ef3cf5347594c2df8bafe6f14..ee2c85d0a00c8d595655a63d6ca440125eed0981 100644 (file)
@@ -3,7 +3,7 @@
  * Wes Hardaker (c) 2000
  * wjhardaker@ucdavis.edu
  *
- * $Id: packet-kerberos.c,v 1.14 2001/01/09 06:31:37 guy Exp $
+ * $Id: packet-kerberos.c,v 1.15 2001/04/15 07:30:02 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
 #define UDP_PORT_KERBEROS              88
 #define TCP_PORT_KERBEROS              88
 
-static gint ett_kerberos   = -1;
-static gint ett_preauth    = -1;
-static gint ett_addresses  = -1;
-static gint ett_request    = -1;
-static gint ett_princ      = -1;
-static gint ett_ticket     = -1;
-static gint ett_encrypted  = -1;
-static gint ett_etype      = -1;
 static gint proto_kerberos = -1;
 
+static gint ett_kerberos = -1;
+static gint ett_preauth = -1;
+static gint ett_addresses = -1;
+static gint ett_request = -1;
+static gint ett_princ = -1;
+static gint ett_ticket = -1;
+static gint ett_encrypted = -1;
+static gint ett_etype = -1;
+static gint ett_additional_tickets = -1;
+
 #define KRB5_MSG_AS_REQ   10   /* AS-REQ type */
 #define KRB5_MSG_AS_REP   11   /* AS-REP type */
 #define KRB5_MSG_TGS_REQ  12   /* TGS-REQ type */
@@ -338,22 +340,20 @@ static const value_string krb5_msg_types[] = {
 };
 
 static int dissect_PrincipalName(char *title, ASN1_SCK *asn1p,
-                                 frame_data *fd, proto_tree *tree,
+                                 packet_info *pinfo, proto_tree *tree,
                                  int start_offset);
-static int dissect_Ticket(char *title, ASN1_SCK *asn1p, frame_data *fd,
+static int dissect_Ticket(char *title, ASN1_SCK *asn1p, packet_info *pinfo,
                           proto_tree *tree, int start_offset);
-static int dissect_EncryptedData(char *title, ASN1_SCK *asn1p, frame_data *fd,
-                                 proto_tree *tree, int start_offset);
-static int dissect_Addresses(char *title, ASN1_SCK *asn1p, frame_data *fd,
+static int dissect_EncryptedData(char *title, ASN1_SCK *asn1p,
+                                packet_info *pinfo, proto_tree *tree,
+                                int start_offset);
+static int dissect_Addresses(char *title, ASN1_SCK *asn1p, packet_info *pinfo,
                              proto_tree *tree, int start_offset);
 
 static const char *
 to_error_str(int ret) {
     switch (ret) {
 
-        case ASN1_ERR_EMPTY:
-            return("Ran out of data");
-
         case ASN1_ERR_EOC_MISMATCH:
             return("EOC mismatch");
 
@@ -374,10 +374,11 @@ to_error_str(int ret) {
 }
 
 static void
-krb_proto_tree_add_time(proto_tree *tree, int offset, int str_len,
-                        char *name, guchar *str) {
+krb_proto_tree_add_time(proto_tree *tree, tvbuff_t *tvb, int offset,
+                       int str_len, char *name, guchar *str)
+{
     if (tree)
-        proto_tree_add_text(tree, NullTVB, offset, str_len,
+        proto_tree_add_text(tree, tvb, offset, str_len,
                             "%s: %.4s-%.2s-%.2s %.2s:%.2s:%.2s (%.1s)",
                             name, str, str+4, str+6,
                             str+8, str+10, str+12,
@@ -391,21 +392,21 @@ krb_proto_tree_add_time(proto_tree *tree, int offset, int str_len,
  */
 
 #define KRB_HEAD_DECODE_OR_DIE(token) \
-   start = asn1p->pointer; \
+   start = asn1p->offset; \
    ret = asn1_header_decode (asn1p, &cls, &con, &tag, &def, &item_len); \
-   if (ret != ASN1_ERR_NOERROR && ret != ASN1_ERR_EMPTY) {\
-       if (check_col(fd, COL_INFO)) \
-           col_add_fstr(fd, COL_INFO, "ERROR: Problem at %s: %s", \
+   if (ret != ASN1_ERR_NOERROR) {\
+       if (check_col(pinfo->fd, COL_INFO)) \
+           col_add_fstr(pinfo->fd, COL_INFO, "ERROR: Problem at %s: %s", \
                     token, to_error_str(ret)); \
        return -1; \
    } \
    if (!def) {\
-       if (check_col(fd, COL_INFO)) \
-           col_add_fstr(fd, COL_INFO, "not definite: %s", token); \
+       if (check_col(pinfo->fd, COL_INFO)) \
+           col_add_fstr(pinfo->fd, COL_INFO, "not definite: %s", token); \
        fprintf(stderr,"not definite: %s\n", token); \
        return -1; \
    } \
-   offset += (asn1p->pointer - start);
+   offset += (asn1p->offset - start);
 
 #define CHECK_APPLICATION_TYPE(expected_tag) \
     (cls == ASN1_APL && con == ASN1_CON && tag == expected_tag)
@@ -423,8 +424,8 @@ krb_proto_tree_add_time(proto_tree *tree, int offset, int str_len,
 
 #define DIE_WITH_BAD_TYPE(token, expected_tag) \
     { \
-      if (check_col(fd, COL_INFO)) \
-         col_add_fstr(fd, COL_INFO, "ERROR: Problem at %s: %s (tag=%d exp=%d)", \
+      if (check_col(pinfo->fd, COL_INFO)) \
+         col_add_fstr(pinfo->fd, COL_INFO, "ERROR: Problem at %s: %s (tag=%d exp=%d)", \
                       token, to_error_str(ASN1_ERR_WRONG_TYPE), tag, expected_tag); \
       return -1; \
     }
@@ -439,9 +440,9 @@ krb_proto_tree_add_time(proto_tree *tree, int offset, int str_len,
 
 #define KRB_SEQ_HEAD_DECODE_OR_DIE(token) \
    ret = asn1_sequence_decode (asn1p, &item_len, &header_len); \
-   if (ret != ASN1_ERR_NOERROR && ret != ASN1_ERR_EMPTY) {\
-       if (check_col(fd, COL_INFO)) \
-           col_add_fstr(fd, COL_INFO, "ERROR: Problem at %s: %s", \
+   if (ret != ASN1_ERR_NOERROR) {\
+       if (check_col(pinfo->fd, COL_INFO)) \
+           col_add_fstr(pinfo->fd, COL_INFO, "ERROR: Problem at %s: %s", \
                     token, to_error_str(ret)); \
        return -1; \
    } \
@@ -450,8 +451,8 @@ krb_proto_tree_add_time(proto_tree *tree, int offset, int str_len,
 #define KRB_DECODE_OR_DIE(token, fn, val) \
     ret = fn (asn1p, &val, &length); \
     if (ret != ASN1_ERR_NOERROR) { \
-       if (check_col(fd, COL_INFO)) \
-         col_add_fstr(fd, COL_INFO, "ERROR: Problem at %s: %s", \
+       if (check_col(pinfo->fd, COL_INFO)) \
+         col_add_fstr(pinfo->fd, COL_INFO, "ERROR: Problem at %s: %s", \
                      token, to_error_str(ret)); \
         return -1; \
     } \
@@ -462,8 +463,8 @@ krb_proto_tree_add_time(proto_tree *tree, int offset, int str_len,
 #define KRB_DECODE_STRING_OR_DIE(token, expected_tag, val, val_len, item_len) \
     ret = asn1_string_decode (asn1p, &val, &val_len, &item_len, expected_tag); \
     if (ret != ASN1_ERR_NOERROR) { \
-       if (check_col(fd, COL_INFO)) \
-         col_add_fstr(fd, COL_INFO, "ERROR: Problem at %s: %s", \
+       if (check_col(pinfo->fd, COL_INFO)) \
+         col_add_fstr(pinfo->fd, COL_INFO, "ERROR: Problem at %s: %s", \
                      token, to_error_str(ret)); \
         return -1; \
     }
@@ -493,20 +494,20 @@ dissect_type_value_pair(ASN1_SCK *asn1p, int *inoff,
     int offset = *inoff;
     guint cls, con, tag;
     gboolean def;
-    const guchar *start;
+    int start;
     guint tmp_len;
     int ret;
 
     /* SEQUENCE */
-    start = asn1p->pointer;
+    start = asn1p->offset;
     asn1_header_decode (asn1p, &cls, &con, &tag, &def, &tmp_len);
-    offset += (asn1p->pointer - start);
+    offset += (asn1p->offset - start);
 
     /* INT */
     /* wrapper */
-    start = asn1p->pointer;
+    start = asn1p->offset;
     asn1_header_decode (asn1p, &cls, &con, &tag, &def, &tmp_len);
-    offset += (asn1p->pointer - start);
+    offset += (asn1p->offset - start);
 
     if (type_off)
         *type_off = offset;
@@ -521,10 +522,10 @@ dissect_type_value_pair(ASN1_SCK *asn1p, int *inoff,
 
     /* OCTET STRING (or generic data) */
     /* wrapper */
-    start = asn1p->pointer;
+    start = asn1p->offset;
     asn1_header_decode (asn1p, &cls, &con, &tag, &def, val_len);
     asn1_header_decode (asn1p, &cls, &con, &tag, &def, val_len);
-    offset += asn1p->pointer - start;
+    offset += asn1p->offset - start;
     
     if (val_off)
         *val_off = offset;
@@ -536,13 +537,14 @@ dissect_type_value_pair(ASN1_SCK *asn1p, int *inoff,
 }
 
 static gboolean
-dissect_kerberos_main(const u_char *pd, int offset, frame_data *fd,
-                      proto_tree *tree)
+dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
+    int offset = 0;
     proto_tree *kerberos_tree = NULL;
     proto_tree *etype_tree = NULL;
     proto_tree *preauth_tree = NULL;
     proto_tree *request_tree = NULL;
+    proto_tree *additional_tickets_tree = NULL;
     ASN1_SCK asn1, *asn1p = &asn1;
     proto_item *item = NULL;
 
@@ -550,7 +552,7 @@ dissect_kerberos_main(const u_char *pd, int offset, frame_data *fd,
     guint cls, con, tag;
     gboolean def;
     guint item_len, total_len;
-    const guchar *start;
+    int start, end, message_end, sequence_end;
 
     int ret;
 
@@ -566,17 +568,17 @@ dissect_kerberos_main(const u_char *pd, int offset, frame_data *fd,
     guchar *str;
     int tmp_pos1, tmp_pos2;
 
-    if (tree) {
-        item = proto_tree_add_item(tree, proto_kerberos, NullTVB, offset,
-                                   END_OF_FRAME, FALSE);
-        kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
-    }
-
-    asn1_open(&asn1, &pd[offset], END_OF_FRAME);
+    asn1_open(&asn1, tvb, 0);
 
     /* top header */
     KRB_HEAD_DECODE_OR_DIE("top");
     protocol_message_type = tag;
+    if (tree) {
+        item = proto_tree_add_item(tree, proto_kerberos, tvb, offset,
+                                   item_len, FALSE);
+        kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
+    }
+    message_end = start + item_len;
     
     /* second header */
     KRB_HEAD_DECODE_OR_DIE("top2");
@@ -586,7 +588,7 @@ dissect_kerberos_main(const u_char *pd, int offset, frame_data *fd,
     KRB_DECODE_UINT32_OR_DIE("version", version);
 
     if (kerberos_tree) {
-        proto_tree_add_text(kerberos_tree, NullTVB, offset, length,
+        proto_tree_add_text(kerberos_tree, tvb, offset, length,
                             "Version: %d",
                             version);
     }
@@ -597,15 +599,15 @@ dissect_kerberos_main(const u_char *pd, int offset, frame_data *fd,
     KRB_DECODE_UINT32_OR_DIE("message-type", msg_type);
 
     if (kerberos_tree) {
-        proto_tree_add_text(kerberos_tree, NullTVB, offset, length,
+        proto_tree_add_text(kerberos_tree, tvb, offset, length,
                             "MSG Type: %s",
                             val_to_str(msg_type, krb5_msg_types,
                                        "Unknown msg type %#x"));
     }
     offset += length;
 
-    if (check_col(fd, COL_INFO))
-        col_add_str(fd, COL_INFO, val_to_str(msg_type, krb5_msg_types,
+    if (check_col(pinfo->fd, COL_INFO))
+        col_add_str(pinfo->fd, COL_INFO, val_to_str(msg_type, krb5_msg_types,
                                              "Unknown msg type %#x"));
 
         /* is preauthentication present? */
@@ -619,26 +621,26 @@ dissect_kerberos_main(const u_char *pd, int offset, frame_data *fd,
         /* pre-authentication supplied */
 
         if (tree) {
-            item = proto_tree_add_text(kerberos_tree, NullTVB, offset,
+            item = proto_tree_add_text(kerberos_tree, tvb, offset,
                                        item_len, "Pre-Authentication");
             preauth_tree = proto_item_add_subtree(item, ett_preauth);
         }
 
         KRB_HEAD_DECODE_OR_DIE("sequence of pa-data");
-        start = asn1p->pointer + item_len;
+        end = asn1p->offset + item_len;
 
-        while(start > asn1p->pointer) {
+        while(asn1p->offset < end) {
             dissect_type_value_pair(asn1p, &offset,
                                     &preauth_type, &item_len, &tmp_pos1,
                                     &str, &str_len, &tmp_pos2);
 
             if (preauth_tree) {
-                proto_tree_add_text(preauth_tree, NullTVB, tmp_pos1,
+                proto_tree_add_text(preauth_tree, tvb, tmp_pos1,
                                     item_len, "Type: %s",
                                     val_to_str(preauth_type,
                                                krb5_preauthentication_types,
                                                "Unknown preauth type %#x"));
-                proto_tree_add_text(preauth_tree, NullTVB, tmp_pos2,
+                proto_tree_add_text(preauth_tree, tvb, tmp_pos2,
                                     str_len, "Value: %s",
                                     bytes_to_str(str, str_len));
             }
@@ -684,10 +686,11 @@ dissect_kerberos_main(const u_char *pd, int offset, frame_data *fd,
         /* request body */
         KRB_HEAD_DECODE_OR_DIE("body-sequence");
         if (tree) {
-            item = proto_tree_add_text(kerberos_tree, NullTVB, offset,
+            item = proto_tree_add_text(kerberos_tree, tvb, offset,
                                        item_len, "Request");
             request_tree = proto_item_add_subtree(item, ett_request);
         }
+        sequence_end = start + item_len;
 
         /* kdc options */
         KRB_HEAD_DECODE_OR_DIE("kdc options");
@@ -695,17 +698,18 @@ dissect_kerberos_main(const u_char *pd, int offset, frame_data *fd,
         KRB_HEAD_DECODE_OR_DIE("kdc options:bits");
 
         if (request_tree) {
-                proto_tree_add_text(request_tree, NullTVB, offset, item_len,
+                proto_tree_add_text(request_tree, tvb, offset, item_len,
                                     "Options: %s",
-                                    bytes_to_str(asn1.pointer, item_len));
+                                    tvb_bytes_to_str(asn1.tvb, asn1.offset,
+                                                     item_len));
         }
         offset += item_len;
-        asn1.pointer += item_len;
+        asn1.offset += item_len;
 
         KRB_HEAD_DECODE_OR_DIE("Client Name or Realm");
 
         if (CHECK_CONTEXT_TYPE(KRB5_BODY_CNAME)) {
-            item_len = dissect_PrincipalName("Client Name", asn1p, fd,
+            item_len = dissect_PrincipalName("Client Name", asn1p, pinfo,
                                              request_tree, offset);
             if (item_len == -1)
                 return -1;
@@ -716,14 +720,14 @@ dissect_kerberos_main(const u_char *pd, int offset, frame_data *fd,
         DIE_IF_NOT_CONTEXT_TYPE("Realm", KRB5_BODY_REALM);
         KRB_DECODE_GENERAL_STRING_OR_DIE("Realm", str, str_len, item_len);
         if (request_tree) {
-            proto_tree_add_text(request_tree, NullTVB, offset, item_len,
+            proto_tree_add_text(request_tree, tvb, offset, item_len,
                                 "Realm: %.*s", str_len, str);
         }
         offset += item_len;
 
         KRB_HEAD_DECODE_OR_DIE("Server Name");
         if (CHECK_CONTEXT_TYPE(KRB5_BODY_SNAME)) {
-            item_len = dissect_PrincipalName("Server Name", asn1p, fd,
+            item_len = dissect_PrincipalName("Server Name", asn1p, pinfo,
                                              request_tree, offset);
             if (item_len == -1)
                 return -1;
@@ -733,7 +737,7 @@ dissect_kerberos_main(const u_char *pd, int offset, frame_data *fd,
 
         if (CHECK_CONTEXT_TYPE(KRB5_BODY_FROM)) {
             KRB_DECODE_GENERAL_TIME_OR_DIE("From", str, str_len, item_len);
-            krb_proto_tree_add_time(request_tree, offset, item_len,
+            krb_proto_tree_add_time(request_tree, asn1p->tvb, offset, item_len,
                                     "Start Time", str);
             offset += item_len;
             KRB_HEAD_DECODE_OR_DIE("Till");
@@ -741,14 +745,14 @@ dissect_kerberos_main(const u_char *pd, int offset, frame_data *fd,
 
         DIE_IF_NOT_CONTEXT_TYPE("Till", KRB5_BODY_TILL);
         KRB_DECODE_GENERAL_TIME_OR_DIE("Till", str, str_len, item_len);
-        krb_proto_tree_add_time(request_tree, offset, item_len,
+        krb_proto_tree_add_time(request_tree, asn1p->tvb, offset, item_len,
                                 "End Time", str);
         offset += item_len;
 
         KRB_HEAD_DECODE_OR_DIE("Renewable Until or Nonce");
         if (CHECK_CONTEXT_TYPE(KRB5_BODY_RTIME)) {
             KRB_DECODE_GENERAL_TIME_OR_DIE("Renewable Until", str, str_len, item_len);
-            krb_proto_tree_add_time(request_tree, offset, item_len,
+            krb_proto_tree_add_time(request_tree, asn1p->tvb, offset, item_len,
                                     "Renewable Until", str);
             offset += item_len;
             KRB_HEAD_DECODE_OR_DIE("Nonce");
@@ -757,7 +761,7 @@ dissect_kerberos_main(const u_char *pd, int offset, frame_data *fd,
         DIE_IF_NOT_CONTEXT_TYPE("Nonce", KRB5_BODY_NONCE);
         KRB_DECODE_UINT32_OR_DIE("Nonce", tmp_int);
         if (request_tree) {
-            proto_tree_add_text(request_tree, NullTVB, offset, length,
+            proto_tree_add_text(request_tree, tvb, offset, length,
                                 "Random Number: %u",
                                 tmp_int);
         }
@@ -767,7 +771,7 @@ dissect_kerberos_main(const u_char *pd, int offset, frame_data *fd,
                                               KRB5_BODY_ENCTYPE);
         KRB_HEAD_DECODE_OR_DIE("encryption type list");
         if (kerberos_tree) {
-            item = proto_tree_add_text(request_tree, NullTVB, offset,
+            item = proto_tree_add_text(request_tree, tvb, offset,
                                        item_len, "Encryption Types");
             etype_tree = proto_item_add_subtree(item, ett_etype);
         }
@@ -775,7 +779,7 @@ dissect_kerberos_main(const u_char *pd, int offset, frame_data *fd,
         while(total_len > 0) {
             KRB_DECODE_UINT32_OR_DIE("encryption type", tmp_int);
             if (etype_tree) {
-                proto_tree_add_text(etype_tree, NullTVB, offset, length,
+                proto_tree_add_text(etype_tree, tvb, offset, length,
                                     "Type: %s",
                                     val_to_str(tmp_int,
                                                krb5_encryption_types,
@@ -785,16 +789,50 @@ dissect_kerberos_main(const u_char *pd, int offset, frame_data *fd,
             total_len -= length;
         }
 
-        KRB_HEAD_DECODE_OR_DIE("addresses");
+        if (asn1p->offset >= sequence_end)
+            break;
+        KRB_HEAD_DECODE_OR_DIE("addresses or enc-authorization-data");
         if (CHECK_CONTEXT_TYPE(KRB5_BODY_ADDRESSES)) {
-            /* pre-authentication supplied */
+            /* addresses supplied */
 
-            offset = dissect_Addresses("Addresses", asn1p, fd, kerberos_tree,
+            length = dissect_Addresses("Addresses", asn1p, pinfo, kerberos_tree,
                                        offset);
             if (offset == -1)
                 return -1;
-            KRB_HEAD_DECODE_OR_DIE("auth-data");
+            offset += length;
+            if (asn1p->offset >= sequence_end)
+                break;
+            KRB_HEAD_DECODE_OR_DIE("enc-authorization-data or additional-tickets");
+        }
+
+        if (CHECK_CONTEXT_TYPE(KRB5_BODY_ENC_AUTHORIZATION_DATA)) {
+            /* enc-authorization-data supplied */
+            length = dissect_EncryptedData("Encrypted Payload", asn1p, pinfo,
+                                           kerberos_tree, offset);
+            if (length == -1)
+                return -1;
+            offset += length;
+            if (asn1p->offset >= sequence_end)
+                break;
+            KRB_HEAD_DECODE_OR_DIE("additional-tickets");
+        }
+
+        /* additional-tickets supplied */
+        if (tree) {
+            item = proto_tree_add_text(kerberos_tree, tvb, offset,
+                                       item_len, "Additional Tickets");
+            additional_tickets_tree = proto_item_add_subtree(item, ett_additional_tickets);
+        }
+        end = asn1p->offset + item_len;
+        while(asn1p->offset < end) {
+            KRB_DECODE_CONTEXT_HEAD_OR_DIE("ticket", KRB5_KDC_REP_TICKET);
+            length = dissect_Ticket("ticket", asn1p, pinfo, additional_tickets_tree,
+                                    offset);
+            if (length == -1)
+                return -1;
+            offset += length;
         }
+
         break;
 
     case KRB5_MSG_AS_REP:
@@ -814,32 +852,34 @@ dissect_kerberos_main(const u_char *pd, int offset, frame_data *fd,
    }
 */
 
-               DIE_IF_NOT_CONTEXT_TYPE("crealm", KRB5_KDC_REP_CREALM);
+       DIE_IF_NOT_CONTEXT_TYPE("crealm", KRB5_KDC_REP_CREALM);
         KRB_DECODE_GENERAL_STRING_OR_DIE("realm name", str, str_len, item_len);
         if (kerberos_tree) {
-            proto_tree_add_text(kerberos_tree, NullTVB, offset, item_len,
+            proto_tree_add_text(kerberos_tree, tvb, offset, item_len,
                                 "Realm: %.*s", str_len, str);
         }
         offset += item_len;
 
         KRB_DECODE_CONTEXT_HEAD_OR_DIE("cname", KRB5_KDC_REP_CNAME);
-        item_len = dissect_PrincipalName("Client Name", asn1p, fd,
+        item_len = dissect_PrincipalName("Client Name", asn1p, pinfo,
                                          kerberos_tree, offset);
         if (item_len == -1)
             return -1;
         offset += item_len;
         
         KRB_DECODE_CONTEXT_HEAD_OR_DIE("ticket", KRB5_KDC_REP_TICKET);
-        offset = dissect_Ticket("ticket", asn1p, fd, kerberos_tree, offset);
-        if (offset == -1)
+        length = dissect_Ticket("ticket", asn1p, pinfo, kerberos_tree, offset);
+        if (length == -1)
             return -1;
+        offset += length;
 
         KRB_DECODE_CONTEXT_HEAD_OR_DIE("enc-msg-part",
                                               KRB5_KDC_REP_ENC_PART);
-        offset = dissect_EncryptedData("Encrypted Payload", asn1p, fd,
+        length = dissect_EncryptedData("Encrypted Payload", asn1p, pinfo,
                                        kerberos_tree, offset);
-        if (offset == -1)
+        if (length == -1)
             return -1;
+        offset += length;
         break;
 
     case KRB5_MSG_ERROR:
@@ -863,115 +903,118 @@ dissect_kerberos_main(const u_char *pd, int offset, frame_data *fd,
 
 */
 
-               /* ctime */
+       /* ctime */
         if (CHECK_CONTEXT_TYPE(KRB5_ERROR_CTIME)) {
             KRB_DECODE_GENERAL_TIME_OR_DIE("ctime", str, str_len, item_len);
-            krb_proto_tree_add_time(kerberos_tree, offset, item_len,
+            krb_proto_tree_add_time(kerberos_tree, asn1p->tvb, offset, item_len,
                                     "ctime", str);
             offset += item_len;
                        KRB_HEAD_DECODE_OR_DIE("cusec");
         }
 
-               /* cusec */
+       /* cusec */
         if (CHECK_CONTEXT_TYPE(KRB5_ERROR_CUSEC)) {
                        KRB_DECODE_UINT32_OR_DIE("cusec", tmp_int);
-               if (kerberos_tree) {
-                   proto_tree_add_text(kerberos_tree, NullTVB, offset, length,
-                                       "cusec: %u",
-                                       tmp_int);
-               }
+           if (kerberos_tree) {
+               proto_tree_add_text(kerberos_tree, tvb, offset, length,
+                                   "cusec: %u",
+                                   tmp_int);
+           }
 
             offset += item_len;
                        KRB_HEAD_DECODE_OR_DIE("sutime");
         }
 
-               DIE_IF_NOT_CONTEXT_TYPE("sutime", KRB5_ERROR_STIME);
-           KRB_DECODE_GENERAL_TIME_OR_DIE("stime", str, str_len, item_len);
-           krb_proto_tree_add_time(kerberos_tree, offset, item_len,
+       DIE_IF_NOT_CONTEXT_TYPE("sutime", KRB5_ERROR_STIME);
+       KRB_DECODE_GENERAL_TIME_OR_DIE("stime", str, str_len, item_len);
+       krb_proto_tree_add_time(kerberos_tree, asn1p->tvb, offset, item_len,
                                    "stime", str);
        offset += item_len;
 
-               KRB_HEAD_DECODE_OR_DIE("susec");
-               DIE_IF_NOT_CONTEXT_TYPE("susec", KRB5_ERROR_SUSEC);             
-               KRB_DECODE_UINT32_OR_DIE("susec", tmp_int);
-               if (kerberos_tree) {
-                   proto_tree_add_text(kerberos_tree, NullTVB, offset, length,
-                                       "susec: %u",
-                                       tmp_int);
-               }
-           offset += item_len;
-
-               KRB_HEAD_DECODE_OR_DIE("errcode");
-               DIE_IF_NOT_CONTEXT_TYPE("errcode", KRB5_ERROR_ERROR_CODE);              
-               KRB_DECODE_UINT32_OR_DIE("errcode", tmp_int);
-           if (kerberos_tree) {
-               proto_tree_add_text(kerberos_tree, NullTVB, offset, length,
-                                   "Error Code: %s",
-                                                               val_to_str(tmp_int,
-                                               krb5_error_codes,
-                                               "Unknown error code %#x"));
-           }
+       KRB_HEAD_DECODE_OR_DIE("susec");
+       DIE_IF_NOT_CONTEXT_TYPE("susec", KRB5_ERROR_SUSEC);             
+       KRB_DECODE_UINT32_OR_DIE("susec", tmp_int);
+       if (kerberos_tree) {
+               proto_tree_add_text(kerberos_tree, tvb, offset, length,
+                                   "susec: %u",
+                                   tmp_int);
+       }
+       offset += item_len;
+
+       KRB_HEAD_DECODE_OR_DIE("errcode");
+       DIE_IF_NOT_CONTEXT_TYPE("errcode", KRB5_ERROR_ERROR_CODE);
+       KRB_DECODE_UINT32_OR_DIE("errcode", tmp_int);
+       if (kerberos_tree) {
+           proto_tree_add_text(kerberos_tree, tvb, offset, length,
+                               "Error Code: %s",
+                               val_to_str(tmp_int, krb5_error_codes,
+                                           "Unknown error code %#x"));
+       }
         offset += item_len;
-               KRB_HEAD_DECODE_OR_DIE("crealm");
+       KRB_HEAD_DECODE_OR_DIE("crealm");
 
         if (CHECK_CONTEXT_TYPE(KRB5_ERROR_CREALM)) {
                KRB_DECODE_GENERAL_STRING_OR_DIE("crealm", str, str_len, item_len);
                if (kerberos_tree) {
-               proto_tree_add_text(kerberos_tree, NullTVB, offset, item_len,
+                   proto_tree_add_text(kerberos_tree, tvb, offset, item_len,
                                        "crealm: %.*s", str_len, str);
                }
                offset += item_len;
-                       KRB_HEAD_DECODE_OR_DIE("cname");
-               }
+               KRB_HEAD_DECODE_OR_DIE("cname");
+       }
 
-               if (CHECK_CONTEXT_TYPE(KRB5_ERROR_CNAME)) {
-               item_len = dissect_PrincipalName("cname", asn1p, fd,
+       if (CHECK_CONTEXT_TYPE(KRB5_ERROR_CNAME)) {
+           item_len = dissect_PrincipalName("cname", asn1p, pinfo,
                                          kerberos_tree, offset);
-               if (item_len == -1)
-                   return -1;
-               offset += item_len;
-                       KRB_HEAD_DECODE_OR_DIE("realm");
-               }
+           if (item_len == -1)
+               return -1;
+           offset += item_len;
+           KRB_HEAD_DECODE_OR_DIE("realm");
+       }
 
-               DIE_IF_NOT_CONTEXT_TYPE("realm", KRB5_ERROR_REALM);
+       DIE_IF_NOT_CONTEXT_TYPE("realm", KRB5_ERROR_REALM);
         KRB_DECODE_GENERAL_STRING_OR_DIE("realm", str, str_len, item_len);
         if (kerberos_tree) {
-            proto_tree_add_text(kerberos_tree, NullTVB, offset, item_len,
+            proto_tree_add_text(kerberos_tree, tvb, offset, item_len,
                                 "realm: %.*s", str_len, str);
         }
         offset += item_len;
-               KRB_HEAD_DECODE_OR_DIE("sname");
-
-               DIE_IF_NOT_CONTEXT_TYPE("sname", KRB5_ERROR_SNAME);
-           item_len = dissect_PrincipalName("sname", asn1p, fd,
-                                     kerberos_tree, offset);
-           if (item_len == -1)
-               return -1;
-           offset += item_len;
-               KRB_HEAD_DECODE_OR_DIE("e-text");
+       KRB_HEAD_DECODE_OR_DIE("sname");
 
-               if ( CHECK_CONTEXT_TYPE(KRB5_ERROR_ETEXT) ) {
-               KRB_DECODE_GENERAL_STRING_OR_DIE("etext", str, str_len, item_len);
-               if (kerberos_tree) {
-               proto_tree_add_text(kerberos_tree, NullTVB, offset, item_len,
+       DIE_IF_NOT_CONTEXT_TYPE("sname", KRB5_ERROR_SNAME);
+       item_len = dissect_PrincipalName("sname", asn1p, pinfo,
+                                         kerberos_tree, offset);
+       if (item_len == -1)
+               return -1;
+       offset += item_len;
+
+        if (asn1p->offset >= message_end)
+            break;
+       KRB_HEAD_DECODE_OR_DIE("e-text");
+       if ( CHECK_CONTEXT_TYPE(KRB5_ERROR_ETEXT) ) {
+            KRB_DECODE_GENERAL_STRING_OR_DIE("etext", str, str_len, item_len);
+            if (kerberos_tree) {
+               proto_tree_add_text(kerberos_tree, tvb, offset, item_len,
                                        "etext: %.*s", str_len, str);
-               }
-               offset += item_len;
-                       KRB_HEAD_DECODE_OR_DIE("e-data");
-               }
+            }
+            offset += item_len;
+            if (asn1p->offset >= message_end)
+                break;
+           KRB_HEAD_DECODE_OR_DIE("e-data");
+       }
 
-               if ( CHECK_CONTEXT_TYPE(KRB5_ERROR_EDATA) ) {
-                  guchar *data;
-                  guint data_len;
+       if ( CHECK_CONTEXT_TYPE(KRB5_ERROR_EDATA) ) {
+           guchar *data;
+           guint data_len;
 
-                  KRB_DECODE_OCTET_STRING_OR_DIE("e-data", data, data_len, item_len);
+           KRB_DECODE_OCTET_STRING_OR_DIE("e-data", data, data_len, item_len);
 
-              if (kerberos_tree) {
-               proto_tree_add_text(kerberos_tree, NullTVB, offset, data_len,
+           if (kerberos_tree) {
+               proto_tree_add_text(kerberos_tree, tvb, offset, data_len,
                             "Error Data: %s", bytes_to_str(data, item_len));
-           }
-           offset += data_len;
-               }
+           }
+           offset += data_len;
+       }
 
         break;
     }
@@ -979,18 +1022,16 @@ dissect_kerberos_main(const u_char *pd, int offset, frame_data *fd,
 }
 
 static void
-dissect_kerberos(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
+dissect_kerberos(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
-    OLD_CHECK_DISPLAY_AS_DATA(proto_kerberos, pd, offset, fd, tree);
-
-    if (check_col(fd, COL_PROTOCOL))
-        col_set_str(fd, COL_PROTOCOL, "KRB5");
+    if (check_col(pinfo->fd, COL_PROTOCOL))
+        col_set_str(pinfo->fd, COL_PROTOCOL, "KRB5");
 
-    dissect_kerberos_main(pd, offset, fd, tree);
+    dissect_kerberos_main(tvb, pinfo, tree);
 }
 
 static int
-dissect_PrincipalName(char *title, ASN1_SCK *asn1p, frame_data *fd,
+dissect_PrincipalName(char *title, ASN1_SCK *asn1p, packet_info *pinfo,
                        proto_tree *tree, int start_offset)
 {
 /*
@@ -1004,7 +1045,7 @@ dissect_PrincipalName(char *title, ASN1_SCK *asn1p, frame_data *fd,
 
     guint32 princ_type;
 
-    const guchar *start;
+    int start;
     guint cls, con, tag;
     guint header_len, item_len, total_len, type_len;
     int ret;
@@ -1022,7 +1063,7 @@ dissect_PrincipalName(char *title, ASN1_SCK *asn1p, frame_data *fd,
     KRB_SEQ_HEAD_DECODE_OR_DIE("principal section");
 
     if (tree) {
-      item = proto_tree_add_text(tree, NullTVB, start_offset,
+      item = proto_tree_add_text(tree, asn1p->tvb, start_offset,
                                  (offset - start_offset) + item_len, "%s",
                                  title);
       princ_tree = proto_item_add_subtree(item, ett_princ);
@@ -1038,7 +1079,7 @@ dissect_PrincipalName(char *title, ASN1_SCK *asn1p, frame_data *fd,
     offset += length;
 
     if (princ_tree) {
-      proto_tree_add_text(princ_tree, NullTVB, type_offset, type_len,
+      proto_tree_add_text(princ_tree, asn1p->tvb, type_offset, type_len,
                                                "Type: %s",
                                                val_to_str(princ_type, krb5_princ_types,
                                            "Unknown name type %#x"));
@@ -1057,7 +1098,7 @@ dissect_PrincipalName(char *title, ASN1_SCK *asn1p, frame_data *fd,
     KRB_DECODE_GENERAL_STRING_OR_DIE("principal name", name, name_len, item_len);
     if (princ_tree) {
         proto_item_set_text(item, "%s: %.*s", title, (int) name_len, name);
-        proto_tree_add_text(princ_tree, NullTVB, offset, item_len,
+        proto_tree_add_text(princ_tree, asn1p->tvb, offset, item_len,
                             "Name: %.*s", (int) name_len, name);
     }
     total_len -= item_len;
@@ -1068,7 +1109,7 @@ dissect_PrincipalName(char *title, ASN1_SCK *asn1p, frame_data *fd,
     while (total_len > 0) {
         KRB_DECODE_GENERAL_STRING_OR_DIE("principal name", name, name_len, item_len);
         if (princ_tree) {
-            proto_tree_add_text(princ_tree, NullTVB, offset, item_len,
+            proto_tree_add_text(princ_tree, asn1p->tvb, offset, item_len,
                                 "Name: %.*s", (int) name_len, name);
         }
         total_len -= item_len;
@@ -1078,12 +1119,12 @@ dissect_PrincipalName(char *title, ASN1_SCK *asn1p, frame_data *fd,
 }
 
 static int
-dissect_Addresses(char *title, ASN1_SCK *asn1p, frame_data *fd,
+dissect_Addresses(char *title, ASN1_SCK *asn1p, packet_info *pinfo,
                   proto_tree *tree, int start_offset) {
     proto_tree *address_tree = NULL;
     int offset = start_offset;
 
-    const guchar *start;
+    int start, end;
     guint cls, con, tag;
     guint item_len;
     int ret;
@@ -1099,44 +1140,45 @@ dissect_Addresses(char *title, ASN1_SCK *asn1p, frame_data *fd,
 
     KRB_HEAD_DECODE_OR_DIE("sequence of addresses");
     if (tree) {
-        item = proto_tree_add_text(tree, NullTVB, offset,
+        item = proto_tree_add_text(tree, asn1p->tvb, offset,
                                    item_len, "Addresses");
         address_tree = proto_item_add_subtree(item, ett_addresses);
     }
 
-    start = asn1p->pointer + item_len;
+    start = offset;
+    end = asn1p->offset + item_len;
 
-    while(start > asn1p->pointer) {
+    while(asn1p->offset < end) {
         dissect_type_value_pair(asn1p, &offset,
                                 &address_type, &item_len, &tmp_pos1,
                                 &str, &str_len, &tmp_pos2);
 
         if (address_tree) {
-            proto_tree_add_text(address_tree, NullTVB, tmp_pos1,
+            proto_tree_add_text(address_tree, asn1p->tvb, tmp_pos1,
                                 item_len, "Type: %s",
                                 val_to_str(address_type, krb5_address_types,
                                            "Unknown address type %#x"));
             switch(address_type) {
                 case KRB5_ADDR_IPv4:
-                    proto_tree_add_text(address_tree, NullTVB, tmp_pos2,
+                    proto_tree_add_text(address_tree, asn1p->tvb, tmp_pos2,
                                         str_len, "Value: %d.%d.%d.%d",
                                         str[0], str[1], str[2], str[3]);
                     break;
                     
                 default:
-                    proto_tree_add_text(address_tree, NullTVB, tmp_pos2,
+                    proto_tree_add_text(address_tree, asn1p->tvb, tmp_pos2,
                                         str_len, "Value: %s",
                                         bytes_to_str(str, str_len));
             }
         }
     }
     
-    return offset;
+    return offset - start_offset;
 }
 
 static int
-dissect_EncryptedData(char *title, ASN1_SCK *asn1p, frame_data *fd,
-                      proto_tree *tree, int start_offset)
+dissect_EncryptedData(char *title, ASN1_SCK *asn1p, packet_info *pinfo,
+                     proto_tree *tree, int start_offset)
 {
 /*
    EncryptedData ::=   SEQUENCE {
@@ -1148,7 +1190,7 @@ dissect_EncryptedData(char *title, ASN1_SCK *asn1p, frame_data *fd,
     proto_tree *encr_tree = NULL;
     int offset = start_offset;
 
-    const guchar *start;
+    int start;
     guint cls, con, tag;
     guint header_len, item_len, data_len;
     int ret;
@@ -1163,7 +1205,7 @@ dissect_EncryptedData(char *title, ASN1_SCK *asn1p, frame_data *fd,
     KRB_SEQ_HEAD_DECODE_OR_DIE("encrypted data section");
 
     if (tree) {
-        item = proto_tree_add_text(tree, NullTVB, start_offset,
+        item = proto_tree_add_text(tree, asn1p->tvb, start_offset,
                                    (offset - start_offset) + item_len,
                                    "Encrypted Data: %s", title);
         encr_tree = proto_item_add_subtree(item, ett_princ);
@@ -1173,7 +1215,7 @@ dissect_EncryptedData(char *title, ASN1_SCK *asn1p, frame_data *fd,
     KRB_DECODE_CONTEXT_HEAD_OR_DIE("encryption type", 0);
     KRB_DECODE_UINT32_OR_DIE("encr-type", val);
     if (encr_tree) {
-        proto_tree_add_text(encr_tree, NullTVB, offset, length,
+        proto_tree_add_text(encr_tree, asn1p->tvb, offset, length,
                             "Type: %s",
                             val_to_str(val, krb5_encryption_types,
                                        "Unknown encryption type %#x"));
@@ -1185,7 +1227,7 @@ dissect_EncryptedData(char *title, ASN1_SCK *asn1p, frame_data *fd,
     if (CHECK_CONTEXT_TYPE(1)) {
       KRB_DECODE_UINT32_OR_DIE("kvno", val);
       if (encr_tree) {
-          proto_tree_add_text(encr_tree, NullTVB, offset, length,
+          proto_tree_add_text(encr_tree, asn1p->tvb, offset, length,
                               "KVNO: %d", val);
       }
       offset += length;
@@ -1196,17 +1238,17 @@ dissect_EncryptedData(char *title, ASN1_SCK *asn1p, frame_data *fd,
     KRB_DECODE_OCTET_STRING_OR_DIE("cipher", data, data_len, item_len);
 
     if (encr_tree) {
-        proto_tree_add_text(encr_tree, NullTVB, offset, data_len,
+        proto_tree_add_text(encr_tree, asn1p->tvb, offset, data_len,
                             "CipherText: %s", bytes_to_str(data, item_len));
     }
     offset += data_len;
     
-    return offset;
+    return offset - start_offset;
 }
 
 static int
-dissect_Ticket(char *title, ASN1_SCK *asn1p, frame_data *fd, proto_tree *tree,
-               int start_offset)
+dissect_Ticket(char *title, ASN1_SCK *asn1p, packet_info *pinfo,
+              proto_tree *tree, int start_offset)
 {
 /*
    Ticket ::=                    [APPLICATION 1] SEQUENCE {
@@ -1219,7 +1261,7 @@ dissect_Ticket(char *title, ASN1_SCK *asn1p, frame_data *fd, proto_tree *tree,
     proto_tree *ticket_tree = NULL;
     int offset = start_offset;
 
-    const guchar *start;
+    int start;
     guint cls, con, tag;
     guint header_len, item_len, total_len;
     int ret;
@@ -1237,7 +1279,7 @@ dissect_Ticket(char *title, ASN1_SCK *asn1p, frame_data *fd, proto_tree *tree,
     total_len = item_len;
 
     if (tree) {
-        item = proto_tree_add_text(tree, NullTVB, start_offset,
+        item = proto_tree_add_text(tree, asn1p->tvb, start_offset,
                                    (offset - start_offset) + item_len,
                                    "Ticket");
         ticket_tree = proto_item_add_subtree(item, ett_ticket);
@@ -1247,7 +1289,7 @@ dissect_Ticket(char *title, ASN1_SCK *asn1p, frame_data *fd, proto_tree *tree,
     KRB_DECODE_CONTEXT_HEAD_OR_DIE("Ticket tkt-vno", KRB5_TKT_TKT_VNO);
     KRB_DECODE_UINT32_OR_DIE("Ticket tkt-vno", val);
     if (ticket_tree) {
-        proto_tree_add_text(ticket_tree, NullTVB, offset, length,
+        proto_tree_add_text(ticket_tree, asn1p->tvb, offset, length,
                             "Version: %u", val);
     }
     offset += length;
@@ -1257,7 +1299,7 @@ dissect_Ticket(char *title, ASN1_SCK *asn1p, frame_data *fd, proto_tree *tree,
     KRB_DECODE_CONTEXT_HEAD_OR_DIE("Ticket realm", KRB5_TKT_REALM);
     KRB_DECODE_GENERAL_STRING_OR_DIE("Ticket realm string", str, str_len, item_len);
     if (ticket_tree) {
-        proto_tree_add_text(ticket_tree, NullTVB, offset, item_len,
+        proto_tree_add_text(ticket_tree, asn1p->tvb, offset, item_len,
                             "Realm: %.*s", str_len, str);
     }
     offset += item_len;
@@ -1265,7 +1307,7 @@ dissect_Ticket(char *title, ASN1_SCK *asn1p, frame_data *fd, proto_tree *tree,
 
     /* server name (sname) */
     KRB_DECODE_CONTEXT_HEAD_OR_DIE("Ticket sname", KRB5_TKT_SNAME);
-    item_len = dissect_PrincipalName("Service Name", asn1p, fd, ticket_tree,
+    item_len = dissect_PrincipalName("Service Name", asn1p, pinfo, ticket_tree,
                                      offset);
     if (item_len == -1)
         return -1;
@@ -1273,12 +1315,13 @@ dissect_Ticket(char *title, ASN1_SCK *asn1p, frame_data *fd, proto_tree *tree,
 
     /* encrypted part */
     KRB_DECODE_CONTEXT_HEAD_OR_DIE("enc-part", KRB5_TKT_ENC_PART);
-    offset = dissect_EncryptedData("Ticket data", asn1p, fd, ticket_tree,
-                                   offset);
-    if (offset == -1)
+    length = dissect_EncryptedData("Ticket data", asn1p, pinfo, ticket_tree,
+                                  offset);
+    if (length == -1)
         return -1;
+    offset += length;
 
-    return offset;
+    return offset - start_offset;
 }
 
 
@@ -1297,6 +1340,7 @@ proto_register_kerberos(void) {
         &ett_ticket,
         &ett_addresses,
         &ett_etype,
+        &ett_additional_tickets,
     };
     proto_kerberos = proto_register_protocol("Kerberos", "KRB5", "kerberos");
 /*
@@ -1308,10 +1352,10 @@ proto_register_kerberos(void) {
 void
 proto_reg_handoff_kerberos(void)
 {
-       old_dissector_add("udp.port", UDP_PORT_KERBEROS, dissect_kerberos,
-           proto_kerberos);
-       old_dissector_add("tcp.port", TCP_PORT_KERBEROS, dissect_kerberos,
-           proto_kerberos);
+    dissector_add("udp.port", UDP_PORT_KERBEROS, dissect_kerberos,
+       proto_kerberos);
+    dissector_add("tcp.port", TCP_PORT_KERBEROS, dissect_kerberos,
+       proto_kerberos);
 }
 
 /*
@@ -1577,16 +1621,16 @@ proto_reg_handoff_kerberos(void)
       METHOD-DATA ::=    SEQUENCE {
                          method-type[0]   INTEGER,
                          method-data[1]   OCTET STRING OPTIONAL
-       }
+      }
 
-          EncryptionKey ::=   SEQUENCE {
-                              keytype[0]    INTEGER,
-                              keyvalue[1]   OCTET STRING
-          }
+      EncryptionKey ::=   SEQUENCE {
+                         keytype[0]    INTEGER,
+                         keyvalue[1]   OCTET STRING
+      }
 
-            Checksum ::=   SEQUENCE {
-                           cksumtype[0]   INTEGER,
-                           checksum[1]    OCTET STRING
-            }
+      Checksum ::=   SEQUENCE {
+                         cksumtype[0]   INTEGER,
+                         checksum[1]    OCTET STRING
+      }
 
 */
index dde6397687eb2d0a5949440e1dd993adaefc5ddf..7d21738819438adc41d389c01cfdb0ec4aa33fc0 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-ldap.c
  * Routines for ldap packet dissection
  *
- * $Id: packet-ldap.c,v 1.22 2001/01/10 23:42:12 guy Exp $
+ * $Id: packet-ldap.c,v 1.23 2001/04/15 07:30:03 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -140,7 +140,7 @@ static int read_length(ASN1_SCK *a, proto_tree *tree, int hf_id, guint *len)
 {
   guint length = 0;
   gboolean def = FALSE;
-  const guchar *start = a->pointer;
+  int start = a->offset;
   
   asn1_length_decode(a, &def, &length);
 
@@ -148,7 +148,7 @@ static int read_length(ASN1_SCK *a, proto_tree *tree, int hf_id, guint *len)
     *len = length;
 
   if (tree)
-    proto_tree_add_uint(tree, hf_id, NullTVB, start-a->begin, a->pointer-start, length);
+    proto_tree_add_uint(tree, hf_id, a->tvb, start, a->offset-start, length);
 
   return 0;
 }
@@ -157,13 +157,15 @@ static int read_sequence(ASN1_SCK *a, guint *len)
 {
   guint cls, con, tag;
   gboolean def;
+  int start;
   guint length;
   
+  start = a->offset;
   if (asn1_header_decode(a, &cls, &con, &tag, &def, &length) != ASN1_ERR_NOERROR)
     return 1;
   if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ)
     return 1;
-  
+
   if (len)
     *len = length;
   
@@ -188,7 +190,7 @@ static int read_set(ASN1_SCK *a, guint *len)
 }
 
 static int read_integer_value(ASN1_SCK *a, proto_tree *tree, int hf_id,
-       proto_tree **new_tree, guint *i, const guchar *start, guint length)
+       proto_tree **new_tree, guint *i, int start, guint length)
 {
   guint integer = 0;
 
@@ -200,7 +202,7 @@ static int read_integer_value(ASN1_SCK *a, proto_tree *tree, int hf_id,
   if (tree)
   {
     proto_tree *temp_tree = 0;
-    temp_tree = proto_tree_add_uint(tree, hf_id, NullTVB, start-a->begin, a->pointer-start, integer);
+    temp_tree = proto_tree_add_uint(tree, hf_id, a->tvb, start, a->offset-start, integer);
     if (new_tree)
       *new_tree = temp_tree;
   }
@@ -214,7 +216,7 @@ static int read_integer(ASN1_SCK *a, proto_tree *tree, int hf_id,
   guint cls, con, tag;
   gboolean def;
   guint length;
-  const guchar *start = a->pointer;
+  int start = a->offset;
   
   if (asn1_header_decode(a, &cls, &con, &tag, &def, &length) != ASN1_ERR_NOERROR)
     return 1;
@@ -225,7 +227,7 @@ static int read_integer(ASN1_SCK *a, proto_tree *tree, int hf_id,
 }
 
 static int read_boolean_value(ASN1_SCK *a, proto_tree *tree, int hf_id,
-       proto_tree **new_tree, guint *i, const guchar *start, guint length)
+       proto_tree **new_tree, guint *i, int start, guint length)
 {
   guint integer = 0;
 
@@ -237,7 +239,7 @@ static int read_boolean_value(ASN1_SCK *a, proto_tree *tree, int hf_id,
   if (tree)
   {
     proto_tree *temp_tree = 0;
-    temp_tree = proto_tree_add_boolean(tree, hf_id, NullTVB, start-a->begin, a->pointer-start, integer);
+    temp_tree = proto_tree_add_boolean(tree, hf_id, a->tvb, start, a->offset-start, integer);
     if (new_tree)
       *new_tree = temp_tree;
   }
@@ -251,7 +253,7 @@ static int read_boolean(ASN1_SCK *a, proto_tree *tree, int hf_id,
   guint cls, con, tag;
   gboolean def;
   guint length;
-  const guchar *start = a->pointer;
+  int start = a->offset;
   
   if (asn1_header_decode(a, &cls, &con, &tag, &def, &length) != ASN1_ERR_NOERROR)
     return 1;
@@ -262,7 +264,7 @@ static int read_boolean(ASN1_SCK *a, proto_tree *tree, int hf_id,
 }
 
 static void read_string_value(ASN1_SCK *a, proto_tree *tree, int hf_id,
-       proto_tree **new_tree, char **s, const guchar *start, guint length)
+       proto_tree **new_tree, char **s, int start, guint length)
 {
   guchar *string;
   
@@ -278,7 +280,7 @@ static void read_string_value(ASN1_SCK *a, proto_tree *tree, int hf_id,
   if (tree)
   {
     proto_tree *temp_tree;
-    temp_tree = proto_tree_add_string(tree, hf_id, NullTVB, start - a->begin, a->pointer - start, string);
+    temp_tree = proto_tree_add_string(tree, hf_id, a->tvb, start, a->offset - start, string);
     if (new_tree)
       *new_tree = temp_tree;
   }
@@ -295,7 +297,7 @@ static int read_string(ASN1_SCK *a, proto_tree *tree, int hf_id,
   guint cls, con, tag;
   gboolean def;
   guint length;
-  const guchar *start = a->pointer;
+  int start = a->offset;
   int ret;
   
   ret = asn1_header_decode(a, &cls, &con, &tag, &def, &length);
@@ -348,7 +350,7 @@ static int parse_filter_strings(ASN1_SCK *a, char **filter, guint *filter_length
 /* Richard Dawe: To parse substring filters, I added this function. */
 static int parse_filter_substrings(ASN1_SCK *a, char **filter, guint *filter_length)
 {
-  guchar *end;
+  int end;
   guchar *string;
   char *filterp;
   guint string_length;
@@ -386,9 +388,9 @@ static int parse_filter_substrings(ASN1_SCK *a, char **filter, guint *filter_len
 
   /* Now decode seq_len's worth of octet strings. */
   any_valued = 0;
-  end = (guchar *) (a->pointer + seq_len);
+  end = a->offset + seq_len;
 
-  while (a->pointer < end) {
+  while (a->offset < end) {
     /* Octet strings here are context-specific, which
      * asn1_octet_string_decode() barfs on. Emulate it, but don't barf. */
     ret = asn1_header_decode (a, &cls, &con, &tag, &def, &string_length);
@@ -446,7 +448,8 @@ static int parse_filter_substrings(ASN1_SCK *a, char **filter, guint *filter_len
 }
 
 /* Returns -1 if we're at the end, returns an ASN1_ERR value otherwise. */
-static int parse_filter(ASN1_SCK *a, char **filter, guint *filter_length, const guchar **end)
+static int parse_filter(ASN1_SCK *a, char **filter, guint *filter_length,
+                       int *end)
 {
   guint cls, con, tag;
   guint length;
@@ -459,7 +462,7 @@ static int parse_filter(ASN1_SCK *a, char **filter, guint *filter_length, const
   
   if (*end == 0)
   {
-    *end = a->pointer + length;
+    *end = a->offset + length;
     *filter_length = 1;
     *filter = g_malloc0(*filter_length);
   }
@@ -470,11 +473,11 @@ static int parse_filter(ASN1_SCK *a, char **filter, guint *filter_length, const
     {
      case LDAP_FILTER_AND:
       {
-        const guchar *add_end;
+        int add_end;
 
         if (con != ASN1_CON)
           return ASN1_ERR_WRONG_TYPE;
-        add_end = a->pointer + length;
+        add_end = a->offset + length;
         *filter_length += 3;
         *filter = g_realloc(*filter, *filter_length);
         strcat(*filter, "(&");
@@ -488,11 +491,11 @@ static int parse_filter(ASN1_SCK *a, char **filter, guint *filter_length, const
       break;
      case LDAP_FILTER_OR:
       {
-        const guchar *or_end;
+        int or_end;
 
         if (con != ASN1_CON)
           return ASN1_ERR_WRONG_TYPE;
-        or_end = a->pointer + length;
+        or_end = a->offset + length;
         *filter_length += 3;
         *filter = g_realloc(*filter, *filter_length);
         strcat(*filter, "(|");
@@ -506,11 +509,11 @@ static int parse_filter(ASN1_SCK *a, char **filter, guint *filter_length, const
       break;
      case LDAP_FILTER_NOT:
       {
-        const guchar *not_end;
+        int not_end;
 
         if (con != ASN1_CON)
           return ASN1_ERR_WRONG_TYPE;
-        not_end = a->pointer + length;
+        not_end = a->offset + length;
         *filter_length += 3;
         *filter = g_realloc(*filter, *filter_length);
         strcat(*filter, "(!");
@@ -586,7 +589,7 @@ static int parse_filter(ASN1_SCK *a, char **filter, guint *filter_length, const
     }
   }
   
-  if (a->pointer == *end)
+  if (a->offset == *end)
     return -1;
   else
     return ret;
@@ -594,10 +597,10 @@ static int parse_filter(ASN1_SCK *a, char **filter, guint *filter_length, const
 
 static int read_filter(ASN1_SCK *a, proto_tree *tree, int hf_id)
 {
-  const guchar *start = a->pointer;
+  int start = a->offset;
   char *filter = 0;
   guint filter_length = 0;
-  const guchar *end = 0;
+  int end = 0;
   int ret;
      
   while ((ret = parse_filter(a, &filter, &filter_length, &end))
@@ -606,10 +609,10 @@ static int read_filter(ASN1_SCK *a, proto_tree *tree, int hf_id)
 
   if (tree) {
     if (ret != -1) {
-      proto_tree_add_text(tree, NullTVB, start-a->begin, 0,
+      proto_tree_add_text(tree, a->tvb, start, 0,
         "Error parsing filter (%d)", ret);
     } else
-      proto_tree_add_string(tree, hf_id, NullTVB, start-a->begin, a->pointer-start, filter);
+      proto_tree_add_string(tree, hf_id, a->tvb, start, a->offset-start, filter);
   }
 
   g_free(filter);
@@ -629,17 +632,17 @@ static int dissect_ldap_result(ASN1_SCK *a, proto_tree *tree)
 
   if (resultCode == 10)                /* Referral */
   {
-    const guchar *start = a->pointer;
-    const guchar *end;
+    int start = a->offset;
+    int end;
     guint length;
     proto_tree *t, *referralTree;
     
     read_sequence(a, &length);
-    t = proto_tree_add_text(tree, NullTVB, start-a->begin, length, "Referral URLs");
+    t = proto_tree_add_text(tree, a->tvb, start, length, "Referral URLs");
     referralTree = proto_item_add_subtree(t, ett_ldap_referrals);
 
-    end = a->pointer + length;;
-    while (a->pointer < end)
+    end = a->offset + length;
+    while (a->offset < end)
       read_string(a, referralTree, hf_ldap_message_result_referral, 0, 0, ASN1_UNI, ASN1_OTS);
   }
     
@@ -650,18 +653,18 @@ static int dissect_ldap_request_bind(ASN1_SCK *a, proto_tree *tree)
 {
   guint cls, con, tag;
   guint def, length;
-  const guchar *start;
+  int start;
 
   read_integer(a, tree, hf_ldap_message_bind_version, 0, 0, ASN1_INT);
   read_string(a, tree, hf_ldap_message_bind_dn, 0, 0, ASN1_UNI, ASN1_OTS);
 
-  start = a->pointer;
+  start = a->offset;
   if (asn1_header_decode(a, &cls, &con, &tag, &def, &length) != ASN1_ERR_NOERROR)
     return 1;  /* XXX - right return value for an error? */
   if (cls != ASN1_CTX)
     return 1;  /* RFCs 1777 and 2251 say these are context-specific types */
-  proto_tree_add_uint(tree, hf_ldap_message_bind_auth, NullTVB, start - a->begin,
-                       a->pointer - start, tag);
+  proto_tree_add_uint(tree, hf_ldap_message_bind_auth, a->tvb, start,
+                       a->offset - start, tag);
   switch (tag)
   {
    case LDAP_AUTH_SIMPLE:
@@ -686,7 +689,7 @@ static int dissect_ldap_response_bind(ASN1_SCK *a, proto_tree *tree)
 static int dissect_ldap_request_search(ASN1_SCK *a, proto_tree *tree)
 {
   guint seq_length;
-  const guchar *end;
+  int end;
   int ret;
   
   read_string(a, tree, hf_ldap_message_search_base, 0, 0, ASN1_UNI, ASN1_OTS);
@@ -699,8 +702,8 @@ static int dissect_ldap_request_search(ASN1_SCK *a, proto_tree *tree)
   if (ret != ASN1_ERR_NOERROR)
     return ret;
   read_sequence(a, &seq_length);
-  end = a->pointer + seq_length;
-  while (a->pointer < end) {
+  end = a->offset + seq_length;
+  while (a->offset < end) {
     ret = read_string(a, tree, hf_ldap_message_attribute, 0, 0, ASN1_UNI, ASN1_OTS);
     if (ret != ASN1_ERR_NOERROR)
       return ret;
@@ -711,25 +714,25 @@ static int dissect_ldap_request_search(ASN1_SCK *a, proto_tree *tree)
 static int dissect_ldap_response_search_entry(ASN1_SCK *a, proto_tree *tree)
 {
   guint seq_length;
-  const guchar *end_of_sequence;
+  int end_of_sequence;
  
   read_string(a, tree, hf_ldap_message_dn, 0, 0, ASN1_UNI, ASN1_OTS);
   read_sequence(a, &seq_length);
 
-  end_of_sequence = a->pointer + seq_length;
-  while (a->pointer < end_of_sequence)
+  end_of_sequence = a->offset + seq_length;
+  while (a->offset < end_of_sequence)
   {
     proto_tree *t, *attr_tree;
     guint set_length;
-    const guchar *end_of_set;
+    int end_of_set;
 
     read_sequence(a, 0);
     read_string(a, tree, hf_ldap_message_attribute, &t, 0, ASN1_UNI, ASN1_OTS);
     attr_tree = proto_item_add_subtree(t, ett_ldap_attribute);
 
     read_set(a, &set_length);
-    end_of_set = a->pointer + set_length;
-    while (a->pointer < end_of_set)
+    end_of_set = a->offset + set_length;
+    while (a->offset < end_of_set)
       read_string(a, attr_tree, hf_ldap_message_value, 0, 0, ASN1_UNI, ASN1_OTS);
   }
 
@@ -739,25 +742,25 @@ static int dissect_ldap_response_search_entry(ASN1_SCK *a, proto_tree *tree)
 static int dissect_ldap_request_add(ASN1_SCK *a, proto_tree *tree)
 {
   guint seq_length;
-  const guchar *end_of_sequence;
+  int end_of_sequence;
   
   read_string(a, tree, hf_ldap_message_dn, 0, 0, ASN1_UNI, ASN1_OTS);
 
   read_sequence(a, &seq_length);
-  end_of_sequence = a->pointer + seq_length;
-  while (a->pointer < end_of_sequence)
+  end_of_sequence = a->offset + seq_length;
+  while (a->offset < end_of_sequence)
   {
     proto_tree *t, *attr_tree;
     guint set_length;
-    const guchar *end_of_set;
+    int end_of_set;
 
     read_sequence(a, 0);
     read_string(a, tree, hf_ldap_message_attribute, &t, 0, ASN1_UNI, ASN1_OTS);
     attr_tree = proto_item_add_subtree(t, ett_ldap_attribute);
 
     read_set(a, &set_length);
-    end_of_set = a->pointer + set_length;
-    while (a->pointer < end_of_set)
+    end_of_set = a->offset + set_length;
+    while (a->offset < end_of_set)
       read_string(a, attr_tree, hf_ldap_message_value, 0, 0, ASN1_UNI, ASN1_OTS);
   }
 
@@ -765,7 +768,7 @@ static int dissect_ldap_request_add(ASN1_SCK *a, proto_tree *tree)
 }
 
 static int dissect_ldap_request_delete(ASN1_SCK *a, proto_tree *tree,
-               const guchar *start, guint length)
+               int start, guint length)
 {
   read_string_value(a, tree, hf_ldap_message_dn, NULL, NULL, start, length);
   return 0;
@@ -774,13 +777,13 @@ static int dissect_ldap_request_delete(ASN1_SCK *a, proto_tree *tree,
 static int dissect_ldap_request_modifyrdn(ASN1_SCK *a, proto_tree *tree,
                guint length)
 {
-  const guchar *start = a->pointer;
+  int start = a->offset;
 
   read_string(a, tree, hf_ldap_message_dn, 0, 0, ASN1_UNI, ASN1_OTS);
   read_string(a, tree, hf_ldap_message_modrdn_name, 0, 0, ASN1_UNI, ASN1_OTS);
   read_boolean(a, tree, hf_ldap_message_modrdn_delete, 0, 0);
   
-  if (a->pointer < (start + length)) {
+  if (a->offset < (start + length)) {
     /* LDAP V3 Modify DN operation, with newSuperior */
     read_string(a, tree, hf_ldap_message_modrdn_superior, 0, 0, ASN1_UNI, ASN1_OTS);
   }
@@ -790,7 +793,7 @@ static int dissect_ldap_request_modifyrdn(ASN1_SCK *a, proto_tree *tree,
 
 static int dissect_ldap_request_compare(ASN1_SCK *a, proto_tree *tree)
 {
-  const guchar *start;
+  int start;
   int length;
   char *string1 = 0;
   char *string2 = 0;
@@ -799,14 +802,15 @@ static int dissect_ldap_request_compare(ASN1_SCK *a, proto_tree *tree)
   read_string(a, tree, hf_ldap_message_dn, 0, 0, ASN1_UNI, ASN1_OTS);
   read_sequence(a, 0);
 
-  start = a->pointer;
+  start = a->offset;
   read_string(a, 0, -1, 0, &string1, ASN1_UNI, ASN1_OTS);
   read_string(a, 0, -1, 0, &string2, ASN1_UNI, ASN1_OTS);
 
   length = 2 + strlen(string1) + strlen(string2);
   compare = g_malloc0(length);
   snprintf(compare, length, "%s=%s", string1, string2);
-  proto_tree_add_string(tree, hf_ldap_message_compare, NullTVB, start-a->begin, a->pointer-start, compare);
+  proto_tree_add_string(tree, hf_ldap_message_compare, a->tvb, start,
+      a->offset-start, compare);
   
   g_free(string1);
   g_free(string2);
@@ -818,16 +822,16 @@ static int dissect_ldap_request_compare(ASN1_SCK *a, proto_tree *tree)
 static int dissect_ldap_request_modify(ASN1_SCK *a, proto_tree *tree)
 {
   guint seq_length;
-  const guchar *end_of_sequence;
+  int end_of_sequence;
   
   read_string(a, tree, hf_ldap_message_dn, 0, 0, ASN1_UNI, ASN1_OTS);
   read_sequence(a, &seq_length);
-  end_of_sequence = a->pointer + seq_length;
-  while (a->pointer < end_of_sequence)
+  end_of_sequence = a->offset + seq_length;
+  while (a->offset < end_of_sequence)
   {
     proto_tree *t = 0, *attr_tree;
     guint set_length;
-    const guchar *end_of_set;
+    int end_of_set;
     guint operation;
 
     read_sequence(a, 0);
@@ -849,8 +853,8 @@ static int dissect_ldap_request_modify(ASN1_SCK *a, proto_tree *tree)
     attr_tree = proto_item_add_subtree(t, ett_ldap_attribute);
 
     read_set(a, &set_length);
-    end_of_set = a->pointer + set_length;
-    while (a->pointer < end_of_set)
+    end_of_set = a->offset + set_length;
+    while (a->offset < end_of_set)
       read_string(a, attr_tree, hf_ldap_message_value, 0, 0, ASN1_UNI, ASN1_OTS);
   }
 
@@ -858,7 +862,7 @@ static int dissect_ldap_request_modify(ASN1_SCK *a, proto_tree *tree)
 }
 
 static int dissect_ldap_request_abandon(ASN1_SCK *a, proto_tree *tree,
-               const guchar *start, guint length)
+               int start, guint length)
 {
   read_integer_value(a, tree, hf_ldap_message_abandon_msgid, NULL, NULL,
                        start, length); 
@@ -866,8 +870,9 @@ static int dissect_ldap_request_abandon(ASN1_SCK *a, proto_tree *tree,
 }
 
 static void
-dissect_ldap(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
+dissect_ldap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
+  int offset = 0;
   proto_tree *ldap_tree = 0, *ti, *msg_tree;
   guint messageLength;
   guint messageId;
@@ -875,49 +880,38 @@ dissect_ldap(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
   gchar *typestr;
   guint opLen;
   ASN1_SCK a;
-  const guchar *start;
+  int start;
   int first_time = 1;
   int ret;
 
-  OLD_CHECK_DISPLAY_AS_DATA(proto_ldap, pd, offset, fd, tree);
-
   if (tree) 
   {
-    ti = proto_tree_add_item(tree, proto_ldap, NullTVB, offset, END_OF_FRAME, FALSE);
+    ti = proto_tree_add_item(tree, proto_ldap, tvb, offset, tvb_length(tvb),
+                            FALSE);
     ldap_tree = proto_item_add_subtree(ti, ett_ldap);
   }
 
-  asn1_open(&a, pd, pi.captured_len);
-  a.pointer += offset;
+  asn1_open(&a, tvb, 0);
 
-  while (a.pointer < a.end)
+  while (tvb_reported_length_remaining(tvb, offset) > 0)
   {
     int message_id_start;
     int message_id_length;
     int message_start;
     
-    message_start = a.pointer - a.begin;
+    message_start = a.offset;
     if (read_sequence(&a, &messageLength))
     {
       if (ldap_tree)
-        proto_tree_add_text(ldap_tree, NullTVB, offset, 1, "Invalid LDAP packet");
+        proto_tree_add_text(ldap_tree, tvb, offset, 1, "Invalid LDAP packet");
       break;
     }
 
-    if (messageLength > (a.end - a.pointer))
-    {
-      if (ldap_tree)
-        proto_tree_add_text(ldap_tree, NullTVB, message_start, END_OF_FRAME,
-                           "Short message! (expected: %u, actual: %lu)",
-                           messageLength, (unsigned long)(a.end - a.pointer));
-      break;
-    }
-  
-    message_id_start = a.pointer - a.begin;
+    message_id_start = a.offset;
     read_integer(&a, 0, -1, 0, &messageId, ASN1_INT);
-    message_id_length = (a.pointer - a.begin) - message_id_start;
+    message_id_length = a.offset - message_id_start;
 
-    start = a.pointer;
+    start = a.offset;
     asn1_id_decode(&a, &protocolOpCls, &protocolOpCon, &protocolOpTag);
     if (protocolOpCls != ASN1_APL)
       typestr = "Bad message type (not Application)";
@@ -926,11 +920,11 @@ dissect_ldap(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
 
     if (first_time)
     {
-      if (check_col(fd, COL_PROTOCOL))
-        col_set_str(fd, COL_PROTOCOL, "LDAP");
+      if (check_col(pinfo->fd, COL_PROTOCOL))
+        col_set_str(pinfo->fd, COL_PROTOCOL, "LDAP");
 
-      if (check_col(fd, COL_INFO))
-        col_add_fstr(fd, COL_INFO, "MsgId=%u MsgType=%s",
+      if (check_col(pinfo->fd, COL_INFO))
+        col_add_fstr(pinfo->fd, COL_INFO, "MsgId=%u MsgType=%s",
                     messageId, typestr);
       first_time = 0;
       if (!tree)
@@ -939,12 +933,12 @@ dissect_ldap(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
 
     if (ldap_tree) 
     {
-      proto_tree_add_uint_hidden(ldap_tree, hf_ldap_message_id, NullTVB, message_id_start, message_id_length, messageId);
-      proto_tree_add_uint_hidden(ldap_tree, hf_ldap_message_type, NullTVB,
-                                start - a.begin, a.pointer - start, protocolOpTag);
-      ti = proto_tree_add_text(ldap_tree, NullTVB, message_id_start, messageLength, "Message: Id=%u  %s", messageId, typestr);
+      proto_tree_add_uint_hidden(ldap_tree, hf_ldap_message_id, tvb, message_id_start, message_id_length, messageId);
+      proto_tree_add_uint_hidden(ldap_tree, hf_ldap_message_type, tvb,
+                                start, a.offset - start, protocolOpTag);
+      ti = proto_tree_add_text(ldap_tree, tvb, message_id_start, messageLength, "Message: Id=%u  %s", messageId, typestr);
       msg_tree = proto_item_add_subtree(ti, ett_ldap_message);
-      start = a.pointer;
+      start = a.offset;
       read_length(&a, msg_tree, hf_ldap_message_length, &opLen);
 
       switch (protocolOpTag)
@@ -954,8 +948,7 @@ dissect_ldap(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
         break;
        case LDAP_REQ_SEARCH:
         ret = dissect_ldap_request_search(&a, msg_tree);
-        if (ret != ASN1_ERR_NOERROR)
-          break;
+        /* XXX - do somethign with "ret" */
         break;
        case LDAP_REQ_ADD:
         dissect_ldap_request_add(&a, msg_tree);
@@ -991,6 +984,7 @@ dissect_ldap(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
         break;
       }
     }
+    offset = a.offset;
   }
 }
 
@@ -1210,5 +1204,5 @@ proto_register_ldap(void)
 void
 proto_reg_handoff_ldap(void)
 {
-  old_dissector_add("tcp.port", TCP_PORT_LDAP, dissect_ldap, proto_ldap);
+  dissector_add("tcp.port", TCP_PORT_LDAP, dissect_ldap, proto_ldap);
 }
index 70f84d0183c797db77ba09b8b9324a22d5a361c5..3539a655c79cd12a55ad1c3380820430b28f8129 100644 (file)
@@ -8,7 +8,7 @@
  *
  * See RFCs 1905, 1906, 1909, and 1910 for SNMPv2u.
  *
- * $Id: packet-snmp.c,v 1.63 2001/04/07 08:23:58 guy Exp $
+ * $Id: packet-snmp.c,v 1.64 2001/04/15 07:30:03 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -519,17 +519,13 @@ snmp_tag_cls2syntax ( guint tag, guint cls, gushort *syntax)
 }
 
 static void
-dissect_snmp_parse_error(const u_char *pd, int offset, frame_data *fd,
+dissect_snmp_parse_error(tvbuff_t *tvb, int offset, packet_info *pinfo,
                   proto_tree *tree, const char *field_name, int ret)
 {
        const gchar *errstr;
 
        switch (ret) {
 
-       case ASN1_ERR_EMPTY:
-               errstr = "Ran out of data";
-               break;
-
        case ASN1_ERR_EOC_MISMATCH:
                errstr = "EOC mismatch";
                break;
@@ -555,27 +551,27 @@ dissect_snmp_parse_error(const u_char *pd, int offset, frame_data *fd,
                break;
        }
 
-       if (check_col(fd, COL_INFO)) {
-               col_add_fstr(fd, COL_INFO,
+       if (check_col(pinfo->fd, COL_INFO)) {
+               col_add_fstr(pinfo->fd, COL_INFO,
                    "ERROR: Couldn't parse %s: %s", field_name, errstr);
        }
        if (tree != NULL) {
-               proto_tree_add_text(tree, NullTVB, offset, 0,
+               proto_tree_add_text(tree, tvb, offset, 0,
                    "ERROR: Couldn't parse %s: %s", field_name, errstr);
-               old_dissect_data(pd, offset, fd, tree);
+               dissect_data(tvb, offset, pinfo, tree);
        }
 }
 
 static void
-dissect_snmp_error(const u_char *pd, int offset, frame_data *fd,
+dissect_snmp_error(tvbuff_t *tvb, int offset, packet_info *pinfo,
                   proto_tree *tree, const char *message)
 {
-       if (check_col(fd, COL_INFO))
-               col_add_str(fd, COL_INFO, message);
+       if (check_col(pinfo->fd, COL_INFO))
+               col_add_str(pinfo->fd, COL_INFO, message);
 
        if (tree != NULL) {
-               proto_tree_add_text(tree, NullTVB, offset, 0, "%s", message);
-               old_dissect_data(pd, offset, fd, tree);
+               proto_tree_add_text(tree, tvb, offset, 0, "%s", message);
+               dissect_data(tvb, offset, pinfo, tree);
        }
 }
 
@@ -705,7 +701,7 @@ snmp_variable_decode(proto_tree *snmp_tree, subid_t *variable_oid,
     guint variable_oid_length, ASN1_SCK *asn1, int offset, guint *lengthp,
     gboolean unsafe)
 {
-       const guchar *start;
+       int start;
        guint length;
        gboolean def;
        guint vb_length;
@@ -735,7 +731,7 @@ snmp_variable_decode(proto_tree *snmp_tree, subid_t *variable_oid,
        int len;
 
        /* parse the type of the object */
-       start = asn1->pointer;
+       start = asn1->offset;
        ret = asn1_header_decode (asn1, &cls, &con, &tag, &def, &vb_length);
        if (ret != ASN1_ERR_NOERROR)
                return ret;
@@ -761,7 +757,7 @@ snmp_variable_decode(proto_tree *snmp_tree, subid_t *variable_oid,
                    &vb_integer_value);
                if (ret != ASN1_ERR_NOERROR)
                        return ret;
-               length = asn1->pointer - start;
+               length = asn1->offset - start;
                if (snmp_tree) {
 #ifdef HAVE_SPRINT_VALUE
                        if (!unsafe) {
@@ -774,14 +770,14 @@ snmp_variable_decode(proto_tree *snmp_tree, subid_t *variable_oid,
                                vb_display_string = format_var(&variable,
                                    variable_oid, variable_oid_length, vb_type,
                                    vb_length);
-                               proto_tree_add_text(snmp_tree, NullTVB, offset,
+                               proto_tree_add_text(snmp_tree, asn1->tvb, offset,
                                    length,
                                    "Value: %s", vb_display_string);
                                g_free(vb_display_string);
                                break;  /* we added formatted version to the tree */
                        }
 #endif /* HAVE_SPRINT_VALUE */
-                       proto_tree_add_text(snmp_tree, NullTVB, offset, length,
+                       proto_tree_add_text(snmp_tree, asn1->tvb, offset, length,
                            "Value: %s: %d (%#x)", vb_type_name,
                            vb_integer_value, vb_integer_value);
                }
@@ -794,7 +790,7 @@ snmp_variable_decode(proto_tree *snmp_tree, subid_t *variable_oid,
                    &vb_uinteger_value);
                if (ret != ASN1_ERR_NOERROR)
                        return ret;
-               length = asn1->pointer - start;
+               length = asn1->offset - start;
                if (snmp_tree) {
 #ifdef HAVE_SPRINT_VALUE
                        if (!unsafe) {
@@ -807,14 +803,14 @@ snmp_variable_decode(proto_tree *snmp_tree, subid_t *variable_oid,
                                vb_display_string = format_var(&variable,
                                    variable_oid, variable_oid_length, vb_type,
                                    vb_length);
-                               proto_tree_add_text(snmp_tree, NullTVB, offset,
+                               proto_tree_add_text(snmp_tree, asn1->tvb, offset,
                                    length,
                                    "Value: %s", vb_display_string);
                                g_free(vb_display_string);
                                break;  /* we added formatted version to the tree */
                        }
 #endif /* HAVE_SPRINT_VALUE */
-                       proto_tree_add_text(snmp_tree, NullTVB, offset, length,
+                       proto_tree_add_text(snmp_tree, asn1->tvb, offset, length,
                            "Value: %s: %u (%#x)", vb_type_name,
                            vb_uinteger_value, vb_uinteger_value);
                }
@@ -830,7 +826,7 @@ snmp_variable_decode(proto_tree *snmp_tree, subid_t *variable_oid,
                    &vb_octet_string);
                if (ret != ASN1_ERR_NOERROR)
                        return ret;
-               length = asn1->pointer - start;
+               length = asn1->offset - start;
                if (snmp_tree) {
 #ifdef HAVE_SPRINT_VALUE
                        if (!unsafe) {
@@ -838,7 +834,7 @@ snmp_variable_decode(proto_tree *snmp_tree, subid_t *variable_oid,
                                vb_display_string = format_var(&variable,
                                    variable_oid, variable_oid_length, vb_type,
                                    vb_length);
-                               proto_tree_add_text(snmp_tree, NullTVB, offset,
+                               proto_tree_add_text(snmp_tree, asn1->tvb, offset,
                                    length,
                                    "Value: %s", vb_display_string);
                                g_free(vb_display_string);
@@ -869,12 +865,12 @@ snmp_variable_decode(proto_tree *snmp_tree, subid_t *variable_oid,
                                            vb_octet_string[i]);
                                        buf += len;
                                }
-                               proto_tree_add_text(snmp_tree, NullTVB, offset, length,
+                               proto_tree_add_text(snmp_tree, asn1->tvb, offset, length,
                                    "Value: %s: %s", vb_type_name,
                                    vb_display_string);
                                g_free(vb_display_string);
                        } else {
-                               proto_tree_add_text(snmp_tree, NullTVB, offset, length,
+                               proto_tree_add_text(snmp_tree, asn1->tvb, offset, length,
                                    "Value: %s: %.*s", vb_type_name,
                                    (int)vb_length,
                                    SAFE_STRING(vb_octet_string));
@@ -887,9 +883,9 @@ snmp_variable_decode(proto_tree *snmp_tree, subid_t *variable_oid,
                ret = asn1_null_decode (asn1, vb_length);
                if (ret != ASN1_ERR_NOERROR)
                        return ret;
-               length = asn1->pointer - start;
+               length = asn1->offset - start;
                if (snmp_tree) {
-                       proto_tree_add_text(snmp_tree, NullTVB, offset, length,
+                       proto_tree_add_text(snmp_tree, asn1->tvb, offset, length,
                            "Value: %s", vb_type_name);
                }
                break;
@@ -899,7 +895,7 @@ snmp_variable_decode(proto_tree *snmp_tree, subid_t *variable_oid,
                    &vb_oid_length);
                if (ret != ASN1_ERR_NOERROR)
                        return ret;
-               length = asn1->pointer - start;
+               length = asn1->offset - start;
                if (snmp_tree) {
 #ifdef HAVE_SPRINT_VALUE
                        if (!unsafe) {
@@ -907,14 +903,14 @@ snmp_variable_decode(proto_tree *snmp_tree, subid_t *variable_oid,
                                vb_display_string = format_var(&variable,
                                    variable_oid, variable_oid_length, vb_type,
                                    vb_length);
-                               proto_tree_add_text(snmp_tree, NullTVB, offset,
+                               proto_tree_add_text(snmp_tree, asn1->tvb, offset,
                                    length,
                                    "Value: %s", vb_display_string);
                                break;  /* we added formatted version to the tree */
                        }
 #endif /* HAVE_SPRINT_VALUE */
                        vb_display_string = format_oid(vb_oid, vb_oid_length);
-                       proto_tree_add_text(snmp_tree, NullTVB, offset, length,
+                       proto_tree_add_text(snmp_tree, asn1->tvb, offset, length,
                            "Value: %s: %s", vb_type_name, vb_display_string);
                        g_free(vb_display_string);
                }
@@ -922,25 +918,25 @@ snmp_variable_decode(proto_tree *snmp_tree, subid_t *variable_oid,
                break;
 
        case SNMP_NOSUCHOBJECT:
-               length = asn1->pointer - start;
+               length = asn1->offset - start;
                if (snmp_tree) {
-                       proto_tree_add_text(snmp_tree, NullTVB, offset, length,
+                       proto_tree_add_text(snmp_tree, asn1->tvb, offset, length,
                            "Value: %s: no such object", vb_type_name);
                }
                break;
 
        case SNMP_NOSUCHINSTANCE:
-               length = asn1->pointer - start;
+               length = asn1->offset - start;
                if (snmp_tree) {
-                       proto_tree_add_text(snmp_tree, NullTVB, offset, length,
+                       proto_tree_add_text(snmp_tree, asn1->tvb, offset, length,
                            "Value: %s: no such instance", vb_type_name);
                }
                break;
 
        case SNMP_ENDOFMIBVIEW:
-               length = asn1->pointer - start;
+               length = asn1->offset - start;
                if (snmp_tree) {
-                       proto_tree_add_text(snmp_tree, NullTVB, offset, length,
+                       proto_tree_add_text(snmp_tree, asn1->tvb, offset, length,
                            "Value: %s: end of mib view", vb_type_name);
                }
                break;
@@ -954,8 +950,8 @@ snmp_variable_decode(proto_tree *snmp_tree, subid_t *variable_oid,
 }
 
 static void
-dissect_common_pdu(const u_char *pd, int offset, frame_data *fd,
-    proto_tree *tree, ASN1_SCK asn1, guint pdu_type, const guchar *start)
+dissect_common_pdu(tvbuff_t *tvb, int offset, packet_info *pinfo,
+    proto_tree *tree, ASN1_SCK asn1, guint pdu_type, int start)
 {
        gboolean def;
        guint length;
@@ -1000,9 +996,9 @@ dissect_common_pdu(const u_char *pd, int offset, frame_data *fd,
 
        pdu_type_string = val_to_str(pdu_type, pdu_types,
            "Unknown PDU type %#x");
-       if (check_col(fd, COL_INFO))
-               col_add_str(fd, COL_INFO, pdu_type_string);
-       length = asn1.pointer - start;
+       if (check_col(pinfo->fd, COL_INFO))
+               col_add_str(pinfo->fd, COL_INFO, pdu_type_string);
+       length = asn1.offset - start;
        if (tree) {
                proto_tree_add_text(tree, NullTVB, offset, length,
                    "PDU type: %s", pdu_type_string);
@@ -1023,7 +1019,7 @@ dissect_common_pdu(const u_char *pd, int offset, frame_data *fd,
                /* request id */
                ret = asn1_uint32_decode (&asn1, &request_id, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, tree,
                            "request ID", ret);
                        return;
                }
@@ -1036,7 +1032,7 @@ dissect_common_pdu(const u_char *pd, int offset, frame_data *fd,
                /* error status, or getbulk non-repeaters */
                ret = asn1_uint32_decode (&asn1, &error_status, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, tree,
                            (pdu_type == SNMP_MSG_GETBULK) ? "non-repeaters"
                                                           : "error status",
                            ret);
@@ -1058,7 +1054,7 @@ dissect_common_pdu(const u_char *pd, int offset, frame_data *fd,
                /* error index, or getbulk max-repetitions */
                ret = asn1_uint32_decode (&asn1, &error_index, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, tree,
                            (pdu_type == SNMP_MSG_GETBULK) ? "max repetitions"
                                                           : "error index",
                            ret);
@@ -1081,7 +1077,7 @@ dissect_common_pdu(const u_char *pd, int offset, frame_data *fd,
                ret = asn1_oid_decode (&asn1, &enterprise, &enterprise_length,
                    &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, tree,
                            "enterprise OID", ret);
                        return;
                }
@@ -1095,11 +1091,11 @@ dissect_common_pdu(const u_char *pd, int offset, frame_data *fd,
                offset += length;
 
                /* agent address */
-               start = asn1.pointer;
+               start = asn1.offset;
                ret = asn1_header_decode (&asn1, &cls, &con, &tag,
                    &def, &agent_address_length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, tree,
                            "agent address", ret);
                        return;
                }
@@ -1107,23 +1103,23 @@ dissect_common_pdu(const u_char *pd, int offset, frame_data *fd,
                    (cls == ASN1_UNI && con == ASN1_PRI && tag == ASN1_OTS))) {
                        /* GXSNMP 0.0.15 says the latter is "needed for
                           Banyan" */
-                       dissect_snmp_parse_error(pd, offset, fd, tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, tree,
                            "agent_address", ASN1_ERR_WRONG_TYPE);
                        return;
                }
                if (agent_address_length != 4) {
-                       dissect_snmp_parse_error(pd, offset, fd, tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, tree,
                            "agent_address", ASN1_ERR_WRONG_LENGTH_FOR_TYPE);
                        return;
                }
                ret = asn1_string_value_decode (&asn1,
                    agent_address_length, &agent_address);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, tree,
                            "agent address", ret);
                        return;
                }
-               length = asn1.pointer - start;
+               length = asn1.offset - start;
                if (tree) {
                        if (agent_address_length != 4) {
                                proto_tree_add_text(tree, NullTVB, offset,
@@ -1143,7 +1139,7 @@ dissect_common_pdu(const u_char *pd, int offset, frame_data *fd,
                /* generic trap type */
                ret = asn1_uint32_decode (&asn1, &trap_type, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, tree,
                            "generic trap type", ret);
                        return;
                }
@@ -1157,7 +1153,7 @@ dissect_common_pdu(const u_char *pd, int offset, frame_data *fd,
                /* specific trap type */
                ret = asn1_uint32_decode (&asn1, &specific_type, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, tree,
                            "specific trap type", ret);
                        return;
                }
@@ -1169,28 +1165,28 @@ dissect_common_pdu(const u_char *pd, int offset, frame_data *fd,
                offset += length;
                
                /* timestamp */
-               start = asn1.pointer;
+               start = asn1.offset;
                ret = asn1_header_decode (&asn1, &cls, &con, &tag,
                    &def, &timestamp_length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, tree,
                            "timestamp", ret);
                        return;
                }
                if (!((cls == ASN1_APL && con == ASN1_PRI && tag == SNMP_TIT) ||
                    (cls == ASN1_UNI && con == ASN1_PRI && tag == ASN1_INT))) {
-                       dissect_snmp_parse_error(pd, offset, fd, tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, tree,
                            "timestamp", ASN1_ERR_WRONG_TYPE);
                        return;
                }
                ret = asn1_uint32_value_decode(&asn1, timestamp_length,
                    &timestamp);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, tree,
                            "timestamp", ret);
                        return;
                }
-               length = asn1.pointer - start;
+               length = asn1.offset - start;
                if (tree) {
                        proto_tree_add_text(tree, NullTVB, offset, length,
                            "Timestamp: %u", timestamp);
@@ -1203,7 +1199,7 @@ dissect_common_pdu(const u_char *pd, int offset, frame_data *fd,
        /* get header for variable-bindings sequence */
        ret = asn1_sequence_decode(&asn1, &variable_bindings_length, &length);
        if (ret != ASN1_ERR_NOERROR) {
-               dissect_snmp_parse_error(pd, offset, fd, tree,
+               dissect_snmp_parse_error(tvb, offset, pinfo, tree,
                        "variable bindings header", ret);
                return;
        }
@@ -1218,7 +1214,7 @@ dissect_common_pdu(const u_char *pd, int offset, frame_data *fd,
                /* parse type */
                ret = asn1_sequence_decode(&asn1, &variable_length, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, tree,
                                "variable binding header", ret);
                        return;
                }
@@ -1228,7 +1224,7 @@ dissect_common_pdu(const u_char *pd, int offset, frame_data *fd,
                ret = asn1_oid_decode (&asn1, &variable_oid,
                    &variable_oid_length, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, tree,
                            "variable binding OID", ret);
                        return;
                }
@@ -1287,7 +1283,7 @@ dissect_common_pdu(const u_char *pd, int offset, frame_data *fd,
                    variable_oid_length, &asn1, offset, &length,
                    unsafe);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, tree,
                            "variable", ret);
                        return;
                }
@@ -1426,11 +1422,11 @@ dissect_snmp2u_parameters(proto_tree *tree, int offset, int length,
 }
 
 void
-dissect_snmp_pdu(const u_char *pd, int offset, frame_data *fd,
+dissect_snmp_pdu(tvbuff_t *tvb, int offset, packet_info *pinfo,
     proto_tree *tree, char *proto_name, int proto, gint ett)
 {
        ASN1_SCK asn1;
-       const guchar *start;
+       int start;
        gboolean def;
        gboolean encrypted;
        guint length;
@@ -1476,11 +1472,11 @@ dissect_snmp_pdu(const u_char *pd, int offset, frame_data *fd,
        int ret;
        guint cls, con, tag;
 
-       if (check_col(fd, COL_PROTOCOL))
-               col_add_str(fd, COL_PROTOCOL, proto_name);
+       if (check_col(pinfo->fd, COL_PROTOCOL))
+               col_add_str(pinfo->fd, COL_PROTOCOL, proto_name);
 
        if (tree) {
-               item = proto_tree_add_item(tree, proto, NullTVB, offset,
+               item = proto_tree_add_item(tree, proto, tvb, offset,
                    END_OF_FRAME, FALSE);
                snmp_tree = proto_item_add_subtree(item, ett);
        }
@@ -1490,10 +1486,10 @@ dissect_snmp_pdu(const u_char *pd, int offset, frame_data *fd,
         * parsing is likely to fail.
         */
        /* parse the SNMP header */
-       asn1_open(&asn1, &pd[offset], END_OF_FRAME);
+       asn1_open(&asn1, tvb, offset);
        ret = asn1_sequence_decode(&asn1, &message_length, &length);
        if (ret != ASN1_ERR_NOERROR) {
-               dissect_snmp_parse_error(pd, offset, fd, snmp_tree,
+               dissect_snmp_parse_error(tvb, offset, pinfo, snmp_tree,
                        "message header", ret);
                return;
        }
@@ -1501,12 +1497,12 @@ dissect_snmp_pdu(const u_char *pd, int offset, frame_data *fd,
 
        ret = asn1_uint32_decode (&asn1, &version, &length);
        if (ret != ASN1_ERR_NOERROR) {
-               dissect_snmp_parse_error(pd, offset, fd, snmp_tree,
+               dissect_snmp_parse_error(tvb, offset, pinfo, snmp_tree,
                    "version number", ret);
                return;
        }
        if (snmp_tree) {
-               proto_tree_add_text(snmp_tree, NullTVB, offset, length,
+               proto_tree_add_text(snmp_tree, tvb, offset, length,
                    "Version: %s",
                    val_to_str(version, versions, "Unknown version %#x"));
        }
@@ -1519,12 +1515,12 @@ dissect_snmp_pdu(const u_char *pd, int offset, frame_data *fd,
                ret = asn1_octet_string_decode (&asn1, &community, 
                    &community_length, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, snmp_tree, 
+                       dissect_snmp_parse_error(tvb, offset, pinfo, snmp_tree, 
                            "community", ret);
                        return;
                }
                if (tree) {
-                       proto_tree_add_text(snmp_tree, NullTVB, offset, length,
+                       proto_tree_add_text(snmp_tree, tvb, offset, length,
                            "Community: %.*s", community_length,
                            SAFE_STRING(community));
                }
@@ -1544,77 +1540,77 @@ dissect_snmp_pdu(const u_char *pd, int offset, frame_data *fd,
        case SNMP_VERSION_3:
                ret = asn1_sequence_decode(&asn1, &global_length, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, snmp_tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, snmp_tree,
                                "message global header", ret);
                        return;
                }
                if (snmp_tree) {
-                       item = proto_tree_add_text(snmp_tree, NullTVB, offset,
+                       item = proto_tree_add_text(snmp_tree, tvb, offset,
                            global_length + length, "Message Global Header");
                        global_tree = proto_item_add_subtree(item, ett_global);
-                       proto_tree_add_text(global_tree, NullTVB, offset,
+                       proto_tree_add_text(global_tree, tvb, offset,
                            length,
                            "Message Global Header Length: %d", global_length);
                }
                offset += length;
                ret = asn1_uint32_decode (&asn1, &msgid, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, snmp_tree, 
+                       dissect_snmp_parse_error(tvb, offset, pinfo, snmp_tree, 
                            "message id", ret);
                        return;
                }
                if (global_tree) {
-                       proto_tree_add_text(global_tree, NullTVB, offset,
+                       proto_tree_add_text(global_tree, tvb, offset,
                            length, "Message ID: %d", msgid);
                }
                offset += length;
                ret = asn1_uint32_decode (&asn1, &msgmax, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, snmp_tree, 
+                       dissect_snmp_parse_error(tvb, offset, pinfo, snmp_tree, 
                            "message max size", ret);
                        return;
                }
                if (global_tree) {
-                       proto_tree_add_text(global_tree, NullTVB, offset,
+                       proto_tree_add_text(global_tree, tvb, offset,
                            length, "Message Max Size: %d", msgmax);
                }
                offset += length;
                ret = asn1_octet_string_decode (&asn1, &msgflags, 
                    &msgflags_length, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, snmp_tree, 
+                       dissect_snmp_parse_error(tvb, offset, pinfo, snmp_tree, 
                            "message flags", ret);
                        return;
                }
                if (msgflags_length != 1) {
-                       dissect_snmp_parse_error(pd, offset, fd, snmp_tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, snmp_tree,
                            "message flags wrong length", ret);
                        g_free(msgflags);
                        return;
                }
                if (global_tree) {
                        item = proto_tree_add_uint_format(global_tree,
-                           hf_snmpv3_flags, NullTVB, offset, length,
+                           hf_snmpv3_flags, tvb, offset, length,
                            msgflags[0], "Flags: 0x%02x", msgflags[0]);
                        flags_tree = proto_item_add_subtree(item, ett_flags);
                        proto_tree_add_boolean(flags_tree, hf_snmpv3_flags_report,
-                           NullTVB, offset, length, msgflags[0]);
+                           tvb, offset, length, msgflags[0]);
                        proto_tree_add_boolean(flags_tree, hf_snmpv3_flags_crypt,
-                           NullTVB, offset, length, msgflags[0]);
+                           tvb, offset, length, msgflags[0]);
                        proto_tree_add_boolean(flags_tree, hf_snmpv3_flags_auth,
-                           NullTVB, offset, length, msgflags[0]);
+                           tvb, offset, length, msgflags[0]);
                }
                encrypted = msgflags[0] & TH_CRYPT;
                g_free(msgflags);
                offset += length;
                ret = asn1_uint32_decode (&asn1, &msgsec, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, snmp_tree, 
+                       dissect_snmp_parse_error(tvb, offset, pinfo, snmp_tree, 
                            "message security model", ret);
                        return;
                }
                if (global_tree) {
-                       proto_tree_add_text(global_tree, NullTVB, offset,
+                       proto_tree_add_text(global_tree, tvb, offset,
                            length, "Message Security Model: %s",
                            val_to_str(msgsec, sec_models,
                            "Unknown model %#x"));
@@ -1622,24 +1618,24 @@ dissect_snmp_pdu(const u_char *pd, int offset, frame_data *fd,
                offset += length;
                switch(msgsec) {
                case SNMP_SEC_USM:
-                       start = asn1.pointer;
+                       start = asn1.offset;
                        ret = asn1_header_decode (&asn1, &cls, &con, &tag,
                            &def, &secparm_length);
-                       length = asn1.pointer - start;
+                       length = asn1.offset - start;
                        if (cls != ASN1_UNI && con != ASN1_PRI && 
                            tag != ASN1_OTS) {
-                               dissect_snmp_parse_error(pd, offset, fd,
+                               dissect_snmp_parse_error(tvb, offset, pinfo,
                                    snmp_tree, "Message Security Parameters",
                                    ASN1_ERR_WRONG_TYPE);
                                return;
                        }
                        if (snmp_tree) {
-                               item = proto_tree_add_text(snmp_tree, NullTVB,
+                               item = proto_tree_add_text(snmp_tree, tvb,
                                    offset, secparm_length + length,
                                    "Message Security Parameters");
                                secur_tree = proto_item_add_subtree(item,
                                    ett_secur);
-                               proto_tree_add_text(secur_tree, NullTVB, offset,
+                               proto_tree_add_text(secur_tree, tvb, offset,
                                    length, 
                                    "Message Security Parameters Length: %d",
                                    secparm_length);
@@ -1648,7 +1644,7 @@ dissect_snmp_pdu(const u_char *pd, int offset, frame_data *fd,
                        ret = asn1_sequence_decode(&asn1, &secparm_length,
                            &length);
                        if (ret != ASN1_ERR_NOERROR) {
-                               dissect_snmp_parse_error(pd, offset, fd,
+                               dissect_snmp_parse_error(tvb, offset, pinfo,
                                    snmp_tree, "USM sequence header", ret);
                                return;
                        }
@@ -1656,12 +1652,12 @@ dissect_snmp_pdu(const u_char *pd, int offset, frame_data *fd,
                        ret = asn1_octet_string_decode (&asn1, &aengineid, 
                            &aengineid_length, &length);
                        if (ret != ASN1_ERR_NOERROR) {
-                               dissect_snmp_parse_error(pd, offset, fd,
+                               dissect_snmp_parse_error(tvb, offset, pinfo,
                                    snmp_tree, "authoritative engine id", ret);
                                return;
                        }
                        if (secur_tree) {
-                               proto_tree_add_text(secur_tree, NullTVB, offset,
+                               proto_tree_add_text(secur_tree, tvb, offset,
                                    length, "Authoritative Engine ID: %s",
                                    bytes_to_str(aengineid, aengineid_length));
                        }
@@ -1669,24 +1665,24 @@ dissect_snmp_pdu(const u_char *pd, int offset, frame_data *fd,
                        offset += length;
                        ret = asn1_uint32_decode (&asn1, &engineboots, &length);
                        if (ret != ASN1_ERR_NOERROR) {
-                               dissect_snmp_parse_error(pd, offset, fd,
+                               dissect_snmp_parse_error(tvb, offset, pinfo,
                                    snmp_tree, "engine boots", ret);
                                return;
                        }
                        if (secur_tree) {
-                               proto_tree_add_text(secur_tree, NullTVB,
+                               proto_tree_add_text(secur_tree, tvb,
                                    offset, length, "Engine Boots: %d", 
                                    engineboots);
                        }
                        offset += length;
                        ret = asn1_uint32_decode (&asn1, &enginetime, &length);
                        if (ret != ASN1_ERR_NOERROR) {
-                               dissect_snmp_parse_error(pd, offset, fd,
+                               dissect_snmp_parse_error(tvb, offset, pinfo,
                                    snmp_tree,  "engine time", ret);
                                return;
                        }
                        if (secur_tree) {
-                               proto_tree_add_text(secur_tree, NullTVB,
+                               proto_tree_add_text(secur_tree, tvb,
                                    offset, length, "Engine Time: %d", 
                                    enginetime);
                        }
@@ -1694,12 +1690,12 @@ dissect_snmp_pdu(const u_char *pd, int offset, frame_data *fd,
                        ret = asn1_octet_string_decode (&asn1, &username, 
                            &username_length, &length);
                        if (ret != ASN1_ERR_NOERROR) {
-                               dissect_snmp_parse_error(pd, offset, fd,
+                               dissect_snmp_parse_error(tvb, offset, pinfo,
                                    snmp_tree, "user name", ret);
                                return;
                        }
                        if (secur_tree) {
-                               proto_tree_add_text(secur_tree, NullTVB, offset,
+                               proto_tree_add_text(secur_tree, tvb, offset,
                                    length, "User Name: %.*s", 
                                    username_length,
                                    SAFE_STRING(username));
@@ -1709,12 +1705,12 @@ dissect_snmp_pdu(const u_char *pd, int offset, frame_data *fd,
                        ret = asn1_octet_string_decode (&asn1, &authpar, 
                            &authpar_length, &length);
                        if (ret != ASN1_ERR_NOERROR) {
-                               dissect_snmp_parse_error(pd, offset, fd,
+                               dissect_snmp_parse_error(tvb, offset, pinfo,
                                    snmp_tree, "authentication parameter", ret);
                                return;
                        }
                        if (secur_tree) {
-                               proto_tree_add_text(secur_tree, NullTVB, offset,
+                               proto_tree_add_text(secur_tree, tvb, offset,
                                    length, "Authentication Parameter: %s",
                                    bytes_to_str(authpar, authpar_length));
                        }
@@ -1723,12 +1719,12 @@ dissect_snmp_pdu(const u_char *pd, int offset, frame_data *fd,
                        ret = asn1_octet_string_decode (&asn1, &privpar, 
                            &privpar_length, &length);
                        if (ret != ASN1_ERR_NOERROR) {
-                               dissect_snmp_parse_error(pd, offset, fd,
+                               dissect_snmp_parse_error(tvb, offset, pinfo,
                                    snmp_tree, "privacy parameter", ret);
                                return;
                        }
                        if (secur_tree) {
-                               proto_tree_add_text(secur_tree, NullTVB, offset,
+                               proto_tree_add_text(secur_tree, tvb, offset,
                                    length, "Privacy Parameter: %s",
                                    bytes_to_str(privpar, privpar_length));
                        }
@@ -1739,13 +1735,13 @@ dissect_snmp_pdu(const u_char *pd, int offset, frame_data *fd,
                        ret = asn1_octet_string_decode (&asn1, 
                            &secparm, &secparm_length, &length);
                        if (ret != ASN1_ERR_NOERROR) {
-                               dissect_snmp_parse_error(pd, offset, fd,
+                               dissect_snmp_parse_error(tvb, offset, pinfo,
                                    snmp_tree, "Message Security Parameters",
                                    ret);
                                return;
                        }
                        if (snmp_tree) {
-                               proto_tree_add_text(snmp_tree, NullTVB, offset,
+                               proto_tree_add_text(snmp_tree, tvb, offset,
                                    length,
                                    "Message Security Parameters Data"
                                    " (%d bytes)", secparm_length);
@@ -1759,20 +1755,20 @@ dissect_snmp_pdu(const u_char *pd, int offset, frame_data *fd,
                        ret = asn1_octet_string_decode (&asn1, &cryptpdu,
                            &cryptpdu_length, &length);
                        if (ret != ASN1_ERR_NOERROR) {
-                               dissect_snmp_parse_error(pd, offset, fd,
+                               dissect_snmp_parse_error(tvb, offset, pinfo,
                                    snmp_tree, "encrypted PDU header", ret);
                                return;
                        }
-                       proto_tree_add_text(snmp_tree, NullTVB, offset, length,
+                       proto_tree_add_text(snmp_tree, tvb, offset, length,
                            "Encrypted PDU (%d bytes)", length);
                        g_free(cryptpdu);
-                       if (check_col(fd, COL_INFO))
-                               col_set_str(fd, COL_INFO, "Encrypted PDU");
+                       if (check_col(pinfo->fd, COL_INFO))
+                               col_set_str(pinfo->fd, COL_INFO, "Encrypted PDU");
                        return;
                }
                ret = asn1_sequence_decode(&asn1, &global_length, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, snmp_tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, snmp_tree,
                                "PDU header", ret);
                        return;
                }
@@ -1780,12 +1776,12 @@ dissect_snmp_pdu(const u_char *pd, int offset, frame_data *fd,
                ret = asn1_octet_string_decode (&asn1, &cengineid, 
                    &cengineid_length, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, snmp_tree, 
+                       dissect_snmp_parse_error(tvb, offset, pinfo, snmp_tree, 
                            "context engine id", ret);
                        return;
                }
                if (snmp_tree) {
-                       proto_tree_add_text(snmp_tree, NullTVB, offset, length,
+                       proto_tree_add_text(snmp_tree, tvb, offset, length,
                            "Context Engine ID: %s",
                            bytes_to_str(cengineid, cengineid_length));
                }
@@ -1794,12 +1790,12 @@ dissect_snmp_pdu(const u_char *pd, int offset, frame_data *fd,
                ret = asn1_octet_string_decode (&asn1, &cname, 
                    &cname_length, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, snmp_tree, 
+                       dissect_snmp_parse_error(tvb, offset, pinfo, snmp_tree, 
                            "context name", ret);
                        return;
                }
                if (snmp_tree) {
-                       proto_tree_add_text(snmp_tree, NullTVB, offset, length,
+                       proto_tree_add_text(snmp_tree, tvb, offset, length,
                            "Context Name: %.*s", cname_length,
                            SAFE_STRING(cname));
                }
@@ -1807,33 +1803,33 @@ dissect_snmp_pdu(const u_char *pd, int offset, frame_data *fd,
                offset += length;
                break;
        default:
-               dissect_snmp_error(pd, offset, fd, snmp_tree,
+               dissect_snmp_error(tvb, offset, pinfo, snmp_tree,
                    "PDU for unknown version of SNMP");
                return;
        }
 
-       start = asn1.pointer;
+       start = asn1.offset;
        ret = asn1_header_decode (&asn1, &cls, &con, &pdu_type, &def,
            &pdu_length);
        if (ret != ASN1_ERR_NOERROR) {
-               dissect_snmp_parse_error(pd, offset, fd, snmp_tree,
+               dissect_snmp_parse_error(tvb, offset, pinfo, snmp_tree,
                    "PDU type", ret);
                return;
        }
        if (cls != ASN1_CTX || con != ASN1_CON) {
-               dissect_snmp_parse_error(pd, offset, fd, snmp_tree,
+               dissect_snmp_parse_error(tvb, offset, pinfo, snmp_tree,
                    "PDU type", ASN1_ERR_WRONG_TYPE);
                return;
        }
-       dissect_common_pdu(pd, offset, fd, snmp_tree, asn1, pdu_type, start);
+       dissect_common_pdu(tvb, offset, pinfo, snmp_tree, asn1, pdu_type, start);
 }
 
 static void
-dissect_smux_pdu(const u_char *pd, int offset, frame_data *fd,
+dissect_smux_pdu(tvbuff_t *tvb, int offset, packet_info *pinfo,
     proto_tree *tree, int proto, gint ett)
 {
        ASN1_SCK asn1;
-       const guchar *start;
+       int start;
        gboolean def;
        guint length;
 
@@ -1863,11 +1859,11 @@ dissect_smux_pdu(const u_char *pd, int offset, frame_data *fd,
        int ret;
        guint cls, con;
 
-       if (check_col(fd, COL_PROTOCOL))
-               col_set_str(fd, COL_PROTOCOL, "SMUX");
+       if (check_col(pinfo->fd, COL_PROTOCOL))
+               col_set_str(pinfo->fd, COL_PROTOCOL, "SMUX");
 
        if (tree) {
-               item = proto_tree_add_item(tree, proto, NullTVB, offset,
+               item = proto_tree_add_item(tree, proto, tvb, offset,
                    END_OF_FRAME, FALSE);
                smux_tree = proto_item_add_subtree(item, ett);
        }
@@ -1877,12 +1873,12 @@ dissect_smux_pdu(const u_char *pd, int offset, frame_data *fd,
         * parsing is likely to fail.
         */
        /* parse the SNMP header */
-       asn1_open(&asn1, &pd[offset], END_OF_FRAME);
-       start = asn1.pointer;
+       asn1_open(&asn1, tvb, offset);
+       start = asn1.offset;
        ret = asn1_header_decode (&asn1, &cls, &con, &pdu_type, &def,
            &pdu_length);
        if (ret != ASN1_ERR_NOERROR) {
-               dissect_snmp_parse_error(pd, offset, fd, smux_tree,
+               dissect_snmp_parse_error(tvb, offset, pinfo, smux_tree,
                    "PDU type", ret);
                return;
        }
@@ -1891,35 +1887,35 @@ dissect_smux_pdu(const u_char *pd, int offset, frame_data *fd,
        if (cls == ASN1_APL && con == ASN1_CON && pdu_type == SMUX_MSG_OPEN) {
                pdu_type_string = val_to_str(pdu_type, smux_types,
                    "Unknown PDU type %#x");
-               if (check_col(fd, COL_INFO))
-                       col_add_str(fd, COL_INFO, pdu_type_string);
-               length = asn1.pointer - start;
+               if (check_col(pinfo->fd, COL_INFO))
+                       col_add_str(pinfo->fd, COL_INFO, pdu_type_string);
+               length = asn1.offset - start;
                if (tree) {
-                       proto_tree_add_text(smux_tree, NullTVB, offset, length,
+                       proto_tree_add_text(smux_tree, tvb, offset, length,
                            "PDU type: %s", pdu_type_string);
                }
                offset += length;
                ret = asn1_uint32_decode (&asn1, &version, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, smux_tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, smux_tree,
                            "version", ret);
                        return;
                }
                if (tree) {
-                       proto_tree_add_text(smux_tree, NullTVB, offset, length,
+                       proto_tree_add_text(smux_tree, tvb, offset, length,
                            "Version: %d", version);
                }
                offset += length;
 
                ret = asn1_oid_decode (&asn1, &regid, &regid_length, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, smux_tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, smux_tree,
                            "registration OID", ret);
                        return;
                }
                if (tree) {
                        oid_string = format_oid(regid, regid_length);
-                       proto_tree_add_text(smux_tree, NullTVB, offset, length,
+                       proto_tree_add_text(smux_tree, tvb, offset, length,
                            "Registration: %s", oid_string);
                        g_free(oid_string);
                }
@@ -1929,12 +1925,12 @@ dissect_smux_pdu(const u_char *pd, int offset, frame_data *fd,
                ret = asn1_octet_string_decode (&asn1, &application, 
                    &application_length, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, smux_tree, 
+                       dissect_snmp_parse_error(tvb, offset, pinfo, smux_tree, 
                            "application", ret);
                        return;
                }
                if (tree) {
-                       proto_tree_add_text(smux_tree, NullTVB, offset, length,
+                       proto_tree_add_text(smux_tree, tvb, offset, length,
                            "Application: %.*s", application_length,
                             SAFE_STRING(application));
                }
@@ -1944,12 +1940,12 @@ dissect_smux_pdu(const u_char *pd, int offset, frame_data *fd,
                ret = asn1_octet_string_decode (&asn1, &password, 
                    &password_length, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, smux_tree, 
+                       dissect_snmp_parse_error(tvb, offset, pinfo, smux_tree, 
                            "password", ret);
                        return;
                }
                if (tree) {
-                       proto_tree_add_text(smux_tree, NullTVB, offset, length,
+                       proto_tree_add_text(smux_tree, tvb, offset, length,
                            "Password: %.*s", password_length,
                            SAFE_STRING(password));
                }
@@ -1960,22 +1956,22 @@ dissect_smux_pdu(const u_char *pd, int offset, frame_data *fd,
        if (cls == ASN1_APL && con == ASN1_PRI && pdu_type == SMUX_MSG_CLOSE) {
                pdu_type_string = val_to_str(pdu_type, smux_types,
                    "Unknown PDU type %#x");
-               if (check_col(fd, COL_INFO))
-                       col_add_str(fd, COL_INFO, pdu_type_string);
-               length = asn1.pointer - start;
+               if (check_col(pinfo->fd, COL_INFO))
+                       col_add_str(pinfo->fd, COL_INFO, pdu_type_string);
+               length = asn1.offset - start;
                if (tree) {
-                       proto_tree_add_text(smux_tree, NullTVB, offset, length,
+                       proto_tree_add_text(smux_tree, tvb, offset, length,
                            "PDU type: %s", pdu_type_string);
                }
                offset += length;
                ret = asn1_uint32_value_decode (&asn1, pdu_length, &cause);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, smux_tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, smux_tree,
                            "cause", ret);
                        return;
                }
                if (tree) {
-                       proto_tree_add_text(smux_tree, NullTVB, offset,
+                       proto_tree_add_text(smux_tree, tvb, offset,
                            pdu_length, "Cause: %s",
                            val_to_str(cause, smux_close, 
                                "Unknown cause %#x"));
@@ -1986,23 +1982,23 @@ dissect_smux_pdu(const u_char *pd, int offset, frame_data *fd,
        if (cls == ASN1_APL && con == ASN1_CON && pdu_type == SMUX_MSG_RREQ) {
                pdu_type_string = val_to_str(pdu_type, smux_types,
                    "Unknown PDU type %#x");
-               if (check_col(fd, COL_INFO))
-                       col_add_str(fd, COL_INFO, pdu_type_string);
-               length = asn1.pointer - start;
+               if (check_col(pinfo->fd, COL_INFO))
+                       col_add_str(pinfo->fd, COL_INFO, pdu_type_string);
+               length = asn1.offset - start;
                if (tree) {
-                       proto_tree_add_text(smux_tree, NullTVB, offset, length,
+                       proto_tree_add_text(smux_tree, tvb, offset, length,
                            "PDU type: %s", pdu_type_string);
                }
                offset += length;
                ret = asn1_oid_decode (&asn1, &regid, &regid_length, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, smux_tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, smux_tree,
                            "registration subtree", ret);
                        return;
                }
                if (tree) {
                        oid_string = format_oid(regid, regid_length);
-                       proto_tree_add_text(smux_tree, NullTVB, offset, length,
+                       proto_tree_add_text(smux_tree, tvb, offset, length,
                            "Registration: %s", oid_string);
                        g_free(oid_string);
                }
@@ -2011,24 +2007,24 @@ dissect_smux_pdu(const u_char *pd, int offset, frame_data *fd,
 
                ret = asn1_uint32_decode (&asn1, &priority, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, smux_tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, smux_tree,
                            "priority", ret);
                        return;
                }
                if (tree) {
-                       proto_tree_add_text(smux_tree, NullTVB, offset, length,
+                       proto_tree_add_text(smux_tree, tvb, offset, length,
                            "Priority: %d", priority);
                }
                offset += length;
 
                ret = asn1_uint32_decode (&asn1, &operation, &length);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, smux_tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, smux_tree,
                            "operation", ret);
                        return;
                }
                if (tree) {
-                       proto_tree_add_text(smux_tree, NullTVB, offset, length,
+                       proto_tree_add_text(smux_tree, tvb, offset, length,
                            "Operation: %s", 
                            val_to_str(operation, smux_rreq, 
                                "Unknown operation %#x"));
@@ -2039,22 +2035,22 @@ dissect_smux_pdu(const u_char *pd, int offset, frame_data *fd,
        if (cls == ASN1_APL && con == ASN1_PRI && pdu_type == SMUX_MSG_RRSP) {
                pdu_type_string = val_to_str(pdu_type, smux_types,
                    "Unknown PDU type %#x");
-               if (check_col(fd, COL_INFO))
-                       col_add_str(fd, COL_INFO, pdu_type_string);
-               length = asn1.pointer - start;
+               if (check_col(pinfo->fd, COL_INFO))
+                       col_add_str(pinfo->fd, COL_INFO, pdu_type_string);
+               length = asn1.offset - start;
                if (tree) {
-                       proto_tree_add_text(smux_tree, NullTVB, offset, length,
+                       proto_tree_add_text(smux_tree, tvb, offset, length,
                            "PDU type: %s", pdu_type_string);
                }
                offset += length;
                ret = asn1_uint32_value_decode (&asn1, pdu_length, &priority);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, smux_tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, smux_tree,
                            "priority", ret);
                        return;
                }
                if (tree) {
-                       proto_tree_add_text(smux_tree, NullTVB, offset,
+                       proto_tree_add_text(smux_tree, tvb, offset,
                            pdu_length, "%s",
                            val_to_str(priority, smux_prio, 
                                "Priority: %#x"));
@@ -2065,22 +2061,22 @@ dissect_smux_pdu(const u_char *pd, int offset, frame_data *fd,
        if (cls == ASN1_APL && con == ASN1_PRI && pdu_type == SMUX_MSG_SOUT) {
                pdu_type_string = val_to_str(pdu_type, smux_types,
                    "Unknown PDU type %#x");
-               if (check_col(fd, COL_INFO))
-                       col_add_str(fd, COL_INFO, pdu_type_string);
-               length = asn1.pointer - start;
+               if (check_col(pinfo->fd, COL_INFO))
+                       col_add_str(pinfo->fd, COL_INFO, pdu_type_string);
+               length = asn1.offset - start;
                if (tree) {
-                       proto_tree_add_text(smux_tree, NullTVB, offset, length,
+                       proto_tree_add_text(smux_tree, tvb, offset, length,
                            "PDU type: %s", pdu_type_string);
                }
                offset += length;
                ret = asn1_uint32_value_decode (&asn1, pdu_length, &commit);
                if (ret != ASN1_ERR_NOERROR) {
-                       dissect_snmp_parse_error(pd, offset, fd, smux_tree,
+                       dissect_snmp_parse_error(tvb, offset, pinfo, smux_tree,
                            "commit", ret);
                        return;
                }
                if (tree) {
-                       proto_tree_add_text(smux_tree, NullTVB, offset,
+                       proto_tree_add_text(smux_tree, tvb, offset,
                            pdu_length, "%s",
                            val_to_str(commit, smux_sout, 
                                "Unknown SOUT Value: %#x"));
@@ -2089,20 +2085,18 @@ dissect_smux_pdu(const u_char *pd, int offset, frame_data *fd,
                return;
        }
        if (cls != ASN1_CTX || con != ASN1_CON) {
-               dissect_snmp_parse_error(pd, offset, fd, smux_tree,
+               dissect_snmp_parse_error(tvb, offset, pinfo, smux_tree,
                    "PDU type", ASN1_ERR_WRONG_TYPE);
                return;
        }
-       dissect_common_pdu(pd, offset, fd, smux_tree, asn1, pdu_type, start);
+       dissect_common_pdu(tvb, offset, pinfo, smux_tree, asn1, pdu_type, start);
 }
 
 static void
-dissect_snmp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) 
+dissect_snmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) 
 {
        conversation_t  *conversation;
 
-       OLD_CHECK_DISPLAY_AS_DATA(proto_snmp, pd, offset, fd, tree);
-
        /*
         * The first SNMP packet goes to the SNMP port; the second one
         * may come from some *other* port, but goes back to the same
@@ -2117,25 +2111,24 @@ dissect_snmp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
         * one, with a wildcard UDP port, and give it the SNMP dissector
         * as a dissector.
         */
-       if (pi.destport == UDP_PORT_SNMP) {
-         conversation = find_conversation(&pi.src, &pi.dst, PT_UDP,
-                                          pi.srcport, 0, NO_DST_PORT);
+       if (pinfo->destport == UDP_PORT_SNMP) {
+         conversation = find_conversation(&pinfo->src, &pinfo->dst, PT_UDP,
+                                          pinfo->srcport, 0, NO_DST_PORT);
          if (conversation == NULL) {
-           conversation = conversation_new(&pi.src, &pi.dst, PT_UDP,
-                                           pi.srcport, 0, NULL,
+           conversation = conversation_new(&pinfo->src, &pinfo->dst, PT_UDP,
+                                           pinfo->srcport, 0, NULL,
                                            NO_DST_PORT);
-           old_conversation_set_dissector(conversation, dissect_snmp);
+           conversation_set_dissector(conversation, dissect_snmp);
          }
        }
 
-       dissect_snmp_pdu(pd, offset, fd, tree, "SNMP", proto_snmp, ett_snmp);
+       dissect_snmp_pdu(tvb, 0, pinfo, tree, "SNMP", proto_snmp, ett_snmp);
 }
 
 static void
-dissect_smux(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) 
+dissect_smux(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) 
 {
-       OLD_CHECK_DISPLAY_AS_DATA(proto_smux, pd, offset, fd, tree);
-       dissect_smux_pdu(pd, offset, fd, tree, proto_smux, ett_smux);
+       dissect_smux_pdu(tvb, 0, pinfo, tree, proto_smux, ett_smux);
 }
 
 void
@@ -2295,16 +2288,12 @@ proto_register_snmp(void)
 void
 proto_reg_handoff_snmp(void)
 {
-       old_dissector_add("udp.port", UDP_PORT_SNMP, dissect_snmp,
-           proto_snmp);
-       old_dissector_add("udp.port", UDP_PORT_SNMP_TRAP, dissect_snmp,
-           proto_snmp);
-       old_dissector_add("tcp.port", TCP_PORT_SMUX, dissect_smux,
-           proto_smux);
-       old_dissector_add("ethertype", ETHERTYPE_SNMP, dissect_snmp,
-           proto_snmp);
-       old_dissector_add("ipx.socket", IPX_SOCKET_SNMP_AGENT, dissect_snmp,
+       dissector_add("udp.port", UDP_PORT_SNMP, dissect_snmp, proto_snmp);
+       dissector_add("udp.port", UDP_PORT_SNMP_TRAP, dissect_snmp, proto_snmp);
+       dissector_add("tcp.port", TCP_PORT_SMUX, dissect_smux, proto_smux);
+       dissector_add("ethertype", ETHERTYPE_SNMP, dissect_snmp, proto_snmp);
+       dissector_add("ipx.socket", IPX_SOCKET_SNMP_AGENT, dissect_snmp,
            proto_snmp);
-       old_dissector_add("ipx.socket", IPX_SOCKET_SNMP_SINK, dissect_snmp,
+       dissector_add("ipx.socket", IPX_SOCKET_SNMP_SINK, dissect_snmp,
            proto_snmp);
 }
index 7b5ef92aad08e30355ce8aaeff1dc98d65f54bb8..2e790be8d82edbe6960a51337ede87005fff498d 100644 (file)
@@ -2,7 +2,7 @@
  * Exported routines for SNMP (simple network management protocol)
  * D.Jorand (c) 1998
  *
- * $Id: packet-snmp.h,v 1.5 2000/08/11 13:34:00 deniel Exp $
+ * $Id: packet-snmp.h,v 1.6 2001/04/15 07:30:03 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -31,7 +31,7 @@
  * Guts of the SNMP dissector - exported for use by protocols such as
  * ILMI.
  */
-void dissect_snmp_pdu(const u_char *, int, frame_data *, proto_tree *tree,
+void dissect_snmp_pdu(tvbuff_t *, int, packet_info *, proto_tree *tree,
     char *, int, gint);
 
 #endif