diff options
author | Heinrich Schuchardt <xypron.glpk@gmx.de> | 2019-08-31 10:55:29 +0200 |
---|---|---|
committer | Heinrich Schuchardt <xypron.glpk@gmx.de> | 2019-09-05 23:18:51 +0200 |
commit | 5947b49b091c016a2031c9f8b476f249e31eb125 (patch) | |
tree | e0081e04210d97494c70a9ad2ccb374d7617ab0a | |
parent | 0c7adf4b5face7f7efcc41cc8b23852edbc1b6db (diff) |
efi_loader: EFI_SIMPLE_NETWORK.Transmit() fill header
Fill the media header in EFI_SIMPLE_NETWORK.Transmit().
Check that the buffer size is large enough for the header.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
-rw-r--r-- | lib/efi_loader/efi_net.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c index bf6d5ab0b3..950b6ed4b2 100644 --- a/lib/efi_loader/efi_net.c +++ b/lib/efi_loader/efi_net.c @@ -409,15 +409,33 @@ static efi_status_t EFIAPI efi_net_transmit goto out; } - if (header_size) { - /* - * TODO: We would need to create the header - * if header_size != 0 - */ - ret = EFI_UNSUPPORTED; + /* At least the IP header has to fit into the buffer */ + if (buffer_size < this->mode->media_header_size) { + ret = EFI_BUFFER_TOO_SMALL; goto out; } + /* + * TODO: + * Support VLANs. Use net_set_ether() for copying the header. Use a + * U_BOOT_ENV_CALLBACK to update the media header size. + */ + if (header_size) { + struct ethernet_hdr *header = buffer; + + if (!dest_addr || !protocol || + header_size != this->mode->media_header_size) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + if (!src_addr) + src_addr = &this->mode->current_address; + + memcpy(header->et_dest, dest_addr, ARP_HLEN); + memcpy(header->et_src, src_addr, ARP_HLEN); + header->et_protlen = htons(*protocol); + } + switch (this->mode->state) { case EFI_NETWORK_STOPPED: ret = EFI_NOT_STARTED; @@ -764,6 +782,7 @@ efi_status_t efi_net_register(void) netobj->net_mode.state = EFI_NETWORK_STARTED; memcpy(netobj->net_mode.current_address.mac_addr, eth_get_ethaddr(), 6); netobj->net_mode.hwaddr_size = ARP_HLEN; + netobj->net_mode.media_header_size = ETHER_HDR_SIZE; netobj->net_mode.max_packet_size = PKTSIZE; netobj->net_mode.if_type = ARP_ETHER; |