123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- /** @file
- Implementation of the SNP.McastIpToMac() function and its private helpers if
- any.
- Copyright (C) 2013, Red Hat, Inc.
- Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <Library/UefiBootServicesTableLib.h>
- #include "VirtioNet.h"
- /**
- Converts a multicast IP address to a multicast HW MAC address.
- @param This The protocol instance pointer.
- @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 network interface has not been started.
- @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The
- current buffer size needed to hold the
- statistics is returned in StatisticsSize.
- @retval EFI_INVALID_PARAMETER One or more of the parameters has an
- unsupported value.
- @retval EFI_DEVICE_ERROR The command could not be sent to the network
- interface.
- @retval EFI_UNSUPPORTED This function is not supported by the network
- interface.
- **/
- EFI_STATUS
- EFIAPI
- VirtioNetMcastIpToMac (
- IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
- IN BOOLEAN IPv6,
- IN EFI_IP_ADDRESS *Ip,
- OUT EFI_MAC_ADDRESS *Mac
- )
- {
- VNET_DEV *Dev;
- EFI_TPL OldTpl;
- EFI_STATUS Status;
- //
- // http://en.wikipedia.org/wiki/Multicast_address
- //
- if ((This == NULL) || (Ip == NULL) || (Mac == NULL) ||
- (IPv6 && ((Ip->v6.Addr[0]) != 0xFF)) || // invalid IPv6 mcast addr
- (!IPv6 && ((Ip->v4.Addr[0] & 0xF0) != 0xE0)) // invalid IPv4 mcast addr
- )
- {
- return EFI_INVALID_PARAMETER;
- }
- Dev = VIRTIO_NET_FROM_SNP (This);
- OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
- switch (Dev->Snm.State) {
- case EfiSimpleNetworkStopped:
- Status = EFI_NOT_STARTED;
- goto Exit;
- case EfiSimpleNetworkStarted:
- Status = EFI_DEVICE_ERROR;
- goto Exit;
- default:
- break;
- }
- //
- // http://en.wikipedia.org/wiki/IP_multicast#Layer_2_delivery
- //
- if (IPv6) {
- Mac->Addr[0] = 0x33;
- Mac->Addr[1] = 0x33;
- Mac->Addr[2] = Ip->v6.Addr[12];
- Mac->Addr[3] = Ip->v6.Addr[13];
- Mac->Addr[4] = Ip->v6.Addr[14];
- Mac->Addr[5] = Ip->v6.Addr[15];
- } else {
- Mac->Addr[0] = 0x01;
- Mac->Addr[1] = 0x00;
- Mac->Addr[2] = 0x5E;
- Mac->Addr[3] = Ip->v4.Addr[1] & 0x7F;
- Mac->Addr[4] = Ip->v4.Addr[2];
- Mac->Addr[5] = Ip->v4.Addr[3];
- }
- Status = EFI_SUCCESS;
- Exit:
- gBS->RestoreTPL (OldTpl);
- return Status;
- }
|