/** @file\r
Functions implementation related with DHCPv6 for HTTP boot driver.\r
\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials are licensed and made available under \r
the terms and conditions of the BSD License that accompanies this distribution. \r
The full text of the license may be found at\r
//\r
// Append client option request option\r
//\r
- OptList[Index]->OpCode = HTONS (HTTP_BOOT_DHCP6_OPT_ORO);\r
+ OptList[Index]->OpCode = HTONS (DHCP6_OPT_ORO);\r
OptList[Index]->OpLen = HTONS (8);\r
OptEnt.Oro = (HTTP_BOOT_DHCP6_OPTION_ORO *) OptList[Index]->Data;\r
- OptEnt.Oro->OpCode[0] = HTONS(HTTP_BOOT_DHCP6_OPT_BOOT_FILE_URL);\r
- OptEnt.Oro->OpCode[1] = HTONS(HTTP_BOOT_DHCP6_OPT_BOOT_FILE_PARAM);\r
- OptEnt.Oro->OpCode[2] = HTONS(HTTP_BOOT_DHCP6_OPT_DNS_SERVERS);\r
- OptEnt.Oro->OpCode[3] = HTONS(HTTP_BOOT_DHCP6_OPT_VENDOR_CLASS);\r
+ OptEnt.Oro->OpCode[0] = HTONS(DHCP6_OPT_BOOT_FILE_URL);\r
+ OptEnt.Oro->OpCode[1] = HTONS(DHCP6_OPT_BOOT_FILE_PARAM);\r
+ OptEnt.Oro->OpCode[2] = HTONS(DHCP6_OPT_DNS_SERVERS);\r
+ OptEnt.Oro->OpCode[3] = HTONS(DHCP6_OPT_VENDOR_CLASS);\r
Index++;\r
OptList[Index] = GET_NEXT_DHCP6_OPTION (OptList[Index - 1]);\r
\r
//\r
// Append client network device interface option\r
//\r
- OptList[Index]->OpCode = HTONS (HTTP_BOOT_DHCP6_OPT_UNDI);\r
+ OptList[Index]->OpCode = HTONS (DHCP6_OPT_UNDI);\r
OptList[Index]->OpLen = HTONS ((UINT16)3);\r
OptEnt.Undi = (HTTP_BOOT_DHCP6_OPTION_UNDI *) OptList[Index]->Data;\r
\r
//\r
// Append client system architecture option\r
//\r
- OptList[Index]->OpCode = HTONS (HTTP_BOOT_DHCP6_OPT_ARCH);\r
+ OptList[Index]->OpCode = HTONS (DHCP6_OPT_ARCH);\r
OptList[Index]->OpLen = HTONS ((UINT16) sizeof (HTTP_BOOT_DHCP6_OPTION_ARCH));\r
OptEnt.Arch = (HTTP_BOOT_DHCP6_OPTION_ARCH *) OptList[Index]->Data;\r
Value = HTONS (EFI_HTTP_BOOT_CLIENT_SYSTEM_ARCHITECTURE);\r
//\r
// Append vendor class identify option.\r
//\r
- OptList[Index]->OpCode = HTONS (HTTP_BOOT_DHCP6_OPT_VENDOR_CLASS);\r
+ OptList[Index]->OpCode = HTONS (DHCP6_OPT_VENDOR_CLASS);\r
OptList[Index]->OpLen = HTONS ((UINT16) sizeof (HTTP_BOOT_DHCP6_OPTION_VENDOR_CLASS));\r
OptEnt.VendorClass = (HTTP_BOOT_DHCP6_OPTION_VENDOR_CLASS *) OptList[Index]->Data;\r
OptEnt.VendorClass->Vendor = HTONL (HTTP_BOOT_DHCP6_ENTERPRISE_NUM);\r
//\r
while (Offset < Length) {\r
\r
- if (NTOHS (Option->OpCode) == HTTP_BOOT_DHCP6_OPT_IA_NA) {\r
+ if (NTOHS (Option->OpCode) == DHCP6_OPT_IA_NA) {\r
Options[HTTP_BOOT_DHCP6_IDX_IA_NA] = Option;\r
- } else if (NTOHS (Option->OpCode) == HTTP_BOOT_DHCP6_OPT_BOOT_FILE_URL) {\r
+ } else if (NTOHS (Option->OpCode) == DHCP6_OPT_BOOT_FILE_URL) {\r
//\r
// The server sends this option to inform the client about an URL to a boot file.\r
//\r
Options[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL] = Option;\r
- } else if (NTOHS (Option->OpCode) == HTTP_BOOT_DHCP6_OPT_BOOT_FILE_PARAM) {\r
+ } else if (NTOHS (Option->OpCode) == DHCP6_OPT_BOOT_FILE_PARAM) {\r
Options[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_PARAM] = Option;\r
- } else if (NTOHS (Option->OpCode) == HTTP_BOOT_DHCP6_OPT_VENDOR_CLASS) {\r
+ } else if (NTOHS (Option->OpCode) == DHCP6_OPT_VENDOR_CLASS) {\r
Options[HTTP_BOOT_DHCP6_IDX_VENDOR_CLASS] = Option;\r
- } else if (NTOHS (Option->OpCode) == HTTP_BOOT_DHCP6_OPT_DNS_SERVERS) {\r
+ } else if (NTOHS (Option->OpCode) == DHCP6_OPT_DNS_SERVERS) {\r
Options[HTTP_BOOT_DHCP6_IDX_DNS_SERVER] = Option;\r
}\r
\r
Option = HttpBootParseDhcp6Options (\r
Option->Data + 12,\r
NTOHS (Option->OpLen),\r
- HTTP_BOOT_DHCP6_OPT_STATUS_CODE\r
+ DHCP6_OPT_STATUS_CODE\r
);\r
if ((Option != NULL && Option->Data[0] == 0) || (Option == NULL)) {\r
IsProxyOffer = FALSE;\r
@param[in] Dst The pointer to the cache buffer for DHCPv6 packet.\r
@param[in] Src The pointer to the DHCPv6 packet to be cached.\r
\r
+ @retval EFI_SUCCESS Packet is copied.\r
+ @retval EFI_BUFFER_TOO_SMALL Cache buffer is not big enough to hold the packet.\r
+\r
**/\r
-VOID\r
+EFI_STATUS\r
HttpBootCacheDhcp6Packet (\r
IN EFI_DHCP6_PACKET *Dst,\r
IN EFI_DHCP6_PACKET *Src\r
)\r
{\r
- ASSERT (Dst->Size >= Src->Length);\r
+ if (Dst->Size < Src->Length) {\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
\r
CopyMem (&Dst->Dhcp6, &Src->Dhcp6, Src->Length);\r
Dst->Length = Src->Length;\r
+ \r
+ return EFI_SUCCESS;\r
}\r
\r
/**\r
@param[in] Private The pointer to HTTP_BOOT_PRIVATE_DATA.\r
@param[in] RcvdOffer The pointer to the received offer packet.\r
\r
+ @retval EFI_SUCCESS Cache and parse the packet successfully.\r
+ @retval Others Operation failed.\r
+\r
**/\r
-VOID\r
+EFI_STATUS\r
HttpBootCacheDhcp6Offer (\r
IN HTTP_BOOT_PRIVATE_DATA *Private,\r
IN EFI_DHCP6_PACKET *RcvdOffer\r
HTTP_BOOT_DHCP6_PACKET_CACHE *Cache6;\r
EFI_DHCP6_PACKET *Offer;\r
HTTP_BOOT_OFFER_TYPE OfferType;\r
+ EFI_STATUS Status;\r
\r
Cache6 = &Private->OfferBuffer[Private->OfferNum].Dhcp6;\r
Offer = &Cache6->Packet.Offer;\r
//\r
// Cache the content of DHCPv6 packet firstly.\r
//\r
- HttpBootCacheDhcp6Packet(Offer, RcvdOffer);\r
+ Status = HttpBootCacheDhcp6Packet(Offer, RcvdOffer);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
\r
//\r
// Validate the DHCPv6 packet, and parse the options and offer type.\r
//\r
if (EFI_ERROR (HttpBootParseDhcp6Packet (Cache6))) {\r
- return ;\r
+ return EFI_ABORTED;\r
}\r
\r
//\r
ASSERT (Private->OfferCount[OfferType] < HTTP_BOOT_OFFER_MAX_NUM);\r
Private->OfferIndex[OfferType][Private->OfferCount[OfferType]] = Private->OfferNum;\r
Private->OfferCount[OfferType]++;\r
- Private->OfferNum++; \r
+ Private->OfferNum++;\r
+ \r
+ return EFI_SUCCESS;\r
}\r
\r
/**\r
OUT EFI_DHCP6_PACKET **NewPacket OPTIONAL\r
)\r
{\r
- HTTP_BOOT_PRIVATE_DATA *Private;\r
- EFI_DHCP6_PACKET *SelectAd;\r
- EFI_STATUS Status;\r
- if ((Dhcp6Event != Dhcp6RcvdAdvertise) && (Dhcp6Event != Dhcp6SelectAdvertise)) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- ASSERT (Packet != NULL);\r
+ HTTP_BOOT_PRIVATE_DATA *Private;\r
+ EFI_DHCP6_PACKET *SelectAd;\r
+ EFI_STATUS Status;\r
+ BOOLEAN Received;\r
+ \r
+ if ((Dhcp6Event != Dhcp6SendSolicit) &&\r
+ (Dhcp6Event != Dhcp6RcvdAdvertise) &&\r
+ (Dhcp6Event != Dhcp6SendRequest) &&\r
+ (Dhcp6Event != Dhcp6RcvdReply) &&\r
+ (Dhcp6Event != Dhcp6SelectAdvertise)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ ASSERT (Packet != NULL);\r
+ \r
+ Private = (HTTP_BOOT_PRIVATE_DATA *) Context;\r
+ Status = EFI_SUCCESS;\r
+ if (Private->HttpBootCallback != NULL && Dhcp6Event != Dhcp6SelectAdvertise) {\r
+ Received = (BOOLEAN) (Dhcp6Event == Dhcp6RcvdAdvertise || Dhcp6Event == Dhcp6RcvdReply);\r
+ Status = Private->HttpBootCallback->Callback (\r
+ Private->HttpBootCallback, \r
+ HttpBootDhcp6,\r
+ Received,\r
+ Packet->Length,\r
+ &Packet->Dhcp6\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_ABORTED;\r
+ }\r
+ }\r
+ switch (Dhcp6Event) {\r
\r
- Private = (HTTP_BOOT_PRIVATE_DATA *) Context;\r
- Status = EFI_SUCCESS;\r
- switch (Dhcp6Event) {\r
- \r
- case Dhcp6RcvdAdvertise:\r
- Status = EFI_NOT_READY;\r
- if (Private->OfferNum < HTTP_BOOT_OFFER_MAX_NUM) {\r
- //\r
- // Cache the dhcp offers to OfferBuffer[] for select later, and record\r
- // the OfferIndex and OfferCount.\r
- //\r
- HttpBootCacheDhcp6Offer (Private, Packet);\r
- }\r
- break;\r
-\r
- case Dhcp6SelectAdvertise:\r
- //\r
- // Select offer by the default policy or by order, and record the SelectIndex\r
- // and SelectProxyType.\r
- //\r
- HttpBootSelectDhcpOffer (Private);\r
-\r
- if (Private->SelectIndex == 0) {\r
- Status = EFI_ABORTED;\r
- } else {\r
- ASSERT (NewPacket != NULL);\r
- SelectAd = &Private->OfferBuffer[Private->SelectIndex - 1].Dhcp6.Packet.Offer;\r
- *NewPacket = AllocateZeroPool (SelectAd->Size);\r
- if (*NewPacket == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- CopyMem (*NewPacket, SelectAd, SelectAd->Size);\r
- }\r
- break;\r
+ case Dhcp6RcvdAdvertise:\r
+ Status = EFI_NOT_READY;\r
+ if (Packet->Length > HTTP_BOOT_DHCP6_PACKET_MAX_SIZE) {\r
+ //\r
+ // Ignore the incoming packets which exceed the maximum length.\r
+ //\r
+ break;\r
+ }\r
+ if (Private->OfferNum < HTTP_BOOT_OFFER_MAX_NUM) {\r
+ //\r
+ // Cache the dhcp offers to OfferBuffer[] for select later, and record\r
+ // the OfferIndex and OfferCount.\r
+ // If error happens, just ignore this packet and continue to wait more offer.\r
+ //\r
+ HttpBootCacheDhcp6Offer (Private, Packet);\r
+ }\r
+ break;\r
+\r
+ case Dhcp6SelectAdvertise:\r
+ //\r
+ // Select offer by the default policy or by order, and record the SelectIndex\r
+ // and SelectProxyType.\r
+ //\r
+ HttpBootSelectDhcpOffer (Private);\r
+\r
+ if (Private->SelectIndex == 0) {\r
+ Status = EFI_ABORTED;\r
+ } else {\r
+ ASSERT (NewPacket != NULL);\r
+ SelectAd = &Private->OfferBuffer[Private->SelectIndex - 1].Dhcp6.Packet.Offer;\r
+ *NewPacket = AllocateZeroPool (SelectAd->Size);\r
+ if (*NewPacket == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ CopyMem (*NewPacket, SelectAd, SelectAd->Size);\r
+ }\r
+ break;\r
\r
- default:\r
- break;\r
+ default:\r
+ break;\r
}\r
\r
return Status; \r