forked from osmocom/wireshark
617 lines
24 KiB
C
617 lines
24 KiB
C
/* packet-jxta.c
|
|
* Routines for JXTA packet dissection
|
|
* Copyright 2004, Mike Duigou <bondolo@jxta.org>
|
|
* Heavily based on packet-jabber.c, which in turn is heavily based on
|
|
* on packet-acap.c, which in turn is heavily based on
|
|
* packet-imap.c, Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
|
|
*
|
|
* $Id$
|
|
*
|
|
* Ethereal - Network traffic analyzer
|
|
* By Gerald Combs <gerald@ethereal.com>
|
|
* Copyright 1998 Gerald Combs
|
|
*
|
|
* Copied from packet-pop.c, packet-jabber.c, packet-udp.c
|
|
*
|
|
* JXTA specification from http://spec.jxta.org
|
|
*
|
|
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
#include <glib.h>
|
|
#include <epan/packet.h>
|
|
#include <epan/strutil.h>
|
|
#include <epan/prefs.h>
|
|
#include "packet-tcp.h"
|
|
|
|
static const char JXTA_UDP_SIG[] = { 'J', 'X', 'T', 'A' };
|
|
static const char JXTA_MSG_SIG[] = { 'j', 'x', 'm', 'g' };
|
|
static const char JXTA_MSGELEM_SIG[] = { 'j', 'x', 'e', 'l' };
|
|
|
|
static int proto_jxta = -1;
|
|
|
|
static int hf_jxta_udp = -1;
|
|
static int hf_jxta_udpsig = -1;
|
|
static int hf_jxta_welcome = -1;
|
|
static int hf_jxta_framing = -1;
|
|
static int hf_jxta_framing_header = -1;
|
|
static int hf_jxta_framing_header_name_length = -1;
|
|
static int hf_jxta_framing_header_name = -1;
|
|
static int hf_jxta_framing_header_value_length = -1;
|
|
static int hf_jxta_framing_header_value = -1;
|
|
static int hf_jxta_message = -1;
|
|
static int hf_jxta_message_sig = -1;
|
|
static int hf_jxta_message_version = -1;
|
|
static int hf_jxta_message_namespaces_count = -1;
|
|
static int hf_jxta_message_namespace_len = -1;
|
|
static int hf_jxta_message_namespace_name = -1;
|
|
static int hf_jxta_message_element_count = -1;
|
|
static int hf_jxta_element = -1;
|
|
static int hf_jxta_element_sig = -1;
|
|
static int hf_jxta_element_namespaceid = -1;
|
|
static int hf_jxta_element_flags = -1;
|
|
static int hf_jxta_element_flag_hasType = -1;
|
|
static int hf_jxta_element_flag_hasEncoding = -1;
|
|
static int hf_jxta_element_flag_hasSignature = -1;
|
|
static int hf_jxta_element_name_len = -1;
|
|
static int hf_jxta_element_name = -1;
|
|
static int hf_jxta_element_type_len = -1;
|
|
static int hf_jxta_element_type = -1;
|
|
static int hf_jxta_element_encoding_len = -1;
|
|
static int hf_jxta_element_encoding = -1;
|
|
static int hf_jxta_element_content_len = -1;
|
|
static int hf_jxta_element_content = -1;
|
|
|
|
static gint ett_jxta_welcome = -1;
|
|
static gint ett_jxta_udp = -1;
|
|
static gint ett_jxta_framing = -1;
|
|
static gint ett_jxta_framing_header = -1;
|
|
static gint ett_jxta_msg = -1;
|
|
static gint ett_jxta_elem = -1;
|
|
static gint ett_jxta_elem_flags = -1;
|
|
|
|
static dissector_handle_t udpm_jxta_handle;
|
|
static dissector_handle_t tcp_jxta_handle;
|
|
static dissector_handle_t http_jxta_handle;
|
|
|
|
static const true_false_string boolstringname = {
|
|
"True",
|
|
"False"
|
|
};
|
|
|
|
/** our header fields */
|
|
static hf_register_info hf[] = {
|
|
{ &hf_jxta_udp,
|
|
{ "JXTA UDP Message", "jxta.udp", FT_NONE, BASE_NONE, NULL, 0x0,
|
|
"JXTA UDP Message", HFILL }
|
|
},
|
|
{ &hf_jxta_udpsig,
|
|
{ "Signature", "jxta.udpsig", FT_STRING, BASE_NONE, NULL, 0x0,
|
|
"JXTA UDP Signature", HFILL }
|
|
},
|
|
{ &hf_jxta_welcome,
|
|
{ "Welcome Message", "jxta.welcome", FT_NONE, BASE_NONE, NULL, 0x0,
|
|
"JXTA Connection Welcome Message", HFILL }
|
|
},
|
|
{ &hf_jxta_framing,
|
|
{ "JXTA Message Framing", "jxta.framing", FT_NONE, BASE_NONE, NULL, 0x0,
|
|
"JXTA Message Framing Headers", HFILL }
|
|
},
|
|
{ &hf_jxta_framing_header,
|
|
{ "Header", "jxta.framing.header", FT_NONE, BASE_NONE, NULL, 0x0,
|
|
"JXTA Message Framing Header", HFILL }
|
|
},
|
|
{ &hf_jxta_framing_header_name_length,
|
|
{ "Name Length", "jxta.framing.header.namelen", FT_UINT8, BASE_DEC, NULL, 0x0,
|
|
"JXTA Message Framing Header Name Length", HFILL }
|
|
},
|
|
{ &hf_jxta_framing_header_name,
|
|
{ "Name", "jxta.framing.header.name", FT_STRING, BASE_NONE, NULL, 0x0,
|
|
"JXTA Message Framing Header Name", HFILL }
|
|
},
|
|
{ &hf_jxta_framing_header_value_length,
|
|
{ "Value Length", "jxta.framing.header.valuelen", FT_UINT16, BASE_DEC, NULL, 0x0,
|
|
"JXTA Message Framing Header Value Length", HFILL }
|
|
},
|
|
{ &hf_jxta_framing_header_value,
|
|
{ "Value", "jxta.framing.header.value", FT_BYTES, BASE_HEX, NULL, 0x0,
|
|
"JXTA Message Framing Header Value", HFILL }
|
|
},
|
|
{ &hf_jxta_message,
|
|
{ "JXTA Message", "jxta.message", FT_NONE, BASE_NONE, NULL, 0x0,
|
|
"JXTA Message", HFILL }
|
|
},
|
|
{ &hf_jxta_message_sig,
|
|
{ "Signature", "jxta.message.signature", FT_STRING, BASE_NONE, NULL, 0x0,
|
|
"JXTA Message Signature", HFILL }
|
|
},
|
|
{ &hf_jxta_message_version,
|
|
{ "Version", "jxta.message.version", FT_UINT8, BASE_DEC, NULL, 0x0,
|
|
"JXTA Message Version", HFILL }
|
|
},
|
|
{ &hf_jxta_message_namespaces_count,
|
|
{ "Namespace Count", "jxta.message.namespaces", FT_UINT16, BASE_DEC, NULL, 0x0,
|
|
"JXTA Message Namespaces", HFILL }
|
|
},
|
|
{ &hf_jxta_message_namespace_len,
|
|
{ "Namespace Name Length", "jxta.message.namespace.len", FT_UINT16, BASE_DEC, NULL, 0x0,
|
|
"JXTA Message Namespace Name Length", HFILL }
|
|
},
|
|
{ &hf_jxta_message_namespace_name,
|
|
{ "Namespace Name", "jxta.message.namespace.name", FT_STRING, BASE_NONE, NULL, 0x0,
|
|
"JXTA Message Namespace Name", HFILL }
|
|
},
|
|
{ &hf_jxta_message_element_count,
|
|
{ "Element Count", "jxta.message.elements", FT_UINT16, BASE_DEC, NULL, 0x0,
|
|
"JXTA Message Element Count", HFILL }
|
|
},
|
|
{ &hf_jxta_element,
|
|
{ "JXTA Message Element", "jxta.message.element", FT_NONE, BASE_NONE, NULL, 0x0,
|
|
"JXTA Message Element", HFILL }
|
|
},
|
|
{ &hf_jxta_element_sig,
|
|
{ "Signature", "jxta.message.element.signature", FT_STRING, BASE_NONE, NULL, 0x0,
|
|
"JXTA Message Element Signature", HFILL }
|
|
},
|
|
{ &hf_jxta_element_namespaceid,
|
|
{ "Namespace ID", "jxta.message.element.namespaceid", FT_UINT8, BASE_DEC, NULL, 0x0,
|
|
"JXTA Message Element Namespace ID", HFILL }
|
|
},
|
|
|
|
/* TODO 20050104 bondolo This should be a bitfield */
|
|
|
|
{ &hf_jxta_element_flags,
|
|
{ "Flags", "jxta.message.element.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
|
|
"JXTA Message Element Flags", HFILL }
|
|
},
|
|
{ &hf_jxta_element_flag_hasType,
|
|
{ "hasType", "jxta.message.element.flags.hasType", FT_BOOLEAN, 3, TFS(&boolstringname), 0x01,
|
|
"JXTA Message Element Flag -- hasType", HFILL }
|
|
},
|
|
{ &hf_jxta_element_flag_hasEncoding,
|
|
{ "hasEncoding", "jxta.message.element.flags.hasEncoding", FT_BOOLEAN, 3, TFS(&boolstringname), 0x02,
|
|
"JXTA Message Element Flag -- hasEncoding", HFILL }
|
|
},
|
|
{ &hf_jxta_element_flag_hasSignature,
|
|
{ "hasSignature", "jxta.message.element.flags.hasSignature", FT_BOOLEAN, 3, TFS(&boolstringname), 0x04,
|
|
"JXTA Message Element Flag -- hasSignature", HFILL }
|
|
},
|
|
{ &hf_jxta_element_name_len,
|
|
{ "Element Name Length", "jxta.message.element.name.length", FT_UINT16, BASE_DEC, NULL, 0x0,
|
|
"JXTA Message Element Name Length", HFILL }
|
|
},
|
|
{ &hf_jxta_element_name,
|
|
{ "Element Name", "jxta.message.element.name", FT_STRING, BASE_NONE, NULL, 0x0,
|
|
"JXTA Message Element Name", HFILL }
|
|
},
|
|
{ &hf_jxta_element_type_len,
|
|
{ "Element Type Length", "jxta.message.element.type.length", FT_UINT16, BASE_DEC, NULL, 0x0,
|
|
"JXTA Message Element Name Length", HFILL }
|
|
},
|
|
{ &hf_jxta_element_type,
|
|
{ "Element Type", "jxta.message.element.type", FT_STRING, BASE_NONE, NULL, 0x0,
|
|
"JXTA Message Element Name", HFILL }
|
|
},
|
|
{ &hf_jxta_element_encoding_len,
|
|
{ "Element Type Length", "jxta.message.element.encoding.length", FT_UINT16, BASE_DEC, NULL, 0x0,
|
|
"JXTA Message Element Encoding Length", HFILL }
|
|
},
|
|
{ &hf_jxta_element_encoding,
|
|
{ "Element Type", "jxta.message.element.encoding", FT_STRING, BASE_NONE, NULL, 0x0,
|
|
"JXTA Message Element Encoding", HFILL }
|
|
},
|
|
{ &hf_jxta_element_content_len,
|
|
{ "Element Content Length", "jxta.message.element.content.length", FT_UINT32, BASE_DEC, NULL, 0x0,
|
|
"JXTA Message Element Content Length", HFILL }
|
|
},
|
|
{ &hf_jxta_element_content,
|
|
{ "Element Content", "jxta.message.element.content", FT_BYTES, BASE_HEX, NULL, 0x0,
|
|
"JXTA Message Element Content", HFILL }
|
|
},
|
|
};
|
|
|
|
/** setup protocol subtree array */
|
|
static gint * const ett[] = {
|
|
&ett_jxta_welcome,
|
|
&ett_jxta_udp,
|
|
&ett_jxta_framing,
|
|
&ett_jxta_framing_header,
|
|
&ett_jxta_msg,
|
|
&ett_jxta_elem,
|
|
&ett_jxta_elem_flags
|
|
};
|
|
|
|
static int gUDP_MULTICAST_PORT_JXTA = 1234;
|
|
static int gHTTP_PORT_JXTA = 9700;
|
|
static int gTCP_PORT_JXTA = 9701;
|
|
|
|
static int regUDP_MULTICAST_PORT_JXTA = -1;
|
|
static int regHTTP_PORT_JXTA = -1;
|
|
static int regTCP_PORT_JXTA = -1;
|
|
|
|
|
|
static void dissect_jxta_framing(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
|
|
|
|
static void dissect_jxta_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
|
|
|
|
void proto_reg_handoff_jxta(void);
|
|
|
|
/**
|
|
Dissect a tvbuff containing a JXTA UDP header, JXTA Message framing and a JXTA Message
|
|
**/
|
|
static void dissect_jxta_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
|
|
proto_tree *jxta_udp_tree = NULL;
|
|
proto_item *jxta_udp_tree_item;
|
|
proto_item *signature_item = NULL;
|
|
|
|
if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "JXTA");
|
|
}
|
|
|
|
if (check_col(pinfo->cinfo, COL_INFO)) {
|
|
/*
|
|
* bondolo For now just say its a message. eventually put in dest addr.
|
|
* XXX - if "dest addr" means the IP destination address, that's
|
|
* already going to be in the "destination address" column if you're
|
|
* displaying that.
|
|
*/
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "%s", "UDP Message");
|
|
}
|
|
|
|
if (tree) {
|
|
jxta_udp_tree_item = proto_tree_add_item(tree, hf_jxta_udp, tvb, 0, -1, FALSE);
|
|
jxta_udp_tree = proto_item_add_subtree(jxta_udp_tree_item, ett_jxta_udp);
|
|
|
|
signature_item = proto_tree_add_item( jxta_udp_tree, hf_jxta_udpsig, tvb, 0, sizeof(JXTA_UDP_SIG), FALSE );
|
|
}
|
|
|
|
if( tvb_memeql(tvb, 0, JXTA_UDP_SIG, sizeof(JXTA_UDP_SIG)) == 0 ) {
|
|
tvbuff_t* jxta_framed_message_tvb = tvb_new_subset( tvb, sizeof(JXTA_UDP_SIG), -1, -1 );
|
|
|
|
dissect_jxta_framing( jxta_framed_message_tvb, pinfo, jxta_udp_tree );
|
|
} else {
|
|
if( tree ) {
|
|
proto_item_append_text(signature_item, " * BAD *" );
|
|
}
|
|
}
|
|
}
|
|
|
|
static void dissect_jxta_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
|
|
dissect_jxta_message( tvb, pinfo, tree );
|
|
}
|
|
|
|
static void dissect_jxta_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
|
|
/* XXX this is broken.
|
|
you MUST provide a header dissector and not NULL
|
|
the header dissector MUST do heuristict to verify it really is a
|
|
proper jxta header.
|
|
you SHOULD also specify desegmentation as a variable and not always TRUE
|
|
tcp_dissect_pdus(tvb, pinfo, tree, TRUE, 0, NULL, dissect_jxta_tcp_pdu);
|
|
*/
|
|
dissect_jxta_tcp_pdu(tvb, pinfo, tree);
|
|
}
|
|
|
|
/**
|
|
Dissect a tvbuff containing a JXTA Message framing and a JXTA Message
|
|
**/
|
|
static void dissect_jxta_framing(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
|
|
proto_item *framing_tree_item = NULL;
|
|
proto_tree *framing_tree = NULL;
|
|
guint offset = 0;
|
|
tvbuff_t* jxta_message_tvb;
|
|
|
|
if (tree) {
|
|
framing_tree_item = proto_tree_add_item(tree, hf_jxta_framing, tvb, 0, -1, FALSE);
|
|
framing_tree = proto_item_add_subtree(framing_tree_item, ett_jxta_framing);
|
|
}
|
|
|
|
/* parse framing headers */
|
|
do {
|
|
guint8 headernamelen = tvb_get_guint8( tvb, offset );
|
|
proto_item *framing_header_tree_item = NULL;
|
|
proto_tree *framing_header_tree = NULL;
|
|
|
|
if(tree) {
|
|
framing_header_tree_item = proto_tree_add_item(framing_tree, hf_jxta_framing_header, tvb, 0, -1, FALSE);
|
|
framing_header_tree = proto_item_add_subtree(framing_header_tree_item, ett_jxta_framing_header);
|
|
|
|
proto_tree_add_item( framing_header_tree, hf_jxta_framing_header_name_length, tvb, offset, 1, headernamelen );
|
|
}
|
|
|
|
if( tree && (headernamelen != 0) ) {
|
|
/*
|
|
* Put header name into protocol tree.
|
|
*/
|
|
guint8* headername = tvb_memdup( tvb, offset + 1, headernamelen );
|
|
|
|
proto_item_append_text(framing_header_tree_item, " \"%*.*s\"", headernamelen, headernamelen, headername );
|
|
|
|
proto_tree_add_item(framing_header_tree, hf_jxta_framing_header_name, tvb, offset+1, headernamelen, FALSE);
|
|
|
|
free(headername);
|
|
}
|
|
|
|
offset += 1 + headernamelen;
|
|
|
|
if( headernamelen > 0 ) {
|
|
guint16 headervaluelen = tvb_get_ntohs( tvb, offset );
|
|
|
|
if( tree ) {
|
|
proto_tree_add_uint(framing_header_tree, hf_jxta_framing_header_value_length, tvb, offset, 2, headervaluelen );
|
|
|
|
/** TODO bondolo Add specific handling for known header types */
|
|
|
|
/*
|
|
* Put header value into protocol tree.
|
|
*/
|
|
proto_tree_add_item(framing_header_tree, hf_jxta_framing_header_value, tvb, offset+2, headervaluelen, FALSE );
|
|
}
|
|
|
|
offset += 2 + headervaluelen;
|
|
}
|
|
|
|
if( tree ) {
|
|
proto_item_set_end( framing_header_tree_item, tvb, offset );
|
|
}
|
|
|
|
if( 0 == headernamelen ) {
|
|
break;
|
|
}
|
|
} while( TRUE );
|
|
|
|
if( tree ) {
|
|
proto_item_set_end( framing_tree_item, tvb, offset );
|
|
}
|
|
|
|
jxta_message_tvb = tvb_new_subset( tvb, offset, -1, -1 );
|
|
|
|
/* Call it a new layer and pass the tree as we got it */
|
|
dissect_jxta_message( jxta_message_tvb, pinfo, tree );
|
|
}
|
|
|
|
/**
|
|
Dissect a tvbuff containing a JXTA Message
|
|
**/
|
|
static void dissect_jxta_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
|
|
proto_tree *jxta_tree = NULL;
|
|
proto_item *ti;
|
|
unsigned int offset = 0;
|
|
|
|
if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "JXTA");
|
|
}
|
|
|
|
if (check_col(pinfo->cinfo, COL_INFO)) {
|
|
/*
|
|
* TODO bondolo For now just say its a message. eventually put in dest addr.
|
|
* XXX - if "dest addr" means the IP destination address, that's
|
|
* already going to be in the "destination address" column if you're
|
|
* displaying that.
|
|
*/
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "%s", "Message");
|
|
}
|
|
|
|
if (tree) {
|
|
ti = proto_tree_add_item(tree, hf_jxta_message, tvb, 0, -1, FALSE);
|
|
jxta_tree = proto_item_add_subtree(ti, ett_jxta_msg);
|
|
}
|
|
|
|
if( tree ) {
|
|
proto_tree_add_item( jxta_tree, hf_jxta_message_sig, tvb, 0, sizeof(JXTA_MSG_SIG), FALSE);
|
|
|
|
if( tvb_memeql(tvb, offset, JXTA_MSG_SIG, sizeof(JXTA_MSG_SIG)) == 0) {
|
|
guint8 messageVersion;
|
|
|
|
offset += sizeof(JXTA_MSG_SIG);
|
|
|
|
messageVersion = tvb_get_guint8( tvb, offset );
|
|
proto_tree_add_uint( jxta_tree, hf_jxta_message_version, tvb, offset, sizeof(guint8), messageVersion );
|
|
offset += sizeof(guint8);
|
|
|
|
if( 0 == messageVersion ) {
|
|
int eachNamespace;
|
|
guint16 numberOfElements;
|
|
guint16 messageNamespaceCount = tvb_get_ntohs( tvb, offset );
|
|
char **namespaces = calloc( messageNamespaceCount + 2, sizeof(char *) );
|
|
|
|
offset += sizeof(guint16);
|
|
namespaces[0] = "";
|
|
namespaces[1] = "jxta";
|
|
|
|
proto_tree_add_uint( jxta_tree, hf_jxta_message_namespaces_count, tvb, offset, sizeof(guint16), messageNamespaceCount );
|
|
|
|
/* parse namespaces */
|
|
/* TODO 20050103 bondolo Should record the namespaces and number them. */
|
|
for( eachNamespace = 0; eachNamespace < messageNamespaceCount; eachNamespace++ ) {
|
|
guint8 namespaceLen = tvb_get_guint8( tvb, offset );
|
|
|
|
proto_tree_add_uint(jxta_tree, hf_jxta_message_namespace_len, tvb, offset++, namespaceLen, namespaceLen );
|
|
|
|
proto_tree_add_item(jxta_tree, hf_jxta_message_namespace_name, tvb, offset, namespaceLen, FALSE);
|
|
|
|
namespaces[2 + eachNamespace] = calloc( namespaceLen + 1, sizeof(char *) );
|
|
|
|
tvb_memcpy( tvb, namespaces[2 + eachNamespace], offset, namespaceLen );
|
|
|
|
offset += namespaceLen;
|
|
}
|
|
|
|
/* parse elements */
|
|
numberOfElements = tvb_get_ntohs( tvb, offset );
|
|
proto_tree_add_item(jxta_tree, hf_jxta_message_element_count, tvb, offset, sizeof(guint16), FALSE );
|
|
offset += sizeof(guint16);
|
|
|
|
while( offset < tvb_reported_length(tvb) ) {
|
|
proto_tree *jxta_elem_tree = NULL;
|
|
proto_item *elem_ti;
|
|
|
|
elem_ti = proto_tree_add_item(jxta_tree, hf_jxta_element, tvb, offset, -1, FALSE);
|
|
jxta_elem_tree = proto_item_add_subtree(elem_ti, ett_jxta_elem);
|
|
|
|
/* gross hack for parsing of signature element */
|
|
element_parse :
|
|
{
|
|
proto_tree_add_item( jxta_elem_tree, hf_jxta_element_sig, tvb, offset, sizeof(JXTA_MSGELEM_SIG), FALSE );
|
|
if( tvb_memeql(tvb, offset, JXTA_MSGELEM_SIG, sizeof(JXTA_MSGELEM_SIG)) == 0 ) {
|
|
guint8 namespaceID;
|
|
guint8 flags;
|
|
guint16 nameLen;
|
|
guint32 elemContentLength;
|
|
proto_item *namespace_ti;
|
|
proto_item *flags_ti;
|
|
proto_tree *jxta_elem_flags_tree = NULL;
|
|
|
|
offset += sizeof(JXTA_MSGELEM_SIG);
|
|
|
|
namespaceID = tvb_get_guint8( tvb, offset );
|
|
namespace_ti = proto_tree_add_uint( jxta_elem_tree, hf_jxta_element_namespaceid, tvb, offset, sizeof(guint8), namespaceID );
|
|
if( namespaceID <= (messageNamespaceCount + 2) ) {
|
|
proto_item_append_text(namespace_ti, " (%s)", namespaces[namespaceID] );
|
|
} else {
|
|
proto_item_append_text(namespace_ti, " * BAD *" );
|
|
}
|
|
offset += sizeof(guint8);
|
|
|
|
flags = tvb_get_guint8( tvb, offset );
|
|
flags_ti = proto_tree_add_uint( jxta_elem_tree, hf_jxta_element_flags, tvb, offset, sizeof(guint8), flags );
|
|
jxta_elem_flags_tree = proto_item_add_subtree(flags_ti, ett_jxta_elem_flags);
|
|
proto_tree_add_boolean(jxta_elem_flags_tree, hf_jxta_element_flag_hasType, tvb, offset, 1, flags);
|
|
proto_tree_add_boolean(jxta_elem_flags_tree, hf_jxta_element_flag_hasEncoding, tvb, offset, 1, flags);
|
|
proto_tree_add_boolean(jxta_elem_flags_tree, hf_jxta_element_flag_hasSignature, tvb, offset, 1, flags);
|
|
offset += sizeof(guint8);
|
|
|
|
nameLen = tvb_get_ntohs( tvb, offset );
|
|
proto_tree_add_uint( jxta_elem_tree, hf_jxta_element_name_len, tvb, offset, sizeof(guint16), nameLen );
|
|
offset += sizeof(guint16);
|
|
|
|
proto_tree_add_item(jxta_elem_tree, hf_jxta_element_name, tvb, offset, nameLen, FALSE);
|
|
|
|
offset += nameLen;
|
|
|
|
/* process type */
|
|
if( (flags & 0x01) != 0 ) {
|
|
guint16 typeLen = tvb_get_ntohs( tvb, offset );
|
|
proto_tree_add_uint( jxta_elem_tree, hf_jxta_element_type_len, tvb, offset, sizeof(guint16), typeLen );
|
|
offset += sizeof(guint16);
|
|
|
|
proto_tree_add_item(jxta_elem_tree, hf_jxta_element_type, tvb, offset, typeLen, FALSE);
|
|
|
|
offset += typeLen;
|
|
}
|
|
|
|
/* process encoding */
|
|
if( (flags & 0x02) != 0 ) {
|
|
guint16 encodingLen = tvb_get_ntohs( tvb, offset );
|
|
ti = proto_tree_add_item( jxta_elem_tree, hf_jxta_element_encoding_len, tvb, offset, sizeof(guint16), FALSE );
|
|
offset += sizeof(guint16);
|
|
|
|
proto_tree_add_item(jxta_elem_tree, hf_jxta_element_encoding, tvb, offset, encodingLen, FALSE);
|
|
|
|
offset += encodingLen;
|
|
}
|
|
|
|
/* content */
|
|
elemContentLength = tvb_get_ntohl( tvb, offset );
|
|
ti = proto_tree_add_item( jxta_elem_tree, hf_jxta_element_content_len, tvb, offset, sizeof(guint32), FALSE );
|
|
offset += sizeof(guint32);
|
|
|
|
ti = proto_tree_add_item( jxta_elem_tree, hf_jxta_element_content, tvb, offset, elemContentLength, FALSE );
|
|
offset += elemContentLength;
|
|
|
|
/* XXX Evil Hack Warning : handle parsing of signature element. Would be better with recursion.*/
|
|
if( (flags & 0x04) != 0 ) {
|
|
goto element_parse;
|
|
}
|
|
}
|
|
|
|
proto_item_set_end( elem_ti, tvb, offset );
|
|
}
|
|
}
|
|
|
|
for( eachNamespace = 2; eachNamespace < messageNamespaceCount; eachNamespace++ ) {
|
|
free( namespaces[eachNamespace] );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void proto_register_jxta(void)
|
|
{
|
|
module_t *jxta_module;
|
|
|
|
proto_jxta = proto_register_protocol("JXTA P2P", "JXTA", "jxta");
|
|
|
|
/* Register header fields */
|
|
proto_register_field_array(proto_jxta, hf, array_length(hf));
|
|
|
|
/* Register JXTA Sub-tree */
|
|
proto_register_subtree_array(ett, array_length(ett));
|
|
|
|
/* Register preferences */
|
|
jxta_module = prefs_register_protocol(proto_jxta, proto_reg_handoff_jxta);
|
|
|
|
prefs_register_uint_preference(jxta_module, "tcp.port", "JXTA TCP Port",
|
|
"Set the port for JXTA TCP messages",
|
|
10, &gTCP_PORT_JXTA);
|
|
|
|
prefs_register_uint_preference(jxta_module, "http.port", "JXTA HTTP Port",
|
|
"Set the port for JXTA HTTP messages",
|
|
10, &gHTTP_PORT_JXTA);
|
|
|
|
prefs_register_uint_preference(jxta_module, "udp.port", "JXTA UDP Multicast Port",
|
|
"Set the port for JXTA UDP Multicast messages",
|
|
10, &gUDP_MULTICAST_PORT_JXTA);
|
|
}
|
|
|
|
void proto_reg_handoff_jxta(void) {
|
|
static gboolean jxta_prefs_initialized = FALSE;
|
|
|
|
if (!jxta_prefs_initialized) {
|
|
udpm_jxta_handle = create_dissector_handle(dissect_jxta_udp, proto_jxta);
|
|
tcp_jxta_handle = create_dissector_handle(dissect_jxta_tcp, proto_jxta);
|
|
http_jxta_handle = create_dissector_handle(dissect_jxta_message, proto_jxta);
|
|
|
|
jxta_prefs_initialized = TRUE;
|
|
} else {
|
|
dissector_delete("udp.port", regUDP_MULTICAST_PORT_JXTA, udpm_jxta_handle);
|
|
|
|
dissector_delete("tcp.port", regTCP_PORT_JXTA, tcp_jxta_handle);
|
|
|
|
dissector_delete("http.port", regHTTP_PORT_JXTA, http_jxta_handle);
|
|
}
|
|
|
|
/* remember what ports we registered on for later removal */
|
|
regUDP_MULTICAST_PORT_JXTA = gUDP_MULTICAST_PORT_JXTA;
|
|
regTCP_PORT_JXTA = gTCP_PORT_JXTA;
|
|
regHTTP_PORT_JXTA = gHTTP_PORT_JXTA;
|
|
|
|
/* register as a sub-dissector of UDP tagged on port field */
|
|
dissector_add("udp.port", regUDP_MULTICAST_PORT_JXTA, udpm_jxta_handle);
|
|
|
|
/* register as a sub-dissector of TCP tagged on port field*/
|
|
dissector_add("tcp.port", regTCP_PORT_JXTA, tcp_jxta_handle);
|
|
|
|
/* register as a sub-dissector of HTTP tagged on port field */
|
|
dissector_add("http.port", regHTTP_PORT_JXTA, http_jxta_handle);
|
|
}
|