Coverage Report

Created: 2026-05-14 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
 */