diff --git a/scapy/layers/bluetooth.py b/scapy/layers/bluetooth.py index 31438ce103e..cca1d5a9086 100644 --- a/scapy/layers/bluetooth.py +++ b/scapy/layers/bluetooth.py @@ -25,6 +25,7 @@ from scapy.packet import bind_layers, Packet from scapy.fields import ( BitField, + XBitField, ByteEnumField, ByteField, FieldLenField, @@ -45,6 +46,7 @@ StrLenField, UUIDField, XByteField, + XLE3BytesField, XLELongField, XStrLenField, XLEShortField, @@ -898,77 +900,54 @@ def extract_padding(self, s): class HCI_Command_Hdr(Packet): name = "HCI Command header" - fields_desc = [XLEShortField("opcode", 0), + fields_desc = [XBitField("ogf", 0, 6, tot_size=-2), + XBitField("ocf", 0, 10, end_tot_size=-2), LenField("len", None, fmt="B"), ] def answers(self, other): return False + @property + def opcode(self): + return (self.ogf << 10) + self.ocf + def post_build(self, p, pay): p += pay if self.len is None: p = p[:2] + struct.pack("B", len(pay)) + p[3:] return p - -class HCI_Cmd_Reset(Packet): - name = "Reset" - - -class HCI_Cmd_Set_Event_Filter(Packet): - name = "Set Event Filter" - fields_desc = [ByteEnumField("type", 0, {0: "clear"}), ] - - -class HCI_Cmd_Connect_Accept_Timeout(Packet): - name = "Connection Attempt Timeout" - fields_desc = [LEShortField("timeout", 32000)] # 32000 slots is 20000 msec - - -class HCI_Cmd_LE_Host_Supported(Packet): - name = "LE Host Supported" - fields_desc = [ByteField("supported", 1), - ByteField("simultaneous", 1), ] - - -class HCI_Cmd_Set_Event_Mask(Packet): - name = "Set Event Mask" - fields_desc = [StrFixedLenField("mask", b"\xff\xff\xfb\xff\x07\xf8\xbf\x3d", 8)] # noqa: E501 - - -class HCI_Cmd_Read_BD_Addr(Packet): - name = "Read BD Addr" +# BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E +# 7 HCI COMMANDS AND EVENTS +# 7.1 LINK CONTROL COMMANDS, the OGF is defined as 0x01 -class HCI_Cmd_Write_Local_Name(Packet): - name = "Write Local Name" - fields_desc = [StrField("name", "")] +class HCI_Cmd_Inquiry(Packet): + name = "HCI_Inquiry" + fields_desc = [XLE3BytesField("lap", 0x9E8B33), + ByteField("inquiry_length", 0), + ByteField("num_responses", 0)] -class HCI_Cmd_Write_Extended_Inquiry_Response(Packet): - name = "Write Extended Inquiry Response" - fields_desc = [ByteField("fec_required", 0), - PacketListField("eir_data", [], EIR_Hdr, - length_from=lambda pkt:pkt.len)] +class HCI_Cmd_Inquiry_Cancel(Packet): + name = "HCI_Inquiry_Cancel" -class HCI_Cmd_LE_Set_Scan_Parameters(Packet): - name = "LE Set Scan Parameters" - fields_desc = [ByteEnumField("type", 1, {1: "active"}), - XLEShortField("interval", 16), - XLEShortField("window", 16), - ByteEnumField("atype", 0, {0: "public"}), - ByteEnumField("policy", 0, {0: "all", 1: "whitelist"})] +class HCI_Cmd_Periodic_Inquiry_Mode(Packet): + name = "HCI_Periodic_Inquiry_Mode" + fields_desc = [LEShortField("max_period_length", 0x0003), + LEShortField("min_period_length", 0x0002), + XLE3BytesField("lap", 0x9E8B33), + ByteField("inquiry_length", 0), + ByteField("num_responses", 0)] -class HCI_Cmd_LE_Set_Scan_Enable(Packet): - name = "LE Set Scan Enable" - fields_desc = [ByteField("enable", 1), - ByteField("filter_dups", 1), ] +class HCI_Cmd_Exit_Peiodic_Inquiry_Mode(Packet): + name = "HCI_Exit_Periodic_Inquiry_Mode" class HCI_Cmd_Create_Connection(Packet): - name = "Create Connection" + name = "HCI_Create_Connection" fields_desc = [LEMACField("bd_addr", None), LEShortField("packet_type", 0xcc18), ByteField("page_scan_repetition_mode", 0x02), @@ -978,100 +957,136 @@ class HCI_Cmd_Create_Connection(Packet): class HCI_Cmd_Disconnect(Packet): - name = "Disconnect" + name = "HCI_Disconnect" fields_desc = [XLEShortField("handle", 0), ByteField("reason", 0x13), ] class HCI_Cmd_Link_Key_Request_Reply(Packet): - name = "Link Key Request Reply" + name = "HCI_Link_Key_Request_Reply" fields_desc = [LEMACField("bd_addr", None), NBytesField("link_key", None, 16), ] class HCI_Cmd_Authentication_Requested(Packet): - name = "Authentication Requested" + name = "HCI_Authentication_Requested" fields_desc = [LEShortField("handle", 0)] class HCI_Cmd_Set_Connection_Encryption(Packet): - name = "Set Connection Encryption" + name = "HCI_Set_Connection_Encryption" fields_desc = [LEShortField("handle", 0), ByteField("encryption_enable", 0)] class HCI_Cmd_Remote_Name_Request(Packet): - name = "Remote Name Request" + name = "HCI_Remote_Name_Request" fields_desc = [LEMACField("bd_addr", None), ByteField("page_scan_repetition_mode", 0x02), ByteField("reserved", 0x0), LEShortField("clock_offset", 0x0), ] -class HCI_Cmd_LE_Create_Connection(Packet): - name = "LE Create Connection" - fields_desc = [LEShortField("interval", 96), - LEShortField("window", 48), - ByteEnumField("filter", 0, {0: "address"}), - ByteEnumField("patype", 0, {0: "public", 1: "random"}), - LEMACField("paddr", None), - ByteEnumField("atype", 0, {0: "public", 1: "random"}), - LEShortField("min_interval", 40), - LEShortField("max_interval", 56), - LEShortField("latency", 0), - LEShortField("timeout", 42), - LEShortField("min_ce", 0), - LEShortField("max_ce", 0), ] +# 7.2 Link Policy commands, the OGF is defined as 0x02 +class HCI_Cmd_Hold_Mode(Packet): + name = "HCI_Hold_Mode" + fields_desc = [LEShortField("connection_handle", 0), + LEShortField("hold_mode_max_interval", 0x0002), + LEShortField("hold_mode_min_interval", 0x0002), ] -class HCI_Cmd_LE_Create_Connection_Cancel(Packet): - name = "LE Create Connection Cancel" +# 7.3 CONTROLLER & BASEBAND COMMANDS, the OGF is defined as 0x03 +class HCI_Cmd_Set_Event_Mask(Packet): + name = "HCI_Set_Event_Mask" + fields_desc = [StrFixedLenField("mask", b"\xff\xff\xfb\xff\x07\xf8\xbf\x3d", 8)] # noqa: E501 -class HCI_Cmd_LE_Read_White_List_Size(Packet): - name = "LE Read White List Size" +class HCI_Cmd_Reset(Packet): + name = "HCI_Reset" -class HCI_Cmd_LE_Clear_White_List(Packet): - name = "LE Clear White List" +class HCI_Cmd_Set_Event_Filter(Packet): + name = "HCI_Set_Event_Filter" + fields_desc = [ByteEnumField("type", 0, {0: "clear"}), ] -class HCI_Cmd_LE_Add_Device_To_White_List(Packet): - name = "LE Add Device to White List" - fields_desc = [ByteEnumField("atype", 0, {0: "public", 1: "random"}), - LEMACField("address", None)] + +class HCI_Cmd_Write_Local_Name(Packet): + name = "HCI_Write_Local_Name" + fields_desc = [StrField("name", "")] -class HCI_Cmd_LE_Remove_Device_From_White_List(HCI_Cmd_LE_Add_Device_To_White_List): # noqa: E501 - name = "LE Remove Device from White List" +class HCI_Cmd_Write_Connect_Accept_Timeout(Packet): + name = "HCI_Write_Connection_Accept_Timeout" + fields_desc = [LEShortField("timeout", 32000)] # 32000 slots is 20000 msec -class HCI_Cmd_LE_Connection_Update(Packet): - name = "LE Connection Update" - fields_desc = [XLEShortField("handle", 0), - XLEShortField("min_interval", 0), - XLEShortField("max_interval", 0), - XLEShortField("latency", 0), - XLEShortField("timeout", 0), - LEShortField("min_ce", 0), - LEShortField("max_ce", 0xffff), ] +class HCI_Cmd_Write_Extended_Inquiry_Response(Packet): + name = "HCI_Write_Extended_Inquiry_Response" + fields_desc = [ByteField("fec_required", 0), + PacketListField("eir_data", [], EIR_Hdr, + length_from=lambda pkt:pkt.len)] -class HCI_Cmd_LE_Read_Buffer_Size(Packet): - name = "LE Read Buffer Size" +class HCI_Cmd_Read_LE_Host_Support(Packet): + name = "HCI_Read_LE_Host_Support" -class HCI_Cmd_LE_Read_Remote_Used_Features(Packet): - name = "LE Read Remote Used Features" - fields_desc = [LEShortField("handle", 64)] +class HCI_Cmd_Write_LE_Host_Support(Packet): + name = "HCI_Write_LE_Host_Support" + fields_desc = [ByteField("supported", 1), + ByteField("unused", 1), ] + + +# 7.4 INFORMATIONAL PARAMETERS, the OGF is defined as 0x04 +class HCI_Cmd_Read_BD_Addr(Packet): + name = "HCI_Read_BD_ADDR" + +# 7.5 STATUS PARAMETERS, the OGF is defined as 0x05 + + +class HCI_Cmd_Read_Link_Quality(Packet): + name = "HCI_Read_Link_Quality" + fields_desc = [LEShortField("handle", 0)] + + +class HCI_Cmd_Read_RSSI(Packet): + name = "HCI_Read_RSSI" + fields_desc = [LEShortField("handle", 0)] + + +# 7.6 TESTING COMMANDS, the OGF is defined as 0x06 +class HCI_Cmd_Read_Loopback_Mode(Packet): + name = "HCI_Read_Loopback_Mode" + + +class HCI_Cmd_Write_Loopback_Mode(Packet): + name = "HCI_Write_Loopback_Mode" + fields_desc = [ByteEnumField("loopback_mode", 0, + {0: "no loopback", + 1: "enable local loopback", + 2: "enable remote loopback"})] + + +# 7.8 LE CONTROLLER COMMANDS, the OGF code is defined as 0x08 +class HCI_Cmd_LE_Read_Buffer_Size_V1(Packet): + name = "HCI_LE_Read_Buffer_Size [v1]" + + +class HCI_Cmd_LE_Read_Buffer_Size_V2(Packet): + name = "HCI_LE_Read_Buffer_Size [v2]" + + +class HCI_Cmd_LE_Read_Local_Supported_Features(Packet): + name = "HCI_LE_Read_Local_Supported_Features" class HCI_Cmd_LE_Set_Random_Address(Packet): - name = "LE Set Random Address" + name = "HCI_LE_Set_Random_Address" fields_desc = [LEMACField("address", None)] class HCI_Cmd_LE_Set_Advertising_Parameters(Packet): - name = "LE Set Advertising Parameters" + name = "HCI_LE_Set_Advertising_Parameters" fields_desc = [LEShortField("interval_min", 0x0800), LEShortField("interval_max", 0x0800), 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 @@ -1083,7 +1098,7 @@ class HCI_Cmd_LE_Set_Advertising_Parameters(Packet): class HCI_Cmd_LE_Set_Advertising_Data(Packet): - name = "LE Set Advertising Data" + name = "HCI_LE_Set_Advertising_Data" fields_desc = [FieldLenField("len", None, length_of="data", fmt="B"), PadField( PacketListField("data", [], EIR_Hdr, @@ -1092,35 +1107,109 @@ class HCI_Cmd_LE_Set_Advertising_Data(Packet): class HCI_Cmd_LE_Set_Scan_Response_Data(Packet): - name = "LE Set Scan Response Data" + name = "HCI_LE_Set_Scan_Response_Data" fields_desc = [FieldLenField("len", None, length_of="data", fmt="B"), StrLenField("data", "", length_from=lambda pkt:pkt.len), ] class HCI_Cmd_LE_Set_Advertise_Enable(Packet): - name = "LE Set Advertise Enable" + name = "HCI_LE_Set_Advertising_Enable" fields_desc = [ByteField("enable", 0)] -class HCI_Cmd_LE_Start_Encryption_Request(Packet): - name = "LE Start Encryption" +class HCI_Cmd_LE_Set_Scan_Parameters(Packet): + name = "HCI_LE_Set_Scan_Parameters" + fields_desc = [ByteEnumField("type", 0, {0: "passive", 1: "active"}), + XLEShortField("interval", 16), + XLEShortField("window", 16), + ByteEnumField("atype", 0, {0: "public", + 1: "random", + 2: "rpa (pub)", + 3: "rpa (random)"}), + ByteEnumField("policy", 0, {0: "all", 1: "whitelist"})] + + +class HCI_Cmd_LE_Set_Scan_Enable(Packet): + name = "HCI_LE_Set_Scan_Enable" + fields_desc = [ByteField("enable", 1), + ByteField("filter_dups", 1), ] + + +class HCI_Cmd_LE_Create_Connection(Packet): + name = "HCI_LE_Create_Connection" + fields_desc = [LEShortField("interval", 96), + LEShortField("window", 48), + ByteEnumField("filter", 0, {0: "address"}), + ByteEnumField("patype", 0, {0: "public", 1: "random"}), + LEMACField("paddr", None), + ByteEnumField("atype", 0, {0: "public", 1: "random"}), + LEShortField("min_interval", 40), + LEShortField("max_interval", 56), + LEShortField("latency", 0), + LEShortField("timeout", 42), + LEShortField("min_ce", 0), + LEShortField("max_ce", 0), ] + + +class HCI_Cmd_LE_Create_Connection_Cancel(Packet): + name = "HCI_LE_Create_Connection_Cancel" + + +class HCI_Cmd_LE_Read_Filter_Accept_List_Size(Packet): + name = "HCI_LE_Read_Filter_Accept_List_Size" + + +class HCI_Cmd_LE_Clear_Filter_Accept_List(Packet): + name = "HCI_LE_Clear_Filter_Accept_List" + + +class HCI_Cmd_LE_Add_Device_To_Filter_Accept_List(Packet): + name = "HCI_LE_Add_Device_To_Filter_Accept_List" + fields_desc = [ByteEnumField("address_type", 0, {0: "public", + 1: "random", + 0xff: "anonymous"}), + LEMACField("address", None)] + + +class HCI_Cmd_LE_Remove_Device_From_Filter_Accept_List(HCI_Cmd_LE_Add_Device_To_Filter_Accept_List): # noqa: E501 + name = "HCI_LE_Remove_Device_From_Filter_Accept_List" + + +class HCI_Cmd_LE_Connection_Update(Packet): + name = "HCI_LE_Connection_Update" + fields_desc = [XLEShortField("handle", 0), + XLEShortField("min_interval", 0), + XLEShortField("max_interval", 0), + XLEShortField("latency", 0), + XLEShortField("timeout", 0), + LEShortField("min_ce", 0), + LEShortField("max_ce", 0xffff), ] + + +class HCI_Cmd_LE_Read_Remote_Features(Packet): + name = "HCI_LE_Read_Remote_Features" + fields_desc = [LEShortField("handle", 64)] + + +class HCI_Cmd_LE_Enable_Encryption(Packet): + name = "HCI_LE_Enable_Encryption" fields_desc = [LEShortField("handle", 0), StrFixedLenField("rand", None, 8), XLEShortField("ediv", 0), StrFixedLenField("ltk", b'\x00' * 16, 16), ] -class HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply(Packet): - name = "LE Long Term Key Request Negative Reply" - fields_desc = [LEShortField("handle", 0), ] - - class HCI_Cmd_LE_Long_Term_Key_Request_Reply(Packet): - name = "LE Long Term Key Request Reply" + name = "HCI_LE_Long_Term_Key_Request_Reply" fields_desc = [LEShortField("handle", 0), StrFixedLenField("ltk", b'\x00' * 16, 16), ] +class HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply(Packet): + name = "HCI_LE_Long_Term_Key_Request _Negative_Reply" + fields_desc = [LEShortField("handle", 0), ] + + class HCI_Event_Hdr(Packet): name = "HCI Event header" fields_desc = [XByteField("code", 0), @@ -1290,40 +1379,69 @@ class HCI_LE_Meta_Long_Term_Key_Request(Packet): conf.l2types.register(DLT_BLUETOOTH_HCI_H4_WITH_PHDR, HCI_PHDR_Hdr) conf.l2types.register(DLT_BLUETOOTH_LINUX_MONITOR, BT_Mon_Pcap_Hdr) -bind_layers(HCI_Command_Hdr, HCI_Cmd_Create_Connection, opcode=0x0405) -bind_layers(HCI_Command_Hdr, HCI_Cmd_Disconnect, opcode=0x0406) -bind_layers(HCI_Command_Hdr, HCI_Cmd_Link_Key_Request_Reply, opcode=0x040b) -bind_layers(HCI_Command_Hdr, HCI_Cmd_Authentication_Requested, opcode=0x0411) -bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Connection_Encryption, opcode=0x0413) -bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_Name_Request, opcode=0x0419) -bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Event_Mask, opcode=0x0c01) -bind_layers(HCI_Command_Hdr, HCI_Cmd_Reset, opcode=0x0c03) -bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Event_Filter, opcode=0x0c05) -bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Local_Name, opcode=0x0c13) -bind_layers(HCI_Command_Hdr, HCI_Cmd_Connect_Accept_Timeout, opcode=0x0c16) -bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Extended_Inquiry_Response, opcode=0x0c52) # noqa: E501 -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Host_Supported, opcode=0x0c6d) -bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_BD_Addr, opcode=0x1009) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Buffer_Size, opcode=0x2002) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Random_Address, opcode=0x2005) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertising_Parameters, opcode=0x2006) # noqa: E501 -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertising_Data, opcode=0x2008) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Response_Data, opcode=0x2009) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertise_Enable, opcode=0x200a) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Parameters, opcode=0x200b) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Enable, opcode=0x200c) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Create_Connection, opcode=0x200d) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Create_Connection_Cancel, opcode=0x200e) # noqa: E501 -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_White_List_Size, opcode=0x200f) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Clear_White_List, opcode=0x2010) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Add_Device_To_White_List, opcode=0x2011) # noqa: E501 -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Remove_Device_From_White_List, opcode=0x2012) # noqa: E501 -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Connection_Update, opcode=0x2013) -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Remote_Used_Features, opcode=0x2016) # noqa: E501 -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Start_Encryption_Request, opcode=0x2019) # noqa: E501 -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Long_Term_Key_Request_Reply, opcode=0x201a) # noqa: E501 -bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply, opcode=0x201b) # noqa: E501 +# 7.1 LINK CONTROL COMMANDS, the OGF is defined as 0x01 +bind_layers(HCI_Command_Hdr, HCI_Cmd_Inquiry, ogf=0x01, ocf=0x0001) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Inquiry_Cancel, ogf=0x01, ocf=0x0002) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Periodic_Inquiry_Mode, ogf=0x01, ocf=0x0003) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Exit_Peiodic_Inquiry_Mode, ogf=0x01, ocf=0x0004) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Create_Connection, ogf=0x01, ocf=0x0005) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Disconnect, ogf=0x01, ocf=0x0006) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Link_Key_Request_Reply, ogf=0x01, ocf=0x000b) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Authentication_Requested, ogf=0x01, ocf=0x0011) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Connection_Encryption, ogf=0x01, ocf=0x0013) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_Name_Request, ogf=0x01, ocf=0x0019) + +# 7.2 Link Policy commands, the OGF is defined as 0x02 +bind_layers(HCI_Command_Hdr, HCI_Cmd_Hold_Mode, ogf=0x02, ocf=0x0001) + +# 7.3 CONTROLLER & BASEBAND COMMANDS, the OGF is defined as 0x03 +bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Event_Mask, ogf=0x03, ocf=0x0001) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Reset, ogf=0x03, ocf=0x0003) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Set_Event_Filter, ogf=0x03, ocf=0x0005) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Local_Name, ogf=0x03, ocf=0x0013) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Connect_Accept_Timeout, ogf=0x03, ocf=0x0016) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Extended_Inquiry_Response, ogf=0x03, ocf=0x0052) # noqa: E501 +bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_LE_Host_Support, ogf=0x03, ocf=0x006c) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_LE_Host_Support, ogf=0x03, ocf=0x006d) + +# 7.4 INFORMATIONAL PARAMETERS, the OGF is defined as 0x04 +bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_BD_Addr, ogf=0x04, ocf=0x0009) + +# 7.5 STATUS PARAMETERS, the OGF is defined as 0x05 +bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Link_Quality, ogf=0x05, ocf=0x0003) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_RSSI, ogf=0x05, ocf=0x0005) + +# 7.6 TESTING COMMANDS, the OGF is defined as 0x06 +bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Loopback_Mode, ogf=0x06, ocf=0x0001) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Write_Loopback_Mode, ogf=0x06, ocf=0x0002) + +# 7.8 LE CONTROLLER COMMANDS, the OGF code is defined as 0x08 +bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Buffer_Size_V1, ogf=0x08, ocf=0x0002) +bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Buffer_Size_V2, ogf=0x08, ocf=0x0060) +bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Local_Supported_Features, + ogf=0x08, ocf=0x0003) +bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Random_Address, ogf=0x08, ocf=0x0005) +bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertising_Parameters, ogf=0x08, ocf=0x0006) # noqa: E501 +bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertising_Data, ogf=0x08, ocf=0x0008) +bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Response_Data, ogf=0x08, ocf=0x0009) +bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Advertise_Enable, ogf=0x08, ocf=0x000a) +bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Parameters, ogf=0x08, ocf=0x000b) +bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Set_Scan_Enable, ogf=0x08, ocf=0x000c) +bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Create_Connection, ogf=0x08, ocf=0x000d) +bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Create_Connection_Cancel, ogf=0x08, ocf=0x000e) # noqa: E501 +bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Filter_Accept_List_Size, + ogf=0x08, ocf=0x000f) +bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Clear_Filter_Accept_List, ogf=0x08, ocf=0x0010) +bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Add_Device_To_Filter_Accept_List, ogf=0x08, ocf=0x0011) # noqa: E501 +bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Remove_Device_From_Filter_Accept_List, ogf=0x08, ocf=0x0012) # noqa: E501 +bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Connection_Update, ogf=0x08, ocf=0x0013) +bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Read_Remote_Features, ogf=0x08, ocf=0x0016) # noqa: E501 +bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Enable_Encryption, ogf=0x08, ocf=0x0019) # noqa: E501 +bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Long_Term_Key_Request_Reply, ogf=0x08, ocf=0x001a) # noqa: E501 +bind_layers(HCI_Command_Hdr, HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply, ogf=0x08, ocf=0x001b) # noqa: E501 + +# 7.7 EVENTS bind_layers(HCI_Event_Hdr, HCI_Event_Connect_Complete, code=0x03) bind_layers(HCI_Event_Hdr, HCI_Event_Disconnection_Complete, code=0x05) bind_layers(HCI_Event_Hdr, HCI_Event_Remote_Name_Request_Complete, code=0x07) diff --git a/test/scapy/layers/bluetooth.uts b/test/scapy/layers/bluetooth.uts index c103fb0081b..1743e6de91c 100644 --- a/test/scapy/layers/bluetooth.uts +++ b/test/scapy/layers/bluetooth.uts @@ -3,50 +3,146 @@ + Bluetooth tests = HCI layers -# a huge packet with all classes in it! -pkt = HCI_ACL_Hdr()/HCI_Cmd_Create_Connection()/HCI_Cmd_Complete_Read_BD_Addr()/HCI_Cmd_Connect_Accept_Timeout()/HCI_Cmd_Disconnect()/HCI_Cmd_LE_Connection_Update()/HCI_Cmd_LE_Create_Connection()/HCI_Cmd_LE_Create_Connection_Cancel()/HCI_Cmd_LE_Host_Supported()/HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply()/HCI_Cmd_LE_Long_Term_Key_Request_Reply()/HCI_Cmd_LE_Read_Buffer_Size()/HCI_Cmd_LE_Set_Advertise_Enable()/HCI_Cmd_LE_Set_Advertising_Data()/HCI_Cmd_LE_Set_Advertising_Parameters()/HCI_Cmd_LE_Set_Random_Address()/HCI_Cmd_LE_Set_Scan_Enable()/HCI_Cmd_LE_Set_Scan_Parameters()/HCI_Cmd_LE_Start_Encryption_Request()/HCI_Cmd_Authentication_Requested()/HCI_Cmd_Link_Key_Request_Reply()/HCI_Cmd_Read_BD_Addr()/HCI_Cmd_Remote_Name_Request()/HCI_Cmd_Reset()/HCI_Cmd_Set_Connection_Encryption()/HCI_Cmd_Set_Event_Filter()/HCI_Cmd_Set_Event_Mask()/HCI_Command_Hdr()/HCI_Event_Command_Complete()/HCI_Event_Command_Status()/HCI_Event_Connect_Complete()/HCI_Event_Disconnection_Complete()/HCI_Event_Encryption_Change()/HCI_Event_Remote_Name_Request_Complete()/HCI_Event_Hdr()/HCI_Event_LE_Meta()/HCI_Event_Number_Of_Completed_Packets()/HCI_Hdr()/HCI_LE_Meta_Advertising_Reports()/HCI_LE_Meta_Connection_Complete()/HCI_LE_Meta_Connection_Update_Complete()/HCI_LE_Meta_Long_Term_Key_Request() -assert HCI_ACL_Hdr in pkt.layers() -assert HCI_Cmd_Create_Connection in pkt.layers() -assert HCI_Cmd_Complete_Read_BD_Addr in pkt.layers() -assert HCI_Cmd_Connect_Accept_Timeout in pkt.layers() -assert HCI_Cmd_Disconnect in pkt.layers() -assert HCI_Cmd_LE_Connection_Update in pkt.layers() -assert HCI_Cmd_LE_Create_Connection in pkt.layers() -assert HCI_Cmd_LE_Create_Connection_Cancel in pkt.layers() -assert HCI_Cmd_LE_Host_Supported in pkt.layers() -assert HCI_Cmd_LE_Long_Term_Key_Request_Negative_Reply in pkt.layers() -assert HCI_Cmd_LE_Long_Term_Key_Request_Reply in pkt.layers() -assert HCI_Cmd_LE_Read_Buffer_Size in pkt.layers() -assert HCI_Cmd_LE_Set_Advertise_Enable in pkt.layers() -assert HCI_Cmd_LE_Set_Advertising_Data in pkt.layers() -assert HCI_Cmd_LE_Set_Advertising_Parameters in pkt.layers() -assert HCI_Cmd_LE_Set_Random_Address in pkt.layers() -assert HCI_Cmd_LE_Set_Scan_Enable in pkt.layers() -assert HCI_Cmd_LE_Set_Scan_Parameters in pkt.layers() -assert HCI_Cmd_LE_Start_Encryption_Request in pkt.layers() -assert HCI_Cmd_Authentication_Requested in pkt.layers() -assert HCI_Cmd_Link_Key_Request_Reply in pkt.layers() -assert HCI_Cmd_Read_BD_Addr in pkt.layers() -assert HCI_Cmd_Remote_Name_Request in pkt.layers() -assert HCI_Cmd_Reset in pkt.layers() -assert HCI_Cmd_Set_Connection_Encryption in pkt.layers() -assert HCI_Cmd_Set_Event_Filter in pkt.layers() -assert HCI_Cmd_Set_Event_Mask in pkt.layers() -assert HCI_Command_Hdr in pkt.layers() -assert HCI_Event_Command_Complete in pkt.layers() -assert HCI_Event_Command_Status in pkt.layers() -assert HCI_Event_Connect_Complete in pkt.layers() -assert HCI_Event_Disconnection_Complete in pkt.layers() -assert HCI_Event_Encryption_Change in pkt.layers() -assert HCI_Event_Remote_Name_Request_Complete in pkt.layers() -assert HCI_Event_Hdr in pkt.layers() -assert HCI_Event_LE_Meta in pkt.layers() -assert HCI_Event_Number_Of_Completed_Packets in pkt.layers() -assert HCI_Hdr in pkt.layers() -assert HCI_LE_Meta_Advertising_Reports in pkt.layers() -assert HCI_LE_Meta_Connection_Complete in pkt.layers() -assert HCI_LE_Meta_Connection_Update_Complete in pkt.layers() -assert HCI_LE_Meta_Long_Term_Key_Request in pkt.layers() + +# HCI_Command_Hdr +# default construction +hci_cmd_hdr = HCI_Command_Hdr() +assert hci_cmd_hdr.ogf == 0 +assert hci_cmd_hdr.ocf == 0 +assert hci_cmd_hdr.len == None +assert raw(hci_cmd_hdr) == b'\x00\x00\x00' + +# parsing +hci_cmd_hdr = HCI_Command_Hdr(raw(hci_cmd_hdr)) +assert hci_cmd_hdr.ogf == 0 +assert hci_cmd_hdr.ocf == 0 +assert hci_cmd_hdr.len == 0 + +# HCI_Cmd_Inquiry default construction +hci_cmd_inquiry = HCI_Command_Hdr() / HCI_Cmd_Inquiry() +assert hci_cmd_inquiry.ogf == 0x01 +assert hci_cmd_inquiry.ocf == 0x01 +assert hci_cmd_inquiry.len == None +assert hci_cmd_inquiry.lap == 0x9e8b33 +assert hci_cmd_inquiry.inquiry_length == 0 +assert hci_cmd_inquiry.num_responses == 0 + +# parsing +hci_cmd_inquiry = HCI_Command_Hdr(raw(hci_cmd_inquiry)) +assert hci_cmd_inquiry.ogf == 0x01 +assert hci_cmd_inquiry.ocf == 0x01 +assert hci_cmd_inquiry.len == 5 +assert hci_cmd_inquiry.lap == 0x9e8b33 +assert hci_cmd_inquiry.inquiry_length == 0 +assert hci_cmd_inquiry.num_responses == 0 + +# HCI_Cmd_Inquiry constructing an invalid packet +hci_cmd_inquiry = HCI_Command_Hdr(len = 10) / HCI_Cmd_Inquiry() +assert hci_cmd_inquiry.ogf == 0x01 +assert hci_cmd_inquiry.ocf == 0x01 +assert hci_cmd_inquiry.len == 10 +assert hci_cmd_inquiry.lap == 0x9e8b33 +assert hci_cmd_inquiry.inquiry_length == 0 +assert hci_cmd_inquiry.num_responses == 0 + +assert raw(hci_cmd_inquiry)[2] == 10 + +# parse the invalid packet +hci_cmd_inquiry = HCI_Command_Hdr(raw(hci_cmd_inquiry)) +assert hci_cmd_inquiry.ogf == 0x01 +assert hci_cmd_inquiry.ocf == 0x01 +assert hci_cmd_inquiry.len == 10 +assert hci_cmd_inquiry.lap == 0x9e8b33 +assert hci_cmd_inquiry.inquiry_length == 0 +assert hci_cmd_inquiry.num_responses == 0 + +# HCI_Cmd_Inquiry_Cancel default construction +hci_cmd_inquiry_cancel = HCI_Command_Hdr() / HCI_Cmd_Inquiry_Cancel() +assert hci_cmd_inquiry_cancel.ogf == 0x01 +assert hci_cmd_inquiry_cancel.ocf == 0x02 +assert hci_cmd_inquiry_cancel.len == None + +# hci_cmd_inquiry_cancel parsing +hci_cmd_inquiry_cancel = HCI_Command_Hdr(raw(hci_cmd_inquiry_cancel)) +assert hci_cmd_inquiry_cancel.ogf == 0x01 +assert hci_cmd_inquiry_cancel.ocf == 0x02 +assert hci_cmd_inquiry_cancel.len == 0 + + +# Hci_Cmd_Hold_Mode +hci_cmd_hold_mode = HCI_Command_Hdr() / HCI_Cmd_Hold_Mode() +assert hci_cmd_hold_mode.ogf == 0x02 +assert hci_cmd_hold_mode.ocf == 0x01 +assert hci_cmd_hold_mode.len == None + +# parsing +hci_cmd_hold_mode = HCI_Command_Hdr(raw(hci_cmd_hold_mode)) +assert hci_cmd_hold_mode.ogf == 0x02 +assert hci_cmd_hold_mode.ocf == 0x01 +assert hci_cmd_hold_mode.len == 6 + +# HCI_Cmd_Set_Event_Mask +hci_cmd_set_event_mask = HCI_Command_Hdr() / HCI_Cmd_Set_Event_Mask() +assert hci_cmd_set_event_mask.ogf == 0x03 +assert hci_cmd_set_event_mask.ocf == 0x01 +assert hci_cmd_set_event_mask.len == None + +# parsing +hci_cmd_set_event_mask = HCI_Command_Hdr(raw(hci_cmd_set_event_mask)) +assert hci_cmd_set_event_mask.ogf == 0x03 +assert hci_cmd_set_event_mask.ocf == 0x01 +assert hci_cmd_set_event_mask.len == 8 + +# HCI_Cmd_Read_BD_Addr +hci_cmd_read_bd_addr = HCI_Command_Hdr() / HCI_Cmd_Read_BD_Addr() +assert hci_cmd_read_bd_addr.ogf == 0x04 +assert hci_cmd_read_bd_addr.ocf == 0x09 +assert hci_cmd_read_bd_addr.len == None + +# parsing +hci_cmd_read_bd_addr = HCI_Command_Hdr(raw(hci_cmd_read_bd_addr)) +assert hci_cmd_read_bd_addr.ogf == 0x04 +assert hci_cmd_read_bd_addr.ocf == 0x09 +assert hci_cmd_read_bd_addr.len == 0 + + +# HCI_Cmd_Read_Link_Quality +hci_cmd_read_link_quality = HCI_Command_Hdr() / HCI_Cmd_Read_Link_Quality() +assert hci_cmd_read_link_quality.ogf == 0x05 +assert hci_cmd_read_link_quality.ocf == 0x03 +assert hci_cmd_read_link_quality.len == None + +# parsing +hci_cmd_read_link_quality = HCI_Command_Hdr(raw(hci_cmd_read_link_quality)) +assert hci_cmd_read_link_quality.ogf == 0x05 +assert hci_cmd_read_link_quality.ocf == 0x03 +assert hci_cmd_read_link_quality.len == 2 + + +# HCI_Cmd_Read_Loopback_Mode +hci_cmd_read_loopback_mode = HCI_Command_Hdr() / HCI_Cmd_Read_Loopback_Mode() +assert hci_cmd_read_loopback_mode.ogf == 0x06 +assert hci_cmd_read_loopback_mode.ocf == 0x01 +assert hci_cmd_read_loopback_mode.len == None + +# parsing +hci_cmd_read_loopback_mode = HCI_Command_Hdr(raw(hci_cmd_read_loopback_mode)) +assert hci_cmd_read_loopback_mode.ogf == 0x06 +assert hci_cmd_read_loopback_mode.ocf == 0x01 +assert hci_cmd_read_loopback_mode.len == 0 + + +# HCI_Cmd_LE_Read_Buffer_Size_V1 +hci_cmd_le_read_buffer_size_v1 = HCI_Command_Hdr() / HCI_Cmd_LE_Read_Buffer_Size_V1() +assert hci_cmd_le_read_buffer_size_v1.ogf == 0x08 +assert hci_cmd_le_read_buffer_size_v1.ocf == 0x02 +assert hci_cmd_le_read_buffer_size_v1.len == None + +# parsing +hci_cmd_le_read_buffer_size_v1 = HCI_Command_Hdr(raw(hci_cmd_le_read_buffer_size_v1)) +assert hci_cmd_le_read_buffer_size_v1.ogf == 0x08 +assert hci_cmd_le_read_buffer_size_v1.ocf == 0x02 +assert hci_cmd_le_read_buffer_size_v1.len == 0 + Bluetooth Transport Layers = Test HCI_PHDR_Hdr