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 LEMACField,
57)
58from scapy.supersocket import SuperSocket
59from scapy.sendrecv import sndrcv
60from scapy.data import MTU
61from scapy.consts import WINDOWS
62from scapy.error import warning
63
64
65############
66# Consts #
67############
68
69# From hci.h
70HCI_CHANNEL_RAW = 0
71HCI_CHANNEL_USER = 1
72HCI_CHANNEL_MONITOR = 2
73HCI_CHANNEL_CONTROL = 3
74HCI_CHANNEL_LOGGING = 4
75
76HCI_DEV_NONE = 0xffff
77
78
79##########
80# Layers #
81##########
82
83# See bluez/lib/hci.h for details
84
85# Transport layers
86
87class HCI_PHDR_Hdr(Packet):
88 name = "HCI PHDR transport layer"
89 fields_desc = [IntField("direction", 0)]
90
91
92# Real layers
93
94_bluetooth_packet_types = {
95 0: "Acknowledgement",
96 1: "Command",
97 2: "ACL Data",
98 3: "Synchronous",
99 4: "Event",
100 5: "Reserve",
101 14: "Vendor",
102 15: "Link Control"
103}
104
105_bluetooth_error_codes = {
106 0x00: "Success",
107 0x01: "Unknown HCI Command",
108 0x02: "Unknown Connection Identifier",
109 0x03: "Hardware Failure",
110 0x04: "Page Timeout",
111 0x05: "Authentication Failure",
112 0x06: "PIN or Key Missing",
113 0x07: "Memory Capacity Exceeded",
114 0x08: "Connection Timeout",
115 0x09: "Connection Limit Exceeded",
116 0x0A: "Synchronous Connection Limit To A Device Exceeded",
117 0x0B: "Connection Already Exists",
118 0x0C: "Command Disallowed",
119 0x0D: "Connection Rejected due to Limited Resources",
120 0x0E: "Connection Rejected Due To Security Reasons",
121 0x0F: "Connection Rejected due to Unacceptable BD_ADDR",
122 0x10: "Connection Accept Timeout Exceeded",
123 0x11: "Unsupported Feature or Parameter Value",
124 0x12: "Invalid HCI Command Parameters",
125 0x13: "Remote User Terminated Connection",
126 0x14: "Remote Device Terminated Connection due to Low Resources",
127 0x15: "Remote Device Terminated Connection due to Power Off",
128 0x16: "Connection Terminated By Local Host",
129 0x17: "Repeated Attempts",
130 0x18: "Pairing Not Allowed",
131 0x19: "Unknown LMP PDU",
132 0x1A: "Unsupported Remote Feature / Unsupported LMP Feature",
133 0x1B: "SCO Offset Rejected",
134 0x1C: "SCO Interval Rejected",
135 0x1D: "SCO Air Mode Rejected",
136 0x1E: "Invalid LMP Parameters / Invalid LL Parameters",
137 0x1F: "Unspecified Error",
138 0x20: "Unsupported LMP Parameter Value / Unsupported LL Parameter Value",
139 0x21: "Role Change Not Allowed",
140 0x22: "LMP Response Timeout / LL Response Timeout",
141 0x23: "LMP Error Transaction Collision / LL Procedure Collision",
142 0x24: "LMP PDU Not Allowed",
143 0x25: "Encryption Mode Not Acceptable",
144 0x26: "Link Key cannot be Changed",
145 0x27: "Requested QoS Not Supported",
146 0x28: "Instant Passed",
147 0x29: "Pairing With Unit Key Not Supported",
148 0x2A: "Different Transaction Collision",
149 0x2B: "Reserved for future use",
150 0x2C: "QoS Unacceptable Parameter",
151 0x2D: "QoS Rejected",
152 0x2E: "Channel Classification Not Supported",
153 0x2F: "Insufficient Security",
154 0x30: "Parameter Out Of Mandatory Range",
155 0x31: "Reserved for future use",
156 0x32: "Role Switch Pending",
157 0x33: "Reserved for future use",
158 0x34: "Reserved Slot Violation",
159 0x35: "Role Switch Failed",
160 0x36: "Extended Inquiry Response Too Large",
161 0x37: "Secure Simple Pairing Not Supported By Host",
162 0x38: "Host Busy - Pairing",
163 0x39: "Connection Rejected due to No Suitable Channel Found",
164 0x3A: "Controller Busy",
165 0x3B: "Unacceptable Connection Parameters",
166 0x3C: "Advertising Timeout",
167 0x3D: "Connection Terminated due to MIC Failure",
168 0x3E: "Connection Failed to be Established / Synchronization Timeout",
169 0x3F: "MAC Connection Failed",
170 0x40: "Coarse Clock Adjustment Rejected but Will Try to Adjust Using Clock"
171 " Dragging",
172 0x41: "Type0 Submap Not Defined",
173 0x42: "Unknown Advertising Identifier",
174 0x43: "Limit Reached",
175 0x44: "Operation Cancelled by Host",
176 0x45: "Packet Too Long"
177}
178
179_att_error_codes = {
180 0x01: "invalid handle",
181 0x02: "read not permitted",
182 0x03: "write not permitted",
183 0x04: "invalid pdu",
184 0x05: "insufficient auth",
185 0x06: "unsupported req",
186 0x07: "invalid offset",
187 0x08: "insufficient author",
188 0x09: "prepare queue full",
189 0x0a: "attr not found",
190 0x0b: "attr not long",
191 0x0c: "insufficient key size",
192 0x0d: "invalid value size",
193 0x0e: "unlikely",
194 0x0f: "insufficiet encrypt",
195 0x10: "unsupported gpr type",
196 0x11: "insufficient resources",
197}
198
199_bluetooth_features = [
200 '3_slot_packets',
201 '5_slot_packets',
202 'encryption',
203 'slot_offset',
204 'timing_accuracy',
205 'role_switch',
206 'hold_mode',
207 'sniff_mode',
208 'park_mode',
209 'power_control_requests',
210 'channel_quality_driven_data_rate',
211 'sco_link',
212 'hv2_packets',
213 'hv3_packets',
214 'u_law_log_synchronous_data',
215 'a_law_log_synchronous_data',
216 'cvsd_synchronous_data',
217 'paging_parameter_negotiation',
218 'power_control',
219 'transparent_synchronous_data',
220 'flow_control_lag_4_bit0',
221 'flow_control_lag_4_bit1',
222 'flow_control_lag_4_bit2',
223 'broadband_encryption',
224 'cvsd_synchronous_data',
225 'edr_acl_2_mbps_mode',
226 'edr_acl_3_mbps_mode',
227 'enhanced_inquiry_scan',
228 'interlaced_inquiry_scan',
229 'interlaced_page_scan',
230 'rssi_with_inquiry_results',
231 'ev3_packets',
232 'ev4_packets',
233 'ev5_packets',
234 'reserved',
235 'afh_capable_slave',
236 'afh_classification_slave',
237 'br_edr_not_supported',
238 'le_supported_controller',
239 '3_slot_edr_acl_packets',
240 '5_slot_edr_acl_packets',
241 'sniff_subrating',
242 'pause_encryption',
243 'afh_capable_master',
244 'afh_classification_master',
245 'edr_esco_2_mbps_mode',
246 'edr_esco_3_mbps_mode',
247 '3_slot_edr_esco_packets',
248 'extended_inquiry_response',
249 'simultaneous_le_and_br_edr_to_same_device_capable_controller',
250 'reserved2',
251 'secure_simple_pairing',
252 'encapsulated_pdu',
253 'erroneous_data_reporting',
254 'non_flushable_packet_boundary_flag',
255 'reserved3',
256 'link_supervision_timeout_changed_event',
257 'inquiry_tx_power_level',
258 'enhanced_power_control',
259 'reserved4_bit0',
260 'reserved4_bit1',
261 'reserved4_bit2',
262 'reserved4_bit3',
263 'extended_features',
264]
265
266
267class HCI_Hdr(Packet):
268 name = "HCI header"
269 fields_desc = [ByteEnumField("type", 2, _bluetooth_packet_types)]
270
271 def mysummary(self):
272 return self.sprintf("HCI %type%")
273
274
275class HCI_ACL_Hdr(Packet):
276 name = "HCI ACL header"
277 fields_desc = [BitField("BC", 0, 2, tot_size=-2),
278 BitField("PB", 0, 2),
279 BitField("handle", 0, 12, end_tot_size=-2),
280 LEShortField("len", None), ]
281
282 def post_build(self, p, pay):
283 p += pay
284 if self.len is None:
285 p = p[:2] + struct.pack("<H", len(pay)) + p[4:]
286 return p
287
288
289class L2CAP_Hdr(Packet):
290 name = "L2CAP header"
291 fields_desc = [LEShortField("len", None),
292 LEShortEnumField("cid", 0, {1: "control", 4: "attribute"}), ] # noqa: E501
293
294 def post_build(self, p, pay):
295 p += pay
296 if self.len is None:
297 p = struct.pack("<H", len(pay)) + p[2:]
298 return p
299
300
301class L2CAP_CmdHdr(Packet):
302 name = "L2CAP command header"
303 fields_desc = [
304 ByteEnumField("code", 8, {1: "rej",
305 2: "conn_req",
306 3: "conn_resp",
307 4: "conf_req",
308 5: "conf_resp",
309 6: "disconn_req",
310 7: "disconn_resp",
311 8: "echo_req",
312 9: "echo_resp",
313 10: "info_req",
314 11: "info_resp",
315 12: "create_channel_req",
316 13: "create_channel_resp",
317 14: "move_channel_req",
318 15: "move_channel_resp",
319 16: "move_channel_confirm_req",
320 17: "move_channel_confirm_resp",
321 18: "conn_param_update_req",
322 19: "conn_param_update_resp",
323 20: "LE_credit_based_conn_req",
324 21: "LE_credit_based_conn_resp",
325 22: "flow_control_credit_ind",
326 23: "credit_based_conn_req",
327 24: "credit_based_conn_resp",
328 25: "credit_based_reconf_req",
329 26: "credit_based_reconf_resp"}),
330 ByteField("id", 0),
331 LEShortField("len", None)]
332
333 def post_build(self, p, pay):
334 p += pay
335 if self.len is None:
336 p = p[:2] + struct.pack("<H", len(pay)) + p[4:]
337 return p
338
339 def answers(self, other):
340 if other.id == self.id:
341 if self.code == 1:
342 return 1
343 if other.code in [2, 4, 6, 8, 10, 18] and self.code == other.code + 1: # noqa: E501
344 if other.code == 8:
345 return 1
346 return self.payload.answers(other.payload)
347 return 0
348
349
350class L2CAP_ConnReq(Packet):
351 name = "L2CAP Conn Req"
352 fields_desc = [LEShortEnumField("psm", 0, {1: "SDP",
353 3: "RFCOMM",
354 5: "TCS-BIN",
355 7: "TCS-BIN-CORDLESS",
356 15: "BNEP",
357 17: "HID-Control",
358 19: "HID-Interrupt",
359 21: "UPnP",
360 23: "AVCTP-Control",
361 25: "AVDTP",
362 27: "AVCTP-Browsing",
363 29: "UDI_C-Plane",
364 31: "ATT",
365 33: "3DSP",
366 35: "IPSP",
367 37: "OTS"}),
368 LEShortField("scid", 0),
369 ]
370
371
372class L2CAP_ConnResp(Packet):
373 name = "L2CAP Conn Resp"
374 fields_desc = [LEShortField("dcid", 0),
375 LEShortField("scid", 0),
376 LEShortEnumField("result", 0, ["success", "pend", "cr_bad_psm", "cr_sec_block", "cr_no_mem", "reserved", "cr_inval_scid", "cr_scid_in_use"]), # noqa: E501
377 LEShortEnumField("status", 0, ["no_info", "authen_pend", "author_pend", "reserved"]), # noqa: E501
378 ]
379
380 def answers(self, other):
381 # dcid Resp == scid Req. Therefore compare SCIDs
382 return isinstance(other, L2CAP_ConnReq) and self.scid == other.scid
383
384
385class L2CAP_CmdRej(Packet):
386 name = "L2CAP Command Rej"
387 fields_desc = [LEShortField("reason", 0),
388 ]
389
390
391class L2CAP_ConfReq(Packet):
392 name = "L2CAP Conf Req"
393 fields_desc = [LEShortField("dcid", 0),
394 LEShortField("flags", 0),
395 ]
396
397
398class L2CAP_ConfResp(Packet):
399 name = "L2CAP Conf Resp"
400 fields_desc = [LEShortField("scid", 0),
401 LEShortField("flags", 0),
402 LEShortEnumField("result", 0, ["success", "unaccept", "reject", "unknown"]), # noqa: E501
403 ]
404
405 def answers(self, other):
406 # Req and Resp contain either the SCID or the DCID.
407 return isinstance(other, L2CAP_ConfReq)
408
409
410class L2CAP_DisconnReq(Packet):
411 name = "L2CAP Disconn Req"
412 fields_desc = [LEShortField("dcid", 0),
413 LEShortField("scid", 0), ]
414
415
416class L2CAP_DisconnResp(Packet):
417 name = "L2CAP Disconn Resp"
418 fields_desc = [LEShortField("dcid", 0),
419 LEShortField("scid", 0), ]
420
421 def answers(self, other):
422 return self.scid == other.scid
423
424
425class L2CAP_EchoReq(Packet):
426 name = "L2CAP Echo Req"
427 fields_desc = [StrField("data", ""), ]
428
429
430class L2CAP_EchoResp(Packet):
431 name = "L2CAP Echo Resp"
432 fields_desc = [StrField("data", ""), ]
433
434
435class L2CAP_InfoReq(Packet):
436 name = "L2CAP Info Req"
437 fields_desc = [LEShortEnumField("type", 0, {1: "CL_MTU", 2: "FEAT_MASK"}),
438 StrField("data", "")
439 ]
440
441
442class L2CAP_InfoResp(Packet):
443 name = "L2CAP Info Resp"
444 fields_desc = [LEShortField("type", 0),
445 LEShortEnumField("result", 0, ["success", "not_supp"]),
446 StrField("data", ""), ]
447
448 def answers(self, other):
449 return self.type == other.type
450
451
452class L2CAP_Create_Channel_Request(Packet):
453 name = "L2CAP Create Channel Request"
454 fields_desc = [LEShortEnumField("psm", 0, {1: "SDP",
455 3: "RFCOMM",
456 5: "TCS-BIN",
457 7: "TCS-BIN-CORDLESS",
458 15: "BNEP",
459 17: "HID-Control",
460 19: "HID-Interrupt",
461 21: "UPnP",
462 23: "AVCTP-Control",
463 25: "AVDTP",
464 27: "AVCTP-Browsing",
465 29: "UDI_C-Plane",
466 31: "ATT",
467 33: "3DSP",
468 35: "IPSP",
469 37: "OTS"}),
470 LEShortField("scid", 0),
471 ByteField("controller_id", 0), ]
472
473
474class L2CAP_Create_Channel_Response(Packet):
475 name = "L2CAP Create Channel Response"
476 fields_desc = [LEShortField("dcid", 0),
477 LEShortField("scid", 0),
478 LEShortEnumField("result", 0, {
479 0: "Connection successful",
480 1: "Connection pending",
481 2: "Connection refused - PSM not supported",
482 3: "Connection refused - security block",
483 4: "Connection refused - no resources available",
484 5: "Connection refused - cont_ID not supported",
485 6: "Connection refused - invalid scid",
486 7: "Connection refused - scid already allocated"}),
487 LEShortEnumField("status", 0, {
488 0: "No further information available",
489 1: "Authentication pending",
490 2: "Authorization pending"}), ]
491
492
493class L2CAP_Move_Channel_Request(Packet):
494 name = "L2CAP Move Channel Request"
495 fields_desc = [LEShortField("icid", 0),
496 ByteField("dest_controller_id", 0), ]
497
498
499class L2CAP_Move_Channel_Response(Packet):
500 name = "L2CAP Move Channel Response"
501 fields_desc = [LEShortField("icid", 0),
502 LEShortEnumField("result", 0, {
503 0: "Move success",
504 1: "Move pending",
505 2: "Move refused - Cont_ID not supported",
506 3: "Move refused - Cont_ID is same as old one",
507 4: "Move refused - Configuration not supported",
508 5: "Move refused - Move channel collision",
509 6: "Move refused - Not allowed to be moved"}), ]
510
511
512class L2CAP_Move_Channel_Confirmation_Request(Packet):
513 name = "L2CAP Move Channel Confirmation Request"
514 fields_desc = [LEShortField("icid", 0),
515 LEShortEnumField("result", 0, {0: "Move success",
516 1: "Move failure"}), ]
517
518
519class L2CAP_Move_Channel_Confirmation_Response(Packet):
520 name = "L2CAP Move Channel Confirmation Response"
521 fields_desc = [LEShortField("icid", 0), ]
522
523
524class L2CAP_Connection_Parameter_Update_Request(Packet):
525 name = "L2CAP Connection Parameter Update Request"
526 fields_desc = [LEShortField("min_interval", 0),
527 LEShortField("max_interval", 0),
528 LEShortField("slave_latency", 0),
529 LEShortField("timeout_mult", 0), ]
530
531
532class L2CAP_Connection_Parameter_Update_Response(Packet):
533 name = "L2CAP Connection Parameter Update Response"
534 fields_desc = [LEShortField("move_result", 0), ]
535
536
537class L2CAP_LE_Credit_Based_Connection_Request(Packet):
538 name = "L2CAP LE Credit Based Connection Request"
539 fields_desc = [LEShortField("spsm", 0),
540 LEShortField("scid", 0),
541 LEShortField("mtu", 0),
542 LEShortField("mps", 0),
543 LEShortField("initial_credits", 0), ]
544
545
546class L2CAP_LE_Credit_Based_Connection_Response(Packet):
547 name = "L2CAP LE Credit Based Connection Response"
548 fields_desc = [LEShortField("dcid", 0),
549 LEShortField("mtu", 0),
550 LEShortField("mps", 0),
551 LEShortField("initial_credits", 0),
552 LEShortEnumField("result", 0, {
553 0: "Connection successful",
554 2: "Connection refused - SPSM not supported",
555 4: "Connection refused - no resources available",
556 5: "Connection refused - authentication error",
557 6: "Connection refused - authorization error",
558 7: "Connection refused - encrypt_key size error",
559 8: "Connection refused - insufficient encryption",
560 9: "Connection refused - invalid scid",
561 10: "Connection refused - scid already allocated",
562 11: "Connection refused - parameters error"}), ]
563
564
565class L2CAP_Flow_Control_Credit_Ind(Packet):
566 name = "L2CAP Flow Control Credit Ind"
567 fields_desc = [LEShortField("cid", 0),
568 LEShortField("credits", 0), ]
569
570
571class L2CAP_Credit_Based_Connection_Request(Packet):
572 name = "L2CAP Credit Based Connection Request"
573 fields_desc = [LEShortField("spsm", 0),
574 LEShortField("mtu", 0),
575 LEShortField("mps", 0),
576 LEShortField("initial_credits", 0),
577 LEShortField("scid", 0), ]
578
579
580class L2CAP_Credit_Based_Connection_Response(Packet):
581 name = "L2CAP Credit Based Connection Response"
582 fields_desc = [LEShortField("mtu", 0),
583 LEShortField("mps", 0),
584 LEShortField("initial_credits", 0),
585 LEShortEnumField("result", 0, {
586 0: "All connection successful",
587 2: "All connection refused - SPSM not supported",
588 4: "Some connections refused - resources error",
589 5: "All connection refused - authentication error",
590 6: "All connection refused - authorization error",
591 7: "All connection refused - encrypt_key size error",
592 8: "All connection refused - encryption error",
593 9: "Some connection refused - invalid scid",
594 10: "Some connection refused - scid already allocated",
595 11: "All Connection refused - unacceptable parameters",
596 12: "All connections refused - invalid parameters"}),
597 LEShortField("dcid", 0), ]
598
599
600class L2CAP_Credit_Based_Reconfigure_Request(Packet):
601 name = "L2CAP Credit Based Reconfigure Request"
602 fields_desc = [LEShortField("mtu", 0),
603 LEShortField("mps", 0),
604 LEShortField("dcid", 0), ]
605
606
607class L2CAP_Credit_Based_Reconfigure_Response(Packet):
608 name = "L2CAP Credit Based Reconfigure Response"
609 fields_desc = [LEShortEnumField("result", 0, {
610 0: "Reconfig successful",
611 1: "Reconfig failed - MTU size reduction not allowed",
612 2: "Reconfig failed - MPS size reduction not allowed",
613 3: "Reconfig failed - one or more dcids invalid",
614 4: "Reconfig failed - unacceptable parameters"}), ]
615
616
617class ATT_Hdr(Packet):
618 name = "ATT header"
619 fields_desc = [XByteField("opcode", None), ]
620
621
622class ATT_Handle(Packet):
623 name = "ATT Short Handle"
624 fields_desc = [XLEShortField("handle", 0),
625 XLEShortField("value", 0)]
626
627 def extract_padding(self, s):
628 return b'', s
629
630
631class ATT_Handle_UUID128(Packet):
632 name = "ATT Handle (UUID 128)"
633 fields_desc = [XLEShortField("handle", 0),
634 UUIDField("value", None, uuid_fmt=UUIDField.FORMAT_REV)]
635
636 def extract_padding(self, s):
637 return b'', s
638
639
640class ATT_Error_Response(Packet):
641 name = "Error Response"
642 fields_desc = [XByteField("request", 0),
643 LEShortField("handle", 0),
644 ByteEnumField("ecode", 0, _att_error_codes), ]
645
646
647class ATT_Exchange_MTU_Request(Packet):
648 name = "Exchange MTU Request"
649 fields_desc = [LEShortField("mtu", 0), ]
650
651
652class ATT_Exchange_MTU_Response(Packet):
653 name = "Exchange MTU Response"
654 fields_desc = [LEShortField("mtu", 0), ]
655
656
657class ATT_Find_Information_Request(Packet):
658 name = "Find Information Request"
659 fields_desc = [XLEShortField("start", 0x0000),
660 XLEShortField("end", 0xffff), ]
661
662
663class ATT_Find_Information_Response(Packet):
664 name = "Find Information Response"
665 fields_desc = [
666 XByteField("format", 1),
667 MultipleTypeField(
668 [
669 (PacketListField("handles", [], ATT_Handle),
670 lambda pkt: pkt.format == 1),
671 (PacketListField("handles", [], ATT_Handle_UUID128),
672 lambda pkt: pkt.format == 2),
673 ],
674 StrFixedLenField("handles", "", length=0)
675 )
676 ]
677
678
679class ATT_Find_By_Type_Value_Request(Packet):
680 name = "Find By Type Value Request"
681 fields_desc = [XLEShortField("start", 0x0001),
682 XLEShortField("end", 0xffff),
683 XLEShortField("uuid", None),
684 StrField("data", ""), ]
685
686
687class ATT_Find_By_Type_Value_Response(Packet):
688 name = "Find By Type Value Response"
689 fields_desc = [PacketListField("handles", [], ATT_Handle)]
690
691
692class ATT_Read_By_Type_Request_128bit(Packet):
693 name = "Read By Type Request"
694 fields_desc = [XLEShortField("start", 0x0001),
695 XLEShortField("end", 0xffff),
696 XLELongField("uuid1", None),
697 XLELongField("uuid2", None)]
698
699 @classmethod
700 def dispatch_hook(cls, _pkt=None, *args, **kargs):
701 if _pkt and len(_pkt) == 6:
702 return ATT_Read_By_Type_Request
703 return ATT_Read_By_Type_Request_128bit
704
705
706class ATT_Read_By_Type_Request(Packet):
707 name = "Read By Type Request"
708 fields_desc = [XLEShortField("start", 0x0001),
709 XLEShortField("end", 0xffff),
710 XLEShortField("uuid", None)]
711
712
713class ATT_Handle_Variable(Packet):
714 __slots__ = ["val_length"]
715 fields_desc = [XLEShortField("handle", 0),
716 XStrLenField(
717 "value", 0,
718 length_from=lambda pkt: pkt.val_length)]
719
720 def __init__(self, _pkt=b"", val_length=2, **kwargs):
721 self.val_length = val_length
722 Packet.__init__(self, _pkt, **kwargs)
723
724 def extract_padding(self, s):
725 return b"", s
726
727
728class ATT_Read_By_Type_Response(Packet):
729 name = "Read By Type Response"
730 fields_desc = [ByteField("len", 4),
731 PacketListField(
732 "handles", [],
733 next_cls_cb=lambda pkt, *args: (
734 pkt._next_cls_cb(pkt, *args)
735 ))]
736
737 @classmethod
738 def _next_cls_cb(cls, pkt, lst, p, remain):
739 if len(remain) >= pkt.len:
740 return functools.partial(
741 ATT_Handle_Variable,
742 val_length=pkt.len - 2
743 )
744 return None
745
746
747class ATT_Read_Request(Packet):
748 name = "Read Request"
749 fields_desc = [XLEShortField("gatt_handle", 0), ]
750
751
752class ATT_Read_Response(Packet):
753 name = "Read Response"
754 fields_desc = [StrField("value", "")]
755
756
757class ATT_Read_Multiple_Request(Packet):
758 name = "Read Multiple Request"
759 fields_desc = [FieldListField("handles", [], XLEShortField("", 0))]
760
761
762class ATT_Read_Multiple_Response(Packet):
763 name = "Read Multiple Response"
764 fields_desc = [StrField("values", "")]
765
766
767class ATT_Read_By_Group_Type_Request(Packet):
768 name = "Read By Group Type Request"
769 fields_desc = [XLEShortField("start", 0),
770 XLEShortField("end", 0xffff),
771 XLEShortField("uuid", 0), ]
772
773
774class ATT_Read_By_Group_Type_Response(Packet):
775 name = "Read By Group Type Response"
776 fields_desc = [XByteField("length", 0),
777 StrField("data", ""), ]
778
779
780class ATT_Write_Request(Packet):
781 name = "Write Request"
782 fields_desc = [XLEShortField("gatt_handle", 0),
783 StrField("data", ""), ]
784
785
786class ATT_Write_Command(Packet):
787 name = "Write Request"
788 fields_desc = [XLEShortField("gatt_handle", 0),
789 StrField("data", ""), ]
790
791
792class ATT_Write_Response(Packet):
793 name = "Write Response"
794
795
796class ATT_Prepare_Write_Request(Packet):
797 name = "Prepare Write Request"
798 fields_desc = [
799 XLEShortField("gatt_handle", 0),
800 LEShortField("offset", 0),
801 StrField("data", "")
802 ]
803
804
805class ATT_Prepare_Write_Response(ATT_Prepare_Write_Request):
806 name = "Prepare Write Response"
807
808
809class ATT_Handle_Value_Notification(Packet):
810 name = "Handle Value Notification"
811 fields_desc = [XLEShortField("gatt_handle", 0),
812 StrField("value", ""), ]
813
814
815class ATT_Execute_Write_Request(Packet):
816 name = "Execute Write Request"
817 fields_desc = [
818 ByteEnumField("flags", 1, {
819 0: "Cancel all prepared writes",
820 1: "Immediately write all pending prepared values",
821 }),
822 ]
823
824
825class ATT_Execute_Write_Response(Packet):
826 name = "Execute Write Response"
827
828
829class ATT_Read_Blob_Request(Packet):
830 name = "Read Blob Request"
831 fields_desc = [
832 XLEShortField("gatt_handle", 0),
833 LEShortField("offset", 0)
834 ]
835
836
837class ATT_Read_Blob_Response(Packet):
838 name = "Read Blob Response"
839 fields_desc = [
840 StrField("value", "")
841 ]
842
843
844class ATT_Handle_Value_Indication(Packet):
845 name = "Handle Value Indication"
846 fields_desc = [
847 XLEShortField("gatt_handle", 0),
848 StrField("value", ""),
849 ]
850
851
852class SM_Hdr(Packet):
853 name = "SM header"
854 fields_desc = [ByteField("sm_command", None)]
855
856
857class SM_Pairing_Request(Packet):
858 name = "Pairing Request"
859 fields_desc = [ByteEnumField("iocap", 3, {0: "DisplayOnly", 1: "DisplayYesNo", 2: "KeyboardOnly", 3: "NoInputNoOutput", 4: "KeyboardDisplay"}), # noqa: E501
860 ByteEnumField("oob", 0, {0: "Not Present", 1: "Present (from remote device)"}), # noqa: E501
861 BitField("authentication", 0, 8),
862 ByteField("max_key_size", 16),
863 ByteField("initiator_key_distribution", 0),
864 ByteField("responder_key_distribution", 0), ]
865
866
867class SM_Pairing_Response(Packet):
868 name = "Pairing Response"
869 fields_desc = [ByteEnumField("iocap", 3, {0: "DisplayOnly", 1: "DisplayYesNo", 2: "KeyboardOnly", 3: "NoInputNoOutput", 4: "KeyboardDisplay"}), # noqa: E501
870 ByteEnumField("oob", 0, {0: "Not Present", 1: "Present (from remote device)"}), # noqa: E501
871 BitField("authentication", 0, 8),
872 ByteField("max_key_size", 16),
873 ByteField("initiator_key_distribution", 0),
874 ByteField("responder_key_distribution", 0), ]
875
876
877class SM_Confirm(Packet):
878 name = "Pairing Confirm"
879 fields_desc = [StrFixedLenField("confirm", b'\x00' * 16, 16)]
880
881
882class SM_Random(Packet):
883 name = "Pairing Random"
884 fields_desc = [StrFixedLenField("random", b'\x00' * 16, 16)]
885
886
887class SM_Failed(Packet):
888 name = "Pairing Failed"
889 fields_desc = [XByteField("reason", 0)]
890
891
892class SM_Encryption_Information(Packet):
893 name = "Encryption Information"
894 fields_desc = [StrFixedLenField("ltk", b"\x00" * 16, 16), ]
895
896
897class SM_Master_Identification(Packet):
898 name = "Master Identification"
899 fields_desc = [XLEShortField("ediv", 0),
900 StrFixedLenField("rand", b'\x00' * 8, 8), ]
901
902
903class SM_Identity_Information(Packet):
904 name = "Identity Information"
905 fields_desc = [StrFixedLenField("irk", b'\x00' * 16, 16), ]
906
907
908class SM_Identity_Address_Information(Packet):
909 name = "Identity Address Information"
910 fields_desc = [ByteEnumField("atype", 0, {0: "public"}),
911 LEMACField("address", None), ]
912
913
914class SM_Signing_Information(Packet):
915 name = "Signing Information"
916 fields_desc = [StrFixedLenField("csrk", b'\x00' * 16, 16), ]
917
918
919class SM_Public_Key(Packet):
920 name = "Public Key"
921 fields_desc = [StrFixedLenField("key_x", b'\x00' * 32, 32),
922 StrFixedLenField("key_y", b'\x00' * 32, 32), ]
923
924
925class SM_DHKey_Check(Packet):
926 name = "DHKey Check"
927 fields_desc = [StrFixedLenField("dhkey_check", b'\x00' * 16, 16), ]
928
929
930class EIR_Hdr(Packet):
931 name = "EIR Header"
932 fields_desc = [
933 LenField("len", None, fmt="B", adjust=lambda x: x + 1), # Add bytes mark # noqa: E501
934 # https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile
935 ByteEnumField("type", 0, {
936 0x01: "flags",
937 0x02: "incomplete_list_16_bit_svc_uuids",
938 0x03: "complete_list_16_bit_svc_uuids",
939 0x04: "incomplete_list_32_bit_svc_uuids",
940 0x05: "complete_list_32_bit_svc_uuids",
941 0x06: "incomplete_list_128_bit_svc_uuids",
942 0x07: "complete_list_128_bit_svc_uuids",
943 0x08: "shortened_local_name",
944 0x09: "complete_local_name",
945 0x0a: "tx_power_level",
946 0x0d: "class_of_device",
947 0x0e: "simple_pairing_hash",
948 0x0f: "simple_pairing_rand",
949
950 0x10: "sec_mgr_tk",
951 0x11: "sec_mgr_oob_flags",
952 0x12: "slave_conn_intvl_range",
953 0x14: "list_16_bit_svc_sollication_uuids",
954 0x15: "list_128_bit_svc_sollication_uuids",
955 0x16: "svc_data_16_bit_uuid",
956 0x17: "pub_target_addr",
957 0x18: "rand_target_addr",
958 0x19: "appearance",
959 0x1a: "adv_intvl",
960 0x1b: "le_addr",
961 0x1c: "le_role",
962 0x1d: "simple_pairing_hash_256",
963 0x1e: "simple_pairing_rand_256",
964 0x1f: "list_32_bit_svc_sollication_uuids",
965
966 0x20: "svc_data_32_bit_uuid",
967 0x21: "svc_data_128_bit_uuid",
968 0x22: "sec_conn_confirm",
969 0x23: "sec_conn_rand",
970 0x24: "uri",
971 0x25: "indoor_positioning",
972 0x26: "transport_discovery",
973 0x27: "le_supported_features",
974 0x28: "channel_map_update",
975 0x29: "mesh_pb_adv",
976 0x2a: "mesh_message",
977 0x2b: "mesh_beacon",
978
979 0x3d: "3d_information",
980
981 0xff: "mfg_specific_data",
982 }),
983 ]
984
985 def mysummary(self):
986 return self.sprintf("EIR %type%")
987
988 def guess_payload_class(self, payload):
989 if self.len == 0:
990 # For Extended_Inquiry_Response, stop when len=0
991 return conf.padding_layer
992 return super(EIR_Hdr, self).guess_payload_class(payload)
993
994
995class EIR_Element(Packet):
996 name = "EIR Element"
997
998 def extract_padding(self, s):
999 # Needed to end each EIR_Element packet and make PacketListField work.
1000 return b'', s
1001
1002 @staticmethod
1003 def length_from(pkt):
1004 if not pkt.underlayer:
1005 warning("Missing an upper-layer")
1006 return 0
1007 # 'type' byte is included in the length, so subtract 1:
1008 return pkt.underlayer.len - 1
1009
1010
1011class EIR_Raw(EIR_Element):
1012 name = "EIR Raw"
1013 fields_desc = [
1014 StrLenField("data", "", length_from=EIR_Element.length_from)
1015 ]
1016
1017
1018class EIR_Flags(EIR_Element):
1019 name = "Flags"
1020 fields_desc = [
1021 FlagsField("flags", 0x2, 8,
1022 ["limited_disc_mode", "general_disc_mode",
1023 "br_edr_not_supported", "simul_le_br_edr_ctrl",
1024 "simul_le_br_edr_host"] + 3 * ["reserved"])
1025 ]
1026
1027
1028class EIR_CompleteList16BitServiceUUIDs(EIR_Element):
1029 name = "Complete list of 16-bit service UUIDs"
1030 fields_desc = [
1031 # https://www.bluetooth.com/specifications/assigned-numbers/16-bit-uuids-for-members
1032 FieldListField("svc_uuids", None, XLEShortField("uuid", 0),
1033 length_from=EIR_Element.length_from)
1034 ]
1035
1036
1037class EIR_IncompleteList16BitServiceUUIDs(EIR_CompleteList16BitServiceUUIDs):
1038 name = "Incomplete list of 16-bit service UUIDs"
1039
1040
1041class EIR_CompleteList128BitServiceUUIDs(EIR_Element):
1042 name = "Complete list of 128-bit service UUIDs"
1043 fields_desc = [
1044 FieldListField("svc_uuids", None,
1045 UUIDField("uuid", None, uuid_fmt=UUIDField.FORMAT_REV),
1046 length_from=EIR_Element.length_from)
1047 ]
1048
1049
1050class EIR_IncompleteList128BitServiceUUIDs(EIR_CompleteList128BitServiceUUIDs):
1051 name = "Incomplete list of 128-bit service UUIDs"
1052
1053
1054class EIR_CompleteLocalName(EIR_Element):
1055 name = "Complete Local Name"
1056 fields_desc = [
1057 StrLenField("local_name", "", length_from=EIR_Element.length_from)
1058 ]
1059
1060
1061class EIR_ShortenedLocalName(EIR_CompleteLocalName):
1062 name = "Shortened Local Name"
1063
1064
1065class EIR_TX_Power_Level(EIR_Element):
1066 name = "TX Power Level"
1067 fields_desc = [SignedByteField("level", 0)]
1068
1069
1070class EIR_Manufacturer_Specific_Data(EIR_Element):
1071 name = "EIR Manufacturer Specific Data"
1072 fields_desc = [
1073 # https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers
1074 XLEShortField("company_id", None),
1075 ]
1076
1077 registered_magic_payloads = {}
1078
1079 @classmethod
1080 def register_magic_payload(cls, payload_cls, magic_check=None):
1081 """
1082 Registers a payload type that uses magic data.
1083
1084 Traditional payloads require registration of a Bluetooth Company ID
1085 (requires company membership of the Bluetooth SIG), or a Bluetooth
1086 Short UUID (requires a once-off payment).
1087
1088 There are alternatives which don't require registration (such as
1089 128-bit UUIDs), but the biggest consumer of energy in a beacon is the
1090 radio -- so the energy consumption of a beacon is proportional to the
1091 number of bytes in a beacon frame.
1092
1093 Some beacon formats side-step this issue by using the Company ID of
1094 their beacon hardware manufacturer, and adding a "magic data sequence"
1095 at the start of the Manufacturer Specific Data field.
1096
1097 Examples of this are AltBeacon and GeoBeacon.
1098
1099 For an example of this method in use, see ``scapy.contrib.altbeacon``.
1100
1101 :param Type[scapy.packet.Packet] payload_cls:
1102 A reference to a Packet subclass to register as a payload.
1103 :param Callable[[bytes], bool] magic_check:
1104 (optional) callable to use to if a payload should be associated
1105 with this type. If not supplied, ``payload_cls.magic_check`` is
1106 used instead.
1107 :raises TypeError: If ``magic_check`` is not specified,
1108 and ``payload_cls.magic_check`` is not implemented.
1109 """
1110 if magic_check is None:
1111 if hasattr(payload_cls, "magic_check"):
1112 magic_check = payload_cls.magic_check
1113 else:
1114 raise TypeError("magic_check not specified, and {} has no "
1115 "attribute magic_check".format(payload_cls))
1116
1117 cls.registered_magic_payloads[payload_cls] = magic_check
1118
1119 def default_payload_class(self, payload):
1120 for cls, check in (
1121 EIR_Manufacturer_Specific_Data.registered_magic_payloads.items()
1122 ):
1123 if check(payload):
1124 return cls
1125
1126 return Packet.default_payload_class(self, payload)
1127
1128 def extract_padding(self, s):
1129 # Needed to end each EIR_Element packet and make PacketListField work.
1130 plen = EIR_Element.length_from(self) - 2
1131 return s[:plen], s[plen:]
1132
1133
1134class EIR_Device_ID(EIR_Element):
1135 name = "Device ID"
1136 fields_desc = [
1137 XLEShortField("vendor_id_source", 0),
1138 XLEShortField("vendor_id", 0),
1139 XLEShortField("product_id", 0),
1140 XLEShortField("version", 0),
1141 ]
1142
1143
1144class EIR_ServiceData16BitUUID(EIR_Element):
1145 name = "EIR Service Data - 16-bit UUID"
1146 fields_desc = [
1147 # https://www.bluetooth.com/specifications/assigned-numbers/16-bit-uuids-for-members
1148 XLEShortField("svc_uuid", None),
1149 ]
1150
1151 def extract_padding(self, s):
1152 # Needed to end each EIR_Element packet and make PacketListField work.
1153 plen = EIR_Element.length_from(self) - 2
1154 return s[:plen], s[plen:]
1155
1156
1157class HCI_Command_Hdr(Packet):
1158 name = "HCI Command header"
1159 fields_desc = [XBitField("ogf", 0, 6, tot_size=-2),
1160 XBitField("ocf", 0, 10, end_tot_size=-2),
1161 LenField("len", None, fmt="B"), ]
1162
1163 def answers(self, other):
1164 return False
1165
1166 @property
1167 def opcode(self):
1168 return (self.ogf << 10) + self.ocf
1169
1170 def post_build(self, p, pay):
1171 p += pay
1172 if self.len is None:
1173 p = p[:2] + struct.pack("B", len(pay)) + p[3:]
1174 return p
1175
1176
1177# BUETOOTH CORE SPECIFICATION 5.4 | Vol 3, Part C
1178# 8 EXTENDED INQUIRY RESPONSE
1179
1180class HCI_Extended_Inquiry_Response(Packet):
1181 fields_desc = [
1182 PadField(
1183 PacketListField(
1184 "eir_data", [],
1185 next_cls_cb=lambda *args: (
1186 (not args[2] or args[2].len != 0) and EIR_Hdr or conf.raw_layer
1187 )
1188 ),
1189 align=31, padwith=b"\0",
1190 ),
1191 ]
1192
1193
1194# BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E
1195# 7 HCI COMMANDS AND EVENTS
1196# 7.1 LINK CONTROL COMMANDS, the OGF is defined as 0x01
1197
1198
1199class HCI_Cmd_Inquiry(Packet):
1200 """
1201
1202 7.1.1 Inquiry command
1203
1204 """
1205
1206 name = "HCI_Inquiry"
1207 fields_desc = [XLE3BytesField("lap", 0x9E8B33),
1208 ByteField("inquiry_length", 0),
1209 ByteField("num_responses", 0)]
1210
1211
1212class HCI_Cmd_Inquiry_Cancel(Packet):
1213 """
1214
1215 7.1.2 Inquiry Cancel command
1216
1217 """
1218
1219 name = "HCI_Inquiry_Cancel"
1220
1221
1222class HCI_Cmd_Periodic_Inquiry_Mode(Packet):
1223 """
1224
1225 7.1.3 Periodic Inquiry Mode command
1226
1227 """
1228
1229 name = "HCI_Periodic_Inquiry_Mode"
1230 fields_desc = [LEShortField("max_period_length", 0x0003),
1231 LEShortField("min_period_length", 0x0002),
1232 XLE3BytesField("lap", 0x9E8B33),
1233 ByteField("inquiry_length", 0),
1234 ByteField("num_responses", 0)]
1235
1236
1237class HCI_Cmd_Exit_Peiodic_Inquiry_Mode(Packet):
1238 """
1239
1240 7.1.4 Exit Periodic Inquiry Mode command
1241
1242 """
1243
1244 name = "HCI_Exit_Periodic_Inquiry_Mode"
1245
1246
1247class HCI_Cmd_Create_Connection(Packet):
1248 """
1249
1250 7.1.5 Create Connection command
1251
1252 """
1253
1254 name = "HCI_Create_Connection"
1255 fields_desc = [LEMACField("bd_addr", None),
1256 LEShortField("packet_type", 0xcc18),
1257 ByteField("page_scan_repetition_mode", 0x02),
1258 ByteField("reserved", 0x0),
1259 LEShortField("clock_offset", 0x0),
1260 ByteField("allow_role_switch", 0x1), ]
1261
1262
1263class HCI_Cmd_Disconnect(Packet):
1264 """
1265
1266 7.1.6 Disconnect command
1267
1268 """
1269
1270 name = "HCI_Disconnect"
1271 fields_desc = [XLEShortField("handle", 0),
1272 ByteField("reason", 0x13), ]
1273
1274
1275class HCI_Cmd_Create_Connection_Cancel(Packet):
1276 """
1277
1278 7.1.7 Create Connection Cancel command
1279
1280 """
1281
1282 name = "HCI_Create_Connection_Cancel"
1283 fields_desc = [LEMACField("bd_addr", None), ]
1284
1285
1286class HCI_Cmd_Accept_Connection_Request(Packet):
1287 """
1288
1289 7.1.8 Accept Connection Request command
1290
1291 """
1292
1293 name = "HCI_Accept_Connection_Request"
1294 fields_desc = [LEMACField("bd_addr", None),
1295 ByteField("role", 0x1), ]
1296
1297
1298class HCI_Cmd_Reject_Connection_Response(Packet):
1299 """
1300
1301 7.1.9 Reject Connection Request command
1302
1303 """
1304 name = "HCI_Reject_Connection_Response"
1305 fields_desc = [LEMACField("bd_addr", None),
1306 ByteField("reason", 0x1), ]
1307
1308
1309class HCI_Cmd_Link_Key_Request_Reply(Packet):
1310 """
1311
1312 7.1.10 Link Key Request Reply command
1313
1314 """
1315
1316 name = "HCI_Link_Key_Request_Reply"
1317 fields_desc = [LEMACField("bd_addr", None),
1318 NBytesField("link_key", None, 16), ]
1319
1320
1321class HCI_Cmd_Link_Key_Request_Negative_Reply(Packet):
1322 """
1323
1324 7.1.11 Link Key Request Negative Reply command
1325
1326 """
1327
1328 name = "HCI_Link_Key_Request_Negative_Reply"
1329 fields_desc = [LEMACField("bd_addr", None), ]
1330
1331
1332class HCI_Cmd_PIN_Code_Request_Reply(Packet):
1333 """
1334
1335 7.1.12 PIN Code Request Reply command
1336
1337 """
1338
1339 name = "HCI_PIN_Code_Request_Reply"
1340 fields_desc = [LEMACField("bd_addr", None),
1341 ByteField("pin_code_length", 7),
1342 NBytesField("pin_code", b"\x00" * 16, sz=16), ]
1343
1344
1345class HCI_Cmd_PIN_Code_Request_Negative_Reply(Packet):
1346 """
1347
1348 7.1.13 PIN Code Request Negative Reply command
1349
1350 """
1351
1352 name = "HCI_PIN_Code_Request_Negative_Reply"
1353 fields_desc = [LEMACField("bd_addr", None), ]
1354
1355
1356class HCI_Cmd_Change_Connection_Packet_Type(Packet):
1357 """
1358
1359 7.1.14 Change Connection Packet Type command
1360
1361 """
1362
1363 name = "HCI_Cmd_Change_Connection_Packet_Type"
1364 fields_desc = [XLEShortField("connection_handle", None),
1365 LEShortField("packet_type", 0), ]
1366
1367
1368class HCI_Cmd_Authentication_Requested(Packet):
1369 """
1370
1371 7.1.15 Authentication Requested command
1372
1373 """
1374
1375 name = "HCI_Authentication_Requested"
1376 fields_desc = [LEShortField("handle", 0)]
1377
1378
1379class HCI_Cmd_Set_Connection_Encryption(Packet):
1380 """
1381
1382 7.1.16 Set Connection Encryption command
1383
1384 """
1385
1386 name = "HCI_Set_Connection_Encryption"
1387 fields_desc = [LEShortField("handle", 0), ByteField("encryption_enable", 0)]
1388
1389
1390class HCI_Cmd_Change_Connection_Link_Key(Packet):
1391 """
1392
1393 7.1.17 Change Connection Link Key command
1394
1395 """
1396
1397 name = "HCI_Change_Connection_Link_Key"
1398 fields_desc = [LEShortField("handle", 0), ]
1399
1400
1401class HCI_Cmd_Link_Key_Selection(Packet):
1402 """
1403
1404 7.1.18 Change Connection Link Key command
1405
1406 """
1407
1408 name = "HCI_Cmd_Link_Key_Selection"
1409 fields_desc = [ByteEnumField("handle", 0, {0: "Use semi-permanent Link Keys",
1410 1: "Use Temporary Link Key", }), ]
1411
1412
1413class HCI_Cmd_Remote_Name_Request(Packet):
1414 """
1415
1416 7.1.19 Remote Name Request command
1417
1418 """
1419
1420 name = "HCI_Remote_Name_Request"
1421 fields_desc = [LEMACField("bd_addr", None),
1422 ByteField("page_scan_repetition_mode", 0x02),
1423 ByteField("reserved", 0x0),
1424 LEShortField("clock_offset", 0x0), ]
1425
1426
1427class HCI_Cmd_Remote_Name_Request_Cancel(Packet):
1428 """
1429
1430 7.1.20 Remote Name Request Cancel command
1431
1432 """
1433
1434 name = "HCI_Remote_Name_Request_Cancel"
1435 fields_desc = [LEMACField("bd_addr", None), ]
1436
1437
1438class HCI_Cmd_Read_Remote_Supported_Features(Packet):
1439 """
1440
1441 7.1.21 Read Remote Supported Features command
1442
1443 """
1444
1445 name = "HCI_Read_Remote_Supported_Features"
1446 fields_desc = [LEShortField("connection_handle", None), ]
1447
1448
1449class HCI_Cmd_Read_Remote_Extended_Features(Packet):
1450 """
1451
1452 7.1.22 Read Remote Extended Features command
1453
1454 """
1455
1456 name = "HCI_Read_Remote_Supported_Features"
1457 fields_desc = [LEShortField("connection_handle", None),
1458 ByteField("page_number", None), ]
1459
1460
1461class HCI_Cmd_IO_Capability_Request_Reply(Packet):
1462 """
1463
1464 7.1.29 IO Capability Request Reply command
1465
1466 """
1467
1468 name = "HCI_Read_Remote_Supported_Features"
1469 fields_desc = [LEMACField("bd_addr", None),
1470 ByteEnumField("io_capability", None, {0x00: "DisplayOnly",
1471 0x01: "DisplayYesNo",
1472 0x02: "KeyboardOnly",
1473 0x03: "NoInputNoOutput", }),
1474 ByteEnumField("oob_data_present", None, {0x00: "Not Present",
1475 0x01: "P-192",
1476 0x02: "P-256",
1477 0x03: "P-192 + P-256", }),
1478 ByteEnumField("authentication_requirement", None,
1479 {0x00: "MITM Not Required",
1480 0x01: "MITM Required, No Bonding",
1481 0x02: "MITM Not Required + Dedicated Pairing",
1482 0x03: "MITM Required + Dedicated Pairing",
1483 0x04: "MITM Not Required, General Bonding",
1484 0x05: "MITM Required + General Bonding"}), ]
1485
1486
1487class HCI_Cmd_User_Confirmation_Request_Reply(Packet):
1488 """
1489
1490 7.1.30 User Confirmation Request Reply command
1491
1492 """
1493
1494 name = "HCI_User_Confirmation_Request_Reply"
1495 fields_desc = [LEMACField("bd_addr", None), ]
1496
1497
1498class HCI_Cmd_User_Confirmation_Request_Negative_Reply(Packet):
1499 """
1500
1501 7.1.31 User Confirmation Request Negative Reply command
1502
1503 """
1504
1505 name = "HCI_User_Confirmation_Request_Negative_Reply"
1506 fields_desc = [LEMACField("bd_addr", None), ]
1507
1508
1509class HCI_Cmd_User_Passkey_Request_Reply(Packet):
1510 """
1511
1512 7.1.32 User Passkey Request Reply command
1513
1514 """
1515
1516 name = "HCI_User_Passkey_Request_Reply"
1517 fields_desc = [LEMACField("bd_addr", None),
1518 LEIntField("numeric_value", None), ]
1519
1520
1521class HCI_Cmd_User_Passkey_Request_Negative_Reply(Packet):
1522 """
1523
1524 7.1.33 User Passkey Request Negative Reply command
1525
1526 """
1527
1528 name = "HCI_User_Passkey_Request_Negative_Reply"
1529 fields_desc = [LEMACField("bd_addr", None), ]
1530
1531
1532class HCI_Cmd_Remote_OOB_Data_Request_Reply(Packet):
1533 """
1534
1535 7.1.34 Remote OOB Data Request Reply command
1536
1537 """
1538
1539 name = "HCI_Remote_OOB_Data_Request_Reply"
1540 fields_desc = [LEMACField("bd_addr", None),
1541 NBytesField("C", b"\x00" * 16, sz=16),
1542 NBytesField("R", b"\x00" * 16, sz=16), ]
1543
1544
1545class HCI_Cmd_Remote_OOB_Data_Request_Negative_Reply(Packet):
1546 """
1547
1548 7.1.35 Remote OOB Data Request Negative Reply command
1549
1550 """
1551
1552 name = "HCI_Remote_OOB_Data_Request_Negative_Reply"
1553 fields_desc = [LEMACField("bd_addr", None), ]
1554
1555# 7.2 Link Policy commands, the OGF is defined as 0x02
1556
1557
1558class HCI_Cmd_Hold_Mode(Packet):
1559 name = "HCI_Hold_Mode"
1560 fields_desc = [LEShortField("connection_handle", 0),
1561 LEShortField("hold_mode_max_interval", 0x0002),
1562 LEShortField("hold_mode_min_interval", 0x0002), ]
1563
1564
1565# 7.3 CONTROLLER & BASEBAND COMMANDS, the OGF is defined as 0x03
1566
1567class HCI_Cmd_Set_Event_Mask(Packet):
1568 name = "HCI_Set_Event_Mask"
1569 fields_desc = [StrFixedLenField("mask", b"\xff\xff\xfb\xff\x07\xf8\xbf\x3d", 8)] # noqa: E501
1570
1571
1572class HCI_Cmd_Reset(Packet):
1573 name = "HCI_Reset"
1574
1575
1576class HCI_Cmd_Set_Event_Filter(Packet):
1577 name = "HCI_Set_Event_Filter"
1578 fields_desc = [ByteEnumField("type", 0, {0: "clear"}), ]
1579
1580
1581class HCI_Cmd_Write_Local_Name(Packet):
1582 name = "HCI_Write_Local_Name"
1583 fields_desc = [StrFixedLenField('name', '', length=248)]
1584
1585
1586class HCI_Cmd_Write_Connect_Accept_Timeout(Packet):
1587 name = "HCI_Write_Connection_Accept_Timeout"
1588 fields_desc = [LEShortField("timeout", 32000)] # 32000 slots is 20000 msec
1589
1590
1591class HCI_Cmd_Write_Extended_Inquiry_Response(Packet):
1592 name = "HCI_Write_Extended_Inquiry_Response"
1593 fields_desc = [ByteField("fec_required", 0),
1594 HCI_Extended_Inquiry_Response]
1595
1596
1597class HCI_Cmd_Read_LE_Host_Support(Packet):
1598 name = "HCI_Read_LE_Host_Support"
1599
1600
1601class HCI_Cmd_Write_LE_Host_Support(Packet):
1602 name = "HCI_Write_LE_Host_Support"
1603 fields_desc = [ByteField("supported", 1),
1604 ByteField("unused", 1), ]
1605
1606
1607# 7.4 INFORMATIONAL PARAMETERS, the OGF is defined as 0x04
1608class HCI_Cmd_Read_BD_Addr(Packet):
1609 name = "HCI_Read_BD_ADDR"
1610
1611# 7.5 STATUS PARAMETERS, the OGF is defined as 0x05
1612
1613
1614class HCI_Cmd_Read_Link_Quality(Packet):
1615 name = "HCI_Read_Link_Quality"
1616 fields_desc = [LEShortField("handle", 0)]
1617
1618
1619class HCI_Cmd_Read_RSSI(Packet):
1620 name = "HCI_Read_RSSI"
1621 fields_desc = [LEShortField("handle", 0)]
1622
1623
1624# 7.6 TESTING COMMANDS, the OGF is defined as 0x06
1625class HCI_Cmd_Read_Loopback_Mode(Packet):
1626 name = "HCI_Read_Loopback_Mode"
1627
1628
1629class HCI_Cmd_Write_Loopback_Mode(Packet):
1630 name = "HCI_Write_Loopback_Mode"
1631 fields_desc = [ByteEnumField("loopback_mode", 0,
1632 {0: "no loopback",
1633 1: "enable local loopback",
1634 2: "enable remote loopback"})]
1635
1636
1637# 7.8 LE CONTROLLER COMMANDS, the OGF code is defined as 0x08
1638class HCI_Cmd_LE_Read_Buffer_Size_V1(Packet):
1639 name = "HCI_LE_Read_Buffer_Size [v1]"
1640
1641
1642class HCI_Cmd_LE_Read_Buffer_Size_V2(Packet):
1643 name = "HCI_LE_Read_Buffer_Size [v2]"
1644
1645
1646class HCI_Cmd_LE_Read_Local_Supported_Features(Packet):
1647 name = "HCI_LE_Read_Local_Supported_Features"
1648
1649
1650class HCI_Cmd_LE_Set_Random_Address(Packet):
1651 name = "HCI_LE_Set_Random_Address"
1652 fields_desc = [LEMACField("address", None)]
1653
1654
1655class HCI_Cmd_LE_Set_Advertising_Parameters(Packet):
1656 name = "HCI_LE_Set_Advertising_Parameters"
1657 fields_desc = [LEShortField("interval_min", 0x0800),
1658 LEShortField("interval_max", 0x0800),
1659 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
1660 ByteEnumField("oatype", 0, {0: "public", 1: "random"}),
1661 ByteEnumField("datype", 0, {0: "public", 1: "random"}),
1662 LEMACField("daddr", None),
1663 ByteField("channel_map", 7),
1664 ByteEnumField("filter_policy", 0, {0: "all:all", 1: "connect:all scan:whitelist", 2: "connect:whitelist scan:all", 3: "all:whitelist"}), ] # noqa: E501
1665
1666
1667class HCI_Cmd_LE_Set_Advertising_Data(Packet):
1668 name = "HCI_LE_Set_Advertising_Data"
1669 fields_desc = [FieldLenField("len", None, length_of="data", fmt="B"),
1670 PadField(
1671 PacketListField("data", [], EIR_Hdr,
1672 length_from=lambda pkt: pkt.len),
1673 align=31, padwith=b"\0"), ]
1674
1675
1676class HCI_Cmd_LE_Set_Scan_Response_Data(Packet):
1677 name = "HCI_LE_Set_Scan_Response_Data"
1678 fields_desc = [FieldLenField("len", None, length_of="data", fmt="B"),
1679 StrLenField("data", "", length_from=lambda pkt: pkt.len), ]
1680
1681
1682class HCI_Cmd_LE_Set_Advertise_Enable(Packet):
1683 name = "HCI_LE_Set_Advertising_Enable"
1684 fields_desc = [ByteField("enable", 0)]
1685
1686
1687class HCI_Cmd_LE_Set_Scan_Parameters(Packet):
1688 name = "HCI_LE_Set_Scan_Parameters"
1689 fields_desc = [ByteEnumField("type", 0, {0: "passive", 1: "active"}),
1690 XLEShortField("interval", 16),
1691 XLEShortField("window", 16),
1692 ByteEnumField("atype", 0, {0: "public",
1693 1: "random",
1694 2: "rpa (pub)",
1695 3: "rpa (random)"}),
1696 ByteEnumField("policy", 0, {0: "all", 1: "whitelist"})]
1697
1698
1699class HCI_Cmd_LE_Set_Scan_Enable(Packet):
1700 name = "HCI_LE_Set_Scan_Enable"
1701 fields_desc = [ByteField("enable", 1),
1702 ByteField("filter_dups", 1), ]
1703
1704
1705class HCI_Cmd_LE_Create_Connection(Packet):
1706 name = "HCI_LE_Create_Connection"
1707 fields_desc = [LEShortField("interval", 96),
1708 LEShortField("window", 48),
1709 ByteEnumField("filter", 0, {0: "address"}),
1710 ByteEnumField("patype", 0, {0: "public", 1: "random"}),
1711 LEMACField("paddr", None),
1712 ByteEnumField("atype", 0, {0: "public", 1: "random"}),
1713 LEShortField("min_interval", 40),
1714 LEShortField("max_interval", 56),
1715 LEShortField("latency", 0),
1716 LEShortField("timeout", 42),
1717 LEShortField("min_ce", 0),
1718 LEShortField("max_ce", 0), ]
1719
1720
1721class HCI_Cmd_LE_Create_Connection_Cancel(Packet):
1722 name = "HCI_LE_Create_Connection_Cancel"
1723
1724
1725class HCI_Cmd_LE_Read_Filter_Accept_List_Size(Packet):
1726 name = "HCI_LE_Read_Filter_Accept_List_Size"
1727
1728
1729class HCI_Cmd_LE_Clear_Filter_Accept_List(Packet):
1730 name = "HCI_LE_Clear_Filter_Accept_List"
1731
1732
1733class HCI_Cmd_LE_Add_Device_To_Filter_Accept_List(Packet):
1734 name = "HCI_LE_Add_Device_To_Filter_Accept_List"
1735 fields_desc = [ByteEnumField("address_type", 0, {0: "public",
1736 1: "random",
1737 0xff: "anonymous"}),
1738 LEMACField("address", None)]
1739
1740
1741class HCI_Cmd_LE_Remove_Device_From_Filter_Accept_List(HCI_Cmd_LE_Add_Device_To_Filter_Accept_List): # noqa: E501
1742 name = "HCI_LE_Remove_Device_From_Filter_Accept_List"
1743
1744
1745class HCI_Cmd_LE_Connection_Update(Packet):
1746 name = "HCI_LE_Connection_Update"
1747 fields_desc = [XLEShortField("handle", 0),
1748 XLEShortField("min_interval", 0),
1749 XLEShortField("max_interval", 0),
1750 XLEShortField("latency", 0),
1751 XLEShortField("timeout", 0),
1752 LEShortField("min_ce", 0),
1753 LEShortField("max_ce", 0xffff), ]
1754
1755
1756class HCI_Cmd_LE_Read_Remote_Features(Packet):
1757 name = "HCI_LE_Read_Remote_Features"
1758 fields_desc = [LEShortField("handle", 64)]
1759
1760
1761class HCI_Cmd_LE_Enable_Encryption(Packet):
1762 name = "HCI_LE_Enable_Encryption"
1763 fields_desc = [LEShortField("handle", 0),
1764 StrFixedLenField("rand", None, 8),
1765 XLEShortField("ediv", 0),
1766 StrFixedLenField("ltk", b'\x00' * 16, 16), ]
1767
1768
1769class HCI_Cmd_LE_Long_Term_Key_Request_Reply(Packet):
1770 name = "HCI_LE_Long_Term_Key_Request_Reply"
1771 fields_desc = [LEShortField("handle", 0),
1772 StrFixedLenField("ltk", b'\x00' * 16, 16), ]
1773
1774
1775class HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply(Packet):
1776 name = "HCI_LE_Long_Term_Key_Request _Negative_Reply"
1777 fields_desc = [LEShortField("handle", 0), ]
1778
1779
1780class HCI_Event_Hdr(Packet):
1781 name = "HCI Event header"
1782 fields_desc = [XByteField("code", 0),
1783 LenField("len", None, fmt="B"), ]
1784
1785 def answers(self, other):
1786 if HCI_Command_Hdr not in other:
1787 return False
1788
1789 # Delegate answers to event types
1790 return self.payload.answers(other)
1791
1792
1793class HCI_Event_Inquiry_Complete(Packet):
1794 """
1795 7.7.1 Inquiry Complete event
1796 """
1797 name = "HCI_Inquiry_Complete"
1798 fields_desc = [
1799 ByteEnumField('status', 0, _bluetooth_error_codes)
1800 ]
1801
1802
1803class HCI_Event_Inquiry_Result(Packet):
1804 """
1805 7.7.2 Inquiry Result event
1806 """
1807 name = "HCI_Inquiry_Result"
1808 fields_desc = [
1809 ByteField("num_response", 0x00),
1810 FieldListField("addr", None, LEMACField("addr", None),
1811 count_from=lambda p: p.num_response),
1812 FieldListField("page_scan_repetition_mode", None,
1813 ByteField("page_scan_repetition_mode", 0),
1814 count_from=lambda p: p.num_response),
1815 FieldListField("reserved", None, LEShortField("reserved", 0),
1816 count_from=lambda p: p.num_response),
1817 FieldListField("device_class", None, XLE3BytesField("device_class", 0),
1818 count_from=lambda p: p.num_response),
1819 FieldListField("clock_offset", None, LEShortField("clock_offset", 0),
1820 count_from=lambda p: p.num_response)
1821 ]
1822
1823
1824class HCI_Event_Connection_Complete(Packet):
1825 """
1826 7.7.3 Connection Complete event
1827 """
1828 name = "HCI_Connection_Complete"
1829 fields_desc = [ByteEnumField('status', 0, _bluetooth_error_codes),
1830 LEShortField("handle", 0x0100),
1831 LEMACField("bd_addr", None),
1832 ByteEnumField("link_type", 0, {0: "SCO connection",
1833 1: "ACL connection", }),
1834 ByteEnumField("encryption_enabled", 0,
1835 {0: "link level encryption disabled",
1836 1: "link level encryption enabled", }), ]
1837
1838
1839class HCI_Event_Disconnection_Complete(Packet):
1840 """
1841 7.7.5 Disconnection Complete event
1842 """
1843 name = "HCI_Disconnection_Complete"
1844 fields_desc = [ByteEnumField("status", 0, _bluetooth_error_codes),
1845 LEShortField("handle", 0),
1846 XByteField("reason", 0), ]
1847
1848
1849class HCI_Event_Remote_Name_Request_Complete(Packet):
1850 """
1851 7.7.7 Remote Name Request Complete event
1852 """
1853 name = "HCI_Remote_Name_Request_Complete"
1854 fields_desc = [ByteEnumField("status", 0, _bluetooth_error_codes),
1855 LEMACField("bd_addr", None),
1856 StrFixedLenField("remote_name", b"\x00", 248), ]
1857
1858
1859class HCI_Event_Encryption_Change(Packet):
1860 """
1861 7.7.8 Encryption Change event
1862 """
1863 name = "HCI_Encryption_Change"
1864 fields_desc = [ByteEnumField("status", 0, {0: "change has occurred"}),
1865 LEShortField("handle", 0),
1866 ByteEnumField("enabled", 0, {0: "OFF", 1: "ON (LE)", 2: "ON (BR/EDR)"}), ] # noqa: E501
1867
1868
1869class HCI_Event_Read_Remote_Supported_Features_Complete(Packet):
1870 """
1871 7.7.11 Read Remote Supported Features Complete event
1872 """
1873 name = "HCI_Read_Remote_Supported_Features_Complete"
1874 fields_desc = [
1875 ByteEnumField('status', 0, _bluetooth_error_codes),
1876 LEShortField('handle', 0),
1877 FlagsField('lmp_features', 0, -64, _bluetooth_features)
1878 ]
1879
1880
1881class HCI_Event_Read_Remote_Version_Information_Complete(Packet):
1882 """
1883 7.7.12 Read Remote Version Information Complete event
1884 """
1885 name = "HCI_Read_Remote_Version_Information"
1886 fields_desc = [
1887 ByteEnumField('status', 0, _bluetooth_error_codes),
1888 LEShortField('handle', 0),
1889 ByteField('version', 0x00),
1890 LEShortField('manufacturer_name', 0x0000),
1891 LEShortField('subversion', 0x0000)
1892 ]
1893
1894
1895class HCI_Event_Command_Complete(Packet):
1896 """
1897 7.7.14 Command Complete event
1898 """
1899 name = "HCI_Command_Complete"
1900 fields_desc = [ByteField("number", 0),
1901 XLEShortField("opcode", 0),
1902 ByteEnumField("status", 0, _bluetooth_error_codes)]
1903
1904 def answers(self, other):
1905 if HCI_Command_Hdr not in other:
1906 return False
1907
1908 return other[HCI_Command_Hdr].opcode == self.opcode
1909
1910
1911class HCI_Event_Command_Status(Packet):
1912 """
1913 7.7.15 Command Status event
1914 """
1915 name = "HCI_Command_Status"
1916 fields_desc = [ByteEnumField("status", 0, {0: "pending"}),
1917 ByteField("number", 0),
1918 XLEShortField("opcode", None), ]
1919
1920 def answers(self, other):
1921 if HCI_Command_Hdr not in other:
1922 return False
1923
1924 return other[HCI_Command_Hdr].opcode == self.opcode
1925
1926
1927class HCI_Event_Number_Of_Completed_Packets(Packet):
1928 """
1929 7.7.19 Number Of Completed Packets event
1930 """
1931 name = "HCI_Number_Of_Completed_Packets"
1932 fields_desc = [ByteField("num_handles", 0),
1933 FieldListField("connection_handle_list", None,
1934 LEShortField("connection_handle", 0),
1935 count_from=lambda p: p.num_handles),
1936 FieldListField("num_completed_packets_list", None,
1937 LEShortField("num_completed_packets", 0),
1938 count_from=lambda p: p.num_handles)]
1939
1940
1941class HCI_Event_Link_Key_Request(Packet):
1942 """
1943 7.7.23 Link Key Request event
1944 """
1945 name = 'HCI_Link_Key_Request'
1946 fields_desc = [
1947 LEMACField('bd_addr', None)
1948 ]
1949
1950
1951class HCI_Event_Inquiry_Result_With_Rssi(Packet):
1952 """
1953 7.7.33 Inquiry Result with RSSI event
1954 """
1955 name = "HCI_Inquiry_Result_with_RSSI"
1956 fields_desc = [
1957 ByteField("num_response", 0x00),
1958 FieldListField("bd_addr", None, LEMACField,
1959 count_from=lambda p: p.num_response),
1960 FieldListField("page_scan_repetition_mode", None, ByteField,
1961 count_from=lambda p: p.num_response),
1962 FieldListField("reserved", None, LEShortField,
1963 count_from=lambda p: p.num_response),
1964 FieldListField("device_class", None, XLE3BytesField,
1965 count_from=lambda p: p.num_response),
1966 FieldListField("clock_offset", None, LEShortField,
1967 count_from=lambda p: p.num_response),
1968 FieldListField("rssi", None, SignedByteField,
1969 count_from=lambda p: p.num_response)
1970 ]
1971
1972
1973class HCI_Event_Read_Remote_Extended_Features_Complete(Packet):
1974 """
1975 7.7.34 Read Remote Extended Features Complete event
1976 """
1977 name = "HCI_Read_Remote_Extended_Features_Complete"
1978 fields_desc = [
1979 ByteEnumField('status', 0, _bluetooth_error_codes),
1980 LEShortField('handle', 0),
1981 ByteField('page', 0x00),
1982 ByteField('max_page', 0x00),
1983 XLELongField('extended_features', 0)
1984 ]
1985
1986
1987class HCI_Event_Extended_Inquiry_Result(Packet):
1988 """
1989 7.7.38 Extended Inquiry Result event
1990 """
1991 name = "HCI_Extended_Inquiry_Result"
1992 fields_desc = [
1993 ByteField('num_response', 0x01),
1994 LEMACField('bd_addr', None),
1995 ByteField('page_scan_repetition_mode', 0x00),
1996 ByteField('reserved', 0x00),
1997 XLE3BytesField('device_class', 0x000000),
1998 LEShortField('clock_offset', 0x0000),
1999 SignedByteField('rssi', 0x00),
2000 HCI_Extended_Inquiry_Response,
2001 ]
2002
2003
2004class HCI_Event_IO_Capability_Response(Packet):
2005 """
2006 7.7.41 IO Capability Response event
2007 """
2008 name = "HCI_IO_Capability_Response"
2009 fields_desc = [
2010 LEMACField('bd_addr', None),
2011 ByteField('io_capability', 0x00),
2012 ByteField('oob_data_present', 0x00),
2013 ByteField('authentication_requirements', 0x00)
2014 ]
2015
2016
2017class HCI_Event_LE_Meta(Packet):
2018 """
2019 7.7.65 LE Meta event
2020 """
2021 name = "HCI_LE_Meta"
2022 fields_desc = [ByteEnumField("event", 0, {
2023 1: "connection_complete",
2024 2: "advertising_report",
2025 3: "connection_update_complete",
2026 5: "long_term_key_request",
2027 }), ]
2028
2029 def answers(self, other):
2030 if not self.payload:
2031 return False
2032
2033 # Delegate answers to payload
2034 return self.payload.answers(other)
2035
2036
2037class HCI_Cmd_Complete_Read_BD_Addr(Packet):
2038 name = "Read BD Addr"
2039 fields_desc = [LEMACField("addr", None), ]
2040
2041
2042class HCI_Cmd_Complete_LE_Read_White_List_Size(Packet):
2043 name = "LE Read White List Size"
2044 fields_desc = [ByteField("status", 0),
2045 ByteField("size", 0), ]
2046
2047
2048class HCI_LE_Meta_Connection_Complete(Packet):
2049 name = "Connection Complete"
2050 fields_desc = [ByteEnumField("status", 0, {0: "success"}),
2051 LEShortField("handle", 0),
2052 ByteEnumField("role", 0, {0: "master"}),
2053 ByteEnumField("patype", 0, {0: "public", 1: "random"}),
2054 LEMACField("paddr", None),
2055 LEShortField("interval", 54),
2056 LEShortField("latency", 0),
2057 LEShortField("supervision", 42),
2058 XByteField("clock_latency", 5), ]
2059
2060 def answers(self, other):
2061 if HCI_Cmd_LE_Create_Connection not in other:
2062 return False
2063
2064 return (other[HCI_Cmd_LE_Create_Connection].patype == self.patype and
2065 other[HCI_Cmd_LE_Create_Connection].paddr == self.paddr)
2066
2067
2068class HCI_LE_Meta_Connection_Update_Complete(Packet):
2069 name = "Connection Update Complete"
2070 fields_desc = [ByteEnumField("status", 0, {0: "success"}),
2071 LEShortField("handle", 0),
2072 LEShortField("interval", 54),
2073 LEShortField("latency", 0),
2074 LEShortField("timeout", 42), ]
2075
2076
2077class HCI_LE_Meta_Advertising_Report(Packet):
2078 name = "Advertising Report"
2079 fields_desc = [ByteEnumField("type", 0, {0: "conn_und", 4: "scan_rsp"}),
2080 ByteEnumField("atype", 0, {0: "public", 1: "random"}),
2081 LEMACField("addr", None),
2082 FieldLenField("len", None, length_of="data", fmt="B"),
2083 PacketListField("data", [], EIR_Hdr,
2084 length_from=lambda pkt: pkt.len),
2085 SignedByteField("rssi", 0)]
2086
2087 def extract_padding(self, s):
2088 return '', s
2089
2090
2091class HCI_LE_Meta_Advertising_Reports(Packet):
2092 name = "Advertising Reports"
2093 fields_desc = [FieldLenField("len", None, count_of="reports", fmt="B"),
2094 PacketListField("reports", None,
2095 HCI_LE_Meta_Advertising_Report,
2096 count_from=lambda pkt: pkt.len)]
2097
2098
2099class HCI_LE_Meta_Long_Term_Key_Request(Packet):
2100 name = "Long Term Key Request"
2101 fields_desc = [LEShortField("handle", 0),
2102 StrFixedLenField("rand", None, 8),
2103 XLEShortField("ediv", 0), ]
2104
2105
2106bind_layers(HCI_PHDR_Hdr, HCI_Hdr)
2107
2108bind_layers(HCI_Hdr, HCI_Command_Hdr, type=1)
2109bind_layers(HCI_Hdr, HCI_ACL_Hdr, type=2)
2110bind_layers(HCI_Hdr, HCI_Event_Hdr, type=4)
2111bind_layers(HCI_Hdr, conf.raw_layer,)
2112
2113conf.l2types.register(DLT_BLUETOOTH_HCI_H4, HCI_Hdr)
2114conf.l2types.register(DLT_BLUETOOTH_HCI_H4_WITH_PHDR, HCI_PHDR_Hdr)
2115
2116
2117# 7.1 LINK CONTROL COMMANDS, the OGF is defined as 0x01
2118bind_layers(HCI_Command_Hdr, HCI_Cmd_Inquiry, ogf=0x01, ocf=0x0001)
2119bind_layers(HCI_Command_Hdr, HCI_Cmd_Inquiry_Cancel, ogf=0x01, ocf=0x0002)
2120bind_layers(HCI_Command_Hdr, HCI_Cmd_Periodic_Inquiry_Mode, ogf=0x01, ocf=0x0003)
2121bind_layers(HCI_Command_Hdr, HCI_Cmd_Exit_Peiodic_Inquiry_Mode, ogf=0x01, ocf=0x0004)
2122bind_layers(HCI_Command_Hdr, HCI_Cmd_Create_Connection, ogf=0x01, ocf=0x0005)
2123bind_layers(HCI_Command_Hdr, HCI_Cmd_Disconnect, ogf=0x01, ocf=0x0006)
2124bind_layers(HCI_Command_Hdr, HCI_Cmd_Create_Connection_Cancel, ogf=0x01, ocf=0x0008)
2125bind_layers(HCI_Command_Hdr, HCI_Cmd_Accept_Connection_Request, ogf=0x01, ocf=0x0009)
2126bind_layers(HCI_Command_Hdr, HCI_Cmd_Reject_Connection_Response, ogf=0x01, ocf=0x000a)
2127bind_layers(HCI_Command_Hdr, HCI_Cmd_Link_Key_Request_Reply, ogf=0x01, ocf=0x000b)
2128bind_layers(HCI_Command_Hdr, HCI_Cmd_Link_Key_Request_Negative_Reply,
2129 ogf=0x01, ocf=0x000c)
2130bind_layers(HCI_Command_Hdr, HCI_Cmd_PIN_Code_Request_Reply, ogf=0x01, ocf=0x000d)
2131bind_layers(HCI_Command_Hdr, HCI_Cmd_Change_Connection_Packet_Type,
2132 ogf=0x01, ocf=0x000f)
2133bind_layers(HCI_Command_Hdr, HCI_Cmd_Authentication_Requested, ogf=0x01, ocf=0x0011)
2134bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Connection_Encryption, ogf=0x01, ocf=0x0013)
2135bind_layers(HCI_Command_Hdr, HCI_Cmd_Change_Connection_Link_Key, ogf=0x01, ocf=0x0017)
2136bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_Name_Request, ogf=0x01, ocf=0x0019)
2137bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_Name_Request_Cancel, ogf=0x01, ocf=0x001a)
2138bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Remote_Supported_Features,
2139 ogf=0x01, ocf=0x001b)
2140bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Remote_Extended_Features,
2141 ogf=0x01, ocf=0x001c)
2142bind_layers(HCI_Command_Hdr, HCI_Cmd_IO_Capability_Request_Reply, ogf=0x01, ocf=0x002b)
2143bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Confirmation_Request_Reply,
2144 ogf=0x01, ocf=0x002c)
2145bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Confirmation_Request_Negative_Reply,
2146 ogf=0x01, ocf=0x002d)
2147bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Passkey_Request_Reply, ogf=0x01, ocf=0x002e)
2148bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Passkey_Request_Negative_Reply,
2149 ogf=0x01, ocf=0x002f)
2150bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_OOB_Data_Request_Reply,
2151 ogf=0x01, ocf=0x0030)
2152bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_OOB_Data_Request_Negative_Reply,
2153 ogf=0x01, ocf=0x0033)
2154
2155# 7.2 Link Policy commands, the OGF is defined as 0x02
2156bind_layers(HCI_Command_Hdr, HCI_Cmd_Hold_Mode, ogf=0x02, ocf=0x0001)
2157
2158# 7.3 CONTROLLER & BASEBAND COMMANDS, the OGF is defined as 0x03
2159bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Event_Mask, ogf=0x03, ocf=0x0001)
2160bind_layers(HCI_Command_Hdr, HCI_Cmd_Reset, ogf=0x03, ocf=0x0003)
2161bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Event_Filter, ogf=0x03, ocf=0x0005)
2162bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Local_Name, ogf=0x03, ocf=0x0013)
2163bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Connect_Accept_Timeout, ogf=0x03, ocf=0x0016)
2164bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Extended_Inquiry_Response, ogf=0x03, ocf=0x0052) # noqa: E501
2165bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_LE_Host_Support, ogf=0x03, ocf=0x006c)
2166bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_LE_Host_Support, ogf=0x03, ocf=0x006d)
2167
2168# 7.4 INFORMATIONAL PARAMETERS, the OGF is defined as 0x04
2169bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_BD_Addr, ogf=0x04, ocf=0x0009)
2170
2171# 7.5 STATUS PARAMETERS, the OGF is defined as 0x05
2172bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Link_Quality, ogf=0x05, ocf=0x0003)
2173bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_RSSI, ogf=0x05, ocf=0x0005)
2174
2175# 7.6 TESTING COMMANDS, the OGF is defined as 0x06
2176bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Loopback_Mode, ogf=0x06, ocf=0x0001)
2177bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Loopback_Mode, ogf=0x06, ocf=0x0002)
2178
2179# 7.8 LE CONTROLLER COMMANDS, the OGF code is defined as 0x08
2180bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Buffer_Size_V1, ogf=0x08, ocf=0x0002)
2181bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Buffer_Size_V2, ogf=0x08, ocf=0x0060)
2182bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Local_Supported_Features,
2183 ogf=0x08, ocf=0x0003)
2184bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Random_Address, ogf=0x08, ocf=0x0005)
2185bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertising_Parameters, ogf=0x08, ocf=0x0006) # noqa: E501
2186bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertising_Data, ogf=0x08, ocf=0x0008)
2187bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Response_Data, ogf=0x08, ocf=0x0009)
2188bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertise_Enable, ogf=0x08, ocf=0x000a)
2189bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Parameters, ogf=0x08, ocf=0x000b)
2190bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Enable, ogf=0x08, ocf=0x000c)
2191bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Create_Connection, ogf=0x08, ocf=0x000d)
2192bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Create_Connection_Cancel, ogf=0x08, ocf=0x000e) # noqa: E501
2193bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Filter_Accept_List_Size,
2194 ogf=0x08, ocf=0x000f)
2195bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Clear_Filter_Accept_List, ogf=0x08, ocf=0x0010)
2196bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Add_Device_To_Filter_Accept_List, ogf=0x08, ocf=0x0011) # noqa: E501
2197bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Remove_Device_From_Filter_Accept_List, ogf=0x08, ocf=0x0012) # noqa: E501
2198bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Connection_Update, ogf=0x08, ocf=0x0013)
2199bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Remote_Features, ogf=0x08, ocf=0x0016) # noqa: E501
2200bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Enable_Encryption, ogf=0x08, ocf=0x0019) # noqa: E501
2201bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Long_Term_Key_Request_Reply, ogf=0x08, ocf=0x001a) # noqa: E501
2202bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply, ogf=0x08, ocf=0x001b) # noqa: E501
2203
2204# 7.7 EVENTS
2205bind_layers(HCI_Event_Hdr, HCI_Event_Inquiry_Complete, code=0x01)
2206bind_layers(HCI_Event_Hdr, HCI_Event_Inquiry_Result, code=0x02)
2207bind_layers(HCI_Event_Hdr, HCI_Event_Connection_Complete, code=0x03)
2208bind_layers(HCI_Event_Hdr, HCI_Event_Disconnection_Complete, code=0x05)
2209bind_layers(HCI_Event_Hdr, HCI_Event_Remote_Name_Request_Complete, code=0x07)
2210bind_layers(HCI_Event_Hdr, HCI_Event_Encryption_Change, code=0x08)
2211bind_layers(HCI_Event_Hdr, HCI_Event_Read_Remote_Supported_Features_Complete, code=0x0b)
2212bind_layers(HCI_Event_Hdr, HCI_Event_Read_Remote_Version_Information_Complete, code=0x0c) # noqa: E501
2213bind_layers(HCI_Event_Hdr, HCI_Event_Command_Complete, code=0x0e)
2214bind_layers(HCI_Event_Hdr, HCI_Event_Command_Status, code=0x0f)
2215bind_layers(HCI_Event_Hdr, HCI_Event_Number_Of_Completed_Packets, code=0x13)
2216bind_layers(HCI_Event_Hdr, HCI_Event_Link_Key_Request, code=0x17)
2217bind_layers(HCI_Event_Hdr, HCI_Event_Inquiry_Result_With_Rssi, code=0x22)
2218bind_layers(HCI_Event_Hdr, HCI_Event_Read_Remote_Extended_Features_Complete, code=0x23)
2219bind_layers(HCI_Event_Hdr, HCI_Event_Extended_Inquiry_Result, code=0x2f)
2220bind_layers(HCI_Event_Hdr, HCI_Event_IO_Capability_Response, code=0x32)
2221bind_layers(HCI_Event_Hdr, HCI_Event_LE_Meta, code=0x3e)
2222
2223bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_Read_BD_Addr, opcode=0x1009) # noqa: E501
2224bind_layers(HCI_Event_Command_Complete, HCI_Cmd_Complete_LE_Read_White_List_Size, opcode=0x200f) # noqa: E501
2225
2226bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Connection_Complete, event=1)
2227bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Advertising_Reports, event=2)
2228bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Connection_Update_Complete, event=3)
2229bind_layers(HCI_Event_LE_Meta, HCI_LE_Meta_Long_Term_Key_Request, event=5)
2230
2231bind_layers(EIR_Hdr, EIR_Flags, type=0x01)
2232bind_layers(EIR_Hdr, EIR_IncompleteList16BitServiceUUIDs, type=0x02)
2233bind_layers(EIR_Hdr, EIR_CompleteList16BitServiceUUIDs, type=0x03)
2234bind_layers(EIR_Hdr, EIR_IncompleteList128BitServiceUUIDs, type=0x06)
2235bind_layers(EIR_Hdr, EIR_CompleteList128BitServiceUUIDs, type=0x07)
2236bind_layers(EIR_Hdr, EIR_ShortenedLocalName, type=0x08)
2237bind_layers(EIR_Hdr, EIR_CompleteLocalName, type=0x09)
2238bind_layers(EIR_Hdr, EIR_Device_ID, type=0x10)
2239bind_layers(EIR_Hdr, EIR_TX_Power_Level, type=0x0a)
2240bind_layers(EIR_Hdr, EIR_ServiceData16BitUUID, type=0x16)
2241bind_layers(EIR_Hdr, EIR_Manufacturer_Specific_Data, type=0xff)
2242bind_layers(EIR_Hdr, EIR_Raw)
2243
2244bind_layers(HCI_ACL_Hdr, L2CAP_Hdr,)
2245bind_layers(L2CAP_Hdr, L2CAP_CmdHdr, cid=1)
2246bind_layers(L2CAP_Hdr, L2CAP_CmdHdr, cid=5) # LE L2CAP Signaling Channel
2247bind_layers(L2CAP_CmdHdr, L2CAP_CmdRej, code=1)
2248bind_layers(L2CAP_CmdHdr, L2CAP_ConnReq, code=2)
2249bind_layers(L2CAP_CmdHdr, L2CAP_ConnResp, code=3)
2250bind_layers(L2CAP_CmdHdr, L2CAP_ConfReq, code=4)
2251bind_layers(L2CAP_CmdHdr, L2CAP_ConfResp, code=5)
2252bind_layers(L2CAP_CmdHdr, L2CAP_DisconnReq, code=6)
2253bind_layers(L2CAP_CmdHdr, L2CAP_DisconnResp, code=7)
2254bind_layers(L2CAP_CmdHdr, L2CAP_EchoReq, code=8)
2255bind_layers(L2CAP_CmdHdr, L2CAP_EchoResp, code=9)
2256bind_layers(L2CAP_CmdHdr, L2CAP_InfoReq, code=10)
2257bind_layers(L2CAP_CmdHdr, L2CAP_InfoResp, code=11)
2258bind_layers(L2CAP_CmdHdr, L2CAP_Create_Channel_Request, code=12)
2259bind_layers(L2CAP_CmdHdr, L2CAP_Create_Channel_Response, code=13)
2260bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Request, code=14)
2261bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Response, code=15)
2262bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Confirmation_Request, code=16)
2263bind_layers(L2CAP_CmdHdr, L2CAP_Move_Channel_Confirmation_Response, code=17)
2264bind_layers(L2CAP_CmdHdr, L2CAP_Connection_Parameter_Update_Request, code=18)
2265bind_layers(L2CAP_CmdHdr, L2CAP_Connection_Parameter_Update_Response, code=19)
2266bind_layers(L2CAP_CmdHdr, L2CAP_LE_Credit_Based_Connection_Request, code=20)
2267bind_layers(L2CAP_CmdHdr, L2CAP_LE_Credit_Based_Connection_Response, code=21)
2268bind_layers(L2CAP_CmdHdr, L2CAP_Flow_Control_Credit_Ind, code=22)
2269bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Connection_Request, code=23)
2270bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Connection_Response, code=24)
2271bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Reconfigure_Request, code=25)
2272bind_layers(L2CAP_CmdHdr, L2CAP_Credit_Based_Reconfigure_Response, code=26)
2273bind_layers(L2CAP_Hdr, ATT_Hdr, cid=4)
2274bind_layers(ATT_Hdr, ATT_Error_Response, opcode=0x1)
2275bind_layers(ATT_Hdr, ATT_Exchange_MTU_Request, opcode=0x2)
2276bind_layers(ATT_Hdr, ATT_Exchange_MTU_Response, opcode=0x3)
2277bind_layers(ATT_Hdr, ATT_Find_Information_Request, opcode=0x4)
2278bind_layers(ATT_Hdr, ATT_Find_Information_Response, opcode=0x5)
2279bind_layers(ATT_Hdr, ATT_Find_By_Type_Value_Request, opcode=0x6)
2280bind_layers(ATT_Hdr, ATT_Find_By_Type_Value_Response, opcode=0x7)
2281bind_layers(ATT_Hdr, ATT_Read_By_Type_Request_128bit, opcode=0x8)
2282bind_layers(ATT_Hdr, ATT_Read_By_Type_Request, opcode=0x8)
2283bind_layers(ATT_Hdr, ATT_Read_By_Type_Response, opcode=0x9)
2284bind_layers(ATT_Hdr, ATT_Read_Request, opcode=0xa)
2285bind_layers(ATT_Hdr, ATT_Read_Response, opcode=0xb)
2286bind_layers(ATT_Hdr, ATT_Read_Blob_Request, opcode=0xc)
2287bind_layers(ATT_Hdr, ATT_Read_Blob_Response, opcode=0xd)
2288bind_layers(ATT_Hdr, ATT_Read_Multiple_Request, opcode=0xe)
2289bind_layers(ATT_Hdr, ATT_Read_Multiple_Response, opcode=0xf)
2290bind_layers(ATT_Hdr, ATT_Read_By_Group_Type_Request, opcode=0x10)
2291bind_layers(ATT_Hdr, ATT_Read_By_Group_Type_Response, opcode=0x11)
2292bind_layers(ATT_Hdr, ATT_Write_Request, opcode=0x12)
2293bind_layers(ATT_Hdr, ATT_Write_Response, opcode=0x13)
2294bind_layers(ATT_Hdr, ATT_Prepare_Write_Request, opcode=0x16)
2295bind_layers(ATT_Hdr, ATT_Prepare_Write_Response, opcode=0x17)
2296bind_layers(ATT_Hdr, ATT_Execute_Write_Request, opcode=0x18)
2297bind_layers(ATT_Hdr, ATT_Execute_Write_Response, opcode=0x19)
2298bind_layers(ATT_Hdr, ATT_Write_Command, opcode=0x52)
2299bind_layers(ATT_Hdr, ATT_Handle_Value_Notification, opcode=0x1b)
2300bind_layers(ATT_Hdr, ATT_Handle_Value_Indication, opcode=0x1d)
2301bind_layers(L2CAP_Hdr, SM_Hdr, cid=6)
2302bind_layers(SM_Hdr, SM_Pairing_Request, sm_command=1)
2303bind_layers(SM_Hdr, SM_Pairing_Response, sm_command=2)
2304bind_layers(SM_Hdr, SM_Confirm, sm_command=3)
2305bind_layers(SM_Hdr, SM_Random, sm_command=4)
2306bind_layers(SM_Hdr, SM_Failed, sm_command=5)
2307bind_layers(SM_Hdr, SM_Encryption_Information, sm_command=6)
2308bind_layers(SM_Hdr, SM_Master_Identification, sm_command=7)
2309bind_layers(SM_Hdr, SM_Identity_Information, sm_command=8)
2310bind_layers(SM_Hdr, SM_Identity_Address_Information, sm_command=9)
2311bind_layers(SM_Hdr, SM_Signing_Information, sm_command=0x0a)
2312bind_layers(SM_Hdr, SM_Public_Key, sm_command=0x0c)
2313bind_layers(SM_Hdr, SM_DHKey_Check, sm_command=0x0d)
2314
2315
2316###############
2317# HCI Monitor #
2318###############
2319
2320
2321# https://elixir.bootlin.com/linux/v6.4.2/source/include/net/bluetooth/hci_mon.h#L27
2322class HCI_Mon_Hdr(Packet):
2323 name = 'Bluetooth Linux Monitor Transport Header'
2324 fields_desc = [
2325 LEShortEnumField('opcode', None, {
2326 0: "New index",
2327 1: "Delete index",
2328 2: "Command pkt",
2329 3: "Event pkt",
2330 4: "ACL TX pkt",
2331 5: "ACL RX pkt",
2332 6: "SCO TX pkt",
2333 7: "SCO RX pkt",
2334 8: "Open index",
2335 9: "Close index",
2336 10: "Index info",
2337 11: "Vendor diag",
2338 12: "System note",
2339 13: "User logging",
2340 14: "Ctrl open",
2341 15: "Ctrl close",
2342 16: "Ctrl command",
2343 17: "Ctrl event",
2344 18: "ISO TX pkt",
2345 19: "ISO RX pkt",
2346 }),
2347 LEShortField('adapter_id', None),
2348 LEShortField('len', None)
2349 ]
2350
2351
2352# https://www.tcpdump.org/linktypes/LINKTYPE_BLUETOOTH_LINUX_MONITOR.html
2353class HCI_Mon_Pcap_Hdr(HCI_Mon_Hdr):
2354 name = 'Bluetooth Linux Monitor Transport Pcap Header'
2355 fields_desc = [
2356 ShortField('adapter_id', None),
2357 ShortField('opcode', None)
2358 ]
2359
2360
2361class HCI_Mon_New_Index(Packet):
2362 name = 'Bluetooth Linux Monitor Transport New Index Packet'
2363 fields_desc = [
2364 ByteEnumField('bus', 0, {
2365 0x00: "BR/EDR",
2366 0x01: "AMP"
2367 }),
2368 ByteEnumField('type', 0, {
2369 0x00: "Virtual",
2370 0x01: "USB",
2371 0x02: "PC Card",
2372 0x03: "UART",
2373 0x04: "RS232",
2374 0x05: "PCI",
2375 0x06: "SDIO"
2376 }),
2377 LEMACField('addr', None),
2378 StrFixedLenField('devname', None, 8)
2379 ]
2380
2381
2382class HCI_Mon_Index_Info(Packet):
2383 name = 'Bluetooth Linux Monitor Transport Index Info Packet'
2384 fields_desc = [
2385 LEMACField('addr', None),
2386 XLEShortField('manufacturer', None)
2387 ]
2388
2389
2390class HCI_Mon_System_Note(Packet):
2391 name = 'Bluetooth Linux Monitor Transport System Note Packet'
2392 fields_desc = [
2393 StrNullField('note', None)
2394 ]
2395
2396
2397# https://elixir.bootlin.com/linux/v6.4.2/source/include/net/bluetooth/hci_mon.h#L34
2398bind_layers(HCI_Mon_Hdr, HCI_Mon_New_Index, opcode=0)
2399bind_layers(HCI_Mon_Hdr, HCI_Command_Hdr, opcode=2)
2400bind_layers(HCI_Mon_Hdr, HCI_Event_Hdr, opcode=3)
2401bind_layers(HCI_Mon_Hdr, HCI_Mon_Index_Info, opcode=10)
2402bind_layers(HCI_Mon_Hdr, HCI_Mon_System_Note, opcode=12)
2403
2404conf.l2types.register(DLT_BLUETOOTH_LINUX_MONITOR, HCI_Mon_Pcap_Hdr)
2405
2406
2407###########
2408# Helpers #
2409###########
2410
2411class LowEnergyBeaconHelper:
2412 """
2413 Helpers for building packets for Bluetooth Low Energy Beacons.
2414
2415 Implementers provide a :meth:`build_eir` implementation.
2416
2417 This is designed to be used as a mix-in -- see
2418 ``scapy.contrib.eddystone`` and ``scapy.contrib.ibeacon`` for examples.
2419 """
2420
2421 # Basic flags that should be used by most beacons.
2422 base_eir = [EIR_Hdr() / EIR_Flags(flags=[
2423 "general_disc_mode", "br_edr_not_supported"]), ]
2424
2425 def build_eir(self):
2426 """
2427 Builds a list of EIR messages to wrap this frame.
2428
2429 Users of this helper must implement this method.
2430
2431 :return: List of HCI_Hdr with payloads that describe this beacon type
2432 :rtype: list[scapy.bluetooth.HCI_Hdr]
2433 """
2434 raise NotImplementedError("build_eir")
2435
2436 def build_advertising_report(self):
2437 """
2438 Builds a HCI_LE_Meta_Advertising_Report containing this frame.
2439
2440 :rtype: scapy.bluetooth.HCI_LE_Meta_Advertising_Report
2441 """
2442
2443 return HCI_LE_Meta_Advertising_Report(
2444 type=0, # Undirected
2445 atype=1, # Random address
2446 data=self.build_eir()
2447 )
2448
2449 def build_set_advertising_data(self):
2450 """Builds a HCI_Cmd_LE_Set_Advertising_Data containing this frame.
2451
2452 This includes the :class:`HCI_Hdr` and :class:`HCI_Command_Hdr` layers.
2453
2454 :rtype: scapy.bluetooth.HCI_Hdr
2455 """
2456
2457 return HCI_Hdr() / HCI_Command_Hdr() / HCI_Cmd_LE_Set_Advertising_Data(
2458 data=self.build_eir()
2459 )
2460
2461
2462###########
2463# Sockets #
2464###########
2465
2466class BluetoothSocketError(BaseException):
2467 pass
2468
2469
2470class BluetoothCommandError(BaseException):
2471 pass
2472
2473
2474class BluetoothL2CAPSocket(SuperSocket):
2475 desc = "read/write packets on a connected L2CAP socket"
2476
2477 def __init__(self, bt_address):
2478 if WINDOWS:
2479 warning("Not available on Windows")
2480 return
2481 s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW,
2482 socket.BTPROTO_L2CAP)
2483 s.connect((bt_address, 0))
2484 self.ins = self.outs = s
2485
2486 def recv(self, x=MTU):
2487 return L2CAP_CmdHdr(self.ins.recv(x))
2488
2489
2490class BluetoothRFCommSocket(BluetoothL2CAPSocket):
2491 """read/write packets on a connected RFCOMM socket"""
2492
2493 def __init__(self, bt_address, port=0):
2494 s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW,
2495 socket.BTPROTO_RFCOMM)
2496 s.connect((bt_address, port))
2497 self.ins = self.outs = s
2498
2499
2500class BluetoothHCISocket(SuperSocket):
2501 desc = "read/write on a BlueTooth HCI socket"
2502
2503 def __init__(self, iface=0x10000, type=None):
2504 if WINDOWS:
2505 warning("Not available on Windows")
2506 return
2507 s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI) # noqa: E501
2508 s.setsockopt(socket.SOL_HCI, socket.HCI_DATA_DIR, 1)
2509 s.setsockopt(socket.SOL_HCI, socket.HCI_TIME_STAMP, 1)
2510 s.setsockopt(socket.SOL_HCI, socket.HCI_FILTER, struct.pack("IIIh2x", 0xffffffff, 0xffffffff, 0xffffffff, 0)) # type mask, event mask, event mask, opcode # noqa: E501
2511 s.bind((iface,))
2512 self.ins = self.outs = s
2513# s.connect((peer,0))
2514
2515 def recv(self, x=MTU):
2516 return HCI_Hdr(self.ins.recv(x))
2517
2518
2519class sockaddr_hci(ctypes.Structure):
2520 _fields_ = [
2521 ("sin_family", ctypes.c_ushort),
2522 ("hci_dev", ctypes.c_ushort),
2523 ("hci_channel", ctypes.c_ushort),
2524 ]
2525
2526
2527class _BluetoothLibcSocket(SuperSocket):
2528 def __init__(self, socket_domain, socket_type, socket_protocol, sock_address):
2529 # type: (int, int, int, sockaddr_hci) -> None
2530 if WINDOWS:
2531 warning("Not available on Windows")
2532 return
2533 # Python socket and bind implementations do not allow us to pass down
2534 # the correct parameters. We must call libc functions directly via
2535 # ctypes.
2536 sockaddr_hcip = ctypes.POINTER(sockaddr_hci)
2537 from ctypes.util import find_library
2538 libc = ctypes.cdll.LoadLibrary(find_library("c"))
2539
2540 socket_c = libc.socket
2541 socket_c.argtypes = (ctypes.c_int, ctypes.c_int, ctypes.c_int)
2542 socket_c.restype = ctypes.c_int
2543
2544 bind = libc.bind
2545 bind.argtypes = (ctypes.c_int,
2546 ctypes.POINTER(sockaddr_hci),
2547 ctypes.c_int)
2548 bind.restype = ctypes.c_int
2549
2550 # Socket
2551 s = socket_c(socket_domain, socket_type, socket_protocol)
2552 if s < 0:
2553 raise BluetoothSocketError(
2554 f"Unable to open socket({socket_domain}, {socket_type}, "
2555 f"{socket_protocol})")
2556
2557 # Bind
2558 r = bind(s, sockaddr_hcip(sock_address), sizeof(sock_address))
2559 if r != 0:
2560 raise BluetoothSocketError("Unable to bind")
2561
2562 self.hci_fd = s
2563 self.ins = self.outs = socket.fromfd(
2564 s, socket_domain, socket_type, socket_protocol)
2565
2566 def readable(self, timeout=0):
2567 (ins, _, _) = select.select([self.ins], [], [], timeout)
2568 return len(ins) > 0
2569
2570 def flush(self):
2571 while self.readable():
2572 self.recv()
2573
2574 def close(self):
2575 if self.closed:
2576 return
2577
2578 # Properly close socket so we can free the device
2579 from ctypes.util import find_library
2580 libc = ctypes.cdll.LoadLibrary(find_library("c"))
2581
2582 close = libc.close
2583 close.restype = ctypes.c_int
2584 self.closed = True
2585 if hasattr(self, "outs"):
2586 if not hasattr(self, "ins") or self.ins != self.outs:
2587 if self.outs and (WINDOWS or self.outs.fileno() != -1):
2588 close(self.outs.fileno())
2589 if hasattr(self, "ins"):
2590 if self.ins and (WINDOWS or self.ins.fileno() != -1):
2591 close(self.ins.fileno())
2592 if hasattr(self, "hci_fd"):
2593 close(self.hci_fd)
2594
2595
2596class BluetoothUserSocket(_BluetoothLibcSocket):
2597 desc = "read/write H4 over a Bluetooth user channel"
2598
2599 def __init__(self, adapter_index=0):
2600 sa = sockaddr_hci()
2601 sa.sin_family = socket.AF_BLUETOOTH
2602 sa.hci_dev = adapter_index
2603 sa.hci_channel = HCI_CHANNEL_USER
2604 super().__init__(
2605 socket_domain=socket.AF_BLUETOOTH,
2606 socket_type=socket.SOCK_RAW,
2607 socket_protocol=socket.BTPROTO_HCI,
2608 sock_address=sa)
2609
2610 def send_command(self, cmd):
2611 opcode = cmd.opcode
2612 self.send(cmd)
2613 while True:
2614 r = self.recv()
2615 if r.type == 0x04 and r.code == 0xe and r.opcode == opcode:
2616 if r.status != 0:
2617 raise BluetoothCommandError("Command %x failed with %x" % (opcode, r.status)) # noqa: E501
2618 return r
2619
2620 def recv(self, x=MTU):
2621 return HCI_Hdr(self.ins.recv(x))
2622
2623
2624class BluetoothMonitorSocket(_BluetoothLibcSocket):
2625 desc = "Read/write over a Bluetooth monitor channel"
2626
2627 def __init__(self):
2628 sa = sockaddr_hci()
2629 sa.sin_family = socket.AF_BLUETOOTH
2630 sa.hci_dev = HCI_DEV_NONE
2631 sa.hci_channel = HCI_CHANNEL_MONITOR
2632 super().__init__(
2633 socket_domain=socket.AF_BLUETOOTH,
2634 socket_type=socket.SOCK_RAW,
2635 socket_protocol=socket.BTPROTO_HCI,
2636 sock_address=sa)
2637
2638 def recv(self, x=MTU):
2639 return HCI_Mon_Hdr(self.ins.recv(x))
2640
2641
2642conf.BTsocket = BluetoothRFCommSocket
2643
2644# Bluetooth
2645
2646
2647@conf.commands.register
2648def srbt(bt_address, pkts, inter=0.1, *args, **kargs):
2649 """send and receive using a bluetooth socket"""
2650 if "port" in kargs:
2651 s = conf.BTsocket(bt_address=bt_address, port=kargs.pop("port"))
2652 else:
2653 s = conf.BTsocket(bt_address=bt_address)
2654 a, b = sndrcv(s, pkts, inter=inter, *args, **kargs)
2655 s.close()
2656 return a, b
2657
2658
2659@conf.commands.register
2660def srbt1(bt_address, pkts, *args, **kargs):
2661 """send and receive 1 packet using a bluetooth socket"""
2662 a, b = srbt(bt_address, pkts, *args, **kargs)
2663 if len(a) > 0:
2664 return a[0][1]