3 * Routines for JXTA packet dissection
4 * JXTA specification from https://jxta-spec.dev.java.net (now at https://github.com/chaupal/jxta-spec ?)
6 * Copyright 2004-08, Mike Duigou <bondolo@dev.java.net>
8 * Heavily based on packet-jabber.c, which in turn is heavily based on
9 * on packet-acap.c, which in turn is heavily based on
10 * packet-imap.c, Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
11 * Copied from packet-pop.c, packet-jabber.c, packet-udp.c, packet-http.c
13 * Wireshark - Network traffic analyzer
14 * By Gerald Combs <gerald@wireshark.org>
15 * Copyright 2000 Gerald Combs
17 * SPDX-License-Identifier: GPL-2.0-or-later
22 #define WS_LOG_DOMAIN "jxta"
24 #include <epan/packet.h>
25 #include <epan/conversation.h>
26 #include <epan/conversation_table.h>
27 #include <epan/prefs.h>
28 #include <epan/to_str.h>
29 #include <epan/address_types.h>
30 #include <epan/expert.h>
32 #include <wsutil/array.h>
33 #include <wsutil/str_util.h>
35 #include "packet-jxta.h"
36 #include "packet-media-type.h"
38 void proto_register_jxta(void);
39 void proto_reg_handoff_jxta(void);
41 static const char JXTA_UDP_SIG
[] = { 'J', 'X', 'T', 'A' };
42 static const char JXTA_MSG_SIG
[] = { 'j', 'x', 'm', 'g' };
43 static const char JXTA_MSGELEM_SIG
[] = { 'j', 'x', 'e', 'l' };
45 static const char JXTA_WELCOME_MSG_SIG
[] = { 'J', 'X', 'T', 'A', 'H', 'E', 'L', 'L', 'O', ' ' };
47 static const char* JXTA_WELCOME_MSG_VERSION_1_1
= "1.1";
48 static const char* JXTA_WELCOME_MSG_VERSION_3_0
= "3.0";
50 static const int JXTA_MSG_VERSION_1
;
51 static const int JXTA_MSG_VERSION_2
= 1;
53 static const int JXTAMSG1_ELMFLAG_TYPE
= 1 << 0;
54 static const int JXTAMSG1_ELMFLAG_ENCODING
= 1 << 1;
55 static const int JXTAMSG1_ELMFLAG_SIGNATURE
= 1 << 2;
57 static const int JXTAMSG2_ELMFLAG_UINT64_LENS
= 1 << 0;
58 static const int JXTAMSG2_ELMFLAG_NAME_LITERAL
= 1 << 1;
59 static const int JXTAMSG2_ELMFLAG_TYPE
= 1 << 2;
60 static const int JXTAMSG2_ELMFLAG_SIGNATURE
= 1 << 3;
61 static const int JXTAMSG2_ELMFLAG_ENCODINGS
= 1 << 4;
63 static int proto_jxta
;
64 static int proto_message_jxta
;
67 static dissector_table_t media_type_dissector_table
;
68 static dissector_handle_t media_handle
;
69 static dissector_handle_t stream_jxta_handle
;
70 static dissector_handle_t tls_handle
;
72 static int hf_uri_addr
;
73 static int hf_uri_src
;
74 static int hf_uri_dst
;
75 static int hf_jxta_udp
;
76 static int hf_jxta_udpsig
;
77 static int hf_jxta_welcome
;
78 static int hf_jxta_welcome_initiator
;
79 static int hf_jxta_welcome_sig
;
80 static int hf_jxta_welcome_destAddr
;
81 static int hf_jxta_welcome_pubAddr
;
82 static int hf_jxta_welcome_peerid
;
83 static int hf_jxta_welcome_noProp
;
84 static int hf_jxta_welcome_msgVers
;
85 static int hf_jxta_welcome_variable
;
86 static int hf_jxta_welcome_version
;
87 static int hf_jxta_framing
;
88 static int hf_jxta_framing_header
;
89 static int hf_jxta_framing_header_name
;
90 static int hf_jxta_framing_header_value_length
;
91 static int hf_jxta_framing_header_value
;
92 static int hf_jxta_message_address
;
93 static int hf_jxta_message_src
;
94 static int hf_jxta_message_dst
;
95 static int hf_jxta_message_sig
;
96 static int hf_jxta_message_version
;
97 static int hf_jxta_message_flags
;
98 static int hf_jxta_message_flag_utf16be
;
99 static int hf_jxta_message_flag_ucs32be
;
100 static int hf_jxta_message_names_count
;
101 static int hf_jxta_message_names_name
;
102 static int hf_jxta_message_element_count
;
103 static int hf_jxta_element
;
104 static int hf_jxta_element_sig
;
105 static int hf_jxta_element1_namespaceid
;
106 static int hf_jxta_element2_namespaceid
;
107 static int hf_jxta_element2_nameid
;
108 static int hf_jxta_element2_mimeid
;
109 static int hf_jxta_element2_encodingid
;
110 static int hf_jxta_element_flags
;
111 static int hf_jxta_element1_flag_hasType
;
112 static int hf_jxta_element1_flag_hasEncoding
;
113 static int hf_jxta_element1_flag_hasSignature
;
114 static int hf_jxta_element2_flag_64bitlens
;
115 static int hf_jxta_element2_flag_nameLiteral
;
116 static int hf_jxta_element2_flag_hasType
;
117 static int hf_jxta_element2_flag_hasSignature
;
118 static int hf_jxta_element2_flag_hasEncoding
;
119 static int hf_jxta_element2_flag_sigOfEncoded
;
120 static int hf_jxta_element_name
;
121 static int hf_jxta_element_type
;
122 static int hf_jxta_element_encoding
;
123 static int hf_jxta_element_content_len
;
124 static int hf_jxta_element_content_len64
;
125 /* static int hf_jxta_element_content; */
128 * JXTA Protocol subtree handles
131 static int ett_jxta_welcome
;
132 static int ett_jxta_udp
;
133 static int ett_jxta_framing
;
134 static int ett_jxta_framing_header
;
135 static int ett_jxta_msg
;
136 static int ett_jxta_msg_flags
;
137 static int ett_jxta_elem
;
138 static int ett_jxta_elem_1_flags
;
139 static int ett_jxta_elem_2_flags
;
141 static expert_field ei_media_too_short
;
143 static int uri_address_type
= -1;
148 static bool gDESEGMENT
= true;
149 static bool gMSG_MEDIA
= true;
151 static dissector_handle_t jxta_udp_handle
;
154 * Stream Conversation data
156 struct jxta_stream_conversation_data
{
159 address initiator_tpt_address
;
160 uint32_t initiator_tpt_port
;
161 uint32_t initiator_welcome_frame
;
162 address initiator_address
;
164 address receiver_tpt_address
;
165 uint32_t receiver_tpt_port
;
166 uint32_t receiver_welcome_frame
;
167 address receiver_address
;
170 typedef struct jxta_stream_conversation_data jxta_stream_conversation_data
;
172 static const char* jxta_conv_get_filter_type(conv_item_t
* conv
, conv_filter_type_e filter
)
174 if ((filter
== CONV_FT_SRC_ADDRESS
) && (conv
->src_address
.type
== uri_address_type
))
175 return "jxta.message.src";
177 if ((filter
== CONV_FT_DST_ADDRESS
) && (conv
->dst_address
.type
== uri_address_type
))
178 return "jxta.message.dst";
180 if ((filter
== CONV_FT_ANY_ADDRESS
) && (conv
->src_address
.type
== uri_address_type
))
181 return "jxta.message.address";
183 return CONV_FILTER_INVALID
;
186 static ct_dissector_info_t jxta_ct_dissector_info
= {&jxta_conv_get_filter_type
};
188 static tap_packet_status
189 jxta_conversation_packet(void *pct
, packet_info
*pinfo _U_
, epan_dissect_t
*edt _U_
, const void *vip
, tap_flags_t flags
)
191 conv_hash_t
*hash
= (conv_hash_t
*) pct
;
194 const jxta_tap_header
*jxtahdr
= (const jxta_tap_header
*) vip
;
196 add_conversation_table_data(hash
, &jxtahdr
->src_address
, &jxtahdr
->dest_address
,
197 0, 0, 1, jxtahdr
->size
, NULL
, NULL
, &jxta_ct_dissector_info
, CONVERSATION_NONE
);
199 return TAP_PACKET_REDRAW
;
202 static const char* jxta_endpoint_get_filter_type(endpoint_item_t
* endpoint
, conv_filter_type_e filter
)
204 if ((filter
== CONV_FT_ANY_ADDRESS
) && (endpoint
->myaddress
.type
== uri_address_type
))
205 return "jxta.message.address";
207 return CONV_FILTER_INVALID
;
210 static et_dissector_info_t jxta_endpoint_dissector_info
= {&jxta_endpoint_get_filter_type
};
212 static tap_packet_status
213 jxta_endpoint_packet(void *pit
, packet_info
*pinfo _U_
, epan_dissect_t
*edt _U_
, const void *vip
, tap_flags_t flags
)
215 conv_hash_t
*hash
= (conv_hash_t
*) pit
;
218 const jxta_tap_header
*jxtahdr
= (const jxta_tap_header
*)vip
;
220 /* Take two "add" passes per packet, adding for each direction, ensures that all
221 packets are counted properly (even if address is sending to itself)
222 XXX - this could probably be done more efficiently inside endpoint_table */
223 add_endpoint_table_data(hash
, &jxtahdr
->src_address
, 0, true, 1, jxtahdr
->size
, &jxta_endpoint_dissector_info
, ENDPOINT_NONE
);
224 add_endpoint_table_data(hash
, &jxtahdr
->dest_address
, 0, false, 1, jxtahdr
->size
, &jxta_endpoint_dissector_info
, ENDPOINT_NONE
);
225 return TAP_PACKET_REDRAW
;
228 static int uri_to_str(const address
* addr
, char *buf
, int buf_len
)
230 int copy_len
= addr
->len
< (buf_len
- 1) ? addr
->len
: (buf_len
- 1);
231 memcpy(buf
, addr
->data
, copy_len
);
232 buf
[copy_len
] = '\0';
236 static int uri_str_len(const address
* addr
)
241 static const char* uri_col_filter_str(const address
* addr _U_
, bool is_src
)
252 static int dissect_jxta_udp(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void * data
);
253 static int dissect_jxta_stream(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void * data
);
254 static jxta_stream_conversation_data
*get_tpt_conversation(packet_info
* pinfo
);
255 static conversation_t
*get_peer_conversation(packet_info
* pinfo
, jxta_stream_conversation_data
* tpt_conv_data
, bool create
);
257 static int dissect_jxta_welcome(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, address
* found_addr
, bool initiator
);
258 static int dissect_jxta_message_framing(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, uint64_t * content_length
,
259 char ** content_type
);
260 static int dissect_jxta_message(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void * data
);
261 static int dissect_jxta_message_element_1(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, unsigned ns_count
,
262 const char ** namespaces
);
263 static int dissect_jxta_message_element_2(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, unsigned ns_count
,
264 const char ** namespaces
);
265 static int dissect_media( const char* fullmediatype
, tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
);
268 * Heuristically dissect a tvbuff containing a JXTA UDP Message
270 * @param tvb The buffer to dissect.
271 * @param pinfo Packet Info.
272 * @param tree The protocol tree.
273 * @return true if the tvb contained JXTA data which was dissected otherwise false
275 static bool dissect_jxta_UDP_heur(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void * data _U_
)
277 /* This is a heuristic dissector, which means we get all the UDP
278 * traffic not sent to a known dissector and not claimed by
279 * a heuristic dissector called before us!
281 int save_desegment_offset
;
282 uint32_t save_desegment_len
;
285 if (tvb_strneql(tvb
, 0, JXTA_UDP_SIG
, sizeof (JXTA_UDP_SIG
)) != 0) {
286 /* Not a JXTA UDP packet (or not enough bytes to check for the sig) */
290 save_desegment_offset
= pinfo
->desegment_offset
;
291 save_desegment_len
= pinfo
->desegment_len
;
292 ret
= dissect_jxta_udp(tvb
, pinfo
, tree
, NULL
);
294 /* ws_message( "%d Heuristic UDP Dissection : %d", pinfo->num, ret ); */
298 * UDP is not a packet stream protocol, so the UDP dissector
299 * should not, and will not, do the sort of dissection help
300 * that the TCP dissector will. If JXTA messages don't
301 * start and end on UDP packet boundaries, the JXTA dissector
302 * will have to do its own byte stream reassembly.
304 pinfo
->desegment_offset
= save_desegment_offset
;
305 pinfo
->desegment_len
= save_desegment_len
;
307 } else if (ret
== 0) {
311 pinfo
->desegment_offset
= save_desegment_offset
;
312 pinfo
->desegment_len
= save_desegment_len
;
316 * A clear acceptance.
323 * Heuristically dissect a tvbuff containing a JXTA TCP Stream
325 * @param tvb The buffer to dissect.
326 * @param pinfo Packet Info.
327 * @param tree The protocol tree.
328 * @return true if the tvb contained JXTA data which was dissected otherwise false
330 static bool dissect_jxta_TCP_heur(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void * data _U_
)
332 /* This is a heuristic dissector, which means we get all the TCP
333 * traffic not sent to a known dissector and not claimed by
334 * a heuristic dissector called before us!
336 int save_desegment_offset
;
337 uint32_t save_desegment_len
;
340 save_desegment_offset
= pinfo
->desegment_offset
;
341 save_desegment_len
= pinfo
->desegment_len
;
342 ret
= dissect_jxta_stream(tvb
, pinfo
, tree
, NULL
);
344 /* ws_message( "%d Heuristic TCP Dissection : %d", pinfo->num, ret ); */
348 * A heuristic dissector for a TCP-based protocol can reject
349 * a packet, or it can request that more data be provided.
350 * It must not attempt to do both, as the notion of doing both
351 * is nonsensical - if the packet isn't considered a packet
352 * for the dissector's protocol, that dissector won't be
353 * dissecting it no matter *how* much more data is added.
355 * Therefore, we treat a negative return from
356 * dissect_jxta_stream() as a rejection.
358 * If that's not desired - i.e., if we should keep trying to get
359 * more data, in the hopes that we'll eventually be able to
360 * determine whether the packet is a JXTA packet or not - we
361 * should, in this case, leave pinfo->desegment_offset and
362 * pinfo->desegment_len alone, and return true, *NOT* false.
364 pinfo
->desegment_offset
= save_desegment_offset
;
365 pinfo
->desegment_len
= save_desegment_len
;
367 } else if (ret
== 0) {
371 pinfo
->desegment_offset
= save_desegment_offset
;
372 pinfo
->desegment_len
= save_desegment_len
;
376 * A clear acceptance.
383 * Heuristically dissect a tvbuff containing a JXTA SCTP Stream
385 * @param tvb The buffer to dissect.
386 * @param pinfo Packet Info.
387 * @param tree The protocol tree.
388 * @return true if the tvb contained JXTA data which was dissected otherwise false
390 static bool dissect_jxta_SCTP_heur(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void * data _U_
)
392 /* This is a heuristic dissector, which means we get all the SCTP
393 * traffic not sent to a known dissector and not claimed by
394 * a heuristic dissector called before us!
396 int save_desegment_offset
;
397 uint32_t save_desegment_len
;
400 save_desegment_offset
= pinfo
->desegment_offset
;
401 save_desegment_len
= pinfo
->desegment_len
;
402 ret
= dissect_jxta_stream(tvb
, pinfo
, tree
, NULL
);
404 /* ws_message( "%d Heuristic SCTP Dissection : %d", pinfo->num, ret ); */
408 * SCTP is not a byte stream protocol, so the SCTP dissector
409 * should not, and will not, do the sort of dissection help
410 * that the SCTP dissector will. If JXTA messages don't
411 * start and end on SCTP packet boundaries, the JXTA dissector
412 * will have to do its own byte stream reassembly.
414 * The SCTP dissector currently won't do reassembly. If that
415 * causes a problem for the JXTA dissector, the correct fix
416 * is to implement reassembly in the SCTP dissector, so *all*
417 * dissectors for protocols running atop SCTP can benefit from
420 pinfo
->desegment_offset
= save_desegment_offset
;
421 pinfo
->desegment_len
= save_desegment_len
;
423 } else if (ret
== 0) {
427 pinfo
->desegment_offset
= save_desegment_offset
;
428 pinfo
->desegment_len
= save_desegment_len
;
432 * A clear acceptance.
439 * Dissect a tvbuff containing a JXTA UDP header, JXTA Message framing and a JXTA Message
441 * @param tvb The buffer to dissect.
442 * @param pinfo Packet Info.
443 * @param tree The protocol tree.
444 * @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
445 * the packet was not recognized as a JXTA packet and negative if the
446 * dissector needs more bytes in order to process a PDU.
448 static int dissect_jxta_udp(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void * data _U_
)
454 conversation_t
*conversation
= find_or_create_conversation(pinfo
);
456 conversation_set_dissector(conversation
, jxta_udp_handle
);
459 tvbuff_t
*jxta_message_framing_tvb
;
461 uint64_t content_length
= -1;
462 char *content_type
= NULL
;
464 available
= tvb_reported_length_remaining(tvb
, offset
);
465 if (available
< sizeof(JXTA_UDP_SIG
)) {
466 needed
= (int) (sizeof(JXTA_UDP_SIG
) - available
);
470 if (tvb_memeql(tvb
, offset
, (const uint8_t*)JXTA_UDP_SIG
, sizeof(JXTA_UDP_SIG
)) != 0) {
475 offset
+= (int)sizeof(JXTA_UDP_SIG
);
477 jxta_message_framing_tvb
= tvb_new_subset_remaining(tvb
, offset
);
478 processed
= dissect_jxta_message_framing(jxta_message_framing_tvb
, pinfo
, NULL
, &content_length
, &content_type
);
480 if ((0 == processed
) || (NULL
== content_type
) || (content_length
<= 0) || (content_length
> UINT_MAX
)) {
481 /** Buffer did not begin with valid framing headers */
492 available
= tvb_reported_length_remaining(tvb
, offset
);
493 if (available
< content_length
) {
494 needed
= (int) (content_length
- available
);
498 offset
+= (unsigned) content_length
;
503 if ((needed
> 0) && gDESEGMENT
&& pinfo
->can_desegment
) {
504 /* ws_message( "UDP requesting %d more bytes", needed ); */
505 pinfo
->desegment_offset
= 0;
506 pinfo
->desegment_len
= needed
;
510 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "JXTA");
512 unsigned tree_offset
= 0;
513 proto_item
*jxta_tree_item
=
514 proto_tree_add_protocol_format(tree
, proto_jxta
, tvb
, tree_offset
, -1, "JXTA" );
515 proto_tree
*jxta_tree
= proto_item_add_subtree(jxta_tree_item
, ett_jxta
);
516 proto_item
*jxta_udp_tree_item
=
517 proto_tree_add_none_format(jxta_tree
, hf_jxta_udp
, tvb
, tree_offset
, -1, "JXTA UDP Message");
518 proto_tree
*jxta_udp_tree
= proto_item_add_subtree(jxta_udp_tree_item
, ett_jxta_udp
);
519 tvbuff_t
*jxta_message_framing_tvb
;
520 uint64_t content_length
= -1;
521 char *content_type
= NULL
;
522 tvbuff_t
*jxta_message_tvb
;
524 proto_tree_add_item(jxta_udp_tree
, hf_jxta_udpsig
, tvb
, tree_offset
, (int)sizeof(JXTA_UDP_SIG
), ENC_ASCII
);
525 tree_offset
+= (int)sizeof(JXTA_UDP_SIG
);
527 jxta_message_framing_tvb
= tvb_new_subset_remaining(tvb
, tree_offset
);
529 tree_offset
+= dissect_jxta_message_framing(jxta_message_framing_tvb
, pinfo
, jxta_tree
, &content_length
, &content_type
);
531 jxta_message_tvb
= tvb_new_subset_length(tvb
, tree_offset
, (int) content_length
);
533 tree_offset
+= dissect_media(content_type
, jxta_message_tvb
, pinfo
, tree
);
535 proto_item_set_end(jxta_udp_tree_item
, tvb
, tree_offset
);
537 // offset is based on reported lengths. tree_offset is based on captured lengths via dissect_media.
538 // Comment this out for now in favor of dissect_media's expert warning.
539 // DISSECTOR_ASSERT(tree_offset == offset);
545 * Dissect a tvbuff containing JXTA stream PDUs. This commonly includes
546 * connections over TCP sockets.
548 * <p/>The stream (in both directions) will consist of a JXTA Welcome Message
549 * followed by an indeterminate number of JXTA Message Framing Headers and
552 * @param tvb The buffer to dissect.
553 * @param pinfo Packet Info.
554 * @param tree The protocol tree.
555 * @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
556 * the packet was not recognized as a JXTA packet and negative if the
557 * dissector needs more bytes in order to process a PDU.
559 static int dissect_jxta_stream(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void * data _U_
)
562 unsigned available
= tvb_reported_length_remaining(tvb
, offset
);
565 jxta_stream_conversation_data
*tpt_conv_data
= NULL
;
566 proto_item
*jxta_tree_item
= NULL
;
567 proto_tree
*jxta_tree
= NULL
;
569 /* ws_message("Dissecting%s : %d", (NULL != tree) ? " for display" : "", pinfo->num ); */
571 if (available
< sizeof(JXTA_WELCOME_MSG_SIG
)) {
572 needed
= (int) (sizeof(JXTA_WELCOME_MSG_SIG
) - available
);
576 if (0 == tvb_memeql(tvb
, 0, (const uint8_t*)JXTA_WELCOME_MSG_SIG
, sizeof(JXTA_WELCOME_MSG_SIG
))) {
577 /* The beginning of a JXTA stream connection */
578 address
*welcome_addr
;
579 bool initiator
= false;
581 tpt_conv_data
= get_tpt_conversation(pinfo
);
583 if (0 == tpt_conv_data
->initiator_welcome_frame
) {
584 /* The initiator welcome frame */
585 tpt_conv_data
->tpt_ptype
= pinfo
->ptype
;
586 tpt_conv_data
->initiator_welcome_frame
= pinfo
->num
;
587 copy_address_wmem(wmem_file_scope(), &tpt_conv_data
->initiator_tpt_address
, &pinfo
->src
);
588 tpt_conv_data
->initiator_tpt_port
= pinfo
->srcport
;
590 welcome_addr
= &tpt_conv_data
->initiator_address
;
593 if (tpt_conv_data
->initiator_welcome_frame
>= pinfo
->num
) {
594 /* what we saw previously was the receiver welcome message */
595 tpt_conv_data
->receiver_welcome_frame
= tpt_conv_data
->initiator_welcome_frame
;
596 tpt_conv_data
->receiver_tpt_address
= tpt_conv_data
->initiator_tpt_address
;
597 tpt_conv_data
->receiver_tpt_port
= tpt_conv_data
->initiator_tpt_port
;
598 tpt_conv_data
->receiver_address
= tpt_conv_data
->initiator_address
;
599 tpt_conv_data
->initiator_welcome_frame
= pinfo
->num
;
600 copy_address_wmem(wmem_file_scope(), &tpt_conv_data
->initiator_tpt_address
, &pinfo
->src
);
601 tpt_conv_data
->initiator_tpt_port
= pinfo
->srcport
;
603 welcome_addr
= &tpt_conv_data
->initiator_address
;
606 /* The receiver welcome frame */
607 tpt_conv_data
->tpt_ptype
= pinfo
->ptype
;
608 tpt_conv_data
->receiver_welcome_frame
= pinfo
->num
;
609 copy_address_wmem(wmem_file_scope(), &tpt_conv_data
->receiver_tpt_address
, &pinfo
->src
);
610 tpt_conv_data
->receiver_tpt_port
= pinfo
->srcport
;
612 welcome_addr
= &tpt_conv_data
->receiver_address
;
617 processed
= dissect_jxta_welcome(tvb
, pinfo
, NULL
, welcome_addr
, initiator
);
619 if( processed
< 0 ) {
624 /* redo, this time creating the display tree. */
625 jxta_tree_item
= proto_tree_add_protocol_format(tree
, proto_jxta
, tvb
, offset
, -1, "JXTA" );
626 jxta_tree
= proto_item_add_subtree(jxta_tree_item
, ett_jxta
);
628 processed
= dissect_jxta_welcome(tvb
, pinfo
, jxta_tree
, welcome_addr
, initiator
);
630 /* Somewhere in the middle of a JXTA stream connection */
631 int64_t content_length
= INT64_C(-1);
632 char *content_type
= NULL
;
633 int headers_len
= dissect_jxta_message_framing(tvb
, pinfo
, NULL
, (uint64_t*) &content_length
, &content_type
);
635 if ((0 == headers_len
) || (NULL
== content_type
) || (content_length
<= 0) || (content_length
> UINT_MAX
)) {
636 /** Buffer did not begin with valid framing headers */
640 /* ws_message("%d Tpt %s:%d -> %s:%d tvb len=%d\n\t%s %d", pinfo->num,
641 address_to_str(pinfo->pool, &pinfo->src), pinfo->srcport,
642 address_to_str(pinfo->pool, &pinfo->dst), pinfo->destport,
643 tvb_reported_length_remaining(tvb, 0),
644 content_type ? content_type : "[unknown content type]", (int) content_length); */
646 if (headers_len
< 0) {
647 /* negative headers_len means we need more bytes */
648 needed
= -headers_len
;
652 available
= tvb_reported_length_remaining(tvb
, offset
+ headers_len
);
653 if (available
>= content_length
) {
654 tvbuff_t
*jxta_message_tvb
= tvb_new_subset_length(tvb
, offset
+ headers_len
, (int) content_length
);
655 conversation_t
*peer_conversation
= NULL
;
657 jxta_tree_item
= proto_tree_add_protocol_format(tree
, proto_jxta
, tvb
, offset
, -1, "JXTA" );
658 jxta_tree
= proto_item_add_subtree(jxta_tree_item
, ett_jxta
);
660 /* Redo header processing, this time populating the tree. */
661 headers_len
= dissect_jxta_message_framing(tvb
, pinfo
, jxta_tree
, &content_length
, &content_type
);
663 tpt_conv_data
= get_tpt_conversation(pinfo
);
664 peer_conversation
= get_peer_conversation(pinfo
, tpt_conv_data
, true);
666 /* Use our source and destination addresses if we have them */
667 if (NULL
!= peer_conversation
) {
668 /* ws_message("%d Tpt %s:%d -> %s:%d", pinfo->num,
669 address_to_str(pinfo->pool, &tpt_conv_data->initiator_tpt_address), tpt_conv_data->initiator_tpt_port,
670 address_to_str(pinfo->pool, &tpt_conv_data->receiver_tpt_address), tpt_conv_data->receiver_tpt_port); */
672 if (addresses_equal(&pinfo
->src
, &tpt_conv_data
->initiator_tpt_address
)
673 && tpt_conv_data
->initiator_tpt_port
== pinfo
->srcport
) {
674 /* ws_message("%d From initiator : %s -> %s ", pinfo->num,
675 address_to_str(pinfo->pool, &tpt_conv_data->initiator_address),
676 address_to_str(pinfo->pool, &tpt_conv_data->receiver_address)); */
677 copy_address_shallow(&pinfo
->src
, &tpt_conv_data
->initiator_address
);
679 copy_address_shallow(&pinfo
->dst
, &tpt_conv_data
->receiver_address
);
681 pinfo
->ptype
= PT_NONE
;
682 } else if (addresses_equal(&pinfo
->src
, &tpt_conv_data
->receiver_tpt_address
) &&
683 tpt_conv_data
->receiver_tpt_port
== pinfo
->srcport
) {
684 /* ws_message("%d From receiver : %s -> %s ", pinfo->num,
685 address_to_str(pinfo->pool, &tpt_conv_data->receiver_address),
686 address_to_str(pinfo->pool, &tpt_conv_data->initiator_address)); */
687 copy_address_shallow(&pinfo
->src
, &tpt_conv_data
->receiver_address
);
689 copy_address_shallow(&pinfo
->dst
, &tpt_conv_data
->initiator_address
);
691 pinfo
->ptype
= PT_NONE
;
693 /* ws_message("%d Nothing matches %s:%d -> %s:%d", pinfo->num,
694 address_to_str(pinfo->pool, &pinfo->src), pinfo->srcport,
695 address_to_str(pinfo->pool, &pinfo->dst), pinfo->destport); */
699 processed
= headers_len
;
701 processed
+= dissect_media(content_type
, jxta_message_tvb
, pinfo
, tree
);
703 /* we need more bytes before we can process message body. */
704 needed
= (int) ((unsigned) content_length
- available
);
712 if ((needed
> 0) && gDESEGMENT
&& pinfo
->can_desegment
) {
713 /* ws_message( "Stream requesting %d more bytes", needed ); */
714 pinfo
->desegment_offset
= offset
;
715 pinfo
->desegment_len
= needed
;
723 * Find or possibly create a transport conversation object for the connection
724 * which is associated with the packet info.
726 * @param pinfo The packet info from the underlying transport.
728 static jxta_stream_conversation_data
*get_tpt_conversation(packet_info
* pinfo
)
730 conversation_t
*tpt_conversation
= find_or_create_conversation(pinfo
);
731 jxta_stream_conversation_data
*tpt_conv_data
;
733 conversation_set_dissector(tpt_conversation
, stream_jxta_handle
);
735 tpt_conv_data
= (jxta_stream_conversation_data
*) conversation_get_proto_data(tpt_conversation
, proto_jxta
);
737 if (NULL
== tpt_conv_data
) {
738 tpt_conv_data
= wmem_new(wmem_file_scope(), jxta_stream_conversation_data
);
739 tpt_conv_data
->tpt_ptype
= pinfo
->ptype
;
741 copy_address_wmem(wmem_file_scope(), &tpt_conv_data
->initiator_tpt_address
, &pinfo
->src
);
742 tpt_conv_data
->initiator_tpt_port
= pinfo
->srcport
;
743 tpt_conv_data
->initiator_welcome_frame
= 0;
744 clear_address(&tpt_conv_data
->initiator_address
);
746 copy_address_wmem(wmem_file_scope(), &tpt_conv_data
->receiver_tpt_address
, &pinfo
->dst
);
747 tpt_conv_data
->receiver_tpt_port
= pinfo
->destport
;
748 tpt_conv_data
->receiver_welcome_frame
= 0;
749 clear_address(&tpt_conv_data
->receiver_address
);
751 conversation_add_proto_data(tpt_conversation
, proto_jxta
, tpt_conv_data
);
754 return tpt_conv_data
;
758 * Find or possibly create a peer conversation object for the connection
759 * which is associated with the packet info.
761 * @param tpt_conv_data The transport conversation from which we will locate the peer conversation.
762 * @param create If true then create a new conversation object if necessary.
764 static conversation_t
*get_peer_conversation(packet_info
* pinfo
, jxta_stream_conversation_data
* tpt_conv_data
, bool create
)
766 conversation_t
* peer_conversation
= NULL
;
768 if ((AT_NONE
!= tpt_conv_data
->initiator_address
.type
) && (AT_NONE
!= tpt_conv_data
->receiver_address
.type
)) {
769 peer_conversation
= find_conversation(pinfo
->num
, &tpt_conv_data
->initiator_address
, &tpt_conv_data
->receiver_address
,
770 CONVERSATION_NONE
, 0, 0, NO_PORT_B
);
772 if (create
&& (NULL
== peer_conversation
)) {
773 peer_conversation
= conversation_new(pinfo
->num
, &tpt_conv_data
->initiator_address
,
774 &tpt_conv_data
->receiver_address
, CONVERSATION_NONE
, 0, 0, NO_PORT2
);
775 conversation_set_dissector(peer_conversation
, stream_jxta_handle
);
780 return peer_conversation
;
784 * Dissect a tvbuff containing a JXTA Welcome Message
786 * @param tvb The buffer to dissect.
787 * @param pinfo Packet Info.
788 * @param tree The protocol tree.
789 * @param found_addr The address found in the welcome message.
790 * @param initiator If true then we believe this welcome message to be the initiator's.
791 * @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
792 * the packet was not recognized as a JXTA packet and negative if the
793 * dissector needs more bytes in order to process a PDU.
795 static int dissect_jxta_welcome(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, address
* found_addr
, bool initiator
)
800 unsigned available
= tvb_reported_length_remaining(tvb
, offset
);
801 char **tokens
= NULL
;
803 if (available
< sizeof(JXTA_WELCOME_MSG_SIG
)) {
804 return (int) (available
- sizeof(JXTA_WELCOME_MSG_SIG
));
807 if (0 != tvb_memeql(tvb
, 0, (const uint8_t*)JXTA_WELCOME_MSG_SIG
, sizeof(JXTA_WELCOME_MSG_SIG
))) {
812 first_linelen
= tvb_find_line_end(tvb
, offset
, -1, &afterwelcome
, gDESEGMENT
&& pinfo
->can_desegment
);
814 if (-1 == first_linelen
) {
815 if (available
> 4096) {
816 /* it's too far too be reasonable */
819 /* ask for more bytes */
820 return -DESEGMENT_ONE_MORE_SEGMENT
;
824 /* Dissect the Welcome Message */
826 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "JXTA");
828 col_set_str(pinfo
->cinfo
, COL_INFO
, "Welcome");
831 char *welcomeline
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
, first_linelen
, ENC_ASCII
);
832 char **current_token
;
833 unsigned token_offset
= offset
;
834 proto_item
*jxta_welcome_tree_item
= NULL
;
835 proto_tree
*jxta_welcome_tree
= NULL
;
837 tokens
= wmem_strsplit(pinfo
->pool
, welcomeline
, " ", 255);
838 current_token
= tokens
;
841 jxta_welcome_tree_item
=
842 proto_tree_add_none_format(tree
, hf_jxta_welcome
, tvb
, offset
, afterwelcome
,
843 "JXTA Connection Welcome Message, %s", welcomeline
);
844 jxta_welcome_tree
= proto_item_add_subtree(jxta_welcome_tree_item
, ett_jxta_welcome
);
847 if (jxta_welcome_tree
) {
848 proto_item
*jxta_welcome_initiator_item
=
849 proto_tree_add_boolean(jxta_welcome_tree
, hf_jxta_welcome_initiator
, tvb
, 0, 0, initiator
);
850 proto_item_set_generated(jxta_welcome_initiator_item
);
853 if (NULL
!= *current_token
) {
854 proto_tree_add_item(jxta_welcome_tree
, hf_jxta_welcome_sig
, tvb
, token_offset
, (int) strlen(*current_token
), ENC_ASCII
);
856 token_offset
+= (unsigned) strlen(*current_token
) + 1;
859 /* invalid welcome message */
864 if (NULL
!= *current_token
) {
865 if (jxta_welcome_tree
) {
866 proto_tree_add_item(jxta_welcome_tree
, hf_jxta_welcome_destAddr
, tvb
, token_offset
, (int) strlen(*current_token
),
870 token_offset
+= (unsigned) strlen(*current_token
) + 1;
873 /* invalid welcome message */
878 if (NULL
!= *current_token
) {
879 if (jxta_welcome_tree
) {
880 proto_tree_add_item(jxta_welcome_tree
, hf_jxta_welcome_pubAddr
, tvb
, token_offset
, (int) strlen(*current_token
), ENC_ASCII
);
883 token_offset
+= (unsigned) strlen(*current_token
) + 1;
886 /* invalid welcome message */
891 if (NULL
!= *current_token
) {
892 if (jxta_welcome_tree
) {
893 proto_tree_add_item(jxta_welcome_tree
, hf_jxta_welcome_peerid
, tvb
, token_offset
, (int) strlen(*current_token
), ENC_ASCII
);
896 col_append_str(pinfo
->cinfo
, COL_INFO
, (initiator
? " -> " : " <- ") );
897 col_append_str(pinfo
->cinfo
, COL_INFO
, *current_token
);
899 if (NULL
!= found_addr
) {
900 set_address(found_addr
, uri_address_type
, (int)strlen(*current_token
) + 1, wmem_strdup(wmem_file_scope(), *current_token
));
903 token_offset
+= (unsigned) strlen(*current_token
) + 1;
906 /* invalid welcome message */
911 if (NULL
!= *current_token
) {
912 int variable_tokens
= 0;
913 char **variable_token
= current_token
;
915 while(NULL
!= *variable_token
) {
920 if( variable_tokens
< 1 ) {
921 /* invalid welcome message */
926 if( (2 == variable_tokens
) && (0 == strcmp(JXTA_WELCOME_MSG_VERSION_1_1
, current_token
[variable_tokens
-1])) ) {
927 if (jxta_welcome_tree
) {
928 proto_tree_add_item(jxta_welcome_tree
, hf_jxta_welcome_noProp
, tvb
, token_offset
, (int) strlen(*current_token
), ENC_ASCII
);
931 token_offset
+= (unsigned) strlen(*current_token
) + 1;
934 if (jxta_welcome_tree
) {
935 proto_tree_add_item(jxta_welcome_tree
, hf_jxta_welcome_version
, tvb
, token_offset
, (int) strlen(*current_token
), ENC_ASCII
);
937 } else if( (3 == variable_tokens
) && (0 == strcmp(JXTA_WELCOME_MSG_VERSION_3_0
, current_token
[variable_tokens
-1])) ) {
938 if (jxta_welcome_tree
) {
939 proto_tree_add_item(jxta_welcome_tree
, hf_jxta_welcome_noProp
, tvb
, token_offset
, (int) strlen(*current_token
), ENC_ASCII
);
942 token_offset
+= (unsigned) strlen(*current_token
) + 1;
945 if (jxta_welcome_tree
) {
946 proto_tree_add_item(jxta_welcome_tree
, hf_jxta_welcome_msgVers
, tvb
, token_offset
, (int) strlen(*current_token
), ENC_ASCII
);
949 token_offset
+= (unsigned) strlen(*current_token
) + 1;
952 if (jxta_welcome_tree
) {
953 proto_tree_add_item(jxta_welcome_tree
, hf_jxta_welcome_version
, tvb
, token_offset
, (int) strlen(*current_token
), ENC_ASCII
);
956 /* Unrecognized Welcome Version */
957 int each_variable_token
;
959 for( each_variable_token
= 0; each_variable_token
< variable_tokens
; each_variable_token
++ ) {
960 if (jxta_welcome_tree
) {
961 jxta_welcome_tree_item
= proto_tree_add_item(jxta_welcome_tree
,
962 (each_variable_token
< (variable_tokens
-1) ? hf_jxta_welcome_variable
: hf_jxta_welcome_version
),
963 tvb
, token_offset
, (int) strlen(*current_token
), ENC_ASCII
|ENC_NA
);
965 proto_item_append_text(jxta_welcome_tree_item
, " (UNRECOGNIZED)");
968 token_offset
+= (unsigned) strlen(*current_token
) + 1;
973 /* invalid welcome message */
980 col_set_writable(pinfo
->cinfo
, -1, false);
986 * Dissect a tvbuff containing JXTA Message framing.
988 * @param tvb The buffer to dissect.
989 * @param pinfo Packet Info.
990 * @param tree The protocol tree.
991 * @param content_length Pointer to a buffer for storing the value of the
992 * "content-length" header or NULL.
993 * @param content_type Pointer-to-a-pointer for a new buffer for storing the
994 * value of the "content_type-length" header or NULL.
995 * @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
996 * the packet was not recognized as a JXTA packet and negative if the
997 * dissector needs more bytes in order to process a PDU.
999 static int dissect_jxta_message_framing(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, uint64_t * content_length
,
1000 char ** content_type
)
1002 unsigned offset
= 0;
1007 * First go around. Make sure all of the bytes are there.
1010 uint8_t headername_len
;
1011 uint8_t headername_offset
;
1012 uint16_t headervalue_len
;
1013 uint16_t headervalue_offset
;
1015 available
= tvb_reported_length_remaining(tvb
, offset
);
1016 if (available
< 1) {
1020 headername_len
= tvb_get_uint8(tvb
, offset
);
1022 headername_offset
= offset
;
1024 available
= tvb_reported_length_remaining(tvb
, offset
);
1025 if (available
< headername_len
) {
1026 needed
= (int) (headername_len
- available
);
1030 if (0 == headername_len
) {
1033 offset
+= headername_len
;
1036 available
= tvb_reported_length_remaining(tvb
, offset
);
1037 if (available
< 2) {
1038 needed
= (int) (2 - available
);
1041 headervalue_len
= tvb_get_ntohs(tvb
, offset
);
1043 headervalue_offset
= offset
;
1045 available
= tvb_reported_length_remaining(tvb
, offset
);
1046 if (available
< headervalue_len
) {
1047 needed
= (int) (headervalue_len
- available
);
1051 offset
+= headervalue_len
;
1054 if (content_type
&& (sizeof("content-type") - 1) == headername_len
) {
1055 if (0 == tvb_strncaseeql(tvb
, headername_offset
, "content-type", sizeof("content-type") - 1)) {
1056 *content_type
= tvb_get_string_enc(pinfo
->pool
, tvb
, headervalue_offset
, headervalue_len
, ENC_ASCII
);
1061 if (content_length
&& (sizeof(uint64_t) == headervalue_len
) && ((sizeof("content-length") - 1) == headername_len
)) {
1062 if (0 == tvb_strncaseeql(tvb
, headername_offset
, "content-length", sizeof("content-length") - 1)) {
1063 *content_length
= tvb_get_ntoh64(tvb
, headervalue_offset
);
1068 if ((needed
> 0) && gDESEGMENT
&& pinfo
->can_desegment
) {
1069 /* ws_message( "Framing requesting %d more bytes", needed ); */
1070 pinfo
->desegment_offset
= 0;
1071 pinfo
->desegment_len
= needed
;
1076 * Second (optional pass) Now that we are sure that all the bytes are there we update the protocol tree.
1079 unsigned tree_offset
= 0;
1080 proto_item
*framing_tree_item
;
1081 proto_tree
*framing_tree
;
1084 proto_tree_add_none_format(tree
, hf_jxta_framing
, tvb
, tree_offset
, -1, "JXTA Message Framing Headers");
1085 framing_tree
= proto_item_add_subtree(framing_tree_item
, ett_jxta_framing
);
1087 /* parse framing headers */
1089 uint8_t headernamelen
= tvb_get_uint8(tvb
, tree_offset
);
1090 proto_item
*framing_header_tree_item
=
1091 proto_tree_add_item(framing_tree
, hf_jxta_framing_header
, tvb
, tree_offset
, -1, ENC_NA
);
1092 proto_tree
*framing_header_tree
= proto_item_add_subtree(framing_header_tree_item
, ett_jxta_framing_header
);
1095 * Put header name into the protocol tree
1097 proto_tree_add_item(framing_header_tree
, hf_jxta_framing_header_name
, tvb
, tree_offset
, (int)sizeof(int8_t), ENC_ASCII
|ENC_BIG_ENDIAN
);
1100 * Append header name into the header protocol item. It's a nice hint so you don't have to reveal all headers.
1102 if (headernamelen
> 0) {
1103 proto_item_append_text(framing_header_tree_item
, " \"%s\"",
1104 tvb_format_text(pinfo
->pool
, tvb
, tree_offset
+ 1, headernamelen
));
1107 tree_offset
+= 1 + headernamelen
;
1109 if (headernamelen
> 0) {
1110 uint16_t headervaluelen
= tvb_get_ntohs(tvb
, tree_offset
);
1113 proto_tree_add_uint(framing_header_tree
, hf_jxta_framing_header_value_length
, tvb
, tree_offset
,
1116 /** TODO bondolo Add specific handling for known header types */
1119 * Put header value into protocol tree.
1121 proto_tree_add_item(framing_header_tree
, hf_jxta_framing_header_value
, tvb
, tree_offset
+ 2,
1122 headervaluelen
, ENC_NA
);
1125 tree_offset
+= 2 + headervaluelen
;
1128 proto_item_set_end(framing_header_tree_item
, tvb
, tree_offset
);
1130 if (0 == headernamelen
) {
1135 proto_item_set_end(framing_tree_item
, tvb
, tree_offset
);
1137 DISSECTOR_ASSERT(offset
== tree_offset
);
1140 /* return how many bytes we used up. */
1145 * Dissect a tvbuff containing one or more JXTA Messages.
1147 * @param tvb The buffer to dissect.
1148 * @param pinfo Packet Info.
1149 * @param tree The protocol tree.
1150 * @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
1151 * the packet was not recognized as a JXTA packet and negative if the
1152 * dissector needs more bytes in order to process a PDU.
1154 static int dissect_jxta_message(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void * data _U_
)
1156 int complete_messages
= 0;
1157 unsigned offset
= 0;
1158 unsigned tree_offset
= 0;
1161 wmem_strbuf_t
* src_addr
;
1162 wmem_strbuf_t
* dst_addr
;
1165 uint8_t message_version
;
1166 unsigned message_start_offset
= offset
;
1168 /* First pass. Make sure all of the bytes we need are available */
1169 available
= tvb_reported_length_remaining(tvb
, offset
);
1171 if((0 == available
) && (0 != complete_messages
)) {
1172 /* We have discovered all of the complete messages in the tvbuff. */
1176 if (available
< sizeof(JXTA_MSG_SIG
)) {
1177 needed
= (int) (sizeof(JXTA_MSG_SIG
) - available
);
1181 if (tvb_memeql(tvb
, offset
, (const uint8_t*)JXTA_MSG_SIG
, sizeof(JXTA_MSG_SIG
)) != 0) {
1182 /* It is not one of ours */
1186 offset
+= (int)sizeof(JXTA_MSG_SIG
);
1188 available
= tvb_reported_length_remaining(tvb
, offset
);
1189 if (available
< 1) {
1193 message_version
= tvb_get_uint8(tvb
, offset
);
1197 if ((JXTA_MSG_VERSION_1
!= message_version
) && (JXTA_MSG_VERSION_2
!= message_version
)) {
1198 /* Sort of a lie, we say that we don't recognize it at all. */
1203 /* Read the flags (Version 2 and later) */
1204 if(message_version
> 0) {
1205 available
= tvb_reported_length_remaining(tvb
, offset
);
1206 if (available
< 1) {
1214 /* Read names table */
1215 available
= tvb_reported_length_remaining(tvb
, offset
);
1216 if (available
< 2) {
1217 needed
= (int) (2 - available
);
1220 uint16_t msg_names_count
= tvb_get_ntohs(tvb
, offset
);
1225 for (each_name
= 0; each_name
< msg_names_count
; each_name
++) {
1228 available
= tvb_reported_length_remaining(tvb
, offset
);
1229 if (available
< sizeof(name_len
)) {
1230 needed
= (int) (sizeof(name_len
) - available
);
1234 name_len
= tvb_get_ntohs(tvb
, offset
);
1236 available
= tvb_reported_length_remaining(tvb
, offset
+ (int)sizeof(name_len
));
1237 if (available
< name_len
) {
1238 needed
= (int) (name_len
- available
);
1242 offset
+= (int)sizeof(name_len
) + name_len
;
1246 /* parse element count */
1247 available
= tvb_reported_length_remaining(tvb
, offset
);
1248 if (available
< 2) {
1249 needed
= (int) (2 - available
);
1252 uint16_t elem_count
= tvb_get_ntohs(tvb
, offset
);
1257 /* parse elements */
1258 for (each_elem
= 0; each_elem
< elem_count
; each_elem
++) {
1259 tvbuff_t
*jxta_message_element_tvb
= tvb_new_subset_remaining(tvb
, offset
);
1262 if (JXTA_MSG_VERSION_1
== message_version
) {
1263 processed
= dissect_jxta_message_element_1(jxta_message_element_tvb
, pinfo
, NULL
, 0, NULL
);
1264 } else { /* JXTA_MSG_VERSION_2 */
1265 processed
= dissect_jxta_message_element_2(jxta_message_element_tvb
, pinfo
, NULL
, 0, NULL
);
1268 if (processed
< 0) {
1269 needed
= -processed
;
1273 if (0 == processed
) {
1274 /* XXX bondolo Not really clear what we should do! */
1275 /* eapache: based on reading the code, I believe this can occur
1276 * when the message_version is valid but the JXTA_MSGELEM_SIG
1277 * (some sort of magic number?) is not. This almost
1278 * certainly indicates a corrupt packet, so this should
1279 * probably be expert info, not a ws_warning. Pending confirmation
1280 * just comment it out since a ws_warning is definitely the
1281 * wrong thing to do.
1282 * ws_warning( "Failure processing message element #%d of %d of frame %d", each_elem, elem_count, pinfo->num );
1287 offset
+= processed
;
1291 if ((uri_address_type
== pinfo
->src
.type
) && (uri_address_type
== pinfo
->dst
.type
)) {
1292 jxta_tap_header
*tap_header
= wmem_new(wmem_file_scope(), jxta_tap_header
);
1294 copy_address_shallow(&tap_header
->src_address
, &pinfo
->src
);
1295 copy_address_shallow(&tap_header
->dest_address
, &pinfo
->dst
);
1296 tap_header
->size
= offset
- message_start_offset
;
1298 tap_queue_packet(jxta_tap
, pinfo
, tap_header
);
1301 complete_messages
++;
1303 /* ws_message( "%d Scanned message #%d: ", pinfo->num, complete_messages ); */
1306 if ((needed
> 0) && gDESEGMENT
&& pinfo
->can_desegment
) {
1307 /* ws_message("Frame %d: Message requesting %d more bytes", pinfo->num, needed); */
1308 pinfo
->desegment_offset
= 0;
1309 pinfo
->desegment_len
= needed
;
1313 src_addr
= wmem_strbuf_create(pinfo
->pool
);
1314 wmem_strbuf_append(src_addr
, address_to_str(pinfo
->pool
, &pinfo
->src
));
1315 dst_addr
= wmem_strbuf_create(pinfo
->pool
);
1316 wmem_strbuf_append(dst_addr
, address_to_str(pinfo
->pool
, &pinfo
->dst
));
1318 /* append the port if appropriate */
1319 if (PT_NONE
!= pinfo
->ptype
) {
1320 wmem_strbuf_append_printf(src_addr
, ":%d", pinfo
->srcport
);
1321 wmem_strbuf_append_printf(dst_addr
, ":%d", pinfo
->destport
);
1324 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "JXTA");
1326 if( complete_messages
> 1 ) {
1327 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%d Messages, %s -> %s", complete_messages
,
1328 wmem_strbuf_get_str(src_addr
), wmem_strbuf_get_str(dst_addr
));
1330 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Message, %s -> %s",
1331 wmem_strbuf_get_str(src_addr
), wmem_strbuf_get_str(dst_addr
));
1334 col_set_writable(pinfo
->cinfo
, -1, false);
1336 while( tree
&& (complete_messages
> 0) ) {
1337 proto_item
*jxta_msg_tree_item
= NULL
;
1338 proto_tree
*jxta_msg_tree
= NULL
;
1339 uint8_t message_version
;
1340 const char **names_table
= NULL
;
1341 uint16_t msg_names_count
;
1343 uint16_t elem_count
;
1345 proto_item
*tree_item
;
1347 jxta_msg_tree_item
= proto_tree_add_protocol_format(tree
, proto_message_jxta
, tvb
, tree_offset
, -1,
1348 "JXTA Message, %s -> %s", wmem_strbuf_get_str(src_addr
),
1349 wmem_strbuf_get_str(dst_addr
));
1351 jxta_msg_tree
= proto_item_add_subtree(jxta_msg_tree_item
, ett_jxta_msg
);
1353 proto_tree_add_item(jxta_msg_tree
, hf_jxta_message_sig
, tvb
, tree_offset
, (int)sizeof(JXTA_MSG_SIG
), ENC_ASCII
);
1354 tree_offset
+= (int)sizeof(JXTA_MSG_SIG
);
1356 tree_item
= proto_tree_add_string(jxta_msg_tree
, hf_jxta_message_src
, tvb
, 0, 0, wmem_strbuf_get_str(src_addr
));
1357 proto_item_set_generated(tree_item
);
1359 tree_item
= proto_tree_add_string(jxta_msg_tree
, hf_jxta_message_address
, tvb
, 0, 0, wmem_strbuf_get_str(src_addr
));
1360 proto_item_set_hidden(tree_item
);
1361 proto_item_set_generated(tree_item
);
1363 if(uri_address_type
== pinfo
->src
.type
) {
1364 tree_item
= proto_tree_add_string(jxta_msg_tree
, hf_uri_src
, tvb
, 0, 0, wmem_strbuf_get_str(src_addr
));
1365 proto_item_set_hidden(tree_item
);
1366 proto_item_set_generated(tree_item
);
1367 tree_item
= proto_tree_add_string(jxta_msg_tree
, hf_uri_addr
, tvb
, 0, 0, wmem_strbuf_get_str(src_addr
));
1368 proto_item_set_hidden(tree_item
);
1369 proto_item_set_generated(tree_item
);
1372 tree_item
= proto_tree_add_string(jxta_msg_tree
, hf_jxta_message_dst
, tvb
, 0, 0, wmem_strbuf_get_str(dst_addr
));
1373 proto_item_set_generated(tree_item
);
1375 tree_item
= proto_tree_add_string(jxta_msg_tree
, hf_jxta_message_address
, tvb
, 0, 0, wmem_strbuf_get_str(dst_addr
));
1376 proto_item_set_hidden(tree_item
);
1377 proto_item_set_generated(tree_item
);
1379 if(uri_address_type
== pinfo
->dst
.type
) {
1380 tree_item
= proto_tree_add_string(jxta_msg_tree
, hf_uri_dst
, tvb
, 0, 0, wmem_strbuf_get_str(dst_addr
));
1381 proto_item_set_hidden(tree_item
);
1382 proto_item_set_generated(tree_item
);
1383 tree_item
= proto_tree_add_string(jxta_msg_tree
, hf_uri_addr
, tvb
, 0, 0, wmem_strbuf_get_str(dst_addr
));
1384 proto_item_set_hidden(tree_item
);
1385 proto_item_set_generated(tree_item
);
1388 message_version
= tvb_get_uint8(tvb
, tree_offset
);
1389 proto_tree_add_uint(jxta_msg_tree
, hf_jxta_message_version
, tvb
, tree_offset
, 1, message_version
);
1392 if( message_version
> 0 ) {
1393 static int * const flags
[] = {
1394 &hf_jxta_message_flag_utf16be
,
1395 &hf_jxta_message_flag_ucs32be
,
1399 proto_tree_add_bitmask(jxta_msg_tree
, tvb
, tree_offset
, hf_jxta_message_flags
, ett_jxta_msg_flags
, flags
, ENC_NA
);
1403 msg_names_count
= tvb_get_ntohs(tvb
, tree_offset
);
1404 proto_tree_add_uint(jxta_msg_tree
, hf_jxta_message_names_count
, tvb
, tree_offset
, 2, msg_names_count
);
1407 names_table
= (const char **)wmem_alloc(pinfo
->pool
, (msg_names_count
+ 2) * sizeof(const char *));
1408 names_table
[0] = "";
1409 names_table
[1] = "jxta";
1412 for (each_name
= 0; each_name
< msg_names_count
; each_name
++) {
1413 uint16_t name_len
= tvb_get_ntohs(tvb
, tree_offset
);
1415 names_table
[2 + each_name
] = tvb_get_string_enc(pinfo
->pool
, tvb
, tree_offset
+ 2, name_len
, ENC_ASCII
);
1416 proto_tree_add_item(jxta_msg_tree
, hf_jxta_message_names_name
, tvb
, tree_offset
, 2, ENC_ASCII
|ENC_BIG_ENDIAN
);
1417 tree_offset
+= 2 + name_len
;
1420 /* parse element count */
1421 elem_count
= tvb_get_ntohs(tvb
, tree_offset
);
1422 proto_tree_add_item(jxta_msg_tree
, hf_jxta_message_element_count
, tvb
, tree_offset
, 2, ENC_BIG_ENDIAN
);
1425 /* FIXME bondolo Element count 0 (Process elements until FIN) should be supported. */
1427 /* parse elements */
1428 for (each_elem
= 0; each_elem
< elem_count
; each_elem
++) {
1429 tvbuff_t
*jxta_message_element_tvb
= tvb_new_subset_remaining(tvb
, tree_offset
);
1431 if(JXTA_MSG_VERSION_1
== message_version
) {
1433 dissect_jxta_message_element_1(jxta_message_element_tvb
, pinfo
, jxta_msg_tree
, msg_names_count
+ 2, names_table
);
1434 } else if(JXTA_MSG_VERSION_2
== message_version
) {
1436 dissect_jxta_message_element_2(jxta_message_element_tvb
, pinfo
, jxta_msg_tree
, msg_names_count
+ 2, names_table
);
1438 /* Sort of a lie, we say that we don't recognize it at all. */
1443 proto_item_set_end(jxta_msg_tree_item
, tvb
, tree_offset
);
1445 complete_messages
--;
1449 /* ws_message( "%d tvb offset : %d tree offset : %d", pinfo->num, offset, tree_offset ); */
1450 DISSECTOR_ASSERT(tree_offset
== offset
);
1457 * Dissect a tvbuff containing a JXTA Message Element (Version 1).
1459 * @param tvb The buffer to dissect.
1460 * @param pinfo Packet Info.
1461 * @param tree The protocol tree.
1462 * @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
1463 * the packet was not recognized as a JXTA packet and negative if the
1464 * dissector needs more bytes in order to process a PDU.
1466 // NOLINTNEXTLINE(misc-no-recursion)
1467 static int dissect_jxta_message_element_1(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, unsigned ns_count
,
1468 const char ** names_table
)
1470 unsigned offset
= 0;
1475 /* First pass. Make sure all of the bytes we need are available */
1478 /* signature field */
1479 available
= tvb_reported_length_remaining(tvb
, offset
);
1480 if (available
< sizeof(JXTA_MSGELEM_SIG
)) {
1481 needed
= (int) (sizeof(JXTA_MSGELEM_SIG
) - available
);
1484 if (tvb_memeql(tvb
, offset
, (const uint8_t*)JXTA_MSGELEM_SIG
, sizeof(JXTA_MSGELEM_SIG
)) != 0) {
1485 /* It is not one of ours */
1489 offset
+= (int)sizeof(JXTA_MSGELEM_SIG
);
1491 /* namespace id field */
1492 available
= tvb_reported_length_remaining(tvb
, offset
);
1493 if (available
< 1) {
1501 available
= tvb_reported_length_remaining(tvb
, offset
);
1502 if (available
< 1) {
1506 flags
= tvb_get_uint8(tvb
, offset
);
1511 available
= tvb_reported_length_remaining(tvb
, offset
);
1512 if (available
< 2) {
1513 needed
= (int) (2 - available
);
1516 uint16_t name_len
= tvb_get_ntohs(tvb
, offset
);
1519 available
= tvb_reported_length_remaining(tvb
, offset
);
1520 if (available
< name_len
) {
1521 needed
= (int) (name_len
- available
);
1529 if ((flags
& JXTAMSG1_ELMFLAG_TYPE
) != 0) {
1532 available
= tvb_reported_length_remaining(tvb
, offset
);
1533 if (available
< 2) {
1534 needed
= (int) (2 - available
);
1538 type_len
= tvb_get_ntohs(tvb
, offset
);
1541 available
= tvb_reported_length_remaining(tvb
, offset
);
1542 if (available
< type_len
) {
1543 needed
= (int) (type_len
- available
);
1550 /* encoding field */
1551 if ((flags
& JXTAMSG1_ELMFLAG_ENCODING
) != 0) {
1552 uint16_t encoding_len
;
1554 available
= tvb_reported_length_remaining(tvb
, offset
);
1555 if (available
< 2) {
1556 needed
= (int) (2 - available
);
1560 encoding_len
= tvb_get_ntohs(tvb
, offset
);
1563 available
= tvb_reported_length_remaining(tvb
, offset
);
1564 if (available
< encoding_len
) {
1565 needed
= (int) (encoding_len
- available
);
1569 offset
+= encoding_len
;
1573 available
= tvb_reported_length_remaining(tvb
, offset
);
1574 if (available
< 2) {
1575 needed
= (int) (2 - available
);
1578 uint32_t content_len
= tvb_get_ntohl(tvb
, offset
);
1581 available
= tvb_reported_length_remaining(tvb
, offset
);
1582 if (available
< content_len
) {
1583 needed
= (int) (content_len
- available
);
1587 offset
+= content_len
;
1590 /* signature element field */
1591 if ((flags
& JXTAMSG1_ELMFLAG_SIGNATURE
) != 0) {
1592 tvbuff_t
*jxta_signature_element_tvb
;
1595 jxta_signature_element_tvb
= tvb_new_subset_remaining(tvb
, offset
);
1597 increment_dissection_depth(pinfo
);
1598 processed
= dissect_jxta_message_element_1(jxta_signature_element_tvb
, pinfo
, NULL
, 0, NULL
);
1599 decrement_dissection_depth(pinfo
);
1601 if (processed
== 0) {
1605 if (processed
< 0) {
1606 needed
= -processed
;
1610 offset
+= processed
;
1616 if ((needed
> 0) && gDESEGMENT
&& pinfo
->can_desegment
) {
1617 /* ws_message( "Element1 requesting %d more bytes", needed ); */
1618 pinfo
->desegment_offset
= 0;
1619 pinfo
->desegment_len
= needed
;
1623 /* Second pass : build the proto tree */
1624 unsigned tree_offset
= 0;
1625 proto_item
*jxta_elem_tree_item
= proto_tree_add_item(tree
, hf_jxta_element
, tvb
, tree_offset
, -1, ENC_NA
);
1626 proto_tree
*jxta_elem_tree
= proto_item_add_subtree(jxta_elem_tree_item
, ett_jxta_elem
);
1627 uint8_t namespaceID
;
1628 proto_item
*namespace_ti
;
1630 uint32_t content_len
;
1631 char *mediatype
= NULL
;
1632 tvbuff_t
*element_content_tvb
;
1633 static int * const element_flags
[] = {
1634 &hf_jxta_element1_flag_hasType
,
1635 &hf_jxta_element1_flag_hasEncoding
,
1636 &hf_jxta_element1_flag_hasSignature
,
1640 proto_tree_add_item(jxta_elem_tree
, hf_jxta_element_sig
, tvb
, tree_offset
, (int)sizeof(JXTA_MSGELEM_SIG
), ENC_ASCII
);
1641 tree_offset
+= (int)sizeof(JXTA_MSGELEM_SIG
);
1643 namespaceID
= tvb_get_uint8(tvb
, tree_offset
);
1645 proto_tree_add_uint(jxta_elem_tree
, hf_jxta_element1_namespaceid
, tvb
, tree_offset
, 1, namespaceID
);
1646 if (namespaceID
< ns_count
) {
1647 proto_item_append_text(namespace_ti
, " (%s)", names_table
[namespaceID
]);
1649 proto_item_append_text(namespace_ti
, " * BAD *");
1653 flags
= tvb_get_uint8(tvb
, tree_offset
);
1654 proto_tree_add_bitmask(jxta_elem_tree
, tvb
, tree_offset
, hf_jxta_element_flags
, ett_jxta_elem_1_flags
, element_flags
, ENC_NA
);
1657 name_len
= tvb_get_ntohs(tvb
, tree_offset
);
1658 proto_item_append_text(jxta_elem_tree_item
, " \"%s\"", tvb_format_text(pinfo
->pool
, tvb
, tree_offset
+ 2, name_len
));
1659 proto_tree_add_item(jxta_elem_tree
, hf_jxta_element_name
, tvb
, tree_offset
, 2, ENC_ASCII
|ENC_BIG_ENDIAN
);
1660 tree_offset
+= 2 + name_len
;
1663 if ((flags
& JXTAMSG1_ELMFLAG_TYPE
) != 0) {
1664 uint16_t type_len
= tvb_get_ntohs(tvb
, tree_offset
);
1665 proto_tree_add_item(jxta_elem_tree
, hf_jxta_element_type
, tvb
, tree_offset
, 2, ENC_ASCII
|ENC_BIG_ENDIAN
);
1668 mediatype
= tvb_get_string_enc(pinfo
->pool
, tvb
, tree_offset
, type_len
, ENC_ASCII
);
1670 tree_offset
+= type_len
;
1673 /* process encoding */
1674 if ((flags
& JXTAMSG1_ELMFLAG_ENCODING
) != 0) {
1675 uint16_t encoding_len
= tvb_get_ntohs(tvb
, tree_offset
);
1676 proto_tree_add_item(jxta_elem_tree
, hf_jxta_element_encoding
, tvb
, tree_offset
, 2, ENC_ASCII
|ENC_BIG_ENDIAN
);
1677 tree_offset
+= 2 + encoding_len
;
1681 content_len
= tvb_get_ntohl(tvb
, tree_offset
);
1682 proto_tree_add_item(jxta_elem_tree
, hf_jxta_element_content_len
, tvb
, tree_offset
, 4, ENC_BIG_ENDIAN
);
1685 element_content_tvb
= tvb_new_subset_length(tvb
, tree_offset
, content_len
);
1687 tree_offset
+= dissect_media(mediatype
, element_content_tvb
, pinfo
, jxta_elem_tree
);
1689 /* process the signature element */
1690 if ((flags
& JXTAMSG1_ELMFLAG_SIGNATURE
) != 0) {
1691 tvbuff_t
*jxta_message_element_tvb
= tvb_new_subset_remaining(tvb
, tree_offset
);
1693 increment_dissection_depth(pinfo
);
1694 tree_offset
+= dissect_jxta_message_element_1(jxta_message_element_tvb
, pinfo
, jxta_elem_tree
, ns_count
, names_table
);
1695 decrement_dissection_depth(pinfo
);
1698 proto_item_set_end(jxta_elem_tree_item
, tvb
, tree_offset
);
1700 // offset is based on reported lengths. tree_offset is based on captured lengths via dissect_media.
1701 // Comment this out for now in favor of dissect_media's expert warning.
1702 // DISSECTOR_ASSERT(tree_offset == offset);
1708 * Dissect a tvbuff containing a JXTA Message Element (Version 2).
1710 * @param tvb The buffer to dissect.
1711 * @param pinfo Packet Info.
1712 * @param tree The protocol tree.
1713 * @param names_count The number of elements in the names table.
1714 * @param names_table The table of names.
1715 * @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
1716 * the packet was not recognized as a JXTA packet and negative if the
1717 * dissector needs more bytes in order to process a PDU.
1719 // NOLINTNEXTLINE(misc-no-recursion)
1720 static int dissect_jxta_message_element_2(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, unsigned names_count
,
1721 const char ** names_table
)
1723 unsigned offset
= 0;
1728 /* First pass. Make sure all of the bytes we need are available */
1731 /* signature field */
1732 available
= tvb_reported_length_remaining(tvb
, offset
);
1733 if (available
< sizeof(JXTA_MSGELEM_SIG
)) {
1734 needed
= (int) (sizeof(JXTA_MSGELEM_SIG
) - available
);
1737 if (tvb_memeql(tvb
, offset
, (const uint8_t*)JXTA_MSGELEM_SIG
, sizeof(JXTA_MSGELEM_SIG
)) != 0) {
1738 /* It is not one of ours */
1742 offset
+= (int)sizeof(JXTA_MSGELEM_SIG
);
1745 available
= tvb_reported_length_remaining(tvb
, offset
);
1746 if (available
< 1) {
1750 flags
= tvb_get_uint8(tvb
, offset
);
1754 /* namespace id field */
1755 available
= tvb_reported_length_remaining(tvb
, offset
);
1756 if (available
< 2) {
1757 needed
= (int) (2 - available
);
1764 if ((flags
& JXTAMSG2_ELMFLAG_NAME_LITERAL
) == 0) {
1765 available
= tvb_reported_length_remaining(tvb
, offset
);
1766 if (available
< 2) {
1767 needed
= (int) (2 - available
);
1773 /* literal name field */
1774 available
= tvb_reported_length_remaining(tvb
, offset
);
1775 if (available
< 2) {
1776 needed
= (int) (2 - available
);
1779 uint16_t name_len
= tvb_get_ntohs(tvb
, offset
);
1782 available
= tvb_reported_length_remaining(tvb
, offset
);
1783 if (available
< name_len
) {
1784 needed
= (int) (name_len
- available
);
1793 if ((flags
& JXTAMSG2_ELMFLAG_TYPE
) != 0) {
1794 available
= tvb_reported_length_remaining(tvb
, offset
);
1795 if (available
< 2) {
1796 needed
= (int) (2 - available
);
1803 /* encoding field */
1804 if ((flags
& JXTAMSG2_ELMFLAG_ENCODINGS
) != 0) {
1805 available
= tvb_reported_length_remaining(tvb
, offset
);
1806 if (available
< 2) {
1807 needed
= (int) (2 - available
);
1816 if ((flags
& JXTAMSG2_ELMFLAG_UINT64_LENS
) != 0) {
1817 available
= tvb_reported_length_remaining(tvb
, offset
);
1818 if (available
< sizeof(uint64_t)) {
1819 needed
= (int) (sizeof(uint64_t) - available
);
1822 uint64_t content_len
= tvb_get_ntoh64(tvb
, offset
);
1823 offset
+= (int)sizeof(uint64_t);
1825 available
= tvb_reported_length_remaining(tvb
, offset
);
1826 if (available
< content_len
) {
1827 needed
= (int) (content_len
- available
);
1831 offset
+= (unsigned) content_len
;
1834 available
= tvb_reported_length_remaining(tvb
, offset
);
1835 if (available
< 4) {
1836 needed
= (int) (4 - available
);
1839 uint64_t content_len
= tvb_get_ntohl(tvb
, offset
);
1842 available
= tvb_reported_length_remaining(tvb
, offset
);
1843 if (available
< content_len
) {
1844 needed
= (int) (content_len
- available
);
1848 offset
+= (unsigned) content_len
;
1852 /* signature element field */
1853 if ((flags
& JXTAMSG2_ELMFLAG_SIGNATURE
) != 0) {
1854 tvbuff_t
*jxta_signature_element_tvb
;
1857 jxta_signature_element_tvb
= tvb_new_subset_remaining(tvb
, offset
);
1859 increment_dissection_depth(pinfo
);
1860 processed
= dissect_jxta_message_element_2(jxta_signature_element_tvb
, pinfo
, NULL
, 0, NULL
);
1861 decrement_dissection_depth(pinfo
);
1863 if (processed
== 0) {
1867 if (processed
< 0) {
1868 needed
= -processed
;
1872 offset
+= processed
;
1878 if ((needed
> 0) && gDESEGMENT
&& pinfo
->can_desegment
) {
1879 /* ws_message( "Element2 requesting %d more bytes", needed ); */
1880 pinfo
->desegment_offset
= 0;
1881 pinfo
->desegment_len
= needed
;
1885 /* Second (optional) pass : build the proto tree */
1886 unsigned tree_offset
= 0;
1887 proto_item
*jxta_elem_tree_item
= proto_tree_add_item(tree
, hf_jxta_element
, tvb
, tree_offset
, -1, ENC_NA
);
1888 proto_tree
*jxta_elem_tree
= proto_item_add_subtree(jxta_elem_tree_item
, ett_jxta_elem
);
1889 uint16_t namespaceID
;
1890 proto_item
*namespace_ti
;
1892 proto_item
*name_ti
;
1893 uint64_t content_len
;
1894 const char *mediatype
= NULL
;
1895 tvbuff_t
*element_content_tvb
;
1896 static int * const element_flags
[] = {
1897 &hf_jxta_element2_flag_64bitlens
,
1898 &hf_jxta_element2_flag_nameLiteral
,
1899 &hf_jxta_element2_flag_hasType
,
1900 &hf_jxta_element2_flag_hasSignature
,
1901 &hf_jxta_element2_flag_hasEncoding
,
1902 &hf_jxta_element2_flag_sigOfEncoded
,
1906 proto_tree_add_item(jxta_elem_tree
, hf_jxta_element_sig
, tvb
, tree_offset
, (int)sizeof(JXTA_MSGELEM_SIG
), ENC_ASCII
);
1907 tree_offset
+= (int)sizeof(JXTA_MSGELEM_SIG
);
1909 flags
= tvb_get_uint8(tvb
, tree_offset
);
1910 proto_tree_add_bitmask(jxta_elem_tree
, tvb
, tree_offset
, hf_jxta_element_flags
, ett_jxta_elem_2_flags
, element_flags
, ENC_NA
);
1914 namespaceID
= tvb_get_ntohs(tvb
, tree_offset
);
1916 proto_tree_add_uint(jxta_elem_tree
, hf_jxta_element2_namespaceid
, tvb
, tree_offset
, 2, namespaceID
);
1917 if (namespaceID
< names_count
) {
1918 proto_item_append_text(namespace_ti
, " (%s)", names_table
[namespaceID
]);
1920 proto_item_append_text(namespace_ti
, " * BAD *");
1925 if ((flags
& JXTAMSG2_ELMFLAG_NAME_LITERAL
) == 0) {
1926 nameID
= tvb_get_ntohs(tvb
, tree_offset
);
1928 proto_tree_add_uint(jxta_elem_tree
, hf_jxta_element2_nameid
, tvb
, tree_offset
, 2, nameID
);
1929 if (nameID
< names_count
) {
1930 proto_item_append_text(name_ti
, " (%s)", names_table
[nameID
]);
1932 proto_item_append_text(name_ti
, " * BAD *");
1937 uint16_t name_len
= tvb_get_ntohs(tvb
, tree_offset
);
1938 proto_item_append_text(jxta_elem_tree_item
, " \"%s\"", tvb_format_text(pinfo
->pool
, tvb
, tree_offset
+ 2, name_len
));
1939 proto_tree_add_item(jxta_elem_tree
, hf_jxta_element_name
, tvb
, tree_offset
, 2, ENC_ASCII
|ENC_BIG_ENDIAN
);
1940 tree_offset
+= 2 + name_len
;
1944 if ((flags
& JXTAMSG2_ELMFLAG_TYPE
) != 0) {
1945 uint16_t mimeID
= tvb_get_ntohs(tvb
, tree_offset
);
1946 proto_item
*mime_ti
=
1947 proto_tree_add_uint(jxta_elem_tree
, hf_jxta_element2_mimeid
, tvb
, tree_offset
, 2, mimeID
);
1949 if (mimeID
< names_count
) {
1950 proto_item_append_text(mime_ti
, " (%s)", names_table
[mimeID
]);
1951 mediatype
= wmem_strdup( pinfo
->pool
, names_table
[mimeID
] );
1953 proto_item_append_text(mime_ti
, " * BAD *");
1958 mediatype
= "application/octet-stream";
1961 /* process encoding */
1962 if ((flags
& JXTAMSG2_ELMFLAG_ENCODINGS
) != 0) {
1963 uint16_t encodingID
= tvb_get_ntohs(tvb
, tree_offset
);
1964 proto_item
*encoding_ti
=
1965 proto_tree_add_uint(jxta_elem_tree
, hf_jxta_element2_encodingid
, tvb
, tree_offset
, 2, encodingID
);
1967 if (encodingID
< names_count
) {
1968 proto_item_append_text(encoding_ti
, " (%s)", names_table
[encodingID
]);
1970 proto_item_append_text(encoding_ti
, " * BAD *");
1977 if ((flags
& JXTAMSG2_ELMFLAG_UINT64_LENS
) != 0) {
1978 content_len
= tvb_get_ntoh64(tvb
, tree_offset
);
1979 proto_tree_add_item(jxta_elem_tree
, hf_jxta_element_content_len64
, tvb
, tree_offset
, 8, ENC_BIG_ENDIAN
);
1982 content_len
= tvb_get_ntohl(tvb
, tree_offset
);
1983 proto_tree_add_item(jxta_elem_tree
, hf_jxta_element_content_len
, tvb
, tree_offset
, 4, ENC_BIG_ENDIAN
);
1988 element_content_tvb
= tvb_new_subset_length(tvb
, tree_offset
, (int)content_len
);
1990 tree_offset
+= dissect_media(mediatype
, element_content_tvb
, pinfo
, jxta_elem_tree
);
1992 /* process the signature element */
1993 if ((flags
& JXTAMSG2_ELMFLAG_SIGNATURE
) != 0) {
1994 tvbuff_t
*jxta_message_element_tvb
= tvb_new_subset_remaining(tvb
, tree_offset
);
1996 tree_offset
+= dissect_jxta_message_element_1(jxta_message_element_tvb
, pinfo
, jxta_elem_tree
, names_count
, names_table
);
1999 proto_item_set_end(jxta_elem_tree_item
, tvb
, tree_offset
);
2001 // offset is based on reported lengths. tree_offset is based on captured lengths via dissect_media.
2002 // Comment this out for now in favor of dissect_media's expert warning.
2003 // DISSECTOR_ASSERT(tree_offset == offset);
2009 * Dissect a tvbuff containing arbitrary typed data.
2011 * <p/>We provide special handling for type media types :
2013 * <dt>application/x-jxta-tls-block</dt>
2014 * <dd>We hand this data off to SSL to dissect.</dd>
2015 * <dt>application/gzip</dt>
2016 * <dd>We decompress the data and then dissect the contents as <tt>text/xml;charset="UTF-8"</tt></dd>
2019 * @param fullmediatype The full media type of the buffer to dissect including params
2020 * @param tvb The buffer to dissect.
2021 * @param pinfo Packet Info.
2022 * @param tree The protocol tree.
2023 * @return Number of bytes from the tvbuff_t which were processed, 0 (zero) if
2024 * the packet was not recognized and negative if the dissector needs
2025 * more bytes in order to process a PDU.
2027 // NOLINTNEXTLINE(misc-no-recursion)
2028 static int dissect_media( const char* fullmediatype
, tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
) {
2031 if (fullmediatype
) {
2032 char *mediatype
= wmem_strdup(pinfo
->pool
, fullmediatype
);
2033 char *parms_at
= strchr(mediatype
, ';');
2034 const char *save_match_string
= pinfo
->match_string
;
2035 media_content_info_t content_info
= { MEDIA_CONTAINER_OTHER
, NULL
, NULL
, NULL
};
2037 /* Based upon what is done in packet-media.c we set up type and params */
2038 if (NULL
!= parms_at
) {
2039 content_info
.media_str
= wmem_strdup( pinfo
->pool
, parms_at
+ 1 );
2043 /* Set the version that goes to packet-media.c before converting case */
2044 pinfo
->match_string
= wmem_strdup(pinfo
->pool
, mediatype
);
2046 /* force to lower case */
2047 ascii_strdown_inplace(mediatype
);
2049 if (0 == strcmp("application/x-jxta-tls-block", mediatype
)) {
2050 /* If we recognize it as a TLS packet then we shuffle it off to tls dissector. */
2051 if (NULL
!= tls_handle
) {
2052 dissected
= call_dissector(tls_handle
, tvb
, pinfo
, tree
);
2054 } else if (0 == strcmp("application/gzip", mediatype
)) {
2055 tvbuff_t
*uncomp_tvb
= tvb_child_uncompress_zlib(tvb
, tvb
, 0, tvb_captured_length(tvb
));
2057 if( NULL
!= uncomp_tvb
) {
2058 add_new_data_source(pinfo
, uncomp_tvb
, "Uncompressed Element Content");
2060 /* XXX bondolo 20060201 Force XML for uncompressed data. */
2061 increment_dissection_depth(pinfo
);
2062 dissected
= dissect_media("text/xml;charset=\"UTF-8\"", uncomp_tvb
, pinfo
, tree
);
2063 decrement_dissection_depth(pinfo
);
2065 if( dissected
> 0 ) {
2066 /* report back the uncompressed length. */
2067 dissected
= tvb_captured_length(tvb
);
2071 dissected
= dissector_try_string_with_data(media_type_dissector_table
, mediatype
, tvb
, pinfo
, tree
, true, &content_info
) ? tvb_captured_length(tvb
) : 0;
2073 if( dissected
!= (int) tvb_captured_length(tvb
) ) {
2074 /* ws_message( "%s : %d expected, %d dissected", mediatype, tvb_captured_length(tvb), dissected ); */
2078 if (0 == dissected
) {
2079 dissected
= call_dissector_with_data(media_handle
, tvb
, pinfo
, tree
, &content_info
);
2082 pinfo
->match_string
= save_match_string
;
2085 if(0 == dissected
) {
2086 /* display it as raw data */
2087 dissected
= call_data_dissector(tvb
, pinfo
, tree
);
2090 if (dissected
< (int) tvb_reported_length(tvb
)) {
2091 proto_item
*item
= proto_tree_add_expert(tree
, pinfo
, &ei_media_too_short
, tvb
, 0, dissected
);
2092 proto_item_set_generated(item
);
2098 * Register jxta protocol and jxta message protocol, header fields, subtree types, preferences.
2100 void proto_register_jxta(void)
2102 module_t
*jxta_module
;
2103 expert_module_t
*expert_jxta
;
2105 /** our header fields */
2106 static hf_register_info hf
[] = {
2108 {"Address", "jxta.uri.addr", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2109 "URI Address (source or destination)", HFILL
}
2112 {"Source", "jxta.uri.src", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2113 "URI Source", HFILL
}
2116 {"Destination", "jxta.uri.dst", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2117 "URI Destination", HFILL
}
2120 {"JXTA UDP", "jxta.udp", FT_NONE
, BASE_NONE
, NULL
, 0x0,
2124 {"Signature", "jxta.udpsig", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2125 "JXTA UDP Signature", HFILL
}
2128 {"Welcome", "jxta.welcome", FT_NONE
, BASE_NONE
, NULL
, 0x00,
2129 "JXTA Connection Welcome Message", HFILL
}
2131 {&hf_jxta_welcome_initiator
,
2132 {"Initiator", "jxta.welcome.initiator", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x00,
2133 "JXTA Connection Welcome Message Initiator", HFILL
}
2135 {&hf_jxta_welcome_sig
,
2136 {"Signature", "jxta.welcome.signature", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2137 "JXTA Connection Welcome Message Signature", HFILL
}
2139 {&hf_jxta_welcome_destAddr
,
2140 {"Destination Address", "jxta.welcome.destAddr", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2141 "JXTA Connection Welcome Message Destination Address", HFILL
}
2143 {&hf_jxta_welcome_pubAddr
,
2144 {"Public Address", "jxta.welcome.pubAddr", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2145 "JXTA Connection Welcome Message Public Address", HFILL
}
2147 {&hf_jxta_welcome_peerid
,
2148 {"PeerID", "jxta.welcome.peerid", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2149 "JXTA Connection Welcome Message PeerID", HFILL
}
2151 {&hf_jxta_welcome_noProp
,
2152 {"No Propagate Flag", "jxta.welcome.noPropFlag", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2153 "JXTA Connection Welcome Message No Propagate Flag", HFILL
}
2155 {&hf_jxta_welcome_msgVers
,
2156 {"Preferred Message Version", "jxta.welcome.msgVersion", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2157 "JXTA Connection Welcome Message Preferred Message Version", HFILL
}
2159 {&hf_jxta_welcome_variable
,
2160 {"Variable Parameter", "jxta.welcome.variable", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2161 "JXTA Connection Welcome Message Variable Parameter", HFILL
}
2163 {&hf_jxta_welcome_version
,
2164 {"Version", "jxta.welcome.version", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2165 "JXTA Connection Welcome Message Version", HFILL
}
2168 {"Framing", "jxta.framing", FT_NONE
, BASE_NONE
, NULL
, 0x0,
2169 "JXTA Message Framing", HFILL
}
2171 {&hf_jxta_framing_header
,
2172 {"Header", "jxta.framing.header", FT_NONE
, BASE_NONE
, NULL
, 0x0,
2173 "JXTA Message Framing Header", HFILL
}
2175 {&hf_jxta_framing_header_name
,
2176 {"Name", "jxta.framing.header.name", FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
2177 "JXTA Message Framing Header Name", HFILL
}
2179 {&hf_jxta_framing_header_value_length
,
2180 {"Value Length", "jxta.framing.header.valuelen", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2181 "JXTA Message Framing Header Value Length", HFILL
}
2183 {&hf_jxta_framing_header_value
,
2184 {"Value", "jxta.framing.header.value", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2185 "JXTA Message Framing Header Value", HFILL
}
2187 {&hf_jxta_message_address
,
2188 {"Address", "jxta.message.address", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2189 "JXTA Message Address (source or destination)", HFILL
}
2191 {&hf_jxta_message_src
,
2192 {"Source", "jxta.message.source", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2193 "JXTA Message Source", HFILL
}
2195 {&hf_jxta_message_dst
,
2196 {"Destination", "jxta.message.destination", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2197 "JXTA Message Destination", HFILL
}
2199 {&hf_jxta_message_sig
,
2200 {"Signature", "jxta.message.signature", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2201 "JXTA Message Signature", HFILL
}
2203 {&hf_jxta_message_version
,
2204 {"Version", "jxta.message.version", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2205 "JXTA Message Version", HFILL
}
2207 {&hf_jxta_message_flags
,
2208 {"Flags", "jxta.message.flags", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
2209 "JXTA Message Flags", HFILL
}
2211 {&hf_jxta_message_flag_utf16be
,
2212 {"UTF16BE", "jxta.message.flags.UTF-16BE", FT_BOOLEAN
, 2, TFS(&tfs_set_notset
), 0x1,
2213 "JXTA Message Element Flag -- UTF16-BE Strings", HFILL
}
2215 {&hf_jxta_message_flag_ucs32be
,
2216 {"UCS32BE", "jxta.message.flags.UCS32BE", FT_BOOLEAN
, 2, TFS(&tfs_set_notset
), 0x2,
2217 "JXTA Message Flag -- UCS32-BE Strings", HFILL
}
2219 {&hf_jxta_message_names_count
,
2220 {"Names Count", "jxta.message.names", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2221 "JXTA Message Names Table", HFILL
}
2223 {&hf_jxta_message_names_name
,
2224 {"Names Table Name", "jxta.message.names.name", FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
2225 "JXTA Message Names Table Name", HFILL
}
2227 {&hf_jxta_message_element_count
,
2228 {"Element Count", "jxta.message.elements", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2229 "JXTA Message Element Count", HFILL
}
2232 {"JXTA Message Element", "jxta.message.element", FT_NONE
, BASE_NONE
, NULL
, 0x0,
2235 {&hf_jxta_element_sig
,
2236 {"Signature", "jxta.message.element.signature", FT_STRING
, BASE_NONE
, NULL
, 0x0,
2237 "JXTA Message Element Signature", HFILL
}
2239 {&hf_jxta_element1_namespaceid
,
2240 {"Namespace ID", "jxta.message.element.namespaceid", FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2241 "JXTA Message Element Namespace ID", HFILL
}
2243 {&hf_jxta_element2_namespaceid
,
2244 {"Namespace ID", "jxta.message.element.namespaceid", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2245 "JXTA Message Element Namespace ID", HFILL
}
2247 {&hf_jxta_element_flags
,
2248 {"Flags", "jxta.message.element.flags", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
2249 "JXTA Message Element Flags", HFILL
}
2251 {&hf_jxta_element1_flag_hasType
,
2252 {"hasType", "jxta.message.element.flags.hasType", FT_BOOLEAN
, 3, TFS(&tfs_set_notset
), 0x1,
2253 "JXTA Message Element Flag -- hasType", HFILL
}
2255 {&hf_jxta_element1_flag_hasEncoding
,
2256 {"hasEncoding", "jxta.message.element.flags.hasEncoding", FT_BOOLEAN
, 3, TFS(&tfs_set_notset
), 0x2,
2257 "JXTA Message Element Flag -- hasEncoding", HFILL
}
2259 {&hf_jxta_element1_flag_hasSignature
,
2260 {"hasSignature", "jxta.message.element.flags.hasSignature", FT_BOOLEAN
, 3, TFS(&tfs_set_notset
), 0x4,
2261 "JXTA Message Element Flag -- hasSignature", HFILL
}
2263 {&hf_jxta_element2_flag_64bitlens
,
2264 {"uint64Lens", "jxta.message.element.flags.uint64Lens", FT_BOOLEAN
, 6, TFS(&tfs_set_notset
), 0x01,
2265 "JXTA Message Element Flag -- uint64Lens", HFILL
}
2267 {&hf_jxta_element2_flag_nameLiteral
,
2268 {"nameLiteral", "jxta.message.element.flags.nameLiteral", FT_BOOLEAN
, 6, TFS(&tfs_set_notset
), 0x02,
2269 "JXTA Message Element Flag -- nameLiteral", HFILL
}
2271 {&hf_jxta_element2_flag_hasType
,
2272 {"hasType", "jxta.message.element.flags.hasType", FT_BOOLEAN
, 6, TFS(&tfs_set_notset
), 0x04,
2273 "JXTA Message Element Flag -- hasType", HFILL
}
2275 {&hf_jxta_element2_flag_hasSignature
,
2276 {"hasSignature", "jxta.message.element.flags.hasSignature", FT_BOOLEAN
, 6, TFS(&tfs_set_notset
), 0x08,
2277 "JXTA Message Element Flag -- hasSignature", HFILL
}
2279 {&hf_jxta_element2_flag_hasEncoding
,
2280 {"hasSignature", "jxta.message.element.flags.hasEncoding", FT_BOOLEAN
, 6, TFS(&tfs_set_notset
), 0x10,
2281 "JXTA Message Element Flag -- hasEncoding", HFILL
}
2283 {&hf_jxta_element2_flag_sigOfEncoded
,
2284 {"sigOfEncoded", "jxta.message.element.flags.sigOfEncoded", FT_BOOLEAN
, 6, TFS(&tfs_set_notset
), 0x20,
2285 "JXTA Message Element Flag -- sigOfEncoded", HFILL
}
2287 {&hf_jxta_element2_nameid
,
2288 {"Name ID", "jxta.message.element.nameid", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2289 "JXTA Message Element Name ID", HFILL
}
2291 {&hf_jxta_element_name
,
2292 {"Element Name", "jxta.message.element.name", FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
2293 "JXTA Message Element Name", HFILL
}
2295 {&hf_jxta_element2_mimeid
,
2296 {"MIME ID", "jxta.message.element.mimeid", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2297 "JXTA Message Element MIME ID", HFILL
}
2299 {&hf_jxta_element2_encodingid
,
2300 {"Encoding ID", "jxta.message.element.encodingid", FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2301 "JXTA Message Element Encoding ID", HFILL
}
2303 {&hf_jxta_element_type
,
2304 {"Element Type", "jxta.message.element.type", FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
2305 "JXTA Message Element Name", HFILL
}
2307 {&hf_jxta_element_encoding
,
2308 {"Element Type", "jxta.message.element.encoding", FT_UINT_STRING
, BASE_NONE
, NULL
, 0x0,
2309 "JXTA Message Element Encoding", HFILL
}
2311 {&hf_jxta_element_content_len
,
2312 {"Element Content Length", "jxta.message.element.content.length", FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2313 "JXTA Message Element Content Length", HFILL
}
2315 {&hf_jxta_element_content_len64
,
2316 {"Element Content Length", "jxta.message.element.content.length64", FT_UINT64
, BASE_DEC
, NULL
, 0x0,
2317 "JXTA Message Element Content Length", HFILL
}
2320 {&hf_jxta_element_content
,
2321 {"Element Content", "jxta.message.element.content", FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2322 "JXTA Message Element Content", HFILL
}
2327 static ei_register_info ei
[] = {
2328 { &ei_media_too_short
, { "jxta.media_too_short", PI_PROTOCOL
, PI_WARN
, "Media length less than expected", EXPFILL
}},
2332 * JXTA Protocol subtree array
2334 static int *ett
[] = {
2339 &ett_jxta_framing_header
,
2341 &ett_jxta_msg_flags
,
2343 &ett_jxta_elem_1_flags
,
2344 &ett_jxta_elem_2_flags
2347 proto_jxta
= proto_register_protocol("JXTA P2P", "JXTA", "jxta");
2349 jxta_tap
= register_tap("jxta");
2351 proto_message_jxta
= proto_register_protocol("JXTA Message", "JXTA Message", "jxta.message");
2353 jxta_udp_handle
= register_dissector("jxta.udp", dissect_jxta_udp
, proto_jxta
);
2354 stream_jxta_handle
= register_dissector("jxta.stream", dissect_jxta_stream
, proto_jxta
);
2356 /* Register header fields */
2357 proto_register_field_array(proto_jxta
, hf
, array_length(hf
));
2359 /* Register JXTA Sub-tree */
2360 proto_register_subtree_array(ett
, array_length(ett
));
2362 expert_jxta
= expert_register_protocol(proto_jxta
);
2363 expert_register_field_array(expert_jxta
, ei
, array_length(ei
));
2365 uri_address_type
= address_type_dissector_register("AT_URI", "URI/URL/URN", uri_to_str
, uri_str_len
, NULL
, uri_col_filter_str
, NULL
, NULL
, NULL
);
2367 /* Register preferences */
2368 /* register re-init routine */
2369 jxta_module
= prefs_register_protocol(proto_jxta
, proto_reg_handoff_jxta
);
2371 prefs_register_bool_preference(jxta_module
, "msg.mediatype", "Register binary JXTA Message as a media type",
2372 "Enable to have correctly typed MIME media dissected as JXTA Messages.", &gMSG_MEDIA
);
2374 prefs_register_bool_preference(jxta_module
, "desegment",
2375 "Reassemble JXTA messages spanning multiple UDP/TCP/SCTP segments",
2376 "Whether the JXTA dissector should reassemble messages spanning multiple UDP/TCP/SCTP segments."
2377 " To use this option you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings "
2378 " and enable \"Reassemble fragmented IP datagrams\" in the IP protocol settings.",
2381 prefs_register_obsolete_preference(jxta_module
, "udp.heuristic");
2382 prefs_register_obsolete_preference(jxta_module
, "tcp.heuristic");
2383 prefs_register_obsolete_preference(jxta_module
, "sctp.heuristic");
2385 register_conversation_table(proto_jxta
, true, jxta_conversation_packet
, jxta_endpoint_packet
);
2390 * Update registrations in response to preferences changes.
2392 void proto_reg_handoff_jxta(void)
2394 static bool init_done
= false;
2395 static dissector_handle_t message_jxta_handle
;
2397 static bool msg_media_register_done
= false;
2400 message_jxta_handle
= create_dissector_handle(dissect_jxta_message
, proto_message_jxta
);
2402 media_type_dissector_table
= find_dissector_table("media_type");
2403 tls_handle
= find_dissector_add_dependency("tls", proto_jxta
);
2405 media_handle
= find_dissector_add_dependency("media", proto_jxta
);
2407 heur_dissector_add("udp", dissect_jxta_UDP_heur
, "JXTA over UDP", "jxta_udp", proto_jxta
, HEURISTIC_ENABLE
);
2408 heur_dissector_add("tcp", dissect_jxta_TCP_heur
, "JXTA over TCP", "jxta_tcp", proto_jxta
, HEURISTIC_ENABLE
);
2409 heur_dissector_add("sctp", dissect_jxta_SCTP_heur
, "JXTA over SCTP", "jxta_sctp", proto_jxta
, HEURISTIC_ENABLE
);
2415 if( !msg_media_register_done
) {
2416 /* ws_message( "Registering JXTA Message media type" ); */
2417 dissector_add_string("media_type", "application/x-jxta-msg", message_jxta_handle
);
2418 msg_media_register_done
= true;
2421 if( msg_media_register_done
) {
2422 /* ws_message( "Deregistering JXTA Message media type" ); */
2423 dissector_delete_string("media_type", "application/x-jxta-msg", message_jxta_handle
);
2424 msg_media_register_done
= false;
2430 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2435 * indent-tabs-mode: nil
2438 * vi: set shiftwidth=4 tabstop=8 expandtab:
2439 * :indentSize=4:tabSize=8:noTabs=true: