PageRenderTime 54ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/epan/dissectors/packet-sdp.c

https://github.com/labx-technologies-llc/wireshark
C | 2763 lines | 2060 code | 333 blank | 370 comment | 488 complexity | f4be8ff309ab793438220629debe7b5e MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  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. * $Id$
  8. *
  9. * Wireshark - Network traffic analyzer
  10. * By Gerald Combs <gerald@wireshark.org>
  11. * Copyright 1998 Gerald Combs
  12. *
  13. * This program is free software; you can redistribute it and/or
  14. * modify it under the terms of the GNU General Public License
  15. * as published by the Free Software Foundation; either version 2
  16. * of the License, or (at your option) any later version.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program; if not, write to the Free Software
  25. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  26. * Ref http://www.ietf.org/rfc/rfc4566.txt?number=4566
  27. */
  28. #include "config.h"
  29. #ifdef HAVE_SYS_TYPES_H
  30. #include <sys/types.h>
  31. #endif
  32. #ifdef HAVE_SYS_SOCKET_H
  33. #include <sys/socket.h>
  34. #endif
  35. #ifdef HAVE_NETINET_IN_H
  36. # include <netinet/in.h>
  37. #endif
  38. #ifdef HAVE_ARPA_INET_H
  39. #include <arpa/inet.h>
  40. #endif
  41. #ifdef HAVE_WINSOCK2_H
  42. #include <winsock2.h> /* needed to define AF_ values on Windows */
  43. #endif
  44. #ifdef NEED_INET_V6DEFS_H
  45. # include "wsutil/inet_v6defs.h"
  46. #endif
  47. #include <glib.h>
  48. #include <epan/packet.h>
  49. #include <epan/strutil.h>
  50. #include <epan/emem.h>
  51. #include <epan/wmem/wmem.h>
  52. #include <epan/base64.h>
  53. #include <epan/asn1.h>
  54. #include <epan/prefs.h>
  55. #include <epan/expert.h>
  56. #include <epan/tap.h>
  57. #include <epan/rtp_pt.h>
  58. #include <epan/show_exception.h>
  59. #include "packet-sdp.h"
  60. #include "packet-rtp.h"
  61. #include "packet-rtcp.h"
  62. #include "packet-t38.h"
  63. #include "packet-msrp.h"
  64. #include "packet-sprt.h"
  65. #include "packet-per.h"
  66. #include "packet-h245.h"
  67. #include "packet-h264.h"
  68. #include "packet-mp4ves.h"
  69. static dissector_handle_t rtp_handle;
  70. static dissector_handle_t rtcp_handle;
  71. static dissector_handle_t t38_handle;
  72. static dissector_handle_t sprt_handle;
  73. static dissector_handle_t msrp_handle;
  74. static dissector_handle_t h264_handle;
  75. static dissector_handle_t mp4ves_handle;
  76. static int sdp_tap = -1;
  77. static int proto_sdp = -1;
  78. static int proto_sprt = -1;
  79. static const char* UNKNOWN_ENCODING = "Unknown";
  80. static emem_tree_t *sdp_transport_reqs = NULL;
  81. static emem_tree_t *sdp_transport_rsps = NULL;
  82. /* preference globals */
  83. static gboolean global_sdp_establish_conversation = TRUE;
  84. /* Top level fields */
  85. static int hf_protocol_version = -1;
  86. static int hf_owner = -1;
  87. static int hf_session_name = -1;
  88. static int hf_session_info = -1;
  89. static int hf_uri = -1;
  90. static int hf_email = -1;
  91. static int hf_phone = -1;
  92. static int hf_connection_info = -1;
  93. static int hf_bandwidth = -1;
  94. static int hf_timezone = -1;
  95. static int hf_encryption_key = -1;
  96. static int hf_session_attribute = -1;
  97. static int hf_media_attribute = -1;
  98. static int hf_time = -1;
  99. static int hf_repeat_time = -1;
  100. static int hf_media = -1;
  101. static int hf_media_title = -1;
  102. static int hf_unknown = -1;
  103. static int hf_invalid = -1;
  104. static int hf_ipbcp_version = -1;
  105. static int hf_ipbcp_type = -1;
  106. /* hf_owner subfields*/
  107. static int hf_owner_username = -1;
  108. static int hf_owner_sessionid = -1;
  109. static int hf_owner_version = -1;
  110. static int hf_owner_network_type = -1;
  111. static int hf_owner_address_type = -1;
  112. static int hf_owner_address = -1;
  113. /* hf_connection_info subfields */
  114. static int hf_connection_info_network_type = -1;
  115. static int hf_connection_info_address_type = -1;
  116. static int hf_connection_info_connection_address = -1;
  117. static int hf_connection_info_ttl = -1;
  118. static int hf_connection_info_num_addr = -1;
  119. /* hf_bandwidth subfields */
  120. static int hf_bandwidth_modifier = -1;
  121. static int hf_bandwidth_value = -1;
  122. /* hf_time subfields */
  123. static int hf_time_start = -1;
  124. static int hf_time_stop = -1;
  125. /* hf_repeat_time subfield */
  126. static int hf_repeat_time_interval = -1;
  127. static int hf_repeat_time_duration = -1;
  128. static int hf_repeat_time_offset = -1;
  129. /* hf_timezone subfields */
  130. static int hf_timezone_time = -1;
  131. static int hf_timezone_offset = -1;
  132. /* hf_encryption_key subfields */
  133. static int hf_encryption_key_type = -1;
  134. static int hf_encryption_key_data = -1;
  135. /* hf_session_attribute subfields */
  136. static int hf_session_attribute_field = -1;
  137. static int hf_session_attribute_value = -1;
  138. /* hf_media subfields */
  139. static int hf_media_media = -1;
  140. static int hf_media_port = -1;
  141. static int hf_media_portcount = -1;
  142. static int hf_media_proto = -1;
  143. static int hf_media_format = -1;
  144. /* hf_session_attribute subfields */
  145. static int hf_media_attribute_field = -1;
  146. static int hf_media_attribute_value = -1;
  147. static int hf_media_encoding_name = -1;
  148. static int hf_media_sample_rate = -1;
  149. static int hf_media_format_specific_parameter = -1;
  150. static int hf_sdp_fmtp_mpeg4_profile_level_id = -1;
  151. static int hf_sdp_fmtp_h263_profile = -1;
  152. static int hf_sdp_fmtp_h263_level = -1;
  153. static int hf_sdp_h264_packetization_mode = -1;
  154. static int hf_SDPh223LogicalChannelParameters = -1;
  155. /* hf_session_attribute hf_media_attribute subfields */
  156. static int hf_key_mgmt_att_value = -1;
  157. static int hf_key_mgmt_prtcl_id = -1;
  158. static int hf_key_mgmt_data = -1;
  159. static int hf_sdp_crypto_tag = -1;
  160. static int hf_sdp_crypto_crypto_suite = -1;
  161. static int hf_sdp_crypto_master_key = -1;
  162. static int hf_sdp_crypto_master_salt = -1;
  163. static int hf_sdp_crypto_lifetime = -1;
  164. static int hf_sdp_crypto_mki = -1;
  165. static int hf_sdp_crypto_mki_length = -1;
  166. /* trees */
  167. static int ett_sdp = -1;
  168. static int ett_sdp_owner = -1;
  169. static int ett_sdp_connection_info = -1;
  170. static int ett_sdp_bandwidth = -1;
  171. static int ett_sdp_time = -1;
  172. static int ett_sdp_repeat_time = -1;
  173. static int ett_sdp_timezone = -1;
  174. static int ett_sdp_encryption_key = -1;
  175. static int ett_sdp_session_attribute = -1;
  176. static int ett_sdp_media = -1;
  177. static int ett_sdp_media_attribute = -1;
  178. static int ett_sdp_fmtp = -1;
  179. static int ett_sdp_key_mgmt = -1;
  180. static int ett_sdp_crypto_key_parameters = -1;
  181. static expert_field ei_sdp_invalid_key_param = EI_INIT;
  182. static expert_field ei_sdp_invalid_line = EI_INIT;
  183. #define SDP_RTP_PROTO 0x00000001
  184. #define SDP_SRTP_PROTO 0x00000002
  185. #define SDP_T38_PROTO 0x00000004
  186. #define SDP_MSRP_PROTO 0x00000008
  187. #define SDP_SPRT_PROTO 0x00000010
  188. #define SDP_IPv4 0x80000000
  189. #define SDP_IPv6 0x40000000
  190. #define SDP_MSRP_IPv4 0x20000000
  191. #define SDP_VIDEO 0x10000000
  192. #define SDP_MAX_RTP_CHANNELS 4
  193. #define SDP_MAX_RTP_PAYLOAD_TYPES 20
  194. #define SDP_NO_OF_PT 128
  195. typedef struct {
  196. gint32 pt[SDP_MAX_RTP_PAYLOAD_TYPES];
  197. gint8 pt_count;
  198. GHashTable *rtp_dyn_payload;
  199. gboolean set_rtp;
  200. } transport_media_pt_t;
  201. typedef struct {
  202. enum sdp_exchange_type sdp_status;
  203. char *encoding_name[SDP_NO_OF_PT];
  204. int sample_rate[SDP_NO_OF_PT];
  205. int media_port[SDP_MAX_RTP_CHANNELS];
  206. address src_addr[SDP_MAX_RTP_CHANNELS];
  207. guint proto_bitmask[SDP_MAX_RTP_CHANNELS];
  208. transport_media_pt_t media[SDP_MAX_RTP_CHANNELS];
  209. gint8 media_count;
  210. /* SRTP related info XXX note currently we only handle one crypto line in the SDP
  211. * We should probably handle offer/answer and session updates etc(SIP) quite possibly the whole handling of
  212. * seting up the RTP conversations should be done by the signaling protocol(s) calling the SDP dissector
  213. * and the SDP dissector just provide the relevant data.
  214. */
  215. guint encryption_algorithm;
  216. guint auth_algorithm;
  217. guint mki_len; /* number of octets used for the MKI in the RTP payload */
  218. guint auth_tag_len; /* number of octets used for the Auth Tag in the RTP payload */
  219. } transport_info_t;
  220. /* Data that is retrieved from a packet, but does not need to be kept */
  221. typedef struct {
  222. char *connection_address;
  223. char *connection_type;
  224. char *media_type;
  225. char *media_port[SDP_MAX_RTP_CHANNELS];
  226. char *media_proto[SDP_MAX_RTP_CHANNELS];
  227. guint8 media_count;
  228. /* MSRP transport info (as set while parsing path attribute) */
  229. gboolean msrp_transport_address_set;
  230. guint32 msrp_ipaddr[4];
  231. guint16 msrp_port_number;
  232. } disposable_media_info_t;
  233. /* key-mgmt dissector
  234. * IANA registry:
  235. * http://www.iana.org/assignments/sdp-parameters
  236. */
  237. static dissector_table_t key_mgmt_dissector_table;
  238. /* Subdissector functions */
  239. static void
  240. dissect_sdp_owner(tvbuff_t *tvb, proto_item *ti) {
  241. proto_tree *sdp_owner_tree;
  242. gint offset, next_offset, tokenlen;
  243. offset = 0;
  244. sdp_owner_tree = proto_item_add_subtree(ti, ett_sdp_owner);
  245. /* Find the username */
  246. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  247. if (next_offset == -1)
  248. return;
  249. tokenlen = next_offset - offset;
  250. proto_tree_add_item(sdp_owner_tree, hf_owner_username, tvb, offset, tokenlen,
  251. ENC_ASCII|ENC_NA);
  252. offset = next_offset + 1;
  253. /* Find the session id */
  254. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  255. if (next_offset == -1)
  256. return;
  257. tokenlen = next_offset - offset;
  258. proto_tree_add_item(sdp_owner_tree, hf_owner_sessionid, tvb, offset,
  259. tokenlen, ENC_ASCII|ENC_NA);
  260. offset = next_offset + 1;
  261. /* Find the version */
  262. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  263. if (next_offset == -1)
  264. return;
  265. tokenlen = next_offset - offset;
  266. proto_tree_add_item(sdp_owner_tree, hf_owner_version, tvb, offset, tokenlen,
  267. ENC_ASCII|ENC_NA);
  268. offset = next_offset + 1;
  269. /* Find the network type */
  270. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  271. if (next_offset == -1)
  272. return;
  273. tokenlen = next_offset - offset;
  274. proto_tree_add_item(sdp_owner_tree, hf_owner_network_type, tvb, offset,
  275. tokenlen, ENC_ASCII|ENC_NA);
  276. offset = next_offset + 1;
  277. /* Find the address type */
  278. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  279. if (next_offset == -1)
  280. return;
  281. tokenlen = next_offset - offset;
  282. proto_tree_add_item(sdp_owner_tree, hf_owner_address_type, tvb, offset,
  283. tokenlen, ENC_ASCII|ENC_NA);
  284. offset = next_offset + 1;
  285. /* Find the address */
  286. proto_tree_add_item(sdp_owner_tree, hf_owner_address, tvb, offset, -1, ENC_ASCII|ENC_NA);
  287. }
  288. /*
  289. * XXX - this can leak memory if an exception is thrown after we've fetched
  290. * a string.
  291. */
  292. static void
  293. dissect_sdp_connection_info(tvbuff_t *tvb, proto_item* ti,
  294. disposable_media_info_t *media_info) {
  295. proto_tree *sdp_connection_info_tree;
  296. gint offset, next_offset, tokenlen;
  297. offset = 0;
  298. sdp_connection_info_tree = proto_item_add_subtree(ti,
  299. ett_sdp_connection_info);
  300. /* Find the network type */
  301. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  302. if (next_offset == -1)
  303. return;
  304. tokenlen = next_offset - offset;
  305. proto_tree_add_item(sdp_connection_info_tree,
  306. hf_connection_info_network_type, tvb, offset, tokenlen,
  307. ENC_ASCII|ENC_NA);
  308. offset = next_offset + 1;
  309. /* Find the address type */
  310. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  311. if (next_offset == -1)
  312. return;
  313. tokenlen = next_offset - offset;
  314. /* Save connection address type */
  315. media_info->connection_type = (char*)tvb_get_ephemeral_string(tvb, offset, tokenlen);
  316. proto_tree_add_item(sdp_connection_info_tree,
  317. hf_connection_info_address_type, tvb, offset, tokenlen,
  318. ENC_ASCII|ENC_NA);
  319. offset = next_offset + 1;
  320. /* Find the connection address */
  321. /* XXX - what if there's a <number of addresses> value? */
  322. next_offset = tvb_find_guint8(tvb, offset, -1, '/');
  323. if (next_offset == -1) {
  324. tokenlen = -1; /* end of tvbuff */
  325. /* Save connection address */
  326. media_info->connection_address =
  327. (char*)tvb_get_ephemeral_string(tvb, offset, tvb_length_remaining(tvb, offset));
  328. } else {
  329. tokenlen = next_offset - offset;
  330. /* Save connection address */
  331. media_info->connection_address = (char*)tvb_get_ephemeral_string(tvb, offset, tokenlen);
  332. }
  333. proto_tree_add_item(sdp_connection_info_tree,
  334. hf_connection_info_connection_address, tvb, offset,
  335. tokenlen, ENC_ASCII|ENC_NA);
  336. if (next_offset != -1) {
  337. offset = next_offset + 1;
  338. next_offset = tvb_find_guint8(tvb, offset, -1, '/');
  339. if (next_offset == -1) {
  340. tokenlen = -1; /* end of tvbuff */
  341. } else {
  342. tokenlen = next_offset - offset;
  343. }
  344. proto_tree_add_item(sdp_connection_info_tree,
  345. hf_connection_info_ttl, tvb, offset, tokenlen, ENC_ASCII|ENC_NA);
  346. if (next_offset != -1) {
  347. offset = next_offset + 1;
  348. proto_tree_add_item(sdp_connection_info_tree,
  349. hf_connection_info_num_addr, tvb, offset, -1, ENC_ASCII|ENC_NA);
  350. }
  351. }
  352. }
  353. static void
  354. dissect_sdp_bandwidth(tvbuff_t *tvb, proto_item *ti) {
  355. proto_tree *sdp_bandwidth_tree;
  356. gint offset, next_offset, tokenlen;
  357. proto_item *item;
  358. gboolean unit_is_kbs = FALSE;
  359. gboolean unit_is_bps = FALSE;
  360. offset = 0;
  361. sdp_bandwidth_tree = proto_item_add_subtree(ti, ett_sdp_bandwidth);
  362. /* find the modifier */
  363. next_offset = tvb_find_guint8(tvb, offset, -1, ':');
  364. if (next_offset == -1)
  365. return;
  366. tokenlen = next_offset - offset;
  367. item = proto_tree_add_item(sdp_bandwidth_tree, hf_bandwidth_modifier, tvb, offset,
  368. tokenlen, ENC_ASCII|ENC_NA);
  369. if (tvb_strneql(tvb, offset, "CT", 2) == 0) {
  370. proto_item_append_text(item, " [Conference Total(total bandwidth of all RTP sessions)]");
  371. unit_is_kbs = TRUE;
  372. } else if (tvb_strneql(tvb, offset, "AS", 2) == 0) {
  373. proto_item_append_text(item, " [Application Specific (RTP session bandwidth)]");
  374. unit_is_kbs = TRUE;
  375. } else if (tvb_strneql(tvb, offset, "TIAS", 4) == 0) {
  376. proto_item_append_text(item, " [Transport Independent Application Specific maximum]");
  377. unit_is_bps = TRUE;
  378. }
  379. offset = next_offset + 1;
  380. item = proto_tree_add_item(sdp_bandwidth_tree, hf_bandwidth_value, tvb, offset, -1,
  381. ENC_ASCII|ENC_NA);
  382. if (unit_is_kbs == TRUE)
  383. proto_item_append_text(item, " kb/s");
  384. if (unit_is_bps == TRUE)
  385. proto_item_append_text(item, " b/s");
  386. }
  387. static void dissect_sdp_time(tvbuff_t *tvb, proto_item* ti) {
  388. proto_tree *sdp_time_tree;
  389. gint offset, next_offset, tokenlen;
  390. offset = 0;
  391. sdp_time_tree = proto_item_add_subtree(ti, ett_sdp_time);
  392. /* get start time */
  393. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  394. if (next_offset == -1)
  395. return;
  396. tokenlen = next_offset - offset;
  397. proto_tree_add_item(sdp_time_tree, hf_time_start, tvb, offset, tokenlen,
  398. ENC_ASCII|ENC_NA);
  399. /* get stop time */
  400. offset = next_offset + 1;
  401. proto_tree_add_item(sdp_time_tree, hf_time_stop, tvb, offset, -1, ENC_ASCII|ENC_NA);
  402. }
  403. static void dissect_sdp_repeat_time(tvbuff_t *tvb, proto_item* ti) {
  404. proto_tree *sdp_repeat_time_tree;
  405. gint offset, next_offset, tokenlen;
  406. offset = 0;
  407. sdp_repeat_time_tree = proto_item_add_subtree(ti, ett_sdp_time);
  408. /* get interval */
  409. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  410. if (next_offset == -1)
  411. return;
  412. tokenlen = next_offset - offset;
  413. proto_tree_add_item(sdp_repeat_time_tree, hf_repeat_time_interval, tvb,
  414. offset, tokenlen, ENC_ASCII|ENC_NA);
  415. /* get duration */
  416. offset = next_offset + 1;
  417. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  418. if (next_offset == -1)
  419. return;
  420. tokenlen = next_offset - offset;
  421. proto_tree_add_item(sdp_repeat_time_tree, hf_repeat_time_duration, tvb,
  422. offset, tokenlen, ENC_ASCII|ENC_NA);
  423. /* get offsets */
  424. do{
  425. offset = next_offset +1;
  426. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  427. if (next_offset != -1) {
  428. tokenlen = next_offset - offset;
  429. } else {
  430. tokenlen = -1; /* end of tvbuff */
  431. }
  432. proto_tree_add_item(sdp_repeat_time_tree, hf_repeat_time_offset,
  433. tvb, offset, tokenlen, ENC_ASCII|ENC_NA);
  434. } while (next_offset != -1);
  435. }
  436. static void
  437. dissect_sdp_timezone(tvbuff_t *tvb, proto_item* ti) {
  438. proto_tree* sdp_timezone_tree;
  439. gint offset, next_offset, tokenlen;
  440. offset = 0;
  441. sdp_timezone_tree = proto_item_add_subtree(ti, ett_sdp_timezone);
  442. do{
  443. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  444. if (next_offset == -1)
  445. break;
  446. tokenlen = next_offset - offset;
  447. proto_tree_add_item(sdp_timezone_tree, hf_timezone_time, tvb, offset,
  448. tokenlen, ENC_ASCII|ENC_NA);
  449. offset = next_offset + 1;
  450. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  451. if (next_offset != -1) {
  452. tokenlen = next_offset - offset;
  453. } else {
  454. tokenlen = -1; /* end of tvbuff */
  455. }
  456. proto_tree_add_item(sdp_timezone_tree, hf_timezone_offset, tvb, offset,
  457. tokenlen, ENC_ASCII|ENC_NA);
  458. offset = next_offset + 1;
  459. } while (next_offset != -1);
  460. }
  461. static void dissect_sdp_encryption_key(tvbuff_t *tvb, proto_item * ti) {
  462. proto_tree *sdp_encryption_key_tree;
  463. gint offset, next_offset, tokenlen;
  464. offset = 0;
  465. sdp_encryption_key_tree = proto_item_add_subtree(ti, ett_sdp_encryption_key);
  466. next_offset = tvb_find_guint8(tvb, offset, -1, ':');
  467. if (next_offset == -1)
  468. return;
  469. tokenlen = next_offset - offset;
  470. proto_tree_add_item(sdp_encryption_key_tree, hf_encryption_key_type,
  471. tvb, offset, tokenlen, ENC_ASCII|ENC_NA);
  472. offset = next_offset + 1;
  473. proto_tree_add_item(sdp_encryption_key_tree, hf_encryption_key_data,
  474. tvb, offset, -1, ENC_ASCII|ENC_NA);
  475. }
  476. static void dissect_key_mgmt(tvbuff_t *tvb, packet_info * pinfo, proto_item * ti) {
  477. gchar *data_p = NULL;
  478. gchar *prtcl_id = NULL;
  479. gint len;
  480. tvbuff_t *keymgmt_tvb;
  481. gboolean found_match = FALSE;
  482. proto_tree *key_tree;
  483. gint next_offset;
  484. gint offset = 0;
  485. gint tokenlen;
  486. key_tree = proto_item_add_subtree(ti, ett_sdp_key_mgmt);
  487. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  488. if (next_offset == -1)
  489. return;
  490. tokenlen = next_offset - offset;
  491. prtcl_id = tvb_get_ephemeral_string(tvb, offset, tokenlen);
  492. proto_tree_add_item(key_tree, hf_key_mgmt_prtcl_id, tvb, offset, tokenlen, ENC_ASCII|ENC_NA);
  493. offset = next_offset + 1;
  494. len = tvb_length_remaining(tvb, offset);
  495. if (len < 0)
  496. return;
  497. data_p = tvb_get_ephemeral_string(tvb, offset, len);
  498. keymgmt_tvb = base64_to_tvb(tvb, data_p);
  499. add_new_data_source(pinfo, keymgmt_tvb, "Key Management Data");
  500. if ((prtcl_id != NULL) && (key_mgmt_dissector_table != NULL)) {
  501. found_match = dissector_try_string(key_mgmt_dissector_table,
  502. prtcl_id,
  503. keymgmt_tvb, pinfo,
  504. key_tree);
  505. }
  506. if (found_match) {
  507. proto_item *ti2 = proto_tree_add_item(key_tree, hf_key_mgmt_data,
  508. keymgmt_tvb, 0, -1, ENC_NA);
  509. PROTO_ITEM_SET_HIDDEN(ti2);
  510. } else {
  511. proto_tree_add_item(key_tree, hf_key_mgmt_data,
  512. keymgmt_tvb, 0, -1, ENC_NA);
  513. }
  514. }
  515. static void dissect_sdp_session_attribute(tvbuff_t *tvb, packet_info * pinfo, proto_item * ti) {
  516. proto_tree *sdp_session_attribute_tree;
  517. gint offset, next_offset, tokenlen;
  518. guint8 *field_name;
  519. offset = 0;
  520. sdp_session_attribute_tree = proto_item_add_subtree(ti,
  521. ett_sdp_session_attribute);
  522. next_offset = tvb_find_guint8(tvb, offset, -1, ':');
  523. if (next_offset == -1)
  524. return;
  525. tokenlen = next_offset - offset;
  526. proto_tree_add_item(sdp_session_attribute_tree, hf_session_attribute_field,
  527. tvb, offset, tokenlen, ENC_ASCII|ENC_NA);
  528. field_name = tvb_get_ephemeral_string(tvb, offset, tokenlen);
  529. offset = next_offset + 1;
  530. if (strcmp((char*)field_name, "ipbcp") == 0) {
  531. offset = tvb_pbrk_guint8(tvb, offset, -1,"0123456789", NULL);
  532. if (offset == -1)
  533. return;
  534. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  535. if (next_offset == -1)
  536. return;
  537. tokenlen = next_offset - offset;
  538. proto_tree_add_item(sdp_session_attribute_tree, hf_ipbcp_version, tvb, offset, tokenlen, ENC_ASCII|ENC_NA);
  539. offset = tvb_pbrk_guint8(tvb, offset, -1,"ABCDEFGHIJKLMNOPQRSTUVWXYZ", NULL);
  540. if (offset == -1)
  541. return;
  542. tokenlen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
  543. if (tokenlen == -1)
  544. return;
  545. proto_tree_add_item(sdp_session_attribute_tree, hf_ipbcp_type, tvb, offset, tokenlen, ENC_ASCII|ENC_NA);
  546. } else if (strcmp((char*)field_name, "key-mgmt") == 0) {
  547. tvbuff_t *key_tvb;
  548. proto_item *key_ti;
  549. key_tvb = tvb_new_subset_remaining(tvb, offset);
  550. key_ti = proto_tree_add_item(sdp_session_attribute_tree, hf_key_mgmt_att_value, key_tvb, 0, -1, ENC_ASCII|ENC_NA);
  551. dissect_key_mgmt(key_tvb, pinfo, key_ti);
  552. } else {
  553. proto_tree_add_item(sdp_session_attribute_tree, hf_session_attribute_value,
  554. tvb, offset, -1, ENC_ASCII|ENC_NA);
  555. }
  556. }
  557. /* Dissect media description */
  558. static void
  559. dissect_sdp_media(tvbuff_t *tvb, proto_item *ti,
  560. transport_info_t *transport_info, disposable_media_info_t *media_info) {
  561. proto_tree *sdp_media_tree;
  562. gint offset, next_offset, tokenlen, idx;
  563. guint8 *media_format;
  564. offset = 0;
  565. /* Create tree for media session */
  566. sdp_media_tree = proto_item_add_subtree(ti, ett_sdp_media);
  567. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  568. if (next_offset == -1)
  569. return;
  570. tokenlen = next_offset - offset;
  571. /* Type of media session */
  572. proto_tree_add_item(sdp_media_tree, hf_media_media, tvb, offset, tokenlen,
  573. ENC_ASCII|ENC_NA);
  574. media_info->media_type = (char*)tvb_get_ephemeral_string(tvb, offset, tokenlen);
  575. offset = next_offset + 1;
  576. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  577. if (next_offset == -1)
  578. return;
  579. tokenlen = next_offset - offset;
  580. next_offset = tvb_find_guint8(tvb, offset, tokenlen, '/');
  581. if (next_offset != -1) {
  582. tokenlen = next_offset - offset;
  583. /* Save port info */
  584. media_info->media_port[media_info->media_count] = (char*)tvb_get_ephemeral_string(tvb, offset, tokenlen);
  585. proto_tree_add_uint(sdp_media_tree, hf_media_port, tvb, offset, tokenlen,
  586. atoi((char*)tvb_get_ephemeral_string(tvb, offset, tokenlen)));
  587. offset = next_offset + 1;
  588. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  589. if (next_offset == -1)
  590. return;
  591. tokenlen = next_offset - offset;
  592. proto_tree_add_item(sdp_media_tree, hf_media_portcount, tvb, offset,
  593. tokenlen, ENC_ASCII|ENC_NA);
  594. offset = next_offset + 1;
  595. } else {
  596. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  597. if (next_offset == -1)
  598. return;
  599. tokenlen = next_offset - offset;
  600. /* Save port info */
  601. media_info->media_port[media_info->media_count] = (char*)tvb_get_ephemeral_string(tvb, offset, tokenlen);
  602. /* XXX Remember Port */
  603. proto_tree_add_uint(sdp_media_tree, hf_media_port, tvb, offset, tokenlen,
  604. atoi((char*)tvb_get_ephemeral_string(tvb, offset, tokenlen)));
  605. offset = next_offset + 1;
  606. }
  607. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  608. if ( next_offset == -1)
  609. return;
  610. tokenlen = next_offset - offset;
  611. /* Save port protocol */
  612. media_info->media_proto[media_info->media_count] = (char*)tvb_get_ephemeral_string(tvb, offset, tokenlen);
  613. /* XXX Remember Protocol */
  614. proto_tree_add_item(sdp_media_tree, hf_media_proto, tvb, offset, tokenlen,
  615. ENC_ASCII|ENC_NA);
  616. do {
  617. offset = next_offset + 1;
  618. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  619. if (next_offset == -1) {
  620. tokenlen = tvb_length_remaining(tvb, offset); /* End of tvbuff */
  621. if (tokenlen == 0)
  622. break; /* Nothing more left */
  623. } else {
  624. tokenlen = next_offset - offset;
  625. }
  626. if (!strcmp(media_info->media_proto[media_info->media_count], "RTP/AVP")) {
  627. media_format = tvb_get_ephemeral_string(tvb, offset, tokenlen);
  628. proto_tree_add_string(sdp_media_tree, hf_media_format, tvb, offset,
  629. tokenlen, val_to_str_ext((guint32)strtoul((char*)media_format, NULL, 10), &rtp_payload_type_vals_ext, "%u"));
  630. idx = transport_info->media[transport_info->media_count].pt_count;
  631. transport_info->media[transport_info->media_count].pt[idx] = (gint32)strtol((char*)media_format, NULL, 10);
  632. if (idx < (SDP_MAX_RTP_PAYLOAD_TYPES-1))
  633. transport_info->media[transport_info->media_count].pt_count++;
  634. } else {
  635. proto_tree_add_item(sdp_media_tree, hf_media_format, tvb, offset,
  636. tokenlen, ENC_ASCII|ENC_NA);
  637. }
  638. } while (next_offset != -1);
  639. /* XXX Dissect traffic to "Port" as "Protocol"
  640. * Remember this Port/Protocol pair so we can tear it down again later
  641. * Actually, it's harder than that:
  642. * We need to find out the address of the other side first and it
  643. * looks like that info can be found in SIP headers only.
  644. */
  645. }
  646. static tvbuff_t *
  647. ascii_bytes_to_tvb(tvbuff_t *tvb, packet_info *pinfo, gint len, gchar *msg)
  648. {
  649. guint8 *buf = (guint8 *)wmem_alloc(pinfo->pool, 10240);
  650. /* arbitrary maximum length */
  651. if (len < 20480) {
  652. int i;
  653. tvbuff_t *bytes_tvb;
  654. /* first, skip to where the encoded pdu starts, this is
  655. the first hex digit after the '=' char.
  656. */
  657. while (1) {
  658. if ((*msg == 0) || (*msg == '\n')) {
  659. return NULL;
  660. }
  661. if (*msg == '=') {
  662. msg++;
  663. break;
  664. }
  665. msg++;
  666. }
  667. while (1) {
  668. if ((*msg == 0) || (*msg == '\n')) {
  669. return NULL;
  670. }
  671. if ( ((*msg >= '0') && (*msg <= '9'))
  672. || ((*msg >= 'a') && (*msg <= 'f'))
  673. || ((*msg >= 'A') && (*msg <= 'F'))) {
  674. break;
  675. }
  676. msg++;
  677. }
  678. i = 0;
  679. while (((*msg >= '0') && (*msg <= '9'))
  680. || ((*msg >= 'a') && (*msg <= 'f'))
  681. || ((*msg >= 'A') && (*msg <= 'F'))) {
  682. int val;
  683. if ((*msg >= '0') && (*msg <= '9')) {
  684. val = (*msg)-'0';
  685. } else if ((*msg >= 'a') && (*msg <= 'f')) {
  686. val = (*msg)-'a'+10;
  687. } else if ((*msg >= 'A') && (*msg <= 'F')) {
  688. val = (*msg)-'A'+10;
  689. } else {
  690. return NULL;
  691. }
  692. val <<= 4;
  693. msg++;
  694. if ((*msg >= '0') && (*msg <= '9')) {
  695. val |= (*msg)-'0';
  696. } else if ((*msg >= 'a') && (*msg <= 'f')) {
  697. val |= (*msg)-'a'+10;
  698. } else if ((*msg >= 'A') && (*msg <= 'F')) {
  699. val |= (*msg)-'A'+10;
  700. } else {
  701. return NULL;
  702. }
  703. msg++;
  704. buf[i] = (guint8)val;
  705. i++;
  706. }
  707. if (i == 0) {
  708. return NULL;
  709. }
  710. bytes_tvb = tvb_new_child_real_data(tvb, buf, i, i);
  711. add_new_data_source(pinfo, bytes_tvb, "ASCII bytes to tvb");
  712. return bytes_tvb;
  713. }
  714. return NULL;
  715. }
  716. /* Annex X Profiles and levels definition */
  717. static const value_string h263_profile_vals[] =
  718. {
  719. { 0, "Baseline Profile" },
  720. { 1, "H.320 Coding Efficiency Version 2 Backward-Compatibility Profile" },
  721. { 2, "Version 1 Backward-Compatibility Profile" },
  722. { 3, "Version 2 Interactive and Streaming Wireless Profile" },
  723. { 4, "Version 3 Interactive and Streaming Wireless Profile" },
  724. { 5, "Conversational High Compression Profile" },
  725. { 6, "Conversational Internet Profile" },
  726. { 7, "Conversational Interlace Profile" },
  727. { 8, "High Latency Profile" },
  728. { 0, NULL },
  729. };
  730. /* RFC 4629 The level are described in table X.2 of H.263 annex X */
  731. static const value_string h263_level_vals[] =
  732. {
  733. { 10, "QCIF (176 x 144), 1 x 64Kb/s" },
  734. { 20, "CIF (352 x 288), 2 x 64Kb/s" },
  735. { 30, "CIF (352 x 288), 6 x 64Kb/s" },
  736. { 40, "CIF (352 x 288), 32 x 64Kb/s" },
  737. { 45, "QCIF (176 x144) support of CPFMT, 2 x 64Kb/s" },
  738. { 50, "CIF (352 x 288) support of CPFMT, 64 x 64Kb/s" },
  739. { 60, "CPFMT: 720 x 288 support of CPFMT, 128 x 64Kb/s" },
  740. { 70, "CPFMT: 720 x 576 support of CPFMT, 256 x 64Kb/s" },
  741. { 0, NULL },
  742. };
  743. static const value_string h264_packetization_mode_vals[] =
  744. {
  745. { 0, "Single NAL mode" },
  746. { 1, "Non-interleaved mode" },
  747. { 2, "Interleaved mode" },
  748. { 0, NULL },
  749. };
  750. /*
  751. * TODO: Make this a more generic routine to dissect fmtp parameters depending on media types
  752. */
  753. static void
  754. decode_sdp_fmtp(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, gint offset, gint tokenlen, char *mime_type) {
  755. gint next_offset;
  756. gint end_offset;
  757. guint8 *field_name;
  758. gchar *format_specific_parameter;
  759. proto_item *item;
  760. tvbuff_t * volatile data_tvb;
  761. end_offset = offset + tokenlen;
  762. #if 0
  763. proto_tree_add_text(tree, tvb, offset, tokenlen, "Debug; Analysed string: '%s'",
  764. tvb_get_ephemeral_string(tvb, offset, tokenlen));
  765. #endif
  766. /* Look for an '=' within this value - this may indicate that there is a
  767. profile-level-id parameter to find if the MPEG4 media type is in use */
  768. next_offset = tvb_find_guint8(tvb, offset, -1, '=');
  769. if (next_offset == -1)
  770. {
  771. /* Give up (and avoid exception) if '=' not found */
  772. return;
  773. }
  774. /* Find the name of the parameter */
  775. tokenlen = next_offset - offset;
  776. field_name = tvb_get_ephemeral_string(tvb, offset, tokenlen);
  777. #if 0
  778. proto_tree_add_text(tree, tvb, offset, tokenlen, "Debug; MIMEtype '%s'Parameter name: '%s'", mime_type, field_name); */
  779. #endif
  780. offset = next_offset;
  781. /* Dissect the MPEG4 profile-level-id parameter if present */
  782. if ((mime_type != NULL) && (g_ascii_strcasecmp(mime_type, "MP4V-ES") == 0)) {
  783. if (strcmp((char*)field_name, "profile-level-id") == 0) {
  784. offset++;
  785. tokenlen = end_offset - offset;
  786. format_specific_parameter = tvb_get_ephemeral_string(tvb, offset, tokenlen);
  787. item = proto_tree_add_uint(tree, hf_sdp_fmtp_mpeg4_profile_level_id, tvb, offset, tokenlen,
  788. (guint32)strtol((char*)format_specific_parameter, NULL, 10));
  789. PROTO_ITEM_SET_GENERATED(item);
  790. } else if (strcmp((char*)field_name, "config") == 0) {
  791. /* String including "=" */
  792. tokenlen = end_offset - offset;
  793. format_specific_parameter = tvb_get_ephemeral_string(tvb, offset, tokenlen);
  794. /* ascii_bytes_to_tvb requires the "=" to be in the buffer */
  795. data_tvb = ascii_bytes_to_tvb(tvb, pinfo, tokenlen, format_specific_parameter);
  796. if (mp4ves_handle && data_tvb) {
  797. dissect_mp4ves_config(data_tvb, pinfo, tree);
  798. }
  799. }
  800. }
  801. /* Dissect the H263-2000 profile parameter if present */
  802. if (((mime_type != NULL) && (g_ascii_strcasecmp(mime_type, "H263-2000") == 0)) ||
  803. ((mime_type != NULL) && (g_ascii_strcasecmp(mime_type, "H263-1998") == 0))) {
  804. if (strcmp((char*)field_name, "profile") == 0) {
  805. offset++;
  806. tokenlen = end_offset - offset;
  807. format_specific_parameter = tvb_get_ephemeral_string(tvb, offset, tokenlen);
  808. item = proto_tree_add_uint(tree, hf_sdp_fmtp_h263_profile, tvb, offset, tokenlen,
  809. (guint32)strtol((char*)format_specific_parameter, NULL, 10));
  810. PROTO_ITEM_SET_GENERATED(item);
  811. } else if (strcmp((char*)field_name, "level") == 0) {
  812. offset++;
  813. tokenlen = end_offset - offset;
  814. format_specific_parameter = tvb_get_ephemeral_string(tvb, offset, tokenlen);
  815. item = proto_tree_add_uint(tree, hf_sdp_fmtp_h263_level, tvb, offset, tokenlen,
  816. (guint32)strtol((char*)format_specific_parameter, NULL, 10));
  817. PROTO_ITEM_SET_GENERATED(item);
  818. }
  819. }
  820. /* Dissect the H264 profile-level-id parameter
  821. * RFC 3984:
  822. * A base16 [6] (hexadecimal) representation of
  823. * the following three bytes in the sequence
  824. * parameter set NAL unit specified in [1]: 1)
  825. * profile_idc, 2) a byte herein referred to as
  826. * profile-iop, composed of the values of
  827. * constraint_set0_flag, constraint_set1_flag,
  828. * constraint_set2_flag, and reserved_zero_5bits
  829. * in bit-significance order, starting from the
  830. * most significant bit, and 3) level_idc.
  831. */
  832. if ((mime_type != NULL) && (g_ascii_strcasecmp(mime_type, "H264") == 0)) {
  833. if (strcmp(field_name, "profile-level-id") == 0) {
  834. int length = 0;
  835. /* Length includes "=" as it's required by ascii_bytes_to_tvb()*/
  836. tokenlen = end_offset - offset;
  837. format_specific_parameter = tvb_get_ephemeral_string(tvb, offset, tokenlen);
  838. data_tvb = ascii_bytes_to_tvb(tvb, pinfo, tokenlen, format_specific_parameter);
  839. if (!data_tvb) {
  840. proto_tree_add_text(tree, tvb, offset, tokenlen, "Could not convert '%s' to 3 bytes", format_specific_parameter);
  841. return;
  842. }
  843. length = tvb_length(data_tvb);
  844. if (length == 3) {
  845. if (h264_handle && data_tvb) {
  846. dissect_h264_profile(data_tvb, pinfo, tree);
  847. }
  848. } else {
  849. item = proto_tree_add_text(tree, tvb, offset, tokenlen, "Incorrectly coded, must be three bytes");
  850. PROTO_ITEM_SET_GENERATED(item);
  851. }
  852. } else if (strcmp(field_name, "packetization-mode") == 0) {
  853. offset++;
  854. tokenlen = end_offset - offset;
  855. format_specific_parameter = tvb_get_ephemeral_string(tvb, offset, tokenlen);
  856. item = proto_tree_add_uint(tree, hf_sdp_h264_packetization_mode, tvb, offset, tokenlen,
  857. (guint32)strtol((char*)format_specific_parameter, NULL, 10));
  858. PROTO_ITEM_SET_GENERATED(item);
  859. } else if (strcmp(field_name, "sprop-parameter-sets") == 0) {
  860. /* The value of the parameter is the
  861. base64 [6] representation of the initial
  862. parameter set NAL units as specified in
  863. sections 7.3.2.1 and 7.3.2.2 of [1]. The
  864. parameter sets are conveyed in decoding order,
  865. and no framing of the parameter set NAL units
  866. takes place. A comma is used to separate any
  867. pair of parameter sets in the list.
  868. */
  869. gchar *data_p = NULL;
  870. gint comma_offset;
  871. /* Move past '=' */
  872. offset++;
  873. comma_offset = tvb_find_guint8(tvb, offset, -1, ',');
  874. if (comma_offset != -1) {
  875. tokenlen = comma_offset - offset;
  876. } else {
  877. tokenlen = end_offset - offset;
  878. }
  879. data_p = tvb_get_ephemeral_string(tvb, offset, tokenlen);
  880. proto_tree_add_text(tree, tvb, offset, tokenlen, "NAL unit 1 string: %s", data_p);
  881. /* proto_tree_add_text(tree, tvb, offset, tokenlen, "String %s", data_p); */
  882. data_tvb = base64_to_tvb(tvb, data_p);
  883. add_new_data_source(pinfo, data_tvb, "h264 prop-parameter-sets");
  884. if (h264_handle && data_tvb) {
  885. TRY {
  886. dissect_h264_nal_unit(data_tvb, pinfo, tree);
  887. }
  888. CATCH_NONFATAL_ERRORS {
  889. show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
  890. }
  891. ENDTRY;
  892. if (comma_offset != -1) {
  893. /* Second NAL unit */
  894. offset = comma_offset +1;
  895. tokenlen = end_offset - offset;
  896. data_p = tvb_get_ephemeral_string(tvb, offset, tokenlen);
  897. proto_tree_add_text(tree, tvb, offset, tokenlen, "NAL unit 2 string: %s", data_p);
  898. data_tvb = base64_to_tvb(tvb, data_p);
  899. add_new_data_source(pinfo, data_tvb, "h264 prop-parameter-sets 2");
  900. dissect_h264_nal_unit(data_tvb, pinfo, tree);
  901. }
  902. }
  903. }
  904. }
  905. }
  906. typedef struct {
  907. const char *name;
  908. } sdp_names_t;
  909. #define SDP_RTPMAP 1
  910. #define SDP_FMTP 2
  911. #define SDP_PATH 3
  912. #define SDP_H248_ITEM 4
  913. #define SDP_CRYPTO 5
  914. #define SDP_SPRTMAP 6
  915. static const sdp_names_t sdp_media_attribute_names[] = {
  916. { "Unknown-name"}, /* 0 Pad so that the real headers start at index 1 */
  917. { "rtpmap"}, /* 1 */
  918. { "fmtp"}, /* 2 */
  919. { "path"}, /* 3 */
  920. { "h248item"}, /* 4 */
  921. { "crypto"}, /* 5 */
  922. { "sprt"}, /* 6 */
  923. };
  924. static gint find_sdp_media_attribute_names(tvbuff_t *tvb, int offset, guint len)
  925. {
  926. guint i;
  927. for (i = 1; i < array_length(sdp_media_attribute_names); i++) {
  928. if ((len == strlen(sdp_media_attribute_names[i].name)) &&
  929. (tvb_strncaseeql(tvb, offset, sdp_media_attribute_names[i].name, len) == 0))
  930. return i;
  931. }
  932. return -1;
  933. }
  934. static void dissect_sdp_media_attribute(tvbuff_t *tvb, packet_info *pinfo, proto_item * ti, int length,
  935. transport_info_t *transport_info, disposable_media_info_t *media_info) {
  936. proto_tree *sdp_media_attribute_tree, *parameter_item;
  937. proto_item *fmtp_item, *media_format_item, *parameter_tree;
  938. proto_tree *fmtp_tree;
  939. gint offset, next_offset, tokenlen, n, colon_offset;
  940. /*??guint8 *field_name;*/
  941. guint8 *payload_type;
  942. guint8 *attribute_value;
  943. gint *key;
  944. guint8 pt;
  945. gint sdp_media_attrbute_code;
  946. const char *msrp_res = "msrp://";
  947. const char *h324ext_h223lcparm = "h324ext/h223lcparm";
  948. gboolean has_more_pars = TRUE;
  949. tvbuff_t *h245_tvb;
  950. guint8 master_key_length = 0, master_salt_length = 0;
  951. encoding_name_and_rate_t *encoding_name_and_rate;
  952. offset = 0;
  953. /* Create attribute tree */
  954. sdp_media_attribute_tree = proto_item_add_subtree(ti,
  955. ett_sdp_media_attribute);
  956. /* Find end of field */
  957. colon_offset = tvb_find_guint8(tvb, offset, -1, ':');
  958. if (colon_offset == -1)
  959. return;
  960. /* Attribute field name is token before ':' */
  961. tokenlen = colon_offset - offset;
  962. proto_tree_add_item(sdp_media_attribute_tree,
  963. hf_media_attribute_field,
  964. tvb, offset, tokenlen, ENC_ASCII|ENC_NA);
  965. /*??field_name = tvb_get_ephemeral_string(tvb, offset, tokenlen);*/
  966. sdp_media_attrbute_code = find_sdp_media_attribute_names(tvb, offset, tokenlen);
  967. /* Skip colon */
  968. offset = colon_offset + 1;
  969. /* skip leading wsp */
  970. offset = tvb_skip_wsp(tvb, offset, tvb_length_remaining(tvb, offset));
  971. /* Value is the remainder of the line */
  972. attribute_value = tvb_get_ephemeral_string(tvb, offset, tvb_length_remaining(tvb, offset));
  973. /*********************************************/
  974. /* Special parsing for some field name types */
  975. switch (sdp_media_attrbute_code) {
  976. case SDP_RTPMAP:
  977. /* decode the rtpmap to see if it is DynamicPayload to dissect them automatic */
  978. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  979. if (next_offset == -1)
  980. return;
  981. tokenlen = next_offset - offset;
  982. proto_tree_add_item(sdp_media_attribute_tree, hf_media_format, tvb,
  983. offset, tokenlen, ENC_ASCII|ENC_NA);
  984. payload_type = tvb_get_ephemeral_string(tvb, offset, tokenlen);
  985. offset = next_offset + 1;
  986. next_offset = tvb_find_guint8(tvb, offset, -1, '/');
  987. if (next_offset == -1) {
  988. return;
  989. }
  990. tokenlen = next_offset - offset;
  991. proto_tree_add_item(sdp_media_attribute_tree, hf_media_encoding_name, tvb,
  992. offset, tokenlen, ENC_ASCII|ENC_NA);
  993. pt = atoi((char*)payload_type);
  994. if (pt >= SDP_NO_OF_PT) {
  995. return; /* Invalid */
  996. }
  997. key = se_new(gint);
  998. *key = (gint)strtol((char*)payload_type, NULL, 10);
  999. transport_info->encoding_name[pt] = (char*)tvb_get_ephemeral_string(tvb, offset, tokenlen);
  1000. next_offset = next_offset + 1;
  1001. offset = next_offset;
  1002. while (length-1 >= next_offset) {
  1003. if (!g_ascii_isdigit(tvb_get_guint8(tvb, next_offset)))
  1004. break;
  1005. next_offset++;
  1006. }
  1007. tokenlen = next_offset - offset;
  1008. proto_tree_add_item(sdp_media_attribute_tree, hf_media_sample_rate, tvb,
  1009. offset, tokenlen, ENC_ASCII|ENC_NA);
  1010. transport_info->sample_rate[pt] = atoi(tvb_get_ephemeral_string(tvb, offset, tokenlen));
  1011. /* As per RFC2327 it is possible to have multiple Media Descriptions ("m=").
  1012. For example:
  1013. a=rtpmap:101 G726-32/8000
  1014. m=audio 49170 RTP/AVP 0 97
  1015. a=rtpmap:97 telephone-event/8000
  1016. m=audio 49172 RTP/AVP 97 101
  1017. a=rtpmap:97 G726-24/8000
  1018. The Media attributes ("a="s) after the "m=" only apply for that "m=".
  1019. If there is an "a=" before the first "m=", that attribute applies for
  1020. all the session (all the "m="s).
  1021. */
  1022. /* so, if this "a=" appear before any "m=", we add it to all the dynamic
  1023. * hash tables
  1024. */
  1025. if (transport_info->media_count < 0) {
  1026. for (n = 0; n < SDP_MAX_RTP_CHANNELS; n++) {
  1027. encoding_name_and_rate = se_new(encoding_name_and_rate_t);
  1028. encoding_name_and_rate->encoding_name = se_strdup(transport_info->encoding_name[pt]);
  1029. encoding_name_and_rate->sample_rate = transport_info->sample_rate[pt];
  1030. if (n == 0) {
  1031. g_hash_table_insert(transport_info->media[n].rtp_dyn_payload,
  1032. key, encoding_name_and_rate);
  1033. } else { /* we create a new key and encoding_name to assign to the other hash tables */
  1034. gint *key2;
  1035. key2 = se_new(gint);
  1036. *key2 = (gint)strtol((char*)payload_type, NULL, 10);
  1037. g_hash_table_insert(transport_info->media[n].rtp_dyn_payload,
  1038. key2, encoding_name_and_rate);
  1039. }
  1040. }
  1041. return;
  1042. /* if the "a=" is after an "m=", only apply to this "m=" */
  1043. } else
  1044. /* in case there is an overflow in SDP_MAX_RTP_CHANNELS, we keep always the last "m=" */
  1045. encoding_name_and_rate = se_new(encoding_name_and_rate_t);
  1046. encoding_name_and_rate->encoding_name = se_strdup(transport_info->encoding_name[pt]);
  1047. encoding_name_and_rate->sample_rate = transport_info->sample_rate[pt];
  1048. g_hash_table_insert(transport_info->media[ transport_info->media_count ].rtp_dyn_payload,
  1049. key, encoding_name_and_rate);
  1050. break;
  1051. case SDP_FMTP:
  1052. if (sdp_media_attribute_tree) {
  1053. guint8 media_format;
  1054. /* Reading the Format parameter(fmtp) */
  1055. /* Skip leading space, if any */
  1056. offset = tvb_skip_wsp(tvb, offset, tvb_length_remaining(tvb, offset));
  1057. /* Media format extends to the next space */
  1058. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  1059. if (next_offset == -1)
  1060. return;
  1061. tokenlen = next_offset - offset;
  1062. media_format_item = proto_tree_add_item(sdp_media_attribute_tree,
  1063. hf_media_format, tvb, offset,
  1064. tokenlen, ENC_ASCII|ENC_NA);
  1065. media_format = atoi((char*)tvb_get_ephemeral_string(tvb, offset, tokenlen));
  1066. if (media_format >= SDP_NO_OF_PT) {
  1067. return; /* Invalid */
  1068. }
  1069. /* Append encoding name to format if known */
  1070. proto_item_append_text(media_format_item, " [%s]",
  1071. transport_info->encoding_name[media_format]);
  1072. #if 0 /* XXX: ?? */
  1073. payload_type = tvb_get_ephemeral_string(tvb, offset, tokenlen);
  1074. #endif
  1075. /* Move offset past the payload type */
  1076. offset = next_offset + 1;
  1077. while (has_more_pars == TRUE) {
  1078. next_offset = tvb_find_guint8(tvb, offset, -1, ';');
  1079. offset = tvb_skip_wsp(tvb, offset, tvb_length_remaining(tvb, offset));
  1080. if (next_offset == -1) {
  1081. has_more_pars = FALSE;
  1082. next_offset= tvb_length(tvb);
  1083. }
  1084. /* There are at least 2 - add the first parameter */
  1085. tokenlen = next_offset - offset;
  1086. fmtp_item = proto_tree_add_item(sdp_media_attribute_tree,
  1087. hf_media_format_specific_parameter, tvb,
  1088. offset, tokenlen, ENC_ASCII|ENC_NA);
  1089. fmtp_tree = proto_item_add_subtree(fmtp_item, ett_sdp_fmtp);
  1090. decode_sdp_fmtp(fmtp_tree, tvb, pinfo, offset, tokenlen,
  1091. transport_info->encoding_name[media_format]);
  1092. /* Move offset past "; " and onto firts char */
  1093. offset = next_offset + 1;
  1094. }
  1095. }
  1096. break;
  1097. case SDP_PATH:
  1098. /* msrp attributes that contain address needed for conversation */
  1099. /* RFC 4975
  1100. * path = path-label ":" path-list
  1101. * path-label = "path"
  1102. * path-list= MSRP-URI *(SP MSRP-URI)
  1103. * MSRP-URI = msrp-scheme "://" authority
  1104. * ["/" session-id] ";" transport *( ";" URI-parameter)
  1105. * ; authority as defined in RFC3986
  1106. *
  1107. * msrp-scheme = "msrp" / "msrps"
  1108. * RFC 3986
  1109. * The authority component is preceded by a double slash ("//") and is terminated by
  1110. * the next slash ("/"), question mark ("?"), or number sign ("#") character, or by
  1111. * the end of the URI.
  1112. */
  1113. /* Check for "msrp://" */
  1114. if (strncmp((char*)attribute_value, msrp_res, strlen(msrp_res)) == 0) {
  1115. int address_offset, port_offset, port_end_offset;
  1116. /* Address starts here */
  1117. address_offset = offset + (int)strlen(msrp_res);
  1118. /* Port is after next ':' */
  1119. port_offset = tvb_find_guint8(tvb, address_offset, -1, ':');
  1120. /* Check if port is present if not skipp */
  1121. if (port_offset!= -1) {
  1122. /* Port ends with '/' */
  1123. port_end_offset = tvb_find_guint8(tvb, port_offset, -1, '/');
  1124. if (port_end_offset == -1) {
  1125. /* No "/" look for the ";" */
  1126. port_end_offset = tvb_find_guint8(tvb, port_offset, -1, ';');;
  1127. }
  1128. /* Attempt to convert address */
  1129. if (inet_pton(AF_INET,
  1130. (char*)tvb_get_ephemeral_string(tvb, address_offset, port_offset-address_offset),
  1131. &media_info->msrp_ipaddr) > 0) {
  1132. /* Get port number */
  1133. media_info->msrp_port_number = atoi((char*)tvb_get_ephemeral_string(tvb, port_offset + 1, port_end_offset - port_offset - 1));
  1134. /* Set flag so this info can be used */
  1135. media_info->msrp_transport_address_set = TRUE;
  1136. }
  1137. }
  1138. }
  1139. break;
  1140. case SDP_H248_ITEM:
  1141. /* Decode h248 item ITU-T Rec. H.248.12 (2001)/Amd.1 (11/2002)*/
  1142. if (strncmp((char*)attribute_value, h324ext_h223lcparm, strlen(msrp_res)) == 0) {
  1143. /* A.5.1.3 H.223 Logical channel parameters
  1144. * This property indicates the H.245
  1145. * H223LogicalChannelsParameters structure encoded by applying the PER specified in
  1146. * ITU-T Rec. X.691. Value encoded as per A.5.1.2. For text encoding the mechanism defined
  1147. * in ITU-T Rec. H.248.15 is used.
  1148. */
  1149. gint len;
  1150. asn1_ctx_t actx;
  1151. len = (gint)strlen(attribute_value);
  1152. h245_tvb = ascii_bytes_to_tvb(tvb, pinfo, len, attribute_value);
  1153. /* arbitrary maximum length */
  1154. /* should go through a handle, however, the two h245 entry
  1155. points are different, one is over tpkt and the other is raw
  1156. */
  1157. if (h245_tvb) {
  1158. asn1_ctx_init(&actx, ASN1_ENC_PER, TRUE, pinfo);
  1159. dissect_h245_H223LogicalChannelParameters(h245_tvb, 0, &actx,
  1160. sdp_media_attribute_tree,
  1161. hf_SDPh223LogicalChannelParameters);
  1162. }
  1163. }
  1164. break;
  1165. case SDP_CRYPTO:
  1166. /* http://tools.ietf.org/html/rfc4568
  1167. * 9.1. Generic "Crypto" Attribute Grammar
  1168. *
  1169. * The ABNF grammar for the crypto attribute is defined below:
  1170. *
  1171. * "a=crypto:" tag 1*WSP crypto-suite 1*WSP key-params
  1172. * *(1*WSP session-param)
  1173. *
  1174. * tag = 1*9DIGIT
  1175. * crypto-suite = 1*(ALPHA / DIGIT / "_")
  1176. *
  1177. * key-params = key-param *(";" key-param)
  1178. * key-param = key-method ":" key-info
  1179. * key-method = "inline" / key-method-ext
  1180. * key-method-ext = 1*(ALPHA / DIGIT / "_")
  1181. * key-info = 1*(%x21-3A / %x3C-7E) ; visible (printing) chars
  1182. * ; except semi-colon
  1183. * session-param = 1*(VCHAR) ; visible (printing) characters
  1184. *
  1185. * where WSP, ALPHA, DIGIT, and VCHAR are defined in [RFC4234].
  1186. *
  1187. */
  1188. /* We are at the first colon */
  1189. /* tag */
  1190. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  1191. if(next_offset==-1){
  1192. /* XXX Add expert item? */
  1193. return;
  1194. }
  1195. tokenlen = next_offset - offset;
  1196. proto_tree_add_uint(sdp_media_attribute_tree, hf_sdp_crypto_tag, tvb, offset, tokenlen,
  1197. atoi((char*)tvb_get_ephemeral_string(tvb, offset, tokenlen)));
  1198. offset = next_offset + 1;
  1199. /* crypto-suite */
  1200. next_offset = tvb_find_guint8(tvb, offset, -1, ' ');
  1201. if(next_offset==-1){
  1202. /* XXX Add expert item? */
  1203. return;
  1204. }
  1205. tokenlen = next_offset - offset;
  1206. parameter_item = proto_tree_add_item(sdp_media_attribute_tree, hf_sdp_crypto_crypto_suite,
  1207. tvb, offset, tokenlen, ENC_ASCII|ENC_NA);
  1208. if (tvb_strncaseeql(tvb, offset, "AES_CM_128_HMAC_SHA1_80", tokenlen) == 0) {
  1209. /* XXX This may only work in simple cases */
  1210. if (transport_info->encryption_algorithm == SRTP_ENC_ALG_NOT_SET) {
  1211. transport_info->encryption_algorithm = SRTP_ENC_ALG_AES_CM;
  1212. transport_info->auth_algorithm = SRTP_AUTH_ALG_HMAC_SHA1;
  1213. /* number of octets used for the Auth Tag in the RTP payload */
  1214. transport_info->auth_tag_len = 10;
  1215. }
  1216. master_key_length = 16; /* 128 bits = 16 octets */
  1217. master_salt_length = 14; /* 112 bits = 14 octets */
  1218. } else if (tvb_strncaseeql(tvb, offset, "AES_CM_128_HMAC_SHA1_32", tokenlen) == 0) {
  1219. /* XXX Thiā€¦

Large files files are truncated, but you can click here to view the full file