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.

Reply via email to