This patch adds the ability to specify a different boot_file for each
client. This is useful if clients have different CPU architectures or if
some clients are legacy BIOS and some are EFI.
It adds a config file option of the form
"for xx:xx:xx:xx:xx:xx boot_file foo" which sets the boot_file to "foo"
for the client with the MAC address xx:xx:xx:xx:xx:xx. If no such line
exists, the global boot_file will be used. The syntax of the option is
intended so that in the future, per-client options other than boot_file
could be added.
--- networking/udhcp/dhcpd.h.orig 2023-01-03 06:17:01.000000000 -0800
+++ networking/udhcp/dhcpd.h 2023-04-16 00:56:09.000000000 -0700
@@ -16,6 +16,7 @@
struct static_lease;
+struct boot_file_override;
struct server_data_t {
char *interface; /* interface to use */
@@ -51,6 +52,7 @@
char *sname; /* bootp server name */
char *boot_file; /* bootp boot file option */
struct static_lease *static_leases; /* List of ip/mac pairs to assign
static leases */
+ struct boot_file_override *boot_file_overrides; /* Boot files for
specific clients */
} FIX_ALIASING;
#define server_data (*(struct server_data_t*)bb_common_bufsiz1)
--- networking/udhcp/dhcpd.c.orig 2023-01-03 06:17:01.000000000 -0800
+++ networking/udhcp/dhcpd.c 2023-05-28 17:13:51.000000000 -0700
@@ -63,6 +63,12 @@
uint8_t opt[1];
};
+struct boot_file_override {
+ struct boot_file_override *next;
+ char *boot_file;
+ uint8_t mac[6];
+};
+
/* Takes the address of the pointer to the static_leases linked list,
* address to a 6 byte mac address,
* 4 byte IP address */
@@ -105,6 +111,33 @@
#endif
}
+static void add_boot_file_override(struct boot_file_override **bfo_pp,
+ uint8_t *mac,
+ const char *boot_file)
+{
+ struct boot_file_override *bfo;
+
+ /* Find the tail of the list */
+ while ((bfo = *bfo_pp) != NULL) {
+ bfo_pp = &bfo->next;
+ }
+
+ /* Add new node */
+ *bfo_pp = bfo = xzalloc(sizeof(*bfo));
+ memcpy(bfo->mac, mac, 6);
+ bfo->boot_file = strdup(boot_file);
+
+#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2
+ if (dhcp_verbose >= 2) {
+ bb_info_msg("boot file override:
mac:%02x:%02x:%02x:%02x:%02x:%02x boot_file:%s",
+ bfo->mac[0], bfo->mac[1], bfo->mac[2],
+ bfo->mac[3], bfo->mac[4], bfo->mac[5],
+ bfo->boot_file
+ );
+ }
+#endif
+}
+
/* Find static lease IP by mac */
static uint32_t get_static_nip_by_mac(void *mac)
{
@@ -380,6 +413,33 @@
return 1;
}
+static int FAST_FUNC read_bfo(const char *const_line, void *arg)
+{
+ char *line;
+ char *mac_string;
+ char *specifier;
+ struct ether_addr mac_bytes;
+ char *boot_file;
+
+ /* Read mac */
+ line = (char *) const_line;
+ mac_string = strtok_r(line, " \t", &line);
+ if (!mac_string || !ether_aton_r(mac_string, &mac_bytes))
+ return 0;
+
+ specifier = strtok_r(NULL, " \t", &line);
+ if (!specifier || strcasecmp(specifier, "boot_file")!=0)
+ return 0;
+
+ boot_file = strtok_r(NULL, " \t", &line);
+ if (!boot_file)
+ return 0;
+
+ add_boot_file_override(arg, (uint8_t*) &mac_bytes, boot_file);
+
+ return 1;
+}
+
static int FAST_FUNC read_optset(const char *line, void *arg)
{
return udhcp_str2optset(line, arg,
@@ -420,6 +480,7 @@
{"sname" , read_str , OFS(sname ), NULL},
{"boot_file" , read_str , OFS(boot_file ), NULL},
{"static_lease" , read_staticlease, OFS(static_leases), ""},
+ {"for" , read_bfo , OFS(boot_file_overrides), ""},
};
enum { KWS_WITH_DEFAULTS = ARRAY_SIZE(keywords) - 6 };
@@ -659,6 +720,7 @@
{
struct option_set *config_opts;
uint8_t *client_hostname_opt;
+ char *boot_file;
client_hostname_opt = NULL;
if (packet->yiaddr) { /* if we aren't from send_inform()... */
@@ -704,8 +766,21 @@
if (server_data.sname)
strncpy((char*)packet->sname, server_data.sname,
sizeof(packet->sname) - 1);
- if (server_data.boot_file)
- strncpy((char*)packet->file, server_data.boot_file,
sizeof(packet->file) - 1);
+
+ boot_file = server_data.boot_file;
+ if (packet->yiaddr) { /* if we aren't from send_inform()... */
+ struct boot_file_override *bfo =
server_data.boot_file_overrides;
+ while (bfo) {
+ if (memcmp(bfo->mac, packet->chaddr, 6) == 0) {
+ boot_file = bfo->boot_file;
+ break;
+ }
+ bfo = bfo->next;
+ }
+ }
+
+ if (boot_file)
+ strncpy((char*)packet->file, boot_file, sizeof(packet->file) -
1);
}
static uint32_t select_lease_time(struct dhcp_packet *packet)
--- examples/udhcp/udhcpd.conf.orig 2023-05-28 17:17:10.000000000 -0700
+++ examples/udhcp/udhcpd.conf 2023-05-28 17:30:19.000000000 -0700
@@ -61,6 +61,11 @@
#static_lease 00:60:08:11:CE:4E 192.168.0.54
#static_lease 00:60:08:11:CE:3E 192.168.0.44 optional_hostname
+# The boot_file can be specified on a client-by-client basis. If there is
+# no matching "for" line for a client, the global boot_file will be used.
+#for 12:34:56:78:90:00 boot_file syslinux32.efi
+#for 98:76:54:32:10:00 boot_file syslinux64.efi
+
# The remainder of options are DHCP options and can be specified with the
# keyword 'opt' or 'option'. If an option can take multiple items, such
# as the dns option, they can be listed on the same line, or multiple
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox