aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-mojito.c
diff options
context:
space:
mode:
authorBill Meier <wmeier@newsguy.com>2012-08-10 17:03:59 +0000
committerBill Meier <wmeier@newsguy.com>2012-08-10 17:03:59 +0000
commit2d81e31f186ac1f6c7d9c5da85e5b647a1f3a715 (patch)
tree02e29f123329be3826deb21e9ae917bdbcfb3d5f /epan/dissectors/packet-mojito.c
parent3cf2df1ef565fa9fbd15a7ff8fda055874cbb18d (diff)
General cleanup:
- Add svn:keywords and svn:eol-style properties; - col_...() and expert...() shouldn't be done under 'if (tree)'; - #if 0 an unused value-string; - Use val_to_str_const as appropriate; - Do some reformatting (whitespace changes). svn path=/trunk/; revision=44426
Diffstat (limited to 'epan/dissectors/packet-mojito.c')
-rw-r--r--epan/dissectors/packet-mojito.c2209
1 files changed, 1109 insertions, 1100 deletions
diff --git a/epan/dissectors/packet-mojito.c b/epan/dissectors/packet-mojito.c
index e750fdd98f..bf0820ec64 100644
--- a/epan/dissectors/packet-mojito.c
+++ b/epan/dissectors/packet-mojito.c
@@ -1,1100 +1,1109 @@
-/* packet-mojito.c
- * Routines for Dissecting the Gnutella Mojito DHT Protocol
- * http://limewire.negatis.com/index.php?title=Mojito_Message_Format
- *
- * Copyright (c) 2008 by Travis Dawson <travis.dawson@sprint.com>
- *
- * $Id: $
- *
- * Wireshark - Network traffic analyzer
- * By Gerald Combs <gerald@wireshark.org>
- * Copyright 1998 Gerald Combs
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <epan/packet.h>
-#include <epan/prefs.h>
-#include <epan/expert.h>
-
-#define MOJITO_HEADER_LENGTH 38
-
-/* All the Defines for OpCodes */
-#define PING_REQUEST 1
-#define PING_RESPONSE 2
-#define STORE_REQUEST 3
-#define STORE_RESPONSE 4
-#define FIND_NODE_REQUEST 5
-#define FIND_NODE_RESPONSE 6
-#define FIND_VALUE_REQUEST 7
-#define FIND_VALUE_RESPONSE 8
-#define STATS_REQUEST_DEPRECATED 9
-#define STATS_RESPONSE_DEPRECATED 10
-
-/* Initialize the protocol and registered fields */
-static int proto_mojito = -1;
-
-/* Start of fields */
-static int hf_mojito_messageid = -1;
-static int hf_mojito_fdhtmessage = -1;
-static int hf_mojito_mjrversion = -1;
-static int hf_mojito_mnrversion = -1;
-static int hf_mojito_length = -1;
-static int hf_mojito_opcode = -1;
-static int hf_mojito_vendor = -1;
-static int hf_mojito_origmjrversion = -1;
-static int hf_mojito_origmnrversion = -1;
-static int hf_mojito_kuid = -1;
-static int hf_mojito_socketaddress_version = -1;
-static int hf_mojito_socketaddress_ipv4 = -1;
-static int hf_mojito_socketaddress_ipv6 = -1;
-static int hf_mojito_socketaddress_port = -1;
-static int hf_mojito_instanceid = -1;
-static int hf_mojito_flags = -1;
-static int hf_mojito_flags_shutdown = -1;
-static int hf_mojito_flags_firewalled = -1;
-static int hf_mojito_extendedlength = -1;
-static int hf_mojito_kuidcount = -1;
-static int hf_mojito_bigintegerlen = -1;
-static int hf_mojito_bigintegerval = -1;
-static int hf_mojito_dhtvaluetype = -1;
-static int hf_mojito_sectokenlen = -1;
-static int hf_mojito_sectoken = -1;
-static int hf_mojito_contactcount = -1;
-static int hf_mojito_contactvendor = -1;
-static int hf_mojito_contactversion = -1;
-static int hf_mojito_contactkuid = -1;
-static int hf_mojito_dhtvaluecount = -1;
-static int hf_mojito_dhtvalue_kuid = -1;
-static int hf_mojito_target_kuid = -1;
-static int hf_mojito_dhtvalue_valuetype = -1;
-static int hf_mojito_dhtvalue_version = -1;
-static int hf_mojito_dhtvalue_length = -1;
-static int hf_mojito_dhtvalue_value = -1;
-static int hf_mojito_bigint_value_one = -1;
-static int hf_mojito_bigint_value_two = -1;
-static int hf_mojito_bigint_value_three = -1;
-static int hf_mojito_bigint_value_four = -1;
-static int hf_mojito_storestatuscode_count = -1;
-static int hf_mojito_storestatuscode_code = -1;
-static int hf_mojito_storestatuscode_kuid = -1;
-static int hf_mojito_storestatuscode_secondary_kuid = -1;
-static int hf_mojito_requestload = -1;
-#if 0
-static int hf_mojito_startflag = -1;
-static int hf_mojito_endflag = -1;
-static int hf_mojito_priorityflag = -1;
-#endif
-static int hf_mojito_opcode_data = -1;
-
-/* Initialize the subtree pointers */
-static gint ett_mojito = -1;
-static gint ett_mojito_header = -1;
-static gint ett_mojito_header_version = -1;
-static gint ett_mojito_contact = -1;
-static gint ett_mojito_contact_version = -1;
-static gint ett_mojito_socket_address = -1;
-static gint ett_mojito_flags = -1;
-static gint ett_mojito_ping_socket_address = -1;
-static gint ett_mojito_bigint = -1;
-static gint ett_mojito_opcode = -1;
-static gint ett_mojito_dht_version = -1;
-static gint ett_mojito_dht = -1;
-static gint ett_mojito_status_code = -1;
-static gint ett_mojito_kuids = -1;
-
-/* Preferences */
-static int udp_mojito_port = 0;
-
-typedef struct mojito_header_data {
- guint8 opcode;
- guint32 payloadlength;
-} mojito_header_data_t;
-
-/* Values for OPCode Flags */
-static const value_string opcodeflags[] = {
- { PING_REQUEST, "PING REQUEST" },
- { PING_RESPONSE, "PING RESPONSE" },
- { STORE_REQUEST, "STORE REQUEST" },
- { STORE_RESPONSE, "STORE RESPONSE" },
- { FIND_NODE_REQUEST, "FIND NODE REQUEST" },
- { FIND_NODE_RESPONSE, "FIND NODE RESPONSE" },
- { FIND_VALUE_REQUEST, "FIND VALUE REQUEST" },
- { FIND_VALUE_RESPONSE, "FIND VALUE RESPONSE" },
- { STATS_REQUEST_DEPRECATED, "STATS REQUEST (DEPRECATED)" },
- { STATS_RESPONSE_DEPRECATED, "STATS RESPONSE (DEPRECATED)" },
- { 0, NULL }
-};
-
-static const value_string statuscodeflags[] = {
- { 1, "OK" },
- { 2, "Error" },
- { 0, NULL }
-};
-
-static const value_string vendorcodeflags[] = {
- { 0, "MESSAGES_SUPPORTED" },
- { 4, "HOPS_FLOW" },
- { 5, "CRAWLER_PING" },
- { 6, "CRAWLER_PONG" },
- { 7, "UDP_CONNECT_BACK" },
- { 8, "UDP_CONNECT_BACK_REDIR" },
- { 9, "NGTH_MINUS_PAYLOAD" },
- { 10, "CAPABILITIES" },
- { 11, "LIME_ACK" },
- { 12, "REPLY_NUMBER" },
- { 13, "OOB_PROXYING_CONTROL" },
- { 14, "GIVE_STATS" },
- { 15, "STATISTICS" },
- { 16, "SIMPP_REQ" },
- { 17, "SIMPP" },
- { 21, "PUSH_PROXY_REQ" },
- { 22, "PUSH_PROXY_ACK" },
- { 23, "UDP_HEAD_PING" },
- { 24, "UDP_HEAD_PONG" },
- { 25, "HEADER_UPDATE" },
- { 26, "UPDATE_REQ" },
- { 27, "UPDATE_RESP" },
- { 28, "CONTENT_REQ" },
- { 29, "CONTENT_RESP" },
- { 30, "INSPECTION_REQ" },
- { 31, "INSPECTION_RESP" },
- { 32, "ADVANCED_TOGGLE" },
- { 33, "DHT_CONTACTS" },
-
- { 0, NULL }
-};
-
-static int
-dissect_mojito_contact(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int contact_id)
-{
- guint8 socketaddressversion;
- proto_tree *contract_tree, *version_tree, *socket_tree;
- proto_item *contract_item, *version_item, *socket_item;
- int socket_length;
-
- if (contact_id > 0)
- {
- contract_item = proto_tree_add_text(tree, tvb, offset, 1, "Contact #%d", contact_id);
- }
- else
- {
- contract_item = proto_tree_add_text(tree, tvb, offset, 1, "Contact");
- }
- contract_tree = proto_item_add_subtree(contract_item, ett_mojito_contact);
-
- proto_tree_add_item(contract_tree, hf_mojito_contactvendor, tvb, offset, 4, ENC_ASCII|ENC_NA);
- offset += 4;
-
- version_item = proto_tree_add_item(contract_tree, hf_mojito_contactversion, tvb, offset, 2, ENC_BIG_ENDIAN);
- version_tree = proto_item_add_subtree(version_item, ett_mojito_contact_version);
- proto_tree_add_item(version_tree, hf_mojito_mjrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
- proto_tree_add_item(version_tree, hf_mojito_mnrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- proto_tree_add_item(contract_tree, hf_mojito_contactkuid, tvb, offset, 20, ENC_NA);
- offset += 20;
-
- /* new subtree for socket address*/
- socketaddressversion = tvb_get_guint8(tvb, offset);
- socket_item = proto_tree_add_text(contract_tree, tvb, offset, 1, "Socket Address");
- socket_tree = proto_item_add_subtree(socket_item, ett_mojito_socket_address);
-
- switch (socketaddressversion)
- {
- case FT_IPv4_LEN: /* IPv4 */
-
- proto_tree_add_item(socket_tree, hf_mojito_socketaddress_version, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- proto_tree_add_item(socket_tree, hf_mojito_socketaddress_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
- offset += 4;
-
- proto_tree_add_item(socket_tree, hf_mojito_socketaddress_port, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
-
- /* Set the socket length to properly set item length */
- socket_length = 7;
- break;
-
- case FT_IPv6_LEN: /* IPv6 */
-
- proto_tree_add_item(socket_tree, hf_mojito_socketaddress_version, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- proto_tree_add_item(socket_tree, hf_mojito_socketaddress_ipv6, tvb, offset, 16, ENC_NA);
- offset += 16;
-
- proto_tree_add_item(socket_tree, hf_mojito_socketaddress_port, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
-
- /* Set the socket length to properly set item length */
- socket_length = 19;
- break;
-
- default: /* ABORT */
- expert_add_info_format(pinfo, socket_item, PI_PROTOCOL, PI_ERROR, "Unsupported Socket Address Type");
- return -1;
- }
-
- proto_item_set_len(socket_item, socket_length);
- proto_item_set_len(contract_item, socket_length+26);
-
- return socket_length+26;
-}
-
-static int
-dissect_mojito_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- int offset, mojito_header_data_t* header_data)
-{
- proto_tree *header_tree, *version_tree, *contract_tree, *socket_tree, *flag_tree;
- proto_item *header_item, *version_item, *contract_item, *socket_item, *flag_item;
- guint8 socketaddressversion;
- int start_offset = offset,
- socket_length;
-
- header_item = proto_tree_add_text(tree, tvb, offset, 61, "Gnutella Header");
- header_tree = proto_item_add_subtree(header_item, ett_mojito_header);
-
- proto_tree_add_item(header_tree, hf_mojito_messageid, tvb, offset, 16, ENC_NA);
- offset += 16;
-
- proto_tree_add_item(header_tree, hf_mojito_fdhtmessage, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- version_item = proto_tree_add_text(header_tree, tvb, offset, 2, "Version");
- version_tree = proto_item_add_subtree(version_item, ett_mojito_header_version);
-
- proto_tree_add_item(version_tree, hf_mojito_mjrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
- proto_tree_add_item(version_tree, hf_mojito_mnrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- /* Payload Length : in Little Endian */
- header_data->payloadlength = tvb_get_letohl(tvb, offset);
- proto_tree_add_item(header_tree, hf_mojito_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
-
- header_data->opcode = tvb_get_guint8(tvb, offset);
- col_add_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str(header_data->opcode, opcodeflags, "Unknown"));
- proto_tree_add_item(header_tree, hf_mojito_opcode, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- contract_item = proto_tree_add_text(header_tree, tvb, offset, 35, "Originating Contact");
- contract_tree = proto_item_add_subtree(contract_item, ett_mojito_contact);
-
- proto_tree_add_item(contract_tree, hf_mojito_vendor, tvb, offset, 4, ENC_ASCII|ENC_NA);
- offset += 4;
-
- version_item = proto_tree_add_text(contract_tree, tvb, offset, 2, "Contact Version");
- version_tree = proto_item_add_subtree(version_item, ett_mojito_contact_version);
-
- proto_tree_add_item(version_tree, hf_mojito_origmjrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
- proto_tree_add_item(version_tree, hf_mojito_origmnrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- proto_tree_add_item(contract_tree, hf_mojito_kuid, tvb, offset, 20, ENC_NA);
- offset += 20;
-
- socket_item = proto_tree_add_text(contract_tree, tvb, offset, 7, "Socket Address");
- socket_tree = proto_item_add_subtree(socket_item, ett_mojito_socket_address);
-
- /* Socket Address */
- socketaddressversion = tvb_get_guint8(tvb, offset);
- switch (socketaddressversion)
- {
- case FT_IPv4_LEN: /* IPv4 */
- proto_tree_add_item(socket_tree, hf_mojito_socketaddress_version, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- proto_tree_add_item(socket_tree, hf_mojito_socketaddress_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
- offset += 4;
- socket_length = 7;
- break;
-
- case FT_IPv6_LEN: /* IPv6 */
- proto_tree_add_item(socket_tree, hf_mojito_socketaddress_version, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
- proto_tree_add_item(socket_tree, hf_mojito_socketaddress_ipv6, tvb, offset, 16, ENC_NA);
- offset += 16;
- socket_length = 19;
- break;
- default:
- /* Abort */
- return 0;
- }
-
- proto_tree_add_item(socket_tree, hf_mojito_socketaddress_port, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
-
- proto_item_set_len(socket_item, socket_length);
- proto_item_set_len(contract_item, socket_length+26);
-
- proto_tree_add_item(header_tree, hf_mojito_instanceid, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- /*Flags*/
- flag_item = proto_tree_add_item(header_tree, hf_mojito_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
- flag_tree = proto_item_add_subtree(flag_item, ett_mojito_flags);
- proto_tree_add_item(flag_tree, hf_mojito_flags_shutdown, tvb, offset, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(flag_tree, hf_mojito_flags_firewalled, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- proto_tree_add_item(header_tree, hf_mojito_extendedlength, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
-
- proto_item_set_len(header_item, offset-start_offset);
- return offset;
-}
-
-static void
-dissect_mojito_ping_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
-{
- guint8 bigintlen,
- socketaddressversion = tvb_get_guint8(tvb, offset);
- proto_tree *socket_tree, *bigint_tree;
- proto_item *socket_item, *bigint_item;
-
- socket_item = proto_tree_add_text(tree, tvb, offset, 1, "Requester\'s External Socket Address");
- socket_tree = proto_item_add_subtree(socket_item, ett_mojito_ping_socket_address);
-
- switch (socketaddressversion)
- {
- case FT_IPv4_LEN:
- proto_item_set_len(socket_item, 7);
-
- proto_tree_add_item(socket_tree, hf_mojito_socketaddress_version, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- proto_tree_add_item(socket_tree, hf_mojito_socketaddress_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
- offset += 4;
- break;
-
- case FT_IPv6_LEN:
- proto_item_set_len(socket_item, 19);
-
- proto_tree_add_item(socket_tree, hf_mojito_socketaddress_version, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- proto_tree_add_item(socket_tree, hf_mojito_socketaddress_ipv6, tvb, offset, 16, ENC_NA);
- offset += 16;
- break;
-
- default:
- expert_add_info_format(pinfo, socket_item, PI_PROTOCOL, PI_ERROR, "Unsupported Socket Address Type");
- return;
- }
-
- proto_tree_add_item(socket_tree, hf_mojito_socketaddress_port, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
-
- /* BigInt subtree */
- bigintlen = tvb_get_guint8(tvb, offset);
- bigint_item = proto_tree_add_text(tree, tvb, offset, bigintlen + 1 , "Estimated DHT size");
- bigint_tree = proto_item_add_subtree(bigint_item, ett_mojito_bigint);
-
- proto_tree_add_item(bigint_tree, hf_mojito_bigintegerlen, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- switch (bigintlen)
- {
- case 1: /* 1 byte */
- proto_tree_add_item(bigint_tree, hf_mojito_bigint_value_one, tvb, offset, bigintlen, ENC_BIG_ENDIAN);
- break;
-
- case 2: /* 2 byte */
- proto_tree_add_item(bigint_tree, hf_mojito_bigint_value_two, tvb, offset, bigintlen, ENC_BIG_ENDIAN);
- break;
-
- case 3: /* 3 byte */
- proto_tree_add_item(bigint_tree, hf_mojito_bigint_value_three, tvb, offset, bigintlen, ENC_BIG_ENDIAN);
- break;
-
- case 4: /* 4 byte */
- proto_tree_add_item(bigint_tree, hf_mojito_bigint_value_four, tvb, offset, bigintlen, ENC_BIG_ENDIAN);
- break;
- default: /* ABORT */
- expert_add_info_format(pinfo, bigint_item, PI_PROTOCOL, PI_ERROR, "Unsupported BigInt length");
- return;
- }
-
- /* BigInt Value */
- proto_tree_add_item(bigint_tree, hf_mojito_bigintegerval, tvb, offset, bigintlen, ENC_NA);
-}
-
-static void
-dissect_mojito_store_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
-{
- proto_tree *dht_tree, *version_tree;
- proto_item *dht_item, *version_item;
- guint8 i, contactcount,
- sectokenlen = tvb_get_guint8(tvb, offset);
- guint16 dhtvaluelength;
- int contact_offset, start_offset;
-
- proto_tree_add_item(tree, hf_mojito_sectokenlen, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- proto_tree_add_item(tree, hf_mojito_sectoken, tvb, offset, sectokenlen, ENC_NA);
- offset += sectokenlen;
-
- /* Contact count */
- proto_tree_add_item(tree, hf_mojito_dhtvaluecount, tvb, offset, 1, ENC_BIG_ENDIAN);
- contactcount = tvb_get_guint8(tvb, offset);
- offset += 1;
-
- /* For each Contact, display the info */
- for (i = 1; i <= contactcount; i++)
- {
- dht_item = proto_tree_add_text(tree, tvb, offset, 1, "DHTValue #%d", i);
- dht_tree = proto_item_add_subtree(dht_item, ett_mojito_dht);
- start_offset = offset;
- contact_offset = dissect_mojito_contact(tvb, pinfo, dht_tree, offset, -1);
- if (contact_offset == -1)
- return;
- offset += contact_offset;
-
- proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_kuid, tvb, offset, 20, ENC_NA);
- offset += 20;
-
- proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_valuetype, tvb, offset, 4, ENC_ASCII|ENC_NA);
- offset += 4;
-
- /* Version */
- version_item = proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_version, tvb, offset, 2, ENC_BIG_ENDIAN);
- version_tree = proto_item_add_subtree(version_item, ett_mojito_dht_version);
-
- proto_tree_add_item(version_tree, hf_mojito_mjrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
- proto_tree_add_item(version_tree, hf_mojito_mnrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- dhtvaluelength = tvb_get_ntohs(tvb, offset);
- proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_length, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
-
- proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_value, tvb, offset, dhtvaluelength, ENC_ASCII|ENC_NA);
- offset += dhtvaluelength;
-
- proto_item_set_len(dht_item, offset-start_offset);
- }
-}
-
-static void
-dissect_mojito_store_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
-{
- proto_tree *sc_tree;
- proto_item *sc_item;
- guint8 i, contactcount = tvb_get_guint8(tvb, offset);
- guint16 dhtvaluelength;
- int start_offset;
-
- proto_tree_add_item(tree, hf_mojito_storestatuscode_count, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- /* For each Contact, display the info */
- for (i = 1; i <= contactcount; i++)
- {
- sc_item = proto_tree_add_text(tree, tvb, offset, 23, "Status Code %d", i);
- sc_tree = proto_item_add_subtree(sc_item, ett_mojito_status_code);
-
- start_offset = offset;
-
- /*Primary KUID */
- proto_tree_add_item(sc_tree, hf_mojito_storestatuscode_kuid, tvb, offset, 20, ENC_NA);
- offset += 20;
-
- if (tvb_reported_length_remaining(tvb, offset+3) > 0)
- {
- /* Must be a secondard KUID */
- proto_tree_add_item(sc_tree, hf_mojito_storestatuscode_secondary_kuid, tvb, offset, 20, ENC_NA);
- offset += 20;
- }
-
- proto_tree_add_item(sc_tree, hf_mojito_storestatuscode_code, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
-
- dhtvaluelength = tvb_get_ntohs(tvb, offset);
- proto_tree_add_item(sc_tree, hf_mojito_dhtvalue_length, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
-
- proto_tree_add_item(sc_tree, hf_mojito_dhtvalue_value, tvb, offset, dhtvaluelength, ENC_ASCII|ENC_NA);
- offset += dhtvaluelength;
-
- proto_item_set_len(sc_item, offset-start_offset);
- }
-}
-
-static void
-dissect_mojito_find_node_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
-{
- guint8 i, contactcount,
- sectokenlen = tvb_get_guint8(tvb, offset);
- int contact_offset;
-
- proto_tree_add_item(tree, hf_mojito_sectokenlen, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- proto_tree_add_item(tree, hf_mojito_sectoken, tvb, offset, sectokenlen, ENC_NA);
- offset += sectokenlen;
-
- contactcount = tvb_get_guint8(tvb, offset);
- proto_tree_add_item(tree, hf_mojito_contactcount, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- /* For each Contact, display the info */
- for (i = 1; i <= contactcount; i++)
- {
- contact_offset = dissect_mojito_contact(tvb, pinfo, tree, offset, i);
- if (contact_offset == -1)
- return;
- offset += contact_offset;
- }
-}
-
-static void
-dissect_mojito_find_value_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
-{
- proto_tree *kuid_tree;
- proto_item *kuid_item;
- guint8 i, kuidcount;
-
- proto_tree_add_item(tree, hf_mojito_target_kuid, tvb, offset, 20, ENC_NA);
- offset += 20;
-
- kuidcount = tvb_get_guint8(tvb, offset);
-
- kuid_item = proto_tree_add_text(tree, tvb, offset, (20 * kuidcount) + 1 , "Secondary KUID\'s");
- kuid_tree = proto_item_add_subtree(kuid_item, ett_mojito_kuids);
-
- proto_tree_add_item(kuid_tree, hf_mojito_kuidcount, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- /* All the Secondary KUID's */
- for (i = 0; i < kuidcount; i++)
- {
- proto_tree_add_item(kuid_tree, hf_mojito_kuid, tvb, offset, 20, ENC_NA);
- offset += 20;
- }
-
- proto_tree_add_item(tree, hf_mojito_dhtvaluetype, tvb, offset, 4, ENC_ASCII|ENC_NA);
- offset += 4;
-}
-
-static void
-dissect_mojito_find_value_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
-{
- proto_tree *dht_tree, *version_tree, *kuid_tree;
- proto_item *dht_item, *version_item, *kuid_item;
- guint16 dhtvaluelength;
- int contact_offset, start_offset;
- guint8 i, dhtvaluescount, kuidcount;
-
- proto_tree_add_item(tree, hf_mojito_requestload, tvb, offset, 4, ENC_BIG_ENDIAN);
- offset += 4;
-
- dhtvaluescount = tvb_get_guint8(tvb, offset);
- proto_tree_add_item(tree, hf_mojito_dhtvaluecount, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- /* For each Contact, display the info */
- for (i = 1; i <= dhtvaluescount; i++)
- {
- dht_item = proto_tree_add_text(tree, tvb, offset, 1, "DHTValue #%d", i);
- dht_tree = proto_item_add_subtree(dht_item, ett_mojito_dht);
- start_offset = offset;
- contact_offset = dissect_mojito_contact(tvb, pinfo, dht_tree, offset, -1);
- if (contact_offset == -1)
- return;
- offset += contact_offset;
-
- proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_kuid, tvb, offset, 20, ENC_NA);
- offset += 20;
-
- proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_valuetype, tvb, offset, 4, ENC_ASCII|ENC_NA);
- offset += 4;
-
- /* Version */
- version_item = proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_version, tvb, offset, 2, ENC_BIG_ENDIAN);
- version_tree = proto_item_add_subtree(version_item, ett_mojito_dht_version);
-
- proto_tree_add_item(version_tree, hf_mojito_mjrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
- proto_tree_add_item(version_tree, hf_mojito_mnrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- /* Length */
- dhtvaluelength = tvb_get_ntohs(tvb, offset);
- proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_length, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
-
- /* Value */
- proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_value, tvb, offset, dhtvaluelength, ENC_ASCII|ENC_NA);
- offset += dhtvaluelength;
-
- proto_item_set_len(dht_item, offset-start_offset);
- }
-
- /*KUID Count */
- kuidcount = tvb_get_guint8(tvb, offset);
- kuid_item = proto_tree_add_text(tree, tvb, offset, (20 * kuidcount) + 1 , "Secondary KUID\'s");
- kuid_tree = proto_item_add_subtree(kuid_item, ett_mojito_kuids);
- proto_tree_add_item(kuid_tree, hf_mojito_kuidcount, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- /* All the Secondary KUID's */
- for (i = 0; i < kuidcount; i++)
- {
- proto_tree_add_item(kuid_tree, hf_mojito_kuid, tvb, offset, 20, ENC_NA);
- offset += 20;
- }
-}
-
-static int
-dissect_mojito(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
-{
- proto_tree *mojito_tree, *opcode_tree;
- proto_item *ti, *opcode_item;
- mojito_header_data_t header_data;
- gint offset = 0;
-
- col_set_str(pinfo->cinfo, COL_PROTOCOL, "Mojito");
- col_clear(pinfo->cinfo, COL_INFO);
-
- if (tree)
- {
- /* Add a new item to the tree */
- ti = proto_tree_add_item(tree, proto_mojito, tvb, 0, -1, ENC_NA);
- mojito_tree = proto_item_add_subtree(ti, ett_mojito);
-
- offset = dissect_mojito_header(tvb, pinfo, mojito_tree, offset, &header_data);
- if (offset == 0) /* Some error occurred */
- return 0;
-
- opcode_item = proto_tree_add_text(mojito_tree, tvb, offset, header_data.payloadlength - MOJITO_HEADER_LENGTH, "Opcode specific data (%s)", val_to_str(header_data.opcode, opcodeflags, "Unknown"));
- opcode_tree = proto_item_add_subtree(opcode_item, ett_mojito_opcode);
-
- /* Now use the opcode to figure out what to do next */
- switch (header_data.opcode)
- {
- case PING_RESPONSE: /* PING RESPONSE */
- dissect_mojito_ping_response(tvb, pinfo, opcode_tree, offset);
- break;
-
- case STORE_REQUEST: /* STORE REQUEST */
- dissect_mojito_store_request(tvb, pinfo, opcode_tree, offset);
- break;
-
- case STORE_RESPONSE: /* STORE RESPONSE */
- dissect_mojito_store_response(tvb, pinfo, opcode_tree, offset);
- break;
-
- case FIND_NODE_REQUEST: /* FIND NODE REQUEST */
- proto_tree_add_item(opcode_tree, hf_mojito_target_kuid, tvb, offset, 20, ENC_NA);
- offset += 20;
- break;
-
- case FIND_NODE_RESPONSE: /* FIND NODE RESPONSE */
- dissect_mojito_find_node_response(tvb, pinfo, opcode_tree, offset);
- break;
-
- case FIND_VALUE_REQUEST: /* FIND VALUE REQUEST */
- dissect_mojito_find_value_request(tvb, pinfo, opcode_tree, offset);
- break;
-
- case FIND_VALUE_RESPONSE: /* FIND VALUE RESPONSE */
- dissect_mojito_find_value_response(tvb, pinfo, opcode_tree, offset);
- break;
-
- case PING_REQUEST: /* PING REQUEST */
- case STATS_REQUEST_DEPRECATED: /* STATS REQUEST (DEPRECATED) */
- case STATS_RESPONSE_DEPRECATED: /* STATS RESPONSE (DEPRECATED) */
- default:
- if (header_data.payloadlength - MOJITO_HEADER_LENGTH > 0)
- proto_tree_add_item(opcode_tree, hf_mojito_opcode_data, tvb, offset, header_data.payloadlength - MOJITO_HEADER_LENGTH, ENC_NA);
- break;
- }
- }
-
- return tvb_length(tvb);
-}
-
-static gboolean dissect_mojito_heuristic (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
-{
- /*
- Test the overall length to make sure its at least 61 bytes (the header)
- Test to make sure that its of type 44 (mojito)
- Test to make sure that the length field is there and correct
- (tvb_get_letohl(tvb, 20) + 23) == tvb_length(tvb)
- */
- if (tvb_length(tvb) >= 60 && tvb_get_guint8(tvb, 16) == 68 &&(tvb_get_letohl(tvb, 19) + 23) == tvb_length(tvb))
- {
- dissect_mojito(tvb, pinfo, tree);
- return TRUE;
- }
-
- return FALSE;
-}
-
-/* Register the mojito dissector */
-void
-proto_register_mojito(void)
-{
- module_t *mojito_module;
-
- static hf_register_info hf[] = {
- { &hf_mojito_dhtvaluecount,
- { "DHTValue Count", "mojito.dhtvaluecount",
- FT_UINT8, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_messageid,
- { "Message ID", "mojito.messageid",
- FT_BYTES, BASE_NONE,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_requestload,
- { "Request Load", "mojito.requestload",
- FT_UINT32, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_fdhtmessage,
- { "FDHTMessage", "mojito.fdhtmessage",
- FT_UINT8, BASE_HEX,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_mjrversion,
- { "Major Version", "mojito.majorversion",
- FT_UINT8, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_mnrversion,
- { "Minor Version", "mojito.minorversion",
- FT_UINT8, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_length,
- { "Payload Length", "mojito.payloadlength",
- FT_UINT32, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_opcode,
- { "OPCode", "mojito.opcode",
- FT_UINT8, BASE_DEC,
- VALS(opcodeflags), 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_vendor,
- { "Vendor", "mojito.vendor",
- FT_STRING, BASE_NONE,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_origmjrversion,
- { "Major Version", "mojito.majorversion",
- FT_UINT8, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_origmnrversion,
- { "Minor Version", "mojito.minorversion",
- FT_UINT8, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_kuid,
- { "Kademlia Unique ID (KUID)", "mojito.kuid",
- FT_BYTES, BASE_NONE,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_socketaddress_version,
- { "IP Version", "mojito.socketaddressversion",
- FT_UINT8, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_socketaddress_ipv4,
- { "IP Address", "mojito.socketaddressipv4",
- FT_IPv4, BASE_NONE,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_socketaddress_ipv6,
- { "IP Address", "mojito.socketaddressipv6",
- FT_IPv6, BASE_NONE,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_socketaddress_port,
- { "IP Port", "mojito.socketaddressport",
- FT_UINT16, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_instanceid,
- { "Instance ID", "mojito.instanceid",
- FT_UINT8, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_flags,
- { "Flags", "mojito.flags",
- FT_UINT8, BASE_HEX,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_flags_shutdown,
- { "SHUTDOWN", "mojito.shutdownflag",
- FT_BOOLEAN, 8,
- NULL, 2,
- NULL, HFILL }
- },
- { &hf_mojito_flags_firewalled,
- { "Firewalled", "mojito.firewalledflag",
- FT_BOOLEAN, 8,
- NULL, 1,
- NULL, HFILL }
- },
- { &hf_mojito_extendedlength,
- { "Extended Length", "mojito.extlength",
- FT_UINT16, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_kuidcount,
- { "Secondary KUID Count", "mojito.kuidcount",
- FT_UINT8, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_dhtvaluetype,
- { "DHT Value Type", "mojito.dhtvaluetype",
- FT_STRING, BASE_NONE,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_bigintegerlen,
- { "Big Integer Length", "mojito.bigintegerlen",
- FT_UINT8, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_bigintegerval,
- { "Big Integer HEX Value", "mojito.bigintegerhexval",
- FT_BYTES, BASE_NONE,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_sectokenlen,
- { "Security Token Length", "mojito.sectokenlen",
- FT_UINT8, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_sectoken,
- { "Security Token", "mojito.sectoken",
- FT_BYTES, BASE_NONE,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_contactcount,
- { "Contact Count", "mojito.contactcount",
- FT_UINT8, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_contactvendor,
- { "Vendor", "mojito.contactvendor",
- FT_STRING, BASE_NONE,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_contactversion,
- { "Contact Version", "mojito.contactversion",
- FT_UINT16, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_contactkuid,
- { "KUID of the Contact", "mojito.contactkuid",
- FT_BYTES, BASE_NONE,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_dhtvalue_valuetype,
- { "DHTValue ValueType", "mojito.dhtvaluevaluetype",
- FT_STRING, BASE_NONE,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_dhtvalue_version,
- { "DHTValue Version", "mojito.dhtvalueversion",
- FT_UINT16, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_dhtvalue_length,
- { "DHTValue Length", "mojito.dhtvaluelength",
- FT_UINT16, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_dhtvalue_value,
- { "DHTValue", "mojito.dhtvaluehexvalue",
- FT_STRING, BASE_NONE,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_bigint_value_one,
- { "Big Integer DEC Value", "mojito.bigintegerval",
- FT_UINT8, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_bigint_value_two,
- { "Big Integer DEC Value", "mojito.bigintegerval",
- FT_UINT16, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_bigint_value_three,
- { "Big Integer DEC Value", "mojito.bigintegerval",
- FT_UINT24, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_bigint_value_four,
- { "Big Integer DEC Value", "mojito.bigintegerval",
- FT_UINT32, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_dhtvalue_kuid,
- { "Kademlia Unique ID (KUID)", "mojito.kuid",
- FT_BYTES, BASE_NONE,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_target_kuid,
- { "Target Kademlia Unique ID (KUID)", "mojito.kuid",
- FT_BYTES, BASE_NONE,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_storestatuscode_count,
- { "Status Code Count", "mojito.statuscodecount",
- FT_UINT8, BASE_DEC,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_storestatuscode_code,
- { "StatusCode", "mojito.statuscodecount",
- FT_UINT16, BASE_DEC,
- VALS(statuscodeflags), 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_storestatuscode_kuid,
- { "Primary KUID of the Status Code", "mojito.statuscodekuid",
- FT_BYTES, BASE_NONE,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_storestatuscode_secondary_kuid,
- { "Secondary KUID of the Status Code", "mojito.statuscodesecondarykuid",
- FT_BYTES, BASE_NONE,
- NULL, 0x0,
- NULL, HFILL }
- },
- { &hf_mojito_opcode_data,
- { "Data", "mojito.opcode.data",
- FT_BYTES, BASE_NONE,
- NULL, 0x0,
- NULL, HFILL }
- }
- };
-
- /* Setup protocol subtree array */
- static gint *ett[] = {
- &ett_mojito,
- &ett_mojito_header,
- &ett_mojito_header_version,
- &ett_mojito_contact,
- &ett_mojito_contact_version,
- &ett_mojito_socket_address,
- &ett_mojito_flags,
- &ett_mojito_ping_socket_address,
- &ett_mojito_bigint,
- &ett_mojito_opcode,
- &ett_mojito_dht_version,
- &ett_mojito_dht,
- &ett_mojito_status_code,
- &ett_mojito_kuids
- };
-
- proto_mojito = proto_register_protocol("Mojito DHT", "Mojito", "mojito");
-
- proto_register_field_array(proto_mojito, hf, array_length(hf));
- proto_register_subtree_array(ett, array_length(ett));
-
- /* Set the Prefs */
- mojito_module = prefs_register_protocol(proto_mojito, NULL);
-
- prefs_register_uint_preference(mojito_module,
- "udp.port",
- "Mojito UDP Port",
- "Mojito UDP Port",
- 10,
- &udp_mojito_port);
-}
-
-/* Control the handoff */
-void
-proto_reg_handoff_mojito(void)
-{
- static gboolean initialized = FALSE;
- static int old_mojito_udp_port = 0;
- static dissector_handle_t mojito_handle;
-
- if (!initialized) {
- mojito_handle = new_create_dissector_handle(dissect_mojito, proto_mojito);
- heur_dissector_add("udp", dissect_mojito_heuristic, proto_mojito);
- initialized = TRUE;
- }
-
- /* Register UDP port for dissection */
- if(old_mojito_udp_port != 0 && old_mojito_udp_port != udp_mojito_port){
- dissector_delete_uint("udp.port", old_mojito_udp_port, mojito_handle);
- }
-
- if(udp_mojito_port != 0 && old_mojito_udp_port != udp_mojito_port) {
- dissector_add_uint("udp.port", udp_mojito_port, mojito_handle);
- }
-
- old_mojito_udp_port = udp_mojito_port;
-}
+/* packet-mojito.c
+ * Routines for Dissecting the Gnutella Mojito DHT Protocol
+ * http://limewire.negatis.com/index.php?title=Mojito_Message_Format
+ *
+ * Copyright (c) 2008 by Travis Dawson <travis.dawson@sprint.com>
+ *
+ * $Id$
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <epan/packet.h>
+#include <epan/prefs.h>
+#include <epan/expert.h>
+
+#define MOJITO_HEADER_LENGTH 38
+
+/* All the Defines for OpCodes */
+#define PING_REQUEST 1
+#define PING_RESPONSE 2
+#define STORE_REQUEST 3
+#define STORE_RESPONSE 4
+#define FIND_NODE_REQUEST 5
+#define FIND_NODE_RESPONSE 6
+#define FIND_VALUE_REQUEST 7
+#define FIND_VALUE_RESPONSE 8
+#define STATS_REQUEST_DEPRECATED 9
+#define STATS_RESPONSE_DEPRECATED 10
+
+/* Initialize the protocol and registered fields */
+static int proto_mojito = -1;
+
+/* Start of fields */
+static int hf_mojito_messageid = -1;
+static int hf_mojito_fdhtmessage = -1;
+static int hf_mojito_mjrversion = -1;
+static int hf_mojito_mnrversion = -1;
+static int hf_mojito_length = -1;
+static int hf_mojito_opcode = -1;
+static int hf_mojito_vendor = -1;
+static int hf_mojito_origmjrversion = -1;
+static int hf_mojito_origmnrversion = -1;
+static int hf_mojito_kuid = -1;
+static int hf_mojito_socketaddress_version = -1;
+static int hf_mojito_socketaddress_ipv4 = -1;
+static int hf_mojito_socketaddress_ipv6 = -1;
+static int hf_mojito_socketaddress_port = -1;
+static int hf_mojito_instanceid = -1;
+static int hf_mojito_flags = -1;
+static int hf_mojito_flags_shutdown = -1;
+static int hf_mojito_flags_firewalled = -1;
+static int hf_mojito_extendedlength = -1;
+static int hf_mojito_kuidcount = -1;
+static int hf_mojito_bigintegerlen = -1;
+static int hf_mojito_bigintegerval = -1;
+static int hf_mojito_dhtvaluetype = -1;
+static int hf_mojito_sectokenlen = -1;
+static int hf_mojito_sectoken = -1;
+static int hf_mojito_contactcount = -1;
+static int hf_mojito_contactvendor = -1;
+static int hf_mojito_contactversion = -1;
+static int hf_mojito_contactkuid = -1;
+static int hf_mojito_dhtvaluecount = -1;
+static int hf_mojito_dhtvalue_kuid = -1;
+static int hf_mojito_target_kuid = -1;
+static int hf_mojito_dhtvalue_valuetype = -1;
+static int hf_mojito_dhtvalue_version = -1;
+static int hf_mojito_dhtvalue_length = -1;
+static int hf_mojito_dhtvalue_value = -1;
+static int hf_mojito_bigint_value_one = -1;
+static int hf_mojito_bigint_value_two = -1;
+static int hf_mojito_bigint_value_three = -1;
+static int hf_mojito_bigint_value_four = -1;
+static int hf_mojito_storestatuscode_count = -1;
+static int hf_mojito_storestatuscode_code = -1;
+static int hf_mojito_storestatuscode_kuid = -1;
+static int hf_mojito_storestatuscode_secondary_kuid = -1;
+static int hf_mojito_requestload = -1;
+#if 0
+static int hf_mojito_startflag = -1;
+static int hf_mojito_endflag = -1;
+static int hf_mojito_priorityflag = -1;
+#endif
+static int hf_mojito_opcode_data = -1;
+
+/* Initialize the subtree pointers */
+static gint ett_mojito = -1;
+static gint ett_mojito_header = -1;
+static gint ett_mojito_header_version = -1;
+static gint ett_mojito_contact = -1;
+static gint ett_mojito_contact_version = -1;
+static gint ett_mojito_socket_address = -1;
+static gint ett_mojito_flags = -1;
+static gint ett_mojito_ping_socket_address = -1;
+static gint ett_mojito_bigint = -1;
+static gint ett_mojito_opcode = -1;
+static gint ett_mojito_dht_version = -1;
+static gint ett_mojito_dht = -1;
+static gint ett_mojito_status_code = -1;
+static gint ett_mojito_kuids = -1;
+
+/* Preferences */
+static int udp_mojito_port = 0;
+
+typedef struct mojito_header_data {
+ guint8 opcode;
+ guint32 payloadlength;
+} mojito_header_data_t;
+
+/* Values for OPCode Flags */
+static const value_string opcodeflags[] = {
+ { PING_REQUEST, "PING REQUEST" },
+ { PING_RESPONSE, "PING RESPONSE" },
+ { STORE_REQUEST, "STORE REQUEST" },
+ { STORE_RESPONSE, "STORE RESPONSE" },
+ { FIND_NODE_REQUEST, "FIND NODE REQUEST" },
+ { FIND_NODE_RESPONSE, "FIND NODE RESPONSE" },
+ { FIND_VALUE_REQUEST, "FIND VALUE REQUEST" },
+ { FIND_VALUE_RESPONSE, "FIND VALUE RESPONSE" },
+ { STATS_REQUEST_DEPRECATED, "STATS REQUEST (DEPRECATED)" },
+ { STATS_RESPONSE_DEPRECATED, "STATS RESPONSE (DEPRECATED)" },
+ { 0, NULL }
+};
+
+static const value_string statuscodeflags[] = {
+ { 1, "OK" },
+ { 2, "Error" },
+ { 0, NULL }
+};
+
+#if 0
+static const value_string vendorcodeflags[] = {
+ { 0, "MESSAGES_SUPPORTED" },
+ { 4, "HOPS_FLOW" },
+ { 5, "CRAWLER_PING" },
+ { 6, "CRAWLER_PONG" },
+ { 7, "UDP_CONNECT_BACK" },
+ { 8, "UDP_CONNECT_BACK_REDIR" },
+ { 9, "NGTH_MINUS_PAYLOAD" },
+ { 10, "CAPABILITIES" },
+ { 11, "LIME_ACK" },
+ { 12, "REPLY_NUMBER" },
+ { 13, "OOB_PROXYING_CONTROL" },
+ { 14, "GIVE_STATS" },
+ { 15, "STATISTICS" },
+ { 16, "SIMPP_REQ" },
+ { 17, "SIMPP" },
+ { 21, "PUSH_PROXY_REQ" },
+ { 22, "PUSH_PROXY_ACK" },
+ { 23, "UDP_HEAD_PING" },
+ { 24, "UDP_HEAD_PONG" },
+ { 25, "HEADER_UPDATE" },
+ { 26, "UPDATE_REQ" },
+ { 27, "UPDATE_RESP" },
+ { 28, "CONTENT_REQ" },
+ { 29, "CONTENT_RESP" },
+ { 30, "INSPECTION_REQ" },
+ { 31, "INSPECTION_RESP" },
+ { 32, "ADVANCED_TOGGLE" },
+ { 33, "DHT_CONTACTS" },
+
+ { 0, NULL }
+};
+#endif
+
+static int
+dissect_mojito_contact(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int contact_id)
+{
+ guint8 socketaddressversion;
+ proto_tree *contract_tree, *version_tree, *socket_tree;
+ proto_item *contract_item, *version_item, *socket_item;
+ int socket_length;
+
+ if (contact_id > 0)
+ {
+ contract_item = proto_tree_add_text(tree, tvb, offset, 1, "Contact #%d", contact_id);
+ }
+ else
+ {
+ contract_item = proto_tree_add_text(tree, tvb, offset, 1, "Contact");
+ }
+ contract_tree = proto_item_add_subtree(contract_item, ett_mojito_contact);
+
+ proto_tree_add_item(contract_tree, hf_mojito_contactvendor, tvb, offset, 4, ENC_ASCII|ENC_NA);
+ offset += 4;
+
+ version_item = proto_tree_add_item(contract_tree, hf_mojito_contactversion, tvb, offset, 2, ENC_BIG_ENDIAN);
+ version_tree = proto_item_add_subtree(version_item, ett_mojito_contact_version);
+ proto_tree_add_item(version_tree, hf_mojito_mjrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(version_tree, hf_mojito_mnrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ proto_tree_add_item(contract_tree, hf_mojito_contactkuid, tvb, offset, 20, ENC_NA);
+ offset += 20;
+
+ /* new subtree for socket address*/
+ socketaddressversion = tvb_get_guint8(tvb, offset);
+ socket_item = proto_tree_add_text(contract_tree, tvb, offset, 1, "Socket Address");
+ socket_tree = proto_item_add_subtree(socket_item, ett_mojito_socket_address);
+
+ switch (socketaddressversion)
+ {
+ case FT_IPv4_LEN: /* IPv4 */
+
+ proto_tree_add_item(socket_tree, hf_mojito_socketaddress_version, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ proto_tree_add_item(socket_tree, hf_mojito_socketaddress_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+
+ proto_tree_add_item(socket_tree, hf_mojito_socketaddress_port, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+
+ /* Set the socket length to properly set item length */
+ socket_length = 7;
+ break;
+
+ case FT_IPv6_LEN: /* IPv6 */
+
+ proto_tree_add_item(socket_tree, hf_mojito_socketaddress_version, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ proto_tree_add_item(socket_tree, hf_mojito_socketaddress_ipv6, tvb, offset, 16, ENC_NA);
+ offset += 16;
+
+ proto_tree_add_item(socket_tree, hf_mojito_socketaddress_port, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+
+ /* Set the socket length to properly set item length */
+ socket_length = 19;
+ break;
+
+ default: /* ABORT */
+ expert_add_info_format(pinfo, socket_item, PI_PROTOCOL, PI_ERROR, "Unsupported Socket Address Type");
+ return -1;
+ }
+
+ proto_item_set_len(socket_item, socket_length);
+ proto_item_set_len(contract_item, socket_length+26);
+
+ return socket_length+26;
+}
+
+static int
+dissect_mojito_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ int offset, mojito_header_data_t* header_data)
+{
+ proto_tree *header_tree, *version_tree, *contract_tree, *socket_tree, *flag_tree;
+ proto_item *header_item, *version_item, *contract_item, *socket_item, *flag_item;
+ guint8 socketaddressversion;
+ int start_offset = offset;
+ int socket_length;
+
+ header_item = proto_tree_add_text(tree, tvb, offset, 61, "Gnutella Header");
+ header_tree = proto_item_add_subtree(header_item, ett_mojito_header);
+
+ proto_tree_add_item(header_tree, hf_mojito_messageid, tvb, offset, 16, ENC_NA);
+ offset += 16;
+
+ proto_tree_add_item(header_tree, hf_mojito_fdhtmessage, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ version_item = proto_tree_add_text(header_tree, tvb, offset, 2, "Version");
+ version_tree = proto_item_add_subtree(version_item, ett_mojito_header_version);
+
+ proto_tree_add_item(version_tree, hf_mojito_mjrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(version_tree, hf_mojito_mnrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ /* Payload Length : in Little Endian */
+ header_data->payloadlength = tvb_get_letohl(tvb, offset);
+ proto_tree_add_item(header_tree, hf_mojito_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+
+ header_data->opcode = tvb_get_guint8(tvb, offset);
+ col_add_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str_const(header_data->opcode, opcodeflags, "Unknown"));
+ proto_tree_add_item(header_tree, hf_mojito_opcode, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ contract_item = proto_tree_add_text(header_tree, tvb, offset, 35, "Originating Contact");
+ contract_tree = proto_item_add_subtree(contract_item, ett_mojito_contact);
+
+ proto_tree_add_item(contract_tree, hf_mojito_vendor, tvb, offset, 4, ENC_ASCII|ENC_NA);
+ offset += 4;
+
+ version_item = proto_tree_add_text(contract_tree, tvb, offset, 2, "Contact Version");
+ version_tree = proto_item_add_subtree(version_item, ett_mojito_contact_version);
+
+ proto_tree_add_item(version_tree, hf_mojito_origmjrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(version_tree, hf_mojito_origmnrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ proto_tree_add_item(contract_tree, hf_mojito_kuid, tvb, offset, 20, ENC_NA);
+ offset += 20;
+
+ socket_item = proto_tree_add_text(contract_tree, tvb, offset, 7, "Socket Address");
+ socket_tree = proto_item_add_subtree(socket_item, ett_mojito_socket_address);
+
+ /* Socket Address */
+ socketaddressversion = tvb_get_guint8(tvb, offset);
+ switch (socketaddressversion)
+ {
+ case FT_IPv4_LEN: /* IPv4 */
+ proto_tree_add_item(socket_tree, hf_mojito_socketaddress_version, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ proto_tree_add_item(socket_tree, hf_mojito_socketaddress_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ socket_length = 7;
+ break;
+
+ case FT_IPv6_LEN: /* IPv6 */
+ proto_tree_add_item(socket_tree, hf_mojito_socketaddress_version, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(socket_tree, hf_mojito_socketaddress_ipv6, tvb, offset, 16, ENC_NA);
+ offset += 16;
+ socket_length = 19;
+ break;
+ default:
+ /* Abort */
+ return 0;
+ }
+
+ proto_tree_add_item(socket_tree, hf_mojito_socketaddress_port, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+
+ proto_item_set_len(socket_item, socket_length);
+ proto_item_set_len(contract_item, socket_length+26);
+
+ proto_tree_add_item(header_tree, hf_mojito_instanceid, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ /*Flags*/
+ flag_item = proto_tree_add_item(header_tree, hf_mojito_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
+ flag_tree = proto_item_add_subtree(flag_item, ett_mojito_flags);
+ proto_tree_add_item(flag_tree, hf_mojito_flags_shutdown, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(flag_tree, hf_mojito_flags_firewalled, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ proto_tree_add_item(header_tree, hf_mojito_extendedlength, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+
+ proto_item_set_len(header_item, offset-start_offset);
+ return offset;
+}
+
+static void
+dissect_mojito_ping_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
+{
+ guint8 bigintlen;
+ guint8 socketaddressversion = tvb_get_guint8(tvb, offset);
+ proto_tree *socket_tree, *bigint_tree;
+ proto_item *socket_item, *bigint_item;
+
+ socket_item = proto_tree_add_text(tree, tvb, offset, 1, "Requester\'s External Socket Address");
+ socket_tree = proto_item_add_subtree(socket_item, ett_mojito_ping_socket_address);
+
+ switch (socketaddressversion)
+ {
+ case FT_IPv4_LEN:
+ proto_item_set_len(socket_item, 7);
+
+ proto_tree_add_item(socket_tree, hf_mojito_socketaddress_version, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ proto_tree_add_item(socket_tree, hf_mojito_socketaddress_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ break;
+
+ case FT_IPv6_LEN:
+ proto_item_set_len(socket_item, 19);
+
+ proto_tree_add_item(socket_tree, hf_mojito_socketaddress_version, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ proto_tree_add_item(socket_tree, hf_mojito_socketaddress_ipv6, tvb, offset, 16, ENC_NA);
+ offset += 16;
+ break;
+
+ default:
+ expert_add_info_format(pinfo, socket_item, PI_PROTOCOL, PI_ERROR, "Unsupported Socket Address Type");
+ return;
+ }
+
+ proto_tree_add_item(socket_tree, hf_mojito_socketaddress_port, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+
+ /* BigInt subtree */
+ bigintlen = tvb_get_guint8(tvb, offset);
+ bigint_item = proto_tree_add_text(tree, tvb, offset, bigintlen + 1 , "Estimated DHT size");
+ bigint_tree = proto_item_add_subtree(bigint_item, ett_mojito_bigint);
+
+ proto_tree_add_item(bigint_tree, hf_mojito_bigintegerlen, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ switch (bigintlen)
+ {
+ case 1: /* 1 byte */
+ proto_tree_add_item(bigint_tree, hf_mojito_bigint_value_one, tvb, offset, bigintlen, ENC_BIG_ENDIAN);
+ break;
+
+ case 2: /* 2 byte */
+ proto_tree_add_item(bigint_tree, hf_mojito_bigint_value_two, tvb, offset, bigintlen, ENC_BIG_ENDIAN);
+ break;
+
+ case 3: /* 3 byte */
+ proto_tree_add_item(bigint_tree, hf_mojito_bigint_value_three, tvb, offset, bigintlen, ENC_BIG_ENDIAN);
+ break;
+
+ case 4: /* 4 byte */
+ proto_tree_add_item(bigint_tree, hf_mojito_bigint_value_four, tvb, offset, bigintlen, ENC_BIG_ENDIAN);
+ break;
+ default: /* ABORT */
+ expert_add_info_format(pinfo, bigint_item, PI_PROTOCOL, PI_ERROR, "Unsupported BigInt length");
+ return;
+ }
+
+ /* BigInt Value */
+ proto_tree_add_item(bigint_tree, hf_mojito_bigintegerval, tvb, offset, bigintlen, ENC_NA);
+}
+
+static void
+dissect_mojito_store_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
+{
+ proto_tree *dht_tree, *version_tree;
+ proto_item *dht_item, *version_item;
+ guint8 i, contactcount;
+ guint8 sectokenlen = tvb_get_guint8(tvb, offset);
+ guint16 dhtvaluelength;
+ int contact_offset, start_offset;
+
+ proto_tree_add_item(tree, hf_mojito_sectokenlen, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ proto_tree_add_item(tree, hf_mojito_sectoken, tvb, offset, sectokenlen, ENC_NA);
+ offset += sectokenlen;
+
+ /* Contact count */
+ proto_tree_add_item(tree, hf_mojito_dhtvaluecount, tvb, offset, 1, ENC_BIG_ENDIAN);
+ contactcount = tvb_get_guint8(tvb, offset);
+ offset += 1;
+
+ /* For each Contact, display the info */
+ for (i = 1; i <= contactcount; i++)
+ {
+ dht_item = proto_tree_add_text(tree, tvb, offset, 1, "DHTValue #%d", i);
+ dht_tree = proto_item_add_subtree(dht_item, ett_mojito_dht);
+ start_offset = offset;
+ contact_offset = dissect_mojito_contact(tvb, pinfo, dht_tree, offset, -1);
+ if (contact_offset == -1)
+ return;
+ offset += contact_offset;
+
+ proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_kuid, tvb, offset, 20, ENC_NA);
+ offset += 20;
+
+ proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_valuetype, tvb, offset, 4, ENC_ASCII|ENC_NA);
+ offset += 4;
+
+ /* Version */
+ version_item = proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_version, tvb, offset, 2, ENC_BIG_ENDIAN);
+ version_tree = proto_item_add_subtree(version_item, ett_mojito_dht_version);
+
+ proto_tree_add_item(version_tree, hf_mojito_mjrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(version_tree, hf_mojito_mnrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ dhtvaluelength = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_length, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+
+ proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_value, tvb, offset, dhtvaluelength, ENC_ASCII|ENC_NA);
+ offset += dhtvaluelength;
+
+ proto_item_set_len(dht_item, offset-start_offset);
+ }
+}
+
+static void
+dissect_mojito_store_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
+{
+ proto_tree *sc_tree;
+ proto_item *sc_item;
+ guint8 i, contactcount = tvb_get_guint8(tvb, offset);
+ guint16 dhtvaluelength;
+ int start_offset;
+
+ proto_tree_add_item(tree, hf_mojito_storestatuscode_count, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ /* For each Contact, display the info */
+ for (i = 1; i <= contactcount; i++)
+ {
+ sc_item = proto_tree_add_text(tree, tvb, offset, 23, "Status Code %d", i);
+ sc_tree = proto_item_add_subtree(sc_item, ett_mojito_status_code);
+
+ start_offset = offset;
+
+ /*Primary KUID */
+ proto_tree_add_item(sc_tree, hf_mojito_storestatuscode_kuid, tvb, offset, 20, ENC_NA);
+ offset += 20;
+
+ if (tvb_reported_length_remaining(tvb, offset+3) > 0)
+ {
+ /* Must be a secondard KUID */
+ proto_tree_add_item(sc_tree, hf_mojito_storestatuscode_secondary_kuid, tvb, offset, 20, ENC_NA);
+ offset += 20;
+ }
+
+ proto_tree_add_item(sc_tree, hf_mojito_storestatuscode_code, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+
+ dhtvaluelength = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_item(sc_tree, hf_mojito_dhtvalue_length, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+
+ proto_tree_add_item(sc_tree, hf_mojito_dhtvalue_value, tvb, offset, dhtvaluelength, ENC_ASCII|ENC_NA);
+ offset += dhtvaluelength;
+
+ proto_item_set_len(sc_item, offset-start_offset);
+ }
+}
+
+static void
+dissect_mojito_find_node_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
+{
+ guint8 i, contactcount;
+ guint8 sectokenlen = tvb_get_guint8(tvb, offset);
+ int contact_offset;
+
+ proto_tree_add_item(tree, hf_mojito_sectokenlen, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ proto_tree_add_item(tree, hf_mojito_sectoken, tvb, offset, sectokenlen, ENC_NA);
+ offset += sectokenlen;
+
+ contactcount = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(tree, hf_mojito_contactcount, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ /* For each Contact, display the info */
+ for (i = 1; i <= contactcount; i++)
+ {
+ contact_offset = dissect_mojito_contact(tvb, pinfo, tree, offset, i);
+ if (contact_offset == -1)
+ return;
+ offset += contact_offset;
+ }
+}
+
+static void
+dissect_mojito_find_value_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
+{
+ proto_tree *kuid_tree;
+ proto_item *kuid_item;
+ guint8 i, kuidcount;
+
+ if (!tree)
+ return;
+
+ proto_tree_add_item(tree, hf_mojito_target_kuid, tvb, offset, 20, ENC_NA);
+ offset += 20;
+
+ kuidcount = tvb_get_guint8(tvb, offset);
+
+ kuid_item = proto_tree_add_text(tree, tvb, offset, (20 * kuidcount) + 1 , "Secondary KUID\'s");
+ kuid_tree = proto_item_add_subtree(kuid_item, ett_mojito_kuids);
+
+ proto_tree_add_item(kuid_tree, hf_mojito_kuidcount, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ /* All the Secondary KUID's */
+ for (i = 0; i < kuidcount; i++)
+ {
+ proto_tree_add_item(kuid_tree, hf_mojito_kuid, tvb, offset, 20, ENC_NA);
+ offset += 20;
+ }
+
+ proto_tree_add_item(tree, hf_mojito_dhtvaluetype, tvb, offset, 4, ENC_ASCII|ENC_NA);
+ offset += 4;
+}
+
+static void
+dissect_mojito_find_value_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
+{
+ proto_tree *dht_tree, *version_tree, *kuid_tree;
+ proto_item *dht_item, *version_item, *kuid_item;
+ guint16 dhtvaluelength;
+ int contact_offset, start_offset;
+ guint8 i, dhtvaluescount, kuidcount;
+
+ proto_tree_add_item(tree, hf_mojito_requestload, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+
+ dhtvaluescount = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(tree, hf_mojito_dhtvaluecount, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ /* For each Contact, display the info */
+ for (i = 1; i <= dhtvaluescount; i++)
+ {
+ dht_item = proto_tree_add_text(tree, tvb, offset, 1, "DHTValue #%d", i);
+ dht_tree = proto_item_add_subtree(dht_item, ett_mojito_dht);
+ start_offset = offset;
+ contact_offset = dissect_mojito_contact(tvb, pinfo, dht_tree, offset, -1);
+ if (contact_offset == -1)
+ return;
+
+ offset += contact_offset;
+
+ proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_kuid, tvb, offset, 20, ENC_NA);
+ offset += 20;
+
+ proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_valuetype, tvb, offset, 4, ENC_ASCII|ENC_NA);
+ offset += 4;
+
+ /* Version */
+ version_item = proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_version, tvb, offset, 2, ENC_BIG_ENDIAN);
+ version_tree = proto_item_add_subtree(version_item, ett_mojito_dht_version);
+
+ proto_tree_add_item(version_tree, hf_mojito_mjrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(version_tree, hf_mojito_mnrversion, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ /* Length */
+ dhtvaluelength = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_length, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+
+ /* Value */
+ proto_tree_add_item(dht_tree, hf_mojito_dhtvalue_value, tvb, offset, dhtvaluelength, ENC_ASCII|ENC_NA);
+ offset += dhtvaluelength;
+
+ proto_item_set_len(dht_item, offset-start_offset);
+ }
+
+ /*KUID Count */
+ kuidcount = tvb_get_guint8(tvb, offset);
+ kuid_item = proto_tree_add_text(tree, tvb, offset, (20 * kuidcount) + 1 , "Secondary KUID\'s");
+ kuid_tree = proto_item_add_subtree(kuid_item, ett_mojito_kuids);
+ proto_tree_add_item(kuid_tree, hf_mojito_kuidcount, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ /* All the Secondary KUID's */
+ for (i = 0; i < kuidcount; i++)
+ {
+ proto_tree_add_item(kuid_tree, hf_mojito_kuid, tvb, offset, 20, ENC_NA);
+ offset += 20;
+ }
+}
+
+static int
+dissect_mojito(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ proto_tree *mojito_tree, *opcode_tree;
+ proto_item *ti, *opcode_item;
+ mojito_header_data_t header_data;
+ gint offset = 0;
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "Mojito");
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ /* Add a new item to the tree */
+ ti = proto_tree_add_item(tree, proto_mojito, tvb, 0, -1, ENC_NA);
+ mojito_tree = proto_item_add_subtree(ti, ett_mojito);
+
+ offset = dissect_mojito_header(tvb, pinfo, mojito_tree, offset, &header_data);
+ if (offset == 0) /* Some error occurred */
+ return 0;
+
+ opcode_item = proto_tree_add_text(mojito_tree, tvb,
+ offset, header_data.payloadlength - MOJITO_HEADER_LENGTH,
+ "Opcode specific data (%s)",
+ val_to_str_const(header_data.opcode, opcodeflags, "Unknown"));
+ opcode_tree = proto_item_add_subtree(opcode_item, ett_mojito_opcode);
+
+ /* Now use the opcode to figure out what to do next */
+ switch (header_data.opcode)
+ {
+ case PING_RESPONSE: /* PING RESPONSE */
+ dissect_mojito_ping_response(tvb, pinfo, opcode_tree, offset);
+ break;
+
+ case STORE_REQUEST: /* STORE REQUEST */
+ dissect_mojito_store_request(tvb, pinfo, opcode_tree, offset);
+ break;
+
+ case STORE_RESPONSE: /* STORE RESPONSE */
+ dissect_mojito_store_response(tvb, pinfo, opcode_tree, offset);
+ break;
+
+ case FIND_NODE_REQUEST: /* FIND NODE REQUEST */
+ proto_tree_add_item(opcode_tree, hf_mojito_target_kuid, tvb, offset, 20, ENC_NA);
+ offset += 20;
+ break;
+
+ case FIND_NODE_RESPONSE: /* FIND NODE RESPONSE */
+ dissect_mojito_find_node_response(tvb, pinfo, opcode_tree, offset);
+ break;
+
+ case FIND_VALUE_REQUEST: /* FIND VALUE REQUEST */
+ dissect_mojito_find_value_request(tvb, pinfo, opcode_tree, offset);
+ break;
+
+ case FIND_VALUE_RESPONSE: /* FIND VALUE RESPONSE */
+ dissect_mojito_find_value_response(tvb, pinfo, opcode_tree, offset);
+ break;
+
+ case PING_REQUEST: /* PING REQUEST */
+ case STATS_REQUEST_DEPRECATED: /* STATS REQUEST (DEPRECATED) */
+ case STATS_RESPONSE_DEPRECATED: /* STATS RESPONSE (DEPRECATED) */
+ default:
+ if (header_data.payloadlength - MOJITO_HEADER_LENGTH > 0)
+ proto_tree_add_item(opcode_tree, hf_mojito_opcode_data, tvb,
+ offset, header_data.payloadlength - MOJITO_HEADER_LENGTH, ENC_NA);
+ break;
+ }
+
+ return tvb_length(tvb);
+}
+
+static gboolean dissect_mojito_heuristic (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ /*
+ Test the overall length to make sure its at least 61 bytes (the header)
+ Test to make sure that it's of type 44 (mojito)
+ Test to make sure that the length field is there and correct
+ (tvb_get_letohl(tvb, 20) + 23) == tvb_length(tvb)
+ */
+ if ((tvb_length(tvb) >= 60) &&
+ (tvb_get_guint8(tvb, 16) == 68) &&
+ ((tvb_get_letohl(tvb, 19) + 23) == tvb_reported_length(tvb)))
+ {
+ dissect_mojito(tvb, pinfo, tree);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Register the mojito dissector */
+void
+proto_register_mojito(void)
+{
+ module_t *mojito_module;
+
+ static hf_register_info hf[] = {
+ { &hf_mojito_dhtvaluecount,
+ { "DHTValue Count", "mojito.dhtvaluecount",
+ FT_UINT8, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_messageid,
+ { "Message ID", "mojito.messageid",
+ FT_BYTES, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_requestload,
+ { "Request Load", "mojito.requestload",
+ FT_UINT32, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_fdhtmessage,
+ { "FDHTMessage", "mojito.fdhtmessage",
+ FT_UINT8, BASE_HEX,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_mjrversion,
+ { "Major Version", "mojito.majorversion",
+ FT_UINT8, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_mnrversion,
+ { "Minor Version", "mojito.minorversion",
+ FT_UINT8, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_length,
+ { "Payload Length", "mojito.payloadlength",
+ FT_UINT32, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_opcode,
+ { "OPCode", "mojito.opcode",
+ FT_UINT8, BASE_DEC,
+ VALS(opcodeflags), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_vendor,
+ { "Vendor", "mojito.vendor",
+ FT_STRING, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_origmjrversion,
+ { "Major Version", "mojito.majorversion",
+ FT_UINT8, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_origmnrversion,
+ { "Minor Version", "mojito.minorversion",
+ FT_UINT8, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_kuid,
+ { "Kademlia Unique ID (KUID)", "mojito.kuid",
+ FT_BYTES, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_socketaddress_version,
+ { "IP Version", "mojito.socketaddressversion",
+ FT_UINT8, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_socketaddress_ipv4,
+ { "IP Address", "mojito.socketaddressipv4",
+ FT_IPv4, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_socketaddress_ipv6,
+ { "IP Address", "mojito.socketaddressipv6",
+ FT_IPv6, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_socketaddress_port,
+ { "IP Port", "mojito.socketaddressport",
+ FT_UINT16, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_instanceid,
+ { "Instance ID", "mojito.instanceid",
+ FT_UINT8, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_flags,
+ { "Flags", "mojito.flags",
+ FT_UINT8, BASE_HEX,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_flags_shutdown,
+ { "SHUTDOWN", "mojito.shutdownflag",
+ FT_BOOLEAN, 8,
+ NULL, 2,
+ NULL, HFILL }
+ },
+ { &hf_mojito_flags_firewalled,
+ { "Firewalled", "mojito.firewalledflag",
+ FT_BOOLEAN, 8,
+ NULL, 1,
+ NULL, HFILL }
+ },
+ { &hf_mojito_extendedlength,
+ { "Extended Length", "mojito.extlength",
+ FT_UINT16, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_kuidcount,
+ { "Secondary KUID Count", "mojito.kuidcount",
+ FT_UINT8, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_dhtvaluetype,
+ { "DHT Value Type", "mojito.dhtvaluetype",
+ FT_STRING, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_bigintegerlen,
+ { "Big Integer Length", "mojito.bigintegerlen",
+ FT_UINT8, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_bigintegerval,
+ { "Big Integer HEX Value", "mojito.bigintegerhexval",
+ FT_BYTES, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_sectokenlen,
+ { "Security Token Length", "mojito.sectokenlen",
+ FT_UINT8, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_sectoken,
+ { "Security Token", "mojito.sectoken",
+ FT_BYTES, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_contactcount,
+ { "Contact Count", "mojito.contactcount",
+ FT_UINT8, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_contactvendor,
+ { "Vendor", "mojito.contactvendor",
+ FT_STRING, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_contactversion,
+ { "Contact Version", "mojito.contactversion",
+ FT_UINT16, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_contactkuid,
+ { "KUID of the Contact", "mojito.contactkuid",
+ FT_BYTES, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_dhtvalue_valuetype,
+ { "DHTValue ValueType", "mojito.dhtvaluevaluetype",
+ FT_STRING, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_dhtvalue_version,
+ { "DHTValue Version", "mojito.dhtvalueversion",
+ FT_UINT16, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_dhtvalue_length,
+ { "DHTValue Length", "mojito.dhtvaluelength",
+ FT_UINT16, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_dhtvalue_value,
+ { "DHTValue", "mojito.dhtvaluehexvalue",
+ FT_STRING, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_bigint_value_one,
+ { "Big Integer DEC Value", "mojito.bigintegerval",
+ FT_UINT8, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_bigint_value_two,
+ { "Big Integer DEC Value", "mojito.bigintegerval",
+ FT_UINT16, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_bigint_value_three,
+ { "Big Integer DEC Value", "mojito.bigintegerval",
+ FT_UINT24, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_bigint_value_four,
+ { "Big Integer DEC Value", "mojito.bigintegerval",
+ FT_UINT32, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_dhtvalue_kuid,
+ { "Kademlia Unique ID (KUID)", "mojito.kuid",
+ FT_BYTES, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_target_kuid,
+ { "Target Kademlia Unique ID (KUID)", "mojito.kuid",
+ FT_BYTES, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_storestatuscode_count,
+ { "Status Code Count", "mojito.statuscodecount",
+ FT_UINT8, BASE_DEC,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_storestatuscode_code,
+ { "StatusCode", "mojito.statuscodecount",
+ FT_UINT16, BASE_DEC,
+ VALS(statuscodeflags), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_storestatuscode_kuid,
+ { "Primary KUID of the Status Code", "mojito.statuscodekuid",
+ FT_BYTES, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_storestatuscode_secondary_kuid,
+ { "Secondary KUID of the Status Code", "mojito.statuscodesecondarykuid",
+ FT_BYTES, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_mojito_opcode_data,
+ { "Data", "mojito.opcode.data",
+ FT_BYTES, BASE_NONE,
+ NULL, 0x0,
+ NULL, HFILL }
+ }
+ };
+
+ /* Setup protocol subtree array */
+ static gint *ett[] = {
+ &ett_mojito,
+ &ett_mojito_header,
+ &ett_mojito_header_version,
+ &ett_mojito_contact,
+ &ett_mojito_contact_version,
+ &ett_mojito_socket_address,
+ &ett_mojito_flags,
+ &ett_mojito_ping_socket_address,
+ &ett_mojito_bigint,
+ &ett_mojito_opcode,
+ &ett_mojito_dht_version,
+ &ett_mojito_dht,
+ &ett_mojito_status_code,
+ &ett_mojito_kuids
+ };
+
+ proto_mojito = proto_register_protocol("Mojito DHT", "Mojito", "mojito");
+
+ proto_register_field_array(proto_mojito, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+
+ /* Set the Prefs */
+ mojito_module = prefs_register_protocol(proto_mojito, NULL);
+
+ prefs_register_uint_preference(mojito_module,
+ "udp.port",
+ "Mojito UDP Port",
+ "Mojito UDP Port",
+ 10,
+ &udp_mojito_port);
+}
+
+/* Control the handoff */
+void
+proto_reg_handoff_mojito(void)
+{
+ static gboolean initialized = FALSE;
+ static int old_mojito_udp_port = 0;
+ static dissector_handle_t mojito_handle;
+
+ if (!initialized) {
+ mojito_handle = new_create_dissector_handle(dissect_mojito, proto_mojito);
+ heur_dissector_add("udp", dissect_mojito_heuristic, proto_mojito);
+ initialized = TRUE;
+ }
+
+ /* Register UDP port for dissection */
+ if(old_mojito_udp_port != 0 && old_mojito_udp_port != udp_mojito_port){
+ dissector_delete_uint("udp.port", old_mojito_udp_port, mojito_handle);
+ }
+
+ if(udp_mojito_port != 0 && old_mojito_udp_port != udp_mojito_port) {
+ dissector_add_uint("udp.port", udp_mojito_port, mojito_handle);
+ }
+
+ old_mojito_udp_port = udp_mojito_port;
+}