[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 2/4] Send a user class identifier in bootp requests and tag it as
From: |
Matthew Garrett |
Subject: |
[PATCH 2/4] Send a user class identifier in bootp requests and tag it as DHCP discover |
Date: |
Mon, 23 Jan 2017 16:35:59 -0800 |
It's helpful to determine that a request was sent by grub in order to permit
the server to provide different information at different stages of the boot
process. Send GRUB2 as a type 77 DHCP option when sending bootp packets in
order to make this possible and tag the request as a DHCP discover to
convince servers to pay attention to it. Add the client architecture for
good measure.
---
grub-core/net/bootp.c | 42 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 41 insertions(+), 1 deletion(-)
diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c
index 9e2fdb7..0da8e24 100644
--- a/grub-core/net/bootp.c
+++ b/grub-core/net/bootp.c
@@ -25,6 +25,24 @@
#include <grub/net/udp.h>
#include <grub/datetime.h>
+#if !defined(GRUB_MACHINE_EFI) && (defined(__i386__) || defined(__x86_64__))
+#define GRUB_NET_BOOTP_ARCH 0x0000
+#elif defined(GRUB_MACHINE_EFI) && defined(__x86_64__)
+#define GRUB_NET_BOOTP_ARCH 0x0007
+#elif defined(GRUB_MACHINE_EFI) && defined(__aarch64__)
+#define GRUB_NET_BOOTP_ARCH 0x000B
+#else
+#error "unknown bootp architecture"
+#endif
+
+static grub_uint8_t dhcp_option_header[] = {GRUB_NET_BOOTP_RFC1048_MAGIC_0,
+ GRUB_NET_BOOTP_RFC1048_MAGIC_1,
+ GRUB_NET_BOOTP_RFC1048_MAGIC_2,
+ GRUB_NET_BOOTP_RFC1048_MAGIC_3};
+static grub_uint8_t grub_userclass[] = {0x4D, 0x06, 0x05, 'G', 'R', 'U', 'B',
'2'};
+static grub_uint8_t grub_dhcpdiscover[] = {0x35, 0x01, 0x01};
+static grub_uint8_t grub_dhcptime[] = {0x33, 0x04, 0x00, 0x00, 0x0e, 0x10};
+
static void
parse_dhcp_vendor (const char *name, const void *vend, int limit, int *mask)
{
@@ -499,10 +517,14 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__
((unused)),
struct udphdr *udph;
grub_net_network_level_address_t target;
grub_net_link_level_address_t ll_target;
+ grub_uint8_t *offset;
if (!ifaces[j].prev)
continue;
- nb = grub_netbuff_alloc (sizeof (*pack) + 64 + 128);
+ nb = grub_netbuff_alloc (sizeof (*pack) + sizeof(dhcp_option_header)
+ + sizeof(grub_userclass)
+ + sizeof(grub_dhcpdiscover)
+ + sizeof(grub_dhcptime) + 64 + 128);
if (!nb)
{
grub_netbuff_free (nb);
@@ -536,6 +558,24 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__
((unused)),
pack->seconds = grub_cpu_to_be16 (t);
grub_memcpy (&pack->mac_addr, &ifaces[j].hwaddress.mac, 6);
+ offset = (grub_uint8_t *)&pack->vendor;
+ grub_memcpy (offset, dhcp_option_header, sizeof(dhcp_option_header));
+ offset += sizeof(dhcp_option_header);
+ grub_memcpy (offset, grub_dhcpdiscover, sizeof(grub_dhcpdiscover));
+ offset += sizeof(grub_dhcpdiscover);
+ grub_memcpy (offset, grub_userclass, sizeof(grub_userclass));
+ offset += sizeof(grub_userclass);
+ grub_memcpy (offset, grub_dhcptime, sizeof(grub_dhcptime));
+
+ /* insert Client System Architecture (option 93) */
+ offset += sizeof(grub_dhcptime);
+ offset[0] = 93;
+ offset[1] = 2;
+ offset[2] = (GRUB_NET_BOOTP_ARCH >> 8);
+ offset[3] = (GRUB_NET_BOOTP_ARCH & 0xFF);
+
+ /* option terminator */
+ offset[4] = 255;
grub_netbuff_push (nb, sizeof (*udph));
--
2.9.3