aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2013-12-07 01:01:31 +0000
committerMichael Mann <mmann78@netscape.net>2013-12-07 01:01:31 +0000
commitcc5543f8243db93356eed7632a81bf42eb0c9830 (patch)
tree7f3d3ab938fe7d6052eabff4dd3e5102c80ca0d2 /epan/dissectors
parentc1ef044de5e4a28cbad0d010aeafe38da0be6750 (diff)
Bluetooth enhancements. Bug 9446 (https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9446)
Bluetooth: SCO: Add Source/Destination addresses Bluetooth: HCRP: Use information from SDP to decoding PSM payload From Michal Labedzki svn path=/trunk/; revision=53816
Diffstat (limited to 'epan/dissectors')
-rw-r--r--epan/dissectors/packet-bthci_evt.c46
-rw-r--r--epan/dissectors/packet-bthci_sco.c152
-rw-r--r--epan/dissectors/packet-bthcrp.c152
-rw-r--r--epan/dissectors/packet-bthfp.c1
-rw-r--r--epan/dissectors/packet-bthsp.c1
-rw-r--r--epan/dissectors/packet-btl2cap.c3
-rw-r--r--epan/dissectors/packet-btrfcomm.c1
-rw-r--r--epan/dissectors/packet-btsdp.c50
-rw-r--r--epan/dissectors/packet-btsdp.h3
9 files changed, 355 insertions, 54 deletions
diff --git a/epan/dissectors/packet-bthci_evt.c b/epan/dissectors/packet-bthci_evt.c
index 55ad423969..44b064e6cc 100644
--- a/epan/dissectors/packet-bthci_evt.c
+++ b/epan/dissectors/packet-bthci_evt.c
@@ -3443,17 +3443,23 @@ dissect_bthci_evt_read_remote_ext_features_complete(tvbuff_t *tvb, int offset, p
}
static int
-dissect_bthci_evt_sync_connection_complete(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+dissect_bthci_evt_sync_connection_complete(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, hci_data_t *hci_data)
{
proto_item *item;
+ guint16 connection_handle;
+ guint8 bd_addr[6];
+ guint8 status;
proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ status = tvb_get_guint8(tvb, offset);
offset += 1;
proto_tree_add_item(tree, hf_bthci_evt_connection_handle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ connection_handle = tvb_get_letohs(tvb, offset) & 0x0FFF;
offset += 2;
- offset = dissect_bthci_evt_bd_addr(tvb, offset, pinfo, tree, NULL);
+ offset = dissect_bthci_evt_bd_addr(tvb, offset, pinfo, tree, bd_addr);
proto_tree_add_item(tree, hf_bthci_evt_sync_link_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
@@ -3475,6 +3481,40 @@ dissect_bthci_evt_sync_connection_complete(tvbuff_t *tvb, int offset, packet_inf
proto_tree_add_item(tree, hf_bthci_evt_air_mode, tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
+
+ if (!pinfo->fd->flags.visited && status == 0x00) {
+ wmem_tree_key_t key[5];
+ guint32 k_interface_id;
+ guint32 k_adapter_id;
+ guint32 k_connection_handle;
+ guint32 k_frame_number;
+ remote_bdaddr_t *remote_bdaddr;
+
+ k_interface_id = hci_data->interface_id;
+ k_adapter_id = hci_data->adapter_id;
+ k_connection_handle = connection_handle;
+ k_frame_number = pinfo->fd->num;
+
+ key[0].length = 1;
+ key[0].key = &k_interface_id;
+ key[1].length = 1;
+ key[1].key = &k_adapter_id;
+ key[2].length = 1;
+ key[2].key = &k_connection_handle;
+ key[3].length = 1;
+ key[3].key = &k_frame_number;
+ key[4].length = 0;
+ key[4].key = NULL;
+
+ remote_bdaddr = (remote_bdaddr_t *) wmem_new(wmem_file_scope(), remote_bdaddr_t);
+ remote_bdaddr->interface_id = hci_data->interface_id;
+ remote_bdaddr->adapter_id = hci_data->adapter_id;
+ remote_bdaddr->chandle = connection_handle;
+ memcpy(remote_bdaddr->bd_addr, bd_addr, 6);
+
+ wmem_tree_insert32_array(hci_data->chandle_to_bdaddr_table, key, remote_bdaddr);
+ }
+
return offset;
}
@@ -3828,7 +3868,7 @@ dissect_bthci_evt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat
break;
case 0x2c: /* Synchronous Connection Complete */
- offset = dissect_bthci_evt_sync_connection_complete(tvb, offset, pinfo, bthci_evt_tree);
+ offset = dissect_bthci_evt_sync_connection_complete(tvb, offset, pinfo, bthci_evt_tree, hci_data);
break;
case 0x2d: /* Synchronous Connection Changed */
diff --git a/epan/dissectors/packet-bthci_sco.c b/epan/dissectors/packet-bthci_sco.c
index a4e2c7269a..491cb3b23f 100644
--- a/epan/dissectors/packet-bthci_sco.c
+++ b/epan/dissectors/packet-bthci_sco.c
@@ -29,6 +29,8 @@
#include "config.h"
#include <epan/packet.h>
+#include <epan/addr_resolv.h>
+#include <epan/wmem/wmem.h>
#include <wiretap/wtap.h>
#include "packet-bluetooth-hci.h"
@@ -47,11 +49,26 @@ void proto_reg_handoff_bthci_sco(void);
/* Code to actually dissect the packets */
static gint
-dissect_bthci_sco(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
+dissect_bthci_sco(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data)
{
proto_item *ti;
proto_tree *bthci_sco_tree;
gint offset = 0;
+ guint16 flags;
+ hci_data_t *hci_data;
+ wmem_tree_key_t key[5];
+ guint32 k_connection_handle;
+ guint32 k_frame_number;
+ guint32 k_interface_id;
+ guint32 k_adapter_id;
+ remote_bdaddr_t *remote_bdaddr;
+ const gchar *localhost_name;
+ guint8 localhost_bdaddr[6];
+ const gchar *localhost_ether_addr;
+ gchar *localhost_addr_name;
+ gint localhost_length;
+ localhost_bdaddr_entry_t *localhost_bdaddr_entry;
+ localhost_name_entry_t *localhost_name_entry;
ti = proto_tree_add_item(tree, proto_bthci_sco, tvb, offset, -1, ENC_NA);
bthci_sco_tree = proto_item_add_subtree(ti, ett_bthci_sco);
@@ -70,11 +87,144 @@ dissect_bthci_sco(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void
}
proto_tree_add_item(bthci_sco_tree, hf_bthci_sco_chandle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ flags = tvb_get_letohs(tvb, offset);
offset += 2;
proto_tree_add_item(bthci_sco_tree, hf_bthci_sco_length, tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset++;
+ hci_data = (hci_data_t *) data;
+ DISSECTOR_ASSERT(hci_data);
+
+ k_interface_id = hci_data->interface_id;
+ k_adapter_id = hci_data->adapter_id;
+ k_connection_handle = flags & 0x0fff;
+ k_frame_number = pinfo->fd->num;
+
+ key[0].length = 1;
+ key[0].key = &k_interface_id;
+ key[1].length = 1;
+ key[1].key = &k_adapter_id;
+ key[2].length = 1;
+ key[2].key = &k_connection_handle;
+ key[3].length = 1;
+ key[3].key = &k_frame_number;
+ key[4].length = 0;
+ key[4].key = NULL;
+
+ /* remote bdaddr and name */
+ remote_bdaddr = (remote_bdaddr_t *)wmem_tree_lookup32_array_le(hci_data->chandle_to_bdaddr_table, key);
+ if (remote_bdaddr && remote_bdaddr->interface_id == hci_data->interface_id &&
+ remote_bdaddr->adapter_id == hci_data->adapter_id &&
+ remote_bdaddr->chandle == (flags & 0x0fff)) {
+ guint32 k_bd_addr_oui;
+ guint32 k_bd_addr_id;
+ guint32 bd_addr_oui;
+ guint32 bd_addr_id;
+ device_name_t *device_name;
+ const gchar *remote_name;
+ const gchar *remote_ether_addr;
+ gchar *remote_addr_name;
+ gint remote_length;
+
+ bd_addr_oui = remote_bdaddr->bd_addr[0] << 16 | remote_bdaddr->bd_addr[1] << 8 | remote_bdaddr->bd_addr[2];
+ bd_addr_id = remote_bdaddr->bd_addr[3] << 16 | remote_bdaddr->bd_addr[4] << 8 | remote_bdaddr->bd_addr[5];
+
+ k_bd_addr_oui = bd_addr_oui;
+ k_bd_addr_id = bd_addr_id;
+ k_frame_number = pinfo->fd->num;
+
+ key[0].length = 1;
+ key[0].key = &k_bd_addr_id;
+ key[1].length = 1;
+ key[1].key = &k_bd_addr_oui;
+ key[2].length = 1;
+ key[2].key = &k_frame_number;
+ key[3].length = 0;
+ key[3].key = NULL;
+
+ device_name = (device_name_t *)wmem_tree_lookup32_array_le(hci_data->bdaddr_to_name_table, key);
+ if (device_name && device_name->bd_addr_oui == bd_addr_oui && device_name->bd_addr_id == bd_addr_id)
+ remote_name = device_name->name;
+ else
+ remote_name = "";
+
+ remote_ether_addr = get_ether_name(remote_bdaddr->bd_addr);
+ remote_length = (gint)(strlen(remote_ether_addr) + 3 + strlen(remote_name) + 1);
+ remote_addr_name = (gchar *)wmem_alloc(pinfo->pool, remote_length);
+
+ g_snprintf(remote_addr_name, remote_length, "%s (%s)", remote_ether_addr, remote_name);
+
+ if (pinfo->p2p_dir == P2P_DIR_RECV) {
+ SET_ADDRESS(&pinfo->net_src, AT_STRINGZ, (int)strlen(remote_name) + 1, remote_name);
+ SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, remote_bdaddr->bd_addr);
+ SET_ADDRESS(&pinfo->src, AT_STRINGZ, (int)strlen(remote_addr_name) + 1, remote_addr_name);
+ } else if (pinfo->p2p_dir == P2P_DIR_SENT) {
+ SET_ADDRESS(&pinfo->net_dst, AT_STRINGZ, (int)strlen(remote_name) + 1, remote_name);
+ SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, remote_bdaddr->bd_addr);
+ SET_ADDRESS(&pinfo->dst, AT_STRINGZ, (int)strlen(remote_addr_name) + 1, remote_addr_name);
+ }
+ } else {
+ if (pinfo->p2p_dir == P2P_DIR_RECV) {
+ SET_ADDRESS(&pinfo->net_src, AT_STRINGZ, 1, "");
+ SET_ADDRESS(&pinfo->dl_src, AT_STRINGZ, 1, "");
+ SET_ADDRESS(&pinfo->src, AT_STRINGZ, 10, "remote ()");
+ } else if (pinfo->p2p_dir == P2P_DIR_SENT) {
+ SET_ADDRESS(&pinfo->net_dst, AT_STRINGZ, 1, "");
+ SET_ADDRESS(&pinfo->dl_dst, AT_STRINGZ, 1, "");
+ SET_ADDRESS(&pinfo->dst, AT_STRINGZ, 10, "remote ()");
+ }
+ }
+
+ k_interface_id = hci_data->interface_id;
+ k_adapter_id = hci_data->adapter_id;
+ k_frame_number = pinfo->fd->num;
+
+ /* localhost bdaddr and name */
+ key[0].length = 1;
+ key[0].key = &k_interface_id;
+ key[1].length = 1;
+ key[1].key = &k_adapter_id;
+ key[2].length = 1;
+ key[2].key = &k_frame_number;
+ key[3].length = 0;
+ key[3].key = NULL;
+
+
+ localhost_bdaddr_entry = (localhost_bdaddr_entry_t *)wmem_tree_lookup32_array_le(hci_data->localhost_bdaddr, key);
+ if (localhost_bdaddr_entry && localhost_bdaddr_entry->interface_id == hci_data->interface_id &&
+ localhost_bdaddr_entry->adapter_id == hci_data->adapter_id) {
+
+ localhost_ether_addr = get_ether_name(localhost_bdaddr_entry->bd_addr);
+ memcpy(localhost_bdaddr, localhost_bdaddr_entry->bd_addr, 6);
+ } else {
+ localhost_ether_addr = "localhost";
+ /* XXX - is this the right value to use? */
+ memset(localhost_bdaddr, 0, 6);
+ }
+
+ localhost_name_entry = (localhost_name_entry_t *)wmem_tree_lookup32_array_le(hci_data->localhost_name, key);
+ if (localhost_name_entry && localhost_name_entry->interface_id == hci_data->interface_id &&
+ localhost_name_entry->adapter_id == hci_data->adapter_id)
+ localhost_name = localhost_name_entry->name;
+ else
+ localhost_name = "";
+
+ localhost_length = (gint)(strlen(localhost_ether_addr) + 3 + strlen(localhost_name) + 1);
+ localhost_addr_name = (gchar *)wmem_alloc(pinfo->pool, localhost_length);
+
+ g_snprintf(localhost_addr_name, localhost_length, "%s (%s)", localhost_ether_addr, localhost_name);
+
+ if (pinfo->p2p_dir == P2P_DIR_RECV) {
+ SET_ADDRESS(&pinfo->net_dst, AT_STRINGZ, (int)strlen(localhost_name) + 1, localhost_name);
+ SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, localhost_bdaddr);
+ SET_ADDRESS(&pinfo->dst, AT_STRINGZ, (int)strlen(localhost_addr_name) + 1, localhost_addr_name);
+ } else if (pinfo->p2p_dir == P2P_DIR_SENT) {
+ SET_ADDRESS(&pinfo->net_src, AT_STRINGZ, (int)strlen(localhost_name) + 1, localhost_name);
+ SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, localhost_bdaddr);
+ SET_ADDRESS(&pinfo->src, AT_STRINGZ, (int)strlen(localhost_addr_name) + 1, localhost_addr_name);
+ }
+
proto_tree_add_item(bthci_sco_tree, hf_bthci_sco_data, tvb, offset, -1, ENC_NA);
return tvb_length(tvb);
diff --git a/epan/dissectors/packet-bthcrp.c b/epan/dissectors/packet-bthcrp.c
index e9754ad9c4..034df4c1df 100644
--- a/epan/dissectors/packet-bthcrp.c
+++ b/epan/dissectors/packet-bthcrp.c
@@ -33,6 +33,12 @@
#include "packet-btl2cap.h"
#include "packet-btsdp.h"
+enum {
+ FORCE_CLIENT_DEFAULT = 0,
+ FORCE_CLIENT_YES = 1,
+ FORCE_CLIENT_NO = 2
+};
+
static int proto_bthcrp = -1;
static int hf_bthcrp_notification_pdu_id = -1;
@@ -65,9 +71,10 @@ static gint ett_bthcrp = -1;
static expert_field ei_bthcrp_control_parameter_length = EI_INIT;
static expert_field ei_bthcrp_unexpected_data = EI_INIT;
+static dissector_handle_t bthcrp_handle;
static dissector_handle_t data_handle;
-static gboolean is_client = TRUE;
+static gint force_client = FORCE_CLIENT_DEFAULT;
static gint psm_control = 0;
static gint psm_data_stream = 0;
static gint psm_notification = 0;
@@ -105,9 +112,17 @@ static const value_string register_vals[] = {
{ 0, NULL }
};
+static const enum_val_t force_client_enum[] = {
+ { "default", "Default", FORCE_CLIENT_DEFAULT },
+ { "yes", "Yes", FORCE_CLIENT_YES },
+ { "no", "No", FORCE_CLIENT_NO },
+ { NULL, NULL, 0 }
+};
+
void proto_register_bthcrp(void);
void proto_reg_handoff_bthcrp(void);
+
static gint
dissect_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
gint offset, gboolean is_client_message)
@@ -126,7 +141,6 @@ dissect_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
control_pdu_id = tvb_get_ntohs(tvb, offset);
offset += 2;
-
col_append_fstr(pinfo->cinfo, COL_INFO, "Control: %s %s",
((is_client_message) ? "Request" : "Response"),
val_to_str(control_pdu_id, control_pdu_id_vals, "Unknown PDU ID"));
@@ -348,11 +362,28 @@ dissect_notification(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
static gint
dissect_bthcrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
- proto_item *main_item;
- proto_tree *main_tree;
- btl2cap_data_t *l2cap_data;
- gint offset = 0;
- gboolean is_client_message;
+ proto_item *main_item;
+ proto_tree *main_tree;
+ btl2cap_data_t *l2cap_data;
+ gint offset = 0;
+ gint protocol = -1;
+ wmem_tree_key_t key[10];
+ guint32 k_interface_id;
+ guint32 k_adapter_id;
+ 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 k_frame_number;
+ guint32 interface_id;
+ guint32 adapter_id;
+ guint32 remote_bd_addr_oui;
+ guint32 remote_bd_addr_id;
+ service_info_t *service_info;
+
+ gboolean is_client_message = FALSE;
/* Reject the packet if data is NULL */
if (data == NULL)
@@ -377,18 +408,89 @@ dissect_bthcrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
break;
}
-/* TODO: Implement streams reconizing by SDP
- * Server provide SDP record for Control and Data PSM
- * Client provide SDP record for Notification PSM (optional)
- */
- is_client_message = (is_client && pinfo->p2p_dir == P2P_DIR_SENT) ||
- (!is_client && pinfo->p2p_dir == P2P_DIR_RECV);
+ interface_id = l2cap_data->interface_id;
+ adapter_id = l2cap_data->adapter_id;
+
+ k_interface_id = interface_id;
+ k_adapter_id = adapter_id;
+ k_sdp_psm = SDP_PSM_DEFAULT;
+ k_direction = (l2cap_data->is_local_psm) ? P2P_DIR_SENT : P2P_DIR_RECV;
+ if (k_direction == P2P_DIR_RECV) {
+ k_bd_addr_oui = l2cap_data->remote_bd_addr_oui;
+ k_bd_addr_id = l2cap_data->remote_bd_addr_id;
+ } else {
+ k_bd_addr_oui = 0;
+ k_bd_addr_id = 0;
+ }
- if (psm_control != 0 && l2cap_data->psm == psm_control) {
+ remote_bd_addr_oui = k_bd_addr_oui;
+ remote_bd_addr_id = k_bd_addr_id;
+
+ k_service_type = BTSDP_L2CAP_PROTOCOL_UUID;
+ k_service_channel = l2cap_data->psm;
+ k_frame_number = pinfo->fd->num;
+
+ key[0].length = 1;
+ key[0].key = &k_interface_id;
+ key[1].length = 1;
+ key[1].key = &k_adapter_id;
+ key[2].length = 1;
+ key[2].key = &k_sdp_psm;
+ key[3].length = 1;
+ key[3].key = &k_direction;
+ key[4].length = 1;
+ key[4].key = &k_bd_addr_oui;
+ key[5].length = 1;
+ key[5].key = &k_bd_addr_id;
+ key[6].length = 1;
+ key[6].key = &k_service_type;
+ key[7].length = 1;
+ key[7].key = &k_service_channel;
+ key[8].length = 1;
+ key[8].key = &k_frame_number;
+ key[9].length = 0;
+ key[9].key = NULL;
+
+ service_info = btsdp_get_service_info(key);
+ 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 == remote_bd_addr_oui &&
+ service_info->bd_addr_id == remote_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_L2CAP_PROTOCOL_UUID &&
+ service_info->channel == l2cap_data->psm) {
+
+ if ((service_info->protocol == BTSDP_HARDCOPY_CONTROL_CHANNEL_PROTOCOL_UUID ||
+ service_info->protocol == BTSDP_HARDCOPY_DATA_CHANNEL_PROTOCOL_UUID) &&
+ ((!l2cap_data->is_local_psm && pinfo->p2p_dir == P2P_DIR_SENT) ||
+ (l2cap_data->is_local_psm && pinfo->p2p_dir == P2P_DIR_RECV))) {
+ is_client_message = TRUE;
+ } else if (service_info->protocol == BTSDP_HARDCOPY_NOTIFICATION_PROTOCOL_UUID &&
+ ((l2cap_data->is_local_psm && pinfo->p2p_dir == P2P_DIR_SENT) ||
+ (!l2cap_data->is_local_psm && pinfo->p2p_dir == P2P_DIR_RECV))) {
+ is_client_message = TRUE;
+ }
+
+ protocol = service_info->protocol;
+ }
+
+ if (force_client != FORCE_CLIENT_DEFAULT) {
+ is_client_message = (force_client == FORCE_CLIENT_YES && pinfo->p2p_dir == P2P_DIR_SENT) ||
+ (force_client != FORCE_CLIENT_YES && pinfo->p2p_dir == P2P_DIR_RECV);
+ }
+
+ if ((psm_control != 0 && l2cap_data->psm == psm_control) ||
+ (psm_control == 0 && protocol == BTSDP_HARDCOPY_CONTROL_CHANNEL_PROTOCOL_UUID)) {
offset = dissect_control(tvb, pinfo, main_tree, offset, is_client_message);
- } else if (psm_data_stream != 0 && l2cap_data->psm == psm_data_stream) {
+ } else if ((psm_data_stream != 0 && l2cap_data->psm == psm_data_stream) ||
+ (psm_data_stream == 0 && protocol == BTSDP_HARDCOPY_DATA_CHANNEL_PROTOCOL_UUID)) {
offset = dissect_data(tvb, pinfo, main_tree, offset);
- } else if (psm_notification != 0 && l2cap_data->psm == psm_notification) {
+ } else if ((psm_notification != 0 && l2cap_data->psm == psm_notification) ||
+ (psm_notification == 0 && protocol == BTSDP_HARDCOPY_NOTIFICATION_PROTOCOL_UUID)) {
offset = dissect_notification(tvb, pinfo, main_tree, offset, is_client_message);
} else {
col_append_fstr(pinfo->cinfo, COL_INFO, "HCRP stream (CID: 0x%04X)", l2cap_data->cid);
@@ -544,7 +646,7 @@ proto_register_bthcrp(void)
};
proto_bthcrp = proto_register_protocol("Bluetooth HCRP Profile", "BT HCRP", "bthcrp");
- new_register_dissector("bthcrp", dissect_bthcrp, proto_bthcrp);
+ bthcrp_handle = new_register_dissector("bthcrp", dissect_bthcrp, proto_bthcrp);
proto_register_field_array(proto_bthcrp, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
@@ -556,9 +658,12 @@ proto_register_bthcrp(void)
"Bluetooth Profile HCRP version: 1.2",
"Version of profile supported by this dissector.");
- prefs_register_bool_preference(module, "hcrp.is_client", "Client Source?",
- "If \"true\" logs should be treat as from Client side, otherwise as from Server side",
- &is_client);
+ prefs_register_obsolete_preference(module, "hcrp.is_client");
+
+ prefs_register_enum_preference(module, "hcrp.force_client", "Force Client",
+ "If \"yes\" localhost will be treat as Client, \"no\" as Server",
+ &force_client, force_client_enum, FALSE);
+
prefs_register_uint_preference(module, "hcrp.control.psm", "L2CAP PSM for Control",
"L2CAP PSM for Control",
10, &psm_control);
@@ -573,15 +678,14 @@ proto_register_bthcrp(void)
void
proto_reg_handoff_bthcrp(void)
{
- dissector_handle_t bthcrp_handle;
-
data_handle = find_dissector("data");
- bthcrp_handle = find_dissector("bthcrp");
-
dissector_add_uint("btl2cap.service", BTSDP_HARDCOPY_CONTROL_CHANNEL_PROTOCOL_UUID, bthcrp_handle);
dissector_add_uint("btl2cap.service", BTSDP_HARDCOPY_DATA_CHANNEL_PROTOCOL_UUID, bthcrp_handle);
dissector_add_uint("btl2cap.service", BTSDP_HARDCOPY_NOTIFICATION_PROTOCOL_UUID, bthcrp_handle);
+ dissector_add_uint("btl2cap.service", BTSDP_HCRP_PRINT_SERVICE_UUID, bthcrp_handle);
+ dissector_add_uint("btl2cap.service", BTSDP_HCRP_SCAN_SERVICE_UUID, bthcrp_handle);
+ dissector_add_uint("btl2cap.service", BTSDP_HCRP_SERVICE_UUID, bthcrp_handle);
dissector_add_handle("btl2cap.psm", bthcrp_handle);
dissector_add_handle("btl2cap.cid", bthcrp_handle);
diff --git a/epan/dissectors/packet-bthfp.c b/epan/dissectors/packet-bthfp.c
index ba81b22339..2ed219120c 100644
--- a/epan/dissectors/packet-bthfp.c
+++ b/epan/dissectors/packet-bthfp.c
@@ -36,7 +36,6 @@
#include <epan/packet.h>
#include <epan/prefs.h>
#include <epan/expert.h>
-#include <epan/tap.h>
#include <epan/wmem/wmem.h>
#include "packet-btrfcomm.h"
diff --git a/epan/dissectors/packet-bthsp.c b/epan/dissectors/packet-bthsp.c
index acef8a2c74..fc07332ccc 100644
--- a/epan/dissectors/packet-bthsp.c
+++ b/epan/dissectors/packet-bthsp.c
@@ -31,7 +31,6 @@
#include <epan/packet.h>
#include <epan/prefs.h>
#include <epan/expert.h>
-#include <epan/tap.h>
#include <epan/wmem/wmem.h>
#include "packet-btrfcomm.h"
diff --git a/epan/dissectors/packet-btl2cap.c b/epan/dissectors/packet-btl2cap.c
index 0fb4bf9e0e..e8d3411170 100644
--- a/epan/dissectors/packet-btl2cap.c
+++ b/epan/dissectors/packet-btl2cap.c
@@ -32,7 +32,6 @@
#include <epan/packet.h>
#include <epan/exceptions.h>
#include <epan/expert.h>
-#include <epan/tap.h>
#include <epan/wmem/wmem.h>
#include <epan/decode_as.h>
@@ -1658,6 +1657,7 @@ dissect_btl2cap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
l2cap_data->adapter_id = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
l2cap_data->chandle = (acl_data) ? acl_data->chandle : 0;
l2cap_data->cid = cid;
+ l2cap_data->is_local_psm = FALSE;
l2cap_data->psm = 0;
l2cap_data->first_scid_frame = 0;
l2cap_data->remote_bd_addr_oui = (acl_data) ? acl_data->remote_bd_addr_oui : 0;
@@ -1904,6 +1904,7 @@ dissect_btl2cap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
psm = psm_data->psm;
l2cap_data->psm = psm;
+ l2cap_data->is_local_psm = psm_data->local_service;
l2cap_data->first_scid_frame = psm_data->first_scid_frame;
l2cap_data->first_dcid_frame = psm_data->first_dcid_frame;
diff --git a/epan/dissectors/packet-btrfcomm.c b/epan/dissectors/packet-btrfcomm.c
index 0db57b80df..e59cf79ac9 100644
--- a/epan/dissectors/packet-btrfcomm.c
+++ b/epan/dissectors/packet-btrfcomm.c
@@ -35,7 +35,6 @@
#include <epan/packet.h>
#include <epan/prefs.h>
#include <epan/expert.h>
-#include <epan/tap.h>
#include <epan/uat.h>
#include <epan/wmem/wmem.h>
#include <epan/decode_as.h>
diff --git a/epan/dissectors/packet-btsdp.c b/epan/dissectors/packet-btsdp.c
index b0eb36453b..db2f8b807a 100644
--- a/epan/dissectors/packet-btsdp.c
+++ b/epan/dissectors/packet-btsdp.c
@@ -36,7 +36,6 @@
#include <epan/expert.h>
#include <epan/prefs.h>
#include <epan/etypes.h>
-#include <epan/tap.h>
#include <epan/ip_opts.h>
#include <epan/wmem/wmem.h>
#include <epan/strutil.h>
@@ -1074,8 +1073,9 @@ get_uuids(packet_info *pinfo, guint32 record_handle, btl2cap_data_t *l2cap_data)
}
-static void
-save_channel(packet_info *pinfo, guint32 protocol, guint32 channel, gint protocol_order, service_info_t *parent_service_info)
+static service_info_t *
+save_channel(packet_info *pinfo, guint32 type_protocol, guint32 channel,
+ gint protocol_order, service_info_t *parent_service_info)
{
wmem_tree_key_t key[10];
guint32 k_interface_id;
@@ -1097,11 +1097,12 @@ save_channel(packet_info *pinfo, guint32 protocol, guint32 channel, gint protoco
service_info->bd_addr_oui = parent_service_info->bd_addr_oui;
service_info->bd_addr_id = parent_service_info->bd_addr_id;
- service_info->type = protocol;
+ service_info->type = type_protocol;
service_info->channel = channel;
service_info->uuid = parent_service_info->uuid;
+ service_info->protocol = -1;
service_info->protocol_order = protocol_order;
service_info->parent_info = parent_service_info;
service_info->data = parent_service_info->data;
@@ -1139,6 +1140,8 @@ save_channel(packet_info *pinfo, guint32 protocol, guint32 channel, gint protoco
key[9].key = NULL;
wmem_tree_insert32_array(service_infos, key, service_info);
+
+ return service_info;
}
@@ -1880,25 +1883,26 @@ dissect_protocol_descriptor_list(proto_tree *next_tree, tvbuff_t *tvb,
packet_info *pinfo, gint offset, gint size, wmem_strbuf_t *info_buf,
service_info_t *service_info, gint *protocol_order)
{
- proto_tree *feature_tree;
- proto_item *feature_item;
- proto_tree *entry_tree;
- proto_item *entry_item;
- proto_tree *sub_tree;
- proto_tree *last_tree;
- gint new_offset;
- gint list_offset;
- gint entry_offset;
- gint entry_length;
- guint32 value;
- gint length;
- guint32 i_protocol;
- uuid_t uuid;
+ proto_tree *feature_tree;
+ proto_item *feature_item;
+ proto_tree *entry_tree;
+ proto_item *entry_item;
+ proto_tree *sub_tree;
+ proto_tree *last_tree;
+ gint new_offset;
+ gint list_offset;
+ gint entry_offset;
+ gint entry_length;
+ guint32 value;
+ gint length;
+ guint32 i_protocol;
+ uuid_t uuid;
+ service_info_t *record = NULL;
list_offset = offset;
i_protocol = 1;
while (list_offset - offset < size) {
- gchar *uuid_str;
+ gchar *uuid_str;
feature_item = proto_tree_add_none_format(next_tree, hf_sdp_protocol_item, tvb, list_offset, 0, "Protocol #%u", i_protocol);
feature_tree = proto_item_add_subtree(feature_item, ett_btsdp_protocol);
@@ -1934,7 +1938,7 @@ dissect_protocol_descriptor_list(proto_tree *next_tree, tvbuff_t *tvb,
proto_item_append_text(entry_item, ", PSM: %u", value);
proto_tree_add_item(sub_tree, hf_sdp_protocol_psm, tvb, entry_offset, 2, ENC_BIG_ENDIAN);
if (!pinfo->fd->flags.visited && service_info)
- save_channel(pinfo, BTSDP_L2CAP_PROTOCOL_UUID, value, *protocol_order, service_info);
+ record = save_channel(pinfo, BTSDP_L2CAP_PROTOCOL_UUID, value, *protocol_order, service_info);
*protocol_order += 1;
} else if (uuid.bt_uuid == BTSDP_RFCOMM_PROTOCOL_UUID) {
wmem_strbuf_append_printf(info_buf, ":%u", value);
@@ -1942,7 +1946,7 @@ dissect_protocol_descriptor_list(proto_tree *next_tree, tvbuff_t *tvb,
proto_item_append_text(entry_item, ", RFCOMM Channel: %u", value);
proto_tree_add_item(sub_tree, hf_sdp_protocol_channel, tvb, entry_offset, 1, ENC_BIG_ENDIAN);
if (!pinfo->fd->flags.visited && service_info)
- save_channel(pinfo, BTSDP_RFCOMM_PROTOCOL_UUID, value, *protocol_order, service_info);
+ record = save_channel(pinfo, BTSDP_RFCOMM_PROTOCOL_UUID, value, *protocol_order, service_info);
*protocol_order += 1;
} else if (uuid.bt_uuid == BTSDP_ATT_PROTOCOL_UUID) {
proto_item_append_text(feature_item, ", GATT Handle Start: 0x%04x", value);
@@ -2006,6 +2010,9 @@ dissect_protocol_descriptor_list(proto_tree *next_tree, tvbuff_t *tvb,
if (list_offset - offset < size)
wmem_strbuf_append(info_buf, " -> ");
+
+ if (record)
+ record->protocol = uuid.bt_uuid;
}
}
@@ -3738,6 +3745,7 @@ dissect_sdp_service_attribute_list(proto_tree *tree, tvbuff_t *tvb, gint offset,
service_info->type = 0;
service_info->channel = 0;
service_info->protocol_order = 0;
+ service_info->protocol = -1;
service_info->parent_info = NULL;
} else {
service_info = NULL;
diff --git a/epan/dissectors/packet-btsdp.h b/epan/dissectors/packet-btsdp.h
index e85b3dfc14..1fca6d8488 100644
--- a/epan/dissectors/packet-btsdp.h
+++ b/epan/dissectors/packet-btsdp.h
@@ -165,7 +165,7 @@ typedef struct _uuid_t {
guint8 data[16];
} uuid_t;
-/* This structure is passed to other dissectors through the tap interface
+/* This structure is passed to other dissectors
* and contains information about the relation between service, PSM/server
* channel, local/remote service. The btrfcomm and btl2cap dissectors
* need this information to determine the kind of data transfered on
@@ -196,6 +196,7 @@ typedef struct _service_info_t {
uuid_t uuid;
gint protocol_order; /* main service protocol has 0, goep -1, additional protocol 1, 2... */
+ gint protocol;
void *data; /* Used to transfer service record data to profiles */