4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mtftp6 option parse functions implementation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync are licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync which accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync http://opensource.org/licenses/bsd-license.php.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "Mtftp6Impl.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCHAR8 *mMtftp6SupportedOptions[MTFTP6_SUPPORTED_OPTIONS_NUM] = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "blksize",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "timeout",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "tsize",
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync "multicast"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Parse the NULL terminated ASCII string of multicast option.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Str The pointer to the Ascii string of multicast option.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ExtInfo The pointer to the option information to be filled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Parse the multicast option successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER The string is malformatted.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed to perform the operation due to lack of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync resources.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncMtftp6ParseMcastOption (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 *Str,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN MTFTP6_EXT_OPTION_INFO *ExtInfo
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Num;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CHAR8 *Ip6Str;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CHAR8 *TempStr;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The multicast option is formated like "addr,port,mc"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The server can also omit the ip and port, use ",,1"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*Str == ',') {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (&ExtInfo->McastIp, sizeof (EFI_IPv6_ADDRESS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6Str = (CHAR8 *) AllocateCopyPool (AsciiStrSize ((CHAR8 *) Str), Str);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6Str == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The IPv6 address locates before comma in the input Str.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TempStr = Ip6Str;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ((*TempStr != '\0') && (*TempStr != ',')) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TempStr++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *TempStr = '\0';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = NetLibAsciiStrToIp6 (Ip6Str, &ExtInfo->McastIp);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Ip6Str);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ((*Str != '\0') && (*Str != ',')) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Str++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*Str != ',') {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Str++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Convert the port setting. the server can send us a port number or
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // empty string. such as the port in ",,1"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*Str == ',') {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtInfo->McastPort = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Num = (UINT32) AsciiStrDecimalToUintn ((CHAR8 *) Str);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Num > 65535) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtInfo->McastPort = (UINT16) Num;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (NET_IS_DIGIT (*Str)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Str++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*Str != ',') {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Str++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check the master/slave setting, 1 for master, 0 for slave.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Num = (UINT32) AsciiStrDecimalToUintn ((CHAR8 *) Str);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Num != 0 && Num != 1) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtInfo->IsMaster = (BOOLEAN) (Num == 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (NET_IS_DIGIT (*Str)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Str++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*Str != '\0') {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Parse the MTFTP6 extesion options.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Options The pointer to the extension options list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Count The num of the extension options.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IsRequest If FALSE, the extension options is included
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync by a request packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ExtInfo The pointer to the option information to be filled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Parse the multicast option successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER There is one option is malformatted at least.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_UNSUPPORTED There is one option is not supported at least.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncMtftp6ParseExtensionOption (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_MTFTP6_OPTION *Options,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 Count,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BOOLEAN IsRequest,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN MTFTP6_EXT_OPTION_INFO *ExtInfo
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_MTFTP6_OPTION *Opt;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Value;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtInfo->BitMap = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (Index = 0; Index < Count; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Opt = Options + Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Opt->OptionStr == NULL || Opt->ValueStr == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (AsciiStriCmp ((CHAR8 *) Opt->OptionStr, "blksize") == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // block size option, valid value is between [8, 65464]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value = (UINT32) AsciiStrDecimalToUintn ((CHAR8 *) Opt->ValueStr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Value < 8) || (Value > 65464)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtInfo->BlkSize = (UINT16) Value;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtInfo->BitMap |= MTFTP6_OPT_BLKSIZE_BIT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (AsciiStriCmp ((CHAR8 *) Opt->OptionStr, "timeout") == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // timeout option, valid value is between [1, 255]
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value = (UINT32) AsciiStrDecimalToUintn ((CHAR8 *) Opt->ValueStr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Value < 1 || Value > 255) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtInfo->Timeout = (UINT8) Value;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtInfo->BitMap |= MTFTP6_OPT_TIMEOUT_BIT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (AsciiStriCmp ((CHAR8 *) Opt->OptionStr, "tsize") == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // tsize option, the biggest transfer supported is 4GB with block size option
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtInfo->Tsize = (UINT32) AsciiStrDecimalToUintn ((CHAR8 *) Opt->ValueStr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtInfo->BitMap |= MTFTP6_OPT_TSIZE_BIT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (AsciiStriCmp ((CHAR8 *) Opt->OptionStr, "multicast") == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Multicast option, if it is a request, the value must be a zero string,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // otherwise, it must be like "addr,port,mc" string, mc indicates master.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!IsRequest) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Mtftp6ParseMcastOption (Opt->ValueStr, ExtInfo);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (*(Opt->ValueStr) != '\0') {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtInfo->BitMap |= MTFTP6_OPT_MCAST_BIT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (IsRequest) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If it's a request, unsupported; else if it's a reply, ignore.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Go through the packet to fill the options array with the start
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync addresses of each MTFTP option name/value pair.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Packet The packet to be checked.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] PacketLen The length of the packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Count The num of the Options on input.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The actual one on output.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Options The option array to be filled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync It is optional.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The packet has been parsed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER The packet is malformatted.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_BUFFER_TOO_SMALL The Options array is too small.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_PROTOCOL_ERROR An unexpected MTFTPv6 packet was received.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncMtftp6ParsePacketOption (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_MTFTP6_PACKET *Packet,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 PacketLen,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT UINT32 *Count,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_MTFTP6_OPTION *Options OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *Cur;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *Last;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 Num;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *Name;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *Value;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Num = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Cur = (UINT8 *) Packet + MTFTP6_OPCODE_LEN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Last = (UINT8 *) Packet + PacketLen - 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // process option name and value pairs.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The last byte is always zero.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (Cur < Last) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Name = Cur;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (*Cur != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Cur++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Cur == Last) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_PROTOCOL_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value = ++Cur;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (*Cur != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Cur++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Num++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Options != NULL && Num <= *Count) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Options[Num - 1].OptionStr = Name;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Options[Num - 1].ValueStr = Value;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Cur++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return buffer too small if the buffer passed-in isn't enough.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*Count < Num || Options == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Count = Num;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_BUFFER_TOO_SMALL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Count = Num;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Go through the packet, generate option list array and fill it
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync by the result of parse options.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Packet The packet to be checked.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] PacketLen The length of the packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] OptionCount The num of the Options on input.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The actual one on output.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] OptionList The option list array to be generated
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and filled. It is optional.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The packet has been parsed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER The packet is malformatted.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_PROTOCOL_ERROR There is one option is malformatted at least.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND The packet has no options.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for the array.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_BUFFER_TOO_SMALL The size of option list array is too small.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncMtftp6ParseStart (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_MTFTP6_PACKET *Packet,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 PacketLen,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT UINT32 *OptionCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT EFI_MTFTP6_OPTION **OptionList OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PacketLen == 0 || Packet == NULL || OptionCount == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *OptionCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (OptionList != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *OptionList = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NTOHS (Packet->OpCode) != EFI_MTFTP6_OPCODE_OACK) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The last byte must be zero to terminate the options.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*((UINT8 *) Packet + PacketLen - 1) != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_PROTOCOL_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Parse packet with NULL buffer for the first time to get the number
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // of options in the packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Mtftp6ParsePacketOption (Packet, PacketLen, OptionCount, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Status != EFI_BUFFER_TOO_SMALL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return not found if there is no option parsed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*OptionCount == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_NOT_FOUND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Only need parse out the number of options.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (OptionList == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Allocate the buffer according to the option number parsed before.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *OptionList = AllocateZeroPool (*OptionCount * sizeof (EFI_MTFTP6_OPTION));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (*OptionList == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Parse packet with allocated buffer for the second time to fill the pointer array
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // of the options in the packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Mtftp6ParsePacketOption (Packet, PacketLen, OptionCount, *OptionList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}