diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2019-05-16 11:18:49 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2019-05-16 11:18:49 +0200 |
commit | a840884531df649aabc72debb2d6025dabe2abb3 (patch) | |
tree | f953e5ac4ac2c7ae6535ac5569fb809cef9d929a | |
parent | 9bf6780c2888805908d9485681dadffeab3414f7 (diff) | |
download | busybox-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.conf | 9 | ||||
-rw-r--r-- | networking/udhcp/dhcpd.c | 72 | ||||
-rw-r--r-- | networking/udhcp/dhcpd.h | 6 |
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 | ||
51 | struct 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 */ |
54 | static void add_static_lease(struct static_lease **st_lease_pp, | 61 | static 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 | */ |
627 | static void add_server_options(struct dhcp_packet *packet) | 647 | static 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 | ||
18 | struct static_lease { | 18 | struct static_lease; |
19 | struct static_lease *next; | ||
20 | uint32_t nip; | ||
21 | uint8_t mac[6]; | ||
22 | }; | ||
23 | 19 | ||
24 | struct server_config_t { | 20 | struct server_config_t { |
25 | char *interface; /* interface to use */ | 21 | char *interface; /* interface to use */ |