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