From c7102245b7dc2f1d400da26dca52c807553d7bd6 Mon Sep 17 00:00:00 2001 From: Hui Peng Date: Sat, 26 Aug 2023 09:07:18 -0700 Subject: [PATCH 1/5] Document the section of definition of some HCI commands --- scapy/layers/bluetooth.py | 60 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/scapy/layers/bluetooth.py b/scapy/layers/bluetooth.py index cca1d5a9086..15fb36692fa 100644 --- a/scapy/layers/bluetooth.py +++ b/scapy/layers/bluetooth.py @@ -923,6 +923,12 @@ def post_build(self, p, pay): class HCI_Cmd_Inquiry(Packet): + """ + + 7.1.1 Inquiry command + + """ + name = "HCI_Inquiry" fields_desc = [XLE3BytesField("lap", 0x9E8B33), ByteField("inquiry_length", 0), @@ -930,10 +936,22 @@ class HCI_Cmd_Inquiry(Packet): class HCI_Cmd_Inquiry_Cancel(Packet): + """ + + 7.1.2 Inquiry Cancel command + + """ + name = "HCI_Inquiry_Cancel" class HCI_Cmd_Periodic_Inquiry_Mode(Packet): + """ + + 7.1.3 Periodic Inquiry Mode command + + """ + name = "HCI_Periodic_Inquiry_Mode" fields_desc = [LEShortField("max_period_length", 0x0003), LEShortField("min_period_length", 0x0002), @@ -943,10 +961,22 @@ class HCI_Cmd_Periodic_Inquiry_Mode(Packet): class HCI_Cmd_Exit_Peiodic_Inquiry_Mode(Packet): + """ + + 7.1.4 Exit Periodic Inquiry Mode command + + """ + name = "HCI_Exit_Periodic_Inquiry_Mode" class HCI_Cmd_Create_Connection(Packet): + """ + + 7.1.5 Create Connection command + + """ + name = "HCI_Create_Connection" fields_desc = [LEMACField("bd_addr", None), LEShortField("packet_type", 0xcc18), @@ -957,28 +987,58 @@ class HCI_Cmd_Create_Connection(Packet): class HCI_Cmd_Disconnect(Packet): + """ + + 7.1.6 Disconnect command + + """ + name = "HCI_Disconnect" fields_desc = [XLEShortField("handle", 0), ByteField("reason", 0x13), ] class HCI_Cmd_Link_Key_Request_Reply(Packet): + """ + + 7.1.10 Link Key Request Reply command + + """ + name = "HCI_Link_Key_Request_Reply" fields_desc = [LEMACField("bd_addr", None), NBytesField("link_key", None, 16), ] class HCI_Cmd_Authentication_Requested(Packet): + """ + + 7.1.15 Authentication Requested command + + """ + name = "HCI_Authentication_Requested" fields_desc = [LEShortField("handle", 0)] class HCI_Cmd_Set_Connection_Encryption(Packet): + """ + + 7.1.16 Set Connection Encryption command + + """ + name = "HCI_Set_Connection_Encryption" fields_desc = [LEShortField("handle", 0), ByteField("encryption_enable", 0)] class HCI_Cmd_Remote_Name_Request(Packet): + """ + + 7.1.19 Remote Name Request command + + """ + name = "HCI_Remote_Name_Request" fields_desc = [LEMACField("bd_addr", None), ByteField("page_scan_repetition_mode", 0x02), From bb77bedcda76d355275de23727e3bf57e1b577d2 Mon Sep 17 00:00:00 2001 From: Hui Peng Date: Sat, 26 Aug 2023 11:01:12 -0700 Subject: [PATCH 2/5] Add more Bluetooth HCI Commands [1] --- scapy/layers/bluetooth.py | 182 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) diff --git a/scapy/layers/bluetooth.py b/scapy/layers/bluetooth.py index 15fb36692fa..41667d6ba42 100644 --- a/scapy/layers/bluetooth.py +++ b/scapy/layers/bluetooth.py @@ -998,6 +998,40 @@ class HCI_Cmd_Disconnect(Packet): ByteField("reason", 0x13), ] +class HCI_Cmd_Create_Connection_Cancel(Packet): + """ + + 7.1.7 Create Connection Cancel command + + """ + + name = "HCI_Create_Connection_Cancel" + fields_desc = [LEMACField("bd_addr", None), ] + + +class HCI_Cmd_Accept_Connection_Request(Packet): + """ + + 7.1.8 Accept Connection Request command + + """ + + name = "HCI_Accept_Connection_Request" + fields_desc = [LEMACField("bd_addr", None), + ByteField("role", 0x1), ] + + +class HCI_Cmd_Reject_Connection_Response(Packet): + """ + + 7.1.9 Reject Connection Request command + + """ + name = "HCI_Reject_Connection_Response" + fields_desc = [LEMACField("bd_addr", None), + ByteField("reason", 0x1), ] + + class HCI_Cmd_Link_Key_Request_Reply(Packet): """ @@ -1010,6 +1044,53 @@ class HCI_Cmd_Link_Key_Request_Reply(Packet): NBytesField("link_key", None, 16), ] +class HCI_Cmd_Link_Key_Request_Negative_Reply(Packet): + """ + + 7.1.11 Link Key Request Negative Reply command + + """ + + name = "HCI_Link_Key_Request_Negative_Reply" + fields_desc = [LEMACField("bd_addr", None), ] + + +class HCI_Cmd_PIN_Code_Request_Reply(Packet): + """ + + 7.1.12 PIN Code Request Reply command + + """ + + name = "HCI_PIN_Code_Request_Reply" + fields_desc = [LEMACField("bd_addr", None), + ByteField("pin_code_length", 7), + NBytesField("pin_code", b"\x00" * 16, sz=16), ] + + +class HCI_Cmd_PIN_Code_Request_Negative_Reply(Packet): + """ + + 7.1.13 PIN Code Request Negative Reply command + + """ + + name = "HCI_PIN_Code_Request_Negative_Reply" + fields_desc = [LEMACField("bd_addr", None), ] + + +class HCI_Cmd_Change_Connection_Packet_Type(Packet): + """ + + 7.1.14 Change Connection Packet Type command + + """ + + name = "HCI_Cmd_Change_Connection_Packet_Type" + fields_desc = [XLEShortField("connection_handle", None), + LEShortField("packet_type", 0), ] + + class HCI_Cmd_Authentication_Requested(Packet): """ @@ -1032,6 +1113,29 @@ class HCI_Cmd_Set_Connection_Encryption(Packet): fields_desc = [LEShortField("handle", 0), ByteField("encryption_enable", 0)] +class HCI_Cmd_Change_Connection_Link_Key(Packet): + """ + + 7.1.17 Change Connection Link Key command + + """ + + name = "HCI_Change_Connection_Link_Key" + fields_desc = [LEShortField("handle", 0), ] + + +class HCI_Cmd_Link_Key_Selection(Packet): + """ + + 7.1.18 Change Connection Link Key command + + """ + + name = "HCI_Cmd_Link_Key_Selection" + fields_desc = [ByteEnumField("handle", 0, {0: "Use semi-permanent Link Keys", + 1: "Use Temporary Link Key", }), ] + + class HCI_Cmd_Remote_Name_Request(Packet): """ @@ -1046,7 +1150,68 @@ class HCI_Cmd_Remote_Name_Request(Packet): LEShortField("clock_offset", 0x0), ] +class HCI_Cmd_Remote_Name_Request_Cancel(Packet): + """ + + 7.1.20 Remote Name Request Cancel command + + """ + + name = "HCI_Remote_Name_Request_Cancel" + fields_desc = [LEMACField("bd_addr", None), ] + + +class HCI_Cmd_Read_Remote_Supported_Features(Packet): + """ + + 7.1.21 Read Remote Supported Features command + + """ + + name = "HCI_Read_Remote_Supported_Features" + fields_desc = [LEShortField("connection_handle", None), ] + + +class HCI_Cmd_Read_Remote_Extended_Features(Packet): + """ + + 7.1.22 Read Remote Extended Features command + + """ + + name = "HCI_Read_Remote_Supported_Features" + fields_desc = [LEShortField("connection_handle", None), + ByteField("page_number", None), ] + + +class HCI_Cmd_IO_Capability_Request_Reply(Packet): + """ + + 7.1.29 IO Capability Request Reply command + + """ + + name = "HCI_Read_Remote_Supported_Features" + fields_desc = [LEMACField("bd_addr", None), + ByteEnumField("io_capability", None, {0x00: "DisplayOnly", + 0x01: "DisplayYesNo", + 0x02: "KeyboardOnly", + 0x03: "NoInputNoOutput", }), + ByteEnumField("oob_data_present", None, {0x00: "Not Present", + 0x01: "P-192", + 0x02: "P-256", + 0x03: "P-192 + P-256", }), + ByteEnumField("authentication_requirement", None, + {0x00: "MITM Not Required", + 0x01: "MITM Required, No Bonding", + 0x02: "MITM Not Required + Dedicated Pairing", + 0x03: "MITM Required + Dedicated Pairing", + 0x04: "MITM Not Required, General Bonding", + 0x05: "MITM Required + General Bonding"}), ] + # 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), @@ -1447,10 +1612,27 @@ class HCI_LE_Meta_Long_Term_Key_Request(Packet): 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_Create_Connection_Cancel, ogf=0x01, ocf=0x0008) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Accept_Connection_Request, ogf=0x01, ocf=0x0009) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Reject_Connection_Response, ogf=0x01, ocf=0x000a) bind_layers(HCI_Command_Hdr, HCI_Cmd_Link_Key_Request_Reply, ogf=0x01, ocf=0x000b) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Link_Key_Request_Negative_Reply, + ogf=0x01, ocf=0x000c) +bind_layers(HCI_Command_Hdr, HCI_Cmd_PIN_Code_Request_Reply, ogf=0x01, ocf=0x000d) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Change_Connection_Packet_Type, + ogf=0x01, ocf=0x000f) 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_Change_Connection_Link_Key, ogf=0x01, ocf=0x0017) bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_Name_Request, ogf=0x01, ocf=0x0019) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_Name_Request_Cancel, ogf=0x01, ocf=0x001a) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Remote_Supported_Features, + ogf=0x01, ocf=0x001b) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Remote_Supported_Features, + ogf=0x01, ocf=0x001c) + +bind_layers(HCI_Command_Hdr, HCI_Cmd_IO_Capability_Request_Reply, ogf=0x01, ocf=0x002b) + # 7.2 Link Policy commands, the OGF is defined as 0x02 bind_layers(HCI_Command_Hdr, HCI_Cmd_Hold_Mode, ogf=0x02, ocf=0x0001) From 60d27d773c82957054ca2614f468fb297acee7c5 Mon Sep 17 00:00:00 2001 From: Hui Peng Date: Sat, 26 Aug 2023 11:28:49 -0700 Subject: [PATCH 3/5] Add more Bluetooth HCI commands [2] --- scapy/layers/bluetooth.py | 83 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 2 deletions(-) diff --git a/scapy/layers/bluetooth.py b/scapy/layers/bluetooth.py index 41667d6ba42..3c57d07e961 100644 --- a/scapy/layers/bluetooth.py +++ b/scapy/layers/bluetooth.py @@ -34,6 +34,7 @@ IntField, LEShortEnumField, LEShortField, + LEIntField, LenField, MultipleTypeField, NBytesField, @@ -1209,6 +1210,75 @@ class HCI_Cmd_IO_Capability_Request_Reply(Packet): 0x04: "MITM Not Required, General Bonding", 0x05: "MITM Required + General Bonding"}), ] + +class HCI_Cmd_User_Confirmation_Request_Reply(Packet): + """ + + 7.1.30 User Confirmation Request Reply command + + """ + + name = "HCI_User_Confirmation_Request_Reply" + fields_desc = [LEMACField("bd_addr", None), ] + + +class HCI_Cmd_User_Confirmation_Request_Negative_Reply(Packet): + """ + + 7.1.31 User Confirmation Request Negative Reply command + + """ + + name = "HCI_User_Confirmation_Request_Negative_Reply" + fields_desc = [LEMACField("bd_addr", None), ] + + +class HCI_Cmd_User_Passkey_Request_Reply(Packet): + """ + + 7.1.32 User Passkey Request Reply command + + """ + + name = "HCI_User_Passkey_Request_Reply" + fields_desc = [LEMACField("bd_addr", None), + LEIntField("numeric_value", None), ] + + +class HCI_Cmd_User_Passkey_Request_Negative_Reply(Packet): + """ + + 7.1.33 User Passkey Request Negative Reply command + + """ + + name = "HCI_User_Passkey_Request_Negative_Reply" + fields_desc = [LEMACField("bd_addr", None), ] + + +class HCI_Cmd_Remote_OOB_Data_Request_Reply(Packet): + """ + + 7.1.34 Remote OOB Data Request Reply command + + """ + + name = "HCI_Remote_OOB_Data_Request_Reply" + fields_desc = [LEMACField("bd_addr", None), + NBytesField("C", b"\x00" * 16, sz=16), + NBytesField("R", b"\x00" * 16, sz=16), ] + + +class HCI_Cmd_Remote_OOB_Data_Request_Negative_Reply(Packet): + """ + + 7.1.35 Remote OOB Data Request Negative Reply command + + """ + + name = "HCI_Remote_OOB_Data_Request_Negative_Reply" + fields_desc = [LEMACField("bd_addr", None), ] + # 7.2 Link Policy commands, the OGF is defined as 0x02 @@ -1630,9 +1700,18 @@ class HCI_LE_Meta_Long_Term_Key_Request(Packet): ogf=0x01, ocf=0x001b) bind_layers(HCI_Command_Hdr, HCI_Cmd_Read_Remote_Supported_Features, ogf=0x01, ocf=0x001c) - bind_layers(HCI_Command_Hdr, HCI_Cmd_IO_Capability_Request_Reply, ogf=0x01, ocf=0x002b) - +bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Confirmation_Request_Reply, + ogf=0x01, ocf=0x002c) +bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Confirmation_Request_Negative_Reply, + ogf=0x01, ocf=0x002d) +bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Passkey_Request_Reply, ogf=0x01, ocf=0x002e) +bind_layers(HCI_Command_Hdr, HCI_Cmd_User_Passkey_Request_Negative_Reply, + ogf=0x01, ocf=0x002f) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_OOB_Data_Request_Reply, + ogf=0x01, ocf=0x0030) +bind_layers(HCI_Command_Hdr, HCI_Cmd_Remote_OOB_Data_Request_Negative_Reply, + ogf=0x01, ocf=0x0033) # 7.2 Link Policy commands, the OGF is defined as 0x02 bind_layers(HCI_Command_Hdr, HCI_Cmd_Hold_Mode, ogf=0x02, ocf=0x0001) From ca0a515e0fec70703655d14cdec127c780ab5fcc Mon Sep 17 00:00:00 2001 From: Hui Peng Date: Wed, 30 Aug 2023 21:06:13 -0700 Subject: [PATCH 4/5] Fix the definition of HCI_Connection_Complete - fix the name - add missing fields - update test --- scapy/layers/bluetooth.py | 17 +++++++++++++---- test/scapy/layers/bluetooth.uts | 8 ++++---- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/scapy/layers/bluetooth.py b/scapy/layers/bluetooth.py index 3c57d07e961..ce67e9f1d0b 100644 --- a/scapy/layers/bluetooth.py +++ b/scapy/layers/bluetooth.py @@ -1518,11 +1518,20 @@ def answers(self, other): return self.payload.answers(other) -class HCI_Event_Connect_Complete(Packet): - name = "Connect Complete" +class HCI_Event_Connection_Complete(Packet): + """ + 7.7.3 Connection Complete event + """ + + name = "HCI_Connection_Complete" fields_desc = [ByteField("status", 0), LEShortField("handle", 0x0100), - LEMACField("bd_addr", None), ] + LEMACField("bd_addr", None), + ByteEnumField("link_type", 0, {0: "SCO connection", + 1: "ACL connection", }), + ByteEnumField("encryption_enaled", 0, + {0: "link level encryption disabled", + 1: "link level encryption enabled", }), ] class HCI_Event_Disconnection_Complete(Packet): @@ -1763,7 +1772,7 @@ class HCI_LE_Meta_Long_Term_Key_Request(Packet): 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_Connection_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) bind_layers(HCI_Event_Hdr, HCI_Event_Encryption_Change, code=0x08) diff --git a/test/scapy/layers/bluetooth.uts b/test/scapy/layers/bluetooth.uts index 1743e6de91c..539a3d97ffd 100644 --- a/test/scapy/layers/bluetooth.uts +++ b/test/scapy/layers/bluetooth.uts @@ -268,10 +268,10 @@ assert expected_cmd_raw_data == cmd_raw_data evt_raw_data = hex_bytes("04030b00000176d56f9501000100") evt_pkt = HCI_Hdr(evt_raw_data) -assert HCI_Event_Connect_Complete in evt_pkt -assert evt_pkt[HCI_Event_Connect_Complete].status == 0 -assert evt_pkt[HCI_Event_Connect_Complete].handle == 256 -assert evt_pkt[HCI_Event_Connect_Complete].bd_addr == "00:01:95:6f:d5:76" +assert HCI_Event_Connection_Complete in evt_pkt +assert evt_pkt[HCI_Event_Connection_Complete].status == 0 +assert evt_pkt[HCI_Event_Connection_Complete].handle == 256 +assert evt_pkt[HCI_Event_Connection_Complete].bd_addr == "00:01:95:6f:d5:76" = Remote Name Request Complete From be02a89535eed427a22c84fa4aa66fd78d99e423 Mon Sep 17 00:00:00 2001 From: Hui Peng Date: Wed, 30 Aug 2023 21:19:19 -0700 Subject: [PATCH 5/5] Add HCI_Inquiry_Complete event --- scapy/layers/bluetooth.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/scapy/layers/bluetooth.py b/scapy/layers/bluetooth.py index ce67e9f1d0b..3b82842f6bb 100644 --- a/scapy/layers/bluetooth.py +++ b/scapy/layers/bluetooth.py @@ -1518,6 +1518,15 @@ def answers(self, other): return self.payload.answers(other) +class HCI_Event_Inquiry_Complete(Packet): + """ + 7.7.1 Inquiry Complete event + """ + + name = "HCI_Inquiry_Complete" + fields_desc = [ByteField("status", 0), ] + + class HCI_Event_Connection_Complete(Packet): """ 7.7.3 Connection Complete event @@ -1772,6 +1781,8 @@ class HCI_LE_Meta_Long_Term_Key_Request(Packet): 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_Inquiry_Complete, code=0x01) + bind_layers(HCI_Event_Hdr, HCI_Event_Connection_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)