aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2006-05-23 05:48:00 +0000
committerAnders Broman <anders.broman@ericsson.com>2006-05-23 05:48:00 +0000
commit1814821adc8f2b6fcb31bb845ee5a9da6c0c6b29 (patch)
tree055ab18cbde4f316b30662da608ec51f3e7f44a6
parent28509cb3111d1bd96fb179dd50a4330fa52c1685 (diff)
From Martin Mathieson:
- Many DCT2000 protocols can be embedded within an IP primitive message. Add a heuristic to see if we can find the protocol payload within in IP primitive message, and look for an ethereal dissector matching the DCT2000 protocol name (this is useful for simple protocol testing where no physical links are involved) - Make some more of these protocols (diameter, http, mgcp) findable by name - Adds protocol 'variant' number to stub and dissector - Break the duplicated writing of the stub header out into a separate function svn path=/trunk/; revision=18212
-rw-r--r--epan/dissectors/packet-catapult-dct2000.c107
-rw-r--r--epan/dissectors/packet-diameter.c3
-rw-r--r--epan/dissectors/packet-http.c1
-rw-r--r--plugins/mgcp/packet-mgcp.c4
-rw-r--r--wiretap/catapult_dct2000.c128
-rw-r--r--wiretap/catapult_dct2000.h1
6 files changed, 190 insertions, 54 deletions
diff --git a/epan/dissectors/packet-catapult-dct2000.c b/epan/dissectors/packet-catapult-dct2000.c
index c3def29f56..0879b17a86 100644
--- a/epan/dissectors/packet-catapult-dct2000.c
+++ b/epan/dissectors/packet-catapult-dct2000.c
@@ -41,11 +41,14 @@ static int hf_catapult_dct2000_context = -1;
static int hf_catapult_dct2000_port_number = -1;
static int hf_catapult_dct2000_timestamp = -1;
static int hf_catapult_dct2000_protocol = -1;
+static int hf_catapult_dct2000_variant = -1;
static int hf_catapult_dct2000_direction = -1;
static int hf_catapult_dct2000_encap = -1;
static int hf_catapult_dct2000_unparsed_data = -1;
+/* Variables used for preferences */
gboolean catapult_dct2000_board_ports_only;
+gboolean catapult_dct2000_try_ipprim_heuristic = TRUE;
/* Protocol subtree. */
static int ett_catapult_dct2000 = -1;
@@ -69,6 +72,56 @@ static const value_string encap_vals[] = {
{ 0, NULL },
};
+/* Look for the protocol data within an ipprim packet.
+ Only set *data_offset if data field found. */
+gboolean find_ipprim_data_offset(tvbuff_t *tvb, int *data_offset)
+{
+ guint8 length;
+ int offset = *data_offset;
+ gboolean is_udp;
+
+ /* Get the ipprim command code. */
+ guint8 tag = tvb_get_guint8(tvb, offset++);
+
+ /* Only accept UDP or TCP data request or indication */
+ switch (tag)
+ {
+ case 0x23: /* UDP data request */
+ case 0x24: /* UDP data indication */
+ is_udp = TRUE;
+ break;
+ case 0x45: /* TCP data request */
+ case 0x46: /* TCP data indication */
+ is_udp = FALSE;
+ break;
+ default:
+ return FALSE;
+ }
+
+ /* Skip any other TLC fields before reach payload */
+ while (tvb_length_remaining(tvb, offset) > 2)
+ {
+ /* Look at next tag */
+ tag = tvb_get_guint8(tvb, offset++);
+
+ /* Is this the data payload we're expecting? */
+ if ((tag == 0x34 && is_udp) || (tag == 0x48 && !is_udp))
+ {
+ *data_offset = offset;
+ return TRUE;
+ }
+ else
+ {
+ /* Read length in next byte */
+ length = tvb_get_guint8(tvb, offset++);
+ /* Skip the following value */
+ offset += length;
+ }
+ }
+
+ /* No data found... */
+ return FALSE;
+}
/*****************************************/
/* Main dissection function. */
@@ -81,6 +134,7 @@ dissect_catapult_dct2000(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
gint offset = 0;
gint context_length;
guint8 port_number;
+ guint8 variant;
gint protocol_start;
gint protocol_length;
gint timestamp_start;
@@ -89,6 +143,7 @@ dissect_catapult_dct2000(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
tvbuff_t *next_tvb;
int encap;
dissector_handle_t protocol_handle = 0;
+ dissector_handle_t heur_ipprim_protocol_handle = 0;
int sub_dissector_result = 0;
/* Protocol name */
@@ -134,6 +189,12 @@ dissect_catapult_dct2000(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
offset, protocol_length, FALSE);
offset += protocol_length;
+ /* Variant */
+ variant = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(dct2000_tree, hf_catapult_dct2000_variant, tvb,
+ offset, 1, FALSE);
+ offset++;
+
/* Direction */
direction = tvb_get_guint8(tvb, offset);
proto_tree_add_item(dct2000_tree, hf_catapult_dct2000_direction, tvb,
@@ -149,12 +210,13 @@ dissect_catapult_dct2000(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_item_set_len(dct2000_tree, offset);
/* Add useful details to protocol tree label */
- proto_item_append_text(ti, " context=%s.%u t=%s %c prot=%s",
+ proto_item_append_text(ti, " context=%s.%u t=%s %c prot=%s (v=%d)",
tvb_get_ephemeral_string(tvb, 0, context_length),
port_number,
tvb_get_ephemeral_string(tvb, timestamp_start, timestamp_length),
(direction == 0) ? 'S' : 'R',
- tvb_get_ephemeral_string(tvb, protocol_start, protocol_length));
+ tvb_get_ephemeral_string(tvb, protocol_start, protocol_length),
+ variant);
/* Note that the first item of pinfo->pseudo_header->dct2000 will contain
@@ -197,7 +259,24 @@ dissect_catapult_dct2000(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
protocol_handle = find_dissector("mtp2");
break;
case DCT2000_ENCAP_UNHANDLED:
+ /* Many DCT2000 protocols have at least one IPPrim variant. If the
+ protocol names match, try to find the UDP/TCP data inside them and
+ pass that offset to dissector
+ */
protocol_handle = 0;
+
+ /* Try IP Prim heuristic if configured to */
+ if (catapult_dct2000_try_ipprim_heuristic)
+ {
+ heur_ipprim_protocol_handle =
+ find_dissector(tvb_get_ephemeral_string(tvb, protocol_start,
+ protocol_length));
+ if ((heur_ipprim_protocol_handle != 0) &&
+ find_ipprim_data_offset(tvb, &offset))
+ {
+ protocol_handle = heur_ipprim_protocol_handle;
+ }
+ }
break;
default:
@@ -205,7 +284,7 @@ dissect_catapult_dct2000(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
this dissector and the wiretap module catapult_dct2000.c !!
*/
DISSECTOR_ASSERT_NOT_REACHED();
- return;
+ return;
}
@@ -230,12 +309,13 @@ dissect_catapult_dct2000(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if (check_col(pinfo->cinfo, COL_INFO))
{
col_add_fstr(pinfo->cinfo, COL_INFO,
- "Unparsed protocol data (context=%s.%u t=%s %c prot=%s)",
+ "Unparsed protocol data (context=%s.%u t=%s %c prot=%s (v=%d))",
tvb_get_ephemeral_string(tvb, 0, context_length),
port_number,
tvb_get_ephemeral_string(tvb, timestamp_start, timestamp_length),
(direction == 0) ? 'S' : 'R',
- tvb_get_ephemeral_string(tvb, protocol_start, protocol_length));
+ tvb_get_ephemeral_string(tvb, protocol_start, protocol_length),
+ variant);
}
}
}
@@ -283,6 +363,12 @@ void proto_register_catapult_dct2000(void)
"Original (DCT2000) protocol name", HFILL
}
},
+ { &hf_catapult_dct2000_variant,
+ { "Protocol variant",
+ "dct2000.variant", FT_UINT8, BASE_DEC, NULL, 0x0,
+ "DCT2000 protocol variant", HFILL
+ }
+ },
{ &hf_catapult_dct2000_direction,
{ "Direction",
"dct2000.direction", FT_UINT8, BASE_DEC, VALS(direction_vals), 0x0,
@@ -331,5 +417,16 @@ void proto_register_catapult_dct2000(void)
"contexts on the same card. The capture file "
"needs to be (re)-loaded before effect will be seen",
&catapult_dct2000_board_ports_only);
+
+ /* Determines whether for not-handled protocols we should try to parse it if:
+ - it looks like its embedded in an ipprim message, AND
+ - the DCT2000 protocol name matches an ethereal dissector name */
+ prefs_register_bool_preference(catapult_dct2000_module, "ipprim_heuristic",
+ "Use IP Primitive heuristic",
+ "If a payload looks like its embedded in an "
+ "IP primitive messages, and there is an ethereal "
+ "dissector matching the DCT2000 protocol name, "
+ "try parsing the payload using that dissector",
+ &catapult_dct2000_try_ipprim_heuristic);
}
diff --git a/epan/dissectors/packet-diameter.c b/epan/dissectors/packet-diameter.c
index 2b0e2e0f50..8ed075529a 100644
--- a/epan/dissectors/packet-diameter.c
+++ b/epan/dissectors/packet-diameter.c
@@ -2291,6 +2291,9 @@ proto_register_diameter(void)
proto_register_field_array(proto_diameter, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
+ /* Allow dissector to find be found by name. */
+ new_register_dissector("diameter", dissect_diameter, proto_diameter);
+
/* Register a configuration option for port */
diameter_module = prefs_register_protocol(proto_diameter,
proto_reg_handoff_diameter);
diff --git a/epan/dissectors/packet-http.c b/epan/dissectors/packet-http.c
index 8e76502101..5167f986c9 100644
--- a/epan/dissectors/packet-http.c
+++ b/epan/dissectors/packet-http.c
@@ -2036,6 +2036,7 @@ proto_register_http(void)
"HTTP", "http");
proto_register_field_array(proto_http, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
+ register_dissector("http", dissect_http, proto_http);
http_module = prefs_register_protocol(proto_http, reinit_http);
prefs_register_bool_preference(http_module, "desegment_headers",
"Reassemble HTTP headers spanning multiple TCP segments",
diff --git a/plugins/mgcp/packet-mgcp.c b/plugins/mgcp/packet-mgcp.c
index 956504c41c..80b2b023ce 100644
--- a/plugins/mgcp/packet-mgcp.c
+++ b/plugins/mgcp/packet-mgcp.c
@@ -847,6 +847,8 @@ void proto_register_mgcp(void)
proto_register_subtree_array(ett, array_length(ett));
register_init_routine(&mgcp_init_protocol);
+ register_dissector("mgcp", dissect_mgcp, proto_mgcp);
+
/* Register our configuration options */
mgcp_module = prefs_register_protocol(proto_mgcp, proto_reg_handoff_mgcp);
@@ -950,7 +952,7 @@ static gboolean is_mgcp_verb(tvbuff_t *tvb, gint offset, gint maxlength, const g
/* Read the string into 'word' and see if it looks like the start of a verb */
if ((maxlength >= 4) && tvb_get_nstringz0(tvb, offset, sizeof(word), word))
{
- if (((strncasecmp(word, "EPCF", 4) == 0) && (*verb_name = "EndpointConfiguration|")) ||
+ if (((strncasecmp(word, "EPCF", 4) == 0) && (*verb_name = "EndpointConfiguration")) ||
((strncasecmp(word, "CRCX", 4) == 0) && (*verb_name = "CreateConnection")) ||
((strncasecmp(word, "MDCX", 4) == 0) && (*verb_name = "ModifyConnection")) ||
((strncasecmp(word, "DLCX", 4) == 0) && (*verb_name = "DeleteConnection")) ||
diff --git a/wiretap/catapult_dct2000.c b/wiretap/catapult_dct2000.c
index c28492ed20..b8bbe77eba 100644
--- a/wiretap/catapult_dct2000.c
+++ b/wiretap/catapult_dct2000.c
@@ -42,6 +42,7 @@
#define MAX_CONTEXT_NAME 64
#define MAX_PROTOCOL_NAME 64
#define MAX_PORT_DIGITS 2
+#define MAX_VARIANT_DIGITS 2
#define AAL_HEADER_CHARS 12
/* TODO:
@@ -101,8 +102,10 @@ static const gchar catapult_dct2000_magic[] = "Session Transcript";
static gchar context_name[MAX_CONTEXT_NAME];
static guint8 context_port;
-/* The DCT2000 protocol name of the packet */
+/* The DCT2000 protocol name of the packet, plus variant number */
static gchar protocol_name[MAX_PROTOCOL_NAME+1];
+static gchar variant;
+
/*************************************************/
/* Preference state (shared with stub protocol). */
@@ -136,6 +139,8 @@ static gboolean parse_line(gint line_length, gint *seconds, gint *useconds,
packet_direction_t *direction,
int *encap,
gboolean seek_read);
+int write_stub_header(guchar *frame_buffer, char *timestamp_string,
+ packet_direction_t direction, int encap);
static guchar hex_from_char(gchar c);
static gchar char_from_hex(guchar hex);
@@ -356,30 +361,8 @@ gboolean catapult_dct2000_read(wtap *wth, int *err, gchar **err_info _U_,
/*********************/
/* Write stub header */
-
- /* Context name */
- strcpy((char*)frame_buffer, context_name);
- stub_offset += (strlen(context_name) + 1);
-
- /* Context port number */
- frame_buffer[stub_offset] = context_port;
- stub_offset++;
-
- /* Timestamp within file */
- strcpy((char*)&frame_buffer[stub_offset], timestamp_string);
- stub_offset += (strlen(timestamp_string) + 1);
-
- /* Protocol name */
- strcpy((char*)&frame_buffer[stub_offset], protocol_name);
- stub_offset += (strlen(protocol_name) + 1);
-
- /* Direction */
- frame_buffer[stub_offset] = direction;
- stub_offset++;
-
- /* Encap */
- frame_buffer[stub_offset] = (guint8)encap;
- stub_offset++;
+ stub_offset = write_stub_header(frame_buffer, timestamp_string,
+ direction, encap);
/* Binary data length is half bytestring length + stub header */
wth->phdr.len = data_chars/2 + stub_offset;
@@ -394,7 +377,7 @@ gboolean catapult_dct2000_read(wtap *wth, int *err, gchar **err_info _U_,
(hex_from_char(linebuff[dollar_offset+n]) << 4) |
hex_from_char(linebuff[dollar_offset+n+1]);
}
-
+
/* Store the packet prefix in the hash table */
line_prefix_info = g_malloc(sizeof(line_prefix_info_t));
@@ -474,29 +457,9 @@ catapult_dct2000_seek_read(wtap *wth, long seek_off,
/*********************/
/* Write stub header */
+ stub_offset = write_stub_header((char*)pd, timestamp_string,
+ direction, encap);
- strcpy((char*)pd, context_name);
- stub_offset += (strlen(context_name) + 1);
-
- /* Context port number */
- pd[stub_offset] = context_port;
- stub_offset++;
-
- /* Timestamp within file */
- strcpy((char*)&pd[stub_offset], timestamp_string);
- stub_offset += (strlen(timestamp_string) + 1);
-
- /* Protocol name */
- strcpy((char*)&pd[stub_offset], protocol_name);
- stub_offset += (strlen(protocol_name) + 1);
-
- /* Direction */
- pd[stub_offset] = direction;
- stub_offset++;
-
- /* Encap */
- pd[stub_offset] = encap;
- stub_offset++;
/********************************/
/* Copy packet data into buffer */
@@ -776,6 +739,9 @@ gboolean parse_line(gint line_length, gint *seconds, gint *useconds,
int n = 0;
int port_digits = 0;
char port_number_string[MAX_PORT_DIGITS+1];
+ int variant_digits = 0;
+ char variant_number_string[MAX_VARIANT_DIGITS+1];
+
int protocol_chars = 0;
char seconds_buff[MAX_SECONDS_CHARS+1];
@@ -859,6 +825,8 @@ gboolean parse_line(gint line_length, gint *seconds, gint *useconds,
{
return FALSE;
}
+ /* Skip it */
+ n++;
/******************************************************************/
@@ -931,6 +899,32 @@ gboolean parse_line(gint line_length, gint *seconds, gint *useconds,
}
+ /* Following the / is the variant number. No digits indicate 1 */
+ for (variant_digits = 0;
+ (isdigit(linebuff[n])) && (variant_digits <= MAX_VARIANT_DIGITS) && (n+1 < line_length);
+ n++, variant_digits++)
+ {
+ if (!isdigit(linebuff[n]))
+ {
+ return FALSE;
+ }
+ variant_number_string[variant_digits] = linebuff[n];
+ }
+ if (variant_digits > MAX_VARIANT_DIGITS || (n+1 >= line_length))
+ {
+ return FALSE;
+ }
+ if (variant_digits > 0)
+ {
+ variant_number_string[variant_digits] = '\0';
+ variant = atoi(variant_number_string);
+ }
+ else
+ {
+ variant = 1;
+ }
+
+
/* Find separate ATM header if necessary */
if (atm_header_present)
{
@@ -1088,6 +1082,44 @@ gboolean parse_line(gint line_length, gint *seconds, gint *useconds,
return TRUE;
}
+/*****************************************************************/
+/* Write the stub info to the data buffer while reading a packet */
+/*****************************************************************/
+int write_stub_header(guchar *frame_buffer, char *timestamp_string,
+ packet_direction_t direction, int encap)
+{
+ int stub_offset = 0;
+
+ strcpy((char*)frame_buffer, context_name);
+ stub_offset += (strlen(context_name) + 1);
+
+ /* Context port number */
+ frame_buffer[stub_offset] = context_port;
+ stub_offset++;
+
+ /* Timestamp within file */
+ strcpy((char*)&frame_buffer[stub_offset], timestamp_string);
+ stub_offset += (strlen(timestamp_string) + 1);
+
+ /* Protocol name */
+ strcpy((char*)&frame_buffer[stub_offset], protocol_name);
+ stub_offset += (strlen(protocol_name) + 1);
+
+ /* Protocol variant number */
+ frame_buffer[stub_offset] = variant;
+ stub_offset++;
+
+ /* Direction */
+ frame_buffer[stub_offset] = direction;
+ stub_offset++;
+
+ /* Encap */
+ frame_buffer[stub_offset] = (guint8)encap;
+ stub_offset++;
+
+ return stub_offset;
+}
+
/**************************************************************/
/* Set pseudo-header info depending upon packet encapsulation */
diff --git a/wiretap/catapult_dct2000.h b/wiretap/catapult_dct2000.h
index 57b6efd388..fb936a91f6 100644
--- a/wiretap/catapult_dct2000.h
+++ b/wiretap/catapult_dct2000.h
@@ -27,3 +27,4 @@ int catapult_dct2000_dump_can_write_encap(int encap);
#define DCT2000_ENCAP_UNHANDLED 0
#define DCT2000_ENCAP_SSCOP 101
#define DCT2000_ENCAP_MTP2 102
+