Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-btmesh-beacon.c
blobe8243b6e9b12c85677e244e8f9909b64541260c0
1 /* packet-btmesh-beacon.c
2 * Routines for Bluetooth mesh PB-ADV dissection
4 * Copyright 2019, Piotr Winiarczyk <wino45@gmail.com>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
12 * Ref: Mesh Profile v1.0
13 * https://www.bluetooth.com/specifications/mesh-specifications
16 #include "config.h"
18 #include <epan/packet.h>
19 #include <epan/prefs.h>
20 #include <epan/expert.h>
21 #include <epan/tfs.h>
23 #include "packet-btmesh.h"
25 #define BEACON_UNPROVISION 0x00
26 #define BEACON_SECURE 0x01
28 void proto_register_btmesh_beacon(void);
30 static int proto_btmesh_beacon;
32 static int hf_btmesh_beacon_type;
33 static int hf_btmesh_beacon_uuid;
34 static int hf_btmesh_beacon_oob;
35 static int hf_btmesh_beacon_oob_other;
36 static int hf_btmesh_beacon_oob_electronic;
37 static int hf_btmesh_beacon_oob_2d_code;
38 static int hf_btmesh_beacon_oob_bar_code;
39 static int hf_btmesh_beacon_oob_nfc;
40 static int hf_btmesh_beacon_oob_number;
41 static int hf_btmesh_beacon_oob_string;
42 static int hf_btmesh_beacon_oob_rfu;
43 static int hf_btmesh_beacon_oob_on_box;
44 static int hf_btmesh_beacon_oob_inside_box;
45 static int hf_btmesh_beacon_oob_on_paper;
46 static int hf_btmesh_beacon_oob_inside_manual;
47 static int hf_btmesh_beacon_oob_on_device;
48 static int hf_btmesh_beacon_uri_hash;
49 static int hf_btmesh_beacon_flags;
50 static int hf_btmesh_beacon_flags_key_refresh;
51 static int hf_btmesh_beacon_flags_iv_update;
52 static int hf_btmesh_beacon_flags_rfu;
53 static int hf_btmesh_beacon_network_id;
54 static int hf_btmesh_beacon_ivindex;
55 //TODO: check authentication value
56 static int hf_btmesh_beacon_authentication_value;
57 static int hf_btmesh_beacon_unknown_data;
59 static int ett_btmesh_beacon;
60 static int ett_btmesh_beacon_oob;
61 static int ett_btmesh_beacon_flags;
63 static expert_field ei_btmesh_beacon_unknown_beacon_type;
64 static expert_field ei_btmesh_beacon_unknown_payload;
65 static expert_field ei_btmesh_beacon_rfu_not_zero;
67 static const value_string btmesh_beacon_type[] = {
68 { 0, "Unprovisioned Device Beacon" },
69 { 1, "Secure Network Beacon" },
70 { 0, NULL }
73 static const true_false_string flags_key_refresh = {
74 "Key Refresh in progress",
75 "Key Refresh not in progress"
78 static const true_false_string flags_iv_update = {
79 "IV Update active",
80 "Normal operation"
83 static int
84 dissect_btmesh_beacon_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
87 proto_item *item, *oob_item, *flags_item;
88 proto_tree *sub_tree, *oob_tree, *flags_tree;
89 unsigned offset = 0;
90 unsigned data_size = 0;
91 btle_mesh_transport_ctx_t *tr_ctx;
92 btle_mesh_transport_ctx_t dummy_ctx = {E_BTMESH_TR_UNKNOWN, false, 0};
93 uint16_t rfu_bits16;
94 uint8_t rfu_bits8;
96 col_set_str(pinfo->cinfo, COL_PROTOCOL, "BT Mesh Beacon");
98 if (data == NULL) {
99 tr_ctx = &dummy_ctx;
100 } else {
101 tr_ctx = (btle_mesh_transport_ctx_t *) data;
104 item = proto_tree_add_item(tree, proto_btmesh_beacon, tvb, offset, -1, ENC_NA);
105 sub_tree = proto_item_add_subtree(item, ett_btmesh_beacon);
107 uint8_t beacon_type = tvb_get_uint8(tvb, offset);
108 proto_tree_add_item(sub_tree, hf_btmesh_beacon_type, tvb, offset, 1, ENC_NA);
109 offset += 1;
111 col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(beacon_type, btmesh_beacon_type, "Unknown Beacon Type"));
112 if (tr_ctx->fragmented) {
113 switch (tr_ctx->transport) {
114 case E_BTMESH_TR_PROXY:
115 col_append_str(pinfo->cinfo, COL_INFO," (Last Segment)");
117 break;
118 default:
119 //No default is needed since this is an additional information only
121 break;
125 switch(beacon_type) {
126 case BEACON_UNPROVISION:
127 proto_tree_add_item(sub_tree, hf_btmesh_beacon_uuid, tvb, offset, 16, ENC_NA);
128 offset += 16;
130 oob_item = proto_tree_add_item(sub_tree, hf_btmesh_beacon_oob, tvb, offset, 2, ENC_BIG_ENDIAN);
131 oob_tree = proto_item_add_subtree(oob_item, ett_btmesh_beacon_oob);
133 proto_tree_add_item(oob_tree, hf_btmesh_beacon_oob_other, tvb, offset, 2, ENC_NA);
134 proto_tree_add_item(oob_tree, hf_btmesh_beacon_oob_electronic, tvb, offset, 2, ENC_NA);
135 proto_tree_add_item(oob_tree, hf_btmesh_beacon_oob_2d_code, tvb, offset, 2, ENC_NA);
136 proto_tree_add_item(oob_tree, hf_btmesh_beacon_oob_bar_code, tvb, offset, 2, ENC_NA);
137 proto_tree_add_item(oob_tree, hf_btmesh_beacon_oob_nfc, tvb, offset, 2, ENC_NA);
138 proto_tree_add_item(oob_tree, hf_btmesh_beacon_oob_number, tvb, offset, 2, ENC_NA);
139 proto_tree_add_item(oob_tree, hf_btmesh_beacon_oob_string, tvb, offset, 2, ENC_NA);
140 proto_tree_add_item(oob_tree, hf_btmesh_beacon_oob_rfu, tvb, offset, 2, ENC_NA);
141 proto_tree_add_item(oob_tree, hf_btmesh_beacon_oob_on_box, tvb, offset, 2, ENC_NA);
142 proto_tree_add_item(oob_tree, hf_btmesh_beacon_oob_inside_box, tvb, offset, 2, ENC_NA);
143 proto_tree_add_item(oob_tree, hf_btmesh_beacon_oob_on_paper, tvb, offset, 2, ENC_NA);
144 proto_tree_add_item(oob_tree, hf_btmesh_beacon_oob_inside_manual, tvb, offset, 2, ENC_NA);
145 proto_tree_add_item(oob_tree, hf_btmesh_beacon_oob_on_device, tvb, offset, 2, ENC_NA);
146 rfu_bits16 = (tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN) & 0x0780) >> 7;
147 if (rfu_bits16 != 0) {
148 //RFU bits should be 0
149 proto_tree_add_expert(oob_tree, pinfo, &ei_btmesh_beacon_rfu_not_zero, tvb, offset, -1);
151 offset += 2;
153 data_size = tvb_reported_length(tvb);
154 if (data_size == offset + 4 ) {
155 proto_tree_add_item(sub_tree, hf_btmesh_beacon_uri_hash, tvb, offset, 4, ENC_NA);
156 offset += 4;
158 //Wrong size handled outside switch/case
160 break;
161 case BEACON_SECURE:
162 flags_item = proto_tree_add_item(sub_tree, hf_btmesh_beacon_flags, tvb, offset, 1, ENC_NA);
163 flags_tree = proto_item_add_subtree(flags_item, ett_btmesh_beacon_flags);
164 proto_tree_add_item(flags_tree, hf_btmesh_beacon_flags_key_refresh, tvb, offset, 1, ENC_NA);
165 proto_tree_add_item(flags_tree, hf_btmesh_beacon_flags_iv_update, tvb, offset, 1, ENC_NA);
166 proto_tree_add_item(flags_tree, hf_btmesh_beacon_flags_rfu, tvb, offset, 1, ENC_NA);
167 rfu_bits8 = tvb_get_uint8(tvb, offset) >> 2;
168 if (rfu_bits8 != 0) {
169 //RFU bits should be 0
170 proto_tree_add_expert(flags_tree, pinfo, &ei_btmesh_beacon_rfu_not_zero, tvb, offset, -1);
172 offset += 1;
173 proto_tree_add_item(sub_tree, hf_btmesh_beacon_network_id, tvb, offset, 8, ENC_NA);
174 offset += 8;
175 proto_tree_add_item(sub_tree, hf_btmesh_beacon_ivindex, tvb, offset, 4, ENC_NA);
176 offset += 4;
177 proto_tree_add_item(sub_tree, hf_btmesh_beacon_authentication_value, tvb, offset, 8, ENC_NA);
178 offset += 8;
179 break;
180 default:
181 //Unknown mesh beacon type, display data and flag it
182 proto_tree_add_item(sub_tree, hf_btmesh_beacon_unknown_data, tvb, offset, -1, ENC_NA);
183 proto_tree_add_expert(sub_tree, pinfo, &ei_btmesh_beacon_unknown_beacon_type, tvb, offset, -1);
184 offset += tvb_captured_length_remaining(tvb, offset);
185 break;
187 //There is still some data but all data should be already disssected
188 if (tvb_captured_length_remaining(tvb, offset) != 0) {
189 proto_tree_add_expert(sub_tree, pinfo, &ei_btmesh_beacon_unknown_payload, tvb, offset, -1);
192 return tvb_reported_length(tvb);
195 void
196 proto_register_btmesh_beacon(void)
198 static hf_register_info hf[] = {
199 { &hf_btmesh_beacon_type,
200 { "Type", "beacon.type",
201 FT_UINT8, BASE_DEC, VALS(btmesh_beacon_type), 0x0,
202 NULL, HFILL }
204 { &hf_btmesh_beacon_uuid,
205 { "Device UUID", "beacon.uuid",
206 FT_GUID, BASE_NONE, NULL, 0x0,
207 NULL, HFILL }
209 { &hf_btmesh_beacon_oob,
210 { "OOB Information", "beacon.oob",
211 FT_UINT16, BASE_HEX, NULL, 0x0,
212 NULL, HFILL }
214 { &hf_btmesh_beacon_oob_other,
215 { "Other", "beacon.oob.other",
216 FT_BOOLEAN, 16, TFS(&tfs_available_not_available), 0x0001,
217 NULL, HFILL }
219 { &hf_btmesh_beacon_oob_electronic,
220 { "Electronic / URI", "beacon.oob.electronic",
221 FT_BOOLEAN, 16, TFS(&tfs_available_not_available), 0x0002,
222 NULL, HFILL }
224 { &hf_btmesh_beacon_oob_2d_code,
225 { "2D machine-readable code", "beacon.oob.2d_code",
226 FT_BOOLEAN, 16, TFS(&tfs_available_not_available), 0x0004,
227 NULL, HFILL }
229 { &hf_btmesh_beacon_oob_bar_code,
230 { "Bar code", "beacon.oob.bar_code",
231 FT_BOOLEAN, 16, TFS(&tfs_available_not_available), 0x0008,
232 NULL, HFILL }
234 { &hf_btmesh_beacon_oob_nfc,
235 { "Near Field Communication (NFC)", "beacon.oob.nfc",
236 FT_BOOLEAN, 16, TFS(&tfs_available_not_available), 0x0010,
237 NULL, HFILL }
239 { &hf_btmesh_beacon_oob_number,
240 { "Number", "beacon.oob.number",
241 FT_BOOLEAN, 16, TFS(&tfs_available_not_available), 0x0020,
242 NULL, HFILL }
244 { &hf_btmesh_beacon_oob_string,
245 { "String", "beacon.oob.string",
246 FT_BOOLEAN, 16, TFS(&tfs_available_not_available), 0x0040,
247 NULL, HFILL }
249 { &hf_btmesh_beacon_oob_rfu,
250 { "Reserved for Future Use", "beacon.oob.rfu",
251 FT_UINT16, BASE_DEC, NULL, 0x0780,
252 NULL, HFILL }
254 { &hf_btmesh_beacon_oob_on_box,
255 { "On box", "beacon.oob.on_box",
256 FT_BOOLEAN, 16, TFS(&tfs_available_not_available), 0x0800,
257 NULL, HFILL }
259 { &hf_btmesh_beacon_oob_inside_box,
260 { "Inside box", "beacon.oob.inside_box",
261 FT_BOOLEAN, 16, TFS(&tfs_available_not_available), 0x1000,
262 NULL, HFILL }
264 { &hf_btmesh_beacon_oob_on_paper,
265 { "On piece of paper", "beacon.oob.on_paper",
266 FT_BOOLEAN, 16, TFS(&tfs_available_not_available), 0x2000,
267 NULL, HFILL }
269 { &hf_btmesh_beacon_oob_inside_manual,
270 { "Inside manual", "beacon.oob.inside_manual",
271 FT_BOOLEAN, 16, TFS(&tfs_available_not_available), 0x4000,
272 NULL, HFILL }
274 { &hf_btmesh_beacon_oob_on_device,
275 { "On device", "beacon.oob.on_device",
276 FT_BOOLEAN, 16, TFS(&tfs_available_not_available), 0x8000,
277 NULL, HFILL }
279 { &hf_btmesh_beacon_uri_hash,
280 { "URI Hash", "beacon.uri_hash",
281 FT_BYTES, BASE_NONE, NULL, 0x0,
282 NULL, HFILL }
284 { &hf_btmesh_beacon_flags,
285 { "Flags", "beacon.flags",
286 FT_UINT8, BASE_HEX, NULL, 0x0,
287 NULL, HFILL }
289 { &hf_btmesh_beacon_flags_key_refresh,
290 { "Key Refresh Flag", "beacon.flags.key_refresh",
291 FT_BOOLEAN, 8, TFS(&flags_key_refresh), 0x01,
292 NULL, HFILL }
294 { &hf_btmesh_beacon_flags_iv_update,
295 { "IV Update Flag", "beacon.flags.iv_update",
296 FT_BOOLEAN, 8, TFS(&flags_iv_update), 0x02,
297 NULL, HFILL }
299 { &hf_btmesh_beacon_flags_rfu,
300 { "Reserved for Future Use", "beacon.flags.rfu",
301 FT_UINT8, BASE_DEC, NULL, 0xFC,
302 NULL, HFILL }
304 { &hf_btmesh_beacon_network_id,
305 { "Network ID", "beacon.network_id",
306 FT_BYTES, BASE_NONE, NULL, 0x0,
307 NULL, HFILL }
309 { &hf_btmesh_beacon_ivindex,
310 { "IV Index", "beacon.ivindex",
311 FT_UINT32, BASE_DEC, NULL, 0x0,
312 NULL, HFILL }
314 { &hf_btmesh_beacon_authentication_value,
315 { "Authentication Value", "beacon.authentication_value",
316 FT_BYTES, BASE_NONE, NULL, 0x0,
317 NULL, HFILL }
319 { &hf_btmesh_beacon_unknown_data,
320 { "Unknown Data", "beacon.unknown_data",
321 FT_BYTES, BASE_NONE, NULL, 0x0,
322 NULL, HFILL }
326 static int *ett[] = {
327 &ett_btmesh_beacon,
328 &ett_btmesh_beacon_oob,
329 &ett_btmesh_beacon_flags,
332 static ei_register_info ei[] = {
333 { &ei_btmesh_beacon_unknown_beacon_type,{ "beacon.unknown_beacon_type", PI_PROTOCOL, PI_ERROR, "Unknown Beacon Type", EXPFILL } },
334 { &ei_btmesh_beacon_unknown_payload,{ "beacon.unknown_payload", PI_PROTOCOL, PI_ERROR, "Unknown Payload", EXPFILL } },
335 { &ei_btmesh_beacon_rfu_not_zero,{ "beacon.rfu_not_zero", PI_PROTOCOL, PI_WARN, "Reserved for Future Use value not equal to 0", EXPFILL } },
338 expert_module_t* expert_btmesh_beacon;
340 proto_btmesh_beacon = proto_register_protocol("Bluetooth Mesh Beacon", "BT Mesh beacon", "beacon");
342 proto_register_field_array(proto_btmesh_beacon, hf, array_length(hf));
343 proto_register_subtree_array(ett, array_length(ett));
345 expert_btmesh_beacon = expert_register_protocol(proto_btmesh_beacon);
346 expert_register_field_array(expert_btmesh_beacon, ei, array_length(ei));
348 prefs_register_protocol_subtree("Bluetooth", proto_btmesh_beacon, NULL);
349 register_dissector("btmesh.beacon", dissect_btmesh_beacon_msg, proto_btmesh_beacon);
353 * Editor modelines
355 * Local Variables:
356 * c-basic-offset: 4
357 * tab-width: 8
358 * indent-tabs-mode: nil
359 * End:
361 * ex: set shiftwidth=4 tabstop=8 expandtab:
362 * :indentSize=4:tabSize=8:noTabs=true: