aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-bthsp.c
diff options
context:
space:
mode:
authorMichal Labedzki <michal.labedzki@tieto.com>2015-09-27 18:22:32 +0200
committerMichal Labedzki <michal.labedzki@tieto.com>2015-10-17 10:22:02 +0000
commitbdf3c0b558d90b13a59b5d22f745f0072a91ca30 (patch)
tree686a38bd87036a062adb0e13a7c24ce269cc44eb /epan/dissectors/packet-bthsp.c
parent106c2893695b54a481f8e9baa4200fee2dfea880 (diff)
Bluetooth: Make dissectors independent of passed data
If Bluetooth dissectors has additional data from previous layer - good. But if do not... try to decode as much as possible - probably using some "force" dissector preferences you can decode payload correctly. Change-Id: I6427afafb987ed3b9b751fd91616e670802b3542 Reviewed-on: https://code.wireshark.org/review/11021 Reviewed-by: Michal Labedzki <michal.labedzki@tieto.com>
Diffstat (limited to 'epan/dissectors/packet-bthsp.c')
-rw-r--r--epan/dissectors/packet-bthsp.c224
1 files changed, 106 insertions, 118 deletions
diff --git a/epan/dissectors/packet-bthsp.c b/epan/dissectors/packet-bthsp.c
index 30af8efa45..d3bcea93d6 100644
--- a/epan/dissectors/packet-bthsp.c
+++ b/epan/dissectors/packet-bthsp.c
@@ -517,23 +517,23 @@ dissect_at_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
first_response_in (if 0 - no response)
- k_interface_id = interface_id;
- k_adapter_id = adapter_id;
- k_chandle = chandle;
- k_dlci = dlci;
- k_frame_number = pinfo->fd->num;
+ interface_id = interface_id;
+ adapter_id = adapter_id;
+ chandle = chandle;
+ dlci = dlci;
+ frame_number = pinfo->fd->num;
key[0].length = 1;
- key[0].key = &k_interface_id;
+ key[0].key = &interface_id;
key[1].length = 1;
- key[1].key = &k_adapter_id;
+ key[1].key = &adapter_id;
key[2].length = 1;
- key[2].key = &k_chandle;
+ key[2].key = &chandle;
key[3].length = 1;
- key[3].key = &k_dlci;
+ key[3].key = &dlci;
key[4].length = 1;
- key[4].key = &k_frame_number;
+ key[4].key = &frame_number;
key[5].length = 0;
key[5].key = NULL;
@@ -634,20 +634,17 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
gint offset = 0;
guint32 role = ROLE_UNKNOWN;
wmem_tree_key_t key[10];
- guint32 k_interface_id;
- guint32 k_adapter_id;
- guint32 k_chandle;
- guint32 k_dlci;
- guint32 k_role;
- guint32 k_frame_number;
guint32 interface_id;
guint32 adapter_id;
guint32 chandle;
guint32 dlci;
+ guint32 frame_number;
+ guint32 direction;
+ guint32 bd_addr_oui;
+ guint32 bd_addr_id;
fragment_t *fragment;
fragment_t *previous_fragment;
fragment_t *i_fragment;
- btrfcomm_data_t *rfcomm_data;
guint8 *at_stream;
gint length;
gint command_number;
@@ -655,13 +652,39 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
tvbuff_t *reassembled_tvb = NULL;
guint reassemble_start_offset = 0;
guint reassemble_end_offset = 0;
+ gint previous_proto;
- /* Reject the packet if data is NULL */
- if (data == NULL)
- return 0;
- rfcomm_data = (btrfcomm_data_t *) data;
+ previous_proto = (GPOINTER_TO_INT(wmem_list_frame_data(wmem_list_frame_prev(wmem_list_tail(pinfo->layers)))));
+ if (data && previous_proto == proto_btrfcomm) {
+ btrfcomm_data_t *rfcomm_data;
- main_item = proto_tree_add_item(tree, proto_bthsp, tvb, 0, -1, ENC_NA);
+ rfcomm_data = (btrfcomm_data_t *) data;
+
+ interface_id = rfcomm_data->interface_id;
+ adapter_id = rfcomm_data->adapter_id;
+ chandle = rfcomm_data->chandle;
+ dlci = rfcomm_data->dlci;
+ direction = (rfcomm_data->is_local_psm) ? P2P_DIR_SENT : P2P_DIR_RECV;
+
+ if (direction == P2P_DIR_RECV) {
+ bd_addr_oui = rfcomm_data->remote_bd_addr_oui;
+ bd_addr_id = rfcomm_data->remote_bd_addr_id;
+ } else {
+ bd_addr_oui = 0;
+ bd_addr_id = 0;
+ }
+ } else {
+ interface_id = HCI_INTERFACE_DEFAULT;
+ adapter_id = HCI_ADAPTER_DEFAULT;
+ chandle = 0;
+ dlci = 0;
+ direction = P2P_DIR_UNKNOWN;
+
+ bd_addr_oui = 0;
+ bd_addr_id = 0;
+ }
+
+ main_item = proto_tree_add_item(tree, proto_bthsp, tvb, 0, tvb_captured_length(tvb), ENC_NA);
main_tree = proto_item_add_subtree(main_item, ett_bthsp);
col_set_str(pinfo->cinfo, COL_PROTOCOL, "HSP");
@@ -678,11 +701,6 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
break;
}
- interface_id = rfcomm_data->interface_id;
- adapter_id = rfcomm_data->adapter_id;
- chandle = rfcomm_data->chandle;
- dlci = rfcomm_data->dlci;
-
if ((hsp_role == ROLE_AG && pinfo->p2p_dir == P2P_DIR_SENT) ||
(hsp_role == ROLE_HS && pinfo->p2p_dir == P2P_DIR_RECV)) {
role = ROLE_AG;
@@ -691,62 +709,50 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
}
if (role == ROLE_UNKNOWN) {
- guint32 k_sdp_psm;
- guint32 k_direction;
- guint32 k_bd_addr_oui;
- guint32 k_bd_addr_id;
- guint32 k_service_type;
- guint32 k_service_channel;
+ guint32 sdp_psm;
+ guint32 service_type;
+ guint32 service_channel;
service_info_t *service_info;
- k_interface_id = rfcomm_data->interface_id;
- k_adapter_id = rfcomm_data->adapter_id;
- k_sdp_psm = SDP_PSM_DEFAULT;
- k_direction = (rfcomm_data->is_local_psm) ? P2P_DIR_SENT : P2P_DIR_RECV;
- if (k_direction == P2P_DIR_RECV) {
- k_bd_addr_oui = rfcomm_data->remote_bd_addr_oui;
- k_bd_addr_id = rfcomm_data->remote_bd_addr_id;
- } else {
- k_bd_addr_oui = 0;
- k_bd_addr_id = 0;
- }
- k_service_type = BTSDP_RFCOMM_PROTOCOL_UUID;
- k_service_channel = rfcomm_data->dlci >> 1;
- k_frame_number = pinfo->fd->num;
+ sdp_psm = SDP_PSM_DEFAULT;
+
+ service_type = BTSDP_RFCOMM_PROTOCOL_UUID;
+ service_channel = dlci >> 1;
+ frame_number = pinfo->fd->num;
key[0].length = 1;
- key[0].key = &k_interface_id;
+ key[0].key = &interface_id;
key[1].length = 1;
- key[1].key = &k_adapter_id;
+ key[1].key = &adapter_id;
key[2].length = 1;
- key[2].key = &k_sdp_psm;
+ key[2].key = &sdp_psm;
key[3].length = 1;
- key[3].key = &k_direction;
+ key[3].key = &direction;
key[4].length = 1;
- key[4].key = &k_bd_addr_oui;
+ key[4].key = &bd_addr_oui;
key[5].length = 1;
- key[5].key = &k_bd_addr_id;
+ key[5].key = &bd_addr_id;
key[6].length = 1;
- key[6].key = &k_service_type;
+ key[6].key = &service_type;
key[7].length = 1;
- key[7].key = &k_service_channel;
+ key[7].key = &service_channel;
key[8].length = 1;
- key[8].key = &k_frame_number;
+ key[8].key = &frame_number;
key[9].length = 0;
key[9].key = NULL;
service_info = btsdp_get_service_info(key);
- if (service_info && service_info->interface_id == rfcomm_data->interface_id &&
- service_info->adapter_id == rfcomm_data->adapter_id &&
+ if (service_info && service_info->interface_id == interface_id &&
+ service_info->adapter_id == adapter_id &&
service_info->sdp_psm == SDP_PSM_DEFAULT &&
((service_info->direction == P2P_DIR_RECV &&
- service_info->bd_addr_oui == rfcomm_data->remote_bd_addr_oui &&
- service_info->bd_addr_id == rfcomm_data->remote_bd_addr_id) ||
+ service_info->bd_addr_oui == bd_addr_oui &&
+ service_info->bd_addr_id == bd_addr_id) ||
(service_info->direction != P2P_DIR_RECV &&
service_info->bd_addr_oui == 0 &&
service_info->bd_addr_id == 0)) &&
service_info->type == BTSDP_RFCOMM_PROTOCOL_UUID &&
- service_info->channel == (rfcomm_data->dlci >> 1)) {
+ service_info->channel == (dlci >> 1)) {
if ((service_info->uuid.bt_uuid == BTSDP_HSP_GW_SERVICE_UUID && service_info->direction == P2P_DIR_RECV && pinfo->p2p_dir == P2P_DIR_SENT) ||
(service_info->uuid.bt_uuid == BTSDP_HSP_GW_SERVICE_UUID && service_info->direction == P2P_DIR_SENT && pinfo->p2p_dir == P2P_DIR_RECV) ||
((service_info->uuid.bt_uuid == BTSDP_HSP_SERVICE_UUID || service_info->uuid.bt_uuid == BTSDP_HSP_HS_SERVICE_UUID) && service_info->direction == P2P_DIR_RECV && pinfo->p2p_dir == P2P_DIR_RECV) ||
@@ -764,31 +770,26 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
if (role == ROLE_UNKNOWN) {
col_append_fstr(pinfo->cinfo, COL_INFO, "Data: %s",
tvb_format_text(tvb, 0, tvb_reported_length(tvb)));
- proto_tree_add_item(main_tree, hf_data, tvb, 0, tvb_reported_length(tvb), ENC_NA | ENC_ASCII);
+ proto_tree_add_item(main_tree, hf_data, tvb, 0, tvb_captured_length(tvb), ENC_NA | ENC_ASCII);
return tvb_reported_length(tvb);
}
/* save fragments */
if (!pinfo->fd->flags.visited) {
- k_interface_id = interface_id;
- k_adapter_id = adapter_id;
- k_chandle = chandle;
- k_dlci = dlci;
- k_role = role;
- k_frame_number = pinfo->fd->num - 1;
+ frame_number = pinfo->fd->num - 1;
key[0].length = 1;
- key[0].key = &k_interface_id;
+ key[0].key = &interface_id;
key[1].length = 1;
- key[1].key = &k_adapter_id;
+ key[1].key = &adapter_id;
key[2].length = 1;
- key[2].key = &k_chandle;
+ key[2].key = &chandle;
key[3].length = 1;
- key[3].key = &k_dlci;
+ key[3].key = &dlci;
key[4].length = 1;
- key[4].key = &k_role;
+ key[4].key = &role;
key[5].length = 1;
- key[5].key = &k_frame_number;
+ key[5].key = &frame_number;
key[6].length = 0;
key[6].key = NULL;
@@ -802,25 +803,20 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
previous_fragment = NULL;
}
- k_interface_id = interface_id;
- k_adapter_id = adapter_id;
- k_chandle = chandle;
- k_dlci = dlci;
- k_role = role;
- k_frame_number = pinfo->fd->num;
+ frame_number = pinfo->fd->num;
key[0].length = 1;
- key[0].key = &k_interface_id;
+ key[0].key = &interface_id;
key[1].length = 1;
- key[1].key = &k_adapter_id;
+ key[1].key = &adapter_id;
key[2].length = 1;
- key[2].key = &k_chandle;
+ key[2].key = &chandle;
key[3].length = 1;
- key[3].key = &k_dlci;
+ key[3].key = &dlci;
key[4].length = 1;
- key[4].key = &k_role;
+ key[4].key = &role;
key[5].length = 1;
- key[5].key = &k_frame_number;
+ key[5].key = &frame_number;
key[6].length = 0;
key[6].key = NULL;
@@ -830,7 +826,7 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
fragment->chandle = chandle;
fragment->dlci = dlci;
fragment->role = role;
- fragment->idx = previous_fragment ? previous_fragment->idx + previous_fragment->length : 0;
+ fragment->idx = previous_fragment ? previous_fragment->idx + previous_fragment->length : 0;
fragment->reassemble_state = REASSEMBLE_FRAGMENT;
fragment->length = tvb_reported_length(tvb);
fragment->data = (guint8 *) wmem_alloc(wmem_file_scope(), fragment->length);
@@ -860,25 +856,20 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
reassemble_start_offset = i_length + 1;
}
- k_interface_id = interface_id;
- k_adapter_id = adapter_id;
- k_chandle = chandle;
- k_dlci = dlci;
- k_role = role;
- k_frame_number = pinfo->fd->num;
+ frame_number = pinfo->fd->num;
key[0].length = 1;
- key[0].key = &k_interface_id;
+ key[0].key = &interface_id;
key[1].length = 1;
- key[1].key = &k_adapter_id;
+ key[1].key = &adapter_id;
key[2].length = 1;
- key[2].key = &k_chandle;
+ key[2].key = &chandle;
key[3].length = 1;
- key[3].key = &k_dlci;
+ key[3].key = &dlci;
key[4].length = 1;
- key[4].key = &k_role;
+ key[4].key = &role;
key[5].length = 1;
- key[5].key = &k_frame_number;
+ key[5].key = &frame_number;
key[6].length = 0;
key[6].key = NULL;
@@ -917,7 +908,8 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
i_fragment->data[1] == '\n') {
fragment->reassemble_state = REASSEMBLE_DONE;
} else if (role == ROLE_HS) {
- fragment->reassemble_state = REASSEMBLE_PARTIALLY;
+/* XXX: Temporary disable reassembling of partial message, it seems to be broken */
+/* fragment->reassemble_state = REASSEMBLE_PARTIALLY;*/
}
fragment->reassemble_start_offset = reassemble_start_offset;
fragment->reassemble_end_offset = reassemble_end_offset;
@@ -926,25 +918,20 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
}
/* recover reassembled payload */
- k_interface_id = interface_id;
- k_adapter_id = adapter_id;
- k_chandle = chandle;
- k_dlci = dlci;
- k_role = role;
- k_frame_number = pinfo->fd->num;
+ frame_number = pinfo->fd->num;
key[0].length = 1;
- key[0].key = &k_interface_id;
+ key[0].key = &interface_id;
key[1].length = 1;
- key[1].key = &k_adapter_id;
+ key[1].key = &adapter_id;
key[2].length = 1;
- key[2].key = &k_chandle;
+ key[2].key = &chandle;
key[3].length = 1;
- key[3].key = &k_dlci;
+ key[3].key = &dlci;
key[4].length = 1;
- key[4].key = &k_role;
+ key[4].key = &role;
key[5].length = 1;
- key[5].key = &k_frame_number;
+ key[5].key = &frame_number;
key[6].length = 0;
key[6].key = NULL;
@@ -964,9 +951,8 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
i_fragment = fragment;
if (i_fragment && i_fragment->reassemble_state == REASSEMBLE_PARTIALLY) {
- i_data_offset -= i_fragment->reassemble_end_offset;
- memcpy(at_data + i_data_offset, i_fragment->data, i_fragment->reassemble_end_offset);
-
+ i_data_offset -= i_fragment->reassemble_end_offset;
+ memcpy(at_data + i_data_offset, i_fragment->data, i_fragment->reassemble_end_offset);
i_fragment = i_fragment->previous_fragment;
}
@@ -989,7 +975,7 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
if (fragment->idx > 0 && fragment->length > 0) {
proto_tree_add_item(main_tree, hf_fragment, tvb, offset,
- tvb_reported_length_remaining(tvb, offset), ENC_ASCII | ENC_NA);
+ tvb_captured_length_remaining(tvb, offset), ENC_ASCII | ENC_NA);
reassembled_tvb = tvb_new_child_real_data(tvb, at_data,
fragment->idx + fragment->length, fragment->idx + fragment->length);
add_new_data_source(pinfo, reassembled_tvb, "Reassembled HSP");
@@ -1004,6 +990,7 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
pinfo, main_tree, reassembled_offset, role, command_number);
command_number += 1;
}
+ offset = tvb_captured_length(tvb);
} else {
while (tvb_reported_length(tvb) > (guint) offset) {
offset = dissect_at_command(tvb, pinfo, main_tree, offset, role, command_number);
@@ -1012,11 +999,12 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
}
} else {
col_append_fstr(pinfo->cinfo, COL_INFO, "Fragment: %s",
- tvb_format_text_wsp(tvb, offset, tvb_reported_length_remaining(tvb, offset)));
+ tvb_format_text_wsp(tvb, offset, tvb_captured_length_remaining(tvb, offset)));
pitem = proto_tree_add_item(main_tree, hf_fragmented, tvb, 0, 0, ENC_NA);
PROTO_ITEM_SET_GENERATED(pitem);
proto_tree_add_item(main_tree, hf_fragment, tvb, offset,
- tvb_reported_length_remaining(tvb, offset), ENC_ASCII | ENC_NA);
+ tvb_captured_length_remaining(tvb, offset), ENC_ASCII | ENC_NA);
+ offset = tvb_captured_length(tvb);
}
return offset;