From 434ce3feca7f5a430db3d5853c54a06343d02ed2 Mon Sep 17 00:00:00 2001 From: vanjeff Date: Mon, 8 Jun 2009 02:13:36 +0000 Subject: [PATCH] sync tracker:PXE misused the parameter of second since boot in DHCP header. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8496 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Universal/Network/Dhcp4Dxe/Dhcp4Impl.h | 5 +- .../Universal/Network/Dhcp4Dxe/Dhcp4Io.c | 47 ++++++-- .../Network/UefiPxeBcDxe/PxeBcDhcp.c | 13 +- .../Network/UefiPxeBcDxe/PxeBcImpl.c | 113 ++++++++---------- 4 files changed, 97 insertions(+), 81 deletions(-) diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h index fa75215dad..36f3ecb819 100644 --- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h +++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h @@ -6,7 +6,7 @@ RFC 1534: Interoperation Between DHCP and BOOTP RFC 3396: Encoding Long Options in DHCP. -Copyright (c) 2006 - 2008, Intel Corporation.
+Copyright (c) 2006 - 2009, 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 @@ -110,7 +110,7 @@ struct _DHCP_SERVICE { UDP_IO_PORT *UdpIo; // Udp child receiving all DHCP message UDP_IO_PORT *LeaseIoPort; // Udp child with lease IP - NET_BUF *LastPacket; // The last sent packet for retransmission + EFI_DHCP4_PACKET *LastPacket; // The last sent packet for retransmission EFI_MAC_ADDRESS Mac; UINT8 HwType; UINT8 HwLen; @@ -126,6 +126,7 @@ struct _DHCP_SERVICE { EFI_EVENT Timer; UINT32 PacketToLive; // Retransmission timer for our packets + UINT32 LastTimeout; // Record the init value of PacketToLive every time INTN CurRetry; INTN MaxRetries; UINT32 LeaseLife; diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c index 7c48340d8b..dc9b0412a8 100644 --- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c +++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c @@ -1,7 +1,7 @@ /** @file EFI DHCP protocol implementation. -Copyright (c) 2006 - 2008, Intel Corporation.
+Copyright (c) 2006 - 2009, 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 @@ -227,7 +227,7 @@ DhcpSetState ( DhcpSb->CurRetry = 0; DhcpSb->PacketToLive = 0; - + DhcpSb->LastTimeout = 0; DhcpSb->DhcpState = State; return EFI_SUCCESS; } @@ -260,6 +260,7 @@ DhcpSetTransmitTimer ( } DhcpSb->PacketToLive = Times[DhcpSb->CurRetry]; + DhcpSb->LastTimeout = DhcpSb->PacketToLive; return; } @@ -470,11 +471,12 @@ DhcpCleanLease ( } 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; @@ -1353,11 +1355,10 @@ 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); // @@ -1377,10 +1378,19 @@ DhcpSendMessage ( } ASSERT (UdpIo != NULL); - Status = UdpIoSendDatagram (UdpIo, Wrap, &EndPoint, 0, DhcpOnPacketSent, DhcpSb); + NET_GET_REF (Wrap); + + Status = UdpIoSendDatagram ( + UdpIo, + Wrap, + &EndPoint, + 0, + DhcpOnPacketSent, + DhcpSb + ); if (EFI_ERROR (Status)) { - NetbufFree (Wrap); + NET_PUT_REF (Wrap); return EFI_ACCESS_DENIED; } @@ -1405,10 +1415,25 @@ DhcpRetransmit ( { UDP_IO_PORT *UdpIo; UDP_POINTS EndPoint; + NET_BUF *Wrap; + NET_FRAGMENT Frag; EFI_STATUS Status; ASSERT (DhcpSb->LastPacket != NULL); + DhcpSb->LastPacket->Dhcp4.Header.Seconds = HTONS (*(UINT16 *)(&DhcpSb->LastTimeout)); + + // + // 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, DhcpReleasePacket, DhcpSb->LastPacket); + + if (Wrap == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // // Broadcast the message, unless we know the server address. // @@ -1426,10 +1451,10 @@ DhcpRetransmit ( ASSERT (UdpIo != NULL); - NET_GET_REF (DhcpSb->LastPacket); + NET_GET_REF (Wrap); Status = UdpIoSendDatagram ( UdpIo, - DhcpSb->LastPacket, + Wrap, &EndPoint, 0, DhcpOnPacketSent, @@ -1437,7 +1462,7 @@ DhcpRetransmit ( ); if (EFI_ERROR (Status)) { - NET_PUT_REF (DhcpSb->LastPacket); + NET_PUT_REF (Wrap); return EFI_ACCESS_DENIED; } diff --git a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.c b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.c index 95f6e9d4df..ad7d139cf7 100644 --- a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.c +++ b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.c @@ -1117,6 +1117,7 @@ PxeBcDiscvBootService ( UINT8 VendorOptLen; CHAR8 *SystemSerialNumber; EFI_DHCP4_HEADER *DhcpHeader; + UINT32 Xid; Mode = Private->PxeBc.Mode; @@ -1183,14 +1184,15 @@ PxeBcDiscvBootService ( DhcpHeader->HwAddrLen = sizeof (EFI_GUID); } - - Token.Packet->Dhcp4.Header.Xid = NET_RANDOM (NetRandomInitSeed ()); - Token.Packet->Dhcp4.Header.Reserved = (UINT16) ((IsBCast) ? 0xf000 : 0x0); + + Xid = NET_RANDOM (NetRandomInitSeed ()); + Token.Packet->Dhcp4.Header.Xid = HTONL(Xid); + Token.Packet->Dhcp4.Header.Reserved = HTONS((IsBCast) ? 0x8000 : 0); CopyMem (&Token.Packet->Dhcp4.Header.ClientAddr, &Private->StationIp, sizeof (EFI_IPv4_ADDRESS)); Token.RemotePort = Sport; - if (DestIp == NULL) { + if (IsBCast) { SetMem (&Token.RemoteAddress, sizeof (EFI_IPv4_ADDRESS), 0xff); } else { CopyMem (&Token.RemoteAddress, DestIp, sizeof (EFI_IPv4_ADDRESS)); @@ -1210,7 +1212,8 @@ PxeBcDiscvBootService ( // for (TryIndex = 1; TryIndex <= PXEBC_BOOT_REQUEST_RETRIES; TryIndex++) { - Token.TimeoutValue = PXEBC_BOOT_REQUEST_TIMEOUT * TryIndex; + Token.TimeoutValue = (UINT16) (PXEBC_BOOT_REQUEST_TIMEOUT * TryIndex); + Token.Packet->Dhcp4.Header.Seconds = (UINT16) (PXEBC_BOOT_REQUEST_TIMEOUT * (TryIndex - 1)); Status = Dhcp4->TransmitReceive (Dhcp4, &Token); diff --git a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.c b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.c index 5a17537b12..646638674c 100644 --- a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.c +++ b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.c @@ -1,7 +1,7 @@ /** @file Interface routines for PxeBc. -Copyright (c) 2007 - 2008, Intel Corporation.
+Copyright (c) 2007 - 2009, 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 @@ -15,7 +15,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "PxeBcImpl.h" -EFI_LOAD_FILE_PROTOCOL mLoadFileProtocolTemplate = { EfiPxeLoadFile }; +UINT32 mPxeDhcpTimeout[4] = { 4, 8, 16, 32 }; /** Get and record the arp cache. @@ -502,6 +502,7 @@ EfiPxeBcStop ( Private->CurrentUdpSrcPort = 0; Private->Udp4Write->Configure (Private->Udp4Write, NULL); + Private->Udp4Read->Groups (Private->Udp4Read, FALSE, NULL); Private->Udp4Read->Configure (Private->Udp4Read, NULL); Private->Dhcp4->Stop (Private->Dhcp4); @@ -560,8 +561,6 @@ EfiPxeBcDhcp ( EFI_DHCP4_MODE_DATA Dhcp4Mode; EFI_DHCP4_PACKET_OPTION *OptList[PXEBC_DHCP4_MAX_OPTION_NUM]; UINT32 OptCount; - UINT32 DiscoverTimeout; - UINTN Index; EFI_STATUS Status; EFI_ARP_CONFIG_DATA ArpConfigData; @@ -589,76 +588,62 @@ EfiPxeBcDhcp ( // // Set the DHCP4 config data. + // The four discovery timeouts are 4, 8, 16, 32 seconds respectively. // ZeroMem (&Dhcp4CfgData, sizeof (EFI_DHCP4_CONFIG_DATA)); Dhcp4CfgData.OptionCount = OptCount; Dhcp4CfgData.OptionList = OptList; Dhcp4CfgData.Dhcp4Callback = PxeBcDhcpCallBack; Dhcp4CfgData.CallbackContext = Private; - Dhcp4CfgData.DiscoverTryCount = 1; - Dhcp4CfgData.DiscoverTimeout = &DiscoverTimeout; + Dhcp4CfgData.DiscoverTryCount = 4; + Dhcp4CfgData.DiscoverTimeout = mPxeDhcpTimeout; - for (Index = 0; Index < PXEBC_DHCP4_DISCOVER_RETRIES; Index++) { - // - // The four discovery timeouts are 4, 8, 16, 32 seconds respectively. - // - DiscoverTimeout = (PXEBC_DHCP4_DISCOVER_INIT_TIMEOUT << Index); + Status = Dhcp4->Configure (Dhcp4, &Dhcp4CfgData); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + // + // Zero those arrays to record the varies numbers of DHCP OFFERS. + // + Private->GotProxyOffer = FALSE; + Private->NumOffers = 0; + Private->BootpIndex = 0; + ZeroMem (Private->ServerCount, sizeof (Private->ServerCount)); + ZeroMem (Private->ProxyIndex, sizeof (Private->ProxyIndex)); - Status = Dhcp4->Configure (Dhcp4, &Dhcp4CfgData); - if (EFI_ERROR (Status)) { - break; - } - // - // Zero those arrays to record the varies numbers of DHCP OFFERS. - // - Private->GotProxyOffer = FALSE; - Private->NumOffers = 0; - Private->BootpIndex = 0; - ZeroMem (Private->ServerCount, sizeof (Private->ServerCount)); - ZeroMem (Private->ProxyIndex, sizeof (Private->ProxyIndex)); - - Status = Dhcp4->Start (Dhcp4, NULL); - if (EFI_ERROR (Status)) { - if (Status == EFI_TIMEOUT) { - // - // If no response is received or all received offers don't match - // the PXE boot requirements, EFI_TIMEOUT will be returned. - // - continue; - } - if (Status == EFI_ICMP_ERROR) { - Mode->IcmpErrorReceived = TRUE; - } - // - // Other error status means the DHCP really fails. - // - break; - } - - Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode); - if (EFI_ERROR (Status)) { - break; - } - - ASSERT (Dhcp4Mode.State == Dhcp4Bound); - - CopyMem (&Private->StationIp, &Dhcp4Mode.ClientAddress, sizeof (EFI_IPv4_ADDRESS)); - CopyMem (&Private->SubnetMask, &Dhcp4Mode.SubnetMask, sizeof (EFI_IPv4_ADDRESS)); - CopyMem (&Private->GatewayIp, &Dhcp4Mode.RouterAddress, sizeof (EFI_IPv4_ADDRESS)); - - CopyMem (&Mode->StationIp, &Private->StationIp, sizeof (EFI_IPv4_ADDRESS)); - CopyMem (&Mode->SubnetMask, &Private->SubnetMask, sizeof (EFI_IPv4_ADDRESS)); - - // - // Check the selected offer to see whether BINL is required, if no or BINL is - // finished, set the various Mode members. - // - Status = PxeBcCheckSelectedOffer (Private); - if (!EFI_ERROR (Status)) { - break; + Status = Dhcp4->Start (Dhcp4, NULL); + if (EFI_ERROR (Status)) { + if (Status == EFI_ICMP_ERROR) { + Mode->IcmpErrorReceived = TRUE; } + goto ON_EXIT; } + Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + ASSERT (Dhcp4Mode.State == Dhcp4Bound); + + CopyMem (&Private->StationIp, &Dhcp4Mode.ClientAddress, sizeof (EFI_IPv4_ADDRESS)); + CopyMem (&Private->SubnetMask, &Dhcp4Mode.SubnetMask, sizeof (EFI_IPv4_ADDRESS)); + CopyMem (&Private->GatewayIp, &Dhcp4Mode.RouterAddress, sizeof (EFI_IPv4_ADDRESS)); + + CopyMem (&Mode->StationIp, &Private->StationIp, sizeof (EFI_IPv4_ADDRESS)); + CopyMem (&Mode->SubnetMask, &Private->SubnetMask, sizeof (EFI_IPv4_ADDRESS)); + + // + // Check the selected offer to see whether BINL is required, if no or BINL is + // finished, set the various Mode members. + // + Status = PxeBcCheckSelectedOffer (Private); + if (!EFI_ERROR (Status)) { + goto ON_EXIT; + } + +ON_EXIT: if (EFI_ERROR (Status)) { Dhcp4->Stop (Dhcp4); Dhcp4->Configure (Dhcp4, NULL); @@ -2755,3 +2740,5 @@ EfiPxeLoadFile ( return Status; } +EFI_LOAD_FILE_PROTOCOL mLoadFileProtocolTemplate = { EfiPxeLoadFile }; +