/src/wireshark/epan/dissectors/packet-bluetooth.c
Line | Count | Source |
1 | | /* packet-bluetooth.c |
2 | | * Routines for the Bluetooth |
3 | | * |
4 | | * Copyright 2014, Michal Labedzki for Tieto Corporation |
5 | | * |
6 | | * Dissector for Bluetooth High Speed over wireless |
7 | | * Copyright 2012 intel Corp. |
8 | | * Written by Andrei Emeltchenko at intel dot com |
9 | | * |
10 | | * Wireshark - Network traffic analyzer |
11 | | * By Gerald Combs <gerald@wireshark.org> |
12 | | * Copyright 1998 Gerald Combs |
13 | | * |
14 | | * SPDX-License-Identifier: GPL-2.0-or-later |
15 | | */ |
16 | | |
17 | | #include "config.h" |
18 | | |
19 | | #include <string.h> |
20 | | #include <epan/packet.h> |
21 | | #include <epan/prefs.h> |
22 | | #include <epan/uat.h> |
23 | | #include <epan/to_str.h> |
24 | | #include <epan/conversation_table.h> |
25 | | #include <epan/decode_as.h> |
26 | | #include <epan/proto_data.h> |
27 | | #include <epan/unit_strings.h> |
28 | | #include <epan/uuid_types.h> |
29 | | #include <wiretap/wtap.h> |
30 | | #include "packet-llc.h" |
31 | | #include <epan/oui.h> |
32 | | |
33 | | #include <wsutil/str_util.h> |
34 | | |
35 | | #include "packet-bluetooth.h" |
36 | | |
37 | | static dissector_handle_t bluetooth_handle; |
38 | | static dissector_handle_t bluetooth_bthci_handle; |
39 | | static dissector_handle_t bluetooth_btmon_handle; |
40 | | static dissector_handle_t bluetooth_usb_handle; |
41 | | |
42 | | int proto_bluetooth; |
43 | | |
44 | | static int hf_bluetooth_src; |
45 | | static int hf_bluetooth_dst; |
46 | | static int hf_bluetooth_addr; |
47 | | static int hf_bluetooth_src_str; |
48 | | static int hf_bluetooth_dst_str; |
49 | | static int hf_bluetooth_addr_str; |
50 | | |
51 | | static int hf_llc_bluetooth_pid; |
52 | | |
53 | | static int ett_bluetooth; |
54 | | |
55 | | static dissector_handle_t btle_handle; |
56 | | static dissector_handle_t hci_usb_handle; |
57 | | |
58 | | static dissector_table_t bluetooth_table; |
59 | | static dissector_table_t hci_vendor_table; |
60 | | dissector_table_t bluetooth_uuid_table; |
61 | | |
62 | | static wmem_tree_t *chandle_sessions; |
63 | | static wmem_tree_t *chandle_to_bdaddr; |
64 | | static wmem_tree_t *chandle_to_mode; |
65 | | static wmem_tree_t *shandle_to_chandle; |
66 | | static wmem_tree_t *bdaddr_to_name; |
67 | | static wmem_tree_t *bdaddr_to_role; |
68 | | static wmem_tree_t *localhost_name; |
69 | | static wmem_tree_t *localhost_bdaddr; |
70 | | static wmem_tree_t *hci_vendors; |
71 | | static wmem_tree_t *cs_configurations; |
72 | | |
73 | | static int bluetooth_uuid_id; |
74 | | |
75 | | static int bluetooth_tap; |
76 | | int bluetooth_device_tap; |
77 | | int bluetooth_hci_summary_tap; |
78 | | |
79 | | // UAT structure |
80 | | typedef struct _bt_uuid_uat_t { |
81 | | char *uuid; |
82 | | char *label; |
83 | | bool long_attr; |
84 | | } bt_uuid_uat_t; |
85 | | static bt_uuid_uat_t* bt_uuids; |
86 | | static unsigned num_bt_uuids; |
87 | | |
88 | | static bluetooth_uuid_t get_bluetooth_uuid_from_str(const char *str); |
89 | | |
90 | | const value_string bluetooth_address_type_vals[] = { |
91 | | { 0x00, "Public" }, |
92 | | { 0x01, "Random" }, |
93 | | { 0, NULL } |
94 | | }; |
95 | | |
96 | | /* |
97 | | * BLUETOOTH SPECIFICATION Version 4.0 [Vol 5] defines that |
98 | | * before transmission, the PAL shall remove the HCI header, |
99 | | * add LLC and SNAP headers and insert an 802.11 MAC header. |
100 | | * Protocol identifier are described in Table 5.2. |
101 | | */ |
102 | | |
103 | 15 | #define AMP_U_L2CAP 0x0001 |
104 | | #define AMP_C_ACTIVITY_REPORT 0x0002 |
105 | 15 | #define AMP_C_SECURITY_FRAME 0x0003 |
106 | | #define AMP_C_LINK_SUP_REQUEST 0x0004 |
107 | | #define AMP_C_LINK_SUP_REPLY 0x0005 |
108 | | |
109 | | static const value_string bluetooth_pid_vals[] = { |
110 | | { AMP_U_L2CAP, "AMP_U L2CAP ACL data" }, |
111 | | { AMP_C_ACTIVITY_REPORT, "AMP-C Activity Report" }, |
112 | | { AMP_C_SECURITY_FRAME, "AMP-C Security frames" }, |
113 | | { AMP_C_LINK_SUP_REQUEST, "AMP-C Link supervision request" }, |
114 | | { AMP_C_LINK_SUP_REPLY, "AMP-C Link supervision reply" }, |
115 | | { 0, NULL } |
116 | | }; |
117 | | |
118 | | uint32_t bluetooth_max_disconnect_in_frame = UINT32_MAX; |
119 | | |
120 | | |
121 | | void proto_register_bluetooth(void); |
122 | | void proto_reg_handoff_bluetooth(void); |
123 | | |
124 | | /* UAT routines */ |
125 | | static bool |
126 | | bt_uuids_update_cb(void *r, char **err) |
127 | 0 | { |
128 | 0 | bt_uuid_uat_t *rec = (bt_uuid_uat_t *)r; |
129 | 0 | bluetooth_uuid_t uuid; |
130 | |
|
131 | 0 | if (rec->uuid == NULL) { |
132 | 0 | *err = g_strdup("UUID can't be empty"); |
133 | 0 | return false; |
134 | 0 | } |
135 | 0 | g_strstrip(rec->uuid); |
136 | 0 | if (rec->uuid[0] == 0) { |
137 | 0 | *err = g_strdup("UUID can't be empty"); |
138 | 0 | return false; |
139 | 0 | } |
140 | | |
141 | 0 | uuid = get_bluetooth_uuid_from_str(rec->uuid); |
142 | 0 | if (uuid.size == 0) { |
143 | 0 | *err = g_strdup("UUID must be 16, 32, or 128-bit, with the latter formatted as XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); |
144 | 0 | return false; |
145 | 0 | } |
146 | | /* print_numeric_bluetooth_uuid uses bytes_to_hexstr, which uses |
147 | | * lowercase hex digits. */ |
148 | 0 | rec->uuid = ascii_strdown_inplace(rec->uuid); |
149 | |
|
150 | 0 | if (rec->label == NULL) { |
151 | 0 | *err = g_strdup("UUID Name can't be empty"); |
152 | 0 | return false; |
153 | 0 | } |
154 | 0 | g_strstrip(rec->label); |
155 | 0 | if (rec->label[0] == 0) { |
156 | 0 | *err = g_strdup("UUID Name can't be empty"); |
157 | 0 | return false; |
158 | 0 | } |
159 | | |
160 | 0 | *err = NULL; |
161 | 0 | return true; |
162 | 0 | } |
163 | | |
164 | | static void * |
165 | | bt_uuids_copy_cb(void* n, const void* o, size_t siz _U_) |
166 | 0 | { |
167 | 0 | bt_uuid_uat_t* new_rec = (bt_uuid_uat_t*)n; |
168 | 0 | const bt_uuid_uat_t* old_rec = (const bt_uuid_uat_t*)o; |
169 | |
|
170 | 0 | new_rec->uuid = g_strdup(old_rec->uuid); |
171 | 0 | new_rec->label = g_strdup(old_rec->label); |
172 | 0 | new_rec->long_attr = old_rec->long_attr; |
173 | |
|
174 | 0 | return new_rec; |
175 | 0 | } |
176 | | |
177 | | static void |
178 | | bt_uuids_free_cb(void*r) |
179 | 0 | { |
180 | 0 | bt_uuid_uat_t* rec = (bt_uuid_uat_t*)r; |
181 | |
|
182 | 0 | bluetooth_uuid_t uuid = get_bluetooth_uuid_from_str(rec->uuid); |
183 | 0 | uuid_type_remove_if_present(bluetooth_uuid_id, &uuid); |
184 | 0 | g_free(rec->uuid); |
185 | 0 | g_free(rec->label); |
186 | 0 | } |
187 | | |
188 | | static void |
189 | | bt_uuids_post_update_cb(void) |
190 | 15 | { |
191 | 15 | if (num_bt_uuids) { |
192 | 0 | for (unsigned i = 0; i < num_bt_uuids; i++) { |
193 | 0 | bluetooth_uuid_t uuid = get_bluetooth_uuid_from_str(bt_uuids[i].uuid); |
194 | 0 | bluetooth_uuid_t* uuid_copy = wmem_memdup(wmem_epan_scope(), &uuid, sizeof(uuid)); |
195 | 0 | uuid_type_insert(bluetooth_uuid_id, uuid_copy, &bt_uuids[i]); |
196 | 0 | } |
197 | 0 | } |
198 | 15 | } |
199 | | |
200 | | static void |
201 | | bt_uuids_reset_cb(void) |
202 | 0 | { |
203 | 0 | } |
204 | | |
205 | 0 | UAT_CSTRING_CB_DEF(bt_uuids, uuid, bt_uuid_uat_t) |
206 | 0 | UAT_CSTRING_CB_DEF(bt_uuids, label, bt_uuid_uat_t) |
207 | 0 | UAT_BOOL_CB_DEF(bt_uuids, long_attr, bt_uuid_uat_t) |
208 | | |
209 | | static unsigned |
210 | | bluetooth_uuid_hash(const void* uuid) |
211 | 17.0k | { |
212 | 17.0k | const bluetooth_uuid_t* bt_uuid = (const bluetooth_uuid_t*)uuid; |
213 | 17.0k | return wmem_strong_hash(bt_uuid->data, bt_uuid->size); |
214 | 17.0k | } |
215 | | |
216 | | static gboolean |
217 | | bluetooth_uuid_equal(const void* u1, const void* u2) |
218 | 0 | { |
219 | 0 | const bluetooth_uuid_t *bt_u1 = (const bluetooth_uuid_t*)u1, |
220 | 0 | *bt_u2 = (const bluetooth_uuid_t*)u2; |
221 | 0 | if (bt_u1->bt_uuid != bt_u2->bt_uuid) |
222 | 0 | return false; |
223 | | |
224 | 0 | if (bt_u1->size != bt_u2->size) |
225 | 0 | return false; |
226 | | |
227 | 0 | return (memcmp(bt_u1->data, bt_u2->data, bt_u1->size) == 0); |
228 | 0 | } |
229 | | |
230 | | static const char* |
231 | | bluetooth_uuid_to_str(void* uuid, wmem_allocator_t* scope) |
232 | 0 | { |
233 | 0 | return print_numeric_bluetooth_uuid(scope, (const bluetooth_uuid_t*)uuid); |
234 | 0 | } |
235 | | |
236 | | void bluetooth_add_custom_uuid(const char *uuid_str, const char *label, bool long_attr) |
237 | 765 | { |
238 | 765 | bluetooth_uuid_t uuid = get_bluetooth_uuid_from_str(uuid_str); |
239 | 765 | if (uuid.size > 0) |
240 | 765 | { |
241 | | //Now that the UUID is valid, add it to the table |
242 | 765 | bluetooth_uuid_t* uuid_copy = wmem_memdup(wmem_epan_scope(), &uuid, sizeof(uuid)); |
243 | 765 | bt_uuid_uat_t* custom_uuid = wmem_new(wmem_epan_scope(), bt_uuid_uat_t); |
244 | | |
245 | 765 | custom_uuid->uuid = wmem_strdup(wmem_epan_scope(), uuid_str); |
246 | 765 | custom_uuid->label = wmem_strdup(wmem_epan_scope(), label); |
247 | 765 | custom_uuid->long_attr = long_attr; |
248 | | |
249 | 765 | uuid_type_insert(bluetooth_uuid_id, uuid_copy, custom_uuid); |
250 | 765 | } |
251 | 765 | } |
252 | | |
253 | | bool bluetooth_get_custom_uuid_long_attr(const bluetooth_uuid_t *uuid) |
254 | 1 | { |
255 | 1 | bt_uuid_uat_t* custom_uuid = (bt_uuid_uat_t*)uuid_type_lookup(bluetooth_uuid_id, (void*)uuid); |
256 | 1 | if (custom_uuid) { |
257 | 0 | return custom_uuid->long_attr; |
258 | 0 | } |
259 | 1 | return false; |
260 | 1 | } |
261 | | |
262 | | const char* bluetooth_get_custom_uuid_description(const bluetooth_uuid_t *uuid) |
263 | 16.3k | { |
264 | 16.3k | bt_uuid_uat_t* custom_uuid = (bt_uuid_uat_t*)uuid_type_lookup(bluetooth_uuid_id, (void*)uuid); |
265 | 16.3k | if (custom_uuid) { |
266 | 0 | return custom_uuid->label; |
267 | 0 | } |
268 | 16.3k | return NULL; |
269 | 16.3k | } |
270 | | |
271 | | /* Decode As routines */ |
272 | | static void bluetooth_uuid_prompt(packet_info *pinfo, char* result) |
273 | 0 | { |
274 | 0 | char *value_data; |
275 | |
|
276 | 0 | value_data = (char *) p_get_proto_data(pinfo->pool, pinfo, proto_bluetooth, PROTO_DATA_BLUETOOTH_SERVICE_UUID); |
277 | 0 | if (value_data) |
278 | 0 | snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "BT Service UUID %s as", (char *) value_data); |
279 | 0 | else |
280 | 0 | snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Unknown BT Service UUID"); |
281 | 0 | } |
282 | | |
283 | | static void *bluetooth_uuid_value(packet_info *pinfo) |
284 | 0 | { |
285 | 0 | char *value_data; |
286 | |
|
287 | 0 | value_data = (char *) p_get_proto_data(pinfo->pool, pinfo, proto_bluetooth, PROTO_DATA_BLUETOOTH_SERVICE_UUID); |
288 | |
|
289 | 0 | if (value_data) |
290 | 0 | return (void *) value_data; |
291 | | |
292 | 0 | return NULL; |
293 | 0 | } |
294 | | |
295 | | int |
296 | | dissect_bd_addr(int hf_bd_addr, packet_info *pinfo, proto_tree *tree, |
297 | | tvbuff_t *tvb, int offset, bool is_local_bd_addr, |
298 | | uint32_t interface_id, uint32_t adapter_id, uint8_t *bdaddr) |
299 | 701 | { |
300 | 701 | uint8_t bd_addr[6]; |
301 | | |
302 | 701 | bd_addr[5] = tvb_get_uint8(tvb, offset); |
303 | 701 | bd_addr[4] = tvb_get_uint8(tvb, offset + 1); |
304 | 701 | bd_addr[3] = tvb_get_uint8(tvb, offset + 2); |
305 | 701 | bd_addr[2] = tvb_get_uint8(tvb, offset + 3); |
306 | 701 | bd_addr[1] = tvb_get_uint8(tvb, offset + 4); |
307 | 701 | bd_addr[0] = tvb_get_uint8(tvb, offset + 5); |
308 | | |
309 | 701 | proto_tree_add_ether(tree, hf_bd_addr, tvb, offset, 6, bd_addr); |
310 | 701 | offset += 6; |
311 | | |
312 | 701 | if (have_tap_listener(bluetooth_device_tap)) { |
313 | 0 | bluetooth_device_tap_t *tap_device; |
314 | |
|
315 | 0 | tap_device = wmem_new(pinfo->pool, bluetooth_device_tap_t); |
316 | 0 | tap_device->interface_id = interface_id; |
317 | 0 | tap_device->adapter_id = adapter_id; |
318 | 0 | memcpy(tap_device->bd_addr, bd_addr, 6); |
319 | 0 | tap_device->has_bd_addr = true; |
320 | 0 | tap_device->is_local = is_local_bd_addr; |
321 | 0 | tap_device->type = BLUETOOTH_DEVICE_BD_ADDR; |
322 | 0 | tap_queue_packet(bluetooth_device_tap, pinfo, tap_device); |
323 | 0 | } |
324 | | |
325 | 701 | if (bdaddr) |
326 | 110 | memcpy(bdaddr, bd_addr, 6); |
327 | | |
328 | 701 | return offset; |
329 | 701 | } |
330 | | |
331 | 0 | void bluetooth_unit_0p625_ms(char *buf, uint32_t value) { |
332 | 0 | snprintf(buf, ITEM_LABEL_LENGTH, "%g ms (%u slots)", 0.625 * value, value); |
333 | 0 | } |
334 | | |
335 | 0 | void bluetooth_unit_1p25_ms(char *buf, uint32_t value) { |
336 | 0 | snprintf(buf, ITEM_LABEL_LENGTH, "%g ms (%u slot-pairs)", 1.25 * value, value); |
337 | 0 | } |
338 | | |
339 | 0 | void bluetooth_unit_0p01_sec(char *buf, uint32_t value) { |
340 | 0 | snprintf(buf, ITEM_LABEL_LENGTH, "%g sec (%u)", 0.01 * value, value); |
341 | 0 | } |
342 | | |
343 | 0 | void bluetooth_unit_0p125_ms(char *buf, uint32_t value) { |
344 | 0 | snprintf(buf, ITEM_LABEL_LENGTH, "%g ms (%u)", 0.125 * value, value); |
345 | 0 | } |
346 | | |
347 | | const value_string bluetooth_procedure_count_special[] = { |
348 | | {0x0, "Infinite, Continue until disabled"}, |
349 | | {0, NULL} |
350 | | }; |
351 | | |
352 | | const value_string bluetooth_not_supported_0x00_special[] = { |
353 | | {0x0, "Not Supported"}, |
354 | | {0, NULL} |
355 | | }; |
356 | | |
357 | | const value_string bluetooth_not_used_0xff_special[] = { |
358 | | {0xff, "Not used"}, |
359 | | {0, NULL} |
360 | | }; |
361 | | |
362 | | void |
363 | | save_local_device_name_from_eir_ad(tvbuff_t *tvb, int offset, packet_info *pinfo, |
364 | | uint8_t size, bluetooth_data_t *bluetooth_data) |
365 | 0 | { |
366 | 0 | int i = 0; |
367 | 0 | uint8_t length; |
368 | 0 | wmem_tree_key_t key[4]; |
369 | 0 | uint32_t k_interface_id; |
370 | 0 | uint32_t k_adapter_id; |
371 | 0 | uint32_t k_frame_number; |
372 | 0 | char *name; |
373 | 0 | localhost_name_entry_t *localhost_name_entry; |
374 | |
|
375 | 0 | if (!(!pinfo->fd->visited && bluetooth_data)) return; |
376 | | |
377 | 0 | while (i < size) { |
378 | 0 | length = tvb_get_uint8(tvb, offset + i); |
379 | 0 | if (length == 0) break; |
380 | | |
381 | 0 | switch(tvb_get_uint8(tvb, offset + i + 1)) { |
382 | 0 | case 0x08: /* Device Name, shortened */ |
383 | 0 | case 0x09: /* Device Name, full */ |
384 | 0 | name = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset + i + 2, length - 1, ENC_ASCII); |
385 | |
|
386 | 0 | k_interface_id = bluetooth_data->interface_id; |
387 | 0 | k_adapter_id = bluetooth_data->adapter_id; |
388 | 0 | k_frame_number = pinfo->num; |
389 | |
|
390 | 0 | key[0].length = 1; |
391 | 0 | key[0].key = &k_interface_id; |
392 | 0 | key[1].length = 1; |
393 | 0 | key[1].key = &k_adapter_id; |
394 | 0 | key[2].length = 1; |
395 | 0 | key[2].key = &k_frame_number; |
396 | 0 | key[3].length = 0; |
397 | 0 | key[3].key = NULL; |
398 | |
|
399 | 0 | localhost_name_entry = (localhost_name_entry_t *) wmem_new(wmem_file_scope(), localhost_name_entry_t); |
400 | 0 | localhost_name_entry->interface_id = k_interface_id; |
401 | 0 | localhost_name_entry->adapter_id = k_adapter_id; |
402 | 0 | localhost_name_entry->name = wmem_strdup(wmem_file_scope(), name); |
403 | |
|
404 | 0 | wmem_tree_insert32_array(bluetooth_data->localhost_name, key, localhost_name_entry); |
405 | |
|
406 | 0 | break; |
407 | 0 | } |
408 | | |
409 | 0 | i += length + 1; |
410 | 0 | } |
411 | 0 | } |
412 | | |
413 | | |
414 | | static const char* bluetooth_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter) |
415 | 0 | { |
416 | 0 | if (filter == CONV_FT_SRC_ADDRESS) { |
417 | 0 | if (conv->src_address.type == AT_ETHER) |
418 | 0 | return "bluetooth.src"; |
419 | 0 | else if (conv->src_address.type == AT_STRINGZ) |
420 | 0 | return "bluetooth.src_str"; |
421 | 0 | } |
422 | | |
423 | 0 | if (filter == CONV_FT_DST_ADDRESS) { |
424 | 0 | if (conv->dst_address.type == AT_ETHER) |
425 | 0 | return "bluetooth.dst"; |
426 | 0 | else if (conv->dst_address.type == AT_STRINGZ) |
427 | 0 | return "bluetooth.dst_str"; |
428 | 0 | } |
429 | | |
430 | 0 | if (filter == CONV_FT_ANY_ADDRESS) { |
431 | 0 | if (conv->src_address.type == AT_ETHER && conv->dst_address.type == AT_ETHER) |
432 | 0 | return "bluetooth.addr"; |
433 | 0 | else if (conv->src_address.type == AT_STRINGZ && conv->dst_address.type == AT_STRINGZ) |
434 | 0 | return "bluetooth.addr_str"; |
435 | 0 | } |
436 | | |
437 | 0 | return CONV_FILTER_INVALID; |
438 | 0 | } |
439 | | |
440 | | static ct_dissector_info_t bluetooth_ct_dissector_info = {&bluetooth_conv_get_filter_type}; |
441 | | |
442 | | |
443 | | static const char* bluetooth_endpoint_get_filter_type(endpoint_item_t* endpoint, conv_filter_type_e filter) |
444 | 0 | { |
445 | 0 | if (filter == CONV_FT_ANY_ADDRESS) { |
446 | 0 | if (endpoint->myaddress.type == AT_ETHER) |
447 | 0 | return "bluetooth.addr"; |
448 | 0 | else if (endpoint->myaddress.type == AT_STRINGZ) |
449 | 0 | return "bluetooth.addr_str"; |
450 | 0 | } |
451 | | |
452 | 0 | return CONV_FILTER_INVALID; |
453 | 0 | } |
454 | | |
455 | | static et_dissector_info_t bluetooth_et_dissector_info = {&bluetooth_endpoint_get_filter_type}; |
456 | | |
457 | | |
458 | | static tap_packet_status |
459 | | bluetooth_conversation_packet(void *pct, packet_info *pinfo, |
460 | | epan_dissect_t *edt _U_, const void *vip _U_, tap_flags_t flags) |
461 | 0 | { |
462 | 0 | conv_hash_t *hash = (conv_hash_t*) pct; |
463 | 0 | hash->flags = flags; |
464 | 0 | add_conversation_table_data(hash, &pinfo->dl_src, &pinfo->dl_dst, 0, 0, 1, |
465 | 0 | pinfo->fd->pkt_len, &pinfo->rel_ts, &pinfo->abs_ts, |
466 | 0 | &bluetooth_ct_dissector_info, CONVERSATION_NONE); |
467 | |
|
468 | 0 | return TAP_PACKET_REDRAW; |
469 | 0 | } |
470 | | |
471 | | |
472 | | static tap_packet_status |
473 | | bluetooth_endpoint_packet(void *pit, packet_info *pinfo, |
474 | | epan_dissect_t *edt _U_, const void *vip _U_, tap_flags_t flags) |
475 | 0 | { |
476 | 0 | conv_hash_t *hash = (conv_hash_t*) pit; |
477 | 0 | hash->flags = flags; |
478 | |
|
479 | 0 | add_endpoint_table_data(hash, &pinfo->dl_src, 0, true, 1, pinfo->fd->pkt_len, &bluetooth_et_dissector_info, ENDPOINT_NONE); |
480 | 0 | add_endpoint_table_data(hash, &pinfo->dl_dst, 0, false, 1, pinfo->fd->pkt_len, &bluetooth_et_dissector_info, ENDPOINT_NONE); |
481 | |
|
482 | 0 | return TAP_PACKET_REDRAW; |
483 | 0 | } |
484 | | |
485 | | static conversation_t * |
486 | | get_conversation(packet_info *pinfo, |
487 | | address *src_addr, address *dst_addr, |
488 | | uint32_t src_endpoint, uint32_t dst_endpoint) |
489 | 192 | { |
490 | 192 | conversation_t *conversation; |
491 | | |
492 | 192 | conversation = find_conversation(pinfo->num, |
493 | 192 | src_addr, dst_addr, |
494 | 192 | CONVERSATION_BLUETOOTH, |
495 | 192 | src_endpoint, dst_endpoint, 0); |
496 | 192 | if (conversation) { |
497 | 148 | return conversation; |
498 | 148 | } |
499 | | |
500 | 44 | conversation = conversation_new(pinfo->num, |
501 | 44 | src_addr, dst_addr, |
502 | 44 | CONVERSATION_BLUETOOTH, |
503 | 44 | src_endpoint, dst_endpoint, 0); |
504 | 44 | return conversation; |
505 | 192 | } |
506 | | |
507 | | static bluetooth_uuid_t |
508 | | get_bluetooth_uuid_from_str(const char *str) |
509 | 765 | { |
510 | 765 | bluetooth_uuid_t uuid; |
511 | 765 | char digits[3]; |
512 | 765 | const char *p = str; |
513 | | |
514 | 765 | memset(&uuid, 0, sizeof(uuid)); |
515 | | |
516 | 765 | ws_return_val_if(!str, uuid); |
517 | | |
518 | 765 | static const char fmt[] = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"; |
519 | 765 | const size_t fmtchars = sizeof(fmt) - 1; |
520 | | |
521 | 765 | size_t size = strlen(str); |
522 | 765 | if (size != 4 && size != 8 && size != fmtchars) { |
523 | 0 | return uuid; |
524 | 0 | } |
525 | | |
526 | 28.3k | for (size_t i = 0; i < size; i++) { |
527 | 27.5k | if (fmt[i] == 'X') { |
528 | 24.4k | if (!g_ascii_isxdigit(str[i])) |
529 | 0 | return uuid; |
530 | 24.4k | } else { |
531 | 3.06k | if (str[i] != fmt[i]) |
532 | 0 | return uuid; |
533 | 3.06k | } |
534 | 27.5k | } |
535 | | |
536 | 765 | if (size == 4) { |
537 | 0 | size = 2; |
538 | 765 | } else if (size == 8) { |
539 | 0 | size = 4; |
540 | 765 | } else if (size == fmtchars) { |
541 | 765 | size = 16; |
542 | 765 | } else { |
543 | 0 | ws_assert_not_reached(); |
544 | 0 | } |
545 | | |
546 | 13.0k | for (size_t i = 0; i < size; i++) { |
547 | 12.2k | if (*p == '-') ++p; |
548 | 12.2k | digits[0] = *(p++); |
549 | 12.2k | digits[1] = *(p++); |
550 | 12.2k | digits[2] = '\0'; |
551 | 12.2k | uuid.data[i] = (uint8_t)strtoul(digits, NULL, 16); |
552 | 12.2k | } |
553 | | |
554 | 765 | if (size == 4) { |
555 | 0 | if (uuid.data[0] == 0x00 && uuid.data[1] == 0x00) { |
556 | 0 | uuid.data[0] = uuid.data[2]; |
557 | 0 | uuid.data[1] = uuid.data[3]; |
558 | 0 | size = 2; |
559 | 0 | } |
560 | 765 | } else if (size == 16) { |
561 | 765 | if (uuid.data[0] == 0x00 && uuid.data[1] == 0x00 && |
562 | 75 | uuid.data[4] == 0x00 && uuid.data[5] == 0x00 && uuid.data[6] == 0x10 && |
563 | 30 | uuid.data[7] == 0x00 && uuid.data[8] == 0x80 && uuid.data[9] == 0x00 && |
564 | 30 | uuid.data[10] == 0x00 && uuid.data[11] == 0x80 && uuid.data[12] == 0x5F && |
565 | 0 | uuid.data[13] == 0x9B && uuid.data[14] == 0x34 && uuid.data[15] == 0xFB) { |
566 | |
|
567 | 0 | uuid.data[0] = uuid.data[2]; |
568 | 0 | uuid.data[1] = uuid.data[3]; |
569 | 0 | size = 2; |
570 | 0 | } |
571 | 765 | } |
572 | | |
573 | 765 | if (size == 2) { |
574 | 0 | uuid.bt_uuid = uuid.data[1] | uuid.data[0] << 8; |
575 | 0 | } |
576 | 765 | uuid.size = (uint8_t)size; |
577 | 765 | return uuid; |
578 | 765 | } |
579 | | |
580 | | bluetooth_uuid_t |
581 | | get_bluetooth_uuid(tvbuff_t *tvb, int offset, int size) |
582 | 3.27k | { |
583 | 3.27k | bluetooth_uuid_t uuid; |
584 | | |
585 | 3.27k | memset(&uuid, 0, sizeof(uuid)); |
586 | | |
587 | 3.27k | if (size != 2 && size != 4 && size != 16) { |
588 | 0 | return uuid; |
589 | 0 | } |
590 | | |
591 | 3.27k | if (size == 2) { |
592 | 2.28k | uuid.data[0] = tvb_get_uint8(tvb, offset + 1); |
593 | 2.28k | uuid.data[1] = tvb_get_uint8(tvb, offset); |
594 | | |
595 | 2.28k | uuid.bt_uuid = uuid.data[1] | uuid.data[0] << 8; |
596 | 2.28k | } else if (size == 4) { |
597 | 353 | uuid.data[0] = tvb_get_uint8(tvb, offset + 3); |
598 | 353 | uuid.data[1] = tvb_get_uint8(tvb, offset + 2); |
599 | 353 | uuid.data[2] = tvb_get_uint8(tvb, offset + 1); |
600 | 353 | uuid.data[3] = tvb_get_uint8(tvb, offset); |
601 | | |
602 | 353 | if (uuid.data[0] == 0x00 && uuid.data[1] == 0x00) { |
603 | 29 | uuid.bt_uuid = uuid.data[3] | uuid.data[2] << 8; |
604 | 29 | size = 2; |
605 | 29 | } |
606 | 637 | } else { |
607 | 637 | uuid.data[0] = tvb_get_uint8(tvb, offset + 15); |
608 | 637 | uuid.data[1] = tvb_get_uint8(tvb, offset + 14); |
609 | 637 | uuid.data[2] = tvb_get_uint8(tvb, offset + 13); |
610 | 637 | uuid.data[3] = tvb_get_uint8(tvb, offset + 12); |
611 | 637 | uuid.data[4] = tvb_get_uint8(tvb, offset + 11); |
612 | 637 | uuid.data[5] = tvb_get_uint8(tvb, offset + 10); |
613 | 637 | uuid.data[6] = tvb_get_uint8(tvb, offset + 9); |
614 | 637 | uuid.data[7] = tvb_get_uint8(tvb, offset + 8); |
615 | 637 | uuid.data[8] = tvb_get_uint8(tvb, offset + 7); |
616 | 637 | uuid.data[9] = tvb_get_uint8(tvb, offset + 6); |
617 | 637 | uuid.data[10] = tvb_get_uint8(tvb, offset + 5); |
618 | 637 | uuid.data[11] = tvb_get_uint8(tvb, offset + 4); |
619 | 637 | uuid.data[12] = tvb_get_uint8(tvb, offset + 3); |
620 | 637 | uuid.data[13] = tvb_get_uint8(tvb, offset + 2); |
621 | 637 | uuid.data[14] = tvb_get_uint8(tvb, offset + 1); |
622 | 637 | uuid.data[15] = tvb_get_uint8(tvb, offset); |
623 | | |
624 | 637 | if (uuid.data[0] == 0x00 && uuid.data[1] == 0x00 && |
625 | 172 | uuid.data[4] == 0x00 && uuid.data[5] == 0x00 && uuid.data[6] == 0x10 && |
626 | 1 | uuid.data[7] == 0x00 && uuid.data[8] == 0x80 && uuid.data[9] == 0x00 && |
627 | 0 | uuid.data[10] == 0x00 && uuid.data[11] == 0x80 && uuid.data[12] == 0x5F && |
628 | 0 | uuid.data[13] == 0x9B && uuid.data[14] == 0x34 && uuid.data[15] == 0xFB) { |
629 | 0 | uuid.bt_uuid = uuid.data[3] | uuid.data[2] << 8; |
630 | 0 | size = 2; |
631 | 0 | } |
632 | 637 | } |
633 | | |
634 | 3.27k | uuid.size = size; |
635 | 3.27k | return uuid; |
636 | 3.27k | } |
637 | | |
638 | | /* Extract a UUID stored in big-endian order within a tvb. */ |
639 | | bluetooth_uuid_t |
640 | | get_bluetooth_uuid_be(tvbuff_t *tvb, int offset, int size) |
641 | 4.65k | { |
642 | 4.65k | bluetooth_uuid_t uuid; |
643 | | |
644 | 4.65k | memset(&uuid, 0, sizeof(uuid)); |
645 | | |
646 | 4.65k | if (size != 2 && size != 4 && size != 16) { |
647 | 3.26k | return uuid; |
648 | 3.26k | } |
649 | | |
650 | 1.38k | tvb_memcpy(tvb, uuid.data, offset, size); |
651 | | |
652 | 1.38k | if (size == 2) { |
653 | | /* [0x11, 0x01] in tvb -> 0x1101 */ |
654 | 580 | uuid.bt_uuid = (uuid.data[0] << 8) | uuid.data[1]; |
655 | 580 | } |
656 | 809 | else if (size == 4) { |
657 | | /* Check if the 32-bit UUID can be collapsed to 16-bit */ |
658 | 651 | if (uuid.data[0] == 0x00 && uuid.data[1] == 0x00) { |
659 | 23 | uuid.bt_uuid = (uuid.data[2] << 8) | uuid.data[3]; |
660 | 23 | size = 2; |
661 | 23 | } |
662 | 651 | } |
663 | 158 | else { |
664 | | /* Check if the 128-bit UUID can be collapsed to 16-bit */ |
665 | 158 | if (uuid.data[0] == 0x00 && uuid.data[1] == 0x00 && |
666 | 17 | uuid.data[4] == 0x00 && uuid.data[5] == 0x00 && uuid.data[6] == 0x10 && |
667 | 0 | uuid.data[7] == 0x00 && uuid.data[8] == 0x80 && uuid.data[9] == 0x00 && |
668 | 0 | uuid.data[10] == 0x00 && uuid.data[11] == 0x80 && uuid.data[12] == 0x5F && |
669 | 0 | uuid.data[13] == 0x9B && uuid.data[14] == 0x34 && uuid.data[15] == 0xFB) { |
670 | |
|
671 | 0 | uuid.bt_uuid = (uuid.data[2] << 8) | uuid.data[3]; |
672 | 0 | size = 2; |
673 | 0 | } |
674 | 158 | } |
675 | | |
676 | 1.38k | uuid.size = size; |
677 | 1.38k | return uuid; |
678 | 4.65k | } |
679 | | |
680 | | |
681 | | const char * |
682 | | print_numeric_bluetooth_uuid(wmem_allocator_t *pool, const bluetooth_uuid_t *uuid) |
683 | 1.46k | { |
684 | 1.46k | if (!(uuid && uuid->size > 0)) |
685 | 13 | return NULL; |
686 | | |
687 | 1.45k | if (uuid->size == 2) { |
688 | 1.38k | return wmem_strdup_printf(pool, "%04x", uuid->bt_uuid); |
689 | 1.38k | } |
690 | 70 | else if (uuid->size != 16) { |
691 | 6 | return bytes_to_str(pool, uuid->data, uuid->size); |
692 | 6 | } |
693 | | |
694 | 64 | char *text; |
695 | | |
696 | 64 | text = (char *) wmem_alloc(pool, 38); |
697 | 64 | bytes_to_hexstr(&text[0], uuid->data, 4); |
698 | 64 | text[8] = '-'; |
699 | 64 | bytes_to_hexstr(&text[9], uuid->data + 4, 2); |
700 | 64 | text[13] = '-'; |
701 | 64 | bytes_to_hexstr(&text[14], uuid->data + 4 + 2 * 1, 2); |
702 | 64 | text[18] = '-'; |
703 | 64 | bytes_to_hexstr(&text[19], uuid->data + 4 + 2 * 2, 2); |
704 | 64 | text[23] = '-'; |
705 | 64 | bytes_to_hexstr(&text[24], uuid->data + 4 + 2 * 3, 6); |
706 | 64 | text[36] = '\0'; |
707 | | |
708 | 64 | return text; |
709 | 1.45k | } |
710 | | |
711 | | const char * |
712 | | try_print_bluetooth_uuid(const bluetooth_uuid_t *uuid) |
713 | 16.5k | { |
714 | 16.5k | const char *description = NULL; |
715 | | |
716 | 16.5k | if (uuid->bt_uuid) { |
717 | 3.42k | const char *name; |
718 | | |
719 | | /* |
720 | | * Known UUID? |
721 | | */ |
722 | 3.42k | name = try_val_to_str_ext(uuid->bt_uuid, &bluetooth_uuid_vals_ext); |
723 | 3.42k | if (name != NULL) { |
724 | | /* |
725 | | * Yes. This string is part of the value_string_ext table, |
726 | | * so we don't have to make a copy. |
727 | | */ |
728 | 277 | return name; |
729 | 277 | } |
730 | | |
731 | | /* |
732 | | * No - fall through to try looking it up. |
733 | | */ |
734 | 3.42k | } |
735 | | |
736 | 16.3k | description = bluetooth_get_custom_uuid_description(uuid); |
737 | | |
738 | 16.3k | return description; |
739 | 16.5k | } |
740 | | |
741 | | const char * |
742 | | print_bluetooth_uuid(const bluetooth_uuid_t *uuid) |
743 | 16.5k | { |
744 | 16.5k | const char *description = try_print_bluetooth_uuid(uuid); |
745 | | |
746 | 16.5k | if (description == NULL) { |
747 | 16.3k | description = "Unknown"; |
748 | 16.3k | } |
749 | | |
750 | 16.5k | return description; |
751 | 16.5k | } |
752 | | |
753 | | bluetooth_data_t * |
754 | | dissect_bluetooth_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) |
755 | 192 | { |
756 | 192 | proto_item *main_item; |
757 | 192 | proto_tree *main_tree; |
758 | 192 | proto_item *sub_item; |
759 | 192 | bluetooth_data_t *bluetooth_data; |
760 | 192 | address *src; |
761 | 192 | address *dst; |
762 | | |
763 | 192 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "Bluetooth"); |
764 | 192 | switch (pinfo->p2p_dir) { |
765 | | |
766 | 0 | case P2P_DIR_SENT: |
767 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Sent "); |
768 | 0 | break; |
769 | | |
770 | 0 | case P2P_DIR_RECV: |
771 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "Rcvd "); |
772 | 0 | break; |
773 | | |
774 | 192 | default: |
775 | 192 | col_set_str(pinfo->cinfo, COL_INFO, "UnknownDirection "); |
776 | 192 | break; |
777 | 192 | } |
778 | | |
779 | 192 | pinfo->ptype = PT_BLUETOOTH; |
780 | 192 | get_conversation(pinfo, &pinfo->dl_src, &pinfo->dl_dst, pinfo->srcport, pinfo->destport); |
781 | | |
782 | 192 | main_item = proto_tree_add_item(tree, proto_bluetooth, tvb, 0, tvb_captured_length(tvb), ENC_NA); |
783 | 192 | main_tree = proto_item_add_subtree(main_item, ett_bluetooth); |
784 | | |
785 | 192 | bluetooth_data = (bluetooth_data_t *) wmem_new(pinfo->pool, bluetooth_data_t); |
786 | 192 | if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID) |
787 | 0 | bluetooth_data->interface_id = pinfo->rec->rec_header.packet_header.interface_id; |
788 | 192 | else |
789 | 192 | bluetooth_data->interface_id = HCI_INTERFACE_DEFAULT; |
790 | 192 | bluetooth_data->adapter_id = HCI_ADAPTER_DEFAULT; |
791 | 192 | bluetooth_data->adapter_disconnect_in_frame = &bluetooth_max_disconnect_in_frame; |
792 | 192 | bluetooth_data->chandle_sessions = chandle_sessions; |
793 | 192 | bluetooth_data->chandle_to_bdaddr = chandle_to_bdaddr; |
794 | 192 | bluetooth_data->chandle_to_mode = chandle_to_mode; |
795 | 192 | bluetooth_data->shandle_to_chandle = shandle_to_chandle; |
796 | 192 | bluetooth_data->bdaddr_to_name = bdaddr_to_name; |
797 | 192 | bluetooth_data->bdaddr_to_role = bdaddr_to_role; |
798 | 192 | bluetooth_data->localhost_bdaddr = localhost_bdaddr; |
799 | 192 | bluetooth_data->localhost_name = localhost_name; |
800 | 192 | bluetooth_data->hci_vendors = hci_vendors; |
801 | 192 | bluetooth_data->cs_configurations = cs_configurations; |
802 | | |
803 | 192 | if (have_tap_listener(bluetooth_tap)) { |
804 | 0 | bluetooth_tap_data_t *bluetooth_tap_data; |
805 | |
|
806 | 0 | bluetooth_tap_data = wmem_new(pinfo->pool, bluetooth_tap_data_t); |
807 | 0 | bluetooth_tap_data->interface_id = bluetooth_data->interface_id; |
808 | 0 | bluetooth_tap_data->adapter_id = bluetooth_data->adapter_id; |
809 | |
|
810 | 0 | tap_queue_packet(bluetooth_tap, pinfo, bluetooth_tap_data); |
811 | 0 | } |
812 | | |
813 | 192 | src = (address *) p_get_proto_data(wmem_file_scope(), pinfo, proto_bluetooth, BLUETOOTH_DATA_SRC); |
814 | 192 | dst = (address *) p_get_proto_data(wmem_file_scope(), pinfo, proto_bluetooth, BLUETOOTH_DATA_DST); |
815 | | |
816 | 192 | if (src && src->type == AT_STRINGZ) { |
817 | 0 | sub_item = proto_tree_add_string(main_tree, hf_bluetooth_addr_str, tvb, 0, 0, (const char *) src->data); |
818 | 0 | proto_item_set_hidden(sub_item); |
819 | |
|
820 | 0 | sub_item = proto_tree_add_string(main_tree, hf_bluetooth_src_str, tvb, 0, 0, (const char *) src->data); |
821 | 0 | proto_item_set_generated(sub_item); |
822 | 192 | } else if (src && src->type == AT_ETHER) { |
823 | 0 | sub_item = proto_tree_add_ether(main_tree, hf_bluetooth_addr, tvb, 0, 0, (const uint8_t *) src->data); |
824 | 0 | proto_item_set_hidden(sub_item); |
825 | |
|
826 | 0 | sub_item = proto_tree_add_ether(main_tree, hf_bluetooth_src, tvb, 0, 0, (const uint8_t *) src->data); |
827 | 0 | proto_item_set_generated(sub_item); |
828 | 0 | } |
829 | | |
830 | 192 | if (dst && dst->type == AT_STRINGZ) { |
831 | 0 | sub_item = proto_tree_add_string(main_tree, hf_bluetooth_addr_str, tvb, 0, 0, (const char *) dst->data); |
832 | 0 | proto_item_set_hidden(sub_item); |
833 | |
|
834 | 0 | sub_item = proto_tree_add_string(main_tree, hf_bluetooth_dst_str, tvb, 0, 0, (const char *) dst->data); |
835 | 0 | proto_item_set_generated(sub_item); |
836 | 192 | } else if (dst && dst->type == AT_ETHER) { |
837 | 0 | sub_item = proto_tree_add_ether(main_tree, hf_bluetooth_addr, tvb, 0, 0, (const uint8_t *) dst->data); |
838 | 0 | proto_item_set_hidden(sub_item); |
839 | |
|
840 | 0 | sub_item = proto_tree_add_ether(main_tree, hf_bluetooth_dst, tvb, 0, 0, (const uint8_t *) dst->data); |
841 | 0 | proto_item_set_generated(sub_item); |
842 | 0 | } |
843 | | |
844 | 192 | return bluetooth_data; |
845 | 192 | } |
846 | | |
847 | | /* |
848 | | * Register this in the wtap_encap dissector table. |
849 | | * It's called for WTAP_ENCAP_BLUETOOTH_H4, WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR, |
850 | | * WTAP_ENCAP_PACKETLOGGER. WTAP_ENCAP_BLUETOOTH_LE_LL, |
851 | | * WTAP_ENCAP_BLUETOOTH_LE_LL_WITH_PHDR, and WTAP_ENCAP_BLUETOOTH_BREDR_BB. |
852 | | * |
853 | | * It does work common to all Bluetooth encapsulations, and then calls |
854 | | * the dissector registered in the bluetooth.encap table to handle the |
855 | | * metadata header in the packet. |
856 | | */ |
857 | | static int |
858 | | dissect_bluetooth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
859 | 192 | { |
860 | 192 | bluetooth_data_t *bluetooth_data; |
861 | | |
862 | 192 | bluetooth_data = dissect_bluetooth_common(tvb, pinfo, tree); |
863 | | |
864 | | /* |
865 | | * There is no pseudo-header, or there's just a p2p pseudo-header. |
866 | | */ |
867 | 192 | bluetooth_data->previous_protocol_data_type = BT_PD_NONE; |
868 | 192 | bluetooth_data->previous_protocol_data.none = NULL; |
869 | | |
870 | 192 | if (!dissector_try_uint_with_data(bluetooth_table, pinfo->rec->rec_header.packet_header.pkt_encap, tvb, pinfo, tree, true, bluetooth_data)) { |
871 | 2 | call_data_dissector(tvb, pinfo, tree); |
872 | 2 | } |
873 | | |
874 | 192 | return tvb_captured_length(tvb); |
875 | 192 | } |
876 | | |
877 | | |
878 | | /* |
879 | | * Register this in the wtap_encap dissector table. |
880 | | * It's called for WTAP_ENCAP_BLUETOOTH_HCI. |
881 | | * |
882 | | * It does work common to all Bluetooth encapsulations, and then calls |
883 | | * the dissector registered in the bluetooth.encap table to handle the |
884 | | * metadata header in the packet. |
885 | | */ |
886 | | static int |
887 | | dissect_bluetooth_bthci(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
888 | 0 | { |
889 | 0 | bluetooth_data_t *bluetooth_data; |
890 | |
|
891 | 0 | bluetooth_data = dissect_bluetooth_common(tvb, pinfo, tree); |
892 | | |
893 | | /* |
894 | | * data points to a struct bthci_phdr. |
895 | | */ |
896 | 0 | bluetooth_data->previous_protocol_data_type = BT_PD_BTHCI; |
897 | 0 | bluetooth_data->previous_protocol_data.bthci = (struct bthci_phdr *)data; |
898 | |
|
899 | 0 | if (!dissector_try_uint_with_data(bluetooth_table, pinfo->rec->rec_header.packet_header.pkt_encap, tvb, pinfo, tree, true, bluetooth_data)) { |
900 | 0 | call_data_dissector(tvb, pinfo, tree); |
901 | 0 | } |
902 | |
|
903 | 0 | return tvb_captured_length(tvb); |
904 | 0 | } |
905 | | |
906 | | /* |
907 | | * Register this in the wtap_encap dissector table. |
908 | | * It's called for WTAP_ENCAP_BLUETOOTH_LINUX_MONITOR. |
909 | | * |
910 | | * It does work common to all Bluetooth encapsulations, and then calls |
911 | | * the dissector registered in the bluetooth.encap table to handle the |
912 | | * metadata header in the packet. |
913 | | */ |
914 | | static int |
915 | | dissect_bluetooth_btmon(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
916 | 0 | { |
917 | 0 | bluetooth_data_t *bluetooth_data; |
918 | |
|
919 | 0 | bluetooth_data = dissect_bluetooth_common(tvb, pinfo, tree); |
920 | | |
921 | | /* |
922 | | * data points to a struct btmon_phdr. |
923 | | */ |
924 | 0 | bluetooth_data->previous_protocol_data_type = BT_PD_BTMON; |
925 | 0 | bluetooth_data->previous_protocol_data.btmon = (struct btmon_phdr *)data; |
926 | |
|
927 | 0 | if (!dissector_try_uint_with_data(bluetooth_table, pinfo->rec->rec_header.packet_header.pkt_encap, tvb, pinfo, tree, true, bluetooth_data)) { |
928 | 0 | call_data_dissector(tvb, pinfo, tree); |
929 | 0 | } |
930 | |
|
931 | 0 | return tvb_captured_length(tvb); |
932 | 0 | } |
933 | | |
934 | | /* |
935 | | * Register this in various USB dissector tables. |
936 | | */ |
937 | | static int |
938 | | dissect_bluetooth_usb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
939 | 0 | { |
940 | 0 | bluetooth_data_t *bluetooth_data; |
941 | |
|
942 | 0 | bluetooth_data = dissect_bluetooth_common(tvb, pinfo, tree); |
943 | | |
944 | | /* |
945 | | * data points to a urb_info_t. |
946 | | */ |
947 | 0 | bluetooth_data->previous_protocol_data_type = BT_PD_URB_INFO; |
948 | 0 | bluetooth_data->previous_protocol_data.urb = (urb_info_t *)data; |
949 | |
|
950 | 0 | return call_dissector_with_data(hci_usb_handle, tvb, pinfo, tree, bluetooth_data); |
951 | 0 | } |
952 | | |
953 | | /* |
954 | | * Register this by name; it's called from the Ubertooth dissector. |
955 | | */ |
956 | | static int |
957 | | dissect_bluetooth_ubertooth(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
958 | 0 | { |
959 | 0 | bluetooth_data_t *bluetooth_data; |
960 | |
|
961 | 0 | bluetooth_data = dissect_bluetooth_common(tvb, pinfo, tree); |
962 | | |
963 | | /* |
964 | | * data points to a ubertooth_data_t. |
965 | | */ |
966 | 0 | bluetooth_data->previous_protocol_data_type = BT_PD_UBERTOOTH_DATA; |
967 | 0 | bluetooth_data->previous_protocol_data.ubertooth_data = (ubertooth_data_t *)data; |
968 | |
|
969 | 0 | call_dissector(btle_handle, tvb, pinfo, tree); |
970 | |
|
971 | 0 | return tvb_captured_length(tvb); |
972 | 0 | } |
973 | | |
974 | | void |
975 | | proto_register_bluetooth(void) |
976 | 15 | { |
977 | 15 | static hf_register_info hf[] = { |
978 | 15 | { &hf_bluetooth_src, |
979 | 15 | { "Source", "bluetooth.src", |
980 | 15 | FT_ETHER, BASE_NONE, NULL, 0x0, |
981 | 15 | NULL, HFILL } |
982 | 15 | }, |
983 | 15 | { &hf_bluetooth_dst, |
984 | 15 | { "Destination", "bluetooth.dst", |
985 | 15 | FT_ETHER, BASE_NONE, NULL, 0x0, |
986 | 15 | NULL, HFILL } |
987 | 15 | }, |
988 | 15 | { &hf_bluetooth_addr, |
989 | 15 | { "Source or Destination", "bluetooth.addr", |
990 | 15 | FT_ETHER, BASE_NONE, NULL, 0x0, |
991 | 15 | NULL, HFILL } |
992 | 15 | }, |
993 | 15 | { &hf_bluetooth_src_str, |
994 | 15 | { "Source", "bluetooth.src_str", |
995 | 15 | FT_STRING, BASE_NONE, NULL, 0x0, |
996 | 15 | NULL, HFILL } |
997 | 15 | }, |
998 | 15 | { &hf_bluetooth_dst_str, |
999 | 15 | { "Destination", "bluetooth.dst_str", |
1000 | 15 | FT_STRING, BASE_NONE, NULL, 0x0, |
1001 | 15 | NULL, HFILL } |
1002 | 15 | }, |
1003 | 15 | { &hf_bluetooth_addr_str, |
1004 | 15 | { "Source or Destination", "bluetooth.addr_str", |
1005 | 15 | FT_STRING, BASE_NONE, NULL, 0x0, |
1006 | 15 | NULL, HFILL } |
1007 | 15 | }, |
1008 | 15 | }; |
1009 | | |
1010 | 15 | static hf_register_info oui_hf[] = { |
1011 | 15 | { &hf_llc_bluetooth_pid, |
1012 | 15 | { "PID", "llc.bluetooth_pid", |
1013 | 15 | FT_UINT16, BASE_HEX, VALS(bluetooth_pid_vals), 0x0, |
1014 | 15 | "Protocol ID", HFILL } |
1015 | 15 | } |
1016 | 15 | }; |
1017 | | |
1018 | 15 | static int *ett[] = { |
1019 | 15 | &ett_bluetooth, |
1020 | 15 | }; |
1021 | | |
1022 | | // UAT |
1023 | 15 | module_t *bluetooth_module; |
1024 | 15 | uat_t* bluetooth_uuids_uat; |
1025 | 15 | static uat_field_t bluetooth_uuids_uat_fields[] = { |
1026 | 15 | UAT_FLD_CSTRING(bt_uuids, uuid, "UUID", "UUID"), |
1027 | 15 | UAT_FLD_CSTRING(bt_uuids, label, "UUID Name", "Readable label"), |
1028 | 15 | UAT_FLD_BOOL(bt_uuids, long_attr, "Long Attribute", "A Long Attribute that may be sent in multiple BT ATT PDUs"), |
1029 | 15 | UAT_END_FIELDS |
1030 | 15 | }; |
1031 | | |
1032 | | /* Decode As handling */ |
1033 | 15 | static build_valid_func bluetooth_uuid_da_build_value[1] = {bluetooth_uuid_value}; |
1034 | 15 | static decode_as_value_t bluetooth_uuid_da_values = {bluetooth_uuid_prompt, 1, bluetooth_uuid_da_build_value}; |
1035 | 15 | static decode_as_t bluetooth_uuid_da = {"bluetooth", "bluetooth.uuid", 1, 0, &bluetooth_uuid_da_values, NULL, NULL, |
1036 | 15 | decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL, NULL, NULL }; |
1037 | | |
1038 | | |
1039 | 15 | proto_bluetooth = proto_register_protocol("Bluetooth", "Bluetooth", "bluetooth"); |
1040 | | |
1041 | 15 | register_dissector("bluetooth_ubertooth", dissect_bluetooth_ubertooth, proto_bluetooth); |
1042 | | |
1043 | 15 | proto_register_field_array(proto_bluetooth, hf, array_length(hf)); |
1044 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
1045 | | |
1046 | 15 | bluetooth_table = register_dissector_table("bluetooth.encap", |
1047 | 15 | "Bluetooth Encapsulation", proto_bluetooth, FT_UINT32, BASE_HEX); |
1048 | | |
1049 | 15 | chandle_sessions = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); |
1050 | 15 | chandle_to_bdaddr = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); |
1051 | 15 | chandle_to_mode = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); |
1052 | 15 | shandle_to_chandle = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); |
1053 | 15 | bdaddr_to_name = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); |
1054 | 15 | bdaddr_to_role = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); |
1055 | 15 | localhost_bdaddr = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); |
1056 | 15 | localhost_name = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); |
1057 | 15 | hci_vendors = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); |
1058 | 15 | cs_configurations = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); |
1059 | | |
1060 | 15 | hci_vendor_table = register_dissector_table("bluetooth.vendor", "HCI Vendor", proto_bluetooth, FT_UINT16, BASE_HEX); |
1061 | 15 | bluetooth_uuid_id = uuid_type_dissector_register("bluetooth", bluetooth_uuid_hash, bluetooth_uuid_equal, bluetooth_uuid_to_str); |
1062 | | |
1063 | 15 | bluetooth_tap = register_tap("bluetooth"); |
1064 | 15 | bluetooth_device_tap = register_tap("bluetooth.device"); |
1065 | 15 | bluetooth_hci_summary_tap = register_tap("bluetooth.hci_summary"); |
1066 | | |
1067 | 15 | bluetooth_uuid_table = register_dissector_table("bluetooth.uuid", "BT Service UUID", proto_bluetooth, FT_STRING, STRING_CASE_SENSITIVE); |
1068 | 15 | llc_add_oui(OUI_BLUETOOTH, "llc.bluetooth_pid", "LLC Bluetooth OUI PID", oui_hf, proto_bluetooth); |
1069 | | |
1070 | 15 | register_conversation_table(proto_bluetooth, true, bluetooth_conversation_packet, bluetooth_endpoint_packet); |
1071 | | |
1072 | 15 | register_decode_as(&bluetooth_uuid_da); |
1073 | | |
1074 | 15 | bluetooth_module = prefs_register_protocol(proto_bluetooth, NULL); |
1075 | 15 | bluetooth_uuids_uat = uat_new("Custom Bluetooth UUIDs", |
1076 | 15 | sizeof(bt_uuid_uat_t), |
1077 | 15 | "bluetooth_uuids", |
1078 | 15 | true, |
1079 | 15 | &bt_uuids, |
1080 | 15 | &num_bt_uuids, |
1081 | 15 | UAT_AFFECTS_DISSECTION, |
1082 | 15 | NULL, |
1083 | 15 | bt_uuids_copy_cb, |
1084 | 15 | bt_uuids_update_cb, |
1085 | 15 | bt_uuids_free_cb, |
1086 | 15 | bt_uuids_post_update_cb, |
1087 | 15 | bt_uuids_reset_cb, |
1088 | 15 | bluetooth_uuids_uat_fields); |
1089 | | |
1090 | 15 | static const char* bt_uuids_uat_defaults_[] = { |
1091 | 15 | NULL, NULL, "FALSE" }; |
1092 | 15 | uat_set_default_values(bluetooth_uuids_uat, bt_uuids_uat_defaults_); |
1093 | | |
1094 | 15 | prefs_register_uat_preference(bluetooth_module, "uuids", |
1095 | 15 | "Custom Bluetooth UUID names", |
1096 | 15 | "Assign readable names to custom UUIDs", |
1097 | 15 | bluetooth_uuids_uat); |
1098 | | |
1099 | 15 | bluetooth_handle = register_dissector("bluetooth", dissect_bluetooth, proto_bluetooth); |
1100 | 15 | bluetooth_bthci_handle = register_dissector("bluetooth.bthci", dissect_bluetooth_bthci, proto_bluetooth); |
1101 | 15 | bluetooth_btmon_handle = register_dissector("bluetooth.btmon", dissect_bluetooth_btmon, proto_bluetooth); |
1102 | 15 | bluetooth_usb_handle = register_dissector("bluetooth.usb", dissect_bluetooth_usb, proto_bluetooth); |
1103 | | |
1104 | 15 | register_external_value_string_ext("bluetooth_company_id_vals_ext", &bluetooth_company_id_vals_ext); |
1105 | 15 | register_external_value_string_ext("bluetooth_uuid_vals_ext", &bluetooth_uuid_vals_ext); |
1106 | 15 | } |
1107 | | |
1108 | | void |
1109 | | proto_reg_handoff_bluetooth(void) |
1110 | 15 | { |
1111 | 15 | dissector_handle_t eapol_handle; |
1112 | 15 | dissector_handle_t btl2cap_handle; |
1113 | | |
1114 | 15 | btle_handle = find_dissector_add_dependency("btle", proto_bluetooth); |
1115 | 15 | hci_usb_handle = find_dissector_add_dependency("hci_usb", proto_bluetooth); |
1116 | | |
1117 | 15 | dissector_add_uint("wtap_encap", WTAP_ENCAP_BLUETOOTH_HCI, bluetooth_bthci_handle); |
1118 | 15 | dissector_add_uint("wtap_encap", WTAP_ENCAP_BLUETOOTH_H4, bluetooth_handle); |
1119 | 15 | dissector_add_uint("wtap_encap", WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR, bluetooth_handle); |
1120 | 15 | dissector_add_uint("wtap_encap", WTAP_ENCAP_BLUETOOTH_LINUX_MONITOR, bluetooth_btmon_handle); |
1121 | 15 | dissector_add_uint("wtap_encap", WTAP_ENCAP_PACKETLOGGER, bluetooth_handle); |
1122 | | |
1123 | 15 | dissector_add_uint("wtap_encap", WTAP_ENCAP_BLUETOOTH_LE_LL, bluetooth_handle); |
1124 | 15 | dissector_add_uint("wtap_encap", WTAP_ENCAP_BLUETOOTH_LE_LL_WITH_PHDR, bluetooth_handle); |
1125 | 15 | dissector_add_uint("wtap_encap", WTAP_ENCAP_BLUETOOTH_BREDR_BB, bluetooth_handle); |
1126 | | |
1127 | 15 | dissector_add_uint("usb.product", (0x0a5c << 16) | 0x21e8, bluetooth_usb_handle); |
1128 | 15 | dissector_add_uint("usb.product", (0x1131 << 16) | 0x1001, bluetooth_usb_handle); |
1129 | 15 | dissector_add_uint("usb.product", (0x050d << 16) | 0x0081, bluetooth_usb_handle); |
1130 | 15 | dissector_add_uint("usb.product", (0x0a5c << 16) | 0x2198, bluetooth_usb_handle); |
1131 | 15 | dissector_add_uint("usb.product", (0x0a5c << 16) | 0x21e8, bluetooth_usb_handle); |
1132 | 15 | dissector_add_uint("usb.product", (0x04bf << 16) | 0x0320, bluetooth_usb_handle); |
1133 | 15 | dissector_add_uint("usb.product", (0x13d3 << 16) | 0x3375, bluetooth_usb_handle); |
1134 | | |
1135 | 15 | dissector_add_uint("usb.protocol", 0xE00101, bluetooth_usb_handle); |
1136 | 15 | dissector_add_uint("usb.protocol", 0xE00104, bluetooth_usb_handle); |
1137 | | |
1138 | 15 | dissector_add_for_decode_as("usb.device", bluetooth_usb_handle); |
1139 | | |
1140 | 15 | bluetooth_add_custom_uuid("00000001-0000-1000-8000-0002EE000002", "SyncML Server", false); |
1141 | 15 | bluetooth_add_custom_uuid("00000002-0000-1000-8000-0002EE000002", "SyncML Client", false); |
1142 | 15 | bluetooth_add_custom_uuid("7905F431-B5CE-4E99-A40F-4B1E122D00D0", "Apple Notification Center Service", false); |
1143 | | |
1144 | 15 | eapol_handle = find_dissector("eapol"); |
1145 | 15 | btl2cap_handle = find_dissector("btl2cap"); |
1146 | | |
1147 | 15 | dissector_add_uint("llc.bluetooth_pid", AMP_C_SECURITY_FRAME, eapol_handle); |
1148 | 15 | dissector_add_uint("llc.bluetooth_pid", AMP_U_L2CAP, btl2cap_handle); |
1149 | | |
1150 | | /* TODO: Add UUID128 version of UUID16; UUID32? UUID16? */ |
1151 | 15 | } |
1152 | | |
1153 | | static int proto_btad_apple_ibeacon; |
1154 | | |
1155 | | static int hf_btad_apple_ibeacon_type; |
1156 | | static int hf_btad_apple_ibeacon_length; |
1157 | | static int hf_btad_apple_ibeacon_uuid128; |
1158 | | static int hf_btad_apple_ibeacon_major; |
1159 | | static int hf_btad_apple_ibeacon_minor; |
1160 | | static int hf_btad_apple_ibeacon_measured_power; |
1161 | | |
1162 | | static int ett_btad_apple_ibeacon; |
1163 | | |
1164 | | static dissector_handle_t btad_apple_ibeacon; |
1165 | | |
1166 | | void proto_register_btad_apple_ibeacon(void); |
1167 | | void proto_reg_handoff_btad_apple_ibeacon(void); |
1168 | | |
1169 | | |
1170 | | static int |
1171 | | dissect_btad_apple_ibeacon(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) |
1172 | 0 | { |
1173 | 0 | proto_tree *main_tree; |
1174 | 0 | proto_item *main_item; |
1175 | 0 | int offset = 0; |
1176 | |
|
1177 | 0 | main_item = proto_tree_add_item(tree, proto_btad_apple_ibeacon, tvb, offset, tvb_captured_length(tvb), ENC_NA); |
1178 | 0 | main_tree = proto_item_add_subtree(main_item, ett_btad_apple_ibeacon); |
1179 | |
|
1180 | 0 | proto_tree_add_item(main_tree, hf_btad_apple_ibeacon_type, tvb, offset, 1, ENC_NA); |
1181 | 0 | offset += 1; |
1182 | |
|
1183 | 0 | proto_tree_add_item(main_tree, hf_btad_apple_ibeacon_length, tvb, offset, 1, ENC_NA); |
1184 | 0 | offset += 1; |
1185 | |
|
1186 | 0 | proto_tree_add_item(main_tree, hf_btad_apple_ibeacon_uuid128, tvb, offset, 16, ENC_BIG_ENDIAN); |
1187 | 0 | offset += 16; |
1188 | |
|
1189 | 0 | proto_tree_add_item(main_tree, hf_btad_apple_ibeacon_major, tvb, offset, 2, ENC_BIG_ENDIAN); |
1190 | 0 | offset += 2; |
1191 | |
|
1192 | 0 | proto_tree_add_item(main_tree, hf_btad_apple_ibeacon_minor, tvb, offset, 2, ENC_BIG_ENDIAN); |
1193 | 0 | offset += 2; |
1194 | |
|
1195 | 0 | proto_tree_add_item(main_tree, hf_btad_apple_ibeacon_measured_power, tvb, offset, 1, ENC_NA); |
1196 | 0 | offset += 1; |
1197 | |
|
1198 | 0 | return offset; |
1199 | 0 | } |
1200 | | |
1201 | | void |
1202 | | proto_register_btad_apple_ibeacon(void) |
1203 | 15 | { |
1204 | 15 | static hf_register_info hf[] = { |
1205 | 15 | {&hf_btad_apple_ibeacon_type, |
1206 | 15 | {"Type", "bluetooth.apple.ibeacon.type", |
1207 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1208 | 15 | NULL, HFILL} |
1209 | 15 | }, |
1210 | 15 | {&hf_btad_apple_ibeacon_length, |
1211 | 15 | {"Length", "bluetooth.apple.ibeacon.length", |
1212 | 15 | FT_UINT8, BASE_DEC, NULL, 0x0, |
1213 | 15 | NULL, HFILL} |
1214 | 15 | }, |
1215 | 15 | {&hf_btad_apple_ibeacon_uuid128, |
1216 | 15 | {"UUID", "bluetooth.apple.ibeacon.uuid128", |
1217 | 15 | FT_GUID, BASE_NONE, NULL, 0x0, |
1218 | 15 | NULL, HFILL} |
1219 | 15 | }, |
1220 | 15 | { &hf_btad_apple_ibeacon_major, |
1221 | 15 | { "Major", "bluetooth.apple.ibeacon.major", |
1222 | 15 | FT_UINT16, BASE_DEC, NULL, 0x0, |
1223 | 15 | NULL, HFILL } |
1224 | 15 | }, |
1225 | 15 | { &hf_btad_apple_ibeacon_minor, |
1226 | 15 | { "Minor", "bluetooth.apple.ibeacon.minor", |
1227 | 15 | FT_UINT16, BASE_DEC, NULL, 0x0, |
1228 | 15 | NULL, HFILL } |
1229 | 15 | }, |
1230 | 15 | { &hf_btad_apple_ibeacon_measured_power, |
1231 | 15 | { "Measured Power", "bluetooth.apple.ibeacon.measured_power", |
1232 | 15 | FT_INT8, BASE_DEC|BASE_UNIT_STRING, UNS(&units_dbm), 0x0, |
1233 | 15 | NULL, HFILL } |
1234 | 15 | } |
1235 | 15 | }; |
1236 | | |
1237 | 15 | static int *ett[] = { |
1238 | 15 | &ett_btad_apple_ibeacon, |
1239 | 15 | }; |
1240 | | |
1241 | 15 | proto_btad_apple_ibeacon = proto_register_protocol("Apple iBeacon", "iBeacon", "ibeacon"); |
1242 | 15 | proto_register_field_array(proto_btad_apple_ibeacon, hf, array_length(hf)); |
1243 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
1244 | 15 | btad_apple_ibeacon = register_dissector("bluetooth.apple.ibeacon", dissect_btad_apple_ibeacon, proto_btad_apple_ibeacon); |
1245 | 15 | } |
1246 | | |
1247 | | |
1248 | | void |
1249 | | proto_reg_handoff_btad_apple_ibeacon(void) |
1250 | 15 | { |
1251 | 15 | dissector_add_for_decode_as("btcommon.eir_ad.manufacturer_company_id", btad_apple_ibeacon); |
1252 | 15 | } |
1253 | | |
1254 | | |
1255 | | static int proto_btad_alt_beacon; |
1256 | | |
1257 | | static int hf_btad_alt_beacon_code; |
1258 | | static int hf_btad_alt_beacon_id; |
1259 | | static int hf_btad_alt_beacon_reference_rssi; |
1260 | | static int hf_btad_alt_beacon_manufacturer_data; |
1261 | | |
1262 | | static int ett_btad_alt_beacon; |
1263 | | |
1264 | | static dissector_handle_t btad_alt_beacon; |
1265 | | |
1266 | | void proto_register_btad_alt_beacon(void); |
1267 | | void proto_reg_handoff_btad_alt_beacon(void); |
1268 | | |
1269 | | |
1270 | | static int |
1271 | | dissect_btad_alt_beacon(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) |
1272 | 0 | { |
1273 | 0 | proto_tree *main_tree; |
1274 | 0 | proto_item *main_item; |
1275 | 0 | int offset = 0; |
1276 | |
|
1277 | 0 | main_item = proto_tree_add_item(tree, proto_btad_alt_beacon, tvb, offset, tvb_captured_length(tvb), ENC_NA); |
1278 | 0 | main_tree = proto_item_add_subtree(main_item, ett_btad_alt_beacon); |
1279 | |
|
1280 | 0 | proto_tree_add_item(main_tree, hf_btad_alt_beacon_code, tvb, offset, 2, ENC_BIG_ENDIAN); |
1281 | 0 | offset += 2; |
1282 | |
|
1283 | 0 | proto_tree_add_item(main_tree, hf_btad_alt_beacon_id, tvb, offset, 20, ENC_NA); |
1284 | 0 | offset += 20; |
1285 | |
|
1286 | 0 | proto_tree_add_item(main_tree, hf_btad_alt_beacon_reference_rssi, tvb, offset, 1, ENC_NA); |
1287 | 0 | offset += 1; |
1288 | |
|
1289 | 0 | proto_tree_add_item(main_tree, hf_btad_alt_beacon_manufacturer_data, tvb, offset, 1, ENC_NA); |
1290 | 0 | offset += 1; |
1291 | |
|
1292 | 0 | return offset; |
1293 | 0 | } |
1294 | | |
1295 | | void |
1296 | | proto_register_btad_alt_beacon(void) |
1297 | 15 | { |
1298 | 15 | static hf_register_info hf[] = { |
1299 | 15 | { &hf_btad_alt_beacon_code, |
1300 | 15 | { "Code", "bluetooth.alt_beacon.code", |
1301 | 15 | FT_UINT16, BASE_HEX, NULL, 0x0, |
1302 | 15 | NULL, HFILL } |
1303 | 15 | }, |
1304 | 15 | {&hf_btad_alt_beacon_id, |
1305 | 15 | {"ID", "bluetooth.alt_beacon.id", |
1306 | 15 | FT_BYTES, BASE_NONE, NULL, 0x0, |
1307 | 15 | NULL, HFILL} |
1308 | 15 | }, |
1309 | 15 | { &hf_btad_alt_beacon_reference_rssi, |
1310 | 15 | { "Reference RSSI", "bluetooth.alt_beacon.reference_rssi", |
1311 | 15 | FT_INT8, BASE_DEC, NULL, 0x0, |
1312 | 15 | NULL, HFILL } |
1313 | 15 | }, |
1314 | 15 | { &hf_btad_alt_beacon_manufacturer_data, |
1315 | 15 | { "Manufacturer Data", "bluetooth.alt_beacon.manufacturer_data", |
1316 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, |
1317 | 15 | NULL, HFILL } |
1318 | 15 | } |
1319 | 15 | }; |
1320 | | |
1321 | 15 | static int *ett[] = { |
1322 | 15 | &ett_btad_alt_beacon, |
1323 | 15 | }; |
1324 | | |
1325 | 15 | proto_btad_alt_beacon = proto_register_protocol("AltBeacon", "AltBeacon", "alt_beacon"); |
1326 | 15 | proto_register_field_array(proto_btad_alt_beacon, hf, array_length(hf)); |
1327 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
1328 | 15 | btad_alt_beacon = register_dissector("bluetooth.alt_beacon", dissect_btad_alt_beacon, proto_btad_alt_beacon); |
1329 | 15 | } |
1330 | | |
1331 | | void |
1332 | | proto_reg_handoff_btad_alt_beacon(void) |
1333 | 15 | { |
1334 | 15 | dissector_add_for_decode_as("btcommon.eir_ad.manufacturer_company_id", btad_alt_beacon); |
1335 | 15 | } |
1336 | | |
1337 | | static int proto_btad_gaen; |
1338 | | |
1339 | | static int hf_btad_gaen_rpi128; |
1340 | | static int hf_btad_gaen_aemd32; |
1341 | | |
1342 | | static int ett_btad_gaen; |
1343 | | |
1344 | | static dissector_handle_t btad_gaen; |
1345 | | |
1346 | | void proto_register_btad_gaen(void); |
1347 | | void proto_reg_handoff_btad_gaen(void); |
1348 | | |
1349 | | static int |
1350 | | dissect_btad_gaen(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) |
1351 | 0 | { |
1352 | 0 | proto_tree *main_tree; |
1353 | 0 | proto_item *main_item; |
1354 | 0 | int offset = 0; |
1355 | | |
1356 | | /* The "Service Data" blob of data has the following format for GAEN: |
1357 | | 1 byte: length (0x17) |
1358 | | 1 byte: Type (0x16) |
1359 | | 2 bytes: Identifier (should be 0xFD6F again) |
1360 | | 16 bytes: Rolling Proximity Identifier |
1361 | | 4 bytes: Associated Encrypted Metadata (Encrypted in AES-CTR mode) |
1362 | | 1 byte: Version |
1363 | | 1 byte: Power level |
1364 | | 2 bytes: Reserved for future use. |
1365 | | |
1366 | | We want to skip everything before the last 20 bytes, because it'll be handled by other parts of the BTLE dissector. */ |
1367 | 0 | offset = tvb_captured_length(tvb) - 20; |
1368 | |
|
1369 | 0 | main_item = proto_tree_add_item(tree, proto_btad_gaen, tvb, offset, -1, ENC_NA); |
1370 | 0 | main_tree = proto_item_add_subtree(main_item, ett_btad_gaen); |
1371 | |
|
1372 | 0 | proto_tree_add_item(main_tree, hf_btad_gaen_rpi128, tvb, offset, 16, ENC_NA); |
1373 | 0 | offset += 16; |
1374 | |
|
1375 | 0 | proto_tree_add_item(main_tree, hf_btad_gaen_aemd32, tvb, offset, 4, ENC_NA); |
1376 | 0 | offset += 4; |
1377 | |
|
1378 | 0 | return offset; |
1379 | 0 | } |
1380 | | |
1381 | | void |
1382 | | proto_register_btad_gaen(void) |
1383 | 15 | { |
1384 | 15 | static hf_register_info hf[] = { |
1385 | 15 | { &hf_btad_gaen_rpi128, |
1386 | 15 | { "Rolling Proximity Identifier", "bluetooth.gaen.rpi", |
1387 | 15 | FT_BYTES, BASE_NONE, NULL, 0x0, |
1388 | 15 | NULL, HFILL } |
1389 | 15 | }, |
1390 | 15 | { &hf_btad_gaen_aemd32, |
1391 | 15 | { "Associated Encrypted Metadata", "bluetooth.gaen.aemd", |
1392 | 15 | FT_BYTES, BASE_NONE, NULL, 0x0, |
1393 | 15 | NULL, HFILL } |
1394 | 15 | } |
1395 | 15 | }; |
1396 | | |
1397 | 15 | static int *ett[] = { |
1398 | 15 | &ett_btad_gaen, |
1399 | 15 | }; |
1400 | | |
1401 | 15 | proto_btad_gaen = proto_register_protocol("Google/Apple Exposure Notification", "Google/Apple Exposure Notification", "bluetooth.gaen"); |
1402 | 15 | proto_register_field_array(proto_btad_gaen, hf, array_length(hf)); |
1403 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
1404 | 15 | btad_gaen = register_dissector("bluetooth.gaen", dissect_btad_gaen, proto_btad_gaen); |
1405 | 15 | } |
1406 | | |
1407 | | void |
1408 | | proto_reg_handoff_btad_gaen(void) |
1409 | 15 | { |
1410 | 15 | dissector_add_string("btcommon.eir_ad.entry.uuid", "fd6f", btad_gaen); |
1411 | 15 | } |
1412 | | |
1413 | | static int proto_btad_matter; |
1414 | | |
1415 | 15 | #define MATTER_OPCODE_COMMISSIONABLE 0x00 |
1416 | 15 | #define MATTER_OPCODE_NETWORK_RECOVERY 0x01 |
1417 | | |
1418 | | static int hf_btad_matter_opcode; |
1419 | | static int hf_btad_matter_version_u8; |
1420 | | static int hf_btad_matter_version_u16; |
1421 | | static int hf_btad_matter_discriminator; |
1422 | | static int hf_btad_matter_vendor_id; |
1423 | | static int hf_btad_matter_product_id; |
1424 | | static int hf_btad_matter_recovery_id; |
1425 | | static int hf_btad_matter_flags; |
1426 | | static int hf_btad_matter_flags_additional_data; |
1427 | | static int hf_btad_matter_flags_ext_announcement; |
1428 | | |
1429 | | static int ett_btad_matter; |
1430 | | static int ett_btad_matter_flags; |
1431 | | |
1432 | | static dissector_handle_t btad_matter; |
1433 | | |
1434 | | void proto_register_btad_matter(void); |
1435 | | void proto_reg_handoff_btad_matter(void); |
1436 | | |
1437 | | static int |
1438 | | dissect_btad_matter(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) |
1439 | 0 | { |
1440 | 0 | int offset = 0; |
1441 | 0 | proto_tree *main_item = proto_tree_add_item(tree, proto_btad_matter, tvb, offset, -1, ENC_NA); |
1442 | 0 | proto_tree *main_tree = proto_item_add_subtree(main_item, ett_btad_matter); |
1443 | |
|
1444 | 0 | unsigned int opcode; |
1445 | 0 | proto_tree_add_item_ret_uint(main_tree, hf_btad_matter_opcode, tvb, offset, 1, ENC_NA, &opcode); |
1446 | 0 | offset += 1; |
1447 | |
|
1448 | 0 | switch (opcode) { |
1449 | 0 | case MATTER_OPCODE_COMMISSIONABLE: |
1450 | 0 | proto_tree_add_item(main_tree, hf_btad_matter_version_u16, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
1451 | 0 | proto_tree_add_item(main_tree, hf_btad_matter_discriminator, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
1452 | 0 | offset += 2; |
1453 | 0 | proto_tree_add_item(main_tree, hf_btad_matter_vendor_id, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
1454 | 0 | offset += 2; |
1455 | 0 | proto_tree_add_item(main_tree, hf_btad_matter_product_id, tvb, offset, 2, ENC_LITTLE_ENDIAN); |
1456 | 0 | offset += 2; |
1457 | 0 | break; |
1458 | 0 | case MATTER_OPCODE_NETWORK_RECOVERY: |
1459 | 0 | proto_tree_add_item(main_tree, hf_btad_matter_version_u8, tvb, offset, 1, ENC_NA); |
1460 | 0 | offset += 1; |
1461 | 0 | proto_tree_add_item(main_tree, hf_btad_matter_recovery_id, tvb, offset, 8, ENC_LITTLE_ENDIAN); |
1462 | 0 | offset += 8; |
1463 | 0 | break; |
1464 | 0 | default: |
1465 | 0 | return offset; |
1466 | 0 | } |
1467 | | |
1468 | 0 | static int * const flags[] = { |
1469 | 0 | &hf_btad_matter_flags_additional_data, |
1470 | 0 | &hf_btad_matter_flags_ext_announcement, |
1471 | 0 | NULL |
1472 | 0 | }; |
1473 | |
|
1474 | 0 | proto_tree_add_bitmask(main_tree, tvb, offset, hf_btad_matter_flags, ett_btad_matter_flags, flags, ENC_NA); |
1475 | 0 | offset += 1; |
1476 | |
|
1477 | 0 | return offset; |
1478 | 0 | } |
1479 | | |
1480 | | void |
1481 | | proto_register_btad_matter(void) |
1482 | 15 | { |
1483 | 15 | static const value_string opcode_vals[] = { |
1484 | 15 | { MATTER_OPCODE_COMMISSIONABLE, "Commissionable" }, |
1485 | 15 | { MATTER_OPCODE_NETWORK_RECOVERY, "Network Recovery" }, |
1486 | 15 | { 0, NULL } |
1487 | 15 | }; |
1488 | | |
1489 | 15 | static hf_register_info hf[] = { |
1490 | 15 | { &hf_btad_matter_opcode, |
1491 | 15 | { "Opcode", "bluetooth.matter.opcode", |
1492 | 15 | FT_UINT8, BASE_HEX, VALS(opcode_vals), 0x0, |
1493 | 15 | NULL, HFILL } |
1494 | 15 | }, |
1495 | 15 | {&hf_btad_matter_version_u8, |
1496 | 15 | {"Advertisement Version", "bluetooth.matter.version", |
1497 | 15 | FT_UINT8, BASE_DEC, NULL, 0xF0, |
1498 | 15 | NULL, HFILL} |
1499 | 15 | }, |
1500 | 15 | {&hf_btad_matter_version_u16, |
1501 | 15 | {"Advertisement Version", "bluetooth.matter.version", |
1502 | 15 | FT_UINT16, BASE_DEC, NULL, 0xF000, |
1503 | 15 | NULL, HFILL} |
1504 | 15 | }, |
1505 | 15 | { &hf_btad_matter_discriminator, |
1506 | 15 | { "Discriminator", "bluetooth.matter.discriminator", |
1507 | 15 | FT_UINT16, BASE_HEX, NULL, 0x0FFF, |
1508 | 15 | "A 12-bit value used in the Setup Code", HFILL } |
1509 | 15 | }, |
1510 | 15 | { &hf_btad_matter_vendor_id, |
1511 | 15 | { "Vendor ID", "bluetooth.matter.vendor_id", |
1512 | 15 | FT_UINT16, BASE_HEX, NULL, 0x0, |
1513 | 15 | "A 16-bit value identifying the device manufacturer", HFILL } |
1514 | 15 | }, |
1515 | 15 | { &hf_btad_matter_product_id, |
1516 | 15 | { "Product ID", "bluetooth.matter.product_id", |
1517 | 15 | FT_UINT16, BASE_HEX, NULL, 0x0, |
1518 | 15 | "A 16-bit value identifying the product", HFILL } |
1519 | 15 | }, |
1520 | 15 | { &hf_btad_matter_recovery_id, |
1521 | 15 | { "Recovery ID", "bluetooth.matter.recovery_id", |
1522 | 15 | FT_UINT64, BASE_HEX, NULL, 0x0, |
1523 | 15 | "A 64-bit recovery ID", HFILL } |
1524 | 15 | }, |
1525 | 15 | { &hf_btad_matter_flags, |
1526 | 15 | { "Flags", "bluetooth.matter.flags", |
1527 | 15 | FT_UINT8, BASE_HEX, NULL, 0x0, |
1528 | 15 | NULL, HFILL } |
1529 | 15 | }, |
1530 | 15 | { &hf_btad_matter_flags_additional_data, |
1531 | 15 | { "Additional Data", "bluetooth.matter.flags.additional_data", |
1532 | 15 | FT_BOOLEAN, 8, NULL, 0x01, |
1533 | 15 | "Set if the device provides the optional C3 GATT characteristic", HFILL } |
1534 | 15 | }, |
1535 | 15 | { &hf_btad_matter_flags_ext_announcement, |
1536 | 15 | { "Extended Announcement", "bluetooth.matter.flags.ext_announcement", |
1537 | 15 | FT_BOOLEAN, 8, NULL, 0x02, |
1538 | 15 | "Set while the device is in the Extended Announcement period", HFILL } |
1539 | 15 | }, |
1540 | 15 | }; |
1541 | | |
1542 | 15 | static int *ett[] = { |
1543 | 15 | &ett_btad_matter, |
1544 | 15 | &ett_btad_matter_flags, |
1545 | 15 | }; |
1546 | | |
1547 | 15 | proto_btad_matter = proto_register_protocol("Matter Advertising Data", "Matter Advertising Data", "bluetooth.matter"); |
1548 | 15 | proto_register_field_array(proto_btad_matter, hf, array_length(hf)); |
1549 | 15 | proto_register_subtree_array(ett, array_length(ett)); |
1550 | 15 | btad_matter = register_dissector("bluetooth.matter", dissect_btad_matter, proto_btad_matter); |
1551 | 15 | } |
1552 | | |
1553 | | void |
1554 | | proto_reg_handoff_btad_matter(void) |
1555 | 15 | { |
1556 | 15 | dissector_add_string("btcommon.eir_ad.entry.uuid", "fff6", btad_matter); |
1557 | 15 | } |
1558 | | |
1559 | | /* |
1560 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
1561 | | * |
1562 | | * Local variables: |
1563 | | * c-basic-offset: 4 |
1564 | | * tab-width: 8 |
1565 | | * indent-tabs-mode: nil |
1566 | | * End: |
1567 | | * |
1568 | | * vi: set shiftwidth=4 tabstop=8 expandtab: |
1569 | | * :indentSize=4:tabSize=8:noTabs=true: |
1570 | | */ |