Revision: 13676 http://edk2.svn.sourceforge.net/edk2/?rev=13676&view=rev Author: sfu5 Date: 2012-08-24 08:25:42 +0000 (Fri, 24 Aug 2012) Log Message: ----------- Fix bugs in PXE driver when using option 43 for boot server list and boot menu prompt.
Signed-off-by: Fu Siyuan <siyuan...@intel.com> Reviewed-by: Ye Ting <ting...@intel.com> Reviewed-by: Ouyang Qian <qian.ouy...@intel.com> Modified Paths: -------------- trunk/edk2/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c trunk/edk2/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.h trunk/edk2/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c trunk/edk2/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.h trunk/edk2/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c Modified: trunk/edk2/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c =================================================================== --- trunk/edk2/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c 2012-08-24 00:37:40 UTC (rev 13675) +++ trunk/edk2/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c 2012-08-24 08:25:42 UTC (rev 13676) @@ -1,7 +1,7 @@ /** @file Boot functions implementation for UefiPxeBc Driver. - Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR> + Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR> This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -86,9 +86,9 @@ OfferType = Mode->UsingIpv6 ? Cache->Dhcp6.OfferType : Cache->Dhcp4.OfferType; // - // Only ProxyPxe10 offer needs boot prompt. + // Only DhcpPxe10 and ProxyPxe10 offer needs boot prompt. // - if (OfferType != PxeOfferTypeProxyPxe10) { + if (OfferType != PxeOfferTypeProxyPxe10 && OfferType != PxeOfferTypeDhcpPxe10) { return EFI_NOT_FOUND; } @@ -99,7 +99,7 @@ VendorOpt = &Cache->Dhcp4.VendorOpt; if (!IS_VALID_BOOT_PROMPT (VendorOpt->BitMap)) { - return EFI_SUCCESS; + return EFI_TIMEOUT; } Timeout = VendorOpt->MenuPrompt->Timeout; @@ -110,10 +110,10 @@ // The valid scope of Timeout refers to PXE2.1 spec. // if (Timeout == 0) { - return EFI_SUCCESS; + return EFI_TIMEOUT; } if (Timeout == 255) { - return EFI_TIMEOUT; + return EFI_SUCCESS; } // @@ -173,6 +173,7 @@ gST->ConOut->SetCursorPosition (gST->ConOut, SecCol + PromptLen, SecRow); AsciiPrint ("(%d) ", Timeout--); + Status = EFI_TIMEOUT; while (EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) { if (!EFI_ERROR (gBS->CheckEvent (DescendEvent))) { gST->ConOut->SetCursorPosition (gST->ConOut, SecCol + PromptLen, SecRow); @@ -184,6 +185,7 @@ } // // Parse the input key by user. + // If <F8> or <Ctrl> + <M> is pressed, return success to display the boot menu. // if (InputKey.ScanCode == 0) { @@ -196,7 +198,7 @@ case CTRL ('m'): case 'm': case 'M': - Status = EFI_TIMEOUT; + Status = EFI_SUCCESS; break; default: @@ -208,7 +210,7 @@ switch (InputKey.ScanCode) { case SCAN_F8: - Status = EFI_TIMEOUT; + Status = EFI_SUCCESS; break; case SCAN_ESC: @@ -284,10 +286,10 @@ OfferType = Mode->UsingIpv6 ? Cache->Dhcp6.OfferType : Cache->Dhcp4.OfferType; // - // There is no specified ProxyPxe10 for IPv6 in PXE and UEFI spec. + // There is no specified DhcpPxe10/ProxyPxe10 for IPv6 in PXE and UEFI spec. // ASSERT (!Mode->UsingIpv6); - ASSERT (OfferType == PxeOfferTypeProxyPxe10); + ASSERT (OfferType == PxeOfferTypeProxyPxe10 || OfferType == PxeOfferTypeDhcpPxe10); VendorOpt = &Cache->Dhcp4.VendorOpt; if (!IS_VALID_BOOT_MENU (VendorOpt->BitMap)) { @@ -351,7 +353,7 @@ gBS->Stall (10 * TICKS_PER_MS); } - if (InputKey.ScanCode != 0) { + if (InputKey.ScanCode == 0) { switch (InputKey.UnicodeChar) { case CTRL ('c'): InputKey.ScanCode = SCAN_ESC; @@ -651,7 +653,7 @@ @param[in] Private Pointer to PxeBc private data. @param[in] Type The type of bootstrap to perform. - @param[in, out] Info Pointer to EFI_PXE_BASE_CODE_DISCOVER_INFO. + @param[in, out] DiscoverInfo Pointer to EFI_PXE_BASE_CODE_DISCOVER_INFO. @param[out] BootEntry Pointer to PXEBC_BOOT_SVR_ENTRY. @param[out] SrvList Pointer to EFI_PXE_BASE_CODE_SRVLIST. @@ -663,7 +665,7 @@ PxeBcExtractDiscoverInfo ( IN PXEBC_PRIVATE_DATA *Private, IN UINT16 Type, - IN OUT EFI_PXE_BASE_CODE_DISCOVER_INFO *Info, + IN OUT EFI_PXE_BASE_CODE_DISCOVER_INFO **DiscoverInfo, OUT PXEBC_BOOT_SVR_ENTRY **BootEntry, OUT EFI_PXE_BASE_CODE_SRVLIST **SrvList ) @@ -673,8 +675,11 @@ PXEBC_VENDOR_OPTION *VendorOpt; PXEBC_BOOT_SVR_ENTRY *Entry; BOOLEAN IsFound; + EFI_PXE_BASE_CODE_DISCOVER_INFO *Info; + UINT16 Index; Mode = Private->PxeBc.Mode; + Info = *DiscoverInfo; if (Mode->UsingIpv6) { Info->IpCnt = 1; @@ -708,7 +713,7 @@ Info->UseMCast = (BOOLEAN) !IS_DISABLE_MCAST_DISCOVER (VendorOpt->DiscoverCtrl); Info->UseBCast = (BOOLEAN) !IS_DISABLE_BCAST_DISCOVER (VendorOpt->DiscoverCtrl); Info->MustUseList = (BOOLEAN) IS_ENABLE_USE_SERVER_LIST (VendorOpt->DiscoverCtrl); - Info->UseUCast = Info->MustUseList; + Info->UseUCast = (BOOLEAN) IS_VALID_BOOT_SERVERS (VendorOpt->BitMap); if (Info->UseMCast) { // @@ -719,7 +724,7 @@ Info->IpCnt = 0; - if (Info->MustUseList) { + if (Info->UseUCast) { Entry = VendorOpt->BootSvr; while (((UINT8) (Entry - VendorOpt->BootSvr)) < VendorOpt->BootSvrLen) { @@ -735,9 +740,24 @@ } Info->IpCnt = Entry->IpCnt; + if (Info->IpCnt >= 1) { + *DiscoverInfo = AllocatePool (sizeof (*Info) + (Info->IpCnt - 1) * sizeof (**SrvList)); + if (*DiscoverInfo == NULL) { + return EFI_OUT_OF_RESOURCES; + } + CopyMem (*DiscoverInfo, Info, sizeof (*Info)); + Info = *DiscoverInfo; + } + + for (Index = 0; Index < Info->IpCnt; Index++) { + CopyMem (&Info->SrvList[Index].IpAddr, &Entry->IpAddr[Index], sizeof (EFI_IPv4_ADDRESS)); + Info->SrvList[Index].AcceptAnyResponse = !Info->MustUseList; + Info->SrvList[Index].Type = NTOHS (Entry->Type); + } } *BootEntry = Entry; + *SrvList = Info->SrvList; } return EFI_SUCCESS; @@ -842,12 +862,12 @@ // // Choose by user's input. // - Status = PxeBcSelectBootMenu (Private, &Type, TRUE); + Status = PxeBcSelectBootMenu (Private, &Type, FALSE); } else if (Status == EFI_TIMEOUT) { // // Choose by default item. // - Status = PxeBcSelectBootMenu (Private, &Type, FALSE); + Status = PxeBcSelectBootMenu (Private, &Type, TRUE); } if (!EFI_ERROR (Status)) { @@ -868,6 +888,27 @@ if (EFI_ERROR (Status)) { return Status; } + + if (Mode->PxeReplyReceived && !Mode->ProxyOfferReceived) { + // + // Some network boot loader only search the packet in Mode.ProxyOffer to get its server + // IP address, so we need to store a copy of Mode.PxeReply packet into Mode.ProxyOffer. + // + if (Mode->UsingIpv6) { + CopyMem ( + &Mode->ProxyOffer.Dhcpv6, + &Mode->PxeReply.Dhcpv6, + Private->PxeReply.Dhcp6.Packet.Ack.Length + ); + } else { + CopyMem ( + &Mode->ProxyOffer.Dhcpv4, + &Mode->PxeReply.Dhcpv4, + Private->PxeReply.Dhcp4.Packet.Ack.Length + ); + } + Mode->ProxyOfferReceived = TRUE; + } } // Modified: trunk/edk2/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.h =================================================================== --- trunk/edk2/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.h 2012-08-24 00:37:40 UTC (rev 13675) +++ trunk/edk2/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.h 2012-08-24 08:25:42 UTC (rev 13676) @@ -1,7 +1,7 @@ /** @file Boot functions declaration for UefiPxeBc Driver. - Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR> + Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR> This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -29,7 +29,7 @@ @param[in] Private Pointer to PxeBc private data. @param[in] Type The type of bootstrap to perform. - @param[in, out] Info Pointer to EFI_PXE_BASE_CODE_DISCOVER_INFO. + @param[in, out] DiscoverInfo Pointer to EFI_PXE_BASE_CODE_DISCOVER_INFO. @param[out] BootEntry Pointer to PXEBC_BOOT_SVR_ENTRY. @param[out] SrvList Pointer to EFI_PXE_BASE_CODE_SRVLIST. @@ -41,7 +41,7 @@ PxeBcExtractDiscoverInfo ( IN PXEBC_PRIVATE_DATA *Private, IN UINT16 Type, - IN OUT EFI_PXE_BASE_CODE_DISCOVER_INFO *Info, + IN OUT EFI_PXE_BASE_CODE_DISCOVER_INFO **DiscoverInfo, OUT PXEBC_BOOT_SVR_ENTRY **BootEntry, OUT EFI_PXE_BASE_CODE_SRVLIST **SrvList ); Modified: trunk/edk2/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c =================================================================== --- trunk/edk2/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c 2012-08-24 00:37:40 UTC (rev 13675) +++ trunk/edk2/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c 2012-08-24 08:25:42 UTC (rev 13676) @@ -1,7 +1,7 @@ /** @file Functions implementation related with DHCPv4 for UefiPxeBc Driver. - Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR> + Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR> This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -1443,7 +1443,7 @@ break; } if ((SrvList[SrvIndex].Type == Type) && - EFI_IP4_EQUAL (&Response->Dhcp4.Header.ServerAddr, &Private->ServerIp)) { + EFI_IP4_EQUAL (&Response->Dhcp4.Header.ServerAddr, &SrvList[SrvIndex].IpAddr)) { break; } SrvIndex++; @@ -1587,6 +1587,7 @@ AsciiPrint ("\n Station IP address is "); PxeBcShowIp4Addr (&Private->StationIp.v4); + AsciiPrint ("\n"); ON_EXIT: if (EFI_ERROR (Status)) { Modified: trunk/edk2/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.h =================================================================== --- trunk/edk2/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.h 2012-08-24 00:37:40 UTC (rev 13675) +++ trunk/edk2/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.h 2012-08-24 08:25:42 UTC (rev 13676) @@ -1,7 +1,7 @@ /** @file Functions declaration related with DHCPv4 for UefiPxeBc Driver. - Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR> + Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR> This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -146,6 +146,10 @@ BIT (PXEBC_VENDOR_TAG_BOOT_MENU) | \ BIT (PXEBC_VENDOR_TAG_MENU_PROMPT)) +#define IS_VALID_BOOT_SERVERS(x) \ + ((((x)[0]) & BIT (PXEBC_VENDOR_TAG_BOOT_SERVERS)) \ + == BIT (PXEBC_VENDOR_TAG_BOOT_SERVERS)) + #define IS_VALID_BOOT_PROMPT(x) \ ((((x)[0]) & BIT (PXEBC_VENDOR_TAG_MENU_PROMPT)) \ == BIT (PXEBC_VENDOR_TAG_MENU_PROMPT)) @@ -256,6 +260,7 @@ PXEBC_DHCP4_OPTION_MAX_MESG_SIZE *MaxMesgSize; } PXEBC_DHCP4_OPTION_ENTRY; +#pragma pack(1) typedef struct { UINT16 Type; UINT8 IpCnt; @@ -272,6 +277,7 @@ UINT8 Timeout; UINT8 Prompt[1]; } PXEBC_MENU_PROMPT; +#pragma pack() typedef struct { UINT32 BitMap[8]; Modified: trunk/edk2/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c =================================================================== --- trunk/edk2/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c 2012-08-24 00:37:40 UTC (rev 13675) +++ trunk/edk2/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c 2012-08-24 08:25:42 UTC (rev 13676) @@ -529,6 +529,7 @@ UINT16 Index; EFI_STATUS Status; EFI_PXE_BASE_CODE_IP_FILTER IpFilter; + EFI_PXE_BASE_CODE_DISCOVER_INFO *NewCreatedInfo; if (This == NULL) { return EFI_INVALID_PARAMETER; @@ -541,6 +542,7 @@ SrvList = NULL; Status = EFI_DEVICE_ERROR; Private->Function = EFI_PXE_BASE_CODE_FUNCTION_DISCOVER; + NewCreatedInfo = NULL; if (!Mode->Started) { return EFI_NOT_STARTED; @@ -594,12 +596,12 @@ // // 2. Extract the discover information from the cached packets if unspecified. // - Info = &DefaultInfo; - Status = PxeBcExtractDiscoverInfo (Private, Type, Info, &BootSvrEntry, &SrvList); + NewCreatedInfo = &DefaultInfo; + Status = PxeBcExtractDiscoverInfo (Private, Type, &NewCreatedInfo, &BootSvrEntry, &SrvList); if (EFI_ERROR (Status)) { goto ON_EXIT; } - + Info = NewCreatedInfo; } else { // // 3. Take the pass-in information as the discover info, and validate the server list. @@ -634,31 +636,8 @@ Private->IsDoDiscover = TRUE; - if (Info->UseUCast) { + if (Info->UseMCast) { // - // Do discover by unicast. - // - for (Index = 0; Index < Info->IpCnt; Index++) { - if (BootSvrEntry == NULL) { - CopyMem (&Private->ServerIp, &SrvList[Index].IpAddr, sizeof (EFI_IP_ADDRESS)); - } else { - ASSERT (!Mode->UsingIpv6); - ZeroMem (&Private->ServerIp, sizeof (EFI_IP_ADDRESS)); - CopyMem (&Private->ServerIp, &BootSvrEntry->IpAddr[Index], sizeof (EFI_IPv4_ADDRESS)); - } - - Status = PxeBcDiscoverBootServer ( - Private, - Type, - Layer, - UseBis, - &SrvList[Index].IpAddr, - 0, - NULL - ); - } - } else if (Info->UseMCast) { - // // Do discover by multicast. // Status = PxeBcDiscoverBootServer ( @@ -667,8 +646,8 @@ Layer, UseBis, &Info->ServerMCastIp, - 0, - NULL + Info->IpCnt, + SrvList ); } else if (Info->UseBCast) { @@ -685,6 +664,30 @@ Info->IpCnt, SrvList ); + + } else if (Info->UseUCast) { + // + // Do discover by unicast. + // + for (Index = 0; Index < Info->IpCnt; Index++) { + if (BootSvrEntry == NULL) { + CopyMem (&Private->ServerIp, &SrvList[Index].IpAddr, sizeof (EFI_IP_ADDRESS)); + } else { + ASSERT (!Mode->UsingIpv6); + ZeroMem (&Private->ServerIp, sizeof (EFI_IP_ADDRESS)); + CopyMem (&Private->ServerIp, &BootSvrEntry->IpAddr[Index], sizeof (EFI_IPv4_ADDRESS)); + } + + Status = PxeBcDiscoverBootServer ( + Private, + Type, + Layer, + UseBis, + &Private->ServerIp, + Info->IpCnt, + SrvList + ); + } } if (EFI_ERROR (Status)) { @@ -698,8 +701,8 @@ if (!EFI_ERROR (Status)) { CopyMem ( &Mode->PxeReply.Dhcpv6, - &Private->PxeReply.Dhcp6.Packet.Offer, - Private->PxeReply.Dhcp6.Packet.Offer.Length + &Private->PxeReply.Dhcp6.Packet.Ack.Dhcp6, + Private->PxeReply.Dhcp6.Packet.Ack.Length ); Mode->PxeReplyReceived = TRUE; Mode->PxeDiscoverValid = TRUE; @@ -709,8 +712,8 @@ if (!EFI_ERROR (Status)) { CopyMem ( &Mode->PxeReply.Dhcpv4, - &Private->PxeReply.Dhcp4.Packet.Offer, - Private->PxeReply.Dhcp4.Packet.Offer.Length + &Private->PxeReply.Dhcp4.Packet.Ack.Dhcp4, + Private->PxeReply.Dhcp4.Packet.Ack.Length ); Mode->PxeReplyReceived = TRUE; Mode->PxeDiscoverValid = TRUE; @@ -720,6 +723,10 @@ ON_EXIT: + if (NewCreatedInfo != NULL && NewCreatedInfo != &DefaultInfo) { + FreePool (NewCreatedInfo); + } + if (Mode->UsingIpv6) { Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData); } else { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ edk2-commits mailing list edk2-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-commits