]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellNetwork1CommandsLib/Ifconfig.c
ShellPkg/UefiShellLib: Handle memory allocation failure
[mirror_edk2.git] / ShellPkg / Library / UefiShellNetwork1CommandsLib / Ifconfig.c
CommitLineData
68fb0527 1/** @file\r
7c25b7ea 2 The implementation for Shell command ifconfig based on IP4Config2 protocol.\r
68fb0527 3\r
c011b6c9 4 (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR>\r
913ba151 5 Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
68fb0527 6\r
7 This program and the accompanying materials\r
8 are licensed and made available under the terms and conditions of the BSD License\r
9 which accompanies this distribution. The full text of the license may be found at\r
10 http://opensource.org/licenses/bsd-license.php.\r
11\r
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
7c25b7ea 14\r
68fb0527 15**/\r
16\r
17#include "UefiShellNetwork1CommandsLib.h"\r
18\r
7c25b7ea 19typedef enum {\r
20 IfConfigOpList = 1,\r
21 IfConfigOpSet = 2,\r
22 IfConfigOpClear = 3\r
23} IFCONFIG_OPCODE;\r
24\r
25typedef enum {\r
26 VarCheckReserved = -1,\r
27 VarCheckOk = 0,\r
28 VarCheckDuplicate,\r
29 VarCheckConflict,\r
30 VarCheckUnknown,\r
31 VarCheckLackValue,\r
32 VarCheckOutOfMem\r
33} VAR_CHECK_CODE;\r
34\r
35typedef enum {\r
36 FlagTypeSingle = 0,\r
37 FlagTypeNeedVar,\r
38 FlagTypeNeedSet,\r
39 FlagTypeSkipUnknown\r
40} VAR_CHECK_FLAG_TYPE;\r
41\r
42#define MACADDRMAXSIZE 32\r
43\r
44typedef struct _IFCONFIG_INTERFACE_CB {\r
45 EFI_HANDLE NicHandle;\r
46 LIST_ENTRY Link;\r
47 EFI_IP4_CONFIG2_PROTOCOL *IfCfg;\r
48 EFI_IP4_CONFIG2_INTERFACE_INFO *IfInfo; \r
49 EFI_IP4_CONFIG2_POLICY Policy;\r
50 UINT32 DnsCnt;\r
51 EFI_IPv4_ADDRESS DnsAddr[1];\r
52} IFCONFIG_INTERFACE_CB;\r
53\r
54typedef struct _ARG_LIST ARG_LIST;\r
55\r
56struct _ARG_LIST {\r
57 ARG_LIST *Next;\r
58 CHAR16 *Arg;\r
59};\r
60\r
61typedef struct _IFCONFIG4_PRIVATE_DATA {\r
62 LIST_ENTRY IfList;\r
63\r
64 UINT32 OpCode;\r
65 CHAR16 *IfName;\r
66 ARG_LIST *VarArg;\r
67} IFCONFIG_PRIVATE_DATA;\r
68\r
69typedef struct _VAR_CHECK_ITEM{\r
70 CHAR16 *FlagStr;\r
71 UINT32 FlagID;\r
72 UINT32 ConflictMask;\r
73 VAR_CHECK_FLAG_TYPE FlagType;\r
74} VAR_CHECK_ITEM;\r
75\r
76SHELL_PARAM_ITEM mIfConfigCheckList[] = {\r
77 {\r
78 L"-b",\r
79 TypeFlag\r
80 },\r
81 {\r
82 L"-l",\r
83 TypeValue\r
84 },\r
85 {\r
86 L"-r",\r
87 TypeValue\r
88 },\r
89 {\r
90 L"-c",\r
91 TypeValue\r
92 },\r
93 {\r
94 L"-s",\r
95 TypeMaxValue\r
96 },\r
97 {\r
98 NULL,\r
99 TypeMax\r
100 },\r
101};\r
102\r
103VAR_CHECK_ITEM mSetCheckList[] = {\r
104 {\r
105 L"static",\r
106 0x00000001,\r
107 0x00000001,\r
108 FlagTypeSingle\r
109 },\r
110 {\r
111 L"dhcp",\r
112 0x00000002,\r
113 0x00000001,\r
114 FlagTypeSingle\r
115 },\r
116 {\r
117 L"dns",\r
118 0x00000008,\r
119 0x00000004,\r
120 FlagTypeSingle\r
121 },\r
122 {\r
123 NULL,\r
124 0x0,\r
125 0x0,\r
126 FlagTypeSkipUnknown\r
127 },\r
128};\r
68fb0527 129\r
68fb0527 130STATIC CONST CHAR16 PermanentString[10] = L"PERMANENT";\r
131\r
68fb0527 132/**\r
7c25b7ea 133 Split a string with specified separator and save the substring to a list.\r
68fb0527 134\r
7c25b7ea 135 @param[in] String The pointer of the input string.\r
136 @param[in] Separator The specified separator.\r
68fb0527 137\r
7c25b7ea 138 @return The pointer of headnode of ARG_LIST.\r
68fb0527 139\r
68fb0527 140**/\r
7c25b7ea 141ARG_LIST *\r
142SplitStrToList (\r
143 IN CONST CHAR16 *String,\r
144 IN CHAR16 Separator\r
68fb0527 145 )\r
146{\r
7c25b7ea 147 CHAR16 *Str;\r
148 CHAR16 *ArgStr;\r
149 ARG_LIST *ArgList;\r
150 ARG_LIST *ArgNode;\r
68fb0527 151\r
7c25b7ea 152 if (*String == L'\0') {\r
153 return NULL;\r
68fb0527 154 }\r
155\r
68fb0527 156 //\r
7c25b7ea 157 // Copy the CONST string to a local copy.\r
68fb0527 158 //\r
7c25b7ea 159 Str = AllocateCopyPool (StrSize (String), String);\r
160 ASSERT (Str != NULL);\r
161 ArgStr = Str;\r
68fb0527 162\r
163 //\r
7c25b7ea 164 // init a node for the list head.\r
68fb0527 165 //\r
7c25b7ea 166 ArgNode = (ARG_LIST *) AllocateZeroPool (sizeof (ARG_LIST));\r
167 ASSERT (ArgNode != NULL);\r
168 ArgList = ArgNode;\r
68fb0527 169\r
170 //\r
7c25b7ea 171 // Split the local copy and save in the list node.\r
68fb0527 172 //\r
7c25b7ea 173 while (*Str != L'\0') {\r
174 if (*Str == Separator) {\r
175 *Str = L'\0';\r
176 ArgNode->Arg = ArgStr;\r
177 ArgStr = Str + 1;\r
178 ArgNode->Next = (ARG_LIST *) AllocateZeroPool (sizeof (ARG_LIST));\r
179 ASSERT (ArgNode->Next != NULL);\r
180 ArgNode = ArgNode->Next;\r
68fb0527 181 }\r
7c25b7ea 182\r
183 Str++;\r
68fb0527 184 }\r
185\r
7c25b7ea 186 ArgNode->Arg = ArgStr;\r
187 ArgNode->Next = NULL;\r
188\r
189 return ArgList;\r
68fb0527 190}\r
191\r
192/**\r
7c25b7ea 193 Check the correctness of input Args with '-s' option.\r
68fb0527 194\r
7c25b7ea 195 @param[in] CheckList The pointer of VAR_CHECK_ITEM array.\r
196 @param[in] Name The pointer of input arg.\r
197 @param[in] Init The switch to execute the check.\r
68fb0527 198\r
7c25b7ea 199 @return VarCheckOk Valid parameter or Initialize check successfully.\r
200 @return VarCheckDuplicate Duplicated parameter happened.\r
201 @return VarCheckConflict Conflicted parameter happened\r
202 @return VarCheckUnknown Unknown parameter.\r
68fb0527 203\r
68fb0527 204**/\r
7c25b7ea 205VAR_CHECK_CODE\r
206IfConfigRetriveCheckListByName(\r
207 IN VAR_CHECK_ITEM *CheckList,\r
208 IN CHAR16 *Name,\r
209 IN BOOLEAN Init\r
210)\r
68fb0527 211{\r
7c25b7ea 212 STATIC UINT32 CheckDuplicate;\r
213 STATIC UINT32 CheckConflict;\r
214 VAR_CHECK_CODE RtCode;\r
215 UINT32 Index;\r
216 VAR_CHECK_ITEM Arg;\r
217\r
218 if (Init) {\r
219 CheckDuplicate = 0;\r
220 CheckConflict = 0;\r
221 return VarCheckOk;\r
68fb0527 222 }\r
223\r
7c25b7ea 224 RtCode = VarCheckOk;\r
225 Index = 0;\r
226 Arg = CheckList[Index];\r
68fb0527 227\r
228 //\r
7c25b7ea 229 // Check the Duplicated/Conflicted/Unknown input Args.\r
68fb0527 230 //\r
7c25b7ea 231 while (Arg.FlagStr != NULL) {\r
232 if (StrCmp (Arg.FlagStr, Name) == 0) {\r
68fb0527 233\r
7c25b7ea 234 if (CheckDuplicate & Arg.FlagID) {\r
235 RtCode = VarCheckDuplicate;\r
236 break;\r
237 }\r
68fb0527 238\r
7c25b7ea 239 if (CheckConflict & Arg.ConflictMask) {\r
240 RtCode = VarCheckConflict;\r
241 break;\r
242 }\r
68fb0527 243\r
7c25b7ea 244 CheckDuplicate |= Arg.FlagID;\r
245 CheckConflict |= Arg.ConflictMask;\r
246 break;\r
247 }\r
68fb0527 248\r
7c25b7ea 249 Arg = CheckList[++Index];\r
68fb0527 250 }\r
7c25b7ea 251\r
252 if (Arg.FlagStr == NULL) {\r
253 RtCode = VarCheckUnknown;\r
68fb0527 254 }\r
255\r
7c25b7ea 256 return RtCode;\r
68fb0527 257}\r
258\r
259/**\r
7c25b7ea 260 The notify function of create event when performing a manual config.\r
68fb0527 261\r
7c25b7ea 262 @param[in] Event The event this notify function registered to.\r
263 @param[in] Context Pointer to the context data registered to the event.\r
68fb0527 264\r
7c25b7ea 265**/\r
266VOID\r
68fb0527 267EFIAPI\r
7c25b7ea 268IfConfigManualAddressNotify (\r
269 IN EFI_EVENT Event,\r
270 IN VOID *Context\r
271 )\r
68fb0527 272{\r
7c25b7ea 273 *((BOOLEAN *) Context) = TRUE;\r
68fb0527 274}\r
275\r
276/**\r
7c25b7ea 277 Print MAC address.\r
68fb0527 278\r
7c25b7ea 279 @param[in] Node The pointer of MAC address buffer.\r
280 @param[in] Size The size of MAC address buffer.\r
68fb0527 281\r
68fb0527 282**/\r
7c25b7ea 283VOID\r
284IfConfigPrintMacAddr (\r
285 IN UINT8 *Node,\r
286 IN UINT32 Size\r
287 )\r
68fb0527 288{\r
7c25b7ea 289 UINTN Index;\r
68fb0527 290\r
7c25b7ea 291 ASSERT (Size <= MACADDRMAXSIZE);\r
68fb0527 292\r
7c25b7ea 293 for (Index = 0; Index < Size; Index++) {\r
294 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MAC_ADDR_BODY), gShellNetwork1HiiHandle, Node[Index]);\r
295 if (Index + 1 < Size) {\r
296 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_COLON), gShellNetwork1HiiHandle);\r
297 }\r
68fb0527 298 }\r
68fb0527 299\r
7c25b7ea 300 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_NEWLINE), gShellNetwork1HiiHandle);\r
301}\r
68fb0527 302\r
68fb0527 303\r
7c25b7ea 304/**\r
305 The get current status of all handles.\r
68fb0527 306\r
7c25b7ea 307 @param[in] IfName The pointer of IfName(interface name).\r
308 @param[in] IfList The pointer of IfList(interface list).\r
68fb0527 309\r
7c25b7ea 310 @retval EFI_SUCCESS The get status processed successfully.\r
311 @retval others The get status process failed.\r
68fb0527 312\r
68fb0527 313**/\r
314EFI_STATUS\r
7c25b7ea 315IfConfigGetInterfaceInfo (\r
316 IN CHAR16 *IfName,\r
317 IN LIST_ENTRY *IfList\r
68fb0527 318 )\r
319{\r
7c25b7ea 320 EFI_STATUS Status;\r
321 UINTN HandleIndex;\r
322 UINTN HandleNum;\r
323 EFI_HANDLE *HandleBuffer;\r
324 EFI_IP4_CONFIG2_PROTOCOL *Ip4Cfg2;\r
325 EFI_IP4_CONFIG2_INTERFACE_INFO *IfInfo;\r
326 IFCONFIG_INTERFACE_CB *IfCb;\r
327 UINTN DataSize;\r
68fb0527 328\r
7c25b7ea 329 HandleBuffer = NULL;\r
330 HandleNum = 0;\r
331\r
332 IfInfo = NULL;\r
333 IfCb = NULL;\r
68fb0527 334\r
335 //\r
7c25b7ea 336 // Locate all the handles with ip4 service binding protocol.\r
68fb0527 337 //\r
338 Status = gBS->LocateHandleBuffer (\r
7c25b7ea 339 ByProtocol,\r
340 &gEfiIp4ServiceBindingProtocolGuid,\r
341 NULL,\r
342 &HandleNum,\r
343 &HandleBuffer\r
68fb0527 344 );\r
7c25b7ea 345 if (EFI_ERROR (Status) || (HandleNum == 0)) {\r
6e3e562c 346 return Status;\r
68fb0527 347 }\r
348\r
7c25b7ea 349 //\r
350 // Enumerate all handles that installed with ip4 service binding protocol.\r
351 //\r
352 for (HandleIndex = 0; HandleIndex < HandleNum; HandleIndex++) {\r
353 IfCb = NULL;\r
354 IfInfo = NULL;\r
355 DataSize = 0;\r
356\r
357 //\r
358 // Ip4config protocol and ip4 service binding protocol are installed\r
359 // on the same handle.\r
360 //\r
361 ASSERT (HandleBuffer != NULL);\r
362 Status = gBS->HandleProtocol (\r
363 HandleBuffer[HandleIndex],\r
364 &gEfiIp4Config2ProtocolGuid,\r
365 (VOID **) &Ip4Cfg2\r
366 );\r
367\r
68fb0527 368 if (EFI_ERROR (Status)) {\r
7c25b7ea 369 goto ON_ERROR;\r
68fb0527 370 }\r
7c25b7ea 371 \r
68fb0527 372 //\r
7c25b7ea 373 // Get the interface information size.\r
68fb0527 374 //\r
7c25b7ea 375 Status = Ip4Cfg2->GetData (\r
376 Ip4Cfg2,\r
377 Ip4Config2DataTypeInterfaceInfo,\r
378 &DataSize,\r
379 NULL\r
380 );\r
381\r
382 if (Status != EFI_BUFFER_TOO_SMALL) {\r
383 goto ON_ERROR;\r
33c031ee 384 }\r
7c25b7ea 385\r
386 IfInfo = AllocateZeroPool (DataSize);\r
387\r
388 if (IfInfo == NULL) {\r
68fb0527 389 Status = EFI_OUT_OF_RESOURCES;\r
390 goto ON_ERROR;\r
391 }\r
7c25b7ea 392 \r
68fb0527 393 //\r
7c25b7ea 394 // Get the interface info.\r
68fb0527 395 //\r
7c25b7ea 396 Status = Ip4Cfg2->GetData (\r
397 Ip4Cfg2,\r
398 Ip4Config2DataTypeInterfaceInfo,\r
399 &DataSize,\r
400 IfInfo\r
401 );\r
68fb0527 402\r
7c25b7ea 403 if (EFI_ERROR (Status)) {\r
68fb0527 404 goto ON_ERROR;\r
405 }\r
7c25b7ea 406 \r
68fb0527 407 //\r
7c25b7ea 408 // Check the interface name if required.\r
68fb0527 409 //\r
7c25b7ea 410 if ((IfName != NULL) && (StrCmp (IfName, IfInfo->Name) != 0)) {\r
411 FreePool (IfInfo);\r
412 continue;\r
68fb0527 413 }\r
414\r
7c25b7ea 415 DataSize = 0;\r
416 \r
68fb0527 417 //\r
7c25b7ea 418 // Get the size of dns server list.\r
68fb0527 419 //\r
7c25b7ea 420 Status = Ip4Cfg2->GetData (\r
421 Ip4Cfg2,\r
422 Ip4Config2DataTypeDnsServer,\r
423 &DataSize,\r
424 NULL\r
425 );\r
426\r
427 if ((Status != EFI_BUFFER_TOO_SMALL) && (Status != EFI_NOT_FOUND)) {\r
428 goto ON_ERROR;\r
429 }\r
430\r
431 IfCb = AllocateZeroPool (sizeof (IFCONFIG_INTERFACE_CB) + DataSize);\r
68fb0527 432\r
7c25b7ea 433 if (IfCb == NULL) {\r
68fb0527 434 Status = EFI_OUT_OF_RESOURCES;\r
435 goto ON_ERROR;\r
436 }\r
437\r
7c25b7ea 438 IfCb->NicHandle = HandleBuffer[HandleIndex];\r
439 IfCb->IfInfo = IfInfo;\r
440 IfCb->IfCfg = Ip4Cfg2;\r
441 IfCb->DnsCnt = (UINT32) (DataSize / sizeof (EFI_IPv4_ADDRESS));\r
442\r
68fb0527 443 //\r
7c25b7ea 444 // Get the dns server list if has.\r
68fb0527 445 //\r
7c25b7ea 446 if (DataSize > 0) {\r
447 Status = Ip4Cfg2->GetData (\r
448 Ip4Cfg2,\r
449 Ip4Config2DataTypeDnsServer,\r
450 &DataSize,\r
451 IfCb->DnsAddr\r
452 );\r
453\r
454 if (EFI_ERROR (Status)) {\r
455 goto ON_ERROR;\r
68fb0527 456 }\r
68fb0527 457 }\r
458\r
459 //\r
7c25b7ea 460 // Get the config policy.\r
68fb0527 461 //\r
7c25b7ea 462 DataSize = sizeof (EFI_IP4_CONFIG2_POLICY);\r
463 Status = Ip4Cfg2->GetData (\r
464 Ip4Cfg2,\r
465 Ip4Config2DataTypePolicy,\r
466 &DataSize,\r
467 &IfCb->Policy\r
468 );\r
469\r
470 if (EFI_ERROR (Status)) {\r
471 goto ON_ERROR;\r
472 }\r
473\r
474 InsertTailList (IfList, &IfCb->Link);\r
68fb0527 475\r
7c25b7ea 476 if ((IfName != NULL) && (StrCmp (IfName, IfInfo->Name) == 0)) {\r
477 //\r
478 // Only need the appointed interface, keep the allocated buffer.\r
479 //\r
480 IfCb = NULL;\r
481 IfInfo = NULL;\r
482 break;\r
483 }\r
68fb0527 484 }\r
485\r
7c25b7ea 486 if (HandleBuffer != NULL) {\r
487 FreePool (HandleBuffer);\r
488 }\r
68fb0527 489\r
490 return EFI_SUCCESS;\r
7c25b7ea 491\r
68fb0527 492ON_ERROR:\r
7c25b7ea 493\r
494 if (IfInfo != NULL) {\r
495 FreePool (IfInfo);\r
68fb0527 496 }\r
497\r
7c25b7ea 498 if (IfCb != NULL) {\r
499 FreePool (IfCb);\r
500 }\r
68fb0527 501\r
502 return Status;\r
503}\r
504\r
505/**\r
7c25b7ea 506 The list process of the ifconfig command.\r
68fb0527 507\r
7c25b7ea 508 @param[in] IfList The pointer of IfList(interface list).\r
509\r
6e3e562c 510 @retval SHELL_SUCCESS The ifconfig command list processed successfully.\r
7c25b7ea 511 @retval others The ifconfig command list process failed.\r
68fb0527 512\r
68fb0527 513**/\r
6e3e562c 514SHELL_STATUS\r
7c25b7ea 515IfConfigShowInterfaceInfo (\r
516 IN LIST_ENTRY *IfList\r
68fb0527 517 )\r
518{\r
34297cef
JW
519 LIST_ENTRY *Entry;\r
520 LIST_ENTRY *Next;\r
521 IFCONFIG_INTERFACE_CB *IfCb;\r
522 BOOLEAN MediaPresent;\r
523 EFI_IPv4_ADDRESS Gateway;\r
524 UINT32 Index;\r
525 \r
526 MediaPresent = TRUE;\r
68fb0527 527\r
7c25b7ea 528 if (IsListEmpty (IfList)) {\r
529 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_INTERFACE), gShellNetwork1HiiHandle);\r
68fb0527 530 }\r
531\r
532 //\r
7c25b7ea 533 // Go through the interface list.\r
68fb0527 534 //\r
7c25b7ea 535 NET_LIST_FOR_EACH_SAFE (Entry, Next, IfList) {\r
536 IfCb = NET_LIST_USER_STRUCT (Entry, IFCONFIG_INTERFACE_CB, Link);\r
68fb0527 537\r
7c25b7ea 538 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_BREAK), gShellNetwork1HiiHandle);\r
68fb0527 539\r
7c25b7ea 540 //\r
541 // Print interface name.\r
542 //\r
34297cef
JW
543 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_IF_NAME), gShellNetwork1HiiHandle, IfCb->IfInfo->Name); \r
544\r
545 //\r
546 // Get Media State.\r
547 //\r
548 NetLibDetectMedia (IfCb->NicHandle, &MediaPresent);\r
549 if (!MediaPresent) {\r
550 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MEDIA_STATE), gShellNetwork1HiiHandle, L"Media disconnected");\r
551 } else {\r
552 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MEDIA_STATE), gShellNetwork1HiiHandle, L"Media present");\r
553 }\r
68fb0527 554\r
7c25b7ea 555 //\r
556 // Print interface config policy.\r
557 //\r
558 if (IfCb->Policy == Ip4Config2PolicyDhcp) {\r
559 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_POLICY_DHCP), gShellNetwork1HiiHandle);\r
560 } else {\r
561 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_POLICY_MAN), gShellNetwork1HiiHandle);\r
562 }\r
68fb0527 563\r
7c25b7ea 564 //\r
565 // Print mac address of the interface.\r
566 //\r
567 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MAC_ADDR_HEAD), gShellNetwork1HiiHandle);\r
68fb0527 568\r
7c25b7ea 569 IfConfigPrintMacAddr (\r
570 IfCb->IfInfo->HwAddress.Addr,\r
571 IfCb->IfInfo->HwAddressSize\r
572 );\r
68fb0527 573\r
7c25b7ea 574 //\r
575 // Print IPv4 address list of the interface.\r
576 //\r
577 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_IP_ADDR_HEAD), gShellNetwork1HiiHandle);\r
68fb0527 578\r
7c25b7ea 579 ShellPrintHiiEx(\r
580 -1, \r
581 -1, \r
582 NULL,\r
583 STRING_TOKEN (STR_IFCONFIG_INFO_IP_ADDR_BODY), \r
584 gShellNetwork1HiiHandle,\r
585 (UINTN)IfCb->IfInfo->StationAddress.Addr[0],\r
586 (UINTN)IfCb->IfInfo->StationAddress.Addr[1],\r
587 (UINTN)IfCb->IfInfo->StationAddress.Addr[2],\r
588 (UINTN)IfCb->IfInfo->StationAddress.Addr[3]\r
589 );\r
590\r
591 //\r
592 // Print subnet mask list of the interface.\r
593 //\r
594 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_SUBNET_MASK_HEAD), gShellNetwork1HiiHandle);\r
68fb0527 595\r
68fb0527 596 ShellPrintHiiEx(\r
597 -1, \r
598 -1, \r
599 NULL,\r
7c25b7ea 600 STRING_TOKEN (STR_IFCONFIG_INFO_IP_ADDR_BODY), \r
601 gShellNetwork1HiiHandle,\r
602 (UINTN)IfCb->IfInfo->SubnetMask.Addr[0],\r
603 (UINTN)IfCb->IfInfo->SubnetMask.Addr[1],\r
604 (UINTN)IfCb->IfInfo->SubnetMask.Addr[2],\r
605 (UINTN)IfCb->IfInfo->SubnetMask.Addr[3]\r
68fb0527 606 );\r
68fb0527 607\r
7c25b7ea 608 //\r
609 // Print default gateway of the interface.\r
610 //\r
611 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_GATEWAY_HEAD), gShellNetwork1HiiHandle);\r
612\r
613 ZeroMem (&Gateway, sizeof (EFI_IPv4_ADDRESS));\r
614 \r
615 for (Index = 0; Index < IfCb->IfInfo->RouteTableSize; Index++) {\r
616 if ((CompareMem (&IfCb->IfInfo->RouteTable[Index].SubnetAddress, &mZeroIp4Addr, sizeof (EFI_IPv4_ADDRESS)) == 0) &&\r
617 (CompareMem (&IfCb->IfInfo->RouteTable[Index].SubnetMask , &mZeroIp4Addr, sizeof (EFI_IPv4_ADDRESS)) == 0) ){\r
618 CopyMem (&Gateway, &IfCb->IfInfo->RouteTable[Index].GatewayAddress, sizeof (EFI_IPv4_ADDRESS));\r
619 }\r
620 } \r
621\r
68fb0527 622 ShellPrintHiiEx(\r
7c25b7ea 623 -1, \r
624 -1, \r
625 NULL,\r
626 STRING_TOKEN (STR_IFCONFIG_INFO_IP_ADDR_BODY), \r
627 gShellNetwork1HiiHandle,\r
628 (UINTN)Gateway.Addr[0],\r
629 (UINTN)Gateway.Addr[1],\r
630 (UINTN)Gateway.Addr[2],\r
631 (UINTN)Gateway.Addr[3]\r
632 );\r
633 \r
634 //\r
635 // Print route table entry.\r
636 //\r
637 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_ROUTES_SIZE), gShellNetwork1HiiHandle, IfCb->IfInfo->RouteTableSize);\r
638\r
639 for (Index = 0; Index < IfCb->IfInfo->RouteTableSize; Index++) {\r
640 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_ROUTES_ENTRY_INDEX), gShellNetwork1HiiHandle, Index);\r
641\r
642 ShellPrintHiiEx(\r
643 -1, \r
644 -1, \r
645 NULL,\r
646 STRING_TOKEN (STR_IFCONFIG_SHOW_IP_ADDR), \r
647 gShellNetwork1HiiHandle, \r
648 L"Subnet ",\r
649 (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetAddress.Addr[0],\r
650 (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetAddress.Addr[1],\r
651 (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetAddress.Addr[2],\r
652 (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetAddress.Addr[3]\r
653 );\r
654\r
655 ShellPrintHiiEx(\r
656 -1, \r
657 -1, \r
658 NULL,\r
659 STRING_TOKEN (STR_IFCONFIG_SHOW_IP_ADDR), \r
660 gShellNetwork1HiiHandle, \r
661 L"Netmask",\r
662 (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetMask.Addr[0],\r
663 (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetMask.Addr[1],\r
664 (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetMask.Addr[2],\r
665 (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetMask.Addr[3]\r
666 );\r
667\r
668 ShellPrintHiiEx(\r
669 -1, \r
670 -1, \r
671 NULL,\r
672 STRING_TOKEN (STR_IFCONFIG_SHOW_IP_ADDR), \r
673 gShellNetwork1HiiHandle, \r
674 L"Gateway",\r
675 (UINTN)IfCb->IfInfo->RouteTable[Index].GatewayAddress.Addr[0],\r
676 (UINTN)IfCb->IfInfo->RouteTable[Index].GatewayAddress.Addr[1],\r
677 (UINTN)IfCb->IfInfo->RouteTable[Index].GatewayAddress.Addr[2],\r
678 (UINTN)IfCb->IfInfo->RouteTable[Index].GatewayAddress.Addr[3]\r
679 );\r
680 }\r
681\r
682 //\r
683 // Print dns server addresses list of the interface if has.\r
684 //\r
685 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_DNS_ADDR_HEAD), gShellNetwork1HiiHandle);\r
686\r
687 for (Index = 0; Index < IfCb->DnsCnt; Index++) {\r
688 ShellPrintHiiEx(\r
689 -1, \r
690 -1, \r
691 NULL,\r
692 STRING_TOKEN (STR_IFCONFIG_INFO_DNS_ADDR_BODY), \r
693 gShellNetwork1HiiHandle,\r
694 (UINTN) IfCb->DnsAddr[Index].Addr[0],\r
695 (UINTN) IfCb->DnsAddr[Index].Addr[1],\r
696 (UINTN) IfCb->DnsAddr[Index].Addr[2],\r
697 (UINTN) IfCb->DnsAddr[Index].Addr[3]\r
698 );\r
699\r
700 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_NEWLINE), gShellNetwork1HiiHandle);\r
701 }\r
68fb0527 702 }\r
7c25b7ea 703 \r
704 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_BREAK), gShellNetwork1HiiHandle);\r
68fb0527 705\r
6e3e562c 706 return SHELL_SUCCESS;\r
68fb0527 707}\r
708\r
709/**\r
7c25b7ea 710 The clean process of the ifconfig command to clear interface info.\r
711\r
712 @param[in] IfList The pointer of IfList(interface list).\r
913ba151 713 @param[in] IfName The pointer of interface name.\r
68fb0527 714\r
6e3e562c 715 @retval SHELL_SUCCESS The ifconfig command clean processed successfully.\r
7c25b7ea 716 @retval others The ifconfig command clean process failed.\r
68fb0527 717\r
68fb0527 718**/\r
6e3e562c 719SHELL_STATUS\r
7c25b7ea 720IfConfigClearInterfaceInfo (\r
913ba151
JW
721 IN LIST_ENTRY *IfList,\r
722 IN CHAR16 *IfName\r
68fb0527 723 )\r
724{\r
6e3e562c
JW
725 EFI_STATUS Status; \r
726 SHELL_STATUS ShellStatus;\r
7c25b7ea 727 LIST_ENTRY *Entry;\r
728 LIST_ENTRY *Next;\r
729 IFCONFIG_INTERFACE_CB *IfCb;\r
730 EFI_IP4_CONFIG2_POLICY Policy;\r
913ba151 731 \r
7c25b7ea 732 Status = EFI_SUCCESS;\r
6e3e562c 733 ShellStatus = SHELL_SUCCESS;\r
68fb0527 734\r
7c25b7ea 735 if (IsListEmpty (IfList)) {\r
736 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_INTERFACE), gShellNetwork1HiiHandle);\r
68fb0527 737 }\r
738\r
739 //\r
7c25b7ea 740 // Go through the interface list.\r
913ba151
JW
741 // If the interface name is specified, DHCP DORA process will be \r
742 // triggered by the policy transition (static -> dhcp).\r
68fb0527 743 //\r
7c25b7ea 744 NET_LIST_FOR_EACH_SAFE (Entry, Next, IfList) {\r
745 IfCb = NET_LIST_USER_STRUCT (Entry, IFCONFIG_INTERFACE_CB, Link);\r
913ba151
JW
746\r
747 if ((IfName != NULL) && (StrCmp (IfName, IfCb->IfInfo->Name) == 0)) {\r
748 Policy = Ip4Config2PolicyStatic;\r
749 \r
750 Status = IfCb->IfCfg->SetData (\r
751 IfCb->IfCfg,\r
752 Ip4Config2DataTypePolicy,\r
753 sizeof (EFI_IP4_CONFIG2_POLICY),\r
754 &Policy\r
755 );\r
756 if (EFI_ERROR (Status)) {\r
757 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork1HiiHandle, L"ifconfig");\r
758 ShellStatus = SHELL_ACCESS_DENIED;\r
759 break;\r
760 } \r
761 }\r
762\r
763 Policy = Ip4Config2PolicyDhcp;\r
68fb0527 764 \r
7c25b7ea 765 Status = IfCb->IfCfg->SetData (\r
766 IfCb->IfCfg,\r
767 Ip4Config2DataTypePolicy,\r
768 sizeof (EFI_IP4_CONFIG2_POLICY),\r
769 &Policy\r
770 );\r
7c25b7ea 771 if (EFI_ERROR (Status)) {\r
d1baf355 772 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork1HiiHandle, L"ifconfig");\r
6e3e562c 773 ShellStatus = SHELL_ACCESS_DENIED;\r
7c25b7ea 774 break;\r
775 }\r
68fb0527 776 }\r
777\r
6e3e562c 778 return ShellStatus;\r
68fb0527 779}\r
780\r
781/**\r
7c25b7ea 782 The set process of the ifconfig command.\r
68fb0527 783\r
7c25b7ea 784 @param[in] IfList The pointer of IfList(interface list).\r
785 @param[in] VarArg The pointer of ARG_LIST(Args with "-s" option).\r
68fb0527 786\r
6e3e562c 787 @retval SHELL_SUCCESS The ifconfig command set processed successfully.\r
7c25b7ea 788 @retval others The ifconfig command set process failed.\r
68fb0527 789\r
68fb0527 790**/\r
6e3e562c 791SHELL_STATUS\r
7c25b7ea 792IfConfigSetInterfaceInfo (\r
793 IN LIST_ENTRY *IfList,\r
794 IN ARG_LIST *VarArg\r
68fb0527 795 )\r
796{\r
7c25b7ea 797 EFI_STATUS Status;\r
6e3e562c 798 SHELL_STATUS ShellStatus;\r
7c25b7ea 799 IFCONFIG_INTERFACE_CB *IfCb;\r
800 VAR_CHECK_CODE CheckCode;\r
801 EFI_EVENT TimeOutEvt;\r
802 EFI_EVENT MappedEvt;\r
803 BOOLEAN IsAddressOk;\r
68fb0527 804\r
7c25b7ea 805 EFI_IP4_CONFIG2_POLICY Policy;\r
806 EFI_IP4_CONFIG2_MANUAL_ADDRESS ManualAddress;\r
807 UINTN DataSize;\r
808 EFI_IPv4_ADDRESS Gateway;\r
809 EFI_IPv4_ADDRESS *Dns;\r
810 ARG_LIST *Tmp;\r
811 UINTN Index;\r
68fb0527 812\r
7c25b7ea 813 CONST CHAR16* TempString;\r
68fb0527 814\r
7c25b7ea 815 Dns = NULL;\r
68fb0527 816\r
7c25b7ea 817 if (IsListEmpty (IfList)) {\r
818 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_INTERFACE), gShellNetwork1HiiHandle);\r
6e3e562c 819 return SHELL_INVALID_PARAMETER;\r
68fb0527 820 }\r
68fb0527 821 \r
7c25b7ea 822 //\r
823 // Make sure to set only one interface each time.\r
824 //\r
825 IfCb = NET_LIST_USER_STRUCT (IfList->ForwardLink, IFCONFIG_INTERFACE_CB, Link);\r
826 Status = EFI_SUCCESS;\r
6e3e562c 827 ShellStatus = SHELL_SUCCESS;\r
68fb0527 828\r
7c25b7ea 829 //\r
830 // Initialize check list mechanism.\r
831 //\r
832 CheckCode = IfConfigRetriveCheckListByName(\r
833 NULL,\r
834 NULL,\r
835 TRUE\r
836 );\r
68fb0527 837\r
7c25b7ea 838 //\r
839 // Create events & timers for asynchronous settings.\r
840 //\r
841 Status = gBS->CreateEvent (\r
842 EVT_TIMER,\r
843 TPL_CALLBACK,\r
844 NULL,\r
845 NULL,\r
846 &TimeOutEvt\r
847 );\r
68fb0527 848 if (EFI_ERROR (Status)) {\r
d1baf355 849 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork1HiiHandle, L"ifconfig");\r
6e3e562c 850 ShellStatus = SHELL_ACCESS_DENIED;\r
7c25b7ea 851 goto ON_EXIT;\r
68fb0527 852 }\r
853\r
7c25b7ea 854 Status = gBS->CreateEvent (\r
855 EVT_NOTIFY_SIGNAL,\r
856 TPL_NOTIFY,\r
857 IfConfigManualAddressNotify,\r
858 &IsAddressOk,\r
859 &MappedEvt\r
860 );\r
861 if (EFI_ERROR (Status)) {\r
d1baf355 862 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork1HiiHandle, L"ifconfig");\r
6e3e562c 863 ShellStatus = SHELL_ACCESS_DENIED;\r
7c25b7ea 864 goto ON_EXIT;\r
68fb0527 865 }\r
866\r
7c25b7ea 867 //\r
868 // Parse the setting variables.\r
869 //\r
870 while (VarArg != NULL) {\r
871 //\r
872 // Check invalid parameters (duplication & unknown & conflict).\r
873 //\r
874 CheckCode = IfConfigRetriveCheckListByName(\r
875 mSetCheckList,\r
876 VarArg->Arg,\r
877 FALSE\r
878 );\r
68fb0527 879\r
7c25b7ea 880 if (VarCheckOk != CheckCode) {\r
881 switch (CheckCode) {\r
882 case VarCheckDuplicate:\r
883 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_DUPLICATE_COMMAND), gShellNetwork1HiiHandle, VarArg->Arg);\r
884 break;\r
68fb0527 885\r
7c25b7ea 886 case VarCheckConflict:\r
887 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_CONFLICT_COMMAND), gShellNetwork1HiiHandle, VarArg->Arg);\r
888 break;\r
68fb0527 889\r
7c25b7ea 890 case VarCheckUnknown:\r
891 //\r
892 // To handle unsupported option.\r
893 //\r
894 TempString = PermanentString;\r
895 if (StringNoCaseCompare(&VarArg->Arg, &TempString) == 0) {\r
896 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_UNSUPPORTED_OPTION), gShellNetwork1HiiHandle, PermanentString);\r
897 goto ON_EXIT;\r
898 }\r
68fb0527 899\r
7c25b7ea 900 //\r
901 // To handle unknown option.\r
902 //\r
903 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_UNKNOWN_COMMAND), gShellNetwork1HiiHandle, VarArg->Arg);\r
904 break;\r
68fb0527 905\r
7c25b7ea 906 default:\r
907 break;\r
908 }\r
68fb0527 909\r
7c25b7ea 910 VarArg = VarArg->Next;\r
911 continue; \r
912 }\r
68fb0527 913\r
68fb0527 914 //\r
7c25b7ea 915 // Process valid variables.\r
68fb0527 916 //\r
7c25b7ea 917 if (StrCmp(VarArg->Arg, L"dhcp") == 0) {\r
db54ae08
JW
918 //\r
919 // Set dhcp config policy\r
920 //\r
921 Policy = Ip4Config2PolicyDhcp;\r
922 Status = IfCb->IfCfg->SetData (\r
923 IfCb->IfCfg,\r
924 Ip4Config2DataTypePolicy,\r
925 sizeof (EFI_IP4_CONFIG2_POLICY),\r
926 &Policy\r
927 );\r
928 if (EFI_ERROR(Status)) {\r
929 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork1HiiHandle, L"ifconfig");\r
930 ShellStatus = SHELL_ACCESS_DENIED;\r
931 goto ON_EXIT;\r
7c25b7ea 932 }\r
d6cf1af9 933 \r
7c25b7ea 934 VarArg= VarArg->Next; \r
68fb0527 935\r
7c25b7ea 936 } else if (StrCmp (VarArg->Arg, L"static") == 0) {\r
d1baf355
JW
937 VarArg= VarArg->Next;\r
938 if (VarArg == NULL) {\r
939 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_LACK_COMMAND), gShellNetwork1HiiHandle);\r
940 ShellStatus = SHELL_INVALID_PARAMETER;\r
68fb0527 941 goto ON_EXIT;\r
942 }\r
943\r
7c25b7ea 944 ZeroMem (&ManualAddress, sizeof (ManualAddress));\r
945 \r
946 //\r
947 // Get manual IP address.\r
948 //\r
949 Status = NetLibStrToIp4 (VarArg->Arg, &ManualAddress.Address);\r
950 if (EFI_ERROR(Status)) {\r
d1baf355 951 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_INVALID_IPADDRESS), gShellNetwork1HiiHandle, VarArg->Arg);\r
6e3e562c 952 ShellStatus = SHELL_INVALID_PARAMETER;\r
7c25b7ea 953 goto ON_EXIT;\r
954 }\r
68fb0527 955\r
7c25b7ea 956 //\r
957 // Get subnetmask.\r
958 // \r
959 VarArg = VarArg->Next;\r
d1baf355
JW
960 if (VarArg == NULL) {\r
961 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_LACK_COMMAND), gShellNetwork1HiiHandle);\r
962 ShellStatus = SHELL_INVALID_PARAMETER;\r
963 goto ON_EXIT;\r
964 }\r
965 \r
7c25b7ea 966 Status = NetLibStrToIp4 (VarArg->Arg, &ManualAddress.SubnetMask);\r
967 if (EFI_ERROR(Status)) {\r
d1baf355 968 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_INVALID_IPADDRESS), gShellNetwork1HiiHandle, VarArg->Arg);\r
6e3e562c 969 ShellStatus = SHELL_INVALID_PARAMETER;\r
7c25b7ea 970 goto ON_EXIT;\r
971 }\r
68fb0527 972\r
7c25b7ea 973 //\r
974 // Get gateway.\r
975 //\r
976 VarArg = VarArg->Next;\r
d1baf355
JW
977 if (VarArg == NULL) {\r
978 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_LACK_COMMAND), gShellNetwork1HiiHandle);\r
979 ShellStatus = SHELL_INVALID_PARAMETER;\r
980 goto ON_EXIT;\r
981 }\r
982 \r
7c25b7ea 983 Status = NetLibStrToIp4 (VarArg->Arg, &Gateway);\r
984 if (EFI_ERROR(Status)) {\r
d1baf355 985 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_INVALID_IPADDRESS), gShellNetwork1HiiHandle, VarArg->Arg);\r
6e3e562c 986 ShellStatus = SHELL_INVALID_PARAMETER;\r
7c25b7ea 987 goto ON_EXIT;\r
988 }\r
d1baf355
JW
989\r
990 //\r
991 // Set manual config policy.\r
992 //\r
993 Policy = Ip4Config2PolicyStatic;\r
994 Status = IfCb->IfCfg->SetData (\r
995 IfCb->IfCfg,\r
996 Ip4Config2DataTypePolicy,\r
997 sizeof (EFI_IP4_CONFIG2_POLICY),\r
998 &Policy\r
999 );\r
1000 if (EFI_ERROR(Status)) {\r
1001 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork1HiiHandle, L"ifconfig");\r
1002 ShellStatus = SHELL_ACCESS_DENIED;\r
1003 goto ON_EXIT;\r
1004 }\r
7c25b7ea 1005 \r
d1baf355
JW
1006 //\r
1007 // Set Manual Address.\r
1008 //\r
7c25b7ea 1009 IsAddressOk = FALSE;\r
1010\r
1011 Status = IfCb->IfCfg->RegisterDataNotify (\r
1012 IfCb->IfCfg,\r
1013 Ip4Config2DataTypeManualAddress,\r
1014 MappedEvt\r
1015 );\r
1016 if (EFI_ERROR (Status)) {\r
d1baf355 1017 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_SET_ADDR_FAILED), gShellNetwork1HiiHandle, Status);\r
6e3e562c 1018 ShellStatus = SHELL_ACCESS_DENIED;\r
7c25b7ea 1019 goto ON_EXIT;\r
1020 }\r
68fb0527 1021\r
7c25b7ea 1022 DataSize = sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS);\r
68fb0527 1023\r
7c25b7ea 1024 Status = IfCb->IfCfg->SetData (\r
1025 IfCb->IfCfg,\r
1026 Ip4Config2DataTypeManualAddress,\r
1027 DataSize,\r
1028 &ManualAddress\r
1029 );\r
68fb0527 1030\r
7c25b7ea 1031 if (Status == EFI_NOT_READY) {\r
1032 gBS->SetTimer (TimeOutEvt, TimerRelative, 50000000);\r
68fb0527 1033\r
7c25b7ea 1034 while (EFI_ERROR (gBS->CheckEvent (TimeOutEvt))) {\r
1035 if (IsAddressOk) {\r
1036 Status = EFI_SUCCESS;\r
1037 break;\r
1038 }\r
1039 }\r
1040 }\r
68fb0527 1041\r
7c25b7ea 1042 IfCb->IfCfg->UnregisterDataNotify (\r
1043 IfCb->IfCfg,\r
1044 Ip4Config2DataTypeManualAddress,\r
1045 MappedEvt\r
1046 );\r
6e3e562c 1047 \r
7c25b7ea 1048 if (EFI_ERROR (Status)) {\r
1049 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_SET_ADDR_FAILED), gShellNetwork1HiiHandle, Status);\r
6e3e562c 1050 ShellStatus = SHELL_ACCESS_DENIED;\r
68fb0527 1051 goto ON_EXIT;\r
1052 }\r
1053\r
7c25b7ea 1054 //\r
1055 // Set gateway.\r
1056 //\r
1057 DataSize = sizeof (EFI_IPv4_ADDRESS);\r
1058\r
1059 Status = IfCb->IfCfg->SetData (\r
1060 IfCb->IfCfg,\r
1061 Ip4Config2DataTypeGateway,\r
1062 DataSize,\r
1063 &Gateway\r
1064 );\r
6e3e562c 1065 if (EFI_ERROR (Status)) {\r
d1baf355 1066 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_SET_ADDR_FAILED), gShellNetwork1HiiHandle, Status);\r
6e3e562c
JW
1067 ShellStatus = SHELL_ACCESS_DENIED;\r
1068 goto ON_EXIT;\r
1069 }\r
1070 \r
7c25b7ea 1071 VarArg = VarArg->Next;\r
1072 \r
1073 } else if (StrCmp (VarArg->Arg, L"dns") == 0) {\r
1074 //\r
1075 // Get DNS addresses.\r
1076 //\r
1077 VarArg = VarArg->Next;\r
1078 Tmp = VarArg;\r
1079 Index = 0;\r
1080 while (Tmp != NULL) {\r
1081 Index ++;\r
1082 Tmp = Tmp->Next;\r
1083 }\r
68fb0527 1084\r
7c25b7ea 1085 Dns = AllocatePool (Index * sizeof (EFI_IPv4_ADDRESS));\r
1086 ASSERT(Dns != NULL);\r
1087 Tmp = VarArg;\r
1088 Index = 0;\r
1089 while (Tmp != NULL) {\r
1090 Status = NetLibStrToIp4 (Tmp->Arg, Dns + Index);\r
1091 if (EFI_ERROR(Status)) {\r
d1baf355 1092 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_INVALID_IPADDRESS), gShellNetwork1HiiHandle, Tmp->Arg);\r
6e3e562c 1093 ShellStatus = SHELL_INVALID_PARAMETER;\r
7c25b7ea 1094 goto ON_EXIT;\r
1095 }\r
1096 Index ++;\r
1097 Tmp = Tmp->Next;\r
1098 }\r
1099 \r
1100 VarArg = Tmp;\r
68fb0527 1101\r
7c25b7ea 1102 //\r
1103 // Set DNS addresses.\r
1104 //\r
1105 DataSize = Index * sizeof (EFI_IPv4_ADDRESS);\r
1106\r
1107 Status = IfCb->IfCfg->SetData (\r
1108 IfCb->IfCfg,\r
1109 Ip4Config2DataTypeDnsServer,\r
1110 DataSize,\r
1111 Dns\r
1112 );\r
6e3e562c 1113 if (EFI_ERROR (Status)) {\r
d1baf355 1114 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork1HiiHandle, L"ifconfig");\r
6e3e562c
JW
1115 ShellStatus = SHELL_ACCESS_DENIED;\r
1116 goto ON_EXIT;\r
1117 }\r
68fb0527 1118 }\r
7c25b7ea 1119 }\r
68fb0527 1120\r
7c25b7ea 1121ON_EXIT:\r
1122 if (Dns != NULL) {\r
1123 FreePool (Dns);\r
1124 }\r
1125 \r
6e3e562c 1126 return ShellStatus;\r
68fb0527 1127\r
7c25b7ea 1128}\r
68fb0527 1129\r
7c25b7ea 1130/**\r
1131 The ifconfig command main process.\r
68fb0527 1132\r
7c25b7ea 1133 @param[in] Private The pointer of IFCONFIG_PRIVATE_DATA.\r
68fb0527 1134\r
6e3e562c 1135 @retval SHELL_SUCCESS ifconfig command processed successfully.\r
7c25b7ea 1136 @retval others The ifconfig command process failed.\r
68fb0527 1137\r
7c25b7ea 1138**/\r
6e3e562c 1139SHELL_STATUS\r
7c25b7ea 1140IfConfig (\r
1141 IN IFCONFIG_PRIVATE_DATA *Private\r
1142 )\r
1143{\r
1144 EFI_STATUS Status;\r
6e3e562c
JW
1145 SHELL_STATUS ShellStatus;\r
1146\r
1147 ShellStatus = SHELL_SUCCESS;\r
68fb0527 1148\r
1149 //\r
7c25b7ea 1150 // Get configure information of all interfaces.\r
68fb0527 1151 //\r
7c25b7ea 1152 Status = IfConfigGetInterfaceInfo (\r
1153 Private->IfName,\r
1154 &Private->IfList\r
1155 );\r
7c25b7ea 1156 if (EFI_ERROR (Status)) {\r
6e3e562c 1157 ShellStatus = SHELL_NOT_FOUND; \r
7c25b7ea 1158 goto ON_EXIT;\r
68fb0527 1159 }\r
1160\r
7c25b7ea 1161 switch (Private->OpCode) {\r
1162 case IfConfigOpList:\r
6e3e562c 1163 ShellStatus = IfConfigShowInterfaceInfo (&Private->IfList);\r
7c25b7ea 1164 break;\r
1165\r
1166 case IfConfigOpClear:\r
913ba151 1167 ShellStatus = IfConfigClearInterfaceInfo (&Private->IfList, Private->IfName);\r
7c25b7ea 1168 break;\r
1169\r
1170 case IfConfigOpSet:\r
6e3e562c 1171 ShellStatus = IfConfigSetInterfaceInfo (&Private->IfList, Private->VarArg);\r
7c25b7ea 1172 break;\r
1173\r
1174 default:\r
6e3e562c 1175 ShellStatus = SHELL_UNSUPPORTED;\r
68fb0527 1176 }\r
7c25b7ea 1177\r
68fb0527 1178ON_EXIT:\r
6e3e562c 1179 return ShellStatus;\r
68fb0527 1180}\r
1181\r
1182/**\r
7c25b7ea 1183 The ifconfig command cleanup process, free the allocated memory.\r
1184\r
1185 @param[in] Private The pointer of IFCONFIG_PRIVATE_DATA.\r
68fb0527 1186\r
68fb0527 1187**/\r
1188VOID\r
7c25b7ea 1189IfConfigCleanup (\r
1190 IN IFCONFIG_PRIVATE_DATA *Private\r
68fb0527 1191 )\r
1192{\r
1193 LIST_ENTRY *Entry;\r
1194 LIST_ENTRY *NextEntry;\r
7c25b7ea 1195 IFCONFIG_INTERFACE_CB *IfCb;\r
1196 ARG_LIST *ArgNode;\r
1197 ARG_LIST *ArgHead;\r
68fb0527 1198\r
7c25b7ea 1199 ASSERT (Private != NULL);\r
68fb0527 1200\r
7c25b7ea 1201 //\r
1202 // Clean the list which save the set config Args.\r
1203 //\r
1204 if (Private->VarArg != NULL) {\r
1205 ArgHead = Private->VarArg;\r
68fb0527 1206\r
7c25b7ea 1207 while (ArgHead->Next != NULL) {\r
1208 ArgNode = ArgHead->Next;\r
1209 FreePool (ArgHead);\r
1210 ArgHead = ArgNode;\r
68fb0527 1211 }\r
1212\r
7c25b7ea 1213 FreePool (ArgHead);\r
68fb0527 1214 }\r
1215\r
7c25b7ea 1216 if (Private->IfName != NULL) {\r
1217 FreePool (Private->IfName);\r
1218 }\r
68fb0527 1219\r
7c25b7ea 1220 //\r
1221 // Clean the IFCONFIG_INTERFACE_CB list.\r
1222 //\r
1223 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->IfList) {\r
1224 IfCb = NET_LIST_USER_STRUCT (Entry, IFCONFIG_INTERFACE_CB, Link);\r
68fb0527 1225\r
7c25b7ea 1226 RemoveEntryList (&IfCb->Link);\r
68fb0527 1227\r
7c25b7ea 1228 if (IfCb->IfInfo != NULL) {\r
68fb0527 1229\r
7c25b7ea 1230 FreePool (IfCb->IfInfo);\r
68fb0527 1231 }\r
1232\r
7c25b7ea 1233 FreePool (IfCb);\r
68fb0527 1234 }\r
1235\r
7c25b7ea 1236 FreePool (Private);\r
68fb0527 1237}\r
1238\r
1239/**\r
1240 Function for 'ifconfig' command.\r
1241\r
1242 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
1243 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
7c25b7ea 1244\r
1245 @retval EFI_SUCCESS ifconfig command processed successfully.\r
1246 @retval others The ifconfig command process failed.\r
1247 \r
68fb0527 1248**/\r
1249SHELL_STATUS\r
1250EFIAPI\r
1251ShellCommandRunIfconfig (\r
1252 IN EFI_HANDLE ImageHandle,\r
1253 IN EFI_SYSTEM_TABLE *SystemTable\r
1254 )\r
1255{\r
7c25b7ea 1256 EFI_STATUS Status;\r
1257 IFCONFIG_PRIVATE_DATA *Private;\r
1258 LIST_ENTRY *ParamPackage;\r
6e3e562c 1259 SHELL_STATUS ShellStatus;\r
7c25b7ea 1260 CONST CHAR16 *ValueStr;\r
1261 ARG_LIST *ArgList;\r
1262 CHAR16 *ProblemParam;\r
1263 CHAR16 *Str;\r
6e3e562c
JW
1264 \r
1265 Status = EFI_INVALID_PARAMETER;\r
7c25b7ea 1266 Private = NULL;\r
6e3e562c 1267 ShellStatus = SHELL_SUCCESS;\r
7c25b7ea 1268\r
1269 Status = ShellCommandLineParseEx (mIfConfigCheckList, &ParamPackage, &ProblemParam, TRUE, FALSE);\r
1270 if (EFI_ERROR (Status)) {\r
6e3e562c
JW
1271 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
1272 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellNetwork1HiiHandle, L"ifconfig", ProblemParam);\r
1273 FreePool(ProblemParam);\r
1274 ShellStatus = SHELL_INVALID_PARAMETER;\r
1275 } else {\r
1276 ASSERT(FALSE);\r
1277 }\r
1278 \r
7c25b7ea 1279 goto ON_EXIT;\r
1280 }\r
68fb0527 1281\r
1282 //\r
7c25b7ea 1283 // To handle unsupported option.\r
68fb0527 1284 //\r
7c25b7ea 1285 if (ShellCommandLineGetFlag (ParamPackage, L"-c")) {\r
1286 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_UNSUPPORTED_OPTION), gShellNetwork1HiiHandle,L"-c");\r
6e3e562c 1287 ShellStatus = SHELL_INVALID_PARAMETER;\r
7c25b7ea 1288 goto ON_EXIT;\r
1289 }\r
68fb0527 1290\r
1291 //\r
7c25b7ea 1292 // To handle no option.\r
68fb0527 1293 //\r
7c25b7ea 1294 if (!ShellCommandLineGetFlag (ParamPackage, L"-r") && !ShellCommandLineGetFlag (ParamPackage, L"-s") &&\r
1295 !ShellCommandLineGetFlag (ParamPackage, L"-l")) {\r
1296 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_LACK_OPTION), gShellNetwork1HiiHandle);\r
6e3e562c 1297 ShellStatus = SHELL_INVALID_PARAMETER;\r
7c25b7ea 1298 goto ON_EXIT;\r
68fb0527 1299 }\r
1300\r
7c25b7ea 1301 //\r
1302 // To handle conflict options.\r
1303 //\r
1304 if (((ShellCommandLineGetFlag (ParamPackage, L"-r")) && (ShellCommandLineGetFlag (ParamPackage, L"-s"))) ||\r
1305 ((ShellCommandLineGetFlag (ParamPackage, L"-r")) && (ShellCommandLineGetFlag (ParamPackage, L"-l"))) ||\r
1306 ((ShellCommandLineGetFlag (ParamPackage, L"-s")) && (ShellCommandLineGetFlag (ParamPackage, L"-l")))) {\r
1307 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellNetwork1HiiHandle, L"ifconfig");\r
6e3e562c 1308 ShellStatus = SHELL_INVALID_PARAMETER;\r
7c25b7ea 1309 goto ON_EXIT;\r
68fb0527 1310 }\r
68fb0527 1311\r
7c25b7ea 1312 Private = AllocateZeroPool (sizeof (IFCONFIG_PRIVATE_DATA));\r
7c25b7ea 1313 if (Private == NULL) {\r
6e3e562c 1314 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
7c25b7ea 1315 goto ON_EXIT;\r
68fb0527 1316 }\r
1317\r
7c25b7ea 1318 InitializeListHead (&Private->IfList);\r
68fb0527 1319\r
7c25b7ea 1320 //\r
1321 // To get interface name for the list option.\r
1322 //\r
1323 if (ShellCommandLineGetFlag (ParamPackage, L"-l")) {\r
1324 Private->OpCode = IfConfigOpList;\r
1325 ValueStr = ShellCommandLineGetValue (ParamPackage, L"-l");\r
1326 if (ValueStr != NULL) {\r
1327 Str = AllocateCopyPool (StrSize (ValueStr), ValueStr);\r
1328 ASSERT (Str != NULL);\r
1329 Private->IfName = Str;\r
1330 }\r
1331 }\r
1332 \r
1333 //\r
1334 // To get interface name for the clear option.\r
1335 //\r
1336 if (ShellCommandLineGetFlag (ParamPackage, L"-r")) {\r
1337 Private->OpCode = IfConfigOpClear;\r
1338 ValueStr = ShellCommandLineGetValue (ParamPackage, L"-r");\r
1339 if (ValueStr != NULL) {\r
1340 Str = AllocateCopyPool (StrSize (ValueStr), ValueStr);\r
1341 ASSERT (Str != NULL);\r
1342 Private->IfName = Str;\r
1343 }\r
1344 }\r
1345 \r
1346 //\r
1347 // To get interface name and corresponding Args for the set option.\r
1348 //\r
1349 if (ShellCommandLineGetFlag (ParamPackage, L"-s")) {\r
1350 ValueStr = ShellCommandLineGetValue (ParamPackage, L"-s");\r
1351 if (ValueStr == NULL) {\r
1352 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_LACK_INTERFACE), gShellNetwork1HiiHandle);\r
6e3e562c 1353 ShellStatus = SHELL_INVALID_PARAMETER;\r
7c25b7ea 1354 goto ON_EXIT;\r
1355 }\r
68fb0527 1356 \r
1357 //\r
7c25b7ea 1358 // To split the configuration into multi-section.\r
68fb0527 1359 //\r
7c25b7ea 1360 ArgList = SplitStrToList (ValueStr, L' ');\r
1361 ASSERT (ArgList != NULL);\r
68fb0527 1362\r
7c25b7ea 1363 Private->OpCode = IfConfigOpSet;\r
1364 Private->IfName = ArgList->Arg;\r
68fb0527 1365\r
7c25b7ea 1366 Private->VarArg = ArgList->Next;\r
68fb0527 1367\r
7c25b7ea 1368 if (Private->IfName == NULL || Private->VarArg == NULL) {\r
1369 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_LACK_COMMAND), gShellNetwork1HiiHandle);\r
6e3e562c 1370 ShellStatus = SHELL_INVALID_PARAMETER;\r
7c25b7ea 1371 goto ON_EXIT;\r
68fb0527 1372 }\r
68fb0527 1373 }\r
7c25b7ea 1374 \r
1375 //\r
1376 // Main process of ifconfig.\r
1377 //\r
6e3e562c 1378 ShellStatus = IfConfig (Private);\r
68fb0527 1379\r
7c25b7ea 1380ON_EXIT:\r
68fb0527 1381\r
7c25b7ea 1382 ShellCommandLineFreeVarList (ParamPackage);\r
1383 \r
1384 if (Private != NULL) {\r
1385 IfConfigCleanup (Private);\r
68fb0527 1386 }\r
1387\r
6e3e562c 1388 return ShellStatus;\r
68fb0527 1389}\r