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