mirror of https://github.com/acidanthera/audk.git
690 lines
15 KiB
C
690 lines
15 KiB
C
/** @file
|
|
Shell application for VLAN configuration.
|
|
|
|
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
|
|
#include <Uefi.h>
|
|
|
|
#include <Protocol/VlanConfig.h>
|
|
|
|
#include <Library/UefiApplicationEntryPoint.h>
|
|
#include <Library/UefiLib.h>
|
|
#include <Library/ShellLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Library/HiiLib.h>
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
#include <Library/UefiHiiServicesLib.h>
|
|
#include <Library/NetLib.h>
|
|
|
|
//
|
|
// String token ID of VConfig command help message text.
|
|
//
|
|
GLOBAL_REMOVE_IF_UNREFERENCED EFI_STRING_ID mStringVConfigHelpTokenId = STRING_TOKEN (STR_VCONFIG_HELP);
|
|
|
|
#define INVALID_NIC_INDEX 0xffff
|
|
#define INVALID_VLAN_ID 0xffff
|
|
|
|
//
|
|
// This is the generated String package data for all .UNI files.
|
|
// This data array is ready to be used as input of HiiAddPackages() to
|
|
// create a packagelist (which contains Form packages, String packages, etc).
|
|
//
|
|
extern UINT8 VConfigStrings[];
|
|
|
|
EFI_HANDLE mImageHandle = NULL;
|
|
EFI_HII_HANDLE mHiiHandle = NULL;
|
|
|
|
SHELL_PARAM_ITEM mParamList[] = {
|
|
{
|
|
L"-l",
|
|
TypeValue
|
|
},
|
|
{
|
|
L"-a",
|
|
TypeMaxValue
|
|
},
|
|
{
|
|
L"-d",
|
|
TypeValue
|
|
},
|
|
{
|
|
NULL,
|
|
TypeMax
|
|
}
|
|
};
|
|
|
|
/**
|
|
Locate the network interface handle buffer.
|
|
|
|
@param[out] NumberOfHandles Pointer to the number of handles.
|
|
@param[out] HandleBuffer Pointer to the buffer to store the returned handles.
|
|
|
|
**/
|
|
VOID
|
|
LocateNicHandleBuffer (
|
|
OUT UINTN *NumberOfHandles,
|
|
OUT EFI_HANDLE **HandleBuffer
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
*NumberOfHandles = 0;
|
|
*HandleBuffer = NULL;
|
|
|
|
Status = gBS->LocateHandleBuffer (
|
|
ByProtocol,
|
|
&gEfiVlanConfigProtocolGuid,
|
|
NULL,
|
|
NumberOfHandles,
|
|
HandleBuffer
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_LOCATE_FAIL), mHiiHandle, Status);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Extract the decimal index from the network interface name.
|
|
|
|
@param[in] Name Name of the network interface.
|
|
|
|
@retval INVALID_NIC_INDEX Failed to extract the network interface index.
|
|
@return others The network interface index.
|
|
|
|
**/
|
|
UINTN
|
|
NicNameToIndex (
|
|
IN CHAR16 *Name
|
|
)
|
|
{
|
|
CHAR16 *Str;
|
|
|
|
Str = Name + 3;
|
|
if ((StrnCmp (Name, L"eth", 3) != 0) || (*Str == 0)) {
|
|
return INVALID_NIC_INDEX;
|
|
}
|
|
|
|
while (*Str != 0) {
|
|
if ((*Str < L'0') || (*Str > L'9')) {
|
|
return INVALID_NIC_INDEX;
|
|
}
|
|
|
|
Str++;
|
|
}
|
|
|
|
return (UINT16)StrDecimalToUintn (Name + 3);
|
|
}
|
|
|
|
/**
|
|
Find network interface device handle by its name.
|
|
|
|
@param[in] Name Name of the network interface.
|
|
|
|
@retval NULL Cannot find the network interface.
|
|
@return others Handle of the network interface.
|
|
|
|
**/
|
|
EFI_HANDLE
|
|
NicNameToHandle (
|
|
IN CHAR16 *Name
|
|
)
|
|
{
|
|
UINTN NumberOfHandles;
|
|
EFI_HANDLE *HandleBuffer;
|
|
UINTN Index;
|
|
EFI_HANDLE Handle;
|
|
|
|
//
|
|
// Find all NIC handles.
|
|
//
|
|
LocateNicHandleBuffer (&NumberOfHandles, &HandleBuffer);
|
|
if (NumberOfHandles == 0) {
|
|
return NULL;
|
|
}
|
|
|
|
Index = NicNameToIndex (Name);
|
|
if (Index >= NumberOfHandles) {
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_INVALID_IF), mHiiHandle, Name);
|
|
Handle = NULL;
|
|
} else {
|
|
Handle = HandleBuffer[Index];
|
|
}
|
|
|
|
FreePool (HandleBuffer);
|
|
return Handle;
|
|
}
|
|
|
|
/**
|
|
Open VlanConfig protocol from a handle.
|
|
|
|
@param[in] Handle The handle to open the VlanConfig protocol.
|
|
|
|
@return The VlanConfig protocol interface.
|
|
|
|
**/
|
|
EFI_VLAN_CONFIG_PROTOCOL *
|
|
OpenVlanConfigProtocol (
|
|
IN EFI_HANDLE Handle
|
|
)
|
|
{
|
|
EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
|
|
|
|
VlanConfig = NULL;
|
|
gBS->OpenProtocol (
|
|
Handle,
|
|
&gEfiVlanConfigProtocolGuid,
|
|
(VOID **)&VlanConfig,
|
|
mImageHandle,
|
|
Handle,
|
|
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
|
);
|
|
|
|
return VlanConfig;
|
|
}
|
|
|
|
/**
|
|
Close VlanConfig protocol of a handle.
|
|
|
|
@param[in] Handle The handle to close the VlanConfig protocol.
|
|
|
|
**/
|
|
VOID
|
|
CloseVlanConfigProtocol (
|
|
IN EFI_HANDLE Handle
|
|
)
|
|
{
|
|
gBS->CloseProtocol (
|
|
Handle,
|
|
&gEfiVlanConfigProtocolGuid,
|
|
mImageHandle,
|
|
Handle
|
|
);
|
|
}
|
|
|
|
/**
|
|
Display VLAN configuration of a network interface.
|
|
|
|
@param[in] Handle Handle of the network interface.
|
|
@param[in] NicIndex Index of the network interface.
|
|
|
|
**/
|
|
VOID
|
|
ShowNicVlanInfo (
|
|
IN EFI_HANDLE Handle,
|
|
IN UINTN NicIndex
|
|
)
|
|
{
|
|
CHAR16 *MacStr;
|
|
EFI_STATUS Status;
|
|
UINTN Index;
|
|
EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
|
|
UINT16 NumberOfVlan;
|
|
EFI_VLAN_FIND_DATA *VlanData;
|
|
|
|
VlanConfig = OpenVlanConfigProtocol (Handle);
|
|
if (VlanConfig == NULL) {
|
|
return;
|
|
}
|
|
|
|
MacStr = NULL;
|
|
Status = NetLibGetMacString (Handle, mImageHandle, &MacStr);
|
|
if (EFI_ERROR (Status)) {
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_MAC_FAIL), mHiiHandle, Status);
|
|
goto Exit;
|
|
}
|
|
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_ETH_MAC), mHiiHandle, NicIndex, MacStr);
|
|
|
|
Status = VlanConfig->Find (VlanConfig, NULL, &NumberOfVlan, &VlanData);
|
|
if (EFI_ERROR (Status)) {
|
|
if (Status == EFI_NOT_FOUND) {
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_VLAN), mHiiHandle);
|
|
} else {
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_FIND_FAIL), mHiiHandle, Status);
|
|
}
|
|
|
|
goto Exit;
|
|
}
|
|
|
|
for (Index = 0; Index < NumberOfVlan; Index++) {
|
|
ShellPrintHiiEx (
|
|
-1,
|
|
-1,
|
|
NULL,
|
|
STRING_TOKEN (STR_VCONFIG_VLAN_DISPLAY),
|
|
mHiiHandle,
|
|
VlanData[Index].VlanId,
|
|
VlanData[Index].Priority
|
|
);
|
|
}
|
|
|
|
FreePool (VlanData);
|
|
|
|
Exit:
|
|
CloseVlanConfigProtocol (Handle);
|
|
|
|
if (MacStr != NULL) {
|
|
FreePool (MacStr);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Display the VLAN configuration of all, or a specified network interface.
|
|
|
|
@param[in] Name Name of the network interface. If NULL, the VLAN
|
|
configuration of all network will be displayed.
|
|
|
|
**/
|
|
VOID
|
|
DisplayVlan (
|
|
IN CHAR16 *Name OPTIONAL
|
|
)
|
|
{
|
|
UINTN NumberOfHandles;
|
|
EFI_HANDLE *HandleBuffer;
|
|
UINTN Index;
|
|
EFI_HANDLE NicHandle;
|
|
|
|
if (Name != NULL) {
|
|
//
|
|
// Display specified NIC
|
|
//
|
|
NicHandle = NicNameToHandle (Name);
|
|
if (NicHandle == NULL) {
|
|
return;
|
|
}
|
|
|
|
ShowNicVlanInfo (NicHandle, 0);
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Find all NIC handles
|
|
//
|
|
LocateNicHandleBuffer (&NumberOfHandles, &HandleBuffer);
|
|
if (NumberOfHandles == 0) {
|
|
return;
|
|
}
|
|
|
|
for (Index = 0; Index < NumberOfHandles; Index++) {
|
|
ShowNicVlanInfo (HandleBuffer[Index], Index);
|
|
}
|
|
|
|
FreePool (HandleBuffer);
|
|
}
|
|
|
|
/**
|
|
Convert a NULL-terminated unicode decimal VLAN ID string to VLAN ID.
|
|
|
|
@param[in] String Pointer to VLAN ID string from user input.
|
|
|
|
@retval Value translated from String, or INVALID_VLAN_ID is string is invalid.
|
|
|
|
**/
|
|
UINT16
|
|
StrToVlanId (
|
|
IN CHAR16 *String
|
|
)
|
|
{
|
|
CHAR16 *Str;
|
|
|
|
if (String == NULL) {
|
|
return INVALID_VLAN_ID;
|
|
}
|
|
|
|
Str = String;
|
|
while ((*Str >= '0') && (*Str <= '9')) {
|
|
Str++;
|
|
}
|
|
|
|
if (*Str != 0) {
|
|
return INVALID_VLAN_ID;
|
|
}
|
|
|
|
return (UINT16)StrDecimalToUintn (String);
|
|
}
|
|
|
|
/**
|
|
Add a VLAN device.
|
|
|
|
@param[in] ParamStr Parameter string from user input.
|
|
|
|
**/
|
|
VOID
|
|
AddVlan (
|
|
IN CHAR16 *ParamStr
|
|
)
|
|
{
|
|
CHAR16 *Name;
|
|
CHAR16 *VlanIdStr;
|
|
CHAR16 *PriorityStr;
|
|
CHAR16 *StrPtr;
|
|
BOOLEAN IsSpace;
|
|
UINTN VlanId;
|
|
UINTN Priority;
|
|
EFI_HANDLE Handle;
|
|
EFI_HANDLE VlanHandle;
|
|
EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
|
|
EFI_STATUS Status;
|
|
|
|
VlanConfig = NULL;
|
|
Priority = 0;
|
|
|
|
if (ParamStr == NULL) {
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_IF), mHiiHandle);
|
|
return;
|
|
}
|
|
|
|
StrPtr = AllocateCopyPool (StrSize (ParamStr), ParamStr);
|
|
if (StrPtr == NULL) {
|
|
return;
|
|
}
|
|
|
|
Name = StrPtr;
|
|
VlanIdStr = NULL;
|
|
PriorityStr = NULL;
|
|
IsSpace = FALSE;
|
|
while (*StrPtr != 0) {
|
|
if (*StrPtr == L' ') {
|
|
*StrPtr = 0;
|
|
IsSpace = TRUE;
|
|
} else {
|
|
if (IsSpace) {
|
|
//
|
|
// Start of a parameter.
|
|
//
|
|
if (VlanIdStr == NULL) {
|
|
//
|
|
// 2nd parameter is VLAN ID.
|
|
//
|
|
VlanIdStr = StrPtr;
|
|
} else if (PriorityStr == NULL) {
|
|
//
|
|
// 3rd parameter is Priority.
|
|
//
|
|
PriorityStr = StrPtr;
|
|
} else {
|
|
//
|
|
// Ignore else parameters.
|
|
//
|
|
break;
|
|
}
|
|
}
|
|
|
|
IsSpace = FALSE;
|
|
}
|
|
|
|
StrPtr++;
|
|
}
|
|
|
|
Handle = NicNameToHandle (Name);
|
|
if (Handle == NULL) {
|
|
goto Exit;
|
|
}
|
|
|
|
VlanConfig = OpenVlanConfigProtocol (Handle);
|
|
if (VlanConfig == NULL) {
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// Check VLAN ID.
|
|
//
|
|
if ((VlanIdStr == NULL) || (*VlanIdStr == 0)) {
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_VID), mHiiHandle);
|
|
goto Exit;
|
|
}
|
|
|
|
VlanId = StrToVlanId (VlanIdStr);
|
|
if (VlanId > 4094) {
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_INVALID_VID), mHiiHandle, VlanIdStr);
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// Check Priority.
|
|
//
|
|
if ((PriorityStr != NULL) && (*PriorityStr != 0)) {
|
|
Priority = StrDecimalToUintn (PriorityStr);
|
|
if (Priority > 7) {
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_INVALID_PRIORITY), mHiiHandle, PriorityStr);
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Set VLAN
|
|
//
|
|
Status = VlanConfig->Set (VlanConfig, (UINT16)VlanId, (UINT8)Priority);
|
|
if (EFI_ERROR (Status)) {
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_SET_FAIL), mHiiHandle, Status);
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// Connect the VLAN device.
|
|
//
|
|
VlanHandle = NetLibGetVlanHandle (Handle, (UINT16)VlanId);
|
|
if (VlanHandle != NULL) {
|
|
gBS->ConnectController (VlanHandle, NULL, NULL, TRUE);
|
|
}
|
|
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_SET_SUCCESS), mHiiHandle);
|
|
|
|
Exit:
|
|
if (VlanConfig != NULL) {
|
|
CloseVlanConfigProtocol (Handle);
|
|
}
|
|
|
|
FreePool (Name);
|
|
}
|
|
|
|
/**
|
|
Remove a VLAN device.
|
|
|
|
@param[in] ParamStr Parameter string from user input.
|
|
|
|
**/
|
|
VOID
|
|
DeleteVlan (
|
|
IN CHAR16 *ParamStr
|
|
)
|
|
{
|
|
CHAR16 *Name;
|
|
CHAR16 *VlanIdStr;
|
|
CHAR16 *StrPtr;
|
|
UINTN VlanId;
|
|
EFI_HANDLE Handle;
|
|
EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
|
|
EFI_STATUS Status;
|
|
UINT16 NumberOfVlan;
|
|
EFI_VLAN_FIND_DATA *VlanData;
|
|
|
|
VlanConfig = NULL;
|
|
|
|
if (ParamStr == NULL) {
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_IF), mHiiHandle);
|
|
return;
|
|
}
|
|
|
|
StrPtr = AllocateCopyPool (StrSize (ParamStr), ParamStr);
|
|
if (StrPtr == NULL) {
|
|
return;
|
|
}
|
|
|
|
Name = StrPtr;
|
|
VlanIdStr = NULL;
|
|
while (*StrPtr != 0) {
|
|
if (*StrPtr == L'.') {
|
|
*StrPtr = 0;
|
|
VlanIdStr = StrPtr + 1;
|
|
break;
|
|
}
|
|
|
|
StrPtr++;
|
|
}
|
|
|
|
Handle = NicNameToHandle (Name);
|
|
if (Handle == NULL) {
|
|
goto Exit;
|
|
}
|
|
|
|
VlanConfig = OpenVlanConfigProtocol (Handle);
|
|
if (VlanConfig == NULL) {
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// Check VLAN ID
|
|
//
|
|
if ((VlanIdStr == NULL) || (*VlanIdStr == 0)) {
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_VID), mHiiHandle);
|
|
goto Exit;
|
|
}
|
|
|
|
VlanId = StrToVlanId (VlanIdStr);
|
|
if (VlanId > 4094) {
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_INVALID_VID), mHiiHandle, VlanIdStr);
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// Delete VLAN.
|
|
//
|
|
Status = VlanConfig->Remove (VlanConfig, (UINT16)VlanId);
|
|
if (EFI_ERROR (Status)) {
|
|
if (Status == EFI_NOT_FOUND) {
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NOT_FOUND), mHiiHandle);
|
|
} else {
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_REMOVE_FAIL), mHiiHandle, Status);
|
|
}
|
|
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// Check whether this is the last VLAN to remove.
|
|
//
|
|
Status = VlanConfig->Find (VlanConfig, NULL, &NumberOfVlan, &VlanData);
|
|
if (EFI_ERROR (Status)) {
|
|
//
|
|
// This is the last VLAN to remove, try to connect the controller handle.
|
|
//
|
|
gBS->ConnectController (Handle, NULL, NULL, TRUE);
|
|
} else {
|
|
FreePool (VlanData);
|
|
}
|
|
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_REMOVE_SUCCESS), mHiiHandle);
|
|
|
|
Exit:
|
|
if (VlanConfig != NULL) {
|
|
CloseVlanConfigProtocol (Handle);
|
|
}
|
|
|
|
FreePool (Name);
|
|
}
|
|
|
|
/**
|
|
The actual entry point for the application.
|
|
|
|
@param[in] ImageHandle The firmware allocated handle for the EFI image.
|
|
@param[in] SystemTable A pointer to the EFI System Table.
|
|
|
|
@retval EFI_SUCCESS The entry point executed successfully.
|
|
@retval other Some error occur when executing this entry point.
|
|
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
VlanConfigMain (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
LIST_ENTRY *List;
|
|
CONST CHAR16 *Str;
|
|
EFI_HII_PACKAGE_LIST_HEADER *PackageList;
|
|
EFI_STATUS Status;
|
|
|
|
mImageHandle = ImageHandle;
|
|
|
|
//
|
|
// Retrieve HII package list from ImageHandle
|
|
//
|
|
Status = gBS->OpenProtocol (
|
|
ImageHandle,
|
|
&gEfiHiiPackageListProtocolGuid,
|
|
(VOID **)&PackageList,
|
|
ImageHandle,
|
|
NULL,
|
|
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Publish HII package list to HII Database.
|
|
//
|
|
Status = gHiiDatabase->NewPackageList (
|
|
gHiiDatabase,
|
|
PackageList,
|
|
NULL,
|
|
&mHiiHandle
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if (mHiiHandle == NULL) {
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
List = NULL;
|
|
ShellCommandLineParseEx (mParamList, &List, NULL, FALSE, FALSE);
|
|
if (List == NULL) {
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_ARG), mHiiHandle);
|
|
goto Exit;
|
|
}
|
|
|
|
if (ShellCommandLineGetFlag (List, L"-l")) {
|
|
Str = ShellCommandLineGetValue (List, L"-l");
|
|
DisplayVlan ((CHAR16 *)Str);
|
|
goto Exit;
|
|
}
|
|
|
|
if (ShellCommandLineGetFlag (List, L"-a")) {
|
|
Str = ShellCommandLineGetValue (List, L"-a");
|
|
AddVlan ((CHAR16 *)Str);
|
|
goto Exit;
|
|
}
|
|
|
|
if (ShellCommandLineGetFlag (List, L"-d")) {
|
|
Str = ShellCommandLineGetValue (List, L"-d");
|
|
DeleteVlan ((CHAR16 *)Str);
|
|
goto Exit;
|
|
}
|
|
|
|
//
|
|
// No valid argument till now.
|
|
//
|
|
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_ARG), mHiiHandle);
|
|
|
|
Exit:
|
|
if (List != NULL) {
|
|
ShellCommandLineFreeVarList (List);
|
|
}
|
|
|
|
//
|
|
// Remove our string package from HII database.
|
|
//
|
|
HiiRemovePackages (mHiiHandle);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|