/** @file\r
+ EFI DHCP protocol implementation.\r
\r
-Copyright (c) 2006 - 2007, Intel Corporation\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
-\r
-Module Name:\r
-\r
- Dhcp4Io.c\r
-\r
-Abstract:\r
-\r
- EFI DHCP protocol implementation\r
-\r
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
Send an initial DISCOVER or REQUEST message according to the\r
DHCP service's current state.\r
\r
- @param DhcpSb The DHCP service instance\r
+ @param[in] DhcpSb The DHCP service instance\r
\r
@retval EFI_SUCCESS The request has been sent\r
+ @retval other Some error occurs when sending the request.\r
\r
**/\r
EFI_STATUS\r
\r
ASSERT ((DhcpSb->DhcpState == Dhcp4Init) || (DhcpSb->DhcpState == Dhcp4InitReboot));\r
\r
+ //\r
+ // Clear initial time to make sure that elapsed-time is set to 0 for first Discover or REQUEST message.\r
+ //\r
+ DhcpSb->ActiveChild->ElaspedTime= 0;\r
+\r
if (DhcpSb->DhcpState == Dhcp4Init) {\r
DhcpSetState (DhcpSb, Dhcp4Selecting, FALSE);\r
Status = DhcpSendMessage (DhcpSb, NULL, NULL, DHCP_MSG_DISCOVER, NULL);\r
proper return value is selected to let the caller continue the\r
normal process.\r
\r
- @param DhcpSb The DHCP service instance\r
- @param Event The event as defined in the spec\r
- @param Packet The current packet trigger the event\r
- @param NewPacket The user's return new packet\r
+ @param[in] DhcpSb The DHCP service instance\r
+ @param[in] Event The event as defined in the spec\r
+ @param[in] Packet The current packet trigger the event\r
+ @param[out] NewPacket The user's return new packet\r
\r
@retval EFI_NOT_READY Direct the caller to continue collecting the offer.\r
@retval EFI_SUCCESS The user function returns success.\r
@retval EFI_ABORTED The user function ask it to abort.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
DhcpCallUser (\r
IN DHCP_SERVICE *DhcpSb,\r
Notify the user about the operation result.\r
\r
@param DhcpSb DHCP service instance\r
- @param Which which notify function to signal\r
-\r
- @return None\r
+ @param Which Which notify function to signal\r
\r
**/\r
VOID\r
}\r
\r
if ((Child->CompletionEvent != NULL) &&\r
- ((Which == DHCP_NOTIFY_COMPLETION) || (Which == DHCP_NOTIFY_ALL))) {\r
+ ((Which == DHCP_NOTIFY_COMPLETION) || (Which == DHCP_NOTIFY_ALL))\r
+ ) {\r
\r
gBS->SignalEvent (Child->CompletionEvent);\r
Child->CompletionEvent = NULL;\r
}\r
\r
if ((Child->RenewRebindEvent != NULL) &&\r
- ((Which == DHCP_NOTIFY_RENEWREBIND) || (Which == DHCP_NOTIFY_ALL))) {\r
+ ((Which == DHCP_NOTIFY_RENEWREBIND) || (Which == DHCP_NOTIFY_ALL))\r
+ ) {\r
\r
gBS->SignalEvent (Child->RenewRebindEvent);\r
Child->RenewRebindEvent = NULL;\r
**/\r
EFI_STATUS\r
DhcpSetState (\r
- IN DHCP_SERVICE *DhcpSb,\r
- IN INTN State,\r
- IN BOOLEAN CallUser\r
+ IN OUT DHCP_SERVICE *DhcpSb,\r
+ IN INTN State,\r
+ IN BOOLEAN CallUser\r
)\r
{\r
EFI_STATUS Status;\r
\r
DhcpSb->CurRetry = 0;\r
DhcpSb->PacketToLive = 0;\r
-\r
+ DhcpSb->LastTimeout = 0;\r
DhcpSb->DhcpState = State;\r
return EFI_SUCCESS;\r
}\r
\r
@param DhcpSb The DHCP service instance.\r
\r
- @return None\r
-\r
**/\r
-STATIC\r
VOID\r
DhcpSetTransmitTimer (\r
- IN DHCP_SERVICE *DhcpSb\r
+ IN OUT DHCP_SERVICE *DhcpSb\r
)\r
{\r
UINT32 *Times;\r
}\r
\r
DhcpSb->PacketToLive = Times[DhcpSb->CurRetry];\r
+ DhcpSb->LastTimeout = DhcpSb->PacketToLive;\r
\r
- if (DhcpSb->DhcpState == Dhcp4Selecting) {\r
- DhcpSb->WaitOffer = DhcpSb->PacketToLive;\r
- }\r
+ return;\r
}\r
\r
/**\r
@param DhcpSb The DHCP service instance\r
@param Para The DHCP parameter extracted from the server's\r
response.\r
-\r
- @return None\r
-\r
**/\r
-STATIC\r
VOID\r
DhcpComputeLease (\r
- IN DHCP_SERVICE *DhcpSb,\r
- IN DHCP_PARAMETER *Para\r
+ IN OUT DHCP_SERVICE *DhcpSb,\r
+ IN DHCP_PARAMETER *Para\r
)\r
{\r
ASSERT (Para != NULL);\r
DHCP driver needs this port to unicast packet to the server\r
such as DHCP release.\r
\r
- @param UdpIo The UDP IO port to configure\r
- @param Context The opaque parameter to the function.\r
+ @param[in] UdpIo The UDP IO to configure\r
+ @param[in] Context Dhcp service instance.\r
\r
@retval EFI_SUCCESS The UDP IO port is successfully configured.\r
@retval Others It failed to configure the port.\r
\r
**/\r
EFI_STATUS\r
+EFIAPI\r
DhcpConfigLeaseIoPort (\r
- IN UDP_IO_PORT *UdpIo,\r
+ IN UDP_IO *UdpIo,\r
IN VOID *Context\r
)\r
{\r
UdpConfigData.RemotePort = DHCP_SERVER_PORT;\r
\r
Ip = HTONL (DhcpSb->ClientAddr);\r
- NetCopyMem (&UdpConfigData.StationAddress, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
+ CopyMem (&UdpConfigData.StationAddress, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
\r
Ip = HTONL (DhcpSb->Netmask);\r
- NetCopyMem (&UdpConfigData.SubnetMask, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
+ CopyMem (&UdpConfigData.SubnetMask, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
\r
- NetZeroMem (&UdpConfigData.RemoteAddress, sizeof (EFI_IPv4_ADDRESS));\r
+ ZeroMem (&UdpConfigData.RemoteAddress, sizeof (EFI_IPv4_ADDRESS));\r
\r
- Status = UdpIo->Udp->Configure (UdpIo->Udp, &UdpConfigData);\r
+ Status = UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, &UdpConfigData);\r
\r
if (EFI_ERROR (Status)) {\r
return Status;\r
// Add a default route if received from the server.\r
//\r
if ((DhcpSb->Para != NULL) && (DhcpSb->Para->Router != 0)) {\r
- NetZeroMem (&Subnet, sizeof (EFI_IPv4_ADDRESS));\r
+ ZeroMem (&Subnet, sizeof (EFI_IPv4_ADDRESS));\r
\r
Ip = HTONL (DhcpSb->Para->Router);\r
- NetCopyMem (&Gateway, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
+ CopyMem (&Gateway, &Ip, sizeof (EFI_IPv4_ADDRESS));\r
\r
- UdpIo->Udp->Routes (UdpIo->Udp, FALSE, &Subnet, &Subnet, &Gateway);\r
+ UdpIo->Protocol.Udp4->Routes (UdpIo->Protocol.Udp4, FALSE, &Subnet, &Subnet, &Gateway);\r
}\r
\r
return EFI_SUCCESS;\r
@retval EFI_SUCCESS The lease is recorded.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
DhcpLeaseAcquired (\r
- IN DHCP_SERVICE *DhcpSb\r
+ IN OUT DHCP_SERVICE *DhcpSb\r
)\r
{\r
- INTN Class;\r
-\r
DhcpSb->ClientAddr = EFI_NTOHL (DhcpSb->Selected->Dhcp4.Header.YourAddr);\r
\r
if (DhcpSb->Para != NULL) {\r
}\r
\r
if (DhcpSb->Netmask == 0) {\r
- Class = NetGetIpClass (DhcpSb->ClientAddr);\r
- DhcpSb->Netmask = mIp4AllMasks[Class << 3];\r
+ return EFI_ABORTED;\r
}\r
\r
if (DhcpSb->LeaseIoPort != NULL) {\r
- UdpIoFreePort (DhcpSb->LeaseIoPort);\r
+ UdpIoFreeIo (DhcpSb->LeaseIoPort);\r
}\r
\r
//\r
// and transmit unicast packet with it as source address. Don't\r
// start receive on this port, the queued packet will be timeout.\r
//\r
- DhcpSb->LeaseIoPort = UdpIoCreatePort (\r
+ DhcpSb->LeaseIoPort = UdpIoCreateIo (\r
DhcpSb->Controller,\r
DhcpSb->Image,\r
DhcpConfigLeaseIoPort,\r
+ UDP_IO_UDP4_VERSION,\r
DhcpSb\r
);\r
\r
\r
@param DhcpSb The DHCP instance service.\r
\r
- @return None\r
-\r
**/\r
VOID\r
DhcpCleanLease (\r
DhcpSb->DhcpState = Dhcp4Init;\r
DhcpSb->Xid = DhcpSb->Xid + 1;\r
DhcpSb->ClientAddr = 0;\r
+ DhcpSb->Netmask = 0;\r
DhcpSb->ServerAddr = 0;\r
\r
if (DhcpSb->LastOffer != NULL) {\r
- NetFreePool (DhcpSb->LastOffer);\r
+ FreePool (DhcpSb->LastOffer);\r
DhcpSb->LastOffer = NULL;\r
}\r
\r
if (DhcpSb->Selected != NULL) {\r
- NetFreePool (DhcpSb->Selected);\r
+ FreePool (DhcpSb->Selected);\r
DhcpSb->Selected = NULL;\r
}\r
\r
if (DhcpSb->Para != NULL) {\r
- NetFreePool (DhcpSb->Para);\r
+ FreePool (DhcpSb->Para);\r
DhcpSb->Para = NULL;\r
}\r
\r
DhcpSb->ExtraRefresh = FALSE;\r
\r
if (DhcpSb->LeaseIoPort != NULL) {\r
- UdpIoFreePort (DhcpSb->LeaseIoPort);\r
+ UdpIoFreeIo (DhcpSb->LeaseIoPort);\r
DhcpSb->LeaseIoPort = NULL;\r
}\r
\r
if (DhcpSb->LastPacket != NULL) {\r
- NetbufFree (DhcpSb->LastPacket);\r
+ FreePool (DhcpSb->LastPacket);\r
DhcpSb->LastPacket = NULL;\r
}\r
\r
DhcpSb->PacketToLive = 0;\r
+ DhcpSb->LastTimeout = 0;\r
DhcpSb->CurRetry = 0;\r
DhcpSb->MaxRetries = 0;\r
- DhcpSb->WaitOffer = 0;\r
DhcpSb->LeaseLife = 0;\r
+\r
+ //\r
+ // Clean active config data.\r
+ //\r
+ DhcpCleanConfigure (&DhcpSb->ActiveConfig);\r
}\r
\r
\r
of BOOTP, the lease is recorded and user notified. If the offer is of\r
DHCP, it will request the offer from the server.\r
\r
- @param DhcpSb The DHCP service instance.\r
+ @param[in] DhcpSb The DHCP service instance.\r
\r
@retval EFI_SUCCESS One of the offer is selected.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
DhcpChooseOffer (\r
IN DHCP_SERVICE *DhcpSb\r
\r
ASSERT (DhcpSb->LastOffer != NULL);\r
\r
- //\r
- // Stop waiting more offers\r
- //\r
- DhcpSb->WaitOffer = 0;\r
-\r
//\r
// User will cache previous offers if he wants to select\r
// from multiple offers. If user provides an invalid packet,\r
Selected = DhcpSb->LastOffer;\r
\r
if ((NewPacket != NULL) && !EFI_ERROR (DhcpValidateOptions (NewPacket, NULL))) {\r
- TempPacket = (EFI_DHCP4_PACKET *) NetAllocatePool (NewPacket->Size);\r
+ TempPacket = (EFI_DHCP4_PACKET *) AllocatePool (NewPacket->Size);\r
if (TempPacket != NULL) {\r
- NetCopyMem (TempPacket, NewPacket, NewPacket->Size);\r
- NetFreePool (Selected);\r
+ CopyMem (TempPacket, NewPacket, NewPacket->Size);\r
+ FreePool (Selected);\r
Selected = TempPacket;\r
}\r
}\r
to this is: only call DhcpEndSession at the highest level, such as\r
DhcpInput, DhcpOnTimerTick...At the other level, just return error.\r
\r
- @param DhcpSb The DHCP service instance\r
- @param Status The result of the DHCP process.\r
-\r
- @return None\r
+ @param[in] DhcpSb The DHCP service instance\r
+ @param[in] Status The result of the DHCP process.\r
\r
**/\r
-STATIC\r
VOID\r
DhcpEndSession (\r
IN DHCP_SERVICE *DhcpSb,\r
/**\r
Handle packets in DHCP select state.\r
\r
- @param DhcpSb The DHCP service instance\r
- @param Packet The DHCP packet received\r
- @param Para The DHCP parameter extracted from the packet. That\r
- is, all the option value that we care.\r
+ @param[in] DhcpSb The DHCP service instance\r
+ @param[in] Packet The DHCP packet received\r
+ @param[in] Para The DHCP parameter extracted from the packet. That\r
+ is, all the option value that we care.\r
\r
@retval EFI_SUCCESS The packet is successfully processed.\r
@retval Others Some error occured.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
DhcpHandleSelect (\r
IN DHCP_SERVICE *DhcpSb,\r
IN DHCP_PARAMETER *Para\r
)\r
{\r
- EFI_DHCP4_HEADER *Head;\r
EFI_STATUS Status;\r
\r
Status = EFI_SUCCESS;\r
// 2. if it is a DHCP message, it must contains a server ID.\r
// Don't return a error for these two case otherwise the session is ended.\r
//\r
- Head = &Packet->Dhcp4.Header;\r
-\r
if (!DHCP_IS_BOOTP (Para) &&\r
- ((Para->DhcpType != DHCP_MSG_OFFER) || (Para->ServerId == 0))) {\r
+ ((Para->DhcpType != DHCP_MSG_OFFER) || (Para->ServerId == 0))\r
+ ) {\r
goto ON_EXIT;\r
}\r
\r
\r
if (Status == EFI_SUCCESS) {\r
if (DhcpSb->LastOffer != NULL) {\r
- NetFreePool (DhcpSb->LastOffer);\r
+ FreePool (DhcpSb->LastOffer);\r
}\r
\r
DhcpSb->LastOffer = Packet;\r
\r
} else if (Status == EFI_NOT_READY) {\r
if (DhcpSb->LastOffer != NULL) {\r
- NetFreePool (DhcpSb->LastOffer);\r
+ FreePool (DhcpSb->LastOffer);\r
}\r
\r
DhcpSb->LastOffer = Packet;\r
return EFI_SUCCESS;\r
\r
ON_EXIT:\r
- NetFreePool (Packet);\r
+ FreePool (Packet);\r
return Status;\r
}\r
\r
/**\r
Handle packets in DHCP request state.\r
\r
- @param DhcpSb The DHCP service instance\r
- @param Packet The DHCP packet received\r
- @param Para The DHCP parameter extracted from the packet. That\r
- is, all the option value that we care.\r
+ @param[in] DhcpSb The DHCP service instance\r
+ @param[in] Packet The DHCP packet received\r
+ @param[in] Para The DHCP parameter extracted from the packet. That\r
+ is, all the option value that we care.\r
\r
@retval EFI_SUCCESS The packet is successfully processed.\r
@retval Others Some error occured.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
DhcpHandleRequest (\r
IN DHCP_SERVICE *DhcpSb,\r
// Ignore the BOOTP message and DHCP messages other than DHCP ACK/NACK.\r
//\r
if (DHCP_IS_BOOTP (Para) ||\r
- (Para->ServerId != DhcpSb->Para->ServerId) ||\r
- ((Para->DhcpType != DHCP_MSG_ACK) && (Para->DhcpType != DHCP_MSG_NAK))) {\r
+ (Para->ServerId != DhcpSb->Para->ServerId) ||\r
+ ((Para->DhcpType != DHCP_MSG_ACK) && (Para->DhcpType != DHCP_MSG_NAK))\r
+ ) {\r
\r
Status = EFI_SUCCESS;\r
goto ON_EXIT;\r
DhcpSb->IoStatus = EFI_SUCCESS;\r
DhcpNotifyUser (DhcpSb, DHCP_NOTIFY_COMPLETION);\r
\r
- NetFreePool (Packet);\r
+ FreePool (Packet);\r
return EFI_SUCCESS;\r
\r
REJECT:\r
DhcpSendMessage (DhcpSb, DhcpSb->Selected, DhcpSb->Para, DHCP_MSG_DECLINE, Message);\r
\r
ON_EXIT:\r
- NetFreePool (Packet);\r
+ FreePool (Packet);\r
return Status;\r
}\r
\r
/**\r
Handle packets in DHCP renew/rebound state.\r
\r
- @param DhcpSb The DHCP service instance\r
- @param Packet The DHCP packet received\r
- @param Para The DHCP parameter extracted from the packet. That\r
- is, all the option value that we care.\r
+ @param[in] DhcpSb The DHCP service instance\r
+ @param[in] Packet The DHCP packet received\r
+ @param[in] Para The DHCP parameter extracted from the packet. That\r
+ is, all the option value that we care.\r
\r
@retval EFI_SUCCESS The packet is successfully processed.\r
@retval Others Some error occured.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
DhcpHandleRenewRebind (\r
IN DHCP_SERVICE *DhcpSb,\r
// Ignore the BOOTP message and DHCP messages other than DHCP ACK/NACK\r
//\r
if (DHCP_IS_BOOTP (Para) ||\r
- (Para->ServerId != DhcpSb->Para->ServerId) ||\r
- ((Para->DhcpType != DHCP_MSG_ACK) && (Para->DhcpType != DHCP_MSG_NAK))) {\r
+ (Para->ServerId != DhcpSb->Para->ServerId) ||\r
+ ((Para->DhcpType != DHCP_MSG_ACK) && (Para->DhcpType != DHCP_MSG_NAK))\r
+ ) {\r
\r
Status = EFI_SUCCESS;\r
goto ON_EXIT;\r
DhcpSb->LeaseLife = 0;\r
DhcpSetState (DhcpSb, Dhcp4Bound, TRUE);\r
\r
- if (DhcpSb->ExtraRefresh) {\r
+ if (DhcpSb->ExtraRefresh != 0) {\r
DhcpSb->ExtraRefresh = FALSE;\r
\r
DhcpSb->IoStatus = EFI_SUCCESS;\r
}\r
\r
ON_EXIT:\r
- NetFreePool (Packet);\r
+ FreePool (Packet);\r
return Status;\r
}\r
\r
/**\r
Handle packets in DHCP reboot state.\r
\r
- @param DhcpSb The DHCP service instance\r
- @param Packet The DHCP packet received\r
- @param Para The DHCP parameter extracted from the packet. That\r
- is, all the option value that we care.\r
+ @param[in] DhcpSb The DHCP service instance\r
+ @param[in] Packet The DHCP packet received\r
+ @param[in] Para The DHCP parameter extracted from the packet. That\r
+ is, all the option value that we care.\r
\r
@retval EFI_SUCCESS The packet is successfully processed.\r
@retval Others Some error occured.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
DhcpHandleReboot (\r
IN DHCP_SERVICE *DhcpSb,\r
// Ignore the BOOTP message and DHCP messages other than DHCP ACK/NACK\r
//\r
if (DHCP_IS_BOOTP (Para) ||\r
- ((Para->DhcpType != DHCP_MSG_ACK) && (Para->DhcpType != DHCP_MSG_NAK))) {\r
+ ((Para->DhcpType != DHCP_MSG_ACK) && (Para->DhcpType != DHCP_MSG_NAK))\r
+ ) {\r
\r
Status = EFI_SUCCESS;\r
goto ON_EXIT;\r
//\r
// OK, get the parameter from server, record the lease\r
//\r
- DhcpSb->Para = NetAllocatePool (sizeof (DHCP_PARAMETER));\r
-\r
+ DhcpSb->Para = AllocateCopyPool (sizeof (DHCP_PARAMETER), Para);\r
if (DhcpSb->Para == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
goto ON_EXIT;\r
}\r
\r
DhcpSb->Selected = Packet;\r
- CopyMem (DhcpSb->Para, Para, sizeof (*DhcpSb->Para));\r
-\r
Status = DhcpLeaseAcquired (DhcpSb);\r
-\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
return EFI_SUCCESS;\r
\r
ON_EXIT:\r
- NetFreePool (Packet);\r
+ FreePool (Packet);\r
return Status;\r
}\r
\r
\r
/**\r
- Handle the received DHCP packets. This function drivers the DHCP\r
+ Handle the received DHCP packets. This function drives the DHCP\r
state machine.\r
\r
@param UdpPacket The UDP packets received.\r
- @param Points The local/remote UDP access points\r
+ @param EndPoint The local/remote UDP access point\r
@param IoStatus The status of the UDP receive\r
@param Context The opaque parameter to the function.\r
\r
- @return None\r
-\r
**/\r
VOID\r
+EFIAPI\r
DhcpInput (\r
NET_BUF *UdpPacket,\r
- UDP_POINTS *Points,\r
+ UDP_END_POINT *EndPoint,\r
EFI_STATUS IoStatus,\r
VOID *Context\r
)\r
DhcpSb = (DHCP_SERVICE *) Context;\r
\r
//\r
- // Don't restart receive if error occurs or DHCP is destoried.\r
+ // Don't restart receive if error occurs or DHCP is destroyed.\r
//\r
if (EFI_ERROR (IoStatus)) {\r
return ;\r
- } else if (DhcpSb->ServiceState == DHCP_DESTORY) {\r
+ } else if (DhcpSb->ServiceState == DHCP_DESTROY) {\r
NetbufFree (UdpPacket);\r
return ;\r
}\r
// Copy the DHCP message to a continuous memory block\r
//\r
Len = sizeof (EFI_DHCP4_PACKET) + UdpPacket->TotalSize - sizeof (EFI_DHCP4_HEADER);\r
- Packet = (EFI_DHCP4_PACKET *) NetAllocatePool (Len);\r
+ Packet = (EFI_DHCP4_PACKET *) AllocatePool (Len);\r
\r
if (Packet == NULL) {\r
goto RESTART;\r
//\r
if ((Head->OpCode != BOOTP_REPLY) ||\r
(NTOHL (Head->Xid) != DhcpSb->Xid) ||\r
- !NET_MAC_EQUAL (&DhcpSb->Mac, Head->ClientHwAddr, DhcpSb->HwLen)) {\r
+ (CompareMem (DhcpSb->ClientAddressSendOut, Head->ClientHwAddr, Head->HwAddrLen) != 0)) {\r
goto RESTART;\r
}\r
\r
//\r
// Ignore the packet in INITREBOOT, INIT and BOUND states\r
//\r
- NetFreePool (Packet);\r
+ FreePool (Packet);\r
Status = EFI_SUCCESS;\r
break;\r
\r
}\r
\r
if (Para != NULL) {\r
- NetFreePool (Para);\r
+ FreePool (Para);\r
}\r
\r
Packet = NULL;\r
\r
if (EFI_ERROR (Status)) {\r
NetbufFree (UdpPacket);\r
+ UdpIoRecvDatagram (DhcpSb->UdpIo, DhcpInput, DhcpSb, 0);\r
DhcpEndSession (DhcpSb, Status);\r
return ;\r
}\r
NetbufFree (UdpPacket);\r
\r
if (Packet != NULL) {\r
- NetFreePool (Packet);\r
+ FreePool (Packet);\r
}\r
\r
Status = UdpIoRecvDatagram (DhcpSb->UdpIo, DhcpInput, DhcpSb, 0);\r
}\r
}\r
\r
-\r
-/**\r
- Release the packet.\r
-\r
- @param Arg The packet to release\r
-\r
- @return None\r
-\r
-**/\r
-VOID\r
-DhcpReleasePacket (\r
- IN VOID *Arg\r
- )\r
-{\r
- NetFreePool (Arg);\r
-}\r
-\r
-\r
/**\r
Release the net buffer when packet is sent.\r
\r
@param UdpPacket The UDP packets received.\r
- @param Points The local/remote UDP access points\r
+ @param EndPoint The local/remote UDP access point\r
@param IoStatus The status of the UDP receive\r
@param Context The opaque parameter to the function.\r
\r
- @return None\r
-\r
**/\r
VOID\r
+EFIAPI\r
DhcpOnPacketSent (\r
NET_BUF *Packet,\r
- UDP_POINTS *Points,\r
+ UDP_END_POINT *EndPoint,\r
EFI_STATUS IoStatus,\r
VOID *Context\r
)\r
the state (as defined in Figure 5. of the same RFC) before sending\r
a DHCP message. The table is adjusted accordingly.\r
\r
- @param DhcpSb The DHCP service instance\r
- @param Seed The seed packet which the new packet is based on\r
- @param Para The DHCP parameter of the Seed packet\r
- @param Type The message type to send\r
- @param Msg The human readable message to include in the packet\r
- sent.\r
+ @param[in] DhcpSb The DHCP service instance\r
+ @param[in] Seed The seed packet which the new packet is based on\r
+ @param[in] Para The DHCP parameter of the Seed packet\r
+ @param[in] Type The message type to send\r
+ @param[in] Msg The human readable message to include in the packet\r
+ sent.\r
\r
@retval EFI_OUT_OF_RESOURCES Failed to allocate resources for the packet\r
@retval EFI_ACCESS_DENIED Failed to transmit the packet through UDP\r
@retval EFI_SUCCESS The message is sent\r
+ @retval other Other error occurs\r
\r
**/\r
EFI_STATUS\r
EFI_DHCP4_PACKET *NewPacket;\r
EFI_DHCP4_HEADER *Head;\r
EFI_DHCP4_HEADER *SeedHead;\r
- UDP_IO_PORT *UdpIo;\r
- UDP_POINTS EndPoint;\r
+ UDP_IO *UdpIo;\r
+ UDP_END_POINT EndPoint;\r
NET_BUF *Wrap;\r
NET_FRAGMENT Frag;\r
EFI_STATUS Status;\r
Len += (UINT32)AsciiStrLen ((CHAR8 *) Msg);\r
}\r
\r
- Packet = NetAllocatePool (Len);\r
+ Packet = AllocatePool (Len);\r
\r
if (Packet == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
Head = &Packet->Dhcp4.Header;\r
- NetZeroMem (Head, sizeof (EFI_DHCP4_HEADER));\r
+ ZeroMem (Head, sizeof (EFI_DHCP4_HEADER));\r
\r
Head->OpCode = BOOTP_REQUEST;\r
Head->HwType = DhcpSb->HwType;\r
Head->Reserved = HTONS (0x8000); //Server, broadcast the message please.\r
\r
EFI_IP4 (Head->ClientAddr) = HTONL (DhcpSb->ClientAddr);\r
- NetCopyMem (Head->ClientHwAddr, DhcpSb->Mac.Addr, DhcpSb->HwLen);\r
+ CopyMem (Head->ClientHwAddr, DhcpSb->Mac.Addr, DhcpSb->HwLen);\r
+\r
+ if ((Type == DHCP_MSG_DECLINE) || (Type == DHCP_MSG_RELEASE)) {\r
+ Head->Seconds = 0;\r
+ } else if ((Type == DHCP_MSG_REQUEST) && (DhcpSb->DhcpState == Dhcp4Requesting)) {\r
+ //\r
+ // Use the same value as the original DHCPDISCOVER message.\r
+ //\r
+ Head->Seconds = DhcpSb->LastPacket->Dhcp4.Header.Seconds;\r
+ } else {\r
+ SetElapsedTime(&Head->Seconds, DhcpSb->ActiveChild);\r
+ }\r
\r
//\r
// Append the DHCP message type\r
//\r
Packet->Dhcp4.Magik = DHCP_OPTION_MAGIC;\r
Buf = Packet->Dhcp4.Option;\r
- Buf = DhcpAppendOption (Buf, DHCP_TAG_TYPE, 1, &Type);\r
+ Buf = DhcpAppendOption (Buf, DHCP4_TAG_MSG_TYPE, 1, &Type);\r
\r
//\r
// Append the serverid option if necessary:\r
// 3. DHCP request to confirm one lease.\r
//\r
if ((Type == DHCP_MSG_DECLINE) || (Type == DHCP_MSG_RELEASE) ||\r
- ((Type == DHCP_MSG_REQUEST) && (DhcpSb->DhcpState == Dhcp4Requesting))) {\r
+ ((Type == DHCP_MSG_REQUEST) && (DhcpSb->DhcpState == Dhcp4Requesting))\r
+ ) {\r
\r
ASSERT ((Para != NULL) && (Para->ServerId != 0));\r
\r
IpAddr = HTONL (Para->ServerId);\r
- Buf = DhcpAppendOption (Buf, DHCP_TAG_SERVER_ID, 4, (UINT8 *) &IpAddr);\r
+ Buf = DhcpAppendOption (Buf, DHCP4_TAG_SERVER_ID, 4, (UINT8 *) &IpAddr);\r
}\r
\r
//\r
}\r
\r
if (IpAddr != 0) {\r
- Buf = DhcpAppendOption (Buf, DHCP_TAG_REQUEST_IP, 4, (UINT8 *) &IpAddr);\r
+ Buf = DhcpAppendOption (Buf, DHCP4_TAG_REQUEST_IP, 4, (UINT8 *) &IpAddr);\r
}\r
\r
//\r
//\r
if ((Type != DHCP_MSG_DECLINE) && (Type != DHCP_MSG_RELEASE)) {\r
MaxMsg = HTONS (0xFF00);\r
- Buf = DhcpAppendOption (Buf, DHCP_TAG_MAXMSG, 2, (UINT8 *) &MaxMsg);\r
+ Buf = DhcpAppendOption (Buf, DHCP4_TAG_MAXMSG, 2, (UINT8 *) &MaxMsg);\r
}\r
\r
//\r
//\r
if (Msg != NULL) {\r
Len = MIN ((UINT32) AsciiStrLen ((CHAR8 *) Msg), 255);\r
- Buf = DhcpAppendOption (Buf, DHCP_TAG_MESSAGE, (UINT16) Len, Msg);\r
+ Buf = DhcpAppendOption (Buf, DHCP4_TAG_MESSAGE, (UINT16) Len, Msg);\r
}\r
\r
//\r
// if it is a DHCP decline or DHCP release .\r
//\r
if (((Type == DHCP_MSG_DECLINE) || (Type == DHCP_MSG_RELEASE)) &&\r
- (Config->OptionList[Index]->OpCode != DHCP_TAG_CLIENT_ID)) {\r
+ (Config->OptionList[Index]->OpCode != DHCP4_TAG_CLIENT_ID)) {\r
continue;\r
}\r
\r
}\r
}\r
\r
- *(Buf++) = DHCP_TAG_EOP;\r
+ *(Buf++) = DHCP4_TAG_EOP;\r
Packet->Length += (UINT32) (Buf - Packet->Dhcp4.Option);\r
\r
//\r
}\r
\r
if (EFI_ERROR (Status)) {\r
- NetFreePool (Packet);\r
+ FreePool (Packet);\r
return Status;\r
}\r
\r
if (NewPacket != NULL) {\r
- NetFreePool (Packet);\r
+ FreePool (Packet);\r
Packet = NewPacket;\r
}\r
\r
+ //\r
+ // Save the Client Address will be sent out\r
+ //\r
+ CopyMem (\r
+ &DhcpSb->ClientAddressSendOut[0],\r
+ &Packet->Dhcp4.Header.ClientHwAddr[0],\r
+ Packet->Dhcp4.Header.HwAddrLen\r
+ );\r
+\r
//\r
// Wrap it into a netbuf then send it.\r
//\r
Frag.Bulk = (UINT8 *) &Packet->Dhcp4.Header;\r
Frag.Len = Packet->Length;\r
- Wrap = NetbufFromExt (&Frag, 1, 0, 0, DhcpReleasePacket, Packet);\r
+ Wrap = NetbufFromExt (&Frag, 1, 0, 0, DhcpDummyExtFree, NULL);\r
\r
if (Wrap == NULL) {\r
- NetFreePool (Packet);\r
+ FreePool (Packet);\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
// Save it as the last sent packet for retransmission\r
//\r
if (DhcpSb->LastPacket != NULL) {\r
- NetbufFree (DhcpSb->LastPacket);\r
+ FreePool (DhcpSb->LastPacket);\r
}\r
\r
- NET_GET_REF (Wrap);\r
- DhcpSb->LastPacket = Wrap;\r
+ DhcpSb->LastPacket = Packet;\r
DhcpSetTransmitTimer (DhcpSb);\r
\r
//\r
// Broadcast the message, unless we know the server address.\r
// Use the lease UdpIo port to send the unicast packet.\r
//\r
- EndPoint.RemoteAddr = 0xffffffff;\r
- EndPoint.LocalAddr = 0;\r
- EndPoint.RemotePort = DHCP_SERVER_PORT;\r
- EndPoint.LocalPort = DHCP_CLIENT_PORT;\r
- UdpIo = DhcpSb->UdpIo;\r
+ EndPoint.RemoteAddr.Addr[0] = 0xffffffff;\r
+ EndPoint.LocalAddr.Addr[0] = 0;\r
+ EndPoint.RemotePort = DHCP_SERVER_PORT;\r
+ EndPoint.LocalPort = DHCP_CLIENT_PORT;\r
+ UdpIo = DhcpSb->UdpIo;\r
\r
if ((DhcpSb->DhcpState == Dhcp4Renewing) || (Type == DHCP_MSG_RELEASE)) {\r
- EndPoint.RemoteAddr = DhcpSb->ServerAddr;\r
- EndPoint.LocalAddr = DhcpSb->ClientAddr;\r
- UdpIo = DhcpSb->LeaseIoPort;\r
+ EndPoint.RemoteAddr.Addr[0] = DhcpSb->ServerAddr;\r
+ EndPoint.LocalAddr.Addr[0] = DhcpSb->ClientAddr;\r
+ UdpIo = DhcpSb->LeaseIoPort;\r
}\r
\r
ASSERT (UdpIo != NULL);\r
- Status = UdpIoSendDatagram (UdpIo, Wrap, &EndPoint, 0, DhcpOnPacketSent, DhcpSb);\r
+\r
+ Status = UdpIoSendDatagram (\r
+ UdpIo,\r
+ Wrap,\r
+ &EndPoint,\r
+ NULL,\r
+ DhcpOnPacketSent,\r
+ DhcpSb\r
+ );\r
\r
if (EFI_ERROR (Status)) {\r
NetbufFree (Wrap);\r
Retransmit a saved packet. Only DISCOVER and REQUEST messages\r
will be retransmitted.\r
\r
- @param DhcpSb The DHCP service instance\r
+ @param[in] DhcpSb The DHCP service instance\r
\r
@retval EFI_ACCESS_DENIED Failed to transmit packet through UDP port\r
@retval EFI_SUCCESS The packet is retransmitted.\r
IN DHCP_SERVICE *DhcpSb\r
)\r
{\r
- UDP_IO_PORT *UdpIo;\r
- UDP_POINTS EndPoint;\r
+ UDP_IO *UdpIo;\r
+ UDP_END_POINT EndPoint;\r
+ NET_BUF *Wrap;\r
+ NET_FRAGMENT Frag;\r
EFI_STATUS Status;\r
\r
ASSERT (DhcpSb->LastPacket != NULL);\r
\r
+ //\r
+ // For REQUEST message in Dhcp4Requesting state, do not change the secs fields.\r
+ //\r
+ if (DhcpSb->DhcpState != Dhcp4Requesting) {\r
+ SetElapsedTime(&DhcpSb->LastPacket->Dhcp4.Header.Seconds, DhcpSb->ActiveChild);\r
+ }\r
+\r
+ //\r
+ // Wrap it into a netbuf then send it.\r
+ //\r
+ Frag.Bulk = (UINT8 *) &DhcpSb->LastPacket->Dhcp4.Header;\r
+ Frag.Len = DhcpSb->LastPacket->Length;\r
+ Wrap = NetbufFromExt (&Frag, 1, 0, 0, DhcpDummyExtFree, NULL);\r
+\r
+ if (Wrap == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
//\r
// Broadcast the message, unless we know the server address.\r
//\r
- EndPoint.RemotePort = DHCP_SERVER_PORT;\r
- EndPoint.LocalPort = DHCP_CLIENT_PORT;\r
- EndPoint.RemoteAddr = 0xffffffff;\r
- EndPoint.LocalAddr = 0;\r
- UdpIo = DhcpSb->UdpIo;\r
+ EndPoint.RemotePort = DHCP_SERVER_PORT;\r
+ EndPoint.LocalPort = DHCP_CLIENT_PORT;\r
+ EndPoint.RemoteAddr.Addr[0] = 0xffffffff;\r
+ EndPoint.LocalAddr.Addr[0] = 0;\r
+ UdpIo = DhcpSb->UdpIo;\r
\r
if (DhcpSb->DhcpState == Dhcp4Renewing) {\r
- EndPoint.RemoteAddr = DhcpSb->ServerAddr;\r
- EndPoint.LocalAddr = DhcpSb->ClientAddr;\r
- UdpIo = DhcpSb->LeaseIoPort;\r
+ EndPoint.RemoteAddr.Addr[0] = DhcpSb->ServerAddr;\r
+ EndPoint.LocalAddr.Addr[0] = DhcpSb->ClientAddr;\r
+ UdpIo = DhcpSb->LeaseIoPort;\r
}\r
\r
ASSERT (UdpIo != NULL);\r
\r
- NET_GET_REF (DhcpSb->LastPacket);\r
Status = UdpIoSendDatagram (\r
UdpIo,\r
- DhcpSb->LastPacket,\r
+ Wrap,\r
&EndPoint,\r
- 0,\r
+ NULL,\r
DhcpOnPacketSent,\r
DhcpSb\r
);\r
\r
if (EFI_ERROR (Status)) {\r
- NET_PUT_REF (DhcpSb->LastPacket);\r
+ NetbufFree (Wrap);\r
return EFI_ACCESS_DENIED;\r
}\r
\r
and lease to determine the time to renew and rebind the lease.\r
DhcpOnTimerTick will be called once every second.\r
\r
- @param Event The timer event\r
- @param Context The context, which is the DHCP service instance.\r
-\r
- @return None\r
+ @param[in] Event The timer event\r
+ @param[in] Context The context, which is the DHCP service instance.\r
\r
**/\r
VOID\r
IN VOID *Context\r
)\r
{\r
+ LIST_ENTRY *Entry;\r
+ LIST_ENTRY *Next;\r
DHCP_SERVICE *DhcpSb;\r
DHCP_PROTOCOL *Instance;\r
EFI_STATUS Status;\r
- \r
+\r
DhcpSb = (DHCP_SERVICE *) Context;\r
Instance = DhcpSb->ActiveChild;\r
\r
//\r
- // Check the time to wait offer\r
+ // 0xffff is the maximum supported value for elapsed time according to RFC.\r
//\r
- if ((DhcpSb->WaitOffer > 0) && (--DhcpSb->WaitOffer == 0)) {\r
- //\r
- // OK, offer collection finished, select a offer\r
- //\r
- ASSERT (DhcpSb->DhcpState == Dhcp4Selecting);\r
-\r
- if (DhcpSb->LastOffer == NULL) {\r
- goto END_SESSION;\r
- }\r
-\r
- if (EFI_ERROR (DhcpChooseOffer (DhcpSb))) {\r
- goto END_SESSION;\r
- }\r
+ if (Instance != NULL && Instance->ElaspedTime < 0xffff) {\r
+ Instance->ElaspedTime++;\r
}\r
- \r
+\r
//\r
// Check the retransmit timer\r
//\r
if ((DhcpSb->PacketToLive > 0) && (--DhcpSb->PacketToLive == 0)) {\r
\r
+ //\r
+ // Select offer at each timeout if any offer received.\r
+ //\r
+ if (DhcpSb->DhcpState == Dhcp4Selecting && DhcpSb->LastOffer != NULL) {\r
+\r
+ Status = DhcpChooseOffer (DhcpSb);\r
+\r
+ if (EFI_ERROR(Status)) {\r
+ if (DhcpSb->LastOffer != NULL) {\r
+ FreePool (DhcpSb->LastOffer);\r
+ DhcpSb->LastOffer = NULL;\r
+ }\r
+ } else {\r
+ goto ON_EXIT;\r
+ }\r
+ }\r
+\r
if (++DhcpSb->CurRetry < DhcpSb->MaxRetries) {\r
//\r
// Still has another try\r
DhcpRetransmit (DhcpSb);\r
DhcpSetTransmitTimer (DhcpSb);\r
\r
- } else {\r
- if (!DHCP_CONNECTED (DhcpSb->DhcpState)) {\r
- goto END_SESSION;\r
- }\r
+ } else if (DHCP_CONNECTED (DhcpSb->DhcpState)) {\r
\r
//\r
// Retransmission failed, if the DHCP request is initiated by\r
// user, adjust the current state according to the lease life.\r
// Otherwise do nothing to wait the lease to timeout\r
//\r
- if (DhcpSb->ExtraRefresh) {\r
+ if (DhcpSb->ExtraRefresh != 0) {\r
Status = EFI_SUCCESS;\r
\r
if (DhcpSb->LeaseLife < DhcpSb->T1) {\r
DhcpSb->IoStatus = EFI_TIMEOUT;\r
DhcpNotifyUser (DhcpSb, DHCP_NOTIFY_RENEWREBIND);\r
}\r
+ } else {\r
+ goto END_SESSION;\r
}\r
}\r
- \r
+\r
//\r
// If an address has been acquired, check whether need to\r
// refresh or whether it has expired.\r
// Don't timeout the lease, only count the life if user is\r
// requesting extra renew/rebind. Adjust the state after that.\r
//\r
- if (DhcpSb->ExtraRefresh) {\r
+ if (DhcpSb->ExtraRefresh != 0) {\r
return ;\r
}\r
\r
goto END_SESSION;\r
}\r
\r
+ if (Instance != NULL) {\r
+ Instance->ElaspedTime= 0;\r
+ }\r
+\r
Status = DhcpSendMessage (\r
DhcpSb,\r
DhcpSb->Selected,\r
goto END_SESSION;\r
}\r
\r
+ if (Instance != NULL) {\r
+ Instance->ElaspedTime= 0;\r
+ }\r
+\r
Status = DhcpSendMessage (\r
DhcpSb,\r
DhcpSb->Selected,\r
}\r
}\r
\r
+ON_EXIT:\r
//\r
+ // Iterate through all the DhcpSb Children.\r
//\r
- //\r
- if ((Instance != NULL) && (Instance->Token != NULL)) {\r
+ NET_LIST_FOR_EACH_SAFE (Entry, Next, &DhcpSb->Children) {\r
+ Instance = NET_LIST_USER_STRUCT (Entry, DHCP_PROTOCOL, Link);\r
Instance->Timeout--;\r
- if (Instance->Timeout == 0) {\r
+ if (Instance->Timeout == 0 && Instance->Token != NULL) {\r
PxeDhcpDone (Instance);\r
}\r
}\r