-/* $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 <florian@openbsd.org>
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];
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)) {
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;
}
-/* $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 <florian@openbsd.org>
#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 */
-/* $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 <florian@openbsd.org>
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];
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)
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;
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:
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,
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,
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';