Make host name DHCP option configurable.
authorflorian <florian@openbsd.org>
Tue, 4 Jan 2022 06:20:37 +0000 (06:20 +0000)
committerflorian <florian@openbsd.org>
Tue, 4 Jan 2022 06:20:37 +0000 (06:20 +0000)
Diff from hagen@sdf.org, tweaks by me.
OK phessler
testing & OK bket

sbin/dhcpleased/dhcpleased.c
sbin/dhcpleased/dhcpleased.conf.5
sbin/dhcpleased/dhcpleased.h
sbin/dhcpleased/engine.c
sbin/dhcpleased/frontend.c
sbin/dhcpleased/parse.y
sbin/dhcpleased/printconf.c

index 497ca5a..3972d2a 100644 (file)
@@ -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 <florian@openbsd.org>
@@ -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);
        }
 
index 31b369b..708462d 100644 (file)
@@ -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 <florian@openbsd.org>
 .\" Copyright (c) 2005 Esben Norby <norby@openbsd.org>
@@ -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 .
index 02121c1..a987b02 100644 (file)
@@ -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 <florian@openbsd.org>
@@ -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;
index 13bea5b..fa25fbb 100644 (file)
@@ -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 <florian@openbsd.org>
@@ -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;
index 90b6c20..58c6153 100644 (file)
@@ -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 <florian@openbsd.org>
@@ -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)
index 33c2dc7..0031dcd 100644 (file)
@@ -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 <florian@openbsd.org>
@@ -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},
index 5de7869..076fe2e 100644 (file)
@@ -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 <florian@openbsd.org>
@@ -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");