MSWSP: add ids for another unknown Property Set
[wireshark-wip.git] / epan / dissectors / packet-jxta.c
blob46851153b3cc0b5f64c7299dfbfac7184d31bc80
1 /* packet-jxta.c
3 * Routines for JXTA packet dissection
4 * JXTA specification from https://jxta-spec.dev.java.net
6 * Copyright 2004-08, Mike Duigou <bondolo@dev.java.net>
8 * Heavily based on packet-jabber.c, which in turn is heavily based on
9 * on packet-acap.c, which in turn is heavily based on
10 * packet-imap.c, Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
11 * Copied from packet-pop.c, packet-jabber.c, packet-udp.c, packet-http.c
13 * $Id$
15 * Wireshark - Network traffic analyzer
16 * By Gerald Combs <gerald@wireshark.org>
17 * Copyright 2000 Gerald Combs
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version 2
22 * of the License, or (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
34 #include "config.h"
36 #define G_LOG_DOMAIN "jxta"
38 #include <glib.h>
40 #include <wsutil/str_util.h>
42 #include <epan/packet.h>
43 #include <epan/conversation.h>
44 #include <epan/strutil.h>
45 #include <epan/prefs.h>
46 #include <epan/tap.h>
47 #include <epan/wmem/wmem.h>
49 #include "packet-jxta.h"
51 #define JXTA_UDP_MAGIC 0x4a5a5441 /* JXTA */
52 static const gchar JXTA_UDP_SIG[] = { 'J', 'X', 'T', 'A' };
53 static const gchar JXTA_MSG_SIG[] = { 'j', 'x', 'm', 'g' };
54 static const gchar JXTA_MSGELEM_SIG[] = { 'j', 'x', 'e', 'l' };
56 static const gchar JXTA_WELCOME_MSG_SIG[] = { 'J', 'X', 'T', 'A', 'H', 'E', 'L', 'L', 'O', ' ' };
58 static const gchar* JXTA_WELCOME_MSG_VERSION_1_1 = "1.1";
59 static const gchar* JXTA_WELCOME_MSG_VERSION_3_0 = "3.0";
61 static const int JXTA_MSG_VERSION_1 = 0;
62 static const int JXTA_MSG_VERSION_2 = 1;
64 static const int JXTAMSG1_ELMFLAG_TYPE = 1 << 0;
65 static const int JXTAMSG1_ELMFLAG_ENCODING = 1 << 1;
66 static const int JXTAMSG1_ELMFLAG_SIGNATURE = 1 << 2;
68 static const int JXTAMSG2_ELMFLAG_UINT64_LENS = 1 << 0;
69 static const int JXTAMSG2_ELMFLAG_NAME_LITERAL = 1 << 1;
70 static const int JXTAMSG2_ELMFLAG_TYPE = 1 << 2;
71 static const int JXTAMSG2_ELMFLAG_SIGNATURE = 1 << 3;
72 static const int JXTAMSG2_ELMFLAG_ENCODINGS = 1 << 4;
74 static int proto_jxta = -1;
75 static int proto_message_jxta = -1;
76 static int jxta_tap = -1;
78 static dissector_table_t media_type_dissector_table = NULL;
79 static dissector_handle_t media_handle = NULL;
80 static dissector_handle_t data_handle = NULL;
81 static dissector_handle_t stream_jxta_handle = NULL;
83 static int hf_uri_addr = -1;
84 static int hf_uri_src = -1;
85 static int hf_uri_dst = -1;
86 static int hf_jxta_udp = -1;
87 static int hf_jxta_udpsig = -1;
88 static int hf_jxta_welcome = -1;
89 static int hf_jxta_welcome_initiator = -1;
90 static int hf_jxta_welcome_sig = -1;
91 static int hf_jxta_welcome_destAddr = -1;
92 static int hf_jxta_welcome_pubAddr = -1;
93 static int hf_jxta_welcome_peerid = -1;
94 static int hf_jxta_welcome_noProp = -1;
95 static int hf_jxta_welcome_msgVers = -1;
96 static int hf_jxta_welcome_variable = -1;
97 static int hf_jxta_welcome_version = -1;
98 static int hf_jxta_framing = -1;
99 static int hf_jxta_framing_header = -1;
100 static int hf_jxta_framing_header_name = -1;
101 static int hf_jxta_framing_header_value_length = -1;
102 static int hf_jxta_framing_header_value = -1;
103 static int hf_jxta_message_address = -1;
104 static int hf_jxta_message_src = -1;
105 static int hf_jxta_message_dst = -1;
106 static int hf_jxta_message_sig = -1;
107 static int hf_jxta_message_version = -1;
108 static int hf_jxta_message_flags = -1;
109 static int hf_jxta_message_flag_utf16be = -1;
110 static int hf_jxta_message_flag_ucs32be = -1;
111 static int hf_jxta_message_names_count = -1;
112 static int hf_jxta_message_names_name = -1;
113 static int hf_jxta_message_element_count = -1;
114 static int hf_jxta_element = -1;
115 static int hf_jxta_element_sig = -1;
116 static int hf_jxta_element1_namespaceid = -1;
117 static int hf_jxta_element2_namespaceid = -1;
118 static int hf_jxta_element2_nameid = -1;
119 static int hf_jxta_element2_mimeid = -1;
120 static int hf_jxta_element2_encodingid = -1;
121 static int hf_jxta_element_flags = -1;
122 static int hf_jxta_element1_flag_hasType = -1;
123 static int hf_jxta_element1_flag_hasEncoding = -1;
124 static int hf_jxta_element1_flag_hasSignature = -1;
125 static int hf_jxta_element2_flag_64bitlens = -1;
126 static int hf_jxta_element2_flag_nameLiteral = -1;
127 static int hf_jxta_element2_flag_hasType = -1;
128 static int hf_jxta_element2_flag_hasSignature = -1;
129 static int hf_jxta_element2_flag_hasEncoding = -1;
130 static int hf_jxta_element2_flag_sigOfEncoded = -1;
131 static int hf_jxta_element_name = -1;
132 static int hf_jxta_element_type = -1;
133 static int hf_jxta_element_encoding = -1;
134 static int hf_jxta_element_content_len = -1;
135 static int hf_jxta_element_content_len64 = -1;
136 /* static int hf_jxta_element_content = -1; */
139 * JXTA Protocol subtree handles
141 static gint ett_jxta = -1;
142 static gint ett_jxta_welcome = -1;
143 static gint ett_jxta_udp = -1;
144 static gint ett_jxta_framing = -1;
145 static gint ett_jxta_framing_header = -1;
146 static gint ett_jxta_msg = -1;
147 static gint ett_jxta_msg_flags = -1;
148 static gint ett_jxta_elem = -1;
149 static gint ett_jxta_elem_1_flags = -1;
150 static gint ett_jxta_elem_2_flags = -1;
153 * JXTA Protocol subtree array
155 static gint *const ett[] = {
156 &ett_jxta,
157 &ett_jxta_welcome,
158 &ett_jxta_udp,
159 &ett_jxta_framing,
160 &ett_jxta_framing_header,
161 &ett_jxta_msg,
162 &ett_jxta_msg_flags,
163 &ett_jxta_elem,
164 &ett_jxta_elem_1_flags,
165 &ett_jxta_elem_2_flags
169 * global preferences
171 static gboolean gDESEGMENT = TRUE;
172 static gboolean gUDP_HEUR = TRUE;
173 static gboolean gTCP_HEUR = TRUE;
174 static gboolean gSCTP_HEUR = TRUE;
175 static gboolean gMSG_MEDIA = TRUE;
178 * Stream Conversation data
180 struct jxta_stream_conversation_data {
181 port_type tpt_ptype;
183 address initiator_tpt_address;
184 guint32 initiator_tpt_port;
185 guint32 initiator_welcome_frame;
186 address initiator_address;
188 address receiver_tpt_address;
189 guint32 receiver_tpt_port;
190 guint32 receiver_welcome_frame;
191 address receiver_address;
194 typedef struct jxta_stream_conversation_data jxta_stream_conversation_data;
197 * Prototypes
199 static int dissect_jxta_udp(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data);
200 static int dissect_jxta_stream(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data);
201 static jxta_stream_conversation_data *get_tpt_conversation(packet_info * pinfo);
202 static conversation_t *get_peer_conversation(packet_info * pinfo, jxta_stream_conversation_data* tpt_conv_data, gboolean create);
204 static int dissect_jxta_welcome(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, address * found_addr, gboolean initiator);
205 static int dissect_jxta_message_framing(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, guint64 * content_length,
206 gchar ** content_type);
207 static int dissect_jxta_message(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data);
208 static int dissect_jxta_message_element_1(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, guint ns_count,
209 const gchar ** namespaces);
210 static int dissect_jxta_message_element_2(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, guint ns_count,
211 const gchar ** namespaces);
212 static int dissect_media( const gchar* fullmediatype, tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree);
214 void proto_reg_handoff_jxta(void);
217 * Heuristically dissect a tvbuff containing a JXTA UDP Message
219 * @param tvb The buffer to dissect.
220 * @param pinfo Packet Info.
221 * @param tree The protocol tree.
222 * @return TRUE if the tvb contained JXTA data which was dissected otherwise FALSE
224 static gboolean dissect_jxta_UDP_heur(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data _U_)
226 /* This is a heuristic dissector, which means we get all the UDP
227 * traffic not sent to a known dissector and not claimed by
228 * a heuristic dissector called before us!
230 int save_desegment_offset;
231 guint32 save_desegment_len;
232 int ret;
233 guint32 magic;
235 magic = tvb_get_ntohl(tvb,0);
236 if(magic != JXTA_UDP_MAGIC){
237 /* Not a JXTA UDP packet. */
238 return FALSE;
241 save_desegment_offset = pinfo->desegment_offset;
242 save_desegment_len = pinfo->desegment_len;
243 ret = dissect_jxta_udp(tvb, pinfo, tree, NULL);
245 /* g_message( "%d Heuristic UDP Dissection : %d", pinfo->fd->num, ret ); */
247 if (ret < 0) {
249 * UDP is not a packet stream protocol, so the UDP dissector
250 * should not, and will not, do the sort of dissection help
251 * that the TCP dissector will. If JXTA messages don't
252 * start and end on UDP packet boundaries, the JXTA dissector
253 * will have to do its own byte stream reassembly.
255 pinfo->desegment_offset = save_desegment_offset;
256 pinfo->desegment_len = save_desegment_len;
257 return FALSE;
258 } else if (ret == 0) {
260 * A clear rejection.
262 pinfo->desegment_offset = save_desegment_offset;
263 pinfo->desegment_len = save_desegment_len;
264 return FALSE;
265 } else {
267 * A clear acceptance.
269 return TRUE;
274 * Heuristically dissect a tvbuff containing a JXTA TCP Stream
276 * @param tvb The buffer to dissect.
277 * @param pinfo Packet Info.
278 * @param tree The protocol tree.
279 * @return TRUE if the tvb contained JXTA data which was dissected otherwise FALSE
281 static gboolean dissect_jxta_TCP_heur(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data _U_)
283 /* This is a heuristic dissector, which means we get all the TCP
284 * traffic not sent to a known dissector and not claimed by
285 * a heuristic dissector called before us!
287 int save_desegment_offset;
288 guint32 save_desegment_len;
289 int ret;
291 save_desegment_offset = pinfo->desegment_offset;
292 save_desegment_len = pinfo->desegment_len;
293 ret = dissect_jxta_stream(tvb, pinfo, tree, NULL);
295 /* g_message( "%d Heuristic TCP Dissection : %d", pinfo->fd->num, ret ); */
297 if (ret < 0) {
299 * A heuristic dissector for a TCP-based protocol can reject
300 * a packet, or it can request that more data be provided.
301 * It must not attempt to do both, as the notion of doing both
302 * is nonsensical - if the packet isn't considered a packet
303 * for the dissector's protocol, that dissector won't be
304 * dissecting it no matter *how* much more data is added.
306 * Therefore, we treat a negative return from
307 * dissect_jxta_stream() as a rejection.
309 * If that's not desired - i.e., if we should keep trying to get
310 * more data, in the hopes that we'll eventually be able to
311 * determine whether the packet is a JXTA packet or not - we
312 * should, in this case, leave pinfo->desegment_offset and
313 * pinfo->desegment_len alone, and return TRUE, *NOT* FALSE.
315 pinfo->desegment_offset = save_desegment_offset;
316 pinfo->desegment_len = save_desegment_len;
317 return FALSE;
318 } else if (ret == 0) {
320 * A clear rejection.
322 pinfo->desegment_offset = save_desegment_offset;
323 pinfo->desegment_len = save_desegment_len;
324 return FALSE;
325 } else {
327 * A clear acceptance.
329 return TRUE;
334 * Heuristically dissect a tvbuff containing a JXTA SCTP Stream
336 * @param tvb The buffer to dissect.
337 * @param pinfo Packet Info.
338 * @param tree The protocol tree.
339 * @return TRUE if the tvb contained JXTA data which was dissected otherwise FALSE
341 static gboolean dissect_jxta_SCTP_heur(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data _U_)
343 /* This is a heuristic dissector, which means we get all the SCTP
344 * traffic not sent to a known dissector and not claimed by
345 * a heuristic dissector called before us!
347 int save_desegment_offset;
348 guint32 save_desegment_len;
349 int ret;
351 save_desegment_offset = pinfo->desegment_offset;
352 save_desegment_len = pinfo->desegment_len;
353 ret = dissect_jxta_stream(tvb, pinfo, tree, NULL);
355 /* g_message( "%d Heuristic SCTP Dissection : %d", pinfo->fd->num, ret ); */
357 if (ret < 0) {
359 * SCTP is not a byte stream protocol, so the SCTP dissector
360 * should not, and will not, do the sort of dissection help
361 * that the SCTP dissector will. If JXTA messages don't
362 * start and end on SCTP packet boundaries, the JXTA dissector
363 * will have to do its own byte stream reassembly.
365 * The SCTP dissector currently won't do reassembly. If that
366 * causes a problem for the JXTA dissector, the correct fix
367 * is to implement reassembly in the SCTP dissector, so *all*
368 * dissectors for protocols running atop SCTP can benefit from
369 * it.
371 pinfo->desegment_offset = save_desegment_offset;
372 pinfo->desegment_len = save_desegment_len;
373 return FALSE;
374 } else if (ret == 0) {
376 * A clear rejection.
378 pinfo->desegment_offset = save_desegment_offset;
379 pinfo->desegment_len = save_desegment_len;
380 return FALSE;
381 } else {
383 * A clear acceptance.
385 return TRUE;
390 * Dissect a tvbuff containing a JXTA UDP header, JXTA Message framing and a JXTA Message
392 * @param tvb The buffer to dissect.
393 * @param pinfo Packet Info.
394 * @param tree The protocol tree.
395 * @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
396 * the packet was not recognized as a JXTA packet and negative if the
397 * dissector needs more bytes in order to process a PDU.
399 static int dissect_jxta_udp(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data _U_)
401 guint offset = 0;
402 guint available;
403 gint needed = 0;
405 conversation_t *conversation = find_or_create_conversation(pinfo);
407 DISSECTOR_ASSERT(find_dissector("jxta.udp"));
409 conversation_set_dissector(conversation, find_dissector("jxta.udp"));
411 while (TRUE) {
412 tvbuff_t *jxta_message_framing_tvb;
413 gint processed = 0;
414 guint64 content_length = -1;
415 gchar *content_type = NULL;
417 available = tvb_reported_length_remaining(tvb, offset);
418 if (available < sizeof(JXTA_UDP_SIG)) {
419 needed = (gint) (sizeof(JXTA_UDP_SIG) - available);
420 break;
423 if (tvb_memeql(tvb, offset, JXTA_UDP_SIG, sizeof(JXTA_UDP_SIG)) != 0) {
424 /* not ours */
425 return 0;
428 offset += (int)sizeof(JXTA_UDP_SIG);
430 jxta_message_framing_tvb = tvb_new_subset_remaining(tvb, offset);
431 processed = dissect_jxta_message_framing(jxta_message_framing_tvb, pinfo, NULL, &content_length, &content_type);
433 if ((0 == processed) || (NULL == content_type) || (content_length <= 0) || (content_length > UINT_MAX)) {
434 /** Buffer did not begin with valid framing headers */
435 return 0;
438 if (processed < 0) {
439 needed = -processed;
440 break;
443 offset += processed;
445 available = tvb_reported_length_remaining(tvb, offset);
446 if (available < content_length) {
447 needed = (gint) (content_length - available);
448 break;
451 offset += (guint) content_length;
453 break;
456 if ((needed > 0) && gDESEGMENT && pinfo->can_desegment) {
457 /* g_message( "UDP requesting %d more bytes", needed ); */
458 pinfo->desegment_offset = 0;
459 pinfo->desegment_len = needed;
460 return -needed;
463 col_set_str(pinfo->cinfo, COL_PROTOCOL, "JXTA");
466 guint tree_offset = 0;
467 proto_item *jxta_tree_item =
468 proto_tree_add_protocol_format(tree, proto_jxta, tvb, offset, -1, "JXTA" );
469 proto_tree *jxta_tree = proto_item_add_subtree(jxta_tree_item, ett_jxta);
470 proto_item *jxta_udp_tree_item =
471 proto_tree_add_none_format(jxta_tree, hf_jxta_udp, tvb, tree_offset, -1, "JXTA UDP Message");
472 proto_tree *jxta_udp_tree = proto_item_add_subtree(jxta_udp_tree_item, ett_jxta_udp);
473 tvbuff_t *jxta_message_framing_tvb;
474 guint64 content_length = -1;
475 gchar *content_type = NULL;
476 tvbuff_t *jxta_message_tvb;
478 proto_tree_add_item(jxta_udp_tree, hf_jxta_udpsig, tvb, tree_offset, (int)sizeof(JXTA_UDP_SIG), ENC_ASCII|ENC_NA);
479 tree_offset += (int)sizeof(JXTA_UDP_SIG);
481 jxta_message_framing_tvb = tvb_new_subset_remaining(tvb, tree_offset);
483 tree_offset += dissect_jxta_message_framing(jxta_message_framing_tvb, pinfo, jxta_tree, &content_length, &content_type);
485 jxta_message_tvb = tvb_new_subset(tvb, tree_offset, (gint) content_length, (gint) content_length);
487 tree_offset += dissect_media(content_type, jxta_message_tvb, pinfo, tree);
489 proto_item_set_end(jxta_udp_tree_item, tvb, tree_offset);
491 DISSECTOR_ASSERT(offset == tree_offset);
494 return offset;
498 * Dissect a tvbuff containing JXTA stream PDUs. This commonly includes
499 * connections over TCP sockets.
501 * <p/>The stream (in both directions) will consist of a JXTA Welcome Message
502 * followed by an indeterminate number of JXTA Message Framing Headers and
503 * JXTA Messages.
505 * @param tvb The buffer to dissect.
506 * @param pinfo Packet Info.
507 * @param tree The protocol tree.
508 * @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
509 * the packet was not recognized as a JXTA packet and negative if the
510 * dissector needs more bytes in order to process a PDU.
512 static int dissect_jxta_stream(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data _U_)
514 guint offset = 0;
515 guint available = tvb_reported_length_remaining(tvb, offset);
516 gint processed = 0;
517 gint needed = 0;
518 jxta_stream_conversation_data *tpt_conv_data = NULL;
519 proto_item *jxta_tree_item = NULL;
520 proto_tree *jxta_tree = NULL;
522 /* g_message("Dissecting%s : %d", (NULL != tree) ? " for display" : "", pinfo->fd->num ); */
524 if (available < sizeof(JXTA_WELCOME_MSG_SIG)) {
525 needed = (gint) (sizeof(JXTA_WELCOME_MSG_SIG) - available);
526 goto Common_Exit;
529 if (0 == tvb_memeql(tvb, 0, JXTA_WELCOME_MSG_SIG, sizeof(JXTA_WELCOME_MSG_SIG))) {
530 /* The beginning of a JXTA stream connection */
531 address *welcome_addr;
532 gboolean initiator = FALSE;
534 tpt_conv_data = get_tpt_conversation(pinfo);
536 if (0 == tpt_conv_data->initiator_welcome_frame) {
537 /* The initiator welcome frame */
538 tpt_conv_data->tpt_ptype = pinfo->ptype;
539 tpt_conv_data->initiator_welcome_frame = pinfo->fd->num;
540 SE_COPY_ADDRESS(&tpt_conv_data->initiator_tpt_address, &pinfo->src);
541 tpt_conv_data->initiator_tpt_port = pinfo->srcport;
543 welcome_addr = &tpt_conv_data->initiator_address;
544 initiator = TRUE;
545 } else {
546 if (tpt_conv_data->initiator_welcome_frame >= pinfo->fd->num) {
547 /* what we saw previously was the receiver welcome message */
548 tpt_conv_data->receiver_welcome_frame = tpt_conv_data->initiator_welcome_frame;
549 tpt_conv_data->receiver_tpt_address = tpt_conv_data->initiator_tpt_address;
550 tpt_conv_data->receiver_tpt_port = tpt_conv_data->initiator_tpt_port;
551 tpt_conv_data->receiver_address = tpt_conv_data->initiator_address;
552 tpt_conv_data->initiator_welcome_frame = pinfo->fd->num;
553 SE_COPY_ADDRESS(&tpt_conv_data->initiator_tpt_address, &pinfo->src);
554 tpt_conv_data->initiator_tpt_port = pinfo->srcport;
556 welcome_addr = &tpt_conv_data->initiator_address;
557 initiator = TRUE;
558 } else {
559 /* The receiver welcome frame */
560 tpt_conv_data->tpt_ptype = pinfo->ptype;
561 tpt_conv_data->receiver_welcome_frame = pinfo->fd->num;
562 SE_COPY_ADDRESS(&tpt_conv_data->receiver_tpt_address, &pinfo->src);
563 tpt_conv_data->receiver_tpt_port = pinfo->srcport;
565 welcome_addr = &tpt_conv_data->receiver_address;
566 initiator = FALSE;
570 processed = dissect_jxta_welcome(tvb, pinfo, NULL, welcome_addr, initiator);
572 if( processed < 0 ) {
573 needed = -processed;
574 goto Common_Exit;
577 /* redo, this time creating the display tree. */
578 jxta_tree_item = proto_tree_add_protocol_format(tree, proto_jxta, tvb, offset, -1, "JXTA" );
579 jxta_tree = proto_item_add_subtree(jxta_tree_item, ett_jxta);
581 processed = dissect_jxta_welcome(tvb, pinfo, jxta_tree, welcome_addr, initiator);
582 } else {
583 /* Somewhere in the middle of a JXTA stream connection */
584 gint64 content_length = -1L;
585 gchar *content_type = NULL;
586 gint headers_len = dissect_jxta_message_framing(tvb, pinfo, NULL, (guint64*) &content_length, &content_type);
588 if ((0 == headers_len) || (NULL == content_type) || (content_length <= 0) || (content_length > UINT_MAX)) {
589 /** Buffer did not begin with valid framing headers */
590 return 0;
593 /* g_message("%d Tpt %s:%d -> %s:%d tvb len=%d\n\t%s %d", pinfo->fd->num,
594 ep_address_to_str(&pinfo->src), pinfo->srcport,
595 ep_address_to_str(&pinfo->dst), pinfo->destport,
596 tvb_reported_length_remaining(tvb, 0),
597 content_type ? content_type : "[unknown content type]", (gint) content_length); */
599 if (headers_len < 0) {
600 /* negative headers_len means we need more bytes */
601 needed = -headers_len;
602 goto Common_Exit;
605 available = tvb_reported_length_remaining(tvb, offset + headers_len);
606 if (available >= content_length) {
607 tvbuff_t *jxta_message_tvb = tvb_new_subset(tvb, offset + headers_len, (gint) content_length, (gint) content_length);
608 conversation_t *peer_conversation = NULL;
610 jxta_tree_item = proto_tree_add_protocol_format(tree, proto_jxta, tvb, offset, -1, "JXTA" );
611 jxta_tree = proto_item_add_subtree(jxta_tree_item, ett_jxta);
613 /* Redo header processing, this time populating the tree. */
614 headers_len = dissect_jxta_message_framing(tvb, pinfo, jxta_tree, &content_length, &content_type);
616 tpt_conv_data = get_tpt_conversation(pinfo);
617 peer_conversation = get_peer_conversation(pinfo, tpt_conv_data, TRUE);
619 /* Use our source and destination addresses if we have them */
620 if (NULL != peer_conversation) {
621 /* g_message("%d Tpt %s:%d -> %s:%d", pinfo->fd->num,
622 ep_address_to_str(&tpt_conv_data->initiator_tpt_address), tpt_conv_data->initiator_tpt_port,
623 ep_address_to_str(&tpt_conv_data->receiver_tpt_address), tpt_conv_data->receiver_tpt_port); */
625 if (ADDRESSES_EQUAL(&pinfo->src, &tpt_conv_data->initiator_tpt_address)
626 && tpt_conv_data->initiator_tpt_port == pinfo->srcport) {
627 /* g_message("%d From initiator : %s -> %s ", pinfo->fd->num,
628 ep_address_to_str(&tpt_conv_data->initiator_address),
629 ep_address_to_str(&tpt_conv_data->receiver_address)); */
630 pinfo->src = tpt_conv_data->initiator_address;
631 pinfo->srcport = 0;
632 pinfo->dst = tpt_conv_data->receiver_address;
633 pinfo->destport = 0;
634 pinfo->ptype = PT_NONE;
635 } else if (ADDRESSES_EQUAL(&pinfo->src, &tpt_conv_data->receiver_tpt_address) &&
636 tpt_conv_data->receiver_tpt_port == pinfo->srcport) {
637 /* g_message("%d From receiver : %s -> %s ", pinfo->fd->num,
638 ep_address_to_str(&tpt_conv_data->receiver_address),
639 ep_address_to_str(&tpt_conv_data->initiator_address)); */
640 pinfo->src = tpt_conv_data->receiver_address;
641 pinfo->srcport = 0;
642 pinfo->dst = tpt_conv_data->initiator_address;
643 pinfo->destport = 0;
644 pinfo->ptype = PT_NONE;
645 } else {
646 /* g_message("%d Nothing matches %s:%d -> %s:%d", pinfo->fd->num,
647 ep_address_to_str(&pinfo->src), pinfo->srcport,
648 ep_address_to_str(&pinfo->dst), pinfo->destport); */
652 processed = headers_len;
654 processed += dissect_media(content_type, jxta_message_tvb, pinfo, tree);
655 } else {
656 /* we need more bytes before we can process message body. */
657 needed = (gint) ((guint) content_length - available);
658 goto Common_Exit;
662 offset += processed;
664 Common_Exit:
665 if ((needed > 0) && gDESEGMENT && pinfo->can_desegment) {
666 /* g_message( "Stream requesting %d more bytes", needed ); */
667 pinfo->desegment_offset = offset;
668 pinfo->desegment_len = needed;
669 return -needed;
672 return offset;
676 * Find or possibly create a transport conversation object for the connection
677 * which is associated with the packet info.
679 * @param pinfo The packet info from the underlying transport.
681 static jxta_stream_conversation_data *get_tpt_conversation(packet_info * pinfo)
683 conversation_t *tpt_conversation =
684 find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
685 jxta_stream_conversation_data *tpt_conv_data;
687 if (tpt_conversation == NULL) {
689 * No conversation exists yet - create one.
691 tpt_conversation =
692 conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
695 conversation_set_dissector(tpt_conversation, stream_jxta_handle);
697 tpt_conv_data = (jxta_stream_conversation_data *) conversation_get_proto_data(tpt_conversation, proto_jxta);
699 if (NULL == tpt_conv_data) {
700 tpt_conv_data = wmem_new(wmem_file_scope(), jxta_stream_conversation_data);
701 tpt_conv_data->tpt_ptype = pinfo->ptype;
703 SE_COPY_ADDRESS(&tpt_conv_data->initiator_tpt_address, &pinfo->src);
704 tpt_conv_data->initiator_tpt_port = pinfo->srcport;
705 tpt_conv_data->initiator_welcome_frame = 0;
706 tpt_conv_data->initiator_address.type = AT_NONE;
707 tpt_conv_data->initiator_address.len = 0;
708 tpt_conv_data->initiator_address.data = NULL;
710 SE_COPY_ADDRESS(&tpt_conv_data->receiver_tpt_address, &pinfo->dst);
711 tpt_conv_data->receiver_tpt_port = pinfo->destport;
712 tpt_conv_data->receiver_welcome_frame = 0;
713 tpt_conv_data->receiver_address.type = AT_NONE;
714 tpt_conv_data->receiver_address.len = 0;
715 tpt_conv_data->receiver_address.data = NULL;
717 conversation_add_proto_data(tpt_conversation, proto_jxta, tpt_conv_data);
720 return tpt_conv_data;
724 * Find or possibly create a peer conversation object for the connection
725 * which is associated with the packet info.
727 * @param tpt_conv_data The transport conversation from which we will locate the peer conversation.
728 * @param create If TRUE then create a new conversation object if necessary.
730 static conversation_t *get_peer_conversation(packet_info * pinfo, jxta_stream_conversation_data* tpt_conv_data, gboolean create)
732 conversation_t * peer_conversation = NULL;
734 if ((AT_NONE != tpt_conv_data->initiator_address.type) && (AT_NONE != tpt_conv_data->receiver_address.type)) {
735 peer_conversation = find_conversation(pinfo->fd->num, &tpt_conv_data->initiator_address, &tpt_conv_data->receiver_address,
736 PT_NONE, 0, 0, NO_PORT_B);
738 if (create && (NULL == peer_conversation)) {
739 peer_conversation = conversation_new(pinfo->fd->num, &tpt_conv_data->initiator_address,
740 &tpt_conv_data->receiver_address, PT_NONE, 0, 0, NO_PORT_B);
741 conversation_set_dissector(peer_conversation, stream_jxta_handle);
746 return peer_conversation;
750 * Dissect a tvbuff containing a JXTA Welcome Message
752 * @param tvb The buffer to dissect.
753 * @param pinfo Packet Info.
754 * @param tree The protocol tree.
755 * @param found_addr The address found in the welcome message.
756 * @param initiator If TRUE then we believe this welcome message to be the initiator's.
757 * @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
758 * the packet was not recognized as a JXTA packet and negative if the
759 * dissector needs more bytes in order to process a PDU.
761 static int dissect_jxta_welcome(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, address * found_addr, gboolean initiator)
763 guint offset = 0;
764 gint afterwelcome;
765 gint first_linelen;
766 guint available = tvb_reported_length_remaining(tvb, offset);
767 gchar **tokens = NULL;
769 if (available < sizeof(JXTA_WELCOME_MSG_SIG)) {
770 return (gint) (available - sizeof(JXTA_WELCOME_MSG_SIG));
773 if (0 != tvb_memeql(tvb, 0, JXTA_WELCOME_MSG_SIG, sizeof(JXTA_WELCOME_MSG_SIG))) {
774 /* not ours! */
775 return 0;
778 first_linelen = tvb_find_line_end(tvb, offset, -1, &afterwelcome, gDESEGMENT && pinfo->can_desegment);
780 if (-1 == first_linelen) {
781 if (available > 4096) {
782 /* it's too far too be reasonable */
783 return 0;
784 } else {
785 /* ask for more bytes */
786 return -1;
790 /* Dissect the Welcome Message */
792 col_set_str(pinfo->cinfo, COL_PROTOCOL, "JXTA");
794 col_set_str(pinfo->cinfo, COL_INFO, "Welcome");
797 gchar *welcomeline = tvb_get_string(wmem_packet_scope(), tvb, offset, first_linelen);
798 gchar **current_token;
799 guint token_offset = offset;
800 proto_item *jxta_welcome_tree_item = NULL;
801 proto_tree *jxta_welcome_tree = NULL;
803 tokens = g_strsplit(welcomeline, " ", 255);
804 current_token = tokens;
806 if (tree) {
807 jxta_welcome_tree_item =
808 proto_tree_add_none_format(tree, hf_jxta_welcome, tvb, offset, afterwelcome,
809 "JXTA Connection Welcome Message, %s", welcomeline);
810 jxta_welcome_tree = proto_item_add_subtree(jxta_welcome_tree_item, ett_jxta_welcome);
813 if (jxta_welcome_tree) {
814 proto_item *jxta_welcome_initiator_item =
815 proto_tree_add_boolean(jxta_welcome_tree, hf_jxta_welcome_initiator, tvb, 0, 0, initiator);
816 PROTO_ITEM_SET_GENERATED(jxta_welcome_initiator_item);
819 if (NULL != *current_token) {
820 if (jxta_welcome_tree) {
821 proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_sig, tvb, token_offset, (gint) strlen(*current_token), ENC_ASCII|ENC_NA);
824 token_offset += (guint) strlen(*current_token) + 1;
825 current_token++;
826 } else {
827 /* invalid welcome message */
828 afterwelcome = 0;
829 goto Common_Exit;
832 if (NULL != *current_token) {
833 if (jxta_welcome_tree) {
834 proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_destAddr, tvb, token_offset, (gint) strlen(*current_token),
835 ENC_ASCII|ENC_NA);
838 token_offset += (guint) strlen(*current_token) + 1;
839 current_token++;
840 } else {
841 /* invalid welcome message */
842 afterwelcome = 0;
843 goto Common_Exit;
846 if (NULL != *current_token) {
847 if (jxta_welcome_tree) {
848 proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_pubAddr, tvb, token_offset, (gint) strlen(*current_token), ENC_ASCII|ENC_NA);
851 token_offset += (guint) strlen(*current_token) + 1;
852 current_token++;
853 } else {
854 /* invalid welcome message */
855 afterwelcome = 0;
856 goto Common_Exit;
859 if (NULL != *current_token) {
860 if (jxta_welcome_tree) {
861 proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_peerid, tvb, token_offset, (gint) strlen(*current_token), ENC_ASCII|ENC_NA);
864 col_append_str(pinfo->cinfo, COL_INFO, (initiator ? " -> " : " <- ") );
865 col_append_str(pinfo->cinfo, COL_INFO, *current_token);
867 if (NULL != found_addr) {
868 found_addr->type = AT_URI;
869 found_addr->len = (int) strlen(*current_token);
870 found_addr->data = wmem_strdup(wmem_file_scope(), *current_token);
873 token_offset += (guint) strlen(*current_token) + 1;
874 current_token++;
875 } else {
876 /* invalid welcome message */
877 afterwelcome = 0;
878 goto Common_Exit;
881 if (NULL != *current_token) {
882 int variable_tokens = 0;
883 gchar **variable_token = current_token;
885 while(NULL != *variable_token) {
886 variable_tokens++;
887 variable_token++;
890 if( variable_tokens < 1 ) {
891 /* invalid welcome message */
892 afterwelcome = 0;
893 goto Common_Exit;
896 if( (2 == variable_tokens) && (0 == strcmp(JXTA_WELCOME_MSG_VERSION_1_1, current_token[variable_tokens -1])) ) {
897 if (jxta_welcome_tree) {
898 proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_noProp, tvb, token_offset, (gint) strlen(*current_token), ENC_ASCII|ENC_NA);
901 token_offset += (guint) strlen(*current_token) + 1;
902 current_token++;
904 if (jxta_welcome_tree) {
905 proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_version, tvb, token_offset, (gint) strlen(*current_token), ENC_ASCII|ENC_NA);
907 } else if( (3 == variable_tokens) && (0 == strcmp(JXTA_WELCOME_MSG_VERSION_3_0, current_token[variable_tokens -1])) ) {
908 if (jxta_welcome_tree) {
909 proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_noProp, tvb, token_offset, (gint) strlen(*current_token), ENC_ASCII|ENC_NA);
912 token_offset += (guint) strlen(*current_token) + 1;
913 current_token++;
915 if (jxta_welcome_tree) {
916 proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_msgVers, tvb, token_offset, (gint) strlen(*current_token), ENC_ASCII|ENC_NA);
919 token_offset += (guint) strlen(*current_token) + 1;
920 current_token++;
922 if (jxta_welcome_tree) {
923 proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_version, tvb, token_offset, (gint) strlen(*current_token), ENC_ASCII|ENC_NA);
925 } else {
926 /* Unrecognized Welcome Version */
927 int each_variable_token;
929 for( each_variable_token = 0; each_variable_token < variable_tokens; each_variable_token++ ) {
930 if (jxta_welcome_tree) {
931 jxta_welcome_tree_item = proto_tree_add_item(jxta_welcome_tree,
932 (each_variable_token < (variable_tokens -1) ? hf_jxta_welcome_variable : hf_jxta_welcome_version),
933 tvb, token_offset, (gint) strlen(*current_token), ENC_ASCII|ENC_NA);
935 proto_item_append_text(jxta_welcome_tree_item, " (UNRECOGNIZED)");
938 token_offset += (guint) strlen(*current_token) + 1;
939 current_token++;
942 } else {
943 /* invalid welcome message */
944 afterwelcome = 0;
945 goto Common_Exit;
949 Common_Exit:
950 g_strfreev(tokens);
952 col_set_writable(pinfo->cinfo, FALSE);
954 return afterwelcome;
958 * Dissect a tvbuff containing JXTA Message framing.
960 * @param tvb The buffer to dissect.
961 * @param pinfo Packet Info.
962 * @param tree The protocol tree.
963 * @param content_length Pointer to a buffer for storing the value of the
964 * "content-length" header or NULL.
965 * @param content_type Pointer-to-a-pointer for a new buffer for storing the
966 * value of the "content_type-length" header or NULL.
967 * @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
968 * the packet was not recognized as a JXTA packet and negative if the
969 * dissector needs more bytes in order to process a PDU.
971 static int dissect_jxta_message_framing(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, guint64 * content_length,
972 gchar ** content_type)
974 guint offset = 0;
975 guint available;
976 gint needed = 0;
979 * First go around. Make sure all of the bytes are there.
981 do {
982 guint8 headername_len;
983 guint8 headername_offset;
984 guint16 headervalue_len;
985 guint16 headervalue_offset;
987 available = tvb_reported_length_remaining(tvb, offset);
988 if (available < sizeof(guint8)) {
989 needed = (gint) (sizeof(guint8) - available);
990 break;
991 } else {
992 headername_len = tvb_get_guint8(tvb, offset);
993 offset += (int)sizeof(guint8);
994 headername_offset = offset;
996 available = tvb_reported_length_remaining(tvb, offset);
997 if (available < headername_len) {
998 needed = (gint) (headername_len - available);
999 break;
1002 if (0 == headername_len) {
1003 break;
1005 offset += headername_len;
1008 available = tvb_reported_length_remaining(tvb, offset);
1009 if (available < sizeof(guint16)) {
1010 needed = (gint) (sizeof(guint16) - available);
1011 break;
1012 } else {
1013 headervalue_len = tvb_get_ntohs(tvb, offset);
1014 offset += (int)sizeof(guint16);
1015 headervalue_offset = offset;
1017 available = tvb_reported_length_remaining(tvb, offset);
1018 if (available < headervalue_len) {
1019 needed = (gint) (headervalue_len - available);
1020 break;
1023 offset += headervalue_len;
1026 if (content_type && (sizeof("content-type") - 1) == headername_len) {
1027 if (0 == tvb_strncaseeql(tvb, headername_offset, "content-type", sizeof("content-type") - 1)) {
1028 *content_type = tvb_get_string(wmem_packet_scope(), tvb, headervalue_offset, headervalue_len);
1033 if (content_length && (sizeof(guint64) == headervalue_len) && ((sizeof("content-length") - 1) == headername_len)) {
1034 if (0 == tvb_strncaseeql(tvb, headername_offset, "content-length", sizeof("content-length") - 1)) {
1035 *content_length = tvb_get_ntoh64(tvb, headervalue_offset);
1038 } while (TRUE);
1040 if ((needed > 0) && gDESEGMENT && pinfo->can_desegment) {
1041 /* g_message( "Framing requesting %d more bytes", needed ); */
1042 pinfo->desegment_offset = 0;
1043 pinfo->desegment_len = needed;
1044 return -needed;
1048 * Second (optional pass) Now that we are sure that all the bytes are there we update the protocol tree.
1050 if (tree) {
1051 guint tree_offset = 0;
1052 proto_item *framing_tree_item;
1053 proto_tree *framing_tree;
1055 /* Disable speed optimization because of use of append_text */
1056 proto_tree_set_visible(tree, TRUE);
1058 framing_tree_item =
1059 proto_tree_add_none_format(tree, hf_jxta_framing, tvb, tree_offset, -1, "JXTA Message Framing Headers");
1060 framing_tree = proto_item_add_subtree(framing_tree_item, ett_jxta_framing);
1062 /* parse framing headers */
1063 do {
1064 guint8 headernamelen = tvb_get_guint8(tvb, tree_offset);
1065 proto_item *framing_header_tree_item =
1066 proto_tree_add_item(framing_tree, hf_jxta_framing_header, tvb, tree_offset, -1, ENC_NA);
1067 proto_tree *framing_header_tree = proto_item_add_subtree(framing_header_tree_item, ett_jxta_framing_header);
1070 * Put header name into the protocol tree
1072 proto_tree_add_item(framing_header_tree, hf_jxta_framing_header_name, tvb, tree_offset, (int)sizeof(gint8), ENC_ASCII|ENC_NA);
1075 * Append header name into the header protocol item. It's a nice hint so you don't have to reveal all headers.
1077 if (headernamelen > 0) {
1078 proto_item_append_text(framing_header_tree_item, " \"%s\"",
1079 tvb_format_text(tvb, tree_offset + (int)sizeof(guint8), headernamelen));
1082 tree_offset += (int)sizeof(guint8) + headernamelen;
1084 if (headernamelen > 0) {
1085 guint16 headervaluelen = tvb_get_ntohs(tvb, tree_offset);
1087 if (tree) {
1088 proto_tree_add_uint(framing_header_tree, hf_jxta_framing_header_value_length, tvb, tree_offset,
1089 (int)sizeof(guint16), headervaluelen);
1091 /** TODO bondolo Add specific handling for known header types */
1094 * Put header value into protocol tree.
1096 proto_tree_add_item(framing_header_tree, hf_jxta_framing_header_value, tvb, tree_offset + (int)sizeof(guint16),
1097 headervaluelen, ENC_NA);
1100 tree_offset += (int)sizeof(guint16) + headervaluelen;
1103 proto_item_set_end(framing_header_tree_item, tvb, tree_offset);
1105 if (0 == headernamelen) {
1106 break;
1108 } while (TRUE);
1110 proto_item_set_end(framing_tree_item, tvb, tree_offset);
1112 DISSECTOR_ASSERT(offset == tree_offset);
1115 /* return how many bytes we used up. */
1116 return offset;
1120 * Dissect a tvbuff containing one or more JXTA Messages.
1122 * @param tvb The buffer to dissect.
1123 * @param pinfo Packet Info.
1124 * @param tree The protocol tree.
1125 * @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
1126 * the packet was not recognized as a JXTA packet and negative if the
1127 * dissector needs more bytes in order to process a PDU.
1129 static int dissect_jxta_message(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data _U_)
1131 gint complete_messages = 0;
1132 guint offset = 0;
1133 guint tree_offset = 0;
1134 guint available;
1135 gint needed = 0;
1136 wmem_strbuf_t* src_addr;
1137 wmem_strbuf_t* dst_addr;
1139 while (TRUE) {
1140 guint8 message_version;
1141 guint message_start_offset = offset;
1143 /* First pass. Make sure all of the bytes we need are available */
1144 available = tvb_reported_length_remaining(tvb, offset);
1146 if((0 == available) && (0 != complete_messages)) {
1147 /* We have discovered all of the complete messages in the tvbuff. */
1148 break;
1151 if (available < sizeof(JXTA_MSG_SIG)) {
1152 needed = (gint) (sizeof(JXTA_MSG_SIG) - available);
1153 break;
1156 if (tvb_memeql(tvb, offset, JXTA_MSG_SIG, sizeof(JXTA_MSG_SIG)) != 0) {
1157 /* It is not one of ours */
1158 return 0;
1161 offset += (int)sizeof(JXTA_MSG_SIG);
1163 available = tvb_reported_length_remaining(tvb, offset);
1164 if (available < sizeof(guint8)) {
1165 needed = (gint) (sizeof(guint8) - available);
1166 break;
1167 } else {
1168 message_version = tvb_get_guint8(tvb, offset);
1170 offset += (int)sizeof(guint8);
1172 if ((JXTA_MSG_VERSION_1 != message_version) && (JXTA_MSG_VERSION_2 != message_version)) {
1173 /* Sort of a lie, we say that we don't recognize it at all. */
1174 return 0;
1178 /* Read the flags (Version 2 and later) */
1179 if(message_version > 0) {
1180 available = tvb_reported_length_remaining(tvb, offset);
1181 if (available < sizeof(guint8)) {
1182 needed = (gint) (sizeof(guint8) - available);
1183 break;
1184 } else {
1185 offset += (int)sizeof(guint8);
1189 /* Read names table */
1190 available = tvb_reported_length_remaining(tvb, offset);
1191 if (available < sizeof(guint16)) {
1192 needed = (gint) (sizeof(guint16) - available);
1193 break;
1194 } else {
1195 guint16 msg_names_count = tvb_get_ntohs(tvb, offset);
1196 guint each_name;
1198 offset += (int)sizeof(guint16);
1200 for (each_name = 0; each_name < msg_names_count; each_name++) {
1201 guint16 name_len;
1203 available = tvb_reported_length_remaining(tvb, offset);
1204 if (available < sizeof(name_len)) {
1205 needed = (gint) (sizeof(name_len) - available);
1206 break;
1209 name_len = tvb_get_ntohs(tvb, offset);
1211 available = tvb_reported_length_remaining(tvb, offset + (int)sizeof(name_len));
1212 if (available < name_len) {
1213 needed = (gint) (name_len - available);
1214 break;
1217 offset += (int)sizeof(name_len) + name_len;
1221 /* parse element count */
1222 available = tvb_reported_length_remaining(tvb, offset);
1223 if (available < sizeof(guint16)) {
1224 needed = (gint) (sizeof(guint16) - available);
1225 break;
1226 } else {
1227 guint16 elem_count = tvb_get_ntohs(tvb, offset);
1228 guint each_elem;
1230 offset += (int)sizeof(guint16);
1232 /* parse elements */
1233 for (each_elem = 0; each_elem < elem_count; each_elem++) {
1234 tvbuff_t *jxta_message_element_tvb = tvb_new_subset_remaining(tvb, offset);
1235 int processed;
1237 if(JXTA_MSG_VERSION_1 == message_version) {
1238 processed = dissect_jxta_message_element_1(jxta_message_element_tvb, pinfo, NULL, 0, NULL);
1239 } else if(JXTA_MSG_VERSION_2 == message_version) {
1240 processed = dissect_jxta_message_element_2(jxta_message_element_tvb, pinfo, NULL, 0, NULL);
1241 } else {
1242 /* Sort of a lie, we say that we don't recognize it at all. */
1243 return 0;
1246 if (processed < 0) {
1247 needed = -processed;
1248 break;
1251 if (0 == processed) {
1252 /* XXX bondolo Not really clear what we should do! */
1253 g_warning( "Failure processing message element #%d of %d of frame %d", each_elem, elem_count, pinfo->fd->num );
1254 return 0;
1257 offset += processed;
1261 if ((AT_URI == pinfo->src.type) && (AT_URI == pinfo->dst.type)) {
1262 jxta_tap_header *tap_header = wmem_new(wmem_file_scope(), jxta_tap_header);
1264 tap_header->src_address = pinfo->src;
1265 tap_header->dest_address = pinfo->dst;
1266 tap_header->size = offset - message_start_offset ;
1268 tap_queue_packet(jxta_tap, pinfo, tap_header);
1271 complete_messages++;
1273 /* g_message( "%d Scanned message #%d: ", pinfo->fd->num, complete_messages ); */
1276 if ((needed > 0) && gDESEGMENT && pinfo->can_desegment) {
1277 /* g_message( "Message requesting %d more bytes", needed ); */
1278 pinfo->desegment_offset = 0;
1279 pinfo->desegment_len = needed;
1280 return -needed;
1283 src_addr = wmem_strbuf_new_label(wmem_packet_scope());
1284 wmem_strbuf_append(src_addr, ep_address_to_str(&pinfo->src));
1285 dst_addr = wmem_strbuf_new_label(wmem_packet_scope());
1286 wmem_strbuf_append(dst_addr, ep_address_to_str(&pinfo->dst));
1288 /* append the port if appropriate */
1289 if (PT_NONE != pinfo->ptype) {
1290 wmem_strbuf_append_printf(src_addr, ":%d", pinfo->srcport);
1291 wmem_strbuf_append_printf(dst_addr, ":%d", pinfo->destport);
1294 col_set_str(pinfo->cinfo, COL_PROTOCOL, "JXTA");
1296 if( complete_messages > 1 ) {
1297 col_add_fstr(pinfo->cinfo, COL_INFO, "%d Messages, %s -> %s", complete_messages,
1298 wmem_strbuf_get_str(src_addr), wmem_strbuf_get_str(dst_addr));
1299 } else {
1300 col_add_fstr(pinfo->cinfo, COL_INFO, "Message, %s -> %s",
1301 wmem_strbuf_get_str(src_addr), wmem_strbuf_get_str(dst_addr));
1304 col_set_writable(pinfo->cinfo, FALSE);
1306 while( tree && (complete_messages > 0) ) {
1307 proto_item *jxta_msg_tree_item = NULL;
1308 proto_tree *jxta_msg_tree = NULL;
1309 guint8 message_version;
1310 const gchar **names_table = NULL;
1311 guint16 msg_names_count;
1312 guint each_name;
1313 guint16 elem_count;
1314 guint each_elem;
1315 proto_item *tree_item;
1317 jxta_msg_tree_item = proto_tree_add_protocol_format(tree, proto_message_jxta, tvb, tree_offset, -1,
1318 "JXTA Message, %s -> %s", wmem_strbuf_get_str(src_addr),
1319 wmem_strbuf_get_str(dst_addr));
1321 jxta_msg_tree = proto_item_add_subtree(jxta_msg_tree_item, ett_jxta_msg);
1323 proto_tree_add_item(jxta_msg_tree, hf_jxta_message_sig, tvb, tree_offset, (int)sizeof(JXTA_MSG_SIG), ENC_ASCII|ENC_NA);
1324 tree_offset += (int)sizeof(JXTA_MSG_SIG);
1326 tree_item = proto_tree_add_string(jxta_msg_tree, hf_jxta_message_src, tvb, 0, 0, wmem_strbuf_get_str(src_addr));
1327 PROTO_ITEM_SET_GENERATED(tree_item);
1329 tree_item = proto_tree_add_string(jxta_msg_tree, hf_jxta_message_address, tvb, 0, 0, wmem_strbuf_get_str(src_addr));
1330 PROTO_ITEM_SET_HIDDEN(tree_item);
1331 PROTO_ITEM_SET_GENERATED(tree_item);
1333 if(AT_URI == pinfo->src.type) {
1334 tree_item = proto_tree_add_string(jxta_msg_tree, hf_uri_src, tvb, 0, 0, wmem_strbuf_get_str(src_addr));
1335 PROTO_ITEM_SET_HIDDEN(tree_item);
1336 PROTO_ITEM_SET_GENERATED(tree_item);
1337 tree_item = proto_tree_add_string(jxta_msg_tree, hf_uri_addr, tvb, 0, 0, wmem_strbuf_get_str(src_addr));
1338 PROTO_ITEM_SET_HIDDEN(tree_item);
1339 PROTO_ITEM_SET_GENERATED(tree_item);
1342 tree_item = proto_tree_add_string(jxta_msg_tree, hf_jxta_message_dst, tvb, 0, 0, wmem_strbuf_get_str(dst_addr));
1343 PROTO_ITEM_SET_GENERATED(tree_item);
1345 tree_item = proto_tree_add_string(jxta_msg_tree, hf_jxta_message_address, tvb, 0, 0, wmem_strbuf_get_str(dst_addr));
1346 PROTO_ITEM_SET_HIDDEN(tree_item);
1347 PROTO_ITEM_SET_GENERATED(tree_item);
1349 if(AT_URI == pinfo->dst.type) {
1350 tree_item = proto_tree_add_string(jxta_msg_tree, hf_uri_dst, tvb, 0, 0, wmem_strbuf_get_str(src_addr));
1351 PROTO_ITEM_SET_HIDDEN(tree_item);
1352 PROTO_ITEM_SET_GENERATED(tree_item);
1353 tree_item = proto_tree_add_string(jxta_msg_tree, hf_uri_addr, tvb, 0, 0, wmem_strbuf_get_str(dst_addr));
1354 PROTO_ITEM_SET_HIDDEN(tree_item);
1355 PROTO_ITEM_SET_GENERATED(tree_item);
1358 message_version = tvb_get_guint8(tvb, tree_offset);
1359 proto_tree_add_uint(jxta_msg_tree, hf_jxta_message_version, tvb, tree_offset, (int)sizeof(guint8), message_version);
1360 tree_offset += (int)sizeof(guint8);
1362 if( message_version > 0 ) {
1363 guint8 flags = tvb_get_guint8(tvb, tree_offset);
1364 proto_item *flags_ti = proto_tree_add_uint(jxta_msg_tree, hf_jxta_message_flags, tvb, tree_offset, (int)sizeof(guint8), flags);
1365 proto_tree *jxta_msg_flags_tree = proto_item_add_subtree(flags_ti, ett_jxta_msg_flags);
1366 proto_tree_add_boolean(jxta_msg_flags_tree, hf_jxta_message_flag_utf16be, tvb, tree_offset, 1, flags);
1367 proto_tree_add_boolean(jxta_msg_flags_tree, hf_jxta_message_flag_ucs32be, tvb, tree_offset, 1, flags);
1368 tree_offset += (int)sizeof(guint8);
1371 msg_names_count = tvb_get_ntohs(tvb, tree_offset);
1372 proto_tree_add_uint(jxta_msg_tree, hf_jxta_message_names_count, tvb, tree_offset, (int)sizeof(guint16), msg_names_count);
1373 tree_offset += (int)sizeof(guint16);
1375 names_table = (const gchar **)wmem_alloc(wmem_packet_scope(), (msg_names_count + 2) * sizeof(const gchar *));
1376 names_table[0] = "";
1377 names_table[1] = "jxta";
1379 /* parse names */
1380 for (each_name = 0; each_name < msg_names_count; each_name++) {
1381 guint16 name_len = tvb_get_ntohs(tvb, tree_offset);
1383 names_table[2 + each_name] = tvb_get_string(wmem_packet_scope(), tvb, tree_offset + (int)sizeof(name_len), name_len);
1384 proto_tree_add_item(jxta_msg_tree, hf_jxta_message_names_name, tvb, tree_offset, (int)sizeof(name_len), ENC_ASCII|ENC_NA);
1385 tree_offset += (int)sizeof(name_len) + name_len;
1388 /* parse element count */
1389 elem_count = tvb_get_ntohs(tvb, tree_offset);
1390 proto_tree_add_item(jxta_msg_tree, hf_jxta_message_element_count, tvb, tree_offset, (int)sizeof(guint16), ENC_BIG_ENDIAN);
1391 tree_offset += (int)sizeof(guint16);
1393 /* FIXME bondolo Element count 0 (Process elements until FIN) should be supported. */
1395 /* parse elements */
1396 for (each_elem = 0; each_elem < elem_count; each_elem++) {
1397 tvbuff_t *jxta_message_element_tvb = tvb_new_subset_remaining(tvb, tree_offset);
1399 if(JXTA_MSG_VERSION_1 == message_version) {
1400 tree_offset +=
1401 dissect_jxta_message_element_1(jxta_message_element_tvb, pinfo, jxta_msg_tree, msg_names_count + 2, names_table);
1402 } else if(JXTA_MSG_VERSION_2 == message_version) {
1403 tree_offset +=
1404 dissect_jxta_message_element_2(jxta_message_element_tvb, pinfo, jxta_msg_tree, msg_names_count + 2, names_table);
1405 } else {
1406 /* Sort of a lie, we say that we don't recognize it at all. */
1407 return 0;
1411 proto_item_set_end(jxta_msg_tree_item, tvb, tree_offset);
1413 complete_messages--;
1416 if( tree ) {
1417 /* g_message( "%d tvb offset : %d tree offset : %d", pinfo->fd->num, offset, tree_offset ); */
1418 DISSECTOR_ASSERT(tree_offset == offset);
1421 return offset;
1425 * Dissect a tvbuff containing a JXTA Message Element (Version 1).
1427 * @param tvb The buffer to dissect.
1428 * @param pinfo Packet Info.
1429 * @param tree The protocol tree.
1430 * @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
1431 * the packet was not recognized as a JXTA packet and negative if the
1432 * dissector needs more bytes in order to process a PDU.
1434 static int dissect_jxta_message_element_1(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, guint ns_count,
1435 const gchar ** names_table)
1437 guint offset = 0;
1438 guint available;
1439 gint needed = 0;
1440 guint8 flags;
1442 /* First pass. Make sure all of the bytes we need are available */
1444 while (TRUE) {
1445 /* signature field */
1446 available = tvb_reported_length_remaining(tvb, offset);
1447 if (available < sizeof(JXTA_MSGELEM_SIG)) {
1448 needed = (gint) (sizeof(JXTA_MSGELEM_SIG) - available);
1451 if (tvb_memeql(tvb, offset, JXTA_MSGELEM_SIG, sizeof(JXTA_MSGELEM_SIG)) != 0) {
1452 /* It is not one of ours */
1453 return 0;
1456 offset += (int)sizeof(JXTA_MSGELEM_SIG);
1458 /* namespace id field */
1459 available = tvb_reported_length_remaining(tvb, offset);
1460 if (available < sizeof(guint8)) {
1461 needed = (gint) (sizeof(guint8) - available);
1462 break;
1465 offset += (int)sizeof(guint8);
1467 /* flags field */
1468 available = tvb_reported_length_remaining(tvb, offset);
1469 if (available < sizeof(guint8)) {
1470 needed = (gint) (sizeof(guint8) - available);
1471 break;
1472 } else {
1473 flags = tvb_get_guint8(tvb, offset);
1474 offset += (int)sizeof(guint8);
1477 /* name field */
1478 available = tvb_reported_length_remaining(tvb, offset);
1479 if (available < sizeof(guint16)) {
1480 needed = (gint) (sizeof(guint16) - available);
1481 break;
1482 } else {
1483 guint16 name_len = tvb_get_ntohs(tvb, offset);
1484 offset += (int)sizeof(guint16);
1486 available = tvb_reported_length_remaining(tvb, offset);
1487 if (available < name_len) {
1488 needed = (gint) (name_len - available);
1489 break;
1492 offset += name_len;
1495 /* type field */
1496 if ((flags & JXTAMSG1_ELMFLAG_TYPE) != 0) {
1497 guint16 type_len;
1499 available = tvb_reported_length_remaining(tvb, offset);
1500 if (available < sizeof(guint16)) {
1501 needed = (gint) (sizeof(guint16) - available);
1502 break;
1505 type_len = tvb_get_ntohs(tvb, offset);
1506 offset += (int)sizeof(guint16);
1508 available = tvb_reported_length_remaining(tvb, offset);
1509 if (available < type_len) {
1510 needed = (gint) (type_len - available);
1511 break;
1514 offset += type_len;
1517 /* encoding field */
1518 if ((flags & JXTAMSG1_ELMFLAG_ENCODING) != 0) {
1519 guint16 encoding_len;
1521 available = tvb_reported_length_remaining(tvb, offset);
1522 if (available < sizeof(guint16)) {
1523 needed = (gint) (sizeof(guint16) - available);
1524 break;
1527 encoding_len = tvb_get_ntohs(tvb, offset);
1528 offset += (int)sizeof(guint16);
1530 available = tvb_reported_length_remaining(tvb, offset);
1531 if (available < encoding_len) {
1532 needed = (gint) (encoding_len - available);
1533 break;
1536 offset += encoding_len;
1539 /* content field */
1540 available = tvb_reported_length_remaining(tvb, offset);
1541 if (available < sizeof(guint16)) {
1542 needed = (gint) (sizeof(guint16) - available);
1543 break;
1544 } else {
1545 guint32 content_len = tvb_get_ntohl(tvb, offset);
1546 offset += (int)sizeof(guint32);
1548 available = tvb_reported_length_remaining(tvb, offset);
1549 if (available < content_len) {
1550 needed = (gint) (content_len - available);
1551 break;
1554 offset += content_len;
1557 /* signature element field */
1558 if ((flags & JXTAMSG1_ELMFLAG_SIGNATURE) != 0) {
1559 tvbuff_t *jxta_signature_element_tvb;
1560 int processed;
1562 jxta_signature_element_tvb = tvb_new_subset_remaining(tvb, offset);
1564 processed = dissect_jxta_message_element_1(jxta_signature_element_tvb, pinfo, NULL, 0, NULL);
1566 if (processed == 0) {
1567 return offset;
1570 if (processed < 0) {
1571 needed = -processed;
1572 break;
1575 offset += processed;
1578 break;
1581 if ((needed > 0) && gDESEGMENT && pinfo->can_desegment) {
1582 /* g_message( "Element1 requesting %d more bytes", needed ); */
1583 pinfo->desegment_offset = 0;
1584 pinfo->desegment_len = needed;
1585 return -needed;
1588 /* Second (optional) pass : build the proto tree */
1590 guint tree_offset = 0;
1591 proto_item *jxta_elem_tree_item = proto_tree_add_item(tree, hf_jxta_element, tvb, tree_offset, -1, ENC_NA);
1592 proto_tree *jxta_elem_tree = proto_item_add_subtree(jxta_elem_tree_item, ett_jxta_elem);
1593 guint8 namespaceID;
1594 proto_item *namespace_ti;
1595 guint16 name_len;
1596 proto_item *flags_ti;
1597 proto_tree *jxta_elem_flags_tree = NULL;
1598 guint32 content_len;
1599 gchar *mediatype = NULL;
1600 tvbuff_t *element_content_tvb;
1602 proto_tree_add_item(jxta_elem_tree, hf_jxta_element_sig, tvb, tree_offset, (int)sizeof(JXTA_MSGELEM_SIG), ENC_ASCII|ENC_NA);
1603 tree_offset += (int)sizeof(JXTA_MSGELEM_SIG);
1605 namespaceID = tvb_get_guint8(tvb, tree_offset);
1606 namespace_ti =
1607 proto_tree_add_uint(jxta_elem_tree, hf_jxta_element1_namespaceid, tvb, tree_offset, (int)sizeof(guint8), namespaceID);
1608 if (namespaceID < ns_count) {
1609 proto_item_append_text(namespace_ti, " (%s)", names_table[namespaceID]);
1610 } else {
1611 proto_item_append_text(namespace_ti, " * BAD *");
1613 tree_offset += (int)sizeof(guint8);
1615 flags = tvb_get_guint8(tvb, tree_offset);
1616 flags_ti = proto_tree_add_uint(jxta_elem_tree, hf_jxta_element_flags, tvb, tree_offset, (int)sizeof(guint8), flags);
1617 jxta_elem_flags_tree = proto_item_add_subtree(flags_ti, ett_jxta_elem_1_flags);
1618 proto_tree_add_boolean(jxta_elem_flags_tree, hf_jxta_element1_flag_hasType, tvb, tree_offset, 1, flags);
1619 proto_tree_add_boolean(jxta_elem_flags_tree, hf_jxta_element1_flag_hasEncoding, tvb, tree_offset, 1, flags);
1620 proto_tree_add_boolean(jxta_elem_flags_tree, hf_jxta_element1_flag_hasSignature, tvb, tree_offset, 1, flags);
1621 tree_offset += (int)sizeof(guint8);
1623 name_len = tvb_get_ntohs(tvb, tree_offset);
1624 proto_item_append_text(jxta_elem_tree_item, " \"%s\"", tvb_format_text(tvb, tree_offset + (int)sizeof(guint16), name_len));
1625 proto_tree_add_item(jxta_elem_tree, hf_jxta_element_name, tvb, tree_offset, (int)sizeof(guint16), ENC_ASCII|ENC_NA);
1626 tree_offset += (int)sizeof(guint16) + name_len;
1628 /* process type */
1629 if ((flags & JXTAMSG1_ELMFLAG_TYPE) != 0) {
1630 guint16 type_len = tvb_get_ntohs(tvb, tree_offset);
1631 proto_tree_add_item(jxta_elem_tree, hf_jxta_element_type, tvb, tree_offset, (int)sizeof(guint16), ENC_ASCII|ENC_NA);
1632 tree_offset += (int)sizeof(guint16);
1634 mediatype = tvb_get_string(wmem_packet_scope(), tvb, tree_offset, type_len);
1636 tree_offset += type_len;
1639 /* process encoding */
1640 if ((flags & JXTAMSG1_ELMFLAG_ENCODING) != 0) {
1641 guint16 encoding_len = tvb_get_ntohs(tvb, tree_offset);
1642 proto_tree_add_item(jxta_elem_tree, hf_jxta_element_encoding, tvb, tree_offset, (int)sizeof(guint16), ENC_ASCII|ENC_NA);
1643 tree_offset += (int)sizeof(guint16) + encoding_len;
1646 /* content */
1647 content_len = tvb_get_ntohl(tvb, tree_offset);
1648 proto_tree_add_item(jxta_elem_tree, hf_jxta_element_content_len, tvb, tree_offset, (int)sizeof(guint32), ENC_BIG_ENDIAN);
1649 tree_offset += (int)sizeof(guint32);
1651 element_content_tvb = tvb_new_subset(tvb, tree_offset, content_len, content_len);
1653 tree_offset += dissect_media(mediatype, element_content_tvb, pinfo, jxta_elem_tree);
1655 /* process the signature element */
1656 if ((flags & JXTAMSG1_ELMFLAG_SIGNATURE) != 0) {
1657 tvbuff_t *jxta_message_element_tvb = tvb_new_subset_remaining(tvb, tree_offset);
1659 tree_offset += dissect_jxta_message_element_1(jxta_message_element_tvb, pinfo, jxta_elem_tree, ns_count, names_table);
1662 proto_item_set_end(jxta_elem_tree_item, tvb, tree_offset);
1664 DISSECTOR_ASSERT(tree_offset == offset);
1667 return offset;
1671 * Dissect a tvbuff containing a JXTA Message Element (Version 2).
1673 * @param tvb The buffer to dissect.
1674 * @param pinfo Packet Info.
1675 * @param tree The protocol tree.
1676 * @param names_count The number of elements in the names table.
1677 * @param names_table The table of names.
1678 * @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
1679 * the packet was not recognized as a JXTA packet and negative if the
1680 * dissector needs more bytes in order to process a PDU.
1682 static int dissect_jxta_message_element_2(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, guint names_count,
1683 const gchar ** names_table)
1685 guint offset = 0;
1686 guint available;
1687 gint needed = 0;
1688 guint8 flags;
1690 /* First pass. Make sure all of the bytes we need are available */
1692 while (TRUE) {
1693 /* signature field */
1694 available = tvb_reported_length_remaining(tvb, offset);
1695 if (available < sizeof(JXTA_MSGELEM_SIG)) {
1696 needed = (gint) (sizeof(JXTA_MSGELEM_SIG) - available);
1699 if (tvb_memeql(tvb, offset, JXTA_MSGELEM_SIG, sizeof(JXTA_MSGELEM_SIG)) != 0) {
1700 /* It is not one of ours */
1701 return 0;
1704 offset += (int)sizeof(JXTA_MSGELEM_SIG);
1706 /* flags field */
1707 available = tvb_reported_length_remaining(tvb, offset);
1708 if (available < sizeof(guint8)) {
1709 needed = (gint) (sizeof(guint8) - available);
1710 break;
1711 } else {
1712 flags = tvb_get_guint8(tvb, offset);
1713 offset += (int)sizeof(guint8);
1716 /* namespace id field */
1717 available = tvb_reported_length_remaining(tvb, offset);
1718 if (available < sizeof(guint16)) {
1719 needed = (gint) (sizeof(guint16) - available);
1720 break;
1723 offset += (int)sizeof(guint16);
1725 /* name field */
1726 if ((flags & JXTAMSG2_ELMFLAG_NAME_LITERAL) == 0) {
1727 available = tvb_reported_length_remaining(tvb, offset);
1728 if (available < sizeof(guint16)) {
1729 needed = (gint) (sizeof(guint16) - available);
1730 break;
1733 offset += (int)sizeof(guint16);
1734 } else {
1735 /* literal name field */
1736 available = tvb_reported_length_remaining(tvb, offset);
1737 if (available < sizeof(guint16)) {
1738 needed = (gint) (sizeof(guint16) - available);
1739 break;
1740 } else {
1741 guint16 name_len = tvb_get_ntohs(tvb, offset);
1742 offset += (int)sizeof(guint16);
1744 available = tvb_reported_length_remaining(tvb, offset);
1745 if (available < name_len) {
1746 needed = (gint) (name_len - available);
1747 break;
1750 offset += name_len;
1754 /* type field */
1755 if ((flags & JXTAMSG2_ELMFLAG_TYPE) != 0) {
1756 available = tvb_reported_length_remaining(tvb, offset);
1757 if (available < sizeof(guint16)) {
1758 needed = (gint) (sizeof(guint16) - available);
1759 break;
1762 offset += (int)sizeof(guint16);
1765 /* encoding field */
1766 if ((flags & JXTAMSG2_ELMFLAG_ENCODINGS) != 0) {
1767 available = tvb_reported_length_remaining(tvb, offset);
1768 if (available < sizeof(guint16)) {
1769 needed = (gint) (sizeof(guint16) - available);
1770 break;
1773 offset += (int)sizeof(guint16);
1777 /* content field */
1778 if ((flags & JXTAMSG2_ELMFLAG_UINT64_LENS) != 0) {
1779 available = tvb_reported_length_remaining(tvb, offset);
1780 if (available < sizeof(guint64)) {
1781 needed = (gint) (sizeof(guint64) - available);
1782 break;
1783 } else {
1784 guint64 content_len = tvb_get_ntoh64(tvb, offset);
1785 offset += (int)sizeof(guint64);
1787 available = tvb_reported_length_remaining(tvb, offset);
1788 if (available < content_len) {
1789 needed = (gint) (content_len - available);
1790 break;
1793 offset += (guint) content_len;
1795 } else {
1796 available = tvb_reported_length_remaining(tvb, offset);
1797 if (available < sizeof(guint32)) {
1798 needed = (gint) (sizeof(guint32) - available);
1799 break;
1800 } else {
1801 guint64 content_len = tvb_get_ntohl(tvb, offset);
1802 offset += (int)sizeof(guint32);
1804 available = tvb_reported_length_remaining(tvb, offset);
1805 if (available < content_len) {
1806 needed = (gint) (content_len - available);
1807 break;
1810 offset += (guint) content_len;
1814 /* signature element field */
1815 if ((flags & JXTAMSG2_ELMFLAG_SIGNATURE) != 0) {
1816 tvbuff_t *jxta_signature_element_tvb;
1817 int processed;
1819 jxta_signature_element_tvb = tvb_new_subset_remaining(tvb, offset);
1821 processed = dissect_jxta_message_element_2(jxta_signature_element_tvb, pinfo, NULL, 0, NULL);
1823 if (processed == 0) {
1824 return offset;
1827 if (processed < 0) {
1828 needed = -processed;
1829 break;
1832 offset += processed;
1835 break;
1838 if ((needed > 0) && gDESEGMENT && pinfo->can_desegment) {
1839 /* g_message( "Element2 requesting %d more bytes", needed ); */
1840 pinfo->desegment_offset = 0;
1841 pinfo->desegment_len = needed;
1842 return -needed;
1845 /* Second (optional) pass : build the proto tree */
1847 guint tree_offset = 0;
1848 proto_item *jxta_elem_tree_item = proto_tree_add_item(tree, hf_jxta_element, tvb, tree_offset, -1, ENC_NA);
1849 proto_tree *jxta_elem_tree = proto_item_add_subtree(jxta_elem_tree_item, ett_jxta_elem);
1850 proto_item *flags_ti;
1851 proto_tree *jxta_elem_flags_tree = NULL;
1852 guint16 namespaceID;
1853 proto_item *namespace_ti;
1854 guint16 nameID;
1855 proto_item *name_ti;
1856 guint64 content_len;
1857 const gchar *mediatype = NULL;
1858 tvbuff_t *element_content_tvb;
1860 proto_tree_add_item(jxta_elem_tree, hf_jxta_element_sig, tvb, tree_offset, (int)sizeof(JXTA_MSGELEM_SIG), ENC_ASCII|ENC_NA);
1861 tree_offset += (int)sizeof(JXTA_MSGELEM_SIG);
1863 flags = tvb_get_guint8(tvb, tree_offset);
1864 flags_ti = proto_tree_add_uint(jxta_elem_tree, hf_jxta_element_flags, tvb, tree_offset, (int)sizeof(guint8), flags);
1865 jxta_elem_flags_tree = proto_item_add_subtree(flags_ti, ett_jxta_elem_2_flags);
1866 proto_tree_add_boolean(jxta_elem_flags_tree, hf_jxta_element2_flag_64bitlens, tvb, tree_offset, 1, flags);
1867 proto_tree_add_boolean(jxta_elem_flags_tree, hf_jxta_element2_flag_nameLiteral, tvb, tree_offset, 1, flags);
1868 proto_tree_add_boolean(jxta_elem_flags_tree, hf_jxta_element2_flag_hasType, tvb, tree_offset, 1, flags);
1869 proto_tree_add_boolean(jxta_elem_flags_tree, hf_jxta_element2_flag_hasSignature, tvb, tree_offset, 1, flags);
1870 proto_tree_add_boolean(jxta_elem_flags_tree, hf_jxta_element2_flag_hasEncoding, tvb, tree_offset, 1, flags);
1871 proto_tree_add_boolean(jxta_elem_flags_tree, hf_jxta_element2_flag_sigOfEncoded, tvb, tree_offset, 1, flags);
1872 tree_offset += (int)sizeof(guint8);
1874 /* Namespace */
1875 namespaceID = tvb_get_ntohs(tvb, tree_offset);
1876 namespace_ti =
1877 proto_tree_add_uint(jxta_elem_tree, hf_jxta_element2_namespaceid, tvb, tree_offset, (int)sizeof(guint16), namespaceID);
1878 if (namespaceID < names_count) {
1879 proto_item_append_text(namespace_ti, " (%s)", names_table[namespaceID]);
1880 } else {
1881 proto_item_append_text(namespace_ti, " * BAD *");
1883 tree_offset += (int)sizeof(guint16);
1885 /* Name */
1886 if ((flags & JXTAMSG2_ELMFLAG_NAME_LITERAL) == 0) {
1887 nameID = tvb_get_ntohs(tvb, tree_offset);
1888 name_ti =
1889 proto_tree_add_uint(jxta_elem_tree, hf_jxta_element2_nameid, tvb, tree_offset, (int)sizeof(guint16), nameID);
1890 if (namespaceID < names_count) {
1891 proto_item_append_text(name_ti, " (%s)", names_table[nameID]);
1892 } else {
1893 proto_item_append_text(name_ti, " * BAD *");
1895 tree_offset += (int)sizeof(guint16);
1896 } else {
1897 /* literal name */
1898 guint16 name_len = tvb_get_ntohs(tvb, tree_offset);
1899 proto_item_append_text(jxta_elem_tree_item, " \"%s\"", tvb_format_text(tvb, tree_offset + (int)sizeof(guint16), name_len));
1900 proto_tree_add_item(jxta_elem_tree, hf_jxta_element_name, tvb, tree_offset, (int)sizeof(guint16), ENC_ASCII|ENC_NA);
1901 tree_offset += (int)sizeof(guint16) + name_len;
1904 /* process type */
1905 if ((flags & JXTAMSG2_ELMFLAG_TYPE) != 0) {
1906 guint16 mimeID = tvb_get_ntohs(tvb, tree_offset);
1907 proto_item *mime_ti =
1908 proto_tree_add_uint(jxta_elem_tree, hf_jxta_element2_mimeid, tvb, tree_offset, (int)sizeof(guint16), mimeID);
1910 if (mimeID < names_count) {
1911 proto_item_append_text(mime_ti, " (%s)", names_table[mimeID]);
1912 mediatype = wmem_strdup( wmem_packet_scope(), names_table[mimeID] );
1913 } else {
1914 proto_item_append_text(mime_ti, " * BAD *");
1917 tree_offset += (int)sizeof(guint16);
1918 } else {
1919 mediatype = "application/octet-stream";
1922 /* process encoding */
1923 if ((flags & JXTAMSG2_ELMFLAG_ENCODINGS) != 0) {
1924 guint16 encodingID = tvb_get_ntohs(tvb, tree_offset);
1925 proto_item *encoding_ti =
1926 proto_tree_add_uint(jxta_elem_tree, hf_jxta_element2_encodingid, tvb, tree_offset, (int)sizeof(guint16), encodingID);
1928 if (encodingID < names_count) {
1929 proto_item_append_text(encoding_ti, " (%s)", names_table[encodingID]);
1930 } else {
1931 proto_item_append_text(encoding_ti, " * BAD *");
1934 tree_offset += (int)sizeof(guint16);
1938 if ((flags & JXTAMSG2_ELMFLAG_UINT64_LENS) != 0) {
1939 content_len = tvb_get_ntoh64(tvb, tree_offset);
1940 proto_tree_add_item(jxta_elem_tree, hf_jxta_element_content_len64, tvb, tree_offset, (int)sizeof(guint64), ENC_BIG_ENDIAN);
1941 tree_offset += (int)sizeof(guint64);
1942 } else {
1943 content_len = tvb_get_ntohl(tvb, tree_offset);
1944 proto_tree_add_item(jxta_elem_tree, hf_jxta_element_content_len, tvb, tree_offset, (int)sizeof(guint32), ENC_BIG_ENDIAN);
1945 tree_offset += (int)sizeof(guint32);
1948 /* content */
1949 element_content_tvb = tvb_new_subset(tvb, tree_offset, (gint)content_len, (gint)content_len);
1951 tree_offset += dissect_media(mediatype, element_content_tvb, pinfo, jxta_elem_tree);
1953 /* process the signature element */
1954 if ((flags & JXTAMSG2_ELMFLAG_SIGNATURE) != 0) {
1955 tvbuff_t *jxta_message_element_tvb = tvb_new_subset_remaining(tvb, tree_offset);
1957 tree_offset += dissect_jxta_message_element_1(jxta_message_element_tvb, pinfo, jxta_elem_tree, names_count, names_table);
1960 proto_item_set_end(jxta_elem_tree_item, tvb, tree_offset);
1962 DISSECTOR_ASSERT(tree_offset == offset);
1965 return offset;
1969 * Dissect a tvbuff containing arbitrary typed data.
1971 * <p/>We provide special handling for type media types :
1972 * <dl>
1973 * <dt>application/x-jxta-tls-block</dt>
1974 * <dd>We hand this data off to SSL to dissect.</dd>
1975 * <dt>application/gzip</dt>
1976 * <dd>We decompress the data and then dissect the contents as <tt>text/xml;charset="UTF-8"</tt></dd>
1977 * </dl>
1979 * @param fullmediatype The full media type of the buffer to dissect including params
1980 * @param tvb The buffer to dissect.
1981 * @param pinfo Packet Info.
1982 * @param tree The protocol tree.
1983 * @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
1984 * the packet was not recognized and negative if the dissector needs
1985 * more bytes in order to process a PDU.
1987 static int dissect_media( const gchar* fullmediatype, tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) {
1988 int dissected = 0;
1990 if (fullmediatype) {
1991 gchar *mediatype = wmem_strdup(wmem_packet_scope(), fullmediatype);
1992 gchar *parms_at = strchr(mediatype, ';');
1993 const char *save_match_string = pinfo->match_string;
1994 void * save_private_data = pinfo->private_data;
1996 /* Based upon what is done in packet-media.c we set up type and params */
1997 if (NULL != parms_at) {
1998 pinfo->private_data = wmem_strdup( wmem_packet_scope(), parms_at + 1 );
1999 *parms_at = '\0';
2000 } else {
2001 pinfo->private_data = NULL;
2004 /* Set the version that goes to packet-media.c before converting case */
2005 pinfo->match_string = wmem_strdup(wmem_packet_scope(), mediatype);
2007 /* force to lower case */
2008 ascii_strdown_inplace(mediatype);
2010 if (0 == strcmp("application/x-jxta-tls-block", mediatype)) {
2011 /* If we recognize it as a TLS packet then we shuffle it off to ssl dissector. */
2012 dissector_handle_t ssl_handle = find_dissector("ssl");
2013 if (NULL != ssl_handle) {
2014 dissected = call_dissector(ssl_handle, tvb, pinfo, tree);
2016 } else if (0 == strcmp("application/gzip", mediatype)) {
2017 tvbuff_t *uncomp_tvb = tvb_child_uncompress(tvb, tvb, 0, tvb_length(tvb));
2019 if( NULL != uncomp_tvb ) {
2020 add_new_data_source(pinfo, uncomp_tvb, "Uncompressed Element Content");
2022 /* XXX bondolo 20060201 Force XML for uncompressed data. */
2023 dissected = dissect_media("text/xml;charset=\"UTF-8\"", uncomp_tvb, pinfo, tree);
2025 if( dissected > 0 ) {
2026 /* report back the uncompressed length. */
2027 dissected = tvb_length(tvb);
2030 } else {
2031 dissected = dissector_try_string(media_type_dissector_table, mediatype, tvb, pinfo, tree, NULL) ? tvb_length(tvb) : 0;
2033 if( dissected != (int) tvb_length(tvb) ) {
2034 /* g_message( "%s : %d expected, %d dissected", mediatype, tvb_length(tvb), dissected ); */
2038 if (0 == dissected) {
2039 dissected = call_dissector(media_handle, tvb, pinfo, tree);
2042 pinfo->match_string = save_match_string;
2043 pinfo->private_data = save_private_data;
2046 if(0 == dissected) {
2047 /* display it as raw data */
2048 dissected = call_dissector_only(data_handle, tvb, pinfo, tree, NULL);
2051 return dissected;
2055 * Register jxta protocol and jxta message protocol, header fields, subtree types, preferences.
2057 void proto_register_jxta(void)
2059 module_t *jxta_module;
2061 /** our header fields */
2062 static hf_register_info hf[] = {
2063 {&hf_uri_addr,
2064 {"Address", "jxta.uri.addr", FT_STRING, BASE_NONE, NULL, 0x0,
2065 "URI Address (source or destination)", HFILL}
2067 {&hf_uri_src,
2068 {"Source", "jxta.uri.src", FT_STRING, BASE_NONE, NULL, 0x0,
2069 "URI Source", HFILL}
2071 {&hf_uri_dst,
2072 {"Destination", "jxta.uri.dst", FT_STRING, BASE_NONE, NULL, 0x0,
2073 "URI Destination", HFILL}
2075 {&hf_jxta_udp,
2076 {"JXTA UDP", "jxta.udp", FT_NONE, BASE_NONE, NULL, 0x0,
2077 NULL, HFILL}
2079 {&hf_jxta_udpsig,
2080 {"Signature", "jxta.udpsig", FT_STRING, BASE_NONE, NULL, 0x0,
2081 "JXTA UDP Signature", HFILL}
2083 {&hf_jxta_welcome,
2084 {"Welcome", "jxta.welcome", FT_NONE, BASE_NONE, NULL, 0x00,
2085 "JXTA Connection Welcome Message", HFILL}
2087 {&hf_jxta_welcome_initiator,
2088 {"Initiator", "jxta.welcome.initiator", FT_BOOLEAN, BASE_NONE, NULL, 0x00,
2089 "JXTA Connection Welcome Message Initiator", HFILL}
2091 {&hf_jxta_welcome_sig,
2092 {"Signature", "jxta.welcome.signature", FT_STRING, BASE_NONE, NULL, 0x0,
2093 "JXTA Connection Welcome Message Signature", HFILL}
2095 {&hf_jxta_welcome_destAddr,
2096 {"Destination Address", "jxta.welcome.destAddr", FT_STRING, BASE_NONE, NULL, 0x0,
2097 "JXTA Connection Welcome Message Destination Address", HFILL}
2099 {&hf_jxta_welcome_pubAddr,
2100 {"Public Address", "jxta.welcome.pubAddr", FT_STRING, BASE_NONE, NULL, 0x0,
2101 "JXTA Connection Welcome Message Public Address", HFILL}
2103 {&hf_jxta_welcome_peerid,
2104 {"PeerID", "jxta.welcome.peerid", FT_STRING, BASE_NONE, NULL, 0x0,
2105 "JXTA Connection Welcome Message PeerID", HFILL}
2107 {&hf_jxta_welcome_noProp,
2108 {"No Propagate Flag", "jxta.welcome.noPropFlag", FT_STRING, BASE_NONE, NULL, 0x0,
2109 "JXTA Connection Welcome Message No Propagate Flag", HFILL}
2111 {&hf_jxta_welcome_msgVers,
2112 {"Preferred Message Version", "jxta.welcome.msgVersion", FT_STRING, BASE_NONE, NULL, 0x0,
2113 "JXTA Connection Welcome Message Preferred Message Version", HFILL}
2115 {&hf_jxta_welcome_variable,
2116 {"Variable Parameter", "jxta.welcome.variable", FT_STRING, BASE_NONE, NULL, 0x0,
2117 "JXTA Connection Welcome Message Variable Parameter", HFILL}
2119 {&hf_jxta_welcome_version,
2120 {"Version", "jxta.welcome.version", FT_STRING, BASE_NONE, NULL, 0x0,
2121 "JXTA Connection Welcome Message Version", HFILL}
2123 {&hf_jxta_framing,
2124 {"Framing", "jxta.framing", FT_NONE, BASE_NONE, NULL, 0x0,
2125 "JXTA Message Framing", HFILL}
2127 {&hf_jxta_framing_header,
2128 {"Header", "jxta.framing.header", FT_NONE, BASE_NONE, NULL, 0x0,
2129 "JXTA Message Framing Header", HFILL}
2131 {&hf_jxta_framing_header_name,
2132 {"Name", "jxta.framing.header.name", FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2133 "JXTA Message Framing Header Name", HFILL}
2135 {&hf_jxta_framing_header_value_length,
2136 {"Value Length", "jxta.framing.header.valuelen", FT_UINT16, BASE_DEC, NULL, 0x0,
2137 "JXTA Message Framing Header Value Length", HFILL}
2139 {&hf_jxta_framing_header_value,
2140 {"Value", "jxta.framing.header.value", FT_BYTES, BASE_NONE, NULL, 0x0,
2141 "JXTA Message Framing Header Value", HFILL}
2143 {&hf_jxta_message_address,
2144 {"Address", "jxta.message.address", FT_STRING, BASE_NONE, NULL, 0x0,
2145 "JXTA Message Address (source or destination)", HFILL}
2147 {&hf_jxta_message_src,
2148 {"Source", "jxta.message.source", FT_STRING, BASE_NONE, NULL, 0x0,
2149 "JXTA Message Source", HFILL}
2151 {&hf_jxta_message_dst,
2152 {"Destination", "jxta.message.destination", FT_STRING, BASE_NONE, NULL, 0x0,
2153 "JXTA Message Destination", HFILL}
2155 {&hf_jxta_message_sig,
2156 {"Signature", "jxta.message.signature", FT_STRING, BASE_NONE, NULL, 0x0,
2157 "JXTA Message Signature", HFILL}
2159 {&hf_jxta_message_version,
2160 {"Version", "jxta.message.version", FT_UINT8, BASE_DEC, NULL, 0x0,
2161 "JXTA Message Version", HFILL}
2163 {&hf_jxta_message_flags,
2164 {"Flags", "jxta.message.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
2165 "JXTA Message Flags", HFILL}
2167 {&hf_jxta_message_flag_utf16be,
2168 {"UTF16BE", "jxta.message.flags.UTF-16BE", FT_BOOLEAN, 2, TFS(&tfs_set_notset), 0x01,
2169 "JXTA Message Element Flag -- UTF16-BE Strings", HFILL}
2171 {&hf_jxta_message_flag_ucs32be,
2172 {"UCS32BE", "jxta.message.flags.UCS32BE", FT_BOOLEAN, 2, TFS(&tfs_set_notset), 0x02,
2173 "JXTA Message Flag -- UCS32-BE Strings", HFILL}
2175 {&hf_jxta_message_names_count,
2176 {"Names Count", "jxta.message.names", FT_UINT16, BASE_DEC, NULL, 0x0,
2177 "JXTA Message Names Table", HFILL}
2179 {&hf_jxta_message_names_name,
2180 {"Names Table Name", "jxta.message.names.name", FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2181 "JXTA Message Names Table Name", HFILL}
2183 {&hf_jxta_message_element_count,
2184 {"Element Count", "jxta.message.elements", FT_UINT16, BASE_DEC, NULL, 0x0,
2185 "JXTA Message Element Count", HFILL}
2187 {&hf_jxta_element,
2188 {"JXTA Message Element", "jxta.message.element", FT_NONE, BASE_NONE, NULL, 0x0,
2189 NULL, HFILL}
2191 {&hf_jxta_element_sig,
2192 {"Signature", "jxta.message.element.signature", FT_STRING, BASE_NONE, NULL, 0x0,
2193 "JXTA Message Element Signature", HFILL}
2195 {&hf_jxta_element1_namespaceid,
2196 {"Namespace ID", "jxta.message.element.namespaceid", FT_UINT8, BASE_DEC, NULL, 0x0,
2197 "JXTA Message Element Namespace ID", HFILL}
2199 {&hf_jxta_element2_namespaceid,
2200 {"Namespace ID", "jxta.message.element.namespaceid", FT_UINT16, BASE_DEC, NULL, 0x0,
2201 "JXTA Message Element Namespace ID", HFILL}
2203 {&hf_jxta_element_flags,
2204 {"Flags", "jxta.message.element.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
2205 "JXTA Message Element Flags", HFILL}
2207 {&hf_jxta_element1_flag_hasType,
2208 {"hasType", "jxta.message.element.flags.hasType", FT_BOOLEAN, 3, TFS(&tfs_set_notset), 0x01,
2209 "JXTA Message Element Flag -- hasType", HFILL}
2211 {&hf_jxta_element1_flag_hasEncoding,
2212 {"hasEncoding", "jxta.message.element.flags.hasEncoding", FT_BOOLEAN, 3, TFS(&tfs_set_notset), 0x02,
2213 "JXTA Message Element Flag -- hasEncoding", HFILL}
2215 {&hf_jxta_element1_flag_hasSignature,
2216 {"hasSignature", "jxta.message.element.flags.hasSignature", FT_BOOLEAN, 3, TFS(&tfs_set_notset), 0x04,
2217 "JXTA Message Element Flag -- hasSignature", HFILL}
2219 {&hf_jxta_element2_flag_64bitlens,
2220 {"uint64Lens", "jxta.message.element.flags.uint64Lens", FT_BOOLEAN, 6, TFS(&tfs_set_notset), 0x01,
2221 "JXTA Message Element Flag -- uint64Lens", HFILL}
2223 {&hf_jxta_element2_flag_nameLiteral,
2224 {"nameLiteral", "jxta.message.element.flags.nameLiteral", FT_BOOLEAN, 6, TFS(&tfs_set_notset), 0x02,
2225 "JXTA Message Element Flag -- nameLiteral", HFILL}
2227 {&hf_jxta_element2_flag_hasType,
2228 {"hasEncoding", "jxta.message.element.flags.hasType", FT_BOOLEAN, 6, TFS(&tfs_set_notset), 0x04,
2229 "JXTA Message Element Flag -- hasType", HFILL}
2231 {&hf_jxta_element2_flag_hasSignature,
2232 {"hasSignature", "jxta.message.element.flags.hasSignature", FT_BOOLEAN, 6, TFS(&tfs_set_notset), 0x08,
2233 "JXTA Message Element Flag -- hasSignature", HFILL}
2235 {&hf_jxta_element2_flag_hasEncoding,
2236 {"hasSignature", "jxta.message.element.flags.hasEncoding", FT_BOOLEAN, 6, TFS(&tfs_set_notset), 0x10,
2237 "JXTA Message Element Flag -- hasEncoding", HFILL}
2239 {&hf_jxta_element2_flag_sigOfEncoded,
2240 {"sigOfEncoded", "jxta.message.element.flags.sigOfEncoded", FT_BOOLEAN, 6, TFS(&tfs_set_notset), 0x20,
2241 "JXTA Message Element Flag -- sigOfEncoded", HFILL}
2243 {&hf_jxta_element2_nameid,
2244 {"Name ID", "jxta.message.element.nameid", FT_UINT16, BASE_DEC, NULL, 0x0,
2245 "JXTA Message Element Name ID", HFILL}
2247 {&hf_jxta_element_name,
2248 {"Element Name", "jxta.message.element.name", FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2249 "JXTA Message Element Name", HFILL}
2251 {&hf_jxta_element2_mimeid,
2252 {"MIME ID", "jxta.message.element.mimeid", FT_UINT16, BASE_DEC, NULL, 0x0,
2253 "JXTA Message Element MIME ID", HFILL}
2255 {&hf_jxta_element2_encodingid,
2256 {"Encoding ID", "jxta.message.element.encodingid", FT_UINT16, BASE_DEC, NULL, 0x0,
2257 "JXTA Message Element Encoding ID", HFILL}
2259 {&hf_jxta_element_type,
2260 {"Element Type", "jxta.message.element.type", FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2261 "JXTA Message Element Name", HFILL}
2263 {&hf_jxta_element_encoding,
2264 {"Element Type", "jxta.message.element.encoding", FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2265 "JXTA Message Element Encoding", HFILL}
2267 {&hf_jxta_element_content_len,
2268 {"Element Content Length", "jxta.message.element.content.length", FT_UINT32, BASE_DEC, NULL, 0x0,
2269 "JXTA Message Element Content Length", HFILL}
2271 {&hf_jxta_element_content_len64,
2272 {"Element Content Length", "jxta.message.element.content.length", FT_UINT64, BASE_DEC, NULL, 0x0,
2273 "JXTA Message Element Content Length", HFILL}
2275 #if 0
2276 {&hf_jxta_element_content,
2277 {"Element Content", "jxta.message.element.content", FT_BYTES, BASE_NONE, NULL, 0x0,
2278 "JXTA Message Element Content", HFILL}
2280 #endif
2283 proto_jxta = proto_register_protocol("JXTA P2P", "JXTA", "jxta");
2285 jxta_tap = register_tap("jxta");
2287 proto_message_jxta = proto_register_protocol("JXTA Message", "JXTA Message", "jxta.message");
2289 new_register_dissector("jxta.udp", dissect_jxta_udp, proto_jxta);
2290 new_register_dissector("jxta.stream", dissect_jxta_stream, proto_jxta);
2292 /* Register header fields */
2293 proto_register_field_array(proto_jxta, hf, array_length(hf));
2295 /* Register JXTA Sub-tree */
2296 proto_register_subtree_array(ett, array_length(ett));
2298 /* Register preferences */
2299 /* register re-init routine */
2300 jxta_module = prefs_register_protocol(proto_jxta, proto_reg_handoff_jxta);
2302 prefs_register_bool_preference(jxta_module, "msg.mediatype", "Register binary JXTA Message as a media type",
2303 "Enable to have correctly typed MIME media dissected as JXTA Messages.", &gMSG_MEDIA);
2305 prefs_register_bool_preference(jxta_module, "desegment",
2306 "Reassemble JXTA messages spanning multiple UDP/TCP/SCTP segments",
2307 "Whether the JXTA dissector should reassemble messages spanning multiple UDP/TCP/SCTP segments."
2308 " To use this option you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings "
2309 " and enable \"Reassemble fragmented IP datagrams\" in the IP protocol settings.",
2310 &gDESEGMENT);
2312 prefs_register_bool_preference(jxta_module, "udp.heuristic", "Try to discover JXTA in UDP datagrams",
2313 "Enable to inspect UDP datagrams for JXTA messages.", &gUDP_HEUR);
2315 prefs_register_bool_preference(jxta_module, "tcp.heuristic", "Try to discover JXTA in TCP connections",
2316 "Enable to inspect TCP connections for JXTA conversations.", &gTCP_HEUR);
2318 prefs_register_bool_preference(jxta_module, "sctp.heuristic", "Try to discover JXTA in SCTP connections",
2319 "Enable to inspect SCTP connections for JXTA conversations.", &gSCTP_HEUR);
2324 * Update registrations in response to preferences changes.
2326 void proto_reg_handoff_jxta(void)
2328 static gboolean init_done = FALSE;
2329 static dissector_handle_t message_jxta_handle;
2331 static gboolean msg_media_register_done = FALSE;
2332 static gboolean udp_register_done = FALSE;
2333 static gboolean tcp_register_done = FALSE;
2334 static gboolean sctp_register_done = FALSE;
2336 if(!init_done) {
2337 message_jxta_handle = new_create_dissector_handle(dissect_jxta_message, proto_message_jxta);
2338 stream_jxta_handle = find_dissector("jxta.stream");
2340 media_type_dissector_table = find_dissector_table("media_type");
2342 data_handle = find_dissector("data");
2343 media_handle = find_dissector("media");
2345 init_done = TRUE;
2348 if( gMSG_MEDIA ) {
2349 if( !msg_media_register_done ) {
2350 /* g_message( "Registering JXTA Message media type" ); */
2351 dissector_add_string("media_type", "application/x-jxta-msg", message_jxta_handle);
2352 msg_media_register_done = TRUE;
2354 } else {
2355 if( msg_media_register_done ) {
2356 /* g_message( "Deregistering JXTA Message media type" ); */
2357 dissector_delete_string("media_type", "application/x-jxta-msg", message_jxta_handle);
2358 msg_media_register_done = FALSE;
2362 if( gUDP_HEUR ) {
2363 if( !udp_register_done ) {
2364 /* g_message( "Registering UDP Heuristic dissector" ); */
2365 heur_dissector_add("udp", dissect_jxta_UDP_heur, proto_jxta);
2366 udp_register_done = TRUE;
2368 } else {
2369 if( udp_register_done ) {
2370 /* g_message( "Deregistering UDP Heuristic dissector" ); */
2371 heur_dissector_delete("udp", dissect_jxta_UDP_heur, proto_jxta);
2372 udp_register_done = FALSE;
2376 if( gTCP_HEUR ) {
2377 if( !tcp_register_done ) {
2378 /* g_message( "Registering TCP Heuristic dissector" ); */
2379 heur_dissector_add("tcp", dissect_jxta_TCP_heur, proto_jxta);
2380 tcp_register_done = TRUE;
2382 } else {
2383 if( tcp_register_done ) {
2384 /* g_message( "Deregistering TCP Heuristic dissector" ); */
2385 heur_dissector_delete("tcp", dissect_jxta_TCP_heur, proto_jxta);
2386 tcp_register_done = FALSE;
2390 if( gSCTP_HEUR ) {
2391 if( !sctp_register_done ) {
2392 /* g_message( "Registering SCTP Heuristic dissector" ); */
2393 heur_dissector_add("sctp", dissect_jxta_SCTP_heur, proto_jxta);
2394 sctp_register_done = TRUE;
2396 } else {
2397 if( sctp_register_done ) {
2398 /* g_message( "Deregistering SCTP Heuristic dissector" ); */
2399 heur_dissector_delete("sctp", dissect_jxta_SCTP_heur, proto_jxta);
2400 sctp_register_done = FALSE;