Home | History | Annotate | Download | only in IpsecConfig
      1 /** @file
      2   The assistant function implementation for IpSecConfig application.
      3 
      4   Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
      5 
      6   This program and the accompanying materials
      7   are licensed and made available under the terms and conditions of the BSD License
      8   which accompanies this distribution.  The full text of the license may be found at
      9   http://opensource.org/licenses/bsd-license.php.
     10 
     11   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 
     16 #include "IpSecConfig.h"
     17 #include "Helper.h"
     18 
     19 /**
     20   Helper function called to change an input parameter in the string format to a number.
     21 
     22   @param[in]      FlagStr         The pointer to the flag string.
     23   @param[in]      Maximum         Greatest value number.
     24   @param[in, out] ValuePtr        The pointer to the input parameter in string format.
     25   @param[in]      ByteCount       The valid byte count
     26   @param[in]      Map             The pointer to the STR2INT table.
     27   @param[in]      ParamPackage    The pointer to the ParamPackage list.
     28   @param[in]      FormatMask      The bit mask.
     29                                   BIT 0 set indicates the value of a flag might be a number.
     30                                   BIT 1 set indicates the value of a flag might be a string that needs to be looked up.
     31 
     32   @retval EFI_SUCCESS              The operation completed successfully.
     33   @retval EFI_NOT_FOUND            The input parameter can't be found.
     34   @retval EFI_INVALID_PARAMETER    The input parameter is an invalid input.
     35 **/
     36 EFI_STATUS
     37 GetNumber (
     38   IN     CHAR16        *FlagStr,
     39   IN     UINT64        Maximum,
     40   IN OUT VOID          *ValuePtr,
     41   IN     UINTN         ByteCount,
     42   IN     STR2INT       *Map,
     43   IN     LIST_ENTRY    *ParamPackage,
     44   IN     UINT32        FormatMask
     45   )
     46 {
     47   EFI_STATUS      Status;
     48   UINT64          Value64;
     49   BOOLEAN         Converted;
     50   UINTN           Index;
     51   CONST CHAR16    *ValueStr;
     52 
     53   ASSERT (FormatMask & (FORMAT_NUMBER | FORMAT_STRING));
     54 
     55   Converted = FALSE;
     56   Value64   = 0;
     57   ValueStr  = ShellCommandLineGetValue (ParamPackage, FlagStr);
     58 
     59   if (ValueStr == NULL) {
     60     return EFI_NOT_FOUND;
     61   } else {
     62     //
     63     // Try to convert to integer directly if MaybeNumber is TRUE.
     64     //
     65     if ((FormatMask & FORMAT_NUMBER) != 0) {
     66       Value64 = StrToUInteger (ValueStr, &Status);
     67       if (!EFI_ERROR (Status)) {
     68         //
     69         // Convert successfully.
     70         //
     71         if (Value64 > Maximum) {
     72           //
     73           // But the result is invalid
     74           //
     75           ShellPrintHiiEx (
     76             -1,
     77             -1,
     78             NULL,
     79             STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
     80             mHiiHandle,
     81             mAppName,
     82             FlagStr,
     83             ValueStr
     84             );
     85           return EFI_INVALID_PARAMETER;
     86         }
     87 
     88         Converted = TRUE;
     89       }
     90     }
     91 
     92     if (!Converted && ((FormatMask & FORMAT_STRING) != 0)) {
     93       //
     94       // Convert falied, so use String->Integer map.
     95       //
     96       ASSERT (Map != NULL);
     97       Value64 = MapStringToInteger (ValueStr, Map);
     98       if (Value64 == (UINT32) -1) {
     99         //
    100         // Cannot find the string in the map.
    101         //
    102         ShellPrintHiiEx (
    103           -1,
    104           -1,
    105           NULL,
    106           STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
    107           mHiiHandle,
    108           mAppName,
    109           FlagStr,
    110           ValueStr
    111           );
    112         ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ACCEPT_PARAMETERS), mHiiHandle);
    113         for (Index = 0; Map[Index].String != NULL; Index++) {
    114           Print (L" %s", Map[Index].String);
    115         }
    116 
    117         Print (L"\n");
    118         return EFI_INVALID_PARAMETER;
    119       }
    120     }
    121 
    122     CopyMem (ValuePtr, &Value64, ByteCount);
    123     return EFI_SUCCESS;
    124   }
    125 }
    126 
    127 /**
    128   Helper function called to convert a string containing an Ipv4 or Ipv6 Internet Protocol address
    129   into a proper address for the EFI_IP_ADDRESS structure.
    130 
    131   @param[in]  Ptr    The pointer to the string containing an Ipv4 or Ipv6 Internet Protocol address.
    132   @param[out] Ip     The pointer to the EFI_IP_ADDRESS structure to contain the result.
    133 
    134   @retval EFI_SUCCESS              The operation completed successfully.
    135   @retval EFI_INVALID_PARAMETER    Invalid parameter.
    136 **/
    137 EFI_STATUS
    138 EfiInetAddr2 (
    139   IN  CHAR16            *Ptr,
    140   OUT EFI_IP_ADDRESS    *Ip
    141   )
    142 {
    143   EFI_STATUS    Status;
    144 
    145   if ((Ptr == NULL) || (Ip == NULL)) {
    146     return EFI_INVALID_PARAMETER;
    147   }
    148 
    149   //
    150   // Parse the input address as Ipv4 Address first.
    151   //
    152   Status = NetLibStrToIp4 (Ptr, &Ip->v4);
    153   if (!EFI_ERROR (Status)) {
    154     return Status;
    155   }
    156 
    157   Status = NetLibStrToIp6 (Ptr, &Ip->v6);
    158   return Status;
    159 }
    160 
    161 /**
    162   Helper function called to calculate the prefix length associated with the string
    163   containing an Ipv4 or Ipv6 Internet Protocol address.
    164 
    165   @param[in]  Ptr     The pointer to the string containing an Ipv4 or Ipv6 Internet Protocol address.
    166   @param[out] Addr    The pointer to the EFI_IP_ADDRESS_INFO structure to contain the result.
    167 
    168   @retval EFI_SUCCESS              The operation completed successfully.
    169   @retval EFI_INVALID_PARAMETER    Invalid parameter.
    170   @retval Others                   Other mistake case.
    171 **/
    172 EFI_STATUS
    173 EfiInetAddrRange (
    174   IN  CHAR16                 *Ptr,
    175   OUT EFI_IP_ADDRESS_INFO    *Addr
    176   )
    177 {
    178   EFI_STATUS    Status;
    179 
    180   if ((Ptr == NULL) || (Addr == NULL)) {
    181     return EFI_INVALID_PARAMETER;
    182   }
    183 
    184   Status = NetLibStrToIp4 (Ptr, &Addr->Address.v4);
    185   if (!EFI_ERROR (Status)) {
    186     if ((UINT32)(*Addr->Address.v4.Addr) == 0) {
    187       Addr->PrefixLength = 0;
    188     } else {
    189       Addr->PrefixLength = 32;
    190     }
    191     return Status;
    192   }
    193 
    194   Status = NetLibStrToIp6andPrefix (Ptr, &Addr->Address.v6, &Addr->PrefixLength);
    195   if (!EFI_ERROR (Status) && (Addr->PrefixLength == 0xFF)) {
    196     Addr->PrefixLength = 128;
    197   }
    198 
    199   return Status;
    200 }
    201 
    202 /**
    203   Helper function called to calculate the port range associated with the string.
    204 
    205   @param[in]  Ptr          The pointer to the string containing a port and range.
    206   @param[out] Port         The pointer to the Port to contain the result.
    207   @param[out] PortRange    The pointer to the PortRange to contain the result.
    208 
    209   @retval EFI_SUCCESS              The operation completed successfully.
    210   @retval EFI_INVALID_PARAMETER    Invalid parameter.
    211   @retval Others                   Other mistake case.
    212 **/
    213 EFI_STATUS
    214 EfiInetPortRange (
    215   IN  CHAR16    *Ptr,
    216   OUT UINT16    *Port,
    217   OUT UINT16    *PortRange
    218   )
    219 {
    220   CHAR16        *BreakPtr;
    221   CHAR16        Ch;
    222   EFI_STATUS    Status;
    223 
    224   for (BreakPtr = Ptr; (*BreakPtr != L'\0') && (*BreakPtr != L':'); BreakPtr++) {
    225     ;
    226   }
    227 
    228   Ch        = *BreakPtr;
    229   *BreakPtr = L'\0';
    230   *Port     = (UINT16) StrToUInteger (Ptr, &Status);
    231   *BreakPtr = Ch;
    232   if (EFI_ERROR (Status)) {
    233     return Status;
    234   }
    235 
    236   *PortRange = 0;
    237   if (*BreakPtr == L':') {
    238     BreakPtr++;
    239     *PortRange = (UINT16) StrToUInteger (BreakPtr, &Status);
    240     if (EFI_ERROR (Status)) {
    241       return Status;
    242     }
    243 
    244     if (*PortRange < *Port) {
    245       return EFI_INVALID_PARAMETER;
    246     }
    247 
    248     *PortRange = (UINT16) (*PortRange - *Port);
    249   }
    250 
    251   return EFI_SUCCESS;
    252 }
    253 
    254 /**
    255   Helper function called to transfer a string to an unsigned integer.
    256 
    257   @param[in]  Str       The pointer to the string.
    258   @param[out] Status    The operation status.
    259 
    260   @return The integer value of converted Str.
    261 **/
    262 UINT64
    263 StrToUInteger (
    264   IN  CONST CHAR16    *Str,
    265   OUT EFI_STATUS      *Status
    266   )
    267 {
    268   UINT64    Value;
    269   UINT64    NewValue;
    270   CHAR16    *StrTail;
    271   CHAR16    Char;
    272   UINTN     Base;
    273   UINTN     Len;
    274 
    275   Base    = 10;
    276   Value   = 0;
    277   *Status = EFI_ABORTED;
    278 
    279   //
    280   // Skip leading white space.
    281   //
    282   while ((*Str != 0) && (*Str == ' ')) {
    283     Str++;
    284   }
    285   //
    286   // For NULL Str, just return.
    287   //
    288   if (*Str == 0) {
    289     return 0;
    290   }
    291   //
    292   // Skip white space in tail.
    293   //
    294   Len     = StrLen (Str);
    295   StrTail = (CHAR16 *) (Str + Len - 1);
    296   while (*StrTail == ' ') {
    297     *StrTail = 0;
    298     StrTail--;
    299   }
    300 
    301   Len = StrTail - Str + 1;
    302 
    303   //
    304   // Check hex prefix '0x'.
    305   //
    306   if ((Len >= 2) && (*Str == '0') && ((*(Str + 1) == 'x') || (*(Str + 1) == 'X'))) {
    307     Str += 2;
    308     Len -= 2;
    309     Base = 16;
    310   }
    311 
    312   if (Len == 0) {
    313     return 0;
    314   }
    315   //
    316   // Convert the string to value.
    317   //
    318   for (; Str <= StrTail; Str++) {
    319 
    320     Char = *Str;
    321 
    322     if (Base == 16) {
    323       if (RShiftU64 (Value, 60) != 0) {
    324         //
    325         // Overflow here x16.
    326         //
    327         return 0;
    328       }
    329 
    330       NewValue = LShiftU64 (Value, 4);
    331     } else {
    332       if (RShiftU64 (Value, 61) != 0) {
    333         //
    334         // Overflow here x8.
    335         //
    336         return 0;
    337       }
    338 
    339       NewValue  = LShiftU64 (Value, 3);
    340       Value     = LShiftU64 (Value, 1);
    341       NewValue += Value;
    342       if (NewValue < Value) {
    343         //
    344         // Overflow here.
    345         //
    346         return 0;
    347       }
    348     }
    349 
    350     Value = NewValue;
    351 
    352     if ((Base == 16) && (Char >= 'a') && (Char <= 'f')) {
    353       Char = (CHAR16) (Char - 'a' + 'A');
    354     }
    355 
    356     if ((Base == 16) && (Char >= 'A') && (Char <= 'F')) {
    357       Value += (Char - 'A') + 10;
    358     } else if ((Char >= '0') && (Char <= '9')) {
    359       Value += (Char - '0');
    360     } else {
    361       //
    362       // Unexpected Char encountered.
    363       //
    364       return 0;
    365     }
    366   }
    367 
    368   *Status = EFI_SUCCESS;
    369   return Value;
    370 }
    371 
    372 /**
    373   Helper function called to transfer a string to an unsigned integer according to the map table.
    374 
    375   @param[in] Str    The pointer to the string.
    376   @param[in] Map    The pointer to the map table.
    377 
    378   @return The integer value of converted Str. If not found, then return -1.
    379 **/
    380 UINT32
    381 MapStringToInteger (
    382   IN CONST CHAR16    *Str,
    383   IN STR2INT         *Map
    384   )
    385 {
    386   STR2INT       *Item;
    387 
    388   for (Item = Map; Item->String != NULL; Item++) {
    389     if (StrCmp (Item->String, Str) == 0) {
    390       return Item->Integer;
    391     }
    392   }
    393 
    394   return (UINT32) -1;
    395 }
    396 
    397 /**
    398   Helper function called to transfer an unsigned integer to a string according to the map table.
    399 
    400   @param[in] Integer    The pointer to the string.
    401   @param[in] Map        The pointer to the map table.
    402 
    403   @return The converted Str. If not found, then return NULL.
    404 **/
    405 CHAR16 *
    406 MapIntegerToString (
    407   IN UINT32     Integer,
    408   IN STR2INT    *Map
    409   )
    410 {
    411   STR2INT    *Item;
    412 
    413   for (Item = Map; Item->String != NULL; Item++) {
    414     if (Integer == Item->Integer) {
    415       return Item->String;
    416     }
    417   }
    418 
    419   return NULL;
    420 }
    421