forked from osmocom/wireshark
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:
parent
2abc54158d
commit
e3473c921f
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue