diff --git a/scapy/layers/bluetooth.py b/scapy/layers/bluetooth.py index e4c2f521ceb..d4ef6417aff 100644 --- a/scapy/layers/bluetooth.py +++ b/scapy/layers/bluetooth.py @@ -26,6 +26,7 @@ from scapy.packet import bind_layers, Packet from scapy.fields import ( BitField, + LEFieldLenField, XBitField, ByteEnumField, ByteField, @@ -841,6 +842,38 @@ class ATT_Execute_Write_Response(Packet): name = "Execute Write Response" +class ATT_Read_Multiple_Variable_Request(Packet): + name = "Read Multiple Variable Request" + fields_desc = [FieldListField("handles", [], XLEShortField("", 0))] + + +class ATT_Length_Value_Tuple(Packet): + fields_desc = [LEFieldLenField("len", None, length_of="value"), + XStrLenField("value", "", length_from=lambda pkt: pkt.len)] + + def extract_padding(self, s): + return b"", s + + +class ATT_Read_Multiple_Variable_Response(Packet): + name = "Read Multiple Variable Response" + fields_desc = [PacketListField("values", [], ATT_Length_Value_Tuple)] + + +class ATT_Handle_Length_Value_Tuple(Packet): + fields_desc = [XLEShortField("handle", 0), + LEFieldLenField("len", None, length_of="value"), + XStrLenField("value", "", length_from=lambda pkt: pkt.len)] + + def extract_padding(self, s): + return b"", s + + +class ATT_Multiple_Handle_Value_Notification(Packet): + name = "Multiple Handle Value Notification" + fields_desc = [PacketListField("handles", [], ATT_Handle_Length_Value_Tuple)] + + class ATT_Read_Blob_Request(Packet): name = "Read Blob Request" fields_desc = [ @@ -864,6 +897,20 @@ class ATT_Handle_Value_Indication(Packet): ] +class ATT_Handle_Value_Confirmation(Packet): + name = "Handle Value Confirmation" + + +class ATT_Signed_Write_Command(Packet): + name = "Signed Write Command" + + fields_desc = [XLEShortField("handle", 0), + StrLenField("value", "", + length_from=lambda pkt: len(pkt.original) - 14), + LEIntField("sign_counter", 0), + StrFixedLenField("signature", b'\x00' * 8, 8), ] + + class SM_Hdr(Packet): name = "SM header" fields_desc = [ByteField("sm_command", None)] @@ -3201,9 +3248,14 @@ class HCI_LE_Meta_Extended_Advertising_Reports(Packet): bind_layers(ATT_Hdr, ATT_Prepare_Write_Response, opcode=0x17) bind_layers(ATT_Hdr, ATT_Execute_Write_Request, opcode=0x18) bind_layers(ATT_Hdr, ATT_Execute_Write_Response, opcode=0x19) +bind_layers(ATT_Hdr, ATT_Read_Multiple_Variable_Request, opcode=0x20) +bind_layers(ATT_Hdr, ATT_Read_Multiple_Variable_Response, opcode=0x21) +bind_layers(ATT_Hdr, ATT_Multiple_Handle_Value_Notification, opcode=0x23) bind_layers(ATT_Hdr, ATT_Write_Command, opcode=0x52) bind_layers(ATT_Hdr, ATT_Handle_Value_Notification, opcode=0x1b) bind_layers(ATT_Hdr, ATT_Handle_Value_Indication, opcode=0x1d) +bind_layers(ATT_Hdr, ATT_Handle_Value_Confirmation, opcode=0x1e) +bind_layers(ATT_Hdr, ATT_Signed_Write_Command, opcode=0xd2) bind_layers(L2CAP_Hdr, SM_Hdr, cid=6) bind_layers(SM_Hdr, SM_Pairing_Request, sm_command=0x01) bind_layers(SM_Hdr, SM_Pairing_Response, sm_command=0x02) diff --git a/test/scapy/layers/bluetooth.uts b/test/scapy/layers/bluetooth.uts index 33e7d4dea82..89dbdfc22c2 100644 --- a/test/scapy/layers/bluetooth.uts +++ b/test/scapy/layers/bluetooth.uts @@ -1046,6 +1046,54 @@ assert pkt.handles[0].value == b'\x00\x18' assert pkt.handles[1].value == b'\x01\x18' assert pkt.handles[2].value == b'\x0a\x18' += ATT Read_Multiple_Variable_Request +pkt = HCI_Hdr(hex_bytes('0200000900050004002010001300')) + +assert ATT_Read_Multiple_Variable_Request in pkt +assert len(pkt.handles) == 2 +assert pkt.handles[0] == 0x10 +assert pkt.handles[1] == 0x13 + += ATT Read_Multiple_Variable_Response +pkt = HCI_Hdr(hex_bytes('02002013000f00040021050032312e354305003538255248')) + +assert ATT_Read_Multiple_Variable_Response in pkt +assert len(pkt.values) == 2 + +assert pkt.values[0].len == 5 +assert pkt.values[1].len == 5 + +assert pkt.values[0].value == b'\x32\x31\x2e\x35\x43' +assert pkt.values[1].value == b'\x35\x38\x25\x52\x48' + += ATT Multiple_Handle_Value_Notification +pkt = HCI_Hdr(hex_bytes('020020170013000400231000050032312e3543130005003538255248')) + +assert ATT_Multiple_Handle_Value_Notification in pkt +assert len(pkt.handles) == 2 + +assert pkt.handles[0].handle == 0x10 +assert pkt.handles[1].handle == 0x13 + +assert pkt.handles[0].len == 5 +assert pkt.handles[1].len == 5 + +assert pkt.handles[0].value == b'\x32\x31\x2e\x35\x43' +assert pkt.handles[1].value == b'\x35\x38\x25\x52\x48' + += ATT Handle_Value_Confirmation +pkt = HCI_Hdr()/HCI_ACL_Hdr()/L2CAP_Hdr()/ATT_Hdr()/ATT_Handle_Value_Confirmation() +assert pkt[ATT_Hdr].opcode == 0x1e + += ATT Signed_Write_Command +pkt = HCI_Hdr(hex_bytes('020000150011000400d21900676f58ff7c816676336f6e318d3f')) + +assert ATT_Signed_Write_Command in pkt +assert pkt[ATT_Signed_Write_Command].handle == 0x19 +assert pkt[ATT_Signed_Write_Command].value == b'\x67\x6f' +assert pkt[ATT_Signed_Write_Command].sign_counter == 2172452696 +assert pkt[ATT_Signed_Write_Command].signature == b'\x66\x76\x33\x6f\x6e\x31\x8d\x3f' + = SM_Security_Request pkt = HCI_Hdr(hex_bytes('0200260600020006000b0d')) assert SM_Security_Request in pkt