Use MAC address documentation range in filter examples
[metze/wireshark/wip.git] / epan / dissectors / packet-sdp.c
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  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  * Ref http://www.ietf.org/rfc/rfc4566.txt?number=4566
25  */
26
27 #include "config.h"
28
29 #include <epan/packet.h>
30 #include <epan/exceptions.h>
31 #include <epan/asn1.h>
32 #include <epan/prefs.h>
33 #include <epan/expert.h>
34 #include <epan/tap.h>
35 #include <epan/rtp_pt.h>
36 #include <epan/show_exception.h>
37 #include <epan/addr_resolv.h>
38
39 #include "packet-sdp.h"
40
41 /* un-comment the following as well as this line in conversation.c, to enable debug printing */
42 /* #define DEBUG_CONVERSATION */
43 #include "conversation_debug.h"
44
45 #include "packet-rtp.h"
46
47 #include "packet-rtcp.h"
48 #include "packet-t38.h"
49 #include "packet-msrp.h"
50 #include "packet-sprt.h"
51 #include "packet-h245.h"
52 #include "packet-h264.h"
53 #include "packet-mp4ves.h"
54
55 void proto_register_sdp(void);
56 void proto_reg_handoff_sdp(void);
57
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 h264_handle;
62 static dissector_handle_t mp4ves_handle;
63
64 static int sdp_tap = -1;
65
66 static int proto_sdp = -1;
67 static int proto_sprt = -1;
68
69 static const char* UNKNOWN_ENCODING = "Unknown";
70 static wmem_tree_t *sdp_transport_reqs = NULL;
71 static wmem_tree_t *sdp_transport_rsps = NULL;
72
73 /* preference globals */
74 static gboolean global_sdp_establish_conversation = TRUE;
75
76 /* Top level fields */
77 static int hf_protocol_version = -1;
78 static int hf_owner = -1;
79 static int hf_session_name = -1;
80 static int hf_session_info = -1;
81 static int hf_uri = -1;
82 static int hf_email = -1;
83 static int hf_phone = -1;
84 static int hf_connection_info = -1;
85 static int hf_bandwidth = -1;
86 static int hf_timezone = -1;
87 static int hf_encryption_key = -1;
88 static int hf_session_attribute = -1;
89 static int hf_media_attribute = -1;
90 static int hf_time = -1;
91 static int hf_repeat_time = -1;
92 static int hf_media = -1;
93 static int hf_media_title = -1;
94 static int hf_unknown = -1;
95 static int hf_invalid = -1;
96 static int hf_ipbcp_version = -1;
97 static int hf_ipbcp_type = -1;
98
99 /* hf_owner subfields*/
100 static int hf_owner_username = -1;
101 static int hf_owner_sessionid = -1;
102 static int hf_owner_version = -1;
103 static int hf_owner_network_type = -1;
104 static int hf_owner_address_type = -1;
105 static int hf_owner_address = -1;
106
107 /* hf_connection_info subfields */
108 static int hf_connection_info_network_type = -1;
109 static int hf_connection_info_address_type = -1;
110 static int hf_connection_info_connection_address = -1;
111 static int hf_connection_info_ttl = -1;
112 static int hf_connection_info_num_addr = -1;
113
114 /* hf_bandwidth subfields */
115 static int hf_bandwidth_modifier = -1;
116 static int hf_bandwidth_value = -1;
117
118 /* hf_time subfields */
119 static int hf_time_start = -1;
120 static int hf_time_stop = -1;
121
122 /* hf_repeat_time subfield */
123 static int hf_repeat_time_interval = -1;
124 static int hf_repeat_time_duration = -1;
125 static int hf_repeat_time_offset = -1;
126
127 /* hf_timezone subfields */
128 static int hf_timezone_time = -1;
129 static int hf_timezone_offset = -1;
130
131 /* hf_encryption_key subfields */
132 static int hf_encryption_key_type = -1;
133 static int hf_encryption_key_data = -1;
134
135 /* hf_session_attribute subfields */
136 static int hf_session_attribute_field = -1;
137 static int hf_session_attribute_value = -1;
138
139 /* hf_media subfields */
140 static int hf_media_media = -1;
141 static int hf_media_port = -1;
142 static int hf_media_port_string = -1;
143 static int hf_media_portcount = -1;
144 static int hf_media_proto = -1;
145 static int hf_media_format = -1;
146
147 /* hf_session_attribute subfields */
148 static int hf_media_attribute_field = -1;
149 static int hf_media_attribute_value = -1;
150 static int hf_media_encoding_name = -1;
151 static int hf_media_sample_rate = -1;
152 static int hf_media_format_specific_parameter = -1;
153 static int hf_sdp_fmtp_mpeg4_profile_level_id = -1;
154 static int hf_sdp_fmtp_h263_profile = -1;
155 static int hf_sdp_fmtp_h263_level = -1;
156 static int hf_sdp_h264_packetization_mode = -1;
157 static int hf_SDPh223LogicalChannelParameters = -1;
158
159 /* hf_session_attribute hf_media_attribute subfields */
160 static int hf_key_mgmt_att_value = -1;
161 static int hf_key_mgmt_prtcl_id = -1;
162 static int hf_key_mgmt_data = -1;
163
164 static int hf_sdp_crypto_tag = -1;
165 static int hf_sdp_crypto_crypto_suite = -1;
166 static int hf_sdp_crypto_master_key = -1;
167 static int hf_sdp_crypto_master_salt = -1;
168 static int hf_sdp_crypto_lifetime = -1;
169 static int hf_sdp_crypto_mki = -1;
170 static int hf_sdp_crypto_mki_length = -1;
171
172 /* Generated from convert_proto_tree_add_text.pl */
173 static int hf_sdp_nal_unit_2_string = -1;
174 static int hf_sdp_key_and_salt = -1;
175 static int hf_sdp_nal_unit_1_string = -1;
176 static int hf_sdp_data = -1;
177
178 /* trees */
179 static int ett_sdp = -1;
180 static int ett_sdp_owner = -1;
181 static int ett_sdp_connection_info = -1;
182 static int ett_sdp_bandwidth = -1;
183 static int ett_sdp_time = -1;
184 static int ett_sdp_repeat_time = -1;
185 static int ett_sdp_timezone = -1;
186 static int ett_sdp_encryption_key = -1;
187 static int ett_sdp_session_attribute = -1;
188 static int ett_sdp_media = -1;
189 static int ett_sdp_media_attribute = -1;
190 static int ett_sdp_fmtp = -1;
191 static int ett_sdp_key_mgmt = -1;
192 static int ett_sdp_crypto_key_parameters = -1;
193
194 static expert_field ei_sdp_invalid_key_param   = EI_INIT;
195 static expert_field ei_sdp_invalid_line_equal  = EI_INIT;
196 static expert_field ei_sdp_invalid_line_fields = EI_INIT;
197 static expert_field ei_sdp_invalid_line_space  = EI_INIT;
198 static expert_field ei_sdp_invalid_conversion = EI_INIT;
199
200 /* patterns used for tvb_ws_mempbrk_pattern_guint8 */
201 static ws_mempbrk_pattern pbrk_digits;
202 static ws_mempbrk_pattern pbrk_alpha;
203
204 #define SDP_RTP_PROTO       0x00000001
205 #define SDP_SRTP_PROTO      0x00000002
206 #define SDP_T38_PROTO       0x00000004
207 #define SDP_MSRP_PROTO      0x00000008
208 #define SDP_SPRT_PROTO      0x00000010
209 #define SDP_IPv4            0x80000000
210 #define SDP_IPv6            0x40000000
211 #define SDP_MSRP_IPv4       0x20000000
212 #define SDP_VIDEO           0x10000000
213
214
215 #define SDP_MAX_RTP_CHANNELS 4
216 #define SDP_MAX_RTP_PAYLOAD_TYPES 20
217 #define SDP_NO_OF_PT 128
218 typedef struct {
219     gint32 pt[SDP_MAX_RTP_PAYLOAD_TYPES];
220     gint8 pt_count;
221     rtp_dyn_payload_t *rtp_dyn_payload;
222     gboolean set_rtp;
223 } transport_media_pt_t;
224
225 typedef struct {
226     enum sdp_exchange_type sdp_status;
227     char  *encoding_name[SDP_NO_OF_PT];
228     int    sample_rate[SDP_NO_OF_PT];
229     int    media_port[SDP_MAX_RTP_CHANNELS];
230     address  src_addr[SDP_MAX_RTP_CHANNELS];
231     guint  proto_bitmask[SDP_MAX_RTP_CHANNELS];
232     transport_media_pt_t media[SDP_MAX_RTP_CHANNELS];
233     gint8  media_count;
234     /* SRTP related info XXX note currently we only handle one crypto line in the SDP
235     * We should probably handle offer/answer and session updates etc(SIP) quite possibly the whole handling of
236     * seting up the RTP conversations should be done by the signaling protocol(s) calling the SDP dissector
237     * and the SDP dissector just provide the relevant data.
238     * YES! packet-sdp.c should be about SDP parsing... SDP *state* needs to be maintained by upper
239     * protocols, because each one has different rules/semantics.
240     */
241     guint  encryption_algorithm;
242     guint  auth_algorithm;
243     guint  mki_len;                /* number of octets used for the MKI in the RTP payload */
244     guint  auth_tag_len;           /* number of octets used for the Auth Tag in the RTP payload */
245 } transport_info_t;
246
247 /* Data that is retrieved from a packet, but does not need to be kept */
248 typedef struct {
249     char  *connection_address; /* there should actually be SDP_MAX_RTP_CHANNELS of these too */
250     char  *connection_type;
251     /* media_type is for 'audio', 'video', etc, so per-stream */
252     char  *media_type[SDP_MAX_RTP_CHANNELS];
253     char  *media_port[SDP_MAX_RTP_CHANNELS];
254     char  *media_proto[SDP_MAX_RTP_CHANNELS];
255     guint8 media_count;
256
257     /* MSRP transport info (as set while parsing path attribute) */
258     gboolean msrp_transport_address_set;
259     guint32  msrp_ipaddr[4];
260     guint16  msrp_port_number;
261
262 } disposable_media_info_t;
263
264
265 /* here lie the debugging dumper functions */
266 #ifdef DEBUG_CONVERSATION
267 static void sdp_dump_transport_media(const transport_media_pt_t* media) {
268     int i;
269     int count;
270     DPRINT2(("transport_media contents:"));
271     DINDENT();
272         if (!media) {
273             DPRINT2(("null transport_media_pt_t*"));
274             DENDENT();
275             return;
276         }
277         count = (int)media->pt_count;
278         DPRINT2(("pt_count=%d",count));
279         DINDENT();
280             for (i=0; i < count; i++) {
281                 DPRINT2(("pt=%d", media->pt[i]));
282             }
283         DENDENT();
284         DPRINT2(("rtp_dyn_payload hashtable=%s", media->rtp_dyn_payload ? "YES" : "NO"));
285         if (media->rtp_dyn_payload) {
286             rtp_dump_dyn_payload(media->rtp_dyn_payload);
287         }
288         DPRINT2(("set_rtp=%s", media->set_rtp ? "TRUE" : "FALSE"));
289     DENDENT();
290 }
291
292 static const value_string sdp_exchange_type_vs[] = {
293     { SDP_EXCHANGE_OFFER,         "SDP_EXCHANGE_OFFER" },
294     { SDP_EXCHANGE_ANSWER_ACCEPT, "SDP_EXCHANGE_ANSWER_ACCEPT" },
295     { SDP_EXCHANGE_ANSWER_REJECT, "SDP_EXCHANGE_ANSWER_REJECT" },
296     { 0, NULL }
297 };
298
299 static void sdp_dump_transport_info(const transport_info_t* info) {
300     int i;
301     int count;
302     DPRINT2(("transport_info contents:"));
303     DINDENT();
304         if (!info) {
305             DPRINT2(("null transport_info_t*"));
306             DENDENT();
307             return;
308         }
309         DPRINT2(("sdp_status=%s",
310                  val_to_str(info->sdp_status, sdp_exchange_type_vs, "SDP_EXCHANGE_UNKNOWN")));
311         DPRINT2(("payload type contents:"));
312         DINDENT();
313             for (i=0; i < SDP_NO_OF_PT; i++) {
314                 /* don't print out unknown encodings */
315                 if (info->encoding_name[i] &&
316                     strcmp(UNKNOWN_ENCODING,info->encoding_name[i]) != 0) {
317                     DPRINT2(("payload type #%d:",i));
318                     DINDENT();
319                         DPRINT2(("encoding_name=%s", info->encoding_name[i]));
320                         DPRINT2(("sample_rate=%d", info->sample_rate[i]));
321                     DENDENT();
322                 }
323             }
324         DENDENT();
325         count = (int)info->media_count;
326         DPRINT2(("media_count=%d", count));
327         DPRINT2(("rtp channels:"));
328         DINDENT();
329             for (i=0; i <= count; i++) {
330                 DPRINT2(("channel #%d:",i));
331                 DINDENT();
332                     DPRINT2(("src_addr=%s",
333                             address_to_str(wmem_packet_scope(), &(info->src_addr[i]))));
334                     DPRINT2(("media_port=%d", info->media_port[i]));
335                     DPRINT2(("proto_bitmask=%x", info->proto_bitmask[i]));
336                     sdp_dump_transport_media(&(info->media[i]));
337                 DENDENT();
338             }
339         DENDENT();
340         DPRINT2(("encryption_algorithm=%u", info->encryption_algorithm));
341         DPRINT2(("auth_algorithm=%u", info->auth_algorithm));
342         if (info->encryption_algorithm || info->auth_algorithm) {
343             DPRINT2(("mki_len=%u", info->mki_len));
344             if (info->auth_algorithm) {
345                 DPRINT2(("auth_tag_len=%u", info->auth_tag_len));
346             }
347         }
348     DENDENT();
349 }
350
351 static void sdp_dump_disposable_media_info(const disposable_media_info_t* info) {
352     int i;
353     int count;
354     DPRINT2(("disposable_media_info contents:"));
355     DINDENT();
356         if (!info) {
357             DPRINT2(("null disposable_media_info_t*"));
358             DENDENT();
359             return;
360         }
361         DPRINT2(("connection_address=%s",
362                 info->connection_address ? info->connection_address : "NULL"));
363         DPRINT2(("connection_type=%s",
364                 info->connection_type ? info->connection_type : "NULL"));
365         count = (int)info->media_count;
366         DPRINT2(("media_count=%d",count));
367         DINDENT();
368             for (i=0; i < count; i++) {
369                 DPRINT2(("media #%d:",i));
370                 DINDENT();
371                     DPRINT2(("media_type=%s", info->media_type[i] ? info->media_type[i] : "NULL"));
372                     DPRINT2(("media_port=%s", info->media_port[i] ? info->media_port[i] : "NULL"));
373                     DPRINT2(("media_proto=%s", info->media_proto[i] ? info->media_proto[i] : "NULL"));
374                 DENDENT();
375             }
376         DENDENT();
377         DPRINT2(("msrp_transport_address_set=%s",
378                 info->msrp_transport_address_set ? "TRUE" : "FALSE"));
379         if (info->msrp_transport_address_set) {
380             DINDENT();
381                 DPRINT2(("msrp_ipaddr=%u.%u.%u.%u",
382                         info->msrp_ipaddr[0],info->msrp_ipaddr[1],
383                         info->msrp_ipaddr[2],info->msrp_ipaddr[3]));
384                 DPRINT2(("msrp_port_number=%hu",info->msrp_port_number));
385             DENDENT();
386         }
387     DENDENT();
388 }
389 #endif /* DEBUG_CONVERSATION */
390
391
392 /* key-mgmt dissector
393  * IANA registry:
394  * http://www.iana.org/assignments/sdp-parameters
395  */
396 static dissector_table_t key_mgmt_dissector_table;
397
398 /* Finds next token (sequence of non-space chars) in tvb from given offset.
399  * The returned value is the token length, or 0 if none found.
400  * The offset is changed to be the starting offset, in case there were one or more
401  * spaces at the beginning. (this will also add expert info in such a case)
402  * The next_offset is set to the next found space after the token, or -1 if the
403  * end of line is hit or no token found.
404  * If this is the last token in the line, tokenlen will not be 0, but next_offset
405  * will be -1.
406  *
407  * The optional param, if TRUE, means no expert error will be issued if no token
408  * is found; if FALSE then a expert error will be issued if no token is found.
409  *
410  * This function expects to be given a tvb of only one line, and does no error
411  * checking of its given arguments.
412  */
413 static inline gint
414 find_next_optional_token_in_line(tvbuff_t *tvb, proto_tree *tree,
415                                  gint *offset, gint *next_offset,
416                                  const gboolean optional)
417 {
418     gint tokenlen = 0;
419     gint next_off = -1;
420     gint off      = *offset;
421
422     if (tvb_offset_exists(tvb, off)) {
423         while (tokenlen == 0) {
424             next_off = tvb_find_guint8(tvb, off, -1, ' ');
425             if (next_off == -1) {
426                 tokenlen = tvb_captured_length_remaining(tvb, off);
427                 break; /* Nothing more left */
428             }
429
430             tokenlen = next_off - off;
431
432             if (tokenlen == 0) {
433                 /* two spaces in a row - illegal, but we'll keep dissecting */
434                 proto_tree_add_expert(tree, NULL, &ei_sdp_invalid_line_space, tvb, off-1, 2);
435                 off = next_off + 1;
436             }
437         }
438     }
439
440     if (!optional && tokenlen == 0) {
441         proto_tree_add_expert(tree, NULL, &ei_sdp_invalid_line_fields, tvb, 0, -1);
442     }
443
444     *next_offset = next_off;
445     *offset      = off;
446     return tokenlen;
447 }
448
449 /* Same as above, but always issues an expert error if a token is not found. */
450 static inline gint
451 find_next_token_in_line(tvbuff_t *tvb, proto_tree *tree, gint *offset, gint *next_offset)
452 {
453     return find_next_optional_token_in_line(tvb, tree, offset, next_offset, FALSE);
454 }
455
456
457 /* Subdissector functions */
458 static void
459 dissect_sdp_owner(tvbuff_t *tvb, proto_item *ti) {
460     proto_tree *sdp_owner_tree;
461     gint        offset, next_offset, tokenlen;
462
463     offset = 0;
464
465     sdp_owner_tree = proto_item_add_subtree(ti, ett_sdp_owner);
466
467     /* Find the username */
468     tokenlen = find_next_token_in_line(tvb, sdp_owner_tree, &offset, &next_offset);
469     if (tokenlen == 0)
470         return;
471
472     proto_tree_add_item(sdp_owner_tree, hf_owner_username, tvb, offset, tokenlen,
473                         ENC_UTF_8|ENC_NA);
474     offset = next_offset  + 1;
475
476     /* Find the session id */
477     tokenlen = find_next_token_in_line(tvb, sdp_owner_tree, &offset, &next_offset);
478     if (tokenlen == 0)
479         return;
480
481     proto_tree_add_item(sdp_owner_tree, hf_owner_sessionid, tvb, offset,
482                         tokenlen, ENC_UTF_8|ENC_NA);
483     offset = next_offset + 1;
484
485     /* Find the version */
486     tokenlen = find_next_token_in_line(tvb, sdp_owner_tree, &offset, &next_offset);
487     if (tokenlen == 0)
488         return;
489
490     proto_tree_add_item(sdp_owner_tree, hf_owner_version, tvb, offset, tokenlen,
491                         ENC_UTF_8|ENC_NA);
492     offset = next_offset + 1;
493
494     /* Find the network type */
495     tokenlen = find_next_token_in_line(tvb, sdp_owner_tree, &offset, &next_offset);
496     if (tokenlen == 0)
497         return;
498
499     proto_tree_add_item(sdp_owner_tree, hf_owner_network_type, tvb, offset,
500                         tokenlen, ENC_UTF_8|ENC_NA);
501     offset = next_offset + 1;
502
503     /* Find the address type */
504     tokenlen = find_next_token_in_line(tvb, sdp_owner_tree, &offset, &next_offset);
505     if (tokenlen == 0)
506         return;
507
508     proto_tree_add_item(sdp_owner_tree, hf_owner_address_type, tvb, offset,
509                         tokenlen, ENC_UTF_8|ENC_NA);
510     offset = next_offset + 1;
511
512     /* Find the address */
513     proto_tree_add_item(sdp_owner_tree, hf_owner_address, tvb, offset, -1, ENC_UTF_8|ENC_NA);
514 }
515
516 /*
517  * XXX - this can leak memory if an exception is thrown after we've fetched
518  * a string.
519  */
520 static void
521 dissect_sdp_connection_info(tvbuff_t *tvb, proto_item* ti,
522                             disposable_media_info_t *media_info) {
523     proto_tree *sdp_connection_info_tree;
524     gint        offset, next_offset, tokenlen;
525
526     offset = 0;
527
528     sdp_connection_info_tree = proto_item_add_subtree(ti,
529                                                       ett_sdp_connection_info);
530
531     /* Find the network type */
532     tokenlen = find_next_token_in_line(tvb, sdp_connection_info_tree, &offset, &next_offset);
533     if (tokenlen == 0)
534         return;
535
536     proto_tree_add_item(sdp_connection_info_tree,
537                         hf_connection_info_network_type, tvb, offset, tokenlen,
538                         ENC_UTF_8|ENC_NA);
539     offset = next_offset + 1;
540
541     /* Find the address type */
542     tokenlen = find_next_token_in_line(tvb, sdp_connection_info_tree, &offset, &next_offset);
543     if (tokenlen == 0)
544         return;
545
546     /* Save connection address type */
547     media_info->connection_type = (char*)tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
548
549     DPRINT(("parsed connection line type=%s", media_info->connection_type));
550
551     proto_tree_add_item(sdp_connection_info_tree,
552                         hf_connection_info_address_type, tvb, offset, tokenlen,
553                         ENC_UTF_8|ENC_NA);
554     offset = next_offset + 1;
555
556     /* Find the connection address */
557     /* XXX - what if there's a <number of addresses> value? */
558     next_offset = tvb_find_guint8(tvb, offset, -1, '/');
559     if (next_offset == -1) {
560         tokenlen = -1; /* end of tvbuff */
561         /* Save connection address */
562         media_info->connection_address =
563             (char*)tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_UTF_8|ENC_NA);
564     } else {
565         tokenlen = next_offset - offset;
566         /* Save connection address */
567         media_info->connection_address = (char*)tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
568     }
569
570     DPRINT(("parsed connection line address=%s", media_info->connection_address));
571
572     proto_tree_add_item(sdp_connection_info_tree,
573                         hf_connection_info_connection_address, tvb, offset,
574                         tokenlen, ENC_UTF_8|ENC_NA);
575     if (next_offset != -1) {
576         offset = next_offset + 1;
577         next_offset = tvb_find_guint8(tvb, offset, -1, '/');
578         if (next_offset == -1) {
579             tokenlen = -1; /* end of tvbuff */
580         } else {
581             tokenlen = next_offset - offset;
582         }
583         proto_tree_add_item(sdp_connection_info_tree,
584                             hf_connection_info_ttl, tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
585         if (next_offset != -1) {
586             offset = next_offset + 1;
587             proto_tree_add_item(sdp_connection_info_tree,
588                                 hf_connection_info_num_addr, tvb, offset, -1, ENC_UTF_8|ENC_NA);
589         }
590     }
591 }
592
593 static void
594 dissect_sdp_bandwidth(tvbuff_t *tvb, proto_item *ti) {
595     proto_tree *sdp_bandwidth_tree;
596     gint        offset, next_offset, tokenlen;
597     proto_item *item;
598     gboolean    unit_is_kbs = FALSE;
599     gboolean    unit_is_bps = FALSE;
600
601     offset = 0;
602
603     sdp_bandwidth_tree = proto_item_add_subtree(ti, ett_sdp_bandwidth);
604
605     /* find the modifier */
606     next_offset = tvb_find_guint8(tvb, offset, -1, ':');
607
608     if (next_offset == -1)
609         return;
610
611     tokenlen = next_offset - offset;
612
613     item = proto_tree_add_item(sdp_bandwidth_tree, hf_bandwidth_modifier, tvb, offset,
614                                tokenlen, ENC_UTF_8|ENC_NA);
615     if (tvb_strneql(tvb, offset, "CT", 2) == 0) {
616         proto_item_append_text(item, " [Conference Total(total bandwidth of all RTP sessions)]");
617         unit_is_kbs = TRUE;
618     } else if (tvb_strneql(tvb, offset, "AS", 2) == 0) {
619         proto_item_append_text(item, " [Application Specific (RTP session bandwidth)]");
620         unit_is_kbs = TRUE;
621     } else if (tvb_strneql(tvb, offset, "TIAS", 4) == 0) {
622         proto_item_append_text(item, " [Transport Independent Application Specific maximum]");
623         unit_is_bps = TRUE;
624     }
625
626
627     offset = next_offset + 1;
628
629     item = proto_tree_add_item(sdp_bandwidth_tree, hf_bandwidth_value, tvb, offset, -1,
630                                ENC_UTF_8|ENC_NA);
631     if (unit_is_kbs == TRUE)
632         proto_item_append_text(item, " kb/s");
633     if (unit_is_bps == TRUE)
634         proto_item_append_text(item, " b/s");
635 }
636
637 static void dissect_sdp_time(tvbuff_t *tvb, proto_item* ti) {
638     proto_tree *sdp_time_tree;
639     gint        offset, next_offset, tokenlen;
640
641     offset = 0;
642
643     sdp_time_tree = proto_item_add_subtree(ti, ett_sdp_time);
644
645     /* get start time */
646     tokenlen = find_next_token_in_line(tvb, sdp_time_tree, &offset, &next_offset);
647     if (tokenlen == 0)
648         return;
649
650     proto_tree_add_item(sdp_time_tree, hf_time_start, tvb, offset, tokenlen,
651                         ENC_UTF_8|ENC_NA);
652
653     /* get stop time */
654     offset = next_offset + 1;
655     proto_tree_add_item(sdp_time_tree, hf_time_stop, tvb, offset, -1, ENC_UTF_8|ENC_NA);
656 }
657
658 static void dissect_sdp_repeat_time(tvbuff_t *tvb, proto_item* ti) {
659     proto_tree *sdp_repeat_time_tree;
660     gint        offset, next_offset, tokenlen;
661     gboolean    optional = FALSE;
662
663     offset = 0;
664
665     sdp_repeat_time_tree = proto_item_add_subtree(ti, ett_sdp_time);
666
667     /* get interval */
668     tokenlen = find_next_token_in_line(tvb, sdp_repeat_time_tree, &offset, &next_offset);
669     if (tokenlen == 0)
670         return;
671
672     proto_tree_add_item(sdp_repeat_time_tree, hf_repeat_time_interval, tvb,
673                         offset, tokenlen, ENC_UTF_8|ENC_NA);
674
675     /* get duration */
676     offset = next_offset + 1;
677     tokenlen = find_next_token_in_line(tvb, sdp_repeat_time_tree, &offset, &next_offset);
678     if (tokenlen == 0)
679         return;
680
681     proto_tree_add_item(sdp_repeat_time_tree, hf_repeat_time_duration, tvb,
682                         offset, tokenlen, ENC_UTF_8|ENC_NA);
683
684     /* get offsets */
685     do {
686         offset = next_offset +1;
687         tokenlen = find_next_optional_token_in_line(tvb, sdp_repeat_time_tree,
688                                                     &offset, &next_offset, optional);
689         if (tokenlen == 0)
690             break;
691         proto_tree_add_item(sdp_repeat_time_tree, hf_repeat_time_offset,
692                             tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
693         optional = TRUE;
694     } while (next_offset != -1);
695
696 }
697
698 static void
699 dissect_sdp_timezone(tvbuff_t *tvb, proto_item* ti) {
700     proto_tree* sdp_timezone_tree;
701     gint        offset, next_offset, tokenlen;
702     gboolean    optional = FALSE;
703
704     offset = 0;
705
706     sdp_timezone_tree = proto_item_add_subtree(ti, ett_sdp_timezone);
707
708     do {
709         tokenlen = find_next_optional_token_in_line(tvb, sdp_timezone_tree,
710                                                     &offset, &next_offset, optional);
711         if (tokenlen == 0)
712             break;
713
714         proto_tree_add_item(sdp_timezone_tree, hf_timezone_time, tvb, offset,
715                             tokenlen, ENC_UTF_8|ENC_NA);
716         offset = next_offset + 1;
717         tokenlen = find_next_optional_token_in_line(tvb, sdp_timezone_tree,
718                                                     &offset, &next_offset, optional);
719         if (tokenlen == 0)
720             break;
721         proto_tree_add_item(sdp_timezone_tree, hf_timezone_offset, tvb, offset,
722                             tokenlen, ENC_UTF_8|ENC_NA);
723         offset = next_offset + 1;
724         optional = TRUE;
725     } while (next_offset != -1);
726
727 }
728
729
730 static void dissect_sdp_encryption_key(tvbuff_t *tvb, proto_item * ti) {
731     proto_tree *sdp_encryption_key_tree;
732     gint        offset, next_offset, tokenlen;
733
734     offset = 0;
735
736     sdp_encryption_key_tree = proto_item_add_subtree(ti, ett_sdp_encryption_key);
737
738     next_offset = tvb_find_guint8(tvb, offset, -1, ':');
739
740     if (next_offset == -1)
741         return;
742
743     tokenlen = next_offset - offset;
744
745     proto_tree_add_item(sdp_encryption_key_tree, hf_encryption_key_type,
746                         tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
747
748     offset = next_offset + 1;
749     proto_tree_add_item(sdp_encryption_key_tree, hf_encryption_key_data,
750                         tvb, offset, -1, ENC_UTF_8|ENC_NA);
751 }
752
753 static void dissect_key_mgmt(tvbuff_t *tvb, packet_info * pinfo, proto_item * ti) {
754     gchar      *data_p      = NULL;
755     gchar      *prtcl_id    = NULL;
756     gint        len;
757     tvbuff_t   *keymgmt_tvb;
758     int         found_match = 0;
759     proto_tree *key_tree;
760     gint        next_offset;
761     gint        offset      = 0;
762     gint        tokenlen;
763
764     key_tree = proto_item_add_subtree(ti, ett_sdp_key_mgmt);
765
766     tokenlen = find_next_token_in_line(tvb, key_tree, &offset, &next_offset);
767     if (tokenlen == 0)
768         return;
769
770     prtcl_id = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
771
772     proto_tree_add_item(key_tree, hf_key_mgmt_prtcl_id, tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
773
774     offset = next_offset + 1;
775
776     len = tvb_captured_length_remaining(tvb, offset);
777     if (len < 0)
778         return;
779
780     data_p = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, len, ENC_UTF_8|ENC_NA);
781     keymgmt_tvb = base64_to_tvb(tvb, data_p);
782     add_new_data_source(pinfo, keymgmt_tvb, "Key Management Data");
783
784     if ((prtcl_id != NULL) && (key_mgmt_dissector_table != NULL)) {
785         found_match = dissector_try_string(key_mgmt_dissector_table,
786                                            prtcl_id,
787                                            keymgmt_tvb, pinfo,
788                                            key_tree, NULL);
789     }
790
791     if (found_match) {
792         proto_item *ti2 = proto_tree_add_item(key_tree, hf_key_mgmt_data,
793                                               keymgmt_tvb, 0, -1, ENC_NA);
794         PROTO_ITEM_SET_HIDDEN(ti2);
795     } else {
796         proto_tree_add_item(key_tree, hf_key_mgmt_data,
797                             keymgmt_tvb, 0, -1, ENC_NA);
798     }
799
800 }
801
802
803 static void dissect_sdp_session_attribute(tvbuff_t *tvb, packet_info * pinfo, proto_item * ti) {
804     proto_tree *sdp_session_attribute_tree;
805     gint        offset, next_offset, tokenlen;
806     guint8     *field_name;
807
808     offset = 0;
809
810     sdp_session_attribute_tree = proto_item_add_subtree(ti,
811                                                         ett_sdp_session_attribute);
812
813     next_offset = tvb_find_guint8(tvb, offset, -1, ':');
814
815     if (next_offset == -1)
816         return;
817
818     tokenlen = next_offset - offset;
819
820     proto_tree_add_item(sdp_session_attribute_tree, hf_session_attribute_field,
821                         tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
822
823     field_name = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
824
825     offset = next_offset + 1;
826
827     if (strcmp((char*)field_name, "ipbcp") == 0) {
828         offset = tvb_ws_mempbrk_pattern_guint8(tvb, offset, -1,&pbrk_digits, NULL);
829
830         if (offset == -1)
831             return;
832
833         tokenlen = find_next_token_in_line(tvb, sdp_session_attribute_tree, &offset, &next_offset);
834         if (tokenlen == 0)
835             return;
836
837         proto_tree_add_item(sdp_session_attribute_tree, hf_ipbcp_version, tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
838
839         offset = tvb_ws_mempbrk_pattern_guint8(tvb, offset, -1,&pbrk_alpha, NULL);
840
841         if (offset == -1)
842             return;
843
844         tokenlen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
845
846         if (tokenlen == -1)
847             return;
848
849         proto_tree_add_item(sdp_session_attribute_tree, hf_ipbcp_type, tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
850     } else if (strcmp((char*)field_name, "key-mgmt") == 0) {
851         tvbuff_t   *key_tvb;
852         proto_item *key_ti;
853
854         key_tvb = tvb_new_subset_remaining(tvb, offset);
855         key_ti = proto_tree_add_item(sdp_session_attribute_tree, hf_key_mgmt_att_value, key_tvb, 0, -1, ENC_UTF_8|ENC_NA);
856
857         dissect_key_mgmt(key_tvb, pinfo, key_ti);
858     } else {
859         proto_tree_add_item(sdp_session_attribute_tree, hf_session_attribute_value,
860                             tvb, offset, -1, ENC_UTF_8|ENC_NA);
861     }
862 }
863
864
865 /* Dissect media description - this is passed the line starting after 'm=', so like one of these:
866  *    audio 29156 RTP/AVP 18 0
867  *    video 49170/2 RTP/AVP 31 99
868  */
869 static void
870 dissect_sdp_media(tvbuff_t *tvb, proto_item *ti,
871                   transport_info_t *transport_info, disposable_media_info_t *media_info) {
872     proto_tree *sdp_media_tree;
873     gint        offset, next_offset, tokenlen, idx;
874     guint8     *media_format;
875     gboolean    optional = FALSE;
876     proto_item *it;
877
878     offset = 0;
879
880     /* Create tree for media session */
881     sdp_media_tree = proto_item_add_subtree(ti, ett_sdp_media);
882
883     tokenlen = find_next_token_in_line(tvb, sdp_media_tree, &offset, &next_offset);
884     if (tokenlen == 0)
885         return;
886
887     /* Type of media session */
888     proto_tree_add_item(sdp_media_tree, hf_media_media, tvb, offset, tokenlen,
889                         ENC_UTF_8|ENC_NA);
890
891     media_info->media_type[media_info->media_count] = (char*)tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
892
893     DPRINT(("parsed media_type=%s, for media_count=%d",
894             media_info->media_type[media_info->media_count],
895             media_info->media_count));
896
897     offset = next_offset + 1;
898
899     tokenlen = find_next_token_in_line(tvb, sdp_media_tree, &offset, &next_offset);
900     if (tokenlen == 0)
901         return;
902
903     next_offset = tvb_find_guint8(tvb, offset, tokenlen, '/');
904
905     if (next_offset != -1) {
906         tokenlen = next_offset - offset;
907         /* Save port info */
908         media_info->media_port[media_info->media_count] = (char*)tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
909
910         DPRINT(("parsed media_port=%s, for media_count=%d",
911                 media_info->media_port[media_info->media_count],
912                 media_info->media_count));
913
914         it = proto_tree_add_string(sdp_media_tree, hf_media_port_string, tvb, offset, tokenlen,
915                                    media_info->media_port[media_info->media_count]);
916         if (g_ascii_isdigit(media_info->media_port[media_info->media_count][0])) {
917             PROTO_ITEM_SET_HIDDEN(it);
918             proto_tree_add_uint(sdp_media_tree, hf_media_port, tvb, offset, tokenlen,
919                                 atoi(media_info->media_port[media_info->media_count]));
920         }
921
922         offset = next_offset + 1;
923         tokenlen = find_next_token_in_line(tvb, sdp_media_tree, &offset, &next_offset);
924         if (tokenlen == 0)
925             return;
926
927         /* TODO: this puts the (optional) number of ports in the tree, but we don't
928            actually use it for building the extra RTP flows, which we should. */
929         proto_tree_add_item(sdp_media_tree, hf_media_portcount, tvb, offset,
930                             tokenlen, ENC_UTF_8|ENC_NA);
931         offset = next_offset + 1;
932     } else {
933         tokenlen = find_next_token_in_line(tvb, sdp_media_tree, &offset, &next_offset);
934         if (tokenlen == 0)
935             return;
936
937         /* Save port info */
938         media_info->media_port[media_info->media_count] = (char*)tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
939         DPRINT(("parsed media_port=%s, for media_count=%d",
940                 media_info->media_port[media_info->media_count],
941                 media_info->media_count));
942         /* XXX Remember Port */
943         it = proto_tree_add_string(sdp_media_tree, hf_media_port_string, tvb, offset, tokenlen,
944                                    media_info->media_port[media_info->media_count]);
945         if (g_ascii_isdigit(media_info->media_port[media_info->media_count][0])) {
946             PROTO_ITEM_SET_HIDDEN(it);
947             proto_tree_add_uint(sdp_media_tree, hf_media_port, tvb, offset, tokenlen,
948                                 atoi(media_info->media_port[media_info->media_count]));
949         }
950         offset = next_offset + 1;
951     }
952
953     tokenlen = find_next_token_in_line(tvb, sdp_media_tree, &offset, &next_offset);
954     if (tokenlen == 0)
955         return;
956
957     /* Save port protocol */
958     media_info->media_proto[media_info->media_count] = (char*)tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
959
960     DPRINT(("parsed media_proto=%s, for media_count=%d",
961             media_info->media_proto[media_info->media_count],
962             media_info->media_count));
963
964     /* XXX Remember Protocol */
965     proto_tree_add_item(sdp_media_tree, hf_media_proto, tvb, offset, tokenlen,
966                         ENC_UTF_8|ENC_NA);
967
968     do {
969         offset = next_offset + 1;
970         tokenlen = find_next_optional_token_in_line(tvb, sdp_media_tree,
971                                                     &offset, &next_offset, optional);
972         if (tokenlen == 0)
973             break;
974
975         if (!strcmp(media_info->media_proto[media_info->media_count], "RTP/AVP")) {
976             media_format = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
977             if (g_ascii_isdigit(media_format[0])) {
978                 proto_tree_add_string(sdp_media_tree, hf_media_format, tvb, offset,
979                                       tokenlen, val_to_str_ext((guint32)strtoul((char*)media_format, NULL, 10), &rtp_payload_type_vals_ext, "%u"));
980                 idx = transport_info->media[transport_info->media_count].pt_count;
981                 transport_info->media[transport_info->media_count].pt[idx] = (gint32)strtol((char*)media_format, NULL, 10);
982                 DPRINT(("parsed media codec pt=%d, for media_count=%d",
983                         transport_info->media[transport_info->media_count].pt[idx],
984                         transport_info->media_count));
985                if (idx < (SDP_MAX_RTP_PAYLOAD_TYPES-1))
986                    transport_info->media[transport_info->media_count].pt_count++;
987             } else {
988                 proto_tree_add_item(sdp_media_tree, hf_media_format, tvb, offset,
989                                     tokenlen, ENC_UTF_8|ENC_NA);
990             }
991         } else {
992             proto_tree_add_item(sdp_media_tree, hf_media_format, tvb, offset,
993                                 tokenlen, ENC_UTF_8|ENC_NA);
994         }
995         optional = TRUE;
996     } while (next_offset != -1);
997
998     /* XXX Dissect traffic to "Port" as "Protocol"
999      *     Remember this Port/Protocol pair so we can tear it down again later
1000      *     Actually, it's harder than that:
1001      *         We need to find out the address of the other side first and it
1002      *         looks like that info can be found in SIP headers only.
1003      */
1004
1005 }
1006
1007 static tvbuff_t *
1008 ascii_bytes_to_tvb(tvbuff_t *tvb, packet_info *pinfo, gint len, gchar *msg)
1009 {
1010     guint8 *buf = (guint8 *)wmem_alloc(pinfo->pool, 10240);
1011
1012     /* arbitrary maximum length */
1013     if (len < 20480) {
1014         int i;
1015         tvbuff_t *bytes_tvb;
1016
1017         /* first, skip to where the encoded pdu starts, this is
1018            the first hex digit after the '=' char.
1019         */
1020         while (1) {
1021             if ((*msg == 0) || (*msg == '\n')) {
1022                 return NULL;
1023             }
1024             if (*msg == '=') {
1025                 msg++;
1026                 break;
1027             }
1028             msg++;
1029         }
1030         while (1) {
1031             if ((*msg == 0) || (*msg == '\n')) {
1032                 return NULL;
1033             }
1034             if ( ((*msg >= '0') && (*msg <= '9'))
1035                  || ((*msg >= 'a') && (*msg <= 'f'))
1036                  || ((*msg >= 'A') && (*msg <= 'F'))) {
1037                 break;
1038             }
1039             msg++;
1040         }
1041         i = 0;
1042         while (((*msg >= '0') && (*msg <= '9'))
1043                || ((*msg >= 'a') && (*msg <= 'f'))
1044                || ((*msg >= 'A') && (*msg <= 'F'))) {
1045             int val;
1046             if ((*msg >= '0') && (*msg <= '9')) {
1047                 val = (*msg)-'0';
1048             } else if ((*msg >= 'a') && (*msg <= 'f')) {
1049                 val = (*msg)-'a'+10;
1050             } else if ((*msg >= 'A') && (*msg <= 'F')) {
1051                 val = (*msg)-'A'+10;
1052             } else {
1053                 return NULL;
1054             }
1055             val <<= 4;
1056             msg++;
1057             if ((*msg >= '0') && (*msg <= '9')) {
1058                 val |= (*msg)-'0';
1059             } else if ((*msg >= 'a') && (*msg <= 'f')) {
1060                 val |= (*msg)-'a'+10;
1061             } else if ((*msg >= 'A') && (*msg <= 'F')) {
1062                 val |= (*msg)-'A'+10;
1063             } else {
1064                 return NULL;
1065             }
1066             msg++;
1067
1068             buf[i] = (guint8)val;
1069             i++;
1070         }
1071         if (i == 0) {
1072             return NULL;
1073         }
1074         bytes_tvb = tvb_new_child_real_data(tvb, buf, i, i);
1075         add_new_data_source(pinfo, bytes_tvb, "ASCII bytes to tvb");
1076         return bytes_tvb;
1077     }
1078     return NULL;
1079 }
1080
1081 /* Annex X Profiles and levels definition */
1082 static const value_string h263_profile_vals[] =
1083 {
1084     { 0,    "Baseline Profile" },
1085     { 1,    "H.320 Coding Efficiency Version 2 Backward-Compatibility Profile" },
1086     { 2,    "Version 1 Backward-Compatibility Profile" },
1087     { 3,    "Version 2 Interactive and Streaming Wireless Profile" },
1088     { 4,    "Version 3 Interactive and Streaming Wireless Profile" },
1089     { 5,    "Conversational High Compression Profile" },
1090     { 6,    "Conversational Internet Profile" },
1091     { 7,    "Conversational Interlace Profile" },
1092     { 8,    "High Latency Profile" },
1093     { 0, NULL },
1094 };
1095
1096
1097 /* RFC 4629 The level are described in table X.2 of H.263 annex X */
1098 static const value_string h263_level_vals[] =
1099 {
1100     { 10,    "QCIF (176 x 144), 1 x 64Kb/s" },
1101     { 20,    "CIF (352 x 288), 2 x 64Kb/s" },
1102     { 30,    "CIF (352 x 288), 6 x 64Kb/s" },
1103     { 40,    "CIF (352 x 288), 32 x 64Kb/s" },
1104     { 45,    "QCIF (176 x144) support of CPFMT, 2 x 64Kb/s" },
1105     { 50,    "CIF (352 x 288) support of CPFMT, 64 x 64Kb/s" },
1106     { 60,    "CPFMT: 720 x 288 support of CPFMT, 128 x 64Kb/s" },
1107     { 70,    "CPFMT: 720 x 576 support of CPFMT, 256 x 64Kb/s" },
1108     { 0, NULL },
1109 };
1110
1111
1112 static const value_string h264_packetization_mode_vals[] =
1113 {
1114     { 0,    "Single NAL mode" },
1115     { 1,    "Non-interleaved mode" },
1116     { 2,    "Interleaved mode" },
1117     { 0, NULL },
1118 };
1119
1120 /*
1121  * TODO: Make this a more generic routine to dissect fmtp parameters depending on media types
1122  */
1123 static void
1124 decode_sdp_fmtp(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, gint offset, gint tokenlen, char *mime_type) {
1125   gint                 next_offset;
1126   gint                 end_offset;
1127   guint8              *field_name;
1128   gchar               *format_specific_parameter;
1129   proto_item          *item;
1130   tvbuff_t * volatile  data_tvb;
1131
1132   end_offset = offset + tokenlen;
1133
1134 #if 0
1135     proto_tree_add_debug(tree, tvb, offset, tokenlen, "Debug; Analysed string: '%s'",
1136     tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_ASCII));
1137 #endif
1138
1139     /* Look for an '=' within this value - this may indicate that there is a
1140        profile-level-id parameter to find if the MPEG4 media type is in use */
1141     next_offset = tvb_find_guint8(tvb, offset, -1, '=');
1142     if (next_offset == -1)
1143     {
1144         /* Give up (and avoid exception) if '=' not found */
1145         return;
1146     }
1147
1148     /* Find the name of the parameter */
1149     tokenlen = next_offset - offset;
1150     field_name = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
1151 #if 0
1152     proto_tree_add_debug(tree, tvb, offset, tokenlen, "Debug; MIMEtype '%s'Parameter name: '%s'", mime_type, field_name); */
1153 #endif
1154     offset = next_offset;
1155
1156     /* Dissect the MPEG4 profile-level-id parameter if present */
1157     if ((mime_type != NULL) && (g_ascii_strcasecmp(mime_type, "MP4V-ES") == 0)) {
1158         if (strcmp((char*)field_name, "profile-level-id") == 0) {
1159             offset++;
1160             tokenlen = end_offset - offset;
1161             format_specific_parameter = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
1162             item = proto_tree_add_uint(tree, hf_sdp_fmtp_mpeg4_profile_level_id, tvb, offset, tokenlen,
1163                                        (guint32)strtol((char*)format_specific_parameter, NULL, 10));
1164             PROTO_ITEM_SET_GENERATED(item);
1165         } else if (strcmp((char*)field_name, "config") == 0) {
1166             /* String including "=" */
1167             tokenlen = end_offset - offset;
1168             format_specific_parameter = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
1169             /* ascii_bytes_to_tvb requires the "=" to be in the buffer */
1170             data_tvb = ascii_bytes_to_tvb(tvb, pinfo, tokenlen, format_specific_parameter);
1171             if (mp4ves_handle && data_tvb) {
1172                 dissect_mp4ves_config(data_tvb, pinfo, tree);
1173             }
1174         }
1175     }
1176
1177     /* Dissect the H263-2000 profile parameter if present */
1178     if (((mime_type != NULL) && (g_ascii_strcasecmp(mime_type, "H263-2000") == 0)) ||
1179         ((mime_type != NULL) && (g_ascii_strcasecmp(mime_type, "H263-1998") == 0))) {
1180         if (strcmp((char*)field_name, "profile") == 0) {
1181             offset++;
1182             tokenlen = end_offset - offset;
1183             format_specific_parameter = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
1184             item = proto_tree_add_uint(tree, hf_sdp_fmtp_h263_profile, tvb, offset, tokenlen,
1185                                        (guint32)strtol((char*)format_specific_parameter, NULL, 10));
1186             PROTO_ITEM_SET_GENERATED(item);
1187         } else if (strcmp((char*)field_name, "level") == 0) {
1188             offset++;
1189             tokenlen = end_offset - offset;
1190             format_specific_parameter = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
1191             item = proto_tree_add_uint(tree, hf_sdp_fmtp_h263_level, tvb, offset, tokenlen,
1192                                        (guint32)strtol((char*)format_specific_parameter, NULL, 10));
1193             PROTO_ITEM_SET_GENERATED(item);
1194         }
1195     }
1196
1197
1198     /* Dissect the H264 profile-level-id parameter
1199      * RFC 3984:
1200      * A base16 [6] (hexadecimal) representation of
1201      * the following three bytes in the sequence
1202      * parameter set NAL unit specified in [1]: 1)
1203      * profile_idc, 2) a byte herein referred to as
1204      * profile-iop, composed of the values of
1205      * constraint_set0_flag, constraint_set1_flag,
1206      * constraint_set2_flag, and reserved_zero_5bits
1207      * in bit-significance order, starting from the
1208      * most significant bit, and 3) level_idc.
1209      */
1210     if ((mime_type != NULL) && ((g_ascii_strcasecmp(mime_type, "H264") == 0) || (g_ascii_strcasecmp(mime_type, "H264-SVC") == 0))) {
1211         if (strcmp(field_name, "profile-level-id") == 0) {
1212             int length = 0;
1213
1214             /* Length includes "=" as it's required by ascii_bytes_to_tvb()*/
1215             tokenlen = end_offset - offset;
1216             format_specific_parameter = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
1217             data_tvb = ascii_bytes_to_tvb(tvb, pinfo, tokenlen, format_specific_parameter);
1218             if (!data_tvb) {
1219                 proto_tree_add_expert_format(tree, pinfo, &ei_sdp_invalid_conversion, tvb, offset, tokenlen, "Could not convert '%s' to 3 bytes", format_specific_parameter);
1220                 return;
1221             }
1222             length = tvb_reported_length(data_tvb);
1223             if (length == 3) {
1224                 if (h264_handle && data_tvb) {
1225                     dissect_h264_profile(data_tvb, pinfo, tree);
1226                 }
1227             } else {
1228                 item = proto_tree_add_expert_format(tree, pinfo, &ei_sdp_invalid_conversion, tvb, offset, tokenlen, "Incorrectly coded, must be three bytes");
1229                 PROTO_ITEM_SET_GENERATED(item);
1230             }
1231         } else if (strcmp(field_name, "packetization-mode") == 0) {
1232             offset++;
1233             tokenlen = end_offset - offset;
1234             format_specific_parameter = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
1235             item = proto_tree_add_uint(tree, hf_sdp_h264_packetization_mode, tvb, offset, tokenlen,
1236                                        (guint32)strtol((char*)format_specific_parameter, NULL, 10));
1237             PROTO_ITEM_SET_GENERATED(item);
1238         } else if (strcmp(field_name, "sprop-parameter-sets") == 0) {
1239             /* The value of the parameter is the
1240                base64 [6] representation of the initial
1241                parameter set NAL units as specified in
1242                sections 7.3.2.1 and 7.3.2.2 of [1].  The
1243                parameter sets are conveyed in decoding order,
1244                and no framing of the parameter set NAL units
1245                takes place.  A comma is used to separate any
1246                pair of parameter sets in the list.
1247             */
1248             gchar *data_p = NULL;
1249             gint   comma_offset;
1250
1251
1252             /* Move past '=' */
1253             offset++;
1254             comma_offset = tvb_find_guint8(tvb, offset, -1, ',');
1255             if (comma_offset != -1) {
1256                 tokenlen = comma_offset - offset;
1257             } else {
1258                 tokenlen = end_offset - offset;
1259             }
1260
1261             data_p = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
1262             proto_tree_add_string(tree, hf_sdp_nal_unit_1_string, tvb, offset, tokenlen, data_p);
1263
1264             data_tvb = base64_to_tvb(tvb, data_p);
1265             add_new_data_source(pinfo, data_tvb, "h264 prop-parameter-sets");
1266
1267             if (h264_handle && data_tvb) {
1268                 TRY {
1269                     dissect_h264_nal_unit(data_tvb, pinfo, tree);
1270                 }
1271                 CATCH_NONFATAL_ERRORS {
1272                     show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
1273                 }
1274                 ENDTRY;
1275                 if (comma_offset != -1) {
1276                     /* Second NAL unit */
1277                     offset   = comma_offset +1;
1278                     tokenlen = end_offset - offset;
1279                     data_p   = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
1280                     proto_tree_add_string(tree, hf_sdp_nal_unit_2_string, tvb, offset, tokenlen, data_p);
1281                     data_tvb = base64_to_tvb(tvb, data_p);
1282                     add_new_data_source(pinfo, data_tvb, "h264 prop-parameter-sets 2");
1283                     dissect_h264_nal_unit(data_tvb, pinfo, tree);
1284                 }
1285             }
1286         }
1287     }
1288
1289 }
1290
1291 typedef struct {
1292   const char *name;
1293 } sdp_names_t;
1294
1295 #define SDP_RTPMAP              1
1296 #define SDP_FMTP                2
1297 #define SDP_PATH                3
1298 #define SDP_H248_ITEM           4
1299 #define SDP_CRYPTO              5
1300 #define SDP_SPRTMAP             6
1301
1302 static const sdp_names_t sdp_media_attribute_names[] = {
1303     { "Unknown-name"},    /* 0 Pad so that the real headers start at index 1 */
1304     { "rtpmap"},          /* 1 */
1305     { "fmtp"},            /* 2 */
1306     { "path"},            /* 3 */
1307     { "h248item"},        /* 4 */
1308     { "crypto"},          /* 5 */
1309     { "sprt"},            /* 6 */
1310 };
1311
1312 static gint find_sdp_media_attribute_names(tvbuff_t *tvb, int offset, guint len)
1313 {
1314     guint i;
1315
1316     for (i = 1; i < array_length(sdp_media_attribute_names); i++) {
1317         if ((len == strlen(sdp_media_attribute_names[i].name)) &&
1318             (tvb_strncaseeql(tvb, offset, sdp_media_attribute_names[i].name, len) == 0))
1319             return i;
1320     }
1321
1322     return -1;
1323 }
1324
1325 static void dissect_sdp_media_attribute(tvbuff_t *tvb, packet_info *pinfo, proto_item * ti, int length,
1326                                         transport_info_t *transport_info, disposable_media_info_t *media_info) {
1327     proto_tree *sdp_media_attribute_tree, *parameter_item;
1328     proto_item *fmtp_item, *media_format_item, *parameter_tree;
1329     proto_tree *fmtp_tree;
1330     gint        offset, next_offset, tokenlen, n, colon_offset;
1331     /*??guint8 *field_name;*/
1332     guint8     *payload_type;
1333     guint8     *attribute_value;
1334     guint8      pt;
1335     gint        sdp_media_attrbute_code;
1336     const char *msrp_res           = "msrp://";
1337     const char *h324ext_h223lcparm = "h324ext/h223lcparm";
1338     gboolean    has_more_pars      = TRUE;
1339     tvbuff_t   *h245_tvb;
1340     guint8      master_key_length  = 0, master_salt_length = 0;
1341
1342     offset = 0;
1343
1344     /* Create attribute tree */
1345     sdp_media_attribute_tree = proto_item_add_subtree(ti,
1346                                                       ett_sdp_media_attribute);
1347     /* Find end of field */
1348     colon_offset = tvb_find_guint8(tvb, offset, -1, ':');
1349
1350     if (colon_offset == -1)
1351       return;
1352
1353     /* Attribute field name is token before ':' */
1354     tokenlen = colon_offset - offset;
1355     proto_tree_add_item(sdp_media_attribute_tree,
1356                         hf_media_attribute_field,
1357                         tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
1358     /*??field_name = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_ASCII);*/
1359     sdp_media_attrbute_code = find_sdp_media_attribute_names(tvb, offset, tokenlen);
1360
1361     /* Skip colon */
1362     offset = colon_offset + 1;
1363     /* skip leading wsp */
1364     offset = tvb_skip_wsp(tvb, offset, tvb_captured_length_remaining(tvb, offset));
1365
1366     /* Value is the remainder of the line */
1367     attribute_value = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_UTF_8|ENC_NA);
1368
1369
1370
1371     /*********************************************/
1372     /* Special parsing for some field name types */
1373
1374     switch (sdp_media_attrbute_code) {
1375         case SDP_RTPMAP:
1376             /* decode the rtpmap to see if it is DynamicPayload to dissect them automatic */
1377             next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
1378
1379             if (next_offset == -1)
1380                 return;
1381
1382             tokenlen = next_offset - offset;
1383
1384             proto_tree_add_item(sdp_media_attribute_tree, hf_media_format, tvb,
1385                                 offset, tokenlen, ENC_UTF_8|ENC_NA);
1386
1387             payload_type = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
1388
1389             offset = next_offset + 1;
1390
1391             next_offset = tvb_find_guint8(tvb, offset, -1, '/');
1392
1393             if (next_offset == -1) {
1394                 return;
1395             }
1396
1397             tokenlen = next_offset - offset;
1398
1399             proto_tree_add_item(sdp_media_attribute_tree, hf_media_encoding_name, tvb,
1400                                 offset, tokenlen, ENC_UTF_8|ENC_NA);
1401
1402             pt = atoi((char*)payload_type);
1403             if (pt >= SDP_NO_OF_PT) {
1404                 return;   /* Invalid */
1405             }
1406
1407             transport_info->encoding_name[pt] = (char*)tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
1408
1409             next_offset =  next_offset + 1;
1410             offset = next_offset;
1411             while (length-1 >= next_offset) {
1412                 if (!g_ascii_isdigit(tvb_get_guint8(tvb, next_offset)))
1413                     break;
1414                 next_offset++;
1415             }
1416             tokenlen = next_offset - offset;
1417             proto_tree_add_item(sdp_media_attribute_tree, hf_media_sample_rate, tvb,
1418                                 offset, tokenlen, ENC_UTF_8|ENC_NA);
1419             transport_info->sample_rate[pt] = atoi(tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA));
1420             /* As per RFC2327 it is possible to have multiple Media Descriptions ("m=").
1421                For example:
1422
1423                a=rtpmap:101 G726-32/8000
1424                m=audio 49170 RTP/AVP 0 97
1425                a=rtpmap:97 telephone-event/8000
1426                m=audio 49172 RTP/AVP 97 101
1427                a=rtpmap:97 G726-24/8000
1428
1429                The Media attributes ("a="s) after the "m=" only apply for that "m=".
1430                If there is an "a=" before the first "m=", that attribute applies for
1431                all the session (all the "m="s).
1432             */
1433
1434             /* so, if this "a=" appear before any "m=", we add it to all the dynamic
1435              * hash tables
1436              */
1437             if (transport_info->media_count < 0) {
1438                 for (n = 0; n < SDP_MAX_RTP_CHANNELS; n++) {
1439                     rtp_dyn_payload_insert(transport_info->media[n].rtp_dyn_payload,
1440                                            pt,
1441                                            transport_info->encoding_name[pt],
1442                                            transport_info->sample_rate[pt]);
1443                 }
1444                 return;
1445                 /* if the "a=" is after an "m=", only apply to this "m=" */
1446             }
1447
1448             rtp_dyn_payload_insert(transport_info->media[ transport_info->media_count ].rtp_dyn_payload,
1449                                   pt, transport_info->encoding_name[pt], transport_info->sample_rate[pt]);
1450             break;
1451         case SDP_FMTP:
1452             if (sdp_media_attribute_tree) {
1453                 guint8 media_format;
1454                 /* Reading the Format parameter(fmtp) */
1455                 /* Skip leading space, if any */
1456                 offset = tvb_skip_wsp(tvb, offset, tvb_captured_length_remaining(tvb, offset));
1457                 /* Media format extends to the next space */
1458                 next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
1459
1460                 if (next_offset == -1)
1461                     return;
1462
1463                 tokenlen = next_offset - offset;
1464
1465
1466                 media_format_item = proto_tree_add_item(sdp_media_attribute_tree,
1467                                                         hf_media_format, tvb, offset,
1468                                                         tokenlen, ENC_UTF_8|ENC_NA);
1469                 media_format = atoi((char*)tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA));
1470                 if (media_format >= SDP_NO_OF_PT) {
1471                     return;   /* Invalid */
1472                 }
1473
1474                 /* Append encoding name to format if known */
1475                 proto_item_append_text(media_format_item, " [%s]",
1476                                        transport_info->encoding_name[media_format]);
1477
1478 #if 0 /* XXX:  ?? */
1479                 payload_type = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_ASCII);
1480 #endif
1481                 /* Move offset past the payload type */
1482                 offset = next_offset + 1;
1483
1484                 while (has_more_pars == TRUE) {
1485                     next_offset = tvb_find_guint8(tvb, offset, -1, ';');
1486                     offset = tvb_skip_wsp(tvb, offset, tvb_captured_length_remaining(tvb, offset));
1487
1488                     if (next_offset == -1) {
1489                         has_more_pars = FALSE;
1490                         next_offset= tvb_captured_length(tvb);
1491                     }
1492
1493                     /* There are at least 2 - add the first parameter */
1494                     tokenlen = next_offset - offset;
1495                     fmtp_item = proto_tree_add_item(sdp_media_attribute_tree,
1496                                                     hf_media_format_specific_parameter, tvb,
1497                                                     offset, tokenlen, ENC_UTF_8|ENC_NA);
1498
1499                     fmtp_tree = proto_item_add_subtree(fmtp_item, ett_sdp_fmtp);
1500
1501                     decode_sdp_fmtp(fmtp_tree, tvb, pinfo, offset, tokenlen,
1502                                     transport_info->encoding_name[media_format]);
1503
1504                     /* Move offset past "; " and onto firts char */
1505                     offset = next_offset + 1;
1506                 }
1507             }
1508             break;
1509         case SDP_PATH:
1510             /* msrp attributes that contain address needed for conversation */
1511             /*    RFC 4975
1512              *    path = path-label ":" path-list
1513              *    path-label = "path"
1514              *    path-list= MSRP-URI *(SP MSRP-URI)
1515              *    MSRP-URI = msrp-scheme "://" authority
1516              *       ["/" session-id] ";" transport *( ";" URI-parameter)
1517              *                        ; authority as defined in RFC3986
1518              *
1519              *    msrp-scheme = "msrp" / "msrps"
1520              * RFC 3986
1521              * The authority component is preceded by a double slash ("//") and is terminated by
1522              * the next slash ("/"), question mark ("?"), or number sign ("#") character, or by
1523              * the end of the URI.
1524              */
1525
1526             /* Check for "msrp://" */
1527             if (strncmp((char*)attribute_value, msrp_res, strlen(msrp_res)) == 0) {
1528                 int address_offset, port_offset, port_end_offset;
1529
1530                 /* Address starts here */
1531                 address_offset = offset + (int)strlen(msrp_res);
1532
1533                 /* Port is after next ':' */
1534                 port_offset = tvb_find_guint8(tvb, address_offset, -1, ':');
1535                 /* Check if port is present if not skipp */
1536                 if (port_offset!= -1) {
1537                     /* Port ends with '/' */
1538                     port_end_offset = tvb_find_guint8(tvb, port_offset, -1, '/');
1539                     if (port_end_offset == -1) {
1540                         /* No "/" look for the ";" */
1541                         port_end_offset = tvb_find_guint8(tvb, port_offset, -1, ';');
1542                     }
1543                     /* Attempt to convert address */
1544                     if (str_to_ip((char*)tvb_get_string_enc(wmem_packet_scope(), tvb, address_offset, port_offset-address_offset, ENC_UTF_8|ENC_NA),
1545                                    &media_info->msrp_ipaddr)) {
1546                         /* Get port number */
1547                         media_info->msrp_port_number = atoi((char*)tvb_get_string_enc(wmem_packet_scope(), tvb, port_offset + 1, port_end_offset - port_offset - 1, ENC_UTF_8|ENC_NA));
1548                         /* Set flag so this info can be used */
1549                         media_info->msrp_transport_address_set = TRUE;
1550                     }
1551                 }
1552             }
1553             break;
1554         case SDP_H248_ITEM:
1555             /* Decode h248 item ITU-T Rec. H.248.12 (2001)/Amd.1 (11/2002)*/
1556             if (strncmp((char*)attribute_value, h324ext_h223lcparm, strlen(msrp_res)) == 0) {
1557                 /* A.5.1.3 H.223 Logical channel parameters
1558                  * This property indicates the H.245
1559                  * H223LogicalChannelsParameters structure encoded by applying the PER specified in
1560                  * ITU-T Rec. X.691. Value encoded as per A.5.1.2. For text encoding the mechanism defined
1561                  * in ITU-T Rec. H.248.15 is used.
1562                  */
1563                 gint len;
1564                 asn1_ctx_t actx;
1565
1566                 len = (gint)strlen(attribute_value);
1567                 h245_tvb = ascii_bytes_to_tvb(tvb, pinfo, len, attribute_value);
1568                 /* arbitrary maximum length */
1569                 /* should go through a handle, however,  the two h245 entry
1570                    points are different, one is over tpkt and the other is raw
1571                 */
1572                 if (h245_tvb) {
1573                     asn1_ctx_init(&actx, ASN1_ENC_PER, TRUE, pinfo);
1574                     dissect_h245_H223LogicalChannelParameters(h245_tvb, 0, &actx,
1575                                                               sdp_media_attribute_tree,
1576                                                               hf_SDPh223LogicalChannelParameters);
1577                 }
1578             }
1579             break;
1580         case SDP_CRYPTO:
1581             /* http://tools.ietf.org/html/rfc4568
1582             * 9.1.  Generic "Crypto" Attribute Grammar
1583             *
1584             *   The ABNF grammar for the crypto attribute is defined below:
1585             *
1586             *   "a=crypto:" tag 1*WSP crypto-suite 1*WSP key-params
1587             *                                           *(1*WSP session-param)
1588             *
1589             *   tag              = 1*9DIGIT
1590             *   crypto-suite     = 1*(ALPHA / DIGIT / "_")
1591             *
1592             *   key-params       = key-param *(";" key-param)
1593             *   key-param        = key-method ":" key-info
1594             *   key-method       = "inline" / key-method-ext
1595             *   key-method-ext   = 1*(ALPHA / DIGIT / "_")
1596             *   key-info         = 1*(%x21-3A / %x3C-7E) ; visible (printing) chars
1597             *                                        ; except semi-colon
1598             *  session-param    = 1*(VCHAR)         ; visible (printing) characters
1599             *
1600             *   where WSP, ALPHA, DIGIT, and VCHAR are defined in [RFC4234].
1601             *
1602             */
1603
1604             /* We are at the first colon */
1605             /* tag */
1606             tokenlen = find_next_token_in_line(tvb, sdp_media_attribute_tree, &offset, &next_offset);
1607             if (tokenlen == 0)
1608                 return;
1609             proto_tree_add_uint(sdp_media_attribute_tree, hf_sdp_crypto_tag, tvb, offset, tokenlen,
1610                 atoi((char*)tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA)));
1611             offset = next_offset + 1;
1612
1613             /* crypto-suite */
1614             tokenlen = find_next_token_in_line(tvb, sdp_media_attribute_tree, &offset, &next_offset);
1615             if (tokenlen == 0)
1616                 return;
1617             parameter_item = proto_tree_add_item(sdp_media_attribute_tree, hf_sdp_crypto_crypto_suite,
1618                 tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
1619             if (tvb_strncaseeql(tvb, offset, "AES_CM_128_HMAC_SHA1_80", tokenlen) == 0) {
1620
1621                 /* XXX This may only work in simple cases */
1622                 if (transport_info->encryption_algorithm == SRTP_ENC_ALG_NOT_SET) {
1623                     transport_info->encryption_algorithm = SRTP_ENC_ALG_AES_CM;
1624                     transport_info->auth_algorithm       = SRTP_AUTH_ALG_HMAC_SHA1;
1625                     /* number of octets used for the Auth Tag in the RTP payload */
1626                     transport_info->auth_tag_len         = 10;
1627                 }
1628                 master_key_length  = 16; /* 128 bits = 16 octets */
1629                 master_salt_length = 14; /* 112 bits = 14 octets */
1630             } else if (tvb_strncaseeql(tvb, offset, "AES_CM_128_HMAC_SHA1_32", tokenlen) == 0) {
1631                 /* XXX This may only work in simple cases */
1632                 if (transport_info->encryption_algorithm == SRTP_ENC_ALG_NOT_SET) {
1633                     transport_info->encryption_algorithm = SRTP_ENC_ALG_AES_CM;
1634                     transport_info->auth_algorithm       = SRTP_AUTH_ALG_HMAC_SHA1;
1635                     /* number of octets used for the Auth Tag in the RTP payload */
1636                     transport_info->auth_tag_len         = 4;
1637                 }
1638                 master_key_length  = 16; /* 128 bits = 16 octets */
1639                 master_salt_length = 14; /* 112 bits = 14 octets */
1640             } else if (tvb_strncaseeql(tvb, offset, "F8_128_HMAC_SHA1_80", tokenlen) == 0) {
1641                 if (transport_info->encryption_algorithm == SRTP_ENC_ALG_NOT_SET) {
1642                     /* XXX This may only work in simple cases */
1643                     transport_info->encryption_algorithm = SRTP_ENC_ALG_AES_F8;
1644                     transport_info->auth_algorithm       = SRTP_AUTH_ALG_HMAC_SHA1;
1645                     /* number of octets used for the Auth Tag in the RTP payload */
1646                     transport_info->auth_tag_len         = 10;
1647                 }
1648                 master_key_length  = 16; /* 128 bits = 16 octets */
1649                 master_salt_length = 14; /* 112 bits = 14 octets */
1650             }
1651             offset = next_offset + 1;
1652
1653             /* key-params */
1654             while (has_more_pars == TRUE) {
1655                 int       param_end_offset;
1656                 tvbuff_t *key_salt_tvb;
1657                 gchar    *data_p = NULL;
1658
1659                 param_end_offset = tvb_find_guint8(tvb, offset, -1, ';');
1660                 if (param_end_offset == -1) {
1661                     has_more_pars = FALSE;
1662                     param_end_offset = tvb_captured_length(tvb);
1663                 }
1664                 /* key-method or key-method-ext */
1665                 next_offset = tvb_find_guint8(tvb, offset, -1, ':');
1666                 if (next_offset == -1) {
1667                     expert_add_info(pinfo, parameter_item, &ei_sdp_invalid_key_param);
1668                     break;
1669                 }
1670
1671                 if (tvb_strncaseeql(tvb, offset, "inline", next_offset-offset) == 0) {
1672                     parameter_tree = proto_tree_add_subtree(sdp_media_attribute_tree, tvb, offset,
1673                         param_end_offset-offset, ett_sdp_crypto_key_parameters, NULL, "Key parameters");
1674                     /* XXX only for SRTP? */
1675                     /* srtp-key-info       = key-salt ["|" lifetime] ["|" mki] */
1676                     offset      = next_offset +1;
1677                     next_offset = tvb_find_guint8(tvb, offset, -1, '|');
1678                     if (next_offset == -1) {
1679                         tokenlen = param_end_offset - offset;
1680                     } else {
1681                         tokenlen = next_offset - offset;
1682                     }
1683                     data_p = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
1684                     key_salt_tvb = base64_to_tvb(tvb, data_p);
1685                     add_new_data_source(pinfo, key_salt_tvb, "Key_Salt_tvb");
1686                     if (master_key_length != 0) {
1687                         proto_tree_add_item(parameter_tree, hf_sdp_key_and_salt, tvb, offset, tokenlen, ENC_NA);
1688                         proto_tree_add_item(parameter_tree, hf_sdp_crypto_master_key,
1689                             key_salt_tvb, 0, master_key_length, ENC_NA);
1690                         proto_tree_add_item(parameter_tree, hf_sdp_crypto_master_salt,
1691                             key_salt_tvb, master_key_length, master_salt_length, ENC_NA);
1692                     } else {
1693                         proto_tree_add_item(parameter_tree, hf_sdp_key_and_salt, key_salt_tvb, 0, -1, ENC_NA);
1694                     }
1695
1696                     /*  ["|" lifetime] ["|" mki] are optional */
1697                     if (next_offset != -1) {
1698                         offset = next_offset + 1;
1699                         next_offset = tvb_find_guint8(tvb, offset, -1, '|');
1700                         if (next_offset == -1) {
1701                             if (next_offset < param_end_offset){
1702                                 next_offset = param_end_offset;
1703                             }
1704                         }
1705                         if (next_offset != -1) {
1706                             /*lifetime           = ["2^"] 1*(DIGIT)   ; see section 6.1 for "2^" */
1707                             tokenlen = next_offset - offset;
1708                             proto_tree_add_item(parameter_tree, hf_sdp_crypto_lifetime,
1709                                 tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
1710                             offset   = next_offset + 1;
1711                         }
1712                         /* mki                 = mki-value ":" mki-length
1713                         *
1714                         * mki-value           = 1*DIGIT
1715                         */
1716                         if (offset>param_end_offset) {
1717                             next_offset = -1;
1718                         } else {
1719                             next_offset = tvb_find_guint8(tvb, offset, -1, ':');
1720                         }
1721                         if (next_offset != -1) {
1722                             tokenlen    = next_offset - offset;
1723                             proto_tree_add_item(parameter_tree, hf_sdp_crypto_mki, tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
1724                             offset      = next_offset + 1;
1725
1726                             /* mki-length          = 1*3DIGIT   ; range 1..128. */
1727                             next_offset = param_end_offset;
1728                             tokenlen    = next_offset - offset;
1729
1730                             /* This will not work if more than one parameter */
1731                             /* number of octets used for the MKI in the RTP payload */
1732                             transport_info->mki_len = atoi((char*)tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_UTF_8|ENC_NA));
1733                             proto_tree_add_item(parameter_tree, hf_sdp_crypto_mki_length,
1734                                 tvb, offset, tokenlen, ENC_UTF_8|ENC_NA);
1735                         }
1736                     }
1737                     offset = param_end_offset;
1738                 } else {
1739                     break;
1740                 }
1741             }
1742
1743           break;
1744         default:
1745             /* No special treatment for values of this attribute type, just add as one item. */
1746             proto_tree_add_item(sdp_media_attribute_tree, hf_media_attribute_value,
1747                                 tvb, offset, -1, ENC_UTF_8|ENC_NA);
1748             break;
1749     }
1750 }
1751
1752 static void
1753 call_sdp_subdissector(tvbuff_t *tvb, packet_info *pinfo, int hf, proto_tree* ti, int length,
1754                       transport_info_t *transport_info, disposable_media_info_t *media_info) {
1755     if (hf == hf_owner) {
1756         dissect_sdp_owner(tvb, ti);
1757     } else if (hf == hf_connection_info) {
1758         dissect_sdp_connection_info(tvb, ti, media_info);
1759     } else if (hf == hf_bandwidth) {
1760         dissect_sdp_bandwidth(tvb, ti);
1761     } else if (hf == hf_time) {
1762         dissect_sdp_time(tvb, ti);
1763     } else if (hf == hf_repeat_time) {
1764         dissect_sdp_repeat_time(tvb, ti);
1765     } else if (hf == hf_timezone) {
1766         dissect_sdp_timezone(tvb, ti);
1767     } else if (hf == hf_encryption_key) {
1768         dissect_sdp_encryption_key(tvb, ti);
1769     } else if (hf == hf_session_attribute) {
1770         dissect_sdp_session_attribute(tvb, pinfo, ti);
1771     } else if (hf == hf_media) {
1772         dissect_sdp_media(tvb, ti, transport_info, media_info);
1773     } else if (hf == hf_media_attribute) {
1774         dissect_sdp_media_attribute(tvb, pinfo, ti, length, transport_info, media_info);
1775     }
1776 }
1777
1778 static void
1779 convert_disposable_media(transport_info_t* transport_info, disposable_media_info_t* media_info,
1780                          gint start_transport_info_count)
1781 {
1782     gint8 n, transport_index;
1783     guint proto_bitmask;
1784
1785     for (n = 0; (n < media_info->media_count) && (n+start_transport_info_count < SDP_MAX_RTP_CHANNELS); n++)
1786     {
1787         transport_index = n+start_transport_info_count;
1788         if (media_info->media_port[n] != NULL) {
1789             transport_info->media_port[transport_index] = (int)strtol(media_info->media_port[n], NULL, 10);
1790             DPRINT(("set transport_info media port number=%d, for transport_index=%d",
1791                     transport_info->media_port[transport_index], transport_index));
1792         }
1793
1794         if (media_info->media_proto[n] != NULL) {
1795             /* Check if media protocol is RTP
1796              * and stream decoding is enabled in preferences
1797              */
1798             if (global_sdp_establish_conversation) {
1799                 proto_bitmask = 0;
1800
1801                 /* Check if media protocol is RTP */
1802                 /* XXX: what about 'RTP/AVPF' or RTP/SAVPF'? */
1803                 if (!strcmp(media_info->media_proto[n],"RTP/AVP")) {
1804                     transport_info->proto_bitmask[transport_index] |= SDP_RTP_PROTO;
1805                     proto_bitmask |= SDP_RTP_PROTO;
1806                     DPRINT(("set SDP_RTP_PROTO bitmask=%x, for transport_index=%d",
1807                             transport_info->proto_bitmask[transport_index], transport_index));
1808                 }
1809                 /* Check if media protocol is SRTP */
1810                 else if (!strcmp(media_info->media_proto[n],"RTP/SAVP")) {
1811                     transport_info->proto_bitmask[transport_index] |= SDP_SRTP_PROTO;
1812                     proto_bitmask |= SDP_SRTP_PROTO;
1813                     DPRINT(("set SDP_SRTP_PROTO bitmask=%x, for transport_index=%d",
1814                             transport_info->proto_bitmask[transport_index], transport_index));
1815                 }
1816                 /* Check if media protocol is T38 */
1817                 else if ((!strcmp(media_info->media_proto[n],"UDPTL")) ||
1818                     (!strcmp(media_info->media_proto[n],"udptl"))) {
1819                     transport_info->proto_bitmask[transport_index] |= SDP_T38_PROTO;
1820                     proto_bitmask |= SDP_T38_PROTO;
1821                     DPRINT(("set SDP_T38_PROTO bitmask=%x, for transport_index=%d",
1822                             transport_info->proto_bitmask[transport_index], transport_index));
1823                 }
1824                 /* Check if media protocol is MSRP/TCP */
1825                 else if (!strcmp(media_info->media_proto[n],"msrp/tcp")) {
1826                     transport_info->proto_bitmask[transport_index] |= SDP_MSRP_PROTO;
1827                     proto_bitmask |= SDP_MSRP_PROTO;
1828                     DPRINT(("set SDP_MSRP_PROTO bitmask=%x, for transport_index=%d",
1829                             transport_info->proto_bitmask[transport_index], transport_index));
1830                 }
1831                 /* Check if media protocol is SPRT */
1832                 else if ((!strcmp(media_info->media_proto[n],"UDPSPRT")) ||
1833                     (!strcmp(media_info->media_proto[n],"udpsprt"))) {
1834                     transport_info->proto_bitmask[transport_index] |= SDP_SPRT_PROTO;
1835                     proto_bitmask |= SDP_SPRT_PROTO;
1836                     DPRINT(("set SDP_SPRT_PROTO bitmask=%x, for transport_index=%d",
1837                             transport_info->proto_bitmask[transport_index], transport_index));
1838                 }
1839
1840                 /* now check if this stream's port==0, in which case we need to disable its paired stream */
1841                 if (transport_info->media_port[transport_index] == 0) {
1842                     /* This should disable the matching media session in the offer - it's a bit of a hack though,
1843                        basically start_transport_info_count is 0 for the offer, and >0 for the answer, so we
1844                        check that and if this is the answer, then we go set the offer's paired stream to 0.
1845                        If it turns out we got a port=0 in the offer, we don't care and it's ok to let the
1846                        answer have a non-port=0 (though that would be illegal per the RFCs). */
1847                     if (start_transport_info_count > 0 && (proto_bitmask & transport_info->proto_bitmask[n])) {
1848                         transport_info->media_port[n] = 0;
1849                         DPRINT(("disabled media_port=%d, for transport_index=%d",
1850                                 n, transport_index));
1851                     }
1852                 }
1853             }
1854         }
1855
1856         if ((media_info->connection_address != NULL) &&
1857             (media_info->connection_type != NULL)) {
1858             if (strcmp(media_info->connection_type, "IP4") == 0) {
1859                 transport_info->src_addr[transport_index].data = wmem_alloc(wmem_file_scope(), 4);
1860                 if (str_to_ip(media_info->connection_address, (void*)transport_info->src_addr[transport_index].data)) {
1861                     /* connection_address could be converted to a valid ipv4 address*/
1862                     transport_info->proto_bitmask[transport_index] |= SDP_IPv4;
1863                     transport_info->src_addr[transport_index].type = AT_IPv4;
1864                     transport_info->src_addr[transport_index].len  = 4;
1865                     DPRINT(("set SDP_IPv4 bitmask=%x, for transport_index=%d",
1866                             transport_info->proto_bitmask[transport_index], transport_index));
1867                 }
1868             } else if (strcmp(media_info->connection_type, "IP6") == 0) {
1869                 transport_info->src_addr[transport_index].data = wmem_alloc(wmem_file_scope(), 16);
1870                 if (str_to_ip6(media_info->connection_address, (void*)transport_info->src_addr[transport_index].data)) {
1871                     /* connection_address could be converted to a valid ipv6 address*/
1872                     transport_info->proto_bitmask[transport_index] |= SDP_IPv6;
1873                     transport_info->src_addr[transport_index].type = AT_IPv6;
1874                     transport_info->src_addr[transport_index].len  = 16;
1875                     DPRINT(("set SDP_IPv6 bitmask=%x, for transport_index=%d",
1876                             transport_info->proto_bitmask[transport_index], transport_index));
1877                 }
1878             }
1879         }
1880
1881         /* MSRP uses addresses discovered in attribute
1882            rather than connection information of media session line */
1883         if ((transport_info->proto_bitmask[transport_index] & SDP_MSRP_PROTO) &&
1884             (transport_info->proto_bitmask[transport_index] & SDP_MSRP_IPv4) &&
1885               msrp_handle) {
1886             transport_info->src_addr[transport_index].type = AT_IPv4;
1887             transport_info->src_addr[transport_index].len  = 4;
1888             transport_info->src_addr[transport_index].data = wmem_memdup(wmem_file_scope(), media_info->msrp_ipaddr, 4);
1889             transport_info->media_port[transport_index] = media_info->msrp_port_number;
1890         }
1891
1892         if ((media_info->media_type[transport_index] != NULL) &&
1893             (strcmp(media_info->media_type[transport_index], "video") == 0)) {
1894             transport_info->proto_bitmask[transport_index] |= SDP_VIDEO;
1895             DPRINT(("set SDP_VIDEO bitmask=%x, for transport_index=%d",
1896                     transport_info->proto_bitmask[transport_index], transport_index));
1897         }
1898     }
1899 }
1900
1901 void
1902 setup_sdp_transport(tvbuff_t *tvb, packet_info *pinfo, enum sdp_exchange_type exchange_type,
1903     int request_frame, const gboolean delay)
1904 {
1905     gint        offset = 0, next_offset, n;
1906     int         linelen;
1907     gboolean    in_media_description = FALSE;
1908     guchar      type, delim;
1909     const int   tokenoffset = 2;
1910     int         hf     = -1;
1911     gint        start_transport_info_count = 0;
1912     transport_info_t* transport_info = NULL;
1913     disposable_media_info_t media_info;
1914
1915     struct srtp_info *srtp_info = NULL;
1916
1917     DPRINT2(("-------------------- setup_sdp_transport -------------------"));
1918
1919     /* Only do this once during first pass */
1920     if (pinfo->fd->flags.visited) {
1921         DPRINT(("already visited"));
1922         return;
1923     }
1924
1925     memset(&media_info, 0, sizeof(media_info));
1926
1927     if (request_frame != 0)
1928         transport_info = (transport_info_t*)wmem_tree_lookup32( sdp_transport_reqs, request_frame );
1929     if (transport_info == NULL) {
1930         transport_info = wmem_new0(wmem_file_scope(), transport_info_t);
1931         transport_info->media_count = -1;
1932
1933         for (n = 0; n < SDP_NO_OF_PT; n++) {
1934             transport_info->encoding_name[n] = (char*)UNKNOWN_ENCODING;
1935         }
1936         for (n = 0; n < SDP_MAX_RTP_CHANNELS; n++) {
1937             transport_info->media[n].rtp_dyn_payload = rtp_dyn_payload_new();
1938             transport_info->media[n].set_rtp = FALSE;
1939         }
1940
1941         if (request_frame != 0)
1942             wmem_tree_insert32(sdp_transport_reqs, request_frame, (void *)transport_info);
1943     }
1944 #ifdef DEBUG_CONVERSATION
1945     else {
1946         DPRINT(("found previous transport_info:"));
1947         sdp_dump_transport_info(transport_info);
1948     }
1949 #endif
1950
1951     if (exchange_type != SDP_EXCHANGE_OFFER)
1952         wmem_tree_insert32(sdp_transport_rsps, pinfo->fd->num, (void *)transport_info);
1953
1954     /* Offer has already been answered or rejected and hash tables freed, so
1955      * don't try to add to it
1956      * XXX - Need to support "modified offers" */
1957     if ((transport_info->sdp_status == SDP_EXCHANGE_ANSWER_REJECT) ||
1958         (transport_info->sdp_status == SDP_EXCHANGE_ANSWER_ACCEPT))
1959         return;
1960
1961     if (transport_info->media_count > 0)
1962         start_transport_info_count = transport_info->media_count;
1963
1964     DPRINT(("start_transport_info_count=%d", start_transport_info_count));
1965
1966     /* if we don't delay, and this is an answer after a previous offer, then
1967        we free'd the unused media rtp_dyn_payload last time while processing
1968        the offer, so we need to re-create them this time in case we need them.
1969        If they don't get used they'll get free'd again later */
1970     if (!delay && (exchange_type == SDP_EXCHANGE_ANSWER_ACCEPT) &&
1971         (transport_info->sdp_status == SDP_EXCHANGE_OFFER)) {
1972         for (n = start_transport_info_count; n < SDP_MAX_RTP_CHANNELS; n++) {
1973             if (!transport_info->media[n].rtp_dyn_payload)
1974                 transport_info->media[n].rtp_dyn_payload = rtp_dyn_payload_new();
1975         }
1976     }
1977
1978     /*
1979      * Show the SDP message a line at a time.
1980      */
1981     while (tvb_offset_exists(tvb, offset)) {
1982         /*
1983          * Find the end of the line.
1984          */
1985         linelen = tvb_find_line_end_unquoted(tvb, offset, -1, &next_offset);
1986
1987         /*
1988          * Line must contain at least e.g. "v=".
1989          */
1990         if (linelen < 2)
1991             break;
1992
1993         type  = tvb_get_guint8(tvb, offset);
1994         delim = tvb_get_guint8(tvb, offset + 1);
1995         if (delim != '=') {
1996             offset = next_offset;
1997             continue;
1998         }
1999
2000         /*
2001          * Attributes.  Only care about ones that affect the transport.  Ignore others.
2002          */
2003         switch (type) {
2004             case 'c':
2005                 hf = hf_connection_info;
2006                 break;
2007             case 'm':
2008                 hf = hf_media;
2009
2010                 /* Increase the count of media channels, but don't walk off the end of the arrays. */
2011                 if (((transport_info->media_count < 0) && (in_media_description == FALSE)) || (transport_info->media_count < (SDP_MAX_RTP_CHANNELS-1)))
2012                     transport_info->media_count++;
2013
2014                 if (in_media_description && (media_info.media_count < (SDP_MAX_RTP_CHANNELS-1)))
2015                     media_info.media_count++;
2016
2017                 in_media_description = TRUE;
2018                 DPRINT(("in media description, transport_info->media_count=%d, "
2019                         "media_info.media_count=%d",
2020                         transport_info->media_count, media_info.media_count));
2021                 break;
2022             case 'a':
2023                 if (in_media_description) {
2024                     hf = hf_media_attribute;
2025                 } else {
2026                     hf = hf_session_attribute;
2027                 }
2028                 break;
2029             default:
2030                 hf = hf_unknown;
2031                 break;
2032         }
2033
2034         if (hf != hf_unknown)
2035         {
2036             DINDENT();
2037             call_sdp_subdissector(tvb_new_subset_length(tvb, offset + tokenoffset,
2038                                                    linelen - tokenoffset),
2039                                     pinfo,
2040                                     hf, NULL, linelen-tokenoffset, transport_info, &media_info);
2041             DENDENT();
2042         }
2043
2044         offset = next_offset;
2045     }
2046
2047     if (in_media_description) {
2048         /* Increase the count of media channels, but don't walk off the end of the arrays. */
2049         /* XXX: I don't know why this was done here - I'm keeping it here in case
2050          * removing it causes problems, but it's wrong. transport_info->media_count
2051          * is already incremented in the while() loop above. Incrementing it
2052          * again here will cause bugs. The name of this is misleading, because
2053          * 'transport_info->media_count' is actually an index, not count.
2054          * In other words, it's a 0-based number, of the current rtp channel.
2055          * So debug printing shows bogus rtp channels get created and then later
2056          * removed because luckily it knows they were bogus. But it will cause bugs
2057          * because if we're not delaying, then for the SDP_EXCHANGE_ANSWER_ACCEPT
2058          * run through this function, it will add new RTP channels at a +1 index,
2059          * which will likely cause problems.
2060          */
2061         if (transport_info->media_count < (SDP_MAX_RTP_CHANNELS-1))
2062             transport_info->media_count++;
2063         if (media_info.media_count < (SDP_MAX_RTP_CHANNELS-1))
2064             media_info.media_count++;
2065     }
2066
2067 #ifdef DEBUG_CONVERSATION
2068     sdp_dump_disposable_media_info(&media_info);
2069 #endif
2070
2071     DPRINT(("calling convert_disposable_media(), transport_info->media_count=%d, "
2072             "media_info.media_count=%d, start_transport_info_count=%d",
2073             transport_info->media_count, media_info.media_count, start_transport_info_count));
2074     DINDENT();
2075     /* Take all of the collected strings and convert them into something permanent
2076      * for the life of the capture
2077      */
2078     convert_disposable_media(transport_info, &media_info, start_transport_info_count);
2079     DENDENT();
2080
2081 #ifdef DEBUG_CONVERSATION
2082     sdp_dump_transport_info(transport_info);
2083 #endif
2084
2085     /* We have a successful negotiation, apply data to their respective protocols */
2086     if (!delay || ((exchange_type == SDP_EXCHANGE_ANSWER_ACCEPT) &&
2087         (transport_info->sdp_status == SDP_EXCHANGE_OFFER))) {
2088
2089         for (n = 0; n <= transport_info->media_count; n++) {
2090           guint32 current_rtp_port = 0;
2091
2092             /* Add (s)rtp and (s)rtcp conversation, if available (overrides t38 if conversation already set) */
2093             if ((transport_info->media_port[n] != 0) &&
2094                 (transport_info->proto_bitmask[n] & (SDP_RTP_PROTO|SDP_SRTP_PROTO)) &&
2095                 (transport_info->proto_bitmask[n] & (SDP_IPv4|SDP_IPv6))) {
2096
2097                 if (transport_info->proto_bitmask[n] & SDP_SRTP_PROTO) {
2098                     srtp_info = wmem_new0(wmem_file_scope(), struct srtp_info);
2099                     if (transport_info->encryption_algorithm != SRTP_ENC_ALG_NOT_SET) {
2100                         srtp_info->encryption_algorithm = transport_info->encryption_algorithm;
2101                         srtp_info->auth_algorithm       = transport_info->auth_algorithm;
2102                         srtp_info->mki_len              = transport_info->mki_len;
2103                         srtp_info->auth_tag_len         = transport_info->auth_tag_len;
2104
2105                     }
2106                     DPRINT(("calling srtp_add_address, channel=%d, media_port=%d",
2107                             n, transport_info->media_port[n]));
2108                     DINDENT();
2109                     /* srtp_add_address and rtp_add_address are given the request_frame's not this frame's number,
2110                        because that's where the RTP flow started, and thus conversation needs to check against */
2111                     srtp_add_address(pinfo, &transport_info->src_addr[n], transport_info->media_port[n], 0, "SDP", request_frame,
2112                                     (transport_info->proto_bitmask[n] & SDP_VIDEO) ? TRUE : FALSE,
2113                                      transport_info->media[n].rtp_dyn_payload, srtp_info);
2114                     DENDENT();
2115                 } else {
2116                     DPRINT(("calling rtp_add_address, channel=%d, media_port=%d",
2117                             n, transport_info->media_port[n]));
2118                     DINDENT();
2119                     rtp_add_address(pinfo, &transport_info->src_addr[n], transport_info->media_port[n], 0, "SDP", request_frame,
2120                                     (transport_info->proto_bitmask[n] & SDP_VIDEO) ? TRUE : FALSE,
2121                                     transport_info->media[n].rtp_dyn_payload);
2122                     DENDENT();
2123                  }
2124                 transport_info->media[n].set_rtp = TRUE;
2125                 /* SPRT might use the same port... */
2126                 current_rtp_port = transport_info->media_port[n];
2127
2128                 if (rtcp_handle) {
2129                     if (transport_info->proto_bitmask[n] & SDP_SRTP_PROTO) {
2130                         DPRINT(("calling rtcp_add_address, channel=%d, media_port=%d",
2131                                 n, transport_info->media_port[n]+1));
2132                         DINDENT();
2133                         srtcp_add_address(pinfo, &transport_info->src_addr[n], transport_info->media_port[n]+1, 0, "SDP", request_frame, srtp_info);
2134                         DENDENT();
2135                      } else {
2136                         DPRINT(("calling rtcp_add_address, channel=%d, media_port=%d",
2137                                 n, transport_info->media_port[n]+1));
2138                         DINDENT();
2139                         rtcp_add_address(pinfo, &transport_info->src_addr[n], transport_info->media_port[n]+1, 0, "SDP", request_frame);
2140                         DENDENT();
2141                      }
2142                 }
2143             }
2144
2145             /* add SPRT conversation */
2146             if ((transport_info->proto_bitmask[n] & SDP_SPRT_PROTO) &&
2147                 (transport_info->proto_bitmask[n] & (SDP_IPv4|SDP_IPv6)) &&
2148                 (sprt_handle)) {
2149
2150                 if (transport_info->media_port[n] == 0 && current_rtp_port) {
2151                     sprt_add_address(pinfo, &transport_info->src_addr[n], current_rtp_port,
2152                                      0, "SDP", pinfo->fd->num); /* will use same port as RTP */
2153                 } else {
2154                     sprt_add_address(pinfo, &transport_info->src_addr[n], transport_info->media_port[n], 0, "SDP", pinfo->fd->num);
2155                 }
2156             }
2157
2158             /* Add t38 conversation, if available and only if no rtp */
2159             if ((transport_info->media_port[n] != 0) &&
2160                 !transport_info->media[n].set_rtp &&
2161                 (transport_info->proto_bitmask[n] & SDP_T38_PROTO) &&
2162                 (transport_info->proto_bitmask[n] & SDP_IPv4)) {
2163                 t38_add_address(pinfo, &transport_info->src_addr[n], transport_info->media_port[n], 0, "SDP", pinfo->fd->num);
2164             }
2165
2166             /* Add MSRP conversation.  Uses addresses discovered in attribute
2167                rather than connection information of media session line
2168                (already handled in media conversion) */
2169             if ((transport_info->proto_bitmask[n] & SDP_MSRP_PROTO) &&
2170                 (transport_info->proto_bitmask[n] & SDP_MSRP_IPv4) &&
2171                 msrp_handle) {
2172                 msrp_add_address(pinfo, &transport_info->src_addr[n], transport_info->media_port[n], "SDP", pinfo->fd->num);
2173             }
2174
2175             /* Free the hash table if we did't assigned it to a conv use it */
2176             if (!transport_info->media[n].set_rtp)
2177             {
2178                 DPRINT(("set_rtp is not set, calling rtp_dyn_payload_free, "
2179                         "channel=%d, media_port=%d",
2180                         n, transport_info->media_port[n]));
2181                 rtp_dyn_payload_free(transport_info->media[n].rtp_dyn_payload);
2182                 transport_info->media[n].rtp_dyn_payload = NULL;
2183             }
2184
2185         } /* end for (n = 0; n <= transport_info->media_count; n++) */
2186
2187         /* Free the remaining hash tables not used */
2188         if (transport_info->media_count == -1)
2189         {
2190             for (n = 0; n < SDP_MAX_RTP_CHANNELS; n++)
2191             {
2192                 if (!transport_info->media[n].set_rtp)
2193                 {
2194                     DPRINT(("media_count == -1, calling rtp_dyn_payload_free, "
2195                             "channel=%d, media_port=%d",
2196                             n, transport_info->media_port[n]));
2197                     rtp_dyn_payload_free(transport_info->media[n].rtp_dyn_payload);
2198                     transport_info->media[n].rtp_dyn_payload = NULL;
2199                 }
2200             }
2201         }
2202         else
2203         {
2204             for (n = transport_info->media_count; n < SDP_MAX_RTP_CHANNELS; n++)
2205             {
2206                 if (!transport_info->media[n].set_rtp)
2207                 {
2208                     DPRINT(("media_count != -1, calling rtp_dyn_payload_free, "
2209                             "channel=%d, media_port=%d",
2210                             n, transport_info->media_port[n]));
2211                     rtp_dyn_payload_free(transport_info->media[n].rtp_dyn_payload);
2212                     transport_info->media[n].rtp_dyn_payload = NULL;
2213                 }
2214             }
2215         }
2216         transport_info->sdp_status = exchange_type;
2217
2218     } else if ((exchange_type == SDP_EXCHANGE_ANSWER_REJECT) &&
2219                (transport_info->sdp_status != SDP_EXCHANGE_ANSWER_REJECT)) {
2220
2221         /* Free the hash tables, since they won't be put to use */
2222         for (n = 0; n < SDP_MAX_RTP_CHANNELS; n++)
2223         {
2224             if (!transport_info->media[n].set_rtp)
2225             {
2226                 rtp_dyn_payload_free(transport_info->media[n].rtp_dyn_payload);
2227                 transport_info->media[n].rtp_dyn_payload = NULL;
2228             }
2229         }
2230
2231         transport_info->sdp_status = SDP_EXCHANGE_ANSWER_REJECT;
2232     }
2233 }
2234
2235 void setup_sdp_transport_resend(int current_frame, int request_frame)
2236 {
2237     transport_info_t* transport_info = NULL;
2238
2239     if (request_frame != 0) {
2240         transport_info = (transport_info_t*)wmem_tree_lookup32( sdp_transport_reqs, request_frame );
2241         if (transport_info != NULL) {
2242             wmem_tree_insert32(sdp_transport_reqs, current_frame, (void *)transport_info);
2243         }
2244     }
2245 }
2246
2247 static void
2248 dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2249 {
2250     proto_tree *sdp_tree;
2251     proto_item *ti, *sub_ti;
2252     gint        offset = 0, next_offset, n, i;
2253     int         linelen;
2254     gboolean    in_media_description;
2255     guchar      type, delim;
2256     int         datalen, tokenoffset, hf = -1;
2257     char       *string;
2258
2259     transport_info_t  local_transport_info;
2260     transport_info_t* transport_info = NULL;
2261     disposable_media_info_t media_info;
2262
2263     sdp_packet_info  *sdp_pi;
2264     struct srtp_info *srtp_info = NULL;
2265
2266     DPRINT2(("----------------------- dissect_sdp ------------------------"));
2267
2268     /* Initialise packet info for passing to tap */
2269     sdp_pi = wmem_new(wmem_packet_scope(), sdp_packet_info);
2270     sdp_pi->summary_str[0] = '\0';
2271
2272     if (!pinfo->fd->flags.visited) {
2273         transport_info = (transport_info_t*)wmem_tree_lookup32( sdp_transport_reqs, pinfo->fd->num );
2274
2275         if (transport_info == NULL) {
2276           /* Can't find it in the requests, make sure it's not a response */
2277           transport_info = (transport_info_t*)wmem_tree_lookup32( sdp_transport_rsps, pinfo->fd->num );
2278         }
2279     }
2280
2281     if (transport_info == NULL) {
2282       transport_info = &local_transport_info;
2283     }
2284 #ifdef DEBUG_CONVERSATION
2285     else {
2286         DPRINT(("found previous transport_info:"));
2287         sdp_dump_transport_info(transport_info);
2288     }
2289 #endif
2290
2291     /* Initialize local transport info */
2292     memset(&local_transport_info, 0, sizeof(local_transport_info));
2293     local_transport_info.media_count = -1;
2294
2295     for (n = 0; n < SDP_NO_OF_PT; n++) {
2296         local_transport_info.encoding_name[n] = (char*)UNKNOWN_ENCODING;
2297     }
2298     for (n = 0; n < SDP_MAX_RTP_CHANNELS; n++) {
2299         local_transport_info.media[n].rtp_dyn_payload = rtp_dyn_payload_new();
2300         local_transport_info.media[n].set_rtp = FALSE;
2301     }
2302
2303     memset(&media_info, 0, sizeof(media_info));
2304
2305     /*
2306      * As RFC 2327 says, "SDP is purely a format for session
2307      * description - it does not incorporate a transport protocol,
2308      * and is intended to use different transport protocols as
2309      * appropriate including the Session Announcement Protocol,
2310      * Session Initiation Protocol, Real-Time Streaming Protocol,
2311      * electronic mail using the MIME extensions, and the
2312      * Hypertext Transport Protocol."
2313      *
2314      * We therefore don't set the protocol or info columns;
2315      * instead, we append to them, so that we don't erase
2316      * what the protocol inside which the SDP stuff resides
2317      * put there.
2318      */
2319     col_append_str(pinfo->cinfo, COL_PROTOCOL, "/SDP");
2320
2321     /* XXX: Needs description.
2322      * Putting with session description in info col is redundant when it's in the
2323      * protocol col in my opinion, commenting it out for now 2012-10-09. Remove if no one complains.
2324      * If some one want it consider " ,with SDP"
2325      */
2326     /*col_append_str(pinfo->cinfo, COL_INFO, ", with session description");*/
2327
2328     ti = proto_tree_add_item(tree, proto_sdp, tvb, offset, -1, ENC_NA);
2329     sdp_tree = proto_item_add_subtree(ti, ett_sdp);
2330
2331     /*
2332      * Show the SDP message a line at a time.
2333      */
2334     in_media_description = FALSE;
2335
2336     while (tvb_offset_exists(tvb, offset)) {
2337         /*
2338          * Find the end of the line.
2339          */
2340         linelen = tvb_find_line_end_unquoted(tvb, offset, -1, &next_offset);
2341
2342         /*
2343          * Line must contain at least e.g. "v=".
2344          */
2345         if (linelen < 2)
2346             break;
2347
2348         type  = tvb_get_guint8(tvb, offset);
2349         delim = tvb_get_guint8(tvb, offset + 1);
2350         if (delim != '=') {
2351             proto_item *ti2 = proto_tree_add_item(sdp_tree, hf_invalid, tvb, offset, linelen, ENC_UTF_8|ENC_NA);
2352             expert_add_info(pinfo, ti2, &ei_sdp_invalid_line_equal);
2353             offset = next_offset;
2354             continue;
2355         }
2356
2357         /*
2358          * Attributes.
2359          */
2360         switch (type) {
2361             case 'v':
2362                 hf = hf_protocol_version;
2363                 break;
2364             case 'o':
2365                 hf = hf_owner;
2366                 break;
2367             case 's':
2368                 hf = hf_session_name;
2369                 break;
2370             case 'i':
2371                 if (in_media_description) {
2372                   hf = hf_media_title;
2373                 } else {
2374                   hf = hf_session_info;
2375                 }
2376                 break;
2377             case 'u':
2378                 hf = hf_uri;
2379                 break;
2380             case 'e':
2381                 hf = hf_email;
2382                 break;
2383             case 'p':
2384                 hf = hf_phone;
2385                 break;
2386             case 'c':
2387                 hf = hf_connection_info;
2388                 break;
2389             case 'b':
2390                 hf = hf_bandwidth;
2391                 break;
2392             case 't':
2393                 hf = hf_time;
2394                 break;
2395             case 'r':
2396                 hf = hf_repeat_time;
2397                 break;
2398             case 'm':
2399                 hf = hf_media;
2400
2401                 /* Increase the count of media channels, but don't walk off the end of the arrays. */
2402                 if (local_transport_info.media_count < (SDP_MAX_RTP_CHANNELS-1))
2403                     local_transport_info.media_count++;
2404
2405                 if (in_media_description && (media_info.media_count < (SDP_MAX_RTP_CHANNELS-1)))
2406                     media_info.media_count++;
2407
2408                 in_media_description = TRUE;
2409                 break;
2410             case 'k':
2411                 hf = hf_encryption_key;
2412                 break;
2413             case 'a':
2414                 if (in_media_description) {
2415                     hf = hf_media_attribute;
2416                 } else {
2417                     hf = hf_session_attribute;
2418                 }
2419                 break;
2420             case 'z':
2421                 hf = hf_timezone;
2422                 break;
2423             default:
2424                 hf = hf_unknown;
2425                 break;
2426         }
2427         tokenoffset = 2;
2428         if (hf == hf_unknown)
2429             tokenoffset = 0;
2430         string = (char*)tvb_get_string_enc(wmem_packet_scope(), tvb, offset + tokenoffset,
2431                                                  linelen - tokenoffset, ENC_ASCII);
2432         sub_ti = proto_tree_add_string(sdp_tree, hf, tvb, offset, linelen,
2433                                        string);
2434
2435         call_sdp_subdissector(tvb_new_subset_length(tvb, offset + tokenoffset,
2436                                              linelen - tokenoffset),
2437                               pinfo,
2438                               hf, sub_ti, linelen-tokenoffset,
2439                               &local_transport_info, &media_info);
2440
2441         offset = next_offset;
2442     }
2443
2444     if (in_media_description) {
2445         /* Increase the count of media channels, but don't walk off the end of the arrays. */
2446         if (local_transport_info.media_count < (SDP_MAX_RTP_CHANNELS-1))
2447             local_transport_info.media_count++;
2448         if (media_info.media_count < (SDP_MAX_RTP_CHANNELS-1))
2449             media_info.media_count++;
2450     }
2451
2452     /* Take all of the collected strings and convert them into something permanent
2453      * for the life of the capture
2454      */
2455     if (transport_info == &local_transport_info) {
2456         DPRINT(("no previous transport_info saved, calling convert_disposable_media()"));
2457         DINDENT();
2458         convert_disposable_media(transport_info, &media_info, 0);
2459         DENDENT();
2460 #ifdef DEBUG_CONVERSATION
2461         sdp_dump_transport_info(transport_info);
2462 #endif
2463     }
2464 #ifdef DEBUG_CONVERSATION
2465     else {
2466         DPRINT(("not overwriting previous transport_info, local_transport_info contents:"));
2467         sdp_dump_transport_info(&local_transport_info);
2468     }
2469 #endif
2470
2471     for (n = 0; n < local_transport_info.media_count; n++)
2472     {
2473         /* Add (s)rtp and (s)rtcp conversation, if available (overrides t38 if conversation already set) */
2474         /* XXX - This is a placeholder for higher layer protocols that haven't implemented the proper
2475          * OFFER/ANSWER functionality using setup_sdp_transport().  Once all of the higher layers
2476          * use setup_sdp_transport(), this should be removed
2477          */
2478         guint32 current_rtp_port = 0;
2479
2480         if ((!pinfo->fd->flags.visited) && (transport_info == &local_transport_info) &&
2481             (transport_info->media_port[n] != 0) &&
2482             (transport_info->proto_bitmask[n] & (SDP_RTP_PROTO|SDP_SRTP_PROTO)) &&
2483             (transport_info->proto_bitmask[n] & (SDP_IPv4|SDP_IPv6))) {
2484
2485             if (transport_info->proto_bitmask[n] & SDP_SRTP_PROTO) {
2486                 srtp_info = wmem_new0(wmem_file_scope(), struct srtp_info);
2487                 if (transport_info->encryption_algorithm != SRTP_ENC_ALG_NOT_SET) {
2488                     srtp_info->encryption_algorithm = transport_info->encryption_algorithm;
2489                     srtp_info->auth_algorithm       = transport_info->auth_algorithm;
2490                     srtp_info->mki_len              = transport_info->mki_len;
2491                     srtp_info->auth_tag_len         = transport_info->auth_tag_len;
2492                 }
2493                 DPRINT(("calling srtp_add_address for media_port=%d, for channel=%d",
2494                         transport_info->media_port[n],n));
2495                 DINDENT();
2496                 srtp_add_address(pinfo, &transport_info->src_addr[n], transport_info->media_port[n], 0, "SDP", pinfo->fd->num,
2497                                 (transport_info->proto_bitmask[n] & SDP_VIDEO) ? TRUE : FALSE,
2498                                  transport_info->media[n].rtp_dyn_payload, srtp_info);
2499                 DENDENT();
2500             } else {
2501                 DPRINT(("calling rtp_add_address for media_port=%d, for channel=%d",
2502                         transport_info->media_port[n],n));
2503                 DINDENT();
2504                 rtp_add_address(pinfo, &transport_info->src_addr[n], transport_info->media_port[n], 0, "SDP", pinfo->fd->num,
2505                                 (transport_info->proto_bitmask[n] & SDP_VIDEO) ? TRUE : FALSE,
2506                                 transport_info->media[n].rtp_dyn_payload);
2507                 DENDENT();
2508             }
2509             transport_info->media[n].set_rtp = TRUE;
2510             /* SPRT might use the same port... */
2511             current_rtp_port = transport_info->media_port[n];
2512
2513             if (rtcp_handle) {
2514                 if (transport_info->proto_bitmask[n] & SDP_SRTP_PROTO) {
2515                     DPRINT(("calling srtcp_add_address for media_port=%d, for channel=%d",
2516                             transport_info->media_port[n],n));
2517                     DINDENT();
2518                     srtcp_add_address(pinfo, &transport_info->src_addr[n], transport_info->media_port[n]+1, 0, "SDP", pinfo->fd->num, srtp_info);
2519                     DENDENT();
2520                 } else {
2521                     DPRINT(("calling rtcp_add_address for media_port=%d, for channel=%d",
2522                             transport_info->media_port[n],n));
2523                     DINDENT();
2524                     rtcp_add_address(pinfo, &transport_info->src_addr[n], transport_info->media_port[n]+1, 0, "SDP", pinfo->fd->num);
2525                     DENDENT();
2526                 }
2527             }
2528         }
2529
2530         /* add SPRT conversation */
2531         /* XXX - more placeholder functionality */
2532         if ((!pinfo->fd->flags.visited) && (transport_info == &local_transport_info) &&
2533             (transport_info->proto_bitmask[n] & SDP_SPRT_PROTO) &&
2534             (transport_info->proto_bitmask[n] & (SDP_IPv4|SDP_IPv6)) &&
2535             (sprt_handle)) {
2536
2537             if (transport_info->media_port[n] == 0 && current_rtp_port) {
2538                 sprt_add_address(pinfo, &transport_info->src_addr[n], current_rtp_port,
2539                                  0, "SDP", pinfo->fd->num); /* will use same port as RTP */
2540             } else {
2541                 sprt_add_address(pinfo, &transport_info->src_addr[n], transport_info->media_port[n], 0, "SDP", pinfo->fd->num);
2542             }
2543         }
2544
2545         /* Add t38 conversation, if available and only if no rtp */
2546         /* XXX - more placeholder functionality */
2547         if ((!pinfo->fd->flags.visited) && (transport_info == &local_transport_info) &&
2548             (transport_info->media_port[n] != 0) &&
2549             !transport_info->media[n].set_rtp &&
2550             (transport_info->proto_bitmask[n] & SDP_T38_PROTO) &&
2551             (transport_info->proto_bitmask[n] & SDP_IPv4)) {
2552             t38_add_address(pinfo, &transport_info->src_addr[n], transport_info->media_port[n], 0, "SDP", pinfo->fd->num);
2553         }
2554
2555         /* Add MSRP conversation.  Uses addresses discovered in attribute
2556            rather than connection information of media session line */
2557         /* XXX - more placeholder functionality */
2558         if ((!pinfo->fd->flags.visited) && (transport_info == &local_transport_info) &&
2559             (transport_info->proto_bitmask[n] & SDP_MSRP_PROTO) &&
2560             (transport_info->proto_bitmask[n] & SDP_MSRP_IPv4) &&
2561             msrp_handle) {
2562             msrp_add_address(pinfo, &transport_info->src_addr[n], transport_info->media_port[n], "SDP", pinfo->fd->num);
2563         }
2564
2565         if (local_transport_info.media_port[n] != 0) {
2566             /* Create the RTP summary str for the Voip Call analysis.
2567              * XXX - Currently this is based only on the current packet
2568              */
2569             for (i = 0; i < local_transport_info.media[n].pt_count; i++)
2570             {
2571                 DPRINT(("in for-loop for voip call analysis setting for media #%d, pt=%d",
2572                         i, local_transport_info.media[n].pt[i]));
2573                 /* if the payload type is dynamic (96 to 127), check the hash table to add the desc in the SDP summary */
2574                 if ((local_transport_info.media[n].pt[i] >= 96) && (local_transport_info.media[n].pt[i] <= 127)) {
2575                     const gchar *payload_type_str = rtp_dyn_payload_get_name(
2576                         local_transport_info.media[n].rtp_dyn_payload,
2577                         local_transport_info.media[n].pt[i]);
2578                     if (payload_type_str) {
2579                         if (strlen(sdp_pi->summary_str))
2580                             g_strlcat(sdp_pi->summary_str, " ", 50);
2581                         g_strlcat(sdp_pi->summary_str, payload_type_str, 50);
2582                     } else {
2583                         char num_pt[10];
2584                         g_snprintf(num_pt, 10, "%u", local_transport_info.media[n].pt[i]);
2585                         if (strlen(sdp_pi->summary_str))
2586                             g_strlcat(sdp_pi->summary_str, " ", 50);
2587                         g_strlcat(sdp_pi->summary_str, num_pt, 50);
2588                       }
2589                 } else {
2590                     if (strlen(sdp_pi->summary_str))
2591                         g_strlcat(sdp_pi->summary_str, " ", 50);
2592                     g_strlcat(sdp_pi->summary_str,
2593                               val_to_str_ext(local_transport_info.media[n].pt[i], &rtp_payload_type_short_vals_ext, "%u"),
2594                               50);
2595                 }
2596             }
2597         }
2598
2599         /* Free the hash table if we did't assigned it to a conv use it */
2600         /* XXX - more placeholder functionality */
2601         if ((transport_info == &local_transport_info) &&
2602             !transport_info->media[n].set_rtp)
2603         {
2604             rtp_dyn_payload_free(transport_info->media[n].rtp_dyn_payload);
2605             transport_info->media[n].rtp_dyn_payload = NULL;
2606         }
2607
2608         /* Create the T38 summary str for the Voip Call analysis
2609          * XXX - Currently this is based only on the current packet
2610          */
2611         if ((local_transport_info.media_port[n] != 0) &&
2612             (local_transport_info.proto_bitmask[n] & SDP_T38_PROTO)) {
2613             if (strlen(sdp_pi->summary_str))
2614                 g_strlcat(sdp_pi->summary_str, " ", 50);
2615             g_strlcat(sdp_pi->summary_str, "t38", 50);
2616         }
2617     }
2618
2619     /* Free the remainded hash tables not used */
2620     /* XXX - more placeholder functionality */
2621     if (transport_info == &local_transport_info) {
2622         for (n = transport_info->media_count; n < SDP_MAX_RTP_CHANNELS; n++)
2623         {
2624             if (!transport_info->media[n].set_rtp)
2625             {
2626                 rtp_dyn_payload_free(transport_info->media[n].rtp_dyn_payload);
2627                 transport_info->media[n].rtp_dyn_payload = NULL;
2628             }
2629         }
2630     }
2631
2632     datalen = tvb_captured_length_remaining(tvb, offset);
2633     if (datalen > 0) {
2634         proto_tree_add_item(sdp_tree, hf_sdp_data, tvb, offset, datalen, ENC_NA);
2635     }
2636     /* Report this packet to the tap */
2637     tap_queue_packet(sdp_tap, pinfo, sdp_pi);
2638 }
2639
2640 void
2641 proto_register_sdp(void)
2642 {
2643     static hf_register_info hf[] = {
2644         { &hf_protocol_version,
2645             { "Session Description Protocol Version (v)", "sdp.version",
2646               FT_STRING, BASE_NONE, NULL, 0x0,
2647               NULL, HFILL }
2648         },
2649         { &hf_owner,
2650             { "Owner/Creator, Session Id (o)",
2651               "sdp.owner", FT_STRING, BASE_NONE, NULL,
2652               0x0, NULL, HFILL}
2653         },
2654         { &hf_session_name,
2655             { "Session Name (s)", "sdp.session_name",
2656               FT_STRING, BASE_NONE, NULL, 0x0,
2657               NULL, HFILL }
2658         },
2659         { &hf_session_info,
2660             { "Session Information (i)", "sdp.session_info",
2661               FT_STRING, BASE_NONE, NULL, 0x0,
2662               NULL, HFILL }
2663         },
2664         { &hf_uri,
2665             { "URI of Description (u)", "sdp.uri",
2666               FT_STRING, BASE_NONE, NULL, 0x0,
2667               NULL, HFILL }
2668         },
2669         { &hf_email,
2670             { "E-mail Address (e)", "sdp.email",
2671               FT_STRING, BASE_NONE, NULL, 0x0,
2672               "E-mail Address", HFILL }
2673         },
2674         { &hf_phone,
2675             { "Phone Number (p)", "sdp.phone",
2676               FT_STRING, BASE_NONE, NULL, 0x0,
2677               NULL, HFILL }
2678         },
2679         { &hf_connection_info,
2680             { "Connection Information (c)", "sdp.connection_info",
2681               FT_STRING, BASE_NONE, NULL, 0x0,
2682               NULL, HFILL }
2683         },
2684         { &hf_bandwidth,
2685             { "Bandwidth Information (b)", "sdp.bandwidth",
2686               FT_STRING, BASE_NONE, NULL, 0x0,
2687               NULL, HFILL }
2688         },
2689         { &hf_timezone,
2690             { "Time Zone Adjustments (z)", "sdp.timezone",
2691               FT_STRING, BASE_NONE, NULL, 0x0,
2692               NULL, HFILL }
2693         },
2694         { &hf_encryption_key,
2695             { "Encryption Key (k)", "sdp.encryption_key",
2696               FT_STRING, BASE_NONE, NULL, 0x0,
2697               NULL, HFILL }
2698         },
2699         { &hf_session_attribute,
2700             { "Session Attribute (a)", "sdp.session_attr",
2701               FT_STRING, BASE_NONE, NULL, 0x0,
2702               NULL, HFILL }
2703         },
2704         { &hf_media_attribute,
2705             { "Media Attribute (a)", "sdp.media_attr",
2706               FT_STRING, BASE_NONE, NULL, 0x0,
2707               NULL, HFILL }
2708         },
2709         { &hf_time,
2710             { "Time Description, active time (t)",
2711               "sdp.time", FT_STRING, BASE_NONE, NULL,
2712               0x0, NULL, HFILL }
2713         },
2714         { &hf_repeat_time,
2715             { "Repeat Time (r)", "sdp.repeat_time",
2716               FT_STRING, BASE_NONE, NULL, 0x0,
2717               NULL, HFILL }
2718         },
2719         { &hf_media,
2720             { "Media Description, name and address (m)",
2721               "sdp.media", FT_STRING, BASE_NONE, NULL,
2722               0x0, NULL, HFILL }
2723         },
2724         { &hf_media_title,
2725             { "Media Title (i)", "sdp.media_title",
2726               FT_STRING, BASE_NONE, NULL, 0x0,
2727               "Media Title", HFILL }
2728         },
2729         { &hf_unknown,
2730             { "Unknown", "sdp.unknown",
2731               FT_STRING, BASE_NONE, NULL, 0x0,
2732               NULL, HFILL }
2733         },
2734         { &hf_invalid,
2735             { "Invalid line", "sdp.invalid",
2736               FT_STRING, BASE_NONE, NULL, 0x0,
2737               NULL, HFILL }
2738         },
2739         { &hf_owner_username,
2740             { "Owner Username", "sdp.owner.username",
2741               FT_STRING, BASE_NONE, NULL, 0x0,
2742               NULL, HFILL }
2743         },
2744         { &hf_owner_sessionid,
2745             { "Session ID", "sdp.owner.sessionid",
2746               FT_STRING, BASE_NONE, NULL, 0x0,
2747               NULL, HFILL }
2748         },
2749         { &hf_owner_version,
2750             { "Session Version", "sdp.owner.version",
2751               FT_STRING, BASE_NONE, NULL, 0x0,
2752               NULL, HFILL }
2753         },
2754         { &hf_owner_network_type,
2755             { "Owner Network Type", "sdp.owner.network_type",
2756               FT_STRING, BASE_NONE, NULL, 0x0,
2757               NULL, HFILL }
2758         },
2759         { &hf_owner_address_type,
2760             { "Owner Address Type", "sdp.owner.address_type",
2761               FT_STRING, BASE_NONE, NULL, 0x0,
2762               NULL, HFILL }
2763         },
2764         { &hf_owner_address,
2765             { "Owner Address", "sdp.owner.address",
2766               FT_STRING, BASE_NONE, NULL, 0x0,
2767               NULL, HFILL }
2768         },
2769         { &hf_connection_info_network_type,
2770             { "Connection Network Type", "sdp.connection_info.network_type",
2771               FT_STRING, BASE_NONE, NULL, 0x0,
2772               NULL, HFILL }
2773         },
2774         { &hf_connection_info_address_type,
2775             { "Connection Address Type", "sdp.connection_info.address_type",
2776               FT_STRING, BASE_NONE, NULL, 0x0,
2777               NULL, HFILL }
2778         },
2779         { &hf_connection_info_connection_address,
2780             { "Connection Address", "sdp.connection_info.address",
2781               FT_STRING, BASE_NONE, NULL, 0x0,
2782               NULL, HFILL }
2783         },
2784         { &hf_connection_info_ttl,
2785             { "Connection TTL", "sdp.connection_info.ttl",
2786               FT_STRING, BASE_NONE, NULL, 0x0,
2787               NULL, HFILL }
2788         },
2789         { &hf_connection_info_num_addr,
2790             { "Connection Number of Addresses", "sdp.connection_info.num_addr",
2791               FT_STRING, BASE_NONE, NULL, 0x0,
2792               NULL, HFILL }
2793         },
2794         { &hf_bandwidth_modifier,
2795             { "Bandwidth Modifier", "sdp.bandwidth.modifier",
2796               FT_STRING, BASE_NONE, NULL, 0x0,
2797               NULL, HFILL }
2798         },
2799         { &hf_bandwidth_value,
2800             { "Bandwidth Value", "sdp.bandwidth.value",
2801               FT_STRING, BASE_NONE, NULL, 0x0,
2802               "Bandwidth Value (in kbits/s)", HFILL }
2803         },
2804         { &hf_time_start,
2805             { "Session Start Time", "sdp.time.start",
2806               FT_STRING, BASE_NONE, NULL, 0x0,
2807               NULL, HFILL }
2808         },
2809         { &hf_time_stop,
2810             { "Session Stop Time", "sdp.time.stop",
2811               FT_STRING, BASE_NONE, NULL, 0x0,
2812               NULL, HFILL }
2813         },
2814         { &hf_repeat_time_interval,
2815             { "Repeat Interval", "sdp.repeat_time.interval",
2816               FT_STRING, BASE_NONE, NULL, 0x0,
2817               NULL, HFILL }
2818         },
2819         { &hf_repeat_time_duration,
2820             { "Repeat Duration", "sdp.repeat_time.duration",
2821               FT_STRING, BASE_NONE, NULL, 0x0,
2822               NULL, HFILL }
2823         },
2824         { &hf_repeat_time_offset,
2825             { "Repeat Offset", "sdp.repeat_time.offset",
2826               FT_STRING, BASE_NONE, NULL, 0x0,
2827               NULL, HFILL }
2828         },
2829         { &hf_timezone_time,
2830             { "Timezone Time", "sdp.timezone.time",
2831               FT_STRING, BASE_NONE, NULL, 0x0,
2832               NULL, HFILL }
2833         },
2834         { &hf_timezone_offset,
2835             { "Timezone Offset", "sdp.timezone.offset",
2836               FT_STRING, BASE_NONE, NULL, 0x0,
2837               NULL, HFILL }
2838         },
2839         { &hf_encryption_key_type,
2840             { "Key Type", "sdp.encryption_key.type",
2841               FT_STRING, BASE_NONE, NULL, 0x0,
2842               NULL, HFILL }
2843         },
2844         { &hf_encryption_key_data,
2845             { "Key Data", "sdp.encryption_key.data",
2846               FT_STRING, BASE_NONE, NULL, 0x0,
2847               NULL, HFILL }
2848         },
2849         { &hf_session_attribute_field,
2850             { "Session Attribute Fieldname", "sdp.session_attr.field",
2851               FT_STRING, BASE_NONE, NULL, 0x0,
2852               NULL, HFILL }
2853         },
2854         { &hf_session_attribute_value,
2855             { "Session Attribute Value", "sdp.session_attr.value",
2856               FT_STRING, BASE_NONE, NULL, 0x0,
2857               NULL, HFILL }
2858         },
2859         { &hf_media_media,
2860             { "Media Type", "sdp.media.media",
2861               FT_STRING, BASE_NONE, NULL, 0x0,
2862               NULL, HFILL }
2863         },
2864         { &hf_media_port,
2865             { "Media Port", "sdp.media.port",
2866               FT_UINT16, BASE_DEC, NULL, 0x0,
2867               NULL, HFILL }
2868         },
2869         { &hf_media_port_string,
2870             { "Media Port", "sdp.media.port_string",
2871               FT_STRING, BASE_NONE, NULL, 0x0,
2872               NULL, HFILL }
2873         },
2874         { &hf_media_portcount,
2875             { "Media Port Count", "sdp.media.portcount",
2876               FT_STRING, BASE_NONE, NULL, 0x0,
2877               NULL, HFILL }
2878         },
2879         { &hf_media_proto,
2880             { "Media Protocol", "sdp.media.proto",
2881               FT_STRING, BASE_NONE, NULL, 0x0,
2882               NULL, HFILL }
2883         },
2884         { &hf_media_format,
2885             { "Media Format", "sdp.media.format",
2886               FT_STRING, BASE_NONE, NULL, 0x0,
2887               NULL, HFILL }
2888         },
2889         { &hf_media_attribute_field,
2890             { "Media Attribute Fieldname", "sdp.media_attribute.field",
2891               FT_STRING, BASE_NONE, NULL, 0x0,
2892               NULL, HFILL }
2893         },
2894         { &hf_media_attribute_value,
2895             { "Media Attribute Value", "sdp.media_attribute.value",
2896               FT_STRING, BASE_NONE, NULL, 0x0,
2897               NULL, HFILL }
2898         },
2899         { &hf_media_encoding_name,
2900             { "MIME Type", "sdp.mime.type",
2901               FT_STRING, BASE_NONE, NULL, 0x0,
2902               "SDP MIME Type", HFILL }
2903         },
2904         { &hf_media_sample_rate,
2905             { "Sample Rate", "sdp.sample_rate",
2906               FT_STRING, BASE_NONE, NULL, 0x0,
2907               NULL, HFILL }
2908         },
2909         { &hf_media_format_specific_parameter,
2910             { "Media format specific parameters", "sdp.fmtp.parameter",
2911               FT_STRING, BASE_NONE, NULL, 0x0,
2912               "Format specific parameter(fmtp)", HFILL }
2913         },
2914         { &hf_ipbcp_version,
2915             { "IPBCP Protocol Version", "sdp.ipbcp.version",
2916               FT_STRING, BASE_NONE, NULL, 0x0,
2917               NULL, HFILL }
2918         },
2919         { &hf_ipbcp_type,
2920             { "IPBCP Command Type", "sdp.ipbcp.command",
2921               FT_STRING, BASE_NONE, NULL, 0x0,
2922               NULL, HFILL }
2923         },
2924         {&hf_sdp_fmtp_mpeg4_profile_level_id,
2925            { "Level Code", "sdp.fmtp.profile_level_id",
2926              FT_UINT32, BASE_DEC, VALS(mp4ves_level_indication_vals), 0x0,
2927              NULL, HFILL }
2928         },
2929         { &hf_sdp_fmtp_h263_profile,
2930             { "Profile", "sdp.fmtp.h263profile",
2931               FT_UINT32, BASE_DEC, VALS(h263_profile_vals), 0x0,
2932               NULL, HFILL }
2933         },
2934         { &hf_sdp_fmtp_h263_level,
2935             { "Level", "sdp.fmtp.h263level",
2936               FT_UINT32, BASE_DEC, VALS(h263_level_vals), 0x0,
2937               NULL, HFILL }
2938         },
2939         { &hf_sdp_h264_packetization_mode,
2940             { "Packetization mode", "sdp.fmtp.h264_packetization_mode",
2941               FT_UINT32, BASE_DEC, VALS(h264_packetization_mode_vals), 0x0,
2942               NULL, HFILL }
2943         },
2944         { &hf_SDPh223LogicalChannelParameters,
2945             { "h223LogicalChannelParameters", "sdp.h223LogicalChannelParameters",
2946               FT_NONE, BASE_NONE, NULL, 0,
2947               NULL, HFILL }
2948         },
2949         { &hf_key_mgmt_att_value,
2950             { "Key Management", "sdp.key_mgmt",
2951               FT_STRING, BASE_NONE, NULL, 0x0,
2952               NULL, HFILL }
2953         },
2954         { &hf_key_mgmt_prtcl_id,
2955             { "Key Management Protocol (kmpid)", "sdp.key_mgmt.kmpid",
2956               FT_STRING, BASE_NONE, NULL, 0x0,
2957               NULL, HFILL }
2958         },
2959         { &hf_key_mgmt_data,
2960             { "Key Management Data", "sdp.key_mgmt.data",
2961               FT_BYTES, BASE_NONE, NULL, 0x0,
2962               NULL, HFILL }
2963         },
2964         { &hf_sdp_crypto_tag,
2965             { "tag", "sdp.crypto.tag",
2966               FT_UINT32, BASE_DEC, NULL, 0x0,
2967               NULL, HFILL }
2968         },
2969         { &hf_sdp_crypto_crypto_suite,
2970             { "Crypto suite", "sdp.crypto.crypto_suite",
2971               FT_STRING, BASE_NONE, NULL, 0x0,
2972               NULL, HFILL }
2973         },
2974         { &hf_sdp_crypto_master_key,
2975             { "Master Key", "sdp.crypto.master_key",
2976               FT_BYTES, BASE_NONE, NULL, 0x0,
2977               NULL, HFILL }
2978         },
2979         { &hf_sdp_crypto_master_salt,
2980             { "Master salt", "sdp.crypto.master_salt",
2981               FT_BYTES, BASE_NONE, NULL, 0x0,
2982               NULL, HFILL }
2983         },
2984         { &hf_sdp_crypto_lifetime,
2985             { "Lifetime", "sdp.crypto.lifetime",
2986               FT_STRING, BASE_NONE, NULL, 0x0,
2987               NULL, HFILL }
2988         },
2989         { &hf_sdp_crypto_mki,
2990             { "mki-value", "sdp.crypto.mki-valu",
2991               FT_STRING, BASE_NONE, NULL, 0x0,
2992               NULL, HFILL }
2993         },
2994         { &hf_sdp_crypto_mki_length,
2995             { "mki_length", "sdp.crypto.mki_length",
2996               FT_STRING, BASE_NONE, NULL, 0x0,
2997               NULL, HFILL }
2998         },
2999       /* Generated from convert_proto_tree_add_text.pl */
3000       { &hf_sdp_nal_unit_1_string, { "NAL unit 1 string", "sdp.nal_unit_1_string", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3001       { &hf_sdp_nal_unit_2_string, { "NAL unit 2 string", "sdp.nal_unit_2_string", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3002       { &hf_sdp_key_and_salt, { "Key and Salt", "sdp.key_and_salt", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3003       { &hf_sdp_data, { "Data", "sdp.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3004     };
3005     static gint *ett[] = {
3006         &ett_sdp,
3007         &ett_sdp_owner,
3008         &ett_sdp_connection_info,
3009         &ett_sdp_bandwidth,
3010         &ett_sdp_time,
3011         &ett_sdp_repeat_time,
3012         &ett_sdp_timezone,
3013         &ett_sdp_encryption_key,
3014         &ett_sdp_session_attribute,
3015         &ett_sdp_media,
3016         &ett_sdp_media_attribute,
3017         &ett_sdp_fmtp,
3018         &ett_sdp_key_mgmt,
3019         &ett_sdp_crypto_key_parameters,
3020     };
3021
3022     static ei_register_info ei[] = {
3023         { &ei_sdp_invalid_key_param,
3024             { "sdp.invalid_key_param",
3025               PI_MALFORMED, PI_NOTE,
3026               "Invalid key-param (no ':' delimiter)",
3027               EXPFILL
3028             }
3029         },
3030         { &ei_sdp_invalid_line_equal,
3031             { "sdp.invalid_line.no_equal",
3032               PI_MALFORMED, PI_NOTE,
3033               "Invalid SDP line (no '=' delimiter)",
3034               EXPFILL
3035             }
3036         },
3037         { &ei_sdp_invalid_line_fields,
3038             { "sdp.invalid_line.missing_fields",
3039               PI_MALFORMED, PI_ERROR,
3040               "Invalid SDP line (missing required fields)",
3041               EXPFILL
3042             }
3043         },
3044         { &ei_sdp_invalid_line_space,
3045             { "sdp.invalid_line.extra_space",
3046               PI_MALFORMED, PI_ERROR,
3047               "Invalid SDP whitespace (extra space character)",
3048               EXPFILL
3049             }
3050         },
3051         { &ei_sdp_invalid_conversion,
3052             { "sdp.invalid_conversion",
3053               PI_PROTOCOL, PI_WARN,
3054               "Invalid conversion",
3055               EXPFILL
3056             }
3057         }
3058     };
3059
3060     module_t *sdp_module;
3061     expert_module_t* expert_sdp;
3062
3063     proto_sdp = proto_register_protocol("Session Description Protocol",
3064                                         "SDP", "sdp");
3065     proto_register_field_array(proto_sdp, hf, array_length(hf));
3066     proto_register_subtree_array(ett, array_length(ett));
3067     expert_sdp = expert_register_protocol(proto_sdp);
3068     expert_register_field_array(expert_sdp, ei, array_length(ei));
3069
3070     key_mgmt_dissector_table = register_dissector_table("key_mgmt",
3071                                                         "Key Management", FT_STRING, BASE_NONE);
3072     /*
3073      * Preferences registration
3074      */
3075     sdp_module = prefs_register_protocol(proto_sdp, NULL);
3076     prefs_register_bool_preference(sdp_module, "establish_conversation",
3077                                    "Establish Media Conversation",
3078                                    "Specifies that RTP/RTCP/T.38/MSRP/etc streams are decoded based "
3079                                    "upon port numbers found in SDP payload",
3080                                    &global_sdp_establish_conversation);
3081
3082     sdp_transport_reqs = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
3083     sdp_transport_rsps = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
3084
3085     /*
3086      * Register the dissector by name, so other dissectors can
3087      * grab it by name rather than just referring to it directly.
3088      */
3089     register_dissector("sdp", dissect_sdp, proto_sdp);
3090
3091     /* Register for tapping */
3092     sdp_tap = register_tap("sdp");
3093
3094     /* compile patterns */
3095     ws_mempbrk_compile(&pbrk_digits, "0123456789");
3096     ws_mempbrk_compile(&pbrk_alpha, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
3097 }
3098
3099 void
3100 proto_reg_handoff_sdp(void)
3101 {
3102     dissector_handle_t sdp_handle;
3103
3104     rtcp_handle   = find_dissector("rtcp");
3105     msrp_handle   = find_dissector("msrp");
3106     sprt_handle   = find_dissector("sprt");
3107     h264_handle   = find_dissector("h264");
3108     mp4ves_handle = find_dissector("mp4ves");
3109
3110     proto_sprt    = dissector_handle_get_protocol_index(find_dissector("sprt"));
3111
3112     sdp_handle = find_dissector("sdp");
3113     dissector_add_string("media_type", "application/sdp", sdp_handle);
3114     dissector_add_uint("bctp.tpi", 0x20, sdp_handle);
3115 }
3116
3117 /*
3118  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
3119  *
3120  * Local variables:
3121  * c-basic-offset: 4
3122  * tab-width: 8
3123  * indent-tabs-mode: nil
3124  * End:
3125  *
3126  * vi: set shiftwidth=4 tabstop=8 expandtab:
3127  * :indentSize=4:tabSize=8:noTabs=true:
3128  */