/** @file\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
+ EFI DHCP protocol implementation.\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
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
-\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
DhcpSb->DhcpState = Dhcp4Init;\r
return Status;\r
}\r
-\r
- DhcpSb->WaitOffer = DHCP_WAIT_OFFER;\r
} else {\r
DhcpSetState (DhcpSb, Dhcp4Rebooting, FALSE);\r
Status = DhcpSendMessage (DhcpSb, NULL, NULL, DHCP_MSG_REQUEST, 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
// This will clear the retry count. This is also why the rule\r
// first transit the state, then send packets.\r
//\r
- if (State == Dhcp4Init) {\r
+ if (State == Dhcp4Selecting) {\r
DhcpSb->MaxRetries = DhcpSb->ActiveConfig.DiscoverTryCount;\r
} else {\r
DhcpSb->MaxRetries = DhcpSb->ActiveConfig.RequestTryCount;\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
ASSERT (DhcpSb->MaxRetries > DhcpSb->CurRetry);\r
\r
- if (DhcpSb->DhcpState == Dhcp4Init) {\r
+ if (DhcpSb->DhcpState == Dhcp4Selecting) {\r
Times = DhcpSb->ActiveConfig.DiscoverTimeout;\r
} else {\r
Times = DhcpSb->ActiveConfig.RequestTimeout;\r
}\r
\r
DhcpSb->PacketToLive = Times[DhcpSb->CurRetry];\r
-}\r
+ DhcpSb->LastTimeout = DhcpSb->PacketToLive;\r
\r
+ return;\r
+}\r
\r
/**\r
Compute the lease. If the server grants a permanent lease, just\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
if (DhcpSb->Netmask == 0) {\r
Class = NetGetIpClass (DhcpSb->ClientAddr);\r
- DhcpSb->Netmask = mIp4AllMasks[Class << 3];\r
+ DhcpSb->Netmask = gIp4AllMasks[Class << 3];\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
EFI_DHCP4_PACKET *Selected;\r
EFI_DHCP4_PACKET *NewPacket;\r
+ EFI_DHCP4_PACKET *TempPacket;\r
EFI_STATUS Status;\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
\r
Selected = DhcpSb->LastOffer;\r
\r
- if (NewPacket != NULL) {\r
- if (EFI_ERROR (DhcpValidateOptions (NewPacket, NULL))) {\r
- NetFreePool (NewPacket);\r
- } else {\r
- NetFreePool (Selected);\r
- Selected = NewPacket;\r
+ if ((NewPacket != NULL) && !EFI_ERROR (DhcpValidateOptions (NewPacket, NULL))) {\r
+ TempPacket = (EFI_DHCP4_PACKET *) AllocatePool (NewPacket->Size);\r
+ if (TempPacket != NULL) {\r
+ CopyMem (TempPacket, NewPacket, NewPacket->Size);\r
+ FreePool (Selected);\r
+ Selected = TempPacket;\r
}\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 (!Ip4IsUnicast (EFI_NTOHL (Head->YourAddr), (Para == NULL ? 0 : Para->NetMask))) {\r
- goto ON_EXIT;\r
- }\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
Message = NULL;\r
\r
if (!EFI_IP4_EQUAL (&Head->YourAddr, &Selected->YourAddr)) {\r
- Message = "Lease confirmed isn't the same as that in the offer";\r
+ Message = (UINT8 *) "Lease confirmed isn't the same as that in the offer";\r
goto REJECT;\r
}\r
\r
Status = DhcpCallUser (DhcpSb, Dhcp4RcvdAck, Packet, NULL);\r
\r
if (EFI_ERROR (Status)) {\r
- Message = "Lease is denied upon received ACK";\r
+ Message = (UINT8 *) "Lease is denied upon received ACK";\r
goto REJECT;\r
}\r
\r
Status = DhcpLeaseAcquired (DhcpSb);\r
\r
if (EFI_ERROR (Status)) {\r
- Message = "Lease is denied upon entering bound";\r
+ Message = (UINT8 *) "Lease is denied upon entering bound";\r
goto REJECT;\r
}\r
\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
// 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
Release the packet.\r
\r
- @param Arg The packet to release\r
-\r
- @return None\r
+ @param[in] Arg The packet to release\r
\r
**/\r
VOID\r
+EFIAPI\r
DhcpReleasePacket (\r
IN VOID *Arg\r
)\r
{\r
- NetFreePool (Arg);\r
+ FreePool (Arg);\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
//\r
// Append the DHCP message type\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
// Append the user's message if it isn't NULL\r
//\r
if (Msg != NULL) {\r
- Len = NET_MIN ((UINT32) AsciiStrLen ((CHAR8 *) Msg), 255);\r
+ Len = MIN ((UINT32) AsciiStrLen ((CHAR8 *) Msg), 255);\r
Buf = DhcpAppendOption (Buf, DHCP_TAG_MESSAGE, (UINT16) Len, Msg);\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
//\r
// Wrap it into a netbuf then send it.\r
//\r
Wrap = NetbufFromExt (&Frag, 1, 0, 0, DhcpReleasePacket, Packet);\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
+ NET_GET_REF (Wrap);\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
+ NET_PUT_REF (Wrap);\r
return EFI_ACCESS_DENIED;\r
}\r
\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
+ DhcpSb->LastPacket->Dhcp4.Header.Seconds = HTONS (*(UINT16 *)(&DhcpSb->LastTimeout));\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, DhcpReleasePacket, DhcpSb->LastPacket);\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
+ NET_GET_REF (Wrap);\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
+ NET_PUT_REF (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
)\r
{\r
DHCP_SERVICE *DhcpSb;\r
+ DHCP_PROTOCOL *Instance;\r
EFI_STATUS Status;\r
\r
- DhcpSb = (DHCP_SERVICE *) Context;\r
-\r
+ DhcpSb = (DHCP_SERVICE *) Context;\r
+ Instance = DhcpSb->ActiveChild;\r
+ \r
//\r
- // Check the retransmit timer first\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
+ FreePool (DhcpSb->LastOffer);\r
+ DhcpSb->LastOffer = NULL;\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
- }\r
- }\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
+ } 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
}\r
}\r
\r
+ON_EXIT:\r
+ if ((Instance != NULL) && (Instance->Token != NULL)) {\r
+ Instance->Timeout--;\r
+ if (Instance->Timeout == 0) {\r
+ PxeDhcpDone (Instance);\r
+ }\r
+ }\r
+\r
return ;\r
\r
END_SESSION:\r