]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellNetwork1CommandsLib/Ifconfig.c
ShellPkg: Fix wrong return status for Ifconfig.c
[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
e75390f0 5 Copyright (c) 2006 - 2015, 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
7c25b7ea 276\r
d6cf1af9
JW
277/**\r
278 Create an IP child, use it to start the auto configuration, then destroy it.\r
279\r
280 @param[in] Controller The controller which has the service installed.\r
281 @param[in] Image The image handle used to open service.\r
282\r
283 @retval EFI_SUCCESS The configuration is done.\r
284**/\r
285EFI_STATUS\r
286EFIAPI\r
287IfConfigStartIp4(\r
288 IN EFI_HANDLE Controller,\r
289 IN EFI_HANDLE Image\r
290 )\r
291{\r
292 EFI_IP4_PROTOCOL *Ip4;\r
293 EFI_HANDLE Ip4Handle;\r
294 EFI_IP4_CONFIG_DATA Ip4ConfigData;\r
295 EFI_STATUS Status;\r
296\r
297 //\r
298 // Get the Ip4ServiceBinding Protocol\r
299 //\r
300 Ip4Handle = NULL;\r
301 Ip4 = NULL;\r
302\r
303 Status = NetLibCreateServiceChild (\r
304 Controller,\r
305 Image,\r
306 &gEfiIp4ServiceBindingProtocolGuid,\r
307 &Ip4Handle\r
308 );\r
309\r
310 if (EFI_ERROR (Status)) {\r
311 return Status;\r
312 }\r
313\r
314 Status = gBS->OpenProtocol (\r
315 Ip4Handle,\r
316 &gEfiIp4ProtocolGuid,\r
317 (VOID **) &Ip4,\r
318 Controller,\r
319 Image,\r
320 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
321 );\r
322\r
323 if (EFI_ERROR (Status)) {\r
324 goto ON_EXIT;\r
325 }\r
326\r
327 Ip4ConfigData.DefaultProtocol = EFI_IP_PROTO_ICMP;\r
328 Ip4ConfigData.AcceptAnyProtocol = FALSE;\r
329 Ip4ConfigData.AcceptIcmpErrors = FALSE;\r
330 Ip4ConfigData.AcceptBroadcast = FALSE;\r
331 Ip4ConfigData.AcceptPromiscuous = FALSE;\r
332 Ip4ConfigData.UseDefaultAddress = TRUE;\r
333 ZeroMem (&Ip4ConfigData.StationAddress, sizeof (EFI_IPv4_ADDRESS));\r
334 ZeroMem (&Ip4ConfigData.SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
335 Ip4ConfigData.TypeOfService = 0;\r
336 Ip4ConfigData.TimeToLive = 1;\r
337 Ip4ConfigData.DoNotFragment = FALSE;\r
338 Ip4ConfigData.RawData = FALSE;\r
339 Ip4ConfigData.ReceiveTimeout = 0;\r
340 Ip4ConfigData.TransmitTimeout = 0;\r
341\r
342 Ip4->Configure (Ip4, &Ip4ConfigData);\r
343 \r
344ON_EXIT: \r
345 NetLibDestroyServiceChild (\r
346 Controller,\r
347 Image,\r
348 &gEfiIp4ServiceBindingProtocolGuid,\r
349 Ip4Handle\r
350 );\r
351 \r
352 return Status;\r
353}\r
354\r
355\r
68fb0527 356/**\r
7c25b7ea 357 Print MAC address.\r
68fb0527 358\r
7c25b7ea 359 @param[in] Node The pointer of MAC address buffer.\r
360 @param[in] Size The size of MAC address buffer.\r
68fb0527 361\r
68fb0527 362**/\r
7c25b7ea 363VOID\r
364IfConfigPrintMacAddr (\r
365 IN UINT8 *Node,\r
366 IN UINT32 Size\r
367 )\r
68fb0527 368{\r
7c25b7ea 369 UINTN Index;\r
68fb0527 370\r
7c25b7ea 371 ASSERT (Size <= MACADDRMAXSIZE);\r
68fb0527 372\r
7c25b7ea 373 for (Index = 0; Index < Size; Index++) {\r
374 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MAC_ADDR_BODY), gShellNetwork1HiiHandle, Node[Index]);\r
375 if (Index + 1 < Size) {\r
376 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_COLON), gShellNetwork1HiiHandle);\r
377 }\r
68fb0527 378 }\r
68fb0527 379\r
7c25b7ea 380 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_NEWLINE), gShellNetwork1HiiHandle);\r
381}\r
68fb0527 382\r
68fb0527 383\r
7c25b7ea 384/**\r
385 The get current status of all handles.\r
68fb0527 386\r
7c25b7ea 387 @param[in] IfName The pointer of IfName(interface name).\r
388 @param[in] IfList The pointer of IfList(interface list).\r
68fb0527 389\r
7c25b7ea 390 @retval EFI_SUCCESS The get status processed successfully.\r
391 @retval others The get status process failed.\r
68fb0527 392\r
68fb0527 393**/\r
394EFI_STATUS\r
7c25b7ea 395IfConfigGetInterfaceInfo (\r
396 IN CHAR16 *IfName,\r
397 IN LIST_ENTRY *IfList\r
68fb0527 398 )\r
399{\r
7c25b7ea 400 EFI_STATUS Status;\r
401 UINTN HandleIndex;\r
402 UINTN HandleNum;\r
403 EFI_HANDLE *HandleBuffer;\r
404 EFI_IP4_CONFIG2_PROTOCOL *Ip4Cfg2;\r
405 EFI_IP4_CONFIG2_INTERFACE_INFO *IfInfo;\r
406 IFCONFIG_INTERFACE_CB *IfCb;\r
407 UINTN DataSize;\r
68fb0527 408\r
7c25b7ea 409 HandleBuffer = NULL;\r
410 HandleNum = 0;\r
411\r
412 IfInfo = NULL;\r
413 IfCb = NULL;\r
68fb0527 414\r
415 //\r
7c25b7ea 416 // Locate all the handles with ip4 service binding protocol.\r
68fb0527 417 //\r
418 Status = gBS->LocateHandleBuffer (\r
7c25b7ea 419 ByProtocol,\r
420 &gEfiIp4ServiceBindingProtocolGuid,\r
421 NULL,\r
422 &HandleNum,\r
423 &HandleBuffer\r
68fb0527 424 );\r
7c25b7ea 425 if (EFI_ERROR (Status) || (HandleNum == 0)) {\r
6e3e562c 426 return Status;\r
68fb0527 427 }\r
428\r
7c25b7ea 429 //\r
430 // Enumerate all handles that installed with ip4 service binding protocol.\r
431 //\r
432 for (HandleIndex = 0; HandleIndex < HandleNum; HandleIndex++) {\r
433 IfCb = NULL;\r
434 IfInfo = NULL;\r
435 DataSize = 0;\r
436\r
437 //\r
438 // Ip4config protocol and ip4 service binding protocol are installed\r
439 // on the same handle.\r
440 //\r
441 ASSERT (HandleBuffer != NULL);\r
442 Status = gBS->HandleProtocol (\r
443 HandleBuffer[HandleIndex],\r
444 &gEfiIp4Config2ProtocolGuid,\r
445 (VOID **) &Ip4Cfg2\r
446 );\r
447\r
68fb0527 448 if (EFI_ERROR (Status)) {\r
7c25b7ea 449 goto ON_ERROR;\r
68fb0527 450 }\r
7c25b7ea 451 \r
68fb0527 452 //\r
7c25b7ea 453 // Get the interface information size.\r
68fb0527 454 //\r
7c25b7ea 455 Status = Ip4Cfg2->GetData (\r
456 Ip4Cfg2,\r
457 Ip4Config2DataTypeInterfaceInfo,\r
458 &DataSize,\r
459 NULL\r
460 );\r
461\r
462 if (Status != EFI_BUFFER_TOO_SMALL) {\r
463 goto ON_ERROR;\r
33c031ee 464 }\r
7c25b7ea 465\r
466 IfInfo = AllocateZeroPool (DataSize);\r
467\r
468 if (IfInfo == NULL) {\r
68fb0527 469 Status = EFI_OUT_OF_RESOURCES;\r
470 goto ON_ERROR;\r
471 }\r
7c25b7ea 472 \r
68fb0527 473 //\r
7c25b7ea 474 // Get the interface info.\r
68fb0527 475 //\r
7c25b7ea 476 Status = Ip4Cfg2->GetData (\r
477 Ip4Cfg2,\r
478 Ip4Config2DataTypeInterfaceInfo,\r
479 &DataSize,\r
480 IfInfo\r
481 );\r
68fb0527 482\r
7c25b7ea 483 if (EFI_ERROR (Status)) {\r
68fb0527 484 goto ON_ERROR;\r
485 }\r
7c25b7ea 486 \r
68fb0527 487 //\r
7c25b7ea 488 // Check the interface name if required.\r
68fb0527 489 //\r
7c25b7ea 490 if ((IfName != NULL) && (StrCmp (IfName, IfInfo->Name) != 0)) {\r
491 FreePool (IfInfo);\r
492 continue;\r
68fb0527 493 }\r
494\r
7c25b7ea 495 DataSize = 0;\r
496 \r
68fb0527 497 //\r
7c25b7ea 498 // Get the size of dns server list.\r
68fb0527 499 //\r
7c25b7ea 500 Status = Ip4Cfg2->GetData (\r
501 Ip4Cfg2,\r
502 Ip4Config2DataTypeDnsServer,\r
503 &DataSize,\r
504 NULL\r
505 );\r
506\r
507 if ((Status != EFI_BUFFER_TOO_SMALL) && (Status != EFI_NOT_FOUND)) {\r
508 goto ON_ERROR;\r
509 }\r
510\r
511 IfCb = AllocateZeroPool (sizeof (IFCONFIG_INTERFACE_CB) + DataSize);\r
68fb0527 512\r
7c25b7ea 513 if (IfCb == NULL) {\r
68fb0527 514 Status = EFI_OUT_OF_RESOURCES;\r
515 goto ON_ERROR;\r
516 }\r
517\r
7c25b7ea 518 IfCb->NicHandle = HandleBuffer[HandleIndex];\r
519 IfCb->IfInfo = IfInfo;\r
520 IfCb->IfCfg = Ip4Cfg2;\r
521 IfCb->DnsCnt = (UINT32) (DataSize / sizeof (EFI_IPv4_ADDRESS));\r
522\r
68fb0527 523 //\r
7c25b7ea 524 // Get the dns server list if has.\r
68fb0527 525 //\r
7c25b7ea 526 if (DataSize > 0) {\r
527 Status = Ip4Cfg2->GetData (\r
528 Ip4Cfg2,\r
529 Ip4Config2DataTypeDnsServer,\r
530 &DataSize,\r
531 IfCb->DnsAddr\r
532 );\r
533\r
534 if (EFI_ERROR (Status)) {\r
535 goto ON_ERROR;\r
68fb0527 536 }\r
68fb0527 537 }\r
538\r
539 //\r
7c25b7ea 540 // Get the config policy.\r
68fb0527 541 //\r
7c25b7ea 542 DataSize = sizeof (EFI_IP4_CONFIG2_POLICY);\r
543 Status = Ip4Cfg2->GetData (\r
544 Ip4Cfg2,\r
545 Ip4Config2DataTypePolicy,\r
546 &DataSize,\r
547 &IfCb->Policy\r
548 );\r
549\r
550 if (EFI_ERROR (Status)) {\r
551 goto ON_ERROR;\r
552 }\r
553\r
554 InsertTailList (IfList, &IfCb->Link);\r
68fb0527 555\r
7c25b7ea 556 if ((IfName != NULL) && (StrCmp (IfName, IfInfo->Name) == 0)) {\r
557 //\r
558 // Only need the appointed interface, keep the allocated buffer.\r
559 //\r
560 IfCb = NULL;\r
561 IfInfo = NULL;\r
562 break;\r
563 }\r
68fb0527 564 }\r
565\r
7c25b7ea 566 if (HandleBuffer != NULL) {\r
567 FreePool (HandleBuffer);\r
568 }\r
68fb0527 569\r
570 return EFI_SUCCESS;\r
7c25b7ea 571\r
68fb0527 572ON_ERROR:\r
7c25b7ea 573\r
574 if (IfInfo != NULL) {\r
575 FreePool (IfInfo);\r
68fb0527 576 }\r
577\r
7c25b7ea 578 if (IfCb != NULL) {\r
579 FreePool (IfCb);\r
580 }\r
68fb0527 581\r
582 return Status;\r
583}\r
584\r
585/**\r
7c25b7ea 586 The list process of the ifconfig command.\r
68fb0527 587\r
7c25b7ea 588 @param[in] IfList The pointer of IfList(interface list).\r
589\r
6e3e562c 590 @retval SHELL_SUCCESS The ifconfig command list processed successfully.\r
7c25b7ea 591 @retval others The ifconfig command list process failed.\r
68fb0527 592\r
68fb0527 593**/\r
6e3e562c 594SHELL_STATUS\r
7c25b7ea 595IfConfigShowInterfaceInfo (\r
596 IN LIST_ENTRY *IfList\r
68fb0527 597 )\r
598{\r
34297cef
JW
599 LIST_ENTRY *Entry;\r
600 LIST_ENTRY *Next;\r
601 IFCONFIG_INTERFACE_CB *IfCb;\r
602 BOOLEAN MediaPresent;\r
603 EFI_IPv4_ADDRESS Gateway;\r
604 UINT32 Index;\r
605 \r
606 MediaPresent = TRUE;\r
68fb0527 607\r
7c25b7ea 608 if (IsListEmpty (IfList)) {\r
609 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_INTERFACE), gShellNetwork1HiiHandle);\r
68fb0527 610 }\r
611\r
612 //\r
7c25b7ea 613 // Go through the interface list.\r
68fb0527 614 //\r
7c25b7ea 615 NET_LIST_FOR_EACH_SAFE (Entry, Next, IfList) {\r
616 IfCb = NET_LIST_USER_STRUCT (Entry, IFCONFIG_INTERFACE_CB, Link);\r
68fb0527 617\r
7c25b7ea 618 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_BREAK), gShellNetwork1HiiHandle);\r
68fb0527 619\r
7c25b7ea 620 //\r
621 // Print interface name.\r
622 //\r
34297cef
JW
623 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_IF_NAME), gShellNetwork1HiiHandle, IfCb->IfInfo->Name); \r
624\r
625 //\r
626 // Get Media State.\r
627 //\r
628 NetLibDetectMedia (IfCb->NicHandle, &MediaPresent);\r
629 if (!MediaPresent) {\r
630 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MEDIA_STATE), gShellNetwork1HiiHandle, L"Media disconnected");\r
631 } else {\r
632 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MEDIA_STATE), gShellNetwork1HiiHandle, L"Media present");\r
633 }\r
68fb0527 634\r
7c25b7ea 635 //\r
636 // Print interface config policy.\r
637 //\r
638 if (IfCb->Policy == Ip4Config2PolicyDhcp) {\r
639 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_POLICY_DHCP), gShellNetwork1HiiHandle);\r
640 } else {\r
641 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_POLICY_MAN), gShellNetwork1HiiHandle);\r
642 }\r
68fb0527 643\r
7c25b7ea 644 //\r
645 // Print mac address of the interface.\r
646 //\r
647 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MAC_ADDR_HEAD), gShellNetwork1HiiHandle);\r
68fb0527 648\r
7c25b7ea 649 IfConfigPrintMacAddr (\r
650 IfCb->IfInfo->HwAddress.Addr,\r
651 IfCb->IfInfo->HwAddressSize\r
652 );\r
68fb0527 653\r
7c25b7ea 654 //\r
655 // Print IPv4 address list of the interface.\r
656 //\r
657 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_IP_ADDR_HEAD), gShellNetwork1HiiHandle);\r
68fb0527 658\r
7c25b7ea 659 ShellPrintHiiEx(\r
660 -1, \r
661 -1, \r
662 NULL,\r
663 STRING_TOKEN (STR_IFCONFIG_INFO_IP_ADDR_BODY), \r
664 gShellNetwork1HiiHandle,\r
665 (UINTN)IfCb->IfInfo->StationAddress.Addr[0],\r
666 (UINTN)IfCb->IfInfo->StationAddress.Addr[1],\r
667 (UINTN)IfCb->IfInfo->StationAddress.Addr[2],\r
668 (UINTN)IfCb->IfInfo->StationAddress.Addr[3]\r
669 );\r
670\r
671 //\r
672 // Print subnet mask list of the interface.\r
673 //\r
674 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_SUBNET_MASK_HEAD), gShellNetwork1HiiHandle);\r
68fb0527 675\r
68fb0527 676 ShellPrintHiiEx(\r
677 -1, \r
678 -1, \r
679 NULL,\r
7c25b7ea 680 STRING_TOKEN (STR_IFCONFIG_INFO_IP_ADDR_BODY), \r
681 gShellNetwork1HiiHandle,\r
682 (UINTN)IfCb->IfInfo->SubnetMask.Addr[0],\r
683 (UINTN)IfCb->IfInfo->SubnetMask.Addr[1],\r
684 (UINTN)IfCb->IfInfo->SubnetMask.Addr[2],\r
685 (UINTN)IfCb->IfInfo->SubnetMask.Addr[3]\r
68fb0527 686 );\r
68fb0527 687\r
7c25b7ea 688 //\r
689 // Print default gateway of the interface.\r
690 //\r
691 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_GATEWAY_HEAD), gShellNetwork1HiiHandle);\r
692\r
693 ZeroMem (&Gateway, sizeof (EFI_IPv4_ADDRESS));\r
694 \r
695 for (Index = 0; Index < IfCb->IfInfo->RouteTableSize; Index++) {\r
696 if ((CompareMem (&IfCb->IfInfo->RouteTable[Index].SubnetAddress, &mZeroIp4Addr, sizeof (EFI_IPv4_ADDRESS)) == 0) &&\r
697 (CompareMem (&IfCb->IfInfo->RouteTable[Index].SubnetMask , &mZeroIp4Addr, sizeof (EFI_IPv4_ADDRESS)) == 0) ){\r
698 CopyMem (&Gateway, &IfCb->IfInfo->RouteTable[Index].GatewayAddress, sizeof (EFI_IPv4_ADDRESS));\r
699 }\r
700 } \r
701\r
68fb0527 702 ShellPrintHiiEx(\r
7c25b7ea 703 -1, \r
704 -1, \r
705 NULL,\r
706 STRING_TOKEN (STR_IFCONFIG_INFO_IP_ADDR_BODY), \r
707 gShellNetwork1HiiHandle,\r
708 (UINTN)Gateway.Addr[0],\r
709 (UINTN)Gateway.Addr[1],\r
710 (UINTN)Gateway.Addr[2],\r
711 (UINTN)Gateway.Addr[3]\r
712 );\r
713 \r
714 //\r
715 // Print route table entry.\r
716 //\r
717 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_ROUTES_SIZE), gShellNetwork1HiiHandle, IfCb->IfInfo->RouteTableSize);\r
718\r
719 for (Index = 0; Index < IfCb->IfInfo->RouteTableSize; Index++) {\r
720 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_ROUTES_ENTRY_INDEX), gShellNetwork1HiiHandle, Index);\r
721\r
722 ShellPrintHiiEx(\r
723 -1, \r
724 -1, \r
725 NULL,\r
726 STRING_TOKEN (STR_IFCONFIG_SHOW_IP_ADDR), \r
727 gShellNetwork1HiiHandle, \r
728 L"Subnet ",\r
729 (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetAddress.Addr[0],\r
730 (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetAddress.Addr[1],\r
731 (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetAddress.Addr[2],\r
732 (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetAddress.Addr[3]\r
733 );\r
734\r
735 ShellPrintHiiEx(\r
736 -1, \r
737 -1, \r
738 NULL,\r
739 STRING_TOKEN (STR_IFCONFIG_SHOW_IP_ADDR), \r
740 gShellNetwork1HiiHandle, \r
741 L"Netmask",\r
742 (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetMask.Addr[0],\r
743 (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetMask.Addr[1],\r
744 (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetMask.Addr[2],\r
745 (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetMask.Addr[3]\r
746 );\r
747\r
748 ShellPrintHiiEx(\r
749 -1, \r
750 -1, \r
751 NULL,\r
752 STRING_TOKEN (STR_IFCONFIG_SHOW_IP_ADDR), \r
753 gShellNetwork1HiiHandle, \r
754 L"Gateway",\r
755 (UINTN)IfCb->IfInfo->RouteTable[Index].GatewayAddress.Addr[0],\r
756 (UINTN)IfCb->IfInfo->RouteTable[Index].GatewayAddress.Addr[1],\r
757 (UINTN)IfCb->IfInfo->RouteTable[Index].GatewayAddress.Addr[2],\r
758 (UINTN)IfCb->IfInfo->RouteTable[Index].GatewayAddress.Addr[3]\r
759 );\r
760 }\r
761\r
762 //\r
763 // Print dns server addresses list of the interface if has.\r
764 //\r
765 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_DNS_ADDR_HEAD), gShellNetwork1HiiHandle);\r
766\r
767 for (Index = 0; Index < IfCb->DnsCnt; Index++) {\r
768 ShellPrintHiiEx(\r
769 -1, \r
770 -1, \r
771 NULL,\r
772 STRING_TOKEN (STR_IFCONFIG_INFO_DNS_ADDR_BODY), \r
773 gShellNetwork1HiiHandle,\r
774 (UINTN) IfCb->DnsAddr[Index].Addr[0],\r
775 (UINTN) IfCb->DnsAddr[Index].Addr[1],\r
776 (UINTN) IfCb->DnsAddr[Index].Addr[2],\r
777 (UINTN) IfCb->DnsAddr[Index].Addr[3]\r
778 );\r
779\r
780 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_NEWLINE), gShellNetwork1HiiHandle);\r
781 }\r
68fb0527 782 }\r
7c25b7ea 783 \r
784 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_BREAK), gShellNetwork1HiiHandle);\r
68fb0527 785\r
6e3e562c 786 return SHELL_SUCCESS;\r
68fb0527 787}\r
788\r
789/**\r
7c25b7ea 790 The clean process of the ifconfig command to clear interface info.\r
791\r
792 @param[in] IfList The pointer of IfList(interface list).\r
68fb0527 793\r
6e3e562c 794 @retval SHELL_SUCCESS The ifconfig command clean processed successfully.\r
7c25b7ea 795 @retval others The ifconfig command clean process failed.\r
68fb0527 796\r
68fb0527 797**/\r
6e3e562c 798SHELL_STATUS\r
7c25b7ea 799IfConfigClearInterfaceInfo (\r
800 IN LIST_ENTRY *IfList\r
68fb0527 801 )\r
802{\r
6e3e562c
JW
803 EFI_STATUS Status; \r
804 SHELL_STATUS ShellStatus;\r
7c25b7ea 805 LIST_ENTRY *Entry;\r
806 LIST_ENTRY *Next;\r
807 IFCONFIG_INTERFACE_CB *IfCb;\r
808 EFI_IP4_CONFIG2_POLICY Policy;\r
68fb0527 809\r
7c25b7ea 810 Policy = Ip4Config2PolicyDhcp;\r
811 Status = EFI_SUCCESS;\r
6e3e562c 812 ShellStatus = SHELL_SUCCESS;\r
68fb0527 813\r
7c25b7ea 814 if (IsListEmpty (IfList)) {\r
815 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_INTERFACE), gShellNetwork1HiiHandle);\r
68fb0527 816 }\r
817\r
818 //\r
7c25b7ea 819 // Go through the interface list.\r
68fb0527 820 //\r
7c25b7ea 821 NET_LIST_FOR_EACH_SAFE (Entry, Next, IfList) {\r
822 IfCb = NET_LIST_USER_STRUCT (Entry, IFCONFIG_INTERFACE_CB, Link);\r
68fb0527 823 \r
7c25b7ea 824 Status = IfCb->IfCfg->SetData (\r
825 IfCb->IfCfg,\r
826 Ip4Config2DataTypePolicy,\r
827 sizeof (EFI_IP4_CONFIG2_POLICY),\r
828 &Policy\r
829 );\r
7c25b7ea 830 if (EFI_ERROR (Status)) {\r
6e3e562c 831 ShellStatus = SHELL_ACCESS_DENIED;\r
7c25b7ea 832 break;\r
833 }\r
68fb0527 834 }\r
835\r
6e3e562c 836 return ShellStatus;\r
68fb0527 837}\r
838\r
839/**\r
7c25b7ea 840 The set process of the ifconfig command.\r
68fb0527 841\r
7c25b7ea 842 @param[in] IfList The pointer of IfList(interface list).\r
843 @param[in] VarArg The pointer of ARG_LIST(Args with "-s" option).\r
68fb0527 844\r
6e3e562c 845 @retval SHELL_SUCCESS The ifconfig command set processed successfully.\r
7c25b7ea 846 @retval others The ifconfig command set process failed.\r
68fb0527 847\r
68fb0527 848**/\r
6e3e562c 849SHELL_STATUS\r
7c25b7ea 850IfConfigSetInterfaceInfo (\r
851 IN LIST_ENTRY *IfList,\r
852 IN ARG_LIST *VarArg\r
68fb0527 853 )\r
854{\r
7c25b7ea 855 EFI_STATUS Status;\r
6e3e562c 856 SHELL_STATUS ShellStatus;\r
7c25b7ea 857 IFCONFIG_INTERFACE_CB *IfCb;\r
858 VAR_CHECK_CODE CheckCode;\r
859 EFI_EVENT TimeOutEvt;\r
860 EFI_EVENT MappedEvt;\r
861 BOOLEAN IsAddressOk;\r
68fb0527 862\r
7c25b7ea 863 EFI_IP4_CONFIG2_POLICY Policy;\r
864 EFI_IP4_CONFIG2_MANUAL_ADDRESS ManualAddress;\r
865 UINTN DataSize;\r
866 EFI_IPv4_ADDRESS Gateway;\r
867 EFI_IPv4_ADDRESS *Dns;\r
868 ARG_LIST *Tmp;\r
869 UINTN Index;\r
68fb0527 870\r
7c25b7ea 871 CONST CHAR16* TempString;\r
68fb0527 872\r
7c25b7ea 873 Dns = NULL;\r
68fb0527 874\r
7c25b7ea 875 if (IsListEmpty (IfList)) {\r
876 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_INTERFACE), gShellNetwork1HiiHandle);\r
6e3e562c 877 return SHELL_INVALID_PARAMETER;\r
68fb0527 878 }\r
68fb0527 879 \r
7c25b7ea 880 //\r
881 // Make sure to set only one interface each time.\r
882 //\r
883 IfCb = NET_LIST_USER_STRUCT (IfList->ForwardLink, IFCONFIG_INTERFACE_CB, Link);\r
884 Status = EFI_SUCCESS;\r
6e3e562c 885 ShellStatus = SHELL_SUCCESS;\r
68fb0527 886\r
7c25b7ea 887 //\r
888 // Initialize check list mechanism.\r
889 //\r
890 CheckCode = IfConfigRetriveCheckListByName(\r
891 NULL,\r
892 NULL,\r
893 TRUE\r
894 );\r
68fb0527 895\r
7c25b7ea 896 //\r
897 // Create events & timers for asynchronous settings.\r
898 //\r
899 Status = gBS->CreateEvent (\r
900 EVT_TIMER,\r
901 TPL_CALLBACK,\r
902 NULL,\r
903 NULL,\r
904 &TimeOutEvt\r
905 );\r
68fb0527 906 if (EFI_ERROR (Status)) {\r
6e3e562c 907 ShellStatus = SHELL_ACCESS_DENIED;\r
7c25b7ea 908 goto ON_EXIT;\r
68fb0527 909 }\r
910\r
7c25b7ea 911 Status = gBS->CreateEvent (\r
912 EVT_NOTIFY_SIGNAL,\r
913 TPL_NOTIFY,\r
914 IfConfigManualAddressNotify,\r
915 &IsAddressOk,\r
916 &MappedEvt\r
917 );\r
918 if (EFI_ERROR (Status)) {\r
6e3e562c 919 ShellStatus = SHELL_ACCESS_DENIED;\r
7c25b7ea 920 goto ON_EXIT;\r
68fb0527 921 }\r
922\r
7c25b7ea 923 //\r
924 // Parse the setting variables.\r
925 //\r
926 while (VarArg != NULL) {\r
927 //\r
928 // Check invalid parameters (duplication & unknown & conflict).\r
929 //\r
930 CheckCode = IfConfigRetriveCheckListByName(\r
931 mSetCheckList,\r
932 VarArg->Arg,\r
933 FALSE\r
934 );\r
68fb0527 935\r
7c25b7ea 936 if (VarCheckOk != CheckCode) {\r
937 switch (CheckCode) {\r
938 case VarCheckDuplicate:\r
939 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_DUPLICATE_COMMAND), gShellNetwork1HiiHandle, VarArg->Arg);\r
940 break;\r
68fb0527 941\r
7c25b7ea 942 case VarCheckConflict:\r
943 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_CONFLICT_COMMAND), gShellNetwork1HiiHandle, VarArg->Arg);\r
944 break;\r
68fb0527 945\r
7c25b7ea 946 case VarCheckUnknown:\r
947 //\r
948 // To handle unsupported option.\r
949 //\r
950 TempString = PermanentString;\r
951 if (StringNoCaseCompare(&VarArg->Arg, &TempString) == 0) {\r
952 ShellPrintHiiEx(-1, -1, NULL,STRING_TOKEN (STR_IFCONFIG_UNSUPPORTED_OPTION), gShellNetwork1HiiHandle, PermanentString);\r
953 goto ON_EXIT;\r
954 }\r
68fb0527 955\r
7c25b7ea 956 //\r
957 // To handle unknown option.\r
958 //\r
959 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_UNKNOWN_COMMAND), gShellNetwork1HiiHandle, VarArg->Arg);\r
960 break;\r
68fb0527 961\r
7c25b7ea 962 default:\r
963 break;\r
964 }\r
68fb0527 965\r
7c25b7ea 966 VarArg = VarArg->Next;\r
967 continue; \r
968 }\r
68fb0527 969\r
68fb0527 970 //\r
7c25b7ea 971 // Process valid variables.\r
68fb0527 972 //\r
7c25b7ea 973 if (StrCmp(VarArg->Arg, L"dhcp") == 0) {\r
d6cf1af9
JW
974 if (IfCb->Policy == Ip4Config2PolicyDhcp) {\r
975 Status = IfConfigStartIp4 (IfCb->NicHandle, gImageHandle);\r
976 if (EFI_ERROR(Status)) {\r
6e3e562c 977 ShellStatus = SHELL_ACCESS_DENIED;\r
d6cf1af9
JW
978 goto ON_EXIT;\r
979 }\r
980 } else {\r
981 //\r
982 // Set dhcp config policy\r
983 //\r
984 Policy = Ip4Config2PolicyDhcp;\r
985 Status = IfCb->IfCfg->SetData (\r
986 IfCb->IfCfg,\r
987 Ip4Config2DataTypePolicy,\r
988 sizeof (EFI_IP4_CONFIG2_POLICY),\r
989 &Policy\r
990 );\r
991 if (EFI_ERROR(Status)) {\r
6e3e562c 992 ShellStatus = SHELL_ACCESS_DENIED;\r
d6cf1af9
JW
993 goto ON_EXIT;\r
994 }\r
7c25b7ea 995 }\r
d6cf1af9 996 \r
7c25b7ea 997 VarArg= VarArg->Next; \r
68fb0527 998\r
7c25b7ea 999 } else if (StrCmp (VarArg->Arg, L"static") == 0) {\r
1000 //\r
1001 // Set manual config policy.\r
1002 //\r
1003 Policy = Ip4Config2PolicyStatic;\r
1004 Status = IfCb->IfCfg->SetData (\r
1005 IfCb->IfCfg,\r
1006 Ip4Config2DataTypePolicy,\r
1007 sizeof (EFI_IP4_CONFIG2_POLICY),\r
1008 &Policy\r
1009 );\r
7c25b7ea 1010 if (EFI_ERROR(Status)) {\r
6e3e562c 1011 ShellStatus = SHELL_ACCESS_DENIED;\r
68fb0527 1012 goto ON_EXIT;\r
1013 }\r
1014\r
7c25b7ea 1015 VarArg= VarArg->Next; \r
68fb0527 1016\r
7c25b7ea 1017 ZeroMem (&ManualAddress, sizeof (ManualAddress));\r
1018 \r
1019 //\r
1020 // Get manual IP address.\r
1021 //\r
1022 Status = NetLibStrToIp4 (VarArg->Arg, &ManualAddress.Address);\r
1023 if (EFI_ERROR(Status)) {\r
6e3e562c 1024 ShellStatus = SHELL_INVALID_PARAMETER;\r
7c25b7ea 1025 goto ON_EXIT;\r
1026 }\r
68fb0527 1027\r
7c25b7ea 1028 //\r
1029 // Get subnetmask.\r
1030 // \r
1031 VarArg = VarArg->Next;\r
1032 Status = NetLibStrToIp4 (VarArg->Arg, &ManualAddress.SubnetMask);\r
1033 if (EFI_ERROR(Status)) {\r
6e3e562c 1034 ShellStatus = SHELL_INVALID_PARAMETER;\r
7c25b7ea 1035 goto ON_EXIT;\r
1036 }\r
68fb0527 1037\r
7c25b7ea 1038 //\r
1039 // Get gateway.\r
1040 //\r
1041 VarArg = VarArg->Next;\r
1042 Status = NetLibStrToIp4 (VarArg->Arg, &Gateway);\r
1043 if (EFI_ERROR(Status)) {\r
6e3e562c 1044 ShellStatus = SHELL_INVALID_PARAMETER;\r
7c25b7ea 1045 goto ON_EXIT;\r
1046 }\r
1047 \r
1048 IsAddressOk = FALSE;\r
1049\r
1050 Status = IfCb->IfCfg->RegisterDataNotify (\r
1051 IfCb->IfCfg,\r
1052 Ip4Config2DataTypeManualAddress,\r
1053 MappedEvt\r
1054 );\r
1055 if (EFI_ERROR (Status)) {\r
6e3e562c 1056 ShellStatus = SHELL_ACCESS_DENIED;\r
7c25b7ea 1057 goto ON_EXIT;\r
1058 }\r
68fb0527 1059\r
7c25b7ea 1060 DataSize = sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS);\r
68fb0527 1061\r
7c25b7ea 1062 Status = IfCb->IfCfg->SetData (\r
1063 IfCb->IfCfg,\r
1064 Ip4Config2DataTypeManualAddress,\r
1065 DataSize,\r
1066 &ManualAddress\r
1067 );\r
68fb0527 1068\r
7c25b7ea 1069 if (Status == EFI_NOT_READY) {\r
1070 gBS->SetTimer (TimeOutEvt, TimerRelative, 50000000);\r
68fb0527 1071\r
7c25b7ea 1072 while (EFI_ERROR (gBS->CheckEvent (TimeOutEvt))) {\r
1073 if (IsAddressOk) {\r
1074 Status = EFI_SUCCESS;\r
1075 break;\r
1076 }\r
1077 }\r
1078 }\r
68fb0527 1079\r
7c25b7ea 1080 IfCb->IfCfg->UnregisterDataNotify (\r
1081 IfCb->IfCfg,\r
1082 Ip4Config2DataTypeManualAddress,\r
1083 MappedEvt\r
1084 );\r
6e3e562c 1085 \r
7c25b7ea 1086 if (EFI_ERROR (Status)) {\r
1087 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_SET_ADDR_FAILED), gShellNetwork1HiiHandle, Status);\r
6e3e562c 1088 ShellStatus = SHELL_ACCESS_DENIED;\r
68fb0527 1089 goto ON_EXIT;\r
1090 }\r
1091\r
7c25b7ea 1092 //\r
1093 // Set gateway.\r
1094 //\r
1095 DataSize = sizeof (EFI_IPv4_ADDRESS);\r
1096\r
1097 Status = IfCb->IfCfg->SetData (\r
1098 IfCb->IfCfg,\r
1099 Ip4Config2DataTypeGateway,\r
1100 DataSize,\r
1101 &Gateway\r
1102 );\r
6e3e562c
JW
1103 if (EFI_ERROR (Status)) {\r
1104 ShellStatus = SHELL_ACCESS_DENIED;\r
1105 goto ON_EXIT;\r
1106 }\r
1107 \r
7c25b7ea 1108 VarArg = VarArg->Next;\r
1109 \r
1110 } else if (StrCmp (VarArg->Arg, L"dns") == 0) {\r
1111 //\r
1112 // Get DNS addresses.\r
1113 //\r
1114 VarArg = VarArg->Next;\r
1115 Tmp = VarArg;\r
1116 Index = 0;\r
1117 while (Tmp != NULL) {\r
1118 Index ++;\r
1119 Tmp = Tmp->Next;\r
1120 }\r
68fb0527 1121\r
7c25b7ea 1122 Dns = AllocatePool (Index * sizeof (EFI_IPv4_ADDRESS));\r
1123 ASSERT(Dns != NULL);\r
1124 Tmp = VarArg;\r
1125 Index = 0;\r
1126 while (Tmp != NULL) {\r
1127 Status = NetLibStrToIp4 (Tmp->Arg, Dns + Index);\r
1128 if (EFI_ERROR(Status)) {\r
6e3e562c 1129 ShellStatus = SHELL_INVALID_PARAMETER;\r
7c25b7ea 1130 goto ON_EXIT;\r
1131 }\r
1132 Index ++;\r
1133 Tmp = Tmp->Next;\r
1134 }\r
1135 \r
1136 VarArg = Tmp;\r
68fb0527 1137\r
7c25b7ea 1138 //\r
1139 // Set DNS addresses.\r
1140 //\r
1141 DataSize = Index * sizeof (EFI_IPv4_ADDRESS);\r
1142\r
1143 Status = IfCb->IfCfg->SetData (\r
1144 IfCb->IfCfg,\r
1145 Ip4Config2DataTypeDnsServer,\r
1146 DataSize,\r
1147 Dns\r
1148 );\r
6e3e562c
JW
1149 if (EFI_ERROR (Status)) {\r
1150 ShellStatus = SHELL_ACCESS_DENIED;\r
1151 goto ON_EXIT;\r
1152 }\r
68fb0527 1153 }\r
7c25b7ea 1154 }\r
68fb0527 1155\r
7c25b7ea 1156ON_EXIT:\r
1157 if (Dns != NULL) {\r
1158 FreePool (Dns);\r
1159 }\r
1160 \r
6e3e562c 1161 return ShellStatus;\r
68fb0527 1162\r
7c25b7ea 1163}\r
68fb0527 1164\r
7c25b7ea 1165/**\r
1166 The ifconfig command main process.\r
68fb0527 1167\r
7c25b7ea 1168 @param[in] Private The pointer of IFCONFIG_PRIVATE_DATA.\r
68fb0527 1169\r
6e3e562c 1170 @retval SHELL_SUCCESS ifconfig command processed successfully.\r
7c25b7ea 1171 @retval others The ifconfig command process failed.\r
68fb0527 1172\r
7c25b7ea 1173**/\r
6e3e562c 1174SHELL_STATUS\r
7c25b7ea 1175IfConfig (\r
1176 IN IFCONFIG_PRIVATE_DATA *Private\r
1177 )\r
1178{\r
1179 EFI_STATUS Status;\r
6e3e562c
JW
1180 SHELL_STATUS ShellStatus;\r
1181\r
1182 ShellStatus = SHELL_SUCCESS;\r
68fb0527 1183\r
1184 //\r
7c25b7ea 1185 // Get configure information of all interfaces.\r
68fb0527 1186 //\r
7c25b7ea 1187 Status = IfConfigGetInterfaceInfo (\r
1188 Private->IfName,\r
1189 &Private->IfList\r
1190 );\r
7c25b7ea 1191 if (EFI_ERROR (Status)) {\r
6e3e562c 1192 ShellStatus = SHELL_NOT_FOUND; \r
7c25b7ea 1193 goto ON_EXIT;\r
68fb0527 1194 }\r
1195\r
7c25b7ea 1196 switch (Private->OpCode) {\r
1197 case IfConfigOpList:\r
6e3e562c 1198 ShellStatus = IfConfigShowInterfaceInfo (&Private->IfList);\r
7c25b7ea 1199 break;\r
1200\r
1201 case IfConfigOpClear:\r
6e3e562c 1202 ShellStatus = IfConfigClearInterfaceInfo (&Private->IfList);\r
7c25b7ea 1203 break;\r
1204\r
1205 case IfConfigOpSet:\r
6e3e562c 1206 ShellStatus = IfConfigSetInterfaceInfo (&Private->IfList, Private->VarArg);\r
7c25b7ea 1207 break;\r
1208\r
1209 default:\r
6e3e562c 1210 ShellStatus = SHELL_UNSUPPORTED;\r
68fb0527 1211 }\r
7c25b7ea 1212\r
68fb0527 1213ON_EXIT:\r
6e3e562c 1214 return ShellStatus;\r
68fb0527 1215}\r
1216\r
1217/**\r
7c25b7ea 1218 The ifconfig command cleanup process, free the allocated memory.\r
1219\r
1220 @param[in] Private The pointer of IFCONFIG_PRIVATE_DATA.\r
68fb0527 1221\r
68fb0527 1222**/\r
1223VOID\r
7c25b7ea 1224IfConfigCleanup (\r
1225 IN IFCONFIG_PRIVATE_DATA *Private\r
68fb0527 1226 )\r
1227{\r
1228 LIST_ENTRY *Entry;\r
1229 LIST_ENTRY *NextEntry;\r
7c25b7ea 1230 IFCONFIG_INTERFACE_CB *IfCb;\r
1231 ARG_LIST *ArgNode;\r
1232 ARG_LIST *ArgHead;\r
68fb0527 1233\r
7c25b7ea 1234 ASSERT (Private != NULL);\r
68fb0527 1235\r
7c25b7ea 1236 //\r
1237 // Clean the list which save the set config Args.\r
1238 //\r
1239 if (Private->VarArg != NULL) {\r
1240 ArgHead = Private->VarArg;\r
68fb0527 1241\r
7c25b7ea 1242 while (ArgHead->Next != NULL) {\r
1243 ArgNode = ArgHead->Next;\r
1244 FreePool (ArgHead);\r
1245 ArgHead = ArgNode;\r
68fb0527 1246 }\r
1247\r
7c25b7ea 1248 FreePool (ArgHead);\r
68fb0527 1249 }\r
1250\r
7c25b7ea 1251 if (Private->IfName != NULL) {\r
1252 FreePool (Private->IfName);\r
1253 }\r
68fb0527 1254\r
7c25b7ea 1255 //\r
1256 // Clean the IFCONFIG_INTERFACE_CB list.\r
1257 //\r
1258 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->IfList) {\r
1259 IfCb = NET_LIST_USER_STRUCT (Entry, IFCONFIG_INTERFACE_CB, Link);\r
68fb0527 1260\r
7c25b7ea 1261 RemoveEntryList (&IfCb->Link);\r
68fb0527 1262\r
7c25b7ea 1263 if (IfCb->IfInfo != NULL) {\r
68fb0527 1264\r
7c25b7ea 1265 FreePool (IfCb->IfInfo);\r
68fb0527 1266 }\r
1267\r
7c25b7ea 1268 FreePool (IfCb);\r
68fb0527 1269 }\r
1270\r
7c25b7ea 1271 FreePool (Private);\r
68fb0527 1272}\r
1273\r
1274/**\r
1275 Function for 'ifconfig' command.\r
1276\r
1277 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
1278 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
7c25b7ea 1279\r
1280 @retval EFI_SUCCESS ifconfig command processed successfully.\r
1281 @retval others The ifconfig command process failed.\r
1282 \r
68fb0527 1283**/\r
1284SHELL_STATUS\r
1285EFIAPI\r
1286ShellCommandRunIfconfig (\r
1287 IN EFI_HANDLE ImageHandle,\r
1288 IN EFI_SYSTEM_TABLE *SystemTable\r
1289 )\r
1290{\r
7c25b7ea 1291 EFI_STATUS Status;\r
1292 IFCONFIG_PRIVATE_DATA *Private;\r
1293 LIST_ENTRY *ParamPackage;\r
6e3e562c 1294 SHELL_STATUS ShellStatus;\r
7c25b7ea 1295 CONST CHAR16 *ValueStr;\r
1296 ARG_LIST *ArgList;\r
1297 CHAR16 *ProblemParam;\r
1298 CHAR16 *Str;\r
6e3e562c
JW
1299 \r
1300 Status = EFI_INVALID_PARAMETER;\r
7c25b7ea 1301 Private = NULL;\r
6e3e562c 1302 ShellStatus = SHELL_SUCCESS;\r
7c25b7ea 1303\r
1304 Status = ShellCommandLineParseEx (mIfConfigCheckList, &ParamPackage, &ProblemParam, TRUE, FALSE);\r
1305 if (EFI_ERROR (Status)) {\r
6e3e562c
JW
1306 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
1307 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellNetwork1HiiHandle, L"ifconfig", ProblemParam);\r
1308 FreePool(ProblemParam);\r
1309 ShellStatus = SHELL_INVALID_PARAMETER;\r
1310 } else {\r
1311 ASSERT(FALSE);\r
1312 }\r
1313 \r
7c25b7ea 1314 goto ON_EXIT;\r
1315 }\r
68fb0527 1316\r
1317 //\r
7c25b7ea 1318 // To handle unsupported option.\r
68fb0527 1319 //\r
7c25b7ea 1320 if (ShellCommandLineGetFlag (ParamPackage, L"-c")) {\r
1321 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_UNSUPPORTED_OPTION), gShellNetwork1HiiHandle,L"-c");\r
6e3e562c 1322 ShellStatus = SHELL_INVALID_PARAMETER;\r
7c25b7ea 1323 goto ON_EXIT;\r
1324 }\r
68fb0527 1325\r
1326 //\r
7c25b7ea 1327 // To handle no option.\r
68fb0527 1328 //\r
7c25b7ea 1329 if (!ShellCommandLineGetFlag (ParamPackage, L"-r") && !ShellCommandLineGetFlag (ParamPackage, L"-s") &&\r
1330 !ShellCommandLineGetFlag (ParamPackage, L"-l")) {\r
1331 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_LACK_OPTION), gShellNetwork1HiiHandle);\r
6e3e562c 1332 ShellStatus = SHELL_INVALID_PARAMETER;\r
7c25b7ea 1333 goto ON_EXIT;\r
68fb0527 1334 }\r
1335\r
7c25b7ea 1336 //\r
1337 // To handle conflict options.\r
1338 //\r
1339 if (((ShellCommandLineGetFlag (ParamPackage, L"-r")) && (ShellCommandLineGetFlag (ParamPackage, L"-s"))) ||\r
1340 ((ShellCommandLineGetFlag (ParamPackage, L"-r")) && (ShellCommandLineGetFlag (ParamPackage, L"-l"))) ||\r
1341 ((ShellCommandLineGetFlag (ParamPackage, L"-s")) && (ShellCommandLineGetFlag (ParamPackage, L"-l")))) {\r
1342 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellNetwork1HiiHandle, L"ifconfig");\r
6e3e562c 1343 ShellStatus = SHELL_INVALID_PARAMETER;\r
7c25b7ea 1344 goto ON_EXIT;\r
68fb0527 1345 }\r
68fb0527 1346\r
7c25b7ea 1347 Private = AllocateZeroPool (sizeof (IFCONFIG_PRIVATE_DATA));\r
7c25b7ea 1348 if (Private == NULL) {\r
6e3e562c 1349 ShellStatus = SHELL_OUT_OF_RESOURCES;\r
7c25b7ea 1350 goto ON_EXIT;\r
68fb0527 1351 }\r
1352\r
7c25b7ea 1353 InitializeListHead (&Private->IfList);\r
68fb0527 1354\r
7c25b7ea 1355 //\r
1356 // To get interface name for the list option.\r
1357 //\r
1358 if (ShellCommandLineGetFlag (ParamPackage, L"-l")) {\r
1359 Private->OpCode = IfConfigOpList;\r
1360 ValueStr = ShellCommandLineGetValue (ParamPackage, L"-l");\r
1361 if (ValueStr != NULL) {\r
1362 Str = AllocateCopyPool (StrSize (ValueStr), ValueStr);\r
1363 ASSERT (Str != NULL);\r
1364 Private->IfName = Str;\r
1365 }\r
1366 }\r
1367 \r
1368 //\r
1369 // To get interface name for the clear option.\r
1370 //\r
1371 if (ShellCommandLineGetFlag (ParamPackage, L"-r")) {\r
1372 Private->OpCode = IfConfigOpClear;\r
1373 ValueStr = ShellCommandLineGetValue (ParamPackage, L"-r");\r
1374 if (ValueStr != NULL) {\r
1375 Str = AllocateCopyPool (StrSize (ValueStr), ValueStr);\r
1376 ASSERT (Str != NULL);\r
1377 Private->IfName = Str;\r
1378 }\r
1379 }\r
1380 \r
1381 //\r
1382 // To get interface name and corresponding Args for the set option.\r
1383 //\r
1384 if (ShellCommandLineGetFlag (ParamPackage, L"-s")) {\r
1385 ValueStr = ShellCommandLineGetValue (ParamPackage, L"-s");\r
1386 if (ValueStr == NULL) {\r
1387 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_LACK_INTERFACE), gShellNetwork1HiiHandle);\r
6e3e562c 1388 ShellStatus = SHELL_INVALID_PARAMETER;\r
7c25b7ea 1389 goto ON_EXIT;\r
1390 }\r
68fb0527 1391 \r
1392 //\r
7c25b7ea 1393 // To split the configuration into multi-section.\r
68fb0527 1394 //\r
7c25b7ea 1395 ArgList = SplitStrToList (ValueStr, L' ');\r
1396 ASSERT (ArgList != NULL);\r
68fb0527 1397\r
7c25b7ea 1398 Private->OpCode = IfConfigOpSet;\r
1399 Private->IfName = ArgList->Arg;\r
68fb0527 1400\r
7c25b7ea 1401 Private->VarArg = ArgList->Next;\r
68fb0527 1402\r
7c25b7ea 1403 if (Private->IfName == NULL || Private->VarArg == NULL) {\r
1404 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_LACK_COMMAND), gShellNetwork1HiiHandle);\r
6e3e562c 1405 ShellStatus = SHELL_INVALID_PARAMETER;\r
7c25b7ea 1406 goto ON_EXIT;\r
68fb0527 1407 }\r
68fb0527 1408 }\r
7c25b7ea 1409 \r
1410 //\r
1411 // Main process of ifconfig.\r
1412 //\r
6e3e562c 1413 ShellStatus = IfConfig (Private);\r
68fb0527 1414\r
7c25b7ea 1415ON_EXIT:\r
68fb0527 1416\r
7c25b7ea 1417 ShellCommandLineFreeVarList (ParamPackage);\r
1418 \r
1419 if (Private != NULL) {\r
1420 IfConfigCleanup (Private);\r
68fb0527 1421 }\r
1422\r
6e3e562c 1423 return ShellStatus;\r
68fb0527 1424}\r