1. Update the parsing logic of DHCP message in PXE driver.

2. Append null terminated character at the end of option 67.
Signed-off-by: Fu Siyuan <siyuan.fu@intel.com>
Reviewed-by: Dong, Guo <guo.dong@intel.com>
Reviewed-by: Jin, Eric <eric.jin@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15099 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Fu Siyuan 2014-01-13 02:53:50 +00:00 committed by sfu5
parent 20182c7ea1
commit 8cb92971e4
2 changed files with 86 additions and 43 deletions

View File

@ -2,7 +2,7 @@
Support for PxeBc dhcp functions. Support for PxeBc dhcp functions.
Copyright (c) 2013, Red Hat, Inc. Copyright (c) 2013, Red Hat, Inc.
Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR> Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License 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 which accompanies this distribution. The full text of the license may be found at
@ -147,6 +147,7 @@ PxeBcParseCachedDhcpPacket (
// //
// Parse interested dhcp options and store their pointers in CachedPacket->Dhcp4Option. // Parse interested dhcp options and store their pointers in CachedPacket->Dhcp4Option.
// First, try to parse DHCPv4 options from the DHCP optional parameters field.
// //
for (Index = 0; Index < PXEBC_DHCP4_TAG_INDEX_MAX; Index++) { for (Index = 0; Index < PXEBC_DHCP4_TAG_INDEX_MAX; Index++) {
Options[Index] = PxeBcParseExtendOptions ( Options[Index] = PxeBcParseExtendOptions (
@ -155,6 +156,35 @@ PxeBcParseCachedDhcpPacket (
mInterestedDhcp4Tags[Index] mInterestedDhcp4Tags[Index]
); );
} }
//
// Second, Check if bootfilename and serverhostname is overloaded to carry DHCP options refers to rfc-2132.
// If yes, try to parse options from the BootFileName field, then ServerName field.
//
Option = Options[PXEBC_DHCP4_TAG_INDEX_OVERLOAD];
if (Option != NULL) {
if ((Option->Data[0] & PXEBC_DHCP4_OVERLOAD_FILE) != 0) {
for (Index = 0; Index < PXEBC_DHCP4_TAG_INDEX_MAX; Index++) {
if (Options[Index] == NULL) {
Options[Index] = PxeBcParseExtendOptions (
(UINT8 *) Offer->Dhcp4.Header.BootFileName,
sizeof (Offer->Dhcp4.Header.BootFileName),
mInterestedDhcp4Tags[Index]
);
}
}
}
if ((Option->Data[0] & PXEBC_DHCP4_OVERLOAD_SERVER_NAME) != 0) {
for (Index = 0; Index < PXEBC_DHCP4_TAG_INDEX_MAX; Index++) {
if (Options[Index] == NULL) {
Options[Index] = PxeBcParseExtendOptions (
(UINT8 *) Offer->Dhcp4.Header.ServerName,
sizeof (Offer->Dhcp4.Header.ServerName),
mInterestedDhcp4Tags[Index]
);
}
}
}
}
// //
// Check whether is an offer with PXEClient or not. // Check whether is an offer with PXEClient or not.
@ -177,31 +207,23 @@ PxeBcParseCachedDhcpPacket (
} }
} }
//
// Check whether bootfilename/serverhostname overloaded (See details in dhcp spec).
// If overloaded, parse this buffer as nested dhcp options, or just parse bootfilename/
// serverhostname option.
//
Option = Options[PXEBC_DHCP4_TAG_INDEX_OVERLOAD];
if ((Option != NULL) && ((Option->Data[0] & PXEBC_DHCP4_OVERLOAD_FILE) != 0)) {
Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] = PxeBcParseExtendOptions ( //
(UINT8 *) Offer->Dhcp4.Header.BootFileName, // Parse PXE boot file name:
sizeof (Offer->Dhcp4.Header.BootFileName), // According to PXE spec, boot file name should be read from DHCP option 67 (bootfile name) if present.
PXEBC_DHCP4_TAG_BOOTFILE // Otherwise, read from boot file field in DHCP header.
); //
if (Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] != NULL) {
// //
// RFC 2132, Section 9.5 does not strictly state Bootfile name (option 67) is null // RFC 2132, Section 9.5 does not strictly state Bootfile name (option 67) is null
// terminated string. So force to append null terminated character at the end of string. // terminated string. So force to append null terminated character at the end of string.
// //
if (Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] != NULL) {
Ptr8 = (UINT8*)&Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE]->Data[0]; Ptr8 = (UINT8*)&Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE]->Data[0];
Ptr8 += Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE]->Length; Ptr8 += Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE]->Length;
if (*(Ptr8 - 1) != '\0') {
*Ptr8 = '\0'; *Ptr8 = '\0';
} }
} else if (Offer->Dhcp4.Header.BootFileName[0] != 0) {
} else if ((Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] == NULL) &&
(Offer->Dhcp4.Header.BootFileName[0] != 0)) {
// //
// If the bootfile is not present and bootfilename is present in dhcp packet, just parse it. // If the bootfile is not present and bootfilename is present in dhcp packet, just parse it.
// And do not count dhcp option header, or else will destroy the serverhostname. // And do not count dhcp option header, or else will destroy the serverhostname.

View File

@ -1,7 +1,7 @@
/** @file /** @file
Functions implementation related with DHCPv4 for UefiPxeBc Driver. Functions implementation related with DHCPv4 for UefiPxeBc Driver.
Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR> Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
@ -472,6 +472,7 @@ PxeBcParseDhcp4Packet (
// //
// Parse DHCPv4 options in this offer, and store the pointers. // Parse DHCPv4 options in this offer, and store the pointers.
// First, try to parse DHCPv4 options from the DHCP optional parameters field.
// //
for (Index = 0; Index < PXEBC_DHCP4_TAG_INDEX_MAX; Index++) { for (Index = 0; Index < PXEBC_DHCP4_TAG_INDEX_MAX; Index++) {
Options[Index] = PxeBcParseDhcp4Options ( Options[Index] = PxeBcParseDhcp4Options (
@ -480,6 +481,35 @@ PxeBcParseDhcp4Packet (
mInterestedDhcp4Tags[Index] mInterestedDhcp4Tags[Index]
); );
} }
//
// Second, Check if bootfilename and serverhostname is overloaded to carry DHCP options refers to rfc-2132.
// If yes, try to parse options from the BootFileName field, then ServerName field.
//
Option = Options[PXEBC_DHCP4_TAG_INDEX_OVERLOAD];
if (Option != NULL) {
if ((Option->Data[0] & PXEBC_DHCP4_OVERLOAD_FILE) != 0) {
for (Index = 0; Index < PXEBC_DHCP4_TAG_INDEX_MAX; Index++) {
if (Options[Index] == NULL) {
Options[Index] = PxeBcParseDhcp4Options (
(UINT8 *) Offer->Dhcp4.Header.BootFileName,
sizeof (Offer->Dhcp4.Header.BootFileName),
mInterestedDhcp4Tags[Index]
);
}
}
}
if ((Option->Data[0] & PXEBC_DHCP4_OVERLOAD_SERVER_NAME) != 0) {
for (Index = 0; Index < PXEBC_DHCP4_TAG_INDEX_MAX; Index++) {
if (Options[Index] == NULL) {
Options[Index] = PxeBcParseDhcp4Options (
(UINT8 *) Offer->Dhcp4.Header.ServerName,
sizeof (Offer->Dhcp4.Header.ServerName),
mInterestedDhcp4Tags[Index]
);
}
}
}
}
// //
// The offer with "yiaddr" is a proxy offer. // The offer with "yiaddr" is a proxy offer.
@ -506,30 +536,21 @@ PxeBcParseDhcp4Packet (
} }
// //
// Check whether bootfilename and serverhostname overloaded, refers to rfc-2132 in details. // Parse PXE boot file name:
// If overloaded, parse the buffer as nested DHCPv4 options, or else just parse as bootfilename // According to PXE spec, boot file name should be read from DHCP option 67 (bootfile name) if present.
// and serverhostname option. // Otherwise, read from boot file field in DHCP header.
// //
Option = Options[PXEBC_DHCP4_TAG_INDEX_OVERLOAD]; if (Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] != NULL) {
if (Option != NULL && (Option->Data[0] & PXEBC_DHCP4_OVERLOAD_FILE) != 0) {
Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] = PxeBcParseDhcp4Options (
(UINT8 *) Offer->Dhcp4.Header.BootFileName,
sizeof (Offer->Dhcp4.Header.BootFileName),
PXEBC_DHCP4_TAG_BOOTFILE
);
// //
// RFC 2132, Section 9.5 does not strictly state Bootfile name (option 67) is null // RFC 2132, Section 9.5 does not strictly state Bootfile name (option 67) is null
// terminated string. So force to append null terminated character at the end of string. // terminated string. So force to append null terminated character at the end of string.
// //
if (Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] != NULL) {
Ptr8 = (UINT8*)&Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE]->Data[0]; Ptr8 = (UINT8*)&Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE]->Data[0];
Ptr8 += Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE]->Length; Ptr8 += Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE]->Length;
if (*(Ptr8 - 1) != '\0') {
*Ptr8 = '\0'; *Ptr8 = '\0';
} }
} else if (Offer->Dhcp4.Header.BootFileName[0] != 0) {
} else if ((Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] == NULL) &&
(Offer->Dhcp4.Header.BootFileName[0] != 0)) {
// //
// If the bootfile is not present and bootfilename is present in DHCPv4 packet, just parse it. // If the bootfile is not present and bootfilename is present in DHCPv4 packet, just parse it.
// Do not count dhcp option header here, or else will destroy the serverhostname. // Do not count dhcp option header here, or else will destroy the serverhostname.