/** @file\r
iSCSI DHCP6 related configuration routines.\r
\r
-Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include "IScsiImpl.h"\r
\r
-\r
/**\r
Extract the Root Path option and get the required target information from\r
Boot File Uniform Resource Locator (URL) Option.\r
IScsiDhcp6ExtractRootPath (\r
IN CHAR8 *RootPath,\r
IN UINT16 Length,\r
- IN OUT ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData\r
+ IN OUT ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData\r
)\r
{\r
- EFI_STATUS Status;\r
- UINT16 IScsiRootPathIdLen;\r
- CHAR8 *TmpStr;\r
- ISCSI_ROOT_PATH_FIELD Fields[RP_FIELD_IDX_MAX];\r
- ISCSI_ROOT_PATH_FIELD *Field;\r
- UINT32 FieldIndex;\r
- UINT8 Index;\r
- ISCSI_SESSION_CONFIG_NVDATA *ConfigNvData;\r
- EFI_IP_ADDRESS Ip;\r
- UINT8 IpMode; \r
-\r
- ConfigNvData = &ConfigData->SessionConfigData;\r
-\r
+ EFI_STATUS Status;\r
+ UINT16 IScsiRootPathIdLen;\r
+ CHAR8 *TmpStr;\r
+ ISCSI_ROOT_PATH_FIELD Fields[RP_FIELD_IDX_MAX];\r
+ ISCSI_ROOT_PATH_FIELD *Field;\r
+ UINT32 FieldIndex;\r
+ UINT8 Index;\r
+ ISCSI_SESSION_CONFIG_NVDATA *ConfigNvData;\r
+ EFI_IP_ADDRESS Ip;\r
+ UINT8 IpMode;\r
+\r
+ ConfigNvData = &ConfigData->SessionConfigData;\r
+ ConfigNvData->DnsMode = FALSE;\r
//\r
// "iscsi:"<servername>":"<protocol>":"<port>":"<LUN>":"<targetname>\r
//\r
- IScsiRootPathIdLen = (UINT16) AsciiStrLen (ISCSI_ROOT_PATH_ID);\r
+ IScsiRootPathIdLen = (UINT16)AsciiStrLen (ISCSI_ROOT_PATH_ID);\r
\r
if ((Length <= IScsiRootPathIdLen) ||\r
- (CompareMem (RootPath, ISCSI_ROOT_PATH_ID, IScsiRootPathIdLen) != 0)) {\r
+ (CompareMem (RootPath, ISCSI_ROOT_PATH_ID, IScsiRootPathIdLen) != 0))\r
+ {\r
return EFI_NOT_FOUND;\r
}\r
+\r
//\r
// Skip the iSCSI RootPath ID "iscsi:".\r
//\r
RootPath = RootPath + IScsiRootPathIdLen;\r
- Length = (UINT16) (Length - IScsiRootPathIdLen);\r
+ Length = (UINT16)(Length - IScsiRootPathIdLen);\r
\r
- TmpStr = (CHAR8 *) AllocatePool (Length + 1);\r
+ TmpStr = (CHAR8 *)AllocatePool (Length + 1);\r
if (TmpStr == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
CopyMem (TmpStr, RootPath, Length);\r
- TmpStr[Length] = '\0';\r
+ TmpStr[Length] = '\0';\r
\r
- Index = 0;\r
- FieldIndex = 0;\r
+ Index = 0;\r
+ FieldIndex = 0;\r
ZeroMem (&Fields[0], sizeof (Fields));\r
\r
//\r
// Extract SERVERNAME field in the Root Path option.\r
//\r
if (TmpStr[Index] != ISCSI_ROOT_PATH_ADDR_START_DELIMITER) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto ON_EXIT;\r
+ //\r
+ // The servername is expressed as domain name.\r
+ //\r
+ ConfigNvData->DnsMode = TRUE;\r
} else {\r
Index++;\r
}\r
\r
Fields[RP_FIELD_IDX_SERVERNAME].Str = &TmpStr[Index];\r
\r
- while ((TmpStr[Index] != ISCSI_ROOT_PATH_ADDR_END_DELIMITER) && (Index < Length)) {\r
- Index++;\r
- }\r
+ if (!ConfigNvData->DnsMode) {\r
+ while ((TmpStr[Index] != ISCSI_ROOT_PATH_ADDR_END_DELIMITER) && (Index < Length)) {\r
+ Index++;\r
+ }\r
\r
- //\r
- // Skip ']' and ':'.\r
- //\r
- TmpStr[Index] = '\0';\r
- Index += 2;\r
+ //\r
+ // Skip ']' and ':'.\r
+ //\r
+ TmpStr[Index] = '\0';\r
+ Index += 2;\r
+ } else {\r
+ while ((TmpStr[Index] != ISCSI_ROOT_PATH_FIELD_DELIMITER) && (Index < Length)) {\r
+ Index++;\r
+ }\r
\r
- Fields[RP_FIELD_IDX_SERVERNAME].Len = (UINT8) AsciiStrLen (Fields[RP_FIELD_IDX_SERVERNAME].Str);\r
+ //\r
+ // Skip ':'.\r
+ //\r
+ TmpStr[Index] = '\0';\r
+ Index += 1;\r
+ }\r
+\r
+ Fields[RP_FIELD_IDX_SERVERNAME].Len = (UINT8)AsciiStrLen (Fields[RP_FIELD_IDX_SERVERNAME].Str);\r
\r
//\r
// Extract others fields in the Root Path option string.\r
//\r
for (FieldIndex = 1; (FieldIndex < RP_FIELD_IDX_MAX) && (Index < Length); FieldIndex++) {\r
-\r
if (TmpStr[Index] != ISCSI_ROOT_PATH_FIELD_DELIMITER) {\r
Fields[FieldIndex].Str = &TmpStr[Index];\r
}\r
}\r
\r
if (Fields[FieldIndex].Str != NULL) {\r
- Fields[FieldIndex].Len = (UINT8) AsciiStrLen (Fields[FieldIndex].Str);\r
+ Fields[FieldIndex].Len = (UINT8)AsciiStrLen (Fields[FieldIndex].Str);\r
}\r
}\r
}\r
if ((Fields[RP_FIELD_IDX_SERVERNAME].Str == NULL) ||\r
(Fields[RP_FIELD_IDX_TARGETNAME].Str == NULL) ||\r
(Fields[RP_FIELD_IDX_PROTOCOL].Len > 1)\r
- ) {\r
-\r
+ )\r
+ {\r
Status = EFI_INVALID_PARAMETER;\r
goto ON_EXIT;\r
}\r
+\r
//\r
// Get the IP address of the target.\r
//\r
- Field = &Fields[RP_FIELD_IDX_SERVERNAME]; \r
+ Field = &Fields[RP_FIELD_IDX_SERVERNAME];\r
if (ConfigNvData->IpMode < IP_MODE_AUTOCONFIG) {\r
IpMode = ConfigNvData->IpMode;\r
} else {\r
IpMode = ConfigData->AutoConfigureMode;\r
}\r
\r
- Status = IScsiAsciiStrToIp (Field->Str, IpMode, &Ip);\r
- CopyMem (&ConfigNvData->TargetIp, &Ip, sizeof (EFI_IP_ADDRESS));\r
+ //\r
+ // Server name is expressed as domain name, just save it.\r
+ //\r
+ if (ConfigNvData->DnsMode) {\r
+ if ((Field->Len + 2) > sizeof (ConfigNvData->TargetUrl)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
\r
+ CopyMem (&ConfigNvData->TargetUrl, Field->Str, Field->Len);\r
+ ConfigNvData->TargetUrl[Field->Len + 1] = '\0';\r
+ } else {\r
+ ZeroMem (&ConfigNvData->TargetUrl, sizeof (ConfigNvData->TargetUrl));\r
+ Status = IScsiAsciiStrToIp (Field->Str, IpMode, &Ip);\r
+ CopyMem (&ConfigNvData->TargetIp, &Ip, sizeof (EFI_IP_ADDRESS));\r
\r
- if (EFI_ERROR (Status)) {\r
- goto ON_EXIT;\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
}\r
+\r
//\r
// Check the protocol type.\r
//\r
Status = EFI_INVALID_PARAMETER;\r
goto ON_EXIT;\r
}\r
+\r
//\r
// Get the port of the iSCSI target.\r
//\r
Field = &Fields[RP_FIELD_IDX_PORT];\r
if (Field->Str != NULL) {\r
- ConfigNvData->TargetPort = (UINT16) AsciiStrDecimalToUintn (Field->Str);\r
+ ConfigNvData->TargetPort = (UINT16)AsciiStrDecimalToUintn (Field->Str);\r
} else {\r
ConfigNvData->TargetPort = ISCSI_WELL_KNOWN_PORT;\r
}\r
+\r
//\r
// Get the LUN.\r
//\r
} else {\r
ZeroMem (ConfigNvData->BootLun, sizeof (ConfigNvData->BootLun));\r
}\r
+\r
//\r
// Get the target iSCSI Name.\r
//\r
Status = EFI_INVALID_PARAMETER;\r
goto ON_EXIT;\r
}\r
+\r
//\r
// Validate the iSCSI name.\r
//\r
}\r
\r
/**\r
- EFI_DHCP6_INFO_CALLBACK is provided by the consumer of the EFI DHCPv6 Protocol \r
+ EFI_DHCP6_INFO_CALLBACK is provided by the consumer of the EFI DHCPv6 Protocol\r
instance to intercept events that occurs in the DHCPv6 Information Request\r
exchange process.\r
\r
- @param[in] This Pointer to the EFI_DHCP6_PROTOCOL instance that \r
+ @param[in] This Pointer to the EFI_DHCP6_PROTOCOL instance that\r
is used to configure this callback function.\r
@param[in] Context Pointer to the context that is initialized in\r
the EFI_DHCP6_PROTOCOL.InfoRequest().\r
EFI_STATUS\r
EFIAPI\r
IScsiDhcp6ParseReply (\r
- IN EFI_DHCP6_PROTOCOL *This,\r
- IN VOID *Context,\r
- IN EFI_DHCP6_PACKET *Packet\r
+ IN EFI_DHCP6_PROTOCOL *This,\r
+ IN VOID *Context,\r
+ IN EFI_DHCP6_PACKET *Packet\r
)\r
{\r
- EFI_STATUS Status;\r
- UINT32 Index;\r
- UINT32 OptionCount;\r
- EFI_DHCP6_PACKET_OPTION *BootFileOpt;\r
- EFI_DHCP6_PACKET_OPTION **OptionList;\r
- ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData;\r
- UINT16 ParaLen;\r
- \r
+ EFI_STATUS Status;\r
+ UINT32 Index;\r
+ UINT32 OptionCount;\r
+ EFI_DHCP6_PACKET_OPTION *BootFileOpt;\r
+ EFI_DHCP6_PACKET_OPTION **OptionList;\r
+ ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData;\r
+ UINT16 ParaLen;\r
+\r
OptionCount = 0;\r
BootFileOpt = NULL;\r
- \r
- Status = This->Parse (This, Packet, &OptionCount, NULL);\r
+\r
+ Status = This->Parse (This, Packet, &OptionCount, NULL);\r
if (Status != EFI_BUFFER_TOO_SMALL) {\r
return EFI_NOT_READY;\r
}\r
goto Exit;\r
}\r
\r
- ConfigData = (ISCSI_ATTEMPT_CONFIG_NVDATA *) Context;\r
+ ConfigData = (ISCSI_ATTEMPT_CONFIG_NVDATA *)Context;\r
\r
for (Index = 0; Index < OptionCount; Index++) {\r
OptionList[Index]->OpCode = NTOHS (OptionList[Index]->OpCode);\r
// Get DNS server addresses from this reply packet.\r
//\r
if (OptionList[Index]->OpCode == DHCP6_OPT_DNS_SERVERS) {\r
-\r
if (((OptionList[Index]->OpLen & 0xf) != 0) || (OptionList[Index]->OpLen == 0)) {\r
Status = EFI_UNSUPPORTED;\r
goto Exit;\r
}\r
+\r
//\r
// Primary DNS server address.\r
//\r
//\r
CopyMem (&ConfigData->SecondaryDns, &OptionList[Index]->Data[16], sizeof (EFI_IPv6_ADDRESS));\r
}\r
-\r
} else if (OptionList[Index]->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
Status = EFI_UNSUPPORTED;\r
goto Exit;\r
}\r
+\r
//\r
// Check param-len 1, should be 16 bytes.\r
//\r
Status = EFI_UNSUPPORTED;\r
goto Exit;\r
}\r
- \r
+\r
//\r
// Get iSCSI root path from Boot File Uniform Resource Locator (URL) Option\r
//\r
Status = IScsiDhcp6ExtractRootPath (\r
- (CHAR8 *) BootFileOpt->Data,\r
+ (CHAR8 *)BootFileOpt->Data,\r
BootFileOpt->OpLen,\r
ConfigData\r
);\r
return Status;\r
}\r
\r
-\r
/**\r
Parse the DHCP ACK to get the address configuration and DNS information.\r
\r
**/\r
EFI_STATUS\r
IScsiDoDhcp6 (\r
- IN EFI_HANDLE Image,\r
- IN EFI_HANDLE Controller,\r
- IN OUT ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData\r
+ IN EFI_HANDLE Image,\r
+ IN EFI_HANDLE Controller,\r
+ IN OUT ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData\r
)\r
{\r
EFI_HANDLE Dhcp6Handle;\r
EFI_DHCP6_PACKET_OPTION *Oro;\r
EFI_DHCP6_RETRANSMISSION InfoReqReXmit;\r
EFI_EVENT Timer;\r
- BOOLEAN MediaPresent;\r
+ EFI_STATUS MediaStatus;\r
\r
//\r
// Check media status before doing DHCP.\r
//\r
- MediaPresent = TRUE;\r
- NetLibDetectMedia (Controller, &MediaPresent);\r
- if (!MediaPresent) {\r
+ MediaStatus = EFI_SUCCESS;\r
+ NetLibDetectMediaWaitTimeout (Controller, ISCSI_CHECK_MEDIA_GET_DHCP_WAITING_TIME, &MediaStatus);\r
+ if (MediaStatus != EFI_SUCCESS) {\r
+ AsciiPrint ("\n Error: Could not detect network connection.\n");\r
return EFI_NO_MEDIA;\r
}\r
\r
Status = gBS->OpenProtocol (\r
Dhcp6Handle,\r
&gEfiDhcp6ProtocolGuid,\r
- (VOID **) &Dhcp6,\r
+ (VOID **)&Dhcp6,\r
Image,\r
Controller,\r
EFI_OPEN_PROTOCOL_BY_DRIVER\r
}\r
\r
do {\r
-\r
TimerStatus = gBS->CheckEvent (Timer);\r
\r
if (!EFI_ERROR (TimerStatus)) {\r
ConfigData\r
);\r
}\r
-\r
} while (TimerStatus == EFI_NOT_READY);\r
-\r
}\r
\r
ON_EXIT:\r
\r
if (Oro != NULL) {\r
FreePool (Oro);\r
- } \r
+ }\r
\r
if (Timer != NULL) {\r
gBS->CloseEvent (Timer);\r
\r
return Status;\r
}\r
-\r