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):