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; guint orig_offset = offset; key = NULL; val = NULL; 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" ); /* 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; break; case 'l': if( strcmp(key,"e")==0 ) offset = dissect_bt_dht_error( tvb, pinfo, sub_tree, offset, &val, "Value" ); else if( strcmp(key,"values")==0 ) offset = dissect_bt_dht_values( tvb, pinfo, sub_tree, offset, &val, "Value" ); /* other unfamiliar lists */ else { offset = dissect_bencoded_list( tvb, pinfo, sub_tree, offset, "Value" ); val = (char*)list_str; } break; case 'i': offset = dissect_bencoded_int( tvb, pinfo, sub_tree, offset, &val, "Value" ); break; /* it's a string */ default: /* special process */ if( strcmp(key,"nodes")==0 ) offset = dissect_bt_dht_nodes( tvb, pinfo, sub_tree, offset, &val, "Value" ); /* some need to return hex string */ else { tohex = strcmp(key,"id")==0 || strcmp(key,"target")==0 || strcmp(key,"info_hash")==0 || strcmp(key,"t")==0 || strcmp(key,"v")==0; offset = dissect_bencoded_string( tvb, pinfo, sub_tree, offset, &val, tohex, "Value" ); } } if( strlen(key)==1 ) key = (char*)val_to_str( key[0], short_key_name_value_string, key ); if( strlen(val)==1 ) 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); return 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; const char *key; const char *val; guint orig_offset = offset; key = NULL; val = NULL; 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" ); /* 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 = dict_str; break; case 'l': if( strcmp(key,"e")==0 ) offset = dissect_bt_dht_error( tvb, pinfo, sub_tree, offset, &val, "Value" ); else if( strcmp(key,"values")==0 ) offset = dissect_bt_dht_values( tvb, pinfo, sub_tree, offset, &val, "Value" ); /* other unfamiliar lists */ else { offset = dissect_bencoded_list( tvb, pinfo, sub_tree, offset, "Value" ); val = list_str; } break; case 'i': offset = dissect_bencoded_int( tvb, pinfo, sub_tree, offset, &val, "Value" ); break; /* it's a string */ default: /* special process */ if( strcmp(key,"nodes")==0 ) { offset = dissect_bt_dht_nodes( tvb, pinfo, sub_tree, offset, &val, "Value" ); } else if( strcmp(key,"ip")==0 ) { /* * Not found in BEP 0005 but explained by * http://www.rasterbar.com/products/libtorrent/dht_sec.html */ int len, old_offset; old_offset = offset; len = bencoded_string_length(tvb, &offset); if(len == 4) { proto_tree_add_item(sub_tree, hf_ip, tvb, offset, len, ENC_BIG_ENDIAN); val = tvb_ip_to_str(tvb, offset); offset += len; } else { offset = dissect_bencoded_string( tvb, pinfo, sub_tree, old_offset, &val, TRUE, "Value" ); } } else { /* some need to return hex string */ tohex = strcmp(key,"id")==0 || strcmp(key,"target")==0 || strcmp(key,"info_hash")==0 || strcmp(key,"t")==0 || strcmp(key,"v")==0 || strcmp(key,"token")==0; offset = dissect_bencoded_string( tvb, pinfo, sub_tree, offset, &val, tohex, "Value" ); } } if( strlen(key)==1 ) key = val_to_str_const( key[0], short_key_name_value_string, key ); if( strlen(val)==1 ) val = val_to_str_const( 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); return offset; }