From b34415180d2436d6ada769ebdc58f13cd41a777a Mon Sep 17 00:00:00 2001 From: florian Date: Tue, 4 Jan 2022 06:20:37 +0000 Subject: [PATCH] Make host name DHCP option configurable. Diff from hagen@sdf.org, tweaks by me. OK phessler testing & OK bket --- sbin/dhcpleased/dhcpleased.c | 6 +++- sbin/dhcpleased/dhcpleased.conf.5 | 11 +++++-- sbin/dhcpleased/dhcpleased.h | 4 ++- sbin/dhcpleased/engine.c | 15 +++++++++- sbin/dhcpleased/frontend.c | 48 +++++++++++++++++++++++++------ sbin/dhcpleased/parse.y | 32 +++++++++++++++++++-- sbin/dhcpleased/printconf.c | 10 ++++++- 7 files changed, 110 insertions(+), 16 deletions(-) diff --git a/sbin/dhcpleased/dhcpleased.c b/sbin/dhcpleased/dhcpleased.c index 497ca5a0a79..3972d2a7365 100644 --- a/sbin/dhcpleased/dhcpleased.c +++ b/sbin/dhcpleased/dhcpleased.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dhcpleased.c,v 1.22 2021/12/13 11:02:26 florian Exp $ */ +/* $OpenBSD: dhcpleased.c,v 1.23 2022/01/04 06:20:37 florian Exp $ */ /* * Copyright (c) 2017, 2021 Florian Obser @@ -732,6 +732,9 @@ main_imsg_send_config(struct dhcpleased_conf *xconf) iface_conf->c_id, iface_conf->c_id_len); main_imsg_compose_engine(IMSG_RECONF_C_ID, -1, iface_conf->c_id, iface_conf->c_id_len); + if (iface_conf->h_name != NULL) + main_imsg_compose_frontend(IMSG_RECONF_H_NAME, -1, + iface_conf->h_name, strlen(iface_conf->h_name) + 1); } /* Config is now complete. */ @@ -1224,6 +1227,7 @@ merge_config(struct dhcpleased_conf *conf, struct dhcpleased_conf *xconf) SIMPLEQ_REMOVE_HEAD(&conf->iface_list, entry); free(iface_conf->vc_id); free(iface_conf->c_id); + free(iface_conf->h_name); free(iface_conf); } diff --git a/sbin/dhcpleased/dhcpleased.conf.5 b/sbin/dhcpleased/dhcpleased.conf.5 index 31b369bdc52..708462d81f1 100644 --- a/sbin/dhcpleased/dhcpleased.conf.5 +++ b/sbin/dhcpleased/dhcpleased.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: dhcpleased.conf.5,v 1.8 2021/09/21 17:23:24 florian Exp $ +.\" $OpenBSD: dhcpleased.conf.5,v 1.9 2022/01/04 06:20:37 florian Exp $ .\" .\" Copyright (c) 2018, 2021 Florian Obser .\" Copyright (c) 2005 Esben Norby @@ -18,7 +18,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: September 21 2021 $ +.Dd $Mdocdate: January 4 2022 $ .Dt DHCPLEASED.CONF 5 .Os .Sh NAME @@ -98,6 +98,13 @@ with hardware type 0 would be configured as: .Bd -literal -offset indent send client id "\e0foobar" .Ed +.It Ic send host name Ar host-name +Send the DHCP client host name option with a value of +.Ar host-name . +The default is to send the name of the host. +.It Ic send no host name +Do not send a DHCP host name option. +The default is to send a DHCP host name option with the name of the host. .It Ic send vendor class id Ar vendor-class-id Send the DHCP vendor class identifier option with a value of .Ar vendor-class-id . diff --git a/sbin/dhcpleased/dhcpleased.h b/sbin/dhcpleased/dhcpleased.h index 02121c19841..a987b02d50d 100644 --- a/sbin/dhcpleased/dhcpleased.h +++ b/sbin/dhcpleased/dhcpleased.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dhcpleased.h,v 1.12 2021/12/09 16:20:12 florian Exp $ */ +/* $OpenBSD: dhcpleased.h,v 1.13 2022/01/04 06:20:37 florian Exp $ */ /* * Copyright (c) 2017, 2021 Florian Obser @@ -203,6 +203,7 @@ enum imsg_type { IMSG_RECONF_IFACE, IMSG_RECONF_VC_ID, IMSG_RECONF_C_ID, + IMSG_RECONF_H_NAME, IMSG_RECONF_END, #endif /* SMALL */ IMSG_SEND_DISCOVER, @@ -253,6 +254,7 @@ struct iface_conf { int vc_id_len; uint8_t *c_id; int c_id_len; + char *h_name; int ignore; struct in_addr ignore_servers[MAX_SERVERS]; int ignore_servers_len; diff --git a/sbin/dhcpleased/engine.c b/sbin/dhcpleased/engine.c index 13bea5b89fd..fa25fbbf0b9 100644 --- a/sbin/dhcpleased/engine.c +++ b/sbin/dhcpleased/engine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: engine.c,v 1.34 2021/12/18 10:34:19 florian Exp $ */ +/* $OpenBSD: engine.c,v 1.35 2022/01/04 06:20:37 florian Exp $ */ /* * Copyright (c) 2017, 2021 Florian Obser @@ -480,6 +480,7 @@ engine_dispatch_main(int fd, short event, void *bula) iface_conf->vc_id_len = 0; iface_conf->c_id = NULL; iface_conf->c_id_len = 0; + iface_conf->h_name = NULL; SIMPLEQ_INSERT_TAIL(&nconf->iface_list, iface_conf, entry); break; @@ -511,6 +512,18 @@ engine_dispatch_main(int fd, short event, void *bula) IMSG_DATA_SIZE(imsg)); iface_conf->c_id_len = IMSG_DATA_SIZE(imsg); break; + case IMSG_RECONF_H_NAME: + if (iface_conf == NULL) + fatal("IMSG_RECONF_H_NAME without " + "IMSG_RECONF_IFACE"); + if (((char *)imsg.data)[IMSG_DATA_SIZE(imsg) - 1] != + '\0') + fatalx("Invalid hostname"); + if (IMSG_DATA_SIZE(imsg) > 256) + fatalx("Invalid hostname"); + if ((iface_conf->h_name = strdup(imsg.data)) == NULL) + fatal(NULL); + break; case IMSG_RECONF_END: { struct dhcpleased_iface *iface; int *ifaces; diff --git a/sbin/dhcpleased/frontend.c b/sbin/dhcpleased/frontend.c index 90b6c20d7bd..58c6153793f 100644 --- a/sbin/dhcpleased/frontend.c +++ b/sbin/dhcpleased/frontend.c @@ -1,4 +1,4 @@ -/* $OpenBSD: frontend.c,v 1.27 2021/12/13 11:03:23 florian Exp $ */ +/* $OpenBSD: frontend.c,v 1.28 2022/01/04 06:20:37 florian Exp $ */ /* * Copyright (c) 2017, 2021 Florian Obser @@ -361,6 +361,7 @@ frontend_dispatch_main(int fd, short event, void *bula) iface_conf->vc_id_len = 0; iface_conf->c_id = NULL; iface_conf->c_id_len = 0; + iface_conf->h_name = NULL; SIMPLEQ_INSERT_TAIL(&nconf->iface_list, iface_conf, entry); break; @@ -392,6 +393,18 @@ frontend_dispatch_main(int fd, short event, void *bula) IMSG_DATA_SIZE(imsg)); iface_conf->c_id_len = IMSG_DATA_SIZE(imsg); break; + case IMSG_RECONF_H_NAME: + if (iface_conf == NULL) + fatal("IMSG_RECONF_H_NAME without " + "IMSG_RECONF_IFACE"); + if (((char *)imsg.data)[IMSG_DATA_SIZE(imsg) - 1] != + '\0') + fatalx("Invalid hostname"); + if (IMSG_DATA_SIZE(imsg) > 256) + fatalx("Invalid hostname"); + if ((iface_conf->h_name = strdup(imsg.data)) == NULL) + fatal(NULL); + break; case IMSG_RECONF_END: { int i; int *ifaces; @@ -904,7 +917,7 @@ build_packet(uint8_t message_type, char *if_name, uint32_t xid, static uint8_t dhcp_cookie[] = DHCP_COOKIE; static uint8_t dhcp_message_type[] = {DHO_DHCP_MESSAGE_TYPE, 1, DHCPDISCOVER}; - static uint8_t dhcp_hostname[255] = {DHO_HOST_NAME, 0 /*, ... */}; + static uint8_t dhcp_hostname[255 + 2] = {DHO_HOST_NAME, 0 /*, ... */}; static uint8_t dhcp_client_id[] = {DHO_DHCP_CLIENT_IDENTIFIER, 7, HTYPE_ETHER, 0, 0, 0, 0, 0, 0}; static uint8_t dhcp_req_list[] = {DHO_DHCP_PARAMETER_REQUEST_LIST, @@ -944,12 +957,27 @@ build_packet(uint8_t message_type, char *if_name, uint32_t xid, p += sizeof(dhcp_cookie); memcpy(p, dhcp_message_type, sizeof(dhcp_message_type)); p += sizeof(dhcp_message_type); - if (gethostname(dhcp_hostname + 2, sizeof(dhcp_hostname) - 2) == 0) { - if ((c = strchr(dhcp_hostname + 2, '.')) != NULL) - *c = '\0'; - dhcp_hostname[1] = strlen(dhcp_hostname + 2); - memcpy(p, dhcp_hostname, dhcp_hostname[1] + 2); - p += dhcp_hostname[1] + 2; + +#ifndef SMALL + if (iface_conf != NULL && iface_conf->h_name != NULL) { + if (iface_conf->h_name[0] != '\0') { + dhcp_hostname[1] = strlen(iface_conf->h_name); + memcpy(dhcp_hostname + 2, iface_conf->h_name, + strlen(iface_conf->h_name)); + memcpy(p, dhcp_hostname, dhcp_hostname[1] + 2); + p += dhcp_hostname[1] + 2; + } + } else +#endif /* SMALL */ + { + if (gethostname(dhcp_hostname + 2, + sizeof(dhcp_hostname) - 2) == 0) { + if ((c = strchr(dhcp_hostname + 2, '.')) != NULL) + *c = '\0'; + dhcp_hostname[1] = strlen(dhcp_hostname + 2); + memcpy(p, dhcp_hostname, dhcp_hostname[1] + 2); + p += dhcp_hostname[1] + 2; + } } #ifndef SMALL @@ -1237,6 +1265,10 @@ iface_conf_cmp(struct iface_conf *a, struct iface_conf *b) return 1; if (memcmp(a->c_id, b->c_id, a->c_id_len) != 0) return 1; + if (a->h_name == NULL || b->h_name == NULL) + return 1; + if (strcmp(a->h_name, b->h_name) != 0) + return 1; if (a->ignore != b->ignore) return 1; if (a->ignore_servers_len != b->ignore_servers_len) diff --git a/sbin/dhcpleased/parse.y b/sbin/dhcpleased/parse.y index 33c2dc7f335..0031dcd095e 100644 --- a/sbin/dhcpleased/parse.y +++ b/sbin/dhcpleased/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.5 2021/10/15 15:01:27 naddy Exp $ */ +/* $OpenBSD: parse.y,v 1.6 2022/01/04 06:20:37 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser @@ -108,7 +108,8 @@ typedef struct { %} -%token DHCP_IFACE ERROR SEND VENDOR CLASS ID CLIENT IGNORE DNS ROUTES +%token DHCP_IFACE ERROR SEND VENDOR CLASS ID CLIENT IGNORE DNS ROUTES HOST NAME +%token NO %token STRING %token NUMBER @@ -274,6 +275,30 @@ ifaceoptsl : SEND VENDOR CLASS ID STRING { iface_conf->c_id[0] = DHO_DHCP_CLIENT_IDENTIFIER; iface_conf->c_id[1] = iface_conf->c_id_len - 2; } + | SEND HOST NAME STRING { + if (iface_conf->h_name != NULL) { + free($4); + yyerror("host name already set"); + YYERROR; + } + if (strlen($4) > 255) { + free($4); + yyerror("host name too long"); + YYERROR; + } + iface_conf->h_name = $4; + } + | SEND NO HOST NAME { + if (iface_conf->h_name != NULL) { + yyerror("host name already set"); + YYERROR; + } + + if ((iface_conf->h_name = strdup("")) == NULL) { + yyerror("malloc"); + YYERROR; + } + } | IGNORE ROUTES { iface_conf->ignore |= IGN_ROUTES; } @@ -337,9 +362,12 @@ lookup(char *s) {"class", CLASS}, {"client", CLIENT}, {"dns", DNS}, + {"host", HOST}, {"id", ID}, {"ignore", IGNORE}, {"interface", DHCP_IFACE}, + {"name", NAME}, + {"no", NO}, {"routes", ROUTES}, {"send", SEND}, {"vendor", VENDOR}, diff --git a/sbin/dhcpleased/printconf.c b/sbin/dhcpleased/printconf.c index 5de78699188..076fe2ec0ad 100644 --- a/sbin/dhcpleased/printconf.c +++ b/sbin/dhcpleased/printconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printconf.c,v 1.3 2021/09/20 11:46:22 florian Exp $ */ +/* $OpenBSD: printconf.c,v 1.4 2022/01/04 06:20:37 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser @@ -106,6 +106,14 @@ print_config(struct dhcpleased_conf *conf) SIMPLEQ_FOREACH(iface, &conf->iface_list, entry) { printf("interface %s {\n", iface->name); print_dhcp_options("\t", iface->c_id, iface->c_id_len); + if (iface->h_name != NULL) { + if (iface->h_name[0] == '\0') + printf("\tsend no host name\n"); + else { + printf("\tsend host name \"%s\"\n", + iface->h_name); + } + } print_dhcp_options("\t", iface->vc_id, iface->vc_id_len); if (iface->ignore & IGN_DNS) printf("\tignore dns\n"); -- 2.20.1