diff options
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/NetworkPkg/SnpDxe/Mcast_ip_to_mac.c')
-rw-r--r-- | src/VBox/Devices/EFI/Firmware/NetworkPkg/SnpDxe/Mcast_ip_to_mac.c | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/NetworkPkg/SnpDxe/Mcast_ip_to_mac.c b/src/VBox/Devices/EFI/Firmware/NetworkPkg/SnpDxe/Mcast_ip_to_mac.c new file mode 100644 index 00000000..e69a5107 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/NetworkPkg/SnpDxe/Mcast_ip_to_mac.c @@ -0,0 +1,173 @@ +/** @file + Implementation of converting an multicast IP address to multicast HW MAC + address. + +Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR> +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "Snp.h" + +/** + Call undi to convert an multicast IP address to a MAC address. + + @param Snp Pointer to snp driver structure. + @param IPv6 Flag to indicate if this is an ipv6 address. + @param IP Multicast IP address. + @param MAC Pointer to hold the return MAC address. + + @retval EFI_SUCCESS The multicast IP address was mapped to the + multicast HW MAC address. + @retval EFI_INVALID_PARAMETER Invalid UNDI command. + @retval EFI_UNSUPPORTED Command is not supported by UNDI. + @retval EFI_DEVICE_ERROR Fail to execute UNDI command. + +**/ +EFI_STATUS +PxeIp2Mac ( + IN SNP_DRIVER *Snp, + IN BOOLEAN IPv6, + IN EFI_IP_ADDRESS *IP, + IN OUT EFI_MAC_ADDRESS *MAC + ) +{ + PXE_CPB_MCAST_IP_TO_MAC *Cpb; + PXE_DB_MCAST_IP_TO_MAC *Db; + + Cpb = Snp->Cpb; + Db = Snp->Db; + Snp->Cdb.OpCode = PXE_OPCODE_MCAST_IP_TO_MAC; + Snp->Cdb.OpFlags = (UINT16) (IPv6 ? PXE_OPFLAGS_MCAST_IPV6_TO_MAC : PXE_OPFLAGS_MCAST_IPV4_TO_MAC); + Snp->Cdb.CPBsize = (UINT16) sizeof (PXE_CPB_MCAST_IP_TO_MAC); + Snp->Cdb.DBsize = (UINT16) sizeof (PXE_DB_MCAST_IP_TO_MAC); + + Snp->Cdb.CPBaddr = (UINT64)(UINTN) Cpb; + Snp->Cdb.DBaddr = (UINT64)(UINTN) Db; + + Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE; + Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE; + Snp->Cdb.IFnum = Snp->IfNum; + Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST; + + CopyMem (&Cpb->IP, IP, sizeof (PXE_IP_ADDR)); + + // + // Issue UNDI command and check result. + // + DEBUG ((EFI_D_NET, "\nSnp->undi.mcast_ip_to_mac() ")); + + (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb); + + switch (Snp->Cdb.StatCode) { + case PXE_STATCODE_SUCCESS: + break; + + case PXE_STATCODE_INVALID_CPB: + return EFI_INVALID_PARAMETER; + + case PXE_STATCODE_UNSUPPORTED: + DEBUG ( + (EFI_D_NET, + "\nSnp->undi.mcast_ip_to_mac() %xh:%xh\n", + Snp->Cdb.StatFlags, + Snp->Cdb.StatCode) + ); + return EFI_UNSUPPORTED; + + default: + // + // UNDI command failed. Return EFI_DEVICE_ERROR + // to caller. + // + DEBUG ( + (EFI_D_NET, + "\nSnp->undi.mcast_ip_to_mac() %xh:%xh\n", + Snp->Cdb.StatFlags, + Snp->Cdb.StatCode) + ); + + return EFI_DEVICE_ERROR; + } + + CopyMem (MAC, &Db->MAC, sizeof (PXE_MAC_ADDR)); + return EFI_SUCCESS; +} + + +/** + Converts a multicast IP address to a multicast HW MAC address. + + This function converts a multicast IP address to a multicast HW MAC address + for all packet transactions. If the mapping is accepted, then EFI_SUCCESS will + be returned. + + @param This A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance. + @param IPv6 Set to TRUE if the multicast IP address is IPv6 [RFC 2460]. + Set to FALSE if the multicast IP address is IPv4 [RFC 791]. + @param IP The multicast IP address that is to be converted to a multicast + HW MAC address. + @param MAC The multicast HW MAC address that is to be generated from IP. + + @retval EFI_SUCCESS The multicast IP address was mapped to the + multicast HW MAC address. + @retval EFI_NOT_STARTED The Simple Network Protocol interface has not + been started by calling Start(). + @retval EFI_INVALID_PARAMETER IP is NULL. + @retval EFI_INVALID_PARAMETER MAC is NULL. + @retval EFI_INVALID_PARAMETER IP does not point to a valid IPv4 or IPv6 + multicast address. + @retval EFI_DEVICE_ERROR The Simple Network Protocol interface has not + been initialized by calling Initialize(). + @retval EFI_UNSUPPORTED IPv6 is TRUE and the implementation does not + support IPv6 multicast to MAC address conversion. + +**/ +EFI_STATUS +EFIAPI +SnpUndi32McastIpToMac ( + IN EFI_SIMPLE_NETWORK_PROTOCOL *This, + IN BOOLEAN IPv6, + IN EFI_IP_ADDRESS *IP, + OUT EFI_MAC_ADDRESS *MAC + ) +{ + SNP_DRIVER *Snp; + EFI_TPL OldTpl; + EFI_STATUS Status; + + // + // Get pointer to SNP driver instance for *this. + // + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (IP == NULL || MAC == NULL) { + return EFI_INVALID_PARAMETER; + } + + Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This); + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + switch (Snp->Mode.State) { + case EfiSimpleNetworkInitialized: + break; + + case EfiSimpleNetworkStopped: + Status = EFI_NOT_STARTED; + goto ON_EXIT; + + default: + Status = EFI_DEVICE_ERROR; + goto ON_EXIT; + } + + Status = PxeIp2Mac (Snp, IPv6, IP, MAC); + +ON_EXIT: + gBS->RestoreTPL (OldTpl); + + return Status; +} |