Change COPY_ADDRESS to SE_COPY_ADDRESS: all of these appear to have "seasonal" scope...
[obnox/wireshark/wip.git] / epan / dissectors / packet-jxta.c
1 /* packet-jxta.c
2  * Routines for JXTA packet dissection
3  * Copyright 2004-06, Mike Duigou <bondolo@jxta.org>
4  * Heavily based on packet-jabber.c, which in turn is heavily based on
5  * on packet-acap.c, which in turn is heavily based on
6  * packet-imap.c, Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
7  *
8  * $Id$
9  *
10  * Wireshark - Network traffic analyzer
11  * By Gerald Combs <gerald@wireshark.org>
12  * Copyright 1998 Gerald Combs
13  *
14  * Copied from packet-pop.c, packet-jabber.c, packet-udp.c
15  *
16  * JXTA specification from http://spec.jxta.org
17  *
18  * This program is free software; you can redistribute it and/or
19  * modify it under the terms of the GNU General Public License
20  * as published by the Free Software Foundation; either version 2
21  * of the License, or (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program; if not, write to the Free Software
30  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
31  */
32
33 #ifdef HAVE_CONFIG_H
34 # include "config.h"
35 #endif
36
37 #include <limits.h>
38 #include <stdio.h>
39 #include <string.h>
40
41 #include <glib.h>
42
43 #include <epan/packet.h>
44 #include <epan/conversation.h>
45 #include <epan/strutil.h>
46 #include <epan/prefs.h>
47 #include <epan/tap.h>
48 #include <epan/emem.h>
49 #include <epan/ws_strsplit.h>
50
51 #include "packet-jxta.h"
52
53 static const gchar JXTA_UDP_SIG[] = { 'J', 'X', 'T', 'A' };
54 static const gchar JXTA_MSG_SIG[] = { 'j', 'x', 'm', 'g' };
55 static const gchar JXTA_MSGELEM_SIG[] = { 'j', 'x', 'e', 'l' };
56
57 static const gchar JXTA_WELCOME_MSG_SIG[] = { 'J', 'X', 'T', 'A', 'H', 'E', 'L', 'L', 'O', ' ' };
58
59 static const gchar* JXTA_WELCOME_MSG_VERSION_1_1 = "1.1";
60 static const gchar* JXTA_WELCOME_MSG_VERSION_3_0 = "3.0";
61
62 static const int JXTA_MSG_VERSION_1 = 0;
63 static const int JXTA_MSG_VERSION_2 = 1;
64
65 static const int JXTAMSG1_ELMFLAG_TYPE = 1 << 0;
66 static const int JXTAMSG1_ELMFLAG_ENCODING = 1 << 1;
67 static const int JXTAMSG1_ELMFLAG_SIGNATURE = 1 << 2;
68
69 static const int JXTAMSG2_ELMFLAG_UINT64_LENS = 1 << 0;
70 static const int JXTAMSG2_ELMFLAG_NAME_LITERAL = 1 << 1;
71 static const int JXTAMSG2_ELMFLAG_TYPE = 1 << 2;
72 static const int JXTAMSG2_ELMFLAG_SIGNATURE = 1 << 3;
73 static const int JXTAMSG2_ELMFLAG_ENCODINGS = 1 << 4;
74
75 static int proto_jxta = -1;
76 static int proto_message_jxta = -1;
77 static int jxta_tap = -1;
78
79 static dissector_table_t media_type_dissector_table = NULL;
80 static dissector_handle_t data_handle = NULL;
81 static dissector_handle_t stream_jxta_handle = NULL;
82 static dissector_handle_t message_jxta_handle;
83
84 static int hf_jxta_udp = -1;
85 static int hf_jxta_udpsig = -1;
86 static int hf_jxta_welcome = -1;
87 static int hf_jxta_welcome_initiator = -1;
88 static int hf_jxta_welcome_sig = -1;
89 static int hf_jxta_welcome_destAddr = -1;
90 static int hf_jxta_welcome_pubAddr = -1;
91 static int hf_jxta_welcome_peerid = -1;
92 static int hf_jxta_welcome_noProp = -1;
93 static int hf_jxta_welcome_msgVers = -1;
94 static int hf_jxta_welcome_variable = -1;
95 static int hf_jxta_welcome_version = -1;
96 static int hf_jxta_framing = -1;
97 static int hf_jxta_framing_header = -1;
98 static int hf_jxta_framing_header_name = -1;
99 static int hf_jxta_framing_header_value_length = -1;
100 static int hf_jxta_framing_header_value = -1;
101 static int hf_jxta_message_address = -1;
102 static int hf_jxta_message_src = -1;
103 static int hf_jxta_message_dst = -1;
104 static int hf_jxta_message_sig = -1;
105 static int hf_jxta_message_version = -1;
106 static int hf_jxta_message_flags = -1;
107 static int hf_jxta_message_flag_utf16be = -1;
108 static int hf_jxta_message_flag_ucs32be = -1;
109 static int hf_jxta_message_names_count = -1;
110 static int hf_jxta_message_names_name = -1;
111 static int hf_jxta_message_element_count = -1;
112 static int hf_jxta_element = -1;
113 static int hf_jxta_element_sig = -1;
114 static int hf_jxta_element1_namespaceid = -1;
115 static int hf_jxta_element2_namespaceid = -1;
116 static int hf_jxta_element2_nameid = -1;
117 static int hf_jxta_element2_mimeid = -1;
118 static int hf_jxta_element2_encodingid = -1;
119 static int hf_jxta_element_flags = -1;
120 static int hf_jxta_element1_flag_hasType = -1;
121 static int hf_jxta_element1_flag_hasEncoding = -1;
122 static int hf_jxta_element1_flag_hasSignature = -1;
123 static int hf_jxta_element2_flag_64bitlens = -1;
124 static int hf_jxta_element2_flag_nameLiteral = -1;
125 static int hf_jxta_element2_flag_hasType = -1;
126 static int hf_jxta_element2_flag_hasSignature = -1;
127 static int hf_jxta_element2_flag_hasEncoding = -1;
128 static int hf_jxta_element2_flag_sigOfEncoded = -1;
129 static int hf_jxta_element_name = -1;
130 static int hf_jxta_element_type = -1;
131 static int hf_jxta_element_encoding = -1;
132 static int hf_jxta_element_content_len = -1;
133 static int hf_jxta_element_content_len64 = -1;
134 static int hf_jxta_element_content = -1;
135
136 /** our header fields */
137 static hf_register_info hf[] = {
138     {&hf_jxta_udp,
139      {"JXTA UDP", "jxta.udp", FT_NONE, BASE_NONE, NULL, 0x0,
140       "JXTA UDP", HFILL}
141      },
142     {&hf_jxta_udpsig,
143      {"Signature", "jxta.udpsig", FT_STRING, BASE_NONE, NULL, 0x0,
144       "JXTA UDP Signature", HFILL}
145      },
146     {&hf_jxta_welcome,
147      {"Welcome", "jxta.welcome", FT_NONE, BASE_NONE, NULL, 0x00,
148       "JXTA Connection Welcome Message", HFILL}
149      },
150     {&hf_jxta_welcome_initiator,
151      {"Initiator", "jxta.welcome.initiator", FT_BOOLEAN, BASE_NONE, NULL, 0x00,
152       "JXTA Connection Welcome Message Initiator", HFILL}
153      },
154     {&hf_jxta_welcome_sig,
155      {"Signature", "jxta.welcome.signature", FT_STRING, BASE_NONE, NULL, 0x0,
156       "JXTA Connection Welcome Message Signature", HFILL}
157      },
158     {&hf_jxta_welcome_destAddr,
159      {"Destination Address", "jxta.welcome.destAddr", FT_STRING, BASE_NONE, NULL, 0x0,
160       "JXTA Connection Welcome Message Destination Address", HFILL}
161      },
162     {&hf_jxta_welcome_pubAddr,
163      {"Public Address", "jxta.welcome.pubAddr", FT_STRING, BASE_NONE, NULL, 0x0,
164       "JXTA Connection Welcome Message Public Address", HFILL}
165      },
166     {&hf_jxta_welcome_peerid,
167      {"PeerID", "jxta.welcome.peerid", FT_STRING, BASE_NONE, NULL, 0x0,
168       "JXTA Connection Welcome Message PeerID", HFILL}
169      },
170     {&hf_jxta_welcome_noProp,
171      {"No Propagate Flag", "jxta.welcome.noPropFlag", FT_STRING, BASE_NONE, NULL, 0x0,
172       "JXTA Connection Welcome Message No Propagate Flag", HFILL}
173      },
174     {&hf_jxta_welcome_msgVers,
175      {"Preferred Message Version", "jxta.welcome.msgVersion", FT_STRING, BASE_NONE, NULL, 0x0,
176       "JXTA Connection Welcome Message Preferred Message Version", HFILL}
177      },
178     {&hf_jxta_welcome_variable,
179      {"Variable Parameter", "jxta.welcome.variable", FT_STRING, BASE_NONE, NULL, 0x0,
180       "JXTA Connection Welcome Message Variable Parameter", HFILL}
181      },
182     {&hf_jxta_welcome_version,
183      {"Version", "jxta.welcome.version", FT_STRING, BASE_NONE, NULL, 0x0,
184       "JXTA Connection Welcome Message Version", HFILL}
185      },
186     {&hf_jxta_framing,
187      {"Framing", "jxta.framing", FT_NONE, BASE_NONE, NULL, 0x0,
188       "JXTA Message Framing", HFILL}
189      },
190     {&hf_jxta_framing_header,
191      {"Header", "jxta.framing.header", FT_NONE, BASE_NONE, NULL, 0x0,
192       "JXTA Message Framing Header", HFILL}
193      },
194     {&hf_jxta_framing_header_name,
195      {"Name", "jxta.framing.header.name", FT_UINT_STRING, BASE_NONE, NULL, 0x0,
196       "JXTA Message Framing Header Name", HFILL}
197      },
198     {&hf_jxta_framing_header_value_length,
199      {"Value Length", "jxta.framing.header.valuelen", FT_UINT16, BASE_DEC, NULL, 0x0,
200       "JXTA Message Framing Header Value Length", HFILL}
201      },
202     {&hf_jxta_framing_header_value,
203      {"Value", "jxta.framing.header.value", FT_BYTES, BASE_HEX, NULL, 0x0,
204       "JXTA Message Framing Header Value", HFILL}
205      },
206     {&hf_jxta_message_address,
207      {"Address", "jxta.message.address", FT_STRING, BASE_NONE, NULL, 0x0,
208       "JXTA Message Address (source or destination)", HFILL}
209      },
210     {&hf_jxta_message_src,
211      {"Source", "jxta.message.source", FT_STRING, BASE_NONE, NULL, 0x0,
212       "JXTA Message Source", HFILL}
213      },
214     {&hf_jxta_message_dst,
215      {"Destination", "jxta.message.destination", FT_STRING, BASE_NONE, NULL, 0x0,
216       "JXTA Message Destination", HFILL}
217      },
218     {&hf_jxta_message_sig,
219      {"Signature", "jxta.message.signature", FT_STRING, BASE_NONE, NULL, 0x0,
220       "JXTA Message Signature", HFILL}
221      },
222     {&hf_jxta_message_version,
223      {"Version", "jxta.message.version", FT_UINT8, BASE_DEC, NULL, 0x0,
224       "JXTA Message Version", HFILL}
225      },
226     {&hf_jxta_message_flags,
227      {"Flags", "jxta.message.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
228       "JXTA Message Flags", HFILL}
229      },
230     {&hf_jxta_message_flag_utf16be,
231      {"UTF16BE", "jxta.message.flags.UTF-16BE", FT_BOOLEAN, 2, TFS(&flags_set_truth), 0x01,
232       "JXTA Message Element Flag -- UTF16-BE Strings", HFILL}
233      },
234     {&hf_jxta_message_flag_ucs32be,
235      {"UCS32BE", "jxta.message.flags.UCS32BE", FT_BOOLEAN, 2, TFS(&flags_set_truth), 0x02,
236       "JXTA Message Flag -- UCS32-BE Strings", HFILL}
237      },
238     {&hf_jxta_message_names_count,
239      {"Names Count", "jxta.message.names", FT_UINT16, BASE_DEC, NULL, 0x0,
240       "JXTA Message Names Table", HFILL}
241      },
242     {&hf_jxta_message_names_name,
243      {"Names Table Name", "jxta.message.names.name", FT_UINT_STRING, BASE_NONE, NULL, 0x0,
244       "JXTA Message Names Table Name", HFILL}
245      },
246     {&hf_jxta_message_element_count,
247      {"Element Count", "jxta.message.elements", FT_UINT16, BASE_DEC, NULL, 0x0,
248       "JXTA Message Element Count", HFILL}
249      },
250     {&hf_jxta_element,
251      {"JXTA Message Element", "jxta.message.element", FT_NONE, BASE_NONE, NULL, 0x0,
252       "JXTA Message Element", HFILL}
253      },
254     {&hf_jxta_element_sig,
255      {"Signature", "jxta.message.element.signature", FT_STRING, BASE_NONE, NULL, 0x0,
256       "JXTA Message Element Signature", HFILL}
257      },
258     {&hf_jxta_element1_namespaceid,
259      {"Namespace ID", "jxta.message.element.namespaceid", FT_UINT8, BASE_DEC, NULL, 0x0,
260       "JXTA Message Element Namespace ID", HFILL}
261      },
262     {&hf_jxta_element2_namespaceid,
263      {"Namespace ID", "jxta.message.element.namespaceid", FT_UINT16, BASE_DEC, NULL, 0x0,
264       "JXTA Message Element Namespace ID", HFILL}
265      },
266     {&hf_jxta_element_flags,
267      {"Flags", "jxta.message.element.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
268       "JXTA Message Element Flags", HFILL}
269      },
270     {&hf_jxta_element1_flag_hasType,
271      {"hasType", "jxta.message.element.flags.hasType", FT_BOOLEAN, 3, TFS(&flags_set_truth), 0x01,
272       "JXTA Message Element Flag -- hasType", HFILL}
273      },
274     {&hf_jxta_element1_flag_hasEncoding,
275      {"hasEncoding", "jxta.message.element.flags.hasEncoding", FT_BOOLEAN, 3, TFS(&flags_set_truth), 0x02,
276       "JXTA Message Element Flag -- hasEncoding", HFILL}
277      },
278     {&hf_jxta_element1_flag_hasSignature,
279      {"hasSignature", "jxta.message.element.flags.hasSignature", FT_BOOLEAN, 3, TFS(&flags_set_truth), 0x04,
280       "JXTA Message Element Flag -- hasSignature", HFILL}
281      },
282     {&hf_jxta_element2_flag_64bitlens,
283      {"uint64Lens", "jxta.message.element.flags.uint64Lens", FT_BOOLEAN, 6, TFS(&flags_set_truth), 0x01,
284       "JXTA Message Element Flag -- uint64Lens", HFILL}
285      },
286     {&hf_jxta_element2_flag_nameLiteral,
287      {"nameLiteral", "jxta.message.element.flags.nameLiteral", FT_BOOLEAN, 6, TFS(&flags_set_truth), 0x02,
288       "JXTA Message Element Flag -- nameLiteral", HFILL}
289      },
290     {&hf_jxta_element2_flag_hasType,
291      {"hasEncoding", "jxta.message.element.flags.hasType", FT_BOOLEAN, 6, TFS(&flags_set_truth), 0x04,
292       "JXTA Message Element Flag -- hasType", HFILL}
293      },
294     {&hf_jxta_element2_flag_hasSignature,
295      {"hasSignature", "jxta.message.element.flags.hasSignature", FT_BOOLEAN, 6, TFS(&flags_set_truth), 0x08,
296       "JXTA Message Element Flag -- hasSignature", HFILL}
297      },
298     {&hf_jxta_element2_flag_hasEncoding,
299      {"hasSignature", "jxta.message.element.flags.hasEncoding", FT_BOOLEAN, 6, TFS(&flags_set_truth), 0x10,
300       "JXTA Message Element Flag -- hasEncoding", HFILL}
301      },
302     {&hf_jxta_element2_flag_sigOfEncoded,
303      {"sigOfEncoded", "jxta.message.element.flags.sigOfEncoded", FT_BOOLEAN, 6, TFS(&flags_set_truth), 0x20,
304       "JXTA Message Element Flag -- sigOfEncoded", HFILL}
305      },
306     {&hf_jxta_element2_nameid,
307      {"Name ID", "jxta.message.element.nameid", FT_UINT16, BASE_DEC, NULL, 0x0,
308       "JXTA Message Element Name ID", HFILL}
309      },
310     {&hf_jxta_element_name,
311      {"Element Name", "jxta.message.element.name", FT_UINT_STRING, BASE_NONE, NULL, 0x0,
312       "JXTA Message Element Name", HFILL}
313      },
314     {&hf_jxta_element2_mimeid,
315      {"MIME ID", "jxta.message.element.mimeid", FT_UINT16, BASE_DEC, NULL, 0x0,
316       "JXTA Message Element MIME ID", HFILL}
317      },
318     {&hf_jxta_element_type,
319      {"Element Type", "jxta.message.element.type", FT_UINT_STRING, BASE_NONE, NULL, 0x0,
320       "JXTA Message Element Name", HFILL}
321      },
322     {&hf_jxta_element_encoding,
323      {"Element Type", "jxta.message.element.encoding", FT_UINT_STRING, BASE_NONE, NULL, 0x0,
324       "JXTA Message Element Encoding", HFILL}
325      },
326     {&hf_jxta_element_content_len,
327      {"Element Content Length", "jxta.message.element.content.length", FT_UINT32, BASE_DEC, NULL, 0x0,
328       "JXTA Message Element Content Length", HFILL}
329      },
330     {&hf_jxta_element_content_len64,
331      {"Element Content Length", "jxta.message.element.content.length", FT_UINT64, BASE_DEC, NULL, 0x0,
332       "JXTA Message Element Content Length", HFILL}
333      },
334     {&hf_jxta_element_content,
335      {"Element Content", "jxta.message.element.content", FT_BYTES, BASE_HEX, NULL, 0x0,
336       "JXTA Message Element Content", HFILL}
337      },
338 };
339
340 /**
341 *    JXTA Protocol subtree handles
342 **/
343 static gint ett_jxta = -1;
344 static gint ett_jxta_welcome = -1;
345 static gint ett_jxta_udp = -1;
346 static gint ett_jxta_framing = -1;
347 static gint ett_jxta_framing_header = -1;
348 static gint ett_jxta_msg = -1;
349 static gint ett_jxta_msg_flags = -1;
350 static gint ett_jxta_elem = -1;
351 static gint ett_jxta_elem_1_flags = -1;
352 static gint ett_jxta_elem_2_flags = -1;
353
354 /**
355 *   JXTA Protocol subtree array
356 **/
357 static gint *const ett[] = {
358     &ett_jxta,
359     &ett_jxta_welcome,
360     &ett_jxta_udp,
361     &ett_jxta_framing,
362     &ett_jxta_framing_header,
363     &ett_jxta_msg,
364     &ett_jxta_msg_flags,
365     &ett_jxta_elem,
366     &ett_jxta_elem_1_flags,
367     &ett_jxta_elem_2_flags
368 };
369
370 /**
371 *   global preferences
372 **/
373 static gboolean gDESEGMENT = TRUE;
374 static gboolean gUDP_HEUR = TRUE;
375 static gboolean gTCP_HEUR = TRUE;
376 static gboolean gSCTP_HEUR = FALSE;
377
378 /**
379 *   Stream Conversation data
380 **/
381 struct jxta_stream_conversation_data {
382     port_type tpt_ptype;
383
384     address initiator_tpt_address;
385     guint32 initiator_tpt_port;
386     guint32 initiator_welcome_frame;
387     address initiator_address;
388
389     address receiver_tpt_address;
390     guint32 receiver_tpt_port;
391     guint32 receiver_welcome_frame;
392     address receiver_address;
393 };
394
395 typedef struct jxta_stream_conversation_data jxta_stream_conversation_data;
396
397 /**
398 *   Prototypes
399 **/
400 static gboolean dissect_jxta_UDP_heur(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree);
401 static gboolean dissect_jxta_TCP_heur(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree);
402 static gboolean dissect_jxta_SCTP_heur(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree);
403
404 static int dissect_jxta_udp(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree);
405 static int dissect_jxta_stream(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree);
406 static conversation_t *get_tpt_conversation(packet_info * pinfo, gboolean create);
407
408 static int dissect_jxta_welcome(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, address * found_addr, gboolean initiator);
409 static int dissect_jxta_message_framing(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, guint64 * content_length,
410                                         gchar ** content_type);
411 static int dissect_jxta_message(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree);
412 static int dissect_jxta_message_element_1(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, guint ns_count,
413                                         const gchar ** namespaces);
414 static int dissect_jxta_message_element_2(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, guint ns_count,
415                                         const gchar ** namespaces);
416
417 void proto_reg_handoff_jxta(void);
418
419 /**
420 *   Heuristically dissect a tvbuff containing a JXTA UDP Message
421 *
422 *   @param  tvb The buffer to dissect.
423 *   @param  pinfo Packet Info.
424 *   @param  tree The protocol tree.
425 *   @return TRUE if the tvb contained JXTA data which was dissected otherwise FALSE
426 **/
427 static gboolean dissect_jxta_UDP_heur(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
428 {
429     /* This is a heuristic dissector, which means we get all the UDP
430      * traffic not sent to a known dissector and not claimed by
431      * a heuristic dissector called before us!
432      */
433     int save_desegment_offset;
434     guint32 save_desegment_len;
435     int ret;
436
437     if (!gUDP_HEUR)
438         return FALSE;
439
440     if (tvb_memeql(tvb, 0, JXTA_UDP_SIG, sizeof(JXTA_UDP_SIG)) != 0) {
441         return FALSE;
442     }
443
444     save_desegment_offset = pinfo->desegment_offset;
445     save_desegment_len = pinfo->desegment_len;
446     ret = dissect_jxta_udp(tvb, pinfo, tree);
447     if (ret < 0) {
448         /*
449          * UDP is not a packet stream protocol, so the UDP dissector
450          * should not, and will not, do the sort of dissection help
451          * that the TCP dissector will.  If JXTA messages don't
452          * start and end on UDP packet boundaries, the JXTA dissector
453          * will have to do its own byte stream reassembly.
454          */
455         pinfo->desegment_offset = save_desegment_offset;
456         pinfo->desegment_len = save_desegment_len;
457         return FALSE;
458     } else if (ret == 0) {
459         /*
460          * A clear rejection.
461          */
462         pinfo->desegment_offset = save_desegment_offset;
463         pinfo->desegment_len = save_desegment_len;
464         return FALSE;
465     } else {
466         /*
467          * A clear acceptance.
468          */
469         return TRUE;
470     }
471 }
472
473 /**
474 *   Heuristically dissect a tvbuff containing a JXTA TCP Stream
475 *
476 *   @param  tvb The buffer to dissect.
477 *   @param  pinfo Packet Info.
478 *   @param  tree The protocol tree.
479 *   @return TRUE if the tvb contained JXTA data which was dissected otherwise FALSE
480 **/
481 static gboolean dissect_jxta_TCP_heur(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
482 {
483     /* This is a heuristic dissector, which means we get all the TCP
484      * traffic not sent to a known dissector and not claimed by
485      * a heuristic dissector called before us!
486      */
487     int save_desegment_offset;
488     guint32 save_desegment_len;
489     int ret;
490
491     if (!gTCP_HEUR)
492         return FALSE;
493
494     save_desegment_offset = pinfo->desegment_offset;
495     save_desegment_len = pinfo->desegment_len;
496     ret = dissect_jxta_stream(tvb, pinfo, tree);
497     if (ret < 0) {
498         /*
499          * A heuristic dissector for a TCP-based protocol can reject
500          * a packet, or it can request that more data be provided.
501          * It must not attempt to do both, as the notion of doing both
502          * is nonsensical - if the packet isn't considered a packet
503          * for the dissector's protocol, that dissector won't be
504          * dissecting it no matter *how* much more data is added.
505          *
506          * Therefore, we treat a negative return from
507          * dissect_jxta_stream() as a rejection.
508          *
509          * If that's not desired - i.e., if we should keep trying to get
510          * more data, in the hopes that we'll eventually be able to
511          * determine whether the packet is a JXTA packet or not - we
512          * should, in this case, leave pinfo->desegment_offset and
513          * pinfo->desegment_len alone, and return TRUE, *NOT* FALSE.
514          */
515         pinfo->desegment_offset = save_desegment_offset;
516         pinfo->desegment_len = save_desegment_len;
517         return FALSE;
518     } else if (ret == 0) {
519         /*
520          * A clear rejection.
521          */
522         pinfo->desegment_offset = save_desegment_offset;
523         pinfo->desegment_len = save_desegment_len;
524         return FALSE;
525     } else {
526         /*
527          * A clear acceptance.
528          */
529         return TRUE;
530     }
531 }
532
533 /**
534 *   Heuristically dissect a tvbuff containing a JXTA SCTP Stream
535 *
536 *   @param  tvb The buffer to dissect.
537 *   @param  pinfo Packet Info.
538 *   @param  tree The protocol tree.
539 *   @return TRUE if the tvb contained JXTA data which was dissected otherwise FALSE
540 **/
541 static gboolean dissect_jxta_SCTP_heur(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
542 {
543     /* This is a heuristic dissector, which means we get all the SCTP
544      * traffic not sent to a known dissector and not claimed by
545      * a heuristic dissector called before us!
546      */
547     int save_desegment_offset;
548     guint32 save_desegment_len;
549     int ret;
550
551     if (!gSCTP_HEUR)
552         return FALSE;
553
554     save_desegment_offset = pinfo->desegment_offset;
555     save_desegment_len = pinfo->desegment_len;
556     ret = dissect_jxta_stream(tvb, pinfo, tree);
557     if (ret < 0) {
558         /*
559          * SCTP is not a byte stream protocol, so the SCTP dissector
560          * should not, and will not, do the sort of dissection help
561          * that the SCTP dissector will.  If JXTA messages don't
562          * start and end on SCTP packet boundaries, the JXTA dissector
563          * will have to do its own byte stream reassembly.
564          *
565          * The SCTP dissector currently won't do reassembly.  If that
566          * causes a problem for the JXTA dissector, the correct fix
567          * is to implement reassembly in the SCTP dissector, so *all*
568          * dissectors for protocols running atop SCTP can benefit from
569          * it.
570          */
571         pinfo->desegment_offset = save_desegment_offset;
572         pinfo->desegment_len = save_desegment_len;
573         return FALSE;
574     } else if (ret == 0) {
575         /*
576          * A clear rejection.
577          */
578         pinfo->desegment_offset = save_desegment_offset;
579         pinfo->desegment_len = save_desegment_len;
580         return FALSE;
581     } else {
582         /*
583          * A clear acceptance.
584          */
585         return TRUE;
586     }
587 }
588
589 /**
590 *   Dissect a tvbuff containing a JXTA UDP header, JXTA Message framing and a JXTA Message
591 *
592 *   @param  tvb The buffer to dissect.
593 *   @param  pinfo Packet Info.
594 *   @param  tree The protocol tree.
595 *   @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
596 *           the packet was not recognized as a JXTA packet and negative if the
597 *           dissector needs more bytes in order to process a PDU.
598 **/
599 static int dissect_jxta_udp(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
600 {
601     guint offset = 0;
602     guint available;
603     gint needed = 0;
604
605     conversation_t *conversation =
606         find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
607
608     if (conversation == NULL) {
609         /*
610          * No conversation exists yet - create one.
611          */
612         conversation =
613             conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
614     }
615
616     DISSECTOR_ASSERT(find_dissector("jxta.udp"));
617
618     conversation_set_dissector(conversation, find_dissector("jxta.udp"));
619
620     while (TRUE) {
621         tvbuff_t *jxta_message_framing_tvb;
622         gint processed = 0;
623         guint64 content_length = -1;
624         gchar *content_type = NULL;
625
626         available = tvb_reported_length_remaining(tvb, offset);
627         if (available < sizeof(JXTA_UDP_SIG)) {
628             needed = (gint) (sizeof(JXTA_UDP_SIG) - available);
629             break;
630         }
631
632         if (tvb_memeql(tvb, offset, JXTA_UDP_SIG, sizeof(JXTA_UDP_SIG)) != 0) {
633             /* not ours */
634             return 0;
635         }
636
637         offset += sizeof(JXTA_UDP_SIG);
638
639         jxta_message_framing_tvb = tvb_new_subset(tvb, offset, -1, -1);
640         processed = dissect_jxta_message_framing(jxta_message_framing_tvb, pinfo, NULL, &content_length, &content_type);
641
642         if ((0 == processed) || (NULL == content_type) || (content_length <= 0) || (content_length > UINT_MAX)) {
643             /** Buffer did not begin with valid framing headers */
644             return 0;
645         }
646
647         if (processed < 0) {
648             needed = -processed;
649             break;
650         }
651
652         /* Redo header processing, this time populating the tree. */
653         processed = dissect_jxta_message_framing(jxta_message_framing_tvb, pinfo, tree, &content_length, &content_type);
654
655
656         offset += processed;
657
658         available = tvb_reported_length_remaining(tvb, offset);
659         if (available < content_length) {
660             needed = (gint) (content_length - available);
661             break;
662         }
663
664         offset += (guint) content_length;
665
666         break;
667     }
668
669     if ((needed > 0) && gDESEGMENT && pinfo->can_desegment) {
670         pinfo->desegment_offset = 0;
671         pinfo->desegment_len = needed;
672         return -needed;
673     }
674
675     if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
676         col_set_str(pinfo->cinfo, COL_PROTOCOL, "JXTA");
677     }
678
679     if (tree) {
680         guint tree_offset = 0;
681         proto_item *jxta_tree_item =
682             proto_tree_add_protocol_format(tree, proto_jxta, tvb, offset, -1, "JXTA" );
683         proto_tree *jxta_tree = proto_item_add_subtree(jxta_tree_item, ett_jxta);
684         proto_item *jxta_udp_tree_item =
685             proto_tree_add_none_format(jxta_tree, hf_jxta_udp, tvb, tree_offset, -1, "JXTA UDP Message");
686         proto_tree *jxta_udp_tree = proto_item_add_subtree(jxta_udp_tree_item, ett_jxta_udp);
687         tvbuff_t *jxta_message_framing_tvb;
688         guint64 content_length = -1;
689         gchar *content_type = NULL;
690         tvbuff_t *jxta_message_tvb;
691         gboolean dissected = FALSE;
692         gint processed = 0;
693
694         proto_tree_add_item(jxta_udp_tree, hf_jxta_udpsig, tvb, tree_offset, sizeof(JXTA_UDP_SIG), FALSE);
695         tree_offset += sizeof(JXTA_UDP_SIG);
696
697         jxta_message_framing_tvb = tvb_new_subset(tvb, tree_offset, -1, -1);
698         processed = dissect_jxta_message_framing(jxta_message_framing_tvb, pinfo, NULL, &content_length, &content_type);
699
700         if ((0 == processed) || (NULL == content_type) || (content_length <= 0) || (content_length > UINT_MAX)) {
701             /** Buffer did not begin with valid framing headers */
702             return 0;
703         }
704
705         processed = dissect_jxta_message_framing(jxta_message_framing_tvb, pinfo, tree, &content_length, &content_type);
706
707         tree_offset += processed;
708
709         jxta_message_tvb = tvb_new_subset(tvb, tree_offset, (gint) content_length, (gint) content_length);
710
711         dissected = dissector_try_string(media_type_dissector_table, content_type, jxta_message_tvb, pinfo, tree);
712
713         if (!dissected) {
714             call_dissector(data_handle, jxta_message_tvb, pinfo, tree);
715         }
716
717         tree_offset += (guint) content_length;
718
719         proto_item_set_end(jxta_udp_tree_item, tvb, tree_offset);
720
721         DISSECTOR_ASSERT(offset == tree_offset);
722     }
723
724     return offset;
725 }
726
727 /**
728 *   Dissect a tvbuff containing JXTA stream PDUs. This commonly includes
729 *   connections over TCP sockets.
730 *
731 *   <p/>The stream (in both directions) will consist of a JXTA Welcome Message
732 *   followed by an indeterminate number of JXTA Message Framing Headers and
733 *   JXTA Messages.
734 *
735 *   @param  tvb The buffer to dissect.
736 *   @param  pinfo Packet Info.
737 *   @param  tree The protocol tree.
738 *   @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
739 *           the packet was not recognized as a JXTA packet and negative if the
740 *           dissector needs more bytes in order to process a PDU.
741 **/
742 static int dissect_jxta_stream(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
743 {
744     guint offset = 0;
745     guint available = tvb_reported_length_remaining(tvb, offset);
746     gint processed;
747     gint needed = 0;
748     conversation_t *tpt_conversation = NULL;
749     jxta_stream_conversation_data *tpt_conv_data = NULL;
750     proto_item *jxta_tree_item = NULL;
751     proto_tree *jxta_tree = NULL;
752
753     /*g_message("Dissecting %s : %d", (NULL != tree) ? "for display" : "", pinfo->fd->num );*/
754
755     if (available < sizeof(JXTA_WELCOME_MSG_SIG)) {
756         needed = (gint) (sizeof(JXTA_WELCOME_MSG_SIG) - available);
757         goto Common_Exit;
758     }
759
760     if (0 == tvb_memeql(tvb, 0, JXTA_WELCOME_MSG_SIG, sizeof(JXTA_WELCOME_MSG_SIG))) {
761         /* The beginning of a JXTA stream connection */
762         address *welcome_addr;
763         gboolean initiator = FALSE;
764
765         tpt_conversation = get_tpt_conversation(pinfo, TRUE);
766         tpt_conv_data = (jxta_stream_conversation_data *) conversation_get_proto_data(tpt_conversation, proto_jxta);
767
768         if (0 == tpt_conv_data->initiator_welcome_frame) {
769             /* The initiator welcome frame */
770             tpt_conv_data->tpt_ptype = pinfo->ptype;
771             tpt_conv_data->initiator_welcome_frame = pinfo->fd->num;
772             SE_COPY_ADDRESS(&tpt_conv_data->initiator_tpt_address, &pinfo->src);
773             tpt_conv_data->initiator_tpt_port = pinfo->srcport;
774
775             welcome_addr = &tpt_conv_data->initiator_address;
776             initiator = TRUE;
777         } else {
778             if (tpt_conv_data->initiator_welcome_frame >= pinfo->fd->num) {
779                 /* what we saw previously was the receiver welcome message */
780                 tpt_conv_data->receiver_welcome_frame = tpt_conv_data->initiator_welcome_frame;
781                 tpt_conv_data->receiver_tpt_address = tpt_conv_data->initiator_tpt_address;
782                 tpt_conv_data->receiver_tpt_port = tpt_conv_data->initiator_tpt_port;
783                 tpt_conv_data->receiver_address = tpt_conv_data->initiator_address;
784                 tpt_conv_data->initiator_welcome_frame = pinfo->fd->num;
785                 SE_COPY_ADDRESS(&tpt_conv_data->initiator_tpt_address, &pinfo->src);
786                 tpt_conv_data->initiator_tpt_port = pinfo->srcport;
787
788                 welcome_addr = &tpt_conv_data->initiator_address;
789                 initiator = TRUE;
790             } else {
791                 /* The receiver welcome frame */
792                 tpt_conv_data->tpt_ptype = pinfo->ptype;
793                 tpt_conv_data->receiver_welcome_frame = pinfo->fd->num;
794                 SE_COPY_ADDRESS(&tpt_conv_data->receiver_tpt_address, &pinfo->src);
795                 tpt_conv_data->receiver_tpt_port = pinfo->srcport;
796
797                 welcome_addr = &tpt_conv_data->receiver_address;
798                 initiator = FALSE;
799             }
800         }
801
802         processed = dissect_jxta_welcome(tvb, pinfo, NULL, welcome_addr, initiator);
803
804         if( processed < 0 ) {
805             needed = -processed;
806             goto Common_Exit;
807         }
808
809         /* redo, this time creating the display tree. */
810         jxta_tree_item =
811             proto_tree_add_protocol_format(tree, proto_jxta, tvb, offset, -1, "JXTA" );
812         jxta_tree = proto_item_add_subtree(jxta_tree_item, ett_jxta);
813
814         processed = dissect_jxta_welcome(tvb, pinfo, jxta_tree, welcome_addr, initiator);
815     } else {
816         /* Somewhere in the middle of a JXTA stream connection */
817         guint64 content_length = -1;
818         gchar *content_type = NULL;
819         gint headers_len = dissect_jxta_message_framing(tvb, pinfo, NULL, &content_length, &content_type);
820
821         /*g_message("%d Tpt %s:%d -> %s:%d tvb len=%d\n\t%s %u", pinfo->fd->num,
822                               address_to_str(&pinfo->src), pinfo->srcport,
823                               address_to_str(&pinfo->dst), pinfo->destport,
824                               tvb_reported_length_remaining(tvb, 0),
825                               (content_type) ? content_type : "[unknown content type]", (guint) content_length);*/
826
827         if ((0 == headers_len) || (NULL == content_type) || (content_length <= 0) || (content_length > UINT_MAX)) {
828             /** Buffer did not begin with valid framing headers */
829             return 0;
830         }
831
832         if (headers_len < 0) {
833             /* negative headers_len means we need more bytes */
834             needed = -headers_len;
835             goto Common_Exit;
836         }
837
838         available = tvb_reported_length_remaining(tvb, offset + headers_len);
839         if (available >= content_length) {
840             tvbuff_t *jxta_message_tvb = tvb_new_subset(tvb, offset + headers_len, (gint) content_length, (gint) content_length);
841             conversation_t *peer_conversation = NULL;
842             address saved_src_addr;
843             guint32 saved_src_port = 0;
844             address saved_dst_addr;
845             guint32 saved_dst_port = 0;
846             port_type saved_port_type = PT_NONE;
847             gboolean dissected;
848
849             jxta_tree_item =
850                 proto_tree_add_protocol_format(tree, proto_jxta, tvb, offset, -1, "JXTA" );
851             jxta_tree = proto_item_add_subtree(jxta_tree_item, ett_jxta);
852
853             /* Redo header processing, this time populating the tree. */
854             headers_len = dissect_jxta_message_framing(tvb, pinfo, jxta_tree, &content_length, &content_type);
855
856             tpt_conversation = get_tpt_conversation(pinfo, TRUE);
857
858             if (NULL != tpt_conversation) {
859                 tpt_conv_data = (jxta_stream_conversation_data *) conversation_get_proto_data(tpt_conversation, proto_jxta);
860
861                 if ((AT_NONE != tpt_conv_data->initiator_address.type) && (AT_NONE != tpt_conv_data->receiver_address.type)) {
862                     peer_conversation =
863                         find_conversation(pinfo->fd->num, &tpt_conv_data->initiator_address, &tpt_conv_data->receiver_address,
864                                           PT_NONE, 0, 0, NO_PORT_B);
865
866                     if (NULL == peer_conversation) {
867                         peer_conversation =
868                             conversation_new(pinfo->fd->num, &tpt_conv_data->initiator_address,
869                                              &tpt_conv_data->receiver_address, PT_NONE, 0, 0, NO_PORT_B);
870                         conversation_set_dissector(peer_conversation, stream_jxta_handle);
871                     }
872
873                 } else {
874                     g_warning("Uninitialized peer conversation");
875                 }
876             }
877
878             /* Use our source and destination addresses if we have them */
879             if (NULL != peer_conversation) {
880                 saved_src_addr = pinfo->src;
881                 saved_src_port = pinfo->srcport;
882                 saved_dst_addr = pinfo->dst;
883                 saved_dst_port = pinfo->destport;
884                 saved_port_type = pinfo->ptype;
885                 /*g_message("%d Tpt %s:%d -> %s:%d", pinfo->fd->num, ip_to_str(tpt_conv_data->initiator_tpt_address.data),
886                           tpt_conv_data->initiator_tpt_port, ip_to_str(tpt_conv_data->receiver_tpt_address.data),
887                           tpt_conv_data->receiver_tpt_port);*/
888                 if (ADDRESSES_EQUAL(&pinfo->src, &tpt_conv_data->initiator_tpt_address)
889                     && tpt_conv_data->initiator_tpt_port == pinfo->srcport) {
890                     /*g_message("%d From initiator : %s -> %s ", pinfo->fd->num, tpt_conv_data->initiator_address.data,
891                               tpt_conv_data->receiver_address.data);*/
892                     pinfo->src = tpt_conv_data->initiator_address;
893                     pinfo->dst = tpt_conv_data->receiver_address;
894                 } else if (ADDRESSES_EQUAL(&pinfo->src, &tpt_conv_data->receiver_tpt_address) &&
895                            tpt_conv_data->receiver_tpt_port == pinfo->srcport) {
896                     /*g_message("%d From receiver : %s -> %s ", pinfo->fd->num, tpt_conv_data->receiver_address.data,
897                               tpt_conv_data->initiator_address.data);*/
898                     pinfo->src = tpt_conv_data->receiver_address;
899                     pinfo->dst = tpt_conv_data->initiator_address;
900                 } else {
901                     /*g_message("%d Nothing matches %s:%d -> %s:%d", pinfo->fd->num, ip_to_str(pinfo->src.data), pinfo->srcport,
902                               ip_to_str(pinfo->dst.data), pinfo->destport);*/
903                 }
904                 /* JXTA doesn't use ports */
905                 pinfo->ptype = PT_NONE;
906                 pinfo->srcport = 0;
907                 pinfo->destport = 0;
908             } else {
909                 /*  Just to avoid compilers from thinking (falsely) that these
910                  *  could be unitialized
911                  */
912                 memset(&saved_src_addr, 0, sizeof(saved_src_addr));
913                 memset(&saved_dst_addr, 0, sizeof(saved_dst_addr));
914             }
915
916
917             dissected =
918                 dissector_try_string(media_type_dissector_table, content_type, jxta_message_tvb, pinfo, tree);
919
920             if (!dissected) {
921                 call_dissector(data_handle, jxta_message_tvb, pinfo, jxta_tree);
922             }
923
924             /* Restore the saved src and dst addresses */
925             if (NULL != peer_conversation) {
926                 pinfo->src = saved_src_addr;
927                 pinfo->srcport = saved_src_port;
928                 pinfo->dst = saved_dst_addr;
929                 pinfo->destport = saved_dst_port;
930                 pinfo->ptype = saved_port_type;
931             }
932
933             processed = (guint) content_length + headers_len;
934         } else {
935             /* we need more bytes before we can process message body. */
936             needed = (gint) ((guint) content_length - available);
937             goto Common_Exit;
938         }
939     }
940
941     offset += processed;
942
943 Common_Exit:
944     if ((needed > 0) && gDESEGMENT && pinfo->can_desegment) {
945         /*g_message( "Requesting %d more bytes", needed );*/
946         pinfo->desegment_offset = offset;
947         pinfo->desegment_len = needed;
948         return -needed;
949     }
950
951     return offset;
952 }
953
954 /**
955 *   Find or possibly create a transport conversation object for the connection
956 *   which is associated with the packet info.
957 *
958 *   @param pinfo  The packet info from the underlying transport.
959 *   @param create If TRUE then create a new conversation object if necessary.
960 **/
961 static conversation_t *get_tpt_conversation(packet_info * pinfo, gboolean create)
962 {
963     conversation_t *tpt_conversation =
964         find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
965     jxta_stream_conversation_data *tpt_conv_data;
966
967     if (tpt_conversation == NULL) {
968         if (!create) {
969             return NULL;
970         }
971
972         /*
973          * No conversation exists yet - create one.
974          */
975         tpt_conversation =
976             conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
977     }
978
979     conversation_set_dissector(tpt_conversation, stream_jxta_handle);
980
981     tpt_conv_data = (jxta_stream_conversation_data *) conversation_get_proto_data(tpt_conversation, proto_jxta);
982
983     if (NULL == tpt_conv_data) {
984         tpt_conv_data = se_alloc(sizeof(jxta_stream_conversation_data));
985         tpt_conv_data->tpt_ptype = pinfo->ptype;
986
987         SE_COPY_ADDRESS(&tpt_conv_data->initiator_tpt_address, &pinfo->src);
988         tpt_conv_data->initiator_tpt_port = pinfo->srcport;
989         tpt_conv_data->initiator_welcome_frame = 0;
990         /* XXX bondolo This is not quite correct as it should include port until a peerid can be associated. */
991         SE_COPY_ADDRESS(&tpt_conv_data->initiator_address, &pinfo->src);
992
993         SE_COPY_ADDRESS(&tpt_conv_data->receiver_tpt_address, &pinfo->dst);
994         tpt_conv_data->receiver_tpt_port = pinfo->destport;
995         tpt_conv_data->receiver_welcome_frame = 0;
996         /* XXX bondolo This is not quite correct as it should include port until a peerid can be associated. */
997         SE_COPY_ADDRESS(&tpt_conv_data->receiver_address, &pinfo->dst);
998
999         conversation_add_proto_data(tpt_conversation, proto_jxta, tpt_conv_data);
1000     }
1001
1002     return tpt_conversation;
1003 }
1004
1005 /**
1006 *   Dissect a tvbuff containing a JXTA Welcome Message
1007 *
1008 *   @param  tvb The buffer to dissect.
1009 *   @param  pinfo Packet Info.
1010 *   @param  tree The protocol tree.
1011 *   @param  found_addr The address found in the welcome message.
1012 *   @param  initiator If TRUE then we believe this welcome message to be the initiator's.
1013 *   @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
1014 *           the packet was not recognized as a JXTA packet and negative if the
1015 *           dissector needs more bytes in order to process a PDU.
1016 **/
1017 static int dissect_jxta_welcome(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, address * found_addr, gboolean initiator)
1018 {
1019     guint offset = 0;
1020     gint afterwelcome;
1021     gint first_linelen;
1022     guint available = tvb_reported_length_remaining(tvb, offset);
1023     gchar **tokens = NULL;
1024
1025     if (available < sizeof(JXTA_WELCOME_MSG_SIG)) {
1026         return (gint) (available - sizeof(JXTA_WELCOME_MSG_SIG));
1027     }
1028
1029     if (0 != tvb_memeql(tvb, 0, JXTA_WELCOME_MSG_SIG, sizeof(JXTA_WELCOME_MSG_SIG))) {
1030         /* not ours! */
1031         return 0;
1032     }
1033
1034     first_linelen = tvb_find_line_end(tvb, offset, -1, &afterwelcome, gDESEGMENT && pinfo->can_desegment);
1035
1036     if (-1 == first_linelen) {
1037         if (available > 4096) {
1038             /* it's too far too be reasonable */
1039             return 0;
1040         } else {
1041             /* ask for more bytes */
1042             return -1;
1043         }
1044     }
1045
1046     /* Dissect the Welcome Message */
1047
1048     if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
1049         col_set_str(pinfo->cinfo, COL_PROTOCOL, "JXTA");
1050     }
1051
1052     if (check_col(pinfo->cinfo, COL_INFO)) {
1053         col_add_str(pinfo->cinfo, COL_INFO, "Welcome");
1054     }
1055
1056     {
1057         gchar *welcomeline = tvb_get_ephemeral_string(tvb, offset, first_linelen);
1058         gchar **current_token;
1059         guint token_offset = offset;
1060         proto_item *jxta_welcome_tree_item = NULL;
1061         proto_tree *jxta_welcome_tree = NULL;
1062
1063         tokens = g_strsplit(welcomeline, " ", 255);
1064         current_token = tokens;
1065
1066         if (tree) {
1067             jxta_welcome_tree_item =
1068                 proto_tree_add_none_format(tree, hf_jxta_welcome, tvb, offset, afterwelcome,
1069                                            "JXTA Connection Welcome Message, %s", welcomeline);
1070             jxta_welcome_tree = proto_item_add_subtree(jxta_welcome_tree_item, ett_jxta_welcome);
1071         }
1072
1073         if (jxta_welcome_tree) {
1074             proto_item *jxta_welcome_initiator_item =
1075                 proto_tree_add_boolean(jxta_welcome_tree, hf_jxta_welcome_initiator, tvb, 0, 0, initiator);
1076             PROTO_ITEM_SET_GENERATED(jxta_welcome_initiator_item);
1077         }
1078
1079         if (NULL != *current_token) {
1080             if (jxta_welcome_tree) {
1081                 proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_sig, tvb, token_offset, strlen(*current_token), FALSE);
1082             }
1083
1084             token_offset += strlen(*current_token) + 1;
1085             current_token++;
1086         } else {
1087             /* invalid welcome message */
1088             afterwelcome = 0;
1089             goto Common_Exit;
1090         }
1091
1092         if (NULL != *current_token) {
1093             if (jxta_welcome_tree) {
1094                 proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_destAddr, tvb, token_offset, strlen(*current_token),
1095                                     FALSE);
1096             }
1097
1098             token_offset += strlen(*current_token) + 1;
1099             current_token++;
1100         } else {
1101             /* invalid welcome message */
1102             afterwelcome = 0;
1103             goto Common_Exit;
1104         }
1105
1106         if (NULL != *current_token) {
1107             if (jxta_welcome_tree) {
1108                 proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_pubAddr, tvb, token_offset, strlen(*current_token), FALSE);
1109             }
1110
1111             token_offset += strlen(*current_token) + 1;
1112             current_token++;
1113         } else {
1114             /* invalid welcome message */
1115             afterwelcome = 0;
1116             goto Common_Exit;
1117         }
1118
1119         if (NULL != *current_token) {
1120             if (jxta_welcome_tree) {
1121                 proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_peerid, tvb, token_offset, strlen(*current_token), FALSE);
1122             }
1123
1124             if (check_col(pinfo->cinfo, COL_INFO)) {
1125                 col_append_str(pinfo->cinfo, COL_INFO, (initiator ? " -> " : " <- ") );
1126                 col_append_str(pinfo->cinfo, COL_INFO, *current_token);
1127             }
1128
1129             if (NULL != found_addr) {
1130                 found_addr->type = AT_URI;
1131                 found_addr->len = strlen(*current_token);
1132                 /* FIXME 20050605 bondolo THIS ALLOCATION IS A MEMORY LEAK! */
1133                 found_addr->data = g_strdup(*current_token);
1134             }
1135
1136             token_offset += strlen(*current_token) + 1;
1137             current_token++;
1138         } else {
1139             /* invalid welcome message */
1140             afterwelcome = 0;
1141             goto Common_Exit;
1142         }
1143
1144         if (NULL != *current_token) {
1145             int variable_tokens = 0;
1146             gchar **variable_token = current_token;
1147
1148             while(NULL != *variable_token) {
1149                 variable_tokens++;
1150                 variable_token++;
1151             }
1152
1153             if( variable_tokens < 1 ) {
1154               /* invalid welcome message */
1155               afterwelcome = 0;
1156               goto Common_Exit;
1157             }
1158
1159             if( (2 == variable_tokens) && (0 == strcmp(JXTA_WELCOME_MSG_VERSION_1_1, current_token[variable_tokens -1])) ) {
1160                   if (jxta_welcome_tree) {
1161                       proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_noProp, tvb, token_offset, strlen(*current_token), FALSE);
1162                   }
1163
1164                   token_offset += strlen(*current_token) + 1;
1165                   current_token++;
1166
1167                   if (jxta_welcome_tree) {
1168                       proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_version, tvb, token_offset, strlen(*current_token), FALSE);
1169                   }
1170             } else if( (3 == variable_tokens) && (0 == strcmp(JXTA_WELCOME_MSG_VERSION_3_0, current_token[variable_tokens -1])) ) {
1171                   if (jxta_welcome_tree) {
1172                       proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_noProp, tvb, token_offset, strlen(*current_token), FALSE);
1173                   }
1174
1175                   token_offset += strlen(*current_token) + 1;
1176                   current_token++;
1177
1178                   if (jxta_welcome_tree) {
1179                       proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_msgVers, tvb, token_offset, strlen(*current_token), FALSE);
1180                   }
1181
1182                   token_offset += strlen(*current_token) + 1;
1183                   current_token++;
1184
1185                   if (jxta_welcome_tree) {
1186                       proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_version, tvb, token_offset, strlen(*current_token), FALSE);
1187                   }
1188             } else {
1189                 /* Unrecognized Welcome Version */
1190                 int each_variable_token;
1191
1192                 for( each_variable_token = 0; each_variable_token < variable_tokens; each_variable_token++ ) {
1193                   if (jxta_welcome_tree) {
1194                       jxta_welcome_tree_item = proto_tree_add_item(jxta_welcome_tree,
1195                         (each_variable_token < (variable_tokens -1) ? hf_jxta_welcome_variable : hf_jxta_welcome_version),
1196                         tvb, token_offset, strlen(*current_token), FALSE);
1197
1198                         proto_item_append_text(jxta_welcome_tree_item, " (UNRECOGNIZED)");
1199                   }
1200
1201                   token_offset += strlen(*current_token) + 1;
1202                   current_token++;
1203                 }
1204             }
1205         } else {
1206             /* invalid welcome message */
1207             afterwelcome = 0;
1208             goto Common_Exit;
1209         }
1210     }
1211
1212 Common_Exit:
1213     g_strfreev(tokens);
1214
1215     col_set_writable(pinfo->cinfo, FALSE);
1216
1217     return afterwelcome;
1218 }
1219
1220 /**
1221 *   Dissect a tvbuff containing JXTA Message framing.
1222 *
1223 *   @param  tvb The buffer to dissect.
1224 *   @param  pinfo Packet Info.
1225 *   @param  tree The protocol tree.
1226 *   @param  content_length Pointer to a buffer for storing the value of the
1227 *           "content-length" header or NULL.
1228 *   @param  content_type Pointer-to-a-pointer for a new buffer for storing the
1229 *           value of the "content_type-length" header or NULL.
1230 *   @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
1231 *           the packet was not recognized as a JXTA packet and negative if the
1232 *           dissector needs more bytes in order to process a PDU.
1233 **/
1234 static int dissect_jxta_message_framing(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, guint64 * content_length,
1235                                         gchar ** content_type)
1236 {
1237     guint offset = 0;
1238     guint available;
1239     gint needed = 0;
1240
1241     /*
1242      *   First go around. Make sure all of the bytes are there.
1243      */
1244     do {
1245         guint8 headername_len;
1246         guint8 headername_offset;
1247         guint16 headervalue_len;
1248         guint16 headervalue_offset;
1249
1250         available = tvb_reported_length_remaining(tvb, offset);
1251         if (available < sizeof(guint8)) {
1252             needed = (gint) (sizeof(guint8) - available);
1253             break;
1254         } else {
1255             headername_len = tvb_get_guint8(tvb, offset);
1256             offset += sizeof(guint8);
1257             headername_offset = offset;
1258
1259             available = tvb_reported_length_remaining(tvb, offset);
1260             if (available < headername_len) {
1261                 needed = (gint) (headername_len - available);
1262                 break;
1263             }
1264
1265             if (0 == headername_len) {
1266                 break;
1267             }
1268             offset += headername_len;
1269         }
1270
1271         available = tvb_reported_length_remaining(tvb, offset);
1272         if (available < sizeof(guint16)) {
1273             needed = (gint) (sizeof(guint16) - available);
1274             break;
1275         } else {
1276             headervalue_len = tvb_get_ntohs(tvb, offset);
1277             offset += sizeof(guint16);
1278             headervalue_offset = offset;
1279
1280             available = tvb_reported_length_remaining(tvb, offset);
1281             if (available < headervalue_len) {
1282                 needed = (gint) (headervalue_len - available);
1283                 break;
1284             }
1285
1286             offset += headervalue_len;
1287         }
1288
1289         if (content_type && (sizeof("content-type") - 1) == headername_len) {
1290             if (0 == tvb_strncaseeql(tvb, headername_offset, "content-type", sizeof("content-type") - 1)) {
1291                 *content_type = tvb_get_ephemeral_string(tvb, headervalue_offset, headervalue_len);
1292             }
1293         }
1294
1295
1296         if (content_length && (sizeof(guint64) == headervalue_len) && ((sizeof("content-length") - 1) == headername_len)) {
1297             if (0 == tvb_strncaseeql(tvb, headername_offset, "content-length", sizeof("content-length") - 1)) {
1298                 *content_length = tvb_get_ntoh64(tvb, headervalue_offset);
1299             }
1300         }
1301     } while (TRUE);
1302
1303     if ((needed > 0) && gDESEGMENT && pinfo->can_desegment) {
1304         pinfo->desegment_offset = 0;
1305         pinfo->desegment_len = needed;
1306         return -needed;
1307     }
1308
1309     /*
1310      *   Second (optional pass) Now that we are sure that all the bytes are there we update the protocol tree.
1311      */
1312     if (tree) {
1313         guint tree_offset = 0;
1314         proto_item *framing_tree_item =
1315             proto_tree_add_none_format(tree, hf_jxta_framing, tvb, tree_offset, -1, "JXTA Message Framing Headers");
1316         proto_tree *framing_tree = proto_item_add_subtree(framing_tree_item, ett_jxta_framing);
1317
1318         /* parse framing headers */
1319         do {
1320             guint8 headernamelen = tvb_get_guint8(tvb, tree_offset);
1321             proto_item *framing_header_tree_item =
1322                 proto_tree_add_item(framing_tree, hf_jxta_framing_header, tvb, tree_offset, -1, FALSE);
1323             proto_tree *framing_header_tree = proto_item_add_subtree(framing_header_tree_item, ett_jxta_framing_header);
1324
1325             /*
1326              *   Put header name into the protocol tree
1327              */
1328             proto_tree_add_item(framing_header_tree, hf_jxta_framing_header_name, tvb, tree_offset, 1, headernamelen);
1329
1330             /*
1331              *   Append header name into the header protocol item. It's a nice hint so you don't have to reveal all headers.
1332              */
1333             if (headernamelen > 0) {
1334                 proto_item_append_text(framing_header_tree_item, " \"%s\"",
1335                                        tvb_format_text(tvb, tree_offset + sizeof(guint8), headernamelen));
1336             }
1337
1338             tree_offset += sizeof(guint8) + headernamelen;
1339
1340             if (headernamelen > 0) {
1341                 guint16 headervaluelen = tvb_get_ntohs(tvb, tree_offset);
1342
1343                 if (tree) {
1344                     proto_tree_add_uint(framing_header_tree, hf_jxta_framing_header_value_length, tvb, tree_offset,
1345                                         sizeof(guint16), headervaluelen);
1346
1347                     /** TODO bondolo Add specific handling for known header types */
1348
1349                     /*
1350                      * Put header value into protocol tree.
1351                      */
1352                     proto_tree_add_item(framing_header_tree, hf_jxta_framing_header_value, tvb, tree_offset + sizeof(guint16),
1353                                         headervaluelen, FALSE);
1354                 }
1355
1356                 tree_offset += sizeof(guint16) + headervaluelen;
1357             }
1358
1359             proto_item_set_end(framing_header_tree_item, tvb, tree_offset);
1360
1361             if (0 == headernamelen) {
1362                 break;
1363             }
1364         } while (TRUE);
1365
1366         proto_item_set_end(framing_tree_item, tvb, tree_offset);
1367
1368         DISSECTOR_ASSERT(offset == tree_offset);
1369     }
1370
1371     /* return how many bytes we used up. */
1372     return offset;
1373 }
1374
1375 /**
1376 *   Dissect a tvbuff containing a JXTA Message.
1377 *
1378 *   @param  tvb The buffer to dissect.
1379 *   @param  pinfo Packet Info.
1380 *   @param  tree The protocol tree.
1381 *   @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
1382 *           the packet was not recognized as a JXTA packet and negative if the
1383 *           dissector needs more bytes in order to process a PDU.
1384 **/
1385 static int dissect_jxta_message(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
1386 {
1387     guint offset = 0;
1388     guint available;
1389     gint needed = 0;
1390
1391     while (TRUE) {
1392         guint8 message_version;
1393
1394         /* First pass. Make sure all of the bytes we need are available */
1395         available = tvb_reported_length_remaining(tvb, offset);
1396         if (available < sizeof(JXTA_MSG_SIG)) {
1397             needed = (gint) (sizeof(JXTA_MSG_SIG) - available);
1398             break;
1399         }
1400
1401         if (tvb_memeql(tvb, offset, JXTA_MSG_SIG, sizeof(JXTA_MSG_SIG)) != 0) {
1402             /* It is not one of ours */
1403             return 0;
1404         }
1405
1406         offset += sizeof(JXTA_MSG_SIG);
1407
1408         available = tvb_reported_length_remaining(tvb, offset);
1409         if (available < sizeof(guint8)) {
1410             needed = (gint) (sizeof(guint8) - available);
1411             break;
1412         } else {
1413             message_version = tvb_get_guint8(tvb, offset);
1414
1415             offset += sizeof(guint8);
1416
1417             if ((JXTA_MSG_VERSION_1 != message_version) && (JXTA_MSG_VERSION_2 != message_version)) {
1418                 /* Sort of a lie, we say that we don't recognize it at all. */
1419                 return 0;
1420             }
1421         }
1422
1423         /* Read the flags (Version 2 and later) */
1424         if(message_version > 0) {
1425             available = tvb_reported_length_remaining(tvb, offset);
1426             if (available < sizeof(guint8)) {
1427                 needed = (gint) (sizeof(guint8) - available);
1428                 break;
1429             } else {
1430                 offset += sizeof(guint8);
1431             }
1432         }
1433
1434         /* Read names table */
1435         available = tvb_reported_length_remaining(tvb, offset);
1436         if (available < sizeof(guint16)) {
1437             needed = (gint) (sizeof(guint16) - available);
1438             break;
1439         } else {
1440             guint16 msg_names_count = tvb_get_ntohs(tvb, offset);
1441             guint each_name;
1442
1443             offset += sizeof(guint16);
1444
1445             for (each_name = 0; each_name < msg_names_count; each_name++) {
1446                 guint16 name_len;
1447
1448                 available = tvb_reported_length_remaining(tvb, offset);
1449                 if (available < sizeof(name_len)) {
1450                     needed = (gint) (sizeof(name_len) - available);
1451                     break;
1452                 }
1453
1454                 name_len = tvb_get_ntohs(tvb, offset);
1455
1456                 available = tvb_reported_length_remaining(tvb, offset + sizeof(name_len));
1457                 if (available < name_len) {
1458                     needed = (gint) (name_len - available);
1459                     break;
1460                 }
1461
1462                 offset += sizeof(name_len) + name_len;
1463             }
1464         }
1465
1466         /* parse element count */
1467         available = tvb_reported_length_remaining(tvb, offset);
1468         if (available < sizeof(guint16)) {
1469             needed = (gint) (sizeof(guint16) - available);
1470             break;
1471         } else {
1472             guint16 elem_count = tvb_get_ntohs(tvb, offset);
1473             guint each_elem;
1474
1475             offset += sizeof(guint16);
1476
1477             /* parse elements */
1478
1479             for (each_elem = 0; each_elem < elem_count; each_elem++) {
1480                 tvbuff_t *jxta_message_element_tvb = tvb_new_subset(tvb, offset, -1, -1);
1481                 int processed;
1482
1483                 if(JXTA_MSG_VERSION_1 == message_version) {
1484                     processed = dissect_jxta_message_element_1(jxta_message_element_tvb, pinfo, NULL, 0, NULL);
1485                 } else if(JXTA_MSG_VERSION_2 == message_version) {
1486                     processed = dissect_jxta_message_element_2(jxta_message_element_tvb, pinfo, NULL, 0, NULL);
1487                 } else {
1488                     /* Sort of a lie, we say that we don't recognize it at all. */
1489                     return 0;
1490                 }
1491
1492                 if (processed < 0) {
1493                     needed = -processed;
1494                     break;
1495                 }
1496
1497                 if (0 == processed) {
1498                     /* XXX bondolo Not really clear what we should do! */
1499                     g_warning( "Failure processing message element #%d of %d of frame %d", each_elem, elem_count, pinfo->fd->num );
1500                     return 0;
1501                 }
1502
1503                 offset += processed;
1504             }
1505         }
1506
1507         break;
1508     }
1509
1510     if ((needed > 0) && gDESEGMENT && pinfo->can_desegment) {
1511         pinfo->desegment_offset = 0;
1512         pinfo->desegment_len = needed;
1513         return -needed;
1514     }
1515
1516     if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
1517         col_set_str(pinfo->cinfo, COL_PROTOCOL, "JXTA");
1518     }
1519
1520     if (check_col(pinfo->cinfo, COL_INFO)) {
1521         gchar src_addr[MAX_ADDR_STR_LEN];
1522         gchar dst_addr[MAX_ADDR_STR_LEN];
1523
1524         address_to_str_buf(&pinfo->src, src_addr, sizeof src_addr);
1525         address_to_str_buf(&pinfo->dst, dst_addr, sizeof dst_addr);
1526
1527         /* append the port if appropriate */
1528         if (PT_NONE != pinfo->ptype) {
1529             size_t len = strlen(src_addr);
1530             src_addr[len] = ':';
1531             g_snprintf(&src_addr[len + 1], 256 - len - 1, "%d", pinfo->srcport);
1532
1533             len = strlen(dst_addr);
1534             dst_addr[len] = ':';
1535             g_snprintf(&dst_addr[len + 1], 256 - len - 1, "%d", pinfo->destport);
1536         }
1537
1538         col_add_fstr(pinfo->cinfo, COL_INFO, "Message, %s -> %s", src_addr, dst_addr);
1539
1540         col_set_writable(pinfo->cinfo, FALSE);
1541     }
1542
1543     if (tree) {
1544         guint tree_offset = 0;
1545         proto_item *jxta_msg_tree_item = NULL;
1546         proto_tree *jxta_msg_tree = NULL;
1547         guint8 message_version;
1548         const gchar **names_table = NULL;
1549         guint16 msg_names_count;
1550         guint each_name;
1551         guint16 elem_count;
1552         guint each_elem;
1553         gchar src_addr[256];
1554         gchar dst_addr[256];
1555         proto_item *tree_item;
1556
1557         address_to_str_buf(&pinfo->src, src_addr, sizeof src_addr);
1558         address_to_str_buf(&pinfo->dst, dst_addr, sizeof dst_addr);
1559
1560         if (PT_NONE != pinfo->ptype) {
1561             size_t len = strlen(src_addr);
1562             src_addr[len] = ':';
1563             g_snprintf(&src_addr[len + 1], 256 - len - 1, "%d", pinfo->srcport);
1564
1565             len = strlen(dst_addr);
1566             dst_addr[len] = ':';
1567             g_snprintf(&dst_addr[len + 1], 256 - len - 1, "%d", pinfo->destport);
1568         }
1569
1570         jxta_msg_tree_item = proto_tree_add_protocol_format(tree, proto_message_jxta, tvb, tree_offset, -1,
1571                                                             "JXTA Message, %s -> %s", src_addr, dst_addr);
1572
1573         jxta_msg_tree = proto_item_add_subtree(jxta_msg_tree_item, ett_jxta_msg);
1574
1575         proto_tree_add_item(jxta_msg_tree, hf_jxta_message_sig, tvb, tree_offset, sizeof(JXTA_MSG_SIG), FALSE);
1576         tree_offset += sizeof(JXTA_MSG_SIG);
1577
1578         tree_item = proto_tree_add_string(jxta_msg_tree, hf_jxta_message_src, tvb, 0, 0, src_addr);
1579         PROTO_ITEM_SET_GENERATED(tree_item);
1580
1581         tree_item = proto_tree_add_string(jxta_msg_tree, hf_jxta_message_address, tvb, 0, 0, src_addr);
1582         PROTO_ITEM_SET_HIDDEN(tree_item);
1583         PROTO_ITEM_SET_GENERATED(tree_item);
1584
1585         tree_item = proto_tree_add_string(jxta_msg_tree, hf_jxta_message_dst, tvb, 0, 0, dst_addr);
1586         PROTO_ITEM_SET_GENERATED(tree_item);
1587
1588         tree_item = proto_tree_add_string(jxta_msg_tree, hf_jxta_message_address, tvb, 0, 0, dst_addr);
1589         PROTO_ITEM_SET_HIDDEN(tree_item);
1590         PROTO_ITEM_SET_GENERATED(tree_item);
1591
1592         message_version = tvb_get_guint8(tvb, tree_offset);
1593         proto_tree_add_uint(jxta_msg_tree, hf_jxta_message_version, tvb, tree_offset, sizeof(guint8), message_version);
1594         tree_offset += sizeof(guint8);
1595
1596         if( message_version > 0 ) {
1597             guint8 flags = tvb_get_guint8(tvb, tree_offset);
1598             proto_item *flags_ti = proto_tree_add_uint(jxta_msg_tree, hf_jxta_message_flags, tvb, tree_offset, sizeof(guint8), flags);
1599             proto_tree *jxta_msg_flags_tree = proto_item_add_subtree(flags_ti, ett_jxta_msg_flags);
1600             proto_tree_add_boolean(jxta_msg_flags_tree, hf_jxta_message_flag_utf16be, tvb, tree_offset, 1, flags);
1601             proto_tree_add_boolean(jxta_msg_flags_tree, hf_jxta_message_flag_ucs32be, tvb, tree_offset, 1, flags);
1602             tree_offset += sizeof(guint8);
1603         }
1604
1605         msg_names_count = tvb_get_ntohs(tvb, tree_offset);
1606         proto_tree_add_uint(jxta_msg_tree, hf_jxta_message_names_count, tvb, tree_offset, sizeof(guint16), msg_names_count);
1607         tree_offset += sizeof(guint16);
1608
1609         names_table = ep_alloc((msg_names_count + 2) * sizeof(const gchar *));
1610         names_table[0] = "";
1611         names_table[1] = "jxta";
1612
1613         /* parse names */
1614         for (each_name = 0; each_name < msg_names_count; each_name++) {
1615             guint16 name_len = tvb_get_ntohs(tvb, tree_offset);
1616
1617             names_table[2 + each_name] = tvb_get_ephemeral_string(tvb, tree_offset + sizeof(name_len), name_len);
1618             proto_tree_add_item(jxta_msg_tree, hf_jxta_message_names_name, tvb, tree_offset, sizeof(name_len), FALSE);
1619             tree_offset += sizeof(name_len) + name_len;
1620         }
1621
1622         /* parse element count */
1623         elem_count = tvb_get_ntohs(tvb, tree_offset);
1624         proto_tree_add_item(jxta_msg_tree, hf_jxta_message_element_count, tvb, tree_offset, sizeof(guint16), FALSE);
1625         tree_offset += sizeof(guint16);
1626
1627         /* parse elements */
1628         for (each_elem = 0; each_elem < elem_count; each_elem++) {
1629             tvbuff_t *jxta_message_element_tvb = tvb_new_subset(tvb, tree_offset, -1, -1);
1630
1631             if(JXTA_MSG_VERSION_1 == message_version) {
1632                 tree_offset +=
1633                     dissect_jxta_message_element_1(jxta_message_element_tvb, pinfo, jxta_msg_tree, msg_names_count + 2, names_table);
1634             } else if(JXTA_MSG_VERSION_2 == message_version) {
1635                 tree_offset +=
1636                     dissect_jxta_message_element_2(jxta_message_element_tvb, pinfo, jxta_msg_tree, msg_names_count + 2, names_table);
1637             } else {
1638                 /* Sort of a lie, we say that we don't recognize it at all. */
1639                 return 0;
1640             }
1641        }
1642
1643         proto_item_set_end(jxta_msg_tree_item, tvb, tree_offset);
1644
1645         DISSECTOR_ASSERT(tree_offset == offset);
1646     }
1647
1648     if ((offset > 0) && (AT_URI == pinfo->src.type) && (AT_URI == pinfo->dst.type)) {
1649         jxta_tap_header *tap_header = se_alloc(sizeof(jxta_tap_header));
1650
1651         tap_header->src_address = pinfo->src;
1652         tap_header->dest_address = pinfo->dst;
1653         tap_header->size = offset;
1654
1655         tap_queue_packet(jxta_tap, pinfo, tap_header);
1656     }
1657
1658     return offset;
1659 }
1660
1661 /**
1662 *   Dissect a tvbuff containing a JXTA Message Element (Version 1).
1663 *
1664 *   @param  tvb The buffer to dissect.
1665 *   @param  pinfo Packet Info.
1666 *   @param  tree The protocol tree.
1667 *   @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
1668 *           the packet was not recognized as a JXTA packet and negative if the
1669 *           dissector needs more bytes in order to process a PDU.
1670 **/
1671 static int dissect_jxta_message_element_1(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, guint ns_count,
1672                                         const gchar ** names_table)
1673 {
1674     guint offset = 0;
1675     guint available;
1676     gint needed = 0;
1677     guint8 flags;
1678
1679     /* First pass. Make sure all of the bytes we need are available */
1680
1681     while (TRUE) {
1682         /* signature field */
1683         available = tvb_reported_length_remaining(tvb, offset);
1684         if (available < sizeof(JXTA_MSGELEM_SIG)) {
1685             needed = (gint) (sizeof(JXTA_MSGELEM_SIG) - available);
1686         }
1687
1688         if (tvb_memeql(tvb, offset, JXTA_MSGELEM_SIG, sizeof(JXTA_MSGELEM_SIG)) != 0) {
1689             /* It is not one of ours */
1690             return 0;
1691         }
1692
1693         offset += sizeof(JXTA_MSGELEM_SIG);
1694
1695         /* namespace id field */
1696         available = tvb_reported_length_remaining(tvb, offset);
1697         if (available < sizeof(guint8)) {
1698             needed = (gint) (sizeof(guint8) - available);
1699             break;
1700         }
1701
1702         offset += sizeof(guint8);
1703
1704         /* flags field */
1705         available = tvb_reported_length_remaining(tvb, offset);
1706         if (available < sizeof(guint8)) {
1707             needed = (gint) (sizeof(guint8) - available);
1708             break;
1709         } else {
1710             flags = tvb_get_guint8(tvb, offset);
1711             offset += sizeof(guint8);
1712         }
1713
1714         /* name field */
1715         available = tvb_reported_length_remaining(tvb, offset);
1716         if (available < sizeof(guint16)) {
1717             needed = (gint) (sizeof(guint16) - available);
1718             break;
1719         } else {
1720             guint16 name_len = tvb_get_ntohs(tvb, offset);
1721             offset += sizeof(guint16);
1722
1723             available = tvb_reported_length_remaining(tvb, offset);
1724             if (available < name_len) {
1725                 needed = (gint) (name_len - available);
1726                 break;
1727             }
1728
1729             offset += name_len;
1730         }
1731
1732         /* type field */
1733         if ((flags & JXTAMSG1_ELMFLAG_TYPE) != 0) {
1734             guint16 type_len;
1735
1736             available = tvb_reported_length_remaining(tvb, offset);
1737             if (available < sizeof(guint16)) {
1738                 needed = (gint) (sizeof(guint16) - available);
1739                 break;
1740             }
1741
1742             type_len = tvb_get_ntohs(tvb, offset);
1743             offset += sizeof(guint16);
1744
1745             available = tvb_reported_length_remaining(tvb, offset);
1746             if (available < type_len) {
1747                 needed = (gint) (type_len - available);
1748                 break;
1749             }
1750
1751             offset += type_len;
1752         }
1753
1754         /* encoding field */
1755         if ((flags & JXTAMSG1_ELMFLAG_ENCODING) != 0) {
1756             guint16 encoding_len;
1757
1758             available = tvb_reported_length_remaining(tvb, offset);
1759             if (available < sizeof(guint16)) {
1760                 needed = (gint) (sizeof(guint16) - available);
1761                 break;
1762             }
1763
1764             encoding_len = tvb_get_ntohs(tvb, offset);
1765             offset += sizeof(guint16);
1766
1767             available = tvb_reported_length_remaining(tvb, offset);
1768             if (available < encoding_len) {
1769                 needed = (gint) (encoding_len - available);
1770                 break;
1771             }
1772
1773             offset += encoding_len;
1774         }
1775
1776         /* content field */
1777         available = tvb_reported_length_remaining(tvb, offset);
1778         if (available < sizeof(guint16)) {
1779             needed = (gint) (sizeof(guint16) - available);
1780             break;
1781         } else {
1782             guint32 content_len = tvb_get_ntohl(tvb, offset);
1783             offset += sizeof(guint32);
1784
1785             available = tvb_reported_length_remaining(tvb, offset);
1786             if (available < content_len) {
1787                 needed = (gint) (content_len - available);
1788                 break;
1789             }
1790
1791             offset += content_len;
1792         }
1793
1794         /* signature element field */
1795         if ((flags & JXTAMSG1_ELMFLAG_SIGNATURE) != 0) {
1796             tvbuff_t *jxta_signature_element_tvb;
1797             int processed;
1798
1799             jxta_signature_element_tvb = tvb_new_subset(tvb, offset, -1, -1);
1800
1801             processed = dissect_jxta_message_element_1(jxta_signature_element_tvb, pinfo, NULL, 0, NULL);
1802
1803             if (processed == 0) {
1804                 return offset;
1805             }
1806
1807             if (processed < 0) {
1808                 needed = -processed;
1809                 break;
1810             }
1811
1812             offset += processed;
1813         }
1814
1815         break;
1816     }
1817
1818     if ((needed > 0) && gDESEGMENT && pinfo->can_desegment) {
1819         pinfo->desegment_offset = 0;
1820         pinfo->desegment_len = needed;
1821         return -needed;
1822     }
1823
1824     /* Second (optional) pass : build the proto tree */
1825     if (tree) {
1826         guint tree_offset = 0;
1827         proto_item *jxta_elem_tree_item = proto_tree_add_item(tree, hf_jxta_element, tvb, tree_offset, -1, FALSE);
1828         proto_tree *jxta_elem_tree = proto_item_add_subtree(jxta_elem_tree_item, ett_jxta_elem);
1829         guint8 namespaceID;
1830         proto_item *namespace_ti;
1831         guint16 name_len;
1832         proto_item *flags_ti;
1833         proto_tree *jxta_elem_flags_tree = NULL;
1834         guint32 content_len;
1835         gchar *mediatype = NULL;
1836         gboolean media_type_recognized = FALSE;
1837         tvbuff_t *element_content_tvb;
1838         proto_item * jxta_elem_length_item = NULL;
1839
1840         proto_tree_add_item(jxta_elem_tree, hf_jxta_element_sig, tvb, tree_offset, sizeof(JXTA_MSGELEM_SIG), FALSE);
1841         tree_offset += sizeof(JXTA_MSGELEM_SIG);
1842
1843         namespaceID = tvb_get_guint8(tvb, tree_offset);
1844         namespace_ti =
1845             proto_tree_add_uint(jxta_elem_tree, hf_jxta_element1_namespaceid, tvb, tree_offset, sizeof(guint8), namespaceID);
1846         if (namespaceID < ns_count) {
1847             proto_item_append_text(namespace_ti, " (%s)", names_table[namespaceID]);
1848         } else {
1849             proto_item_append_text(namespace_ti, " * BAD *");
1850         }
1851         tree_offset += sizeof(guint8);
1852
1853         flags = tvb_get_guint8(tvb, tree_offset);
1854         flags_ti = proto_tree_add_uint(jxta_elem_tree, hf_jxta_element_flags, tvb, tree_offset, sizeof(guint8), flags);
1855         jxta_elem_flags_tree = proto_item_add_subtree(flags_ti, ett_jxta_elem_1_flags);
1856         proto_tree_add_boolean(jxta_elem_flags_tree, hf_jxta_element1_flag_hasType, tvb, tree_offset, 1, flags);
1857         proto_tree_add_boolean(jxta_elem_flags_tree, hf_jxta_element1_flag_hasEncoding, tvb, tree_offset, 1, flags);
1858         proto_tree_add_boolean(jxta_elem_flags_tree, hf_jxta_element1_flag_hasSignature, tvb, tree_offset, 1, flags);
1859         tree_offset += sizeof(guint8);
1860
1861         name_len = tvb_get_ntohs(tvb, tree_offset);
1862         proto_item_append_text(jxta_elem_tree_item, " \"%s\"", tvb_format_text(tvb, tree_offset + sizeof(guint16), name_len));
1863         proto_tree_add_item(jxta_elem_tree, hf_jxta_element_name, tvb, tree_offset, sizeof(guint16), FALSE);
1864         tree_offset += sizeof(guint16) + name_len;
1865
1866         /* process type */
1867         if ((flags & JXTAMSG1_ELMFLAG_TYPE) != 0) {
1868             guint16 type_len = tvb_get_ntohs(tvb, tree_offset);
1869             proto_tree_add_item(jxta_elem_tree, hf_jxta_element_type, tvb, tree_offset, sizeof(guint16), FALSE);
1870             tree_offset += sizeof(guint16);
1871
1872             mediatype = tvb_get_ephemeral_string(tvb, tree_offset, type_len);
1873
1874             /* remove any params */
1875             {
1876                 gchar *parms_at = strchr(mediatype, ';');
1877
1878                 if (NULL != parms_at) {
1879                     *parms_at = '\0';
1880                 }
1881             }
1882
1883             /* force to lower case */
1884 #if GLIB_MAJOR_VERSION < 2
1885             g_strdown(mediatype);
1886 #else
1887             {
1888                 gchar *mediatype_lowercase = g_ascii_strdown(mediatype, -1);
1889                 mediatype = mediatype_lowercase;
1890             }
1891 #endif
1892             tree_offset += type_len;
1893         }
1894
1895         /* process encoding */
1896         if ((flags & JXTAMSG1_ELMFLAG_ENCODING) != 0) {
1897             guint16 encoding_len = tvb_get_ntohs(tvb, tree_offset);
1898             proto_tree_add_item(jxta_elem_tree, hf_jxta_element_encoding, tvb, tree_offset, sizeof(guint16), FALSE);
1899             tree_offset += sizeof(guint16) + encoding_len;
1900         }
1901
1902         /* content */
1903         content_len = tvb_get_ntohl(tvb, tree_offset);
1904         jxta_elem_length_item = proto_tree_add_item(jxta_elem_tree, hf_jxta_element_content_len, tvb, tree_offset, sizeof(guint32), FALSE);
1905         tree_offset += sizeof(guint32);
1906
1907         element_content_tvb = tvb_new_subset(tvb, tree_offset, content_len, content_len);
1908
1909         if (mediatype) {
1910             if (0 == strcmp("application/x-jxta-tls-block", mediatype)) {
1911                 /* If we recognize it as a TLS packet then we shuffle it off to ssl dissector. */
1912                 dissector_handle_t ssl_handle = find_dissector("ssl");
1913                 if (NULL != ssl_handle) {
1914                     int processed = call_dissector(ssl_handle, element_content_tvb, pinfo, jxta_elem_tree);
1915                     media_type_recognized = processed != 0;
1916                 }
1917             } else if (0 == strcmp("application/gzip", mediatype)) {
1918                 tvbuff_t *uncomp_tvb = tvb_uncompress(element_content_tvb, 0, tvb_length(element_content_tvb));
1919
1920                 if( NULL != uncomp_tvb ) {
1921                     proto_item_append_text( jxta_elem_length_item, " -> (%u uncompressed)", tvb_length(uncomp_tvb) );
1922
1923                     tvb_set_child_real_data_tvbuff(element_content_tvb, uncomp_tvb);
1924                     add_new_data_source(pinfo, uncomp_tvb, "Uncompressed Element Content");
1925
1926                     /* XXX bondolo 20060201 Force XML for uncompressed data. */
1927                     media_type_recognized = dissector_try_string(media_type_dissector_table,
1928                                                              "text/xml", uncomp_tvb, pinfo, jxta_elem_tree);
1929                 }
1930             } else {
1931                 media_type_recognized = dissector_try_string(media_type_dissector_table,
1932                                                              mediatype, element_content_tvb, pinfo, jxta_elem_tree);
1933             }
1934
1935         }
1936
1937         if (!media_type_recognized) {
1938             /* display it as raw data */
1939             call_dissector(data_handle, element_content_tvb, pinfo, jxta_elem_tree);
1940         }
1941         tree_offset += content_len;
1942
1943         /* process the signature element */
1944         if ((flags & JXTAMSG1_ELMFLAG_SIGNATURE) != 0) {
1945             tvbuff_t *jxta_message_element_tvb = tvb_new_subset(tvb, tree_offset, -1, -1);
1946
1947             tree_offset += dissect_jxta_message_element_1(jxta_message_element_tvb, pinfo, jxta_elem_tree, ns_count, names_table);
1948         }
1949
1950         proto_item_set_end(jxta_elem_tree_item, tvb, tree_offset);
1951
1952         DISSECTOR_ASSERT(tree_offset == offset);
1953     }
1954
1955     return offset;
1956 }
1957
1958 /**
1959 *   Dissect a tvbuff containing a JXTA Message Element (Version 2).
1960 *
1961 *   WARNING : The Version 2 Message Format is still under development and may change without notice (breaking this dissector).
1962 *
1963 *   @param  tvb The buffer to dissect.
1964 *   @param  pinfo Packet Info.
1965 *   @param  tree The protocol tree.
1966 *   @param  names_count The number of elements in the names table.
1967 *   @param  names The table of names.
1968 *   @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
1969 *           the packet was not recognized as a JXTA packet and negative if the
1970 *           dissector needs more bytes in order to process a PDU.
1971 **/
1972 static int dissect_jxta_message_element_2(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, guint names_count,
1973                                         const gchar ** names_table)
1974 {
1975     guint offset = 0;
1976     guint available;
1977     gint needed = 0;
1978     guint8 flags;
1979
1980     /* First pass. Make sure all of the bytes we need are available */
1981
1982     while (TRUE) {
1983         /* signature field */
1984         available = tvb_reported_length_remaining(tvb, offset);
1985         if (available < sizeof(JXTA_MSGELEM_SIG)) {
1986             needed = (gint) (sizeof(JXTA_MSGELEM_SIG) - available);
1987         }
1988
1989         if (tvb_memeql(tvb, offset, JXTA_MSGELEM_SIG, sizeof(JXTA_MSGELEM_SIG)) != 0) {
1990             /* It is not one of ours */
1991             return 0;
1992         }
1993
1994         offset += sizeof(JXTA_MSGELEM_SIG);
1995
1996         /* flags field */
1997         available = tvb_reported_length_remaining(tvb, offset);
1998         if (available < sizeof(guint8)) {
1999             needed = (gint) (sizeof(guint8) - available);
2000             break;
2001         } else {
2002             flags = tvb_get_guint8(tvb, offset);
2003             offset += sizeof(guint8);
2004         }
2005
2006         /* namespace id field */
2007         available = tvb_reported_length_remaining(tvb, offset);
2008         if (available < sizeof(guint16)) {
2009             needed = (gint) (sizeof(guint16) - available);
2010             break;
2011         }
2012
2013         offset += sizeof(guint16);
2014
2015         /* name field */
2016         if ((flags & JXTAMSG2_ELMFLAG_NAME_LITERAL) == 0) {
2017             available = tvb_reported_length_remaining(tvb, offset);
2018             if (available < sizeof(guint16)) {
2019                 needed = (gint) (sizeof(guint16) - available);
2020                 break;
2021             }
2022
2023             offset += sizeof(guint16);
2024         } else {
2025             /* literal name field */
2026             available = tvb_reported_length_remaining(tvb, offset);
2027             if (available < sizeof(guint16)) {
2028                 needed = (gint) (sizeof(guint16) - available);
2029                 break;
2030             } else {
2031                 guint16 name_len = tvb_get_ntohs(tvb, offset);
2032                 offset += sizeof(guint16);
2033
2034                 available = tvb_reported_length_remaining(tvb, offset);
2035                 if (available < name_len) {
2036                     needed = (gint) (name_len - available);
2037                     break;
2038                 }
2039
2040                 offset += name_len;
2041             }
2042         }
2043
2044         /* type field */
2045         if ((flags & JXTAMSG2_ELMFLAG_TYPE) != 0) {
2046             available = tvb_reported_length_remaining(tvb, offset);
2047             if (available < sizeof(guint16)) {
2048                 needed = (gint) (sizeof(guint16) - available);
2049                 break;
2050             }
2051
2052             offset += sizeof(guint16);
2053         }
2054
2055         /* encoding field */
2056         if ((flags & JXTAMSG2_ELMFLAG_ENCODINGS) != 0) {
2057             available = tvb_reported_length_remaining(tvb, offset);
2058             if (available < sizeof(guint16)) {
2059                 needed = (gint) (sizeof(guint16) - available);
2060                 break;
2061             }
2062
2063             offset += sizeof(guint16);
2064         }
2065
2066
2067         /* content field */
2068         if ((flags & JXTAMSG2_ELMFLAG_UINT64_LENS) != 0) {
2069             available = tvb_reported_length_remaining(tvb, offset);
2070             if (available < sizeof(guint64)) {
2071                 needed = (gint) (sizeof(guint64) - available);
2072                 break;
2073             } else {
2074                 guint64 content_len = tvb_get_ntoh64(tvb, offset);
2075                 offset += sizeof(guint64);
2076
2077                 available = tvb_reported_length_remaining(tvb, offset);
2078                 if (available < content_len) {
2079                     needed = (gint) (content_len - available);
2080                     break;
2081                 }
2082
2083                 offset += (guint) content_len;
2084             }
2085         } else {
2086             available = tvb_reported_length_remaining(tvb, offset);
2087             if (available < sizeof(guint32)) {
2088                 needed = (gint) (sizeof(guint32) - available);
2089                 break;
2090             } else {
2091                 guint64 content_len = tvb_get_ntohl(tvb, offset);
2092                 offset += sizeof(guint32);
2093
2094                 available = tvb_reported_length_remaining(tvb, offset);
2095                 if (available < content_len) {
2096                     needed = (gint) (content_len - available);
2097                     break;
2098                 }
2099
2100                 offset += (guint) content_len;
2101             }
2102         }
2103
2104         /* signature element field */
2105         if ((flags & JXTAMSG2_ELMFLAG_SIGNATURE) != 0) {
2106             tvbuff_t *jxta_signature_element_tvb;
2107             int processed;
2108
2109             jxta_signature_element_tvb = tvb_new_subset(tvb, offset, -1, -1);
2110
2111             processed = dissect_jxta_message_element_2(jxta_signature_element_tvb, pinfo, NULL, 0, NULL);
2112
2113             if (processed == 0) {
2114                 return offset;
2115             }
2116
2117             if (processed < 0) {
2118                 needed = -processed;
2119                 break;
2120             }
2121
2122             offset += processed;
2123         }
2124
2125         break;
2126     }
2127
2128     if ((needed > 0) && gDESEGMENT && pinfo->can_desegment) {
2129         pinfo->desegment_offset = 0;
2130         pinfo->desegment_len = needed;
2131         return -needed;
2132     }
2133
2134     /* Second (optional) pass : build the proto tree */
2135     if (tree) {
2136         guint tree_offset = 0;
2137         proto_item *jxta_elem_tree_item = proto_tree_add_item(tree, hf_jxta_element, tvb, tree_offset, -1, FALSE);
2138         proto_tree *jxta_elem_tree = proto_item_add_subtree(jxta_elem_tree_item, ett_jxta_elem);
2139         proto_item *flags_ti;
2140         proto_tree *jxta_elem_flags_tree = NULL;
2141         guint16 namespaceID;
2142         proto_item *namespace_ti;
2143         guint16 nameID;
2144         proto_item *name_ti;
2145         guint64 content_len;
2146         gchar *mediatype = NULL;
2147         gboolean media_type_recognized = FALSE;
2148         tvbuff_t *element_content_tvb;
2149         proto_item * jxta_elem_length_item = NULL;
2150
2151         proto_tree_add_item(jxta_elem_tree, hf_jxta_element_sig, tvb, tree_offset, sizeof(JXTA_MSGELEM_SIG), FALSE);
2152         tree_offset += sizeof(JXTA_MSGELEM_SIG);
2153
2154         flags = tvb_get_guint8(tvb, tree_offset);
2155         flags_ti = proto_tree_add_uint(jxta_elem_tree, hf_jxta_element_flags, tvb, tree_offset, sizeof(guint8), flags);
2156         jxta_elem_flags_tree = proto_item_add_subtree(flags_ti, ett_jxta_elem_2_flags);
2157         proto_tree_add_boolean(jxta_elem_flags_tree, hf_jxta_element2_flag_64bitlens, tvb, tree_offset, 1, flags);
2158         proto_tree_add_boolean(jxta_elem_flags_tree, hf_jxta_element2_flag_nameLiteral, tvb, tree_offset, 1, flags);
2159         proto_tree_add_boolean(jxta_elem_flags_tree, hf_jxta_element2_flag_hasType, tvb, tree_offset, 1, flags);
2160         proto_tree_add_boolean(jxta_elem_flags_tree, hf_jxta_element2_flag_hasSignature, tvb, tree_offset, 1, flags);
2161         proto_tree_add_boolean(jxta_elem_flags_tree, hf_jxta_element2_flag_hasEncoding, tvb, tree_offset, 1, flags);
2162         proto_tree_add_boolean(jxta_elem_flags_tree, hf_jxta_element2_flag_sigOfEncoded, tvb, tree_offset, 1, flags);
2163         tree_offset += sizeof(guint8);
2164
2165         /* Namespace */
2166         namespaceID = tvb_get_ntohs(tvb, tree_offset);
2167         namespace_ti =
2168             proto_tree_add_uint(jxta_elem_tree, hf_jxta_element2_namespaceid, tvb, tree_offset, sizeof(guint16), namespaceID);
2169         if (namespaceID < names_count) {
2170             proto_item_append_text(namespace_ti, " (%s)", names_table[namespaceID]);
2171         } else {
2172             proto_item_append_text(namespace_ti, " * BAD *");
2173         }
2174         tree_offset += sizeof(guint16);
2175
2176         /* Name */
2177         if ((flags & JXTAMSG2_ELMFLAG_NAME_LITERAL) == 0) {
2178             nameID = tvb_get_ntohs(tvb, tree_offset);
2179             name_ti =
2180                 proto_tree_add_uint(jxta_elem_tree, hf_jxta_element2_nameid, tvb, tree_offset, sizeof(guint16), nameID);
2181             if (namespaceID < names_count) {
2182                 proto_item_append_text(name_ti, " (%s)", names_table[nameID]);
2183             } else {
2184                 proto_item_append_text(name_ti, " * BAD *");
2185             }
2186             tree_offset += sizeof(guint16);
2187         } else {
2188             /* literal name */
2189             guint16 name_len = tvb_get_ntohs(tvb, tree_offset);
2190             proto_item_append_text(jxta_elem_tree_item, " \"%s\"", tvb_format_text(tvb, tree_offset + sizeof(guint16), name_len));
2191             proto_tree_add_item(jxta_elem_tree, hf_jxta_element_name, tvb, tree_offset, sizeof(guint16), FALSE);
2192             tree_offset += sizeof(guint16) + name_len;
2193         }
2194
2195         /* process type */
2196         if ((flags & JXTAMSG2_ELMFLAG_TYPE) != 0) {
2197             guint16 mimeID = tvb_get_ntohs(tvb, tree_offset);
2198             proto_item *mime_ti =
2199                 proto_tree_add_uint(jxta_elem_tree, hf_jxta_element2_mimeid, tvb, tree_offset, sizeof(guint16), mimeID);
2200
2201             if (mimeID < names_count) {
2202                 proto_item_append_text(mime_ti, " (%s)", names_table[mimeID]);
2203                 mediatype = strdup( names_table[mimeID] );
2204
2205                 /* remove any params */
2206                 {
2207                     gchar *parms_at = strchr(mediatype, ';');
2208
2209                     if (NULL != parms_at) {
2210                         *parms_at = '\0';
2211                     }
2212                 }
2213
2214                 /* force to lower case */
2215 #if GLIB_MAJOR_VERSION < 2
2216                 g_strdown(mediatype);
2217 #else
2218                 {
2219                     gchar *mediatype_lowercase = g_ascii_strdown(mediatype, -1);
2220                     mediatype = mediatype_lowercase;
2221                 }
2222 #endif
2223             } else {
2224                 proto_item_append_text(mime_ti, " * BAD *");
2225             }
2226
2227             tree_offset += sizeof(guint16);
2228         } else {
2229             mediatype = strdup( "application/octect-stream" );
2230         }
2231
2232         /* process encoding */
2233         if ((flags & JXTAMSG2_ELMFLAG_ENCODINGS) != 0) {
2234             guint16 encodingID = tvb_get_ntohs(tvb, tree_offset);
2235             proto_item *encoding_ti =
2236                 proto_tree_add_uint(jxta_elem_tree, hf_jxta_element2_encodingid, tvb, tree_offset, sizeof(guint16), encodingID);
2237
2238             if (encodingID < names_count) {
2239                 proto_item_append_text(encoding_ti, " (%s)", names_table[encodingID]);
2240             } else {
2241                 proto_item_append_text(encoding_ti, " * BAD *");
2242             }
2243
2244             tree_offset += sizeof(guint16);
2245         }
2246
2247
2248         if ((flags & JXTAMSG2_ELMFLAG_UINT64_LENS) != 0) {
2249             content_len = tvb_get_ntoh64(tvb, tree_offset);
2250             jxta_elem_length_item = proto_tree_add_item(jxta_elem_tree, hf_jxta_element_content_len64, tvb, tree_offset, sizeof(guint64), FALSE);
2251             tree_offset += sizeof(guint64);
2252         } else {
2253             content_len = tvb_get_ntohl(tvb, tree_offset);
2254             jxta_elem_length_item = proto_tree_add_item(jxta_elem_tree, hf_jxta_element_content_len, tvb, tree_offset, sizeof(guint32), FALSE);
2255             tree_offset += sizeof(guint32);
2256         }
2257
2258         /* content */
2259         element_content_tvb = tvb_new_subset(tvb, tree_offset, (gint)content_len, (gint)content_len);
2260
2261         if (mediatype) {
2262             if (0 == strcmp("application/x-jxta-tls-block", mediatype)) {
2263                 /* If we recognize it as a TLS packet then we shuffle it off to ssl dissector. */
2264                 dissector_handle_t ssl_handle = find_dissector("ssl");
2265                 if (NULL != ssl_handle) {
2266                     int processed = call_dissector(ssl_handle, element_content_tvb, pinfo, jxta_elem_tree);
2267                     media_type_recognized = processed != 0;
2268                 }
2269             } else if (0 == strcmp("application/gzip", mediatype)) {
2270                 tvbuff_t *uncomp_tvb = tvb_uncompress(element_content_tvb, 0, tvb_length(element_content_tvb));
2271
2272                 if( NULL != uncomp_tvb ) {
2273                     proto_item_append_text( jxta_elem_length_item, " -> (%u uncompressed)", tvb_length(uncomp_tvb) );
2274
2275                     tvb_set_child_real_data_tvbuff(element_content_tvb, uncomp_tvb);
2276                     add_new_data_source(pinfo, uncomp_tvb, "Uncompressed Element Content");
2277
2278                     /* XXX bondolo 20060201 Force XML for uncompressed data. */
2279                     media_type_recognized = dissector_try_string(media_type_dissector_table,
2280                                                              "text/xml", uncomp_tvb, pinfo, jxta_elem_tree);
2281                 }
2282             } else {
2283                 media_type_recognized = dissector_try_string(media_type_dissector_table,
2284                                                              mediatype, element_content_tvb, pinfo, jxta_elem_tree);
2285             }
2286
2287         }
2288
2289         if (!media_type_recognized) {
2290             /* display it as raw data */
2291             call_dissector(data_handle, element_content_tvb, pinfo, jxta_elem_tree);
2292         }
2293         tree_offset += (guint) content_len;
2294
2295         /* process the signature element */
2296         if ((flags & JXTAMSG2_ELMFLAG_SIGNATURE) != 0) {
2297             tvbuff_t *jxta_message_element_tvb = tvb_new_subset(tvb, tree_offset, -1, -1);
2298
2299             tree_offset += dissect_jxta_message_element_1(jxta_message_element_tvb, pinfo, jxta_elem_tree, names_count, names_table);
2300         }
2301
2302         proto_item_set_end(jxta_elem_tree_item, tvb, tree_offset);
2303
2304         DISSECTOR_ASSERT(tree_offset == offset);
2305     }
2306
2307     return offset;
2308 }
2309
2310 /**
2311 *    Register jxta protocol and jxta message protocol, header fields, subtree types, preferences.
2312 **/
2313 void proto_register_jxta(void)
2314 {
2315     module_t *jxta_module;
2316
2317     media_type_dissector_table = find_dissector_table("media_type");
2318
2319     data_handle = find_dissector("data");
2320
2321     proto_jxta = proto_register_protocol("JXTA P2P", "JXTA", "jxta");
2322
2323     jxta_tap = register_tap("jxta");
2324
2325     /* The JXTA Binary Message Wire Format : Registered and dissected by MIME type */
2326     proto_message_jxta = proto_register_protocol("JXTA Message", "JXTA Message", "jxta.message");
2327
2328     message_jxta_handle = new_create_dissector_handle(dissect_jxta_message, proto_message_jxta);
2329
2330     dissector_add_string("media_type", "application/x-jxta-msg", message_jxta_handle);
2331
2332     /* Register header fields */
2333     proto_register_field_array(proto_jxta, hf, array_length(hf));
2334
2335     /* Register JXTA Sub-tree */
2336     proto_register_subtree_array(ett, array_length(ett));
2337
2338     /* Register preferences */
2339     /* register re-init routine */
2340     jxta_module = prefs_register_protocol(proto_jxta, proto_reg_handoff_jxta);
2341
2342     prefs_register_bool_preference(jxta_module, "desegment",
2343                                    "Reassemble JXTA messages spanning multiple UDP/TCP/HTTP segments",
2344                                    "Whether the JXTA dissector should reassemble messages spanning multiple UDP/HTTP/TCP segments."
2345                                    " To use this option you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings "
2346                                    " and enable \"Reassemble fragmented IP datagrams\" in the IP protocol settings.",
2347                                    &gDESEGMENT);
2348
2349     prefs_register_bool_preference(jxta_module, "udp.heuristic", "Try to discover JXTA in UDP datagrams",
2350                                    "Enable to inspect UDP datagrams for JXTA messages.", &gUDP_HEUR);
2351
2352     prefs_register_bool_preference(jxta_module, "tcp.heuristic", "Try to discover JXTA in TCP connections",
2353                                    "Enable to inspect TCP connections for JXTA conversations.", &gTCP_HEUR);
2354
2355     prefs_register_bool_preference(jxta_module, "sctp.heuristic", "Try to discover JXTA in SCTP connections",
2356                                    "Enable to inspect SCTP connections for JXTA conversations.", &gSCTP_HEUR);
2357 }
2358
2359 /**
2360 *   Update registrations in response to
2361 **/
2362 void proto_reg_handoff_jxta(void)
2363 {
2364     static gboolean init_done = FALSE;
2365
2366     if (!init_done) {
2367         /* XXX 20051004 bondolo We could dynamically add dissectors based upon prefs. */
2368         new_register_dissector("jxta.udp", dissect_jxta_udp, proto_jxta);
2369         heur_dissector_add("udp", dissect_jxta_UDP_heur, proto_jxta);
2370
2371         new_register_dissector("jxta.stream", dissect_jxta_stream, proto_jxta);
2372         stream_jxta_handle = find_dissector("jxta.stream");
2373         heur_dissector_add("tcp", dissect_jxta_TCP_heur, proto_jxta);
2374         heur_dissector_add("sctp", dissect_jxta_SCTP_heur, proto_jxta);
2375
2376         init_done = TRUE;
2377     }
2378 }