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 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include <epan/packet.h>
29 #include <epan/prefs.h>
30 #include <epan/expert.h>
32 void proto_register_mojito(void);
33 void proto_reg_handoff_mojito(void);
35 #define MOJITO_HEADER_LENGTH 38
37 /* All the Defines for OpCodes */
38 #define MOJITO_PING_REQUEST 1
39 #define MOJITO_PING_RESPONSE 2
40 #define MOJITO_STORE_REQUEST 3
41 #define MOJITO_STORE_RESPONSE 4
42 #define MOJITO_FIND_NODE_REQUEST 5
43 #define MOJITO_FIND_NODE_RESPONSE 6
44 #define MOJITO_FIND_VALUE_REQUEST 7
45 #define MOJITO_FIND_VALUE_RESPONSE 8
46 #define MOJITO_STATS_REQUEST_DEPRECATED 9
47 #define MOJITO_STATS_RESPONSE_DEPRECATED 10
49 /* Initialize the protocol and registered fields */
50 static int proto_mojito = -1;
53 static int hf_mojito_messageid = -1;
54 static int hf_mojito_fdhtmessage = -1;
55 static int hf_mojito_mjrversion = -1;
56 static int hf_mojito_mnrversion = -1;
57 static int hf_mojito_length = -1;
58 static int hf_mojito_opcode = -1;
59 static int hf_mojito_vendor = -1;
60 static int hf_mojito_origmjrversion = -1;
61 static int hf_mojito_origmnrversion = -1;
62 static int hf_mojito_kuid = -1;
63 static int hf_mojito_socketaddress_version = -1;
64 static int hf_mojito_socketaddress_ipv4 = -1;
65 static int hf_mojito_socketaddress_ipv6 = -1;
66 static int hf_mojito_socketaddress_port = -1;
67 static int hf_mojito_instanceid = -1;
68 static int hf_mojito_flags = -1;
69 static int hf_mojito_flags_shutdown = -1;
70 static int hf_mojito_flags_firewalled = -1;
71 static int hf_mojito_extendedlength = -1;
72 static int hf_mojito_kuidcount = -1;
73 static int hf_mojito_bigintegerlen = -1;
74 static int hf_mojito_bigintegerval = -1;
75 static int hf_mojito_dhtvaluetype = -1;
76 static int hf_mojito_sectokenlen = -1;
77 static int hf_mojito_sectoken = -1;
78 static int hf_mojito_contactcount = -1;
79 static int hf_mojito_contactvendor = -1;
80 static int hf_mojito_contactversion = -1;
81 static int hf_mojito_contactkuid = -1;
82 static int hf_mojito_dhtvaluecount = -1;
83 static int hf_mojito_dhtvalue_kuid = -1;
84 static int hf_mojito_target_kuid = -1;
85 static int hf_mojito_dhtvalue_valuetype = -1;
86 static int hf_mojito_dhtvalue_version = -1;
87 static int hf_mojito_dhtvalue_length = -1;
88 static int hf_mojito_dhtvalue_value = -1;
89 static int hf_mojito_bigint_value_one = -1;
90 static int hf_mojito_bigint_value_two = -1;
91 static int hf_mojito_bigint_value_three = -1;
92 static int hf_mojito_bigint_value_four = -1;
93 static int hf_mojito_storestatuscode_count = -1;
94 static int hf_mojito_storestatuscode_code = -1;
95 static int hf_mojito_storestatuscode_kuid = -1;
96 static int hf_mojito_storestatuscode_secondary_kuid = -1;
97 static int hf_mojito_requestload = -1;
99 static int hf_mojito_startflag = -1;
100 static int hf_mojito_endflag = -1;
101 static int hf_mojito_priorityflag = -1;
103 static int hf_mojito_opcode_data = -1;
105 /* Initialize the subtree pointers */
106 static gint ett_mojito = -1;
107 static gint ett_mojito_header = -1;
108 static gint ett_mojito_header_version = -1;
109 static gint ett_mojito_contact = -1;
110 static gint ett_mojito_contact_version = -1;
111 static gint ett_mojito_socket_address = -1;
112 static gint ett_mojito_flags = -1;
113 static gint ett_mojito_bigint = -1;
114 static gint ett_mojito_opcode = -1;
115 static gint ett_mojito_dht_version = -1;
116 static gint ett_mojito_dht = -1;
117 static gint ett_mojito_status_code = -1;
118 static gint ett_mojito_kuids = -1;
120 static expert_field ei_mojito_socketaddress_unknown = EI_INIT;
121 static expert_field ei_mojito_bigint_unsupported = EI_INIT;
124 static int udp_mojito_port = 0;
126 typedef struct mojito_header_data {
128 guint32 payloadlength;
129 } mojito_header_data_t;
131 /* Values for OPCode Flags */
132 static const value_string opcodeflags[] = {
133 { MOJITO_PING_REQUEST, "PING REQUEST" },
134 { MOJITO_PING_RESPONSE, "PING RESPONSE" },
135 { MOJITO_STORE_REQUEST, "STORE REQUEST" },
136 { MOJITO_STORE_RESPONSE, "STORE RESPONSE" },
137 { MOJITO_FIND_NODE_REQUEST, "FIND NODE REQUEST" },
138 { MOJITO_FIND_NODE_RESPONSE, "FIND NODE RESPONSE" },
139 { MOJITO_FIND_VALUE_REQUEST, "FIND VALUE REQUEST" },
140 { MOJITO_FIND_VALUE_RESPONSE, "FIND VALUE RESPONSE" },
141 { MOJITO_STATS_REQUEST_DEPRECATED, "STATS REQUEST (DEPRECATED)" },
142 { MOJITO_STATS_RESPONSE_DEPRECATED, "STATS RESPONSE (DEPRECATED)" },
146 static const value_string statuscodeflags[] = {
153 static const value_string vendorcodeflags[] = {
154 { 0, "MESSAGES_SUPPORTED" },
156 { 5, "CRAWLER_PING" },
157 { 6, "CRAWLER_PONG" },
158 { 7, "UDP_CONNECT_BACK" },
159 { 8, "UDP_CONNECT_BACK_REDIR" },
160 { 9, "NGTH_MINUS_PAYLOAD" },
161 { 10, "CAPABILITIES" },
163 { 12, "REPLY_NUMBER" },
164 { 13, "OOB_PROXYING_CONTROL" },
165 { 14, "GIVE_STATS" },
166 { 15, "STATISTICS" },
169 { 21, "PUSH_PROXY_REQ" },
170 { 22, "PUSH_PROXY_ACK" },
171 { 23, "UDP_HEAD_PING" },
172 { 24, "UDP_HEAD_PONG" },
173 { 25, "HEADER_UPDATE" },
174 { 26, "UPDATE_REQ" },
175 { 27, "UPDATE_RESP" },
176 { 28, "CONTENT_REQ" },
177 { 29, "CONTENT_RESP" },
178 { 30, "INSPECTION_REQ" },
179 { 31, "INSPECTION_RESP" },
180 { 32, "ADVANCED_TOGGLE" },
181 { 33, "DHT_CONTACTS" },
188 dissect_mojito_address(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
189 int offset, const char *title)
192 guint8 socket_address_version;
193 proto_tree *socket_tree;
194 proto_item *socket_item;
196 offset_start = offset;
198 /* new subtree for socket address*/
199 socket_address_version = tvb_get_guint8(tvb, offset);
200 socket_item = proto_tree_add_text(tree, tvb, offset, 1, "%s", title);
201 socket_tree = proto_item_add_subtree(socket_item, ett_mojito_socket_address);
203 proto_tree_add_item(socket_tree, hf_mojito_socketaddress_version, tvb, offset, 1, ENC_NA);
206 switch (socket_address_version)
208 case FT_IPv4_LEN: /* IPv4 */
210 proto_tree_add_item(socket_tree, hf_mojito_socketaddress_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
214 case FT_IPv6_LEN: /* IPv6 */
216 proto_tree_add_item(socket_tree, hf_mojito_socketaddress_ipv6, tvb, offset, 16, ENC_NA);
221 expert_add_info(pinfo, socket_item, &ei_mojito_socketaddress_unknown);
225 proto_tree_add_item(socket_tree, hf_mojito_socketaddress_port, tvb, offset, 2, ENC_BIG_ENDIAN);
228 proto_item_set_len(socket_item, offset - offset_start);
234 dissect_mojito_contact(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int contact_id)
237 proto_tree *contact_tree, *version_tree;
238 proto_item *contact_item, *version_item;
240 offset_start = offset;
244 contact_item = proto_tree_add_text(tree, tvb, offset, 1, "Contact #%d", contact_id);
248 contact_item = proto_tree_add_text(tree, tvb, offset, 1, "Contact");
250 contact_tree = proto_item_add_subtree(contact_item, ett_mojito_contact);
252 proto_tree_add_item(contact_tree, hf_mojito_contactvendor, tvb, offset, 4, ENC_ASCII|ENC_NA);
255 version_item = proto_tree_add_item(contact_tree, hf_mojito_contactversion, tvb, offset, 2, ENC_BIG_ENDIAN);
256 version_tree = proto_item_add_subtree(version_item, ett_mojito_contact_version);
257 proto_tree_add_item(version_tree, hf_mojito_mjrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
259 proto_tree_add_item(version_tree, hf_mojito_mnrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
262 proto_tree_add_item(contact_tree, hf_mojito_contactkuid, tvb, offset, 20, ENC_NA);
265 offset = dissect_mojito_address(tvb, pinfo, contact_tree, offset, "Socket Address");
272 proto_item_set_len(contact_item, offset - offset_start);
274 return offset - offset_start;
278 dissect_mojito_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
279 int offset, mojito_header_data_t* header_data)
281 proto_tree *header_tree, *version_tree, *contact_tree, *flag_tree;
282 proto_item *header_item, *version_item, *contact_item, *flag_item;
283 int start_offset = offset;
284 int contact_start_offset;
286 header_item = proto_tree_add_text(tree, tvb, offset, 61, "Gnutella Header");
287 header_tree = proto_item_add_subtree(header_item, ett_mojito_header);
289 proto_tree_add_item(header_tree, hf_mojito_messageid, tvb, offset, 16, ENC_NA);
292 proto_tree_add_item(header_tree, hf_mojito_fdhtmessage, tvb, offset, 1, ENC_BIG_ENDIAN);
295 version_item = proto_tree_add_text(header_tree, tvb, offset, 2, "Version");
296 version_tree = proto_item_add_subtree(version_item, ett_mojito_header_version);
298 proto_tree_add_item(version_tree, hf_mojito_mjrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
300 proto_tree_add_item(version_tree, hf_mojito_mnrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
303 /* Payload Length : in Little Endian */
304 header_data->payloadlength = tvb_get_letohl(tvb, offset);
305 proto_tree_add_item(header_tree, hf_mojito_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
308 header_data->opcode = tvb_get_guint8(tvb, offset);
309 col_add_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str_const(header_data->opcode, opcodeflags, "Unknown"));
310 proto_tree_add_item(header_tree, hf_mojito_opcode, tvb, offset, 1, ENC_BIG_ENDIAN);
313 contact_start_offset = offset;
314 contact_item = proto_tree_add_text(header_tree, tvb, offset, 35, "Originating Contact");
315 contact_tree = proto_item_add_subtree(contact_item, ett_mojito_contact);
317 proto_tree_add_item(contact_tree, hf_mojito_vendor, tvb, offset, 4, ENC_ASCII|ENC_NA);
320 version_item = proto_tree_add_text(contact_tree, tvb, offset, 2, "Contact Version");
321 version_tree = proto_item_add_subtree(version_item, ett_mojito_contact_version);
323 proto_tree_add_item(version_tree, hf_mojito_origmjrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
325 proto_tree_add_item(version_tree, hf_mojito_origmnrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
328 proto_tree_add_item(contact_tree, hf_mojito_kuid, tvb, offset, 20, ENC_NA);
331 offset = dissect_mojito_address(tvb, pinfo, contact_tree, offset, "Socket Address");
338 proto_item_set_len(contact_item, offset - contact_start_offset);
340 proto_tree_add_item(header_tree, hf_mojito_instanceid, tvb, offset, 1, ENC_BIG_ENDIAN);
344 flag_item = proto_tree_add_item(header_tree, hf_mojito_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
345 flag_tree = proto_item_add_subtree(flag_item, ett_mojito_flags);
346 proto_tree_add_item(flag_tree, hf_mojito_flags_shutdown, tvb, offset, 1, ENC_BIG_ENDIAN);
347 proto_tree_add_item(flag_tree, hf_mojito_flags_firewalled, tvb, offset, 1, ENC_BIG_ENDIAN);
350 proto_tree_add_item(header_tree, hf_mojito_extendedlength, tvb, offset, 2, ENC_BIG_ENDIAN);
353 proto_item_set_len(header_item, offset-start_offset);
358 dissect_mojito_ping_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
361 proto_tree *bigint_tree;
362 proto_item *bigint_item;
364 offset = dissect_mojito_address(tvb, pinfo, tree,
365 offset, "Requester's External Socket Address");
373 bigintlen = tvb_get_guint8(tvb, offset);
374 bigint_item = proto_tree_add_text(tree, tvb, offset, bigintlen + 1 , "Estimated DHT size");
375 bigint_tree = proto_item_add_subtree(bigint_item, ett_mojito_bigint);
377 proto_tree_add_item(bigint_tree, hf_mojito_bigintegerlen, tvb, offset, 1, ENC_BIG_ENDIAN);
383 proto_tree_add_item(bigint_tree, hf_mojito_bigint_value_one, tvb, offset, bigintlen, ENC_BIG_ENDIAN);
387 proto_tree_add_item(bigint_tree, hf_mojito_bigint_value_two, tvb, offset, bigintlen, ENC_BIG_ENDIAN);
391 proto_tree_add_item(bigint_tree, hf_mojito_bigint_value_three, tvb, offset, bigintlen, ENC_BIG_ENDIAN);
395 proto_tree_add_item(bigint_tree, hf_mojito_bigint_value_four, tvb, offset, bigintlen, ENC_BIG_ENDIAN);
398 expert_add_info(pinfo, bigint_item, &ei_mojito_bigint_unsupported);
403 proto_tree_add_item(bigint_tree, hf_mojito_bigintegerval, tvb, offset, bigintlen, ENC_NA);
407 dissect_mojito_store_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
409 proto_tree *dht_tree, *version_tree;
410 proto_item *dht_item, *version_item;
411 guint8 ii, contactcount;
412 guint8 sectokenlen = tvb_get_guint8(tvb, offset);
413 guint16 dhtvaluelength;
414 int contact_offset, start_offset;
416 proto_tree_add_item(tree, hf_mojito_sectokenlen, tvb, offset, 1, ENC_BIG_ENDIAN);
419 proto_tree_add_item(tree, hf_mojito_sectoken, tvb, offset, sectokenlen, ENC_NA);
420 offset += sectokenlen;
423 proto_tree_add_item(tree, hf_mojito_dhtvaluecount, tvb, offset, 1, ENC_BIG_ENDIAN);
424 contactcount = tvb_get_guint8(tvb, offset);
427 /* For each Contact, display the info */
428 for (ii = 0; ii < contactcount; ii++)
430 dht_item = proto_tree_add_text(tree, tvb, offset, 1, "DHTValue #%d", ii+1);
431 dht_tree = proto_item_add_subtree(dht_item, ett_mojito_dht);
432 start_offset = offset;
433 contact_offset = dissect_mojito_contact(tvb, pinfo, dht_tree, offset, -1);
434 if (contact_offset == 0)
436 offset += contact_offset;
438 proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_kuid, tvb, offset, 20, ENC_NA);
441 proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_valuetype, tvb, offset, 4, ENC_ASCII|ENC_NA);
445 version_item = proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_version, tvb, offset, 2, ENC_BIG_ENDIAN);
446 version_tree = proto_item_add_subtree(version_item, ett_mojito_dht_version);
448 proto_tree_add_item(version_tree, hf_mojito_mjrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
450 proto_tree_add_item(version_tree, hf_mojito_mnrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
453 dhtvaluelength = tvb_get_ntohs(tvb, offset);
454 proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_length, tvb, offset, 2, ENC_BIG_ENDIAN);
457 proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_value, tvb, offset, dhtvaluelength, ENC_ASCII|ENC_NA);
458 offset += dhtvaluelength;
460 proto_item_set_len(dht_item, offset-start_offset);
465 dissect_mojito_store_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
469 guint8 ii, contactcount = tvb_get_guint8(tvb, offset);
470 guint16 dhtvaluelength;
473 proto_tree_add_item(tree, hf_mojito_storestatuscode_count, tvb, offset, 1, ENC_BIG_ENDIAN);
476 /* For each Contact, display the info */
477 for (ii = 0; ii < contactcount; ii++)
479 sc_item = proto_tree_add_text(tree, tvb, offset, 23, "Status Code %d", ii+1);
480 sc_tree = proto_item_add_subtree(sc_item, ett_mojito_status_code);
482 start_offset = offset;
485 proto_tree_add_item(sc_tree, hf_mojito_storestatuscode_kuid, tvb, offset, 20, ENC_NA);
488 if (tvb_reported_length_remaining(tvb, offset+3) > 0)
490 /* Must be a secondard KUID */
491 proto_tree_add_item(sc_tree, hf_mojito_storestatuscode_secondary_kuid, tvb, offset, 20, ENC_NA);
495 proto_tree_add_item(sc_tree, hf_mojito_storestatuscode_code, tvb, offset, 2, ENC_BIG_ENDIAN);
498 dhtvaluelength = tvb_get_ntohs(tvb, offset);
499 proto_tree_add_item(sc_tree, hf_mojito_dhtvalue_length, tvb, offset, 2, ENC_BIG_ENDIAN);
502 proto_tree_add_item(sc_tree, hf_mojito_dhtvalue_value, tvb, offset, dhtvaluelength, ENC_ASCII|ENC_NA);
503 offset += dhtvaluelength;
505 proto_item_set_len(sc_item, offset-start_offset);
510 dissect_mojito_find_node_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
512 guint8 ii, contactcount;
513 guint8 sectokenlen = tvb_get_guint8(tvb, offset);
516 proto_tree_add_item(tree, hf_mojito_sectokenlen, tvb, offset, 1, ENC_BIG_ENDIAN);
519 proto_tree_add_item(tree, hf_mojito_sectoken, tvb, offset, sectokenlen, ENC_NA);
520 offset += sectokenlen;
522 contactcount = tvb_get_guint8(tvb, offset);
523 proto_tree_add_item(tree, hf_mojito_contactcount, tvb, offset, 1, ENC_BIG_ENDIAN);
526 /* For each Contact, display the info */
527 for (ii = 0; ii < contactcount; ii++)
529 contact_offset = dissect_mojito_contact(tvb, pinfo, tree, offset, ii+1);
530 if (contact_offset == 0)
532 offset += contact_offset;
537 dissect_mojito_find_value_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
539 proto_tree *kuid_tree;
540 proto_item *kuid_item;
546 proto_tree_add_item(tree, hf_mojito_target_kuid, tvb, offset, 20, ENC_NA);
549 kuidcount = tvb_get_guint8(tvb, offset);
551 kuid_item = proto_tree_add_text(tree, tvb, offset, (20 * kuidcount) + 1 , "Secondary KUID\'s");
552 kuid_tree = proto_item_add_subtree(kuid_item, ett_mojito_kuids);
554 proto_tree_add_item(kuid_tree, hf_mojito_kuidcount, tvb, offset, 1, ENC_BIG_ENDIAN);
557 /* All the Secondary KUID's */
558 for (i = 0; i < kuidcount; i++)
560 proto_tree_add_item(kuid_tree, hf_mojito_kuid, tvb, offset, 20, ENC_NA);
564 proto_tree_add_item(tree, hf_mojito_dhtvaluetype, tvb, offset, 4, ENC_ASCII|ENC_NA);
569 dissect_mojito_find_value_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
571 proto_tree *dht_tree, *version_tree, *kuid_tree;
572 proto_item *dht_item, *version_item, *kuid_item;
573 guint16 dhtvaluelength;
574 int contact_offset, start_offset;
575 guint8 ii, dhtvaluescount, kuidcount;
577 proto_tree_add_item(tree, hf_mojito_requestload, tvb, offset, 4, ENC_BIG_ENDIAN);
580 dhtvaluescount = tvb_get_guint8(tvb, offset);
581 proto_tree_add_item(tree, hf_mojito_dhtvaluecount, tvb, offset, 1, ENC_BIG_ENDIAN);
584 /* For each Contact, display the info */
585 for (ii = 0; ii < dhtvaluescount; ii++)
587 dht_item = proto_tree_add_text(tree, tvb, offset, 1, "DHTValue #%d", ii+1);
588 dht_tree = proto_item_add_subtree(dht_item, ett_mojito_dht);
589 start_offset = offset;
590 contact_offset = dissect_mojito_contact(tvb, pinfo, dht_tree, offset, -1);
591 if (contact_offset == 0)
594 offset += contact_offset;
596 proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_kuid, tvb, offset, 20, ENC_NA);
599 proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_valuetype, tvb, offset, 4, ENC_ASCII|ENC_NA);
603 version_item = proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_version, tvb, offset, 2, ENC_BIG_ENDIAN);
604 version_tree = proto_item_add_subtree(version_item, ett_mojito_dht_version);
606 proto_tree_add_item(version_tree, hf_mojito_mjrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
608 proto_tree_add_item(version_tree, hf_mojito_mnrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
612 dhtvaluelength = tvb_get_ntohs(tvb, offset);
613 proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_length, tvb, offset, 2, ENC_BIG_ENDIAN);
617 proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_value, tvb, offset, dhtvaluelength, ENC_ASCII|ENC_NA);
618 offset += dhtvaluelength;
620 proto_item_set_len(dht_item, offset-start_offset);
624 kuidcount = tvb_get_guint8(tvb, offset);
625 kuid_item = proto_tree_add_text(tree, tvb, offset, (20 * kuidcount) + 1 , "Secondary KUID\'s");
626 kuid_tree = proto_item_add_subtree(kuid_item, ett_mojito_kuids);
627 proto_tree_add_item(kuid_tree, hf_mojito_kuidcount, tvb, offset, 1, ENC_BIG_ENDIAN);
630 /* All the Secondary KUID's */
631 for (ii = 0; ii < kuidcount; ii++)
633 proto_tree_add_item(kuid_tree, hf_mojito_kuid, tvb, offset, 20, ENC_NA);
639 dissect_mojito(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
641 proto_tree *mojito_tree, *opcode_tree;
642 proto_item *ti, *opcode_item;
643 mojito_header_data_t header_data;
646 col_set_str(pinfo->cinfo, COL_PROTOCOL, "Mojito");
647 col_clear(pinfo->cinfo, COL_INFO);
649 /* Add a new item to the tree */
650 ti = proto_tree_add_item(tree, proto_mojito, tvb, 0, -1, ENC_NA);
651 mojito_tree = proto_item_add_subtree(ti, ett_mojito);
653 offset = dissect_mojito_header(tvb, pinfo, mojito_tree, offset, &header_data);
654 if (offset == 0) /* Some error occurred */
657 opcode_item = proto_tree_add_text(mojito_tree, tvb,
658 offset, header_data.payloadlength - MOJITO_HEADER_LENGTH,
659 "Opcode specific data (%s)",
660 val_to_str_const(header_data.opcode, opcodeflags, "Unknown"));
661 opcode_tree = proto_item_add_subtree(opcode_item, ett_mojito_opcode);
663 /* Now use the opcode to figure out what to do next */
664 switch (header_data.opcode)
666 case MOJITO_PING_RESPONSE: /* PING RESPONSE */
667 dissect_mojito_ping_response(tvb, pinfo, opcode_tree, offset);
670 case MOJITO_STORE_REQUEST: /* STORE REQUEST */
671 dissect_mojito_store_request(tvb, pinfo, opcode_tree, offset);
674 case MOJITO_STORE_RESPONSE: /* STORE RESPONSE */
675 dissect_mojito_store_response(tvb, pinfo, opcode_tree, offset);
678 case MOJITO_FIND_NODE_REQUEST: /* FIND NODE REQUEST */
679 proto_tree_add_item(opcode_tree, hf_mojito_target_kuid, tvb, offset, 20, ENC_NA);
682 case MOJITO_FIND_NODE_RESPONSE: /* FIND NODE RESPONSE */
683 dissect_mojito_find_node_response(tvb, pinfo, opcode_tree, offset);
686 case MOJITO_FIND_VALUE_REQUEST: /* FIND VALUE REQUEST */
687 dissect_mojito_find_value_request(tvb, pinfo, opcode_tree, offset);
690 case MOJITO_FIND_VALUE_RESPONSE: /* FIND VALUE RESPONSE */
691 dissect_mojito_find_value_response(tvb, pinfo, opcode_tree, offset);
694 case MOJITO_PING_REQUEST: /* PING REQUEST */
695 case MOJITO_STATS_REQUEST_DEPRECATED: /* STATS REQUEST (DEPRECATED) */
696 case MOJITO_STATS_RESPONSE_DEPRECATED: /* STATS RESPONSE (DEPRECATED) */
698 if (header_data.payloadlength - MOJITO_HEADER_LENGTH > 0)
699 proto_tree_add_item(opcode_tree, hf_mojito_opcode_data, tvb,
700 offset, header_data.payloadlength - MOJITO_HEADER_LENGTH, ENC_NA);
704 return tvb_length(tvb);
707 static gboolean dissect_mojito_heuristic (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
710 Test the overall length to make sure it's at least 61 bytes (the header)
711 Test to make sure that it's of type 44 (mojito)
712 Test to make sure that the length field is there and correct
713 (tvb_get_letohl(tvb, 20) + 23) == tvb_length(tvb)
715 if ((tvb_length(tvb) >= 60) &&
716 (tvb_get_guint8(tvb, 16) == 68) &&
717 ((tvb_get_letohl(tvb, 19) + 23) == tvb_reported_length(tvb)))
719 dissect_mojito(tvb, pinfo, tree, NULL);
726 /* Register the mojito dissector */
728 proto_register_mojito(void)
730 module_t *mojito_module;
731 expert_module_t* expert_mojito;
733 static hf_register_info hf[] = {
734 { &hf_mojito_dhtvaluecount,
735 { "DHTValue Count", "mojito.dhtvaluecount",
740 { &hf_mojito_messageid,
741 { "Message ID", "mojito.messageid",
746 { &hf_mojito_requestload,
747 { "Request Load", "mojito.requestload",
752 { &hf_mojito_fdhtmessage,
753 { "FDHTMessage", "mojito.fdhtmessage",
758 { &hf_mojito_mjrversion,
759 { "Major Version", "mojito.majorversion",
764 { &hf_mojito_mnrversion,
765 { "Minor Version", "mojito.minorversion",
771 { "Payload Length", "mojito.payloadlength",
777 { "OPCode", "mojito.opcode",
779 VALS(opcodeflags), 0x0,
783 { "Vendor", "mojito.vendor",
784 FT_STRING, BASE_NONE,
788 { &hf_mojito_origmjrversion,
789 { "Major Version", "mojito.majorversion",
794 { &hf_mojito_origmnrversion,
795 { "Minor Version", "mojito.minorversion",
801 { "Kademlia Unique ID (KUID)", "mojito.kuid",
806 { &hf_mojito_socketaddress_version,
807 { "IP Version", "mojito.socketaddressversion",
812 { &hf_mojito_socketaddress_ipv4,
813 { "IP Address", "mojito.socketaddressipv4",
818 { &hf_mojito_socketaddress_ipv6,
819 { "IP Address", "mojito.socketaddressipv6",
824 { &hf_mojito_socketaddress_port,
825 { "IP Port", "mojito.socketaddressport",
830 { &hf_mojito_instanceid,
831 { "Instance ID", "mojito.instanceid",
837 { "Flags", "mojito.flags",
842 { &hf_mojito_flags_shutdown,
843 { "SHUTDOWN", "mojito.shutdownflag",
848 { &hf_mojito_flags_firewalled,
849 { "Firewalled", "mojito.firewalledflag",
854 { &hf_mojito_extendedlength,
855 { "Extended Length", "mojito.extlength",
860 { &hf_mojito_kuidcount,
861 { "Secondary KUID Count", "mojito.kuidcount",
866 { &hf_mojito_dhtvaluetype,
867 { "DHT Value Type", "mojito.dhtvaluetype",
868 FT_STRING, BASE_NONE,
872 { &hf_mojito_bigintegerlen,
873 { "Big Integer Length", "mojito.bigintegerlen",
878 { &hf_mojito_bigintegerval,
879 { "Big Integer HEX Value", "mojito.bigintegerhexval",
884 { &hf_mojito_sectokenlen,
885 { "Security Token Length", "mojito.sectokenlen",
890 { &hf_mojito_sectoken,
891 { "Security Token", "mojito.sectoken",
896 { &hf_mojito_contactcount,
897 { "Contact Count", "mojito.contactcount",
902 { &hf_mojito_contactvendor,
903 { "Vendor", "mojito.contactvendor",
904 FT_STRING, BASE_NONE,
908 { &hf_mojito_contactversion,
909 { "Contact Version", "mojito.contactversion",
914 { &hf_mojito_contactkuid,
915 { "KUID of the Contact", "mojito.contactkuid",
920 { &hf_mojito_dhtvalue_valuetype,
921 { "DHTValue ValueType", "mojito.dhtvaluevaluetype",
922 FT_STRING, BASE_NONE,
926 { &hf_mojito_dhtvalue_version,
927 { "DHTValue Version", "mojito.dhtvalueversion",
932 { &hf_mojito_dhtvalue_length,
933 { "DHTValue Length", "mojito.dhtvaluelength",
938 { &hf_mojito_dhtvalue_value,
939 { "DHTValue", "mojito.dhtvaluehexvalue",
940 FT_STRING, BASE_NONE,
944 { &hf_mojito_bigint_value_one,
945 { "Big Integer DEC Value", "mojito.bigintegerval",
950 { &hf_mojito_bigint_value_two,
951 { "Big Integer DEC Value", "mojito.bigintegerval",
956 { &hf_mojito_bigint_value_three,
957 { "Big Integer DEC Value", "mojito.bigintegerval",
962 { &hf_mojito_bigint_value_four,
963 { "Big Integer DEC Value", "mojito.bigintegerval",
968 { &hf_mojito_dhtvalue_kuid,
969 { "Kademlia Unique ID (KUID)", "mojito.kuid",
974 { &hf_mojito_target_kuid,
975 { "Target Kademlia Unique ID (KUID)", "mojito.kuid",
980 { &hf_mojito_storestatuscode_count,
981 { "Status Code Count", "mojito.statuscodecount",
986 { &hf_mojito_storestatuscode_code,
987 { "StatusCode", "mojito.statuscodecount",
989 VALS(statuscodeflags), 0x0,
992 { &hf_mojito_storestatuscode_kuid,
993 { "Primary KUID of the Status Code", "mojito.statuscodekuid",
998 { &hf_mojito_storestatuscode_secondary_kuid,
999 { "Secondary KUID of the Status Code", "mojito.statuscodesecondarykuid",
1000 FT_BYTES, BASE_NONE,
1004 { &hf_mojito_opcode_data,
1005 { "Data", "mojito.opcode.data",
1006 FT_BYTES, BASE_NONE,
1012 /* Setup protocol subtree array */
1013 static gint *ett[] = {
1016 &ett_mojito_header_version,
1017 &ett_mojito_contact,
1018 &ett_mojito_contact_version,
1019 &ett_mojito_socket_address,
1023 &ett_mojito_dht_version,
1025 &ett_mojito_status_code,
1029 static ei_register_info ei[] = {
1030 { &ei_mojito_socketaddress_unknown, { "mojito.socketaddress.unknown", PI_PROTOCOL, PI_ERROR, "Unsupported Socket Address Type", EXPFILL }},
1031 { &ei_mojito_bigint_unsupported, { "mojito.bigint.unsupported", PI_PROTOCOL, PI_ERROR, "Unsupported BigInt length", EXPFILL }},
1034 proto_mojito = proto_register_protocol("Mojito DHT", "Mojito", "mojito");
1036 proto_register_field_array(proto_mojito, hf, array_length(hf));
1037 proto_register_subtree_array(ett, array_length(ett));
1038 expert_mojito = expert_register_protocol(proto_mojito);
1039 expert_register_field_array(expert_mojito, ei, array_length(ei));
1042 mojito_module = prefs_register_protocol(proto_mojito, NULL);
1044 prefs_register_uint_preference(mojito_module,
1052 /* Control the handoff */
1054 proto_reg_handoff_mojito(void)
1056 static gboolean initialized = FALSE;
1057 static int old_mojito_udp_port = 0;
1058 static dissector_handle_t mojito_handle;
1061 mojito_handle = new_create_dissector_handle(dissect_mojito, proto_mojito);
1062 heur_dissector_add("udp", dissect_mojito_heuristic, proto_mojito);
1066 /* Register UDP port for dissection */
1067 if(old_mojito_udp_port != 0 && old_mojito_udp_port != udp_mojito_port){
1068 dissector_delete_uint("udp.port", old_mojito_udp_port, mojito_handle);
1071 if(udp_mojito_port != 0 && old_mojito_udp_port != udp_mojito_port) {
1072 dissector_add_uint("udp.port", udp_mojito_port, mojito_handle);
1075 old_mojito_udp_port = udp_mojito_port;
1079 * Editor modelines - http://www.wireshark.org/tools/modelines.html
1084 * indent-tabs-mode: t
1087 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1088 * :indentSize=8:tabSize=8:noTabs=false: