diff options
-rw-r--r-- | epan/dissectors/packet-btavdtp.c | 343 | ||||
-rw-r--r-- | epan/dissectors/packet-btavdtp.h | 12 | ||||
-rw-r--r-- | epan/dissectors/packet-hci_h1.c | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-hci_h4.c | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-rtp.c | 272 | ||||
-rw-r--r-- | epan/dissectors/packet-rtp.h | 19 | ||||
-rw-r--r-- | ui/rtp_stream.h | 2 | ||||
-rw-r--r-- | ui/tap-rtp-common.c | 2 |
8 files changed, 534 insertions, 120 deletions
diff --git a/epan/dissectors/packet-btavdtp.c b/epan/dissectors/packet-btavdtp.c index a316080297..b86bfc6af3 100644 --- a/epan/dissectors/packet-btavdtp.c +++ b/epan/dissectors/packet-btavdtp.c @@ -34,6 +34,7 @@ #include "packet-btl2cap.h" #include "packet-btsdp.h" #include "packet-btavdtp.h" +#include "packet-rtp.h" #define AVDTP_MESSAGE_TYPE_MASK 0x03 #define AVDTP_PACKET_TYPE_MASK 0x0C @@ -250,21 +251,58 @@ static wmem_tree_t *sep_open = NULL; static wmem_tree_t *cid_to_type_table = NULL; /* A2DP declarations */ -static int proto_bta2dp = -1; -static gint ett_bta2dp = -1; +static gint proto_bta2dp = -1; +static gint ett_bta2dp = -1; +static gint proto_bta2dp_cph_scms_t = -1; +static gint ett_bta2dp_cph_scms_t = -1; + +static int hf_bta2dp_codec = -1; +static int hf_bta2dp_content_protection = -1; +static int hf_bta2dp_l_bit = -1; +static int hf_bta2dp_cp_bit = -1; +static int hf_bta2dp_reserved = -1; static dissector_handle_t sbc_handle; static dissector_handle_t mp2t_handle; static dissector_handle_t mpeg_audio_handle; static dissector_handle_t atrac_handle; +static gboolean force_a2dp_scms_t = FALSE; +static gint force_a2dp_codec = CODEC_SBC; + +static const enum_val_t pref_a2dp_codec[] = { + { "sbc", "SBC", CODEC_SBC }, + { "mp2t", "MPEG12 AUDIO", CODEC_MPEG12_AUDIO }, + { "mpeg-audio", "MPEG24 AAC", CODEC_MPEG24_AAC }, +/* XXX: Not supported in Wireshark yet { "atrac", "ATRAC", CODEC_ATRAC },*/ + { NULL, NULL, 0 } +}; + + /* VDP declarations */ -static int proto_btvdp = -1; -static gint ett_btvdp = -1; +static gint proto_btvdp = -1; +static gint ett_btvdp = -1; +static gint proto_btvdp_cph_scms_t = -1; +static gint ett_btvdp_cph_scms_t = -1; + +static int hf_btvdp_codec = -1; +static int hf_btvdp_content_protection = -1; +static int hf_btvdp_l_bit = -1; +static int hf_btvdp_cp_bit = -1; +static int hf_btvdp_reserved = -1; static dissector_handle_t h263_handle; static dissector_handle_t mp4v_es_handle; +static gboolean force_vdp_scms_t = FALSE; +static gint force_vdp_codec = CODEC_H263_BASELINE; + +static const enum_val_t pref_vdp_codec[] = { + { "h263", "H263", CODEC_H263_BASELINE }, + { "mp4v-es", "MPEG4 VSP", CODEC_MPEG4_VSP }, + { NULL, NULL, 0 } +}; + static const value_string message_type_vals[] = { { 0x00, "Command" }, @@ -392,6 +430,12 @@ static const value_string media_codec_video_type_vals[] = { { 0, NULL } }; +static const value_string content_protection_type_vals[] = { + { 0x01, "DTCP" }, + { 0x02, "SCMS-T" }, + { 0, NULL } +}; + extern value_string_ext bthci_evt_comp_id_ext; enum sep_state { @@ -405,6 +449,7 @@ typedef struct _sep_entry_t { guint8 type; guint8 media_type; gint codec; + gint content_protection_type; enum sep_state state; } sep_entry_t; @@ -414,12 +459,20 @@ typedef struct _cid_type_data_t { sep_entry_t *sep; } cid_type_data_t; + +typedef struct _sep_data_t { + gint codec; + gint content_protection_type; +} sep_data_t; + void proto_register_btavdtp(void); void proto_reg_handoff_btavdtp(void); void proto_register_bta2dp(void); void proto_reg_handoff_bta2dp(void); +void proto_register_bta2dp_content_protection_header_scms_t(void); void proto_register_btvdp(void); void proto_reg_handoff_btvdp(void); +void proto_register_btvdp_content_protection_header_scms_t(void); static const char * get_sep_type(guint32 frame_number, guint seid) @@ -527,6 +580,7 @@ dissect_sep(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset) sep_data->seid = seid; sep_data->type = type; sep_data->codec = -1; + sep_data->content_protection_type = 0; sep_data->media_type = media_type; if (in_use) { sep_data->state = SEP_STATE_IN_USE; @@ -700,7 +754,8 @@ dissect_codec(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, static gint dissect_capabilities(tvbuff_t *tvb, packet_info *pinfo, - proto_tree *tree, gint offset, gint *codec) + proto_tree *tree, gint offset, gint *codec, + gint *content_protection_type) { proto_item *pitem = NULL; proto_item *ptree = NULL; @@ -805,13 +860,19 @@ dissect_capabilities(tvbuff_t *tvb, packet_info *pinfo, losc = 0; break; case SERVICE_CATEGORY_CONTENT_PROTECTION: + /* ENC_LITTLE_ENDIAN is correct here... */ proto_tree_add_item(service_tree, hf_btavdtp_content_protection_type, tvb, offset, 2, ENC_LITTLE_ENDIAN); + if (content_protection_type) { + *content_protection_type = tvb_get_letohs(tvb, offset); + } offset += 2; losc -= 2; - proto_tree_add_item(service_tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA); - offset += losc; - losc = 0; + if (losc > 0) { + proto_tree_add_item(service_tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA); + offset += losc; + losc = 0; + } break; case SERVICE_CATEGORY_HEADER_COMPRESSION: proto_tree_add_item(service_tree, hf_btavdtp_header_compression_backch, tvb, offset, 1, ENC_BIG_ENDIAN); @@ -950,7 +1011,8 @@ dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) tvbuff_t *next_tvb; guint32 seid; guint32 t_seid; - gint codec; + gint codec = -1; + gint content_protection_type = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "AVDTP"); @@ -1047,11 +1109,21 @@ dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) get_sep_type(pinfo->fd->num, cid_type_data->sep->seid)); if (cid_type_data->sep->media_type == MEDIA_TYPE_AUDIO) { + sep_data_t sep_data; + + sep_data.codec = cid_type_data->sep->codec; + sep_data.content_protection_type = cid_type_data->sep->content_protection_type; + next_tvb = tvb_new_subset_remaining(tvb, offset); - call_dissector_with_data(bta2dp_handle, next_tvb, pinfo, tree, &cid_type_data->sep->codec); + call_dissector_with_data(bta2dp_handle, next_tvb, pinfo, tree, &sep_data); } else if (cid_type_data->sep->media_type == MEDIA_TYPE_VIDEO) { + sep_data_t sep_data; + + sep_data.codec = cid_type_data->sep->codec; + sep_data.content_protection_type = cid_type_data->sep->content_protection_type; + next_tvb = tvb_new_subset_remaining(tvb, offset); - call_dissector_with_data(btvdp_handle, next_tvb, pinfo, tree, &cid_type_data->sep->codec); + call_dissector_with_data(btvdp_handle, next_tvb, pinfo, tree, &sep_data); } else { ti = proto_tree_add_item(tree, proto_btavdtp, tvb, offset, -1, ENC_NA); btavdtp_tree = proto_item_add_subtree(ti, ett_btavdtp); @@ -1129,13 +1201,13 @@ dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_BIG_ENDIAN); break; } - offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, NULL); + offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, NULL, NULL); break; case SIGNAL_ID_SET_CONFIGURATION: if (message_type == MESSAGE_TYPE_COMMAND) { offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset, SEID_ACP, 0, &seid); offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset, SEID_INT, 0, NULL); - offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, &codec); + offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, &codec, &content_protection_type); t_frame_number = pinfo->fd->num; t_seid = seid; @@ -1150,6 +1222,7 @@ dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) sep = (sep_entry_t *)wmem_tree_lookup32_array_le(sep_list, key); if (sep && sep->seid == seid) { sep->codec = codec; + sep->content_protection_type = content_protection_type; } break; @@ -1170,12 +1243,12 @@ dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_BIG_ENDIAN); break; } - offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, NULL); + offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, NULL, NULL); break; case SIGNAL_ID_RECONFIGURE: if (message_type == MESSAGE_TYPE_COMMAND) { offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset, SEID_ACP, 0, &seid); - offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, &codec); + offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, &codec, &content_protection_type); t_frame_number = pinfo->fd->num; t_seid = seid; @@ -1190,6 +1263,7 @@ dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) sep = (sep_entry_t *)wmem_tree_lookup32_array_le(sep_list, key); if (sep && sep->seid == seid) { sep->codec = codec; + sep->content_protection_type = content_protection_type; } break; @@ -1504,7 +1578,7 @@ proto_register_btavdtp(void) }, { &hf_btavdtp_content_protection_type, { "Type", "btavdtp.content_protection_type", - FT_UINT16, BASE_HEX, NULL, 0x0000, + FT_UINT16, BASE_HEX, VALS(content_protection_type_vals), 0x0000, NULL, HFILL } }, { &hf_btavdtp_media_codec_media_type, @@ -2013,14 +2087,28 @@ dissect_bta2dp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) proto_item *ti; proto_tree *bta2dp_tree; proto_item *pitem; - gint offset = 0; - gint codec = -1; - void *save_private_data; - dissector_handle_t codec_dissector = NULL; - btavdtp_data_t *btavdtp_data; - - if (data) - codec = *((gint *) data); + gint offset = 0; + dissector_handle_t codec_dissector = NULL; + bta2dp_codec_info_t bta2dp_codec_info; + sep_data_t sep_data; + + sep_data.codec = CODEC_SBC; + sep_data.content_protection_type = 0; + + if (force_a2dp_scms_t || force_a2dp_codec) { + if (force_a2dp_scms_t) + sep_data.content_protection_type = 2; + else if (data) + sep_data.content_protection_type = ((sep_data_t *) data)->content_protection_type; + + if (force_a2dp_codec) + sep_data.codec = force_a2dp_codec; + else if (data) + sep_data.codec = ((sep_data_t *) data)->codec; + } else { + if (data) + sep_data = *((sep_data_t *) data); + } col_set_str(pinfo->cinfo, COL_PROTOCOL, "A2DP"); @@ -2046,15 +2134,19 @@ dissect_bta2dp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) ti = proto_tree_add_item(tree, proto_bta2dp, tvb, offset, -1, ENC_NA); col_append_fstr(pinfo->cinfo, COL_INFO, "Audio stream - %s", - val_to_str_const(codec, media_codec_audio_type_vals, "unknown codec")); + val_to_str_const(sep_data.codec, media_codec_audio_type_vals, "unknown codec")); bta2dp_tree = proto_item_add_subtree(ti, ett_bta2dp); - pitem = proto_tree_add_text(bta2dp_tree, tvb, offset, tvb_length_remaining(tvb, offset), "Codec: %s", - val_to_str_const(codec, media_codec_audio_type_vals, "unknown codec")); + pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_codec, tvb, offset, 0, sep_data.codec); PROTO_ITEM_SET_GENERATED(pitem); - switch (codec) { + if (sep_data.content_protection_type > 0) { + pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_content_protection, tvb, offset, 0, sep_data.content_protection_type); + PROTO_ITEM_SET_GENERATED(pitem); + } + + switch (sep_data.codec) { case CODEC_SBC: codec_dissector = sbc_handle; break; @@ -2069,18 +2161,13 @@ dissect_bta2dp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) break; } - save_private_data = pinfo->private_data; - - btavdtp_data = wmem_new(wmem_packet_scope(), btavdtp_data_t); - btavdtp_data->codec_dissector = codec_dissector; - - pinfo->private_data = btavdtp_data; + bta2dp_codec_info.codec_dissector = codec_dissector; + bta2dp_codec_info.content_protection_type = sep_data.content_protection_type; + bluetooth_add_address(pinfo, &pinfo->net_dst, "BT A2DP", pinfo->fd->num, FALSE, &bta2dp_codec_info); call_dissector(rtp_handle, tvb, pinfo, tree); offset += tvb_length_remaining(tvb, offset); - pinfo->private_data = save_private_data; - return offset; } @@ -2088,7 +2175,7 @@ void proto_register_bta2dp(void) { module_t *module; -#if 0 + static hf_register_info hf[] = { { &hf_bta2dp_codec, { "Codec", "bta2dp.codec", @@ -2101,16 +2188,13 @@ proto_register_bta2dp(void) NULL, HFILL } } }; -#endif static gint *ett[] = { &ett_bta2dp }; proto_bta2dp = proto_register_protocol("Bluetooth A2DP Profile", "BT A2DP", "bta2dp"); -#if 0 proto_register_field_array(proto_bta2dp, hf, array_length(hf)); -#endif proto_register_subtree_array(ett, array_length(ett)); new_register_dissector("bta2dp", dissect_bta2dp, proto_bta2dp); @@ -2119,6 +2203,16 @@ proto_register_bta2dp(void) prefs_register_static_text_preference(module, "a2dp.version", "Bluetooth Profile A2DP version: 1.3", "Version of profile supported by this dissector."); + + prefs_register_bool_preference(module, "a2dp.content_protection.scms_t", + "Force SCMS-T decoding", + "Force decoding stream as A2DP with Content Protection SCMS-T ", + &force_a2dp_scms_t); + + prefs_register_enum_preference(module, "a2dp.codec", + "Force codec", + "Force decoding stream as A2DP with specified codec", + &force_a2dp_codec, pref_a2dp_codec, FALSE); } void @@ -2139,21 +2233,34 @@ proto_reg_handoff_bta2dp(void) dissector_add_handle("btl2cap.cid", bta2dp_handle); } - static gint dissect_btvdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { proto_item *ti; proto_tree *btvdp_tree; proto_item *pitem; - gint offset = 0; - gint codec = -1; - void *save_private_data; - dissector_handle_t codec_dissector = NULL; - btavdtp_data_t *btavdtp_data; - - if (data) - codec = *((gint *) data); + gint offset = 0; + dissector_handle_t codec_dissector = NULL; + btvdp_codec_info_t btvdp_codec_info; + sep_data_t sep_data; + + sep_data.codec = CODEC_H263_BASELINE; + sep_data.content_protection_type = 0; + + if (force_vdp_scms_t || force_vdp_codec) { + if (force_vdp_scms_t) + sep_data.content_protection_type = 2; + else if (data) + sep_data.content_protection_type = ((sep_data_t *) data)->content_protection_type; + + if (force_vdp_codec) + sep_data.codec = force_vdp_codec; + else if (data) + sep_data.codec = ((sep_data_t *) data)->codec; + } else { + if (data) + sep_data = *((sep_data_t *) data); + } col_set_str(pinfo->cinfo, COL_PROTOCOL, "VDP"); @@ -2179,15 +2286,19 @@ dissect_btvdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) ti = proto_tree_add_item(tree, proto_btvdp, tvb, offset, -1, ENC_NA); col_append_fstr(pinfo->cinfo, COL_INFO, "Video stream - %s", - val_to_str_const(codec, media_codec_video_type_vals, "unknown codec")); + val_to_str_const(sep_data.codec, media_codec_video_type_vals, "unknown codec")); btvdp_tree = proto_item_add_subtree(ti, ett_btvdp); - pitem = proto_tree_add_text(btvdp_tree, tvb, offset, tvb_length_remaining(tvb, offset), "Codec: %s", - val_to_str_const(codec, media_codec_video_type_vals, "unknown codec")); + pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_codec, tvb, offset, 0, sep_data.codec); PROTO_ITEM_SET_GENERATED(pitem); - switch (codec) { + if (sep_data.content_protection_type > 0) { + pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_content_protection, tvb, offset, 0, sep_data.content_protection_type); + PROTO_ITEM_SET_GENERATED(pitem); + } + + switch (sep_data.codec) { case CODEC_H263_BASELINE: case CODEC_H263_PROFILE_3: case CODEC_H263_PROFILE_8: @@ -2198,18 +2309,13 @@ dissect_btvdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) break; } - save_private_data = pinfo->private_data; - - btavdtp_data = wmem_new(wmem_packet_scope(), btavdtp_data_t); - btavdtp_data->codec_dissector = codec_dissector; - - pinfo->private_data = btavdtp_data; + btvdp_codec_info.codec_dissector = codec_dissector; + btvdp_codec_info.content_protection_type = sep_data.content_protection_type; + bluetooth_add_address(pinfo, &pinfo->net_dst, "BT VDP", pinfo->fd->num, TRUE, &btvdp_codec_info); call_dissector(rtp_handle, tvb, pinfo, tree); offset += tvb_length_remaining(tvb, offset); - pinfo->private_data = save_private_data; - return offset; } @@ -2219,7 +2325,6 @@ proto_register_btvdp(void) module_t *module; expert_module_t* expert_btavdtp; -#if 0 static hf_register_info hf[] = { { &hf_btvdp_codec, { "Codec", "btvdp.codec", @@ -2232,7 +2337,6 @@ proto_register_btvdp(void) NULL, HFILL } } }; -#endif static gint *ett[] = { &ett_btvdp @@ -2246,9 +2350,7 @@ proto_register_btvdp(void) proto_btvdp = proto_register_protocol("Bluetooth VDP Profile", "BT VDP", "btvdp"); new_register_dissector("btvdp", dissect_btvdp, proto_btvdp); -#if 0 proto_register_field_array(proto_bta2dp, hf, array_length(hf)); -#endif proto_register_subtree_array(ett, array_length(ett)); expert_btavdtp = expert_register_protocol(proto_btvdp); expert_register_field_array(expert_btavdtp, ei, array_length(ei)); @@ -2257,6 +2359,16 @@ proto_register_btvdp(void) prefs_register_static_text_preference(module, "vdp.version", "Bluetooth Profile VDP version: 1.1", "Version of profile supported by this dissector."); + + prefs_register_bool_preference(module, "vdp.content_protection.scms_t", + "Force SCMS-T decoding", + "Force decoding stream as VDP with Content Protection SCMS-T ", + &force_vdp_scms_t); + + prefs_register_enum_preference(module, "vdp.codec", + "Force codec", + "Force decoding stream as VDP with specified codec", + &force_vdp_codec, pref_vdp_codec, FALSE); } void @@ -2275,6 +2387,107 @@ proto_reg_handoff_btvdp(void) } + +static gint +dissect_a2dp_cp_scms_t(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) +{ + proto_item *main_item; + proto_tree *main_tree; + gint offset = 0; + + main_item = proto_tree_add_item(tree, proto_bta2dp_cph_scms_t, tvb, offset, 1, ENC_NA); + main_tree = proto_item_add_subtree(main_item, ett_bta2dp_cph_scms_t); + + proto_tree_add_item(main_tree, hf_bta2dp_reserved , tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(main_tree, hf_bta2dp_cp_bit, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(main_tree, hf_bta2dp_l_bit , tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + + return offset; +} + +void +proto_register_bta2dp_content_protection_header_scms_t(void) +{ + static hf_register_info hf[] = { + { &hf_bta2dp_l_bit, + { "L-bit", "bta2dp.content_protection_header.scms_t.l_bit", + FT_BOOLEAN, 8, NULL, 0x01, + NULL, HFILL } + }, + { &hf_bta2dp_cp_bit, + { "Cp-bit", "bta2dp.content_protection_header.scms_t.cp_bit", + FT_BOOLEAN, 8, NULL, 0x02, + NULL, HFILL } + }, + { &hf_bta2dp_reserved, + { "Reserved", "bta2dp.content_protection_header.scms_t.reserved", + FT_BOOLEAN, 8, NULL, 0xFC, + NULL, HFILL } + } + }; + + static gint *ett[] = { + &ett_bta2dp_cph_scms_t + }; + + proto_bta2dp_cph_scms_t = proto_register_protocol("Bluetooth A2DP Content Protection Header SCMS-T", "BT A2DP Content Protection Header SCMS-T", "bta2dp_content_protection_header_scms_t"); + proto_register_field_array(proto_bta2dp_cph_scms_t, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + new_register_dissector("bta2dp_content_protection_header_scms_t", dissect_a2dp_cp_scms_t, proto_bta2dp_cph_scms_t); +} + +static gint +dissect_vdp_cp_scms_t(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) +{ + proto_item *main_item; + proto_tree *main_tree; + gint offset = 0; + + main_item = proto_tree_add_item(tree, proto_btvdp_cph_scms_t, tvb, offset, 1, ENC_NA); + main_tree = proto_item_add_subtree(main_item, ett_btvdp_cph_scms_t); + + proto_tree_add_item(main_tree, hf_btvdp_reserved , tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(main_tree, hf_btvdp_cp_bit, tvb, offset, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(main_tree, hf_btvdp_l_bit , tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + + return offset; +} + +void +proto_register_btvdp_content_protection_header_scms_t(void) +{ + static hf_register_info hf[] = { + { &hf_btvdp_l_bit, + { "L-bit", "btvdp.content_protection_header.scms_t.l_bit", + FT_BOOLEAN, 8, NULL, 0x01, + NULL, HFILL } + }, + { &hf_btvdp_cp_bit, + { "Cp-bit", "btvdp.content_protection_header.scms_t.cp_bit", + FT_BOOLEAN, 8, NULL, 0x02, + NULL, HFILL } + }, + { &hf_btvdp_reserved, + { "Reserved", "btvdp.content_protection_header.scms_t.reserved", + FT_BOOLEAN, 8, NULL, 0xFC, + NULL, HFILL } + } + }; + + static gint *ett[] = { + &ett_btvdp_cph_scms_t + }; + + proto_btvdp_cph_scms_t = proto_register_protocol("Bluetooth VDP Content Protection Header SCMS-T", "BT VDP Content Protection Header SCMS-T", "btvdp_content_protection_header_scms_t"); + proto_register_field_array(proto_btvdp_cph_scms_t, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + new_register_dissector("btvdp_content_protection_header_scms_t", dissect_vdp_cp_scms_t, proto_btvdp_cph_scms_t); +} + /* * Editor modelines - http://www.wireshark.org/tools/modelines.html * diff --git a/epan/dissectors/packet-btavdtp.h b/epan/dissectors/packet-btavdtp.h index c847571332..0fa9cb4e26 100644 --- a/epan/dissectors/packet-btavdtp.h +++ b/epan/dissectors/packet-btavdtp.h @@ -27,9 +27,17 @@ #ifndef __PACKET_BTAVDTP_H__ #define __PACKET_BTAVDTP_H__ -typedef struct _btavdtp_data_t { +#define BTAVDTP_CONTENT_PROTECTION_TYPE_SCMS_T 0x02 + +typedef struct _bta2dp_codec_info_t { + dissector_handle_t codec_dissector; + gint content_protection_type; +} bta2dp_codec_info_t; + +typedef struct _btvdp_codec_info_t { dissector_handle_t codec_dissector; -} btavdtp_data_t; + gint content_protection_type; +} btvdp_codec_info_t; #endif diff --git a/epan/dissectors/packet-hci_h1.c b/epan/dissectors/packet-hci_h1.c index f0200b7261..a72657f6b9 100644 --- a/epan/dissectors/packet-hci_h1.c +++ b/epan/dissectors/packet-hci_h1.c @@ -114,6 +114,8 @@ dissect_hci_h1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _ hci_data->localhost_bdaddr = localhost_bdaddr; hci_data->localhost_name = localhost_name; + pinfo->ptype = PT_BLUETOOTH; + ti = proto_tree_add_int(hci_h1_tree, hf_hci_h1_direction, tvb, 0, 0, pinfo->p2p_dir); PROTO_ITEM_SET_GENERATED(ti); diff --git a/epan/dissectors/packet-hci_h4.c b/epan/dissectors/packet-hci_h4.c index 655a8f9ecb..1b79e3e508 100644 --- a/epan/dissectors/packet-hci_h4.c +++ b/epan/dissectors/packet-hci_h4.c @@ -110,6 +110,8 @@ dissect_hci_h4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _ hci_data->localhost_bdaddr = localhost_bdaddr; hci_data->localhost_name = localhost_name; + pinfo->ptype = PT_BLUETOOTH; + ti = proto_tree_add_uint(hci_h4_tree, hf_hci_h4_direction, tvb, 0, 0, pinfo->p2p_dir); PROTO_ITEM_SET_GENERATED(ti); diff --git a/epan/dissectors/packet-rtp.c b/epan/dissectors/packet-rtp.c index bb4aa81c5a..1f4b04375d 100644 --- a/epan/dissectors/packet-rtp.c +++ b/epan/dissectors/packet-rtp.c @@ -61,11 +61,12 @@ #include <epan/packet.h> #include "packet-rtp.h" + #include <epan/rtp_pt.h> #include <epan/conversation.h> #include <epan/reassemble.h> #include <epan/tap.h> - +#include <epan/epan_dissect.h> #include <epan/prefs.h> #include <epan/wmem/wmem.h> #include <epan/strutil.h> @@ -142,6 +143,12 @@ static dissector_handle_t zrtp_handle; static dissector_handle_t sprt_handle; static dissector_handle_t v150fw_handle; +static dissector_handle_t bta2dp_content_protection_header_scms_t; +static dissector_handle_t btvdp_content_protection_header_scms_t; +static dissector_handle_t bta2dp_handle; +static dissector_handle_t btvdp_handle; +static dissector_handle_t sbc_handle; + static int rtp_tap = -1; static dissector_table_t rtp_pt_dissector_table; @@ -266,11 +273,12 @@ static gint global_rtp_version0_type = 0; static dissector_handle_t data_handle; /* Forward declaration we need below */ +void proto_register_rtp(void); void proto_reg_handoff_rtp(void); +void proto_register_pkt_ccc(void); void proto_reg_handoff_pkt_ccc(void); -static void dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, - proto_tree *tree ); +static gint dissect_rtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data); static void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); static void get_conv_info(packet_info *pinfo, struct _rtp_info *rtp_info); @@ -806,12 +814,94 @@ rtp_free_hash_dyn_payload(GHashTable *rtp_dyn_payload) rtp_dyn_payload = NULL; } + +void +bluetooth_add_address(packet_info *pinfo, address *addr, + const gchar *setup_method, guint32 setup_frame_number, + gboolean is_video, void *data) +{ + address null_addr; + conversation_t* p_conv; + struct _rtp_conversation_info *p_conv_data = NULL; + /* + * If this isn't the first time this packet has been processed, + * we've already done this work, so we don't need to do it + * again. + */ + if (pinfo->fd->flags.visited) + { + return; + } + + SET_ADDRESS(&null_addr, AT_NONE, 0, NULL); + + /* + * Check if the ip address and port combination is not + * already registered as a conversation. + */ + p_conv = find_conversation(setup_frame_number, addr, &null_addr, PT_BLUETOOTH, 0, 0, + NO_ADDR_B | NO_PORT_B); + + /* + * If not, create a new conversation. + */ + if (!p_conv || p_conv->setup_frame != setup_frame_number) { + p_conv = conversation_new(setup_frame_number, addr, &null_addr, PT_BLUETOOTH, 0, 0, + NO_ADDR2 | NO_PORT2); + } + + /* Set dissector */ + conversation_set_dissector(p_conv, rtp_handle); + + /* + * Check if the conversation has data associated with it. + */ + p_conv_data = (struct _rtp_conversation_info *)conversation_get_proto_data(p_conv, proto_rtp); + + /* + * If not, add a new data item. + */ + if (! p_conv_data) { + /* Create conversation data */ + p_conv_data = wmem_new(wmem_file_scope(), struct _rtp_conversation_info); + p_conv_data->rtp_dyn_payload = NULL; + + /* start this at 0x10000 so that we cope gracefully with the + * first few packets being out of order (hence 0,65535,1,2,...) + */ + p_conv_data->extended_seqno = 0x10000; + p_conv_data->rtp_conv_info = wmem_new(wmem_file_scope(), rtp_private_conv_info); + p_conv_data->rtp_conv_info->multisegment_pdus = wmem_tree_new(wmem_file_scope()); + conversation_add_proto_data(p_conv, proto_rtp, p_conv_data); + + if (is_video) { + p_conv_data->bta2dp_info = NULL; + p_conv_data->btvdp_info = (btvdp_codec_info_t *) wmem_memdup(wmem_file_scope(), data, sizeof(btvdp_codec_info_t)); + } else { + p_conv_data->bta2dp_info = (bta2dp_codec_info_t *) wmem_memdup(wmem_file_scope(), data, sizeof(bta2dp_codec_info_t)); + p_conv_data->btvdp_info = NULL; + } + } + + /* + * Update the conversation data. + */ + /* Free the hash if already exists */ + rtp_free_hash_dyn_payload(p_conv_data->rtp_dyn_payload); + + g_strlcpy(p_conv_data->method, setup_method, MAX_RTP_SETUP_METHOD_SIZE+1); + p_conv_data->frame_number = setup_frame_number; + p_conv_data->is_video = is_video; + p_conv_data->rtp_dyn_payload = NULL; + p_conv_data->srtp_info = NULL; +} + /* Set up an SRTP conversation */ void srtp_add_address(packet_info *pinfo, address *addr, int port, int other_port, const gchar *setup_method, guint32 setup_frame_number, gboolean is_video _U_, GHashTable *rtp_dyn_payload, - struct srtp_info *srtp_info) + struct srtp_info *srtp_info) { address null_addr; conversation_t* p_conv; @@ -887,6 +977,8 @@ srtp_add_address(packet_info *pinfo, address *addr, int port, int other_port, p_conv_data->is_video = is_video; p_conv_data->rtp_dyn_payload = rtp_dyn_payload; p_conv_data->srtp_info = srtp_info; + p_conv_data->bta2dp_info = NULL; + p_conv_data->btvdp_info = NULL; } /* Set up an RTP conversation */ @@ -899,7 +991,7 @@ rtp_add_address(packet_info *pinfo, address *addr, int port, int other_port, } static gboolean -dissect_rtp_heur_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean check_destport) +dissect_rtp_heur_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, gboolean check_destport) { guint8 octet1; unsigned int version; @@ -954,20 +1046,20 @@ dissect_rtp_heur_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gbo return FALSE; } - dissect_rtp( tvb, pinfo, tree ); + dissect_rtp( tvb, pinfo, tree, data ); return TRUE; } static gboolean -dissect_rtp_heur_udp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_ ) +dissect_rtp_heur_udp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data ) { - return dissect_rtp_heur_common(tvb, pinfo, tree, TRUE); + return dissect_rtp_heur_common(tvb, pinfo, tree, data, TRUE); } static gboolean -dissect_rtp_heur_stun( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_ ) +dissect_rtp_heur_stun( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data ) { - return dissect_rtp_heur_common(tvb, pinfo, tree, FALSE); + return dissect_rtp_heur_common(tvb, pinfo, tree, data, FALSE); } /* @@ -975,14 +1067,13 @@ dissect_rtp_heur_stun( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void */ static void process_rtp_payload(tvbuff_t *newtvb, packet_info *pinfo, proto_tree *tree, - proto_tree *rtp_tree, - unsigned int payload_type) + proto_tree *rtp_tree, unsigned int payload_type) { struct _rtp_conversation_info *p_conv_data = NULL; gboolean found_match = FALSE; int payload_len; struct srtp_info *srtp_info; - int offset=0; + int offset = 0; payload_len = tvb_length_remaining(newtvb, offset); @@ -1015,10 +1106,9 @@ process_rtp_payload(tvbuff_t *newtvb, packet_info *pinfo, proto_tree *tree, proto_tree_add_item(rtp_tree, hf_srtp_auth_tag, newtvb, offset, srtp_info->auth_tag_len, ENC_NA); /*offset += srtp_info->auth_tag_len;*/ } - } - - /* if the payload type is dynamic, we check if the conv is set and we look for the pt definition */ - else if ( (payload_type >= PT_UNDF_96 && payload_type <= PT_UNDF_127) ) { + } else if (p_conv_data && !p_conv_data->bta2dp_info && !p_conv_data->btvdp_info && + payload_type >= PT_UNDF_96 && payload_type <= PT_UNDF_127) { + /* if the payload type is dynamic, we check if the conv is set and we look for the pt definition */ if (p_conv_data && p_conv_data->rtp_dyn_payload) { gchar *payload_type_str = NULL; encoding_name_and_rate_t *encoding_name_and_rate_pt = NULL; @@ -1041,6 +1131,34 @@ process_rtp_payload(tvbuff_t *newtvb, packet_info *pinfo, proto_tree *tree, } } + } else if (p_conv_data && p_conv_data->bta2dp_info) { + tvbuff_t *nexttvb; + gint suboffset = 0; + + found_match = TRUE; + + if (p_conv_data->bta2dp_info->content_protection_type == BTAVDTP_CONTENT_PROTECTION_TYPE_SCMS_T) { + nexttvb = tvb_new_subset(newtvb, 0, 1, 1); + call_dissector(bta2dp_content_protection_header_scms_t, nexttvb, pinfo, tree); + suboffset = 1; + } + + nexttvb = tvb_new_subset_remaining(newtvb, suboffset); + call_dissector(p_conv_data->bta2dp_info->codec_dissector, nexttvb, pinfo, tree); + } else if (p_conv_data && p_conv_data->btvdp_info) { + tvbuff_t *nexttvb; + gint suboffset = 0; + + found_match = TRUE; + + if (p_conv_data->btvdp_info->content_protection_type == BTAVDTP_CONTENT_PROTECTION_TYPE_SCMS_T) { + nexttvb = tvb_new_subset(newtvb, 0, 1, 1); + call_dissector(bta2dp_content_protection_header_scms_t, nexttvb, pinfo, tree); + suboffset = 1; + } + + nexttvb = tvb_new_subset_remaining(newtvb, suboffset); + call_dissector(p_conv_data->btvdp_info->codec_dissector, nexttvb, pinfo, tree); } /* if we don't found, it is static OR could be set static from the preferences */ @@ -1265,7 +1383,7 @@ dissect_rtp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, static void dissect_rtp_rfc2198(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { - int offset = 0; + gint offset = 0; guint8 octet1; int cnt; gboolean hdr_follow = TRUE; @@ -1355,7 +1473,7 @@ dissect_rtp_rfc2198(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) static void dissect_rtp_hext_rfc5215_onebyte( tvbuff_t *tvb, packet_info *pinfo, - proto_tree *rtp_hext_tree ) + proto_tree *rtp_hext_tree ) { proto_item *ti = NULL; proto_tree *rtp_hext_rfc5285_tree = NULL; @@ -1409,7 +1527,7 @@ dissect_rtp_hext_rfc5215_onebyte( tvbuff_t *tvb, packet_info *pinfo, static void dissect_rtp_hext_rfc5215_twobytes(tvbuff_t *parent_tvb, guint id_offset, - guint8 id, tvbuff_t *tvb, packet_info *pinfo, proto_tree *rtp_hext_tree) + guint8 id, tvbuff_t *tvb, packet_info *pinfo, proto_tree *rtp_hext_tree) { proto_item *ti = NULL; proto_tree *rtp_hext_rfc5285_tree = NULL; @@ -1454,8 +1572,8 @@ dissect_rtp_hext_rfc5215_twobytes(tvbuff_t *parent_tvb, guint id_offset, } } -static void -dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) +static gint +dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { proto_item *ti = NULL; proto_tree *volatile rtp_tree = NULL; @@ -1485,8 +1603,8 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) /*struct srtp_info *srtp_info = NULL;*/ /*unsigned int srtp_offset;*/ unsigned int hdrext_offset = 0; - tvbuff_t *newtvb = NULL; - + tvbuff_t *newtvb = NULL; + const char *pt = NULL; /* Can tap up to 4 RTP packets within same packet */ static struct _rtp_info rtp_info_arr[4]; static int rtp_info_current=0; @@ -1506,24 +1624,24 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) switch (global_rtp_version0_type) { case RTP0_STUN: call_dissector(stun_handle, tvb, pinfo, tree); - return; + return tvb_length(tvb); case RTP0_CLASSICSTUN: call_dissector(classicstun_handle, tvb, pinfo, tree); - return; + return tvb_length(tvb); case RTP0_T38: call_dissector(t38_handle, tvb, pinfo, tree); - return; + return tvb_length(tvb); case RTP0_SPRT: call_dissector(sprt_handle, tvb, pinfo, tree); - return; + return tvb_length(tvb); case RTP0_INVALID: if (!(tvb_memeql(tvb, 4, "ZRTP", 4))) { call_dissector(zrtp_handle,tvb,pinfo,tree); - return; + return tvb_length(tvb); } default: ; /* Unknown or unsupported version (let it fall through) */ @@ -1548,7 +1666,7 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) proto_tree_add_uint( rtp_tree, hf_rtp_version, tvb, offset, 1, octet1); } - return; + return offset; } padding_set = RTP_PADDING( octet1 ); @@ -1636,6 +1754,12 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) } #endif + if (p_conv_data && p_conv_data->bta2dp_info && p_conv_data->bta2dp_info->codec_dissector) { + rtp_info->info_payload_type_str = (const char *) dissector_handle_get_short_name(p_conv_data->bta2dp_info->codec_dissector); + } else if (p_conv_data && p_conv_data->btvdp_info && p_conv_data->btvdp_info->codec_dissector) { + rtp_info->info_payload_type_str = (const char *) dissector_handle_get_short_name(p_conv_data->btvdp_info->codec_dissector); + } + /* if it is dynamic payload, let use the conv data to see if it is defined */ if ( (payload_type>95) && (payload_type<128) ) { if (p_conv_data && p_conv_data->rtp_dyn_payload){ @@ -1648,15 +1772,22 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) } } + if (p_conv_data && p_conv_data->bta2dp_info) { + pt = (p_conv_data->bta2dp_info->codec_dissector) ? dissector_handle_get_short_name(p_conv_data->bta2dp_info->codec_dissector) : "Unknown"; + } else if (p_conv_data && p_conv_data->btvdp_info) { + pt = (p_conv_data->btvdp_info->codec_dissector) ? dissector_handle_get_short_name(p_conv_data->btvdp_info->codec_dissector) : "Unknown"; + } else { + pt = (payload_type_str ? payload_type_str : val_to_str_ext(payload_type, &rtp_payload_type_vals_ext,"Unknown (%u)")); + } + col_add_fstr( pinfo->cinfo, COL_INFO, "PT=%s, SSRC=0x%X, Seq=%u, Time=%u%s", - payload_type_str ? payload_type_str : val_to_str_ext( payload_type, &rtp_payload_type_vals_ext,"Unknown (%u)" ), + pt, sync_src, seq_num, timestamp, marker_set ? ", Mark" : ""); - if ( tree ) { proto_tree *item; /* Create RTP protocol tree */ @@ -1682,10 +1813,8 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) proto_tree_add_boolean( rtp_tree, hf_rtp_marker, tvb, offset, 1, octet2 ); - proto_tree_add_uint_format_value( rtp_tree, hf_rtp_payload_type, tvb, - offset, 1, octet2, "%s (%u)", - payload_type_str ? payload_type_str : val_to_str_ext_const( payload_type, &rtp_payload_type_vals_ext,"Unknown"), - payload_type); + proto_tree_add_uint_format( rtp_tree, hf_rtp_payload_type, tvb, + offset, 1, octet2, "Payload type: %s (%u)", pt, payload_type); offset++; @@ -1714,7 +1843,7 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) proto_item_append_text(ti, " (%u items)", csrc_count); rtp_csrc_tree = proto_item_add_subtree( ti, ett_csrc_list ); - for (i = 0; i < csrc_count; i++ ) { + for (i = 0; i < csrc_count; i++ ) { csrc_item = tvb_get_ntohl( tvb, offset ); proto_tree_add_uint_format( rtp_csrc_tree, hf_rtp_csrc_item, tvb, offset, 4, @@ -1788,7 +1917,7 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo, rtp_tree); - return; + return tvb_length(tvb);; } padding_count = tvb_get_guint8( tvb, @@ -1800,6 +1929,24 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) rtp_info->info_payload_len = tvb_length_remaining(tvb, offset); rtp_info->info_padding_count = padding_count; + if (p_conv_data && p_conv_data->bta2dp_info) { + if (p_conv_data->bta2dp_info->codec_dissector == sbc_handle) { + rtp_info->info_payload_offset += 1; + rtp_info->info_payload_len -= 1; + } + + if (p_conv_data->bta2dp_info->content_protection_type == BTAVDTP_CONTENT_PROTECTION_TYPE_SCMS_T) { + rtp_info->info_payload_offset += 1; + rtp_info->info_payload_len -= 1; + } + } + + if (p_conv_data && p_conv_data->btvdp_info && + p_conv_data->bta2dp_info->content_protection_type == BTAVDTP_CONTENT_PROTECTION_TYPE_SCMS_T) { + rtp_info->info_payload_offset += 1; + rtp_info->info_payload_len -= 1; + } + if (data_len > 0) { /* * There's data left over when you take out @@ -1811,7 +1958,7 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) offset, data_len, data_len, - payload_type ); + payload_type); } CATCH_ALL { if (!pinfo->flags.in_error_pkt) tap_queue_packet(rtp_tap, pinfo, rtp_info); @@ -1852,13 +1999,34 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) /* * No padding. */ + rtp_info->info_payload_offset = offset; + rtp_info->info_payload_len = tvb_length_remaining(tvb, offset); + + if (p_conv_data && p_conv_data->bta2dp_info) { + if (p_conv_data->bta2dp_info->codec_dissector == sbc_handle) { + rtp_info->info_payload_offset += 1; + rtp_info->info_payload_len -= 1; + } + + if (p_conv_data->bta2dp_info->content_protection_type == BTAVDTP_CONTENT_PROTECTION_TYPE_SCMS_T) { + rtp_info->info_payload_offset += 1; + rtp_info->info_payload_len -= 1; + } + } + + if (p_conv_data && p_conv_data->btvdp_info && + p_conv_data->bta2dp_info->content_protection_type == BTAVDTP_CONTENT_PROTECTION_TYPE_SCMS_T) { + rtp_info->info_payload_offset += 1; + rtp_info->info_payload_len -= 1; + } + if (tvb_reported_length_remaining(tvb, offset) > 0) { /* Ensure that tap is called after packet dissection, even in case of exception */ TRY { dissect_rtp_data( tvb, pinfo, tree, rtp_tree, offset, tvb_length_remaining( tvb, offset ), tvb_reported_length_remaining( tvb, offset ), - payload_type ); + payload_type); } CATCH_ALL { if (!pinfo->flags.in_error_pkt) tap_queue_packet(rtp_tap, pinfo, rtp_info); @@ -1866,11 +2034,11 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) } ENDTRY; } - rtp_info->info_payload_offset = offset; - rtp_info->info_payload_len = tvb_length_remaining(tvb, offset); } if (!pinfo->flags.in_error_pkt) tap_queue_packet(rtp_tap, pinfo, rtp_info); + + return offset; } static void @@ -2079,6 +2247,8 @@ get_conv_info(packet_info *pinfo, struct _rtp_info *rtp_info) p_conv_packet_data->rtp_dyn_payload = p_conv_data->rtp_dyn_payload; p_conv_packet_data->rtp_conv_info = p_conv_data->rtp_conv_info; p_conv_packet_data->srtp_info = p_conv_data->srtp_info; + p_conv_packet_data->bta2dp_info = p_conv_data->bta2dp_info; + p_conv_packet_data->btvdp_info = p_conv_data->btvdp_info; p_add_proto_data(pinfo->fd, proto_rtp, 0, p_conv_packet_data); /* calculate extended sequence number */ @@ -2129,8 +2299,8 @@ show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) /* Dissect PacketCable CCC header */ -static void -dissect_pkt_ccc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +static int +dissect_pkt_ccc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) { proto_item *ti = NULL; proto_tree *pkt_ccc_tree = NULL; @@ -2144,7 +2314,7 @@ dissect_pkt_ccc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) ENC_TIME_NTP|ENC_BIG_ENDIAN); } - dissect_rtp(tvb, pinfo, tree); + return dissect_rtp(tvb, pinfo, tree, data); } @@ -2194,7 +2364,7 @@ proto_register_pkt_ccc(void) proto_register_field_array(proto_pkt_ccc, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); - register_dissector("pkt_ccc", dissect_pkt_ccc, proto_pkt_ccc); + new_register_dissector("pkt_ccc", dissect_pkt_ccc, proto_pkt_ccc); pkt_ccc_module = prefs_register_protocol(proto_pkt_ccc, proto_reg_handoff_pkt_ccc); @@ -3041,7 +3211,7 @@ proto_register_rtp(void) proto_register_field_array(proto_rtp, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); - register_dissector("rtp", dissect_rtp, proto_rtp); + new_register_dissector("rtp", dissect_rtp, proto_rtp); register_dissector("rtp.rfc2198", dissect_rtp_rfc2198, proto_rtp); rtp_tap = register_tap("rtp"); @@ -3128,8 +3298,16 @@ proto_reg_handoff_rtp(void) sprt_handle = find_dissector("sprt"); v150fw_handle = find_dissector("v150fw"); + bta2dp_content_protection_header_scms_t = find_dissector("bta2dp_content_protection_header_scms_t"); + btvdp_content_protection_header_scms_t = find_dissector("btvdp_content_protection_header_scms_t"); + bta2dp_handle = find_dissector("bta2dp"); + btvdp_handle = find_dissector("btvdp"); + sbc_handle = find_dissector("sbc"); + dissector_add_string("rtp_dyn_payload_type", "v150fw", v150fw_handle); + dissector_add_handle("btl2cap.cid", rtp_handle); + rtp_prefs_initialized = TRUE; } else { dissector_delete_uint("rtp.pt", rtp_saved_rfc2198_pt, rtp_rfc2198_handle); diff --git a/epan/dissectors/packet-rtp.h b/epan/dissectors/packet-rtp.h index ec95019dd9..7fb7b69c8a 100644 --- a/epan/dissectors/packet-rtp.h +++ b/epan/dissectors/packet-rtp.h @@ -27,13 +27,16 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include "epan/packet.h" #include "ws_symbol_export.h" +#include "packet-btavdtp.h" + struct _rtp_info { unsigned int info_version; gboolean info_padding_set; gboolean info_marker_set; - gboolean info_is_video; + gboolean info_is_video; unsigned int info_payload_type; unsigned int info_padding_count; guint16 info_seq_num; @@ -44,10 +47,10 @@ struct _rtp_info { guint info_payload_offset; /* start of payload relative to info_data */ guint info_payload_len; /* length of payload (incl padding) */ gboolean info_is_srtp; - guint32 info_setup_frame_num; /* the frame num of the packet that set this RTP connection */ + guint32 info_setup_frame_num; /* the frame num of the packet that set this RTP connection */ const guint8* info_data; /* pointer to raw rtp data */ - gchar *info_payload_type_str; - gint info_payload_rate; + const gchar *info_payload_type_str; + gint info_payload_rate; /* * info_data: pointer to raw rtp data = header + payload incl. padding. * That should be safe because the "epan_dissect_t" constructed for the packet @@ -116,6 +119,8 @@ struct _rtp_conversation_info * to the rtp dissector */ struct srtp_info *srtp_info; /* SRTP context */ + bta2dp_codec_info_t *bta2dp_info; + btvdp_codec_info_t *btvdp_info; }; typedef struct { @@ -144,6 +149,12 @@ void srtp_add_address(packet_info *pinfo, GHashTable *rtp_dyn_payload, struct srtp_info *srtp_info); +/* Add an Bluetooth conversation with the given details */ +void +bluetooth_add_address(packet_info *pinfo, address *addr, + const gchar *setup_method, guint32 setup_frame_number, + gboolean is_video, void *data); + /* Free and destroy the dyn_payload hash table */ WS_DLL_PUBLIC void rtp_free_hash_dyn_payload(GHashTable *rtp_dyn_payload); diff --git a/ui/rtp_stream.h b/ui/rtp_stream.h index 059444b96d..14c484bbd9 100644 --- a/ui/rtp_stream.h +++ b/ui/rtp_stream.h @@ -58,7 +58,7 @@ typedef struct _rtp_stream_info { guint32 dest_port; guint32 ssrc; guint8 pt; - gchar *info_payload_type_str; + const gchar *info_payload_type_str; guint32 npackets; guint32 first_frame_num; /**< frame number of first frame */ diff --git a/ui/tap-rtp-common.c b/ui/tap-rtp-common.c index 6785e5fd1d..9f9c070f6c 100644 --- a/ui/tap-rtp-common.c +++ b/ui/tap-rtp-common.c @@ -417,7 +417,7 @@ static const mimetype_and_clock mimetype_and_clock_map[] = { #define NUM_DYN_CLOCK_VALUES (sizeof mimetype_and_clock_map / sizeof mimetype_and_clock_map[0]) static guint32 -get_dyn_pt_clock_rate(gchar *payload_type_str) +get_dyn_pt_clock_rate(const gchar *payload_type_str) { int i; |