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