/** @file\r
-\r
-Copyright (c) 2006, Intel Corporation\r
+ Function to validate, parse, process the DHCP options.\r
+ \r
+Copyright (c) 2006 - 2009, Intel Corporation.<BR>\r
All rights reserved. This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
\r
-Module Name:\r
-\r
- Dhcp4Option.c\r
-\r
-Abstract:\r
-\r
- Function to validate, parse, process the DHCP options\r
-\r
-\r
**/\r
\r
#include "Dhcp4Impl.h"\r
\r
-//\r
-// A list of the format of DHCP Options sorted by option tag\r
-// to validate a dhcp message. Refere the comments of the\r
-// DHCP_OPTION_FORMAT structure.\r
-//\r
-STATIC\r
-DHCP_OPTION_FORMAT\r
-DhcpOptionFormats [] = {\r
+///\r
+/// A list of the format of DHCP Options sorted by option tag\r
+/// to validate a dhcp message. Refere the comments of the\r
+/// DHCP_OPTION_FORMAT structure.\r
+///\r
+DHCP_OPTION_FORMAT DhcpOptionFormats[] = {\r
{DHCP_TAG_NETMASK, DHCP_OPTION_IP, 1, 1 , TRUE},\r
{DHCP_TAG_TIME_OFFSET, DHCP_OPTION_INT32, 1, 1 , FALSE},\r
{DHCP_TAG_ROUTER, DHCP_OPTION_IP, 1, -1 , TRUE},\r
Binary search the DhcpOptionFormats array to find the format\r
information about a specific option.\r
\r
- @param Tag The option's tag.\r
+ @param[in] Tag The option's tag.\r
\r
@return The point to the option's format, NULL if not found.\r
\r
**/\r
-STATIC\r
DHCP_OPTION_FORMAT *\r
DhcpFindOptionFormat (\r
IN UINT8 Tag\r
if (Tag < DhcpOptionFormats[Middle].Tag) {\r
Right = Middle - 1;\r
} else {\r
- Left = Middle + 1;\r
+ Left = Middle + 1;\r
}\r
}\r
\r
/**\r
Validate whether a single DHCP option is valid according to its format.\r
\r
- @param Format The option's format\r
- @param OptValue The value of the option\r
- @param Len The length of the option value\r
+ @param[in] Format The option's format\r
+ @param[in] OptValue The value of the option\r
+ @param[in] Len The length of the option value\r
\r
- @return TRUE is the option is valid, otherwise FALSE.\r
+ @retval TRUE The option is valid.\r
+ @retval FALSE Otherwise.\r
\r
**/\r
-STATIC\r
BOOLEAN\r
DhcpOptionIsValid (\r
IN DHCP_OPTION_FORMAT *Format,\r
Occur = Len / Unit;\r
\r
if (((Format->MinOccur != -1) && (Occur < Format->MinOccur)) ||\r
- ((Format->MaxOccur != -1) && (Occur > Format->MaxOccur))) {\r
+ ((Format->MaxOccur != -1) && (Occur > Format->MaxOccur))\r
+ ) {\r
return FALSE;\r
}\r
\r
Extract the client interested options, all the parameters are\r
converted to host byte order.\r
\r
- @param Tag The DHCP option tag\r
- @param Len The length of the option\r
- @param Data The value of the DHCP option\r
- @param Para The variable to save the interested parameter\r
+ @param[in] Tag The DHCP option tag\r
+ @param[in] Len The length of the option\r
+ @param[in] Data The value of the DHCP option\r
+ @param[out] Para The variable to save the interested parameter\r
\r
@retval EFI_SUCCESS The DHCP option is successfully extracted.\r
@retval EFI_INVALID_PARAMETER The DHCP option is mal-formated\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
DhcpGetParameter (\r
- IN UINT8 Tag,\r
- IN INTN Len,\r
- IN UINT8 *Data,\r
- IN DHCP_PARAMETER *Para\r
+ IN UINT8 Tag,\r
+ IN INTN Len,\r
+ IN UINT8 *Data,\r
+ OUT DHCP_PARAMETER *Para\r
)\r
{\r
switch (Tag) {\r
in several buffers, such as the BOOTP options filed, boot file or server\r
name. Each option buffer is required to end with DHCP_TAG_EOP.\r
\r
- @param Buffer The buffer which contains DHCP options\r
- @param BufLen The length of the buffer\r
- @param Check The callback function for each option found\r
- @param Context The opaque parameter for the Check\r
- @param Overload variable to save the value of DHCP_TAG_OVERLOAD\r
- option.\r
+ @param[in] Buffer The buffer which contains DHCP options\r
+ @param[in] BufLen The length of the buffer\r
+ @param[in] Check The callback function for each option found\r
+ @param[in] Context The opaque parameter for the Check\r
+ @param[out] Overload Variable to save the value of DHCP_TAG_OVERLOAD\r
+ option.\r
\r
@retval EFI_SUCCESS All the options are valid\r
@retval EFI_INVALID_PARAMETER The options are mal-formated.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
DhcpIterateBufferOptions (\r
IN UINT8 *Buffer,\r
IN INTN BufLen,\r
- IN DHCP_CHECK_OPTION Check, OPTIONAL\r
+ IN DHCP_CHECK_OPTION Check OPTIONAL,\r
IN VOID *Context,\r
OUT UINT8 *Overload OPTIONAL\r
)\r
the options in FILENAME and SERVERNAME fields. One option may be\r
encoded in several places. See RFC 3396 Encoding Long Options in DHCP\r
\r
- @param Packet The DHCP packet to check the options for\r
- @param Check The callback function to be called for each option\r
- found\r
- @param Context The opaque parameter for Check\r
+ @param[in] Packet The DHCP packet to check the options for\r
+ @param[in] Check The callback function to be called for each option\r
+ found\r
+ @param[in] Context The opaque parameter for Check\r
\r
@retval EFI_SUCCESS The DHCP packet's options are well formated\r
- @retval Others The DHCP packet's options are not well formated\r
+ @retval EFI_INVALID_PARAMETER The DHCP packet's options are not well formated\r
\r
**/\r
EFI_STATUS\r
DhcpIterateOptions (\r
IN EFI_DHCP4_PACKET *Packet,\r
- IN DHCP_CHECK_OPTION Check, OPTIONAL\r
+ IN DHCP_CHECK_OPTION Check OPTIONAL,\r
IN VOID *Context\r
)\r
{\r
\r
if ((Overload == DHCP_OVERLOAD_FILENAME) || (Overload == DHCP_OVERLOAD_BOTH)) {\r
Status = DhcpIterateBufferOptions (\r
- Packet->Dhcp4.Header.BootFileName,\r
+ (UINT8 *) Packet->Dhcp4.Header.BootFileName,\r
128,\r
Check,\r
Context,\r
\r
if ((Overload == DHCP_OVERLOAD_SVRNAME) || (Overload == DHCP_OVERLOAD_BOTH)) {\r
Status = DhcpIterateBufferOptions (\r
- Packet->Dhcp4.Header.ServerName,\r
+ (UINT8 *) Packet->Dhcp4.Header.ServerName,\r
64,\r
Check,\r
Context,\r
\r
\r
/**\r
- Call back function to DhcpiterateOptions to compute each option's\r
+ Call back function to DhcpIterateOptions to compute each option's\r
length. It just adds the data length of all the occurances of this\r
Tag. Context is an array of 256 DHCP_OPTION_COUNT.\r
\r
- @param Tag The current option to check\r
- @param Len The length of the option data\r
- @param Data The option data\r
- @param Context The context, which is a array of 256\r
- DHCP_OPTION_COUNT.\r
+ @param[in] Tag The current option to check\r
+ @param[in] Len The length of the option data\r
+ @param[in] Data The option data\r
+ @param[in] Context The context, which is a array of 256\r
+ DHCP_OPTION_COUNT.\r
\r
@retval EFI_SUCCESS It always returns EFI_SUCCESS.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
DhcpGetOptionLen (\r
IN UINT8 Tag,\r
DHCP_OPTION_COUNT *OpCount;\r
\r
OpCount = (DHCP_OPTION_COUNT *) Context;\r
- OpCount[Tag].Offset = OpCount[Tag].Offset + Len;\r
+ OpCount[Tag].Offset = (UINT16) (OpCount[Tag].Offset + Len);\r
\r
return EFI_SUCCESS;\r
}\r
\r
\r
/**\r
- Call back function to DhcpiterateOptions to consolidate each option's\r
- data. There are maybe several occurance of the same option.\r
+ Call back function to DhcpIterateOptions to consolidate each option's\r
+ data. There are maybe several occurrence of the same option.\r
\r
- @param Tag The option to consolidate its data\r
- @param Len The length of option data\r
- @param Data The data of the option's current occurance\r
- @param Context The context, which is DHCP_OPTION_CONTEXT. This\r
- array is just a wrap to pass THREE parameters.\r
+ @param[in] Tag The option to consolidate its data\r
+ @param[in] Len The length of option data\r
+ @param[in] Data The data of the option's current occurance\r
+ @param[in] Context The context, which is DHCP_OPTION_CONTEXT. This\r
+ array is just a wrap to pass THREE parameters.\r
\r
@retval EFI_SUCCESS It always returns EFI_SUCCESS\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
DhcpFillOption (\r
IN UINT8 Tag,\r
Options[Index].Data = Buf + OptCount[Tag].Offset;\r
}\r
\r
- NetCopyMem (Buf + OptCount[Tag].Offset, Data, Len);\r
+ CopyMem (Buf + OptCount[Tag].Offset, Data, Len);\r
\r
- OptCount[Tag].Offset = OptCount[Tag].Offset + Len;\r
- Options[Index].Len = Options[Index].Len + Len;\r
+ OptCount[Tag].Offset = (UINT16) (OptCount[Tag].Offset + Len);\r
+ Options[Index].Len = (UINT16) (Options[Index].Len + Len);\r
return EFI_SUCCESS;\r
}\r
\r
as a UINT8. It then iterates the DHCP packet to get data length of\r
each option by calling DhcpIterOptions with DhcpGetOptionLen. Now, it\r
knows the number of present options and their length. It allocates a\r
- array of DHCP_OPTION and a continous buffer after the array to put\r
+ array of DHCP_OPTION and a continuous buffer after the array to put\r
all the options' data. Each option's data is pointed to by the Data\r
field in DHCP_OPTION structure. At last, it call DhcpIterateOptions\r
with DhcpFillOption to fill each option's data to its position in the\r
buffer.\r
\r
- @param Packet The DHCP packet to parse the options\r
- @param Count The number of valid dhcp options present in the\r
- packet\r
- @param OptionPoint The array that contains the DHCP options. Caller\r
- should free it.\r
+ @param[in] Packet The DHCP packet to parse the options\r
+ @param[out] Count The number of valid dhcp options present in the\r
+ packet\r
+ @param[out] OptionPoint The array that contains the DHCP options. Caller\r
+ should free it.\r
\r
+ @retval EFI_NOT_FOUND Cannot find any option.\r
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory to parse the packet.\r
@retval EFI_INVALID_PARAMETER The options are mal-formated\r
@retval EFI_SUCCESS The options are parsed into OptionPoint\r
// First compute how many options and how long each option is\r
// with the "Key indexed counting" algorithms.\r
//\r
- OptCount = NetAllocateZeroPool (DHCP_MAX_OPTIONS * sizeof (DHCP_OPTION_COUNT));\r
+ OptCount = AllocateZeroPool (DHCP_MAX_OPTIONS * sizeof (DHCP_OPTION_COUNT));\r
\r
if (OptCount == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
if (OptCount[Index].Offset != 0) {\r
OptCount[Index].Index = (UINT8) OptNum;\r
\r
- TotalLen = TotalLen + OptCount[Index].Offset;\r
- OptCount[Index].Offset = TotalLen - OptCount[Index].Offset;\r
+ TotalLen = (UINT16) (TotalLen + OptCount[Index].Offset);\r
+ OptCount[Index].Offset = (UINT16) (TotalLen - OptCount[Index].Offset);\r
\r
OptNum++;\r
}\r
// Allocate a buffer to hold the DHCP options, and after that, a\r
// continuous buffer to put all the options' data.\r
//\r
- Options = NetAllocateZeroPool (OptNum * sizeof (DHCP_OPTION) + TotalLen);\r
+ Options = AllocateZeroPool (OptNum * sizeof (DHCP_OPTION) + TotalLen);\r
\r
if (Options == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
Status = DhcpIterateOptions (Packet, DhcpFillOption, &Context);\r
\r
if (EFI_ERROR (Status)) {\r
- NetFreePool (Options);\r
+ FreePool (Options);\r
goto ON_EXIT;\r
}\r
\r
*OptionPoint = Options;\r
\r
ON_EXIT:\r
- NetFreePool (OptCount);\r
+ FreePool (OptCount);\r
return Status;\r
}\r
\r
Validate the packet's options. If necessary, allocate\r
and fill in the interested parameters.\r
\r
- @param Packet The packet to validate the options\r
- @param Para The variable to save the DHCP parameters.\r
+ @param[in] Packet The packet to validate the options\r
+ @param[out] Para The variable to save the DHCP parameters.\r
\r
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory to validate the packet.\r
@retval EFI_INVALID_PARAMETER The options are mal-formated\r
}\r
\r
AllOption = NULL;\r
- Status = DhcpParseOption (Packet, &Count, &AllOption);\r
\r
+ Status = DhcpParseOption (Packet, &Count, &AllOption);\r
if (EFI_ERROR (Status) || (Count == 0)) {\r
return Status;\r
}\r
+ ASSERT (AllOption != NULL);\r
\r
Updated = FALSE;\r
- NetZeroMem (&Parameter, sizeof (Parameter));\r
+ ZeroMem (&Parameter, sizeof (Parameter));\r
\r
for (Index = 0; Index < Count; Index++) {\r
Option = &AllOption[Index];\r
}\r
\r
if (Updated && (Para != NULL)) {\r
- if ((*Para = NetAllocatePool (sizeof (DHCP_PARAMETER))) == NULL) {\r
+ *Para = AllocateCopyPool (sizeof (DHCP_PARAMETER), &Parameter);\r
+ if (*Para == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
goto ON_EXIT;\r
}\r
-\r
- CopyMem (*Para, &Parameter, sizeof (DHCP_PARAMETER));\r
}\r
\r
ON_EXIT:\r
- NetFreePool (AllOption);\r
+ FreePool (AllOption);\r
return Status;\r
}\r
\r
Append an option to the memory, if the option is longer than\r
255 bytes, splits it into several options.\r
\r
- @param Buf The buffer to append the option to\r
- @param Tag The option's tag\r
- @param DataLen The length of the option's data\r
- @param Data The option's data\r
+ @param[out] Buf The buffer to append the option to\r
+ @param[in] Tag The option's tag\r
+ @param[in] DataLen The length of the option's data\r
+ @param[in] Data The option's data\r
\r
@return The position to append the next option\r
\r
**/\r
UINT8 *\r
DhcpAppendOption (\r
- IN UINT8 *Buf,\r
- IN UINT8 Tag,\r
- IN UINT16 DataLen,\r
- IN UINT8 *Data\r
+ OUT UINT8 *Buf,\r
+ IN UINT8 Tag,\r
+ IN UINT16 DataLen,\r
+ IN UINT8 *Data\r
)\r
{\r
INTN Index;\r
ASSERT (DataLen != 0);\r
\r
for (Index = 0; Index < (DataLen + 254) / 255; Index++) {\r
- Len = NET_MIN (255, DataLen - Index * 255);\r
+ Len = MIN (255, DataLen - Index * 255);\r
\r
*(Buf++) = Tag;\r
*(Buf++) = (UINT8) Len;\r
- NetCopyMem (Buf, Data + Index * 255, Len);\r
+ CopyMem (Buf, Data + Index * 255, Len);\r
\r
Buf += Len;\r
}\r
Build a new DHCP packet from a seed packet. Options may be deleted or\r
appended. The caller should free the NewPacket when finished using it.\r
\r
- @param SeedPacket The seed packet to start with\r
- @param DeleteCount The number of options to delete\r
- @param DeleteList The options to delete from the packet\r
- @param AppendCount The number of options to append\r
- @param AppendList The options to append to the packet\r
- @param NewPacket The new packet, allocated and built by this\r
- function.\r
+ @param[in] SeedPacket The seed packet to start with\r
+ @param[in] DeleteCount The number of options to delete\r
+ @param[in] DeleteList The options to delete from the packet\r
+ @param[in] AppendCount The number of options to append\r
+ @param[in] AppendList The options to append to the packet\r
+ @param[out] NewPacket The new packet, allocated and built by this\r
+ function.\r
\r
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory\r
+ @retval EFI_INVALID_PARAMETER The options in SeekPacket are mal-formated\r
@retval EFI_SUCCESS The packet is build.\r
\r
**/\r
// Use an array of DHCP_OPTION to mark the existance\r
// and position of each valid options.\r
//\r
- Mark = NetAllocatePool (sizeof (DHCP_OPTION) * DHCP_MAX_OPTIONS);\r
+ Mark = AllocatePool (sizeof (DHCP_OPTION) * DHCP_MAX_OPTIONS);\r
\r
if (Mark == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
goto ON_ERROR;\r
}\r
\r
- for (Index = 0; Index < (UINT32) Count; Index++) {\r
- Mark[SeedOptions[Index].Tag] = SeedOptions[Index];\r
+ if (SeedOptions != NULL) {\r
+ for (Index = 0; Index < (UINT32) Count; Index++) {\r
+ Mark[SeedOptions[Index].Tag] = SeedOptions[Index];\r
+ }\r
}\r
\r
//\r
}\r
\r
Status = EFI_OUT_OF_RESOURCES;\r
- Packet = (EFI_DHCP4_PACKET *) NetAllocatePool (Len);\r
+ Packet = (EFI_DHCP4_PACKET *) AllocatePool (Len);\r
\r
if (Packet == NULL) {\r
goto ON_ERROR;\r
\r
Packet->Size = Len;\r
Packet->Length = 0;\r
- CopyMem (&Packet->Dhcp4.Header, &SeedPacket->Dhcp4.Header, sizeof (EFI_DHCP4_HEADER));\r
+ CopyMem (&Packet->Dhcp4.Header, &SeedPacket->Dhcp4.Header, sizeof (Packet->Dhcp4.Header));\r
Packet->Dhcp4.Magik = DHCP_OPTION_MAGIC;\r
Buf = Packet->Dhcp4.Option;\r
\r
\r
ON_ERROR:\r
if (SeedOptions != NULL) {\r
- NetFreePool (SeedOptions);\r
+ FreePool (SeedOptions);\r
}\r
\r
- NetFreePool (Mark);\r
+ FreePool (Mark);\r
return Status;\r
}\r