]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/IScsiDxe/IScsiDhcp6.c
CryptoPkg/BaseCryptLib: Make HMAC_CTX size backward compatible
[mirror_edk2.git] / NetworkPkg / IScsiDxe / IScsiDhcp6.c
index 2bf102ba8b88705f5c274976f066b754e788a447..86a872adeccc89edbde78e5a41ac46d4e68582c5 100644 (file)
@@ -1,14 +1,8 @@
 /** @file\r
   iSCSI DHCP6 related configuration routines.\r
 \r
-Copyright (c) 2009 - 2011, 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
@@ -47,10 +41,10 @@ IScsiDhcp6ExtractRootPath (
   UINT8                       Index;\r
   ISCSI_SESSION_CONFIG_NVDATA *ConfigNvData;\r
   EFI_IP_ADDRESS              Ip;\r
-  UINT8                       IpMode;  \r
+  UINT8                       IpMode;\r
 \r
   ConfigNvData = &ConfigData->SessionConfigData;\r
-\r
+  ConfigNvData->DnsMode = FALSE;\r
   //\r
   // "iscsi:"<servername>":"<protocol>":"<port>":"<LUN>":"<targetname>\r
   //\r
@@ -82,23 +76,36 @@ IScsiDhcp6ExtractRootPath (
   // 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
+    // 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
@@ -143,20 +150,32 @@ IScsiDhcp6ExtractRootPath (
   //\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
+  //\r
+  // Server name is expressed as domain name, just save it.\r
+  //\r
+  if (ConfigNvData->DnsMode) {\r
+    if (Field->Len > sizeof (ConfigNvData->TargetUrl)) {\r
+      return EFI_INVALID_PARAMETER;\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
@@ -203,7 +222,7 @@ IScsiDhcp6ExtractRootPath (
     goto ON_EXIT;\r
   }\r
 \r
-  AsciiStrCpy (ConfigNvData->TargetName, Field->Str);\r
+  AsciiStrCpyS (ConfigNvData->TargetName, ISCSI_NAME_MAX_SIZE, Field->Str);\r
 \r
 ON_EXIT:\r
 \r
@@ -213,11 +232,11 @@ ON_EXIT:
 }\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
@@ -250,10 +269,11 @@ IScsiDhcp6ParseReply (
   EFI_DHCP6_PACKET_OPTION     *BootFileOpt;\r
   EFI_DHCP6_PACKET_OPTION     **OptionList;\r
   ISCSI_ATTEMPT_CONFIG_NVDATA *ConfigData;\r
\r
+  UINT16                      ParaLen;\r
+\r
   OptionCount = 0;\r
   BootFileOpt = NULL;\r
-  \r
+\r
   Status      = This->Parse (This, Packet, &OptionCount, NULL);\r
   if (Status != EFI_BUFFER_TOO_SMALL) {\r
     return EFI_NOT_READY;\r
@@ -282,7 +302,7 @@ IScsiDhcp6ParseReply (
     if (OptionList[Index]->OpCode == DHCP6_OPT_DNS_SERVERS) {\r
 \r
       if (((OptionList[Index]->OpLen & 0xf) != 0) || (OptionList[Index]->OpLen == 0)) {\r
-        Status = EFI_INVALID_PARAMETER;\r
+        Status = EFI_UNSUPPORTED;\r
         goto Exit;\r
       }\r
       //\r
@@ -302,6 +322,24 @@ IScsiDhcp6ParseReply (
       // The server sends this option to inform the client about an URL to a boot file.\r
       //\r
       BootFileOpt = OptionList[Index];\r
+    } else if (OptionList[Index]->OpCode == DHCP6_OPT_BOOT_FILE_PARAM) {\r
+      //\r
+      // The server sends this option to inform the client about DHCP6 server address.\r
+      //\r
+      if (OptionList[Index]->OpLen < 18) {\r
+        Status = EFI_UNSUPPORTED;\r
+        goto Exit;\r
+      }\r
+      //\r
+      // Check param-len 1, should be 16 bytes.\r
+      //\r
+      CopyMem (&ParaLen, &OptionList[Index]->Data[0], sizeof (UINT16));\r
+      if (NTOHS (ParaLen) != 16) {\r
+        Status = EFI_UNSUPPORTED;\r
+        goto Exit;\r
+      }\r
+\r
+      CopyMem (&ConfigData->DhcpServer, &OptionList[Index]->Data[2], sizeof (EFI_IPv6_ADDRESS));\r
     }\r
   }\r
 \r
@@ -309,7 +347,7 @@ IScsiDhcp6ParseReply (
     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
@@ -357,14 +395,15 @@ IScsiDoDhcp6 (
   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
@@ -405,7 +444,7 @@ IScsiDoDhcp6 (
     goto ON_EXIT;\r
   }\r
 \r
-  Oro = AllocateZeroPool (sizeof (EFI_DHCP6_PACKET_OPTION) + 3);\r
+  Oro = AllocateZeroPool (sizeof (EFI_DHCP6_PACKET_OPTION) + 5);\r
   if (Oro == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto ON_EXIT;\r
@@ -415,10 +454,11 @@ IScsiDoDhcp6 (
   // Ask the server to reply with DNS and Boot File URL options by info request.\r
   // All members in EFI_DHCP6_PACKET_OPTION are in network order.\r
   //\r
-  Oro->OpCode  = HTONS (DHCP6_OPT_REQUEST_OPTION);\r
-  Oro->OpLen   = HTONS (2 * 2);\r
+  Oro->OpCode  = HTONS (DHCP6_OPT_ORO);\r
+  Oro->OpLen   = HTONS (2 * 3);\r
   Oro->Data[1] = DHCP6_OPT_DNS_SERVERS;\r
   Oro->Data[3] = DHCP6_OPT_BOOT_FILE_URL;\r
+  Oro->Data[5] = DHCP6_OPT_BOOT_FILE_PARAM;\r
 \r
   InfoReqReXmit.Irt = 4;\r
   InfoReqReXmit.Mrc = 1;\r
@@ -478,7 +518,7 @@ ON_EXIT:
 \r
   if (Oro != NULL) {\r
     FreePool (Oro);\r
-  }  \r
+  }\r
 \r
   if (Timer != NULL) {\r
     gBS->CloseEvent (Timer);\r