From: Marcin Wojtas <mw@semihalf.com>
To: edk2-devel@lists.01.org
Cc: feng.tian@intel.com, michael.d.kinney@intel.com,
liming.gao@intel.com, leif.lindholm@linaro.org, mw@semihalf.com,
jsd@semihalf.com, bsz@semihalf.com
Subject: [PATCH 1/2] MdeModulePkg: NetLib: introduce MAC address handling helper routines
Date: Fri, 4 Nov 2016 19:28:42 +0100 [thread overview]
Message-ID: <1478284123-4355-2-git-send-email-mw@semihalf.com> (raw)
In-Reply-To: <1478284123-4355-1-git-send-email-mw@semihalf.com>
This patch introduces three functions that can be used for handling
MAC address update. It's also a preparation commit for adding support
for this feature using 'ifconfig' shell command. New functions are as
following:
* NetLibSetMacAddress - locate simple network protocol associated with the
Service Binding Handle and try to update/reset the MAC address from SNP,
using Snp->StationAddress() callback.
* NetLibStrToMac - convert one Null-terminated Unicode string to
EFI_MAC_ADDRESS format.
* NetLibAsciiStrToMac - convert one Null-terminated ASCII string to
EFI_MAC_ADDRESS format.
* NetLibReconnectInterface - reconnect the service handle. When called
after NetLibSetMacAddress() it allows for updating associated
protocols with new MAC address information.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
---
MdeModulePkg/Include/Library/NetLib.h | 83 ++++++++++++
MdeModulePkg/Library/DxeNetLib/DxeNetLib.c | 196 +++++++++++++++++++++++++++++
2 files changed, 279 insertions(+)
diff --git a/MdeModulePkg/Include/Library/NetLib.h b/MdeModulePkg/Include/Library/NetLib.h
index 26709af..7a50f9c 100644
--- a/MdeModulePkg/Include/Library/NetLib.h
+++ b/MdeModulePkg/Include/Library/NetLib.h
@@ -523,6 +523,9 @@ extern IP4_ADDR gIp4AllMasks[IP4_MASK_NUM];
extern EFI_IPv4_ADDRESS mZeroIp4Addr;
#define NET_IS_DIGIT(Ch) (('0' <= (Ch)) && ((Ch) <= '9'))
+#define NET_IS_HEX(Ch) ((('0' <= (Ch)) && ((Ch) <= '9')) || \
+ (('A' <= (Ch)) && ((Ch) <= 'F')) || \
+ (('a' <= (Ch)) && ((Ch) <= 'f')))
#define NET_ROUNDUP(size, unit) (((size) + (unit) - 1) & (~((unit) - 1)))
#define NET_IS_LOWER_CASE_CHAR(Ch) (('a' <= (Ch)) && ((Ch) <= 'z'))
#define NET_IS_UPPER_CASE_CHAR(Ch) (('A' <= (Ch)) && ((Ch) <= 'Z'))
@@ -1180,6 +1183,49 @@ NetLibGetMacAddress (
);
/**
+ Update or reset MAC address associated with the network service handle.
+
+ Locate simple network protocol associated with the Service Binding Handle and
+ try to update/reset the mac address from SNP, using Snp->StationAddress().
+
+ @param[in] ServiceHandle The handle where network service binding protocols are
+ installed on.
+ @param[in] MacAddress The pointer with new MAC address.
+ @param[in] AddressSize The length of set MAC address.
+ @param[in] Reset Reset MAC address to initial settings.
+
+ @retval EFI_SUCCESS MAC address was updated/reset successfully.
+ @retval Others Failed to set SNP MAC address.
+
+**/
+EFI_STATUS
+EFIAPI
+NetLibSetMacAddress (
+ IN EFI_HANDLE ServiceHandle,
+ IN EFI_MAC_ADDRESS *MacAddress,
+ IN UINT32 AddressSize,
+ IN BOOLEAN Reset
+ );
+
+/**
+ Reconnect the network service handle.
+
+ Reconnect Service Binding Handle using Boot Services Dis/ConnectController() routines.
+
+ @param[in] ServiceHandle The handle where network service binding protocols are
+ installed on.
+
+ @retval EFI_SUCCESS Interface handle was reconnected successfully.
+ @retval Others Failed to reconnect interface handle.
+
+**/
+EFI_STATUS
+EFIAPI
+NetLibReconnectInterface (
+ IN EFI_HANDLE ServiceHandle
+ );
+
+/**
Convert MAC address of the NIC associated with specified Service Binding Handle
to a unicode string. Callers are responsible for freeing the string storage.
@@ -1348,6 +1394,24 @@ NetLibDefaultUnload (
);
/**
+ Convert one Null-terminated ASCII string to EFI_MAC_ADDRESS. The format of
+ the string has to be compliant with colon-separated EUI-48.
+
+ @param[in] String The pointer to the Ascii string.
+ @param[out] MacAddress The pointer to the converted MAC address.
+
+ @retval EFI_SUCCESS Converted to an MAC address successfully.
+ @retval EFI_INVALID_PARAMETER The string is malformated, or MacAddress is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+NetLibAsciiStrToMac (
+ IN CONST CHAR8 *String,
+ OUT EFI_MAC_ADDRESS *MacAddress
+ );
+
+/**
Convert one Null-terminated ASCII string (decimal dotted) to EFI_IPv4_ADDRESS.
@param[in] String The pointer to the Ascii string.
@@ -1383,6 +1447,25 @@ NetLibAsciiStrToIp6 (
);
/**
+ Convert one Null-terminated Unicode string to EFI_MAC_ADDRESS. The format of
+ the string has to be compliant with colon-separated EUI-48.
+
+ @param[in] String The pointer to the Ascii string.
+ @param[out] MacAddress The pointer to the converted MAC address.
+
+ @retval EFI_SUCCESS Converted to an MAC address successfully.
+ @retval EFI_INVALID_PARAMETER The string is mal-formated or MacAddress is NULL.
+ @retval EFI_OUT_OF_RESOURCES Failed to perform the operation due to lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+NetLibStrToMac (
+ IN CONST CHAR16 *String,
+ OUT EFI_MAC_ADDRESS *MacAddress
+ );
+
+/**
Convert one Null-terminated Unicode string (decimal dotted) to EFI_IPv4_ADDRESS.
@param[in] String The pointer to the Ascii string.
diff --git a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c b/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
index 04d8345..f9ed863 100644
--- a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
+++ b/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
@@ -2189,6 +2189,90 @@ NetLibGetMacAddress (
}
/**
+ Update or reset MAC address associated with the network service handle.
+
+ Locate simple network protocol associated with the Service Binding Handle and
+ try to update/reset the mac address from SNP, using Snp->StationAddress().
+
+ @param[in] ServiceHandle The handle where network service binding protocols are
+ installed on.
+ @param[in] MacAddress The pointer with new MAC address.
+ @param[in] AddressSize The length of set MAC address.
+ @param[in] Reset Reset MAC address to initial settings.
+
+ @retval EFI_SUCCESS MAC address was updated/reset successfully.
+ @retval Others Failed to set SNP MAC address.
+
+**/
+EFI_STATUS
+EFIAPI
+NetLibSetMacAddress (
+ IN EFI_HANDLE ServiceHandle,
+ IN EFI_MAC_ADDRESS *MacAddress,
+ IN UINT32 AddressSize,
+ IN BOOLEAN Reset
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
+ EFI_HANDLE *SnpHandle;
+
+ ASSERT (AddressSize == NET_ETHER_ADDR_LEN);
+
+ //
+ // Get SNP handle
+ //
+ Snp = NULL;
+ SnpHandle = NetLibGetSnpHandle (ServiceHandle, &Snp);
+
+ if (SnpHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!Snp->StationAddress) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Invoke Snp->StationAddress()
+ //
+ Status = Snp->StationAddress (Snp, Reset, MacAddress);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Reconnect the network service handle.
+
+ Reconnect Service Binding Handle using Boot Services Dis/ConnectController() routines.
+
+ @param[in] ServiceHandle The handle where network service binding protocols are
+ installed on.
+
+ @retval EFI_SUCCESS Interface handle was reconnected successfully.
+ @retval Others Failed to reconnect interface handle.
+
+**/
+EFI_STATUS
+EFIAPI
+NetLibReconnectInterface (
+ IN EFI_HANDLE ServiceHandle
+ )
+{
+ EFI_STATUS Status;
+
+ Status = gBS->DisconnectController(ServiceHandle, NULL, NULL);
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->ConnectController(ServiceHandle, NULL, NULL, TRUE);
+ }
+
+ return Status;
+}
+
+/**
Convert MAC address of the NIC associated with specified Service Binding Handle
to a unicode string. Callers are responsible for freeing the string storage.
@@ -2693,6 +2777,76 @@ NetLibGetNicHandle (
}
/**
+ Convert one Null-terminated ASCII string to EFI_MAC_ADDRESS. The format of
+ the string has to be compliant with colon-separated EUI-48.
+
+ @param[in] String The pointer to the Ascii string.
+ @param[out] MacAddress The pointer to the converted MAC address.
+
+ @retval EFI_SUCCESS Convert to MAC address successfully.
+ @retval EFI_INVALID_PARAMETER The string is mal-formated or MacAddress is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+NetLibAsciiStrToMac (
+ IN CONST CHAR8 *String,
+ OUT EFI_MAC_ADDRESS *MacAddress
+ )
+{
+ UINT8 Index;
+ CHAR8 *MacStr;
+ CHAR8 *TempStr;
+ UINTN NodeVal;
+
+ if ((String == NULL) || (MacAddress == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ MacStr = (CHAR8 *) String;
+
+ for (Index = 0; Index < 6; Index++) {
+ TempStr = MacStr;
+
+ while ((*MacStr != '\0') && (*MacStr != ':')) {
+ if (!NET_IS_HEX (*MacStr)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ MacStr++;
+ }
+
+ //
+ // The MAC address is X:X:X:X:X:X
+ //
+ if (*MacStr == ':') {
+ if (Index == 5) {
+ return EFI_INVALID_PARAMETER;
+ }
+ } else {
+ if (Index != 5) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ //
+ // Convert the string to MAC address. AsciiStrHexToUintn stops at the
+ // first character that is not a valid hexadecimal character,
+ // ':' or '\0' here.
+ //
+ NodeVal = AsciiStrHexToUintn (TempStr);
+ if (NodeVal > 0xFF) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ MacAddress->Addr[Index] = (UINT8) NodeVal;
+
+ MacStr++;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
Convert one Null-terminated ASCII string (decimal dotted) to EFI_IPv4_ADDRESS.
@param[in] String The pointer to the Ascii string.
@@ -2957,6 +3111,48 @@ NetLibAsciiStrToIp6 (
return EFI_SUCCESS;
}
+/**
+ Convert one Null-terminated Unicode string to EFI_MAC_ADDRESS. The format of
+ the string has to be compliant with colon-separated EUI-48.
+
+ @param[in] String The pointer to the Ascii string.
+ @param[out] MacAddress The pointer to the converted MAC address.
+
+ @retval EFI_SUCCESS Convert to MAC address successfully.
+ @retval EFI_INVALID_PARAMETER The string is mal-formated or MacAddress is NULL.
+ @retval EFI_OUT_OF_RESOURCES Fail to perform the operation due to lack of resource.
+
+**/
+EFI_STATUS
+EFIAPI
+NetLibStrToMac (
+ IN CONST CHAR16 *String,
+ OUT EFI_MAC_ADDRESS *MacAddress
+ )
+{
+ CHAR8 *MacStr;
+ UINTN StringSize;
+ EFI_STATUS Status;
+
+ if ((String == NULL) || (MacAddress == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ StringSize = StrLen (String) + 1;
+ MacStr = (CHAR8 *) AllocatePool (StringSize * sizeof (CHAR8));
+ if (MacStr == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ UnicodeStrToAsciiStrS (String, MacStr, StringSize);
+
+ Status = NetLibAsciiStrToMac (MacStr, MacAddress);
+
+ FreePool (MacStr);
+
+ return Status;
+}
+
/**
Convert one Null-terminated Unicode string (decimal dotted) to EFI_IPv4_ADDRESS.
--
1.8.3.1
next prev parent reply other threads:[~2016-11-04 18:27 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-04 18:28 [PATCH 0/2] MAC address configuration from Shell Marcin Wojtas
2016-11-04 18:28 ` Marcin Wojtas [this message]
2016-11-04 18:28 ` [PATCH 2/2] ShellPkg/Ifconfig: Enable setting MAC address Marcin Wojtas
2016-11-04 20:38 ` Carsey, Jaben
2016-11-07 11:54 ` Marcin Wojtas
2016-11-07 18:16 ` Carsey, Jaben
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1478284123-4355-2-git-send-email-mw@semihalf.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox