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
GetNumber(IN CHAR16 * FlagStr,IN UINT64 Maximum,IN OUT VOID * ValuePtr,IN UINTN ByteCount,IN STR2INT * Map,IN LIST_ENTRY * ParamPackage,IN UINT32 FormatMask)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
EfiInetAddr2(IN CHAR16 * Ptr,OUT EFI_IP_ADDRESS * Ip)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
EfiInetAddrRange(IN CHAR16 * Ptr,OUT EFI_IP_ADDRESS_INFO * Addr)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
EfiInetPortRange(IN CHAR16 * Ptr,OUT UINT16 * Port,OUT UINT16 * PortRange)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
StrToUInteger(IN CONST CHAR16 * Str,OUT EFI_STATUS * Status)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
MapStringToInteger(IN CONST CHAR16 * Str,IN STR2INT * Map)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 *
MapIntegerToString(IN UINT32 Integer,IN STR2INT * Map)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