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