Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-vuze-dht.c
blobac8cf75fc5befa5054066bce5e82fbdf4ebb483a
1 /* packet-vuze-dht.c
2 * Routines for Vuze-DHT dissection
3 * Copyright 2011, Xiao Xiangquan <xiaoxiangquan@gmail.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1999 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 #include "config.h"
14 #include <epan/packet.h>
15 #include <epan/to_str.h>
17 #define DEFAULT_UDP_PORT 11273 /* Not IANA registered */
19 void proto_register_vuze_dht(void);
21 /* --- protocol specification:
22 * http://wiki.vuze.com/w/Distributed_hash_table
25 /* protocol versions */
26 enum {
27 PV_DIV_AND_CONT = 6,
28 PV_ANTI_SPOOF = 7,
29 PV_ANTI_SPOOF2 = 8,
30 PV_FIX_ORIGINATOR = 9,
31 PV_NETWORKS = 9,
32 PV_VIVALDI = 10,
33 PV_REMOVE_DIST_ADD_VER = 11,
34 PV_XFER_STATUS = 12,
35 PV_SIZE_ESTIMATE = 13,
36 PV_VENDOR_ID = 14,
37 PV_BLOCK_KEYS = 14,
38 PV_GENERIC_NETPOS = 15,
39 PV_VIVALDI_FINDVALUE = 16,
40 PV_ANON_VALUES = 17,
41 PV_CVS_FIX_OVERLOAD_V1 = 18,
42 PV_CVS_FIX_OVERLOAD_V2 = 19,
43 PV_MORE_STATS = 20,
44 PV_CVS_FIX_OVERLOAD_V3 = 21,
45 PV_MORE_NODE_STATUS = 22,
46 PV_LONGER_LIFE = 23,
47 PV_REPLICATION_CONTROL = 24,
48 PV_RESTRICT_ID_PORTS = 32,
49 PV_RESTRICT_ID_PORTS2 = 33,
50 PV_RESTRICT_ID_PORTS2X = 34,
51 PV_RESTRICT_ID_PORTS2Y = 35,
52 PV_RESTRICT_ID_PORTS2Z = 36,
53 PV_RESTRICT_ID3 = 50,
54 PV_VIVALDI_OPTIONAL = 51,
55 PV_PACKET_FLAGS = 51,
56 PV_ALT_CONTACTS = 52,
57 PV_PACKET_FLAGS2 = 53
60 /* Type Length */
61 enum {
62 TL_BYTE = 1,
63 TL_BOOL = 1,
64 TL_SHORT = 2,
65 TL_INT = 4,
66 TL_IPv4 = 4,
67 TL_FLOAT = 4,
68 TL_LONG = 8,
69 TL_IPv6 = 16
72 /* Bool type */
73 enum {
74 BT_FALSE = 0x0,
75 BT_TRUE = 0x1
77 static const value_string vuze_dht_bool_type_vals[] = {
78 { BT_FALSE, "False" },
79 { BT_TRUE, "True" },
80 { 0, NULL }
83 /* action type */
84 enum {
85 AT_PING_REQUEST = 1024,
86 AT_PING_REPLY = 1025,
87 AT_STORE_REQUEST = 1026,
88 AT_STORE_REPLY = 1027,
89 AT_FIND_NODE_REQUEST = 1028,
90 AT_FIND_NODE_REPLY = 1029,
91 AT_FIND_VALUE_REQUEST = 1030,
92 AT_FIND_VALUE_REPLY = 1031,
93 AT_ERROR_REPLY = 1032,
94 AT_KEY_BLOCK_REQUEST = 1036,
95 AT_KEY_BLOCK_REPLY = 1037
97 static const value_string vuze_dht_action_type_vals[] = {
98 { AT_PING_REQUEST, "PING request" },
99 { AT_PING_REPLY, "PING reply" },
100 { AT_STORE_REQUEST, "STORE request" },
101 { AT_STORE_REPLY, "STORE reply" },
102 { AT_FIND_NODE_REQUEST, "FIND_NODE request" },
103 { AT_FIND_NODE_REPLY, "FIND_NODE reply" },
104 { AT_FIND_VALUE_REQUEST, "FIND_VALUE request" },
105 { AT_FIND_VALUE_REPLY, "FIND_VALUE reply" },
106 { AT_ERROR_REPLY, "ERROR reply" },
107 { AT_KEY_BLOCK_REQUEST, "kEY_BLOCK request" },
108 { AT_KEY_BLOCK_REPLY, "KEY_BLOCK reply" },
109 { 0, NULL }
112 /* Contact type, must be 1(UDP) */
113 enum {
114 CONTACT_UDP = 1
116 static const value_string vuze_dht_contact_type_vals[] = {
117 { CONTACT_UDP, "UDP" },
118 { 0, NULL }
121 /* Node type */
122 enum {
123 NT_BOOTSTRAP_NODE = 0x0,
124 NT_ORDINARY_NODE = 0x1,
125 NT_UNKNOWN_NODE = -1
127 static const value_string vuze_dht_node_type_vals[] = {
128 { NT_BOOTSTRAP_NODE, "Bootstrap node" },
129 { NT_ORDINARY_NODE, "Ordinary node" },
130 { NT_UNKNOWN_NODE, "Unknown node" },
131 { 0, NULL }
134 /* flag type */
135 enum {
136 FT_SINGLE_VALUE = 0x00,
137 FT_DOWNLOADING = 0x01,
138 FT_SEEDING = 0x02,
139 FT_MULTI_VALUE = 0x04,
140 FT_STATS = 0x08,
141 FLAG_ANON = 0x10,
142 FLAG_PRECIOUS = 0x20
144 static const value_string vuze_dht_flag_type_vals[] = {
145 { FT_SINGLE_VALUE, "Single value" },
146 { FT_DOWNLOADING, "Downloading" },
147 { FT_SEEDING, "Seeding" },
148 { FT_MULTI_VALUE, "Multi value" },
149 { FT_STATS, "Stats" },
150 { FLAG_ANON, "Anon" },
151 { FLAG_PRECIOUS, "Precious" },
152 { 0, NULL }
155 /* generic flag type */
156 enum {
157 GF_NONE = 0x00,
158 GF_DHT_SLEEPING = 0x01
160 static const value_string vuze_dht_generic_flag_type_vals[] = {
161 { GF_NONE, "None"},
162 { GF_DHT_SLEEPING, "DHT sleeping" },
163 {0, NULL}
166 /* error type */
167 enum {
168 ET_WRONG_ADDRESS = 1,
169 ET_KEY_BLOCKED = 2
171 static const value_string vuze_dht_error_type_vals[] = {
172 { ET_WRONG_ADDRESS, "Originator's address stored in the request is incorrect" },
173 { ET_KEY_BLOCKED, "The requested key has been blocked" },
174 { 0, NULL }
177 /* network coordinate type */
178 enum {
179 NC_VIVALDI = 1
181 static const value_string vuze_dht_network_coordinate_type_vals[] = {
182 { NC_VIVALDI, "Vivaldi" },
183 { 0, NULL }
186 static int proto_vuze_dht;
188 /* --- fields ---*/
190 /* address appears in contacts, request header, reply error */
191 static int hf_vuze_dht_address;
192 static int hf_vuze_dht_address_len;
193 static int hf_vuze_dht_address_v4;
194 static int hf_vuze_dht_address_v6;
195 static int hf_vuze_dht_address_port;
197 /* contact appears in values, reply find_node, reply find_value */
198 static int hf_vuze_dht_contact;
199 static int hf_vuze_dht_contact_type;
200 static int hf_vuze_dht_proto_ver;
202 /* value appears in reply find_value */
203 static int hf_vuze_dht_value;
204 static int hf_vuze_dht_value_ver;
205 static int hf_vuze_dht_value_created;
206 static int hf_vuze_dht_value_bytes_count;
207 static int hf_vuze_dht_value_bytes;
208 static int hf_vuze_dht_value_flags;
209 static int hf_vuze_dht_value_life_hours;
210 static int hf_vuze_dht_value_replication_factor;
212 /* firstly appear in request header */
213 static int hf_vuze_dht_connection_id;
214 static int hf_vuze_dht_action;
215 static int hf_vuze_dht_transaction_id;
216 static int hf_vuze_dht_vendor_id;
217 static int hf_vuze_dht_network_id;
218 static int hf_vuze_dht_local_proto_ver;
219 static int hf_vuze_dht_instance_id;
220 static int hf_vuze_dht_time;
221 static int hf_vuze_dht_generic_flags;
222 static int hf_vuze_dht_generic_flags2;
224 /* firstly appear in reply ping */
225 static int hf_vuze_dht_network_coordinates_count;
226 static int hf_vuze_dht_network_coordinates;
227 static int hf_vuze_dht_network_coordinate;
228 static int hf_vuze_dht_network_coordinate_type;
229 static int hf_vuze_dht_network_coordinate_size;
230 static int hf_vuze_dht_network_coordinate_data;
231 static int hf_vuze_dht_network_coordinate_x;
232 static int hf_vuze_dht_network_coordinate_y;
233 static int hf_vuze_dht_network_coordinate_height;
234 static int hf_vuze_dht_network_coordinate_error;
236 /* firstly appear in request store */
237 static int hf_vuze_dht_spoof_id;
238 static int hf_vuze_dht_keys_count;
239 static int hf_vuze_dht_keys;
240 static int hf_vuze_dht_key;
241 static int hf_vuze_dht_key_len;
242 static int hf_vuze_dht_key_data;
243 static int hf_vuze_dht_value_group;
244 static int hf_vuze_dht_value_groups;
245 static int hf_vuze_dht_value_groups_count;
246 static int hf_vuze_dht_values_count;
248 /* firstly appear in reply store */
249 static int hf_vuze_dht_diversifications_len;
250 static int hf_vuze_dht_diversifications;
252 /* firstly appear in request find_node */
253 static int hf_vuze_dht_id_len;
254 static int hf_vuze_dht_id;
255 static int hf_vuze_dht_node_status;
256 static int hf_vuze_dht_size;
258 /* firstly appear in reply find_node */
259 static int hf_vuze_dht_node_type;
260 static int hf_vuze_dht_contacts_count;
261 static int hf_vuze_dht_contacts;
263 /* firstly appear in request find_value */
264 static int hf_vuze_dht_flags;
265 static int hf_vuze_dht_values_num;
266 static int hf_vuze_dht_values_total;
267 static int hf_vuze_dht_reads_per_min;
268 static int hf_vuze_dht_diversification_type;
269 static int hf_vuze_dht_max_values;
271 /* firstly appear in reply find_value */
272 static int hf_vuze_dht_has_continuation;
273 static int hf_vuze_dht_has_values;
275 /* firstly appear in reply error */
276 static int hf_vuze_dht_error_type;
277 static int hf_vuze_dht_key_block_request_len;
278 static int hf_vuze_dht_key_block_request;
279 static int hf_vuze_dht_signature_len;
280 static int hf_vuze_dht_signature;
282 /* trees */
283 static int ett_vuze_dht;
284 static int ett_vuze_dht_address;
285 static int ett_vuze_dht_contacts;
286 static int ett_vuze_dht_contact;
287 static int ett_vuze_dht_keys;
288 static int ett_vuze_dht_key;
289 static int ett_vuze_dht_value_groups;
290 static int ett_vuze_dht_value_group;
291 static int ett_vuze_dht_value;
292 static int ett_vuze_dht_network_coordinates;
293 static int ett_vuze_dht_network_coordinate;
295 static dissector_handle_t vuze_dht_handle;
297 void proto_reg_handoff_vuze_dht(void);
299 /* --- Address format --------------
301 byte: indicates length of the IP address (4 for IPv4, 16 for IPv6)
302 4 or 16 bytes: the address in network byte order
303 short: port number
306 static int
307 dissect_vuze_dht_address(tvbuff_t *tvb, packet_info _U_*pinfo, proto_tree *tree, int offset, const char* addr_name)
309 uint8_t ip_length;
310 proto_tree *sub_tree;
311 proto_item *ti;
312 address addr;
314 ip_length = tvb_get_uint8(tvb,offset);
315 /* the decoded length is ip length+3, see the format above */
316 ti = proto_tree_add_none_format(tree, hf_vuze_dht_address, tvb, offset, ip_length+3, "%s: ", addr_name );
317 sub_tree = proto_item_add_subtree(ti, ett_vuze_dht_address);
319 proto_tree_add_item(sub_tree, hf_vuze_dht_address_len, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
320 offset += TL_BYTE;
322 switch(ip_length)
324 case TL_IPv4:
325 proto_tree_add_item(sub_tree, hf_vuze_dht_address_v4, tvb, offset, ip_length, ENC_BIG_ENDIAN);
326 set_address_tvb( &addr, AT_IPv4, ip_length, tvb, offset);
327 break;
328 case TL_IPv6:
329 proto_tree_add_item(sub_tree, hf_vuze_dht_address_v6, tvb, offset, ip_length, ENC_NA);
330 set_address_tvb( &addr, AT_IPv6, ip_length, tvb, offset);
331 break;
332 default:
333 clear_address(&addr);
334 break;
336 offset += ip_length;
338 proto_tree_add_item(sub_tree, hf_vuze_dht_address_port, tvb, offset, TL_SHORT, ENC_BIG_ENDIAN);
339 proto_item_append_text( ti, "%s:%d", address_to_str(pinfo->pool, &addr ), tvb_get_ntohs(tvb,offset) );
340 offset += TL_SHORT;
342 return offset;
345 /* --- Contact format --------------
347 byte: indicates contact type, which must be UDP(1)
348 byte: the contact's protocol version
349 7 or 19 bytes: Address
352 static int
353 dissect_vuze_dht_contact(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
355 proto_item *ti;
356 proto_tree *sub_tree;
358 /* the decoded length is ip length+5, see the format above */
359 ti = proto_tree_add_none_format( tree, hf_vuze_dht_contact, tvb, offset, tvb_get_uint8(tvb,offset+2)+5,
360 "%s contact, version %d",
361 val_to_str_const( tvb_get_uint8(tvb, offset), vuze_dht_contact_type_vals, "Unknown"),
362 tvb_get_uint8(tvb, offset+1) );
363 sub_tree = proto_item_add_subtree(ti, ett_vuze_dht_contact);
365 proto_tree_add_item(sub_tree, hf_vuze_dht_contact_type, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
366 offset += TL_BYTE;
367 proto_tree_add_item(sub_tree, hf_vuze_dht_proto_ver, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
368 offset += TL_BYTE;
369 offset = dissect_vuze_dht_address( tvb, pinfo, sub_tree, offset, "Contact Address" );
371 return offset;
374 /* --- Contact List --- */
375 static int
376 dissect_vuze_dht_contacts(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int contacts_count)
378 proto_item *ti;
379 proto_tree *sub_tree;
380 int i;
382 ti = proto_tree_add_none_format( tree, hf_vuze_dht_contacts, tvb, offset, 0, "%d contacts", contacts_count );
383 sub_tree = proto_item_add_subtree(ti, ett_vuze_dht_contacts);
384 for( i=0; i<contacts_count; i++ )
385 offset = dissect_vuze_dht_contact( tvb, pinfo, sub_tree, offset );
387 return offset;
390 /* --- Key format
391 Name | Type
392 LENGTH byte
393 KEY byte[LENGTH]
394 --- */
395 static int
396 dissect_vuze_dht_key(tvbuff_t *tvb, packet_info _U_*pinfo, proto_tree *tree, int offset)
398 proto_item *ti;
399 proto_tree *sub_tree;
400 unsigned key_len;
402 key_len = tvb_get_uint8( tvb, offset );
403 ti = proto_tree_add_item( tree, hf_vuze_dht_key, tvb, offset, key_len+1, ENC_NA );
404 sub_tree = proto_item_add_subtree(ti, ett_vuze_dht_key);
406 proto_tree_add_item( sub_tree, hf_vuze_dht_key_len, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN );
407 offset += TL_BYTE;
409 proto_tree_add_item( sub_tree, hf_vuze_dht_key_data, tvb, offset, key_len, ENC_NA );
410 proto_item_append_text( ti, ": %d bytes ( %s )", key_len, tvb_bytes_to_str(pinfo->pool, tvb, offset, key_len ) );
411 offset += key_len;
413 return offset;
416 /* --- Keys List --- */
417 static int
418 dissect_vuze_dht_keys(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int keys_count)
420 proto_item *ti;
421 proto_tree *sub_tree;
422 int i;
424 ti = proto_tree_add_none_format( tree, hf_vuze_dht_keys, tvb, offset, 0, "%d keys", keys_count );
425 sub_tree = proto_item_add_subtree(ti, ett_vuze_dht_keys);
426 for( i=0; i<keys_count; i++ )
427 offset = dissect_vuze_dht_key( tvb, pinfo, sub_tree, offset );
429 return offset;
432 /* --- Value format --------------
434 Name | Type | Protocol version | Note
435 VERSION byte >=REMOVE_DIST_ADD_VER Version of the value. (details later)
436 CREATED long always Creation time. Units unknown; probably milliseconds since the epoch.
437 VALUE_BYTES_COUNT short always Number of bytes in the value.
438 VALUE_BYTES bytes always The bytes of the value.
439 ORIGINATOR contact always presumably the node that created the value.
440 FLAGS byte always
441 LIFE_HOURS byte >=LONGER_LIFE Hours for the value to live. (Details of how it's handled)
442 REPLICATION_FACTOR byte >=REPLICATION_CONTROL Per-value # of replicas to maintain.
444 If STATS are used in request, then some stats for the value are returned instead of value itself.
445 They are serialised as follows:
446 0 (byte) - version,
447 number of stored values for the key (int),
448 total size of stored values (int),
449 reads per minute (int),
450 diversification type (byte).
452 static int
453 dissect_vuze_dht_value(tvbuff_t *tvb, packet_info _U_*pinfo, proto_tree *tree, int offset, int ver )
455 proto_item *ti;
456 proto_tree *sub_tree;
457 int value_ver = -1;
459 ti = proto_tree_add_item( tree, hf_vuze_dht_value, tvb, offset, 0, ENC_NA );
460 sub_tree = proto_item_add_subtree(ti, ett_vuze_dht_value);
461 if( ver >= PV_REMOVE_DIST_ADD_VER )
463 proto_tree_add_item(sub_tree, hf_vuze_dht_value_ver, tvb, offset, TL_INT, ENC_BIG_ENDIAN);
464 value_ver = tvb_get_ntohl( tvb, offset );
465 offset += TL_INT;
467 /* It's a return for STATS */
468 if( value_ver==0 )
470 proto_item_append_text( ti,
471 " (reply to STATS): %d values for the key, out of %d in total...",
472 tvb_get_ntohl(tvb, offset), tvb_get_ntohl(tvb, offset+TL_INT) );
474 proto_tree_add_item(tree, hf_vuze_dht_values_num, tvb, offset, TL_INT, ENC_BIG_ENDIAN);
475 offset += TL_INT;
476 proto_tree_add_item(tree, hf_vuze_dht_values_total, tvb, offset, TL_INT, ENC_BIG_ENDIAN);
477 offset += TL_INT;
478 proto_tree_add_item(tree, hf_vuze_dht_reads_per_min, tvb, offset, TL_INT, ENC_BIG_ENDIAN);
479 offset += TL_INT;
480 proto_tree_add_item(tree, hf_vuze_dht_diversification_type, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
481 offset += TL_BYTE;
483 /* regular value */
484 else
486 int value_bytes_count;
488 proto_tree_add_item(sub_tree, hf_vuze_dht_value_created, tvb, offset, TL_LONG, ENC_BIG_ENDIAN);
489 offset += TL_LONG;
491 proto_tree_add_item(sub_tree, hf_vuze_dht_value_bytes_count, tvb, offset, TL_SHORT, ENC_BIG_ENDIAN);
492 value_bytes_count = tvb_get_ntohs(tvb, offset);
493 offset += TL_SHORT;
495 proto_tree_add_item(sub_tree, hf_vuze_dht_value_bytes, tvb, offset, value_bytes_count, ENC_NA);
496 proto_item_append_text( ti, ": %d bytes ( %s )", value_bytes_count, tvb_bytes_to_str(pinfo->pool, tvb, offset, value_bytes_count ) );
497 offset += value_bytes_count;
499 offset = dissect_vuze_dht_contact( tvb, pinfo, sub_tree, offset );
501 proto_tree_add_item(sub_tree, hf_vuze_dht_value_flags, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
502 offset += TL_BYTE;
503 proto_tree_add_item(sub_tree, hf_vuze_dht_value_life_hours, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
504 offset += TL_BYTE;
505 proto_tree_add_item(sub_tree, hf_vuze_dht_value_replication_factor, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
506 offset += TL_BYTE;
509 return offset;
512 /* --- Values format
513 values_count short
514 values value[values_count]
515 --- */
516 static int
517 dissect_vuze_dht_value_group(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int ver)
519 proto_item *ti;
520 proto_tree *sub_tree;
521 int values_count;
522 int i;
524 values_count = tvb_get_ntohs( tvb, offset );
526 ti = proto_tree_add_none_format( tree, hf_vuze_dht_value_group, tvb, offset, 0, "%d values", values_count );
527 sub_tree = proto_item_add_subtree(ti, ett_vuze_dht_value_group);
529 proto_tree_add_item( sub_tree, hf_vuze_dht_values_count, tvb, offset, TL_SHORT, ENC_BIG_ENDIAN );
530 offset += TL_SHORT;
532 for( i=0; i<values_count; i++ )
533 offset = dissect_vuze_dht_value( tvb, pinfo, sub_tree, offset, ver );
535 return offset;
538 /* --- Values Groups format
539 value_group[value_groups_count]
540 --- */
541 static int
542 dissect_vuze_dht_value_groups(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int value_groups_count, int ver)
544 proto_item *ti;
545 proto_tree *sub_tree;
546 int i;
548 ti = proto_tree_add_none_format( tree, hf_vuze_dht_value_groups, tvb, offset, 0, "%d value groups", value_groups_count );
549 sub_tree = proto_item_add_subtree(ti, ett_vuze_dht_value_groups);
550 for( i=0; i<value_groups_count; i++ )
551 offset = dissect_vuze_dht_value_group( tvb, pinfo, sub_tree, offset, ver );
553 return offset;
556 /* --- Network Coordinates format ------
557 Name | Type
558 TYPE byte
559 SIZE byte
560 Network Coordinates byte[SIZE]
562 static int
563 dissect_vuze_dht_network_coordinate(tvbuff_t *tvb, packet_info _U_*pinfo, proto_tree *tree, int offset)
565 proto_item *ti;
566 proto_tree *sub_tree;
567 unsigned coordinate_size;
568 unsigned coordinate_type;
570 coordinate_type = tvb_get_uint8( tvb, offset );
571 coordinate_size = tvb_get_uint8( tvb, offset+1 );
573 ti = proto_tree_add_item( tree, hf_vuze_dht_network_coordinate, tvb, offset, coordinate_size+2, ENC_NA );
574 sub_tree = proto_item_add_subtree(ti, ett_vuze_dht_network_coordinate);
576 proto_item_append_text( ti, ": type %d, length %d", tvb_get_uint8(tvb,offset), tvb_get_uint8(tvb,offset+TL_BYTE) );
578 if (coordinate_type == NC_VIVALDI) {
579 proto_item_append_text( ti, " ( %.2f, %.2f, %.2f, %.2f )",
580 tvb_get_ntohieee_float(tvb, offset+TL_BYTE+TL_BYTE),
581 tvb_get_ntohieee_float(tvb, offset+TL_BYTE+TL_BYTE+TL_FLOAT),
582 tvb_get_ntohieee_float(tvb, offset+TL_BYTE+TL_BYTE+TL_FLOAT+TL_FLOAT),
583 tvb_get_ntohieee_float(tvb, offset+TL_BYTE+TL_BYTE+TL_FLOAT+TL_FLOAT+TL_FLOAT) );
584 } else {
585 proto_item_append_text( ti, " ( %s )",
586 tvb_bytes_to_str(pinfo->pool, tvb, offset+TL_BYTE+TL_BYTE, coordinate_size ) );
589 proto_tree_add_item( sub_tree, hf_vuze_dht_network_coordinate_type, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN );
590 offset += TL_BYTE;
591 proto_tree_add_item( sub_tree, hf_vuze_dht_network_coordinate_size, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN );
592 offset += TL_BYTE;
594 if (coordinate_type == NC_VIVALDI) {
595 proto_tree_add_item( sub_tree, hf_vuze_dht_network_coordinate_x, tvb, offset, TL_FLOAT, ENC_BIG_ENDIAN );
596 offset += TL_FLOAT;
597 proto_tree_add_item( sub_tree, hf_vuze_dht_network_coordinate_y, tvb, offset, TL_FLOAT, ENC_BIG_ENDIAN );
598 offset += TL_FLOAT;
599 proto_tree_add_item( sub_tree, hf_vuze_dht_network_coordinate_height, tvb, offset, TL_FLOAT, ENC_BIG_ENDIAN );
600 offset += TL_FLOAT;
601 proto_tree_add_item( sub_tree, hf_vuze_dht_network_coordinate_error, tvb, offset, TL_FLOAT, ENC_BIG_ENDIAN );
602 offset += TL_FLOAT;
603 } else {
604 proto_tree_add_item( sub_tree, hf_vuze_dht_network_coordinate_data, tvb, offset, coordinate_size, ENC_NA );
605 offset += coordinate_size;
608 return offset;
611 /* --- Network Coordinates List ---
612 Name | Type | Protocol version
613 Network Coordinates Count byte >=PV_GENERIC_NETPOS
614 Network Coordinates Network Coordinate >=PV_GENERIC_NETPOS
616 static int
617 dissect_vuze_dht_network_coordinates(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int ver)
619 proto_item *ti;
620 proto_tree *sub_tree;
621 unsigned i;
622 unsigned network_coordinates_count;
624 if( ver >= PV_GENERIC_NETPOS )
626 proto_tree_add_item(tree, hf_vuze_dht_network_coordinates_count, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
627 network_coordinates_count = tvb_get_uint8( tvb, offset );
628 offset += TL_BYTE;
630 ti = proto_tree_add_none_format( tree, hf_vuze_dht_network_coordinates, tvb, offset, 0, "%d network coordinates", network_coordinates_count );
631 sub_tree = proto_item_add_subtree(ti, ett_vuze_dht_network_coordinates);
632 for( i=0; i<network_coordinates_count; i++ )
633 offset = dissect_vuze_dht_network_coordinate( tvb, pinfo, sub_tree, offset );
635 return offset;
638 /* --- Request Header format --------------
640 Name | Type | Protocol version | Note
641 CONNECTION_ID long always random number with most significant bit set to 1
642 ACTION int always type of the packet
643 TRANSACTION_ID int always unique number used through the communication; it is randomly generated
644 at the start of the application and increased by 1 with each sent packet
645 PROTOCOL_VERSION byte always version of protocol used in this packet
646 VENDOR_ID byte >=VENDOR_ID ID of the DHT implementator; 0 = Azureus, 1 = ShareNet, 255 = unknown
647 NETWORK_ID int >=NETWORKS ID of the network; 0 = stable version; 1 = CVS version
648 LOCAL_PROTOCOL_VERSION byte >=FIX_ORIGINATOR maximum protocol version this node supports; if this packet's protocol
649 version is <FIX_ORIGINATOR then the value is stored at the end of the packet
650 NODE_ADDRESS address always address of the local node
651 INSTANCE_ID int always application's helper number; randomly generated at the start
652 TIME long always time of the local node; stored as number of milliseconds since Epoch
653 FLAG byte >=PACKET_FLAGS
654 FLAG2 byte >=PACKET_FLAGS2
657 static int
658 dissect_vuze_dht_request_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int *action, int *ver )
660 proto_tree_add_item(tree, hf_vuze_dht_connection_id, tvb, offset, TL_LONG, ENC_BIG_ENDIAN);
661 offset += TL_LONG;
663 proto_tree_add_item(tree, hf_vuze_dht_action, tvb, offset, TL_INT, ENC_BIG_ENDIAN);
664 *action = tvb_get_ntohl(tvb, offset);
665 col_append_fstr(pinfo->cinfo, COL_INFO, " Action: %s", val_to_str_const( *action, vuze_dht_action_type_vals, "Unknown") );
666 offset += TL_INT;
668 proto_tree_add_item(tree, hf_vuze_dht_transaction_id, tvb, offset, TL_INT, ENC_BIG_ENDIAN);
669 offset += TL_INT;
671 proto_tree_add_item(tree, hf_vuze_dht_proto_ver, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
672 *ver = tvb_get_uint8( tvb, offset );
673 offset += TL_BYTE;
675 if( *ver >= PV_VENDOR_ID )
677 proto_tree_add_item(tree, hf_vuze_dht_vendor_id, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
678 offset += TL_BYTE;
681 if( *ver >= PV_NETWORKS )
683 proto_tree_add_item(tree, hf_vuze_dht_network_id, tvb, offset, TL_INT, ENC_BIG_ENDIAN);
684 offset += TL_INT;
686 if( *ver >= PV_FIX_ORIGINATOR )
688 proto_tree_add_item(tree, hf_vuze_dht_local_proto_ver, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
689 offset += TL_BYTE;
692 offset = dissect_vuze_dht_address(tvb, pinfo, tree, offset, "Local Address");
693 proto_tree_add_item(tree, hf_vuze_dht_instance_id, tvb, offset, TL_INT, ENC_BIG_ENDIAN);
694 offset += TL_INT;
695 proto_tree_add_item(tree, hf_vuze_dht_time, tvb, offset, TL_LONG, ENC_BIG_ENDIAN);
696 offset += TL_LONG;
698 if( *ver >= PV_PACKET_FLAGS )
700 proto_tree_add_item(tree, hf_vuze_dht_generic_flags, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
701 offset += TL_BYTE;
703 if( *ver >= PV_PACKET_FLAGS2 )
705 proto_tree_add_item(tree, hf_vuze_dht_generic_flags2, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
706 offset += TL_BYTE;
709 return offset;
712 /* --- Reply Header format --------------
714 Name | Type | Protocol version | Note
715 ACTION int always type of the packet
716 TRANSACTION_ID int always must be equal to TRANSACTION_ID from the request
717 CONNECTION_ID long always must be equal to CONNECTION_ID from the request
718 PROTOCOL_VERSION byte always version of protocol used in this packet
719 VENDOR_ID byte >=VENDOR_ID same meaning as in the request
720 NETWORK_ID int >=NETWORKS same meaning as in the request
721 INSTANCE_ID int always instance id of the node that replies to the request
722 FLAG byte >=PACKET_FLAGS
723 FLAG2 byte >=PACKET_FLAGS2
726 static int
727 dissect_vuze_dht_reply_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int *action, int *ver )
729 proto_tree_add_item(tree, hf_vuze_dht_action, tvb, offset, TL_INT, ENC_BIG_ENDIAN);
730 *action = tvb_get_ntohl(tvb, offset);
731 col_append_fstr(pinfo->cinfo, COL_INFO, " Action: %s", val_to_str_const( *action, vuze_dht_action_type_vals, "Unknown") );
732 offset += TL_INT;
734 proto_tree_add_item(tree, hf_vuze_dht_transaction_id, tvb, offset, TL_INT, ENC_BIG_ENDIAN);
735 offset += TL_INT;
737 proto_tree_add_item(tree, hf_vuze_dht_connection_id, tvb, offset, TL_LONG, ENC_BIG_ENDIAN);
738 offset += TL_LONG;
740 proto_tree_add_item(tree, hf_vuze_dht_proto_ver, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
741 *ver = tvb_get_uint8( tvb, offset );
742 offset += TL_BYTE;
744 if( *ver >= PV_VENDOR_ID )
746 proto_tree_add_item(tree, hf_vuze_dht_vendor_id, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
747 offset += TL_BYTE;
750 if( *ver >= PV_NETWORKS )
752 proto_tree_add_item(tree, hf_vuze_dht_network_id, tvb, offset, TL_INT, ENC_BIG_ENDIAN);
753 offset += TL_INT;
756 proto_tree_add_item(tree, hf_vuze_dht_instance_id, tvb, offset, TL_INT, ENC_BIG_ENDIAN);
757 offset += TL_INT;
759 if( *ver >= PV_PACKET_FLAGS )
761 proto_tree_add_item(tree, hf_vuze_dht_generic_flags, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
762 offset += TL_BYTE;
764 if( *ver >= PV_PACKET_FLAGS2 )
766 proto_tree_add_item(tree, hf_vuze_dht_generic_flags2, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
767 offset += TL_BYTE;
770 return offset;
773 /* --- Reply Ping -----------------
775 ACTION equal to 1025
776 If protocol version is >=VIVALDI then packet's body carries network coordinates.
779 static int
780 dissect_vuze_dht_reply_ping(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int ver )
782 if( ver >= PV_VIVALDI )
784 offset = dissect_vuze_dht_network_coordinates( tvb, pinfo, tree, offset, ver );
786 return offset;
789 /* --- Request Store -----------------
791 Name | Type | Protocol version | Note
792 SPOOF_ID int >=ANTI_SPOOF Spoof ID of the target node; it must be the same number as previously retrived through FIND_NODE reply.
793 KEYS_COUNT byte always Number of keys that follow.
794 KEYS keys always Keys that the target node should store.
795 VALUE_GROUPS_COUNT byte always Number of groups of values this packet contains.
796 VALUES value groups always Groups of values, one for each key; values are stored in the same order as keys.
799 static int
800 dissect_vuze_dht_request_store(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int ver )
802 uint8_t keys_count, value_groups_count;
803 if( ver >= PV_ANTI_SPOOF )
805 proto_tree_add_item(tree, hf_vuze_dht_spoof_id, tvb, offset, TL_INT, ENC_BIG_ENDIAN);
806 offset += TL_INT;
808 proto_tree_add_item(tree, hf_vuze_dht_keys_count, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
809 keys_count = tvb_get_uint8( tvb, offset );
810 offset += TL_BYTE;
812 offset = dissect_vuze_dht_keys( tvb, pinfo, tree, offset, keys_count );
814 proto_tree_add_item(tree, hf_vuze_dht_value_groups_count, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
815 value_groups_count = tvb_get_uint8( tvb, offset );
816 offset += TL_BYTE;
818 offset = dissect_vuze_dht_value_groups( tvb, pinfo, tree, offset, value_groups_count, ver );
820 return offset;
823 /* --- Reply Store -----------------
825 Name | Type | Protocol version | Note
826 DIVERSIFICATIONS_LENGTH byte >=DIV_AND_CONT Number of diversifications this packet contains.
827 DIVERSIFICATIONS byte[] >=DIV_AND_CONT Array with diversifications;
828 they are stored in the same order as keys and values from the request.
830 static int
831 dissect_vuze_dht_reply_store(tvbuff_t *tvb, packet_info _U_*pinfo, proto_tree *tree, int offset, int ver )
833 if( ver >= PV_DIV_AND_CONT )
835 unsigned diversifications_len;
836 proto_tree_add_item(tree, hf_vuze_dht_diversifications_len, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
837 diversifications_len = tvb_get_uint8( tvb, offset );
838 offset += TL_BYTE;
840 proto_tree_add_item(tree, hf_vuze_dht_diversifications, tvb, offset, diversifications_len, ENC_NA);
841 offset += diversifications_len;
844 return offset;
847 /* --- Request Find node -----------------
849 Name | Type | Protocol version | Note
850 ID_LENGTH byte always Length of the following ID.
851 ID byte[] always ID to search
852 NODE_STATUS int >=MORE_NODE_STATUS Node status
853 DHT_SIZE int >=MORE_NODE_STATUS Estimated size of the DHT; Unknown value can be indicated as zero.
856 static int
857 dissect_vuze_dht_request_find_node(tvbuff_t *tvb, packet_info _U_*pinfo, proto_tree *tree, int offset, int ver )
859 unsigned id_len;
861 proto_tree_add_item(tree, hf_vuze_dht_id_len, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
862 id_len = tvb_get_uint8( tvb, offset );
863 offset += TL_BYTE;
865 proto_tree_add_item(tree, hf_vuze_dht_id, tvb, offset, id_len, ENC_NA);
866 offset += id_len;
868 if( ver >= PV_MORE_NODE_STATUS )
870 proto_tree_add_item(tree, hf_vuze_dht_node_status, tvb, offset, TL_INT, ENC_BIG_ENDIAN);
871 offset += TL_INT;
872 proto_tree_add_item(tree, hf_vuze_dht_size, tvb, offset, TL_INT, ENC_BIG_ENDIAN);
873 offset += TL_INT;
876 return offset;
879 /* --- Reply Find node -----------------
881 Name | Type | Protocol version | Note
882 SPOOF_ID int >=ANTI_SPOOF Spoof ID of the requesting node;
883 it should be constructed from information known about
884 requesting contact and not easily guessed by others.
885 NODE_TYPE int >=XFER_STATUS Type of the replying node;
886 Possible values are 0 for bootstrap node,
887 1 for ordinary node and ffffffffh for unknown type.
888 DHT_SIZE int >=SIZE_ESTIMATE Estimated size of the DHT; Unknown value can be indicated as zero.
889 NETWORK_COORDINATES network coordinates >=VIVALDI Network coordinates of replying node.
890 CONTACTS_COUNT short always Number of carried contacts.
891 CONTACTS contacts always List with contacts.
894 static int
895 dissect_vuze_dht_reply_find_node(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int ver )
897 unsigned contacts_count;
899 if( ver >= PV_ANTI_SPOOF )
901 proto_tree_add_item(tree, hf_vuze_dht_spoof_id, tvb, offset, TL_INT, ENC_BIG_ENDIAN);
902 offset += TL_INT;
904 if( ver >= PV_XFER_STATUS )
906 proto_tree_add_item(tree, hf_vuze_dht_node_type, tvb, offset, TL_INT, ENC_BIG_ENDIAN);
907 offset += TL_INT;
909 if( ver >= PV_SIZE_ESTIMATE )
911 proto_tree_add_item(tree, hf_vuze_dht_size, tvb, offset, TL_INT, ENC_BIG_ENDIAN);
912 offset += TL_INT;
914 if( ver >= PV_VIVALDI )
916 offset = dissect_vuze_dht_network_coordinates( tvb, pinfo, tree, offset, ver );
919 proto_tree_add_item(tree, hf_vuze_dht_contacts_count, tvb, offset, TL_SHORT, ENC_BIG_ENDIAN);
920 contacts_count = tvb_get_ntohs( tvb, offset );
921 offset += TL_SHORT;
923 offset = dissect_vuze_dht_contacts( tvb, pinfo, tree, offset, contacts_count );
925 return offset;
928 /* --- Request Find value -----------------
930 Name | Type | Note
931 KEY key Key for which the values are requested.
932 FLAGS byte Flags for the operation, possible values are:
933 SINGLE_VALUE = 00h
934 DOWNLOADING = 01h
935 SEEDING = 02h
936 MULTI_VALUE = 04h
937 STATS = 08h
938 MAX_VALUES byte Maximum number of returned values.
940 static int
941 dissect_vuze_dht_request_find_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int ver _U_ )
943 offset = dissect_vuze_dht_key( tvb, pinfo, tree, offset );
944 proto_tree_add_item(tree, hf_vuze_dht_flags, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
945 offset += TL_BYTE;
946 proto_tree_add_item(tree, hf_vuze_dht_max_values, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
947 offset += TL_BYTE;
949 return offset;
952 /* --- Reply Find value -----------------
954 Name | Type | Condition | Note
955 HAS_CONTINUATION boolean protocol version >=DIV_AND_CONT Indicates whether there is at least one other packet with values.
956 HAS_VALUES boolean always Indicates whether this packet carries values or contacts.
957 CONTACTS_COUNT short HAS_VALUES == false Number of stored contacts.
958 CONTACTS contacts HAS_VALUES == false Stored contacts that are close to the searched key.
959 NETWORK_COORDINATES network coordinates HAS_VALUES == false Network coordinates of the replying node.
960 && protocol version >=VIVALDI_FINDVALUE
961 DIVERSIFICATION_TYPE byte HAS_VALUES == true Type of key's diversification.
962 && protocol version >=DIV_AND_CONT
963 VALUES value group HAS_VALUES == true Values that match searched key.
966 static int
967 dissect_vuze_dht_reply_find_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int ver )
969 uint8_t has_values;
970 unsigned contacts_count;
971 if( ver >= PV_DIV_AND_CONT )
973 proto_tree_add_item(tree, hf_vuze_dht_has_continuation, tvb, offset, TL_BOOL, ENC_BIG_ENDIAN);
974 offset += TL_BOOL;
976 proto_tree_add_item(tree, hf_vuze_dht_has_values, tvb, offset, TL_BOOL, ENC_BIG_ENDIAN);
977 has_values = tvb_get_uint8( tvb, offset );
978 offset += TL_BOOL;
980 if( has_values )
982 proto_tree_add_item(tree, hf_vuze_dht_contacts_count, tvb, offset, TL_SHORT, ENC_BIG_ENDIAN);
983 contacts_count = tvb_get_ntohs( tvb, offset );
984 offset += TL_SHORT;
985 offset = dissect_vuze_dht_contacts( tvb, pinfo, tree, offset, contacts_count );
987 if( ver >= PV_VIVALDI_FINDVALUE )
989 offset = dissect_vuze_dht_network_coordinates( tvb, pinfo, tree, offset, ver );
991 if( ver >= PV_DIV_AND_CONT )
993 proto_tree_add_item(tree, hf_vuze_dht_diversification_type, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
994 offset += TL_BYTE;
996 offset = dissect_vuze_dht_value_group( tvb, pinfo, tree, offset, ver );
999 return offset;
1002 /* --- Reply Error -----------------
1004 Name | Type | Condition | Note
1005 ERROR_TYPE int always Type of the error. Possible values are:
1006 WRONG_ADDRESS = 1 - originator's address stored in the request is incorrect
1007 KEY_BLOCKED = 2 - the requested key has been blocked
1008 SENDER_ADDRESS address ERROR_TYPE == WRONG_ADDRESS Real originator's address.
1009 KEY_BLOCK_REQUEST_LENGTH byte ERROR_TYPE == KEY_BLOCKED Length of the following request.
1010 KEY_BLOCK_REQUEST byte[] ERROR_TYPE == KEY_BLOCKED Request that blocks/unlocks the key.
1011 SIGNATURE_LENGTH short ERROR_TYPE == KEY_BLOCKED Length of the following signature.
1012 SIGNATURE byte[] ERROR_TYPE == KEY_BLOCKED Signature of the request.
1015 static int
1016 dissect_vuze_dht_reply_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int ver _U_ )
1018 unsigned error_type;
1019 uint8_t key_block_request_len;
1020 unsigned signature_len;
1022 proto_tree_add_item(tree, hf_vuze_dht_error_type, tvb, offset, TL_INT, ENC_BIG_ENDIAN);
1023 error_type = tvb_get_ntohl( tvb, offset );
1024 col_append_fstr(pinfo->cinfo, COL_INFO, " Error: %s", val_to_str_const( error_type, vuze_dht_error_type_vals, "Unknown") );
1025 offset += TL_INT;
1027 switch(error_type)
1029 case ET_WRONG_ADDRESS:
1030 offset = dissect_vuze_dht_address( tvb, pinfo, tree, offset, "Sender Address" );
1031 break;
1032 case ET_KEY_BLOCKED:
1033 proto_tree_add_item(tree, hf_vuze_dht_key_block_request_len, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
1034 key_block_request_len = tvb_get_uint8( tvb, offset );
1035 offset += TL_BYTE;
1037 proto_tree_add_item(tree, hf_vuze_dht_key_block_request, tvb, offset, key_block_request_len, ENC_NA);
1038 offset += key_block_request_len;
1040 proto_tree_add_item(tree, hf_vuze_dht_signature_len, tvb, offset, TL_SHORT, ENC_BIG_ENDIAN);
1041 signature_len = tvb_get_ntohs( tvb, offset );
1042 offset += TL_SHORT;
1044 proto_tree_add_item(tree, hf_vuze_dht_signature, tvb, offset, signature_len, ENC_NA);
1045 offset += signature_len;
1046 break;
1047 default:
1048 break;
1051 return offset;
1054 /* --- Request Key block -----------------
1056 Name | Type | Note
1057 SPOOF_ID int Spoof ID obtained through FIND_NODE request.
1058 KEY_BLOCK_REQUEST_LENGTH byte Length of the following request.
1059 KEY_BLOCK_REQUEST byte[] Request that blocks/unlocks the key.
1060 SIGNATURE_LENGTH short Length of the following signature.
1061 SIGNATURE byte[] Signature of the request.
1064 static int
1065 dissect_vuze_dht_request_key_block(tvbuff_t *tvb, packet_info _U_*pinfo, proto_tree *tree, int offset, int ver _U_ )
1067 uint8_t key_block_request_len;
1068 unsigned signature_len;
1070 proto_tree_add_item(tree, hf_vuze_dht_spoof_id, tvb, offset, TL_INT, ENC_BIG_ENDIAN);
1071 offset += TL_INT;
1073 proto_tree_add_item(tree, hf_vuze_dht_key_block_request_len, tvb, offset, TL_BYTE, ENC_BIG_ENDIAN);
1074 key_block_request_len = tvb_get_uint8( tvb, offset );
1075 offset += TL_BYTE;
1077 proto_tree_add_item(tree, hf_vuze_dht_key_block_request, tvb, offset, key_block_request_len, ENC_NA);
1078 offset += key_block_request_len;
1080 proto_tree_add_item(tree, hf_vuze_dht_signature_len, tvb, offset, TL_SHORT, ENC_BIG_ENDIAN);
1081 signature_len = tvb_get_ntohs( tvb, offset );
1082 offset += TL_SHORT;
1084 proto_tree_add_item(tree, hf_vuze_dht_signature, tvb, offset, signature_len, ENC_NA);
1085 offset += signature_len;
1087 return offset;
1090 static int
1091 dissect_vuze_dht(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1093 proto_item *ti;
1094 proto_tree *sub_tree;
1095 int action, proto_ver;
1096 int decoded_length = 0;
1098 /* set the protocol column */
1099 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vuze-DHT");
1100 /* clear the info column */
1101 col_clear( pinfo->cinfo, COL_INFO);
1103 ti = proto_tree_add_item(tree, proto_vuze_dht, tvb, 0, -1, ENC_NA);
1104 sub_tree = proto_item_add_subtree(ti, ett_vuze_dht);
1107 Requests always start with Connection IDs, which guaranteed to have their MSB set to 1
1108 Replies always start with the action, which always has the MSB clear
1109 Therefore, the MSB of an incoming packet should be used to distinguish requests from replies.
1111 if( tvb_get_uint8(tvb,0) & 0x80 )
1113 decoded_length = dissect_vuze_dht_request_header(tvb, pinfo, sub_tree, decoded_length, &action, &proto_ver );
1115 else
1117 decoded_length = dissect_vuze_dht_reply_header(tvb, pinfo, sub_tree, decoded_length, &action, &proto_ver );
1120 switch( action )
1122 case AT_PING_REQUEST:
1123 break;
1124 case AT_PING_REPLY:
1125 decoded_length = dissect_vuze_dht_reply_ping(tvb, pinfo, sub_tree, decoded_length, proto_ver );
1126 break;
1127 case AT_STORE_REQUEST:
1128 decoded_length = dissect_vuze_dht_request_store(tvb, pinfo, sub_tree, decoded_length, proto_ver );
1129 break;
1130 case AT_STORE_REPLY:
1131 decoded_length = dissect_vuze_dht_reply_store(tvb, pinfo, sub_tree, decoded_length, proto_ver );
1132 break;
1133 case AT_FIND_NODE_REQUEST:
1134 decoded_length = dissect_vuze_dht_request_find_node(tvb, pinfo, sub_tree, decoded_length, proto_ver );
1135 break;
1136 case AT_FIND_NODE_REPLY:
1137 decoded_length = dissect_vuze_dht_reply_find_node(tvb, pinfo, sub_tree, decoded_length, proto_ver );
1138 break;
1139 case AT_FIND_VALUE_REQUEST:
1140 decoded_length = dissect_vuze_dht_request_find_value(tvb, pinfo, sub_tree, decoded_length, proto_ver );
1141 break;
1142 case AT_FIND_VALUE_REPLY:
1143 decoded_length = dissect_vuze_dht_reply_find_value(tvb, pinfo, sub_tree, decoded_length, proto_ver );
1144 break;
1145 case AT_ERROR_REPLY:
1146 decoded_length = dissect_vuze_dht_reply_error(tvb, pinfo, sub_tree, decoded_length, proto_ver );
1147 break;
1148 case AT_KEY_BLOCK_REQUEST:
1149 decoded_length = dissect_vuze_dht_request_key_block(tvb, pinfo, sub_tree, decoded_length, proto_ver );
1150 break;
1151 default:
1152 break;
1155 return decoded_length;
1158 void
1159 proto_register_vuze_dht(void)
1161 static hf_register_info hf[] = {
1162 { &hf_vuze_dht_address,
1163 { "Address", "vuze-dht.address",
1164 FT_NONE, BASE_NONE, NULL, 0x0,
1165 NULL, HFILL }
1167 { &hf_vuze_dht_address_len,
1168 { "Address Length", "vuze-dht.address.length",
1169 FT_UINT8, BASE_DEC, NULL, 0x0,
1170 NULL, HFILL }
1172 { &hf_vuze_dht_address_v4,
1173 { "IPv4 Address", "vuze-dht.address.ipv4",
1174 FT_IPv4, BASE_NONE, NULL, 0x0,
1175 NULL, HFILL }
1177 { &hf_vuze_dht_address_v6,
1178 { "IPv6 Address", "vuze-dht.address.ipv6",
1179 FT_IPv6, BASE_NONE, NULL, 0x0,
1180 NULL, HFILL }
1182 { &hf_vuze_dht_address_port,
1183 { "Port", "vuze-dht.address.port",
1184 FT_UINT16, BASE_DEC, NULL, 0x0,
1185 NULL, HFILL }
1187 { &hf_vuze_dht_contact,
1188 { "Contact", "vuze-dht.contact",
1189 FT_NONE, BASE_NONE, NULL, 0x0,
1190 NULL, HFILL }
1192 { &hf_vuze_dht_contact_type,
1193 { "Contact Type", "vuze-dht.contact.type",
1194 FT_UINT8, BASE_DEC, VALS(vuze_dht_contact_type_vals), 0x0,
1195 NULL, HFILL }
1197 { &hf_vuze_dht_proto_ver,
1198 { "Protocol Version", "vuze-dht.proto_ver",
1199 FT_UINT8, BASE_DEC, NULL, 0x0,
1200 NULL, HFILL }
1202 { &hf_vuze_dht_value,
1203 { "Value", "vuze-dht.value",
1204 FT_NONE, BASE_NONE, NULL, 0x0,
1205 NULL, HFILL }
1207 { &hf_vuze_dht_value_ver,
1208 { "Value Version", "vuze-dht.value.ver",
1209 FT_UINT32, BASE_DEC, NULL, 0x0,
1210 NULL, HFILL }
1212 { &hf_vuze_dht_value_created,
1213 { "Value Creation Time", "vuze-dht.value.creation_time",
1214 FT_UINT64, BASE_DEC, NULL, 0x0,
1215 NULL, HFILL }
1217 { &hf_vuze_dht_value_bytes_count,
1218 { "Value Bytes Count", "vuze-dht.value.bytes_count",
1219 FT_UINT16, BASE_DEC, NULL, 0x0,
1220 NULL, HFILL }
1222 { &hf_vuze_dht_value_bytes,
1223 { "Value Bytes", "vuze-dht.value.bytes",
1224 FT_BYTES, BASE_NONE, NULL, 0x0,
1225 NULL, HFILL }
1227 { &hf_vuze_dht_value_flags,
1228 { "Value Flags", "vuze-dht.value.flags",
1229 FT_UINT8, BASE_DEC, NULL, 0x0,
1230 NULL, HFILL }
1232 { &hf_vuze_dht_value_life_hours,
1233 { "Value Life Hours", "vuze-dht.value.life_hours",
1234 FT_UINT8, BASE_DEC, NULL, 0x0,
1235 NULL, HFILL }
1237 { &hf_vuze_dht_value_replication_factor,
1238 { "Value Replication Factor", "vuze-dht.value.replication_factor",
1239 FT_UINT8, BASE_DEC, NULL, 0x0,
1240 NULL, HFILL }
1242 { &hf_vuze_dht_connection_id,
1243 { "Connection ID", "vuze-dht.connection_id",
1244 FT_UINT64, BASE_DEC, NULL, 0x0,
1245 NULL, HFILL }
1247 { &hf_vuze_dht_action,
1248 { "Action", "vuze-dht.action",
1249 FT_UINT32, BASE_DEC, VALS(vuze_dht_action_type_vals), 0x0,
1250 NULL, HFILL }
1252 { &hf_vuze_dht_transaction_id,
1253 { "Transaction ID", "vuze-dht.transaction_id",
1254 FT_UINT32, BASE_DEC, NULL, 0x0,
1255 NULL, HFILL }
1257 { &hf_vuze_dht_vendor_id,
1258 { "Vendor ID", "vuze-dht.vendor_id",
1259 FT_UINT8, BASE_DEC, NULL, 0x0,
1260 NULL, HFILL }
1262 { &hf_vuze_dht_network_id,
1263 { "Network ID", "vuze-dht.network_id",
1264 FT_UINT32, BASE_DEC, NULL, 0x0,
1265 NULL, HFILL }
1267 { &hf_vuze_dht_local_proto_ver,
1268 { "Local Protocol Version", "vuze-dht.local_proto_ver",
1269 FT_UINT8, BASE_DEC, NULL, 0x0,
1270 NULL, HFILL }
1272 { &hf_vuze_dht_instance_id,
1273 { "Instance ID", "vuze-dht.instance_id",
1274 FT_UINT32, BASE_DEC, NULL, 0x0,
1275 NULL, HFILL }
1277 { &hf_vuze_dht_time,
1278 { "Time", "vuze-dht.time",
1279 FT_UINT64, BASE_DEC, NULL, 0x0,
1280 NULL, HFILL }
1282 { &hf_vuze_dht_network_coordinates_count,
1283 { "Network Coordinates Count", "vuze-dht.network_coordinates_count",
1284 FT_UINT8, BASE_DEC, NULL, 0x0,
1285 NULL, HFILL }
1287 { &hf_vuze_dht_network_coordinates,
1288 { "Network Coordinates", "vuze-dht.network_coordinates",
1289 FT_NONE, BASE_NONE, NULL, 0x0,
1290 NULL, HFILL }
1292 { &hf_vuze_dht_network_coordinate,
1293 { "Network Coordinate", "vuze-dht.network_coordinate",
1294 FT_NONE, BASE_NONE, NULL, 0x0,
1295 NULL, HFILL }
1297 { &hf_vuze_dht_network_coordinate_type,
1298 { "Network Coordinate Type", "vuze-dht.network_coordinate.type",
1299 FT_UINT8, BASE_DEC, VALS(vuze_dht_network_coordinate_type_vals), 0x0,
1300 NULL, HFILL }
1302 { &hf_vuze_dht_network_coordinate_size,
1303 { "Network Coordinate Size", "vuze-dht.network_coordinate.size",
1304 FT_UINT8, BASE_DEC, NULL, 0x0,
1305 NULL, HFILL }
1307 { &hf_vuze_dht_network_coordinate_data,
1308 { "Network Coordinate Data", "vuze-dht.network_coordinate.data",
1309 FT_BYTES, BASE_NONE, NULL, 0x0,
1310 NULL, HFILL }
1312 { &hf_vuze_dht_network_coordinate_x,
1313 { "Network Coordinate X", "vuze-dht.network_coordinate.x",
1314 FT_FLOAT, BASE_NONE, NULL, 0x0,
1315 NULL, HFILL }
1317 { &hf_vuze_dht_network_coordinate_y,
1318 { "Network Coordinate Y", "vuze-dht.network_coordinate.y",
1319 FT_FLOAT, BASE_NONE, NULL, 0x0,
1320 NULL, HFILL }
1322 { &hf_vuze_dht_network_coordinate_height,
1323 { "Network Coordinate Height", "vuze-dht.network_coordinate.height",
1324 FT_FLOAT, BASE_NONE, NULL, 0x0,
1325 NULL, HFILL }
1327 { &hf_vuze_dht_network_coordinate_error,
1328 { "Network Coordinate Error", "vuze-dht.network_coordinate.error",
1329 FT_FLOAT, BASE_NONE, NULL, 0x0,
1330 NULL, HFILL }
1332 { &hf_vuze_dht_spoof_id,
1333 { "Spoof ID", "vuze-dht.spoof_id",
1334 FT_UINT32, BASE_DEC, NULL, 0x0,
1335 NULL, HFILL }
1337 { &hf_vuze_dht_keys_count,
1338 { "Keys Count", "vuze-dht.keys_count",
1339 FT_UINT8, BASE_DEC, NULL, 0x0,
1340 NULL, HFILL }
1342 { &hf_vuze_dht_keys,
1343 { "Keys", "vuze-dht.keys",
1344 FT_NONE, BASE_NONE, NULL, 0x0,
1345 NULL, HFILL }
1347 { &hf_vuze_dht_key,
1348 { "Key", "vuze-dht.key",
1349 FT_NONE, BASE_NONE, NULL, 0x0,
1350 NULL, HFILL }
1352 { &hf_vuze_dht_key_len,
1353 { "Key Length", "vuze-dht.key.len",
1354 FT_UINT8, BASE_DEC, NULL, 0x0,
1355 NULL, HFILL }
1357 { &hf_vuze_dht_key_data,
1358 { "Key Data", "vuze-dht.key.data",
1359 FT_BYTES, BASE_NONE, NULL, 0x0,
1360 NULL, HFILL }
1362 { &hf_vuze_dht_values_count,
1363 { "Values Count", "vuze-dht.values_count",
1364 FT_UINT16, BASE_DEC, NULL, 0x0,
1365 NULL, HFILL }
1367 { &hf_vuze_dht_value_groups_count,
1368 { "Value Groups Count", "vuze-dht.value_groups_count",
1369 FT_UINT8, BASE_DEC, NULL, 0x0,
1370 NULL, HFILL }
1372 { &hf_vuze_dht_value_group,
1373 { "Values", "vuze-dht.values",
1374 FT_NONE, BASE_NONE, NULL, 0x0,
1375 NULL, HFILL }
1377 { &hf_vuze_dht_value_groups,
1378 { "Value Groups", "vuze-dht.value_groups",
1379 FT_NONE, BASE_NONE, NULL, 0x0,
1380 NULL, HFILL }
1382 { &hf_vuze_dht_diversifications_len,
1383 { "Diversifications Length", "vuze-dht.diversifications_len",
1384 FT_UINT8, BASE_DEC, NULL, 0x0,
1385 NULL, HFILL }
1387 { &hf_vuze_dht_diversifications,
1388 { "Diversifications", "vuze-dht.diversifications",
1389 FT_BYTES, BASE_NONE, NULL, 0x0,
1390 NULL, HFILL }
1392 { &hf_vuze_dht_id_len,
1393 { "ID Length", "vuze-dht.id_len",
1394 FT_UINT8, BASE_DEC, NULL, 0x0,
1395 NULL, HFILL }
1397 { &hf_vuze_dht_id,
1398 { "ID", "vuze-dht.id",
1399 FT_BYTES, BASE_NONE, NULL, 0x0,
1400 NULL, HFILL }
1402 { &hf_vuze_dht_node_status,
1403 { "Node Status", "vuze-dht.node_status",
1404 FT_UINT32, BASE_HEX, NULL, 0x0,
1405 NULL, HFILL }
1407 { &hf_vuze_dht_size,
1408 { "DHT Size", "vuze-dht.dht_size",
1409 FT_UINT32, BASE_DEC, NULL, 0x0,
1410 NULL, HFILL }
1412 { &hf_vuze_dht_node_type,
1413 { "Node Type", "vuze-dht.node_type",
1414 FT_UINT32, BASE_DEC, VALS(vuze_dht_node_type_vals), 0x0,
1415 NULL, HFILL }
1417 { &hf_vuze_dht_contacts_count,
1418 { "Contacts Count", "vuze-dht.contacts_count",
1419 FT_UINT16, BASE_DEC, NULL, 0x0,
1420 NULL, HFILL }
1422 { &hf_vuze_dht_contacts,
1423 { "Contacts", "vuze-dht.contacts",
1424 FT_NONE, BASE_NONE, NULL, 0x0,
1425 NULL, HFILL }
1427 { &hf_vuze_dht_flags,
1428 { "Flags", "vuze-dht.flags",
1429 FT_UINT8, BASE_DEC, VALS(vuze_dht_flag_type_vals), 0x0,
1430 NULL, HFILL }
1432 { &hf_vuze_dht_values_num,
1433 { "Values Num", "vuze-dht.stats.values_num",
1434 FT_UINT32, BASE_DEC, NULL, 0x0,
1435 NULL, HFILL }
1437 { &hf_vuze_dht_values_total,
1438 { "Values Total", "vuze-dht.stats.values_total",
1439 FT_UINT32, BASE_DEC, NULL, 0x0,
1440 NULL, HFILL }
1442 { &hf_vuze_dht_reads_per_min,
1443 { "Reads Per Minute", "vuze-dht.stats.reads_per_min",
1444 FT_UINT32, BASE_DEC, NULL, 0x0,
1445 NULL, HFILL }
1447 { &hf_vuze_dht_diversification_type,
1448 { "Diversification Type", "vuze-dht.stats.diversification_type",
1449 FT_UINT8, BASE_DEC, NULL, 0x0,
1450 NULL, HFILL }
1452 { &hf_vuze_dht_max_values,
1453 { "Max values", "vuze-dht.max_values",
1454 FT_UINT8, BASE_DEC, NULL, 0x0,
1455 NULL, HFILL }
1457 { &hf_vuze_dht_has_continuation,
1458 { "Has Continuation", "vuze-dht.has_continuation",
1459 FT_UINT8, BASE_DEC, VALS(vuze_dht_bool_type_vals), 0x0,
1460 NULL, HFILL }
1462 { &hf_vuze_dht_has_values,
1463 { "Has Values", "vuze-dht.has_values",
1464 FT_UINT8, BASE_DEC, VALS(vuze_dht_bool_type_vals), 0x0,
1465 NULL, HFILL }
1467 { &hf_vuze_dht_error_type,
1468 { "Error Type", "vuze-dht.error_type",
1469 FT_UINT32, BASE_DEC, VALS(vuze_dht_error_type_vals), 0x0,
1470 NULL, HFILL }
1472 { &hf_vuze_dht_key_block_request_len,
1473 { "Key Block Request Length", "vuze-dht.key_block_request_len",
1474 FT_UINT8, BASE_DEC, NULL, 0x0,
1475 NULL, HFILL }
1477 { &hf_vuze_dht_key_block_request,
1478 { "Key Block Request", "vuze-dht.key_block_request",
1479 FT_BYTES, BASE_NONE, NULL, 0x0,
1480 NULL, HFILL }
1482 { &hf_vuze_dht_signature_len,
1483 { "Signature Length", "vuze-dht.signature_len",
1484 FT_UINT16, BASE_DEC, NULL, 0x0,
1485 NULL, HFILL }
1487 { &hf_vuze_dht_signature,
1488 { "Signature", "vuze-dht.signature",
1489 FT_BYTES, BASE_NONE, NULL, 0x0,
1490 NULL, HFILL }
1492 { &hf_vuze_dht_generic_flags,
1493 { "Generic Flags", "vuze-dht.generic_flags",
1494 FT_UINT8, BASE_DEC, VALS(vuze_dht_generic_flag_type_vals), 0x0,
1495 NULL, HFILL }
1497 { &hf_vuze_dht_generic_flags2,
1498 { "Generic Flags 2", "vuze-dht.generic_flags2",
1499 FT_UINT8, BASE_DEC, VALS(vuze_dht_flag_type_vals), 0x0,
1500 NULL, HFILL }
1504 /* Setup protocol subtree array */
1505 static int *ett[] = {
1506 &ett_vuze_dht,
1507 &ett_vuze_dht_address,
1508 &ett_vuze_dht_contacts,
1509 &ett_vuze_dht_contact,
1510 &ett_vuze_dht_keys,
1511 &ett_vuze_dht_key,
1512 &ett_vuze_dht_value_groups,
1513 &ett_vuze_dht_value_group,
1514 &ett_vuze_dht_value,
1515 &ett_vuze_dht_network_coordinates,
1516 &ett_vuze_dht_network_coordinate
1519 /* Register protocol */
1520 proto_vuze_dht = proto_register_protocol ( "Vuze DHT Protocol", "Vuze-DHT", "vuze-dht" );
1522 proto_register_field_array(proto_vuze_dht, hf, array_length(hf));
1523 proto_register_subtree_array(ett, array_length(ett));
1525 vuze_dht_handle = register_dissector("vuze-dht", dissect_vuze_dht, proto_vuze_dht);
1528 void
1529 proto_reg_handoff_vuze_dht(void)
1531 dissector_add_uint("udp.port", DEFAULT_UDP_PORT, vuze_dht_handle);
1534 * Editor modelines
1536 * Local Variables:
1537 * c-basic-offset: 2
1538 * tab-width: 8
1539 * indent-tabs-mode: nil
1540 * End:
1542 * ex: set shiftwidth=2 tabstop=8 expandtab:
1543 * :indentSize=2:tabSize=8:noTabs=true: