2 * Routines for Dissecting the Gnutella Mojito DHT Protocol
3 * http://limewire.negatis.com/index.php?title=Mojito_Message_Format
5 * Copyright (c) 2008 by Travis Dawson <travis.dawson@sprint.com>
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include <epan/packet.h>
31 #include <epan/prefs.h>
32 #include <epan/expert.h>
34 #define MOJITO_HEADER_LENGTH 38
36 /* All the Defines for OpCodes */
37 #define MOJITO_PING_REQUEST 1
38 #define MOJITO_PING_RESPONSE 2
39 #define MOJITO_STORE_REQUEST 3
40 #define MOJITO_STORE_RESPONSE 4
41 #define MOJITO_FIND_NODE_REQUEST 5
42 #define MOJITO_FIND_NODE_RESPONSE 6
43 #define MOJITO_FIND_VALUE_REQUEST 7
44 #define MOJITO_FIND_VALUE_RESPONSE 8
45 #define MOJITO_STATS_REQUEST_DEPRECATED 9
46 #define MOJITO_STATS_RESPONSE_DEPRECATED 10
48 /* Initialize the protocol and registered fields */
49 static int proto_mojito
= -1;
52 static int hf_mojito_messageid
= -1;
53 static int hf_mojito_fdhtmessage
= -1;
54 static int hf_mojito_mjrversion
= -1;
55 static int hf_mojito_mnrversion
= -1;
56 static int hf_mojito_length
= -1;
57 static int hf_mojito_opcode
= -1;
58 static int hf_mojito_vendor
= -1;
59 static int hf_mojito_origmjrversion
= -1;
60 static int hf_mojito_origmnrversion
= -1;
61 static int hf_mojito_kuid
= -1;
62 static int hf_mojito_socketaddress_version
= -1;
63 static int hf_mojito_socketaddress_ipv4
= -1;
64 static int hf_mojito_socketaddress_ipv6
= -1;
65 static int hf_mojito_socketaddress_port
= -1;
66 static int hf_mojito_instanceid
= -1;
67 static int hf_mojito_flags
= -1;
68 static int hf_mojito_flags_shutdown
= -1;
69 static int hf_mojito_flags_firewalled
= -1;
70 static int hf_mojito_extendedlength
= -1;
71 static int hf_mojito_kuidcount
= -1;
72 static int hf_mojito_bigintegerlen
= -1;
73 static int hf_mojito_bigintegerval
= -1;
74 static int hf_mojito_dhtvaluetype
= -1;
75 static int hf_mojito_sectokenlen
= -1;
76 static int hf_mojito_sectoken
= -1;
77 static int hf_mojito_contactcount
= -1;
78 static int hf_mojito_contactvendor
= -1;
79 static int hf_mojito_contactversion
= -1;
80 static int hf_mojito_contactkuid
= -1;
81 static int hf_mojito_dhtvaluecount
= -1;
82 static int hf_mojito_dhtvalue_kuid
= -1;
83 static int hf_mojito_target_kuid
= -1;
84 static int hf_mojito_dhtvalue_valuetype
= -1;
85 static int hf_mojito_dhtvalue_version
= -1;
86 static int hf_mojito_dhtvalue_length
= -1;
87 static int hf_mojito_dhtvalue_value
= -1;
88 static int hf_mojito_bigint_value_one
= -1;
89 static int hf_mojito_bigint_value_two
= -1;
90 static int hf_mojito_bigint_value_three
= -1;
91 static int hf_mojito_bigint_value_four
= -1;
92 static int hf_mojito_storestatuscode_count
= -1;
93 static int hf_mojito_storestatuscode_code
= -1;
94 static int hf_mojito_storestatuscode_kuid
= -1;
95 static int hf_mojito_storestatuscode_secondary_kuid
= -1;
96 static int hf_mojito_requestload
= -1;
98 static int hf_mojito_startflag
= -1;
99 static int hf_mojito_endflag
= -1;
100 static int hf_mojito_priorityflag
= -1;
102 static int hf_mojito_opcode_data
= -1;
104 /* Initialize the subtree pointers */
105 static gint ett_mojito
= -1;
106 static gint ett_mojito_header
= -1;
107 static gint ett_mojito_header_version
= -1;
108 static gint ett_mojito_contact
= -1;
109 static gint ett_mojito_contact_version
= -1;
110 static gint ett_mojito_socket_address
= -1;
111 static gint ett_mojito_flags
= -1;
112 static gint ett_mojito_bigint
= -1;
113 static gint ett_mojito_opcode
= -1;
114 static gint ett_mojito_dht_version
= -1;
115 static gint ett_mojito_dht
= -1;
116 static gint ett_mojito_status_code
= -1;
117 static gint ett_mojito_kuids
= -1;
119 static expert_field ei_mojito_socketaddress_unknown
= EI_INIT
;
120 static expert_field ei_mojito_bigint_unsupported
= EI_INIT
;
123 static int udp_mojito_port
= 0;
125 typedef struct mojito_header_data
{
127 guint32 payloadlength
;
128 } mojito_header_data_t
;
130 /* Values for OPCode Flags */
131 static const value_string opcodeflags
[] = {
132 { MOJITO_PING_REQUEST
, "PING REQUEST" },
133 { MOJITO_PING_RESPONSE
, "PING RESPONSE" },
134 { MOJITO_STORE_REQUEST
, "STORE REQUEST" },
135 { MOJITO_STORE_RESPONSE
, "STORE RESPONSE" },
136 { MOJITO_FIND_NODE_REQUEST
, "FIND NODE REQUEST" },
137 { MOJITO_FIND_NODE_RESPONSE
, "FIND NODE RESPONSE" },
138 { MOJITO_FIND_VALUE_REQUEST
, "FIND VALUE REQUEST" },
139 { MOJITO_FIND_VALUE_RESPONSE
, "FIND VALUE RESPONSE" },
140 { MOJITO_STATS_REQUEST_DEPRECATED
, "STATS REQUEST (DEPRECATED)" },
141 { MOJITO_STATS_RESPONSE_DEPRECATED
, "STATS RESPONSE (DEPRECATED)" },
145 static const value_string statuscodeflags
[] = {
152 static const value_string vendorcodeflags
[] = {
153 { 0, "MESSAGES_SUPPORTED" },
155 { 5, "CRAWLER_PING" },
156 { 6, "CRAWLER_PONG" },
157 { 7, "UDP_CONNECT_BACK" },
158 { 8, "UDP_CONNECT_BACK_REDIR" },
159 { 9, "NGTH_MINUS_PAYLOAD" },
160 { 10, "CAPABILITIES" },
162 { 12, "REPLY_NUMBER" },
163 { 13, "OOB_PROXYING_CONTROL" },
164 { 14, "GIVE_STATS" },
165 { 15, "STATISTICS" },
168 { 21, "PUSH_PROXY_REQ" },
169 { 22, "PUSH_PROXY_ACK" },
170 { 23, "UDP_HEAD_PING" },
171 { 24, "UDP_HEAD_PONG" },
172 { 25, "HEADER_UPDATE" },
173 { 26, "UPDATE_REQ" },
174 { 27, "UPDATE_RESP" },
175 { 28, "CONTENT_REQ" },
176 { 29, "CONTENT_RESP" },
177 { 30, "INSPECTION_REQ" },
178 { 31, "INSPECTION_RESP" },
179 { 32, "ADVANCED_TOGGLE" },
180 { 33, "DHT_CONTACTS" },
187 dissect_mojito_address(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
188 int offset
, const char *title
)
191 guint8 socket_address_version
;
192 proto_tree
*socket_tree
;
193 proto_item
*socket_item
;
195 offset_start
= offset
;
197 /* new subtree for socket address*/
198 socket_address_version
= tvb_get_guint8(tvb
, offset
);
199 socket_item
= proto_tree_add_text(tree
, tvb
, offset
, 1, "%s", title
);
200 socket_tree
= proto_item_add_subtree(socket_item
, ett_mojito_socket_address
);
202 proto_tree_add_item(socket_tree
, hf_mojito_socketaddress_version
, tvb
, offset
, 1, ENC_NA
);
205 switch (socket_address_version
)
207 case FT_IPv4_LEN
: /* IPv4 */
209 proto_tree_add_item(socket_tree
, hf_mojito_socketaddress_ipv4
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
213 case FT_IPv6_LEN
: /* IPv6 */
215 proto_tree_add_item(socket_tree
, hf_mojito_socketaddress_ipv6
, tvb
, offset
, 16, ENC_NA
);
220 expert_add_info(pinfo
, socket_item
, &ei_mojito_socketaddress_unknown
);
224 proto_tree_add_item(socket_tree
, hf_mojito_socketaddress_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
227 proto_item_set_len(socket_item
, offset
- offset_start
);
233 dissect_mojito_contact(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
, int contact_id
)
236 proto_tree
*contact_tree
, *version_tree
;
237 proto_item
*contact_item
, *version_item
;
239 offset_start
= offset
;
243 contact_item
= proto_tree_add_text(tree
, tvb
, offset
, 1, "Contact #%d", contact_id
);
247 contact_item
= proto_tree_add_text(tree
, tvb
, offset
, 1, "Contact");
249 contact_tree
= proto_item_add_subtree(contact_item
, ett_mojito_contact
);
251 proto_tree_add_item(contact_tree
, hf_mojito_contactvendor
, tvb
, offset
, 4, ENC_ASCII
|ENC_NA
);
254 version_item
= proto_tree_add_item(contact_tree
, hf_mojito_contactversion
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
255 version_tree
= proto_item_add_subtree(version_item
, ett_mojito_contact_version
);
256 proto_tree_add_item(version_tree
, hf_mojito_mjrversion
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
258 proto_tree_add_item(version_tree
, hf_mojito_mnrversion
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
261 proto_tree_add_item(contact_tree
, hf_mojito_contactkuid
, tvb
, offset
, 20, ENC_NA
);
264 offset
= dissect_mojito_address(tvb
, pinfo
, contact_tree
, offset
, "Socket Address");
271 proto_item_set_len(contact_item
, offset
- offset_start
);
273 return offset
- offset_start
;
277 dissect_mojito_header(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
278 int offset
, mojito_header_data_t
* header_data
)
280 proto_tree
*header_tree
, *version_tree
, *contact_tree
, *flag_tree
;
281 proto_item
*header_item
, *version_item
, *contact_item
, *flag_item
;
282 int start_offset
= offset
;
283 int contact_start_offset
;
285 header_item
= proto_tree_add_text(tree
, tvb
, offset
, 61, "Gnutella Header");
286 header_tree
= proto_item_add_subtree(header_item
, ett_mojito_header
);
288 proto_tree_add_item(header_tree
, hf_mojito_messageid
, tvb
, offset
, 16, ENC_NA
);
291 proto_tree_add_item(header_tree
, hf_mojito_fdhtmessage
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
294 version_item
= proto_tree_add_text(header_tree
, tvb
, offset
, 2, "Version");
295 version_tree
= proto_item_add_subtree(version_item
, ett_mojito_header_version
);
297 proto_tree_add_item(version_tree
, hf_mojito_mjrversion
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
299 proto_tree_add_item(version_tree
, hf_mojito_mnrversion
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
302 /* Payload Length : in Little Endian */
303 header_data
->payloadlength
= tvb_get_letohl(tvb
, offset
);
304 proto_tree_add_item(header_tree
, hf_mojito_length
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
307 header_data
->opcode
= tvb_get_guint8(tvb
, offset
);
308 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s", val_to_str_const(header_data
->opcode
, opcodeflags
, "Unknown"));
309 proto_tree_add_item(header_tree
, hf_mojito_opcode
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
312 contact_start_offset
= offset
;
313 contact_item
= proto_tree_add_text(header_tree
, tvb
, offset
, 35, "Originating Contact");
314 contact_tree
= proto_item_add_subtree(contact_item
, ett_mojito_contact
);
316 proto_tree_add_item(contact_tree
, hf_mojito_vendor
, tvb
, offset
, 4, ENC_ASCII
|ENC_NA
);
319 version_item
= proto_tree_add_text(contact_tree
, tvb
, offset
, 2, "Contact Version");
320 version_tree
= proto_item_add_subtree(version_item
, ett_mojito_contact_version
);
322 proto_tree_add_item(version_tree
, hf_mojito_origmjrversion
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
324 proto_tree_add_item(version_tree
, hf_mojito_origmnrversion
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
327 proto_tree_add_item(contact_tree
, hf_mojito_kuid
, tvb
, offset
, 20, ENC_NA
);
330 offset
= dissect_mojito_address(tvb
, pinfo
, contact_tree
, offset
, "Socket Address");
337 proto_item_set_len(contact_item
, offset
- contact_start_offset
);
339 proto_tree_add_item(header_tree
, hf_mojito_instanceid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
343 flag_item
= proto_tree_add_item(header_tree
, hf_mojito_flags
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
344 flag_tree
= proto_item_add_subtree(flag_item
, ett_mojito_flags
);
345 proto_tree_add_item(flag_tree
, hf_mojito_flags_shutdown
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
346 proto_tree_add_item(flag_tree
, hf_mojito_flags_firewalled
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
349 proto_tree_add_item(header_tree
, hf_mojito_extendedlength
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
352 proto_item_set_len(header_item
, offset
-start_offset
);
357 dissect_mojito_ping_response(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
360 proto_tree
*bigint_tree
;
361 proto_item
*bigint_item
;
363 offset
= dissect_mojito_address(tvb
, pinfo
, tree
,
364 offset
, "Requester's External Socket Address");
372 bigintlen
= tvb_get_guint8(tvb
, offset
);
373 bigint_item
= proto_tree_add_text(tree
, tvb
, offset
, bigintlen
+ 1 , "Estimated DHT size");
374 bigint_tree
= proto_item_add_subtree(bigint_item
, ett_mojito_bigint
);
376 proto_tree_add_item(bigint_tree
, hf_mojito_bigintegerlen
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
382 proto_tree_add_item(bigint_tree
, hf_mojito_bigint_value_one
, tvb
, offset
, bigintlen
, ENC_BIG_ENDIAN
);
386 proto_tree_add_item(bigint_tree
, hf_mojito_bigint_value_two
, tvb
, offset
, bigintlen
, ENC_BIG_ENDIAN
);
390 proto_tree_add_item(bigint_tree
, hf_mojito_bigint_value_three
, tvb
, offset
, bigintlen
, ENC_BIG_ENDIAN
);
394 proto_tree_add_item(bigint_tree
, hf_mojito_bigint_value_four
, tvb
, offset
, bigintlen
, ENC_BIG_ENDIAN
);
397 expert_add_info(pinfo
, bigint_item
, &ei_mojito_bigint_unsupported
);
402 proto_tree_add_item(bigint_tree
, hf_mojito_bigintegerval
, tvb
, offset
, bigintlen
, ENC_NA
);
406 dissect_mojito_store_request(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
408 proto_tree
*dht_tree
, *version_tree
;
409 proto_item
*dht_item
, *version_item
;
410 guint8 ii
, contactcount
;
411 guint8 sectokenlen
= tvb_get_guint8(tvb
, offset
);
412 guint16 dhtvaluelength
;
413 int contact_offset
, start_offset
;
415 proto_tree_add_item(tree
, hf_mojito_sectokenlen
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
418 proto_tree_add_item(tree
, hf_mojito_sectoken
, tvb
, offset
, sectokenlen
, ENC_NA
);
419 offset
+= sectokenlen
;
422 proto_tree_add_item(tree
, hf_mojito_dhtvaluecount
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
423 contactcount
= tvb_get_guint8(tvb
, offset
);
426 /* For each Contact, display the info */
427 for (ii
= 0; ii
< contactcount
; ii
++)
429 dht_item
= proto_tree_add_text(tree
, tvb
, offset
, 1, "DHTValue #%d", ii
+1);
430 dht_tree
= proto_item_add_subtree(dht_item
, ett_mojito_dht
);
431 start_offset
= offset
;
432 contact_offset
= dissect_mojito_contact(tvb
, pinfo
, dht_tree
, offset
, -1);
433 if (contact_offset
== 0)
435 offset
+= contact_offset
;
437 proto_tree_add_item(dht_tree
, hf_mojito_dhtvalue_kuid
, tvb
, offset
, 20, ENC_NA
);
440 proto_tree_add_item(dht_tree
, hf_mojito_dhtvalue_valuetype
, tvb
, offset
, 4, ENC_ASCII
|ENC_NA
);
444 version_item
= proto_tree_add_item(dht_tree
, hf_mojito_dhtvalue_version
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
445 version_tree
= proto_item_add_subtree(version_item
, ett_mojito_dht_version
);
447 proto_tree_add_item(version_tree
, hf_mojito_mjrversion
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
449 proto_tree_add_item(version_tree
, hf_mojito_mnrversion
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
452 dhtvaluelength
= tvb_get_ntohs(tvb
, offset
);
453 proto_tree_add_item(dht_tree
, hf_mojito_dhtvalue_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
456 proto_tree_add_item(dht_tree
, hf_mojito_dhtvalue_value
, tvb
, offset
, dhtvaluelength
, ENC_ASCII
|ENC_NA
);
457 offset
+= dhtvaluelength
;
459 proto_item_set_len(dht_item
, offset
-start_offset
);
464 dissect_mojito_store_response(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
468 guint8 ii
, contactcount
= tvb_get_guint8(tvb
, offset
);
469 guint16 dhtvaluelength
;
472 proto_tree_add_item(tree
, hf_mojito_storestatuscode_count
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
475 /* For each Contact, display the info */
476 for (ii
= 0; ii
< contactcount
; ii
++)
478 sc_item
= proto_tree_add_text(tree
, tvb
, offset
, 23, "Status Code %d", ii
+1);
479 sc_tree
= proto_item_add_subtree(sc_item
, ett_mojito_status_code
);
481 start_offset
= offset
;
484 proto_tree_add_item(sc_tree
, hf_mojito_storestatuscode_kuid
, tvb
, offset
, 20, ENC_NA
);
487 if (tvb_reported_length_remaining(tvb
, offset
+3) > 0)
489 /* Must be a secondard KUID */
490 proto_tree_add_item(sc_tree
, hf_mojito_storestatuscode_secondary_kuid
, tvb
, offset
, 20, ENC_NA
);
494 proto_tree_add_item(sc_tree
, hf_mojito_storestatuscode_code
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
497 dhtvaluelength
= tvb_get_ntohs(tvb
, offset
);
498 proto_tree_add_item(sc_tree
, hf_mojito_dhtvalue_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
501 proto_tree_add_item(sc_tree
, hf_mojito_dhtvalue_value
, tvb
, offset
, dhtvaluelength
, ENC_ASCII
|ENC_NA
);
502 offset
+= dhtvaluelength
;
504 proto_item_set_len(sc_item
, offset
-start_offset
);
509 dissect_mojito_find_node_response(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
511 guint8 ii
, contactcount
;
512 guint8 sectokenlen
= tvb_get_guint8(tvb
, offset
);
515 proto_tree_add_item(tree
, hf_mojito_sectokenlen
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
518 proto_tree_add_item(tree
, hf_mojito_sectoken
, tvb
, offset
, sectokenlen
, ENC_NA
);
519 offset
+= sectokenlen
;
521 contactcount
= tvb_get_guint8(tvb
, offset
);
522 proto_tree_add_item(tree
, hf_mojito_contactcount
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
525 /* For each Contact, display the info */
526 for (ii
= 0; ii
< contactcount
; ii
++)
528 contact_offset
= dissect_mojito_contact(tvb
, pinfo
, tree
, offset
, ii
+1);
529 if (contact_offset
== 0)
531 offset
+= contact_offset
;
536 dissect_mojito_find_value_request(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
538 proto_tree
*kuid_tree
;
539 proto_item
*kuid_item
;
545 proto_tree_add_item(tree
, hf_mojito_target_kuid
, tvb
, offset
, 20, ENC_NA
);
548 kuidcount
= tvb_get_guint8(tvb
, offset
);
550 kuid_item
= proto_tree_add_text(tree
, tvb
, offset
, (20 * kuidcount
) + 1 , "Secondary KUID\'s");
551 kuid_tree
= proto_item_add_subtree(kuid_item
, ett_mojito_kuids
);
553 proto_tree_add_item(kuid_tree
, hf_mojito_kuidcount
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
556 /* All the Secondary KUID's */
557 for (i
= 0; i
< kuidcount
; i
++)
559 proto_tree_add_item(kuid_tree
, hf_mojito_kuid
, tvb
, offset
, 20, ENC_NA
);
563 proto_tree_add_item(tree
, hf_mojito_dhtvaluetype
, tvb
, offset
, 4, ENC_ASCII
|ENC_NA
);
568 dissect_mojito_find_value_response(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
570 proto_tree
*dht_tree
, *version_tree
, *kuid_tree
;
571 proto_item
*dht_item
, *version_item
, *kuid_item
;
572 guint16 dhtvaluelength
;
573 int contact_offset
, start_offset
;
574 guint8 ii
, dhtvaluescount
, kuidcount
;
576 proto_tree_add_item(tree
, hf_mojito_requestload
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
579 dhtvaluescount
= tvb_get_guint8(tvb
, offset
);
580 proto_tree_add_item(tree
, hf_mojito_dhtvaluecount
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
583 /* For each Contact, display the info */
584 for (ii
= 0; ii
< dhtvaluescount
; ii
++)
586 dht_item
= proto_tree_add_text(tree
, tvb
, offset
, 1, "DHTValue #%d", ii
+1);
587 dht_tree
= proto_item_add_subtree(dht_item
, ett_mojito_dht
);
588 start_offset
= offset
;
589 contact_offset
= dissect_mojito_contact(tvb
, pinfo
, dht_tree
, offset
, -1);
590 if (contact_offset
== 0)
593 offset
+= contact_offset
;
595 proto_tree_add_item(dht_tree
, hf_mojito_dhtvalue_kuid
, tvb
, offset
, 20, ENC_NA
);
598 proto_tree_add_item(dht_tree
, hf_mojito_dhtvalue_valuetype
, tvb
, offset
, 4, ENC_ASCII
|ENC_NA
);
602 version_item
= proto_tree_add_item(dht_tree
, hf_mojito_dhtvalue_version
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
603 version_tree
= proto_item_add_subtree(version_item
, ett_mojito_dht_version
);
605 proto_tree_add_item(version_tree
, hf_mojito_mjrversion
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
607 proto_tree_add_item(version_tree
, hf_mojito_mnrversion
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
611 dhtvaluelength
= tvb_get_ntohs(tvb
, offset
);
612 proto_tree_add_item(dht_tree
, hf_mojito_dhtvalue_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
616 proto_tree_add_item(dht_tree
, hf_mojito_dhtvalue_value
, tvb
, offset
, dhtvaluelength
, ENC_ASCII
|ENC_NA
);
617 offset
+= dhtvaluelength
;
619 proto_item_set_len(dht_item
, offset
-start_offset
);
623 kuidcount
= tvb_get_guint8(tvb
, offset
);
624 kuid_item
= proto_tree_add_text(tree
, tvb
, offset
, (20 * kuidcount
) + 1 , "Secondary KUID\'s");
625 kuid_tree
= proto_item_add_subtree(kuid_item
, ett_mojito_kuids
);
626 proto_tree_add_item(kuid_tree
, hf_mojito_kuidcount
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
629 /* All the Secondary KUID's */
630 for (ii
= 0; ii
< kuidcount
; ii
++)
632 proto_tree_add_item(kuid_tree
, hf_mojito_kuid
, tvb
, offset
, 20, ENC_NA
);
638 dissect_mojito(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
640 proto_tree
*mojito_tree
, *opcode_tree
;
641 proto_item
*ti
, *opcode_item
;
642 mojito_header_data_t header_data
;
645 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "Mojito");
646 col_clear(pinfo
->cinfo
, COL_INFO
);
648 /* Add a new item to the tree */
649 ti
= proto_tree_add_item(tree
, proto_mojito
, tvb
, 0, -1, ENC_NA
);
650 mojito_tree
= proto_item_add_subtree(ti
, ett_mojito
);
652 offset
= dissect_mojito_header(tvb
, pinfo
, mojito_tree
, offset
, &header_data
);
653 if (offset
== 0) /* Some error occurred */
656 opcode_item
= proto_tree_add_text(mojito_tree
, tvb
,
657 offset
, header_data
.payloadlength
- MOJITO_HEADER_LENGTH
,
658 "Opcode specific data (%s)",
659 val_to_str_const(header_data
.opcode
, opcodeflags
, "Unknown"));
660 opcode_tree
= proto_item_add_subtree(opcode_item
, ett_mojito_opcode
);
662 /* Now use the opcode to figure out what to do next */
663 switch (header_data
.opcode
)
665 case MOJITO_PING_RESPONSE
: /* PING RESPONSE */
666 dissect_mojito_ping_response(tvb
, pinfo
, opcode_tree
, offset
);
669 case MOJITO_STORE_REQUEST
: /* STORE REQUEST */
670 dissect_mojito_store_request(tvb
, pinfo
, opcode_tree
, offset
);
673 case MOJITO_STORE_RESPONSE
: /* STORE RESPONSE */
674 dissect_mojito_store_response(tvb
, pinfo
, opcode_tree
, offset
);
677 case MOJITO_FIND_NODE_REQUEST
: /* FIND NODE REQUEST */
678 proto_tree_add_item(opcode_tree
, hf_mojito_target_kuid
, tvb
, offset
, 20, ENC_NA
);
681 case MOJITO_FIND_NODE_RESPONSE
: /* FIND NODE RESPONSE */
682 dissect_mojito_find_node_response(tvb
, pinfo
, opcode_tree
, offset
);
685 case MOJITO_FIND_VALUE_REQUEST
: /* FIND VALUE REQUEST */
686 dissect_mojito_find_value_request(tvb
, pinfo
, opcode_tree
, offset
);
689 case MOJITO_FIND_VALUE_RESPONSE
: /* FIND VALUE RESPONSE */
690 dissect_mojito_find_value_response(tvb
, pinfo
, opcode_tree
, offset
);
693 case MOJITO_PING_REQUEST
: /* PING REQUEST */
694 case MOJITO_STATS_REQUEST_DEPRECATED
: /* STATS REQUEST (DEPRECATED) */
695 case MOJITO_STATS_RESPONSE_DEPRECATED
: /* STATS RESPONSE (DEPRECATED) */
697 if (header_data
.payloadlength
- MOJITO_HEADER_LENGTH
> 0)
698 proto_tree_add_item(opcode_tree
, hf_mojito_opcode_data
, tvb
,
699 offset
, header_data
.payloadlength
- MOJITO_HEADER_LENGTH
, ENC_NA
);
703 return tvb_length(tvb
);
706 static gboolean
dissect_mojito_heuristic (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
709 Test the overall length to make sure it's at least 61 bytes (the header)
710 Test to make sure that it's of type 44 (mojito)
711 Test to make sure that the length field is there and correct
712 (tvb_get_letohl(tvb, 20) + 23) == tvb_length(tvb)
714 if ((tvb_length(tvb
) >= 60) &&
715 (tvb_get_guint8(tvb
, 16) == 68) &&
716 ((tvb_get_letohl(tvb
, 19) + 23) == tvb_reported_length(tvb
)))
718 dissect_mojito(tvb
, pinfo
, tree
, NULL
);
725 /* Register the mojito dissector */
727 proto_register_mojito(void)
729 module_t
*mojito_module
;
730 expert_module_t
* expert_mojito
;
732 static hf_register_info hf
[] = {
733 { &hf_mojito_dhtvaluecount
,
734 { "DHTValue Count", "mojito.dhtvaluecount",
739 { &hf_mojito_messageid
,
740 { "Message ID", "mojito.messageid",
745 { &hf_mojito_requestload
,
746 { "Request Load", "mojito.requestload",
751 { &hf_mojito_fdhtmessage
,
752 { "FDHTMessage", "mojito.fdhtmessage",
757 { &hf_mojito_mjrversion
,
758 { "Major Version", "mojito.majorversion",
763 { &hf_mojito_mnrversion
,
764 { "Minor Version", "mojito.minorversion",
770 { "Payload Length", "mojito.payloadlength",
776 { "OPCode", "mojito.opcode",
778 VALS(opcodeflags
), 0x0,
782 { "Vendor", "mojito.vendor",
783 FT_STRING
, BASE_NONE
,
787 { &hf_mojito_origmjrversion
,
788 { "Major Version", "mojito.majorversion",
793 { &hf_mojito_origmnrversion
,
794 { "Minor Version", "mojito.minorversion",
800 { "Kademlia Unique ID (KUID)", "mojito.kuid",
805 { &hf_mojito_socketaddress_version
,
806 { "IP Version", "mojito.socketaddressversion",
811 { &hf_mojito_socketaddress_ipv4
,
812 { "IP Address", "mojito.socketaddressipv4",
817 { &hf_mojito_socketaddress_ipv6
,
818 { "IP Address", "mojito.socketaddressipv6",
823 { &hf_mojito_socketaddress_port
,
824 { "IP Port", "mojito.socketaddressport",
829 { &hf_mojito_instanceid
,
830 { "Instance ID", "mojito.instanceid",
836 { "Flags", "mojito.flags",
841 { &hf_mojito_flags_shutdown
,
842 { "SHUTDOWN", "mojito.shutdownflag",
847 { &hf_mojito_flags_firewalled
,
848 { "Firewalled", "mojito.firewalledflag",
853 { &hf_mojito_extendedlength
,
854 { "Extended Length", "mojito.extlength",
859 { &hf_mojito_kuidcount
,
860 { "Secondary KUID Count", "mojito.kuidcount",
865 { &hf_mojito_dhtvaluetype
,
866 { "DHT Value Type", "mojito.dhtvaluetype",
867 FT_STRING
, BASE_NONE
,
871 { &hf_mojito_bigintegerlen
,
872 { "Big Integer Length", "mojito.bigintegerlen",
877 { &hf_mojito_bigintegerval
,
878 { "Big Integer HEX Value", "mojito.bigintegerhexval",
883 { &hf_mojito_sectokenlen
,
884 { "Security Token Length", "mojito.sectokenlen",
889 { &hf_mojito_sectoken
,
890 { "Security Token", "mojito.sectoken",
895 { &hf_mojito_contactcount
,
896 { "Contact Count", "mojito.contactcount",
901 { &hf_mojito_contactvendor
,
902 { "Vendor", "mojito.contactvendor",
903 FT_STRING
, BASE_NONE
,
907 { &hf_mojito_contactversion
,
908 { "Contact Version", "mojito.contactversion",
913 { &hf_mojito_contactkuid
,
914 { "KUID of the Contact", "mojito.contactkuid",
919 { &hf_mojito_dhtvalue_valuetype
,
920 { "DHTValue ValueType", "mojito.dhtvaluevaluetype",
921 FT_STRING
, BASE_NONE
,
925 { &hf_mojito_dhtvalue_version
,
926 { "DHTValue Version", "mojito.dhtvalueversion",
931 { &hf_mojito_dhtvalue_length
,
932 { "DHTValue Length", "mojito.dhtvaluelength",
937 { &hf_mojito_dhtvalue_value
,
938 { "DHTValue", "mojito.dhtvaluehexvalue",
939 FT_STRING
, BASE_NONE
,
943 { &hf_mojito_bigint_value_one
,
944 { "Big Integer DEC Value", "mojito.bigintegerval",
949 { &hf_mojito_bigint_value_two
,
950 { "Big Integer DEC Value", "mojito.bigintegerval",
955 { &hf_mojito_bigint_value_three
,
956 { "Big Integer DEC Value", "mojito.bigintegerval",
961 { &hf_mojito_bigint_value_four
,
962 { "Big Integer DEC Value", "mojito.bigintegerval",
967 { &hf_mojito_dhtvalue_kuid
,
968 { "Kademlia Unique ID (KUID)", "mojito.kuid",
973 { &hf_mojito_target_kuid
,
974 { "Target Kademlia Unique ID (KUID)", "mojito.kuid",
979 { &hf_mojito_storestatuscode_count
,
980 { "Status Code Count", "mojito.statuscodecount",
985 { &hf_mojito_storestatuscode_code
,
986 { "StatusCode", "mojito.statuscodecount",
988 VALS(statuscodeflags
), 0x0,
991 { &hf_mojito_storestatuscode_kuid
,
992 { "Primary KUID of the Status Code", "mojito.statuscodekuid",
997 { &hf_mojito_storestatuscode_secondary_kuid
,
998 { "Secondary KUID of the Status Code", "mojito.statuscodesecondarykuid",
1003 { &hf_mojito_opcode_data
,
1004 { "Data", "mojito.opcode.data",
1005 FT_BYTES
, BASE_NONE
,
1011 /* Setup protocol subtree array */
1012 static gint
*ett
[] = {
1015 &ett_mojito_header_version
,
1016 &ett_mojito_contact
,
1017 &ett_mojito_contact_version
,
1018 &ett_mojito_socket_address
,
1022 &ett_mojito_dht_version
,
1024 &ett_mojito_status_code
,
1028 static ei_register_info ei
[] = {
1029 { &ei_mojito_socketaddress_unknown
, { "mojito.socketaddress.unknown", PI_PROTOCOL
, PI_ERROR
, "Unsupported Socket Address Type", EXPFILL
}},
1030 { &ei_mojito_bigint_unsupported
, { "mojito.bigint.unsupported", PI_PROTOCOL
, PI_ERROR
, "Unsupported BigInt length", EXPFILL
}},
1033 proto_mojito
= proto_register_protocol("Mojito DHT", "Mojito", "mojito");
1035 proto_register_field_array(proto_mojito
, hf
, array_length(hf
));
1036 proto_register_subtree_array(ett
, array_length(ett
));
1037 expert_mojito
= expert_register_protocol(proto_mojito
);
1038 expert_register_field_array(expert_mojito
, ei
, array_length(ei
));
1041 mojito_module
= prefs_register_protocol(proto_mojito
, NULL
);
1043 prefs_register_uint_preference(mojito_module
,
1051 /* Control the handoff */
1053 proto_reg_handoff_mojito(void)
1055 static gboolean initialized
= FALSE
;
1056 static int old_mojito_udp_port
= 0;
1057 static dissector_handle_t mojito_handle
;
1060 mojito_handle
= new_create_dissector_handle(dissect_mojito
, proto_mojito
);
1061 heur_dissector_add("udp", dissect_mojito_heuristic
, proto_mojito
);
1065 /* Register UDP port for dissection */
1066 if(old_mojito_udp_port
!= 0 && old_mojito_udp_port
!= udp_mojito_port
){
1067 dissector_delete_uint("udp.port", old_mojito_udp_port
, mojito_handle
);
1070 if(udp_mojito_port
!= 0 && old_mojito_udp_port
!= udp_mojito_port
) {
1071 dissector_add_uint("udp.port", udp_mojito_port
, mojito_handle
);
1074 old_mojito_udp_port
= udp_mojito_port
;
1078 * Editor modelines - http://www.wireshark.org/tools/modelines.html
1083 * indent-tabs-mode: t
1086 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1087 * :indentSize=8:tabSize=8:noTabs=false: