Signed-off-by: Dong Eric <eric.dong@intel.com> Reviewed-by: Ye Ting <ting.ye@intel.com> Reviewed-by: Ouyang Qian <Ouyang.qian@intel.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13175 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			421 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			421 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  The assistant function implementation for IpSecConfig application.
 | 
						|
 | 
						|
  Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
 | 
						|
 | 
						|
  This program and the accompanying materials
 | 
						|
  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
 | 
						|
  http://opensource.org/licenses/bsd-license.php.
 | 
						|
 | 
						|
  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "IpSecConfig.h"
 | 
						|
#include "Helper.h"
 | 
						|
 | 
						|
/**
 | 
						|
  Helper function called to change an input parameter in the string format to a number.
 | 
						|
 | 
						|
  @param[in]      FlagStr         The pointer to the flag string.
 | 
						|
  @param[in]      Maximum         Greatest value number.
 | 
						|
  @param[in, out] ValuePtr        The pointer to the input parameter in string format.
 | 
						|
  @param[in]      ByteCount       The valid byte count
 | 
						|
  @param[in]      Map             The pointer to the STR2INT table.
 | 
						|
  @param[in]      ParamPackage    The pointer to the ParamPackage list.
 | 
						|
  @param[in]      FormatMask      The bit mask.
 | 
						|
                                  BIT 0 set indicates the value of a flag might be a number.
 | 
						|
                                  BIT 1 set indicates the value of a flag might be a string that needs to be looked up.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS              The operation completed successfully.
 | 
						|
  @retval EFI_NOT_FOUND            The input parameter can't be found.
 | 
						|
  @retval EFI_INVALID_PARAMETER    The input parameter is an invalid input.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
GetNumber (
 | 
						|
  IN     CHAR16        *FlagStr,
 | 
						|
  IN     UINT64        Maximum,
 | 
						|
  IN OUT VOID          *ValuePtr,
 | 
						|
  IN     UINTN         ByteCount,
 | 
						|
  IN     STR2INT       *Map,
 | 
						|
  IN     LIST_ENTRY    *ParamPackage,
 | 
						|
  IN     UINT32        FormatMask
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS      Status;
 | 
						|
  UINT64          Value64;
 | 
						|
  BOOLEAN         Converted;
 | 
						|
  UINTN           Index;
 | 
						|
  CONST CHAR16    *ValueStr;
 | 
						|
 | 
						|
  ASSERT (FormatMask & (FORMAT_NUMBER | FORMAT_STRING));
 | 
						|
 | 
						|
  Converted = FALSE;
 | 
						|
  Value64   = 0;
 | 
						|
  ValueStr  = ShellCommandLineGetValue (ParamPackage, FlagStr);
 | 
						|
 | 
						|
  if (ValueStr == NULL) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // Try to convert to integer directly if MaybeNumber is TRUE.
 | 
						|
    //
 | 
						|
    if ((FormatMask & FORMAT_NUMBER) != 0) {
 | 
						|
      Value64 = StrToUInteger (ValueStr, &Status);
 | 
						|
      if (!EFI_ERROR (Status)) {
 | 
						|
        //
 | 
						|
        // Convert successfully.
 | 
						|
        //
 | 
						|
        if (Value64 > Maximum) {
 | 
						|
          //
 | 
						|
          // But the result is invalid
 | 
						|
          //
 | 
						|
          ShellPrintHiiEx (
 | 
						|
            -1,
 | 
						|
            -1,
 | 
						|
            NULL,
 | 
						|
            STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
 | 
						|
            mHiiHandle,
 | 
						|
            mAppName,
 | 
						|
            FlagStr,
 | 
						|
            ValueStr
 | 
						|
            );
 | 
						|
          return EFI_INVALID_PARAMETER;
 | 
						|
        }
 | 
						|
 | 
						|
        Converted = TRUE;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (!Converted && ((FormatMask & FORMAT_STRING) != 0)) {
 | 
						|
      //
 | 
						|
      // Convert falied, so use String->Integer map.
 | 
						|
      //
 | 
						|
      ASSERT (Map != NULL);
 | 
						|
      Value64 = MapStringToInteger (ValueStr, Map);
 | 
						|
      if (Value64 == (UINT32) -1) {
 | 
						|
        //
 | 
						|
        // Cannot find the string in the map.
 | 
						|
        //
 | 
						|
        ShellPrintHiiEx (
 | 
						|
          -1,
 | 
						|
          -1,
 | 
						|
          NULL,
 | 
						|
          STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
 | 
						|
          mHiiHandle,
 | 
						|
          mAppName,
 | 
						|
          FlagStr,
 | 
						|
          ValueStr
 | 
						|
          );
 | 
						|
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ACCEPT_PARAMETERS), mHiiHandle);
 | 
						|
        for (Index = 0; Map[Index].String != NULL; Index++) {
 | 
						|
          Print (L" %s", Map[Index].String);
 | 
						|
        }
 | 
						|
 | 
						|
        Print (L"\n");
 | 
						|
        return EFI_INVALID_PARAMETER;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    CopyMem (ValuePtr, &Value64, ByteCount);
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Helper function called to convert a string containing an Ipv4 or Ipv6 Internet Protocol address
 | 
						|
  into a proper address for the EFI_IP_ADDRESS structure.
 | 
						|
 | 
						|
  @param[in]  Ptr    The pointer to the string containing an Ipv4 or Ipv6 Internet Protocol address.
 | 
						|
  @param[out] Ip     The pointer to the EFI_IP_ADDRESS structure to contain the result.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS              The operation completed successfully.
 | 
						|
  @retval EFI_INVALID_PARAMETER    Invalid parameter.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EfiInetAddr2 (
 | 
						|
  IN  CHAR16            *Ptr,
 | 
						|
  OUT EFI_IP_ADDRESS    *Ip
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS    Status;
 | 
						|
 | 
						|
  if ((Ptr == NULL) || (Ip == NULL)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Parse the input address as Ipv4 Address first.
 | 
						|
  //
 | 
						|
  Status = NetLibStrToIp4 (Ptr, &Ip->v4);
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = NetLibStrToIp6 (Ptr, &Ip->v6);
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Helper function called to calculate the prefix length associated with the string
 | 
						|
  containing an Ipv4 or Ipv6 Internet Protocol address.
 | 
						|
 | 
						|
  @param[in]  Ptr     The pointer to the string containing an Ipv4 or Ipv6 Internet Protocol address.
 | 
						|
  @param[out] Addr    The pointer to the EFI_IP_ADDRESS_INFO structure to contain the result.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS              The operation completed successfully.
 | 
						|
  @retval EFI_INVALID_PARAMETER    Invalid parameter.
 | 
						|
  @retval Others                   Other mistake case.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EfiInetAddrRange (
 | 
						|
  IN  CHAR16                 *Ptr,
 | 
						|
  OUT EFI_IP_ADDRESS_INFO    *Addr
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS    Status;
 | 
						|
 | 
						|
  if ((Ptr == NULL) || (Addr == NULL)) {
 | 
						|
    return EFI_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = NetLibStrToIp4 (Ptr, &Addr->Address.v4);
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    if ((UINT32)(*Addr->Address.v4.Addr) == 0) {
 | 
						|
      Addr->PrefixLength = 0;
 | 
						|
    } else {
 | 
						|
      Addr->PrefixLength = 32;
 | 
						|
    }
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = NetLibStrToIp6andPrefix (Ptr, &Addr->Address.v6, &Addr->PrefixLength);
 | 
						|
  if (!EFI_ERROR (Status) && (Addr->PrefixLength == 0xFF)) {
 | 
						|
    Addr->PrefixLength = 128;
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Helper function called to calculate the port range associated with the string.
 | 
						|
 | 
						|
  @param[in]  Ptr          The pointer to the string containing a port and range.
 | 
						|
  @param[out] Port         The pointer to the Port to contain the result.
 | 
						|
  @param[out] PortRange    The pointer to the PortRange to contain the result.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS              The operation completed successfully.
 | 
						|
  @retval EFI_INVALID_PARAMETER    Invalid parameter.
 | 
						|
  @retval Others                   Other mistake case.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EfiInetPortRange (
 | 
						|
  IN  CHAR16    *Ptr,
 | 
						|
  OUT UINT16    *Port,
 | 
						|
  OUT UINT16    *PortRange
 | 
						|
  )
 | 
						|
{
 | 
						|
  CHAR16        *BreakPtr;
 | 
						|
  CHAR16        Ch;
 | 
						|
  EFI_STATUS    Status;
 | 
						|
 | 
						|
  for (BreakPtr = Ptr; (*BreakPtr != L'\0') && (*BreakPtr != L':'); BreakPtr++) {
 | 
						|
    ;
 | 
						|
  }
 | 
						|
 | 
						|
  Ch        = *BreakPtr;
 | 
						|
  *BreakPtr = L'\0';
 | 
						|
  *Port     = (UINT16) StrToUInteger (Ptr, &Status);
 | 
						|
  *BreakPtr = Ch;
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  *PortRange = 0;
 | 
						|
  if (*BreakPtr == L':') {
 | 
						|
    BreakPtr++;
 | 
						|
    *PortRange = (UINT16) StrToUInteger (BreakPtr, &Status);
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
 | 
						|
    if (*PortRange < *Port) {
 | 
						|
      return EFI_INVALID_PARAMETER;
 | 
						|
    }
 | 
						|
 | 
						|
    *PortRange = (UINT16) (*PortRange - *Port);
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Helper function called to transfer a string to an unsigned integer.
 | 
						|
 | 
						|
  @param[in]  Str       The pointer to the string.
 | 
						|
  @param[out] Status    The operation status.
 | 
						|
 | 
						|
  @return The integer value of converted Str.
 | 
						|
**/
 | 
						|
UINT64
 | 
						|
StrToUInteger (
 | 
						|
  IN  CONST CHAR16    *Str,
 | 
						|
  OUT EFI_STATUS      *Status
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT64    Value;
 | 
						|
  UINT64    NewValue;
 | 
						|
  CHAR16    *StrTail;
 | 
						|
  CHAR16    Char;
 | 
						|
  UINTN     Base;
 | 
						|
  UINTN     Len;
 | 
						|
 | 
						|
  Base    = 10;
 | 
						|
  Value   = 0;
 | 
						|
  *Status = EFI_ABORTED;
 | 
						|
 | 
						|
  //
 | 
						|
  // Skip leading white space.
 | 
						|
  //
 | 
						|
  while ((*Str != 0) && (*Str == ' ')) {
 | 
						|
    Str++;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // For NULL Str, just return.
 | 
						|
  //
 | 
						|
  if (*Str == 0) {
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Skip white space in tail.
 | 
						|
  //
 | 
						|
  Len     = StrLen (Str);
 | 
						|
  StrTail = (CHAR16 *) (Str + Len - 1);
 | 
						|
  while (*StrTail == ' ') {
 | 
						|
    *StrTail = 0;
 | 
						|
    StrTail--;
 | 
						|
  }
 | 
						|
 | 
						|
  Len = StrTail - Str + 1;
 | 
						|
 | 
						|
  //
 | 
						|
  // Check hex prefix '0x'.
 | 
						|
  //
 | 
						|
  if ((Len >= 2) && (*Str == '0') && ((*(Str + 1) == 'x') || (*(Str + 1) == 'X'))) {
 | 
						|
    Str += 2;
 | 
						|
    Len -= 2;
 | 
						|
    Base = 16;
 | 
						|
  }
 | 
						|
 | 
						|
  if (Len == 0) {
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Convert the string to value.
 | 
						|
  //
 | 
						|
  for (; Str <= StrTail; Str++) {
 | 
						|
 | 
						|
    Char = *Str;
 | 
						|
 | 
						|
    if (Base == 16) {
 | 
						|
      if (RShiftU64 (Value, 60) != 0) {
 | 
						|
        //
 | 
						|
        // Overflow here x16.
 | 
						|
        //
 | 
						|
        return 0;
 | 
						|
      }
 | 
						|
 | 
						|
      NewValue = LShiftU64 (Value, 4);
 | 
						|
    } else {
 | 
						|
      if (RShiftU64 (Value, 61) != 0) {
 | 
						|
        //
 | 
						|
        // Overflow here x8.
 | 
						|
        //
 | 
						|
        return 0;
 | 
						|
      }
 | 
						|
 | 
						|
      NewValue  = LShiftU64 (Value, 3);
 | 
						|
      Value     = LShiftU64 (Value, 1);
 | 
						|
      NewValue += Value;
 | 
						|
      if (NewValue < Value) {
 | 
						|
        //
 | 
						|
        // Overflow here.
 | 
						|
        //
 | 
						|
        return 0;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    Value = NewValue;
 | 
						|
 | 
						|
    if ((Base == 16) && (Char >= 'a') && (Char <= 'f')) {
 | 
						|
      Char = (CHAR16) (Char - 'a' + 'A');
 | 
						|
    }
 | 
						|
 | 
						|
    if ((Base == 16) && (Char >= 'A') && (Char <= 'F')) {
 | 
						|
      Value += (Char - 'A') + 10;
 | 
						|
    } else if ((Char >= '0') && (Char <= '9')) {
 | 
						|
      Value += (Char - '0');
 | 
						|
    } else {
 | 
						|
      //
 | 
						|
      // Unexpected Char encountered.
 | 
						|
      //
 | 
						|
      return 0;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  *Status = EFI_SUCCESS;
 | 
						|
  return Value;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Helper function called to transfer a string to an unsigned integer according to the map table.
 | 
						|
 | 
						|
  @param[in] Str    The pointer to the string.
 | 
						|
  @param[in] Map    The pointer to the map table.
 | 
						|
 | 
						|
  @return The integer value of converted Str. If not found, then return -1.
 | 
						|
**/
 | 
						|
UINT32
 | 
						|
MapStringToInteger (
 | 
						|
  IN CONST CHAR16    *Str,
 | 
						|
  IN STR2INT         *Map
 | 
						|
  )
 | 
						|
{
 | 
						|
  STR2INT       *Item;
 | 
						|
 | 
						|
  for (Item = Map; Item->String != NULL; Item++) {
 | 
						|
    if (StrCmp (Item->String, Str) == 0) {
 | 
						|
      return Item->Integer;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return (UINT32) -1;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Helper function called to transfer an unsigned integer to a string according to the map table.
 | 
						|
 | 
						|
  @param[in] Integer    The pointer to the string.
 | 
						|
  @param[in] Map        The pointer to the map table.
 | 
						|
 | 
						|
  @return The converted Str. If not found, then return NULL.
 | 
						|
**/
 | 
						|
CHAR16 *
 | 
						|
MapIntegerToString (
 | 
						|
  IN UINT32     Integer,
 | 
						|
  IN STR2INT    *Map
 | 
						|
  )
 | 
						|
{
 | 
						|
  STR2INT    *Item;
 | 
						|
 | 
						|
  for (Item = Map; Item->String != NULL; Item++) {
 | 
						|
    if (Integer == Item->Integer) {
 | 
						|
      return Item->String;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return NULL;
 | 
						|
}
 |