grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/2] efinet and bootp: add support for dhcpv6


From: Javier Martinez Canillas
Subject: [PATCH 2/2] efinet and bootp: add support for dhcpv6
Date: Fri, 18 Oct 2019 14:41:16 +0200

From: Peter Jones <address@hidden>

Signed-off-by: Peter Jones <address@hidden>
Signed-off-by: Javier Martinez Canillas <address@hidden>
---

 grub-core/net/bootp.c              | 174 +++++++++++++++++++++++++++++
 grub-core/net/drivers/efi/efinet.c |  54 +++++++--
 grub-core/net/net.c                |  72 ++++++++++++
 grub-core/net/tftp.c               |   4 +
 include/grub/efi/api.h             | 129 ++++++++++++++++++++-
 include/grub/net.h                 |  60 ++++++++++
 6 files changed, 479 insertions(+), 14 deletions(-)

diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c
index 04cfbb04504..d4f13ab1a43 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>
 
 struct grub_dhcp_discover_options
@@ -866,6 +867,179 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ 
((unused)),
 
 static grub_command_t cmd_getdhcp, cmd_bootp, cmd_dhcp;
 
+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 || !path)
+    return NULL;
+
+  *device = 0;
+  *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_bootp_init (void)
 {
diff --git a/grub-core/net/drivers/efi/efinet.c 
b/grub-core/net/drivers/efi/efinet.c
index 5388f952ba9..a57189e8bb3 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+");
 
@@ -329,7 +333,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)
@@ -340,14 +344,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
@@ -356,7 +365,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))
@@ -373,16 +381,46 @@ 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;
+       struct grub_net_network_level_interface *intf;
+
+       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));
+
+       intf = grub_net_configure_by_dhcpv6_ack (card->name, card, 0, &hwaddr,
+             (const struct grub_net_dhcpv6_packet *)&pxe_mode->dhcp_ack.dhcpv6,
+             1, device, path);
+       if (intf && 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 d5d726a315e..160777066c1 100644
--- a/grub-core/net/net.c
+++ b/grub-core/net/net.c
@@ -955,6 +955,78 @@ grub_net_network_level_interface_register (struct 
grub_net_network_level_interfa
   grub_net_network_level_interfaces = inter;
 }
 
+int
+grub_ipv6_get_masksize (grub_uint16_t be_mask[8])
+{
+  grub_uint8_t *mask;
+  grub_uint16_t mask16[8];
+  int x, y;
+  int ret = 128;
+
+  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];
+      if (!octet)
+       {
+         ret -= 8;
+         continue;
+       }
+      for (y = 0; y < 8; y++)
+       {
+         if (octet & (1 << y))
+           break;
+         else
+           ret--;
+       }
+      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_uint16_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 7d90bf66e76..1157524fc50 100644
--- a/grub-core/net/tftp.c
+++ b/grub-core/net/tftp.c
@@ -379,19 +379,23 @@ tftp_open (struct grub_file *file, const char *filename)
       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);
       grub_free (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);
       grub_free (data);
       return grub_errno;
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
index 57607438435..17e48d5ae19 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -577,10 +577,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;
 
@@ -1455,16 +1461,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 4a9069a1474..da52bf06edf 100644
--- a/include/grub/net.h
+++ b/include/grub/net.h
@@ -447,6 +447,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
@@ -480,6 +525,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_uint16_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);
-- 
2.21.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]