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:
parent
60ab49592b
commit
68e65021e0
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue