Helper.c revision a3bcde70e6dc69000f85cc5deee98101d2ae200a
1/** @file
2  The assistant function implementation for IpSecConfig application.
3
4  Copyright (c) 2009 - 2010, 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**/
36EFI_STATUS
37GetNumber (
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      Value64 = MapStringToInteger (ValueStr, Map);
97      if (Value64 == (UINT32) -1) {
98        //
99        // Cannot find the string in the map.
100        //
101        ShellPrintHiiEx (
102          -1,
103          -1,
104          NULL,
105          STRING_TOKEN (STR_IPSEC_CONFIG_INCORRECT_PARAMETER_VALUE),
106          mHiiHandle,
107          mAppName,
108          FlagStr,
109          ValueStr
110          );
111        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IPSEC_CONFIG_ACCEPT_PARAMETERS), mHiiHandle);
112        for (Index = 0; Map[Index].String != NULL; Index++) {
113          Print (L" %s", Map[Index].String);
114        }
115
116        Print (L"\n");
117        return EFI_INVALID_PARAMETER;
118      }
119    }
120
121    CopyMem (ValuePtr, &Value64, ByteCount);
122    return EFI_SUCCESS;
123  }
124}
125
126/**
127  Helper function called to convert a string containing an Ipv4 or Ipv6 Internet Protocol address
128  into a proper address for the EFI_IP_ADDRESS structure.
129
130  @param[in]  Ptr    The pointer to the string containing an Ipv4 or Ipv6 Internet Protocol address.
131  @param[out] Ip     The pointer to the EFI_IP_ADDRESS structure to contain the result.
132
133  @retval EFI_SUCCESS              The operation completed successfully.
134  @retval EFI_INVALID_PARAMETER    Invalid parameter.
135**/
136EFI_STATUS
137EfiInetAddr2 (
138  IN  CHAR16            *Ptr,
139  OUT EFI_IP_ADDRESS    *Ip
140  )
141{
142  EFI_STATUS    Status;
143
144  if ((Ptr == NULL) || (Ip == NULL)) {
145    return EFI_INVALID_PARAMETER;
146  }
147
148  //
149  // Parse the input address as Ipv4 Address first.
150  //
151  Status = NetLibStrToIp4 (Ptr, &Ip->v4);
152  if (!EFI_ERROR (Status)) {
153    return Status;
154  }
155
156  Status = NetLibStrToIp6 (Ptr, &Ip->v6);
157  return Status;
158}
159
160/**
161  Helper function called to calculate the prefix length associated with the string
162  containing an Ipv4 or Ipv6 Internet Protocol address.
163
164  @param[in]  Ptr     The pointer to the string containing an Ipv4 or Ipv6 Internet Protocol address.
165  @param[out] Addr    The pointer to the EFI_IP_ADDRESS_INFO structure to contain the result.
166
167  @retval EFI_SUCCESS              The operation completed successfully.
168  @retval EFI_INVALID_PARAMETER    Invalid parameter.
169  @retval Others                   Other mistake case.
170**/
171EFI_STATUS
172EfiInetAddrRange (
173  IN  CHAR16                 *Ptr,
174  OUT EFI_IP_ADDRESS_INFO    *Addr
175  )
176{
177  EFI_STATUS    Status;
178
179  if ((Ptr == NULL) || (Addr == NULL)) {
180    return EFI_INVALID_PARAMETER;
181  }
182
183  Status = NetLibStrToIp4 (Ptr, &Addr->Address.v4);
184  if (!EFI_ERROR (Status)) {
185    if ((UINT32)(*Addr->Address.v4.Addr) == 0) {
186      Addr->PrefixLength = 0;
187    } else {
188      Addr->PrefixLength = 32;
189    }
190    return Status;
191  }
192
193  Status = NetLibStrToIp6andPrefix (Ptr, &Addr->Address.v6, &Addr->PrefixLength);
194  if (!EFI_ERROR (Status) && (Addr->PrefixLength == 0xFF)) {
195    Addr->PrefixLength = 128;
196  }
197
198  return Status;
199}
200
201/**
202  Helper function called to calculate the port range associated with the string.
203
204  @param[in]  Ptr          The pointer to the string containing a port and range.
205  @param[out] Port         The pointer to the Port to contain the result.
206  @param[out] PortRange    The pointer to the PortRange to contain the result.
207
208  @retval EFI_SUCCESS              The operation completed successfully.
209  @retval EFI_INVALID_PARAMETER    Invalid parameter.
210  @retval Others                   Other mistake case.
211**/
212EFI_STATUS
213EfiInetPortRange (
214  IN  CHAR16    *Ptr,
215  OUT UINT16    *Port,
216  OUT UINT16    *PortRange
217  )
218{
219  CHAR16        *BreakPtr;
220  CHAR16        Ch;
221  EFI_STATUS    Status;
222
223  for (BreakPtr = Ptr; (*BreakPtr != L'\0') && (*BreakPtr != L':'); BreakPtr++) {
224    ;
225  }
226
227  Ch        = *BreakPtr;
228  *BreakPtr = L'\0';
229  *Port     = (UINT16) StrToUInteger (Ptr, &Status);
230  *BreakPtr = Ch;
231  if (EFI_ERROR (Status)) {
232    return Status;
233  }
234
235  *PortRange = 0;
236  if (*BreakPtr == L':') {
237    BreakPtr++;
238    *PortRange = (UINT16) StrToUInteger (BreakPtr, &Status);
239    if (EFI_ERROR (Status)) {
240      return Status;
241    }
242
243    if (*PortRange < *Port) {
244      return EFI_INVALID_PARAMETER;
245    }
246
247    *PortRange = (UINT16) (*PortRange - *Port);
248  }
249
250  return EFI_SUCCESS;
251}
252
253/**
254  Helper function called to transfer a string to an unsigned integer.
255
256  @param[in]  Str       The pointer to the string.
257  @param[out] Status    The operation status.
258
259  @return The integer value of converted Str.
260**/
261UINT64
262StrToUInteger (
263  IN  CONST CHAR16    *Str,
264  OUT EFI_STATUS      *Status
265  )
266{
267  UINT64    Value;
268  UINT64    NewValue;
269  CHAR16    *StrTail;
270  CHAR16    Char;
271  UINTN     Base;
272  UINTN     Len;
273
274  Base    = 10;
275  Value   = 0;
276  *Status = EFI_ABORTED;
277
278  //
279  // Skip leading white space.
280  //
281  while ((*Str != 0) && (*Str == ' ')) {
282    Str++;
283  }
284  //
285  // For NULL Str, just return.
286  //
287  if (*Str == 0) {
288    return 0;
289  }
290  //
291  // Skip white space in tail.
292  //
293  Len     = StrLen (Str);
294  StrTail = (CHAR16 *) (Str + Len - 1);
295  while (*StrTail == ' ') {
296    *StrTail = 0;
297    StrTail--;
298  }
299
300  Len = StrTail - Str + 1;
301
302  //
303  // Check hex prefix '0x'.
304  //
305  if ((Len >= 2) && (*Str == '0') && ((*(Str + 1) == 'x') || (*(Str + 1) == 'X'))) {
306    Str += 2;
307    Len -= 2;
308    Base = 16;
309  }
310
311  if (Len == 0) {
312    return 0;
313  }
314  //
315  // Convert the string to value.
316  //
317  for (; Str <= StrTail; Str++) {
318
319    Char = *Str;
320
321    if (Base == 16) {
322      if (RShiftU64 (Value, 60) != 0) {
323        //
324        // Overflow here x16.
325        //
326        return 0;
327      }
328
329      NewValue = LShiftU64 (Value, 4);
330    } else {
331      if (RShiftU64 (Value, 61) != 0) {
332        //
333        // Overflow here x8.
334        //
335        return 0;
336      }
337
338      NewValue  = LShiftU64 (Value, 3);
339      Value     = LShiftU64 (Value, 1);
340      NewValue += Value;
341      if (NewValue < Value) {
342        //
343        // Overflow here.
344        //
345        return 0;
346      }
347    }
348
349    Value = NewValue;
350
351    if ((Base == 16) && (Char >= 'a') && (Char <= 'f')) {
352      Char = (CHAR16) (Char - 'a' + 'A');
353    }
354
355    if ((Base == 16) && (Char >= 'A') && (Char <= 'F')) {
356      Value += (Char - 'A') + 10;
357    } else if ((Char >= '0') && (Char <= '9')) {
358      Value += (Char - '0');
359    } else {
360      //
361      // Unexpected Char encountered.
362      //
363      return 0;
364    }
365  }
366
367  *Status = EFI_SUCCESS;
368  return Value;
369}
370
371/**
372  Helper function called to transfer a string to an unsigned integer according to the map table.
373
374  @param[in] Str    The pointer to the string.
375  @param[in] Map    The pointer to the map table.
376
377  @return The integer value of converted Str. If not found, then return -1.
378**/
379UINT32
380MapStringToInteger (
381  IN CONST CHAR16    *Str,
382  IN STR2INT         *Map
383  )
384{
385  STR2INT       *Item;
386
387  for (Item = Map; Item->String != NULL; Item++) {
388    if (StrCmp (Item->String, Str) == 0) {
389      return Item->Integer;
390    }
391  }
392
393  return (UINT32) -1;
394}
395
396/**
397  Helper function called to transfer an unsigned integer to a string according to the map table.
398
399  @param[in] Integer    The pointer to the string.
400  @param[in] Map        The pointer to the map table.
401
402  @return The converted Str. If not found, then return NULL.
403**/
404CHAR16 *
405MapIntegerToString (
406  IN UINT32     Integer,
407  IN STR2INT    *Map
408  )
409{
410  STR2INT    *Item;
411
412  for (Item = Map; Item->String != NULL; Item++) {
413    if (Integer == Item->Integer) {
414      return Item->String;
415    }
416  }
417
418  return NULL;
419}
420