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>
This commit is contained in:
parent
9bf6780c28
commit
a840884531
@ -44,7 +44,7 @@ interface eth0
|
|||||||
#notify_file # default: no script
|
#notify_file # default: no script
|
||||||
#notify_file dumpleases # useful for debugging
|
#notify_file dumpleases # useful for debugging
|
||||||
|
|
||||||
# The following are bootp specific options
|
# The following are BOOTP specific options
|
||||||
# next server to use in bootstrap
|
# next server to use in bootstrap
|
||||||
#siaddr 192.168.0.22 # default: 0.0.0.0 (none)
|
#siaddr 192.168.0.22 # default: 0.0.0.0 (none)
|
||||||
# tftp server name
|
# tftp server name
|
||||||
@ -52,9 +52,14 @@ interface eth0
|
|||||||
# tftp file to download (e.g. kernel image)
|
# tftp file to download (e.g. kernel image)
|
||||||
#boot_file /var/nfs_root # default: none
|
#boot_file /var/nfs_root # default: none
|
||||||
|
|
||||||
|
# NOTE: "boot_file FILE" and "opt bootfile FILE" are conceptually the same,
|
||||||
|
# but "boot_file" goes into BOOTP-defined fixed-size field in the packet,
|
||||||
|
# whereas "opt bootfile" goes into DHCP option 0x43.
|
||||||
|
# Same for "sname HOST" and "opt tftp HOST".
|
||||||
|
|
||||||
# Static leases map
|
# Static leases map
|
||||||
#static_lease 00:60:08:11:CE:4E 192.168.0.54
|
#static_lease 00:60:08:11:CE:4E 192.168.0.54
|
||||||
#static_lease 00:60:08:11:CE:3E 192.168.0.44
|
#static_lease 00:60:08:11:CE:3E 192.168.0.44 optional_hostname
|
||||||
|
|
||||||
# The remainder of options are DHCP options and can be specified with the
|
# 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
|
# keyword 'opt' or 'option'. If an option can take multiple items, such
|
||||||
|
@ -48,14 +48,23 @@
|
|||||||
#define g_leases ((struct dyn_lease*)ptr_to_globals)
|
#define g_leases ((struct dyn_lease*)ptr_to_globals)
|
||||||
/* struct server_config_t server_config is in bb_common_bufsiz1 */
|
/* struct server_config_t server_config is in bb_common_bufsiz1 */
|
||||||
|
|
||||||
|
struct static_lease {
|
||||||
|
struct static_lease *next;
|
||||||
|
uint32_t nip;
|
||||||
|
uint8_t mac[6];
|
||||||
|
uint8_t opt[1];
|
||||||
|
};
|
||||||
|
|
||||||
/* Takes the address of the pointer to the static_leases linked list,
|
/* Takes the address of the pointer to the static_leases linked list,
|
||||||
* address to a 6 byte mac address,
|
* address to a 6 byte mac address,
|
||||||
* 4 byte IP address */
|
* 4 byte IP address */
|
||||||
static void add_static_lease(struct static_lease **st_lease_pp,
|
static void add_static_lease(struct static_lease **st_lease_pp,
|
||||||
uint8_t *mac,
|
uint8_t *mac,
|
||||||
uint32_t nip)
|
uint32_t nip,
|
||||||
|
const char *opts)
|
||||||
{
|
{
|
||||||
struct static_lease *st_lease;
|
struct static_lease *st_lease;
|
||||||
|
unsigned optlen;
|
||||||
|
|
||||||
/* Find the tail of the list */
|
/* Find the tail of the list */
|
||||||
while ((st_lease = *st_lease_pp) != NULL) {
|
while ((st_lease = *st_lease_pp) != NULL) {
|
||||||
@ -63,10 +72,17 @@ static void add_static_lease(struct static_lease **st_lease_pp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Add new node */
|
/* Add new node */
|
||||||
*st_lease_pp = st_lease = xzalloc(sizeof(*st_lease));
|
optlen = (opts ? 1+1+strnlen(opts, 120) : 0);
|
||||||
|
*st_lease_pp = st_lease = xzalloc(sizeof(*st_lease) + optlen);
|
||||||
memcpy(st_lease->mac, mac, 6);
|
memcpy(st_lease->mac, mac, 6);
|
||||||
st_lease->nip = nip;
|
st_lease->nip = nip;
|
||||||
/*st_lease->next = NULL;*/
|
/*st_lease->next = NULL;*/
|
||||||
|
if (optlen) {
|
||||||
|
st_lease->opt[OPT_CODE] = DHCP_HOST_NAME;
|
||||||
|
optlen -= 2;
|
||||||
|
st_lease->opt[OPT_LEN] = optlen;
|
||||||
|
memcpy(&st_lease->opt[OPT_DATA], opts, optlen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find static lease IP by mac */
|
/* Find static lease IP by mac */
|
||||||
@ -344,6 +360,7 @@ static int FAST_FUNC read_staticlease(const char *const_line, void *arg)
|
|||||||
char *line;
|
char *line;
|
||||||
char *mac_string;
|
char *mac_string;
|
||||||
char *ip_string;
|
char *ip_string;
|
||||||
|
char *opts;
|
||||||
struct ether_addr mac_bytes; /* it's "struct { uint8_t mac[6]; }" */
|
struct ether_addr mac_bytes; /* it's "struct { uint8_t mac[6]; }" */
|
||||||
uint32_t nip;
|
uint32_t nip;
|
||||||
|
|
||||||
@ -358,7 +375,10 @@ static int FAST_FUNC read_staticlease(const char *const_line, void *arg)
|
|||||||
if (!ip_string || !udhcp_str2nip(ip_string, &nip))
|
if (!ip_string || !udhcp_str2nip(ip_string, &nip))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
add_static_lease(arg, (uint8_t*) &mac_bytes, nip);
|
opts = strtok_r(NULL, " \t", &line);
|
||||||
|
/* opts might be NULL, that's not an error */
|
||||||
|
|
||||||
|
add_static_lease(arg, (uint8_t*) &mac_bytes, nip, opts);
|
||||||
|
|
||||||
log_static_leases(arg);
|
log_static_leases(arg);
|
||||||
|
|
||||||
@ -626,14 +646,49 @@ static void init_packet(struct dhcp_packet *packet, struct dhcp_packet *oldpacke
|
|||||||
*/
|
*/
|
||||||
static void add_server_options(struct dhcp_packet *packet)
|
static void add_server_options(struct dhcp_packet *packet)
|
||||||
{
|
{
|
||||||
struct option_set *curr = server_config.options;
|
struct option_set *config_opts;
|
||||||
|
uint8_t *client_hostname_opt;
|
||||||
|
|
||||||
while (curr) {
|
client_hostname_opt = NULL;
|
||||||
if (curr->data[OPT_CODE] != DHCP_LEASE_TIME)
|
if (packet->yiaddr) { /* if we aren't from send_inform()... */
|
||||||
udhcp_add_binary_option(packet, curr->data);
|
struct static_lease *st_lease = server_config.static_leases;
|
||||||
curr = curr->next;
|
while (st_lease) {
|
||||||
|
if (st_lease->nip == packet->yiaddr) {
|
||||||
|
if (st_lease->opt[0] != 0)
|
||||||
|
client_hostname_opt = st_lease->opt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
st_lease = st_lease->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
config_opts = server_config.options;
|
||||||
|
while (config_opts) {
|
||||||
|
if (config_opts->data[OPT_CODE] != DHCP_LEASE_TIME) {
|
||||||
|
/* ^^^^
|
||||||
|
* DHCP_LEASE_TIME is already filled, or in case of
|
||||||
|
* send_inform(), should not be filled at all.
|
||||||
|
*/
|
||||||
|
if (config_opts->data[OPT_CODE] != DHCP_HOST_NAME
|
||||||
|
|| !client_hostname_opt
|
||||||
|
) {
|
||||||
|
/* Why "!client_hostname_opt":
|
||||||
|
* add hostname only if client has no hostname
|
||||||
|
* on its static lease line.
|
||||||
|
* (Not that "opt hostname HOST"
|
||||||
|
* makes much sense in udhcpd.conf,
|
||||||
|
* that'd give all clients the same hostname,
|
||||||
|
* but it's a valid configuration).
|
||||||
|
*/
|
||||||
|
udhcp_add_binary_option(packet, config_opts->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
config_opts = config_opts->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client_hostname_opt)
|
||||||
|
udhcp_add_binary_option(packet, client_hostname_opt);
|
||||||
|
|
||||||
packet->siaddr_nip = server_config.siaddr_nip;
|
packet->siaddr_nip = server_config.siaddr_nip;
|
||||||
|
|
||||||
if (server_config.sname)
|
if (server_config.sname)
|
||||||
@ -753,7 +808,6 @@ static NOINLINE void send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr)
|
|||||||
|
|
||||||
lease_time_sec = select_lease_time(oldpacket);
|
lease_time_sec = select_lease_time(oldpacket);
|
||||||
udhcp_add_simple_option(&packet, DHCP_LEASE_TIME, htonl(lease_time_sec));
|
udhcp_add_simple_option(&packet, DHCP_LEASE_TIME, htonl(lease_time_sec));
|
||||||
|
|
||||||
add_server_options(&packet);
|
add_server_options(&packet);
|
||||||
|
|
||||||
addr.s_addr = yiaddr;
|
addr.s_addr = yiaddr;
|
||||||
|
@ -15,11 +15,7 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
|
|||||||
#define DHCPD_CONF_FILE "/etc/udhcpd.conf"
|
#define DHCPD_CONF_FILE "/etc/udhcpd.conf"
|
||||||
|
|
||||||
|
|
||||||
struct static_lease {
|
struct static_lease;
|
||||||
struct static_lease *next;
|
|
||||||
uint32_t nip;
|
|
||||||
uint8_t mac[6];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct server_config_t {
|
struct server_config_t {
|
||||||
char *interface; /* interface to use */
|
char *interface; /* interface to use */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user