From bf7e4ce90948af368a11a043fa2617f72e357b96 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Tue, 9 Apr 2002 08:15:04 +0000 Subject: Move the definition of the FROM_DCE bit in the "flags" field of a "struct x25_phdr" to "wiretap/wtap.h". Have two X.25 dissectors, one of which assumes that there's a "struct x25_phdr" pseudo-header and one of which doesn't; the former uses the information in that pseudo-header to determine whether the packet is DTE->DCE or DCE->DTE, and the latter assumes it has no clue whether the packet is DTE->DCE or DCE->TDE. Use the former one in the LAPB dissector, and the latter one in the XOT dissector and in the LLC dissector table. In the X.25-over-TCP dissector, handle multiple X.25 packets per TCP segment, and handle X.25 packets split across TCP segments. svn path=/trunk/; revision=5134 --- packet-xot.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 129 insertions(+), 26 deletions(-) (limited to 'packet-xot.c') diff --git a/packet-xot.c b/packet-xot.c index 72696e061c..17b3451528 100644 --- a/packet-xot.c +++ b/packet-xot.c @@ -1,9 +1,9 @@ /* packet-xot.c - * Routines for X25 over TCP dissection (RFC 1613) + * Routines for X.25 over TCP dissection (RFC 1613) * * Copyright 2000, Paul Ionescu * - * $Id: packet-xot.c,v 1.9 2002/01/21 07:36:48 guy Exp $ + * $Id: packet-xot.c,v 1.10 2002/04/09 08:15:02 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -35,6 +35,8 @@ #include #include #include +#include "packet-frame.h" +#include "prefs.h" #define TCP_PORT_XOT 1998 @@ -44,39 +46,133 @@ static gint hf_xot_length = -1; static gint ett_xot = -1; +/* desegmentation of X.25 over TCP */ +static gboolean xot_desegment = TRUE; + static dissector_handle_t x25_handle; static void dissect_xot(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { + volatile int offset = 0; + int length_remaining; + guint16 version; + guint16 plen; + int length; proto_item *ti; proto_tree *xot_tree; - guint16 version,len; tvbuff_t *next_tvb; - - if (check_col(pinfo->cinfo, COL_PROTOCOL)) - col_set_str(pinfo->cinfo, COL_PROTOCOL, "XOT"); - if (check_col(pinfo->cinfo, COL_INFO)) - col_clear(pinfo->cinfo, COL_INFO); - - version = tvb_get_ntohs(tvb,0); - len = tvb_get_ntohs(tvb,2); - - if (check_col(pinfo->cinfo, COL_INFO)) - col_add_fstr(pinfo->cinfo, COL_INFO, "XOT Version = %u, size = %u",version,len ); - - if (tree) { - - ti = proto_tree_add_protocol_format(tree, proto_xot, tvb, 0, 4, "X.25 over TCP"); - xot_tree = proto_item_add_subtree(ti, ett_xot); - - proto_tree_add_uint(xot_tree, hf_xot_version, tvb, 0, 2, version); - proto_tree_add_uint(xot_tree, hf_xot_length, tvb, 2, 2, len); + while (tvb_reported_length_remaining(tvb, offset) != 0) { + length_remaining = tvb_length_remaining(tvb, offset); + + /* + * Can we do reassembly? + */ + if (xot_desegment && pinfo->can_desegment) { + /* + * Yes - is the X.25-over-TCP header split across segment boundaries? + */ + if (length_remaining < 4) { + /* + * Yes. Tell the TCP dissector where the data for this message + * starts in the data it handed us, and how many + * more bytes we need, and return. + */ + pinfo->desegment_offset = offset; + pinfo->desegment_len = 4 - length_remaining; + return; + } + } + + /* + * Get the length of the XOT packet. + */ + version = tvb_get_ntohs(tvb, offset + 0); + if (version != 0) + return; + plen = tvb_get_ntohs(tvb, offset + 2); + + /* + * Can we do reassembly? + */ + if (xot_desegment && pinfo->can_desegment) { + /* + * Yes - is the XOT packet split across segment boundaries? + */ + if (length_remaining < plen + 4) { + /* + * Yes. Tell the TCP dissector where the data for this message + * starts in the data it handed us, and how many more bytes we + * need, and return. + */ + pinfo->desegment_offset = offset; + pinfo->desegment_len = (plen + 4) - length_remaining; + return; + } + } + + /* + * Dissect the X.25-over-TCP packet. + * + * Catch the ReportedBoundsError exception; if this particular message + * happens to get a ReportedBoundsError exception, that doesn't mean + * that we should stop dissecting X.25-over-TCP messages within this + * frame or chunk of reassembled data. + * + * If it gets a BoundsError, we can stop, as there's nothing more to see, + * so we just re-throw it. + */ + TRY { + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "XOT"); + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "XOT Version = %u, size = %u", + version,plen ); + + if (tree) { + ti = proto_tree_add_protocol_format(tree, proto_xot, tvb, offset, 4, + "X.25 over TCP"); + xot_tree = proto_item_add_subtree(ti, ett_xot); + + proto_tree_add_uint(xot_tree, hf_xot_version, tvb, offset, 2, version); + proto_tree_add_uint(xot_tree, hf_xot_length, tvb, offset + 2, 2, plen); + } + + /* + * Construct a tvbuff containing the amount of the payload we have + * available. Make its reported length the amount of data in the + * X.25-over-TCP packet. + * + * XXX - if reassembly isn't enabled. the subdissector will throw a + * BoundsError exception, rather than a ReportedBoundsError exception. + * We really want a tvbuff where the length is "length", the reported + * length is "plen + 4", and the "if the snapshot length were infinite" + * length is the minimum of the reported length of the tvbuff handed + * to us and "plen+4", with a new type of exception thrown if the offset + * is within the reported length but beyond that third length, with that + * exception getting the "Unreassembled Packet" error. + */ + length = length_remaining - 4; + if (length > plen) + length = plen; + next_tvb = tvb_new_subset(tvb, offset + 4, length, plen); + call_dissector(x25_handle,next_tvb,pinfo,tree); + } + CATCH(BoundsError) { + RETHROW; + } + CATCH(ReportedBoundsError) { + show_reported_bounds_error(tvb, pinfo, tree); + } + ENDTRY; + + /* + * Skip the X.25-over-TCP header and the payload. + */ + offset += plen + 4; } - next_tvb = tvb_new_subset(tvb,4, -1 , -1); - call_dissector(x25_handle,next_tvb,pinfo,tree); } - + /* Register the protocol with Ethereal */ void proto_register_xot(void) @@ -95,11 +191,18 @@ proto_register_xot(void) static gint *ett[] = { &ett_xot, }; + module_t *xot_module; proto_xot = proto_register_protocol("X.25 over TCP", "XOT", "xot"); proto_register_field_array(proto_xot, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); -}; + + xot_module = prefs_register_protocol(proto_xot, NULL); + prefs_register_bool_preference(xot_module, "desegment", + "Desegment all X.25-over-TCP messages spanning multiple TCP segments", + "Whether the X.25-over-TCP dissector should desegment all messages spanning multiple TCP segments", + &xot_desegment); +} void proto_reg_handoff_xot(void) -- cgit v1.2.3