You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
652 lines
19 KiB
652 lines
19 KiB
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
|
From: Peter Jones <pjones@redhat.com> |
|
Date: Wed, 8 Jun 2016 21:03:37 -0400 |
|
Subject: [PATCH] efinet and bootp: add support for dhcpv6 |
|
|
|
Signed-off-by: Peter Jones <pjones@redhat.com> |
|
--- |
|
grub-core/net/bootp.c | 173 +++++++++++++++++++++++++++++++++++++ |
|
grub-core/net/drivers/efi/efinet.c | 52 +++++++++-- |
|
grub-core/net/net.c | 67 ++++++++++++++ |
|
grub-core/net/tftp.c | 4 + |
|
include/grub/efi/api.h | 129 +++++++++++++++++++++++++-- |
|
include/grub/net.h | 60 +++++++++++++ |
|
6 files changed, 471 insertions(+), 14 deletions(-) |
|
|
|
diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c |
|
index 88f20568914..4793ebc434e 100644 |
|
--- a/grub-core/net/bootp.c |
|
+++ b/grub-core/net/bootp.c |
|
@@ -23,6 +23,7 @@ |
|
#include <grub/net/ip.h> |
|
#include <grub/net/netbuff.h> |
|
#include <grub/net/udp.h> |
|
+#include <grub/net/url.h> |
|
#include <grub/datetime.h> |
|
|
|
static char * |
|
@@ -335,6 +336,178 @@ grub_net_configure_by_dhcp_ack (const char *name, |
|
return inter; |
|
} |
|
|
|
+struct grub_net_network_level_interface * |
|
+grub_net_configure_by_dhcpv6_ack (const char *name, |
|
+ struct grub_net_card *card, |
|
+ grub_net_interface_flags_t flags |
|
+ __attribute__((__unused__)), |
|
+ const grub_net_link_level_address_t *hwaddr, |
|
+ const struct grub_net_dhcpv6_packet *packet, |
|
+ int is_def, char **device, char **path) |
|
+{ |
|
+ struct grub_net_network_level_interface *inter = NULL; |
|
+ struct grub_net_network_level_address addr; |
|
+ int mask = -1; |
|
+ |
|
+ if (device) |
|
+ *device = 0; |
|
+ if (path) |
|
+ *path = 0; |
|
+ |
|
+ grub_dprintf ("net", "mac address is %02x:%02x:%02x:%02x:%02x:%02x\n", |
|
+ hwaddr->mac[0], hwaddr->mac[1], hwaddr->mac[2], |
|
+ hwaddr->mac[3], hwaddr->mac[4], hwaddr->mac[5]); |
|
+ |
|
+ if (is_def) |
|
+ grub_net_default_server = 0; |
|
+ |
|
+ if (is_def && !grub_net_default_server && packet) |
|
+ { |
|
+ const grub_uint8_t *options = packet->dhcp_options; |
|
+ unsigned int option_max = 1024 - OFFSET_OF (dhcp_options, packet); |
|
+ unsigned int i; |
|
+ |
|
+ for (i = 0; i < option_max - sizeof (grub_net_dhcpv6_option_t); ) |
|
+ { |
|
+ grub_uint16_t num, len; |
|
+ grub_net_dhcpv6_option_t *opt = |
|
+ (grub_net_dhcpv6_option_t *)(options + i); |
|
+ |
|
+ num = grub_be_to_cpu16(opt->option_num); |
|
+ len = grub_be_to_cpu16(opt->option_len); |
|
+ |
|
+ grub_dprintf ("net", "got dhcpv6 option %d len %d\n", num, len); |
|
+ |
|
+ if (len == 0) |
|
+ break; |
|
+ |
|
+ if (len + i > 1024) |
|
+ break; |
|
+ |
|
+ if (num == GRUB_NET_DHCP6_BOOTFILE_URL) |
|
+ { |
|
+ char *scheme, *userinfo, *host, *file; |
|
+ char *tmp; |
|
+ int hostlen; |
|
+ int port; |
|
+ int rc = extract_url_info ((const char *)opt->option_data, |
|
+ (grub_size_t)len, |
|
+ &scheme, &userinfo, &host, &port, |
|
+ &file); |
|
+ if (rc < 0) |
|
+ continue; |
|
+ |
|
+ /* right now this only handles tftp. */ |
|
+ if (grub_strcmp("tftp", scheme)) |
|
+ { |
|
+ grub_free (scheme); |
|
+ grub_free (userinfo); |
|
+ grub_free (host); |
|
+ grub_free (file); |
|
+ continue; |
|
+ } |
|
+ grub_free (userinfo); |
|
+ |
|
+ hostlen = grub_strlen (host); |
|
+ if (hostlen > 2 && host[0] == '[' && host[hostlen-1] == ']') |
|
+ { |
|
+ tmp = host+1; |
|
+ host[hostlen-1] = '\0'; |
|
+ } |
|
+ else |
|
+ tmp = host; |
|
+ |
|
+ *device = grub_xasprintf ("%s,%s", scheme, tmp); |
|
+ grub_free (scheme); |
|
+ grub_free (host); |
|
+ |
|
+ if (file && *file) |
|
+ { |
|
+ tmp = grub_strrchr (file, '/'); |
|
+ if (tmp) |
|
+ *(tmp+1) = '\0'; |
|
+ else |
|
+ file[0] = '\0'; |
|
+ } |
|
+ else if (!file) |
|
+ file = grub_strdup (""); |
|
+ |
|
+ if (file[0] == '/') |
|
+ { |
|
+ *path = grub_strdup (file+1); |
|
+ grub_free (file); |
|
+ } |
|
+ else |
|
+ *path = file; |
|
+ } |
|
+ else if (num == GRUB_NET_DHCP6_IA_NA) |
|
+ { |
|
+ const grub_net_dhcpv6_option_t *ia_na_opt; |
|
+ const grub_net_dhcpv6_opt_ia_na_t *ia_na = |
|
+ (const grub_net_dhcpv6_opt_ia_na_t *)opt; |
|
+ unsigned int left = len - OFFSET_OF (options, ia_na); |
|
+ unsigned int j; |
|
+ |
|
+ if ((grub_uint8_t *)ia_na + left > |
|
+ (grub_uint8_t *)options + option_max) |
|
+ left -= ((grub_uint8_t *)ia_na + left) |
|
+ - ((grub_uint8_t *)options + option_max); |
|
+ |
|
+ if (len < OFFSET_OF (option_data, opt) |
|
+ + sizeof (grub_net_dhcpv6_option_t)) |
|
+ { |
|
+ grub_dprintf ("net", |
|
+ "found dhcpv6 ia_na option with no address\n"); |
|
+ continue; |
|
+ } |
|
+ |
|
+ for (j = 0; left > sizeof (grub_net_dhcpv6_option_t); ) |
|
+ { |
|
+ ia_na_opt = (const grub_net_dhcpv6_option_t *) |
|
+ (ia_na->options + j); |
|
+ grub_uint16_t ia_na_opt_num, ia_na_opt_len; |
|
+ |
|
+ ia_na_opt_num = grub_be_to_cpu16 (ia_na_opt->option_num); |
|
+ ia_na_opt_len = grub_be_to_cpu16 (ia_na_opt->option_len); |
|
+ if (ia_na_opt_len == 0) |
|
+ break; |
|
+ if (j + ia_na_opt_len > left) |
|
+ break; |
|
+ if (ia_na_opt_num == GRUB_NET_DHCP6_IA_ADDRESS) |
|
+ { |
|
+ const grub_net_dhcpv6_opt_ia_address_t *ia_addr; |
|
+ |
|
+ ia_addr = (const grub_net_dhcpv6_opt_ia_address_t *) |
|
+ ia_na_opt; |
|
+ addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; |
|
+ grub_memcpy(addr.ipv6, ia_addr->ipv6_address, |
|
+ sizeof (ia_addr->ipv6_address)); |
|
+ inter = grub_net_add_addr (name, card, &addr, hwaddr, 0); |
|
+ } |
|
+ |
|
+ j += ia_na_opt_len; |
|
+ left -= ia_na_opt_len; |
|
+ } |
|
+ } |
|
+ |
|
+ i += len + 4; |
|
+ } |
|
+ |
|
+ grub_print_error (); |
|
+ } |
|
+ |
|
+ if (is_def) |
|
+ { |
|
+ grub_env_set ("net_default_interface", name); |
|
+ grub_env_export ("net_default_interface"); |
|
+ } |
|
+ |
|
+ if (inter) |
|
+ grub_net_add_ipv6_local (inter, mask); |
|
+ return inter; |
|
+} |
|
+ |
|
+ |
|
void |
|
grub_net_process_dhcp (struct grub_net_buff *nb, |
|
struct grub_net_card *card) |
|
diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c |
|
index 3f112438a93..d7befb2ba9b 100644 |
|
--- a/grub-core/net/drivers/efi/efinet.c |
|
+++ b/grub-core/net/drivers/efi/efinet.c |
|
@@ -18,11 +18,15 @@ |
|
|
|
#include <grub/net/netbuff.h> |
|
#include <grub/dl.h> |
|
+#include <grub/env.h> |
|
#include <grub/net.h> |
|
+#include <grub/net/url.h> |
|
#include <grub/time.h> |
|
#include <grub/efi/api.h> |
|
#include <grub/efi/efi.h> |
|
#include <grub/i18n.h> |
|
+#include <grub/lib/hexdump.h> |
|
+#include <grub/types.h> |
|
|
|
GRUB_MOD_LICENSE ("GPLv3+"); |
|
|
|
@@ -339,7 +343,7 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, |
|
char **path) |
|
{ |
|
struct grub_net_card *card; |
|
- grub_efi_device_path_t *dp; |
|
+ grub_efi_device_path_t *dp, *ldp = NULL; |
|
|
|
dp = grub_efi_get_device_path (hnd); |
|
if (! dp) |
|
@@ -350,14 +354,19 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, |
|
grub_efi_device_path_t *cdp; |
|
struct grub_efi_pxe *pxe; |
|
struct grub_efi_pxe_mode *pxe_mode; |
|
+ |
|
if (card->driver != &efidriver) |
|
continue; |
|
+ |
|
cdp = grub_efi_get_device_path (card->efi_handle); |
|
if (! cdp) |
|
continue; |
|
+ |
|
+ ldp = grub_efi_find_last_device_path (dp); |
|
+ |
|
if (grub_efi_compare_device_paths (dp, cdp) != 0) |
|
{ |
|
- grub_efi_device_path_t *ldp, *dup_dp, *dup_ldp; |
|
+ grub_efi_device_path_t *dup_dp, *dup_ldp; |
|
int match; |
|
|
|
/* EDK2 UEFI PXE driver creates pseudo devices with type IPv4/IPv6 |
|
@@ -366,7 +375,6 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, |
|
devices. We skip them when enumerating cards, so here we need to |
|
find matching MAC device. |
|
*/ |
|
- ldp = grub_efi_find_last_device_path (dp); |
|
if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE |
|
|| (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE |
|
&& GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE)) |
|
@@ -383,16 +391,44 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, |
|
if (!match) |
|
continue; |
|
} |
|
+ |
|
pxe = grub_efi_open_protocol (hnd, &pxe_io_guid, |
|
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); |
|
if (! pxe) |
|
continue; |
|
+ |
|
pxe_mode = pxe->mode; |
|
- grub_net_configure_by_dhcp_ack (card->name, card, 0, |
|
- (struct grub_net_bootp_packet *) |
|
- &pxe_mode->dhcp_ack, |
|
- sizeof (pxe_mode->dhcp_ack), |
|
- 1, device, path); |
|
+ if (pxe_mode->using_ipv6) |
|
+ { |
|
+ grub_net_link_level_address_t hwaddr; |
|
+ |
|
+ grub_dprintf ("efinet", "using ipv6 and dhcpv6\n"); |
|
+ grub_dprintf ("efinet", "dhcp_ack_received: %s%s\n", |
|
+ pxe_mode->dhcp_ack_received ? "yes" : "no", |
|
+ pxe_mode->dhcp_ack_received ? "" : " cannot continue"); |
|
+ if (!pxe_mode->dhcp_ack_received) |
|
+ continue; |
|
+ |
|
+ hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; |
|
+ grub_memcpy (hwaddr.mac, |
|
+ card->efi_net->mode->current_address, |
|
+ sizeof (hwaddr.mac)); |
|
+ |
|
+ grub_net_configure_by_dhcpv6_ack (card->name, card, 0, |
|
+ &hwaddr, &pxe_mode->dhcp_ack, |
|
+ 1, device, path); |
|
+ grub_dprintf ("efinet", "device: `%s' path: `%s'\n", *device, *path); |
|
+ } |
|
+ else |
|
+ { |
|
+ grub_dprintf ("efinet", "using ipv4 and dhcp\n"); |
|
+ grub_net_configure_by_dhcp_ack (card->name, card, 0, |
|
+ (struct grub_net_bootp_packet *) |
|
+ &pxe_mode->dhcp_ack, |
|
+ sizeof (pxe_mode->dhcp_ack), |
|
+ 1, device, path); |
|
+ grub_dprintf ("efinet", "device: `%s' path: `%s'\n", *device, *path); |
|
+ } |
|
return; |
|
} |
|
} |
|
diff --git a/grub-core/net/net.c b/grub-core/net/net.c |
|
index b10addbe27b..81d3b6208cb 100644 |
|
--- a/grub-core/net/net.c |
|
+++ b/grub-core/net/net.c |
|
@@ -969,6 +969,73 @@ grub_net_network_level_interface_register (struct grub_net_network_level_interfa |
|
grub_net_network_level_interfaces = inter; |
|
} |
|
|
|
+int |
|
+grub_ipv6_get_masksize(grub_uint8_t *be_mask) |
|
+{ |
|
+ grub_uint8_t *mask; |
|
+ grub_uint16_t mask16[8]; |
|
+ unsigned int x; |
|
+ int ret = 0; |
|
+ |
|
+ grub_memcpy (mask16, be_mask, sizeof(mask16)); |
|
+ for (x = 0; x < 8; x++) |
|
+ mask16[x] = grub_be_to_cpu16 (mask16[x]); |
|
+ |
|
+ mask = (grub_uint8_t *)mask16; |
|
+ |
|
+ for (x = 15; x > 0; x++) |
|
+ { |
|
+ grub_uint8_t octet = mask[x]; |
|
+ while (octet & 0x80) |
|
+ { |
|
+ ret++; |
|
+ octet <<= 1; |
|
+ } |
|
+ if (ret) |
|
+ ret += 8 * (15 - x); |
|
+ break; |
|
+ } |
|
+ |
|
+ return ret; |
|
+} |
|
+ |
|
+grub_err_t |
|
+grub_net_add_ipv6_local (struct grub_net_network_level_interface *inter, |
|
+ int mask) |
|
+{ |
|
+ struct grub_net_route *route; |
|
+ |
|
+ if (inter->address.type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6) |
|
+ return 0; |
|
+ |
|
+ if (mask == -1) |
|
+ mask = grub_ipv6_get_masksize ((grub_uint8_t *)inter->address.ipv6); |
|
+ |
|
+ if (mask == -1) |
|
+ return 0; |
|
+ |
|
+ route = grub_zalloc (sizeof (*route)); |
|
+ if (!route) |
|
+ return grub_errno; |
|
+ |
|
+ route->name = grub_xasprintf ("%s:local", inter->name); |
|
+ if (!route->name) |
|
+ { |
|
+ grub_free (route); |
|
+ return grub_errno; |
|
+ } |
|
+ |
|
+ route->target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; |
|
+ grub_memcpy (route->target.ipv6.base, inter->address.ipv6, |
|
+ sizeof (inter->address.ipv6)); |
|
+ route->target.ipv6.masksize = mask; |
|
+ route->is_gateway = 0; |
|
+ route->interface = inter; |
|
+ |
|
+ grub_net_route_register (route); |
|
+ |
|
+ return 0; |
|
+} |
|
|
|
grub_err_t |
|
grub_net_add_ipv4_local (struct grub_net_network_level_interface *inter, |
|
diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c |
|
index 51736142764..22a4debdcd4 100644 |
|
--- a/grub-core/net/tftp.c |
|
+++ b/grub-core/net/tftp.c |
|
@@ -370,18 +370,22 @@ tftp_open (struct grub_file *file, const char *filename) |
|
if (!data->pq) |
|
return grub_errno; |
|
|
|
+ grub_dprintf("tftp", "resolving address for %s\n", file->device->net->server); |
|
err = grub_net_resolve_address (file->device->net->server, &addr); |
|
if (err) |
|
{ |
|
+ grub_dprintf("tftp", "Address resolution failed: %d\n", err); |
|
destroy_pq (data); |
|
return err; |
|
} |
|
|
|
+ grub_dprintf("tftp", "opening connection\n"); |
|
data->sock = grub_net_udp_open (addr, |
|
TFTP_SERVER_PORT, tftp_receive, |
|
file); |
|
if (!data->sock) |
|
{ |
|
+ grub_dprintf("tftp", "connection failed\n"); |
|
destroy_pq (data); |
|
return grub_errno; |
|
} |
|
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h |
|
index a6cce6e3395..9422ba9a9db 100644 |
|
--- a/include/grub/efi/api.h |
|
+++ b/include/grub/efi/api.h |
|
@@ -527,10 +527,16 @@ typedef void *grub_efi_handle_t; |
|
typedef void *grub_efi_event_t; |
|
typedef grub_efi_uint64_t grub_efi_lba_t; |
|
typedef grub_efi_uintn_t grub_efi_tpl_t; |
|
-typedef grub_uint8_t grub_efi_mac_address_t[32]; |
|
-typedef grub_uint8_t grub_efi_ipv4_address_t[4]; |
|
-typedef grub_uint16_t grub_efi_ipv6_address_t[8]; |
|
-typedef grub_uint8_t grub_efi_ip_address_t[8] __attribute__ ((aligned(4))); |
|
+typedef grub_efi_uint8_t grub_efi_mac_address_t[32]; |
|
+typedef grub_efi_uint8_t grub_efi_ipv4_address_t[4]; |
|
+typedef grub_efi_uint8_t grub_efi_ipv6_address_t[16]; |
|
+typedef union |
|
+{ |
|
+ grub_efi_uint32_t addr[4]; |
|
+ grub_efi_ipv4_address_t v4; |
|
+ grub_efi_ipv6_address_t v6; |
|
+} grub_efi_ip_address_t __attribute__ ((aligned(4))); |
|
+ |
|
typedef grub_efi_uint64_t grub_efi_physical_address_t; |
|
typedef grub_efi_uint64_t grub_efi_virtual_address_t; |
|
|
|
@@ -1405,16 +1411,127 @@ struct grub_efi_simple_text_output_interface |
|
}; |
|
typedef struct grub_efi_simple_text_output_interface grub_efi_simple_text_output_interface_t; |
|
|
|
-typedef grub_uint8_t grub_efi_pxe_packet_t[1472]; |
|
+typedef struct grub_efi_pxe_dhcpv4_packet |
|
+{ |
|
+ grub_efi_uint8_t bootp_opcode; |
|
+ grub_efi_uint8_t bootp_hwtype; |
|
+ grub_efi_uint8_t bootp_hwaddr_len; |
|
+ grub_efi_uint8_t bootp_gate_hops; |
|
+ grub_efi_uint32_t bootp_ident; |
|
+ grub_efi_uint16_t bootp_seconds; |
|
+ grub_efi_uint16_t bootp_flags; |
|
+ grub_efi_uint8_t bootp_ci_addr[4]; |
|
+ grub_efi_uint8_t bootp_yi_addr[4]; |
|
+ grub_efi_uint8_t bootp_si_addr[4]; |
|
+ grub_efi_uint8_t bootp_gi_addr[4]; |
|
+ grub_efi_uint8_t bootp_hw_addr[16]; |
|
+ grub_efi_uint8_t bootp_srv_name[64]; |
|
+ grub_efi_uint8_t bootp_boot_file[128]; |
|
+ grub_efi_uint32_t dhcp_magik; |
|
+ grub_efi_uint8_t dhcp_options[56]; |
|
+} grub_efi_pxe_dhcpv4_packet_t; |
|
+ |
|
+struct grub_efi_pxe_dhcpv6_packet |
|
+{ |
|
+ grub_efi_uint32_t message_type:8; |
|
+ grub_efi_uint32_t transaction_id:24; |
|
+ grub_efi_uint8_t dhcp_options[1024]; |
|
+} GRUB_PACKED; |
|
+typedef struct grub_efi_pxe_dhcpv6_packet grub_efi_pxe_dhcpv6_packet_t; |
|
+ |
|
+typedef union |
|
+{ |
|
+ grub_efi_uint8_t raw[1472]; |
|
+ grub_efi_pxe_dhcpv4_packet_t dhcpv4; |
|
+ grub_efi_pxe_dhcpv6_packet_t dhcpv6; |
|
+} grub_efi_pxe_packet_t; |
|
+ |
|
+#define GRUB_EFI_PXE_MAX_IPCNT 8 |
|
+#define GRUB_EFI_PXE_MAX_ARP_ENTRIES 8 |
|
+#define GRUB_EFI_PXE_MAX_ROUTE_ENTRIES 8 |
|
+ |
|
+typedef struct grub_efi_pxe_ip_filter |
|
+{ |
|
+ grub_efi_uint8_t filters; |
|
+ grub_efi_uint8_t ip_count; |
|
+ grub_efi_uint8_t reserved; |
|
+ grub_efi_ip_address_t ip_list[GRUB_EFI_PXE_MAX_IPCNT]; |
|
+} grub_efi_pxe_ip_filter_t; |
|
+ |
|
+typedef struct grub_efi_pxe_arp_entry |
|
+{ |
|
+ grub_efi_ip_address_t ip_addr; |
|
+ grub_efi_mac_address_t mac_addr; |
|
+} grub_efi_pxe_arp_entry_t; |
|
+ |
|
+typedef struct grub_efi_pxe_route_entry |
|
+{ |
|
+ grub_efi_ip_address_t ip_addr; |
|
+ grub_efi_ip_address_t subnet_mask; |
|
+ grub_efi_ip_address_t gateway_addr; |
|
+} grub_efi_pxe_route_entry_t; |
|
+ |
|
+typedef struct grub_efi_pxe_icmp_error |
|
+{ |
|
+ grub_efi_uint8_t type; |
|
+ grub_efi_uint8_t code; |
|
+ grub_efi_uint16_t checksum; |
|
+ union |
|
+ { |
|
+ grub_efi_uint32_t reserved; |
|
+ grub_efi_uint32_t mtu; |
|
+ grub_efi_uint32_t pointer; |
|
+ struct |
|
+ { |
|
+ grub_efi_uint16_t identifier; |
|
+ grub_efi_uint16_t sequence; |
|
+ } echo; |
|
+ } u; |
|
+ grub_efi_uint8_t data[494]; |
|
+} grub_efi_pxe_icmp_error_t; |
|
+ |
|
+typedef struct grub_efi_pxe_tftp_error |
|
+{ |
|
+ grub_efi_uint8_t error_code; |
|
+ grub_efi_char8_t error_string[127]; |
|
+} grub_efi_pxe_tftp_error_t; |
|
|
|
typedef struct grub_efi_pxe_mode |
|
{ |
|
- grub_uint8_t unused[52]; |
|
+ grub_efi_boolean_t started; |
|
+ grub_efi_boolean_t ipv6_available; |
|
+ grub_efi_boolean_t ipv6_supported; |
|
+ grub_efi_boolean_t using_ipv6; |
|
+ grub_efi_boolean_t bis_supported; |
|
+ grub_efi_boolean_t bis_detected; |
|
+ grub_efi_boolean_t auto_arp; |
|
+ grub_efi_boolean_t send_guid; |
|
+ grub_efi_boolean_t dhcp_discover_valid; |
|
+ grub_efi_boolean_t dhcp_ack_received; |
|
+ grub_efi_boolean_t proxy_offer_received; |
|
+ grub_efi_boolean_t pxe_discover_valid; |
|
+ grub_efi_boolean_t pxe_reply_received; |
|
+ grub_efi_boolean_t pxe_bis_reply_received; |
|
+ grub_efi_boolean_t icmp_error_received; |
|
+ grub_efi_boolean_t tftp_error_received; |
|
+ grub_efi_boolean_t make_callbacks; |
|
+ grub_efi_uint8_t ttl; |
|
+ grub_efi_uint8_t tos; |
|
+ grub_efi_ip_address_t station_ip; |
|
+ grub_efi_ip_address_t subnet_mask; |
|
grub_efi_pxe_packet_t dhcp_discover; |
|
grub_efi_pxe_packet_t dhcp_ack; |
|
grub_efi_pxe_packet_t proxy_offer; |
|
grub_efi_pxe_packet_t pxe_discover; |
|
grub_efi_pxe_packet_t pxe_reply; |
|
+ grub_efi_pxe_packet_t pxe_bis_reply; |
|
+ grub_efi_pxe_ip_filter_t ip_filter; |
|
+ grub_efi_uint32_t arp_cache_entries; |
|
+ grub_efi_pxe_arp_entry_t arp_cache[GRUB_EFI_PXE_MAX_ARP_ENTRIES]; |
|
+ grub_efi_uint32_t route_table_entries; |
|
+ grub_efi_pxe_route_entry_t route_table[GRUB_EFI_PXE_MAX_ROUTE_ENTRIES]; |
|
+ grub_efi_pxe_icmp_error_t icmp_error; |
|
+ grub_efi_pxe_tftp_error_t tftp_error; |
|
} grub_efi_pxe_mode_t; |
|
|
|
typedef struct grub_efi_pxe |
|
diff --git a/include/grub/net.h b/include/grub/net.h |
|
index 88fc71ceffe..c7b8e2ac885 100644 |
|
--- a/include/grub/net.h |
|
+++ b/include/grub/net.h |
|
@@ -418,6 +418,51 @@ struct grub_net_bootp_packet |
|
grub_uint8_t vendor[0]; |
|
} GRUB_PACKED; |
|
|
|
+enum |
|
+ { |
|
+ GRUB_NET_DHCP6_IA_NA = 3, |
|
+ GRUB_NET_DHCP6_IA_ADDRESS = 5, |
|
+ GRUB_NET_DHCP6_BOOTFILE_URL = 59, |
|
+ }; |
|
+ |
|
+struct grub_net_dhcpv6_option |
|
+{ |
|
+ grub_uint16_t option_num; |
|
+ grub_uint16_t option_len; |
|
+ grub_uint8_t option_data[]; |
|
+} GRUB_PACKED; |
|
+typedef struct grub_net_dhcpv6_option grub_net_dhcpv6_option_t; |
|
+ |
|
+struct grub_net_dhcpv6_opt_ia_na |
|
+{ |
|
+ grub_uint16_t option_num; |
|
+ grub_uint16_t option_len; |
|
+ grub_uint32_t iaid; |
|
+ grub_uint32_t t1; |
|
+ grub_uint32_t t2; |
|
+ grub_uint8_t options[]; |
|
+} GRUB_PACKED; |
|
+typedef struct grub_net_dhcpv6_opt_ia_na grub_net_dhcpv6_opt_ia_na_t; |
|
+ |
|
+struct grub_net_dhcpv6_opt_ia_address |
|
+{ |
|
+ grub_uint16_t option_num; |
|
+ grub_uint16_t option_len; |
|
+ grub_uint64_t ipv6_address[2]; |
|
+ grub_uint32_t preferred_lifetime; |
|
+ grub_uint32_t valid_lifetime; |
|
+ grub_uint8_t options[]; |
|
+} GRUB_PACKED; |
|
+typedef struct grub_net_dhcpv6_opt_ia_address grub_net_dhcpv6_opt_ia_address_t; |
|
+ |
|
+struct grub_net_dhcpv6_packet |
|
+{ |
|
+ grub_uint32_t message_type:8; |
|
+ grub_uint32_t transaction_id:24; |
|
+ grub_uint8_t dhcp_options[1024]; |
|
+} GRUB_PACKED; |
|
+typedef struct grub_net_dhcpv6_packet grub_net_dhcpv6_packet_t; |
|
+ |
|
#define GRUB_NET_BOOTP_RFC1048_MAGIC_0 0x63 |
|
#define GRUB_NET_BOOTP_RFC1048_MAGIC_1 0x82 |
|
#define GRUB_NET_BOOTP_RFC1048_MAGIC_2 0x53 |
|
@@ -446,6 +491,21 @@ grub_net_configure_by_dhcp_ack (const char *name, |
|
grub_size_t size, |
|
int is_def, char **device, char **path); |
|
|
|
+struct grub_net_network_level_interface * |
|
+grub_net_configure_by_dhcpv6_ack (const char *name, |
|
+ struct grub_net_card *card, |
|
+ grub_net_interface_flags_t flags, |
|
+ const grub_net_link_level_address_t *hwaddr, |
|
+ const struct grub_net_dhcpv6_packet *packet, |
|
+ int is_def, char **device, char **path); |
|
+ |
|
+int |
|
+grub_ipv6_get_masksize(grub_uint8_t *mask); |
|
+ |
|
+grub_err_t |
|
+grub_net_add_ipv6_local (struct grub_net_network_level_interface *inf, |
|
+ int mask); |
|
+ |
|
grub_err_t |
|
grub_net_add_ipv4_local (struct grub_net_network_level_interface *inf, |
|
int mask);
|
|
|