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