20 { 0xFF, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2 }
50 while (Offset < Length) {
51 if (NTOHS (Option->
OpCode) == OptTag) {
55 Offset += (NTOHS (Option->
OpLen) + 4);
89 OptList[Index]->OpCode = HTONS (DHCP6_OPT_ORO);
90 OptList[Index]->OpLen = HTONS (8);
92 OptEnt.Oro->OpCode[0] = HTONS (DHCP6_OPT_BOOT_FILE_URL);
93 OptEnt.Oro->OpCode[1] = HTONS (DHCP6_OPT_BOOT_FILE_PARAM);
94 OptEnt.Oro->OpCode[2] = HTONS (DHCP6_OPT_DNS_SERVERS);
95 OptEnt.Oro->OpCode[3] = HTONS (DHCP6_OPT_VENDOR_CLASS);
97 OptList[Index] = GET_NEXT_DHCP6_OPTION (OptList[Index - 1]);
102 OptList[Index]->OpCode = HTONS (DHCP6_OPT_UNDI);
103 OptList[Index]->OpLen = HTONS ((UINT16)3);
106 if (Private->Nii !=
NULL) {
107 OptEnt.Undi->Type = Private->Nii->Type;
108 OptEnt.Undi->MajorVer = Private->Nii->MajorVer;
109 OptEnt.Undi->MinorVer = Private->Nii->MinorVer;
111 OptEnt.Undi->Type = DEFAULT_UNDI_TYPE;
112 OptEnt.Undi->MajorVer = DEFAULT_UNDI_MAJOR;
113 OptEnt.Undi->MinorVer = DEFAULT_UNDI_MINOR;
117 OptList[Index] = GET_NEXT_DHCP6_OPTION (OptList[Index - 1]);
122 OptList[Index]->OpCode = HTONS (DHCP6_OPT_ARCH);
125 Value = HTONS (EFI_PXE_CLIENT_SYSTEM_ARCHITECTURE);
126 CopyMem (&OptEnt.Arch->Type, &Value, sizeof (UINT16));
128 OptList[Index] = GET_NEXT_DHCP6_OPTION (OptList[Index - 1]);
133 OptList[Index]->OpCode = HTONS (DHCP6_OPT_VENDOR_CLASS);
136 OptEnt.VendorClass->Vendor = HTONL (PXEBC_DHCP6_ENTERPRISE_NUM);
137 OptEnt.VendorClass->ClassLen = HTONS ((UINT16)
sizeof (
PXEBC_CLASS_ID));
139 &OptEnt.VendorClass->ClassId,
140 DEFAULT_CLASS_ID_DATA,
144 EFI_PXE_CLIENT_SYSTEM_ARCHITECTURE,
145 OptEnt.VendorClass->ClassId.ArchitectureType,
146 sizeof (OptEnt.VendorClass->ClassId.ArchitectureType)
149 if (Private->Nii !=
NULL) {
151 OptEnt.VendorClass->ClassId.InterfaceName,
152 Private->Nii->StringId,
153 sizeof (OptEnt.VendorClass->ClassId.InterfaceName)
156 Private->Nii->MajorVer,
157 OptEnt.VendorClass->ClassId.UndiMajor,
158 sizeof (OptEnt.VendorClass->ClassId.UndiMajor)
161 Private->Nii->MinorVer,
162 OptEnt.VendorClass->ClassId.UndiMinor,
163 sizeof (OptEnt.VendorClass->ClassId.UndiMinor)
188 if (Dst->Size < Src->Length) {
189 return EFI_BUFFER_TOO_SMALL;
192 CopyMem (&Dst->Dhcp6, &Src->Dhcp6, Src->Length);
193 Dst->Length = Src->Length;
228 DnsServerList = Private->DnsServer;
237 &gEfiDns6ServiceBindingProtocolGuid,
240 if (EFI_ERROR (Status)) {
244 Status =
gBS->OpenProtocol (
246 &gEfiDns6ProtocolGuid,
250 EFI_OPEN_PROTOCOL_BY_DRIVER
252 if (EFI_ERROR (Status)) {
263 Dns6ConfigData.
Protocol = EFI_IP_PROTO_UDP;
264 IP6_COPY_ADDRESS (&Dns6ConfigData.
StationIp, &Private->TmpStationIp.v6);
265 Status = Dns6->Configure (
269 if (EFI_ERROR (Status)) {
273 Token.
Status = EFI_NOT_READY;
278 Status =
gBS->CreateEvent (
285 if (EFI_ERROR (Status)) {
292 Status = Dns6->HostNameToIp (Dns6, HostName, &Token);
293 if (EFI_ERROR (Status)) {
305 if (!EFI_ERROR (Status)) {
307 Status = EFI_DEVICE_ERROR;
312 Status = EFI_DEVICE_ERROR;
339 Dns6->Configure (Dns6,
NULL);
343 &gEfiDns6ProtocolGuid,
349 if (Dns6Handle !=
NULL) {
353 &gEfiDns6ServiceBindingProtocolGuid,
358 if (DnsServerList !=
NULL) {
382 OUT UINT8 **FileName,
389 CHAR8 *BootFileNamePtr;
391 UINT16 BootFileNameLen;
394 CHAR8 *ServerAddressOption;
395 CHAR8 *ServerAddress;
398 BOOLEAN IpExpressedUrl;
402 IpExpressedUrl =
TRUE;
423 PrefixLen = (UINT16)
AsciiStrLen (PXEBC_DHCP6_BOOT_FILE_URL_PREFIX);
425 if ((Length <= PrefixLen) ||
426 (
CompareMem (BootFile, PXEBC_DHCP6_BOOT_FILE_URL_PREFIX, PrefixLen) != 0))
428 return EFI_NOT_FOUND;
431 BootFile = BootFile + PrefixLen;
432 Length = (UINT16)(Length - PrefixLen);
435 if (TmpStr ==
NULL) {
436 return EFI_OUT_OF_RESOURCES;
439 CopyMem (TmpStr, BootFile, Length);
440 TmpStr[Length] =
'\0';
445 ServerAddressOption = TmpStr;
446 if (*ServerAddressOption == PXEBC_ADDR_START_DELIMITER) {
447 ServerAddressOption++;
448 ServerAddress = ServerAddressOption;
449 while (*ServerAddress !=
'\0' && *ServerAddress != PXEBC_ADDR_END_DELIMITER) {
453 if (*ServerAddress != PXEBC_ADDR_END_DELIMITER) {
455 return EFI_INVALID_PARAMETER;
458 *ServerAddress =
'\0';
464 if (EFI_ERROR (Status)) {
469 IpExpressedUrl =
FALSE;
470 ServerAddress = ServerAddressOption;
471 while (*ServerAddress !=
'\0' && *ServerAddress != PXEBC_TFTP_URL_SEPARATOR) {
475 if (*ServerAddress != PXEBC_TFTP_URL_SEPARATOR) {
477 return EFI_INVALID_PARAMETER;
480 *ServerAddress =
'\0';
484 if (HostName ==
NULL) {
486 return EFI_OUT_OF_RESOURCES;
498 Status =
PxeBcDns6 (Private, HostName, SrvAddr);
499 if (EFI_ERROR (Status)) {
508 BootFileNamePtr = (CHAR8 *)((
UINTN)ServerAddress + 1);
509 if (IpExpressedUrl) {
510 if (*BootFileNamePtr != PXEBC_TFTP_URL_SEPARATOR) {
512 return EFI_INVALID_PARAMETER;
518 BootFileNameLen = (UINT16)(Length - (UINT16)((
UINTN)BootFileNamePtr - (
UINTN)TmpStr) + 1);
519 if ((BootFileNameLen != 0) || (FileName !=
NULL)) {
524 ModeStr =
AsciiStrStr (BootFileNamePtr,
";mode=octet");
525 if ((ModeStr !=
NULL) && (*(ModeStr +
AsciiStrLen (
";mode=octet")) ==
'\0')) {
529 return EFI_INVALID_PARAMETER;
536 if (BootFileName ==
NULL) {
538 return EFI_OUT_OF_RESOURCES;
541 *FileName = (UINT8 *)BootFileName;
546 while (*BootFileNamePtr !=
'\0') {
547 if (*BootFileNamePtr ==
'%') {
548 TmpChar = *(BootFileNamePtr+ 3);
549 *(BootFileNamePtr+ 3) =
'\0';
552 *(BootFileNamePtr+ 3) = TmpChar;
553 BootFileNamePtr += 3;
555 *BootFileName = *BootFileNamePtr;
561 *BootFileName =
'\0';
581 IN CHAR8 *BootFilePara,
582 OUT UINT16 *BootFileSize
590 CopyMem (&Length, BootFilePara,
sizeof (UINT16));
591 Length = NTOHS (Length);
596 if ((Length < 1) || (Length > 5)) {
597 return EFI_NOT_FOUND;
603 BootFilePara = BootFilePara +
sizeof (UINT16);
605 for (Index = 0; Index < Length; Index++) {
607 return EFI_NOT_FOUND;
610 Size = (Size + Digit) * 10;
614 if (Size > PXEBC_DHCP6_MAX_BOOT_FILE_SIZE) {
615 return EFI_NOT_FOUND;
618 *BootFileSize = (UINT16)Size;
639 PXEBC_OFFER_TYPE OfferType;
640 BOOLEAN IsProxyOffer;
644 UINT32 EnterpriseNum;
648 Offer = &Cache6->Packet.Offer;
649 Options = Cache6->OptList;
651 ZeroMem (Cache6->OptList, sizeof (Cache6->OptList));
655 Length = GET_DHCP6_OPTION_SIZE (Offer);
660 while (Offset < Length) {
661 if (NTOHS (Option->
OpCode) == DHCP6_OPT_IA_NA) {
662 Options[PXEBC_DHCP6_IDX_IA_NA] = Option;
663 }
else if (NTOHS (Option->
OpCode) == DHCP6_OPT_BOOT_FILE_URL) {
667 Options[PXEBC_DHCP6_IDX_BOOT_FILE_URL] = Option;
668 }
else if (NTOHS (Option->
OpCode) == DHCP6_OPT_BOOT_FILE_PARAM) {
669 Options[PXEBC_DHCP6_IDX_BOOT_FILE_PARAM] = Option;
670 }
else if (NTOHS (Option->
OpCode) == DHCP6_OPT_VENDOR_CLASS) {
671 Options[PXEBC_DHCP6_IDX_VENDOR_CLASS] = Option;
672 }
else if (NTOHS (Option->
OpCode) == DHCP6_OPT_DNS_SERVERS) {
673 Options[PXEBC_DHCP6_IDX_DNS_SERVER] = Option;
676 Offset += (NTOHS (Option->
OpLen) + 4);
684 Option = Options[PXEBC_DHCP6_IDX_IA_NA];
685 if (Option !=
NULL) {
688 NTOHS (Option->
OpLen),
689 DHCP6_OPT_STATUS_CODE
691 if (((Option !=
NULL) && (Option->
Data[0] == 0)) || (Option ==
NULL)) {
692 IsProxyOffer =
FALSE;
699 Option = Options[PXEBC_DHCP6_IDX_VENDOR_CLASS];
700 EnterpriseNum = HTONL (PXEBC_DHCP6_ENTERPRISE_NUM);
702 if ((Option !=
NULL) &&
703 (NTOHS (Option->
OpLen) >= 13) &&
704 (
CompareMem (Option->
Data, &EnterpriseNum, sizeof (UINT32)) == 0) &&
717 OfferType = IsProxyOffer ? PxeOfferTypeProxyBinl : PxeOfferTypeDhcpBinl;
722 OfferType = PxeOfferTypeDhcpOnly;
725 Cache6->OfferType = OfferType;
751 Mode = Private->PxeBc.Mode;
754 if (EFI_ERROR (Status)) {
763 CopyMem (&Mode->DhcpAck.Dhcpv6, &Ack->Dhcp6, Ack->Length);
764 Mode->DhcpAckReceived =
TRUE;
790 ASSERT (OfferIndex < Private->OfferNum);
791 ASSERT (OfferIndex < PXEBC_OFFER_MAX_NUM);
793 Mode = Private->PxeBc.Mode;
794 Offer = &Private->OfferBuffer[OfferIndex].Dhcp6.Packet.Offer;
800 if (EFI_ERROR (Status)) {
809 CopyMem (&Mode->ProxyOffer.Dhcpv6, &Offer->Dhcp6, Offer->
Length);
810 Mode->ProxyOfferReceived =
TRUE;
841 while (Cursor < Buf + SeekLen) {
843 if (OpCode == HTONS (OptType)) {
849 Cursor += (DataLen + 4);
873 EFI_PXE_BASE_CODE_UDP_PORT SrcPort;
874 EFI_PXE_BASE_CODE_UDP_PORT DestPort;
890 UINTN DiscoverLenNeeded;
892 PxeBc = &Private->PxeBc;
893 Request = Private->Dhcp6Request;
894 IndexOffer = &Private->OfferBuffer[Index].Dhcp6.Packet.Offer;
895 SrcPort = PXEBC_BS_DISCOVER_PORT;
896 DestPort = PXEBC_BS_DISCOVER_PORT;
899 if (Request ==
NULL) {
900 return EFI_DEVICE_ERROR;
905 if (Discover ==
NULL) {
906 return EFI_OUT_OF_RESOURCES;
914 RequestOpt = Request->Dhcp6.
Option;
915 DiscoverOpt = Discover->DhcpOptions;
917 RequestLen = DiscoverLen;
922 if (Private->OfferBuffer[Index].Dhcp6.OfferType == PxeOfferTypeProxyBinl) {
928 if (Option ==
NULL) {
929 Status = EFI_NOT_FOUND;
941 if ((OpLen < PXEBC_MIN_SIZE_OF_DUID) || (OpLen > PXEBC_MAX_SIZE_OF_DUID)) {
942 Status = EFI_INVALID_PARAMETER;
949 if ((DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN) > DiscoverLenNeeded) {
950 Status = EFI_OUT_OF_RESOURCES;
954 CopyMem (DiscoverOpt, Option, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
955 DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
956 DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
959 while (RequestLen < Request->Length) {
964 (OpCode != DHCP6_OPT_SERVER_ID)
970 if (DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN > DiscoverLenNeeded) {
971 Status = EFI_OUT_OF_RESOURCES;
978 CopyMem (DiscoverOpt, RequestOpt, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
979 DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
980 DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
983 RequestOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
984 RequestLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
991 Discover->DhcpOptions,
992 (UINT32)(RequestLen - 4),
993 DHCP6_OPT_ELAPSED_TIME
995 if (Option !=
NULL) {
997 WriteUnaligned16 ((UINT16 *)(Option + 4), HTONS ((UINT16)Private->ElapsedTime));
1000 Status = PxeBc->UdpWrite (
1006 &Private->StationIp,
1014 if (EFI_ERROR (Status)) {
1022 Reply = &Private->ProxyOffer.Dhcp6.Packet.Offer;
1028 Status = Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData);
1029 if (EFI_ERROR (Status)) {
1033 Status = PxeBc->UdpRead (
1035 EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP | EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP,
1043 (VOID *)&Reply->Dhcp6
1048 Private->Udp6Read->Configure (Private->Udp6Read,
NULL);
1050 if (EFI_ERROR (Status)) {
1057 Reply->
Length = (UINT32)ReadSize;
1062 if (Discover !=
NULL) {
1090 ASSERT (Index < PXEBC_OFFER_MAX_NUM);
1092 Private->OfferBuffer[Index].Dhcp6.OfferType == PxeOfferTypeDhcpBinl ||
1093 Private->OfferBuffer[Index].Dhcp6.OfferType == PxeOfferTypeProxyBinl
1096 Mode = Private->PxeBc.Mode;
1097 Private->IsDoDiscover =
FALSE;
1098 Offer = &Private->OfferBuffer[Index].Dhcp6;
1099 if (Offer->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL] ==
NULL) {
1104 &Private->ServerIp.v6,
1105 &mAllDhcpRelayAndServersAddress,
1109 ASSERT (Offer->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL] !=
NULL);
1115 &Private->BootFileName,
1116 &Private->ServerIp.v6,
1117 (CHAR8 *)(Offer->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL]->
Data),
1118 NTOHS (Offer->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL]->
OpLen)
1120 if (EFI_ERROR (Status)) {
1130 if (EFI_ERROR (Status)) {
1134 Cache6 = &Private->ProxyOffer.Dhcp6;
1136 if (EFI_ERROR (Status)) {
1140 if ((Cache6->OfferType != PxeOfferTypeProxyPxe10) &&
1141 (Cache6->OfferType != PxeOfferTypeProxyWfm11a) &&
1142 (Cache6->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL] ==
NULL))
1148 return EFI_DEVICE_ERROR;
1151 Mode->ProxyOfferReceived =
TRUE;
1153 &Mode->ProxyOffer.Dhcpv6,
1154 &Cache6->Packet.Offer.Dhcp6,
1155 Cache6->Packet.Offer.
Length
1178 PXEBC_OFFER_TYPE OfferType;
1181 Cache6 = &Private->OfferBuffer[Private->OfferNum].Dhcp6;
1182 Offer = &Cache6->Packet.Offer;
1188 if (EFI_ERROR (Status)) {
1202 OfferType = Cache6->OfferType;
1203 ASSERT (OfferType < PxeOfferTypeMax);
1204 ASSERT (Private->OfferCount[OfferType] < PXEBC_OFFER_MAX_NUM);
1206 if (IS_PROXY_OFFER (OfferType)) {
1210 Private->IsProxyRecved =
TRUE;
1212 if (OfferType == PxeOfferTypeProxyBinl) {
1216 Private->OfferIndex[OfferType][Private->OfferCount[OfferType]] = Private->OfferNum;
1217 Private->OfferCount[OfferType]++;
1218 }
else if (((OfferType == PxeOfferTypeProxyPxe10) || (OfferType == PxeOfferTypeProxyWfm11a)) &&
1219 (Private->OfferCount[OfferType] < 1))
1224 Private->OfferIndex[OfferType][0] = Private->OfferNum;
1225 Private->OfferCount[OfferType] = 1;
1233 Private->OfferIndex[OfferType][Private->OfferCount[OfferType]] = Private->OfferNum;
1234 Private->OfferCount[OfferType]++;
1237 Private->OfferNum++;
1255 PXEBC_OFFER_TYPE OfferType;
1257 Private->SelectIndex = 0;
1259 if (Private->IsOfferSorted) {
1263 if (Private->OfferCount[PxeOfferTypeDhcpPxe10] > 0) {
1267 Private->SelectIndex = Private->OfferIndex[PxeOfferTypeDhcpPxe10][0] + 1;
1268 }
else if (Private->OfferCount[PxeOfferTypeDhcpWfm11a] > 0) {
1272 Private->SelectIndex = Private->OfferIndex[PxeOfferTypeDhcpWfm11a][0] + 1;
1273 }
else if ((Private->OfferCount[PxeOfferTypeDhcpOnly] > 0) &&
1274 (Private->OfferCount[PxeOfferTypeProxyPxe10] > 0))
1279 Private->SelectIndex = Private->OfferIndex[PxeOfferTypeDhcpOnly][0] + 1;
1280 Private->SelectProxyType = PxeOfferTypeProxyPxe10;
1281 }
else if ((Private->OfferCount[PxeOfferTypeDhcpOnly] > 0) &&
1282 (Private->OfferCount[PxeOfferTypeProxyWfm11a] > 0))
1287 Private->SelectIndex = Private->OfferIndex[PxeOfferTypeDhcpOnly][0] + 1;
1288 Private->SelectProxyType = PxeOfferTypeProxyWfm11a;
1289 }
else if (Private->OfferCount[PxeOfferTypeDhcpBinl] > 0) {
1293 Private->SelectIndex = Private->OfferIndex[PxeOfferTypeDhcpBinl][0] + 1;
1294 }
else if ((Private->OfferCount[PxeOfferTypeDhcpOnly] > 0) &&
1295 (Private->OfferCount[PxeOfferTypeProxyBinl] > 0))
1300 Private->SelectIndex = Private->OfferIndex[PxeOfferTypeDhcpOnly][0] + 1;
1301 Private->SelectProxyType = PxeOfferTypeProxyBinl;
1306 for (Index = 0; Index < Private->OfferCount[PxeOfferTypeDhcpOnly]; Index++) {
1307 OfferIndex = Private->OfferIndex[PxeOfferTypeDhcpOnly][Index];
1308 if (Private->OfferBuffer[OfferIndex].Dhcp6.OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL] !=
NULL) {
1309 Private->SelectIndex = OfferIndex + 1;
1318 for (Index = 0; Index < Private->OfferNum; Index++) {
1319 OfferType = Private->OfferBuffer[Index].Dhcp6.OfferType;
1321 if (IS_PROXY_OFFER (OfferType)) {
1328 if (!Private->IsProxyRecved &&
1329 (OfferType == PxeOfferTypeDhcpOnly) &&
1330 (Private->OfferBuffer[Index].Dhcp6.OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL] ==
NULL))
1338 Private->SelectIndex = Index + 1;
1361 UINT16 DnsServerLen;
1363 DnsServerLen = NTOHS (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen);
1367 if (DnsServerLen == 0) {
1368 return EFI_DEVICE_ERROR;
1375 return EFI_DEVICE_ERROR;
1390 if (Private->DnsServer ==
NULL) {
1391 return EFI_OUT_OF_RESOURCES;
1421 PXEBC_OFFER_TYPE OfferType;
1426 ASSERT (Private !=
NULL);
1427 ASSERT (Private->SelectIndex > 0);
1428 SelectIndex = (UINT32)(Private->SelectIndex - 1);
1429 ASSERT (SelectIndex < PXEBC_OFFER_MAX_NUM);
1430 Cache6 = &Private->OfferBuffer[SelectIndex].Dhcp6;
1436 if (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] !=
NULL) {
1438 if (EFI_ERROR (Status)) {
1443 if (Cache6->OfferType == PxeOfferTypeDhcpBinl) {
1448 Status = EFI_NO_RESPONSE;
1450 }
else if (Cache6->OfferType == PxeOfferTypeDhcpOnly) {
1451 if (Private->IsProxyRecved) {
1456 if (Private->IsOfferSorted) {
1461 ASSERT (Private->OfferCount[Private->SelectProxyType] > 0);
1463 if (Private->SelectProxyType == PxeOfferTypeProxyBinl) {
1467 for (Index = 0; Index < Private->OfferCount[Private->SelectProxyType]; Index++) {
1468 ProxyIndex = Private->OfferIndex[Private->SelectProxyType][Index];
1474 if (Index == Private->OfferCount[Private->SelectProxyType]) {
1475 Status = EFI_NO_RESPONSE;
1481 ProxyIndex = Private->OfferIndex[Private->SelectProxyType][0];
1487 Status = EFI_NO_RESPONSE;
1489 for (Index = 0; Index < Private->OfferNum; Index++) {
1490 OfferType = Private->OfferBuffer[Index].Dhcp6.OfferType;
1492 if (!IS_PROXY_OFFER (OfferType)) {
1499 if (OfferType == PxeOfferTypeProxyBinl) {
1508 Private->SelectProxyType = OfferType;
1515 if (!EFI_ERROR (Status) && (Private->SelectProxyType != PxeOfferTypeProxyBinl)) {
1525 ASSERT (Cache6->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL] !=
NULL);
1529 if (!EFI_ERROR (Status)) {
1534 Private->PxeBc.Mode->DhcpDiscoverValid =
TRUE;
1551 if (Private->Ip6Policy != PXEBC_IP6_POLICY_MAX) {
1587 BOOLEAN GatewayIsFound;
1589 ASSERT (GatewayAddr !=
NULL);
1590 ASSERT (Private !=
NULL);
1593 GatewayIsFound =
FALSE;
1599 Status = Ip6->GetModeData (Ip6, &Ip6ModeData,
NULL,
NULL);
1600 if (EFI_ERROR (Status)) {
1607 for (Index = 0; Index < Ip6ModeData.
RouteCount; Index++) {
1610 GatewayIsFound =
TRUE;
1639 if (GatewayIsFound || (RetryCount == TimeOutInSecond)) {
1648 if (TimeOutEvt ==
NULL) {
1649 Status =
gBS->CreateEvent (
1656 if (EFI_ERROR (Status)) {
1662 if (EFI_ERROR (Status)) {
1666 while (EFI_ERROR (
gBS->CheckEvent (TimeOutEvt))) {
1672 if (TimeOutEvt !=
NULL) {
1673 gBS->CloseEvent (TimeOutEvt);
1676 if (GatewayIsFound) {
1678 }
else if (RetryCount == TimeOutInSecond) {
1679 Status = EFI_TIMEOUT;
1717 Ip6Cfg = Private->Ip6Cfg;
1724 Status = Ip6->Configure (Ip6, &Private->Ip6CfgData);
1725 if (EFI_ERROR (Status)) {
1733 if (EFI_ERROR (Status)) {
1742 Status = Ip6Cfg->SetData (
1748 if (EFI_ERROR (Status)) {
1752 Private->Ip6Policy = PXEBC_IP6_POLICY_MAX;
1759 Status =
gBS->CreateEvent (
1763 &Private->IsAddressOk,
1766 if (EFI_ERROR (Status)) {
1770 Private->IsAddressOk =
FALSE;
1771 Status = Ip6Cfg->RegisterDataNotify (
1776 if (EFI_ERROR (Status)) {
1780 Status = Ip6Cfg->SetData (
1786 if (EFI_ERROR (Status) && (Status != EFI_NOT_READY)) {
1788 }
else if (Status == EFI_NOT_READY) {
1792 while (!Private->IsAddressOk) {
1800 Status = Ip6Cfg->GetData (
1806 if ((Status != EFI_BUFFER_TOO_SMALL) || (DataSize == 0)) {
1807 Status = EFI_DEVICE_ERROR;
1812 if (Ip6Addr ==
NULL) {
1813 return EFI_OUT_OF_RESOURCES;
1816 Status = Ip6Cfg->GetData (
1822 if (EFI_ERROR (Status)) {
1823 Status = EFI_DEVICE_ERROR;
1834 Status = EFI_ABORTED;
1843 Status = Ip6Cfg->SetData (
1849 if (EFI_ERROR (Status)) {
1855 if (MappedEvt !=
NULL) {
1856 Ip6Cfg->UnregisterDataNotify (
1861 gBS->CloseEvent (MappedEvt);
1864 if (Ip6Addr !=
NULL) {
1890 Ip6Cfg = Private->Ip6Cfg;
1896 Status = Ip6Cfg->GetData (
1902 if (EFI_ERROR (Status)) {
1908 Status = Ip6Cfg->SetData (
1914 if (EFI_ERROR (Status)) {
1918 Private->Ip6Policy = PXEBC_IP6_POLICY_MAX;
1942 Dhcp6 = Private->Dhcp6;
1948 if (EFI_ERROR (Status)) {
1949 Dhcp6->Stop (Dhcp6);
1954 if (EFI_ERROR (Status)) {
1956 Dhcp6->Stop (Dhcp6);
2011 ASSERT (Packet !=
NULL);
2014 Mode = Private->PxeBc.
Mode;
2015 Callback = Private->PxeBcCallback;
2022 Status = Callback->Callback (
2029 if (Status != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {
2036 switch (Dhcp6Event) {
2038 if (Packet->Length > PXEBC_DHCP6_PACKET_MAX_SIZE) {
2042 Status = EFI_ABORTED;
2049 if (Private->SolicitTimes == 0) {
2051 Private->SolicitTimes++;
2057 CopyMem (&Mode->DhcpDiscover.Dhcpv4, &Packet->Dhcp6, Packet->Length);
2061 Status = EFI_NOT_READY;
2062 if (Packet->Length > PXEBC_DHCP6_PACKET_MAX_SIZE) {
2069 if (Private->OfferNum < PXEBC_OFFER_MAX_NUM) {
2080 if (Packet->Length > PXEBC_DHCP6_PACKET_MAX_SIZE) {
2084 Status = EFI_ABORTED;
2091 if (Private->Dhcp6Request !=
NULL) {
2096 if (Private->Dhcp6Request !=
NULL) {
2097 CopyMem (Private->Dhcp6Request, Packet, Packet->
Size);
2109 if (Private->SelectIndex == 0) {
2110 Status = EFI_ABORTED;
2112 ASSERT (NewPacket !=
NULL);
2113 SelectAd = &Private->OfferBuffer[Private->SelectIndex - 1].Dhcp6.Packet.Offer;
2115 ASSERT (*NewPacket !=
NULL);
2116 if (*NewPacket ==
NULL) {
2130 ASSERT (Private->SelectIndex != 0);
2132 if (EFI_ERROR (Status)) {
2133 Status = EFI_ABORTED;
2169 EFI_PXE_BASE_CODE_UDP_PORT SrcPort;
2170 EFI_PXE_BASE_CODE_UDP_PORT DestPort;
2185 UINTN DiscoverLenNeeded;
2187 PxeBc = &Private->PxeBc;
2189 Request = Private->Dhcp6Request;
2190 SrcPort = PXEBC_BS_DISCOVER_PORT;
2191 DestPort = PXEBC_BS_DISCOVER_PORT;
2193 if (!UseBis && (Layer !=
NULL)) {
2194 *Layer &= EFI_PXE_BASE_CODE_BOOT_LAYER_MASK;
2197 if (Request ==
NULL) {
2198 return EFI_DEVICE_ERROR;
2202 if (EFI_ERROR (Status)) {
2203 DEBUG ((DEBUG_ERROR,
"%a failed to generate random number: %r\n", __func__, Status));
2209 if (Discover ==
NULL) {
2210 return EFI_OUT_OF_RESOURCES;
2216 Discover->TransactionId = HTONL (Random);
2218 RequestOpt = Request->Dhcp6.
Option;
2219 DiscoverOpt = Discover->DhcpOptions;
2221 RequestLen = DiscoverLen;
2233 while (RequestLen < Request->Length) {
2239 if (DiscoverLen + OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN > DiscoverLenNeeded) {
2240 Status = EFI_OUT_OF_RESOURCES;
2247 CopyMem (DiscoverOpt, RequestOpt, OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
2248 DiscoverOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
2249 DiscoverLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
2252 RequestOpt += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
2253 RequestLen += (OpLen + PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN);
2256 Status = PxeBc->UdpWrite (
2262 &Private->StationIp,
2269 if (EFI_ERROR (Status)) {
2277 if (Private->IsDoDiscover) {
2278 CopyMem (&Mode->PxeDiscover.Dhcpv6, Discover, DiscoverLen);
2279 Reply = &Private->PxeReply.Dhcp6.Packet.Ack;
2281 Reply = &Private->ProxyOffer.Dhcp6.Packet.Offer;
2289 Status = Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData);
2290 if (EFI_ERROR (Status)) {
2294 Status = PxeBc->UdpRead (
2296 EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP,
2304 (VOID *)&Reply->Dhcp6
2309 Private->Udp6Read->Configure (Private->Udp6Read,
NULL);
2310 if (EFI_ERROR (Status)) {
2317 if (Discover !=
NULL) {
2345 UINT8 Buffer[PXEBC_DHCP6_OPTION_MAX_SIZE];
2351 UINT64 GetMappingTimeOut;
2356 PxeMode = Private->PxeBc.Mode;
2357 Ip6Cfg = Private->Ip6Cfg;
2364 ASSERT (OptCount > 0);
2367 if (Retransmit ==
NULL) {
2368 return EFI_OUT_OF_RESOURCES;
2384 Retransmit->
Irt = 4;
2385 Retransmit->
Mrc = 4;
2386 Retransmit->
Mrt = 32;
2387 Retransmit->
Mrd = 60;
2392 Status = Dhcp6->Configure (Dhcp6, &Config);
2394 if (EFI_ERROR (Status)) {
2401 Private->IsProxyRecved =
FALSE;
2402 Private->OfferNum = 0;
2403 Private->SelectIndex = 0;
2404 ZeroMem (Private->OfferCount, sizeof (Private->OfferCount));
2405 ZeroMem (Private->OfferIndex, sizeof (Private->OfferIndex));
2410 Status = Dhcp6->Start (Dhcp6);
2411 if (Status == EFI_NO_MAPPING) {
2416 Dhcp6->Stop (Dhcp6);
2422 Status = Ip6Cfg->GetData (
2428 if (EFI_ERROR (Status)) {
2429 Dhcp6->Configure (Dhcp6,
NULL);
2433 Status =
gBS->CreateEvent (EVT_TIMER, TPL_CALLBACK,
NULL,
NULL, &Timer);
2434 if (EFI_ERROR (Status)) {
2435 Dhcp6->Configure (Dhcp6,
NULL);
2441 if (EFI_ERROR (Status)) {
2442 gBS->CloseEvent (Timer);
2443 Dhcp6->Configure (Dhcp6,
NULL);
2448 TimerStatus =
gBS->CheckEvent (Timer);
2449 if (!EFI_ERROR (TimerStatus)) {
2450 Status = Dhcp6->Start (Dhcp6);
2452 }
while (TimerStatus == EFI_NOT_READY);
2454 gBS->CloseEvent (Timer);
2457 if (EFI_ERROR (Status)) {
2458 if (Status == EFI_ICMP_ERROR) {
2459 PxeMode->IcmpErrorReceived =
TRUE;
2462 Dhcp6->Configure (Dhcp6,
NULL);
2469 Status = Dhcp6->GetModeData (Dhcp6, &Mode,
NULL);
2470 if (EFI_ERROR (Status)) {
2471 Dhcp6->Stop (Dhcp6);
2496 if (EFI_ERROR (Status)) {
2497 Dhcp6->Stop (Dhcp6);
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
UINT16 EFIAPI ReadUnaligned16(IN CONST UINT16 *Buffer)
UINTN EFIAPI AsciiStrHexToUintn(IN CONST CHAR8 *String)
UINT16 EFIAPI WriteUnaligned16(OUT UINT16 *Buffer, IN UINT16 Value)
RETURN_STATUS EFIAPI AsciiStrToUnicodeStrS(IN CONST CHAR8 *Source, OUT CHAR16 *Destination, IN UINTN DestMax)
UINTN EFIAPI AsciiStrSize(IN CONST CHAR8 *String)
CHAR8 *EFIAPI AsciiStrStr(IN CONST CHAR8 *String, IN CONST CHAR8 *SearchString)
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
#define EFI_DHCP6_IA_TYPE_TA
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
@ Ip6ConfigDataTypeDupAddrDetectTransmits
@ Ip6ConfigDataTypeGateway
@ Ip6ConfigDataTypeManualAddress
@ Ip6ConfigDataTypePolicy
@ Ip6ConfigPolicyAutomatic
#define DEBUG(Expression)
EFI_STATUS EFIAPI NetLibCreateServiceChild(IN EFI_HANDLE Controller, IN EFI_HANDLE Image, IN EFI_GUID *ServiceBindingGuid, IN OUT EFI_HANDLE *ChildHandle)
BOOLEAN EFIAPI NetIp6IsNetEqual(EFI_IPv6_ADDRESS *Ip1, EFI_IPv6_ADDRESS *Ip2, UINT8 PrefixLength)
EFI_STATUS EFIAPI NetLibDestroyServiceChild(IN EFI_HANDLE Controller, IN EFI_HANDLE Image, IN EFI_GUID *ServiceBindingGuid, IN EFI_HANDLE ChildHandle)
BOOLEAN EFIAPI NetIp6IsUnspecifiedAddr(IN EFI_IPv6_ADDRESS *Ip6)
EFI_STATUS EFIAPI NetLibAsciiStrToIp6(IN CONST CHAR8 *String, OUT EFI_IPv6_ADDRESS *Ip6Address)
EFI_STATUS EFIAPI PseudoRandomU32(OUT UINT32 *Output)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_STATUS PxeBcRegisterIp6Address(IN PXEBC_PRIVATE_DATA *Private, IN EFI_IPv6_ADDRESS *Address)
EFI_STATUS PxeBcSetIp6Address(IN PXEBC_PRIVATE_DATA *Private)
VOID PxeBcUnregisterIp6Address(IN PXEBC_PRIVATE_DATA *Private)
EFI_STATUS PxeBcCopyDhcp6Ack(IN PXEBC_PRIVATE_DATA *Private, IN EFI_DHCP6_PACKET *Ack, IN BOOLEAN Verified)
EFI_STATUS PxeBcCacheDnsServerAddresses(IN PXEBC_PRIVATE_DATA *Private, IN PXEBC_DHCP6_PACKET_CACHE *Cache6)
EFI_STATUS PxeBcSetIp6Policy(IN PXEBC_PRIVATE_DATA *Private)
UINT8 * PxeBcDhcp6SeekOption(IN UINT8 *Buf, IN UINT32 SeekLen, IN UINT16 OptType)
EFI_STATUS PxeBcCacheDhcp6Offer(IN PXEBC_PRIVATE_DATA *Private, IN EFI_DHCP6_PACKET *RcvdOffer)
EFI_STATUS EFIAPI PxeBcDhcp6CallBack(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 PxeBcParseDhcp6Packet(IN PXEBC_DHCP6_PACKET_CACHE *Cache6)
UINT32 PxeBcBuildDhcp6Options(IN PXEBC_PRIVATE_DATA *Private, OUT EFI_DHCP6_PACKET_OPTION **OptList, IN UINT8 *Buffer)
EFI_STATUS PxeBcHandleDhcp6Offer(IN PXEBC_PRIVATE_DATA *Private)
EFI_STATUS PxeBcCacheDhcp6Packet(IN EFI_DHCP6_PACKET *Dst, IN EFI_DHCP6_PACKET *Src)
VOID PxeBcSelectDhcp6Offer(IN PXEBC_PRIVATE_DATA *Private)
EFI_DHCP6_PACKET_OPTION * PxeBcParseDhcp6Options(IN UINT8 *Buffer, IN UINT32 Length, IN UINT16 OptTag)
EFI_STATUS PxeBcExtractBootFileUrl(IN PXEBC_PRIVATE_DATA *Private, OUT UINT8 **FileName, IN OUT EFI_IPv6_ADDRESS *SrvAddr, IN CHAR8 *BootFile, IN UINT16 Length)
EFI_STATUS PxeBcRetryDhcp6Binl(IN PXEBC_PRIVATE_DATA *Private, IN UINT32 Index)
EFI_STATUS PxeBcCheckRouteTable(IN PXEBC_PRIVATE_DATA *Private, IN UINTN TimeOutInSecond, OUT EFI_IPv6_ADDRESS *GatewayAddr)
EFI_STATUS PxeBcDhcp6Sarr(IN PXEBC_PRIVATE_DATA *Private, IN EFI_DHCP6_PROTOCOL *Dhcp6)
EFI_STATUS PxeBcRequestBootService(IN PXEBC_PRIVATE_DATA *Private, IN UINT32 Index)
EFI_STATUS PxeBcCopyDhcp6Proxy(IN PXEBC_PRIVATE_DATA *Private, IN UINT32 OfferIndex)
EFI_STATUS PxeBcExtractBootFileParam(IN CHAR8 *BootFilePara, OUT UINT16 *BootFileSize)
EFI_STATUS PxeBcDhcp6Discover(IN PXEBC_PRIVATE_DATA *Private, IN UINT16 Type, IN UINT16 *Layer, IN BOOLEAN UseBis, IN EFI_IP_ADDRESS *DestIp)
EFI_STATUS PxeBcDns6(IN PXEBC_PRIVATE_DATA *Private, IN CHAR16 *HostName, OUT EFI_IPv6_ADDRESS *IpAddress)
VOID PxeBcShowIp6Addr(IN EFI_IPv6_ADDRESS *Ip)
VOID CalcElapsedTime(IN PXEBC_PRIVATE_DATA *Private)
EFI_STATUS PxeBcUniHexToUint8(OUT UINT8 *Digit, IN CHAR16 Char)
EFI_STATUS PxeBcFlushStationIp(PXEBC_PRIVATE_DATA *Private, EFI_IP_ADDRESS *StationIp OPTIONAL, EFI_IP_ADDRESS *SubnetMask OPTIONAL)
VOID PxeBcUintnToAscDecWithFormat(IN UINTN Number, IN UINT8 *Buffer, IN INTN Length)
VOID EFIAPI PxeBcCommonNotify(IN EFI_EVENT Event, IN VOID *Context)
VOID EFIAPI Exit(IN EFI_STATUS Status)
IPv6_ADDRESS EFI_IPv6_ADDRESS
UINTN EFIAPI AsciiPrint(IN CONST CHAR8 *Format,...)
EFI_PXE_BASE_CODE_MODE * Mode
EFI_IPv6_ADDRESS * IpList
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
DNS6_HOST_TO_ADDR_DATA * H2AData
union EFI_DNS6_COMPLETION_TOKEN::@574 RspData
EFI_IPv6_ADDRESS * DnsServerList
EFI_IPv6_ADDRESS StationIp
UINT32 DupAddrDetectTransmits
The number of consecutive Neighbor Solicitation messages sent.
EFI_IPv6_ADDRESS Address
The IPv6 unicast address.
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