]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sbin/dhclient/dhclient.c
MFV r329799, r329800:
[FreeBSD/FreeBSD.git] / sbin / dhclient / dhclient.c
1 /*      $OpenBSD: dhclient.c,v 1.63 2005/02/06 17:10:13 krw Exp $       */
2
3 /*-
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  * Copyright 2004 Henning Brauer <henning@openbsd.org>
7  * Copyright (c) 1995, 1996, 1997, 1998, 1999
8  * The Internet Software Consortium.    All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. Neither the name of The Internet Software Consortium nor the names
20  *    of its contributors may be used to endorse or promote products derived
21  *    from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
24  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
25  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27  * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
28  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
31  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
32  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
34  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  *
37  * This software has been written for the Internet Software Consortium
38  * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
39  * Enterprises.  To learn more about the Internet Software Consortium,
40  * see ``http://www.vix.com/isc''.  To learn more about Vixie
41  * Enterprises, see ``http://www.vix.com''.
42  *
43  * This client was substantially modified and enhanced by Elliot Poger
44  * for use on Linux while he was working on the MosquitoNet project at
45  * Stanford.
46  *
47  * The current version owes much to Elliot's Linux enhancements, but
48  * was substantially reorganized and partially rewritten by Ted Lemon
49  * so as to use the same networking framework that the Internet Software
50  * Consortium DHCP server uses.   Much system-specific configuration code
51  * was moved into a shell script so that as support for more operating
52  * systems is added, it will not be necessary to port and maintain
53  * system-specific configuration code to these operating systems - instead,
54  * the shell script can invoke the native tools to accomplish the same
55  * purpose.
56  */
57
58 #include <sys/cdefs.h>
59 __FBSDID("$FreeBSD$");
60
61 #include "dhcpd.h"
62 #include "privsep.h"
63
64 #include <sys/capsicum.h>
65 #include <sys/endian.h>
66
67 #include <net80211/ieee80211_freebsd.h>
68
69 #ifndef _PATH_VAREMPTY
70 #define _PATH_VAREMPTY  "/var/empty"
71 #endif
72
73 #define PERIOD 0x2e
74 #define hyphenchar(c) ((c) == 0x2d)
75 #define bslashchar(c) ((c) == 0x5c)
76 #define periodchar(c) ((c) == PERIOD)
77 #define asterchar(c) ((c) == 0x2a)
78 #define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) || \
79             ((c) >= 0x61 && (c) <= 0x7a))
80 #define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
81 #define whitechar(c) ((c) == ' ' || (c) == '\t')
82
83 #define borderchar(c) (alphachar(c) || digitchar(c))
84 #define middlechar(c) (borderchar(c) || hyphenchar(c))
85 #define domainchar(c) ((c) > 0x20 && (c) < 0x7f)
86
87 #define CLIENT_PATH "PATH=/usr/bin:/usr/sbin:/bin:/sbin"
88
89 cap_channel_t *capsyslog;
90
91 time_t cur_time;
92 time_t default_lease_time = 43200; /* 12 hours... */
93
94 const char *path_dhclient_conf = _PATH_DHCLIENT_CONF;
95 char *path_dhclient_db = NULL;
96
97 int log_perror = 1;
98 int privfd;
99 int nullfd = -1;
100
101 char hostname[_POSIX_HOST_NAME_MAX + 1];
102
103 struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } };
104 struct in_addr inaddr_any, inaddr_broadcast;
105
106 char *path_dhclient_pidfile;
107 struct pidfh *pidfile;
108
109 /*
110  * ASSERT_STATE() does nothing now; it used to be
111  * assert (state_is == state_shouldbe).
112  */
113 #define ASSERT_STATE(state_is, state_shouldbe) {}
114
115 /*
116  * We need to check that the expiry, renewal and rebind times are not beyond
117  * the end of time (~2038 when a 32-bit time_t is being used).
118  */
119 #define TIME_MAX        ((((time_t) 1 << (sizeof(time_t) * CHAR_BIT - 2)) - 1) * 2 + 1)
120
121 int             log_priority;
122 int             no_daemon;
123 int             unknown_ok = 1;
124 int             routefd;
125
126 struct interface_info   *ifi;
127
128 int              findproto(char *, int);
129 struct sockaddr *get_ifa(char *, int);
130 void             routehandler(struct protocol *);
131 void             usage(void);
132 int              check_option(struct client_lease *l, int option);
133 int              check_classless_option(unsigned char *data, int len);
134 int              ipv4addrs(const char * buf);
135 int              res_hnok(const char *dn);
136 int              check_search(const char *srch);
137 const char      *option_as_string(unsigned int code, unsigned char *data, int len);
138 int              fork_privchld(int, int);
139
140 #define ROUNDUP(a) \
141             ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
142 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
143
144 /* Minimum MTU is 68 as per RFC791, p. 24 */
145 #define MIN_MTU 68
146
147 static time_t   scripttime;
148
149 int
150 findproto(char *cp, int n)
151 {
152         struct sockaddr *sa;
153         unsigned i;
154
155         if (n == 0)
156                 return -1;
157         for (i = 1; i; i <<= 1) {
158                 if (i & n) {
159                         sa = (struct sockaddr *)cp;
160                         switch (i) {
161                         case RTA_IFA:
162                         case RTA_DST:
163                         case RTA_GATEWAY:
164                         case RTA_NETMASK:
165                                 if (sa->sa_family == AF_INET)
166                                         return AF_INET;
167                                 if (sa->sa_family == AF_INET6)
168                                         return AF_INET6;
169                                 break;
170                         case RTA_IFP:
171                                 break;
172                         }
173                         ADVANCE(cp, sa);
174                 }
175         }
176         return (-1);
177 }
178
179 struct sockaddr *
180 get_ifa(char *cp, int n)
181 {
182         struct sockaddr *sa;
183         unsigned i;
184
185         if (n == 0)
186                 return (NULL);
187         for (i = 1; i; i <<= 1)
188                 if (i & n) {
189                         sa = (struct sockaddr *)cp;
190                         if (i == RTA_IFA)
191                                 return (sa);
192                         ADVANCE(cp, sa);
193                 }
194
195         return (NULL);
196 }
197
198 struct iaddr defaddr = { .len = 4 };
199 uint8_t curbssid[6];
200
201 static void
202 disassoc(void *arg)
203 {
204         struct interface_info *_ifi = arg;
205
206         /*
207          * Clear existing state.
208          */
209         if (_ifi->client->active != NULL) {
210                 script_init("EXPIRE", NULL);
211                 script_write_params("old_",
212                     _ifi->client->active);
213                 if (_ifi->client->alias)
214                         script_write_params("alias_",
215                                 _ifi->client->alias);
216                 script_go();
217         }
218         _ifi->client->state = S_INIT;
219 }
220
221 void
222 routehandler(struct protocol *p __unused)
223 {
224         char msg[2048], *addr;
225         struct rt_msghdr *rtm;
226         struct if_msghdr *ifm;
227         struct ifa_msghdr *ifam;
228         struct if_announcemsghdr *ifan;
229         struct ieee80211_join_event *jev;
230         struct client_lease *l;
231         time_t t = time(NULL);
232         struct sockaddr_in *sa;
233         struct iaddr a;
234         ssize_t n;
235         int linkstat;
236
237         n = read(routefd, &msg, sizeof(msg));
238         rtm = (struct rt_msghdr *)msg;
239         if (n < (ssize_t)sizeof(rtm->rtm_msglen) ||
240             n < (ssize_t)rtm->rtm_msglen ||
241             rtm->rtm_version != RTM_VERSION)
242                 return;
243
244         switch (rtm->rtm_type) {
245         case RTM_NEWADDR:
246         case RTM_DELADDR:
247                 ifam = (struct ifa_msghdr *)rtm;
248
249                 if (ifam->ifam_index != ifi->index)
250                         break;
251                 if (findproto((char *)(ifam + 1), ifam->ifam_addrs) != AF_INET)
252                         break;
253                 if (scripttime == 0 || t < scripttime + 10)
254                         break;
255
256                 sa = (struct sockaddr_in*)get_ifa((char *)(ifam + 1), ifam->ifam_addrs);
257                 if (sa == NULL)
258                         break;
259
260                 if ((a.len = sizeof(struct in_addr)) > sizeof(a.iabuf))
261                         error("king bula sez: len mismatch");
262                 memcpy(a.iabuf, &sa->sin_addr, a.len);
263                 if (addr_eq(a, defaddr))
264                         break;
265
266                 for (l = ifi->client->active; l != NULL; l = l->next)
267                         if (addr_eq(a, l->address))
268                                 break;
269
270                 if (l == NULL)  /* added/deleted addr is not the one we set */
271                         break;
272
273                 addr = inet_ntoa(sa->sin_addr);
274                 if (rtm->rtm_type == RTM_NEWADDR)  {
275                         /*
276                          * XXX: If someone other than us adds our address,
277                          * should we assume they are taking over from us,
278                          * delete the lease record, and exit without modifying
279                          * the interface?
280                          */
281                         warning("My address (%s) was re-added", addr);
282                 } else {
283                         warning("My address (%s) was deleted, dhclient exiting",
284                             addr);
285                         goto die;
286                 }
287                 break;
288         case RTM_IFINFO:
289                 ifm = (struct if_msghdr *)rtm;
290                 if (ifm->ifm_index != ifi->index)
291                         break;
292                 if ((rtm->rtm_flags & RTF_UP) == 0) {
293                         warning("Interface %s is down, dhclient exiting",
294                             ifi->name);
295                         goto die;
296                 }
297                 linkstat = interface_link_status(ifi->name);
298                 if (linkstat != ifi->linkstat) {
299                         debug("%s link state %s -> %s", ifi->name,
300                             ifi->linkstat ? "up" : "down",
301                             linkstat ? "up" : "down");
302                         ifi->linkstat = linkstat;
303                         if (linkstat)
304                                 state_reboot(ifi);
305                 }
306                 break;
307         case RTM_IFANNOUNCE:
308                 ifan = (struct if_announcemsghdr *)rtm;
309                 if (ifan->ifan_what == IFAN_DEPARTURE &&
310                     ifan->ifan_index == ifi->index) {
311                         warning("Interface %s is gone, dhclient exiting",
312                             ifi->name);
313                         goto die;
314                 }
315                 break;
316         case RTM_IEEE80211:
317                 ifan = (struct if_announcemsghdr *)rtm;
318                 if (ifan->ifan_index != ifi->index)
319                         break;
320                 switch (ifan->ifan_what) {
321                 case RTM_IEEE80211_ASSOC:
322                 case RTM_IEEE80211_REASSOC:
323                         /*
324                          * Use assoc/reassoc event to kick state machine
325                          * in case we roam.  Otherwise fall back to the
326                          * normal state machine just like a wired network.
327                          */
328                         jev = (struct ieee80211_join_event *) &ifan[1];
329                         if (memcmp(curbssid, jev->iev_addr, 6)) {
330                                 disassoc(ifi);
331                                 state_reboot(ifi);
332                         }
333                         memcpy(curbssid, jev->iev_addr, 6);
334                         break;
335                 }
336                 break;
337         default:
338                 break;
339         }
340         return;
341
342 die:
343         script_init("FAIL", NULL);
344         if (ifi->client->alias)
345                 script_write_params("alias_", ifi->client->alias);
346         script_go();
347         if (pidfile != NULL)
348                 pidfile_remove(pidfile);
349         exit(1);
350 }
351
352 static void
353 init_casper(void)
354 {
355         cap_channel_t           *casper;
356
357         casper = cap_init();
358         if (casper == NULL)
359                 error("unable to start casper");
360
361         capsyslog = cap_service_open(casper, "system.syslog");
362         cap_close(casper);
363         if (capsyslog == NULL)
364                 error("unable to open system.syslog service");
365 }
366
367 int
368 main(int argc, char *argv[])
369 {
370         extern char             *__progname;
371         int                      ch, fd, quiet = 0, i = 0;
372         int                      pipe_fd[2];
373         int                      immediate_daemon = 0;
374         struct passwd           *pw;
375         pid_t                    otherpid;
376         cap_rights_t             rights;
377
378         init_casper();
379
380         /* Initially, log errors to stderr as well as to syslogd. */
381         cap_openlog(capsyslog, __progname, LOG_PID | LOG_NDELAY, DHCPD_LOG_FACILITY);
382         cap_setlogmask(capsyslog, LOG_UPTO(LOG_DEBUG));
383
384         while ((ch = getopt(argc, argv, "bc:dl:p:qu")) != -1)
385                 switch (ch) {
386                 case 'b':
387                         immediate_daemon = 1;
388                         break;
389                 case 'c':
390                         path_dhclient_conf = optarg;
391                         break;
392                 case 'd':
393                         no_daemon = 1;
394                         break;
395                 case 'l':
396                         path_dhclient_db = optarg;
397                         break;
398                 case 'p':
399                         path_dhclient_pidfile = optarg;
400                         break;
401                 case 'q':
402                         quiet = 1;
403                         break;
404                 case 'u':
405                         unknown_ok = 0;
406                         break;
407                 default:
408                         usage();
409                 }
410
411         argc -= optind;
412         argv += optind;
413
414         if (argc != 1)
415                 usage();
416
417         if (path_dhclient_pidfile == NULL) {
418                 asprintf(&path_dhclient_pidfile,
419                     "%sdhclient.%s.pid", _PATH_VARRUN, *argv);
420                 if (path_dhclient_pidfile == NULL)
421                         error("asprintf");
422         }
423         pidfile = pidfile_open(path_dhclient_pidfile, 0644, &otherpid);
424         if (pidfile == NULL) {
425                 if (errno == EEXIST)
426                         error("dhclient already running, pid: %d.", otherpid);
427                 if (errno == EAGAIN)
428                         error("dhclient already running.");
429                 warning("Cannot open or create pidfile: %m");
430         }
431
432         if ((ifi = calloc(1, sizeof(struct interface_info))) == NULL)
433                 error("calloc");
434         if (strlcpy(ifi->name, argv[0], IFNAMSIZ) >= IFNAMSIZ)
435                 error("Interface name too long");
436         if (path_dhclient_db == NULL && asprintf(&path_dhclient_db, "%s.%s",
437             _PATH_DHCLIENT_DB, ifi->name) == -1)
438                 error("asprintf");
439
440         if (quiet)
441                 log_perror = 0;
442
443         tzset();
444         time(&cur_time);
445
446         inaddr_broadcast.s_addr = INADDR_BROADCAST;
447         inaddr_any.s_addr = INADDR_ANY;
448
449         read_client_conf();
450
451         /* The next bit is potentially very time-consuming, so write out
452            the pidfile right away.  We will write it out again with the
453            correct pid after daemonizing. */
454         if (pidfile != NULL)
455                 pidfile_write(pidfile);
456
457         if (!interface_link_status(ifi->name)) {
458                 fprintf(stderr, "%s: no link ...", ifi->name);
459                 fflush(stderr);
460                 sleep(1);
461                 while (!interface_link_status(ifi->name)) {
462                         fprintf(stderr, ".");
463                         fflush(stderr);
464                         if (++i > 10) {
465                                 fprintf(stderr, " giving up\n");
466                                 exit(1);
467                         }
468                         sleep(1);
469                 }
470                 fprintf(stderr, " got link\n");
471         }
472         ifi->linkstat = 1;
473
474         if ((nullfd = open(_PATH_DEVNULL, O_RDWR, 0)) == -1)
475                 error("cannot open %s: %m", _PATH_DEVNULL);
476
477         if ((pw = getpwnam("_dhcp")) == NULL) {
478                 warning("no such user: _dhcp, falling back to \"nobody\"");
479                 if ((pw = getpwnam("nobody")) == NULL)
480                         error("no such user: nobody");
481         }
482
483         /*
484          * Obtain hostname before entering capability mode - it won't be
485          * possible then, as reading kern.hostname is not permitted.
486          */
487         if (gethostname(hostname, sizeof(hostname)) < 0)
488                 hostname[0] = '\0';
489
490         priv_script_init("PREINIT", NULL);
491         if (ifi->client->alias)
492                 priv_script_write_params("alias_", ifi->client->alias);
493         priv_script_go();
494
495         /* set up the interface */
496         discover_interfaces(ifi);
497
498         if (pipe(pipe_fd) == -1)
499                 error("pipe");
500
501         fork_privchld(pipe_fd[0], pipe_fd[1]);
502
503         close(ifi->ufdesc);
504         ifi->ufdesc = -1;
505         close(ifi->wfdesc);
506         ifi->wfdesc = -1;
507
508         close(pipe_fd[0]);
509         privfd = pipe_fd[1];
510         cap_rights_init(&rights, CAP_READ, CAP_WRITE);
511         if (cap_rights_limit(privfd, &rights) < 0 && errno != ENOSYS)
512                 error("can't limit private descriptor: %m");
513
514         if ((fd = open(path_dhclient_db, O_RDONLY|O_EXLOCK|O_CREAT, 0)) == -1)
515                 error("can't open and lock %s: %m", path_dhclient_db);
516         read_client_leases();
517         rewrite_client_leases();
518         close(fd);
519
520         if ((routefd = socket(PF_ROUTE, SOCK_RAW, 0)) != -1)
521                 add_protocol("AF_ROUTE", routefd, routehandler, ifi);
522         if (shutdown(routefd, SHUT_WR) < 0)
523                 error("can't shutdown route socket: %m");
524         cap_rights_init(&rights, CAP_EVENT, CAP_READ);
525         if (cap_rights_limit(routefd, &rights) < 0 && errno != ENOSYS)
526                 error("can't limit route socket: %m");
527
528         if (chroot(_PATH_VAREMPTY) == -1)
529                 error("chroot");
530         if (chdir("/") == -1)
531                 error("chdir(\"/\")");
532
533         if (setgroups(1, &pw->pw_gid) ||
534             setegid(pw->pw_gid) || setgid(pw->pw_gid) ||
535             seteuid(pw->pw_uid) || setuid(pw->pw_uid))
536                 error("can't drop privileges: %m");
537
538         endpwent();
539
540         setproctitle("%s", ifi->name);
541
542         if (CASPER_SUPPORT && cap_enter() < 0 && errno != ENOSYS)
543                 error("can't enter capability mode: %m");
544
545         if (immediate_daemon)
546                 go_daemon();
547
548         ifi->client->state = S_INIT;
549         state_reboot(ifi);
550
551         bootp_packet_handler = do_packet;
552
553         dispatch();
554
555         /* not reached */
556         return (0);
557 }
558
559 void
560 usage(void)
561 {
562         extern char     *__progname;
563
564         fprintf(stderr, "usage: %s [-bdqu] ", __progname);
565         fprintf(stderr, "[-c conffile] [-l leasefile] interface\n");
566         exit(1);
567 }
568
569 /*
570  * Individual States:
571  *
572  * Each routine is called from the dhclient_state_machine() in one of
573  * these conditions:
574  * -> entering INIT state
575  * -> recvpacket_flag == 0: timeout in this state
576  * -> otherwise: received a packet in this state
577  *
578  * Return conditions as handled by dhclient_state_machine():
579  * Returns 1, sendpacket_flag = 1: send packet, reset timer.
580  * Returns 1, sendpacket_flag = 0: just reset the timer (wait for a milestone).
581  * Returns 0: finish the nap which was interrupted for no good reason.
582  *
583  * Several per-interface variables are used to keep track of the process:
584  *   active_lease: the lease that is being used on the interface
585  *                 (null pointer if not configured yet).
586  *   offered_leases: leases corresponding to DHCPOFFER messages that have
587  *                   been sent to us by DHCP servers.
588  *   acked_leases: leases corresponding to DHCPACK messages that have been
589  *                 sent to us by DHCP servers.
590  *   sendpacket: DHCP packet we're trying to send.
591  *   destination: IP address to send sendpacket to
592  * In addition, there are several relevant per-lease variables.
593  *   T1_expiry, T2_expiry, lease_expiry: lease milestones
594  * In the active lease, these control the process of renewing the lease;
595  * In leases on the acked_leases list, this simply determines when we
596  * can no longer legitimately use the lease.
597  */
598
599 void
600 state_reboot(void *ipp)
601 {
602         struct interface_info *ip = ipp;
603
604         /* If we don't remember an active lease, go straight to INIT. */
605         if (!ip->client->active || ip->client->active->is_bootp) {
606                 state_init(ip);
607                 return;
608         }
609
610         /* We are in the rebooting state. */
611         ip->client->state = S_REBOOTING;
612
613         /* make_request doesn't initialize xid because it normally comes
614            from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
615            so pick an xid now. */
616         ip->client->xid = arc4random();
617
618         /* Make a DHCPREQUEST packet, and set appropriate per-interface
619            flags. */
620         make_request(ip, ip->client->active);
621         ip->client->destination = iaddr_broadcast;
622         ip->client->first_sending = cur_time;
623         ip->client->interval = ip->client->config->initial_interval;
624
625         /* Zap the medium list... */
626         ip->client->medium = NULL;
627
628         /* Send out the first DHCPREQUEST packet. */
629         send_request(ip);
630 }
631
632 /*
633  * Called when a lease has completely expired and we've
634  * been unable to renew it.
635  */
636 void
637 state_init(void *ipp)
638 {
639         struct interface_info *ip = ipp;
640
641         ASSERT_STATE(state, S_INIT);
642
643         /* Make a DHCPDISCOVER packet, and set appropriate per-interface
644            flags. */
645         make_discover(ip, ip->client->active);
646         ip->client->xid = ip->client->packet.xid;
647         ip->client->destination = iaddr_broadcast;
648         ip->client->state = S_SELECTING;
649         ip->client->first_sending = cur_time;
650         ip->client->interval = ip->client->config->initial_interval;
651
652         /* Add an immediate timeout to cause the first DHCPDISCOVER packet
653            to go out. */
654         send_discover(ip);
655 }
656
657 /*
658  * state_selecting is called when one or more DHCPOFFER packets
659  * have been received and a configurable period of time has passed.
660  */
661 void
662 state_selecting(void *ipp)
663 {
664         struct interface_info *ip = ipp;
665         struct client_lease *lp, *next, *picked;
666
667         ASSERT_STATE(state, S_SELECTING);
668
669         /* Cancel state_selecting and send_discover timeouts, since either
670            one could have got us here. */
671         cancel_timeout(state_selecting, ip);
672         cancel_timeout(send_discover, ip);
673
674         /* We have received one or more DHCPOFFER packets.   Currently,
675            the only criterion by which we judge leases is whether or
676            not we get a response when we arp for them. */
677         picked = NULL;
678         for (lp = ip->client->offered_leases; lp; lp = next) {
679                 next = lp->next;
680
681                 /* Check to see if we got an ARPREPLY for the address
682                    in this particular lease. */
683                 if (!picked) {
684                         script_init("ARPCHECK", lp->medium);
685                         script_write_params("check_", lp);
686
687                         /* If the ARPCHECK code detects another
688                            machine using the offered address, it exits
689                            nonzero.  We need to send a DHCPDECLINE and
690                            toss the lease. */
691                         if (script_go()) {
692                                 make_decline(ip, lp);
693                                 send_decline(ip);
694                                 goto freeit;
695                         }
696                         picked = lp;
697                         picked->next = NULL;
698                 } else {
699 freeit:
700                         free_client_lease(lp);
701                 }
702         }
703         ip->client->offered_leases = NULL;
704
705         /* If we just tossed all the leases we were offered, go back
706            to square one. */
707         if (!picked) {
708                 ip->client->state = S_INIT;
709                 state_init(ip);
710                 return;
711         }
712
713         /* If it was a BOOTREPLY, we can just take the address right now. */
714         if (!picked->options[DHO_DHCP_MESSAGE_TYPE].len) {
715                 ip->client->new = picked;
716
717                 /* Make up some lease expiry times
718                    XXX these should be configurable. */
719                 ip->client->new->expiry = cur_time + 12000;
720                 ip->client->new->renewal += cur_time + 8000;
721                 ip->client->new->rebind += cur_time + 10000;
722
723                 ip->client->state = S_REQUESTING;
724
725                 /* Bind to the address we received. */
726                 bind_lease(ip);
727                 return;
728         }
729
730         /* Go to the REQUESTING state. */
731         ip->client->destination = iaddr_broadcast;
732         ip->client->state = S_REQUESTING;
733         ip->client->first_sending = cur_time;
734         ip->client->interval = ip->client->config->initial_interval;
735
736         /* Make a DHCPREQUEST packet from the lease we picked. */
737         make_request(ip, picked);
738         ip->client->xid = ip->client->packet.xid;
739
740         /* Toss the lease we picked - we'll get it back in a DHCPACK. */
741         free_client_lease(picked);
742
743         /* Add an immediate timeout to send the first DHCPREQUEST packet. */
744         send_request(ip);
745 }
746
747 /* state_requesting is called when we receive a DHCPACK message after
748    having sent out one or more DHCPREQUEST packets. */
749
750 void
751 dhcpack(struct packet *packet)
752 {
753         struct interface_info *ip = packet->interface;
754         struct client_lease *lease;
755
756         /* If we're not receptive to an offer right now, or if the offer
757            has an unrecognizable transaction id, then just drop it. */
758         if (packet->interface->client->xid != packet->raw->xid ||
759             (packet->interface->hw_address.hlen != packet->raw->hlen) ||
760             (memcmp(packet->interface->hw_address.haddr,
761             packet->raw->chaddr, packet->raw->hlen)))
762                 return;
763
764         if (ip->client->state != S_REBOOTING &&
765             ip->client->state != S_REQUESTING &&
766             ip->client->state != S_RENEWING &&
767             ip->client->state != S_REBINDING)
768                 return;
769
770         note("DHCPACK from %s", piaddr(packet->client_addr));
771
772         lease = packet_to_lease(packet);
773         if (!lease) {
774                 note("packet_to_lease failed.");
775                 return;
776         }
777
778         ip->client->new = lease;
779
780         /* Stop resending DHCPREQUEST. */
781         cancel_timeout(send_request, ip);
782
783         /* Figure out the lease time. */
784         if (ip->client->config->default_actions[DHO_DHCP_LEASE_TIME] ==
785             ACTION_SUPERSEDE)
786                 ip->client->new->expiry = getULong(
787                     ip->client->config->defaults[DHO_DHCP_LEASE_TIME].data);
788         else if (ip->client->new->options[DHO_DHCP_LEASE_TIME].data)
789                 ip->client->new->expiry = getULong(
790                     ip->client->new->options[DHO_DHCP_LEASE_TIME].data);
791         else
792                 ip->client->new->expiry = default_lease_time;
793         /* A number that looks negative here is really just very large,
794            because the lease expiry offset is unsigned. Also make sure that
795            the addition of cur_time below does not overflow (a 32 bit) time_t. */
796         if (ip->client->new->expiry < 0 ||
797             ip->client->new->expiry > TIME_MAX - cur_time)
798                 ip->client->new->expiry = TIME_MAX - cur_time;
799         /* XXX should be fixed by resetting the client state */
800         if (ip->client->new->expiry < 60)
801                 ip->client->new->expiry = 60;
802
803         /* Unless overridden in the config, take the server-provided renewal
804          * time if there is one. Otherwise figure it out according to the spec.
805          * Also make sure the renewal time does not exceed the expiry time.
806          */
807         if (ip->client->config->default_actions[DHO_DHCP_RENEWAL_TIME] ==
808             ACTION_SUPERSEDE)
809                 ip->client->new->renewal = getULong(
810                     ip->client->config->defaults[DHO_DHCP_RENEWAL_TIME].data);
811         else if (ip->client->new->options[DHO_DHCP_RENEWAL_TIME].len)
812                 ip->client->new->renewal = getULong(
813                     ip->client->new->options[DHO_DHCP_RENEWAL_TIME].data);
814         else
815                 ip->client->new->renewal = ip->client->new->expiry / 2;
816         if (ip->client->new->renewal < 0 ||
817             ip->client->new->renewal > ip->client->new->expiry / 2)
818                 ip->client->new->renewal = ip->client->new->expiry / 2;
819
820         /* Same deal with the rebind time. */
821         if (ip->client->config->default_actions[DHO_DHCP_REBINDING_TIME] ==
822             ACTION_SUPERSEDE)
823                 ip->client->new->rebind = getULong(
824                     ip->client->config->defaults[DHO_DHCP_REBINDING_TIME].data);
825         else if (ip->client->new->options[DHO_DHCP_REBINDING_TIME].len)
826                 ip->client->new->rebind = getULong(
827                     ip->client->new->options[DHO_DHCP_REBINDING_TIME].data);
828         else
829                 ip->client->new->rebind = ip->client->new->renewal / 4 * 7;
830         if (ip->client->new->rebind < 0 ||
831             ip->client->new->rebind > ip->client->new->renewal / 4 * 7)
832                 ip->client->new->rebind = ip->client->new->renewal / 4 * 7;
833
834         /* Convert the time offsets into seconds-since-the-epoch */
835         ip->client->new->expiry += cur_time;
836         ip->client->new->renewal += cur_time;
837         ip->client->new->rebind += cur_time;
838
839         bind_lease(ip);
840 }
841
842 void
843 bind_lease(struct interface_info *ip)
844 {
845         struct option_data *opt;
846
847         /* Remember the medium. */
848         ip->client->new->medium = ip->client->medium;
849
850         opt = &ip->client->new->options[DHO_INTERFACE_MTU];
851         if (opt->len == sizeof(u_int16_t)) {
852                 u_int16_t mtu = be16dec(opt->data);
853                 if (mtu < MIN_MTU)
854                         warning("mtu size %u < %d: ignored", (unsigned)mtu, MIN_MTU);
855                 else
856                         interface_set_mtu_unpriv(privfd, mtu);
857         }
858
859         /* Write out the new lease. */
860         write_client_lease(ip, ip->client->new, 0);
861
862         /* Run the client script with the new parameters. */
863         script_init((ip->client->state == S_REQUESTING ? "BOUND" :
864             (ip->client->state == S_RENEWING ? "RENEW" :
865             (ip->client->state == S_REBOOTING ? "REBOOT" : "REBIND"))),
866             ip->client->new->medium);
867         if (ip->client->active && ip->client->state != S_REBOOTING)
868                 script_write_params("old_", ip->client->active);
869         script_write_params("new_", ip->client->new);
870         if (ip->client->alias)
871                 script_write_params("alias_", ip->client->alias);
872         script_go();
873
874         /* Replace the old active lease with the new one. */
875         if (ip->client->active)
876                 free_client_lease(ip->client->active);
877         ip->client->active = ip->client->new;
878         ip->client->new = NULL;
879
880         /* Set up a timeout to start the renewal process. */
881         add_timeout(ip->client->active->renewal, state_bound, ip);
882
883         note("bound to %s -- renewal in %d seconds.",
884             piaddr(ip->client->active->address),
885             (int)(ip->client->active->renewal - cur_time));
886         ip->client->state = S_BOUND;
887         reinitialize_interfaces();
888         go_daemon();
889 }
890
891 /*
892  * state_bound is called when we've successfully bound to a particular
893  * lease, but the renewal time on that lease has expired.   We are
894  * expected to unicast a DHCPREQUEST to the server that gave us our
895  * original lease.
896  */
897 void
898 state_bound(void *ipp)
899 {
900         struct interface_info *ip = ipp;
901
902         ASSERT_STATE(state, S_BOUND);
903
904         /* T1 has expired. */
905         make_request(ip, ip->client->active);
906         ip->client->xid = ip->client->packet.xid;
907
908         if (ip->client->active->options[DHO_DHCP_SERVER_IDENTIFIER].len == 4) {
909                 memcpy(ip->client->destination.iabuf, ip->client->active->
910                     options[DHO_DHCP_SERVER_IDENTIFIER].data, 4);
911                 ip->client->destination.len = 4;
912         } else
913                 ip->client->destination = iaddr_broadcast;
914
915         ip->client->first_sending = cur_time;
916         ip->client->interval = ip->client->config->initial_interval;
917         ip->client->state = S_RENEWING;
918
919         /* Send the first packet immediately. */
920         send_request(ip);
921 }
922
923 void
924 bootp(struct packet *packet)
925 {
926         struct iaddrlist *ap;
927
928         if (packet->raw->op != BOOTREPLY)
929                 return;
930
931         /* If there's a reject list, make sure this packet's sender isn't
932            on it. */
933         for (ap = packet->interface->client->config->reject_list;
934             ap; ap = ap->next) {
935                 if (addr_eq(packet->client_addr, ap->addr)) {
936                         note("BOOTREPLY from %s rejected.", piaddr(ap->addr));
937                         return;
938                 }
939         }
940         dhcpoffer(packet);
941 }
942
943 void
944 dhcp(struct packet *packet)
945 {
946         struct iaddrlist *ap;
947         void (*handler)(struct packet *);
948         const char *type;
949
950         switch (packet->packet_type) {
951         case DHCPOFFER:
952                 handler = dhcpoffer;
953                 type = "DHCPOFFER";
954                 break;
955         case DHCPNAK:
956                 handler = dhcpnak;
957                 type = "DHCPNACK";
958                 break;
959         case DHCPACK:
960                 handler = dhcpack;
961                 type = "DHCPACK";
962                 break;
963         default:
964                 return;
965         }
966
967         /* If there's a reject list, make sure this packet's sender isn't
968            on it. */
969         for (ap = packet->interface->client->config->reject_list;
970             ap; ap = ap->next) {
971                 if (addr_eq(packet->client_addr, ap->addr)) {
972                         note("%s from %s rejected.", type, piaddr(ap->addr));
973                         return;
974                 }
975         }
976         (*handler)(packet);
977 }
978
979 void
980 dhcpoffer(struct packet *packet)
981 {
982         struct interface_info *ip = packet->interface;
983         struct client_lease *lease, *lp;
984         int i;
985         int arp_timeout_needed, stop_selecting;
986         const char *name = packet->options[DHO_DHCP_MESSAGE_TYPE].len ?
987             "DHCPOFFER" : "BOOTREPLY";
988
989         /* If we're not receptive to an offer right now, or if the offer
990            has an unrecognizable transaction id, then just drop it. */
991         if (ip->client->state != S_SELECTING ||
992             packet->interface->client->xid != packet->raw->xid ||
993             (packet->interface->hw_address.hlen != packet->raw->hlen) ||
994             (memcmp(packet->interface->hw_address.haddr,
995             packet->raw->chaddr, packet->raw->hlen)))
996                 return;
997
998         note("%s from %s", name, piaddr(packet->client_addr));
999
1000
1001         /* If this lease doesn't supply the minimum required parameters,
1002            blow it off. */
1003         for (i = 0; ip->client->config->required_options[i]; i++) {
1004                 if (!packet->options[ip->client->config->
1005                     required_options[i]].len) {
1006                         note("%s isn't satisfactory.", name);
1007                         return;
1008                 }
1009         }
1010
1011         /* If we've already seen this lease, don't record it again. */
1012         for (lease = ip->client->offered_leases;
1013             lease; lease = lease->next) {
1014                 if (lease->address.len == sizeof(packet->raw->yiaddr) &&
1015                     !memcmp(lease->address.iabuf,
1016                     &packet->raw->yiaddr, lease->address.len)) {
1017                         debug("%s already seen.", name);
1018                         return;
1019                 }
1020         }
1021
1022         lease = packet_to_lease(packet);
1023         if (!lease) {
1024                 note("packet_to_lease failed.");
1025                 return;
1026         }
1027
1028         /* If this lease was acquired through a BOOTREPLY, record that
1029            fact. */
1030         if (!packet->options[DHO_DHCP_MESSAGE_TYPE].len)
1031                 lease->is_bootp = 1;
1032
1033         /* Record the medium under which this lease was offered. */
1034         lease->medium = ip->client->medium;
1035
1036         /* Send out an ARP Request for the offered IP address. */
1037         script_init("ARPSEND", lease->medium);
1038         script_write_params("check_", lease);
1039         /* If the script can't send an ARP request without waiting,
1040            we'll be waiting when we do the ARPCHECK, so don't wait now. */
1041         if (script_go())
1042                 arp_timeout_needed = 0;
1043         else
1044                 arp_timeout_needed = 2;
1045
1046         /* Figure out when we're supposed to stop selecting. */
1047         stop_selecting =
1048             ip->client->first_sending + ip->client->config->select_interval;
1049
1050         /* If this is the lease we asked for, put it at the head of the
1051            list, and don't mess with the arp request timeout. */
1052         if (lease->address.len == ip->client->requested_address.len &&
1053             !memcmp(lease->address.iabuf,
1054             ip->client->requested_address.iabuf,
1055             ip->client->requested_address.len)) {
1056                 lease->next = ip->client->offered_leases;
1057                 ip->client->offered_leases = lease;
1058         } else {
1059                 /* If we already have an offer, and arping for this
1060                    offer would take us past the selection timeout,
1061                    then don't extend the timeout - just hope for the
1062                    best. */
1063                 if (ip->client->offered_leases &&
1064                     (cur_time + arp_timeout_needed) > stop_selecting)
1065                         arp_timeout_needed = 0;
1066
1067                 /* Put the lease at the end of the list. */
1068                 lease->next = NULL;
1069                 if (!ip->client->offered_leases)
1070                         ip->client->offered_leases = lease;
1071                 else {
1072                         for (lp = ip->client->offered_leases; lp->next;
1073                             lp = lp->next)
1074                                 ;       /* nothing */
1075                         lp->next = lease;
1076                 }
1077         }
1078
1079         /* If we're supposed to stop selecting before we've had time
1080            to wait for the ARPREPLY, add some delay to wait for
1081            the ARPREPLY. */
1082         if (stop_selecting - cur_time < arp_timeout_needed)
1083                 stop_selecting = cur_time + arp_timeout_needed;
1084
1085         /* If the selecting interval has expired, go immediately to
1086            state_selecting().  Otherwise, time out into
1087            state_selecting at the select interval. */
1088         if (stop_selecting <= 0)
1089                 state_selecting(ip);
1090         else {
1091                 add_timeout(stop_selecting, state_selecting, ip);
1092                 cancel_timeout(send_discover, ip);
1093         }
1094 }
1095
1096 /* Allocate a client_lease structure and initialize it from the parameters
1097    in the specified packet. */
1098
1099 struct client_lease *
1100 packet_to_lease(struct packet *packet)
1101 {
1102         struct client_lease *lease;
1103         int i;
1104
1105         lease = malloc(sizeof(struct client_lease));
1106
1107         if (!lease) {
1108                 warning("dhcpoffer: no memory to record lease.");
1109                 return (NULL);
1110         }
1111
1112         memset(lease, 0, sizeof(*lease));
1113
1114         /* Copy the lease options. */
1115         for (i = 0; i < 256; i++) {
1116                 if (packet->options[i].len) {
1117                         lease->options[i].data =
1118                             malloc(packet->options[i].len + 1);
1119                         if (!lease->options[i].data) {
1120                                 warning("dhcpoffer: no memory for option %d", i);
1121                                 free_client_lease(lease);
1122                                 return (NULL);
1123                         } else {
1124                                 memcpy(lease->options[i].data,
1125                                     packet->options[i].data,
1126                                     packet->options[i].len);
1127                                 lease->options[i].len =
1128                                     packet->options[i].len;
1129                                 lease->options[i].data[lease->options[i].len] =
1130                                     0;
1131                         }
1132                         if (!check_option(lease,i)) {
1133                                 /* ignore a bogus lease offer */
1134                                 warning("Invalid lease option - ignoring offer");
1135                                 free_client_lease(lease);
1136                                 return (NULL);
1137                         }
1138                 }
1139         }
1140
1141         lease->address.len = sizeof(packet->raw->yiaddr);
1142         memcpy(lease->address.iabuf, &packet->raw->yiaddr, lease->address.len);
1143
1144         lease->nextserver.len = sizeof(packet->raw->siaddr);
1145         memcpy(lease->nextserver.iabuf, &packet->raw->siaddr, lease->nextserver.len);
1146
1147         /* If the server name was filled out, copy it.
1148            Do not attempt to validate the server name as a host name.
1149            RFC 2131 merely states that sname is NUL-terminated (which do
1150            do not assume) and that it is the server's host name.  Since
1151            the ISC client and server allow arbitrary characters, we do
1152            as well. */
1153         if ((!packet->options[DHO_DHCP_OPTION_OVERLOAD].len ||
1154             !(packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 2)) &&
1155             packet->raw->sname[0]) {
1156                 lease->server_name = malloc(DHCP_SNAME_LEN + 1);
1157                 if (!lease->server_name) {
1158                         warning("dhcpoffer: no memory for server name.");
1159                         free_client_lease(lease);
1160                         return (NULL);
1161                 }
1162                 memcpy(lease->server_name, packet->raw->sname, DHCP_SNAME_LEN);
1163                 lease->server_name[DHCP_SNAME_LEN]='\0';
1164         }
1165
1166         /* Ditto for the filename. */
1167         if ((!packet->options[DHO_DHCP_OPTION_OVERLOAD].len ||
1168             !(packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 1)) &&
1169             packet->raw->file[0]) {
1170                 /* Don't count on the NUL terminator. */
1171                 lease->filename = malloc(DHCP_FILE_LEN + 1);
1172                 if (!lease->filename) {
1173                         warning("dhcpoffer: no memory for filename.");
1174                         free_client_lease(lease);
1175                         return (NULL);
1176                 }
1177                 memcpy(lease->filename, packet->raw->file, DHCP_FILE_LEN);
1178                 lease->filename[DHCP_FILE_LEN]='\0';
1179         }
1180         return lease;
1181 }
1182
1183 void
1184 dhcpnak(struct packet *packet)
1185 {
1186         struct interface_info *ip = packet->interface;
1187
1188         /* If we're not receptive to an offer right now, or if the offer
1189            has an unrecognizable transaction id, then just drop it. */
1190         if (packet->interface->client->xid != packet->raw->xid ||
1191             (packet->interface->hw_address.hlen != packet->raw->hlen) ||
1192             (memcmp(packet->interface->hw_address.haddr,
1193             packet->raw->chaddr, packet->raw->hlen)))
1194                 return;
1195
1196         if (ip->client->state != S_REBOOTING &&
1197             ip->client->state != S_REQUESTING &&
1198             ip->client->state != S_RENEWING &&
1199             ip->client->state != S_REBINDING)
1200                 return;
1201
1202         note("DHCPNAK from %s", piaddr(packet->client_addr));
1203
1204         if (!ip->client->active) {
1205                 note("DHCPNAK with no active lease.\n");
1206                 return;
1207         }
1208
1209         free_client_lease(ip->client->active);
1210         ip->client->active = NULL;
1211
1212         /* Stop sending DHCPREQUEST packets... */
1213         cancel_timeout(send_request, ip);
1214
1215         ip->client->state = S_INIT;
1216         state_init(ip);
1217 }
1218
1219 /* Send out a DHCPDISCOVER packet, and set a timeout to send out another
1220    one after the right interval has expired.  If we don't get an offer by
1221    the time we reach the panic interval, call the panic function. */
1222
1223 void
1224 send_discover(void *ipp)
1225 {
1226         struct interface_info *ip = ipp;
1227         int interval, increase = 1;
1228
1229         /* Figure out how long it's been since we started transmitting. */
1230         interval = cur_time - ip->client->first_sending;
1231
1232         /* If we're past the panic timeout, call the script and tell it
1233            we haven't found anything for this interface yet. */
1234         if (interval > ip->client->config->timeout) {
1235                 state_panic(ip);
1236                 return;
1237         }
1238
1239         /* If we're selecting media, try the whole list before doing
1240            the exponential backoff, but if we've already received an
1241            offer, stop looping, because we obviously have it right. */
1242         if (!ip->client->offered_leases &&
1243             ip->client->config->media) {
1244                 int fail = 0;
1245 again:
1246                 if (ip->client->medium) {
1247                         ip->client->medium = ip->client->medium->next;
1248                         increase = 0;
1249                 }
1250                 if (!ip->client->medium) {
1251                         if (fail)
1252                                 error("No valid media types for %s!", ip->name);
1253                         ip->client->medium = ip->client->config->media;
1254                         increase = 1;
1255                 }
1256
1257                 note("Trying medium \"%s\" %d", ip->client->medium->string,
1258                     increase);
1259                 script_init("MEDIUM", ip->client->medium);
1260                 if (script_go())
1261                         goto again;
1262         }
1263
1264         /*
1265          * If we're supposed to increase the interval, do so.  If it's
1266          * currently zero (i.e., we haven't sent any packets yet), set
1267          * it to one; otherwise, add to it a random number between zero
1268          * and two times itself.  On average, this means that it will
1269          * double with every transmission.
1270          */
1271         if (increase) {
1272                 if (!ip->client->interval)
1273                         ip->client->interval =
1274                             ip->client->config->initial_interval;
1275                 else {
1276                         ip->client->interval += (arc4random() >> 2) %
1277                             (2 * ip->client->interval);
1278                 }
1279
1280                 /* Don't backoff past cutoff. */
1281                 if (ip->client->interval >
1282                     ip->client->config->backoff_cutoff)
1283                         ip->client->interval =
1284                                 ((ip->client->config->backoff_cutoff / 2)
1285                                  + ((arc4random() >> 2) %
1286                                     ip->client->config->backoff_cutoff));
1287         } else if (!ip->client->interval)
1288                 ip->client->interval =
1289                         ip->client->config->initial_interval;
1290
1291         /* If the backoff would take us to the panic timeout, just use that
1292            as the interval. */
1293         if (cur_time + ip->client->interval >
1294             ip->client->first_sending + ip->client->config->timeout)
1295                 ip->client->interval =
1296                         (ip->client->first_sending +
1297                          ip->client->config->timeout) - cur_time + 1;
1298
1299         /* Record the number of seconds since we started sending. */
1300         if (interval < 65536)
1301                 ip->client->packet.secs = htons(interval);
1302         else
1303                 ip->client->packet.secs = htons(65535);
1304         ip->client->secs = ip->client->packet.secs;
1305
1306         note("DHCPDISCOVER on %s to %s port %d interval %d",
1307             ip->name, inet_ntoa(inaddr_broadcast), REMOTE_PORT,
1308             (int)ip->client->interval);
1309
1310         /* Send out a packet. */
1311         send_packet_unpriv(privfd, &ip->client->packet,
1312             ip->client->packet_length, inaddr_any, inaddr_broadcast);
1313
1314         add_timeout(cur_time + ip->client->interval, send_discover, ip);
1315 }
1316
1317 /*
1318  * state_panic gets called if we haven't received any offers in a preset
1319  * amount of time.   When this happens, we try to use existing leases
1320  * that haven't yet expired, and failing that, we call the client script
1321  * and hope it can do something.
1322  */
1323 void
1324 state_panic(void *ipp)
1325 {
1326         struct interface_info *ip = ipp;
1327         struct client_lease *loop = ip->client->active;
1328         struct client_lease *lp;
1329
1330         note("No DHCPOFFERS received.");
1331
1332         /* We may not have an active lease, but we may have some
1333            predefined leases that we can try. */
1334         if (!ip->client->active && ip->client->leases)
1335                 goto activate_next;
1336
1337         /* Run through the list of leases and see if one can be used. */
1338         while (ip->client->active) {
1339                 if (ip->client->active->expiry > cur_time) {
1340                         note("Trying recorded lease %s",
1341                             piaddr(ip->client->active->address));
1342                         /* Run the client script with the existing
1343                            parameters. */
1344                         script_init("TIMEOUT",
1345                             ip->client->active->medium);
1346                         script_write_params("new_", ip->client->active);
1347                         if (ip->client->alias)
1348                                 script_write_params("alias_",
1349                                     ip->client->alias);
1350
1351                         /* If the old lease is still good and doesn't
1352                            yet need renewal, go into BOUND state and
1353                            timeout at the renewal time. */
1354                         if (!script_go()) {
1355                                 if (cur_time <
1356                                     ip->client->active->renewal) {
1357                                         ip->client->state = S_BOUND;
1358                                         note("bound: renewal in %d seconds.",
1359                                             (int)(ip->client->active->renewal -
1360                                             cur_time));
1361                                         add_timeout(
1362                                             ip->client->active->renewal,
1363                                             state_bound, ip);
1364                                 } else {
1365                                         ip->client->state = S_BOUND;
1366                                         note("bound: immediate renewal.");
1367                                         state_bound(ip);
1368                                 }
1369                                 reinitialize_interfaces();
1370                                 go_daemon();
1371                                 return;
1372                         }
1373                 }
1374
1375                 /* If there are no other leases, give up. */
1376                 if (!ip->client->leases) {
1377                         ip->client->leases = ip->client->active;
1378                         ip->client->active = NULL;
1379                         break;
1380                 }
1381
1382 activate_next:
1383                 /* Otherwise, put the active lease at the end of the
1384                    lease list, and try another lease.. */
1385                 for (lp = ip->client->leases; lp->next; lp = lp->next)
1386                         ;
1387                 lp->next = ip->client->active;
1388                 if (lp->next)
1389                         lp->next->next = NULL;
1390                 ip->client->active = ip->client->leases;
1391                 ip->client->leases = ip->client->leases->next;
1392
1393                 /* If we already tried this lease, we've exhausted the
1394                    set of leases, so we might as well give up for
1395                    now. */
1396                 if (ip->client->active == loop)
1397                         break;
1398                 else if (!loop)
1399                         loop = ip->client->active;
1400         }
1401
1402         /* No leases were available, or what was available didn't work, so
1403            tell the shell script that we failed to allocate an address,
1404            and try again later. */
1405         note("No working leases in persistent database - sleeping.\n");
1406         script_init("FAIL", NULL);
1407         if (ip->client->alias)
1408                 script_write_params("alias_", ip->client->alias);
1409         script_go();
1410         ip->client->state = S_INIT;
1411         add_timeout(cur_time + ip->client->config->retry_interval, state_init,
1412             ip);
1413         go_daemon();
1414 }
1415
1416 void
1417 send_request(void *ipp)
1418 {
1419         struct interface_info *ip = ipp;
1420         struct in_addr from, to;
1421         int interval;
1422
1423         /* Figure out how long it's been since we started transmitting. */
1424         interval = cur_time - ip->client->first_sending;
1425
1426         /* If we're in the INIT-REBOOT or REQUESTING state and we're
1427            past the reboot timeout, go to INIT and see if we can
1428            DISCOVER an address... */
1429         /* XXX In the INIT-REBOOT state, if we don't get an ACK, it
1430            means either that we're on a network with no DHCP server,
1431            or that our server is down.  In the latter case, assuming
1432            that there is a backup DHCP server, DHCPDISCOVER will get
1433            us a new address, but we could also have successfully
1434            reused our old address.  In the former case, we're hosed
1435            anyway.  This is not a win-prone situation. */
1436         if ((ip->client->state == S_REBOOTING ||
1437             ip->client->state == S_REQUESTING) &&
1438             interval > ip->client->config->reboot_timeout) {
1439 cancel:
1440                 ip->client->state = S_INIT;
1441                 cancel_timeout(send_request, ip);
1442                 state_init(ip);
1443                 return;
1444         }
1445
1446         /* If we're in the reboot state, make sure the media is set up
1447            correctly. */
1448         if (ip->client->state == S_REBOOTING &&
1449             !ip->client->medium &&
1450             ip->client->active->medium ) {
1451                 script_init("MEDIUM", ip->client->active->medium);
1452
1453                 /* If the medium we chose won't fly, go to INIT state. */
1454                 if (script_go())
1455                         goto cancel;
1456
1457                 /* Record the medium. */
1458                 ip->client->medium = ip->client->active->medium;
1459         }
1460
1461         /* If the lease has expired, relinquish the address and go back
1462            to the INIT state. */
1463         if (ip->client->state != S_REQUESTING &&
1464             cur_time > ip->client->active->expiry) {
1465                 /* Run the client script with the new parameters. */
1466                 script_init("EXPIRE", NULL);
1467                 script_write_params("old_", ip->client->active);
1468                 if (ip->client->alias)
1469                         script_write_params("alias_", ip->client->alias);
1470                 script_go();
1471
1472                 /* Now do a preinit on the interface so that we can
1473                    discover a new address. */
1474                 script_init("PREINIT", NULL);
1475                 if (ip->client->alias)
1476                         script_write_params("alias_", ip->client->alias);
1477                 script_go();
1478
1479                 ip->client->state = S_INIT;
1480                 state_init(ip);
1481                 return;
1482         }
1483
1484         /* Do the exponential backoff... */
1485         if (!ip->client->interval)
1486                 ip->client->interval = ip->client->config->initial_interval;
1487         else
1488                 ip->client->interval += ((arc4random() >> 2) %
1489                     (2 * ip->client->interval));
1490
1491         /* Don't backoff past cutoff. */
1492         if (ip->client->interval >
1493             ip->client->config->backoff_cutoff)
1494                 ip->client->interval =
1495                     ((ip->client->config->backoff_cutoff / 2) +
1496                     ((arc4random() >> 2) % ip->client->interval));
1497
1498         /* If the backoff would take us to the expiry time, just set the
1499            timeout to the expiry time. */
1500         if (ip->client->state != S_REQUESTING &&
1501             cur_time + ip->client->interval >
1502             ip->client->active->expiry)
1503                 ip->client->interval =
1504                     ip->client->active->expiry - cur_time + 1;
1505
1506         /* If the lease T2 time has elapsed, or if we're not yet bound,
1507            broadcast the DHCPREQUEST rather than unicasting. */
1508         if (ip->client->state == S_REQUESTING ||
1509             ip->client->state == S_REBOOTING ||
1510             cur_time > ip->client->active->rebind)
1511                 to.s_addr = INADDR_BROADCAST;
1512         else
1513                 memcpy(&to.s_addr, ip->client->destination.iabuf,
1514                     sizeof(to.s_addr));
1515
1516         if (ip->client->state != S_REQUESTING)
1517                 memcpy(&from, ip->client->active->address.iabuf,
1518                     sizeof(from));
1519         else
1520                 from.s_addr = INADDR_ANY;
1521
1522         /* Record the number of seconds since we started sending. */
1523         if (ip->client->state == S_REQUESTING)
1524                 ip->client->packet.secs = ip->client->secs;
1525         else {
1526                 if (interval < 65536)
1527                         ip->client->packet.secs = htons(interval);
1528                 else
1529                         ip->client->packet.secs = htons(65535);
1530         }
1531
1532         note("DHCPREQUEST on %s to %s port %d", ip->name, inet_ntoa(to),
1533             REMOTE_PORT);
1534
1535         /* Send out a packet. */
1536         send_packet_unpriv(privfd, &ip->client->packet,
1537             ip->client->packet_length, from, to);
1538
1539         add_timeout(cur_time + ip->client->interval, send_request, ip);
1540 }
1541
1542 void
1543 send_decline(void *ipp)
1544 {
1545         struct interface_info *ip = ipp;
1546
1547         note("DHCPDECLINE on %s to %s port %d", ip->name,
1548             inet_ntoa(inaddr_broadcast), REMOTE_PORT);
1549
1550         /* Send out a packet. */
1551         send_packet_unpriv(privfd, &ip->client->packet,
1552             ip->client->packet_length, inaddr_any, inaddr_broadcast);
1553 }
1554
1555 void
1556 make_discover(struct interface_info *ip, struct client_lease *lease)
1557 {
1558         unsigned char discover = DHCPDISCOVER;
1559         struct tree_cache *options[256];
1560         struct tree_cache option_elements[256];
1561         int i;
1562
1563         memset(option_elements, 0, sizeof(option_elements));
1564         memset(options, 0, sizeof(options));
1565         memset(&ip->client->packet, 0, sizeof(ip->client->packet));
1566
1567         /* Set DHCP_MESSAGE_TYPE to DHCPDISCOVER */
1568         i = DHO_DHCP_MESSAGE_TYPE;
1569         options[i] = &option_elements[i];
1570         options[i]->value = &discover;
1571         options[i]->len = sizeof(discover);
1572         options[i]->buf_size = sizeof(discover);
1573         options[i]->timeout = 0xFFFFFFFF;
1574
1575         /* Request the options we want */
1576         i  = DHO_DHCP_PARAMETER_REQUEST_LIST;
1577         options[i] = &option_elements[i];
1578         options[i]->value = ip->client->config->requested_options;
1579         options[i]->len = ip->client->config->requested_option_count;
1580         options[i]->buf_size =
1581                 ip->client->config->requested_option_count;
1582         options[i]->timeout = 0xFFFFFFFF;
1583
1584         /* If we had an address, try to get it again. */
1585         if (lease) {
1586                 ip->client->requested_address = lease->address;
1587                 i = DHO_DHCP_REQUESTED_ADDRESS;
1588                 options[i] = &option_elements[i];
1589                 options[i]->value = lease->address.iabuf;
1590                 options[i]->len = lease->address.len;
1591                 options[i]->buf_size = lease->address.len;
1592                 options[i]->timeout = 0xFFFFFFFF;
1593         } else
1594                 ip->client->requested_address.len = 0;
1595
1596         /* Send any options requested in the config file. */
1597         for (i = 0; i < 256; i++)
1598                 if (!options[i] &&
1599                     ip->client->config->send_options[i].data) {
1600                         options[i] = &option_elements[i];
1601                         options[i]->value =
1602                             ip->client->config->send_options[i].data;
1603                         options[i]->len =
1604                             ip->client->config->send_options[i].len;
1605                         options[i]->buf_size =
1606                             ip->client->config->send_options[i].len;
1607                         options[i]->timeout = 0xFFFFFFFF;
1608                 }
1609
1610         /* send host name if not set via config file. */
1611         if (!options[DHO_HOST_NAME]) {
1612                 if (hostname[0] != '\0') {
1613                         size_t len;
1614                         char* posDot = strchr(hostname, '.');
1615                         if (posDot != NULL)
1616                                 len = posDot - hostname;
1617                         else
1618                                 len = strlen(hostname);
1619                         options[DHO_HOST_NAME] = &option_elements[DHO_HOST_NAME];
1620                         options[DHO_HOST_NAME]->value = hostname;
1621                         options[DHO_HOST_NAME]->len = len;
1622                         options[DHO_HOST_NAME]->buf_size = len;
1623                         options[DHO_HOST_NAME]->timeout = 0xFFFFFFFF;
1624                 }
1625         }
1626
1627         /* set unique client identifier */
1628         char client_ident[sizeof(ip->hw_address.haddr) + 1];
1629         if (!options[DHO_DHCP_CLIENT_IDENTIFIER]) {
1630                 int hwlen = (ip->hw_address.hlen < sizeof(client_ident)-1) ?
1631                                 ip->hw_address.hlen : sizeof(client_ident)-1;
1632                 client_ident[0] = ip->hw_address.htype;
1633                 memcpy(&client_ident[1], ip->hw_address.haddr, hwlen);
1634                 options[DHO_DHCP_CLIENT_IDENTIFIER] = &option_elements[DHO_DHCP_CLIENT_IDENTIFIER];
1635                 options[DHO_DHCP_CLIENT_IDENTIFIER]->value = client_ident;
1636                 options[DHO_DHCP_CLIENT_IDENTIFIER]->len = hwlen+1;
1637                 options[DHO_DHCP_CLIENT_IDENTIFIER]->buf_size = hwlen+1;
1638                 options[DHO_DHCP_CLIENT_IDENTIFIER]->timeout = 0xFFFFFFFF;
1639         }
1640
1641         /* Set up the option buffer... */
1642         ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
1643             options, 0, 0, 0, NULL, 0);
1644         if (ip->client->packet_length < BOOTP_MIN_LEN)
1645                 ip->client->packet_length = BOOTP_MIN_LEN;
1646
1647         ip->client->packet.op = BOOTREQUEST;
1648         ip->client->packet.htype = ip->hw_address.htype;
1649         ip->client->packet.hlen = ip->hw_address.hlen;
1650         ip->client->packet.hops = 0;
1651         ip->client->packet.xid = arc4random();
1652         ip->client->packet.secs = 0; /* filled in by send_discover. */
1653         ip->client->packet.flags = 0;
1654
1655         memset(&(ip->client->packet.ciaddr),
1656             0, sizeof(ip->client->packet.ciaddr));
1657         memset(&(ip->client->packet.yiaddr),
1658             0, sizeof(ip->client->packet.yiaddr));
1659         memset(&(ip->client->packet.siaddr),
1660             0, sizeof(ip->client->packet.siaddr));
1661         memset(&(ip->client->packet.giaddr),
1662             0, sizeof(ip->client->packet.giaddr));
1663         memcpy(ip->client->packet.chaddr,
1664             ip->hw_address.haddr, ip->hw_address.hlen);
1665 }
1666
1667
1668 void
1669 make_request(struct interface_info *ip, struct client_lease * lease)
1670 {
1671         unsigned char request = DHCPREQUEST;
1672         struct tree_cache *options[256];
1673         struct tree_cache option_elements[256];
1674         int i;
1675
1676         memset(options, 0, sizeof(options));
1677         memset(&ip->client->packet, 0, sizeof(ip->client->packet));
1678
1679         /* Set DHCP_MESSAGE_TYPE to DHCPREQUEST */
1680         i = DHO_DHCP_MESSAGE_TYPE;
1681         options[i] = &option_elements[i];
1682         options[i]->value = &request;
1683         options[i]->len = sizeof(request);
1684         options[i]->buf_size = sizeof(request);
1685         options[i]->timeout = 0xFFFFFFFF;
1686
1687         /* Request the options we want */
1688         i = DHO_DHCP_PARAMETER_REQUEST_LIST;
1689         options[i] = &option_elements[i];
1690         options[i]->value = ip->client->config->requested_options;
1691         options[i]->len = ip->client->config->requested_option_count;
1692         options[i]->buf_size =
1693                 ip->client->config->requested_option_count;
1694         options[i]->timeout = 0xFFFFFFFF;
1695
1696         /* If we are requesting an address that hasn't yet been assigned
1697            to us, use the DHCP Requested Address option. */
1698         if (ip->client->state == S_REQUESTING) {
1699                 /* Send back the server identifier... */
1700                 i = DHO_DHCP_SERVER_IDENTIFIER;
1701                 options[i] = &option_elements[i];
1702                 options[i]->value = lease->options[i].data;
1703                 options[i]->len = lease->options[i].len;
1704                 options[i]->buf_size = lease->options[i].len;
1705                 options[i]->timeout = 0xFFFFFFFF;
1706         }
1707         if (ip->client->state == S_REQUESTING ||
1708             ip->client->state == S_REBOOTING) {
1709                 ip->client->requested_address = lease->address;
1710                 i = DHO_DHCP_REQUESTED_ADDRESS;
1711                 options[i] = &option_elements[i];
1712                 options[i]->value = lease->address.iabuf;
1713                 options[i]->len = lease->address.len;
1714                 options[i]->buf_size = lease->address.len;
1715                 options[i]->timeout = 0xFFFFFFFF;
1716         } else
1717                 ip->client->requested_address.len = 0;
1718
1719         /* Send any options requested in the config file. */
1720         for (i = 0; i < 256; i++)
1721                 if (!options[i] &&
1722                     ip->client->config->send_options[i].data) {
1723                         options[i] = &option_elements[i];
1724                         options[i]->value =
1725                             ip->client->config->send_options[i].data;
1726                         options[i]->len =
1727                             ip->client->config->send_options[i].len;
1728                         options[i]->buf_size =
1729                             ip->client->config->send_options[i].len;
1730                         options[i]->timeout = 0xFFFFFFFF;
1731                 }
1732
1733         /* send host name if not set via config file. */
1734         if (!options[DHO_HOST_NAME]) {
1735                 if (hostname[0] != '\0') {
1736                         size_t len;
1737                         char* posDot = strchr(hostname, '.');
1738                         if (posDot != NULL)
1739                                 len = posDot - hostname;
1740                         else
1741                                 len = strlen(hostname);
1742                         options[DHO_HOST_NAME] = &option_elements[DHO_HOST_NAME];
1743                         options[DHO_HOST_NAME]->value = hostname;
1744                         options[DHO_HOST_NAME]->len = len;
1745                         options[DHO_HOST_NAME]->buf_size = len;
1746                         options[DHO_HOST_NAME]->timeout = 0xFFFFFFFF;
1747                 }
1748         }
1749
1750         /* set unique client identifier */
1751         char client_ident[sizeof(struct hardware)];
1752         if (!options[DHO_DHCP_CLIENT_IDENTIFIER]) {
1753                 int hwlen = (ip->hw_address.hlen < sizeof(client_ident)-1) ?
1754                                 ip->hw_address.hlen : sizeof(client_ident)-1;
1755                 client_ident[0] = ip->hw_address.htype;
1756                 memcpy(&client_ident[1], ip->hw_address.haddr, hwlen);
1757                 options[DHO_DHCP_CLIENT_IDENTIFIER] = &option_elements[DHO_DHCP_CLIENT_IDENTIFIER];
1758                 options[DHO_DHCP_CLIENT_IDENTIFIER]->value = client_ident;
1759                 options[DHO_DHCP_CLIENT_IDENTIFIER]->len = hwlen+1;
1760                 options[DHO_DHCP_CLIENT_IDENTIFIER]->buf_size = hwlen+1;
1761                 options[DHO_DHCP_CLIENT_IDENTIFIER]->timeout = 0xFFFFFFFF;
1762         }
1763
1764         /* Set up the option buffer... */
1765         ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
1766             options, 0, 0, 0, NULL, 0);
1767         if (ip->client->packet_length < BOOTP_MIN_LEN)
1768                 ip->client->packet_length = BOOTP_MIN_LEN;
1769
1770         ip->client->packet.op = BOOTREQUEST;
1771         ip->client->packet.htype = ip->hw_address.htype;
1772         ip->client->packet.hlen = ip->hw_address.hlen;
1773         ip->client->packet.hops = 0;
1774         ip->client->packet.xid = ip->client->xid;
1775         ip->client->packet.secs = 0; /* Filled in by send_request. */
1776
1777         /* If we own the address we're requesting, put it in ciaddr;
1778            otherwise set ciaddr to zero. */
1779         if (ip->client->state == S_BOUND ||
1780             ip->client->state == S_RENEWING ||
1781             ip->client->state == S_REBINDING) {
1782                 memcpy(&ip->client->packet.ciaddr,
1783                     lease->address.iabuf, lease->address.len);
1784                 ip->client->packet.flags = 0;
1785         } else {
1786                 memset(&ip->client->packet.ciaddr, 0,
1787                     sizeof(ip->client->packet.ciaddr));
1788                 ip->client->packet.flags = 0;
1789         }
1790
1791         memset(&ip->client->packet.yiaddr, 0,
1792             sizeof(ip->client->packet.yiaddr));
1793         memset(&ip->client->packet.siaddr, 0,
1794             sizeof(ip->client->packet.siaddr));
1795         memset(&ip->client->packet.giaddr, 0,
1796             sizeof(ip->client->packet.giaddr));
1797         memcpy(ip->client->packet.chaddr,
1798             ip->hw_address.haddr, ip->hw_address.hlen);
1799 }
1800
1801 void
1802 make_decline(struct interface_info *ip, struct client_lease *lease)
1803 {
1804         struct tree_cache *options[256], message_type_tree;
1805         struct tree_cache requested_address_tree;
1806         struct tree_cache server_id_tree, client_id_tree;
1807         unsigned char decline = DHCPDECLINE;
1808         int i;
1809
1810         memset(options, 0, sizeof(options));
1811         memset(&ip->client->packet, 0, sizeof(ip->client->packet));
1812
1813         /* Set DHCP_MESSAGE_TYPE to DHCPDECLINE */
1814         i = DHO_DHCP_MESSAGE_TYPE;
1815         options[i] = &message_type_tree;
1816         options[i]->value = &decline;
1817         options[i]->len = sizeof(decline);
1818         options[i]->buf_size = sizeof(decline);
1819         options[i]->timeout = 0xFFFFFFFF;
1820
1821         /* Send back the server identifier... */
1822         i = DHO_DHCP_SERVER_IDENTIFIER;
1823         options[i] = &server_id_tree;
1824         options[i]->value = lease->options[i].data;
1825         options[i]->len = lease->options[i].len;
1826         options[i]->buf_size = lease->options[i].len;
1827         options[i]->timeout = 0xFFFFFFFF;
1828
1829         /* Send back the address we're declining. */
1830         i = DHO_DHCP_REQUESTED_ADDRESS;
1831         options[i] = &requested_address_tree;
1832         options[i]->value = lease->address.iabuf;
1833         options[i]->len = lease->address.len;
1834         options[i]->buf_size = lease->address.len;
1835         options[i]->timeout = 0xFFFFFFFF;
1836
1837         /* Send the uid if the user supplied one. */
1838         i = DHO_DHCP_CLIENT_IDENTIFIER;
1839         if (ip->client->config->send_options[i].len) {
1840                 options[i] = &client_id_tree;
1841                 options[i]->value = ip->client->config->send_options[i].data;
1842                 options[i]->len = ip->client->config->send_options[i].len;
1843                 options[i]->buf_size = ip->client->config->send_options[i].len;
1844                 options[i]->timeout = 0xFFFFFFFF;
1845         }
1846
1847
1848         /* Set up the option buffer... */
1849         ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
1850             options, 0, 0, 0, NULL, 0);
1851         if (ip->client->packet_length < BOOTP_MIN_LEN)
1852                 ip->client->packet_length = BOOTP_MIN_LEN;
1853
1854         ip->client->packet.op = BOOTREQUEST;
1855         ip->client->packet.htype = ip->hw_address.htype;
1856         ip->client->packet.hlen = ip->hw_address.hlen;
1857         ip->client->packet.hops = 0;
1858         ip->client->packet.xid = ip->client->xid;
1859         ip->client->packet.secs = 0; /* Filled in by send_request. */
1860         ip->client->packet.flags = 0;
1861
1862         /* ciaddr must always be zero. */
1863         memset(&ip->client->packet.ciaddr, 0,
1864             sizeof(ip->client->packet.ciaddr));
1865         memset(&ip->client->packet.yiaddr, 0,
1866             sizeof(ip->client->packet.yiaddr));
1867         memset(&ip->client->packet.siaddr, 0,
1868             sizeof(ip->client->packet.siaddr));
1869         memset(&ip->client->packet.giaddr, 0,
1870             sizeof(ip->client->packet.giaddr));
1871         memcpy(ip->client->packet.chaddr,
1872             ip->hw_address.haddr, ip->hw_address.hlen);
1873 }
1874
1875 void
1876 free_client_lease(struct client_lease *lease)
1877 {
1878         int i;
1879
1880         if (lease->server_name)
1881                 free(lease->server_name);
1882         if (lease->filename)
1883                 free(lease->filename);
1884         for (i = 0; i < 256; i++) {
1885                 if (lease->options[i].len)
1886                         free(lease->options[i].data);
1887         }
1888         free(lease);
1889 }
1890
1891 FILE *leaseFile;
1892
1893 void
1894 rewrite_client_leases(void)
1895 {
1896         struct client_lease *lp;
1897         cap_rights_t rights;
1898
1899         if (!leaseFile) {
1900                 leaseFile = fopen(path_dhclient_db, "w");
1901                 if (!leaseFile)
1902                         error("can't create %s: %m", path_dhclient_db);
1903                 cap_rights_init(&rights, CAP_FCNTL, CAP_FSTAT, CAP_FSYNC,
1904                     CAP_FTRUNCATE, CAP_SEEK, CAP_WRITE);
1905                 if (cap_rights_limit(fileno(leaseFile), &rights) < 0 &&
1906                     errno != ENOSYS) {
1907                         error("can't limit lease descriptor: %m");
1908                 }
1909                 if (cap_fcntls_limit(fileno(leaseFile), CAP_FCNTL_GETFL) < 0 &&
1910                     errno != ENOSYS) {
1911                         error("can't limit lease descriptor fcntls: %m");
1912                 }
1913         } else {
1914                 fflush(leaseFile);
1915                 rewind(leaseFile);
1916         }
1917
1918         for (lp = ifi->client->leases; lp; lp = lp->next)
1919                 write_client_lease(ifi, lp, 1);
1920         if (ifi->client->active)
1921                 write_client_lease(ifi, ifi->client->active, 1);
1922
1923         fflush(leaseFile);
1924         ftruncate(fileno(leaseFile), ftello(leaseFile));
1925         fsync(fileno(leaseFile));
1926 }
1927
1928 void
1929 write_client_lease(struct interface_info *ip, struct client_lease *lease,
1930     int rewrite)
1931 {
1932         static int leases_written;
1933         struct tm *t;
1934         int i;
1935
1936         if (!rewrite) {
1937                 if (leases_written++ > 20) {
1938                         rewrite_client_leases();
1939                         leases_written = 0;
1940                 }
1941         }
1942
1943         /* If the lease came from the config file, we don't need to stash
1944            a copy in the lease database. */
1945         if (lease->is_static)
1946                 return;
1947
1948         if (!leaseFile) {       /* XXX */
1949                 leaseFile = fopen(path_dhclient_db, "w");
1950                 if (!leaseFile)
1951                         error("can't create %s: %m", path_dhclient_db);
1952         }
1953
1954         fprintf(leaseFile, "lease {\n");
1955         if (lease->is_bootp)
1956                 fprintf(leaseFile, "  bootp;\n");
1957         fprintf(leaseFile, "  interface \"%s\";\n", ip->name);
1958         fprintf(leaseFile, "  fixed-address %s;\n", piaddr(lease->address));
1959         if (lease->nextserver.len == sizeof(inaddr_any) &&
1960             0 != memcmp(lease->nextserver.iabuf, &inaddr_any,
1961             sizeof(inaddr_any)))
1962                 fprintf(leaseFile, "  next-server %s;\n",
1963                     piaddr(lease->nextserver));
1964         if (lease->filename)
1965                 fprintf(leaseFile, "  filename \"%s\";\n", lease->filename);
1966         if (lease->server_name)
1967                 fprintf(leaseFile, "  server-name \"%s\";\n",
1968                     lease->server_name);
1969         if (lease->medium)
1970                 fprintf(leaseFile, "  medium \"%s\";\n", lease->medium->string);
1971         for (i = 0; i < 256; i++)
1972                 if (lease->options[i].len)
1973                         fprintf(leaseFile, "  option %s %s;\n",
1974                             dhcp_options[i].name,
1975                             pretty_print_option(i, lease->options[i].data,
1976                             lease->options[i].len, 1, 1));
1977
1978         t = gmtime(&lease->renewal);
1979         fprintf(leaseFile, "  renew %d %d/%d/%d %02d:%02d:%02d;\n",
1980             t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
1981             t->tm_hour, t->tm_min, t->tm_sec);
1982         t = gmtime(&lease->rebind);
1983         fprintf(leaseFile, "  rebind %d %d/%d/%d %02d:%02d:%02d;\n",
1984             t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
1985             t->tm_hour, t->tm_min, t->tm_sec);
1986         t = gmtime(&lease->expiry);
1987         fprintf(leaseFile, "  expire %d %d/%d/%d %02d:%02d:%02d;\n",
1988             t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
1989             t->tm_hour, t->tm_min, t->tm_sec);
1990         fprintf(leaseFile, "}\n");
1991         fflush(leaseFile);
1992 }
1993
1994 void
1995 script_init(const char *reason, struct string_list *medium)
1996 {
1997         size_t           len, mediumlen = 0;
1998         struct imsg_hdr  hdr;
1999         struct buf      *buf;
2000         int              errs;
2001
2002         if (medium != NULL && medium->string != NULL)
2003                 mediumlen = strlen(medium->string);
2004
2005         hdr.code = IMSG_SCRIPT_INIT;
2006         hdr.len = sizeof(struct imsg_hdr) +
2007             sizeof(size_t) + mediumlen +
2008             sizeof(size_t) + strlen(reason);
2009
2010         if ((buf = buf_open(hdr.len)) == NULL)
2011                 error("buf_open: %m");
2012
2013         errs = 0;
2014         errs += buf_add(buf, &hdr, sizeof(hdr));
2015         errs += buf_add(buf, &mediumlen, sizeof(mediumlen));
2016         if (mediumlen > 0)
2017                 errs += buf_add(buf, medium->string, mediumlen);
2018         len = strlen(reason);
2019         errs += buf_add(buf, &len, sizeof(len));
2020         errs += buf_add(buf, reason, len);
2021
2022         if (errs)
2023                 error("buf_add: %m");
2024
2025         if (buf_close(privfd, buf) == -1)
2026                 error("buf_close: %m");
2027 }
2028
2029 void
2030 priv_script_init(const char *reason, char *medium)
2031 {
2032         struct interface_info *ip = ifi;
2033
2034         if (ip) {
2035                 ip->client->scriptEnvsize = 100;
2036                 if (ip->client->scriptEnv == NULL)
2037                         ip->client->scriptEnv =
2038                             malloc(ip->client->scriptEnvsize * sizeof(char *));
2039                 if (ip->client->scriptEnv == NULL)
2040                         error("script_init: no memory for environment");
2041
2042                 ip->client->scriptEnv[0] = strdup(CLIENT_PATH);
2043                 if (ip->client->scriptEnv[0] == NULL)
2044                         error("script_init: no memory for environment");
2045
2046                 ip->client->scriptEnv[1] = NULL;
2047
2048                 script_set_env(ip->client, "", "interface", ip->name);
2049
2050                 if (medium)
2051                         script_set_env(ip->client, "", "medium", medium);
2052
2053                 script_set_env(ip->client, "", "reason", reason);
2054         }
2055 }
2056
2057 void
2058 priv_script_write_params(const char *prefix, struct client_lease *lease)
2059 {
2060         struct interface_info *ip = ifi;
2061         u_int8_t dbuf[1500], *dp = NULL;
2062         int i;
2063         size_t len;
2064         char tbuf[128];
2065
2066         script_set_env(ip->client, prefix, "ip_address",
2067             piaddr(lease->address));
2068
2069         if (ip->client->config->default_actions[DHO_SUBNET_MASK] ==
2070             ACTION_SUPERSEDE) {
2071                 dp = ip->client->config->defaults[DHO_SUBNET_MASK].data;
2072                 len = ip->client->config->defaults[DHO_SUBNET_MASK].len;
2073         } else {
2074                 dp = lease->options[DHO_SUBNET_MASK].data;
2075                 len = lease->options[DHO_SUBNET_MASK].len;
2076         }
2077         if (len && (len < sizeof(lease->address.iabuf))) {
2078                 struct iaddr netmask, subnet, broadcast;
2079
2080                 memcpy(netmask.iabuf, dp, len);
2081                 netmask.len = len;
2082                 subnet = subnet_number(lease->address, netmask);
2083                 if (subnet.len) {
2084                         script_set_env(ip->client, prefix, "network_number",
2085                             piaddr(subnet));
2086                         if (!lease->options[DHO_BROADCAST_ADDRESS].len) {
2087                                 broadcast = broadcast_addr(subnet, netmask);
2088                                 if (broadcast.len)
2089                                         script_set_env(ip->client, prefix,
2090                                             "broadcast_address",
2091                                             piaddr(broadcast));
2092                         }
2093                 }
2094         }
2095
2096         if (lease->filename)
2097                 script_set_env(ip->client, prefix, "filename", lease->filename);
2098         if (lease->server_name)
2099                 script_set_env(ip->client, prefix, "server_name",
2100                     lease->server_name);
2101         for (i = 0; i < 256; i++) {
2102                 len = 0;
2103
2104                 if (ip->client->config->defaults[i].len) {
2105                         if (lease->options[i].len) {
2106                                 switch (
2107                                     ip->client->config->default_actions[i]) {
2108                                 case ACTION_DEFAULT:
2109                                         dp = lease->options[i].data;
2110                                         len = lease->options[i].len;
2111                                         break;
2112                                 case ACTION_SUPERSEDE:
2113 supersede:
2114                                         dp = ip->client->
2115                                                 config->defaults[i].data;
2116                                         len = ip->client->
2117                                                 config->defaults[i].len;
2118                                         break;
2119                                 case ACTION_PREPEND:
2120                                         len = ip->client->
2121                                             config->defaults[i].len +
2122                                             lease->options[i].len;
2123                                         if (len >= sizeof(dbuf)) {
2124                                                 warning("no space to %s %s",
2125                                                     "prepend option",
2126                                                     dhcp_options[i].name);
2127                                                 goto supersede;
2128                                         }
2129                                         dp = dbuf;
2130                                         memcpy(dp,
2131                                                 ip->client->
2132                                                 config->defaults[i].data,
2133                                                 ip->client->
2134                                                 config->defaults[i].len);
2135                                         memcpy(dp + ip->client->
2136                                                 config->defaults[i].len,
2137                                                 lease->options[i].data,
2138                                                 lease->options[i].len);
2139                                         dp[len] = '\0';
2140                                         break;
2141                                 case ACTION_APPEND:
2142                                         /*
2143                                          * When we append, we assume that we're
2144                                          * appending to text.  Some MS servers
2145                                          * include a NUL byte at the end of
2146                                          * the search string provided.
2147                                          */
2148                                         len = ip->client->
2149                                             config->defaults[i].len +
2150                                             lease->options[i].len;
2151                                         if (len >= sizeof(dbuf)) {
2152                                                 warning("no space to %s %s",
2153                                                     "append option",
2154                                                     dhcp_options[i].name);
2155                                                 goto supersede;
2156                                         }
2157                                         memcpy(dbuf,
2158                                                 lease->options[i].data,
2159                                                 lease->options[i].len);
2160                                         for (dp = dbuf + lease->options[i].len;
2161                                             dp > dbuf; dp--, len--)
2162                                                 if (dp[-1] != '\0')
2163                                                         break;
2164                                         memcpy(dp,
2165                                                 ip->client->
2166                                                 config->defaults[i].data,
2167                                                 ip->client->
2168                                                 config->defaults[i].len);
2169                                         dp = dbuf;
2170                                         dp[len] = '\0';
2171                                 }
2172                         } else {
2173                                 dp = ip->client->
2174                                         config->defaults[i].data;
2175                                 len = ip->client->
2176                                         config->defaults[i].len;
2177                         }
2178                 } else if (lease->options[i].len) {
2179                         len = lease->options[i].len;
2180                         dp = lease->options[i].data;
2181                 } else {
2182                         len = 0;
2183                 }
2184                 if (len) {
2185                         char name[256];
2186
2187                         if (dhcp_option_ev_name(name, sizeof(name),
2188                             &dhcp_options[i]))
2189                                 script_set_env(ip->client, prefix, name,
2190                                     pretty_print_option(i, dp, len, 0, 0));
2191                 }
2192         }
2193         snprintf(tbuf, sizeof(tbuf), "%d", (int)lease->expiry);
2194         script_set_env(ip->client, prefix, "expiry", tbuf);
2195 }
2196
2197 void
2198 script_write_params(const char *prefix, struct client_lease *lease)
2199 {
2200         size_t           fn_len = 0, sn_len = 0, pr_len = 0;
2201         struct imsg_hdr  hdr;
2202         struct buf      *buf;
2203         int              errs, i;
2204
2205         if (lease->filename != NULL)
2206                 fn_len = strlen(lease->filename);
2207         if (lease->server_name != NULL)
2208                 sn_len = strlen(lease->server_name);
2209         if (prefix != NULL)
2210                 pr_len = strlen(prefix);
2211
2212         hdr.code = IMSG_SCRIPT_WRITE_PARAMS;
2213         hdr.len = sizeof(hdr) + sizeof(*lease) +
2214             sizeof(fn_len) + fn_len + sizeof(sn_len) + sn_len +
2215             sizeof(pr_len) + pr_len;
2216
2217         for (i = 0; i < 256; i++) {
2218                 hdr.len += sizeof(lease->options[i].len);
2219                 hdr.len += lease->options[i].len;
2220         }
2221
2222         scripttime = time(NULL);
2223
2224         if ((buf = buf_open(hdr.len)) == NULL)
2225                 error("buf_open: %m");
2226
2227         errs = 0;
2228         errs += buf_add(buf, &hdr, sizeof(hdr));
2229         errs += buf_add(buf, lease, sizeof(*lease));
2230         errs += buf_add(buf, &fn_len, sizeof(fn_len));
2231         errs += buf_add(buf, lease->filename, fn_len);
2232         errs += buf_add(buf, &sn_len, sizeof(sn_len));
2233         errs += buf_add(buf, lease->server_name, sn_len);
2234         errs += buf_add(buf, &pr_len, sizeof(pr_len));
2235         errs += buf_add(buf, prefix, pr_len);
2236
2237         for (i = 0; i < 256; i++) {
2238                 errs += buf_add(buf, &lease->options[i].len,
2239                     sizeof(lease->options[i].len));
2240                 errs += buf_add(buf, lease->options[i].data,
2241                     lease->options[i].len);
2242         }
2243
2244         if (errs)
2245                 error("buf_add: %m");
2246
2247         if (buf_close(privfd, buf) == -1)
2248                 error("buf_close: %m");
2249 }
2250
2251 int
2252 script_go(void)
2253 {
2254         struct imsg_hdr  hdr;
2255         struct buf      *buf;
2256         int              ret;
2257
2258         hdr.code = IMSG_SCRIPT_GO;
2259         hdr.len = sizeof(struct imsg_hdr);
2260
2261         if ((buf = buf_open(hdr.len)) == NULL)
2262                 error("buf_open: %m");
2263
2264         if (buf_add(buf, &hdr, sizeof(hdr)))
2265                 error("buf_add: %m");
2266
2267         if (buf_close(privfd, buf) == -1)
2268                 error("buf_close: %m");
2269
2270         bzero(&hdr, sizeof(hdr));
2271         buf_read(privfd, &hdr, sizeof(hdr));
2272         if (hdr.code != IMSG_SCRIPT_GO_RET)
2273                 error("unexpected msg type %u", hdr.code);
2274         if (hdr.len != sizeof(hdr) + sizeof(int))
2275                 error("received corrupted message");
2276         buf_read(privfd, &ret, sizeof(ret));
2277
2278         scripttime = time(NULL);
2279
2280         return (ret);
2281 }
2282
2283 int
2284 priv_script_go(void)
2285 {
2286         char *scriptName, *argv[2], **envp, *epp[3], reason[] = "REASON=NBI";
2287         static char client_path[] = CLIENT_PATH;
2288         struct interface_info *ip = ifi;
2289         int pid, wpid, wstatus;
2290
2291         scripttime = time(NULL);
2292
2293         if (ip) {
2294                 scriptName = ip->client->config->script_name;
2295                 envp = ip->client->scriptEnv;
2296         } else {
2297                 scriptName = top_level_config.script_name;
2298                 epp[0] = reason;
2299                 epp[1] = client_path;
2300                 epp[2] = NULL;
2301                 envp = epp;
2302         }
2303
2304         argv[0] = scriptName;
2305         argv[1] = NULL;
2306
2307         pid = fork();
2308         if (pid < 0) {
2309                 error("fork: %m");
2310                 wstatus = 0;
2311         } else if (pid) {
2312                 do {
2313                         wpid = wait(&wstatus);
2314                 } while (wpid != pid && wpid > 0);
2315                 if (wpid < 0) {
2316                         error("wait: %m");
2317                         wstatus = 0;
2318                 }
2319         } else {
2320                 execve(scriptName, argv, envp);
2321                 error("execve (%s, ...): %m", scriptName);
2322         }
2323
2324         if (ip)
2325                 script_flush_env(ip->client);
2326
2327         return (wstatus & 0xff);
2328 }
2329
2330 void
2331 script_set_env(struct client_state *client, const char *prefix,
2332     const char *name, const char *value)
2333 {
2334         int i, namelen;
2335         size_t j;
2336
2337         /* No `` or $() command substitution allowed in environment values! */
2338         for (j=0; j < strlen(value); j++)
2339                 switch (value[j]) {
2340                 case '`':
2341                 case '$':
2342                         warning("illegal character (%c) in value '%s'",
2343                             value[j], value);
2344                         /* Ignore this option */
2345                         return;
2346                 }
2347
2348         namelen = strlen(name);
2349
2350         for (i = 0; client->scriptEnv[i]; i++)
2351                 if (strncmp(client->scriptEnv[i], name, namelen) == 0 &&
2352                     client->scriptEnv[i][namelen] == '=')
2353                         break;
2354
2355         if (client->scriptEnv[i])
2356                 /* Reuse the slot. */
2357                 free(client->scriptEnv[i]);
2358         else {
2359                 /* New variable.  Expand if necessary. */
2360                 if (i >= client->scriptEnvsize - 1) {
2361                         char **newscriptEnv;
2362                         int newscriptEnvsize = client->scriptEnvsize + 50;
2363
2364                         newscriptEnv = realloc(client->scriptEnv,
2365                             newscriptEnvsize);
2366                         if (newscriptEnv == NULL) {
2367                                 free(client->scriptEnv);
2368                                 client->scriptEnv = NULL;
2369                                 client->scriptEnvsize = 0;
2370                                 error("script_set_env: no memory for variable");
2371                         }
2372                         client->scriptEnv = newscriptEnv;
2373                         client->scriptEnvsize = newscriptEnvsize;
2374                 }
2375                 /* need to set the NULL pointer at end of array beyond
2376                    the new slot. */
2377                 client->scriptEnv[i + 1] = NULL;
2378         }
2379         /* Allocate space and format the variable in the appropriate slot. */
2380         client->scriptEnv[i] = malloc(strlen(prefix) + strlen(name) + 1 +
2381             strlen(value) + 1);
2382         if (client->scriptEnv[i] == NULL)
2383                 error("script_set_env: no memory for variable assignment");
2384         snprintf(client->scriptEnv[i], strlen(prefix) + strlen(name) +
2385             1 + strlen(value) + 1, "%s%s=%s", prefix, name, value);
2386 }
2387
2388 void
2389 script_flush_env(struct client_state *client)
2390 {
2391         int i;
2392
2393         for (i = 0; client->scriptEnv[i]; i++) {
2394                 free(client->scriptEnv[i]);
2395                 client->scriptEnv[i] = NULL;
2396         }
2397         client->scriptEnvsize = 0;
2398 }
2399
2400 int
2401 dhcp_option_ev_name(char *buf, size_t buflen, struct option *option)
2402 {
2403         size_t i;
2404
2405         for (i = 0; option->name[i]; i++) {
2406                 if (i + 1 == buflen)
2407                         return 0;
2408                 if (option->name[i] == '-')
2409                         buf[i] = '_';
2410                 else
2411                         buf[i] = option->name[i];
2412         }
2413
2414         buf[i] = 0;
2415         return 1;
2416 }
2417
2418 void
2419 go_daemon(void)
2420 {
2421         static int state = 0;
2422         cap_rights_t rights;
2423
2424         if (no_daemon || state)
2425                 return;
2426
2427         state = 1;
2428
2429         /* Stop logging to stderr... */
2430         log_perror = 0;
2431
2432         if (daemonfd(-1, nullfd) == -1)
2433                 error("daemon");
2434
2435         cap_rights_init(&rights);
2436
2437         if (pidfile != NULL) {
2438                 pidfile_write(pidfile);
2439                 if (cap_rights_limit(pidfile_fileno(pidfile), &rights) < 0 &&
2440                     errno != ENOSYS) {
2441                         error("can't limit pidfile descriptor: %m");
2442                 }
2443         }
2444
2445         if (nullfd != -1) {
2446                 close(nullfd);
2447                 nullfd = -1;
2448         }
2449
2450         if (cap_rights_limit(STDIN_FILENO, &rights) < 0 && errno != ENOSYS)
2451                 error("can't limit stdin: %m");
2452         cap_rights_init(&rights, CAP_WRITE);
2453         if (cap_rights_limit(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS)
2454                 error("can't limit stdout: %m");
2455         if (cap_rights_limit(STDERR_FILENO, &rights) < 0 && errno != ENOSYS)
2456                 error("can't limit stderr: %m");
2457 }
2458
2459 int
2460 check_option(struct client_lease *l, int option)
2461 {
2462         const char *opbuf;
2463         const char *sbuf;
2464
2465         /* we use this, since this is what gets passed to dhclient-script */
2466
2467         opbuf = pretty_print_option(option, l->options[option].data,
2468             l->options[option].len, 0, 0);
2469
2470         sbuf = option_as_string(option, l->options[option].data,
2471             l->options[option].len);
2472
2473         switch (option) {
2474         case DHO_SUBNET_MASK:
2475         case DHO_TIME_SERVERS:
2476         case DHO_NAME_SERVERS:
2477         case DHO_ROUTERS:
2478         case DHO_DOMAIN_NAME_SERVERS:
2479         case DHO_LOG_SERVERS:
2480         case DHO_COOKIE_SERVERS:
2481         case DHO_LPR_SERVERS:
2482         case DHO_IMPRESS_SERVERS:
2483         case DHO_RESOURCE_LOCATION_SERVERS:
2484         case DHO_SWAP_SERVER:
2485         case DHO_BROADCAST_ADDRESS:
2486         case DHO_NIS_SERVERS:
2487         case DHO_NTP_SERVERS:
2488         case DHO_NETBIOS_NAME_SERVERS:
2489         case DHO_NETBIOS_DD_SERVER:
2490         case DHO_FONT_SERVERS:
2491         case DHO_DHCP_SERVER_IDENTIFIER:
2492         case DHO_NISPLUS_SERVERS:
2493         case DHO_MOBILE_IP_HOME_AGENT:
2494         case DHO_SMTP_SERVER:
2495         case DHO_POP_SERVER:
2496         case DHO_NNTP_SERVER:
2497         case DHO_WWW_SERVER:
2498         case DHO_FINGER_SERVER:
2499         case DHO_IRC_SERVER:
2500         case DHO_STREETTALK_SERVER:
2501         case DHO_STREETTALK_DA_SERVER:
2502                 if (!ipv4addrs(opbuf)) {
2503                         warning("Invalid IP address in option: %s", opbuf);
2504                         return (0);
2505                 }
2506                 return (1)  ;
2507         case DHO_HOST_NAME:
2508         case DHO_NIS_DOMAIN:
2509         case DHO_NISPLUS_DOMAIN:
2510         case DHO_TFTP_SERVER_NAME:
2511                 if (!res_hnok(sbuf)) {
2512                         warning("Bogus Host Name option %d: %s (%s)", option,
2513                             sbuf, opbuf);
2514                         l->options[option].len = 0;
2515                         free(l->options[option].data);
2516                 }
2517                 return (1);
2518         case DHO_DOMAIN_NAME:
2519         case DHO_DOMAIN_SEARCH:
2520                 if (!res_hnok(sbuf)) {
2521                         if (!check_search(sbuf)) {
2522                                 warning("Bogus domain search list %d: %s (%s)",
2523                                     option, sbuf, opbuf);
2524                                 l->options[option].len = 0;
2525                                 free(l->options[option].data);
2526                         }
2527                 }
2528                 return (1);
2529         case DHO_PAD:
2530         case DHO_TIME_OFFSET:
2531         case DHO_BOOT_SIZE:
2532         case DHO_MERIT_DUMP:
2533         case DHO_ROOT_PATH:
2534         case DHO_EXTENSIONS_PATH:
2535         case DHO_IP_FORWARDING:
2536         case DHO_NON_LOCAL_SOURCE_ROUTING:
2537         case DHO_POLICY_FILTER:
2538         case DHO_MAX_DGRAM_REASSEMBLY:
2539         case DHO_DEFAULT_IP_TTL:
2540         case DHO_PATH_MTU_AGING_TIMEOUT:
2541         case DHO_PATH_MTU_PLATEAU_TABLE:
2542         case DHO_INTERFACE_MTU:
2543         case DHO_ALL_SUBNETS_LOCAL:
2544         case DHO_PERFORM_MASK_DISCOVERY:
2545         case DHO_MASK_SUPPLIER:
2546         case DHO_ROUTER_DISCOVERY:
2547         case DHO_ROUTER_SOLICITATION_ADDRESS:
2548         case DHO_STATIC_ROUTES:
2549         case DHO_TRAILER_ENCAPSULATION:
2550         case DHO_ARP_CACHE_TIMEOUT:
2551         case DHO_IEEE802_3_ENCAPSULATION:
2552         case DHO_DEFAULT_TCP_TTL:
2553         case DHO_TCP_KEEPALIVE_INTERVAL:
2554         case DHO_TCP_KEEPALIVE_GARBAGE:
2555         case DHO_VENDOR_ENCAPSULATED_OPTIONS:
2556         case DHO_NETBIOS_NODE_TYPE:
2557         case DHO_NETBIOS_SCOPE:
2558         case DHO_X_DISPLAY_MANAGER:
2559         case DHO_DHCP_REQUESTED_ADDRESS:
2560         case DHO_DHCP_LEASE_TIME:
2561         case DHO_DHCP_OPTION_OVERLOAD:
2562         case DHO_DHCP_MESSAGE_TYPE:
2563         case DHO_DHCP_PARAMETER_REQUEST_LIST:
2564         case DHO_DHCP_MESSAGE:
2565         case DHO_DHCP_MAX_MESSAGE_SIZE:
2566         case DHO_DHCP_RENEWAL_TIME:
2567         case DHO_DHCP_REBINDING_TIME:
2568         case DHO_DHCP_CLASS_IDENTIFIER:
2569         case DHO_DHCP_CLIENT_IDENTIFIER:
2570         case DHO_BOOTFILE_NAME:
2571         case DHO_DHCP_USER_CLASS_ID:
2572         case DHO_END:
2573                 return (1);
2574         case DHO_CLASSLESS_ROUTES:
2575                 return (check_classless_option(l->options[option].data,
2576                     l->options[option].len));
2577         default:
2578                 warning("unknown dhcp option value 0x%x", option);
2579                 return (unknown_ok);
2580         }
2581 }
2582
2583 /* RFC 3442 The Classless Static Routes option checks */
2584 int
2585 check_classless_option(unsigned char *data, int len)
2586 {
2587         int i = 0;
2588         unsigned char width;
2589         in_addr_t addr, mask;
2590
2591         if (len < 5) {
2592                 warning("Too small length: %d", len);
2593                 return (0);
2594         }
2595         while(i < len) {
2596                 width = data[i++];
2597                 if (width == 0) {
2598                         i += 4;
2599                         continue;
2600                 } else if (width < 9) {
2601                         addr =  (in_addr_t)(data[i]     << 24);
2602                         i += 1;
2603                 } else if (width < 17) {
2604                         addr =  (in_addr_t)(data[i]     << 24) +
2605                                 (in_addr_t)(data[i + 1] << 16);
2606                         i += 2;
2607                 } else if (width < 25) {
2608                         addr =  (in_addr_t)(data[i]     << 24) +
2609                                 (in_addr_t)(data[i + 1] << 16) +
2610                                 (in_addr_t)(data[i + 2] << 8);
2611                         i += 3;
2612                 } else if (width < 33) {
2613                         addr =  (in_addr_t)(data[i]     << 24) +
2614                                 (in_addr_t)(data[i + 1] << 16) +
2615                                 (in_addr_t)(data[i + 2] << 8)  +
2616                                 data[i + 3];
2617                         i += 4;
2618                 } else {
2619                         warning("Incorrect subnet width: %d", width);
2620                         return (0);
2621                 }
2622                 mask = (in_addr_t)(~0) << (32 - width);
2623                 addr = ntohl(addr);
2624                 mask = ntohl(mask);
2625
2626                 /*
2627                  * From RFC 3442:
2628                  * ... After deriving a subnet number and subnet mask
2629                  * from each destination descriptor, the DHCP client
2630                  * MUST zero any bits in the subnet number where the
2631                  * corresponding bit in the mask is zero...
2632                  */
2633                 if ((addr & mask) != addr) {
2634                         addr &= mask;
2635                         data[i - 1] = (unsigned char)(
2636                                 (addr >> (((32 - width)/8)*8)) & 0xFF);
2637                 }
2638                 i += 4;
2639         }
2640         if (i > len) {
2641                 warning("Incorrect data length: %d (must be %d)", len, i);
2642                 return (0);
2643         }
2644         return (1);
2645 }
2646
2647 int
2648 res_hnok(const char *dn)
2649 {
2650         int pch = PERIOD, ch = *dn++;
2651
2652         while (ch != '\0') {
2653                 int nch = *dn++;
2654
2655                 if (periodchar(ch)) {
2656                         ;
2657                 } else if (periodchar(pch)) {
2658                         if (!borderchar(ch))
2659                                 return (0);
2660                 } else if (periodchar(nch) || nch == '\0') {
2661                         if (!borderchar(ch))
2662                                 return (0);
2663                 } else {
2664                         if (!middlechar(ch))
2665                                 return (0);
2666                 }
2667                 pch = ch, ch = nch;
2668         }
2669         return (1);
2670 }
2671
2672 int
2673 check_search(const char *srch)
2674 {
2675         int pch = PERIOD, ch = *srch++;
2676         int domains = 1;
2677
2678         /* 256 char limit re resolv.conf(5) */
2679         if (strlen(srch) > 256)
2680                 return (0);
2681
2682         while (whitechar(ch))
2683                 ch = *srch++;
2684
2685         while (ch != '\0') {
2686                 int nch = *srch++;
2687
2688                 if (periodchar(ch) || whitechar(ch)) {
2689                         ;
2690                 } else if (periodchar(pch)) {
2691                         if (!borderchar(ch))
2692                                 return (0);
2693                 } else if (periodchar(nch) || nch == '\0') {
2694                         if (!borderchar(ch))
2695                                 return (0);
2696                 } else {
2697                         if (!middlechar(ch))
2698                                 return (0);
2699                 }
2700                 if (!whitechar(ch)) {
2701                         pch = ch;
2702                 } else {
2703                         while (whitechar(nch)) {
2704                                 nch = *srch++;
2705                         }
2706                         if (nch != '\0')
2707                                 domains++;
2708                         pch = PERIOD;
2709                 }
2710                 ch = nch;
2711         }
2712         /* 6 domain limit re resolv.conf(5) */
2713         if (domains > 6)
2714                 return (0);
2715         return (1);
2716 }
2717
2718 /* Does buf consist only of dotted decimal ipv4 addrs?
2719  * return how many if so,
2720  * otherwise, return 0
2721  */
2722 int
2723 ipv4addrs(const char * buf)
2724 {
2725         struct in_addr jnk;
2726         int count = 0;
2727
2728         while (inet_aton(buf, &jnk) == 1){
2729                 count++;
2730                 while (periodchar(*buf) || digitchar(*buf))
2731                         buf++;
2732                 if (*buf == '\0')
2733                         return (count);
2734                 while (*buf ==  ' ')
2735                         buf++;
2736         }
2737         return (0);
2738 }
2739
2740
2741 const char *
2742 option_as_string(unsigned int code, unsigned char *data, int len)
2743 {
2744         static char optbuf[32768]; /* XXX */
2745         char *op = optbuf;
2746         int opleft = sizeof(optbuf);
2747         unsigned char *dp = data;
2748
2749         if (code > 255)
2750                 error("option_as_string: bad code %d", code);
2751
2752         for (; dp < data + len; dp++) {
2753                 if (!isascii(*dp) || !isprint(*dp)) {
2754                         if (dp + 1 != data + len || *dp != 0) {
2755                                 snprintf(op, opleft, "\\%03o", *dp);
2756                                 op += 4;
2757                                 opleft -= 4;
2758                         }
2759                 } else if (*dp == '"' || *dp == '\'' || *dp == '$' ||
2760                     *dp == '`' || *dp == '\\') {
2761                         *op++ = '\\';
2762                         *op++ = *dp;
2763                         opleft -= 2;
2764                 } else {
2765                         *op++ = *dp;
2766                         opleft--;
2767                 }
2768         }
2769         if (opleft < 1)
2770                 goto toobig;
2771         *op = 0;
2772         return optbuf;
2773 toobig:
2774         warning("dhcp option too large");
2775         return "<error>";
2776 }
2777
2778 int
2779 fork_privchld(int fd, int fd2)
2780 {
2781         struct pollfd pfd[1];
2782         int nfds;
2783
2784         switch (fork()) {
2785         case -1:
2786                 error("cannot fork");
2787         case 0:
2788                 break;
2789         default:
2790                 return (0);
2791         }
2792
2793         setproctitle("%s [priv]", ifi->name);
2794
2795         setsid();
2796         dup2(nullfd, STDIN_FILENO);
2797         dup2(nullfd, STDOUT_FILENO);
2798         dup2(nullfd, STDERR_FILENO);
2799         close(nullfd);
2800         close(fd2);
2801         close(ifi->rfdesc);
2802         ifi->rfdesc = -1;
2803
2804         for (;;) {
2805                 pfd[0].fd = fd;
2806                 pfd[0].events = POLLIN;
2807                 if ((nfds = poll(pfd, 1, INFTIM)) == -1)
2808                         if (errno != EINTR)
2809                                 error("poll error");
2810
2811                 if (nfds == 0 || !(pfd[0].revents & POLLIN))
2812                         continue;
2813
2814                 dispatch_imsg(ifi, fd);
2815         }
2816 }