]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c
Fix FSP_INFO_EXTENTED_HEADER.
[mirror_edk2.git] / NetworkPkg / UefiPxeBcDxe / PxeBcDhcp4.c
index 08415d97b421583d57263e50d919cc8dcce0e993..df171598b1b19f3bf356ab8560e5df57300af580 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Functions implementation related with DHCPv4 for UefiPxeBc Driver.\r
 \r
-  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -316,7 +316,7 @@ PxeBcBuildDhcp4Options (
   Index++;\r
   OptList[Index]          = GET_NEXT_DHCP_OPTION (OptList[Index - 1]);\r
 \r
-  if (EFI_ERROR (PxeBcGetSystemGuid ((EFI_GUID *) OptEnt.Uuid->Guid))) {\r
+  if (EFI_ERROR (NetLibGetSystemGuid ((EFI_GUID *) OptEnt.Uuid->Guid))) {\r
     //\r
     // Zero the Guid to indicate NOT programable if failed to get system Guid.\r
     //\r
@@ -472,6 +472,7 @@ PxeBcParseDhcp4Packet (
 \r
   //\r
   // Parse DHCPv4 options in this offer, and store the pointers.\r
+  // First, try to parse DHCPv4 options from the DHCP optional parameters field.\r
   //\r
   for (Index = 0; Index < PXEBC_DHCP4_TAG_INDEX_MAX; Index++) {\r
     Options[Index] = PxeBcParseDhcp4Options (\r
@@ -480,9 +481,38 @@ PxeBcParseDhcp4Packet (
                        mInterestedDhcp4Tags[Index]\r
                        );\r
   }\r
+  //\r
+  // Second, Check if bootfilename and serverhostname is overloaded to carry DHCP options refers to rfc-2132. \r
+  // If yes, try to parse options from the BootFileName field, then ServerName field.\r
+  //\r
+  Option = Options[PXEBC_DHCP4_TAG_INDEX_OVERLOAD];\r
+  if (Option != NULL) {\r
+    if ((Option->Data[0] & PXEBC_DHCP4_OVERLOAD_FILE) != 0) {\r
+      for (Index = 0; Index < PXEBC_DHCP4_TAG_INDEX_MAX; Index++) {\r
+        if (Options[Index] == NULL) {\r
+          Options[Index] = PxeBcParseDhcp4Options (\r
+                             (UINT8 *) Offer->Dhcp4.Header.BootFileName,\r
+                             sizeof (Offer->Dhcp4.Header.BootFileName),\r
+                             mInterestedDhcp4Tags[Index]\r
+                             );\r
+        }\r
+      }\r
+    }\r
+    if ((Option->Data[0] & PXEBC_DHCP4_OVERLOAD_SERVER_NAME) != 0) {\r
+      for (Index = 0; Index < PXEBC_DHCP4_TAG_INDEX_MAX; Index++) {\r
+        if (Options[Index] == NULL) {\r
+          Options[Index] = PxeBcParseDhcp4Options (\r
+                             (UINT8 *) Offer->Dhcp4.Header.ServerName,\r
+                             sizeof (Offer->Dhcp4.Header.ServerName),\r
+                             mInterestedDhcp4Tags[Index]\r
+                             );\r
+        }\r
+      }\r
+    }\r
+  }\r
 \r
   //\r
-  // The offer with "yiaddr" is a proxy offer.\r
+  // The offer with zero "yiaddr" is a proxy offer.\r
   //\r
   if (Offer->Dhcp4.Header.YourAddr.Addr[0] == 0) {\r
     IsProxyOffer = TRUE;\r
@@ -506,33 +536,24 @@ PxeBcParseDhcp4Packet (
   }\r
 \r
   //\r
-  // Check whether bootfilename and serverhostname overloaded, refers to rfc-2132 in details.\r
-  // If overloaded, parse the buffer as nested DHCPv4 options, or else just parse as bootfilename\r
-  // and serverhostname option.\r
+  // Parse PXE boot file name:\r
+  // According to PXE spec, boot file name should be read from DHCP option 67 (bootfile name) if present.\r
+  // Otherwise, read from boot file field in DHCP header.\r
   //\r
-  Option = Options[PXEBC_DHCP4_TAG_INDEX_OVERLOAD];\r
-  if (Option != NULL && (Option->Data[0] & PXEBC_DHCP4_OVERLOAD_FILE) != 0) {\r
-\r
-    Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] = PxeBcParseDhcp4Options (\r
-                                                (UINT8 *) Offer->Dhcp4.Header.BootFileName,\r
-                                                sizeof (Offer->Dhcp4.Header.BootFileName),\r
-                                                PXEBC_DHCP4_TAG_BOOTFILE\r
-                                                );\r
+  if (Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] != NULL) {\r
     //\r
     // RFC 2132, Section 9.5 does not strictly state Bootfile name (option 67) is null\r
     // terminated string. So force to append null terminated character at the end of string.\r
     //\r
-    if (Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] != NULL) {\r
-      Ptr8 =  (UINT8*)&Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE]->Data[0];\r
-      Ptr8 += Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE]->Length;\r
-      *Ptr8 =  '\0';\r
+    Ptr8 =  (UINT8*)&Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE]->Data[0];\r
+    Ptr8 += Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE]->Length;\r
+    if (*(Ptr8 - 1) != '\0') {\r
+      *Ptr8 = '\0';\r
     }\r
-\r
-  } else if ((Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] == NULL) &&\r
-            (Offer->Dhcp4.Header.BootFileName[0] != 0)) {\r
+  } else if (Offer->Dhcp4.Header.BootFileName[0] != 0) {\r
     //\r
     // If the bootfile is not present and bootfilename is present in DHCPv4 packet, just parse it.\r
-    // Do not count dhcp option header here, or else will destory the serverhostname.\r
+    // Do not count dhcp option header here, or else will destroy the serverhostname.\r
     //\r
     Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] = (EFI_DHCP4_PACKET_OPTION *)\r
                                                 (&Offer->Dhcp4.Header.BootFileName[0] -\r
@@ -960,6 +981,7 @@ PxeBcSelectDhcp4Offer (
 \r
   @retval     EFI_SUCCESS         Handled the DHCPv4 offer packet successfully.\r
   @retval     EFI_NO_RESPONSE     No response to the following request packet.\r
+  @retval     EFI_NOT_FOUND       No boot filename received.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -1070,7 +1092,9 @@ PxeBcHandleDhcp4Offer (
       //\r
       //  Othewise, the bootfile name must be included in DhcpOnly offer.\r
       //\r
-      ASSERT (Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] != NULL);\r
+      if (Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] == NULL) {\r
+        Status = EFI_NOT_FOUND;\r
+      }\r
     }\r
   }\r
 \r
@@ -1193,7 +1217,7 @@ PxeBcDhcp4CallBack (
       //\r
       // Send the system Guid instead of the MAC address as the hardware address if required.\r
       //\r
-      if (EFI_ERROR (PxeBcGetSystemGuid ((EFI_GUID *) Packet->Dhcp4.Header.ClientHwAddr))) {\r
+      if (EFI_ERROR (NetLibGetSystemGuid ((EFI_GUID *) Packet->Dhcp4.Header.ClientHwAddr))) {\r
         //\r
         // Zero the Guid to indicate NOT programable if failed to get system Guid.\r
         //\r
@@ -1369,7 +1393,7 @@ PxeBcDhcp4Discover (
   }\r
 \r
   if (Mode->SendGUID) {\r
-    if (EFI_ERROR (PxeBcGetSystemGuid ((EFI_GUID *) Token.Packet->Dhcp4.Header.ClientHwAddr))) {\r
+    if (EFI_ERROR (NetLibGetSystemGuid ((EFI_GUID *) Token.Packet->Dhcp4.Header.ClientHwAddr))) {\r
       //\r
       // Zero the Guid to indicate NOT programable if failed to get system Guid.\r
       //\r
@@ -1440,7 +1464,7 @@ PxeBcDhcp4Discover (
           break;\r
         }\r
         if ((SrvList[SrvIndex].Type == Type) &&\r
-            EFI_IP4_EQUAL (&Response->Dhcp4.Header.ServerAddr, &Private->ServerIp)) {\r
+            EFI_IP4_EQUAL (&Response->Dhcp4.Header.ServerAddr, &SrvList[SrvIndex].IpAddr)) {\r
           break;\r
         }\r
         SrvIndex++;\r
@@ -1571,7 +1595,7 @@ PxeBcDhcp4Dora (
   CopyMem (&PxeMode->StationIp, &Private->StationIp, sizeof (EFI_IPv4_ADDRESS));\r
   CopyMem (&PxeMode->SubnetMask, &Private->SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
 \r
-  Status = PxeBcFlushStaionIp (Private, &Private->StationIp, &Private->SubnetMask);\r
+  Status = PxeBcFlushStationIp (Private, &Private->StationIp, &Private->SubnetMask);\r
   if (EFI_ERROR (Status)) {\r
     goto ON_EXIT;\r
   }\r
@@ -1584,6 +1608,7 @@ PxeBcDhcp4Dora (
   AsciiPrint ("\n  Station IP address is ");\r
 \r
   PxeBcShowIp4Addr (&Private->StationIp.v4);\r
+  AsciiPrint ("\n");\r
 \r
 ON_EXIT:\r
   if (EFI_ERROR (Status)) {\r