Wireshark-dev: [Wireshark-dev] DCT2000 [Patch]
From: Martin Mathieson <martin.mathieson@xxxxxxxxxxxx>
Date: Fri, 30 Jun 2006 17:29:03 +0100
Hi, this patch: - Removes last traces of 'board ports only' preference- Add a preference to try to find messages within sctp primitive messages (tries renaming of known mismatches)
- Add outhdr to stub protocol (getting ready for IuB FP) Regards, Martin
Index: wiretap/catapult_dct2000.c =================================================================== --- wiretap/catapult_dct2000.c (revision 18621) +++ wiretap/catapult_dct2000.c (working copy) @@ -43,6 +43,7 @@ #define MAX_PROTOCOL_NAME 64 #define MAX_PORT_DIGITS 2 #define MAX_VARIANT_DIGITS 32 +#define MAX_OUTHDR_NAME 64 #define AAL_HEADER_CHARS 12 /* TODO: @@ -105,14 +106,9 @@ /* The DCT2000 protocol name of the packet, plus variant number */ static gchar protocol_name[MAX_PROTOCOL_NAME+1]; static gchar variant_name[MAX_VARIANT_DIGITS+1]; +static gchar outhdr_name[MAX_OUTHDR_NAME+1]; -/*************************************************/ -/* Preference state (shared with stub protocol). */ -/* Set to FALSE to get better use out of other */ -/* wiretap applications (mergecap, editcap) */ -gboolean catapult_dct2000_board_ports_only = FALSE; - /************************************************************/ /* Functions called from wiretap */ static gboolean catapult_dct2000_read(wtap *wth, int *err, gchar **err_info, @@ -137,8 +133,7 @@ long *data_offset, gint *data_chars, packet_direction_t *direction, - int *encap, - gboolean seek_read); + int *encap); static int write_stub_header(guchar *frame_buffer, char *timestamp_string, packet_direction_t direction, int encap); static guchar hex_from_char(gchar c); @@ -319,7 +314,7 @@ if (parse_line(line_length, &seconds, &useconds, &before_time_offset, &after_time_offset, &dollar_offset, - &data_chars, &direction, &encap, FALSE)) + &data_chars, &direction, &encap)) { guchar *frame_buffer; int n; @@ -444,7 +439,7 @@ if (parse_line(length, &seconds, &useconds, &before_time_offset, &after_time_offset, &dollar_offset, - &data_chars, &direction, &encap, TRUE)) + &data_chars, &direction, &encap)) { int n; int stub_offset = 0; @@ -652,6 +647,10 @@ for (; pd[n] != '\0'; n++); n++; + /* Outhdr (as string) */ + for (; pd[n] != '\0'; n++); + n++; + /* Direction & encap */ n += 2; @@ -737,14 +736,15 @@ long *before_time_offset, long *after_time_offset, long *data_offset, gint *data_chars, packet_direction_t *direction, - int *encap, - gboolean seek_read) + int *encap) { int n = 0; int port_digits = 0; char port_number_string[MAX_PORT_DIGITS+1]; int variant_digits = 0; + int variant = 1; int protocol_chars = 0; + int outhdr_chars = 0; char seconds_buff[MAX_SECONDS_CHARS+1]; int seconds_chars; @@ -831,6 +831,61 @@ n++; + /* 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_name[variant_digits] = linebuff[n]; + } + if (variant_digits > MAX_VARIANT_DIGITS || (n+1 >= line_length)) + { + return FALSE; + } + if (variant_digits > 0) + { + variant_name[variant_digits] = '\0'; + variant = atoi(variant_name); + } + else + { + strcpy(variant_name, "1"); + } + + + /* Outheader values may follow */ + outhdr_name[0] = '\0'; + if (linebuff[n] == ',') + { + /* Skip , */ + n++; + + for (outhdr_chars = 0; + (isdigit(linebuff[n]) || linebuff[n] == ',') && + (outhdr_chars <= MAX_OUTHDR_NAME) && (n+1 < line_length); + n++, outhdr_chars++) + { + if (!isdigit(linebuff[n]) && (linebuff[n] != ',')) + { + return FALSE; + } + outhdr_name[outhdr_chars] = linebuff[n]; + } + if (outhdr_chars > MAX_OUTHDR_NAME || (n+1 >= line_length)) + { + return FALSE; + } + /* Terminate (possibly empty) string */ + outhdr_name[outhdr_chars] = '\0'; + } + + + + /******************************************************************/ /* Now check whether we know how to use a packet of this protocol */ @@ -840,14 +895,23 @@ } else - /* For ATM protocols, we need to read the separate atm headerparse */ + /* FP may be carried over ATM, which has separate atm header to parse */ if ((strcmp(protocol_name, "fp") == 0) || (strcmp(protocol_name, "fp_r4") == 0) || (strcmp(protocol_name, "fp_r5") == 0) || (strcmp(protocol_name, "fp_r6") == 0)) { - *encap = WTAP_ENCAP_ATM_PDUS_UNTRUNCATED; - atm_header_present = TRUE; + if ((variant > 256) && (variant % 256 == 3)) + { + /* FP over udp is contained in IPPrim... */ + *encap = 0; + } + else + { + /* FP over AAL0 or AAL2 */ + *encap = WTAP_ENCAP_ATM_PDUS_UNTRUNCATED; + atm_header_present = TRUE; + } } else @@ -884,48 +948,11 @@ } else { - /* Only reject protocol if reading for the first time and preference - setting says board ports only. This should not fail to read a - non board-port protocol on re-reading because the preference setting - has since changed... - */ - if (catapult_dct2000_board_ports_only && !seek_read) - { - return FALSE; - } - else - { - /* Not a supported protocol/encap, but should show as raw data anyway */ - *encap = DCT2000_ENCAP_UNHANDLED; - } + /* Not a supported board port protocol/encap, but can show as raw data anyway */ + *encap = DCT2000_ENCAP_UNHANDLED; } - /* 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_name[variant_digits] = linebuff[n]; - } - if (variant_digits > MAX_VARIANT_DIGITS || (n+1 >= line_length)) - { - return FALSE; - } - if (variant_digits > 0) - { - variant_name[variant_digits] = '\0'; - } - else - { - strcpy(variant_name, "1"); - } - - /* Find separate ATM header if necessary */ if (atm_header_present) { @@ -1106,10 +1133,14 @@ strcpy((char*)&frame_buffer[stub_offset], protocol_name); stub_offset += (strlen(protocol_name) + 1); - /* Protocol variant number */ + /* Protocol variant number (as string) */ strcpy((void*)&frame_buffer[stub_offset], variant_name); stub_offset += (strlen(variant_name) + 1); + /* Outhdr */ + strcpy((char*)&frame_buffer[stub_offset], outhdr_name); + stub_offset += (strlen(outhdr_name) + 1); + /* Direction */ frame_buffer[stub_offset] = direction; stub_offset++; @@ -1117,7 +1148,7 @@ /* Encap */ frame_buffer[stub_offset] = (guint8)encap; stub_offset++; - + return stub_offset; }
Index: epan/dissectors/packet-catapult-dct2000.c =================================================================== --- epan/dissectors/packet-catapult-dct2000.c (revision 18621) +++ epan/dissectors/packet-catapult-dct2000.c (working copy) @@ -42,19 +42,21 @@ 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_outhdr = -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_try_ipprim_heuristic = TRUE; +gboolean catapult_dct2000_try_sctpprim_heuristic = TRUE; /* Protocol subtree. */ static int ett_catapult_dct2000 = -1; static const value_string direction_vals[] = { - { 0, "Sent" }, - { 1, "Received" }, + { 0, "Sent" }, + { 1, "Received" }, { 0, NULL }, }; @@ -122,6 +124,80 @@ return FALSE; } + + +/* Look for the protocol data within an sctpprim (variant 1 or 2...) packet. + Only set *data_offset if data field found. */ +static gboolean find_sctpprim_data_offset(tvbuff_t *tvb, int *data_offset) +{ + guint8 length; + int offset = *data_offset; + + /* Get the sctpprim command code. */ + guint8 tag = tvb_get_guint8(tvb, offset++); + + /* Only accept UDP or TCP data request or indication */ + switch (tag) + { + case 0x04: /* data request */ + case 0x62: /* data indication */ + break; + default: + return FALSE; + } + + /* Length field. msb set indicates 2 bytes */ + if (tvb_get_guint8(tvb, offset) & 0x80) + { + offset += 2; + } + else + { + offset++; + } + + /* 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 == 0x19) + { + *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; +} + + +/* Look up dissector by protocol name. Fix up known name mis-matches. */ +dissector_handle_t look_for_dissector(char *protocol_name) +{ + /* Use know aliases... */ + if (strcmp(protocol_name, "tbcp") == 0) + { + return find_dissector("rtcp"); + } + else + { + /* Presume name matches exactly */ + return find_dissector(protocol_name); + } +} + + /*****************************************/ /* Main dissection function. */ /*****************************************/ @@ -139,11 +215,13 @@ gint timestamp_length; gint variant_start; gint variant_length; + gint outhdr_start; + gint outhdr_length; guint8 direction; tvbuff_t *next_tvb; int encap; dissector_handle_t protocol_handle = 0; - dissector_handle_t heur_ipprim_protocol_handle = 0; + dissector_handle_t heur_protocol_handle = 0; int sub_dissector_result = 0; /* Protocol name */ @@ -196,6 +274,17 @@ offset, variant_length, FALSE); offset += variant_length; + /* Outhdr */ + outhdr_start = offset; + outhdr_length = tvb_strsize(tvb, offset); + if (outhdr_length > 1) + { + proto_tree_add_item(dct2000_tree, hf_catapult_dct2000_outhdr, tvb, + offset, outhdr_length, FALSE); + } + offset += outhdr_length; + + /* Direction */ direction = tvb_get_guint8(tvb, offset); proto_tree_add_item(dct2000_tree, hf_catapult_dct2000_direction, tvb, @@ -269,15 +358,29 @@ /* 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, + heur_protocol_handle = + look_for_dissector(tvb_get_ephemeral_string(tvb, protocol_start, protocol_length)); - if ((heur_ipprim_protocol_handle != 0) && + if ((heur_protocol_handle != 0) && find_ipprim_data_offset(tvb, &offset)) { - protocol_handle = heur_ipprim_protocol_handle; + protocol_handle = heur_protocol_handle; } } + + /* Try SCTP Prim heuristic if configured to */ + if (!protocol_handle && catapult_dct2000_try_sctpprim_heuristic) + { + heur_protocol_handle = + look_for_dissector(tvb_get_ephemeral_string(tvb, protocol_start, + protocol_length)); + if ((heur_protocol_handle != 0) && + find_sctpprim_data_offset(tvb, &offset)) + { + protocol_handle = heur_protocol_handle; + } + } + break; default: @@ -370,6 +473,12 @@ "DCT2000 protocol variant", HFILL } }, + { &hf_catapult_dct2000_outhdr, + { "Out-header", + "dct2000.outhdr", FT_STRING, BASE_NONE, NULL, 0x0, + "DCT2000 protocol outhdr", HFILL + } + }, { &hf_catapult_dct2000_direction, { "Direction", "dct2000.direction", FT_UINT8, BASE_DEC, VALS(direction_vals), 0x0, @@ -410,24 +519,26 @@ catapult_dct2000_module = prefs_register_protocol(proto_catapult_dct2000, proto_reg_handoff_catapult_dct2000); - /* Determines whether non-supported protocols should be shown anyway */ -/* prefs_register_bool_preference(catapult_dct2000_module, "board_ports_only", - "Only show known 'board-port' protocols", - "Don't show other protocols, i.e. unknown board-port " - "protocols and non-standard primitives between " - "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 wireshark 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 wireshark " + "IP primitive message, and there is an wireshark " "dissector matching the DCT2000 protocol name, " "try parsing the payload using that dissector", &catapult_dct2000_try_ipprim_heuristic); + + /* Determines whether for not-handled protocols we should try to parse it if: + - it looks like its embedded in an sctpprim message, AND + - the DCT2000 protocol name matches an wireshark dissector name */ + prefs_register_bool_preference(catapult_dct2000_module, "sctpprim_heuristic", + "Use SCTP Primitive heuristic", + "If a payload looks like its embedded in an " + "SCTP primitive message, and there is an wireshark " + "dissector matching the DCT2000 protocol name, " + "try parsing the payload using that dissector", + &catapult_dct2000_try_sctpprim_heuristic); }
- Follow-Ups:
- Re: [Wireshark-dev] DCT2000 [Patch]
- From: Jaap Keuter
- Re: [Wireshark-dev] DCT2000 [Patch]
- Prev by Date: [Wireshark-dev] Problems building register.c on Win XP
- Next by Date: Re: [Wireshark-dev] DCT2000 [Patch]
- Previous by thread: [Wireshark-dev] Problems building register.c on Win XP
- Next by thread: Re: [Wireshark-dev] DCT2000 [Patch]
- Index(es):