mirror of https://github.com/acidanthera/audk.git
1444 lines
40 KiB
C
1444 lines
40 KiB
C
/** @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 - 2017, Intel Corporation. All rights reserved.<BR>
|
|
|
|
This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php.
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
**/
|
|
|
|
#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;
|
|
BOOLEAN MediaPresent;
|
|
EFI_IPv4_ADDRESS Gateway;
|
|
UINT32 Index;
|
|
|
|
MediaPresent = TRUE;
|
|
|
|
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.
|
|
//
|
|
NetLibDetectMedia (IfCb->NicHandle, &MediaPresent);
|
|
if (!MediaPresent) {
|
|
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");
|
|
}
|
|
|
|
//
|
|
// 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) &&
|
|
!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;
|
|
}
|