Node->Ipv4.StaticIpAddress = FALSE;\r
CopyMem (&Node->Ipv4.GatewayIpAddress, &Private->GatewayIp, sizeof (EFI_IPv4_ADDRESS));\r
CopyMem (&Node->Ipv4.SubnetMask, &Private->SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
- \r
- TmpDevicePath = AppendDevicePathNode (Private->ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);\r
- FreePool (Node);\r
- if (TmpDevicePath == NULL) {\r
+ } else {\r
+ Node = AllocateZeroPool (sizeof (IPv6_DEVICE_PATH));\r
+ if (Node == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
- } else {\r
- ASSERT (FALSE);\r
+ Node->Ipv6.Header.Type = MESSAGING_DEVICE_PATH;\r
+ Node->Ipv6.Header.SubType = MSG_IPv6_DP;\r
+ SetDevicePathNodeLength (Node, sizeof (IPv6_DEVICE_PATH));\r
+ Node->Ipv6.PrefixLength = IP6_PREFIX_LENGTH;\r
+ Node->Ipv6.RemotePort = Private->Port;\r
+ Node->Ipv6.Protocol = EFI_IP_PROTO_TCP; \r
+ Node->Ipv6.IpAddressOrigin = 0;\r
+ CopyMem (&Node->Ipv6.LocalIpAddress, &Private->StationIp.v6, sizeof (EFI_IPv6_ADDRESS));\r
+ CopyMem (&Node->Ipv6.RemoteIpAddress, &Private->ServerIp.v6, sizeof (EFI_IPv6_ADDRESS));\r
+ CopyMem (&Node->Ipv6.GatewayIpAddress, &Private->GatewayIp.v6, sizeof (EFI_IPv6_ADDRESS));\r
+ }\r
+ \r
+ TmpDevicePath = AppendDevicePathNode (Private->ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);\r
+ FreePool (Node);\r
+ if (TmpDevicePath == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
}\r
\r
//\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- //\r
- // Reinstall the device path protocol of the child handle.\r
- //\r
- Status = gBS->ReinstallProtocolInterface (\r
- Private->ChildHandle,\r
- &gEfiDevicePathProtocolGuid,\r
- Private->DevicePath,\r
- NewDevicePath\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
+ if (!Private->UsingIpv6) {\r
+ //\r
+ // Reinstall the device path protocol of the child handle.\r
+ //\r
+ Status = gBS->ReinstallProtocolInterface (\r
+ Private->Ip4Nic->Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ Private->Ip4Nic->DevicePath,\r
+ NewDevicePath\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ \r
+ FreePool (Private->Ip4Nic->DevicePath);\r
+ Private->Ip4Nic->DevicePath = NewDevicePath;\r
+ } else {\r
+ //\r
+ // Reinstall the device path protocol of the child handle.\r
+ //\r
+ Status = gBS->ReinstallProtocolInterface (\r
+ Private->Ip6Nic->Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ Private->Ip6Nic->DevicePath,\r
+ NewDevicePath\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ FreePool (Private->Ip6Nic->DevicePath);\r
+ Private->Ip6Nic->DevicePath = NewDevicePath;\r
}\r
\r
- FreePool (Private->DevicePath);\r
- Private->DevicePath = NewDevicePath;\r
return EFI_SUCCESS;\r
}\r
\r
\r
**/\r
EFI_STATUS\r
-HttpBootExtractUriInfo (\r
+HttpBootDhcp4ExtractUriInfo (\r
IN HTTP_BOOT_PRIVATE_DATA *Private\r
)\r
{\r
return Status;\r
}\r
\r
+/**\r
+ Parse the boot file URI information from the selected Dhcp6 offer packet.\r
+\r
+ @param[in] Private The pointer to the driver's private data.\r
+\r
+ @retval EFI_SUCCESS Successfully parsed out all the boot information.\r
+ @retval Others Failed to parse out the boot information.\r
+\r
+**/\r
+EFI_STATUS\r
+HttpBootDhcp6ExtractUriInfo (\r
+ IN HTTP_BOOT_PRIVATE_DATA *Private\r
+ )\r
+{\r
+ HTTP_BOOT_DHCP6_PACKET_CACHE *SelectOffer;\r
+ HTTP_BOOT_DHCP6_PACKET_CACHE *HttpOffer;\r
+ UINT32 SelectIndex;\r
+ UINT32 ProxyIndex;\r
+ EFI_DHCP6_PACKET_OPTION *Option;\r
+ EFI_IPv6_ADDRESS IpAddr;\r
+ CHAR8 *HostName;\r
+ CHAR16 *HostNameStr;\r
+ EFI_STATUS Status;\r
+\r
+ ASSERT (Private != NULL);\r
+ ASSERT (Private->SelectIndex != 0);\r
+ SelectIndex = Private->SelectIndex - 1;\r
+ ASSERT (SelectIndex < HTTP_BOOT_OFFER_MAX_NUM);\r
+\r
+ Status = EFI_SUCCESS;\r
+ HostName = NULL;\r
+ //\r
+ // SelectOffer contains the IP address configuration and name server configuration.\r
+ // HttpOffer contains the boot file URL.\r
+ //\r
+ SelectOffer = &Private->OfferBuffer[SelectIndex].Dhcp6;\r
+ if ((SelectOffer->OfferType == HttpOfferTypeDhcpIpUri) || (SelectOffer->OfferType == HttpOfferTypeDhcpNameUriDns)) {\r
+ HttpOffer = SelectOffer;\r
+ } else {\r
+ ASSERT (Private->SelectProxyType != HttpOfferTypeMax);\r
+ ProxyIndex = Private->OfferIndex[Private->SelectProxyType][0];\r
+ HttpOffer = &Private->OfferBuffer[ProxyIndex].Dhcp6;\r
+ }\r
+\r
+ //\r
+ // Set the Local station address to IP layer.\r
+ //\r
+ Status = HttpBootSetIp6Address (Private);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ \r
+ //\r
+ // Configure the default DNS server if server assigned.\r
+ //\r
+ if ((SelectOffer->OfferType == HttpOfferTypeDhcpNameUriDns) || (SelectOffer->OfferType == HttpOfferTypeDhcpDns)) {\r
+ Option = SelectOffer->OptList[HTTP_BOOT_DHCP6_IDX_DNS_SERVER];\r
+ ASSERT (Option != NULL);\r
+ Status = HttpBootSetIp6Dns (\r
+ Private,\r
+ HTONS (Option->OpLen),\r
+ Option->Data\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+ \r
+ //\r
+ // Extract the HTTP server Ip frome URL. This is used to Check route table \r
+ // whether can send message to HTTP Server Ip through the GateWay.\r
+ //\r
+ Status = HttpUrlGetIp6 (\r
+ (CHAR8*) HttpOffer->OptList[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL]->Data,\r
+ HttpOffer->UriParser,\r
+ &IpAddr\r
+ );\r
+ \r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // The Http server address is expressed by Name Ip, so perform DNS resolution\r
+ //\r
+ Status = HttpUrlGetHostName (\r
+ (CHAR8*) HttpOffer->OptList[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL]->Data,\r
+ HttpOffer->UriParser,\r
+ &HostName\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ \r
+ HostNameStr = AllocateZeroPool ((AsciiStrLen (HostName) + 1) * sizeof (CHAR16));\r
+ if (HostNameStr == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Error;\r
+ }\r
+ \r
+ AsciiStrToUnicodeStr (HostName, HostNameStr);\r
+ Status = HttpBootDns (Private, HostNameStr, &IpAddr);\r
+ FreePool (HostNameStr);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Error;\r
+ } \r
+ } \r
+ \r
+ CopyMem (&Private->ServerIp.v6, &IpAddr, sizeof (EFI_IPv6_ADDRESS)); \r
+ \r
+ //\r
+ // register the IPv6 gateway address to the network device.\r
+ //\r
+ Status = HttpBootSetIp6Gateway (Private);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ \r
+ //\r
+ // Extract the port from URL, and use default HTTP port 80 if not provided.\r
+ //\r
+ Status = HttpUrlGetPort (\r
+ (CHAR8*) HttpOffer->OptList[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL]->Data,\r
+ HttpOffer->UriParser,\r
+ &Private->Port\r
+ );\r
+ if (EFI_ERROR (Status) || Private->Port == 0) {\r
+ Private->Port = 80;\r
+ }\r
+ \r
+ //\r
+ // Record the URI of boot file from the selected HTTP offer.\r
+ //\r
+ Private->BootFileUriParser = HttpOffer->UriParser;\r
+ Private->BootFileUri = (CHAR8*) HttpOffer->OptList[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL]->Data;\r
+\r
+ \r
+ //\r
+ // All boot informations are valid here.\r
+ //\r
+ AsciiPrint ("\n URI: %a", Private->BootFileUri);\r
+ //\r
+ // Update the device path to include the IP and boot URI information.\r
+ //\r
+ Status = HttpBootUpdateDevicePath (Private);\r
+\r
+Error:\r
+ \r
+ if (HostName != NULL) {\r
+ FreePool (HostName);\r
+ }\r
+ \r
+ return Status;\r
+}\r
+\r
+\r
/**\r
Discover all the boot information for boot file.\r
\r
}\r
\r
if (!Private->UsingIpv6) {\r
- Status = HttpBootExtractUriInfo (Private);\r
+ Status = HttpBootDhcp4ExtractUriInfo (Private);\r
} else {\r
- ASSERT (FALSE);\r
+ Status = HttpBootDhcp6ExtractUriInfo (Private);\r
}\r
\r
return Status;\r
\r
ZeroMem (&ConfigData, sizeof (HTTP_IO_CONFIG_DATA));\r
if (!Private->UsingIpv6) {\r
- ConfigData.Config4.HttpVersion = HttpVersion11;\r
+ ConfigData.Config4.HttpVersion = HttpVersion11;\r
ConfigData.Config4.RequestTimeOut = HTTP_BOOT_REQUEST_TIMEOUT;\r
IP4_COPY_ADDRESS (&ConfigData.Config4.LocalIp, &Private->StationIp.v4);\r
IP4_COPY_ADDRESS (&ConfigData.Config4.SubnetMask, &Private->SubnetMask.v4);\r
} else {\r
- ASSERT (FALSE);\r
+ ConfigData.Config6.HttpVersion = HttpVersion11;\r
+ ConfigData.Config6.RequestTimeOut = HTTP_BOOT_REQUEST_TIMEOUT;\r
+ IP6_COPY_ADDRESS (&ConfigData.Config6.LocalIp, &Private->StationIp.v6);\r
}\r
\r
Status = HttpIoCreateIo (\r