grub-devel
[Top][All Lists]
Advanced

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

[PATCH v3 09/10] net: dhcp: actually send out DHCPv4 DISCOVER and REQUES


From: Andre Przywara
Subject: [PATCH v3 09/10] net: dhcp: actually send out DHCPv4 DISCOVER and REQUEST messages
Date: Thu, 7 Mar 2019 15:14:15 +0000

From: Andrei Borzenkov <address@hidden>

Even though we were parsing some DHCP options sent by the server, so far
we are only using the BOOTP 2-way handshake, even when talking to a DHCP
server.

Change this by actually sending out DHCP DISCOVER packets instead of the
generic (mostly empty) BOOTP BOOTREQUEST packets.

A pure BOOTP server would ignore the extra DHCP options in the DISCOVER
packet and would just reply with a BOOTREPLY packet, which we also
handle in the code.

Signed-off-by: Andre Przywara <address@hidden>
Reviewed-by: Daniel Kiper <address@hidden>
---
 grub-core/net/bootp.c | 120 +++++++++++++++++++++++++++++++++++++++++-
 include/grub/net.h    |   2 +
 2 files changed, 121 insertions(+), 1 deletion(-)

diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c
index d0482a7d5..63763aaab 100644
--- a/grub-core/net/bootp.c
+++ b/grub-core/net/bootp.c
@@ -25,6 +25,48 @@
 #include <grub/net/udp.h>
 #include <grub/datetime.h>
 
+struct grub_dhcp_discover_options
+{
+  grub_uint8_t magic[4];
+  struct
+  {
+    grub_uint8_t code;
+    grub_uint8_t len;
+    grub_uint8_t data;
+  } GRUB_PACKED  message_type;
+  grub_uint8_t end;
+} GRUB_PACKED;
+
+struct grub_dhcp_request_options
+{
+  grub_uint8_t magic[4];
+  struct
+  {
+    grub_uint8_t code;
+    grub_uint8_t len;
+    grub_uint8_t data;
+  } GRUB_PACKED  message_type;
+  struct
+  {
+    grub_uint8_t type;
+    grub_uint8_t len;
+    grub_uint32_t data;
+  } GRUB_PACKED        server_identifier;
+  struct
+  {
+    grub_uint8_t type;
+    grub_uint8_t len;
+    grub_uint32_t data;
+  } GRUB_PACKED        requested_ip;
+  struct
+  {
+    grub_uint8_t type;
+    grub_uint8_t len;
+    grub_uint8_t data[7];
+  } GRUB_PACKED        parameter_request;
+  grub_uint8_t end;
+} GRUB_PACKED;
+
 enum
 {
   GRUB_DHCP_OPT_OVERLOAD_FILE = 1,
@@ -43,6 +85,8 @@ enum
   GRUB_DHCP_MESSAGE_INFORM,
 };
 
+#define GRUB_BOOTP_MAX_OPTIONS_SIZE 64
+
 /* Max timeout when waiting for BOOTP/DHCP reply */
 #define GRUB_DHCP_MAX_PACKET_TIMEOUT 32
 
@@ -386,6 +430,64 @@ send_dhcp_packet (struct grub_net_network_level_interface 
*iface)
   grub_net_network_level_address_t target;
   grub_net_link_level_address_t ll_target;
 
+  static struct grub_dhcp_discover_options discover_options =
+    {
+      {
+       GRUB_NET_BOOTP_RFC1048_MAGIC_0,
+       GRUB_NET_BOOTP_RFC1048_MAGIC_1,
+       GRUB_NET_BOOTP_RFC1048_MAGIC_2,
+       GRUB_NET_BOOTP_RFC1048_MAGIC_3,
+      },
+      {
+       GRUB_NET_DHCP_MESSAGE_TYPE,
+       sizeof (discover_options.message_type.data),
+       GRUB_DHCP_MESSAGE_DISCOVER,
+      },
+      GRUB_NET_BOOTP_END,
+    };
+
+  static struct grub_dhcp_request_options request_options =
+    {
+      {
+       GRUB_NET_BOOTP_RFC1048_MAGIC_0,
+       GRUB_NET_BOOTP_RFC1048_MAGIC_1,
+       GRUB_NET_BOOTP_RFC1048_MAGIC_2,
+       GRUB_NET_BOOTP_RFC1048_MAGIC_3,
+      },
+      {
+       GRUB_NET_DHCP_MESSAGE_TYPE,
+       sizeof (request_options.message_type.data),
+       GRUB_DHCP_MESSAGE_REQUEST,
+      },
+      {
+       GRUB_NET_DHCP_SERVER_IDENTIFIER,
+       sizeof (request_options.server_identifier.data),
+       0,
+      },
+      {
+       GRUB_NET_DHCP_REQUESTED_IP_ADDRESS,
+       sizeof (request_options.requested_ip.data),
+       0,
+      },
+      {
+       GRUB_NET_DHCP_PARAMETER_REQUEST_LIST,
+       sizeof (request_options.parameter_request.data),
+       {
+         GRUB_NET_BOOTP_NETMASK,
+         GRUB_NET_BOOTP_ROUTER,
+         GRUB_NET_BOOTP_DNS,
+         GRUB_NET_BOOTP_DOMAIN,
+         GRUB_NET_BOOTP_HOSTNAME,
+         GRUB_NET_BOOTP_ROOT_PATH,
+         GRUB_NET_BOOTP_EXTENSIONS_PATH,
+       },
+      },
+      GRUB_NET_BOOTP_END,
+    };
+
+  COMPILE_TIME_ASSERT (sizeof (discover_options) <= 
GRUB_BOOTP_MAX_OPTIONS_SIZE);
+  COMPILE_TIME_ASSERT (sizeof (request_options) <= 
GRUB_BOOTP_MAX_OPTIONS_SIZE);
+
   nb = grub_netbuff_alloc (sizeof (*pack) + GRUB_BOOTP_MAX_OPTIONS_SIZE + 128);
   if (!nb)
     return grub_errno;
@@ -399,6 +501,19 @@ send_dhcp_packet (struct grub_net_network_level_interface 
*iface)
     goto out;
 
   grub_memset (nb->data, 0, GRUB_BOOTP_MAX_OPTIONS_SIZE);
+  if (!iface->srv_id)
+    {
+      grub_memcpy (nb->data, &discover_options, sizeof (discover_options));
+    }
+  else
+    {
+      struct grub_dhcp_request_options *ro = (struct grub_dhcp_request_options 
*) nb->data;
+
+      grub_memcpy (nb->data, &request_options, sizeof (request_options));
+      /* my_ip and srv_id are stored in network order so do not need 
conversion. */
+      grub_set_unaligned32 (&ro->server_identifier.data, iface->srv_id);
+      grub_set_unaligned32 (&ro->requested_ip.data, iface->my_ip);
+    }
 
   err = grub_netbuff_push (nb, sizeof (*pack));
   if (err)
@@ -416,7 +531,10 @@ send_dhcp_packet (struct grub_net_network_level_interface 
*iface)
       t = 0;
     }
   pack->seconds = grub_cpu_to_be16 (t);
-  pack->ident = grub_cpu_to_be32 (t);
+  if (!iface->srv_id)
+    iface->xid = pack->ident = grub_cpu_to_be32 (t);
+  else
+    pack->ident = iface->xid;
 
   grub_memcpy (&pack->mac_addr, &iface->hwaddress.mac, 6);
 
diff --git a/include/grub/net.h b/include/grub/net.h
index 68a9f1311..4a9069a14 100644
--- a/include/grub/net.h
+++ b/include/grub/net.h
@@ -462,9 +462,11 @@ enum
     GRUB_NET_BOOTP_DOMAIN = 0x0f,
     GRUB_NET_BOOTP_ROOT_PATH = 0x11,
     GRUB_NET_BOOTP_EXTENSIONS_PATH = 0x12,
+    GRUB_NET_DHCP_REQUESTED_IP_ADDRESS = 50,
     GRUB_NET_DHCP_OVERLOAD = 52,
     GRUB_NET_DHCP_MESSAGE_TYPE = 53,
     GRUB_NET_DHCP_SERVER_IDENTIFIER = 54,
+    GRUB_NET_DHCP_PARAMETER_REQUEST_LIST = 55,
     GRUB_NET_DHCP_TFTP_SERVER_NAME = 66,
     GRUB_NET_DHCP_BOOTFILE_NAME = 67,
     GRUB_NET_BOOTP_END = 0xff
-- 
2.17.1




reply via email to

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