]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sbin/dhclient/dhclient.c
Upgrade Unbound to 1.7.1.
[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             ip->client->state != S_REBOOTING)
1518                 memcpy(&from, ip->client->active->address.iabuf,
1519                     sizeof(from));
1520         else
1521                 from.s_addr = INADDR_ANY;
1522
1523         /* Record the number of seconds since we started sending. */
1524         if (ip->client->state == S_REQUESTING)
1525                 ip->client->packet.secs = ip->client->secs;
1526         else {
1527                 if (interval < 65536)
1528                         ip->client->packet.secs = htons(interval);
1529                 else
1530                         ip->client->packet.secs = htons(65535);
1531         }
1532
1533         note("DHCPREQUEST on %s to %s port %d", ip->name, inet_ntoa(to),
1534             REMOTE_PORT);
1535
1536         /* Send out a packet. */
1537         send_packet_unpriv(privfd, &ip->client->packet,
1538             ip->client->packet_length, from, to);
1539
1540         add_timeout(cur_time + ip->client->interval, send_request, ip);
1541 }
1542
1543 void
1544 send_decline(void *ipp)
1545 {
1546         struct interface_info *ip = ipp;
1547
1548         note("DHCPDECLINE on %s to %s port %d", ip->name,
1549             inet_ntoa(inaddr_broadcast), REMOTE_PORT);
1550
1551         /* Send out a packet. */
1552         send_packet_unpriv(privfd, &ip->client->packet,
1553             ip->client->packet_length, inaddr_any, inaddr_broadcast);
1554 }
1555
1556 void
1557 make_discover(struct interface_info *ip, struct client_lease *lease)
1558 {
1559         unsigned char discover = DHCPDISCOVER;
1560         struct tree_cache *options[256];
1561         struct tree_cache option_elements[256];
1562         int i;
1563
1564         memset(option_elements, 0, sizeof(option_elements));
1565         memset(options, 0, sizeof(options));
1566         memset(&ip->client->packet, 0, sizeof(ip->client->packet));
1567
1568         /* Set DHCP_MESSAGE_TYPE to DHCPDISCOVER */
1569         i = DHO_DHCP_MESSAGE_TYPE;
1570         options[i] = &option_elements[i];
1571         options[i]->value = &discover;
1572         options[i]->len = sizeof(discover);
1573         options[i]->buf_size = sizeof(discover);
1574         options[i]->timeout = 0xFFFFFFFF;
1575
1576         /* Request the options we want */
1577         i  = DHO_DHCP_PARAMETER_REQUEST_LIST;
1578         options[i] = &option_elements[i];
1579         options[i]->value = ip->client->config->requested_options;
1580         options[i]->len = ip->client->config->requested_option_count;
1581         options[i]->buf_size =
1582                 ip->client->config->requested_option_count;
1583         options[i]->timeout = 0xFFFFFFFF;
1584
1585         /* If we had an address, try to get it again. */
1586         if (lease) {
1587                 ip->client->requested_address = lease->address;
1588                 i = DHO_DHCP_REQUESTED_ADDRESS;
1589                 options[i] = &option_elements[i];
1590                 options[i]->value = lease->address.iabuf;
1591                 options[i]->len = lease->address.len;
1592                 options[i]->buf_size = lease->address.len;
1593                 options[i]->timeout = 0xFFFFFFFF;
1594         } else
1595                 ip->client->requested_address.len = 0;
1596
1597         /* Send any options requested in the config file. */
1598         for (i = 0; i < 256; i++)
1599                 if (!options[i] &&
1600                     ip->client->config->send_options[i].data) {
1601                         options[i] = &option_elements[i];
1602                         options[i]->value =
1603                             ip->client->config->send_options[i].data;
1604                         options[i]->len =
1605                             ip->client->config->send_options[i].len;
1606                         options[i]->buf_size =
1607                             ip->client->config->send_options[i].len;
1608                         options[i]->timeout = 0xFFFFFFFF;
1609                 }
1610
1611         /* send host name if not set via config file. */
1612         if (!options[DHO_HOST_NAME]) {
1613                 if (hostname[0] != '\0') {
1614                         size_t len;
1615                         char* posDot = strchr(hostname, '.');
1616                         if (posDot != NULL)
1617                                 len = posDot - hostname;
1618                         else
1619                                 len = strlen(hostname);
1620                         options[DHO_HOST_NAME] = &option_elements[DHO_HOST_NAME];
1621                         options[DHO_HOST_NAME]->value = hostname;
1622                         options[DHO_HOST_NAME]->len = len;
1623                         options[DHO_HOST_NAME]->buf_size = len;
1624                         options[DHO_HOST_NAME]->timeout = 0xFFFFFFFF;
1625                 }
1626         }
1627
1628         /* set unique client identifier */
1629         char client_ident[sizeof(ip->hw_address.haddr) + 1];
1630         if (!options[DHO_DHCP_CLIENT_IDENTIFIER]) {
1631                 int hwlen = (ip->hw_address.hlen < sizeof(client_ident)-1) ?
1632                                 ip->hw_address.hlen : sizeof(client_ident)-1;
1633                 client_ident[0] = ip->hw_address.htype;
1634                 memcpy(&client_ident[1], ip->hw_address.haddr, hwlen);
1635                 options[DHO_DHCP_CLIENT_IDENTIFIER] = &option_elements[DHO_DHCP_CLIENT_IDENTIFIER];
1636                 options[DHO_DHCP_CLIENT_IDENTIFIER]->value = client_ident;
1637                 options[DHO_DHCP_CLIENT_IDENTIFIER]->len = hwlen+1;
1638                 options[DHO_DHCP_CLIENT_IDENTIFIER]->buf_size = hwlen+1;
1639                 options[DHO_DHCP_CLIENT_IDENTIFIER]->timeout = 0xFFFFFFFF;
1640         }
1641
1642         /* Set up the option buffer... */
1643         ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
1644             options, 0, 0, 0, NULL, 0);
1645         if (ip->client->packet_length < BOOTP_MIN_LEN)
1646                 ip->client->packet_length = BOOTP_MIN_LEN;
1647
1648         ip->client->packet.op = BOOTREQUEST;
1649         ip->client->packet.htype = ip->hw_address.htype;
1650         ip->client->packet.hlen = ip->hw_address.hlen;
1651         ip->client->packet.hops = 0;
1652         ip->client->packet.xid = arc4random();
1653         ip->client->packet.secs = 0; /* filled in by send_discover. */
1654         ip->client->packet.flags = 0;
1655
1656         memset(&(ip->client->packet.ciaddr),
1657             0, sizeof(ip->client->packet.ciaddr));
1658         memset(&(ip->client->packet.yiaddr),
1659             0, sizeof(ip->client->packet.yiaddr));
1660         memset(&(ip->client->packet.siaddr),
1661             0, sizeof(ip->client->packet.siaddr));
1662         memset(&(ip->client->packet.giaddr),
1663             0, sizeof(ip->client->packet.giaddr));
1664         memcpy(ip->client->packet.chaddr,
1665             ip->hw_address.haddr, ip->hw_address.hlen);
1666 }
1667
1668
1669 void
1670 make_request(struct interface_info *ip, struct client_lease * lease)
1671 {
1672         unsigned char request = DHCPREQUEST;
1673         struct tree_cache *options[256];
1674         struct tree_cache option_elements[256];
1675         int i;
1676
1677         memset(options, 0, sizeof(options));
1678         memset(&ip->client->packet, 0, sizeof(ip->client->packet));
1679
1680         /* Set DHCP_MESSAGE_TYPE to DHCPREQUEST */
1681         i = DHO_DHCP_MESSAGE_TYPE;
1682         options[i] = &option_elements[i];
1683         options[i]->value = &request;
1684         options[i]->len = sizeof(request);
1685         options[i]->buf_size = sizeof(request);
1686         options[i]->timeout = 0xFFFFFFFF;
1687
1688         /* Request the options we want */
1689         i = DHO_DHCP_PARAMETER_REQUEST_LIST;
1690         options[i] = &option_elements[i];
1691         options[i]->value = ip->client->config->requested_options;
1692         options[i]->len = ip->client->config->requested_option_count;
1693         options[i]->buf_size =
1694                 ip->client->config->requested_option_count;
1695         options[i]->timeout = 0xFFFFFFFF;
1696
1697         /* If we are requesting an address that hasn't yet been assigned
1698            to us, use the DHCP Requested Address option. */
1699         if (ip->client->state == S_REQUESTING) {
1700                 /* Send back the server identifier... */
1701                 i = DHO_DHCP_SERVER_IDENTIFIER;
1702                 options[i] = &option_elements[i];
1703                 options[i]->value = lease->options[i].data;
1704                 options[i]->len = lease->options[i].len;
1705                 options[i]->buf_size = lease->options[i].len;
1706                 options[i]->timeout = 0xFFFFFFFF;
1707         }
1708         if (ip->client->state == S_REQUESTING ||
1709             ip->client->state == S_REBOOTING) {
1710                 ip->client->requested_address = lease->address;
1711                 i = DHO_DHCP_REQUESTED_ADDRESS;
1712                 options[i] = &option_elements[i];
1713                 options[i]->value = lease->address.iabuf;
1714                 options[i]->len = lease->address.len;
1715                 options[i]->buf_size = lease->address.len;
1716                 options[i]->timeout = 0xFFFFFFFF;
1717         } else
1718                 ip->client->requested_address.len = 0;
1719
1720         /* Send any options requested in the config file. */
1721         for (i = 0; i < 256; i++)
1722                 if (!options[i] &&
1723                     ip->client->config->send_options[i].data) {
1724                         options[i] = &option_elements[i];
1725                         options[i]->value =
1726                             ip->client->config->send_options[i].data;
1727                         options[i]->len =
1728                             ip->client->config->send_options[i].len;
1729                         options[i]->buf_size =
1730                             ip->client->config->send_options[i].len;
1731                         options[i]->timeout = 0xFFFFFFFF;
1732                 }
1733
1734         /* send host name if not set via config file. */
1735         if (!options[DHO_HOST_NAME]) {
1736                 if (hostname[0] != '\0') {
1737                         size_t len;
1738                         char* posDot = strchr(hostname, '.');
1739                         if (posDot != NULL)
1740                                 len = posDot - hostname;
1741                         else
1742                                 len = strlen(hostname);
1743                         options[DHO_HOST_NAME] = &option_elements[DHO_HOST_NAME];
1744                         options[DHO_HOST_NAME]->value = hostname;
1745                         options[DHO_HOST_NAME]->len = len;
1746                         options[DHO_HOST_NAME]->buf_size = len;
1747                         options[DHO_HOST_NAME]->timeout = 0xFFFFFFFF;
1748                 }
1749         }
1750
1751         /* set unique client identifier */
1752         char client_ident[sizeof(struct hardware)];
1753         if (!options[DHO_DHCP_CLIENT_IDENTIFIER]) {
1754                 int hwlen = (ip->hw_address.hlen < sizeof(client_ident)-1) ?
1755                                 ip->hw_address.hlen : sizeof(client_ident)-1;
1756                 client_ident[0] = ip->hw_address.htype;
1757                 memcpy(&client_ident[1], ip->hw_address.haddr, hwlen);
1758                 options[DHO_DHCP_CLIENT_IDENTIFIER] = &option_elements[DHO_DHCP_CLIENT_IDENTIFIER];
1759                 options[DHO_DHCP_CLIENT_IDENTIFIER]->value = client_ident;
1760                 options[DHO_DHCP_CLIENT_IDENTIFIER]->len = hwlen+1;
1761                 options[DHO_DHCP_CLIENT_IDENTIFIER]->buf_size = hwlen+1;
1762                 options[DHO_DHCP_CLIENT_IDENTIFIER]->timeout = 0xFFFFFFFF;
1763         }
1764
1765         /* Set up the option buffer... */
1766         ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
1767             options, 0, 0, 0, NULL, 0);
1768         if (ip->client->packet_length < BOOTP_MIN_LEN)
1769                 ip->client->packet_length = BOOTP_MIN_LEN;
1770
1771         ip->client->packet.op = BOOTREQUEST;
1772         ip->client->packet.htype = ip->hw_address.htype;
1773         ip->client->packet.hlen = ip->hw_address.hlen;
1774         ip->client->packet.hops = 0;
1775         ip->client->packet.xid = ip->client->xid;
1776         ip->client->packet.secs = 0; /* Filled in by send_request. */
1777
1778         /* If we own the address we're requesting, put it in ciaddr;
1779            otherwise set ciaddr to zero. */
1780         if (ip->client->state == S_BOUND ||
1781             ip->client->state == S_RENEWING ||
1782             ip->client->state == S_REBINDING) {
1783                 memcpy(&ip->client->packet.ciaddr,
1784                     lease->address.iabuf, lease->address.len);
1785                 ip->client->packet.flags = 0;
1786         } else {
1787                 memset(&ip->client->packet.ciaddr, 0,
1788                     sizeof(ip->client->packet.ciaddr));
1789                 ip->client->packet.flags = 0;
1790         }
1791
1792         memset(&ip->client->packet.yiaddr, 0,
1793             sizeof(ip->client->packet.yiaddr));
1794         memset(&ip->client->packet.siaddr, 0,
1795             sizeof(ip->client->packet.siaddr));
1796         memset(&ip->client->packet.giaddr, 0,
1797             sizeof(ip->client->packet.giaddr));
1798         memcpy(ip->client->packet.chaddr,
1799             ip->hw_address.haddr, ip->hw_address.hlen);
1800 }
1801
1802 void
1803 make_decline(struct interface_info *ip, struct client_lease *lease)
1804 {
1805         struct tree_cache *options[256], message_type_tree;
1806         struct tree_cache requested_address_tree;
1807         struct tree_cache server_id_tree, client_id_tree;
1808         unsigned char decline = DHCPDECLINE;
1809         int i;
1810
1811         memset(options, 0, sizeof(options));
1812         memset(&ip->client->packet, 0, sizeof(ip->client->packet));
1813
1814         /* Set DHCP_MESSAGE_TYPE to DHCPDECLINE */
1815         i = DHO_DHCP_MESSAGE_TYPE;
1816         options[i] = &message_type_tree;
1817         options[i]->value = &decline;
1818         options[i]->len = sizeof(decline);
1819         options[i]->buf_size = sizeof(decline);
1820         options[i]->timeout = 0xFFFFFFFF;
1821
1822         /* Send back the server identifier... */
1823         i = DHO_DHCP_SERVER_IDENTIFIER;
1824         options[i] = &server_id_tree;
1825         options[i]->value = lease->options[i].data;
1826         options[i]->len = lease->options[i].len;
1827         options[i]->buf_size = lease->options[i].len;
1828         options[i]->timeout = 0xFFFFFFFF;
1829
1830         /* Send back the address we're declining. */
1831         i = DHO_DHCP_REQUESTED_ADDRESS;
1832         options[i] = &requested_address_tree;
1833         options[i]->value = lease->address.iabuf;
1834         options[i]->len = lease->address.len;
1835         options[i]->buf_size = lease->address.len;
1836         options[i]->timeout = 0xFFFFFFFF;
1837
1838         /* Send the uid if the user supplied one. */
1839         i = DHO_DHCP_CLIENT_IDENTIFIER;
1840         if (ip->client->config->send_options[i].len) {
1841                 options[i] = &client_id_tree;
1842                 options[i]->value = ip->client->config->send_options[i].data;
1843                 options[i]->len = ip->client->config->send_options[i].len;
1844                 options[i]->buf_size = ip->client->config->send_options[i].len;
1845                 options[i]->timeout = 0xFFFFFFFF;
1846         }
1847
1848
1849         /* Set up the option buffer... */
1850         ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
1851             options, 0, 0, 0, NULL, 0);
1852         if (ip->client->packet_length < BOOTP_MIN_LEN)
1853                 ip->client->packet_length = BOOTP_MIN_LEN;
1854
1855         ip->client->packet.op = BOOTREQUEST;
1856         ip->client->packet.htype = ip->hw_address.htype;
1857         ip->client->packet.hlen = ip->hw_address.hlen;
1858         ip->client->packet.hops = 0;
1859         ip->client->packet.xid = ip->client->xid;
1860         ip->client->packet.secs = 0; /* Filled in by send_request. */
1861         ip->client->packet.flags = 0;
1862
1863         /* ciaddr must always be zero. */
1864         memset(&ip->client->packet.ciaddr, 0,
1865             sizeof(ip->client->packet.ciaddr));
1866         memset(&ip->client->packet.yiaddr, 0,
1867             sizeof(ip->client->packet.yiaddr));
1868         memset(&ip->client->packet.siaddr, 0,
1869             sizeof(ip->client->packet.siaddr));
1870         memset(&ip->client->packet.giaddr, 0,
1871             sizeof(ip->client->packet.giaddr));
1872         memcpy(ip->client->packet.chaddr,
1873             ip->hw_address.haddr, ip->hw_address.hlen);
1874 }
1875
1876 void
1877 free_client_lease(struct client_lease *lease)
1878 {
1879         int i;
1880
1881         if (lease->server_name)
1882                 free(lease->server_name);
1883         if (lease->filename)
1884                 free(lease->filename);
1885         for (i = 0; i < 256; i++) {
1886                 if (lease->options[i].len)
1887                         free(lease->options[i].data);
1888         }
1889         free(lease);
1890 }
1891
1892 FILE *leaseFile;
1893
1894 void
1895 rewrite_client_leases(void)
1896 {
1897         struct client_lease *lp;
1898         cap_rights_t rights;
1899
1900         if (!leaseFile) {
1901                 leaseFile = fopen(path_dhclient_db, "w");
1902                 if (!leaseFile)
1903                         error("can't create %s: %m", path_dhclient_db);
1904                 cap_rights_init(&rights, CAP_FCNTL, CAP_FSTAT, CAP_FSYNC,
1905                     CAP_FTRUNCATE, CAP_SEEK, CAP_WRITE);
1906                 if (cap_rights_limit(fileno(leaseFile), &rights) < 0 &&
1907                     errno != ENOSYS) {
1908                         error("can't limit lease descriptor: %m");
1909                 }
1910                 if (cap_fcntls_limit(fileno(leaseFile), CAP_FCNTL_GETFL) < 0 &&
1911                     errno != ENOSYS) {
1912                         error("can't limit lease descriptor fcntls: %m");
1913                 }
1914         } else {
1915                 fflush(leaseFile);
1916                 rewind(leaseFile);
1917         }
1918
1919         for (lp = ifi->client->leases; lp; lp = lp->next)
1920                 write_client_lease(ifi, lp, 1);
1921         if (ifi->client->active)
1922                 write_client_lease(ifi, ifi->client->active, 1);
1923
1924         fflush(leaseFile);
1925         ftruncate(fileno(leaseFile), ftello(leaseFile));
1926         fsync(fileno(leaseFile));
1927 }
1928
1929 void
1930 write_client_lease(struct interface_info *ip, struct client_lease *lease,
1931     int rewrite)
1932 {
1933         static int leases_written;
1934         struct tm *t;
1935         int i;
1936
1937         if (!rewrite) {
1938                 if (leases_written++ > 20) {
1939                         rewrite_client_leases();
1940                         leases_written = 0;
1941                 }
1942         }
1943
1944         /* If the lease came from the config file, we don't need to stash
1945            a copy in the lease database. */
1946         if (lease->is_static)
1947                 return;
1948
1949         if (!leaseFile) {       /* XXX */
1950                 leaseFile = fopen(path_dhclient_db, "w");
1951                 if (!leaseFile)
1952                         error("can't create %s: %m", path_dhclient_db);
1953         }
1954
1955         fprintf(leaseFile, "lease {\n");
1956         if (lease->is_bootp)
1957                 fprintf(leaseFile, "  bootp;\n");
1958         fprintf(leaseFile, "  interface \"%s\";\n", ip->name);
1959         fprintf(leaseFile, "  fixed-address %s;\n", piaddr(lease->address));
1960         if (lease->nextserver.len == sizeof(inaddr_any) &&
1961             0 != memcmp(lease->nextserver.iabuf, &inaddr_any,
1962             sizeof(inaddr_any)))
1963                 fprintf(leaseFile, "  next-server %s;\n",
1964                     piaddr(lease->nextserver));
1965         if (lease->filename)
1966                 fprintf(leaseFile, "  filename \"%s\";\n", lease->filename);
1967         if (lease->server_name)
1968                 fprintf(leaseFile, "  server-name \"%s\";\n",
1969                     lease->server_name);
1970         if (lease->medium)
1971                 fprintf(leaseFile, "  medium \"%s\";\n", lease->medium->string);
1972         for (i = 0; i < 256; i++)
1973                 if (lease->options[i].len)
1974                         fprintf(leaseFile, "  option %s %s;\n",
1975                             dhcp_options[i].name,
1976                             pretty_print_option(i, lease->options[i].data,
1977                             lease->options[i].len, 1, 1));
1978
1979         t = gmtime(&lease->renewal);
1980         fprintf(leaseFile, "  renew %d %d/%d/%d %02d:%02d:%02d;\n",
1981             t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
1982             t->tm_hour, t->tm_min, t->tm_sec);
1983         t = gmtime(&lease->rebind);
1984         fprintf(leaseFile, "  rebind %d %d/%d/%d %02d:%02d:%02d;\n",
1985             t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
1986             t->tm_hour, t->tm_min, t->tm_sec);
1987         t = gmtime(&lease->expiry);
1988         fprintf(leaseFile, "  expire %d %d/%d/%d %02d:%02d:%02d;\n",
1989             t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
1990             t->tm_hour, t->tm_min, t->tm_sec);
1991         fprintf(leaseFile, "}\n");
1992         fflush(leaseFile);
1993 }
1994
1995 void
1996 script_init(const char *reason, struct string_list *medium)
1997 {
1998         size_t           len, mediumlen = 0;
1999         struct imsg_hdr  hdr;
2000         struct buf      *buf;
2001         int              errs;
2002
2003         if (medium != NULL && medium->string != NULL)
2004                 mediumlen = strlen(medium->string);
2005
2006         hdr.code = IMSG_SCRIPT_INIT;
2007         hdr.len = sizeof(struct imsg_hdr) +
2008             sizeof(size_t) + mediumlen +
2009             sizeof(size_t) + strlen(reason);
2010
2011         if ((buf = buf_open(hdr.len)) == NULL)
2012                 error("buf_open: %m");
2013
2014         errs = 0;
2015         errs += buf_add(buf, &hdr, sizeof(hdr));
2016         errs += buf_add(buf, &mediumlen, sizeof(mediumlen));
2017         if (mediumlen > 0)
2018                 errs += buf_add(buf, medium->string, mediumlen);
2019         len = strlen(reason);
2020         errs += buf_add(buf, &len, sizeof(len));
2021         errs += buf_add(buf, reason, len);
2022
2023         if (errs)
2024                 error("buf_add: %m");
2025
2026         if (buf_close(privfd, buf) == -1)
2027                 error("buf_close: %m");
2028 }
2029
2030 void
2031 priv_script_init(const char *reason, char *medium)
2032 {
2033         struct interface_info *ip = ifi;
2034
2035         if (ip) {
2036                 ip->client->scriptEnvsize = 100;
2037                 if (ip->client->scriptEnv == NULL)
2038                         ip->client->scriptEnv =
2039                             malloc(ip->client->scriptEnvsize * sizeof(char *));
2040                 if (ip->client->scriptEnv == NULL)
2041                         error("script_init: no memory for environment");
2042
2043                 ip->client->scriptEnv[0] = strdup(CLIENT_PATH);
2044                 if (ip->client->scriptEnv[0] == NULL)
2045                         error("script_init: no memory for environment");
2046
2047                 ip->client->scriptEnv[1] = NULL;
2048
2049                 script_set_env(ip->client, "", "interface", ip->name);
2050
2051                 if (medium)
2052                         script_set_env(ip->client, "", "medium", medium);
2053
2054                 script_set_env(ip->client, "", "reason", reason);
2055         }
2056 }
2057
2058 void
2059 priv_script_write_params(const char *prefix, struct client_lease *lease)
2060 {
2061         struct interface_info *ip = ifi;
2062         u_int8_t dbuf[1500], *dp = NULL;
2063         int i;
2064         size_t len;
2065         char tbuf[128];
2066
2067         script_set_env(ip->client, prefix, "ip_address",
2068             piaddr(lease->address));
2069
2070         if (ip->client->config->default_actions[DHO_SUBNET_MASK] ==
2071             ACTION_SUPERSEDE) {
2072                 dp = ip->client->config->defaults[DHO_SUBNET_MASK].data;
2073                 len = ip->client->config->defaults[DHO_SUBNET_MASK].len;
2074         } else {
2075                 dp = lease->options[DHO_SUBNET_MASK].data;
2076                 len = lease->options[DHO_SUBNET_MASK].len;
2077         }
2078         if (len && (len < sizeof(lease->address.iabuf))) {
2079                 struct iaddr netmask, subnet, broadcast;
2080
2081                 memcpy(netmask.iabuf, dp, len);
2082                 netmask.len = len;
2083                 subnet = subnet_number(lease->address, netmask);
2084                 if (subnet.len) {
2085                         script_set_env(ip->client, prefix, "network_number",
2086                             piaddr(subnet));
2087                         if (!lease->options[DHO_BROADCAST_ADDRESS].len) {
2088                                 broadcast = broadcast_addr(subnet, netmask);
2089                                 if (broadcast.len)
2090                                         script_set_env(ip->client, prefix,
2091                                             "broadcast_address",
2092                                             piaddr(broadcast));
2093                         }
2094                 }
2095         }
2096
2097         if (lease->filename)
2098                 script_set_env(ip->client, prefix, "filename", lease->filename);
2099         if (lease->server_name)
2100                 script_set_env(ip->client, prefix, "server_name",
2101                     lease->server_name);
2102         for (i = 0; i < 256; i++) {
2103                 len = 0;
2104
2105                 if (ip->client->config->defaults[i].len) {
2106                         if (lease->options[i].len) {
2107                                 switch (
2108                                     ip->client->config->default_actions[i]) {
2109                                 case ACTION_DEFAULT:
2110                                         dp = lease->options[i].data;
2111                                         len = lease->options[i].len;
2112                                         break;
2113                                 case ACTION_SUPERSEDE:
2114 supersede:
2115                                         dp = ip->client->
2116                                                 config->defaults[i].data;
2117                                         len = ip->client->
2118                                                 config->defaults[i].len;
2119                                         break;
2120                                 case ACTION_PREPEND:
2121                                         len = ip->client->
2122                                             config->defaults[i].len +
2123                                             lease->options[i].len;
2124                                         if (len >= sizeof(dbuf)) {
2125                                                 warning("no space to %s %s",
2126                                                     "prepend option",
2127                                                     dhcp_options[i].name);
2128                                                 goto supersede;
2129                                         }
2130                                         dp = dbuf;
2131                                         memcpy(dp,
2132                                                 ip->client->
2133                                                 config->defaults[i].data,
2134                                                 ip->client->
2135                                                 config->defaults[i].len);
2136                                         memcpy(dp + ip->client->
2137                                                 config->defaults[i].len,
2138                                                 lease->options[i].data,
2139                                                 lease->options[i].len);
2140                                         dp[len] = '\0';
2141                                         break;
2142                                 case ACTION_APPEND:
2143                                         /*
2144                                          * When we append, we assume that we're
2145                                          * appending to text.  Some MS servers
2146                                          * include a NUL byte at the end of
2147                                          * the search string provided.
2148                                          */
2149                                         len = ip->client->
2150                                             config->defaults[i].len +
2151                                             lease->options[i].len;
2152                                         if (len >= sizeof(dbuf)) {
2153                                                 warning("no space to %s %s",
2154                                                     "append option",
2155                                                     dhcp_options[i].name);
2156                                                 goto supersede;
2157                                         }
2158                                         memcpy(dbuf,
2159                                                 lease->options[i].data,
2160                                                 lease->options[i].len);
2161                                         for (dp = dbuf + lease->options[i].len;
2162                                             dp > dbuf; dp--, len--)
2163                                                 if (dp[-1] != '\0')
2164                                                         break;
2165                                         memcpy(dp,
2166                                                 ip->client->
2167                                                 config->defaults[i].data,
2168                                                 ip->client->
2169                                                 config->defaults[i].len);
2170                                         dp = dbuf;
2171                                         dp[len] = '\0';
2172                                 }
2173                         } else {
2174                                 dp = ip->client->
2175                                         config->defaults[i].data;
2176                                 len = ip->client->
2177                                         config->defaults[i].len;
2178                         }
2179                 } else if (lease->options[i].len) {
2180                         len = lease->options[i].len;
2181                         dp = lease->options[i].data;
2182                 } else {
2183                         len = 0;
2184                 }
2185                 if (len) {
2186                         char name[256];
2187
2188                         if (dhcp_option_ev_name(name, sizeof(name),
2189                             &dhcp_options[i]))
2190                                 script_set_env(ip->client, prefix, name,
2191                                     pretty_print_option(i, dp, len, 0, 0));
2192                 }
2193         }
2194         snprintf(tbuf, sizeof(tbuf), "%d", (int)lease->expiry);
2195         script_set_env(ip->client, prefix, "expiry", tbuf);
2196 }
2197
2198 void
2199 script_write_params(const char *prefix, struct client_lease *lease)
2200 {
2201         size_t           fn_len = 0, sn_len = 0, pr_len = 0;
2202         struct imsg_hdr  hdr;
2203         struct buf      *buf;
2204         int              errs, i;
2205
2206         if (lease->filename != NULL)
2207                 fn_len = strlen(lease->filename);
2208         if (lease->server_name != NULL)
2209                 sn_len = strlen(lease->server_name);
2210         if (prefix != NULL)
2211                 pr_len = strlen(prefix);
2212
2213         hdr.code = IMSG_SCRIPT_WRITE_PARAMS;
2214         hdr.len = sizeof(hdr) + sizeof(*lease) +
2215             sizeof(fn_len) + fn_len + sizeof(sn_len) + sn_len +
2216             sizeof(pr_len) + pr_len;
2217
2218         for (i = 0; i < 256; i++) {
2219                 hdr.len += sizeof(lease->options[i].len);
2220                 hdr.len += lease->options[i].len;
2221         }
2222
2223         scripttime = time(NULL);
2224
2225         if ((buf = buf_open(hdr.len)) == NULL)
2226                 error("buf_open: %m");
2227
2228         errs = 0;
2229         errs += buf_add(buf, &hdr, sizeof(hdr));
2230         errs += buf_add(buf, lease, sizeof(*lease));
2231         errs += buf_add(buf, &fn_len, sizeof(fn_len));
2232         errs += buf_add(buf, lease->filename, fn_len);
2233         errs += buf_add(buf, &sn_len, sizeof(sn_len));
2234         errs += buf_add(buf, lease->server_name, sn_len);
2235         errs += buf_add(buf, &pr_len, sizeof(pr_len));
2236         errs += buf_add(buf, prefix, pr_len);
2237
2238         for (i = 0; i < 256; i++) {
2239                 errs += buf_add(buf, &lease->options[i].len,
2240                     sizeof(lease->options[i].len));
2241                 errs += buf_add(buf, lease->options[i].data,
2242                     lease->options[i].len);
2243         }
2244
2245         if (errs)
2246                 error("buf_add: %m");
2247
2248         if (buf_close(privfd, buf) == -1)
2249                 error("buf_close: %m");
2250 }
2251
2252 int
2253 script_go(void)
2254 {
2255         struct imsg_hdr  hdr;
2256         struct buf      *buf;
2257         int              ret;
2258
2259         hdr.code = IMSG_SCRIPT_GO;
2260         hdr.len = sizeof(struct imsg_hdr);
2261
2262         if ((buf = buf_open(hdr.len)) == NULL)
2263                 error("buf_open: %m");
2264
2265         if (buf_add(buf, &hdr, sizeof(hdr)))
2266                 error("buf_add: %m");
2267
2268         if (buf_close(privfd, buf) == -1)
2269                 error("buf_close: %m");
2270
2271         bzero(&hdr, sizeof(hdr));
2272         buf_read(privfd, &hdr, sizeof(hdr));
2273         if (hdr.code != IMSG_SCRIPT_GO_RET)
2274                 error("unexpected msg type %u", hdr.code);
2275         if (hdr.len != sizeof(hdr) + sizeof(int))
2276                 error("received corrupted message");
2277         buf_read(privfd, &ret, sizeof(ret));
2278
2279         scripttime = time(NULL);
2280
2281         return (ret);
2282 }
2283
2284 int
2285 priv_script_go(void)
2286 {
2287         char *scriptName, *argv[2], **envp, *epp[3], reason[] = "REASON=NBI";
2288         static char client_path[] = CLIENT_PATH;
2289         struct interface_info *ip = ifi;
2290         int pid, wpid, wstatus;
2291
2292         scripttime = time(NULL);
2293
2294         if (ip) {
2295                 scriptName = ip->client->config->script_name;
2296                 envp = ip->client->scriptEnv;
2297         } else {
2298                 scriptName = top_level_config.script_name;
2299                 epp[0] = reason;
2300                 epp[1] = client_path;
2301                 epp[2] = NULL;
2302                 envp = epp;
2303         }
2304
2305         argv[0] = scriptName;
2306         argv[1] = NULL;
2307
2308         pid = fork();
2309         if (pid < 0) {
2310                 error("fork: %m");
2311                 wstatus = 0;
2312         } else if (pid) {
2313                 do {
2314                         wpid = wait(&wstatus);
2315                 } while (wpid != pid && wpid > 0);
2316                 if (wpid < 0) {
2317                         error("wait: %m");
2318                         wstatus = 0;
2319                 }
2320         } else {
2321                 execve(scriptName, argv, envp);
2322                 error("execve (%s, ...): %m", scriptName);
2323         }
2324
2325         if (ip)
2326                 script_flush_env(ip->client);
2327
2328         return (wstatus & 0xff);
2329 }
2330
2331 void
2332 script_set_env(struct client_state *client, const char *prefix,
2333     const char *name, const char *value)
2334 {
2335         int i, namelen;
2336         size_t j;
2337
2338         /* No `` or $() command substitution allowed in environment values! */
2339         for (j=0; j < strlen(value); j++)
2340                 switch (value[j]) {
2341                 case '`':
2342                 case '$':
2343                         warning("illegal character (%c) in value '%s'",
2344                             value[j], value);
2345                         /* Ignore this option */
2346                         return;
2347                 }
2348
2349         namelen = strlen(name);
2350
2351         for (i = 0; client->scriptEnv[i]; i++)
2352                 if (strncmp(client->scriptEnv[i], name, namelen) == 0 &&
2353                     client->scriptEnv[i][namelen] == '=')
2354                         break;
2355
2356         if (client->scriptEnv[i])
2357                 /* Reuse the slot. */
2358                 free(client->scriptEnv[i]);
2359         else {
2360                 /* New variable.  Expand if necessary. */
2361                 if (i >= client->scriptEnvsize - 1) {
2362                         char **newscriptEnv;
2363                         int newscriptEnvsize = client->scriptEnvsize + 50;
2364
2365                         newscriptEnv = realloc(client->scriptEnv,
2366                             newscriptEnvsize);
2367                         if (newscriptEnv == NULL) {
2368                                 free(client->scriptEnv);
2369                                 client->scriptEnv = NULL;
2370                                 client->scriptEnvsize = 0;
2371                                 error("script_set_env: no memory for variable");
2372                         }
2373                         client->scriptEnv = newscriptEnv;
2374                         client->scriptEnvsize = newscriptEnvsize;
2375                 }
2376                 /* need to set the NULL pointer at end of array beyond
2377                    the new slot. */
2378                 client->scriptEnv[i + 1] = NULL;
2379         }
2380         /* Allocate space and format the variable in the appropriate slot. */
2381         client->scriptEnv[i] = malloc(strlen(prefix) + strlen(name) + 1 +
2382             strlen(value) + 1);
2383         if (client->scriptEnv[i] == NULL)
2384                 error("script_set_env: no memory for variable assignment");
2385         snprintf(client->scriptEnv[i], strlen(prefix) + strlen(name) +
2386             1 + strlen(value) + 1, "%s%s=%s", prefix, name, value);
2387 }
2388
2389 void
2390 script_flush_env(struct client_state *client)
2391 {
2392         int i;
2393
2394         for (i = 0; client->scriptEnv[i]; i++) {
2395                 free(client->scriptEnv[i]);
2396                 client->scriptEnv[i] = NULL;
2397         }
2398         client->scriptEnvsize = 0;
2399 }
2400
2401 int
2402 dhcp_option_ev_name(char *buf, size_t buflen, struct option *option)
2403 {
2404         size_t i;
2405
2406         for (i = 0; option->name[i]; i++) {
2407                 if (i + 1 == buflen)
2408                         return 0;
2409                 if (option->name[i] == '-')
2410                         buf[i] = '_';
2411                 else
2412                         buf[i] = option->name[i];
2413         }
2414
2415         buf[i] = 0;
2416         return 1;
2417 }
2418
2419 void
2420 go_daemon(void)
2421 {
2422         static int state = 0;
2423         cap_rights_t rights;
2424
2425         if (no_daemon || state)
2426                 return;
2427
2428         state = 1;
2429
2430         /* Stop logging to stderr... */
2431         log_perror = 0;
2432
2433         if (daemonfd(-1, nullfd) == -1)
2434                 error("daemon");
2435
2436         cap_rights_init(&rights);
2437
2438         if (pidfile != NULL) {
2439                 pidfile_write(pidfile);
2440                 if (cap_rights_limit(pidfile_fileno(pidfile), &rights) < 0 &&
2441                     errno != ENOSYS) {
2442                         error("can't limit pidfile descriptor: %m");
2443                 }
2444         }
2445
2446         if (nullfd != -1) {
2447                 close(nullfd);
2448                 nullfd = -1;
2449         }
2450
2451         if (cap_rights_limit(STDIN_FILENO, &rights) < 0 && errno != ENOSYS)
2452                 error("can't limit stdin: %m");
2453         cap_rights_init(&rights, CAP_WRITE);
2454         if (cap_rights_limit(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS)
2455                 error("can't limit stdout: %m");
2456         if (cap_rights_limit(STDERR_FILENO, &rights) < 0 && errno != ENOSYS)
2457                 error("can't limit stderr: %m");
2458 }
2459
2460 int
2461 check_option(struct client_lease *l, int option)
2462 {
2463         const char *opbuf;
2464         const char *sbuf;
2465
2466         /* we use this, since this is what gets passed to dhclient-script */
2467
2468         opbuf = pretty_print_option(option, l->options[option].data,
2469             l->options[option].len, 0, 0);
2470
2471         sbuf = option_as_string(option, l->options[option].data,
2472             l->options[option].len);
2473
2474         switch (option) {
2475         case DHO_SUBNET_MASK:
2476         case DHO_TIME_SERVERS:
2477         case DHO_NAME_SERVERS:
2478         case DHO_ROUTERS:
2479         case DHO_DOMAIN_NAME_SERVERS:
2480         case DHO_LOG_SERVERS:
2481         case DHO_COOKIE_SERVERS:
2482         case DHO_LPR_SERVERS:
2483         case DHO_IMPRESS_SERVERS:
2484         case DHO_RESOURCE_LOCATION_SERVERS:
2485         case DHO_SWAP_SERVER:
2486         case DHO_BROADCAST_ADDRESS:
2487         case DHO_NIS_SERVERS:
2488         case DHO_NTP_SERVERS:
2489         case DHO_NETBIOS_NAME_SERVERS:
2490         case DHO_NETBIOS_DD_SERVER:
2491         case DHO_FONT_SERVERS:
2492         case DHO_DHCP_SERVER_IDENTIFIER:
2493         case DHO_NISPLUS_SERVERS:
2494         case DHO_MOBILE_IP_HOME_AGENT:
2495         case DHO_SMTP_SERVER:
2496         case DHO_POP_SERVER:
2497         case DHO_NNTP_SERVER:
2498         case DHO_WWW_SERVER:
2499         case DHO_FINGER_SERVER:
2500         case DHO_IRC_SERVER:
2501         case DHO_STREETTALK_SERVER:
2502         case DHO_STREETTALK_DA_SERVER:
2503                 if (!ipv4addrs(opbuf)) {
2504                         warning("Invalid IP address in option: %s", opbuf);
2505                         return (0);
2506                 }
2507                 return (1)  ;
2508         case DHO_HOST_NAME:
2509         case DHO_NIS_DOMAIN:
2510         case DHO_NISPLUS_DOMAIN:
2511         case DHO_TFTP_SERVER_NAME:
2512                 if (!res_hnok(sbuf)) {
2513                         warning("Bogus Host Name option %d: %s (%s)", option,
2514                             sbuf, opbuf);
2515                         l->options[option].len = 0;
2516                         free(l->options[option].data);
2517                 }
2518                 return (1);
2519         case DHO_DOMAIN_NAME:
2520         case DHO_DOMAIN_SEARCH:
2521                 if (!res_hnok(sbuf)) {
2522                         if (!check_search(sbuf)) {
2523                                 warning("Bogus domain search list %d: %s (%s)",
2524                                     option, sbuf, opbuf);
2525                                 l->options[option].len = 0;
2526                                 free(l->options[option].data);
2527                         }
2528                 }
2529                 return (1);
2530         case DHO_PAD:
2531         case DHO_TIME_OFFSET:
2532         case DHO_BOOT_SIZE:
2533         case DHO_MERIT_DUMP:
2534         case DHO_ROOT_PATH:
2535         case DHO_EXTENSIONS_PATH:
2536         case DHO_IP_FORWARDING:
2537         case DHO_NON_LOCAL_SOURCE_ROUTING:
2538         case DHO_POLICY_FILTER:
2539         case DHO_MAX_DGRAM_REASSEMBLY:
2540         case DHO_DEFAULT_IP_TTL:
2541         case DHO_PATH_MTU_AGING_TIMEOUT:
2542         case DHO_PATH_MTU_PLATEAU_TABLE:
2543         case DHO_INTERFACE_MTU:
2544         case DHO_ALL_SUBNETS_LOCAL:
2545         case DHO_PERFORM_MASK_DISCOVERY:
2546         case DHO_MASK_SUPPLIER:
2547         case DHO_ROUTER_DISCOVERY:
2548         case DHO_ROUTER_SOLICITATION_ADDRESS:
2549         case DHO_STATIC_ROUTES:
2550         case DHO_TRAILER_ENCAPSULATION:
2551         case DHO_ARP_CACHE_TIMEOUT:
2552         case DHO_IEEE802_3_ENCAPSULATION:
2553         case DHO_DEFAULT_TCP_TTL:
2554         case DHO_TCP_KEEPALIVE_INTERVAL:
2555         case DHO_TCP_KEEPALIVE_GARBAGE:
2556         case DHO_VENDOR_ENCAPSULATED_OPTIONS:
2557         case DHO_NETBIOS_NODE_TYPE:
2558         case DHO_NETBIOS_SCOPE:
2559         case DHO_X_DISPLAY_MANAGER:
2560         case DHO_DHCP_REQUESTED_ADDRESS:
2561         case DHO_DHCP_LEASE_TIME:
2562         case DHO_DHCP_OPTION_OVERLOAD:
2563         case DHO_DHCP_MESSAGE_TYPE:
2564         case DHO_DHCP_PARAMETER_REQUEST_LIST:
2565         case DHO_DHCP_MESSAGE:
2566         case DHO_DHCP_MAX_MESSAGE_SIZE:
2567         case DHO_DHCP_RENEWAL_TIME:
2568         case DHO_DHCP_REBINDING_TIME:
2569         case DHO_DHCP_CLASS_IDENTIFIER:
2570         case DHO_DHCP_CLIENT_IDENTIFIER:
2571         case DHO_BOOTFILE_NAME:
2572         case DHO_DHCP_USER_CLASS_ID:
2573         case DHO_END:
2574                 return (1);
2575         case DHO_CLASSLESS_ROUTES:
2576                 return (check_classless_option(l->options[option].data,
2577                     l->options[option].len));
2578         default:
2579                 warning("unknown dhcp option value 0x%x", option);
2580                 return (unknown_ok);
2581         }
2582 }
2583
2584 /* RFC 3442 The Classless Static Routes option checks */
2585 int
2586 check_classless_option(unsigned char *data, int len)
2587 {
2588         int i = 0;
2589         unsigned char width;
2590         in_addr_t addr, mask;
2591
2592         if (len < 5) {
2593                 warning("Too small length: %d", len);
2594                 return (0);
2595         }
2596         while(i < len) {
2597                 width = data[i++];
2598                 if (width == 0) {
2599                         i += 4;
2600                         continue;
2601                 } else if (width < 9) {
2602                         addr =  (in_addr_t)(data[i]     << 24);
2603                         i += 1;
2604                 } else if (width < 17) {
2605                         addr =  (in_addr_t)(data[i]     << 24) +
2606                                 (in_addr_t)(data[i + 1] << 16);
2607                         i += 2;
2608                 } else if (width < 25) {
2609                         addr =  (in_addr_t)(data[i]     << 24) +
2610                                 (in_addr_t)(data[i + 1] << 16) +
2611                                 (in_addr_t)(data[i + 2] << 8);
2612                         i += 3;
2613                 } else if (width < 33) {
2614                         addr =  (in_addr_t)(data[i]     << 24) +
2615                                 (in_addr_t)(data[i + 1] << 16) +
2616                                 (in_addr_t)(data[i + 2] << 8)  +
2617                                 data[i + 3];
2618                         i += 4;
2619                 } else {
2620                         warning("Incorrect subnet width: %d", width);
2621                         return (0);
2622                 }
2623                 mask = (in_addr_t)(~0) << (32 - width);
2624                 addr = ntohl(addr);
2625                 mask = ntohl(mask);
2626
2627                 /*
2628                  * From RFC 3442:
2629                  * ... After deriving a subnet number and subnet mask
2630                  * from each destination descriptor, the DHCP client
2631                  * MUST zero any bits in the subnet number where the
2632                  * corresponding bit in the mask is zero...
2633                  */
2634                 if ((addr & mask) != addr) {
2635                         addr &= mask;
2636                         data[i - 1] = (unsigned char)(
2637                                 (addr >> (((32 - width)/8)*8)) & 0xFF);
2638                 }
2639                 i += 4;
2640         }
2641         if (i > len) {
2642                 warning("Incorrect data length: %d (must be %d)", len, i);
2643                 return (0);
2644         }
2645         return (1);
2646 }
2647
2648 int
2649 res_hnok(const char *dn)
2650 {
2651         int pch = PERIOD, ch = *dn++;
2652
2653         while (ch != '\0') {
2654                 int nch = *dn++;
2655
2656                 if (periodchar(ch)) {
2657                         ;
2658                 } else if (periodchar(pch)) {
2659                         if (!borderchar(ch))
2660                                 return (0);
2661                 } else if (periodchar(nch) || nch == '\0') {
2662                         if (!borderchar(ch))
2663                                 return (0);
2664                 } else {
2665                         if (!middlechar(ch))
2666                                 return (0);
2667                 }
2668                 pch = ch, ch = nch;
2669         }
2670         return (1);
2671 }
2672
2673 int
2674 check_search(const char *srch)
2675 {
2676         int pch = PERIOD, ch = *srch++;
2677         int domains = 1;
2678
2679         /* 256 char limit re resolv.conf(5) */
2680         if (strlen(srch) > 256)
2681                 return (0);
2682
2683         while (whitechar(ch))
2684                 ch = *srch++;
2685
2686         while (ch != '\0') {
2687                 int nch = *srch++;
2688
2689                 if (periodchar(ch) || whitechar(ch)) {
2690                         ;
2691                 } else if (periodchar(pch)) {
2692                         if (!borderchar(ch))
2693                                 return (0);
2694                 } else if (periodchar(nch) || nch == '\0') {
2695                         if (!borderchar(ch))
2696                                 return (0);
2697                 } else {
2698                         if (!middlechar(ch))
2699                                 return (0);
2700                 }
2701                 if (!whitechar(ch)) {
2702                         pch = ch;
2703                 } else {
2704                         while (whitechar(nch)) {
2705                                 nch = *srch++;
2706                         }
2707                         if (nch != '\0')
2708                                 domains++;
2709                         pch = PERIOD;
2710                 }
2711                 ch = nch;
2712         }
2713         /* 6 domain limit re resolv.conf(5) */
2714         if (domains > 6)
2715                 return (0);
2716         return (1);
2717 }
2718
2719 /* Does buf consist only of dotted decimal ipv4 addrs?
2720  * return how many if so,
2721  * otherwise, return 0
2722  */
2723 int
2724 ipv4addrs(const char * buf)
2725 {
2726         struct in_addr jnk;
2727         int count = 0;
2728
2729         while (inet_aton(buf, &jnk) == 1){
2730                 count++;
2731                 while (periodchar(*buf) || digitchar(*buf))
2732                         buf++;
2733                 if (*buf == '\0')
2734                         return (count);
2735                 while (*buf ==  ' ')
2736                         buf++;
2737         }
2738         return (0);
2739 }
2740
2741
2742 const char *
2743 option_as_string(unsigned int code, unsigned char *data, int len)
2744 {
2745         static char optbuf[32768]; /* XXX */
2746         char *op = optbuf;
2747         int opleft = sizeof(optbuf);
2748         unsigned char *dp = data;
2749
2750         if (code > 255)
2751                 error("option_as_string: bad code %d", code);
2752
2753         for (; dp < data + len; dp++) {
2754                 if (!isascii(*dp) || !isprint(*dp)) {
2755                         if (dp + 1 != data + len || *dp != 0) {
2756                                 snprintf(op, opleft, "\\%03o", *dp);
2757                                 op += 4;
2758                                 opleft -= 4;
2759                         }
2760                 } else if (*dp == '"' || *dp == '\'' || *dp == '$' ||
2761                     *dp == '`' || *dp == '\\') {
2762                         *op++ = '\\';
2763                         *op++ = *dp;
2764                         opleft -= 2;
2765                 } else {
2766                         *op++ = *dp;
2767                         opleft--;
2768                 }
2769         }
2770         if (opleft < 1)
2771                 goto toobig;
2772         *op = 0;
2773         return optbuf;
2774 toobig:
2775         warning("dhcp option too large");
2776         return "<error>";
2777 }
2778
2779 int
2780 fork_privchld(int fd, int fd2)
2781 {
2782         struct pollfd pfd[1];
2783         int nfds;
2784
2785         switch (fork()) {
2786         case -1:
2787                 error("cannot fork");
2788         case 0:
2789                 break;
2790         default:
2791                 return (0);
2792         }
2793
2794         setproctitle("%s [priv]", ifi->name);
2795
2796         setsid();
2797         dup2(nullfd, STDIN_FILENO);
2798         dup2(nullfd, STDOUT_FILENO);
2799         dup2(nullfd, STDERR_FILENO);
2800         close(nullfd);
2801         close(fd2);
2802         close(ifi->rfdesc);
2803         ifi->rfdesc = -1;
2804
2805         for (;;) {
2806                 pfd[0].fd = fd;
2807                 pfd[0].events = POLLIN;
2808                 if ((nfds = poll(pfd, 1, INFTIM)) == -1)
2809                         if (errno != EINTR)
2810                                 error("poll error");
2811
2812                 if (nfds == 0 || !(pfd[0].revents & POLLIN))
2813                         continue;
2814
2815                 dispatch_imsg(ifi, fd);
2816         }
2817 }