Bluetooth: AVDTP: Upgrade session logic

To correctly resolve connections single "ID" value
like L2CAP PSM, is not enough, because next connection may use
the same PSM value. Solution is save frame number of frame that
make disconnection.

Conclusion:
Any session key values should be updated to pair:
{ID_1, disconnect_in_frame}, {ID_2, disconnect_in_frame}...
then we should check if  "disconnect_in_frame" is greater then
current frame number, otherwise it is not valid session.

Change-Id: I3d760112b6e53358a93c994f4aae455ac1bf5de6
Reviewed-on: https://code.wireshark.org/review/1878
Tested-by: Michal Labedzki <michal.labedzki@tieto.com>
Reviewed-by: Michal Labedzki <michal.labedzki@tieto.com>
This commit is contained in:
Michal Labedzki 2014-04-10 17:46:25 +02:00
parent 2abc54158d
commit e3473c921f
3 changed files with 12 additions and 3 deletions

View File

@ -509,6 +509,7 @@ typedef struct _channels_info_t {
gboolean media_is_local_psm;
wmem_tree_t *stream_numbers;
guint32 disconnect_in_frame;
guint32 *l2cap_disconnect_in_frame;
sep_entry_t *sep;
} channels_info_t;
@ -1136,7 +1137,7 @@ dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
subtree = (wmem_tree_t *) wmem_tree_lookup32_array(channels, key);
channels_info = (subtree) ? (channels_info_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL;
if (!(channels_info && channels_info->disconnect_in_frame >= pinfo->fd->num)) {
if (!(channels_info && *channels_info->l2cap_disconnect_in_frame >= pinfo->fd->num && channels_info->disconnect_in_frame >= pinfo->fd->num)) {
channels_info = (channels_info_t *) wmem_new (wmem_file_scope(), channels_info_t);
channels_info->control_scid = l2cap_data->scid;
@ -1144,6 +1145,7 @@ dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
channels_info->media_scid = -1;
channels_info->media_dcid = -1;
channels_info->disconnect_in_frame = G_MAXUINT32;
channels_info->l2cap_disconnect_in_frame = l2cap_data->disconnect_in_frame;
channels_info->sep = NULL;
if (!pinfo->fd->flags.visited) {
@ -1582,7 +1584,7 @@ dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
break;
}
if (!pinfo->fd->flags.visited && message_type == MESSAGE_TYPE_ACCEPT &&
channels_info->disconnect_in_frame == G_MAXUINT32) {
channels_info->disconnect_in_frame > pinfo->fd->num) {
channels_info->disconnect_in_frame = pinfo->fd->num;
}
break;
@ -1619,7 +1621,7 @@ dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
break;
}
if (!pinfo->fd->flags.visited && message_type == MESSAGE_TYPE_ACCEPT &&
channels_info->disconnect_in_frame == G_MAXUINT32) {
channels_info->disconnect_in_frame > pinfo->fd->num) {
channels_info->disconnect_in_frame = pinfo->fd->num;
}
break;

View File

@ -156,6 +156,8 @@ static dissector_table_t l2cap_service_dissector_table;
*/
static wmem_tree_t *cid_to_psm_table = NULL;
static guint32 max_disconnect_in_frame = G_MAXUINT32;
typedef struct _config_data_t {
guint8 mode;
guint8 txwindow;
@ -1390,6 +1392,7 @@ dissect_disconnrequestresponse(tvbuff_t *tvb, int offset, packet_info *pinfo,
}
}
return offset;
}
@ -1713,6 +1716,7 @@ dissect_btl2cap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
l2cap_data->is_local_psm = FALSE;
l2cap_data->psm = 0;
l2cap_data->first_scid_frame = 0;
l2cap_data->disconnect_in_frame = &max_disconnect_in_frame;
l2cap_data->remote_bd_addr_oui = (acl_data) ? acl_data->remote_bd_addr_oui : 0;
l2cap_data->remote_bd_addr_id = (acl_data) ? acl_data->remote_bd_addr_id : 0;
@ -1885,6 +1889,7 @@ dissect_btl2cap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
l2cap_data->scid = psm_data->scid;
l2cap_data->dcid = psm_data->dcid;
l2cap_data->psm = psm;
l2cap_data->disconnect_in_frame = &psm_data->disconnect_in_frame;
if (p_get_proto_data(pinfo->pool, pinfo, proto_btl2cap, BTL2CAP_PSM_CONV ) == NULL) {
p_add_proto_data(pinfo->pool, pinfo, proto_btl2cap, BTL2CAP_PSM_CONV, GUINT_TO_POINTER((guint)psm));
@ -2016,6 +2021,7 @@ dissect_btl2cap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
l2cap_data->is_local_psm = psm_data->local_service;
l2cap_data->first_scid_frame = psm_data->first_scid_frame;
l2cap_data->first_dcid_frame = psm_data->first_dcid_frame;
l2cap_data->disconnect_in_frame = &psm_data->disconnect_in_frame;
if (pinfo->p2p_dir == P2P_DIR_RECV)
config_data = &(psm_data->in);

View File

@ -56,6 +56,7 @@ typedef struct _btl2cap_data_t {
guint16 cid;
gint32 scid;
gint32 dcid;
guint32 *disconnect_in_frame;
gboolean is_local_psm; /* otherwise it is PSM in remote device */
guint16 psm;
guint32 first_scid_frame;