39 OptList[Index]->OpCode = HTONS (DHCP6_OPT_ORO);
40 OptList[Index]->OpLen = HTONS (8);
42 OptEnt.Oro->OpCode[0] = HTONS (DHCP6_OPT_BOOT_FILE_URL);
43 OptEnt.Oro->OpCode[1] = HTONS (DHCP6_OPT_BOOT_FILE_PARAM);
44 OptEnt.Oro->OpCode[2] = HTONS (DHCP6_OPT_DNS_SERVERS);
45 OptEnt.Oro->OpCode[3] = HTONS (DHCP6_OPT_VENDOR_CLASS);
47 OptList[Index] = GET_NEXT_DHCP6_OPTION (OptList[Index - 1]);
52 OptList[Index]->OpCode = HTONS (DHCP6_OPT_UNDI);
53 OptList[Index]->OpLen = HTONS ((UINT16)3);
56 if (Private->Nii !=
NULL) {
57 OptEnt.Undi->Type = Private->Nii->Type;
58 OptEnt.Undi->MajorVer = Private->Nii->MajorVer;
59 OptEnt.Undi->MinorVer = Private->Nii->MinorVer;
61 OptEnt.Undi->Type = DEFAULT_UNDI_TYPE;
62 OptEnt.Undi->MajorVer = DEFAULT_UNDI_MAJOR;
63 OptEnt.Undi->MinorVer = DEFAULT_UNDI_MINOR;
67 OptList[Index] = GET_NEXT_DHCP6_OPTION (OptList[Index - 1]);
72 OptList[Index]->OpCode = HTONS (DHCP6_OPT_ARCH);
75 Value = HTONS (EFI_HTTP_BOOT_CLIENT_SYSTEM_ARCHITECTURE);
76 CopyMem (&OptEnt.Arch->Type, &Value, sizeof (UINT16));
78 OptList[Index] = GET_NEXT_DHCP6_OPTION (OptList[Index - 1]);
83 OptList[Index]->OpCode = HTONS (DHCP6_OPT_VENDOR_CLASS);
86 OptEnt.VendorClass->Vendor = HTONL (HTTP_BOOT_DHCP6_ENTERPRISE_NUM);
89 &OptEnt.VendorClass->ClassId,
90 DEFAULT_CLASS_ID_DATA,
94 EFI_HTTP_BOOT_CLIENT_SYSTEM_ARCHITECTURE,
95 OptEnt.VendorClass->ClassId.ArchitectureType,
96 sizeof (OptEnt.VendorClass->ClassId.ArchitectureType)
99 if (Private->Nii !=
NULL) {
101 OptEnt.VendorClass->ClassId.InterfaceName,
102 Private->Nii->StringId,
103 sizeof (OptEnt.VendorClass->ClassId.InterfaceName)
106 Private->Nii->MajorVer,
107 OptEnt.VendorClass->ClassId.UndiMajor,
108 sizeof (OptEnt.VendorClass->ClassId.UndiMajor)
111 Private->Nii->MinorVer,
112 OptEnt.VendorClass->ClassId.UndiMinor,
113 sizeof (OptEnt.VendorClass->ClassId.UndiMinor)
149 while (Offset < Length) {
150 if (NTOHS (Option->
OpCode) == OptTag) {
154 Offset += (NTOHS (Option->
OpLen) + 4);
180 BOOLEAN IsProxyOffer;
183 BOOLEAN IpExpressedUri;
189 IpExpressedUri =
FALSE;
192 Offer = &Cache6->Packet.Offer;
193 Options = Cache6->OptList;
195 ZeroMem (Cache6->OptList, sizeof (Cache6->OptList));
199 Length = GET_DHCP6_OPTION_SIZE (Offer);
204 while (Offset < Length) {
205 if (NTOHS (Option->
OpCode) == DHCP6_OPT_IA_NA) {
206 Options[HTTP_BOOT_DHCP6_IDX_IA_NA] = Option;
207 }
else if (NTOHS (Option->
OpCode) == DHCP6_OPT_BOOT_FILE_URL) {
211 Options[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL] = Option;
212 }
else if (NTOHS (Option->
OpCode) == DHCP6_OPT_BOOT_FILE_PARAM) {
213 Options[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_PARAM] = Option;
214 }
else if (NTOHS (Option->
OpCode) == DHCP6_OPT_VENDOR_CLASS) {
215 Options[HTTP_BOOT_DHCP6_IDX_VENDOR_CLASS] = Option;
216 }
else if (NTOHS (Option->
OpCode) == DHCP6_OPT_DNS_SERVERS) {
217 Options[HTTP_BOOT_DHCP6_IDX_DNS_SERVER] = Option;
220 Offset += (NTOHS (Option->
OpLen) + 4);
228 Option = Options[HTTP_BOOT_DHCP6_IDX_IA_NA];
229 if (Option !=
NULL) {
232 NTOHS (Option->
OpLen),
233 DHCP6_OPT_STATUS_CODE
235 if (((Option !=
NULL) && (Option->
Data[0] == 0)) || (Option ==
NULL)) {
236 IsProxyOffer =
FALSE;
243 Option = Options[HTTP_BOOT_DHCP6_IDX_VENDOR_CLASS];
245 if ((Option !=
NULL) &&
246 (NTOHS (Option->
OpLen) >= 16) &&
247 (
CompareMem ((Option->
Data + 6), DEFAULT_CLASS_ID_DATA, 10) == 0))
255 Option = Options[HTTP_BOOT_DHCP6_IDX_DNS_SERVER];
256 if (Option !=
NULL) {
263 if (IsHttpOffer && (Options[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL] ==
NULL)) {
264 return EFI_DEVICE_ERROR;
272 (CHAR8 *)Options[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL]->Data,
273 (UINT32)
AsciiStrLen ((CHAR8 *)Options[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL]->Data),
277 if (EFI_ERROR (Status)) {
278 return EFI_DEVICE_ERROR;
282 (CHAR8 *)Options[HTTP_BOOT_DHCP6_IDX_BOOT_FILE_URL]->Data,
286 IpExpressedUri = !EFI_ERROR (Status);
293 if (IpExpressedUri) {
295 OfferType = HttpOfferTypeProxyIpUri;
297 OfferType = IsDnsOffer ? HttpOfferTypeDhcpIpUriDns : HttpOfferTypeDhcpIpUri;
301 OfferType = IsDnsOffer ? HttpOfferTypeDhcpNameUriDns : HttpOfferTypeDhcpNameUri;
303 OfferType = HttpOfferTypeProxyNameUri;
308 OfferType = IsDnsOffer ? HttpOfferTypeDhcpDns : HttpOfferTypeDhcpOnly;
310 return EFI_DEVICE_ERROR;
314 Cache6->OfferType = OfferType;
334 if (Dst->Size < Src->Length) {
335 return EFI_BUFFER_TOO_SMALL;
338 CopyMem (&Dst->Dhcp6, &Src->Dhcp6, Src->Length);
339 Dst->Length = Src->Length;
365 Cache6 = &Private->OfferBuffer[Private->OfferNum].Dhcp6;
366 Offer = &Cache6->Packet.Offer;
372 if (EFI_ERROR (Status)) {
386 OfferType = Cache6->OfferType;
387 ASSERT (OfferType < HttpOfferTypeMax);
388 ASSERT (Private->OfferCount[OfferType] < HTTP_BOOT_OFFER_MAX_NUM);
389 Private->OfferIndex[OfferType][Private->OfferCount[OfferType]] = Private->OfferNum;
390 Private->OfferCount[OfferType]++;
440 ASSERT (Packet !=
NULL);
446 Status = Private->HttpBootCallback->Callback (
447 Private->HttpBootCallback,
453 if (EFI_ERROR (Status)) {
458 switch (Dhcp6Event) {
460 Status = EFI_NOT_READY;
461 if (Packet->Length > HTTP_BOOT_DHCP6_PACKET_MAX_SIZE) {
468 if (Private->OfferNum < HTTP_BOOT_OFFER_MAX_NUM) {
486 if (Private->SelectIndex == 0) {
487 Status = EFI_ABORTED;
489 ASSERT (NewPacket !=
NULL);
490 SelectAd = &Private->OfferBuffer[Private->SelectIndex - 1].Dhcp6.Packet.Offer;
492 if (*NewPacket ==
NULL) {
493 return EFI_OUT_OF_RESOURCES;
536 BOOLEAN GatewayIsFound;
538 ASSERT (GatewayAddr !=
NULL);
539 ASSERT (Private !=
NULL);
542 GatewayIsFound =
FALSE;
549 Status = Ip6->GetModeData (Ip6, &Ip6ModeData,
NULL,
NULL);
550 if (EFI_ERROR (Status)) {
557 for (Index = 0; Index < Ip6ModeData.
RouteCount; Index++) {
560 GatewayIsFound =
TRUE;
589 if (GatewayIsFound || (RetryCount == TimeOutInSecond)) {
598 if (TimeOutEvt ==
NULL) {
599 Status =
gBS->CreateEvent (
606 if (EFI_ERROR (Status)) {
612 if (EFI_ERROR (Status)) {
616 while (EFI_ERROR (
gBS->CheckEvent (TimeOutEvt))) {
622 if (TimeOutEvt !=
NULL) {
623 gBS->CloseEvent (TimeOutEvt);
626 if (GatewayIsFound) {
628 }
else if (RetryCount == TimeOutInSecond) {
629 Status = EFI_TIMEOUT;
654 Ip6Config = Private->Ip6Config;
660 Status = Ip6Config->GetData (
666 if (EFI_ERROR (Status)) {
672 Status = Ip6Config->SetData (
678 if (EFI_ERROR (Status)) {
702 IN VOID *DnsServerData
707 ASSERT (Private->UsingIpv6);
709 Ip6Config = Private->Ip6Config;
711 return Ip6Config->SetData (
736 ASSERT (Private->UsingIpv6);
737 Ip6Config = Private->Ip6Config;
743 Status = Ip6Config->SetData (
747 &Private->GatewayIp.v6
749 if (EFI_ERROR (Status)) {
784 ASSERT (Private->UsingIpv6);
789 Ip6Cfg = Private->Ip6Config;
798 Ip6CfgData.
HopLimit = HTTP_BOOT_DEFAULT_HOPLIMIT;
802 Status = Ip6->Configure (Ip6, &Ip6CfgData);
803 if (EFI_ERROR (Status)) {
811 if (EFI_ERROR (Status)) {
812 Private->NoGateway =
TRUE;
814 IP6_COPY_ADDRESS (&Private->GatewayIp.v6, &GatewayAddr);
821 Status = Ip6Cfg->SetData (
827 if (EFI_ERROR (Status)) {
834 Status =
gBS->CreateEvent (
841 if (EFI_ERROR (Status)) {
848 Status = Ip6Cfg->RegisterDataNotify (
853 if (EFI_ERROR (Status)) {
857 Status = Ip6Cfg->SetData (
863 if (EFI_ERROR (Status) && (Status != EFI_NOT_READY)) {
865 }
else if (Status == EFI_NOT_READY) {
869 while (!IsAddressOk) {
877 Status = Ip6Cfg->GetData (
883 if ((Status != EFI_BUFFER_TOO_SMALL) || (DataSize == 0)) {
884 Status = EFI_DEVICE_ERROR;
889 if (Ip6Addr ==
NULL) {
890 return EFI_OUT_OF_RESOURCES;
893 Status = Ip6Cfg->GetData (
899 if (EFI_ERROR (Status)) {
900 Status = EFI_DEVICE_ERROR;
911 Status = EFI_ABORTED;
917 if (MappedEvt !=
NULL) {
918 Ip6Cfg->UnregisterDataNotify (
923 gBS->CloseEvent (MappedEvt);
926 if (Ip6Addr !=
NULL) {
953 UINT8 Buffer[HTTP_BOOT_DHCP6_OPTION_MAX_SIZE];
957 Dhcp6 = Private->Dhcp6;
958 ASSERT (Dhcp6 !=
NULL);
964 ASSERT (OptCount > 0);
967 if (EFI_ERROR (Status)) {
968 DEBUG ((DEBUG_ERROR,
"%a failed to generate random number: %r\n", __func__, Status));
973 if (Retransmit ==
NULL) {
974 return EFI_OUT_OF_RESOURCES;
992 Retransmit->
Mrt = 32;
993 Retransmit->
Mrd = 60;
998 Status = Dhcp6->Configure (Dhcp6, &Config);
1000 if (EFI_ERROR (Status)) {
1007 Private->OfferNum = 0;
1008 Private->SelectIndex = 0;
1009 ZeroMem (Private->OfferCount, sizeof (Private->OfferCount));
1010 ZeroMem (Private->OfferIndex, sizeof (Private->OfferIndex));
1015 Status = Dhcp6->Start (Dhcp6);
1016 if (EFI_ERROR (Status)) {
1023 Status = Dhcp6->GetModeData (Dhcp6, &Mode,
NULL);
1024 if (EFI_ERROR (Status)) {
1036 if (EFI_ERROR (Status)) {
1037 Dhcp6->Stop (Dhcp6);
1038 Dhcp6->Configure (Dhcp6,
NULL);
1041 Dhcp6->Configure (Dhcp6, &Config);
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define EFI_DHCP6_IA_TYPE_NA
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID HttpBootSelectDhcpOffer(IN HTTP_BOOT_PRIVATE_DATA *Private)
EFI_STATUS HttpBootSetIp6Gateway(IN HTTP_BOOT_PRIVATE_DATA *Private)
UINT32 HttpBootBuildDhcp6Options(IN HTTP_BOOT_PRIVATE_DATA *Private, OUT EFI_DHCP6_PACKET_OPTION **OptList, IN UINT8 *Buffer)
EFI_STATUS HttpBootCheckRouteTable(IN HTTP_BOOT_PRIVATE_DATA *Private, IN UINTN TimeOutInSecond, OUT EFI_IPv6_ADDRESS *GatewayAddr)
EFI_STATUS HttpBootSetIp6Dns(IN HTTP_BOOT_PRIVATE_DATA *Private, IN UINTN DataLength, IN VOID *DnsServerData)
EFI_STATUS HttpBootCacheDhcp6Packet(IN EFI_DHCP6_PACKET *Dst, IN EFI_DHCP6_PACKET *Src)
EFI_STATUS HttpBootCacheDhcp6Offer(IN HTTP_BOOT_PRIVATE_DATA *Private, IN EFI_DHCP6_PACKET *RcvdOffer)
EFI_STATUS HttpBootSetIp6Policy(IN HTTP_BOOT_PRIVATE_DATA *Private)
EFI_STATUS HttpBootParseDhcp6Packet(IN HTTP_BOOT_DHCP6_PACKET_CACHE *Cache6)
EFI_STATUS HttpBootDhcp6Sarr(IN HTTP_BOOT_PRIVATE_DATA *Private)
EFI_DHCP6_PACKET_OPTION * HttpBootParseDhcp6Options(IN UINT8 *Buffer, IN UINT32 Length, IN UINT16 OptTag)
EFI_STATUS EFIAPI HttpBootDhcp6CallBack(IN EFI_DHCP6_PROTOCOL *This, IN VOID *Context, IN EFI_DHCP6_STATE CurrentState, IN EFI_DHCP6_EVENT Dhcp6Event, IN EFI_DHCP6_PACKET *Packet, OUT EFI_DHCP6_PACKET **NewPacket OPTIONAL)
EFI_STATUS HttpBootSetIp6Address(IN HTTP_BOOT_PRIVATE_DATA *Private)
VOID HttpBootShowIp6Addr(IN EFI_IPv6_ADDRESS *Ip)
VOID HttpBootUintnToAscDecWithFormat(IN UINTN Number, IN UINT8 *Buffer, IN INTN Length)
VOID EFIAPI HttpBootCommonNotify(IN EFI_EVENT Event, IN VOID *Context)
EFI_STATUS EFIAPI HttpUrlGetIp6(IN CHAR8 *Url, IN VOID *UrlParser, OUT EFI_IPv6_ADDRESS *Ip6Address)
EFI_STATUS EFIAPI HttpParseUrl(IN CHAR8 *Url, IN UINT32 Length, IN BOOLEAN IsConnectMethod, OUT VOID **UrlParser)
@ Ip6ConfigDataTypeGateway
@ Ip6ConfigDataTypeManualAddress
@ Ip6ConfigDataTypePolicy
@ Ip6ConfigDataTypeDnsServer
@ Ip6ConfigPolicyAutomatic
#define DEBUG(Expression)
BOOLEAN EFIAPI NetIp6IsNetEqual(EFI_IPv6_ADDRESS *Ip1, EFI_IPv6_ADDRESS *Ip2, UINT8 PrefixLength)
BOOLEAN EFIAPI NetIp6IsUnspecifiedAddr(IN EFI_IPv6_ADDRESS *Ip6)
EFI_STATUS EFIAPI PseudoRandomU32(OUT UINT32 *Output)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
IPv6_ADDRESS EFI_IPv6_ADDRESS
UINTN EFIAPI AsciiPrint(IN CONST CHAR8 *Format,...)
BOOLEAN ReconfigureAccept
EFI_DHCP6_IA_DESCRIPTOR IaDescriptor
EFI_DHCP6_RETRANSMISSION * SolicitRetransmission
EFI_DHCP6_CALLBACK Dhcp6Callback
EFI_DHCP6_PACKET_OPTION ** OptionList
EFI_IPv6_ADDRESS IpAddress
UINT16 Type
Type for an IA.
UINT32 IaId
The identifier for an IA.
EFI_DHCP6_IA_ADDRESS IaAddress[1]
EFI_DHCP6_DUID * ClientId
EFI_IP6_NEIGHBOR_CACHE * NeighborCache
EFI_IP6_ICMP_TYPE * IcmpTypeList
EFI_IP6_ADDRESS_INFO * AddressList
EFI_IP6_ROUTE_TABLE * RouteTable
EFI_IPv6_ADDRESS * GroupTable
EFI_IP6_ADDRESS_INFO * PrefixTable
EFI_IPv6_ADDRESS Destination