summaryrefslogtreecommitdiff
path: root/epan/dissectors/packet-bt-dht.c
diff options
context:
space:
mode:
authorBill Meier <wmeier@newsguy.com>2012-01-20 03:24:05 +0000
committerBill Meier <wmeier@newsguy.com>2012-01-20 03:24:05 +0000
commit1311f29800d0bda5895cf200804b7872bbd0c0a7 (patch)
tree87e747c208b84b528be9c59cdfd7660e8a052665 /epan/dissectors/packet-bt-dht.c
parent0a6eca4097b839b3c02fe1d18da04f33fb935bdd (diff)
downloadwireshark-1311f29800d0bda5895cf200804b7872bbd0c0a7.tar.gz
Fix Fix "bt-dht [..] NOT registered properly" as reported in Bug #6571.
"bt-dht [...] should also be common dissectors while not only heuristic ones. So we can use them with 'Decode As...' command." Essentially: -Register dissector handle so the dissector can be accessed via "decode-as". From me: 1. Given that the current heuristic is much too weak and causes 'false positives': Add a preference to allow enabling/disabling of heuristic dissection. The default is 'disabled' since the current heuristic is quite weak. (For example: The heuristic incorrectly dissects about 40 files in menagerie/public as being the BT-DHT protocol). Note: only heuristic dissection is disabled; 'decode-as' remains enabled. Also: 1. Fix some bugs wherein bytes in the hex pane were not highlighted when a field was selected in the details pane. 2. Do some minor re-formatting of the source code. svn path=/trunk/; revision=40603
Diffstat (limited to 'epan/dissectors/packet-bt-dht.c')
-rw-r--r--epan/dissectors/packet-bt-dht.c180
1 files changed, 119 insertions, 61 deletions
diff --git a/epan/dissectors/packet-bt-dht.c b/epan/dissectors/packet-bt-dht.c
index ed242b3f92..b821d37e8d 100644
--- a/epan/dissectors/packet-bt-dht.c
+++ b/epan/dissectors/packet-bt-dht.c
@@ -32,6 +32,7 @@
#include <epan/packet.h>
#include <epan/conversation.h>
+#include <epan/prefs.h>
/* Specifications: BEP-0005
* http://www.bittorrent.org/beps/bep_0005.html
@@ -40,6 +41,8 @@
static int proto_bt_dht = -1;
static dissector_handle_t bt_dht_handle;
+static gboolean bt_dht_enable_heuristic_dissection = FALSE; /* disabled by default since heuristic is weak */
+
/* fields */
static int hf_bencoded_int = -1;
static int hf_bencoded_string = -1;
@@ -93,7 +96,9 @@ static const char list_str[] = "list...";
* dissect a bencoded string from tvb, start at offset. it's like "5:abcde"
* *result will be the decoded value
*/
-static int dissect_bencoded_string(tvbuff_t *tvb, packet_info _U_*pinfo, proto_tree *tree, guint offset, char **result, gboolean tohex, char *label )
+
+static int
+dissect_bencoded_string(tvbuff_t *tvb, packet_info _U_*pinfo, proto_tree *tree, guint offset, char **result, gboolean tohex, char *label )
{
guint string_len_start;
guint string_len;
@@ -101,11 +106,11 @@ static int dissect_bencoded_string(tvbuff_t *tvb, packet_info _U_*pinfo, proto_t
string_len_start = offset;
while( tvb_get_guint8(tvb,offset) != ':' )
- offset ++;
+ offset += 1;
string_len = atoi( tvb_get_ephemeral_string(tvb,string_len_start,offset-string_len_start) );
/* skip the ':' */
- offset++;
+ offset += 1;
/* fill the return data */
if( tohex )
@@ -122,23 +127,24 @@ static int dissect_bencoded_string(tvbuff_t *tvb, packet_info _U_*pinfo, proto_t
* dissect a bencoded integer from tvb, start at offset. it's like "i5673e"
* *result will be the decoded value
*/
-static int dissect_bencoded_int(tvbuff_t *tvb, packet_info _U_*pinfo, proto_tree *tree, guint offset, char **result, char *label )
+static int
+dissect_bencoded_int(tvbuff_t *tvb, packet_info _U_*pinfo, proto_tree *tree, guint offset, char **result, char *label )
{
guint start_offset;
start_offset = offset;
- /* we has confirmed that the first byte is 'i' */
- offset ++;
+ /* we have confirmed that the first byte is 'i' */
+ offset += 1;
while( tvb_get_guint8(tvb,offset)!='e' )
- offset ++;
+ offset += 1;
*result = tvb_get_ephemeral_string( tvb, offset, offset-start_offset-1 );
proto_tree_add_string_format( tree, hf_bencoded_int, tvb, offset, offset-start_offset-1, *result,
"%s: %s", label, *result );
- offset ++;
+ offset += 1;
return offset;
}
@@ -146,18 +152,19 @@ static int dissect_bencoded_int(tvbuff_t *tvb, packet_info _U_*pinfo, proto_tree
static int dissect_bencoded_dict(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, char *label );
/* dissect a bencoded list from tvb, start at offset. it's like "lXXXe", "X" is any bencoded thing */
-static int dissect_bencoded_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, char *label )
+static int
+dissect_bencoded_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, char *label )
{
proto_item *ti;
proto_tree *sub_tree;
- guint one_byte;
- char *result;
+ guint one_byte;
+ char *result;
ti = proto_tree_add_none_format( tree, hf_bencoded_list, tvb, offset, 0, "%s: list...", label );
sub_tree = proto_item_add_subtree( ti, ett_bencoded_list);
/* skip the 'l' */
- offset++;
+ offset += 1;
while( (one_byte=tvb_get_guint8(tvb,offset)) != 'e' )
{
@@ -181,25 +188,26 @@ static int dissect_bencoded_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
break;
}
}
- offset++;
+ offset += 1;
return offset;
}
/* dissect a bt dht error from tvb, start at offset. it's like "li201e9:error msge" */
-static int dissect_bt_dht_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, char **result, char *label )
+static int
+dissect_bt_dht_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, char **result, char *label )
{
proto_item *ti;
proto_tree *sub_tree;
- char *error_no, *error_msg;
+ char *error_no, *error_msg;
- error_no = NULL;
+ error_no = NULL;
error_msg = NULL;
- ti = proto_tree_add_item( tree, hf_bt_dht_error, tvb, offset, 0, ENC_NA );
+ ti = proto_tree_add_item( tree, hf_bt_dht_error, tvb, offset, 0, ENC_NA );
sub_tree = proto_item_add_subtree( ti, ett_bt_dht_error);
/* we have confirmed that the first byte is 'l' */
- offset ++;
+ offset += 1;
/* dissect bt-dht error number and message */
offset = dissect_bencoded_int( tvb, pinfo, sub_tree, offset, &error_no, "Error ID" );
@@ -213,40 +221,41 @@ static int dissect_bt_dht_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
}
/* dissect a bt dht values list from tvb, start at offset. it's like "l6:....6:....e" */
-static int dissect_bt_dht_values(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, char **result, char *label )
+static int
+dissect_bt_dht_values(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, char **result, char *label )
{
proto_item *ti;
proto_tree *sub_tree;
proto_item *value_ti;
proto_tree *value_tree;
- address addr;
+ address addr;
- guint peer_index;
- guint string_len_start;
- guint string_len;
- guint16 port;
+ guint peer_index;
+ guint string_len_start;
+ guint string_len;
+ guint16 port;
ti = proto_tree_add_item( tree, hf_bt_dht_peers, tvb, offset, 0, ENC_NA );
sub_tree = proto_item_add_subtree( ti, ett_bt_dht_peers);
peer_index = 0;
/* we has confirmed that the first byte is 'l' */
- offset ++;
+ offset += 1;
/* dissect bt-dht values */
while( tvb_get_guint8(tvb,offset)!='e' )
{
string_len_start = offset;
while( tvb_get_guint8(tvb,offset) != ':' )
- offset ++;
+ offset += 1;
string_len = atoi( tvb_get_ephemeral_string(tvb,string_len_start,offset-string_len_start) );
/* skip the ':' */
- offset++;
+ offset += 1;
/* 4 bytes ip, 2 bytes port */
for( ; string_len>=6; string_len-=6, offset+=6 )
{
- peer_index ++;
+ peer_index += 1;
SET_ADDRESS( &addr, AT_IPv4, 4, tvb_get_ptr( tvb, offset, 4) );
port = tvb_get_letohl( tvb, offset+4 );
@@ -271,19 +280,20 @@ static int dissect_bt_dht_values(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
return offset;
}
-static int dissect_bt_dht_nodes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, char **result, char *label )
+static int
+dissect_bt_dht_nodes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, char **result, char *label )
{
proto_item *ti;
proto_tree *sub_tree;
proto_item *node_ti;
proto_tree *node_tree;
- guint node_index;
- guint string_len_start;
- guint string_len;
- address addr;
- guint16 port;
- guint8 *id;
+ guint node_index;
+ guint string_len_start;
+ guint string_len;
+ address addr;
+ guint16 port;
+ guint8 *id;
ti = proto_tree_add_item( tree, hf_bt_dht_nodes, tvb, offset, 0, ENC_NA );
sub_tree = proto_item_add_subtree( ti, ett_bt_dht_nodes);
@@ -291,16 +301,16 @@ static int dissect_bt_dht_nodes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
string_len_start = offset;
while( tvb_get_guint8(tvb,offset) != ':' )
- offset ++;
+ offset += 1;
string_len = atoi( tvb_get_ephemeral_string(tvb,string_len_start,offset-string_len_start) );
/* skip the ':' */
- offset++;
+ offset += 1;
/* 20 bytes id, 4 bytes ip, 2 bytes port */
for( ; string_len>=26; string_len-=26, offset+=26 )
{
- node_index++;
+ node_index += 1;
id = tvb_bytes_to_str(tvb, offset, 20 );
SET_ADDRESS( &addr, AT_IPv4, 4, tvb_get_ptr( tvb, offset, 4) );
@@ -326,28 +336,30 @@ static int dissect_bt_dht_nodes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
return offset;
}
-static int dissect_bencoded_dict_entry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset )
+static int
+dissect_bencoded_dict_entry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset )
{
proto_item *ti;
proto_tree *sub_tree;
- gboolean tohex;
- char *key, *val;
+ gboolean tohex;
+ char *key, *val;
+ guint orig_offset = offset;
key = NULL;
val = NULL;
- ti = proto_tree_add_item( tree, hf_bencoded_dict_entry, tvb, offset, 0, ENC_NA );
+ ti = proto_tree_add_item( tree, hf_bencoded_dict_entry, tvb, offset, 0, ENC_NA );
sub_tree = proto_item_add_subtree( ti, ett_bencoded_dict_entry);
/* dissect the key, it must be a string */
- offset = dissect_bencoded_string( tvb, pinfo, sub_tree, offset, &key, FALSE, "Key" );
+ offset = dissect_bencoded_string( tvb, pinfo, sub_tree, offset, &key, FALSE, "Key" );
- /* it is a dict, just recursion */
+ /* If it is a dict, then just do recursion */
switch( tvb_get_guint8(tvb,offset) )
{
case 'd':
offset = dissect_bencoded_dict( tvb, pinfo, sub_tree, offset, "Value" );
- val = (char*)dict_str;
+ val = (char*)dict_str;
break;
case 'l':
if( strcmp(key,"e")==0 )
@@ -385,6 +397,7 @@ static int dissect_bencoded_dict_entry(tvbuff_t *tvb, packet_info *pinfo, proto_
val = (char*)val_to_str( val[0], short_val_name_value_string, val );
proto_item_set_text( ti, "%s: %s", key, val );
+ proto_item_set_len( ti, offset-orig_offset );
if( strcmp(key,"message_type")==0 || strcmp(key,"request_type")==0 )
col_append_fstr(pinfo->cinfo, COL_INFO, "%s=%s ", key, val);
@@ -393,50 +406,60 @@ static int dissect_bencoded_dict_entry(tvbuff_t *tvb, packet_info *pinfo, proto_
}
/* dict = d...e */
-static int dissect_bencoded_dict(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, char *label )
+static int
+dissect_bencoded_dict(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, char *label )
{
proto_item *ti;
proto_tree *sub_tree;
+ guint orig_offset = offset;
ti = proto_tree_add_none_format( tree, hf_bencoded_dict, tvb, offset, 0, "%s: dictionary...", label );
sub_tree = proto_item_add_subtree( ti, ett_bencoded_dict);
/* skip the first char('d') */
- offset ++;
+ offset += 1;
while( tvb_get_guint8(tvb,offset)!='e' )
offset = dissect_bencoded_dict_entry( tvb, pinfo, sub_tree, offset );
- offset++;
+ offset += 1;
+ proto_item_set_len( ti, offset-orig_offset );
+
return offset;
}
-static void dissect_bt_dht(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+static int
+dissect_bt_dht(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
col_set_str(pinfo->cinfo, COL_PROTOCOL, "BT-DHT");
col_clear(pinfo->cinfo, COL_INFO);
- if( tree )
- dissect_bencoded_dict(tvb, pinfo, tree, 0, "BT-DHT Protocol" );
+
+ return dissect_bencoded_dict(tvb, pinfo, tree, 0, "BT-DHT Protocol" );
}
-static gboolean test_bt_dht_packet (tvbuff_t *tvb, packet_info *pinfo,
+static
+gboolean dissect_bt_dht_heur (tvbuff_t *tvb, packet_info *pinfo,
proto_tree *tree)
{
- conversation_t *conversation;
-
/* try dissecting */
+ /* XXX: This is a very weak heuristic; so: heuristic dissection is disabled by default */
if( tvb_get_guint8(tvb,0)=='d' )
{
- conversation = find_or_create_conversation(pinfo);
- conversation_set_dissector(conversation, bt_dht_handle);
+ conversation_t *conversation;
- dissect_bt_dht(tvb, pinfo, tree);
- return TRUE;
+ conversation = find_or_create_conversation(pinfo);
+ conversation_set_dissector(conversation, bt_dht_handle);
+
+ dissect_bt_dht(tvb, pinfo, tree);
+ return TRUE;
}
return FALSE;
}
-void proto_register_bt_dht(void)
+void proto_reg_handoff_bt_dht(void);
+
+void
+proto_register_bt_dht(void)
{
static hf_register_info hf[] = {
{ &hf_bencoded_string,
@@ -508,18 +531,53 @@ void proto_register_bt_dht(void)
&ett_bencoded_dict_entry
};
+ module_t *bt_dht_module;
+
proto_bt_dht = proto_register_protocol (
"Bittorrent DHT Protocol", /* name */
"BT-DHT", /* short name */
"bt-dht" /* abbrev */
);
+ bt_dht_module = prefs_register_protocol(proto_bt_dht, proto_reg_handoff_bt_dht);
+ prefs_register_bool_preference(bt_dht_module, "enable", "Enable BT-DHT heuristic_dissection",
+ "Enable BT-DHT heuristic dissection (default is disabled)",
+ &bt_dht_enable_heuristic_dissection);
+
proto_register_field_array(proto_bt_dht, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
}
-void proto_reg_handoff_bt_dht(void)
+void
+proto_reg_handoff_bt_dht(void)
{
- heur_dissector_add("udp", test_bt_dht_packet, proto_bt_dht);
+ static gboolean prefs_initialized = FALSE;
+
+ /* "Decode As" is always available;
+ * Heuristic dissection in disabled by default since the heuristic is quite weak.
+ */
+ if (!prefs_initialized) {
+ heur_dissector_add("udp", dissect_bt_dht_heur, proto_bt_dht);
+
+ bt_dht_handle = new_create_dissector_handle(dissect_bt_dht, proto_bt_dht);
+ dissector_add_handle("udp.port", bt_dht_handle); /* for "decode_as" */
+
+ prefs_initialized = TRUE;
+ }
+
+ heur_dissector_set_enabled("udp", dissect_bt_dht_heur, proto_bt_dht, bt_dht_enable_heuristic_dissection);
}
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 2
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=2 tabstop=8 expandtab:
+ * :indentSize=2:tabSize=8:noTabs=true:
+ */
+