]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c
Fix default VENDOR_CLASS in DHCP discover.
[mirror_edk2.git] / NetworkPkg / UefiPxeBcDxe / PxeBcDhcp4.c
index ecafc86a038780e2e7ac95e6cb7978fe17593dad..b113505d9758851650b558806b9a59e2933b333c 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Functions implementation related with DHCPv4 for UefiPxeBc Driver.\r
 \r
-  Copyright (c) 2009 - 2012, 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
@@ -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,6 +481,35 @@ 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
@@ -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
@@ -1574,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