summaryrefslogtreecommitdiff
path: root/lib/efi_loader/efi_net.c
diff options
context:
space:
mode:
authorHeinrich Schuchardt <xypron.glpk@gmx.de>2019-08-31 10:55:29 +0200
committerHeinrich Schuchardt <xypron.glpk@gmx.de>2019-09-05 23:18:51 +0200
commit5947b49b091c016a2031c9f8b476f249e31eb125 (patch)
treee0081e04210d97494c70a9ad2ccb374d7617ab0a /lib/efi_loader/efi_net.c
parent0c7adf4b5face7f7efcc41cc8b23852edbc1b6db (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>
Diffstat (limited to 'lib/efi_loader/efi_net.c')
-rw-r--r--lib/efi_loader/efi_net.c31
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;