summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2012-07-30 11:07:29 +0000
committerMichael Mann <mmann78@netscape.net>2012-07-30 11:07:29 +0000
commit7dc7977c0440804e7733644911216e9de5205c38 (patch)
tree931acee9f50910afb9a7ad32174078ab4f36c887
parentc852982ebc94c72d0cf918454c8cd1a406a11a23 (diff)
downloadwireshark-7dc7977c0440804e7733644911216e9de5205c38.tar.gz
Add Mojito dissector (https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=2688)
properly alphabetize packet-mim.c in makefiles svn path=/trunk/; revision=44132
-rw-r--r--epan/CMakeLists.txt3
-rw-r--r--epan/dissectors/Makefile.common3
-rw-r--r--epan/dissectors/packet-mojito.c1099
3 files changed, 1103 insertions, 2 deletions
diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt
index cc8e6d30f9..9733804bf6 100644
--- a/epan/CMakeLists.txt
+++ b/epan/CMakeLists.txt
@@ -837,12 +837,14 @@ set(DISSECTOR_SRC
dissectors/packet-meta.c
dissectors/packet-mgcp.c
dissectors/packet-mikey.c
+ dissectors/packet-mim.c
dissectors/packet-mime-encap.c
dissectors/packet-miop.c
dissectors/packet-mip.c
dissectors/packet-mip6.c
dissectors/packet-mmse.c
dissectors/packet-mndp.c
+ dissectors/packet-mojito.c
dissectors/packet-moldudp.c
dissectors/packet-moldudp64.c
dissectors/packet-mongo.c
@@ -1139,7 +1141,6 @@ set(DISSECTOR_SRC
dissectors/packet-tpncp.c
dissectors/packet-tr.c
dissectors/packet-trill.c
- dissectors/packet-mim.c
dissectors/packet-trmac.c
dissectors/packet-tsp.c
dissectors/packet-tte.c
diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common
index d43c849246..2531dcc5fd 100644
--- a/epan/dissectors/Makefile.common
+++ b/epan/dissectors/Makefile.common
@@ -758,12 +758,14 @@ DISSECTOR_SRC = \
packet-meta.c \
packet-mgcp.c \
packet-mikey.c \
+ packet-mim.c \
packet-mime-encap.c \
packet-miop.c \
packet-mip.c \
packet-mip6.c \
packet-mmse.c \
packet-mndp.c \
+ packet-mojito.c \
packet-moldudp.c \
packet-moldudp64.c \
packet-mongo.c \
@@ -1060,7 +1062,6 @@ DISSECTOR_SRC = \
packet-tpncp.c \
packet-tr.c \
packet-trill.c \
- packet-mim.c \
packet-trmac.c \
packet-tsp.c \
packet-tte.c \
diff --git a/epan/dissectors/packet-mojito.c b/epan/dissectors/packet-mojito.c
new file mode 100644
index 0000000000..78d1a1dc50
--- /dev/null
+++ b/epan/dissectors/packet-mojito.c
@@ -0,0 +1,1099 @@
+/* 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;
+static int hf_mojito_startflag = -1;
+static int hf_mojito_endflag = -1;
+static int hf_mojito_priorityflag = -1;
+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, 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, 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 guint 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;
+}