From ebace80c28e0f6c842b014accbacb80c1825da50 Mon Sep 17 00:00:00 2001 From: florian Date: Sun, 20 Jun 2021 08:31:45 +0000 Subject: [PATCH] Put (boot) filename, next-server, host-name and domain-name into lease file for the installer. --- sbin/dhcpleased/dhcpleased.c | 26 +++++++++++++++----- sbin/dhcpleased/dhcpleased.h | 11 ++++++--- sbin/dhcpleased/engine.c | 47 ++++++++++++++++++++++++++++++------ sbin/dhcpleased/engine.h | 6 ++++- 4 files changed, 72 insertions(+), 18 deletions(-) diff --git a/sbin/dhcpleased/dhcpleased.c b/sbin/dhcpleased/dhcpleased.c index ad18e134147..d5aca108549 100644 --- a/sbin/dhcpleased/dhcpleased.c +++ b/sbin/dhcpleased/dhcpleased.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dhcpleased.c,v 1.12 2021/06/16 14:06:17 florian Exp $ */ +/* $OpenBSD: dhcpleased.c,v 1.13 2021/06/20 08:31:45 florian Exp $ */ /* * Copyright (c) 2017, 2021 Florian Obser @@ -626,7 +626,8 @@ configure_interface(struct imsg_configure_interface *imsg) struct sockaddr_in *req_sin_addr, *req_sin_mask; int found = 0, udpsock, opt = 1, len, fd = -1; char *if_name; - char ntop_buf[INET_ADDRSTRLEN]; + char ip_ntop_buf[INET_ADDRSTRLEN]; + char nextserver_ntop_buf[INET_ADDRSTRLEN]; char lease_buf[LEASE_SIZE]; char lease_file_buf[sizeof(_PATH_LEASE) + IF_NAMESIZE]; @@ -723,12 +724,21 @@ configure_interface(struct imsg_configure_interface *imsg) if (no_lease_files) return; - if (inet_ntop(AF_INET, &imsg->addr, ntop_buf, sizeof(ntop_buf)) == + if (inet_ntop(AF_INET, &imsg->addr, ip_ntop_buf, sizeof(ip_ntop_buf)) == NULL) { log_warn("%s: inet_ntop", __func__); return; } + if (imsg->siaddr.s_addr == INADDR_ANY) + nextserver_ntop_buf[0] = '\0'; + else { + if (inet_ntop(AF_INET, &imsg->siaddr, nextserver_ntop_buf, + sizeof(nextserver_ntop_buf)) == NULL) { + log_warn("%s: inet_ntop", __func__); + return; + } + } len = snprintf(lease_file_buf, sizeof(lease_file_buf), "%s%s", _PATH_LEASE, if_name); if ( len == -1 || (size_t) len >= sizeof(lease_file_buf)) { @@ -737,11 +747,15 @@ configure_interface(struct imsg_configure_interface *imsg) return; } - len = snprintf(lease_buf, sizeof(lease_buf), "%s%s\n", LEASE_PREFIX, - ntop_buf); + len = snprintf(lease_buf, sizeof(lease_buf), + "%s\n%s%s\n%s%s\n%s%s\n%s%s\n%s%s\n", + LEASE_VERSION, LEASE_IP_PREFIX, ip_ntop_buf, + LEASE_NEXTSERVER_PREFIX, nextserver_ntop_buf, LEASE_BOOTFILE_PREFIX, + imsg->file, LEASE_HOSTNAME_PREFIX, imsg->hostname, + LEASE_DOMAIN_PREFIX, imsg->domainname); if ( len == -1 || (size_t) len >= sizeof(lease_buf)) { log_warnx("%s: failed to encode lease for %s", __func__, - ntop_buf); + ip_ntop_buf); return; } diff --git a/sbin/dhcpleased/dhcpleased.h b/sbin/dhcpleased/dhcpleased.h index bf23ba76df5..2654293dcb5 100644 --- a/sbin/dhcpleased/dhcpleased.h +++ b/sbin/dhcpleased/dhcpleased.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dhcpleased.h,v 1.5 2021/06/16 14:06:17 florian Exp $ */ +/* $OpenBSD: dhcpleased.h,v 1.6 2021/06/20 08:31:45 florian Exp $ */ /* * Copyright (c) 2017, 2021 Florian Obser @@ -24,8 +24,13 @@ #define SERVER_PORT 67 #define CLIENT_PORT 68 #define _PATH_LEASE "/var/db/dhcpleased/" -#define LEASE_PREFIX "version: 1\nip: " -#define LEASE_SIZE sizeof(LEASE_PREFIX"xxx.xxx.xxx.xxx\n") +#define LEASE_VERSION "version: 2" +#define LEASE_IP_PREFIX "ip: " +#define LEASE_NEXTSERVER_PREFIX "next-server: " +#define LEASE_BOOTFILE_PREFIX "filename: " +#define LEASE_HOSTNAME_PREFIX "host-name: " +#define LEASE_DOMAIN_PREFIX "domain-name: " +#define LEASE_SIZE 4096 /* MAXDNAME from arpa/namesr.h */ #define DHCPLEASED_MAX_DNSSL 1025 #define MAX_RDNS_COUNT 8 /* max nameserver in a RTM_PROPOSAL */ diff --git a/sbin/dhcpleased/engine.c b/sbin/dhcpleased/engine.c index 9a24cee2f47..dfe2a1b15e8 100644 --- a/sbin/dhcpleased/engine.c +++ b/sbin/dhcpleased/engine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: engine.c,v 1.16 2021/06/18 11:44:48 florian Exp $ */ +/* $OpenBSD: engine.c,v 1.17 2021/06/20 08:31:45 florian Exp $ */ /* * Copyright (c) 2017, 2021 Florian Obser @@ -101,6 +101,10 @@ struct dhcpleased_iface { struct in_addr dhcp_server; /* for unicast */ struct in_addr requested_ip; struct in_addr mask; + struct in_addr siaddr; + char file[4 * DHCP_FILE_LEN + 1]; + char hostname[4 * 255 + 1]; + char domainname[4 * 255 + 1]; struct dhcp_route routes[MAX_DHCP_ROUTES]; int routes_len; struct in_addr nameservers[MAX_RDNS_COUNT]; @@ -615,7 +619,8 @@ parse_dhcp(struct dhcpleased_iface *iface, struct imsg_dhcp *dhcp) char hbuf_src[INET_ADDRSTRLEN]; char hbuf_dst[INET_ADDRSTRLEN]; char hbuf[INET_ADDRSTRLEN]; - char vis_buf[4 * 255 + 1]; + char domainname[4 * 255 + 1]; + char hostname[4 * 255 + 1]; char ifnamebuf[IF_NAMESIZE], *if_name; if (bcast_mac.ether_addr_octet[0] == 0) @@ -872,13 +877,21 @@ parse_dhcp(struct dhcpleased_iface *iface, struct imsg_dhcp *dhcp) p += dho_len; rem -= dho_len; break; + case DHO_HOST_NAME: + if ( dho_len < 1) + goto wrong_length; + strvisx(hostname, p, dho_len, VIS_SAFE); + if (log_getverbose() > 1) + log_debug("DHO_HOST_NAME: %s", hostname); + p += dho_len; + rem -= dho_len; + break; case DHO_DOMAIN_NAME: if ( dho_len < 1) goto wrong_length; - if (log_getverbose() > 1) { - strvisx(vis_buf, p, dho_len, VIS_SAFE); - log_debug("DHO_DOMAIN_NAME: %s", vis_buf); - } + strvisx(domainname, p, dho_len, VIS_SAFE); + if (log_getverbose() > 1) + log_debug("DHO_DOMAIN_NAME: %s", domainname); p += dho_len; rem -= dho_len; break; @@ -1071,6 +1084,16 @@ parse_dhcp(struct dhcpleased_iface *iface, struct imsg_dhcp *dhcp) iface->rebinding_time = rebinding_time; memcpy(iface->nameservers, nameservers, sizeof(iface->nameservers)); + + iface->siaddr.s_addr = dhcp_hdr->siaddr.s_addr; + + /* we made sure this is a string futher up */ + strnvis(iface->file, dhcp_hdr->file, sizeof(iface->file), + VIS_SAFE); + + strlcpy(iface->domainname, domainname, + sizeof(iface->domainname)); + strlcpy(iface->hostname, hostname, sizeof(iface->hostname)); state_transition(iface, IF_BOUND); break; case DHCPNAK: @@ -1330,6 +1353,10 @@ send_configure_interface(struct dhcpleased_iface *iface) imsg.rdomain = iface->rdomain; imsg.addr.s_addr = iface->requested_ip.s_addr; imsg.mask.s_addr = iface->mask.s_addr; + imsg.siaddr.s_addr = iface->siaddr.s_addr; + strlcpy(imsg.file, iface->file, sizeof(imsg.file)); + strlcpy(imsg.domainname, iface->domainname, sizeof(imsg.domainname)); + strlcpy(imsg.hostname, iface->hostname, sizeof(imsg.hostname)); imsg.routes_len = iface->routes_len; memcpy(imsg.routes, iface->routes, sizeof(imsg.routes)); engine_imsg_compose_main(IMSG_CONFIGURE_INTERFACE, 0, &imsg, @@ -1350,6 +1377,10 @@ send_deconfigure_interface(struct dhcpleased_iface *iface) imsg.rdomain = iface->rdomain; imsg.addr.s_addr = iface->requested_ip.s_addr; imsg.mask.s_addr = iface->mask.s_addr; + imsg.siaddr.s_addr = iface->siaddr.s_addr; + strlcpy(imsg.file, iface->file, sizeof(imsg.file)); + strlcpy(imsg.domainname, iface->domainname, sizeof(imsg.domainname)); + strlcpy(imsg.hostname, iface->hostname, sizeof(imsg.hostname)); imsg.routes_len = iface->routes_len; memcpy(imsg.routes, iface->routes, sizeof(imsg.routes)); engine_imsg_compose_main(IMSG_DECONFIGURE_INTERFACE, 0, &imsg, @@ -1446,10 +1477,10 @@ parse_lease(struct dhcpleased_iface *iface, struct imsg_ifinfo *imsg_ifinfo) iface->requested_ip.s_addr = INADDR_ANY; - if ((p = strstr(imsg_ifinfo->lease, LEASE_PREFIX)) == NULL) + if ((p = strstr(imsg_ifinfo->lease, LEASE_IP_PREFIX)) == NULL) return; - p += sizeof(LEASE_PREFIX) - 1; + p += sizeof(LEASE_IP_PREFIX) - 1; if ((p1 = strchr(p, '\n')) == NULL) return; *p1 = '\0'; diff --git a/sbin/dhcpleased/engine.h b/sbin/dhcpleased/engine.h index c6aded13005..418de2383f0 100644 --- a/sbin/dhcpleased/engine.h +++ b/sbin/dhcpleased/engine.h @@ -1,4 +1,4 @@ -/* $OpenBSD: engine.h,v 1.2 2021/06/16 14:06:17 florian Exp $ */ +/* $OpenBSD: engine.h,v 1.3 2021/06/20 08:31:45 florian Exp $ */ /* * Copyright (c) 2021 Florian Obser @@ -21,6 +21,10 @@ struct imsg_configure_interface { int rdomain; struct in_addr addr; struct in_addr mask; + struct in_addr siaddr; + char file[4 * DHCP_FILE_LEN + 1]; + char domainname[4 * 255 + 1]; + char hostname[4 * 255 + 1]; struct dhcp_route routes[MAX_DHCP_ROUTES]; int routes_len; }; -- 2.20.1