X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FNetwork%2FDhcp4Dxe%2FDhcp4Io.c;h=4728b94c5803110d05bb2209032ef28643183841;hp=da42e670b5ce381f4770df7febe2c722a2a064e6;hb=c0fd7f734e2d33e22215899b40a47b843129541d;hpb=f92046412a466c208adbeb5e09e511a3a5e2ae31 diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c index da42e670b5..4728b94c58 100644 --- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c +++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c @@ -1,22 +1,8 @@ /** @file + EFI DHCP protocol implementation. -Copyright (c) 2006 - 2008, Intel Corporation -All rights reserved. This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - Dhcp4Io.c - -Abstract: - - EFI DHCP protocol implementation - +Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -30,7 +16,7 @@ UINT32 mDhcp4DefaultTimeout[4] = { 4, 8, 16, 32 }; Send an initial DISCOVER or REQUEST message according to the DHCP service's current state. - @param DhcpSb The DHCP service instance + @param[in] DhcpSb The DHCP service instance @retval EFI_SUCCESS The request has been sent @retval other Some error occurs when sending the request. @@ -45,6 +31,11 @@ DhcpInitRequest ( ASSERT ((DhcpSb->DhcpState == Dhcp4Init) || (DhcpSb->DhcpState == Dhcp4InitReboot)); + // + // Clear initial time to make sure that elapsed-time is set to 0 for first Discover or REQUEST message. + // + DhcpSb->ActiveChild->ElaspedTime= 0; + if (DhcpSb->DhcpState == Dhcp4Init) { DhcpSetState (DhcpSb, Dhcp4Selecting, FALSE); Status = DhcpSendMessage (DhcpSb, NULL, NULL, DHCP_MSG_DISCOVER, NULL); @@ -73,10 +64,10 @@ DhcpInitRequest ( proper return value is selected to let the caller continue the normal process. - @param DhcpSb The DHCP service instance - @param Event The event as defined in the spec - @param Packet The current packet trigger the event - @param NewPacket The user's return new packet + @param[in] DhcpSb The DHCP service instance + @param[in] Event The event as defined in the spec + @param[in] Packet The current packet trigger the event + @param[out] NewPacket The user's return new packet @retval EFI_NOT_READY Direct the caller to continue collecting the offer. @retval EFI_SUCCESS The user function returns success. @@ -143,8 +134,6 @@ DhcpCallUser ( @param DhcpSb DHCP service instance @param Which Which notify function to signal - @return None - **/ VOID DhcpNotifyUser ( @@ -237,7 +226,7 @@ DhcpSetState ( DhcpSb->CurRetry = 0; DhcpSb->PacketToLive = 0; - + DhcpSb->LastTimeout = 0; DhcpSb->DhcpState = State; return EFI_SUCCESS; } @@ -249,8 +238,6 @@ DhcpSetState ( @param DhcpSb The DHCP service instance. - @return None - **/ VOID DhcpSetTransmitTimer ( @@ -272,6 +259,7 @@ DhcpSetTransmitTimer ( } DhcpSb->PacketToLive = Times[DhcpSb->CurRetry]; + DhcpSb->LastTimeout = DhcpSb->PacketToLive; return; } @@ -284,9 +272,6 @@ DhcpSetTransmitTimer ( @param DhcpSb The DHCP service instance @param Para The DHCP parameter extracted from the server's response. - - @return None - **/ VOID DhcpComputeLease ( @@ -319,16 +304,17 @@ DhcpComputeLease ( DHCP driver needs this port to unicast packet to the server such as DHCP release. - @param UdpIo The UDP IO port to configure - @param Context Dhcp service instance. + @param[in] UdpIo The UDP IO to configure + @param[in] Context Dhcp service instance. @retval EFI_SUCCESS The UDP IO port is successfully configured. @retval Others It failed to configure the port. **/ EFI_STATUS +EFIAPI DhcpConfigLeaseIoPort ( - IN UDP_IO_PORT *UdpIo, + IN UDP_IO *UdpIo, IN VOID *Context ) { @@ -363,7 +349,7 @@ DhcpConfigLeaseIoPort ( ZeroMem (&UdpConfigData.RemoteAddress, sizeof (EFI_IPv4_ADDRESS)); - Status = UdpIo->Udp->Configure (UdpIo->Udp, &UdpConfigData); + Status = UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, &UdpConfigData); if (EFI_ERROR (Status)) { return Status; @@ -378,7 +364,7 @@ DhcpConfigLeaseIoPort ( Ip = HTONL (DhcpSb->Para->Router); CopyMem (&Gateway, &Ip, sizeof (EFI_IPv4_ADDRESS)); - UdpIo->Udp->Routes (UdpIo->Udp, FALSE, &Subnet, &Subnet, &Gateway); + UdpIo->Protocol.Udp4->Routes (UdpIo->Protocol.Udp4, FALSE, &Subnet, &Subnet, &Gateway); } return EFI_SUCCESS; @@ -401,8 +387,6 @@ DhcpLeaseAcquired ( IN OUT DHCP_SERVICE *DhcpSb ) { - INTN Class; - DhcpSb->ClientAddr = EFI_NTOHL (DhcpSb->Selected->Dhcp4.Header.YourAddr); if (DhcpSb->Para != NULL) { @@ -411,12 +395,11 @@ DhcpLeaseAcquired ( } if (DhcpSb->Netmask == 0) { - Class = NetGetIpClass (DhcpSb->ClientAddr); - DhcpSb->Netmask = gIp4AllMasks[Class << 3]; + return EFI_ABORTED; } if (DhcpSb->LeaseIoPort != NULL) { - UdpIoFreePort (DhcpSb->LeaseIoPort); + UdpIoFreeIo (DhcpSb->LeaseIoPort); } // @@ -424,10 +407,11 @@ DhcpLeaseAcquired ( // and transmit unicast packet with it as source address. Don't // start receive on this port, the queued packet will be timeout. // - DhcpSb->LeaseIoPort = UdpIoCreatePort ( + DhcpSb->LeaseIoPort = UdpIoCreateIo ( DhcpSb->Controller, DhcpSb->Image, DhcpConfigLeaseIoPort, + UDP_IO_UDP4_VERSION, DhcpSb ); @@ -448,8 +432,6 @@ DhcpLeaseAcquired ( @param DhcpSb The DHCP instance service. - @return None - **/ VOID DhcpCleanLease ( @@ -459,20 +441,21 @@ DhcpCleanLease ( DhcpSb->DhcpState = Dhcp4Init; DhcpSb->Xid = DhcpSb->Xid + 1; DhcpSb->ClientAddr = 0; + DhcpSb->Netmask = 0; DhcpSb->ServerAddr = 0; if (DhcpSb->LastOffer != NULL) { - gBS->FreePool (DhcpSb->LastOffer); + FreePool (DhcpSb->LastOffer); DhcpSb->LastOffer = NULL; } if (DhcpSb->Selected != NULL) { - gBS->FreePool (DhcpSb->Selected); + FreePool (DhcpSb->Selected); DhcpSb->Selected = NULL; } if (DhcpSb->Para != NULL) { - gBS->FreePool (DhcpSb->Para); + FreePool (DhcpSb->Para); DhcpSb->Para = NULL; } @@ -482,19 +465,25 @@ DhcpCleanLease ( DhcpSb->ExtraRefresh = FALSE; if (DhcpSb->LeaseIoPort != NULL) { - UdpIoFreePort (DhcpSb->LeaseIoPort); + UdpIoFreeIo (DhcpSb->LeaseIoPort); DhcpSb->LeaseIoPort = NULL; } if (DhcpSb->LastPacket != NULL) { - NetbufFree (DhcpSb->LastPacket); + FreePool (DhcpSb->LastPacket); DhcpSb->LastPacket = NULL; } DhcpSb->PacketToLive = 0; + DhcpSb->LastTimeout = 0; DhcpSb->CurRetry = 0; DhcpSb->MaxRetries = 0; DhcpSb->LeaseLife = 0; + + // + // Clean active config data. + // + DhcpCleanConfigure (&DhcpSb->ActiveConfig); } @@ -503,7 +492,7 @@ DhcpCleanLease ( of BOOTP, the lease is recorded and user notified. If the offer is of DHCP, it will request the offer from the server. - @param DhcpSb The DHCP service instance. + @param[in] DhcpSb The DHCP service instance. @retval EFI_SUCCESS One of the offer is selected. @@ -538,7 +527,7 @@ DhcpChooseOffer ( TempPacket = (EFI_DHCP4_PACKET *) AllocatePool (NewPacket->Size); if (TempPacket != NULL) { CopyMem (TempPacket, NewPacket, NewPacket->Size); - gBS->FreePool (Selected); + FreePool (Selected); Selected = TempPacket; } } @@ -583,10 +572,8 @@ DhcpChooseOffer ( to this is: only call DhcpEndSession at the highest level, such as DhcpInput, DhcpOnTimerTick...At the other level, just return error. - @param DhcpSb The DHCP service instance - @param Status The result of the DHCP process. - - @return None + @param[in] DhcpSb The DHCP service instance + @param[in] Status The result of the DHCP process. **/ VOID @@ -611,10 +598,10 @@ DhcpEndSession ( /** Handle packets in DHCP select state. - @param DhcpSb The DHCP service instance - @param Packet The DHCP packet received - @param Para The DHCP parameter extracted from the packet. That - is, all the option value that we care. + @param[in] DhcpSb The DHCP service instance + @param[in] Packet The DHCP packet received + @param[in] Para The DHCP parameter extracted from the packet. That + is, all the option value that we care. @retval EFI_SUCCESS The packet is successfully processed. @retval Others Some error occured. @@ -653,7 +640,7 @@ DhcpHandleSelect ( if (Status == EFI_SUCCESS) { if (DhcpSb->LastOffer != NULL) { - gBS->FreePool (DhcpSb->LastOffer); + FreePool (DhcpSb->LastOffer); } DhcpSb->LastOffer = Packet; @@ -662,7 +649,7 @@ DhcpHandleSelect ( } else if (Status == EFI_NOT_READY) { if (DhcpSb->LastOffer != NULL) { - gBS->FreePool (DhcpSb->LastOffer); + FreePool (DhcpSb->LastOffer); } DhcpSb->LastOffer = Packet; @@ -678,7 +665,7 @@ DhcpHandleSelect ( return EFI_SUCCESS; ON_EXIT: - gBS->FreePool (Packet); + FreePool (Packet); return Status; } @@ -686,10 +673,10 @@ ON_EXIT: /** Handle packets in DHCP request state. - @param DhcpSb The DHCP service instance - @param Packet The DHCP packet received - @param Para The DHCP parameter extracted from the packet. That - is, all the option value that we care. + @param[in] DhcpSb The DHCP service instance + @param[in] Packet The DHCP packet received + @param[in] Para The DHCP parameter extracted from the packet. That + is, all the option value that we care. @retval EFI_SUCCESS The packet is successfully processed. @retval Others Some error occured. @@ -764,14 +751,14 @@ DhcpHandleRequest ( DhcpSb->IoStatus = EFI_SUCCESS; DhcpNotifyUser (DhcpSb, DHCP_NOTIFY_COMPLETION); - gBS->FreePool (Packet); + FreePool (Packet); return EFI_SUCCESS; REJECT: DhcpSendMessage (DhcpSb, DhcpSb->Selected, DhcpSb->Para, DHCP_MSG_DECLINE, Message); ON_EXIT: - gBS->FreePool (Packet); + FreePool (Packet); return Status; } @@ -779,10 +766,10 @@ ON_EXIT: /** Handle packets in DHCP renew/rebound state. - @param DhcpSb The DHCP service instance - @param Packet The DHCP packet received - @param Para The DHCP parameter extracted from the packet. That - is, all the option value that we care. + @param[in] DhcpSb The DHCP service instance + @param[in] Packet The DHCP packet received + @param[in] Para The DHCP parameter extracted from the packet. That + is, all the option value that we care. @retval EFI_SUCCESS The packet is successfully processed. @retval Others Some error occured. @@ -855,7 +842,7 @@ DhcpHandleRenewRebind ( } ON_EXIT: - gBS->FreePool (Packet); + FreePool (Packet); return Status; } @@ -863,10 +850,10 @@ ON_EXIT: /** Handle packets in DHCP reboot state. - @param DhcpSb The DHCP service instance - @param Packet The DHCP packet received - @param Para The DHCP parameter extracted from the packet. That - is, all the option value that we care. + @param[in] DhcpSb The DHCP service instance + @param[in] Packet The DHCP packet received + @param[in] Para The DHCP parameter extracted from the packet. That + is, all the option value that we care. @retval EFI_SUCCESS The packet is successfully processed. @retval Others Some error occured. @@ -924,18 +911,14 @@ DhcpHandleReboot ( // // OK, get the parameter from server, record the lease // - DhcpSb->Para = AllocatePool (sizeof (DHCP_PARAMETER)); - + DhcpSb->Para = AllocateCopyPool (sizeof (DHCP_PARAMETER), Para); if (DhcpSb->Para == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } DhcpSb->Selected = Packet; - CopyMem (DhcpSb->Para, Para, sizeof (*DhcpSb->Para)); - Status = DhcpLeaseAcquired (DhcpSb); - if (EFI_ERROR (Status)) { return Status; } @@ -945,7 +928,7 @@ DhcpHandleReboot ( return EFI_SUCCESS; ON_EXIT: - gBS->FreePool (Packet); + FreePool (Packet); return Status; } @@ -955,17 +938,16 @@ ON_EXIT: state machine. @param UdpPacket The UDP packets received. - @param Points The local/remote UDP access points + @param EndPoint The local/remote UDP access point @param IoStatus The status of the UDP receive @param Context The opaque parameter to the function. - @return None - **/ VOID +EFIAPI DhcpInput ( NET_BUF *UdpPacket, - UDP_POINTS *Points, + UDP_END_POINT *EndPoint, EFI_STATUS IoStatus, VOID *Context ) @@ -981,11 +963,11 @@ DhcpInput ( DhcpSb = (DHCP_SERVICE *) Context; // - // Don't restart receive if error occurs or DHCP is destoried. + // Don't restart receive if error occurs or DHCP is destroyed. // if (EFI_ERROR (IoStatus)) { return ; - } else if (DhcpSb->ServiceState == DHCP_DESTORY) { + } else if (DhcpSb->ServiceState == DHCP_DESTROY) { NetbufFree (UdpPacket); return ; } @@ -1067,7 +1049,7 @@ DhcpInput ( // // Ignore the packet in INITREBOOT, INIT and BOUND states // - gBS->FreePool (Packet); + FreePool (Packet); Status = EFI_SUCCESS; break; @@ -1082,13 +1064,14 @@ DhcpInput ( } if (Para != NULL) { - gBS->FreePool (Para); + FreePool (Para); } Packet = NULL; if (EFI_ERROR (Status)) { NetbufFree (UdpPacket); + UdpIoRecvDatagram (DhcpSb->UdpIo, DhcpInput, DhcpSb, 0); DhcpEndSession (DhcpSb, Status); return ; } @@ -1097,7 +1080,7 @@ RESTART: NetbufFree (UdpPacket); if (Packet != NULL) { - gBS->FreePool (Packet); + FreePool (Packet); } Status = UdpIoRecvDatagram (DhcpSb->UdpIo, DhcpInput, DhcpSb, 0); @@ -1107,39 +1090,20 @@ RESTART: } } - -/** - Release the packet. - - @param Arg The packet to release - - @return None - -**/ -VOID -DhcpReleasePacket ( - IN VOID *Arg - ) -{ - gBS->FreePool (Arg); -} - - /** Release the net buffer when packet is sent. @param UdpPacket The UDP packets received. - @param Points The local/remote UDP access points + @param EndPoint The local/remote UDP access point @param IoStatus The status of the UDP receive @param Context The opaque parameter to the function. - @return None - **/ VOID +EFIAPI DhcpOnPacketSent ( NET_BUF *Packet, - UDP_POINTS *Points, + UDP_END_POINT *EndPoint, EFI_STATUS IoStatus, VOID *Context ) @@ -1155,12 +1119,12 @@ DhcpOnPacketSent ( the state (as defined in Figure 5. of the same RFC) before sending a DHCP message. The table is adjusted accordingly. - @param DhcpSb The DHCP service instance - @param Seed The seed packet which the new packet is based on - @param Para The DHCP parameter of the Seed packet - @param Type The message type to send - @param Msg The human readable message to include in the packet - sent. + @param[in] DhcpSb The DHCP service instance + @param[in] Seed The seed packet which the new packet is based on + @param[in] Para The DHCP parameter of the Seed packet + @param[in] Type The message type to send + @param[in] Msg The human readable message to include in the packet + sent. @retval EFI_OUT_OF_RESOURCES Failed to allocate resources for the packet @retval EFI_ACCESS_DENIED Failed to transmit the packet through UDP @@ -1182,8 +1146,8 @@ DhcpSendMessage ( EFI_DHCP4_PACKET *NewPacket; EFI_DHCP4_HEADER *Head; EFI_DHCP4_HEADER *SeedHead; - UDP_IO_PORT *UdpIo; - UDP_POINTS EndPoint; + UDP_IO *UdpIo; + UDP_END_POINT EndPoint; NET_BUF *Wrap; NET_FRAGMENT Frag; EFI_STATUS Status; @@ -1233,12 +1197,23 @@ DhcpSendMessage ( EFI_IP4 (Head->ClientAddr) = HTONL (DhcpSb->ClientAddr); CopyMem (Head->ClientHwAddr, DhcpSb->Mac.Addr, DhcpSb->HwLen); + if ((Type == DHCP_MSG_DECLINE) || (Type == DHCP_MSG_RELEASE)) { + Head->Seconds = 0; + } else if ((Type == DHCP_MSG_REQUEST) && (DhcpSb->DhcpState == Dhcp4Requesting)) { + // + // Use the same value as the original DHCPDISCOVER message. + // + Head->Seconds = DhcpSb->LastPacket->Dhcp4.Header.Seconds; + } else { + SetElapsedTime(&Head->Seconds, DhcpSb->ActiveChild); + } + // // Append the DHCP message type // Packet->Dhcp4.Magik = DHCP_OPTION_MAGIC; Buf = Packet->Dhcp4.Option; - Buf = DhcpAppendOption (Buf, DHCP_TAG_TYPE, 1, &Type); + Buf = DhcpAppendOption (Buf, DHCP4_TAG_MSG_TYPE, 1, &Type); // // Append the serverid option if necessary: @@ -1253,7 +1228,7 @@ DhcpSendMessage ( ASSERT ((Para != NULL) && (Para->ServerId != 0)); IpAddr = HTONL (Para->ServerId); - Buf = DhcpAppendOption (Buf, DHCP_TAG_SERVER_ID, 4, (UINT8 *) &IpAddr); + Buf = DhcpAppendOption (Buf, DHCP4_TAG_SERVER_ID, 4, (UINT8 *) &IpAddr); } // @@ -1279,7 +1254,7 @@ DhcpSendMessage ( } if (IpAddr != 0) { - Buf = DhcpAppendOption (Buf, DHCP_TAG_REQUEST_IP, 4, (UINT8 *) &IpAddr); + Buf = DhcpAppendOption (Buf, DHCP4_TAG_REQUEST_IP, 4, (UINT8 *) &IpAddr); } // @@ -1289,7 +1264,7 @@ DhcpSendMessage ( // if ((Type != DHCP_MSG_DECLINE) && (Type != DHCP_MSG_RELEASE)) { MaxMsg = HTONS (0xFF00); - Buf = DhcpAppendOption (Buf, DHCP_TAG_MAXMSG, 2, (UINT8 *) &MaxMsg); + Buf = DhcpAppendOption (Buf, DHCP4_TAG_MAXMSG, 2, (UINT8 *) &MaxMsg); } // @@ -1297,7 +1272,7 @@ DhcpSendMessage ( // if (Msg != NULL) { Len = MIN ((UINT32) AsciiStrLen ((CHAR8 *) Msg), 255); - Buf = DhcpAppendOption (Buf, DHCP_TAG_MESSAGE, (UINT16) Len, Msg); + Buf = DhcpAppendOption (Buf, DHCP4_TAG_MESSAGE, (UINT16) Len, Msg); } // @@ -1310,7 +1285,7 @@ DhcpSendMessage ( // if it is a DHCP decline or DHCP release . // if (((Type == DHCP_MSG_DECLINE) || (Type == DHCP_MSG_RELEASE)) && - (Config->OptionList[Index]->OpCode != DHCP_TAG_CLIENT_ID)) { + (Config->OptionList[Index]->OpCode != DHCP4_TAG_CLIENT_ID)) { continue; } @@ -1323,7 +1298,7 @@ DhcpSendMessage ( } } - *(Buf++) = DHCP_TAG_EOP; + *(Buf++) = DHCP4_TAG_EOP; Packet->Length += (UINT32) (Buf - Packet->Dhcp4.Option); // @@ -1343,12 +1318,12 @@ DhcpSendMessage ( } if (EFI_ERROR (Status)) { - gBS->FreePool (Packet); + FreePool (Packet); return Status; } if (NewPacket != NULL) { - gBS->FreePool (Packet); + FreePool (Packet); Packet = NewPacket; } @@ -1361,16 +1336,15 @@ DhcpSendMessage ( Packet->Dhcp4.Header.HwAddrLen ); - // // Wrap it into a netbuf then send it. // Frag.Bulk = (UINT8 *) &Packet->Dhcp4.Header; Frag.Len = Packet->Length; - Wrap = NetbufFromExt (&Frag, 1, 0, 0, DhcpReleasePacket, Packet); + Wrap = NetbufFromExt (&Frag, 1, 0, 0, DhcpDummyExtFree, NULL); if (Wrap == NULL) { - gBS->FreePool (Packet); + FreePool (Packet); return EFI_OUT_OF_RESOURCES; } @@ -1378,31 +1352,38 @@ DhcpSendMessage ( // Save it as the last sent packet for retransmission // if (DhcpSb->LastPacket != NULL) { - NetbufFree (DhcpSb->LastPacket); + FreePool (DhcpSb->LastPacket); } - NET_GET_REF (Wrap); - DhcpSb->LastPacket = Wrap; + DhcpSb->LastPacket = Packet; DhcpSetTransmitTimer (DhcpSb); // // Broadcast the message, unless we know the server address. // Use the lease UdpIo port to send the unicast packet. // - EndPoint.RemoteAddr = 0xffffffff; - EndPoint.LocalAddr = 0; - EndPoint.RemotePort = DHCP_SERVER_PORT; - EndPoint.LocalPort = DHCP_CLIENT_PORT; - UdpIo = DhcpSb->UdpIo; + EndPoint.RemoteAddr.Addr[0] = 0xffffffff; + EndPoint.LocalAddr.Addr[0] = 0; + EndPoint.RemotePort = DHCP_SERVER_PORT; + EndPoint.LocalPort = DHCP_CLIENT_PORT; + UdpIo = DhcpSb->UdpIo; if ((DhcpSb->DhcpState == Dhcp4Renewing) || (Type == DHCP_MSG_RELEASE)) { - EndPoint.RemoteAddr = DhcpSb->ServerAddr; - EndPoint.LocalAddr = DhcpSb->ClientAddr; - UdpIo = DhcpSb->LeaseIoPort; + EndPoint.RemoteAddr.Addr[0] = DhcpSb->ServerAddr; + EndPoint.LocalAddr.Addr[0] = DhcpSb->ClientAddr; + UdpIo = DhcpSb->LeaseIoPort; } ASSERT (UdpIo != NULL); - Status = UdpIoSendDatagram (UdpIo, Wrap, &EndPoint, 0, DhcpOnPacketSent, DhcpSb); + + Status = UdpIoSendDatagram ( + UdpIo, + Wrap, + &EndPoint, + NULL, + DhcpOnPacketSent, + DhcpSb + ); if (EFI_ERROR (Status)) { NetbufFree (Wrap); @@ -1417,7 +1398,7 @@ DhcpSendMessage ( Retransmit a saved packet. Only DISCOVER and REQUEST messages will be retransmitted. - @param DhcpSb The DHCP service instance + @param[in] DhcpSb The DHCP service instance @retval EFI_ACCESS_DENIED Failed to transmit packet through UDP port @retval EFI_SUCCESS The packet is retransmitted. @@ -1428,41 +1409,60 @@ DhcpRetransmit ( IN DHCP_SERVICE *DhcpSb ) { - UDP_IO_PORT *UdpIo; - UDP_POINTS EndPoint; + UDP_IO *UdpIo; + UDP_END_POINT EndPoint; + NET_BUF *Wrap; + NET_FRAGMENT Frag; EFI_STATUS Status; ASSERT (DhcpSb->LastPacket != NULL); + // + // For REQUEST message in Dhcp4Requesting state, do not change the secs fields. + // + if (DhcpSb->DhcpState != Dhcp4Requesting) { + SetElapsedTime(&DhcpSb->LastPacket->Dhcp4.Header.Seconds, DhcpSb->ActiveChild); + } + + // + // Wrap it into a netbuf then send it. + // + Frag.Bulk = (UINT8 *) &DhcpSb->LastPacket->Dhcp4.Header; + Frag.Len = DhcpSb->LastPacket->Length; + Wrap = NetbufFromExt (&Frag, 1, 0, 0, DhcpDummyExtFree, NULL); + + if (Wrap == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // // Broadcast the message, unless we know the server address. // - EndPoint.RemotePort = DHCP_SERVER_PORT; - EndPoint.LocalPort = DHCP_CLIENT_PORT; - EndPoint.RemoteAddr = 0xffffffff; - EndPoint.LocalAddr = 0; - UdpIo = DhcpSb->UdpIo; + EndPoint.RemotePort = DHCP_SERVER_PORT; + EndPoint.LocalPort = DHCP_CLIENT_PORT; + EndPoint.RemoteAddr.Addr[0] = 0xffffffff; + EndPoint.LocalAddr.Addr[0] = 0; + UdpIo = DhcpSb->UdpIo; if (DhcpSb->DhcpState == Dhcp4Renewing) { - EndPoint.RemoteAddr = DhcpSb->ServerAddr; - EndPoint.LocalAddr = DhcpSb->ClientAddr; - UdpIo = DhcpSb->LeaseIoPort; + EndPoint.RemoteAddr.Addr[0] = DhcpSb->ServerAddr; + EndPoint.LocalAddr.Addr[0] = DhcpSb->ClientAddr; + UdpIo = DhcpSb->LeaseIoPort; } ASSERT (UdpIo != NULL); - NET_GET_REF (DhcpSb->LastPacket); Status = UdpIoSendDatagram ( UdpIo, - DhcpSb->LastPacket, + Wrap, &EndPoint, - 0, + NULL, DhcpOnPacketSent, DhcpSb ); if (EFI_ERROR (Status)) { - NET_PUT_REF (DhcpSb->LastPacket); + NetbufFree (Wrap); return EFI_ACCESS_DENIED; } @@ -1477,10 +1477,8 @@ DhcpRetransmit ( and lease to determine the time to renew and rebind the lease. DhcpOnTimerTick will be called once every second. - @param Event The timer event - @param Context The context, which is the DHCP service instance. - - @return None + @param[in] Event The timer event + @param[in] Context The context, which is the DHCP service instance. **/ VOID @@ -1490,13 +1488,22 @@ DhcpOnTimerTick ( IN VOID *Context ) { + LIST_ENTRY *Entry; + LIST_ENTRY *Next; DHCP_SERVICE *DhcpSb; DHCP_PROTOCOL *Instance; EFI_STATUS Status; DhcpSb = (DHCP_SERVICE *) Context; Instance = DhcpSb->ActiveChild; - + + // + // 0xffff is the maximum supported value for elapsed time according to RFC. + // + if (Instance != NULL && Instance->ElaspedTime < 0xffff) { + Instance->ElaspedTime++; + } + // // Check the retransmit timer // @@ -1510,13 +1517,15 @@ DhcpOnTimerTick ( Status = DhcpChooseOffer (DhcpSb); if (EFI_ERROR(Status)) { - FreePool (DhcpSb->LastOffer); - DhcpSb->LastOffer = NULL; + if (DhcpSb->LastOffer != NULL) { + FreePool (DhcpSb->LastOffer); + DhcpSb->LastOffer = NULL; + } } else { goto ON_EXIT; } } - + if (++DhcpSb->CurRetry < DhcpSb->MaxRetries) { // // Still has another try @@ -1555,7 +1564,7 @@ DhcpOnTimerTick ( goto END_SESSION; } } - + // // If an address has been acquired, check whether need to // refresh or whether it has expired. @@ -1585,6 +1594,10 @@ DhcpOnTimerTick ( goto END_SESSION; } + if (Instance != NULL) { + Instance->ElaspedTime= 0; + } + Status = DhcpSendMessage ( DhcpSb, DhcpSb->Selected, @@ -1605,6 +1618,10 @@ DhcpOnTimerTick ( goto END_SESSION; } + if (Instance != NULL) { + Instance->ElaspedTime= 0; + } + Status = DhcpSendMessage ( DhcpSb, DhcpSb->Selected, @@ -1620,9 +1637,13 @@ DhcpOnTimerTick ( } ON_EXIT: - if ((Instance != NULL) && (Instance->Token != NULL)) { + // + // Iterate through all the DhcpSb Children. + // + NET_LIST_FOR_EACH_SAFE (Entry, Next, &DhcpSb->Children) { + Instance = NET_LIST_USER_STRUCT (Entry, DHCP_PROTOCOL, Link); Instance->Timeout--; - if (Instance->Timeout == 0) { + if (Instance->Timeout == 0 && Instance->Token != NULL) { PxeDhcpDone (Instance); } }