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>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include <epan/packet.h>
17 #include <epan/expert.h>
19 void proto_register_mojito(void);
20 void proto_reg_handoff_mojito(void);
22 static dissector_handle_t mojito_handle
;
24 #define MOJITO_HEADER_LENGTH 38
26 /* All the Defines for OpCodes */
27 #define MOJITO_PING_REQUEST 1
28 #define MOJITO_PING_RESPONSE 2
29 #define MOJITO_STORE_REQUEST 3
30 #define MOJITO_STORE_RESPONSE 4
31 #define MOJITO_FIND_NODE_REQUEST 5
32 #define MOJITO_FIND_NODE_RESPONSE 6
33 #define MOJITO_FIND_VALUE_REQUEST 7
34 #define MOJITO_FIND_VALUE_RESPONSE 8
35 #define MOJITO_STATS_REQUEST_DEPRECATED 9
36 #define MOJITO_STATS_RESPONSE_DEPRECATED 10
38 /* Initialize the protocol and registered fields */
39 static int proto_mojito
;
42 static int hf_mojito_messageid
;
43 static int hf_mojito_fdhtmessage
;
44 static int hf_mojito_mjrversion
;
45 static int hf_mojito_mnrversion
;
46 static int hf_mojito_length
;
47 static int hf_mojito_opcode
;
48 static int hf_mojito_vendor
;
49 static int hf_mojito_origmjrversion
;
50 static int hf_mojito_origmnrversion
;
51 static int hf_mojito_kuid
;
52 static int hf_mojito_socketaddress_version
;
53 static int hf_mojito_socketaddress_ipv4
;
54 static int hf_mojito_socketaddress_ipv6
;
55 static int hf_mojito_socketaddress_port
;
56 static int hf_mojito_instanceid
;
57 static int hf_mojito_flags
;
58 static int hf_mojito_flags_shutdown
;
59 static int hf_mojito_flags_firewalled
;
60 static int hf_mojito_extendedlength
;
61 static int hf_mojito_kuidcount
;
62 static int hf_mojito_bigintegerlen
;
63 static int hf_mojito_bigintegerval
;
64 static int hf_mojito_dhtvaluetype
;
65 static int hf_mojito_sectokenlen
;
66 static int hf_mojito_sectoken
;
67 static int hf_mojito_contactcount
;
68 static int hf_mojito_contactvendor
;
69 static int hf_mojito_contactversion
;
70 static int hf_mojito_contactkuid
;
71 static int hf_mojito_dhtvaluecount
;
72 static int hf_mojito_dhtvalue_kuid
;
73 static int hf_mojito_target_kuid
;
74 static int hf_mojito_dhtvalue_valuetype
;
75 static int hf_mojito_dhtvalue_version
;
76 static int hf_mojito_dhtvalue_length
;
77 static int hf_mojito_dhtvalue_value
;
78 static int hf_mojito_bigint_value_one
;
79 static int hf_mojito_bigint_value_two
;
80 static int hf_mojito_bigint_value_three
;
81 static int hf_mojito_bigint_value_four
;
82 static int hf_mojito_storestatuscode_count
;
83 static int hf_mojito_storestatuscode_code
;
84 static int hf_mojito_storestatuscode_kuid
;
85 static int hf_mojito_storestatuscode_secondary_kuid
;
86 static int hf_mojito_requestload
;
88 static int hf_mojito_startflag
;
89 static int hf_mojito_endflag
;
90 static int hf_mojito_priorityflag
;
92 static int hf_mojito_opcode_data
;
94 /* Initialize the subtree pointers */
95 static int ett_mojito
;
96 static int ett_mojito_header
;
97 static int ett_mojito_header_version
;
98 static int ett_mojito_contact
;
99 static int ett_mojito_contact_version
;
100 static int ett_mojito_socket_address
;
101 static int ett_mojito_flags
;
102 static int ett_mojito_bigint
;
103 static int ett_mojito_opcode
;
104 static int ett_mojito_dht_version
;
105 static int ett_mojito_dht
;
106 static int ett_mojito_status_code
;
107 static int ett_mojito_kuids
;
109 static expert_field ei_mojito_socketaddress_unknown
;
110 static expert_field ei_mojito_bigint_unsupported
;
112 typedef struct mojito_header_data
{
114 uint32_t payloadlength
;
115 } mojito_header_data_t
;
117 /* Values for OPCode Flags */
118 static const value_string opcodeflags
[] = {
119 { MOJITO_PING_REQUEST
, "PING REQUEST" },
120 { MOJITO_PING_RESPONSE
, "PING RESPONSE" },
121 { MOJITO_STORE_REQUEST
, "STORE REQUEST" },
122 { MOJITO_STORE_RESPONSE
, "STORE RESPONSE" },
123 { MOJITO_FIND_NODE_REQUEST
, "FIND NODE REQUEST" },
124 { MOJITO_FIND_NODE_RESPONSE
, "FIND NODE RESPONSE" },
125 { MOJITO_FIND_VALUE_REQUEST
, "FIND VALUE REQUEST" },
126 { MOJITO_FIND_VALUE_RESPONSE
, "FIND VALUE RESPONSE" },
127 { MOJITO_STATS_REQUEST_DEPRECATED
, "STATS REQUEST (DEPRECATED)" },
128 { MOJITO_STATS_RESPONSE_DEPRECATED
, "STATS RESPONSE (DEPRECATED)" },
132 static const value_string statuscodeflags
[] = {
139 static const value_string vendorcodeflags
[] = {
140 { 0, "MESSAGES_SUPPORTED" },
142 { 5, "CRAWLER_PING" },
143 { 6, "CRAWLER_PONG" },
144 { 7, "UDP_CONNECT_BACK" },
145 { 8, "UDP_CONNECT_BACK_REDIR" },
146 { 9, "NGTH_MINUS_PAYLOAD" },
147 { 10, "CAPABILITIES" },
149 { 12, "REPLY_NUMBER" },
150 { 13, "OOB_PROXYING_CONTROL" },
151 { 14, "GIVE_STATS" },
152 { 15, "STATISTICS" },
155 { 21, "PUSH_PROXY_REQ" },
156 { 22, "PUSH_PROXY_ACK" },
157 { 23, "UDP_HEAD_PING" },
158 { 24, "UDP_HEAD_PONG" },
159 { 25, "HEADER_UPDATE" },
160 { 26, "UPDATE_REQ" },
161 { 27, "UPDATE_RESP" },
162 { 28, "CONTENT_REQ" },
163 { 29, "CONTENT_RESP" },
164 { 30, "INSPECTION_REQ" },
165 { 31, "INSPECTION_RESP" },
166 { 32, "ADVANCED_TOGGLE" },
167 { 33, "DHT_CONTACTS" },
174 dissect_mojito_address(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
175 int offset
, const char *title
)
178 uint8_t socket_address_version
;
179 proto_tree
*socket_tree
;
180 proto_item
*socket_item
;
182 offset_start
= offset
;
184 /* new subtree for socket address*/
185 socket_address_version
= tvb_get_uint8(tvb
, offset
);
186 socket_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, 1, ett_mojito_socket_address
, &socket_item
, title
);
188 proto_tree_add_item(socket_tree
, hf_mojito_socketaddress_version
, tvb
, offset
, 1, ENC_NA
);
191 switch (socket_address_version
)
193 case FT_IPv4_LEN
: /* IPv4 */
195 proto_tree_add_item(socket_tree
, hf_mojito_socketaddress_ipv4
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
199 case FT_IPv6_LEN
: /* IPv6 */
201 proto_tree_add_item(socket_tree
, hf_mojito_socketaddress_ipv6
, tvb
, offset
, 16, ENC_NA
);
206 expert_add_info(pinfo
, socket_item
, &ei_mojito_socketaddress_unknown
);
210 proto_tree_add_item(socket_tree
, hf_mojito_socketaddress_port
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
213 proto_item_set_len(socket_item
, offset
- offset_start
);
219 dissect_mojito_contact(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
, int contact_id
)
222 proto_tree
*contact_tree
, *version_tree
;
223 proto_item
*contact_item
, *version_item
;
225 offset_start
= offset
;
229 contact_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
, 1, ett_mojito_contact
, &contact_item
, "Contact #%d", contact_id
);
233 contact_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, 1, ett_mojito_contact
, &contact_item
, "Contact");
236 proto_tree_add_item(contact_tree
, hf_mojito_contactvendor
, tvb
, offset
, 4, ENC_ASCII
);
239 version_item
= proto_tree_add_item(contact_tree
, hf_mojito_contactversion
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
240 version_tree
= proto_item_add_subtree(version_item
, ett_mojito_contact_version
);
241 proto_tree_add_item(version_tree
, hf_mojito_mjrversion
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
243 proto_tree_add_item(version_tree
, hf_mojito_mnrversion
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
246 proto_tree_add_item(contact_tree
, hf_mojito_contactkuid
, tvb
, offset
, 20, ENC_NA
);
249 offset
= dissect_mojito_address(tvb
, pinfo
, contact_tree
, offset
, "Socket Address");
256 proto_item_set_len(contact_item
, offset
- offset_start
);
258 return offset
- offset_start
;
262 dissect_mojito_header(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
263 int offset
, mojito_header_data_t
* header_data
)
265 proto_tree
*header_tree
, *version_tree
, *contact_tree
, *flag_tree
;
266 proto_item
*header_item
, *contact_item
, *flag_item
;
267 int start_offset
= offset
;
268 int contact_start_offset
;
270 header_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, 61, ett_mojito_header
, &header_item
, "Gnutella Header");
272 proto_tree_add_item(header_tree
, hf_mojito_messageid
, tvb
, offset
, 16, ENC_NA
);
275 proto_tree_add_item(header_tree
, hf_mojito_fdhtmessage
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
278 version_tree
= proto_tree_add_subtree(header_tree
, tvb
, offset
, 2, ett_mojito_header_version
, NULL
, "Version");
280 proto_tree_add_item(version_tree
, hf_mojito_mjrversion
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
282 proto_tree_add_item(version_tree
, hf_mojito_mnrversion
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
285 /* Payload Length : in Little Endian */
286 header_data
->payloadlength
= tvb_get_letohl(tvb
, offset
);
287 proto_tree_add_item(header_tree
, hf_mojito_length
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
290 header_data
->opcode
= tvb_get_uint8(tvb
, offset
);
291 col_set_str(pinfo
->cinfo
, COL_INFO
, val_to_str_const(header_data
->opcode
, opcodeflags
, "Unknown"));
292 proto_tree_add_item(header_tree
, hf_mojito_opcode
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
295 contact_start_offset
= offset
;
296 contact_tree
= proto_tree_add_subtree(header_tree
, tvb
, offset
, 35, ett_mojito_contact
, &contact_item
, "Originating Contact");
298 proto_tree_add_item(contact_tree
, hf_mojito_vendor
, tvb
, offset
, 4, ENC_ASCII
);
301 version_tree
= proto_tree_add_subtree(contact_tree
, tvb
, offset
, 2, ett_mojito_contact_version
, NULL
, "Contact Version");
303 proto_tree_add_item(version_tree
, hf_mojito_origmjrversion
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
305 proto_tree_add_item(version_tree
, hf_mojito_origmnrversion
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
308 proto_tree_add_item(contact_tree
, hf_mojito_kuid
, tvb
, offset
, 20, ENC_NA
);
311 offset
= dissect_mojito_address(tvb
, pinfo
, contact_tree
, offset
, "Socket Address");
318 proto_item_set_len(contact_item
, offset
- contact_start_offset
);
320 proto_tree_add_item(header_tree
, hf_mojito_instanceid
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
324 flag_item
= proto_tree_add_item(header_tree
, hf_mojito_flags
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
325 flag_tree
= proto_item_add_subtree(flag_item
, ett_mojito_flags
);
326 proto_tree_add_item(flag_tree
, hf_mojito_flags_shutdown
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
327 proto_tree_add_item(flag_tree
, hf_mojito_flags_firewalled
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
330 proto_tree_add_item(header_tree
, hf_mojito_extendedlength
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
333 proto_item_set_len(header_item
, offset
-start_offset
);
338 dissect_mojito_ping_response(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
341 proto_tree
*bigint_tree
;
342 proto_item
*bigint_item
;
344 offset
= dissect_mojito_address(tvb
, pinfo
, tree
,
345 offset
, "Requester's External Socket Address");
353 bigintlen
= tvb_get_uint8(tvb
, offset
);
354 bigint_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, bigintlen
+ 1, ett_mojito_bigint
, &bigint_item
, "Estimated DHT size");
356 proto_tree_add_item(bigint_tree
, hf_mojito_bigintegerlen
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
362 proto_tree_add_item(bigint_tree
, hf_mojito_bigint_value_one
, tvb
, offset
, bigintlen
, ENC_BIG_ENDIAN
);
366 proto_tree_add_item(bigint_tree
, hf_mojito_bigint_value_two
, tvb
, offset
, bigintlen
, ENC_BIG_ENDIAN
);
370 proto_tree_add_item(bigint_tree
, hf_mojito_bigint_value_three
, tvb
, offset
, bigintlen
, ENC_BIG_ENDIAN
);
374 proto_tree_add_item(bigint_tree
, hf_mojito_bigint_value_four
, tvb
, offset
, bigintlen
, ENC_BIG_ENDIAN
);
377 expert_add_info(pinfo
, bigint_item
, &ei_mojito_bigint_unsupported
);
382 proto_tree_add_item(bigint_tree
, hf_mojito_bigintegerval
, tvb
, offset
, bigintlen
, ENC_NA
);
386 dissect_mojito_store_request(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
388 proto_tree
*dht_tree
, *version_tree
;
389 proto_item
*dht_item
, *version_item
;
390 uint8_t ii
, contactcount
;
391 uint8_t sectokenlen
= tvb_get_uint8(tvb
, offset
);
392 uint16_t dhtvaluelength
;
393 int contact_offset
, start_offset
;
395 proto_tree_add_item(tree
, hf_mojito_sectokenlen
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
398 proto_tree_add_item(tree
, hf_mojito_sectoken
, tvb
, offset
, sectokenlen
, ENC_NA
);
399 offset
+= sectokenlen
;
402 proto_tree_add_item(tree
, hf_mojito_dhtvaluecount
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
403 contactcount
= tvb_get_uint8(tvb
, offset
);
406 /* For each Contact, display the info */
407 for (ii
= 0; ii
< contactcount
; ii
++)
409 dht_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
, 1, ett_mojito_dht
, &dht_item
, "DHTValue #%d", ii
+1);
410 start_offset
= offset
;
411 contact_offset
= dissect_mojito_contact(tvb
, pinfo
, dht_tree
, offset
, -1);
412 if (contact_offset
== 0)
414 offset
+= contact_offset
;
416 proto_tree_add_item(dht_tree
, hf_mojito_dhtvalue_kuid
, tvb
, offset
, 20, ENC_NA
);
419 proto_tree_add_item(dht_tree
, hf_mojito_dhtvalue_valuetype
, tvb
, offset
, 4, ENC_ASCII
);
423 version_item
= proto_tree_add_item(dht_tree
, hf_mojito_dhtvalue_version
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
424 version_tree
= proto_item_add_subtree(version_item
, ett_mojito_dht_version
);
426 proto_tree_add_item(version_tree
, hf_mojito_mjrversion
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
428 proto_tree_add_item(version_tree
, hf_mojito_mnrversion
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
431 dhtvaluelength
= tvb_get_ntohs(tvb
, offset
);
432 proto_tree_add_item(dht_tree
, hf_mojito_dhtvalue_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
435 proto_tree_add_item(dht_tree
, hf_mojito_dhtvalue_value
, tvb
, offset
, dhtvaluelength
, ENC_ASCII
);
436 offset
+= dhtvaluelength
;
438 proto_item_set_len(dht_item
, offset
-start_offset
);
443 dissect_mojito_store_response(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
447 uint8_t ii
, contactcount
= tvb_get_uint8(tvb
, offset
);
448 uint16_t dhtvaluelength
;
451 proto_tree_add_item(tree
, hf_mojito_storestatuscode_count
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
454 /* For each Contact, display the info */
455 for (ii
= 0; ii
< contactcount
; ii
++)
457 sc_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
, 23, ett_mojito_status_code
, &sc_item
, "Status Code %d", ii
+1);
459 start_offset
= offset
;
462 proto_tree_add_item(sc_tree
, hf_mojito_storestatuscode_kuid
, tvb
, offset
, 20, ENC_NA
);
465 if (tvb_reported_length_remaining(tvb
, offset
+3) > 0)
467 /* Must be a secondary KUID */
468 proto_tree_add_item(sc_tree
, hf_mojito_storestatuscode_secondary_kuid
, tvb
, offset
, 20, ENC_NA
);
472 proto_tree_add_item(sc_tree
, hf_mojito_storestatuscode_code
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
475 dhtvaluelength
= tvb_get_ntohs(tvb
, offset
);
476 proto_tree_add_item(sc_tree
, hf_mojito_dhtvalue_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
479 proto_tree_add_item(sc_tree
, hf_mojito_dhtvalue_value
, tvb
, offset
, dhtvaluelength
, ENC_ASCII
);
480 offset
+= dhtvaluelength
;
482 proto_item_set_len(sc_item
, offset
-start_offset
);
487 dissect_mojito_find_node_response(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
489 uint8_t ii
, contactcount
;
490 uint8_t sectokenlen
= tvb_get_uint8(tvb
, offset
);
493 proto_tree_add_item(tree
, hf_mojito_sectokenlen
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
496 proto_tree_add_item(tree
, hf_mojito_sectoken
, tvb
, offset
, sectokenlen
, ENC_NA
);
497 offset
+= sectokenlen
;
499 contactcount
= tvb_get_uint8(tvb
, offset
);
500 proto_tree_add_item(tree
, hf_mojito_contactcount
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
503 /* For each Contact, display the info */
504 for (ii
= 0; ii
< contactcount
; ii
++)
506 contact_offset
= dissect_mojito_contact(tvb
, pinfo
, tree
, offset
, ii
+1);
507 if (contact_offset
== 0)
509 offset
+= contact_offset
;
514 dissect_mojito_find_value_request(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
516 proto_tree
*kuid_tree
;
517 uint8_t i
, kuidcount
;
522 proto_tree_add_item(tree
, hf_mojito_target_kuid
, tvb
, offset
, 20, ENC_NA
);
525 kuidcount
= tvb_get_uint8(tvb
, offset
);
527 kuid_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, (20 * kuidcount
) + 1, ett_mojito_kuids
, NULL
, "Secondary KUID\'s");
529 proto_tree_add_item(kuid_tree
, hf_mojito_kuidcount
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
532 /* All the Secondary KUID's */
533 for (i
= 0; i
< kuidcount
; i
++)
535 proto_tree_add_item(kuid_tree
, hf_mojito_kuid
, tvb
, offset
, 20, ENC_NA
);
539 proto_tree_add_item(tree
, hf_mojito_dhtvaluetype
, tvb
, offset
, 4, ENC_ASCII
);
544 dissect_mojito_find_value_response(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
546 proto_tree
*dht_tree
, *version_tree
, *kuid_tree
;
547 proto_item
*dht_item
, *version_item
;
548 uint16_t dhtvaluelength
;
549 int contact_offset
, start_offset
;
550 uint8_t ii
, dhtvaluescount
, kuidcount
;
552 proto_tree_add_item(tree
, hf_mojito_requestload
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
555 dhtvaluescount
= tvb_get_uint8(tvb
, offset
);
556 proto_tree_add_item(tree
, hf_mojito_dhtvaluecount
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
559 /* For each Contact, display the info */
560 for (ii
= 0; ii
< dhtvaluescount
; ii
++)
562 dht_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
, 1, ett_mojito_dht
, &dht_item
, "DHTValue #%d", ii
+1);
563 start_offset
= offset
;
564 contact_offset
= dissect_mojito_contact(tvb
, pinfo
, dht_tree
, offset
, -1);
565 if (contact_offset
== 0)
568 offset
+= contact_offset
;
570 proto_tree_add_item(dht_tree
, hf_mojito_dhtvalue_kuid
, tvb
, offset
, 20, ENC_NA
);
573 proto_tree_add_item(dht_tree
, hf_mojito_dhtvalue_valuetype
, tvb
, offset
, 4, ENC_ASCII
);
577 version_item
= proto_tree_add_item(dht_tree
, hf_mojito_dhtvalue_version
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
578 version_tree
= proto_item_add_subtree(version_item
, ett_mojito_dht_version
);
580 proto_tree_add_item(version_tree
, hf_mojito_mjrversion
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
582 proto_tree_add_item(version_tree
, hf_mojito_mnrversion
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
586 dhtvaluelength
= tvb_get_ntohs(tvb
, offset
);
587 proto_tree_add_item(dht_tree
, hf_mojito_dhtvalue_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
591 proto_tree_add_item(dht_tree
, hf_mojito_dhtvalue_value
, tvb
, offset
, dhtvaluelength
, ENC_ASCII
);
592 offset
+= dhtvaluelength
;
594 proto_item_set_len(dht_item
, offset
-start_offset
);
598 kuidcount
= tvb_get_uint8(tvb
, offset
);
599 kuid_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, (20 * kuidcount
) + 1, ett_mojito_kuids
, NULL
, "Secondary KUID\'s");
600 proto_tree_add_item(kuid_tree
, hf_mojito_kuidcount
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
603 /* All the Secondary KUID's */
604 for (ii
= 0; ii
< kuidcount
; ii
++)
606 proto_tree_add_item(kuid_tree
, hf_mojito_kuid
, tvb
, offset
, 20, ENC_NA
);
612 dissect_mojito(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
614 proto_tree
*mojito_tree
, *opcode_tree
;
616 mojito_header_data_t header_data
;
619 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "Mojito");
620 col_clear(pinfo
->cinfo
, COL_INFO
);
622 /* Add a new item to the tree */
623 ti
= proto_tree_add_item(tree
, proto_mojito
, tvb
, 0, -1, ENC_NA
);
624 mojito_tree
= proto_item_add_subtree(ti
, ett_mojito
);
626 offset
= dissect_mojito_header(tvb
, pinfo
, mojito_tree
, offset
, &header_data
);
627 if (offset
== 0) /* Some error occurred */
630 opcode_tree
= proto_tree_add_subtree_format(mojito_tree
, tvb
,
631 offset
, header_data
.payloadlength
- MOJITO_HEADER_LENGTH
,
632 ett_mojito_opcode
, NULL
, "Opcode specific data (%s)",
633 val_to_str_const(header_data
.opcode
, opcodeflags
, "Unknown"));
635 /* Now use the opcode to figure out what to do next */
636 switch (header_data
.opcode
)
638 case MOJITO_PING_RESPONSE
: /* PING RESPONSE */
639 dissect_mojito_ping_response(tvb
, pinfo
, opcode_tree
, offset
);
642 case MOJITO_STORE_REQUEST
: /* STORE REQUEST */
643 dissect_mojito_store_request(tvb
, pinfo
, opcode_tree
, offset
);
646 case MOJITO_STORE_RESPONSE
: /* STORE RESPONSE */
647 dissect_mojito_store_response(tvb
, pinfo
, opcode_tree
, offset
);
650 case MOJITO_FIND_NODE_REQUEST
: /* FIND NODE REQUEST */
651 proto_tree_add_item(opcode_tree
, hf_mojito_target_kuid
, tvb
, offset
, 20, ENC_NA
);
654 case MOJITO_FIND_NODE_RESPONSE
: /* FIND NODE RESPONSE */
655 dissect_mojito_find_node_response(tvb
, pinfo
, opcode_tree
, offset
);
658 case MOJITO_FIND_VALUE_REQUEST
: /* FIND VALUE REQUEST */
659 dissect_mojito_find_value_request(tvb
, pinfo
, opcode_tree
, offset
);
662 case MOJITO_FIND_VALUE_RESPONSE
: /* FIND VALUE RESPONSE */
663 dissect_mojito_find_value_response(tvb
, pinfo
, opcode_tree
, offset
);
666 case MOJITO_PING_REQUEST
: /* PING REQUEST */
667 case MOJITO_STATS_REQUEST_DEPRECATED
: /* STATS REQUEST (DEPRECATED) */
668 case MOJITO_STATS_RESPONSE_DEPRECATED
: /* STATS RESPONSE (DEPRECATED) */
670 if (header_data
.payloadlength
- MOJITO_HEADER_LENGTH
> 0)
671 proto_tree_add_item(opcode_tree
, hf_mojito_opcode_data
, tvb
,
672 offset
, header_data
.payloadlength
- MOJITO_HEADER_LENGTH
, ENC_NA
);
676 return tvb_captured_length(tvb
);
679 static bool dissect_mojito_heuristic (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
682 Test the overall length to make sure it's at least 61 bytes (the header)
683 Test to make sure that it's of type 44 (mojito)
684 Test to make sure that the length field is there and correct
685 (tvb_get_letohl(tvb, 20) + 23) == tvb_length(tvb)
687 if ((tvb_captured_length(tvb
) >= 60) &&
688 (tvb_get_uint8(tvb
, 16) == 68) &&
689 ((tvb_get_letohl(tvb
, 19) + 23) == tvb_reported_length(tvb
)))
691 dissect_mojito(tvb
, pinfo
, tree
, data
);
698 /* Register the mojito dissector */
700 proto_register_mojito(void)
702 expert_module_t
* expert_mojito
;
704 static hf_register_info hf
[] = {
705 { &hf_mojito_dhtvaluecount
,
706 { "DHTValue Count", "mojito.dhtvaluecount",
711 { &hf_mojito_messageid
,
712 { "Message ID", "mojito.messageid",
717 { &hf_mojito_requestload
,
718 { "Request Load", "mojito.requestload",
723 { &hf_mojito_fdhtmessage
,
724 { "FDHTMessage", "mojito.fdhtmessage",
729 { &hf_mojito_mjrversion
,
730 { "Major Version", "mojito.majorversion",
735 { &hf_mojito_mnrversion
,
736 { "Minor Version", "mojito.minorversion",
742 { "Payload Length", "mojito.payloadlength",
748 { "OPCode", "mojito.opcode",
750 VALS(opcodeflags
), 0x0,
754 { "Vendor", "mojito.vendor",
755 FT_STRING
, BASE_NONE
,
759 { &hf_mojito_origmjrversion
,
760 { "Major Version", "mojito.majorversion",
765 { &hf_mojito_origmnrversion
,
766 { "Minor Version", "mojito.minorversion",
772 { "Kademlia Unique ID (KUID)", "mojito.kuid",
777 { &hf_mojito_socketaddress_version
,
778 { "IP Version", "mojito.socketaddressversion",
783 { &hf_mojito_socketaddress_ipv4
,
784 { "IP Address", "mojito.socketaddressipv4",
789 { &hf_mojito_socketaddress_ipv6
,
790 { "IP Address", "mojito.socketaddressipv6",
795 { &hf_mojito_socketaddress_port
,
796 { "IP Port", "mojito.socketaddressport",
801 { &hf_mojito_instanceid
,
802 { "Instance ID", "mojito.instanceid",
808 { "Flags", "mojito.flags",
813 { &hf_mojito_flags_shutdown
,
814 { "SHUTDOWN", "mojito.shutdownflag",
819 { &hf_mojito_flags_firewalled
,
820 { "Firewalled", "mojito.firewalledflag",
825 { &hf_mojito_extendedlength
,
826 { "Extended Length", "mojito.extlength",
831 { &hf_mojito_kuidcount
,
832 { "Secondary KUID Count", "mojito.kuidcount",
837 { &hf_mojito_dhtvaluetype
,
838 { "DHT Value Type", "mojito.dhtvaluetype",
839 FT_STRING
, BASE_NONE
,
843 { &hf_mojito_bigintegerlen
,
844 { "Big Integer Length", "mojito.bigintegerlen",
849 { &hf_mojito_bigintegerval
,
850 { "Big Integer HEX Value", "mojito.bigintegerhexval",
855 { &hf_mojito_sectokenlen
,
856 { "Security Token Length", "mojito.sectokenlen",
861 { &hf_mojito_sectoken
,
862 { "Security Token", "mojito.sectoken",
867 { &hf_mojito_contactcount
,
868 { "Contact Count", "mojito.contactcount",
873 { &hf_mojito_contactvendor
,
874 { "Vendor", "mojito.contactvendor",
875 FT_STRING
, BASE_NONE
,
879 { &hf_mojito_contactversion
,
880 { "Contact Version", "mojito.contactversion",
885 { &hf_mojito_contactkuid
,
886 { "KUID of the Contact", "mojito.contactkuid",
891 { &hf_mojito_dhtvalue_valuetype
,
892 { "DHTValue ValueType", "mojito.dhtvaluevaluetype",
893 FT_STRING
, BASE_NONE
,
897 { &hf_mojito_dhtvalue_version
,
898 { "DHTValue Version", "mojito.dhtvalueversion",
903 { &hf_mojito_dhtvalue_length
,
904 { "DHTValue Length", "mojito.dhtvaluelength",
909 { &hf_mojito_dhtvalue_value
,
910 { "DHTValue", "mojito.dhtvaluehexvalue",
911 FT_STRING
, BASE_NONE
,
915 { &hf_mojito_bigint_value_one
,
916 { "Big Integer DEC Value", "mojito.bigintegerval",
921 { &hf_mojito_bigint_value_two
,
922 { "Big Integer DEC Value", "mojito.bigintegerval",
927 { &hf_mojito_bigint_value_three
,
928 { "Big Integer DEC Value", "mojito.bigintegerval",
933 { &hf_mojito_bigint_value_four
,
934 { "Big Integer DEC Value", "mojito.bigintegerval",
939 { &hf_mojito_dhtvalue_kuid
,
940 { "Kademlia Unique ID (KUID)", "mojito.kuid",
945 { &hf_mojito_target_kuid
,
946 { "Target Kademlia Unique ID (KUID)", "mojito.kuid",
951 { &hf_mojito_storestatuscode_count
,
952 { "Status Code Count", "mojito.statuscodecount",
957 { &hf_mojito_storestatuscode_code
,
958 { "StatusCode", "mojito.statuscodecode",
960 VALS(statuscodeflags
), 0x0,
963 { &hf_mojito_storestatuscode_kuid
,
964 { "Primary KUID of the Status Code", "mojito.statuscodekuid",
969 { &hf_mojito_storestatuscode_secondary_kuid
,
970 { "Secondary KUID of the Status Code", "mojito.statuscodesecondarykuid",
975 { &hf_mojito_opcode_data
,
976 { "Data", "mojito.opcode.data",
983 /* Setup protocol subtree array */
984 static int *ett
[] = {
987 &ett_mojito_header_version
,
989 &ett_mojito_contact_version
,
990 &ett_mojito_socket_address
,
994 &ett_mojito_dht_version
,
996 &ett_mojito_status_code
,
1000 static ei_register_info ei
[] = {
1001 { &ei_mojito_socketaddress_unknown
, { "mojito.socketaddress.unknown", PI_PROTOCOL
, PI_ERROR
, "Unsupported Socket Address Type", EXPFILL
}},
1002 { &ei_mojito_bigint_unsupported
, { "mojito.bigint.unsupported", PI_PROTOCOL
, PI_ERROR
, "Unsupported BigInt length", EXPFILL
}},
1005 proto_mojito
= proto_register_protocol("Mojito DHT", "Mojito", "mojito");
1007 proto_register_field_array(proto_mojito
, hf
, array_length(hf
));
1008 proto_register_subtree_array(ett
, array_length(ett
));
1009 expert_mojito
= expert_register_protocol(proto_mojito
);
1010 expert_register_field_array(expert_mojito
, ei
, array_length(ei
));
1012 mojito_handle
= register_dissector("mojito", dissect_mojito
, proto_mojito
);
1015 /* Control the handoff */
1017 proto_reg_handoff_mojito(void)
1019 heur_dissector_add("udp", dissect_mojito_heuristic
, "Mojito over UDP", "mojito_udp", proto_mojito
, HEURISTIC_ENABLE
);
1020 dissector_add_for_decode_as_with_preference("udp.port", mojito_handle
);
1024 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1029 * indent-tabs-mode: t
1032 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1033 * :indentSize=8:tabSize=8:noTabs=false: