net/dhcp: Set net_<interface>_client{id, uuid} variables from DHCP options

This patch sets a net_<interface>_clientid and net_<interface>_clientuuid
GRUB environment variables, using the DHCP client ID and UUID options if
these are found.

In the same way than net_<interface>_<option> variables are set for other
options such domain name, boot file, next server, etc.

Signed-off-by: Paulo Flabiano Smorigo <pfsmorigo@br.ibm.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This commit is contained in:
Paulo Flabiano Smorigo 2020-01-22 12:01:54 +01:00 committed by Daniel Kiper
parent e921119857
commit febc761e67
2 changed files with 46 additions and 8 deletions

View file

@ -95,6 +95,14 @@ enum
/* Max timeout when waiting for BOOTP/DHCP reply */ /* Max timeout when waiting for BOOTP/DHCP reply */
#define GRUB_DHCP_MAX_PACKET_TIMEOUT 32 #define GRUB_DHCP_MAX_PACKET_TIMEOUT 32
static char
hexdigit (grub_uint8_t val)
{
if (val < 10)
return val + '0';
return val + 'a' - 10;
}
static const void * static const void *
find_dhcp_option (const struct grub_net_bootp_packet *bp, grub_size_t size, find_dhcp_option (const struct grub_net_bootp_packet *bp, grub_size_t size,
grub_uint8_t opt_code, grub_uint8_t *opt_len) grub_uint8_t opt_code, grub_uint8_t *opt_len)
@ -152,6 +160,9 @@ again:
if (i + taglength >= size) if (i + taglength >= size)
return NULL; return NULL;
grub_dprintf("net", "DHCP option %u (0x%02x) found with length %u.\n",
tagtype, tagtype, taglength);
/* FIXME RFC 3396 options concatentation */ /* FIXME RFC 3396 options concatentation */
if (tagtype == opt_code) if (tagtype == opt_code)
{ {
@ -406,6 +417,39 @@ grub_net_configure_by_dhcp_ack (const char *name,
if (opt && opt_len) if (opt && opt_len)
grub_env_set_net_property (name, "extensionspath", (const char *) opt, opt_len); grub_env_set_net_property (name, "extensionspath", (const char *) opt, opt_len);
opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_CLIENT_ID, &opt_len);
if (opt && opt_len)
grub_env_set_net_property (name, "clientid", (const char *) opt, opt_len);
opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_CLIENT_UUID, &opt_len);
if (opt && opt_len == 17)
{
/* The format is 9cfe245e-d0c8-bd45-a79f-54ea5fbd3d97 */
char *val;
int i, j = 0;
opt += 1;
opt_len -= 1;
val = grub_malloc (2 * opt_len + 4 + 1);
if (!val)
return inter;
for (i = 0; i < opt_len; i++)
{
val[2 * i + j] = hexdigit (opt[i] >> 4);
val[2 * i + 1 + j] = hexdigit (opt[i] & 0xf);
if ((i == 3) || (i == 5) || (i == 7) || (i == 9))
{
j++;
val[2 * i + 1+ j] = '-';
}
}
grub_env_set_net_property (name, "clientuuid", (char *) val, 2 * opt_len + 4);
grub_free (val);
}
inter->dhcp_ack = grub_malloc (size); inter->dhcp_ack = grub_malloc (size);
if (inter->dhcp_ack) if (inter->dhcp_ack)
{ {
@ -631,14 +675,6 @@ grub_net_process_dhcp (struct grub_net_buff *nb,
} }
} }
static char
hexdigit (grub_uint8_t val)
{
if (val < 10)
return val + '0';
return val + 'a' - 10;
}
static grub_err_t static grub_err_t
grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)),
int argc, char **args) int argc, char **args)

View file

@ -467,8 +467,10 @@ enum
GRUB_NET_DHCP_MESSAGE_TYPE = 53, GRUB_NET_DHCP_MESSAGE_TYPE = 53,
GRUB_NET_DHCP_SERVER_IDENTIFIER = 54, GRUB_NET_DHCP_SERVER_IDENTIFIER = 54,
GRUB_NET_DHCP_PARAMETER_REQUEST_LIST = 55, GRUB_NET_DHCP_PARAMETER_REQUEST_LIST = 55,
GRUB_NET_BOOTP_CLIENT_ID = 61,
GRUB_NET_DHCP_TFTP_SERVER_NAME = 66, GRUB_NET_DHCP_TFTP_SERVER_NAME = 66,
GRUB_NET_DHCP_BOOTFILE_NAME = 67, GRUB_NET_DHCP_BOOTFILE_NAME = 67,
GRUB_NET_BOOTP_CLIENT_UUID = 97,
GRUB_NET_BOOTP_END = 255 GRUB_NET_BOOTP_END = 255
}; };