From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-x22b.google.com (mail-wm0-x22b.google.com [IPv6:2a00:1450:400c:c09::22b]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id B3ABA81CDC for ; Fri, 4 Nov 2016 11:27:47 -0700 (PDT) Received: by mail-wm0-x22b.google.com with SMTP id p190so68139716wmp.1 for ; Fri, 04 Nov 2016 11:27:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=93h5v2W4sX+rio5/rLCXsjy2JhSpunQVdZ603Ynncsw=; b=W7rfrJAC2yakA8I5x6yzU4RC0DsfBhK49aY2IxkO3PCTb6xsPf5qyHMgZSCRHVchRr epvbCqR84PJ8Snwrkxh1jd+W45TttnwkFS2OuEjAz3L+7ORkem7LOP/+DvALu7lYJ4aG a5WKsepdAztwMAu3eeK4dCkYJsZUvYGGuA69k49rdzqG+gTPVOkg7sfDb9zmrKDq9TM3 GyLINxD8EGs2NZk13EEWWjjwKtY3aGtAc3DkcFyl/UfQjeW6CyngytgVE3mWeHFlg5GC xedP0tITEfWX9vKPx82uue1o+4+UHGVnDlDEW9bXYat/FgZmv/isd+FQkOhnY5SB8MNM WhDg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=93h5v2W4sX+rio5/rLCXsjy2JhSpunQVdZ603Ynncsw=; b=LAlc1BhuxT/p9TeKELqtiXxAoJmvXqYYwJQWC6sPmRYezT6rPfne62QY9I023LEtRI 5Rw7MWF8JL+dyi0x+NZJK54r2ZHD0UH6OAUMccIJvFlhEbNLwl7nIslpeng+1+xyxjTL S9B5UZYrXB+yiCGBNNbJvG0zK/0LALj8HGoHItU146sDF68Lh1g/dbn5VyOrPaE4eAuy j/b5yVYo+YR7vE4XQvIx4BIx1T+0A+0CD9YR/DGDAAbcanb15ul5gr+IsF61IRO5CSVy vHJJF2ElyJOHdIl6BKgtfAeWTOlH3p2nszLQRF8urb4OsFXv0bTJMAxZ6QHhxUmfnt4b VUGQ== X-Gm-Message-State: ABUngvfHeJ/q0jZIsTntxrsv7GNFrj/fPh/vGAtKZTtHzSIsUKjtjizvHiwqJLBNLSWC/g== X-Received: by 10.194.111.102 with SMTP id ih6mr12905555wjb.214.1478284068375; Fri, 04 Nov 2016 11:27:48 -0700 (PDT) Received: from enkidu.semihalf.local (31-172-191-173.noc.fibertech.net.pl. [31.172.191.173]) by smtp.gmail.com with ESMTPSA id jb2sm15552903wjb.44.2016.11.04.11.27.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 04 Nov 2016 11:27:47 -0700 (PDT) From: Marcin Wojtas 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 Date: Fri, 4 Nov 2016 19:28:42 +0100 Message-Id: <1478284123-4355-2-git-send-email-mw@semihalf.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1478284123-4355-1-git-send-email-mw@semihalf.com> References: <1478284123-4355-1-git-send-email-mw@semihalf.com> Subject: [PATCH 1/2] MdeModulePkg: NetLib: introduce MAC address handling helper routines X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 04 Nov 2016 18:27:48 -0000 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 --- 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