/** @file\r
+ Routines to process MTFTP4 options.\r
\r
-Copyright (c) 2006, Intel Corporation\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
-http://opensource.org/licenses/bsd-license.php\r
-\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
- Mtftp4Option.c\r
-\r
-Abstract:\r
- routines to process MTFTP4 options\r
-\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
\r
CHAR8 *mMtftp4SupportedOptions[MTFTP4_SUPPORTED_OPTIONS] = {\r
"blksize",\r
+ "windowsize",\r
"timeout",\r
"tsize",\r
"multicast"\r
};\r
\r
\r
+/**\r
+ Check whether two ascii strings are equel, ignore the case.\r
+\r
+ @param Str1 The first ascii string\r
+ @param Str2 The second ascii string\r
+\r
+ @retval TRUE Two strings are equal when case is ignored.\r
+ @retval FALSE Two string are not equal.\r
+\r
+**/\r
+BOOLEAN\r
+NetStringEqualNoCase (\r
+ IN UINT8 *Str1,\r
+ IN UINT8 *Str2\r
+ )\r
+{\r
+ UINT8 Ch1;\r
+ UINT8 Ch2;\r
+\r
+ ASSERT ((Str1 != NULL) && (Str2 != NULL));\r
+\r
+ for (; (*Str1 != '\0') && (*Str2 != '\0'); Str1++, Str2++) {\r
+ Ch1 = *Str1;\r
+ Ch2 = *Str2;\r
+\r
+ //\r
+ // Convert them to lower case then compare two\r
+ //\r
+ if (('A' <= Ch1) && (Ch1 <= 'Z')) {\r
+ Ch1 += 'a' - 'A';\r
+ }\r
+\r
+ if (('A' <= Ch2) && (Ch2 <= 'Z')) {\r
+ Ch2 += 'a' - 'A';\r
+ }\r
+\r
+ if (Ch1 != Ch2) {\r
+ return FALSE;\r
+ }\r
+ }\r
+\r
+ return (BOOLEAN) (*Str1 == *Str2);\r
+}\r
+\r
+\r
+/**\r
+ Convert a string to a UINT32 number.\r
+\r
+ @param Str The string to convert from\r
+\r
+ @return The number get from the string\r
+\r
+**/\r
+UINT32\r
+NetStringToU32 (\r
+ IN UINT8 *Str\r
+ )\r
+{\r
+ UINT32 Num;\r
+\r
+ ASSERT (Str != NULL);\r
+\r
+ Num = 0;\r
+\r
+ for (; NET_IS_DIGIT (*Str); Str++) {\r
+ Num = Num * 10 + (*Str - '0');\r
+ }\r
+\r
+ return Num;\r
+}\r
+\r
+\r
+/**\r
+ Convert a string of the format "192.168.0.1" to an IP address.\r
+\r
+ @param Str The string representation of IP\r
+ @param Ip The varible to get IP.\r
+\r
+ @retval EFI_INVALID_PARAMETER The IP string is invalid.\r
+ @retval EFI_SUCCESS The IP is parsed into the Ip\r
+\r
+**/\r
+EFI_STATUS\r
+NetStringToIp (\r
+ IN UINT8 *Str,\r
+ OUT IP4_ADDR *Ip\r
+ )\r
+{\r
+ UINT32 Byte;\r
+ UINT32 Addr;\r
+ UINTN Index;\r
+\r
+ *Ip = 0;\r
+ Addr = 0;\r
+\r
+ for (Index = 0; Index < 4; Index++) {\r
+ if (!NET_IS_DIGIT (*Str)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Byte = NetStringToU32 (Str);\r
+\r
+ if (Byte > 255) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Addr = (Addr << 8) | Byte;\r
+\r
+ //\r
+ // Skip all the digitals and check whether the sepeator is the dot\r
+ //\r
+ while (NET_IS_DIGIT (*Str)) {\r
+ Str++;\r
+ }\r
+\r
+ if ((Index < 3) && (*Str != '.')) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Str++;\r
+ }\r
+\r
+ *Ip = Addr;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
/**\r
Go through the packet to fill the Options array with the start\r
addresses of each MTFTP option name/value pair.\r
@retval EFI_SUCCESS The packet has been parsed into the Options array.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
Mtftp4FillOptions (\r
- IN EFI_MTFTP4_PACKET *Packet,\r
- IN UINT32 PacketLen,\r
- IN OUT UINT32 *Count,\r
- OUT EFI_MTFTP4_OPTION *Options OPTIONAL\r
+ IN EFI_MTFTP4_PACKET *Packet,\r
+ IN UINT32 PacketLen,\r
+ IN OUT UINT32 *Count,\r
+ OUT EFI_MTFTP4_OPTION *Options OPTIONAL\r
)\r
{\r
UINT8 *Cur;\r
\r
\r
/**\r
- Allocate and fill in a array of Mtftp options from the Packet. It\r
- first calls Mtftp4FillOption to get the option number, then allocate\r
+ Allocate and fill in a array of Mtftp options from the Packet.\r
+\r
+ It first calls Mtftp4FillOption to get the option number, then allocate\r
the array, at last, call Mtftp4FillOption again to save the options.\r
\r
@param Packet The packet to parse\r
**/\r
EFI_STATUS\r
Mtftp4ExtractOptions (\r
- IN EFI_MTFTP4_PACKET *Packet,\r
- IN UINT32 PacketLen,\r
- IN OUT UINT32 *OptionCount,\r
- OUT EFI_MTFTP4_OPTION **OptionList OPTIONAL\r
+ IN EFI_MTFTP4_PACKET *Packet,\r
+ IN UINT32 PacketLen,\r
+ OUT UINT32 *OptionCount,\r
+ OUT EFI_MTFTP4_OPTION **OptionList OPTIONAL\r
)\r
{\r
EFI_STATUS Status;\r
}\r
\r
\r
-/**\r
- Check whether two ascii strings are equel, ignore the case.\r
-\r
- @param Str1 The first ascii string\r
- @param Str2 The second ascii string\r
-\r
- @retval TRUE Two strings are equal when case is ignored.\r
- @retval FALSE Two string are not equal.\r
-\r
-**/\r
-BOOLEAN\r
-NetStringEqualNoCase (\r
- IN UINT8 *Str1,\r
- IN UINT8 *Str2\r
- )\r
-{\r
- UINT8 Ch1;\r
- UINT8 Ch2;\r
-\r
- ASSERT ((Str1 != NULL) && (Str2 != NULL));\r
-\r
- for (; (*Str1 != '\0') && (*Str2 != '\0'); Str1++, Str2++) {\r
- Ch1 = *Str1;\r
- Ch2 = *Str2;\r
-\r
- //\r
- // Convert them to lower case then compare two\r
- //\r
- if (('A' <= Ch1) && (Ch1 <= 'Z')) {\r
- Ch1 += 'a' - 'A';\r
- }\r
-\r
- if (('A' <= Ch2) && (Ch2 <= 'Z')) {\r
- Ch2 += 'a' - 'A';\r
- }\r
-\r
- if (Ch1 != Ch2) {\r
- return FALSE;\r
- }\r
- }\r
-\r
- return (BOOLEAN) (*Str1 == *Str2);\r
-}\r
-\r
-\r
-/**\r
- Convert a string to a UINT32 number.\r
-\r
- @param Str The string to convert from\r
-\r
- @return The number get from the string\r
-\r
-**/\r
-UINT32\r
-NetStringToU32 (\r
- IN UINT8 *Str\r
- )\r
-{\r
- UINT32 Num;\r
-\r
- ASSERT (Str != NULL);\r
-\r
- Num = 0;\r
-\r
- for (; NET_IS_DIGIT (*Str); Str++) {\r
- Num = Num * 10 + (*Str - '0');\r
- }\r
-\r
- return Num;\r
-}\r
-\r
-\r
-/**\r
- Convert a string of the format "192.168.0.1" to an IP address.\r
-\r
- @param Str The string representation of IP\r
- @param Ip The varible to get IP.\r
-\r
- @retval EFI_INVALID_PARAMETER The IP string is invalid.\r
- @retval EFI_SUCCESS The IP is parsed into the Ip\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-NetStringToIp (\r
- IN UINT8 *Str,\r
- OUT IP4_ADDR *Ip\r
- )\r
-{\r
- UINT32 Byte;\r
- UINT32 Addr;\r
- UINTN Index;\r
-\r
- *Ip = 0;\r
- Addr = 0;\r
-\r
- for (Index = 0; Index < 4; Index++) {\r
- if (!NET_IS_DIGIT (*Str)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Byte = NetStringToU32 (Str);\r
-\r
- if (Byte > 255) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Addr = (Addr << 8) | Byte;\r
-\r
- //\r
- // Skip all the digitals and check whether the sepeator is the dot\r
- //\r
- while (NET_IS_DIGIT (*Str)) {\r
- Str++;\r
- }\r
-\r
- if ((Index < 3) && (*Str != '.')) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Str++;\r
- }\r
-\r
- *Ip = Addr;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
/**\r
Parse the MTFTP multicast option.\r
\r
@retval EFI_SUCCESS The multicast value is parsed into the Option\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
Mtftp4ExtractMcast (\r
- IN UINT8 *Value,\r
- IN MTFTP4_OPTION *Option\r
+ IN UINT8 *Value,\r
+ IN OUT MTFTP4_OPTION *Option\r
)\r
{\r
EFI_STATUS Status;\r
return Status;\r
}\r
\r
- while (*Value && (*Value != ',')) {\r
+ while ((*Value != 0) && (*Value != ',')) {\r
Value++;\r
}\r
}\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- Option->McastPort = (UINT16)Num;\r
+ Option->McastPort = (UINT16) Num;\r
\r
while (NET_IS_DIGIT (*Value)) {\r
Value++;\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- Option->Master = (BOOLEAN)(Num == 1);\r
+ Option->Master = (BOOLEAN) (Num == 1);\r
\r
while (NET_IS_DIGIT (*Value)) {\r
Value++;\r
can access directly.\r
\r
@param Options The option array, which contains addresses of each\r
- option's name/value string.\r
+ option's name/value string.\r
@param Count The number of options in the Options\r
@param Request Whether this is a request or OACK. The format of\r
multicast is different according to this setting.\r
+ @param Operation The current performed operation.\r
@param MtftpOption The MTFTP4_OPTION for easy access.\r
\r
@retval EFI_INVALID_PARAMETER The option is mal-formated\r
**/\r
EFI_STATUS\r
Mtftp4ParseOption (\r
- IN EFI_MTFTP4_OPTION *Options,\r
- IN UINT32 Count,\r
- IN BOOLEAN Request,\r
- OUT MTFTP4_OPTION *MtftpOption\r
+ IN EFI_MTFTP4_OPTION *Options,\r
+ IN UINT32 Count,\r
+ IN BOOLEAN Request,\r
+ IN UINT16 Operation,\r
+ OUT MTFTP4_OPTION *MtftpOption\r
)\r
{\r
EFI_STATUS Status;\r
\r
MtftpOption->Exist |= MTFTP4_MCAST_EXIST;\r
\r
+ } else if (NetStringEqualNoCase (This->OptionStr, (UINT8 *) "windowsize")) {\r
+ if (Operation == EFI_MTFTP4_OPCODE_WRQ) {\r
+ //\r
+ // Currently, windowsize is not supported in the write operation.\r
+ //\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Value = NetStringToU32 (This->ValueStr);\r
+\r
+ if (Value < 1) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ MtftpOption->WindowSize = (UINT16) Value;\r
+ MtftpOption->Exist |= MTFTP4_WINDOWSIZE_EXIST;\r
} else if (Request) {\r
//\r
// Ignore the unsupported option if it is a reply, and return\r
\r
@param Packet The OACK packet to parse\r
@param PacketLen The length of the packet\r
+ @param Operation The current performed operation.\r
@param MtftpOption The MTFTP_OPTION for easy access.\r
\r
@retval EFI_INVALID_PARAMETER The packet option is mal-formated\r
**/\r
EFI_STATUS\r
Mtftp4ParseOptionOack (\r
- IN EFI_MTFTP4_PACKET *Packet,\r
- IN UINT32 PacketLen,\r
- OUT MTFTP4_OPTION *MtftpOption\r
+ IN EFI_MTFTP4_PACKET *Packet,\r
+ IN UINT32 PacketLen,\r
+ IN UINT16 Operation,\r
+ OUT MTFTP4_OPTION *MtftpOption\r
)\r
{\r
EFI_MTFTP4_OPTION *OptionList;\r
if (EFI_ERROR (Status) || (Count == 0)) {\r
return Status;\r
}\r
+ ASSERT (OptionList != NULL);\r
\r
- Status = Mtftp4ParseOption (OptionList, Count, FALSE, MtftpOption);\r
+ Status = Mtftp4ParseOption (OptionList, Count, FALSE, Operation, MtftpOption);\r
\r
- gBS->FreePool (OptionList);\r
+ FreePool (OptionList);\r
return Status;\r
}\r