mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-10-31 03:03:46 +01:00 
			
		
		
		
	NetworkPkg: Dhcp6Dxe: SECURITY PATCH CVE-2023-45230 Patch
REF:https://bugzilla.tianocore.org/show_bug.cgi?id=4535 Bug Details: PixieFail Bug #2 CVE-2023-45230 CVSS 8.3 : CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H CWE-119 Improper Restriction of Operations within the Bounds of a Memory Buffer Changes Overview: > -UINT8 * > +EFI_STATUS > Dhcp6AppendOption ( > - IN OUT UINT8 *Buf, > - IN UINT16 OptType, > - IN UINT16 OptLen, > - IN UINT8 *Data > + IN OUT EFI_DHCP6_PACKET *Packet, > + IN OUT UINT8 **PacketCursor, > + IN UINT16 OptType, > + IN UINT16 OptLen, > + IN UINT8 *Data > ); Dhcp6AppendOption() and variants can return errors now. All callsites are adapted accordingly. It gets passed in EFI_DHCP6_PACKET as additional parameter ... > + // > + // Verify the PacketCursor is within the packet > + // > + if ( (*PacketCursor < Packet->Dhcp6.Option) > + || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) > + { > + return EFI_INVALID_PARAMETER; > + } ... so it can look at Packet->Size when checking buffer space. Also to allow Packet->Length updates. Lots of checks added. Cc: Saloni Kasbekar <saloni.kasbekar@intel.com> Cc: Zachary Clark-williams <zachary.clark-williams@intel.com> Signed-off-by: Doug Flick [MSFT] <doug.edk2@gmail.com> Reviewed-by: Saloni Kasbekar <saloni.kasbekar@intel.com>
This commit is contained in:
		
							parent
							
								
									959f71c801
								
							
						
					
					
						commit
						f31453e8d6
					
				| @ -45,6 +45,49 @@ typedef struct _DHCP6_INSTANCE  DHCP6_INSTANCE; | |||||||
| #define DHCP6_SERVICE_SIGNATURE   SIGNATURE_32 ('D', 'H', '6', 'S') | #define DHCP6_SERVICE_SIGNATURE   SIGNATURE_32 ('D', 'H', '6', 'S') | ||||||
| #define DHCP6_INSTANCE_SIGNATURE  SIGNATURE_32 ('D', 'H', '6', 'I') | #define DHCP6_INSTANCE_SIGNATURE  SIGNATURE_32 ('D', 'H', '6', 'I') | ||||||
| 
 | 
 | ||||||
|  | //
 | ||||||
|  | // For more information on DHCP options see RFC 8415, Section 21.1
 | ||||||
|  | //
 | ||||||
|  | // The format of DHCP options is:
 | ||||||
|  | //
 | ||||||
|  | //     0                   1                   2                   3
 | ||||||
|  | //     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 | ||||||
|  | //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | ||||||
|  | //    |          option-code          |           option-len          |
 | ||||||
|  | //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | ||||||
|  | //    |                          option-data                          |
 | ||||||
|  | //    |                      (option-len octets)                      |
 | ||||||
|  | //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | ||||||
|  | //
 | ||||||
|  | #define DHCP6_SIZE_OF_OPT_CODE  (sizeof(UINT16)) | ||||||
|  | #define DHCP6_SIZE_OF_OPT_LEN   (sizeof(UINT16)) | ||||||
|  | 
 | ||||||
|  | //
 | ||||||
|  | // Combined size of Code and Length
 | ||||||
|  | //
 | ||||||
|  | #define DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN  (DHCP6_SIZE_OF_OPT_CODE + \ | ||||||
|  |                                               DHCP6_SIZE_OF_OPT_LEN) | ||||||
|  | 
 | ||||||
|  | STATIC_ASSERT ( | ||||||
|  |   DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN == 4, | ||||||
|  |   "Combined size of Code and Length must be 4 per RFC 8415" | ||||||
|  |   ); | ||||||
|  | 
 | ||||||
|  | //
 | ||||||
|  | // Offset to the length is just past the code
 | ||||||
|  | //
 | ||||||
|  | #define DHCP6_OPT_LEN_OFFSET(a)  (a + DHCP6_SIZE_OF_OPT_CODE) | ||||||
|  | STATIC_ASSERT ( | ||||||
|  |   DHCP6_OPT_LEN_OFFSET (0) == 2, | ||||||
|  |   "Offset of length is + 2 past start of option" | ||||||
|  |   ); | ||||||
|  | 
 | ||||||
|  | #define DHCP6_OPT_DATA_OFFSET(a)  (a + DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN) | ||||||
|  | STATIC_ASSERT ( | ||||||
|  |   DHCP6_OPT_DATA_OFFSET (0) == 4, | ||||||
|  |   "Offset to option data should be +4 from start of option" | ||||||
|  |   ); | ||||||
|  | 
 | ||||||
| #define DHCP6_PACKET_ALL        0 | #define DHCP6_PACKET_ALL        0 | ||||||
| #define DHCP6_PACKET_STATEFUL   1 | #define DHCP6_PACKET_STATEFUL   1 | ||||||
| #define DHCP6_PACKET_STATELESS  2 | #define DHCP6_PACKET_STATELESS  2 | ||||||
|  | |||||||
| @ -3,9 +3,9 @@ | |||||||
| 
 | 
 | ||||||
|   (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR> |   (C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR> | ||||||
|   Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> |   Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR> | ||||||
|  |   Copyright (c) Microsoft Corporation | ||||||
| 
 | 
 | ||||||
|   SPDX-License-Identifier: BSD-2-Clause-Patent |   SPDX-License-Identifier: BSD-2-Clause-Patent | ||||||
| 
 |  | ||||||
| **/ | **/ | ||||||
| 
 | 
 | ||||||
| #include "Dhcp6Impl.h" | #include "Dhcp6Impl.h" | ||||||
| @ -930,7 +930,8 @@ Dhcp6SendSolicitMsg   ( | |||||||
|   //
 |   //
 | ||||||
|   Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); |   Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); | ||||||
|   if (Packet == NULL) { |   if (Packet == NULL) { | ||||||
|     return EFI_OUT_OF_RESOURCES; |     Status = EFI_OUT_OF_RESOURCES; | ||||||
|  |     goto ON_ERROR; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Packet->Size                       = DHCP6_BASE_PACKET_SIZE + UserLen; |   Packet->Size                       = DHCP6_BASE_PACKET_SIZE + UserLen; | ||||||
| @ -944,54 +945,64 @@ Dhcp6SendSolicitMsg   ( | |||||||
|   Cursor = Packet->Dhcp6.Option; |   Cursor = Packet->Dhcp6.Option; | ||||||
| 
 | 
 | ||||||
|   Length = HTONS (ClientId->Length); |   Length = HTONS (ClientId->Length); | ||||||
|   Cursor = Dhcp6AppendOption ( |   Status = Dhcp6AppendOption ( | ||||||
|              Cursor, |              Packet, | ||||||
|  |              &Cursor, | ||||||
|              HTONS (Dhcp6OptClientId), |              HTONS (Dhcp6OptClientId), | ||||||
|              Length, |              Length, | ||||||
|              ClientId->Duid |              ClientId->Duid | ||||||
|              ); |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   Cursor = Dhcp6AppendETOption ( |   Status = Dhcp6AppendETOption ( | ||||||
|              Cursor, |              Packet, | ||||||
|  |              &Cursor, | ||||||
|              Instance, |              Instance, | ||||||
|              &Elapsed |              &Elapsed | ||||||
|              ); |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   Cursor = Dhcp6AppendIaOption ( |   Status = Dhcp6AppendIaOption ( | ||||||
|              Cursor, |              Packet, | ||||||
|  |              &Cursor, | ||||||
|              Instance->IaCb.Ia, |              Instance->IaCb.Ia, | ||||||
|              Instance->IaCb.T1, |              Instance->IaCb.T1, | ||||||
|              Instance->IaCb.T2, |              Instance->IaCb.T2, | ||||||
|              Packet->Dhcp6.Header.MessageType |              Packet->Dhcp6.Header.MessageType | ||||||
|              ); |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Append user-defined when configurate Dhcp6 service.
 |   // Append user-defined when configurate Dhcp6 service.
 | ||||||
|   //
 |   //
 | ||||||
|   for (Index = 0; Index < Instance->Config->OptionCount; Index++) { |   for (Index = 0; Index < Instance->Config->OptionCount; Index++) { | ||||||
|     UserOpt = Instance->Config->OptionList[Index]; |     UserOpt = Instance->Config->OptionList[Index]; | ||||||
|     Cursor  = Dhcp6AppendOption ( |     Status  = Dhcp6AppendOption ( | ||||||
|                 Cursor, |                 Packet, | ||||||
|  |                 &Cursor, | ||||||
|                 UserOpt->OpCode, |                 UserOpt->OpCode, | ||||||
|                 UserOpt->OpLen, |                 UserOpt->OpLen, | ||||||
|                 UserOpt->Data |                 UserOpt->Data | ||||||
|                 ); |                 ); | ||||||
|  |     if (EFI_ERROR (Status)) { | ||||||
|  |       goto ON_ERROR; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   //
 |  | ||||||
|   // Determine the size/length of packet.
 |  | ||||||
|   //
 |  | ||||||
|   Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option); |  | ||||||
|   ASSERT (Packet->Size > Packet->Length + 8); |   ASSERT (Packet->Size > Packet->Length + 8); | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Callback to user with the packet to be sent and check the user's feedback.
 |   // Callback to user with the packet to be sent and check the user's feedback.
 | ||||||
|   //
 |   //
 | ||||||
|   Status = Dhcp6CallbackUser (Instance, Dhcp6SendSolicit, &Packet); |   Status = Dhcp6CallbackUser (Instance, Dhcp6SendSolicit, &Packet); | ||||||
| 
 |  | ||||||
|   if (EFI_ERROR (Status)) { |   if (EFI_ERROR (Status)) { | ||||||
|     FreePool (Packet); |     goto ON_ERROR; | ||||||
|     return Status; |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
| @ -1005,10 +1016,8 @@ Dhcp6SendSolicitMsg   ( | |||||||
|   Instance->StartTime = 0; |   Instance->StartTime = 0; | ||||||
| 
 | 
 | ||||||
|   Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); |   Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); | ||||||
| 
 |  | ||||||
|   if (EFI_ERROR (Status)) { |   if (EFI_ERROR (Status)) { | ||||||
|     FreePool (Packet); |     goto ON_ERROR; | ||||||
|     return Status; |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
| @ -1020,6 +1029,14 @@ Dhcp6SendSolicitMsg   ( | |||||||
|            Elapsed, |            Elapsed, | ||||||
|            Instance->Config->SolicitRetransmission |            Instance->Config->SolicitRetransmission | ||||||
|            ); |            ); | ||||||
|  | 
 | ||||||
|  | ON_ERROR: | ||||||
|  | 
 | ||||||
|  |   if (Packet) { | ||||||
|  |     FreePool (Packet); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return Status; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
| @ -1110,7 +1127,8 @@ Dhcp6SendRequestMsg ( | |||||||
|   //
 |   //
 | ||||||
|   Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); |   Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); | ||||||
|   if (Packet == NULL) { |   if (Packet == NULL) { | ||||||
|     return EFI_OUT_OF_RESOURCES; |     Status = EFI_OUT_OF_RESOURCES; | ||||||
|  |     goto ON_ERROR; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Packet->Size                       = DHCP6_BASE_PACKET_SIZE + UserLen; |   Packet->Size                       = DHCP6_BASE_PACKET_SIZE + UserLen; | ||||||
| @ -1124,51 +1142,67 @@ Dhcp6SendRequestMsg ( | |||||||
|   Cursor = Packet->Dhcp6.Option; |   Cursor = Packet->Dhcp6.Option; | ||||||
| 
 | 
 | ||||||
|   Length = HTONS (ClientId->Length); |   Length = HTONS (ClientId->Length); | ||||||
|   Cursor = Dhcp6AppendOption ( |   Status = Dhcp6AppendOption ( | ||||||
|              Cursor, |              Packet, | ||||||
|  |              &Cursor, | ||||||
|              HTONS (Dhcp6OptClientId), |              HTONS (Dhcp6OptClientId), | ||||||
|              Length, |              Length, | ||||||
|              ClientId->Duid |              ClientId->Duid | ||||||
|              ); |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   Cursor = Dhcp6AppendETOption ( |   Status = Dhcp6AppendETOption ( | ||||||
|              Cursor, |              Packet, | ||||||
|  |              &Cursor, | ||||||
|              Instance, |              Instance, | ||||||
|              &Elapsed |              &Elapsed | ||||||
|              ); |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   Cursor = Dhcp6AppendOption ( |   Status = Dhcp6AppendOption ( | ||||||
|              Cursor, |              Packet, | ||||||
|  |              &Cursor, | ||||||
|              HTONS (Dhcp6OptServerId), |              HTONS (Dhcp6OptServerId), | ||||||
|              ServerId->Length, |              ServerId->Length, | ||||||
|              ServerId->Duid |              ServerId->Duid | ||||||
|              ); |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   Cursor = Dhcp6AppendIaOption ( |   Status = Dhcp6AppendIaOption ( | ||||||
|              Cursor, |              Packet, | ||||||
|  |              &Cursor, | ||||||
|              Instance->IaCb.Ia, |              Instance->IaCb.Ia, | ||||||
|              Instance->IaCb.T1, |              Instance->IaCb.T1, | ||||||
|              Instance->IaCb.T2, |              Instance->IaCb.T2, | ||||||
|              Packet->Dhcp6.Header.MessageType |              Packet->Dhcp6.Header.MessageType | ||||||
|              ); |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Append user-defined when configurate Dhcp6 service.
 |   // Append user-defined when configurate Dhcp6 service.
 | ||||||
|   //
 |   //
 | ||||||
|   for (Index = 0; Index < Instance->Config->OptionCount; Index++) { |   for (Index = 0; Index < Instance->Config->OptionCount; Index++) { | ||||||
|     UserOpt = Instance->Config->OptionList[Index]; |     UserOpt = Instance->Config->OptionList[Index]; | ||||||
|     Cursor  = Dhcp6AppendOption ( |     Status  = Dhcp6AppendOption ( | ||||||
|                 Cursor, |                 Packet, | ||||||
|  |                 &Cursor, | ||||||
|                 UserOpt->OpCode, |                 UserOpt->OpCode, | ||||||
|                 UserOpt->OpLen, |                 UserOpt->OpLen, | ||||||
|                 UserOpt->Data |                 UserOpt->Data | ||||||
|                 ); |                 ); | ||||||
|  |     if (EFI_ERROR (Status)) { | ||||||
|  |       goto ON_ERROR; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   //
 |  | ||||||
|   // Determine the size/length of packet.
 |  | ||||||
|   //
 |  | ||||||
|   Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option); |  | ||||||
|   ASSERT (Packet->Size > Packet->Length + 8); |   ASSERT (Packet->Size > Packet->Length + 8); | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
| @ -1177,8 +1211,7 @@ Dhcp6SendRequestMsg ( | |||||||
|   Status = Dhcp6CallbackUser (Instance, Dhcp6SendRequest, &Packet); |   Status = Dhcp6CallbackUser (Instance, Dhcp6SendRequest, &Packet); | ||||||
| 
 | 
 | ||||||
|   if (EFI_ERROR (Status)) { |   if (EFI_ERROR (Status)) { | ||||||
|     FreePool (Packet); |     goto ON_ERROR; | ||||||
|     return Status; |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
| @ -1194,14 +1227,21 @@ Dhcp6SendRequestMsg ( | |||||||
|   Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); |   Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); | ||||||
| 
 | 
 | ||||||
|   if (EFI_ERROR (Status)) { |   if (EFI_ERROR (Status)) { | ||||||
|     FreePool (Packet); |     goto ON_ERROR; | ||||||
|     return Status; |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Enqueue the sent packet for the retransmission in case reply timeout.
 |   // Enqueue the sent packet for the retransmission in case reply timeout.
 | ||||||
|   //
 |   //
 | ||||||
|   return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); |   return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); | ||||||
|  | 
 | ||||||
|  | ON_ERROR: | ||||||
|  | 
 | ||||||
|  |   if (Packet) { | ||||||
|  |     FreePool (Packet); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return Status; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
| @ -1266,7 +1306,8 @@ Dhcp6SendDeclineMsg ( | |||||||
|   //
 |   //
 | ||||||
|   Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE); |   Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE); | ||||||
|   if (Packet == NULL) { |   if (Packet == NULL) { | ||||||
|     return EFI_OUT_OF_RESOURCES; |     Status = EFI_OUT_OF_RESOURCES; | ||||||
|  |     goto ON_ERROR; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Packet->Size                       = DHCP6_BASE_PACKET_SIZE; |   Packet->Size                       = DHCP6_BASE_PACKET_SIZE; | ||||||
| @ -1280,42 +1321,58 @@ Dhcp6SendDeclineMsg ( | |||||||
|   Cursor = Packet->Dhcp6.Option; |   Cursor = Packet->Dhcp6.Option; | ||||||
| 
 | 
 | ||||||
|   Length = HTONS (ClientId->Length); |   Length = HTONS (ClientId->Length); | ||||||
|   Cursor = Dhcp6AppendOption ( |   Status = Dhcp6AppendOption ( | ||||||
|              Cursor, |              Packet, | ||||||
|  |              &Cursor, | ||||||
|              HTONS (Dhcp6OptClientId), |              HTONS (Dhcp6OptClientId), | ||||||
|              Length, |              Length, | ||||||
|              ClientId->Duid |              ClientId->Duid | ||||||
|              ); |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   Cursor = Dhcp6AppendETOption ( |   Status = Dhcp6AppendETOption ( | ||||||
|              Cursor, |              Packet, | ||||||
|  |              &Cursor, | ||||||
|              Instance, |              Instance, | ||||||
|              &Elapsed |              &Elapsed | ||||||
|              ); |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   Cursor = Dhcp6AppendOption ( |   Status = Dhcp6AppendOption ( | ||||||
|              Cursor, |              Packet, | ||||||
|  |              &Cursor, | ||||||
|              HTONS (Dhcp6OptServerId), |              HTONS (Dhcp6OptServerId), | ||||||
|              ServerId->Length, |              ServerId->Length, | ||||||
|              ServerId->Duid |              ServerId->Duid | ||||||
|              ); |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   Cursor = Dhcp6AppendIaOption (Cursor, DecIa, 0, 0, Packet->Dhcp6.Header.MessageType); |   Status = Dhcp6AppendIaOption ( | ||||||
|  |              Packet, | ||||||
|  |              &Cursor, | ||||||
|  |              DecIa, | ||||||
|  |              0, | ||||||
|  |              0, | ||||||
|  |              Packet->Dhcp6.Header.MessageType | ||||||
|  |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   //
 |  | ||||||
|   // Determine the size/length of packet.
 |  | ||||||
|   //
 |  | ||||||
|   Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option); |  | ||||||
|   ASSERT (Packet->Size > Packet->Length + 8); |   ASSERT (Packet->Size > Packet->Length + 8); | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Callback to user with the packet to be sent and check the user's feedback.
 |   // Callback to user with the packet to be sent and check the user's feedback.
 | ||||||
|   //
 |   //
 | ||||||
|   Status = Dhcp6CallbackUser (Instance, Dhcp6SendDecline, &Packet); |   Status = Dhcp6CallbackUser (Instance, Dhcp6SendDecline, &Packet); | ||||||
| 
 |  | ||||||
|   if (EFI_ERROR (Status)) { |   if (EFI_ERROR (Status)) { | ||||||
|     FreePool (Packet); |     goto ON_ERROR; | ||||||
|     return Status; |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
| @ -1329,16 +1386,22 @@ Dhcp6SendDeclineMsg ( | |||||||
|   Instance->StartTime = 0; |   Instance->StartTime = 0; | ||||||
| 
 | 
 | ||||||
|   Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); |   Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); | ||||||
| 
 |  | ||||||
|   if (EFI_ERROR (Status)) { |   if (EFI_ERROR (Status)) { | ||||||
|     FreePool (Packet); |     goto ON_ERROR; | ||||||
|     return Status; |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Enqueue the sent packet for the retransmission in case reply timeout.
 |   // Enqueue the sent packet for the retransmission in case reply timeout.
 | ||||||
|   //
 |   //
 | ||||||
|   return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); |   return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); | ||||||
|  | 
 | ||||||
|  | ON_ERROR: | ||||||
|  | 
 | ||||||
|  |   if (Packet) { | ||||||
|  |     FreePool (Packet); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return Status; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
| @ -1399,7 +1462,8 @@ Dhcp6SendReleaseMsg ( | |||||||
|   //
 |   //
 | ||||||
|   Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE); |   Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE); | ||||||
|   if (Packet == NULL) { |   if (Packet == NULL) { | ||||||
|     return EFI_OUT_OF_RESOURCES; |     Status = EFI_OUT_OF_RESOURCES; | ||||||
|  |     goto ON_ERROR; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Packet->Size                       = DHCP6_BASE_PACKET_SIZE; |   Packet->Size                       = DHCP6_BASE_PACKET_SIZE; | ||||||
| @ -1413,45 +1477,61 @@ Dhcp6SendReleaseMsg ( | |||||||
|   Cursor = Packet->Dhcp6.Option; |   Cursor = Packet->Dhcp6.Option; | ||||||
| 
 | 
 | ||||||
|   Length = HTONS (ClientId->Length); |   Length = HTONS (ClientId->Length); | ||||||
|   Cursor = Dhcp6AppendOption ( |   Status = Dhcp6AppendOption ( | ||||||
|              Cursor, |              Packet, | ||||||
|  |              &Cursor, | ||||||
|              HTONS (Dhcp6OptClientId), |              HTONS (Dhcp6OptClientId), | ||||||
|              Length, |              Length, | ||||||
|              ClientId->Duid |              ClientId->Duid | ||||||
|              ); |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // ServerId is extracted from packet, it's network order.
 |   // ServerId is extracted from packet, it's network order.
 | ||||||
|   //
 |   //
 | ||||||
|   Cursor = Dhcp6AppendOption ( |   Status = Dhcp6AppendOption ( | ||||||
|              Cursor, |              Packet, | ||||||
|  |              &Cursor, | ||||||
|              HTONS (Dhcp6OptServerId), |              HTONS (Dhcp6OptServerId), | ||||||
|              ServerId->Length, |              ServerId->Length, | ||||||
|              ServerId->Duid |              ServerId->Duid | ||||||
|              ); |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   Cursor = Dhcp6AppendETOption ( |   Status = Dhcp6AppendETOption ( | ||||||
|              Cursor, |              Packet, | ||||||
|  |              &Cursor, | ||||||
|              Instance, |              Instance, | ||||||
|              &Elapsed |              &Elapsed | ||||||
|              ); |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   Cursor = Dhcp6AppendIaOption (Cursor, RelIa, 0, 0, Packet->Dhcp6.Header.MessageType); |   Status = Dhcp6AppendIaOption ( | ||||||
|  |              Packet, | ||||||
|  |              &Cursor, | ||||||
|  |              RelIa, | ||||||
|  |              0, | ||||||
|  |              0, | ||||||
|  |              Packet->Dhcp6.Header.MessageType | ||||||
|  |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   //
 |  | ||||||
|   // Determine the size/length of packet
 |  | ||||||
|   //
 |  | ||||||
|   Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option); |  | ||||||
|   ASSERT (Packet->Size > Packet->Length + 8); |   ASSERT (Packet->Size > Packet->Length + 8); | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Callback to user with the packet to be sent and check the user's feedback.
 |   // Callback to user with the packet to be sent and check the user's feedback.
 | ||||||
|   //
 |   //
 | ||||||
|   Status = Dhcp6CallbackUser (Instance, Dhcp6SendRelease, &Packet); |   Status = Dhcp6CallbackUser (Instance, Dhcp6SendRelease, &Packet); | ||||||
| 
 |  | ||||||
|   if (EFI_ERROR (Status)) { |   if (EFI_ERROR (Status)) { | ||||||
|     FreePool (Packet); |     goto ON_ERROR; | ||||||
|     return Status; |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
| @ -1461,16 +1541,22 @@ Dhcp6SendReleaseMsg ( | |||||||
|   Instance->IaCb.Ia->State = Dhcp6Releasing; |   Instance->IaCb.Ia->State = Dhcp6Releasing; | ||||||
| 
 | 
 | ||||||
|   Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); |   Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); | ||||||
| 
 |  | ||||||
|   if (EFI_ERROR (Status)) { |   if (EFI_ERROR (Status)) { | ||||||
|     FreePool (Packet); |     goto ON_ERROR; | ||||||
|     return Status; |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Enqueue the sent packet for the retransmission in case reply timeout.
 |   // Enqueue the sent packet for the retransmission in case reply timeout.
 | ||||||
|   //
 |   //
 | ||||||
|   return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); |   return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); | ||||||
|  | 
 | ||||||
|  | ON_ERROR: | ||||||
|  | 
 | ||||||
|  |   if (Packet) { | ||||||
|  |     FreePool (Packet); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return Status; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
| @ -1529,7 +1615,8 @@ Dhcp6SendRenewRebindMsg ( | |||||||
|   //
 |   //
 | ||||||
|   Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); |   Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); | ||||||
|   if (Packet == NULL) { |   if (Packet == NULL) { | ||||||
|     return EFI_OUT_OF_RESOURCES; |     Status = EFI_OUT_OF_RESOURCES; | ||||||
|  |     goto ON_ERROR; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Packet->Size                       = DHCP6_BASE_PACKET_SIZE + UserLen; |   Packet->Size                       = DHCP6_BASE_PACKET_SIZE + UserLen; | ||||||
| @ -1543,26 +1630,38 @@ Dhcp6SendRenewRebindMsg ( | |||||||
|   Cursor = Packet->Dhcp6.Option; |   Cursor = Packet->Dhcp6.Option; | ||||||
| 
 | 
 | ||||||
|   Length = HTONS (ClientId->Length); |   Length = HTONS (ClientId->Length); | ||||||
|   Cursor = Dhcp6AppendOption ( |   Status = Dhcp6AppendOption ( | ||||||
|              Cursor, |              Packet, | ||||||
|  |              &Cursor, | ||||||
|              HTONS (Dhcp6OptClientId), |              HTONS (Dhcp6OptClientId), | ||||||
|              Length, |              Length, | ||||||
|              ClientId->Duid |              ClientId->Duid | ||||||
|              ); |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   Cursor = Dhcp6AppendETOption ( |   Status = Dhcp6AppendETOption ( | ||||||
|              Cursor, |              Packet, | ||||||
|  |              &Cursor, | ||||||
|              Instance, |              Instance, | ||||||
|              &Elapsed |              &Elapsed | ||||||
|              ); |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   Cursor = Dhcp6AppendIaOption ( |   Status = Dhcp6AppendIaOption ( | ||||||
|              Cursor, |              Packet, | ||||||
|  |              &Cursor, | ||||||
|              Instance->IaCb.Ia, |              Instance->IaCb.Ia, | ||||||
|              Instance->IaCb.T1, |              Instance->IaCb.T1, | ||||||
|              Instance->IaCb.T2, |              Instance->IaCb.T2, | ||||||
|              Packet->Dhcp6.Header.MessageType |              Packet->Dhcp6.Header.MessageType | ||||||
|              ); |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   if (!RebindRequest) { |   if (!RebindRequest) { | ||||||
|     //
 |     //
 | ||||||
| @ -1578,18 +1677,22 @@ Dhcp6SendRenewRebindMsg ( | |||||||
|                Dhcp6OptServerId |                Dhcp6OptServerId | ||||||
|                ); |                ); | ||||||
|     if (Option == NULL) { |     if (Option == NULL) { | ||||||
|       FreePool (Packet); |       Status = EFI_DEVICE_ERROR; | ||||||
|       return EFI_DEVICE_ERROR; |       goto ON_ERROR; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     ServerId = (EFI_DHCP6_DUID *)(Option + 2); |     ServerId = (EFI_DHCP6_DUID *)(Option + 2); | ||||||
| 
 | 
 | ||||||
|     Cursor = Dhcp6AppendOption ( |     Status = Dhcp6AppendOption ( | ||||||
|                Cursor, |                Packet, | ||||||
|  |                &Cursor, | ||||||
|                HTONS (Dhcp6OptServerId), |                HTONS (Dhcp6OptServerId), | ||||||
|                ServerId->Length, |                ServerId->Length, | ||||||
|                ServerId->Duid |                ServerId->Duid | ||||||
|                ); |                ); | ||||||
|  |     if (EFI_ERROR (Status)) { | ||||||
|  |       goto ON_ERROR; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
| @ -1597,18 +1700,18 @@ Dhcp6SendRenewRebindMsg ( | |||||||
|   //
 |   //
 | ||||||
|   for (Index = 0; Index < Instance->Config->OptionCount; Index++) { |   for (Index = 0; Index < Instance->Config->OptionCount; Index++) { | ||||||
|     UserOpt = Instance->Config->OptionList[Index]; |     UserOpt = Instance->Config->OptionList[Index]; | ||||||
|     Cursor  = Dhcp6AppendOption ( |     Status  = Dhcp6AppendOption ( | ||||||
|                 Cursor, |                 Packet, | ||||||
|  |                 &Cursor, | ||||||
|                 UserOpt->OpCode, |                 UserOpt->OpCode, | ||||||
|                 UserOpt->OpLen, |                 UserOpt->OpLen, | ||||||
|                 UserOpt->Data |                 UserOpt->Data | ||||||
|                 ); |                 ); | ||||||
|  |     if (EFI_ERROR (Status)) { | ||||||
|  |       goto ON_ERROR; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   //
 |  | ||||||
|   // Determine the size/length of packet.
 |  | ||||||
|   //
 |  | ||||||
|   Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option); |  | ||||||
|   ASSERT (Packet->Size > Packet->Length + 8); |   ASSERT (Packet->Size > Packet->Length + 8); | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
| @ -1618,10 +1721,8 @@ Dhcp6SendRenewRebindMsg ( | |||||||
|   Event = (RebindRequest) ? Dhcp6EnterRebinding : Dhcp6EnterRenewing; |   Event = (RebindRequest) ? Dhcp6EnterRebinding : Dhcp6EnterRenewing; | ||||||
| 
 | 
 | ||||||
|   Status = Dhcp6CallbackUser (Instance, Event, &Packet); |   Status = Dhcp6CallbackUser (Instance, Event, &Packet); | ||||||
| 
 |  | ||||||
|   if (EFI_ERROR (Status)) { |   if (EFI_ERROR (Status)) { | ||||||
|     FreePool (Packet); |     goto ON_ERROR; | ||||||
|     return Status; |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
| @ -1638,16 +1739,22 @@ Dhcp6SendRenewRebindMsg ( | |||||||
|   Instance->StartTime = 0; |   Instance->StartTime = 0; | ||||||
| 
 | 
 | ||||||
|   Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); |   Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); | ||||||
| 
 |  | ||||||
|   if (EFI_ERROR (Status)) { |   if (EFI_ERROR (Status)) { | ||||||
|     FreePool (Packet); |     goto ON_ERROR; | ||||||
|     return Status; |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Enqueue the sent packet for the retransmission in case reply timeout.
 |   // Enqueue the sent packet for the retransmission in case reply timeout.
 | ||||||
|   //
 |   //
 | ||||||
|   return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); |   return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); | ||||||
|  | 
 | ||||||
|  | ON_ERROR: | ||||||
|  | 
 | ||||||
|  |   if (Packet) { | ||||||
|  |     FreePool (Packet); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return Status; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
| @ -1811,7 +1918,8 @@ Dhcp6SendInfoRequestMsg ( | |||||||
|   //
 |   //
 | ||||||
|   Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); |   Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); | ||||||
|   if (Packet == NULL) { |   if (Packet == NULL) { | ||||||
|     return EFI_OUT_OF_RESOURCES; |     Status = EFI_OUT_OF_RESOURCES; | ||||||
|  |     goto ON_ERROR; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Packet->Size                       = DHCP6_BASE_PACKET_SIZE + UserLen; |   Packet->Size                       = DHCP6_BASE_PACKET_SIZE + UserLen; | ||||||
| @ -1828,44 +1936,56 @@ Dhcp6SendInfoRequestMsg ( | |||||||
| 
 | 
 | ||||||
|   if (SendClientId) { |   if (SendClientId) { | ||||||
|     Length = HTONS (ClientId->Length); |     Length = HTONS (ClientId->Length); | ||||||
|     Cursor = Dhcp6AppendOption ( |     Status = Dhcp6AppendOption ( | ||||||
|                Cursor, |                Packet, | ||||||
|  |                &Cursor, | ||||||
|                HTONS (Dhcp6OptClientId), |                HTONS (Dhcp6OptClientId), | ||||||
|                Length, |                Length, | ||||||
|                ClientId->Duid |                ClientId->Duid | ||||||
|                ); |                ); | ||||||
|  |     if (EFI_ERROR (Status)) { | ||||||
|  |       goto ON_ERROR; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Cursor = Dhcp6AppendETOption ( |   Status = Dhcp6AppendETOption ( | ||||||
|              Cursor, |              Packet, | ||||||
|  |              &Cursor, | ||||||
|              Instance, |              Instance, | ||||||
|              &Elapsed |              &Elapsed | ||||||
|              ); |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   Cursor = Dhcp6AppendOption ( |   Status = Dhcp6AppendOption ( | ||||||
|              Cursor, |              Packet, | ||||||
|  |              &Cursor, | ||||||
|              OptionRequest->OpCode, |              OptionRequest->OpCode, | ||||||
|              OptionRequest->OpLen, |              OptionRequest->OpLen, | ||||||
|              OptionRequest->Data |              OptionRequest->Data | ||||||
|              ); |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Append user-defined when configurate Dhcp6 service.
 |   // Append user-defined when configurate Dhcp6 service.
 | ||||||
|   //
 |   //
 | ||||||
|   for (Index = 0; Index < OptionCount; Index++) { |   for (Index = 0; Index < OptionCount; Index++) { | ||||||
|     UserOpt = OptionList[Index]; |     UserOpt = OptionList[Index]; | ||||||
|     Cursor  = Dhcp6AppendOption ( |     Status  = Dhcp6AppendOption ( | ||||||
|                 Cursor, |                 Packet, | ||||||
|  |                 &Cursor, | ||||||
|                 UserOpt->OpCode, |                 UserOpt->OpCode, | ||||||
|                 UserOpt->OpLen, |                 UserOpt->OpLen, | ||||||
|                 UserOpt->Data |                 UserOpt->Data | ||||||
|                 ); |                 ); | ||||||
|  |     if (EFI_ERROR (Status)) { | ||||||
|  |       goto ON_ERROR; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   //
 |  | ||||||
|   // Determine the size/length of packet.
 |  | ||||||
|   //
 |  | ||||||
|   Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option); |  | ||||||
|   ASSERT (Packet->Size > Packet->Length + 8); |   ASSERT (Packet->Size > Packet->Length + 8); | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
| @ -1877,16 +1997,22 @@ Dhcp6SendInfoRequestMsg ( | |||||||
|   // Send info-request packet with no state.
 |   // Send info-request packet with no state.
 | ||||||
|   //
 |   //
 | ||||||
|   Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); |   Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); | ||||||
| 
 |  | ||||||
|   if (EFI_ERROR (Status)) { |   if (EFI_ERROR (Status)) { | ||||||
|     FreePool (Packet); |     goto ON_ERROR; | ||||||
|     return Status; |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Enqueue the sent packet for the retransmission in case reply timeout.
 |   // Enqueue the sent packet for the retransmission in case reply timeout.
 | ||||||
|   //
 |   //
 | ||||||
|   return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, Retransmission); |   return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, Retransmission); | ||||||
|  | 
 | ||||||
|  | ON_ERROR: | ||||||
|  | 
 | ||||||
|  |   if (Packet) { | ||||||
|  |     FreePool (Packet); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return Status; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
| @ -1937,7 +2063,8 @@ Dhcp6SendConfirmMsg ( | |||||||
|   //
 |   //
 | ||||||
|   Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); |   Packet = AllocateZeroPool (DHCP6_BASE_PACKET_SIZE + UserLen); | ||||||
|   if (Packet == NULL) { |   if (Packet == NULL) { | ||||||
|     return EFI_OUT_OF_RESOURCES; |     Status = EFI_OUT_OF_RESOURCES; | ||||||
|  |     goto ON_ERROR; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Packet->Size                       = DHCP6_BASE_PACKET_SIZE + UserLen; |   Packet->Size                       = DHCP6_BASE_PACKET_SIZE + UserLen; | ||||||
| @ -1951,54 +2078,64 @@ Dhcp6SendConfirmMsg ( | |||||||
|   Cursor = Packet->Dhcp6.Option; |   Cursor = Packet->Dhcp6.Option; | ||||||
| 
 | 
 | ||||||
|   Length = HTONS (ClientId->Length); |   Length = HTONS (ClientId->Length); | ||||||
|   Cursor = Dhcp6AppendOption ( |   Status = Dhcp6AppendOption ( | ||||||
|              Cursor, |              Packet, | ||||||
|  |              &Cursor, | ||||||
|              HTONS (Dhcp6OptClientId), |              HTONS (Dhcp6OptClientId), | ||||||
|              Length, |              Length, | ||||||
|              ClientId->Duid |              ClientId->Duid | ||||||
|              ); |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   Cursor = Dhcp6AppendETOption ( |   Status = Dhcp6AppendETOption ( | ||||||
|              Cursor, |              Packet, | ||||||
|  |              &Cursor, | ||||||
|              Instance, |              Instance, | ||||||
|              &Elapsed |              &Elapsed | ||||||
|              ); |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   Cursor = Dhcp6AppendIaOption ( |   Status = Dhcp6AppendIaOption ( | ||||||
|              Cursor, |              Packet, | ||||||
|  |              &Cursor, | ||||||
|              Instance->IaCb.Ia, |              Instance->IaCb.Ia, | ||||||
|              Instance->IaCb.T1, |              Instance->IaCb.T1, | ||||||
|              Instance->IaCb.T2, |              Instance->IaCb.T2, | ||||||
|              Packet->Dhcp6.Header.MessageType |              Packet->Dhcp6.Header.MessageType | ||||||
|              ); |              ); | ||||||
|  |   if (EFI_ERROR (Status)) { | ||||||
|  |     goto ON_ERROR; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Append user-defined when configurate Dhcp6 service.
 |   // Append user-defined when configurate Dhcp6 service.
 | ||||||
|   //
 |   //
 | ||||||
|   for (Index = 0; Index < Instance->Config->OptionCount; Index++) { |   for (Index = 0; Index < Instance->Config->OptionCount; Index++) { | ||||||
|     UserOpt = Instance->Config->OptionList[Index]; |     UserOpt = Instance->Config->OptionList[Index]; | ||||||
|     Cursor  = Dhcp6AppendOption ( |     Status  = Dhcp6AppendOption ( | ||||||
|                 Cursor, |                 Packet, | ||||||
|  |                 &Cursor, | ||||||
|                 UserOpt->OpCode, |                 UserOpt->OpCode, | ||||||
|                 UserOpt->OpLen, |                 UserOpt->OpLen, | ||||||
|                 UserOpt->Data |                 UserOpt->Data | ||||||
|                 ); |                 ); | ||||||
|  |     if (EFI_ERROR (Status)) { | ||||||
|  |       goto ON_ERROR; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   //
 |  | ||||||
|   // Determine the size/length of packet.
 |  | ||||||
|   //
 |  | ||||||
|   Packet->Length += (UINT32)(Cursor - Packet->Dhcp6.Option); |  | ||||||
|   ASSERT (Packet->Size > Packet->Length + 8); |   ASSERT (Packet->Size > Packet->Length + 8); | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Callback to user with the packet to be sent and check the user's feedback.
 |   // Callback to user with the packet to be sent and check the user's feedback.
 | ||||||
|   //
 |   //
 | ||||||
|   Status = Dhcp6CallbackUser (Instance, Dhcp6SendConfirm, &Packet); |   Status = Dhcp6CallbackUser (Instance, Dhcp6SendConfirm, &Packet); | ||||||
| 
 |  | ||||||
|   if (EFI_ERROR (Status)) { |   if (EFI_ERROR (Status)) { | ||||||
|     FreePool (Packet); |     goto ON_ERROR; | ||||||
|     return Status; |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
| @ -2012,16 +2149,22 @@ Dhcp6SendConfirmMsg ( | |||||||
|   Instance->StartTime = 0; |   Instance->StartTime = 0; | ||||||
| 
 | 
 | ||||||
|   Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); |   Status = Dhcp6TransmitPacket (Instance, Packet, Elapsed); | ||||||
| 
 |  | ||||||
|   if (EFI_ERROR (Status)) { |   if (EFI_ERROR (Status)) { | ||||||
|     FreePool (Packet); |     goto ON_ERROR; | ||||||
|     return Status; |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Enqueue the sent packet for the retransmission in case reply timeout.
 |   // Enqueue the sent packet for the retransmission in case reply timeout.
 | ||||||
|   //
 |   //
 | ||||||
|   return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); |   return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL); | ||||||
|  | 
 | ||||||
|  | ON_ERROR: | ||||||
|  | 
 | ||||||
|  |   if (Packet) { | ||||||
|  |     FreePool (Packet); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return Status; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | |||||||
| @ -577,24 +577,33 @@ Dhcp6OnTransmitted ( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   Append the option to Buf, and move Buf to the end. |   Append the option to Buf, update the length of packet, and move Buf to the end. | ||||||
| 
 | 
 | ||||||
|   @param[in, out] Buf           The pointer to the buffer. |   @param[in, out] Packet         A pointer to the packet, on success Packet->Length | ||||||
|   @param[in]      OptType       The option type. |                                  will be updated. | ||||||
|   @param[in]      OptLen        The length of option contents. |   @param[in, out] PacketCursor   The pointer in the packet, on success PacketCursor | ||||||
|   @param[in]      Data          The pointer to the option content. |                                  will be moved to the end of the option. | ||||||
|  |   @param[in]      OptType        The option type. | ||||||
|  |   @param[in]      OptLen         The length of option contents. | ||||||
|  |   @param[in]      Data           The pointer to the option content. | ||||||
| 
 | 
 | ||||||
|   @return         Buf           The position to append the next option. |   @retval   EFI_INVALID_PARAMETER An argument provided to the function was invalid | ||||||
|  |   @retval   EFI_BUFFER_TOO_SMALL  The buffer is too small to append the option. | ||||||
|  |   @retval   EFI_SUCCESS           The option is appended successfully. | ||||||
| 
 | 
 | ||||||
| **/ | **/ | ||||||
| UINT8 * | EFI_STATUS | ||||||
| Dhcp6AppendOption ( | Dhcp6AppendOption ( | ||||||
|   IN OUT UINT8   *Buf, |   IN OUT EFI_DHCP6_PACKET  *Packet, | ||||||
|   IN     UINT16  OptType, |   IN OUT UINT8             **PacketCursor, | ||||||
|   IN     UINT16  OptLen, |   IN     UINT16            OptType, | ||||||
|   IN     UINT8   *Data |   IN     UINT16            OptLen, | ||||||
|  |   IN     UINT8             *Data | ||||||
|   ) |   ) | ||||||
| { | { | ||||||
|  |   UINT32  Length; | ||||||
|  |   UINT32  BytesNeeded; | ||||||
|  | 
 | ||||||
|   //
 |   //
 | ||||||
|   //  The format of Dhcp6 option:
 |   //  The format of Dhcp6 option:
 | ||||||
|   //
 |   //
 | ||||||
| @ -607,35 +616,95 @@ Dhcp6AppendOption ( | |||||||
|   //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |   //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | ||||||
|   //
 |   //
 | ||||||
| 
 | 
 | ||||||
|   ASSERT (OptLen != 0); |   //
 | ||||||
|  |   // Verify the arguments are valid
 | ||||||
|  |   //
 | ||||||
|  |   if (Packet == NULL) { | ||||||
|  |     return EFI_INVALID_PARAMETER; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   WriteUnaligned16 ((UINT16 *)Buf, OptType); |   if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { | ||||||
|   Buf += 2; |     return EFI_INVALID_PARAMETER; | ||||||
|   WriteUnaligned16 ((UINT16 *)Buf, OptLen); |   } | ||||||
|   Buf += 2; |  | ||||||
|   CopyMem (Buf, Data, NTOHS (OptLen)); |  | ||||||
|   Buf += NTOHS (OptLen); |  | ||||||
| 
 | 
 | ||||||
|   return Buf; |   if (Data == NULL) { | ||||||
|  |     return EFI_INVALID_PARAMETER; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if (OptLen == 0) { | ||||||
|  |     return EFI_INVALID_PARAMETER; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   //
 | ||||||
|  |   // Verify the PacketCursor is within the packet
 | ||||||
|  |   //
 | ||||||
|  |   if (  (*PacketCursor < Packet->Dhcp6.Option) | ||||||
|  |      || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) | ||||||
|  |   { | ||||||
|  |     return EFI_INVALID_PARAMETER; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   //
 | ||||||
|  |   // Calculate the bytes needed for the option
 | ||||||
|  |   //
 | ||||||
|  |   BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + NTOHS (OptLen); | ||||||
|  | 
 | ||||||
|  |   //
 | ||||||
|  |   // Space remaining in the packet
 | ||||||
|  |   //
 | ||||||
|  |   Length = Packet->Size - Packet->Length; | ||||||
|  |   if (Length < BytesNeeded) { | ||||||
|  |     return EFI_BUFFER_TOO_SMALL; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   //
 | ||||||
|  |   // Verify the PacketCursor is within the packet
 | ||||||
|  |   //
 | ||||||
|  |   if (  (*PacketCursor < Packet->Dhcp6.Option) | ||||||
|  |      || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) | ||||||
|  |   { | ||||||
|  |     return EFI_INVALID_PARAMETER; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   WriteUnaligned16 ((UINT16 *)*PacketCursor, OptType); | ||||||
|  |   *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; | ||||||
|  |   WriteUnaligned16 ((UINT16 *)*PacketCursor, OptLen); | ||||||
|  |   *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; | ||||||
|  |   CopyMem (*PacketCursor, Data, NTOHS (OptLen)); | ||||||
|  |   *PacketCursor += NTOHS (OptLen); | ||||||
|  | 
 | ||||||
|  |   // Update the packet length by the length of the option + 4 bytes
 | ||||||
|  |   Packet->Length += BytesNeeded; | ||||||
|  | 
 | ||||||
|  |   return EFI_SUCCESS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   Append the appointed IA Address option to Buf, and move Buf to the end. |   Append the appointed IA Address option to Buf, and move Buf to the end. | ||||||
| 
 | 
 | ||||||
|   @param[in, out] Buf           The pointer to the position to append. |   @param[in, out] Packet        A pointer to the packet, on success Packet->Length | ||||||
|  |                                 will be updated. | ||||||
|  |   @param[in, out] PacketCursor  The pointer in the packet, on success PacketCursor | ||||||
|  |                                 will be moved to the end of the option. | ||||||
|   @param[in]      IaAddr        The pointer to the IA Address. |   @param[in]      IaAddr        The pointer to the IA Address. | ||||||
|   @param[in]      MessageType   Message type of DHCP6 package. |   @param[in]      MessageType   Message type of DHCP6 package. | ||||||
| 
 | 
 | ||||||
|   @return         Buf           The position to append the next option. |   @retval   EFI_INVALID_PARAMETER An argument provided to the function was invalid | ||||||
|  |   @retval   EFI_BUFFER_TOO_SMALL  The buffer is too small to append the option. | ||||||
|  |   @retval   EFI_SUCCESS           The option is appended successfully. | ||||||
| 
 | 
 | ||||||
| **/ | **/ | ||||||
| UINT8 * | EFI_STATUS | ||||||
| Dhcp6AppendIaAddrOption ( | Dhcp6AppendIaAddrOption ( | ||||||
|   IN OUT UINT8                 *Buf, |   IN OUT EFI_DHCP6_PACKET      *Packet, | ||||||
|  |   IN OUT UINT8                 **PacketCursor, | ||||||
|   IN     EFI_DHCP6_IA_ADDRESS  *IaAddr, |   IN     EFI_DHCP6_IA_ADDRESS  *IaAddr, | ||||||
|   IN     UINT32                MessageType |   IN     UINT32                MessageType | ||||||
|   ) |   ) | ||||||
| { | { | ||||||
|  |   UINT32  BytesNeeded; | ||||||
|  |   UINT32  Length; | ||||||
|  | 
 | ||||||
|   //  The format of the IA Address option is:
 |   //  The format of the IA Address option is:
 | ||||||
|   //
 |   //
 | ||||||
|   //       0                   1                   2                   3
 |   //       0                   1                   2                   3
 | ||||||
| @ -657,17 +726,60 @@ Dhcp6AppendIaAddrOption ( | |||||||
|   //      .                                                               .
 |   //      .                                                               .
 | ||||||
|   //      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |   //      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | ||||||
| 
 | 
 | ||||||
|  |   //
 | ||||||
|  |   // Verify the arguments are valid
 | ||||||
|  |   //
 | ||||||
|  |   if (Packet == NULL) { | ||||||
|  |     return EFI_INVALID_PARAMETER; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { | ||||||
|  |     return EFI_INVALID_PARAMETER; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if (IaAddr == NULL) { | ||||||
|  |     return EFI_INVALID_PARAMETER; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   //
 | ||||||
|  |   // Verify the PacketCursor is within the packet
 | ||||||
|  |   //
 | ||||||
|  |   if (  (*PacketCursor < Packet->Dhcp6.Option) | ||||||
|  |      || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) | ||||||
|  |   { | ||||||
|  |     return EFI_INVALID_PARAMETER; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   BytesNeeded  = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN; | ||||||
|  |   BytesNeeded += sizeof (EFI_IPv6_ADDRESS); | ||||||
|  |   //
 | ||||||
|  |   // Even if the preferred-lifetime is 0, it still needs to store it.
 | ||||||
|  |   //
 | ||||||
|  |   BytesNeeded += sizeof (IaAddr->PreferredLifetime); | ||||||
|  |   //
 | ||||||
|  |   // Even if the valid-lifetime is 0, it still needs to store it.
 | ||||||
|  |   //
 | ||||||
|  |   BytesNeeded += sizeof (IaAddr->ValidLifetime); | ||||||
|  | 
 | ||||||
|  |   //
 | ||||||
|  |   // Space remaining in the packet
 | ||||||
|  |   //
 | ||||||
|  |   Length = Packet->Size - Packet->Length; | ||||||
|  |   if (Length < BytesNeeded) { | ||||||
|  |     return EFI_BUFFER_TOO_SMALL; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Fill the value of Ia Address option type
 |   // Fill the value of Ia Address option type
 | ||||||
|   //
 |   //
 | ||||||
|   WriteUnaligned16 ((UINT16 *)Buf, HTONS (Dhcp6OptIaAddr)); |   WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptIaAddr)); | ||||||
|   Buf += 2; |   *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; | ||||||
| 
 | 
 | ||||||
|   WriteUnaligned16 ((UINT16 *)Buf, HTONS (sizeof (EFI_DHCP6_IA_ADDRESS))); |   WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (sizeof (EFI_DHCP6_IA_ADDRESS))); | ||||||
|   Buf += 2; |   *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; | ||||||
| 
 | 
 | ||||||
|   CopyMem (Buf, &IaAddr->IpAddress, sizeof (EFI_IPv6_ADDRESS)); |   CopyMem (*PacketCursor, &IaAddr->IpAddress, sizeof (EFI_IPv6_ADDRESS)); | ||||||
|   Buf += sizeof (EFI_IPv6_ADDRESS); |   *PacketCursor += sizeof (EFI_IPv6_ADDRESS); | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Fill the value of preferred-lifetime and valid-lifetime.
 |   // Fill the value of preferred-lifetime and valid-lifetime.
 | ||||||
| @ -675,44 +787,58 @@ Dhcp6AppendIaAddrOption ( | |||||||
|   // should set to 0 when initiate a Confirm message.
 |   // should set to 0 when initiate a Confirm message.
 | ||||||
|   //
 |   //
 | ||||||
|   if (MessageType != Dhcp6MsgConfirm) { |   if (MessageType != Dhcp6MsgConfirm) { | ||||||
|     WriteUnaligned32 ((UINT32 *)Buf, HTONL (IaAddr->PreferredLifetime)); |     WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->PreferredLifetime)); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Buf += 4; |   *PacketCursor += sizeof (IaAddr->PreferredLifetime); | ||||||
| 
 | 
 | ||||||
|   if (MessageType != Dhcp6MsgConfirm) { |   if (MessageType != Dhcp6MsgConfirm) { | ||||||
|     WriteUnaligned32 ((UINT32 *)Buf, HTONL (IaAddr->ValidLifetime)); |     WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->ValidLifetime)); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   Buf += 4; |   *PacketCursor += sizeof (IaAddr->ValidLifetime); | ||||||
| 
 | 
 | ||||||
|   return Buf; |   //
 | ||||||
|  |   // Update the packet length
 | ||||||
|  |   //
 | ||||||
|  |   Packet->Length += BytesNeeded; | ||||||
|  | 
 | ||||||
|  |   return EFI_SUCCESS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   Append the appointed Ia option to Buf, and move Buf to the end. |   Append the appointed Ia option to Buf, and move Buf to the end. | ||||||
| 
 | 
 | ||||||
|   @param[in, out] Buf           The pointer to the position to append. |   @param[in, out] Packet        A pointer to the packet, on success Packet->Length | ||||||
|  |                                 will be updated. | ||||||
|  |   @param[in, out] PacketCursor  The pointer in the packet, on success PacketCursor | ||||||
|  |                                 will be moved to the end of the option. | ||||||
|   @param[in]      Ia            The pointer to the Ia. |   @param[in]      Ia            The pointer to the Ia. | ||||||
|   @param[in]      T1            The time of T1. |   @param[in]      T1            The time of T1. | ||||||
|   @param[in]      T2            The time of T2. |   @param[in]      T2            The time of T2. | ||||||
|   @param[in]      MessageType   Message type of DHCP6 package. |   @param[in]      MessageType   Message type of DHCP6 package. | ||||||
| 
 | 
 | ||||||
|   @return         Buf           The position to append the next Ia option. |   @retval   EFI_INVALID_PARAMETER An argument provided to the function was invalid | ||||||
|  |   @retval   EFI_BUFFER_TOO_SMALL  The buffer is too small to append the option. | ||||||
|  |   @retval   EFI_SUCCESS           The option is appended successfully. | ||||||
| 
 | 
 | ||||||
| **/ | **/ | ||||||
| UINT8 * | EFI_STATUS | ||||||
| Dhcp6AppendIaOption ( | Dhcp6AppendIaOption ( | ||||||
|   IN OUT UINT8         *Buf, |   IN OUT EFI_DHCP6_PACKET  *Packet, | ||||||
|   IN     EFI_DHCP6_IA  *Ia, |   IN OUT UINT8             **PacketCursor, | ||||||
|   IN     UINT32        T1, |   IN     EFI_DHCP6_IA      *Ia, | ||||||
|   IN     UINT32        T2, |   IN     UINT32            T1, | ||||||
|   IN     UINT32        MessageType |   IN     UINT32            T2, | ||||||
|  |   IN     UINT32            MessageType | ||||||
|   ) |   ) | ||||||
| { | { | ||||||
|   UINT8   *AddrOpt; |   UINT8       *AddrOpt; | ||||||
|   UINT16  *Len; |   UINT16      *Len; | ||||||
|   UINTN   Index; |   UINTN       Index; | ||||||
|  |   UINT32      BytesNeeded; | ||||||
|  |   UINT32      Length; | ||||||
|  |   EFI_STATUS  Status; | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   //  The format of IA_NA and IA_TA option:
 |   //  The format of IA_NA and IA_TA option:
 | ||||||
| @ -733,32 +859,74 @@ Dhcp6AppendIaOption ( | |||||||
|   //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |   //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | ||||||
|   //
 |   //
 | ||||||
| 
 | 
 | ||||||
|  |   //
 | ||||||
|  |   // Verify the arguments are valid
 | ||||||
|  |   //
 | ||||||
|  |   if (Packet == NULL) { | ||||||
|  |     return EFI_INVALID_PARAMETER; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { | ||||||
|  |     return EFI_INVALID_PARAMETER; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if (Ia == NULL) { | ||||||
|  |     return EFI_INVALID_PARAMETER; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   //
 | ||||||
|  |   // Verify the PacketCursor is within the packet
 | ||||||
|  |   //
 | ||||||
|  |   if (  (*PacketCursor < Packet->Dhcp6.Option) | ||||||
|  |      || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) | ||||||
|  |   { | ||||||
|  |     return EFI_INVALID_PARAMETER; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   BytesNeeded  = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN; | ||||||
|  |   BytesNeeded += sizeof (Ia->Descriptor.IaId); | ||||||
|  |   //
 | ||||||
|  |   // + N for the IA_NA-options/IA_TA-options
 | ||||||
|  |   // Dhcp6AppendIaAddrOption will need to check the length for each address
 | ||||||
|  |   //
 | ||||||
|  |   if (Ia->Descriptor.Type == Dhcp6OptIana) { | ||||||
|  |     BytesNeeded += sizeof (T1) + sizeof (T2); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   //
 | ||||||
|  |   // Space remaining in the packet
 | ||||||
|  |   //
 | ||||||
|  |   Length = (UINT16)(Packet->Size - Packet->Length); | ||||||
|  |   if (Length < BytesNeeded) { | ||||||
|  |     return EFI_BUFFER_TOO_SMALL; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Fill the value of Ia option type
 |   // Fill the value of Ia option type
 | ||||||
|   //
 |   //
 | ||||||
|   WriteUnaligned16 ((UINT16 *)Buf, HTONS (Ia->Descriptor.Type)); |   WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Ia->Descriptor.Type)); | ||||||
|   Buf += 2; |   *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Fill the len of Ia option later, keep the pointer first
 |   // Fill the len of Ia option later, keep the pointer first
 | ||||||
|   //
 |   //
 | ||||||
|   Len  = (UINT16 *)Buf; |   Len            = (UINT16 *)*PacketCursor; | ||||||
|   Buf += 2; |   *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Fill the value of iaid
 |   // Fill the value of iaid
 | ||||||
|   //
 |   //
 | ||||||
|   WriteUnaligned32 ((UINT32 *)Buf, HTONL (Ia->Descriptor.IaId)); |   WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (Ia->Descriptor.IaId)); | ||||||
|   Buf += 4; |   *PacketCursor += sizeof (Ia->Descriptor.IaId); | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Fill the value of t1 and t2 if iana, keep it 0xffffffff if no specified.
 |   // Fill the value of t1 and t2 if iana, keep it 0xffffffff if no specified.
 | ||||||
|   //
 |   //
 | ||||||
|   if (Ia->Descriptor.Type == Dhcp6OptIana) { |   if (Ia->Descriptor.Type == Dhcp6OptIana) { | ||||||
|     WriteUnaligned32 ((UINT32 *)Buf, HTONL ((T1 != 0) ? T1 : 0xffffffff)); |     WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T1 != 0) ? T1 : 0xffffffff)); | ||||||
|     Buf += 4; |     *PacketCursor += sizeof (T1); | ||||||
|     WriteUnaligned32 ((UINT32 *)Buf, HTONL ((T2 != 0) ? T2 : 0xffffffff)); |     WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T2 != 0) ? T2 : 0xffffffff)); | ||||||
|     Buf += 4; |     *PacketCursor += sizeof (T2); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
| @ -766,35 +934,51 @@ Dhcp6AppendIaOption ( | |||||||
|   //
 |   //
 | ||||||
|   for (Index = 0; Index < Ia->IaAddressCount; Index++) { |   for (Index = 0; Index < Ia->IaAddressCount; Index++) { | ||||||
|     AddrOpt = (UINT8 *)Ia->IaAddress + Index * sizeof (EFI_DHCP6_IA_ADDRESS); |     AddrOpt = (UINT8 *)Ia->IaAddress + Index * sizeof (EFI_DHCP6_IA_ADDRESS); | ||||||
|     Buf     = Dhcp6AppendIaAddrOption (Buf, (EFI_DHCP6_IA_ADDRESS *)AddrOpt, MessageType); |     Status  = Dhcp6AppendIaAddrOption (Packet, PacketCursor, (EFI_DHCP6_IA_ADDRESS *)AddrOpt, MessageType); | ||||||
|  |     if (EFI_ERROR (Status)) { | ||||||
|  |       return Status; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Fill the value of Ia option length
 |   // Fill the value of Ia option length
 | ||||||
|   //
 |   //
 | ||||||
|   *Len = HTONS ((UINT16)(Buf - (UINT8 *)Len - 2)); |   *Len = HTONS ((UINT16)(*PacketCursor - (UINT8 *)Len - 2)); | ||||||
| 
 | 
 | ||||||
|   return Buf; |   //
 | ||||||
|  |   // Update the packet length
 | ||||||
|  |   //
 | ||||||
|  |   Packet->Length += BytesNeeded; | ||||||
|  | 
 | ||||||
|  |   return EFI_SUCCESS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   Append the appointed Elapsed time option to Buf, and move Buf to the end. |   Append the appointed Elapsed time option to Buf, and move Buf to the end. | ||||||
| 
 | 
 | ||||||
|   @param[in, out] Buf           The pointer to the position to append. |   @param[in, out] Packet        A pointer to the packet, on success Packet->Length | ||||||
|  |   @param[in, out] PacketCursor  The pointer in the packet, on success PacketCursor | ||||||
|  |                                 will be moved to the end of the option. | ||||||
|   @param[in]      Instance      The pointer to the Dhcp6 instance. |   @param[in]      Instance      The pointer to the Dhcp6 instance. | ||||||
|   @param[out]     Elapsed       The pointer to the elapsed time value in |   @param[out]     Elapsed       The pointer to the elapsed time value in | ||||||
|                                   the generated packet. |                                 the generated packet. | ||||||
| 
 | 
 | ||||||
|   @return         Buf           The position to append the next Ia option. |   @retval   EFI_INVALID_PARAMETER An argument provided to the function was invalid | ||||||
|  |   @retval   EFI_BUFFER_TOO_SMALL  The buffer is too small to append the option. | ||||||
|  |   @retval   EFI_SUCCESS           The option is appended successfully. | ||||||
| 
 | 
 | ||||||
| **/ | **/ | ||||||
| UINT8 * | EFI_STATUS | ||||||
| Dhcp6AppendETOption ( | Dhcp6AppendETOption ( | ||||||
|   IN OUT UINT8           *Buf, |   IN OUT EFI_DHCP6_PACKET  *Packet, | ||||||
|   IN     DHCP6_INSTANCE  *Instance, |   IN OUT UINT8             **PacketCursor, | ||||||
|   OUT    UINT16          **Elapsed |   IN     DHCP6_INSTANCE    *Instance, | ||||||
|  |   OUT    UINT16            **Elapsed | ||||||
|   ) |   ) | ||||||
| { | { | ||||||
|  |   UINT32  BytesNeeded; | ||||||
|  |   UINT32  Length; | ||||||
|  | 
 | ||||||
|   //
 |   //
 | ||||||
|   //  The format of elapsed time option:
 |   //  The format of elapsed time option:
 | ||||||
|   //
 |   //
 | ||||||
| @ -806,27 +990,70 @@ Dhcp6AppendETOption ( | |||||||
|   //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |   //  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | ||||||
|   //
 |   //
 | ||||||
| 
 | 
 | ||||||
|  |   //
 | ||||||
|  |   // Verify the arguments are valid
 | ||||||
|  |   //
 | ||||||
|  |   if (Packet == NULL) { | ||||||
|  |     return EFI_INVALID_PARAMETER; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if ((PacketCursor == NULL) || (*PacketCursor == NULL)) { | ||||||
|  |     return EFI_INVALID_PARAMETER; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if (Instance == NULL) { | ||||||
|  |     return EFI_INVALID_PARAMETER; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if ((Elapsed == NULL)) { | ||||||
|  |     return EFI_INVALID_PARAMETER; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   //
 | ||||||
|  |   // Verify the PacketCursor is within the packet
 | ||||||
|  |   //
 | ||||||
|  |   if (  (*PacketCursor < Packet->Dhcp6.Option) | ||||||
|  |      || (*PacketCursor >= Packet->Dhcp6.Option + (Packet->Size - sizeof (EFI_DHCP6_HEADER)))) | ||||||
|  |   { | ||||||
|  |     return EFI_INVALID_PARAMETER; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN; | ||||||
|  |   //
 | ||||||
|  |   // + 2 for elapsed-time
 | ||||||
|  |   //
 | ||||||
|  |   BytesNeeded += sizeof (UINT16); | ||||||
|  |   //
 | ||||||
|  |   // Space remaining in the packet
 | ||||||
|  |   //
 | ||||||
|  |   Length = Packet->Size - Packet->Length; | ||||||
|  |   if (Length < BytesNeeded) { | ||||||
|  |     return EFI_BUFFER_TOO_SMALL; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Fill the value of elapsed-time option type.
 |   // Fill the value of elapsed-time option type.
 | ||||||
|   //
 |   //
 | ||||||
|   WriteUnaligned16 ((UINT16 *)Buf, HTONS (Dhcp6OptElapsedTime)); |   WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptElapsedTime)); | ||||||
|   Buf += 2; |   *PacketCursor += DHCP6_SIZE_OF_OPT_CODE; | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Fill the len of elapsed-time option, which is fixed.
 |   // Fill the len of elapsed-time option, which is fixed.
 | ||||||
|   //
 |   //
 | ||||||
|   WriteUnaligned16 ((UINT16 *)Buf, HTONS (2)); |   WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (2)); | ||||||
|   Buf += 2; |   *PacketCursor += DHCP6_SIZE_OF_OPT_LEN; | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Fill in elapsed time value with 0 value for now.  The actual value is
 |   // Fill in elapsed time value with 0 value for now.  The actual value is
 | ||||||
|   // filled in later just before the packet is transmitted.
 |   // filled in later just before the packet is transmitted.
 | ||||||
|   //
 |   //
 | ||||||
|   WriteUnaligned16 ((UINT16 *)Buf, HTONS (0)); |   WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (0)); | ||||||
|   *Elapsed = (UINT16 *)Buf; |   *Elapsed       = (UINT16 *)*PacketCursor; | ||||||
|   Buf     += 2; |   *PacketCursor += sizeof (UINT16); | ||||||
| 
 | 
 | ||||||
|   return Buf; |   Packet->Length += BytesNeeded; | ||||||
|  | 
 | ||||||
|  |   return EFI_SUCCESS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | |||||||
| @ -160,69 +160,85 @@ Dhcp6OnTransmitted ( | |||||||
|   ); |   ); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   Append the appointed option to the buf, and move the buf to the end. |   Append the option to Buf, update the length of packet, and move Buf to the end. | ||||||
| 
 | 
 | ||||||
|   @param[in, out] Buf           The pointer to buffer. |   @param[in, out] Packet         A pointer to the packet, on success Packet->Length | ||||||
|   @param[in]      OptType       The option type. |                                  will be updated. | ||||||
|   @param[in]      OptLen        The length of option content.s |   @param[in, out] PacketCursor   The pointer in the packet, on success PacketCursor | ||||||
|   @param[in]      Data          The pointer to the option content. |                                  will be moved to the end of the option. | ||||||
| 
 |   @param[in]      OptType        The option type. | ||||||
|   @return         Buf           The position to append the next option. |   @param[in]      OptLen         The length of option contents. | ||||||
|  |   @param[in]      Data           The pointer to the option content. | ||||||
| 
 | 
 | ||||||
|  |   @retval   EFI_INVALID_PARAMETER An argument provided to the function was invalid | ||||||
|  |   @retval   EFI_BUFFER_TOO_SMALL  The buffer is too small to append the option. | ||||||
|  |   @retval   EFI_SUCCESS           The option is appended successfully. | ||||||
| **/ | **/ | ||||||
| UINT8 * | EFI_STATUS | ||||||
| Dhcp6AppendOption ( | Dhcp6AppendOption ( | ||||||
|   IN OUT UINT8   *Buf, |   IN OUT EFI_DHCP6_PACKET  *Packet, | ||||||
|   IN     UINT16  OptType, |   IN OUT UINT8             **PacketCursor, | ||||||
|   IN     UINT16  OptLen, |   IN     UINT16            OptType, | ||||||
|   IN     UINT8   *Data |   IN     UINT16            OptLen, | ||||||
|  |   IN     UINT8             *Data | ||||||
|   ); |   ); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   Append the Ia option to Buf, and move Buf to the end. |   Append the appointed Ia option to Buf, update the Ia option length, and move Buf | ||||||
| 
 |   to the end of the option. | ||||||
|   @param[in, out] Buf           The pointer to the position to append. |   @param[in, out] Packet        A pointer to the packet, on success Packet->Length | ||||||
|  |                                 will be updated. | ||||||
|  |   @param[in, out] PacketCursor   The pointer in the packet, on success PacketCursor | ||||||
|  |                                  will be moved to the end of the option. | ||||||
|   @param[in]      Ia            The pointer to the Ia. |   @param[in]      Ia            The pointer to the Ia. | ||||||
|   @param[in]      T1            The time of T1. |   @param[in]      T1            The time of T1. | ||||||
|   @param[in]      T2            The time of T2. |   @param[in]      T2            The time of T2. | ||||||
|   @param[in]      MessageType   Message type of DHCP6 package. |   @param[in]      MessageType   Message type of DHCP6 package. | ||||||
| 
 | 
 | ||||||
|   @return         Buf           The position to append the next Ia option. |   @retval   EFI_INVALID_PARAMETER An argument provided to the function was invalid | ||||||
| 
 |   @retval   EFI_BUFFER_TOO_SMALL  The buffer is too small to append the option. | ||||||
|  |   @retval   EFI_SUCCESS           The option is appended successfully. | ||||||
| **/ | **/ | ||||||
| UINT8 * | EFI_STATUS | ||||||
| Dhcp6AppendIaOption ( | Dhcp6AppendIaOption ( | ||||||
|   IN OUT UINT8         *Buf, |   IN OUT EFI_DHCP6_PACKET  *Packet, | ||||||
|   IN     EFI_DHCP6_IA  *Ia, |   IN OUT UINT8             **PacketCursor, | ||||||
|   IN     UINT32        T1, |   IN     EFI_DHCP6_IA      *Ia, | ||||||
|   IN     UINT32        T2, |   IN     UINT32            T1, | ||||||
|   IN     UINT32        MessageType |   IN     UINT32            T2, | ||||||
|  |   IN     UINT32            MessageType | ||||||
|   ); |   ); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   Append the appointed Elapsed time option to Buf, and move Buf to the end. |   Append the appointed Elapsed time option to Buf, and move Buf to the end. | ||||||
| 
 | 
 | ||||||
|   @param[in, out] Buf           The pointer to the position to append. |   @param[in, out] Packet        A pointer to the packet, on success Packet->Length | ||||||
|  |   @param[in, out] PacketCursor   The pointer in the packet, on success PacketCursor | ||||||
|  |                                  will be moved to the end of the option. | ||||||
|   @param[in]      Instance      The pointer to the Dhcp6 instance. |   @param[in]      Instance      The pointer to the Dhcp6 instance. | ||||||
|   @param[out]     Elapsed       The pointer to the elapsed time value in |   @param[out]     Elapsed       The pointer to the elapsed time value in | ||||||
|                                   the generated packet. |                                   the generated packet. | ||||||
| 
 | 
 | ||||||
|   @return         Buf           The position to append the next Ia option. |   @retval   EFI_INVALID_PARAMETER An argument provided to the function was invalid | ||||||
|  |   @retval   EFI_BUFFER_TOO_SMALL  The buffer is too small to append the option. | ||||||
|  |   @retval   EFI_SUCCESS           The option is appended successfully. | ||||||
| 
 | 
 | ||||||
| **/ | **/ | ||||||
| UINT8 * | EFI_STATUS | ||||||
| Dhcp6AppendETOption ( | Dhcp6AppendETOption ( | ||||||
|   IN OUT UINT8           *Buf, |   IN OUT EFI_DHCP6_PACKET  *Packet, | ||||||
|   IN     DHCP6_INSTANCE  *Instance, |   IN OUT UINT8             **PacketCursor, | ||||||
|   OUT    UINT16          **Elapsed |   IN     DHCP6_INSTANCE    *Instance, | ||||||
|  |   OUT    UINT16            **Elapsed | ||||||
|   ); |   ); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|   Set the elapsed time based on the given instance and the pointer to the |   Set the elapsed time based on the given instance and the pointer to the | ||||||
|   elapsed time option. |   elapsed time option. | ||||||
| 
 | 
 | ||||||
|   @param[in]      Elapsed       The pointer to the position to append. |   @retval   EFI_INVALID_PARAMETER An argument provided to the function was invalid | ||||||
|   @param[in]      Instance      The pointer to the Dhcp6 instance. |   @retval   EFI_BUFFER_TOO_SMALL  The buffer is too small to append the option. | ||||||
|  |   @retval   EFI_SUCCESS           The option is appended successfully. | ||||||
| **/ | **/ | ||||||
| VOID | VOID | ||||||
| SetElapsedTime ( | SetElapsedTime ( | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user