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-sdp.c
Line
Count
Source
1
/* packet-sdp.c
2
 * Routines for SDP packet disassembly (RFC 2327)
3
 *
4
 * Jason Lango <jal@netapp.com>
5
 * Liberally copied from packet-http.c, by Guy Harris <guy@alum.mit.edu>
6
 *
7
 * Wireshark - Network traffic analyzer
8
 * By Gerald Combs <gerald@wireshark.org>
9
 * Copyright 1998 Gerald Combs
10
 *
11
 * SPDX-License-Identifier: GPL-2.0-or-later
12
 * Ref https://www.ietf.org/rfc/rfc4566
13
 */
14
15
#include "config.h"
16
17
#include <epan/packet.h>
18
#include <epan/exceptions.h>
19
#include <epan/asn1.h>
20
#include <epan/prefs.h>
21
#include <epan/expert.h>
22
#include <epan/tap.h>
23
#include <epan/show_exception.h>
24
#include <epan/addr_resolv.h>
25
#include <epan/conversation.h>
26
#include <epan/proto_data.h>
27
#include <epan/strutil.h>
28
29
#include <wsutil/strtoi.h>
30
#include <wsutil/str_util.h>
31
#include <wsutil/array.h>
32
33
#include "packet-media-type.h"
34
#include "packet-sdp.h"
35
#include "packet-http.h"
36
37
/* un-comment the following as well as this line in conversation.c, to enable debug printing */
38
/* #define DEBUG_CONVERSATION */
39
#include "conversation_debug.h"
40
41
#include "packet-gsm_osmux.h"
42
#include "packet-rtp.h"
43
#include "packet-rtp_pt.h"
44
#include "packet-rtcp.h"
45
#include "packet-t38.h"
46
#include "packet-msrp.h"
47
#include "packet-sprt.h"
48
#include "packet-bfcp.h"
49
#include "packet-h245.h"
50
#include "packet-h264.h"
51
#include "packet-h265.h"
52
#include "packet-mp4ves.h"
53
54
void proto_register_sdp(void);
55
void proto_reg_handoff_sdp(void);
56
57
static dissector_handle_t sdp_handle;
58
static dissector_handle_t rtcp_handle;
59
static dissector_handle_t sprt_handle;
60
static dissector_handle_t msrp_handle;
61
static dissector_handle_t bfcp_handle;
62
static dissector_handle_t h264_handle;
63
static dissector_handle_t h265_handle;
64
static dissector_handle_t mp4ves_config_handle;
65
66
static int sdp_tap;
67
68
static int proto_sdp;
69
static int proto_sprt;
70
71
static const char* UNKNOWN_ENCODING = "Unknown";
72
static wmem_tree_t *sdp_transport_reqs;
73
static wmem_tree_t *sdp_transport_rsps;
74
static wmem_map_t *sdp_rtsp_control_map;
75
76
/* preference globals */
77
static bool global_sdp_establish_conversation = true;
78
79
/* Top level fields */
80
static int hf_protocol_version;
81
static int hf_owner;
82
static int hf_session_name;
83
static int hf_session_info;
84
static int hf_uri;
85
static int hf_email;
86
static int hf_phone;
87
static int hf_connection_info;
88
static int hf_bandwidth;
89
static int hf_timezone;
90
static int hf_encryption_key;
91
static int hf_session_attribute;
92
static int hf_media_attribute;
93
static int hf_time;
94
static int hf_repeat_time;
95
static int hf_media;
96
static int hf_media_title;
97
static int hf_unknown;
98
static int hf_invalid;
99
static int hf_ipbcp_version;
100
static int hf_ipbcp_type;
101
102
/* hf_owner subfields*/
103
static int hf_owner_username;
104
static int hf_owner_sessionid;
105
static int hf_owner_version;
106
static int hf_owner_network_type;
107
static int hf_owner_address_type;
108
static int hf_owner_address;
109
110
/* hf_connection_info subfields */
111
static int hf_connection_info_network_type;
112
static int hf_connection_info_address_type;
113
static int hf_connection_info_connection_address;
114
static int hf_connection_info_ttl;
115
static int hf_connection_info_num_addr;
116
117
/* hf_bandwidth subfields */
118
static int hf_bandwidth_modifier;
119
static int hf_bandwidth_value;
120
121
/* hf_time subfields */
122
static int hf_time_start;
123
static int hf_time_stop;
124
125
/* hf_repeat_time subfield */
126
static int hf_repeat_time_interval;
127
static int hf_repeat_time_duration;
128
static int hf_repeat_time_offset;
129
130
/* hf_timezone subfields */
131
static int hf_timezone_time;
132
static int hf_timezone_offset;
133
134
/* hf_encryption_key subfields */
135
static int hf_encryption_key_type;
136
static int hf_encryption_key_data;
137
138
/* hf_session_attribute subfields */
139
static int hf_session_attribute_field;
140
static int hf_session_attribute_value;
141
142
/* hf_media subfields */
143
static int hf_media_media;
144
static int hf_media_port;
145
static int hf_media_port_string;
146
static int hf_media_portcount;
147
static int hf_media_proto;
148
static int hf_media_format;
149
150
/* hf_session_attribute subfields */
151
static int hf_media_attribute_field;
152
static int hf_media_attribute_value;
153
static int hf_media_encoding_name;
154
static int hf_media_sample_rate;
155
static int hf_media_channels;
156
static int hf_media_format_specific_parameter;
157
static int hf_sdp_fmtp_mpeg4_profile_level_id;
158
static int hf_sdp_fmtp_h263_profile;
159
static int hf_sdp_fmtp_h263_level;
160
static int hf_sdp_h264_packetization_mode;
161
static int hf_SDPh223LogicalChannelParameters;
162
163
/* hf_session_attribute hf_media_attribute subfields */
164
static int hf_key_mgmt_att_value;
165
static int hf_key_mgmt_prtcl_id;
166
static int hf_key_mgmt_data;
167
168
static int hf_sdp_crypto_tag;
169
static int hf_sdp_crypto_crypto_suite;
170
static int hf_sdp_crypto_master_key;
171
static int hf_sdp_crypto_master_salt;
172
static int hf_sdp_crypto_lifetime;
173
static int hf_sdp_crypto_mki;
174
static int hf_sdp_crypto_mki_length;
175
176
/* a=candidate subfields */
177
static int hf_ice_candidate_foundation;
178
static int hf_ice_candidate_componentid;
179
static int hf_ice_candidate_transport;
180
static int hf_ice_candidate_priority;
181
static int hf_ice_candidate_address;
182
static int hf_ice_candidate_port;
183
static int hf_ice_candidate_type;
184
185
/* Generated from convert_proto_tree_add_text.pl */
186
static int hf_sdp_nal_unit_2_string;
187
static int hf_sdp_key_and_salt;
188
static int hf_sdp_nal_unit_1_string;
189
static int hf_sdp_data;
190
191
/* trees */
192
static int ett_sdp;
193
static int ett_sdp_owner;
194
static int ett_sdp_connection_info;
195
static int ett_sdp_bandwidth;
196
static int ett_sdp_time;
197
static int ett_sdp_repeat_time;
198
static int ett_sdp_timezone;
199
static int ett_sdp_encryption_key;
200
static int ett_sdp_session_attribute;
201
static int ett_sdp_media;
202
static int ett_sdp_media_attribute;
203
static int ett_sdp_fmtp;
204
static int ett_sdp_key_mgmt;
205
static int ett_sdp_crypto_key_parameters;
206
207
static expert_field ei_sdp_invalid_key_param;
208
static expert_field ei_sdp_invalid_line_equal;
209
static expert_field ei_sdp_invalid_line_fields;
210
static expert_field ei_sdp_invalid_line_space;
211
static expert_field ei_sdp_invalid_conversion;
212
static expert_field ei_sdp_invalid_media_port;
213
static expert_field ei_sdp_invalid_sample_rate;
214
static expert_field ei_sdp_invalid_channels;
215
static expert_field ei_sdp_invalid_media_format;
216
static expert_field ei_sdp_invalid_crypto_tag;
217
static expert_field ei_sdp_invalid_crypto_mki_length;
218
219
/* patterns used for tvb_ws_mempbrk_pattern_uint8 */
220
static ws_mempbrk_pattern pbrk_digits;
221
static ws_mempbrk_pattern pbrk_alpha;
222
223
typedef enum {
224
    SDP_PROTO_UNKNOWN = 0,
225
    SDP_PROTO_RTP,
226
    SDP_PROTO_SRTP,
227
    SDP_PROTO_T38,
228
    SDP_PROTO_MSRP,
229
    SDP_PROTO_SPRT,
230
    SDP_PROTO_BFCP,
231
} transport_proto_t;
232
233
234
930
#define SDP_MAX_RTP_CHANNELS 4
235
47
#define SDP_MAX_RTP_PAYLOAD_TYPES 20
236
39.9k
#define SDP_NO_OF_PT 128
237
/*
238
 * All parameters specific to one media description ("m=").
239
 */
240
typedef struct {
241
    int32_t pt[SDP_MAX_RTP_PAYLOAD_TYPES];
242
    int8_t pt_count;
243
    rtp_dyn_payload_t *rtp_dyn_payload;
244
    bool set_rtp;
245
} transport_media_pt_t;
246
247
/*
248
 * Store data extracted from one Media Description section of a SDP. Memory is
249
 * allocated in wmem_file_scope().
250
 */
251
typedef struct {
252
    transport_proto_t proto;    /**< Protocol, parsed from "m=" line. */
253
    uint32_t media_types;        /**< Whether "m=video" or others */
254
    bool bundled;           /**< "m=" lines are "bundled", that is, all on same port */
255
    uint16_t media_port;         /**< Port number, parsed from "m=" line. */
256
    uint16_t control_port;       /**< Port number, parsed from "a=rtcp" or "a=rtcp-mux" line. */
257
    address conn_addr;          /**< The address from the "c=" line (default
258
                                     from session level, possibly overridden at
259
                                     the media level). */
260
    char* control_uri;          /**< RTSP media control URI, parsed from "a=control:"
261
                                     XXX - allowed to default to session level if not
262
                                     overridden if only one media desc, but this is
263
                                     not implemented yet. */
264
    transport_media_pt_t media; /**< Information about payload numbers for this media. */
265
266
    /*
267
     * Media-level only attributes.
268
     */
269
    union {
270
        struct {
271
            address ipaddr;
272
            uint16_t port_number;
273
        } msrp;                 /**< MSRP transport info, parsed from "a=label:" */
274
    } media_attr;
275
} media_description_t;
276
277
/*
278
 * Information parsed from one or two (offer/answer) SDPs that is stored in the
279
 * conversation. The contents are allocated within wmem_file_scope().
280
 */
281
typedef struct {
282
    enum sdp_exchange_type sdp_status;
283
    char  *encoding_name[SDP_NO_OF_PT];
284
    unsigned sample_rate[SDP_NO_OF_PT];
285
    unsigned channels[SDP_NO_OF_PT];
286
287
    /* Data parsed from "m=" */
288
    wmem_array_t *media_descriptions;   /* array of media_description_t */
289
290
    wmem_array_t *sdp_setup_info_list;  /* array of sdp_setup_info_t that refer
291
                                         * to the same RTP conversation */
292
293
    /* SRTP related info XXX note currently we only handle one crypto line in the SDP
294
    * We should probably handle offer/answer and session updates etc(SIP) quite possibly the whole handling of
295
    * setting up the RTP conversations should be done by the signaling protocol(s) calling the SDP dissector
296
    * and the SDP dissector just provide the relevant data.
297
    * YES! packet-sdp.c should be about SDP parsing... SDP *state* needs to be maintained by upper
298
    * protocols, because each one has different rules/semantics.
299
    */
300
    unsigned  encryption_algorithm;
301
    unsigned  auth_algorithm;
302
    unsigned  mki_len;                /* number of octets used for the MKI in the RTP payload */
303
    unsigned  auth_tag_len;           /* number of octets used for the Auth Tag in the RTP payload */
304
} transport_info_t;
305
306
/*
307
 * Information about the session description. These are accumulated while
308
 * parsing the session description and will be applied to the media description.
309
 * Memory scope can be pinfo->pool since the contents are no longer
310
 * needed once they are processed into transport_info_t (via
311
 * complete_descriptions).
312
 */
313
typedef struct {
314
    address conn_addr;         /**< Parsed from "c=" line. */
315
    rtp_dyn_payload_t *rtp_dyn_payload; /**< Parsed from "a=rtpmap:" line.
316
                                             Note: wmem_file_scope, needs manual dealloc. */
317
} session_info_t;
318
319
/* Structure for private data to hold ED137 related values */
320
typedef struct sdp_data_t {
321
  char *ed137_type;           /* Radio session type */
322
  char *ed137_txrxmode;       /* Tx/Rx mode */
323
  char *ed137_fid;            /* Frequency ID */
324
} sdp_data_t;
325
326
327
/* here lie the debugging dumper functions */
328
#ifdef DEBUG_CONVERSATION
329
static void sdp_dump_transport_media(const transport_media_pt_t* media) {
330
    int i;
331
    int count;
332
    DPRINT2(("transport_media contents:"));
333
    DINDENT();
334
        if (!media) {
335
            DPRINT2(("null transport_media_pt_t*"));
336
            DENDENT();
337
            return;
338
        }
339
        count = (int)media->pt_count;
340
        DPRINT2(("pt_count=%d",count));
341
        DINDENT();
342
            for (i=0; i < count; i++) {
343
                DPRINT2(("pt=%d", media->pt[i]));
344
            }
345
        DENDENT();
346
        DPRINT2(("rtp_dyn_payload hashtable=%s", media->rtp_dyn_payload ? "YES" : "NO"));
347
        if (media->rtp_dyn_payload) {
348
            rtp_dump_dyn_payload(media->rtp_dyn_payload);
349
        }
350
        DPRINT2(("set_rtp=%s", media->set_rtp ? "TRUE" : "FALSE"));
351
    DENDENT();
352
}
353
354
static const value_string sdp_exchange_type_vs[] = {
355
    { SDP_EXCHANGE_OFFER,         "SDP_EXCHANGE_OFFER" },
356
    { SDP_EXCHANGE_ANSWER_ACCEPT, "SDP_EXCHANGE_ANSWER_ACCEPT" },
357
    { SDP_EXCHANGE_ANSWER_REJECT, "SDP_EXCHANGE_ANSWER_REJECT" },
358
    { 0, NULL }
359
};
360
361
static void sdp_dump_transport_info(packet_info *pinfo, const transport_info_t* info) {
362
    int i;
363
    int count;
364
    DPRINT2(("transport_info contents:"));
365
    DINDENT();
366
        if (!info) {
367
            DPRINT2(("null transport_info_t*"));
368
            DENDENT();
369
            return;
370
        }
371
        DPRINT2(("sdp_status=%s",
372
                 val_to_str_const(info->sdp_status, sdp_exchange_type_vs, "SDP_EXCHANGE_UNKNOWN")));
373
        DPRINT2(("payload type contents:"));
374
        DINDENT();
375
            for (i=0; i < SDP_NO_OF_PT; i++) {
376
                /* don't print out unknown encodings */
377
                if (info->encoding_name[i] &&
378
                    strcmp(UNKNOWN_ENCODING,info->encoding_name[i]) != 0) {
379
                    DPRINT2(("payload type #%d:",i));
380
                    DINDENT();
381
                        DPRINT2(("encoding_name=%s", info->encoding_name[i]));
382
                        DPRINT2(("sample_rate=%d", info->sample_rate[i]));
383
                    DENDENT();
384
                }
385
            }
386
        DENDENT();
387
        count = wmem_array_get_count(info->media_descriptions);
388
        DPRINT2(("media_count=%d", count));
389
        DPRINT2(("rtp channels:"));
390
        DINDENT();
391
            for (i=0; i < count; i++) {
392
                media_description_t *media_desc = (media_description_t *)wmem_array_index(info->media_descriptions, i);
393
                DPRINT2(("channel #%d:",i));
394
                DINDENT();
395
                    DPRINT2(("conn_addr=%s", address_to_str(pinfo->pool, &(media_desc->conn_addr))));
396
                    DPRINT2(("media_port=%d", media_desc->media_port));
397
                    DPRINT2(("proto=%d", media_desc->proto));
398
                    sdp_dump_transport_media(&(media_desc->media));
399
                DENDENT();
400
            }
401
        DENDENT();
402
        DPRINT2(("encryption_algorithm=%u", info->encryption_algorithm));
403
        DPRINT2(("auth_algorithm=%u", info->auth_algorithm));
404
        if (info->encryption_algorithm || info->auth_algorithm) {
405
            DPRINT2(("mki_len=%u", info->mki_len));
406
            if (info->auth_algorithm) {
407
                DPRINT2(("auth_tag_len=%u", info->auth_tag_len));
408
            }
409
        }
410
    DENDENT();
411
}
412
413
#endif /* DEBUG_CONVERSATION */
414
415
416
/* key-mgmt dissector
417
 * IANA registry:
418
 * http://www.iana.org/assignments/sdp-parameters
419
 */
420
static dissector_table_t key_mgmt_dissector_table;
421
422
/* Finds next token (sequence of non-space chars) in tvb from given offset.
423
 * The returned value is the token length, or 0 if none found.
424
 * The offset is changed to be the starting offset, in case there were one or more
425
 * spaces at the beginning. (this will also add expert info in such a case)
426
 * The next_offset is set to the next found space after the token, or -1 if the
427
 * end of line is hit or no token found.
428
 * If this is the last token in the line, tokenlen will not be 0, but next_offset
429
 * will be -1.
430
 *
431
 * The optional param, if true, means no expert error will be issued if no token
432
 * is found; if false then a expert error will be issued if no token is found.
433
 *
434
 * This function expects to be given a tvb of only one line, and does no error
435
 * checking of its given arguments.
436
 */
437
static inline int
438
find_next_optional_token_in_line(tvbuff_t *tvb, proto_tree *tree,
439
                                 int *offset, int *next_offset,
440
                                 const bool optional)
441
6.80k
{
442
6.80k
    int tokenlen = 0;
443
6.80k
    int next_off = -1;
444
6.80k
    int off      = *offset;
445
446
6.80k
    if (tvb_offset_exists(tvb, off)) {
447
14.5k
        while (tokenlen == 0) {
448
10.3k
            next_off = tvb_find_uint8(tvb, off, -1, ' ');
449
10.3k
            if (next_off == -1) {
450
2.34k
                tokenlen = tvb_captured_length_remaining(tvb, off);
451
2.34k
                break; /* Nothing more left */
452
2.34k
            }
453
454
7.98k
            tokenlen = next_off - off;
455
456
7.98k
            if (tokenlen == 0) {
457
                /* two spaces in a row - illegal, but we'll keep dissecting */
458
3.75k
                proto_tree_add_expert(tree, NULL, &ei_sdp_invalid_line_space, tvb, off-1, 2);
459
3.75k
                off = next_off + 1;
460
3.75k
            }
461
7.98k
        }
462
6.57k
    }
463
464
6.80k
    if (!optional && tokenlen == 0) {
465
404
        proto_tree_add_expert(tree, NULL, &ei_sdp_invalid_line_fields, tvb, 0, -1);
466
404
    }
467
468
6.80k
    *next_offset = next_off;
469
6.80k
    *offset      = off;
470
6.80k
    return tokenlen;
471
6.80k
}
472
473
/* Same as above, but always issues an expert error if a token is not found. */
474
static inline int
475
find_next_token_in_line(tvbuff_t *tvb, proto_tree *tree, int *offset, int *next_offset)
476
4.56k
{
477
4.56k
    return find_next_optional_token_in_line(tvb, tree, offset, next_offset, false);
478
4.56k
}
479
480
/* Convert the protocol from the "m=" line to something we understand. */
481
static transport_proto_t
482
parse_sdp_media_protocol(const char *media_proto)
483
711
{
484
    /* Sorted according to the "proto" registry at
485
     * https://www.iana.org/assignments/sdp-parameters/sdp-parameters.xhtml#sdp-parameters-2 */
486
711
    const struct {
487
711
        const char *proto_name;
488
711
        transport_proto_t proto;
489
711
    } protocols[] = {
490
711
        { "RTP/AVP",            SDP_PROTO_RTP }, /* RFC 4566 */
491
711
        { "udptl",              SDP_PROTO_T38 }, /* ITU-T T.38, example in Annex E */
492
711
        { "UDPTL",              SDP_PROTO_T38 }, /* Note: IANA registry contains lower case */
493
711
        { "RTP/AVPF",           SDP_PROTO_RTP }, /* RFC 4585 */
494
711
        { "RTP/SAVP",           SDP_PROTO_SRTP }, /* RFC 3711 */
495
711
        { "RTP/SAVPF",          SDP_PROTO_SRTP }, /* RFC 5124 */
496
711
        { "UDP/TLS/RTP/SAVP",   SDP_PROTO_SRTP }, /* RFC 5764 */
497
711
        { "UDP/TLS/RTP/SAVPF",  SDP_PROTO_SRTP }, /* RFC 5764 */
498
711
        { "msrp/tcp",           SDP_PROTO_MSRP }, /* Not in IANA, where is this from? */
499
711
        { "UDPSPRT",            SDP_PROTO_SPRT }, /* Not in IANA, but draft-rajeshkumar-avt-v150-registration-00 */
500
711
        { "udpsprt",            SDP_PROTO_SPRT }, /* lowercase per section E.1.1 of ITU-T V.150.1 */
501
711
        { "udpsprt",            SDP_PROTO_SPRT }, /* lowercase per section E.1.1 of ITU-T V.150.1 */
502
711
        { "UDP/BFCP",           SDP_PROTO_BFCP }, /* RFC 8856 */
503
711
    };
504
505
9.42k
    for (unsigned i = 0; i < G_N_ELEMENTS(protocols); i++) {
506
8.75k
        if (!strcmp(protocols[i].proto_name, media_proto)) {
507
41
            return protocols[i].proto;
508
41
        }
509
8.75k
    }
510
511
670
    return SDP_PROTO_UNKNOWN;
512
711
}
513
514
/* Parses the parts from "c=" into address structures. */
515
static void
516
parse_sdp_connection_address(const char *connection_type, const char *connection_address,
517
        wmem_allocator_t *allocator, address *conn_addr)
518
143
{
519
143
    if (strcmp(connection_type, "IP4") == 0) {
520
0
        uint32_t ip4_addr;
521
522
0
        if (str_to_ip(connection_address, &ip4_addr)) {
523
            /* connection_address could be converted to a valid ipv4 address*/
524
0
            alloc_address_wmem(allocator, conn_addr, AT_IPv4, 4, &ip4_addr);
525
0
        }
526
143
    } else if (strcmp(connection_type, "IP6") == 0) {
527
0
        ws_in6_addr ip6_addr;
528
529
0
        if (str_to_ip6(connection_address, &ip6_addr)) {
530
            /* connection_address could be converted to a valid ipv6 address*/
531
0
            alloc_address_wmem(allocator, conn_addr, AT_IPv6, 16, &ip6_addr);
532
0
        }
533
0
    }
534
143
}
535
536
/**
537
 * Starts a new media description. If there are too many media descriptions,
538
 * no new media description is started and NULL is returned.
539
 */
540
static media_description_t *
541
sdp_new_media_description(wmem_array_t *media_descriptions, session_info_t *session_info)
542
930
{
543
930
    media_description_t empty_desc;
544
930
    media_description_t *media_desc;
545
546
    /* Limit number to avoid consuming excess memory. */
547
930
    if (wmem_array_get_count(media_descriptions) >= SDP_MAX_RTP_CHANNELS) {
548
455
        DPRINT(("Too many media descriptions (more than %d), returning NULL!",
549
455
                wmem_array_get_count(media_descriptions)));
550
455
        return NULL;
551
455
    }
552
553
475
    memset(&empty_desc, 0, sizeof(media_description_t));
554
475
    wmem_array_append_one(media_descriptions, empty_desc);
555
475
    media_desc = (media_description_t *) wmem_array_index(media_descriptions,
556
475
            wmem_array_get_count(media_descriptions) - 1);
557
558
    /* XXX does it make sense making media_desc->media.pt a wmem array? */
559
560
    /* If "c=" is given at the session level, copy it to the media description.
561
     * It will be overridden as needed. */
562
475
    if (session_info->conn_addr.type != AT_NONE) {
563
0
        copy_address_wmem(wmem_file_scope(), &media_desc->conn_addr, &session_info->conn_addr);
564
0
    }
565
566
    /* If "a=rtpmap:" was set on the session level, copy them to media level. */
567
475
    media_desc->media.rtp_dyn_payload =
568
475
        rtp_dyn_payload_dup(session_info->rtp_dyn_payload);
569
570
475
    return media_desc;
571
930
}
572
573
rtp_dyn_payload_t *
574
sdp_get_rtsp_media_desc(const char* control_uri)
575
0
{
576
0
    return wmem_map_lookup(sdp_rtsp_control_map, control_uri);
577
0
}
578
579
/* Remove information about media descriptions which are unused. These appeared
580
 * in the "a=rtpmap:" (and maybe even in the payload types part of "m="?), but
581
 * are not used (port is zero or it was not assigned to RTP dissector). */
582
static void
583
clean_unused_media_descriptions(wmem_array_t *descs)
584
307
{
585
782
    for (unsigned i = 0; i < wmem_array_get_count(descs); i++) {
586
475
        media_description_t *media_desc = (media_description_t *)wmem_array_index(descs, i);
587
588
        /* If not assigned to subdissector, clear the unused information. */
589
475
        if (!media_desc->media.set_rtp) {
590
475
            rtp_dyn_payload_free(media_desc->media.rtp_dyn_payload);
591
475
            media_desc->media.rtp_dyn_payload = NULL;
592
475
        }
593
475
    }
594
307
}
595
596
597
/* Subdissector functions */
598
static void
599
135
dissect_sdp_owner(tvbuff_t *tvb, proto_item *ti) {
600
135
    proto_tree *sdp_owner_tree;
601
135
    int         offset, next_offset, tokenlen;
602
603
135
    offset = 0;
604
605
135
    sdp_owner_tree = proto_item_add_subtree(ti, ett_sdp_owner);
606
607
    /* Find the username */
608
135
    tokenlen = find_next_token_in_line(tvb, sdp_owner_tree, &offset, &next_offset);
609
135
    if (tokenlen == 0)
610
1
        return;
611
612
134
    proto_tree_add_item(sdp_owner_tree, hf_owner_username, tvb, offset, tokenlen,
613
134
                        ENC_UTF_8);
614
134
    offset = next_offset  + 1;
615
616
    /* Find the session id */
617
134
    tokenlen = find_next_token_in_line(tvb, sdp_owner_tree, &offset, &next_offset);
618
134
    if (tokenlen == 0)
619
18
        return;
620
621
116
    proto_tree_add_item(sdp_owner_tree, hf_owner_sessionid, tvb, offset,
622
116
                        tokenlen, ENC_UTF_8);
623
116
    offset = next_offset + 1;
624
625
    /* Find the version */
626
116
    tokenlen = find_next_token_in_line(tvb, sdp_owner_tree, &offset, &next_offset);
627
116
    if (tokenlen == 0)
628
19
        return;
629
630
97
    proto_tree_add_item(sdp_owner_tree, hf_owner_version, tvb, offset, tokenlen,
631
97
                        ENC_UTF_8);
632
97
    offset = next_offset + 1;
633
634
    /* Find the network type */
635
97
    tokenlen = find_next_token_in_line(tvb, sdp_owner_tree, &offset, &next_offset);
636
97
    if (tokenlen == 0)
637
11
        return;
638
639
86
    proto_tree_add_item(sdp_owner_tree, hf_owner_network_type, tvb, offset,
640
86
                        tokenlen, ENC_UTF_8);
641
86
    offset = next_offset + 1;
642
643
    /* Find the address type */
644
86
    tokenlen = find_next_token_in_line(tvb, sdp_owner_tree, &offset, &next_offset);
645
86
    if (tokenlen == 0)
646
11
        return;
647
648
75
    proto_tree_add_item(sdp_owner_tree, hf_owner_address_type, tvb, offset,
649
75
                        tokenlen, ENC_UTF_8);
650
75
    offset = next_offset + 1;
651
652
    /* Find the address */
653
75
    proto_tree_add_item(sdp_owner_tree, hf_owner_address, tvb, offset, -1, ENC_UTF_8);
654
75
}
655
656
/*
657
 * XXX - this can leak memory if an exception is thrown after we've fetched
658
 * a string.
659
 */
660
static void
661
dissect_sdp_connection_info(packet_info *pinfo, tvbuff_t *tvb, proto_item* ti, session_info_t *session_info, media_description_t *media_desc)
662
198
{
663
198
    proto_tree *sdp_connection_info_tree;
664
198
    int         offset, next_offset, tokenlen;
665
198
    const char *connection_type, *connection_address;
666
667
198
    offset = 0;
668
669
198
    sdp_connection_info_tree = proto_item_add_subtree(ti,
670
198
                                                      ett_sdp_connection_info);
671
672
    /* Find the network type */
673
198
    tokenlen = find_next_token_in_line(tvb, sdp_connection_info_tree, &offset, &next_offset);
674
198
    if (tokenlen == 0)
675
35
        return;
676
677
163
    proto_tree_add_item(sdp_connection_info_tree,
678
163
                        hf_connection_info_network_type, tvb, offset, tokenlen,
679
163
                        ENC_UTF_8);
680
163
    offset = next_offset + 1;
681
682
    /* Find the address type */
683
163
    tokenlen = find_next_token_in_line(tvb, sdp_connection_info_tree, &offset, &next_offset);
684
163
    if (tokenlen == 0)
685
15
        return;
686
687
    /* Save connection address type */
688
148
    proto_tree_add_item_ret_string(sdp_connection_info_tree,
689
148
                        hf_connection_info_address_type, tvb, offset, tokenlen,
690
148
                        ENC_UTF_8|ENC_NA, pinfo->pool, (const uint8_t**)&connection_type);
691
148
    DPRINT(("parsed connection line type=%s", connection_type));
692
148
    offset = next_offset + 1;
693
694
    /* Find the connection address */
695
    /* XXX - what if there's a <number of addresses> value? */
696
148
    next_offset = tvb_find_uint8(tvb, offset, -1, '/');
697
148
    if (next_offset == -1) {
698
102
        tokenlen = -1; /* end of tvbuff */
699
        /* Save connection address */
700
102
        connection_address = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_UTF_8|ENC_NA);
701
102
    } else {
702
46
        tokenlen = next_offset - offset;
703
        /* Save connection address */
704
46
        connection_address = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
705
46
    }
706
707
148
    DPRINT(("parsed connection line address=%s", connection_address));
708
    /* Parse and store connection address. Session-level addresses are
709
     * packet-scoped since they will be cloned in file-scope when needed. */
710
148
    if (session_info) {
711
138
        parse_sdp_connection_address(connection_type, connection_address,
712
138
                pinfo->pool,
713
138
                &session_info->conn_addr);
714
138
    } else if (media_desc) {
715
        /* Clear possibly inherited address from session level. */
716
5
        free_address_wmem(wmem_file_scope(), &media_desc->conn_addr);
717
718
5
        parse_sdp_connection_address(connection_type, connection_address,
719
5
                wmem_file_scope(),
720
5
                &media_desc->conn_addr);
721
5
    }
722
723
148
    proto_tree_add_item(sdp_connection_info_tree,
724
148
                        hf_connection_info_connection_address, tvb, offset,
725
148
                        tokenlen, ENC_UTF_8);
726
148
    if (next_offset != -1) {
727
46
        offset = next_offset + 1;
728
46
        next_offset = tvb_find_uint8(tvb, offset, -1, '/');
729
46
        if (next_offset == -1) {
730
41
            tokenlen = -1; /* end of tvbuff */
731
41
        } else {
732
5
            tokenlen = next_offset - offset;
733
5
        }
734
46
        proto_tree_add_item(sdp_connection_info_tree,
735
46
                            hf_connection_info_ttl, tvb, offset, tokenlen, ENC_UTF_8);
736
46
        if (next_offset != -1) {
737
5
            offset = next_offset + 1;
738
5
            proto_tree_add_item(sdp_connection_info_tree,
739
5
                                hf_connection_info_num_addr, tvb, offset, -1, ENC_UTF_8);
740
5
        }
741
46
    }
742
148
}
743
744
static void
745
15
dissect_sdp_bandwidth(tvbuff_t *tvb, proto_item *ti) {
746
15
    proto_tree *sdp_bandwidth_tree;
747
15
    int         offset, next_offset, tokenlen;
748
15
    proto_item *item;
749
15
    bool        unit_is_kbs = false;
750
15
    bool        unit_is_bps = false;
751
752
15
    offset = 0;
753
754
15
    sdp_bandwidth_tree = proto_item_add_subtree(ti, ett_sdp_bandwidth);
755
756
    /* find the modifier */
757
15
    next_offset = tvb_find_uint8(tvb, offset, -1, ':');
758
759
15
    if (next_offset == -1)
760
15
        return;
761
762
0
    tokenlen = next_offset - offset;
763
764
0
    item = proto_tree_add_item(sdp_bandwidth_tree, hf_bandwidth_modifier, tvb, offset,
765
0
                               tokenlen, ENC_UTF_8);
766
0
    if (tvb_strneql(tvb, offset, "CT", 2) == 0) {
767
0
        proto_item_append_text(item, " [Conference Total(total bandwidth of all RTP sessions)]");
768
0
        unit_is_kbs = true;
769
0
    } else if (tvb_strneql(tvb, offset, "AS", 2) == 0) {
770
0
        proto_item_append_text(item, " [Application Specific (RTP session bandwidth)]");
771
0
        unit_is_kbs = true;
772
0
    } else if (tvb_strneql(tvb, offset, "TIAS", 4) == 0) {
773
0
        proto_item_append_text(item, " [Transport Independent Application Specific maximum]");
774
0
        unit_is_bps = true;
775
0
    }
776
777
778
0
    offset = next_offset + 1;
779
780
0
    item = proto_tree_add_item(sdp_bandwidth_tree, hf_bandwidth_value, tvb, offset, -1,
781
0
                               ENC_UTF_8);
782
0
    if (unit_is_kbs == true)
783
0
        proto_item_append_text(item, " kb/s");
784
0
    if (unit_is_bps == true)
785
0
        proto_item_append_text(item, " b/s");
786
0
}
787
788
7
static void dissect_sdp_time(tvbuff_t *tvb, proto_item* ti) {
789
7
    proto_tree *sdp_time_tree;
790
7
    int         offset, next_offset, tokenlen;
791
792
7
    offset = 0;
793
794
7
    sdp_time_tree = proto_item_add_subtree(ti, ett_sdp_time);
795
796
    /* get start time */
797
7
    tokenlen = find_next_token_in_line(tvb, sdp_time_tree, &offset, &next_offset);
798
7
    if (tokenlen == 0)
799
1
        return;
800
801
6
    proto_tree_add_item(sdp_time_tree, hf_time_start, tvb, offset, tokenlen,
802
6
                        ENC_UTF_8);
803
804
    /* get stop time */
805
6
    offset = next_offset + 1;
806
6
    proto_tree_add_item(sdp_time_tree, hf_time_stop, tvb, offset, -1, ENC_UTF_8);
807
6
}
808
809
92
static void dissect_sdp_repeat_time(tvbuff_t *tvb, proto_item* ti) {
810
92
    proto_tree *sdp_repeat_time_tree;
811
92
    int         offset, next_offset, tokenlen;
812
92
    bool        optional = false;
813
814
92
    offset = 0;
815
816
92
    sdp_repeat_time_tree = proto_item_add_subtree(ti, ett_sdp_time);
817
818
    /* get interval */
819
92
    tokenlen = find_next_token_in_line(tvb, sdp_repeat_time_tree, &offset, &next_offset);
820
92
    if (tokenlen == 0)
821
0
        return;
822
823
92
    proto_tree_add_item(sdp_repeat_time_tree, hf_repeat_time_interval, tvb,
824
92
                        offset, tokenlen, ENC_UTF_8);
825
826
    /* get duration */
827
92
    offset = next_offset + 1;
828
92
    tokenlen = find_next_token_in_line(tvb, sdp_repeat_time_tree, &offset, &next_offset);
829
92
    if (tokenlen == 0)
830
34
        return;
831
832
58
    proto_tree_add_item(sdp_repeat_time_tree, hf_repeat_time_duration, tvb,
833
58
                        offset, tokenlen, ENC_UTF_8);
834
835
    /* get offsets */
836
180
    do {
837
180
        offset = next_offset +1;
838
180
        tokenlen = find_next_optional_token_in_line(tvb, sdp_repeat_time_tree,
839
180
                                                    &offset, &next_offset, optional);
840
180
        if (tokenlen == 0)
841
14
            break;
842
166
        proto_tree_add_item(sdp_repeat_time_tree, hf_repeat_time_offset,
843
166
                            tvb, offset, tokenlen, ENC_UTF_8);
844
166
        optional = true;
845
166
    } while (next_offset != -1);
846
847
58
}
848
849
static void
850
116
dissect_sdp_timezone(tvbuff_t *tvb, proto_item* ti) {
851
116
    proto_tree* sdp_timezone_tree;
852
116
    int         offset, next_offset, tokenlen;
853
116
    bool        optional = false;
854
855
116
    offset = 0;
856
857
116
    sdp_timezone_tree = proto_item_add_subtree(ti, ett_sdp_timezone);
858
859
306
    do {
860
306
        tokenlen = find_next_optional_token_in_line(tvb, sdp_timezone_tree,
861
306
                                                    &offset, &next_offset, optional);
862
306
        if (tokenlen == 0)
863
21
            break;
864
865
285
        proto_tree_add_item(sdp_timezone_tree, hf_timezone_time, tvb, offset,
866
285
                            tokenlen, ENC_UTF_8);
867
285
        offset = next_offset + 1;
868
285
        tokenlen = find_next_optional_token_in_line(tvb, sdp_timezone_tree,
869
285
                                                    &offset, &next_offset, optional);
870
285
        if (tokenlen == 0)
871
8
            break;
872
277
        proto_tree_add_item(sdp_timezone_tree, hf_timezone_offset, tvb, offset,
873
277
                            tokenlen, ENC_UTF_8);
874
277
        offset = next_offset + 1;
875
277
        optional = true;
876
277
    } while (next_offset != -1);
877
878
116
}
879
880
881
29
static void dissect_sdp_encryption_key(tvbuff_t *tvb, proto_item * ti) {
882
29
    proto_tree *sdp_encryption_key_tree;
883
29
    int         offset, next_offset, tokenlen;
884
885
29
    offset = 0;
886
887
29
    sdp_encryption_key_tree = proto_item_add_subtree(ti, ett_sdp_encryption_key);
888
889
29
    next_offset = tvb_find_uint8(tvb, offset, -1, ':');
890
891
29
    if (next_offset == -1)
892
24
        return;
893
894
5
    tokenlen = next_offset - offset;
895
896
5
    proto_tree_add_item(sdp_encryption_key_tree, hf_encryption_key_type,
897
5
                        tvb, offset, tokenlen, ENC_UTF_8);
898
899
5
    offset = next_offset + 1;
900
5
    proto_tree_add_item(sdp_encryption_key_tree, hf_encryption_key_data,
901
5
                        tvb, offset, -1, ENC_UTF_8);
902
5
}
903
904
0
static void dissect_key_mgmt(tvbuff_t *tvb, packet_info * pinfo, proto_item * ti) {
905
0
    char         *data_p      = NULL;
906
0
    const uint8_t *prtcl_id    = NULL;
907
0
    int           len;
908
0
    tvbuff_t     *keymgmt_tvb;
909
0
    int           found_match = 0;
910
0
    proto_tree   *key_tree;
911
0
    int           next_offset;
912
0
    int           offset      = 0;
913
0
    int           tokenlen;
914
915
0
    key_tree = proto_item_add_subtree(ti, ett_sdp_key_mgmt);
916
917
0
    tokenlen = find_next_token_in_line(tvb, key_tree, &offset, &next_offset);
918
0
    if (tokenlen == 0)
919
0
        return;
920
921
0
    proto_tree_add_item_ret_string(key_tree, hf_key_mgmt_prtcl_id, tvb, offset, tokenlen, ENC_UTF_8|ENC_NA, pinfo->pool, &prtcl_id);
922
923
0
    offset = next_offset + 1;
924
925
0
    len = tvb_captured_length_remaining(tvb, offset);
926
0
    if (len < 0)
927
0
        return;
928
929
0
    data_p = (char *)tvb_get_string_enc(pinfo->pool, tvb, offset, len, ENC_UTF_8|ENC_NA);
930
0
    keymgmt_tvb = base64_to_tvb(tvb, data_p);
931
0
    add_new_data_source(pinfo, keymgmt_tvb, "Key Management Data");
932
933
0
    if ((prtcl_id != NULL) && (key_mgmt_dissector_table != NULL)) {
934
0
        found_match = dissector_try_string_with_data(key_mgmt_dissector_table,
935
0
                                           (const char *)prtcl_id,
936
0
                                           keymgmt_tvb, pinfo,
937
0
                                           key_tree, true, NULL);
938
0
    }
939
940
0
    if (found_match) {
941
0
        proto_item *ti2 = proto_tree_add_item(key_tree, hf_key_mgmt_data,
942
0
                                              keymgmt_tvb, 0, -1, ENC_NA);
943
0
        proto_item_set_hidden(ti2);
944
0
    } else {
945
0
        proto_tree_add_item(key_tree, hf_key_mgmt_data,
946
0
                            keymgmt_tvb, 0, -1, ENC_NA);
947
0
    }
948
949
0
}
950
951
952
0
static void dissect_sdp_session_attribute(tvbuff_t *tvb, packet_info * pinfo, proto_item * ti) {
953
0
    proto_tree   *sdp_session_attribute_tree;
954
0
    int           offset, next_offset, tokenlen;
955
0
    const uint8_t *field_name;
956
957
0
    offset = 0;
958
959
0
    sdp_session_attribute_tree = proto_item_add_subtree(ti,
960
0
                                                        ett_sdp_session_attribute);
961
962
0
    next_offset = tvb_find_uint8(tvb, offset, -1, ':');
963
964
0
    if (next_offset == -1)
965
0
        return;
966
967
0
    tokenlen = next_offset - offset;
968
969
0
    proto_tree_add_item_ret_string(sdp_session_attribute_tree, hf_session_attribute_field,
970
0
                        tvb, offset, tokenlen, ENC_UTF_8|ENC_NA, pinfo->pool, &field_name);
971
972
0
    offset = next_offset + 1;
973
974
0
    if (tvb_captured_length_remaining(tvb, offset) == 0) {
975
0
        expert_add_info(pinfo, ti, &ei_sdp_invalid_line_fields);
976
0
        return;
977
0
    }
978
979
0
    if (strcmp((const char *)field_name, "ipbcp") == 0) {
980
0
        offset = tvb_ws_mempbrk_pattern_uint8(tvb, offset, -1,&pbrk_digits, NULL);
981
982
0
        if (offset == -1)
983
0
            return;
984
985
0
        tokenlen = find_next_token_in_line(tvb, sdp_session_attribute_tree, &offset, &next_offset);
986
0
        if (tokenlen == 0)
987
0
            return;
988
989
0
        proto_tree_add_item(sdp_session_attribute_tree, hf_ipbcp_version, tvb, offset, tokenlen, ENC_UTF_8);
990
991
0
        offset = tvb_ws_mempbrk_pattern_uint8(tvb, offset, -1,&pbrk_alpha, NULL);
992
993
0
        if (offset == -1)
994
0
            return;
995
996
0
        tokenlen = tvb_find_line_end(tvb, offset, -1, &next_offset, false);
997
998
0
        if (tokenlen == -1)
999
0
            return;
1000
1001
0
        proto_tree_add_item(sdp_session_attribute_tree, hf_ipbcp_type, tvb, offset, tokenlen, ENC_UTF_8);
1002
0
    } else if (strcmp((const char *)field_name, "key-mgmt") == 0) {
1003
0
        tvbuff_t   *key_tvb;
1004
0
        proto_item *key_ti;
1005
1006
0
        key_tvb = tvb_new_subset_remaining(tvb, offset);
1007
0
        key_ti = proto_tree_add_item(sdp_session_attribute_tree, hf_key_mgmt_att_value, key_tvb, 0, -1, ENC_UTF_8);
1008
1009
0
        dissect_key_mgmt(key_tvb, pinfo, key_ti);
1010
0
    } else {
1011
0
        proto_tree_add_item(sdp_session_attribute_tree, hf_session_attribute_value,
1012
0
                            tvb, offset, -1, ENC_UTF_8);
1013
0
    }
1014
0
}
1015
1016
1017
/* Dissect media description - this is passed the line starting after 'm=', so like one of these:
1018
 *    audio 29156 RTP/AVP 18 0
1019
 *    video 49170/2 RTP/AVP 31 99
1020
 */
1021
static void
1022
dissect_sdp_media(tvbuff_t *tvb, packet_info* pinfo, proto_item *ti,
1023
930
                  media_description_t *media_desc) {
1024
930
    proto_tree *sdp_media_tree;
1025
930
    int         offset, next_offset, tokenlen, idx;
1026
930
    uint8_t    *media_format;
1027
930
    bool        optional = false;
1028
930
    proto_item *it;
1029
930
    const char *media_type_str;
1030
930
    const char *media_port_str;
1031
930
    const char *media_proto_str;
1032
930
    transport_proto_t transport_proto;
1033
930
    uint16_t    media_port;
1034
930
    bool        media_port_valid;
1035
930
    proto_item *pi;
1036
1037
930
    offset = 0;
1038
1039
    /* Create tree for media session */
1040
930
    sdp_media_tree = proto_item_add_subtree(ti, ett_sdp_media);
1041
1042
930
    tokenlen = find_next_token_in_line(tvb, sdp_media_tree, &offset, &next_offset);
1043
930
    if (tokenlen == 0)
1044
9
        return;
1045
1046
    /* Type of media session */
1047
921
    proto_tree_add_item_ret_string(sdp_media_tree, hf_media_media, tvb, offset, tokenlen,
1048
921
                        ENC_UTF_8|ENC_NA, pinfo->pool, (const uint8_t**)&media_type_str);
1049
921
    if (media_desc) {
1050
        /* for RTP statistics (supposedly?) */
1051
468
        if (strcmp(media_type_str, "audio") == 0)
1052
0
            media_desc->media_types |= RTP_MEDIA_AUDIO;
1053
468
        else if (strcmp(media_type_str, "video") == 0)
1054
0
            media_desc->media_types |= RTP_MEDIA_VIDEO;
1055
468
        else
1056
468
            media_desc->media_types |= RTP_MEDIA_OTHER;
1057
468
    }
1058
921
    DPRINT(("parsed media_type=%s", media_type_str));
1059
1060
921
    offset = next_offset + 1;
1061
1062
921
    tokenlen = find_next_token_in_line(tvb, sdp_media_tree, &offset, &next_offset);
1063
921
    if (tokenlen == 0)
1064
117
        return;
1065
1066
804
    next_offset = tvb_find_uint8(tvb, offset, tokenlen, '/');
1067
1068
804
    if (next_offset != -1) {
1069
102
        tokenlen = next_offset - offset;
1070
        /* Save port info */
1071
102
        it = proto_tree_add_item_ret_string(sdp_media_tree, hf_media_port_string, tvb, offset, tokenlen,
1072
102
                                   ENC_UTF_8|ENC_NA, pinfo->pool, (const uint8_t**)&media_port_str);
1073
102
        DPRINT(("parsed media_port=%s", media_port_str));
1074
102
        if (g_ascii_isdigit(media_port_str[0])) {
1075
41
            proto_item_set_hidden(it);
1076
41
            media_port_valid = ws_strtou16(media_port_str, NULL, &media_port);
1077
41
            pi = proto_tree_add_uint(sdp_media_tree, hf_media_port, tvb, offset, tokenlen,
1078
41
                                media_port);
1079
41
            if (!media_port_valid)
1080
28
                expert_add_info(pinfo, pi, &ei_sdp_invalid_media_port);
1081
41
            if (media_desc) {
1082
17
                media_desc->media_port = media_port;
1083
17
            }
1084
41
        }
1085
1086
102
        offset = next_offset + 1;
1087
102
        tokenlen = find_next_token_in_line(tvb, sdp_media_tree, &offset, &next_offset);
1088
102
        if (tokenlen == 0)
1089
14
            return;
1090
1091
        /* TODO: this puts the (optional) number of ports in the tree, but we don't
1092
           actually use it for building the extra RTP flows, which we should. */
1093
88
        proto_tree_add_item(sdp_media_tree, hf_media_portcount, tvb, offset,
1094
88
                            tokenlen, ENC_UTF_8);
1095
88
        offset = next_offset + 1;
1096
702
    } else {
1097
702
        tokenlen = find_next_token_in_line(tvb, sdp_media_tree, &offset, &next_offset);
1098
702
        if (tokenlen == 0)
1099
0
            return;
1100
1101
        /* Save port info */
1102
702
        it = proto_tree_add_item_ret_string(sdp_media_tree, hf_media_port_string, tvb, offset, tokenlen,
1103
702
                                   ENC_UTF_8|ENC_NA, pinfo->pool, (const uint8_t**)&media_port_str);
1104
702
        DPRINT(("parsed media_port=%s", media_port_str));
1105
702
        if (g_ascii_isdigit(media_port_str[0])) {
1106
233
            proto_item_set_hidden(it);
1107
233
            media_port_valid = ws_strtou16(media_port_str, NULL, &media_port);
1108
233
            pi = proto_tree_add_uint(sdp_media_tree, hf_media_port, tvb, offset, tokenlen,
1109
233
                                media_port);
1110
233
            if (!media_port_valid)
1111
92
                expert_add_info(pinfo, pi, &ei_sdp_invalid_media_port);
1112
233
            if (media_desc) {
1113
119
                media_desc->media_port = media_port;
1114
119
            }
1115
233
        }
1116
702
        offset = next_offset + 1;
1117
702
    }
1118
1119
790
    tokenlen = find_next_token_in_line(tvb, sdp_media_tree, &offset, &next_offset);
1120
790
    if (tokenlen == 0)
1121
79
        return;
1122
1123
    /* Save port protocol */
1124
711
    proto_tree_add_item_ret_string(sdp_media_tree, hf_media_proto, tvb, offset, tokenlen,
1125
711
                        ENC_UTF_8|ENC_NA, pinfo->pool, (const uint8_t**)&media_proto_str);
1126
711
    DPRINT(("parsed media_proto=%s", media_proto_str));
1127
    /* Detect protocol for registering with other dissectors like RTP. */
1128
711
    transport_proto = parse_sdp_media_protocol(media_proto_str);
1129
711
    if (media_desc) {
1130
388
        media_desc->proto = transport_proto;
1131
388
    }
1132
1133
1.47k
    do {
1134
1.47k
        offset = next_offset + 1;
1135
1.47k
        tokenlen = find_next_optional_token_in_line(tvb, sdp_media_tree,
1136
1.47k
                                                    &offset, &next_offset, optional);
1137
1.47k
        if (tokenlen == 0)
1138
72
            break;
1139
1140
        /* RFC 4566: If the <proto> sub-field is "RTP/AVP" or "RTP/SAVP" the
1141
         * <fmt> sub-fields contain RTP payload type numbers. */
1142
1.39k
        if (transport_proto == SDP_PROTO_RTP || transport_proto == SDP_PROTO_SRTP) {
1143
193
            media_format = tvb_get_string_enc(pinfo->pool, tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
1144
193
            if (g_ascii_isdigit(media_format[0])) {
1145
84
                proto_tree_add_string(sdp_media_tree, hf_media_format, tvb, offset,
1146
84
                                      tokenlen, val_to_str_ext(pinfo->pool, (uint32_t)strtoul((char*)media_format, NULL, 10), &rtp_payload_type_vals_ext, "%u"));
1147
1148
84
                if (media_desc) {
1149
47
                    idx = media_desc->media.pt_count;
1150
47
                    media_desc->media.pt[idx] = (int32_t)strtol((char*)media_format, NULL, 10);
1151
47
                    DPRINT(("parsed media codec pt=%d", media_desc->media.pt[idx]));
1152
47
                    if (idx < (SDP_MAX_RTP_PAYLOAD_TYPES-1))
1153
47
                        media_desc->media.pt_count++;
1154
47
                }
1155
109
            } else {
1156
109
                proto_tree_add_item(sdp_media_tree, hf_media_format, tvb, offset,
1157
109
                                    tokenlen, ENC_UTF_8);
1158
109
            }
1159
1.20k
        } else {
1160
1.20k
            proto_tree_add_item(sdp_media_tree, hf_media_format, tvb, offset,
1161
1.20k
                                tokenlen, ENC_UTF_8);
1162
1.20k
        }
1163
1.39k
        optional = true;
1164
1.39k
    } while (next_offset != -1);
1165
1166
    /* XXX Dissect traffic to "Port" as "Protocol"
1167
     *     Remember this Port/Protocol pair so we can tear it down again later
1168
     *     Actually, it's harder than that:
1169
     *         We need to find out the address of the other side first and it
1170
     *         looks like that info can be found in SIP headers only.
1171
     */
1172
1173
711
}
1174
1175
static tvbuff_t *
1176
ascii_bytes_to_tvb(tvbuff_t *tvb, packet_info *pinfo, char *msg)
1177
0
{
1178
0
    size_t nbytes;
1179
0
    uint8_t *buf = convert_string_to_hex(msg, &nbytes);
1180
0
    if (buf) {
1181
0
        tvbuff_t *bytes_tvb;
1182
1183
0
        bytes_tvb = tvb_new_child_real_data(tvb, buf, (unsigned)nbytes, (unsigned)nbytes);
1184
0
        tvb_set_free_cb(bytes_tvb, g_free);
1185
0
        add_new_data_source(pinfo, bytes_tvb, "ASCII bytes to tvb");
1186
0
        return bytes_tvb;
1187
0
    }
1188
0
    return NULL;
1189
0
}
1190
1191
/* Annex X Profiles and levels definition */
1192
static const value_string h263_profile_vals[] =
1193
{
1194
    { 0,    "Baseline Profile" },
1195
    { 1,    "H.320 Coding Efficiency Version 2 Backward-Compatibility Profile" },
1196
    { 2,    "Version 1 Backward-Compatibility Profile" },
1197
    { 3,    "Version 2 Interactive and Streaming Wireless Profile" },
1198
    { 4,    "Version 3 Interactive and Streaming Wireless Profile" },
1199
    { 5,    "Conversational High Compression Profile" },
1200
    { 6,    "Conversational Internet Profile" },
1201
    { 7,    "Conversational Interlace Profile" },
1202
    { 8,    "High Latency Profile" },
1203
    { 0, NULL },
1204
};
1205
1206
1207
/* RFC 4629 The level are described in table X.2 of H.263 annex X */
1208
static const value_string h263_level_vals[] =
1209
{
1210
    { 10,    "QCIF (176 x 144), 1 x 64Kb/s" },
1211
    { 20,    "CIF (352 x 288), 2 x 64Kb/s" },
1212
    { 30,    "CIF (352 x 288), 6 x 64Kb/s" },
1213
    { 40,    "CIF (352 x 288), 32 x 64Kb/s" },
1214
    { 45,    "QCIF (176 x144) support of CPFMT, 2 x 64Kb/s" },
1215
    { 50,    "CIF (352 x 288) support of CPFMT, 64 x 64Kb/s" },
1216
    { 60,    "CPFMT: 720 x 288 support of CPFMT, 128 x 64Kb/s" },
1217
    { 70,    "CPFMT: 720 x 576 support of CPFMT, 256 x 64Kb/s" },
1218
    { 0, NULL },
1219
};
1220
1221
1222
static const value_string h264_packetization_mode_vals[] =
1223
{
1224
    { 0,    "Single NAL mode" },
1225
    { 1,    "Non-interleaved mode" },
1226
    { 2,    "Interleaved mode" },
1227
    { 0, NULL },
1228
};
1229
1230
/*
1231
 * TODO: Make this a more generic routine to dissect fmtp parameters depending on media types
1232
 */
1233
static void
1234
0
decode_sdp_fmtp(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset, int tokenlen, uint8_t pt, transport_info_t *transport_info, rtp_dyn_payload_t *rtp_dyn_payload) {
1235
0
  int                  next_offset;
1236
0
  int                  end_offset;
1237
0
  char                *field_name;
1238
0
  char                *format_specific_parameter;
1239
0
  proto_item          *item;
1240
0
  tvbuff_t * volatile  data_tvb;
1241
1242
0
  const char *mime_type = transport_info->encoding_name[pt];
1243
0
  end_offset = offset + tokenlen;
1244
1245
#if 0
1246
    proto_tree_add_debug(tree, tvb, offset, tokenlen, "Debug; Analysed string: '%s'",
1247
    tvb_get_string_enc(pinfo->pool, tvb, offset, tokenlen, ENC_ASCII));
1248
#endif
1249
1250
    /* Look for an '=' within this string - RFC 4855 suggests that parameters
1251
       be "parameter=value" pairs. We'll store them in a hash map from the
1252
       parameter name to the value, as well as dissect some of them here,
1253
       depending on the media type.
1254
     */
1255
0
    next_offset = tvb_find_uint8(tvb, offset, tokenlen, '=');
1256
0
    if (next_offset == -1)
1257
0
    {
1258
        /* Some media types, like telephone-event and RED, don't have the
1259
         * "parameter=value" syntax:
1260
         * https://datatracker.ietf.org/doc/html/rfc4733
1261
         * 2.4.1. "Relationship to SDP"
1262
         * "The "events" media type parameter deviates from the convention
1263
         * suggested in RFC 3555 because it omits the string "events=" before
1264
         * the list of supported events."
1265
         * https://www.iana.org/assignments/media-types/audio/RED
1266
         * We'll handle them with the empty string as the parameter name.
1267
         * The media types should know how to deal with that, if necessary.
1268
         */
1269
0
        field_name = wmem_strdup(pinfo->pool, "");
1270
0
    } else {
1271
        /* Find the name of the parameter */
1272
0
        tokenlen = next_offset - offset;
1273
0
        field_name = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, tokenlen, ENC_UTF_8);
1274
1275
#if 0
1276
        proto_tree_add_debug(tree, tvb, offset, tokenlen, "Debug; MIMEtype '%s'Parameter name: '%s'", mime_type, field_name); */
1277
#endif
1278
1279
        /* Move past the '=' */
1280
0
        offset = next_offset + 1;
1281
0
    }
1282
1283
    /* Get the value */
1284
0
    tokenlen = end_offset - offset;
1285
0
    format_specific_parameter = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, tokenlen, ENC_UTF_8);
1286
1287
0
    if (rtp_dyn_payload) {
1288
0
        rtp_dyn_payload_add_fmtp(rtp_dyn_payload, pt,
1289
0
                                 field_name,
1290
0
                                 format_specific_parameter);
1291
0
    }
1292
1293
    /* Dissect the MPEG4 profile-level-id parameter if present */
1294
0
    if ((mime_type != NULL) && (g_ascii_strcasecmp(mime_type, "MP4V-ES") == 0)) {
1295
0
        if (strcmp((char*)field_name, "profile-level-id") == 0) {
1296
0
            item = proto_tree_add_uint(tree, hf_sdp_fmtp_mpeg4_profile_level_id, tvb, offset, tokenlen,
1297
0
                                       (uint32_t)strtol((char*)format_specific_parameter, NULL, 10));
1298
0
            proto_item_set_generated(item);
1299
0
        } else if (strcmp((char*)field_name, "config") == 0) {
1300
0
            data_tvb = ascii_bytes_to_tvb(tvb, pinfo, format_specific_parameter);
1301
0
            if (mp4ves_config_handle && data_tvb) {
1302
0
                call_dissector(mp4ves_config_handle, data_tvb, pinfo, tree);
1303
0
            }
1304
0
        }
1305
0
    }
1306
1307
    /* Dissect the H263-2000 profile parameter if present */
1308
0
    if (((mime_type != NULL) && (g_ascii_strcasecmp(mime_type, "H263-2000") == 0)) ||
1309
0
        ((mime_type != NULL) && (g_ascii_strcasecmp(mime_type, "H263-1998") == 0))) {
1310
0
        if (strcmp((char*)field_name, "profile") == 0) {
1311
0
            item = proto_tree_add_uint(tree, hf_sdp_fmtp_h263_profile, tvb, offset, tokenlen,
1312
0
                                       (uint32_t)strtol((char*)format_specific_parameter, NULL, 10));
1313
0
            proto_item_set_generated(item);
1314
0
        } else if (strcmp((char*)field_name, "level") == 0) {
1315
0
            item = proto_tree_add_uint(tree, hf_sdp_fmtp_h263_level, tvb, offset, tokenlen,
1316
0
                                       (uint32_t)strtol((char*)format_specific_parameter, NULL, 10));
1317
0
            proto_item_set_generated(item);
1318
0
        }
1319
0
    }
1320
1321
1322
    /* Dissect the H264 profile-level-id parameter
1323
     * RFC 3984:
1324
     * A base16 [6] (hexadecimal) representation of
1325
     * the following three bytes in the sequence
1326
     * parameter set NAL unit specified in [1]: 1)
1327
     * profile_idc, 2) a byte herein referred to as
1328
     * profile-iop, composed of the values of
1329
     * constraint_set0_flag, constraint_set1_flag,
1330
     * constraint_set2_flag, and reserved_zero_5bits
1331
     * in bit-significance order, starting from the
1332
     * most significant bit, and 3) level_idc.
1333
     */
1334
0
    if ((mime_type != NULL) && ((g_ascii_strcasecmp(mime_type, "H264") == 0) || (g_ascii_strcasecmp(mime_type, "H264-SVC") == 0))) {
1335
0
        if (strcmp(field_name, "profile-level-id") == 0) {
1336
0
            int length = 0;
1337
1338
0
            data_tvb = ascii_bytes_to_tvb(tvb, pinfo, format_specific_parameter);
1339
0
            if (!data_tvb) {
1340
0
                proto_tree_add_expert_format(tree, pinfo, &ei_sdp_invalid_conversion, tvb, offset, tokenlen, "Could not convert '%s' to 3 bytes", format_specific_parameter);
1341
0
                return;
1342
0
            }
1343
0
            length = tvb_reported_length(data_tvb);
1344
0
            if (length == 3) {
1345
0
                if (h264_handle && data_tvb) {
1346
0
                    dissect_h264_profile(data_tvb, pinfo, tree);
1347
0
                }
1348
0
            } else {
1349
0
                item = proto_tree_add_expert_format(tree, pinfo, &ei_sdp_invalid_conversion, tvb, offset, tokenlen, "Incorrectly coded, must be three bytes");
1350
0
                proto_item_set_generated(item);
1351
0
            }
1352
0
        } else if (strcmp(field_name, "packetization-mode") == 0) {
1353
0
            item = proto_tree_add_uint(tree, hf_sdp_h264_packetization_mode, tvb, offset, tokenlen,
1354
0
                                       (uint32_t)strtol((char*)format_specific_parameter, NULL, 10));
1355
0
            proto_item_set_generated(item);
1356
0
        } else if (strcmp(field_name, "sprop-parameter-sets") == 0) {
1357
            /* The value of the parameter is the
1358
               base64 [6] representation of the initial
1359
               parameter set NAL units as specified in
1360
               sections 7.3.2.1 and 7.3.2.2 of [1].  The
1361
               parameter sets are conveyed in decoding order,
1362
               and no framing of the parameter set NAL units
1363
               takes place.  A comma is used to separate any
1364
               pair of parameter sets in the list.
1365
            */
1366
0
            const char *data_p = NULL;
1367
0
            int    comma_offset;
1368
1369
0
            comma_offset = tvb_find_uint8(tvb, offset, -1, ',');
1370
0
            if (comma_offset != -1) {
1371
0
                tokenlen = comma_offset - offset;
1372
0
            } else {
1373
0
                tokenlen = end_offset - offset;
1374
0
            }
1375
1376
0
            proto_tree_add_item_ret_string(tree, hf_sdp_nal_unit_1_string, tvb, offset, tokenlen, ENC_UTF_8|ENC_NA, pinfo->pool, (const uint8_t**)&data_p);
1377
1378
0
            data_tvb = base64_to_tvb(tvb, data_p);
1379
0
            add_new_data_source(pinfo, data_tvb, "h264 prop-parameter-sets");
1380
1381
0
            if (h264_handle && data_tvb) {
1382
0
                TRY {
1383
0
                    dissect_h264_nal_unit(data_tvb, pinfo, tree);
1384
0
                }
1385
0
                CATCH_NONFATAL_ERRORS {
1386
0
                    show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
1387
0
                }
1388
0
                ENDTRY;
1389
0
                if (comma_offset != -1) {
1390
                    /* Second NAL unit */
1391
0
                    offset   = comma_offset +1;
1392
0
                    tokenlen = end_offset - offset;
1393
0
                    proto_tree_add_item_ret_string(tree, hf_sdp_nal_unit_2_string, tvb, offset, tokenlen, ENC_UTF_8|ENC_NA, pinfo->pool, (const uint8_t**)&data_p);
1394
0
                    data_tvb = base64_to_tvb(tvb, data_p);
1395
0
                    add_new_data_source(pinfo, data_tvb, "h264 prop-parameter-sets 2");
1396
0
                    dissect_h264_nal_unit(data_tvb, pinfo, tree);
1397
0
                }
1398
0
            }
1399
0
        }
1400
0
    }
1401
1402
    /* Dissect the H265
1403
    * RFC 7798:
1404
    */
1405
0
    else if ((mime_type != NULL) && (g_ascii_strcasecmp(mime_type, "H265") == 0)) {
1406
0
        if (strcmp(field_name, "sprop-vps") == 0 || strcmp(field_name, "sprop-sps") == 0 || strcmp(field_name, "sprop-pps") == 0) {
1407
1408
0
            data_tvb = base64_to_tvb(tvb, format_specific_parameter);
1409
0
            add_new_data_source(pinfo, data_tvb, field_name);
1410
0
            if (h265_handle && data_tvb) {
1411
0
                dissect_h265_format_specific_parameter(tree, data_tvb, pinfo);
1412
0
            }
1413
0
        }
1414
0
    }
1415
1416
0
}
1417
1418
static const string_string ice_candidate_types[] = {
1419
    { "host",       "Host candidate" },
1420
    { "srflx",      "Server reflexive candidate" },
1421
    { "prflx",      "Peer reflexive candidate" },
1422
    { "relay",      "Relayed candidate" },
1423
    { NULL, NULL }
1424
};
1425
1426
static void
1427
dissect_sdp_media_attribute_candidate(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int offset)
1428
0
{
1429
    /* RFC 5245 (ICE): "The candidate attribute is a media-level attribute
1430
     * only. It contains a transport address for a candidate that can be
1431
     * used for connectivity checks."
1432
     * https://tools.ietf.org/html/rfc5245#section-15.1
1433
     *
1434
     *   candidate-attribute   = "candidate" ":" foundation SP component-id SP
1435
     *                           transport SP
1436
     *                           priority SP
1437
     *                           connection-address SP     ;from RFC 4566
1438
     *                           port         ;port from RFC 4566
1439
     *                           SP cand-type
1440
     *                           [SP rel-addr]
1441
     *                           [SP rel-port]
1442
     *                           *(SP extension-att-name SP
1443
     *                                extension-att-value)
1444
     *
1445
     * Example: "candidate:0 1 UDP 2122252543 10.9.0.2 60299 typ host"
1446
     */
1447
0
    proto_item   *pi;
1448
0
    int           next_offset, tokenlen;
1449
0
    const char   *candidate_type;
1450
1451
    /* foundation: between 1 and 32 "ICE chars" (ALPHA / DIGIT / "+" / "/") */
1452
0
    tokenlen = find_next_token_in_line(tvb, tree, &offset, &next_offset);
1453
0
    if (tokenlen == 0)
1454
0
        return;
1455
0
    proto_tree_add_item(tree, hf_ice_candidate_foundation,
1456
0
            tvb, offset, tokenlen, ENC_ASCII);
1457
0
    offset = next_offset + 1;
1458
1459
    /* component-id: integer between 1 and 256.
1460
     * For RTP, 1 MUST be RTP and 2 MUST be RTCP (RFC 5245) */
1461
0
    tokenlen = find_next_token_in_line(tvb, tree, &offset, &next_offset);
1462
0
    if (tokenlen == 0)
1463
0
        return;
1464
0
    proto_tree_add_item(tree, hf_ice_candidate_componentid,
1465
0
            tvb, offset, tokenlen, ENC_ASCII);
1466
0
    offset = next_offset + 1;
1467
1468
    /* transport: "UDP", etc. */
1469
0
    tokenlen = find_next_token_in_line(tvb, tree, &offset, &next_offset);
1470
0
    if (tokenlen == 0)
1471
0
        return;
1472
0
    proto_tree_add_item(tree, hf_ice_candidate_transport,
1473
0
            tvb, offset, tokenlen, ENC_ASCII);
1474
0
    offset = next_offset + 1;
1475
1476
    /* priority: integer between 1 and 2^31-1 */
1477
0
    tokenlen = find_next_token_in_line(tvb, tree, &offset, &next_offset);
1478
0
    if (tokenlen == 0)
1479
0
        return;
1480
0
    proto_tree_add_item(tree, hf_ice_candidate_priority,
1481
0
            tvb, offset, tokenlen, ENC_ASCII);
1482
0
    offset = next_offset + 1;
1483
1484
    /* connection-address: IPv4, IPv6 address or FQDN. */
1485
0
    tokenlen = find_next_token_in_line(tvb, tree, &offset, &next_offset);
1486
0
    if (tokenlen == 0)
1487
0
        return;
1488
0
    proto_tree_add_item(tree, hf_ice_candidate_address,
1489
0
            tvb, offset, tokenlen, ENC_ASCII);
1490
0
    offset = next_offset + 1;
1491
1492
    /* port */
1493
0
    tokenlen = find_next_token_in_line(tvb, tree, &offset, &next_offset);
1494
0
    if (tokenlen == 0)
1495
0
        return;
1496
0
    proto_tree_add_item(tree, hf_ice_candidate_port,
1497
0
            tvb, offset, tokenlen, ENC_ASCII);
1498
0
    offset = next_offset + 1;
1499
1500
    /* cand-type: type of candidate (where it learned the candidate)
1501
     * Check for "typ " in "typ host" and skip it. */
1502
0
    if (tvb_strneql(tvb, offset, "typ ", 4))
1503
0
        return;
1504
0
    offset += 4;
1505
0
    tokenlen = find_next_token_in_line(tvb, tree, &offset, &next_offset);
1506
0
    if (tokenlen == 0)
1507
0
        return;
1508
0
    pi = proto_tree_add_item_ret_string(tree, hf_ice_candidate_type,
1509
0
            tvb, offset, tokenlen, ENC_ASCII|ENC_NA,
1510
0
            pinfo->pool, (const uint8_t**)&candidate_type);
1511
0
    if ((candidate_type = try_str_to_str(candidate_type, ice_candidate_types))) {
1512
0
        proto_item_append_text(pi, " (%s)", candidate_type);
1513
0
    }
1514
    /* offset = next_offset + 1; */
1515
1516
    /* Ignored: [rel-addr] [rel-port] *(extension-att-name extension-att-value) */
1517
0
}
1518
1519
typedef struct {
1520
  const char *name;
1521
} sdp_names_t;
1522
1523
0
#define SDP_RTPMAP              1
1524
0
#define SDP_FMTP                2
1525
0
#define SDP_PATH                3
1526
0
#define SDP_H248_ITEM           4
1527
0
#define SDP_CRYPTO              5
1528
#define SDP_SPRTMAP             6
1529
0
#define SDP_CANDIDATE           7
1530
0
#define SDP_ED137_TYPE          8
1531
0
#define SDP_ED137_TXRXMODE      9
1532
0
#define SDP_ED137_FID           10
1533
0
#define SDP_RTCP                11
1534
0
#define SDP_RTCP_MUX            12
1535
0
#define SDP_CONTROL             13
1536
1537
static const sdp_names_t sdp_media_attribute_names[] = {
1538
    { "Unknown-name"},    /* 0 Pad so that the real headers start at index 1 */
1539
    { "rtpmap"},          /* 1 */
1540
    { "fmtp"},            /* 2 */
1541
    { "path"},            /* 3 */
1542
    { "h248item"},        /* 4 */
1543
    { "crypto"},          /* 5 */
1544
    { "sprt"},            /* 6 */
1545
    { "candidate" },      /* 7 */
1546
    { "type" },           /* 8 */
1547
    { "txrxmode" },       /* 9 */
1548
    { "fid" },            /* 10 */
1549
    { "rtcp" },           /* 11 */
1550
    { "rtcp-mux" },       /* 12 */
1551
    { "control" },        /* 13 */
1552
};
1553
1554
static int find_sdp_media_attribute_names(tvbuff_t *tvb, int offset, unsigned len)
1555
0
{
1556
0
    unsigned i;
1557
1558
0
    for (i = 1; i < array_length(sdp_media_attribute_names); i++) {
1559
0
        if ((len == strlen(sdp_media_attribute_names[i].name)) &&
1560
0
            (tvb_strncaseeql(tvb, offset, sdp_media_attribute_names[i].name, len) == 0))
1561
0
            return i;
1562
0
    }
1563
1564
0
    return -1;
1565
0
}
1566
1567
/* A few protocols give the fmtp parameter as a string instead of a
1568
 * numeric payload type, list them here (lower case for comparison).
1569
 */
1570
static const string_string media_format_str_types[] = {
1571
    /* ETSI TS 102 472, ETSI TS 102 592 */
1572
    { "ipdc-kmm", "IP Datacast Key Management Message"},
1573
    { "ipdc-ksm", "IP Datacast Key Stream Message"},
1574
    /* ETSI TS 124 380 */
1575
    { "mcptt",    "Mission Critical Push To Talk"},
1576
    /* ETSI TS 124 581 */
1577
    { "mcvideo",  "Mission Critical Video"},
1578
    /* OMA PoC Control Plane */
1579
    { "tbcp",     "Talk Burst Control Protocol"},
1580
    { NULL, NULL }
1581
};
1582
1583
static void
1584
dissect_sdp_media_attribute_rtpmap(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int length,
1585
                                   transport_info_t *transport_info, session_info_t *session_info,
1586
                                   media_description_t *media_desc, int offset)
1587
0
{
1588
0
    int           next_offset, tokenlen;
1589
0
    const char   *payload_type;
1590
0
    proto_item   *pi;
1591
0
    uint8_t       pt;
1592
1593
    /* RFC 8866 6.6 rtpmap
1594
       Syntax:
1595
          rtpmap-value = payload-type SP encoding-name
1596
          "/" clock-rate [ "/" encoding-params ]
1597
          payload-type = zero-based-integer
1598
          encoding-name = token
1599
          clock-rate = integer
1600
          encoding-params = channels
1601
          channels = integer
1602
     */
1603
0
    next_offset = tvb_find_uint8(tvb, offset, -1, ' ');
1604
1605
0
    if (next_offset == -1)
1606
0
        return;
1607
1608
0
    tokenlen = next_offset - offset;
1609
1610
0
    proto_tree_add_item_ret_string(tree, hf_media_format, tvb,
1611
0
                                   offset, tokenlen, ENC_UTF_8|ENC_NA, pinfo->pool,
1612
0
                                   (const uint8_t**)&payload_type);
1613
1614
0
    offset = next_offset + 1;
1615
1616
0
    next_offset = tvb_find_uint8(tvb, offset, -1, '/');
1617
1618
0
    if (next_offset == -1) {
1619
0
        return;
1620
0
    }
1621
1622
0
    tokenlen = next_offset - offset;
1623
1624
0
    proto_tree_add_item(tree, hf_media_encoding_name, tvb,
1625
0
                        offset, tokenlen, ENC_UTF_8);
1626
1627
0
    if (!ws_strtou8(payload_type, NULL, &pt) || pt >= SDP_NO_OF_PT) {
1628
0
        return;   /* Invalid */
1629
0
    }
1630
1631
    /* String is file scope allocated because transport_info is connection related */
1632
0
    transport_info->encoding_name[pt] = (char*)tvb_get_string_enc(wmem_file_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
1633
1634
0
    offset = next_offset + 1;
1635
1636
0
    next_offset = tvb_find_uint8(tvb, offset, length - offset, '/');
1637
0
    if (next_offset == -1) {
1638
0
        next_offset = length;
1639
0
    }
1640
1641
0
    tokenlen = next_offset - offset;
1642
0
    pi = proto_tree_add_item(tree, hf_media_sample_rate, tvb,
1643
0
                             offset, tokenlen, ENC_UTF_8);
1644
0
    transport_info->sample_rate[pt] = 0;
1645
0
    if (!ws_strtou32((char*)tvb_get_string_enc(pinfo->pool, tvb, offset, tokenlen, ENC_UTF_8|ENC_NA),
1646
0
                     NULL, &transport_info->sample_rate[pt])) {
1647
0
        expert_add_info(pinfo, pi, &ei_sdp_invalid_sample_rate);
1648
0
    } else if (!strcmp(transport_info->encoding_name[pt], "G722")) {
1649
        // The reported sampling rate is 8000, but the actual value is
1650
        // 16kHz. https://tools.ietf.org/html/rfc3551#section-4.5.2
1651
0
        proto_item_append_text(pi, " (RTP clock rate is 8kHz, actual sampling rate is 16kHz)");
1652
0
    }
1653
1654
0
    transport_info->channels[pt] = 1;
1655
0
    if (media_desc && media_desc->media_types & RTP_MEDIA_AUDIO) {
1656
0
        if (next_offset < length) {
1657
0
            offset = next_offset + 1;
1658
0
            tokenlen = length - offset;
1659
0
            pi = proto_tree_add_item(tree, hf_media_channels, tvb,
1660
0
                                     offset, tokenlen, ENC_UTF_8);
1661
0
            if (!ws_strtou32((char*)tvb_get_string_enc(pinfo->pool, tvb, offset, tokenlen, ENC_UTF_8|ENC_NA),
1662
0
                             NULL, &transport_info->channels[pt])) {
1663
0
                expert_add_info(pinfo, pi, &ei_sdp_invalid_channels);
1664
0
            }
1665
0
        }
1666
0
    }
1667
    /* As per RFC2327 it is possible to have multiple Media Descriptions ("m=").
1668
       For example:
1669
1670
       a=rtpmap:101 G726-32/8000
1671
       m=audio 49170 RTP/AVP 0 97
1672
       a=rtpmap:97 telephone-event/8000
1673
       m=audio 49172 RTP/AVP 97 101
1674
       a=rtpmap:97 G726-24/8000
1675
1676
       The Media attributes ("a="s) after the "m=" only apply for that "m=".
1677
       If there is an "a=" before the first "m=", that attribute applies for
1678
       all the session (all the "m="s).
1679
    */
1680
1681
0
    if (session_info) {
1682
        /* If this "a=" appear before any "m=", we add it to the session
1683
         * info, these will be added later to all media (via
1684
         * sdp_new_media_description).
1685
         *
1686
         * NOTE: This should not happen, because rtpmap is Usage Level: media
1687
         * (RFC 8866 6.6, also RFC 4566 6, and heavily implied by RFC 2327)
1688
         */
1689
0
        rtp_dyn_payload_insert(session_info->rtp_dyn_payload,
1690
0
                               pt,
1691
0
                               transport_info->encoding_name[pt],
1692
0
                               transport_info->sample_rate[pt],
1693
0
                               transport_info->channels[pt]);
1694
0
    } else if (media_desc) {
1695
        /* if the "a=" is after an "m=", only apply to this "m=" */
1696
0
        rtp_dyn_payload_insert(media_desc->media.rtp_dyn_payload,
1697
0
                               pt,
1698
0
                               transport_info->encoding_name[pt],
1699
0
                               transport_info->sample_rate[pt],
1700
0
                               transport_info->channels[pt]);
1701
0
    }
1702
0
}
1703
1704
static void
1705
dissect_sdp_media_attribute_fmtp(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
1706
                                 transport_info_t *transport_info, session_info_t *session_info,
1707
                                 media_description_t *media_desc, int offset)
1708
0
{
1709
0
    int           next_offset, tokenlen;
1710
0
    proto_item   *fmtp_item, *media_format_item;
1711
0
    const char   *payload_type;
1712
0
    const char   *media_format_str;
1713
0
    proto_tree   *fmtp_tree;
1714
0
    bool          has_more_pars      = true;
1715
    /* Reading the Format parameter(fmtp) */
1716
0
    uint8_t       media_format;
1717
1718
    /* Skip leading space, if any */
1719
0
    offset = tvb_skip_wsp(tvb, offset, tvb_captured_length_remaining(tvb, offset));
1720
    /* Media format extends to the next space */
1721
0
    next_offset = tvb_find_uint8(tvb, offset, -1, ' ');
1722
1723
0
    if (next_offset == -1)
1724
0
        return;
1725
1726
0
    tokenlen = next_offset - offset;
1727
1728
0
    media_format_item = proto_tree_add_item_ret_string(tree, hf_media_format, tvb,
1729
0
                                                       offset, tokenlen, ENC_UTF_8 | ENC_NA, pinfo->pool,
1730
0
                                                       (const uint8_t**)&payload_type);
1731
1732
    /* Append encoding name to format if known */
1733
0
    payload_type = wmem_ascii_strdown(pinfo->pool, payload_type, -1);
1734
0
    media_format = 0;
1735
0
    if ((media_format_str = try_str_to_str(payload_type, media_format_str_types))) {
1736
1737
0
        proto_item_append_text(media_format_item, " [%s]",
1738
0
                               media_format_str);
1739
0
    } else if (ws_strtou8(payload_type, NULL, &media_format) && media_format < SDP_NO_OF_PT) {
1740
0
        if (media_format) {
1741
0
            proto_item_append_text(media_format_item, " [%s]",
1742
0
                                   transport_info->encoding_name[media_format]);
1743
0
        }
1744
0
    } else {
1745
0
        expert_add_info(pinfo, media_format_item, &ei_sdp_invalid_media_format);
1746
0
        return;
1747
0
    }
1748
1749
1750
#if 0 /* XXX:  ?? */
1751
    payload_type = tvb_get_string_enc(pinfo->pool, tvb, offset, tokenlen, ENC_ASCII);
1752
#endif
1753
    /* Move offset past the payload type */
1754
0
    offset = next_offset + 1;
1755
1756
0
    while (has_more_pars == true) {
1757
0
        next_offset = tvb_find_uint8(tvb, offset, -1, ';');
1758
0
        offset = tvb_skip_wsp(tvb, offset, tvb_captured_length_remaining(tvb, offset));
1759
1760
0
        if (next_offset == -1) {
1761
0
            has_more_pars = false;
1762
0
            next_offset= tvb_captured_length(tvb);
1763
0
        }
1764
1765
        /* There are at least 2 - add the first parameter */
1766
0
        tokenlen = next_offset - offset;
1767
0
        fmtp_item = proto_tree_add_item(tree, hf_media_format_specific_parameter, tvb,
1768
0
                                        offset, tokenlen, ENC_UTF_8);
1769
1770
0
        fmtp_tree = proto_item_add_subtree(fmtp_item, ett_sdp_fmtp);
1771
1772
0
        rtp_dyn_payload_t *rtp_dyn_payload = NULL;
1773
0
        if (session_info) {
1774
0
            rtp_dyn_payload = session_info->rtp_dyn_payload;
1775
0
        } else if (media_desc) {
1776
0
            rtp_dyn_payload = media_desc->media.rtp_dyn_payload;
1777
0
        }
1778
0
        decode_sdp_fmtp(fmtp_tree, tvb, pinfo, offset, tokenlen,
1779
0
                        media_format, transport_info, rtp_dyn_payload);
1780
1781
        /* Move offset past "; " and onto first char */
1782
0
        offset = next_offset + 1;
1783
0
    }
1784
0
}
1785
1786
static void
1787
dissect_sdp_media_attribute_path(packet_info *pinfo, tvbuff_t *tvb, char *attribute_value,
1788
                                 media_description_t *media_desc, const char *msrp_res, int offset)
1789
0
{
1790
    /* msrp attributes that contain address needed for conversation */
1791
    /*    RFC 4975
1792
     *    path = path-label ":" path-list
1793
     *    path-label = "path"
1794
     *    path-list= MSRP-URI *(SP MSRP-URI)
1795
     *    MSRP-URI = msrp-scheme "://" authority
1796
     *       ["/" session-id] ";" transport *( ";" URI-parameter)
1797
     *                        ; authority as defined in RFC3986
1798
     *
1799
     *    msrp-scheme = "msrp" / "msrps"
1800
     * RFC 3986
1801
     * The authority component is preceded by a double slash ("//") and is terminated by
1802
     * the next slash ("/"), question mark ("?"), or number sign ("#") character, or by
1803
     * the end of the URI.
1804
     */
1805
1806
    /* Check for "msrp://" */
1807
0
    if (strncmp(attribute_value, msrp_res, strlen(msrp_res)) == 0 && msrp_handle &&
1808
0
        media_desc && media_desc->proto == SDP_PROTO_MSRP) {
1809
0
        int address_offset, port_offset, port_end_offset;
1810
1811
        /* Address starts here */
1812
0
        address_offset = offset + (int)strlen(msrp_res);
1813
1814
        /* Port is after next ':' */
1815
0
        port_offset = tvb_find_uint8(tvb, address_offset, -1, ':');
1816
        /* Check if port is present, if not skip */
1817
0
        if (port_offset!= -1) {
1818
            /* Port ends with '/' */
1819
0
            port_end_offset = tvb_find_uint8(tvb, port_offset, -1, '/');
1820
0
            if (port_end_offset == -1) {
1821
                /* No "/" look for the ";" */
1822
0
                port_end_offset = tvb_find_uint8(tvb, port_offset, -1, ';');
1823
0
            }
1824
            /* Attempt to convert address */
1825
0
            uint32_t msrp_ipaddr;
1826
0
            uint16_t msrp_port_number;
1827
0
            if (str_to_ip((char*)tvb_get_string_enc(pinfo->pool, tvb, address_offset, port_offset-address_offset, ENC_UTF_8|ENC_NA),
1828
0
                          &msrp_ipaddr)) {
1829
                /* Get port number */
1830
0
                if (ws_strtou16((char*)tvb_get_string_enc(pinfo->pool, tvb, port_offset + 1,
1831
0
                                                   port_end_offset - port_offset - 1, ENC_UTF_8|ENC_NA), NULL, &msrp_port_number)) {
1832
                    /* Port and address are usable, store for later use in
1833
                     * complete_descriptions (overrides the "c=" address). */
1834
0
                    alloc_address_wmem(wmem_file_scope(), &media_desc->media_attr.msrp.ipaddr, AT_IPv4, 4, &msrp_ipaddr);
1835
0
                    media_desc->media_attr.msrp.port_number = msrp_port_number;
1836
0
                }
1837
0
            }
1838
0
        }
1839
0
    }
1840
0
}
1841
1842
static void
1843
dissect_sdp_media_attribute_h248_item(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
1844
                                      char *attribute_value, const char *msrp_res)
1845
0
{
1846
0
    const char   *h324ext_h223lcparm = "h324ext/h223lcparm";
1847
0
    tvbuff_t     *h245_tvb;
1848
1849
0
    if (strncmp((char*)attribute_value, h324ext_h223lcparm, strlen(msrp_res)) == 0) {
1850
        /* A.5.1.3 H.223 Logical channel parameters
1851
         * This property indicates the H.245
1852
         * H223LogicalChannelsParameters structure encoded by applying the PER specified in
1853
         * ITU-T Rec. X.691. Value encoded as per A.5.1.2. For text encoding the mechanism defined
1854
         * in ITU-T Rec. H.248.15 is used.
1855
         *
1856
         * H.248.15 6 IANA considerations
1857
         * The format of the Package attribute is as below:
1858
         *     a=h248item:<package name>/<property name> = <value>
1859
         */
1860
0
        asn1_ctx_t actx;
1861
1862
0
        attribute_value = strchr(attribute_value, '=');
1863
0
        if (!attribute_value) {
1864
0
            return;
1865
0
        }
1866
1867
0
        h245_tvb = ascii_bytes_to_tvb(tvb, pinfo, ++attribute_value);
1868
        /* should go through a handle, however,  the two h245 entry
1869
           points are different, one is over tpkt and the other is raw
1870
        */
1871
0
        if (h245_tvb) {
1872
0
            asn1_ctx_init(&actx, ASN1_ENC_PER, true, pinfo);
1873
0
            dissect_h245_H223LogicalChannelParameters(h245_tvb, 0, &actx,
1874
0
                                                      tree,hf_SDPh223LogicalChannelParameters);
1875
0
        }
1876
0
    }
1877
0
}
1878
1879
static void
1880
dissect_sdp_media_attribute_crypto(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb,
1881
                                   transport_info_t *transport_info, int offset)
1882
0
{
1883
    /* https://tools.ietf.org/html/rfc4568
1884
    * 9.1.  Generic "Crypto" Attribute Grammar
1885
    *
1886
    *   The ABNF grammar for the crypto attribute is defined below:
1887
    *
1888
    *   "a=crypto:" tag 1*WSP crypto-suite 1*WSP key-params
1889
    *                                           *(1*WSP session-param)
1890
    *
1891
    *   tag              = 1*9DIGIT
1892
    *   crypto-suite     = 1*(ALPHA / DIGIT / "_")
1893
    *
1894
    *   key-params       = key-param *(";" key-param)
1895
    *   key-param        = key-method ":" key-info
1896
    *   key-method       = "inline" / key-method-ext
1897
    *   key-method-ext   = 1*(ALPHA / DIGIT / "_")
1898
    *   key-info         = 1*(%x21-3A / %x3C-7E) ; visible (printing) chars
1899
    *                                        ; except semi-colon
1900
    *  session-param    = 1*(VCHAR)         ; visible (printing) characters
1901
    *
1902
    *   where WSP, ALPHA, DIGIT, and VCHAR are defined in [RFC4234].
1903
    *
1904
    */
1905
0
    int           next_offset, tokenlen;
1906
0
    proto_tree   *parameter_item;
1907
0
    proto_item   *parameter_tree;
1908
0
    uint32_t      crypto_tag;
1909
0
    bool          crypto_tag_valid;
1910
0
    bool          has_more_pars      = true;
1911
0
    uint8_t       master_key_length  = 0, master_salt_length = 0;
1912
0
    bool          mki_len_valid;
1913
0
    proto_item   *pi;
1914
1915
    /* We are at the first colon */
1916
    /* tag */
1917
0
    tokenlen = find_next_token_in_line(tvb, tree, &offset, &next_offset);
1918
0
    if (tokenlen == 0)
1919
0
        return;
1920
0
    crypto_tag_valid = ws_strtou32((char*)tvb_get_string_enc(pinfo->pool, tvb, offset,
1921
0
                                                      tokenlen, ENC_UTF_8|ENC_NA), NULL, &crypto_tag);
1922
0
    pi = proto_tree_add_uint(tree, hf_sdp_crypto_tag, tvb, offset, tokenlen, crypto_tag);
1923
0
    if (!crypto_tag_valid)
1924
0
        expert_add_info(pinfo, pi, &ei_sdp_invalid_crypto_tag);
1925
0
    offset = next_offset + 1;
1926
1927
    /* crypto-suite */
1928
0
    tokenlen = find_next_token_in_line(tvb, tree, &offset, &next_offset);
1929
0
    if (tokenlen == 0)
1930
0
        return;
1931
0
    parameter_item = proto_tree_add_item(tree, hf_sdp_crypto_crypto_suite, tvb, offset, tokenlen, ENC_UTF_8);
1932
0
    if (tvb_strncaseeql(tvb, offset, "AES_CM_128_HMAC_SHA1_80", tokenlen) == 0) {
1933
1934
        /* XXX This may only work in simple cases */
1935
0
        if (transport_info->encryption_algorithm == SRTP_ENC_ALG_NOT_SET) {
1936
0
            transport_info->encryption_algorithm = SRTP_ENC_ALG_AES_CM;
1937
0
            transport_info->auth_algorithm       = SRTP_AUTH_ALG_HMAC_SHA1;
1938
            /* number of octets used for the Auth Tag in the RTP payload */
1939
0
            transport_info->auth_tag_len         = 10;
1940
0
        }
1941
0
        master_key_length  = 16; /* 128 bits = 16 octets */
1942
0
        master_salt_length = 14; /* 112 bits = 14 octets */
1943
0
    } else if (tvb_strncaseeql(tvb, offset, "AES_CM_128_HMAC_SHA1_32", tokenlen) == 0) {
1944
        /* XXX This may only work in simple cases */
1945
0
        if (transport_info->encryption_algorithm == SRTP_ENC_ALG_NOT_SET) {
1946
0
            transport_info->encryption_algorithm = SRTP_ENC_ALG_AES_CM;
1947
0
            transport_info->auth_algorithm       = SRTP_AUTH_ALG_HMAC_SHA1;
1948
            /* number of octets used for the Auth Tag in the RTP payload */
1949
0
            transport_info->auth_tag_len         = 4;
1950
0
        }
1951
0
        master_key_length  = 16; /* 128 bits = 16 octets */
1952
0
        master_salt_length = 14; /* 112 bits = 14 octets */
1953
0
    } else if (tvb_strncaseeql(tvb, offset, "F8_128_HMAC_SHA1_80", tokenlen) == 0) {
1954
0
        if (transport_info->encryption_algorithm == SRTP_ENC_ALG_NOT_SET) {
1955
            /* XXX This may only work in simple cases */
1956
0
            transport_info->encryption_algorithm = SRTP_ENC_ALG_AES_F8;
1957
0
            transport_info->auth_algorithm       = SRTP_AUTH_ALG_HMAC_SHA1;
1958
            /* number of octets used for the Auth Tag in the RTP payload */
1959
0
            transport_info->auth_tag_len         = 10;
1960
0
        }
1961
0
        master_key_length  = 16; /* 128 bits = 16 octets */
1962
0
        master_salt_length = 14; /* 112 bits = 14 octets */
1963
0
    }
1964
0
    offset = next_offset + 1;
1965
1966
    /* key-params */
1967
0
    while (has_more_pars == true) {
1968
0
        int       param_end_offset;
1969
0
        tvbuff_t *key_salt_tvb;
1970
0
        char     *data_p = NULL;
1971
1972
0
        param_end_offset = tvb_find_uint8(tvb, offset, -1, ';');
1973
0
        if (param_end_offset == -1) {
1974
0
            has_more_pars = false;
1975
0
            param_end_offset = tvb_captured_length(tvb);
1976
0
        }
1977
        /* key-method or key-method-ext */
1978
0
        next_offset = tvb_find_uint8(tvb, offset, -1, ':');
1979
0
        if (next_offset == -1) {
1980
0
            expert_add_info(pinfo, parameter_item, &ei_sdp_invalid_key_param);
1981
0
            break;
1982
0
        }
1983
1984
0
        if (tvb_strncaseeql(tvb, offset, "inline", next_offset-offset) == 0) {
1985
0
            parameter_tree = proto_tree_add_subtree(tree, tvb, offset,param_end_offset-offset,
1986
0
                                                    ett_sdp_crypto_key_parameters, NULL, "Key parameters");
1987
            /* XXX only for SRTP? */
1988
            /* srtp-key-info       = key-salt ["|" lifetime] ["|" mki] */
1989
0
            offset      = next_offset +1;
1990
0
            next_offset = tvb_find_uint8(tvb, offset, -1, '|');
1991
0
            if (next_offset == -1) {
1992
0
                tokenlen = param_end_offset - offset;
1993
0
            } else {
1994
0
                tokenlen = next_offset - offset;
1995
0
            }
1996
0
            data_p = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
1997
0
            key_salt_tvb = base64_to_tvb(tvb, data_p);
1998
0
            add_new_data_source(pinfo, key_salt_tvb, "Key_Salt_tvb");
1999
0
            if (master_key_length != 0) {
2000
0
                proto_tree_add_item(parameter_tree, hf_sdp_key_and_salt, tvb, offset, tokenlen, ENC_NA);
2001
0
                proto_tree_add_item(parameter_tree, hf_sdp_crypto_master_key,
2002
0
                                    key_salt_tvb, 0, master_key_length, ENC_NA);
2003
0
                proto_tree_add_item(parameter_tree, hf_sdp_crypto_master_salt,
2004
0
                                    key_salt_tvb, master_key_length, master_salt_length, ENC_NA);
2005
0
            } else {
2006
0
                proto_tree_add_item(parameter_tree, hf_sdp_key_and_salt, key_salt_tvb, 0, -1, ENC_NA);
2007
0
            }
2008
2009
            /*  ["|" lifetime] ["|" mki] are optional */
2010
0
            if (next_offset != -1) {
2011
0
                offset = next_offset + 1;
2012
0
                next_offset = tvb_find_uint8(tvb, offset, -1, '|');
2013
0
                if (next_offset == -1) {
2014
0
                    if (next_offset < param_end_offset){
2015
0
                        next_offset = param_end_offset;
2016
0
                    }
2017
0
                }
2018
0
                if (next_offset != -1) {
2019
                    /*lifetime           = ["2^"] 1*(DIGIT)   ; see section 6.1 for "2^" */
2020
0
                    tokenlen = next_offset - offset;
2021
0
                    proto_tree_add_item(parameter_tree, hf_sdp_crypto_lifetime,
2022
0
                                        tvb, offset, tokenlen, ENC_UTF_8);
2023
0
                    offset   = next_offset + 1;
2024
0
                }
2025
                /* mki                 = mki-value ":" mki-length
2026
                *
2027
                * mki-value           = 1*DIGIT
2028
                */
2029
0
                if (offset>param_end_offset) {
2030
0
                    next_offset = -1;
2031
0
                } else {
2032
0
                    next_offset = tvb_find_uint8(tvb, offset, -1, ':');
2033
0
                }
2034
0
                if (next_offset != -1) {
2035
0
                    tokenlen    = next_offset - offset;
2036
0
                    proto_tree_add_item(parameter_tree, hf_sdp_crypto_mki, tvb, offset, tokenlen, ENC_UTF_8);
2037
0
                    offset      = next_offset + 1;
2038
2039
                    /* mki-length          = 1*3DIGIT   ; range 1..128. */
2040
0
                    next_offset = param_end_offset;
2041
0
                    tokenlen    = next_offset - offset;
2042
2043
                    /* This will not work if more than one parameter */
2044
                    /* number of octets used for the MKI in the RTP payload */
2045
0
                    mki_len_valid = ws_strtou32((char*)tvb_get_string_enc(pinfo->pool, tvb, offset, tokenlen,
2046
0
                                                                   ENC_UTF_8|ENC_NA), NULL, &transport_info->mki_len);
2047
0
                    pi = proto_tree_add_item(parameter_tree, hf_sdp_crypto_mki_length,
2048
0
                                             tvb, offset, tokenlen, ENC_UTF_8);
2049
0
                    if (!mki_len_valid)
2050
0
                        expert_add_info(pinfo, pi, &ei_sdp_invalid_crypto_mki_length);
2051
0
                }
2052
0
            }
2053
0
            offset = param_end_offset;
2054
0
        } else {
2055
0
            break;
2056
0
        }
2057
0
    }
2058
0
}
2059
2060
static void dissect_sdp_media_attribute(tvbuff_t *tvb, packet_info *pinfo, proto_item * ti, int length,
2061
                                        transport_info_t *transport_info,
2062
                                        session_info_t *session_info,
2063
                                        media_description_t *media_desc,
2064
                                        sdp_data_t *sdp_data)
2065
0
{
2066
0
    proto_tree   *sdp_media_attribute_tree;
2067
0
    proto_item   *pi;
2068
0
    int           offset, tokenlen, colon_offset;
2069
0
    char         *attribute_value;
2070
0
    int           sdp_media_attrbute_code;
2071
0
    const char   *msrp_res           = "msrp://";
2072
2073
0
    offset = 0;
2074
2075
    /* Create attribute tree */
2076
0
    sdp_media_attribute_tree = proto_item_add_subtree(ti,
2077
0
                                                      ett_sdp_media_attribute);
2078
    /* Find end of field */
2079
0
    colon_offset = tvb_find_uint8(tvb, offset, -1, ':');
2080
2081
0
    if (colon_offset == -1)
2082
0
      return;
2083
2084
    /* Attribute field name is token before ':' */
2085
0
    tokenlen = colon_offset - offset;
2086
0
    pi = proto_tree_add_item(sdp_media_attribute_tree,
2087
0
                             hf_media_attribute_field,
2088
0
                             tvb, offset, tokenlen, ENC_UTF_8);
2089
    /*??field_name = tvb_get_string_enc(pinfo->pool, tvb, offset, tokenlen, ENC_ASCII);*/
2090
0
    sdp_media_attrbute_code = find_sdp_media_attribute_names(tvb, offset, tokenlen);
2091
2092
    /* Skip colon */
2093
0
    offset = colon_offset + 1;
2094
    /* skip leading wsp */
2095
0
    offset = tvb_skip_wsp(tvb, offset, tvb_captured_length_remaining(tvb, offset));
2096
2097
    /* Value is the remainder of the line */
2098
0
    if (tvb_captured_length_remaining(tvb, offset) > 0)
2099
0
        attribute_value = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_UTF_8|ENC_NA);
2100
0
    else
2101
0
    {
2102
0
        expert_add_info(pinfo, pi, &ei_sdp_invalid_line_fields);
2103
0
        return;
2104
0
    }
2105
2106
    /*********************************************/
2107
    /* Special parsing for some field name types */
2108
2109
0
    switch (sdp_media_attrbute_code) {
2110
0
        case SDP_RTPMAP:
2111
            /* decode the rtpmap to see if it is DynamicPayload to dissect them automatic */
2112
0
            dissect_sdp_media_attribute_rtpmap(sdp_media_attribute_tree, pinfo, tvb, length, transport_info,
2113
0
                                               session_info, media_desc, offset);
2114
0
            break;
2115
0
        case SDP_FMTP:
2116
0
            dissect_sdp_media_attribute_fmtp(sdp_media_attribute_tree, pinfo, tvb, transport_info,
2117
0
                                               session_info, media_desc, offset);
2118
0
            break;
2119
0
        case SDP_PATH:
2120
0
            dissect_sdp_media_attribute_path(pinfo, tvb, attribute_value, media_desc, msrp_res, offset);
2121
0
            break;
2122
0
        case SDP_H248_ITEM:
2123
            /* Decode h248 item ITU-T Rec. H.248.12 (2001)/Amd.1 (11/2002)*/
2124
0
            dissect_sdp_media_attribute_h248_item(sdp_media_attribute_tree, pinfo, tvb, attribute_value, msrp_res);
2125
0
            break;
2126
0
        case SDP_CRYPTO:
2127
0
            dissect_sdp_media_attribute_crypto(sdp_media_attribute_tree, pinfo, tvb, transport_info, offset);
2128
0
            break;
2129
0
        case SDP_CANDIDATE:
2130
0
            dissect_sdp_media_attribute_candidate(sdp_media_attribute_tree, pinfo, tvb, offset);
2131
0
            break;
2132
0
        case SDP_ED137_TYPE:
2133
            /* Remember the value and add it to tree */
2134
0
            sdp_data->ed137_type = attribute_value;
2135
0
            proto_tree_add_item(sdp_media_attribute_tree, hf_media_attribute_value,
2136
0
                                tvb, offset, -1, ENC_UTF_8);
2137
0
            break;
2138
0
        case SDP_ED137_TXRXMODE:
2139
            /* Remember the value and add it to tree */
2140
0
            sdp_data->ed137_txrxmode = attribute_value;
2141
0
            proto_tree_add_item(sdp_media_attribute_tree, hf_media_attribute_value,
2142
0
                                tvb, offset, -1, ENC_UTF_8);
2143
0
            break;
2144
0
        case SDP_ED137_FID:
2145
            /* Remember the value and add it to tree */
2146
0
            sdp_data->ed137_fid = attribute_value;
2147
0
            proto_tree_add_item(sdp_media_attribute_tree, hf_media_attribute_value,
2148
0
                                tvb, offset, -1, ENC_UTF_8);
2149
0
            break;
2150
0
        case SDP_RTCP :
2151
0
            if (media_desc) {
2152
0
                if (!ws_strtou16(attribute_value, NULL, &media_desc->control_port))
2153
0
                    media_desc->control_port = 0; /* Just use default, if not legal port */
2154
0
            }
2155
0
            proto_tree_add_item(sdp_media_attribute_tree, hf_media_attribute_value,
2156
0
                                tvb, offset, -1, ENC_UTF_8);
2157
0
            break;
2158
0
        case SDP_RTCP_MUX :
2159
0
            if (media_desc) {
2160
0
                media_desc->control_port = media_desc->media_port;
2161
0
            }
2162
0
            proto_tree_add_item(sdp_media_attribute_tree, hf_media_attribute_value,
2163
0
                                tvb, offset, -1, ENC_UTF_8);
2164
0
            break;
2165
0
        case SDP_CONTROL:
2166
0
            if (media_desc) {
2167
0
                media_desc->control_uri = wmem_ascii_strdown(wmem_file_scope(), attribute_value, -1);
2168
0
            }
2169
0
            proto_tree_add_item(sdp_media_attribute_tree, hf_media_attribute_value,
2170
0
                                tvb, offset, -1, ENC_UTF_8);
2171
0
            break;
2172
0
        default:
2173
            /* No special treatment for values of this attribute type, just add as one item. */
2174
0
            proto_tree_add_item(sdp_media_attribute_tree, hf_media_attribute_value,
2175
0
                                tvb, offset, -1, ENC_UTF_8);
2176
0
            break;
2177
0
    }
2178
0
}
2179
2180
static void
2181
call_sdp_subdissector(tvbuff_t *tvb, packet_info *pinfo, int hf, proto_tree* ti, int length,
2182
                      transport_info_t *transport_info,
2183
                      session_info_t *session_info,
2184
                      media_description_t *media_desc,
2185
                      sdp_data_t *sdp_data)
2186
1.65k
{
2187
1.65k
    if (hf == hf_owner) {
2188
135
        dissect_sdp_owner(tvb, ti);
2189
1.51k
    } else if (hf == hf_connection_info) {
2190
198
        dissect_sdp_connection_info(pinfo, tvb, ti, session_info, media_desc);
2191
1.31k
    } else if (hf == hf_bandwidth) {
2192
15
        dissect_sdp_bandwidth(tvb, ti);
2193
1.30k
    } else if (hf == hf_time) {
2194
7
        dissect_sdp_time(tvb, ti);
2195
1.29k
    } else if (hf == hf_repeat_time) {
2196
92
        dissect_sdp_repeat_time(tvb, ti);
2197
1.20k
    } else if (hf == hf_timezone) {
2198
116
        dissect_sdp_timezone(tvb, ti);
2199
1.08k
    } else if (hf == hf_encryption_key) {
2200
29
        dissect_sdp_encryption_key(tvb, ti);
2201
1.05k
    } else if (hf == hf_session_attribute) {
2202
0
        dissect_sdp_session_attribute(tvb, pinfo, ti);
2203
1.05k
    } else if (hf == hf_media) {
2204
930
        dissect_sdp_media(tvb, pinfo, ti, media_desc);
2205
930
    } else if (hf == hf_media_attribute) {
2206
0
        dissect_sdp_media_attribute(tvb, pinfo, ti, length, transport_info, session_info, media_desc, sdp_data);
2207
0
    }
2208
1.65k
}
2209
2210
/**
2211
 * Post-processes the media descriptions after parsing it from the tvb. This
2212
 * performs processing that can only be done when the full media description is
2213
 * parsed (since otherwise the order of attributes could influence the result).
2214
 * Must be called before applying the SDP with apply_sdp_transport.
2215
 * It will remove media streams when the port number in the answer is zero.
2216
 *
2217
 * If the currently processed SDP is an Answer to a known previous Offer, then
2218
 * answer_offset is non-zero.
2219
 */
2220
static void
2221
complete_descriptions(transport_info_t *transport_info, unsigned answer_offset)
2222
307
{
2223
307
    unsigned media_count = wmem_array_get_count(transport_info->media_descriptions);
2224
307
    media_description_t *media_descs = (media_description_t *)wmem_array_get_raw(transport_info->media_descriptions);
2225
307
    media_description_t *bundle_media_desc = NULL;
2226
2227
307
    DPRINT(("complete_descriptions called with answer_offset=%d media_count=%d",
2228
307
            answer_offset, media_count));
2229
2230
492
    for (unsigned i = answer_offset; i < media_count && !bundle_media_desc; i++) {
2231
389
        for (unsigned j = i+1; j < media_count && !bundle_media_desc; j++) {
2232
204
            if (media_descs[i].media_port == media_descs[j].media_port)
2233
124
                bundle_media_desc = &media_descs[i];
2234
204
        }
2235
185
    }
2236
2237
307
    if (bundle_media_desc) {
2238
        /* We have "bundling" of media, so now combine all the media bit masks
2239
           and merge the rtp_dyn_payload so that the first media description
2240
           has all the data for every media description. */
2241
553
        for (unsigned i = answer_offset; i < media_count; i++) {
2242
429
            media_description_t *media_desc = &media_descs[i];
2243
2244
429
            if (bundle_media_desc->media_port == media_desc->media_port) {
2245
377
                media_desc->bundled = true;
2246
2247
377
                if (media_desc != bundle_media_desc) {
2248
253
                    bundle_media_desc->media_types |= media_desc->media_types;
2249
32.6k
                    for (unsigned pt = 0; pt < 128; ++pt) {
2250
32.3k
                        const char * encoding_name;
2251
32.3k
                        int sample_rate;
2252
32.3k
                        unsigned channels;
2253
32.3k
                        wmem_map_t *fmtp_map;
2254
32.3k
                        if (rtp_dyn_payload_get_full(media_desc->media.rtp_dyn_payload,
2255
32.3k
                                                     pt, &encoding_name, &sample_rate, &channels, &fmtp_map))
2256
0
                            rtp_dyn_payload_insert_full(bundle_media_desc->media.rtp_dyn_payload,
2257
0
                                                        pt, encoding_name, sample_rate, channels, fmtp_map);
2258
32.3k
                    }
2259
253
                }
2260
377
            }
2261
429
        }
2262
124
    }
2263
2264
782
    for (unsigned i = answer_offset; i < media_count; i++) {
2265
475
        media_description_t *media_desc = &media_descs[i];
2266
2267
475
        if (media_desc->control_port == 0)
2268
475
            media_desc->control_port = media_desc->media_port + 1;
2269
2270
475
        if (media_desc->control_port == 0)
2271
7
            media_desc->control_port = media_desc->media_port + 1;
2272
2273
        /* If this is an answer to a previous offer... */
2274
475
        if (answer_offset > 0) {
2275
            /* A zero port removes the media stream (RFC 3264, Section 8.2) */
2276
0
            if (media_desc->media_port == 0) {
2277
0
                DPRINT(("disabling media_port=%d, for index=%d",
2278
0
                        media_descs[i - answer_offset].media_port,
2279
0
                        i - answer_offset));
2280
0
                media_descs[i - answer_offset].media_port = 0;
2281
0
            }
2282
0
        }
2283
2284
        /* MSRP uses addresses discovered in attribute
2285
           rather than connection information of media session line */
2286
475
        if (media_desc->proto == SDP_PROTO_MSRP && msrp_handle &&
2287
0
            media_desc->media_attr.msrp.ipaddr.type != AT_NONE) {
2288
            /* clear old address and set new address and port. */
2289
0
            free_address_wmem(wmem_file_scope(), &media_desc->conn_addr);
2290
0
            copy_address_shallow(&media_desc->conn_addr,
2291
0
                                 &media_desc->media_attr.msrp.ipaddr);
2292
0
            media_desc->media_port = media_desc->media_attr.msrp.port_number;
2293
0
        }
2294
475
    }
2295
307
}
2296
2297
/**
2298
 * Given is a structure containing the parsed result from the SDP (including
2299
 * protocol type (RTP, SRTP, T38, etc.), media info (payload type, etc.) and
2300
 * connection info (address, port). Register the address+port such that the
2301
 * protocol will be invoked for this tuple with the media information.
2302
 *
2303
 * For use with SDP using the Offer/Answer model (such as SIP with INVITE and
2304
 * 200 OK).
2305
 * XXX what about RTSP where the SDP merely provides media info, without
2306
 * actually establishing connections (Bug 5208).
2307
 *
2308
 * The passed transport information is modified: 'set_rtp' is set when the media
2309
 * is assigned to a conversation. Note that the unassigned media (payload types)
2310
 * are not freed, this is the responsibility of the caller.
2311
 */
2312
static void
2313
apply_sdp_transport(packet_info *pinfo, transport_info_t *transport_info, int request_frame, sdp_setup_info_t *setup_info)
2314
307
{
2315
307
    int establish_frame = 0;
2316
307
    wmem_array_t *setup_info_list;
2317
2318
307
    struct srtp_info *srtp_info = NULL;
2319
2320
307
    if (!global_sdp_establish_conversation) {
2321
        /* Do not register with other dissectors when this pref is disabled. */
2322
0
        return;
2323
0
    }
2324
2325
    /* If no request_frame number has been found use this frame's number */
2326
307
    if (request_frame == 0) {
2327
307
        establish_frame = pinfo->num;
2328
307
    } else {
2329
0
        establish_frame = request_frame;
2330
0
    }
2331
2332
307
    bool bundled_media_set = false;
2333
2334
782
    for (unsigned i = 0; i < wmem_array_get_count(transport_info->media_descriptions); i++) {
2335
475
        media_description_t *media_desc =
2336
475
            (media_description_t *)wmem_array_index(transport_info->media_descriptions, i);
2337
475
        uint32_t current_rtp_port = 0;
2338
2339
        /* "a=control:" is an attribute unique to RTSP. RTSP uses the same
2340
         * transport types as RTP but the port is either zero or merely a
2341
         * suggestion, actual information is obtained by later RTSP methods.
2342
         * We do not apply the descriptor here but save it, keyed by the
2343
         * URI. (RTSP clients can also receive media description via other
2344
         * protocols like HTTP, so there is no guarantee that the RTSP protocol
2345
         * is the caller here.)
2346
         */
2347
475
        if (media_desc->control_uri) {
2348
            /* Ensure that we do not attempt to set it below. */
2349
0
            media_desc->media.set_rtp = true;
2350
0
            if (setup_info && setup_info->base_uri) {
2351
0
                char *absolute_uri = determine_http_location_target(wmem_file_scope(), setup_info->base_uri, media_desc->control_uri);
2352
0
                if (absolute_uri) {
2353
0
                    media_desc->control_uri = absolute_uri;
2354
0
                }
2355
0
            }
2356
0
            ascii_strdown_inplace(media_desc->control_uri);
2357
            /* If there are multiple entries with the same URI they SHOULD be
2358
             * the same, so we could free the existing entry.  */
2359
0
            rtp_dyn_payload_t *old_rtp_pt;
2360
0
            old_rtp_pt = wmem_map_insert(sdp_rtsp_control_map, media_desc->control_uri, media_desc->media.rtp_dyn_payload);
2361
0
            if (old_rtp_pt) {
2362
0
                rtp_dyn_payload_free(old_rtp_pt);
2363
0
            }
2364
0
        }
2365
2366
        /* Add (s)rtp and (s)rtcp conversation, if available (overrides t38 if conversation already set) */
2367
475
        if ((media_desc->media_port != 0) &&
2368
75
            !media_desc->media.set_rtp &&
2369
75
            (media_desc->proto == SDP_PROTO_RTP ||
2370
68
             media_desc->proto == SDP_PROTO_SRTP) &&
2371
7
            (media_desc->conn_addr.type == AT_IPv4 ||
2372
7
             media_desc->conn_addr.type == AT_IPv6)) {
2373
2374
0
            media_desc->media.set_rtp = true;
2375
2376
0
            if (media_desc->bundled) {
2377
0
                if (bundled_media_set)
2378
0
                    continue;
2379
0
                bundled_media_set = true;
2380
0
            }
2381
2382
0
            if (media_desc->proto == SDP_PROTO_SRTP) {
2383
0
                srtp_info = wmem_new0(wmem_file_scope(), struct srtp_info);
2384
0
                if (transport_info->encryption_algorithm != SRTP_ENC_ALG_NOT_SET) {
2385
0
                    srtp_info->encryption_algorithm = transport_info->encryption_algorithm;
2386
0
                    srtp_info->auth_algorithm       = transport_info->auth_algorithm;
2387
0
                    srtp_info->mki_len              = transport_info->mki_len;
2388
0
                    srtp_info->auth_tag_len         = transport_info->auth_tag_len;
2389
2390
0
                }
2391
0
                DPRINT(("calling srtp_add_address, channel=%d, media_port=%d",
2392
0
                        i, media_desc->media_port));
2393
0
                DINDENT();
2394
                /* srtp_add_address and rtp_add_address are given the request_frame's not this frame's number,
2395
                   because that's where the RTP flow started, and thus conversation needs to check against */
2396
0
                srtp_add_address(pinfo, PT_UDP, &media_desc->conn_addr, media_desc->media_port, 0, "SDP", establish_frame,
2397
0
                                 media_desc->media_types,
2398
0
                                 media_desc->media.rtp_dyn_payload, srtp_info,
2399
0
                                 setup_info);
2400
0
                DENDENT();
2401
0
            } else if (setup_info && setup_info->is_osmux) {
2402
0
                DPRINT(("calling osmux_add_address, channel=%d, media_port=%d",
2403
0
                        i, media_desc->media_port));
2404
0
                DINDENT();
2405
0
                osmux_add_address(pinfo, &media_desc->conn_addr, media_desc->media_port, 0, establish_frame);
2406
0
                DENDENT();
2407
0
            } else {
2408
0
                DPRINT(("calling rtp_add_address, channel=%d, media_port=%d",
2409
0
                        i, media_desc->media_port));
2410
0
                DINDENT();
2411
0
                srtp_add_address(pinfo, PT_UDP, &media_desc->conn_addr, media_desc->media_port, 0, "SDP", establish_frame,
2412
0
                                 media_desc->media_types,
2413
0
                                 media_desc->media.rtp_dyn_payload, NULL, setup_info);
2414
0
                DENDENT();
2415
0
            }
2416
            /* SPRT might use the same port... */
2417
0
            current_rtp_port = media_desc->media_port;
2418
2419
0
            if (rtcp_handle && media_desc->media_port != media_desc->control_port) {
2420
0
                if (media_desc->proto == SDP_PROTO_SRTP) {
2421
0
                    DPRINT(("calling rtcp_add_address, channel=%d, control_port=%d",
2422
0
                            i, media_desc->control_port));
2423
0
                    DINDENT();
2424
0
                    srtcp_add_address(pinfo, &media_desc->conn_addr, media_desc->control_port, 0, "SDP", establish_frame, srtp_info);
2425
0
                    DENDENT();
2426
0
                 } else if (!setup_info || !setup_info->is_osmux) {
2427
0
                    DPRINT(("calling rtcp_add_address, channel=%d, control_port=%d",
2428
0
                            i, media_desc->control_port));
2429
0
                    DINDENT();
2430
0
                    rtcp_add_address(pinfo, &media_desc->conn_addr, media_desc->control_port, 0, "SDP", establish_frame);
2431
0
                    DENDENT();
2432
0
                 }
2433
0
            }
2434
0
        }
2435
2436
        /* add SPRT conversation */
2437
475
        if (media_desc->proto == SDP_PROTO_SPRT &&
2438
0
            (media_desc->conn_addr.type == AT_IPv4 ||
2439
0
             media_desc->conn_addr.type == AT_IPv6) &&
2440
0
            (sprt_handle)) {
2441
2442
0
            if (media_desc->media_port == 0 && current_rtp_port) {
2443
0
                sprt_add_address(pinfo, &media_desc->conn_addr, current_rtp_port,
2444
0
                                 0, "SDP", pinfo->num); /* will use same port as RTP */
2445
0
            } else {
2446
0
                sprt_add_address(pinfo, &media_desc->conn_addr, media_desc->media_port, 0, "SDP", pinfo->num);
2447
0
            }
2448
0
        }
2449
2450
        /* Add t38 conversation, if available and only if no rtp */
2451
475
        if ((media_desc->media_port != 0) &&
2452
75
            !media_desc->media.set_rtp &&
2453
75
            media_desc->proto == SDP_PROTO_T38 &&
2454
0
            media_desc->conn_addr.type == AT_IPv4) {
2455
0
            t38_add_address(pinfo, &media_desc->conn_addr, media_desc->media_port, 0, "SDP", pinfo->num);
2456
0
        }
2457
2458
        /* Add MSRP conversation.  Uses addresses discovered in attribute
2459
           rather than connection information of media session line
2460
           (already handled in media conversion) */
2461
475
        if (media_desc->proto == SDP_PROTO_MSRP && msrp_handle) {
2462
0
            msrp_add_address(pinfo, &media_desc->conn_addr, media_desc->media_port, "SDP", pinfo->num);
2463
0
        }
2464
2465
        /* Add BFCP conversation.  Uses addresses discovered in attribute
2466
           rather than connection information of media session line
2467
           (already handled in media conversion) */
2468
475
        if (media_desc->proto == SDP_PROTO_BFCP && bfcp_handle) {
2469
0
            bfcp_add_address(pinfo, PT_UDP, &media_desc->conn_addr, media_desc->media_port, "SDP", establish_frame);
2470
0
        }
2471
475
    } /* end of loop through all media descriptions. */
2472
2473
    /* Copy the list of setup info of calls with the same RTP information
2474
     * to the transport info, so that we have it when dissecting the
2475
     * request as well.
2476
     * XXX - There can be multiple media descriptions, and while this SDP's
2477
     * setup info is on all of them, some other SDP might have some but not
2478
     * all media descriptions, so the arrays of setup infos might be different.
2479
     * They should be consolidated as with rtp_add_setup_info_if_no_duplicate()
2480
     * in packet-rtp.c, or stored with each media descriptor.
2481
     */
2482
307
    setup_info_list = p_get_proto_data(pinfo->pool, pinfo, proto_sdp, 0);
2483
307
    if (setup_info_list) {
2484
0
        transport_info->sdp_setup_info_list = setup_info_list;
2485
0
    }
2486
307
}
2487
2488
void
2489
setup_sdp_transport(tvbuff_t *tvb, packet_info *pinfo, enum sdp_exchange_type exchange_type,
2490
    int request_frame, const bool delay, sdp_setup_info_t *setup_info)
2491
0
{
2492
0
    int         offset = 0, next_offset, n;
2493
0
    int         linelen;
2494
0
    bool        in_media_description = false;
2495
0
    unsigned char      type, delim;
2496
0
    const int   tokenoffset = 2;
2497
0
    int         hf     = -1;
2498
0
    int         start_transport_info_count = 0;
2499
0
    transport_info_t* transport_info = NULL;
2500
0
    media_description_t *media_desc = NULL;
2501
0
    session_info_t session_info;
2502
0
    sdp_data_t  sdp_data;
2503
2504
0
    DPRINT2(("-------------------- setup_sdp_transport -------------------"));
2505
2506
    /* Only do this once during first pass */
2507
0
    if (pinfo->fd->visited) {
2508
0
        DPRINT(("already visited"));
2509
0
        return;
2510
0
    }
2511
2512
0
    memset(&sdp_data, 0, sizeof(sdp_data));
2513
2514
0
    if (request_frame != 0)
2515
0
        transport_info = (transport_info_t*)wmem_tree_lookup32( sdp_transport_reqs, request_frame );
2516
0
    if (transport_info == NULL) {
2517
0
        transport_info = wmem_new0(wmem_file_scope(), transport_info_t);
2518
0
        transport_info->media_descriptions = wmem_array_new(wmem_file_scope(), sizeof(media_description_t));
2519
2520
0
        for (n = 0; n < SDP_NO_OF_PT; n++) {
2521
            /* String is file scope allocated because transport_info is connection related */
2522
0
            transport_info->encoding_name[n] = wmem_strdup(wmem_file_scope(), UNKNOWN_ENCODING);
2523
0
        }
2524
2525
0
        if (request_frame != 0)
2526
0
            wmem_tree_insert32(sdp_transport_reqs, request_frame, (void *)transport_info);
2527
0
    }
2528
#ifdef DEBUG_CONVERSATION
2529
    else {
2530
        DPRINT(("found previous transport_info:"));
2531
        sdp_dump_transport_info(pinfo, transport_info);
2532
    }
2533
#endif
2534
2535
0
    if (exchange_type != SDP_EXCHANGE_OFFER)
2536
0
        wmem_tree_insert32(sdp_transport_rsps, pinfo->num, (void *)transport_info);
2537
2538
    /* Offer has already been answered or rejected and hash tables freed, so
2539
     * don't try to add to it
2540
     * XXX - Need to support "modified offers" */
2541
0
    if ((transport_info->sdp_status == SDP_EXCHANGE_ANSWER_REJECT) ||
2542
0
        (transport_info->sdp_status == SDP_EXCHANGE_ANSWER_ACCEPT))
2543
0
        return;
2544
2545
    /* Initialize the session description before parsing the media descriptions. */
2546
0
    memset(&session_info, 0, sizeof(session_info_t));
2547
0
    session_info.rtp_dyn_payload = rtp_dyn_payload_new();
2548
2549
    /* Remember where the answer should start (it will be zero if there was no
2550
     * previous offer with media descriptions). */
2551
0
    start_transport_info_count = wmem_array_get_count(transport_info->media_descriptions);
2552
2553
0
    DPRINT(("start_transport_info_count=%d", start_transport_info_count));
2554
2555
    /*
2556
     * Show the SDP message a line at a time.
2557
     */
2558
0
    while (tvb_offset_exists(tvb, offset)) {
2559
        /*
2560
         * Find the end of the line.
2561
         */
2562
0
        linelen = tvb_find_line_end_unquoted(tvb, offset, -1, &next_offset);
2563
2564
        /*
2565
         * Line must contain at least e.g. "v=".
2566
         */
2567
0
        if (linelen < 2)
2568
0
            break;
2569
2570
0
        type  = tvb_get_uint8(tvb, offset);
2571
0
        delim = tvb_get_uint8(tvb, offset + 1);
2572
0
        if (delim != '=') {
2573
0
            offset = next_offset;
2574
0
            continue;
2575
0
        }
2576
2577
        /*
2578
         * Attributes.  Only care about ones that affect the transport.  Ignore others.
2579
         */
2580
0
        switch (type) {
2581
0
            case 'c':
2582
0
                hf = hf_connection_info;
2583
0
                break;
2584
0
            case 'm':
2585
0
                hf = hf_media;
2586
2587
                /* Try to create a new media description (it will return NULL if
2588
                 * there are too many). */
2589
0
                media_desc = sdp_new_media_description(transport_info->media_descriptions, &session_info);
2590
2591
0
                in_media_description = true;
2592
0
                DPRINT(("in media description, media descriptions count=%d",
2593
0
                        wmem_array_get_count(transport_info->media_descriptions)));
2594
0
                break;
2595
0
            case 'a':
2596
0
                if (in_media_description) {
2597
0
                    hf = hf_media_attribute;
2598
0
                } else {
2599
0
                    hf = hf_session_attribute;
2600
0
                }
2601
0
                break;
2602
0
            default:
2603
0
                hf = hf_unknown;
2604
0
                break;
2605
0
        }
2606
2607
0
        if (hf != hf_unknown)
2608
0
        {
2609
0
            DINDENT();
2610
0
            call_sdp_subdissector(tvb_new_subset_length(tvb, offset + tokenoffset,
2611
0
                                                   linelen - tokenoffset),
2612
0
                                    pinfo,
2613
0
                                    hf, NULL, linelen-tokenoffset,
2614
0
                                    transport_info,
2615
0
                                    in_media_description ? NULL : &session_info,
2616
0
                                    media_desc,
2617
0
                                    &sdp_data);
2618
0
            DENDENT();
2619
0
        }
2620
2621
0
        offset = next_offset;
2622
0
    }
2623
2624
    /* Done parsing media description, no more need for the session-level details. */
2625
0
    rtp_dyn_payload_free(session_info.rtp_dyn_payload);
2626
0
    session_info.rtp_dyn_payload = NULL;
2627
2628
    /* Post-processing, close media streams, apply attributes, etc. */
2629
0
    complete_descriptions(transport_info, start_transport_info_count);
2630
2631
#ifdef DEBUG_CONVERSATION
2632
    sdp_dump_transport_info(pinfo, transport_info);
2633
#endif
2634
2635
    /* We have a successful negotiation, apply data to their respective protocols */
2636
0
    if (!delay || ((exchange_type == SDP_EXCHANGE_ANSWER_ACCEPT) &&
2637
0
        (transport_info->sdp_status == SDP_EXCHANGE_OFFER))) {
2638
        /* Accepting answer to a previous offer (or delay pref is false). */
2639
0
        apply_sdp_transport(pinfo, transport_info, request_frame, setup_info);
2640
2641
        /* Free all media hash tables that were not assigned to a conversation
2642
         * ('set_rtp' is false) */
2643
0
        clean_unused_media_descriptions(transport_info->media_descriptions);
2644
2645
0
        transport_info->sdp_status = exchange_type;
2646
2647
0
    } else if ((exchange_type == SDP_EXCHANGE_ANSWER_REJECT) &&
2648
0
               (transport_info->sdp_status != SDP_EXCHANGE_ANSWER_REJECT)) {
2649
        /* Rejecting answer */
2650
0
        clean_unused_media_descriptions(transport_info->media_descriptions);
2651
2652
0
        transport_info->sdp_status = SDP_EXCHANGE_ANSWER_REJECT;
2653
0
    } /* else attempt to accept an unknown offer. */
2654
0
}
2655
2656
void setup_sdp_transport_resend(int current_frame, int request_frame)
2657
0
{
2658
0
    transport_info_t* transport_info = NULL;
2659
2660
0
    if (request_frame != 0) {
2661
0
        transport_info = (transport_info_t*)wmem_tree_lookup32( sdp_transport_reqs, request_frame );
2662
0
        if (transport_info != NULL) {
2663
0
            wmem_tree_insert32(sdp_transport_reqs, current_frame, (void *)transport_info);
2664
0
        }
2665
0
    }
2666
0
}
2667
2668
static int
2669
dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
2670
310
{
2671
310
    proto_tree *sdp_tree;
2672
310
    proto_item *ti, *sub_ti;
2673
310
    int         offset = 0, next_offset, n;
2674
310
    int         linelen;
2675
310
    bool        in_media_description;
2676
310
    unsigned char      type, delim;
2677
310
    int         datalen, tokenoffset, hf = -1;
2678
310
    char       *string;
2679
310
    sdp_data_t  sdp_data;
2680
2681
310
    transport_info_t  local_transport_info;
2682
310
    transport_info_t* transport_info = NULL;
2683
310
    media_description_t *media_desc = NULL;
2684
310
    session_info_t session_info;
2685
310
    sdp_packet_info  *sdp_pi;
2686
310
    sdp_setup_info_t *setup_info = NULL;
2687
2688
310
    if (data) {
2689
63
        media_content_info_t *content_info = (media_content_info_t *)data;
2690
63
        if (content_info->type == MEDIA_CONTAINER_SIP_DATA) {
2691
63
            setup_info = (sdp_setup_info_t *)content_info->data;
2692
63
        }
2693
63
    }
2694
2695
310
    DPRINT2(("----------------------- dissect_sdp ------------------------"));
2696
2697
    /* Initialise packet info for passing to tap */
2698
310
    sdp_pi = wmem_new(pinfo->pool, sdp_packet_info);
2699
310
    sdp_pi->summary_str[0] = '\0';
2700
2701
310
    memset(&sdp_data, 0, sizeof(sdp_data));
2702
2703
310
    transport_info = (transport_info_t*)wmem_tree_lookup32( sdp_transport_reqs, pinfo->num );
2704
2705
310
    if (transport_info == NULL) {
2706
      /* Can't find it in the requests, make sure it's not a response */
2707
310
      transport_info = (transport_info_t*)wmem_tree_lookup32( sdp_transport_rsps, pinfo->num );
2708
310
    }
2709
2710
310
    if (transport_info == NULL) {
2711
310
      transport_info = &local_transport_info;
2712
310
    }
2713
#ifdef DEBUG_CONVERSATION
2714
    else {
2715
        DPRINT(("found previous transport_info:"));
2716
        sdp_dump_transport_info(pinfo, transport_info);
2717
    }
2718
#endif
2719
2720
    /* Initialize local transport info */
2721
310
    memset(&local_transport_info, 0, sizeof(local_transport_info));
2722
    /* Note: packet-scoped since it is only needed while parsing this packet. */
2723
310
    local_transport_info.media_descriptions = wmem_array_new(pinfo->pool, sizeof(media_description_t));
2724
2725
39.9k
    for (n = 0; n < SDP_NO_OF_PT; n++) {
2726
39.6k
        local_transport_info.encoding_name[n] = wmem_strdup(pinfo->pool, UNKNOWN_ENCODING);
2727
39.6k
    }
2728
2729
    /*
2730
     * As RFC 2327 says, "SDP is purely a format for session
2731
     * description - it does not incorporate a transport protocol,
2732
     * and is intended to use different transport protocols as
2733
     * appropriate including the Session Announcement Protocol,
2734
     * Session Initiation Protocol, Real-Time Streaming Protocol,
2735
     * electronic mail using the MIME extensions, and the
2736
     * Hypertext Transport Protocol."
2737
     *
2738
     * We therefore don't set the protocol or info columns;
2739
     * instead, we append to them, so that we don't erase
2740
     * what the protocol inside which the SDP stuff resides
2741
     * put there.
2742
     */
2743
310
    col_append_str(pinfo->cinfo, COL_PROTOCOL, "/SDP");
2744
2745
310
    ti = proto_tree_add_item(tree, proto_sdp, tvb, offset, -1, ENC_NA);
2746
310
    sdp_tree = proto_item_add_subtree(ti, ett_sdp);
2747
2748
    /*
2749
     * Show the SDP message a line at a time.
2750
     */
2751
310
    in_media_description = false;
2752
2753
    /* Initialize the session description before parsing the media level. */
2754
310
    memset(&session_info, 0, sizeof(session_info_t));
2755
310
    session_info.rtp_dyn_payload = rtp_dyn_payload_new();
2756
2757
2.76k
    while (tvb_offset_exists(tvb, offset)) {
2758
        /*
2759
         * Find the end of the line.
2760
         */
2761
2.48k
        linelen = tvb_find_line_end_unquoted(tvb, offset, -1, &next_offset);
2762
2763
        /*
2764
         * Line must contain at least e.g. "v=".
2765
         */
2766
2.48k
        if (linelen < 2)
2767
29
            break;
2768
2769
2.45k
        type  = tvb_get_uint8(tvb, offset);
2770
2.45k
        delim = tvb_get_uint8(tvb, offset + 1);
2771
2.45k
        if (delim != '=') {
2772
808
            proto_item *ti2 = proto_tree_add_item(sdp_tree, hf_invalid, tvb, offset, linelen, ENC_UTF_8);
2773
808
            expert_add_info(pinfo, ti2, &ei_sdp_invalid_line_equal);
2774
808
            offset = next_offset;
2775
808
            continue;
2776
808
        }
2777
2778
        /*
2779
         * Attributes.
2780
         */
2781
1.65k
        switch (type) {
2782
1
            case 'v':
2783
1
                hf = hf_protocol_version;
2784
1
                break;
2785
135
            case 'o':
2786
135
                hf = hf_owner;
2787
135
                break;
2788
2
            case 's':
2789
2
                hf = hf_session_name;
2790
2
                break;
2791
9
            case 'i':
2792
9
                if (in_media_description) {
2793
2
                  hf = hf_media_title;
2794
7
                } else {
2795
7
                  hf = hf_session_info;
2796
7
                }
2797
9
                break;
2798
0
            case 'u':
2799
0
                hf = hf_uri;
2800
0
                break;
2801
0
            case 'e':
2802
0
                hf = hf_email;
2803
0
                break;
2804
0
            case 'p':
2805
0
                hf = hf_phone;
2806
0
                break;
2807
198
            case 'c':
2808
198
                hf = hf_connection_info;
2809
198
                break;
2810
15
            case 'b':
2811
15
                hf = hf_bandwidth;
2812
15
                break;
2813
7
            case 't':
2814
7
                hf = hf_time;
2815
7
                break;
2816
92
            case 'r':
2817
92
                hf = hf_repeat_time;
2818
92
                break;
2819
930
            case 'm':
2820
930
                hf = hf_media;
2821
2822
                /* Try to create a new media description (it will return NULL if
2823
                 * there are too many). Pass local_transport_info since we do
2824
                 * not want to modify the transport_info that was created by
2825
                 * setup_sdp_transport. */
2826
930
                media_desc = sdp_new_media_description(local_transport_info.media_descriptions, &session_info);
2827
2828
930
                in_media_description = true;
2829
930
                break;
2830
29
            case 'k':
2831
29
                hf = hf_encryption_key;
2832
29
                break;
2833
0
            case 'a':
2834
0
                if (in_media_description) {
2835
0
                    hf = hf_media_attribute;
2836
0
                } else {
2837
0
                    hf = hf_session_attribute;
2838
0
                }
2839
0
                break;
2840
116
            case 'z':
2841
116
                hf = hf_timezone;
2842
116
                break;
2843
116
            default:
2844
116
                hf = hf_unknown;
2845
116
                break;
2846
1.65k
        }
2847
1.65k
        tokenoffset = 2;
2848
1.65k
        if (hf == hf_unknown)
2849
116
            tokenoffset = 0;
2850
1.65k
        string = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset + tokenoffset,
2851
1.65k
                                                 linelen - tokenoffset, ENC_ASCII);
2852
1.65k
        sub_ti = proto_tree_add_string(sdp_tree, hf, tvb, offset, linelen,
2853
1.65k
                                       string);
2854
2855
1.65k
        call_sdp_subdissector(tvb_new_subset_length(tvb, offset + tokenoffset,
2856
1.65k
                                             linelen - tokenoffset),
2857
1.65k
                              pinfo,
2858
1.65k
                              hf, sub_ti, linelen-tokenoffset,
2859
1.65k
                              &local_transport_info,
2860
1.65k
                              in_media_description ? NULL : &session_info,
2861
1.65k
                              in_media_description ? media_desc : NULL,
2862
1.65k
                              &sdp_data);
2863
2864
1.65k
        offset = next_offset;
2865
1.65k
    }
2866
2867
310
    if (NULL != sdp_data.ed137_fid) {
2868
0
      col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", sdp_data.ed137_fid);
2869
0
      (void) g_strlcat(sdp_pi->summary_str, sdp_data.ed137_fid, 50);
2870
0
    }
2871
310
    if (NULL != sdp_data.ed137_txrxmode) {
2872
0
      col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", sdp_data.ed137_txrxmode);
2873
0
      if (strlen(sdp_pi->summary_str))
2874
0
          (void) g_strlcat(sdp_pi->summary_str, " ", 50);
2875
0
      (void) g_strlcat(sdp_pi->summary_str, sdp_data.ed137_txrxmode, 50);
2876
0
    }
2877
310
    if (NULL != sdp_data.ed137_type) {
2878
0
      col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", sdp_data.ed137_type);
2879
0
      if (strlen(sdp_pi->summary_str))
2880
0
          (void) g_strlcat(sdp_pi->summary_str, " ", 50);
2881
0
      (void) g_strlcat(sdp_pi->summary_str, sdp_data.ed137_type, 50);
2882
0
    }
2883
2884
    /* Done parsing media description, no more need for the session-level details. */
2885
310
    rtp_dyn_payload_free(session_info.rtp_dyn_payload);
2886
310
    session_info.rtp_dyn_payload = NULL;
2887
2888
    /* Post-processing, close media streams, apply attributes, etc. */
2889
310
    if (transport_info == &local_transport_info) {
2890
307
        DPRINT(("no previous transport_info saved, calling complete_descriptions()"));
2891
307
        DINDENT();
2892
307
        complete_descriptions(transport_info, 0);
2893
307
        DENDENT();
2894
#ifdef DEBUG_CONVERSATION
2895
        sdp_dump_transport_info(pinfo, transport_info);
2896
#endif
2897
307
    }
2898
#ifdef DEBUG_CONVERSATION
2899
    else {
2900
        DPRINT(("not overwriting previous transport_info, local_transport_info contents:"));
2901
        sdp_dump_transport_info(pinfo, &local_transport_info);
2902
    }
2903
#endif
2904
2905
    /* For messages not part of the Offer/Answer model, assume that the SDP is
2906
     * immediately effective (apply it now). */
2907
310
    if ((!pinfo->fd->visited) && (transport_info == &local_transport_info)) {
2908
        /* XXX - This is a placeholder for higher layer protocols that haven't implemented the proper
2909
         * OFFER/ANSWER functionality using setup_sdp_transport().  Once all of the higher layers
2910
         * use setup_sdp_transport(), this should be removed
2911
         * Note that transport_info contains the SDP info from this frame (and
2912
         * not an earlier request (transport_info == &local_transport_info).
2913
         * Use 0 as request_frame since there is no (known) request.
2914
         */
2915
307
        apply_sdp_transport(pinfo, transport_info, 0, setup_info);
2916
        /* Save the list of setup info of calls with the same RTP information
2917
         * to the packet in file scope, since transport_info is local and
2918
         * we won't do this on future passes.
2919
         */
2920
307
        p_add_proto_data(wmem_file_scope(), pinfo, proto_sdp, 0, transport_info->sdp_setup_info_list);
2921
307
    }
2922
2923
    /* Add information to the VoIP Calls dialog. */
2924
785
    for (unsigned i = 0; i < wmem_array_get_count(local_transport_info.media_descriptions); i++)
2925
475
    {
2926
475
        media_desc = (media_description_t *)wmem_array_index(local_transport_info.media_descriptions, i);
2927
2928
475
        if (media_desc->media_port != 0) {
2929
            /* Create the RTP summary str for the Voip Call analysis.
2930
             * XXX - Currently this is based only on the current packet
2931
             */
2932
88
            for (int j = 0; j < media_desc->media.pt_count; j++)
2933
13
            {
2934
13
                DPRINT(("in for-loop for voip call analysis setting for media #%d, pt=%d",
2935
13
                        j, media_desc->media. pt[j]));
2936
                /* if the payload type is dynamic (96 to 127), check the hash table to add the desc in the SDP summary */
2937
13
                if ((media_desc->media.pt[j] >= 96) && (media_desc->media.pt[j] <= 127)) {
2938
0
                    const char *payload_type_str = rtp_dyn_payload_get_name(
2939
0
                        media_desc->media.rtp_dyn_payload,
2940
0
                        media_desc->media.pt[j]);
2941
0
                    if (payload_type_str) {
2942
0
                        if (strlen(sdp_pi->summary_str))
2943
0
                            (void) g_strlcat(sdp_pi->summary_str, " ", 50);
2944
0
                        (void) g_strlcat(sdp_pi->summary_str, payload_type_str, 50);
2945
0
                    } else {
2946
0
                        char num_pt[10];
2947
0
                        snprintf(num_pt, 10, "%u", media_desc->media.pt[j]);
2948
0
                        if (strlen(sdp_pi->summary_str))
2949
0
                            (void) g_strlcat(sdp_pi->summary_str, " ", 50);
2950
0
                        (void) g_strlcat(sdp_pi->summary_str, num_pt, 50);
2951
0
                      }
2952
13
                } else {
2953
13
                    if (strlen(sdp_pi->summary_str))
2954
7
                        (void) g_strlcat(sdp_pi->summary_str, " ", 50);
2955
13
                    (void) g_strlcat(sdp_pi->summary_str,
2956
13
                              val_to_str_ext(pinfo->pool, media_desc->media.pt[j], &rtp_payload_type_short_vals_ext, "%u"),
2957
13
                              50);
2958
13
                }
2959
13
            }
2960
75
        }
2961
2962
        /* Create the T38 summary str for the Voip Call analysis
2963
         * XXX - Currently this is based only on the current packet
2964
         */
2965
475
        if ((media_desc->media_port != 0) && media_desc->proto == SDP_PROTO_T38) {
2966
0
            if (strlen(sdp_pi->summary_str))
2967
0
                (void) g_strlcat(sdp_pi->summary_str, " ", 50);
2968
0
            (void) g_strlcat(sdp_pi->summary_str, "t38", 50);
2969
0
        }
2970
475
    }
2971
2972
    /* Free all media hash tables that were not assigned to a conversation
2973
     * ('set_rtp' is false) */
2974
310
    if (transport_info == &local_transport_info) {
2975
307
        clean_unused_media_descriptions(transport_info->media_descriptions);
2976
307
    }
2977
2978
310
    datalen = tvb_captured_length_remaining(tvb, offset);
2979
310
    if (datalen > 0) {
2980
29
        proto_tree_add_item(sdp_tree, hf_sdp_data, tvb, offset, datalen, ENC_NA);
2981
29
    }
2982
    /* Add Trace info */
2983
310
    wmem_array_t *setup_info_list = transport_info->sdp_setup_info_list;
2984
310
    if (!setup_info_list) {
2985
307
        setup_info_list = (wmem_array_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_sdp, 0);
2986
307
    }
2987
310
    if (setup_info_list) {
2988
0
        unsigned i;
2989
0
        sdp_setup_info_t *stored_setup_info;
2990
0
        proto_item *item;
2991
0
        for (i = 0; i < wmem_array_get_count(setup_info_list); i++) {
2992
0
            stored_setup_info = (sdp_setup_info_t *)wmem_array_index(setup_info_list, i);
2993
0
            if (stored_setup_info->hf_id) {
2994
0
                if (stored_setup_info->hf_type == SDP_TRACE_ID_HF_TYPE_STR) {
2995
0
                    item = proto_tree_add_string(sdp_tree, stored_setup_info->hf_id, tvb, 0, 0, stored_setup_info->trace_id.str);
2996
0
                    proto_item_set_generated(item);
2997
0
                    if (stored_setup_info->add_hidden == true) {
2998
0
                        proto_item_set_hidden(item);
2999
0
                    }
3000
0
                } else if (stored_setup_info->hf_type == SDP_TRACE_ID_HF_TYPE_UINT32) {
3001
0
                    item = proto_tree_add_uint(sdp_tree, stored_setup_info->hf_id, tvb, 0, 0, stored_setup_info->trace_id.num);
3002
0
                    proto_item_set_generated(item);
3003
0
                    if (stored_setup_info->add_hidden == true) {
3004
0
                        proto_item_set_hidden(item);
3005
0
                    }
3006
0
                }
3007
0
            }
3008
0
        }
3009
0
    }
3010
    /* Report this packet to the tap */
3011
310
    tap_queue_packet(sdp_tap, pinfo, sdp_pi);
3012
3013
310
    return tvb_captured_length(tvb);
3014
310
}
3015
3016
void
3017
proto_register_sdp(void)
3018
14
{
3019
14
    static hf_register_info hf[] = {
3020
14
        { &hf_protocol_version,
3021
14
            { "Session Description Protocol Version (v)", "sdp.version",
3022
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3023
14
              NULL, HFILL }
3024
14
        },
3025
14
        { &hf_owner,
3026
14
            { "Owner/Creator, Session Id (o)",
3027
14
              "sdp.owner", FT_STRING, BASE_NONE, NULL,
3028
14
              0x0, NULL, HFILL}
3029
14
        },
3030
14
        { &hf_session_name,
3031
14
            { "Session Name (s)", "sdp.session_name",
3032
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3033
14
              NULL, HFILL }
3034
14
        },
3035
14
        { &hf_session_info,
3036
14
            { "Session Information (i)", "sdp.session_info",
3037
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3038
14
              NULL, HFILL }
3039
14
        },
3040
14
        { &hf_uri,
3041
14
            { "URI of Description (u)", "sdp.uri",
3042
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3043
14
              NULL, HFILL }
3044
14
        },
3045
14
        { &hf_email,
3046
14
            { "E-mail Address (e)", "sdp.email",
3047
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3048
14
              NULL, HFILL }
3049
14
        },
3050
14
        { &hf_phone,
3051
14
            { "Phone Number (p)", "sdp.phone",
3052
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3053
14
              NULL, HFILL }
3054
14
        },
3055
14
        { &hf_connection_info,
3056
14
            { "Connection Information (c)", "sdp.connection_info",
3057
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3058
14
              NULL, HFILL }
3059
14
        },
3060
14
        { &hf_bandwidth,
3061
14
            { "Bandwidth Information (b)", "sdp.bandwidth",
3062
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3063
14
              NULL, HFILL }
3064
14
        },
3065
14
        { &hf_timezone,
3066
14
            { "Time Zone Adjustments (z)", "sdp.timezone",
3067
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3068
14
              NULL, HFILL }
3069
14
        },
3070
14
        { &hf_encryption_key,
3071
14
            { "Encryption Key (k)", "sdp.encryption_key",
3072
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3073
14
              NULL, HFILL }
3074
14
        },
3075
14
        { &hf_session_attribute,
3076
14
            { "Session Attribute (a)", "sdp.session_attr",
3077
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3078
14
              NULL, HFILL }
3079
14
        },
3080
14
        { &hf_media_attribute,
3081
14
            { "Media Attribute (a)", "sdp.media_attr",
3082
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3083
14
              NULL, HFILL }
3084
14
        },
3085
14
        { &hf_time,
3086
14
            { "Time Description, active time (t)",
3087
14
              "sdp.time", FT_STRING, BASE_NONE, NULL,
3088
14
              0x0, NULL, HFILL }
3089
14
        },
3090
14
        { &hf_repeat_time,
3091
14
            { "Repeat Time (r)", "sdp.repeat_time",
3092
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3093
14
              NULL, HFILL }
3094
14
        },
3095
14
        { &hf_media,
3096
14
            { "Media Description, name and address (m)",
3097
14
              "sdp.media", FT_STRING, BASE_NONE, NULL, 0x0,
3098
14
              NULL, HFILL }
3099
14
        },
3100
14
        { &hf_media_title,
3101
14
            { "Media Title (i)", "sdp.media_title",
3102
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3103
14
              NULL, HFILL }
3104
14
        },
3105
14
        { &hf_unknown,
3106
14
            { "Unknown", "sdp.unknown",
3107
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3108
14
              NULL, HFILL }
3109
14
        },
3110
14
        { &hf_invalid,
3111
14
            { "Invalid line", "sdp.invalid",
3112
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3113
14
              NULL, HFILL }
3114
14
        },
3115
14
        { &hf_owner_username,
3116
14
            { "Owner Username", "sdp.owner.username",
3117
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3118
14
              NULL, HFILL }
3119
14
        },
3120
14
        { &hf_owner_sessionid,
3121
14
            { "Session ID", "sdp.owner.sessionid",
3122
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3123
14
              NULL, HFILL }
3124
14
        },
3125
14
        { &hf_owner_version,
3126
14
            { "Session Version", "sdp.owner.version",
3127
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3128
14
              NULL, HFILL }
3129
14
        },
3130
14
        { &hf_owner_network_type,
3131
14
            { "Owner Network Type", "sdp.owner.network_type",
3132
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3133
14
              NULL, HFILL }
3134
14
        },
3135
14
        { &hf_owner_address_type,
3136
14
            { "Owner Address Type", "sdp.owner.address_type",
3137
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3138
14
              NULL, HFILL }
3139
14
        },
3140
14
        { &hf_owner_address,
3141
14
            { "Owner Address", "sdp.owner.address",
3142
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3143
14
              NULL, HFILL }
3144
14
        },
3145
14
        { &hf_connection_info_network_type,
3146
14
            { "Connection Network Type", "sdp.connection_info.network_type",
3147
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3148
14
              NULL, HFILL }
3149
14
        },
3150
14
        { &hf_connection_info_address_type,
3151
14
            { "Connection Address Type", "sdp.connection_info.address_type",
3152
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3153
14
              NULL, HFILL }
3154
14
        },
3155
14
        { &hf_connection_info_connection_address,
3156
14
            { "Connection Address", "sdp.connection_info.address",
3157
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3158
14
              NULL, HFILL }
3159
14
        },
3160
14
        { &hf_connection_info_ttl,
3161
14
            { "Connection TTL", "sdp.connection_info.ttl",
3162
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3163
14
              NULL, HFILL }
3164
14
        },
3165
14
        { &hf_connection_info_num_addr,
3166
14
            { "Connection Number of Addresses", "sdp.connection_info.num_addr",
3167
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3168
14
              NULL, HFILL }
3169
14
        },
3170
14
        { &hf_bandwidth_modifier,
3171
14
            { "Bandwidth Modifier", "sdp.bandwidth.modifier",
3172
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3173
14
              NULL, HFILL }
3174
14
        },
3175
14
        { &hf_bandwidth_value,
3176
14
            { "Bandwidth Value", "sdp.bandwidth.value",
3177
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3178
14
              "Bandwidth Value (in kbits/s)", HFILL }
3179
14
        },
3180
14
        { &hf_time_start,
3181
14
            { "Session Start Time", "sdp.time.start",
3182
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3183
14
              NULL, HFILL }
3184
14
        },
3185
14
        { &hf_time_stop,
3186
14
            { "Session Stop Time", "sdp.time.stop",
3187
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3188
14
              NULL, HFILL }
3189
14
        },
3190
14
        { &hf_repeat_time_interval,
3191
14
            { "Repeat Interval", "sdp.repeat_time.interval",
3192
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3193
14
              NULL, HFILL }
3194
14
        },
3195
14
        { &hf_repeat_time_duration,
3196
14
            { "Repeat Duration", "sdp.repeat_time.duration",
3197
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3198
14
              NULL, HFILL }
3199
14
        },
3200
14
        { &hf_repeat_time_offset,
3201
14
            { "Repeat Offset", "sdp.repeat_time.offset",
3202
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3203
14
              NULL, HFILL }
3204
14
        },
3205
14
        { &hf_timezone_time,
3206
14
            { "Timezone Time", "sdp.timezone.time",
3207
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3208
14
              NULL, HFILL }
3209
14
        },
3210
14
        { &hf_timezone_offset,
3211
14
            { "Timezone Offset", "sdp.timezone.offset",
3212
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3213
14
              NULL, HFILL }
3214
14
        },
3215
14
        { &hf_encryption_key_type,
3216
14
            { "Key Type", "sdp.encryption_key.type",
3217
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3218
14
              NULL, HFILL }
3219
14
        },
3220
14
        { &hf_encryption_key_data,
3221
14
            { "Key Data", "sdp.encryption_key.data",
3222
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3223
14
              NULL, HFILL }
3224
14
        },
3225
14
        { &hf_session_attribute_field,
3226
14
            { "Session Attribute Fieldname", "sdp.session_attr.field",
3227
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3228
14
              NULL, HFILL }
3229
14
        },
3230
14
        { &hf_session_attribute_value,
3231
14
            { "Session Attribute Value", "sdp.session_attr.value",
3232
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3233
14
              NULL, HFILL }
3234
14
        },
3235
14
        { &hf_media_media,
3236
14
            { "Media Type", "sdp.media.media",
3237
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3238
14
              NULL, HFILL }
3239
14
        },
3240
14
        { &hf_media_port,
3241
14
            { "Media Port", "sdp.media.port",
3242
14
              FT_UINT16, BASE_PT_UDP, NULL, 0x0,
3243
14
              NULL, HFILL }
3244
14
        },
3245
14
        { &hf_media_port_string,
3246
14
            { "Media Port", "sdp.media.port_string",
3247
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3248
14
              NULL, HFILL }
3249
14
        },
3250
14
        { &hf_media_portcount,
3251
14
            { "Media Port Count", "sdp.media.portcount",
3252
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3253
14
              NULL, HFILL }
3254
14
        },
3255
14
        { &hf_media_proto,
3256
14
            { "Media Protocol", "sdp.media.proto",
3257
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3258
14
              NULL, HFILL }
3259
14
        },
3260
14
        { &hf_media_format,
3261
14
            { "Media Format", "sdp.media.format",
3262
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3263
14
              NULL, HFILL }
3264
14
        },
3265
14
        { &hf_media_attribute_field,
3266
14
            { "Media Attribute Fieldname", "sdp.media_attribute.field",
3267
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3268
14
              NULL, HFILL }
3269
14
        },
3270
14
        { &hf_media_attribute_value,
3271
14
            { "Media Attribute Value", "sdp.media_attribute.value",
3272
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3273
14
              NULL, HFILL }
3274
14
        },
3275
14
        { &hf_media_encoding_name,
3276
14
            { "MIME Type", "sdp.mime.type",
3277
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3278
14
              "SDP MIME Type", HFILL }
3279
14
        },
3280
14
        { &hf_media_sample_rate,
3281
14
            { "Sample Rate", "sdp.sample_rate",
3282
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3283
14
              NULL, HFILL }
3284
14
        },
3285
14
        { &hf_media_channels,
3286
14
            { "Audio Channels", "sdp.channels",
3287
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3288
14
              NULL, HFILL }
3289
14
        },
3290
14
        { &hf_media_format_specific_parameter,
3291
14
            { "Media format specific parameters", "sdp.fmtp.parameter",
3292
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3293
14
              "Format specific parameter(fmtp)", HFILL }
3294
14
        },
3295
14
        { &hf_ipbcp_version,
3296
14
            { "IPBCP Protocol Version", "sdp.ipbcp.version",
3297
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3298
14
              NULL, HFILL }
3299
14
        },
3300
14
        { &hf_ipbcp_type,
3301
14
            { "IPBCP Command Type", "sdp.ipbcp.command",
3302
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3303
14
              NULL, HFILL }
3304
14
        },
3305
14
        {&hf_sdp_fmtp_mpeg4_profile_level_id,
3306
14
           { "Level Code", "sdp.fmtp.profile_level_id",
3307
14
             FT_UINT32, BASE_DEC, VALS(mp4ves_level_indication_vals), 0x0,
3308
14
             NULL, HFILL }
3309
14
        },
3310
14
        { &hf_sdp_fmtp_h263_profile,
3311
14
            { "Profile", "sdp.fmtp.h263profile",
3312
14
              FT_UINT32, BASE_DEC, VALS(h263_profile_vals), 0x0,
3313
14
              NULL, HFILL }
3314
14
        },
3315
14
        { &hf_sdp_fmtp_h263_level,
3316
14
            { "Level", "sdp.fmtp.h263level",
3317
14
              FT_UINT32, BASE_DEC, VALS(h263_level_vals), 0x0,
3318
14
              NULL, HFILL }
3319
14
        },
3320
14
        { &hf_sdp_h264_packetization_mode,
3321
14
            { "Packetization mode", "sdp.fmtp.h264_packetization_mode",
3322
14
              FT_UINT32, BASE_DEC, VALS(h264_packetization_mode_vals), 0x0,
3323
14
              NULL, HFILL }
3324
14
        },
3325
14
        { &hf_SDPh223LogicalChannelParameters,
3326
14
            { "h223LogicalChannelParameters", "sdp.h223LogicalChannelParameters",
3327
14
              FT_NONE, BASE_NONE, NULL, 0,
3328
14
              NULL, HFILL }
3329
14
        },
3330
14
        { &hf_key_mgmt_att_value,
3331
14
            { "Key Management", "sdp.key_mgmt",
3332
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3333
14
              NULL, HFILL }
3334
14
        },
3335
14
        { &hf_key_mgmt_prtcl_id,
3336
14
            { "Key Management Protocol (kmpid)", "sdp.key_mgmt.kmpid",
3337
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3338
14
              NULL, HFILL }
3339
14
        },
3340
14
        { &hf_key_mgmt_data,
3341
14
            { "Key Management Data", "sdp.key_mgmt.data",
3342
14
              FT_BYTES, BASE_NONE, NULL, 0x0,
3343
14
              NULL, HFILL }
3344
14
        },
3345
14
        { &hf_sdp_crypto_tag,
3346
14
            { "tag", "sdp.crypto.tag",
3347
14
              FT_UINT32, BASE_DEC, NULL, 0x0,
3348
14
              NULL, HFILL }
3349
14
        },
3350
14
        { &hf_sdp_crypto_crypto_suite,
3351
14
            { "Crypto suite", "sdp.crypto.crypto_suite",
3352
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3353
14
              NULL, HFILL }
3354
14
        },
3355
14
        { &hf_sdp_crypto_master_key,
3356
14
            { "Master Key", "sdp.crypto.master_key",
3357
14
              FT_BYTES, BASE_NONE, NULL, 0x0,
3358
14
              NULL, HFILL }
3359
14
        },
3360
14
        { &hf_sdp_crypto_master_salt,
3361
14
            { "Master salt", "sdp.crypto.master_salt",
3362
14
              FT_BYTES, BASE_NONE, NULL, 0x0,
3363
14
              NULL, HFILL }
3364
14
        },
3365
14
        { &hf_sdp_crypto_lifetime,
3366
14
            { "Lifetime", "sdp.crypto.lifetime",
3367
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3368
14
              NULL, HFILL }
3369
14
        },
3370
14
        { &hf_sdp_crypto_mki,
3371
14
            { "mki-value", "sdp.crypto.mki-valu",
3372
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3373
14
              NULL, HFILL }
3374
14
        },
3375
14
        { &hf_sdp_crypto_mki_length,
3376
14
            { "mki_length", "sdp.crypto.mki_length",
3377
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3378
14
              NULL, HFILL }
3379
14
        },
3380
14
        { &hf_ice_candidate_foundation,
3381
14
            { "Foundation", "sdp.ice_candidate.foundation",
3382
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3383
14
              "Identifier, same for two candidates with same type, base address, protocol and STUN server", HFILL }
3384
14
        },
3385
14
        { &hf_ice_candidate_componentid,
3386
14
            { "Component ID", "sdp.ice_candidate.componentid",
3387
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3388
14
              "Media component identifier (For RTP media, 1 is RTP, 2 is RTCP)", HFILL }
3389
14
        },
3390
14
        { &hf_ice_candidate_transport,
3391
14
            { "Transport", "sdp.ice_candidate.transport",
3392
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3393
14
              "Transport protocol", HFILL }
3394
14
        },
3395
14
        { &hf_ice_candidate_priority,
3396
14
            { "Priority", "sdp.ice_candidate.priority",
3397
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3398
14
              NULL, HFILL }
3399
14
        },
3400
14
        { &hf_ice_candidate_address,
3401
14
            { "Connection Address", "sdp.ice_candidate.address",
3402
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3403
14
              "IP address or FQDN of the candidate", HFILL }
3404
14
        },
3405
14
        { &hf_ice_candidate_port,
3406
14
            { "Candidate Port", "sdp.ice_candidate.port",
3407
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3408
14
              "Port of the candidate", HFILL }
3409
14
        },
3410
14
        { &hf_ice_candidate_type,
3411
14
            { "Candidate Type", "sdp.ice_candidate.type",
3412
14
              FT_STRING, BASE_NONE, NULL, 0x0,
3413
14
              "The origin of the address and port, i.e. where it was learned", HFILL }
3414
14
        },
3415
      /* Generated from convert_proto_tree_add_text.pl */
3416
14
      { &hf_sdp_nal_unit_1_string, { "NAL unit 1 string", "sdp.nal_unit_1_string", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3417
14
      { &hf_sdp_nal_unit_2_string, { "NAL unit 2 string", "sdp.nal_unit_2_string", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3418
14
      { &hf_sdp_key_and_salt, { "Key and Salt", "sdp.key_and_salt", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3419
14
      { &hf_sdp_data, { "Data", "sdp.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3420
14
    };
3421
14
    static int *ett[] = {
3422
14
        &ett_sdp,
3423
14
        &ett_sdp_owner,
3424
14
        &ett_sdp_connection_info,
3425
14
        &ett_sdp_bandwidth,
3426
14
        &ett_sdp_time,
3427
14
        &ett_sdp_repeat_time,
3428
14
        &ett_sdp_timezone,
3429
14
        &ett_sdp_encryption_key,
3430
14
        &ett_sdp_session_attribute,
3431
14
        &ett_sdp_media,
3432
14
        &ett_sdp_media_attribute,
3433
14
        &ett_sdp_fmtp,
3434
14
        &ett_sdp_key_mgmt,
3435
14
        &ett_sdp_crypto_key_parameters,
3436
14
    };
3437
3438
14
    static ei_register_info ei[] = {
3439
14
        { &ei_sdp_invalid_key_param,
3440
14
            { "sdp.invalid_key_param",
3441
14
              PI_MALFORMED, PI_NOTE,
3442
14
              "Invalid key-param (no ':' delimiter)",
3443
14
              EXPFILL
3444
14
            }
3445
14
        },
3446
14
        { &ei_sdp_invalid_line_equal,
3447
14
            { "sdp.invalid_line.no_equal",
3448
14
              PI_MALFORMED, PI_NOTE,
3449
14
              "Invalid SDP line (no '=' delimiter)",
3450
14
              EXPFILL
3451
14
            }
3452
14
        },
3453
14
        { &ei_sdp_invalid_line_fields,
3454
14
            { "sdp.invalid_line.missing_fields",
3455
14
              PI_MALFORMED, PI_ERROR,
3456
14
              "Invalid SDP line (missing required fields)",
3457
14
              EXPFILL
3458
14
            }
3459
14
        },
3460
14
        { &ei_sdp_invalid_line_space,
3461
14
            { "sdp.invalid_line.extra_space",
3462
14
              PI_MALFORMED, PI_ERROR,
3463
14
              "Invalid SDP whitespace (extra space character)",
3464
14
              EXPFILL
3465
14
            }
3466
14
        },
3467
14
        { &ei_sdp_invalid_conversion,
3468
14
            { "sdp.invalid_conversion",
3469
14
              PI_PROTOCOL, PI_WARN,
3470
14
              "Invalid conversion",
3471
14
              EXPFILL
3472
14
            }
3473
14
        },
3474
14
        { &ei_sdp_invalid_media_port,
3475
14
            { "sdp.invalid_media_port",
3476
14
              PI_MALFORMED, PI_ERROR,
3477
14
              "Invalid media port",
3478
14
              EXPFILL
3479
14
            }
3480
14
        },
3481
14
        { &ei_sdp_invalid_sample_rate,
3482
14
            { "sdp.invalid_sample_rate",
3483
14
              PI_MALFORMED, PI_ERROR,
3484
14
              "Invalid sample rate",
3485
14
              EXPFILL
3486
14
            }
3487
14
        },
3488
14
        { &ei_sdp_invalid_channels,
3489
14
            { "sdp.invalid_channels",
3490
14
              PI_MALFORMED, PI_WARN,
3491
14
              "Invalid number of audio channels",
3492
14
              EXPFILL
3493
14
            }
3494
14
        },
3495
14
        { &ei_sdp_invalid_media_format,
3496
14
            { "sdp.invalid_media_format",
3497
14
              PI_MALFORMED, PI_ERROR,
3498
14
              "Invalid media format",
3499
14
              EXPFILL
3500
14
            }
3501
14
        },
3502
14
        { &ei_sdp_invalid_crypto_tag,
3503
14
            { "sdp.invalid_crypto_tag",
3504
14
              PI_MALFORMED, PI_ERROR,
3505
14
              "Invalid crypto tag",
3506
14
              EXPFILL
3507
14
            }
3508
14
        },
3509
14
        { &ei_sdp_invalid_crypto_mki_length,
3510
14
            { "sdp.invalid_crypto_mki_length",
3511
14
              PI_MALFORMED, PI_ERROR,
3512
14
              "Invalid crypto mki length",
3513
14
              EXPFILL
3514
14
            }
3515
14
        }
3516
14
    };
3517
3518
14
    module_t *sdp_module;
3519
14
    expert_module_t* expert_sdp;
3520
3521
14
    proto_sdp = proto_register_protocol("Session Description Protocol",
3522
14
                                        "SDP", "sdp");
3523
14
    proto_register_field_array(proto_sdp, hf, array_length(hf));
3524
14
    proto_register_subtree_array(ett, array_length(ett));
3525
14
    expert_sdp = expert_register_protocol(proto_sdp);
3526
14
    expert_register_field_array(expert_sdp, ei, array_length(ei));
3527
3528
14
    key_mgmt_dissector_table = register_dissector_table("key_mgmt",
3529
14
                                                        "Key Management", proto_sdp, FT_STRING, STRING_CASE_SENSITIVE);
3530
    /*
3531
     * Preferences registration
3532
     */
3533
14
    sdp_module = prefs_register_protocol(proto_sdp, NULL);
3534
14
    prefs_register_bool_preference(sdp_module, "establish_conversation",
3535
14
                                   "Establish Media Conversation",
3536
14
                                   "Specifies that RTP/RTCP/T.38/MSRP/etc streams are decoded based "
3537
14
                                   "upon port numbers found in SDP payload",
3538
14
                                   &global_sdp_establish_conversation);
3539
3540
14
    sdp_transport_reqs = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
3541
14
    sdp_transport_rsps = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
3542
14
    sdp_rtsp_control_map = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), wmem_str_hash, g_str_equal);
3543
3544
    /*
3545
     * Register the dissector by name, so other dissectors can
3546
     * grab it by name rather than just referring to it directly.
3547
     */
3548
14
    sdp_handle = register_dissector("sdp", dissect_sdp, proto_sdp);
3549
3550
    /* Register for tapping */
3551
14
    sdp_tap = register_tap("sdp");
3552
3553
    /* compile patterns */
3554
14
    ws_mempbrk_compile(&pbrk_digits, "0123456789");
3555
14
    ws_mempbrk_compile(&pbrk_alpha, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
3556
14
}
3557
3558
void
3559
proto_reg_handoff_sdp(void)
3560
14
{
3561
14
    rtcp_handle   = find_dissector_add_dependency("rtcp", proto_sdp);
3562
14
    msrp_handle   = find_dissector_add_dependency("msrp", proto_sdp);
3563
14
    sprt_handle   = find_dissector_add_dependency("sprt", proto_sdp);
3564
14
    bfcp_handle   = find_dissector_add_dependency("bfcp", proto_sdp);
3565
14
    h264_handle   = find_dissector_add_dependency("h264", proto_sdp);
3566
14
    h265_handle   = find_dissector_add_dependency("h265", proto_sdp);
3567
14
    mp4ves_config_handle = find_dissector_add_dependency("mp4ves_config", proto_sdp);
3568
3569
14
    proto_sprt    = dissector_handle_get_protocol_index(find_dissector("sprt"));
3570
3571
14
    dissector_add_string("media_type", "application/sdp", sdp_handle);
3572
14
    dissector_add_uint("bctp.tpi", 0x20, sdp_handle);
3573
14
}
3574
3575
/*
3576
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
3577
 *
3578
 * Local variables:
3579
 * c-basic-offset: 4
3580
 * tab-width: 8
3581
 * indent-tabs-mode: nil
3582
 * End:
3583
 *
3584
 * vi: set shiftwidth=4 tabstop=8 expandtab:
3585
 * :indentSize=4:tabSize=8:noTabs=true:
3586
 */