diff --git a/epan/dissectors/CMakeLists.txt b/epan/dissectors/CMakeLists.txt index 8a160aaedc..9a93adf226 100644 --- a/epan/dissectors/CMakeLists.txt +++ b/epan/dissectors/CMakeLists.txt @@ -277,6 +277,7 @@ set(DISSECTOR_PUBLIC_HEADERS packet-bthci_acl.h packet-bthci_cmd.h packet-bthci_evt.h + packet-bthci_iso.h packet-bthci_sco.h packet-btl2cap.h packet-btle.h @@ -761,6 +762,7 @@ set(DISSECTOR_SRC ${CMAKE_CURRENT_SOURCE_DIR}/packet-bthci_acl.c ${CMAKE_CURRENT_SOURCE_DIR}/packet-bthci_cmd.c ${CMAKE_CURRENT_SOURCE_DIR}/packet-bthci_evt.c + ${CMAKE_CURRENT_SOURCE_DIR}/packet-bthci_iso.c ${CMAKE_CURRENT_SOURCE_DIR}/packet-bthci_sco.c ${CMAKE_CURRENT_SOURCE_DIR}/packet-bthci_vendor.c ${CMAKE_CURRENT_SOURCE_DIR}/packet-bthcrp.c diff --git a/epan/dissectors/packet-bluetooth.h b/epan/dissectors/packet-bluetooth.h index 0a25d266ae..bf87276625 100644 --- a/epan/dissectors/packet-bluetooth.h +++ b/epan/dissectors/packet-bluetooth.h @@ -28,6 +28,7 @@ extern "C" { #define HCI_H4_TYPE_ACL 0x02 #define HCI_H4_TYPE_SCO 0x03 #define HCI_H4_TYPE_EVT 0x04 +#define HCI_H4_TYPE_ISO 0x05 #define HCI_OGF_LINK_CONTROL 0x01 #define HCI_OGF_LINK_POLICY 0x02 diff --git a/epan/dissectors/packet-bthci_iso.c b/epan/dissectors/packet-bthci_iso.c new file mode 100644 index 0000000000..b7e4122a4b --- /dev/null +++ b/epan/dissectors/packet-bthci_iso.c @@ -0,0 +1,202 @@ +/* packet-bthci_iso.c + * Routines for the Bluetooth ISO dissection + * Copyright 2020, Jakub Pawlowski + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "packet-bluetooth.h" + +/* Initialize the protocol and registered fields */ +static int proto_bthci_iso = -1; +static int hf_bthci_iso_connection_handle = -1; +static int hf_bthci_iso_pb_flag = -1; +static int hf_bthci_iso_ts_flag = -1; +static int hf_bthci_iso_reserved_1 = -1; +static int hf_bthci_iso_length = -1; +static int hf_bthci_iso_reserved_2 = -1; +static int hf_bthci_iso_data = -1; + +/* Initialize the subtree pointers */ +static gint ett_bthci_iso = -1; + +static dissector_handle_t bthci_iso_handle; + +static const value_string pb_flag_vals[] = { + { 0, "First fragment of fragmented SDU" }, + { 1, "Continuation Fragment of an SDU" }, + { 2, "Complete SDU" }, + { 3, "Last fragment of an SDU" }, + { 0, NULL } +}; + +static const value_string ts_flag_vals[] = { + { 0, "No Time Stamp" }, + { 1, "Contains Time Stamp" }, + { 0, NULL } +}; + +void proto_register_bthci_iso(void); +void proto_reg_handoff_bthci_iso(void); + +/* Code to actually dissect the packets */ +static gint +dissect_bthci_iso(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) +{ + proto_item *bthci_iso_item; + proto_tree *bthci_iso_tree; + proto_item *sub_item; + guint16 flags; + gboolean fragmented; + gint offset = 0; + guint16 pb_flag; + + /* Reject the packet if data is NULL */ + if (data == NULL) + return 0; + + bthci_iso_item = proto_tree_add_item(tree, proto_bthci_iso, tvb, offset, -1, ENC_NA); + bthci_iso_tree = proto_item_add_subtree(bthci_iso_item, ett_bthci_iso); + + switch (pinfo->p2p_dir) { + case P2P_DIR_SENT: + col_set_str(pinfo->cinfo, COL_INFO, "Sent "); + break; + case P2P_DIR_RECV: + col_set_str(pinfo->cinfo, COL_INFO, "Rcvd "); + break; + default: + col_set_str(pinfo->cinfo, COL_INFO, "UnknownDirection "); + break; + } + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "HCI_ISO"); + + flags = tvb_get_letohs(tvb, offset); + pb_flag = (flags & 0x3000) >> 12; + proto_tree_add_item(bthci_iso_tree, hf_bthci_iso_connection_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(bthci_iso_tree, hf_bthci_iso_pb_flag, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(bthci_iso_tree, hf_bthci_iso_ts_flag, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(bthci_iso_tree, hf_bthci_iso_reserved_1, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 2; + + proto_tree_add_item(bthci_iso_tree, hf_bthci_iso_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(bthci_iso_tree, hf_bthci_iso_reserved_2, tvb, offset, 1, ENC_LITTLE_ENDIAN); + + offset += 2; + + /* determine if packet is fragmented */ + switch(pb_flag) { + case 0x00: /* First Fragment */ + case 0x01: /* Continuation */ + case 0x11: /* Last */ + fragmented = TRUE; + break; + case 0x10: /* Complete */ + default: + /* unknown pb_flag */ + fragmented = FALSE; + } + + + if (tvb_captured_length_remaining(tvb, offset) > 0) { + sub_item = proto_tree_add_item(bthci_iso_tree, hf_bthci_iso_data, tvb, offset, -1, ENC_NA); + if (fragmented) { + proto_item_append_text(sub_item, " Fragment"); + } + } + + return tvb_captured_length(tvb); +} + + +void +proto_register_bthci_iso(void) +{ + /* Setup list of header fields See Section 1.6.1 for details*/ + static hf_register_info hf[] = { + { &hf_bthci_iso_connection_handle, + { "Connection Handle", "bthci_iso.connection_handle", + FT_UINT16, BASE_HEX, NULL, 0x0FFF, + NULL, HFILL } + }, + { &hf_bthci_iso_pb_flag, + { "PB Flag", "bthci_iso.pb_flag", + FT_UINT16, BASE_DEC, VALS(pb_flag_vals), 0x3000, + "Packet Boundary Flag", HFILL } + }, + { &hf_bthci_iso_ts_flag, + { "TS Flag", "bthci_iso.ts_flag", + FT_UINT16, BASE_DEC, VALS(ts_flag_vals), 0x4000, + "Time stamp Flag", HFILL } + }, + { &hf_bthci_iso_reserved_1, + { "Reserved 1", "bthci_iso.reserved_1", + FT_UINT16, BASE_DEC, NULL, 0x8000, + "Reserved", HFILL } + }, + { &hf_bthci_iso_length, + { "ISO Data Load Length", "bthci_iso.length", + FT_UINT16, BASE_DEC, NULL, 0x7FFFF, + NULL, HFILL } + }, + { &hf_bthci_iso_reserved_2, + { "Reserved 2", "bthci_iso.reserved_2", + FT_UINT16, BASE_DEC, NULL, 0x8000, + "Reserved", HFILL } + }, + { &hf_bthci_iso_data, + { "ISO Data Load", "bthci_iso.data", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + }; + + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_bthci_iso, + }; + + /* Register the protocol name and description */ + proto_bthci_iso = proto_register_protocol("Bluetooth HCI ISO Packet", "HCI_ISO", "bthci_iso"); + bthci_iso_handle = register_dissector("bthci_iso", dissect_bthci_iso, proto_bthci_iso); + + /* Required function calls to register the header fields and subtrees used */ + proto_register_field_array(proto_bthci_iso, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + prefs_register_protocol_subtree("Bluetooth", proto_bthci_iso, NULL); +} + + +void +proto_reg_handoff_bthci_iso(void) +{ + dissector_add_uint("hci_h4.type", HCI_H4_TYPE_ISO, bthci_iso_handle); + dissector_add_uint("hci_h1.type", BTHCI_CHANNEL_ISO, bthci_iso_handle); +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/epan/dissectors/packet-bthci_iso.h b/epan/dissectors/packet-bthci_iso.h new file mode 100644 index 0000000000..d814d1cce9 --- /dev/null +++ b/epan/dissectors/packet-bthci_iso.h @@ -0,0 +1,26 @@ +/* packet-bthci_iso.h + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef __PACKET_BTHCI_ISO_H__ +#define __PACKET_BTHCI_ISO_H__ + +#endif + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/epan/dissectors/packet-hci_h1.c b/epan/dissectors/packet-hci_h1.c index f60e3f6e88..f0cd09eea1 100644 --- a/epan/dissectors/packet-hci_h1.c +++ b/epan/dissectors/packet-hci_h1.c @@ -30,6 +30,7 @@ static const value_string hci_h1_type_vals[] = { {BTHCI_CHANNEL_ACL, "ACL Data"}, {BTHCI_CHANNEL_SCO, "SCO Data"}, {BTHCI_CHANNEL_EVENT, "HCI Event"}, + {BTHCI_CHANNEL_ISO, "ISO Data"}, {0, NULL } }; static const value_string hci_h1_direction_vals[] = { diff --git a/epan/dissectors/packet-hci_h4.c b/epan/dissectors/packet-hci_h4.c index 5df387a76c..1811769dce 100644 --- a/epan/dissectors/packet-hci_h4.c +++ b/epan/dissectors/packet-hci_h4.c @@ -35,6 +35,7 @@ static const value_string hci_h4_type_vals[] = { {HCI_H4_TYPE_ACL, "ACL Data"}, {HCI_H4_TYPE_SCO, "SCO Data"}, {HCI_H4_TYPE_EVT, "HCI Event"}, + {HCI_H4_TYPE_ISO, "ISO Data"}, {0, NULL } }; static const value_string hci_h4_direction_vals[] = { diff --git a/wiretap/wtap.h b/wiretap/wtap.h index d01be8fa91..f27aa9f263 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -1114,6 +1114,7 @@ struct bthci_phdr { #define BTHCI_CHANNEL_ACL 2 #define BTHCI_CHANNEL_SCO 3 #define BTHCI_CHANNEL_EVENT 4 +#define BTHCI_CHANNEL_ISO 5 /* pseudo header for WTAP_ENCAP_BLUETOOTH_LINUX_MONITOR */ struct btmon_phdr {