Clean up handling of metadata in Bluetooth dissectors.

Make the "previous protocol data" union in bluetooth_data_t a
discriminated union, and use the discriminator to decide whether to use
a given member of the union or not (or to check whether the member you
plan to use is valid).

Have separate top-level dissectors depending on what the data type
pointed to by the "data" argument is.

Use that member to point to pseudo-header metadata, and, for now, set it
to point to the appropriate pinfo->pseudo_header value; eventually, we
plan to pass the pseudo-header pointer in as the "data" argument from
the "frame" dissector.

Don't overwrite the pseudo-header in the packetlogger dissector -
construct a new one and pass it in.

Change-Id: Ia1ef71e7082a964c5d92d47221f8c00e32f3f087
Reviewed-on: https://code.wireshark.org/review/8943
Reviewed-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
Guy Harris 2015-06-15 20:23:24 -07:00
parent 60ab49592b
commit 68e65021e0
8 changed files with 167 additions and 46 deletions

View File

@ -32,7 +32,6 @@
#include "packet-bluetooth.h"
int proto_bluetooth = -1;
static int proto_ubertooth = -1;
static int hf_bluetooth_src = -1;
static int hf_bluetooth_dst = -1;
@ -43,7 +42,6 @@ static int hf_bluetooth_str_addr = -1;
static gint ett_bluetooth = -1;
static dissector_handle_t bluetooth_handle;
static dissector_handle_t btle_handle;
static dissector_handle_t data_handle;
@ -1255,8 +1253,8 @@ print_numeric_uuid(bluetooth_uuid_t *uuid)
}
static gint
dissect_bluetooth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
static bluetooth_data_t *
dissect_bluetooth_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_item *main_item;
proto_tree *main_tree;
@ -1303,8 +1301,6 @@ dissect_bluetooth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
bluetooth_data->localhost_name = localhost_name;
bluetooth_data->hci_vendors = hci_vendors;
bluetooth_data->previous_protocol_data.data = data;
if (have_tap_listener(bluetooth_tap)) {
bluetooth_tap_data_t *bluetooth_tap_data;
@ -1346,16 +1342,123 @@ dissect_bluetooth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
PROTO_ITEM_SET_GENERATED(sub_item);
}
if (proto_ubertooth == (gint) GPOINTER_TO_UINT(wmem_list_frame_data(
wmem_list_frame_prev(wmem_list_tail(pinfo->layers))))) {
call_dissector(btle_handle, tvb, pinfo, tree);
} else if (!dissector_try_uint_new(bluetooth_table, pinfo->phdr->pkt_encap, tvb, pinfo, tree, TRUE, bluetooth_data)) {
return bluetooth_data;
}
/*
* Register this in the wtap_encap dissector table.
*/
static gint
dissect_bluetooth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
bluetooth_data_t *bluetooth_data;
bluetooth_data = dissect_bluetooth_common(tvb, pinfo, tree);
/*
* There is no pseudo-header, or there's just a p2p pseudo-header.
*/
bluetooth_data->previous_protocol_data_type = BT_PD_NONE;
bluetooth_data->previous_protocol_data.none = NULL;
if (!dissector_try_uint_new(bluetooth_table, pinfo->phdr->pkt_encap, tvb, pinfo, tree, TRUE, bluetooth_data)) {
call_dissector(data_handle, tvb, pinfo, tree);
}
return tvb_captured_length(tvb);
}
/*
* Register this in the wtap_encap dissector table.
*/
static gint
dissect_bluetooth_bthci(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
bluetooth_data_t *bluetooth_data;
bluetooth_data = dissect_bluetooth_common(tvb, pinfo, tree);
/*
* Point to the bthci pseudo-header.
*/
bluetooth_data->previous_protocol_data_type = BT_PD_BTHCI;
bluetooth_data->previous_protocol_data.bthci = &pinfo->pseudo_header->bthci;
if (!dissector_try_uint_new(bluetooth_table, pinfo->phdr->pkt_encap, tvb, pinfo, tree, TRUE, bluetooth_data)) {
call_dissector(data_handle, tvb, pinfo, tree);
}
return tvb_captured_length(tvb);
}
/*
* Register this in the wtap_encap dissector table.
*/
static gint
dissect_bluetooth_btmon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
bluetooth_data_t *bluetooth_data;
bluetooth_data = dissect_bluetooth_common(tvb, pinfo, tree);
/*
* Point to the btmon pseudo-header.
*/
bluetooth_data->previous_protocol_data_type = BT_PD_BTMON;
bluetooth_data->previous_protocol_data.btmon = &pinfo->pseudo_header->btmon;
if (!dissector_try_uint_new(bluetooth_table, pinfo->phdr->pkt_encap, tvb, pinfo, tree, TRUE, bluetooth_data)) {
call_dissector(data_handle, tvb, pinfo, tree);
}
return tvb_captured_length(tvb);
}
/*
* Register this in various USB dissector tables.
*/
static gint
dissect_bluetooth_usb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
bluetooth_data_t *bluetooth_data;
bluetooth_data = dissect_bluetooth_common(tvb, pinfo, tree);
/*
* data points to a usb_conv_info_t.
*/
bluetooth_data->previous_protocol_data_type = BT_PD_USB_CONV_INFO;
bluetooth_data->previous_protocol_data.usb_conv_info = (usb_conv_info_t *)data;
if (!dissector_try_uint_new(bluetooth_table, pinfo->phdr->pkt_encap, tvb, pinfo, tree, TRUE, bluetooth_data)) {
call_dissector(data_handle, tvb, pinfo, tree);
}
return tvb_captured_length(tvb);
}
/*
* Register this by name; it's called from the Ubertooth dissector.
*/
static gint
dissect_bluetooth_ubertooth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
bluetooth_data_t *bluetooth_data;
bluetooth_data = dissect_bluetooth_common(tvb, pinfo, tree);
/*
* data points to a ubertooth_data_t.
*/
bluetooth_data->previous_protocol_data_type = BT_PD_UBERTOOTH_DATA;
bluetooth_data->previous_protocol_data.ubertooth_data = (ubertooth_data_t *)data;
call_dissector(btle_handle, tvb, pinfo, tree);
return tvb_captured_length(tvb);
}
void
proto_register_bluetooth(void)
{
@ -1399,7 +1502,7 @@ proto_register_bluetooth(void)
proto_bluetooth = proto_register_protocol("Bluetooth",
"Bluetooth", "bluetooth");
bluetooth_handle = new_register_dissector("bluetooth", dissect_bluetooth, proto_bluetooth);
new_register_dissector("bluetooth_ubertooth", dissect_bluetooth_ubertooth, proto_bluetooth);
proto_register_field_array(proto_bluetooth, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
@ -1427,32 +1530,36 @@ proto_register_bluetooth(void)
void
proto_reg_handoff_bluetooth(void)
{
proto_ubertooth = proto_get_id_by_filter_name("ubertooth");
dissector_handle_t bluetooth_handle = new_create_dissector_handle(dissect_bluetooth, proto_bluetooth);
dissector_handle_t bluetooth_bthci_handle = new_create_dissector_handle(dissect_bluetooth_bthci, proto_bluetooth);
dissector_handle_t bluetooth_btmon_handle = new_create_dissector_handle(dissect_bluetooth_btmon, proto_bluetooth);
dissector_handle_t bluetooth_usb_handle = new_create_dissector_handle(dissect_bluetooth_usb, proto_bluetooth);
btle_handle = find_dissector("btle");
data_handle = find_dissector("data");
dissector_add_uint("wtap_encap", WTAP_ENCAP_BLUETOOTH_HCI, bluetooth_handle);
dissector_add_uint("wtap_encap", WTAP_ENCAP_BLUETOOTH_HCI, bluetooth_bthci_handle);
dissector_add_uint("wtap_encap", WTAP_ENCAP_BLUETOOTH_H4, bluetooth_handle);
dissector_add_uint("wtap_encap", WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR, bluetooth_handle);
dissector_add_uint("wtap_encap", WTAP_ENCAP_BLUETOOTH_LINUX_MONITOR, bluetooth_handle);
dissector_add_uint("wtap_encap", WTAP_ENCAP_BLUETOOTH_LINUX_MONITOR, bluetooth_btmon_handle);
dissector_add_uint("wtap_encap", WTAP_ENCAP_PACKETLOGGER, bluetooth_handle);
dissector_add_uint("wtap_encap", WTAP_ENCAP_BLUETOOTH_LE_LL, bluetooth_handle);
dissector_add_uint("wtap_encap", WTAP_ENCAP_BLUETOOTH_LE_LL_WITH_PHDR, bluetooth_handle);
dissector_add_uint("wtap_encap", WTAP_ENCAP_BLUETOOTH_BREDR_BB, bluetooth_handle);
dissector_add_uint("usb.product", (0x0a5c << 16) | 0x21e8, bluetooth_handle);
dissector_add_uint("usb.product", (0x1131 << 16) | 0x1001, bluetooth_handle);
dissector_add_uint("usb.product", (0x050d << 16) | 0x0081, bluetooth_handle);
dissector_add_uint("usb.product", (0x0a5c << 16) | 0x2198, bluetooth_handle);
dissector_add_uint("usb.product", (0x0a5c << 16) | 0x21e8, bluetooth_handle);
dissector_add_uint("usb.product", (0x04bf << 16) | 0x0320, bluetooth_handle);
dissector_add_uint("usb.product", (0x13d3 << 16) | 0x3375, bluetooth_handle);
dissector_add_uint("usb.product", (0x0a5c << 16) | 0x21e8, bluetooth_usb_handle);
dissector_add_uint("usb.product", (0x1131 << 16) | 0x1001, bluetooth_usb_handle);
dissector_add_uint("usb.product", (0x050d << 16) | 0x0081, bluetooth_usb_handle);
dissector_add_uint("usb.product", (0x0a5c << 16) | 0x2198, bluetooth_usb_handle);
dissector_add_uint("usb.product", (0x0a5c << 16) | 0x21e8, bluetooth_usb_handle);
dissector_add_uint("usb.product", (0x04bf << 16) | 0x0320, bluetooth_usb_handle);
dissector_add_uint("usb.product", (0x13d3 << 16) | 0x3375, bluetooth_usb_handle);
dissector_add_uint("usb.protocol", 0xE00101, bluetooth_handle);
dissector_add_uint("usb.protocol", 0xE00104, bluetooth_handle);
dissector_add_uint("usb.protocol", 0xE00101, bluetooth_usb_handle);
dissector_add_uint("usb.protocol", 0xE00104, bluetooth_usb_handle);
dissector_add_for_decode_as("usb.device", bluetooth_handle);
dissector_add_for_decode_as("usb.device", bluetooth_usb_handle);
}
/*

View File

@ -86,6 +86,14 @@ extern const value_string bluetooth_address_type_vals[];
#define HCI_INTERFACE_DEFAULT 0
#define HCI_ADAPTER_DEFAULT 0
typedef enum {
BT_PD_NONE, /* no protocol data */
BT_PD_BTHCI, /* struct bthci_phdr * */
BT_PD_BTMON, /* struct btmon_phdr * */
BT_PD_USB_CONV_INFO, /* usb_conv_info_t * */
BT_PD_UBERTOOTH_DATA /* ubertooth_data_t * */
} bt_protocol_data_type;
/* chandle_sessions: interface_id + adapter_id + connection_handle + frame_number -> connect_in_frame, disconnect_in_frame */
/* chandle_to_bdaddr: interface_id + adapter_id + connection_handle + frame_number -> bd_addr[6] */
/* chandle_to_mode: interface_id + adapter_id + connection_handle + frame_number -> mode */
@ -106,8 +114,11 @@ typedef struct _bluetooth_data_t {
wmem_tree_t *localhost_name;
wmem_tree_t *hci_vendors;
bt_protocol_data_type previous_protocol_data_type;
union {
void *data;
void *none;
struct bthci_phdr *bthci;
struct btmon_phdr *btmon;
usb_conv_info_t *usb_conv_info;
ubertooth_data_t *ubertooth_data;
} previous_protocol_data;

View File

@ -38,7 +38,6 @@
static int proto_btle = -1;
static int proto_btle_rf = -1;
static int proto_ubertooth = -1;
static int hf_access_address = -1;
static int hf_crc = -1;
@ -346,7 +345,7 @@ dissect_btle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
}
list_data = wmem_list_frame_prev(list_data);
if (bluetooth_data && list_data && proto_ubertooth == GPOINTER_TO_INT(wmem_list_frame_data(list_data))) {
if (bluetooth_data && bluetooth_data->previous_protocol_data_type == BT_PD_UBERTOOTH_DATA) {
ubertooth_data = bluetooth_data->previous_protocol_data.ubertooth_data;
}
}
@ -1396,7 +1395,6 @@ proto_reg_handoff_btle(void)
btl2cap_handle = find_dissector("btl2cap");
proto_btle_rf = proto_get_id_by_filter_name("btle_rf");
proto_ubertooth = proto_get_id_by_filter_name("ubertooth");
dissector_add_uint("bluetooth.encap", WTAP_ENCAP_BLUETOOTH_LE_LL, btle_handle);
}

View File

@ -70,7 +70,8 @@ dissect_hci_h1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
col_clear(pinfo->cinfo, COL_INFO);
type = pinfo->pseudo_header->bthci.channel;
DISSECTOR_ASSERT(bluetooth_data->previous_protocol_data_type == BT_PD_BTHCI);
type = bluetooth_data->previous_protocol_data.bthci->channel;
if (tree) {
ti = proto_tree_add_item(tree, proto_hci_h1, tvb, 0, 0, ENC_NA);

View File

@ -105,11 +105,12 @@ dissect_hci_mon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
guint32 k_adapter_id;
guint32 k_frame_number;
adapter_id = pinfo->pseudo_header->btmon.adapter_id;
opcode = pinfo->pseudo_header->btmon.opcode;
bluetooth_data = (bluetooth_data_t *) data;
DISSECTOR_ASSERT(bluetooth_data->previous_protocol_data_type == BT_PD_BTMON);
adapter_id = bluetooth_data->previous_protocol_data.btmon->adapter_id;
opcode = bluetooth_data->previous_protocol_data.btmon->opcode;
if (opcode == 0x00 || opcode == 0x01)
pinfo->p2p_dir = P2P_DIR_RECV;
else if (opcode % 2)

View File

@ -126,6 +126,7 @@ dissect_hci_usb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
if (data == NULL)
return 0;
DISSECTOR_ASSERT(bluetooth_data->previous_protocol_data_type == BT_PD_USB_CONV_INFO);
usb_conv_info = bluetooth_data->previous_protocol_data.usb_conv_info;
titem = proto_tree_add_item(tree, proto_hci_usb, tvb, offset, -1, ENC_NA);

View File

@ -80,6 +80,7 @@ static int dissect_packetlogger(tvbuff_t *tvb, packet_info *pinfo,
guint8 pl_type;
gint len;
bluetooth_data_t *bluetooth_data;
struct bthci_phdr bthci;
bluetooth_data = (bluetooth_data_t *) data;
@ -100,35 +101,36 @@ static int dissect_packetlogger(tvbuff_t *tvb, packet_info *pinfo,
/* HCI H1 packages */
switch (pl_type) {
case PKT_HCI_COMMAND:
pinfo->pseudo_header->bthci.channel = BTHCI_CHANNEL_COMMAND;
pinfo->pseudo_header->bthci.sent = P2P_DIR_SENT;
bthci.channel = BTHCI_CHANNEL_COMMAND;
bthci.sent = P2P_DIR_SENT;
pinfo->p2p_dir = P2P_DIR_SENT;
break;
case PKT_HCI_EVENT:
pinfo->pseudo_header->bthci.channel = BTHCI_CHANNEL_EVENT;
pinfo->pseudo_header->bthci.sent = P2P_DIR_RECV;
bthci.channel = BTHCI_CHANNEL_EVENT;
bthci.sent = P2P_DIR_RECV;
pinfo->p2p_dir = P2P_DIR_RECV;
break;
case PKT_SENT_ACL_DATA:
pinfo->pseudo_header->bthci.channel = BTHCI_CHANNEL_ACL;
pinfo->pseudo_header->bthci.sent = P2P_DIR_SENT;
bthci.channel = BTHCI_CHANNEL_ACL;
bthci.sent = P2P_DIR_SENT;
pinfo->p2p_dir = P2P_DIR_SENT;
break;
case PKT_RECV_ACL_DATA:
pinfo->pseudo_header->bthci.channel = BTHCI_CHANNEL_ACL;
pinfo->pseudo_header->bthci.sent = P2P_DIR_RECV;
bthci.channel = BTHCI_CHANNEL_ACL;
bthci.sent = P2P_DIR_RECV;
pinfo->p2p_dir = P2P_DIR_RECV;
break;
default:
pinfo->pseudo_header->bthci.channel = pl_type;
pinfo->pseudo_header->bthci.sent = P2P_DIR_UNKNOWN;
bthci.channel = pl_type;
bthci.sent = P2P_DIR_UNKNOWN;
pinfo->p2p_dir = P2P_DIR_UNKNOWN;
break;
}
bluetooth_data->previous_protocol_data.bthci = &bthci;
proto_item_set_len (ti, 1);
col_add_fstr (pinfo->cinfo, COL_INFO, "%s", val_to_str(pl_type, type_vals, "Unknown 0x%02x"));
if (!dissector_try_uint_new(hci_h1_table, pinfo->pseudo_header->bthci.channel,
if (!dissector_try_uint_new(hci_h1_table, bthci.channel,
next_tvb, pinfo, tree, TRUE, bluetooth_data)) {
call_dissector (data_handle, next_tvb, pinfo, tree);
}

View File

@ -332,7 +332,7 @@ static expert_field ei_unknown_data = EI_INIT;
static expert_field ei_unexpected_data = EI_INIT;
static dissector_handle_t ubertooth_handle;
static dissector_handle_t bluetooth_handle;
static dissector_handle_t bluetooth_ubertooth_handle;
static wmem_tree_t *command_info = NULL;
@ -1318,7 +1318,7 @@ dissect_usb_rx_packet(proto_tree *main_tree, proto_tree *tree, packet_info *pinf
ubertooth_data->channel = channel;
next_tvb = tvb_new_subset_length(tvb, offset, length);
call_dissector_with_data(bluetooth_handle, next_tvb, pinfo, main_tree, ubertooth_data);
call_dissector_with_data(bluetooth_ubertooth_handle, next_tvb, pinfo, main_tree, ubertooth_data);
offset += length;
if (tvb_length_remaining(tvb, offset) > 0) {
@ -3424,7 +3424,7 @@ proto_register_ubertooth(void)
void
proto_reg_handoff_ubertooth(void)
{
bluetooth_handle = find_dissector("bluetooth");
bluetooth_ubertooth_handle = find_dissector("bluetooth_ubertooth");
dissector_add_uint("usb.product", (0x1d50 << 16) | 0x6000, ubertooth_handle); /* Ubertooth Zero */
dissector_add_uint("usb.product", (0x1d50 << 16) | 0x6002, ubertooth_handle); /* Ubertooth One */