diff options
author | Olivier Abad <oabad@noos.fr> | 2000-05-25 21:34:58 +0000 |
---|---|---|
committer | Olivier Abad <oabad@noos.fr> | 2000-05-25 21:34:58 +0000 |
commit | b7b0a32400341193a15069040b66cba1c978d584 (patch) | |
tree | f05e928aec47bd8366f0ec9ff0079e2ac6fcf588 | |
parent | 294cd03b275b1673029bada36a5a200b10b81ca1 (diff) |
Convert X.25 dissector to use tvbuffs.
svn path=/trunk/; revision=2007
-rw-r--r-- | packet-lapb.c | 5 | ||||
-rw-r--r-- | packet-x25.c | 1126 | ||||
-rw-r--r-- | packet-x25.h | 5 |
3 files changed, 586 insertions, 550 deletions
diff --git a/packet-lapb.c b/packet-lapb.c index cf27722eaa..5a7db2b036 100644 --- a/packet-lapb.c +++ b/packet-lapb.c @@ -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); } } diff --git a/packet-x25.c b/packet-x25.c index 5f004a9d7b..fbc99db69f 100644 --- a/packet-x25.c +++ b/packet-x25.c @@ -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); + } } } diff --git a/packet-x25.h b/packet-x25.h index aea5350dd3..cf931426e7 100644 --- a/packet-x25.h +++ b/packet-x25.h @@ -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 *); |