xref: /aosp_15_r20/external/scapy/scapy/layers/bluetooth.py (revision 7dc08ffc4802948ccbc861daaf1e81c405c2c4bd)
1## This file is part of Scapy
2## See http://www.secdev.org/projects/scapy for more informations
3## Copyright (C) Philippe Biondi <[email protected]>
4## Copyright (C) Mike Ryan <[email protected]>
5## This program is published under a GPLv2 license
6
7"""
8Bluetooth layers, sockets and send/receive functions.
9"""
10
11import socket,struct,array
12from ctypes import *
13from select import select
14
15from scapy.config import conf
16from scapy.data import DLT_BLUETOOTH_HCI_H4
17from scapy.packet import *
18from scapy.fields import *
19from scapy.supersocket import SuperSocket
20from scapy.sendrecv import sndrcv
21from scapy.data import MTU
22from scapy.consts import WINDOWS
23from scapy.error import warning, log_loading
24
25
26##########
27# Fields #
28##########
29
30class XLEShortField(LEShortField):
31    def i2repr(self, pkt, x):
32        return lhex(self.i2h(pkt, x))
33
34class XLELongField(LEShortField):
35    def __init__(self, name, default):
36        Field.__init__(self, name, default, "<Q")
37    def i2repr(self, pkt, x):
38        return lhex(self.i2h(pkt, x))
39
40
41class LEMACField(Field):
42    def __init__(self, name, default):
43        Field.__init__(self, name, default, "6s")
44    def i2m(self, pkt, x):
45        if x is None:
46            return b"\0\0\0\0\0\0"
47        return mac2str(x)[::-1]
48    def m2i(self, pkt, x):
49        return str2mac(x[::-1])
50    def any2i(self, pkt, x):
51        if isinstance(x, str) and len(x) is 6:
52            x = self.m2i(pkt, x)
53        return x
54    def i2repr(self, pkt, x):
55        x = self.i2h(pkt, x)
56        if self in conf.resolve:
57            x = conf.manufdb._resolve_MAC(x)
58        return x
59    def randval(self):
60        return RandMAC()
61
62_bluetooth_packet_types = {
63        0: "Acknowledgement",
64        1: "Command",
65        2: "ACL Data",
66        3: "Synchronous",
67        4: "Event",
68        5: "Reserve",
69        14: "Vendor",
70        15: "Link Control"
71    }
72
73class HCI_Hdr(Packet):
74    name = "HCI header"
75    fields_desc = [ ByteEnumField("type", 2, _bluetooth_packet_types) ]
76
77    def mysummary(self):
78        return self.sprintf("HCI %type%")
79
80class HCI_ACL_Hdr(Packet):
81    name = "HCI ACL header"
82    fields_desc = [ BitField("handle",0,12),    # TODO: Create and use LEBitField
83                    BitField("PB",0,2),      # They are recieved as a **combined** LE Short
84                    BitField("BC",0,2),      # Handle is 12 bits, eacg flag is 2 bits.
85                    LEShortField("len",None), ]
86
87    def pre_dissect(self, s):
88        # Recieve data as LE stored as
89        # .... 1111 0100 1100 = handle
90        # 1010 .... .... .... = flags
91        # And turn it into
92        # 1111 0100 1100 .... = handle
93        # .... .... .... 1010 = flags
94        hf = socket.ntohs(struct.unpack("!H", s[:2])[0])
95        r = ((hf & 0x0fff) << 4) + (hf >> 12)
96        return struct.pack("!H", r) + s[2:]
97
98    def post_dissect(self, s):
99        self.raw_packet_cache = None # Reset packet to allow post_build
100        return s
101
102    def post_build(self, p, pay):
103        p += pay
104        if self.len is None:
105            p = p[:2] + struct.pack("<H", len(pay)) + p[4:]
106        # Reverse, opposite of pre_dissect
107        hf = struct.unpack("!H", p[:2])[0]
108        r = socket.ntohs(((hf & 0xf) << 12) + (hf >> 4))
109        return struct.pack("!H", r) + p[2:]
110
111
112class L2CAP_Hdr(Packet):
113    name = "L2CAP header"
114    fields_desc = [ LEShortField("len",None),
115            LEShortEnumField("cid",0,{1:"control", 4:"attribute"}),]
116
117    def post_build(self, p, pay):
118        p += pay
119        if self.len is None:
120            p = struct.pack("<H", len(pay)) + p[2:]
121        return p
122
123
124
125class L2CAP_CmdHdr(Packet):
126    name = "L2CAP command header"
127    fields_desc = [
128        ByteEnumField("code",8,{1:"rej",2:"conn_req",3:"conn_resp",
129                                4:"conf_req",5:"conf_resp",6:"disconn_req",
130                                7:"disconn_resp",8:"echo_req",9:"echo_resp",
131                                10:"info_req",11:"info_resp", 18:"conn_param_update_req",
132                                19:"conn_param_update_resp"}),
133        ByteField("id",0),
134        LEShortField("len",None) ]
135    def post_build(self, p, pay):
136        p += pay
137        if self.len is None:
138            p = p[:2] + struct.pack("<H", len(pay)) + p[4:]
139        return p
140    def answers(self, other):
141        if other.id == self.id:
142            if self.code == 1:
143                return 1
144            if other.code in [2,4,6,8,10,18] and self.code == other.code+1:
145                if other.code == 8:
146                    return 1
147                return self.payload.answers(other.payload)
148        return 0
149
150class L2CAP_ConnReq(Packet):
151    name = "L2CAP Conn Req"
152    fields_desc = [ LEShortEnumField("psm",0,{1:"SDP",3:"RFCOMM",5:"telephony control"}),
153                    LEShortField("scid",0),
154                    ]
155
156class L2CAP_ConnResp(Packet):
157    name = "L2CAP Conn Resp"
158    fields_desc = [ LEShortField("dcid",0),
159                    LEShortField("scid",0),
160                    LEShortEnumField("result",0,["success", "pend", "cr_bad_psm", "cr_sec_block", "cr_no_mem", "reserved","cr_inval_scid", "cr_scid_in_use"]),
161                    LEShortEnumField("status",0,["no_info", "authen_pend", "author_pend", "reserved"]),
162                    ]
163    def answers(self, other):
164        return isinstance(other, L2CAP_ConnReq) and self.dcid == other.scid
165
166class L2CAP_CmdRej(Packet):
167    name = "L2CAP Command Rej"
168    fields_desc = [ LEShortField("reason",0),
169                    ]
170
171
172class L2CAP_ConfReq(Packet):
173    name = "L2CAP Conf Req"
174    fields_desc = [ LEShortField("dcid",0),
175                    LEShortField("flags",0),
176                    ]
177
178class L2CAP_ConfResp(Packet):
179    name = "L2CAP Conf Resp"
180    fields_desc = [ LEShortField("scid",0),
181                    LEShortField("flags",0),
182                    LEShortEnumField("result",0,["success","unaccept","reject","unknown"]),
183                    ]
184    def answers(self, other):
185        return isinstance(other, L2CAP_ConfReq) and self.scid == other.dcid
186
187
188class L2CAP_DisconnReq(Packet):
189    name = "L2CAP Disconn Req"
190    fields_desc = [ LEShortField("dcid",0),
191                    LEShortField("scid",0), ]
192
193class L2CAP_DisconnResp(Packet):
194    name = "L2CAP Disconn Resp"
195    fields_desc = [ LEShortField("dcid",0),
196                    LEShortField("scid",0), ]
197    def answers(self, other):
198        return self.scid == other.scid
199
200
201
202class L2CAP_InfoReq(Packet):
203    name = "L2CAP Info Req"
204    fields_desc = [ LEShortEnumField("type",0,{1:"CL_MTU",2:"FEAT_MASK"}),
205                    StrField("data","")
206                    ]
207
208
209class L2CAP_InfoResp(Packet):
210    name = "L2CAP Info Resp"
211    fields_desc = [ LEShortField("type",0),
212                    LEShortEnumField("result",0,["success","not_supp"]),
213                    StrField("data",""), ]
214    def answers(self, other):
215        return self.type == other.type
216
217
218class L2CAP_Connection_Parameter_Update_Request(Packet):
219    name = "L2CAP Connection Parameter Update Request"
220    fields_desc = [ LEShortField("min_interval", 0),
221                    LEShortField("max_interval", 0),
222                    LEShortField("slave_latency", 0),
223                    LEShortField("timeout_mult", 0), ]
224
225
226class L2CAP_Connection_Parameter_Update_Response(Packet):
227    name = "L2CAP Connection Parameter Update Response"
228    fields_desc = [ LEShortField("move_result", 0), ]
229
230
231class ATT_Hdr(Packet):
232    name = "ATT header"
233    fields_desc = [ XByteField("opcode", None), ]
234
235
236class ATT_Error_Response(Packet):
237    name = "Error Response"
238    fields_desc = [ XByteField("request", 0),
239                    LEShortField("handle", 0),
240                    XByteField("ecode", 0), ]
241
242class ATT_Exchange_MTU_Request(Packet):
243    name = "Exchange MTU Request"
244    fields_desc = [ LEShortField("mtu", 0), ]
245
246class ATT_Exchange_MTU_Response(Packet):
247    name = "Exchange MTU Response"
248    fields_desc = [ LEShortField("mtu", 0), ]
249
250class ATT_Find_Information_Request(Packet):
251    name = "Find Information Request"
252    fields_desc = [ XLEShortField("start", 0x0000),
253                    XLEShortField("end", 0xffff), ]
254
255class ATT_Find_Information_Response(Packet):
256    name = "Find Information Reponse"
257    fields_desc = [ XByteField("format", 1),
258                    StrField("data", "") ]
259
260class ATT_Find_By_Type_Value_Request(Packet):
261    name = "Find By Type Value Request"
262    fields_desc = [ XLEShortField("start", 0x0001),
263                    XLEShortField("end", 0xffff),
264                    XLEShortField("uuid", None),
265                    StrField("data", ""), ]
266
267class ATT_Find_By_Type_Value_Response(Packet):
268    name = "Find By Type Value Response"
269    fields_desc = [ StrField("handles", ""), ]
270
271class ATT_Read_By_Type_Request_128bit(Packet):
272    name = "Read By Type Request"
273    fields_desc = [ XLEShortField("start", 0x0001),
274                    XLEShortField("end", 0xffff),
275                    XLELongField("uuid1", None),
276                    XLELongField("uuid2", None)]
277    @classmethod
278    def dispatch_hook(cls, _pkt=None, *args, **kargs):
279        if _pkt and len(_pkt) == 6:
280            return ATT_Read_By_Type_Request
281        return ATT_Read_By_Type_Request_128bit
282
283class ATT_Read_By_Type_Request(Packet):
284    name = "Read By Type Request"
285    fields_desc = [ XLEShortField("start", 0x0001),
286                    XLEShortField("end", 0xffff),
287                    XLEShortField("uuid", None)]
288
289class ATT_Read_By_Type_Response(Packet):
290    name = "Read By Type Response"
291    # fields_desc = [ FieldLenField("len", None, length_of="data", fmt="B"),
292    #                 StrLenField("data", "", length_from=lambda pkt:pkt.len), ]
293    fields_desc = [ StrField("data", "") ]
294
295class ATT_Read_Request(Packet):
296    name = "Read Request"
297    fields_desc = [ XLEShortField("gatt_handle", 0), ]
298
299class ATT_Read_Response(Packet):
300    name = "Read Response"
301    fields_desc = [ StrField("value", ""), ]
302
303class ATT_Read_By_Group_Type_Request(Packet):
304    name = "Read By Group Type Request"
305    fields_desc = [ XLEShortField("start", 0),
306                    XLEShortField("end", 0xffff),
307                    XLEShortField("uuid", 0), ]
308
309class ATT_Read_By_Group_Type_Response(Packet):
310    name = "Read By Group Type Response"
311    fields_desc = [ XByteField("length", 0),
312                    StrField("data", ""), ]
313
314class ATT_Write_Request(Packet):
315    name = "Write Request"
316    fields_desc = [ XLEShortField("gatt_handle", 0),
317                    StrField("data", ""), ]
318
319class ATT_Write_Command(Packet):
320    name = "Write Request"
321    fields_desc = [ XLEShortField("gatt_handle", 0),
322                    StrField("data", ""), ]
323
324class ATT_Write_Response(Packet):
325    name = "Write Response"
326    fields_desc = [ ]
327
328class ATT_Handle_Value_Notification(Packet):
329    name = "Handle Value Notification"
330    fields_desc = [ XLEShortField("handle", 0),
331                    StrField("value", ""), ]
332
333
334class SM_Hdr(Packet):
335    name = "SM header"
336    fields_desc = [ ByteField("sm_command", None) ]
337
338
339class SM_Pairing_Request(Packet):
340    name = "Pairing Request"
341    fields_desc = [ ByteEnumField("iocap", 3, {0:"DisplayOnly", 1:"DisplayYesNo", 2:"KeyboardOnly", 3:"NoInputNoOutput", 4:"KeyboardDisplay"}),
342                    ByteEnumField("oob", 0, {0:"Not Present", 1:"Present (from remote device)"}),
343                    BitField("authentication", 0, 8),
344                    ByteField("max_key_size", 16),
345                    ByteField("initiator_key_distribution", 0),
346                    ByteField("responder_key_distribution", 0), ]
347
348class SM_Pairing_Response(Packet):
349    name = "Pairing Response"
350    fields_desc = [ ByteEnumField("iocap", 3, {0:"DisplayOnly", 1:"DisplayYesNo", 2:"KeyboardOnly", 3:"NoInputNoOutput", 4:"KeyboardDisplay"}),
351                    ByteEnumField("oob", 0, {0:"Not Present", 1:"Present (from remote device)"}),
352                    BitField("authentication", 0, 8),
353                    ByteField("max_key_size", 16),
354                    ByteField("initiator_key_distribution", 0),
355                    ByteField("responder_key_distribution", 0), ]
356
357
358class SM_Confirm(Packet):
359    name = "Pairing Confirm"
360    fields_desc = [ StrFixedLenField("confirm", b'\x00' * 16, 16) ]
361
362class SM_Random(Packet):
363    name = "Pairing Random"
364    fields_desc = [ StrFixedLenField("random", b'\x00' * 16, 16) ]
365
366class SM_Failed(Packet):
367    name = "Pairing Failed"
368    fields_desc = [ XByteField("reason", 0) ]
369
370class SM_Encryption_Information(Packet):
371    name = "Encryption Information"
372    fields_desc = [ StrFixedLenField("ltk", b"\x00" * 16, 16), ]
373
374class SM_Master_Identification(Packet):
375    name = "Master Identification"
376    fields_desc = [ XLEShortField("ediv", 0),
377                    StrFixedLenField("rand", b'\x00' * 8, 8), ]
378
379class SM_Identity_Information(Packet):
380    name = "Identity Information"
381    fields_desc = [ StrFixedLenField("irk", b'\x00' * 16, 16), ]
382
383class SM_Identity_Address_Information(Packet):
384    name = "Identity Address Information"
385    fields_desc = [ ByteEnumField("atype", 0, {0:"public"}),
386                    LEMACField("address", None), ]
387
388class SM_Signing_Information(Packet):
389    name = "Signing Information"
390    fields_desc = [ StrFixedLenField("csrk", b'\x00' * 16, 16), ]
391
392
393class EIR_Hdr(Packet):
394    name = "EIR Header"
395    fields_desc = [
396        LenField("len", None, fmt="B", adjust=lambda x: x+1), # Add bytes mark
397        ByteEnumField("type", 0, {
398            0x01: "flags",
399            0x02: "incomplete_list_16_bit_svc_uuids",
400            0x03: "complete_list_16_bit_svc_uuids",
401            0x04: "incomplete_list_32_bit_svc_uuids",
402            0x05: "complete_list_32_bit_svc_uuids",
403            0x06: "incomplete_list_128_bit_svc_uuids",
404            0x07: "complete_list_128_bit_svc_uuids",
405            0x08: "shortened_local_name",
406            0x09: "complete_local_name",
407            0x0a: "tx_power_level",
408            0x0d: "class_of_device",
409            0x0e: "simple_pairing_hash",
410            0x0f: "simple_pairing_rand",
411            0x10: "sec_mgr_tk",
412            0x11: "sec_mgr_oob_flags",
413            0x12: "slave_conn_intvl_range",
414            0x17: "pub_target_addr",
415            0x18: "rand_target_addr",
416            0x19: "appearance",
417            0x1a: "adv_intvl",
418            0x1b: "le_addr",
419            0x1c: "le_role",
420            0x14: "list_16_bit_svc_sollication_uuids",
421            0x1f: "list_32_bit_svc_sollication_uuids",
422            0x15: "list_128_bit_svc_sollication_uuids",
423            0x16: "svc_data_16_bit_uuid",
424            0x20: "svc_data_32_bit_uuid",
425            0x21: "svc_data_128_bit_uuid",
426            0x22: "sec_conn_confirm",
427            0x22: "sec_conn_rand",
428            0x24: "uri",
429            0xff: "mfg_specific_data",
430        }),
431    ]
432
433    def mysummary(self):
434        return self.sprintf("EIR %type%")
435
436class EIR_Element(Packet):
437    name = "EIR Element"
438
439    def extract_padding(self, s):
440        # Needed to end each EIR_Element packet and make PacketListField work.
441        return '', s
442
443    @staticmethod
444    def length_from(pkt):
445        if not pkt.underlayer:
446            warning("Missing an upper-layer")
447            return 0
448        # 'type' byte is included in the length, so substract 1:
449        return pkt.underlayer.len - 1
450
451class EIR_Raw(EIR_Element):
452    name = "EIR Raw"
453    fields_desc = [
454        StrLenField("data", "", length_from=EIR_Element.length_from)
455    ]
456
457class EIR_Flags(EIR_Element):
458    name = "Flags"
459    fields_desc = [
460        FlagsField("flags", 0x2, 8,
461                   ["limited_disc_mode", "general_disc_mode",
462                    "br_edr_not_supported", "simul_le_br_edr_ctrl",
463                    "simul_le_br_edr_host"] + 3*["reserved"])
464    ]
465
466class EIR_CompleteList16BitServiceUUIDs(EIR_Element):
467    name = "Complete list of 16-bit service UUIDs"
468    fields_desc = [
469        FieldListField("svc_uuids", None, XLEShortField("uuid", 0),
470                       length_from=EIR_Element.length_from)
471    ]
472
473class EIR_IncompleteList16BitServiceUUIDs(EIR_CompleteList16BitServiceUUIDs):
474    name = "Incomplete list of 16-bit service UUIDs"
475
476class EIR_CompleteLocalName(EIR_Element):
477    name = "Complete Local Name"
478    fields_desc = [
479        StrLenField("local_name", "", length_from=EIR_Element.length_from)
480    ]
481
482class EIR_ShortenedLocalName(EIR_CompleteLocalName):
483    name = "Shortened Local Name"
484
485class EIR_TX_Power_Level(EIR_Element):
486    name = "TX Power Level"
487    fields_desc = [SignedByteField("level", 0)]
488
489class EIR_Manufacturer_Specific_Data(EIR_Element):
490    name = "EIR Manufacturer Specific Data"
491    fields_desc = [
492        XLEShortField("company_id", 0),
493        StrLenField("data", "",
494                    length_from=lambda pkt: EIR_Element.length_from(pkt) - 2)
495    ]
496
497
498class HCI_Command_Hdr(Packet):
499    name = "HCI Command header"
500    fields_desc = [ XLEShortField("opcode", 0),
501                    ByteField("len", None), ]
502
503    def post_build(self, p, pay):
504        p += pay
505        if self.len is None:
506            p = p[:2] + struct.pack("B", len(pay)) + p[3:]
507        return p
508
509class HCI_Cmd_Reset(Packet):
510    name = "Reset"
511
512class HCI_Cmd_Set_Event_Filter(Packet):
513    name = "Set Event Filter"
514    fields_desc = [ ByteEnumField("type", 0, {0:"clear"}), ]
515
516class HCI_Cmd_Connect_Accept_Timeout(Packet):
517    name = "Connection Attempt Timeout"
518    fields_desc = [ LEShortField("timeout", 32000) ] # 32000 slots is 20000 msec
519
520class HCI_Cmd_LE_Host_Supported(Packet):
521    name = "LE Host Supported"
522    fields_desc = [ ByteField("supported", 1),
523                    ByteField("simultaneous", 1), ]
524
525class HCI_Cmd_Set_Event_Mask(Packet):
526    name = "Set Event Mask"
527    fields_desc = [ StrFixedLenField("mask", b"\xff\xff\xfb\xff\x07\xf8\xbf\x3d", 8) ]
528
529class HCI_Cmd_Read_BD_Addr(Packet):
530    name = "Read BD Addr"
531
532
533class HCI_Cmd_LE_Set_Scan_Parameters(Packet):
534    name = "LE Set Scan Parameters"
535    fields_desc = [ ByteEnumField("type", 1, {1:"active"}),
536                    XLEShortField("interval", 16),
537                    XLEShortField("window", 16),
538                    ByteEnumField("atype", 0, {0:"public"}),
539                    ByteEnumField("policy", 0, {0:"all"}), ]
540
541class HCI_Cmd_LE_Set_Scan_Enable(Packet):
542    name = "LE Set Scan Enable"
543    fields_desc = [ ByteField("enable", 1),
544                    ByteField("filter_dups", 1), ]
545
546class HCI_Cmd_Disconnect(Packet):
547    name = "Disconnect"
548    fields_desc = [ XLEShortField("handle", 0),
549                    ByteField("reason", 0x13), ]
550
551class HCI_Cmd_LE_Create_Connection(Packet):
552    name = "LE Create Connection"
553    fields_desc = [ LEShortField("interval", 96),
554                    LEShortField("window", 48),
555                    ByteEnumField("filter", 0, {0:"address"}),
556                    ByteEnumField("patype", 0, {0:"public", 1:"random"}),
557                    LEMACField("paddr", None),
558                    ByteEnumField("atype", 0, {0:"public", 1:"random"}),
559                    LEShortField("min_interval", 40),
560                    LEShortField("max_interval", 56),
561                    LEShortField("latency", 0),
562                    LEShortField("timeout", 42),
563                    LEShortField("min_ce", 0),
564                    LEShortField("max_ce", 0), ]
565
566class HCI_Cmd_LE_Create_Connection_Cancel(Packet):
567    name = "LE Create Connection Cancel"
568
569class HCI_Cmd_LE_Connection_Update(Packet):
570    name = "LE Connection Update"
571    fields_desc = [ XLEShortField("handle", 0),
572                    XLEShortField("min_interval", 0),
573                    XLEShortField("max_interval", 0),
574                    XLEShortField("latency", 0),
575                    XLEShortField("timeout", 0),
576                    LEShortField("min_ce", 0),
577                    LEShortField("max_ce", 0xffff), ]
578
579class HCI_Cmd_LE_Read_Buffer_Size(Packet):
580    name = "LE Read Buffer Size"
581
582class HCI_Cmd_LE_Set_Random_Address(Packet):
583    name = "LE Set Random Address"
584    fields_desc = [ LEMACField("address", None) ]
585
586class HCI_Cmd_LE_Set_Advertising_Parameters(Packet):
587    name = "LE Set Advertising Parameters"
588    fields_desc = [ LEShortField("interval_min", 0x0800),
589                    LEShortField("interval_max", 0x0800),
590                    ByteEnumField("adv_type", 0, {0:"ADV_IND", 1:"ADV_DIRECT_IND", 2:"ADV_SCAN_IND", 3:"ADV_NONCONN_IND", 4:"ADV_DIRECT_IND_LOW"}),
591                    ByteEnumField("oatype", 0, {0:"public", 1:"random"}),
592                    ByteEnumField("datype", 0, {0:"public", 1:"random"}),
593                    LEMACField("daddr", None),
594                    ByteField("channel_map", 7),
595                    ByteEnumField("filter_policy", 0, {0:"all:all", 1:"connect:all scan:whitelist", 2:"connect:whitelist scan:all", 3:"all:whitelist"}), ]
596
597class HCI_Cmd_LE_Set_Advertising_Data(Packet):
598    name = "LE Set Advertising Data"
599    fields_desc = [ FieldLenField("len", None, length_of="data", fmt="B"),
600                    StrLenField("data", "", length_from=lambda pkt:pkt.len), ]
601
602class HCI_Cmd_LE_Set_Advertise_Enable(Packet):
603    name = "LE Set Advertise Enable"
604    fields_desc = [ ByteField("enable", 0) ]
605
606class HCI_Cmd_LE_Start_Encryption_Request(Packet):
607    name = "LE Start Encryption"
608    fields_desc = [ LEShortField("handle", 0),
609                    StrFixedLenField("rand", None, 8),
610                    XLEShortField("ediv", 0),
611                    StrFixedLenField("ltk", b'\x00' * 16, 16), ]
612
613class HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply(Packet):
614    name = "LE Long Term Key Request Negative Reply"
615    fields_desc = [ LEShortField("handle", 0), ]
616
617class HCI_Cmd_LE_Long_Term_Key_Request_Reply(Packet):
618    name = "LE Long Term Key Request Reply"
619    fields_desc = [ LEShortField("handle", 0),
620                    StrFixedLenField("ltk", b'\x00' * 16, 16), ]
621
622class HCI_Event_Hdr(Packet):
623    name = "HCI Event header"
624    fields_desc = [ XByteField("code", 0),
625                    ByteField("length", 0), ]
626
627
628class HCI_Event_Disconnection_Complete(Packet):
629    name = "Disconnection Complete"
630    fields_desc = [ ByteEnumField("status", 0, {0:"success"}),
631                    LEShortField("handle", 0),
632                    XByteField("reason", 0), ]
633
634
635class HCI_Event_Encryption_Change(Packet):
636    name = "Encryption Change"
637    fields_desc = [ ByteEnumField("status", 0, {0:"change has occurred"}),
638                    LEShortField("handle", 0),
639                    ByteEnumField("enabled", 0, {0:"OFF", 1:"ON (LE)", 2:"ON (BR/EDR)"}), ]
640
641class HCI_Event_Command_Complete(Packet):
642    name = "Command Complete"
643    fields_desc = [ ByteField("number", 0),
644                    XLEShortField("opcode", 0),
645                    ByteEnumField("status", 0, {0:"success"}), ]
646
647
648class HCI_Cmd_Complete_Read_BD_Addr(Packet):
649    name = "Read BD Addr"
650    fields_desc = [ LEMACField("addr", None), ]
651
652
653
654class HCI_Event_Command_Status(Packet):
655    name = "Command Status"
656    fields_desc = [ ByteEnumField("status", 0, {0:"pending"}),
657                    ByteField("number", 0),
658                    XLEShortField("opcode", None), ]
659
660class HCI_Event_Number_Of_Completed_Packets(Packet):
661    name = "Number Of Completed Packets"
662    fields_desc = [ ByteField("number", 0) ]
663
664class HCI_Event_LE_Meta(Packet):
665    name = "LE Meta"
666    fields_desc = [ ByteEnumField("event", 0, {2:"advertising_report"}) ]
667
668class HCI_LE_Meta_Connection_Complete(Packet):
669    name = "Connection Complete"
670    fields_desc = [ ByteEnumField("status", 0, {0:"success"}),
671                    LEShortField("handle", 0),
672                    ByteEnumField("role", 0, {0:"master"}),
673                    ByteEnumField("patype", 0, {0:"public", 1:"random"}),
674                    LEMACField("paddr", None),
675                    LEShortField("interval", 54),
676                    LEShortField("latency", 0),
677                    LEShortField("supervision", 42),
678                    XByteField("clock_latency", 5), ]
679
680class HCI_LE_Meta_Connection_Update_Complete(Packet):
681    name = "Connection Update Complete"
682    fields_desc = [ ByteEnumField("status", 0, {0:"success"}),
683                    LEShortField("handle", 0),
684                    LEShortField("interval", 54),
685                    LEShortField("latency", 0),
686                    LEShortField("timeout", 42), ]
687
688class HCI_LE_Meta_Advertising_Report(Packet):
689    name = "Advertising Report"
690    fields_desc = [ ByteField("number", 0),
691                    ByteEnumField("type", 0, {0:"conn_und", 4:"scan_rsp"}),
692                    ByteEnumField("atype", 0, {0:"public", 1:"random"}),
693                    LEMACField("addr", None),
694                    FieldLenField("len", None, length_of="data", fmt="B"),
695                    PacketListField("data", [], EIR_Hdr,
696                                    length_from=lambda pkt:pkt.len),
697                    SignedByteField("rssi", 0)]
698
699
700class HCI_LE_Meta_Long_Term_Key_Request(Packet):
701    name = "Long Term Key Request"
702    fields_desc = [ LEShortField("handle", 0),
703                    StrFixedLenField("rand", None, 8),
704                    XLEShortField("ediv", 0), ]
705
706
707bind_layers( HCI_Hdr,       HCI_Command_Hdr,    type=1)
708bind_layers( HCI_Hdr,       HCI_ACL_Hdr,        type=2)
709bind_layers( HCI_Hdr,       HCI_Event_Hdr,      type=4)
710bind_layers( HCI_Hdr,       conf.raw_layer,           )
711
712conf.l2types.register(DLT_BLUETOOTH_HCI_H4, HCI_Hdr)
713
714bind_layers( HCI_Command_Hdr, HCI_Cmd_Reset, opcode=0x0c03)
715bind_layers( HCI_Command_Hdr, HCI_Cmd_Set_Event_Mask, opcode=0x0c01)
716bind_layers( HCI_Command_Hdr, HCI_Cmd_Set_Event_Filter, opcode=0x0c05)
717bind_layers( HCI_Command_Hdr, HCI_Cmd_Connect_Accept_Timeout, opcode=0x0c16)
718bind_layers( HCI_Command_Hdr, HCI_Cmd_LE_Host_Supported, opcode=0x0c6d)
719bind_layers( HCI_Command_Hdr, HCI_Cmd_Read_BD_Addr, opcode=0x1009)
720bind_layers( HCI_Command_Hdr, HCI_Cmd_LE_Read_Buffer_Size, opcode=0x2002)
721bind_layers( HCI_Command_Hdr, HCI_Cmd_LE_Set_Random_Address, opcode=0x2005)
722bind_layers( HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertising_Parameters, opcode=0x2006)
723bind_layers( HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertising_Data, opcode=0x2008)
724bind_layers( HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertise_Enable, opcode=0x200a)
725bind_layers( HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Parameters, opcode=0x200b)
726bind_layers( HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Enable, opcode=0x200c)
727bind_layers( HCI_Command_Hdr, HCI_Cmd_Disconnect, opcode=0x406)
728bind_layers( HCI_Command_Hdr, HCI_Cmd_LE_Create_Connection, opcode=0x200d)
729bind_layers( HCI_Command_Hdr, HCI_Cmd_LE_Create_Connection_Cancel, opcode=0x200e)
730bind_layers( HCI_Command_Hdr, HCI_Cmd_LE_Connection_Update, opcode=0x2013)
731
732
733bind_layers( HCI_Command_Hdr, HCI_Cmd_LE_Start_Encryption_Request, opcode=0x2019)
734
735bind_layers( HCI_Command_Hdr, HCI_Cmd_LE_Long_Term_Key_Request_Reply, opcode=0x201a)
736bind_layers( HCI_Command_Hdr, HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply, opcode=0x201b)
737
738bind_layers( HCI_Event_Hdr, HCI_Event_Disconnection_Complete, code=0x5)
739bind_layers( HCI_Event_Hdr, HCI_Event_Encryption_Change, code=0x8)
740bind_layers( HCI_Event_Hdr, HCI_Event_Command_Complete, code=0xe)
741bind_layers( HCI_Event_Hdr, HCI_Event_Command_Status, code=0xf)
742bind_layers( HCI_Event_Hdr, HCI_Event_Number_Of_Completed_Packets, code=0x13)
743bind_layers( HCI_Event_Hdr, HCI_Event_LE_Meta, code=0x3e)
744
745bind_layers( HCI_Event_Command_Complete, HCI_Cmd_Complete_Read_BD_Addr, opcode=0x1009)
746
747bind_layers( HCI_Event_LE_Meta, HCI_LE_Meta_Connection_Complete, event=1)
748bind_layers( HCI_Event_LE_Meta, HCI_LE_Meta_Advertising_Report, event=2)
749bind_layers( HCI_Event_LE_Meta, HCI_LE_Meta_Connection_Update_Complete, event=3)
750bind_layers( HCI_Event_LE_Meta, HCI_LE_Meta_Long_Term_Key_Request, event=5)
751
752bind_layers(EIR_Hdr, EIR_Flags, type=0x01)
753bind_layers(EIR_Hdr, EIR_IncompleteList16BitServiceUUIDs, type=0x02)
754bind_layers(EIR_Hdr, EIR_CompleteList16BitServiceUUIDs, type=0x03)
755bind_layers(EIR_Hdr, EIR_ShortenedLocalName, type=0x08)
756bind_layers(EIR_Hdr, EIR_CompleteLocalName, type=0x09)
757bind_layers(EIR_Hdr, EIR_TX_Power_Level, type=0x0a)
758bind_layers(EIR_Hdr, EIR_Manufacturer_Specific_Data, type=0xff)
759bind_layers(EIR_Hdr, EIR_Raw)
760
761bind_layers( HCI_ACL_Hdr,   L2CAP_Hdr,     )
762bind_layers( L2CAP_Hdr,     L2CAP_CmdHdr,      cid=1)
763bind_layers( L2CAP_Hdr,     L2CAP_CmdHdr,      cid=5) #LE L2CAP Signaling Channel
764bind_layers( L2CAP_CmdHdr,  L2CAP_CmdRej,      code=1)
765bind_layers( L2CAP_CmdHdr,  L2CAP_ConnReq,     code=2)
766bind_layers( L2CAP_CmdHdr,  L2CAP_ConnResp,    code=3)
767bind_layers( L2CAP_CmdHdr,  L2CAP_ConfReq,     code=4)
768bind_layers( L2CAP_CmdHdr,  L2CAP_ConfResp,    code=5)
769bind_layers( L2CAP_CmdHdr,  L2CAP_DisconnReq,  code=6)
770bind_layers( L2CAP_CmdHdr,  L2CAP_DisconnResp, code=7)
771bind_layers( L2CAP_CmdHdr,  L2CAP_InfoReq,     code=10)
772bind_layers( L2CAP_CmdHdr,  L2CAP_InfoResp,    code=11)
773bind_layers( L2CAP_CmdHdr,  L2CAP_Connection_Parameter_Update_Request,    code=18)
774bind_layers( L2CAP_CmdHdr,  L2CAP_Connection_Parameter_Update_Response,    code=19)
775bind_layers( L2CAP_Hdr,     ATT_Hdr,           cid=4)
776bind_layers( ATT_Hdr,       ATT_Error_Response, opcode=0x1)
777bind_layers( ATT_Hdr,       ATT_Exchange_MTU_Request, opcode=0x2)
778bind_layers( ATT_Hdr,       ATT_Exchange_MTU_Response, opcode=0x3)
779bind_layers( ATT_Hdr,       ATT_Find_Information_Request, opcode=0x4)
780bind_layers( ATT_Hdr,       ATT_Find_Information_Response, opcode=0x5)
781bind_layers( ATT_Hdr,       ATT_Find_By_Type_Value_Request, opcode=0x6)
782bind_layers( ATT_Hdr,       ATT_Find_By_Type_Value_Response, opcode=0x7)
783bind_layers( ATT_Hdr,       ATT_Read_By_Type_Request_128bit, opcode=0x8)
784bind_layers( ATT_Hdr,       ATT_Read_By_Type_Request, opcode=0x8)
785bind_layers( ATT_Hdr,       ATT_Read_By_Type_Response, opcode=0x9)
786bind_layers( ATT_Hdr,       ATT_Read_Request, opcode=0xa)
787bind_layers( ATT_Hdr,       ATT_Read_Response, opcode=0xb)
788bind_layers( ATT_Hdr,       ATT_Read_By_Group_Type_Request, opcode=0x10)
789bind_layers( ATT_Hdr,       ATT_Read_By_Group_Type_Response, opcode=0x11)
790bind_layers( ATT_Hdr,       ATT_Write_Request, opcode=0x12)
791bind_layers( ATT_Hdr,       ATT_Write_Response, opcode=0x13)
792bind_layers( ATT_Hdr,       ATT_Write_Command, opcode=0x52)
793bind_layers( ATT_Hdr,       ATT_Handle_Value_Notification, opcode=0x1b)
794bind_layers( L2CAP_Hdr,     SM_Hdr,            cid=6)
795bind_layers( SM_Hdr,        SM_Pairing_Request, sm_command=1)
796bind_layers( SM_Hdr,        SM_Pairing_Response, sm_command=2)
797bind_layers( SM_Hdr,        SM_Confirm,        sm_command=3)
798bind_layers( SM_Hdr,        SM_Random,         sm_command=4)
799bind_layers( SM_Hdr,        SM_Failed,         sm_command=5)
800bind_layers( SM_Hdr,        SM_Encryption_Information, sm_command=6)
801bind_layers( SM_Hdr,        SM_Master_Identification, sm_command=7)
802bind_layers( SM_Hdr,        SM_Identity_Information, sm_command=8)
803bind_layers( SM_Hdr,        SM_Identity_Address_Information, sm_command=9)
804bind_layers( SM_Hdr,        SM_Signing_Information, sm_command=0x0a)
805
806class BluetoothSocketError(BaseException):
807    pass
808
809class BluetoothCommandError(BaseException):
810    pass
811
812class BluetoothL2CAPSocket(SuperSocket):
813    desc = "read/write packets on a connected L2CAP socket"
814    def __init__(self, bt_address):
815        if WINDOWS:
816            warning("Not available on Windows")
817            return
818        s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW,
819                          socket.BTPROTO_L2CAP)
820        s.connect((bt_address,0))
821        self.ins = self.outs = s
822
823    def recv(self, x=MTU):
824        return L2CAP_CmdHdr(self.ins.recv(x))
825
826class BluetoothRFCommSocket(BluetoothL2CAPSocket):
827    """read/write packets on a connected RFCOMM socket"""
828    def __init__(self, bt_address, port=0):
829        s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW,
830                          socket.BTPROTO_RFCOMM)
831        s.connect((bt_address,port))
832        self.ins = self.outs = s
833
834class BluetoothHCISocket(SuperSocket):
835    desc = "read/write on a BlueTooth HCI socket"
836    def __init__(self, iface=0x10000, type=None):
837        if WINDOWS:
838            warning("Not available on Windows")
839            return
840        s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI)
841        s.setsockopt(socket.SOL_HCI, socket.HCI_DATA_DIR,1)
842        s.setsockopt(socket.SOL_HCI, socket.HCI_TIME_STAMP,1)
843        s.setsockopt(socket.SOL_HCI, socket.HCI_FILTER, struct.pack("IIIh2x", 0xffffffff,0xffffffff,0xffffffff,0)) #type mask, event mask, event mask, opcode
844        s.bind((iface,))
845        self.ins = self.outs = s
846#        s.connect((peer,0))
847
848
849    def recv(self, x):
850        return HCI_Hdr(self.ins.recv(x))
851
852class sockaddr_hci(Structure):
853    _fields_ = [
854        ("sin_family",      c_ushort),
855        ("hci_dev",         c_ushort),
856        ("hci_channel",     c_ushort),
857    ]
858
859class BluetoothUserSocket(SuperSocket):
860    desc = "read/write H4 over a Bluetooth user channel"
861    def __init__(self, adapter_index=0):
862        if WINDOWS:
863            warning("Not available on Windows")
864            return
865        # s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI)
866        # s.bind((0,1))
867
868        # yeah, if only
869        # thanks to Python's weak ass socket and bind implementations, we have
870        # to call down into libc with ctypes
871
872        sockaddr_hcip = POINTER(sockaddr_hci)
873        cdll.LoadLibrary("libc.so.6")
874        libc = CDLL("libc.so.6")
875
876        socket_c = libc.socket
877        socket_c.argtypes = (c_int, c_int, c_int);
878        socket_c.restype = c_int
879
880        bind = libc.bind
881        bind.argtypes = (c_int, POINTER(sockaddr_hci), c_int)
882        bind.restype = c_int
883
884        ########
885        ## actual code
886
887        s = socket_c(31, 3, 1) # (AF_BLUETOOTH, SOCK_RAW, HCI_CHANNEL_USER)
888        if s < 0:
889            raise BluetoothSocketError("Unable to open PF_BLUETOOTH socket")
890
891        sa = sockaddr_hci()
892        sa.sin_family = 31  # AF_BLUETOOTH
893        sa.hci_dev = adapter_index # adapter index
894        sa.hci_channel = 1   # HCI_USER_CHANNEL
895
896        r = bind(s, sockaddr_hcip(sa), sizeof(sa))
897        if r != 0:
898            raise BluetoothSocketError("Unable to bind")
899
900        self.ins = self.outs = socket.fromfd(s, 31, 3, 1)
901
902    def send_command(self, cmd):
903        opcode = cmd.opcode
904        self.send(cmd)
905        while True:
906            r = self.recv()
907            if r.type == 0x04 and r.code == 0xe and r.opcode == opcode:
908                if r.status != 0:
909                    raise BluetoothCommandError("Command %x failed with %x" % (opcode, r.status))
910                return r
911
912    def recv(self, x=512):
913        return HCI_Hdr(self.ins.recv(x))
914
915    def readable(self, timeout=0):
916        (ins, outs, foo) = select([self.ins], [], [], timeout)
917        return len(ins) > 0
918
919    def flush(self):
920        while self.readable():
921            self.recv()
922
923conf.BTsocket = BluetoothRFCommSocket
924
925## Bluetooth
926
927@conf.commands.register
928def srbt(bt_address, pkts, inter=0.1, *args, **kargs):
929    """send and receive using a bluetooth socket"""
930    if "port" in kargs.keys():
931        s = conf.BTsocket(bt_address=bt_address, port=kargs.pop("port"))
932    else:
933        s = conf.BTsocket(bt_address=bt_address)
934    a,b = sndrcv(s,pkts,inter=inter,*args,**kargs)
935    s.close()
936    return a,b
937
938@conf.commands.register
939def srbt1(bt_address, pkts, *args, **kargs):
940    """send and receive 1 packet using a bluetooth socket"""
941    a,b = srbt(bt_address, pkts, *args, **kargs)
942    if len(a) > 0:
943        return a[0][1]
944