diff options
Diffstat (limited to 'ShellPkg/Library/UefiShellNetwork1CommandsLib/Ifconfig.c')
| -rw-r--r-- | ShellPkg/Library/UefiShellNetwork1CommandsLib/Ifconfig.c | 2894 |
1 files changed, 1447 insertions, 1447 deletions
diff --git a/ShellPkg/Library/UefiShellNetwork1CommandsLib/Ifconfig.c b/ShellPkg/Library/UefiShellNetwork1CommandsLib/Ifconfig.c index 71b08bdff1..27b07920bb 100644 --- a/ShellPkg/Library/UefiShellNetwork1CommandsLib/Ifconfig.c +++ b/ShellPkg/Library/UefiShellNetwork1CommandsLib/Ifconfig.c @@ -1,1447 +1,1447 @@ -/** @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;
-}
+/** @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; +} |
