Convert X.25 dissector to use tvbuffs.
authoroabad <oabad@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 25 May 2000 21:34:58 +0000 (21:34 +0000)
committeroabad <oabad@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 25 May 2000 21:34:58 +0000 (21:34 +0000)
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@2007 f5534014-38df-0310-8fa8-9805f1628bb7

packet-lapb.c
packet-x25.c
packet-x25.h

index cf27722eaa01a228773c31de9bd74dcdeff7db17..5a7db2b03654137ae423864224045c60907b599e 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for lapb frame disassembly
  * Olivier Abad <abad@daba.dhis.net>
  *
- * $Id: packet-lapb.c,v 1.17 2000/05/25 14:57:34 oabad Exp $
+ * $Id: packet-lapb.c,v 1.18 2000/05/25 21:34:56 oabad Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -114,8 +114,7 @@ dissect_lapb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     /* not end of frame ==> X.25 */
     if (tvb_length(tvb) > 2) {
            next_tvb = tvb_new_subset(tvb, 2, -1, -1);
-           tvb_compat(next_tvb, &next_pd, &next_offset);
-           dissect_x25(pinfo->pseudo_header, next_pd, next_offset, pinfo->fd, tree);
+           dissect_x25(next_tvb, pinfo, tree);
     }
 }
 
index 5f004a9d7bc02e512ed181ab3044c4ccd9b5afbe..fbc99db69fcb3f6743cd19d85510eb8832825333 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for x25 packet disassembly
  * Olivier Abad <abad@daba.dhis.net>
  *
- * $Id: packet-x25.c,v 1.27 2000/05/19 23:06:09 gram Exp $
+ * $Id: packet-x25.c,v 1.28 2000/05/25 21:34:57 oabad Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -622,37 +622,38 @@ static char *registration_code(unsigned char code)
 }
 
 void
-dump_facilities(proto_tree *tree, int *offset, const guint8 *p)
+dump_facilities(proto_tree *tree, int *offset, tvbuff_t *tvb)
 {
-    const guint8 *ptr = p;
+    guint8 fac, byte1, byte2, byte3;
     guint32 len;      /* facilities length */
     proto_item *ti=0;
     proto_tree *fac_tree = 0;
     proto_tree *fac_subtree;
 
-    len = *ptr++;
+    len = tvb_get_guint8(tvb, *offset);
     if (len && tree) {
-       ti = proto_tree_add_text(tree, NullTVB, *offset, len + 1,
+       ti = proto_tree_add_text(tree, tvb, *offset, len + 1,
                                 "Facilities");
        fac_tree = proto_item_add_subtree(ti, ett_x25_fac);
-       proto_tree_add_text(fac_tree, NullTVB, *offset, 1,
+       proto_tree_add_text(fac_tree, tvb, *offset, 1,
                            "Facilities length: %d", len);
     }
     (*offset)++;
 
     while (len > 0) {
-       switch(*ptr & X25_FAC_CLASS_MASK) {
+       fac = tvb_get_guint8(tvb, *offset);
+       switch(fac & X25_FAC_CLASS_MASK) {
        case X25_FAC_CLASS_A:
-           switch (*ptr) {
+           switch (fac) {
            case X25_FAC_COMP_MARK:
                if (fac_tree)
-                   ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1,
+                   ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
                            "Code : 00 (Marker)");
-               switch (ptr[1]) {
+               switch (tvb_get_guint8(tvb, *offset + 1)) {
                case 0x00:
                    if (fac_tree) {
                        fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
-                       proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
+                       proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
                                            "Parameter : 00 (Network complementary "
                                            "services - calling DTE)");
                    }
@@ -660,7 +661,7 @@ dump_facilities(proto_tree *tree, int *offset, const guint8 *p)
                case 0xFF:
                    if (fac_tree) {
                        fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
-                       proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
+                       proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
                                            "Parameter : FF (Network complementary "
                                            "services - called DTE)");
                    }
@@ -668,7 +669,7 @@ dump_facilities(proto_tree *tree, int *offset, const guint8 *p)
                case 0x0F:
                    if (fac_tree) {
                        fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
-                       proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
+                       proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
                                            "Parameter : 0F (DTE complementary "
                                            "services)");
                    }
@@ -676,31 +677,32 @@ dump_facilities(proto_tree *tree, int *offset, const guint8 *p)
                default:
                    if (fac_tree) {
                        fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_mark);
-                       proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
+                       proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
                                            "Parameter : %02X (Unknown marker)",
-                                           ptr[1]);
+                                           tvb_get_guint8(tvb, *offset+1));
                    }
                    break;
                }
                break;
            case X25_FAC_REVERSE:
                if (fac_tree) {
-                   ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1, "Code : %02X "
-                           "(Reverse charging / Fast select)", *ptr);
+                   ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
+                           "(Reverse charging / Fast select)", fac);
                    fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_reverse);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1, "Parameter : %02X",
-                           ptr[1]);
-                   if (ptr[1] & 0xC0)
-                       proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
+                   byte1 = tvb_get_guint8(tvb, *offset + 1);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
+                           "Parameter : %02X", byte1);
+                   if (byte1 & 0xC0)
+                       proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
                                "11.. .... = Fast select with restriction");
-                   else if (ptr[1] & 0x80)
-                       proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
+                   else if (byte1 & 0x80)
+                       proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
                                "10.. .... = Fast select - no restriction");
                    else
-                       proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
+                       proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
                                "00.. .... = Fast select not requested");
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
-                           decode_boolean_bitfield(ptr[1], 0x01, 1*8,
+                   proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
+                           decode_boolean_bitfield(byte1, 0x01, 1*8,
                                "Reverse charging requested",
                                "Reverse charging not requested"));
                }
@@ -709,10 +711,11 @@ dump_facilities(proto_tree *tree, int *offset, const guint8 *p)
                if (fac_tree) {
                    char tmpbuf[80];
 
-                   ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1, "Code : %02X "
-                           "(Throughput class negociation)", *ptr);
+                   ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
+                           "(Throughput class negociation)", fac);
                    fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_throughput);
-                   switch (ptr[1] >> 4)
+                   byte1 = tvb_get_guint8(tvb, *offset + 1);
+                   switch (byte1 >> 4)
                    {
                    case 3:
                    case 4:
@@ -724,7 +727,7 @@ dump_facilities(proto_tree *tree, int *offset, const guint8 *p)
                    case 10:
                    case 11:
                        sprintf(tmpbuf, "From the called DTE : %%u (%d bps)",
-                               75*(1<<((ptr[1] >> 4)-3)));
+                               75*(1<<((byte1 >> 4)-3)));
                        break;
                    case 12:
                        sprintf(tmpbuf, "From the called DTE : %%u (48000 bps)");
@@ -735,9 +738,9 @@ dump_facilities(proto_tree *tree, int *offset, const guint8 *p)
                    default:
                        sprintf(tmpbuf, "From the called DTE : %%u (Reserved)");
                    }
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
-                           decode_numeric_bitfield(ptr[1], 0xF0, 1*8, tmpbuf));
-                   switch (ptr[1] & 0x0F)
+                   proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
+                           decode_numeric_bitfield(byte1, 0xF0, 1*8, tmpbuf));
+                   switch (byte1 & 0x0F)
                    {
                    case 3:
                    case 4:
@@ -749,7 +752,7 @@ dump_facilities(proto_tree *tree, int *offset, const guint8 *p)
                    case 10:
                    case 11:
                        sprintf(tmpbuf, "From the calling DTE : %%u (%d bps)",
-                               75*(1<<((ptr[1] & 0x0F)-3)));
+                               75*(1<<((byte1 & 0x0F)-3)));
                        break;
                    case 12:
                        sprintf(tmpbuf, "From the calling DTE : %%u (48000 bps)");
@@ -760,85 +763,84 @@ dump_facilities(proto_tree *tree, int *offset, const guint8 *p)
                    default:
                        sprintf(tmpbuf, "From the calling DTE : %%u (Reserved)");
                    }
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
-                           decode_numeric_bitfield(ptr[1], 0x0F, 1*8, tmpbuf));
+                   proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
+                           decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
                }
                break;
            case X25_FAC_CUG:
                if (fac_tree) {
-                   ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1, "Code : %02X "
-                           "(Closed user group selection)", *ptr);
+                   ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
+                           "(Closed user group selection)", fac);
                    fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_cug);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
-                           "Closed user group: %02X", ptr[1]);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
+                           "Closed user group: %02X", tvb_get_guint8(tvb, *offset+1));
                }
                break;
            case X25_FAC_CALLED_MODIF:
                if (fac_tree) {
-                   ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1, "Code : %02X "
-                           "(Called address modified)", *ptr);
+                   ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
+                           "(Called address modified)", fac);
                    fac_subtree = proto_item_add_subtree(ti,
                            ett_x25_fac_called_modif);
-                   proto_tree_add_text(fac_tree, NullTVB, *offset, 2,
-                           "Parameter %02X", ptr[1]);
+                   proto_tree_add_text(fac_tree, tvb, *offset+1, 1,
+                           "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
                }
                break;
            case X25_FAC_CUG_OUTGOING_ACC:
                if (fac_tree) {
-                   ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1, "Code : %02X "
+                   ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
                            "(Closed user group with outgoing access selection)",
-                           *ptr);
+                           fac);
                    fac_subtree = proto_item_add_subtree(ti,
                            ett_x25_fac_cug_outgoing_acc);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
-                           "Closed user group: %02X", ptr[1]);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
+                           "Closed user group: %02X", tvb_get_guint8(tvb, *offset+1));
                }
                break;
            case X25_FAC_THROUGHPUT_MIN:
                if (fac_tree) {
-                   ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1, "Code : %02X "
-                           "(Minimum throughput class)", *ptr);
+                   ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
+                           "(Minimum throughput class)", fac);
                    fac_subtree = proto_item_add_subtree(ti,
                            ett_x25_fac_throughput_min);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
-                           "Parameter %02X", ptr[1]);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
+                           "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
                }
                break;
            case X25_FAC_EXPRESS_DATA:
                if (fac_tree) {
-                   ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1, "Code : %02X "
-                           "(Negociation of express data)", *ptr);
+                   ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
+                           "(Negociation of express data)", fac);
                    fac_subtree = proto_item_add_subtree(ti,
                            ett_x25_fac_express_data);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
-                           "Parameter %02X", ptr[1]);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
+                           "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
                }
                break;
            default:
                if (fac_tree) {
-                   ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1,
-                           "Code : %02X (Unknown class A)", *ptr);
+                   ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
+                           "Code : %02X (Unknown class A)", fac);
                    fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
-                           "Parameter %02X", ptr[1]);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
+                           "Parameter %02X", tvb_get_guint8(tvb, *offset+1));
                }
                break;
            }
            (*offset) += 2;
            len -= 2;
-           ptr += 2;
            break;
        case X25_FAC_CLASS_B:
-           switch (*ptr) {
+           switch (fac) {
            case X25_FAC_BILATERAL_CUG:
                if (fac_tree) {
-                   ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1, "Code : %02X "
-                           "(Bilateral closed user group selection)", *ptr);
+                   ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
+                           "(Bilateral closed user group selection)", fac);
                    fac_subtree = proto_item_add_subtree(ti,
                            ett_x25_fac_bilateral_cug);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 2,
-                                       "Bilateral CUG: %02X%02X",
-                                       ptr[1], ptr[2]);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
+                                       "Bilateral CUG: %04X",
+                                       tvb_get_ntohs(tvb, *offset+1));
                }
                break;
            case X25_FAC_PACKET_SIZE:
@@ -846,10 +848,11 @@ dump_facilities(proto_tree *tree, int *offset, const guint8 *p)
                {
                    char tmpbuf[80];
 
-                   ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1, "Code : %02X "
-                           "(Packet size)", *ptr);
+                   ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
+                           "(Packet size)", fac);
                    fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_packet_size);
-                   switch (ptr[1])
+                   byte1 = tvb_get_guint8(tvb, *offset + 1);
+                   switch (byte1)
                    {
                    case 0x04:
                        sprintf(tmpbuf, "From the called DTE : %%u (16)");
@@ -882,10 +885,11 @@ dump_facilities(proto_tree *tree, int *offset, const guint8 *p)
                        sprintf(tmpbuf, "From the called DTE : %%u (Unknown)");
                        break;
                    }
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
-                           decode_numeric_bitfield(ptr[1], 0x0F, 1*8, tmpbuf));
+                   proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
+                           decode_numeric_bitfield(byte1, 0x0F, 1*8, tmpbuf));
 
-                   switch (ptr[2])
+                   byte2 = tvb_get_guint8(tvb, *offset + 1);
+                   switch (byte2)
                    {
                    case 0x04:
                        sprintf(tmpbuf, "From the calling DTE : %%u (16)");
@@ -918,128 +922,132 @@ dump_facilities(proto_tree *tree, int *offset, const guint8 *p)
                        sprintf(tmpbuf, "From the calling DTE : %%u (Unknown)");
                        break;
                    }
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+2, 1,
-                           decode_numeric_bitfield(ptr[2], 0x0F, 1*8, tmpbuf));
+                   proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
+                           decode_numeric_bitfield(byte2, 0x0F, 1*8, tmpbuf));
                }
                break;
            case X25_FAC_WINDOW_SIZE:
                if (fac_tree) {
-                   ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1, "Code : %02X "
-                           "(Window size)", *ptr);
+                   ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
+                           "(Window size)", fac);
                    fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_window_size);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
-                           decode_numeric_bitfield(ptr[1], 0x7F, 1*8,
-                           "From the called DTE: %u"));
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+2, 1,
-                           decode_numeric_bitfield(ptr[2], 0x7F, 1*8,
-                           "From the calling DTE: %u"));
+                   proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
+                           decode_numeric_bitfield(tvb_get_guint8(tvb, *offset+1),
+                               0x7F, 1*8, "From the called DTE: %u"));
+                   proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
+                           decode_numeric_bitfield(tvb_get_guint8(tvb, *offset+2),
+                               0x7F, 1*8, "From the calling DTE: %u"));
                }
                break;
            case X25_FAC_RPOA_SELECTION:
                if (fac_tree) {
-                   ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1, "Code : %02X "
-                           "(RPOA selection)", *ptr);
+                   ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
+                           "(RPOA selection)", fac);
                    fac_subtree = proto_item_add_subtree(ti,
                            ett_x25_fac_rpoa_selection);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 2,
-                                       "Data network identification code : %02X%02X",
-                                       ptr[1], ptr[2]);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
+                                       "Data network identification code : %04X",
+                                       tvb_get_ntohs(tvb, *offset+1));
                }
                break;
            case X25_FAC_TRANSIT_DELAY:
                if (fac_tree) {
-                   ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1, "Code : %02X "
-                           "(Transit delay selection and indication)", *ptr);
+                   ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
+                           "(Transit delay selection and indication)", fac);
                    fac_subtree = proto_item_add_subtree(ti,
                            ett_x25_fac_transit_delay);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 2,
+                   proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
                                        "Transit delay: %d ms",
-                                       (ptr[1]<<8) + ptr[2]);
+                                       tvb_get_ntohs(tvb, *offset+1));
                }
                break;
            default:
                if (fac_tree) {
-                   ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1,
-                           "Code : %02X (Unknown class B)", *ptr);
+                   ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
+                           "Code : %02X (Unknown class B)", fac);
                    fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 2,
-                           "Parameter %02X%02X", ptr[1], ptr[2]);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+1, 2,
+                           "Parameter %04X", tvb_get_ntohs(tvb, *offset+1));
                }
                break;
            }
            (*offset) += 3;
            len -= 3;
-           ptr += 3;
            break;
        case X25_FAC_CLASS_C:
            if (fac_tree) {
-               ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1,
-                       "Code : %02X (Unknown class C)", *ptr);
+               ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
+                       "Code : %02X (Unknown class C)", fac);
                fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
-               proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 3,
-                       "Parameter %02X%02X%02X",
-                       ptr[1], ptr[2], ptr[3]);
+               proto_tree_add_text(fac_subtree, tvb, *offset+1, 3,
+                       "Parameter %06X",
+                       tvb_get_ntoh24(tvb, *offset+1));
            }
            (*offset) += 4;
            len -= 4;
-           ptr += 4;
            break;
        case X25_FAC_CLASS_D:
-           switch (*ptr) {
+           switch (fac) {
            case X25_FAC_CALL_TRANSFER:
                if (fac_tree) {
                    int i;
                    char tmpbuf[256];
 
-                   ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1, "Code : %02X "
-                           "(Call redirection or deflection notification)", *ptr);
+                   ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
+                           "(Call redirection or deflection notification)", fac);
                    fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_call_transfer);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
-                           "Length : %u", ptr[1]);
-                   if ((ptr[2] & 0xC0) == 0xC0) {
-                       proto_tree_add_text(fac_subtree, NullTVB, *offset+2, 1,
+                   byte1 = tvb_get_guint8(tvb, *offset+1);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
+                           "Length : %u", byte1);
+                   byte2 = tvb_get_guint8(tvb, *offset+2);
+                   if ((byte2 & 0xC0) == 0xC0) {
+                       proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
                                "Reason : call deflection by the originally "
                                "called DTE address");
                    }
                    else {
-                       switch (ptr[2]) {
+                       switch (byte2) {
                        case 0x01:
-                           proto_tree_add_text(fac_subtree, NullTVB, *offset+2, 1,
+                           proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
                                    "Reason : originally called DTE busy");
                            break;
                        case 0x07:
-                           proto_tree_add_text(fac_subtree, NullTVB, *offset+2, 1,
+                           proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
                                    "Reason : call dist. within a hunt group");
                            break;
                        case 0x09:
-                           proto_tree_add_text(fac_subtree, NullTVB, *offset+2, 1,
+                           proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
                                    "Reason : originally called DTE out of order");
                            break;
                        case 0x0F:
-                           proto_tree_add_text(fac_subtree, NullTVB, *offset+2, 1,
+                           proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
                                    "Reason : systematic call redirection");
                            break;
                        default:
-                           proto_tree_add_text(fac_subtree, NullTVB, *offset+2, 1,
+                           proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
                                    "Reason : unknown");
                            break;
                        }
                    }
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+3, 1,
-                           "Number of semi-octets in DTE address : %u", ptr[3]);
-                   for (i = 0; i < ptr[3]; i++) {
+                   byte3 = tvb_get_guint8(tvb, *offset+3);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+3, 1,
+                           "Number of semi-octets in DTE address : %u",
+                           byte3);
+                   for (i = 0; i < byte3; i++) {
                        if (i % 2 == 0) {
-                           tmpbuf[i] = ((ptr[4+i/2] >> 4) & 0x0F) + '0';
+                           tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
+                                   & 0x0F) + '0';
                            /* if > 9, convert to the right hexadecimal letter */
                            if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
                        } else {
-                           tmpbuf[i] = (ptr[4+i/2] & 0x0F) + '0';
+                           tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
+                                   & 0x0F) + '0';
                            /* if > 9, convert to the right hexadecimal letter */
                            if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
                        }
                    }
                    tmpbuf[i] = 0;
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+4, ptr[1] - 2,
+                   proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
                            "DTE address : %s", tmpbuf);
                }
                break;
@@ -1048,27 +1056,31 @@ dump_facilities(proto_tree *tree, int *offset, const guint8 *p)
                    int i;
                    char tmpbuf[256];
 
-                   ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1, "Code : %02X "
-                           "(Calling address extension)", *ptr);
+                   ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
+                           "(Calling address extension)", fac);
                    fac_subtree = proto_item_add_subtree(ti,
                            ett_x25_fac_calling_addr_ext);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
-                           "Length : %u", ptr[1]);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+2, 1,
-                           "Number of semi-octets in DTE address : %u", ptr[2]);
-                   for (i = 0; i < ptr[2]; i++) {
+                   byte1 = tvb_get_guint8(tvb, *offset+1);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
+                           "Length : %u", byte1);
+                   byte2 = tvb_get_guint8(tvb, *offset+2);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
+                           "Number of semi-octets in DTE address : %u", byte2);
+                   for (i = 0; i < byte2; i++) {
                        if (i % 2 == 0) {
-                           tmpbuf[i] = ((ptr[3+i/2] >> 4) & 0x0F) + '0';
+                           tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
+                                   & 0x0F) + '0';
                            /* if > 9, convert to the right hexadecimal letter */
                            if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
                        } else {
-                           tmpbuf[i] = (ptr[3+i/2] & 0x0F) + '0';
+                           tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
+                                   & 0x0F) + '0';
                            /* if > 9, convert to the right hexadecimal letter */
                            if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
                        }
                    }
                    tmpbuf[i] = 0;
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+3, ptr[1] - 1,
+                   proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
                            "DTE address : %s", tmpbuf);
                }
                break;
@@ -1077,39 +1089,44 @@ dump_facilities(proto_tree *tree, int *offset, const guint8 *p)
                    int i;
                    char tmpbuf[256];
 
-                   ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1, "Code : %02X "
-                           "(Called address extension)", *ptr);
+                   ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
+                           "(Called address extension)", fac);
                    fac_subtree = proto_item_add_subtree(ti,
                            ett_x25_fac_called_addr_ext);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
-                           "Length : %u", ptr[1]);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+2, 1,
-                           "Number of semi-octets in DTE address : %u", ptr[2]);
-                   for (i = 0; i < ptr[2]; i++) {
+                   byte1 = tvb_get_guint8(tvb, *offset+1);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
+                           "Length : %u", byte1);
+                   byte2 = tvb_get_guint8(tvb, *offset+2);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
+                           "Number of semi-octets in DTE address : %u", byte2);
+                   for (i = 0; i < byte2; i++) {
                        if (i % 2 == 0) {
-                           tmpbuf[i] = ((ptr[3+i/2] >> 4) & 0x0F) + '0';
+                           tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+3+i/2) >> 4)
+                                   & 0x0F) + '0';
                            /* if > 9, convert to the right hexadecimal letter */
                            if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
                        } else {
-                           tmpbuf[i] = (ptr[3+i/2] & 0x0F) + '0';
+                           tmpbuf[i] = (tvb_get_guint8(tvb, *offset+3+i/2)
+                                   & 0x0F) + '0';
                            /* if > 9, convert to the right hexadecimal letter */
                            if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
                        }
                    }
                    tmpbuf[i] = 0;
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+3, ptr[1] - 1,
+                   proto_tree_add_text(fac_subtree, tvb, *offset+3, byte1 - 1,
                            "DTE address : %s", tmpbuf);
                }
                break;
            case X25_FAC_ETE_TRANSIT_DELAY:
                if (fac_tree) {
-                   ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1, "Code : %02X "
-                           "(End to end transit delay)", *ptr);
+                   ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
+                           "(End to end transit delay)", fac);
                    fac_subtree = proto_item_add_subtree(ti,
                            ett_x25_fac_ete_transit_delay);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
-                           "Length : %u", ptr[1]);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+2, ptr[1], "Value");
+                   byte1 = tvb_get_guint8(tvb, *offset+1);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
+                           "Length : %u", byte1);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
                }
                break;
            case X25_FAC_CALL_DEFLECT:
@@ -1117,106 +1134,119 @@ dump_facilities(proto_tree *tree, int *offset, const guint8 *p)
                    int i;
                    char tmpbuf[256];
 
-                   ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1, "Code : %02X "
-                           "(Call deflection selection)", *ptr);
+                   ti = proto_tree_add_text(fac_tree, tvb, *offset, 1, "Code : %02X "
+                           "(Call deflection selection)", fac);
                    fac_subtree = proto_item_add_subtree(ti,
                            ett_x25_fac_call_deflect);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
-                           "Length : %u", ptr[1]);
-                   if ((ptr[2] & 0xC0) == 0xC0)
-                       proto_tree_add_text(fac_subtree, NullTVB, *offset+2, 1,
+                   byte1 = tvb_get_guint8(tvb, *offset+1);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
+                           "Length : %u", byte1);
+                   byte2 = tvb_get_guint8(tvb, *offset+2);
+                   if ((byte2 & 0xC0) == 0xC0)
+                       proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
                                "Reason : call DTE originated");
                    else
-                       proto_tree_add_text(fac_subtree, NullTVB, *offset+2, 1,
+                       proto_tree_add_text(fac_subtree, tvb, *offset+2, 1,
                                "Reason : unknown");
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+3, 1,
+                   byte3 = tvb_get_guint8(tvb, *offset+3);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+3, 1,
                            "Number of semi-octets in the alternative DTE address : %u",
-                           ptr[3]);
-                   for (i = 0; i < ptr[3]; i++) {
+                           byte3);
+                   for (i = 0; i < byte3; i++) {
                        if (i % 2 == 0) {
-                           tmpbuf[i] = ((ptr[4+i/2] >> 4) & 0x0F) + '0';
+                           tmpbuf[i] = ((tvb_get_guint8(tvb, *offset+4+i/2) >> 4)
+                                   & 0x0F) + '0';
                            /* if > 9, convert to the right hexadecimal letter */
                            if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
                        } else {
-                           tmpbuf[i] = (ptr[4+i/2] & 0x0F) + '0';
+                           tmpbuf[i] = (tvb_get_guint8(tvb, *offset+4+i/2)
+                                   & 0x0F) + '0';
                            /* if > 9, convert to the right hexadecimal letter */
                            if (tmpbuf[i] > '9') tmpbuf[i] += ('A' - '0' - 10);
                        }
                    }
                    tmpbuf[i] = 0;
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+4, ptr[1] - 2,
+                   proto_tree_add_text(fac_subtree, tvb, *offset+4, byte1 - 2,
                            "Alternative DTE address : %s", tmpbuf);
                }
                break;
            case X25_FAC_PRIORITY:
                if (fac_tree) {
-                   ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1,
-                           "Code : %02X (Priority)", *ptr);
+                   ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
+                           "Code : %02X (Priority)", fac);
                    fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_priority);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
-                           "Length : %u", ptr[1]);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+2, ptr[1], "Value");
+                   byte1 = tvb_get_guint8(tvb, *offset+1);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
+                           "Length : %u", byte1);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
                }
                break;
            default:
                if (fac_tree) {
-                   ti = proto_tree_add_text(fac_tree, NullTVB, *offset, 1,
-                           "Code : %02X (Unknown class D)", *ptr);
+                   ti = proto_tree_add_text(fac_tree, tvb, *offset, 1,
+                           "Code : %02X (Unknown class D)", fac);
                    fac_subtree = proto_item_add_subtree(ti, ett_x25_fac_unknown);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+1, 1,
-                           "Length : %u", ptr[1]);
-                   proto_tree_add_text(fac_subtree, NullTVB, *offset+2, ptr[1], "Value");
+                   byte1 = tvb_get_guint8(tvb, *offset+1);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+1, 1,
+                           "Length : %u", byte1);
+                   proto_tree_add_text(fac_subtree, tvb, *offset+2, byte1, "Value");
                }
            }
-           (*offset) += ptr[1]+2;
-           len -= ptr[1]+2;
-           ptr += ptr[1]+2;
+           byte1 = tvb_get_guint8(tvb, *offset+1);
+           (*offset) += byte1+2;
+           len -= byte1+2;
            break;
        }
     }
 }
 
 void
-x25_ntoa(proto_tree *tree, int *offset, const guint8 *p,
+x25_ntoa(proto_tree *tree, int *offset, tvbuff_t *tvb,
         frame_data *fd, gboolean toa)
 {
     int len1, len2;
     int i;
     char addr1[16], addr2[16];
     char *first, *second;
+    guint8 byte;
+    int localoffset;
 
-    len1  = (*p >> 4) & 0x0F;
-    len2 = (*p >> 0) & 0x0F;
+    byte = tvb_get_guint8(tvb, *offset);
+    len1 = (byte >> 4) & 0x0F;
+    len2 = (byte >> 0) & 0x0F;
     if (tree) {
-       proto_tree_add_text(tree, NullTVB, *offset, 1,
-               decode_numeric_bitfield(*p, 0xF0, 1*8,
+       proto_tree_add_text(tree, tvb, *offset, 1,
+               decode_numeric_bitfield(byte, 0xF0, 1*8,
                    toa ? "Called address length : %u" :
                          "Calling address length : %u"));
-       proto_tree_add_text(tree, NullTVB, *offset, 1,
-               decode_numeric_bitfield(*p, 0x0F, 1*8,
+       proto_tree_add_text(tree, tvb, *offset, 1,
+               decode_numeric_bitfield(byte, 0x0F, 1*8,
                    toa ? "Calling address length : %u" :
                          "Called address length : %u"));
     }
     (*offset)++;
 
-    p++;
+    localoffset = *offset;
+    byte = tvb_get_guint8(tvb, localoffset);
 
     first=addr1;
     second=addr2;
     for (i = 0; i < (len1 + len2); i++) {
        if (i < len1) {
            if (i % 2 != 0) {
-               *first++ = ((*p >> 0) & 0x0F) + '0';
-               p++;
+               *first++ = ((byte >> 0) & 0x0F) + '0';
+               localoffset++;
+               byte = tvb_get_guint8(tvb, localoffset);
            } else {
-               *first++ = ((*p >> 4) & 0x0F) + '0';
+               *first++ = ((byte >> 4) & 0x0F) + '0';
            }
        } else {
            if (i % 2 != 0) {
-               *second++ = ((*p >> 0) & 0x0F) + '0';
-               p++;
+               *second++ = ((byte >> 0) & 0x0F) + '0';
+               localoffset++;
+               byte = tvb_get_guint8(tvb, localoffset);
            } else {
-               *second++ = ((*p >> 4) & 0x0F) + '0';
+               *second++ = ((byte >> 4) & 0x0F) + '0';
            }
        }
     }
@@ -1234,7 +1264,7 @@ x25_ntoa(proto_tree *tree, int *offset, const guint8 *p,
                col_add_str(fd, COL_RES_DL_SRC, addr1);
        }
        if (tree)
-           proto_tree_add_text(tree, NullTVB, *offset,
+           proto_tree_add_text(tree, tvb, *offset,
                                (len1 + 1) / 2,
                                "%s address : %s",
                                toa ? "Called" : "Calling",
@@ -1250,7 +1280,7 @@ x25_ntoa(proto_tree *tree, int *offset, const guint8 *p,
                col_add_str(fd, COL_RES_DL_DST, addr2);
        }
        if (tree)
-           proto_tree_add_text(tree, NullTVB, *offset + len1/2,
+           proto_tree_add_text(tree, tvb, *offset + len1/2,
                                (len2+1)/2+(len1%2+(len2+1)%2)/2,
                                "%s address : %s",
                                toa ? "Calling" : "Called",
@@ -1260,91 +1290,82 @@ x25_ntoa(proto_tree *tree, int *offset, const guint8 *p,
 }
 
 int
-get_x25_pkt_len(const char *data, frame_data *fd, int offset)
+get_x25_pkt_len(tvbuff_t *tvb)
 {
     int length, called_len, calling_len, dte_len, dce_len;
+    guint8 byte2, bytex;
 
-    /* packet size should always be > 3 */
-    if (!BYTES_ARE_IN_FRAME(offset, 3)) return END_OF_FRAME;
-
-    switch ((guint8)data[2])
+    byte2 = tvb_get_guint8(tvb, 2);
+    switch (byte2)
     {
     case X25_CALL_REQUEST:
-       if (BYTES_ARE_IN_FRAME(offset, 4)) /* pkt size >= 4 */
-       {
-           called_len  = (data[3] >> 0) & 0x0F;
-           calling_len = (data[3] >> 4) & 0x0F;
-           length = 4 + (called_len + calling_len + 1) / 2; /* addr */
-           if (length+offset < pi.captured_len)
-               length += (1 + data[length]); /* facilities */
-       }
-       else length = END_OF_FRAME;
-       return MIN(END_OF_FRAME,length);
+       bytex = tvb_get_guint8(tvb, 3);
+       called_len  = (bytex >> 0) & 0x0F;
+       calling_len = (bytex >> 4) & 0x0F;
+       length = 4 + (called_len + calling_len + 1) / 2; /* addr */
+       if (length < tvb_length(tvb))
+           length += (1 + tvb_get_guint8(tvb, length)); /* facilities */
+
+       return MIN(tvb_length(tvb),length);
 
     case X25_CALL_ACCEPTED:
-       if (BYTES_ARE_IN_FRAME(offset, 4)) /* pkt size >= 4 */
-       {
-           called_len  = (data[3] >> 0) & 0x0F;
-           calling_len = (data[3] >> 4) & 0x0F;
-           length = 4 + (called_len + calling_len + 1) / 2; /* addr */
-           if (length+offset < pi.captured_len)
-               length += (1 + data[length]); /* facilities */
-       }
-       else length = END_OF_FRAME;
-       return MIN(END_OF_FRAME,length);
+       bytex = tvb_get_guint8(tvb, 3);
+       called_len  = (bytex >> 0) & 0x0F;
+       calling_len = (bytex >> 4) & 0x0F;
+       length = 4 + (called_len + calling_len + 1) / 2; /* addr */
+       if (length < tvb_length(tvb))
+           length += (1 + tvb_get_guint8(tvb, length)); /* facilities */
+
+       return MIN(tvb_length(tvb),length);
 
     case X25_CLEAR_REQUEST:
     case X25_RESET_REQUEST:
     case X25_RESTART_REQUEST:
-       return MIN(END_OF_FRAME,5);
+       return MIN(tvb_length(tvb),5);
 
     case X25_DIAGNOSTIC:
-       return MIN(END_OF_FRAME,4);
+       return MIN(tvb_length(tvb),4);
 
     case X25_CLEAR_CONFIRMATION:
     case X25_INTERRUPT:
     case X25_INTERRUPT_CONFIRMATION:
     case X25_RESET_CONFIRMATION:
     case X25_RESTART_CONFIRMATION:
-       return MIN(END_OF_FRAME,3);
+       return MIN(tvb_length(tvb),3);
 
     case X25_REGISTRATION_REQUEST:
-       if (BYTES_ARE_IN_FRAME(offset, 4)) /* pkt size >= 4 */
-       {
-           dce_len  = (data[3] >> 0) & 0x0F;
-           dte_len = (data[3] >> 4) & 0x0F;
-           length = 4 + (dte_len + dce_len + 1) / 2; /* addr */
-           if (length+offset < pi.captured_len)
-               length += (1 + data[length]); /* registration */
-       }
-       else length = END_OF_FRAME;
-       return MIN(END_OF_FRAME,length);
+       bytex = tvb_get_guint8(tvb, 3);
+       dce_len = (bytex >> 0) & 0x0F;
+       dte_len = (bytex >> 4) & 0x0F;
+       length = 4 + (dte_len + dce_len + 1) / 2; /* addr */
+       if (length < tvb_length(tvb))
+           length += (1 + tvb_get_guint8(tvb, length)); /* registration */
+
+       return MIN(tvb_length(tvb),length);
 
     case X25_REGISTRATION_CONFIRMATION:
-       if (BYTES_ARE_IN_FRAME(offset, 6)) /* pkt size >= 6 */
-       {
-           dce_len  = (data[5] >> 0) & 0x0F;
-           dte_len = (data[5] >> 4) & 0x0F;
-           length = 6 + (dte_len + dce_len + 1) / 2; /* addr */
-           if (length+offset < pi.captured_len)
-               length += (1 + data[length]); /* registration */
-       }
-       else length = END_OF_FRAME;
-       return MIN(END_OF_FRAME,length);
+       bytex = tvb_get_guint8(tvb, 5);
+       dce_len = (bytex >> 0) & 0x0F;
+       dte_len = (bytex >> 4) & 0x0F;
+       length = 6 + (dte_len + dce_len + 1) / 2; /* addr */
+       if (length < tvb_length(tvb))
+           length += (1 + tvb_get_guint8(tvb, length)); /* registration */
+
+       return MIN(tvb_length(tvb),length);
     }
-           
-    if ((data[2] & 0x01) == X25_DATA) return MIN(END_OF_FRAME,3);
 
-    switch (data[2] & 0x1F)
+    if ((byte2 & 0x01) == X25_DATA) return MIN(tvb_length(tvb),3);
+
+    switch (byte2 & 0x1F)
     {
     case X25_RR:
-       return MIN(END_OF_FRAME,3);
+       return MIN(tvb_length(tvb),3);
 
     case X25_RNR:
-       return MIN(END_OF_FRAME,3);
+       return MIN(tvb_length(tvb),3);
 
     case X25_REJ:
-       return MIN(END_OF_FRAME,3);
+       return MIN(tvb_length(tvb),3);
     }
 
     return 0;
@@ -1366,97 +1387,111 @@ static const value_string sharing_strategy_vals[] = {
 };
 
 void
-dissect_x25(const union wtap_pseudo_header *pseudo_header, const u_char *pd,
-               int offset, frame_data *fd, proto_tree *tree)
+dissect_x25(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
     proto_tree *x25_tree=0, *ti;
-    int localoffset=offset;
+    int localoffset=0;
     int x25_pkt_len;
     int modulo;
     guint16 vc;
     void (*dissect)(const u_char *, int, frame_data *, proto_tree *);
     gboolean toa;         /* TOA/NPI address format */
+    guint16 bytes0_1;
+    guint8 pkt_type;
+    tvbuff_t *next_tvb;
+    const guint8 *next_pd;
+    int next_offset;
+
+    pinfo->current_proto = "X.25";
+
+    if (check_col(pinfo->fd, COL_PROTOCOL))
+       col_add_str(pinfo->fd, COL_PROTOCOL, "X.25");
 
-    if (check_col(fd, COL_PROTOCOL))
-       col_add_str(fd, COL_PROTOCOL, "X.25");
+    bytes0_1 = tvb_get_ntohs(tvb, 0);
 
-    modulo = ((pd[localoffset] & 0x20) ? 128 : 8);
+    modulo = ((bytes0_1 & 0x2000) ? 128 : 8);
+    vc     = (int)(bytes0_1 & 0x0FFF);
 
-    if (pd[localoffset] & 0x80) toa = TRUE;
+    if (bytes0_1 & 0x8000) toa = TRUE;
     else toa = FALSE;
 
-    x25_pkt_len = get_x25_pkt_len(&pd[localoffset], fd, offset);
+    x25_pkt_len = get_x25_pkt_len(tvb);
     if (x25_pkt_len < 3) /* packet too short */
     {
-       if (check_col(fd, COL_INFO))
-           col_add_str(fd, COL_INFO, "Invalid/short X.25 packet");
+       if (check_col(pinfo->fd, COL_INFO))
+           col_add_str(pinfo->fd, COL_INFO, "Invalid/short X.25 packet");
        if (tree)
-           proto_tree_add_protocol_format(tree, (modulo == 8 ? proto_x25 : proto_ex25), NullTVB,
-                           localoffset, END_OF_FRAME,
-                           "Invalid/short X.25 packet");
+           proto_tree_add_protocol_format(tree,
+                   (modulo == 8 ? proto_x25 : proto_ex25), tvb, 0,
+                   tvb_length(tvb), "Invalid/short X.25 packet");
        return;
     }
-    vc = (int)(pd[localoffset] & 0x0F)*256 + (int)pd[localoffset+1];
     if (tree) {
-       ti = proto_tree_add_item(tree, (modulo == 8) ? proto_x25 : proto_ex25, NullTVB,
-               localoffset, x25_pkt_len, NULL);
+       ti = proto_tree_add_protocol_format(tree,
+               (modulo == 8) ? proto_x25 : proto_ex25, tvb, 0, x25_pkt_len,
+               "X.25");
        x25_tree = proto_item_add_subtree(ti, ett_x25);
-       if (pd[localoffset] & 0x80)
-           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_qbit : hf_ex25_qbit, NullTVB,
-                   localoffset, 2, pd[localoffset]*256+pd[localoffset+1]);
-       if (pd[localoffset] & 0x40)
-           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_dbit : hf_ex25_dbit, NullTVB,
-                   localoffset, 2, pd[localoffset]*256+pd[localoffset+1]);
-       proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_mod : hf_ex25_mod, NullTVB,
-               localoffset, 2, pd[localoffset]*256+pd[localoffset+1]);
+       if (bytes0_1 & 0x8000)
+           proto_tree_add_item(x25_tree,
+                   (modulo == 8) ? hf_x25_qbit : hf_ex25_qbit, tvb, 0, 2,
+                   bytes0_1);
+       if (bytes0_1 & 0x4000)
+           proto_tree_add_item(x25_tree,
+                   (modulo == 8) ? hf_x25_dbit : hf_ex25_dbit, tvb, 0, 2,
+                   bytes0_1);
+       proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_mod : hf_ex25_mod,
+               tvb, 0, 2, bytes0_1);
     }
-    switch (pd[localoffset+2]) {
+
+    pkt_type = tvb_get_guint8(tvb, 2);
+    switch (pkt_type) {
     case X25_CALL_REQUEST:
-       if (check_col(fd, COL_INFO))
-           col_add_fstr(fd, COL_INFO, "%s VC:%d",
-                   (pseudo_header->x25.flags & FROM_DCE) ? "Inc. call"
-                                                         : "Call req." ,
+       if (check_col(pinfo->fd, COL_INFO))
+           col_add_fstr(pinfo->fd, COL_INFO, "%s VC:%d",
+                   (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Inc. call"
+                                                                : "Call req." ,
                     vc);
        if (x25_tree) {
-           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, NullTVB,
-                   localoffset, 2, pd[localoffset]*256+pd[localoffset+1]);
+           proto_tree_add_item(x25_tree,
+                   (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, tvb,
+                   0, 2, bytes0_1);
            proto_tree_add_uint_format(x25_tree,
-                   (modulo == 8) ? hf_x25_type : hf_ex25_type,
-                   NullTVB, localoffset+2, 1, X25_CALL_REQUEST,
-                   (pseudo_header->x25.flags & FROM_DCE) ? "Incoming call"
-                                                            : "Call request");
+                   (modulo == 8) ? hf_x25_type : hf_ex25_type, tvb, 2, 1,
+                   X25_CALL_REQUEST,
+                   (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Incoming call"
+                                                                : "Call request");
        }
-       localoffset += 3;
-       if (localoffset < x25_pkt_len+offset) /* calling/called addresses */
-           x25_ntoa(x25_tree, &localoffset, &pd[localoffset], fd, toa);
+       localoffset = 3;
+       if (localoffset < x25_pkt_len) /* calling/called addresses */
+           x25_ntoa(x25_tree, &localoffset, tvb, pinfo->fd, toa);
 
-       if (localoffset < x25_pkt_len+offset) /* facilities */
-           dump_facilities(x25_tree, &localoffset, &pd[localoffset]);
+       if (localoffset < x25_pkt_len) /* facilities */
+           dump_facilities(x25_tree, &localoffset, tvb);
 
-       if (IS_DATA_IN_FRAME(localoffset)) /* user data */
+       if (localoffset < tvb_length(tvb)) /* user data */
        {
            guint8 spi;
            guint8 prt_id;
 
            /* Compare the first octet of the CALL REQUEST packet with
               various ISO 9577 NLPIDs, as per Annex A of ISO 9577. */
-           spi = pd[localoffset];
+           spi = tvb_get_guint8(tvb, localoffset);
            switch (spi) {
 
            /* XXX - handle other NLPIDs, e.g. PPP? */
 
            case NLPID_IP:
-               x25_hash_add_proto_start(vc, fd->abs_secs,
-                                        fd->abs_usecs, dissect_ip);
+               x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
+                                        pinfo->fd->abs_usecs, dissect_ip);
                if (x25_tree)
-                   proto_tree_add_text(x25_tree, NullTVB, localoffset, 1,
+                   proto_tree_add_text(x25_tree, tvb, localoffset, 1,
                                        "X.224 secondary protocol ID: IP");
                localoffset++;
                break;
 
            default:
-               if ((pd[localoffset] >= 0x03 && pd[localoffset] <= 0x82)
-                   && pd[localoffset+1] == 0x01) {
+               if ((spi >= 0x03 && spi <= 0x82)
+                   && tvb_get_guint8(tvb, localoffset+1) == 0x01) {
                    /* ISO 9577 claims that a SPI in that range is a
                       length field for X.224/ISO 8073 or X.264/ISO 11570;
                       however, some of them collide with NLPIDs such
@@ -1479,33 +1514,35 @@ dissect_x25(const union wtap_pseudo_header *pseudo_header, const u_char *pd,
                       So we'll assume that's what it is, as the SPI
                       is in the right range for a length, and the UN
                       field is 0x01. */
-                   prt_id = pd[localoffset+2];
+                   prt_id = tvb_get_guint8(tvb, localoffset+2);
                    if (x25_tree) {
-                       proto_tree_add_text(x25_tree, NullTVB, localoffset, 1,
+                       proto_tree_add_text(x25_tree, tvb, localoffset, 1,
                                        "X.264 length indicator: %u",
-                                       pd[localoffset]);
-                       proto_tree_add_text(x25_tree, NullTVB, localoffset+1, 1,
+                                       spi);
+                       proto_tree_add_text(x25_tree, tvb, localoffset+1, 1,
                                        "X.264 UN TPDU identifier: 0x%02X",
-                                       pd[localoffset+1]);
-                       proto_tree_add_text(x25_tree, NullTVB, localoffset+2, 1,
+                                       tvb_get_guint8(tvb, localoffset+1));
+                       proto_tree_add_text(x25_tree, tvb, localoffset+2, 1,
                                        "X.264 protocol identifier: %s",
-                                       val_to_str(prt_id, prt_id_vals, "Unknown (0x%02X)"));
-                       proto_tree_add_text(x25_tree, NullTVB, localoffset+3, 1,
+                                       val_to_str(prt_id, prt_id_vals,
+                                           "Unknown (0x%02X)"));
+                       proto_tree_add_text(x25_tree, tvb, localoffset+3, 1,
                                        "X.264 sharing strategy: %s",
-                                       val_to_str(pd[localoffset+3], sharing_strategy_vals, "Unknown (0x%02X)"));
+                                       val_to_str(tvb_get_guint8(tvb, localoffset+3),
+                                           sharing_strategy_vals, "Unknown (0x%02X)"));
                    }
 
                    /* XXX - dissect the variable part? */
 
                    /* The length doesn't include the length octet itself. */
-                   localoffset += pd[localoffset] + 1;
+                   localoffset += spi + 1;
 
                    switch (prt_id) {
 
                    case PRT_ID_ISO_8073:
                        /* ISO 8073 COTP */
-                       x25_hash_add_proto_start(vc, fd->abs_secs,
-                                        fd->abs_usecs, dissect_cotp);
+                       x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
+                                        pinfo->fd->abs_usecs, dissect_cotp);
                        break;
 
                    default:
@@ -1514,383 +1551,384 @@ dissect_x25(const union wtap_pseudo_header *pseudo_header, const u_char *pd,
                } else {
                unknown:
                    if (x25_tree) {
-                       if (IS_DATA_IN_FRAME(localoffset))
-                          proto_tree_add_text(x25_tree, NullTVB, localoffset,
-                                       pi.captured_len-localoffset, "Data");
+                       proto_tree_add_text(x25_tree, tvb, localoffset,
+                               tvb_length(tvb)-localoffset, "Data");
                    }
-                   localoffset = pi.captured_len;
+                   localoffset = tvb_length(tvb);
                }
            }
        }
        break;
     case X25_CALL_ACCEPTED:
-       if(check_col(fd, COL_INFO))
-           col_add_fstr(fd, COL_INFO, "%s VC:%d",
-                   (pseudo_header->x25.flags & FROM_DCE) ? "Call conn."
-                                                         : "Call acc." ,
+       if(check_col(pinfo->fd, COL_INFO))
+           col_add_fstr(pinfo->fd, COL_INFO, "%s VC:%d",
+                   (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Call conn."
+                                                                : "Call acc." ,
                    vc);
        if (x25_tree) {
-           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, NullTVB,
-                   localoffset, 2, pd[localoffset]*256+pd[localoffset+1]);
+           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn,
+                   tvb, 0, 2, bytes0_1);
            proto_tree_add_uint_format(x25_tree,
                    (modulo == 8) ? hf_x25_type : hf_ex25_type,
-                   NullTVB, localoffset+2, 1, X25_CALL_ACCEPTED,
-                   (pseudo_header->x25.flags & FROM_DCE) ? "Call connected"
-                                                            : "Call accepted");
+                   tvb, 2, 1, X25_CALL_ACCEPTED,
+                   (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Call connected"
+                                                                : "Call accepted");
        }
-       localoffset += 3;
-        if (localoffset < x25_pkt_len+offset) /* calling/called addresses */
-           x25_ntoa(x25_tree, &localoffset, &pd[localoffset], fd, toa);
+       localoffset = 3;
+        if (localoffset < x25_pkt_len) /* calling/called addresses */
+           x25_ntoa(x25_tree, &localoffset, tvb, pinfo->fd, toa);
 
-       if (localoffset < x25_pkt_len+offset) /* facilities */
-           dump_facilities(x25_tree, &localoffset, &pd[localoffset]);
+       if (localoffset < x25_pkt_len) /* facilities */
+           dump_facilities(x25_tree, &localoffset, tvb);
 
-       if (IS_DATA_IN_FRAME(localoffset)) { /* user data */
+       if (localoffset < tvb_length(tvb)) { /* user data */
            if (x25_tree)
-               proto_tree_add_text(x25_tree, NullTVB, localoffset,
-                                   pi.captured_len-localoffset, "Data");
-           localoffset=pi.captured_len;
+               proto_tree_add_text(x25_tree, tvb, localoffset,
+                                   tvb_length(tvb)-localoffset, "Data");
+           localoffset=tvb_length(tvb);
        }
        break;
     case X25_CLEAR_REQUEST:
-       if(check_col(fd, COL_INFO)) {
-           col_add_fstr(fd, COL_INFO, "%s VC:%d %s - %s",
-                   (pseudo_header->x25.flags & FROM_DCE) ? "Clear ind."
-                                                         : "Clear req." ,
-                   vc, clear_code(pd[localoffset+3]),
-                   clear_diag(pd[localoffset+4]));
+       if(check_col(pinfo->fd, COL_INFO)) {
+           col_add_fstr(pinfo->fd, COL_INFO, "%s VC:%d %s - %s",
+                   (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Clear ind."
+                                                                : "Clear req." ,
+                   vc, clear_code(tvb_get_guint8(tvb, 3)),
+                   clear_diag(tvb_get_guint8(tvb, 4)));
        }
-       x25_hash_add_proto_end(vc, fd->abs_secs, fd->abs_usecs);
+       x25_hash_add_proto_end(vc, pinfo->fd->abs_secs, pinfo->fd->abs_usecs);
        if (x25_tree) {
-           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, NullTVB,
-                   localoffset, 2, pd[localoffset]*256+pd[localoffset+1]);
+           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, tvb,
+                   0, 2, bytes0_1);
            proto_tree_add_uint_format(x25_tree,
                    (modulo == 8) ? hf_x25_type : hf_ex25_type,
-                   NullTVB, localoffset+2, 1, X25_CLEAR_REQUEST,
-                   (pseudo_header->x25.flags & FROM_DCE) ? "Clear indication"
-                                                            : "Clear request");
-           if (localoffset+3 < x25_pkt_len+offset)
-               proto_tree_add_text(x25_tree, NullTVB, localoffset+3, 1,
-                       "Cause : %s", clear_code(pd[localoffset+3]));
-           if (localoffset+4 < x25_pkt_len+offset)
-               proto_tree_add_text(x25_tree, NullTVB, localoffset+4, 1,
-                       "Diagnostic : %s",
-                       clear_diag(pd[localoffset+4]));
+                   tvb, localoffset+2, 1, X25_CLEAR_REQUEST,
+                   (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Clear indication"
+                                                                : "Clear request");
+           proto_tree_add_text(x25_tree, tvb, 3, 1,
+                   "Cause : %s", clear_code(tvb_get_guint8(tvb, 3)));
+           proto_tree_add_text(x25_tree, tvb, 4, 1,
+                   "Diagnostic : %s", clear_diag(tvb_get_guint8(tvb, 4)));
        }
-       localoffset += x25_pkt_len;
+       localoffset = x25_pkt_len;
        break;
     case X25_CLEAR_CONFIRMATION:
-       if(check_col(fd, COL_INFO))
-           col_add_fstr(fd, COL_INFO, "Clear Conf. VC:%d", vc);
+       if(check_col(pinfo->fd, COL_INFO))
+           col_add_fstr(pinfo->fd, COL_INFO, "Clear Conf. VC:%d", vc);
        if (x25_tree) {
-           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, NullTVB,
-                   localoffset, 2, pd[localoffset]*256+pd[localoffset+1]);
-           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, NullTVB,
-                   localoffset+2, 1, X25_CLEAR_CONFIRMATION);
+           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, tvb,
+                   0, 2, bytes0_1);
+           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, tvb,
+                   2, 1, X25_CLEAR_CONFIRMATION);
        }
-       localoffset += x25_pkt_len;
+       localoffset = x25_pkt_len;
 
-       if (IS_DATA_IN_FRAME(localoffset)) /* extended clear conf format */
-           x25_ntoa(x25_tree, &localoffset, &pd[localoffset], fd, toa);
+       if (localoffset < tvb_length(tvb)) /* extended clear conf format */
+           x25_ntoa(x25_tree, &localoffset, tvb, pinfo->fd, toa);
 
-       if (IS_DATA_IN_FRAME(localoffset)) /* facilities */
-           dump_facilities(x25_tree, &localoffset, &pd[localoffset]);
+       if (localoffset < tvb_length(tvb)) /* facilities */
+           dump_facilities(x25_tree, &localoffset, tvb);
        break;
     case X25_DIAGNOSTIC:
-       if(check_col(fd, COL_INFO)) {
-           col_add_fstr(fd, COL_INFO, "Diag. %d", (int)pd[localoffset+3]);
+       if(check_col(pinfo->fd, COL_INFO)) {
+           col_add_fstr(pinfo->fd, COL_INFO, "Diag. %d",
+                   (int)tvb_get_guint8(tvb, 3));
        }
        if (x25_tree) {
-           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, NullTVB,
-                   localoffset+2, 1, X25_DIAGNOSTIC);
-           if (localoffset+3 < x25_pkt_len+offset)
-               proto_tree_add_text(x25_tree, NullTVB, localoffset+3, 1,
-                       "Diagnostic : %d", (int)pd[localoffset+3]);
+           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, tvb,
+                   2, 1, X25_DIAGNOSTIC);
+           proto_tree_add_text(x25_tree, tvb, 3, 1,
+                   "Diagnostic : %d", (int)tvb_get_guint8(tvb, 3));
        }
-       localoffset += x25_pkt_len;
+       localoffset = x25_pkt_len;
        break;
     case X25_INTERRUPT:
-       if(check_col(fd, COL_INFO))
-           col_add_fstr(fd, COL_INFO, "Interrupt VC:%d", vc);
+       if(check_col(pinfo->fd, COL_INFO))
+           col_add_fstr(pinfo->fd, COL_INFO, "Interrupt VC:%d", vc);
        if (x25_tree) {
-           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, NullTVB,
-                   localoffset, 2, pd[localoffset]*256+pd[localoffset+1]);
-           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, NullTVB,
-                   localoffset+2, 1, X25_INTERRUPT);
+           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, tvb,
+                   0, 2, bytes0_1);
+           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, tvb,
+                   2, 1, X25_INTERRUPT);
        }
-       localoffset += x25_pkt_len;
+       localoffset = x25_pkt_len;
        break;
     case X25_INTERRUPT_CONFIRMATION:
-       if(check_col(fd, COL_INFO))
-           col_add_fstr(fd, COL_INFO, "Interrupt Conf. VC:%d", vc);
+       if(check_col(pinfo->fd, COL_INFO))
+           col_add_fstr(pinfo->fd, COL_INFO, "Interrupt Conf. VC:%d", vc);
        if (x25_tree) {
-           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, NullTVB,
-                   localoffset, 2, pd[localoffset]*256+pd[localoffset+1]);
-           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, NullTVB,
-                   localoffset+2, 1, X25_INTERRUPT_CONFIRMATION);
+           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, tvb,
+                   0, 2, bytes0_1);
+           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, tvb,
+                   2, 1, X25_INTERRUPT_CONFIRMATION);
        }
-       localoffset += x25_pkt_len;
+       localoffset = x25_pkt_len;
        break;
     case X25_RESET_REQUEST:
-       if(check_col(fd, COL_INFO)) {
-           col_add_fstr(fd, COL_INFO, "%s VC:%d %s - Diag.:%d",
-                   (pseudo_header->x25.flags & FROM_DCE) ? "Reset ind."
-                                                         : "Reset req.",
-                   vc, reset_code(pd[localoffset+3]),
-                   (int)pd[localoffset+4]);
+       if(check_col(pinfo->fd, COL_INFO)) {
+           col_add_fstr(pinfo->fd, COL_INFO, "%s VC:%d %s - Diag.:%d",
+                   (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Reset ind."
+                                                                : "Reset req.",
+                   vc, reset_code(tvb_get_guint8(tvb, 3)),
+                   (int)tvb_get_guint8(tvb, 4));
        }
-       x25_hash_add_proto_end(vc, fd->abs_secs, fd->abs_usecs);
+       x25_hash_add_proto_end(vc, pinfo->fd->abs_secs, pinfo->fd->abs_usecs);
        if (x25_tree) {
-           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, NullTVB,
-                   localoffset, 2, pd[localoffset]*256+pd[localoffset+1]);
+           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, tvb,
+                   0, 2, bytes0_1);
            proto_tree_add_uint_format(x25_tree,
-                   (modulo == 8) ? hf_x25_type : hf_ex25_type, NullTVB, localoffset+2, 1,
+                   (modulo == 8) ? hf_x25_type : hf_ex25_type, tvb, 2, 1,
                    X25_RESET_REQUEST,
-                   (pseudo_header->x25.flags & FROM_DCE) ? "Reset indication"
-                                                          : "Reset request");
-           if (localoffset+3 < x25_pkt_len+offset)
-               proto_tree_add_text(x25_tree, NullTVB, localoffset+3, 1,
-                       "Cause : %s", reset_code(pd[localoffset+3]));
-           if (localoffset+4 < x25_pkt_len+offset)
-               proto_tree_add_text(x25_tree, NullTVB, localoffset+4, 1,
-                       "Diagnostic : %d", (int)pd[localoffset+4]);
+                   (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Reset indication"
+                                                                 : "Reset request");
+           proto_tree_add_text(x25_tree, tvb, 3, 1,
+                   "Cause : %s", reset_code(tvb_get_guint8(tvb, 3)));
+           proto_tree_add_text(x25_tree, tvb, 4, 1,
+                   "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
        }
-       localoffset += x25_pkt_len;
+       localoffset = x25_pkt_len;
        break;
     case X25_RESET_CONFIRMATION:
-       if(check_col(fd, COL_INFO))
-           col_add_fstr(fd, COL_INFO, "Reset conf. VC:%d", vc);
+       if(check_col(pinfo->fd, COL_INFO))
+           col_add_fstr(pinfo->fd, COL_INFO, "Reset conf. VC:%d", vc);
        if (x25_tree) {
-           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, NullTVB,
-                   localoffset, 2, pd[localoffset]*256+pd[localoffset+1]);
-           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, NullTVB,
-                   localoffset+2, 1, X25_RESET_CONFIRMATION);
+           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, tvb,
+                   0, 2, bytes0_1);
+           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, tvb,
+                   2, 1, X25_RESET_CONFIRMATION);
        }
-       localoffset += x25_pkt_len;
+       localoffset = x25_pkt_len;
        break;
     case X25_RESTART_REQUEST:
-       if(check_col(fd, COL_INFO)) {
-           col_add_fstr(fd, COL_INFO, "%s %s - Diag.:%d",
-                   (pseudo_header->x25.flags & FROM_DCE) ? "Restart ind."
-                                                         : "Restart req.",
-                   restart_code(pd[localoffset+3]),
-                   (int)pd[localoffset+4]);
+       if(check_col(pinfo->fd, COL_INFO)) {
+           col_add_fstr(pinfo->fd, COL_INFO, "%s %s - Diag.:%d",
+                   (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Restart ind."
+                                                                : "Restart req.",
+                   restart_code(tvb_get_guint8(tvb, 3)),
+                   (int)tvb_get_guint8(tvb, 3));
        }
        if (x25_tree) {
            proto_tree_add_uint_format(x25_tree,
-                   (modulo == 8) ? hf_x25_type : hf_ex25_type, NullTVB, localoffset+2, 1,
+                   (modulo == 8) ? hf_x25_type : hf_ex25_type, tvb, 2, 1,
                    X25_RESTART_REQUEST,
-                   (pseudo_header->x25.flags & FROM_DCE) ? "Restart indication"
-                                                         : "Restart request");
-           if (localoffset+3 < x25_pkt_len+offset)
-               proto_tree_add_text(x25_tree, NullTVB, localoffset+3, 1,
-                       "Cause : %s", restart_code(pd[localoffset+3]));
-           if (localoffset+4 < x25_pkt_len+offset)
-               proto_tree_add_text(x25_tree, NullTVB, localoffset+4, 1,
-                       "Diagnostic : %d", (int)pd[localoffset+4]);
+                   (pinfo->pseudo_header->x25.flags & FROM_DCE) ? "Restart indication"
+                                                                : "Restart request");
+           proto_tree_add_text(x25_tree, tvb, 3, 1,
+                   "Cause : %s", restart_code(tvb_get_guint8(tvb, 3)));
+           proto_tree_add_text(x25_tree, tvb, 4, 1,
+                   "Diagnostic : %d", (int)tvb_get_guint8(tvb, 4));
        }
-       localoffset += x25_pkt_len;
+       localoffset = x25_pkt_len;
        break;
     case X25_RESTART_CONFIRMATION:
-       if(check_col(fd, COL_INFO))
-           col_add_str(fd, COL_INFO, "Restart conf.");
+       if(check_col(pinfo->fd, COL_INFO))
+           col_add_str(pinfo->fd, COL_INFO, "Restart conf.");
        if (x25_tree)
-           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, NullTVB,
-                   localoffset+2, 1, X25_RESTART_CONFIRMATION);
-       localoffset += x25_pkt_len;
+           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, tvb,
+                   2, 1, X25_RESTART_CONFIRMATION);
+       localoffset = x25_pkt_len;
        break;
     case X25_REGISTRATION_REQUEST:
-       if(check_col(fd, COL_INFO))
-           col_add_str(fd, COL_INFO, "Registration req.");
+       if(check_col(pinfo->fd, COL_INFO))
+           col_add_str(pinfo->fd, COL_INFO, "Registration req.");
        if (x25_tree)
-           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, NullTVB,
-                   localoffset+2, 1, X25_REGISTRATION_REQUEST);
-       localoffset += 3;
-       if (localoffset < x25_pkt_len+offset)
-           x25_ntoa(x25_tree, &localoffset, &pd[localoffset], fd, FALSE);
+           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, tvb,
+                   2, 1, X25_REGISTRATION_REQUEST);
+       localoffset = 3;
+       if (localoffset < x25_pkt_len)
+           x25_ntoa(x25_tree, &localoffset, tvb, pinfo->fd, FALSE);
 
        if (x25_tree) {
-           if (localoffset < x25_pkt_len+offset)
-               proto_tree_add_text(x25_tree, NullTVB, localoffset, 1,
-                       "Registration length: %d", pd[localoffset] & 0x7F);
-           if (localoffset+1 < x25_pkt_len+offset)
-               proto_tree_add_text(x25_tree, NullTVB, localoffset+1,
-                       pd[localoffset] & 0x7F, "Registration");
+           if (localoffset < x25_pkt_len)
+               proto_tree_add_text(x25_tree, tvb, localoffset, 1,
+                       "Registration length: %d",
+                       tvb_get_guint8(tvb, localoffset) & 0x7F);
+           if (localoffset+1 < x25_pkt_len)
+               proto_tree_add_text(x25_tree, tvb, localoffset+1,
+                       tvb_get_guint8(tvb, localoffset) & 0x7F,
+                       "Registration");
        }
-       localoffset = pi.captured_len;
+       localoffset = tvb_length(tvb);
        break;
     case X25_REGISTRATION_CONFIRMATION:
-       if(check_col(fd, COL_INFO))
-           col_add_str(fd, COL_INFO, "Registration conf.");
+       if(check_col(pinfo->fd, COL_INFO))
+           col_add_str(pinfo->fd, COL_INFO, "Registration conf.");
        if (x25_tree) {
-           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, NullTVB,
-                   localoffset+2, 1, X25_REGISTRATION_CONFIRMATION);
-           if (localoffset+3 < x25_pkt_len+offset)
-               proto_tree_add_text(x25_tree, NullTVB, localoffset+3, 1,
-                       "Cause: %s", registration_code(pd[localoffset+3]));
-           if (localoffset+4 < x25_pkt_len+offset)
-               proto_tree_add_text(x25_tree, NullTVB, localoffset+4, 1,
-                       "Diagnostic: %s", registration_code(pd[localoffset+4]));
+           proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_type : hf_ex25_type, tvb,
+                   2, 1, X25_REGISTRATION_CONFIRMATION);
+           proto_tree_add_text(x25_tree, tvb, 3, 1,
+                   "Cause: %s", registration_code(tvb_get_guint8(tvb, 3)));
+           proto_tree_add_text(x25_tree, tvb, 4, 1,
+                   "Diagnostic: %s", registration_code(tvb_get_guint8(tvb, 4)));
        }
-       localoffset += 5;
-       if (localoffset < x25_pkt_len+offset)
-           x25_ntoa(x25_tree, &localoffset, &pd[localoffset], fd, TRUE);
+       localoffset = 5;
+       if (localoffset < x25_pkt_len)
+           x25_ntoa(x25_tree, &localoffset, tvb, pinfo->fd, TRUE);
 
        if (x25_tree) {
-           if (localoffset < x25_pkt_len+offset)
-               proto_tree_add_text(x25_tree, NullTVB, localoffset, 1,
-                       "Registration length: %d", pd[localoffset] & 0x7F);
-           if (localoffset+1 < x25_pkt_len+offset)
-               proto_tree_add_text(x25_tree, NullTVB, localoffset+1,
-                       pd[localoffset] & 0x7F, "Registration");
+           if (localoffset < x25_pkt_len)
+               proto_tree_add_text(x25_tree, tvb, localoffset, 1,
+                       "Registration length: %d",
+                       tvb_get_guint8(tvb, localoffset) & 0x7F);
+           if (localoffset+1 < x25_pkt_len)
+               proto_tree_add_text(x25_tree, tvb, localoffset+1,
+                       tvb_get_guint8(tvb, localoffset) & 0x7F,
+                       "Registration");
        }
-       localoffset = pi.captured_len;
+       localoffset = tvb_length(tvb);
        break;
     default :
-       localoffset += 2;
-       if ((pd[localoffset] & 0x01) == X25_DATA)
+       localoffset = 2;
+       if ((pkt_type & 0x01) == X25_DATA)
        {
-           if(check_col(fd, COL_INFO)) {
+           if(check_col(pinfo->fd, COL_INFO)) {
                if (modulo == 8)
-                   col_add_fstr(fd, COL_INFO,
+                   col_add_fstr(pinfo->fd, COL_INFO,
                            "Data VC:%d P(S):%d P(R):%d %s", vc,
-                           (pd[localoffset] >> 1) & 0x07,
-                           (pd[localoffset] >> 5) & 0x07,
-                           ((pd[localoffset]>>4) & 0x01) ? " M" : "");
+                           (pkt_type >> 1) & 0x07,
+                           (pkt_type >> 5) & 0x07,
+                           ((pkt_type >> 4) & 0x01) ? " M" : "");
                else
-                   col_add_fstr(fd, COL_INFO,
+                   col_add_fstr(pinfo->fd, COL_INFO,
                            "Data VC:%d P(S):%d P(R):%d %s", vc,
-                           pd[localoffset+1] >> 1,
-                           pd[localoffset] >> 1,
-                           (pd[localoffset+1] & 0x01) ? " M" : "");
+                           tvb_get_guint8(tvb, localoffset+1) >> 1,
+                           pkt_type >> 1,
+                           (tvb_get_guint8(tvb, localoffset+1) & 0x01) ? " M" : "");
            }
            if (x25_tree) {
-               proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, NullTVB,
-                       localoffset-2, 2, pd[localoffset-2]*256+pd[localoffset-1]);
+               proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn,
+                       tvb, localoffset-2, 2, bytes0_1);
                if (modulo == 8) {
-                   proto_tree_add_item_hidden(x25_tree, hf_x25_type, NullTVB, localoffset, 1,
-                           X25_DATA);
-                   proto_tree_add_item(x25_tree, hf_x25_p_r, NullTVB, localoffset, 1,
-                           pd[localoffset]);
-                   if (pd[localoffset] & 0x10)
-                       proto_tree_add_item(x25_tree, hf_x25_mbit, NullTVB, localoffset, 1,
-                           pd[localoffset]);
-                   proto_tree_add_item(x25_tree, hf_x25_p_s, NullTVB, localoffset, 1,
-                           pd[localoffset]);
-                   proto_tree_add_text(x25_tree, NullTVB, localoffset, 1,
-                           decode_boolean_bitfield(pd[localoffset], 0x01, 1*8,
+                   proto_tree_add_item_hidden(x25_tree, hf_x25_type, tvb,
+                           localoffset, 1, X25_DATA);
+                   proto_tree_add_item(x25_tree, hf_x25_p_r, tvb,
+                           localoffset, 1, pkt_type);
+                   if (pkt_type & 0x10)
+                       proto_tree_add_item(x25_tree, hf_x25_mbit, tvb, localoffset, 1,
+                           pkt_type);
+                   proto_tree_add_item(x25_tree, hf_x25_p_s, tvb, localoffset, 1,
+                           pkt_type);
+                   proto_tree_add_text(x25_tree, tvb, localoffset, 1,
+                           decode_boolean_bitfield(pkt_type, 0x01, 1*8,
                                NULL, "DATA"));
                }
                else {
-                   proto_tree_add_item_hidden(x25_tree, hf_ex25_type, NullTVB, localoffset, 1,
-                           X25_DATA);
-                   proto_tree_add_item(x25_tree, hf_x25_p_r, NullTVB, localoffset, 1,
-                           pd[localoffset]);
-                   proto_tree_add_item(x25_tree, hf_x25_p_s, NullTVB, localoffset+1, 1,
-                           pd[localoffset+1]);
-                   if (pd[localoffset+1] & 0x01)
-                       proto_tree_add_item(x25_tree, hf_ex25_mbit, NullTVB, localoffset+1, 1,
-                           pd[localoffset+1]);
+                   proto_tree_add_item_hidden(x25_tree, hf_ex25_type, tvb,
+                           localoffset, 1, X25_DATA);
+                   proto_tree_add_item(x25_tree, hf_x25_p_r, tvb,
+                           localoffset, 1, pkt_type);
+                   proto_tree_add_item(x25_tree, hf_x25_p_s, tvb,
+                           localoffset+1, 1, tvb_get_guint8(tvb, localoffset+1));
+                   if (tvb_get_guint8(tvb, localoffset+1) & 0x01)
+                       proto_tree_add_item(x25_tree, hf_ex25_mbit, tvb,
+                               localoffset+1, 1, tvb_get_guint8(tvb, localoffset+1));
                }
            }
            localoffset += (modulo == 8) ? 1 : 2;
            break;
        }
-       switch (pd[localoffset] & 0x1F)
+       switch (pkt_type & 0x1F)
        {
        case X25_RR:
-           if(check_col(fd, COL_INFO)) {
+           if(check_col(pinfo->fd, COL_INFO)) {
                if (modulo == 8)
-                   col_add_fstr(fd, COL_INFO, "RR VC:%d P(R):%d",
-                           vc, (pd[localoffset] >> 5) & 0x07);
+                   col_add_fstr(pinfo->fd, COL_INFO, "RR VC:%d P(R):%d",
+                           vc, (pkt_type >> 5) & 0x07);
                else
-                   col_add_fstr(fd, COL_INFO, "RR VC:%d P(R):%d",
-                           vc, pd[localoffset+1] >> 1);
+                   col_add_fstr(pinfo->fd, COL_INFO, "RR VC:%d P(R):%d",
+                           vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
            }
            if (x25_tree) {
-               proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, NullTVB,
-                       localoffset-2, 2, pd[localoffset-2]*256+pd[localoffset-1]);
+               proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn,
+                       tvb, localoffset-2, 2, bytes0_1);
                if (modulo == 8) {
-                   proto_tree_add_item(x25_tree, hf_x25_p_r, NullTVB,
-                           localoffset, 1, pd[localoffset]);
-                   proto_tree_add_item(x25_tree, hf_x25_type, NullTVB, localoffset, 1, X25_RR);
+                   proto_tree_add_item(x25_tree, hf_x25_p_r, tvb,
+                           localoffset, 1, pkt_type);
+                   proto_tree_add_item(x25_tree, hf_x25_type, tvb,
+                           localoffset, 1, X25_RR);
                }
                else {
-                   proto_tree_add_item(x25_tree, hf_ex25_type, NullTVB, localoffset, 1, X25_RR);
-                   proto_tree_add_item(x25_tree, hf_ex25_p_r, NullTVB,
-                           localoffset+1, 1, pd[localoffset+1]);
+                   proto_tree_add_item(x25_tree, hf_ex25_type, tvb,
+                           localoffset, 1, X25_RR);
+                   proto_tree_add_item(x25_tree, hf_ex25_p_r, tvb,
+                           localoffset+1, 1, tvb_get_guint8(tvb, localoffset+1));
                }
            }
            break;
 
        case X25_RNR:
-           if(check_col(fd, COL_INFO)) {
+           if(check_col(pinfo->fd, COL_INFO)) {
                if (modulo == 8)
-                   col_add_fstr(fd, COL_INFO, "RNR VC:%d P(R):%d",
-                           vc, (pd[localoffset] >> 5) & 0x07);
+                   col_add_fstr(pinfo->fd, COL_INFO, "RNR VC:%d P(R):%d",
+                           vc, (pkt_type >> 5) & 0x07);
                else
-                   col_add_fstr(fd, COL_INFO, "RNR VC:%d P(R):%d",
-                           vc, pd[localoffset+1] >> 1);
+                   col_add_fstr(pinfo->fd, COL_INFO, "RNR VC:%d P(R):%d",
+                           vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
            }
            if (x25_tree) {
-               proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, NullTVB,
-                       localoffset-2, 2, pd[localoffset-2]*256+pd[localoffset-1]);
+               proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn,
+                       tvb, localoffset-2, 2, bytes0_1);
                if (modulo == 8) {
-                   proto_tree_add_item(x25_tree, hf_x25_p_r, NullTVB,
-                           localoffset, 1, pd[localoffset]);
-                   proto_tree_add_item(x25_tree, hf_x25_type, NullTVB, localoffset, 1, X25_RNR);
+                   proto_tree_add_item(x25_tree, hf_x25_p_r, tvb,
+                           localoffset, 1, pkt_type);
+                   proto_tree_add_item(x25_tree, hf_x25_type, tvb,
+                           localoffset, 1, X25_RNR);
                }
                else {
-                   proto_tree_add_item(x25_tree, hf_ex25_type, NullTVB, localoffset, 1, X25_RNR);
-                   proto_tree_add_item(x25_tree, hf_ex25_p_r, NullTVB,
-                           localoffset+1, 1, pd[localoffset+1]);
+                   proto_tree_add_item(x25_tree, hf_ex25_type, tvb,
+                           localoffset, 1, X25_RNR);
+                   proto_tree_add_item(x25_tree, hf_ex25_p_r, tvb,
+                           localoffset+1, 1, tvb_get_guint8(tvb, localoffset+1));
                }
            }
            break;
 
        case X25_REJ:
-           if(check_col(fd, COL_INFO)) {
+           if(check_col(pinfo->fd, COL_INFO)) {
                if (modulo == 8)
-                   col_add_fstr(fd, COL_INFO, "REJ VC:%d P(R):%d",
-                           vc, (pd[localoffset] >> 5) & 0x07);
+                   col_add_fstr(pinfo->fd, COL_INFO, "REJ VC:%d P(R):%d",
+                           vc, (pkt_type >> 5) & 0x07);
                else
-                   col_add_fstr(fd, COL_INFO, "REJ VC:%d P(R):%d",
-                           vc, pd[localoffset+1] >> 1);
+                   col_add_fstr(pinfo->fd, COL_INFO, "REJ VC:%d P(R):%d",
+                           vc, tvb_get_guint8(tvb, localoffset+1) >> 1);
            }
            if (x25_tree) {
-               proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn, NullTVB,
-                       localoffset-2, 2, pd[localoffset-2]*256+pd[localoffset-1]);
+               proto_tree_add_item(x25_tree, (modulo == 8) ? hf_x25_lcn : hf_ex25_lcn,
+                       tvb, localoffset-2, 2, bytes0_1);
                if (modulo == 8) {
-                   proto_tree_add_item(x25_tree, hf_x25_p_r, NullTVB,
-                           localoffset, 1, pd[localoffset]);
-                   proto_tree_add_item(x25_tree, hf_x25_type, NullTVB, localoffset, 1, X25_REJ);
+                   proto_tree_add_item(x25_tree, hf_x25_p_r, tvb,
+                           localoffset, 1, pkt_type);
+                   proto_tree_add_item(x25_tree, hf_x25_type, tvb,
+                           localoffset, 1, X25_REJ);
                }
                else {
-                   proto_tree_add_item(x25_tree, hf_ex25_type, NullTVB, localoffset, 1, X25_REJ);
-                   proto_tree_add_item(x25_tree, hf_ex25_p_r, NullTVB,
-                           localoffset+1, 1, pd[localoffset+1]);
+                   proto_tree_add_item(x25_tree, hf_ex25_type, tvb,
+                           localoffset, 1, X25_REJ);
+                   proto_tree_add_item(x25_tree, hf_ex25_p_r, tvb,
+                           localoffset+1, 1, tvb_get_guint8(tvb, localoffset+1));
                }
            }
        }
        localoffset += (modulo == 8) ? 1 : 2;
     }
 
-    if (!IS_DATA_IN_FRAME(localoffset)) return;
+    if (localoffset >= tvb_length(tvb)) return;
 
+    next_tvb = tvb_new_subset(tvb, localoffset, -1, -1);
+    tvb_compat(next_tvb, &next_pd, &next_offset);
     /* search the dissector in the hash table */
-    if ((dissect = x25_hash_get_dissect(fd->abs_secs, fd->abs_usecs, vc)))
-      (*dissect)(pd, localoffset, fd, tree);
+    if ((dissect = x25_hash_get_dissect(pinfo->fd->abs_secs, pinfo->fd->abs_usecs, vc)))
+       (*dissect)(next_pd, next_offset, pinfo->fd, tree);
     else {
-      if (pd[localoffset] == 0x45) /* If the Call Req. has not been captured,
-                                   * assume these packets carry IP */
-      {
-         x25_hash_add_proto_start(vc, fd->abs_secs,
-                                  fd->abs_usecs, dissect_ip);
-         dissect_ip(pd, localoffset, fd, tree);
-      }
-      else {
-         dissect_data(pd, localoffset, fd, tree);
-      }
+       /* If the Call Req. has not been captured, assume these packets carry IP */
+       if (tvb_get_guint8(tvb, localoffset) == 0x45) {
+           x25_hash_add_proto_start(vc, pinfo->fd->abs_secs,
+                   pinfo->fd->abs_usecs, dissect_ip);
+           dissect_ip(next_pd, next_offset, pinfo->fd, tree);
+       }
+       else {
+           dissect_data(next_pd, next_offset, pinfo->fd, tree);
+       }
     }
 }
 
index aea5350dd3584abaf7ba7ee35f5f2a30808e2217..cf931426e781ce63aea58cf31b97d9b54f4c7189 100644 (file)
@@ -1,6 +1,6 @@
 /* packet-x25.h
  *
- * $Id: packet-x25.h,v 1.5 2000/05/19 23:06:10 gram Exp $
+ * $Id: packet-x25.h,v 1.6 2000/05/25 21:34:58 oabad Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -22,5 +22,4 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
-void dissect_x25(const union wtap_pseudo_header *, const u_char *, int, frame_data *,
-    proto_tree *);
+void dissect_x25(tvbuff_t *, packet_info *, proto_tree *);