aboutsummaryrefslogtreecommitdiff
path: root/lib/libnet/dhcp.c
diff options
context:
space:
mode:
authorThomas Huth <thuth@redhat.com>2018-05-26 08:06:06 +0200
committerAlexey Kardashevskiy <aik@ozlabs.ru>2018-05-29 19:06:59 +1000
commit9976594366a3e0da456e4688ac93d802dad56c71 (patch)
tree98195e06236baa1f29bf44f9edf56476a39f7064 /lib/libnet/dhcp.c
parent08e22e4019030b2f643f65c192c64f3a939fec24 (diff)
downloadSLOF-9976594366a3e0da456e4688ac93d802dad56c71.zip
SLOF-9976594366a3e0da456e4688ac93d802dad56c71.tar.gz
SLOF-9976594366a3e0da456e4688ac93d802dad56c71.tar.bz2
libnet: Add support for DHCPv4 options 209 and 210
There are two dedicated DHCP options for loading PXELINUX config files, option 209 (config file name) and 210 (path prefix). We should support them, too, in case some users want to configure their boot flow this way. See RFC 5071 and the following URL for more details: https://www.syslinux.org/wiki/index.php?title=PXELINUX#DHCP_options Unlike most other strings in libnet, I've chosen to not use fixed-size arrays for these two strings, but to allocate the memory via malloc here. We always have to make sure not to overflow the stack in Paflof, so adding 2 * 256 byte arrays to struct filename_ip sounded just too dangerous to me. Signed-off-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Diffstat (limited to 'lib/libnet/dhcp.c')
-rw-r--r--lib/libnet/dhcp.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/lib/libnet/dhcp.c b/lib/libnet/dhcp.c
index d3e5170..85cd7c0 100644
--- a/lib/libnet/dhcp.c
+++ b/lib/libnet/dhcp.c
@@ -79,6 +79,8 @@
#define DHCP_TFTP_SERVER 66
#define DHCP_BOOTFILE 67
#define DHCP_CLIENT_ARCH 93
+#define DHCP_PXELINUX_CFGFILE 209 /* See RFC 5071 */
+#define DHCP_PXELINUX_PREFIX 210
#define DHCP_ENDOPT 0xFF
#define DHCP_PADOPT 0x00
@@ -167,6 +169,8 @@ static uint32_t dhcp_siaddr_ip = 0;
static char dhcp_filename[256];
static char dhcp_tftp_name[256];
static uint32_t dhcp_xid;
+static char *pxelinux_cfgfile;
+static char *pxelinux_prefix;
static char * response_buffer;
@@ -185,6 +189,8 @@ int32_t dhcpv4(char *ret_buffer, filename_ip_t *fn_ip)
strcpy(dhcp_filename, "");
strcpy(dhcp_tftp_name, "");
+ pxelinux_cfgfile = pxelinux_prefix = NULL;
+
response_buffer = ret_buffer;
if (dhcp_attempt(fd) == 0)
@@ -232,6 +238,10 @@ int32_t dhcpv4(char *ret_buffer, filename_ip_t *fn_ip)
fn_ip -> server_ip = dhcp_tftp_ip;
strcpy(fn_ip->filename, dhcp_filename);
+ fn_ip->pl_cfgfile = pxelinux_cfgfile;
+ fn_ip->pl_prefix = pxelinux_prefix;
+ pxelinux_cfgfile = pxelinux_prefix = NULL;
+
return 0;
}
@@ -456,6 +466,26 @@ static int32_t dhcp_decode_options(uint8_t opt_field[], uint32_t opt_len,
offset += 4;
break;
+ case DHCP_PXELINUX_CFGFILE:
+ pxelinux_cfgfile = malloc(opt_field[offset + 1] + 1);
+ if (pxelinux_cfgfile) {
+ memcpy(pxelinux_cfgfile, opt_field + offset + 2,
+ opt_field[offset + 1]);
+ pxelinux_cfgfile[opt_field[offset + 1]] = 0;
+ }
+ offset += 2 + opt_field[offset + 1];
+ break;
+
+ case DHCP_PXELINUX_PREFIX:
+ pxelinux_prefix = malloc(opt_field[offset + 1] + 1);
+ if (pxelinux_prefix) {
+ memcpy(pxelinux_prefix, opt_field + offset + 2,
+ opt_field[offset + 1]);
+ pxelinux_prefix[opt_field[offset + 1]] = 0;
+ }
+ offset += 2 + opt_field[offset + 1];
+ break;
+
case DHCP_PADOPT :
offset++;
break;
@@ -681,6 +711,9 @@ static void dhcp_send_request(int fd)
opt.request_list[DHCP_ROUTER] = 1;
opt.request_list[DHCP_TFTP_SERVER] = 1;
opt.request_list[DHCP_BOOTFILE] = 1;
+ opt.request_list[DHCP_PXELINUX_CFGFILE] = 1;
+ opt.request_list[DHCP_PXELINUX_PREFIX] = 1;
+
opt.request_list[DHCP_CLIENT_ARCH] = USE_DHCPARCH;
opt.flag[DHCP_CLIENT_ARCH] = USE_DHCPARCH;