aboutsummaryrefslogtreecommitdiffstats
path: root/packet-tpkt.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2002-02-22 08:56:48 +0000
committerGuy Harris <guy@alum.mit.edu>2002-02-22 08:56:48 +0000
commite9bc3da3707e51d56a96bf079b99f577f7c5ae6c (patch)
tree22e81a4bb0f52d77136bcefccfacdee0d743da32 /packet-tpkt.c
parentdf151b784ad010e9efe84b59e2667ae3a4eaeaab (diff)
Handle TPKT packets split across segment boundaries, and multiple TPKT
packets per segment. Instead of having a routine for dissectors such as the Q.931 dissector to call to dissect the TPKT header, have a routine that does all the reassembly and multiple-packets-per-segment work, and have the Q.931 dissector call it. Export "is_tpkt()", and the new routine, to plugins. Add preferences for TPKT and Q.931 reassembly. svn path=/trunk/; revision=4778
Diffstat (limited to 'packet-tpkt.c')
-rw-r--r--packet-tpkt.c201
1 files changed, 131 insertions, 70 deletions
diff --git a/packet-tpkt.c b/packet-tpkt.c
index 270c7641c4..50e793f70e 100644
--- a/packet-tpkt.c
+++ b/packet-tpkt.c
@@ -7,7 +7,7 @@
* 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>
@@ -47,6 +47,7 @@
#include <string.h>
#include "packet-tpkt.h"
+#include "prefs.h"
/* TPKT header fields */
static int proto_tpkt = -1;
@@ -57,6 +58,9 @@ static int hf_tpkt_length = -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) */
@@ -81,7 +85,7 @@ is_tpkt( tvbuff_t *tvb, int *offset )
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 */
/*
@@ -100,53 +104,125 @@ 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 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;
}
/*
@@ -154,30 +230,9 @@ dissect_tpkt_header( tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *
* 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
@@ -227,11 +282,17 @@ proto_register_tpkt(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