/* plugins.c
* plugin routines
*
- * $Id: plugins.c,v 1.48 2002/02/20 08:24:51 guy Exp $
+ * $Id: plugins.c,v 1.49 2002/02/22 08:56:47 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
#ifdef PLUGINS_NEED_ADDRESS_TABLE
#include "conversation.h"
#include "packet-giop.h"
+#include "packet-tpkt.h"
#include "plugins/plugin_table.h"
static plugin_address_table_t patable;
#endif
patable.p_get_CDR_enum = get_CDR_enum;
patable.p_get_CDR_object = get_CDR_object;
patable.p_get_CDR_boolean = get_CDR_boolean;
+
+ patable.p_is_tpkt = is_tpkt;
+ patable.p_dissect_tpkt_encap = dissect_tpkt_encap;
#endif
#ifdef WIN32
* Routines for Q.931 frame disassembly
* Guy Harris <guy@alum.mit.edu>
*
- * $Id: packet-q931.c,v 1.37 2002/02/12 10:21:05 guy Exp $
+ * $Id: packet-q931.c,v 1.38 2002/02/22 08:56:45 guy Exp $
*
* Modified by Andreas Sikkema for possible use with H.323
*
#include <epan/strutil.h>
#include "nlpid.h"
#include "packet-q931.h"
+#include "prefs.h"
#include "packet-tpkt.h"
static gint ett_q931 = -1;
static gint ett_q931_ie = -1;
+/* desegmentation of Q.931 over TPKT over TCP */
+static gboolean q931_desegment = TRUE;
+
static dissector_handle_t h225_cs_handle;
+static dissector_handle_t q931_tpkt_pdu_handle;
/*
* Q.931 message types.
};
static void
-dissect_q931_pdu(tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree, gboolean is_tpkt)
+dissect_q931_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ gboolean is_tpkt)
{
+ int offset = 0;
proto_tree *q931_tree = NULL;
proto_item *ti;
proto_tree *ie_tree = NULL;
/*
* Q.931-over-TPKT-over-TCP.
- *
- * XXX - this should do the usual TCP loop-over-everything-in-the-segment
- * stuff, and should also handle TPKT PDUs split across segment boundaries.
*/
static gboolean
dissect_q931_tpkt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/*
* OK, it looks like Q.931-over-TPKT.
- *
- * Dissect the TPKT header.
- */
- dissect_tpkt_header(tvb, offset, pinfo, tree);
-
- offset = q931_offset;
-
- /*
- * Reset the current_proto variable because
- * "dissect_tpkt_header()" messed with it.
+ * Call the "dissect TPKT over a TCP stream" routine.
*/
- pinfo->current_proto = "Q.931";
-
- dissect_q931_pdu(tvb, q931_offset, pinfo, tree, TRUE);
+ dissect_tpkt_encap(tvb, pinfo, tree, q931_desegment,
+ q931_tpkt_pdu_handle);
return TRUE;
}
+static void
+dissect_q931_tpkt_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ dissect_q931_pdu(tvb, pinfo, tree, TRUE);
+}
+
static void
dissect_q931(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- dissect_q931_pdu(tvb, 0, pinfo, tree, FALSE);
+ dissect_q931_pdu(tvb, pinfo, tree, FALSE);
}
void
{ &hf_q931_message_type,
{ "Message type", "q931.message_type", FT_UINT8, BASE_HEX, VALS(q931_message_type_vals), 0x0,
"", HFILL }},
-
- };
+ };
static gint *ett[] = {
&ett_q931,
&ett_q931_ie,
};
+ module_t *q931_module;
proto_q931 = proto_register_protocol("Q.931", "Q.931", "q931");
proto_register_field_array (proto_q931, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
register_dissector("q931", dissect_q931, proto_q931);
+ q931_tpkt_pdu_handle = create_dissector_handle(dissect_q931_tpkt_pdu,
+ proto_q931);
+
+ q931_module = prefs_register_protocol(proto_q931, NULL);
+ prefs_register_bool_preference(q931_module, "desegment_h323_messages",
+ "Desegment all Q.931 messages spanning multiple TCP segments",
+ "Whether the Q.931 dissector should desegment all messages spanning multiple TCP segments",
+ &q931_desegment);
}
void
proto_reg_handoff_q931(void)
{
- dissector_handle_t q931_tpkt_handle;
-
/*
* Attempt to get a handle for the H.225 Call Setup dissector.
* If we can't, the handle we get is null.
* Routine to dissect RFC 1006 TPKT packet containing OSI TP PDU
* Copyright 2001, Martin Thomas <Martin_A_Thomas@yahoo.com>
*
- * $Id: packet-tpkt.c,v 1.11 2002/02/02 02:51:20 guy Exp $
+ * $Id: packet-tpkt.c,v 1.12 2002/02/22 08:56:46 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
#include <string.h>
#include "packet-tpkt.h"
+#include "prefs.h"
/* TPKT header fields */
static int proto_tpkt = -1;
/* TPKT fields defining a sub tree */
static gint ett_tpkt = -1;
+/* desegmentation of OSI over TPKT over TCP */
+static gboolean tpkt_desegment = TRUE;
+
#define TCP_PORT_TPKT 102
/* find the dissector for OSI TP (aka COTP) */
return -1;
/* There should at least be 4 bytes left in the frame */
- if ( (*offset) + 4 > (int)tvb_length( tvb ) )
+ if (!tvb_bytes_exist(tvb, *offset, 4))
return -1; /* there aren't */
/*
}
/*
- * Dissect the TPKT header; called from the TPKT dissector, as well as
- * from dissectors such as the dissector for Q.931-over-TCP.
- *
- * Returns the PDU length from the TPKT header.
+ * Dissect TPKT-encapsulated data in a TCP stream.
*/
-int
-dissect_tpkt_header( tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree )
+void
+dissect_tpkt_encap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ gboolean desegment, dissector_handle_t subdissector_handle)
{
- proto_item *ti = NULL;
- proto_tree *tpkt_tree = NULL;
- guint16 data_len;
-
- pinfo->current_proto = "TPKT";
-
- if ( check_col( pinfo->cinfo, COL_PROTOCOL ) ) {
- col_set_str( pinfo->cinfo, COL_PROTOCOL, "TPKT" );
- }
-
- data_len = tvb_get_ntohs( tvb, offset + 2 );
-
- if ( check_col( pinfo->cinfo, COL_INFO) ) {
- col_add_fstr( pinfo->cinfo, COL_INFO, "TPKT Data length = %u",
- data_len );
- }
-
- if ( tree ) {
- ti = proto_tree_add_item( tree, proto_tpkt, tvb, offset, 4,
- FALSE );
- tpkt_tree = proto_item_add_subtree( ti, ett_tpkt );
- /* Version 1st octet */
- proto_tree_add_item( tpkt_tree, hf_tpkt_version, tvb,
- offset, 1, FALSE );
- offset++;
- /* Reserved octet*/
- proto_tree_add_item( tpkt_tree, hf_tpkt_reserved, tvb,
- offset, 1, FALSE );
- offset++;
- }
- else {
- offset += 2;
+ proto_item *ti = NULL;
+ proto_tree *tpkt_tree = NULL;
+ int offset = 0;
+ int length_remaining;
+ int data_len;
+ int length;
+ tvbuff_t *next_tvb;
+ const char *saved_proto;
+
+ while (tvb_reported_length_remaining(tvb, offset) != 0) {
+ length_remaining = tvb_length_remaining(tvb, offset);
+
+ /*
+ * Can we do reassembly?
+ */
+ if (desegment && pinfo->can_desegment) {
+ /*
+ * Yes - is the TPKT 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;
+ }
+ }
+
+ /*
+ * Dissect the TPKT header.
+ * Save and restore "pinfo->current_proto".
+ */
+ saved_proto = pinfo->current_proto;
+ pinfo->current_proto = "TPKT";
+
+ data_len = tvb_get_ntohs(tvb, offset + 2);
+
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "TPKT");
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_add_fstr(pinfo->cinfo, COL_INFO,
+ "TPKT Data length = %u", data_len);
+ }
+
+ if (tree) {
+ ti = proto_tree_add_item(tree, proto_tpkt, tvb,
+ offset, 4, FALSE);
+ tpkt_tree = proto_item_add_subtree(ti, ett_tpkt);
+
+ /* Version */
+ proto_tree_add_item(tpkt_tree, hf_tpkt_version, tvb,
+ offset, 1, FALSE);
+
+ /* Reserved octet*/
+ proto_tree_add_item(tpkt_tree, hf_tpkt_reserved, tvb,
+ offset + 1, 1, FALSE);
+
+ /* Length */
+ proto_tree_add_uint(tpkt_tree, hf_tpkt_length, tvb,
+ offset + 2, 2, data_len);
+ }
+ pinfo->current_proto = saved_proto;
+
+ /*
+ * Can we do reassembly?
+ */
+ if (desegment && pinfo->can_desegment) {
+ /*
+ * Yes - is the payload split across segment
+ * boundaries?
+ */
+ if (length_remaining < data_len + 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 =
+ (data_len + 4) - length_remaining;
+ return;
+ }
+ }
+
+ /* Skip the TPKT header. */
+ offset += 4;
+
+ /*
+ * Construct a tvbuff containing the amount of the payload
+ * we have available. Make its reported length the
+ * amount of data in this TPKT packet.
+ */
+ length = length_remaining - 4;
+ if (length > data_len)
+ length = data_len;
+ next_tvb = tvb_new_subset(tvb, offset, length, data_len);
+
+ /*
+ * Call the subdissector.
+ */
+ call_dissector(subdissector_handle, next_tvb, pinfo, tree);
+
+ /*
+ * Skip the payload.
+ */
+ offset += length;
}
-
- if ( tree )
- proto_tree_add_uint( tpkt_tree, hf_tpkt_length, tvb,
- offset, 2, data_len );
-
- return data_len;
}
/*
* PDU.
*/
static void
-dissect_tpkt( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
+dissect_tpkt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- int tpkt_len;
- int offset = 0;
- int length, reported_length;
- tvbuff_t *next_tvb;
-
- /* Dissect the TPKT header. */
- tpkt_len = dissect_tpkt_header(tvb, offset, pinfo, tree);
- offset += 4;
-
- /*
- * Now hand the minimum of (what's in this frame, what the TPKT
- * header says is in the PDU) on to the OSI TP dissector.
- */
- length = tvb_length_remaining(tvb, offset);
- reported_length = tvb_reported_length_remaining(tvb, offset);
- if (length > tpkt_len)
- length = tpkt_len;
- if (reported_length > tpkt_len)
- reported_length = tpkt_len;
- next_tvb = tvb_new_subset(tvb, offset, length, reported_length);
-
- call_dissector(osi_tp_handle, next_tvb, pinfo, tree);
+ dissect_tpkt_encap(tvb, pinfo, tree, tpkt_desegment, osi_tp_handle);
}
void
{
&ett_tpkt,
};
-
+ module_t *tpkt_module;
proto_tpkt = proto_register_protocol("TPKT", "TPKT", "tpkt");
proto_register_field_array(proto_tpkt, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
+
+ tpkt_module = prefs_register_protocol(proto_tpkt, NULL);
+ prefs_register_bool_preference(tpkt_module, "desegment",
+ "Desegment all TPKT messages spanning multiple TCP segments",
+ "Whether the TPKT dissector should desegment all messages spanning multiple TCP segments",
+ &tpkt_desegment);
}
void
* Copyright 2000, Philips Electronics N.V.
* Andreas Sikkema <andreas.sikkema@philips.com>
*
- * $Id: packet-tpkt.h,v 1.5 2002/02/02 02:51:20 guy Exp $
+ * $Id: packet-tpkt.h,v 1.6 2002/02/22 08:56:46 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* Sets "*offset" to the offset of the first byte past the TPKT header,
* and returns the length from the TPKT header, if it is.
*/
-int is_tpkt( tvbuff_t *tvb, int *offset );
-
+extern int is_tpkt(tvbuff_t *tvb, int *offset);
/*
- * Dissect the TPKT header; called from the TPKT dissector, as well as
- * from dissectors such as the dissector for Q.931-over-TCP.
- *
- * Returns -1 if TPKT isn't enabled, otherwise returns the PDU length
- * from the TPKT header.
+ * Dissect TPKT-encapsulated data in a TCP stream.
*/
-int dissect_tpkt_header( tvbuff_t *tvb, int offset, packet_info *pinfo,
- proto_tree *tree );
+extern void dissect_tpkt_encap(tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *tree, gboolean desegment,
+ dissector_handle_t subdissector_handle);
/* plugin_api.c
* Routines for Ethereal plugins.
*
- * $Id: plugin_api.c,v 1.36 2002/02/20 08:24:52 guy Exp $
+ * $Id: plugin_api.c,v 1.37 2002/02/22 08:56:48 guy Exp $
*
* Ethereal - Network traffic analyzer
* Copyright 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
/* GIOP End */
+ /* TPKT Begin */
+
+ p_is_tpkt = pat->p_is_tpkt;
+ p_dissect_tpkt_encap = pat->p_dissect_tpkt_encap;
+
+ /* TPKT End */
}
/* plugin_api.h
* Routines for Ethereal plugins.
*
- * $Id: plugin_api.h,v 1.37 2002/02/20 08:24:52 guy Exp $
+ * $Id: plugin_api.h,v 1.38 2002/02/22 08:56:48 guy Exp $
*
* Ethereal - Network traffic analyzer
* Copyright 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
#define prefs_register_enum_preference (*p_prefs_register_enum_preference)
#define prefs_register_string_preference (*p_prefs_register_string_preference)
-
/* GIOP entries Begin */
#define register_giop_user (*p_register_giop_user)
/* GIOP entries End */
+/* TPKT entries Begin */
+
+#define is_tpkt (*p_is_tpkt)
+#define dissect_tpkt_encap (*p_dissect_tpkt_encap)
+
+/* TPKT entries End */
#endif
#include <epan/packet.h>
#include <epan/conversation.h>
#include "prefs.h"
#include "packet-giop.h"
+#include "packet-tpkt.h"
#include "plugin_table.h"
/* plugin_api_defs.h
* Define the variables that hold pointers to plugin API functions
*
- * $Id: plugin_api_defs.h,v 1.12 2002/02/20 08:24:52 guy Exp $
+ * $Id: plugin_api_defs.h,v 1.13 2002/02/22 08:56:48 guy Exp $
*
* Ethereal - Network traffic analyzer
* Copyright 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
addr_get_CDR_wchar p_get_CDR_wchar;
addr_get_CDR_wstring p_get_CDR_wstring;
+addr_is_tpkt p_is_tpkt;
+addr_dissect_tpkt_encap p_dissect_tpkt_encap;
+
#endif /* PLUGINS_NEED_ADDRESS_TABLE */
#endif /* PLUGIN_API_DEFS_H */
/* plugin_table.h
* Table of exported addresses for Ethereal plugins.
*
- * $Id: plugin_table.h,v 1.40 2002/02/20 08:24:52 guy Exp $
+ * $Id: plugin_table.h,v 1.41 2002/02/22 08:56:48 guy Exp $
*
* Ethereal - Network traffic analyzer
* Copyright 2000 by Gilbert Ramirez <gram@alumni.rice.edu>
typedef guint32 (*addr_get_CDR_wstring)(tvbuff_t *, gchar **, int *, gboolean,
int, MessageHeader *);
+typedef int (*addr_is_tpkt)(tvbuff_t *, int *);
+typedef void (*addr_dissect_tpkt_encap)(tvbuff_t *, packet_info *,
+ proto_tree *, gboolean, dissector_handle_t);
+
typedef struct {
addr_check_col p_check_col;
/* GIOP End */
+ /* TPKT Begin */
+
+ addr_is_tpkt p_is_tpkt;
+ addr_dissect_tpkt_encap p_dissect_tpkt_encap;
+ /* GIOP End */
} plugin_address_table_t;
#else /* ! PLUGINS_NEED_ADDRESS_TABLE */