| /** @file | |
| The implementation for Shell command ifconfig based on IP4Config2 protocol. | |
| (C) Copyright 2013-2015 Hewlett-Packard Development Company, L.P.<BR> | |
| Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| **/ | |
| #include "UefiShellNetwork1CommandsLib.h" | |
| typedef enum { | |
| IfConfigOpList = 1, | |
| IfConfigOpSet = 2, | |
| IfConfigOpClear = 3 | |
| } IFCONFIG_OPCODE; | |
| typedef enum { | |
| VarCheckReserved = -1, | |
| VarCheckOk = 0, | |
| VarCheckDuplicate, | |
| VarCheckConflict, | |
| VarCheckUnknown, | |
| VarCheckLackValue, | |
| VarCheckOutOfMem | |
| } VAR_CHECK_CODE; | |
| typedef enum { | |
| FlagTypeSingle = 0, | |
| FlagTypeNeedVar, | |
| FlagTypeNeedSet, | |
| FlagTypeSkipUnknown | |
| } VAR_CHECK_FLAG_TYPE; | |
| #define MACADDRMAXSIZE 32 | |
| typedef struct _IFCONFIG_INTERFACE_CB { | |
| EFI_HANDLE NicHandle; | |
| LIST_ENTRY Link; | |
| EFI_IP4_CONFIG2_PROTOCOL *IfCfg; | |
| EFI_IP4_CONFIG2_INTERFACE_INFO *IfInfo; | |
| EFI_IP4_CONFIG2_POLICY Policy; | |
| UINT32 DnsCnt; | |
| EFI_IPv4_ADDRESS DnsAddr[1]; | |
| } IFCONFIG_INTERFACE_CB; | |
| typedef struct _ARG_LIST ARG_LIST; | |
| struct _ARG_LIST { | |
| ARG_LIST *Next; | |
| CHAR16 *Arg; | |
| }; | |
| typedef struct _IFCONFIG4_PRIVATE_DATA { | |
| LIST_ENTRY IfList; | |
| UINT32 OpCode; | |
| CHAR16 *IfName; | |
| ARG_LIST *VarArg; | |
| } IFCONFIG_PRIVATE_DATA; | |
| typedef struct _VAR_CHECK_ITEM { | |
| CHAR16 *FlagStr; | |
| UINT32 FlagID; | |
| UINT32 ConflictMask; | |
| VAR_CHECK_FLAG_TYPE FlagType; | |
| } VAR_CHECK_ITEM; | |
| SHELL_PARAM_ITEM mIfConfigCheckList[] = { | |
| { | |
| L"-b", | |
| TypeFlag | |
| }, | |
| { | |
| L"-l", | |
| TypeValue | |
| }, | |
| { | |
| L"-r", | |
| TypeValue | |
| }, | |
| { | |
| L"-c", | |
| TypeValue | |
| }, | |
| { | |
| L"-s", | |
| TypeMaxValue | |
| }, | |
| { | |
| NULL, | |
| TypeMax | |
| }, | |
| }; | |
| VAR_CHECK_ITEM mSetCheckList[] = { | |
| { | |
| L"static", | |
| 0x00000001, | |
| 0x00000001, | |
| FlagTypeSingle | |
| }, | |
| { | |
| L"dhcp", | |
| 0x00000002, | |
| 0x00000001, | |
| FlagTypeSingle | |
| }, | |
| { | |
| L"dns", | |
| 0x00000008, | |
| 0x00000004, | |
| FlagTypeSingle | |
| }, | |
| { | |
| NULL, | |
| 0x0, | |
| 0x0, | |
| FlagTypeSkipUnknown | |
| }, | |
| }; | |
| STATIC CONST CHAR16 PermanentString[10] = L"PERMANENT"; | |
| /** | |
| Free the ARG_LIST. | |
| @param List Pointer to ARG_LIST to free. | |
| **/ | |
| VOID | |
| FreeArgList ( | |
| ARG_LIST *List | |
| ) | |
| { | |
| ARG_LIST *Next; | |
| while (List->Next != NULL) { | |
| Next = List->Next; | |
| FreePool (List); | |
| List = Next; | |
| } | |
| FreePool (List); | |
| } | |
| /** | |
| Split a string with specified separator and save the substring to a list. | |
| @param[in] String The pointer of the input string. | |
| @param[in] Separator The specified separator. | |
| @return The pointer of headnode of ARG_LIST. | |
| **/ | |
| ARG_LIST * | |
| SplitStrToList ( | |
| IN CONST CHAR16 *String, | |
| IN CHAR16 Separator | |
| ) | |
| { | |
| CHAR16 *Str; | |
| CHAR16 *ArgStr; | |
| ARG_LIST *ArgList; | |
| ARG_LIST *ArgNode; | |
| if (*String == L'\0') { | |
| return NULL; | |
| } | |
| // | |
| // Copy the CONST string to a local copy. | |
| // | |
| Str = AllocateCopyPool (StrSize (String), String); | |
| if (Str == NULL) { | |
| return NULL; | |
| } | |
| ArgStr = Str; | |
| // | |
| // init a node for the list head. | |
| // | |
| ArgNode = (ARG_LIST *)AllocateZeroPool (sizeof (ARG_LIST)); | |
| if (ArgNode == NULL) { | |
| return NULL; | |
| } | |
| ArgList = ArgNode; | |
| // | |
| // Split the local copy and save in the list node. | |
| // | |
| while (*Str != L'\0') { | |
| if (*Str == Separator) { | |
| *Str = L'\0'; | |
| ArgNode->Arg = ArgStr; | |
| ArgStr = Str + 1; | |
| ArgNode->Next = (ARG_LIST *)AllocateZeroPool (sizeof (ARG_LIST)); | |
| if (ArgNode->Next == NULL) { | |
| // | |
| // Free the local copy of string stored in the first node | |
| // | |
| FreePool (ArgList->Arg); | |
| FreeArgList (ArgList); | |
| return NULL; | |
| } | |
| ArgNode = ArgNode->Next; | |
| } | |
| Str++; | |
| } | |
| ArgNode->Arg = ArgStr; | |
| ArgNode->Next = NULL; | |
| return ArgList; | |
| } | |
| /** | |
| Check the correctness of input Args with '-s' option. | |
| @param[in] CheckList The pointer of VAR_CHECK_ITEM array. | |
| @param[in] Name The pointer of input arg. | |
| @param[in] Init The switch to execute the check. | |
| @return VarCheckOk Valid parameter or Initialize check successfully. | |
| @return VarCheckDuplicate Duplicated parameter happened. | |
| @return VarCheckConflict Conflicted parameter happened | |
| @return VarCheckUnknown Unknown parameter. | |
| **/ | |
| VAR_CHECK_CODE | |
| IfConfigRetriveCheckListByName ( | |
| IN VAR_CHECK_ITEM *CheckList, | |
| IN CHAR16 *Name, | |
| IN BOOLEAN Init | |
| ) | |
| { | |
| STATIC UINT32 CheckDuplicate; | |
| STATIC UINT32 CheckConflict; | |
| VAR_CHECK_CODE RtCode; | |
| UINT32 Index; | |
| VAR_CHECK_ITEM Arg; | |
| if (Init) { | |
| CheckDuplicate = 0; | |
| CheckConflict = 0; | |
| return VarCheckOk; | |
| } | |
| RtCode = VarCheckOk; | |
| Index = 0; | |
| Arg = CheckList[Index]; | |
| // | |
| // Check the Duplicated/Conflicted/Unknown input Args. | |
| // | |
| while (Arg.FlagStr != NULL) { | |
| if (StrCmp (Arg.FlagStr, Name) == 0) { | |
| if (CheckDuplicate & Arg.FlagID) { | |
| RtCode = VarCheckDuplicate; | |
| break; | |
| } | |
| if (CheckConflict & Arg.ConflictMask) { | |
| RtCode = VarCheckConflict; | |
| break; | |
| } | |
| CheckDuplicate |= Arg.FlagID; | |
| CheckConflict |= Arg.ConflictMask; | |
| break; | |
| } | |
| Arg = CheckList[++Index]; | |
| } | |
| if (Arg.FlagStr == NULL) { | |
| RtCode = VarCheckUnknown; | |
| } | |
| return RtCode; | |
| } | |
| /** | |
| The notify function of create event when performing a manual config. | |
| @param[in] Event The event this notify function registered to. | |
| @param[in] Context Pointer to the context data registered to the event. | |
| **/ | |
| VOID | |
| EFIAPI | |
| IfConfigManualAddressNotify ( | |
| IN EFI_EVENT Event, | |
| IN VOID *Context | |
| ) | |
| { | |
| *((BOOLEAN *)Context) = TRUE; | |
| } | |
| /** | |
| Print MAC address. | |
| @param[in] Node The pointer of MAC address buffer. | |
| @param[in] Size The size of MAC address buffer. | |
| **/ | |
| VOID | |
| IfConfigPrintMacAddr ( | |
| IN UINT8 *Node, | |
| IN UINT32 Size | |
| ) | |
| { | |
| UINTN Index; | |
| ASSERT (Size <= MACADDRMAXSIZE); | |
| for (Index = 0; Index < Size; Index++) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MAC_ADDR_BODY), gShellNetwork1HiiHandle, Node[Index]); | |
| if (Index + 1 < Size) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_COLON), gShellNetwork1HiiHandle); | |
| } | |
| } | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_NEWLINE), gShellNetwork1HiiHandle); | |
| } | |
| /** | |
| The get current status of all handles. | |
| @param[in] IfName The pointer of IfName(interface name). | |
| @param[in] IfList The pointer of IfList(interface list). | |
| @retval EFI_SUCCESS The get status processed successfully. | |
| @retval others The get status process failed. | |
| **/ | |
| EFI_STATUS | |
| IfConfigGetInterfaceInfo ( | |
| IN CHAR16 *IfName, | |
| IN LIST_ENTRY *IfList | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| UINTN HandleIndex; | |
| UINTN HandleNum; | |
| EFI_HANDLE *HandleBuffer; | |
| EFI_IP4_CONFIG2_PROTOCOL *Ip4Cfg2; | |
| EFI_IP4_CONFIG2_INTERFACE_INFO *IfInfo; | |
| IFCONFIG_INTERFACE_CB *IfCb; | |
| UINTN DataSize; | |
| HandleBuffer = NULL; | |
| HandleNum = 0; | |
| IfInfo = NULL; | |
| IfCb = NULL; | |
| // | |
| // Locate all the handles with ip4 service binding protocol. | |
| // | |
| Status = gBS->LocateHandleBuffer ( | |
| ByProtocol, | |
| &gEfiIp4ServiceBindingProtocolGuid, | |
| NULL, | |
| &HandleNum, | |
| &HandleBuffer | |
| ); | |
| if (EFI_ERROR (Status) || (HandleNum == 0)) { | |
| return Status; | |
| } | |
| // | |
| // Enumerate all handles that installed with ip4 service binding protocol. | |
| // | |
| for (HandleIndex = 0; HandleIndex < HandleNum; HandleIndex++) { | |
| IfCb = NULL; | |
| IfInfo = NULL; | |
| DataSize = 0; | |
| // | |
| // Ip4config protocol and ip4 service binding protocol are installed | |
| // on the same handle. | |
| // | |
| ASSERT (HandleBuffer != NULL); | |
| Status = gBS->HandleProtocol ( | |
| HandleBuffer[HandleIndex], | |
| &gEfiIp4Config2ProtocolGuid, | |
| (VOID **)&Ip4Cfg2 | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| goto ON_ERROR; | |
| } | |
| // | |
| // Get the interface information size. | |
| // | |
| Status = Ip4Cfg2->GetData ( | |
| Ip4Cfg2, | |
| Ip4Config2DataTypeInterfaceInfo, | |
| &DataSize, | |
| NULL | |
| ); | |
| if (Status != EFI_BUFFER_TOO_SMALL) { | |
| goto ON_ERROR; | |
| } | |
| IfInfo = AllocateZeroPool (DataSize); | |
| if (IfInfo == NULL) { | |
| Status = EFI_OUT_OF_RESOURCES; | |
| goto ON_ERROR; | |
| } | |
| // | |
| // Get the interface info. | |
| // | |
| Status = Ip4Cfg2->GetData ( | |
| Ip4Cfg2, | |
| Ip4Config2DataTypeInterfaceInfo, | |
| &DataSize, | |
| IfInfo | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| goto ON_ERROR; | |
| } | |
| // | |
| // Check the interface name if required. | |
| // | |
| if ((IfName != NULL) && (StrCmp (IfName, IfInfo->Name) != 0)) { | |
| FreePool (IfInfo); | |
| continue; | |
| } | |
| DataSize = 0; | |
| // | |
| // Get the size of dns server list. | |
| // | |
| Status = Ip4Cfg2->GetData ( | |
| Ip4Cfg2, | |
| Ip4Config2DataTypeDnsServer, | |
| &DataSize, | |
| NULL | |
| ); | |
| if ((Status != EFI_BUFFER_TOO_SMALL) && (Status != EFI_NOT_FOUND)) { | |
| goto ON_ERROR; | |
| } | |
| IfCb = AllocateZeroPool (sizeof (IFCONFIG_INTERFACE_CB) + DataSize); | |
| if (IfCb == NULL) { | |
| Status = EFI_OUT_OF_RESOURCES; | |
| goto ON_ERROR; | |
| } | |
| IfCb->NicHandle = HandleBuffer[HandleIndex]; | |
| IfCb->IfInfo = IfInfo; | |
| IfCb->IfCfg = Ip4Cfg2; | |
| IfCb->DnsCnt = (UINT32)(DataSize / sizeof (EFI_IPv4_ADDRESS)); | |
| // | |
| // Get the dns server list if has. | |
| // | |
| if (DataSize > 0) { | |
| Status = Ip4Cfg2->GetData ( | |
| Ip4Cfg2, | |
| Ip4Config2DataTypeDnsServer, | |
| &DataSize, | |
| IfCb->DnsAddr | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| goto ON_ERROR; | |
| } | |
| } | |
| // | |
| // Get the config policy. | |
| // | |
| DataSize = sizeof (EFI_IP4_CONFIG2_POLICY); | |
| Status = Ip4Cfg2->GetData ( | |
| Ip4Cfg2, | |
| Ip4Config2DataTypePolicy, | |
| &DataSize, | |
| &IfCb->Policy | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| goto ON_ERROR; | |
| } | |
| InsertTailList (IfList, &IfCb->Link); | |
| if ((IfName != NULL) && (StrCmp (IfName, IfInfo->Name) == 0)) { | |
| // | |
| // Only need the appointed interface, keep the allocated buffer. | |
| // | |
| IfCb = NULL; | |
| IfInfo = NULL; | |
| break; | |
| } | |
| } | |
| if (HandleBuffer != NULL) { | |
| FreePool (HandleBuffer); | |
| } | |
| return EFI_SUCCESS; | |
| ON_ERROR: | |
| if (IfInfo != NULL) { | |
| FreePool (IfInfo); | |
| } | |
| if (IfCb != NULL) { | |
| FreePool (IfCb); | |
| } | |
| return Status; | |
| } | |
| /** | |
| The list process of the ifconfig command. | |
| @param[in] IfList The pointer of IfList(interface list). | |
| @retval SHELL_SUCCESS The ifconfig command list processed successfully. | |
| @retval others The ifconfig command list process failed. | |
| **/ | |
| SHELL_STATUS | |
| IfConfigShowInterfaceInfo ( | |
| IN LIST_ENTRY *IfList | |
| ) | |
| { | |
| LIST_ENTRY *Entry; | |
| LIST_ENTRY *Next; | |
| IFCONFIG_INTERFACE_CB *IfCb; | |
| EFI_STATUS MediaStatus; | |
| EFI_IPv4_ADDRESS Gateway; | |
| UINT32 Index; | |
| MediaStatus = EFI_SUCCESS; | |
| if (IsListEmpty (IfList)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_INTERFACE), gShellNetwork1HiiHandle); | |
| } | |
| // | |
| // Go through the interface list. | |
| // | |
| NET_LIST_FOR_EACH_SAFE (Entry, Next, IfList) { | |
| IfCb = NET_LIST_USER_STRUCT (Entry, IFCONFIG_INTERFACE_CB, Link); | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_BREAK), gShellNetwork1HiiHandle); | |
| // | |
| // Print interface name. | |
| // | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_IF_NAME), gShellNetwork1HiiHandle, IfCb->IfInfo->Name); | |
| // | |
| // Get Media State. | |
| // | |
| if (EFI_SUCCESS == NetLibDetectMediaWaitTimeout (IfCb->NicHandle, 0, &MediaStatus)) { | |
| if (MediaStatus != EFI_SUCCESS) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MEDIA_STATE), gShellNetwork1HiiHandle, L"Media disconnected"); | |
| } else { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MEDIA_STATE), gShellNetwork1HiiHandle, L"Media present"); | |
| } | |
| } else { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MEDIA_STATE), gShellNetwork1HiiHandle, L"Media state unknown"); | |
| } | |
| // | |
| // Print interface config policy. | |
| // | |
| if (IfCb->Policy == Ip4Config2PolicyDhcp) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_POLICY_DHCP), gShellNetwork1HiiHandle); | |
| } else { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_POLICY_MAN), gShellNetwork1HiiHandle); | |
| } | |
| // | |
| // Print mac address of the interface. | |
| // | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_MAC_ADDR_HEAD), gShellNetwork1HiiHandle); | |
| IfConfigPrintMacAddr ( | |
| IfCb->IfInfo->HwAddress.Addr, | |
| IfCb->IfInfo->HwAddressSize | |
| ); | |
| // | |
| // Print IPv4 address list of the interface. | |
| // | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_IP_ADDR_HEAD), gShellNetwork1HiiHandle); | |
| ShellPrintHiiEx ( | |
| -1, | |
| -1, | |
| NULL, | |
| STRING_TOKEN (STR_IFCONFIG_INFO_IP_ADDR_BODY), | |
| gShellNetwork1HiiHandle, | |
| (UINTN)IfCb->IfInfo->StationAddress.Addr[0], | |
| (UINTN)IfCb->IfInfo->StationAddress.Addr[1], | |
| (UINTN)IfCb->IfInfo->StationAddress.Addr[2], | |
| (UINTN)IfCb->IfInfo->StationAddress.Addr[3] | |
| ); | |
| // | |
| // Print subnet mask list of the interface. | |
| // | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_SUBNET_MASK_HEAD), gShellNetwork1HiiHandle); | |
| ShellPrintHiiEx ( | |
| -1, | |
| -1, | |
| NULL, | |
| STRING_TOKEN (STR_IFCONFIG_INFO_IP_ADDR_BODY), | |
| gShellNetwork1HiiHandle, | |
| (UINTN)IfCb->IfInfo->SubnetMask.Addr[0], | |
| (UINTN)IfCb->IfInfo->SubnetMask.Addr[1], | |
| (UINTN)IfCb->IfInfo->SubnetMask.Addr[2], | |
| (UINTN)IfCb->IfInfo->SubnetMask.Addr[3] | |
| ); | |
| // | |
| // Print default gateway of the interface. | |
| // | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_GATEWAY_HEAD), gShellNetwork1HiiHandle); | |
| ZeroMem (&Gateway, sizeof (EFI_IPv4_ADDRESS)); | |
| for (Index = 0; Index < IfCb->IfInfo->RouteTableSize; Index++) { | |
| if ((CompareMem (&IfCb->IfInfo->RouteTable[Index].SubnetAddress, &mZeroIp4Addr, sizeof (EFI_IPv4_ADDRESS)) == 0) && | |
| (CompareMem (&IfCb->IfInfo->RouteTable[Index].SubnetMask, &mZeroIp4Addr, sizeof (EFI_IPv4_ADDRESS)) == 0)) | |
| { | |
| CopyMem (&Gateway, &IfCb->IfInfo->RouteTable[Index].GatewayAddress, sizeof (EFI_IPv4_ADDRESS)); | |
| } | |
| } | |
| ShellPrintHiiEx ( | |
| -1, | |
| -1, | |
| NULL, | |
| STRING_TOKEN (STR_IFCONFIG_INFO_IP_ADDR_BODY), | |
| gShellNetwork1HiiHandle, | |
| (UINTN)Gateway.Addr[0], | |
| (UINTN)Gateway.Addr[1], | |
| (UINTN)Gateway.Addr[2], | |
| (UINTN)Gateway.Addr[3] | |
| ); | |
| // | |
| // Print route table entry. | |
| // | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_ROUTES_SIZE), gShellNetwork1HiiHandle, IfCb->IfInfo->RouteTableSize); | |
| for (Index = 0; Index < IfCb->IfInfo->RouteTableSize; Index++) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_ROUTES_ENTRY_INDEX), gShellNetwork1HiiHandle, Index); | |
| ShellPrintHiiEx ( | |
| -1, | |
| -1, | |
| NULL, | |
| STRING_TOKEN (STR_IFCONFIG_SHOW_IP_ADDR), | |
| gShellNetwork1HiiHandle, | |
| L"Subnet ", | |
| (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetAddress.Addr[0], | |
| (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetAddress.Addr[1], | |
| (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetAddress.Addr[2], | |
| (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetAddress.Addr[3] | |
| ); | |
| ShellPrintHiiEx ( | |
| -1, | |
| -1, | |
| NULL, | |
| STRING_TOKEN (STR_IFCONFIG_SHOW_IP_ADDR), | |
| gShellNetwork1HiiHandle, | |
| L"Netmask", | |
| (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetMask.Addr[0], | |
| (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetMask.Addr[1], | |
| (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetMask.Addr[2], | |
| (UINTN)IfCb->IfInfo->RouteTable[Index].SubnetMask.Addr[3] | |
| ); | |
| ShellPrintHiiEx ( | |
| -1, | |
| -1, | |
| NULL, | |
| STRING_TOKEN (STR_IFCONFIG_SHOW_IP_ADDR), | |
| gShellNetwork1HiiHandle, | |
| L"Gateway", | |
| (UINTN)IfCb->IfInfo->RouteTable[Index].GatewayAddress.Addr[0], | |
| (UINTN)IfCb->IfInfo->RouteTable[Index].GatewayAddress.Addr[1], | |
| (UINTN)IfCb->IfInfo->RouteTable[Index].GatewayAddress.Addr[2], | |
| (UINTN)IfCb->IfInfo->RouteTable[Index].GatewayAddress.Addr[3] | |
| ); | |
| } | |
| // | |
| // Print dns server addresses list of the interface if has. | |
| // | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_DNS_ADDR_HEAD), gShellNetwork1HiiHandle); | |
| for (Index = 0; Index < IfCb->DnsCnt; Index++) { | |
| ShellPrintHiiEx ( | |
| -1, | |
| -1, | |
| NULL, | |
| STRING_TOKEN (STR_IFCONFIG_INFO_DNS_ADDR_BODY), | |
| gShellNetwork1HiiHandle, | |
| (UINTN)IfCb->DnsAddr[Index].Addr[0], | |
| (UINTN)IfCb->DnsAddr[Index].Addr[1], | |
| (UINTN)IfCb->DnsAddr[Index].Addr[2], | |
| (UINTN)IfCb->DnsAddr[Index].Addr[3] | |
| ); | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_NEWLINE), gShellNetwork1HiiHandle); | |
| } | |
| } | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INFO_BREAK), gShellNetwork1HiiHandle); | |
| return SHELL_SUCCESS; | |
| } | |
| /** | |
| The clean process of the ifconfig command to clear interface info. | |
| @param[in] IfList The pointer of IfList(interface list). | |
| @param[in] IfName The pointer of interface name. | |
| @retval SHELL_SUCCESS The ifconfig command clean processed successfully. | |
| @retval others The ifconfig command clean process failed. | |
| **/ | |
| SHELL_STATUS | |
| IfConfigClearInterfaceInfo ( | |
| IN LIST_ENTRY *IfList, | |
| IN CHAR16 *IfName | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| SHELL_STATUS ShellStatus; | |
| LIST_ENTRY *Entry; | |
| LIST_ENTRY *Next; | |
| IFCONFIG_INTERFACE_CB *IfCb; | |
| EFI_IP4_CONFIG2_POLICY Policy; | |
| Status = EFI_SUCCESS; | |
| ShellStatus = SHELL_SUCCESS; | |
| if (IsListEmpty (IfList)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_INTERFACE), gShellNetwork1HiiHandle); | |
| } | |
| // | |
| // Go through the interface list. | |
| // If the interface name is specified, DHCP DORA process will be | |
| // triggered by the policy transition (static -> dhcp). | |
| // | |
| NET_LIST_FOR_EACH_SAFE (Entry, Next, IfList) { | |
| IfCb = NET_LIST_USER_STRUCT (Entry, IFCONFIG_INTERFACE_CB, Link); | |
| if ((IfName != NULL) && (StrCmp (IfName, IfCb->IfInfo->Name) == 0)) { | |
| Policy = Ip4Config2PolicyStatic; | |
| Status = IfCb->IfCfg->SetData ( | |
| IfCb->IfCfg, | |
| Ip4Config2DataTypePolicy, | |
| sizeof (EFI_IP4_CONFIG2_POLICY), | |
| &Policy | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork1HiiHandle, L"ifconfig"); | |
| ShellStatus = SHELL_ACCESS_DENIED; | |
| break; | |
| } | |
| } | |
| Policy = Ip4Config2PolicyDhcp; | |
| Status = IfCb->IfCfg->SetData ( | |
| IfCb->IfCfg, | |
| Ip4Config2DataTypePolicy, | |
| sizeof (EFI_IP4_CONFIG2_POLICY), | |
| &Policy | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork1HiiHandle, L"ifconfig"); | |
| ShellStatus = SHELL_ACCESS_DENIED; | |
| break; | |
| } | |
| } | |
| return ShellStatus; | |
| } | |
| /** | |
| The set process of the ifconfig command. | |
| @param[in] IfList The pointer of IfList(interface list). | |
| @param[in] VarArg The pointer of ARG_LIST(Args with "-s" option). | |
| @retval SHELL_SUCCESS The ifconfig command set processed successfully. | |
| @retval others The ifconfig command set process failed. | |
| **/ | |
| SHELL_STATUS | |
| IfConfigSetInterfaceInfo ( | |
| IN LIST_ENTRY *IfList, | |
| IN ARG_LIST *VarArg | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| SHELL_STATUS ShellStatus; | |
| IFCONFIG_INTERFACE_CB *IfCb; | |
| VAR_CHECK_CODE CheckCode; | |
| EFI_EVENT TimeOutEvt; | |
| EFI_EVENT MappedEvt; | |
| BOOLEAN IsAddressOk; | |
| EFI_IP4_CONFIG2_POLICY Policy; | |
| EFI_IP4_CONFIG2_MANUAL_ADDRESS ManualAddress; | |
| UINTN DataSize; | |
| EFI_IPv4_ADDRESS Gateway; | |
| IP4_ADDR SubnetMask; | |
| IP4_ADDR TempGateway; | |
| EFI_IPv4_ADDRESS *Dns; | |
| ARG_LIST *Tmp; | |
| UINTN Index; | |
| CONST CHAR16 *TempString; | |
| Dns = NULL; | |
| if (IsListEmpty (IfList)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_INTERFACE), gShellNetwork1HiiHandle); | |
| return SHELL_INVALID_PARAMETER; | |
| } | |
| // | |
| // Make sure to set only one interface each time. | |
| // | |
| IfCb = NET_LIST_USER_STRUCT (IfList->ForwardLink, IFCONFIG_INTERFACE_CB, Link); | |
| Status = EFI_SUCCESS; | |
| ShellStatus = SHELL_SUCCESS; | |
| // | |
| // Initialize check list mechanism. | |
| // | |
| CheckCode = IfConfigRetriveCheckListByName ( | |
| NULL, | |
| NULL, | |
| TRUE | |
| ); | |
| // | |
| // Create events & timers for asynchronous settings. | |
| // | |
| Status = gBS->CreateEvent ( | |
| EVT_TIMER, | |
| TPL_CALLBACK, | |
| NULL, | |
| NULL, | |
| &TimeOutEvt | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork1HiiHandle, L"ifconfig"); | |
| ShellStatus = SHELL_ACCESS_DENIED; | |
| goto ON_EXIT; | |
| } | |
| Status = gBS->CreateEvent ( | |
| EVT_NOTIFY_SIGNAL, | |
| TPL_NOTIFY, | |
| IfConfigManualAddressNotify, | |
| &IsAddressOk, | |
| &MappedEvt | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork1HiiHandle, L"ifconfig"); | |
| ShellStatus = SHELL_ACCESS_DENIED; | |
| goto ON_EXIT; | |
| } | |
| // | |
| // Parse the setting variables. | |
| // | |
| while (VarArg != NULL) { | |
| // | |
| // Check invalid parameters (duplication & unknown & conflict). | |
| // | |
| CheckCode = IfConfigRetriveCheckListByName ( | |
| mSetCheckList, | |
| VarArg->Arg, | |
| FALSE | |
| ); | |
| if (VarCheckOk != CheckCode) { | |
| switch (CheckCode) { | |
| case VarCheckDuplicate: | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_DUPLICATE_COMMAND), gShellNetwork1HiiHandle, VarArg->Arg); | |
| break; | |
| case VarCheckConflict: | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_CONFLICT_COMMAND), gShellNetwork1HiiHandle, VarArg->Arg); | |
| break; | |
| case VarCheckUnknown: | |
| // | |
| // To handle unsupported option. | |
| // | |
| TempString = PermanentString; | |
| if (StringNoCaseCompare (&VarArg->Arg, &TempString) == 0) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_UNSUPPORTED_OPTION), gShellNetwork1HiiHandle, PermanentString); | |
| goto ON_EXIT; | |
| } | |
| // | |
| // To handle unknown option. | |
| // | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_UNKNOWN_COMMAND), gShellNetwork1HiiHandle, VarArg->Arg); | |
| break; | |
| default: | |
| break; | |
| } | |
| VarArg = VarArg->Next; | |
| continue; | |
| } | |
| // | |
| // Process valid variables. | |
| // | |
| if (StrCmp (VarArg->Arg, L"dhcp") == 0) { | |
| // | |
| // Set dhcp config policy | |
| // | |
| Policy = Ip4Config2PolicyDhcp; | |
| Status = IfCb->IfCfg->SetData ( | |
| IfCb->IfCfg, | |
| Ip4Config2DataTypePolicy, | |
| sizeof (EFI_IP4_CONFIG2_POLICY), | |
| &Policy | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork1HiiHandle, L"ifconfig"); | |
| ShellStatus = SHELL_ACCESS_DENIED; | |
| goto ON_EXIT; | |
| } | |
| VarArg = VarArg->Next; | |
| } else if (StrCmp (VarArg->Arg, L"static") == 0) { | |
| VarArg = VarArg->Next; | |
| if (VarArg == NULL) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_LACK_COMMAND), gShellNetwork1HiiHandle); | |
| ShellStatus = SHELL_INVALID_PARAMETER; | |
| goto ON_EXIT; | |
| } | |
| ZeroMem (&ManualAddress, sizeof (ManualAddress)); | |
| // | |
| // Get manual IP address. | |
| // | |
| Status = NetLibStrToIp4 (VarArg->Arg, &ManualAddress.Address); | |
| if (EFI_ERROR (Status)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_IPADDRESS), gShellNetwork1HiiHandle, VarArg->Arg); | |
| ShellStatus = SHELL_INVALID_PARAMETER; | |
| goto ON_EXIT; | |
| } | |
| // | |
| // Get subnetmask. | |
| // | |
| VarArg = VarArg->Next; | |
| if (VarArg == NULL) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_LACK_COMMAND), gShellNetwork1HiiHandle); | |
| ShellStatus = SHELL_INVALID_PARAMETER; | |
| goto ON_EXIT; | |
| } | |
| Status = NetLibStrToIp4 (VarArg->Arg, &ManualAddress.SubnetMask); | |
| if (EFI_ERROR (Status)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_IPADDRESS), gShellNetwork1HiiHandle, VarArg->Arg); | |
| ShellStatus = SHELL_INVALID_PARAMETER; | |
| goto ON_EXIT; | |
| } | |
| // | |
| // Get gateway. | |
| // | |
| VarArg = VarArg->Next; | |
| if (VarArg == NULL) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_LACK_COMMAND), gShellNetwork1HiiHandle); | |
| ShellStatus = SHELL_INVALID_PARAMETER; | |
| goto ON_EXIT; | |
| } | |
| Status = NetLibStrToIp4 (VarArg->Arg, &Gateway); | |
| if (EFI_ERROR (Status)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_IPADDRESS), gShellNetwork1HiiHandle, VarArg->Arg); | |
| ShellStatus = SHELL_INVALID_PARAMETER; | |
| goto ON_EXIT; | |
| } | |
| // | |
| // Need to check the gateway validity before set Manual Address. | |
| // In case we can set manual address but fail to configure Gateway. | |
| // | |
| CopyMem (&SubnetMask, &ManualAddress.SubnetMask, sizeof (IP4_ADDR)); | |
| CopyMem (&TempGateway, &Gateway, sizeof (IP4_ADDR)); | |
| SubnetMask = NTOHL (SubnetMask); | |
| TempGateway = NTOHL (TempGateway); | |
| if ((SubnetMask != 0) && | |
| (SubnetMask != 0xFFFFFFFFu) && | |
| !NetIp4IsUnicast (TempGateway, SubnetMask)) | |
| { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_GATEWAY), gShellNetwork1HiiHandle, VarArg->Arg); | |
| ShellStatus = SHELL_INVALID_PARAMETER; | |
| goto ON_EXIT; | |
| } | |
| // | |
| // Set manual config policy. | |
| // | |
| Policy = Ip4Config2PolicyStatic; | |
| Status = IfCb->IfCfg->SetData ( | |
| IfCb->IfCfg, | |
| Ip4Config2DataTypePolicy, | |
| sizeof (EFI_IP4_CONFIG2_POLICY), | |
| &Policy | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork1HiiHandle, L"ifconfig"); | |
| ShellStatus = SHELL_ACCESS_DENIED; | |
| goto ON_EXIT; | |
| } | |
| // | |
| // Set Manual Address. | |
| // | |
| IsAddressOk = FALSE; | |
| Status = IfCb->IfCfg->RegisterDataNotify ( | |
| IfCb->IfCfg, | |
| Ip4Config2DataTypeManualAddress, | |
| MappedEvt | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_SET_ADDR_FAILED), gShellNetwork1HiiHandle, Status); | |
| ShellStatus = SHELL_ACCESS_DENIED; | |
| goto ON_EXIT; | |
| } | |
| DataSize = sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS); | |
| Status = IfCb->IfCfg->SetData ( | |
| IfCb->IfCfg, | |
| Ip4Config2DataTypeManualAddress, | |
| DataSize, | |
| &ManualAddress | |
| ); | |
| if (Status == EFI_NOT_READY) { | |
| gBS->SetTimer (TimeOutEvt, TimerRelative, 50000000); | |
| while (EFI_ERROR (gBS->CheckEvent (TimeOutEvt))) { | |
| if (IsAddressOk) { | |
| Status = EFI_SUCCESS; | |
| break; | |
| } | |
| } | |
| } | |
| IfCb->IfCfg->UnregisterDataNotify ( | |
| IfCb->IfCfg, | |
| Ip4Config2DataTypeManualAddress, | |
| MappedEvt | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_SET_ADDR_FAILED), gShellNetwork1HiiHandle, Status); | |
| ShellStatus = SHELL_ACCESS_DENIED; | |
| goto ON_EXIT; | |
| } | |
| // | |
| // Set gateway. | |
| // | |
| DataSize = sizeof (EFI_IPv4_ADDRESS); | |
| Status = IfCb->IfCfg->SetData ( | |
| IfCb->IfCfg, | |
| Ip4Config2DataTypeGateway, | |
| DataSize, | |
| &Gateway | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_SET_ADDR_FAILED), gShellNetwork1HiiHandle, Status); | |
| ShellStatus = SHELL_ACCESS_DENIED; | |
| goto ON_EXIT; | |
| } | |
| VarArg = VarArg->Next; | |
| } else if (StrCmp (VarArg->Arg, L"dns") == 0) { | |
| // | |
| // Get DNS addresses. | |
| // | |
| VarArg = VarArg->Next; | |
| Tmp = VarArg; | |
| Index = 0; | |
| while (Tmp != NULL) { | |
| Index++; | |
| Tmp = Tmp->Next; | |
| } | |
| Dns = AllocatePool (Index * sizeof (EFI_IPv4_ADDRESS)); | |
| if (Dns == NULL) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork1HiiHandle, L"ifconfig"); | |
| ShellStatus = SHELL_OUT_OF_RESOURCES; | |
| goto ON_EXIT; | |
| } | |
| Tmp = VarArg; | |
| Index = 0; | |
| while (Tmp != NULL) { | |
| Status = NetLibStrToIp4 (Tmp->Arg, Dns + Index); | |
| if (EFI_ERROR (Status)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_INVALID_IPADDRESS), gShellNetwork1HiiHandle, Tmp->Arg); | |
| ShellStatus = SHELL_INVALID_PARAMETER; | |
| goto ON_EXIT; | |
| } | |
| Index++; | |
| Tmp = Tmp->Next; | |
| } | |
| VarArg = Tmp; | |
| // | |
| // Set DNS addresses. | |
| // | |
| DataSize = Index * sizeof (EFI_IPv4_ADDRESS); | |
| Status = IfCb->IfCfg->SetData ( | |
| IfCb->IfCfg, | |
| Ip4Config2DataTypeDnsServer, | |
| DataSize, | |
| Dns | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_ERR_AD), gShellNetwork1HiiHandle, L"ifconfig"); | |
| ShellStatus = SHELL_ACCESS_DENIED; | |
| goto ON_EXIT; | |
| } | |
| } | |
| } | |
| ON_EXIT: | |
| if (Dns != NULL) { | |
| FreePool (Dns); | |
| } | |
| return ShellStatus; | |
| } | |
| /** | |
| The ifconfig command main process. | |
| @param[in] Private The pointer of IFCONFIG_PRIVATE_DATA. | |
| @retval SHELL_SUCCESS ifconfig command processed successfully. | |
| @retval others The ifconfig command process failed. | |
| **/ | |
| SHELL_STATUS | |
| IfConfig ( | |
| IN IFCONFIG_PRIVATE_DATA *Private | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| SHELL_STATUS ShellStatus; | |
| ShellStatus = SHELL_SUCCESS; | |
| // | |
| // Get configure information of all interfaces. | |
| // | |
| Status = IfConfigGetInterfaceInfo ( | |
| Private->IfName, | |
| &Private->IfList | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| ShellStatus = SHELL_NOT_FOUND; | |
| goto ON_EXIT; | |
| } | |
| switch (Private->OpCode) { | |
| case IfConfigOpList: | |
| ShellStatus = IfConfigShowInterfaceInfo (&Private->IfList); | |
| break; | |
| case IfConfigOpClear: | |
| ShellStatus = IfConfigClearInterfaceInfo (&Private->IfList, Private->IfName); | |
| break; | |
| case IfConfigOpSet: | |
| ShellStatus = IfConfigSetInterfaceInfo (&Private->IfList, Private->VarArg); | |
| break; | |
| default: | |
| ShellStatus = SHELL_UNSUPPORTED; | |
| } | |
| ON_EXIT: | |
| return ShellStatus; | |
| } | |
| /** | |
| The ifconfig command cleanup process, free the allocated memory. | |
| @param[in] Private The pointer of IFCONFIG_PRIVATE_DATA. | |
| **/ | |
| VOID | |
| IfConfigCleanup ( | |
| IN IFCONFIG_PRIVATE_DATA *Private | |
| ) | |
| { | |
| LIST_ENTRY *Entry; | |
| LIST_ENTRY *NextEntry; | |
| IFCONFIG_INTERFACE_CB *IfCb; | |
| ASSERT (Private != NULL); | |
| // | |
| // Clean the list which save the set config Args. | |
| // | |
| if (Private->VarArg != NULL) { | |
| FreeArgList (Private->VarArg); | |
| } | |
| if (Private->IfName != NULL) { | |
| FreePool (Private->IfName); | |
| } | |
| // | |
| // Clean the IFCONFIG_INTERFACE_CB list. | |
| // | |
| NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Private->IfList) { | |
| IfCb = NET_LIST_USER_STRUCT (Entry, IFCONFIG_INTERFACE_CB, Link); | |
| RemoveEntryList (&IfCb->Link); | |
| if (IfCb->IfInfo != NULL) { | |
| FreePool (IfCb->IfInfo); | |
| } | |
| FreePool (IfCb); | |
| } | |
| FreePool (Private); | |
| } | |
| /** | |
| Function for 'ifconfig' command. | |
| @param[in] ImageHandle Handle to the Image (NULL if Internal). | |
| @param[in] SystemTable Pointer to the System Table (NULL if Internal). | |
| @retval EFI_SUCCESS ifconfig command processed successfully. | |
| @retval others The ifconfig command process failed. | |
| **/ | |
| SHELL_STATUS | |
| EFIAPI | |
| ShellCommandRunIfconfig ( | |
| IN EFI_HANDLE ImageHandle, | |
| IN EFI_SYSTEM_TABLE *SystemTable | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| IFCONFIG_PRIVATE_DATA *Private; | |
| LIST_ENTRY *ParamPackage; | |
| SHELL_STATUS ShellStatus; | |
| CONST CHAR16 *ValueStr; | |
| ARG_LIST *ArgList; | |
| CHAR16 *ProblemParam; | |
| CHAR16 *Str; | |
| Status = EFI_INVALID_PARAMETER; | |
| Private = NULL; | |
| ShellStatus = SHELL_SUCCESS; | |
| Status = ShellCommandLineParseEx (mIfConfigCheckList, &ParamPackage, &ProblemParam, TRUE, FALSE); | |
| if (EFI_ERROR (Status)) { | |
| if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellNetwork1HiiHandle, L"ifconfig", ProblemParam); | |
| FreePool (ProblemParam); | |
| ShellStatus = SHELL_INVALID_PARAMETER; | |
| } else { | |
| ASSERT (FALSE); | |
| } | |
| goto ON_EXIT; | |
| } | |
| // | |
| // To handle unsupported option. | |
| // | |
| if (ShellCommandLineGetFlag (ParamPackage, L"-c")) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_UNSUPPORTED_OPTION), gShellNetwork1HiiHandle, L"-c"); | |
| ShellStatus = SHELL_INVALID_PARAMETER; | |
| goto ON_EXIT; | |
| } | |
| // | |
| // To handle no option. | |
| // | |
| if (!ShellCommandLineGetFlag (ParamPackage, L"-r") && !ShellCommandLineGetFlag (ParamPackage, L"-s") && | |
| !ShellCommandLineGetFlag (ParamPackage, L"-l")) | |
| { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_LACK_OPTION), gShellNetwork1HiiHandle); | |
| ShellStatus = SHELL_INVALID_PARAMETER; | |
| goto ON_EXIT; | |
| } | |
| // | |
| // To handle conflict options. | |
| // | |
| if (((ShellCommandLineGetFlag (ParamPackage, L"-r")) && (ShellCommandLineGetFlag (ParamPackage, L"-s"))) || | |
| ((ShellCommandLineGetFlag (ParamPackage, L"-r")) && (ShellCommandLineGetFlag (ParamPackage, L"-l"))) || | |
| ((ShellCommandLineGetFlag (ParamPackage, L"-s")) && (ShellCommandLineGetFlag (ParamPackage, L"-l")))) | |
| { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellNetwork1HiiHandle, L"ifconfig"); | |
| ShellStatus = SHELL_INVALID_PARAMETER; | |
| goto ON_EXIT; | |
| } | |
| Private = AllocateZeroPool (sizeof (IFCONFIG_PRIVATE_DATA)); | |
| if (Private == NULL) { | |
| ShellStatus = SHELL_OUT_OF_RESOURCES; | |
| goto ON_EXIT; | |
| } | |
| InitializeListHead (&Private->IfList); | |
| // | |
| // To get interface name for the list option. | |
| // | |
| if (ShellCommandLineGetFlag (ParamPackage, L"-l")) { | |
| Private->OpCode = IfConfigOpList; | |
| ValueStr = ShellCommandLineGetValue (ParamPackage, L"-l"); | |
| if (ValueStr != NULL) { | |
| Str = AllocateCopyPool (StrSize (ValueStr), ValueStr); | |
| if (Str == NULL) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork1HiiHandle, L"ifconfig"); | |
| ShellStatus = SHELL_OUT_OF_RESOURCES; | |
| goto ON_EXIT; | |
| } | |
| Private->IfName = Str; | |
| } | |
| } | |
| // | |
| // To get interface name for the clear option. | |
| // | |
| if (ShellCommandLineGetFlag (ParamPackage, L"-r")) { | |
| Private->OpCode = IfConfigOpClear; | |
| ValueStr = ShellCommandLineGetValue (ParamPackage, L"-r"); | |
| if (ValueStr != NULL) { | |
| Str = AllocateCopyPool (StrSize (ValueStr), ValueStr); | |
| if (Str == NULL) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork1HiiHandle, L"ifconfig"); | |
| ShellStatus = SHELL_OUT_OF_RESOURCES; | |
| goto ON_EXIT; | |
| } | |
| Private->IfName = Str; | |
| } | |
| } | |
| // | |
| // To get interface name and corresponding Args for the set option. | |
| // | |
| if (ShellCommandLineGetFlag (ParamPackage, L"-s")) { | |
| ValueStr = ShellCommandLineGetValue (ParamPackage, L"-s"); | |
| if (ValueStr == NULL) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_LACK_INTERFACE), gShellNetwork1HiiHandle); | |
| ShellStatus = SHELL_INVALID_PARAMETER; | |
| goto ON_EXIT; | |
| } | |
| // | |
| // To split the configuration into multi-section. | |
| // | |
| ArgList = SplitStrToList (ValueStr, L' '); | |
| if (ArgList == NULL) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellNetwork1HiiHandle, L"ifconfig"); | |
| ShellStatus = SHELL_OUT_OF_RESOURCES; | |
| goto ON_EXIT; | |
| } | |
| Private->OpCode = IfConfigOpSet; | |
| Private->IfName = ArgList->Arg; | |
| Private->VarArg = ArgList->Next; | |
| if ((Private->IfName == NULL) || (Private->VarArg == NULL)) { | |
| ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG_LACK_COMMAND), gShellNetwork1HiiHandle); | |
| ShellStatus = SHELL_INVALID_PARAMETER; | |
| goto ON_EXIT; | |
| } | |
| } | |
| // | |
| // Main process of ifconfig. | |
| // | |
| ShellStatus = IfConfig (Private); | |
| ON_EXIT: | |
| ShellCommandLineFreeVarList (ParamPackage); | |
| if (Private != NULL) { | |
| IfConfigCleanup (Private); | |
| } | |
| return ShellStatus; | |
| } |