Coverage Report

Created: 2025-12-27 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-jxta.c
Line
Count
Source
1
/* packet-jxta.c
2
 *
3
 * Routines for JXTA packet dissection
4
 * JXTA specification from https://jxta-spec.dev.java.net (now at https://github.com/chaupal/jxta-spec ?)
5
 *
6
 * Copyright 2004-08, Mike Duigou <bondolo@dev.java.net>
7
 *
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
12
 *
13
 * Wireshark - Network traffic analyzer
14
 * By Gerald Combs <gerald@wireshark.org>
15
 * Copyright 2000 Gerald Combs
16
 *
17
 * SPDX-License-Identifier: GPL-2.0-or-later
18
 */
19
20
#include "config.h"
21
22
0
#define WS_LOG_DOMAIN "jxta"
23
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>
31
#include <epan/tfs.h>
32
#include <wsutil/array.h>
33
#include <wsutil/str_util.h>
34
35
#include "packet-jxta.h"
36
#include "packet-media-type.h"
37
38
void proto_register_jxta(void);
39
void proto_reg_handoff_jxta(void);
40
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' };
44
45
static const char JXTA_WELCOME_MSG_SIG[] = { 'J', 'X', 'T', 'A', 'H', 'E', 'L', 'L', 'O', ' ' };
46
47
static const char* JXTA_WELCOME_MSG_VERSION_1_1 = "1.1";
48
static const char* JXTA_WELCOME_MSG_VERSION_3_0 = "3.0";
49
50
static const int JXTA_MSG_VERSION_1;
51
static const int JXTA_MSG_VERSION_2 = 1;
52
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;
56
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;
62
63
static int proto_jxta;
64
static int proto_message_jxta;
65
static int jxta_tap;
66
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;
71
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; */
126
127
/**
128
*    JXTA Protocol subtree handles
129
**/
130
static int ett_jxta;
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;
140
141
static expert_field ei_media_too_short;
142
143
static int uri_address_type = -1;
144
145
/**
146
*   global preferences
147
**/
148
static bool gDESEGMENT = true;
149
static bool gMSG_MEDIA = true;
150
151
static dissector_handle_t jxta_udp_handle;
152
153
/**
154
*   Stream Conversation data
155
**/
156
struct jxta_stream_conversation_data {
157
    port_type tpt_ptype;
158
159
    address initiator_tpt_address;
160
    uint32_t initiator_tpt_port;
161
    uint32_t initiator_welcome_frame;
162
    address initiator_address;
163
164
    address receiver_tpt_address;
165
    uint32_t receiver_tpt_port;
166
    uint32_t receiver_welcome_frame;
167
    address receiver_address;
168
};
169
170
typedef struct jxta_stream_conversation_data jxta_stream_conversation_data;
171
172
static const char* jxta_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter)
173
0
{
174
0
    if ((filter == CONV_FT_SRC_ADDRESS) && (conv->src_address.type == uri_address_type))
175
0
        return "jxta.message.src";
176
177
0
    if ((filter == CONV_FT_DST_ADDRESS) && (conv->dst_address.type == uri_address_type))
178
0
        return "jxta.message.dst";
179
180
0
    if ((filter == CONV_FT_ANY_ADDRESS) && (conv->src_address.type == uri_address_type))
181
0
        return "jxta.message.address";
182
183
0
    return CONV_FILTER_INVALID;
184
0
}
185
186
static ct_dissector_info_t jxta_ct_dissector_info = {&jxta_conv_get_filter_type};
187
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)
190
0
{
191
0
    conv_hash_t *hash = (conv_hash_t*) pct;
192
0
    hash->flags = flags;
193
194
0
    const jxta_tap_header *jxtahdr = (const jxta_tap_header *) vip;
195
196
0
    add_conversation_table_data(hash, &jxtahdr->src_address, &jxtahdr->dest_address,
197
0
        0, 0, 1, jxtahdr->size, NULL, NULL, &jxta_ct_dissector_info, CONVERSATION_NONE);
198
199
0
    return TAP_PACKET_REDRAW;
200
0
}
201
202
static const char* jxta_endpoint_get_filter_type(endpoint_item_t* endpoint, conv_filter_type_e filter)
203
0
{
204
0
    if ((filter == CONV_FT_ANY_ADDRESS) && (endpoint->myaddress.type == uri_address_type))
205
0
        return "jxta.message.address";
206
207
0
    return CONV_FILTER_INVALID;
208
0
}
209
210
static et_dissector_info_t jxta_endpoint_dissector_info = {&jxta_endpoint_get_filter_type};
211
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)
214
0
{
215
0
    conv_hash_t *hash = (conv_hash_t*) pit;
216
0
    hash->flags = flags;
217
218
0
    const jxta_tap_header *jxtahdr = (const jxta_tap_header *)vip;
219
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
0
    add_endpoint_table_data(hash, &jxtahdr->src_address, 0, true, 1, jxtahdr->size, &jxta_endpoint_dissector_info, ENDPOINT_NONE);
224
0
    add_endpoint_table_data(hash, &jxtahdr->dest_address, 0, false, 1, jxtahdr->size, &jxta_endpoint_dissector_info, ENDPOINT_NONE);
225
0
    return TAP_PACKET_REDRAW;
226
0
}
227
228
static int uri_to_str(const address* addr, char *buf, int buf_len)
229
0
{
230
0
    int copy_len = addr->len < (buf_len - 1) ? addr->len : (buf_len - 1);
231
0
    memcpy(buf, addr->data, copy_len );
232
0
    buf[copy_len] = '\0';
233
0
    return copy_len+1;
234
0
}
235
236
static int uri_str_len(const address* addr)
237
0
{
238
0
    return addr->len+1;
239
0
}
240
241
static const char* uri_col_filter_str(const address* addr _U_, bool is_src)
242
0
{
243
0
    if (is_src)
244
0
        return "uri.src";
245
246
0
    return "uri.dst";
247
0
}
248
249
/**
250
*   Prototypes
251
**/
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);
256
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);
266
267
/**
268
*   Heuristically dissect a tvbuff containing a JXTA UDP Message
269
*
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
274
**/
275
static bool dissect_jxta_UDP_heur(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data _U_)
276
1.34k
{
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!
280
     */
281
1.34k
    int save_desegment_offset;
282
1.34k
    uint32_t save_desegment_len;
283
1.34k
    int ret;
284
285
1.34k
    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) */
287
1.33k
        return false;
288
1.33k
    }
289
290
11
    save_desegment_offset = pinfo->desegment_offset;
291
11
    save_desegment_len = pinfo->desegment_len;
292
11
    ret = dissect_jxta_udp(tvb, pinfo, tree, NULL);
293
294
    /* ws_message( "%d Heuristic UDP Dissection : %d", pinfo->num, ret ); */
295
296
11
    if (ret < 0) {
297
        /*
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.
303
         */
304
0
        pinfo->desegment_offset = save_desegment_offset;
305
0
        pinfo->desegment_len = save_desegment_len;
306
0
        return false;
307
11
    } else if (ret == 0) {
308
        /*
309
         * A clear rejection.
310
         */
311
11
        pinfo->desegment_offset = save_desegment_offset;
312
11
        pinfo->desegment_len = save_desegment_len;
313
11
        return false;
314
11
    } else {
315
        /*
316
         * A clear acceptance.
317
         */
318
0
        return true;
319
0
    }
320
11
}
321
322
/**
323
*   Heuristically dissect a tvbuff containing a JXTA TCP Stream
324
*
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
329
**/
330
static bool dissect_jxta_TCP_heur(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data _U_)
331
3.12k
{
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!
335
     */
336
3.12k
    int save_desegment_offset;
337
3.12k
    uint32_t save_desegment_len;
338
3.12k
    int ret;
339
340
3.12k
    save_desegment_offset = pinfo->desegment_offset;
341
3.12k
    save_desegment_len = pinfo->desegment_len;
342
3.12k
    ret = dissect_jxta_stream(tvb, pinfo, tree, NULL);
343
344
    /* ws_message( "%d Heuristic TCP Dissection : %d", pinfo->num, ret ); */
345
346
3.12k
    if (ret < 0) {
347
        /*
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.
354
         *
355
         * Therefore, we treat a negative return from
356
         * dissect_jxta_stream() as a rejection.
357
         *
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.
363
         */
364
0
        pinfo->desegment_offset = save_desegment_offset;
365
0
        pinfo->desegment_len = save_desegment_len;
366
0
        return false;
367
3.12k
    } else if (ret == 0) {
368
        /*
369
         * A clear rejection.
370
         */
371
3.11k
        pinfo->desegment_offset = save_desegment_offset;
372
3.11k
        pinfo->desegment_len = save_desegment_len;
373
3.11k
        return false;
374
3.11k
    } else {
375
        /*
376
         * A clear acceptance.
377
         */
378
10
        return true;
379
10
    }
380
3.12k
}
381
382
/**
383
*   Heuristically dissect a tvbuff containing a JXTA SCTP Stream
384
*
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
389
**/
390
static bool dissect_jxta_SCTP_heur(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data _U_)
391
100
{
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!
395
     */
396
100
    int save_desegment_offset;
397
100
    uint32_t save_desegment_len;
398
100
    int ret;
399
400
100
    save_desegment_offset = pinfo->desegment_offset;
401
100
    save_desegment_len = pinfo->desegment_len;
402
100
    ret = dissect_jxta_stream(tvb, pinfo, tree, NULL);
403
404
    /* ws_message( "%d Heuristic SCTP Dissection : %d", pinfo->num, ret ); */
405
406
100
    if (ret < 0) {
407
        /*
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.
413
         *
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
418
         * it.
419
         */
420
0
        pinfo->desegment_offset = save_desegment_offset;
421
0
        pinfo->desegment_len = save_desegment_len;
422
0
        return false;
423
100
    } else if (ret == 0) {
424
        /*
425
         * A clear rejection.
426
         */
427
98
        pinfo->desegment_offset = save_desegment_offset;
428
98
        pinfo->desegment_len = save_desegment_len;
429
98
        return false;
430
98
    } else {
431
        /*
432
         * A clear acceptance.
433
         */
434
2
        return true;
435
2
    }
436
100
}
437
438
/**
439
*   Dissect a tvbuff containing a JXTA UDP header, JXTA Message framing and a JXTA Message
440
*
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.
447
**/
448
static int dissect_jxta_udp(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data _U_)
449
16
{
450
16
    unsigned offset = 0;
451
16
    unsigned available;
452
16
    int needed = 0;
453
454
16
    conversation_t *conversation = find_or_create_conversation(pinfo);
455
456
16
    conversation_set_dissector(conversation, jxta_udp_handle);
457
458
16
    while (true) {
459
16
        tvbuff_t *jxta_message_framing_tvb;
460
16
        int processed = 0;
461
16
        uint64_t content_length = -1;
462
16
        char *content_type = NULL;
463
464
16
        available = tvb_reported_length_remaining(tvb, offset);
465
16
        if (available < sizeof(JXTA_UDP_SIG)) {
466
0
            needed = (int) (sizeof(JXTA_UDP_SIG) - available);
467
0
            break;
468
0
        }
469
470
16
        if (tvb_memeql(tvb, offset, (const uint8_t*)JXTA_UDP_SIG, sizeof(JXTA_UDP_SIG)) != 0) {
471
            /* not ours */
472
2
            return 0;
473
2
        }
474
475
14
        offset += (int)sizeof(JXTA_UDP_SIG);
476
477
14
        jxta_message_framing_tvb = tvb_new_subset_remaining(tvb, offset);
478
14
        processed = dissect_jxta_message_framing(jxta_message_framing_tvb, pinfo, NULL, &content_length, &content_type);
479
480
14
        if ((0 == processed) || (NULL == content_type) || (content_length <= 0) || (content_length > UINT_MAX)) {
481
            /** Buffer did not begin with valid framing headers */
482
14
            return 0;
483
14
        }
484
485
0
        if (processed < 0) {
486
0
            needed = -processed;
487
0
            break;
488
0
        }
489
490
0
        offset += processed;
491
492
0
        available = tvb_reported_length_remaining(tvb, offset);
493
0
        if (available < content_length) {
494
0
            needed = (int) (content_length - available);
495
0
            break;
496
0
        }
497
498
0
        offset += (unsigned) content_length;
499
500
0
        break;
501
0
    }
502
503
0
    if ((needed > 0) && gDESEGMENT && pinfo->can_desegment) {
504
        /* ws_message( "UDP requesting %d more bytes", needed ); */
505
0
        pinfo->desegment_offset = 0;
506
0
        pinfo->desegment_len = needed;
507
0
        return -needed;
508
0
    }
509
510
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "JXTA");
511
512
0
    unsigned tree_offset = 0;
513
0
    proto_item *jxta_tree_item =
514
0
        proto_tree_add_protocol_format(tree, proto_jxta, tvb, tree_offset, -1, "JXTA" );
515
0
    proto_tree *jxta_tree = proto_item_add_subtree(jxta_tree_item, ett_jxta);
516
0
    proto_item *jxta_udp_tree_item =
517
0
        proto_tree_add_none_format(jxta_tree, hf_jxta_udp, tvb, tree_offset, -1, "JXTA UDP Message");
518
0
    proto_tree *jxta_udp_tree = proto_item_add_subtree(jxta_udp_tree_item, ett_jxta_udp);
519
0
    tvbuff_t *jxta_message_framing_tvb;
520
0
    uint64_t content_length = -1;
521
0
    char *content_type = NULL;
522
0
    tvbuff_t *jxta_message_tvb;
523
524
0
    proto_tree_add_item(jxta_udp_tree, hf_jxta_udpsig, tvb, tree_offset, (int)sizeof(JXTA_UDP_SIG), ENC_ASCII);
525
0
    tree_offset += (int)sizeof(JXTA_UDP_SIG);
526
527
0
    jxta_message_framing_tvb = tvb_new_subset_remaining(tvb, tree_offset);
528
529
0
    tree_offset += dissect_jxta_message_framing(jxta_message_framing_tvb, pinfo, jxta_tree, &content_length, &content_type);
530
531
0
    jxta_message_tvb = tvb_new_subset_length(tvb, tree_offset, (int) content_length);
532
533
0
    tree_offset += dissect_media(content_type, jxta_message_tvb, pinfo, tree);
534
535
0
    proto_item_set_end(jxta_udp_tree_item, tvb, tree_offset);
536
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);
540
541
0
    return offset;
542
0
}
543
544
/**
545
*   Dissect a tvbuff containing JXTA stream PDUs. This commonly includes
546
*   connections over TCP sockets.
547
*
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
550
*   JXTA Messages.
551
*
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.
558
**/
559
static int dissect_jxta_stream(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data _U_)
560
3.25k
{
561
3.25k
    unsigned offset = 0;
562
3.25k
    unsigned available = tvb_reported_length_remaining(tvb, offset);
563
3.25k
    int processed = 0;
564
3.25k
    int needed = 0;
565
3.25k
    jxta_stream_conversation_data *tpt_conv_data = NULL;
566
3.25k
    proto_item *jxta_tree_item = NULL;
567
3.25k
    proto_tree *jxta_tree = NULL;
568
569
    /* ws_message("Dissecting%s : %d", (NULL != tree) ? " for display" : "", pinfo->num ); */
570
571
3.25k
    if (available < sizeof(JXTA_WELCOME_MSG_SIG)) {
572
467
        needed = (int) (sizeof(JXTA_WELCOME_MSG_SIG) - available);
573
467
        goto Common_Exit;
574
467
    }
575
576
2.78k
    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
32
        address *welcome_addr;
579
32
        bool initiator = false;
580
581
32
        tpt_conv_data = get_tpt_conversation(pinfo);
582
583
32
        if (0 == tpt_conv_data->initiator_welcome_frame) {
584
            /* The initiator welcome frame */
585
19
            tpt_conv_data->tpt_ptype = pinfo->ptype;
586
19
            tpt_conv_data->initiator_welcome_frame = pinfo->num;
587
19
            copy_address_wmem(wmem_file_scope(), &tpt_conv_data->initiator_tpt_address, &pinfo->src);
588
19
            tpt_conv_data->initiator_tpt_port = pinfo->srcport;
589
590
19
            welcome_addr = &tpt_conv_data->initiator_address;
591
19
            initiator = true;
592
19
        } else {
593
13
            if (tpt_conv_data->initiator_welcome_frame >= pinfo->num) {
594
                /* what we saw previously was the receiver welcome message */
595
3
                tpt_conv_data->receiver_welcome_frame = tpt_conv_data->initiator_welcome_frame;
596
3
                tpt_conv_data->receiver_tpt_address = tpt_conv_data->initiator_tpt_address;
597
3
                tpt_conv_data->receiver_tpt_port = tpt_conv_data->initiator_tpt_port;
598
3
                tpt_conv_data->receiver_address = tpt_conv_data->initiator_address;
599
3
                tpt_conv_data->initiator_welcome_frame = pinfo->num;
600
3
                copy_address_wmem(wmem_file_scope(), &tpt_conv_data->initiator_tpt_address, &pinfo->src);
601
3
                tpt_conv_data->initiator_tpt_port = pinfo->srcport;
602
603
3
                welcome_addr = &tpt_conv_data->initiator_address;
604
3
                initiator = true;
605
10
            } else {
606
                /* The receiver welcome frame */
607
10
                tpt_conv_data->tpt_ptype = pinfo->ptype;
608
10
                tpt_conv_data->receiver_welcome_frame = pinfo->num;
609
10
                copy_address_wmem(wmem_file_scope(), &tpt_conv_data->receiver_tpt_address, &pinfo->src);
610
10
                tpt_conv_data->receiver_tpt_port = pinfo->srcport;
611
612
10
                welcome_addr = &tpt_conv_data->receiver_address;
613
10
                initiator = false;
614
10
            }
615
13
        }
616
617
32
        processed = dissect_jxta_welcome(tvb, pinfo, NULL, welcome_addr, initiator);
618
619
32
        if( processed < 0 ) {
620
0
            needed = -processed;
621
0
            goto Common_Exit;
622
0
        }
623
624
        /* redo, this time creating the display tree. */
625
32
        jxta_tree_item = proto_tree_add_protocol_format(tree, proto_jxta, tvb, offset, -1, "JXTA" );
626
32
        jxta_tree = proto_item_add_subtree(jxta_tree_item, ett_jxta);
627
628
32
        processed = dissect_jxta_welcome(tvb, pinfo, jxta_tree, welcome_addr, initiator);
629
2.75k
    } else {
630
        /* Somewhere in the middle of a JXTA stream connection */
631
2.75k
        uint64_t content_length = UINT64_MAX;
632
2.75k
        char *content_type = NULL;
633
2.75k
        int headers_len = dissect_jxta_message_framing(tvb, pinfo, NULL, &content_length, &content_type);
634
635
2.75k
        if ((0 == headers_len) || (NULL == content_type) || (content_length <= 0) || (content_length > UINT_MAX)) {
636
            /** Buffer did not begin with valid framing headers */
637
2.75k
            return 0;
638
2.75k
        }
639
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); */
645
646
0
        if (headers_len < 0) {
647
            /* negative headers_len means we need more bytes */
648
0
            needed = -headers_len;
649
0
            goto Common_Exit;
650
0
        }
651
652
0
        available = tvb_reported_length_remaining(tvb, offset + headers_len);
653
0
        if (available >= content_length) {
654
0
            tvbuff_t *jxta_message_tvb = tvb_new_subset_length(tvb, offset + headers_len, (int) content_length);
655
0
            conversation_t *peer_conversation = NULL;
656
657
0
            jxta_tree_item = proto_tree_add_protocol_format(tree, proto_jxta, tvb, offset, -1, "JXTA" );
658
0
            jxta_tree = proto_item_add_subtree(jxta_tree_item, ett_jxta);
659
660
            /* Redo header processing, this time populating the tree. */
661
0
            headers_len = dissect_jxta_message_framing(tvb, pinfo, jxta_tree, &content_length, &content_type);
662
663
0
            tpt_conv_data = get_tpt_conversation(pinfo);
664
0
            peer_conversation = get_peer_conversation(pinfo, tpt_conv_data, true);
665
666
            /* Use our source and destination addresses if we have them */
667
0
            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); */
671
672
0
                if (addresses_equal(&pinfo->src, &tpt_conv_data->initiator_tpt_address)
673
0
                    && 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
0
                    copy_address_shallow(&pinfo->src, &tpt_conv_data->initiator_address);
678
0
                    pinfo->srcport = 0;
679
0
                    copy_address_shallow(&pinfo->dst, &tpt_conv_data->receiver_address);
680
0
                    pinfo->destport = 0;
681
0
                    pinfo->ptype = PT_NONE;
682
0
                } else if (addresses_equal(&pinfo->src, &tpt_conv_data->receiver_tpt_address) &&
683
0
                           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
0
                    copy_address_shallow(&pinfo->src, &tpt_conv_data->receiver_address);
688
0
                    pinfo->srcport = 0;
689
0
                    copy_address_shallow(&pinfo->dst, &tpt_conv_data->initiator_address);
690
0
                    pinfo->destport = 0;
691
0
                    pinfo->ptype = PT_NONE;
692
0
                } else {
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); */
696
0
                }
697
0
            }
698
699
0
            processed = headers_len;
700
701
0
            processed += dissect_media(content_type, jxta_message_tvb, pinfo, tree);
702
0
        } else {
703
            /* we need more bytes before we can process message body. */
704
0
            needed = (int) ((unsigned) content_length - available);
705
0
            goto Common_Exit;
706
0
        }
707
0
    }
708
709
32
    offset += processed;
710
711
485
Common_Exit:
712
485
    if ((needed > 0) && gDESEGMENT && pinfo->can_desegment) {
713
        /* ws_message( "Stream requesting %d more bytes", needed ); */
714
0
        pinfo->desegment_offset = offset;
715
0
        pinfo->desegment_len = needed;
716
0
        return -needed;
717
0
    }
718
719
485
    return offset;
720
485
}
721
722
/**
723
*   Find or possibly create a transport conversation object for the connection
724
*   which is associated with the packet info.
725
*
726
*   @param pinfo  The packet info from the underlying transport.
727
**/
728
static jxta_stream_conversation_data *get_tpt_conversation(packet_info * pinfo)
729
32
{
730
32
    conversation_t *tpt_conversation = find_or_create_conversation(pinfo);
731
32
    jxta_stream_conversation_data *tpt_conv_data;
732
733
32
    conversation_set_dissector(tpt_conversation, stream_jxta_handle);
734
735
32
    tpt_conv_data = (jxta_stream_conversation_data *) conversation_get_proto_data(tpt_conversation, proto_jxta);
736
737
32
    if (NULL == tpt_conv_data) {
738
19
        tpt_conv_data = wmem_new(wmem_file_scope(), jxta_stream_conversation_data);
739
19
        tpt_conv_data->tpt_ptype = pinfo->ptype;
740
741
19
        copy_address_wmem(wmem_file_scope(), &tpt_conv_data->initiator_tpt_address, &pinfo->src);
742
19
        tpt_conv_data->initiator_tpt_port = pinfo->srcport;
743
19
        tpt_conv_data->initiator_welcome_frame = 0;
744
19
        clear_address(&tpt_conv_data->initiator_address);
745
746
19
        copy_address_wmem(wmem_file_scope(), &tpt_conv_data->receiver_tpt_address, &pinfo->dst);
747
19
        tpt_conv_data->receiver_tpt_port = pinfo->destport;
748
19
        tpt_conv_data->receiver_welcome_frame = 0;
749
19
        clear_address(&tpt_conv_data->receiver_address);
750
751
19
        conversation_add_proto_data(tpt_conversation, proto_jxta, tpt_conv_data);
752
19
    }
753
754
32
    return tpt_conv_data;
755
32
}
756
757
/**
758
*   Find or possibly create a peer conversation object for the connection
759
*   which is associated with the packet info.
760
*
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.
763
**/
764
static conversation_t *get_peer_conversation(packet_info * pinfo, jxta_stream_conversation_data* tpt_conv_data, bool create)
765
0
{
766
0
    conversation_t * peer_conversation = NULL;
767
768
0
    if ((AT_NONE != tpt_conv_data->initiator_address.type) && (AT_NONE != tpt_conv_data->receiver_address.type)) {
769
0
        peer_conversation = find_conversation(pinfo->num, &tpt_conv_data->initiator_address, &tpt_conv_data->receiver_address,
770
0
                                               CONVERSATION_NONE, 0, 0, NO_PORT_B);
771
772
0
        if (create && (NULL == peer_conversation)) {
773
0
            peer_conversation = conversation_new(pinfo->num, &tpt_conv_data->initiator_address,
774
0
                                                  &tpt_conv_data->receiver_address, CONVERSATION_NONE, 0, 0, NO_PORT2);
775
0
            conversation_set_dissector(peer_conversation, stream_jxta_handle);
776
0
        }
777
778
0
    }
779
780
0
    return peer_conversation;
781
0
}
782
783
/**
784
*   Dissect a tvbuff containing a JXTA Welcome Message
785
*
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.
794
**/
795
static int dissect_jxta_welcome(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, address * found_addr, bool initiator)
796
64
{
797
64
    unsigned offset = 0;
798
64
    int afterwelcome;
799
64
    int first_linelen;
800
64
    unsigned available = tvb_reported_length_remaining(tvb, offset);
801
64
    char **tokens = NULL;
802
803
64
    if (available < sizeof(JXTA_WELCOME_MSG_SIG)) {
804
0
        return (int) (available - sizeof(JXTA_WELCOME_MSG_SIG));
805
0
    }
806
807
64
    if (0 != tvb_memeql(tvb, 0, (const uint8_t*)JXTA_WELCOME_MSG_SIG, sizeof(JXTA_WELCOME_MSG_SIG))) {
808
        /* not ours! */
809
0
        return 0;
810
0
    }
811
812
64
    first_linelen = tvb_find_line_end(tvb, offset, -1, &afterwelcome, gDESEGMENT && pinfo->can_desegment);
813
814
64
    if (-1 == first_linelen) {
815
0
        if (available > 4096) {
816
            /* it's too far too be reasonable */
817
0
            return 0;
818
0
        } else {
819
            /* ask for more bytes */
820
0
            return -DESEGMENT_ONE_MORE_SEGMENT;
821
0
        }
822
0
    }
823
824
    /* Dissect the Welcome Message */
825
826
64
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "JXTA");
827
828
64
    col_set_str(pinfo->cinfo, COL_INFO, "Welcome");
829
830
64
    {
831
64
        char *welcomeline = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, first_linelen, ENC_ASCII);
832
64
        char **current_token;
833
64
        unsigned token_offset = offset;
834
64
        proto_item *jxta_welcome_tree_item = NULL;
835
64
        proto_tree *jxta_welcome_tree = NULL;
836
837
64
        tokens = wmem_strsplit(pinfo->pool, welcomeline, " ", 255);
838
64
        current_token = tokens;
839
840
64
        if (tree) {
841
32
            jxta_welcome_tree_item =
842
32
                proto_tree_add_none_format(tree, hf_jxta_welcome, tvb, offset, afterwelcome,
843
32
                                           "JXTA Connection Welcome Message, %s", welcomeline);
844
32
            jxta_welcome_tree = proto_item_add_subtree(jxta_welcome_tree_item, ett_jxta_welcome);
845
32
        }
846
847
64
        if (jxta_welcome_tree) {
848
32
            proto_item *jxta_welcome_initiator_item =
849
32
                proto_tree_add_boolean(jxta_welcome_tree, hf_jxta_welcome_initiator, tvb, 0, 0, initiator);
850
32
            proto_item_set_generated(jxta_welcome_initiator_item);
851
32
        }
852
853
64
        if (NULL != *current_token) {
854
64
            proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_sig, tvb, token_offset, (int) strlen(*current_token), ENC_ASCII);
855
856
64
            token_offset += (unsigned) strlen(*current_token) + 1;
857
64
            current_token++;
858
64
        } else {
859
            /* invalid welcome message */
860
0
            afterwelcome = 0;
861
0
            goto Common_Exit;
862
0
        }
863
864
64
        if (NULL != *current_token) {
865
64
            if (jxta_welcome_tree) {
866
32
                proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_destAddr, tvb, token_offset, (int) strlen(*current_token),
867
32
                                    ENC_ASCII);
868
32
            }
869
870
64
            token_offset += (unsigned) strlen(*current_token) + 1;
871
64
            current_token++;
872
64
        } else {
873
            /* invalid welcome message */
874
0
            afterwelcome = 0;
875
0
            goto Common_Exit;
876
0
        }
877
878
64
        if (NULL != *current_token) {
879
40
            if (jxta_welcome_tree) {
880
19
                proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_pubAddr, tvb, token_offset, (int) strlen(*current_token), ENC_ASCII);
881
19
            }
882
883
40
            token_offset += (unsigned) strlen(*current_token) + 1;
884
40
            current_token++;
885
40
        } else {
886
            /* invalid welcome message */
887
24
            afterwelcome = 0;
888
24
            goto Common_Exit;
889
24
        }
890
891
40
        if (NULL != *current_token) {
892
29
            if (jxta_welcome_tree) {
893
13
                proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_peerid, tvb, token_offset, (int) strlen(*current_token), ENC_ASCII);
894
13
            }
895
896
29
            col_append_str(pinfo->cinfo, COL_INFO, (initiator ? " -> " : " <- ") );
897
29
            col_append_str(pinfo->cinfo, COL_INFO, *current_token);
898
899
29
            if (NULL != found_addr) {
900
28
                set_address(found_addr, uri_address_type, (int)strlen(*current_token) + 1, wmem_strdup(wmem_file_scope(), *current_token));
901
28
            }
902
903
29
            token_offset += (unsigned) strlen(*current_token) + 1;
904
29
            current_token++;
905
29
        } else {
906
            /* invalid welcome message */
907
11
            afterwelcome = 0;
908
11
            goto Common_Exit;
909
11
        }
910
911
29
        if (NULL != *current_token) {
912
25
            int variable_tokens = 0;
913
25
            char **variable_token = current_token;
914
915
127
            while(NULL != *variable_token) {
916
102
                variable_tokens++;
917
102
                variable_token++;
918
102
            }
919
920
25
            if( variable_tokens < 1 ) {
921
              /* invalid welcome message */
922
0
              afterwelcome = 0;
923
0
              goto Common_Exit;
924
0
            }
925
926
25
            if( (2 == variable_tokens) && (0 == strcmp(JXTA_WELCOME_MSG_VERSION_1_1, current_token[variable_tokens -1])) ) {
927
0
                  if (jxta_welcome_tree) {
928
0
                      proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_noProp, tvb, token_offset, (int) strlen(*current_token), ENC_ASCII);
929
0
                  }
930
931
0
                  token_offset += (unsigned) strlen(*current_token) + 1;
932
0
                  current_token++;
933
934
0
                  if (jxta_welcome_tree) {
935
0
                      proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_version, tvb, token_offset, (int) strlen(*current_token), ENC_ASCII);
936
0
                  }
937
25
            } else if( (3 == variable_tokens) && (0 == strcmp(JXTA_WELCOME_MSG_VERSION_3_0, current_token[variable_tokens -1])) ) {
938
0
                  if (jxta_welcome_tree) {
939
0
                      proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_noProp, tvb, token_offset, (int) strlen(*current_token), ENC_ASCII);
940
0
                  }
941
942
0
                  token_offset += (unsigned) strlen(*current_token) + 1;
943
0
                  current_token++;
944
945
0
                  if (jxta_welcome_tree) {
946
0
                      proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_msgVers, tvb, token_offset, (int) strlen(*current_token), ENC_ASCII);
947
0
                  }
948
949
0
                  token_offset += (unsigned) strlen(*current_token) + 1;
950
0
                  current_token++;
951
952
0
                  if (jxta_welcome_tree) {
953
0
                      proto_tree_add_item(jxta_welcome_tree, hf_jxta_welcome_version, tvb, token_offset, (int) strlen(*current_token), ENC_ASCII);
954
0
                  }
955
25
            } else {
956
                /* Unrecognized Welcome Version */
957
25
                int each_variable_token;
958
959
126
                for( each_variable_token = 0; each_variable_token < variable_tokens; each_variable_token++ ) {
960
101
                  if (jxta_welcome_tree) {
961
47
                      jxta_welcome_tree_item = proto_tree_add_item(jxta_welcome_tree,
962
47
                        (each_variable_token < (variable_tokens -1) ? hf_jxta_welcome_variable : hf_jxta_welcome_version),
963
47
                        tvb, token_offset, (int) strlen(*current_token), ENC_ASCII|ENC_NA);
964
965
47
                        proto_item_append_text(jxta_welcome_tree_item, " (UNRECOGNIZED)");
966
47
                  }
967
968
101
                  token_offset += (unsigned) strlen(*current_token) + 1;
969
101
                  current_token++;
970
101
                }
971
25
            }
972
25
        } else {
973
            /* invalid welcome message */
974
4
            afterwelcome = 0;
975
4
            goto Common_Exit;
976
4
        }
977
29
    }
978
979
50
Common_Exit:
980
50
    col_set_writable(pinfo->cinfo, -1, false);
981
982
50
    return afterwelcome;
983
29
}
984
985
/**
986
*   Dissect a tvbuff containing JXTA Message framing.
987
*
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.
998
**/
999
static int dissect_jxta_message_framing(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, uint64_t * content_length,
1000
                                        char ** content_type)
1001
2.76k
{
1002
2.76k
    unsigned offset = 0;
1003
2.76k
    unsigned available;
1004
2.76k
    int needed = 0;
1005
1006
    /*
1007
     *   First go around. Make sure all of the bytes are there.
1008
     */
1009
3.03k
    do {
1010
3.03k
        uint8_t headername_len;
1011
3.03k
        uint8_t headername_offset;
1012
3.03k
        uint16_t headervalue_len;
1013
3.03k
        uint16_t headervalue_offset;
1014
1015
3.03k
        available = tvb_reported_length_remaining(tvb, offset);
1016
3.03k
        if (available < 1) {
1017
6
            needed = 1;
1018
6
            break;
1019
3.03k
        } else {
1020
3.03k
            headername_len = tvb_get_uint8(tvb, offset);
1021
3.03k
            offset++;
1022
3.03k
            headername_offset = offset;
1023
1024
3.03k
            available = tvb_reported_length_remaining(tvb, offset);
1025
3.03k
            if (available < headername_len) {
1026
1.25k
                needed = (int) (headername_len - available);
1027
1.25k
                break;
1028
1.25k
            }
1029
1030
1.77k
            if (0 == headername_len) {
1031
674
                break;
1032
674
            }
1033
1.10k
            offset += headername_len;
1034
1.10k
        }
1035
1036
1.10k
        available = tvb_reported_length_remaining(tvb, offset);
1037
1.10k
        if (available < 2) {
1038
20
            needed = (int) (2 - available);
1039
20
            break;
1040
1.08k
        } else {
1041
1.08k
            headervalue_len = tvb_get_ntohs(tvb, offset);
1042
1.08k
            offset += 2;
1043
1.08k
            headervalue_offset = offset;
1044
1045
1.08k
            available = tvb_reported_length_remaining(tvb, offset);
1046
1.08k
            if (available < headervalue_len) {
1047
809
                needed = (int) (headervalue_len - available);
1048
809
                break;
1049
809
            }
1050
1051
272
            offset += headervalue_len;
1052
272
        }
1053
1054
272
        if (content_type && (sizeof("content-type") - 1) == headername_len) {
1055
8
            if (0 == tvb_strncaseeql(tvb, headername_offset, "content-type", sizeof("content-type") - 1)) {
1056
0
                *content_type = (char*)tvb_get_string_enc(pinfo->pool, tvb, headervalue_offset, headervalue_len, ENC_ASCII);
1057
0
            }
1058
8
        }
1059
1060
1061
272
        if (content_length && (sizeof(uint64_t) == headervalue_len) && ((sizeof("content-length") - 1) == headername_len)) {
1062
1
            if (0 == tvb_strncaseeql(tvb, headername_offset, "content-length", sizeof("content-length") - 1)) {
1063
0
                *content_length = tvb_get_ntoh64(tvb, headervalue_offset);
1064
0
            }
1065
1
        }
1066
2.76k
    } while (true);
1067
1068
2.76k
    if ((needed > 0) && gDESEGMENT && pinfo->can_desegment) {
1069
        /* ws_message( "Framing requesting %d more bytes", needed ); */
1070
0
        pinfo->desegment_offset = 0;
1071
0
        pinfo->desegment_len = needed;
1072
0
        return -needed;
1073
0
    }
1074
1075
    /*
1076
     *   Second (optional pass) Now that we are sure that all the bytes are there we update the protocol tree.
1077
     */
1078
2.76k
    if (tree) {
1079
0
        unsigned tree_offset = 0;
1080
0
        proto_item *framing_tree_item;
1081
0
        proto_tree *framing_tree;
1082
1083
0
        framing_tree_item =
1084
0
            proto_tree_add_none_format(tree, hf_jxta_framing, tvb, tree_offset, -1, "JXTA Message Framing Headers");
1085
0
        framing_tree = proto_item_add_subtree(framing_tree_item, ett_jxta_framing);
1086
1087
        /* parse framing headers */
1088
0
        do {
1089
0
            uint8_t headernamelen = tvb_get_uint8(tvb, tree_offset);
1090
0
            proto_item *framing_header_tree_item =
1091
0
                proto_tree_add_item(framing_tree, hf_jxta_framing_header, tvb, tree_offset, -1, ENC_NA);
1092
0
            proto_tree *framing_header_tree = proto_item_add_subtree(framing_header_tree_item, ett_jxta_framing_header);
1093
1094
            /*
1095
             *   Put header name into the protocol tree
1096
             */
1097
0
            proto_tree_add_item(framing_header_tree, hf_jxta_framing_header_name, tvb, tree_offset, (int)sizeof(int8_t), ENC_ASCII|ENC_BIG_ENDIAN);
1098
1099
            /*
1100
             *   Append header name into the header protocol item. It's a nice hint so you don't have to reveal all headers.
1101
             */
1102
0
            if (headernamelen > 0) {
1103
0
                proto_item_append_text(framing_header_tree_item, " \"%s\"",
1104
0
                                       tvb_format_text(pinfo->pool, tvb, tree_offset + 1, headernamelen));
1105
0
            }
1106
1107
0
            tree_offset += 1 + headernamelen;
1108
1109
0
            if (headernamelen > 0) {
1110
0
                uint16_t headervaluelen = tvb_get_ntohs(tvb, tree_offset);
1111
1112
0
                if (tree) {
1113
0
                    proto_tree_add_uint(framing_header_tree, hf_jxta_framing_header_value_length, tvb, tree_offset,
1114
0
                                        2, headervaluelen);
1115
1116
                    /** TODO bondolo Add specific handling for known header types */
1117
1118
                    /*
1119
                     * Put header value into protocol tree.
1120
                     */
1121
0
                    proto_tree_add_item(framing_header_tree, hf_jxta_framing_header_value, tvb, tree_offset + 2,
1122
0
                                        headervaluelen, ENC_NA);
1123
0
                }
1124
1125
0
                tree_offset += 2 + headervaluelen;
1126
0
            }
1127
1128
0
            proto_item_set_end(framing_header_tree_item, tvb, tree_offset);
1129
1130
0
            if (0 == headernamelen) {
1131
0
                break;
1132
0
            }
1133
0
        } while (true);
1134
1135
0
        proto_item_set_end(framing_tree_item, tvb, tree_offset);
1136
1137
0
        DISSECTOR_ASSERT(offset == tree_offset);
1138
0
    }
1139
1140
    /* return how many bytes we used up. */
1141
2.76k
    return offset;
1142
2.76k
}
1143
1144
/**
1145
*   Dissect a tvbuff containing one or more JXTA Messages.
1146
*
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.
1153
**/
1154
static int dissect_jxta_message(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void * data _U_)
1155
0
{
1156
0
    int complete_messages = 0;
1157
0
    unsigned offset = 0;
1158
0
    unsigned tree_offset = 0;
1159
0
    unsigned available;
1160
0
    int needed = 0;
1161
0
    wmem_strbuf_t* src_addr;
1162
0
    wmem_strbuf_t* dst_addr;
1163
1164
0
    while (true) {
1165
0
        uint8_t message_version;
1166
0
        unsigned message_start_offset = offset;
1167
1168
        /* First pass. Make sure all of the bytes we need are available */
1169
0
        available = tvb_reported_length_remaining(tvb, offset);
1170
1171
0
        if((0 == available) && (0 != complete_messages)) {
1172
            /* We have discovered all of the complete messages in the tvbuff. */
1173
0
            break;
1174
0
        }
1175
1176
0
        if (available < sizeof(JXTA_MSG_SIG)) {
1177
0
            needed = (int) (sizeof(JXTA_MSG_SIG) - available);
1178
0
            break;
1179
0
        }
1180
1181
0
        if (tvb_memeql(tvb, offset, (const uint8_t*)JXTA_MSG_SIG, sizeof(JXTA_MSG_SIG)) != 0) {
1182
            /* It is not one of ours */
1183
0
            return 0;
1184
0
        }
1185
1186
0
        offset += (int)sizeof(JXTA_MSG_SIG);
1187
1188
0
        available = tvb_reported_length_remaining(tvb, offset);
1189
0
        if (available < 1) {
1190
0
            needed = 1;
1191
0
            break;
1192
0
        } else {
1193
0
            message_version = tvb_get_uint8(tvb, offset);
1194
1195
0
            offset++;
1196
1197
0
            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. */
1199
0
                return 0;
1200
0
            }
1201
0
        }
1202
1203
        /* Read the flags (Version 2 and later) */
1204
0
        if(message_version > 0) {
1205
0
            available = tvb_reported_length_remaining(tvb, offset);
1206
0
            if (available < 1) {
1207
0
                needed = 1;
1208
0
                break;
1209
0
            } else {
1210
0
                offset++;
1211
0
            }
1212
0
        }
1213
1214
        /* Read names table */
1215
0
        available = tvb_reported_length_remaining(tvb, offset);
1216
0
        if (available < 2) {
1217
0
            needed = (int) (2 - available);
1218
0
            break;
1219
0
        } else {
1220
0
            uint16_t msg_names_count = tvb_get_ntohs(tvb, offset);
1221
0
            unsigned each_name;
1222
1223
0
            offset += 2;
1224
1225
0
            for (each_name = 0; each_name < msg_names_count; each_name++) {
1226
0
                uint16_t name_len;
1227
1228
0
                available = tvb_reported_length_remaining(tvb, offset);
1229
0
                if (available < sizeof(name_len)) {
1230
0
                    needed = (int) (sizeof(name_len) - available);
1231
0
                    break;
1232
0
                }
1233
1234
0
                name_len = tvb_get_ntohs(tvb, offset);
1235
1236
0
                available = tvb_reported_length_remaining(tvb, offset + (int)sizeof(name_len));
1237
0
                if (available < name_len) {
1238
0
                    needed = (int) (name_len - available);
1239
0
                    break;
1240
0
                }
1241
1242
0
                offset += (int)sizeof(name_len) + name_len;
1243
0
            }
1244
0
        }
1245
1246
        /* parse element count */
1247
0
        available = tvb_reported_length_remaining(tvb, offset);
1248
0
        if (available < 2) {
1249
0
            needed = (int) (2 - available);
1250
0
            break;
1251
0
        } else {
1252
0
            uint16_t elem_count = tvb_get_ntohs(tvb, offset);
1253
0
            unsigned each_elem;
1254
1255
0
            offset += 2;
1256
1257
            /* parse elements */
1258
0
            for (each_elem = 0; each_elem < elem_count; each_elem++) {
1259
0
                tvbuff_t *jxta_message_element_tvb = tvb_new_subset_remaining(tvb, offset);
1260
0
                int processed;
1261
1262
0
                if (JXTA_MSG_VERSION_1 == message_version) {
1263
0
                    processed = dissect_jxta_message_element_1(jxta_message_element_tvb, pinfo, NULL, 0, NULL);
1264
0
                } else { /* JXTA_MSG_VERSION_2 */
1265
0
                    processed = dissect_jxta_message_element_2(jxta_message_element_tvb, pinfo, NULL, 0, NULL);
1266
0
                }
1267
1268
0
                if (processed < 0) {
1269
0
                    needed = -processed;
1270
0
                    break;
1271
0
                }
1272
1273
0
                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 );
1283
                     */
1284
0
                    return 0;
1285
0
                }
1286
1287
0
                offset += processed;
1288
0
            }
1289
0
        }
1290
1291
0
        if ((uri_address_type == pinfo->src.type) && (uri_address_type == pinfo->dst.type)) {
1292
0
            jxta_tap_header *tap_header = wmem_new(wmem_file_scope(), jxta_tap_header);
1293
1294
0
            copy_address_shallow(&tap_header->src_address, &pinfo->src);
1295
0
            copy_address_shallow(&tap_header->dest_address, &pinfo->dst);
1296
0
            tap_header->size = offset - message_start_offset ;
1297
1298
0
            tap_queue_packet(jxta_tap, pinfo, tap_header);
1299
0
        }
1300
1301
0
        complete_messages++;
1302
1303
        /* ws_message( "%d Scanned message #%d: ", pinfo->num, complete_messages ); */
1304
0
    }
1305
1306
0
    if ((needed > 0) && gDESEGMENT && pinfo->can_desegment) {
1307
        /* ws_message("Frame %d: Message requesting %d more bytes", pinfo->num, needed); */
1308
0
        pinfo->desegment_offset = 0;
1309
0
        pinfo->desegment_len = needed;
1310
0
        return -needed;
1311
0
    }
1312
1313
0
    src_addr = wmem_strbuf_create(pinfo->pool);
1314
0
    wmem_strbuf_append(src_addr, address_to_str(pinfo->pool, &pinfo->src));
1315
0
    dst_addr = wmem_strbuf_create(pinfo->pool);
1316
0
    wmem_strbuf_append(dst_addr, address_to_str(pinfo->pool, &pinfo->dst));
1317
1318
    /* append the port if appropriate */
1319
0
    if (PT_NONE != pinfo->ptype) {
1320
0
        wmem_strbuf_append_printf(src_addr, ":%d", pinfo->srcport);
1321
0
        wmem_strbuf_append_printf(dst_addr, ":%d", pinfo->destport);
1322
0
    }
1323
1324
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "JXTA");
1325
1326
0
    if( complete_messages > 1 ) {
1327
0
        col_add_fstr(pinfo->cinfo, COL_INFO, "%d Messages, %s -> %s", complete_messages,
1328
0
                     wmem_strbuf_get_str(src_addr), wmem_strbuf_get_str(dst_addr));
1329
0
    } else {
1330
0
        col_add_fstr(pinfo->cinfo, COL_INFO, "Message, %s -> %s",
1331
0
                     wmem_strbuf_get_str(src_addr), wmem_strbuf_get_str(dst_addr));
1332
0
    }
1333
1334
0
    col_set_writable(pinfo->cinfo, -1, false);
1335
1336
0
    while( tree && (complete_messages > 0) ) {
1337
0
        proto_item *jxta_msg_tree_item = NULL;
1338
0
        proto_tree *jxta_msg_tree = NULL;
1339
0
        uint8_t message_version;
1340
0
        const char **names_table = NULL;
1341
0
        uint16_t msg_names_count;
1342
0
        unsigned each_name;
1343
0
        uint16_t elem_count;
1344
0
        unsigned each_elem;
1345
0
        proto_item *tree_item;
1346
1347
0
        jxta_msg_tree_item = proto_tree_add_protocol_format(tree, proto_message_jxta, tvb, tree_offset, -1,
1348
0
                                                            "JXTA Message, %s -> %s", wmem_strbuf_get_str(src_addr),
1349
0
                                                            wmem_strbuf_get_str(dst_addr));
1350
1351
0
        jxta_msg_tree = proto_item_add_subtree(jxta_msg_tree_item, ett_jxta_msg);
1352
1353
0
        proto_tree_add_item(jxta_msg_tree, hf_jxta_message_sig, tvb, tree_offset, (int)sizeof(JXTA_MSG_SIG), ENC_ASCII);
1354
0
        tree_offset += (int)sizeof(JXTA_MSG_SIG);
1355
1356
0
        tree_item = proto_tree_add_string(jxta_msg_tree, hf_jxta_message_src, tvb, 0, 0, wmem_strbuf_get_str(src_addr));
1357
0
        proto_item_set_generated(tree_item);
1358
1359
0
        tree_item = proto_tree_add_string(jxta_msg_tree, hf_jxta_message_address, tvb, 0, 0, wmem_strbuf_get_str(src_addr));
1360
0
        proto_item_set_hidden(tree_item);
1361
0
        proto_item_set_generated(tree_item);
1362
1363
0
        if(uri_address_type == pinfo->src.type) {
1364
0
            tree_item = proto_tree_add_string(jxta_msg_tree, hf_uri_src, tvb, 0, 0, wmem_strbuf_get_str(src_addr));
1365
0
            proto_item_set_hidden(tree_item);
1366
0
            proto_item_set_generated(tree_item);
1367
0
            tree_item = proto_tree_add_string(jxta_msg_tree, hf_uri_addr, tvb, 0, 0, wmem_strbuf_get_str(src_addr));
1368
0
            proto_item_set_hidden(tree_item);
1369
0
            proto_item_set_generated(tree_item);
1370
0
        }
1371
1372
0
        tree_item = proto_tree_add_string(jxta_msg_tree, hf_jxta_message_dst, tvb, 0, 0, wmem_strbuf_get_str(dst_addr));
1373
0
        proto_item_set_generated(tree_item);
1374
1375
0
        tree_item = proto_tree_add_string(jxta_msg_tree, hf_jxta_message_address, tvb, 0, 0, wmem_strbuf_get_str(dst_addr));
1376
0
        proto_item_set_hidden(tree_item);
1377
0
        proto_item_set_generated(tree_item);
1378
1379
0
        if(uri_address_type == pinfo->dst.type) {
1380
0
            tree_item = proto_tree_add_string(jxta_msg_tree, hf_uri_dst, tvb, 0, 0, wmem_strbuf_get_str(dst_addr));
1381
0
            proto_item_set_hidden(tree_item);
1382
0
            proto_item_set_generated(tree_item);
1383
0
            tree_item = proto_tree_add_string(jxta_msg_tree, hf_uri_addr, tvb, 0, 0, wmem_strbuf_get_str(dst_addr));
1384
0
            proto_item_set_hidden(tree_item);
1385
0
            proto_item_set_generated(tree_item);
1386
0
        }
1387
1388
0
        message_version = tvb_get_uint8(tvb, tree_offset);
1389
0
        proto_tree_add_uint(jxta_msg_tree, hf_jxta_message_version, tvb, tree_offset, 1, message_version);
1390
0
        tree_offset += 1;
1391
1392
0
        if( message_version > 0 ) {
1393
0
            static int * const flags[] = {
1394
0
                &hf_jxta_message_flag_utf16be,
1395
0
                &hf_jxta_message_flag_ucs32be,
1396
0
                NULL
1397
0
            };
1398
1399
0
            proto_tree_add_bitmask(jxta_msg_tree, tvb, tree_offset, hf_jxta_message_flags, ett_jxta_msg_flags, flags, ENC_NA);
1400
0
            tree_offset += 1;
1401
0
        }
1402
1403
0
        msg_names_count = tvb_get_ntohs(tvb, tree_offset);
1404
0
        proto_tree_add_uint(jxta_msg_tree, hf_jxta_message_names_count, tvb, tree_offset, 2, msg_names_count);
1405
0
        tree_offset += 2;
1406
1407
0
        names_table = (const char **)wmem_alloc(pinfo->pool, (msg_names_count + 2) * sizeof(const char *));
1408
0
        names_table[0] = "";
1409
0
        names_table[1] = "jxta";
1410
1411
        /* parse names */
1412
0
        for (each_name = 0; each_name < msg_names_count; each_name++) {
1413
0
            uint16_t name_len = tvb_get_ntohs(tvb, tree_offset);
1414
1415
0
            names_table[2 + each_name] = (char*)tvb_get_string_enc(pinfo->pool, tvb, tree_offset + 2, name_len, ENC_ASCII);
1416
0
            proto_tree_add_item(jxta_msg_tree, hf_jxta_message_names_name, tvb, tree_offset, 2, ENC_ASCII|ENC_BIG_ENDIAN);
1417
0
            tree_offset += 2 + name_len;
1418
0
        }
1419
1420
        /* parse element count */
1421
0
        elem_count = tvb_get_ntohs(tvb, tree_offset);
1422
0
        proto_tree_add_item(jxta_msg_tree, hf_jxta_message_element_count, tvb, tree_offset, 2, ENC_BIG_ENDIAN);
1423
0
        tree_offset += 2;
1424
1425
        /* FIXME bondolo Element count 0 (Process elements until FIN) should be supported. */
1426
1427
        /* parse elements */
1428
0
        for (each_elem = 0; each_elem < elem_count; each_elem++) {
1429
0
            tvbuff_t *jxta_message_element_tvb = tvb_new_subset_remaining(tvb, tree_offset);
1430
1431
0
            if(JXTA_MSG_VERSION_1 == message_version) {
1432
0
                tree_offset +=
1433
0
                    dissect_jxta_message_element_1(jxta_message_element_tvb, pinfo, jxta_msg_tree, msg_names_count + 2, names_table);
1434
0
            } else if(JXTA_MSG_VERSION_2 == message_version) {
1435
0
                tree_offset +=
1436
0
                    dissect_jxta_message_element_2(jxta_message_element_tvb, pinfo, jxta_msg_tree, msg_names_count + 2, names_table);
1437
0
            } else {
1438
                /* Sort of a lie, we say that we don't recognize it at all. */
1439
0
                return 0;
1440
0
            }
1441
0
       }
1442
1443
0
       proto_item_set_end(jxta_msg_tree_item, tvb, tree_offset);
1444
1445
0
       complete_messages--;
1446
0
    }
1447
1448
0
    if( tree ) {
1449
        /* ws_message( "%d tvb offset : %d  tree offset : %d", pinfo->num, offset, tree_offset ); */
1450
0
        DISSECTOR_ASSERT(tree_offset == offset);
1451
0
    }
1452
1453
0
    return offset;
1454
0
}
1455
1456
/**
1457
*   Dissect a tvbuff containing a JXTA Message Element (Version 1).
1458
*
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.
1465
**/
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)
1469
0
{
1470
0
    unsigned offset = 0;
1471
0
    unsigned available;
1472
0
    int needed = 0;
1473
0
    uint8_t flags;
1474
1475
    /* First pass. Make sure all of the bytes we need are available */
1476
1477
0
    while (true) {
1478
        /* signature field */
1479
0
        available = tvb_reported_length_remaining(tvb, offset);
1480
0
        if (available < sizeof(JXTA_MSGELEM_SIG)) {
1481
0
            needed = (int) (sizeof(JXTA_MSGELEM_SIG) - available);
1482
0
        }
1483
1484
0
        if (tvb_memeql(tvb, offset, (const uint8_t*)JXTA_MSGELEM_SIG, sizeof(JXTA_MSGELEM_SIG)) != 0) {
1485
            /* It is not one of ours */
1486
0
            return 0;
1487
0
        }
1488
1489
0
        offset += (int)sizeof(JXTA_MSGELEM_SIG);
1490
1491
        /* namespace id field */
1492
0
        available = tvb_reported_length_remaining(tvb, offset);
1493
0
        if (available < 1) {
1494
0
            needed = 1;
1495
0
            break;
1496
0
        }
1497
1498
0
        offset++;
1499
1500
        /* flags field */
1501
0
        available = tvb_reported_length_remaining(tvb, offset);
1502
0
        if (available < 1) {
1503
0
            needed = 1;
1504
0
            break;
1505
0
        } else {
1506
0
            flags = tvb_get_uint8(tvb, offset);
1507
0
            offset++;
1508
0
        }
1509
1510
        /* name field */
1511
0
        available = tvb_reported_length_remaining(tvb, offset);
1512
0
        if (available < 2) {
1513
0
            needed = (int) (2 - available);
1514
0
            break;
1515
0
        } else {
1516
0
            uint16_t name_len = tvb_get_ntohs(tvb, offset);
1517
0
            offset += 2;
1518
1519
0
            available = tvb_reported_length_remaining(tvb, offset);
1520
0
            if (available < name_len) {
1521
0
                needed = (int) (name_len - available);
1522
0
                break;
1523
0
            }
1524
1525
0
            offset += name_len;
1526
0
        }
1527
1528
        /* type field */
1529
0
        if ((flags & JXTAMSG1_ELMFLAG_TYPE) != 0) {
1530
0
            uint16_t type_len;
1531
1532
0
            available = tvb_reported_length_remaining(tvb, offset);
1533
0
            if (available < 2) {
1534
0
                needed = (int) (2 - available);
1535
0
                break;
1536
0
            }
1537
1538
0
            type_len = tvb_get_ntohs(tvb, offset);
1539
0
            offset += 2;
1540
1541
0
            available = tvb_reported_length_remaining(tvb, offset);
1542
0
            if (available < type_len) {
1543
0
                needed = (int) (type_len - available);
1544
0
                break;
1545
0
            }
1546
1547
0
            offset += type_len;
1548
0
        }
1549
1550
        /* encoding field */
1551
0
        if ((flags & JXTAMSG1_ELMFLAG_ENCODING) != 0) {
1552
0
            uint16_t encoding_len;
1553
1554
0
            available = tvb_reported_length_remaining(tvb, offset);
1555
0
            if (available < 2) {
1556
0
                needed = (int) (2 - available);
1557
0
                break;
1558
0
            }
1559
1560
0
            encoding_len = tvb_get_ntohs(tvb, offset);
1561
0
            offset += 2;
1562
1563
0
            available = tvb_reported_length_remaining(tvb, offset);
1564
0
            if (available < encoding_len) {
1565
0
                needed = (int) (encoding_len - available);
1566
0
                break;
1567
0
            }
1568
1569
0
            offset += encoding_len;
1570
0
        }
1571
1572
        /* content field */
1573
0
        available = tvb_reported_length_remaining(tvb, offset);
1574
0
        if (available < 2) {
1575
0
            needed = (int) (2 - available);
1576
0
            break;
1577
0
        } else {
1578
0
            uint32_t content_len = tvb_get_ntohl(tvb, offset);
1579
0
            offset += 4;
1580
1581
0
            available = tvb_reported_length_remaining(tvb, offset);
1582
0
            if (available < content_len) {
1583
0
                needed = (int) (content_len - available);
1584
0
                break;
1585
0
            }
1586
1587
0
            offset += content_len;
1588
0
        }
1589
1590
        /* signature element field */
1591
0
        if ((flags & JXTAMSG1_ELMFLAG_SIGNATURE) != 0) {
1592
0
            tvbuff_t *jxta_signature_element_tvb;
1593
0
            int processed;
1594
1595
0
            jxta_signature_element_tvb = tvb_new_subset_remaining(tvb, offset);
1596
1597
0
            increment_dissection_depth(pinfo);
1598
0
            processed = dissect_jxta_message_element_1(jxta_signature_element_tvb, pinfo, NULL, 0, NULL);
1599
0
            decrement_dissection_depth(pinfo);
1600
1601
0
            if (processed == 0) {
1602
0
                return offset;
1603
0
            }
1604
1605
0
            if (processed < 0) {
1606
0
                needed = -processed;
1607
0
                break;
1608
0
            }
1609
1610
0
            offset += processed;
1611
0
        }
1612
1613
0
        break;
1614
0
    }
1615
1616
0
    if ((needed > 0) && gDESEGMENT && pinfo->can_desegment) {
1617
        /* ws_message( "Element1 requesting %d more bytes", needed ); */
1618
0
        pinfo->desegment_offset = 0;
1619
0
        pinfo->desegment_len = needed;
1620
0
        return -needed;
1621
0
    }
1622
1623
    /* Second pass : build the proto tree */
1624
0
    unsigned tree_offset = 0;
1625
0
    proto_item *jxta_elem_tree_item = proto_tree_add_item(tree, hf_jxta_element, tvb, tree_offset, -1, ENC_NA);
1626
0
    proto_tree *jxta_elem_tree = proto_item_add_subtree(jxta_elem_tree_item, ett_jxta_elem);
1627
0
    uint8_t namespaceID;
1628
0
    proto_item *namespace_ti;
1629
0
    uint16_t name_len;
1630
0
    uint32_t content_len;
1631
0
    char *mediatype = NULL;
1632
0
    tvbuff_t *element_content_tvb;
1633
0
    static int * const element_flags[] = {
1634
0
        &hf_jxta_element1_flag_hasType,
1635
0
        &hf_jxta_element1_flag_hasEncoding,
1636
0
        &hf_jxta_element1_flag_hasSignature,
1637
0
        NULL
1638
0
    };
1639
1640
0
    proto_tree_add_item(jxta_elem_tree, hf_jxta_element_sig, tvb, tree_offset, (int)sizeof(JXTA_MSGELEM_SIG), ENC_ASCII);
1641
0
    tree_offset += (int)sizeof(JXTA_MSGELEM_SIG);
1642
1643
0
    namespaceID = tvb_get_uint8(tvb, tree_offset);
1644
0
    namespace_ti =
1645
0
        proto_tree_add_uint(jxta_elem_tree, hf_jxta_element1_namespaceid, tvb, tree_offset, 1, namespaceID);
1646
0
    if (namespaceID < ns_count) {
1647
0
        proto_item_append_text(namespace_ti, " (%s)", names_table[namespaceID]);
1648
0
    } else {
1649
0
        proto_item_append_text(namespace_ti, " * BAD *");
1650
0
    }
1651
0
    tree_offset += 1;
1652
1653
0
    flags = tvb_get_uint8(tvb, tree_offset);
1654
0
    proto_tree_add_bitmask(jxta_elem_tree, tvb, tree_offset, hf_jxta_element_flags, ett_jxta_elem_1_flags, element_flags, ENC_NA);
1655
0
    tree_offset += 1;
1656
1657
0
    name_len = tvb_get_ntohs(tvb, tree_offset);
1658
0
    proto_item_append_text(jxta_elem_tree_item, " \"%s\"", tvb_format_text(pinfo->pool, tvb, tree_offset + 2, name_len));
1659
0
    proto_tree_add_item(jxta_elem_tree, hf_jxta_element_name, tvb, tree_offset, 2, ENC_ASCII|ENC_BIG_ENDIAN);
1660
0
    tree_offset += 2 + name_len;
1661
1662
    /* process type */
1663
0
    if ((flags & JXTAMSG1_ELMFLAG_TYPE) != 0) {
1664
0
        uint16_t type_len = tvb_get_ntohs(tvb, tree_offset);
1665
0
        proto_tree_add_item(jxta_elem_tree, hf_jxta_element_type, tvb, tree_offset, 2, ENC_ASCII|ENC_BIG_ENDIAN);
1666
0
        tree_offset += 2;
1667
1668
0
        mediatype = (char*)tvb_get_string_enc(pinfo->pool, tvb, tree_offset, type_len, ENC_ASCII);
1669
1670
0
        tree_offset += type_len;
1671
0
    }
1672
1673
    /* process encoding */
1674
0
    if ((flags & JXTAMSG1_ELMFLAG_ENCODING) != 0) {
1675
0
        uint16_t encoding_len = tvb_get_ntohs(tvb, tree_offset);
1676
0
        proto_tree_add_item(jxta_elem_tree, hf_jxta_element_encoding, tvb, tree_offset, 2, ENC_ASCII|ENC_BIG_ENDIAN);
1677
0
        tree_offset += 2 + encoding_len;
1678
0
    }
1679
1680
    /* content */
1681
0
    content_len = tvb_get_ntohl(tvb, tree_offset);
1682
0
    proto_tree_add_item(jxta_elem_tree, hf_jxta_element_content_len, tvb, tree_offset, 4, ENC_BIG_ENDIAN);
1683
0
    tree_offset += 4;
1684
1685
0
    element_content_tvb = tvb_new_subset_length(tvb, tree_offset, content_len);
1686
1687
0
    tree_offset += dissect_media(mediatype, element_content_tvb, pinfo, jxta_elem_tree);
1688
1689
    /* process the signature element */
1690
0
    if ((flags & JXTAMSG1_ELMFLAG_SIGNATURE) != 0) {
1691
0
        tvbuff_t *jxta_message_element_tvb = tvb_new_subset_remaining(tvb, tree_offset);
1692
1693
0
        increment_dissection_depth(pinfo);
1694
0
        tree_offset += dissect_jxta_message_element_1(jxta_message_element_tvb, pinfo, jxta_elem_tree, ns_count, names_table);
1695
0
        decrement_dissection_depth(pinfo);
1696
0
    }
1697
1698
0
    proto_item_set_end(jxta_elem_tree_item, tvb, tree_offset);
1699
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);
1703
1704
0
    return offset;
1705
0
}
1706
1707
/**
1708
*   Dissect a tvbuff containing a JXTA Message Element (Version 2).
1709
*
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.
1718
**/
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)
1722
0
{
1723
0
    unsigned offset = 0;
1724
0
    unsigned available;
1725
0
    int needed = 0;
1726
0
    uint8_t flags;
1727
1728
    /* First pass. Make sure all of the bytes we need are available */
1729
1730
0
    while (true) {
1731
        /* signature field */
1732
0
        available = tvb_reported_length_remaining(tvb, offset);
1733
0
        if (available < sizeof(JXTA_MSGELEM_SIG)) {
1734
0
            needed = (int) (sizeof(JXTA_MSGELEM_SIG) - available);
1735
0
        }
1736
1737
0
        if (tvb_memeql(tvb, offset, (const uint8_t*)JXTA_MSGELEM_SIG, sizeof(JXTA_MSGELEM_SIG)) != 0) {
1738
            /* It is not one of ours */
1739
0
            return 0;
1740
0
        }
1741
1742
0
        offset += (int)sizeof(JXTA_MSGELEM_SIG);
1743
1744
        /* flags field */
1745
0
        available = tvb_reported_length_remaining(tvb, offset);
1746
0
        if (available < 1) {
1747
0
            needed = 1;
1748
0
            break;
1749
0
        } else {
1750
0
            flags = tvb_get_uint8(tvb, offset);
1751
0
            offset++;
1752
0
        }
1753
1754
        /* namespace id field */
1755
0
        available = tvb_reported_length_remaining(tvb, offset);
1756
0
        if (available < 2) {
1757
0
            needed = (int) (2 - available);
1758
0
            break;
1759
0
        }
1760
1761
0
        offset += 2;
1762
1763
        /* name field */
1764
0
        if ((flags & JXTAMSG2_ELMFLAG_NAME_LITERAL) == 0) {
1765
0
            available = tvb_reported_length_remaining(tvb, offset);
1766
0
            if (available < 2) {
1767
0
                needed = (int) (2 - available);
1768
0
                break;
1769
0
            }
1770
1771
0
            offset += 2;
1772
0
        } else {
1773
            /* literal name field */
1774
0
            available = tvb_reported_length_remaining(tvb, offset);
1775
0
            if (available < 2) {
1776
0
                needed = (int) (2 - available);
1777
0
                break;
1778
0
            } else {
1779
0
                uint16_t name_len = tvb_get_ntohs(tvb, offset);
1780
0
                offset += 2;
1781
1782
0
                available = tvb_reported_length_remaining(tvb, offset);
1783
0
                if (available < name_len) {
1784
0
                    needed = (int) (name_len - available);
1785
0
                    break;
1786
0
                }
1787
1788
0
                offset += name_len;
1789
0
            }
1790
0
        }
1791
1792
        /* type field */
1793
0
        if ((flags & JXTAMSG2_ELMFLAG_TYPE) != 0) {
1794
0
            available = tvb_reported_length_remaining(tvb, offset);
1795
0
            if (available < 2) {
1796
0
                needed = (int) (2 - available);
1797
0
                break;
1798
0
            }
1799
1800
0
            offset += 2;
1801
0
        }
1802
1803
        /* encoding field */
1804
0
        if ((flags & JXTAMSG2_ELMFLAG_ENCODINGS) != 0) {
1805
0
            available = tvb_reported_length_remaining(tvb, offset);
1806
0
            if (available < 2) {
1807
0
                needed = (int) (2 - available);
1808
0
                break;
1809
0
            }
1810
1811
0
            offset += 2;
1812
0
        }
1813
1814
1815
        /* content field */
1816
0
        if ((flags & JXTAMSG2_ELMFLAG_UINT64_LENS) != 0) {
1817
0
            available = tvb_reported_length_remaining(tvb, offset);
1818
0
            if (available < sizeof(uint64_t)) {
1819
0
                needed = (int) (sizeof(uint64_t) - available);
1820
0
                break;
1821
0
            } else {
1822
0
                uint64_t content_len = tvb_get_ntoh64(tvb, offset);
1823
0
                offset += (int)sizeof(uint64_t);
1824
1825
0
                available = tvb_reported_length_remaining(tvb, offset);
1826
0
                if (available < content_len) {
1827
0
                    needed = (int) (content_len - available);
1828
0
                    break;
1829
0
                }
1830
1831
0
                offset += (unsigned) content_len;
1832
0
            }
1833
0
        } else {
1834
0
            available = tvb_reported_length_remaining(tvb, offset);
1835
0
            if (available < 4) {
1836
0
                needed = (int) (4 - available);
1837
0
                break;
1838
0
            } else {
1839
0
                uint64_t content_len = tvb_get_ntohl(tvb, offset);
1840
0
                offset += 4;
1841
1842
0
                available = tvb_reported_length_remaining(tvb, offset);
1843
0
                if (available < content_len) {
1844
0
                    needed = (int) (content_len - available);
1845
0
                    break;
1846
0
                }
1847
1848
0
                offset += (unsigned) content_len;
1849
0
            }
1850
0
        }
1851
1852
        /* signature element field */
1853
0
        if ((flags & JXTAMSG2_ELMFLAG_SIGNATURE) != 0) {
1854
0
            tvbuff_t *jxta_signature_element_tvb;
1855
0
            int processed;
1856
1857
0
            jxta_signature_element_tvb = tvb_new_subset_remaining(tvb, offset);
1858
1859
0
            increment_dissection_depth(pinfo);
1860
0
            processed = dissect_jxta_message_element_2(jxta_signature_element_tvb, pinfo, NULL, 0, NULL);
1861
0
            decrement_dissection_depth(pinfo);
1862
1863
0
            if (processed == 0) {
1864
0
                return offset;
1865
0
            }
1866
1867
0
            if (processed < 0) {
1868
0
                needed = -processed;
1869
0
                break;
1870
0
            }
1871
1872
0
            offset += processed;
1873
0
        }
1874
1875
0
        break;
1876
0
    }
1877
1878
0
    if ((needed > 0) && gDESEGMENT && pinfo->can_desegment) {
1879
        /* ws_message( "Element2 requesting %d more bytes", needed ); */
1880
0
        pinfo->desegment_offset = 0;
1881
0
        pinfo->desegment_len = needed;
1882
0
        return -needed;
1883
0
    }
1884
1885
    /* Second (optional) pass : build the proto tree */
1886
0
    unsigned tree_offset = 0;
1887
0
    proto_item *jxta_elem_tree_item = proto_tree_add_item(tree, hf_jxta_element, tvb, tree_offset, -1, ENC_NA);
1888
0
    proto_tree *jxta_elem_tree = proto_item_add_subtree(jxta_elem_tree_item, ett_jxta_elem);
1889
0
    uint16_t namespaceID;
1890
0
    proto_item *namespace_ti;
1891
0
    uint16_t nameID;
1892
0
    proto_item *name_ti;
1893
0
    uint64_t content_len;
1894
0
    const char *mediatype = NULL;
1895
0
    tvbuff_t *element_content_tvb;
1896
0
    static int * const element_flags[] = {
1897
0
        &hf_jxta_element2_flag_64bitlens,
1898
0
        &hf_jxta_element2_flag_nameLiteral,
1899
0
        &hf_jxta_element2_flag_hasType,
1900
0
        &hf_jxta_element2_flag_hasSignature,
1901
0
        &hf_jxta_element2_flag_hasEncoding,
1902
0
        &hf_jxta_element2_flag_sigOfEncoded,
1903
0
        NULL
1904
0
    };
1905
1906
0
    proto_tree_add_item(jxta_elem_tree, hf_jxta_element_sig, tvb, tree_offset, (int)sizeof(JXTA_MSGELEM_SIG), ENC_ASCII);
1907
0
    tree_offset += (int)sizeof(JXTA_MSGELEM_SIG);
1908
1909
0
    flags = tvb_get_uint8(tvb, tree_offset);
1910
0
    proto_tree_add_bitmask(jxta_elem_tree, tvb, tree_offset, hf_jxta_element_flags, ett_jxta_elem_2_flags, element_flags, ENC_NA);
1911
0
    tree_offset += 1;
1912
1913
    /* Namespace */
1914
0
    namespaceID = tvb_get_ntohs(tvb, tree_offset);
1915
0
    namespace_ti =
1916
0
        proto_tree_add_uint(jxta_elem_tree, hf_jxta_element2_namespaceid, tvb, tree_offset, 2, namespaceID);
1917
0
    if (namespaceID < names_count) {
1918
0
        proto_item_append_text(namespace_ti, " (%s)", names_table[namespaceID]);
1919
0
    } else {
1920
0
        proto_item_append_text(namespace_ti, " * BAD *");
1921
0
    }
1922
0
    tree_offset += 2;
1923
1924
    /* Name */
1925
0
    if ((flags & JXTAMSG2_ELMFLAG_NAME_LITERAL) == 0) {
1926
0
        nameID = tvb_get_ntohs(tvb, tree_offset);
1927
0
        name_ti =
1928
0
            proto_tree_add_uint(jxta_elem_tree, hf_jxta_element2_nameid, tvb, tree_offset, 2, nameID);
1929
0
        if (nameID < names_count) {
1930
0
            proto_item_append_text(name_ti, " (%s)", names_table[nameID]);
1931
0
        } else {
1932
0
            proto_item_append_text(name_ti, " * BAD *");
1933
0
        }
1934
0
        tree_offset += 2;
1935
0
    } else {
1936
        /* literal name */
1937
0
        uint16_t name_len = tvb_get_ntohs(tvb, tree_offset);
1938
0
        proto_item_append_text(jxta_elem_tree_item, " \"%s\"", tvb_format_text(pinfo->pool, tvb, tree_offset + 2, name_len));
1939
0
        proto_tree_add_item(jxta_elem_tree, hf_jxta_element_name, tvb, tree_offset, 2, ENC_ASCII|ENC_BIG_ENDIAN);
1940
0
        tree_offset += 2 + name_len;
1941
0
    }
1942
1943
    /* process type */
1944
0
    if ((flags & JXTAMSG2_ELMFLAG_TYPE) != 0) {
1945
0
        uint16_t mimeID = tvb_get_ntohs(tvb, tree_offset);
1946
0
        proto_item *mime_ti =
1947
0
            proto_tree_add_uint(jxta_elem_tree, hf_jxta_element2_mimeid, tvb, tree_offset, 2, mimeID);
1948
1949
0
        if (mimeID < names_count) {
1950
0
            proto_item_append_text(mime_ti, " (%s)", names_table[mimeID]);
1951
0
            mediatype = wmem_strdup( pinfo->pool, names_table[mimeID] );
1952
0
        } else {
1953
0
            proto_item_append_text(mime_ti, " * BAD *");
1954
0
        }
1955
1956
0
        tree_offset += 2;
1957
0
    } else {
1958
0
        mediatype = "application/octet-stream";
1959
0
    }
1960
1961
    /* process encoding */
1962
0
    if ((flags & JXTAMSG2_ELMFLAG_ENCODINGS) != 0) {
1963
0
        uint16_t encodingID = tvb_get_ntohs(tvb, tree_offset);
1964
0
        proto_item *encoding_ti =
1965
0
            proto_tree_add_uint(jxta_elem_tree, hf_jxta_element2_encodingid, tvb, tree_offset, 2, encodingID);
1966
1967
0
        if (encodingID < names_count) {
1968
0
            proto_item_append_text(encoding_ti, " (%s)", names_table[encodingID]);
1969
0
        } else {
1970
0
            proto_item_append_text(encoding_ti, " * BAD *");
1971
0
        }
1972
1973
0
        tree_offset += 2;
1974
0
    }
1975
1976
1977
0
    if ((flags & JXTAMSG2_ELMFLAG_UINT64_LENS) != 0) {
1978
0
        content_len = tvb_get_ntoh64(tvb, tree_offset);
1979
0
        proto_tree_add_item(jxta_elem_tree, hf_jxta_element_content_len64, tvb, tree_offset, 8, ENC_BIG_ENDIAN);
1980
0
        tree_offset += 8;
1981
0
    } else {
1982
0
        content_len = tvb_get_ntohl(tvb, tree_offset);
1983
0
        proto_tree_add_item(jxta_elem_tree, hf_jxta_element_content_len, tvb, tree_offset, 4, ENC_BIG_ENDIAN);
1984
0
        tree_offset += 4;
1985
0
    }
1986
1987
    /* content */
1988
0
    element_content_tvb = tvb_new_subset_length(tvb, tree_offset, (int)content_len);
1989
1990
0
    tree_offset += dissect_media(mediatype, element_content_tvb, pinfo, jxta_elem_tree);
1991
1992
    /* process the signature element */
1993
0
    if ((flags & JXTAMSG2_ELMFLAG_SIGNATURE) != 0) {
1994
0
        tvbuff_t *jxta_message_element_tvb = tvb_new_subset_remaining(tvb, tree_offset);
1995
1996
0
        tree_offset += dissect_jxta_message_element_1(jxta_message_element_tvb, pinfo, jxta_elem_tree, names_count, names_table);
1997
0
    }
1998
1999
0
    proto_item_set_end(jxta_elem_tree_item, tvb, tree_offset);
2000
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);
2004
2005
0
    return offset;
2006
0
}
2007
2008
/**
2009
*   Dissect a tvbuff containing arbitrary typed data.
2010
*
2011
*   <p/>We provide special handling for type media types :
2012
*   <dl>
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>
2017
*   </dl>
2018
*
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.
2026
**/
2027
// NOLINTNEXTLINE(misc-no-recursion)
2028
0
static int dissect_media( const char* fullmediatype, tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) {
2029
0
    int dissected = 0;
2030
2031
0
    if (fullmediatype) {
2032
0
        char *mediatype = wmem_strdup(pinfo->pool, fullmediatype);
2033
0
        char *parms_at = strchr(mediatype, ';');
2034
0
        const char *save_match_string = pinfo->match_string;
2035
0
        media_content_info_t content_info = { MEDIA_CONTAINER_OTHER, NULL, NULL, NULL };
2036
2037
        /* Based upon what is done in packet-media.c we set up type and params */
2038
0
        if (NULL != parms_at) {
2039
0
            content_info.media_str = wmem_strdup( pinfo->pool, parms_at + 1 );
2040
0
            *parms_at = '\0';
2041
0
        }
2042
2043
        /* Set the version that goes to packet-media.c before converting case */
2044
0
        pinfo->match_string = wmem_strdup(pinfo->pool, mediatype);
2045
2046
        /* force to lower case */
2047
0
        ascii_strdown_inplace(mediatype);
2048
2049
0
        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
0
            if (NULL != tls_handle) {
2052
0
                dissected = call_dissector(tls_handle, tvb, pinfo, tree);
2053
0
            }
2054
0
        } else if (0 == strcmp("application/gzip", mediatype)) {
2055
0
            tvbuff_t *uncomp_tvb = tvb_child_uncompress_zlib(tvb, tvb, 0, tvb_captured_length(tvb));
2056
2057
0
            if( NULL != uncomp_tvb ) {
2058
0
                add_new_data_source(pinfo, uncomp_tvb, "Uncompressed Element Content");
2059
2060
                /* XXX bondolo 20060201 Force XML for uncompressed data. */
2061
0
                increment_dissection_depth(pinfo);
2062
0
                dissected = dissect_media("text/xml;charset=\"UTF-8\"", uncomp_tvb, pinfo, tree);
2063
0
                decrement_dissection_depth(pinfo);
2064
2065
0
                if( dissected > 0 ) {
2066
                    /* report back the uncompressed length. */
2067
0
                    dissected = tvb_captured_length(tvb);
2068
0
                }
2069
0
            }
2070
0
        } else {
2071
0
            dissected = dissector_try_string_with_data(media_type_dissector_table, mediatype, tvb, pinfo, tree, true, &content_info) ? tvb_captured_length(tvb) : 0;
2072
2073
0
            if( dissected != (int) tvb_captured_length(tvb) ) {
2074
                /* ws_message( "%s : %d expected, %d dissected", mediatype, tvb_captured_length(tvb), dissected ); */
2075
0
            }
2076
0
        }
2077
2078
0
        if (0 == dissected) {
2079
0
            dissected = call_dissector_with_data(media_handle, tvb, pinfo, tree, &content_info);
2080
0
        }
2081
2082
0
        pinfo->match_string = save_match_string;
2083
0
    }
2084
2085
0
    if(0 == dissected) {
2086
        /* display it as raw data */
2087
0
        dissected = call_data_dissector(tvb, pinfo, tree);
2088
0
    }
2089
2090
0
    if (dissected < (int) tvb_reported_length(tvb)) {
2091
0
        proto_item *item = proto_tree_add_expert(tree, pinfo, &ei_media_too_short, tvb, 0, dissected);
2092
0
        proto_item_set_generated(item);
2093
0
    }
2094
0
    return dissected;
2095
0
}
2096
2097
/**
2098
*    Register jxta protocol and jxta message protocol, header fields, subtree types, preferences.
2099
**/
2100
void proto_register_jxta(void)
2101
14
{
2102
14
    module_t *jxta_module;
2103
14
    expert_module_t *expert_jxta;
2104
2105
    /** our header fields */
2106
14
    static hf_register_info hf[] = {
2107
14
        {&hf_uri_addr,
2108
14
         {"Address", "jxta.uri.addr", FT_STRING, BASE_NONE, NULL, 0x0,
2109
14
          "URI Address (source or destination)", HFILL}
2110
14
         },
2111
14
        {&hf_uri_src,
2112
14
         {"Source", "jxta.uri.src", FT_STRING, BASE_NONE, NULL, 0x0,
2113
14
          "URI Source", HFILL}
2114
14
         },
2115
14
        {&hf_uri_dst,
2116
14
         {"Destination", "jxta.uri.dst", FT_STRING, BASE_NONE, NULL, 0x0,
2117
14
          "URI Destination", HFILL}
2118
14
         },
2119
14
        {&hf_jxta_udp,
2120
14
         {"JXTA UDP", "jxta.udp", FT_NONE, BASE_NONE, NULL, 0x0,
2121
14
          NULL, HFILL}
2122
14
         },
2123
14
        {&hf_jxta_udpsig,
2124
14
         {"Signature", "jxta.udpsig", FT_STRING, BASE_NONE, NULL, 0x0,
2125
14
          "JXTA UDP Signature", HFILL}
2126
14
         },
2127
14
        {&hf_jxta_welcome,
2128
14
         {"Welcome", "jxta.welcome", FT_NONE, BASE_NONE, NULL, 0x00,
2129
14
          "JXTA Connection Welcome Message", HFILL}
2130
14
         },
2131
14
        {&hf_jxta_welcome_initiator,
2132
14
         {"Initiator", "jxta.welcome.initiator", FT_BOOLEAN, BASE_NONE, NULL, 0x00,
2133
14
          "JXTA Connection Welcome Message Initiator", HFILL}
2134
14
         },
2135
14
        {&hf_jxta_welcome_sig,
2136
14
         {"Signature", "jxta.welcome.signature", FT_STRING, BASE_NONE, NULL, 0x0,
2137
14
          "JXTA Connection Welcome Message Signature", HFILL}
2138
14
         },
2139
14
        {&hf_jxta_welcome_destAddr,
2140
14
         {"Destination Address", "jxta.welcome.destAddr", FT_STRING, BASE_NONE, NULL, 0x0,
2141
14
          "JXTA Connection Welcome Message Destination Address", HFILL}
2142
14
         },
2143
14
        {&hf_jxta_welcome_pubAddr,
2144
14
         {"Public Address", "jxta.welcome.pubAddr", FT_STRING, BASE_NONE, NULL, 0x0,
2145
14
          "JXTA Connection Welcome Message Public Address", HFILL}
2146
14
         },
2147
14
        {&hf_jxta_welcome_peerid,
2148
14
         {"PeerID", "jxta.welcome.peerid", FT_STRING, BASE_NONE, NULL, 0x0,
2149
14
          "JXTA Connection Welcome Message PeerID", HFILL}
2150
14
         },
2151
14
        {&hf_jxta_welcome_noProp,
2152
14
         {"No Propagate Flag", "jxta.welcome.noPropFlag", FT_STRING, BASE_NONE, NULL, 0x0,
2153
14
          "JXTA Connection Welcome Message No Propagate Flag", HFILL}
2154
14
         },
2155
14
        {&hf_jxta_welcome_msgVers,
2156
14
         {"Preferred Message Version", "jxta.welcome.msgVersion", FT_STRING, BASE_NONE, NULL, 0x0,
2157
14
          "JXTA Connection Welcome Message Preferred Message Version", HFILL}
2158
14
         },
2159
14
        {&hf_jxta_welcome_variable,
2160
14
         {"Variable Parameter", "jxta.welcome.variable", FT_STRING, BASE_NONE, NULL, 0x0,
2161
14
          "JXTA Connection Welcome Message Variable Parameter", HFILL}
2162
14
         },
2163
14
        {&hf_jxta_welcome_version,
2164
14
         {"Version", "jxta.welcome.version", FT_STRING, BASE_NONE, NULL, 0x0,
2165
14
          "JXTA Connection Welcome Message Version", HFILL}
2166
14
         },
2167
14
        {&hf_jxta_framing,
2168
14
         {"Framing", "jxta.framing", FT_NONE, BASE_NONE, NULL, 0x0,
2169
14
          "JXTA Message Framing", HFILL}
2170
14
         },
2171
14
        {&hf_jxta_framing_header,
2172
14
         {"Header", "jxta.framing.header", FT_NONE, BASE_NONE, NULL, 0x0,
2173
14
          "JXTA Message Framing Header", HFILL}
2174
14
         },
2175
14
        {&hf_jxta_framing_header_name,
2176
14
         {"Name", "jxta.framing.header.name", FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2177
14
          "JXTA Message Framing Header Name", HFILL}
2178
14
         },
2179
14
        {&hf_jxta_framing_header_value_length,
2180
14
         {"Value Length", "jxta.framing.header.valuelen", FT_UINT16, BASE_DEC, NULL, 0x0,
2181
14
          "JXTA Message Framing Header Value Length", HFILL}
2182
14
         },
2183
14
        {&hf_jxta_framing_header_value,
2184
14
         {"Value", "jxta.framing.header.value", FT_BYTES, BASE_NONE, NULL, 0x0,
2185
14
          "JXTA Message Framing Header Value", HFILL}
2186
14
         },
2187
14
        {&hf_jxta_message_address,
2188
14
         {"Address", "jxta.message.address", FT_STRING, BASE_NONE, NULL, 0x0,
2189
14
          "JXTA Message Address (source or destination)", HFILL}
2190
14
         },
2191
14
        {&hf_jxta_message_src,
2192
14
         {"Source", "jxta.message.source", FT_STRING, BASE_NONE, NULL, 0x0,
2193
14
          "JXTA Message Source", HFILL}
2194
14
         },
2195
14
        {&hf_jxta_message_dst,
2196
14
         {"Destination", "jxta.message.destination", FT_STRING, BASE_NONE, NULL, 0x0,
2197
14
          "JXTA Message Destination", HFILL}
2198
14
         },
2199
14
        {&hf_jxta_message_sig,
2200
14
         {"Signature", "jxta.message.signature", FT_STRING, BASE_NONE, NULL, 0x0,
2201
14
          "JXTA Message Signature", HFILL}
2202
14
         },
2203
14
        {&hf_jxta_message_version,
2204
14
         {"Version", "jxta.message.version", FT_UINT8, BASE_DEC, NULL, 0x0,
2205
14
          "JXTA Message Version", HFILL}
2206
14
         },
2207
14
        {&hf_jxta_message_flags,
2208
14
         {"Flags", "jxta.message.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
2209
14
          "JXTA Message Flags", HFILL}
2210
14
         },
2211
14
        {&hf_jxta_message_flag_utf16be,
2212
14
         {"UTF16BE", "jxta.message.flags.UTF-16BE", FT_BOOLEAN, 2, TFS(&tfs_set_notset), 0x1,
2213
14
          "JXTA Message Element Flag -- UTF16-BE Strings", HFILL}
2214
14
         },
2215
14
        {&hf_jxta_message_flag_ucs32be,
2216
14
         {"UCS32BE", "jxta.message.flags.UCS32BE", FT_BOOLEAN, 2, TFS(&tfs_set_notset), 0x2,
2217
14
          "JXTA Message Flag -- UCS32-BE Strings", HFILL}
2218
14
         },
2219
14
        {&hf_jxta_message_names_count,
2220
14
         {"Names Count", "jxta.message.names", FT_UINT16, BASE_DEC, NULL, 0x0,
2221
14
          "JXTA Message Names Table", HFILL}
2222
14
         },
2223
14
        {&hf_jxta_message_names_name,
2224
14
         {"Names Table Name", "jxta.message.names.name", FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2225
14
          "JXTA Message Names Table Name", HFILL}
2226
14
         },
2227
14
        {&hf_jxta_message_element_count,
2228
14
         {"Element Count", "jxta.message.elements", FT_UINT16, BASE_DEC, NULL, 0x0,
2229
14
          "JXTA Message Element Count", HFILL}
2230
14
         },
2231
14
        {&hf_jxta_element,
2232
14
         {"JXTA Message Element", "jxta.message.element", FT_NONE, BASE_NONE, NULL, 0x0,
2233
14
          NULL, HFILL}
2234
14
         },
2235
14
        {&hf_jxta_element_sig,
2236
14
         {"Signature", "jxta.message.element.signature", FT_STRING, BASE_NONE, NULL, 0x0,
2237
14
          "JXTA Message Element Signature", HFILL}
2238
14
         },
2239
14
        {&hf_jxta_element1_namespaceid,
2240
14
         {"Namespace ID", "jxta.message.element.namespaceid", FT_UINT8, BASE_DEC, NULL, 0x0,
2241
14
          "JXTA Message Element Namespace ID", HFILL}
2242
14
         },
2243
14
        {&hf_jxta_element2_namespaceid,
2244
14
         {"Namespace ID", "jxta.message.element.namespaceid", FT_UINT16, BASE_DEC, NULL, 0x0,
2245
14
          "JXTA Message Element Namespace ID", HFILL}
2246
14
         },
2247
14
        {&hf_jxta_element_flags,
2248
14
         {"Flags", "jxta.message.element.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
2249
14
          "JXTA Message Element Flags", HFILL}
2250
14
         },
2251
14
        {&hf_jxta_element1_flag_hasType,
2252
14
         {"hasType", "jxta.message.element.flags.hasType", FT_BOOLEAN, 3, TFS(&tfs_set_notset), 0x1,
2253
14
          "JXTA Message Element Flag -- hasType", HFILL}
2254
14
         },
2255
14
        {&hf_jxta_element1_flag_hasEncoding,
2256
14
         {"hasEncoding", "jxta.message.element.flags.hasEncoding", FT_BOOLEAN, 3, TFS(&tfs_set_notset), 0x2,
2257
14
          "JXTA Message Element Flag -- hasEncoding", HFILL}
2258
14
         },
2259
14
        {&hf_jxta_element1_flag_hasSignature,
2260
14
         {"hasSignature", "jxta.message.element.flags.hasSignature", FT_BOOLEAN, 3, TFS(&tfs_set_notset), 0x4,
2261
14
          "JXTA Message Element Flag -- hasSignature", HFILL}
2262
14
         },
2263
14
        {&hf_jxta_element2_flag_64bitlens,
2264
14
         {"uint64Lens", "jxta.message.element.flags.uint64Lens", FT_BOOLEAN, 6, TFS(&tfs_set_notset), 0x01,
2265
14
          "JXTA Message Element Flag -- uint64Lens", HFILL}
2266
14
         },
2267
14
        {&hf_jxta_element2_flag_nameLiteral,
2268
14
         {"nameLiteral", "jxta.message.element.flags.nameLiteral", FT_BOOLEAN, 6, TFS(&tfs_set_notset), 0x02,
2269
14
          "JXTA Message Element Flag -- nameLiteral", HFILL}
2270
14
         },
2271
14
        {&hf_jxta_element2_flag_hasType,
2272
14
         {"hasType", "jxta.message.element.flags.hasType", FT_BOOLEAN, 6, TFS(&tfs_set_notset), 0x04,
2273
14
          "JXTA Message Element Flag -- hasType", HFILL}
2274
14
         },
2275
14
        {&hf_jxta_element2_flag_hasSignature,
2276
14
         {"hasSignature", "jxta.message.element.flags.hasSignature", FT_BOOLEAN, 6, TFS(&tfs_set_notset), 0x08,
2277
14
          "JXTA Message Element Flag -- hasSignature", HFILL}
2278
14
         },
2279
14
        {&hf_jxta_element2_flag_hasEncoding,
2280
14
         {"hasSignature", "jxta.message.element.flags.hasEncoding", FT_BOOLEAN, 6, TFS(&tfs_set_notset), 0x10,
2281
14
          "JXTA Message Element Flag -- hasEncoding", HFILL}
2282
14
         },
2283
14
        {&hf_jxta_element2_flag_sigOfEncoded,
2284
14
         {"sigOfEncoded", "jxta.message.element.flags.sigOfEncoded", FT_BOOLEAN, 6, TFS(&tfs_set_notset), 0x20,
2285
14
          "JXTA Message Element Flag -- sigOfEncoded", HFILL}
2286
14
         },
2287
14
        {&hf_jxta_element2_nameid,
2288
14
         {"Name ID", "jxta.message.element.nameid", FT_UINT16, BASE_DEC, NULL, 0x0,
2289
14
          "JXTA Message Element Name ID", HFILL}
2290
14
         },
2291
14
        {&hf_jxta_element_name,
2292
14
         {"Element Name", "jxta.message.element.name", FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2293
14
          "JXTA Message Element Name", HFILL}
2294
14
         },
2295
14
        {&hf_jxta_element2_mimeid,
2296
14
         {"MIME ID", "jxta.message.element.mimeid", FT_UINT16, BASE_DEC, NULL, 0x0,
2297
14
          "JXTA Message Element MIME ID", HFILL}
2298
14
         },
2299
14
        {&hf_jxta_element2_encodingid,
2300
14
         {"Encoding ID", "jxta.message.element.encodingid", FT_UINT16, BASE_DEC, NULL, 0x0,
2301
14
          "JXTA Message Element Encoding ID", HFILL}
2302
14
         },
2303
14
        {&hf_jxta_element_type,
2304
14
         {"Element Type", "jxta.message.element.type", FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2305
14
          "JXTA Message Element Name", HFILL}
2306
14
         },
2307
14
        {&hf_jxta_element_encoding,
2308
14
         {"Element Type", "jxta.message.element.encoding", FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2309
14
          "JXTA Message Element Encoding", HFILL}
2310
14
         },
2311
14
        {&hf_jxta_element_content_len,
2312
14
         {"Element Content Length", "jxta.message.element.content.length", FT_UINT32, BASE_DEC, NULL, 0x0,
2313
14
          "JXTA Message Element Content Length", HFILL}
2314
14
         },
2315
14
        {&hf_jxta_element_content_len64,
2316
14
         {"Element Content Length", "jxta.message.element.content.length64", FT_UINT64, BASE_DEC, NULL, 0x0,
2317
14
          "JXTA Message Element Content Length", HFILL}
2318
14
         },
2319
#if 0
2320
        {&hf_jxta_element_content,
2321
         {"Element Content", "jxta.message.element.content", FT_BYTES, BASE_NONE, NULL, 0x0,
2322
          "JXTA Message Element Content", HFILL}
2323
         },
2324
#endif
2325
14
    };
2326
2327
14
  static ei_register_info ei[] = {
2328
14
     { &ei_media_too_short, { "jxta.media_too_short", PI_PROTOCOL, PI_WARN, "Media length less than expected", EXPFILL }},
2329
14
  };
2330
2331
    /**
2332
    *   JXTA Protocol subtree array
2333
    **/
2334
14
    static int *ett[] = {
2335
14
        &ett_jxta,
2336
14
        &ett_jxta_welcome,
2337
14
        &ett_jxta_udp,
2338
14
        &ett_jxta_framing,
2339
14
        &ett_jxta_framing_header,
2340
14
        &ett_jxta_msg,
2341
14
        &ett_jxta_msg_flags,
2342
14
        &ett_jxta_elem,
2343
14
        &ett_jxta_elem_1_flags,
2344
14
        &ett_jxta_elem_2_flags
2345
14
    };
2346
2347
14
    proto_jxta = proto_register_protocol("JXTA P2P", "JXTA", "jxta");
2348
2349
14
    jxta_tap = register_tap("jxta");
2350
2351
14
    proto_message_jxta = proto_register_protocol("JXTA Message", "JXTA Message", "jxta.message");
2352
2353
14
    jxta_udp_handle = register_dissector("jxta.udp", dissect_jxta_udp, proto_jxta);
2354
14
    stream_jxta_handle = register_dissector("jxta.stream", dissect_jxta_stream, proto_jxta);
2355
2356
    /* Register header fields */
2357
14
    proto_register_field_array(proto_jxta, hf, array_length(hf));
2358
2359
    /* Register JXTA Sub-tree */
2360
14
    proto_register_subtree_array(ett, array_length(ett));
2361
2362
14
  expert_jxta = expert_register_protocol(proto_jxta);
2363
14
  expert_register_field_array(expert_jxta, ei, array_length(ei));
2364
2365
14
    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);
2366
2367
    /* Register preferences */
2368
    /* register re-init routine */
2369
14
    jxta_module = prefs_register_protocol(proto_jxta, proto_reg_handoff_jxta);
2370
2371
14
    prefs_register_bool_preference(jxta_module, "msg.mediatype", "Register binary JXTA Message as a media type",
2372
14
                                   "Enable to have correctly typed MIME media dissected as JXTA Messages.", &gMSG_MEDIA);
2373
2374
14
    prefs_register_bool_preference(jxta_module, "desegment",
2375
14
                                   "Reassemble JXTA messages spanning multiple UDP/TCP/SCTP segments",
2376
14
                                   "Whether the JXTA dissector should reassemble messages spanning multiple UDP/TCP/SCTP segments."
2377
14
                                   " To use this option you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings "
2378
14
                                   " and enable \"Reassemble fragmented IP datagrams\" in the IP protocol settings.",
2379
14
                                   &gDESEGMENT);
2380
2381
14
    prefs_register_obsolete_preference(jxta_module, "udp.heuristic");
2382
14
    prefs_register_obsolete_preference(jxta_module, "tcp.heuristic");
2383
14
    prefs_register_obsolete_preference(jxta_module, "sctp.heuristic");
2384
2385
14
    register_conversation_table(proto_jxta, true, jxta_conversation_packet, jxta_endpoint_packet);
2386
14
}
2387
2388
2389
/**
2390
*   Update registrations in response to preferences changes.
2391
**/
2392
void proto_reg_handoff_jxta(void)
2393
14
{
2394
14
    static bool init_done = false;
2395
14
    static dissector_handle_t message_jxta_handle;
2396
2397
14
    static bool msg_media_register_done = false;
2398
2399
14
    if(!init_done) {
2400
14
        message_jxta_handle = create_dissector_handle(dissect_jxta_message, proto_message_jxta);
2401
2402
14
        media_type_dissector_table = find_dissector_table("media_type");
2403
14
        tls_handle = find_dissector_add_dependency("tls", proto_jxta);
2404
2405
14
        media_handle = find_dissector_add_dependency("media", proto_jxta);
2406
2407
14
        heur_dissector_add("udp", dissect_jxta_UDP_heur, "JXTA over UDP", "jxta_udp", proto_jxta, HEURISTIC_ENABLE);
2408
14
        heur_dissector_add("tcp", dissect_jxta_TCP_heur, "JXTA over TCP", "jxta_tcp", proto_jxta, HEURISTIC_ENABLE);
2409
14
        heur_dissector_add("sctp", dissect_jxta_SCTP_heur, "JXTA over SCTP", "jxta_sctp", proto_jxta, HEURISTIC_ENABLE);
2410
2411
14
        init_done = true;
2412
14
        }
2413
2414
14
    if( gMSG_MEDIA ) {
2415
14
        if( !msg_media_register_done ) {
2416
            /* ws_message( "Registering JXTA Message media type" ); */
2417
14
            dissector_add_string("media_type", "application/x-jxta-msg", message_jxta_handle);
2418
14
            msg_media_register_done = true;
2419
14
            }
2420
14
    } else {
2421
0
        if( msg_media_register_done ) {
2422
            /* ws_message( "Deregistering JXTA Message media type" ); */
2423
0
            dissector_delete_string("media_type", "application/x-jxta-msg", message_jxta_handle);
2424
            msg_media_register_done = false;
2425
0
            }
2426
0
    }
2427
14
}
2428
2429
/*
2430
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2431
 *
2432
 * Local variables:
2433
 * c-basic-offset: 4
2434
 * tab-width: 8
2435
 * indent-tabs-mode: nil
2436
 * End:
2437
 *
2438
 * vi: set shiftwidth=4 tabstop=8 expandtab:
2439
 * :indentSize=4:tabSize=8:noTabs=true:
2440
 */