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