|
|
5593c8 |
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
5593c8 |
From: Andrzej Kacprowski <andrzej.kacprowski@intel.com>
|
|
|
5593c8 |
Date: Wed, 10 Jul 2019 15:22:29 +0200
|
|
|
5593c8 |
Subject: [PATCH] Add support for non-Ethernet network cards
|
|
|
5593c8 |
|
|
|
5593c8 |
This patch replaces fixed 6-byte link layer address with
|
|
|
5593c8 |
up to 32-byte variable sized address.
|
|
|
5593c8 |
This allows supporting Infiniband and Omni-Path fabric
|
|
|
5593c8 |
which use 20-byte address, but other network card types
|
|
|
5593c8 |
can also take advantage of this change.
|
|
|
5593c8 |
The network card driver is responsible for replacing L2
|
|
|
5593c8 |
header provided by grub2 if needed.
|
|
|
5593c8 |
This approach is compatible with UEFI network stack which
|
|
|
5593c8 |
also allows up to 32-byte variable size link address.
|
|
|
5593c8 |
|
|
|
5593c8 |
The BOOTP/DHCP packet format is limited to 16 byte client
|
|
|
5593c8 |
hardware address, if link address is more that 16-bytes
|
|
|
5593c8 |
then chaddr field in BOOTP it will be set to 0 as per rfc4390.
|
|
|
5593c8 |
|
|
|
5593c8 |
Resolves: rhbz#1370642
|
|
|
5593c8 |
|
|
|
5593c8 |
Signed-off-by: Andrzej Kacprowski <andrzej.kacprowski@intel.com>
|
|
|
5593c8 |
[msalter: Fix max string calculation in grub_net_hwaddr_to_str]
|
|
|
5593c8 |
Signed-off-by: Mark Salter <msalter@redhat.com>
|
|
|
5593c8 |
---
|
|
|
5593c8 |
grub-core/net/arp.c | 155 ++++++++++++++++++++++-----------
|
|
|
5593c8 |
grub-core/net/bootp.c | 15 ++--
|
|
|
5593c8 |
grub-core/net/drivers/efi/efinet.c | 8 +-
|
|
|
5593c8 |
grub-core/net/drivers/emu/emunet.c | 1 +
|
|
|
5593c8 |
grub-core/net/drivers/i386/pc/pxe.c | 13 +--
|
|
|
5593c8 |
grub-core/net/drivers/ieee1275/ofnet.c | 2 +
|
|
|
5593c8 |
grub-core/net/drivers/uboot/ubootnet.c | 1 +
|
|
|
5593c8 |
grub-core/net/ethernet.c | 88 +++++++++----------
|
|
|
5593c8 |
grub-core/net/icmp6.c | 15 ++--
|
|
|
5593c8 |
grub-core/net/ip.c | 4 +-
|
|
|
5593c8 |
grub-core/net/net.c | 50 ++++++-----
|
|
|
5593c8 |
include/grub/net.h | 19 ++--
|
|
|
5593c8 |
12 files changed, 219 insertions(+), 152 deletions(-)
|
|
|
5593c8 |
|
|
|
5593c8 |
diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c
|
|
|
5593c8 |
index 54306e3b16d..67b409a8acc 100644
|
|
|
5593c8 |
--- a/grub-core/net/arp.c
|
|
|
5593c8 |
+++ b/grub-core/net/arp.c
|
|
|
5593c8 |
@@ -31,22 +31,12 @@ enum
|
|
|
5593c8 |
ARP_REPLY = 2
|
|
|
5593c8 |
};
|
|
|
5593c8 |
|
|
|
5593c8 |
-enum
|
|
|
5593c8 |
- {
|
|
|
5593c8 |
- /* IANA ARP constant to define hardware type as ethernet. */
|
|
|
5593c8 |
- GRUB_NET_ARPHRD_ETHERNET = 1
|
|
|
5593c8 |
- };
|
|
|
5593c8 |
-
|
|
|
5593c8 |
-struct arppkt {
|
|
|
5593c8 |
+struct arphdr {
|
|
|
5593c8 |
grub_uint16_t hrd;
|
|
|
5593c8 |
grub_uint16_t pro;
|
|
|
5593c8 |
grub_uint8_t hln;
|
|
|
5593c8 |
grub_uint8_t pln;
|
|
|
5593c8 |
grub_uint16_t op;
|
|
|
5593c8 |
- grub_uint8_t sender_mac[6];
|
|
|
5593c8 |
- grub_uint32_t sender_ip;
|
|
|
5593c8 |
- grub_uint8_t recv_mac[6];
|
|
|
5593c8 |
- grub_uint32_t recv_ip;
|
|
|
5593c8 |
} GRUB_PACKED;
|
|
|
5593c8 |
|
|
|
5593c8 |
static int have_pending;
|
|
|
5593c8 |
@@ -57,12 +47,16 @@ grub_net_arp_send_request (struct grub_net_network_level_interface *inf,
|
|
|
5593c8 |
const grub_net_network_level_address_t *proto_addr)
|
|
|
5593c8 |
{
|
|
|
5593c8 |
struct grub_net_buff nb;
|
|
|
5593c8 |
- struct arppkt *arp_packet;
|
|
|
5593c8 |
+ struct arphdr *arp_header;
|
|
|
5593c8 |
grub_net_link_level_address_t target_mac_addr;
|
|
|
5593c8 |
grub_err_t err;
|
|
|
5593c8 |
int i;
|
|
|
5593c8 |
grub_uint8_t *nbd;
|
|
|
5593c8 |
grub_uint8_t arp_data[128];
|
|
|
5593c8 |
+ grub_uint8_t hln;
|
|
|
5593c8 |
+ grub_uint8_t pln;
|
|
|
5593c8 |
+ grub_uint8_t arp_packet_len;
|
|
|
5593c8 |
+ grub_uint8_t *tmp_ptr;
|
|
|
5593c8 |
|
|
|
5593c8 |
if (proto_addr->type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4)
|
|
|
5593c8 |
return grub_error (GRUB_ERR_BUG, "unsupported address family");
|
|
|
5593c8 |
@@ -73,23 +67,39 @@ grub_net_arp_send_request (struct grub_net_network_level_interface *inf,
|
|
|
5593c8 |
grub_netbuff_clear (&nb);
|
|
|
5593c8 |
grub_netbuff_reserve (&nb, 128);
|
|
|
5593c8 |
|
|
|
5593c8 |
- err = grub_netbuff_push (&nb, sizeof (*arp_packet));
|
|
|
5593c8 |
+ hln = inf->card->default_address.len;
|
|
|
5593c8 |
+ pln = sizeof (proto_addr->ipv4);
|
|
|
5593c8 |
+ arp_packet_len = sizeof (*arp_header) + 2 * (hln + pln);
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ err = grub_netbuff_push (&nb, arp_packet_len);
|
|
|
5593c8 |
if (err)
|
|
|
5593c8 |
return err;
|
|
|
5593c8 |
|
|
|
5593c8 |
- arp_packet = (struct arppkt *) nb.data;
|
|
|
5593c8 |
- arp_packet->hrd = grub_cpu_to_be16_compile_time (GRUB_NET_ARPHRD_ETHERNET);
|
|
|
5593c8 |
- arp_packet->hln = 6;
|
|
|
5593c8 |
- arp_packet->pro = grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP);
|
|
|
5593c8 |
- arp_packet->pln = 4;
|
|
|
5593c8 |
- arp_packet->op = grub_cpu_to_be16_compile_time (ARP_REQUEST);
|
|
|
5593c8 |
- /* Sender hardware address. */
|
|
|
5593c8 |
- grub_memcpy (arp_packet->sender_mac, &inf->hwaddress.mac, 6);
|
|
|
5593c8 |
- arp_packet->sender_ip = inf->address.ipv4;
|
|
|
5593c8 |
- grub_memset (arp_packet->recv_mac, 0, 6);
|
|
|
5593c8 |
- arp_packet->recv_ip = proto_addr->ipv4;
|
|
|
5593c8 |
- /* Target protocol address */
|
|
|
5593c8 |
- grub_memset (&target_mac_addr.mac, 0xff, 6);
|
|
|
5593c8 |
+ arp_header = (struct arphdr *) nb.data;
|
|
|
5593c8 |
+ arp_header->hrd = grub_cpu_to_be16 (inf->card->default_address.type);
|
|
|
5593c8 |
+ arp_header->hln = hln;
|
|
|
5593c8 |
+ arp_header->pro = grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP);
|
|
|
5593c8 |
+ arp_header->pln = pln;
|
|
|
5593c8 |
+ arp_header->op = grub_cpu_to_be16_compile_time (ARP_REQUEST);
|
|
|
5593c8 |
+ tmp_ptr = nb.data + sizeof (*arp_header);
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ /* The source hardware address. */
|
|
|
5593c8 |
+ grub_memcpy (tmp_ptr, inf->hwaddress.mac, hln);
|
|
|
5593c8 |
+ tmp_ptr += hln;
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ /* The source protocol address. */
|
|
|
5593c8 |
+ grub_memcpy (tmp_ptr, &inf->address.ipv4, pln);
|
|
|
5593c8 |
+ tmp_ptr += pln;
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ /* The target hardware address. */
|
|
|
5593c8 |
+ grub_memset (tmp_ptr, 0, hln);
|
|
|
5593c8 |
+ tmp_ptr += hln;
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ /* The target protocol address */
|
|
|
5593c8 |
+ grub_memcpy (tmp_ptr, &proto_addr->ipv4, pln);
|
|
|
5593c8 |
+ tmp_ptr += pln;
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ grub_memset (&target_mac_addr.mac, 0xff, hln);
|
|
|
5593c8 |
|
|
|
5593c8 |
nbd = nb.data;
|
|
|
5593c8 |
send_ethernet_packet (inf, &nb, target_mac_addr, GRUB_NET_ETHERTYPE_ARP);
|
|
|
5593c8 |
@@ -114,28 +124,53 @@ grub_err_t
|
|
|
5593c8 |
grub_net_arp_receive (struct grub_net_buff *nb, struct grub_net_card *card,
|
|
|
5593c8 |
grub_uint16_t *vlantag)
|
|
|
5593c8 |
{
|
|
|
5593c8 |
- struct arppkt *arp_packet = (struct arppkt *) nb->data;
|
|
|
5593c8 |
+ struct arphdr *arp_header = (struct arphdr *) nb->data;
|
|
|
5593c8 |
grub_net_network_level_address_t sender_addr, target_addr;
|
|
|
5593c8 |
grub_net_link_level_address_t sender_mac_addr;
|
|
|
5593c8 |
struct grub_net_network_level_interface *inf;
|
|
|
5593c8 |
+ grub_uint16_t hw_type;
|
|
|
5593c8 |
+ grub_uint8_t hln;
|
|
|
5593c8 |
+ grub_uint8_t pln;
|
|
|
5593c8 |
+ grub_uint8_t arp_packet_len;
|
|
|
5593c8 |
+ grub_uint8_t *tmp_ptr;
|
|
|
5593c8 |
|
|
|
5593c8 |
- if (arp_packet->pro != grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP)
|
|
|
5593c8 |
- || arp_packet->pln != 4 || arp_packet->hln != 6
|
|
|
5593c8 |
- || nb->tail - nb->data < (int) sizeof (*arp_packet))
|
|
|
5593c8 |
+ hw_type = card->default_address.type;
|
|
|
5593c8 |
+ hln = card->default_address.len;
|
|
|
5593c8 |
+ pln = sizeof(sender_addr.ipv4);
|
|
|
5593c8 |
+ arp_packet_len = sizeof (*arp_header) + 2 * (pln + hln);
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ if (arp_header->pro != grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP)
|
|
|
5593c8 |
+ || arp_header->hrd != grub_cpu_to_be16 (hw_type)
|
|
|
5593c8 |
+ || arp_header->hln != hln || arp_header->pln != pln
|
|
|
5593c8 |
+ || nb->tail - nb->data < (int) arp_packet_len) {
|
|
|
5593c8 |
return GRUB_ERR_NONE;
|
|
|
5593c8 |
+ }
|
|
|
5593c8 |
|
|
|
5593c8 |
+ tmp_ptr = nb->data + sizeof (*arp_header);
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ /* The source hardware address. */
|
|
|
5593c8 |
+ sender_mac_addr.type = hw_type;
|
|
|
5593c8 |
+ sender_mac_addr.len = hln;
|
|
|
5593c8 |
+ grub_memcpy (sender_mac_addr.mac, tmp_ptr, hln);
|
|
|
5593c8 |
+ tmp_ptr += hln;
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ /* The source protocol address. */
|
|
|
5593c8 |
sender_addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
|
|
|
5593c8 |
+ grub_memcpy(&sender_addr.ipv4, tmp_ptr, pln);
|
|
|
5593c8 |
+ tmp_ptr += pln;
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ grub_net_link_layer_add_address (card, &sender_addr, &sender_mac_addr, 1);
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ /* The target hardware address. */
|
|
|
5593c8 |
+ tmp_ptr += hln;
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ /* The target protocol address. */
|
|
|
5593c8 |
target_addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
|
|
|
5593c8 |
- sender_addr.ipv4 = arp_packet->sender_ip;
|
|
|
5593c8 |
- target_addr.ipv4 = arp_packet->recv_ip;
|
|
|
5593c8 |
- if (arp_packet->sender_ip == pending_req)
|
|
|
5593c8 |
+ grub_memcpy(&target_addr.ipv4, tmp_ptr, pln);
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ if (sender_addr.ipv4 == pending_req)
|
|
|
5593c8 |
have_pending = 1;
|
|
|
5593c8 |
|
|
|
5593c8 |
- sender_mac_addr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
|
|
|
5593c8 |
- grub_memcpy (sender_mac_addr.mac, arp_packet->sender_mac,
|
|
|
5593c8 |
- sizeof (sender_mac_addr.mac));
|
|
|
5593c8 |
- grub_net_link_layer_add_address (card, &sender_addr, &sender_mac_addr, 1);
|
|
|
5593c8 |
-
|
|
|
5593c8 |
FOR_NET_NETWORK_LEVEL_INTERFACES (inf)
|
|
|
5593c8 |
{
|
|
|
5593c8 |
/* Verify vlantag id */
|
|
|
5593c8 |
@@ -148,11 +183,11 @@ grub_net_arp_receive (struct grub_net_buff *nb, struct grub_net_card *card,
|
|
|
5593c8 |
|
|
|
5593c8 |
/* Am I the protocol address target? */
|
|
|
5593c8 |
if (grub_net_addr_cmp (&inf->address, &target_addr) == 0
|
|
|
5593c8 |
- && arp_packet->op == grub_cpu_to_be16_compile_time (ARP_REQUEST))
|
|
|
5593c8 |
+ && arp_header->op == grub_cpu_to_be16_compile_time (ARP_REQUEST))
|
|
|
5593c8 |
{
|
|
|
5593c8 |
grub_net_link_level_address_t target;
|
|
|
5593c8 |
struct grub_net_buff nb_reply;
|
|
|
5593c8 |
- struct arppkt *arp_reply;
|
|
|
5593c8 |
+ struct arphdr *arp_reply;
|
|
|
5593c8 |
grub_uint8_t arp_data[128];
|
|
|
5593c8 |
grub_err_t err;
|
|
|
5593c8 |
|
|
|
5593c8 |
@@ -161,25 +196,39 @@ grub_net_arp_receive (struct grub_net_buff *nb, struct grub_net_card *card,
|
|
|
5593c8 |
grub_netbuff_clear (&nb_reply);
|
|
|
5593c8 |
grub_netbuff_reserve (&nb_reply, 128);
|
|
|
5593c8 |
|
|
|
5593c8 |
- err = grub_netbuff_push (&nb_reply, sizeof (*arp_packet));
|
|
|
5593c8 |
+ err = grub_netbuff_push (&nb_reply, arp_packet_len);
|
|
|
5593c8 |
if (err)
|
|
|
5593c8 |
return err;
|
|
|
5593c8 |
|
|
|
5593c8 |
- arp_reply = (struct arppkt *) nb_reply.data;
|
|
|
5593c8 |
+ arp_reply = (struct arphdr *) nb_reply.data;
|
|
|
5593c8 |
|
|
|
5593c8 |
- arp_reply->hrd = grub_cpu_to_be16_compile_time (GRUB_NET_ARPHRD_ETHERNET);
|
|
|
5593c8 |
+ arp_reply->hrd = grub_cpu_to_be16 (hw_type);
|
|
|
5593c8 |
arp_reply->pro = grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP);
|
|
|
5593c8 |
- arp_reply->pln = 4;
|
|
|
5593c8 |
- arp_reply->hln = 6;
|
|
|
5593c8 |
+ arp_reply->pln = pln;
|
|
|
5593c8 |
+ arp_reply->hln = hln;
|
|
|
5593c8 |
arp_reply->op = grub_cpu_to_be16_compile_time (ARP_REPLY);
|
|
|
5593c8 |
- arp_reply->sender_ip = arp_packet->recv_ip;
|
|
|
5593c8 |
- arp_reply->recv_ip = arp_packet->sender_ip;
|
|
|
5593c8 |
- arp_reply->hln = 6;
|
|
|
5593c8 |
-
|
|
|
5593c8 |
- target.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
|
|
|
5593c8 |
- grub_memcpy (target.mac, arp_packet->sender_mac, 6);
|
|
|
5593c8 |
- grub_memcpy (arp_reply->sender_mac, inf->hwaddress.mac, 6);
|
|
|
5593c8 |
- grub_memcpy (arp_reply->recv_mac, arp_packet->sender_mac, 6);
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ tmp_ptr = nb_reply.data + sizeof (*arp_reply);
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ /* The source hardware address. */
|
|
|
5593c8 |
+ grub_memcpy (tmp_ptr, inf->hwaddress.mac, hln);
|
|
|
5593c8 |
+ tmp_ptr += hln;
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ /* The source protocol address. */
|
|
|
5593c8 |
+ grub_memcpy (tmp_ptr, &target_addr.ipv4, pln);
|
|
|
5593c8 |
+ tmp_ptr += pln;
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ /* The target hardware address. */
|
|
|
5593c8 |
+ grub_memcpy (tmp_ptr, sender_mac_addr.mac, hln);
|
|
|
5593c8 |
+ tmp_ptr += hln;
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ /* The target protocol address */
|
|
|
5593c8 |
+ grub_memcpy (tmp_ptr, &sender_addr.ipv4, pln);
|
|
|
5593c8 |
+ tmp_ptr += pln;
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ target.type = hw_type;
|
|
|
5593c8 |
+ target.len = hln;
|
|
|
5593c8 |
+ grub_memcpy (target.mac, sender_mac_addr.mac, hln);
|
|
|
5593c8 |
|
|
|
5593c8 |
/* Change operation to REPLY and send packet */
|
|
|
5593c8 |
send_ethernet_packet (inf, &nb_reply, target, GRUB_NET_ETHERTYPE_ARP);
|
|
|
5593c8 |
diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c
|
|
|
5593c8 |
index e28fb6a09f9..08b6b2b5d6c 100644
|
|
|
5593c8 |
--- a/grub-core/net/bootp.c
|
|
|
5593c8 |
+++ b/grub-core/net/bootp.c
|
|
|
5593c8 |
@@ -233,7 +233,6 @@ grub_net_configure_by_dhcp_ack (const char *name,
|
|
|
5593c8 |
int is_def, char **device, char **path)
|
|
|
5593c8 |
{
|
|
|
5593c8 |
grub_net_network_level_address_t addr;
|
|
|
5593c8 |
- grub_net_link_level_address_t hwaddr;
|
|
|
5593c8 |
struct grub_net_network_level_interface *inter;
|
|
|
5593c8 |
int mask = -1;
|
|
|
5593c8 |
char server_ip[sizeof ("xxx.xxx.xxx.xxx")];
|
|
|
5593c8 |
@@ -250,12 +249,8 @@ grub_net_configure_by_dhcp_ack (const char *name,
|
|
|
5593c8 |
if (path)
|
|
|
5593c8 |
*path = 0;
|
|
|
5593c8 |
|
|
|
5593c8 |
- grub_memcpy (hwaddr.mac, bp->mac_addr,
|
|
|
5593c8 |
- bp->hw_len < sizeof (hwaddr.mac) ? bp->hw_len
|
|
|
5593c8 |
- : sizeof (hwaddr.mac));
|
|
|
5593c8 |
- hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
|
|
|
5593c8 |
-
|
|
|
5593c8 |
- inter = grub_net_add_addr (name, card, &addr, &hwaddr, flags);
|
|
|
5593c8 |
+ grub_dprintf("dhcp", "configuring dhcp for %s\n", name);
|
|
|
5593c8 |
+ inter = grub_net_add_addr (name, card, &addr, &card->default_address, flags);
|
|
|
5593c8 |
if (!inter)
|
|
|
5593c8 |
return 0;
|
|
|
5593c8 |
|
|
|
5593c8 |
@@ -567,7 +562,9 @@ send_dhcp_packet (struct grub_net_network_level_interface *iface)
|
|
|
5593c8 |
grub_memset (pack, 0, sizeof (*pack));
|
|
|
5593c8 |
pack->opcode = 1;
|
|
|
5593c8 |
pack->hw_type = 1;
|
|
|
5593c8 |
- pack->hw_len = 6;
|
|
|
5593c8 |
+ pack->hw_len = iface->hwaddress.len > 16 ? 0
|
|
|
5593c8 |
+ : iface->hwaddress.len;
|
|
|
5593c8 |
+
|
|
|
5593c8 |
err = grub_get_datetime (&date);
|
|
|
5593c8 |
if (err || !grub_datetime2unixtime (&date, &t))
|
|
|
5593c8 |
{
|
|
|
5593c8 |
@@ -580,7 +577,7 @@ send_dhcp_packet (struct grub_net_network_level_interface *iface)
|
|
|
5593c8 |
else
|
|
|
5593c8 |
pack->ident = iface->xid;
|
|
|
5593c8 |
|
|
|
5593c8 |
- grub_memcpy (&pack->mac_addr, &iface->hwaddress.mac, 6);
|
|
|
5593c8 |
+ grub_memcpy (&pack->mac_addr, &iface->hwaddress.mac, pack->hw_len);
|
|
|
5593c8 |
|
|
|
5593c8 |
grub_netbuff_push (nb, sizeof (*udph));
|
|
|
5593c8 |
|
|
|
5593c8 |
diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
|
|
|
5593c8 |
index 173fb63153c..a673bea807a 100644
|
|
|
5593c8 |
--- a/grub-core/net/drivers/efi/efinet.c
|
|
|
5593c8 |
+++ b/grub-core/net/drivers/efi/efinet.c
|
|
|
5593c8 |
@@ -279,6 +279,9 @@ grub_efinet_findcards (void)
|
|
|
5593c8 |
/* This should not happen... Why? */
|
|
|
5593c8 |
continue;
|
|
|
5593c8 |
|
|
|
5593c8 |
+ if (net->mode->hwaddr_size > GRUB_NET_MAX_LINK_ADDRESS_SIZE)
|
|
|
5593c8 |
+ continue;
|
|
|
5593c8 |
+
|
|
|
5593c8 |
if (net->mode->state == GRUB_EFI_NETWORK_STOPPED
|
|
|
5593c8 |
&& efi_call_1 (net->start, net) != GRUB_EFI_SUCCESS)
|
|
|
5593c8 |
continue;
|
|
|
5593c8 |
@@ -315,10 +318,11 @@ grub_efinet_findcards (void)
|
|
|
5593c8 |
card->name = grub_xasprintf ("efinet%d", i++);
|
|
|
5593c8 |
card->driver = &efidriver;
|
|
|
5593c8 |
card->flags = 0;
|
|
|
5593c8 |
- card->default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
|
|
|
5593c8 |
+ card->default_address.type = net->mode->if_type;
|
|
|
5593c8 |
+ card->default_address.len = net->mode->hwaddr_size;
|
|
|
5593c8 |
grub_memcpy (card->default_address.mac,
|
|
|
5593c8 |
net->mode->current_address,
|
|
|
5593c8 |
- sizeof (card->default_address.mac));
|
|
|
5593c8 |
+ net->mode->hwaddr_size);
|
|
|
5593c8 |
card->efi_net = net;
|
|
|
5593c8 |
card->efi_handle = *handle;
|
|
|
5593c8 |
|
|
|
5593c8 |
diff --git a/grub-core/net/drivers/emu/emunet.c b/grub-core/net/drivers/emu/emunet.c
|
|
|
5593c8 |
index b194920861f..5b6c5e16a6d 100644
|
|
|
5593c8 |
--- a/grub-core/net/drivers/emu/emunet.c
|
|
|
5593c8 |
+++ b/grub-core/net/drivers/emu/emunet.c
|
|
|
5593c8 |
@@ -46,6 +46,7 @@ static struct grub_net_card emucard =
|
|
|
5593c8 |
.mtu = 1500,
|
|
|
5593c8 |
.default_address = {
|
|
|
5593c8 |
.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET,
|
|
|
5593c8 |
+ . len = 6,
|
|
|
5593c8 |
{.mac = {0, 1, 2, 3, 4, 5}}
|
|
|
5593c8 |
},
|
|
|
5593c8 |
.flags = 0
|
|
|
5593c8 |
diff --git a/grub-core/net/drivers/i386/pc/pxe.c b/grub-core/net/drivers/i386/pc/pxe.c
|
|
|
5593c8 |
index 3f4152d036c..9f8fb4b6d2b 100644
|
|
|
5593c8 |
--- a/grub-core/net/drivers/i386/pc/pxe.c
|
|
|
5593c8 |
+++ b/grub-core/net/drivers/i386/pc/pxe.c
|
|
|
5593c8 |
@@ -386,20 +386,21 @@ GRUB_MOD_INIT(pxe)
|
|
|
5593c8 |
grub_memset (ui, 0, sizeof (*ui));
|
|
|
5593c8 |
grub_pxe_call (GRUB_PXENV_UNDI_GET_INFORMATION, ui, pxe_rm_entry);
|
|
|
5593c8 |
|
|
|
5593c8 |
+ grub_pxe_card.default_address.len = 6;
|
|
|
5593c8 |
grub_memcpy (grub_pxe_card.default_address.mac, ui->current_addr,
|
|
|
5593c8 |
- sizeof (grub_pxe_card.default_address.mac));
|
|
|
5593c8 |
- for (i = 0; i < sizeof (grub_pxe_card.default_address.mac); i++)
|
|
|
5593c8 |
+ grub_pxe_card.default_address.len);
|
|
|
5593c8 |
+ for (i = 0; i < grub_pxe_card.default_address.len; i++)
|
|
|
5593c8 |
if (grub_pxe_card.default_address.mac[i] != 0)
|
|
|
5593c8 |
break;
|
|
|
5593c8 |
- if (i != sizeof (grub_pxe_card.default_address.mac))
|
|
|
5593c8 |
+ if (i != grub_pxe_card.default_address.len)
|
|
|
5593c8 |
{
|
|
|
5593c8 |
- for (i = 0; i < sizeof (grub_pxe_card.default_address.mac); i++)
|
|
|
5593c8 |
+ for (i = 0; i < grub_pxe_card.default_address.len; i++)
|
|
|
5593c8 |
if (grub_pxe_card.default_address.mac[i] != 0xff)
|
|
|
5593c8 |
break;
|
|
|
5593c8 |
}
|
|
|
5593c8 |
- if (i == sizeof (grub_pxe_card.default_address.mac))
|
|
|
5593c8 |
+ if (i == grub_pxe_card.default_address.len)
|
|
|
5593c8 |
grub_memcpy (grub_pxe_card.default_address.mac, ui->permanent_addr,
|
|
|
5593c8 |
- sizeof (grub_pxe_card.default_address.mac));
|
|
|
5593c8 |
+ grub_pxe_card.default_address.len);
|
|
|
5593c8 |
grub_pxe_card.mtu = ui->mtu;
|
|
|
5593c8 |
|
|
|
5593c8 |
grub_pxe_card.default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
|
|
|
5593c8 |
diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c
|
|
|
5593c8 |
index 3860b6f78d8..bcb3f9ea02d 100644
|
|
|
5593c8 |
--- a/grub-core/net/drivers/ieee1275/ofnet.c
|
|
|
5593c8 |
+++ b/grub-core/net/drivers/ieee1275/ofnet.c
|
|
|
5593c8 |
@@ -160,6 +160,7 @@ grub_ieee1275_parse_bootpath (const char *devpath, char *bootpath,
|
|
|
5593c8 |
grub_uint16_t vlantag = 0;
|
|
|
5593c8 |
|
|
|
5593c8 |
hw_addr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
|
|
|
5593c8 |
+ hw_addr.len = 6;
|
|
|
5593c8 |
|
|
|
5593c8 |
args = bootpath + grub_strlen (devpath) + 1;
|
|
|
5593c8 |
do
|
|
|
5593c8 |
@@ -503,6 +504,7 @@ search_net_devices (struct grub_ieee1275_devalias *alias)
|
|
|
5593c8 |
grub_memcpy (&lla.mac, pprop, 6);
|
|
|
5593c8 |
|
|
|
5593c8 |
lla.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
|
|
|
5593c8 |
+ lla.len = 6;
|
|
|
5593c8 |
card->default_address = lla;
|
|
|
5593c8 |
|
|
|
5593c8 |
card->txbufsize = ALIGN_UP (card->mtu, 64) + 256;
|
|
|
5593c8 |
diff --git a/grub-core/net/drivers/uboot/ubootnet.c b/grub-core/net/drivers/uboot/ubootnet.c
|
|
|
5593c8 |
index 056052e40d5..22ebcbf211e 100644
|
|
|
5593c8 |
--- a/grub-core/net/drivers/uboot/ubootnet.c
|
|
|
5593c8 |
+++ b/grub-core/net/drivers/uboot/ubootnet.c
|
|
|
5593c8 |
@@ -131,6 +131,7 @@ GRUB_MOD_INIT (ubootnet)
|
|
|
5593c8 |
|
|
|
5593c8 |
grub_memcpy (&(card->default_address.mac), &devinfo->di_net.hwaddr, 6);
|
|
|
5593c8 |
card->default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
|
|
|
5593c8 |
+ card->default_address.len = 6;
|
|
|
5593c8 |
|
|
|
5593c8 |
card->txbufsize = ALIGN_UP (card->mtu, 64) + 256;
|
|
|
5593c8 |
card->txbuf = grub_zalloc (card->txbufsize);
|
|
|
5593c8 |
diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c
|
|
|
5593c8 |
index 4d7ceed6f93..9aae83a5eb4 100644
|
|
|
5593c8 |
--- a/grub-core/net/ethernet.c
|
|
|
5593c8 |
+++ b/grub-core/net/ethernet.c
|
|
|
5593c8 |
@@ -29,13 +29,6 @@
|
|
|
5593c8 |
|
|
|
5593c8 |
#define LLCADDRMASK 0x7f
|
|
|
5593c8 |
|
|
|
5593c8 |
-struct etherhdr
|
|
|
5593c8 |
-{
|
|
|
5593c8 |
- grub_uint8_t dst[6];
|
|
|
5593c8 |
- grub_uint8_t src[6];
|
|
|
5593c8 |
- grub_uint16_t type;
|
|
|
5593c8 |
-} GRUB_PACKED;
|
|
|
5593c8 |
-
|
|
|
5593c8 |
struct llchdr
|
|
|
5593c8 |
{
|
|
|
5593c8 |
grub_uint8_t dsap;
|
|
|
5593c8 |
@@ -55,13 +48,15 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf,
|
|
|
5593c8 |
grub_net_link_level_address_t target_addr,
|
|
|
5593c8 |
grub_net_ethertype_t ethertype)
|
|
|
5593c8 |
{
|
|
|
5593c8 |
- struct etherhdr *eth;
|
|
|
5593c8 |
+ grub_uint8_t *eth;
|
|
|
5593c8 |
grub_err_t err;
|
|
|
5593c8 |
- grub_uint8_t etherhdr_size;
|
|
|
5593c8 |
- grub_uint16_t vlantag_id = VLANTAG_IDENTIFIER;
|
|
|
5593c8 |
+ grub_uint32_t vlantag = 0;
|
|
|
5593c8 |
+ grub_uint8_t hw_addr_len = inf->card->default_address.len;
|
|
|
5593c8 |
+ grub_uint8_t etherhdr_size = 2 * hw_addr_len + 2;
|
|
|
5593c8 |
|
|
|
5593c8 |
- etherhdr_size = sizeof (*eth);
|
|
|
5593c8 |
- COMPILE_TIME_ASSERT (sizeof (*eth) + 4 < GRUB_NET_MAX_LINK_HEADER_SIZE);
|
|
|
5593c8 |
+ /* Source and destination link addresses + ethertype + vlan tag */
|
|
|
5593c8 |
+ COMPILE_TIME_ASSERT ((GRUB_NET_MAX_LINK_ADDRESS_SIZE * 2 + 2 + 4) <
|
|
|
5593c8 |
+ GRUB_NET_MAX_LINK_HEADER_SIZE);
|
|
|
5593c8 |
|
|
|
5593c8 |
/* Increase ethernet header in case of vlantag */
|
|
|
5593c8 |
if (inf->vlantag != 0)
|
|
|
5593c8 |
@@ -70,11 +65,22 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf,
|
|
|
5593c8 |
err = grub_netbuff_push (nb, etherhdr_size);
|
|
|
5593c8 |
if (err)
|
|
|
5593c8 |
return err;
|
|
|
5593c8 |
- eth = (struct etherhdr *) nb->data;
|
|
|
5593c8 |
- grub_memcpy (eth->dst, target_addr.mac, 6);
|
|
|
5593c8 |
- grub_memcpy (eth->src, inf->hwaddress.mac, 6);
|
|
|
5593c8 |
+ eth = nb->data;
|
|
|
5593c8 |
+ grub_memcpy (eth, target_addr.mac, hw_addr_len);
|
|
|
5593c8 |
+ eth += hw_addr_len;
|
|
|
5593c8 |
+ grub_memcpy (eth, inf->hwaddress.mac, hw_addr_len);
|
|
|
5593c8 |
+ eth += hw_addr_len;
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ /* Check if a vlan-tag is present. */
|
|
|
5593c8 |
+ if (vlantag != 0)
|
|
|
5593c8 |
+ {
|
|
|
5593c8 |
+ *((grub_uint32_t *)eth) = grub_cpu_to_be32 (vlantag);
|
|
|
5593c8 |
+ eth += sizeof (vlantag);
|
|
|
5593c8 |
+ }
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ /* Write ethertype */
|
|
|
5593c8 |
+ *((grub_uint16_t*) eth) = grub_cpu_to_be16 (ethertype);
|
|
|
5593c8 |
|
|
|
5593c8 |
- eth->type = grub_cpu_to_be16 (ethertype);
|
|
|
5593c8 |
if (!inf->card->opened)
|
|
|
5593c8 |
{
|
|
|
5593c8 |
err = GRUB_ERR_NONE;
|
|
|
5593c8 |
@@ -85,18 +91,6 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf,
|
|
|
5593c8 |
inf->card->opened = 1;
|
|
|
5593c8 |
}
|
|
|
5593c8 |
|
|
|
5593c8 |
- /* Check and add a vlan-tag if needed. */
|
|
|
5593c8 |
- if (inf->vlantag != 0)
|
|
|
5593c8 |
- {
|
|
|
5593c8 |
- /* Move eth type to the right */
|
|
|
5593c8 |
- grub_memcpy ((char *) nb->data + etherhdr_size - 2,
|
|
|
5593c8 |
- (char *) nb->data + etherhdr_size - 6, 2);
|
|
|
5593c8 |
-
|
|
|
5593c8 |
- /* Add the tag in the middle */
|
|
|
5593c8 |
- grub_memcpy ((char *) nb->data + etherhdr_size - 6, &vlantag_id, 2);
|
|
|
5593c8 |
- grub_memcpy ((char *) nb->data + etherhdr_size - 4, (char *) &(inf->vlantag), 2);
|
|
|
5593c8 |
- }
|
|
|
5593c8 |
-
|
|
|
5593c8 |
return inf->card->driver->send (inf->card, nb);
|
|
|
5593c8 |
}
|
|
|
5593c8 |
|
|
|
5593c8 |
@@ -104,31 +98,40 @@ grub_err_t
|
|
|
5593c8 |
grub_net_recv_ethernet_packet (struct grub_net_buff *nb,
|
|
|
5593c8 |
struct grub_net_card *card)
|
|
|
5593c8 |
{
|
|
|
5593c8 |
- struct etherhdr *eth;
|
|
|
5593c8 |
+ grub_uint8_t *eth;
|
|
|
5593c8 |
struct llchdr *llch;
|
|
|
5593c8 |
struct snaphdr *snaph;
|
|
|
5593c8 |
grub_net_ethertype_t type;
|
|
|
5593c8 |
grub_net_link_level_address_t hwaddress;
|
|
|
5593c8 |
grub_net_link_level_address_t src_hwaddress;
|
|
|
5593c8 |
grub_err_t err;
|
|
|
5593c8 |
- grub_uint8_t etherhdr_size = sizeof (*eth);
|
|
|
5593c8 |
+ grub_uint8_t hw_addr_len = card->default_address.len;
|
|
|
5593c8 |
+ grub_uint8_t etherhdr_size = 2 * hw_addr_len + 2;
|
|
|
5593c8 |
grub_uint16_t vlantag = 0;
|
|
|
5593c8 |
|
|
|
5593c8 |
+ eth = nb->data;
|
|
|
5593c8 |
|
|
|
5593c8 |
- /* Check if a vlan-tag is present. If so, the ethernet header is 4 bytes */
|
|
|
5593c8 |
- /* longer than the original one. The vlantag id is extracted and the header */
|
|
|
5593c8 |
- /* is reseted to the original size. */
|
|
|
5593c8 |
- if (grub_get_unaligned16 (nb->data + etherhdr_size - 2) == VLANTAG_IDENTIFIER)
|
|
|
5593c8 |
+ hwaddress.type = card->default_address.type;
|
|
|
5593c8 |
+ hwaddress.len = hw_addr_len;
|
|
|
5593c8 |
+ grub_memcpy (hwaddress.mac, eth, hw_addr_len);
|
|
|
5593c8 |
+ eth += hw_addr_len;
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ src_hwaddress.type = card->default_address.type;
|
|
|
5593c8 |
+ src_hwaddress.len = hw_addr_len;
|
|
|
5593c8 |
+ grub_memcpy (src_hwaddress.mac, eth, hw_addr_len);
|
|
|
5593c8 |
+ eth += hw_addr_len;
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ type = grub_be_to_cpu16 (*(grub_uint16_t*)(eth));
|
|
|
5593c8 |
+ if (type == VLANTAG_IDENTIFIER)
|
|
|
5593c8 |
{
|
|
|
5593c8 |
- vlantag = grub_get_unaligned16 (nb->data + etherhdr_size);
|
|
|
5593c8 |
+ /* Skip vlan tag */
|
|
|
5593c8 |
+ eth += 2;
|
|
|
5593c8 |
+ vlantag = grub_be_to_cpu16 (*(grub_uint16_t*)(eth));
|
|
|
5593c8 |
etherhdr_size += 4;
|
|
|
5593c8 |
- /* Move eth type to the original position */
|
|
|
5593c8 |
- grub_memcpy((char *) nb->data + etherhdr_size - 6,
|
|
|
5593c8 |
- (char *) nb->data + etherhdr_size - 2, 2);
|
|
|
5593c8 |
+ eth += 2;
|
|
|
5593c8 |
+ type = grub_be_to_cpu16 (*(grub_uint16_t*)(eth));
|
|
|
5593c8 |
}
|
|
|
5593c8 |
|
|
|
5593c8 |
- eth = (struct etherhdr *) nb->data;
|
|
|
5593c8 |
- type = grub_be_to_cpu16 (eth->type);
|
|
|
5593c8 |
err = grub_netbuff_pull (nb, etherhdr_size);
|
|
|
5593c8 |
if (err)
|
|
|
5593c8 |
return err;
|
|
|
5593c8 |
@@ -148,11 +151,6 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb,
|
|
|
5593c8 |
}
|
|
|
5593c8 |
}
|
|
|
5593c8 |
|
|
|
5593c8 |
- hwaddress.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
|
|
|
5593c8 |
- grub_memcpy (hwaddress.mac, eth->dst, sizeof (hwaddress.mac));
|
|
|
5593c8 |
- src_hwaddress.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
|
|
|
5593c8 |
- grub_memcpy (src_hwaddress.mac, eth->src, sizeof (src_hwaddress.mac));
|
|
|
5593c8 |
-
|
|
|
5593c8 |
switch (type)
|
|
|
5593c8 |
{
|
|
|
5593c8 |
/* ARP packet. */
|
|
|
5593c8 |
diff --git a/grub-core/net/icmp6.c b/grub-core/net/icmp6.c
|
|
|
5593c8 |
index 2cbd95dce25..56a3ec5c8e8 100644
|
|
|
5593c8 |
--- a/grub-core/net/icmp6.c
|
|
|
5593c8 |
+++ b/grub-core/net/icmp6.c
|
|
|
5593c8 |
@@ -231,8 +231,9 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb,
|
|
|
5593c8 |
&& ohdr->len == 1)
|
|
|
5593c8 |
{
|
|
|
5593c8 |
grub_net_link_level_address_t ll_address;
|
|
|
5593c8 |
- ll_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
|
|
|
5593c8 |
- grub_memcpy (ll_address.mac, ohdr + 1, sizeof (ll_address.mac));
|
|
|
5593c8 |
+ ll_address.type = card->default_address.type;
|
|
|
5593c8 |
+ ll_address.len = card->default_address.len;
|
|
|
5593c8 |
+ grub_memcpy (ll_address.mac, ohdr + 1, ll_address.len);
|
|
|
5593c8 |
grub_net_link_layer_add_address (card, source, &ll_address, 0);
|
|
|
5593c8 |
}
|
|
|
5593c8 |
}
|
|
|
5593c8 |
@@ -335,8 +336,9 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb,
|
|
|
5593c8 |
&& ohdr->len == 1)
|
|
|
5593c8 |
{
|
|
|
5593c8 |
grub_net_link_level_address_t ll_address;
|
|
|
5593c8 |
- ll_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
|
|
|
5593c8 |
- grub_memcpy (ll_address.mac, ohdr + 1, sizeof (ll_address.mac));
|
|
|
5593c8 |
+ ll_address.type = card->default_address.type;
|
|
|
5593c8 |
+ ll_address.len = card->default_address.len;
|
|
|
5593c8 |
+ grub_memcpy (ll_address.mac, ohdr + 1, ll_address.len);
|
|
|
5593c8 |
grub_net_link_layer_add_address (card, source, &ll_address, 0);
|
|
|
5593c8 |
}
|
|
|
5593c8 |
}
|
|
|
5593c8 |
@@ -384,8 +386,9 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb,
|
|
|
5593c8 |
&& ohdr->len == 1)
|
|
|
5593c8 |
{
|
|
|
5593c8 |
grub_net_link_level_address_t ll_address;
|
|
|
5593c8 |
- ll_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
|
|
|
5593c8 |
- grub_memcpy (ll_address.mac, ohdr + 1, sizeof (ll_address.mac));
|
|
|
5593c8 |
+ ll_address.type = card->default_address.type;
|
|
|
5593c8 |
+ ll_address.len = card->default_address.len;
|
|
|
5593c8 |
+ grub_memcpy (ll_address.mac, ohdr + 1, ll_address.len);
|
|
|
5593c8 |
grub_net_link_layer_add_address (card, source, &ll_address, 0);
|
|
|
5593c8 |
}
|
|
|
5593c8 |
if (ohdr->type == OPTION_PREFIX && ohdr->len == 4)
|
|
|
5593c8 |
diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c
|
|
|
5593c8 |
index ea5edf8f1f6..a5896f6dc26 100644
|
|
|
5593c8 |
--- a/grub-core/net/ip.c
|
|
|
5593c8 |
+++ b/grub-core/net/ip.c
|
|
|
5593c8 |
@@ -276,8 +276,8 @@ handle_dgram (struct grub_net_buff *nb,
|
|
|
5593c8 |
if (inf->card == card
|
|
|
5593c8 |
&& inf->address.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV
|
|
|
5593c8 |
&& inf->hwaddress.type == GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET
|
|
|
5593c8 |
- && grub_memcmp (inf->hwaddress.mac, &bootp->mac_addr,
|
|
|
5593c8 |
- sizeof (inf->hwaddress.mac)) == 0)
|
|
|
5593c8 |
+ && (grub_memcmp (inf->hwaddress.mac, &bootp->mac_addr,
|
|
|
5593c8 |
+ bootp->hw_len) == 0 || bootp->hw_len == 0))
|
|
|
5593c8 |
{
|
|
|
5593c8 |
grub_net_process_dhcp (nb, inf);
|
|
|
5593c8 |
grub_netbuff_free (nb);
|
|
|
5593c8 |
diff --git a/grub-core/net/net.c b/grub-core/net/net.c
|
|
|
5593c8 |
index 22f2689aaeb..a46f82362ed 100644
|
|
|
5593c8 |
--- a/grub-core/net/net.c
|
|
|
5593c8 |
+++ b/grub-core/net/net.c
|
|
|
5593c8 |
@@ -133,8 +133,9 @@ grub_net_link_layer_resolve (struct grub_net_network_level_interface *inf,
|
|
|
5593c8 |
<< 48)
|
|
|
5593c8 |
&& proto_addr->ipv6[1] == (grub_be_to_cpu64_compile_time (1))))
|
|
|
5593c8 |
{
|
|
|
5593c8 |
- hw_addr->type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
|
|
|
5593c8 |
- grub_memset (hw_addr->mac, -1, 6);
|
|
|
5593c8 |
+ hw_addr->type = inf->card->default_address.type;
|
|
|
5593c8 |
+ hw_addr->len = inf->card->default_address.len;
|
|
|
5593c8 |
+ grub_memset (hw_addr->mac, -1, hw_addr->len);
|
|
|
5593c8 |
return GRUB_ERR_NONE;
|
|
|
5593c8 |
}
|
|
|
5593c8 |
|
|
|
5593c8 |
@@ -142,6 +143,7 @@ grub_net_link_layer_resolve (struct grub_net_network_level_interface *inf,
|
|
|
5593c8 |
&& ((grub_be_to_cpu64 (proto_addr->ipv6[0]) >> 56) == 0xff))
|
|
|
5593c8 |
{
|
|
|
5593c8 |
hw_addr->type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
|
|
|
5593c8 |
+ hw_addr->len = inf->card->default_address.len;
|
|
|
5593c8 |
hw_addr->mac[0] = 0x33;
|
|
|
5593c8 |
hw_addr->mac[1] = 0x33;
|
|
|
5593c8 |
hw_addr->mac[2] = ((grub_be_to_cpu64 (proto_addr->ipv6[1]) >> 24) & 0xff);
|
|
|
5593c8 |
@@ -762,23 +764,23 @@ grub_net_addr_to_str (const grub_net_network_level_address_t *target, char *buf)
|
|
|
5593c8 |
void
|
|
|
5593c8 |
grub_net_hwaddr_to_str (const grub_net_link_level_address_t *addr, char *str)
|
|
|
5593c8 |
{
|
|
|
5593c8 |
- str[0] = 0;
|
|
|
5593c8 |
- switch (addr->type)
|
|
|
5593c8 |
+ char *ptr;
|
|
|
5593c8 |
+ unsigned i;
|
|
|
5593c8 |
+ int maxstr;
|
|
|
5593c8 |
+
|
|
|
5593c8 |
+ if (addr->len > GRUB_NET_MAX_LINK_ADDRESS_SIZE)
|
|
|
5593c8 |
{
|
|
|
5593c8 |
- case GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET:
|
|
|
5593c8 |
- {
|
|
|
5593c8 |
- char *ptr;
|
|
|
5593c8 |
- unsigned i;
|
|
|
5593c8 |
- for (ptr = str, i = 0; i < ARRAY_SIZE (addr->mac); i++)
|
|
|
5593c8 |
- {
|
|
|
5593c8 |
- grub_snprintf (ptr, GRUB_NET_MAX_STR_HWADDR_LEN - (ptr - str),
|
|
|
5593c8 |
- "%02x:", addr->mac[i] & 0xff);
|
|
|
5593c8 |
- ptr += (sizeof ("XX:") - 1);
|
|
|
5593c8 |
- }
|
|
|
5593c8 |
- return;
|
|
|
5593c8 |
- }
|
|
|
5593c8 |
+ str[0] = 0;
|
|
|
5593c8 |
+ grub_printf (_("Unsupported hw address type %d len %d\n"),
|
|
|
5593c8 |
+ addr->type, addr->len);
|
|
|
5593c8 |
+ return;
|
|
|
5593c8 |
+ }
|
|
|
5593c8 |
+ maxstr = addr->len * grub_strlen ("XX:");
|
|
|
5593c8 |
+ for (ptr = str, i = 0; i < addr->len; i++)
|
|
|
5593c8 |
+ {
|
|
|
5593c8 |
+ ptr += grub_snprintf (ptr, maxstr - (ptr - str),
|
|
|
5593c8 |
+ "%02x:", addr->mac[i] & 0xff);
|
|
|
5593c8 |
}
|
|
|
5593c8 |
- grub_printf (_("Unsupported hw address type %d\n"), addr->type);
|
|
|
5593c8 |
}
|
|
|
5593c8 |
|
|
|
5593c8 |
int
|
|
|
5593c8 |
@@ -789,13 +791,17 @@ grub_net_hwaddr_cmp (const grub_net_link_level_address_t *a,
|
|
|
5593c8 |
return -1;
|
|
|
5593c8 |
if (a->type > b->type)
|
|
|
5593c8 |
return +1;
|
|
|
5593c8 |
- switch (a->type)
|
|
|
5593c8 |
+ if (a->len < b->len)
|
|
|
5593c8 |
+ return -1;
|
|
|
5593c8 |
+ if (a->len > b->len)
|
|
|
5593c8 |
+ return +1;
|
|
|
5593c8 |
+ if (a->len > GRUB_NET_MAX_LINK_ADDRESS_SIZE)
|
|
|
5593c8 |
{
|
|
|
5593c8 |
- case GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET:
|
|
|
5593c8 |
- return grub_memcmp (a->mac, b->mac, sizeof (a->mac));
|
|
|
5593c8 |
+ grub_printf (_("Unsupported hw address type %d len %d\n"),
|
|
|
5593c8 |
+ a->type, a->len);
|
|
|
5593c8 |
+ return + 1;
|
|
|
5593c8 |
}
|
|
|
5593c8 |
- grub_printf (_("Unsupported hw address type %d\n"), a->type);
|
|
|
5593c8 |
- return 1;
|
|
|
5593c8 |
+ return grub_memcmp (a->mac, b->mac, a->len);
|
|
|
5593c8 |
}
|
|
|
5593c8 |
|
|
|
5593c8 |
int
|
|
|
5593c8 |
diff --git a/include/grub/net.h b/include/grub/net.h
|
|
|
5593c8 |
index 8a05ec4fe7a..af0404db7e3 100644
|
|
|
5593c8 |
--- a/include/grub/net.h
|
|
|
5593c8 |
+++ b/include/grub/net.h
|
|
|
5593c8 |
@@ -29,7 +29,8 @@
|
|
|
5593c8 |
|
|
|
5593c8 |
enum
|
|
|
5593c8 |
{
|
|
|
5593c8 |
- GRUB_NET_MAX_LINK_HEADER_SIZE = 64,
|
|
|
5593c8 |
+ GRUB_NET_MAX_LINK_HEADER_SIZE = 96,
|
|
|
5593c8 |
+ GRUB_NET_MAX_LINK_ADDRESS_SIZE = 32,
|
|
|
5593c8 |
GRUB_NET_UDP_HEADER_SIZE = 8,
|
|
|
5593c8 |
GRUB_NET_TCP_HEADER_SIZE = 20,
|
|
|
5593c8 |
GRUB_NET_OUR_IPV4_HEADER_SIZE = 20,
|
|
|
5593c8 |
@@ -42,15 +43,17 @@ enum
|
|
|
5593c8 |
|
|
|
5593c8 |
typedef enum grub_link_level_protocol_id
|
|
|
5593c8 |
{
|
|
|
5593c8 |
- GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET
|
|
|
5593c8 |
+ /* IANA ARP constant to define hardware type. */
|
|
|
5593c8 |
+ GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET = 1,
|
|
|
5593c8 |
} grub_link_level_protocol_id_t;
|
|
|
5593c8 |
|
|
|
5593c8 |
typedef struct grub_net_link_level_address
|
|
|
5593c8 |
{
|
|
|
5593c8 |
grub_link_level_protocol_id_t type;
|
|
|
5593c8 |
+ grub_uint8_t len;
|
|
|
5593c8 |
union
|
|
|
5593c8 |
{
|
|
|
5593c8 |
- grub_uint8_t mac[6];
|
|
|
5593c8 |
+ grub_uint8_t mac[GRUB_NET_MAX_LINK_ADDRESS_SIZE];
|
|
|
5593c8 |
};
|
|
|
5593c8 |
} grub_net_link_level_address_t;
|
|
|
5593c8 |
|
|
|
5593c8 |
@@ -566,11 +569,13 @@ grub_net_addr_cmp (const grub_net_network_level_address_t *a,
|
|
|
5593c8 |
#define GRUB_NET_MAX_STR_ADDR_LEN sizeof ("XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX")
|
|
|
5593c8 |
|
|
|
5593c8 |
/*
|
|
|
5593c8 |
- Currently suppoerted adresses:
|
|
|
5593c8 |
- ethernet: XX:XX:XX:XX:XX:XX
|
|
|
5593c8 |
+ Up to 32 byte hardware address supported, see GRUB_NET_MAX_LINK_ADDRESS_SIZE
|
|
|
5593c8 |
*/
|
|
|
5593c8 |
-
|
|
|
5593c8 |
-#define GRUB_NET_MAX_STR_HWADDR_LEN (sizeof ("XX:XX:XX:XX:XX:XX"))
|
|
|
5593c8 |
+#define GRUB_NET_MAX_STR_HWADDR_LEN (sizeof (\
|
|
|
5593c8 |
+ "XX:XX:XX:XX:XX:XX:XX:XX:"\
|
|
|
5593c8 |
+ "XX:XX:XX:XX:XX:XX:XX:XX:"\
|
|
|
5593c8 |
+ "XX:XX:XX:XX:XX:XX:XX:XX:"\
|
|
|
5593c8 |
+ "XX:XX:XX:XX:XX:XX:XX:XX"))
|
|
|
5593c8 |
|
|
|
5593c8 |
void
|
|
|
5593c8 |
grub_net_addr_to_str (const grub_net_network_level_address_t *target,
|