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