Ethereal-dev: [Ethereal-dev] [Patch] An update to DCT2000 file support
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Martin Mathieson <martin.mathieson@xxxxxxxxxxxx>
Date: Mon, 22 May 2006 14:38:05 +0100
Hi,- 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
Regards, Martin
Index: wiretap/catapult_dct2000.c =================================================================== --- wiretap/catapult_dct2000.c (revision 18189) +++ wiretap/catapult_dct2000.c (working copy) @@ -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,9 +102,11 @@ 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). */ /* Set to FALSE to get better use out of other */ @@ -136,6 +139,8 @@ 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,31 +361,9 @@ /*********************/ /* Write stub header */ + stub_offset = write_stub_header(frame_buffer, timestamp_string, + direction, encap); - /* 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++; - /* Binary data length is half bytestring length + stub header */ wth->phdr.len = data_chars/2 + stub_offset; wth->phdr.caplen = data_chars/2 + stub_offset; @@ -394,7 +377,7 @@ (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,30 +457,10 @@ /*********************/ /* 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 */ for (n=0; n <= data_chars; n+=2) @@ -776,6 +739,9 @@ 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 @@ { return FALSE; } + /* Skip it */ + n++; /******************************************************************/ @@ -931,6 +899,32 @@ } + /* 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,7 +1082,45 @@ 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 */ /**************************************************************/
Index: wiretap/catapult_dct2000.h =================================================================== --- wiretap/catapult_dct2000.h (revision 18189) +++ wiretap/catapult_dct2000.h (working copy) @@ -27,3 +27,4 @@ #define DCT2000_ENCAP_UNHANDLED 0 #define DCT2000_ENCAP_SSCOP 101 #define DCT2000_ENCAP_MTP2 102 +
Index: epan/dissectors/packet-catapult-dct2000.c =================================================================== --- epan/dissectors/packet-catapult-dct2000.c (revision 18189) +++ epan/dissectors/packet-catapult-dct2000.c (working copy) @@ -41,11 +41,14 @@ 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,7 +72,57 @@ { 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 @@ gint offset = 0; gint context_length; guint8 port_number; + guint8 variant; gint protocol_start; gint protocol_length; gint timestamp_start; @@ -89,6 +143,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ this dissector and the wiretap module catapult_dct2000.c !! */ DISSECTOR_ASSERT_NOT_REACHED(); - return; + return; } @@ -230,12 +309,13 @@ 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 @@ "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 @@ "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); }
Index: epan/dissectors/packet-diameter.c =================================================================== --- epan/dissectors/packet-diameter.c (revision 18189) +++ epan/dissectors/packet-diameter.c (working copy) @@ -2291,6 +2291,9 @@ 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);
Index: plugins/mgcp/packet-mgcp.c =================================================================== --- plugins/mgcp/packet-mgcp.c (revision 18189) +++ plugins/mgcp/packet-mgcp.c (working copy) @@ -847,6 +847,8 @@ 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 @@ /* 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")) ||
Index: epan/dissectors/packet-http.c =================================================================== --- epan/dissectors/packet-http.c (revision 18189) +++ epan/dissectors/packet-http.c (working copy) @@ -2036,6 +2036,7 @@ "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",
_______________________________________________ Ethereal-dev mailing list Ethereal-dev@xxxxxxxxxxxx http://www.ethereal.com/mailman/listinfo/ethereal-dev
- Prev by Date: Re: [Ethereal-dev] Re: problem in protocol item tree header field display
- Next by Date: [Ethereal-dev] [PATCH] dissect tivoconnect beacons
- Previous by thread: Re: [Ethereal-dev] COM interfaces registry lookup feature broken?
- Next by thread: [Ethereal-dev] [PATCH] dissect tivoconnect beacons
- Index(es):