--- /dev/null
+/** @file\r
+ Tests for Dhcp6Io.c.\r
+\r
+ Copyright (c) Microsoft Corporation\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+**/\r
+#include <gtest/gtest.h>\r
+\r
+extern "C" {\r
+ #include <Uefi.h>\r
+ #include <Library/BaseLib.h>\r
+ #include <Library/DebugLib.h>\r
+ #include <Library/BaseMemoryLib.h>\r
+ #include "../Dhcp6Impl.h"\r
+ #include "../Dhcp6Utility.h"\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Defines\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+#define DHCP6_PACKET_MAX_LEN 1500\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+////////////////////////////////////////////////////////////////////////\r
+// Symbol Definitions\r
+// These functions are not directly under test - but required to compile\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+// This definition is used by this test but is also required to compile\r
+// by Dhcp6Io.c\r
+EFI_IPv6_ADDRESS mAllDhcpRelayAndServersAddress = {\r
+ { 0xFF, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2 }\r
+};\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UdpIoSendDatagram (\r
+ IN UDP_IO *UdpIo,\r
+ IN NET_BUF *Packet,\r
+ IN UDP_END_POINT *EndPoint OPTIONAL,\r
+ IN EFI_IP_ADDRESS *Gateway OPTIONAL,\r
+ IN UDP_IO_CALLBACK CallBack,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UdpIoRecvDatagram (\r
+ IN UDP_IO *UdpIo,\r
+ IN UDP_IO_CALLBACK CallBack,\r
+ IN VOID *Context,\r
+ IN UINT32 HeadLen\r
+ )\r
+{\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Dhcp6AppendOptionTest Tests\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+class Dhcp6AppendOptionTest : public ::testing::Test {\r
+public:\r
+ UINT8 *Buffer = NULL;\r
+ EFI_DHCP6_PACKET *Packet;\r
+\r
+protected:\r
+ // Add any setup code if needed\r
+ virtual void\r
+ SetUp (\r
+ )\r
+ {\r
+ // Initialize any resources or variables\r
+ Buffer = (UINT8 *)AllocateZeroPool (DHCP6_PACKET_MAX_LEN);\r
+ ASSERT_NE (Buffer, (UINT8 *)NULL);\r
+\r
+ Packet = (EFI_DHCP6_PACKET *)Buffer;\r
+ Packet->Size = DHCP6_PACKET_MAX_LEN;\r
+ }\r
+\r
+ // Add any cleanup code if needed\r
+ virtual void\r
+ TearDown (\r
+ )\r
+ {\r
+ // Clean up any resources or variables\r
+ if (Buffer != NULL) {\r
+ FreePool (Buffer);\r
+ }\r
+ }\r
+};\r
+\r
+// Test Description:\r
+// Attempt to append an option to a packet that is too small by a duid that is too large\r
+TEST_F (Dhcp6AppendOptionTest, InvalidDataExpectBufferTooSmall) {\r
+ UINT8 *Cursor;\r
+ EFI_DHCP6_DUID *UntrustedDuid;\r
+ EFI_STATUS Status;\r
+\r
+ UntrustedDuid = (EFI_DHCP6_DUID *)AllocateZeroPool (sizeof (EFI_DHCP6_DUID));\r
+ ASSERT_NE (UntrustedDuid, (EFI_DHCP6_DUID *)NULL);\r
+\r
+ UntrustedDuid->Length = NTOHS (0xFFFF);\r
+\r
+ Cursor = Dhcp6AppendOptionTest::Packet->Dhcp6.Option;\r
+\r
+ Status = Dhcp6AppendOption (\r
+ Dhcp6AppendOptionTest::Packet,\r
+ &Cursor,\r
+ HTONS (Dhcp6OptServerId),\r
+ UntrustedDuid->Length,\r
+ UntrustedDuid->Duid\r
+ );\r
+\r
+ ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL);\r
+}\r
+\r
+// Test Description:\r
+// Attempt to append an option to a packet that is large enough\r
+TEST_F (Dhcp6AppendOptionTest, ValidDataExpectSuccess) {\r
+ UINT8 *Cursor;\r
+ EFI_DHCP6_DUID *UntrustedDuid;\r
+ EFI_STATUS Status;\r
+ UINTN OriginalLength;\r
+\r
+ UINT8 Duid[6] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };\r
+\r
+ Packet->Length = sizeof (EFI_DHCP6_HEADER);\r
+ OriginalLength = Packet->Length;\r
+\r
+ UntrustedDuid = (EFI_DHCP6_DUID *)AllocateZeroPool (sizeof (EFI_DHCP6_DUID));\r
+ ASSERT_NE (UntrustedDuid, (EFI_DHCP6_DUID *)NULL);\r
+\r
+ UntrustedDuid->Length = NTOHS (sizeof (Duid));\r
+ CopyMem (UntrustedDuid->Duid, Duid, sizeof (Duid));\r
+\r
+ Cursor = Dhcp6AppendOptionTest::Packet->Dhcp6.Option;\r
+\r
+ Status = Dhcp6AppendOption (\r
+ Dhcp6AppendOptionTest::Packet,\r
+ &Cursor,\r
+ HTONS (Dhcp6OptServerId),\r
+ UntrustedDuid->Length,\r
+ UntrustedDuid->Duid\r
+ );\r
+\r
+ ASSERT_EQ (Status, EFI_SUCCESS);\r
+\r
+ // verify that the pointer to cursor moved by the expected amount\r
+ ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendOptionTest::Packet->Dhcp6.Option + sizeof (Duid) + 4);\r
+\r
+ // verify that the length of the packet is now the expected amount\r
+ ASSERT_EQ (Dhcp6AppendOptionTest::Packet->Length, OriginalLength + sizeof (Duid) + 4);\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Dhcp6AppendETOption Tests\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+class Dhcp6AppendETOptionTest : public ::testing::Test {\r
+public:\r
+ UINT8 *Buffer = NULL;\r
+ EFI_DHCP6_PACKET *Packet;\r
+\r
+protected:\r
+ // Add any setup code if needed\r
+ virtual void\r
+ SetUp (\r
+ )\r
+ {\r
+ // Initialize any resources or variables\r
+ Buffer = (UINT8 *)AllocateZeroPool (DHCP6_PACKET_MAX_LEN);\r
+ ASSERT_NE (Buffer, (UINT8 *)NULL);\r
+\r
+ Packet = (EFI_DHCP6_PACKET *)Buffer;\r
+ Packet->Size = DHCP6_PACKET_MAX_LEN;\r
+ Packet->Length = sizeof (EFI_DHCP6_HEADER);\r
+ }\r
+\r
+ // Add any cleanup code if needed\r
+ virtual void\r
+ TearDown (\r
+ )\r
+ {\r
+ // Clean up any resources or variables\r
+ if (Buffer != NULL) {\r
+ FreePool (Buffer);\r
+ }\r
+ }\r
+};\r
+\r
+// Test Description:\r
+// Attempt to append an option to a packet that is too small by a duid that is too large\r
+TEST_F (Dhcp6AppendETOptionTest, InvalidDataExpectBufferTooSmall) {\r
+ UINT8 *Cursor;\r
+ EFI_STATUS Status;\r
+ DHCP6_INSTANCE Instance;\r
+ UINT16 ElapsedTimeVal;\r
+ UINT16 *ElapsedTime;\r
+\r
+ Cursor = Dhcp6AppendETOptionTest::Packet->Dhcp6.Option;\r
+ ElapsedTime = &ElapsedTimeVal;\r
+\r
+ Packet->Length = Packet->Size - 2;\r
+\r
+ Status = Dhcp6AppendETOption (\r
+ Dhcp6AppendETOptionTest::Packet,\r
+ &Cursor,\r
+ &Instance, // Instance is not used in this function\r
+ &ElapsedTime\r
+ );\r
+\r
+ // verify that we error out because the packet is too small for the option header\r
+ ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL);\r
+\r
+ // reset the length\r
+ Packet->Length = sizeof (EFI_DHCP6_HEADER);\r
+}\r
+\r
+// Test Description:\r
+// Attempt to append an option to a packet that is large enough\r
+TEST_F (Dhcp6AppendETOptionTest, ValidDataExpectSuccess) {\r
+ UINT8 *Cursor;\r
+ EFI_STATUS Status;\r
+ DHCP6_INSTANCE Instance;\r
+ UINT16 ElapsedTimeVal;\r
+ UINT16 *ElapsedTime;\r
+ UINTN ExpectedSize;\r
+ UINTN OriginalLength;\r
+\r
+ Cursor = Dhcp6AppendETOptionTest::Packet->Dhcp6.Option;\r
+ ElapsedTime = &ElapsedTimeVal;\r
+ ExpectedSize = 6;\r
+ OriginalLength = Packet->Length;\r
+\r
+ Status = Dhcp6AppendETOption (\r
+ Dhcp6AppendETOptionTest::Packet,\r
+ &Cursor,\r
+ &Instance, // Instance is not used in this function\r
+ &ElapsedTime\r
+ );\r
+\r
+ // verify that the status is EFI_SUCCESS\r
+ ASSERT_EQ (Status, EFI_SUCCESS);\r
+\r
+ // verify that the pointer to cursor moved by the expected amount\r
+ ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendETOptionTest::Packet->Dhcp6.Option + ExpectedSize);\r
+\r
+ // verify that the length of the packet is now the expected amount\r
+ ASSERT_EQ (Dhcp6AppendETOptionTest::Packet->Length, OriginalLength + ExpectedSize);\r
+}\r
+\r
+////////////////////////////////////////////////////////////////////////\r
+// Dhcp6AppendIaOption Tests\r
+////////////////////////////////////////////////////////////////////////\r
+\r
+class Dhcp6AppendIaOptionTest : public ::testing::Test {\r
+public:\r
+ UINT8 *Buffer = NULL;\r
+ EFI_DHCP6_PACKET *Packet;\r
+ EFI_DHCP6_IA *Ia;\r
+\r
+protected:\r
+ // Add any setup code if needed\r
+ virtual void\r
+ SetUp (\r
+ )\r
+ {\r
+ // Initialize any resources or variables\r
+ Buffer = (UINT8 *)AllocateZeroPool (DHCP6_PACKET_MAX_LEN);\r
+ ASSERT_NE (Buffer, (UINT8 *)NULL);\r
+\r
+ Packet = (EFI_DHCP6_PACKET *)Buffer;\r
+ Packet->Size = DHCP6_PACKET_MAX_LEN;\r
+\r
+ Ia = (EFI_DHCP6_IA *)AllocateZeroPool (sizeof (EFI_DHCP6_IA) + sizeof (EFI_DHCP6_IA_ADDRESS) * 2);\r
+ ASSERT_NE (Ia, (EFI_DHCP6_IA *)NULL);\r
+\r
+ CopyMem (Ia->IaAddress, mAllDhcpRelayAndServersAddress.Addr, sizeof (EFI_IPv6_ADDRESS));\r
+ CopyMem (Ia->IaAddress + 1, mAllDhcpRelayAndServersAddress.Addr, sizeof (EFI_IPv6_ADDRESS));\r
+\r
+ Ia->IaAddressCount = 2;\r
+ }\r
+\r
+ // Add any cleanup code if needed\r
+ virtual void\r
+ TearDown (\r
+ )\r
+ {\r
+ // Clean up any resources or variables\r
+ if (Buffer != NULL) {\r
+ FreePool (Buffer);\r
+ }\r
+\r
+ if (Ia != NULL) {\r
+ FreePool (Ia);\r
+ }\r
+ }\r
+};\r
+\r
+// Test Description:\r
+// Attempt to append an option to a packet that doesn't have enough space\r
+// for the option header\r
+TEST_F (Dhcp6AppendIaOptionTest, IaNaInvalidDataExpectBufferTooSmall) {\r
+ UINT8 *Cursor;\r
+ EFI_STATUS Status;\r
+\r
+ Packet->Length = Packet->Size - 2;\r
+\r
+ Ia->Descriptor.Type = Dhcp6OptIana;\r
+ Ia->Descriptor.IaId = 0x12345678;\r
+\r
+ Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option;\r
+\r
+ Status = Dhcp6AppendIaOption (\r
+ Dhcp6AppendIaOptionTest::Packet,\r
+ &Cursor,\r
+ Ia,\r
+ 0x12345678,\r
+ 0x11111111,\r
+ Dhcp6OptIana\r
+ );\r
+\r
+ // verify that we error out because the packet is too small for the option header\r
+ ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL);\r
+\r
+ // reset the length\r
+ Packet->Length = sizeof (EFI_DHCP6_HEADER);\r
+}\r
+\r
+// Test Description:\r
+// Attempt to append an option to a packet that doesn't have enough space\r
+// for the option header\r
+TEST_F (Dhcp6AppendIaOptionTest, IaTaInvalidDataExpectBufferTooSmall) {\r
+ UINT8 *Cursor;\r
+ EFI_STATUS Status;\r
+\r
+ // Use up nearly all the space in the packet\r
+ Packet->Length = Packet->Size - 2;\r
+\r
+ Ia->Descriptor.Type = Dhcp6OptIata;\r
+ Ia->Descriptor.IaId = 0x12345678;\r
+\r
+ Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option;\r
+\r
+ Status = Dhcp6AppendIaOption (\r
+ Dhcp6AppendIaOptionTest::Packet,\r
+ &Cursor,\r
+ Ia,\r
+ 0,\r
+ 0,\r
+ Dhcp6OptIata\r
+ );\r
+\r
+ // verify that we error out because the packet is too small for the option header\r
+ ASSERT_EQ (Status, EFI_BUFFER_TOO_SMALL);\r
+\r
+ // reset the length\r
+ Packet->Length = sizeof (EFI_DHCP6_HEADER);\r
+}\r
+\r
+TEST_F (Dhcp6AppendIaOptionTest, IaNaValidDataExpectSuccess) {\r
+ UINT8 *Cursor;\r
+ EFI_STATUS Status;\r
+ UINTN ExpectedSize;\r
+ UINTN OriginalLength;\r
+\r
+ //\r
+ // 2 bytes for the option header type\r
+ //\r
+ ExpectedSize = 2;\r
+ //\r
+ // 2 bytes for the option header length\r
+ //\r
+ ExpectedSize += 2;\r
+ //\r
+ // 4 bytes for the IAID\r
+ //\r
+ ExpectedSize += 4;\r
+ //\r
+ // + 4 bytes for the T1\r
+ //\r
+ ExpectedSize += 4;\r
+ //\r
+ // + 4 bytes for the T2\r
+ //\r
+ ExpectedSize += 4;\r
+ //\r
+ // + (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2;\r
+ // + 2 bytes for the option header type\r
+ // + 2 bytes for the option header length\r
+ // + sizeof (EFI_DHCP6_IA_ADDRESS) for the IA Address\r
+ //\r
+ ExpectedSize += (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2;\r
+\r
+ Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option;\r
+\r
+ Packet->Length = sizeof (EFI_DHCP6_HEADER);\r
+ OriginalLength = Packet->Length;\r
+\r
+ Ia->Descriptor.Type = Dhcp6OptIana;\r
+ Ia->Descriptor.IaId = 0x12345678;\r
+\r
+ Status = Dhcp6AppendIaOption (\r
+ Dhcp6AppendIaOptionTest::Packet,\r
+ &Cursor,\r
+ Ia,\r
+ 0x12345678,\r
+ 0x12345678,\r
+ Dhcp6OptIana\r
+ );\r
+\r
+ // verify that the pointer to cursor moved by the expected amount\r
+ ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option + ExpectedSize);\r
+\r
+ // verify that the length of the packet is now the expected amount\r
+ ASSERT_EQ (Dhcp6AppendIaOptionTest::Packet->Length, OriginalLength + ExpectedSize);\r
+\r
+ // verify that the status is EFI_SUCCESS\r
+ ASSERT_EQ (Status, EFI_SUCCESS);\r
+}\r
+\r
+TEST_F (Dhcp6AppendIaOptionTest, IaTaValidDataExpectSuccess) {\r
+ UINT8 *Cursor;\r
+ EFI_STATUS Status;\r
+ UINTN ExpectedSize;\r
+ UINTN OriginalLength;\r
+\r
+ //\r
+ // 2 bytes for the option header type\r
+ //\r
+ ExpectedSize = 2;\r
+ //\r
+ // 2 bytes for the option header length\r
+ //\r
+ ExpectedSize += 2;\r
+ //\r
+ // 4 bytes for the IAID\r
+ //\r
+ ExpectedSize += 4;\r
+ //\r
+ // + (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2;\r
+ // + 2 bytes for the option header type\r
+ // + 2 bytes for the option header length\r
+ // + sizeof (EFI_DHCP6_IA_ADDRESS) for the IA Address\r
+ //\r
+ ExpectedSize += (4 + sizeof (EFI_DHCP6_IA_ADDRESS)) * 2;\r
+\r
+ Cursor = Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option;\r
+\r
+ Packet->Length = sizeof (EFI_DHCP6_HEADER);\r
+ OriginalLength = Packet->Length;\r
+\r
+ Ia->Descriptor.Type = Dhcp6OptIata;\r
+ Ia->Descriptor.IaId = 0x12345678;\r
+\r
+ Status = Dhcp6AppendIaOption (\r
+ Dhcp6AppendIaOptionTest::Packet,\r
+ &Cursor,\r
+ Ia,\r
+ 0,\r
+ 0,\r
+ Dhcp6OptIata\r
+ );\r
+\r
+ // verify that the pointer to cursor moved by the expected amount\r
+ ASSERT_EQ (Cursor, (UINT8 *)Dhcp6AppendIaOptionTest::Packet->Dhcp6.Option + ExpectedSize);\r
+\r
+ // verify that the length of the packet is now the expected amount\r
+ ASSERT_EQ (Dhcp6AppendIaOptionTest::Packet->Length, OriginalLength + ExpectedSize);\r
+\r
+ // verify that the status is EFI_SUCCESS\r
+ ASSERT_EQ (Status, EFI_SUCCESS);\r
+}\r