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