/** @file The assistant function implementation for IpSecConfig application. Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
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. // 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; }