aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2019-05-16 11:18:49 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2019-05-16 11:18:49 +0200
commita840884531df649aabc72debb2d6025dabe2abb3 (patch)
treef953e5ac4ac2c7ae6535ac5569fb809cef9d929a
parent9bf6780c2888805908d9485681dadffeab3414f7 (diff)
downloadbusybox-w32-a840884531df649aabc72debb2d6025dabe2abb3.tar.gz
busybox-w32-a840884531df649aabc72debb2d6025dabe2abb3.tar.bz2
busybox-w32-a840884531df649aabc72debb2d6025dabe2abb3.zip
udhcpd: support per-client hostnames in static leases
function old new delta read_staticlease 222 299 +77 add_server_options 92 154 +62 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 139/0) Total: 139 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--examples/udhcp/udhcpd.conf9
-rw-r--r--networking/udhcp/dhcpd.c72
-rw-r--r--networking/udhcp/dhcpd.h6
3 files changed, 71 insertions, 16 deletions
diff --git a/examples/udhcp/udhcpd.conf b/examples/udhcp/udhcpd.conf
index bb8774e08..df1258aaf 100644
--- a/examples/udhcp/udhcpd.conf
+++ b/examples/udhcp/udhcpd.conf
@@ -44,7 +44,7 @@ interface eth0
44#notify_file # default: no script 44#notify_file # default: no script
45#notify_file dumpleases # useful for debugging 45#notify_file dumpleases # useful for debugging
46 46
47# The following are bootp specific options 47# The following are BOOTP specific options
48# next server to use in bootstrap 48# next server to use in bootstrap
49#siaddr 192.168.0.22 # default: 0.0.0.0 (none) 49#siaddr 192.168.0.22 # default: 0.0.0.0 (none)
50# tftp server name 50# tftp server name
@@ -52,9 +52,14 @@ interface eth0
52# tftp file to download (e.g. kernel image) 52# tftp file to download (e.g. kernel image)
53#boot_file /var/nfs_root # default: none 53#boot_file /var/nfs_root # default: none
54 54
55# NOTE: "boot_file FILE" and "opt bootfile FILE" are conceptually the same,
56# but "boot_file" goes into BOOTP-defined fixed-size field in the packet,
57# whereas "opt bootfile" goes into DHCP option 0x43.
58# Same for "sname HOST" and "opt tftp HOST".
59
55# Static leases map 60# Static leases map
56#static_lease 00:60:08:11:CE:4E 192.168.0.54 61#static_lease 00:60:08:11:CE:4E 192.168.0.54
57#static_lease 00:60:08:11:CE:3E 192.168.0.44 62#static_lease 00:60:08:11:CE:3E 192.168.0.44 optional_hostname
58 63
59# The remainder of options are DHCP options and can be specified with the 64# The remainder of options are DHCP options and can be specified with the
60# keyword 'opt' or 'option'. If an option can take multiple items, such 65# keyword 'opt' or 'option'. If an option can take multiple items, such
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c
index bf44320a1..f231e4001 100644
--- a/networking/udhcp/dhcpd.c
+++ b/networking/udhcp/dhcpd.c
@@ -48,14 +48,23 @@
48#define g_leases ((struct dyn_lease*)ptr_to_globals) 48#define g_leases ((struct dyn_lease*)ptr_to_globals)
49/* struct server_config_t server_config is in bb_common_bufsiz1 */ 49/* struct server_config_t server_config is in bb_common_bufsiz1 */
50 50
51struct static_lease {
52 struct static_lease *next;
53 uint32_t nip;
54 uint8_t mac[6];
55 uint8_t opt[1];
56};
57
51/* Takes the address of the pointer to the static_leases linked list, 58/* Takes the address of the pointer to the static_leases linked list,
52 * address to a 6 byte mac address, 59 * address to a 6 byte mac address,
53 * 4 byte IP address */ 60 * 4 byte IP address */
54static void add_static_lease(struct static_lease **st_lease_pp, 61static void add_static_lease(struct static_lease **st_lease_pp,
55 uint8_t *mac, 62 uint8_t *mac,
56 uint32_t nip) 63 uint32_t nip,
64 const char *opts)
57{ 65{
58 struct static_lease *st_lease; 66 struct static_lease *st_lease;
67 unsigned optlen;
59 68
60 /* Find the tail of the list */ 69 /* Find the tail of the list */
61 while ((st_lease = *st_lease_pp) != NULL) { 70 while ((st_lease = *st_lease_pp) != NULL) {
@@ -63,10 +72,17 @@ static void add_static_lease(struct static_lease **st_lease_pp,
63 } 72 }
64 73
65 /* Add new node */ 74 /* Add new node */
66 *st_lease_pp = st_lease = xzalloc(sizeof(*st_lease)); 75 optlen = (opts ? 1+1+strnlen(opts, 120) : 0);
76 *st_lease_pp = st_lease = xzalloc(sizeof(*st_lease) + optlen);
67 memcpy(st_lease->mac, mac, 6); 77 memcpy(st_lease->mac, mac, 6);
68 st_lease->nip = nip; 78 st_lease->nip = nip;
69 /*st_lease->next = NULL;*/ 79 /*st_lease->next = NULL;*/
80 if (optlen) {
81 st_lease->opt[OPT_CODE] = DHCP_HOST_NAME;
82 optlen -= 2;
83 st_lease->opt[OPT_LEN] = optlen;
84 memcpy(&st_lease->opt[OPT_DATA], opts, optlen);
85 }
70} 86}
71 87
72/* Find static lease IP by mac */ 88/* Find static lease IP by mac */
@@ -344,6 +360,7 @@ static int FAST_FUNC read_staticlease(const char *const_line, void *arg)
344 char *line; 360 char *line;
345 char *mac_string; 361 char *mac_string;
346 char *ip_string; 362 char *ip_string;
363 char *opts;
347 struct ether_addr mac_bytes; /* it's "struct { uint8_t mac[6]; }" */ 364 struct ether_addr mac_bytes; /* it's "struct { uint8_t mac[6]; }" */
348 uint32_t nip; 365 uint32_t nip;
349 366
@@ -358,7 +375,10 @@ static int FAST_FUNC read_staticlease(const char *const_line, void *arg)
358 if (!ip_string || !udhcp_str2nip(ip_string, &nip)) 375 if (!ip_string || !udhcp_str2nip(ip_string, &nip))
359 return 0; 376 return 0;
360 377
361 add_static_lease(arg, (uint8_t*) &mac_bytes, nip); 378 opts = strtok_r(NULL, " \t", &line);
379 /* opts might be NULL, that's not an error */
380
381 add_static_lease(arg, (uint8_t*) &mac_bytes, nip, opts);
362 382
363 log_static_leases(arg); 383 log_static_leases(arg);
364 384
@@ -626,14 +646,49 @@ static void init_packet(struct dhcp_packet *packet, struct dhcp_packet *oldpacke
626 */ 646 */
627static void add_server_options(struct dhcp_packet *packet) 647static void add_server_options(struct dhcp_packet *packet)
628{ 648{
629 struct option_set *curr = server_config.options; 649 struct option_set *config_opts;
650 uint8_t *client_hostname_opt;
651
652 client_hostname_opt = NULL;
653 if (packet->yiaddr) { /* if we aren't from send_inform()... */
654 struct static_lease *st_lease = server_config.static_leases;
655 while (st_lease) {
656 if (st_lease->nip == packet->yiaddr) {
657 if (st_lease->opt[0] != 0)
658 client_hostname_opt = st_lease->opt;
659 break;
660 }
661 st_lease = st_lease->next;
662 }
663 }
630 664
631 while (curr) { 665 config_opts = server_config.options;
632 if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) 666 while (config_opts) {
633 udhcp_add_binary_option(packet, curr->data); 667 if (config_opts->data[OPT_CODE] != DHCP_LEASE_TIME) {
634 curr = curr->next; 668 /* ^^^^
669 * DHCP_LEASE_TIME is already filled, or in case of
670 * send_inform(), should not be filled at all.
671 */
672 if (config_opts->data[OPT_CODE] != DHCP_HOST_NAME
673 || !client_hostname_opt
674 ) {
675 /* Why "!client_hostname_opt":
676 * add hostname only if client has no hostname
677 * on its static lease line.
678 * (Not that "opt hostname HOST"
679 * makes much sense in udhcpd.conf,
680 * that'd give all clients the same hostname,
681 * but it's a valid configuration).
682 */
683 udhcp_add_binary_option(packet, config_opts->data);
684 }
685 }
686 config_opts = config_opts->next;
635 } 687 }
636 688
689 if (client_hostname_opt)
690 udhcp_add_binary_option(packet, client_hostname_opt);
691
637 packet->siaddr_nip = server_config.siaddr_nip; 692 packet->siaddr_nip = server_config.siaddr_nip;
638 693
639 if (server_config.sname) 694 if (server_config.sname)
@@ -753,7 +808,6 @@ static NOINLINE void send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr)
753 808
754 lease_time_sec = select_lease_time(oldpacket); 809 lease_time_sec = select_lease_time(oldpacket);
755 udhcp_add_simple_option(&packet, DHCP_LEASE_TIME, htonl(lease_time_sec)); 810 udhcp_add_simple_option(&packet, DHCP_LEASE_TIME, htonl(lease_time_sec));
756
757 add_server_options(&packet); 811 add_server_options(&packet);
758 812
759 addr.s_addr = yiaddr; 813 addr.s_addr = yiaddr;
diff --git a/networking/udhcp/dhcpd.h b/networking/udhcp/dhcpd.h
index b8f96b029..5c3bf5147 100644
--- a/networking/udhcp/dhcpd.h
+++ b/networking/udhcp/dhcpd.h
@@ -15,11 +15,7 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
15#define DHCPD_CONF_FILE "/etc/udhcpd.conf" 15#define DHCPD_CONF_FILE "/etc/udhcpd.conf"
16 16
17 17
18struct static_lease { 18struct static_lease;
19 struct static_lease *next;
20 uint32_t nip;
21 uint8_t mac[6];
22};
23 19
24struct server_config_t { 20struct server_config_t {
25 char *interface; /* interface to use */ 21 char *interface; /* interface to use */