delete dhclient(8). ipv4 dhcp leases have been acquired by the
authorderaadt <deraadt@openbsd.org>
Sun, 30 Jun 2024 17:30:52 +0000 (17:30 +0000)
committerderaadt <deraadt@openbsd.org>
Sun, 30 Jun 2024 17:30:52 +0000 (17:30 +0000)
always-running-in-background dhcpleased(8) for a while, which is
activated per-interface with "ifconfig $if autoconf', or
"ifconfig $if inet autoconf", or with "inet autoconf" in /etc/hostname.$if
dhclient(8) has done execve(3) of ifconfig(8) to handle this for a while,
so everyone has moved to the dhcpleased(8) method
ok florian

25 files changed:
distrib/sets/lists/base/mi
distrib/sets/lists/man/mi
etc/Makefile
etc/examples/dhclient.conf [deleted file]
sbin/Makefile
sbin/dhclient/Makefile [deleted file]
sbin/dhclient/bpf.c [deleted file]
sbin/dhclient/clparse.c [deleted file]
sbin/dhclient/conflex.c [deleted file]
sbin/dhclient/dhclient.8 [deleted file]
sbin/dhclient/dhclient.c [deleted file]
sbin/dhclient/dhclient.conf.5 [deleted file]
sbin/dhclient/dhclient.leases.5 [deleted file]
sbin/dhclient/dhcp.h [deleted file]
sbin/dhclient/dhcpd.h [deleted file]
sbin/dhclient/dhctoken.h [deleted file]
sbin/dhclient/dispatch.c [deleted file]
sbin/dhclient/kroute.c [deleted file]
sbin/dhclient/log.c [deleted file]
sbin/dhclient/log.h [deleted file]
sbin/dhclient/options.c [deleted file]
sbin/dhclient/packet.c [deleted file]
sbin/dhclient/parse.c [deleted file]
sbin/dhclient/privsep.c [deleted file]
sbin/dhclient/privsep.h [deleted file]

index 754cd48..6132ea9 100644 (file)
@@ -54,7 +54,6 @@
 ./etc/examples/acme-client.conf
 ./etc/examples/bgpd.conf
 ./etc/examples/chio.conf
-./etc/examples/dhclient.conf
 ./etc/examples/dhcpd.conf
 ./etc/examples/doas.conf
 ./etc/examples/dvmrpd.conf
 ./sbin/bioctl
 ./sbin/chown
 ./sbin/clri
-./sbin/dhclient
 ./sbin/dhcp6leased
 ./sbin/dhcpleased
 ./sbin/disklabel
index 5e32cc2..6c769ec 100644 (file)
 ./usr/share/man/man5/crontab.5
 ./usr/share/man/man5/cvs.5
 ./usr/share/man/man5/defaultdomain.5
-./usr/share/man/man5/dhclient.conf.5
-./usr/share/man/man5/dhclient.leases.5
 ./usr/share/man/man5/dhcp-options.5
 ./usr/share/man/man5/dhcp6leased.conf.5
 ./usr/share/man/man5/dhcpd.conf.5
 ./usr/share/man/man8/cvsbug.8
 ./usr/share/man/man8/daily.8
 ./usr/share/man/man8/dev_mkdb.8
-./usr/share/man/man8/dhclient.8
 ./usr/share/man/man8/dhcp6leasectl.8
 ./usr/share/man/man8/dhcp6leased.8
 ./usr/share/man/man8/dhcpd.8
index 5bac711..2a80ccc 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile,v 1.489 2024/06/03 10:06:35 florian Exp $
+#      $OpenBSD: Makefile,v 1.490 2024/06/30 17:30:54 deraadt Exp $
 
 .include <bsd.own.mk>
 
@@ -45,7 +45,7 @@ MUTABLE=changelist daily etc.${MACHINE}/disktab \
        pf.os protocols rc rc.conf rpc services shells syslog.conf weekly
 
 # -rw-r--r--
-EXAMPLES=acme-client.conf chio.conf dhclient.conf dhcpd.conf exports \
+EXAMPLES=acme-client.conf chio.conf dhcpd.conf exports \
        httpd.conf ifstated.conf inetd.conf man.conf mixerctl.conf \
        mrouted.conf ntpd.conf printcap rad.conf rbootd.conf \
        remote sensorsd.conf wsconsctl.conf
diff --git a/etc/examples/dhclient.conf b/etc/examples/dhclient.conf
deleted file mode 100644 (file)
index 3fba667..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-# $OpenBSD: dhclient.conf,v 1.2 2017/10/16 23:43:41 krw Exp $
-#
-# DHCP Client Configuration
-#
-# See dhclient.conf(5) for possible contents of this file.
-#
-# Example:
-#
-# send dhcp-lease-time 3600;
-# send host-name "myhost";
-# supersede host-name "myhost";
-# supersede domain-name "my.domain";
-# request subnet-mask, broadcast-address, time-offset, routers,
-#      domain-name, domain-name-servers, host-name, lpr-servers, ntp-servers;
-# require subnet-mask, domain-name-servers, routers;
index 81ac089..19d0a8e 100644 (file)
@@ -1,6 +1,6 @@
-#      $OpenBSD: Makefile,v 1.111 2024/06/03 10:05:18 florian Exp $
+#      $OpenBSD: Makefile,v 1.112 2024/06/30 17:30:54 deraadt Exp $
 
-SUBDIR=        atactl badsect bioctl clri dhclient dhcp6leased dhcpleased \
+SUBDIR=        atactl badsect bioctl clri dhcp6leased dhcpleased \
        disklabel dmesg dump dumpfs fdisk fsck fsck_ext2fs fsck_ffs  \
        fsck_msdos fsdb fsirand growfs ifconfig iked init ipsecctl  \
        isakmpd kbd ldattach mknod mount \
diff --git a/sbin/dhclient/Makefile b/sbin/dhclient/Makefile
deleted file mode 100644 (file)
index b011385..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-# $OpenBSD: Makefile,v 1.20 2017/07/08 20:38:31 krw Exp $
-#
-# Copyright (c) 1996, 1997 The Internet Software Consortium.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# 1. Redistributions of source code must retain the above copyright
-#    notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions and the following disclaimer in the
-#    documentation and/or other materials provided with the distribution.
-# 3. Neither the name of The Internet Software Consortium nor the names of its
-#    contributors may be used to endorse or promote products derived
-#    from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
-# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
-# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-# FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
-# THE INTERNET SOFTWARE CONSORTIUM OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-# OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-.include <bsd.own.mk>
-
-SRCS=  dhclient.c clparse.c dispatch.c bpf.c options.c \
-       conflex.c log.c packet.c  \
-       parse.c privsep.c kroute.c
-
-PROG=  dhclient
-LDADD+=        -lutil
-DPADD+= ${LIBUTIL}
-MAN=   dhclient.8 dhclient.conf.5 dhclient.leases.5
-
-CFLAGS+=-Wall
-CFLAGS+=-Wstrict-prototypes -Wmissing-prototypes
-CFLAGS+=-Wmissing-declarations
-CFLAGS+=-Wshadow -Wpointer-arith -Wcast-qual
-CFLAGS+=-Wsign-compare
-
-.include <bsd.prog.mk>
diff --git a/sbin/dhclient/bpf.c b/sbin/dhclient/bpf.c
deleted file mode 100644 (file)
index 1bb2876..0000000
+++ /dev/null
@@ -1,401 +0,0 @@
-/*     $OpenBSD: bpf.c,v 1.75 2019/03/18 00:00:59 dlg Exp $    */
-
-/* BPF socket interface code, originally contributed by Archie Cobbs. */
-
-/*
- * Copyright (c) 1995, 1996, 1998, 1999
- * The Internet Software Consortium.    All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#include <sys/ioctl.h>
-#include <sys/queue.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#include <net/bpf.h>
-#include <net/if.h>
-
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/udp.h>
-#include <netinet/if_ether.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "dhcp.h"
-#include "dhcpd.h"
-#include "log.h"
-
-int
-get_bpf_sock(char *name)
-{
-       struct ifreq     ifr;
-       int             sock;
-
-       if ((sock = open("/dev/bpf", O_RDWR | O_CLOEXEC)) == -1)
-               fatal("open(/dev/bpf)");
-
-       /* Set the BPF device to point at this interface. */
-       strlcpy(ifr.ifr_name, name, IFNAMSIZ);
-       if (ioctl(sock, BIOCSETIF, &ifr) == -1)
-               fatal("BIOCSETIF");
-
-       return sock;
-}
-
-int
-get_udp_sock(int rdomain)
-{
-       int      sock, on = 1;
-
-       /*
-        * Use raw socket for unicast send.
-        */
-       if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP)) == -1)
-               fatal("socket(AF_INET, SOCK_RAW)");
-       if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &on,
-           sizeof(on)) == -1)
-               fatal("setsockopt(IP_HDRINCL)");
-       if (setsockopt(sock, IPPROTO_IP, SO_RTABLE, &rdomain,
-           sizeof(rdomain)) == -1)
-               fatal("setsockopt(SO_RTABLE)");
-
-       return sock;
-}
-
-/*
- * Packet filter program.
- *
- * N.B.: Changes to the filter program may require changes to the
- * constant offsets used in if_register_receive to patch the BPF program!
- */
-struct bpf_insn dhcp_bpf_filter[] = {
-       /* Make sure this is an IP packet. */
-       BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 12),
-       BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 8),
-
-       /* Make sure it's a UDP packet. */
-       BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 23),
-       BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6),
-
-       /* Make sure this isn't a fragment. */
-       BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20),
-       BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
-
-       /* Get the IP header length. */
-       BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 14),
-
-       /* Make sure it's to the right port. */
-       BPF_STMT(BPF_LD + BPF_H + BPF_IND, 16),
-       BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),          /* patch */
-
-       /* If we passed all the tests, ask for the whole packet. */
-       BPF_STMT(BPF_RET+BPF_K, (unsigned int)-1),
-
-       /* Otherwise, drop it. */
-       BPF_STMT(BPF_RET+BPF_K, 0),
-};
-
-int dhcp_bpf_filter_len = sizeof(dhcp_bpf_filter) / sizeof(struct bpf_insn);
-
-/*
- * Packet write filter program:
- * 'ip and udp and src port bootps and dst port (bootps or bootpc)'
- */
-struct bpf_insn dhcp_bpf_wfilter[] = {
-       BPF_STMT(BPF_LD + BPF_B + BPF_IND, 14),
-       BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, (IPVERSION << 4) + 5, 0, 12),
-
-       /* Make sure this is an IP packet. */
-       BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 12),
-       BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 10),
-
-       /* Make sure it's a UDP packet. */
-       BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 23),
-       BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 8),
-
-       /* Make sure this isn't a fragment. */
-       BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20),
-       BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 6, 0),     /* patched */
-
-       /* Get the IP header length. */
-       BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 14),
-
-       /* Make sure it's from the right port. */
-       BPF_STMT(BPF_LD + BPF_H + BPF_IND, 14),
-       BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 68, 0, 3),
-
-       /* Make sure it is to the right ports. */
-       BPF_STMT(BPF_LD + BPF_H + BPF_IND, 16),
-       BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),
-
-       /* If we passed all the tests, ask for the whole packet. */
-       BPF_STMT(BPF_RET+BPF_K, (unsigned int)-1),
-
-       /* Otherwise, drop it. */
-       BPF_STMT(BPF_RET+BPF_K, 0),
-};
-
-int dhcp_bpf_wfilter_len = sizeof(dhcp_bpf_wfilter) / sizeof(struct bpf_insn);
-
-int
-configure_bpf_sock(int bpffd)
-{
-       struct bpf_version       v;
-       struct bpf_program       p;
-       int                      flag = 1, sz;
-       int                      fildrop = BPF_FILDROP_CAPTURE;
-
-       /* Make sure the BPF version is in range. */
-       if (ioctl(bpffd, BIOCVERSION, &v) == -1)
-               fatal("BIOCVERSION");
-
-       if (v.bv_major != BPF_MAJOR_VERSION ||
-           v.bv_minor < BPF_MINOR_VERSION)
-               fatalx("kernel BPF version out of range - recompile "
-                   "dhclient");
-
-       /*
-        * Set immediate mode so that reads return as soon as a packet
-        * comes in, rather than waiting for the input buffer to fill
-        * with packets.
-        */
-       if (ioctl(bpffd, BIOCIMMEDIATE, &flag) == -1)
-               fatal("BIOCIMMEDIATE");
-
-       if (ioctl(bpffd, BIOCSFILDROP, &fildrop) == -1)
-               fatal("BIOCSFILDROP");
-
-       /* Get the required BPF buffer length from the kernel. */
-       if (ioctl(bpffd, BIOCGBLEN, &sz) == -1)
-               fatal("BIOCGBLEN");
-
-       /* Set up the bpf filter program structure. */
-       p.bf_len = dhcp_bpf_filter_len;
-       p.bf_insns = dhcp_bpf_filter;
-
-       /* Patch the server port into the BPF program.
-        *
-        * N.B.: changes to filter program may require changes to the
-        * insn number(s) used below!
-        */
-       dhcp_bpf_filter[8].k = LOCAL_PORT;
-
-       if (ioctl(bpffd, BIOCSETF, &p) == -1)
-               fatal("BIOCSETF");
-
-       /* Set up the bpf write filter program structure. */
-       p.bf_len = dhcp_bpf_wfilter_len;
-       p.bf_insns = dhcp_bpf_wfilter;
-
-       if (dhcp_bpf_wfilter[7].k == 0x1fff)
-               dhcp_bpf_wfilter[7].k = htons(IP_MF|IP_OFFMASK);
-
-       if (ioctl(bpffd, BIOCSETWF, &p) == -1)
-               fatal("BIOCSETWF");
-
-       if (ioctl(bpffd, BIOCLOCK, NULL) == -1)
-               fatal("BIOCLOCK");
-
-       return sz;
-}
-
-ssize_t
-send_packet(struct interface_info *ifi, struct in_addr from, struct in_addr to,
-    const char *desc)
-{
-       struct iovec             iov[4];
-       struct sockaddr_in       dest;
-       struct ether_header      eh;
-       struct ip                ip;
-       struct udphdr            udp;
-       struct msghdr            msg;
-       struct dhcp_packet      *packet = &ifi->sent_packet;
-       ssize_t                  result, total;
-       unsigned int             iovcnt = 0, i;
-       int                      len = ifi->sent_packet_length;
-
-       memset(&dest, 0, sizeof(dest));
-       dest.sin_family = AF_INET;
-       dest.sin_port = htons(REMOTE_PORT);
-       dest.sin_addr.s_addr = to.s_addr;
-
-       if (to.s_addr == INADDR_BROADCAST) {
-               assemble_eh_header(ifi->hw_address, &eh);
-               iov[0].iov_base = &eh;
-               iov[0].iov_len = sizeof(eh);
-               iovcnt++;
-       }
-
-       ip.ip_v = 4;
-       ip.ip_hl = 5;
-       ip.ip_tos = IPTOS_LOWDELAY;
-       ip.ip_len = htons(sizeof(ip) + sizeof(udp) + len);
-       ip.ip_id = 0;
-       ip.ip_off = 0;
-       ip.ip_ttl = 128;
-       ip.ip_p = IPPROTO_UDP;
-       ip.ip_sum = 0;
-       ip.ip_src.s_addr = from.s_addr;
-       ip.ip_dst.s_addr = to.s_addr;
-       ip.ip_sum = wrapsum(checksum((unsigned char *)&ip, sizeof(ip), 0));
-       iov[iovcnt].iov_base = &ip;
-       iov[iovcnt].iov_len = sizeof(ip);
-       iovcnt++;
-
-       udp.uh_sport = htons(LOCAL_PORT);
-       udp.uh_dport = htons(REMOTE_PORT);
-       udp.uh_ulen = htons(sizeof(udp) + len);
-       udp.uh_sum = 0;
-       udp.uh_sum = wrapsum(checksum((unsigned char *)&udp, sizeof(udp),
-           checksum((unsigned char *)packet, len,
-           checksum((unsigned char *)&ip.ip_src,
-           2 * sizeof(ip.ip_src),
-           IPPROTO_UDP + (uint32_t)ntohs(udp.uh_ulen)))));
-       iov[iovcnt].iov_base = &udp;
-       iov[iovcnt].iov_len = sizeof(udp);
-       iovcnt++;
-
-       iov[iovcnt].iov_base = packet;
-       iov[iovcnt].iov_len = len;
-       iovcnt++;
-
-       total = 0;
-       for (i = 0; i < iovcnt; i++)
-               total += iov[i].iov_len;
-
-       if (to.s_addr == INADDR_BROADCAST) {
-               result = writev(ifi->bpffd, iov, iovcnt);
-               if (result == -1)
-                       log_warn("%s: writev(%s)", log_procname, desc);
-               else if (result < total) {
-                       log_warnx("%s, writev(%s): %zd of %zd bytes",
-                           log_procname, desc, result, total);
-                       result = -1;
-               }
-       } else {
-               memset(&msg, 0, sizeof(msg));
-               msg.msg_name = (struct sockaddr *)&dest;
-               msg.msg_namelen = sizeof(dest);
-               msg.msg_iov = iov;
-               msg.msg_iovlen = iovcnt;
-               result = sendmsg(ifi->udpfd, &msg, 0);
-               if (result == -1)
-                       log_warn("%s: sendmsg(%s)", log_procname, desc);
-               else if (result < total) {
-                       result = -1;
-                       log_warnx("%s, sendmsg(%s): %zd of %zd bytes",
-                           log_procname, desc, result, total);
-               }
-       }
-
-       return result;
-}
-
-/*
- * Extract a DHCP packet from a bpf capture buffer.
- *
- * Each captured packet is
- *
- *     <BPF header>
- *     <padding to BPF_WORDALIGN>
- *     <captured DHCP packet>
- *     <padding to BPF_WORDALIGN>
- *
- * Return the number of bytes processed or 0 if there is
- * no valid DHCP packet in the buffer.
- */
-ssize_t
-receive_packet(unsigned char *buf, unsigned char *lim,
-    struct sockaddr_in *from, struct ether_addr *hfrom,
-    struct dhcp_packet *packet)
-{
-       struct bpf_hdr           bh;
-       struct ether_header      eh;
-       unsigned char           *pktlim, *data, *next;
-       size_t                   datalen;
-       int                      len;
-
-       for (next = buf; next < lim; next = pktlim) {
-               /* No bpf header means no more packets. */
-               if (lim < next + sizeof(bh))
-                       return 0;
-
-               memcpy(&bh, next, sizeof(bh));
-               pktlim = next + BPF_WORDALIGN(bh.bh_hdrlen + bh.bh_caplen);
-
-               /* Truncated bpf packet means no more packets. */
-               if (lim < next + bh.bh_hdrlen + bh.bh_caplen)
-                       return 0;
-
-               /* Drop incompletely captured DHCP packets. */
-               if (bh.bh_caplen != bh.bh_datalen)
-                       continue;
-
-               /*
-                * Drop packets with invalid ethernet/ip/udp headers.
-                */
-               if (pktlim < next + bh.bh_hdrlen + sizeof(eh))
-                       continue;
-               memcpy(&eh, next + bh.bh_hdrlen, sizeof(eh));
-               memcpy(hfrom->ether_addr_octet, eh.ether_shost, ETHER_ADDR_LEN);
-
-               len = decode_udp_ip_header(next + bh.bh_hdrlen + sizeof(eh),
-                   bh.bh_caplen - sizeof(eh), from);
-               if (len < 0)
-                       continue;
-
-               /* Drop packets larger than sizeof(struct dhcp_packet). */
-               datalen = bh.bh_caplen - (sizeof(eh) + len);
-               if (datalen > sizeof(*packet))
-                       continue;
-
-               /* Extract the DHCP packet for further processing. */
-               data = next + bh.bh_hdrlen + sizeof(eh) + len;
-               memset(packet, DHO_END, sizeof(*packet));
-               memcpy(packet, data, datalen);
-
-               return (pktlim - buf);
-       }
-
-       return 0;
-}
diff --git a/sbin/dhclient/clparse.c b/sbin/dhclient/clparse.c
deleted file mode 100644 (file)
index 051b3bb..0000000
+++ /dev/null
@@ -1,1029 +0,0 @@
-/*     $OpenBSD: clparse.c,v 1.203 2021/02/27 17:44:58 krw Exp $       */
-
-/* Parser for dhclient config and lease files. */
-
-/*
- * Copyright (c) 1997 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#include <sys/queue.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <net/if.h>
-#include <net/if_arp.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "dhcp.h"
-#include "dhcpd.h"
-#include "dhctoken.h"
-#include "log.h"
-
-void   parse_conf_decl(FILE *, char *);
-int    parse_hex_octets(FILE *, unsigned int *, uint8_t **);
-int    parse_domain_list(FILE *, int *, char **);
-int    parse_option_list(FILE *, int *, uint8_t *);
-int    parse_interface(FILE *, char *);
-int    parse_lease(FILE *, struct client_lease **);
-void   parse_lease_decl(FILE *, struct client_lease *);
-int    parse_option(FILE *, int *, struct option_data *);
-int    parse_reject_statement(FILE *);
-
-void   apply_actions(uint8_t *);
-void   set_default_client_identifier(struct ether_addr *);
-void   set_default_hostname(void);
-
-void
-init_config(void)
-{
-       struct option_data      *option;
-       uint32_t                 expiry;
-
-       config = calloc(1, sizeof(*config));
-       if (config == NULL)
-               fatal("config");
-
-       TAILQ_INIT(&config->reject_list);
-
-       /* Set some defaults. */
-       config->link_interval = 10;     /* secs before going daemon w/o lease */
-       config->select_interval = 0;    /* secs to wait for other OFFERs */
-       config->retry_interval = 1;     /* secs before asking for OFFER */
-#ifdef SMALL
-       config->backoff_cutoff = 2;     /* max secs between packet retries */
-       config->reboot_interval = 5;    /* secs before giving up on reboot */
-       config->offer_interval = 10;            /* secs to wait for an OFFER */
-#else
-       config->backoff_cutoff = 10;    /* max secs between packet retries */
-       config->reboot_interval = 1;    /* secs before giving up on reboot */
-       config->offer_interval = 30;            /* secs to wait for an OFFER */
-#endif
-       config->initial_interval = 1;   /* secs before 1st retry */
-
-       /* All leases must supply a subnet mask. Classful defaults are dead, Jim. */
-       config->required_options[config->required_option_count++] = DHO_SUBNET_MASK;
-
-       /*
-        * Set default lease length, which will determine default renewal
-        * and rebind times.
-        *
-        * XXX Thus applies to both BOOTP and DHCP leases.
-        *
-        * DHO_DHCP_LEASE_TIME (12 hours == 43200 seconds),
-        */
-       option = &config->defaults[DHO_DHCP_LEASE_TIME];
-       option->data = malloc(4);
-       if (option->data == NULL)
-               fatal("default lease length");
-
-       config->default_actions[DHO_DHCP_LEASE_TIME] = ACTION_DEFAULT;
-       option->len = 4;
-       expiry = htonl(43200);
-       memcpy(option->data, &expiry, 4);
-
-       config->requested_options
-           [config->requested_option_count++] = DHO_SUBNET_MASK;
-       config->requested_options
-           [config->requested_option_count++] = DHO_BROADCAST_ADDRESS;
-       config->requested_options
-           [config->requested_option_count++] = DHO_TIME_OFFSET;
-       /* RFC 3442 says CLASSLESS_STATIC_ROUTES must be before ROUTERS! */
-       config->requested_options
-           [config->requested_option_count++] = DHO_CLASSLESS_STATIC_ROUTES;
-       config->requested_options
-           [config->requested_option_count++] = DHO_ROUTERS;
-       config->requested_options
-           [config->requested_option_count++] = DHO_DOMAIN_NAME;
-       config->requested_options
-           [config->requested_option_count++] = DHO_DOMAIN_SEARCH;
-       config->requested_options
-           [config->requested_option_count++] = DHO_DOMAIN_NAME_SERVERS;
-       config->requested_options
-           [config->requested_option_count++] = DHO_HOST_NAME;
-       config->requested_options
-           [config->requested_option_count++] = DHO_BOOTFILE_NAME;
-       config->requested_options
-           [config->requested_option_count++] = DHO_TFTP_SERVER;
-}
-
-/*
- * conf-decls :==
- *       <nil>
- *     | conf-decl
- *     | conf-decls conf-decl
- */
-void
-read_conf(char *name, uint8_t *actions, struct ether_addr *hwaddr)
-{
-       FILE                    *cfile;
-       int                      token;
-
-       init_config();
-
-       if (path_dhclient_conf != NULL) {
-               cfile = fopen(path_dhclient_conf, "r");
-               if (cfile == NULL)
-                       fatal("fopen(%s)", path_dhclient_conf);
-               new_parse(path_dhclient_conf);
-               for (;;) {
-                       token = peek_token(NULL, cfile);
-                       if (token == EOF)
-                               break;
-                       parse_conf_decl(cfile, name);
-               }
-               fclose(cfile);
-       }
-
-       set_default_client_identifier(hwaddr);
-       set_default_hostname();
-       apply_actions(actions);
-}
-
-/*
- * leases :==
- *       <nil>
- *     | lease
- *     | leases lease
- */
-void
-read_lease_db(struct client_lease_tq *lease_db)
-{
-       struct client_lease     *lease, *lp, *nlp;
-       FILE                    *cfile;
-       int                      i;
-
-       TAILQ_INIT(lease_db);
-
-       if ((cfile = fopen(path_lease_db, "r")) == NULL)
-               return;
-
-       new_parse(path_lease_db);
-
-       i = DHO_DHCP_CLIENT_IDENTIFIER;
-       while (feof(cfile) == 0) {
-               if (parse_lease(cfile, &lease) == 0)
-                       continue;
-
-               /*
-                * The new lease will supersede a lease with the same
-                * ssid AND the same Client Identifier AND the same
-                * IP address.
-                */
-               TAILQ_FOREACH_SAFE(lp, lease_db, next, nlp) {
-                       if (lp->ssid_len != lease->ssid_len)
-                               continue;
-                       if (memcmp(lp->ssid, lease->ssid, lp->ssid_len) != 0)
-                               continue;
-                       if ((lease->options[i].len != 0) &&
-                           ((lp->options[i].len != lease->options[i].len) ||
-                           memcmp(lp->options[i].data, lease->options[i].data,
-                           lp->options[i].len) != 0))
-                               continue;
-                       if (lp->address.s_addr != lease->address.s_addr)
-                               continue;
-
-                       TAILQ_REMOVE(lease_db, lp, next);
-                       free_client_lease(lp);
-               }
-
-               if (lease->epoch == 0)
-                       time(&lease->epoch);
-               TAILQ_INSERT_TAIL(lease_db, lease, next);
-       }
-
-       fclose(cfile);
-}
-
-/*
- * conf-decl :==
- *       APPEND                option SEMI
- *     | BACKOFF_CUTOFF        number SEMI
- *     | DEFAULT               option SEMI
- *     | FILENAME              string SEMI
- *     | FIXED_ADDR            ip-address SEMI
- *     | IGNORE                option-name-list SEMI
- *     | INITIAL_INTERVAL      number SEMI
- *     | INTERFACE             interface
- *     | LINK_TIMEOUT          number SEMI
- *     | NEXT_SERVER           string SEMI
- *     | PREPEND               option SEMI
- *     | REBOOT                number SEMI
- *     | REJECT                ip-address SEMI
- *     | REQUEST               option-name-list SEMI
- *     | REQUIRE               option-name-list SEMI
- *     | RETRY                 number SEMI
- *     | SELECT_TIMEOUT        number SEMI
- *     | SEND                  option SEMI
- *     | SERVER_NAME           string SEMI
- *     | SUPERSEDE             option SEMI
- *     | TIMEOUT               number SEMI
- */
-void
-parse_conf_decl(FILE *cfile, char *name)
-{
-       uint8_t                  list[DHO_COUNT];
-       char                    *val;
-       enum actions            *p;
-       int                      action, count, i, token;
-
-       token = next_token(NULL, cfile);
-
-       switch (token) {
-       case TOK_APPEND:
-               if (parse_option(cfile, &i, config->defaults) == 0)
-                       return;
-               action = code_to_action(i, ACTION_APPEND);
-               if (action == ACTION_DEFAULT)
-                       parse_warn("'append' treated as 'default'");
-               config->default_actions[i] = action;
-               break;
-       case TOK_BACKOFF_CUTOFF:
-               if (parse_number(cfile, &config->backoff_cutoff, 0, INT32_MAX)
-                   == 0)
-                       return;
-               break;
-       case TOK_DEFAULT:
-               if (parse_option(cfile, &i, config->defaults) == 0)
-                       return;
-               config->default_actions[i] = ACTION_DEFAULT;
-               break;
-       case TOK_FILENAME:
-               if (parse_string(cfile, &val) == 0)
-                       return;
-               free(config->filename);
-               config->filename = val;
-               break;
-       case TOK_FIXED_ADDR:
-               if (parse_ip_addr(cfile, &config->address) == 0)
-                       return;
-               break;
-       case TOK_IGNORE:
-               memset(list, 0, sizeof(list));
-               count = 0;
-               if (parse_option_list(cfile, &count, list) == 0)
-                       return;
-               p = config->default_actions;
-               if (count == 0) {
-                       for (i = 0; i < DHO_COUNT; i++)
-                               if (p[i] == ACTION_IGNORE)
-                                       p[i] = ACTION_USELEASE;
-               } else {
-                       for (i = 0; i < count; i++)
-                               p[list[i]] = ACTION_IGNORE;
-               }
-               break;
-       case TOK_INITIAL_INTERVAL:
-               if (parse_number(cfile, &config->initial_interval, 0, INT32_MAX)
-                   == 0)
-                       return;
-               break;
-       case TOK_INTERFACE:
-               parse_interface(cfile, name);
-               return;
-       case TOK_LINK_TIMEOUT:
-               if (parse_number(cfile, &config->link_interval, 0, INT32_MAX)
-                   == 0)
-                       return;
-               break;
-       case TOK_NEXT_SERVER:
-               if (parse_ip_addr(cfile, &config->next_server) == 0)
-                       return;
-               break;
-       case TOK_PREPEND:
-               if (parse_option(cfile, &i, config->defaults) == 0)
-                       return;
-               action = code_to_action(i, ACTION_PREPEND);
-               if (action == ACTION_SUPERSEDE)
-                       parse_warn("'prepend' treated as 'supersede'");
-               config->default_actions[i] = action;
-               break;
-       case TOK_REBOOT:
-               if (parse_number(cfile, &config->reboot_interval, 0, INT32_MAX)
-                   == 0)
-                       return;
-               break;
-       case TOK_REJECT:
-               if (parse_reject_statement(cfile) == 0)
-                       return;
-               break;
-       case TOK_REQUEST:
-               if (parse_option_list(cfile, &config->requested_option_count,
-                   config->requested_options) == 0)
-                       return;
-               break;
-       case TOK_REQUIRE:
-               if (parse_option_list(cfile, &config->required_option_count,
-                   config->required_options) == 0)
-                       return;
-               break;
-       case TOK_RETRY:
-               if (parse_number(cfile, &config->retry_interval, 0, INT32_MAX)
-                   == 0)
-                       return;
-               break;
-       case TOK_SELECT_TIMEOUT:
-               if (parse_number(cfile, &config->select_interval, 0, INT32_MAX)
-                   == 0)
-                       return;
-               break;
-       case TOK_SEND:
-               if (parse_option(cfile, &i, config->send_options) == 0)
-                       return;
-               break;
-       case TOK_SERVER_NAME:
-               if (parse_string(cfile, &val) == 0)
-                       return;
-               free(config->server_name);
-               config->server_name = val;
-               break;
-       case TOK_SUPERSEDE:
-               if (parse_option(cfile, &i, config->defaults) == 0)
-                       return;
-               config->default_actions[i] = ACTION_SUPERSEDE;
-               break;
-       case TOK_TIMEOUT:
-               if (parse_number(cfile, &config->offer_interval, 0, INT32_MAX)
-                   == 0)
-                       return;
-               break;
-       case TOK_USELEASE:
-               memset(list, 0, sizeof(list));
-               count = 0;
-               if (parse_option_list(cfile, &count, list) == 0)
-                       return;
-               p = config->default_actions;
-               if (count == 0) {
-                       for (i = 0; i < DHO_COUNT; i++) {
-                               free(config->defaults[i].data);
-                               config->defaults[i].data = NULL;
-                               config->defaults[i].len = 0;
-                               p[i] = ACTION_USELEASE;
-                       }
-               } else {
-                       for (i = 0; i < count; i++) {
-                               free(config->defaults[list[i]].data);
-                               config->defaults[list[i]].data = NULL;
-                               config->defaults[list[i]].len = 0;
-                               p[list[i]] = ACTION_USELEASE;
-                       }
-               }
-               break;
-       default:
-               parse_warn("expecting statement.");
-               skip_to_semi(cfile);
-               return;
-       }
-
-       parse_semi(cfile);
-}
-
-int
-parse_hex_octets(FILE *cfile, unsigned int *len, uint8_t **buf)
-{
-       static uint8_t           octets[1500];
-       char                    *val, *ep;
-       unsigned long            ulval;
-       unsigned int             i;
-       int                      token;
-
-       i = 0;
-       do {
-               token = next_token(&val, cfile);
-
-               errno = 0;
-               ulval = strtoul(val, &ep, 16);
-               if ((val[0] == '\0' || *ep != '\0') ||
-                   (errno == ERANGE && ulval == ULONG_MAX) ||
-                   (ulval > UINT8_MAX))
-                       break;
-               octets[i++] = ulval;
-
-               if (peek_token(NULL, cfile) == ';') {
-                       *buf = malloc(i);
-                       if (*buf == NULL)
-                               break;
-                       memcpy(*buf, octets, i);
-                       *len = i;
-                       return 1;
-               }
-               if (i == sizeof(octets))
-                       break;
-               token = next_token(NULL, cfile);
-       } while (token == ':');
-
-       parse_warn("expecting colon delimited list of hex octets.");
-
-       if (token != ';')
-               skip_to_semi(cfile);
-
-       return 0;
-}
-
-int
-parse_domain_list(FILE *cfile, int *len, char **dp)
-{
-       uint8_t          buf[DHCP_DOMAIN_SEARCH_LEN];
-       char            *domain;
-       int              count, token;
-
-       memset(buf, 0, sizeof(buf));
-       count = 0;
-
-       do {
-               if (parse_string(cfile, &domain) == 0)
-                       return 0;
-
-               count++;
-               if (count > DHCP_DOMAIN_SEARCH_CNT) {
-                       parse_warn("more than 6 search domains");
-                       break;
-               }
-
-               if (count > 1)
-                       strlcat(buf, " ", sizeof(buf));
-               if (strlcat(buf, domain, sizeof(buf)) >= sizeof(buf)) {
-                       parse_warn("domain list too long");
-                       break;
-               }
-
-               token = peek_token(NULL, cfile);
-               if (token == ';') {
-                       *dp = strdup(buf);
-                       if (*dp == NULL)
-                               fatal("domain name list");
-                       *len = strlen(*dp);
-                       return 1;
-               }
-               token = next_token(NULL, cfile);
-               if (token != ',')
-                       parse_warn("';' or ',' expected");
-       } while (token == ',');
-
-       if (token != ';')
-               skip_to_semi(cfile);
-
-       return 0;
-}
-
-/*
- * option-list :==
- *       <nil>
- *     | option-name
- *     | option-list COMMA option-name
- */
-int
-parse_option_list(FILE *cfile, int *count, uint8_t *optlist)
-{
-       uint8_t          list[DHO_COUNT];
-       unsigned int     ix, j;
-       int              i;
-       int              token;
-       char            *val;
-
-       /* Empty list of option names is allowed, to re-init optlist. */
-       if (peek_token(NULL, cfile) == ';') {
-               memset(optlist, DHO_PAD, sizeof(list));
-               *count = 0;
-               return 1;
-       }
-
-       memset(list, 0, sizeof(list));
-       memcpy(list, optlist, *count);
-       ix = *count;
-       do {
-               /* Next token must be an option name. */
-               token = next_token(&val, cfile);
-               i = name_to_code(val);
-               if (i == DHO_END)
-                       break;
-
-               /* Avoid storing duplicate options in the list. */
-               for (j = 0; j < ix && list[j] != i; j++)
-                       ;
-               if (j == ix)
-                       list[ix++] = i;
-
-               if (peek_token(NULL, cfile) == ';') {
-                       memcpy(optlist, list, sizeof(list));
-                       *count = ix;
-                       return 1;
-               }
-               token = next_token(NULL, cfile);
-       } while (token == ',');
-
-       parse_warn("expecting comma delimited list of option names.");
-
-       if (token != ';')
-               skip_to_semi(cfile);
-
-       return 0;
-}
-
-/*
- * interface :==
- *     string LBRACE conf-decls RBRACE
- */
-int
-parse_interface(FILE *cfile, char *name)
-{
-       char    *val;
-       int      token;
-
-       token = next_token(&val, cfile);
-       if (token != TOK_STRING) {
-               parse_warn("expecting string.");
-               if (token != ';')
-                       skip_to_semi(cfile);
-               return 0;
-       }
-
-       if (strcmp(name, val) != 0) {
-               skip_to_semi(cfile);
-               return 1;
-       }
-
-       token = next_token(&val, cfile);
-       if (token != '{') {
-               parse_warn("expecting '{'.");
-               if (token != ';')
-                       skip_to_semi(cfile);
-               return 0;
-       }
-
-       for (;;) {
-               token = peek_token(&val, cfile);
-               if (token == EOF) {
-                       parse_warn("unterminated interface declaration.");
-                       return 0;
-               }
-               if (token == '}') {
-                       token = next_token(NULL, cfile);
-                       return 1;
-               }
-               parse_conf_decl(cfile, name);
-       }
-
-       return 0;
-}
-
-/*
- * lease :== LEASE RBRACE lease-decls LBRACE
- *
- * lease-decls :==
- *       <nil>
- *     | lease-decl
- *     | lease-decls lease-decl
- */
-int
-parse_lease(FILE *cfile, struct client_lease **lp)
-{
-       struct client_lease     *lease;
-       int                      token;
-
-       token = next_token(NULL, cfile);
-       if (token == EOF)
-               return 0;
-       if (token != TOK_LEASE) {
-               parse_warn("expecting lease");
-               if (token != ';')
-                       skip_to_semi(cfile);
-               return 0;
-       }
-
-       token = next_token(NULL, cfile);
-       if (token != '{') {
-               parse_warn("expecting '{'.");
-               if (token != ';')
-                       skip_to_semi(cfile);
-               return 0;
-       }
-
-       lease = calloc(1, sizeof(*lease));
-       if (lease == NULL)
-               fatal("lease");
-
-       for (;;) {
-               token = peek_token(NULL, cfile);
-               if (token == EOF) {
-                       parse_warn("unterminated lease.");
-                       free_client_lease(lease);
-                       break;
-               }
-               if (token == '}') {
-                       token = next_token(NULL, cfile);
-                       *lp = lease;
-                       return 1;
-               }
-               parse_lease_decl(cfile, lease);
-       }
-
-       return 0;
-}
-
-/*
- * lease-decl :==
- *       BOOTP         SEMI
- *     | EPOCH         number SEMI
- *     | EXPIRE        <skip to semi> SEMI
- *     | FILENAME      string SEMI
- *     | FIXED_ADDR    ip_address SEMI
- *     | INTERFACE     string SEMI
- *     | NEXT_SERVER   string SEMI
- *     | OPTION        option SEMI
- *     | REBIND        <skip to semi> SEMI
- *     | RENEW         <skip to semi> SEMI
- *     | SERVER_NAME   string SEMI
- *     | SSID          string SEMI
- */
-void
-parse_lease_decl(FILE *cfile, struct client_lease *lease)
-{
-       char            *val;
-       unsigned int     len;
-       int              i, token;
-
-       token = next_token(&val, cfile);
-
-       switch (token) {
-       case TOK_BOOTP:
-               /* 'bootp' is just a comment. See BOOTP_LEASE(). */
-               break;
-       case TOK_EPOCH:
-               if (parse_number(cfile, &lease->epoch, INT64_MIN, INT64_MAX)
-                   == 0)
-                       return;
-               break;
-       case TOK_EXPIRE:
-               /* 'expire' is just a comment. See 'epoch'. */
-               skip_to_semi(cfile);
-               return;
-       case TOK_FILENAME:
-               if (parse_string(cfile, &val) == 0)
-                       return;
-               free(lease->filename);
-               lease->filename = val;
-               break;
-       case TOK_FIXED_ADDR:
-               if (parse_ip_addr(cfile, &lease->address) == 0)
-                       return;
-               break;
-       case TOK_INTERFACE:
-               /* 'interface' is just a comment. */
-               skip_to_semi(cfile);
-               return;
-       case TOK_NEXT_SERVER:
-               if (parse_ip_addr(cfile, &lease->next_server) == 0)
-                       return;
-               break;
-       case TOK_OPTION:
-               if (parse_option(cfile, &i, lease->options) == 0)
-                       return;
-               break;
-       case TOK_REBIND:
-       case TOK_RENEW:
-               /* 'rebind' & 'renew' are just comments. See 'epoch'. */
-               skip_to_semi(cfile);
-               return;
-       case TOK_SERVER_NAME:
-               if (parse_string(cfile, &val) == 0)
-                       return;
-               free(lease->server_name);
-               lease->server_name = val;
-               break;
-       case TOK_SSID:
-               if (parse_string(cfile, &val) == 0)
-                       return;
-               len = strlen(val);
-               if (len > sizeof(lease->ssid)) {
-                       free(val);
-                       parse_warn("ssid > 32 bytes");
-                       skip_to_semi(cfile);
-                       return;
-               }
-               memset(lease->ssid, 0, sizeof(lease->ssid));
-               memcpy(lease->ssid, val, len);
-               free(val);
-               lease->ssid_len = len;
-               break;
-       default:
-               parse_warn("expecting lease declaration.");
-               skip_to_semi(cfile);
-               return;
-       }
-
-       parse_semi(cfile);
-}
-
-/*
- * option :==
- *     option-name option-value
- *
- * option-value :==
- *       text
- *     | hex-octets
- *     | signed-32
- *     | unsigned-32
- *     | unsigned-16
- *     | unsigned-8
- *     | flag
- *     | ip-address
- *     | ip-address-array
- *     | ip-address-pair-array
- *     | uint16-array
- *     | cidr-ip-address-array
- */
-int
-parse_option(FILE *cfile, int *code, struct option_data *options)
-{
-       uint8_t                  hunkbuf[1024], cidr[5], buf[4];
-       struct in_addr           ip_addr;
-       uint8_t                 *dp;
-       char                    *fmt, *val;
-       long long                number;
-       unsigned int             hunkix = 0;
-       int                      i, freedp, len, token;
-
-       token = next_token(&val, cfile);
-       i = name_to_code(val);
-       if (i == DHO_END) {
-               parse_warn("expecting option name.");
-               skip_to_semi(cfile);
-               return 0;
-       }
-
-       /* Parse the option data. */
-       do {
-               for (fmt = code_to_format(i); *fmt != '\0'; fmt++) {
-                       if (*fmt == 'A')
-                               break;
-                       freedp = 0;
-                       switch (*fmt) {
-                       case 'X':
-                               if (peek_token(NULL, cfile) == TOK_STRING) {
-                                       if (parse_string(cfile, (char **)&dp)
-                                           == 0)
-                                               return 0;
-                                       len = strlen(dp);
-                               } else if (parse_hex_octets(cfile, &len, &dp)
-                                   == 0)
-                                       return 0;
-                               freedp = 1;
-                               break;
-                       case 't': /* Text string. */
-                               if (parse_string(cfile, (char **)&dp) == 0)
-                                       return 0;
-                               len = strlen(dp);
-                               freedp = 1;
-                               break;
-                       case 'I': /* IP address. */
-                               if (parse_ip_addr(cfile, &ip_addr) == 0)
-                                       return 0;
-                               len = sizeof(ip_addr);
-                               dp = (uint8_t *)&ip_addr;
-                               break;
-                       case 'l':       /* Signed 32-bit integer. */
-                               if (parse_number(cfile, &number, INT32_MIN,
-                                   INT32_MAX) == 0)
-                                       return 0;
-                               number = htobe64(number);
-                               len = sizeof(int32_t);
-                               memcpy(buf, (char *)&number + (sizeof(number) - len), len);
-                               dp = buf;
-                               break;
-                       case 'L':       /* Unsigned 32-bit integer. */
-                               if (parse_number(cfile, &number, 0, UINT32_MAX) == 0)
-                                       return 0;
-                               number = htobe64(number);
-                               len = sizeof(uint32_t);
-                               memcpy(buf, (char *)&number + (sizeof(number) - len), len);
-                               dp = buf;
-                               break;
-                       case 'S':       /* Unsigned 16-bit integer. */
-                               if (parse_number(cfile, &number, 0, UINT16_MAX) == 0)
-                                       return 0;
-                               number = htobe64(number);
-                               len = sizeof(uint16_t);
-                               memcpy(buf, (char *)&number + (sizeof(number) - len), len);
-                               dp = buf;
-                               break;
-                       case 'B':       /* Unsigned 8-bit integer. */
-                               if (parse_number(cfile, &number, 0, UINT8_MAX) == 0)
-                                       return 0;
-                               buf[0] = number;
-                               len = 1;
-                               dp = buf;
-                               break;
-                       case 'f': /* Boolean flag. */
-                               if (parse_boolean(cfile, buf) == 0)
-                                       return 0;
-                               len = 1;
-                               dp = buf;
-                               break;
-                       case 'C':
-                               if (parse_cidr(cfile, cidr) == 0)
-                                       return 0;
-                               len = 1 + (cidr[0] + 7) / 8;
-                               dp = cidr;
-                               break;
-                       case 'D':
-                               if (peek_token(NULL, cfile) == TOK_STRING) {
-                                       if (parse_domain_list(cfile, &len,
-                                           (char **)&dp) == 0)
-                                               return 0;
-                               } else {
-                                       if (parse_hex_octets(cfile, &len, &dp)
-                                           == 0)
-                                               return 0;
-                                       val = rfc1035_as_string(dp, len);
-                                       free(dp);
-                                       dp = strdup(val);
-                                       if (dp == NULL)
-                                               fatal("RFC1035 hex octets");
-                                       len = strlen(dp);
-                               }
-                               freedp = 1;
-                               break;
-                       default:
-                               log_warnx("%s: bad format %c in "
-                                   "parse_option_param", log_procname, *fmt);
-                               skip_to_semi(cfile);
-                               return 0;
-                       }
-                       if (dp != NULL && len > 0) {
-                               if (hunkix + len > sizeof(hunkbuf)) {
-                                       if (freedp == 1)
-                                               free(dp);
-                                       parse_warn("option data buffer "
-                                           "overflow");
-                                       skip_to_semi(cfile);
-                                       return 0;
-                               }
-                               memcpy(&hunkbuf[hunkix], dp, len);
-                               hunkix += len;
-                               if (freedp == 1)
-                                       free(dp);
-                       }
-               }
-               token = peek_token(NULL, cfile);
-               if (*fmt == 'A' && token == ',')
-                       token = next_token(NULL, cfile);
-       } while (*fmt == 'A' && token == ',');
-
-       free(options[i].data);
-       options[i].data = malloc(hunkix);
-       if (options[i].data == NULL)
-               fatal("option data");
-       memcpy(options[i].data, hunkbuf, hunkix);
-       options[i].len = hunkix;
-
-       *code = i;
-
-       return 1;
-}
-
-int
-parse_reject_statement(FILE *cfile)
-{
-       struct in_addr           addr;
-       struct reject_elem      *elem;
-
-       if (parse_ip_addr(cfile, &addr) == 0)
-               return 0;
-
-       TAILQ_FOREACH(elem, &config->reject_list, next) {
-               if (elem->addr.s_addr == addr.s_addr)
-                       return 1;
-       }
-
-       elem = malloc(sizeof(*elem));
-       if (elem == NULL)
-               fatal("reject address");
-       elem->addr = addr;
-       TAILQ_INSERT_TAIL(&config->reject_list, elem, next);
-
-       return 1;
-}
-
-void
-apply_actions(uint8_t *actions)
-{
-       int              i;
-
-       for (i = 0; i < DHO_END; i++) {
-               switch (actions[i]) {
-               case ACTION_IGNORE:
-                       config->default_actions[i] = ACTION_IGNORE;
-                       free(config->defaults[i].data);
-                       config->defaults[i].data = NULL;
-                       config->defaults[i].len = 0;
-                       break;
-               default:
-                       break;
-               }
-       }
-}
-
-void
-set_default_client_identifier(struct ether_addr *hwaddr)
-{
-       struct option_data      *opt;
-
-       /*
-        * Check both len && data so
-        *
-        *     send dhcp-client-identifier "";
-        *
-        * can be used to suppress sending the default client
-        * identifier.
-        */
-       opt = &config->send_options[DHO_DHCP_CLIENT_IDENTIFIER];
-       if (opt->len == 0 && opt->data == NULL) {
-               opt->data = calloc(1, ETHER_ADDR_LEN + 1);
-               if (opt->data == NULL)
-                       fatal("default client identifier");
-               opt->data[0] = HTYPE_ETHER;
-               memcpy(&opt->data[1], hwaddr->ether_addr_octet,
-                   ETHER_ADDR_LEN);
-               opt->len = ETHER_ADDR_LEN + 1;
-       }
-}
-
-void
-set_default_hostname(void)
-{
-       char                     hn[HOST_NAME_MAX + 1], *p;
-       struct option_data      *opt;
-       int                      rslt;
-
-       /*
-        * Check both len && data so
-        *
-        *     send host-name "";
-        *
-        * can be used to suppress sending the default host
-        * name.
-        */
-       opt = &config->send_options[DHO_HOST_NAME];
-       if (opt->len == 0 && opt->data == NULL) {
-               rslt = gethostname(hn, sizeof(hn));
-               if (rslt == -1) {
-                       log_warn("host-name");
-                       return;
-               }
-               p = strchr(hn, '.');
-               if (p != NULL)
-                       *p = '\0';
-               opt->data = strdup(hn);
-               if (opt->data == NULL)
-                       fatal("default host-name");
-               opt->len = strlen(opt->data);
-       }
-}
diff --git a/sbin/dhclient/conflex.c b/sbin/dhclient/conflex.c
deleted file mode 100644 (file)
index cba4c6f..0000000
+++ /dev/null
@@ -1,406 +0,0 @@
-/*     $OpenBSD: conflex.c,v 1.50 2019/01/26 23:26:20 krw Exp $        */
-
-/* Lexical scanner for dhclient config file. */
-
-/*
- * Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#include <sys/queue.h>
-#include <sys/socket.h>
-
-#include <arpa/inet.h>
-
-#include <net/if.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include <ctype.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "dhcp.h"
-#include "dhcpd.h"
-#include "dhctoken.h"
-#include "log.h"
-
-int lexline;
-int lexchar;
-char *token_line;
-char *tlname;
-
-static char line1[81];
-static char line2[81];
-static char *prev_line;
-static char *cur_line;
-static int lpos;
-static int line;
-static int tlpos;
-static int tline;
-static int token;
-static int ugflag;
-static char *tval;
-static char tokbuf[1500];
-
-static void eol(void);
-static void skip_to_eol(FILE *);
-
-static int get_char(FILE *);
-static int get_token(FILE *);
-static int read_string(FILE *);
-static int read_num_or_name(int, FILE *);
-static int intern(char *, int);
-
-void
-new_parse(char *name)
-{
-       /*
-        * Initialize all parsing state, as we are starting to parse a
-        * new file, 'name'.
-        */
-
-       memset(line1, 0, sizeof(line1));
-       memset(line2, 0, sizeof(line2));
-       memset(tokbuf, 0, sizeof(tokbuf));
-
-       lpos = line = 1;
-       tlpos = tline = token = ugflag = 0;
-       tval = NULL;
-
-       lexline = lexchar = 0;
-       cur_line = line1;
-       prev_line = line2;
-       token_line = cur_line;
-       tlname = name;
-}
-
-/*
- * eol() increments the lexical line.
- *
- * It is split from get_char() because read_num_or_name() does *not*
- * want the lexical line incremented when a '\n' ends the token assembly.
- * Instead, it ungetc()'s the '\n' for the next token parse to deal with.
- * Incrementing the lexical line in that case causes parse_warn() to
- * generate messages that display a blank line instead of the offending
- * token in context.
- *
- * Invoccations of get_char() wanting to increment the lexical line on '\n'
- * must call eol().
- */
-static void
-eol(void)
-{
-       if (cur_line == line1) {
-               cur_line = line2;
-               prev_line = line1;
-       } else {
-               cur_line = line1;
-               prev_line = line2;
-       }
-       line++;
-       lpos = 1;
-       cur_line[0] = 0;
-}
-
-static int
-get_char(FILE *cfile)
-{
-       int c;
-
-       c = getc(cfile);
-
-       if (ugflag == 0) {
-               if (c != EOF && c != '\n') {
-                       if ((unsigned int)lpos < sizeof(line1)) {
-                               cur_line[lpos - 1] = c;
-                               cur_line[lpos] = 0;
-                       }
-                       lpos++;
-               }
-       } else
-               ugflag = 0;
-
-       return c;
-}
-
-static int
-get_token(FILE *cfile)
-{
-       static char     tb[2];
-       int             c, ttok;
-       int             l, p, u;
-
-       u = ugflag;
-
-       for (;;) {
-               l = line;
-               p = lpos - u;
-               u = 0;
-
-               c = get_char(cfile);
-
-               if (isascii(c) != 0 && isspace(c) != 0) {
-                       if (c == '\n')
-                               eol();
-                       continue;
-               }
-               if (c == '#') {
-                       skip_to_eol(cfile);
-                       continue;
-               }
-               lexline = l;
-               lexchar = p;
-               if (c == '"') {
-                       ttok = read_string(cfile);
-                       break;
-               } else if (c == '-' || (isascii(c) != 0 && isalnum(c) != 0)) {
-                       ttok = read_num_or_name(c, cfile);
-                       break;
-               } else {
-                       tb[0] = c;
-                       tb[1] = 0;
-                       tval = tb;
-                       ttok = c;
-                       break;
-               }
-       }
-       return ttok;
-}
-
-int
-next_token(char **rval, FILE *cfile)
-{
-       int     rv;
-
-       if (token != 0) {
-               if (lexline != tline)
-                       token_line = cur_line;
-               lexchar = tlpos;
-               lexline = tline;
-               rv = token;
-               token = 0;
-       } else {
-               rv = get_token(cfile);
-               token_line = cur_line;
-       }
-       if (rval != 0)
-               *rval = tval;
-
-       return rv;
-}
-
-int
-peek_token(char **rval, FILE *cfile)
-{
-       int      x;
-
-       if (token == 0) {
-               tlpos = lexchar;
-               tline = lexline;
-               token = get_token(cfile);
-               if (lexline != tline)
-                       token_line = prev_line;
-               x = lexchar;
-               lexchar = tlpos;
-               tlpos = x;
-               x = lexline;
-               lexline = tline;
-               tline = x;
-       }
-       if (rval != 0)
-               *rval = tval;
-
-       return token;
-}
-
-static void
-skip_to_eol(FILE *cfile)
-{
-       int      c;
-
-       for (;;) {
-               c = get_char(cfile);
-               if (c == EOF)
-                       return;
-               if (c == '\n') {
-                       eol();
-                       return;
-               }
-       }
-}
-
-static int
-read_string(FILE *cfile)
-{
-       int      i, c, bs;
-
-       /*
-        * Read in characters until an un-escaped '"' is encountered.
-        */
-       bs = i = 0;
-       while ((c = get_char(cfile)) != EOF) {
-               if (c == '"' && bs == 0)
-                       break;
-               if (c == '\n')
-                       eol();
-
-               tokbuf[i++] = c;
-               if (bs != 0)
-                       bs = 0;
-               else if (c == '\\')
-                       bs = 1;
-
-               if (i == sizeof(tokbuf) - 1)
-                       break;
-       }
-       if (bs == 1)
-               i--;
-
-       if (c == EOF)
-               parse_warn("eof in string constant");
-       else if (c != '"')
-               parse_warn("string constant too long");
-
-       tokbuf[i] = '\0';
-       tval = tokbuf;
-
-       return TOK_STRING;
-}
-
-static int
-read_num_or_name(int c, FILE *cfile)
-{
-       unsigned int     i, xdigits;
-       int              rv;
-
-       xdigits = (isxdigit(c) != 0) ? 1 : 0;
-
-       tokbuf[0] = c;
-       for (i = 1; i < sizeof(tokbuf); i++) {
-               c = get_char(cfile);
-               if (isascii(c) == 0 || (c != '-' && c != '_' &&
-                   isalnum(c) == 0)) {
-                       /* N.B.: Do not call eol()! '\n' is put back. */
-                       ungetc(c, cfile);
-                       ugflag = 1;
-                       break;
-               }
-               if (isxdigit(c) != 0)
-                       xdigits++;
-               tokbuf[i] = c;
-       }
-       if (i == sizeof(tokbuf)) {
-               parse_warn("token larger than internal buffer");
-               i--;
-               c = tokbuf[i];
-               if (isxdigit(c) != 0)
-                       xdigits--;
-       }
-       tokbuf[i] = 0;
-       tval = tokbuf;
-
-       c = (unsigned int)tokbuf[0];
-
-       if (c == '-')
-               rv = TOK_NUMBER;
-       else
-               rv = intern(tval, TOK_NUMBER_OR_NAME);
-
-       if (rv == TOK_NUMBER_OR_NAME && xdigits != i)
-               rv = TOK_NAME;
-
-       return rv;
-}
-
-static const struct keywords {
-       const char      *k_name;
-       int              k_val;
-} keywords[] = {
-       { "append",                             TOK_APPEND },
-       { "backoff-cutoff",                     TOK_BACKOFF_CUTOFF },
-       { "bootp",                              TOK_BOOTP },
-       { "default",                            TOK_DEFAULT },
-       { "epoch",                              TOK_EPOCH },
-       { "expire",                             TOK_EXPIRE },
-       { "filename",                           TOK_FILENAME },
-       { "fixed-address",                      TOK_FIXED_ADDR },
-       { "ignore",                             TOK_IGNORE },
-       { "initial-interval",                   TOK_INITIAL_INTERVAL },
-       { "interface",                          TOK_INTERFACE },
-       { "lease",                              TOK_LEASE },
-       { "link-timeout",                       TOK_LINK_TIMEOUT },
-       { "next-server",                        TOK_NEXT_SERVER },
-       { "option",                             TOK_OPTION },
-       { "prepend",                            TOK_PREPEND },
-       { "rebind",                             TOK_REBIND },
-       { "reboot",                             TOK_REBOOT },
-       { "reject",                             TOK_REJECT },
-       { "renew",                              TOK_RENEW },
-       { "request",                            TOK_REQUEST },
-       { "require",                            TOK_REQUIRE },
-       { "retry",                              TOK_RETRY },
-       { "select-timeout",                     TOK_SELECT_TIMEOUT },
-       { "send",                               TOK_SEND },
-       { "server-name",                        TOK_SERVER_NAME },
-       { "ssid",                               TOK_SSID },
-       { "supersede",                          TOK_SUPERSEDE },
-       { "timeout",                            TOK_TIMEOUT },
-       { "uselease",                           TOK_USELEASE }
-};
-
-int    kw_cmp(const void *k, const void *e);
-
-int
-kw_cmp(const void *k, const void *e)
-{
-       return strcasecmp(k, ((const struct keywords *)e)->k_name);
-}
-
-static int
-intern(char *atom, int dfv)
-{
-       const struct keywords   *p;
-
-       p = bsearch(atom, keywords, sizeof(keywords)/sizeof(keywords[0]),
-           sizeof(keywords[0]), kw_cmp);
-       if (p != NULL)
-               return p->k_val;
-       return dfv;
-}
diff --git a/sbin/dhclient/dhclient.8 b/sbin/dhclient/dhclient.8
deleted file mode 100644 (file)
index 27895f9..0000000
+++ /dev/null
@@ -1,292 +0,0 @@
-.\" $OpenBSD: dhclient.8,v 1.50 2022/05/16 17:15:16 abieber Exp $
-.\"
-.\" Copyright (c) 1997 The Internet Software Consortium.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\"
-.\" 1. Redistributions of source code must retain the above copyright
-.\"    notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\"    notice, this list of conditions and the following disclaimer in the
-.\"    documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of The Internet Software Consortium nor the names
-.\"    of its contributors may be used to endorse or promote products derived
-.\"    from this software without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
-.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
-.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-.\" DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
-.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" This software has been written for the Internet Software Consortium
-.\" by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
-.\" Enterprises.  To learn more about the Internet Software Consortium,
-.\" see ``http://www.isc.org/isc''.  To learn more about Vixie
-.\" Enterprises, see ``http://www.vix.com''.
-.Dd $Mdocdate: May 16 2022 $
-.Dt DHCLIENT 8
-.Os
-.Sh NAME
-.Nm dhclient
-.Nd Dynamic Host Configuration Protocol (DHCP) client
-.Sh SYNOPSIS
-.Nm
-.Op Fl dnrv
-.Op Fl c Ar file
-.Op Fl i Ar options
-.Ar interface
-.Sh DESCRIPTION
-.Nm
-uses the Dynamic Host Configuration Protocol (DHCP), or its
-predecessor BOOTP, to configure a network interface.
-Information typically provided via DHCP includes
-IPv4 address and subnet mask, default route,
-and domain name server.
-.Pp
-The options are as follows:
-.Bl -tag -width Ds
-.It Fl c Ar file
-Specify an alternate location to
-.Pa /etc/dhclient.conf
-for the configuration file.
-If
-.Ar file
-is the empty string then no configuration file is read.
-.It Fl d
-Do not daemonize.
-If this option is specified,
-.Nm
-will run in the foreground and log to
-.Em stderr .
-.It Fl i Ar options
-.Nm
-will ignore values provided by leases for the options specified.
-This list will supplement ignore statements in
-.Xr dhclient.conf 5 .
-.Ar options
-must be a comma separated list of valid option names.
-.It Fl n
-Configtest mode.
-Only check the configuration file for validity.
-.It Fl r
-Release the current lease back to the server it came from.
-.Nm
-exits after removing the active lease from
-.Pa /var/db/dhclient.leases . Ns Aq Ar IFNAME ,
-deleting the address the lease caused to be added to the interface,
-and sending a DHCPRELEASE packet to the server that supplied the lease.
-.Pp
-If there is no
-.Nm
-controlling the specified interface, or
-.Nm
-has no active lease configured, no action is performed.
-.It Fl v
-Causes
-.Nm
-to show more information about interactions with the DHCP server and what
-network configuration changes are attempted after accepting a lease.
-.Fl v
-is implied if either
-.Fl d
-or
-.Fl n
-is present.
-.El
-.Pp
-The DHCP protocol allows a host to contact a central server which
-maintains a list of IP addresses which may be assigned on one or more
-subnets.
-A DHCP client may request an address from this pool, and
-then use it on a temporary basis for communication on the network.
-The DHCP protocol also provides a mechanism whereby a client can learn
-important details about the network to which it is attached, such as
-the location of a default router, the location of a name server, and
-so on.
-.Pp
-On startup,
-.Nm
-reads
-.Pa /etc/dhclient.conf
-for configuration instructions.
-It then attempts to configure the network interface
-.Ar interface
-with DHCP.
-The special value
-.Dq egress
-may be used instead of a network interface name.
-In this case
-.Nm
-will look for the network interface currently in the interface group
-.Dq egress
-and configure it with DHCP.
-If there is more than one network interface in the egress group,
-.Nm
-will exit with an error.
-.Pp
-When configuring the interface,
-.Nm
-attempts to remove any existing addresses, gateway routes that use
-the interface, and non-permanent
-.Xr arp 8
-entries.
-.Nm
-automatically exits whenever a new
-.Nm
-is run on the same interface.
-.Pp
-Once the interface is configured,
-.Nm
-constructs a
-.Xr resolv.conf 5
-file.
-It does this only if any of the options
-.Cm domain-name ,
-.Cm domain-name-servers ,
-or
-.Cm domain-search
-are present
-(note that these options may be offered by the DHCP server but suppressed by
-.Xr dhclient.conf 5 ) .
-If a resolv.conf is constructed,
-.Nm
-appends any contents of the
-.Pa /etc/resolv.conf.tail
-file, which are read once at start up.
-The constructed resolv.conf is copied into
-.Pa /etc/resolv.conf
-whenever the default route goes out the interface
-.Nm
-is running on.
-.Nm
-monitors the system for changes to the default route and re-checks
-whether it should write its resolv.conf when possible changes are
-detected.
-.Pp
-In order to keep track of leases across system reboots and server
-restarts,
-.Nm
-keeps a list of leases it has been assigned in the
-.Pa /var/db/dhclient.leases . Ns Aq Ar IFNAME
-file.
-.Ar IFNAME
-represents the network interface of the DHCP client
-.Pq e.g. em0 ,
-one for each interface.
-On startup, after reading the
-.Xr dhclient.conf 5
-file,
-.Nm
-reads the leases file to refresh its memory about what leases it has been
-assigned.
-.Pp
-Old leases are kept around in case the DHCP server is unavailable when
-.Nm
-is first invoked (generally during the initial system boot
-process).
-In that event, old leases from the
-.Pa dhclient.leases . Ns Aq Ar IFNAME
-file which have not yet expired are tested, and if they are determined to
-be valid, they are used until either they expire or the DHCP server
-becomes available.
-.Pp
-A mobile host which may sometimes need to access a network on which no
-DHCP server exists may be preloaded with a lease for a fixed
-address on that network.
-When all attempts to contact a DHCP server have failed,
-.Nm
-will try to validate the static lease, and if it
-succeeds, it will use that lease until it is restarted.
-.Pp
-A mobile host may also travel to some networks on which DHCP is not
-available but BOOTP is.
-In that case, it may be advantageous to
-arrange with the network administrator for an entry on the BOOTP
-database, so that the host can boot quickly on that network rather
-than cycling through the list of old leases.
-.Sh FILES
-.Bl -tag -width "/var/db/dhclient.leases.<IFNAME>XXX" -compact
-.It Pa /etc/dhclient.conf
-DHCP client configuration file
-.It Pa /etc/hostname.XXX
-interface-specific configuration files
-.It Pa /var/db/dhclient.leases . Ns Aq Ar IFNAME
-database of acquired leases
-.El
-.Sh SEE ALSO
-.Xr dhclient.conf 5 ,
-.Xr dhclient.leases 5 ,
-.Xr hostname.if 5 ,
-.Xr dhcpd 8 ,
-.Xr dhcrelay 8 ,
-.Xr ifconfig 8
-.Sh STANDARDS
-.Rs
-.%A R. Droms
-.%D October 1993
-.%R RFC 1534
-.%T Interoperation Between DHCP and BOOTP
-.Re
-.Pp
-.Rs
-.%A R. Droms
-.%D March 1997
-.%R RFC 2131
-.%T Dynamic Host Configuration Protocol
-.Re
-.Pp
-.Rs
-.%A S. Alexander
-.%A R. Droms
-.%D March 1997
-.%R RFC 2132
-.%T DHCP Options and BOOTP Vendor Extensions
-.Re
-.Pp
-.Rs
-.%A T. Lemon
-.%A S. Cheshire
-.%D November 2002
-.%R RFC 3396
-.%T Encoding Long Options in the Dynamic Host Configuration Protocol (DHCPv4)
-.Re
-.Pp
-.Rs
-.%A T. Lemon
-.%A S. Cheshire
-.%A B. Volz
-.%D December 2002
-.%R RFC 3442
-.%T The Classless Static Route Option for Dynamic Host Configuration Protocol (DHCP) version 4
-.Re
-.Pp
-.Rs
-.%A N. Swamy
-.%A G. Halwasia
-.%A P. Jhingram
-.%D January 2013
-.%R RFC 6842
-.%T Client Identifier Option in DHCP Server Replies
-.Re
-.Sh AUTHORS
-.An -nosplit
-.Nm
-was written by
-.An Ted Lemon Aq Mt mellon@fugue.com
-and
-.An Elliot Poger Aq Mt elliot@poger.com .
-.Pp
-The current implementation was reworked by
-.An Henning Brauer Aq Mt henning@openbsd.org .
diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c
deleted file mode 100644 (file)
index e96dae1..0000000
+++ /dev/null
@@ -1,2927 +0,0 @@
-/*     $OpenBSD: dhclient.c,v 1.728 2024/04/28 16:43:42 florian Exp $  */
-
-/*
- * Copyright 2004 Henning Brauer <henning@openbsd.org>
- * Copyright (c) 1995, 1996, 1997, 1998, 1999
- * The Internet Software Consortium.    All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- *
- * This client was substantially modified and enhanced by Elliot Poger
- * for use on Linux while he was working on the MosquitoNet project at
- * Stanford.
- *
- * The current version owes much to Elliot's Linux enhancements, but
- * was substantially reorganized and partially rewritten by Ted Lemon
- * so as to use the same networking framework that the Internet Software
- * Consortium DHCP server uses.   Much system-specific configuration code
- * was moved into a shell script so that as support for more operating
- * systems is added, it will not be necessary to port and maintain
- * system-specific configuration code to these operating systems - instead,
- * the shell script can invoke the native tools to accomplish the same
- * purpose.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/uio.h>
-#include <sys/queue.h>
-
-#include <net/if.h>
-#include <net/if_types.h>
-#include <net/if_dl.h>
-#include <net/route.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include <net80211/ieee80211.h>
-#include <net80211/ieee80211_ioctl.h>
-
-#include <arpa/inet.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <ifaddrs.h>
-#include <imsg.h>
-#include <limits.h>
-#include <paths.h>
-#include <poll.h>
-#include <pwd.h>
-#include <resolv.h>
-#include <signal.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-#include <unistd.h>
-
-#include "dhcp.h"
-#include "dhcpd.h"
-#include "log.h"
-#include "privsep.h"
-
-char *path_dhclient_conf;
-char *path_lease_db;
-char *log_procname;
-
-int nullfd = -1;
-int cmd_opts;
-int quit;
-
-const struct in_addr inaddr_any = { INADDR_ANY };
-const struct in_addr inaddr_broadcast = { INADDR_BROADCAST };
-
-struct client_config *config;
-struct imsgbuf *unpriv_ibuf;
-
-void            usage(void);
-int             res_hnok_list(const char *);
-int             addressinuse(char *, struct in_addr, char *);
-
-void            fork_privchld(struct interface_info *, int, int);
-void            get_name(struct interface_info *, int, char *);
-void            get_ssid(struct interface_info *, int);
-void            get_sockets(struct interface_info *);
-int             get_routefd(int);
-void            set_iff_up(struct interface_info *, int);
-void            set_user(char *);
-int             get_ifa_family(char *, int);
-struct ifaddrs *get_link_ifa(const char *, struct ifaddrs *);
-void            interface_state(struct interface_info *);
-struct interface_info *initialize_interface(char *, int);
-void            tick_msg(const char *, int);
-void            rtm_dispatch(struct interface_info *, struct rt_msghdr *);
-
-struct client_lease *apply_defaults(struct client_lease *);
-struct client_lease *clone_lease(struct client_lease *);
-
-void state_reboot(struct interface_info *);
-void state_init(struct interface_info *);
-void state_selecting(struct interface_info *);
-void state_bound(struct interface_info *);
-void state_panic(struct interface_info *);
-
-void set_interval(struct interface_info *, struct timespec *);
-void set_resend_timeout(struct interface_info *, struct timespec *,
-    void (*where)(struct interface_info *));
-void set_secs(struct interface_info *, struct timespec *);
-
-void send_discover(struct interface_info *);
-void send_request(struct interface_info *);
-void send_decline(struct interface_info *);
-void send_release(struct interface_info *);
-
-void process_offer(struct interface_info *, struct option_data *,
-    const char *);
-void bind_lease(struct interface_info *);
-
-void make_discover(struct interface_info *, struct client_lease *);
-void make_request(struct interface_info *, struct client_lease *);
-void make_decline(struct interface_info *, struct client_lease *);
-void make_release(struct interface_info *, struct client_lease *);
-
-void release_lease(struct interface_info *);
-void propose_release(struct interface_info *);
-
-void write_lease_db(struct interface_info *);
-char *lease_as_string(char *, struct client_lease *);
-struct proposal *lease_as_proposal(struct client_lease *);
-struct unwind_info *lease_as_unwind_info(struct client_lease *);
-void append_statement(char *, size_t, char *, char *);
-time_t lease_expiry(struct client_lease *);
-time_t lease_renewal(struct client_lease *);
-time_t lease_rebind(struct client_lease *);
-void   get_lease_timeouts(struct interface_info *, struct client_lease *);
-
-struct client_lease *packet_to_lease(struct interface_info *,
-    struct option_data *);
-void go_daemon(void);
-int rdaemon(int);
-int take_charge(struct interface_info *, int, char *);
-int autoconf(struct interface_info *);
-struct client_lease *get_recorded_lease(struct interface_info *);
-
-#define ROUNDUP(a)     \
-       ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
-#define        ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
-
-#define        TICK_WAIT       0
-#define        TICK_SUCCESS    1
-#define        TICK_DAEMON     2
-
-static FILE *leaseFile;
-
-int
-get_ifa_family(char *cp, int n)
-{
-       struct sockaddr         *sa;
-       unsigned int             i;
-
-       for (i = 1; i; i <<= 1) {
-               if ((i & n) != 0) {
-                       sa = (struct sockaddr *)cp;
-                       if (i == RTA_IFA)
-                               return sa->sa_family;
-                       ADVANCE(cp, sa);
-               }
-       }
-
-       return AF_UNSPEC;
-}
-
-struct ifaddrs *
-get_link_ifa(const char *name, struct ifaddrs *ifap)
-{
-       struct ifaddrs          *ifa;
-       struct sockaddr_dl      *sdl;
-
-       for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
-               if (strcmp(name, ifa->ifa_name) == 0 &&
-                   (ifa->ifa_flags & IFF_LOOPBACK) == 0 &&
-                   (ifa->ifa_flags & IFF_POINTOPOINT) == 0 &&
-                   ifa->ifa_data != NULL && /* NULL shouldn't be possible. */
-                   ifa->ifa_addr != NULL &&
-                   ifa->ifa_addr->sa_family == AF_LINK) {
-                       sdl = (struct sockaddr_dl *)ifa->ifa_addr;
-                       if (sdl->sdl_alen == ETHER_ADDR_LEN &&
-                           (sdl->sdl_type == IFT_ETHER ||
-                           sdl->sdl_type == IFT_CARP))
-                               break;
-               }
-       }
-
-       if (ifa == NULL)
-               fatal("get_link_ifa()");
-
-       return ifa;
-}
-
-void
-interface_state(struct interface_info *ifi)
-{
-       struct ifaddrs                  *ifap, *ifa;
-       struct if_data                  *ifd;
-       struct sockaddr_dl              *sdl;
-       char                            *oldlladdr;
-       int                              newlinkup, oldlinkup;
-
-       oldlinkup = LINK_STATE_IS_UP(ifi->link_state);
-
-       if (getifaddrs(&ifap) == -1)
-               fatal("getifaddrs");
-
-       ifa = get_link_ifa(ifi->name, ifap);
-       sdl = (struct sockaddr_dl *)ifa->ifa_addr;
-       ifd = (struct if_data *)ifa->ifa_data;
-
-       if ((ifa->ifa_flags & IFF_UP) == 0 ||
-           (ifa->ifa_flags & IFF_RUNNING) == 0) {
-               ifi->link_state = LINK_STATE_DOWN;
-       } else {
-               ifi->link_state = ifd->ifi_link_state;
-               ifi->mtu = ifd->ifi_mtu;
-       }
-
-       newlinkup = LINK_STATE_IS_UP(ifi->link_state);
-       if (newlinkup != oldlinkup) {
-               log_debug("%s: link %s -> %s", log_procname,
-                   (oldlinkup != 0) ? "up" : "down",
-                   (newlinkup != 0) ? "up" : "down");
-               tick_msg("link", newlinkup ? TICK_SUCCESS : TICK_WAIT);
-       }
-
-       if (memcmp(&ifi->hw_address, LLADDR(sdl), ETHER_ADDR_LEN) != 0) {
-               if (log_getverbose()) {
-                       oldlladdr = strdup(ether_ntoa(&ifi->hw_address));
-                       if (oldlladdr == NULL)
-                               fatal("oldlladdr");
-                       log_debug("%s: LLADDR %s -> %s", log_procname,
-                           oldlladdr,
-                           ether_ntoa((struct ether_addr *)LLADDR(sdl)));
-                       free(oldlladdr);
-               }
-               memcpy(&ifi->hw_address, LLADDR(sdl), ETHER_ADDR_LEN);
-               quit = RESTART; /* Even if MTU has changed. */
-       }
-
-       freeifaddrs(ifap);
-}
-
-struct interface_info *
-initialize_interface(char *name, int noaction)
-{
-       struct interface_info           *ifi;
-       struct ifaddrs                  *ifap, *ifa;
-       struct if_data                  *ifd;
-       struct sockaddr_dl              *sdl;
-       int                              ioctlfd;
-
-       ifi = calloc(1, sizeof(*ifi));
-       if (ifi == NULL)
-               fatal("ifi");
-
-       ifi->rbuf_max = RT_BUF_SIZE;
-       ifi->rbuf = malloc(ifi->rbuf_max);
-       if (ifi->rbuf == NULL)
-               fatal("rbuf");
-
-       if ((ioctlfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
-               fatal("socket(AF_INET, SOCK_DGRAM)");
-
-       get_name(ifi, ioctlfd, name);
-       ifi->index = if_nametoindex(ifi->name);
-       if (ifi->index == 0)
-               fatalx("if_nametoindex(%s) == 0", ifi->name);
-
-       if (getifaddrs(&ifap) == -1)
-               fatal("getifaddrs()");
-
-       ifa = get_link_ifa(ifi->name, ifap);
-       sdl = (struct sockaddr_dl *)ifa->ifa_addr;
-       ifd = (struct if_data *)ifa->ifa_data;
-
-       if ((ifa->ifa_flags & IFF_UP) == 0 ||
-           (ifa->ifa_flags & IFF_RUNNING) == 0)
-               ifi->link_state = LINK_STATE_DOWN;
-       else
-               ifi->link_state = ifd->ifi_link_state;
-
-       memcpy(ifi->hw_address.ether_addr_octet, LLADDR(sdl), ETHER_ADDR_LEN);
-       ifi->rdomain = ifd->ifi_rdomain;
-
-       get_sockets(ifi);
-       get_ssid(ifi, ioctlfd);
-
-       if (noaction == 0 && !LINK_STATE_IS_UP(ifi->link_state))
-               set_iff_up(ifi, ioctlfd);
-
-       close(ioctlfd);
-       freeifaddrs(ifap);
-
-       return ifi;
-}
-
-void
-get_name(struct interface_info *ifi, int ioctlfd, char *arg)
-{
-       struct ifgroupreq        ifgr;
-       size_t                   len;
-
-       if (strcmp(arg, "egress") == 0) {
-               memset(&ifgr, 0, sizeof(ifgr));
-               strlcpy(ifgr.ifgr_name, "egress", sizeof(ifgr.ifgr_name));
-               if (ioctl(ioctlfd, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1)
-                       fatal("SIOCGIFGMEMB");
-               if (ifgr.ifgr_len > sizeof(struct ifg_req))
-                       fatalx("too many interfaces in group egress");
-               if ((ifgr.ifgr_groups = calloc(1, ifgr.ifgr_len)) == NULL)
-                       fatalx("ifgr_groups");
-               if (ioctl(ioctlfd, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1)
-                       fatal("SIOCGIFGMEMB");
-               len = strlcpy(ifi->name, ifgr.ifgr_groups->ifgrq_member,
-                   IFNAMSIZ);
-               free(ifgr.ifgr_groups);
-       } else
-               len = strlcpy(ifi->name, arg, IFNAMSIZ);
-
-       if (len >= IFNAMSIZ)
-               fatalx("interface name too long");
-}
-
-void
-get_ssid(struct interface_info *ifi, int ioctlfd)
-{
-       struct ieee80211_nwid           nwid;
-       struct ifreq                    ifr;
-
-       memset(&ifr, 0, sizeof(ifr));
-       memset(&nwid, 0, sizeof(nwid));
-
-       ifr.ifr_data = (caddr_t)&nwid;
-       strlcpy(ifr.ifr_name, ifi->name, sizeof(ifr.ifr_name));
-
-       if (ioctl(ioctlfd, SIOCG80211NWID, (caddr_t)&ifr) == 0) {
-               memset(ifi->ssid, 0, sizeof(ifi->ssid));
-               memcpy(ifi->ssid, nwid.i_nwid, nwid.i_len);
-               ifi->ssid_len = nwid.i_len;
-       }
-}
-
-void
-set_iff_up(struct interface_info *ifi, int ioctlfd)
-{
-       struct ifreq     ifr;
-
-       memset(&ifr, 0, sizeof(ifr));
-       strlcpy(ifr.ifr_name, ifi->name, sizeof(ifr.ifr_name));
-
-       if (ioctl(ioctlfd, SIOCGIFFLAGS, (caddr_t)&ifr) == -1)
-               fatal("%s: SIOCGIFFLAGS", ifi->name);
-
-       if ((ifr.ifr_flags & IFF_UP) == 0) {
-               ifi->link_state = LINK_STATE_DOWN;
-               ifr.ifr_flags |= IFF_UP;
-               if (ioctl(ioctlfd, SIOCSIFFLAGS, (caddr_t)&ifr) == -1)
-                       fatal("%s: SIOCSIFFLAGS", ifi->name);
-       }
-}
-
-void
-set_user(char *user)
-{
-       struct passwd           *pw;
-
-       pw = getpwnam(user);
-       if (pw == NULL)
-               fatalx("no such user: %s", user);
-
-       if (chroot(pw->pw_dir) == -1)
-               fatal("chroot(%s)", pw->pw_dir);
-       if (chdir("/") == -1)
-               fatal("chdir(\"/\")");
-       if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1)
-               fatal("setresgid");
-       if (setgroups(1, &pw->pw_gid) == -1)
-               fatal("setgroups");
-       if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1)
-               fatal("setresuid");
-
-       endpwent();
-}
-
-void
-get_sockets(struct interface_info *ifi)
-{
-       unsigned char           *newp;
-       size_t                   newsize;
-
-       ifi->udpfd = get_udp_sock(ifi->rdomain);
-       ifi->bpffd = get_bpf_sock(ifi->name);
-
-       newsize = configure_bpf_sock(ifi->bpffd);
-       if (newsize > ifi->rbuf_max) {
-               if ((newp = realloc(ifi->rbuf, newsize)) == NULL)
-                       fatal("rbuf");
-               ifi->rbuf = newp;
-               ifi->rbuf_max = newsize;
-       }
-}
-
-int
-get_routefd(int rdomain)
-{
-       int             routefd, rtfilter;
-
-       if ((routefd = socket(AF_ROUTE, SOCK_RAW, AF_INET)) == -1)
-               fatal("socket(AF_ROUTE, SOCK_RAW)");
-
-       rtfilter = ROUTE_FILTER(RTM_PROPOSAL) | ROUTE_FILTER(RTM_IFINFO) |
-           ROUTE_FILTER(RTM_NEWADDR) | ROUTE_FILTER(RTM_DELADDR) |
-           ROUTE_FILTER(RTM_IFANNOUNCE) | ROUTE_FILTER(RTM_80211INFO);
-
-       if (setsockopt(routefd, AF_ROUTE, ROUTE_MSGFILTER,
-           &rtfilter, sizeof(rtfilter)) == -1)
-               fatal("setsockopt(ROUTE_MSGFILTER)");
-       if (setsockopt(routefd, AF_ROUTE, ROUTE_TABLEFILTER, &rdomain,
-           sizeof(rdomain)) == -1)
-               fatal("setsockopt(ROUTE_TABLEFILTER)");
-
-       return routefd;
-}
-
-void
-routefd_handler(struct interface_info *ifi, int routefd)
-{
-       struct rt_msghdr                *rtm;
-       unsigned char                   *buf = ifi->rbuf;
-       unsigned char                   *lim, *next;
-       ssize_t                          n;
-
-       do {
-               n = read(routefd, buf, RT_BUF_SIZE);
-       } while (n == -1 && errno == EINTR);
-       if (n == -1) {
-               log_warn("%s: routing socket", log_procname);
-               return;
-       }
-       if (n == 0)
-               fatalx("%s: routing socket closed", log_procname);
-
-       lim = buf + n;
-       for (next = buf; next < lim && quit == 0; next += rtm->rtm_msglen) {
-               rtm = (struct rt_msghdr *)next;
-               if (lim < next + sizeof(rtm->rtm_msglen) ||
-                   lim < next + rtm->rtm_msglen)
-                       fatalx("%s: partial rtm in buffer", log_procname);
-
-               if (rtm->rtm_version != RTM_VERSION)
-                       continue;
-
-               rtm_dispatch(ifi, rtm);
-       }
-}
-
-void
-rtm_dispatch(struct interface_info *ifi, struct rt_msghdr *rtm)
-{
-       struct if_msghdr                *ifm;
-       struct if_announcemsghdr        *ifan;
-       struct ifa_msghdr               *ifam;
-       struct if_ieee80211_data        *ifie;
-       char                            *oldssid;
-       uint32_t                         oldmtu;
-
-       switch (rtm->rtm_type) {
-       case RTM_PROPOSAL:
-               if (rtm->rtm_priority == RTP_PROPOSAL_SOLICIT) {
-                       if (quit == 0 && ifi->active != NULL)
-                               tell_unwind(ifi->unwind_info, ifi->flags);
-                       return;
-               }
-               if (rtm->rtm_index != ifi->index ||
-                   rtm->rtm_priority != RTP_PROPOSAL_DHCLIENT)
-                       return;
-               if ((rtm->rtm_flags & RTF_PROTO3) != 0) {
-                       if (rtm->rtm_seq == (int32_t)ifi->xid) {
-                               ifi->flags |= IFI_IN_CHARGE;
-                               return;
-                       } else if ((ifi->flags & IFI_IN_CHARGE) != 0) {
-                               log_debug("%s: yielding responsibility",
-                                   log_procname);
-                               quit = TERMINATE;
-                       }
-               } else if ((rtm->rtm_flags & RTF_PROTO2) != 0) {
-                       release_lease(ifi); /* OK even if we sent it. */
-                       quit = TERMINATE;
-               } else
-                       return; /* Ignore tell_unwind() proposals. */
-               break;
-
-       case RTM_DESYNC:
-               log_warnx("%s: RTM_DESYNC", log_procname);
-               break;
-
-       case RTM_IFINFO:
-               ifm = (struct if_msghdr *)rtm;
-               if (ifm->ifm_index != ifi->index)
-                       break;
-               if ((rtm->rtm_flags & RTF_UP) == 0)
-                       fatalx("down");
-
-               oldmtu = ifi->mtu;
-               interface_state(ifi);
-               if (oldmtu == ifi->mtu)
-                       quit = RESTART;
-               else
-                       log_debug("%s: MTU %u -> %u",
-                           log_procname, oldmtu, ifi->mtu);
-               break;
-
-       case RTM_80211INFO:
-               if (rtm->rtm_index != ifi->index)
-                       break;
-               ifie = &((struct if_ieee80211_msghdr *)rtm)->ifim_ifie;
-               if (ifi->ssid_len != ifie->ifie_nwid_len || memcmp(ifi->ssid,
-                   ifie->ifie_nwid, ifie->ifie_nwid_len) != 0) {
-                       if (log_getverbose()) {
-                               oldssid = strdup(pretty_print_string(ifi->ssid,
-                                   ifi->ssid_len, 1));
-                               if (oldssid == NULL)
-                                       fatal("oldssid");
-                               log_debug("%s: SSID %s -> %s", log_procname,
-                                   oldssid, pretty_print_string(ifie->ifie_nwid,
-                                   ifie->ifie_nwid_len, 1));
-                               free(oldssid);
-                       }
-                       quit = RESTART;
-               }
-               break;
-
-       case RTM_IFANNOUNCE:
-               ifan = (struct if_announcemsghdr *)rtm;
-               if (ifan->ifan_what == IFAN_DEPARTURE && ifan->ifan_index ==
-                   ifi->index)
-                       fatalx("departed");
-               break;
-
-       case RTM_NEWADDR:
-       case RTM_DELADDR:
-               /* Need to check if it is time to write resolv.conf. */
-               ifam = (struct ifa_msghdr *)rtm;
-               if (get_ifa_family((char *)ifam + ifam->ifam_hdrlen,
-                   ifam->ifam_addrs) != AF_INET)
-                       return;
-               break;
-
-       default:
-               break;
-       }
-
-       /*
-        * Responsibility for resolv.conf may have changed hands.
-        */
-       if (quit == 0 && ifi->active != NULL &&
-           (ifi->flags & IFI_IN_CHARGE) != 0 &&
-           ifi->state == S_BOUND)
-               write_resolv_conf();
-}
-
-int
-main(int argc, char *argv[])
-{
-       uint8_t                  actions[DHO_END];
-       struct stat              sb;
-       struct interface_info   *ifi;
-       char                    *ignore_list, *p;
-       int                      fd, socket_fd[2];
-       int                      routefd;
-       int                      ch, i;
-
-       if (isatty(STDERR_FILENO) != 0)
-               log_init(1, LOG_DEBUG); /* log to stderr until daemonized */
-       else
-               log_init(0, LOG_DEBUG); /* can't log to stderr */
-
-       log_setverbose(0);      /* Don't show log_debug() messages. */
-
-       if (lstat(_PATH_DHCLIENT_CONF, &sb) == 0)
-               path_dhclient_conf = _PATH_DHCLIENT_CONF;
-       memset(actions, ACTION_USELEASE, sizeof(actions));
-
-       while ((ch = getopt(argc, argv, "c:di:nrv")) != -1) {
-               syslog(LOG_ALERT | LOG_CONS,
-                   "dhclient will go away, so -%c option will not exist", ch);
-               switch (ch) {
-               case 'c':
-                       if (strlen(optarg) == 0)
-                               path_dhclient_conf = NULL;
-                       else if (lstat(optarg, &sb) == 0)
-                               path_dhclient_conf = optarg;
-                       else
-                               fatal("lstat(%s)", optarg);
-                       break;
-               case 'd':
-                       cmd_opts |= OPT_FOREGROUND;
-                       break;
-               case 'i':
-                       syslog(LOG_ALERT | LOG_CONS,
-                           "dhclient will go away, for -i learn dhcpleased.conf");
-                       if (strlen(optarg) == 0)
-                               break;
-                       ignore_list = strdup(optarg);
-                       if (ignore_list == NULL)
-                               fatal("ignore_list");
-                       for (p = strsep(&ignore_list, ", "); p != NULL;
-                            p = strsep(&ignore_list, ", ")) {
-                               if (*p == '\0')
-                                       continue;
-                               i = name_to_code(p);
-                               if (i == DHO_END)
-                                       fatalx("invalid option name: '%s'", p);
-                               actions[i] = ACTION_IGNORE;
-                       }
-                       free(ignore_list);
-                       break;
-               case 'n':
-                       cmd_opts |= OPT_NOACTION;
-                       break;
-               case 'r':
-                       cmd_opts |= OPT_RELEASE;
-                       break;
-               case 'v':
-                       cmd_opts |= OPT_VERBOSE;
-                       break;
-               default:
-                       usage();
-               }
-       }
-
-       argc -= optind;
-       argv += optind;
-
-       if (argc != 1)
-               usage();
-
-       syslog(LOG_ALERT | LOG_CONS,
-           "dhclient will go away, stop using it");
-
-       execl("/sbin/ifconfig", "ifconfig", argv[0], "inet", "autoconf", NULL);
-
-       if ((cmd_opts & (OPT_FOREGROUND | OPT_NOACTION)) != 0)
-               cmd_opts |= OPT_VERBOSE;
-
-       if ((cmd_opts & OPT_VERBOSE) != 0)
-               log_setverbose(1);      /* Show log_debug() messages. */
-
-       ifi = initialize_interface(argv[0], cmd_opts & OPT_NOACTION);
-
-       log_procname = strdup(ifi->name);
-       if (log_procname == NULL)
-               fatal("log_procname");
-       setproctitle("%s", log_procname);
-       log_procinit(log_procname);
-
-       tzset();
-
-       if (setrtable(ifi->rdomain) == -1)
-               fatal("setrtable(%u)", ifi->rdomain);
-
-       if ((cmd_opts & OPT_RELEASE) != 0) {
-               if ((cmd_opts & OPT_NOACTION) == 0)
-                       propose_release(ifi);
-               exit(0);
-       }
-
-       signal(SIGPIPE, SIG_IGN);       /* Don't wait for go_daemon()! */
-
-       if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0,
-           socket_fd) == -1)
-               fatal("socketpair");
-
-       if ((nullfd = open(_PATH_DEVNULL, O_RDWR)) == -1)
-               fatal("open(%s)", _PATH_DEVNULL);
-
-       fork_privchld(ifi, socket_fd[0], socket_fd[1]);
-
-       close(socket_fd[0]);
-       if ((unpriv_ibuf = malloc(sizeof(*unpriv_ibuf))) == NULL)
-               fatal("unpriv_ibuf");
-       imsg_init(unpriv_ibuf, socket_fd[1]);
-
-       read_conf(ifi->name, actions, &ifi->hw_address);
-       if ((cmd_opts & OPT_NOACTION) != 0)
-               return 0;
-
-       if (asprintf(&path_lease_db, "%s.%s", _PATH_LEASE_DB, ifi->name) == -1)
-               fatal("path_lease_db");
-
-       routefd = get_routefd(ifi->rdomain);
-       fd = take_charge(ifi, routefd, path_lease_db);  /* Kill other dhclients. */
-       if (autoconf(ifi)) {
-               /* dhcpleased has been notified to request a new lease. */
-               return 0;
-       }
-       if (fd != -1)
-               read_lease_db(&ifi->lease_db);
-
-       if ((leaseFile = fopen(path_lease_db, "w")) == NULL)
-               log_warn("%s: fopen(%s)", log_procname, path_lease_db);
-       write_lease_db(ifi);
-
-       set_user("_dhcp");
-
-       if ((cmd_opts & OPT_FOREGROUND) == 0) {
-               if (pledge("stdio inet dns route proc", NULL) == -1)
-                       fatal("pledge");
-       } else {
-               if (pledge("stdio inet dns route", NULL) == -1)
-                       fatal("pledge");
-       }
-
-       tick_msg("link", LINK_STATE_IS_UP(ifi->link_state) ? TICK_SUCCESS :
-           TICK_WAIT);
-       quit = RESTART;
-       dispatch(ifi, routefd);
-
-       return 0;
-}
-
-void
-usage(void)
-{
-       extern char     *__progname;
-
-       fprintf(stderr,
-           "usage: %s [-dnrv] [-c file] [-i options] "
-           "interface\n", __progname);
-       exit(1);
-}
-
-void
-state_preboot(struct interface_info *ifi)
-{
-       interface_state(ifi);
-       if (quit != 0)
-               return;
-
-       if (LINK_STATE_IS_UP(ifi->link_state)) {
-               tick_msg("link", TICK_SUCCESS);
-               ifi->state = S_REBOOTING;
-               state_reboot(ifi);
-       } else {
-               tick_msg("link", TICK_WAIT);
-               set_timeout(ifi, 1, state_preboot);
-       }
-}
-
-/*
- * Called when the interface link becomes active.
- */
-void
-state_reboot(struct interface_info *ifi)
-{
-       const struct timespec    reboot_intvl = {config->reboot_interval, 0};
-       struct client_lease     *lease;
-
-       cancel_timeout(ifi);
-
-       /*
-        * If there is no recorded lease or the lease is BOOTP then
-        * go straight to INIT and try to DISCOVER a new lease.
-        */
-       ifi->active = get_recorded_lease(ifi);
-       if (ifi->active == NULL || BOOTP_LEASE(ifi->active)) {
-               ifi->state = S_INIT;
-               state_init(ifi);
-               return;
-       }
-       lease = apply_defaults(ifi->active);
-       get_lease_timeouts(ifi, lease);
-       free_client_lease(lease);
-
-       ifi->xid = arc4random();
-       make_request(ifi, ifi->active);
-
-       ifi->destination.s_addr = INADDR_BROADCAST;
-       clock_gettime(CLOCK_MONOTONIC, &ifi->first_sending);
-       timespecadd(&ifi->first_sending, &reboot_intvl, &ifi->reboot_timeout);
-       ifi->interval = 0;
-
-       send_request(ifi);
-}
-
-/*
- * Called when a lease has completely expired and we've been unable to
- * renew it.
- */
-void
-state_init(struct interface_info *ifi)
-{
-       const struct timespec   offer_intvl = {config->offer_interval, 0};
-
-       ifi->xid = arc4random();
-       make_discover(ifi, ifi->active);
-
-       ifi->destination.s_addr = INADDR_BROADCAST;
-       ifi->state = S_SELECTING;
-       clock_gettime(CLOCK_MONOTONIC, &ifi->first_sending);
-       timespecadd(&ifi->first_sending, &offer_intvl, &ifi->offer_timeout);
-       ifi->select_timeout = ifi->offer_timeout;
-       ifi->interval = 0;
-
-       send_discover(ifi);
-}
-
-/*
- * Called when one or more DHCPOFFER packets have been received and a
- * configurable period of time has passed.
- */
-void
-state_selecting(struct interface_info *ifi)
-{
-       cancel_timeout(ifi);
-
-       if (ifi->offer == NULL) {
-               state_panic(ifi);
-               return;
-       }
-
-       ifi->state = S_REQUESTING;
-
-       /* If it was a BOOTREPLY, we can just take the lease right now. */
-       if (BOOTP_LEASE(ifi->offer)) {
-               bind_lease(ifi);
-               return;
-       }
-
-       ifi->destination.s_addr = INADDR_BROADCAST;
-       clock_gettime(CLOCK_MONOTONIC, &ifi->first_sending);
-       ifi->interval = 0;
-
-       /*
-        * Make a DHCPREQUEST packet from the lease we picked. Keep
-        * the current xid, as all offers should have had the same
-        * one.
-        */
-       make_request(ifi, ifi->offer);
-
-       /* Toss the lease we picked - we'll get it back in a DHCPACK. */
-       free_client_lease(ifi->offer);
-       ifi->offer = NULL;
-       free(ifi->offer_src);
-       ifi->offer_src = NULL;
-
-       send_request(ifi);
-}
-
-void
-dhcpoffer(struct interface_info *ifi, struct option_data *options,
-    const char *src)
-{
-       if (ifi->state != S_SELECTING) {
-               log_debug("%s: unexpected DHCPOFFER from %s - state #%d",
-                   log_procname, src, ifi->state);
-               return;
-       }
-
-       log_debug("%s: DHCPOFFER from %s", log_procname, src);
-       process_offer(ifi, options, src);
-}
-
-void
-bootreply(struct interface_info *ifi, struct option_data *options,
-    const char *src)
-{
-       if (ifi->state != S_SELECTING) {
-               log_debug("%s: unexpected BOOTREPLY from %s - state #%d",
-                   log_procname, src, ifi->state);
-               return;
-       }
-
-       log_debug("%s: BOOTREPLY from %s", log_procname, src);
-       process_offer(ifi, options, src);
-}
-
-void
-process_offer(struct interface_info *ifi, struct option_data *options,
-    const char *src)
-{
-       const struct timespec    select_intvl = {config->select_interval, 0};
-       struct timespec          now;
-       struct client_lease     *lease;
-
-       clock_gettime(CLOCK_MONOTONIC, &now);
-
-       lease = packet_to_lease(ifi, options);
-       if (lease != NULL) {
-               if (ifi->offer == NULL) {
-                       ifi->offer = lease;
-                       free(ifi->offer_src);
-                       ifi->offer_src = strdup(src);   /* NULL is OK */
-                       timespecadd(&now, &select_intvl, &ifi->select_timeout);
-                       if (timespeccmp(&ifi->select_timeout,
-                           &ifi->offer_timeout, >))
-                               ifi->select_timeout = ifi->offer_timeout;
-               } else if (lease->address.s_addr ==
-                   ifi->offer->address.s_addr) {
-                       /* Decline duplicate offers. */
-               } else if (lease->address.s_addr ==
-                   ifi->requested_address.s_addr) {
-                       free_client_lease(ifi->offer);
-                       ifi->offer = lease;
-                       free(ifi->offer_src);
-                       ifi->offer_src = strdup(src);   /* NULL is OK */
-               }
-
-               if (ifi->offer != lease) {
-                       make_decline(ifi, lease);
-                       send_decline(ifi);
-                       free_client_lease(lease);
-               } else if (ifi->offer->address.s_addr ==
-                   ifi->requested_address.s_addr) {
-                       ifi->select_timeout = now;
-               }
-       }
-
-       if (timespeccmp(&now, &ifi->select_timeout, >=))
-               state_selecting(ifi);
-       else {
-               ifi->timeout = ifi->select_timeout;
-               ifi->timeout_func = state_selecting;
-       }
-}
-
-void
-dhcpack(struct interface_info *ifi, struct option_data *options,
-    const char *src)
-{
-       struct client_lease     *lease;
-
-       if (ifi->state != S_REBOOTING &&
-           ifi->state != S_REQUESTING &&
-           ifi->state != S_RENEWING) {
-               log_debug("%s: unexpected DHCPACK from %s - state #%d",
-                   log_procname, src, ifi->state);
-               return;
-       }
-
-       log_debug("%s: DHCPACK", log_procname);
-
-       lease = packet_to_lease(ifi, options);
-       if (lease == NULL) {
-               ifi->state = S_INIT;
-               state_init(ifi);
-               return;
-       }
-
-       ifi->offer = lease;
-       ifi->offer_src = strdup(src);   /* NULL is OK */
-       memcpy(ifi->offer->ssid, ifi->ssid, sizeof(ifi->offer->ssid));
-       ifi->offer->ssid_len = ifi->ssid_len;
-
-       /* Stop resending DHCPREQUEST. */
-       cancel_timeout(ifi);
-
-       bind_lease(ifi);
-}
-
-void
-dhcpnak(struct interface_info *ifi, const char *src)
-{
-       struct client_lease             *ll, *pl;
-
-       if (ifi->state != S_REBOOTING &&
-           ifi->state != S_REQUESTING &&
-           ifi->state != S_RENEWING) {
-               log_debug("%s: unexpected DHCPNAK from %s - state #%d",
-                   log_procname, src, ifi->state);
-               return;
-       }
-
-       log_debug("%s: DHCPNAK", log_procname);
-
-       /* Remove the NAK'd address from the database. */
-       TAILQ_FOREACH_SAFE(ll, &ifi->lease_db, next, pl) {
-               if (ifi->ssid_len == ll->ssid_len &&
-                   memcmp(ifi->ssid, ll->ssid, ll->ssid_len) == 0 &&
-                   ll->address.s_addr == ifi->requested_address.s_addr) {
-                       if (ll == ifi->active) {
-                               tell_unwind(NULL, ifi->flags);
-                               free(ifi->unwind_info);
-                               ifi->unwind_info = NULL;
-                               revoke_proposal(ifi->configured);
-                               free(ifi->configured);
-                               ifi->configured = NULL;
-                               ifi->active = NULL;
-                       }
-                       TAILQ_REMOVE(&ifi->lease_db, ll, next);
-                       free_client_lease(ll);
-                       write_lease_db(ifi);
-               }
-       }
-
-       /* Stop sending DHCPREQUEST packets. */
-       cancel_timeout(ifi);
-
-       ifi->state = S_INIT;
-       state_init(ifi);
-}
-
-void
-bind_lease(struct interface_info *ifi)
-{
-       struct timespec          now;
-       struct client_lease     *lease, *pl, *ll;
-       struct proposal         *effective_proposal = NULL;
-       struct unwind_info      *unwind_info;
-       char                    *msg = NULL;
-       int                      rslt, seen;
-
-       tick_msg("lease", TICK_SUCCESS);
-       clock_gettime(CLOCK_MONOTONIC, &now);
-
-       lease = apply_defaults(ifi->offer);
-       get_lease_timeouts(ifi, lease);
-
-       /* Replace the old active lease with the accepted offer. */
-       ifi->active = ifi->offer;
-       ifi->offer = NULL;
-
-       /*
-        * Supply unwind with updated info.
-        */
-       unwind_info = lease_as_unwind_info(ifi->active);
-       if (ifi->unwind_info == NULL && unwind_info != NULL) {
-               ifi->unwind_info = unwind_info;
-               tell_unwind(ifi->unwind_info, ifi->flags);
-       } else if (ifi->unwind_info != NULL && unwind_info == NULL) {
-               tell_unwind(NULL, ifi->flags);
-               free(ifi->unwind_info);
-               ifi->unwind_info = NULL;
-       } else if (ifi->unwind_info != NULL && unwind_info != NULL) {
-               if (memcmp(ifi->unwind_info, unwind_info,
-                   sizeof(*ifi->unwind_info)) != 0) {
-                       tell_unwind(NULL, ifi->flags);
-                       free(ifi->unwind_info);
-                       ifi->unwind_info = unwind_info;
-                       tell_unwind(ifi->unwind_info, ifi->flags);
-               }
-       }
-
-       effective_proposal = lease_as_proposal(lease);
-       if (ifi->configured != NULL) {
-               if (memcmp(ifi->configured, effective_proposal,
-                   sizeof(*ifi->configured)) == 0)
-                       goto newlease;
-       }
-       free(ifi->configured);
-       ifi->configured = effective_proposal;
-       effective_proposal = NULL;
-
-       propose(ifi->configured);
-       rslt = asprintf(&msg, "%s lease accepted from %s",
-           inet_ntoa(ifi->active->address),
-           (ifi->offer_src == NULL) ? "<unknown>" : ifi->offer_src);
-       if (rslt == -1)
-               fatal("bind msg");
-
-newlease:
-       seen = 0;
-       TAILQ_FOREACH_SAFE(ll, &ifi->lease_db, next, pl) {
-               if (ifi->ssid_len != ll->ssid_len ||
-                   memcmp(ifi->ssid, ll->ssid, ll->ssid_len) != 0)
-                       continue;
-               if (ifi->active == ll)
-                       seen = 1;
-               else if (ll->address.s_addr == ifi->active->address.s_addr) {
-                       TAILQ_REMOVE(&ifi->lease_db, ll, next);
-                       free_client_lease(ll);
-               }
-       }
-       if (seen == 0) {
-               if (ifi->active->epoch == 0)
-                       time(&ifi->active->epoch);
-               TAILQ_INSERT_HEAD(&ifi->lease_db, ifi->active,  next);
-       }
-
-       /*
-        * Write out updated information before going daemon.
-        *
-        * Some scripts (e.g. the installer in autoinstall mode) assume that
-        * the bind process is complete and all related information is in
-        * place when dhclient(8) goes daemon.
-        */
-       write_lease_db(ifi);
-
-       free_client_lease(lease);
-       free(effective_proposal);
-       free(ifi->offer_src);
-       ifi->offer_src = NULL;
-
-       if (msg != NULL) {
-               if ((cmd_opts & OPT_FOREGROUND) != 0) {
-                       /* log msg on console only. */
-                       ;
-               } else if (isatty(STDERR_FILENO) != 0) {
-                       /*
-                        * log msg to console and then go_daemon() so it is
-                        * logged again, this time to /var/log/daemon.
-                        */
-                       log_info("%s: %s", log_procname, msg);
-                       go_daemon();
-               }
-               log_info("%s: %s", log_procname, msg);
-               free(msg);
-       }
-
-       ifi->state = S_BOUND;
-       go_daemon();
-
-       /*
-        * Set timeout to start the renewal process.
-        *
-        * If the renewal time is in the past, the lease is from the
-        * leaseDB. Rather than immediately trying to contact a server,
-        * pause the configured time between attempts.
-        */
-       if (timespeccmp(&now, &ifi->renew, >=))
-               set_timeout(ifi, config->retry_interval, state_bound);
-       else {
-               ifi->timeout = ifi->renew;
-               ifi->timeout_func = state_bound;
-       }
-}
-
-/*
- * Called when we've successfully bound to a particular lease, but the renewal
- * time on that lease has expired.  We are expected to unicast a DHCPREQUEST to
- * the server that gave us our original lease.
- */
-void
-state_bound(struct interface_info *ifi)
-{
-       struct option_data      *opt;
-       struct in_addr          *dest;
-
-       ifi->xid = arc4random();
-       make_request(ifi, ifi->active);
-
-       dest = &ifi->destination;
-       opt = &ifi->active->options[DHO_DHCP_SERVER_IDENTIFIER];
-
-       if (opt->len == sizeof(*dest))
-               dest->s_addr = ((struct in_addr *)opt->data)->s_addr;
-       else
-               dest->s_addr = INADDR_BROADCAST;
-
-       clock_gettime(CLOCK_MONOTONIC, &ifi->first_sending);
-       ifi->interval = 0;
-       ifi->state = S_RENEWING;
-
-       send_request(ifi);
-}
-
-int
-addressinuse(char *name, struct in_addr address, char *ifname)
-{
-       struct ifaddrs          *ifap, *ifa;
-       struct sockaddr_in      *sin;
-       int                      used = 0;
-
-       if (getifaddrs(&ifap) != 0) {
-               log_warn("%s: getifaddrs", log_procname);
-               return 0;
-       }
-
-       for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
-               if (ifa->ifa_addr == NULL ||
-                   ifa->ifa_addr->sa_family != AF_INET)
-                       continue;
-
-               sin = (struct sockaddr_in *)ifa->ifa_addr;
-               if (memcmp(&address, &sin->sin_addr, sizeof(address)) == 0) {
-                       strlcpy(ifname, ifa->ifa_name, IF_NAMESIZE);
-                       used = 1;
-                       if (strncmp(ifname, name, IF_NAMESIZE) != 0)
-                               break;
-               }
-       }
-
-       freeifaddrs(ifap);
-       return used;
-}
-
-/*
- * Allocate a client_lease structure and initialize it from the
- * parameters in the received packet.
- *
- * Return NULL and decline the lease if a valid lease cannot be
- * constructed.
- */
-struct client_lease *
-packet_to_lease(struct interface_info *ifi, struct option_data *options)
-{
-       char                     ifname[IF_NAMESIZE];
-       struct dhcp_packet      *packet = &ifi->recv_packet;
-       struct client_lease     *lease;
-       char                    *pretty, *name;
-       int                      i;
-
-       lease = calloc(1, sizeof(*lease));
-       if (lease == NULL) {
-               log_warn("%s: lease", log_procname);
-               return NULL;    /* Can't even DECLINE. */
-       }
-
-       /*  Copy the lease addresses. */
-       lease->address.s_addr = packet->yiaddr.s_addr;
-       lease->next_server.s_addr = packet->siaddr.s_addr;
-
-       /* Copy the lease options. */
-       for (i = 0; i < DHO_COUNT; i++) {
-               if (options[i].len == 0)
-                       continue;
-               name = code_to_name(i);
-               if (i == DHO_DOMAIN_SEARCH) {
-                       /* Replace RFC 1035 data with a string. */
-                       pretty = rfc1035_as_string(options[i].data,
-                           options[i].len);
-                       free(options[i].data);
-                       options[i].data = strdup(pretty);
-                       if (options[i].data == NULL)
-                               fatal("RFC1035 string");
-                       options[i].len = strlen(options[i].data);
-               } else
-                       pretty = pretty_print_option(i, &options[i], 0);
-               if (strlen(pretty) == 0)
-                       continue;
-               switch (i) {
-               case DHO_DOMAIN_SEARCH:
-               case DHO_DOMAIN_NAME:
-                       /*
-                        * Allow deviant but historically blessed
-                        * practice of supplying multiple domain names
-                        * with DHO_DOMAIN_NAME. Thus allowing multiple
-                        * entries in the resolv.conf 'search' statement.
-                        */
-                       if (res_hnok_list(pretty) == 0) {
-                               log_debug("%s: invalid host name in %s",
-                                   log_procname, name);
-                               continue;
-                       }
-                       break;
-               case DHO_HOST_NAME:
-               case DHO_NIS_DOMAIN:
-                       if (res_hnok(pretty) == 0) {
-                               log_debug("%s: invalid host name in %s",
-                                   log_procname, name);
-                               continue;
-                       }
-                       break;
-               default:
-                       break;
-               }
-               lease->options[i] = options[i];
-               options[i].data = NULL;
-               options[i].len = 0;
-       }
-
-       /*
-        * If this lease doesn't supply a required parameter, decline it.
-        */
-       for (i = 0; i < config->required_option_count; i++) {
-               if (lease->options[config->required_options[i]].len == 0) {
-                       name = code_to_name(config->required_options[i]);
-                       log_warnx("%s: %s required but missing", log_procname,
-                           name);
-                       goto decline;
-               }
-       }
-
-       /*
-        * If this lease is trying to sell us an address we are already
-        * using, decline it.
-        */
-       memset(ifname, 0, sizeof(ifname));
-       if (addressinuse(ifi->name, lease->address, ifname) != 0 &&
-           strncmp(ifname, ifi->name, IF_NAMESIZE) != 0) {
-               log_warnx("%s: %s already configured on %s", log_procname,
-                   inet_ntoa(lease->address), ifname);
-               goto decline;
-       }
-
-       /* If the server name was filled out, copy it. */
-       if ((lease->options[DHO_DHCP_OPTION_OVERLOAD].len == 0 ||
-           (lease->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 2) == 0) &&
-           packet->sname[0]) {
-               lease->server_name = calloc(1, DHCP_SNAME_LEN + 1);
-               if (lease->server_name == NULL) {
-                       log_warn("%s: SNAME", log_procname);
-                       goto decline;
-               }
-               memcpy(lease->server_name, packet->sname, DHCP_SNAME_LEN);
-               if (res_hnok(lease->server_name) == 0) {
-                       log_debug("%s: invalid host name in SNAME ignored",
-                           log_procname);
-                       free(lease->server_name);
-                       lease->server_name = NULL;
-               }
-       }
-
-       /* If the file name was filled out, copy it. */
-       if ((lease->options[DHO_DHCP_OPTION_OVERLOAD].len == 0 ||
-           (lease->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 1) == 0) &&
-           packet->file[0]) {
-               /* Don't count on the NUL terminator. */
-               lease->filename = malloc(DHCP_FILE_LEN + 1);
-               if (lease->filename == NULL) {
-                       log_warn("%s: filename", log_procname);
-                       goto decline;
-               }
-               memcpy(lease->filename, packet->file, DHCP_FILE_LEN);
-               lease->filename[DHCP_FILE_LEN] = '\0';
-       }
-
-       /*
-        * Record the client identifier used to obtain the lease.  We already
-        * checked that the packet client identifier is absent (RFC 2131) or
-        * matches what we sent (RFC 6842),
-        */
-       i = DHO_DHCP_CLIENT_IDENTIFIER;
-       if (lease->options[i].len == 0 && config->send_options[i].len != 0) {
-               lease->options[i].len = config->send_options[i].len;
-               lease->options[i].data = malloc(lease->options[i].len);
-               if (lease->options[i].data == NULL)
-                       fatal("lease client-identifier");
-               memcpy(lease->options[i].data, config->send_options[i].data,
-                   lease->options[i].len);
-       }
-
-       time(&lease->epoch);
-       return lease;
-
-decline:
-       make_decline(ifi, lease);
-       send_decline(ifi);
-       free_client_lease(lease);
-       return NULL;
-}
-
-void
-set_interval(struct interface_info *ifi, struct timespec *now)
-{
-       struct timespec         interval;
-
-       if (timespeccmp(now, &ifi->timeout, >))
-               ifi->interval = 1;
-       else {
-               timespecsub(&ifi->timeout, now, &interval);
-               if (interval.tv_sec == 0 || interval.tv_nsec > 500000000LL)
-                       interval.tv_sec++;
-               ifi->interval = interval.tv_sec;
-       }
-}
-
-void
-set_resend_timeout(struct interface_info *ifi, struct timespec *now,
-    void (*where)(struct interface_info *))
-{
-       const struct timespec   reboot_intvl = {config->reboot_interval, 0};
-       const struct timespec   initial_intvl = {config->initial_interval, 0};
-       const struct timespec   cutoff_intvl = {config->backoff_cutoff, 0};
-       const struct timespec   onesecond = {1, 0};
-       struct timespec         interval, when;
-
-       if (timespeccmp(now, &ifi->link_timeout, <))
-               interval = onesecond;
-       else if (ifi->interval == 0) {
-               if (ifi->state == S_REBOOTING)
-                       interval = reboot_intvl;
-               else
-                       interval = initial_intvl;
-       } else {
-               timespecclear(&interval);
-               interval.tv_sec = ifi->interval + arc4random_uniform(2 *
-                   ifi->interval);
-       }
-       if (timespeccmp(&interval, &onesecond, <))
-               interval = onesecond;
-       else if (timespeccmp(&interval, &cutoff_intvl, >))
-               interval = cutoff_intvl;
-
-       timespecadd(now, &interval, &when);
-       switch (ifi->state) {
-       case S_REBOOTING:
-       case S_RENEWING:
-               if (timespeccmp(&when, &ifi->expiry, >))
-                       when = ifi->expiry;
-               break;
-       case S_SELECTING:
-               if (timespeccmp(&when, &ifi->select_timeout, >))
-                       when = ifi->select_timeout;
-               break;
-       case S_REQUESTING:
-               if (timespeccmp(&when, &ifi->offer_timeout, >))
-                       when = ifi->offer_timeout;
-               break;
-       default:
-               break;
-       }
-
-       ifi->timeout = when;
-       ifi->timeout_func = where;
-}
-
-void
-set_secs(struct interface_info *ifi, struct timespec *now)
-{
-       struct timespec interval;
-
-       if (ifi->state != S_REQUESTING) {
-               /* Update the number of seconds since we started sending. */
-               timespecsub(now, &ifi->first_sending, &interval);
-               if (interval.tv_nsec > 500000000LL)
-                       interval.tv_sec++;
-               if (interval.tv_sec > UINT16_MAX)
-                       ifi->secs = UINT16_MAX;
-               else
-                       ifi->secs = interval.tv_sec;
-       }
-
-       ifi->sent_packet.secs = htons(ifi->secs);
-}
-
-/*
- * Send out a DHCPDISCOVER packet, and set a timeout to send out another
- * one after the right interval has expired.  If we don't get an offer by
- * the time we reach the panic interval, call the panic function.
- */
-void
-send_discover(struct interface_info *ifi)
-{
-       struct timespec          now;
-       ssize_t                  rslt;
-
-       clock_gettime(CLOCK_MONOTONIC, &now);
-       if (timespeccmp(&now, &ifi->offer_timeout, >=)) {
-               state_panic(ifi);
-               return;
-       }
-
-       set_resend_timeout(ifi, &now, send_discover);
-       set_interval(ifi, &now);
-       set_secs(ifi, &now);
-
-       rslt = send_packet(ifi, inaddr_any, inaddr_broadcast, "DHCPDISCOVER");
-       if (rslt != -1)
-               log_debug("%s: DHCPDISCOVER %s", log_procname,
-                   (ifi->requested_address.s_addr == INADDR_ANY) ? "" :
-                   inet_ntoa(ifi->requested_address));
-
-       tick_msg("lease", TICK_WAIT);
-}
-
-/*
- * Called if we haven't received any offers in a preset amount of time. When
- * this happens, we try to use existing leases that haven't yet expired.
- *
- * If LINK_STATE_UNKNOWN, do NOT use recorded leases.
- */
-void
-state_panic(struct interface_info *ifi)
-{
-       log_debug("%s: no acceptable DHCPOFFERS received", log_procname);
-
-       if (ifi->link_state >= LINK_STATE_UP) {
-               ifi->offer = get_recorded_lease(ifi);
-               if (ifi->offer != NULL) {
-                       ifi->state = S_REQUESTING;
-                       ifi->offer_src = strdup(path_lease_db); /* NULL is OK. */
-                       bind_lease(ifi);
-                       return;
-               }
-       }
-
-       /*
-        * No leases were available, or what was available didn't work
-        */
-       log_debug("%s: no working leases in persistent database - sleeping",
-           log_procname);
-       ifi->state = S_INIT;
-       set_timeout(ifi, config->retry_interval, state_init);
-       tick_msg("lease", TICK_DAEMON);
-}
-
-void
-send_request(struct interface_info *ifi)
-{
-       struct sockaddr_in       destination;
-       struct in_addr           from;
-       struct timespec          now;
-       ssize_t                  rslt;
-       char                    *addr;
-
-       cancel_timeout(ifi);
-       clock_gettime(CLOCK_MONOTONIC, &now);
-
-       switch (ifi->state) {
-       case S_REBOOTING:
-               if (timespeccmp(&now, &ifi->reboot_timeout, >=))
-                       ifi->state = S_INIT;
-               else {
-                       destination.sin_addr.s_addr = INADDR_BROADCAST;
-                       if (ifi->active == NULL)
-                               from.s_addr = INADDR_ANY;
-                       else
-                               from.s_addr = ifi->active->address.s_addr;
-               }
-               break;
-       case S_RENEWING:
-               if (timespeccmp(&now, &ifi->expiry, >=))
-                       ifi->state = S_INIT;
-               else {
-                       if (timespeccmp(&now, &ifi->rebind, >=))
-                               destination.sin_addr.s_addr = INADDR_BROADCAST;
-                       else
-                               destination.sin_addr.s_addr = ifi->destination.s_addr;
-                       if (ifi->active == NULL)
-                               from.s_addr = INADDR_ANY;
-                       else
-                               from.s_addr = ifi->active->address.s_addr;
-               }
-               break;
-       case S_REQUESTING:
-               if (timespeccmp(&now, &ifi->offer_timeout, >=))
-                       ifi->state = S_INIT;
-               else {
-                       destination.sin_addr.s_addr = INADDR_BROADCAST;
-                       from.s_addr = INADDR_ANY;
-               }
-               break;
-       default:
-               ifi->state = S_INIT;
-               break;
-       }
-
-       if (ifi->state == S_INIT) {
-               /* Something has gone wrong. Start over. */
-               state_init(ifi);
-               return;
-       }
-
-       set_resend_timeout(ifi, &now, send_request);
-       set_interval(ifi, &now);
-       set_secs(ifi, &now);
-
-       rslt = send_packet(ifi, from, destination.sin_addr, "DHCPREQUEST");
-       if (rslt != -1 && log_getverbose()) {
-               addr = strdup(inet_ntoa(ifi->requested_address));
-               if (addr == NULL)
-                       fatal("strdup(ifi->requested_address)");
-               if (destination.sin_addr.s_addr == INADDR_BROADCAST)
-                       log_debug("%s: DHCPREQUEST %s", log_procname, addr);
-               else
-                       log_debug("%s: DHCPREQUEST %s from %s", log_procname,
-                           addr, inet_ntoa(destination.sin_addr));
-               free(addr);
-       }
-
-       tick_msg("lease", TICK_WAIT);
-}
-
-void
-send_decline(struct interface_info *ifi)
-{
-       ssize_t         rslt;
-
-       rslt = send_packet(ifi, inaddr_any, inaddr_broadcast, "DHCPDECLINE");
-       if (rslt != -1)
-               log_debug("%s: DHCPDECLINE", log_procname);
-}
-
-void
-send_release(struct interface_info *ifi)
-{
-       ssize_t         rslt;
-
-       rslt = send_packet(ifi, ifi->configured->address, ifi->destination,
-           "DHCPRELEASE");
-       if (rslt != -1)
-               log_debug("%s: DHCPRELEASE", log_procname);
-}
-
-void
-make_discover(struct interface_info *ifi, struct client_lease *lease)
-{
-       struct option_data       options[DHO_COUNT];
-       struct dhcp_packet      *packet = &ifi->sent_packet;
-       unsigned char            discover = DHCPDISCOVER;
-       int                      i;
-
-       memset(options, 0, sizeof(options));
-       memset(packet, 0, sizeof(*packet));
-
-       /* Set DHCP_MESSAGE_TYPE to DHCPDISCOVER */
-       i = DHO_DHCP_MESSAGE_TYPE;
-       options[i].data = &discover;
-       options[i].len = sizeof(discover);
-
-       /* Request the options we want */
-       i  = DHO_DHCP_PARAMETER_REQUEST_LIST;
-       options[i].data = config->requested_options;
-       options[i].len = config->requested_option_count;
-
-       /* If we had an address, try to get it again. */
-       if (lease != NULL) {
-               ifi->requested_address = lease->address;
-               i = DHO_DHCP_REQUESTED_ADDRESS;
-               options[i].data = (char *)&lease->address;
-               options[i].len = sizeof(lease->address);
-       } else
-               ifi->requested_address.s_addr = INADDR_ANY;
-
-       /* Send any options requested in the config file. */
-       for (i = 0; i < DHO_COUNT; i++)
-               if (options[i].data == NULL &&
-                   config->send_options[i].data != NULL) {
-                       options[i].data = config->send_options[i].data;
-                       options[i].len = config->send_options[i].len;
-               }
-
-       /*
-        * Set up the option buffer to fit in a 576-byte UDP packet, which
-        * RFC 791 says is the largest packet that *MUST* be accepted
-        * by any host.
-        */
-       i = pack_options(ifi->sent_packet.options, 576 - DHCP_FIXED_LEN,
-           options);
-       if (i == -1 || packet->options[i] != DHO_END)
-               fatalx("options do not fit in DHCPDISCOVER packet");
-       ifi->sent_packet_length = DHCP_FIXED_NON_UDP+i+1;
-       if (ifi->sent_packet_length < BOOTP_MIN_LEN)
-               ifi->sent_packet_length = BOOTP_MIN_LEN;
-
-       packet->op = BOOTREQUEST;
-       packet->htype = HTYPE_ETHER;
-       packet->hlen = ETHER_ADDR_LEN;
-       packet->hops = 0;
-       packet->xid = ifi->xid;
-       packet->secs = 0; /* filled in by send_discover. */
-       packet->flags = 0;
-
-       packet->ciaddr.s_addr = INADDR_ANY;
-       packet->yiaddr.s_addr = INADDR_ANY;
-       packet->siaddr.s_addr = INADDR_ANY;
-       packet->giaddr.s_addr = INADDR_ANY;
-
-       memcpy(&packet->chaddr, ifi->hw_address.ether_addr_octet,
-           ETHER_ADDR_LEN);
-}
-
-void
-make_request(struct interface_info *ifi, struct client_lease *lease)
-{
-       struct option_data       options[DHO_COUNT];
-       struct dhcp_packet      *packet = &ifi->sent_packet;
-       unsigned char            request = DHCPREQUEST;
-       int                      i;
-
-       memset(options, 0, sizeof(options));
-       memset(packet, 0, sizeof(*packet));
-
-       /* Set DHCP_MESSAGE_TYPE to DHCPREQUEST */
-       i = DHO_DHCP_MESSAGE_TYPE;
-       options[i].data = &request;
-       options[i].len = sizeof(request);
-
-       /* Request the options we want */
-       i = DHO_DHCP_PARAMETER_REQUEST_LIST;
-       options[i].data = config->requested_options;
-       options[i].len = config->requested_option_count;
-
-       /*
-        * If we are requesting an address that hasn't yet been assigned
-        * to us, use the DHCP Requested Address option.
-        */
-       if (ifi->state == S_REQUESTING) {
-               /* Send back the server identifier. */
-               i = DHO_DHCP_SERVER_IDENTIFIER;
-               options[i].data = lease->options[i].data;
-               options[i].len = lease->options[i].len;
-       }
-       if (ifi->state == S_REQUESTING ||
-           ifi->state == S_REBOOTING) {
-               i = DHO_DHCP_REQUESTED_ADDRESS;
-               options[i].data = (char *)&lease->address.s_addr;
-               options[i].len = sizeof(lease->address.s_addr);
-       }
-
-       /* Send any options requested in the config file. */
-       for (i = 0; i < DHO_COUNT; i++)
-               if (options[i].data == NULL &&
-                   config->send_options[i].data != NULL) {
-                       options[i].data = config->send_options[i].data;
-                       options[i].len = config->send_options[i].len;
-               }
-
-       /*
-        * Set up the option buffer to fit in a 576-byte UDP packet, which
-        * RFC 791 says is the largest packet that *MUST* be accepted
-        * by any host.
-        */
-       i = pack_options(ifi->sent_packet.options, 576 - DHCP_FIXED_LEN,
-           options);
-       if (i == -1 || packet->options[i] != DHO_END)
-               fatalx("options do not fit in DHCPREQUEST packet");
-       ifi->sent_packet_length = DHCP_FIXED_NON_UDP+i+1;
-       if (ifi->sent_packet_length < BOOTP_MIN_LEN)
-               ifi->sent_packet_length = BOOTP_MIN_LEN;
-
-       packet->op = BOOTREQUEST;
-       packet->htype = HTYPE_ETHER;
-       packet->hlen = ETHER_ADDR_LEN;
-       packet->hops = 0;
-       packet->xid = ifi->xid;
-       packet->secs = 0; /* Filled in by send_request. */
-       packet->flags = 0;
-
-       /*
-        * If we own the address we're requesting, put it in ciaddr. Otherwise
-        * set ciaddr to zero.
-        */
-       ifi->requested_address = lease->address;
-       if (ifi->state == S_BOUND ||
-           ifi->state == S_RENEWING)
-               packet->ciaddr.s_addr = lease->address.s_addr;
-       else
-               packet->ciaddr.s_addr = INADDR_ANY;
-
-       packet->yiaddr.s_addr = INADDR_ANY;
-       packet->siaddr.s_addr = INADDR_ANY;
-       packet->giaddr.s_addr = INADDR_ANY;
-
-       memcpy(&packet->chaddr, ifi->hw_address.ether_addr_octet,
-           ETHER_ADDR_LEN);
-}
-
-void
-make_decline(struct interface_info *ifi, struct client_lease *lease)
-{
-       struct option_data       options[DHO_COUNT];
-       struct dhcp_packet      *packet = &ifi->sent_packet;
-       unsigned char            decline = DHCPDECLINE;
-       int                      i;
-
-       memset(options, 0, sizeof(options));
-       memset(packet, 0, sizeof(*packet));
-
-       /* Set DHCP_MESSAGE_TYPE to DHCPDECLINE */
-       i = DHO_DHCP_MESSAGE_TYPE;
-       options[i].data = &decline;
-       options[i].len = sizeof(decline);
-
-       /* Send back the server identifier. */
-       i = DHO_DHCP_SERVER_IDENTIFIER;
-       options[i].data = lease->options[i].data;
-       options[i].len = lease->options[i].len;
-
-       /* Send back the address we're declining. */
-       i = DHO_DHCP_REQUESTED_ADDRESS;
-       options[i].data = (char *)&lease->address.s_addr;
-       options[i].len = sizeof(lease->address.s_addr);
-
-       /* Send the uid if the user supplied one. */
-       i = DHO_DHCP_CLIENT_IDENTIFIER;
-       if (config->send_options[i].len != 0) {
-               options[i].data = config->send_options[i].data;
-               options[i].len = config->send_options[i].len;
-       }
-
-       /*
-        * Set up the option buffer to fit in a 576-byte UDP packet, which
-        * RFC 791 says is the largest packet that *MUST* be accepted
-        * by any host.
-        */
-       i = pack_options(ifi->sent_packet.options, 576 - DHCP_FIXED_LEN,
-           options);
-       if (i == -1 || packet->options[i] != DHO_END)
-               fatalx("options do not fit in DHCPDECLINE packet");
-       ifi->sent_packet_length = DHCP_FIXED_NON_UDP+i+1;
-       if (ifi->sent_packet_length < BOOTP_MIN_LEN)
-               ifi->sent_packet_length = BOOTP_MIN_LEN;
-
-       packet->op = BOOTREQUEST;
-       packet->htype = HTYPE_ETHER;
-       packet->hlen = ETHER_ADDR_LEN;
-       packet->hops = 0;
-       packet->xid = ifi->xid;
-       packet->secs = 0;
-       packet->flags = 0;
-
-       /* ciaddr must always be zero. */
-       packet->ciaddr.s_addr = INADDR_ANY;
-       packet->yiaddr.s_addr = INADDR_ANY;
-       packet->siaddr.s_addr = INADDR_ANY;
-       packet->giaddr.s_addr = INADDR_ANY;
-
-       memcpy(&packet->chaddr, ifi->hw_address.ether_addr_octet,
-           ETHER_ADDR_LEN);
-}
-
-void
-make_release(struct interface_info *ifi, struct client_lease *lease)
-{
-       struct option_data       options[DHO_COUNT];
-       struct dhcp_packet      *packet = &ifi->sent_packet;
-       unsigned char            release = DHCPRELEASE;
-       int                      i;
-
-       memset(options, 0, sizeof(options));
-       memset(packet, 0, sizeof(*packet));
-
-       /* Set DHCP_MESSAGE_TYPE to DHCPRELEASE */
-       i = DHO_DHCP_MESSAGE_TYPE;
-       options[i].data = &release;
-       options[i].len = sizeof(release);
-
-       /* Send back the server identifier. */
-       i = DHO_DHCP_SERVER_IDENTIFIER;
-       options[i].data = lease->options[i].data;
-       options[i].len = lease->options[i].len;
-
-       i = pack_options(ifi->sent_packet.options, 576 - DHCP_FIXED_LEN,
-           options);
-       if (i == -1 || packet->options[i] != DHO_END)
-               fatalx("options do not fit in DHCPRELEASE packet");
-       ifi->sent_packet_length = DHCP_FIXED_NON_UDP+i+1;
-       if (ifi->sent_packet_length < BOOTP_MIN_LEN)
-               ifi->sent_packet_length = BOOTP_MIN_LEN;
-
-       packet->op = BOOTREQUEST;
-       packet->htype = HTYPE_ETHER;
-       packet->hlen = ETHER_ADDR_LEN;
-       packet->hops = 0;
-       packet->xid = ifi->xid;
-       packet->secs = 0;
-       packet->flags = 0;
-
-       /*
-        * Note we return the *offered* address. NOT the configured address
-        * which could have been changed via dhclient.conf. But the packet
-        * is sent from the *configured* address.
-        *
-        * This might easily confuse a server, but if you play with fire
-        * by modifying the address you are on your own!
-        */
-       packet->ciaddr.s_addr = ifi->active->address.s_addr;
-       packet->yiaddr.s_addr = INADDR_ANY;
-       packet->siaddr.s_addr = INADDR_ANY;
-       packet->giaddr.s_addr = INADDR_ANY;
-
-       memcpy(&packet->chaddr, ifi->hw_address.ether_addr_octet,
-           ETHER_ADDR_LEN);
-}
-
-void
-free_client_lease(struct client_lease *lease)
-{
-       int      i;
-
-       if (lease == NULL)
-               return;
-
-       free(lease->server_name);
-       free(lease->filename);
-       for (i = 0; i < DHO_COUNT; i++)
-               free(lease->options[i].data);
-
-       free(lease);
-}
-
-void
-write_lease_db(struct interface_info *ifi)
-{
-       struct client_lease_tq *lease_db = &ifi->lease_db;
-       struct client_lease     *lp, *pl;
-       char                    *leasestr;
-
-       TAILQ_FOREACH_SAFE(lp, lease_db, next, pl) {
-               if (lp != ifi->active && lease_expiry(lp) == 0) {
-                       TAILQ_REMOVE(lease_db, lp, next);
-                       free_client_lease(lp);
-               }
-       }
-
-       if (leaseFile == NULL)
-               return;
-
-       rewind(leaseFile);
-
-       /*
-        * The leases file is kept in chronological order, with the
-        * most recently bound lease last. When the file was read
-        * leases that were not expired were added to the head of the
-        * TAILQ ifi->leases as they were read. Therefore write out
-        * the leases in ifi->leases in reverse order to recreate
-        * the chonological order required.
-        */
-       TAILQ_FOREACH_REVERSE(lp, lease_db, client_lease_tq, next) {
-               leasestr = lease_as_string("lease", lp);
-               if (leasestr != NULL)
-                       fprintf(leaseFile, "%s", leasestr);
-               else
-                       log_warnx("%s: cannot make lease into string",
-                           log_procname);
-       }
-
-       fflush(leaseFile);
-       ftruncate(fileno(leaseFile), ftello(leaseFile));
-       fsync(fileno(leaseFile));
-}
-
-void
-append_statement(char *string, size_t sz, char *s1, char *s2)
-{
-       strlcat(string, s1, sz);
-       strlcat(string, s2, sz);
-       strlcat(string, ";\n", sz);
-}
-
-struct unwind_info *
-lease_as_unwind_info(struct client_lease *lease)
-{
-       struct unwind_info      *unwind_info;
-       struct option_data      *opt;
-       unsigned int             servers;
-
-       unwind_info = calloc(1, sizeof(*unwind_info));
-       if (unwind_info == NULL)
-               fatal("unwind_info");
-
-       opt = &lease->options[DHO_DOMAIN_NAME_SERVERS];
-       if (opt->len != 0) {
-               servers = opt->len / sizeof(in_addr_t);
-               if (servers > MAXNS)
-                       servers = MAXNS;
-               if (servers > 0) {
-                       unwind_info->count = servers;
-                       memcpy(unwind_info->ns, opt->data, servers *
-                           sizeof(in_addr_t));
-               }
-       }
-
-       if (unwind_info->count == 0) {
-               free(unwind_info);
-               unwind_info = NULL;
-       }
-
-       return unwind_info;
-}
-
-struct proposal *
-lease_as_proposal(struct client_lease *lease)
-{
-       uint8_t                  defroute[5];   /* 1 + sizeof(in_addr_t) */
-       struct option_data       fake;
-       struct option_data      *opt;
-       struct proposal         *proposal;
-       uint8_t                 *ns, *p, *routes, *domains;
-       unsigned int             routes_len = 0, domains_len = 0, ns_len = 0;
-       uint16_t                 mtu;
-
-       /* Determine sizes of variable length data. */
-       opt = NULL;
-       if (lease->options[DHO_CLASSLESS_STATIC_ROUTES].len != 0) {
-               opt = &lease->options[DHO_CLASSLESS_STATIC_ROUTES];
-       } else if (lease->options[DHO_CLASSLESS_MS_STATIC_ROUTES].len != 0) {
-               opt = &lease->options[DHO_CLASSLESS_MS_STATIC_ROUTES];
-       } else if (lease->options[DHO_ROUTERS].len != 0) {
-               /* Fake a classless static default route. */
-               opt = &lease->options[DHO_ROUTERS];
-               fake.len = sizeof(defroute);
-               fake.data = defroute;
-               fake.data[0] = 0;
-               memcpy(&fake.data[1], opt->data, sizeof(defroute) - 1);
-               opt = &fake;
-       }
-       if (opt != NULL) {
-               routes_len = opt->len;
-               routes = opt->data;
-       }
-
-       opt = NULL;
-       if (lease->options[DHO_DOMAIN_SEARCH].len != 0)
-               opt = &lease->options[DHO_DOMAIN_SEARCH];
-       else if (lease->options[DHO_DOMAIN_NAME].len != 0)
-               opt = &lease->options[DHO_DOMAIN_NAME];
-       if (opt != NULL) {
-               domains_len = opt->len;
-               domains = opt->data;
-       }
-
-       if (lease->options[DHO_DOMAIN_NAME_SERVERS].len != 0) {
-               opt = &lease->options[DHO_DOMAIN_NAME_SERVERS];
-               ns_len = opt->len;
-               ns = opt->data;
-       }
-
-       /* Allocate proposal. */
-       proposal = calloc(1, sizeof(*proposal) + routes_len + domains_len +
-           ns_len);
-       if (proposal == NULL)
-               fatal("proposal");
-
-       /* Fill in proposal. */
-       proposal->address = lease->address;
-
-       opt = &lease->options[DHO_INTERFACE_MTU];
-       if (opt->len == sizeof(mtu)) {
-               memcpy(&mtu, opt->data, sizeof(mtu));
-               proposal->mtu = ntohs(mtu);
-       }
-
-       opt = &lease->options[DHO_SUBNET_MASK];
-       if (opt->len == sizeof(proposal->netmask))
-               memcpy(&proposal->netmask, opt->data, opt->len);
-
-       /* Append variable length uint8_t data. */
-       p = (uint8_t *)proposal + sizeof(struct proposal);
-       memcpy(p, routes, routes_len);
-       p += routes_len;
-       proposal->routes_len = routes_len;
-       memcpy(p, domains, domains_len);
-       p += domains_len;
-       proposal->domains_len = domains_len;
-       memcpy(p, ns, ns_len);
-       proposal->ns_len = ns_len;
-
-       return proposal;
-}
-
-char *
-lease_as_string(char *type, struct client_lease *lease)
-{
-       static char              string[8192];
-       char                     timebuf[27];   /* 6 2017/04/08 05:47:50 UTC; */
-       struct option_data      *opt;
-       struct tm               *tm;
-       char                    *buf, *name;
-       time_t                   t;
-       size_t                   rslt;
-       int                      i;
-
-       memset(string, 0, sizeof(string));
-
-       strlcat(string, type, sizeof(string));
-       strlcat(string, " {\n", sizeof(string));
-       strlcat(string, BOOTP_LEASE(lease) ? "  bootp;\n" : "", sizeof(string));
-
-       append_statement(string, sizeof(string), "  fixed-address ",
-           inet_ntoa(lease->address));
-       append_statement(string, sizeof(string), "  next-server ",
-           inet_ntoa(lease->next_server));
-
-       if (lease->filename != NULL) {
-               buf = pretty_print_string(lease->filename,
-                   strlen(lease->filename), 1);
-               if (buf == NULL)
-                       return NULL;
-               append_statement(string, sizeof(string), "  filename ", buf);
-       }
-       if (lease->server_name != NULL) {
-               buf = pretty_print_string(lease->server_name,
-                   strlen(lease->server_name), 1);
-               if (buf == NULL)
-                       return NULL;
-               append_statement(string, sizeof(string), "  server-name ",
-                   buf);
-       }
-       if (lease->ssid_len != 0) {
-               buf = pretty_print_string(lease->ssid, lease->ssid_len, 1);
-               if (buf == NULL)
-                       return NULL;
-               append_statement(string, sizeof(string), "  ssid ", buf);
-       }
-
-       for (i = 0; i < DHO_COUNT; i++) {
-               opt = &lease->options[i];
-               if (opt->len == 0)
-                       continue;
-               name = code_to_name(i);
-
-               buf = pretty_print_option(i, opt, 1);
-               if (strlen(buf) == 0)
-                       continue;
-               strlcat(string, "  option ", sizeof(string));
-               strlcat(string, name, sizeof(string));
-               append_statement(string, sizeof(string), " ", buf);
-       }
-
-       i = asprintf(&buf, "%lld", (long long)lease->epoch);
-       if (i == -1)
-               return NULL;
-       append_statement(string, sizeof(string), "  epoch ", buf);
-       free(buf);
-
-       t = lease->epoch + lease_renewal(lease);
-       if ((tm = gmtime(&t)) == NULL)
-               return NULL;
-       rslt = strftime(timebuf, sizeof(timebuf), DB_TIMEFMT, tm);
-       if (rslt == 0)
-               return NULL;
-       append_statement(string, sizeof(string), "  renew ", timebuf);
-
-       t = lease->epoch + lease_rebind(lease);
-       if ((tm = gmtime(&t)) == NULL)
-               return NULL;
-       rslt = strftime(timebuf, sizeof(timebuf), DB_TIMEFMT, tm);
-       if (rslt == 0)
-               return NULL;
-       append_statement(string, sizeof(string), "  rebind ", timebuf);
-
-       t = lease->epoch + lease_expiry(lease);
-       if ((tm = gmtime(&t)) == NULL)
-               return NULL;
-       rslt = strftime(timebuf, sizeof(timebuf), DB_TIMEFMT, tm);
-       if (rslt == 0)
-               return NULL;
-       append_statement(string, sizeof(string), "  expire ", timebuf);
-
-       rslt = strlcat(string, "}\n", sizeof(string));
-       if (rslt >= sizeof(string))
-               return NULL;
-
-       return string;
-}
-
-void
-go_daemon(void)
-{
-       static int       daemonized = 0;
-
-       if ((cmd_opts & OPT_FOREGROUND) != 0 || daemonized != 0)
-               return;
-
-       daemonized = 1;
-
-       if (rdaemon(nullfd) == -1)
-               fatal("daemonize");
-
-       /* Stop logging to stderr. */
-       log_init(0, LOG_DAEMON);
-       if ((cmd_opts & OPT_VERBOSE) != 0)
-               log_setverbose(1);      /* Show log_debug() messages. */
-       log_procinit(log_procname);
-
-       setproctitle("%s", log_procname);
-       signal(SIGHUP, SIG_IGN);
-       signal(SIGPIPE, SIG_IGN);
-}
-
-int
-rdaemon(int devnull)
-{
-       if (devnull == -1) {
-               errno = EBADF;
-               return -1;
-       }
-       if (fcntl(devnull, F_GETFL) == -1)
-               return -1;
-
-       switch (fork()) {
-       case -1:
-               return -1;
-       case 0:
-               break;
-       default:
-               _exit(0);
-       }
-
-       if (setsid() == -1)
-               return -1;
-
-       (void)dup2(devnull, STDIN_FILENO);
-       (void)dup2(devnull, STDOUT_FILENO);
-       (void)dup2(devnull, STDERR_FILENO);
-       if (devnull > 2)
-               (void)close(devnull);
-
-       return 0;
-}
-
-/*
- * resolv_conf(5) says a max of DHCP_DOMAIN_SEARCH_CNT domains and total
- * length of DHCP_DOMAIN_SEARCH_LEN bytes are acceptable for the 'search'
- * statement.
- */
-int
-res_hnok_list(const char *names)
-{
-       char    *dupnames, *hn, *inputstring;
-       int      count;
-
-       if (strlen(names) >= DHCP_DOMAIN_SEARCH_LEN)
-               return 0;
-
-       dupnames = inputstring = strdup(names);
-       if (inputstring == NULL)
-               fatal("domain name list");
-
-       count = 0;
-       while ((hn = strsep(&inputstring, " \t")) != NULL) {
-               if (strlen(hn) == 0)
-                       continue;
-               if (res_hnok(hn) == 0)
-                       break;
-               count++;
-               if (count > DHCP_DOMAIN_SEARCH_CNT)
-                       break;
-       }
-
-       free(dupnames);
-
-       return count > 0 && count < 7 && hn == NULL;
-}
-
-/*
- * Decode a byte string encoding a list of domain names as specified in RFC1035
- * section 4.1.4.
- *
- * The result is a string consisting of a blank separated list of domain names.
- *
- * e.g.
- *
- * 3:65:6e:67:5:61:70:70:6c:65:3:63:6f:6d:0:9:6d:61:72:6b:65:74:69:6e:67:c0:04
- *
- * which represents
- *
- *    3 |'e'|'n'|'g'| 5 |'a'|'p'|'p'|'l'|
- *   'e'| 3 |'c'|'o'|'m'| 0 | 9 |'m'|'a'|
- *   'r'|'k'|'e'|'t'|'i'|'n'|'g'|xC0|x04|
- *
- * will be translated to
- *
- * "eng.apple.com. marketing.apple.com."
- */
-char *
-rfc1035_as_string(unsigned char *src, size_t srclen)
-{
-       static char              search[DHCP_DOMAIN_SEARCH_LEN];
-       unsigned char            name[DHCP_DOMAIN_SEARCH_LEN];
-       unsigned char           *endsrc, *cp;
-       int                      len, domains;
-
-       memset(search, 0, sizeof(search));
-
-       /* Compute expanded length. */
-       domains = 0;
-       cp = src;
-       endsrc = src + srclen;
-
-       while (cp < endsrc && domains < DHCP_DOMAIN_SEARCH_CNT) {
-               len = dn_expand(src, endsrc, cp, name, sizeof(name));
-               if (len == -1)
-                       goto bad;
-               cp += len;
-               if (domains > 0)
-                       strlcat(search, " ", sizeof(search));
-               strlcat(search, name, sizeof(search));
-               if (strlcat(search, ".", sizeof(search)) >= sizeof(search))
-                       goto bad;
-               domains++;
-       }
-
-       return search;
-
-bad:
-       memset(search, 0, sizeof(search));
-       return search;
-}
-
-void
-fork_privchld(struct interface_info *ifi, int fd, int fd2)
-{
-       struct pollfd    pfd[1];
-       struct imsgbuf  *priv_ibuf;
-       ssize_t          n;
-       int              ioctlfd, routefd, nfds, rslt;
-
-       switch (fork()) {
-       case -1:
-               fatal("fork");
-               break;
-       case 0:
-               break;
-       default:
-               return;
-       }
-
-       if (chdir("/") == -1)
-               fatal("chdir(\"/\")");
-
-       go_daemon();
-
-       free(log_procname);
-       rslt = asprintf(&log_procname, "%s [priv]", ifi->name);
-       if (rslt == -1)
-               fatal("log_procname");
-       setproctitle("%s", log_procname);
-       log_procinit(log_procname);
-
-       close(fd2);
-
-       if ((priv_ibuf = malloc(sizeof(*priv_ibuf))) == NULL)
-               fatal("priv_ibuf");
-
-       imsg_init(priv_ibuf, fd);
-
-       if ((ioctlfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
-               fatal("socket(AF_INET, SOCK_DGRAM)");
-       if ((routefd = socket(AF_ROUTE, SOCK_RAW, 0)) == -1)
-               fatal("socket(AF_ROUTE, SOCK_RAW)");
-
-       if (unveil(_PATH_RESCONF, "wc") == -1)
-               fatal("unveil %s", _PATH_RESCONF);
-       if (unveil("/etc/resolv.conf.tail", "r") == -1)
-               fatal("unveil /etc/resolve.conf.tail");
-       if (unveil(NULL, NULL) == -1)
-               fatal("unveil");
-
-       while (quit == 0) {
-               pfd[0].fd = priv_ibuf->fd;
-               pfd[0].events = POLLIN;
-
-               nfds = ppoll(pfd, 1, NULL, NULL);
-               if (nfds == -1) {
-                       if (errno == EINTR)
-                               continue;
-                       log_warn("%s: ppoll(priv_ibuf)", log_procname);
-                       break;
-               }
-               if ((pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL)) != 0)
-                       break;
-               if (nfds == 0 || (pfd[0].revents & POLLIN) == 0)
-                       continue;
-
-               if ((n = imsg_read(priv_ibuf)) == -1 && errno != EAGAIN) {
-                       log_warn("%s: imsg_read(priv_ibuf)", log_procname);
-                       break;
-               }
-               if (n == 0) {
-                       /* Connection closed - other end should log message. */
-                       break;
-               }
-
-               dispatch_imsg(ifi->name, ifi->rdomain, ioctlfd, routefd,
-                   priv_ibuf);
-       }
-       close(routefd);
-       close(ioctlfd);
-
-       imsg_clear(priv_ibuf);
-       close(fd);
-
-       exit(1);
-}
-
-struct client_lease *
-apply_defaults(struct client_lease *lease)
-{
-       struct option_data       emptyopt = {0, NULL};
-       struct client_lease     *newlease;
-       char                    *fmt;
-       int                      i;
-
-       newlease = clone_lease(lease);
-       if (newlease == NULL)
-               fatalx("unable to clone lease");
-
-       if (config->filename != NULL) {
-               free(newlease->filename);
-               newlease->filename = strdup(config->filename);
-               if (newlease->filename == NULL)
-                       fatal("strdup(config->filename)");
-       }
-       if (config->server_name != NULL) {
-               free(newlease->server_name);
-               newlease->server_name = strdup(config->server_name);
-               if (newlease->server_name == NULL)
-                       fatal("strdup(config->server_name)");
-       }
-       if (config->address.s_addr != INADDR_ANY)
-               newlease->address.s_addr = config->address.s_addr;
-       if (config->next_server.s_addr != INADDR_ANY)
-               newlease->next_server.s_addr = config->next_server.s_addr;
-
-       for (i = 0; i < DHO_COUNT; i++) {
-               fmt = code_to_format(i);
-               switch (config->default_actions[i]) {
-               case ACTION_IGNORE:
-                       merge_option_data(fmt, &emptyopt, &emptyopt,
-                           &newlease->options[i]);
-                       break;
-
-               case ACTION_SUPERSEDE:
-                       merge_option_data(fmt, &config->defaults[i], &emptyopt,
-                           &newlease->options[i]);
-                       break;
-
-               case ACTION_PREPEND:
-                       merge_option_data(fmt, &config->defaults[i],
-                           &lease->options[i], &newlease->options[i]);
-                       break;
-
-               case ACTION_APPEND:
-                       merge_option_data(fmt, &lease->options[i],
-                           &config->defaults[i], &newlease->options[i]);
-                       break;
-
-               case ACTION_DEFAULT:
-                       if (newlease->options[i].len == 0)
-                               merge_option_data(fmt, &config->defaults[i],
-                                   &emptyopt, &newlease->options[i]);
-                       break;
-
-               default:
-                       break;
-               }
-       }
-
-       if (newlease->options[DHO_STATIC_ROUTES].len != 0) {
-               log_debug("%s: DHO_STATIC_ROUTES (option 33) not supported",
-                   log_procname);
-               free(newlease->options[DHO_STATIC_ROUTES].data);
-               newlease->options[DHO_STATIC_ROUTES].data = NULL;
-               newlease->options[DHO_STATIC_ROUTES].len = 0;
-       }
-
-       /*
-        * RFC 3442 says client *MUST* ignore DHO_ROUTERS
-        * when DHO_CLASSLESS_[MS_]_ROUTES present.
-        */
-       if ((newlease->options[DHO_CLASSLESS_MS_STATIC_ROUTES].len != 0) ||
-           (newlease->options[DHO_CLASSLESS_STATIC_ROUTES].len != 0)) {
-               free(newlease->options[DHO_ROUTERS].data);
-               newlease->options[DHO_ROUTERS].data = NULL;
-               newlease->options[DHO_ROUTERS].len = 0;
-       }
-
-       return newlease;
-}
-
-struct client_lease *
-clone_lease(struct client_lease *oldlease)
-{
-       struct client_lease     *newlease;
-       int                      i;
-
-       newlease = calloc(1, sizeof(*newlease));
-       if (newlease == NULL)
-               goto cleanup;
-
-       newlease->epoch = oldlease->epoch;
-       newlease->address = oldlease->address;
-       newlease->next_server = oldlease->next_server;
-       memcpy(newlease->ssid, oldlease->ssid, sizeof(newlease->ssid));
-       newlease->ssid_len = oldlease->ssid_len;
-
-       if (oldlease->server_name != NULL) {
-               newlease->server_name = strdup(oldlease->server_name);
-               if (newlease->server_name == NULL)
-                       goto cleanup;
-       }
-       if (oldlease->filename != NULL) {
-               newlease->filename = strdup(oldlease->filename);
-               if (newlease->filename == NULL)
-                       goto cleanup;
-       }
-
-       for (i = 0; i < DHO_COUNT; i++) {
-               if (oldlease->options[i].len == 0)
-                       continue;
-               newlease->options[i].len = oldlease->options[i].len;
-               newlease->options[i].data = calloc(1,
-                   newlease->options[i].len);
-               if (newlease->options[i].data == NULL)
-                       goto cleanup;
-               memcpy(newlease->options[i].data, oldlease->options[i].data,
-                   newlease->options[i].len);
-       }
-
-       return newlease;
-
-cleanup:
-       free_client_lease(newlease);
-
-       return NULL;
-}
-
-int
-autoconf(struct interface_info *ifi)
-{
-       struct ifreq            ifr;
-       int                     ioctlfd;
-
-       if ((ioctlfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
-               fatal("socket(AF_INET, SOCK_DGRAM)");
-
-       memset(&ifr, 0, sizeof(ifr));
-       strlcpy(ifr.ifr_name, ifi->name, sizeof(ifr.ifr_name));
-
-       if (ioctl(ioctlfd, SIOCGIFXFLAGS, (caddr_t)&ifr) < 0)
-               fatal("SIOGIFXFLAGS");
-
-       close(ioctlfd);
-
-       return ifr.ifr_flags & IFXF_AUTOCONF4;
-}
-
-int
-take_charge(struct interface_info *ifi, int routefd, char *leasespath)
-{
-       const struct timespec    max_timeout = { 9, 0 };
-       const struct timespec    resend_intvl = { 3, 0 };
-       const struct timespec    leasefile_intvl = { 0, 3000000 };
-       struct timespec          now, resend, stop, timeout;
-       struct pollfd            fds[1];
-       struct rt_msghdr         rtm;
-       int                      fd, nfds;
-
-       clock_gettime(CLOCK_MONOTONIC, &now);
-       resend = now;
-       timespecadd(&now, &max_timeout, &stop);
-
-       /*
-        * Send RTM_PROPOSAL with RTF_PROTO3 set.
-        *
-        * When it comes back, we're in charge and other dhclients are
-        * dead processes walking.
-        */
-       memset(&rtm, 0, sizeof(rtm));
-
-       rtm.rtm_version = RTM_VERSION;
-       rtm.rtm_type = RTM_PROPOSAL;
-       rtm.rtm_msglen = sizeof(rtm);
-       rtm.rtm_tableid = ifi->rdomain;
-       rtm.rtm_index = ifi->index;
-       rtm.rtm_priority = RTP_PROPOSAL_DHCLIENT;
-       rtm.rtm_addrs = 0;
-       rtm.rtm_flags = RTF_UP | RTF_PROTO3;
-
-       for (fd = -1; fd == -1 && quit != TERMINATE;) {
-               clock_gettime(CLOCK_MONOTONIC, &now);
-               if (timespeccmp(&now, &stop, >=))
-                       fatalx("failed to take charge");
-
-               if ((ifi->flags & IFI_IN_CHARGE) == 0) {
-                       if (timespeccmp(&now, &resend, >=)) {
-                               timespecadd(&resend, &resend_intvl, &resend);
-                               rtm.rtm_seq = ifi->xid = arc4random();
-                               if (write(routefd, &rtm, sizeof(rtm)) == -1)
-                                       fatal("write(routefd)");
-                       }
-                       timespecsub(&resend, &now, &timeout);
-               } else {
-                       /*
-                        * Keep trying to open leasefile in 3ms intervals
-                        * while continuing to process any RTM_* messages
-                        * that come in.
-                        */
-                        timeout = leasefile_intvl;
-               }
-
-               fds[0].fd = routefd;
-               fds[0].events = POLLIN;
-               nfds = ppoll(fds, 1, &timeout, NULL);
-               if (nfds == -1) {
-                       if (errno == EINTR)
-                               continue;
-                       fatal("ppoll(routefd)");
-               }
-
-               if ((fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) != 0)
-                       fatalx("routefd: ERR|HUP|NVAL");
-               if (nfds == 1 && (fds[0].revents & POLLIN) == POLLIN)
-                       routefd_handler(ifi, routefd);
-
-               if (quit != TERMINATE && (ifi->flags & IFI_IN_CHARGE) == IFI_IN_CHARGE) {
-                       fd = open(leasespath, O_NONBLOCK |
-                           O_RDONLY|O_EXLOCK|O_CREAT|O_NOFOLLOW, 0640);
-                       if (fd == -1 && errno != EWOULDBLOCK)
-                               break;
-               }
-       }
-
-       return fd;
-}
-
-struct client_lease *
-get_recorded_lease(struct interface_info *ifi)
-{
-       char                     ifname[IF_NAMESIZE];
-       struct client_lease     *lp;
-       int                      i;
-
-       /* Update on-disk db, which clears out expired leases. */
-       ifi->active = NULL;
-       write_lease_db(ifi);
-
-       /* Run through the list of leases and see if one can be used. */
-       i = DHO_DHCP_CLIENT_IDENTIFIER;
-       TAILQ_FOREACH(lp, &ifi->lease_db, next) {
-               if (lp->ssid_len != ifi->ssid_len)
-                       continue;
-               if (memcmp(lp->ssid, ifi->ssid, lp->ssid_len) != 0)
-                       continue;
-               if ((lp->options[i].len != 0) && ((lp->options[i].len !=
-                   config->send_options[i].len) ||
-                   memcmp(lp->options[i].data, config->send_options[i].data,
-                   lp->options[i].len) != 0))
-                       continue;
-               if (addressinuse(ifi->name, lp->address, ifname) != 0 &&
-                   strncmp(ifname, ifi->name, IF_NAMESIZE) != 0)
-                       continue;
-               break;
-       }
-
-       return lp;
-}
-
-time_t
-lease_expiry(struct client_lease *lease)
-{
-       time_t          cur_time;
-       uint32_t        expiry;
-
-       time(&cur_time);
-       expiry = 0;
-       if (lease->options[DHO_DHCP_LEASE_TIME].len == sizeof(expiry)) {
-               memcpy(&expiry, lease->options[DHO_DHCP_LEASE_TIME].data,
-                   sizeof(expiry));
-               expiry = ntohl(expiry);
-               if (expiry < 60)
-                       expiry = 60;
-       }
-       expiry = lease->epoch + expiry - cur_time;
-
-       return (expiry > 0) ? expiry : 0;
-}
-
-time_t
-lease_renewal(struct client_lease *lease)
-{
-       time_t           cur_time, expiry;
-       uint32_t         renewal;
-
-       time(&cur_time);
-       expiry = lease_expiry(lease);
-
-       renewal = expiry / 2;
-       if (lease->options[DHO_DHCP_RENEWAL_TIME].len == sizeof(renewal)) {
-               memcpy(&renewal, lease->options[DHO_DHCP_RENEWAL_TIME].data,
-                   sizeof(renewal));
-               renewal = ntohl(renewal);
-       }
-       renewal = lease->epoch + renewal - cur_time;
-
-       return (renewal > 0) ? renewal : 0;
-}
-
-time_t
-lease_rebind(struct client_lease *lease)
-{
-       time_t          cur_time, expiry;
-       uint32_t        rebind;
-
-       time(&cur_time);
-       expiry = lease_expiry(lease);
-
-       rebind = (expiry / 8) * 7;
-       if (lease->options[DHO_DHCP_REBINDING_TIME].len == sizeof(rebind)) {
-               memcpy(&rebind, lease->options[DHO_DHCP_REBINDING_TIME].data,
-                   sizeof(rebind));
-               rebind = ntohl(rebind);
-       }
-       rebind = lease->epoch + rebind - cur_time;
-
-       return (rebind > 0) ? rebind : 0;
-}
-
-void
-get_lease_timeouts(struct interface_info *ifi, struct client_lease *lease)
-{
-       struct timespec now, interval;
-
-       clock_gettime(CLOCK_MONOTONIC, &now);
-       timespecclear(&interval);
-
-       interval.tv_sec = lease_expiry(lease);
-       timespecadd(&now, &interval, &ifi->expiry);
-
-       interval.tv_sec = lease_rebind(lease);
-       timespecadd(&now, &interval, &ifi->rebind);
-
-       interval.tv_sec = lease_renewal(lease);
-       timespecadd(&now, &interval, &ifi->renew);
-
-       if (timespeccmp(&ifi->rebind, &ifi->expiry, >))
-               ifi->rebind = ifi->expiry;
-       if (timespeccmp(&ifi->renew, &ifi->rebind, >))
-               ifi->renew = ifi->rebind;
-}
-
-void
-tick_msg(const char *preamble, int action)
-{
-       const struct timespec           grace_intvl = {3, 0};
-       const struct timespec           link_intvl = {config->link_interval, 0};
-       static struct timespec          grace, stop;
-       struct timespec                 now;
-       static int                      linkup, preamble_sent, sleeping;
-       int                             printmsg;
-
-       clock_gettime(CLOCK_MONOTONIC, &now);
-
-       if (!timespecisset(&stop)) {
-               preamble_sent = 0;
-               timespecadd(&now, &link_intvl, &stop);
-               timespecadd(&now, &grace_intvl, &grace);
-               return;
-       }
-
-       if (isatty(STDERR_FILENO) == 0 || sleeping == 1)
-               printmsg = 0;   /* Already in the background. */
-       else if (timespeccmp(&now, &grace, <))
-               printmsg = 0;   /* Wait a bit before speaking. */
-       else if (linkup && strcmp("link", preamble) == 0)
-               printmsg = 0;   /* One 'got link' is enough for anyone. */
-       else if (log_getverbose())
-               printmsg = 0;   /* Verbose has sufficent verbiage. */
-       else
-               printmsg = 1;
-
-       if (timespeccmp(&now, &stop, >=)) {
-               if (action == TICK_WAIT)
-                       action = TICK_DAEMON;
-               if (linkup == 0) {
-                       log_debug("%s: link timeout (%lld seconds) expired",
-                           log_procname, (long long)link_intvl.tv_sec);
-                       linkup = 1;
-               }
-       }
-
-       if (printmsg && preamble_sent == 0) {
-               fprintf(stderr, "%s: no %s...", log_procname, preamble);
-               preamble_sent = 1;
-       }
-
-       switch (action) {
-       case TICK_SUCCESS:
-               if (printmsg)
-                       fprintf(stderr, "got %s\n", preamble);
-               preamble_sent = 0;
-               if (strcmp("link", preamble) == 0) {
-                       linkup = 1;
-                       /* New silent period for "no lease ... got lease". */
-                       timespecadd(&now, &grace_intvl, &grace);
-               }
-               break;
-       case TICK_WAIT:
-               if (printmsg)
-                       fprintf(stderr, ".");
-               break;
-       case TICK_DAEMON:
-               if (printmsg)
-                       fprintf(stderr, "sleeping\n");
-               go_daemon();
-               sleeping = 1;   /* OPT_FOREGROUND means isatty() == 1! */
-               break;
-       default:
-               break;
-       }
-
-       if (printmsg)
-               fflush(stderr);
-}
-
-/*
- * Release the lease used to configure the interface.
- *
- * 1) Send DHCPRELEASE.
- * 2) Unconfigure address/routes/etc.
- * 3) Remove lease from database & write updated DB.
- */
-void
-release_lease(struct interface_info *ifi)
-{
-       char                     buf[INET_ADDRSTRLEN];
-       struct option_data      *opt;
-
-       if (ifi->configured == NULL || ifi->active == NULL)
-               return; /* Nothing to release. */
-       strlcpy(buf, inet_ntoa(ifi->configured->address), sizeof(buf));
-
-       opt = &ifi->active->options[DHO_DHCP_SERVER_IDENTIFIER];
-       if (opt->len == sizeof(in_addr_t))
-               ifi->destination.s_addr = *(in_addr_t *)opt->data;
-       else
-               ifi->destination.s_addr = INADDR_BROADCAST;
-
-       ifi->xid = arc4random();
-       make_release(ifi, ifi->active);
-       send_release(ifi);
-
-       tell_unwind(NULL, ifi->flags);
-
-       revoke_proposal(ifi->configured);
-       imsg_flush(unpriv_ibuf);
-
-       TAILQ_REMOVE(&ifi->lease_db, ifi->active, next);
-       free_client_lease(ifi->active);
-       ifi->active = NULL;
-       write_lease_db(ifi);
-
-       free(ifi->configured);
-       ifi->configured = NULL;
-       free(ifi->unwind_info);
-       ifi->unwind_info = NULL;
-
-       log_warnx("%s: %s RELEASED to %s", log_procname, buf,
-           inet_ntoa(ifi->destination));
-}
-
-void
-propose_release(struct interface_info *ifi)
-{
-       const struct timespec    max_timeout = { 3, 0 };
-       struct timespec          now, stop, timeout;
-       struct pollfd            fds[1];
-       struct rt_msghdr         rtm;
-       int                      nfds, routefd, rtfilter;
-
-       clock_gettime(CLOCK_MONOTONIC, &now);
-       timespecadd(&now, &max_timeout, &stop);
-
-       if ((routefd = socket(AF_ROUTE, SOCK_RAW, AF_INET)) == -1)
-               fatal("socket(AF_ROUTE, SOCK_RAW)");
-
-       rtfilter = ROUTE_FILTER(RTM_PROPOSAL);
-
-       if (setsockopt(routefd, AF_ROUTE, ROUTE_MSGFILTER,
-           &rtfilter, sizeof(rtfilter)) == -1)
-               fatal("setsockopt(ROUTE_MSGFILTER)");
-       if (setsockopt(routefd, AF_ROUTE, ROUTE_TABLEFILTER, &ifi->rdomain,
-           sizeof(ifi->rdomain)) == -1)
-               fatal("setsockopt(ROUTE_TABLEFILTER)");
-
-       memset(&rtm, 0, sizeof(rtm));
-       rtm.rtm_version = RTM_VERSION;
-       rtm.rtm_type = RTM_PROPOSAL;
-       rtm.rtm_msglen = sizeof(rtm);
-       rtm.rtm_tableid = ifi->rdomain;
-       rtm.rtm_index = ifi->index;
-       rtm.rtm_priority = RTP_PROPOSAL_DHCLIENT;
-       rtm.rtm_addrs = 0;
-       rtm.rtm_flags = RTF_UP;
-       rtm.rtm_flags |= RTF_PROTO2;
-       rtm.rtm_seq = ifi->xid = arc4random();
-
-       if (write(routefd, &rtm, sizeof(rtm)) == -1)
-               fatal("write(routefd)");
-       log_debug("%s: sent RTM_PROPOSAL to release lease", log_procname);
-
-       while (quit == 0) {
-               clock_gettime(CLOCK_MONOTONIC, &now);
-               if (timespeccmp(&now, &stop, >=))
-                       break;
-               timespecsub(&stop, &now, &timeout);
-               fds[0].fd = routefd;
-               fds[0].events = POLLIN;
-               nfds = ppoll(fds, 1, &timeout, NULL);
-               if (nfds == -1) {
-                       if (errno == EINTR)
-                               continue;
-                       fatal("ppoll(routefd)");
-               }
-               if ((fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) != 0)
-                       fatalx("routefd: ERR|HUP|NVAL");
-               if (nfds == 0 || (fds[0].revents & POLLIN) == 0)
-                       continue;
-               routefd_handler(ifi, routefd);
-       }
-}
diff --git a/sbin/dhclient/dhclient.conf.5 b/sbin/dhclient/dhclient.conf.5
deleted file mode 100644 (file)
index dcf1105..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-.\"    $OpenBSD: dhclient.conf.5,v 1.52 2022/03/31 17:27:19 naddy Exp $
-.\"
-.\" Copyright (c) 1997 The Internet Software Consortium.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\"
-.\" 1. Redistributions of source code must retain the above copyright
-.\"    notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\"    notice, this list of conditions and the following disclaimer in the
-.\"    documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of The Internet Software Consortium nor the names
-.\"    of its contributors may be used to endorse or promote products derived
-.\"    from this software without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
-.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
-.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-.\" DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
-.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" This software has been written for the Internet Software Consortium
-.\" by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
-.\" Enterprises.  To learn more about the Internet Software Consortium,
-.\" see ``http://www.isc.org/isc''.  To learn more about Vixie
-.\" Enterprises, see ``http://www.vix.com''.
-.\"
-.Dd $Mdocdate: March 31 2022 $
-.Dt DHCLIENT.CONF 5
-.Os
-.Sh NAME
-.Nm dhclient.conf
-.Nd DHCP client configuration file
-.Sh DESCRIPTION
-.Nm
-is the configuration file for
-.Xr dhclient 8 .
-It is a free-form ASCII text file made up of declarations, extra
-tabs and newlines for formatting purposes and comments.
-Keywords in the file are case-insensitive.
-Comments begin with the
-.Sq #
-character and extend to the end of the current line.
-.Sh PROTOCOL TIMING DECLARATIONS
-.Bl -tag -width Ds
-.It Ic backoff-cutoff Ar seconds ;
-Sets the maximum number of seconds to
-wait before retransmitting a packet.
-The default is 10 seconds.
-.It Ic initial-interval Ar seconds ;
-Sets the number of seconds between the first packet transmission
-and the first retransmission of the packet.
-The default is 1 second.
-.It Ic link-timeout Ar seconds ;
-Sets the number of seconds
-to wait for a lease before going into the background as a daemon.
-The default is 10 seconds.
-.It Ic reboot Ar seconds ;
-Sets the number of seconds to wait
-before giving up on reacquiring the previous lease, and how long
-to attempt unicast renewal requests before falling back to broadcast
-renewal requests.
-The default is 1 second.
-.It Ic retry Ar seconds ;
-Sets the number of seconds to wait before starting a new attempt to
-obtain a lease.
-The default is 1 second.
-.It Ic select-timeout Ar seconds ;
-Sets the number of seconds to wait for additional leases after the
-first lease arrives.
-After
-.Ic select-timeout
-seconds the best lease received will be selected.
-The default is 0 seconds, i.e. immediately use
-the first acceptable lease received.
-.It Ic timeout Ar seconds ;
-Sets the number of seconds to wait for a lease.
-If no lease is received, the first valid lease in
-.Xr dhclient.leases 5
-will be used.
-The default is 30 seconds.
-.El
-.Sh DHCP OPTION DECLARATIONS
-.Bl -tag -width Ds
-.It Ic append Ar option option-value ;
-Append
-.Ar option-value
-to the value of
-.Ar option
-in the lease.
-Each
-.Ic append
-for
-.Ar option
-overrides any previous
-.Ic append ,
-.Ic default ,
-.Ic ignore ,
-.Ic prepend
-or
-.Ic supersede
-for
-.Ar option .
-.Pp
-If the option's data cannot be appended to, i.e. it has a fixed size,
-then
-.Ic append
-will be treated as
-.Ic default .
-.It Ic default Ar option option-value ;
-If no value for
-.Ar option
-is present in the lease, use
-.Ar option-value .
-Each
-.Ic default
-for
-.Ar option
-overrides any previous
-.Ic append ,
-.Ic default ,
-.Ic ignore ,
-.Ic prepend
-or
-.Ic supersede
-for
-.Ar option .
-.It Ic ignore Op Ar option , ... ;
-Discard values provided for the listed options.
-.Ic ignore
-statements are cumulative, except that an empty
-list will remove all previously specified options.
-Each
-.Ic ignore
-for
-.Ar option
-overrides any previous
-.Ic append ,
-.Ic default ,
-.Ic prepend
-or
-.Ic supersede
-for
-.Ar option .
-.It Ic prepend Ar option option-value ;
-Prepend
-.Ar option-value
-to the value of
-.Ar option
-in the lease.
-Each
-.Ic prepend
-for
-.Ar option
-overrides any previous
-.Ic append ,
-.Ic default ,
-.Ic ignore ,
-.Ic prepend
-or
-.Ic supersede
-for
-.Ar option .
-.Pp
-If the option's data cannot be prepended to, i.e. it has a fixed size,
-then
-.Ic prepend
-will be treated as
-.Ic supersede .
-.It Ic request Op Ar option , ... ;
-Ask that any lease contain values
-for the listed options.
-.Ic request
-statements are cumulative, except that an empty
-list will remove all previously specified options.
-The default is to request the options
-bootfile-name,
-broadcast-address,
-classless-static-routes,
-host-name,
-domain-name,
-domain-name-servers,
-domain-search,
-routers,
-subnet-mask,
-tftp-server-name
-and
-time-offset.
-.It Ic require Op Ar option , ... ;
-Discard leases that do not contain the listed options.
-.Ic require
-statements are cumulative, except that an empty
-list will remove all previously specified options.
-The default is to require the option subnet-mask.
-.It Ic send Ar option option-value ;
-Include
-.Ar option-value
-in requests for a lease.
-To include multiple options in requests,
-.Ic send
-can be used multiple times.
-.It Ic supersede Ar option option-value ;
-Use
-.Ar option-value
-for the given
-.Ar option
-regardless of the value in the lease.
-Each
-.Ic supersede
-for
-.Ar option
-overrides any previous
-.Ic append ,
-.Ic default ,
-.Ic ignore ,
-.Ic prepend
-or
-.Ic supersede
-for
-.Ar option .
-.It Ic uselease Op Ar option , ... ;
-Use the unmodified values provided in the lease for
-any specified
-.Ar option .
-.Ic uselease
-statements are cumulative.
-If no
-.Ar option
-is specified, all lease option values will be used unmodified.
-.Ic uselease
-for
-.Ar option
-overrides any previous
-.Ic append ,
-.Ic default ,
-.Ic ignore ,
-.Ic prepend
-or
-.Ic supersede
-for
-.Ar option .
-.El
-.Sh OTHER DECLARATIONS
-.Bl -tag -width Ds
-.It Ic filename Ar path ;
-Use
-.Ar path
-instead of the
-.Ic file
-field of the DHCP offer when binding a lease.
-.It Ic fixed-address Ar ip-address ;
-Use
-.Ar ip-address
-instead of the
-.Ic yiaddr
-field of the DHCP offer when binding a lease.
-.It Ic interface Qo Ar name Qc No { Ar declaration ; ... ; No }
-Apply any
-.Ar declaration
-only to the named interface.
-.It Ic reject Ar ip-address ;
-Discard leases from the specified address.
-If more than one
-.Ic reject
-is present, all leases from any of the
-addresses will be discarded.
-.It Ic next-server Ar ip-address ;
-Use
-.Ar ip-address
-instead of the
-.Ic siaddr
-field of the DHCP offer when binding a lease.
-.It Ic server-name Ar host ;
-Use
-.Ar host
-instead of the
-.Ic sname
-field of the DHCP offer when binding a lease.
-.El
-.Sh FILES
-.Bl -tag -width /etc/examples/dhclient.conf -compact
-.It Pa /etc/dhclient.conf
-.It Pa /etc/examples/dhclient.conf
-.El
-.Sh SEE ALSO
-.Xr dhclient.leases 5 ,
-.Xr dhcp-options 5 ,
-.Xr dhcpd.conf 5 ,
-.Xr dhclient 8 ,
-.Xr dhcpd 8
diff --git a/sbin/dhclient/dhclient.leases.5 b/sbin/dhclient/dhclient.leases.5
deleted file mode 100644 (file)
index 782f71f..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-.\"    $OpenBSD: dhclient.leases.5,v 1.14 2017/12/18 14:17:58 krw Exp $
-.\"
-.\" Copyright (c) 1997 The Internet Software Consortium.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\"
-.\" 1. Redistributions of source code must retain the above copyright
-.\"    notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\"    notice, this list of conditions and the following disclaimer in the
-.\"    documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of The Internet Software Consortium nor the names
-.\"    of its contributors may be used to endorse or promote products derived
-.\"    from this software without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
-.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
-.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-.\" DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
-.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" This software has been written for the Internet Software Consortium
-.\" by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
-.\" Enterprises.  To learn more about the Internet Software Consortium,
-.\" see ``http://www.isc.org/isc''.  To learn more about Vixie
-.\" Enterprises, see ``http://www.vix.com''.
-.\"
-.Dd $Mdocdate: December 18 2017 $
-.Dt DHCLIENT.LEASES 5
-.Os
-.Sh NAME
-.Nm dhclient.leases
-.Nd DHCP client lease database
-.Sh DESCRIPTION
-.Xr dhclient 8
-keeps a persistent database of leases that it has acquired that are still
-valid.
-The database is a free-form ASCII file containing one valid declaration
-per lease.
-The file is written as a log, so the last declaration is the most recent
-lease obtained.
-.Pp
-The lease file is named
-.Pa /var/db/dhclient.leases . Ns Aq Ar IFNAME ,
-where
-.Qq IFNAME
-represents the network interface
-.Xr dhclient 8
-acquired the lease on.
-For example, if
-.Xr dhclient 8
-is configured for the em0 network device,
-the lease file will be named
-.Pa /var/db/dhclient.leases.em0 ,
-.Pp
-A lease statement has the format
-.Pp
-.D1 Ic lease No { Ar lease-declaration ; ... ; No }
-.Pp
-Where
-.Ar lease\-declaration
-is one of:
-.Pp
-.Bl -tag -width Ds -compact
-.It Ic bootp
-The lease was acquired using the
-BOOTP protocol rather than the DHCP protocol.
-.Pp
-.It Ic epoch
-The
-.Xr time 3
-when the lease was obtained.
-This value is used to convert the values of the DHCP options
-.Ic dhcp-lease-time ,
-.Ic dhcp-renewal-time ,
-and
-.Ic dhcp-rebinding-time
-to times.
-A value of 0 will cause
-.Ic epoch
-to be set to the current time when
-.Nm
-is processed.
-.Pp
-.It Ic expire Ar date
-.It Ic rebind Ar date
-.It Ic renew Ar date
-.Ic expire
-is when
-.Xr dhclient 8
-will no longer use the lease to configure the interface.
-.Ic rebind
-is when
-.Xr dhclient 8
-will begin trying to renew the lease with broadcasts to any server.
-.Ic renew
-is when
-.Xr dhclient 8
-will begin trying to renew the lease with unicasts to the originating server.
-.Pp
-Dates are specified in accordance with the
-.Xr strptime 3
-format:
-.Pp
-.D1 %w %Y/%m/%d \&%T UTC
-.Pp
-For example:
-.Pp
-.Dl renew 1 2017/10/16 14:03:49 UTC
-.Pp
-.Ic expire ,
-.Ic rebind ,
-.Ic renew
-are just comments that are ignored when processing
-.Nm .
-The values used by
-.Xr dhclient 8
-are always recalculated based on
-.Ic epoch
-when
-.Nm
-is processed.
-.Pp
-.It Ic filename Qq Ar string
-The boot filename.
-.Pp
-.It Ic fixed-address Ar ip-address
-The IPv4 address of the lease.
-This is required for all lease statements.
-The IPv4 address is specified as a dotted quad (e.g. 12.34.56.78).
-.Pp
-.It Ic next-server Ar ip-address
-The IPv4 address of the boot server.
-The IPv4 address is specified as a dotted quad (e.g. 12.34.56.78).
-.Pp
-.It Ic option Ar option option-value
-The value of
-.Ar option .
-DHCP options are described in
-.Xr dhcp-options 5 .
-.Pp
-.It Ic server-name Qq Ar string
-The name of the boot server.
-.Pp
-.It Ic ssid Qq Ar string
-The SSID to which the lease applies.
-.El
-.Sh FILES
-.Bl -tag -width "/var/db/dhclient.leases.IFNAME   "
-.It Pa /var/db/dhclient.leases . Ns Aq Ar IFNAME
-Persistent database of leases for
-.Aq Ar IFNAME .
-.El
-.Sh SEE ALSO
-.Xr dhclient.conf 5 ,
-.Xr dhcp-options 5 ,
-.Xr dhcpd.conf 5 ,
-.Xr dhclient 8 ,
-.Xr dhcpd 8
diff --git a/sbin/dhclient/dhcp.h b/sbin/dhclient/dhcp.h
deleted file mode 100644 (file)
index 644b9e4..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-/*     $OpenBSD: dhcp.h,v 1.21 2017/07/24 16:17:35 krw Exp $   */
-
-/* Protocol structures. */
-
-/*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#define DHCP_UDP_OVERHEAD      (20 + /* IP header */           \
-                                8)   /* UDP header */
-#define DHCP_SNAME_LEN         64
-#define DHCP_FILE_LEN          128
-#define DHCP_FIXED_NON_UDP     236
-#define DHCP_FIXED_LEN         (DHCP_FIXED_NON_UDP + DHCP_UDP_OVERHEAD)
-                                               /* Everything but options. */
-#define DHCP_MTU_MAX           1500
-#define DHCP_OPTION_LEN                (DHCP_MTU_MAX - DHCP_FIXED_LEN)
-
-/* Respect historical limits on 'search' line in resolv.conf(5) */
-#define DHCP_DOMAIN_SEARCH_LEN 1024
-#define DHCP_DOMAIN_SEARCH_CNT 6
-
-#define BOOTP_MIN_LEN          300
-
-struct dhcp_packet {
-       uint8_t         op;     /* Message opcode/type */
-       uint8_t         htype;  /* Hardware addr type (see net/if_types.h) */
-       uint8_t         hlen;   /* Hardware addr length */
-       uint8_t         hops;   /* Number of relay agent hops from client */
-       uint32_t        xid;    /* Transaction ID */
-       uint16_t        secs;   /* Seconds since client started looking */
-       uint16_t        flags;  /* Flag bits */
-       struct in_addr  ciaddr; /* Client IP address (if already in use) */
-       struct in_addr  yiaddr; /* Client IP address */
-       struct in_addr  siaddr; /* IP address of next server to talk to */
-       struct in_addr  giaddr; /* DHCP relay agent IP address */
-       unsigned char   chaddr[16];             /* Client hardware address */
-       char            sname[DHCP_SNAME_LEN];  /* Server name */
-       char            file[DHCP_FILE_LEN];    /* Boot filename */
-       unsigned char   options[DHCP_OPTION_LEN];
-                               /* Optional parameters
-                                  (actual length dependent on MTU). */
-};
-
-/* BOOTP (rfc951) message types */
-#define BOOTREQUEST    1
-#define BOOTREPLY      2
-
-/* Possible values for flags field. */
-#define BOOTP_BROADCAST 32768L
-
-/* Possible values for hardware type (htype) field. */
-#define HTYPE_ETHER            1       /* Ethernet                     */
-#define HTYPE_IPSEC_TUNNEL     31      /* IPsec Tunnel (RFC3456)       */
-
-/*
- * Magic cookie validating dhcp options field (and bootp vendor
- * extensions field).
- */
-#define DHCP_OPTIONS_COOKIE            "\143\202\123\143"
-#define DHCP_OPTIONS_COOKIE_LEN                4
-#define DHCP_OPTIONS_MESSAGE_TYPE      "\065\001\000"
-
-/* DHCP Option codes: */
-#define DHO_PAD                                0
-#define DHO_SUBNET_MASK                        1
-#define DHO_TIME_OFFSET                        2
-#define DHO_ROUTERS                    3
-#define DHO_TIME_SERVERS               4
-#define DHO_NAME_SERVERS               5
-#define DHO_DOMAIN_NAME_SERVERS                6
-#define DHO_LOG_SERVERS                        7
-#define DHO_COOKIE_SERVERS             8
-#define DHO_LPR_SERVERS                        9
-#define DHO_IMPRESS_SERVERS            10
-#define DHO_RESOURCE_LOCATION_SERVERS  11
-#define DHO_HOST_NAME                  12
-#define DHO_BOOT_SIZE                  13
-#define DHO_MERIT_DUMP                 14
-#define DHO_DOMAIN_NAME                        15
-#define DHO_SWAP_SERVER                        16
-#define DHO_ROOT_PATH                  17
-#define DHO_EXTENSIONS_PATH            18
-#define DHO_IP_FORWARDING              19
-#define DHO_NON_LOCAL_SOURCE_ROUTING   20
-#define DHO_POLICY_FILTER              21
-#define DHO_MAX_DGRAM_REASSEMBLY       22
-#define DHO_DEFAULT_IP_TTL             23
-#define DHO_PATH_MTU_AGING_TIMEOUT     24
-#define DHO_PATH_MTU_PLATEAU_TABLE     25
-#define DHO_INTERFACE_MTU              26
-#define DHO_ALL_SUBNETS_LOCAL          27
-#define DHO_BROADCAST_ADDRESS          28
-#define DHO_PERFORM_MASK_DISCOVERY     29
-#define DHO_MASK_SUPPLIER              30
-#define DHO_ROUTER_DISCOVERY           31
-#define DHO_ROUTER_SOLICITATION_ADDRESS        32
-#define DHO_STATIC_ROUTES              33
-#define DHO_TRAILER_ENCAPSULATION      34
-#define DHO_ARP_CACHE_TIMEOUT          35
-#define DHO_IEEE802_3_ENCAPSULATION    36
-#define DHO_DEFAULT_TCP_TTL            37
-#define DHO_TCP_KEEPALIVE_INTERVAL     38
-#define DHO_TCP_KEEPALIVE_GARBAGE      39
-#define DHO_NIS_DOMAIN                 40
-#define DHO_NIS_SERVERS                        41
-#define DHO_NTP_SERVERS                        42
-#define DHO_VENDOR_ENCAPSULATED_OPTIONS        43
-#define DHO_NETBIOS_NAME_SERVERS       44
-#define DHO_NETBIOS_DD_SERVER          45
-#define DHO_NETBIOS_NODE_TYPE          46
-#define DHO_NETBIOS_SCOPE              47
-#define DHO_FONT_SERVERS               48
-#define DHO_X_DISPLAY_MANAGER          49
-#define DHO_DHCP_REQUESTED_ADDRESS     50
-#define DHO_DHCP_LEASE_TIME            51
-#define DHO_DHCP_OPTION_OVERLOAD       52
-#define DHO_DHCP_MESSAGE_TYPE          53
-#define DHO_DHCP_SERVER_IDENTIFIER     54
-#define DHO_DHCP_PARAMETER_REQUEST_LIST        55
-#define DHO_DHCP_MESSAGE               56
-#define DHO_DHCP_MAX_MESSAGE_SIZE      57
-#define DHO_DHCP_RENEWAL_TIME          58
-#define DHO_DHCP_REBINDING_TIME                59
-#define DHO_DHCP_CLASS_IDENTIFIER      60
-#define DHO_DHCP_CLIENT_IDENTIFIER     61
-#define DHO_NISPLUS_DOMAIN             64
-#define DHO_NISPLUS_SERVERS            65
-#define DHO_TFTP_SERVER                        66
-#define DHO_BOOTFILE_NAME              67
-#define DHO_MOBILE_IP_HOME_AGENT       68
-#define DHO_SMTP_SERVER                        69
-#define DHO_POP_SERVER                 70
-#define DHO_NNTP_SERVER                        71
-#define DHO_WWW_SERVER                 72
-#define DHO_FINGER_SERVER              73
-#define DHO_IRC_SERVER                 74
-#define DHO_STREETTALK_SERVER          75
-#define DHO_STREETTALK_DIRECTORY_ASSISTANCE_SERVER     76
-#define DHO_DHCP_USER_CLASS_ID         77
-#define DHO_RELAY_AGENT_INFORMATION    82
-#define DHO_NDS_SERVERS                        85
-#define DHO_NDS_TREE_NAME              86
-#define DHO_NDS_CONTEXT                        87
-#define        DHO_DOMAIN_SEARCH               119
-#define DHO_CLASSLESS_STATIC_ROUTES    121
-#define DHO_TFTP_CONFIG_FILE           144
-#define DHO_VOIP_CONFIGURATION_SERVER  150
-#define DHO_CLASSLESS_MS_STATIC_ROUTES 249
-#define DHO_AUTOPROXY_SCRIPT           252
-#define DHO_END                                255
-#define DHO_COUNT                      256     /* # of DHCP options */
-
-/* DHCP message types. */
-#define DHCPDISCOVER   1
-#define DHCPOFFER      2
-#define DHCPREQUEST    3
-#define DHCPDECLINE    4
-#define DHCPACK                5
-#define DHCPNAK                6
-#define DHCPRELEASE    7
-#define DHCPINFORM     8
-
-/* Relay Agent Information sub-options */
-#define RAI_CIRCUIT_ID 1
-#define RAI_REMOTE_ID  2
-#define RAI_AGENT_ID   3
diff --git a/sbin/dhclient/dhcpd.h b/sbin/dhclient/dhcpd.h
deleted file mode 100644 (file)
index f0dd252..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-/*     $OpenBSD: dhcpd.h,v 1.299 2021/03/28 16:23:05 krw Exp $ */
-
-/*
- * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
- * Copyright (c) 1995, 1996, 1997, 1998, 1999
- * The Internet Software Consortium.    All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#define        LOCAL_PORT      68
-#define        REMOTE_PORT     67
-#define        TERMINATE       1
-#define        RESTART         2
-#define DB_TIMEFMT     "%w %Y/%m/%d %T UTC"
-#define        RT_BUF_SIZE     2048
-
-struct option_data {
-       unsigned int     len;
-       uint8_t         *data;
-};
-
-struct reject_elem {
-       TAILQ_ENTRY(reject_elem) next;
-       struct in_addr           addr;
-};
-
-struct client_lease {
-       TAILQ_ENTRY(client_lease) next;
-       time_t                   epoch;
-       struct in_addr           address;
-       struct in_addr           next_server;
-       char                    *server_name;
-       char                    *filename;
-       char                     ssid[32];
-       uint8_t                  ssid_len;
-       struct option_data       options[DHO_COUNT];
-};
-#define BOOTP_LEASE(l) ((l)->options[DHO_DHCP_MESSAGE_TYPE].len == 0)
-
-/* Possible states in which the client can be. */
-enum dhcp_state {
-       S_PREBOOT,
-       S_REBOOTING,
-       S_INIT,
-       S_SELECTING,
-       S_REQUESTING,
-       S_BOUND,
-       S_RENEWING
-};
-
-enum actions {
-       ACTION_USELEASE,
-       ACTION_DEFAULT,
-       ACTION_SUPERSEDE,
-       ACTION_PREPEND,
-       ACTION_APPEND,
-       ACTION_IGNORE
-};
-
-TAILQ_HEAD(client_lease_tq, client_lease);
-
-struct client_config {
-       struct option_data       defaults[DHO_COUNT];
-       enum actions             default_actions[DHO_COUNT];
-       struct in_addr           address;
-       struct in_addr           next_server;
-       struct option_data       send_options[DHO_COUNT];
-       uint8_t                  required_options[DHO_COUNT];
-       uint8_t                  requested_options[DHO_COUNT];
-       int                      requested_option_count;
-       int                      required_option_count;
-       time_t                   offer_interval;
-       time_t                   initial_interval;
-       time_t                   link_interval;
-       time_t                   retry_interval;
-       time_t                   select_interval;
-       time_t                   reboot_interval;
-       time_t                   backoff_cutoff;
-       TAILQ_HEAD(, reject_elem) reject_list;
-       char                    *filename;
-       char                    *server_name;
-};
-
-
-struct interface_info {
-       struct ether_addr        hw_address;
-       char                     name[IFNAMSIZ];
-       char                     ssid[32];
-       uint8_t                  ssid_len;
-       int                      bpffd; /* bpf - reading & broadcast writing*/
-       int                      udpfd; /* udp - unicast writing */
-       unsigned char           *rbuf;
-       size_t                   rbuf_max;
-       int                      errors;
-       uint16_t                 index;
-       int                      link_state;
-       int                      rdomain;
-       int                      flags;
-#define IFI_IN_CHARGE          0x01
-       uint32_t                 mtu;
-       struct dhcp_packet       recv_packet;
-       struct dhcp_packet       sent_packet;
-       int                      sent_packet_length;
-       uint32_t                 xid;
-       struct timespec          timeout;
-       struct timespec          reboot_timeout;
-       struct timespec          expiry;
-       struct timespec          rebind;
-       struct timespec          renew;
-       void                    (*timeout_func)(struct interface_info *);
-       uint16_t                 secs;
-       struct timespec          first_sending;
-       struct timespec          link_timeout;
-       struct timespec          offer_timeout;
-       struct timespec          select_timeout;
-       enum dhcp_state          state;
-       struct in_addr           destination;
-       time_t                   interval;
-       struct in_addr           requested_address;
-       struct client_lease     *active;
-       struct client_lease     *offer;
-       char                    *offer_src;
-       struct proposal         *configured;
-       struct unwind_info      *unwind_info;
-       struct client_lease_tq   lease_db;
-};
-
-#define        _PATH_DHCLIENT_CONF     "/etc/dhclient.conf"
-#define        _PATH_LEASE_DB          "/var/db/dhclient.leases"
-
-/* options.c */
-int                     pack_options(unsigned char *, int,
-       struct option_data *);
-struct option_data     *unpack_options(struct dhcp_packet *);
-char                   *pretty_print_option(unsigned int, struct option_data *,
-    int);
-char                   *pretty_print_string(unsigned char *, size_t, int);
-char                   *code_to_name(int);
-char                   *code_to_format(int);
-int                     code_to_action(int, int);
-int                     name_to_code(char *);
-void                    merge_option_data(char *, struct option_data *,
-    struct option_data *, struct option_data *);
-
-/* conflex.c */
-extern int      lexline, lexchar;
-extern char    *token_line, *tlname;
-
-void            new_parse(char *);
-int             next_token(char **, FILE *);
-int             peek_token(char **, FILE *);
-
-/* parse.c */
-void            skip_to_semi(FILE *);
-int             parse_semi(FILE *);
-int             parse_string(FILE *, char **);
-int             parse_ip_addr(FILE *, struct in_addr *);
-int             parse_cidr(FILE *, unsigned char *);
-int             parse_number(FILE *, long long *, long long, long long);
-int             parse_boolean(FILE *, unsigned char *);
-void            parse_warn(char *);
-
-/* bpf.c */
-int             get_bpf_sock(char *);
-int             get_udp_sock(int);
-int             configure_bpf_sock(int);
-ssize_t                 send_packet(struct interface_info *, struct in_addr,
-    struct in_addr, const char *);
-ssize_t                 receive_packet(unsigned char *, unsigned char *,
-    struct sockaddr_in *, struct ether_addr *, struct dhcp_packet *);
-
-/* dispatch.c */
-void            dispatch(struct interface_info *, int);
-void            set_timeout( struct interface_info *, time_t,
-    void (*)(struct interface_info *));
-void            cancel_timeout(struct interface_info *);
-
-/* dhclient.c */
-extern char                    *path_dhclient_conf;
-extern char                    *path_lease_db;
-extern char                    *log_procname;
-extern struct client_config    *config;
-extern struct imsgbuf          *unpriv_ibuf;
-extern int                      quit;
-extern int                      cmd_opts;
-#define                OPT_NOACTION    0x01
-#define                OPT_VERBOSE     0x02
-#define                OPT_FOREGROUND  0x04
-#define                OPT_RELEASE     0x08
-
-void            dhcpoffer(struct interface_info *, struct option_data *,
-    const char *);
-void            dhcpack(struct interface_info *, struct option_data *,
-    const char *);
-void            dhcpnak(struct interface_info *, const char *);
-void            bootreply(struct interface_info *, struct option_data *,
-    const char *);
-void            free_client_lease(struct client_lease *);
-void            routefd_handler(struct interface_info *, int);
-void            state_preboot(struct interface_info *);
-char           *rfc1035_as_string(unsigned char *, size_t);
-
-/* packet.c */
-void            assemble_eh_header(struct ether_addr, struct ether_header *);
-ssize_t                 decode_udp_ip_header(unsigned char *, uint32_t,
-    struct sockaddr_in *);
-uint32_t        checksum(unsigned char *, uint32_t, uint32_t);
-uint32_t        wrapsum(uint32_t);
-
-/* clparse.c */
-void            init_config(void);
-void            read_conf(char *, uint8_t *, struct ether_addr *);
-void            read_lease_db(struct client_lease_tq *);
-
-/* kroute.c */
-unsigned int    extract_route(uint8_t *, unsigned int, in_addr_t *,
-    in_addr_t *, in_addr_t *);
-void            write_resolv_conf(void);
-
-void            propose(struct proposal *);
-void            revoke_proposal(struct proposal *);
-
-void            tell_unwind(struct unwind_info *, int);
diff --git a/sbin/dhclient/dhctoken.h b/sbin/dhclient/dhctoken.h
deleted file mode 100644 (file)
index c2d749c..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*     $OpenBSD: dhctoken.h,v 1.16 2019/01/26 23:26:20 krw Exp $       */
-
-/* Tokens for config file lexer and parser. */
-
-/*
- * Copyright (c) 1995, 1996, 1997, 1998, 1999
- * The Internet Software Consortium.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#define TOK_FIRST_TOKEN        TOK_FILENAME
-#define TOK_FILENAME           257
-#define TOK_FIXED_ADDR         259
-#define TOK_OPTION             260
-#define TOK_STRING             262
-#define TOK_NUMBER             263
-#define TOK_NUMBER_OR_NAME     264
-#define TOK_NAME               265
-#define TOK_LEASE              266
-#define TOK_SERVER_NAME                267
-#define TOK_SEND               269
-#define TOK_REQUEST            270
-#define TOK_REQUIRE            271
-#define TOK_TIMEOUT            272
-#define TOK_RETRY              273
-#define TOK_SELECT_TIMEOUT     274
-#define TOK_NEXT_SERVER                275
-#define TOK_INTERFACE          276
-#define TOK_RENEW              277
-#define TOK_REBIND             278
-#define TOK_EXPIRE             279
-#define TOK_BOOTP              280
-#define TOK_DEFAULT            282
-#define TOK_REBOOT             286
-#define TOK_BACKOFF_CUTOFF     287
-#define TOK_INITIAL_INTERVAL   288
-#define TOK_SUPERSEDE          289
-#define TOK_APPEND             290
-#define TOK_PREPEND            291
-#define TOK_REJECT             292
-#define TOK_LINK_TIMEOUT       294
-#define TOK_IGNORE             295
-#define TOK_SSID               296
-#define TOK_EPOCH              297
-#define TOK_USELEASE           298
-
-#define is_identifier(x)       ((x) >= TOK_FIRST_TOKEN &&      \
-    (x) != TOK_STRING &&                                       \
-    (x) != TOK_NUMBER &&                                       \
-    (x) != EOF)
diff --git a/sbin/dhclient/dispatch.c b/sbin/dhclient/dispatch.c
deleted file mode 100644 (file)
index 5951ba8..0000000
+++ /dev/null
@@ -1,322 +0,0 @@
-/*     $OpenBSD: dispatch.c,v 1.172 2021/03/28 17:25:21 krw Exp $      */
-
-/*
- * Copyright 2004 Henning Brauer <henning@openbsd.org>
- * Copyright (c) 1995, 1996, 1997, 1998, 1999
- * The Internet Software Consortium.   All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#include <sys/ioctl.h>
-#include <sys/queue.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#include <net/if.h>
-#include <net/if_arp.h>
-#include <net/if_media.h>
-#include <net/route.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include <arpa/inet.h>
-
-#include <errno.h>
-#include <imsg.h>
-#include <limits.h>
-#include <poll.h>
-#include <resolv.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "dhcp.h"
-#include "dhcpd.h"
-#include "log.h"
-#include "privsep.h"
-
-
-void bpffd_handler(struct interface_info *);
-void dhcp_packet_dispatch(struct interface_info *, struct sockaddr_in *,
-    struct ether_addr *);
-void flush_unpriv_ibuf(void);
-
-/*
- * Loop waiting for packets, timeouts or routing messages.
- */
-void
-dispatch(struct interface_info *ifi, int routefd)
-{
-       const struct timespec    link_intvl = {config->link_interval, 0};
-       struct pollfd            fds[3];
-       struct timespec          timeout;
-       struct timespec         *ts;
-       void                    (*func)(struct interface_info *);
-       int                      nfds;
-
-       log_debug("%s: link is %s", log_procname,
-           LINK_STATE_IS_UP(ifi->link_state) ? "up" : "down");
-
-       while (quit == 0 || quit == RESTART) {
-               if (quit == RESTART) {
-                       quit = 0;
-                       clock_gettime(CLOCK_MONOTONIC, &ifi->link_timeout);
-                       timespecadd(&ifi->link_timeout, &link_intvl, &ifi->link_timeout);
-                       free(ifi->configured);
-                       ifi->configured = NULL;
-                       free(ifi->unwind_info);
-                       ifi->unwind_info = NULL;
-                       ifi->state = S_PREBOOT;
-                       state_preboot(ifi);
-               }
-               if (timespecisset(&ifi->timeout)) {
-                       clock_gettime(CLOCK_MONOTONIC, &timeout);
-                       if (timespeccmp(&timeout, &ifi->timeout, >=)) {
-                               func = ifi->timeout_func;
-                               cancel_timeout(ifi);
-                               (*(func))(ifi);
-                               continue;
-                       }
-                       timespecsub(&ifi->timeout, &timeout, &timeout);
-                       ts = &timeout;
-               } else
-                       ts = NULL;
-
-               /*
-                * Set up the descriptors to be polled.
-                *
-                *  fds[0] == bpf socket for incoming packets
-                *  fds[1] == routing socket for incoming RTM messages
-                *  fds[2] == imsg socket to privileged process
-                */
-               fds[0].fd = ifi->bpffd;
-               fds[1].fd = routefd;
-               fds[2].fd = unpriv_ibuf->fd;
-               fds[0].events = fds[1].events = fds[2].events = POLLIN;
-
-               if (unpriv_ibuf->w.queued)
-                       fds[2].events |= POLLOUT;
-
-               nfds = ppoll(fds, 3, ts, NULL);
-               if (nfds == -1) {
-                       if (errno == EINTR)
-                               continue;
-                       log_warn("%s: ppoll(bpffd, routefd, unpriv_ibuf)",
-                           log_procname);
-                       break;
-               }
-
-               if ((fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) != 0) {
-                       log_debug("%s: bpffd: ERR|HUP|NVAL", log_procname);
-                       break;
-               }
-               if ((fds[1].revents & (POLLERR | POLLHUP | POLLNVAL)) != 0) {
-                       log_debug("%s: routefd: ERR|HUP|NVAL", log_procname);
-                       break;
-               }
-               if ((fds[2].revents & (POLLERR | POLLHUP | POLLNVAL)) != 0) {
-                       log_debug("%s: unpriv_ibuf: ERR|HUP|NVAL", log_procname);
-                       break;
-               }
-
-               if (nfds == 0)
-                       continue;
-
-               if ((fds[0].revents & POLLIN) != 0)
-                       bpffd_handler(ifi);
-               if ((fds[1].revents & POLLIN) != 0)
-                       routefd_handler(ifi, routefd);
-               if ((fds[2].revents & POLLOUT) != 0)
-                       flush_unpriv_ibuf();
-               if ((fds[2].revents & POLLIN) != 0)
-                       break;
-       }
-}
-
-void
-bpffd_handler(struct interface_info *ifi)
-{
-       struct sockaddr_in       from;
-       struct ether_addr        hfrom;
-       unsigned char           *next, *lim;
-       ssize_t                  n;
-
-       n = read(ifi->bpffd, ifi->rbuf, ifi->rbuf_max);
-       if (n == -1) {
-               log_warn("%s: read(bpffd)", log_procname);
-               ifi->errors++;
-               if (ifi->errors > 20)
-                       fatalx("too many read(bpffd) failures");
-               return;
-       }
-       ifi->errors = 0;
-
-       lim = ifi->rbuf + n;
-       for (next = ifi->rbuf; quit == 0 && n > 0; next += n) {
-               n = receive_packet(next, lim, &from, &hfrom, &ifi->recv_packet);
-               if (n > 0)
-                       dhcp_packet_dispatch(ifi, &from, &hfrom);
-       }
-}
-
-void
-dhcp_packet_dispatch(struct interface_info *ifi, struct sockaddr_in *from,
-    struct ether_addr *hfrom)
-{
-       struct in_addr           ifrom;
-       struct dhcp_packet      *packet = &ifi->recv_packet;
-       struct reject_elem      *ap;
-       struct option_data      *options;
-       char                    *src;
-       int                      i, rslt;
-
-       ifrom.s_addr = from->sin_addr.s_addr;
-
-       if (packet->hlen != ETHER_ADDR_LEN) {
-               log_debug("%s: discarding packet with hlen == %u", log_procname,
-                   packet->hlen);
-               return;
-       } else if (memcmp(&ifi->hw_address, packet->chaddr,
-           sizeof(ifi->hw_address)) != 0) {
-               log_debug("%s: discarding packet with chaddr == %s",
-                   log_procname,
-                   ether_ntoa((struct ether_addr *)packet->chaddr));
-               return;
-       }
-
-       if (ifi->xid != packet->xid) {
-               log_debug("%s: discarding packet with XID != %u (%u)",
-                   log_procname, ifi->xid, packet->xid);
-               return;
-       }
-
-       TAILQ_FOREACH(ap, &config->reject_list, next)
-           if (ifrom.s_addr == ap->addr.s_addr) {
-                   log_debug("%s: discarding packet from address on reject "
-                       "list (%s)", log_procname, inet_ntoa(ifrom));
-                   return;
-           }
-
-       options = unpack_options(&ifi->recv_packet);
-
-       /*
-        * RFC 6842 says if the server sends a client identifier
-        * that doesn't match then the packet must be dropped.
-        */
-       i = DHO_DHCP_CLIENT_IDENTIFIER;
-       if ((options[i].len != 0) &&
-           ((options[i].len != config->send_options[i].len) ||
-           memcmp(options[i].data, config->send_options[i].data,
-           options[i].len) != 0)) {
-               log_debug("%s: discarding packet with client-identifier %s'",
-                   log_procname, pretty_print_option(i, &options[i], 0));
-               return;
-       }
-
-       rslt = asprintf(&src, "%s (%s)", inet_ntoa(ifrom), ether_ntoa(hfrom));
-       if (rslt == -1)
-               fatal("src");
-
-       i = DHO_DHCP_MESSAGE_TYPE;
-       if (options[i].data != NULL) {
-               /* Always try a DHCP packet, even if a bad option was seen. */
-               switch (options[i].data[0]) {
-               case DHCPOFFER:
-                       dhcpoffer(ifi, options, src);
-                       break;
-               case DHCPNAK:
-                       dhcpnak(ifi, src);
-                       break;
-               case DHCPACK:
-                       dhcpack(ifi, options, src);
-                       break;
-               default:
-                       log_debug("%s: discarding DHCP packet of unknown type "
-                           "(%d)", log_procname, options[i].data[0]);
-                       break;
-               }
-       } else if (packet->op == BOOTREPLY) {
-               bootreply(ifi, options, src);
-       } else {
-               log_debug("%s: discarding packet which is neither DHCP nor "
-                   "BOOTP", log_procname);
-       }
-
-       free(src);
-}
-
-/*
- * flush_unpriv_ibuf stuffs queued messages into the imsg socket.
- */
-void
-flush_unpriv_ibuf(void)
-{
-       while (unpriv_ibuf->w.queued) {
-               if (msgbuf_write(&unpriv_ibuf->w) <= 0) {
-                       if (errno == EAGAIN)
-                               break;
-                       if (quit == 0)
-                               quit = TERMINATE;
-                       if (errno != EPIPE && errno != 0)
-                               log_warn("%s: msgbuf_write(unpriv_ibuf)",
-                                   log_procname);
-                       break;
-               }
-       }
-}
-
-void
-set_timeout(struct interface_info *ifi, time_t secs,
-    void (*where)(struct interface_info *))
-{
-       struct timespec         now;
-
-       clock_gettime(CLOCK_MONOTONIC, &now);
-       timespecclear(&ifi->timeout);
-       ifi->timeout.tv_sec = secs;
-       timespecadd(&ifi->timeout, &now, &ifi->timeout);
-       ifi->timeout_func = where;
-}
-
-void
-cancel_timeout(struct interface_info *ifi)
-{
-       timespecclear(&ifi->timeout);
-       ifi->timeout_func = NULL;
-}
diff --git a/sbin/dhclient/kroute.c b/sbin/dhclient/kroute.c
deleted file mode 100644 (file)
index d85425f..0000000
+++ /dev/null
@@ -1,1072 +0,0 @@
-/*     $OpenBSD: kroute.c,v 1.197 2021/03/28 17:25:21 krw Exp $        */
-
-/*
- * Copyright 2012 Kenneth R Westerback <krw@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/ioctl.h>
-#include <sys/queue.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/sysctl.h>
-
-#include <arpa/inet.h>
-
-#include <net/if.h>
-#include <net/if_types.h>
-#include <net/route.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <ifaddrs.h>
-#include <imsg.h>
-#include <limits.h>
-#include <poll.h>
-#include <resolv.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "dhcp.h"
-#include "dhcpd.h"
-#include "log.h"
-#include "privsep.h"
-
-#define ROUNDUP(a) \
-       ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
-
-#define        CIDR_MAX_BITS   32
-
-int             delete_addresses(char *, int, struct in_addr, struct in_addr);
-void            set_address(char *, int, struct in_addr, struct in_addr);
-void            delete_address(char *, int, struct in_addr);
-
-char           *get_routes(int, size_t *);
-void            get_rtaddrs(int, struct sockaddr *, struct sockaddr **);
-unsigned int    route_pos(struct rt_msghdr *, uint8_t *, unsigned int,
-    struct in_addr);
-void            flush_routes(int, int, int, uint8_t *, unsigned int,
-    struct in_addr);
-void            discard_route(uint8_t *, unsigned int);
-void            add_route(char *, int, int, struct in_addr, struct in_addr,
-                   struct in_addr, struct in_addr, int);
-void            set_routes(char *, int, int, int, struct in_addr,
-    struct in_addr, uint8_t *, unsigned int);
-
-int             default_route_index(int, int);
-char           *resolv_conf_tail(void);
-char           *set_resolv_conf(char *, char *, struct unwind_info *);
-
-void            set_mtu(char *, int, uint16_t);
-
-/*
- * delete_addresses() removes all inet addresses on the named interface, except
- * for newaddr/newnetmask.
- *
- * If newaddr/newmask is already present, return 1, else 0.
- */
-int
-delete_addresses(char *name, int ioctlfd, struct in_addr newaddr,
-    struct in_addr newnetmask)
-{
-       struct in_addr                   addr, netmask;
-       struct ifaddrs                  *ifap, *ifa;
-       int                              found;
-
-       if (getifaddrs(&ifap) == -1)
-               fatal("getifaddrs");
-
-       found = 0;
-       for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
-               if ((ifa->ifa_flags & IFF_LOOPBACK) != 0 ||
-                   (ifa->ifa_flags & IFF_POINTOPOINT) != 0 ||
-                   ((ifa->ifa_flags & IFF_UP) == 0) ||
-                   (ifa->ifa_addr->sa_family != AF_INET) ||
-                   (strcmp(name, ifa->ifa_name) != 0))
-                       continue;
-
-               memcpy(&addr,
-                   &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr,
-                   sizeof(addr));
-               memcpy(&netmask,
-                   &((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr,
-                   sizeof(netmask));
-
-               if (addr.s_addr == newaddr.s_addr &&
-                   netmask.s_addr == newnetmask.s_addr) {
-                       found = 1;
-               } else {
-                       delete_address(name, ioctlfd, addr);
-               }
-       }
-
-       freeifaddrs(ifap);
-       return found;
-}
-
-/*
- * set_address() is the equivalent of
- *
- *     ifconfig <if> inet <addr> netmask <mask> broadcast <addr>
- */
-void
-set_address(char *name, int ioctlfd, struct in_addr addr,
-    struct in_addr netmask)
-{
-       struct ifaliasreq        ifaliasreq;
-       struct sockaddr_in      *in;
-
-       if (delete_addresses(name, ioctlfd, addr, netmask) == 1)
-               return;
-
-       memset(&ifaliasreq, 0, sizeof(ifaliasreq));
-       strncpy(ifaliasreq.ifra_name, name, sizeof(ifaliasreq.ifra_name));
-
-       /* The actual address in ifra_addr. */
-       in = (struct sockaddr_in *)&ifaliasreq.ifra_addr;
-       in->sin_family = AF_INET;
-       in->sin_len = sizeof(ifaliasreq.ifra_addr);
-       in->sin_addr.s_addr = addr.s_addr;
-
-       /* And the netmask in ifra_mask. */
-       in = (struct sockaddr_in *)&ifaliasreq.ifra_mask;
-       in->sin_family = AF_INET;
-       in->sin_len = sizeof(ifaliasreq.ifra_mask);
-       in->sin_addr.s_addr = netmask.s_addr;
-
-       /* No need to set broadcast address. Kernel can figure it out. */
-
-       if (ioctl(ioctlfd, SIOCAIFADDR, &ifaliasreq) == -1)
-               log_warn("%s: SIOCAIFADDR %s", log_procname,
-                   inet_ntoa(addr));
-}
-
-void
-delete_address(char *name, int ioctlfd, struct in_addr addr)
-{
-       struct ifaliasreq        ifaliasreq;
-       struct sockaddr_in      *in;
-
-       /*
-        * Delete specified address on specified interface.
-        *
-        * Deleting the address also clears out arp entries.
-        */
-
-       memset(&ifaliasreq, 0, sizeof(ifaliasreq));
-       strncpy(ifaliasreq.ifra_name, name, sizeof(ifaliasreq.ifra_name));
-
-       in = (struct sockaddr_in *)&ifaliasreq.ifra_addr;
-       in->sin_family = AF_INET;
-       in->sin_len = sizeof(ifaliasreq.ifra_addr);
-       in->sin_addr.s_addr = addr.s_addr;
-
-       /* SIOCDIFADDR will result in a RTM_DELADDR message we must catch! */
-       if (ioctl(ioctlfd, SIOCDIFADDR, &ifaliasreq) == -1) {
-               if (errno != EADDRNOTAVAIL)
-                       log_warn("%s: SIOCDIFADDR %s", log_procname,
-                           inet_ntoa(addr));
-       }
-}
-
-/*
- * get_routes() returns all relevant routes currently configured, and the
- * length of the buffer being returned.
- */
-char *
-get_routes(int rdomain, size_t *len)
-{
-       int              mib[7];
-       char            *buf, *bufp, *errmsg = NULL;
-       size_t           needed;
-
-       mib[0] = CTL_NET;
-       mib[1] = PF_ROUTE;      /* PF_ROUTE (not AF_ROUTE) for sysctl(2)! */
-       mib[2] = 0;
-       mib[3] = AF_INET;
-       mib[4] = NET_RT_FLAGS;
-       mib[5] = RTF_STATIC;
-       mib[6] = rdomain;
-
-       buf = NULL;
-       errmsg = NULL;
-       for (;;) {
-               if (sysctl(mib, 7, NULL, &needed, NULL, 0) == -1) {
-                       errmsg = "sysctl size of routes:";
-                       break;
-               }
-               if (needed == 0) {
-                       free(buf);
-                       return NULL;
-               }
-               if ((bufp = realloc(buf, needed)) == NULL) {
-                       errmsg = "routes buf realloc:";
-                       break;
-               }
-               buf = bufp;
-               if (sysctl(mib, 7, buf, &needed, NULL, 0) == -1) {
-                       if (errno == ENOMEM)
-                               continue;
-                       errmsg = "sysctl retrieval of routes:";
-                       break;
-               }
-               break;
-       }
-
-       if (errmsg != NULL) {
-               log_warn("%s: get_routes - %s (msize=%zu)", log_procname,
-                   errmsg, needed);
-               free(buf);
-               buf = NULL;
-       }
-
-       *len = needed;
-       return buf;
-}
-
-/*
- * get_rtaddrs() populates rti_info with pointers to the
- * sockaddr's contained in a rtm message.
- */
-void
-get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
-{
-       int     i;
-
-       for (i = 0; i < RTAX_MAX; i++) {
-               if (addrs & (1 << i)) {
-                       rti_info[i] = sa;
-                       sa = (struct sockaddr *)((char *)(sa) +
-                           ROUNDUP(sa->sa_len));
-               } else
-                       rti_info[i] = NULL;
-       }
-}
-/*
- * route_pos() finds the position of the *rtm route within
- * routes.
- *
- * If the *rtm route is not in routes, return routes_len.
- */
-unsigned int
-route_pos(struct rt_msghdr *rtm, uint8_t *routes, unsigned int routes_len,
-    struct in_addr address)
-{
-       struct sockaddr         *rti_info[RTAX_MAX];
-       struct sockaddr         *dst, *netmask, *gateway;
-       in_addr_t                dstaddr, netmaskaddr, gatewayaddr;
-       in_addr_t                routesdstaddr, routesnetmaskaddr;
-       in_addr_t                routesgatewayaddr;
-       unsigned int             i, len;
-
-       get_rtaddrs(rtm->rtm_addrs,
-           (struct sockaddr *)((char *)(rtm) + rtm->rtm_hdrlen),
-           rti_info);
-
-       dst = rti_info[RTAX_DST];
-       netmask = rti_info[RTAX_NETMASK];
-       gateway = rti_info[RTAX_GATEWAY];
-
-       if (dst == NULL || netmask == NULL || gateway == NULL)
-               return routes_len;
-
-       if (dst->sa_family != AF_INET || netmask->sa_family != AF_INET ||
-           gateway->sa_family != AF_INET)
-               return routes_len;
-
-       dstaddr = ((struct sockaddr_in *)dst)->sin_addr.s_addr;
-       netmaskaddr = ((struct sockaddr_in *)netmask)->sin_addr.s_addr;
-       gatewayaddr = ((struct sockaddr_in *)gateway)->sin_addr.s_addr;
-
-       dstaddr &= netmaskaddr;
-       i = 0;
-       while (i < routes_len)  {
-               len = extract_route(&routes[i], routes_len - i, &routesdstaddr,
-                   &routesnetmaskaddr, &routesgatewayaddr);
-               if (len == 0)
-                       break;
-
-               /* Direct route in routes:
-                *
-                * dst=1.2.3.4 netmask=255.255.255.255 gateway=0.0.0.0
-                *
-                * direct route in rtm:
-                *
-                * dst=1.2.3.4 netmask=255.255.255.255 gateway = address
-                *
-                * So replace 0.0.0.0 with address for comparison.
-                */
-               if (routesgatewayaddr == INADDR_ANY)
-                       routesgatewayaddr = address.s_addr;
-               routesdstaddr &= routesnetmaskaddr;
-
-               if (dstaddr == routesdstaddr &&
-                   netmaskaddr == routesnetmaskaddr &&
-                   gatewayaddr == routesgatewayaddr)
-                       return i;
-
-               i += len;
-       }
-
-       return routes_len;
-}
-
-void
-flush_routes(int index, int routefd, int rdomain, uint8_t *routes,
-    unsigned int routes_len, struct in_addr address)
-{
-       static int                       seqno;
-       char                            *lim, *buf, *next;
-       struct rt_msghdr                *rtm;
-       size_t                           len;
-       ssize_t                          rlen;
-       unsigned int                     pos;
-
-       buf = get_routes(rdomain, &len);
-       if (buf == NULL)
-               return;
-
-       lim = buf + len;
-       for (next = buf; next < lim; next += rtm->rtm_msglen) {
-               rtm = (struct rt_msghdr *)next;
-               if (rtm->rtm_version != RTM_VERSION)
-                       continue;
-               if (rtm->rtm_index != index)
-                       continue;
-               if (rtm->rtm_tableid != rdomain)
-                       continue;
-               if ((rtm->rtm_flags & RTF_STATIC) == 0)
-                       continue;
-               if ((rtm->rtm_flags & (RTF_LOCAL|RTF_BROADCAST)) != 0)
-                       continue;
-
-               pos = route_pos(rtm, routes, routes_len, address);
-               if (pos < routes_len) {
-                       discard_route(routes + pos, routes_len - pos);
-                       continue;
-               }
-
-               rtm->rtm_type = RTM_DELETE;
-               rtm->rtm_seq = seqno++;
-
-               rlen = write(routefd, (char *)rtm, rtm->rtm_msglen);
-               if (rlen == -1) {
-                       if (errno != ESRCH)
-                               log_warn("%s: write(RTM_DELETE)", log_procname);
-               } else if (rlen < (int)rtm->rtm_msglen)
-                       log_warnx("%s: write(RTM_DELETE): %zd of %u bytes",
-                           log_procname, rlen, rtm->rtm_msglen);
-       }
-
-       free(buf);
-}
-
-void
-discard_route(uint8_t *routes, unsigned int routes_len)
-{
-       unsigned int            len;
-
-       len = 1 + sizeof(struct in_addr) + (routes[0] + 7) / 8;
-       memmove(routes, routes + len, routes_len - len);
-       routes[routes_len - len] = CIDR_MAX_BITS + 1;
-}
-
-/*
- * add_route() adds a single route to the routing table.
- */
-void
-add_route(char *name, int rdomain, int routefd, struct in_addr dest,
-    struct in_addr netmask, struct in_addr gateway, struct in_addr address,
-    int flags)
-{
-       char                     destbuf[INET_ADDRSTRLEN];
-       char                     maskbuf[INET_ADDRSTRLEN];
-       struct iovec             iov[5];
-       struct sockaddr_in       sockaddr_in[4];
-       struct rt_msghdr         rtm;
-       int                      i, iovcnt = 0;
-
-       memset(&rtm, 0, sizeof(rtm));
-       rtm.rtm_index = if_nametoindex(name);
-       if (rtm.rtm_index == 0)
-               return;
-
-       rtm.rtm_version = RTM_VERSION;
-       rtm.rtm_type = RTM_ADD;
-       rtm.rtm_tableid = rdomain;
-       rtm.rtm_priority = RTP_NONE;
-       rtm.rtm_flags = flags;
-
-       iov[0].iov_base = &rtm;
-       iov[0].iov_len = sizeof(rtm);
-
-       memset(sockaddr_in, 0, sizeof(sockaddr_in));
-       for (i = 0; i < 4; i++) {
-               sockaddr_in[i].sin_len = sizeof(sockaddr_in[i]);
-               sockaddr_in[i].sin_family = AF_INET;
-               iov[i+1].iov_base = &sockaddr_in[i];
-               iov[i+1].iov_len = sizeof(sockaddr_in[i]);
-       }
-
-       /* Order of sockaddr_in's is mandatory! */
-       sockaddr_in[0].sin_addr = dest;
-       sockaddr_in[1].sin_addr = gateway;
-       sockaddr_in[2].sin_addr = netmask;
-       sockaddr_in[3].sin_addr = address;
-       if (address.s_addr == INADDR_ANY) {
-               rtm.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
-               iovcnt = 4;
-       } else {
-               rtm.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK | RTA_IFA;
-               iovcnt = 5;
-       }
-
-       for (i = 0; i < iovcnt; i++)
-               rtm.rtm_msglen += iov[i].iov_len;
-
-       if (writev(routefd, iov, iovcnt) == -1) {
-               if (errno != EEXIST || log_getverbose() != 0) {
-                       strlcpy(destbuf, inet_ntoa(dest), sizeof(destbuf));
-                       strlcpy(maskbuf, inet_ntoa(netmask),sizeof(maskbuf));
-                       log_warn("%s: add route %s/%s via %s", log_procname,
-                           destbuf, maskbuf, inet_ntoa(gateway));
-               }
-       }
-}
-
-/*
- * set_routes() adds the routes contained in 'routes' to the routing table.
- */
-void
-set_routes(char *name, int index, int rdomain, int routefd, struct in_addr addr,
-    struct in_addr addrmask, uint8_t *routes, unsigned int routes_len)
-{
-       const struct in_addr     any = { INADDR_ANY };
-       const struct in_addr     broadcast = { INADDR_BROADCAST };
-       struct in_addr           dest, gateway, netmask;
-       in_addr_t                addrnet, gatewaynet;
-       unsigned int             i, len;
-
-       flush_routes(index, routefd, rdomain, routes, routes_len, addr);
-
-       addrnet = addr.s_addr & addrmask.s_addr;
-
-       /* Add classless static routes. */
-       i = 0;
-       while (i < routes_len) {
-               len = extract_route(&routes[i], routes_len - i,
-                   &dest.s_addr, &netmask.s_addr, &gateway.s_addr);
-               if (len == 0)
-                       return;
-               i += len;
-
-               if (gateway.s_addr == INADDR_ANY) {
-                       /*
-                        * DIRECT ROUTE
-                        *
-                        * route add -net $dest -netmask $netmask -cloning
-                        *     -iface $addr
-                        */
-                       add_route(name, rdomain, routefd, dest, netmask,
-                           addr, any, RTF_STATIC | RTF_CLONING);
-               } else if (netmask.s_addr == INADDR_ANY) {
-                       /*
-                        * DEFAULT ROUTE
-                        */
-                       gatewaynet = gateway.s_addr & addrmask.s_addr;
-                       if (gatewaynet != addrnet) {
-                               /*
-                                * DIRECT ROUTE TO DEFAULT GATEWAY
-                                *
-                                * route add -net $gateway
-                                *      -netmask 255.255.255.255
-                                *      -cloning -iface $addr
-                                *
-                                * If the default route gateway is not reachable
-                                * via the IP assignment then add a cloning
-                                * direct route for the gateway. Deals with
-                                * weird configs seen in the wild.
-                                *
-                                * e.g. add the route if we were given a /32 IP
-                                * assignment. a.k.a. "make Google Cloud DHCP
-                                * work".
-                                *
-                                */
-                               add_route(name, rdomain, routefd, gateway,
-                                   broadcast, addr, any,
-                                   RTF_STATIC | RTF_CLONING);
-                       }
-
-                       if (memcmp(&gateway, &addr, sizeof(addr)) == 0) {
-                               /*
-                                * DEFAULT ROUTE IS A DIRECT ROUTE
-                                *
-                                * route add default -iface $addr
-                                */
-                               add_route(name, rdomain, routefd, any, any,
-                                   gateway, any, RTF_STATIC);
-                       } else {
-                               /*
-                                * DEFAULT ROUTE IS VIA GATEWAY
-                                *
-                                * route add default $gateway -ifa $addr
-                                *
-                                */
-                               add_route(name, rdomain, routefd, any, any,
-                                   gateway, addr, RTF_STATIC | RTF_GATEWAY);
-                       }
-               } else {
-                       /*
-                        * NON-DIRECT, NON-DEFAULT ROUTE
-                        *
-                        * route add -net $dest -netmask $netmask $gateway
-                        */
-                       add_route(name, rdomain, routefd, dest, netmask,
-                           gateway, any, RTF_STATIC | RTF_GATEWAY);
-               }
-       }
-}
-
-/*
- * default_route_index() returns the interface index of the current
- * default route (a.k.a. 0.0.0.0/0).
- */
-int
-default_route_index(int rdomain, int routefd)
-{
-       struct pollfd            fds[1];
-       struct timespec          now, stop, timeout;
-       int                      nfds;
-       struct iovec             iov[3];
-       struct sockaddr_in       sin;
-       struct {
-               struct rt_msghdr        m_rtm;
-               char                    m_space[512];
-       } m_rtmsg;
-       pid_t                    pid;
-       ssize_t                  len;
-       int                      seq;
-
-       memset(&m_rtmsg, 0, sizeof(m_rtmsg));
-       m_rtmsg.m_rtm.rtm_version = RTM_VERSION;
-       m_rtmsg.m_rtm.rtm_type = RTM_GET;
-       m_rtmsg.m_rtm.rtm_tableid = rdomain;
-       m_rtmsg.m_rtm.rtm_seq = seq = arc4random();
-       m_rtmsg.m_rtm.rtm_addrs = RTA_DST | RTA_NETMASK;
-       m_rtmsg.m_rtm.rtm_msglen = sizeof(struct rt_msghdr) +
-           2 * sizeof(struct sockaddr_in);
-
-       memset(&sin, 0, sizeof(sin));
-       sin.sin_len = sizeof(sin);
-       sin.sin_family = AF_INET;
-
-       iov[0].iov_base = &m_rtmsg.m_rtm;
-       iov[0].iov_len = sizeof(m_rtmsg.m_rtm);
-       iov[1].iov_base = &sin;
-       iov[1].iov_len = sizeof(sin);
-       iov[2].iov_base = &sin;
-       iov[2].iov_len = sizeof(sin);
-
-       pid = getpid();
-       clock_gettime(CLOCK_MONOTONIC, &now);
-       timespecclear(&timeout);
-       timeout.tv_sec = 3;
-       timespecadd(&now, &timeout, &stop);
-
-       if (writev(routefd, iov, 3) == -1) {
-               if (errno == ESRCH)
-                       log_debug("%s: writev(RTM_GET) - no default route",
-                           log_procname);
-               else
-                       log_warn("%s: writev(RTM_GET)", log_procname);
-               return 0;
-       }
-
-       for (;;) {
-               clock_gettime(CLOCK_MONOTONIC, &now);
-               if (timespeccmp(&stop, &now, <=))
-                       break;
-               timespecsub(&stop, &now, &timeout);
-
-               fds[0].fd = routefd;
-               fds[0].events = POLLIN;
-               nfds = ppoll(fds, 1, &timeout, NULL);
-               if (nfds == -1) {
-                       if (errno == EINTR)
-                               continue;
-                       log_warn("%s: ppoll(routefd)", log_procname);
-                       break;
-               }
-               if ((fds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) != 0) {
-                       log_warnx("%s: routefd: ERR|HUP|NVAL", log_procname);
-                       break;
-               }
-               if (nfds == 0 || (fds[0].revents & POLLIN) == 0)
-                       continue;
-
-               len = read(routefd, &m_rtmsg, sizeof(m_rtmsg));
-               if (len == -1) {
-                       log_warn("%s: read(RTM_GET)", log_procname);
-                       break;
-               } else if (len == 0) {
-                       log_warnx("%s: read(RTM_GET): 0 bytes", log_procname);
-                       break;
-               }
-
-               if (m_rtmsg.m_rtm.rtm_version == RTM_VERSION &&
-                   m_rtmsg.m_rtm.rtm_type == RTM_GET &&
-                   m_rtmsg.m_rtm.rtm_pid == pid &&
-                   m_rtmsg.m_rtm.rtm_seq == seq &&
-                   (m_rtmsg.m_rtm.rtm_flags & RTF_UP) == RTF_UP) {
-                       if (m_rtmsg.m_rtm.rtm_errno != 0) {
-                               log_warnx("%s: read(RTM_GET): %s", log_procname,
-                                   strerror(m_rtmsg.m_rtm.rtm_errno));
-                               break;
-                       }
-                       return m_rtmsg.m_rtm.rtm_index;
-               }
-       }
-
-       return 0;
-}
-
-/*
- * resolv_conf_tail() returns the contents of /etc/resolv.conf.tail, if
- * any. NULL is returned if there is no such file, the file is emtpy
- * or any errors are encounted in reading the file.
- */
-char *
-resolv_conf_tail(void)
-{
-       struct stat              sb;
-       const char              *tail_path = "/etc/resolv.conf.tail";
-       char                    *tailcontents = NULL;
-       ssize_t                  tailn;
-       int                      tailfd;
-
-       tailfd = open(tail_path, O_RDONLY);
-       if (tailfd == -1) {
-               if (errno != ENOENT)
-                       log_warn("%s: open(%s)", log_procname, tail_path);
-       } else if (fstat(tailfd, &sb) == -1) {
-               log_warn("%s: fstat(%s)", log_procname, tail_path);
-       } else if (sb.st_size > 0 && sb.st_size < LLONG_MAX) {
-               tailcontents = calloc(1, sb.st_size + 1);
-               if (tailcontents == NULL)
-                       fatal("%s contents", tail_path);
-               tailn = read(tailfd, tailcontents, sb.st_size);
-               if (tailn == -1)
-                       log_warn("%s: read(%s)", log_procname,
-                           tail_path);
-               else if (tailn == 0)
-                       log_warnx("%s: got no data from %s",
-                           log_procname,tail_path);
-               else if (tailn != sb.st_size)
-                       log_warnx("%s: short read of %s",
-                           log_procname, tail_path);
-               else {
-                       close(tailfd);
-                       return tailcontents;
-               }
-
-               close(tailfd);
-               free(tailcontents);
-       }
-
-       return NULL;
-}
-
-/*
- * set_resolv_conf() creates a string that are the resolv.conf contents
- * that should be used when IMSG_WRITE_RESOLV_CONF messages are received.
- */
-char *
-set_resolv_conf(char *name, char *search, struct unwind_info *ns_info)
-{
-       char            *ns, *p, *tail;
-       struct in_addr   addr;
-       unsigned int     i;
-       int              rslt;
-
-       ns = NULL;
-       for (i = 0; i < ns_info->count; i++) {
-               addr.s_addr = ns_info->ns[i];
-               rslt = asprintf(&p, "%snameserver %s\n",
-                   (ns == NULL) ? "" : ns, inet_ntoa(addr));
-               if (rslt == -1)
-                       fatal("nameserver");
-               free(ns);
-               ns = p;
-       }
-
-       if (search == NULL && ns == NULL)
-               return NULL;
-
-       tail = resolv_conf_tail();
-
-       rslt = asprintf(&p, "# Generated by %s dhclient\n%s%s%s", name,
-           (search == NULL) ? "" : search,
-           (ns == NULL) ? "" : ns,
-           (tail == NULL) ? "" : tail);
-       if (rslt == -1)
-               fatal("resolv.conf");
-
-       free(tail);
-       free(ns);
-
-       return p;
-}
-
-/*
- * set_mtu() is the equivalent of
- *
- *      ifconfig <if> mtu <mtu>
- */
-void
-set_mtu(char *name, int ioctlfd, uint16_t mtu)
-{
-       struct ifreq     ifr;
-
-       memset(&ifr, 0, sizeof(ifr));
-       strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
-
-       if (ioctl(ioctlfd, SIOCGIFMTU, &ifr) == -1) {
-               log_warn("%s: SIOCGIFMTU", log_procname);
-               return;
-       }
-       if (ifr.ifr_mtu == mtu)
-               return; /* Avoid unnecessary RTM_IFINFO! */
-
-       ifr.ifr_mtu = mtu;
-       if (ioctl(ioctlfd, SIOCSIFMTU, &ifr) == -1)
-               log_warn("%s: SIOCSIFMTU %u", log_procname, mtu);
-}
-
-/*
- * extract_route() decodes the route pointed to by routes into its
- * {destination, netmask, gateway} and returns the number of bytes consumed
- * from routes.
- */
-unsigned int
-extract_route(uint8_t *routes, unsigned int routes_len, in_addr_t *dest,
-    in_addr_t *netmask, in_addr_t *gateway)
-{
-       unsigned int     bits, bytes, len;
-
-       if (routes[0] > CIDR_MAX_BITS)
-               return 0;
-
-       bits = routes[0];
-       bytes = (bits + 7) / 8;
-       len = 1 + bytes + sizeof(*gateway);
-       if (len > routes_len)
-               return 0;
-
-       if (dest != NULL)
-               memcpy(dest, &routes[1], bytes);
-
-       if (netmask != NULL) {
-               if (bits == 0)
-                       *netmask = INADDR_ANY;
-               else
-                       *netmask = htonl(0xffffffff << (CIDR_MAX_BITS - bits));
-               if (dest != NULL)
-                       *dest &= *netmask;
-       }
-
-       if (gateway != NULL)
-               memcpy(gateway, &routes[1 +  bytes], sizeof(*gateway));
-
-       return len;
-}
-
-/*
- * [priv_]write_resolv_conf write out a new resolv.conf.
- */
-void
-write_resolv_conf(void)
-{
-       int      rslt;
-
-       rslt = imsg_compose(unpriv_ibuf, IMSG_WRITE_RESOLV_CONF,
-           0, 0, -1, NULL, 0);
-       if (rslt == -1)
-               log_warn("%s: imsg_compose(IMSG_WRITE_RESOLV_CONF)",
-                   log_procname);
-}
-
-void
-priv_write_resolv_conf(int index, int routefd, int rdomain, char *contents,
-    int *lastidx)
-{
-       char             ifname[IF_NAMESIZE];
-       const char      *path = "/etc/resolv.conf";
-       ssize_t          n;
-       size_t           sz;
-       int              fd, retries, newidx;
-
-       if (contents == NULL)
-               return;
-
-       retries = 0;
-       do {
-               newidx = default_route_index(rdomain, routefd);
-               retries++;
-       } while (newidx == 0 && retries < 3);
-
-       if (newidx == 0) {
-               log_debug("%s: %s not updated, no default route is UP",
-                   log_procname, path);
-               return;
-       } else if (newidx != index) {
-               *lastidx = newidx;
-               if (if_indextoname(newidx, ifname) == NULL) {
-                       memset(ifname, 0, sizeof(ifname));
-                       strlcat(ifname, "<unknown>", sizeof(ifname));
-               }
-               log_debug("%s: %s not updated, default route on %s",
-                   log_procname, path, ifname);
-               return;
-       } else if (newidx == *lastidx) {
-               log_debug("%s: %s not updated, same as last write",
-                   log_procname, path);
-               return;
-       }
-
-       *lastidx = newidx;
-       log_debug("%s: %s updated", log_procname, path);
-
-       fd = open(path, O_WRONLY | O_CREAT | O_TRUNC,
-           S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
-       if (fd == -1) {
-               log_warn("%s: open(%s)", log_procname, path);
-               return;
-       }
-
-       sz = strlen(contents);
-       n = write(fd, contents, sz);
-       if (n == -1)
-               log_warn("%s: write(%s)", log_procname, path);
-       else if ((size_t)n < sz)
-               log_warnx("%s: write(%s): %zd of %zu bytes", log_procname,
-                   path, n, sz);
-
-       close(fd);
-}
-
-/*
- * [priv_]propose implements a proposal.
- */
-void
-propose(struct proposal *proposal)
-{
-       struct option_data       opt;
-       int                      rslt;
-
-       log_debug("%s: proposing address %s netmask 0x%08x", log_procname,
-           inet_ntoa(proposal->address), ntohl(proposal->netmask.s_addr));
-
-       opt.data = (u_int8_t *)proposal + sizeof(struct proposal);
-       opt.len = proposal->routes_len;
-       if (opt.len > 0)
-               log_debug("%s: proposing static route(s) %s", log_procname,
-                   pretty_print_option(DHO_CLASSLESS_STATIC_ROUTES, &opt, 0));
-
-       opt.data += opt.len;
-       opt.len = proposal->domains_len;
-       if (opt.len > 0)
-               log_debug("%s: proposing search domain(s) %s", log_procname,
-                   pretty_print_option(DHO_DOMAIN_SEARCH, &opt, 0));
-
-       opt.data += opt.len;
-       opt.len = proposal->ns_len;
-       if (opt.len > 0)
-               log_debug("%s: proposing DNS server(s) %s", log_procname,
-                   pretty_print_option(DHO_DOMAIN_NAME_SERVERS, &opt, 0));
-
-       if (proposal->mtu != 0)
-               log_debug("%s: proposing mtu %u", log_procname, proposal->mtu);
-
-       rslt = imsg_compose(unpriv_ibuf, IMSG_PROPOSE, 0, 0, -1, proposal,
-           sizeof(*proposal) + proposal->routes_len +
-           proposal->domains_len + proposal->ns_len);
-       if (rslt == -1)
-               log_warn("%s: imsg_compose(IMSG_PROPOSE)", log_procname);
-}
-
-void
-priv_propose(char *name, int ioctlfd, struct proposal *proposal,
-    size_t sz, char **resolv_conf, int routefd, int rdomain, int index,
-    int *lastidx)
-{
-       struct unwind_info       unwind_info;
-       uint8_t                 *dns, *domains, *routes;
-       char                    *search = NULL;
-       int                      rslt;
-
-       if (sz != proposal->routes_len + proposal->domains_len +
-           proposal->ns_len) {
-               log_warnx("%s: bad IMSG_PROPOSE data", log_procname);
-               return;
-       }
-
-       routes = (uint8_t *)proposal + sizeof(struct proposal);
-       domains = routes + proposal->routes_len;
-       dns = domains + proposal->domains_len;
-
-       memset(&unwind_info, 0, sizeof(unwind_info));
-       if (proposal->ns_len >= sizeof(in_addr_t)) {
-               if (proposal->ns_len > sizeof(unwind_info.ns)) {
-                       memcpy(unwind_info.ns, dns, sizeof(unwind_info.ns));
-                       unwind_info.count = sizeof(unwind_info.ns) /
-                           sizeof(in_addr_t);
-               } else {
-                       memcpy(unwind_info.ns, dns, proposal->ns_len);
-                       unwind_info.count = proposal->ns_len /
-                           sizeof(in_addr_t);
-               }
-       }
-
-       if (proposal->domains_len > 0) {
-               rslt = asprintf(&search, "search %.*s\n",
-                   proposal->domains_len, domains);
-               if (rslt == -1)
-                       search = NULL;
-       }
-
-       free(*resolv_conf);
-       *resolv_conf = set_resolv_conf(name, search, &unwind_info);
-       free(search);
-
-       if (proposal->mtu != 0) {
-               if (proposal->mtu < 68)
-                       log_warnx("%s: mtu size %d < 68: ignored", log_procname,
-                           proposal->mtu);
-               else
-                       set_mtu(name, ioctlfd, proposal->mtu);
-       }
-
-       set_address(name, ioctlfd, proposal->address, proposal->netmask);
-
-       set_routes(name, index, rdomain, routefd, proposal->address,
-           proposal->netmask, routes, proposal->routes_len);
-
-       *lastidx = 0;
-       priv_write_resolv_conf(index, routefd, rdomain, *resolv_conf, lastidx);
-}
-
-/*
- * [priv_]revoke_proposal de-configures a proposal.
- */
-void
-revoke_proposal(struct proposal *proposal)
-{
-       int                      rslt;
-
-       if (proposal == NULL)
-               return;
-
-       rslt = imsg_compose(unpriv_ibuf, IMSG_REVOKE, 0, 0, -1, proposal,
-           sizeof(*proposal));
-       if (rslt == -1)
-               log_warn("%s: imsg_compose(IMSG_REVOKE)", log_procname);
-}
-
-void
-priv_revoke_proposal(char *name, int ioctlfd, struct proposal *proposal,
-    char **resolv_conf)
-{
-       free(*resolv_conf);
-       *resolv_conf = NULL;
-
-       delete_address(name, ioctlfd, proposal->address);
-}
-
-/*
- * [priv_]tell_unwind sends out inforation unwind may be intereted in.
- */
-void
-tell_unwind(struct unwind_info *unwind_info, int ifi_flags)
-{
-       struct  unwind_info              noinfo;
-       int                              rslt;
-
-       if ((ifi_flags & IFI_IN_CHARGE) == 0)
-               return;
-
-       if (unwind_info != NULL)
-               rslt = imsg_compose(unpriv_ibuf, IMSG_TELL_UNWIND, 0, 0, -1,
-                   unwind_info, sizeof(*unwind_info));
-       else {
-               memset(&noinfo, 0, sizeof(noinfo));
-               rslt = imsg_compose(unpriv_ibuf, IMSG_TELL_UNWIND, 0, 0, -1,
-                   &noinfo, sizeof(noinfo));
-       }
-
-       if (rslt == -1)
-               log_warn("%s: imsg_compose(IMSG_TELL_UNWIND)", log_procname);
-}
-
-void
-priv_tell_unwind(int index, int routefd, int rdomain,
-    struct unwind_info *unwind_info)
-{
-       struct rt_msghdr                 rtm;
-       struct sockaddr_rtdns            rtdns;
-       struct iovec                     iov[3];
-       long                             pad = 0;
-       int                              iovcnt = 0, padlen;
-
-       memset(&rtm, 0, sizeof(rtm));
-
-       rtm.rtm_version = RTM_VERSION;
-       rtm.rtm_type = RTM_PROPOSAL;
-       rtm.rtm_msglen = sizeof(rtm);
-       rtm.rtm_tableid = rdomain;
-       rtm.rtm_index = index;
-       rtm.rtm_seq = arc4random();
-       rtm.rtm_priority = RTP_PROPOSAL_DHCLIENT;
-       rtm.rtm_addrs = RTA_DNS;
-       rtm.rtm_flags = RTF_UP;
-
-       iov[iovcnt].iov_base = &rtm;
-       iov[iovcnt++].iov_len = sizeof(rtm);
-
-       memset(&rtdns, 0, sizeof(rtdns));
-       rtdns.sr_family = AF_INET;
-
-       rtdns.sr_len = 2 + unwind_info->count * sizeof(in_addr_t);
-       memcpy(rtdns.sr_dns, unwind_info->ns,
-           unwind_info->count * sizeof(in_addr_t));
-
-       iov[iovcnt].iov_base = &rtdns;
-       iov[iovcnt++].iov_len = sizeof(rtdns);
-       rtm.rtm_msglen += sizeof(rtdns);
-       padlen = ROUNDUP(sizeof(rtdns)) - sizeof(rtdns);
-       if (padlen > 0) {
-               iov[iovcnt].iov_base = &pad;
-               iov[iovcnt++].iov_len = padlen;
-               rtm.rtm_msglen += padlen;
-       }
-
-       if (writev(routefd, iov, iovcnt) == -1)
-               log_warn("failed to tell unwind");
-}
diff --git a/sbin/dhclient/log.c b/sbin/dhclient/log.c
deleted file mode 100644 (file)
index 8956cd8..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-/*     $OpenBSD: log.c,v 1.2 2017/03/21 12:06:55 bluhm Exp $   */
-
-/*
- * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <syslog.h>
-#include <errno.h>
-#include <time.h>
-
-#include "log.h"
-
-static int              debug;
-static int              verbose;
-static const char      *log_procname;
-
-void
-log_init(int n_debug, int facility)
-{
-       extern char     *__progname;
-
-       debug = n_debug;
-       verbose = n_debug;
-       log_procinit(__progname);
-
-       if (!debug)
-               openlog(__progname, LOG_PID | LOG_NDELAY, facility);
-
-       tzset();
-}
-
-void
-log_procinit(const char *procname)
-{
-       if (procname != NULL)
-               log_procname = procname;
-}
-
-void
-log_setverbose(int v)
-{
-       verbose = v;
-}
-
-int
-log_getverbose(void)
-{
-       return (verbose);
-}
-
-void
-logit(int pri, const char *fmt, ...)
-{
-       va_list ap;
-
-       va_start(ap, fmt);
-       vlog(pri, fmt, ap);
-       va_end(ap);
-}
-
-void
-vlog(int pri, const char *fmt, va_list ap)
-{
-       char    *nfmt;
-       int      saved_errno = errno;
-
-       if (debug) {
-               /* best effort in out of mem situations */
-               if (asprintf(&nfmt, "%s\n", fmt) == -1) {
-                       vfprintf(stderr, fmt, ap);
-                       fprintf(stderr, "\n");
-               } else {
-                       vfprintf(stderr, nfmt, ap);
-                       free(nfmt);
-               }
-               fflush(stderr);
-       } else
-               vsyslog(pri, fmt, ap);
-
-       errno = saved_errno;
-}
-
-void
-log_warn(const char *emsg, ...)
-{
-       char            *nfmt;
-       va_list          ap;
-       int              saved_errno = errno;
-
-       /* best effort to even work in out of memory situations */
-       if (emsg == NULL)
-               logit(LOG_ERR, "%s", strerror(saved_errno));
-       else {
-               va_start(ap, emsg);
-
-               if (asprintf(&nfmt, "%s: %s", emsg,
-                   strerror(saved_errno)) == -1) {
-                       /* we tried it... */
-                       vlog(LOG_ERR, emsg, ap);
-                       logit(LOG_ERR, "%s", strerror(saved_errno));
-               } else {
-                       vlog(LOG_ERR, nfmt, ap);
-                       free(nfmt);
-               }
-               va_end(ap);
-       }
-
-       errno = saved_errno;
-}
-
-void
-log_warnx(const char *emsg, ...)
-{
-       va_list  ap;
-
-       va_start(ap, emsg);
-       vlog(LOG_ERR, emsg, ap);
-       va_end(ap);
-}
-
-void
-log_info(const char *emsg, ...)
-{
-       va_list  ap;
-
-       va_start(ap, emsg);
-       vlog(LOG_INFO, emsg, ap);
-       va_end(ap);
-}
-
-void
-log_debug(const char *emsg, ...)
-{
-       va_list  ap;
-
-       if (verbose) {
-               va_start(ap, emsg);
-               vlog(LOG_DEBUG, emsg, ap);
-               va_end(ap);
-       }
-}
-
-static void
-vfatalc(int code, const char *emsg, va_list ap)
-{
-       static char     s[BUFSIZ];
-       const char      *sep;
-
-       if (emsg != NULL) {
-               (void)vsnprintf(s, sizeof(s), emsg, ap);
-               sep = ": ";
-       } else {
-               s[0] = '\0';
-               sep = "";
-       }
-       if (code)
-               logit(LOG_CRIT, "fatal in %s: %s%s%s",
-                   log_procname, s, sep, strerror(code));
-       else
-               logit(LOG_CRIT, "fatal in %s%s%s", log_procname, sep, s);
-}
-
-void
-fatal(const char *emsg, ...)
-{
-       va_list ap;
-
-       va_start(ap, emsg);
-       vfatalc(errno, emsg, ap);
-       va_end(ap);
-       exit(1);
-}
-
-void
-fatalx(const char *emsg, ...)
-{
-       va_list ap;
-
-       va_start(ap, emsg);
-       vfatalc(0, emsg, ap);
-       va_end(ap);
-       exit(1);
-}
diff --git a/sbin/dhclient/log.h b/sbin/dhclient/log.h
deleted file mode 100644 (file)
index fc64312..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*     $OpenBSD: log.h,v 1.2 2021/12/13 18:28:39 deraadt Exp $ */
-
-/*
- * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef LOG_H
-#define LOG_H
-
-#include <stdarg.h>
-
-void   log_init(int, int);
-void   log_procinit(const char *);
-void   log_setverbose(int);
-int    log_getverbose(void);
-void   log_warn(const char *, ...)
-           __attribute__((__format__ (printf, 1, 2)));
-void   log_warnx(const char *, ...)
-           __attribute__((__format__ (printf, 1, 2)));
-void   log_info(const char *, ...)
-           __attribute__((__format__ (printf, 1, 2)));
-void   log_debug(const char *, ...)
-           __attribute__((__format__ (printf, 1, 2)));
-void   logit(int, const char *, ...)
-           __attribute__((__format__ (printf, 2, 3)));
-void   vlog(int, const char *, va_list)
-           __attribute__((__format__ (printf, 2, 0)));
-__dead void fatal(const char *, ...)
-           __attribute__((__format__ (printf, 1, 2)));
-__dead void fatalx(const char *, ...)
-           __attribute__((__format__ (printf, 1, 2)));
-
-#endif /* LOG_H */
diff --git a/sbin/dhclient/options.c b/sbin/dhclient/options.c
deleted file mode 100644 (file)
index 84b76e1..0000000
+++ /dev/null
@@ -1,1001 +0,0 @@
-/*     $OpenBSD: options.c,v 1.123 2020/07/07 19:48:31 krw Exp $       */
-
-/* DHCP options parsing and reassembly. */
-
-/*
- * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#include <sys/queue.h>
-#include <sys/socket.h>
-
-#include <arpa/inet.h>
-
-#include <net/if.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include <ctype.h>
-#include <resolv.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <vis.h>
-
-#include "dhcp.h"
-#include "dhcpd.h"
-#include "log.h"
-
-int    parse_option_buffer(struct option_data *, unsigned char *, int);
-void   pretty_print_classless_routes(unsigned char *, size_t, unsigned char *,
-    size_t);
-void   pretty_print_domain_list(unsigned char *, size_t, unsigned char *,
-    size_t);
-
-/*
- * DHCP Option names, formats and codes, from RFC1533.
- *
- * Format codes:
- *
- * e - end of data
- * I - IP address
- * l - 32-bit signed integer
- * L - 32-bit unsigned integer
- * S - 16-bit unsigned integer
- * B - 8-bit unsigned integer
- * t - ASCII text
- * f - flag (true or false)
- * A - array of whatever precedes (e.g., IA means array of IP addresses)
- * C - CIDR description
- * X - hex octets
- * D - domain name list, comma separated list of domain names.
- */
-
-static const struct {
-       char *name;
-       char *format;
-} dhcp_options[DHO_COUNT] = {
-       /*   0 */ { "pad", "" },
-       /*   1 */ { "subnet-mask", "I" },
-       /*   2 */ { "time-offset", "l" },
-       /*   3 */ { "routers", "IA" },
-       /*   4 */ { "time-servers", "IA" },
-       /*   5 */ { "ien116-name-servers", "IA" },
-       /*   6 */ { "domain-name-servers", "IA" },
-       /*   7 */ { "log-servers", "IA" },
-       /*   8 */ { "cookie-servers", "IA" },
-       /*   9 */ { "lpr-servers", "IA" },
-       /*  10 */ { "impress-servers", "IA" },
-       /*  11 */ { "resource-location-servers", "IA" },
-       /*  12 */ { "host-name", "t" },
-       /*  13 */ { "boot-size", "S" },
-       /*  14 */ { "merit-dump", "t" },
-       /*  15 */ { "domain-name", "t" },
-       /*  16 */ { "swap-server", "I" },
-       /*  17 */ { "root-path", "t" },
-       /*  18 */ { "extensions-path", "t" },
-       /*  19 */ { "ip-forwarding", "f" },
-       /*  20 */ { "non-local-source-routing", "f" },
-       /*  21 */ { "policy-filter", "IIA" },
-       /*  22 */ { "max-dgram-reassembly", "S" },
-       /*  23 */ { "default-ip-ttl", "B" },
-       /*  24 */ { "path-mtu-aging-timeout", "L" },
-       /*  25 */ { "path-mtu-plateau-table", "SA" },
-       /*  26 */ { "interface-mtu", "S" },
-       /*  27 */ { "all-subnets-local", "f" },
-       /*  28 */ { "broadcast-address", "I" },
-       /*  29 */ { "perform-mask-discovery", "f" },
-       /*  30 */ { "mask-supplier", "f" },
-       /*  31 */ { "router-discovery", "f" },
-       /*  32 */ { "router-solicitation-address", "I" },
-       /*  33 */ { "static-routes", "IIA" },
-       /*  34 */ { "trailer-encapsulation", "f" },
-       /*  35 */ { "arp-cache-timeout", "L" },
-       /*  36 */ { "ieee802-3-encapsulation", "f" },
-       /*  37 */ { "default-tcp-ttl", "B" },
-       /*  38 */ { "tcp-keepalive-interval", "L" },
-       /*  39 */ { "tcp-keepalive-garbage", "f" },
-       /*  40 */ { "nis-domain", "t" },
-       /*  41 */ { "nis-servers", "IA" },
-       /*  42 */ { "ntp-servers", "IA" },
-       /*  43 */ { "vendor-encapsulated-options", "X" },
-       /*  44 */ { "netbios-name-servers", "IA" },
-       /*  45 */ { "netbios-dd-server", "IA" },
-       /*  46 */ { "netbios-node-type", "B" },
-       /*  47 */ { "netbios-scope", "t" },
-       /*  48 */ { "font-servers", "IA" },
-       /*  49 */ { "x-display-manager", "IA" },
-       /*  50 */ { "dhcp-requested-address", "I" },
-       /*  51 */ { "dhcp-lease-time", "L" },
-       /*  52 */ { "dhcp-option-overload", "B" },
-       /*  53 */ { "dhcp-message-type", "B" },
-       /*  54 */ { "dhcp-server-identifier", "I" },
-       /*  55 */ { "dhcp-parameter-request-list", "BA" },
-       /*  56 */ { "dhcp-message", "t" },
-       /*  57 */ { "dhcp-max-message-size", "S" },
-       /*  58 */ { "dhcp-renewal-time", "L" },
-       /*  59 */ { "dhcp-rebinding-time", "L" },
-       /*  60 */ { "dhcp-class-identifier", "t" },
-       /*  61 */ { "dhcp-client-identifier", "X" },
-       /*  62 */ { NULL, NULL },
-       /*  63 */ { NULL, NULL },
-       /*  64 */ { "nisplus-domain", "t" },
-       /*  65 */ { "nisplus-servers", "IA" },
-       /*  66 */ { "tftp-server-name", "t" },
-       /*  67 */ { "bootfile-name", "t" },
-       /*  68 */ { "mobile-ip-home-agent", "IA" },
-       /*  69 */ { "smtp-server", "IA" },
-       /*  70 */ { "pop-server", "IA" },
-       /*  71 */ { "nntp-server", "IA" },
-       /*  72 */ { "www-server", "IA" },
-       /*  73 */ { "finger-server", "IA" },
-       /*  74 */ { "irc-server", "IA" },
-       /*  75 */ { "streettalk-server", "IA" },
-       /*  76 */ { "streettalk-directory-assistance-server", "IA" },
-       /*  77 */ { "user-class", "t" },
-       /*  78 */ { NULL, NULL },
-       /*  79 */ { NULL, NULL },
-       /*  80 */ { NULL, NULL },
-       /*  81 */ { NULL, NULL },
-       /*  82 */ { "relay-agent-information", "X" },
-       /*  83 */ { NULL, NULL },
-       /*  84 */ { NULL, NULL },
-       /*  85 */ { "nds-servers", "IA" },
-       /*  86 */ { "nds-tree-name", "X" },
-       /*  87 */ { "nds-context", "X" },
-       /*  88 */ { NULL, NULL },
-       /*  89 */ { NULL, NULL },
-       /*  90 */ { NULL, NULL },
-       /*  91 */ { NULL, NULL },
-       /*  92 */ { NULL, NULL },
-       /*  93 */ { NULL, NULL },
-       /*  94 */ { NULL, NULL },
-       /*  95 */ { NULL, NULL },
-       /*  96 */ { NULL, NULL },
-       /*  97 */ { NULL, NULL },
-       /*  98 */ { NULL, NULL },
-       /*  99 */ { NULL, NULL },
-       /* 100 */ { NULL, NULL },
-       /* 101 */ { NULL, NULL },
-       /* 102 */ { NULL, NULL },
-       /* 103 */ { NULL, NULL },
-       /* 104 */ { NULL, NULL },
-       /* 105 */ { NULL, NULL },
-       /* 106 */ { NULL, NULL },
-       /* 107 */ { NULL, NULL },
-       /* 108 */ { NULL, NULL },
-       /* 109 */ { NULL, NULL },
-       /* 110 */ { NULL, NULL },
-       /* 111 */ { NULL, NULL },
-       /* 112 */ { NULL, NULL },
-       /* 113 */ { NULL, NULL },
-       /* 114 */ { NULL, NULL },
-       /* 115 */ { NULL, NULL },
-       /* 116 */ { NULL, NULL },
-       /* 117 */ { NULL, NULL },
-       /* 118 */ { NULL, NULL },
-       /* 119 */ { "domain-search", "D" },
-       /* 120 */ { NULL, NULL },
-       /* 121 */ { "classless-static-routes", "CIA" },
-       /* 122 */ { NULL, NULL },
-       /* 123 */ { NULL, NULL },
-       /* 124 */ { NULL, NULL },
-       /* 125 */ { NULL, NULL },
-       /* 126 */ { NULL, NULL },
-       /* 127 */ { NULL, NULL },
-       /* 128 */ { NULL, NULL },
-       /* 129 */ { NULL, NULL },
-       /* 130 */ { NULL, NULL },
-       /* 131 */ { NULL, NULL },
-       /* 132 */ { NULL, NULL },
-       /* 133 */ { NULL, NULL },
-       /* 134 */ { NULL, NULL },
-       /* 135 */ { NULL, NULL },
-       /* 136 */ { NULL, NULL },
-       /* 137 */ { NULL, NULL },
-       /* 138 */ { NULL, NULL },
-       /* 139 */ { NULL, NULL },
-       /* 140 */ { NULL, NULL },
-       /* 141 */ { NULL, NULL },
-       /* 142 */ { NULL, NULL },
-       /* 143 */ { NULL, NULL },
-       /* 144 */ { "tftp-config-file", "t" },
-       /* 145 */ { NULL, NULL },
-       /* 146 */ { NULL, NULL },
-       /* 147 */ { NULL, NULL },
-       /* 148 */ { NULL, NULL },
-       /* 149 */ { NULL, NULL },
-       /* 150 */ { "voip-configuration-server", "IA" },
-       /* 151 */ { NULL, NULL },
-       /* 152 */ { NULL, NULL },
-       /* 153 */ { NULL, NULL },
-       /* 154 */ { NULL, NULL },
-       /* 155 */ { NULL, NULL },
-       /* 156 */ { NULL, NULL },
-       /* 157 */ { NULL, NULL },
-       /* 158 */ { NULL, NULL },
-       /* 159 */ { NULL, NULL },
-       /* 160 */ { NULL, NULL },
-       /* 161 */ { NULL, NULL },
-       /* 162 */ { NULL, NULL },
-       /* 163 */ { NULL, NULL },
-       /* 164 */ { NULL, NULL },
-       /* 165 */ { NULL, NULL },
-       /* 166 */ { NULL, NULL },
-       /* 167 */ { NULL, NULL },
-       /* 168 */ { NULL, NULL },
-       /* 169 */ { NULL, NULL },
-       /* 170 */ { NULL, NULL },
-       /* 171 */ { NULL, NULL },
-       /* 172 */ { NULL, NULL },
-       /* 173 */ { NULL, NULL },
-       /* 174 */ { NULL, NULL },
-       /* 175 */ { NULL, NULL },
-       /* 176 */ { NULL, NULL },
-       /* 177 */ { NULL, NULL },
-       /* 178 */ { NULL, NULL },
-       /* 179 */ { NULL, NULL },
-       /* 180 */ { NULL, NULL },
-       /* 181 */ { NULL, NULL },
-       /* 182 */ { NULL, NULL },
-       /* 183 */ { NULL, NULL },
-       /* 184 */ { NULL, NULL },
-       /* 185 */ { NULL, NULL },
-       /* 186 */ { NULL, NULL },
-       /* 187 */ { NULL, NULL },
-       /* 188 */ { NULL, NULL },
-       /* 189 */ { NULL, NULL },
-       /* 190 */ { NULL, NULL },
-       /* 191 */ { NULL, NULL },
-       /* 192 */ { NULL, NULL },
-       /* 193 */ { NULL, NULL },
-       /* 194 */ { NULL, NULL },
-       /* 195 */ { NULL, NULL },
-       /* 196 */ { NULL, NULL },
-       /* 197 */ { NULL, NULL },
-       /* 198 */ { NULL, NULL },
-       /* 199 */ { NULL, NULL },
-       /* 200 */ { NULL, NULL },
-       /* 201 */ { NULL, NULL },
-       /* 202 */ { NULL, NULL },
-       /* 203 */ { NULL, NULL },
-       /* 204 */ { NULL, NULL },
-       /* 205 */ { NULL, NULL },
-       /* 206 */ { NULL, NULL },
-       /* 207 */ { NULL, NULL },
-       /* 208 */ { NULL, NULL },
-       /* 209 */ { NULL, NULL },
-       /* 210 */ { NULL, NULL },
-       /* 211 */ { NULL, NULL },
-       /* 212 */ { NULL, NULL },
-       /* 213 */ { NULL, NULL },
-       /* 214 */ { NULL, NULL },
-       /* 215 */ { NULL, NULL },
-       /* 216 */ { NULL, NULL },
-       /* 217 */ { NULL, NULL },
-       /* 218 */ { NULL, NULL },
-       /* 219 */ { NULL, NULL },
-       /* 220 */ { NULL, NULL },
-       /* 221 */ { NULL, NULL },
-       /* 222 */ { NULL, NULL },
-       /* 223 */ { NULL, NULL },
-       /* 224 */ { NULL, NULL },
-       /* 225 */ { NULL, NULL },
-       /* 226 */ { NULL, NULL },
-       /* 227 */ { NULL, NULL },
-       /* 228 */ { NULL, NULL },
-       /* 229 */ { NULL, NULL },
-       /* 230 */ { NULL, NULL },
-       /* 231 */ { NULL, NULL },
-       /* 232 */ { NULL, NULL },
-       /* 233 */ { NULL, NULL },
-       /* 234 */ { NULL, NULL },
-       /* 235 */ { NULL, NULL },
-       /* 236 */ { NULL, NULL },
-       /* 237 */ { NULL, NULL },
-       /* 238 */ { NULL, NULL },
-       /* 239 */ { NULL, NULL },
-       /* 240 */ { NULL, NULL },
-       /* 241 */ { NULL, NULL },
-       /* 242 */ { NULL, NULL },
-       /* 243 */ { NULL, NULL },
-       /* 244 */ { NULL, NULL },
-       /* 245 */ { NULL, NULL },
-       /* 246 */ { NULL, NULL },
-       /* 247 */ { NULL, NULL },
-       /* 248 */ { NULL, NULL },
-       /* 249 */ { "classless-ms-static-routes", "CIA" },
-       /* 250 */ { NULL, NULL },
-       /* 251 */ { NULL, NULL },
-       /* 252 */ { "autoproxy-script", "t" },
-       /* 253 */ { NULL, NULL },
-       /* 254 */ { NULL, NULL },
-       /* 255 */ { "option-end", "e" },
-};
-
-char *
-code_to_name(int code)
-{
-       static char      unknown[11];   /* "option-NNN" */
-       int              ret;
-
-       if (code < 0 || code >= DHO_COUNT)
-               return "";
-
-       if (dhcp_options[code].name != NULL)
-               return dhcp_options[code].name;
-
-       ret = snprintf(unknown, sizeof(unknown), "option-%d", code);
-       if (ret < 0 || ret >= (int)sizeof(unknown))
-               return "";
-
-       return unknown;
-}
-
-int
-name_to_code(char *name)
-{
-       char    unknown[11];    /* "option-NNN" */
-       int     code, ret;
-
-       for (code = 1; code < DHO_END; code++) {
-               if (dhcp_options[code].name == NULL) {
-                       ret = snprintf(unknown, sizeof(unknown), "option-%d",
-                           code);
-                       if (ret < 0 || ret >= (int)sizeof(unknown))
-                               return DHO_END;
-                       if (strcasecmp(unknown, name) == 0)
-                               return code;
-               } else if (strcasecmp(dhcp_options[code].name, name) == 0) {
-                       return code;
-               }
-       }
-
-       return DHO_END;
-}
-
-char *
-code_to_format(int code)
-{
-       if (code < 0 || code >= DHO_COUNT)
-               return "";
-
-       if (dhcp_options[code].format == NULL)
-               return "X";
-
-       return dhcp_options[code].format;
-}
-
-/*
- * Some option data types cannot be appended or prepended to. For
- * such options change ACTION_PREPEND to ACTION_SUPERSEDE and
- * ACTION_APPEND to ACTION_DEFAULT.
- */
-int
-code_to_action(int code, int action)
-{
-       char    *fmt;
-
-       fmt = code_to_format(code);
-       if (fmt == NULL || strpbrk(fmt, "ADtX") != NULL)
-               return action;
-
-       /*
-        * For our protection all formats which have been excluded shall be
-        * deemed included.
-        */
-       switch (action) {
-       case ACTION_APPEND:
-               action = ACTION_DEFAULT;
-               break;
-       case ACTION_PREPEND:
-               action = ACTION_SUPERSEDE;
-               break;
-       default:
-               break;
-       }
-
-       return action;
-}
-
-/*
- * Parse options out of the specified buffer, storing addresses of
- * option values in options. Return 0 if errors, 1 if not.
- */
-int
-parse_option_buffer(struct option_data *options, unsigned char *buffer,
-    int length)
-{
-       unsigned char   *s, *t, *end;
-       char            *name, *fmt;
-       int              code, len, newlen;
-
-       s = buffer;
-       end = s + length;
-       while (s < end) {
-               code = s[0];
-
-               /* End options terminate processing. */
-               if (code == DHO_END)
-                       break;
-
-               /* Pad options don't have a length - just skip them. */
-               if (code == DHO_PAD) {
-                       s++;
-                       continue;
-               }
-
-               name = code_to_name(code);
-               fmt = code_to_format(code);
-
-               /*
-                * All options other than DHO_PAD and DHO_END have a one-byte
-                * length field. It could be 0! Make sure that the length byte
-                * is present, and all the data is available.
-                */
-               if (s + 1 < end) {
-                       len = s[1];
-                       if (s + 1 + len < end) {
-                               ; /* option data is all there. */
-                       } else {
-                               log_warnx("%s: option %s (%d) larger than "
-                                   "buffer", log_procname, name, len);
-                               return 0;
-                       }
-               } else {
-                       log_warnx("%s: option %s has no length field",
-                           log_procname, name);
-                       return 0;
-               }
-
-               /*
-                * Strip trailing NULs from ascii ('t') options. RFC 2132
-                * says "Options containing NVT ASCII data SHOULD NOT include
-                * a trailing NULL; however, the receiver of such options
-                * MUST be prepared to delete trailing nulls if they exist."
-                */
-               if (fmt[0] == 't') {
-                       while (len > 0 && s[len + 1] == '\0')
-                               len--;
-               }
-
-               /*
-                * Concatenate new data + NUL to existing option data.
-                *
-                * Note that the NUL is *not* counted in the len field!
-                */
-               newlen = options[code].len + len;
-               if ((t = realloc(options[code].data, newlen + 1)) == NULL)
-                       fatal("option %s", name);
-
-               memcpy(t + options[code].len, &s[2], len);
-               t[newlen] = 0;
-
-               options[code].len = newlen;
-               options[code].data = t;
-
-               s += s[1] + 2;
-       }
-
-       return 1;
-}
-
-/*
- * Pack as many options as fit in buflen bytes of buf. Return the
- * offset of the start of the last option copied. A caller can check
- * to see if it's DHO_END to decide if all the options were copied.
- */
-int
-pack_options(unsigned char *buf, int buflen, struct option_data *options)
-{
-       int      ix, incr, length, bufix, code, lastopt = -1;
-
-       memset(buf, 0, buflen);
-
-       memcpy(buf, DHCP_OPTIONS_COOKIE, 4);
-       if (options[DHO_DHCP_MESSAGE_TYPE].data != NULL) {
-               memcpy(&buf[4], DHCP_OPTIONS_MESSAGE_TYPE, 3);
-               buf[6] = options[DHO_DHCP_MESSAGE_TYPE].data[0];
-               bufix = 7;
-       } else
-               bufix = 4;
-
-       for (code = DHO_SUBNET_MASK; code < DHO_END; code++) {
-               if (options[code].data == NULL ||
-                   code == DHO_DHCP_MESSAGE_TYPE)
-                       continue;
-
-               length = options[code].len;
-               if (bufix + length + 2*((length+254)/255) >= buflen)
-                       return lastopt;
-
-               lastopt = bufix;
-               ix = 0;
-
-               while (length) {
-                       incr = length > 255 ? 255 : length;
-
-                       buf[bufix++] = code;
-                       buf[bufix++] = incr;
-                       memcpy(buf + bufix, options[code].data + ix, incr);
-
-                       length -= incr;
-                       ix += incr;
-                       bufix += incr;
-               }
-       }
-
-       if (bufix < buflen) {
-               buf[bufix] = DHO_END;
-               lastopt = bufix;
-       }
-
-       return lastopt;
-}
-
-/*
- * Use vis() to encode characters of src and append encoded characters onto
- * dst. Also encode ", ', $, ` and \, to ensure resulting strings can be
- * represented as '"' delimited strings and safely passed to scripts. Surround
- * result with double quotes if emit_punct is true.
- */
-char *
-pretty_print_string(unsigned char *src, size_t srclen, int emit_punct)
-{
-       static char      string[8196];
-       char             visbuf[5];
-       unsigned char   *origsrc = src;
-       size_t           rslt = 0;
-
-       memset(string, 0, sizeof(string));
-
-       if (emit_punct != 0)
-               rslt = strlcat(string, "\"", sizeof(string));
-
-       for (; src < origsrc + srclen; src++) {
-               if (*src && strchr("\"'$`\\", *src))
-                       vis(visbuf, *src, VIS_ALL | VIS_OCTAL, *src+1);
-               else
-                       vis(visbuf, *src, VIS_OCTAL, *src+1);
-               rslt = strlcat(string, visbuf, sizeof(string));
-       }
-
-       if (emit_punct != 0)
-               rslt = strlcat(string, "\"", sizeof(string));
-
-       if (rslt >= sizeof(string))
-               return NULL;
-
-       return string;
-}
-
-/*
- * Must special case *_CLASSLESS_* route options due to the variable size
- * of the CIDR element in its CIA format.
- */
-void
-pretty_print_classless_routes(unsigned char *src, size_t srclen,
-    unsigned char *buf, size_t buflen)
-{
-       char             bitsbuf[5];    /* to hold "/nn " */
-       struct in_addr   dest, netmask, gateway;
-       unsigned int     bits, i, len;
-       uint32_t         m;
-       int              rslt;
-
-       i = 0;
-       while (i < srclen) {
-               len = extract_route(&src[i], srclen - i, &dest.s_addr,
-                   &netmask.s_addr, &gateway.s_addr);
-               if (len == 0)
-                       goto bad;
-               i += len;
-
-               m = ntohl(netmask.s_addr);
-               bits = 32;
-               while ((bits > 0) && ((m & 1) == 0)) {
-                       m >>= 1;
-                       bits--;
-               }
-
-               rslt = snprintf(bitsbuf, sizeof(bitsbuf), "/%d ", bits);
-               if (rslt < 0 || (unsigned int)rslt >= sizeof(bitsbuf))
-                       goto bad;
-
-               if (strlen(buf) > 0)
-                       strlcat(buf, ", ", buflen);
-               strlcat(buf, inet_ntoa(dest), buflen);
-               strlcat(buf, bitsbuf, buflen);
-               if (strlcat(buf, inet_ntoa(gateway), buflen) >= buflen)
-                       goto bad;
-       }
-
-       return;
-
-bad:
-       memset(buf, 0, buflen);
-}
-
-/*
- * Print string containing blank separated list of domain names
- * as a comma separated list of double-quote delimited strings.
- *
- * e.g.  "eng.apple.com. marketing.apple.com."
- *
- * will be translated to
- *
- * "eng.apple.com.", "marketing.apple.com."
- */
-void
-pretty_print_domain_list(unsigned char *src, size_t srclen,
-    unsigned char *buf, size_t buflen)
-{
-       char    *dupnames, *hn, *inputstring;
-       int      count;
-
-       memset(buf, 0, buflen);
-
-       /*
-        * N.B.: option data is *NOT* guaranteed to be NUL
-        *       terminated. Avoid strlen(), strdup(), etc.!
-        */
-       if (srclen >= DHCP_DOMAIN_SEARCH_LEN || src[0] == '\0')
-               return;
-
-       inputstring = malloc(srclen + 1);
-       if (inputstring == NULL)
-               fatal("domain name list");
-       memcpy(inputstring, src, srclen);
-       inputstring[srclen] = '\0';
-       dupnames = inputstring;
-
-       count = 0;
-       while ((hn = strsep(&inputstring, " \t")) != NULL) {
-               if (strlen(hn) == 0)
-                       continue;
-               if (res_hnok(hn) == 0)
-                       goto bad;
-               if (count > 0)
-                       strlcat(buf, ", ", buflen);
-               strlcat(buf, "\"", buflen);
-               strlcat(buf, hn, buflen);
-               if (strlcat(buf, "\"", buflen) >= buflen)
-                       goto bad;
-               count++;
-               if (count > DHCP_DOMAIN_SEARCH_CNT)
-                       goto bad;
-       }
-
-       free(dupnames);
-       return;
-
-bad:
-       free(dupnames);
-       memset(buf, 0, buflen);
-}
-
-/*
- * Format the specified option so that a human can easily read it.
- */
-char *
-pretty_print_option(unsigned int code, struct option_data *option,
-    int emit_punct)
-{
-       static char      optbuf[8192]; /* XXX */
-       char             fmtbuf[32];
-       struct in_addr   foo;
-       unsigned char   *data = option->data;
-       unsigned char   *dp = data;
-       char            *op = optbuf, *buf, *name, *fmt;
-       int              hunksize = 0, numhunk = -1, numelem = 0;
-       int              i, j, k, opleft = sizeof(optbuf);
-       int              len = option->len;
-       int              opcount = 0;
-       int32_t          int32val;
-       uint32_t         uint32val;
-       uint16_t         uint16val;
-       char             comma;
-
-       memset(optbuf, 0, sizeof(optbuf));
-
-       /* Code should be between 0 and 255. */
-       if (code > 255) {
-               log_warnx("%s: pretty_print_option: bad code %d", log_procname,
-                   code);
-               goto done;
-       }
-
-       if (emit_punct != 0)
-               comma = ',';
-       else
-               comma = ' ';
-
-       /* Handle the princess class options with weirdo formats. */
-       switch (code) {
-       case DHO_CLASSLESS_STATIC_ROUTES:
-       case DHO_CLASSLESS_MS_STATIC_ROUTES:
-               pretty_print_classless_routes(dp, len, optbuf, sizeof(optbuf));
-               goto done;
-       case DHO_DOMAIN_SEARCH:
-               pretty_print_domain_list(dp, len, optbuf, sizeof(optbuf));
-               goto done;
-       default:
-               break;
-       }
-
-       name = code_to_name(code);
-       fmt = code_to_format(code);
-
-       /* Figure out the size of the data. */
-       for (i = 0; fmt[i]; i++) {
-               if (numhunk == 0) {
-                       log_warnx("%s: %s: excess information in format "
-                           "string: %s", log_procname, name, &fmt[i]);
-                       goto done;
-               }
-               numelem++;
-               fmtbuf[i] = fmt[i];
-               switch (fmt[i]) {
-               case 'A':
-                       --numelem;
-                       fmtbuf[i] = 0;
-                       numhunk = 0;
-                       if (hunksize == 0) {
-                               log_warnx("%s: %s: no size indicator before A"
-                                   " in format string: %s", log_procname,
-                                   name, fmt);
-                               goto done;
-                       }
-                       break;
-               case 'X':
-                       for (k = 0; k < len; k++)
-                               if (isascii(data[k]) == 0 ||
-                                   isprint(data[k]) == 0)
-                                       break;
-                       if (k == len) {
-                               fmtbuf[i] = 't';
-                               numhunk = -2;
-                       } else {
-                               hunksize++;
-                               comma = ':';
-                               numhunk = 0;
-                       }
-                       fmtbuf[i + 1] = 0;
-                       break;
-               case 't':
-                       fmtbuf[i + 1] = 0;
-                       numhunk = -2;
-                       break;
-               case 'I':
-               case 'l':
-               case 'L':
-                       hunksize += 4;
-                       break;
-               case 'S':
-                       hunksize += 2;
-                       break;
-               case 'B':
-               case 'f':
-                       hunksize++;
-                       break;
-               case 'e':
-                       break;
-               default:
-                       log_warnx("%s: %s: garbage in format string: %s",
-                           log_procname, name, &fmt[i]);
-                       goto done;
-               }
-       }
-
-       /* Check for too few bytes. */
-       if (hunksize > len) {
-               log_warnx("%s: %s: expecting at least %d bytes; got %d",
-                   log_procname, name, hunksize, len);
-               goto done;
-       }
-       /* Check for too many bytes. */
-       if (numhunk == -1 && hunksize < len) {
-               log_warnx("%s: %s: expecting only %d bytes: got %d",
-                   log_procname, name, hunksize, len);
-               goto done;
-       }
-
-       /* If this is an array, compute its size. */
-       if (numhunk == 0)
-               numhunk = len / hunksize;
-       /* See if we got an exact number of hunks. */
-       if (numhunk > 0 && numhunk * hunksize != len) {
-               log_warnx("%s: %s: expecting %d bytes: got %d", log_procname,
-                   name, numhunk * hunksize, len);
-               goto done;
-       }
-
-       /* A one-hunk array prints the same as a single hunk. */
-       if (numhunk < 0)
-               numhunk = 1;
-
-       /* Cycle through the array (or hunk) printing the data. */
-       for (i = 0; i < numhunk; i++) {
-               for (j = 0; j < numelem; j++) {
-                       switch (fmtbuf[j]) {
-                       case 't':
-                               buf = pretty_print_string(dp, len, emit_punct);
-                               if (buf == NULL)
-                                       opcount = -1;
-                               else
-                                       opcount = strlcat(op, buf, opleft);
-                               break;
-                       case 'I':
-                               memcpy(&foo.s_addr, dp, sizeof(foo.s_addr));
-                               opcount = snprintf(op, opleft, "%s",
-                                   inet_ntoa(foo));
-                               dp += sizeof(foo.s_addr);
-                               break;
-                       case 'l':
-                               memcpy(&int32val, dp, sizeof(int32val));
-                               opcount = snprintf(op, opleft, "%d",
-                                   ntohl(int32val));
-                               dp += sizeof(int32val);
-                               break;
-                       case 'L':
-                               memcpy(&uint32val, dp, sizeof(uint32val));
-                               opcount = snprintf(op, opleft, "%u",
-                                   ntohl(uint32val));
-                               dp += sizeof(uint32val);
-                               break;
-                       case 'S':
-                               memcpy(&uint16val, dp, sizeof(uint16val));
-                               opcount = snprintf(op, opleft, "%hu",
-                                   ntohs(uint16val));
-                               dp += sizeof(uint16val);
-                               break;
-                       case 'B':
-                               opcount = snprintf(op, opleft, "%u", *dp);
-                               dp++;
-                               break;
-                       case 'X':
-                               opcount = snprintf(op, opleft, "%x", *dp);
-                               dp++;
-                               break;
-                       case 'f':
-                               opcount = snprintf(op, opleft, "%s",
-                                   *dp ? "true" : "false");
-                               dp++;
-                               break;
-                       default:
-                               log_warnx("%s: unexpected format code %c",
-                                   log_procname, fmtbuf[j]);
-                               goto toobig;
-                       }
-                       if (opcount < 0 || opcount >= opleft)
-                               goto toobig;
-                       opleft -= opcount;
-                       op += opcount;
-                       if (j + 1 < numelem && comma != ':') {
-                               opcount = snprintf(op, opleft, " ");
-                               if (opcount < 0 || opcount >= opleft)
-                                       goto toobig;
-                               opleft -= opcount;
-                               op += opcount;
-                       }
-               }
-               if (i + 1 < numhunk) {
-                       opcount = snprintf(op, opleft, "%c", comma);
-                       if (opcount < 0 || opcount >= opleft)
-                               goto toobig;
-                       opleft -= opcount;
-                       op += opcount;
-               }
-       }
-
-done:
-       return optbuf;
-
-toobig:
-       memset(optbuf, 0, sizeof(optbuf));
-       return optbuf;
-}
-
-struct option_data *
-unpack_options(struct dhcp_packet *packet)
-{
-       static struct option_data        options[DHO_COUNT];
-       int                              i;
-
-       for (i = 0; i < DHO_COUNT; i++) {
-               free(options[i].data);
-               options[i].data = NULL;
-               options[i].len = 0;
-       }
-
-       if (memcmp(&packet->options, DHCP_OPTIONS_COOKIE, 4) == 0) {
-               /* Parse the BOOTP/DHCP options field. */
-               parse_option_buffer(options, &packet->options[4],
-                   sizeof(packet->options) - 4);
-
-               /* DHCP packets can also use overload areas for options. */
-               if (options[DHO_DHCP_MESSAGE_TYPE].data != NULL &&
-                   options[DHO_DHCP_OPTION_OVERLOAD].data != NULL) {
-                       if ((options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 1) !=
-                           0)
-                               parse_option_buffer(options,
-                                   (unsigned char *)packet->file,
-                                   sizeof(packet->file));
-                       if ((options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 2) !=
-                           0)
-                               parse_option_buffer(options,
-                                   (unsigned char *)packet->sname,
-                                   sizeof(packet->sname));
-               }
-       }
-
-       return options;
-}
-
-void
-merge_option_data(char *fmt, struct option_data *first,
-    struct option_data *second, struct option_data *dest)
-{
-       int space = 0;
-
-       free(dest->data);
-       dest->data = NULL;
-       dest->len = first->len + second->len;
-       if (dest->len == 0)
-               return;
-
-       /*
-        * N.B.: option data is *NOT* guaranteed to be NUL
-        *       terminated. Avoid strlen(), strdup(), etc.!
-        */
-       if (fmt[0] == 'D') {
-               if (first->len > 0 && second->len > 0)
-                       space = 1;
-       }
-
-       dest->len += space;
-       dest->data = malloc(dest->len);
-       if (dest->data == NULL)
-               fatal("merged option data");
-
-       memcpy(dest->data, first->data, first->len);
-       if (space == 1)
-               dest->data[first->len] = ' ';
-       memcpy(dest->data + first->len + space, second->data, second->len);
-}
diff --git a/sbin/dhclient/packet.c b/sbin/dhclient/packet.c
deleted file mode 100644 (file)
index 8b4afbc..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-/*     $OpenBSD: packet.c,v 1.45 2021/02/22 23:43:59 jsg Exp $ */
-
-/* Packet assembly code, originally contributed by Archie Cobbs. */
-
-/*
- * Copyright (c) 1995, 1996, 1999 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#include <sys/queue.h>
-#include <sys/socket.h>
-
-#include <net/if.h>
-
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/udp.h>
-#include <netinet/if_ether.h>
-
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "dhcp.h"
-#include "dhcpd.h"
-#include "log.h"
-
-uint32_t
-checksum(unsigned char *buf, uint32_t nbytes, uint32_t sum)
-{
-       unsigned int     i;
-
-       /* Checksum all the pairs of bytes first. */
-       for (i = 0; i < (nbytes & ~1U); i += 2) {
-               sum += (uint16_t)ntohs(*((uint16_t *)(buf + i)));
-               if (sum > 0xFFFF)
-                       sum -= 0xFFFF;
-       }
-
-       /*
-        * If there's a single byte left over, checksum it, too.
-        * Network byte order is big-endian, so the remaining byte is
-        * the high byte.
-        */
-       if (i < nbytes) {
-               sum += buf[i] << 8;
-               if (sum > 0xFFFF)
-                       sum -= 0xFFFF;
-       }
-
-       return sum;
-}
-
-uint32_t
-wrapsum(uint32_t sum)
-{
-       sum = ~sum & 0xFFFF;
-       return htons(sum);
-}
-
-void
-assemble_eh_header(struct ether_addr shost, struct ether_header *eh)
-{
-       memset(eh->ether_dhost, 0xff, sizeof(eh->ether_dhost));
-
-       memcpy(eh->ether_shost, shost.ether_addr_octet,
-           sizeof(eh->ether_shost));
-
-       eh->ether_type = htons(ETHERTYPE_IP);
-}
-
-ssize_t
-decode_udp_ip_header(unsigned char *buf, uint32_t buflen,
-    struct sockaddr_in *from)
-{
-       static int       ip_packets_seen;
-       static int       ip_packets_bad_checksum;
-       static int       udp_packets_seen;
-       static int       udp_packets_bad_checksum;
-       static int       udp_packets_length_checked;
-       static int       udp_packets_length_overflow;
-       struct ip       *ip;
-       struct udphdr   *udp;
-       unsigned char   *data;
-       int              len;
-       uint32_t         ip_len;
-       uint32_t         sum, usum;
-
-       /* Assure that an entire IP header is within the buffer. */
-       if (sizeof(*ip) > buflen)
-               return -1;
-       ip_len = (*buf & 0xf) << 2;
-       if (ip_len > buflen)
-               return -1;
-       ip = (struct ip *)(buf);
-       ip_packets_seen++;
-
-       /* Check the IP header checksum - it should be zero. */
-       if (wrapsum(checksum((unsigned char *)ip, ip_len, 0)) != 0) {
-               ip_packets_bad_checksum++;
-               if (ip_packets_seen > 4 && ip_packets_bad_checksum != 0 &&
-                   (ip_packets_seen / ip_packets_bad_checksum) < 2) {
-                       log_debug("%s: %d bad IP checksums seen in %d packets",
-                           log_procname, ip_packets_bad_checksum,
-                           ip_packets_seen);
-                       ip_packets_seen = ip_packets_bad_checksum = 0;
-               }
-               return -1;
-       }
-
-       memcpy(&from->sin_addr, &ip->ip_src, sizeof(from->sin_addr));
-
-       if (ntohs(ip->ip_len) != buflen)
-               log_debug("%s: ip length %hu disagrees with bytes received %d",
-                   log_procname, ntohs(ip->ip_len), buflen);
-
-       /* Assure that the entire IP packet is within the buffer. */
-       if (ntohs(ip->ip_len) > buflen)
-               return -1;
-
-       /* Assure that the UDP header is within the buffer. */
-       if (ip_len + sizeof(*udp) > buflen)
-               return -1;
-       udp = (struct udphdr *)(buf + ip_len);
-       udp_packets_seen++;
-
-       /* Assure that the entire UDP packet is within the buffer. */
-       if (ip_len + ntohs(udp->uh_ulen) > buflen)
-               return -1;
-       data = buf + ip_len + sizeof(*udp);
-
-       /*
-        * Compute UDP checksums, including the ``pseudo-header'', the
-        * UDP header and the data. If the UDP checksum field is zero,
-        * we're not supposed to do a checksum.
-        */
-       udp_packets_length_checked++;
-       len = ntohs(udp->uh_ulen) - sizeof(*udp);
-       if ((len < 0) || (len + data > buf + buflen)) {
-               udp_packets_length_overflow++;
-               if (udp_packets_length_checked > 4 &&
-                   udp_packets_length_overflow != 0 &&
-                   (udp_packets_length_checked /
-                   udp_packets_length_overflow) < 2) {
-                       log_debug("%s: %d udp packets in %d too long - dropped",
-                           log_procname, udp_packets_length_overflow,
-                           udp_packets_length_checked);
-                       udp_packets_length_overflow =
-                           udp_packets_length_checked = 0;
-               }
-               return -1;
-       }
-       if (len + data != buf + buflen)
-               log_debug("%s: accepting packet with data after udp payload",
-                   log_procname);
-
-       usum = udp->uh_sum;
-       udp->uh_sum = 0;
-
-       sum = wrapsum(checksum((unsigned char *)udp, sizeof(*udp),
-           checksum(data, len, checksum((unsigned char *)&ip->ip_src,
-           2 * sizeof(ip->ip_src),
-           IPPROTO_UDP + (uint32_t)ntohs(udp->uh_ulen)))));
-
-       udp_packets_seen++;
-       if (usum != 0 && usum != sum) {
-               udp_packets_bad_checksum++;
-               if (udp_packets_seen > 4 && udp_packets_bad_checksum != 0 &&
-                   (udp_packets_seen / udp_packets_bad_checksum) < 2) {
-                       log_debug("%s: %d bad udp checksums in %d packets",
-                           log_procname, udp_packets_bad_checksum,
-                           udp_packets_seen);
-                       udp_packets_seen = udp_packets_bad_checksum = 0;
-               }
-               return -1;
-       }
-
-       memcpy(&from->sin_port, &udp->uh_sport, sizeof(udp->uh_sport));
-
-       return ip_len + sizeof(*udp);
-}
diff --git a/sbin/dhclient/parse.c b/sbin/dhclient/parse.c
deleted file mode 100644 (file)
index fd0f7cb..0000000
+++ /dev/null
@@ -1,300 +0,0 @@
-/*     $OpenBSD: parse.c,v 1.83 2019/07/22 17:20:06 krw Exp $  */
-
-/* Common parser code for dhcpd and dhclient. */
-
-/*
- * Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- *    of its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
- * Enterprises.  To learn more about the Internet Software Consortium,
- * see ``http://www.vix.com/isc''.  To learn more about Vixie
- * Enterprises, see ``http://www.vix.com''.
- */
-
-#include <sys/queue.h>
-#include <sys/socket.h>
-
-#include <net/if.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include <errno.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <syslog.h>
-#include <unistd.h>
-#include <vis.h>
-
-#include "dhcp.h"
-#include "dhcpd.h"
-#include "dhctoken.h"
-#include "log.h"
-
-/*
- * Skip to the semicolon ending the current statement.   If we encounter
- * braces, the matching closing brace terminates the statement.   If we
- * encounter a right brace but haven't encountered a left brace, return
- * leaving the brace in the token buffer for the caller.   If we see a
- * semicolon and haven't seen a left brace, return.   This lets us skip
- * over:
- *
- *     statement;
- *     statement foo bar { }
- *     statement foo bar { statement { } }
- *     statement}
- *
- *     ...et cetera.
- */
-void
-skip_to_semi(FILE *cfile)
-{
-       int              token;
-       int              brace_count = 0;
-
-       do {
-               token = peek_token(NULL, cfile);
-               if (token == '}') {
-                       if (brace_count > 0) {
-                               if (--brace_count == 0) {
-                                       token = next_token(NULL, cfile);
-                                       return;
-                               }
-                       } else
-                               return;
-               } else if (token == '{') {
-                       brace_count++;
-               } else if (token == ';' && brace_count == 0) {
-                       token = next_token(NULL, cfile);
-                       return;
-               }
-               token = next_token(NULL, cfile);
-       } while (token != EOF);
-}
-
-int
-parse_semi(FILE *cfile)
-{
-       int token;
-
-       token = next_token(NULL, cfile);
-       if (token == ';')
-               return 1;
-
-       parse_warn("expecting semicolon.");
-       skip_to_semi(cfile);
-
-       return 0;
-}
-
-int
-parse_string(FILE *cfile, char **string)
-{
-       static char      unvisbuf[1500];
-       char            *val;
-       int              i, token;
-
-       token = next_token(&val, cfile);
-       if (token == TOK_STRING) {
-               i = strnunvis(unvisbuf, val, sizeof(unvisbuf));
-               if (i >= 0) {
-                       *string = strdup(unvisbuf);
-                       if (*string == NULL)
-                               fatal("strdup(unvisbuf)");
-                       return 1;
-               }
-       }
-
-       parse_warn("expecting string.");
-
-       if (token != ';')
-               skip_to_semi(cfile);
-
-       return 0;
-}
-
-/*
- * cidr :== ip-address "/" bit-count
- * ip-address :== NUMBER [ DOT NUMBER [ DOT NUMBER [ DOT NUMBER ] ] ]
- * bit-count :== 0..32
- */
-int
-parse_cidr(FILE *cfile, unsigned char *cidr)
-{
-       uint8_t          buf[5];
-       const char      *errstr;
-       char            *val;
-       long long        numval;
-       unsigned int     i;
-       int              token;
-
-       memset(buf, 0, sizeof(buf));
-       i = 1;  /* Last four octets hold subnet, first octet the # of bits. */
-       do {
-               token = next_token(&val, cfile);
-               if (i == 0)
-                       numval = strtonum(val, 0, 32, &errstr);
-               else
-                       numval = strtonum(val, 0, UINT8_MAX, &errstr);
-               if (errstr != NULL)
-                       break;
-               buf[i++] = numval;
-               if (i == 1) {
-                       memcpy(cidr, buf, sizeof(buf)); /* XXX Need cidr_t */
-                       return 1;
-               }
-               token = next_token(NULL, cfile);
-               if (token == '/')
-                       i = 0;
-               if (i == sizeof(buf))
-                       break;
-       } while (token == '.' || token == '/');
-
-       parse_warn("expecting IPv4 CIDR block.");
-
-       if (token != ';')
-               skip_to_semi(cfile);
-
-       return 0;
-}
-
-int
-parse_ip_addr(FILE *cfile, struct in_addr *addr)
-{
-       struct in_addr   buf;
-       const char      *errstr;
-       char            *val;
-       long long        numval;
-       unsigned int     i;
-       int              token;
-
-       i = 0;
-       do {
-               token = next_token(&val, cfile);
-               numval = strtonum(val, 0, UINT8_MAX, &errstr);
-               if (errstr != NULL)
-                       break;
-               ((uint8_t *)&buf)[i++] = numval;
-               if (i == sizeof(buf)) {
-                       memcpy(addr, &buf, sizeof(*addr));
-                       return 1;
-               }
-               token = next_token(NULL, cfile);
-       } while (token == '.');
-
-       parse_warn("expecting IPv4 address.");
-
-       if (token != ';')
-               skip_to_semi(cfile);
-
-       return 0;
-}
-
-int
-parse_boolean(FILE *cfile, unsigned char *buf)
-{
-       char    *val;
-       int      token;
-
-       token = next_token(&val, cfile);
-       if (is_identifier(token) != 0) {
-               if (strcasecmp(val, "true") == 0 ||
-                   strcasecmp(val, "on") == 0) {
-                       buf[0] = 1;
-                       return 1;
-               }
-               if (strcasecmp(val, "false") == 0 ||
-                   strcasecmp(val, "off") == 0) {
-                       buf[0] = 0;
-                       return 1;
-               }
-       }
-
-       parse_warn("expecting boolean.");
-       if (token != ';')
-               skip_to_semi(cfile);
-
-       return 0;
-}
-
-int
-parse_number(FILE *cfile, long long *number, long long low, long long high)
-{
-       const char      *errstr;
-       char            *val, *msg;
-       int              rslt, token;
-       long long        numval;
-
-       token = next_token(&val, cfile);
-
-       numval = strtonum(val, low, high, &errstr);
-       if (errstr == NULL) {
-               *number = numval;
-               return 1;
-       }
-
-       rslt = asprintf(&msg, "expecting integer between %lld and %lld", low,
-           high);
-       if (rslt != -1) {
-               parse_warn(msg);
-               free(msg);
-       }
-
-       if (token != ';')
-               skip_to_semi(cfile);
-
-       return 0;
-}
-
-void
-parse_warn(char *msg)
-{
-       static char      spaces[81];
-       unsigned int     i;
-
-       log_warnx("%s: %s line %d: %s", log_procname, tlname, lexline, msg);
-       log_warnx("%s: %s", log_procname, token_line);
-       if ((unsigned int)lexchar < sizeof(spaces)) {
-               memset(spaces, 0, sizeof(spaces));
-               for (i = 0; (int)i < lexchar - 1; i++) {
-                       if (token_line[i] == '\t')
-                               spaces[i] = '\t';
-                       else
-                               spaces[i] = ' ';
-               }
-               log_warnx("%s: %s^", log_procname, spaces);
-       }
-}
diff --git a/sbin/dhclient/privsep.c b/sbin/dhclient/privsep.c
deleted file mode 100644 (file)
index dfddbe6..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*     $OpenBSD: privsep.c,v 1.79 2020/11/21 18:34:25 krw Exp $ */
-
-/*
- * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE, ABUSE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/queue.h>
-#include <sys/socket.h>
-
-#include <net/if.h>
-#include <net/route.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include <errno.h>
-#include <imsg.h>
-#include <resolv.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "dhcp.h"
-#include "dhcpd.h"
-#include "log.h"
-#include "privsep.h"
-
-void
-dispatch_imsg(char *name, int rdomain, int ioctlfd, int routefd,
-    struct imsgbuf *ibuf)
-{
-       static char     *resolv_conf;
-       static int       lastidx;
-       struct imsg      imsg;
-       ssize_t          n;
-       int              index;
-
-       index = if_nametoindex(name);
-       if (index == 0) {
-               log_warnx("%s: unknown interface", log_procname);
-               quit = TERMINATE;
-               return;
-       }
-
-       for (;;) {
-               if ((n = imsg_get(ibuf, &imsg)) == -1)
-                       fatal("imsg_get");
-
-               if (n == 0)
-                       break;
-
-               switch (imsg.hdr.type) {
-               case IMSG_REVOKE:
-                       if (imsg.hdr.len != IMSG_HEADER_SIZE +
-                           sizeof(struct proposal))
-                               log_warnx("%s: bad IMSG_REVOKE",
-                                   log_procname);
-                       else
-                               priv_revoke_proposal(name, ioctlfd, imsg.data,
-                                   &resolv_conf);
-                       break;
-
-               case IMSG_PROPOSE:
-                       if (imsg.hdr.len < IMSG_HEADER_SIZE +
-                           sizeof(struct proposal))
-                               log_warnx("%s: bad IMSG_PROPOSE",
-                                   log_procname);
-                       else {
-                               priv_propose(name, ioctlfd, imsg.data,
-                                   imsg.hdr.len - IMSG_HEADER_SIZE - sizeof(struct proposal),
-                                   &resolv_conf, routefd, rdomain, index, &lastidx);
-                       }
-                       break;
-
-               case IMSG_WRITE_RESOLV_CONF:
-                       if (imsg.hdr.len != IMSG_HEADER_SIZE)
-                               log_warnx("%s: bad IMSG_WRITE_RESOLV_CONF",
-                                   log_procname);
-                       else
-                               priv_write_resolv_conf(index, routefd, rdomain,
-                                   resolv_conf, &lastidx);
-                       break;
-
-               case IMSG_TELL_UNWIND:
-                       if (imsg.hdr.len != IMSG_HEADER_SIZE +
-                           sizeof(struct unwind_info))
-                               log_warnx("%s: bad IMSG_TELL_UNWIND",
-                                   log_procname);
-                       else
-                               priv_tell_unwind(index, routefd, rdomain, imsg.data);
-                       break;
-
-               default:
-                       log_warnx("%s: received unknown message, code %u",
-                           log_procname, imsg.hdr.type);
-               }
-
-               imsg_free(&imsg);
-       }
-}
diff --git a/sbin/dhclient/privsep.h b/sbin/dhclient/privsep.h
deleted file mode 100644 (file)
index 84a40a0..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*     $OpenBSD: privsep.h,v 1.70 2020/11/21 18:34:25 krw Exp $ */
-
-/*
- * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE, ABUSE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-enum imsg_code {
-       IMSG_NONE,
-       IMSG_REVOKE,
-       IMSG_WRITE_RESOLV_CONF,
-       IMSG_PROPOSE,
-       IMSG_TELL_UNWIND
-};
-
-struct proposal {
-       struct in_addr  address;
-       struct in_addr  netmask;
-       unsigned int    routes_len;
-       unsigned int    domains_len;
-       unsigned int    ns_len;
-       int             mtu;
-};
-
-struct unwind_info {
-       in_addr_t       ns[MAXNS];
-       unsigned int    count;
-};
-
-void   dispatch_imsg(char *, int, int, int, struct imsgbuf *);
-
-void   priv_write_resolv_conf(int, int, int, char *, int *);
-void   priv_propose(char *, int, struct proposal *, size_t, char **, int, int,
-    int, int *);
-
-void   priv_revoke_proposal(char *, int, struct proposal *, char **);
-
-void   priv_tell_unwind(int, int, int, struct unwind_info *);