ping On 2021-12-24 10:16 +01, Florian Obser <flor...@openbsd.org> wrote: > Make host name DHCP option configurable. > Diff from ha...@sdf.org, tweaks by me. > > RFC 2132 says a host name must have a lenght of at least 1, so we can > use strlen(h_name) == 0 to not send a host name option at all and h_name > == NULL to send the default host name option. > > OK? > > diff --git dhcpleased.c dhcpleased.c > index 497ca5a0a79..92e96deac00 100644 > --- dhcpleased.c > +++ dhcpleased.c > @@ -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 dhcpleased.conf.5 dhcpleased.conf.5 > index 31b369bdc52..38026c46eeb 100644 > --- dhcpleased.conf.5 > +++ dhcpleased.conf.5 > @@ -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 dhcpleased.h dhcpleased.h > index 02121c19841..5ca6a3a3c2a 100644 > --- dhcpleased.h > +++ dhcpleased.h > @@ -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 engine.c engine.c > index 13bea5b89fd..42fec7a4caf 100644 > --- engine.c > +++ engine.c > @@ -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 frontend.c frontend.c > index 90b6c20d7bd..cc3815f49ab 100644 > --- frontend.c > +++ frontend.c > @@ -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 parse.y parse.y > index 33c2dc7f335..9b9441403a0 100644 > --- parse.y > +++ parse.y > @@ -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 <v.string> STRING > %token <v.number> 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 printconf.c printconf.c > index 5de78699188..5eced3d19dd 100644 > --- printconf.c > +++ printconf.c > @@ -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"); > > -- > > I'm not entirely sure you are real. >
-- I'm not entirely sure you are real.