/** @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
{\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
}\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
DHCP_SERVICE *DhcpSb;\r
EFI_STATUS Status;\r
EFI_TPL OldTpl;\r
+ EFI_STATUS MediaStatus;\r
\r
//\r
// First validate the parameters\r
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
\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
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
\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
\r
return EFI_SUCCESS;\r
\r
-ON_ERROR:\r
+ON_EXIT:\r
gBS->RestoreTPL (OldTpl);\r
return Status;\r
}\r
@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
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
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
)\r
{\r
DHCP_SERVICE *DhcpSb;\r
+ EFI_STATUS Status;\r
+ VOID *Udp4;\r
\r
ASSERT (Instance->Token != NULL);\r
\r
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
\r
**/\r
VOID\r
+EFIAPI\r
DhcpDummyExtFree (\r
IN VOID *Arg\r
)\r
\r
**/\r
VOID\r
+EFIAPI\r
PxeDhcpInput (\r
NET_BUF *UdpPacket,\r
UDP_END_POINT *EndPoint,\r
)\r
{\r
DHCP_PROTOCOL *Instance;\r
- DHCP_SERVICE *DhcpSb;\r
EFI_DHCP4_HEADER *Head;\r
NET_BUF *Wrap;\r
EFI_DHCP4_PACKET *Packet;\r
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
//\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
//\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
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
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
//\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
\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
\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