MSWSP: fix dissect_mswsp_smb()
[wireshark-wip.git] / epan / dissectors / packet-mojito.c
blob48199ae30ad7bd2d34423384d55b1cfd7aa73823
1 /* packet-mojito.c
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 * $Id$
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.
28 #include "config.h"
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;
51 /* Start of fields */
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;
97 #if 0
98 static int hf_mojito_startflag = -1;
99 static int hf_mojito_endflag = -1;
100 static int hf_mojito_priorityflag = -1;
101 #endif
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;
122 /* Preferences */
123 static int udp_mojito_port = 0;
125 typedef struct mojito_header_data {
126 guint8 opcode;
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)" },
142 { 0, NULL }
145 static const value_string statuscodeflags[] = {
146 { 1, "OK" },
147 { 2, "Error" },
148 { 0, NULL }
151 #if 0
152 static const value_string vendorcodeflags[] = {
153 { 0, "MESSAGES_SUPPORTED" },
154 { 4, "HOPS_FLOW" },
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" },
161 { 11, "LIME_ACK" },
162 { 12, "REPLY_NUMBER" },
163 { 13, "OOB_PROXYING_CONTROL" },
164 { 14, "GIVE_STATS" },
165 { 15, "STATISTICS" },
166 { 16, "SIMPP_REQ" },
167 { 17, "SIMPP" },
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" },
182 { 0, NULL }
184 #endif
186 static int
187 dissect_mojito_address(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
188 int offset, const char *title)
190 int offset_start;
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);
203 offset += 1;
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);
210 offset += 4;
211 break;
213 case FT_IPv6_LEN: /* IPv6 */
215 proto_tree_add_item(socket_tree, hf_mojito_socketaddress_ipv6, tvb, offset, 16, ENC_NA);
216 offset += 16;
217 break;
219 default: /* ABORT */
220 expert_add_info(pinfo, socket_item, &ei_mojito_socketaddress_unknown);
221 return 0;
224 proto_tree_add_item(socket_tree, hf_mojito_socketaddress_port, tvb, offset, 2, ENC_BIG_ENDIAN);
225 offset += 2;
227 proto_item_set_len(socket_item, offset - offset_start);
229 return offset;
232 static int
233 dissect_mojito_contact(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int contact_id)
235 int offset_start;
236 proto_tree *contact_tree, *version_tree;
237 proto_item *contact_item, *version_item;
239 offset_start = offset;
241 if (contact_id > 0)
243 contact_item = proto_tree_add_text(tree, tvb, offset, 1, "Contact #%d", contact_id);
245 else
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);
252 offset += 4;
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);
257 offset += 1;
258 proto_tree_add_item(version_tree, hf_mojito_mnrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
259 offset += 1;
261 proto_tree_add_item(contact_tree, hf_mojito_contactkuid, tvb, offset, 20, ENC_NA);
262 offset += 20;
264 offset = dissect_mojito_address(tvb, pinfo, contact_tree, offset, "Socket Address");
266 if (offset == 0)
268 return 0;
271 proto_item_set_len(contact_item, offset - offset_start);
273 return offset - offset_start;
276 static int
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);
289 offset += 16;
291 proto_tree_add_item(header_tree, hf_mojito_fdhtmessage, tvb, offset, 1, ENC_BIG_ENDIAN);
292 offset += 1;
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);
298 offset += 1;
299 proto_tree_add_item(version_tree, hf_mojito_mnrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
300 offset += 1;
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);
305 offset += 4;
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);
310 offset += 1;
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);
317 offset += 4;
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);
323 offset += 1;
324 proto_tree_add_item(version_tree, hf_mojito_origmnrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
325 offset += 1;
327 proto_tree_add_item(contact_tree, hf_mojito_kuid, tvb, offset, 20, ENC_NA);
328 offset += 20;
330 offset = dissect_mojito_address(tvb, pinfo, contact_tree, offset, "Socket Address");
332 if (offset == 0)
334 return 0;
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);
340 offset += 1;
342 /*Flags*/
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);
347 offset += 1;
349 proto_tree_add_item(header_tree, hf_mojito_extendedlength, tvb, offset, 2, ENC_BIG_ENDIAN);
350 offset += 2;
352 proto_item_set_len(header_item, offset-start_offset);
353 return offset;
356 static void
357 dissect_mojito_ping_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
359 guint8 bigintlen;
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");
366 if (offset == 0)
368 return;
371 /* BigInt subtree */
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);
377 offset += 1;
379 switch (bigintlen)
381 case 1: /* 1 byte */
382 proto_tree_add_item(bigint_tree, hf_mojito_bigint_value_one, tvb, offset, bigintlen, ENC_BIG_ENDIAN);
383 break;
385 case 2: /* 2 byte */
386 proto_tree_add_item(bigint_tree, hf_mojito_bigint_value_two, tvb, offset, bigintlen, ENC_BIG_ENDIAN);
387 break;
389 case 3: /* 3 byte */
390 proto_tree_add_item(bigint_tree, hf_mojito_bigint_value_three, tvb, offset, bigintlen, ENC_BIG_ENDIAN);
391 break;
393 case 4: /* 4 byte */
394 proto_tree_add_item(bigint_tree, hf_mojito_bigint_value_four, tvb, offset, bigintlen, ENC_BIG_ENDIAN);
395 break;
396 default: /* ABORT */
397 expert_add_info(pinfo, bigint_item, &ei_mojito_bigint_unsupported);
398 return;
401 /* BigInt Value */
402 proto_tree_add_item(bigint_tree, hf_mojito_bigintegerval, tvb, offset, bigintlen, ENC_NA);
405 static void
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);
416 offset += 1;
418 proto_tree_add_item(tree, hf_mojito_sectoken, tvb, offset, sectokenlen, ENC_NA);
419 offset += sectokenlen;
421 /* Contact count */
422 proto_tree_add_item(tree, hf_mojito_dhtvaluecount, tvb, offset, 1, ENC_BIG_ENDIAN);
423 contactcount = tvb_get_guint8(tvb, offset);
424 offset += 1;
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)
434 return;
435 offset += contact_offset;
437 proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_kuid, tvb, offset, 20, ENC_NA);
438 offset += 20;
440 proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_valuetype, tvb, offset, 4, ENC_ASCII|ENC_NA);
441 offset += 4;
443 /* Version */
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);
448 offset += 1;
449 proto_tree_add_item(version_tree, hf_mojito_mnrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
450 offset += 1;
452 dhtvaluelength = tvb_get_ntohs(tvb, offset);
453 proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_length, tvb, offset, 2, ENC_BIG_ENDIAN);
454 offset += 2;
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);
463 static void
464 dissect_mojito_store_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
466 proto_tree *sc_tree;
467 proto_item *sc_item;
468 guint8 ii, contactcount = tvb_get_guint8(tvb, offset);
469 guint16 dhtvaluelength;
470 int start_offset;
472 proto_tree_add_item(tree, hf_mojito_storestatuscode_count, tvb, offset, 1, ENC_BIG_ENDIAN);
473 offset += 1;
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;
483 /*Primary KUID */
484 proto_tree_add_item(sc_tree, hf_mojito_storestatuscode_kuid, tvb, offset, 20, ENC_NA);
485 offset += 20;
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);
491 offset += 20;
494 proto_tree_add_item(sc_tree, hf_mojito_storestatuscode_code, tvb, offset, 2, ENC_BIG_ENDIAN);
495 offset += 2;
497 dhtvaluelength = tvb_get_ntohs(tvb, offset);
498 proto_tree_add_item(sc_tree, hf_mojito_dhtvalue_length, tvb, offset, 2, ENC_BIG_ENDIAN);
499 offset += 2;
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);
508 static void
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);
513 int contact_offset;
515 proto_tree_add_item(tree, hf_mojito_sectokenlen, tvb, offset, 1, ENC_BIG_ENDIAN);
516 offset += 1;
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);
523 offset += 1;
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)
530 return;
531 offset += contact_offset;
535 static void
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;
540 guint8 i, kuidcount;
542 if (!tree)
543 return;
545 proto_tree_add_item(tree, hf_mojito_target_kuid, tvb, offset, 20, ENC_NA);
546 offset += 20;
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);
554 offset += 1;
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);
560 offset += 20;
563 proto_tree_add_item(tree, hf_mojito_dhtvaluetype, tvb, offset, 4, ENC_ASCII|ENC_NA);
564 /*offset += 4;*/
567 static void
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);
577 offset += 4;
579 dhtvaluescount = tvb_get_guint8(tvb, offset);
580 proto_tree_add_item(tree, hf_mojito_dhtvaluecount, tvb, offset, 1, ENC_BIG_ENDIAN);
581 offset += 1;
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)
591 return;
593 offset += contact_offset;
595 proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_kuid, tvb, offset, 20, ENC_NA);
596 offset += 20;
598 proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_valuetype, tvb, offset, 4, ENC_ASCII|ENC_NA);
599 offset += 4;
601 /* Version */
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);
606 offset += 1;
607 proto_tree_add_item(version_tree, hf_mojito_mnrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
608 offset += 1;
610 /* Length */
611 dhtvaluelength = tvb_get_ntohs(tvb, offset);
612 proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_length, tvb, offset, 2, ENC_BIG_ENDIAN);
613 offset += 2;
615 /* Value */
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);
622 /*KUID Count */
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);
627 offset += 1;
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);
633 offset += 20;
637 static int
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;
643 gint offset = 0;
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 */
654 return 0;
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);
667 break;
669 case MOJITO_STORE_REQUEST: /* STORE REQUEST */
670 dissect_mojito_store_request(tvb, pinfo, opcode_tree, offset);
671 break;
673 case MOJITO_STORE_RESPONSE: /* STORE RESPONSE */
674 dissect_mojito_store_response(tvb, pinfo, opcode_tree, offset);
675 break;
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);
679 break;
681 case MOJITO_FIND_NODE_RESPONSE: /* FIND NODE RESPONSE */
682 dissect_mojito_find_node_response(tvb, pinfo, opcode_tree, offset);
683 break;
685 case MOJITO_FIND_VALUE_REQUEST: /* FIND VALUE REQUEST */
686 dissect_mojito_find_value_request(tvb, pinfo, opcode_tree, offset);
687 break;
689 case MOJITO_FIND_VALUE_RESPONSE: /* FIND VALUE RESPONSE */
690 dissect_mojito_find_value_response(tvb, pinfo, opcode_tree, offset);
691 break;
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) */
696 default:
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);
700 break;
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);
719 return TRUE;
722 return FALSE;
725 /* Register the mojito dissector */
726 void
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",
735 FT_UINT8, BASE_DEC,
736 NULL, 0x0,
737 NULL, HFILL }
739 { &hf_mojito_messageid,
740 { "Message ID", "mojito.messageid",
741 FT_BYTES, BASE_NONE,
742 NULL, 0x0,
743 NULL, HFILL }
745 { &hf_mojito_requestload,
746 { "Request Load", "mojito.requestload",
747 FT_UINT32, BASE_DEC,
748 NULL, 0x0,
749 NULL, HFILL }
751 { &hf_mojito_fdhtmessage,
752 { "FDHTMessage", "mojito.fdhtmessage",
753 FT_UINT8, BASE_HEX,
754 NULL, 0x0,
755 NULL, HFILL }
757 { &hf_mojito_mjrversion,
758 { "Major Version", "mojito.majorversion",
759 FT_UINT8, BASE_DEC,
760 NULL, 0x0,
761 NULL, HFILL }
763 { &hf_mojito_mnrversion,
764 { "Minor Version", "mojito.minorversion",
765 FT_UINT8, BASE_DEC,
766 NULL, 0x0,
767 NULL, HFILL }
769 { &hf_mojito_length,
770 { "Payload Length", "mojito.payloadlength",
771 FT_UINT32, BASE_DEC,
772 NULL, 0x0,
773 NULL, HFILL }
775 { &hf_mojito_opcode,
776 { "OPCode", "mojito.opcode",
777 FT_UINT8, BASE_DEC,
778 VALS(opcodeflags), 0x0,
779 NULL, HFILL }
781 { &hf_mojito_vendor,
782 { "Vendor", "mojito.vendor",
783 FT_STRING, BASE_NONE,
784 NULL, 0x0,
785 NULL, HFILL }
787 { &hf_mojito_origmjrversion,
788 { "Major Version", "mojito.majorversion",
789 FT_UINT8, BASE_DEC,
790 NULL, 0x0,
791 NULL, HFILL }
793 { &hf_mojito_origmnrversion,
794 { "Minor Version", "mojito.minorversion",
795 FT_UINT8, BASE_DEC,
796 NULL, 0x0,
797 NULL, HFILL }
799 { &hf_mojito_kuid,
800 { "Kademlia Unique ID (KUID)", "mojito.kuid",
801 FT_BYTES, BASE_NONE,
802 NULL, 0x0,
803 NULL, HFILL }
805 { &hf_mojito_socketaddress_version,
806 { "IP Version", "mojito.socketaddressversion",
807 FT_UINT8, BASE_DEC,
808 NULL, 0x0,
809 NULL, HFILL }
811 { &hf_mojito_socketaddress_ipv4,
812 { "IP Address", "mojito.socketaddressipv4",
813 FT_IPv4, BASE_NONE,
814 NULL, 0x0,
815 NULL, HFILL }
817 { &hf_mojito_socketaddress_ipv6,
818 { "IP Address", "mojito.socketaddressipv6",
819 FT_IPv6, BASE_NONE,
820 NULL, 0x0,
821 NULL, HFILL }
823 { &hf_mojito_socketaddress_port,
824 { "IP Port", "mojito.socketaddressport",
825 FT_UINT16, BASE_DEC,
826 NULL, 0x0,
827 NULL, HFILL }
829 { &hf_mojito_instanceid,
830 { "Instance ID", "mojito.instanceid",
831 FT_UINT8, BASE_DEC,
832 NULL, 0x0,
833 NULL, HFILL }
835 { &hf_mojito_flags,
836 { "Flags", "mojito.flags",
837 FT_UINT8, BASE_HEX,
838 NULL, 0x0,
839 NULL, HFILL }
841 { &hf_mojito_flags_shutdown,
842 { "SHUTDOWN", "mojito.shutdownflag",
843 FT_BOOLEAN, 8,
844 NULL, 2,
845 NULL, HFILL }
847 { &hf_mojito_flags_firewalled,
848 { "Firewalled", "mojito.firewalledflag",
849 FT_BOOLEAN, 8,
850 NULL, 1,
851 NULL, HFILL }
853 { &hf_mojito_extendedlength,
854 { "Extended Length", "mojito.extlength",
855 FT_UINT16, BASE_DEC,
856 NULL, 0x0,
857 NULL, HFILL }
859 { &hf_mojito_kuidcount,
860 { "Secondary KUID Count", "mojito.kuidcount",
861 FT_UINT8, BASE_DEC,
862 NULL, 0x0,
863 NULL, HFILL }
865 { &hf_mojito_dhtvaluetype,
866 { "DHT Value Type", "mojito.dhtvaluetype",
867 FT_STRING, BASE_NONE,
868 NULL, 0x0,
869 NULL, HFILL }
871 { &hf_mojito_bigintegerlen,
872 { "Big Integer Length", "mojito.bigintegerlen",
873 FT_UINT8, BASE_DEC,
874 NULL, 0x0,
875 NULL, HFILL }
877 { &hf_mojito_bigintegerval,
878 { "Big Integer HEX Value", "mojito.bigintegerhexval",
879 FT_BYTES, BASE_NONE,
880 NULL, 0x0,
881 NULL, HFILL }
883 { &hf_mojito_sectokenlen,
884 { "Security Token Length", "mojito.sectokenlen",
885 FT_UINT8, BASE_DEC,
886 NULL, 0x0,
887 NULL, HFILL }
889 { &hf_mojito_sectoken,
890 { "Security Token", "mojito.sectoken",
891 FT_BYTES, BASE_NONE,
892 NULL, 0x0,
893 NULL, HFILL }
895 { &hf_mojito_contactcount,
896 { "Contact Count", "mojito.contactcount",
897 FT_UINT8, BASE_DEC,
898 NULL, 0x0,
899 NULL, HFILL }
901 { &hf_mojito_contactvendor,
902 { "Vendor", "mojito.contactvendor",
903 FT_STRING, BASE_NONE,
904 NULL, 0x0,
905 NULL, HFILL }
907 { &hf_mojito_contactversion,
908 { "Contact Version", "mojito.contactversion",
909 FT_UINT16, BASE_DEC,
910 NULL, 0x0,
911 NULL, HFILL }
913 { &hf_mojito_contactkuid,
914 { "KUID of the Contact", "mojito.contactkuid",
915 FT_BYTES, BASE_NONE,
916 NULL, 0x0,
917 NULL, HFILL }
919 { &hf_mojito_dhtvalue_valuetype,
920 { "DHTValue ValueType", "mojito.dhtvaluevaluetype",
921 FT_STRING, BASE_NONE,
922 NULL, 0x0,
923 NULL, HFILL }
925 { &hf_mojito_dhtvalue_version,
926 { "DHTValue Version", "mojito.dhtvalueversion",
927 FT_UINT16, BASE_DEC,
928 NULL, 0x0,
929 NULL, HFILL }
931 { &hf_mojito_dhtvalue_length,
932 { "DHTValue Length", "mojito.dhtvaluelength",
933 FT_UINT16, BASE_DEC,
934 NULL, 0x0,
935 NULL, HFILL }
937 { &hf_mojito_dhtvalue_value,
938 { "DHTValue", "mojito.dhtvaluehexvalue",
939 FT_STRING, BASE_NONE,
940 NULL, 0x0,
941 NULL, HFILL }
943 { &hf_mojito_bigint_value_one,
944 { "Big Integer DEC Value", "mojito.bigintegerval",
945 FT_UINT8, BASE_DEC,
946 NULL, 0x0,
947 NULL, HFILL }
949 { &hf_mojito_bigint_value_two,
950 { "Big Integer DEC Value", "mojito.bigintegerval",
951 FT_UINT16, BASE_DEC,
952 NULL, 0x0,
953 NULL, HFILL }
955 { &hf_mojito_bigint_value_three,
956 { "Big Integer DEC Value", "mojito.bigintegerval",
957 FT_UINT24, BASE_DEC,
958 NULL, 0x0,
959 NULL, HFILL }
961 { &hf_mojito_bigint_value_four,
962 { "Big Integer DEC Value", "mojito.bigintegerval",
963 FT_UINT32, BASE_DEC,
964 NULL, 0x0,
965 NULL, HFILL }
967 { &hf_mojito_dhtvalue_kuid,
968 { "Kademlia Unique ID (KUID)", "mojito.kuid",
969 FT_BYTES, BASE_NONE,
970 NULL, 0x0,
971 NULL, HFILL }
973 { &hf_mojito_target_kuid,
974 { "Target Kademlia Unique ID (KUID)", "mojito.kuid",
975 FT_BYTES, BASE_NONE,
976 NULL, 0x0,
977 NULL, HFILL }
979 { &hf_mojito_storestatuscode_count,
980 { "Status Code Count", "mojito.statuscodecount",
981 FT_UINT8, BASE_DEC,
982 NULL, 0x0,
983 NULL, HFILL }
985 { &hf_mojito_storestatuscode_code,
986 { "StatusCode", "mojito.statuscodecount",
987 FT_UINT16, BASE_DEC,
988 VALS(statuscodeflags), 0x0,
989 NULL, HFILL }
991 { &hf_mojito_storestatuscode_kuid,
992 { "Primary KUID of the Status Code", "mojito.statuscodekuid",
993 FT_BYTES, BASE_NONE,
994 NULL, 0x0,
995 NULL, HFILL }
997 { &hf_mojito_storestatuscode_secondary_kuid,
998 { "Secondary KUID of the Status Code", "mojito.statuscodesecondarykuid",
999 FT_BYTES, BASE_NONE,
1000 NULL, 0x0,
1001 NULL, HFILL }
1003 { &hf_mojito_opcode_data,
1004 { "Data", "mojito.opcode.data",
1005 FT_BYTES, BASE_NONE,
1006 NULL, 0x0,
1007 NULL, HFILL }
1011 /* Setup protocol subtree array */
1012 static gint *ett[] = {
1013 &ett_mojito,
1014 &ett_mojito_header,
1015 &ett_mojito_header_version,
1016 &ett_mojito_contact,
1017 &ett_mojito_contact_version,
1018 &ett_mojito_socket_address,
1019 &ett_mojito_flags,
1020 &ett_mojito_bigint,
1021 &ett_mojito_opcode,
1022 &ett_mojito_dht_version,
1023 &ett_mojito_dht,
1024 &ett_mojito_status_code,
1025 &ett_mojito_kuids
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));
1040 /* Set the Prefs */
1041 mojito_module = prefs_register_protocol(proto_mojito, NULL);
1043 prefs_register_uint_preference(mojito_module,
1044 "udp.port",
1045 "Mojito UDP Port",
1046 "Mojito UDP Port",
1048 &udp_mojito_port);
1051 /* Control the handoff */
1052 void
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;
1059 if (!initialized) {
1060 mojito_handle = new_create_dissector_handle(dissect_mojito, proto_mojito);
1061 heur_dissector_add("udp", dissect_mojito_heuristic, proto_mojito);
1062 initialized = TRUE;
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
1080 * Local variables:
1081 * c-basic-offset: 8
1082 * tab-width: 8
1083 * indent-tabs-mode: t
1084 * End:
1086 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1087 * :indentSize=8:tabSize=8:noTabs=false: