diff options
author | Michal Labedzki <michal.labedzki@tieto.com> | 2015-12-14 17:28:06 +0100 |
---|---|---|
committer | Michal Labedzki <michal.labedzki@tieto.com> | 2016-01-20 11:47:40 +0000 |
commit | d51989e3ac8b1bab43a89ef07e12065a1c7485a0 (patch) | |
tree | 9b9495af5ff2577227a9ac1b729ee277b431bbe6 | |
parent | 5de7817315eddd5ee712d1bf9bfd4e379dbdb624 (diff) |
Bluetooth: Add dissector table for EIR/AD Manufacturer content
Now it is possible to DecodeAs manufacturer specific content of
EIR or AD, so you are able to write custom plugin to dissect it.
New dissector table: btcommon.eir_ad.manufacturer_company_id
Change-Id: Iac458cd51f7b9bab51ccf7a4411984fb269a86ef
Reviewed-on: https://code.wireshark.org/review/13389
Petri-Dish: Michal Labedzki <michal.labedzki@tieto.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michal Labedzki <michal.labedzki@tieto.com>
-rw-r--r-- | epan/dissectors/packet-bluetooth.h | 8 | ||||
-rw-r--r-- | epan/dissectors/packet-bthci_cmd.c | 100 | ||||
-rw-r--r-- | epan/dissectors/packet-bthci_evt.c | 32 |
3 files changed, 123 insertions, 17 deletions
diff --git a/epan/dissectors/packet-bluetooth.h b/epan/dissectors/packet-bluetooth.h index 112cdde5fa..6637a9e144 100644 --- a/epan/dissectors/packet-bluetooth.h +++ b/epan/dissectors/packet-bluetooth.h @@ -251,6 +251,14 @@ typedef struct _bluetooth_hci_summary_tap_t { enum bluetooth_hci_summary_type type; } bluetooth_hci_summary_tap_t; +typedef struct _bluetooth_eir_ad_data_t { + guint32 interface_id; + guint32 adapter_id; + + guint8 *bd_addr; +} bluetooth_eir_ad_data_t; + + extern int bluetooth_device_tap; extern int bluetooth_hci_summary_tap; diff --git a/epan/dissectors/packet-bthci_cmd.c b/epan/dissectors/packet-bthci_cmd.c index c5bbbca151..ef87a50696 100644 --- a/epan/dissectors/packet-bthci_cmd.c +++ b/epan/dissectors/packet-bthci_cmd.c @@ -559,6 +559,8 @@ static dissector_handle_t btcommon_ad_handle; static dissector_handle_t btcommon_le_channel_map_handle; static dissector_handle_t bthci_cmd_handle; +static dissector_table_t bluetooth_eir_ad_manufacturer_company_id; + wmem_tree_t *bthci_cmds = NULL; extern value_string_ext ext_usb_vendors_vals; @@ -2568,12 +2570,22 @@ dissect_host_controller_baseband_cmd(tvbuff_t *tvb, int offset, packet_info *pin break; case 0x0052: /* Write Extended Inquiry Response */ + { + bluetooth_eir_ad_data_t *eir_data; + + eir_data = wmem_new0(wmem_packet_scope(), bluetooth_eir_ad_data_t); + eir_data->interface_id = bluetooth_data->interface_id; + eir_data->adapter_id = bluetooth_data->adapter_id; + eir_data->bd_addr = NULL; + proto_tree_add_item(tree, hf_bthci_cmd_fec_required, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; - call_dissector_with_data(btcommon_eir_handle, tvb_new_subset_length(tvb, offset, 240), pinfo, tree, bluetooth_data); + call_dissector_with_data(btcommon_eir_handle, tvb_new_subset_length(tvb, offset, 240), pinfo, tree, eir_data); save_local_device_name_from_eir_ad(tvb, offset, pinfo, 240, bluetooth_data); offset += 240; + + } break; case 0x0053: /* Refresh Encryption Key */ @@ -2923,12 +2935,22 @@ dissect_le_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, case 0x0008: /* LE Set Advertising Data */ case 0x0009: /* LE Set Scan Response Data */ + { + bluetooth_eir_ad_data_t *ad_data; + + ad_data = wmem_new0(wmem_packet_scope(), bluetooth_eir_ad_data_t); + ad_data->interface_id = bluetooth_data->interface_id; + ad_data->adapter_id = bluetooth_data->adapter_id; + ad_data->bd_addr = NULL; + proto_tree_add_item(tree, hf_bthci_cmd_le_data_length, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; - call_dissector_with_data(btcommon_ad_handle, tvb_new_subset_length(tvb, offset, 31), pinfo, tree, bluetooth_data); + call_dissector_with_data(btcommon_ad_handle, tvb_new_subset_length(tvb, offset, 31), pinfo, tree, ad_data); save_local_device_name_from_eir_ad(tvb, offset, pinfo, 31, bluetooth_data); offset += 31; + + } break; case 0x000a: /* LE Set Advertise Enable */ @@ -4926,8 +4948,33 @@ proto_reg_handoff_bthci_cmd(void) } +#define PROTO_DATA_BLUETOOTH_EIR_AD_MANUFACTURER_COMPANY_ID 0 + +static void bluetooth_eir_ad_manufacturer_company_id_prompt(packet_info *pinfo, gchar* result) +{ + guint16 *value_data; + + value_data = (guint16 *) p_get_proto_data(pinfo->pool, pinfo, proto_btcommon, PROTO_DATA_BLUETOOTH_EIR_AD_MANUFACTURER_COMPANY_ID); + if (value_data) + g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "EIR/AD Manufacturer Company ID 0x%02x as", (guint) *value_data); + else + g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Unknown EIR/AD Manufacturer"); +} + +static gpointer bluetooth_eir_ad_manufacturer_company_id_value(packet_info *pinfo) +{ + guint16 *value_data; + + value_data = (guint16 *) p_get_proto_data(pinfo->pool, pinfo, proto_btcommon, PROTO_DATA_BLUETOOTH_EIR_AD_MANUFACTURER_COMPANY_ID); + + if (value_data) + return GUINT_TO_POINTER((gulong)*value_data); + + return NULL; +} + static gint -dissect_eir_ad_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, bluetooth_data_t *bluetooth_data) +dissect_eir_ad_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, bluetooth_eir_ad_data_t *bluetooth_eir_ad_data) { proto_item *entry_item; proto_tree *entry_tree; @@ -4943,7 +4990,7 @@ dissect_eir_ad_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, bluetoo guint8 bd_addr[6]; guint8 *name = NULL; - DISSECTOR_ASSERT(bluetooth_data); + DISSECTOR_ASSERT(bluetooth_eir_ad_data); data_size = tvb_reported_length(tvb); @@ -5095,7 +5142,7 @@ dissect_eir_ad_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, bluetoo break; case 0x0C: /* BD_ADDR */ /* From CSS v3.pdf */ - offset = dissect_bd_addr(hf_btcommon_eir_ad_bd_addr, pinfo, tree, tvb, offset, FALSE, bluetooth_data->interface_id, bluetooth_data->adapter_id, bd_addr); + offset = dissect_bd_addr(hf_btcommon_eir_ad_bd_addr, pinfo, tree, tvb, offset, FALSE, bluetooth_eir_ad_data->interface_id, bluetooth_eir_ad_data->adapter_id, bd_addr); has_bd_addr = TRUE; break; @@ -5190,7 +5237,7 @@ dissect_eir_ad_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, bluetoo case 0x18: /* Random Target Address */ end_offset = offset + length; while (offset < end_offset) { - offset = dissect_bd_addr(hf_btcommon_eir_ad_bd_addr, pinfo, entry_tree, tvb, offset, FALSE, bluetooth_data->interface_id, bluetooth_data->adapter_id, NULL); + offset = dissect_bd_addr(hf_btcommon_eir_ad_bd_addr, pinfo, entry_tree, tvb, offset, FALSE, bluetooth_eir_ad_data->interface_id, bluetooth_eir_ad_data->adapter_id, NULL); } break; @@ -5212,7 +5259,7 @@ dissect_eir_ad_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, bluetoo proto_tree_add_item(entry_tree, hf_btcommon_eir_ad_le_bd_addr_type, tvb, offset, 1, ENC_NA); offset += 1; - offset = dissect_bd_addr(hf_btcommon_eir_ad_bd_addr, pinfo, entry_tree, tvb, offset, FALSE, bluetooth_data->interface_id, bluetooth_data->adapter_id, NULL); + offset = dissect_bd_addr(hf_btcommon_eir_ad_bd_addr, pinfo, entry_tree, tvb, offset, FALSE, bluetooth_eir_ad_data->interface_id, bluetooth_eir_ad_data->adapter_id, NULL); break; case 0x1C: /* LE Role */ @@ -5313,6 +5360,15 @@ dissect_eir_ad_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, bluetoo offset += 2; length -= 2; + if (p_get_proto_data(pinfo->pool, pinfo, proto_btcommon, PROTO_DATA_BLUETOOTH_EIR_AD_MANUFACTURER_COMPANY_ID) == NULL) { + guint16 *value_data; + + value_data = wmem_new(wmem_file_scope(), guint16); + *value_data = company_id; + + p_add_proto_data(pinfo->pool, pinfo, proto_btcommon, PROTO_DATA_BLUETOOTH_EIR_AD_MANUFACTURER_COMPANY_ID, value_data); + } + if (company_id == 0x000F && tvb_get_guint8(tvb, offset) == 0) { /* 3DS profile Legacy Devices */ proto_tree_add_item(entry_tree, hf_btcommon_eir_ad_3ds_legacy_fixed, tvb, offset, 1, ENC_NA); offset += 1; @@ -5328,8 +5384,15 @@ dissect_eir_ad_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, bluetoo proto_tree_add_item(entry_tree, hf_btcommon_eir_ad_3ds_legacy_path_loss_threshold, tvb, offset, 1, ENC_NA); offset += 1; } else { - sub_item = proto_tree_add_item(entry_tree, hf_btcommon_eir_ad_data, tvb, offset, length, ENC_NA); - expert_add_info(pinfo, sub_item, &ei_eir_ad_undecoded); + tvbuff_t *new_tvb; + + new_tvb = tvb_new_subset_length(tvb, offset, length); + + if (!dissector_try_uint_new(bluetooth_eir_ad_manufacturer_company_id, company_id, new_tvb, pinfo, tree, TRUE, bluetooth_eir_ad_data)) { + sub_item = proto_tree_add_item(entry_tree, hf_btcommon_eir_ad_data, tvb, offset, length, ENC_NA); + expert_add_info(pinfo, sub_item, &ei_eir_ad_undecoded); + } + offset += length; } } @@ -5356,9 +5419,9 @@ dissect_eir_ad_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, bluetoo bluetooth_device_tap_t *tap_device; tap_device = wmem_new(wmem_packet_scope(), bluetooth_device_tap_t); - if (bluetooth_data) { - tap_device->interface_id = bluetooth_data->interface_id; - tap_device->adapter_id = bluetooth_data->adapter_id; + if (bluetooth_eir_ad_data) { + tap_device->interface_id = bluetooth_eir_ad_data->interface_id; + tap_device->adapter_id = bluetooth_eir_ad_data->adapter_id; } else { tap_device->interface_id = HCI_INTERFACE_DEFAULT; tap_device->adapter_id = HCI_ADAPTER_DEFAULT; @@ -5487,7 +5550,7 @@ dissect_btcommon_ad(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *d main_item = proto_tree_add_item(tree, hf_btcommon_eir_ad_advertising_data, tvb, 0, -1, ENC_NA); main_tree = proto_item_add_subtree(main_item, ett_eir_ad); - return dissect_eir_ad_data(tvb, pinfo, main_tree, (bluetooth_data_t *) data); + return dissect_eir_ad_data(tvb, pinfo, main_tree, (bluetooth_eir_ad_data_t *) data); } static gint @@ -5499,7 +5562,7 @@ dissect_btcommon_eir(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void * main_item = proto_tree_add_item(tree, hf_btcommon_eir_ad_extended_inquiry_response_data, tvb, 0, -1, ENC_NA); main_tree = proto_item_add_subtree(main_item, ett_eir_ad); - return dissect_eir_ad_data(tvb, pinfo, main_tree, (bluetooth_data_t *) data); + return dissect_eir_ad_data(tvb, pinfo, main_tree, (bluetooth_eir_ad_data_t *) data); } static gint @@ -6329,6 +6392,11 @@ proto_register_btcommon(void) { &ei_eir_ad_not_used, { "btcommon.eir_ad.not_used", PI_PROTOCOL, PI_WARN, "Value should not be used", EXPFILL }}, }; + static build_valid_func bluetooth_eir_ad_manufacturer_company_id_da_build_value[1] = {bluetooth_eir_ad_manufacturer_company_id_value}; + static decode_as_value_t bluetooth_eir_ad_manufacturer_company_id_da_values = {bluetooth_eir_ad_manufacturer_company_id_prompt, 1, bluetooth_eir_ad_manufacturer_company_id_da_build_value}; + static decode_as_t bluetooth_eir_ad_manufacturer_company_id_da = {"btcommon.eir_ad", "EIR/AD Manufacturer Company ID", "btcommon.eir_ad.manufacturer_company_id", 1, 0, &bluetooth_eir_ad_manufacturer_company_id_da_values, NULL, NULL, + decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL}; + proto_btcommon = proto_register_protocol("Bluetooth Common", "BT Common", "btcommon"); proto_register_field_array(proto_btcommon, hf, array_length(hf)); @@ -6341,6 +6409,10 @@ proto_register_btcommon(void) btcommon_eir_handle = register_dissector("btcommon.eir_ad.eir", dissect_btcommon_eir, proto_btcommon); btcommon_cod_handle = register_dissector("btcommon.cod", dissect_btcommon_cod, proto_btcommon); btcommon_le_channel_map_handle = register_dissector("btcommon.le_channel_map", dissect_btcommon_le_channel_map, proto_btcommon); + + bluetooth_eir_ad_manufacturer_company_id = register_dissector_table("btcommon.eir_ad.manufacturer_company_id", "BT EIR/AD Manufacturer Company ID", FT_UINT16, BASE_HEX, DISSECTOR_TABLE_NOT_ALLOW_DUPLICATE); + + register_decode_as(&bluetooth_eir_ad_manufacturer_company_id_da); } /* diff --git a/epan/dissectors/packet-bthci_evt.c b/epan/dissectors/packet-bthci_evt.c index 7cf68a5bda..e939f1aaea 100644 --- a/epan/dissectors/packet-bthci_evt.c +++ b/epan/dissectors/packet-bthci_evt.c @@ -2054,7 +2054,14 @@ dissect_bthci_evt_le_meta(tvbuff_t *tvb, int offset, packet_info *pinfo, offset += 1; if (length > 0) { - call_dissector_with_data(btcommon_ad_handle, tvb_new_subset_length(tvb, offset, length), pinfo, tree, bluetooth_data); + bluetooth_eir_ad_data_t *ad_data; + + ad_data = wmem_new0(wmem_packet_scope(), bluetooth_eir_ad_data_t); + ad_data->interface_id = bluetooth_data->interface_id; + ad_data->adapter_id = bluetooth_data->adapter_id; + ad_data->bd_addr = bd_addr; + + call_dissector_with_data(btcommon_ad_handle, tvb_new_subset_length(tvb, offset, length), pinfo, tree, ad_data); save_remote_device_name(tvb, offset, pinfo, length, bd_addr, bluetooth_data); offset += length; } @@ -2944,6 +2951,14 @@ dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset, break; case 0x0c51: /* Read Extended Inquiry Response */ + { + bluetooth_eir_ad_data_t *eir_data; + + eir_data = wmem_new0(wmem_packet_scope(), bluetooth_eir_ad_data_t); + eir_data->interface_id = bluetooth_data->interface_id; + eir_data->adapter_id = bluetooth_data->adapter_id; + eir_data->bd_addr = NULL; + proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); send_hci_summary_status_tap(tvb_get_guint8(tvb, offset), pinfo, bluetooth_data); offset += 1; @@ -2951,9 +2966,10 @@ dissect_bthci_evt_command_complete(tvbuff_t *tvb, int offset, proto_tree_add_item(tree, hf_bthci_evt_fec_required, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; - call_dissector_with_data(btcommon_eir_handle, tvb_new_subset_length(tvb, offset, 240), pinfo, tree, bluetooth_data); + call_dissector_with_data(btcommon_eir_handle, tvb_new_subset_length(tvb, offset, 240), pinfo, tree, eir_data); offset += 240; + } break; case 0x0c55: /* Read Simple Pairing Mode */ @@ -4206,12 +4222,22 @@ dissect_bthci_evt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat break; case 0x2f: /* Extended Inquiry Result */ + { + bluetooth_eir_ad_data_t *eir_data; + previous_offset = offset; offset = dissect_bthci_evt_inquire_result_with_rssi(tvb, offset, pinfo, bthci_evt_tree, bluetooth_data, bd_addr); - call_dissector_with_data(btcommon_eir_handle, tvb_new_subset_length(tvb, offset, 240), pinfo, bthci_evt_tree, bluetooth_data); + eir_data = wmem_new0(wmem_packet_scope(), bluetooth_eir_ad_data_t); + eir_data->interface_id = bluetooth_data->interface_id; + eir_data->adapter_id = bluetooth_data->adapter_id; + eir_data->bd_addr = bd_addr; + + + call_dissector_with_data(btcommon_eir_handle, tvb_new_subset_length(tvb, offset, 240), pinfo, bthci_evt_tree, eir_data); save_remote_device_name(tvb, offset, pinfo, 240, (offset - previous_offset <= 1) ? NULL : bd_addr, bluetooth_data); offset += 240; + } break; |