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

Reply via email to