]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c
BaseTools:Change the path of the file that Binary Cache
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Dhcp4Dxe / Dhcp4Impl.c
index f470844ee4d9930b975900cd3867290b1a41bc51..0b35bdf4df95b51339dcf63c0c1b032cb450420d 100644 (file)
@@ -1,14 +1,8 @@
 /** @file\r
   This file implement the EFI_DHCP4_PROTOCOL interface.\r
 \r
-Copyright (c) 2006 - 2010, Intel Corporation.<BR>\r
-All rights reserved. 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) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -467,7 +461,7 @@ DhcpCopyConfigure (
 {\r
   EFI_DHCP4_PACKET_OPTION   **DstOptions;\r
   EFI_DHCP4_PACKET_OPTION   **SrcOptions;\r
-  INTN                      Len;\r
+  UINTN                     Len;\r
   UINT32                    Index;\r
 \r
   CopyMem (Dst, Src, sizeof (*Dst));\r
@@ -660,9 +654,7 @@ EfiDhcp4Configure (
     }\r
 \r
     CopyMem (&Ip, &Dhcp4CfgData->ClientAddress, sizeof (IP4_ADDR));\r
-\r
-    if ((Ip != 0) && !NetIp4IsUnicast (NTOHL (Ip), 0)) {\r
-\r
+    if (IP4_IS_LOCAL_BROADCAST(NTOHL (Ip))) {\r
       return EFI_INVALID_PARAMETER;\r
     }\r
   }\r
@@ -784,6 +776,7 @@ EfiDhcp4Start (
   DHCP_SERVICE              *DhcpSb;\r
   EFI_STATUS                Status;\r
   EFI_TPL                   OldTpl;\r
+  EFI_STATUS                MediaStatus;\r
 \r
   //\r
   // First validate the parameters\r
@@ -811,6 +804,16 @@ EfiDhcp4Start (
     goto ON_ERROR;\r
   }\r
 \r
+  //\r
+  // Check Media Satus.\r
+  //\r
+  MediaStatus = EFI_SUCCESS;\r
+  NetLibDetectMediaWaitTimeout (DhcpSb->Controller, DHCP_CHECK_MEDIA_WAITING_TIME, &MediaStatus);\r
+  if (MediaStatus != EFI_SUCCESS) {\r
+    Status = EFI_NO_MEDIA;\r
+    goto ON_ERROR;\r
+  }\r
+\r
   DhcpSb->IoStatus = EFI_ALREADY_STARTED;\r
 \r
   if (EFI_ERROR (Status = DhcpInitRequest (DhcpSb))) {\r
@@ -910,16 +913,17 @@ EfiDhcp4RenewRebind (
 \r
   if (DhcpSb->DhcpState == Dhcp4Stopped) {\r
     Status = EFI_NOT_STARTED;\r
-    goto ON_ERROR;\r
+    goto ON_EXIT;\r
   }\r
 \r
   if (DhcpSb->DhcpState != Dhcp4Bound) {\r
     Status = EFI_ACCESS_DENIED;\r
-    goto ON_ERROR;\r
+    goto ON_EXIT;\r
   }\r
 \r
   if (DHCP_IS_BOOTP (DhcpSb->Para)) {\r
-    return EFI_SUCCESS;\r
+    Status = EFI_SUCCESS;\r
+    goto ON_EXIT;\r
   }\r
 \r
   //\r
@@ -931,6 +935,12 @@ EfiDhcp4RenewRebind (
     DhcpSetState (DhcpSb, Dhcp4Rebinding, FALSE);\r
   }\r
 \r
+  //\r
+  // Clear initial time to make sure that elapsed-time\r
+  // is set to 0 for first REQUEST in renewal process.\r
+  //\r
+  Instance->ElaspedTime = 0;\r
+\r
   Status = DhcpSendMessage (\r
              DhcpSb,\r
              DhcpSb->Selected,\r
@@ -941,7 +951,7 @@ EfiDhcp4RenewRebind (
 \r
   if (EFI_ERROR (Status)) {\r
     DhcpSetState (DhcpSb, Dhcp4Bound, FALSE);\r
-    goto ON_ERROR;\r
+    goto ON_EXIT;\r
   }\r
 \r
   DhcpSb->ExtraRefresh        = TRUE;\r
@@ -961,7 +971,7 @@ EfiDhcp4RenewRebind (
 \r
   return EFI_SUCCESS;\r
 \r
-ON_ERROR:\r
+ON_EXIT:\r
   gBS->RestoreTPL (OldTpl);\r
   return Status;\r
 }\r
@@ -1170,10 +1180,13 @@ EfiDhcp4Build (
   @param[in] UdpIo      The UdpIo being created.\r
   @param[in] Context    Dhcp4 instance.\r
 \r
-  @retval EFI_SUCCESS   UdpIo is configured successfully.\r
-  @retval other         Other error occurs.\r
+  @retval EFI_SUCCESS              UdpIo is configured successfully.\r
+  @retval EFI_INVALID_PARAMETER    Class E IP address is not supported or other parameters\r
+                                   are not valid.\r
+  @retval other                    Other error occurs.\r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 Dhcp4InstanceConfigUdpIo (\r
   IN UDP_IO       *UdpIo,\r
   IN VOID         *Context\r
@@ -1183,7 +1196,10 @@ Dhcp4InstanceConfigUdpIo (
   DHCP_SERVICE                      *DhcpSb;\r
   EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN  *Token;\r
   EFI_UDP4_CONFIG_DATA              UdpConfigData;\r
+  IP4_ADDR                          ClientAddr;\r
   IP4_ADDR                          Ip;\r
+  INTN                              Class;\r
+  IP4_ADDR                          SubnetMask;\r
 \r
   Instance = (DHCP_PROTOCOL *) Context;\r
   DhcpSb   = Instance->Service;\r
@@ -1196,10 +1212,33 @@ Dhcp4InstanceConfigUdpIo (
   UdpConfigData.TimeToLive         = 64;\r
   UdpConfigData.DoNotFragment      = TRUE;\r
 \r
-  Ip = HTONL (DhcpSb->ClientAddr);\r
+  ClientAddr = EFI_NTOHL (Token->Packet->Dhcp4.Header.ClientAddr);\r
+  Ip = HTONL (ClientAddr);\r
   CopyMem (&UdpConfigData.StationAddress, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
 \r
-  Ip = HTONL (DhcpSb->Netmask);\r
+  if (DhcpSb->Netmask == 0) {\r
+    //\r
+    // The Dhcp4.TransmitReceive() API should be able to used at any time according to\r
+    // UEFI spec, while in classless addressing network, the netmask must be explicitly\r
+    // provided together with the station address.\r
+    // If the DHCP instance haven't be configured with a valid netmask, we could only\r
+    // compute it according to the classful addressing rule.\r
+    //\r
+    Class = NetGetIpClass (ClientAddr);\r
+    //\r
+    //  Class E IP address is not supported here!\r
+    //\r
+    ASSERT (Class < IP4_ADDR_CLASSE);\r
+    if (Class >= IP4_ADDR_CLASSE) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    SubnetMask = gIp4AllMasks[Class << 3];\r
+  } else {\r
+    SubnetMask = DhcpSb->Netmask;\r
+  }\r
+\r
+  Ip = HTONL (SubnetMask);\r
   CopyMem (&UdpConfigData.SubnetMask, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
 \r
   if ((Token->ListenPointCount == 0) || (Token->ListenPoints[0].ListenPort == 0)) {\r
@@ -1226,6 +1265,8 @@ Dhcp4InstanceCreateUdpIo (
   )\r
 {\r
   DHCP_SERVICE  *DhcpSb;\r
+  EFI_STATUS    Status;\r
+  VOID          *Udp4;\r
 \r
   ASSERT (Instance->Token != NULL);\r
 \r
@@ -1240,7 +1281,19 @@ Dhcp4InstanceCreateUdpIo (
   if (Instance->UdpIo == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   } else {\r
-    return EFI_SUCCESS;\r
+    Status = gBS->OpenProtocol (\r
+                    Instance->UdpIo->UdpHandle,\r
+                    &gEfiUdp4ProtocolGuid,\r
+                    (VOID **) &Udp4,\r
+                    Instance->Service->Image,\r
+                    Instance->Handle,\r
+                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      UdpIoFreeIo (Instance->UdpIo);\r
+      Instance->UdpIo = NULL;\r
+    }\r
+    return Status;\r
   }\r
 }\r
 \r
@@ -1251,6 +1304,7 @@ Dhcp4InstanceCreateUdpIo (
 \r
 **/\r
 VOID\r
+EFIAPI\r
 DhcpDummyExtFree (\r
   IN VOID                   *Arg\r
   )\r
@@ -1270,6 +1324,7 @@ DhcpDummyExtFree (
 \r
 **/\r
 VOID\r
+EFIAPI\r
 PxeDhcpInput (\r
   NET_BUF                   *UdpPacket,\r
   UDP_END_POINT             *EndPoint,\r
@@ -1278,7 +1333,6 @@ PxeDhcpInput (
   )\r
 {\r
   DHCP_PROTOCOL                     *Instance;\r
-  DHCP_SERVICE                      *DhcpSb;\r
   EFI_DHCP4_HEADER                  *Head;\r
   NET_BUF                           *Wrap;\r
   EFI_DHCP4_PACKET                  *Packet;\r
@@ -1289,7 +1343,6 @@ PxeDhcpInput (
   Wrap     = NULL;\r
   Instance = (DHCP_PROTOCOL *) Context;\r
   Token    = Instance->Token;\r
-  DhcpSb   = Instance->Service;\r
 \r
   //\r
   // Don't restart receive if error occurs or DHCP is destroyed.\r
@@ -1333,7 +1386,7 @@ PxeDhcpInput (
   //\r
   if ((Head->OpCode != BOOTP_REPLY) ||\r
       (Head->Xid != Token->Packet->Dhcp4.Header.Xid) ||\r
-      (CompareMem (DhcpSb->ClientAddressSendOut, Head->ClientHwAddr, Head->HwAddrLen) != 0)) {\r
+      (CompareMem (&Token->Packet->Dhcp4.Header.ClientHwAddr[0], Head->ClientHwAddr, Head->HwAddrLen) != 0)) {\r
     goto RESTART;\r
   }\r
 \r
@@ -1406,6 +1459,12 @@ SIGNAL_USER:
   //\r
   NetbufQueFlush (&Instance->ResponseQueue);\r
   UdpIoCleanIo (Instance->UdpIo);\r
+  gBS->CloseProtocol (\r
+         Instance->UdpIo->UdpHandle,\r
+         &gEfiUdp4ProtocolGuid,\r
+         Instance->Service->Image,\r
+         Instance->Handle\r
+         );\r
   UdpIoFreeIo (Instance->UdpIo);\r
   Instance->UdpIo = NULL;\r
   Instance->Token = NULL;\r
@@ -1451,7 +1510,7 @@ EfiDhcp4TransmitReceive (
   IP4_ADDR       Ip;\r
   DHCP_SERVICE   *DhcpSb;\r
   EFI_IP_ADDRESS Gateway;\r
-  IP4_ADDR       SubnetMask;\r
+  IP4_ADDR       ClientAddr;\r
 \r
   if ((This == NULL) || (Token == NULL) || (Token->Packet == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -1482,8 +1541,9 @@ EfiDhcp4TransmitReceive (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  if (DhcpSb->ClientAddr == 0) {\r
+  ClientAddr = EFI_NTOHL (Token->Packet->Dhcp4.Header.ClientAddr);\r
 \r
+  if (ClientAddr == 0) {\r
     return EFI_NO_MAPPING;\r
   }\r
 \r
@@ -1543,9 +1603,8 @@ EfiDhcp4TransmitReceive (
   //\r
   // Get the gateway.\r
   //\r
-  SubnetMask = DhcpSb->Netmask;\r
   ZeroMem (&Gateway, sizeof (Gateway));\r
-  if (!IP4_NET_EQUAL (DhcpSb->ClientAddr, EndPoint.RemoteAddr.Addr[0], SubnetMask)) {\r
+  if (!IP4_NET_EQUAL (ClientAddr, EndPoint.RemoteAddr.Addr[0], DhcpSb->Netmask)) {\r
     CopyMem (&Gateway.v4, &Token->GatewayAddress, sizeof (EFI_IPv4_ADDRESS));\r
     Gateway.Addr[0] = NTOHL (Gateway.Addr[0]);\r
   }\r
@@ -1571,6 +1630,12 @@ ON_ERROR:
 \r
   if (EFI_ERROR (Status) && (Instance->UdpIo != NULL)) {\r
     UdpIoCleanIo (Instance->UdpIo);\r
+    gBS->CloseProtocol (\r
+           Instance->UdpIo->UdpHandle,\r
+           &gEfiUdp4ProtocolGuid,\r
+           Instance->Service->Image,\r
+           Instance->Handle\r
+           );\r
     UdpIoFreeIo (Instance->UdpIo);\r
     Instance->UdpIo = NULL;\r
     Instance->Token = NULL;\r
@@ -1719,3 +1784,19 @@ EfiDhcp4Parse (
 \r
   return EFI_SUCCESS;\r
 }\r
+\r
+/**\r
+  Set the elapsed time based on the given instance and the pointer to the\r
+  elapsed time option.\r
+\r
+  @param[in]      Elapsed       The pointer to the position to append.\r
+  @param[in]      Instance      The pointer to the Dhcp4 instance.\r
+**/\r
+VOID\r
+SetElapsedTime (\r
+  IN     UINT16                 *Elapsed,\r
+  IN     DHCP_PROTOCOL          *Instance\r
+  )\r
+{\r
+  WriteUnaligned16 (Elapsed, HTONS(Instance->ElaspedTime));\r
+}\r