1# SPDX-License-Identifier: GPL-2.0-only
2# This file is part of Scapy
3# See https://scapy.net/ for more information
4# Copyright (C) Philippe Biondi <phil@secdev.org>
5# Copyright (C) Mike Ryan <mikeryan@lacklustre.net>
6# Copyright (C) Michael Farrell <micolous+git@gmail.com>
7# Copyright (C) Haram Park <freehr94@korea.ac.kr>
8
9"""
10Bluetooth layers, sockets and send/receive functions.
11"""
12
13import ctypes
14import functools
15import socket
16import struct
17import select
18from ctypes import sizeof
19
20from scapy.config import conf
21from scapy.data import (
22 DLT_BLUETOOTH_HCI_H4,
23 DLT_BLUETOOTH_HCI_H4_WITH_PHDR,
24 DLT_BLUETOOTH_LINUX_MONITOR
25)
26from scapy.packet import bind_layers, Packet
27from scapy.fields import (
28 BitField,
29 XBitField,
30 ByteEnumField,
31 ByteField,
32 FieldLenField,
33 FieldListField,
34 FlagsField,
35 IntField,
36 LEShortEnumField,
37 LEShortField,
38 LEIntField,
39 LenField,
40 MultipleTypeField,
41 NBytesField,
42 PacketListField,
43 PadField,
44 ShortField,
45 SignedByteField,
46 StrField,
47 StrFixedLenField,
48 StrLenField,
49 StrNullField,
50 UUIDField,
51 XByteField,
52 XLE3BytesField,
53 XLELongField,
54 XStrLenField,
55 XLEShortField,
56 XLEIntField,
57 LEMACField,
58 BitEnumField,
59 LEThreeBytesField,
60)
61from scapy.supersocket import SuperSocket
62from scapy.sendrecv import sndrcv
63from scapy.data import MTU
64from scapy.consts import WINDOWS
65from scapy.error import warning
66
67
68############
69# Consts #
70############
71
72# From hci.h
73HCI_CHANNEL_RAW = 0
74HCI_CHANNEL_USER = 1
75HCI_CHANNEL_MONITOR = 2
76HCI_CHANNEL_CONTROL = 3
77HCI_CHANNEL_LOGGING = 4
78
79HCI_DEV_NONE = 0xffff
80
81
82##########
83# Layers #
84##########
85
86# See bluez/lib/hci.h for details
87
88# Transport layers
89
90class HCI_PHDR_Hdr(Packet):
91 name = "HCI PHDR transport layer"
92 fields_desc = [IntField("direction", 0)]
93
94
95# Real layers
96
97_bluetooth_packet_types = {
98 0: "Acknowledgement",
99 1: "Command",
100 2: "ACL Data",
101 3: "Synchronous",
102 4: "Event",
103 5: "Reserve",
104 14: "Vendor",
105 15: "Link Control"
106}
107
108_bluetooth_error_codes = {
109 0x00: "Success",
110 0x01: "Unknown HCI Command",
111 0x02: "Unknown Connection Identifier",
112 0x03: "Hardware Failure",
113 0x04: "Page Timeout",
114 0x05: "Authentication Failure",
115 0x06: "PIN or Key Missing",
116 0x07: "Memory Capacity Exceeded",
117 0x08: "Connection Timeout",
118 0x09: "Connection Limit Exceeded",
119 0x0A: "Synchronous Connection Limit To A Device Exceeded",
120 0x0B: "Connection Already Exists",
121 0x0C: "Command Disallowed",
122 0x0D: "Connection Rejected due to Limited Resources",
123 0x0E: "Connection Rejected Due To Security Reasons",
124 0x0F: "Connection Rejected due to Unacceptable BD_ADDR",
125 0x10: "Connection Accept Timeout Exceeded",
126 0x11: "Unsupported Feature or Parameter Value",
127 0x12: "Invalid HCI Command Parameters",
128 0x13: "Remote User Terminated Connection",
129 0x14: "Remote Device Terminated Connection due to Low Resources",
130 0x15: "Remote Device Terminated Connection due to Power Off",
131 0x16: "Connection Terminated By Local Host",
132 0x17: "Repeated Attempts",
133 0x18: "Pairing Not Allowed",
134 0x19: "Unknown LMP PDU",
135 0x1A: "Unsupported Remote Feature / Unsupported LMP Feature",
136 0x1B: "SCO Offset Rejected",
137 0x1C: "SCO Interval Rejected",
138 0x1D: "SCO Air Mode Rejected",
139 0x1E: "Invalid LMP Parameters / Invalid LL Parameters",
140 0x1F: "Unspecified Error",
141 0x20: "Unsupported LMP Parameter Value / Unsupported LL Parameter Value",
142 0x21: "Role Change Not Allowed",
143 0x22: "LMP Response Timeout / LL Response Timeout",
144 0x23: "LMP Error Transaction Collision / LL Procedure Collision",
145 0x24: "LMP PDU Not Allowed",
146 0x25: "Encryption Mode Not Acceptable",
147 0x26: "Link Key cannot be Changed",
148 0x27: "Requested QoS Not Supported",
149 0x28: "Instant Passed",
150 0x29: "Pairing With Unit Key Not Supported",
151 0x2A: "Different Transaction Collision",
152 0x2B: "Reserved for future use",
153 0x2C: "QoS Unacceptable Parameter",
154 0x2D: "QoS Rejected",
155 0x2E: "Channel Classification Not Supported",
156 0x2F: "Insufficient Security",
157 0x30: "Parameter Out Of Mandatory Range",
158 0x31: "Reserved for future use",
159 0x32: "Role Switch Pending",
160 0x33: "Reserved for future use",
161 0x34: "Reserved Slot Violation",
162 0x35: "Role Switch Failed",
163 0x36: "Extended Inquiry Response Too Large",
164 0x37: "Secure Simple Pairing Not Supported By Host",
165 0x38: "Host Busy - Pairing",
166 0x39: "Connection Rejected due to No Suitable Channel Found",
167 0x3A: "Controller Busy",
168 0x3B: "Unacceptable Connection Parameters",
169 0x3C: "Advertising Timeout",
170 0x3D: "Connection Terminated due to MIC Failure",
171 0x3E: "Connection Failed to be Established / Synchronization Timeout",
172 0x3F: "MAC Connection Failed",
173 0x40: "Coarse Clock Adjustment Rejected but Will Try to Adjust Using Clock"
174 " Dragging",
175 0x41: "Type0 Submap Not Defined",
176 0x42: "Unknown Advertising Identifier",
177 0x43: "Limit Reached",
178 0x44: "Operation Cancelled by Host",
179 0x45: "Packet Too Long"
180}
181
182_att_error_codes = {
183 0x01: "invalid handle",
184 0x02: "read not permitted",
185 0x03: "write not permitted",
186 0x04: "invalid pdu",
187 0x05: "insufficient auth",
188 0x06: "unsupported req",
189 0x07: "invalid offset",
190 0x08: "insufficient author",
191 0x09: "prepare queue full",
192 0x0a: "attr not found",
193 0x0b: "attr not long",
194 0x0c: "insufficient key size",
195 0x0d: "invalid value size",
196 0x0e: "unlikely",
197 0x0f: "insufficiet encrypt",
198 0x10: "unsupported gpr type",
199 0x11: "insufficient resources",
200}
201
202_bluetooth_features = [
203 '3_slot_packets',
204 '5_slot_packets',
205 'encryption',
206 'slot_offset',
207 'timing_accuracy',
208 'role_switch',
209 'hold_mode',
210 'sniff_mode',
211 'park_mode',
212 'power_control_requests',
213 'channel_quality_driven_data_rate',
214 'sco_link',
215 'hv2_packets',
216 'hv3_packets',
217 'u_law_log_synchronous_data',
218 'a_law_log_synchronous_data',
219 'cvsd_synchronous_data',
220 'paging_parameter_negotiation',
221 'power_control',
222 'transparent_synchronous_data',
223 'flow_control_lag_4_bit0',
224 'flow_control_lag_4_bit1',
225 'flow_control_lag_4_bit2',
226 'broadband_encryption',
227 'cvsd_synchronous_data',
228 'edr_acl_2_mbps_mode',
229 'edr_acl_3_mbps_mode',
230 'enhanced_inquiry_scan',
231 'interlaced_inquiry_scan',
232 'interlaced_page_scan',
233 'rssi_with_inquiry_results',
234 'ev3_packets',
235 'ev4_packets',
236 'ev5_packets',
237 'reserved',
238 'afh_capable_slave',
239 'afh_classification_slave',
240 'br_edr_not_supported',
241 'le_supported_controller',
242 '3_slot_edr_acl_packets',
243 '5_slot_edr_acl_packets',
244 'sniff_subrating',
245 'pause_encryption',
246 'afh_capable_master',
247 'afh_classification_master',
248 'edr_esco_2_mbps_mode',
249 'edr_esco_3_mbps_mode',
250 '3_slot_edr_esco_packets',
251 'extended_inquiry_response',
252 'simultaneous_le_and_br_edr_to_same_device_capable_controller',
253 'reserved2',
254 'secure_simple_pairing',
255 'encapsulated_pdu',
256 'erroneous_data_reporting',
257 'non_flushable_packet_boundary_flag',
258 'reserved3',
259 'link_supervision_timeout_changed_event',
260 'inquiry_tx_power_level',
261 'enhanced_power_control',
262 'reserved4_bit0',
263 'reserved4_bit1',
264 'reserved4_bit2',
265 'reserved4_bit3',
266 'extended_features',
267]
268
269
270class HCI_Hdr(Packet):
271 name = "HCI header"
272 fields_desc = [ByteEnumField("type", 2, _bluetooth_packet_types)]
273
274 def mysummary(self):
275 return self.sprintf("HCI %type%")
276
277
278class HCI_ACL_Hdr(Packet):
279 name = "HCI ACL header"
280 fields_desc = [BitField("BC", 0, 2, tot_size=-2),
281 BitField("PB", 0, 2),
282 BitField("handle", 0, 12, end_tot_size=-2),
283 LEShortField("len", None), ]
284
285 def post_build(self, p, pay):
286 p += pay
287 if self.len is None:
288 p = p[:2] + struct.pack("<H", len(pay)) + p[4:]
289 return p
290
291
292class L2CAP_Hdr(Packet):
293 name = "L2CAP header"
294 fields_desc = [LEShortField("len", None),
295 LEShortEnumField("cid", 0, {1: "control", 4: "attribute"}), ] # noqa: E501
296
297 def post_build(self, p, pay):
298 p += pay
299 if self.len is None:
300 p = struct.pack("<H", len(pay)) + p[2:]
301 return p
302
303
304class L2CAP_CmdHdr(Packet):
305 name = "L2CAP command header"
306 fields_desc = [
307 ByteEnumField("code", 8, {1: "rej",
308 2: "conn_req",
309 3: "conn_resp",
310 4: "conf_req",
311 5: "conf_resp",
312 6: "disconn_req",
313 7: "disconn_resp",
314 8: "echo_req",
315 9: "echo_resp",
316 10: "info_req",
317 11: "info_resp",
318 12: "create_channel_req",
319 13: "create_channel_resp",
320 14: "move_channel_req",
321 15: "move_channel_resp",
322 16: "move_channel_confirm_req",
323 17: "move_channel_confirm_resp",
324 18: "conn_param_update_req",
325 19: "conn_param_update_resp",
326 20: "LE_credit_based_conn_req",
327 21: "LE_credit_based_conn_resp",
328 22: "flow_control_credit_ind",
329 23: "credit_based_conn_req",
330 24: "credit_based_conn_resp",
331 25: "credit_based_reconf_req",
332 26: "credit_based_reconf_resp"}),
333 ByteField("id", 0),
334 LEShortField("len", None)]
335
336 def post_build(self, p, pay):
337 p += pay
338 if self.len is None:
339 p = p[:2] + struct.pack("<H", len(pay)) + p[4:]
340 return p
341
342 def answers(self, other):
343 if other.id == self.id:
344 if self.code == 1:
345 return 1
346 if other.code in [2, 4, 6, 8, 10, 18] and self.code == other.code + 1: # noqa: E501
347 if other.code == 8:
348 return 1
349 return self.payload.answers(other.payload)
350 return 0
351
352
353class L2CAP_ConnReq(Packet):
354 name = "L2CAP Conn Req"
355 fields_desc = [LEShortEnumField("psm", 0, {1: "SDP",
356 3: "RFCOMM",
357 5: "TCS-BIN",
358 7: "TCS-BIN-CORDLESS",
359 15: "BNEP",
360 17: "HID-Control",
361 19: "HID-Interrupt",
362 21: "UPnP",
363 23: "AVCTP-Control",
364 25: "AVDTP",
365 27: "AVCTP-Browsing",
366 29: "UDI_C-Plane",
367 31: "ATT",
368 33: "3DSP",
369 35: "IPSP",
370 37: "OTS"}),
371 LEShortField("scid", 0),
372 ]
373
374
375class L2CAP_ConnResp(Packet):
376 name = "L2CAP Conn Resp"
377 fields_desc = [LEShortField("dcid", 0),
378 LEShortField("scid", 0),
379 LEShortEnumField("result", 0, ["success", "pend", "cr_bad_psm", "cr_sec_block", "cr_no_mem", "reserved", "cr_inval_scid", "cr_scid_in_use"]), # noqa: E501
380 LEShortEnumField("status", 0, ["no_info", "authen_pend", "author_pend", "reserved"]), # noqa: E501
381 ]
382
383 def answers(self, other):
384 # dcid Resp == scid Req. Therefore compare SCIDs
385 return isinstance(other, L2CAP_ConnReq) and self.scid == other.scid
386
387
388class L2CAP_CmdRej(Packet):
389 name = "L2CAP Command Rej"
390 fields_desc = [LEShortField("reason", 0),
391 ]
392
393
394class L2CAP_ConfReq(Packet):
395 name = "L2CAP Conf Req"
396 fields_desc = [LEShortField("dcid", 0),
397 LEShortField("flags", 0),
398 ]
399
400
401class L2CAP_ConfResp(Packet):
402 name = "L2CAP Conf Resp"
403 fields_desc = [LEShortField("scid", 0),
404 LEShortField("flags", 0),
405 LEShortEnumField("result", 0, ["success", "unaccept", "reject", "unknown"]), # noqa: E501
406 ]
407
408 def answers(self, other):
409 # Req and Resp contain either the SCID or the DCID.
410 return isinstance(other, L2CAP_ConfReq)
411
412
413class L2CAP_DisconnReq(Packet):
414 name = "L2CAP Disconn Req"
415 fields_desc = [LEShortField("dcid", 0),
416 LEShortField("scid", 0), ]
417
418
419class L2CAP_DisconnResp(Packet):
420 name = "L2CAP Disconn Resp"
421 fields_desc = [LEShortField("dcid", 0),
422 LEShortField("scid", 0), ]
423
424 def answers(self, other):
425 return self.scid == other.scid
426
427
428class L2CAP_EchoReq(Packet):
429 name = "L2CAP Echo Req"
430 fields_desc = [StrField("data", ""), ]
431
432
433class L2CAP_EchoResp(Packet):
434 name = "L2CAP Echo Resp"
435 fields_desc = [StrField("data", ""), ]
436
437
438class L2CAP_InfoReq(Packet):
439 name = "L2CAP Info Req"
440 fields_desc = [LEShortEnumField("type", 0, {1: "CL_MTU", 2: "FEAT_MASK"}),
441 StrField("data", "")
442 ]
443
444
445class L2CAP_InfoResp(Packet):
446 name = "L2CAP Info Resp"
447 fields_desc = [LEShortField("type", 0),
448 LEShortEnumField("result", 0, ["success", "not_supp"]),
449 StrField("data", ""), ]
450
451 def answers(self, other):
452 return self.type == other.type
453
454
455class L2CAP_Create_Channel_Request(Packet):
456 name = "L2CAP Create Channel Request"
457 fields_desc = [LEShortEnumField("psm", 0, {1: "SDP",
458 3: "RFCOMM",
459 5: "TCS-BIN",
460 7: "TCS-BIN-CORDLESS",
461 15: "BNEP",
462 17: "HID-Control",
463 19: "HID-Interrupt",
464 21: "UPnP",
465 23: "AVCTP-Control",
466 25: "AVDTP",
467 27: "AVCTP-Browsing",
468 29: "UDI_C-Plane",
469 31: "ATT",
470 33: "3DSP",
471 35: "IPSP",
472 37: "OTS"}),
473 LEShortField("scid", 0),
474 ByteField("controller_id", 0), ]
475
476
477class L2CAP_Create_Channel_Response(Packet):
478 name = "L2CAP Create Channel Response"
479 fields_desc = [LEShortField("dcid", 0),
480 LEShortField("scid", 0),
481 LEShortEnumField("result", 0, {
482 0: "Connection successful",
483 1: "Connection pending",
484 2: "Connection refused - PSM not supported",
485 3: "Connection refused - security block",
486 4: "Connection refused - no resources available",
487 5: "Connection refused - cont_ID not supported",
488 6: "Connection refused - invalid scid",
489 7: "Connection refused - scid already allocated"}),
490 LEShortEnumField("status", 0, {
491 0: "No further information available",
492 1: "Authentication pending",
493 2: "Authorization pending"}), ]
494
495
496class L2CAP_Move_Channel_Request(Packet):
497 name = "L2CAP Move Channel Request"
498 fields_desc = [LEShortField("icid", 0),
499 ByteField("dest_controller_id", 0), ]
500
501
502class L2CAP_Move_Channel_Response(Packet):
503 name = "L2CAP Move Channel Response"
504 fields_desc = [LEShortField("icid", 0),
505 LEShortEnumField("result", 0, {
506 0: "Move success",
507 1: "Move pending",
508 2: "Move refused - Cont_ID not supported",
509 3: "Move refused - Cont_ID is same as old one",
510 4: "Move refused - Configuration not supported",
511 5: "Move refused - Move channel collision",
512 6: "Move refused - Not allowed to be moved"}), ]
513
514
515class L2CAP_Move_Channel_Confirmation_Request(Packet):
516 name = "L2CAP Move Channel Confirmation Request"
517 fields_desc = [LEShortField("icid", 0),
518 LEShortEnumField("result", 0, {0: "Move success",
519 1: "Move failure"}), ]
520
521
522class L2CAP_Move_Channel_Confirmation_Response(Packet):
523 name = "L2CAP Move Channel Confirmation Response"
524 fields_desc = [LEShortField("icid", 0), ]
525
526
527class L2CAP_Connection_Parameter_Update_Request(Packet):
528 name = "L2CAP Connection Parameter Update Request"
529 fields_desc = [LEShortField("min_interval", 0),
530 LEShortField("max_interval", 0),
531 LEShortField("slave_latency", 0),
532 LEShortField("timeout_mult", 0), ]
533
534
535class L2CAP_Connection_Parameter_Update_Response(Packet):
536 name = "L2CAP Connection Parameter Update Response"
537 fields_desc = [LEShortField("move_result", 0), ]
538
539
540class L2CAP_LE_Credit_Based_Connection_Request(Packet):
541 name = "L2CAP LE Credit Based Connection Request"
542 fields_desc = [LEShortField("spsm", 0),
543 LEShortField("scid", 0),
544 LEShortField("mtu", 0),
545 LEShortField("mps", 0),
546 LEShortField("initial_credits", 0), ]
547
548
549class L2CAP_LE_Credit_Based_Connection_Response(Packet):
550 name = "L2CAP LE Credit Based Connection Response"
551 fields_desc = [LEShortField("dcid", 0),
552 LEShortField("mtu", 0),
553 LEShortField("mps", 0),
554 LEShortField("initial_credits", 0),
555 LEShortEnumField("result", 0, {
556 0: "Connection successful",
557 2: "Connection refused - SPSM not supported",
558 4: "Connection refused - no resources available",
559 5: "Connection refused - authentication error",
560 6: "Connection refused - authorization error",
561 7: "Connection refused - encrypt_key size error",
562 8: "Connection refused - insufficient encryption",
563 9: "Connection refused - invalid scid",
564 10: "Connection refused - scid already allocated",
565 11: "Connection refused - parameters error"}), ]
566
567
568class L2CAP_Flow_Control_Credit_Ind(Packet):
569 name = "L2CAP Flow Control Credit Ind"
570 fields_desc = [LEShortField("cid", 0),
571 LEShortField("credits", 0), ]
572
573
574class L2CAP_Credit_Based_Connection_Request(Packet):
575 name = "L2CAP Credit Based Connection Request"
576 fields_desc = [LEShortField("spsm", 0),
577 LEShortField("mtu", 0),
578 LEShortField("mps", 0),
579 LEShortField("initial_credits", 0),
580 LEShortField("scid", 0), ]
581
582
583class L2CAP_Credit_Based_Connection_Response(Packet):
584 name = "L2CAP Credit Based Connection Response"
585 fields_desc = [LEShortField("mtu", 0),
586 LEShortField("mps", 0),
587 LEShortField("initial_credits", 0),
588 LEShortEnumField("result", 0, {
589 0: "All connection successful",
590 2: "All connection refused - SPSM not supported",
591 4: "Some connections refused - resources error",
592 5: "All connection refused - authentication error",
593 6: "All connection refused - authorization error",
594 7: "All connection refused - encrypt_key size error",
595 8: "All connection refused - encryption error",
596 9: "Some connection refused - invalid scid",
597 10: "Some connection refused - scid already allocated",
598 11: "All Connection refused - unacceptable parameters",
599 12: "All connections refused - invalid parameters"}),
600 LEShortField("dcid", 0), ]
601
602
603class L2CAP_Credit_Based_Reconfigure_Request(Packet):
604 name = "L2CAP Credit Based Reconfigure Request"
605 fields_desc = [LEShortField("mtu", 0),
606 LEShortField("mps", 0),
607 LEShortField("dcid", 0), ]
608
609
610class L2CAP_Credit_Based_Reconfigure_Response(Packet):
611 name = "L2CAP Credit Based Reconfigure Response"
612 fields_desc = [LEShortEnumField("result", 0, {
613 0: "Reconfig successful",
614 1: "Reconfig failed - MTU size reduction not allowed",
615 2: "Reconfig failed - MPS size reduction not allowed",
616 3: "Reconfig failed - one or more dcids invalid",
617 4: "Reconfig failed - unacceptable parameters"}), ]
618
619
620class ATT_Hdr(Packet):
621 name = "ATT header"
622 fields_desc = [XByteField("opcode", None), ]
623
624
625class ATT_Handle(Packet):
626 name = "ATT Short Handle"
627 fields_desc = [XLEShortField("handle", 0),
628 XLEShortField("value", 0)]
629
630 def extract_padding(self, s):
631 return b'', s
632
633
634class ATT_Handle_UUID128(Packet):
635 name = "ATT Handle (UUID 128)"
636 fields_desc = [XLEShortField("handle", 0),
637 UUIDField("value", None, uuid_fmt=UUIDField.FORMAT_REV)]
638
639 def extract_padding(self, s):
640 return b'', s
641
642
643class ATT_Error_Response(Packet):
644 name = "Error Response"
645 fields_desc = [XByteField("request", 0),
646 LEShortField("handle", 0),
647 ByteEnumField("ecode", 0, _att_error_codes), ]
648
649
650class ATT_Exchange_MTU_Request(Packet):
651 name = "Exchange MTU Request"
652 fields_desc = [LEShortField("mtu", 0), ]
653
654
655class ATT_Exchange_MTU_Response(Packet):
656 name = "Exchange MTU Response"
657 fields_desc = [LEShortField("mtu", 0), ]
658
659
660class ATT_Find_Information_Request(Packet):
661 name = "Find Information Request"
662 fields_desc = [XLEShortField("start", 0x0000),
663 XLEShortField("end", 0xffff), ]
664
665
666class ATT_Find_Information_Response(Packet):
667 name = "Find Information Response"
668 fields_desc = [
669 XByteField("format", 1),
670 MultipleTypeField(
671 [
672 (PacketListField("handles", [], ATT_Handle),
673 lambda pkt: pkt.format == 1),
674 (PacketListField("handles", [], ATT_Handle_UUID128),
675 lambda pkt: pkt.format == 2),
676 ],
677 StrFixedLenField("handles", "", length=0)
678 )
679 ]
680
681
682class ATT_Find_By_Type_Value_Request(Packet):
683 name = "Find By Type Value Request"
684 fields_desc = [XLEShortField("start", 0x0001),
685 XLEShortField("end", 0xffff),
686 XLEShortField("uuid", None),
687 StrField("data", ""), ]
688
689
690class ATT_Find_By_Type_Value_Response(Packet):
691 name = "Find By Type Value Response"
692 fields_desc = [PacketListField("handles", [], ATT_Handle)]
693
694
695class ATT_Read_By_Type_Request_128bit(Packet):
696 name = "Read By Type Request"
697 fields_desc = [XLEShortField("start", 0x0001),
698 XLEShortField("end", 0xffff),
699 XLELongField("uuid1", None),
700 XLELongField("uuid2", None)]
701
702 @classmethod
703 def dispatch_hook(cls, _pkt=None, *args, **kargs):
704 if _pkt and len(_pkt) == 6:
705 return ATT_Read_By_Type_Request
706 return ATT_Read_By_Type_Request_128bit
707
708
709class ATT_Read_By_Type_Request(Packet):
710 name = "Read By Type Request"
711 fields_desc = [XLEShortField("start", 0x0001),
712 XLEShortField("end", 0xffff),
713 XLEShortField("uuid", None)]
714
715
716class ATT_Handle_Variable(Packet):
717 __slots__ = ["val_length"]
718 fields_desc = [XLEShortField("handle", 0),
719 XStrLenField(
720 "value", 0,
721 length_from=lambda pkt: pkt.val_length)]
722
723 def __init__(self, _pkt=b"", val_length=2, **kwargs):
724 self.val_length = val_length
725 Packet.__init__(self, _pkt, **kwargs)
726
727 def extract_padding(self, s):
728 return b"", s
729
730
731class ATT_Read_By_Type_Response(Packet):
732 name = "Read By Type Response"
733 fields_desc = [ByteField("len", 4),
734 PacketListField(
735 "handles", [],
736 next_cls_cb=lambda pkt, *args: (
737 pkt._next_cls_cb(pkt, *args)
738 ))]
739
740 @classmethod
741 def _next_cls_cb(cls, pkt, lst, p, remain):
742 if len(remain) >= pkt.len:
743 return functools.partial(
744 ATT_Handle_Variable,
745 val_length=pkt.len - 2
746 )
747 return None
748
749
750class ATT_Read_Request(Packet):
751 name = "Read Request"
752 fields_desc = [XLEShortField("gatt_handle", 0), ]
753
754
755class ATT_Read_Response(Packet):
756 name = "Read Response"
757 fields_desc = [StrField("value", "")]
758
759
760class ATT_Read_Multiple_Request(Packet):
761 name = "Read Multiple Request"
762 fields_desc = [FieldListField("handles", [], XLEShortField("", 0))]
763
764
765class ATT_Read_Multiple_Response(Packet):
766 name = "Read Multiple Response"
767 fields_desc = [StrField("values", "")]
768
769
770class ATT_Read_By_Group_Type_Request(Packet):
771 name = "Read By Group Type Request"
772 fields_desc = [XLEShortField("start", 0),
773 XLEShortField("end", 0xffff),
774 XLEShortField("uuid", 0), ]
775
776
777class ATT_Read_By_Group_Type_Response(Packet):
778 name = "Read By Group Type Response"
779 fields_desc = [XByteField("length", 0),
780 StrField("data", ""), ]
781
782
783class ATT_Write_Request(Packet):
784 name = "Write Request"
785 fields_desc = [XLEShortField("gatt_handle", 0),
786 StrField("data", ""), ]
787
788
789class ATT_Write_Command(Packet):
790 name = "Write Request"
791 fields_desc = [XLEShortField("gatt_handle", 0),
792 StrField("data", ""), ]
793
794
795class ATT_Write_Response(Packet):
796 name = "Write Response"
797
798
799class ATT_Prepare_Write_Request(Packet):
800 name = "Prepare Write Request"
801 fields_desc = [
802 XLEShortField("gatt_handle", 0),
803 LEShortField("offset", 0),
804 StrField("data", "")
805 ]
806
807
808class ATT_Prepare_Write_Response(ATT_Prepare_Write_Request):
809 name = "Prepare Write Response"
810
811
812class ATT_Handle_Value_Notification(Packet):
813 name = "Handle Value Notification"
814 fields_desc = [XLEShortField("gatt_handle", 0),
815 StrField("value", ""), ]
816
817
818class ATT_Execute_Write_Request(Packet):
819 name = "Execute Write Request"
820 fields_desc = [
821 ByteEnumField("flags", 1, {
822 0: "Cancel all prepared writes",
823 1: "Immediately write all pending prepared values",
824 }),
825 ]
826
827
828class ATT_Execute_Write_Response(Packet):
829 name = "Execute Write Response"
830
831
832class ATT_Read_Blob_Request(Packet):
833 name = "Read Blob Request"
834 fields_desc = [
835 XLEShortField("gatt_handle", 0),
836 LEShortField("offset", 0)
837 ]
838
839
840class ATT_Read_Blob_Response(Packet):
841 name = "Read Blob Response"
842 fields_desc = [
843 StrField("value", "")
844 ]
845
846
847class ATT_Handle_Value_Indication(Packet):
848 name = "Handle Value Indication"
849 fields_desc = [
850 XLEShortField("gatt_handle", 0),
851 StrField("value", ""),
852 ]
853
854
855class SM_Hdr(Packet):
856 name = "SM header"
857 fields_desc = [ByteField("sm_command", None)]
858
859
860class SM_Pairing_Request(Packet):
861 name = "Pairing Request"
862 fields_desc = [ByteEnumField("iocap", 3, {0: "DisplayOnly", 1: "DisplayYesNo", 2: "KeyboardOnly", 3: "NoInputNoOutput", 4: "KeyboardDisplay"}), # noqa: E501
863 ByteEnumField("oob", 0, {0: "Not Present", 1: "Present (from remote device)"}), # noqa: E501
864 BitField("authentication", 0, 8),
865 ByteField("max_key_size", 16),
866 ByteField("initiator_key_distribution", 0),
867 ByteField("responder_key_distribution", 0), ]
868
869
870class SM_Pairing_Response(Packet):
871 name = "Pairing Response"
872 fields_desc = [ByteEnumField("iocap", 3, {0: "DisplayOnly", 1: "DisplayYesNo", 2: "KeyboardOnly", 3: "NoInputNoOutput", 4: "KeyboardDisplay"}), # noqa: E501
873 ByteEnumField("oob", 0, {0: "Not Present", 1: "Present (from remote device)"}), # noqa: E501
874 BitField("authentication", 0, 8),
875 ByteField("max_key_size", 16),
876 ByteField("initiator_key_distribution", 0),
877 ByteField("responder_key_distribution", 0), ]
878
879
880class SM_Confirm(Packet):
881 name = "Pairing Confirm"
882 fields_desc = [StrFixedLenField("confirm", b'\x00' * 16, 16)]
883
884
885class SM_Random(Packet):
886 name = "Pairing Random"
887 fields_desc = [StrFixedLenField("random", b'\x00' * 16, 16)]
888
889
890class SM_Failed(Packet):
891 name = "Pairing Failed"
892 fields_desc = [XByteField("reason", 0)]
893
894
895class SM_Encryption_Information(Packet):
896 name = "Encryption Information"
897 fields_desc = [StrFixedLenField("ltk", b"\x00" * 16, 16), ]
898
899
900class SM_Master_Identification(Packet):
901 name = "Master Identification"
902 fields_desc = [XLEShortField("ediv", 0),
903 StrFixedLenField("rand", b'\x00' * 8, 8), ]
904
905
906class SM_Identity_Information(Packet):
907 name = "Identity Information"
908 fields_desc = [StrFixedLenField("irk", b'\x00' * 16, 16), ]
909
910
911class SM_Identity_Address_Information(Packet):
912 name = "Identity Address Information"
913 fields_desc = [ByteEnumField("atype", 0, {0: "public"}),
914 LEMACField("address", None), ]
915
916
917class SM_Signing_Information(Packet):
918 name = "Signing Information"
919 fields_desc = [StrFixedLenField("csrk", b'\x00' * 16, 16), ]
920
921
922class SM_Security_Request(Packet):
923 name = "Security Request"
924 fields_desc = [BitField("auth_req", 0, 8), ]
925
926
927class SM_Public_Key(Packet):
928 name = "Public Key"
929 fields_desc = [StrFixedLenField("key_x", b'\x00' * 32, 32),
930 StrFixedLenField("key_y", b'\x00' * 32, 32), ]
931
932
933class SM_DHKey_Check(Packet):
934 name = "DHKey Check"
935 fields_desc = [StrFixedLenField("dhkey_check", b'\x00' * 16, 16), ]
936
937
938class EIR_Hdr(Packet):
939 name = "EIR Header"
940 fields_desc = [
941 LenField("len", None, fmt="B", adjust=lambda x: x + 1), # Add bytes mark # noqa: E501
942 # https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile
943 ByteEnumField("type", 0, {
944 0x01: "flags",
945 0x02: "incomplete_list_16_bit_svc_uuids",
946 0x03: "complete_list_16_bit_svc_uuids",
947 0x04: "incomplete_list_32_bit_svc_uuids",
948 0x05: "complete_list_32_bit_svc_uuids",
949 0x06: "incomplete_list_128_bit_svc_uuids",
950 0x07: "complete_list_128_bit_svc_uuids",
951 0x08: "shortened_local_name",
952 0x09: "complete_local_name",
953 0x0a: "tx_power_level",
954 0x0d: "class_of_device",
955 0x0e: "simple_pairing_hash",
956 0x0f: "simple_pairing_rand",
957
958 0x10: "sec_mgr_tk",
959 0x11: "sec_mgr_oob_flags",
960 0x12: "slave_conn_intvl_range",
961 0x14: "list_16_bit_svc_sollication_uuids",
962 0x15: "list_128_bit_svc_sollication_uuids",
963 0x16: "svc_data_16_bit_uuid",
964 0x17: "pub_target_addr",
965 0x18: "rand_target_addr",
966 0x19: "appearance",
967 0x1a: "adv_intvl",
968 0x1b: "le_addr",
969 0x1c: "le_role",
970 0x1d: "simple_pairing_hash_256",
971 0x1e: "simple_pairing_rand_256",
972 0x1f: "list_32_bit_svc_sollication_uuids",
973
974 0x20: "svc_data_32_bit_uuid",
975 0x21: "svc_data_128_bit_uuid",
976 0x22: "sec_conn_confirm",
977 0x23: "sec_conn_rand",
978 0x24: "uri",
979 0x25: "indoor_positioning",
980 0x26: "transport_discovery",
981 0x27: "le_supported_features",
982 0x28: "channel_map_update",
983 0x29: "mesh_pb_adv",
984 0x2a: "mesh_message",
985 0x2b: "mesh_beacon",
986
987 0x3d: "3d_information",
988
989 0xff: "mfg_specific_data",
990 }),
991 ]
992
993 def mysummary(self):
994 return self.sprintf("EIR %type%")
995
996 def guess_payload_class(self, payload):
997 if self.len == 0:
998 # For Extended_Inquiry_Response, stop when len=0
999 return conf.padding_layer
1000 return super(EIR_Hdr, self).guess_payload_class(payload)
1001
1002
1003class EIR_Element(Packet):
1004 name = "EIR Element"
1005
1006 def extract_padding(self, s):
1007 # Needed to end each EIR_Element packet and make PacketListField work.
1008 return b'', s
1009
1010 @staticmethod
1011 def length_from(pkt):
1012 if not pkt.underlayer:
1013 warning("Missing an upper-layer")
1014 return 0
1015 # 'type' byte is included in the length, so subtract 1:
1016 return pkt.underlayer.len - 1
1017
1018
1019class EIR_Raw(EIR_Element):
1020 name = "EIR Raw"
1021 fields_desc = [
1022 StrLenField("data", "", length_from=EIR_Element.length_from)
1023 ]
1024
1025
1026class EIR_Flags(EIR_Element):
1027 name = "Flags"
1028 fields_desc = [
1029 FlagsField("flags", 0x2, 8,
1030 ["limited_disc_mode", "general_disc_mode",
1031 "br_edr_not_supported", "simul_le_br_edr_ctrl",
1032 "simul_le_br_edr_host"] + 3 * ["reserved"])
1033 ]
1034
1035
1036class EIR_CompleteList16BitServiceUUIDs(EIR_Element):
1037 name = "Complete list of 16-bit service UUIDs"
1038 fields_desc = [
1039 # https://www.bluetooth.com/specifications/assigned-numbers/16-bit-uuids-for-members
1040 FieldListField("svc_uuids", None, XLEShortField("uuid", 0),
1041 length_from=EIR_Element.length_from)
1042 ]
1043
1044
1045class EIR_IncompleteList16BitServiceUUIDs(EIR_CompleteList16BitServiceUUIDs):
1046 name = "Incomplete list of 16-bit service UUIDs"
1047
1048
1049class EIR_CompleteList32BitServiceUUIDs(EIR_Element):
1050 name = 'Complete list of 32-bit service UUIDs'
1051 fields_desc = [
1052 # https://www.bluetooth.com/specifications/assigned-numbers
1053 FieldListField('svc_uuids', None, XLEIntField('uuid', 0),
1054 length_from=EIR_Element.length_from)
1055 ]
1056
1057
1058class EIR_IncompleteList32BitServiceUUIDs(EIR_CompleteList32BitServiceUUIDs):
1059 name = 'Incomplete list of 32-bit service UUIDs'
1060
1061
1062class EIR_CompleteList128BitServiceUUIDs(EIR_Element):
1063 name = "Complete list of 128-bit service UUIDs"
1064 fields_desc = [
1065 FieldListField("svc_uuids", None,
1066 UUIDField("uuid", None, uuid_fmt=UUIDField.FORMAT_REV),
1067 length_from=EIR_Element.length_from)
1068 ]
1069
1070
1071class EIR_IncompleteList128BitServiceUUIDs(EIR_CompleteList128BitServiceUUIDs):
1072 name = "Incomplete list of 128-bit service UUIDs"
1073
1074
1075class EIR_CompleteLocalName(EIR_Element):
1076 name = "Complete Local Name"
1077 fields_desc = [
1078 StrLenField("local_name", "", length_from=EIR_Element.length_from)
1079 ]
1080
1081
1082class EIR_ShortenedLocalName(EIR_CompleteLocalName):
1083 name = "Shortened Local Name"
1084
1085
1086class EIR_TX_Power_Level(EIR_Element):
1087 name = "TX Power Level"
1088 fields_desc = [SignedByteField("level", 0)]
1089
1090
1091class EIR_ClassOfDevice(EIR_Element):
1092 name = 'Class of device'
1093 fields_desc = [
1094 FlagsField('major_service_classes', 0, 11, [
1095 'limited_discoverable_mode',
1096 'le_audio',
1097 'reserved',
1098 'positioning',
1099 'networking',
1100 'rendering',
1101 'capturing',
1102 'object_transfer',
1103 'audio',
1104 'telephony',
1105 'information'
1106 ], tot_size=-3),
1107 BitEnumField('major_device_class', 0, 5, {
1108 0x00: 'miscellaneous',
1109 0x01: 'computer',
1110 0x02: 'phone',
1111 0x03: 'lan',
1112 0x04: 'audio_video',
1113 0x05: 'peripheral',
1114 0x06: 'imaging',
1115 0x07: 'wearable',
1116 0x08: 'toy',
1117 0x09: 'health',
1118 0x1f: 'uncategorized'
1119 }),
1120 BitField('minor_device_class', 0, 6),
1121 BitField('fixed', 0, 2, end_tot_size=-3)
1122 ]
1123
1124
1125class EIR_SecureSimplePairingHashC192(EIR_Element):
1126 name = 'Secure Simple Pairing Hash C-192'
1127 fields_desc = [NBytesField('hash', 0, 16)]
1128
1129
1130class EIR_SecureSimplePairingRandomizerR192(EIR_Element):
1131 name = 'Secure Simple Pairing Randomizer R-192'
1132 fields_desc = [NBytesField('randomizer', 0, 16)]
1133
1134
1135class EIR_SecurityManagerOOBFlags(EIR_Element):
1136 name = 'Security Manager Out of Band Flags'
1137 fields_desc = [
1138 BitField('oob_flags_field', 0, 1),
1139 BitField('le_supported', 0, 1),
1140 BitField('previously_used', 0, 1),
1141 BitField('address_type', 0, 1),
1142 BitField('reserved', 0, 4)
1143 ]
1144
1145
1146class EIR_PeripheralConnectionIntervalRange(EIR_Element):
1147 name = 'Peripheral Connection Interval Range'
1148 fields_desc = [
1149 LEShortField('conn_interval_min', 0xFFFF),
1150 LEShortField('conn_interval_max', 0xFFFF)
1151 ]
1152
1153
1154class EIR_Manufacturer_Specific_Data(EIR_Element):
1155 name = "EIR Manufacturer Specific Data"
1156 fields_desc = [
1157 # https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers
1158 XLEShortField("company_id", None),
1159 ]
1160
1161 registered_magic_payloads = {}
1162
1163 @classmethod
1164 def register_magic_payload(cls, payload_cls, magic_check=None):
1165 """
1166 Registers a payload type that uses magic data.
1167
1168 Traditional payloads require registration of a Bluetooth Company ID
1169 (requires company membership of the Bluetooth SIG), or a Bluetooth
1170 Short UUID (requires a once-off payment).
1171
1172 There are alternatives which don't require registration (such as
1173 128-bit UUIDs), but the biggest consumer of energy in a beacon is the
1174 radio -- so the energy consumption of a beacon is proportional to the
1175 number of bytes in a beacon frame.
1176
1177 Some beacon formats side-step this issue by using the Company ID of
1178 their beacon hardware manufacturer, and adding a "magic data sequence"
1179 at the start of the Manufacturer Specific Data field.
1180
1181 Examples of this are AltBeacon and GeoBeacon.
1182
1183 For an example of this method in use, see ``scapy.contrib.altbeacon``.
1184
1185 :param Type[scapy.packet.Packet] payload_cls:
1186 A reference to a Packet subclass to register as a payload.
1187 :param Callable[[bytes], bool] magic_check:
1188 (optional) callable to use to if a payload should be associated
1189 with this type. If not supplied, ``payload_cls.magic_check`` is
1190 used instead.
1191 :raises TypeError: If ``magic_check`` is not specified,
1192 and ``payload_cls.magic_check`` is not implemented.
1193 """
1194 if magic_check is None:
1195 if hasattr(payload_cls, "magic_check"):
1196 magic_check = payload_cls.magic_check
1197 else:
1198 raise TypeError("magic_check not specified, and {} has no "
1199 "attribute magic_check".format(payload_cls))
1200
1201 cls.registered_magic_payloads[payload_cls] = magic_check
1202
1203 def default_payload_class(self, payload):
1204 for cls, check in (
1205 EIR_Manufacturer_Specific_Data.registered_magic_payloads.items()
1206 ):
1207 if check(payload):
1208 return cls
1209
1210 return Packet.default_payload_class(self, payload)
1211
1212 def extract_padding(self, s):
1213 # Needed to end each EIR_Element packet and make PacketListField work.
1214 plen = EIR_Element.length_from(self) - 2
1215 return s[:plen], s[plen:]
1216
1217
1218class EIR_Device_ID(EIR_Element):
1219 name = "Device ID"
1220 fields_desc = [
1221 XLEShortField("vendor_id_source", 0),
1222 XLEShortField("vendor_id", 0),
1223 XLEShortField("product_id", 0),
1224 XLEShortField("version", 0),
1225 ]
1226
1227
1228class EIR_ServiceSolicitation16BitUUID(EIR_Element):
1229 name = "EIR Service Solicitation - 16-bit UUID"
1230 fields_desc = [
1231 XLEShortField("svc_uuid", None)
1232 ]
1233
1234 def extract_padding(self, s):
1235 # Needed to end each EIR_Element packet and make PacketListField work.
1236 plen = EIR_Element.length_from(self) - 2
1237 return s[:plen], s[plen:]
1238
1239
1240class EIR_ServiceSolicitation128BitUUID(EIR_Element):
1241 name = "EIR Service Solicitation - 128-bit UUID"
1242 fields_desc = [
1243 UUIDField('svc_uuid', None, uuid_fmt=UUIDField.FORMAT_REV)
1244 ]
1245
1246 def extract_padding(self, s):
1247 # Needed to end each EIR_Element packet and make PacketListField work.
1248 plen = EIR_Element.length_from(self) - 2
1249 return s[:plen], s[plen:]
1250
1251
1252class EIR_ServiceData16BitUUID(EIR_Element):
1253 name = "EIR Service Data - 16-bit UUID"
1254 fields_desc = [
1255 # https://www.bluetooth.com/specifications/assigned-numbers/16-bit-uuids-for-members
1256 XLEShortField("svc_uuid", None),
1257 ]
1258
1259 def extract_padding(self, s):
1260 # Needed to end each EIR_Element packet and make PacketListField work.
1261 plen = EIR_Element.length_from(self) - 2
1262 return s[:plen], s[plen:]
1263
1264
1265class EIR_PublicTargetAddress(EIR_Element):
1266 name = "Public Target Address"
1267 fields_desc = [
1268 LEMACField('bd_addr', None)
1269 ]
1270
1271
1272class EIR_AdvertisingInterval(EIR_Element):
1273 name = "Advertising Interval"
1274 fields_desc = [
1275 MultipleTypeField(
1276 [
1277 (ByteField("advertising_interval", 0),
1278 lambda p: p.underlayer.len - 1 == 1),
1279 (LEShortField("advertising_interval", 0),
1280 lambda p: p.underlayer.len - 1 == 2),
1281 (LEThreeBytesField("advertising_interval", 0),
1282 lambda p: p.underlayer.len - 1 == 3),
1283 (LEIntField("advertising_interval", 0),
1284 lambda p: p.underlayer.len - 1 == 4),
1285 ],
1286 LEShortField("advertising_interval", 0)
1287 )
1288 ]
1289
1290
1291class EIR_LEBluetoothDeviceAddress(EIR_Element):
1292 name = "LE Bluetooth Device Address"
1293 fields_desc = [
1294 XBitField('reserved', 0, 7, tot_size=-1),
1295 BitEnumField('addr_type', 0, 1, end_tot_size=-1, enum={
1296 0x0: 'Public',
1297 0x1: 'Random'
1298 }),
1299 LEMACField('bd_addr', None)
1300 ]
1301
1302
1303class EIR_Appearance(EIR_Element):
1304 name = "EIR_Appearance"
1305 fields_desc = [
1306 BitEnumField('category', 0, 10, tot_size=-2, enum={
1307 0x000: 'Unknown',
1308 0x001: 'Phone',
1309 0x002: 'Computer',
1310 0x003: 'Watch',
1311 0x004: 'Clock',
1312 0x005: 'Display',
1313 0x006: 'Remote Control',
1314 0x007: 'Eyeglasses',
1315 0x008: 'Tag',
1316 0x009: 'Keyring',
1317 0x00A: 'Media Player',
1318 0x00B: 'Barcode Scanner',
1319 0x00C: 'Thermometer',
1320 0x00D: 'Heart Rate Sensor',
1321 0x00E: 'Blood Pressure',
1322 0x00F: 'Human Interface Device',
1323 0x010: 'Glucose Meter',
1324 0x011: 'Running Walking Sensor',
1325 0x012: 'Cycling',
1326 0x013: 'Control Device',
1327 0x014: 'Network Device',
1328 0x015: 'Sensor',
1329 0x016: 'Light Fixtures',
1330 0x017: 'Fan',
1331 0x018: 'HVAC',
1332 0x019: 'Air Conditioning',
1333 0x01A: 'Humidifier',
1334 0x01B: 'Heating',
1335 0x01C: 'Access Control',
1336 0x01D: 'Motorized Device',
1337 0x01E: 'Power Device',
1338 0x01F: 'Light Source',
1339 0x020: 'Window Covering',
1340 0x021: 'Audio Sink',
1341 0x022: 'Audio Source',
1342 0x023: 'Motorized Vehicle',
1343 0x024: 'Domestic Appliance',
1344 0x025: 'Wearable Audio Device',
1345 0x026: 'Aircraft',
1346 0x027: 'AV Equipment',
1347 0x028: 'Display Equipment',
1348 0x029: 'Hearing aid',
1349 0x02A: 'Gaming',
1350 0x02B: 'Signage',
1351 0x031: 'Pulse Oximeter',
1352 0x032: 'Weight Scale',
1353 0x033: 'Personal Mobility Device',
1354 0x034: 'Continuous Glucose Monitor',
1355 0x035: 'Insulin Pump',
1356 0x036: 'Medication Delivery',
1357 0x037: 'Spirometer',
1358 0x051: 'Outdoor Sports Activity'
1359 }),
1360 XBitField('subcategory', 0, 6, end_tot_size=-2)
1361 ]
1362
1363 @property
1364 def appearance(self):
1365 return (self.category << 6) + self.subcategory
1366
1367
1368class EIR_ServiceData32BitUUID(EIR_Element):
1369 name = 'EIR Service Data - 32-bit UUID'
1370 fields_desc = [
1371 XLEIntField('svc_uuid', 0),
1372 ]
1373
1374 def extract_padding(self, s):
1375 # Needed to end each EIR_Element packet and make PacketListField work.
1376 plen = EIR_Element.length_from(self) - 4
1377 return s[:plen], s[plen:]
1378
1379
1380class EIR_ServiceData128BitUUID(EIR_Element):
1381 name = 'EIR Service Data - 128-bit UUID'
1382 fields_desc = [
1383 UUIDField('svc_uuid', None, uuid_fmt=UUIDField.FORMAT_REV)
1384 ]
1385
1386 def extract_padding(self, s):
1387 # Needed to end each EIR_Element packet and make PacketListField work.
1388 plen = EIR_Element.length_from(self) - 16
1389 return s[:plen], s[plen:]
1390
1391
1392class EIR_URI(EIR_Element):
1393 name = 'EIR URI'
1394 fields_desc = [
1395 ByteEnumField('scheme', 0, {
1396 0x01: '',
1397 0x02: 'aaa:',
1398 0x03: 'aaas:',
1399 0x04: 'about:',
1400 0x05: 'acap:',
1401 0x06: 'acct:',
1402 0x07: 'cap:',
1403 0x08: 'cid:',
1404 0x09: 'coap:',
1405 0x0A: 'coaps:',
1406 0x0B: 'crid:',
1407 0x0C: 'data:',
1408 0x0D: 'dav:',
1409 0x0E: 'dict:',
1410 0x0F: 'dns:',
1411 0x10: 'file:',
1412 0x11: 'ftp:',
1413 0x12: 'geo:',
1414 0x13: 'go:',
1415 0x14: 'gopher:',
1416 0x15: 'h323:',
1417 0x16: 'http:',
1418 0x17: 'https:',
1419 0x18: 'iax:',
1420 0x19: 'icap:',
1421 0x1A: 'im:',
1422 0x1B: 'imap:',
1423 0x1C: 'info:',
1424 0x1D: 'ipp:',
1425 0x1E: 'ipps:',
1426 0x1F: 'iris:',
1427 0x20: 'iris.beep:',
1428 0x21: 'iris.xpc:',
1429 0x22: 'iris.xpcs:',
1430 0x23: 'iris.lwz:',
1431 0x24: 'jabber:',
1432 0x25: 'ldap:',
1433 0x26: 'mailto:',
1434 0x27: 'mid:',
1435 0x28: 'msrp:',
1436 0x29: 'msrps:',
1437 0x2A: 'mtqp:',
1438 0x2B: 'mupdate:',
1439 0x2C: 'news:',
1440 0x2D: 'nfs:',
1441 0x2E: 'ni:',
1442 0x2F: 'nih:',
1443 0x30: 'nntp:',
1444 0x31: 'opaquelocktoken:',
1445 0x32: 'pop:',
1446 0x33: 'pres:',
1447 0x34: 'reload:',
1448 0x35: 'rtsp:',
1449 0x36: 'rtsps:',
1450 0x37: 'rtspu:',
1451 0x38: 'service:',
1452 0x39: 'session:',
1453 0x3A: 'shttp:',
1454 0x3B: 'sieve:',
1455 0x3C: 'sip:',
1456 0x3D: 'sips:',
1457 0x3E: 'sms:',
1458 0x3F: 'snmp:',
1459 0x40: 'soap.beep:',
1460 0x41: 'soap.beeps:',
1461 0x42: 'stun:',
1462 0x43: 'stuns:',
1463 0x44: 'tag:',
1464 0x45: 'tel:',
1465 0x46: 'telnet:',
1466 0x47: 'tftp:',
1467 0x48: 'thismessage:',
1468 0x49: 'tn3270:',
1469 0x4A: 'tip:',
1470 0x4B: 'turn:',
1471 0x4C: 'turns:',
1472 0x4D: 'tv:',
1473 0x4E: 'urn:',
1474 0x4F: 'vemmi:',
1475 0x50: 'ws:',
1476 0x51: 'wss:',
1477 0x52: 'xcon:',
1478 0x53: 'xconuserid:',
1479 0x54: 'xmlrpc.beep:',
1480 0x55: 'xmlrpc.beeps:',
1481 0x56: 'xmpp:',
1482 0x57: 'z39.50r:',
1483 0x58: 'z39.50s:',
1484 0x59: 'acr:',
1485 0x5A: 'adiumxtra:',
1486 0x5B: 'afp:',
1487 0x5C: 'afs:',
1488 0x5D: 'aim:',
1489 0x5E: 'apt:',
1490 0x5F: 'attachment:',
1491 0x60: 'aw:',
1492 0x61: 'barion:',
1493 0x62: 'beshare:',
1494 0x63: 'bitcoin:',
1495 0x64: 'bolo:',
1496 0x65: 'callto:',
1497 0x66: 'chrome:',
1498 0x67: 'chromeextension:',
1499 0x68: 'comeventbriteattendee:',
1500 0x69: 'content:',
1501 0x6A: 'cvs:',
1502 0x6B: 'dlnaplaysingle:',
1503 0x6C: 'dlnaplaycontainer:',
1504 0x6D: 'dtn:',
1505 0x6E: 'dvb:',
1506 0x6F: 'ed2k:',
1507 0x70: 'facetime:',
1508 0x71: 'feed:',
1509 0x72: 'feedready:',
1510 0x73: 'finger:',
1511 0x74: 'fish:',
1512 0x75: 'gg:',
1513 0x76: 'git:',
1514 0x77: 'gizmoproject:',
1515 0x78: 'gtalk:',
1516 0x79: 'ham:',
1517 0x7A: 'hcp:',
1518 0x7B: 'icon:',
1519 0x7C: 'ipn:',
1520 0x7D: 'irc:',
1521 0x7E: 'irc6:',
1522 0x7F: 'ircs:',
1523 0x80: 'itms:',
1524 0x81: 'jar:',
1525 0x82: 'jms:',
1526 0x83: 'keyparc:',
1527 0x84: 'lastfm:',
1528 0x85: 'ldaps:',
1529 0x86: 'magnet:',
1530 0x87: 'maps:',
1531 0x88: 'market:',
1532 0x89: 'message:',
1533 0x8A: 'mms:',
1534 0x8B: 'mshelp:',
1535 0x8C: 'mssettingspower:',
1536 0x8D: 'msnim:',
1537 0x8E: 'mumble:',
1538 0x8F: 'mvn:',
1539 0x90: 'notes:',
1540 0x91: 'oid:',
1541 0x92: 'palm:',
1542 0x93: 'paparazzi:',
1543 0x94: 'pkcs11:',
1544 0x95: 'platform:',
1545 0x96: 'proxy:',
1546 0x97: 'psyc:',
1547 0x98: 'query:',
1548 0x99: 'res:',
1549 0x9A: 'resource:',
1550 0x9B: 'rmi:',
1551 0x9C: 'rsync:',
1552 0x9D: 'rtmfp:',
1553 0x9E: 'rtmp:',
1554 0x9F: 'secondlife:',
1555 0xA0: 'sftp:',
1556 0xA1: 'sgn:',
1557 0xA2: 'skype:',
1558 0xA3: 'smb:',
1559 0xA4: 'smtp:',
1560 0xA5: 'soldat:',
1561 0xA6: 'spotify:',
1562 0xA7: 'ssh:',
1563 0xA8: 'steam:',
1564 0xA9: 'submit:',
1565 0xAA: 'svn:',
1566 0xAB: 'teamspeak:',
1567 0xAC: 'teliaeid:',
1568 0xAD: 'things:',
1569 0xAE: 'udp:',
1570 0xAF: 'unreal:',
1571 0xB0: 'ut2004:',
1572 0xB1: 'ventrilo:',
1573 0xB2: 'viewsource:',
1574 0xB3: 'webcal:',
1575 0xB4: 'wtai:',
1576 0xB5: 'wyciwyg:',
1577 0xB6: 'xfire:',
1578 0xB7: 'xri:',
1579 0xB8: 'ymsgr:',
1580 0xB9: 'example:',
1581 0xBA: 'mssettingscloudstorage:'
1582 }),
1583 StrLenField('uri_hier_part', None, length_from=EIR_Element.length_from)
1584 ]
1585
1586 @property
1587 def uri(self):
1588 return EIR_URI.scheme.i2s[self.scheme] + self.uri_hier_part.decode('utf-8')
1589
1590
1591class HCI_Command_Hdr(Packet):
1592 name = "HCI Command header"
1593 fields_desc = [XBitField("ogf", 0, 6, tot_size=-2),
1594 XBitField("ocf", 0, 10, end_tot_size=-2),
1595 LenField("len", None, fmt="B"), ]
1596
1597 def answers(self, other):
1598 return False
1599
1600 @property
1601 def opcode(self):
1602 return (self.ogf << 10) + self.ocf
1603
1604 def post_build(self, p, pay):
1605 p += pay
1606 if self.len is None:
1607 p = p[:2] + struct.pack("B", len(pay)) + p[3:]
1608 return p
1609
1610
1611# BUETOOTH CORE SPECIFICATION 5.4 | Vol 3, Part C
1612# 8 EXTENDED INQUIRY RESPONSE
1613
1614class HCI_Extended_Inquiry_Response(Packet):
1615 fields_desc = [
1616 PadField(
1617 PacketListField(
1618 "eir_data", [],
1619 next_cls_cb=lambda *args: (
1620 (not args[2] or args[2].len != 0) and EIR_Hdr or conf.raw_layer
1621 )
1622 ),
1623 align=31, padwith=b"\0",
1624 ),
1625 ]
1626
1627
1628# BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E
1629# 7 HCI COMMANDS AND EVENTS
1630# 7.1 LINK CONTROL COMMANDS, the OGF is defined as 0x01
1631
1632class HCI_Cmd_Inquiry(Packet):
1633 """
1634 7.1.1 Inquiry command
1635 """
1636 name = "HCI_Inquiry"
1637 fields_desc = [XLE3BytesField("lap", 0x9E8B33),
1638 ByteField("inquiry_length", 0),
1639 ByteField("num_responses", 0)]
1640
1641
1642class HCI_Cmd_Inquiry_Cancel(Packet):
1643 """
1644 7.1.2 Inquiry Cancel command
1645 """
1646 name = "HCI_Inquiry_Cancel"
1647
1648
1649class HCI_Cmd_Periodic_Inquiry_Mode(Packet):
1650 """
1651 7.1.3 Periodic Inquiry Mode command
1652 """
1653 name = "HCI_Periodic_Inquiry_Mode"
1654 fields_desc = [LEShortField("max_period_length", 0x0003),
1655 LEShortField("min_period_length", 0x0002),
1656 XLE3BytesField("lap", 0x9E8B33),
1657 ByteField("inquiry_length", 0),
1658 ByteField("num_responses", 0)]
1659
1660
1661class HCI_Cmd_Exit_Peiodic_Inquiry_Mode(Packet):
1662 """
1663 7.1.4 Exit Periodic Inquiry Mode command
1664 """
1665 name = "HCI_Exit_Periodic_Inquiry_Mode"
1666
1667
1668class HCI_Cmd_Create_Connection(Packet):
1669 """
1670 7.1.5 Create Connection command
1671 """
1672 name = "HCI_Create_Connection"
1673 fields_desc = [LEMACField("bd_addr", None),
1674 LEShortField("packet_type", 0xcc18),
1675 ByteField("page_scan_repetition_mode", 0x02),
1676 ByteField("reserved", 0x0),
1677 LEShortField("clock_offset", 0x0),
1678 ByteField("allow_role_switch", 0x1), ]
1679
1680
1681class HCI_Cmd_Disconnect(Packet):
1682 """
1683 7.1.6 Disconnect command
1684 """
1685 name = "HCI_Disconnect"
1686 fields_desc = [XLEShortField("handle", 0),
1687 ByteField("reason", 0x13), ]
1688
1689
1690class HCI_Cmd_Create_Connection_Cancel(Packet):
1691 """
1692 7.1.7 Create Connection Cancel command
1693 """
1694 name = "HCI_Create_Connection_Cancel"
1695 fields_desc = [LEMACField("bd_addr", None), ]
1696
1697
1698class HCI_Cmd_Accept_Connection_Request(Packet):
1699 """
1700 7.1.8 Accept Connection Request command
1701 """
1702 name = "HCI_Accept_Connection_Request"
1703 fields_desc = [LEMACField("bd_addr", None),
1704 ByteField("role", 0x1), ]
1705
1706
1707class HCI_Cmd_Reject_Connection_Response(Packet):
1708 """
1709 7.1.9 Reject Connection Request command
1710 """
1711 name = "HCI_Reject_Connection_Response"
1712 fields_desc = [LEMACField("bd_addr", None),
1713 ByteField("reason", 0x1), ]
1714
1715
1716class HCI_Cmd_Link_Key_Request_Reply(Packet):
1717 """
1718 7.1.10 Link Key Request Reply command
1719 """
1720 name = "HCI_Link_Key_Request_Reply"
1721 fields_desc = [LEMACField("bd_addr", None),
1722 NBytesField("link_key", None, 16), ]
1723
1724
1725class HCI_Cmd_Link_Key_Request_Negative_Reply(Packet):
1726 """
1727 7.1.11 Link Key Request Negative Reply command
1728 """
1729 name = "HCI_Link_Key_Request_Negative_Reply"
1730 fields_desc = [LEMACField("bd_addr", None), ]
1731
1732
1733class HCI_Cmd_PIN_Code_Request_Reply(Packet):
1734 """
1735 7.1.12 PIN Code Request Reply command
1736 """
1737 name = "HCI_PIN_Code_Request_Reply"
1738 fields_desc = [LEMACField("bd_addr", None),
1739 ByteField("pin_code_length", 7),
1740 NBytesField("pin_code", b"\x00" * 16, sz=16), ]
1741
1742
1743class HCI_Cmd_PIN_Code_Request_Negative_Reply(Packet):
1744 """
1745 7.1.13 PIN Code Request Negative Reply command
1746 """
1747 name = "HCI_PIN_Code_Request_Negative_Reply"
1748 fields_desc = [LEMACField("bd_addr", None), ]
1749
1750
1751class HCI_Cmd_Change_Connection_Packet_Type(Packet):
1752 """
1753 7.1.14 Change Connection Packet Type command
1754 """
1755 name = "HCI_Cmd_Change_Connection_Packet_Type"
1756 fields_desc = [XLEShortField("connection_handle", None),
1757 LEShortField("packet_type", 0), ]
1758
1759
1760class HCI_Cmd_Authentication_Requested(Packet):
1761 """
1762 7.1.15 Authentication Requested command
1763 """
1764 name = "HCI_Authentication_Requested"
1765 fields_desc = [LEShortField("handle", 0)]
1766
1767
1768class HCI_Cmd_Set_Connection_Encryption(Packet):
1769 """
1770 7.1.16 Set Connection Encryption command
1771 """
1772 name = "HCI_Set_Connection_Encryption"
1773 fields_desc = [LEShortField("handle", 0), ByteField("encryption_enable", 0)]
1774
1775
1776class HCI_Cmd_Change_Connection_Link_Key(Packet):
1777 """
1778 7.1.17 Change Connection Link Key command
1779 """
1780 name = "HCI_Change_Connection_Link_Key"
1781 fields_desc = [LEShortField("handle", 0), ]
1782
1783
1784class HCI_Cmd_Link_Key_Selection(Packet):
1785 """
1786 7.1.18 Change Connection Link Key command
1787 """
1788 name = "HCI_Cmd_Link_Key_Selection"
1789 fields_desc = [ByteEnumField("handle", 0, {0: "Use semi-permanent Link Keys",
1790 1: "Use Temporary Link Key", }), ]
1791
1792
1793class HCI_Cmd_Remote_Name_Request(Packet):
1794 """
1795 7.1.19 Remote Name Request command
1796 """
1797 name = "HCI_Remote_Name_Request"
1798 fields_desc = [LEMACField("bd_addr", None),
1799 ByteField("page_scan_repetition_mode", 0x02),
1800 ByteField("reserved", 0x0),
1801 LEShortField("clock_offset", 0x0), ]
1802
1803
1804class HCI_Cmd_Remote_Name_Request_Cancel(Packet):
1805 """
1806 7.1.20 Remote Name Request Cancel command
1807 """
1808 name = "HCI_Remote_Name_Request_Cancel"
1809 fields_desc = [LEMACField("bd_addr", None), ]
1810
1811
1812class HCI_Cmd_Read_Remote_Supported_Features(Packet):
1813 """
1814 7.1.21 Read Remote Supported Features command
1815 """
1816 name = "HCI_Read_Remote_Supported_Features"
1817 fields_desc = [LEShortField("connection_handle", None), ]
1818
1819
1820class HCI_Cmd_Read_Remote_Extended_Features(Packet):
1821 """
1822 7.1.22 Read Remote Extended Features command
1823 """
1824 name = "HCI_Read_Remote_Supported_Features"
1825 fields_desc = [LEShortField("connection_handle", None),
1826 ByteField("page_number", None), ]
1827
1828
1829class HCI_Cmd_IO_Capability_Request_Reply(Packet):
1830 """
1831 7.1.29 IO Capability Request Reply command
1832 """
1833 name = "HCI_Read_Remote_Supported_Features"
1834 fields_desc = [LEMACField("bd_addr", None),
1835 ByteEnumField("io_capability", None, {0x00: "DisplayOnly",
1836 0x01: "DisplayYesNo",
1837 0x02: "KeyboardOnly",
1838 0x03: "NoInputNoOutput", }),
1839 ByteEnumField("oob_data_present", None, {0x00: "Not Present",
1840 0x01: "P-192",
1841 0x02: "P-256",
1842 0x03: "P-192 + P-256", }),
1843 ByteEnumField("authentication_requirement", None,
1844 {0x00: "MITM Not Required",
1845 0x01: "MITM Required, No Bonding",
1846 0x02: "MITM Not Required + Dedicated Pairing",
1847 0x03: "MITM Required + Dedicated Pairing",
1848 0x04: "MITM Not Required, General Bonding",
1849 0x05: "MITM Required + General Bonding"}), ]
1850
1851
1852class HCI_Cmd_User_Confirmation_Request_Reply(Packet):
1853 """
1854 7.1.30 User Confirmation Request Reply command
1855 """
1856 name = "HCI_User_Confirmation_Request_Reply"
1857 fields_desc = [LEMACField("bd_addr", None), ]
1858
1859
1860class HCI_Cmd_User_Confirmation_Request_Negative_Reply(Packet):
1861 """
1862 7.1.31 User Confirmation Request Negative Reply command
1863 """
1864 name = "HCI_User_Confirmation_Request_Negative_Reply"
1865 fields_desc = [LEMACField("bd_addr", None), ]
1866
1867
1868class HCI_Cmd_User_Passkey_Request_Reply(Packet):
1869 """
1870 7.1.32 User Passkey Request Reply command
1871 """
1872 name = "HCI_User_Passkey_Request_Reply"
1873 fields_desc = [LEMACField("bd_addr", None),
1874 LEIntField("numeric_value", None), ]
1875
1876
1877class HCI_Cmd_User_Passkey_Request_Negative_Reply(Packet):
1878 """
1879 7.1.33 User Passkey Request Negative Reply command
1880 """
1881 name = "HCI_User_Passkey_Request_Negative_Reply"
1882 fields_desc = [LEMACField("bd_addr", None), ]
1883
1884
1885class HCI_Cmd_Remote_OOB_Data_Request_Reply(Packet):
1886 """
1887 7.1.34 Remote OOB Data Request Reply command
1888 """
1889 name = "HCI_Remote_OOB_Data_Request_Reply"
1890 fields_desc = [LEMACField("bd_addr", None),
1891 NBytesField("C", b"\x00" * 16, sz=16),
1892 NBytesField("R", b"\x00" * 16, sz=16), ]
1893
1894
1895class HCI_Cmd_Remote_OOB_Data_Request_Negative_Reply(Packet):
1896 """
1897 7.1.35 Remote OOB Data Request Negative Reply command
1898 """
1899 name = "HCI_Remote_OOB_Data_Request_Negative_Reply"
1900 fields_desc = [LEMACField("bd_addr", None), ]
1901
1902
1903# 7.2 Link Policy commands, the OGF is defined as 0x02
1904
1905class HCI_Cmd_Hold_Mode(Packet):
1906 name = "HCI_Hold_Mode"
1907 fields_desc = [LEShortField("connection_handle", 0),
1908 LEShortField("hold_mode_max_interval", 0x0002),
1909 LEShortField("hold_mode_min_interval", 0x0002), ]
1910
1911
1912# 7.3 CONTROLLER & BASEBAND COMMANDS, the OGF is defined as 0x03
1913
1914class HCI_Cmd_Set_Event_Mask(Packet):
1915 """
1916 7.3.1 Set Event Mask command
1917 """
1918 name = "HCI_Set_Event_Mask"
1919 fields_desc = [StrFixedLenField("mask", b"\xff\xff\xfb\xff\x07\xf8\xbf\x3d", 8)] # noqa: E501
1920
1921
1922class HCI_Cmd_Reset(Packet):
1923 """
1924 7.3.2 Reset command
1925 """
1926 name = "HCI_Reset"
1927
1928
1929class HCI_Cmd_Set_Event_Filter(Packet):
1930 """
1931 7.3.3 Set Event Filter command
1932 """
1933 name = "HCI_Set_Event_Filter"
1934 fields_desc = [ByteEnumField("type", 0, {0: "clear"}), ]
1935
1936
1937class HCI_Cmd_Write_Local_Name(Packet):
1938 """
1939 7.3.11 Write Local Name command
1940 """
1941 name = "HCI_Write_Local_Name"
1942 fields_desc = [StrFixedLenField('name', '', length=248)]
1943
1944
1945class HCI_Cmd_Read_Local_Name(Packet):
1946 """
1947 7.3.12 Read Local Name command
1948 """
1949 name = "HCI_Read_Local_Name"
1950
1951
1952class HCI_Cmd_Write_Connect_Accept_Timeout(Packet):
1953 name = "HCI_Write_Connection_Accept_Timeout"
1954 fields_desc = [LEShortField("timeout", 32000)] # 32000 slots is 20000 msec
1955
1956
1957class HCI_Cmd_Write_Extended_Inquiry_Response(Packet):
1958 name = "HCI_Write_Extended_Inquiry_Response"
1959 fields_desc = [ByteField("fec_required", 0),
1960 HCI_Extended_Inquiry_Response]
1961
1962
1963class HCI_Cmd_Read_LE_Host_Support(Packet):
1964 name = "HCI_Read_LE_Host_Support"
1965
1966
1967class HCI_Cmd_Write_LE_Host_Support(Packet):
1968 name = "HCI_Write_LE_Host_Support"
1969 fields_desc = [ByteField("supported", 1),
1970 ByteField("unused", 1), ]
1971
1972
1973# 7.4 INFORMATIONAL PARAMETERS, the OGF is defined as 0x04
1974
1975class HCI_Cmd_Read_Local_Version_Information(Packet):
1976 """
1977 7.4.1 Read Local Version Information command
1978 """
1979 name = "HCI_Read_Local_Version_Information"
1980
1981
1982class HCI_Cmd_Read_Local_Extended_Features(Packet):
1983 """
1984 7.4.4 Read Local Extended Features command
1985 """
1986 name = "HCI_Read_Local_Extended_Features"
1987 fields_desc = [ByteField("page_number", 0)]
1988
1989
1990class HCI_Cmd_Read_BD_Addr(Packet):
1991 """
1992 7.4.6 Read BD_ADDR command
1993 """
1994 name = "HCI_Read_BD_ADDR"
1995
1996
1997# 7.5 STATUS PARAMETERS, the OGF is defined as 0x05
1998
1999class HCI_Cmd_Read_Link_Quality(Packet):
2000 name = "HCI_Read_Link_Quality"
2001 fields_desc = [LEShortField("handle", 0)]
2002
2003
2004class HCI_Cmd_Read_RSSI(Packet):
2005 name = "HCI_Read_RSSI"
2006 fields_desc = [LEShortField("handle", 0)]
2007
2008
2009# 7.6 TESTING COMMANDS, the OGF is defined as 0x06
2010
2011class HCI_Cmd_Read_Loopback_Mode(Packet):
2012 name = "HCI_Read_Loopback_Mode"
2013
2014
2015class HCI_Cmd_Write_Loopback_Mode(Packet):
2016 name = "HCI_Write_Loopback_Mode"
2017 fields_desc = [ByteEnumField("loopback_mode", 0,
2018 {0: "no loopback",
2019 1: "enable local loopback",
2020 2: "enable remote loopback"})]
2021
2022
2023# 7.8 LE CONTROLLER COMMANDS, the OGF code is defined as 0x08
2024
2025class HCI_Cmd_LE_Read_Buffer_Size_V1(Packet):
2026 name = "HCI_LE_Read_Buffer_Size [v1]"
2027
2028
2029class HCI_Cmd_LE_Read_Buffer_Size_V2(Packet):
2030 name = "HCI_LE_Read_Buffer_Size [v2]"
2031
2032
2033class HCI_Cmd_LE_Read_Local_Supported_Features(Packet):
2034 name = "HCI_LE_Read_Local_Supported_Features"
2035
2036
2037class HCI_Cmd_LE_Set_Random_Address(Packet):
2038 name = "HCI_LE_Set_Random_Address"
2039 fields_desc = [LEMACField("address", None)]
2040
2041
2042class HCI_Cmd_LE_Set_Advertising_Parameters(Packet):
2043 name = "HCI_LE_Set_Advertising_Parameters"
2044 fields_desc = [LEShortField("interval_min", 0x0800),
2045 LEShortField("interval_max", 0x0800),
2046 ByteEnumField("adv_type", 0, {0: "ADV_IND", 1: "ADV_DIRECT_IND", 2: "ADV_SCAN_IND", 3: "ADV_NONCONN_IND", 4: "ADV_DIRECT_IND_LOW"}), # noqa: E501
2047 ByteEnumField("oatype", 0, {0: "public", 1: "random"}),
2048 ByteEnumField("datype", 0, {0: "public", 1: "random"}),
2049 LEMACField("daddr", None),
2050 ByteField("channel_map", 7),
2051 ByteEnumField("filter_policy", 0, {0: "all:all", 1: "connect:all scan:whitelist", 2: "connect:whitelist scan:all", 3: "all:whitelist"}), ] # noqa: E501
2052
2053
2054class HCI_Cmd_LE_Set_Advertising_Data(Packet):
2055 name = "HCI_LE_Set_Advertising_Data"
2056 fields_desc = [FieldLenField("len", None, length_of="data", fmt="B"),
2057 PadField(
2058 PacketListField("data", [], EIR_Hdr,
2059 length_from=lambda pkt: pkt.len),
2060 align=31, padwith=b"\0"), ]
2061
2062
2063class HCI_Cmd_LE_Set_Scan_Response_Data(Packet):
2064 name = "HCI_LE_Set_Scan_Response_Data"
2065 fields_desc = [FieldLenField("len", None, length_of="data", fmt="B"),
2066 StrLenField("data", "", length_from=lambda pkt: pkt.len), ]
2067
2068
2069class HCI_Cmd_LE_Set_Advertise_Enable(Packet):
2070 name = "HCI_LE_Set_Advertising_Enable"
2071 fields_desc = [ByteField("enable", 0)]
2072
2073
2074class HCI_Cmd_LE_Set_Scan_Parameters(Packet):
2075 name = "HCI_LE_Set_Scan_Parameters"
2076 fields_desc = [ByteEnumField("type", 0, {0: "passive", 1: "active"}),
2077 XLEShortField("interval", 16),
2078 XLEShortField("window", 16),
2079 ByteEnumField("atype", 0, {0: "public",
2080 1: "random",
2081 2: "rpa (pub)",
2082 3: "rpa (random)"}),
2083 ByteEnumField("policy", 0, {0: "all", 1: "whitelist"})]
2084
2085
2086class HCI_Cmd_LE_Set_Scan_Enable(Packet):
2087 name = "HCI_LE_Set_Scan_Enable"
2088 fields_desc = [ByteField("enable", 1),
2089 ByteField("filter_dups", 1), ]
2090
2091
2092class HCI_Cmd_LE_Create_Connection(Packet):
2093 name = "HCI_LE_Create_Connection"
2094 fields_desc = [LEShortField("interval", 96),
2095 LEShortField("window", 48),
2096 ByteEnumField("filter", 0, {0: "address"}),
2097 ByteEnumField("patype", 0, {0: "public", 1: "random"}),
2098 LEMACField("paddr", None),
2099 ByteEnumField("atype", 0, {0: "public", 1: "random"}),
2100 LEShortField("min_interval", 40),
2101 LEShortField("max_interval", 56),
2102 LEShortField("latency", 0),
2103 LEShortField("timeout", 42),
2104 LEShortField("min_ce", 0),
2105 LEShortField("max_ce", 0), ]
2106
2107
2108class HCI_Cmd_LE_Create_Connection_Cancel(Packet):
2109 name = "HCI_LE_Create_Connection_Cancel"
2110
2111
2112class HCI_Cmd_LE_Read_Filter_Accept_List_Size(Packet):
2113 name = "HCI_LE_Read_Filter_Accept_List_Size"
2114
2115
2116class HCI_Cmd_LE_Clear_Filter_Accept_List(Packet):
2117 name = "HCI_LE_Clear_Filter_Accept_List"
2118
2119
2120class HCI_Cmd_LE_Add_Device_To_Filter_Accept_List(Packet):
2121 name = "HCI_LE_Add_Device_To_Filter_Accept_List"
2122 fields_desc = [ByteEnumField("address_type", 0, {0: "public",
2123 1: "random",
2124 0xff: "anonymous"}),
2125 LEMACField("address", None)]
2126
2127
2128class HCI_Cmd_LE_Remove_Device_From_Filter_Accept_List(HCI_Cmd_LE_Add_Device_To_Filter_Accept_List): # noqa: E501
2129 name = "HCI_LE_Remove_Device_From_Filter_Accept_List"
2130
2131
2132class HCI_Cmd_LE_Connection_Update(Packet):
2133 name = "HCI_LE_Connection_Update"
2134 fields_desc = [XLEShortField("handle", 0),
2135 XLEShortField("min_interval", 0),
2136 XLEShortField("max_interval", 0),
2137 XLEShortField("latency", 0),
2138 XLEShortField("timeout", 0),
2139 LEShortField("min_ce", 0),
2140 LEShortField("max_ce", 0xffff), ]
2141
2142
2143class HCI_Cmd_LE_Read_Remote_Features(Packet):
2144 name = "HCI_LE_Read_Remote_Features"
2145 fields_desc = [LEShortField("handle", 64)]
2146
2147
2148class HCI_Cmd_LE_Enable_Encryption(Packet):
2149 name = "HCI_LE_Enable_Encryption"
2150 fields_desc = [LEShortField("handle", 0),
2151 StrFixedLenField("rand", None, 8),
2152 XLEShortField("ediv", 0),
2153 StrFixedLenField("ltk", b'\x00' * 16, 16), ]
2154
2155
2156class HCI_Cmd_LE_Long_Term_Key_Request_Reply(Packet):
2157 name = "HCI_LE_Long_Term_Key_Request_Reply"
2158 fields_desc = [LEShortField("handle", 0),
2159 StrFixedLenField("ltk", b'\x00' * 16, 16), ]
2160
2161
2162class HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply(Packet):
2163 name = "HCI_LE_Long_Term_Key_Request _Negative_Reply"
2164 fields_desc = [LEShortField("handle", 0), ]
2165
2166
2167class HCI_Event_Hdr(Packet):
2168 name = "HCI Event header"
2169 fields_desc = [XByteField("code", 0),
2170 LenField("len", None, fmt="B"), ]
2171
2172 def answers(self, other):
2173 if HCI_Command_Hdr not in other:
2174 return False
2175
2176 # Delegate answers to event types
2177 return self.payload.answers(other)
2178
2179
2180class HCI_Event_Inquiry_Complete(Packet):
2181 """
2182 7.7.1 Inquiry Complete event
2183 """
2184 name = "HCI_Inquiry_Complete"
2185 fields_desc = [
2186 ByteEnumField('status', 0, _bluetooth_error_codes)
2187 ]
2188
2189
2190class HCI_Event_Inquiry_Result(Packet):
2191 """
2192 7.7.2 Inquiry Result event
2193 """
2194 name = "HCI_Inquiry_Result"
2195 fields_desc = [
2196 ByteField("num_response", 0x00),
2197 FieldListField("addr", None, LEMACField("addr", None),
2198 count_from=lambda p: p.num_response),
2199 FieldListField("page_scan_repetition_mode", None,
2200 ByteField("page_scan_repetition_mode", 0),
2201 count_from=lambda p: p.num_response),
2202 FieldListField("reserved", None, LEShortField("reserved", 0),
2203 count_from=lambda p: p.num_response),
2204 FieldListField("device_class", None, XLE3BytesField("device_class", 0),
2205 count_from=lambda p: p.num_response),
2206 FieldListField("clock_offset", None, LEShortField("clock_offset", 0),
2207 count_from=lambda p: p.num_response)
2208 ]
2209
2210
2211class HCI_Event_Connection_Complete(Packet):
2212 """
2213 7.7.3 Connection Complete event
2214 """
2215 name = "HCI_Connection_Complete"
2216 fields_desc = [ByteEnumField('status', 0, _bluetooth_error_codes),
2217 LEShortField("handle", 0x0100),
2218 LEMACField("bd_addr", None),
2219 ByteEnumField("link_type", 0, {0: "SCO connection",
2220 1: "ACL connection", }),
2221 ByteEnumField("encryption_enabled", 0,
2222 {0: "link level encryption disabled",
2223 1: "link level encryption enabled", }), ]
2224
2225
2226class HCI_Event_Disconnection_Complete(Packet):
2227 """
2228 7.7.5 Disconnection Complete event
2229 """
2230 name = "HCI_Disconnection_Complete"
2231 fields_desc = [ByteEnumField("status", 0, _bluetooth_error_codes),
2232 LEShortField("handle", 0),
2233 XByteField("reason", 0), ]
2234
2235
2236class HCI_Event_Remote_Name_Request_Complete(Packet):
2237 """
2238 7.7.7 Remote Name Request Complete event
2239 """
2240 name = "HCI_Remote_Name_Request_Complete"
2241 fields_desc = [ByteEnumField("status", 0, _bluetooth_error_codes),
2242 LEMACField("bd_addr", None),
2243 StrFixedLenField("remote_name", b"\x00", 248), ]
2244
2245
2246class HCI_Event_Encryption_Change(Packet):
2247 """
2248 7.7.8 Encryption Change event
2249 """
2250 name = "HCI_Encryption_Change"
2251 fields_desc = [ByteEnumField("status", 0, {0: "change has occurred"}),
2252 LEShortField("handle", 0),
2253 ByteEnumField("enabled", 0, {0: "OFF", 1: "ON (LE)", 2: "ON (BR/EDR)"}), ] # noqa: E501
2254
2255
2256class HCI_Event_Read_Remote_Supported_Features_Complete(Packet):
2257 """
2258 7.7.11 Read Remote Supported Features Complete event
2259 """
2260 name = "HCI_Read_Remote_Supported_Features_Complete"
2261 fields_desc = [
2262 ByteEnumField('status', 0, _bluetooth_error_codes),
2263 LEShortField('handle', 0),
2264 FlagsField('lmp_features', 0, -64, _bluetooth_features)
2265 ]
2266
2267
2268class HCI_Event_Read_Remote_Version_Information_Complete(Packet):
2269 """
2270 7.7.12 Read Remote Version Information Complete event
2271 """
2272 name = "HCI_Read_Remote_Version_Information"
2273 fields_desc = [
2274 ByteEnumField('status', 0, _bluetooth_error_codes),
2275 LEShortField('handle', 0),
2276 ByteField('version', 0x00),
2277 LEShortField('manufacturer_name', 0x0000),
2278 LEShortField('subversion', 0x0000)
2279 ]
2280
2281
2282class HCI_Event_Command_Complete(Packet):
2283 """
2284 7.7.14 Command Complete event
2285 """
2286 name = "HCI_Command_Complete"
2287 fields_desc = [ByteField("number", 0),
2288 XLEShortField("opcode", 0),
2289 ByteEnumField("status", 0, _bluetooth_error_codes)]
2290
2291 def answers(self, other):
2292 if HCI_Command_Hdr not in other:
2293 return False
2294
2295 return other[HCI_Command_Hdr].opcode == self.opcode
2296
2297
2298class HCI_Event_Command_Status(Packet):
2299 """
2300 7.7.15 Command Status event
2301 """
2302 name = "HCI_Command_Status"
2303 fields_desc = [ByteEnumField("status", 0, {0: "pending"}),
2304 ByteField("number", 0),
2305 XLEShortField("opcode", None), ]
2306
2307 def answers(self, other):
2308 if HCI_Command_Hdr not in other:
2309 return False
2310
2311 return other[HCI_Command_Hdr].opcode == self.opcode
2312
2313
2314class HCI_Event_Number_Of_Completed_Packets(Packet):
2315 """
2316 7.7.19 Number Of Completed Packets event
2317 """
2318 name = "HCI_Number_Of_Completed_Packets"
2319 fields_desc = [ByteField("num_handles", 0),
2320 FieldListField("connection_handle_list", None,
2321 LEShortField("connection_handle", 0),
2322 count_from=lambda p: p.num_handles),
2323 FieldListField("num_completed_packets_list", None,
2324 LEShortField("num_completed_packets", 0),
2325 count_from=lambda p: p.num_handles)]
2326
2327
2328class HCI_Event_Link_Key_Request(Packet):
2329 """
2330 7.7.23 Link Key Request event
2331 """
2332 name = 'HCI_Link_Key_Request'
2333 fields_desc = [
2334 LEMACField('bd_addr', None)
2335 ]
2336
2337
2338class HCI_Event_Inquiry_Result_With_Rssi(Packet):
2339 """
2340 7.7.33 Inquiry Result with RSSI event
2341 """
2342 name = "HCI_Inquiry_Result_with_RSSI"
2343 fields_desc = [
2344 ByteField("num_response", 0x00),
2345 FieldListField("bd_addr", None, LEMACField,
2346 count_from=lambda p: p.num_response),
2347 FieldListField("page_scan_repetition_mode", None, ByteField,
2348 count_from=lambda p: p.num_response),
2349 FieldListField("reserved", None, LEShortField,
2350 count_from=lambda p: p.num_response),
2351 FieldListField("device_class", None, XLE3BytesField,
2352 count_from=lambda p: p.num_response),
2353 FieldListField("clock_offset", None, LEShortField,
2354 count_from=lambda p: p.num_response),
2355 FieldListField("rssi", None, SignedByteField,
2356 count_from=lambda p: p.num_response)
2357 ]
2358
2359
2360class HCI_Event_Read_Remote_Extended_Features_Complete(Packet):
2361 """
2362 7.7.34 Read Remote Extended Features Complete event
2363 """
2364 name = "HCI_Read_Remote_Extended_Features_Complete"
2365 fields_desc = [
2366 ByteEnumField('status', 0, _bluetooth_error_codes),
2367 LEShortField('handle', 0),
2368 ByteField('page', 0x00),
2369 ByteField('max_page', 0x00),
2370 XLELongField('extended_features', 0)
2371 ]
2372
2373
2374class HCI_Event_Extended_Inquiry_Result(Packet):
2375 """
2376 7.7.38 Extended Inquiry Result event
2377 """
2378 name = "HCI_Extended_Inquiry_Result"
2379 fields_desc = [
2380 ByteField('num_response', 0x01),
2381 LEMACField('bd_addr', None),
2382 ByteField('page_scan_repetition_mode', 0x00),
2383 ByteField('reserved', 0x00),
2384 XLE3BytesField('device_class', 0x000000),
2385 LEShortField('clock_offset', 0x0000),
2386 SignedByteField('rssi', 0x00),
2387 HCI_Extended_Inquiry_Response,
2388 ]
2389
2390
2391class HCI_Event_IO_Capability_Response(Packet):
2392 """
2393 7.7.41 IO Capability Response event
2394 """
2395 name = "HCI_IO_Capability_Response"
2396 fields_desc = [
2397 LEMACField('bd_addr', None),
2398 ByteField('io_capability', 0x00),
2399 ByteField('oob_data_present', 0x00),
2400 ByteField('authentication_requirements', 0x00)
2401 ]
2402
2403
2404class HCI_Event_LE_Meta(Packet):
2405 """
2406 7.7.65 LE Meta event
2407 """
2408 name = "HCI_LE_Meta"
2409 fields_desc = [ByteEnumField("event", 0, {
2410 0x01: "connection_complete",
2411 0x02: "advertising_report",
2412 0x03: "connection_update_complete",
2413 0x04: "read_remote_features_page_0_complete",
2414 0x05: "long_term_key_request",
2415 0x06: "remote_connection_parameter_request",
2416 0x07: "data_length_change",
2417 0x08: "read_local_p256_public_key_complete",
2418 0x09: "generate_dhkey_complete",
2419 0x0a: "enhanced_connection_complete_v1",
2420 0x0b: "directed_advertising_report",
2421 0x0c: "phy_update_complete",
2422 0x0d: "extended_advertising_report",
2423 0x29: "enhanced_connection_complete_v2"
2424 }), ]
2425
2426 def answers(self, other):
2427 if not self.payload:
2428 return False
2429
2430 # Delegate answers to payload
2431 return self.payload.answers(other)
2432
2433
2434class HCI_Cmd_Complete_Read_Local_Name(Packet):
2435 """
2436 7.3.12 Read Local Name command complete
2437 """
2438 name = 'Read Local Name command complete'
2439 fields_desc = [StrFixedLenField('local_name', '', length=248)]
2440
2441
2442class HCI_Cmd_Complete_Read_Local_Version_Information(Packet):
2443 """
2444 7.4.1 Read Local Version Information command complete
2445 """
2446 name = 'Read Local Version Information'
2447 fields_desc = [
2448 ByteField('hci_version', 0),
2449 LEShortField('hci_subversion', 0),
2450 ByteField('lmp_version', 0),
2451 LEShortField('company_identifier', 0),
2452 LEShortField('lmp_subversion', 0)]
2453
2454
2455class HCI_Cmd_Complete_Read_Local_Extended_Features(Packet):
2456 """
2457 7.4.4 Read Local Extended Features command complete
2458 """
2459 name = 'Read Local Extended Features command complete'
2460 fields_desc = [
2461 ByteField('page', 0x00),
2462 ByteField('max_page', 0x00),
2463 XLELongField('extended_features', 0)
2464 ]
2465
2466
2467class HCI_Cmd_Complete_Read_BD_Addr(Packet):
2468 """
2469 7.4.6 Read BD_ADDR command complete
2470 """
2471 name = "Read BD Addr"
2472 fields_desc = [LEMACField("addr", None), ]
2473
2474
2475class HCI_Cmd_Complete_LE_Read_White_List_Size(Packet):
2476 name = "LE Read White List Size"
2477 fields_desc = [ByteField("status", 0),
2478 ByteField("size", 0), ]
2479
2480
2481class HCI_LE_Meta_Connection_Complete(Packet):
2482 name = "Connection Complete"
2483 fields_desc = [ByteEnumField("status", 0, {0: "success"}),
2484 LEShortField("handle", 0),
2485 ByteEnumField("role", 0, {0: "master"}),
2486 ByteEnumField("patype", 0, {0: "public", 1: "random"}),
2487 LEMACField("paddr", None),
2488 LEShortField("interval", 54),
2489 LEShortField("latency", 0),
2490 LEShortField("supervision", 42),
2491 XByteField("clock_latency", 5), ]
2492
2493 def answers(self, other):
2494 if HCI_Cmd_LE_Create_Connection not in other:
2495 return False
2496
2497 return (other[HCI_Cmd_LE_Create_Connection].patype == self.patype and
2498 other[HCI_Cmd_LE_Create_Connection].paddr == self.paddr)
2499
2500
2501class HCI_LE_Meta_Connection_Update_Complete(Packet):
2502 name = "Connection Update Complete"
2503 fields_desc = [ByteEnumField("status", 0, {0: "success"}),
2504 LEShortField("handle", 0),
2505 LEShortField("interval", 54),
2506 LEShortField("latency", 0),
2507 LEShortField("timeout", 42), ]
2508
2509
2510class HCI_LE_Meta_Advertising_Report(Packet):
2511 name = "Advertising Report"
2512 fields_desc = [ByteEnumField("type", 0, {0: "conn_und", 4: "scan_rsp"}),
2513 ByteEnumField("atype", 0, {0: "public", 1: "random"}),
2514 LEMACField("addr", None),
2515 FieldLenField("len", None, length_of="data", fmt="B"),
2516 PacketListField("data", [], EIR_Hdr,
2517 length_from=lambda pkt: pkt.len),
2518 SignedByteField("rssi", 0)]
2519
2520 def extract_padding(self, s):
2521 return '', s
2522
2523
2524class HCI_LE_Meta_Advertising_Reports(Packet):
2525 name = "Advertising Reports"
2526 fields_desc = [FieldLenField("len", None, count_of="reports", fmt="B"),
2527 PacketListField("reports", None,
2528 HCI_LE_Meta_Advertising_Report,
2529 count_from=lambda pkt: pkt.len)]
2530
2531
2532class HCI_LE_Meta_Long_Term_Key_Request(Packet):
2533 name = "Long Term Key Request"
2534 fields_desc = [LEShortField("handle", 0),
2535 StrFixedLenField("rand", None, 8),
2536 XLEShortField("ediv", 0), ]
2537
2538
2539class HCI_LE_Meta_Extended_Advertising_Report(Packet):
2540 name = "Extended Advertising Report"
2541 fields_desc = [
2542 BitField("reserved0", 0, 1),
2543 BitEnumField("data_status", 0, 2, {
2544 0b00: "complete",
2545 0b01: "incomplete",
2546 0b10: "incomplete_truncated",
2547 0b11: "reserved"
2548 }),
2549 BitField("legacy", 0, 1),
2550 BitField("scan_response", 0, 1),
2551 BitField("directed", 0, 1),
2552 BitField("scannable", 0, 1),
2553 BitField("connectable", 0, 1),
2554 ByteField("reserved", 0),
2555 ByteEnumField("address_type", 0, {
2556 0x00: "public_device_address",
2557 0x01: "random_device_address",
2558 0x02: "public_identity_address",
2559 0x03: "random_identity_address",
2560 0xff: "anonymous"
2561 }),
2562 LEMACField('address', None),
2563 ByteEnumField("primary_phy", 0, {
2564 0x01: "le_1m",
2565 0x03: "le_coded_s8",
2566 0x04: "le_coded_s2"
2567 }),
2568 ByteEnumField("secondary_phy", 0, {
2569 0x01: "le_1m",
2570 0x02: "le_2m",
2571 0x03: "le_coded_s8",
2572 0x04: "le_coded_s2"
2573 }),
2574 ByteField("advertising_sid", 0xff),
2575 ByteField("tx_power", 0x7f),
2576 SignedByteField("rssi", 0x00),
2577 LEShortField("periodic_advertising_interval", 0x0000),
2578 ByteEnumField("direct_address_type", 0, {
2579 0x00: "public_device_address",
2580 0x01: "non_resolvable_private_address",
2581 0x02: "resolvable_private_address_resolved_0",
2582 0x03: "resolvable_private_address_resolved_1",
2583 0xfe: "resolvable_private_address_unable_resolve"}),
2584 LEMACField("direct_address", None),
2585 FieldLenField("data_length", None, length_of="data", fmt="B"),
2586 PacketListField("data", [], EIR_Hdr,
2587 length_from=lambda pkt: pkt.data_length),
2588 ]
2589
2590 def extract_padding(self, s):
2591 return '', s
2592
2593
2594class HCI_LE_Meta_Extended_Advertising_Reports(Packet):
2595 name = "Extended Advertising Reports"
2596 fields_desc = [FieldLenField("num_reports", None, count_of="reports", fmt="B"),
2597 PacketListField("reports", None,
2598 HCI_LE_Meta_Extended_Advertising_Report,
2599 count_from=lambda pkt: pkt.num_reports)]
2600
2601
2602bind_layers(HCI_PHDR_Hdr, HCI_Hdr)
2603
2604bind_layers(HCI_Hdr, HCI_Command_Hdr, type=1)
2605bind_layers(HCI_Hdr, HCI_ACL_Hdr, type=2)
2606bind_layers(HCI_Hdr, HCI_Event_Hdr, type=4)
2607bind_layers(HCI_Hdr, conf.raw_layer,)
2608
2609conf.l2types.register(DLT_BLUETOOTH_HCI_H4, HCI_Hdr)
2610conf.l2types.register(DLT_BLUETOOTH_HCI_H4_WITH_PHDR, HCI_PHDR_Hdr)
2611
2612
2613# 7.1 LINK CONTROL COMMANDS, the OGF is defined as 0x01
2614bind_layers(HCI_Command_Hdr, HCI_Cmd_Inquiry, ogf=0x01, ocf=0x0001)
2615bind_layers(HCI_Command_Hdr, HCI_Cmd_Inquiry_Cancel, ogf=0x01, ocf=0x0002)
2616bind_layers(HCI_Command_Hdr, HCI_Cmd_Periodic_Inquiry_Mode, ogf=0x01, ocf=0x0003)
2617bind_layers(HCI_Command_Hdr, HCI_Cmd_Exit_Peiodic_Inquiry_Mode, ogf=0x01, ocf=0x0004)
2618bind_layers(HCI_Command_Hdr, HCI_Cmd_Create_Connection, ogf=0x01, ocf=0x0005)
2619bind_layers(HCI_Command_Hdr, HCI_Cmd_Disconnect, ogf=0x01, ocf=0x0006)
2620bind_layers(HCI_Command_Hdr, HCI_Cmd_Create_Connection_Cancel, ogf=0x01, ocf=0x0008)
2621bind_layers(HCI_Command_Hdr, HCI_Cmd_Accept_Connection_Request, ogf=0x01, ocf=0x0009)
2622bind_layers(HCI_Command_Hdr, HCI_Cmd_Reject_Connection_Response, ogf=0x01, ocf=0x000a)
2623bind_layers(HCI_Command_Hdr, HCI_Cmd_Link_Key_Request_Reply, ogf=0x01, ocf=0x000b)
2624bind_layers(HCI_Command_Hdr, HCI_Cmd_Link_Key_Request_Negative_Reply,
2625 ogf=0x01, ocf=0x000c)
2626bind_layers(HCI_Command_Hdr, HCI_Cmd_PIN_Code_Request_Reply, ogf=0x01, ocf=0x000d)
2627bind_layers(HCI_Command_Hdr, HCI_Cmd_Change_Connection_Packet_Type,
2628 ogf=0x01, ocf=0x000f)
2629bind_layers(HCI_Command_Hdr, HCI_Cmd_Authentication_Requested, ogf=0x01, ocf=0x0011)
2630bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Connection_Encryption, ogf=0x01, ocf=0x0013)
2631bind_layers(HCI_Command_Hdr, HCI_Cmd_Change_Connection_Link_Key, ogf=0x01, ocf=0x0017)
2632bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_Name_Request, ogf=0x01, ocf=0x0019)
2633bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_Name_Request_Cancel, ogf=0x01, ocf=0x001a)
2634bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Remote_Supported_Features,
2635 ogf=0x01, ocf=0x001b)
2636bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Remote_Extended_Features,
2637 ogf=0x01, ocf=0x001c)
2638bind_layers(HCI_Command_Hdr, HCI_Cmd_IO_Capability_Request_Reply, ogf=0x01, ocf=0x002b)
2639bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Confirmation_Request_Reply,
2640 ogf=0x01, ocf=0x002c)
2641bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Confirmation_Request_Negative_Reply,
2642 ogf=0x01, ocf=0x002d)
2643bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Passkey_Request_Reply, ogf=0x01, ocf=0x002e)
2644bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Passkey_Request_Negative_Reply,
2645 ogf=0x01, ocf=0x002f)
2646bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_OOB_Data_Request_Reply,
2647 ogf=0x01, ocf=0x0030)
2648bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_OOB_Data_Request_Negative_Reply,
2649 ogf=0x01, ocf=0x0033)
2650
2651# 7.2 Link Policy commands, the OGF is defined as 0x02
2652bind_layers(HCI_Command_Hdr, HCI_Cmd_Hold_Mode, ogf=0x02, ocf=0x0001)
2653
2654# 7.3 CONTROLLER & BASEBAND COMMANDS, the OGF is defined as 0x03
2655bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Event_Mask, ogf=0x03, ocf=0x0001)
2656bind_layers(HCI_Command_Hdr, HCI_Cmd_Reset, ogf=0x03, ocf=0x0003)
2657bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Event_Filter, ogf=0x03, ocf=0x0005)
2658bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Local_Name, ogf=0x03, ocf=0x0013)
2659bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Local_Name, ogf=0x03, ocf=0x0014)
2660bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Connect_Accept_Timeout, ogf=0x03, ocf=0x0016)
2661bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Extended_Inquiry_Response, ogf=0x03, ocf=0x0052) # noqa: E501
2662bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_LE_Host_Support, ogf=0x03, ocf=0x006c)
2663bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_LE_Host_Support, ogf=0x03, ocf=0x006d)
2664
2665# 7.4 INFORMATIONAL PARAMETERS, the OGF is defined as 0x04
2666bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Local_Version_Information, ogf=0x04, ocf=0x0001) # noqa: E501
2667bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Local_Extended_Features, ogf=0x04, ocf=0x0004)
2668bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_BD_Addr, ogf=0x04, ocf=0x0009)
2669
2670# 7.5 STATUS PARAMETERS, the OGF is defined as 0x05
2671bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Link_Quality, ogf=0x05, ocf=0x0003)
2672bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_RSSI, ogf=0x05, ocf=0x0005)
2673
2674# 7.6 TESTING COMMANDS, the OGF is defined as 0x06
2675bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Loopback_Mode, ogf=0x06, ocf=0x0001)
2676bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Loopback_Mode, ogf=0x06, ocf=0x0002)
2677
2678# 7.8 LE CONTROLLER COMMANDS, the OGF code is defined as 0x08
2679bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Buffer_Size_V1, ogf=0x08, ocf=0x0002)
2680bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Buffer_Size_V2, ogf=0x08, ocf=0x0060)
2681bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Local_Supported_Features,
2682 ogf=0x08, ocf=0x0003)
2683bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Random_Address, ogf=0x08, ocf=0x0005)
2684bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertising_Parameters, ogf=0x08, ocf=0x0006) # noqa: E501
2685bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertising_Data, ogf=0x08, ocf=0x0008)
2686bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Response_Data, ogf=0x08, ocf=0x0009)
2687bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertise_Enable, ogf=0x08, ocf=0x000a)
2688bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Parameters, ogf=0x08, ocf=0x000b)
2689bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Enable, ogf=0x08, ocf=0x000c)
2690bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Create_Connection, ogf=0x08, ocf=0x000d)
2691bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Create_Connection_Cancel, ogf=0x08, ocf=0x000e) # noqa: E501
2692bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Filter_Accept_List_Size,
2693 ogf=0x08, ocf=0x000f)
2694bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Clear_Filter_Accept_List, ogf=0x08, ocf=0x0010)
2695bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Add_Device_To_Filter_Accept_List, ogf=0x08, ocf=0x0011) # noqa: E501
2696bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Remove_Device_From_Filter_Accept_List, ogf=0x08, ocf=0x0012) # noqa: E501
2697bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Connection_Update, ogf=0x08, ocf=0x0013)
2698bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Remote_Features, ogf=0x08, ocf=0x0016) # noqa: E501
2699bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Enable_Encryption, ogf=0x08, ocf=0x0019) # noqa: E501
2700bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Long_Term_Key_Request_Reply, ogf=0x08, ocf=0x001a) # noqa: E501
2701bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply, ogf=0x08, ocf=0x001b) # noqa: E501
2702
2703# 7.7 EVENTS
2704bind_layers(HCI_Event_Hdr, HCI_Event_Inquiry_Complete, code=0x01)
2705bind_layers(HCI_Event_Hdr, HCI_Event_Inquiry_Result, code=0x02)
2706bind_layers(HCI_Event_Hdr, HCI_Event_Connection_Complete, code=0x03)
2707bind_layers(HCI_Event_Hdr, HCI_Event_Disconnection_Complete, code=0x05)
2708bind_layers(HCI_Event_Hdr, HCI_Event_Remote_Name_Request_Complete, code=0x07)
2709bind_layers(HCI_Event_Hdr, HCI_Event_Encryption_Change, code=0x08)
2710bind_layers(HCI_Event_Hdr, HCI_Event_Read_Remote_Supported_Features_Complete, code=0x0b)
2711bind_layers(HCI_Event_Hdr, HCI_Event_Read_Remote_Version_Information_Complete, code=0x0c) # noqa: E501
2712bind_layers(HCI_Event_Hdr, HCI_Event_Command_Complete, code=0x0e)
2713bind_layers(HCI_Event_Hdr, HCI_Event_Command_Status, code=0x0f)
2714bind_layers(HCI_Event_Hdr, HCI_Event_Number_Of_Completed_Packets, code=0x13)
2715bind_layers(HCI_Event_Hdr, HCI_Event_Link_Key_Request, code=0x17)
2716bind_layers(HCI_Event_Hdr, HCI_Event_Inquiry_Result_With_Rssi, code=0x22)
2717bind_layers(HCI_Event_Hdr, HCI_Event_Read_Remote_Extended_Features_Complete, code=0x23)
2718bind_layers(HCI_Event_Hdr, HCI_Event_Extended_Inquiry_Result, code=0x2f)
2719bind_layers(HCI_Event_Hdr, HCI_Event_IO_Capability_Response, code=0x32)
2720bind_layers(HCI_Event_Hdr, HCI_Event_LE_Meta, code=0x3e)
2721
2722bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_Read_Local_Name, opcode=0x0c14) # noqa: E501
2723bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_Read_Local_Version_Information, opcode=0x1001) # noqa: E501
2724bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_Read_Local_Extended_Features, opcode=0x1004) # noqa: E501
2725bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_Read_BD_Addr, opcode=0x1009) # noqa: E501
2726bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_LE_Read_White_List_Size, opcode=0x200f) # noqa: E501
2727
2728bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Connection_Complete, event=0x01)
2729bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Advertising_Reports, event=0x02)
2730bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Connection_Update_Complete, event=0x03)
2731bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Long_Term_Key_Request, event=0x05)
2732bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Extended_Advertising_Reports, event=0x0d)
2733
2734bind_layers(EIR_Hdr, EIR_Flags, type=0x01)
2735bind_layers(EIR_Hdr, EIR_IncompleteList16BitServiceUUIDs, type=0x02)
2736bind_layers(EIR_Hdr, EIR_CompleteList16BitServiceUUIDs, type=0x03)
2737bind_layers(EIR_Hdr, EIR_IncompleteList32BitServiceUUIDs, type=0x04)
2738bind_layers(EIR_Hdr, EIR_CompleteList32BitServiceUUIDs, type=0x05)
2739bind_layers(EIR_Hdr, EIR_IncompleteList128BitServiceUUIDs, type=0x06)
2740bind_layers(EIR_Hdr, EIR_CompleteList128BitServiceUUIDs, type=0x07)
2741bind_layers(EIR_Hdr, EIR_ShortenedLocalName, type=0x08)
2742bind_layers(EIR_Hdr, EIR_CompleteLocalName, type=0x09)
2743bind_layers(EIR_Hdr, EIR_Device_ID, type=0x10)
2744bind_layers(EIR_Hdr, EIR_TX_Power_Level, type=0x0a)
2745bind_layers(EIR_Hdr, EIR_ClassOfDevice, type=0x0d)
2746bind_layers(EIR_Hdr, EIR_SecureSimplePairingHashC192, type=0x0e)
2747bind_layers(EIR_Hdr, EIR_SecureSimplePairingRandomizerR192, type=0x0f)
2748bind_layers(EIR_Hdr, EIR_SecurityManagerOOBFlags, type=0x11)
2749bind_layers(EIR_Hdr, EIR_PeripheralConnectionIntervalRange, type=0x12)
2750bind_layers(EIR_Hdr, EIR_ServiceSolicitation16BitUUID, type=0x14)
2751bind_layers(EIR_Hdr, EIR_ServiceSolicitation128BitUUID, type=0x15)
2752bind_layers(EIR_Hdr, EIR_ServiceData16BitUUID, type=0x16)
2753bind_layers(EIR_Hdr, EIR_PublicTargetAddress, type=0x17)
2754bind_layers(EIR_Hdr, EIR_Appearance, type=0x19)
2755bind_layers(EIR_Hdr, EIR_AdvertisingInterval, type=0x1a)
2756bind_layers(EIR_Hdr, EIR_LEBluetoothDeviceAddress, type=0x1b)
2757bind_layers(EIR_Hdr, EIR_ServiceData32BitUUID, type=0x20)
2758bind_layers(EIR_Hdr, EIR_ServiceData128BitUUID, type=0x21)
2759bind_layers(EIR_Hdr, EIR_URI, type=0x24)
2760bind_layers(EIR_Hdr, EIR_Manufacturer_Specific_Data, type=0xff)
2761bind_layers(EIR_Hdr, EIR_Raw)
2762
2763bind_layers(HCI_ACL_Hdr, L2CAP_Hdr,)
2764bind_layers(L2CAP_Hdr, L2CAP_CmdHdr, cid=1)
2765bind_layers(L2CAP_Hdr, L2CAP_CmdHdr, cid=5) # LE L2CAP Signaling Channel
2766bind_layers(L2CAP_CmdHdr, L2CAP_CmdRej, code=1)
2767bind_layers(L2CAP_CmdHdr, L2CAP_ConnReq, code=2)
2768bind_layers(L2CAP_CmdHdr, L2CAP_ConnResp, code=3)
2769bind_layers(L2CAP_CmdHdr, L2CAP_ConfReq, code=4)
2770bind_layers(L2CAP_CmdHdr, L2CAP_ConfResp, code=5)
2771bind_layers(L2CAP_CmdHdr, L2CAP_DisconnReq, code=6)
2772bind_layers(L2CAP_CmdHdr, L2CAP_DisconnResp, code=7)
2773bind_layers(L2CAP_CmdHdr, L2CAP_EchoReq, code=8)
2774bind_layers(L2CAP_CmdHdr, L2CAP_EchoResp, code=9)
2775bind_layers(L2CAP_CmdHdr, L2CAP_InfoReq, code=10)
2776bind_layers(L2CAP_CmdHdr, L2CAP_InfoResp, code=11)
2777bind_layers(L2CAP_CmdHdr, L2CAP_Create_Channel_Request, code=12)
2778bind_layers(L2CAP_CmdHdr, L2CAP_Create_Channel_Response, code=13)
2779bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Request, code=14)
2780bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Response, code=15)
2781bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Confirmation_Request, code=16)
2782bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Confirmation_Response, code=17)
2783bind_layers(L2CAP_CmdHdr, L2CAP_Connection_Parameter_Update_Request, code=18)
2784bind_layers(L2CAP_CmdHdr, L2CAP_Connection_Parameter_Update_Response, code=19)
2785bind_layers(L2CAP_CmdHdr, L2CAP_LE_Credit_Based_Connection_Request, code=20)
2786bind_layers(L2CAP_CmdHdr, L2CAP_LE_Credit_Based_Connection_Response, code=21)
2787bind_layers(L2CAP_CmdHdr, L2CAP_Flow_Control_Credit_Ind, code=22)
2788bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Connection_Request, code=23)
2789bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Connection_Response, code=24)
2790bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Reconfigure_Request, code=25)
2791bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Reconfigure_Response, code=26)
2792bind_layers(L2CAP_Hdr, ATT_Hdr, cid=4)
2793bind_layers(ATT_Hdr, ATT_Error_Response, opcode=0x1)
2794bind_layers(ATT_Hdr, ATT_Exchange_MTU_Request, opcode=0x2)
2795bind_layers(ATT_Hdr, ATT_Exchange_MTU_Response, opcode=0x3)
2796bind_layers(ATT_Hdr, ATT_Find_Information_Request, opcode=0x4)
2797bind_layers(ATT_Hdr, ATT_Find_Information_Response, opcode=0x5)
2798bind_layers(ATT_Hdr, ATT_Find_By_Type_Value_Request, opcode=0x6)
2799bind_layers(ATT_Hdr, ATT_Find_By_Type_Value_Response, opcode=0x7)
2800bind_layers(ATT_Hdr, ATT_Read_By_Type_Request_128bit, opcode=0x8)
2801bind_layers(ATT_Hdr, ATT_Read_By_Type_Request, opcode=0x8)
2802bind_layers(ATT_Hdr, ATT_Read_By_Type_Response, opcode=0x9)
2803bind_layers(ATT_Hdr, ATT_Read_Request, opcode=0xa)
2804bind_layers(ATT_Hdr, ATT_Read_Response, opcode=0xb)
2805bind_layers(ATT_Hdr, ATT_Read_Blob_Request, opcode=0xc)
2806bind_layers(ATT_Hdr, ATT_Read_Blob_Response, opcode=0xd)
2807bind_layers(ATT_Hdr, ATT_Read_Multiple_Request, opcode=0xe)
2808bind_layers(ATT_Hdr, ATT_Read_Multiple_Response, opcode=0xf)
2809bind_layers(ATT_Hdr, ATT_Read_By_Group_Type_Request, opcode=0x10)
2810bind_layers(ATT_Hdr, ATT_Read_By_Group_Type_Response, opcode=0x11)
2811bind_layers(ATT_Hdr, ATT_Write_Request, opcode=0x12)
2812bind_layers(ATT_Hdr, ATT_Write_Response, opcode=0x13)
2813bind_layers(ATT_Hdr, ATT_Prepare_Write_Request, opcode=0x16)
2814bind_layers(ATT_Hdr, ATT_Prepare_Write_Response, opcode=0x17)
2815bind_layers(ATT_Hdr, ATT_Execute_Write_Request, opcode=0x18)
2816bind_layers(ATT_Hdr, ATT_Execute_Write_Response, opcode=0x19)
2817bind_layers(ATT_Hdr, ATT_Write_Command, opcode=0x52)
2818bind_layers(ATT_Hdr, ATT_Handle_Value_Notification, opcode=0x1b)
2819bind_layers(ATT_Hdr, ATT_Handle_Value_Indication, opcode=0x1d)
2820bind_layers(L2CAP_Hdr, SM_Hdr, cid=6)
2821bind_layers(SM_Hdr, SM_Pairing_Request, sm_command=0x01)
2822bind_layers(SM_Hdr, SM_Pairing_Response, sm_command=0x02)
2823bind_layers(SM_Hdr, SM_Confirm, sm_command=0x03)
2824bind_layers(SM_Hdr, SM_Random, sm_command=0x04)
2825bind_layers(SM_Hdr, SM_Failed, sm_command=0x05)
2826bind_layers(SM_Hdr, SM_Encryption_Information, sm_command=0x06)
2827bind_layers(SM_Hdr, SM_Master_Identification, sm_command=0x07)
2828bind_layers(SM_Hdr, SM_Identity_Information, sm_command=0x08)
2829bind_layers(SM_Hdr, SM_Identity_Address_Information, sm_command=0x09)
2830bind_layers(SM_Hdr, SM_Signing_Information, sm_command=0x0a)
2831bind_layers(SM_Hdr, SM_Security_Request, sm_command=0x0b)
2832bind_layers(SM_Hdr, SM_Public_Key, sm_command=0x0c)
2833bind_layers(SM_Hdr, SM_DHKey_Check, sm_command=0x0d)
2834
2835
2836###############
2837# HCI Monitor #
2838###############
2839
2840
2841# https://elixir.bootlin.com/linux/v6.4.2/source/include/net/bluetooth/hci_mon.h#L27
2842class HCI_Mon_Hdr(Packet):
2843 name = 'Bluetooth Linux Monitor Transport Header'
2844 fields_desc = [
2845 LEShortEnumField('opcode', None, {
2846 0: "New index",
2847 1: "Delete index",
2848 2: "Command pkt",
2849 3: "Event pkt",
2850 4: "ACL TX pkt",
2851 5: "ACL RX pkt",
2852 6: "SCO TX pkt",
2853 7: "SCO RX pkt",
2854 8: "Open index",
2855 9: "Close index",
2856 10: "Index info",
2857 11: "Vendor diag",
2858 12: "System note",
2859 13: "User logging",
2860 14: "Ctrl open",
2861 15: "Ctrl close",
2862 16: "Ctrl command",
2863 17: "Ctrl event",
2864 18: "ISO TX pkt",
2865 19: "ISO RX pkt",
2866 }),
2867 LEShortField('adapter_id', None),
2868 LEShortField('len', None)
2869 ]
2870
2871
2872# https://www.tcpdump.org/linktypes/LINKTYPE_BLUETOOTH_LINUX_MONITOR.html
2873class HCI_Mon_Pcap_Hdr(HCI_Mon_Hdr):
2874 name = 'Bluetooth Linux Monitor Transport Pcap Header'
2875 fields_desc = [
2876 ShortField('adapter_id', None),
2877 ShortField('opcode', None)
2878 ]
2879
2880
2881class HCI_Mon_New_Index(Packet):
2882 name = 'Bluetooth Linux Monitor Transport New Index Packet'
2883 fields_desc = [
2884 ByteEnumField('bus', 0, {
2885 0x00: "BR/EDR",
2886 0x01: "AMP"
2887 }),
2888 ByteEnumField('type', 0, {
2889 0x00: "Virtual",
2890 0x01: "USB",
2891 0x02: "PC Card",
2892 0x03: "UART",
2893 0x04: "RS232",
2894 0x05: "PCI",
2895 0x06: "SDIO"
2896 }),
2897 LEMACField('addr', None),
2898 StrFixedLenField('devname', None, 8)
2899 ]
2900
2901
2902class HCI_Mon_Index_Info(Packet):
2903 name = 'Bluetooth Linux Monitor Transport Index Info Packet'
2904 fields_desc = [
2905 LEMACField('addr', None),
2906 XLEShortField('manufacturer', None)
2907 ]
2908
2909
2910class HCI_Mon_System_Note(Packet):
2911 name = 'Bluetooth Linux Monitor Transport System Note Packet'
2912 fields_desc = [
2913 StrNullField('note', None)
2914 ]
2915
2916
2917# https://elixir.bootlin.com/linux/v6.4.2/source/include/net/bluetooth/hci_mon.h#L34
2918bind_layers(HCI_Mon_Hdr, HCI_Mon_New_Index, opcode=0)
2919bind_layers(HCI_Mon_Hdr, HCI_Command_Hdr, opcode=2)
2920bind_layers(HCI_Mon_Hdr, HCI_Event_Hdr, opcode=3)
2921bind_layers(HCI_Mon_Hdr, HCI_Mon_Index_Info, opcode=10)
2922bind_layers(HCI_Mon_Hdr, HCI_Mon_System_Note, opcode=12)
2923
2924conf.l2types.register(DLT_BLUETOOTH_LINUX_MONITOR, HCI_Mon_Pcap_Hdr)
2925
2926
2927###########
2928# Helpers #
2929###########
2930
2931class LowEnergyBeaconHelper:
2932 """
2933 Helpers for building packets for Bluetooth Low Energy Beacons.
2934
2935 Implementers provide a :meth:`build_eir` implementation.
2936
2937 This is designed to be used as a mix-in -- see
2938 ``scapy.contrib.eddystone`` and ``scapy.contrib.ibeacon`` for examples.
2939 """
2940
2941 # Basic flags that should be used by most beacons.
2942 base_eir = [EIR_Hdr() / EIR_Flags(flags=[
2943 "general_disc_mode", "br_edr_not_supported"]), ]
2944
2945 def build_eir(self):
2946 """
2947 Builds a list of EIR messages to wrap this frame.
2948
2949 Users of this helper must implement this method.
2950
2951 :return: List of HCI_Hdr with payloads that describe this beacon type
2952 :rtype: list[scapy.bluetooth.HCI_Hdr]
2953 """
2954 raise NotImplementedError("build_eir")
2955
2956 def build_advertising_report(self):
2957 """
2958 Builds a HCI_LE_Meta_Advertising_Report containing this frame.
2959
2960 :rtype: scapy.bluetooth.HCI_LE_Meta_Advertising_Report
2961 """
2962
2963 return HCI_LE_Meta_Advertising_Report(
2964 type=0, # Undirected
2965 atype=1, # Random address
2966 data=self.build_eir()
2967 )
2968
2969 def build_set_advertising_data(self):
2970 """Builds a HCI_Cmd_LE_Set_Advertising_Data containing this frame.
2971
2972 This includes the :class:`HCI_Hdr` and :class:`HCI_Command_Hdr` layers.
2973
2974 :rtype: scapy.bluetooth.HCI_Hdr
2975 """
2976
2977 return HCI_Hdr() / HCI_Command_Hdr() / HCI_Cmd_LE_Set_Advertising_Data(
2978 data=self.build_eir()
2979 )
2980
2981
2982###########
2983# Sockets #
2984###########
2985
2986class BluetoothSocketError(BaseException):
2987 pass
2988
2989
2990class BluetoothCommandError(BaseException):
2991 pass
2992
2993
2994class BluetoothL2CAPSocket(SuperSocket):
2995 desc = "read/write packets on a connected L2CAP socket"
2996
2997 def __init__(self, bt_address):
2998 if WINDOWS:
2999 warning("Not available on Windows")
3000 return
3001 s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW,
3002 socket.BTPROTO_L2CAP)
3003 s.connect((bt_address, 0))
3004 self.ins = self.outs = s
3005
3006 def recv(self, x=MTU):
3007 return L2CAP_CmdHdr(self.ins.recv(x))
3008
3009
3010class BluetoothRFCommSocket(BluetoothL2CAPSocket):
3011 """read/write packets on a connected RFCOMM socket"""
3012
3013 def __init__(self, bt_address, port=0):
3014 s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW,
3015 socket.BTPROTO_RFCOMM)
3016 s.connect((bt_address, port))
3017 self.ins = self.outs = s
3018
3019
3020class BluetoothHCISocket(SuperSocket):
3021 desc = "read/write on a BlueTooth HCI socket"
3022
3023 def __init__(self, iface=0x10000, type=None):
3024 if WINDOWS:
3025 warning("Not available on Windows")
3026 return
3027 s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI) # noqa: E501
3028 s.setsockopt(socket.SOL_HCI, socket.HCI_DATA_DIR, 1)
3029 s.setsockopt(socket.SOL_HCI, socket.HCI_TIME_STAMP, 1)
3030 s.setsockopt(socket.SOL_HCI, socket.HCI_FILTER, struct.pack("IIIh2x", 0xffffffff, 0xffffffff, 0xffffffff, 0)) # type mask, event mask, event mask, opcode # noqa: E501
3031 s.bind((iface,))
3032 self.ins = self.outs = s
3033# s.connect((peer,0))
3034
3035 def recv(self, x=MTU):
3036 return HCI_Hdr(self.ins.recv(x))
3037
3038
3039class sockaddr_hci(ctypes.Structure):
3040 _fields_ = [
3041 ("sin_family", ctypes.c_ushort),
3042 ("hci_dev", ctypes.c_ushort),
3043 ("hci_channel", ctypes.c_ushort),
3044 ]
3045
3046
3047class _BluetoothLibcSocket(SuperSocket):
3048 def __init__(self, socket_domain, socket_type, socket_protocol, sock_address):
3049 # type: (int, int, int, sockaddr_hci) -> None
3050 if WINDOWS:
3051 warning("Not available on Windows")
3052 return
3053 # Python socket and bind implementations do not allow us to pass down
3054 # the correct parameters. We must call libc functions directly via
3055 # ctypes.
3056 sockaddr_hcip = ctypes.POINTER(sockaddr_hci)
3057 from ctypes.util import find_library
3058 libc = ctypes.cdll.LoadLibrary(find_library("c"))
3059
3060 socket_c = libc.socket
3061 socket_c.argtypes = (ctypes.c_int, ctypes.c_int, ctypes.c_int)
3062 socket_c.restype = ctypes.c_int
3063
3064 bind = libc.bind
3065 bind.argtypes = (ctypes.c_int,
3066 ctypes.POINTER(sockaddr_hci),
3067 ctypes.c_int)
3068 bind.restype = ctypes.c_int
3069
3070 # Socket
3071 s = socket_c(socket_domain, socket_type, socket_protocol)
3072 if s < 0:
3073 raise BluetoothSocketError(
3074 f"Unable to open socket({socket_domain}, {socket_type}, "
3075 f"{socket_protocol})")
3076
3077 # Bind
3078 r = bind(s, sockaddr_hcip(sock_address), sizeof(sock_address))
3079 if r != 0:
3080 raise BluetoothSocketError("Unable to bind")
3081
3082 self.hci_fd = s
3083 self.ins = self.outs = socket.fromfd(
3084 s, socket_domain, socket_type, socket_protocol)
3085
3086 def readable(self, timeout=0):
3087 (ins, _, _) = select.select([self.ins], [], [], timeout)
3088 return len(ins) > 0
3089
3090 def flush(self):
3091 while self.readable():
3092 self.recv()
3093
3094 def close(self):
3095 if self.closed:
3096 return
3097
3098 # Properly close socket so we can free the device
3099 from ctypes.util import find_library
3100 libc = ctypes.cdll.LoadLibrary(find_library("c"))
3101
3102 close = libc.close
3103 close.restype = ctypes.c_int
3104 self.closed = True
3105 if hasattr(self, "outs"):
3106 if not hasattr(self, "ins") or self.ins != self.outs:
3107 if self.outs and (WINDOWS or self.outs.fileno() != -1):
3108 close(self.outs.fileno())
3109 if hasattr(self, "ins"):
3110 if self.ins and (WINDOWS or self.ins.fileno() != -1):
3111 close(self.ins.fileno())
3112 if hasattr(self, "hci_fd"):
3113 close(self.hci_fd)
3114
3115
3116class BluetoothUserSocket(_BluetoothLibcSocket):
3117 desc = "read/write H4 over a Bluetooth user channel"
3118
3119 def __init__(self, adapter_index=0):
3120 sa = sockaddr_hci()
3121 sa.sin_family = socket.AF_BLUETOOTH
3122 sa.hci_dev = adapter_index
3123 sa.hci_channel = HCI_CHANNEL_USER
3124 super().__init__(
3125 socket_domain=socket.AF_BLUETOOTH,
3126 socket_type=socket.SOCK_RAW,
3127 socket_protocol=socket.BTPROTO_HCI,
3128 sock_address=sa)
3129
3130 def send_command(self, cmd):
3131 opcode = cmd[HCI_Command_Hdr].opcode
3132 self.send(cmd)
3133 while True:
3134 r = self.recv()
3135 if r.type == 0x04 and r.code == 0xe and r.opcode == opcode:
3136 if r.status != 0:
3137 raise BluetoothCommandError("Command %x failed with %x" % (opcode, r.status)) # noqa: E501
3138 return r
3139
3140 def recv(self, x=MTU):
3141 return HCI_Hdr(self.ins.recv(x))
3142
3143
3144class BluetoothMonitorSocket(_BluetoothLibcSocket):
3145 desc = "Read/write over a Bluetooth monitor channel"
3146
3147 def __init__(self):
3148 sa = sockaddr_hci()
3149 sa.sin_family = socket.AF_BLUETOOTH
3150 sa.hci_dev = HCI_DEV_NONE
3151 sa.hci_channel = HCI_CHANNEL_MONITOR
3152 super().__init__(
3153 socket_domain=socket.AF_BLUETOOTH,
3154 socket_type=socket.SOCK_RAW,
3155 socket_protocol=socket.BTPROTO_HCI,
3156 sock_address=sa)
3157
3158 def recv(self, x=MTU):
3159 return HCI_Mon_Hdr(self.ins.recv(x))
3160
3161
3162conf.BTsocket = BluetoothRFCommSocket
3163
3164# Bluetooth
3165
3166
3167@conf.commands.register
3168def srbt(bt_address, pkts, inter=0.1, *args, **kargs):
3169 """send and receive using a bluetooth socket"""
3170 if "port" in kargs:
3171 s = conf.BTsocket(bt_address=bt_address, port=kargs.pop("port"))
3172 else:
3173 s = conf.BTsocket(bt_address=bt_address)
3174 a, b = sndrcv(s, pkts, inter=inter, *args, **kargs)
3175 s.close()
3176 return a, b
3177
3178
3179@conf.commands.register
3180def srbt1(bt_address, pkts, *args, **kargs):
3181 """send and receive 1 packet using a bluetooth socket"""
3182 a, b = srbt(bt_address, pkts, *args, **kargs)
3183 if len(a) > 0:
3184 return a[0][1]