aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorHeinrich Schuchardt <xypron.glpk@gmx.de>2019-09-01 17:17:53 +0200
committerHeinrich Schuchardt <xypron.glpk@gmx.de>2019-09-05 23:18:51 +0200
commit5b4746fd6be68bb0b773d9830275fbee7dbdab66 (patch)
treefa8be5f68a4ed4f696f4ece2910731fdc264c869 /lib
parent72a8f1685a3fece42b6dd31e41be613bf80352e4 (diff)
downloadu-boot-5b4746fd6be68bb0b773d9830275fbee7dbdab66.zip
u-boot-5b4746fd6be68bb0b773d9830275fbee7dbdab66.tar.gz
u-boot-5b4746fd6be68bb0b773d9830275fbee7dbdab66.tar.bz2
efi_loader: implement MCastIPtoMAC
Implement the MCastIPtoMAC service of the simple network protocol. It converts an multicast IPv4 (or IPv6) address to a multicast Ethernet address. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Diffstat (limited to 'lib')
-rw-r--r--lib/efi_loader/efi_net.c44
1 files changed, 42 insertions, 2 deletions
diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c
index 66c1898..cff6332 100644
--- a/lib/efi_loader/efi_net.c
+++ b/lib/efi_loader/efi_net.c
@@ -332,7 +332,7 @@ static efi_status_t EFIAPI efi_net_statistics(struct efi_simple_network *this,
/*
* efi_net_mcastiptomac() - translate multicast IP address to MAC address
*
- * This function implements the Statistics service of the
+ * This function implements the MCastIPtoMAC service of the
* EFI_SIMPLE_NETWORK_PROTOCOL. See the Unified Extensible Firmware Interface
* (UEFI) specification for details.
*
@@ -347,9 +347,49 @@ static efi_status_t EFIAPI efi_net_mcastiptomac(struct efi_simple_network *this,
struct efi_ip_address *ip,
struct efi_mac_address *mac)
{
+ efi_status_t ret = EFI_SUCCESS;
+
EFI_ENTRY("%p, %x, %p, %p", this, ipv6, ip, mac);
- return EFI_EXIT(EFI_INVALID_PARAMETER);
+ if (!this || !ip || !mac) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+
+ if (ipv6) {
+ ret = EFI_UNSUPPORTED;
+ goto out;
+ }
+
+ /* Multi-cast addresses are in the range 224.0.0.0 - 239.255.255.255 */
+ if ((ip->ip_addr[0] & 0xf0) != 0xe0) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ };
+
+ switch (this->mode->state) {
+ case EFI_NETWORK_INITIALIZED:
+ case EFI_NETWORK_STARTED:
+ break;
+ default:
+ ret = EFI_NOT_STARTED;
+ goto out;
+ }
+
+ memset(mac, 0, sizeof(struct efi_mac_address));
+
+ /*
+ * Copy lower 23 bits of IPv4 multi-cast address
+ * RFC 1112, RFC 7042 2.1.1.
+ */
+ mac->mac_addr[0] = 0x01;
+ mac->mac_addr[1] = 0x00;
+ mac->mac_addr[2] = 0x5E;
+ mac->mac_addr[3] = ip->ip_addr[1] & 0x7F;
+ mac->mac_addr[4] = ip->ip_addr[2];
+ mac->mac_addr[5] = ip->ip_addr[3];
+out:
+ return EFI_EXIT(ret);
}
/**