Bluetooth: simple HCI ISO Data packet dissector
Change-Id: I2da85d4ebe069a566943896fddb31e9a095d67b5 Reviewed-on: https://code.wireshark.org/review/38007 Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
parent
d7f7b62ef3
commit
2364968cd6
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,202 @@
|
|||
/* packet-bthci_iso.c
|
||||
* Routines for the Bluetooth ISO dissection
|
||||
* Copyright 2020, Jakub Pawlowski <jpawlowski@google.com>
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <epan/packet.h>
|
||||
#include <epan/prefs.h>
|
||||
#include <epan/addr_resolv.h>
|
||||
#include <epan/expert.h>
|
||||
#include <epan/proto_data.h>
|
||||
|
||||
#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:
|
||||
*/
|
|
@ -0,0 +1,26 @@
|
|||
/* packet-bthci_iso.h
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* 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:
|
||||
*/
|
|
@ -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[] = {
|
||||
|
|
|
@ -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[] = {
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue