]> Zhao Yanbai Git Server - minix.git/commitdiff
Retire MINIX dhcpd(8) 39/3439/1
authorDavid van Moolenbroek <david@minix3.org>
Tue, 14 Feb 2017 17:50:02 +0000 (17:50 +0000)
committerDavid van Moolenbroek <david@minix3.org>
Thu, 9 Mar 2017 23:40:02 +0000 (23:40 +0000)
Change-Id: I4b8c738b6176ce390a7a7817b0dcaf9caffe636c

20 files changed:
distrib/sets/lists/minix-base/mi
distrib/sets/lists/minix-debug/mi
distrib/sets/lists/minix-man/mi
etc/Makefile
etc/usr/dhcptags.conf [deleted file]
lib/libc/gen/Makefile.inc
minix/commands/Makefile
minix/commands/dhcpd/Makefile [deleted file]
minix/commands/dhcpd/arp.h [deleted file]
minix/commands/dhcpd/devices.c [deleted file]
minix/commands/dhcpd/dhcp.conf.5 [deleted file]
minix/commands/dhcpd/dhcpd.8 [deleted file]
minix/commands/dhcpd/dhcpd.c [deleted file]
minix/commands/dhcpd/dhcpd.h [deleted file]
minix/commands/dhcpd/ether.c [deleted file]
minix/commands/dhcpd/tags.c [deleted file]
minix/include/minix/paths.h
minix/lib/libc/gen/dhcp_gettag.c [deleted file]
minix/lib/libc/gen/dhcp_settag.c [deleted file]
minix/man/man5/configfile.5

index 7a2e75228546106464cafc5479e8592846b356db..65f5a8555c97e20707f656a7f1570e5b0dc188d6 100644 (file)
 ./usr/bin/deroff                                        minix-base
 ./usr/bin/devmand                                       minix-base
 ./usr/bin/devsize                                       minix-base
-./usr/bin/dhcpd                                         minix-base
+./usr/bin/dhcpd                                         minix-base      obsolete
 ./usr/bin/dhrystone                                     minix-base
 ./usr/bin/diff                                          minix-base
 ./usr/bin/dirname                                       minix-base
 ./usr/bin/znew                                          minix-base
 ./usr/etc                                               minix-base
 ./usr/etc/daily                                         minix-base
-./usr/etc/dhcptags.conf                                 minix-base
+./usr/etc/dhcptags.conf                                 minix-base      obsolete
 ./usr/etc/rc                                            minix-base
 ./usr/include/c++                                       minix-base      gcc=5
 ./usr/include/c++/experimental                          minix-base      gcc=5
index 0a3fdd67471057331f0ed3f599acd15b78f91e2f..ddaf06aa9912c46f219c432150fd814835cfe64b 100644 (file)
 ./usr/libdata/debug/usr/bin/deroff.debug                minix-debug     debug
 ./usr/libdata/debug/usr/bin/devmand.debug               minix-debug     debug
 ./usr/libdata/debug/usr/bin/devsize.debug               minix-debug     debug
-./usr/libdata/debug/usr/bin/dhcpd.debug                 minix-debug     debug
+./usr/libdata/debug/usr/bin/dhcpd.debug                 minix-debug     debug,obsolete
 ./usr/libdata/debug/usr/bin/dhrystone.debug             minix-debug     debug
 ./usr/libdata/debug/usr/bin/diff.debug                  minix-debug     debug
 ./usr/libdata/debug/usr/bin/dirname.debug               minix-debug     debug
index 651b925f4e19509b25c03fc7fb18f3d01cc52787..22892fd3de465508d3616539ec31ba4f932ce0da 100644 (file)
 ./usr/man/man5/configfile.5                             minix-man
 ./usr/man/man5/cpio.5                                   minix-man
 ./usr/man/man5/crontab.5                                minix-man
-./usr/man/man5/dhcp.conf.5                              minix-man
+./usr/man/man5/dhcp.conf.5                              minix-man       obsolete
 ./usr/man/man5/dir.5                                    minix-man       obsolete
 ./usr/man/man5/editrc.5                                 minix-man
 ./usr/man/man5/ethers.5                                 minix-man
 ./usr/man/man8/cron.8                                   minix-man
 ./usr/man/man8/dev_mkdb.8                               minix-man
 ./usr/man/man8/devsize.8                                minix-man
-./usr/man/man8/dhcpd.8                                  minix-man
+./usr/man/man8/dhcpd.8                                  minix-man       obsolete
 ./usr/man/man8/diskctl.8                                minix-man
 ./usr/man/man8/fbdctl.8                                 minix-man
 ./usr/man/man8/fdisk.8                                  minix-man
index e25a70daeed568845415e7d95392b2279d3db8f0..d1fcd01990485a73addce7a512520db022dd4b07 100644 (file)
@@ -458,7 +458,6 @@ install-etc-files-safe: .PHONY .MAKE check_DESTDIR MAKEDEV
 .else # LSC Minix Specific
 .for owner group mode sdir tdir files in \
                ${BINOWN} ${BINGRP}     ${BINMODE}      ${NETBSDSRCDIR}/etc/usr/ ${DESTDIR}/usr/etc/ daily \
-               ${BINOWN} ${BINGRP}     ${BINMODE}      ${NETBSDSRCDIR}/etc/usr/ ${DESTDIR}/usr/etc/ dhcptags.conf \
                ${BINOWN} ${BINGRP}     ${BINMODE}      ${NETBSDSRCDIR}/etc/usr/ ${DESTDIR}/usr/etc/ rc \
                ${BINOWN} ${BINGRP}     ${BINMODE}      ${NETBSDSRCDIR}/etc/ ${DESTDIR}/usr/lib/ crontab \
                ${BINOWN} ${BINGRP}     ${BINMODE}      ${NETBSDSRCDIR}/etc/ ${DESTDIR}/etc/ system.conf \
diff --git a/etc/usr/dhcptags.conf b/etc/usr/dhcptags.conf
deleted file mode 100644 (file)
index e649b46..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-# A list of all tags mentioned in RFC-1533.
-
-tag 1 netmask ip 1 1;
-tag 2 zoneoffset number 4 1;
-tag 3 gateway ip 1 0;
-tag 4 timeserver ip 1 0;
-tag 5 nameserver ip 1 0;
-tag 6 DNSserver ip 1 0;
-tag 7 logserver ip 1 0;
-tag 8 cookieserver ip 1 0;
-tag 9 LPR ip 1 0;
-tag 10 impress ip 1 0;
-tag 11 resource ip 1 0;
-tag 12 hostname ascii 1 0;
-tag 13 bootfilesize number 2 1;
-tag 14 coredump ip 1 0;
-tag 15 domain ascii 1 0;
-tag 16 swapserver ip 1 1;
-tag 17 rootpath ascii 1 0;
-tag 18 extensions ascii 1 0;
-tag 19 IPforwarding boolean 1 1;
-tag 20 IPnonlocalsource boolean 1 1;
-tag 21 IPpolicyfilter ip 2 0;
-tag 22 IPmaxreassembly number 2 1;
-tag 23 IPTTL number 1 1;
-tag 24 IPMTUaging number 4 1;
-tag 25 IPMTUplateau number 2 0;
-tag 26 IPMTU number 2 1;
-tag 27 IPsublocal boolean 1 1;
-tag 28 IPbroadcast ip 1 1;
-tag 29 IPmaskdiscovery boolean 1 1;
-tag 30 IPmasksupplier boolean 1 1;
-tag 31 IPdiscovery boolean 1 1;
-tag 32 IPsolicitation ip 1 1;
-tag 33 IPstaticroute ip 2 0;
-tag 34 ARPtrailer boolean 1 1;
-tag 35 ARPtimeout number 4 1;
-tag 36 ETHencapsulation boolean 1 1;
-tag 37 TCPTTL number 1 1;
-tag 38 TCPkeepaliveinterval number 4 1;
-tag 39 TCPkeepalivegarbage boolean 1 1;
-tag 40 NISdomain ascii 1 0;
-tag 41 NISserver ip 1 0;
-tag 42 NTPserver ip 1 0;
-tag 43 VENDOR octet 1 0;
-tag 44 NetBIOSNS ip 1 0;
-tag 45 NetBIOSdgram ip 1 0;
-tag 46 NetBIOSnodetype number 1 1;
-tag 47 NetBIOSscope octet 1 0;
-tag 48 Xfontserver ip 1 0;
-tag 49 XDM ip 1 0;
-tag 50 DHCPreqip ip 1 1;
-tag 51 DHCPlease number 4 1;
-tag 52 DHCPoverload number 1 1;
-tag 53 DHCPtype number 1 1;
-tag 54 DHCPserverID ip 1 1;
-tag 55 DHCPreqpar number 1 0;
-tag 56 DHCPmessage ascii 1 0;
-tag 57 DHCPsize number 2 1;
-tag 58 DHCPrenewal number 4 1;
-tag 59 DHCPrebinding number 4 1;
-tag 60 DHCPclassID ascii 1 0;
-tag 61 DHCPclientID octet 1 0;
index c2853c996e422fdcd23a1e4019436a08f090cc90..62167dde1fb2976fa2e94ecfcce1d5687efc1048 100644 (file)
@@ -8,7 +8,7 @@
 CPPFLAGS.fslib.c+= -I${NETBSDSRCDIR}/minix/fs
 CPPFLAGS.fsversion.c+= -I${NETBSDSRCDIR}/minix/fs
 
-SRCS+= dhcp_gettag.c dhcp_settag.c fsversion.c gcov.c itoa.c \
+SRCS+= fsversion.c gcov.c itoa.c \
        oneC_sum.c read_tsc_64.c servxcheck.c fslib.c
 
 .endif # defined(__MINIX)
index 1f2b240355e29e4f9f787c8cd241093183c00d97..00dd3b8ba7c7d29770fe2d7d63f340837bd1f177 100644 (file)
@@ -6,7 +6,7 @@ SUBDIR= arp at backup \
        cawf cdprobe \
        cleantmp \
        compress crc cron crontab \
-       DESCRIBE devmand devsize dhcpd \
+       DESCRIBE devmand devsize \
        dhrystone \
        eject \
        fix format fsck.mfs \
diff --git a/minix/commands/dhcpd/Makefile b/minix/commands/dhcpd/Makefile
deleted file mode 100644 (file)
index ec9267b..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-# Makefile for dhcpd.
-
-PROG=  dhcpd
-SRCS=  dhcpd.c tags.c devices.c ether.c
-MAN=   dhcpd.8 dhcp.conf.5
-
-.include <bsd.prog.mk>
diff --git a/minix/commands/dhcpd/arp.h b/minix/commands/dhcpd/arp.h
deleted file mode 100644 (file)
index 0d0b131..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*     arp.h - Address Resolution Protocol packet format.
- *                                                     Author: Kees J. Bot
- *                                                             16 Dec 2000
- */
-#ifndef ARP_H
-#define ARP_H
-
-typedef struct arp46 {
-       ether_addr_t    dstaddr;
-       ether_addr_t    srcaddr;
-       ether_type_t    ethtype;        /* ARP_PROTO. */
-       u16_t           hdr, pro;       /* ARP_ETHERNET & ETH_IP_PROTO. */
-       u8_t            hln, pln;       /* 6 & 4. */
-       u16_t           op;             /* ARP_REQUEST or ARP_REPLY. */
-       ether_addr_t    sha;            /* Source hardware address. */
-       u8_t            spa[4];         /* Source protocol address. */
-       ether_addr_t    tha;            /* Likewise for the target. */
-       u8_t            tpa[4];
-       char            padding[60 - (4*6 + 2*4 + 4*2 + 2*1)];
-} arp46_t;
-
-#define ARP_ETHERNET   1       /* ARP on Ethernet. */
-#define ARP_REQUEST    1       /* A request for an IP address. */
-#define ARP_REPLY      2       /* A reply to a request. */
-
-#endif /* ARP_H */
diff --git a/minix/commands/dhcpd/devices.c b/minix/commands/dhcpd/devices.c
deleted file mode 100644 (file)
index 183d31e..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-/*     devices.c - Handle network devices.
- *                                                     Author: Kees J. Bot
- *                                                             11 Jun 1999
- */
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <limits.h>
-#include <signal.h>
-#include <time.h>
-#include <sys/ioctl.h>
-#include <sys/asynchio.h>
-#include <net/hton.h>
-#include <net/gen/in.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <net/gen/ether.h>
-#include <net/gen/eth_hdr.h>
-#include <net/gen/eth_io.h>
-#include <net/gen/ip_hdr.h>
-#include <net/gen/ip_io.h>
-#include <net/gen/udp.h>
-#include <net/gen/udp_hdr.h>
-#include <net/gen/udp_io.h>
-#include <net/gen/dhcp.h>
-#include "dhcpd.h"
-
-void get_buf(buf_t **bp)
-{
-    /* Allocate and return a buffer pointer iff *bp == nil. */
-    if (*bp != nil) {
-       /* Already has one. */
-    } else {
-       /* Get one from the heap. */
-       buf_t *new= allocate(sizeof(*new));
-       new->dhcp= (dhcp_t *) (new->buf + sizeof(eth_hdr_t)
-                               + sizeof(ip_hdr_t) + sizeof(udp_hdr_t));
-       new->udpio= ((udp_io_hdr_t *) new->dhcp) - 1;
-       new->udp= ((udp_hdr_t *) new->dhcp) - 1;
-       new->ip= ((ip_hdr_t *) new->udp) - 1;
-       new->eth= ((eth_hdr_t *) new->ip) - 1;
-       *bp= new;
-    }
-}
-
-void put_buf(buf_t **bp)
-{
-    /* Return a buffer to the heap. */
-    if (*bp != nil) {
-       free(*bp);
-       *bp= nil;
-    }
-}
-
-void give_buf(buf_t **dbp, buf_t **sbp)
-{
-    /* Hand over a buffer to another variable. */
-    put_buf(dbp);
-    *dbp= *sbp;
-    *sbp= nil;
-}
-
-#define N_FDS          16              /* Minix can go async on many fds. */
-
-static fd_t fds[N_FDS];                        /* List of open descriptors. */
-static struct network *fdwaitq;                /* Queue of nets waiting for fds. */
-
-network_t *newnetwork(void)
-{
-    /* Create and initialize a network structure. */
-    network_t *new;
-
-    new= allocate(sizeof(*new));
-    memset(new, 0, sizeof(*new));
-    new->hostname= nil;
-    new->solicit= NEVER;
-    new->sol_ct= -1;
-    return new;
-}
-
-void closefd(fd_t *fdp)
-{
-    /* Close a descriptor. */
-    if (fdp->fdtype != FT_CLOSED) {
-       asyn_close(&asyn, fdp->fd);
-       close(fdp->fd);
-       fdp->fdtype= FT_CLOSED;
-       fdp->since= 0;
-       put_buf(&fdp->bp);
-       if (debug >= 3) printf("%s: Closed\n", fdp->device);
-    }
-}
-
-static void timeout(int signum)
-{
-    /* nothing to do, ioctl will be aborted automatically */
-    if (alarm(1) == (unsigned int)-1) fatal("alarm(1)");
-}
-
-int opendev(network_t *np, fdtype_t fdtype, int compete)
-{
-    /* Make sure that a network has the proper device open and configured.
-     * Return true if this is made so, or false if the device doesn't exist.
-     * If compete is true then the caller competes for old descriptors.
-     * The errno value is EAGAIN if we're out of descriptors.
-     */
-    fd_t *fdp, *fdold;
-    time_t oldest;
-    nwio_ethstat_t ethstat;
-    nwio_ethopt_t ethopt;
-    nwio_ipopt_t ipopt;
-    nwio_udpopt_t udpopt;
-    network_t **pqp;
-    static char devbytype[][4] = { "", "eth", "ip", "udp", "udp" };
-
-    /* Don't attempt to open higher level devices if not bound. */
-    if (!(np->flags & NF_BOUND) && fdtype > FT_ETHERNET) {
-       errno= EAGAIN;
-       return 0;
-    }
-
-    /* Check if already open / Find the oldest descriptor. */
-    fdold= nil;
-    oldest= NEVER;
-    for (fdp= fds; fdp < arraylimit(fds); fdp++) {
-       if (fdp->n == np->n && fdp->fdtype == fdtype) {
-           /* Already open. */
-           np->fdp= fdp;
-           return 1;
-       }
-       if (fdp->since <= oldest) { fdold= fdp; oldest= fdp->since; }
-    }
-
-    /* None free?  Then wait for one to get old if so desired. */
-    if (fdold->fdtype != FT_CLOSED && !compete) {
-       errno= EAGAIN;
-       return 0;
-    }
-
-    if (!(np->flags & NF_WAIT)) {
-       for (pqp= &fdwaitq; *pqp != nil; pqp= &(*pqp)->wait) {}
-       *pqp= np;
-       np->wait= nil;
-       np->flags |= NF_WAIT;
-    }
-
-    /* We allow a net to keep a descriptor for half of the fast period. */
-    oldest += DELTA_FAST/2;
-
-    if (fdwaitq != np || (fdold->fdtype != FT_CLOSED && oldest > now)) {
-       /* This net is not the first in the queue, or the oldest isn't
-        * old enough.  Forget it for now.
-        */
-       if (oldest < event) event= oldest;
-       errno= EAGAIN;
-       return 0;
-    }
-
-    /* The oldest is mine. */
-    np->flags &= ~NF_WAIT;
-    fdwaitq= np->wait;
-    closefd(fdold);
-
-    /* Open the proper device in the proper mode. */
-    fdp= fdold;
-    fdp->n= np->n;
-    if (lwip && (fdtype == FT_ETHERNET || fdtype == FT_ICMP))
-           sprintf(fdp->device, "/dev/ip");
-    else
-           sprintf(fdp->device, "/dev/%s%d", devbytype[fdtype], np->n);
-    np->fdp= fdp;
-
-    if ((fdp->fd= open(fdp->device, O_RDWR)) < 0) {
-       if (errno == ENOENT || errno == ENODEV || errno == ENXIO) return 0;
-       fatal(fdp->device);
-    }
-
-    switch (fdtype) {
-    case FT_ETHERNET:
-        if (lwip) {
-                nwio_ipopt_t ipopt;
-                int result;
-                char ethdev[64];
-                int efd;
-                
-                sprintf(ethdev, "/dev/eth%d", np->n);
-    
-                if ((efd = open(fdp->device, O_RDWR)) < 0) {
-                        if (errno == ENOENT || errno == ENODEV ||
-                                        errno == ENXIO)
-                                return 0;
-                        fatal(ethdev);
-                }
-       
-                if (ioctl(efd, NWIOGETHSTAT, &ethstat) < 0) {
-                        /* Not an Ethernet. */
-                        close(efd);
-                        return 0;
-                }
-                close(efd);
-
-                np->eth= ethstat.nwes_addr;
-
-                ipopt.nwio_flags= NWIO_COPY | NWIO_PROTOSPEC;
-                ipopt.nwio_proto= 17; /* UDP */
-                result= ioctl (fdp->fd, NWIOSIPOPT, &ipopt);
-                if (result<0)
-                        perror("ioctl (NWIOSIPOPT)"), exit(1);
-
-                break;
-        }
-       /* Cannot use NWIOGETHSTAT in non-blocking mode due to a race between 
-         * the reply from the ethernet driver and the cancel message from VFS
-        * for reaching inet. Hence, a signal is used to interrupt NWIOGETHSTAT
-        * in case the driver isn't ready yet.
-        */
-       if (signal(SIGALRM, timeout) == SIG_ERR) fatal("signal(SIGALRM)");
-       if (alarm(1) == (unsigned int)-1) fatal("alarm(1)");
-       if (ioctl(np->fdp->fd, NWIOGETHSTAT, &ethstat) < 0) {
-           /* Not an Ethernet. */
-           close(fdp->fd);
-           return 0;
-       }
-       if (alarm(0) == (unsigned int)-1) fatal("alarm(0)");
-       np->eth= ethstat.nwes_addr;
-       ethopt.nweo_flags= NWEO_COPY | NWEO_EN_LOC | NWEO_EN_BROAD
-                       | NWEO_REMANY | NWEO_TYPEANY | NWEO_RWDATALL;
-
-       if (ioctl(fdp->fd, NWIOSETHOPT, &ethopt) < 0) {
-           fprintf(stderr, "%s: %s: Unable to set eth options: %s\n",
-               program, fdp->device, strerror(errno));
-           exit(1);
-       }
-       break;
-
-    case FT_ICMP:
-       ipopt.nwio_flags= NWIO_COPY | NWIO_EN_LOC | NWIO_EN_BROAD
-                       | NWIO_REMANY | NWIO_PROTOSPEC
-                       | NWIO_HDR_O_SPEC | NWIO_RWDATALL;
-       ipopt.nwio_tos= 0;
-       ipopt.nwio_ttl= 1;
-       ipopt.nwio_df= 0;
-       ipopt.nwio_hdropt.iho_opt_siz= 0;
-       ipopt.nwio_proto= IPPROTO_ICMP;
-
-       if (ioctl(fdp->fd, NWIOSIPOPT, &ipopt) < 0) {
-           fprintf(stderr, "%s: %s: Unable to set IP options: %s\n",
-               program, fdp->device, strerror(errno));
-           exit(1);
-       }
-       break;
-
-    case FT_BOOTPC:
-       if (lwip) {
-               struct sockaddr_in si_me;
-
-               close(fdp->fd);
-               fdp->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-               if (fdp->fd < 0)
-                       return 0;
-               memset((char *) &si_me, 0, sizeof(si_me));
-               si_me.sin_family = AF_INET;
-               si_me.sin_addr.s_addr = htonl(INADDR_ANY);
-               si_me.sin_port = htons(port_client);
-               if (bind(fdp->fd, (struct sockaddr *) &si_me,
-                                       sizeof(si_me)) == -1) {
-                       close(fdp->fd);
-                       printf("DHCP : cannot bind client socket to port %d\n",
-                                                               port_client);
-                       return 0;
-               }
-               break;
-       }
-       udpopt.nwuo_flags= NWUO_COPY | NWUO_EN_LOC | NWUO_EN_BROAD
-                       | NWUO_RP_ANY | NWUO_RA_ANY | NWUO_RWDATALL
-                       | NWUO_DI_IPOPT | NWUO_LP_SET;
-       udpopt.nwuo_locport= port_client;
-       goto udp;
-
-    case FT_BOOTPS:
-       udpopt.nwuo_flags= NWUO_EXCL | NWUO_EN_LOC | NWUO_EN_BROAD
-                       | NWUO_RP_ANY | NWUO_RA_ANY | NWUO_RWDATALL
-                       | NWUO_DI_IPOPT | NWUO_LP_SET;
-       udpopt.nwuo_locport= port_server;
-    udp:
-       if (ioctl(fdp->fd, NWIOSUDPOPT, &udpopt) == -1) {
-           fprintf(stderr, "%s: %s: Unable to set UDP options: %s\n",
-               program, fdp->device, strerror(errno));
-           exit(1);
-       }
-       break;
-
-    default:;
-    }
-
-    fdp->fdtype= fdtype;
-    fdp->since= now;
-    if (debug >= 3) printf("%s: Opened\n", fdp->device);
-    return 1;
-}
-
-void closedev(network_t *np, fdtype_t fdtype)
-{
-    /* We no longer need a given type of device to be open. */
-    fd_t *fdp;
-
-    for (fdp= fds; fdp < arraylimit(fds); fdp++) {
-       if (fdp->n == np->n && (fdp->fdtype == fdtype || fdtype == FT_ALL)) {
-           closefd(fdp);
-       }
-    }
-}
-
-char *ipdev(int n)
-{
-    /* IP device for network #n. */
-    static char device[sizeof("/dev/ipNNN")];
-
-    sprintf(device, "/dev/ip%d", n);
-    return device;
-}
-
-void set_ipconf(char *device, ipaddr_t ip, ipaddr_t mask, unsigned mtu)
-{
-    /* Set IP address and netmask of an IP device. */
-    int fd;
-    nwio_ipconf_t ipconf;
-
-    if (test > 0) return;
-
-    if ((fd= open(device, O_RDWR)) < 0) fatal(device);
-    ipconf.nwic_flags= NWIC_IPADDR_SET | NWIC_NETMASK_SET;
-    ipconf.nwic_ipaddr= ip;
-    ipconf.nwic_netmask= mask;
-#ifdef NWIC_MTU_SET
-    if (mtu != 0) {
-       ipconf.nwic_flags |= NWIC_MTU_SET;
-       ipconf.nwic_mtu= mtu;
-    }
-#endif
-    if (ioctl(fd, NWIOSIPCONF, &ipconf) < 0) fatal(device);
-    close(fd);
-}
diff --git a/minix/commands/dhcpd/dhcp.conf.5 b/minix/commands/dhcpd/dhcp.conf.5
deleted file mode 100644 (file)
index da9e5eb..0000000
+++ /dev/null
@@ -1,498 +0,0 @@
-.TH DHCP.CONF 5
-.SH NAME
-dhcp.conf \- dynamic host configuration protocol configuration
-.SH SYNOPSIS
-.B /etc/dhcp.conf
-.SH DESCRIPTION
-.de SP
-.if t .sp 0.4
-.if n .sp
-..
-The file
-.B /etc/dhcp.conf
-contains the configuration for the DHCP client/server program
-.BR dhcpd .
-This text is a long summation of all the elements that can be found in this
-configuration file.  For a more "just tell me what to do" approach see
-.BR boot (8).
-.PP
-The syntax used is that of the common configuration file described in
-.BR configfile (5).
-.PP
-To find information for a client we first need its IP address.  Occasionally
-this IP address is already known (the special "INFORM" query), but normally
-we have to make a first pass through the configuration file for a
-.B client
-entry.  If that fails then we use an IP address from the pool file.  If we
-now have an IP address then the real information gathering can begin.
-.PP
-The DHCP daemon reads the configuration file from beginning to end and
-gathers all information that matches, and information from all macros that
-are mentioned within the elements that match.  If we end up with DHCP
-information that includes at least a netmask definition, and is good for the
-network the request came in from, then it is returned to the client.  If a
-DHCP tag is specified twice then the last one wins.
-.PP
-In the description below we use [ and ] to denote optional things, and | to
-show a choice between two things.
-.PP
-Client IDs can be either ordinary Ethernet addresses, that are treated as a
-seven octet string (01 followed by the Ethernet address), or any random
-octet string in hexadecimal.
-.PP
-IP addresses can be simply that, or host names.  These host names are
-searched in
-.B /etc/hosts
-by
-.B dhcpd
-itself using a domain based prefix match, i.e. you can use "flotsam" for
-"flotsam.example.com", but not "alpha" for "alphabeta".  Once the program
-decides to be a server it will also look up names normally in the DNS.
-If a host has more than one IP address then the address on the network the
-query was seen on is used.
-.PP
-Case isn't important in the configuration file, "client", "CLIENT" and
-"ClIeNt" are all treated the same.
-.PP
-Some elements may optionally name a macro or a curly braces enclosed
-parameter list of more elements.  If the element matches then the data
-in the macro body or parameter list is gathered.
-.PP
-The following elements can be used:
-.PP
-.B client
-.I client-ID
-.RB [ ip #]
-.I host
-.RI [ macro |{ params }];
-.PP
-.RS
-Defines a client with a given client ID that is to have the IP address
-denoted by
-.I host .
-On the first pass only the client ID is matched looking for an IP address
-that lies on the network the request came in on.  On the
-information gathering pass both client ID and IP address must match.  If
-a machine has the same Ethernet address on two or more interfaces then the
-IP address given out is the one on the same network as the request came in
-on.  The optional interface name
-.RB ( ip #)
-must be used if the DHCP daemon is gathering data for itself at boot time
-to differentiate interfaces with the same ethernet addresses.  This is
-only necessary under Minix-vmd when ethernets on different VLANs share
-the same physical ethernet.  The interface name is only used for a machine's
-own networks, it ignored on entries for other hosts.
-.RE
-.PP
-.B class
-.IR class-name " ..."
-.IR macro |{ params };
-.PP
-.RS
-Includes the macro or parameters if one of the class names is matched.  A
-host normally includes a class ID in its request.  MINIX 3 and Minix-vmd
-use "Minix" as the class name.  For Windows the class ID starts with
-"MSFT", and Solaris' starts with "SUNW".
-(Use
-.B dhcpd \-d3
-to find out what the full IDs are exactly.)  The class names are matched if a
-.I class-name
-is a prefix of the class ID sent by the client.
-.RE
-.PP
-.B host
-.I host-spec
-.IR macro |{ params };
-.PP
-.RS
-Includes the macro or parameters if the IP address of the client matches the
-host specification.  This can either be an ordinary hostname, or a netblock
-in CIDR notation, e.g. 172.35.0.0/16.  The example includes all IP addresses
-whose top 16 bits are the same as the top 16 bits of 172.35.0.0.  Such a
-netblock automatically defines a netmask (255.255.0.0 in the example) if no
-netmask has been specified yet.
-.RE
-.PP
-.B interface
-.BR ip #
-.I host
-.RI [ macro |{ params }];
-.PP
-.RS
-Makes
-.B dhcpd
-set the IP address of interface
-.BR ip #
-(where # is a number) to the IP address denoted by
-.IR host .
-This element should only be used for interfaces that are not true Ethernets,
-and so do not have a unique Ethernet address that can be used for a client
-element.  If the machine has at least one true Ethernet then all interface
-elements should be added to the parameter list of a host or client element
-for that Ethernet interface.  This binds them to that machine and allows a
-single configuration file to be shared among machines.  Especially a server
-should never have "free" interface elements.  The macro or parameters are
-only evaluated if data is gathered for the given interface.  (Note that they
-will be hidden by a client element for another interface.)
-.RE
-.PP
-.B macro
-.IR macro-name ;
-.PP
-.RS
-Include the parameter list of the macro named
-.I macro-name
-defined elsewhere.  (This means that "host flotsam stuff" is just short
-for "host flotsam { macro stuff; }".)
-.RE
-.PP
-.B macro
-.I macro-name
-.RI { params };
-.PP
-.RS
-Defines a macro with the given parameter list.  Whenever the macro is used
-the parameter list is substituted instead.  A macro can not be defined
-within another parameter list.
-.RE
-.PP
-.B option
-.RB [ ip #]
-.B server
-.RB [ inform ];
-.br
-.B option
-.RB [ ip #]
-.B relay
-.IR host ;
-.br
-.B option
-.RB [ ip #]
-.BR possessive ;
-.br
-.B option
-.RB [ ip #]
-.B hostname
-.IR name ;
-.PP
-.RS
-Makes
-.B dhcpd
-set special options for the interface that it is gathering data for, or the
-interface denoted by the optional
-.BR ip #
-argument.  The options are:
-.SP
-.B server
-.RB [ inform ]
-.RS
-Be a DHCP server on the network connected to the interface.  Add the word
-.B inform
-if DHCPINFORM requests must be answered for hosts we don't have an address
-for.
-.RE
-.SP
-.B relay
-.I host
-.RS
-Be a DHCP relay to the indicated host.
-.RE
-.SP
-.B possessive
-.RS
-Do not disable the interface if the DHCP lease expires.  Useful if the
-DHCP server of the provider is unreliable, crashing a lot and causing the
-lease to expire.  (Think twice before turning this option on.  You have to
-be absolutely sure that it's the DHCP server that's the culprit and not
-a flaky network.  You don't want an IP address conflict to be your fault.)
-.RE
-.SP
-.B hostname
-.I name
-.RS
-Use the given name as our hostname in the DHCP queries.  Some sites key on
-that bit of information instead of a client ID.
-.RE
-.RE
-.PP
-.B tag
-.I number name type granularity
-.IR max ;
-.PP
-.RS
-Defines a DHCP tag for the given tag number and gives it a name.  The name can
-be used in the configuration file to set tag values when gathering data.
-The
-.I type
-field can be one of
-.BR ascii ,
-.BR boolean ,
-.BR ip ,
-.BR number
-or
-.BR octet
-to specify the type of the tag as a simple string, a boolean, an IP address,
-a number, or a string of octet values.
-The
-.I granularity
-field specifies that that number of items must be given or a multiple
-thereof, unless the type is a number, then it is the size of the number (1,
-2 or 4).
-The
-.I max
-field tells the maximum number of items that may be used with the tag, with
-0 meaning "unlimited".
-.SP
-Three tags, the ones that MINIX 3 really cares about, have been predefined,
-and there are also a few pseudotags predefined for the static fields in a
-DHCP packet that one may want to set:
-.SP
-.RS
-.nf
-tag ? siaddr ip 1 1;
-tag ? sname ascii 1 64;
-tag ? file ascii 1 128;
-tag 1 netmask ip 1 1;
-tag 3 gateway ip 1 0;
-tag 6 DNSserver ip 1 0;
-.fi
-.RE
-.SP
-The file
-.B /usr/etc/dhcptags.conf
-contains tag definitions for all standard DHCP tags.  It is wise to include
-this file at the top of any DHCP configuration file.
-.RE
-.PP
-.B no
-.IR tag-name ;
-.PP
-.RS
-Removes a tag with the given name from the data gathered at this point.
-Useful if one host is different from all others, for instance if it doesn't
-need a gateway definition, because it happens to be the gateway.
-.RE
-.PP
-.IR "ascii-tag string" ;
-.PP
-.RS
-Adds an ASCII tag to the gathered data.  The string can be a simple word, or
-a quoted string.
-.RE
-.PP
-.I boolean-tag
-.BR false | true ;
-.PP
-.RS
-Set a boolean tag to be false or true.  (Encoded as a octet of value 0 or 1.
-Note that if you prefer to use 0 or 1 instead of false or true then you can
-define a boolean tag as a size 1 number instead.)
-.RE
-.PP
-.IR "ip-tag host" " ...;"
-.PP
-.RS
-Sets a tag that needs one or more IP addresses.  The host names are
-translated as usual.  To make it easier to specify netmasks one can use a
-slash followed by a number, e.g.
-.BR "netmask /27" ,
-which is a handy alternative for
-.BR "netmask 255.255.255.224" .
-.RE
-.PP
-.IR "number-tag number" " ...;"
-.PP
-.RS
-Set a number tag.
-.RE
-.PP
-.IR "octet-tag hexdigits" ;
-.PP
-.RS
-Set an octet string tag.
-.I Hexdigits
-is a series of hexadecimal digits that are two by two used to set the
-octets.
-.RE
-.PP
-.SH EXAMPLE
-As an example the DHCP configuration used by the author of this document is
-included.  His network at home consists of a number of PCs, an ISDN router
-named rhone and a PC named saone serving as router/tunnel to/via a cable
-ISP.  Both the rhone and the saone connect the home net to the network of
-the Vrije Universiteit, but the rhone is only active if the cable doesn't
-work.
-.PP
-The saone is a DHCP server, and one of the ordinary PCs is a backup DHCP
-server.  Both use the same configuration file, which is added below, with
-extra commentary introduced by
-.B ##
-at a deeper indent level:
-.RS
-.de xS \" Example start
-.sp
-.nf
-.ft C
-..
-.de xE \" Example end
-.fi
-.ft R
-..
-.de cS \" Commentary start
-.sp
-.in +12m
-.ti -\w'## 'u
-##\ \c
-..
-.de cE \" Commentary end
-.in -12m
-..
-.xS
-.ta +8m +16m
-include /usr/etc/dhcptags.conf;
-.xE
-.cS
-With the help of the tag definitions we can use tags like "DHCPlease".
-.cE
-.xS
-host 130.37.102.64/27 {
-       DNSserver saone darask;
-       host 130.37.102.88/29 { DHCPlease 259200; }
-};
-.xE
-.cS
-This defines the network 130.37.102.64/27, with netmask 255.255.255.224
-(implicit from the network definition).  The DNS servers for this net are
-saone and darask.  A smaller subrange of addresses is used as an address
-pool on the saone, so a lease of 259200 seconds (3 days) is defined.  The
-netmask is still /27, as set by the outer network definition.
-.cE
-.xS
-host 130.37.102.248/30 {};
-.xE
-.cS
-A network of two addresses for routing tests.
-.cE
-.xS
-host saone {
-       option server;
-       option ip1 possessive;
-       interface ip2 saone-net2;
-       DNSserver 130.37.24.3 130.37.24.6;
-};
-.xE
-.cS
-With the network definitions done we turn our attention to the hosts.  Saone
-is a DHCP server on its main interface.  The second interface
-.RB ( ip1 )
-is connected to the cable modem.  It gets its address from the cableco's
-DHCP server, and if that server decides to go deaf then the saone keeps
-the interface up ("possessive") even if the lease expires.  The pseudo IP
-interface
-.B ip2
-is set to the IP address of
-.BR saone-net2 ,
-one side of the encrypted tunnel over the cable to a Minix-vmd box at the VU.
-The DNS servers specified override the default setting for the network, naming
-two external servers at the VU that know the world.
-.cE
-.xS
-host darask {
-       option server;
-       DNSserver saone;
-       class MINIX 3 { DNSserver saone 130.37.24.3 130.37.24.6; };
-};
-.xE
-.cS
-The darask is also a server, the backup for saone on the odd chance that it
-is unavailable.  It uses saone and the external name servers, but only
-when it is running MINIX 3.  When running Windows it only uses saone.
-.cE
-.xS
-.ta +32m +16m
-client 0:1:1b:a:68:ce  darask; # NE2000
-client 0:1:1b:a:77:23  burask; # NE2000
-#lient 0:0:c0:b0:da:64 burask; # WD8013EWC
-client 8:0:5a:38:b2:f  finiah; # PCMCIA NE2000
-client 0:0:c0:3a:12:10 bardelask;      # WD8003
-#lient 2:60:8c:ab:8a:6d        bardelask;      # 3C503
-client 0:a0:c5:20:9:6d rhone;
-client 0:1:1b:a:4c:3b  saone;  # NE2000
-#lient 0:0:c0:fb:2:6a  saone-net1;     # WD8013EWC
-.xE
-.cS
-Lastly the ethernet addresses of all the hosts are listed, so that they can
-be translated to IP addresses.  The lines that are commented out are for
-extra network cards that are currently unused.  The last is used to connect
-to the cable modem, so it's only here because it's nice to have the ethernet
-address written down somewhere.
-.cE
-.RE
-.PP
-The host names shown above are translated by DHCP using this
-.BR /etc/hosts :
-.RS
-.xS
-.ta +\w'130.37.102.249mm'u
-604800 %ttl
-2419200        %stale
-
-130.37.102.65  darask.kjb.upwind.org
-130.37.102.66  burask.kjb.upwind.org
-130.37.102.67  finiah.kjb.upwind.org
-130.37.102.68  bardelask.kjb.upwind.org
-130.37.102.69  roniah.kjb.upwind.org
-
-130.37.102.70  saone.kjb.upwind.org
-130.37.102.2   saone-net2.kjb.upwind.org
-
-130.37.102.88  rhone.kjb.upwind.org
-130.37.102.89  dyn89.kjb.upwind.org
-130.37.102.90  dyn90.kjb.upwind.org
-130.37.102.91  dyn91.kjb.upwind.org
-130.37.102.92  dyn92.kjb.upwind.org
-130.37.102.93  dyn93.kjb.upwind.org
-130.37.102.94  dyn94.kjb.upwind.org
-
-130.37.102.249 tst1.kjb.upwind.org
-130.37.102.250 tst2.kjb.upwind.org
-.xE
-.RE
-.SH FILES
-.TP
-.B /usr/etc/dhcptags.conf
-A supplied list of standard tag definitions as per RFC-1533.  (Well, the
-tag numbers and their meaning are standard, the names are made up.)
-.SH "SEE ALSO"
-.BR RFC-2131 ,
-.BR RFC-1533 ,
-.BR configfile (5),
-.BR hosts (5),
-.BR boot (8),
-.BR dhcpd (8).
-.SH NOTES
-The amount of memory
-.B dhcpd
-needs increases with the size of configuration file.  MINIX 3 can
-handle
-.B dhcptags.conf
-and a modest sized
-.BR dhcp.conf .
-You have to increase the stack size to accommodate more.  (No problem under
-Minix-vmd, of course.)
-.SH NOTES
-Items that are only necessary for a certain host should only be specified
-for that host.  Items for a whole network are best added to a netblock
-specification.  Use class elements for a certain type of host, and macros
-for exceptions.  Try to limit information as much as possibly to those hosts
-that need it.  (Don't go overboard.  A MINIX 3 machine won't be bothered by a
-few NetBIOS tags.)
-.PP
-DHCPINFORM requests should always be answered when being a server, but
-J. Random Sysadmin trying to diagnose problems doesn't like it when little
-MINIX 3 machines show up in a packet trace unexpectedly.  It's best to be
-inconspicuous on a network you don't own.
-.SH BUGS
-There are a few too many subtle mistakes one can make.
-.SH AUTHOR
-Kees J. Bot <kjb@cs.vu.nl>
diff --git a/minix/commands/dhcpd/dhcpd.8 b/minix/commands/dhcpd/dhcpd.8
deleted file mode 100644 (file)
index 0598d9d..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-.TH DHCPD 8
-.SH NAME
-dhcpd \- dynamic host configuration protocol daemon
-.SH SYNOPSIS
-.in +.5i
-.ti -.5i
-.B dhdpd
-.RB [ \-qar ]
-.RB [ \-t [\fIlevel\fP]]
-.RB [ \-d [\fIlevel\fP]]
-.RB [ \-f
-.IR configfile ]
-.RB [ \-c
-.IR cachefile ]
-.RB [ \-p
-.IR poolfile ]
-.RI [ host " ...]"
-.in -.5i
-.SH DESCRIPTION
-.de SP
-.if t .sp 0.4
-.if n .sp
-..
-.B Dhcpd
-is a client and a server for the Dynamic Host Configuration Protocol.  As a
-client it collects DHCP data to configure the Ethernet networks with, and as
-a server it answers DHCP queries from other machines.
-.PP
-This manual page describes the operation of
-.BR dhcpd ,
-the associated configuration file is described in
-.BR dhcp.conf (5).
-(The latter, together with
-.BR boot (8),
-is of more practical value when it comes to getting a machine's networks
-interfaces up and running.  See the options section below for debugging DCHP
-problems.)
-.SS Initialization
-On a normal startup, i.e. none of the
-.BR \-q ,
-.BR \-a
-or
-.BR \-r
-options are given,
-.B dhcpd
-determines what IP devices are present, and which of those are Ethernets.
-For each network it looks for information in the configuration file as if
-it were a server answering a query for that network.  If any information is
-found then the IP address is configured and the information stored in the
-cache file.
-.SS "Client Operation"
-For each still unconfigured network a DHCP DISCOVER request is broadcast on
-that network.  If a DHCP OFFER reply is received then a DHCP REQUEST is
-broadcast for the IP address offered, and if a DHCP ACK is received then the
-network is configured and the information stored in the cache file.
-.PP
-If no reply is received then another query is sent after 4 seconds, and then
-again after 8 seconds, doubling each time until 64 seconds.  Every 64
-seconds thereafter a request is broadcast until a reply is received.
-.PP
-Once configured the DHCP lease, rebind and renew times are computed.  At the
-renew time a DHCP REQUEST is sent to the DHCP server to extend the lease.
-Normally we get an answer and refresh our information, but if no reply is
-received we wait for half the remaining time until the rebind time and keep
-retrying and halving the remaining time.  When the rebind time is reached
-the DHCP REQUEST is broadcast to try and reach some other DHCP server.
-Halving the remaining time again and again until the lease expires.  At that
-point we go back to square one and broadcast a DHCP DISCOVER.
-.PP
-If at any point a DHCP NAK is received we start over completely.  After a
-DHCP OFFER an ARP request is transmitted just before the DHCP REQUEST to
-check if the address offered is already in use.  If an ARP reply is received
-before the DHCP ACK then after the ACK we send a DHCP DECLINE to the server
-to tell that the address isn't what we want and again we start over.
-.SS "Router Discovery"
-The gateway offered by the DHCP server is made known to the TCP/IP server by
-sending an ICMP router advertisement to the local interface with a short
-lifetime and a low priority.  Then up to three router solicitations are
-broadcast three seconds apart to look for a router.  If a router answers
-with a router advertisement then we no longer worry about routing for that
-interface.  Otherwise the router information is refreshed before it expires
-and another solicitation is sent out.  This happens about twice an hour.
-.SS "Server Operation"
-Once all networks so marked are configured the daemon starts answering
-requests by other machines or relaying requests to other DHCP servers.
-DHCP requests are answered if information for a client
-can be found in the configuration file, or if a free address can be found in
-the pool file, or if a client rerequests an address it already owns.
-.PP
-If the daemon is both a server and a relay for a network then it will try
-to answer a request and only relay if it has no answer.
-.SS "Nothing more to do?"
-If the daemon finds out that all networks have an infinite lease (configured
-with a fixed address), there is no router information to keep warm, and
-it isn't a server then it simply exits.
-.SS "Asynchronous I/O?"
-MINIX 3 doesn't have the asynchronous I/O that Minix-vmd has, so under MINIX 3
-the daemon only works with one network at a time.  If it's stuck on the same
-network for 32 seconds then that network is closed and another network is
-tried for 32 seconds.  This usually works ok as a client, but as a server it
-can only handle one network.
-.SH OPTIONS
-.TP
-.B \-q
-Read and print the cache and pool file contents, showing DHCP information
-for each network, and the IP addresses in the pool with lease times and
-current/last owners of those addresses.
-.TP
-.B \-a
-Add the named hosts (or IP addresses) to the pool file.
-.TP
-.B \-r
-Remove hosts from the pool file.
-.TP
-.RB [ \-t [\fIlevel\fP]]
-Set the test level (by default 1).  At test level 1 all networks are seen as
-unconfigured, will not be configured and no data will be put in the cache.
-The program will just act as-if.  At test level 2 the interfaces will not be
-configured from the configuration file, the data must come from a remote
-server.  At level 3 the renewal, rebind and lease time will be 60, 120
-and 180 seconds.  At level 4 these times will be 60, 60, and 120.  At
-level 5 these times will be 60, 60, and 60.  These test levels are meant
-to debug the DHCP client code, and are best used with a high debug level.
-.TP
-.RB [ \-d [\fIlevel\fP]]
-Set the debug level (by default 1).  At debug level 1 the program shows
-Ethernet and IP addresses as they are determined or configured, DHCP
-messages sent and received with little detail (one line per message), and
-memory use.  At debug level 2 each DHCP packet is decoded and shown in
-detail.  At debug level 3 device opens and closes are shown.  The debugging
-level may also be increased by 1 at runtime by sending signal
-.BR SIGUSR1
-or turned off (set to 0) with
-.BR SIGUSR2 .
-.TP
-.BI \-f " configfile"
-Names the configuration file, by default
-.BR /etc/dhcp.conf .
-.TP
-.BI \-c " cachefile"
-Names the cache file, by default
-.BR /usr/adm/dhcp.cache .
-.TP
-.BI \-p " poolfile"
-Names the IP address pool, by default
-.BR /usr/adm/dhcp.pool .
-.SH "SEE ALSO"
-.BR RFC-2131 ,
-.BR RFC-1533 ,
-.BR dhcp.conf (5),
-.BR hosts (5),
-.BR ifconfig (8),
-.BR inet (8),
-.BR boot (8),
-.BR inetd (8),
-.BR nonamed (8).
-.SH DIAGNOSTICS
-.TP
-"'/etc/dhcp.conf', line ..."
-The program exits on any configuration file error.  You have to correct the
-error and restart the program.
-.TP
-"No lease set for address ..."
-There must be a lease time defined for addresses in the pool.  Correct and
-restart the program.
-.TP
-"###### declines #.#.#.# saying '...'"
-A client with the given client identifier (usually 01 followed by the client's
-Ethernet address) declines an IP address, hopefully with a message telling
-why.  This usually means that the IP address is already in use by another
-host.  This program, acting as a client, will tell what other host in its
-message, but Windows has no additional info alas.
-.TP
-"Got a NAK from #.#.#.# [through #.#.#.#] saying '...'"
-The server with the given IP address doesn't want us to have or keep the IP
-address we were offered or are rerequesting.  This could mean that the server
-has forgotten about us and has given our address to another machine.  This
-is bad if our lease hasn't yet expired.  There may be a relay involved, and
-there may even be a text message with precise information.
-.TP
-"#.#.#.# offered by #.#.#.# is already in use by #:#:#:#:#:#"
-We got an ARP reply for an offered address.  We won't accept it, and send
-out a DECLINE when we get an ACK.
-.TP
-"DHCP packet too big, ..."
-You've got way to much information in the configuration file, more than fits
-in a minimum size DHCP packet.  (Notify the author if you really need to send
-more information.  He doesn't think anyone needs to.)
-.TP
-"Pool table is corrupt"
-You will have to remove and refill the pool file.  Chaos may ensue if
-there are active clients and they don't use ARP to detect each other.
-(Most do.)
-.SH BUGS
-There is no randomization of timers.  Modern systems don't blink under the
-load of several clients broadcasting a few packets in sync.
-.PP
-There is no extra time spent waiting for an ARP reply.  It is assumed that
-any IP stack will immediately respond, so that the DHCP server can't
-possibly beat it at sending out an ACK.  (The DHCP server has to commit the
-lease to stable storage first anyway.)
-.PP
-Way more nonsense can be sent in a DHCP packet that MINIX 3 could do
-something with, but nobody does so we don't bother.
-.PP
-DHCP was invented by a rabid gerbil on speed.
-.SH AUTHOR
-Kees J. Bot <kjb@cs.vu.nl>
diff --git a/minix/commands/dhcpd/dhcpd.c b/minix/commands/dhcpd/dhcpd.c
deleted file mode 100644 (file)
index d4c1bfd..0000000
+++ /dev/null
@@ -1,1434 +0,0 @@
-/*     dhcpd 1.15 - Dynamic Host Configuration Protocol daemon.
- *                                                     Author: Kees J. Bot
- *                                                             11 Jun 1999
- */
-#include <sys/types.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <signal.h>
-#include <string.h>
-#include <time.h>
-#include <limits.h>
-#include <configfile.h>
-#include <sys/ioctl.h>
-#include <sys/asynchio.h>
-#include <net/hton.h>
-#include <net/gen/socket.h>
-#include <netdb.h>
-#include <net/gen/in.h>
-#include <net/gen/inet.h>
-#include <net/gen/ether.h>
-#include <net/gen/if_ether.h>
-#include <net/gen/eth_hdr.h>
-#include <net/gen/ip_hdr.h>
-#include <net/gen/udp.h>
-#include <net/gen/udp_hdr.h>
-#include <net/gen/udp_io.h>
-#include <net/gen/dhcp.h>
-#include <arpa/inet.h>
-#include "arp.h"
-#define EXTERN
-#include "dhcpd.h"
-
-char *configfile= PATH_DHCPCONF;
-char *poolfile= PATH_DHCPPOOL;
-static char *cachefile= PATH_DHCPCACHE;
-static int qflag;              /* True if printing cached DHCP data. */
-static int aflag, rflag;       /* True if adding or deleting pool addresses. */
-
-#define BCAST_IP       htonl(0xFFFFFFFFUL)
-
-/* We try to play with up to this many networks. */
-#define N_NETS         32
-static unsigned n_nets;                /* Actual number of networks. */
-
-int lwip;
-
-void report(const char *label)
-{
-    static FILE *logfp;
-    if(!logfp)
-       logfp = fopen("/usr/log/dhcp.log", "w");
-    if(logfp)
-       fprintf(logfp, "%s: %s: %s\n", program, label, strerror(errno));
-}
-
-void fatal(const char *label)
-{
-    report(label);
-    exit(1);
-}
-
-void *allocate(size_t size)
-{
-    void *mem;
-
-    if ((mem= malloc(size)) == nil) fatal("Can't allocate memory");
-    return mem;
-}
-
-/* Choose a DHCP xid based on the start time and network number.  Not really
- * random, but we don't have anything more random than the clock anyway.
- */
-#define XID(np)                htonl(((u32_t) (np)->start << 8) | (np)->n)
-
-static network_t *network[N_NETS];
-
-int ifname2if(const char *name)
-{
-    /* Translate an interface name to a number, -1 if bad. */
-    char *end;
-    unsigned long n;
-
-    if (*name++ != 'i' || *name++ != 'p') return -1;
-    n= strtoul(name, &end, 10);
-    if (end == name || *end != 0) return -1;
-    if (n >= N_NETS) return -1;
-    return n;
-}
-
-network_t *if2net(int n)
-{
-    /* Translate an interface number to a network struct. */
-    int i;
-
-    for (i= 0; i < n_nets; i++) {
-       if (network[i]->n == n) return network[i];
-    }
-    return nil;
-}
-
-static ipaddr_t defaultmask(ipaddr_t ip)
-{
-    /* Compute netmask by the oldfashioned Class rules. */
-    if (B(&ip)[0] < 0x80) return htonl(0xFF000000UL);  /* Class A. */
-    if (B(&ip)[0] < 0xC0) return htonl(0xFFFF0000UL);  /* Class B. */
-    if (B(&ip)[0] < 0xE0) return htonl(0xFFFFFF00UL);  /* Class C. */
-    return htonl(0xFFFFFFFFUL);  /* Multicast?  Shouldn't happen... */
-}
-
-#define POOL_MAGIC     htonl(0x81F85D00UL)
-
-typedef struct pool {          /* Dynamic pool entry. */
-       u32_t           magic;          /* Pool file magic number. */
-       ipaddr_t        ip;             /* IP address. */
-       u32_t           expire;         /* When does/did the lease expire? */
-       u8_t            len;            /* Client ID length. */
-       u8_t            unused[19];     /* Space for extensions. */
-       u8_t            clid[CLID_MAX]; /* Client ID of current/last user. */
-} pool_t;
-
-static int openpool(int mode)
-{
-    /* Open the dynamic pool and lock it, return fd on success or -1. */
-    int fd;
-    struct flock lck;
-
-    if ((fd= open(poolfile, mode, 0644)) < 0) {
-       if (errno != ENOENT) fatal(poolfile);
-       return -1;
-    }
-    if (mode != O_RDONLY) {
-       lck.l_type= F_WRLCK;
-       lck.l_whence= SEEK_SET;
-       lck.l_start= 0;
-       lck.l_len= 0;
-       if (fcntl(fd, F_SETLKW, &lck) < 0) fatal(poolfile);
-    }
-    return fd;
-}
-
-static int readpool(int fd, pool_t *entry)
-{
-    /* Read one pool table entry, return true unless EOF. */
-    ssize_t r;
-
-    if ((r= read(fd, entry, sizeof(*entry))) < 0) fatal(poolfile);
-    if (r == 0) return 0;
-
-    if (r != sizeof(*entry) || entry->magic != POOL_MAGIC) {
-       fprintf(stderr, "%s: %s: Pool table is corrupt\n",
-           program, poolfile);
-       close(fd);
-       return 0;
-    }
-    return 1;
-}
-
-static void writepool(int fd, pool_t *entry)
-{
-    /* (Over)write a pool table entry. */
-    if (write(fd, entry, sizeof(*entry)) < 0
-       || (entry->expire > now && fsync(fd) < 0)
-    ) {
-       fatal(poolfile);
-    }
-}
-
-static ipaddr_t findpool(u8_t *client, size_t len, ipaddr_t ifip)
-{
-    /* Look for a client ID in the dynamic address pool within the same network
-     * as 'ifip'.  Select an unused one for a new client if necessary.  Return
-     * 0 if nothing is available, otherwise the IP address we can offer.
-     */
-    int fd, found;
-    pool_t entry, oldest;
-    dhcp_t dhcp;
-    u8_t *pmask;
-    ipaddr_t mask;
-
-    /* Any information available on the network the client is at? */
-    if (!makedhcp(&dhcp, nil, 0, nil, 0, ifip, ifip, nil)) return 0;
-
-    if ((fd= openpool(O_RDWR)) < 0) return 0;
-
-    (void) gettag(&dhcp, DHCP_TAG_NETMASK, &pmask, nil);
-    memcpy(&mask, pmask, sizeof(mask));
-
-    oldest.expire= NEVER;
-    while ((found= readpool(fd, &entry))) {
-       /* Deleted entry? */
-       if (entry.ip == 0) continue;
-
-       /* Correct network? */
-       if (((entry.ip ^ ifip) & mask) != 0) continue;
-
-       /* Client present? */
-       if (entry.len == len && memcmp(entry.clid, client, len) == 0) break;
-
-       /* Oldest candidate for a new lease? */
-       entry.expire= ntohl(entry.expire);
-       if (entry.expire < oldest.expire) oldest= entry;
-    }
-    close(fd);
-
-    if (found) return entry.ip;
-    if (oldest.expire <= now) return oldest.ip;
-    return 0;
-}
-
-static int commitpool(ipaddr_t ip, u8_t *client, size_t len, time_t expire)
-{
-    /* Commit a new binding to stable storage, return true on success. */
-    int fd;
-    pool_t entry;
-
-    if ((fd= openpool(O_RDWR)) < 0) return 0;
-
-    do {
-       if (!readpool(fd, &entry)) {
-           close(fd);
-           return 0;
-       }
-    } while (entry.ip != ip);
-
-    entry.expire= htonl(expire);
-    entry.len= len;
-    memcpy(entry.clid, client, len);
-    if (lseek(fd, -(off_t)sizeof(entry), SEEK_CUR) == -1) fatal(poolfile);
-    writepool(fd, &entry);
-    close(fd);
-    return 1;
-}
-
-static void updatepool(int add, const char *name)
-{
-    /* Add a new IP address to the dynamic pool. */
-    ipaddr_t ip;
-    int fd, i;
-    pool_t entry;
-    struct hostent *he;
-    off_t off, off0;
-
-    if ((he= gethostbyname(name)) == nil || he->h_addrtype != AF_INET) {
-       fprintf(stderr, "%s: %s: Unknown host\n", program, name);
-       exit(1);
-    }
-    for (i= 0; he->h_addr_list[i] != nil; i++) {}
-    if (i != 1) {
-       fprintf(stderr, "%s: %s has %d addresses\n", program, name, i);
-       exit(1);
-    }
-    memcpy(&ip, he->h_addr_list[0], sizeof(ip));
-
-    if ((fd= openpool(O_RDWR|O_CREAT)) < 0) fatal(poolfile);
-
-    off= 0;
-    off0= -1;
-    while (readpool(fd, &entry)) {
-       if (add) {
-           if (entry.ip == ip) {
-               fprintf(stderr, "%s: %s: %s is already present\n",
-                   program, poolfile, name);
-               exit(1);
-           }
-           if (entry.ip == 0 && off0 == -1) off0= off;
-       } else {
-           if (entry.ip == ip) {
-               memset(&entry, 0, sizeof(entry));
-               entry.magic= POOL_MAGIC;
-               entry.ip= 0;
-               if (lseek(fd, off, SEEK_SET) == -1) fatal(poolfile);
-               writepool(fd, &entry);
-           }
-       }
-       off+= sizeof(entry);
-    }
-
-    if (add) {
-       if (off0 != -1 && lseek(fd, off0, SEEK_SET) == -1) fatal(poolfile);
-       memset(&entry, 0, sizeof(entry));
-       entry.magic= POOL_MAGIC;
-       entry.ip= ip;
-       writepool(fd, &entry);
-    }
-    close(fd);
-}
-
-static void cachedhcp(int n, dhcp_t *dp)
-{
-    /* Store a DHCP packet in a cache where those who care can find it. */
-    static int inited;
-    FILE *fp;
-    int fd;
-    int mode;
-
-    if (test > 0) return;
-
-    if (!inited) {
-       /* First time, clear store and also save my pid. */
-       if ((fp= fopen(PATH_DHCPPID, "w")) != nil) {
-           if (fprintf(fp, "%d\n", getpid()) == EOF || fclose(fp) == EOF) {
-               fatal(PATH_DHCPPID);
-           }
-       }
-       inited= 1;
-       mode= O_WRONLY | O_CREAT | O_TRUNC;
-    } else {
-       mode= O_WRONLY;
-    }
-
-    dp->xid= htonl(now);       /* To tell how old this data is. */
-
-    if ((fd= open(cachefile, mode, 0666)) < 0
-       || lseek(fd, (off_t) n * sizeof(*dp), SEEK_SET) == -1
-       || write(fd, dp, sizeof(*dp)) < 0
-       || close(fd) < 0
-    ) {
-       if (errno != ENOENT) fatal(cachefile);
-    }
-}
-
-static void printdata(void)
-{
-    /* Show the contents of the cache and the dynamic pool. */
-    int fd;
-    dhcp_t d;
-    ssize_t r;
-    int i;
-    pool_t entry;
-    unsigned long expire;
-    char delta[3*sizeof(u32_t)];
-
-    initdhcpconf();
-
-    if ((fd= open(cachefile, O_RDONLY)) < 0) fatal(cachefile);
-    i= 0;
-    while ((r= read(fd, &d, sizeof(d))) == sizeof(d)) {
-       if (d.yiaddr != 0) {
-           printf("DHCP data for network %d:\n", i);
-           printdhcp(&d);
-       }
-       i++;
-    }
-    if (r < 0) fatal(cachefile);
-    close(fd);
-
-    if ((fd= openpool(O_RDONLY)) >= 0) {
-       printf("Dynamic address pool since %ld:\n", (long) now);
-       while (readpool(fd, &entry)) {
-           if (entry.ip == 0) continue;
-           expire= ntohl(entry.expire);
-           if (expire == 0) {
-               strcpy(delta, "unused");
-           } else
-           if (expire == 0xFFFFFFFFUL) {
-               strcpy(delta, "infinite");
-           } else
-           if (expire < now) {
-               sprintf(delta, "-%llu", now - expire);
-           } else {
-               sprintf(delta, "+%llu", expire - now);
-           }
-           printf("\t%-15s %8s  ", inet_ntoa(*(struct in_addr *)&entry.ip),
-               delta);
-           for (i= 0; i < entry.len; i++) {
-               printf("%02X", entry.clid[i]);
-           }
-           fputc('\n', stdout);
-       }
-       close(fd);
-    }
-}
-
-static udpport_t portbyname(const char *name)
-{
-    struct servent *se;
-
-    if ((se= getservbyname(name, "udp")) == nil) {
-       fprintf(stderr, "%s: Unknown port \"%s\"\n", program, name);
-       exit(1);
-    }
-    return se->s_port;
-}
-
-static int sendpacket(network_t *np, void *data, size_t len)
-{
-    /* Send out a packet using a filedescriptor that is probably in async mode,
-     * so first dup() a sync version, then write.  Return true on success.
-     */
-    int fd;
-    ssize_t r;
-
-    if ((fd= dup(np->fdp->fd)) < 0) fatal("Can't dup()");
-    if ((r= write(fd, data, len)) < 0) {
-       report(np->fdp->device);
-       sleep(10);
-    }
-    close(fd);
-    return r >= 0;
-}
-
-static size_t servdhcp(network_t *np, buf_t *bp, size_t dlen)
-{
-    buf_t *abp= nil;
-    ipaddr_t cip, ifip;
-    u8_t defclid[1+sizeof(bp->dhcp->chaddr)];
-    u8_t *pdata, *client, *class, *server, *reqip, *lease;
-    u32_t expire;
-    size_t len, cilen, calen;
-    int type, dyn;
-    u8_t atype;
-    static char NAKMESS[] = "IP address requested isn't yours";
-
-    if (test > 0) return 0;
-
-    /* The IP address of the interface close to the client. */
-    ifip= bp->dhcp->giaddr != 0 ? bp->dhcp->giaddr : np->ip;
-
-    /* All kinds of DHCP tags. */
-    if (gettag(bp->dhcp, DHCP_TAG_TYPE, &pdata, nil)) {
-       type= *pdata;
-    } else {
-       type= -1;               /* BOOTP? */
-    }
-
-    if (!gettag(bp->dhcp, DHCP_TAG_CLIENTID, &client, &cilen)) {
-       defclid[0]= bp->dhcp->htype;
-       memcpy(defclid+1, bp->dhcp->chaddr, bp->dhcp->hlen);
-       client= defclid;
-       cilen= 1+bp->dhcp->hlen;
-    }
-
-    if (!gettag(bp->dhcp, DHCP_TAG_CLASSID, &class, &calen)) {
-       calen= 0;
-    }
-
-    if (!gettag(bp->dhcp, DHCP_TAG_SERVERID, &server, nil)) {
-       server= B(&np->ip);
-    }
-
-    if (!gettag(bp->dhcp, DHCP_TAG_REQIP, &reqip, nil)) {
-       reqip= nil;
-    }
-
-    /* I'm a server?  Then see if I know this client. */
-    if ((np->flags & NF_SERVING)
-       && bp->dhcp->op == DHCP_BOOTREQUEST
-       && between(1, bp->dhcp->hlen, sizeof(bp->dhcp->chaddr))
-       && (server == nil || memcmp(server, &np->ip, sizeof(np->ip)) == 0)
-    ) {
-       get_buf(&abp);
-
-       /* Is the client in my tables? */
-       (void) makedhcp(abp->dhcp, class, calen, client, cilen, 0, ifip, nil);
-       cip= abp->dhcp->yiaddr;
-
-       dyn= 0;
-       /* If not, do we have a dynamic address? */
-       if (cip == 0 && (cip= findpool(client, cilen, ifip)) != 0) dyn= 1;
-
-       if (type == DHCP_INFORM) {
-           /* The client already has an address, it just wants information.
-            * We only answer if we could answer a normal request (cip != 0),
-            * unless configured to answer anyone.
-            */
-           if (cip != 0 || (np->flags & NF_INFORM)) cip= bp->dhcp->ciaddr;
-       }
-
-       if (cip == 0 || !makedhcp(abp->dhcp, class, calen,
-                                       client, cilen, cip, ifip, nil)) {
-           put_buf(&abp);
-       }
-
-       if (abp != nil) {
-           if (gettag(abp->dhcp, DHCP_TAG_LEASE, &lease, nil)) {
-               memcpy(&expire, lease, sizeof(expire));
-               expire= now + ntohl(expire);
-               if (expire < now) expire= 0xFFFFFFFFUL;
-           } else {
-               if (dyn) {
-                   /* A dynamic address must have a lease. */
-                   fprintf(stderr, "%s: No lease set for address %s\n",
-                       program, inet_ntoa(*(struct in_addr *)&cip));
-                   exit(1);
-               }
-               lease= nil;
-               expire= 0xFFFFFFFFUL;
-           }
-
-           /* What does our client want, and what do we say? */
-           switch (type) {
-           case DHCP_DISCOVER:
-               atype= DHCP_OFFER;
-
-               /* Assign this address for a short moment. */
-               if (dyn && !commitpool(cip, client, cilen, now + DELTA_FAST)) {
-                   put_buf(&abp);
-               }
-               break;
-
-           case -1:/* BOOTP */
-           case DHCP_REQUEST:
-           case DHCP_INFORM:
-               atype= DHCP_ACK;
-               /* The address wanted must be the address we offer. */
-               if ((reqip != nil && memcmp(reqip, &cip, sizeof(cip)) != 0)
-                   || (bp->dhcp->ciaddr != 0 && bp->dhcp->ciaddr != cip)
-               ) {
-                   atype= DHCP_NAK;
-               } else
-               if (dyn && type == DHCP_REQUEST) {
-                   /* Assign this address for the duration of the lease. */
-                   if (!commitpool(cip, client, cilen, expire)) put_buf(&abp);
-               }
-               break;
-
-           case DHCP_DECLINE:
-               /* Our client doesn't want the offered address! */
-               if (dyn
-                   && reqip != nil
-                   && memcmp(reqip, &cip, sizeof(cip)) == 0
-               ) {
-                   int i;
-
-                   fprintf(stderr, "%s: ", program);
-                   for (i= 0; i < cilen; i++) {
-                       fprintf(stderr, "%02X", client[i]);
-                   }
-                   fprintf(stderr, " declines %s",
-                       inet_ntoa(*(struct in_addr *)&cip));
-                   if (gettag(bp->dhcp, DHCP_TAG_MESSAGE, &pdata, &len)) {
-                       fprintf(stderr, " saying: \"%.*s\"", (int)len, pdata);
-                   }
-                   fputc('\n', stderr);
-
-                   /* Disable address for the duration of the lease. */
-                   (void) commitpool(cip, nil, 0, expire);
-               }
-               put_buf(&abp);
-               break;
-
-           case DHCP_RELEASE:
-               /* Our client is nice enough to return its address. */
-               if (dyn) (void) commitpool(cip, client, cilen, now);
-               put_buf(&abp);
-               break;
-
-           default:    /* Anything else is ignored. */
-               put_buf(&abp);
-           }
-       }
-
-       if (abp != nil) {
-           /* Finish the return packet. */
-           abp->dhcp->htype= bp->dhcp->htype;
-           abp->dhcp->hlen= bp->dhcp->hlen;
-           abp->dhcp->hops= 0;
-           abp->dhcp->xid= bp->dhcp->xid;
-           abp->dhcp->secs= 0;
-           abp->dhcp->flags= bp->dhcp->flags;
-           abp->dhcp->ciaddr= 0;
-           abp->dhcp->yiaddr= atype == DHCP_NAK ? 0 : cip;
-           if (atype == DHCP_NAK) abp->dhcp->siaddr= 0;
-           abp->dhcp->giaddr= bp->dhcp->giaddr;
-           memcpy(abp->dhcp->chaddr,bp->dhcp->chaddr,sizeof(bp->dhcp->chaddr));
-
-           settag(abp->dhcp, DHCP_TAG_SERVERID, &np->ip, sizeof(np->ip));
-
-           if (lease == nil) {
-               /* No lease specified?  Then give an infinite lease. */
-               settag(abp->dhcp, DHCP_TAG_LEASE, &expire, sizeof(expire));
-           }
-
-           if (type == DHCP_INFORM) {
-               /* Oops, this one has a fixed address, so no lease business. */
-               abp->dhcp->yiaddr= 0;
-               settag(abp->dhcp, DHCP_TAG_LEASE, nil, 0);
-               settag(abp->dhcp, DHCP_TAG_RENEWAL, nil, 0);
-               settag(abp->dhcp, DHCP_TAG_REBINDING, nil, 0);
-           }
-
-           if (atype == DHCP_NAK) {
-               /* A NAK doesn't need much. */
-               memset(abp->dhcp->sname, 0, sizeof(abp->dhcp->sname));
-               memset(abp->dhcp->file, 0, sizeof(abp->dhcp->file));
-               memset(abp->dhcp->options, 255, sizeof(abp->dhcp->options));
-               settag(abp->dhcp, DHCP_TAG_MESSAGE, NAKMESS, sizeof(NAKMESS));
-           }
-
-           settag(abp->dhcp, DHCP_TAG_TYPE, &atype, sizeof(atype));
-
-           /* Figure out where to send this to. */
-           abp->udpio->uih_src_addr= np->ip;
-           abp->udpio->uih_src_port= port_server;
-           if (bp->dhcp->giaddr != 0) {
-               abp->udpio->uih_dst_addr= bp->dhcp->giaddr;
-               abp->udpio->uih_dst_port= port_server;
-           } else
-           if (bp->dhcp->flags & DHCP_FLAGS_BCAST) {
-               abp->udpio->uih_dst_addr= BCAST_IP;
-               abp->udpio->uih_dst_port= port_client;
-           } else
-           if (bp->udpio->uih_src_addr != 0
-               && bp->udpio->uih_dst_addr == np->ip
-           ) {
-               abp->udpio->uih_dst_addr= bp->udpio->uih_src_addr;
-               abp->udpio->uih_dst_port= port_client;
-           } else {
-               abp->udpio->uih_dst_addr= BCAST_IP;
-               abp->udpio->uih_dst_port= port_client;
-           }
-           abp->udpio->uih_ip_opt_len= 0;
-           abp->udpio->uih_data_len= sizeof(dhcp_t);
-
-           /* Copy the packet to the input buffer, and return the new size. */
-           memcpy(bp->buf, abp->buf, sizeof(bp->buf));
-           put_buf(&abp);
-           return sizeof(udp_io_hdr_t) + sizeof(dhcp_t);
-       }
-    }
-
-    /* I'm a relay?  If it is a not already a relayed request then relay. */
-    if ((np->flags & NF_RELAYING)
-       && bp->dhcp->op == DHCP_BOOTREQUEST
-       && bp->dhcp->giaddr == 0
-    ) {
-       bp->dhcp->giaddr= np->ip;
-       bp->udpio->uih_src_addr= np->ip;
-       bp->udpio->uih_src_port= port_server;
-       bp->udpio->uih_dst_addr= np->server;
-       bp->udpio->uih_dst_port= port_server;
-       return dlen;
-    }
-
-    /* I'm a relay?  If the server sends a reply to me then relay back. */
-    if ((np->flags & NF_RELAYING)
-       && bp->dhcp->op == DHCP_BOOTREPLY
-       && bp->dhcp->giaddr == np->ip
-    ) {
-       bp->dhcp->giaddr= 0;
-       bp->udpio->uih_src_addr= np->ip;
-       bp->udpio->uih_src_port= port_server;
-       bp->udpio->uih_dst_addr= BCAST_IP;
-       bp->udpio->uih_dst_port= port_client;
-       return dlen;
-    }
-
-    /* Don't know what to do otherwise, so doing nothing seems wise. */
-    return 0;
-}
-
-static void onsig(int sig)
-{
-    switch (sig) {
-    case SIGUSR1:      debug++;        break;
-    case SIGUSR2:      debug= 0;       break;
-    }
-}
-
-static void usage(void)
-{
-    fprintf(stderr,
-"Usage: %s [-qar] [-t[L]] [-d[L]] [-f config] [-c cache] [-p pool] [host ...]\n",
-       program);
-    exit(1);
-}
-
-int main(int argc, char **argv)
-{
-    int i;
-    network_t *np;
-    struct sigaction sa;
-    ssize_t r;
-    buf_t *bp;
-    static struct timeval eventtv;
-
-main:
-    n_nets = 0;
-    r = -1;
-    bp = nil;
-    program= argv[0];
-    start= now= time(nil);
-
-    debug= 0;
-    i= 1;
-    while (i < argc && argv[i][0] == '-') {
-       char *opt= argv[i++]+1;
-
-       if (opt[0] == '-' && opt[1] == 0) break;        /* -- */
-       
-       if (strcmp(opt, "-lwip") == 0) {
-               lwip = 1;
-               continue;
-       }
-
-       while (*opt != 0) switch (*opt++) {
-       case 'f':
-           if (*opt == 0) {
-               if (i == argc) usage();
-               opt= argv[i++];
-           }
-           configfile= opt;
-           opt= "";
-           break;
-       case 'c':
-           if (*opt == 0) {
-               if (i == argc) usage();
-               opt= argv[i++];
-           }
-           cachefile= opt;
-           opt= "";
-           break;
-       case 'p':
-           if (*opt == 0) {
-               if (i == argc) usage();
-               opt= argv[i++];
-           }
-           poolfile= opt;
-           opt= "";
-           break;
-       case 't':
-           test= 1;
-           if (between('0', *opt, '9')) test= strtoul(opt, &opt, 10);
-           break;
-       case 'd':
-           debug= 1;
-           if (between('0', *opt, '9')) debug= strtoul(opt, &opt, 10);
-           break;
-       case 'q':
-           qflag= 1;
-           break;
-       case 'a':
-           aflag= 1;
-           break;
-       case 'r':
-           rflag= 1;
-           break;
-       default:
-           usage();
-       }
-    }
-    if (aflag + rflag + qflag > 1) usage();
-
-    if (aflag || rflag) {
-       /* Add or remove addresses from the dynamic pool. */
-       while (i < argc) updatepool(aflag, argv[i++]);
-       exit(0);
-    }
-
-    if (i != argc) usage();
-
-    if (qflag) {
-       /* Only show the contents of the cache and dynamic pool to the user. */
-       printdata();
-       exit(0);
-    }
-
-    /* BOOTP ports. */
-    port_server= portbyname("bootps");
-    port_client= portbyname("bootpc");
-
-    sa.sa_handler= onsig;
-    sigemptyset(&sa.sa_mask);
-    sa.sa_flags= 0;
-    sigaction(SIGUSR1, &sa, nil);
-    sigaction(SIGUSR2, &sa, nil);
-
-    /* Initial configuration. */
-    for (i= 0; i < N_NETS; i++) {
-       int fd;
-       ipaddr_t ip, mask;
-
-       /* Is there something there? */
-       if ((fd= open(ipdev(i), O_RDWR|O_NONBLOCK)) < 0) {
-           if (errno != ENOENT && errno != ENODEV && errno != ENXIO) {
-               fatal(ipdev(i));
-           }
-           continue;
-       }
-       close(fd);
-
-       network[n_nets++]= np= newnetwork();
-       np->n= i;
-
-       /* Ethernet? */
-       if (lwip) {
-               np->type = NT_ETHERNET;
-       } else if (opendev(np, FT_ETHERNET, 1)) {
-           np->type= B(&np->eth)[0] != 'Z' ? NT_ETHERNET : NT_SINK;
-           if (debug >= 1) {
-               printf("%s: Ethernet address is %s%s\n",
-                   np->fdp->device, ether_ntoa(&np->eth),
-                   np->type == NT_SINK ? " (sink)" : "");
-           }
-           closedev(np, FT_ETHERNET);
-       }
-
-       /* Only true Ethernets worry about DHCP. */
-       if (np->type != NT_ETHERNET) np->renew= np->rebind= np->lease= NEVER;
-    }
-
-    /* Try to find my interfaces in the DHCP table. */
-    for (i= 0; i < n_nets; i++) {
-       ipaddr_t cip;
-       u8_t clid[1+DHCP_HLEN_ETH];
-       size_t cilen;
-
-       np= network[i];
-       if (np->flags & NF_BOUND) continue;
-
-       if (np->type == NT_IP) {
-           cilen= 0;
-       } else {
-           ether2clid(clid, &np->eth);
-           cilen= 1+DHCP_HLEN_ETH;
-       }
-
-       /* Try to find an Ethernet address, or the IP address of an already
-        * configured network.  If we have data we get an IP address back.
-        */
-       get_buf(&bp);
-       (void) makedhcp(bp->dhcp, (u8_t *) "Minix", 5,
-                                       clid, cilen, np->ip, 0, np);
-       cip= bp->dhcp->yiaddr;
-
-       /* Gather information on the interface. */
-       if (cip != 0
-           && makedhcp(bp->dhcp, (u8_t *) "Minix", 5,
-                                       clid, cilen, cip, cip, np)
-           && test < 2
-       ) {
-           u8_t *pdata;
-           u16_t mtu;
-
-           cachedhcp(np->n, bp->dhcp);
-           np->ip= cip;
-           (void) gettag(bp->dhcp, DHCP_TAG_NETMASK, &pdata, nil);
-           memcpy(&np->mask, pdata, sizeof(np->mask));
-           if (gettag(bp->dhcp, DHCP_TAG_GATEWAY, &pdata, nil)) {
-               memcpy(&np->gateway, pdata, sizeof(np->gateway));
-           } else {
-               np->gateway= 0;
-           }
-           if (gettag(bp->dhcp, DHCP_TAG_IPMTU, &pdata, nil)) {
-               memcpy(&mtu, pdata, sizeof(mtu));
-               mtu= ntohs(mtu);
-           } else {
-               mtu= 0;
-           }
-           set_ipconf(ipdev(np->n), np->ip, np->mask, mtu);
-           if (debug >= 1) {
-               printf("%s: IP address is %s\n",
-                   ipdev(np->n), cidr_ntoa(np->ip, np->mask));
-           }
-           np->flags |= NF_BOUND;
-           np->renew= np->rebind= np->lease= NEVER;
-           np->sol_ct= N_SOLICITS;
-           np->solicit= 0;
-
-           /* Other (previous) interfaces may have been defined. */
-           i= 0;
-       }
-       put_buf(&bp);
-    }
-
-    for (;;) {
-       now= time(nil);
-       event= NEVER;
-
-       /* Is it time to request/renew a lease? */
-       for (i= 0; i < n_nets; i++) {
-           np= network[i];
-
-           if (np->renew <= now) {
-               u8_t type;
-               static u8_t taglist[] = {
-                   DHCP_TAG_NETMASK, DHCP_TAG_GATEWAY, DHCP_TAG_DNS,
-                       DHCP_TAG_HOSTNAME
-               };
-               u8_t ethclid[1+DHCP_HLEN_ETH];
-
-               /* We may have lost our binding or even our lease. */
-               if (np->rebind <= now) np->server= BCAST_IP;
-
-               if (np->lease <= now) {
-                   if (np->flags & NF_BOUND) closedev(np, FT_ALL);
-
-                   if ((np->flags & (NF_BOUND | NF_POSSESSIVE)) == NF_BOUND) {
-                       set_ipconf(ipdev(np->n), np->ip= 0, np->mask= 0, 0);
-                       if (debug >= 1) {
-                           printf("%s: Interface disabled (lease expired)\n",
-                               ipdev(np->n));
-                       }
-                   }
-                   np->flags &= ~NF_BOUND;
-               }
-
-               /* See if we can open the network we need to send on. */
-               if (!(np->flags & NF_BOUND)) {
-                   if (!opendev(np, FT_ETHERNET, 1)) continue;
-               } else {
-                   if (!opendev(np, FT_BOOTPC, 1)) continue;
-               }
-
-               if (!(np->flags & NF_NEGOTIATING)) {
-                   /* We need to start querying a DHCP server. */
-                   np->start= now;
-                   np->delta= DELTA_FIRST;
-                   np->flags |= NF_NEGOTIATING;
-               }
-
-               /* Fill in a DHCP query packet. */
-               get_buf(&bp);
-               dhcp_init(bp->dhcp);
-               bp->dhcp->op= DHCP_BOOTREQUEST;
-               bp->dhcp->htype= DHCP_HTYPE_ETH;
-               bp->dhcp->hlen= DHCP_HLEN_ETH;
-               bp->dhcp->xid= XID(np);
-               bp->dhcp->secs= htons(now - np->start > 0xFFFF
-                                       ? 0xFFFF : now - np->start);
-               memcpy(bp->dhcp->chaddr, &np->eth, sizeof(np->eth));
-
-               if (np->lease <= now) {
-                   /* First time, or my old server is unresponsive. */
-                   type= DHCP_DISCOVER;
-               } else {
-                   /* Request an offered address or renew an address. */
-                   type= DHCP_REQUEST;
-                   if (np->flags & NF_BOUND) {
-                       /* A renewal, I claim my current address. */
-                       bp->dhcp->ciaddr= np->ip;
-                   } else {
-                       /* Nicely ask for the address just offered. */
-                       settag(bp->dhcp, DHCP_TAG_REQIP, &np->ip,
-                                                       sizeof(np->ip));
-                       settag(bp->dhcp, DHCP_TAG_SERVERID, &np->server,
-                                                       sizeof(np->server));
-                   }
-               }
-               settag(bp->dhcp, DHCP_TAG_TYPE, &type, 1);
-
-               /* My client ID.  Simply use the default. */
-               ether2clid(ethclid, &np->eth);
-               settag(bp->dhcp, DHCP_TAG_CLIENTID, ethclid, sizeof(ethclid));
-
-               /* The Class ID may serve to recognize Minix hosts. */
-               settag(bp->dhcp, DHCP_TAG_CLASSID, "Minix", 5);
-
-               /* The few tags that Minix can make good use of. */
-               settag(bp->dhcp, DHCP_TAG_REQPAR, taglist, sizeof(taglist));
-
-               /* Some weird sites use a hostname, not a client ID. */
-               if (np->hostname != nil) {
-                   settag(bp->dhcp, DHCP_TAG_HOSTNAME,
-                               (void *)np->hostname, strlen(np->hostname));
-               }
-
-               bp->udpio->uih_src_addr= np->ip;
-               bp->udpio->uih_dst_addr= np->server;
-               bp->udpio->uih_src_port= port_client;
-               bp->udpio->uih_dst_port= port_server;
-               bp->udpio->uih_ip_opt_len= 0;
-               bp->udpio->uih_data_len= sizeof(dhcp_t);
-
-               if (!(np->flags & NF_BOUND)) {
-                   /* Rebind over Ethernet. */
-                   udp2ether(bp, np);
-                   if (sendpacket(np, (lwip ? bp->ip : (void *) bp->eth), 
-                                       (lwip ? 0 : sizeof(eth_hdr_t)) + sizeof(ip_hdr_t)
-                                       + sizeof(udp_hdr_t) + sizeof(dhcp_t))) {
-                       if (debug >= 1) {
-                           printf("%s: Broadcast DHCP %s\n",
-                               np->fdp->device, dhcptypename(type));
-                           if (debug >= 2) printdhcp(bp->dhcp);
-                       }
-                   }
-               } else {
-                   /* Renew over UDP. */
-                   if (sendpacket(np, bp->udpio, sizeof(udp_io_hdr_t)
-                                                       + sizeof(dhcp_t))) {
-                       if (debug >= 1) {
-                           printf("%s: Sent DHCP %s to %s\n",
-                               np->fdp->device,
-                               dhcptypename(type),
-                               inet_ntoa(*(struct in_addr *)&np->server));
-                           if (debug >= 2) printdhcp(bp->dhcp);
-                       }
-                   }
-               }
-               put_buf(&bp);
-
-               /* When to continue querying a DHCP server? */
-               if (np->flags & NF_BOUND) {
-                   /* Still bound, keep halving time till next event. */
-                   time_t e, d;
-
-                   e= now < np->rebind ? np->rebind : np->lease;
-                   d= (e - now) / 2;
-                   if (d < DELTA_SLOW) d= DELTA_SLOW;
-                   np->renew= now + d;
-                   if (np->renew > e) np->renew= e;
-               } else {
-                   /* Not bound, be desparate. */
-                   np->renew= now + np->delta;
-                   if ((np->delta *= 2) > DELTA_FAST) np->delta= DELTA_FAST;
-               }
-           }
-           if (np->renew < event) event= np->renew;
-       }
-
-       /* Read DHCP responses. */
-       for (i= 0; i < n_nets; i++) {
-           np= network[i];
-           if (!(np->flags & NF_NEGOTIATING)) continue;
-
-           if (!(np->flags & NF_BOUND)) {
-               if (!opendev(np, FT_ETHERNET, 0)) continue;
-               get_buf(&np->fdp->bp);
-               r= asyn_read(&asyn, np->fdp->fd,
-                       lwip ? np->fdp->bp->ip : (void *) np->fdp->bp->eth,
-                       lwip ? BUF_IP_SIZE : BUF_ETH_SIZE);
-           } else {
-               if (!opendev(np, FT_BOOTPC, 0)) continue;
-               get_buf(&np->fdp->bp);
-               r= asyn_read(&asyn, np->fdp->fd, np->fdp->bp->udpio,
-                                                       BUF_UDP_SIZE);
-           }
-           if (r != -1) break;
-           if (errno != ASYN_INPROGRESS && errno != EPACKSIZE) {
-               report(np->fdp->device);
-               sleep(10);
-           }
-       }
-
-       /* Is there a response? */
-       if (i < n_nets) {
-           give_buf(&bp, &np->fdp->bp);
-           if (((!(np->flags & NF_BOUND)
-                   && r >= (lwip ? 0 : (sizeof(eth_hdr_t)) + sizeof(ip_hdr_t)
-                               + sizeof(udp_hdr_t) + offsetof(dhcp_t, options))
-                   && ether2udp(bp)
-                   && bp->udpio->uih_dst_port == port_client)
-                 ||
-                 ((np->flags & NF_BOUND)
-                   && r >= sizeof(udp_io_hdr_t) + offsetof(dhcp_t, options)))
-               && bp->dhcp->op == DHCP_BOOTREPLY
-               && bp->dhcp->htype == DHCP_HTYPE_ETH
-               && bp->dhcp->hlen == DHCP_HLEN_ETH
-               && bp->dhcp->xid == XID(np)
-               && memcmp(bp->dhcp->chaddr, &np->eth, sizeof(np->eth)) == 0
-           ) {
-               /* Pfew!  We got a DHCP reply! */
-               u8_t *pdata;
-               size_t len;
-               int type;
-               ipaddr_t mask, gateway, relay, server;
-               u16_t mtu;
-               u32_t lease, renew, rebind, t;
-
-               relay= bp->udpio->uih_src_addr;
-               if (gettag(bp->dhcp, DHCP_TAG_SERVERID, &pdata, nil)) {
-                   memcpy(&server, pdata, sizeof(server));
-               } else {
-                   server= relay;
-               }
-
-               if (gettag(bp->dhcp, DHCP_TAG_TYPE, &pdata, nil)) {
-                   type= pdata[0];
-               } else {
-                   type= DHCP_ACK;     /* BOOTP? */
-               }
-
-               if (debug >= 1) {
-                   printf("%s: Got a DHCP %s from %s",
-                       np->fdp->device, dhcptypename(type),
-                       inet_ntoa(*(struct in_addr *)&server));
-                   if (relay != server)
-                       printf(" through %s\n",
-                           inet_ntoa(*(struct in_addr *)&relay));
-                   else printf("\n");
-                   if (debug >= 2) printdhcp(bp->dhcp);
-               }
-
-               if (gettag(bp->dhcp, DHCP_TAG_NETMASK, &pdata, nil)) {
-                   memcpy(&mask, pdata, sizeof(mask));
-               } else {
-                   mask= defaultmask(bp->dhcp->ciaddr);
-               }
-
-               if (gettag(bp->dhcp, DHCP_TAG_IPMTU, &pdata, nil)) {
-                   memcpy(&mtu, pdata, sizeof(mtu));
-                   mtu= ntohs(mtu);
-               } else {
-                   mtu= 0;
-               }
-
-               if (gettag(bp->dhcp, DHCP_TAG_GATEWAY, &pdata, nil)) {
-                   memcpy(&gateway, pdata, sizeof(gateway));
-               } else {
-                   gateway= 0;
-               }
-
-               lease= NEVER;
-               if (gettag(bp->dhcp, DHCP_TAG_LEASE, &pdata, nil)) {
-                   memcpy(&lease, pdata, sizeof(lease));
-                   lease= ntohl(lease);
-               }
-
-               rebind= lease - lease / 8;
-               if (gettag(bp->dhcp, DHCP_TAG_REBINDING, &pdata, nil)) {
-                   memcpy(&t, pdata, sizeof(t));
-                   t= ntohl(t);
-                   if (t < rebind) rebind= t;
-               }
-
-               renew= lease / 2;
-               if (gettag(bp->dhcp, DHCP_TAG_RENEWAL, &pdata, nil)) {
-                   memcpy(&t, pdata, sizeof(t));
-                   t= ntohl(t);
-                   if (t < renew) renew= t;
-               }
-
-               if (type == DHCP_OFFER && np->rebind <= np->renew) {
-                   /* It's an offer for an address and we haven't taken one
-                    * yet.  It's all the same to us, so take this one.
-                    */
-                   np->ip= bp->dhcp->yiaddr;
-                   np->mask= mask;
-                   np->server= server;
-                   np->gateway= gateway;
-                   np->delta= DELTA_FIRST;
-                   np->renew= now;
-                   np->rebind= np->lease= now + DELTA_FAST;
-
-                   /* Send out an ARP request to see if the offered address
-                    * is in use already.
-                    */
-                   make_arp(bp, np);
-                   if (sendpacket(np, bp->eth, sizeof(arp46_t))) {
-                       if (debug >= 2) {
-                           printf("Sent ARP for %s\n",
-                               inet_ntoa(*(struct in_addr *)&np->ip));
-                       }
-                   }
-                   np->flags &= ~NF_CONFLICT;
-               }
-
-               if (type == DHCP_ACK && !(np->flags & NF_CONFLICT)) {
-                   /* An acknowledgment.  The address is all mine. */
-                   cachedhcp(np->n, bp->dhcp);
-                   np->ip= bp->dhcp->yiaddr;
-                   np->mask= mask;
-                   np->server= server;
-                   set_ipconf(ipdev(np->n), np->ip, np->mask, mtu);
-                   if (debug >= 1) {
-                       printf("%s: Address set to %s\n",
-                           ipdev(np->n), cidr_ntoa(np->ip, np->mask));
-                   }
-                   if (lease >= NEVER - now) {
-                       /* The lease is infinite! */
-                       np->renew= np->rebind= np->lease= NEVER;
-                   } else {
-                       np->lease= now + lease;
-                       np->renew= now + renew;
-                       np->rebind= now + rebind;
-                   }
-                   if (test >= 3) {
-                       np->renew= now + 60;
-                       np->rebind= test >= 4 ? np->renew : np->renew + 60;
-                       np->lease= test >= 5 ? np->rebind : np->rebind + 60;
-                   }
-                   if (!(np->flags & NF_IRDP)) {
-                       np->sol_ct= (np->flags & NF_BOUND) ? 1 : N_SOLICITS;
-                       np->solicit= 0;
-                   }
-                   np->flags &= ~NF_NEGOTIATING;
-                   np->flags |= NF_BOUND;
-                   closedev(np, FT_ETHERNET);
-                   closedev(np, FT_BOOTPC);
-               }
-
-               if (type == DHCP_ACK && (np->flags & NF_CONFLICT)) {
-                   /* Alas there is a conflict.  Decline to use the address. */
-                   u8_t ethclid[1+DHCP_HLEN_ETH];
-                   static char USED[]= "Address in use by 00:00:00:00:00:00";
-
-                   type= DHCP_DECLINE;
-                   dhcp_init(bp->dhcp);
-                   bp->dhcp->op= DHCP_BOOTREQUEST;
-                   bp->dhcp->htype= DHCP_HTYPE_ETH;
-                   bp->dhcp->hlen= DHCP_HLEN_ETH;
-                   bp->dhcp->xid= XID(np);
-                   bp->dhcp->secs= 0;
-                   memcpy(bp->dhcp->chaddr, &np->eth, sizeof(np->eth));
-                   settag(bp->dhcp, DHCP_TAG_REQIP, &np->ip, sizeof(np->ip));
-                   settag(bp->dhcp, DHCP_TAG_TYPE, &type, 1);
-                   ether2clid(ethclid, &np->eth);
-                   settag(bp->dhcp, DHCP_TAG_CLIENTID,ethclid,sizeof(ethclid));
-                   strcpy(USED+18, ether_ntoa(&np->conflict));
-                   settag(bp->dhcp, DHCP_TAG_MESSAGE, USED, strlen(USED));
-
-                   bp->udpio->uih_src_port= port_client;
-                   bp->udpio->uih_dst_port= port_server;
-                   bp->udpio->uih_ip_opt_len= 0;
-                   bp->udpio->uih_data_len= sizeof(dhcp_t);
-                   udp2ether(bp, np);
-
-                   if (sendpacket(np, bp->eth, 
-                                       sizeof(eth_hdr_t) + sizeof(ip_hdr_t)
-                                       + sizeof(udp_hdr_t) + sizeof(dhcp_t))) {
-                       if (debug >= 1) {
-                           printf("%s: Broadcast DHCP %s\n",
-                               np->fdp->device, dhcptypename(type));
-                           if (debug >= 2) printdhcp(bp->dhcp);
-                       }
-                   }
-                   
-                   np->renew= np->rebind= np->lease= now + DELTA_FAST;
-                   np->delta= DELTA_FIRST;
-               }
-
-               if (type == DHCP_NAK) {
-                   /* Oops, a DHCP server doesn't like me, start over! */
-                   np->renew= np->rebind= np->lease= now + DELTA_FAST;
-                   np->delta= DELTA_FIRST;
-
-                   fprintf(stderr, "%s: Got a NAK from %s",
-                       program, inet_ntoa(*(struct in_addr *)&server));
-                   if (relay != server) {
-                       fprintf(stderr, " through %s",
-                         inet_ntoa(*(struct in_addr *)&relay));
-                   }
-                   if (gettag(bp->dhcp, DHCP_TAG_MESSAGE, &pdata, &len)) {
-                       fprintf(stderr, " saying: \"%.*s\"", (int)len, pdata);
-                   }
-                   fputc('\n', stderr);
-               }
-           } else
-           if (!(np->flags & NF_BOUND)
-               && np->rebind > now
-               && r >= sizeof(arp46_t)
-               && is_arp_me(bp, np)
-           ) {
-               /* Oh no, someone else is using the address offered to me! */
-               np->flags |= NF_CONFLICT;
-
-               fprintf(stderr, "%s: %s: %s offered by ",
-                       program,
-                       np->fdp->device,
-                       inet_ntoa(*(struct in_addr *)&np->ip));
-               fprintf(stderr, "%s is already in use by %s\n",
-                       inet_ntoa(*(struct in_addr *)&np->server),
-                       ether_ntoa(&np->conflict));
-           }
-           put_buf(&bp);
-           if (np->renew < event) event= np->renew;
-       }
-
-       /* Perform router solicitations. */
-       for (i= 0; i < n_nets; i++) {
-           np= network[i];
-           if (!(np->flags & NF_BOUND)) continue;
-
-           if (np->solicit <= now) {
-               if (!opendev(np, FT_ICMP, 1)) continue;
-               np->solicit= NEVER;
-
-               get_buf(&bp);
-               if (np->gateway != 0) {
-                   /* No IRDP response seen yet, advertise the router given
-                    * by DHCP to my own interface.
-                    */
-                   icmp_advert(bp, np);
-                   if (sendpacket(np, bp->ip, sizeof(ip_hdr_t) + 16)) {
-                       if (debug >= 2) {
-                           printf("%s: Sent advert for %s to self\n",
-                               np->fdp->device,
-                               inet_ntoa(*(struct in_addr *)&np->gateway));
-                       }
-                   }
-                   np->solicit= now + DELTA_ADV/2;
-               }
-
-               if (np->sol_ct >= 0 && --np->sol_ct >= 0) {
-                   /* Send a router solicitation. */
-                   icmp_solicit(bp);
-                   if (sendpacket(np, bp->ip, sizeof(*bp->ip) + 8)) {
-                       if (debug >= 2) {
-                           printf("%s: Broadcast router solicitation\n",
-                               np->fdp->device);
-                       }
-                   }
-                   np->solicit= now + DELTA_SOL;
-               } else {
-                   /* No response, or not soliciting right now. */
-                   closedev(np, FT_ICMP);
-               }
-
-               put_buf(&bp);
-           }
-           if (np->solicit < event) event= np->solicit;
-       }
-
-       /* Read router adverts. */
-       for (i= 0; i < n_nets; i++) {
-           np= network[i];
-           if (!(np->flags & NF_BOUND)) continue;
-           if (np->sol_ct < 0) continue;
-
-           if (!opendev(np, FT_ICMP, 0)) continue;
-           get_buf(&np->fdp->bp);
-           r= asyn_read(&asyn, np->fdp->fd, np->fdp->bp->ip, BUF_IP_SIZE);
-           if (r != -1) break;
-           if (errno != ASYN_INPROGRESS && errno != EPACKSIZE) {
-               report(np->fdp->device);
-               sleep(10);
-           }
-       }
-
-       /* Is there an advert? */
-       if (i < n_nets && r >= sizeof(ip_hdr_t) + 8) {
-           ipaddr_t router;
-
-           give_buf(&bp, &np->fdp->bp);
-           if ((router= icmp_is_advert(bp)) != 0) {
-               if (debug >= 2) {
-                   printf("%s: Router advert received from %s\n",
-                       np->fdp->device,
-                       inet_ntoa(*(struct in_addr *)&router));
-               }
-               np->solicit= NEVER;
-               np->sol_ct= -1;
-               np->flags |= NF_IRDP;
-               closedev(np, FT_ICMP);
-           }
-           put_buf(&bp);
-       }
-
-       /* We start serving if all the interfaces so marked are configured. */
-       for (i= 0; i < n_nets; i++) {
-           np= network[i];
-           if ((np->flags & NF_RELAYING) && (np->flags & NF_BOUND)) {
-               if (((np->ip ^ np->server) & np->mask) == 0) {
-                   /* Don't relay to a server that is on this same net. */
-                   np->flags &= ~NF_RELAYING;
-               }
-           }
-           if (!(np->flags & (NF_SERVING|NF_RELAYING))) continue;
-           if (!(np->flags & NF_BOUND)) { serving= 0; break; }
-           serving= 1;
-       }
-
-       /* Read DHCP requests. */
-       for (i= 0; i < n_nets; i++) {
-           np= network[i];
-           if (!(np->flags & NF_BOUND)) continue;
-           if (!(np->flags & (NF_SERVING|NF_RELAYING)) || !serving) continue;
-
-           if (!opendev(np, FT_BOOTPS, 0)) continue;
-           get_buf(&np->fdp->bp);
-           r= asyn_read(&asyn, np->fdp->fd, np->fdp->bp->udpio, BUF_UDP_SIZE);
-
-           if (r != -1) break;
-           if (errno != ASYN_INPROGRESS && errno != EPACKSIZE) {
-               report(np->fdp->device);
-               sleep(10);
-           }
-       }
-
-       /* Is there a request? */
-       if (i < n_nets
-           && r >= sizeof(udp_io_hdr_t) + offsetof(dhcp_t, options)
-       ) {
-           give_buf(&bp, &np->fdp->bp);
-
-           if (debug >= 1) {
-               printf("%s: Got DHCP packet from %s to ",
-                   np->fdp->device,
-                   inet_ntoa(*(struct in_addr *)&bp->udpio->uih_src_addr));
-               printf("%s\n",
-                   inet_ntoa(*(struct in_addr *)&bp->udpio->uih_dst_addr));
-               if (debug >= 2) printdhcp(bp->dhcp);
-           }
-
-           /* Can we do something with this DHCP packet? */
-           if ((r= servdhcp(np, bp, r)) > 0) {
-               /* Yes, we have something to send somewhere. */
-               if (sendpacket(np, bp->udpio, r)) {
-                   if (debug >= 1) {
-                       printf("%s: Sent DHCP packet to %s\n",
-                           np->fdp->device,
-                           inet_ntoa(*(struct in_addr *)
-                           &bp->udpio->uih_dst_addr));
-                       if (debug >= 2) printdhcp(bp->dhcp);
-                   }
-               }
-           }
-           put_buf(&bp);
-       }
-
-       if (debug >= 1) {
-           static char *lastbrk;
-           extern char _end;
-
-           if (sbrk(0) != lastbrk) {
-               lastbrk= sbrk(0);
-               printf("Memory use = %lu\n",
-                   (unsigned long) (lastbrk - &_end));
-           }
-           fflush(stdout);
-       }
-
-       /* Bail out if not a server, and there is nothing else to do ever. */
-       if (!serving && event == NEVER) break;
-
-       /* Wait for something to do. */
-       eventtv.tv_sec= event;
-       if (asyn_wait(&asyn, 0, event == NEVER ? nil : &eventtv) < 0) {
-           if (errno != EINTR) {
-               report("asyn_wait()");
-               sleep(10);
-           }
-       }
-    }
-    if (debug >= 1) printf("Nothing more to do! Starting over...\n");
-    sleep(2);
-    goto main;
-
-    return 0;
-}
diff --git a/minix/commands/dhcpd/dhcpd.h b/minix/commands/dhcpd/dhcpd.h
deleted file mode 100644 (file)
index 35d729d..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/*     dhcpd.h - Dynamic Host Configuration Protocol daemon.
- *                                                     Author: Kees J. Bot
- *                                                             16 Dec 2000
- */
-
-#define nil ((void*)0)
-
-#include <minix/paths.h>
-#include <net/if_ether.h>
-
-/* Paths to files. */
-#define PATH_DHCPCONF  _PATH_DHCPCONF
-#define PATH_DHCPPID   _PATH_DHCPPID
-#define PATH_DHCPCACHE _PATH_DHCPCACHE
-#define PATH_DHCPPOOL  _PATH_DHCPPOOL
-
-#define CLID_MAX       32      /* Maximum client ID length. */
-
-#ifndef EXTERN
-#define EXTERN extern
-#endif
-
-extern int lwip;
-
-EXTERN char *program;          /* This program's name. */
-extern char *configfile;       /* Configuration file. */
-extern char *poolfile;         /* Dynamic address pool. */
-EXTERN int serving;            /* True if being a DHCP server. */
-EXTERN unsigned test;          /* Test level. */
-EXTERN unsigned debug;         /* Debug level. */
-EXTERN asynchio_t asyn;                /* Bookkeeping for all async I/O. */
-
-/* BOOTP UDP ports:  (That they are different is quite stupid.) */
-EXTERN u16_t port_server;      /* Port server listens on. */
-EXTERN u16_t port_client;      /* Port client listens on. */
-
-#define arraysize(a)   (sizeof(a) / sizeof((a)[0]))
-#define arraylimit(a)  ((a) + arraysize(a))
-#define between(a,c,z) (sizeof(c) <= sizeof(unsigned) ? \
-       (unsigned) (c) - (a) <= (unsigned) (z) - (a) : \
-       (unsigned long) (c) - (a) <= (unsigned long) (z) - (a))
-
-/* To treat objects as octet arrays: */
-#define B(a)           ((u8_t *) (a))
-
-/* Times. */
-EXTERN time_t start, now;              /* Start and current time. */
-EXTERN time_t event;                   /* Time of the next timed event. */
-
-/* Special times and periods: */
-#define NEVER  (sizeof(time_t) <= sizeof(int) ? INT_MAX : LONG_MAX)
-#define DELTA_FIRST               4    /* Between first and second query. */
-#define DELTA_FAST               64    /* Unbound queries this often. */
-#define DELTA_SLOW              512    /* Bound queries are more relaxed. */
-#define N_SOLICITS                3    /* Number of solicitations. */
-#define DELTA_SOL                 3    /* Time between solicitations. */
-#define DELTA_ADV              2048    /* Router adverts to self lifetime. */
-
-/* Buffers for packets. */
-typedef struct buf {
-       eth_hdr_t       *eth;           /* Ethernet header in payload. */
-       ip_hdr_t        *ip;            /* IP header in payload. */
-       udp_hdr_t       *udp;           /* UDP header in payload. */
-       udp_io_hdr_t    *udpio;         /* UDP I/O header in payload. */
-       dhcp_t          *dhcp;          /* DHCP data in payload. */
-       u8_t            pad[2];         /* buf[] must start at 2 mod 4. */
-                                       /* Payload: */
-       u8_t            buf[ETH_MAX_PACK_SIZE];
-} buf_t;
-
-#define BUF_ETH_SIZE   (ETH_MAX_PACK_SIZE)
-#define BUF_IP_SIZE    (BUF_ETH_SIZE - sizeof(eth_hdr_t))
-#define BUF_UDP_SIZE   (BUF_IP_SIZE - sizeof(ip_hdr_t) - sizeof(udp_hdr_t) \
-                               + sizeof(udp_io_hdr_t))
-
-/* Type of network device open: Ethernet, ICMP, BOOTP client, BOOTP server. */
-typedef enum { FT_CLOSED, FT_ETHERNET, FT_ICMP, FT_BOOTPC, FT_BOOTPS } fdtype_t;
-
-#define FT_ALL FT_CLOSED       /* To close all open descriptors at once. */
-
-typedef struct fd {            /* An open descriptor. */
-       i8_t            fd;             /* Open descriptor. */
-       u8_t            fdtype;         /* Type of network open. */
-       char            device[sizeof("/dev/eth###")];  /* Device name. */
-       u8_t            n;              /* Network that owns it. */
-       buf_t           *bp;            /* Associated packet buffer. */
-       time_t          since;          /* Open since when? */
-} fd_t;
-
-/* Network state: Any IP device, Ethernet in sink mode, True Ethernet. */
-typedef enum { NT_IP, NT_SINK, NT_ETHERNET } nettype_t;
-
-typedef struct network {       /* Information on a network. */
-       u8_t            n;              /* Network number. */
-       ether_addr_t    eth;            /* Ethernet address of this net. */
-       u8_t            type;           /* What kind of net is this? */
-       i8_t            sol_ct;         /* Router solicitation count. */
-       ether_addr_t    conflict;       /* Address conflict with this one. */
-       unsigned        flags;          /* Various flags. */
-       fd_t            *fdp;           /* Current open device. */
-       struct network  *wait;          /* Wait for a resource list. */
-       ipaddr_t        ip;             /* IP address of this net. */
-       ipaddr_t        mask;           /* Associated netmask. */
-       ipaddr_t        gateway;        /* My router. */
-       ipaddr_t        server;         /* My DHCP server. */
-       const char      *hostname;      /* Optional hostname to query for. */
-       time_t          start;          /* Query or lease start time. */
-       time_t          delta;          /* Query again after delta seconds. */
-       time_t          renew;          /* Next query or go into renewal. */
-       time_t          rebind;         /* When to go into rebind. */
-       time_t          lease;          /* When our lease expires. */
-       time_t          solicit;        /* Time to do a router solicitation. */
-} network_t;
-
-/* Flags. */
-#define NF_NEGOTIATING 0x001           /* Negotiating with a DHCP server. */
-#define NF_BOUND       0x002           /* Address configured through DHCP. */
-#define NF_SERVING     0x004           /* I'm a server on this network. */
-#define NF_RELAYING    0x008           /* I'm relaying for this network. */
-#define NF_WAIT                0x010           /* Wait for a resource to free up. */
-#define NF_IRDP                0x020           /* IRDP is used on this net. */
-#define NF_CONFLICT    0x040           /* There is an address conflict. */
-#define NF_POSSESSIVE  0x080           /* Keep address if lease expires. */
-#define NF_INFORM      0x100           /* It's ok to answer DHCPINFORM. */
-
-/* Functions defined in dhcpd.c. */
-void report(const char *label);
-void fatal(const char *label);
-void *allocate(size_t size);
-int ifname2if(const char *name);
-network_t *if2net(int n);
-
-/* Devices.c */
-void get_buf(buf_t **bp);
-void put_buf(buf_t **bp);
-void give_buf(buf_t **dbp, buf_t **sbp);
-network_t *newnetwork(void);
-void closefd(fd_t *fdp);
-int opendev(network_t *np, fdtype_t fdtype, int compete);
-void closedev(network_t *np, fdtype_t fdtype);
-char *ipdev(int n);
-void set_ipconf(char *device, ipaddr_t ip, ipaddr_t mask, unsigned mtu);
-
-/* Ether.c */
-void udp2ether(buf_t *bp, network_t *np);
-int ether2udp(buf_t *bp);
-void make_arp(buf_t *bp, network_t *np);
-int is_arp_me(buf_t *bp, network_t *np);
-void icmp_solicit(buf_t *bp);
-void icmp_advert(buf_t *bp, network_t *np);
-ipaddr_t icmp_is_advert(buf_t *bp);
-
-/* Tags.c */
-#define gettag(dp, st, pd, pl) dhcp_gettag((dp), (st), (pd), (pl))
-void settag(dhcp_t *dp, int tag, void *data, size_t len);
-char *cidr_ntoa(ipaddr_t addr, ipaddr_t mask);
-void ether2clid(u8_t *clid, ether_addr_t *eth);
-void initdhcpconf(void);
-int makedhcp(dhcp_t *dp, u8_t *class, size_t calen, u8_t *client, size_t cilen,
-                               ipaddr_t ip, ipaddr_t ifip, network_t *np);
-char *dhcptypename(int type);
-void printdhcp(dhcp_t *dp);
diff --git a/minix/commands/dhcpd/ether.c b/minix/commands/dhcpd/ether.c
deleted file mode 100644 (file)
index b9edadf..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-/*     ether.c - Raw Ethernet stuff
- *                                                     Author: Kees J. Bot
- *                                                             16 Dec 2000
- */
-#include <sys/types.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/asynchio.h>
-#include <net/hton.h>
-#include <net/gen/in.h>
-#include <net/gen/ether.h>
-#include <net/gen/eth_hdr.h>
-#include <net/gen/ip_hdr.h>
-#include <net/gen/icmp.h>
-#include <net/gen/icmp_hdr.h>
-#include <net/gen/oneCsum.h>
-#include <net/gen/udp.h>
-#include <net/gen/udp_hdr.h>
-#include <net/gen/dhcp.h>
-#include "arp.h"
-#include "dhcpd.h"
-
-static ether_addr_t BCAST_ETH =        {{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }};
-#define BCAST_IP       htonl(0xFFFFFFFFUL)
-#define LOCALHOST      htonl(0x7F000001UL)
-
-static u16_t udp_cksum(ipaddr_t src, ipaddr_t dst, udp_hdr_t *udp)
-{
-    /* Compute the checksum of an UDP packet plus data. */
-    struct udp_pseudo {
-       ipaddr_t        src, dst;
-       u8_t            zero, proto;
-       u16_t           length;
-    } pseudo;
-    size_t len;
-
-    /* Fill in the UDP pseudo header that must be prefixed to the UDP
-     * packet to compute the checksum of the whole thing.
-     */
-    pseudo.src= src;
-    pseudo.dst= dst;
-    pseudo.zero= 0;
-    pseudo.proto= IPPROTO_UDP;
-    pseudo.length= udp->uh_length;
-
-    len= ntohs(udp->uh_length);
-    if (len & 1) {
-       /* Length is odd?  Pad with a zero. */
-       B(udp)[len++]= 0;
-    }
-    return oneC_sum(oneC_sum(0, &pseudo, sizeof(pseudo)), udp, len);
-}
-
-void udp2ether(buf_t *bp, network_t *np)
-{
-    /* Transform a packet in UDP format to raw Ethernet.  Ignore the UDP
-     * addresses, always broadcast from 0.0.0.0.
-     */
-    udp_io_hdr_t udpio;
-
-    /* Save the UDP I/O header. */
-    udpio= *bp->udpio;
-
-    /* Fill in the Ethernet, IP and UDP headers. */
-    bp->eth->eh_dst= BCAST_ETH;
-    bp->eth->eh_src= np->eth;
-    bp->eth->eh_proto= htons(ETH_IP_PROTO);
-    bp->ip->ih_vers_ihl= 0x45;
-    bp->ip->ih_tos= 0;
-    bp->ip->ih_length= htons(sizeof(ip_hdr_t)
-                       + sizeof(udp_hdr_t) + udpio.uih_data_len);
-    bp->ip->ih_id= 0;
-    bp->ip->ih_flags_fragoff= ntohs(0x4000);
-    bp->ip->ih_ttl= IP_MAX_TTL;
-    bp->ip->ih_proto= IPPROTO_UDP;
-    bp->ip->ih_hdr_chk= 0;
-    bp->ip->ih_src= 0;
-    bp->ip->ih_dst= BCAST_IP;
-    bp->ip->ih_hdr_chk= ~oneC_sum(0, bp->ip, sizeof(*bp->ip));
-    bp->udp->uh_src_port= udpio.uih_src_port;
-    bp->udp->uh_dst_port= udpio.uih_dst_port;
-    bp->udp->uh_length= htons(sizeof(udp_hdr_t) + udpio.uih_data_len);
-    bp->udp->uh_chksum= 0;
-    bp->udp->uh_chksum= ~udp_cksum(bp->ip->ih_src, bp->ip->ih_dst, bp->udp);
-}
-
-int ether2udp(buf_t *bp)
-{
-    /* Transform an UDP packet read from raw Ethernet to normal UDP.
-     * Return true iff the packet is indeed UDP and has no errors.
-     */
-    udp_io_hdr_t udpio;
-
-    if (bp->eth->eh_proto != htons(ETH_IP_PROTO)
-       || bp->ip->ih_vers_ihl != 0x45
-       || bp->ip->ih_proto != IPPROTO_UDP
-       || oneC_sum(0, bp->ip, 20) != (u16_t) ~0
-       || udp_cksum(bp->ip->ih_src, bp->ip->ih_dst, bp->udp) != (u16_t) ~0
-    ) {
-       /* Not UDP/IP or checksums bad. */
-       return 0;
-    }
-    udpio.uih_src_addr= bp->ip->ih_src;
-    udpio.uih_dst_addr= bp->ip->ih_dst;
-    udpio.uih_src_port= bp->udp->uh_src_port;
-    udpio.uih_dst_port= bp->udp->uh_dst_port;
-    udpio.uih_ip_opt_len= 0;
-    udpio.uih_data_len= ntohs(bp->udp->uh_length) - sizeof(udp_hdr_t);
-    *bp->udpio= udpio;
-    return 1;
-}
-
-void make_arp(buf_t *bp, network_t *np)
-{
-    /* Create an ARP packet to query for my IP address. */
-    arp46_t *arp= (arp46_t *) bp->eth;
-
-    memset(arp, 0, sizeof(*arp));
-    arp->dstaddr= BCAST_ETH;
-    arp->srcaddr= np->eth;
-    arp->ethtype= htons(ETH_ARP_PROTO);
-    arp->hdr= htons(ARP_ETHERNET);
-    arp->pro= htons(ETH_IP_PROTO);
-    arp->op= htons(ARP_REQUEST);
-    arp->hln= 6;
-    arp->pln= 4;
-
-    arp->sha= np->eth;
-    memcpy(arp->spa, &np->ip, sizeof(np->ip));
-    memcpy(arp->tpa, &np->ip, sizeof(np->ip));
-}
-
-int is_arp_me(buf_t *bp, network_t *np)
-{
-    /* True iff an ARP packet is a reply from someone else with an address I
-     * thought was mine.  (That's like, bad.)
-     */
-    arp46_t *arp= (arp46_t *) bp->eth;
-
-    if (arp->ethtype == htons(ETH_ARP_PROTO)
-       && arp->hdr == htons(ARP_ETHERNET)
-       && arp->pro == htons(ETH_IP_PROTO)
-       && arp->op == htons(ARP_REPLY)
-       && memcmp(&arp->spa, &np->ip, sizeof(np->ip)) == 0
-       && memcmp(&arp->sha, &np->eth, sizeof(np->eth)) != 0
-    ) {
-       np->conflict= arp->sha;
-       return 1;
-    }
-    return 0;
-}
-
-void icmp_solicit(buf_t *bp)
-{
-    /* Fill in a router solicitation ICMP packet. */
-    icmp_hdr_t *icmp= (icmp_hdr_t *) (bp->ip + 1);
-
-    bp->ip->ih_vers_ihl= 0x45;
-    bp->ip->ih_dst= BCAST_IP;
-
-    icmp->ih_type= ICMP_TYPE_ROUTE_SOL;
-    icmp->ih_code= 0;
-    icmp->ih_hun.ihh_unused= 0;
-    icmp->ih_chksum= 0;
-    icmp->ih_chksum= ~oneC_sum(0, icmp, 8);
-}
-
-void icmp_advert(buf_t *bp, network_t *np)
-{
-    /* Fill in a router advert to be sent to my own interface. */
-    u32_t *data;
-    icmp_hdr_t *icmp= (icmp_hdr_t *) (bp->ip + 1);
-
-    bp->ip->ih_vers_ihl= 0x45;
-    bp->ip->ih_dst= LOCALHOST;
-
-    icmp->ih_type= ICMP_TYPE_ROUTER_ADVER;
-    icmp->ih_code= 0;
-    icmp->ih_hun.ihh_ram.iram_na= 1;
-    icmp->ih_hun.ihh_ram.iram_aes= 2;
-    icmp->ih_hun.ihh_ram.iram_lt= htons(DELTA_ADV);
-    data = (u32_t *) icmp->ih_dun.uhd_data;
-    data[0] = np->gateway;
-    data[1] = htonl((u32_t) -9999);
-    icmp->ih_chksum= 0;
-    icmp->ih_chksum= ~oneC_sum(0, icmp, 16);
-}
-
-ipaddr_t icmp_is_advert(buf_t *bp)
-{
-    /* Check if an IP packet is a router advertisement, and if it's genuine,
-     * i.e. the sender is mentioned in the packet.
-     */
-    icmp_hdr_t *icmp= (icmp_hdr_t *) (bp->ip + 1);
-    int i;
-
-    if (icmp->ih_type == ICMP_TYPE_ROUTER_ADVER) {
-       for (i= 0; i < icmp->ih_hun.ihh_ram.iram_na; i++) {
-           if (((u32_t *) icmp->ih_dun.uhd_data)[2*i] == bp->ip->ih_src) {
-               /* It's a router! */
-               return bp->ip->ih_src;
-           }
-       }
-    }
-    return 0;
-}
diff --git a/minix/commands/dhcpd/tags.c b/minix/commands/dhcpd/tags.c
deleted file mode 100644 (file)
index 6ab015c..0000000
+++ /dev/null
@@ -1,926 +0,0 @@
-/*     tags.c - Obtain DHCP tags from the config file
- *                                                     Author: Kees J. Bot
- *                                                             16 Dec 2000
- */
-#include <sys/types.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <signal.h>
-#include <string.h>
-#include <time.h>
-#include <limits.h>
-#include <configfile.h>
-#include <sys/ioctl.h>
-#include <sys/asynchio.h>
-#include <net/hton.h>
-#include <net/gen/socket.h>
-#include <netdb.h>
-#include <net/gen/in.h>
-#include <net/gen/inet.h>
-#include <net/gen/ether.h>
-#include <net/gen/if_ether.h>
-#include <net/gen/eth_hdr.h>
-#include <net/gen/ip_hdr.h>
-#include <net/gen/udp.h>
-#include <net/gen/udp_hdr.h>
-#include <net/gen/dhcp.h>
-#include <arpa/inet.h>
-#include "dhcpd.h"
-
-#define doff(field)            offsetof(dhcp_t, field)
-
-void settag(dhcp_t *dp, int tag, void *data, size_t len)
-{
-    if (!dhcp_settag(dp, tag, data, len)) {
-       /* Oops, it didn't fit?  Is this really Minix??? */
-       fprintf(stderr,
-           "%s: DHCP packet too big, please trim the configuration\n",
-           program);
-       exit(1);
-    }
-}
-
-static int name2ip(ipaddr_t *pip, const char *name, ipaddr_t ifip)
-{
-    /* Translate a name to an IP address, preferably from the hosts file,
-     * but also from the DNS if being a server.  Prefer the address closest
-     * to the interface with IP address 'ifip' if there are choices..
-     */
-    extern struct hostent *_gethostent(void);  /* File reading versions. */
-    extern void _endhostent(void);
-    struct hostent *he;
-    size_t len= strlen(name);
-    u32_t d, distance= -1;
-    ipaddr_t ip;
-    int i;
-    char *hn;
-
-    /* Already an IP address? */
-    if (inet_aton(name, (struct in_addr *)pip)) return 1;
-
-    /* In the hosts file? */
-    while ((he= _gethostent()) != nil) {
-       hn= he->h_name;
-       i= -1;
-       do {
-           if (strncasecmp(name, hn, len) == 0
-               && (hn[len] == 0 || hn[len] == '.')
-           ) {
-               memcpy(&ip, he->h_addr, sizeof(ip));
-               d= ntohl(ip) ^ ntohl(ifip);
-               if (d < distance) {
-                   *pip= ip;
-                   distance= d;
-               }
-               break;
-           }
-       } while ((hn= he->h_aliases[++i]) != nil);
-    }
-    _endhostent();
-    if (distance < -1) return 1;
-
-    /* Nothing?  Try the real DNS if being a server. */
-    if (serving) {
-       if ((he= gethostbyname(name)) != nil && he->h_addrtype == AF_INET) {
-           /* Select the address closest to 'ifip'. */
-           for (i= 0; he->h_addr_list[i] != nil; i++) {
-               memcpy(&ip, he->h_addr_list[i], sizeof(ip));
-               d= ntohl(ip) ^ ntohl(ifip);
-               if (d < distance) {
-                   *pip= ip;
-                   distance= d;
-               }
-           }
-           return 1;
-       }
-    }
-    return 0;
-}
-
-static char *ip2name(ipaddr_t ip)
-{
-    /* Translate an IP address to a name, etc, etc. */
-    extern struct hostent *_gethostent(void);  /* File reading versions. */
-    extern void _endhostent(void);
-    struct hostent *he;
-
-    /* In the hosts file? */
-    while ((he= _gethostent()) != nil) {
-       if (memcmp(he->h_addr, &ip, sizeof(ip)) == 0) break;
-    }
-    _endhostent();
-
-    /* Nothing?  Try the real DNS if being a server. */
-    if (he == nil && serving) {
-       he= gethostbyaddr((char *) &ip, sizeof(ip), AF_INET);
-    }
-    return he != nil ? he->h_name : nil;
-}
-
-static int cidr_aton(const char *cidr, ipaddr_t *addr, ipaddr_t *mask)
-{
-    char *slash, *check;
-    ipaddr_t a;
-    int ok;
-    unsigned long len;
-
-    if ((slash= strchr(cidr, '/')) == nil) return 0;
-
-    *slash++= 0;
-    ok= inet_aton(cidr, (struct in_addr *)&a);
-
-    len= strtoul(slash, &check, 10);
-    if (check == slash || *check != 0 || len > 32) ok= 0;
-
-    *--slash= '/';
-    if (!ok) return 0;
-    *addr= a;
-    *mask= htonl(len == 0 ? 0 : (0xFFFFFFFFUL << (32-len)) & 0xFFFFFFFFUL);
-    return 1;
-}
-
-char *cidr_ntoa(ipaddr_t addr, ipaddr_t mask)
-{
-    ipaddr_t testmask= 0xFFFFFFFFUL;
-    int n;
-    static char result[sizeof("255.255.255.255/255.255.255.255")];
-
-    for (n= 32; n >= 0; n--) {
-       if (mask == htonl(testmask)) break;
-       testmask= (testmask << 1) & 0xFFFFFFFFUL;
-    }
-
-    sprintf(result, "%s/%-2d", inet_ntoa(*(struct in_addr *)&addr), n);
-    if (n == -1) strcpy(strchr(result, '/')+1,
-       inet_ntoa(*(struct in_addr *)&mask));
-    return result;
-}
-
-static size_t ascii2octet(u8_t *b, size_t size, const char *a)
-{
-    /* Convert a series of hex digit pairs to an octet (binary) array at
-     * 'b' with length 'size'.  Return the number of octets in 'a' or
-     * -1 on error.
-     */
-    size_t len;
-    int n, c;
-
-    len= 0;
-    n= 0;
-    while ((c= *a++) != 0) {
-       if (between('0', c, '9')) c= (c - '0') + 0x0;
-       else
-       if (between('a', c, 'f')) c= (c - 'a') + 0xa;
-       else
-       if (between('A', c, 'F')) c= (c - 'A') + 0xA;
-       else {
-           return -1;
-       }
-
-       if (n == 0) {
-           if (len < size) b[len] = c << 4;
-       } else {
-           if (len < size) b[len] |= c;
-           len++;
-       }
-       n ^= 1;
-    }
-    return n == 0 ? len : -1;
-}
-
-void ether2clid(u8_t *clid, ether_addr_t *eth)
-{
-    /* Convert an Ethernet address to the default client ID form. */
-    clid[0]= DHCP_HTYPE_ETH;
-    memcpy(clid+1, eth, DHCP_HLEN_ETH);
-}
-
-static size_t ascii2clid(u8_t *clid, const char *a)
-{
-    /* Convert an ethernet address, or a series of hex digits to a client ID.
-     * Return its length if ok, otherwise -1.
-     */
-    size_t len;
-    ether_addr_t *eth;
-
-    if ((eth= ether_aton(a)) != nil) {
-       ether2clid(clid, eth);
-       len= 1+DHCP_HLEN_ETH;
-    } else {
-       len= ascii2octet(clid, CLID_MAX, a);
-    }
-    return len;
-}
-
-static config_t *dhcpconf;             /* In-core DHCP configuration. */
-
-/* DHCP tag types. */
-typedef enum { TT_ASCII, TT_BOOLEAN, TT_IP, TT_NUMBER, TT_OCTET } tagtype_t;
-
-/* DHCP/BOOTP tag definitions. */
-typedef struct tagdef {
-       u8_t            tag;            /* Tag number. */
-       u8_t            type;           /* Type and flags. */
-       u8_t            gran;           /* Granularity. */
-       u8_t            max;            /* Maximum number of arguments. */
-       const char      *name;          /* Defined name. */
-} tagdef_t;
-
-#define TF_TYPE                0x07            /* To mask out the type. */
-#define TF_STATIC      0x08            /* "Static", i.e. a struct field. */
-#define TF_RO          0x10            /* Read-only, user can't set. */
-
-/* List of static DHCP fields.  The tag field is misused here as an offset
- * into the DHCP structure.
- */
-static tagdef_t statictag[] = {
-    { doff(op),     TT_NUMBER|TF_STATIC|TF_RO, 1,   1, "op"            },
-    { doff(htype),  TT_NUMBER|TF_STATIC|TF_RO, 1,   1, "htype"         },
-    { doff(hlen),   TT_NUMBER|TF_STATIC|TF_RO, 1,   1, "hlen"          },
-    { doff(hops),   TT_NUMBER|TF_STATIC|TF_RO, 1,   1, "hops"          },
-    { doff(xid),    TT_NUMBER|TF_STATIC|TF_RO, 4,   1, "xid"           },
-    { doff(secs),   TT_NUMBER|TF_STATIC|TF_RO, 2,   1, "secs"          },
-    { doff(flags),  TT_NUMBER|TF_STATIC|TF_RO, 2,   1, "flags"         },
-    { doff(ciaddr), TT_IP|TF_STATIC|TF_RO,     1,   1, "ciaddr"        },
-    { doff(yiaddr), TT_IP|TF_STATIC|TF_RO,     1,   1, "yiaddr"        },
-    { doff(siaddr), TT_IP|TF_STATIC,           1,   1, "siaddr"        },
-    { doff(giaddr), TT_IP|TF_STATIC|TF_RO,     1,   1, "giaddr"        },
-    { doff(chaddr), TT_OCTET|TF_STATIC|TF_RO,  1,  16, "chaddr"        },
-    { doff(sname),  TT_ASCII|TF_STATIC,                1,  64, "sname"         },
-    { doff(file),   TT_ASCII|TF_STATIC,                1, 128, "file"          },
-};
-#define N_STATIC       arraysize(statictag)
-
-static tagdef_t alltagdef[N_STATIC + 254];     /* List of tag definitions. */
-#define tagdef (alltagdef+N_STATIC-1)          /* Just the optional ones. */
-
-#define tagdefined(tp)         ((tp)->name != nil)
-
-static void inittagdef(void)
-{
-    /* Initialize the tag definitions from the "tag" commands in the config
-     * file.
-     */
-    int t;
-    tagdef_t *tp;
-    static tagdef_t predef[] = {
-       { DHCP_TAG_NETMASK,     TT_IP,     1,     1,    "netmask"       },
-       { DHCP_TAG_GATEWAY,     TT_IP,     1,   255,    "gateway"       },
-       { DHCP_TAG_DNS,         TT_IP,     1,   255,    "DNSserver"     },
-    };
-    static char *typenames[] = { "ascii", "boolean", "ip", "number", "octet" };
-    config_t *cfg;
-    static u8_t rotags[] = {
-       DHCP_TAG_REQIP, DHCP_TAG_OVERLOAD, DHCP_TAG_TYPE, DHCP_TAG_SERVERID,
-       DHCP_TAG_REQPAR, DHCP_TAG_MESSAGE, DHCP_TAG_MAXDHCP
-    };
-
-    for (t= 1; t <= 254; t++) {
-       tp= &tagdef[t];
-       tp->tag= t;
-       tp->type= TT_OCTET;
-       tp->name= nil;
-    }
-
-    /* Set the static and "all Minix needs" tags. */
-    memcpy(alltagdef, statictag, sizeof(statictag));
-    for (tp= predef; tp < arraylimit(predef); tp++) tagdef[tp->tag] = *tp;
-
-    /* Search for tag definitions in the config file. */
-    for (cfg= dhcpconf; cfg != nil; cfg= cfg->next) {
-       config_t *cmd= cfg->list;
-
-       if (strcasecmp(cmd->word, "tag") == 0) {
-           if (config_length(cmd) == 6
-               && (cmd->next->flags & CFG_DULONG)
-               && config_isatom(cmd->next->next)
-               && config_isatom(cmd->next->next->next)
-               && (cmd->next->next->next->next->flags & CFG_DULONG)
-               && (cmd->next->next->next->next->next->flags & CFG_DULONG)
-           ) {
-               unsigned long tag, gran, max;
-               const char *name, *typename;
-               unsigned type;
-
-               tag= strtoul(cmd->next->word, nil, 10);
-               name= cmd->next->next->word;
-               typename= cmd->next->next->next->word;
-               gran= strtoul(cmd->next->next->next->next->word, nil, 10);
-               max= strtoul(cmd->next->next->next->next->next->word, nil, 10);
-
-               for (type= 0; type < arraysize(typenames); type++) {
-                   if (strcasecmp(typename, typenames[type]) == 0) break;
-               }
-
-               if (!(1 <= tag && tag <= 254)
-                   || !(type < arraysize(typenames))
-                   || !((type == TT_NUMBER
-                           && (gran == 1 || gran == 2 || gran == 4))
-                       || (type != TT_NUMBER && 1 <= gran && gran <= 16))
-                   || !(max <= 255)
-               ) {
-                   fprintf(stderr,
-                       "\"%s\", line %u: Tag definition is incorrect\n",
-                       cmd->file, cmd->line);
-                   exit(1);
-               }
-
-               tp= &tagdef[(int)tag];
-               tp->type= type;
-               tp->name= name;
-               tp->gran= gran;
-               tp->max= max;
-           } else {
-               fprintf(stderr,
-           "\"%s\", line %u: Usage: tag number name type granularity max\n",
-                   cmd->file, cmd->line);
-               exit(1);
-           }
-       }
-    }
-
-    /* Many DHCP tags are not for the user to play with. */
-    for (t= 0; t < arraysize(rotags); t++) tagdef[rotags[t]].type |= TF_RO;
-}
-
-static tagdef_t *tagdefbyname(const char *name)
-{
-    /* Find a tag definition by the name of the tag.  Return null if not
-     * defined.
-     */
-    tagdef_t *tp;
-
-    for (tp= alltagdef; tp < arraylimit(alltagdef); tp++) {
-       if (tagdefined(tp) && strcasecmp(tp->name, name) == 0) return tp;
-    }
-    return nil;
-}
-
-void initdhcpconf(void)
-{
-    /* Read/refresh configuration from the DHCP configuration file. */
-    dhcpconf= config_read(configfile, 0, dhcpconf);
-    if (config_renewed(dhcpconf)) inittagdef();
-}
-
-static void configtag(dhcp_t *dp, config_t *cmd, ipaddr_t ifip)
-{
-    /* Add a tag to a DHCP packet from the config file. */
-    tagdef_t *tp;
-    u8_t data[260], *d;
-    size_t i;
-    int delete= 0;
-
-    if (strcasecmp(cmd->word, "no") == 0) {
-       if (config_length(cmd) != 2 || !config_isatom(cmd->next)) {
-           fprintf(stderr, "\"%s\", line %u: Usage: no tag-name\n",
-               cmd->file, cmd->line);
-           exit(1);
-       }
-       cmd= cmd->next;
-       delete= 1;
-    }
-
-    if ((tp= tagdefbyname(cmd->word)) == nil) {
-       fprintf(stderr, "\"%s\", line %u: Unknown tag '%s'\n",
-           cmd->file, cmd->line, cmd->word);
-       exit(1);
-    }
-
-    if (tp->type & TF_RO) {
-       fprintf(stderr, "\"%s\", line %u: Tag '%s' can't be configured\n",
-           cmd->file, cmd->line, cmd->word);
-       exit(1);
-    }
-
-    i= 0;
-    d= data;
-    if (!delete) {
-       config_t *arg= cmd->next;
-       do {
-           switch (tp->type & TF_TYPE) {
-           case TT_ASCII: {
-               if (arg == nil || !config_isatom(arg) || arg->next != nil) {
-                   fprintf(stderr, "\"%s\", line %u: Usage: %s string\n",
-                       cmd->file, cmd->line, cmd->word);
-                   exit(1);
-               }
-               strncpy((char *) data, arg->word, sizeof(data));
-               d += i = strnlen((char *) data, sizeof(data));
-               break;}
-           case TT_BOOLEAN: {
-               if (arg == nil || !config_isatom(arg)
-                   || !(strcasecmp(arg->word, "false") == 0
-                           || strcasecmp(arg->word, "true") == 0)
-               ) {
-                   fprintf(stderr,
-                       "\"%s\", line %u: Usage: %s false|true ...\n",
-                       cmd->file, cmd->line, cmd->word);
-                   exit(1);
-               }
-               if (d < arraylimit(data)) {
-                   *d++ = (arg->word[0] != 'f' && arg->word[0] != 'F');
-               }
-               i++;
-               break;}
-           case TT_IP: {
-               ipaddr_t ip;
-               unsigned long len;
-               char *end;
-
-               if (arg == nil || !config_isatom(arg)) {
-                   fprintf(stderr, "\"%s\", line %u: Usage: %s host ...\n",
-                       cmd->file, cmd->line, cmd->word);
-                   exit(1);
-               }
-               if (arg->word[0] == '/'
-                       && between(1, len= strtoul(arg->word+1, &end, 10), 31)
-                       && *end == 0
-               ) {
-                   ip= htonl((0xFFFFFFFFUL << (32-len)) & 0xFFFFFFFFUL);
-               } else
-               if (!name2ip(&ip, arg->word, ifip)) {
-                   fprintf(stderr,
-                   "\"%s\", line %u: Can't translate %s to an IP address\n",
-                       arg->file, arg->line, arg->word);
-                   exit(1);
-               }
-               if (d <= arraylimit(data) - sizeof(ip)) {
-                   memcpy(d, &ip, sizeof(ip));
-                   d += sizeof(ip);
-               }
-               i++;
-               break;}
-           case TT_NUMBER: {
-               unsigned long n;
-               int g;
-
-               if (arg == nil || !(arg->flags & CFG_CLONG)) {
-                   fprintf(stderr, "\"%s\", line %u: Usage: %s number ...\n",
-                       cmd->file, cmd->line, cmd->word);
-                   exit(1);
-               }
-               n= strtoul(arg->word, nil, 0);
-               g= tp->gran;
-               do {
-                   if (d <= arraylimit(data)) *d++ = (n >> (--g * 8)) & 0xFF;
-               } while (g != 0);
-               i++;
-               break;}
-           case TT_OCTET: {
-               if (arg == nil || !config_isatom(arg) || arg->next != nil) {
-                   fprintf(stderr, "\"%s\", line %u: Usage: %s hexdigits\n",
-                       cmd->file, cmd->line, cmd->word);
-                   exit(1);
-               }
-               i= ascii2octet(data, sizeof(data), arg->word);
-               if (i == -1) {
-                   fprintf(stderr,
-                       "\"%s\", line %u: %s: Bad hexdigit string\n",
-                       arg->file, arg->line, arg->word);
-                   exit(1);
-               }
-               d= data + i;
-               break;}
-           }
-       } while ((arg= arg->next) != nil);
-
-       if (d > data + 255) {
-           fprintf(stderr, "\"%s\", line %u: Tag value is way too big\n",
-               cmd->file, cmd->line);
-           exit(1);
-       }
-       if ((tp->type & TF_TYPE) != TT_NUMBER && (i % tp->gran) != 0) {
-           fprintf(stderr,
-               "\"%s\", line %u: Expected a multiple of %d initializers\n",
-               cmd->file, cmd->line, tp->gran);
-           exit(1);
-       }
-       if (tp->max != 0 && i > tp->max) {
-           fprintf(stderr,
-               "\"%s\", line %u: Got %d initializers, can have only %d\n",
-               cmd->file, cmd->line, (int) i, tp->max);
-           exit(1);
-       }
-    }
-    if (tp->type & TF_STATIC) {
-       size_t len= tp->gran * tp->max;
-       if ((tp->type & TF_TYPE) == TT_IP) len *= sizeof(ipaddr_t);
-       memset(B(dp) + tp->tag, 0, len);
-       memcpy(B(dp) + tp->tag, data, (d - data));
-    } else {
-       settag(dp, tp->tag, data, (d - data));
-    }
-}
-
-int makedhcp(dhcp_t *dp, u8_t *class, size_t calen, u8_t *client, size_t cilen,
-                               ipaddr_t ip, ipaddr_t ifip, network_t *np)
-{
-    /* Fill in a DHCP packet at 'dp' for the host identified by the
-     * (class, client, ip) combination.  Makedhcp is normally called twice,
-     * once to find the IP address (so ip == 0) and once again to find all
-     * data that goes with that IP address (ip != 0).  On the first call the
-     * return value of this function should be ignored and only 'yiaddr'
-     * checked and used as 'ip' on the next pass.  True is returned iff there
-     * is information for the client on the network at interface address
-     * 'ifip', by checking if the 'ip' and 'ifip' are on the same network.
-     * If np is nonnull then we are working for one of our own interfaces, so
-     * options can be set and adjourning interfaces can be programmed.
-     */
-    config_t *todo[16];
-    size_t ntodo= 0;
-    ipaddr_t hip, mask;
-    u8_t *pmask;
-    char *hostname;
-    u32_t distance= -1;
-
-    initdhcpconf();
-
-    /* Start creating a packet. */
-    dhcp_init(dp);
-    dp->op= DHCP_BOOTREPLY;
-
-    /* The initial TODO list is the whole DHCP config. */
-    todo[ntodo++]= dhcpconf;
-
-    while (ntodo > 0) {
-       config_t *cmd, *follow;
-
-       if (todo[ntodo-1] == nil) { ntodo--; continue; }
-       cmd= todo[ntodo-1]->list;
-       todo[ntodo-1]= todo[ntodo-1]->next;
-
-       follow= nil;    /* Macro or list to follow next? */
-
-       if (strcasecmp(cmd->word, "client") == 0) {
-           u8_t cfgid[CLID_MAX];
-           size_t cfglen;
-           char *name;
-           int ifno;
-           u32_t d;
-
-           if (between(3, config_length(cmd), 5)
-               && config_isatom(cmd->next)
-               && (cfglen= ascii2clid(cfgid, cmd->next->word)) != -1
-               && config_isatom(cmd->next->next)
-               && (((ifno= ifname2if(cmd->next->next->word)) == -1
-                       && config_length(cmd) <= 4)
-                   || ((ifno= ifname2if(cmd->next->next->word)) != -1
-                       && config_length(cmd) >= 4
-                       && config_isatom(cmd->next->next->next)))
-           ) {
-               if (cilen == cfglen && memcmp(client, cfgid, cilen) == 0
-                   && (ifno == -1 || np == nil || ifno == np->n)
-               ) {
-                   config_t *atname= cmd->next->next;
-                   if (ifno != -1) atname= atname->next;
-                   name= (char *)atname->word;
-
-                   if (name2ip(&hip, name, ifip) && (ip == 0 || ip == hip)) {
-                       d= ntohl(hip) ^ ntohl(ifip);
-                       if (d < distance) {
-                           dp->yiaddr= hip;
-                           follow= atname->next;
-                           distance= d;
-                       }
-                   }
-               }
-           } else {
-               fprintf(stderr,
-           "\"%s\", line %u: Usage: client ID [ip#] host [macro|{params}]\n",
-                   cmd->file, cmd->line);
-               exit(1);
-           }
-       } else
-       if (strcasecmp(cmd->word, "class") == 0) {
-           config_t *clist;
-           int match;
-
-           match= 0;
-           for (clist= cmd->next; clist != nil
-                               && clist->next != nil
-                               && config_isatom(clist); clist= clist->next) {
-               if (calen > 0
-                   && strncmp(clist->word, (char *) class, calen) == 0
-               ) {
-                   match= 1;
-               }
-           }
-           if (clist == cmd->next || clist->next != nil) {
-               fprintf(stderr,
-               "\"%s\", line %u: Usage: class class-name ... macro|{params}\n",
-                   cmd->file, cmd->line);
-           }
-           if (match) follow= clist;
-       } else
-       if (strcasecmp(cmd->word, "host") == 0) {
-           if (config_length(cmd) == 3
-               && config_isatom(cmd->next)
-           ) {
-               if (ip != 0) {
-                   if (cidr_aton(cmd->next->word, &hip, &mask)) {
-                       if (((hip ^ ip) & mask) == 0) {
-                           if (!gettag(dp, DHCP_TAG_NETMASK, nil, nil)) {
-                               settag(dp, DHCP_TAG_NETMASK,
-                                               &mask, sizeof(mask));
-                           }
-                           dp->yiaddr= ip;
-                           follow= cmd->next->next;
-                       }
-                   } else
-                   if (name2ip(&hip, cmd->next->word, ifip)) {
-                       if (hip == ip) {
-                           dp->yiaddr= ip;
-                           follow= cmd->next->next;
-                       }
-                   }
-               }
-           } else {
-               fprintf(stderr,
-               "\"%s\", line %u: Usage: host host-spec macro|{params}\n",
-                   cmd->file, cmd->line);
-               exit(1);
-           }
-       } else
-       if (strcasecmp(cmd->word, "interface") == 0) {
-           if (between(3, config_length(cmd), 4)
-               && config_isatom(cmd->next)
-               && config_isatom(cmd->next->next)
-           ) {
-               network_t *ifnp;
-
-               if (np != nil) {
-                   if ((ifnp= if2net(ifname2if(cmd->next->word))) == nil) {
-                       fprintf(stderr,
-                           "\"%s\", line %u: Can't find interface %s\n",
-                           cmd->next->file, cmd->next->line, cmd->next->word);
-                       exit(1);
-                   }
-                   if (!name2ip(&hip, cmd->next->next->word, 0)) {
-                       fprintf(stderr,
-                           "\"%s\", line %u: Can't find IP address of %s\n",
-                           cmd->next->next->file, cmd->next->next->line,
-                           cmd->next->next->word);
-                       exit(1);
-                   }
-                   ifnp->ip= hip;
-                   if (ifnp == np) {
-                       dp->yiaddr= hip;
-                       follow= cmd->next->next->next;
-                   }
-               }
-           } else {
-               fprintf(stderr,
-               "\"%s\", line %u: Usage: interface ip# host%s\n",
-                   cmd->file, cmd->line, ntodo==1 ? " [macro|{params}]" : "");
-               exit(1);
-           }
-       } else
-       if (strcasecmp(cmd->word, "macro") == 0) {
-           if (config_length(cmd) == 2 && config_isatom(cmd->next)) {
-               follow= cmd->next;
-           } else
-           if (ntodo > 1) {
-               fprintf(stderr, "\"%s\", line %u: Usage: macro macro-name\n",
-                   cmd->file, cmd->line);
-               exit(1);
-           }
-       } else
-       if (strcasecmp(cmd->word, "tag") == 0) {
-           if (ntodo > 1) {
-               fprintf(stderr,
-                   "\"%s\", line %u: A %s can't be defined here\n",
-                   cmd->file, cmd->line, cmd->word);
-               exit(1);
-           }
-       } else
-       if (strcasecmp(cmd->word, "option") == 0) {
-           int ifno;
-           network_t *ifnp;
-           config_t *opt;
-
-           if ((opt= cmd->next) != nil
-               && config_isatom(opt)
-               && (ifno= ifname2if(opt->word)) != -1
-           ) {
-               if ((ifnp= if2net(ifno)) == nil) {
-                   fprintf(stderr,
-                       "\"%s\", line %u: Interface %s is not enabled\n",
-                       opt->file, opt->line, opt->word);
-                   exit(1);
-               }
-               opt= opt->next;
-           } else {
-               ifnp= np;
-           }
-
-           if (between(1, config_length(opt), 2)
-               && config_isatom(opt)
-               && strcasecmp(opt->word, "server") == 0
-               && (opt->next == nil
-                   || strcasecmp(opt->next->word, "inform") == 0)
-           ) {
-               if (np != nil) {
-                   ifnp->flags |= NF_SERVING;
-                   if (opt->next != nil) ifnp->flags |= NF_INFORM;
-               }
-           } else
-           if (config_length(opt) == 2
-               && config_isatom(opt)
-               && strcasecmp(opt->word, "relay") == 0
-               && config_isatom(opt->next)
-           ) {
-               if (np != nil) {
-                   if (!name2ip(&hip, opt->next->word, ifip)) {
-                       fprintf(stderr,
-                           "\"%s\", line %u: Can't find IP address of %s\n",
-                           opt->next->file, opt->next->line,
-                           opt->next->word);
-                       exit(1);
-                   }
-                   ifnp->flags |= NF_RELAYING;
-                   ifnp->server= hip;
-               }
-           } else
-           if (config_length(opt) == 1
-               && config_isatom(opt)
-               && strcasecmp(opt->word, "possessive") == 0
-           ) {
-               if (np != nil) ifnp->flags |= NF_POSSESSIVE;
-           } else
-           if (config_length(opt) == 2
-               && config_isatom(opt)
-               && strcasecmp(opt->word, "hostname") == 0
-               && config_isatom(opt->next)
-           ) {
-               if (np != nil) np->hostname= opt->next->word;
-           } else {
-               fprintf(stderr, "\"%s\", line %u: Unknown option\n",
-                   cmd->file, cmd->line);
-               exit(1);
-           }
-       } else {
-           /* Must be an actual data carrying tag. */
-           configtag(dp, cmd, ifip);
-       }
-
-       if (follow != nil) {
-           /* A client/class/host entry selects a macro or list that must
-            * be followed next.
-            */
-           config_t *macro;
-
-           if (config_isatom(follow)) {        /* Macro name */
-               config_t *cfg;
-
-               for (cfg= dhcpconf; cfg != nil; cfg= cfg->next) {
-                   macro= cfg->list;
-
-                   if (strcasecmp(macro->word, "macro") == 0) {
-                       if (config_length(macro) == 3
-                           && config_isatom(macro->next)
-                           && config_issub(macro->next->next)
-                       ) {
-                           if (strcasecmp(macro->next->word, follow->word) == 0
-                           ) {
-                               break;
-                           }
-                       } else {
-                           fprintf(stderr,
-                       "\"%s\", line %u: Usage: macro macro-name {params}\n",
-                               macro->file, macro->line);
-                       }
-                   }
-               }
-               follow= cfg == nil ? nil : macro->next->next->list;
-           } else {
-               /* Simply a list of more tags and stuff. */
-               follow= follow->list;
-           }
-
-           if (ntodo == arraysize(todo)) {
-               fprintf(stderr, "\"%s\", line %u: Nesting is too deep\n",
-                   follow->file, follow->line);
-               exit(1);
-           }
-           todo[ntodo++]= follow;
-       }
-    }
-
-    /* Check if the IP and netmask are OK for the interface. */
-    if (!gettag(dp, DHCP_TAG_NETMASK, &pmask, nil)) return 0;
-    memcpy(&mask, pmask, sizeof(mask));
-    if (((ip ^ ifip) & mask) != 0) return 0;
-
-    /* Fill in the hostname and/or domain. */
-    if ((hostname= ip2name(ip)) != nil) {
-       char *domain;
-
-       if ((domain= strchr(hostname, '.')) != nil) *domain++ = 0;
-
-       if (!gettag(dp, DHCP_TAG_HOSTNAME, nil, nil)) {
-           settag(dp, DHCP_TAG_HOSTNAME, hostname, strlen(hostname));
-       }
-
-       if (domain != nil && !gettag(dp, DHCP_TAG_DOMAIN, nil, nil)) {
-           settag(dp, DHCP_TAG_DOMAIN, domain, strlen(domain));
-       }
-    }
-
-    return 1;
-}
-
-static char *dhcpopname(int op)
-{
-    static char *onames[] = { "??\?", "REQUEST", "REPLY" };
-    return onames[op < arraysize(onames) ? op : 0];
-}
-
-char *dhcptypename(int type)
-{
-    static char *tnames[] = {
-       "??\?", "DISCOVER", "OFFER", "REQUEST", "DECLINE",
-       "ACK", "NAK", "RELEASE", "INFORM"
-    };
-    return tnames[type < arraysize(tnames) ? type : 0];
-}
-
-void printdhcp(dhcp_t *dp)
-{
-    /* Print the contents of a DHCP packet, usually for debug purposes. */
-    tagdef_t *tp;
-    u8_t *data, *ovld;
-    size_t i, len;
-
-    for (tp= alltagdef; tp < arraylimit(alltagdef); tp++) {
-       if (tp->type & TF_STATIC) {
-           data= B(dp) + tp->tag;
-           len= tp->gran * tp->max;
-           if ((tp->type & TF_TYPE) == TT_IP) len *= sizeof(ipaddr_t);
-           if (tp->tag == doff(chaddr)) len= dp->hlen;
-
-           /* Don't show uninteresting stuff. */
-           if (tp->tag == doff(htype) && dp->htype == DHCP_HTYPE_ETH) continue;
-
-           if (tp->tag == doff(hlen) && dp->hlen == DHCP_HLEN_ETH) continue;
-
-           if ((tp->tag == doff(file) || tp->tag == doff(sname))
-               && gettag(dp, DHCP_TAG_OVERLOAD, &ovld, nil)
-               && (ovld[0] & (tp->tag == doff(file) ? 1 : 2))
-           ) {
-               continue;
-           }
-           for (i= 0; i < len && data[i] == 0; i++) {}
-           if (i == len) continue;
-       } else {
-           if (!gettag(dp, tp->tag, &data, &len)) continue;
-       }
-
-       if (tagdefined(tp)) {
-           printf("\t%s =", tp->name);
-       } else {
-           printf("\tT%d =", tp->tag);
-       }
-
-       i= 0;
-       while (i < len) {
-           switch (tp->type & TF_TYPE) {
-           case TT_ASCII: {
-               printf(" \"%.*s\"", (int) len, data);
-               i= len;
-               break;}
-           case TT_BOOLEAN: {
-               printf(data[i++] == 0 ? " false" : " true");
-               break;}
-           case TT_IP: {
-               ipaddr_t ip;
-               memcpy(&ip, data+i, sizeof(ip));
-               printf(" %s", inet_ntoa(*(struct in_addr *)&ip));
-               i += sizeof(ip);
-               break;}
-           case TT_NUMBER: {
-               u32_t n= 0;
-               int g= tp->gran;
-
-               do n= (n << 8) | data[i++]; while (--g != 0);
-               printf(" %lu", (unsigned long) n);
-               if ((tp->type & TF_STATIC) && tp->tag == doff(op)) {
-                   printf(" (%s)", dhcpopname(n));
-               }
-               if (!(tp->type & TF_STATIC) && tp->tag == DHCP_TAG_TYPE) {
-                   printf(" (%s)", dhcptypename(n));
-               }
-               break;}
-           case TT_OCTET: {
-               if (i == 0) fputc(' ', stdout);
-               printf("%02X", data[i++]);
-               break;}
-           }
-       }
-       fputc('\n', stdout);
-    }
-}
index 8e0de45428d50e0470b0450aabf5ba2442aa588a..87f4fc064b252f59a55cf07b1635681a7d7e300e 100644 (file)
@@ -8,11 +8,6 @@
 #define _PATH_SYSTEM_CONF_DIR "/etc/system.conf.d"
 #define _PATH_SYSTEM_CONF_PKG_DIR       "/usr/pkg/etc/system.conf.d"
 
-#define _PATH_DHCPCONF "/etc/dhcp.conf"
-#define _PATH_DHCPPID  "/usr/run/dhcpd.pid"
-#define _PATH_DHCPCACHE        "/usr/adm/dhcp.cache"
-#define _PATH_DHCPPOOL "/usr/adm/dhcp.pool"
-
 #define _PATH_RAMDISK  "/dev/ram"
 
 #define _PATH_DRIVERS  "/service"
diff --git a/minix/lib/libc/gen/dhcp_gettag.c b/minix/lib/libc/gen/dhcp_gettag.c
deleted file mode 100644 (file)
index 3dcb6e8..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*     dhcp_gettag()                                   Author: Kees J. Bot
- *                                                             1 Dec 2000
- */
-#define nil ((void*)0)
-#include <stddef.h>
-#include <string.h>
-#include <sys/types.h>
-#include <net/hton.h>
-#include <net/gen/in.h>
-#include <net/gen/dhcp.h>
-
-#define arraysize(a)   (sizeof(a) / sizeof((a)[0]))
-
-int dhcp_gettag(dhcp_t *dp, int searchtag, u8_t **pdata, size_t *plen)
-{
-    /* Find a tag in the options field, or possibly in the file or sname
-     * fields.  Return true iff found, and return the data and/or length if
-     * their pointers are non-null.
-     */
-    u8_t *p;
-    u8_t *optfield[3];
-    size_t optlen[3];
-    int i, tag, len;
-
-    /* The DHCP magic number must be correct, or no tags. */
-    if (dp->magic != DHCP_MAGIC) return 0;
-
-    optfield[0]= dp->options;
-    optlen[0]= arraysize(dp->options);
-    optfield[1]= dp->file;
-    optlen[1]= 0;              /* Unknown if used for options yet. */
-    optfield[2]= dp->sname;
-    optlen[2]= 0;
-
-    for (i= 0; i < 3; i++) {
-       p= optfield[i];
-       while (p < optfield[i] + optlen[i]) {
-           tag= *p++;
-           if (tag == 255) break;
-           len= tag == 0 ? 0 : *p++;
-           if (tag == searchtag) {
-               if (pdata != nil) *pdata= p;
-               if (plen != nil) *plen= len;
-               return 1;
-           }
-           if (tag == DHCP_TAG_OVERLOAD) {
-               /* There are also options in the file or sname field. */
-               if (*p & 1) optlen[1]= arraysize(dp->file);
-               if (*p & 2) optlen[1]= arraysize(dp->sname);
-           }
-           p += len;
-       }
-    }
-    return 0;
-}
diff --git a/minix/lib/libc/gen/dhcp_settag.c b/minix/lib/libc/gen/dhcp_settag.c
deleted file mode 100644 (file)
index 7cba82d..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*     dhcp_init(), dhcp_settag()                      Author: Kees J. Bot
- *                                                             1 Dec 2000
- */
-#define nil ((void*)0)
-#include <stddef.h>
-#include <string.h>
-#include <sys/types.h>
-#include <net/hton.h>
-#include <net/gen/in.h>
-#include <net/gen/dhcp.h>
-
-#define arraysize(a)   (sizeof(a) / sizeof((a)[0]))
-#define arraylimit(a)  ((a) + arraysize(a))
-
-void dhcp_init(dhcp_t *dp)
-{
-    /* Initialize a DHCP packet. */
-    memset(dp, 0, offsetof(dhcp_t, magic));
-    dp->magic= DHCP_MAGIC;
-    memset(dp->options, 255, sizeof(dp->options));
-}
-
-int dhcp_settag(dhcp_t *dp, int tag, void *data, size_t len)
-{
-    /* Add a tag to a DHCP packet.  No padding.  Only do the options field.
-     * (This is Minix, we don't need megabytes of silly bits of data.)
-     * The length may be zero to delete a tag.
-     */
-    u8_t *p;
-    int n;
-
-    if (tag <= 0 || tag >= 255) return 0;
-
-    for (p= dp->options; p < arraylimit(dp->options) && *p != 255; p += n) {
-       n= 1 + 1 + p[1];
-       if (*p == tag) {
-           /* The tag is already there, remove it so it gets replaced. */
-           memmove(p, p + n, arraylimit(dp->options) - (p + n));
-           memset(arraylimit(dp->options) - n, 255, n);
-           n= 0;
-       }
-    }
-
-    /* Add tag. */
-    if (len == 0) {
-       /* We're merely deleting a tag. */
-    } else
-    if (p + 1 + 1 + len <= arraylimit(dp->options)) {
-       *p++ = tag;
-       *p++ = len;
-       memcpy(p, data, len);
-    } else {
-       /* Oops, it didn't fit?  Is this really Minix??? */
-       return 0;
-    }
-    return 1;
-}
index e9e151fdc0ccfb916ee688c3e00242e27e0e5641..30cbb315e600e2b5abefa7bff495e2548e59848b 100644 (file)
@@ -71,9 +71,6 @@ A file that doesn't exist is seen as empty.
 .PP
 A generic configuration file can be read with the functions described in
 .BR configfile (3).
-.SH EXAMPLES
-Have a look at
-.BR /etc/dhcp.conf .
 .SH "SEE ALSO"
 .BR configfile (3).
 .SH NOTES