Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / contrib / isc-dhcp / client / dhclient.c
1 /* dhclient.c
2
3    DHCP Client. */
4
5 /*
6  * Copyright (c) 1995-2002 Internet Software Consortium.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of Internet Software Consortium nor the names
19  *    of its contributors may be used to endorse or promote products derived
20  *    from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
23  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
27  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  * This code is based on the original client state machine that was
37  * written by Elliot Poger.  The code has been extensively hacked on
38  * by Ted Lemon since then, so any mistakes you find are probably his
39  * fault and not Elliot's.
40  *
41  * @(#) Copyright (c) 1995-2002 Internet Software Consortium.  All rights reserved.";
42  * $Id: dhclient.c,v 1.129.2.12 2002/11/07 23:26:38 dhankins Exp $
43  * $FreeBSD: src/contrib/isc-dhcp/client/dhclient.c,v 1.9.2.8 2003/03/23 23:33:05 mbr Exp $
44  * $DragonFly: src/contrib/isc-dhcp/client/Attic/dhclient.c,v 1.2 2003/06/17 04:24:02 dillon Exp $
45  */
46
47 static char ocopyright[] = "$Id: dhclient.c,v 1.129.2.12 2002/11/07 23:26:38 dhankins Exp $ Copyright (c) 1995-2002 Internet Software Consortium.  All rights reserved.";
48
49 #include "dhcpd.h"
50 #include "version.h"
51
52 TIME cur_time;
53 TIME default_lease_time = 43200; /* 12 hours... */
54 TIME max_lease_time = 86400; /* 24 hours... */
55
56 const char *path_dhclient_conf = _PATH_DHCLIENT_CONF;
57 const char *path_dhclient_db = _PATH_DHCLIENT_DB;
58 const char *path_dhclient_pid = _PATH_DHCLIENT_PID;
59 static char path_dhclient_script_array [] = _PATH_DHCLIENT_SCRIPT;
60 char *path_dhclient_script = path_dhclient_script_array;
61
62 int dhcp_max_agent_option_packet_length = 0;
63
64 int interfaces_requested = 0;
65
66 struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } };
67 struct iaddr iaddr_any = { 4, { 0, 0, 0, 0 } };
68 struct in_addr inaddr_any;
69 struct sockaddr_in sockaddr_broadcast;
70 struct in_addr giaddr;
71
72 /* ASSERT_STATE() does nothing now; it used to be
73    assert (state_is == state_shouldbe). */
74 #define ASSERT_STATE(state_is, state_shouldbe) {}
75
76 static char copyright[] = "Copyright 1995-2002 Internet Software Consortium.";
77 static char arr [] = "All rights reserved.";
78 static char message [] = "Internet Software Consortium DHCP Client";
79 static char url [] = "For info, please visit http://www.isc.org/products/DHCP";
80
81 u_int16_t local_port=0;
82 u_int16_t remote_port=0;
83 int no_daemon=0;
84 struct string_list *client_env=NULL;
85 int client_env_count=0;
86 int onetry=0;
87 int quiet=1;
88 int nowait=0;
89
90 static void usage PROTO ((void));
91
92 void do_release(struct client_state *);
93
94 int main (argc, argv, envp)
95         int argc;
96         char **argv, **envp;
97 {
98         int i, e;
99         struct servent *ent;
100         struct interface_info *ip;
101         struct client_state *client;
102         unsigned seed;
103         char *server = (char *)0;
104         char *relay = (char *)0;
105         isc_result_t status;
106         int release_mode = 0;
107         omapi_object_t *listener;
108         isc_result_t result;
109         int persist = 0;
110         int omapi_port;
111         int no_dhclient_conf = 0;
112         int no_dhclient_db = 0;
113         int no_dhclient_pid = 0;
114         int no_dhclient_script = 0;
115         FILE *pidfd;
116         pid_t oldpid;
117         char *s;
118
119         oldpid = 0;
120         /* Make sure we have stdin, stdout and stderr. */
121         i = open ("/dev/null", O_RDWR);
122         if (i == 0)
123                 i = open ("/dev/null", O_RDWR);
124         if (i == 1) {
125                 i = open ("/dev/null", O_RDWR);
126                 log_perror = 0; /* No sense logging to /dev/null. */
127         } else if (i != -1)
128                 close (i);
129
130 #ifdef SYSLOG_4_2
131         openlog ("dhclient", LOG_NDELAY);
132         log_priority = LOG_DAEMON;
133 #else
134         openlog ("dhclient", LOG_NDELAY, LOG_DAEMON);
135 #endif
136
137 #if !(defined (DEBUG) || defined (SYSLOG_4_2) || defined (__CYGWIN32__))
138         setlogmask (LOG_UPTO (LOG_INFO));
139 #endif  
140
141         /* Set up the OMAPI. */
142         status = omapi_init ();
143         if (status != ISC_R_SUCCESS)
144                 log_fatal ("Can't initialize OMAPI: %s",
145                            isc_result_totext (status));
146
147         /* Set up the OMAPI wrappers for various server database internal
148            objects. */
149         dhcp_common_objects_setup ();
150
151         dhcp_interface_discovery_hook = dhclient_interface_discovery_hook;
152         dhcp_interface_shutdown_hook = dhclient_interface_shutdown_hook;
153         dhcp_interface_startup_hook = dhclient_interface_startup_hook;
154
155         for (i = 1; i < argc; i++) {
156                 if (!strcmp (argv [i], "-r")) {
157                         release_mode = 1;
158                         no_daemon = 1;
159                 } else if (!strcmp (argv [i], "-p")) {
160                         if (++i == argc)
161                                 usage ();
162                         local_port = htons (atoi (argv [i]));
163                         log_debug ("binding to user-specified port %d",
164                                ntohs (local_port));
165                 } else if (!strcmp (argv [i], "-d")) {
166                         no_daemon = 1;
167                 } else if (!strcmp (argv [i], "-pf")) {
168                         if (++i == argc)
169                                 usage ();
170                         path_dhclient_pid = argv [i];
171                         no_dhclient_pid = 1;
172                 } else if (!strcmp (argv [i], "-cf")) {
173                         if (++i == argc)
174                                 usage ();
175                         path_dhclient_conf = argv [i];
176                         no_dhclient_conf = 1;
177                 } else if (!strcmp (argv [i], "-lf")) {
178                         if (++i == argc)
179                                 usage ();
180                         path_dhclient_db = argv [i];
181                         no_dhclient_db = 1;
182                 } else if (!strcmp (argv [i], "-sf")) {
183                         if (++i == argc)
184                                 usage ();
185                         path_dhclient_script = argv [i];
186                         no_dhclient_script = 1;
187                 } else if (!strcmp (argv [i], "-1")) {
188                         onetry = 1;
189                 } else if (!strcmp (argv [i], "-q")) {
190                         quiet = 1;
191                         quiet_interface_discovery = 1;
192                 } else if (!strcmp (argv [i], "-s")) {
193                         if (++i == argc)
194                                 usage ();
195                         server = argv [i];
196                 } else if (!strcmp (argv [i], "-g")) {
197                         if (++i == argc)
198                                 usage ();
199                         relay = argv [i];
200                 } else if (!strcmp (argv [i], "-n")) {
201                         /* do not start up any interfaces */
202                         interfaces_requested = 1;
203                 } else if (!strcmp (argv [i], "-w")) {
204                         /* do not exit if there are no broadcast interfaces. */
205                         persist = 1;
206                 } else if (!strcmp (argv [i], "-e")) {
207                         struct string_list *tmp;
208                         if (++i == argc)
209                                 usage ();
210                         tmp = dmalloc (strlen (argv [i]) + sizeof *tmp, MDL);
211                         if (!tmp)
212                                 log_fatal ("No memory for %s", argv [i]);
213                         strcpy (tmp -> string, argv [i]);
214                         tmp -> next = client_env;
215                         client_env = tmp;
216                         client_env_count++;
217                 } else if (!strcmp (argv [i], "--version")) {
218                         log_info ("isc-dhclient-%s", DHCP_VERSION);
219                         exit (0);
220                 } else if (!strcmp (argv [i], "-nw")) {
221                         nowait = 1;
222                 } else if (argv [i][0] == '-') {
223                     usage ();
224                 } else {
225                     struct interface_info *tmp = (struct interface_info *)0;
226                     status = interface_allocate (&tmp, MDL);
227                     if (status != ISC_R_SUCCESS)
228                         log_fatal ("Can't record interface %s:%s",
229                                    argv [i], isc_result_totext (status));
230                     if (strlen (argv [i]) > sizeof tmp -> name)
231                             log_fatal ("%s: interface name too long (max %ld)",
232                                        argv [i], (long)strlen (argv [i]));
233                     strlcpy (tmp -> name, argv [i], IFNAMSIZ);
234                     if (interfaces) {
235                             interface_reference (&tmp -> next,
236                                                  interfaces, MDL);
237                             interface_dereference (&interfaces, MDL);
238                     }
239                     interface_reference (&interfaces, tmp, MDL);
240                     tmp -> flags = INTERFACE_REQUESTED;
241                     interfaces_requested = 1;
242                 }
243         }
244
245         if (!no_dhclient_conf && (s = getenv ("PATH_DHCLIENT_CONF"))) {
246                 path_dhclient_conf = s;
247         }
248         if (!no_dhclient_db && (s = getenv ("PATH_DHCLIENT_DB"))) {
249                 path_dhclient_db = s;
250         }
251         if (!no_dhclient_pid && (s = getenv ("PATH_DHCLIENT_PID"))) {
252                 path_dhclient_pid = s;
253         }
254         if (!no_dhclient_script && (s = getenv ("PATH_DHCLIENT_SCRIPT"))) {
255                 path_dhclient_script = s;
256         }
257
258         /* first kill of any currently running client */
259         if (release_mode) {
260
261                 if ((pidfd = fopen(path_dhclient_pid, "r")) != NULL) {
262                         e = fscanf(pidfd, "%d", &oldpid);
263
264                         if (e != 0 && e != EOF) {
265                                 if (oldpid) {
266                                         if (kill(oldpid, SIGKILL) == 0)
267                                                 unlink(path_dhclient_pid);
268                                 }
269                         }
270                         fclose(pidfd);
271                 }
272         }
273
274         if (!quiet) {
275                 log_info ("%s %s", message, DHCP_VERSION);
276                 log_info (copyright);
277                 log_info (arr);
278                 log_info (url);
279                 log_info ("%s", "");
280         } else
281                 log_perror = 0;
282
283         /* If we're given a relay agent address to insert, for testing
284            purposes, figure out what it is. */
285         if (relay) {
286                 if (!inet_aton (relay, &giaddr)) {
287                         struct hostent *he;
288                         he = gethostbyname (relay);
289                         if (he) {
290                                 memcpy (&giaddr, he -> h_addr_list [0],
291                                         sizeof giaddr);
292                         } else {
293                                 log_fatal ("%s: no such host", relay);
294                         }
295                 }
296         }
297
298         /* Default to the DHCP/BOOTP port. */
299         if (!local_port) {
300                 /* If we're faking a relay agent, and we're not using loopback,
301                    use the server port, not the client port. */
302                 if (relay && giaddr.s_addr != htonl (INADDR_LOOPBACK)) {
303                         local_port = htons(67);
304                 } else {
305                         ent = getservbyname ("dhcpc", "udp");
306                         if (!ent)
307                                 local_port = htons (68);
308                         else
309                                 local_port = ent -> s_port;
310 #ifndef __CYGWIN32__
311                         endservent ();
312 #endif
313                 }
314         }
315
316         /* If we're faking a relay agent, and we're not using loopback,
317            we're using the server port, not the client port. */
318         if (relay && giaddr.s_addr != htonl (INADDR_LOOPBACK)) {
319                 remote_port = local_port;
320         } else
321                 remote_port = htons (ntohs (local_port) - 1);   /* XXX */
322
323         /* Get the current time... */
324         GET_TIME (&cur_time);
325
326         sockaddr_broadcast.sin_family = AF_INET;
327         sockaddr_broadcast.sin_port = remote_port;
328         if (server) {
329                 if (!inet_aton (server, &sockaddr_broadcast.sin_addr)) {
330                         struct hostent *he;
331                         he = gethostbyname (server);
332                         if (he) {
333                                 memcpy (&sockaddr_broadcast.sin_addr,
334                                         he -> h_addr_list [0],
335                                         sizeof sockaddr_broadcast.sin_addr);
336                         } else
337                                 sockaddr_broadcast.sin_addr.s_addr =
338                                         INADDR_BROADCAST;
339                 }
340         } else {
341                 sockaddr_broadcast.sin_addr.s_addr = INADDR_BROADCAST;
342         }
343
344         inaddr_any.s_addr = INADDR_ANY;
345
346         /* Discover all the network interfaces. */
347         discover_interfaces (DISCOVER_UNCONFIGURED);
348
349         /* Parse the dhclient.conf file. */
350         read_client_conf ();
351
352         /* Parse the lease database. */
353         read_client_leases ();
354
355         /* Rewrite the lease database... */
356         rewrite_client_leases ();
357
358         /* XXX */
359 /*      config_counter(&snd_counter, &rcv_counter); */
360
361         /* If no broadcast interfaces were discovered, call the script
362            and tell it so. */
363         if (!interfaces) {
364                 /* Call dhclient-script with the NBI flag, in case somebody
365                    cares. */
366                 script_init ((struct client_state *)0, "NBI",
367                              (struct string_list *)0);
368                 script_go ((struct client_state *)0);
369
370                 /* If we haven't been asked to persist, waiting for new
371                    interfaces, then just exit. */
372                 if (!persist) {
373                         /* Nothing more to do. */
374                         log_info ("No broadcast interfaces found - exiting.");
375                         exit (0);
376                 }
377         } else if (!release_mode) {
378                 /* Call the script with the list of interfaces. */
379                 for (ip = interfaces; ip; ip = ip -> next) {
380                         /* If interfaces were specified, don't configure
381                            interfaces that weren't specified! */
382                         if (interfaces_requested &&
383                             ((ip -> flags & (INTERFACE_REQUESTED |
384                                              INTERFACE_AUTOMATIC)) !=
385                              INTERFACE_REQUESTED))
386                                 continue;
387                         script_init (ip -> client,
388                                      "PREINIT", (struct string_list *)0);
389                         if (ip -> client -> alias)
390                                 script_write_params (ip -> client, "alias_",
391                                                      ip -> client -> alias);
392                         script_go (ip -> client);
393                 }
394         }
395
396         /* At this point, all the interfaces that the script thinks
397            are relevant should be running, so now we once again call
398            discover_interfaces(), and this time ask it to actually set
399            up the interfaces. */
400         discover_interfaces (interfaces_requested
401                              ? DISCOVER_REQUESTED
402                              : DISCOVER_RUNNING);
403
404         /* Make up a seed for the random number generator from current
405            time plus the sum of the last four bytes of each
406            interface's hardware address interpreted as an integer.
407            Not much entropy, but we're booting, so we're not likely to
408            find anything better. */
409         seed = 0;
410         for (ip = interfaces; ip; ip = ip -> next) {
411                 int junk;
412                 memcpy (&junk,
413                         &ip -> hw_address.hbuf [ip -> hw_address.hlen -
414                                                sizeof seed], sizeof seed);
415                 seed += junk;
416         }
417         srandom (seed + cur_time);
418
419         /* Start a configuration state machine for each interface. */
420         for (ip = interfaces; ip; ip = ip -> next) {
421                 ip -> flags |= INTERFACE_RUNNING;
422                 for (client = ip -> client; client; client = client -> next) {
423                         if (release_mode)
424                                 do_release (client);
425                         else {
426                                 client -> state = S_INIT;
427                                 /* Set up a timeout to start the initialization
428                                    process. */
429                                 add_timeout (cur_time + random () % 5,
430                                              state_reboot, client, 0, 0);
431                         }
432                 }
433         }
434
435         if (release_mode)
436                 return 0;
437
438         /* Start up a listener for the object management API protocol. */
439         if (top_level_config.omapi_port != -1) {
440                 listener = (omapi_object_t *)0;
441                 result = omapi_generic_new (&listener, MDL);
442                 if (result != ISC_R_SUCCESS)
443                         log_fatal ("Can't allocate new generic object: %s\n",
444                                    isc_result_totext (result));
445                 result = omapi_protocol_listen (listener,
446                                                 (unsigned)
447                                                 top_level_config.omapi_port,
448                                                 1);
449                 if (result != ISC_R_SUCCESS)
450                         log_fatal ("Can't start OMAPI protocol: %s",
451                                    isc_result_totext (result));
452         }
453
454         /* Set up the bootp packet handler... */
455         bootp_packet_handler = do_packet;
456
457 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
458                 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
459         dmalloc_cutoff_generation = dmalloc_generation;
460         dmalloc_longterm = dmalloc_outstanding;
461         dmalloc_outstanding = 0;
462 #endif
463
464         /* If we're not supposed to wait before getting the address,
465            don't. */
466         if (nowait)
467                 go_daemon ();
468
469         /* If we're not going to daemonize, write the pid file
470            now. */
471         if (no_daemon || nowait)
472                 write_client_pid_file ();
473
474         /* Start dispatching packets and timeouts... */
475         dispatch ();
476
477         /*NOTREACHED*/
478         return 0;
479 }
480
481 static void usage ()
482 {
483         log_info ("%s %s", message, DHCP_VERSION);
484         log_info (copyright);
485         log_info (arr);
486         log_info (url);
487
488         log_error ("Usage: dhclient [-1Ddqr] [-nw] [-p <port>] %s",
489                    "[-s server]");
490         log_error ("                [-cf config-file] [-lf lease-file]%s",
491                    "[-pf pid-file] [-e VAR=val]");
492         log_fatal ("                [-sf script-file] [interface]");
493 }
494
495 isc_result_t find_class (struct class **c,
496                 const char *s, const char *file, int line)
497 {
498         return 0;
499 }
500
501 int check_collection (packet, lease, collection)
502         struct packet *packet;
503         struct lease *lease;
504         struct collection *collection;
505 {
506         return 0;
507 }
508
509 void classify (packet, class)
510         struct packet *packet;
511         struct class *class;
512 {
513 }
514
515 int unbill_class (lease, class)
516         struct lease *lease;
517         struct class *class;
518 {
519         return 0;
520 }
521
522 int find_subnet (struct subnet **sp,
523                  struct iaddr addr, const char *file, int line)
524 {
525         return 0;
526 }
527
528 /* Individual States:
529  * 
530  * Each routine is called from the dhclient_state_machine() in one of
531  * these conditions:
532  * -> entering INIT state
533  * -> recvpacket_flag == 0: timeout in this state
534  * -> otherwise: received a packet in this state
535  *
536  * Return conditions as handled by dhclient_state_machine():
537  * Returns 1, sendpacket_flag = 1: send packet, reset timer.
538  * Returns 1, sendpacket_flag = 0: just reset the timer (wait for a milestone).
539  * Returns 0: finish the nap which was interrupted for no good reason.
540  *
541  * Several per-interface variables are used to keep track of the process:
542  *   active_lease: the lease that is being used on the interface
543  *                 (null pointer if not configured yet).
544  *   offered_leases: leases corresponding to DHCPOFFER messages that have
545  *                   been sent to us by DHCP servers.
546  *   acked_leases: leases corresponding to DHCPACK messages that have been
547  *                 sent to us by DHCP servers.
548  *   sendpacket: DHCP packet we're trying to send.
549  *   destination: IP address to send sendpacket to
550  * In addition, there are several relevant per-lease variables.
551  *   T1_expiry, T2_expiry, lease_expiry: lease milestones
552  * In the active lease, these control the process of renewing the lease;
553  * In leases on the acked_leases list, this simply determines when we
554  * can no longer legitimately use the lease.
555  */
556
557 void state_reboot (cpp)
558         void *cpp;
559 {
560         struct client_state *client = cpp;
561
562         /* If we don't remember an active lease, go straight to INIT. */
563         if (!client -> active ||
564             client -> active -> is_bootp ||
565             client -> active -> expiry <= cur_time) {
566                 state_init (client);
567                 return;
568         }
569
570         /* We are in the rebooting state. */
571         client -> state = S_REBOOTING;
572
573         /* make_request doesn't initialize xid because it normally comes
574            from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
575            so pick an xid now. */
576         client -> xid = random ();
577
578         /* Make a DHCPREQUEST packet, and set appropriate per-interface
579            flags. */
580         make_request (client, client -> active);
581         client -> destination = iaddr_broadcast;
582         client -> first_sending = cur_time;
583         client -> interval = client -> config -> initial_interval;
584
585         /* Zap the medium list... */
586         client -> medium = (struct string_list *)0;
587
588         /* Send out the first DHCPREQUEST packet. */
589         send_request (client);
590 }
591
592 /* Called when a lease has completely expired and we've been unable to
593    renew it. */
594
595 void state_init (cpp)
596         void *cpp;
597 {
598         struct client_state *client = cpp;
599
600         ASSERT_STATE(state, S_INIT);
601
602         /* Make a DHCPDISCOVER packet, and set appropriate per-interface
603            flags. */
604         make_discover (client, client -> active);
605         client -> xid = client -> packet.xid;
606         client -> destination = iaddr_broadcast;
607         client -> state = S_SELECTING;
608         client -> first_sending = cur_time;
609         client -> interval = client -> config -> initial_interval;
610
611         /* Add an immediate timeout to cause the first DHCPDISCOVER packet
612            to go out. */
613         send_discover (client);
614 }
615
616 /* state_selecting is called when one or more DHCPOFFER packets have been
617    received and a configurable period of time has passed. */
618
619 void state_selecting (cpp)
620         void *cpp;
621 {
622         struct client_state *client = cpp;
623         struct client_lease *lp, *next, *picked;
624
625
626         ASSERT_STATE(state, S_SELECTING);
627
628         /* Cancel state_selecting and send_discover timeouts, since either
629            one could have got us here. */
630         cancel_timeout (state_selecting, client);
631         cancel_timeout (send_discover, client);
632
633         /* We have received one or more DHCPOFFER packets.   Currently,
634            the only criterion by which we judge leases is whether or
635            not we get a response when we arp for them. */
636         picked = (struct client_lease *)0;
637         for (lp = client -> offered_leases; lp; lp = next) {
638                 next = lp -> next;
639
640                 /* Check to see if we got an ARPREPLY for the address
641                    in this particular lease. */
642                 if (!picked) {
643                         picked = lp;
644                         picked -> next = (struct client_lease *)0;
645                 } else {
646                       freeit:
647                         destroy_client_lease (lp);
648                 }
649         }
650         client -> offered_leases = (struct client_lease *)0;
651
652         /* If we just tossed all the leases we were offered, go back
653            to square one. */
654         if (!picked) {
655                 client -> state = S_INIT;
656                 state_init (client);
657                 return;
658         }
659
660         /* If it was a BOOTREPLY, we can just take the address right now. */
661         if (picked -> is_bootp) {
662                 client -> new = picked;
663
664                 /* Make up some lease expiry times
665                    XXX these should be configurable. */
666                 client -> new -> expiry = cur_time + 12000;
667                 client -> new -> renewal += cur_time + 8000;
668                 client -> new -> rebind += cur_time + 10000;
669
670                 client -> state = S_REQUESTING;
671
672                 /* Bind to the address we received. */
673                 bind_lease (client);
674                 return;
675         }
676
677         /* Go to the REQUESTING state. */
678         client -> destination = iaddr_broadcast;
679         client -> state = S_REQUESTING;
680         client -> first_sending = cur_time;
681         client -> interval = client -> config -> initial_interval;
682
683         /* Make a DHCPREQUEST packet from the lease we picked. */
684         make_request (client, picked);
685         client -> xid = client -> packet.xid;
686
687         /* Toss the lease we picked - we'll get it back in a DHCPACK. */
688         destroy_client_lease (picked);
689
690         /* Add an immediate timeout to send the first DHCPREQUEST packet. */
691         send_request (client);
692 }  
693
694 /* state_requesting is called when we receive a DHCPACK message after
695    having sent out one or more DHCPREQUEST packets. */
696
697 void dhcpack (packet)
698         struct packet *packet;
699 {
700         struct interface_info *ip = packet -> interface;
701         struct client_state *client;
702         struct client_lease *lease;
703         struct option_cache *oc;
704         struct data_string ds;
705         int i;
706         
707         /* If we're not receptive to an offer right now, or if the offer
708            has an unrecognizable transaction id, then just drop it. */
709         for (client = ip -> client; client; client = client -> next) {
710                 if (client -> xid == packet -> raw -> xid)
711                         break;
712         }
713         if (!client ||
714             (packet -> interface -> hw_address.hlen - 1 !=
715              packet -> raw -> hlen) ||
716             (memcmp (&packet -> interface -> hw_address.hbuf [1],
717                      packet -> raw -> chaddr, packet -> raw -> hlen))) {
718 #if defined (DEBUG)
719                 log_debug ("DHCPACK in wrong transaction.");
720 #endif
721                 return;
722         }
723
724         if (client -> state != S_REBOOTING &&
725             client -> state != S_REQUESTING &&
726             client -> state != S_RENEWING &&
727             client -> state != S_REBINDING) {
728 #if defined (DEBUG)
729                 log_debug ("DHCPACK in wrong state.");
730 #endif
731                 return;
732         }
733
734         log_info ("DHCPACK from %s", piaddr (packet -> client_addr));
735
736         lease = packet_to_lease (packet, client);
737         if (!lease) {
738                 log_info ("packet_to_lease failed.");
739                 return;
740         }
741
742         client -> new = lease;
743
744         /* Stop resending DHCPREQUEST. */
745         cancel_timeout (send_request, client);
746
747         /* Figure out the lease time. */
748         oc = lookup_option (&dhcp_universe, client -> new -> options,
749                             DHO_DHCP_LEASE_TIME);
750         memset (&ds, 0, sizeof ds);
751         if (oc &&
752             evaluate_option_cache (&ds, packet, (struct lease *)0, client,
753                                    packet -> options, client -> new -> options,
754                                    &global_scope, oc, MDL)) {
755                 if (ds.len > 3)
756                         client -> new -> expiry = getULong (ds.data);
757                 else
758                         client -> new -> expiry = 0;
759                 data_string_forget (&ds, MDL);
760         } else
761                         client -> new -> expiry = 0;
762
763         if (!client -> new -> expiry) {
764                 log_error ("no expiry time on offered lease.");
765                 /* XXX this is going to be bad - if this _does_
766                    XXX happen, we should probably dynamically 
767                    XXX disqualify the DHCP server that gave us the
768                    XXX bad packet from future selections and
769                    XXX then go back into the init state. */
770                 state_init (client);
771                 return;
772         }
773
774         /* A number that looks negative here is really just very large,
775            because the lease expiry offset is unsigned. */
776         if (client -> new -> expiry < 0)
777                 client -> new -> expiry = TIME_MAX;
778         /* Take the server-provided renewal time if there is one. */
779         oc = lookup_option (&dhcp_universe, client -> new -> options,
780                             DHO_DHCP_RENEWAL_TIME);
781         if (oc &&
782             evaluate_option_cache (&ds, packet, (struct lease *)0, client,
783                                    packet -> options, client -> new -> options,
784                                    &global_scope, oc, MDL)) {
785                 if (ds.len > 3)
786                         client -> new -> renewal = getULong (ds.data);
787                 else
788                         client -> new -> renewal = 0;
789                 data_string_forget (&ds, MDL);
790         } else
791                         client -> new -> renewal = 0;
792
793         /* If it wasn't specified by the server, calculate it. */
794         if (!client -> new -> renewal)
795                 client -> new -> renewal =
796                         client -> new -> expiry / 2;
797
798         /* Now introduce some randomness to the renewal time: */
799         client -> new -> renewal = (((client -> new -> renewal + 3) * 3 / 4) +
800                                     (random () % /* XXX NUMS */
801                                      ((client -> new -> renewal + 3) / 4)));
802
803         /* Same deal with the rebind time. */
804         oc = lookup_option (&dhcp_universe, client -> new -> options,
805                             DHO_DHCP_REBINDING_TIME);
806         if (oc &&
807             evaluate_option_cache (&ds, packet, (struct lease *)0, client,
808                                    packet -> options, client -> new -> options,
809                                    &global_scope, oc, MDL)) {
810                 if (ds.len > 3)
811                         client -> new -> rebind = getULong (ds.data);
812                 else
813                         client -> new -> rebind = 0;
814                 data_string_forget (&ds, MDL);
815         } else
816                         client -> new -> rebind = 0;
817
818         if (!client -> new -> rebind)
819                 client -> new -> rebind =
820                         (client -> new -> expiry * 7) / 8; /* XXX NUMS */
821
822         /* Make sure our randomness didn't run the renewal time past the
823            rebind time. */
824         if (client -> new -> renewal > client -> new -> rebind)
825                 client -> new -> renewal = (client -> new -> rebind * 3) / 4;
826
827         client -> new -> expiry += cur_time;
828         /* Lease lengths can never be negative. */
829         if (client -> new -> expiry < cur_time)
830                 client -> new -> expiry = TIME_MAX;
831         client -> new -> renewal += cur_time;
832         if (client -> new -> renewal < cur_time)
833                 client -> new -> renewal = TIME_MAX;
834         client -> new -> rebind += cur_time;
835         if (client -> new -> rebind < cur_time)
836                 client -> new -> rebind = TIME_MAX;
837
838         bind_lease (client);
839 }
840
841 void bind_lease (client)
842         struct client_state *client;
843 {
844         struct interface_info *ip = client -> interface;
845
846         /* Remember the medium. */
847         client -> new -> medium = client -> medium;
848
849         /* Run the client script with the new parameters. */
850         script_init (client, (client -> state == S_REQUESTING
851                           ? "BOUND"
852                           : (client -> state == S_RENEWING
853                              ? "RENEW"
854                              : (client -> state == S_REBOOTING
855                                 ? "REBOOT" : "REBIND"))),
856                      client -> new -> medium);
857         if (client -> active && client -> state != S_REBOOTING)
858                 script_write_params (client, "old_", client -> active);
859         script_write_params (client, "new_", client -> new);
860         if (client -> alias)
861                 script_write_params (client, "alias_", client -> alias);
862
863         /* If the BOUND/RENEW code detects another machine using the
864            offered address, it exits nonzero.  We need to send a
865            DHCPDECLINE and toss the lease. */
866         if (script_go (client)) {
867                 make_decline (client, client -> new);
868                 send_decline (client);
869                 destroy_client_lease (client -> new);
870                 client -> new = (struct client_lease *)0;
871                 state_init (client);
872                 return;
873         }
874
875         /* Write out the new lease. */
876         write_client_lease (client, client -> new, 0, 0);
877
878         /* Replace the old active lease with the new one. */
879         if (client -> active)
880                 destroy_client_lease (client -> active);
881         client -> active = client -> new;
882         client -> new = (struct client_lease *)0;
883
884         /* Set up a timeout to start the renewal process. */
885         add_timeout (client -> active -> renewal,
886                      state_bound, client, 0, 0);
887
888         log_info ("bound to %s -- renewal in %ld seconds.",
889               piaddr (client -> active -> address),
890               (long)(client -> active -> renewal - cur_time));
891         client -> state = S_BOUND;
892         reinitialize_interfaces ();
893         go_daemon ();
894         if (client -> config -> do_forward_update) {
895                 client -> dns_update_timeout = 1;
896                 add_timeout (cur_time + 1, client_dns_update_timeout,
897                              client, 0, 0);
898         }
899 }  
900
901 /* state_bound is called when we've successfully bound to a particular
902    lease, but the renewal time on that lease has expired.   We are
903    expected to unicast a DHCPREQUEST to the server that gave us our
904    original lease. */
905
906 void state_bound (cpp)
907         void *cpp;
908 {
909         struct client_state *client = cpp;
910         int i;
911         struct option_cache *oc;
912         struct data_string ds;
913
914         ASSERT_STATE(state, S_BOUND);
915
916         /* T1 has expired. */
917         make_request (client, client -> active);
918         client -> xid = client -> packet.xid;
919
920         memset (&ds, 0, sizeof ds);
921         oc = lookup_option (&dhcp_universe, client -> active -> options,
922                             DHO_DHCP_SERVER_IDENTIFIER);
923         if (oc &&
924             evaluate_option_cache (&ds, (struct packet *)0, (struct lease *)0,
925                                    client, (struct option_state *)0,
926                                    client -> active -> options,
927                                    &global_scope, oc, MDL)) {
928                 if (ds.len > 3) {
929                         memcpy (client -> destination.iabuf, ds.data, 4);
930                         client -> destination.len = 4;
931                 } else
932                         client -> destination = iaddr_broadcast;
933         } else
934                 client -> destination = iaddr_broadcast;
935
936         client -> first_sending = cur_time;
937         client -> interval = client -> config -> initial_interval;
938         client -> state = S_RENEWING;
939
940         /* Send the first packet immediately. */
941         send_request (client);
942 }  
943
944 /* state_stop is called when we've been told to shut down.   We unconfigure
945    the interfaces, and then stop operating until told otherwise. */
946
947 void state_stop (cpp)
948         void *cpp;
949 {
950         struct client_state *client = cpp;
951         int i;
952
953         /* Cancel all timeouts. */
954         cancel_timeout (state_selecting, client);
955         cancel_timeout (send_discover, client);
956         cancel_timeout (send_request, client);
957         cancel_timeout (state_bound, client);
958
959         /* If we have an address, unconfigure it. */
960         if (client -> active) {
961                 script_init (client, "STOP", client -> active -> medium);
962                 script_write_params (client, "old_", client -> active);
963                 if (client -> alias)
964                         script_write_params (client, "alias_",
965                                              client -> alias);
966                 script_go (client);
967         }
968 }  
969
970 int commit_leases ()
971 {
972         return 0;
973 }
974
975 int write_lease (lease)
976         struct lease *lease;
977 {
978         return 0;
979 }
980
981 int write_host (host)
982         struct host_decl *host;
983 {
984         return 0;
985 }
986
987 void db_startup (testp)
988         int testp;
989 {
990 }
991
992 void bootp (packet)
993         struct packet *packet;
994 {
995         struct iaddrlist *ap;
996
997         if (packet -> raw -> op != BOOTREPLY)
998                 return;
999
1000         /* If there's a reject list, make sure this packet's sender isn't
1001            on it. */
1002         for (ap = packet -> interface -> client -> config -> reject_list;
1003              ap; ap = ap -> next) {
1004                 if (addr_eq (packet -> client_addr, ap -> addr)) {
1005                         log_info ("BOOTREPLY from %s rejected.",
1006                               piaddr (ap -> addr));
1007                         return;
1008                 }
1009         }
1010         
1011         dhcpoffer (packet);
1012
1013 }
1014
1015 void dhcp (packet)
1016         struct packet *packet;
1017 {
1018         struct iaddrlist *ap;
1019         void (*handler) PROTO ((struct packet *));
1020         const char *type;
1021
1022         switch (packet -> packet_type) {
1023               case DHCPOFFER:
1024                 handler = dhcpoffer;
1025                 type = "DHCPOFFER";
1026                 break;
1027
1028               case DHCPNAK:
1029                 handler = dhcpnak;
1030                 type = "DHCPNACK";
1031                 break;
1032
1033               case DHCPACK:
1034                 handler = dhcpack;
1035                 type = "DHCPACK";
1036                 break;
1037
1038               default:
1039                 return;
1040         }
1041
1042         /* If there's a reject list, make sure this packet's sender isn't
1043            on it. */
1044         for (ap = packet -> interface -> client -> config -> reject_list;
1045              ap; ap = ap -> next) {
1046                 if (addr_eq (packet -> client_addr, ap -> addr)) {
1047                         log_info ("%s from %s rejected.",
1048                               type, piaddr (ap -> addr));
1049                         return;
1050                 }
1051         }
1052         (*handler) (packet);
1053 }
1054
1055 void dhcpoffer (packet)
1056         struct packet *packet;
1057 {
1058         struct interface_info *ip = packet -> interface;
1059         struct client_state *client;
1060         struct client_lease *lease, *lp;
1061         int i;
1062         int stop_selecting;
1063         const char *name = packet -> packet_type ? "DHCPOFFER" : "BOOTREPLY";
1064         struct iaddrlist *ap;
1065         struct option_cache *oc;
1066         char obuf [1024];
1067         
1068 #ifdef DEBUG_PACKET
1069         dump_packet (packet);
1070 #endif  
1071
1072         /* Find a client state that matches the xid... */
1073         for (client = ip -> client; client; client = client -> next)
1074                 if (client -> xid == packet -> raw -> xid)
1075                         break;
1076
1077         /* If we're not receptive to an offer right now, or if the offer
1078            has an unrecognizable transaction id, then just drop it. */
1079         if (!client ||
1080             client -> state != S_SELECTING ||
1081             (packet -> interface -> hw_address.hlen - 1 !=
1082              packet -> raw -> hlen) ||
1083             (memcmp (&packet -> interface -> hw_address.hbuf [1],
1084                      packet -> raw -> chaddr, packet -> raw -> hlen))) {
1085 #if defined (DEBUG)
1086                 log_debug ("%s in wrong transaction.", name);
1087 #endif
1088                 return;
1089         }
1090
1091         sprintf (obuf, "%s from %s", name, piaddr (packet -> client_addr));
1092
1093
1094         /* If this lease doesn't supply the minimum required parameters,
1095            blow it off. */
1096         if (client -> config -> required_options) {
1097             for (i = 0; client -> config -> required_options [i]; i++) {
1098                 if (!lookup_option
1099                     (&dhcp_universe, packet -> options,
1100                      client -> config -> required_options [i])) {
1101                     log_info ("%s: no %s option.",
1102                               obuf, (dhcp_universe.options
1103                                      [client -> config -> required_options [i]]
1104                                      -> name));
1105                                 return;
1106                         }
1107                 }
1108         }
1109
1110         /* If we've already seen this lease, don't record it again. */
1111         for (lease = client -> offered_leases; lease; lease = lease -> next) {
1112                 if (lease -> address.len == sizeof packet -> raw -> yiaddr &&
1113                     !memcmp (lease -> address.iabuf,
1114                              &packet -> raw -> yiaddr, lease -> address.len)) {
1115                         log_debug ("%s: already seen.", obuf);
1116                         return;
1117                 }
1118         }
1119
1120         lease = packet_to_lease (packet, client);
1121         if (!lease) {
1122                 log_info ("%s: packet_to_lease failed.", obuf);
1123                 return;
1124         }
1125
1126         /* If this lease was acquired through a BOOTREPLY, record that
1127            fact. */
1128         if (!packet -> options_valid || !packet -> packet_type)
1129                 lease -> is_bootp = 1;
1130
1131         /* Record the medium under which this lease was offered. */
1132         lease -> medium = client -> medium;
1133
1134         /* Figure out when we're supposed to stop selecting. */
1135         stop_selecting = (client -> first_sending +
1136                           client -> config -> select_interval);
1137
1138         /* If this is the lease we asked for, put it at the head of the
1139            list, and don't mess with the arp request timeout. */
1140         if (lease -> address.len == client -> requested_address.len &&
1141             !memcmp (lease -> address.iabuf,
1142                      client -> requested_address.iabuf,
1143                      client -> requested_address.len)) {
1144                 lease -> next = client -> offered_leases;
1145                 client -> offered_leases = lease;
1146         } else {
1147                 /* Put the lease at the end of the list. */
1148                 lease -> next = (struct client_lease *)0;
1149                 if (!client -> offered_leases)
1150                         client -> offered_leases = lease;
1151                 else {
1152                         for (lp = client -> offered_leases; lp -> next;
1153                              lp = lp -> next)
1154                                 ;
1155                         lp -> next = lease;
1156                 }
1157         }
1158
1159         /* If the selecting interval has expired, go immediately to
1160            state_selecting().  Otherwise, time out into
1161            state_selecting at the select interval. */
1162         if (stop_selecting <= 0)
1163                 state_selecting (client);
1164         else {
1165                 add_timeout (stop_selecting, state_selecting, client, 0, 0);
1166                 cancel_timeout (send_discover, client);
1167         }
1168         log_info ("%s", obuf);
1169 }
1170
1171 /* Allocate a client_lease structure and initialize it from the parameters
1172    in the specified packet. */
1173
1174 struct client_lease *packet_to_lease (packet, client)
1175         struct packet *packet;
1176         struct client_state *client;
1177 {
1178         struct client_lease *lease;
1179         unsigned i;
1180         struct option_cache *oc;
1181         struct data_string data;
1182
1183         lease = (struct client_lease *)new_client_lease (MDL);
1184
1185         if (!lease) {
1186                 log_error ("packet_to_lease: no memory to record lease.\n");
1187                 return (struct client_lease *)0;
1188         }
1189
1190         memset (lease, 0, sizeof *lease);
1191
1192         /* Copy the lease options. */
1193         option_state_reference (&lease -> options, packet -> options, MDL);
1194
1195         lease -> address.len = sizeof (packet -> raw -> yiaddr);
1196         memcpy (lease -> address.iabuf, &packet -> raw -> yiaddr,
1197                 lease -> address.len);
1198
1199         memset (&data, 0, sizeof data);
1200
1201         if (client -> config -> vendor_space_name) {
1202                 i = DHO_VENDOR_ENCAPSULATED_OPTIONS;
1203
1204                 /* See if there was a vendor encapsulation option. */
1205                 oc = lookup_option (&dhcp_universe, lease -> options, i);
1206                 if (oc &&
1207                     client -> config -> vendor_space_name &&
1208                     evaluate_option_cache (&data, packet,
1209                                            (struct lease *)0, client,
1210                                            packet -> options, lease -> options,
1211                                            &global_scope, oc, MDL)) {
1212                         if (data.len) {
1213                                 parse_encapsulated_suboptions
1214                                         (packet -> options, &dhcp_options [i],
1215                                          data.data, data.len, &dhcp_universe,
1216                                          client -> config -> vendor_space_name
1217                                                 );
1218                         }
1219                         data_string_forget (&data, MDL);
1220                 }
1221         } else
1222                 i = 0;
1223
1224         /* Figure out the overload flag. */
1225         oc = lookup_option (&dhcp_universe, lease -> options,
1226                             DHO_DHCP_OPTION_OVERLOAD);
1227         if (oc &&
1228             evaluate_option_cache (&data, packet, (struct lease *)0, client,
1229                                    packet -> options, lease -> options,
1230                                    &global_scope, oc, MDL)) {
1231                 if (data.len > 0)
1232                         i = data.data [0];
1233                 else
1234                         i = 0;
1235                 data_string_forget (&data, MDL);
1236         } else
1237                 i = 0;
1238
1239         /* If the server name was filled out, copy it. */
1240         if (!(i & 2) && packet -> raw -> sname [0]) {
1241                 unsigned len;
1242                 /* Don't count on the NUL terminator. */
1243                 for (len = 0; len < 64; len++)
1244                         if (!packet -> raw -> sname [len])
1245                                 break;
1246                 lease -> server_name = dmalloc (len + 1, MDL);
1247                 if (!lease -> server_name) {
1248                         log_error ("dhcpoffer: no memory for filename.\n");
1249                         destroy_client_lease (lease);
1250                         return (struct client_lease *)0;
1251                 } else {
1252                         memcpy (lease -> server_name,
1253                                 packet -> raw -> sname, len);
1254                         lease -> server_name [len] = 0;
1255                 }
1256         }
1257
1258         /* Ditto for the filename. */
1259         if (!(i & 1) && packet -> raw -> file [0]) {
1260                 unsigned len;
1261                 /* Don't count on the NUL terminator. */
1262                 for (len = 0; len < 64; len++)
1263                         if (!packet -> raw -> file [len])
1264                                 break;
1265                 lease -> filename = dmalloc (len + 1, MDL);
1266                 if (!lease -> filename) {
1267                         log_error ("dhcpoffer: no memory for filename.\n");
1268                         destroy_client_lease (lease);
1269                         return (struct client_lease *)0;
1270                 } else {
1271                         memcpy (lease -> filename,
1272                                 packet -> raw -> file, len);
1273                         lease -> filename [len] = 0;
1274                 }
1275         }
1276
1277         execute_statements_in_scope ((struct binding_value **)0,
1278                                      (struct packet *)packet,
1279                                      (struct lease *)0, client,
1280                                      lease -> options, lease -> options,
1281                                      &global_scope,
1282                                      client -> config -> on_receipt,
1283                                      (struct group *)0);
1284
1285         return lease;
1286 }       
1287
1288 void dhcpnak (packet)
1289         struct packet *packet;
1290 {
1291         struct interface_info *ip = packet -> interface;
1292         struct client_state *client;
1293
1294         /* Find a client state that matches the xid... */
1295         for (client = ip -> client; client; client = client -> next)
1296                 if (client -> xid == packet -> raw -> xid)
1297                         break;
1298
1299         /* If we're not receptive to an offer right now, or if the offer
1300            has an unrecognizable transaction id, then just drop it. */
1301         if (!client ||
1302             (packet -> interface -> hw_address.hlen - 1 !=
1303              packet -> raw -> hlen) ||
1304             (memcmp (&packet -> interface -> hw_address.hbuf [1],
1305                      packet -> raw -> chaddr, packet -> raw -> hlen))) {
1306 #if defined (DEBUG)
1307                 log_debug ("DHCPNAK in wrong transaction.");
1308 #endif
1309                 return;
1310         }
1311
1312         if (client -> state != S_REBOOTING &&
1313             client -> state != S_REQUESTING &&
1314             client -> state != S_RENEWING &&
1315             client -> state != S_REBINDING) {
1316 #if defined (DEBUG)
1317                 log_debug ("DHCPNAK in wrong state.");
1318 #endif
1319                 return;
1320         }
1321
1322         log_info ("DHCPNAK from %s", piaddr (packet -> client_addr));
1323
1324         if (!client -> active) {
1325 #if defined (DEBUG)
1326                 log_info ("DHCPNAK with no active lease.\n");
1327 #endif
1328                 return;
1329         }
1330
1331         destroy_client_lease (client -> active);
1332         client -> active = (struct client_lease *)0;
1333
1334         /* Stop sending DHCPREQUEST packets... */
1335         cancel_timeout (send_request, client);
1336
1337         client -> state = S_INIT;
1338         state_init (client);
1339 }
1340
1341 /* Send out a DHCPDISCOVER packet, and set a timeout to send out another
1342    one after the right interval has expired.  If we don't get an offer by
1343    the time we reach the panic interval, call the panic function. */
1344
1345 void send_discover (cpp)
1346         void *cpp;
1347 {
1348         struct client_state *client = cpp;
1349
1350         int result;
1351         int interval;
1352         int increase = 1;
1353
1354         /* Figure out how long it's been since we started transmitting. */
1355         interval = cur_time - client -> first_sending;
1356
1357         /* If we're past the panic timeout, call the script and tell it
1358            we haven't found anything for this interface yet. */
1359         if (interval > client -> config -> timeout) {
1360                 state_panic (client);
1361                 return;
1362         }
1363
1364         /* If we're selecting media, try the whole list before doing
1365            the exponential backoff, but if we've already received an
1366            offer, stop looping, because we obviously have it right. */
1367         if (!client -> offered_leases &&
1368             client -> config -> media) {
1369                 int fail = 0;
1370               again:
1371                 if (client -> medium) {
1372                         client -> medium = client -> medium -> next;
1373                         increase = 0;
1374                 } 
1375                 if (!client -> medium) {
1376                         if (fail)
1377                                 log_fatal ("No valid media types for %s!",
1378                                        client -> interface -> name);
1379                         client -> medium =
1380                                 client -> config -> media;
1381                         increase = 1;
1382                 }
1383                         
1384                 log_info ("Trying medium \"%s\" %d",
1385                           client -> medium -> string, increase);
1386                 script_init (client, "MEDIUM", client -> medium);
1387                 if (script_go (client)) {
1388                         fail = 1;
1389                         goto again;
1390                 }
1391         }
1392
1393         /* If we're supposed to increase the interval, do so.  If it's
1394            currently zero (i.e., we haven't sent any packets yet), set
1395            it to one; otherwise, add to it a random number between
1396            zero and two times itself.  On average, this means that it
1397            will double with every transmission. */
1398         if (increase) {
1399                 if (!client -> interval)
1400                         client -> interval =
1401                                 client -> config -> initial_interval;
1402                 else
1403                         client -> interval += ((random () >> 2) %
1404                                                (2 * client -> interval));
1405
1406                 /* Don't backoff past cutoff. */
1407                 if (client -> interval >
1408                     client -> config -> backoff_cutoff)
1409                         client -> interval =
1410                                 ((client -> config -> backoff_cutoff / 2)
1411                                  + ((random () >> 2) %
1412                                     client -> config -> backoff_cutoff));
1413         } else if (!client -> interval)
1414                 client -> interval = client -> config -> initial_interval;
1415                 
1416         /* If the backoff would take us to the panic timeout, just use that
1417            as the interval. */
1418         if (cur_time + client -> interval >
1419             client -> first_sending + client -> config -> timeout)
1420                 client -> interval =
1421                         (client -> first_sending +
1422                          client -> config -> timeout) - cur_time + 1;
1423
1424         /* Record the number of seconds since we started sending. */
1425         if (interval < 65536)
1426                 client -> packet.secs = htons (interval);
1427         else
1428                 client -> packet.secs = htons (65535);
1429         client -> secs = client -> packet.secs;
1430
1431         log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",
1432               client -> name ? client -> name : client -> interface -> name,
1433               inet_ntoa (sockaddr_broadcast.sin_addr),
1434               ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval));
1435
1436         /* Send out a packet. */
1437         result = send_packet (client -> interface, (struct packet *)0,
1438                               &client -> packet,
1439                               client -> packet_length,
1440                               inaddr_any, &sockaddr_broadcast,
1441                               (struct hardware *)0);
1442
1443         add_timeout (cur_time + client -> interval,
1444                      send_discover, client, 0, 0);
1445 }
1446
1447 /* state_panic gets called if we haven't received any offers in a preset
1448    amount of time.   When this happens, we try to use existing leases that
1449    haven't yet expired, and failing that, we call the client script and
1450    hope it can do something. */
1451
1452 void state_panic (cpp)
1453         void *cpp;
1454 {
1455         struct client_state *client = cpp;
1456         struct client_lease *loop;
1457         struct client_lease *lp;
1458
1459         loop = lp = client -> active;
1460
1461         log_info ("No DHCPOFFERS received.");
1462
1463         /* We may not have an active lease, but we may have some
1464            predefined leases that we can try. */
1465         if (!client -> active && client -> leases)
1466                 goto activate_next;
1467
1468         /* Run through the list of leases and see if one can be used. */
1469         while (client -> active) {
1470                 if (client -> active -> expiry > cur_time) {
1471                         log_info ("Trying recorded lease %s",
1472                               piaddr (client -> active -> address));
1473                         /* Run the client script with the existing
1474                            parameters. */
1475                         script_init (client, "TIMEOUT",
1476                                      client -> active -> medium);
1477                         script_write_params (client, "new_", client -> active);
1478                         if (client -> alias)
1479                                 script_write_params (client, "alias_",
1480                                                      client -> alias);
1481
1482                         /* If the old lease is still good and doesn't
1483                            yet need renewal, go into BOUND state and
1484                            timeout at the renewal time. */
1485                         if (!script_go (client)) {
1486                             if (cur_time < client -> active -> renewal) {
1487                                 client -> state = S_BOUND;
1488                                 log_info ("bound: renewal in %ld %s.",
1489                                           (long)(client -> active -> renewal -
1490                                                  cur_time), "seconds");
1491                                 add_timeout (client -> active -> renewal,
1492                                              state_bound, client, 0, 0);
1493                             } else {
1494                                 client -> state = S_BOUND;
1495                                 log_info ("bound: immediate renewal.");
1496                                 state_bound (client);
1497                             }
1498                             reinitialize_interfaces ();
1499                             go_daemon ();
1500                             return;
1501                         }
1502                 }
1503
1504                 /* If there are no other leases, give up. */
1505                 if (!client -> leases) {
1506                         client -> leases = client -> active;
1507                         client -> active = (struct client_lease *)0;
1508                         break;
1509                 }
1510
1511         activate_next:
1512                 /* Otherwise, put the active lease at the end of the
1513                    lease list, and try another lease.. */
1514                 for (lp = client -> leases; lp -> next; lp = lp -> next)
1515                         ;
1516                 lp -> next = client -> active;
1517                 if (lp -> next) {
1518                         lp -> next -> next = (struct client_lease *)0;
1519                 }
1520                 client -> active = client -> leases;
1521                 client -> leases = client -> leases -> next;
1522
1523                 /* If we already tried this lease, we've exhausted the
1524                    set of leases, so we might as well give up for
1525                    now. */
1526                 if (client -> active == loop)
1527                         break;
1528                 else if (!loop)
1529                         loop = client -> active;
1530         }
1531
1532         /* No leases were available, or what was available didn't work, so
1533            tell the shell script that we failed to allocate an address,
1534            and try again later. */
1535         if (onetry) {
1536                 if (!quiet)
1537                         log_info ("Unable to obtain a lease on first try.%s",
1538                                   "  Exiting.");
1539                 exit (2);
1540         }
1541
1542         log_info ("No working leases in persistent database - sleeping.");
1543         script_init (client, "FAIL", (struct string_list *)0);
1544         if (client -> alias)
1545                 script_write_params (client, "alias_", client -> alias);
1546         script_go (client);
1547         client -> state = S_INIT;
1548         add_timeout (cur_time +
1549                      ((client -> config -> retry_interval + 1) / 2 +
1550                       (random () % client -> config -> retry_interval)),
1551                      state_init, client, 0, 0);
1552         go_daemon ();
1553 }
1554
1555 void send_request (cpp)
1556         void *cpp;
1557 {
1558         struct client_state *client = cpp;
1559
1560         int result;
1561         int interval;
1562         struct sockaddr_in destination;
1563         struct in_addr from;
1564
1565         /* Figure out how long it's been since we started transmitting. */
1566         interval = cur_time - client -> first_sending;
1567
1568         /* If we're in the INIT-REBOOT or REQUESTING state and we're
1569            past the reboot timeout, go to INIT and see if we can
1570            DISCOVER an address... */
1571         /* XXX In the INIT-REBOOT state, if we don't get an ACK, it
1572            means either that we're on a network with no DHCP server,
1573            or that our server is down.  In the latter case, assuming
1574            that there is a backup DHCP server, DHCPDISCOVER will get
1575            us a new address, but we could also have successfully
1576            reused our old address.  In the former case, we're hosed
1577            anyway.  This is not a win-prone situation. */
1578         if ((client -> state == S_REBOOTING ||
1579              client -> state == S_REQUESTING) &&
1580             interval > client -> config -> reboot_timeout) {
1581         cancel:
1582                 client -> state = S_INIT;
1583                 cancel_timeout (send_request, client);
1584                 state_init (client);
1585                 return;
1586         }
1587
1588         /* If we're in the reboot state, make sure the media is set up
1589            correctly. */
1590         if (client -> state == S_REBOOTING &&
1591             !client -> medium &&
1592             client -> active -> medium ) {
1593                 script_init (client, "MEDIUM", client -> active -> medium);
1594
1595                 /* If the medium we chose won't fly, go to INIT state. */
1596                 if (script_go (client))
1597                         goto cancel;
1598
1599                 /* Record the medium. */
1600                 client -> medium = client -> active -> medium;
1601         }
1602
1603         /* If the lease has expired, relinquish the address and go back
1604            to the INIT state. */
1605         if (client -> state != S_REQUESTING &&
1606             cur_time > client -> active -> expiry) {
1607                 /* Run the client script with the new parameters. */
1608                 script_init (client, "EXPIRE", (struct string_list *)0);
1609                 script_write_params (client, "old_", client -> active);
1610                 if (client -> alias)
1611                         script_write_params (client, "alias_",
1612                                              client -> alias);
1613                 script_go (client);
1614
1615                 /* Now do a preinit on the interface so that we can
1616                    discover a new address. */
1617                 script_init (client, "PREINIT", (struct string_list *)0);
1618                 if (client -> alias)
1619                         script_write_params (client, "alias_",
1620                                              client -> alias);
1621                 script_go (client);
1622
1623                 client -> state = S_INIT;
1624                 state_init (client);
1625                 return;
1626         }
1627
1628         /* Do the exponential backoff... */
1629         if (!client -> interval)
1630                 client -> interval = client -> config -> initial_interval;
1631         else {
1632                 client -> interval += ((random () >> 2) %
1633                                        (2 * client -> interval));
1634         }
1635         
1636         /* Don't backoff past cutoff. */
1637         if (client -> interval >
1638             client -> config -> backoff_cutoff)
1639                 client -> interval =
1640                         ((client -> config -> backoff_cutoff / 2)
1641                          + ((random () >> 2) % client -> interval));
1642
1643         /* If the backoff would take us to the expiry time, just set the
1644            timeout to the expiry time. */
1645         if (client -> state != S_REQUESTING &&
1646             cur_time + client -> interval > client -> active -> expiry)
1647                 client -> interval =
1648                         client -> active -> expiry - cur_time + 1;
1649
1650         /* If the lease T2 time has elapsed, or if we're not yet bound,
1651            broadcast the DHCPREQUEST rather than unicasting. */
1652         if (client -> state == S_REQUESTING ||
1653             client -> state == S_REBOOTING ||
1654             cur_time > client -> active -> rebind)
1655                 destination.sin_addr = sockaddr_broadcast.sin_addr;
1656         else
1657                 memcpy (&destination.sin_addr.s_addr,
1658                         client -> destination.iabuf,
1659                         sizeof destination.sin_addr.s_addr);
1660         destination.sin_port = remote_port;
1661         destination.sin_family = AF_INET;
1662 #ifdef HAVE_SA_LEN
1663         destination.sin_len = sizeof destination;
1664 #endif
1665
1666         if (client -> state == S_RENEWING ||
1667             client -> state == S_REBINDING)
1668                 memcpy (&from, client -> active -> address.iabuf,
1669                         sizeof from);
1670         else
1671                 from.s_addr = INADDR_ANY;
1672
1673         /* Record the number of seconds since we started sending. */
1674         if (client -> state == S_REQUESTING)
1675                 client -> packet.secs = client -> secs;
1676         else {
1677                 if (interval < 65536)
1678                         client -> packet.secs = htons (interval);
1679                 else
1680                         client -> packet.secs = htons (65535);
1681         }
1682
1683         log_info ("DHCPREQUEST on %s to %s port %d",
1684               client -> name ? client -> name : client -> interface -> name,
1685               inet_ntoa (destination.sin_addr),
1686               ntohs (destination.sin_port));
1687
1688         if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
1689             fallback_interface)
1690                 result = send_packet (fallback_interface,
1691                                       (struct packet *)0,
1692                                       &client -> packet,
1693                                       client -> packet_length,
1694                                       from, &destination,
1695                                       (struct hardware *)0);
1696         else
1697                 /* Send out a packet. */
1698                 result = send_packet (client -> interface, (struct packet *)0,
1699                                       &client -> packet,
1700                                       client -> packet_length,
1701                                       from, &destination,
1702                                       (struct hardware *)0);
1703
1704         add_timeout (cur_time + client -> interval,
1705                      send_request, client, 0, 0);
1706 }
1707
1708 void send_decline (cpp)
1709         void *cpp;
1710 {
1711         struct client_state *client = cpp;
1712
1713         int result;
1714
1715         log_info ("DHCPDECLINE on %s to %s port %d",
1716               client -> name ? client -> name : client -> interface -> name,
1717               inet_ntoa (sockaddr_broadcast.sin_addr),
1718               ntohs (sockaddr_broadcast.sin_port));
1719
1720         /* Send out a packet. */
1721         result = send_packet (client -> interface, (struct packet *)0,
1722                               &client -> packet,
1723                               client -> packet_length,
1724                               inaddr_any, &sockaddr_broadcast,
1725                               (struct hardware *)0);
1726 }
1727
1728 void send_release (cpp)
1729         void *cpp;
1730 {
1731         struct client_state *client = cpp;
1732
1733         int result;
1734         struct sockaddr_in destination;
1735         struct in_addr from;
1736
1737         memcpy (&from, client -> active -> address.iabuf,
1738                 sizeof from);
1739         memcpy (&destination.sin_addr.s_addr,
1740                 client -> destination.iabuf,
1741                 sizeof destination.sin_addr.s_addr);
1742         destination.sin_port = remote_port;
1743         destination.sin_family = AF_INET;
1744 #ifdef HAVE_SA_LEN
1745         destination.sin_len = sizeof destination;
1746 #endif
1747
1748         /* Set the lease to end now, so that we don't accidentally
1749            reuse it if we restart before the old expiry time. */
1750         client -> active -> expiry =
1751                 client -> active -> renewal =
1752                 client -> active -> rebind = cur_time;
1753         if (!write_client_lease (client, client -> active, 1, 1)) {
1754                 log_error ("Can't release lease: lease write failed.");
1755                 return;
1756         }
1757
1758         log_info ("DHCPRELEASE on %s to %s port %d",
1759               client -> name ? client -> name : client -> interface -> name,
1760               inet_ntoa (destination.sin_addr),
1761               ntohs (destination.sin_port));
1762
1763         if (fallback_interface)
1764                 result = send_packet (fallback_interface,
1765                                       (struct packet *)0,
1766                                       &client -> packet,
1767                                       client -> packet_length,
1768                                       from, &destination,
1769                                       (struct hardware *)0);
1770         else
1771                 /* Send out a packet. */
1772                 result = send_packet (client -> interface, (struct packet *)0,
1773                                       &client -> packet,
1774                                       client -> packet_length,
1775                                       from, &destination,
1776                                       (struct hardware *)0);
1777 }
1778
1779 void make_client_options (client, lease, type, sid, rip, prl, op)
1780         struct client_state *client;
1781         struct client_lease *lease;
1782         u_int8_t *type;
1783         struct option_cache *sid;
1784         struct iaddr *rip;
1785         u_int32_t *prl;
1786         struct option_state **op;
1787 {
1788         unsigned i;
1789         struct option_cache *oc;
1790         struct buffer *bp = (struct buffer *)0;
1791
1792         /* If there are any leftover options, get rid of them. */
1793         if (*op)
1794                 option_state_dereference (op, MDL);
1795
1796         /* Allocate space for options. */
1797         option_state_allocate (op, MDL);
1798
1799         /* Send the server identifier if provided. */
1800         if (sid)
1801                 save_option (&dhcp_universe, *op, sid);
1802
1803         oc = (struct option_cache *)0;
1804
1805         /* Send the requested address if provided. */
1806         if (rip) {
1807                 client -> requested_address = *rip;
1808                 if (!(make_const_option_cache
1809                       (&oc, (struct buffer **)0, rip -> iabuf, rip -> len,
1810                        &dhcp_options [DHO_DHCP_REQUESTED_ADDRESS], MDL)))
1811                         log_error ("can't make requested address cache.");
1812                 else {
1813                         save_option (&dhcp_universe, *op, oc);
1814                         option_cache_dereference (&oc, MDL);
1815                 }
1816         } else {
1817                 client -> requested_address.len = 0;
1818         }
1819
1820         if (!(make_const_option_cache
1821               (&oc, (struct buffer **)0,
1822                type, 1, &dhcp_options [DHO_DHCP_MESSAGE_TYPE], MDL)))
1823                 log_error ("can't make message type.");
1824         else {
1825                 save_option (&dhcp_universe, *op, oc);
1826                 option_cache_dereference (&oc, MDL);
1827         }
1828
1829         if (prl) {
1830                 /* Figure out how many parameters were requested. */
1831                 for (i = 0; prl [i]; i++)
1832                         ;
1833                 if (!buffer_allocate (&bp, i, MDL))
1834                         log_error ("can't make parameter list buffer.");
1835                 else {
1836                         for (i = 0; prl [i]; i++)
1837                                 bp -> data [i] = prl [i];
1838                         if (!(make_const_option_cache
1839                               (&oc, &bp, (u_int8_t *)0, i,
1840                                &dhcp_options [DHO_DHCP_PARAMETER_REQUEST_LIST],
1841                                MDL)))
1842                                 log_error ("can't make option cache");
1843                         else {
1844                                 save_option (&dhcp_universe, *op, oc);
1845                                 option_cache_dereference (&oc, MDL);
1846                         }
1847                 }
1848         }
1849
1850         /* Run statements that need to be run on transmission. */
1851         if (client -> config -> on_transmission)
1852                 execute_statements_in_scope
1853                         ((struct binding_value **)0,
1854                          (struct packet *)0, (struct lease *)0, client,
1855                          (lease ? lease -> options : (struct option_state *)0),
1856                          *op, &global_scope,
1857                          client -> config -> on_transmission,
1858                          (struct group *)0);
1859 }
1860
1861 void make_discover (client, lease)
1862         struct client_state *client;
1863         struct client_lease *lease;
1864 {
1865         unsigned char discover = DHCPDISCOVER;
1866         int i;
1867         struct option_state *options = (struct option_state *)0;
1868
1869         memset (&client -> packet, 0, sizeof (client -> packet));
1870
1871         make_client_options (client,
1872                              lease, &discover, (struct option_cache *)0,
1873                              lease ? &lease -> address : (struct iaddr *)0,
1874                              client -> config -> requested_options,
1875                              &options);
1876
1877         /* Set up the option buffer... */
1878         client -> packet_length =
1879                 cons_options ((struct packet *)0, &client -> packet,
1880                               (struct lease *)0, client, 0,
1881                               (struct option_state *)0, options,
1882                               &global_scope, 0, 0, 0, (struct data_string *)0,
1883                               client -> config -> vendor_space_name);
1884         option_state_dereference (&options, MDL);
1885         if (client -> packet_length < BOOTP_MIN_LEN)
1886                 client -> packet_length = BOOTP_MIN_LEN;
1887
1888         client -> packet.op = BOOTREQUEST;
1889         client -> packet.htype = client -> interface -> hw_address.hbuf [0];
1890         client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
1891         client -> packet.hops = 0;
1892         client -> packet.xid = random ();
1893         client -> packet.secs = 0; /* filled in by send_discover. */
1894
1895         if (can_receive_unicast_unconfigured (client -> interface))
1896                 client -> packet.flags = 0;
1897         else
1898                 client -> packet.flags = htons (BOOTP_BROADCAST);
1899
1900         memset (&(client -> packet.ciaddr),
1901                 0, sizeof client -> packet.ciaddr);
1902         memset (&(client -> packet.yiaddr),
1903                 0, sizeof client -> packet.yiaddr);
1904         memset (&(client -> packet.siaddr),
1905                 0, sizeof client -> packet.siaddr);
1906         client -> packet.giaddr = giaddr;
1907         if (client -> interface -> hw_address.hlen > 0)
1908             memcpy (client -> packet.chaddr,
1909                     &client -> interface -> hw_address.hbuf [1],
1910                     (unsigned)(client -> interface -> hw_address.hlen - 1));
1911
1912 #ifdef DEBUG_PACKET
1913         dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
1914 #endif
1915 }
1916
1917
1918 void make_request (client, lease)
1919         struct client_state *client;
1920         struct client_lease *lease;
1921 {
1922         unsigned char request = DHCPREQUEST;
1923         int i, j;
1924         unsigned char *tmp, *digest;
1925         unsigned char *old_digest_loc;
1926         struct option_cache *oc;
1927
1928         memset (&client -> packet, 0, sizeof (client -> packet));
1929
1930         if (client -> state == S_REQUESTING)
1931                 oc = lookup_option (&dhcp_universe, lease -> options,
1932                                     DHO_DHCP_SERVER_IDENTIFIER);
1933         else
1934                 oc = (struct option_cache *)0;
1935
1936         make_client_options (client, lease, &request, oc,
1937                              ((client -> state == S_REQUESTING ||
1938                                client -> state == S_REBOOTING)
1939                               ? &lease -> address
1940                               : (struct iaddr *)0),
1941                              client -> config -> requested_options,
1942                              &client -> sent_options);
1943
1944         /* Set up the option buffer... */
1945         client -> packet_length =
1946                 cons_options ((struct packet *)0, &client -> packet,
1947                               (struct lease *)0, client, 0,
1948                               (struct option_state *)0, client -> sent_options,
1949                               &global_scope, 0, 0, 0, (struct data_string *)0,
1950                               client -> config -> vendor_space_name);
1951         option_state_dereference (&client -> sent_options, MDL);
1952         if (client -> packet_length < BOOTP_MIN_LEN)
1953                 client -> packet_length = BOOTP_MIN_LEN;
1954
1955         client -> packet.op = BOOTREQUEST;
1956         client -> packet.htype = client -> interface -> hw_address.hbuf [0];
1957         client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
1958         client -> packet.hops = 0;
1959         client -> packet.xid = client -> xid;
1960         client -> packet.secs = 0; /* Filled in by send_request. */
1961
1962         /* If we own the address we're requesting, put it in ciaddr;
1963            otherwise set ciaddr to zero. */
1964         if (client -> state == S_BOUND ||
1965             client -> state == S_RENEWING ||
1966             client -> state == S_REBINDING) {
1967                 memcpy (&client -> packet.ciaddr,
1968                         lease -> address.iabuf, lease -> address.len);
1969                 client -> packet.flags = 0;
1970         } else {
1971                 memset (&client -> packet.ciaddr, 0,
1972                         sizeof client -> packet.ciaddr);
1973                 if (can_receive_unicast_unconfigured (client -> interface))
1974                         client -> packet.flags = 0;
1975                 else
1976                         client -> packet.flags = htons (BOOTP_BROADCAST);
1977         }
1978
1979         memset (&client -> packet.yiaddr, 0,
1980                 sizeof client -> packet.yiaddr);
1981         memset (&client -> packet.siaddr, 0,
1982                 sizeof client -> packet.siaddr);
1983         if (client -> state != S_BOUND &&
1984             client -> state != S_RENEWING)
1985                 client -> packet.giaddr = giaddr;
1986         else
1987                 memset (&client -> packet.giaddr, 0,
1988                         sizeof client -> packet.giaddr);
1989         if (client -> interface -> hw_address.hlen > 0)
1990             memcpy (client -> packet.chaddr,
1991                     &client -> interface -> hw_address.hbuf [1],
1992                     (unsigned)(client -> interface -> hw_address.hlen - 1));
1993
1994 #ifdef DEBUG_PACKET
1995         dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
1996 #endif
1997 }
1998
1999 void make_decline (client, lease)
2000         struct client_state *client;
2001         struct client_lease *lease;
2002 {
2003         unsigned char decline = DHCPDECLINE;
2004         int i;
2005         struct option_cache *oc;
2006
2007         struct option_state *options = (struct option_state *)0;
2008
2009         oc = lookup_option (&dhcp_universe, lease -> options,
2010                             DHO_DHCP_SERVER_IDENTIFIER);
2011         make_client_options (client, lease, &decline, oc,
2012                              &lease -> address, (u_int32_t *)0, &options);
2013
2014         /* Set up the option buffer... */
2015         memset (&client -> packet, 0, sizeof (client -> packet));
2016         client -> packet_length =
2017                 cons_options ((struct packet *)0, &client -> packet,
2018                               (struct lease *)0, client, 0,
2019                               (struct option_state *)0, options,
2020                               &global_scope, 0, 0, 0, (struct data_string *)0,
2021                               client -> config -> vendor_space_name);
2022         option_state_dereference (&options, MDL);
2023         if (client -> packet_length < BOOTP_MIN_LEN)
2024                 client -> packet_length = BOOTP_MIN_LEN;
2025         option_state_dereference (&options, MDL);
2026
2027         client -> packet.op = BOOTREQUEST;
2028         client -> packet.htype = client -> interface -> hw_address.hbuf [0];
2029         client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
2030         client -> packet.hops = 0;
2031         client -> packet.xid = client -> xid;
2032         client -> packet.secs = 0; /* Filled in by send_request. */
2033         if (can_receive_unicast_unconfigured (client -> interface))
2034                 client -> packet.flags = 0;
2035         else
2036                 client -> packet.flags = htons (BOOTP_BROADCAST);
2037
2038         /* ciaddr must always be zero. */
2039         memset (&client -> packet.ciaddr, 0,
2040                 sizeof client -> packet.ciaddr);
2041         memset (&client -> packet.yiaddr, 0,
2042                 sizeof client -> packet.yiaddr);
2043         memset (&client -> packet.siaddr, 0,
2044                 sizeof client -> packet.siaddr);
2045         client -> packet.giaddr = giaddr;
2046         memcpy (client -> packet.chaddr,
2047                 &client -> interface -> hw_address.hbuf [1],
2048                 client -> interface -> hw_address.hlen);
2049
2050 #ifdef DEBUG_PACKET
2051         dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
2052 #endif
2053 }
2054
2055 void make_release (client, lease)
2056         struct client_state *client;
2057         struct client_lease *lease;
2058 {
2059         unsigned char request = DHCPRELEASE;
2060         int i;
2061         struct option_cache *oc;
2062
2063         struct option_state *options = (struct option_state *)0;
2064
2065         memset (&client -> packet, 0, sizeof (client -> packet));
2066
2067         oc = lookup_option (&dhcp_universe, lease -> options,
2068                             DHO_DHCP_SERVER_IDENTIFIER);
2069         make_client_options (client, lease, &request, oc,
2070                              (struct iaddr *)0, (u_int32_t *)0,
2071                              &options);
2072
2073         /* Set up the option buffer... */
2074         client -> packet_length =
2075                 cons_options ((struct packet *)0, &client -> packet,
2076                               (struct lease *)0, client, 0,
2077                               (struct option_state *)0, options,
2078                               &global_scope, 0, 0, 0, (struct data_string *)0,
2079                               client -> config -> vendor_space_name);
2080         if (client -> packet_length < BOOTP_MIN_LEN)
2081                 client -> packet_length = BOOTP_MIN_LEN;
2082         option_state_dereference (&options, MDL);
2083
2084         client -> packet.op = BOOTREQUEST;
2085         client -> packet.htype = client -> interface -> hw_address.hbuf [0];
2086         client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
2087         client -> packet.hops = 0;
2088         client -> packet.xid = random ();
2089         client -> packet.secs = 0;
2090         client -> packet.flags = 0;
2091         memcpy (&client -> packet.ciaddr,
2092                 lease -> address.iabuf, lease -> address.len);
2093         memset (&client -> packet.yiaddr, 0,
2094                 sizeof client -> packet.yiaddr);
2095         memset (&client -> packet.siaddr, 0,
2096                 sizeof client -> packet.siaddr);
2097         client -> packet.giaddr = giaddr;
2098         memcpy (client -> packet.chaddr,
2099                 &client -> interface -> hw_address.hbuf [1],
2100                 client -> interface -> hw_address.hlen);
2101
2102 #ifdef DEBUG_PACKET
2103         dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
2104 #endif
2105 }
2106
2107 void destroy_client_lease (lease)
2108         struct client_lease *lease;
2109 {
2110         int i;
2111
2112         if (lease -> server_name)
2113                 dfree (lease -> server_name, MDL);
2114         if (lease -> filename)
2115                 dfree (lease -> filename, MDL);
2116         option_state_dereference (&lease -> options, MDL);
2117         free_client_lease (lease, MDL);
2118 }
2119
2120 FILE *leaseFile;
2121
2122 void rewrite_client_leases ()
2123 {
2124         struct interface_info *ip;
2125         struct client_state *client;
2126         struct client_lease *lp;
2127
2128         if (leaseFile)
2129                 fclose (leaseFile);
2130         leaseFile = fopen (path_dhclient_db, "w");
2131         if (!leaseFile) {
2132                 log_error ("can't create %s: %m", path_dhclient_db);
2133                 return;
2134         }
2135
2136         /* Write out all the leases attached to configured interfaces that
2137            we know about. */
2138         for (ip = interfaces; ip; ip = ip -> next) {
2139                 for (client = ip -> client; client; client = client -> next) {
2140                         for (lp = client -> leases; lp; lp = lp -> next) {
2141                                 write_client_lease (client, lp, 1, 0);
2142                         }
2143                         if (client -> active)
2144                                 write_client_lease (client,
2145                                                     client -> active, 1, 0);
2146                 }
2147         }
2148
2149         /* Write out any leases that are attached to interfaces that aren't
2150            currently configured. */
2151         for (ip = dummy_interfaces; ip; ip = ip -> next) {
2152                 for (client = ip -> client; client; client = client -> next) {
2153                         for (lp = client -> leases; lp; lp = lp -> next) {
2154                                 write_client_lease (client, lp, 1, 0);
2155                         }
2156                         if (client -> active)
2157                                 write_client_lease (client,
2158                                                     client -> active, 1, 0);
2159                 }
2160         }
2161         fflush (leaseFile);
2162 }
2163
2164 void write_lease_option (struct option_cache *oc,
2165                          struct packet *packet, struct lease *lease,
2166                          struct client_state *client_state,
2167                          struct option_state *in_options,
2168                          struct option_state *cfg_options,
2169                          struct binding_scope **scope,
2170                          struct universe *u, void *stuff)
2171 {
2172         const char *name, *dot;
2173         struct data_string ds;
2174         int status;
2175         struct client_state *client;
2176
2177         memset (&ds, 0, sizeof ds);
2178
2179         if (u != &dhcp_universe) {
2180                 name = u -> name;
2181                 dot = ".";
2182         } else {
2183                 name = "";
2184                 dot = "";
2185         }
2186         if (evaluate_option_cache (&ds, packet, lease, client_state,
2187                                    in_options, cfg_options, scope, oc, MDL)) {
2188                 fprintf (leaseFile,
2189                          "  option %s%s%s %s;\n",
2190                          name, dot, oc -> option -> name,
2191                          pretty_print_option (oc -> option,
2192                                               ds.data, ds.len, 1, 1));
2193                 data_string_forget (&ds, MDL);
2194         }
2195 }
2196
2197 int write_client_lease (client, lease, rewrite, makesure)
2198         struct client_state *client;
2199         struct client_lease *lease;
2200         int rewrite;
2201         int makesure;
2202 {
2203         int i;
2204         struct tm *t;
2205         static int leases_written;
2206         struct option_cache *oc;
2207         struct data_string ds;
2208         pair *hash;
2209         int errors = 0;
2210         char *s;
2211
2212         if (!rewrite) {
2213                 if (leases_written++ > 20) {
2214                         rewrite_client_leases ();
2215                         leases_written = 0;
2216                 }
2217         }
2218
2219         /* If the lease came from the config file, we don't need to stash
2220            a copy in the lease database. */
2221         if (lease -> is_static)
2222                 return 1;
2223
2224         if (!leaseFile) {       /* XXX */
2225                 leaseFile = fopen (path_dhclient_db, "w");
2226                 if (!leaseFile) {
2227                         log_error ("can't create %s: %m", path_dhclient_db);
2228                         return 0;
2229                 }
2230         }
2231
2232         errno = 0;
2233         fprintf (leaseFile, "lease {\n");
2234         if (lease -> is_bootp) {
2235                 fprintf (leaseFile, "  bootp;\n");
2236                 if (errno) {
2237                         ++errors;
2238                         errno = 0;
2239                 }
2240         }
2241         fprintf (leaseFile, "  interface \"%s\";\n",
2242                  client -> interface -> name);
2243         if (errno) {
2244                 ++errors;
2245                 errno = 0;
2246         }
2247         if (client -> name) {
2248                 fprintf (leaseFile, "  name \"%s\";\n", client -> name);
2249                 if (errno) {
2250                         ++errors;
2251                         errno = 0;
2252                 }
2253         }
2254         fprintf (leaseFile, "  fixed-address %s;\n",
2255                  piaddr (lease -> address));
2256         if (errno) {
2257                 ++errors;
2258                 errno = 0;
2259         }
2260         if (lease -> filename) {
2261                 s = quotify_string (lease -> filename, MDL);
2262                 if (s) {
2263                         fprintf (leaseFile, "  filename \"%s\";\n", s);
2264                         if (errno) {
2265                                 ++errors;
2266                                 errno = 0;
2267                         }
2268                         dfree (s, MDL);
2269                 } else
2270                         errors++;
2271
2272         }
2273         if (lease -> server_name) {
2274                 s = quotify_string (lease -> filename, MDL);
2275                 if (s) {
2276                         fprintf (leaseFile, "  server-name \"%s\";\n", s);
2277                         if (errno) {
2278                                 ++errors;
2279                                 errno = 0;
2280                         }
2281                         dfree (s, MDL);
2282                 } else
2283                         ++errors;
2284         }
2285         if (lease -> medium) {
2286                 s = quotify_string (lease -> medium -> string, MDL);
2287                 if (s) {
2288                         fprintf (leaseFile, "  medium \"%s\";\n", s);
2289                         if (errno) {
2290                                 ++errors;
2291                                 errno = 0;
2292                         }
2293                         dfree (s, MDL);
2294                 } else
2295                         errors++;
2296         }
2297         if (errno != 0) {
2298                 errors++;
2299                 errno = 0;
2300         }
2301
2302         memset (&ds, 0, sizeof ds);
2303
2304         for (i = 0; i < lease -> options -> universe_count; i++) {
2305                 option_space_foreach ((struct packet *)0, (struct lease *)0,
2306                                       client, (struct option_state *)0,
2307                                       lease -> options, &global_scope,
2308                                       universes [i],
2309                                       client, write_lease_option);
2310         }
2311
2312         /* Note: the following is not a Y2K bug - it's a Y1.9K bug.   Until
2313            somebody invents a time machine, I think we can safely disregard
2314            it. */
2315         t = gmtime (&lease -> renewal);
2316         fprintf (leaseFile,
2317                  "  renew %d %d/%d/%d %02d:%02d:%02d;\n",
2318                  t -> tm_wday, t -> tm_year + 1900,
2319                  t -> tm_mon + 1, t -> tm_mday,
2320                  t -> tm_hour, t -> tm_min, t -> tm_sec);
2321         if (errno != 0) {
2322                 errors++;
2323                 errno = 0;
2324         }
2325         t = gmtime (&lease -> rebind);
2326         fprintf (leaseFile,
2327                  "  rebind %d %d/%d/%d %02d:%02d:%02d;\n",
2328                  t -> tm_wday, t -> tm_year + 1900,
2329                  t -> tm_mon + 1, t -> tm_mday,
2330                  t -> tm_hour, t -> tm_min, t -> tm_sec);
2331         if (errno != 0) {
2332                 errors++;
2333                 errno = 0;
2334         }
2335         t = gmtime (&lease -> expiry);
2336         fprintf (leaseFile,
2337                  "  expire %d %d/%d/%d %02d:%02d:%02d;\n",
2338                  t -> tm_wday, t -> tm_year + 1900,
2339                  t -> tm_mon + 1, t -> tm_mday,
2340                  t -> tm_hour, t -> tm_min, t -> tm_sec);
2341         if (errno != 0) {
2342                 errors++;
2343                 errno = 0;
2344         }
2345         fprintf (leaseFile, "}\n");
2346         if (errno != 0) {
2347                 errors++;
2348                 errno = 0;
2349         }
2350         fflush (leaseFile);
2351         if (errno != 0) {
2352                 errors++;
2353                 errno = 0;
2354         }
2355         if (!errors && makesure) {
2356                 if (fsync (fileno (leaseFile)) < 0) {
2357                         log_info ("write_client_lease: %m");
2358                         return 0;
2359                 }
2360         }
2361         return errors ? 0 : 1;
2362 }
2363
2364 /* Variables holding name of script and file pointer for writing to
2365    script.   Needless to say, this is not reentrant - only one script
2366    can be invoked at a time. */
2367 char scriptName [256];
2368 FILE *scriptFile;
2369
2370 void script_init (client, reason, medium)
2371         struct client_state *client;
2372         const char *reason;
2373         struct string_list *medium;
2374 {
2375         struct string_list *sl, *next;
2376
2377         if (client) {
2378                 for (sl = client -> env; sl; sl = next) {
2379                         next = sl -> next;
2380                         dfree (sl, MDL);
2381                 }
2382                 client -> env = (struct string_list *)0;
2383                 client -> envc = 0;
2384                 
2385                 if (client -> interface) {
2386                         client_envadd (client, "", "interface", "%s",
2387                                        client -> interface -> name);
2388                 }
2389                 if (client -> name)
2390                         client_envadd (client,
2391                                        "", "client", "%s", client -> name);
2392                 if (medium)
2393                         client_envadd (client,
2394                                        "", "medium", "%s", medium -> string);
2395
2396                 client_envadd (client, "", "reason", "%s", reason);
2397                 client_envadd (client, "", "pid", "%ld", (long int)getpid ());
2398         }
2399 }
2400
2401 struct envadd_state {
2402         struct client_state *client;
2403         const char *prefix;
2404 };
2405
2406 void client_option_envadd (struct option_cache *oc,
2407                            struct packet *packet, struct lease *lease,
2408                            struct client_state *client_state,
2409                            struct option_state *in_options,
2410                            struct option_state *cfg_options,
2411                            struct binding_scope **scope,
2412                            struct universe *u, void *stuff)
2413 {
2414         struct envadd_state *es = stuff;
2415         struct data_string data;
2416         memset (&data, 0, sizeof data);
2417
2418         if (evaluate_option_cache (&data, packet, lease, client_state,
2419                                    in_options, cfg_options, scope, oc, MDL)) {
2420                 if (data.len) {
2421                         char name [256];
2422                         if (dhcp_option_ev_name (name, sizeof name,
2423                                                  oc -> option)) {
2424                                 client_envadd (es -> client, es -> prefix,
2425                                                name, "%s",
2426                                                (pretty_print_option
2427                                                 (oc -> option,
2428                                                  data.data, data.len,
2429                                                  0, 0)));
2430                                 data_string_forget (&data, MDL);
2431                         }
2432                 }
2433         }
2434 }
2435
2436 void script_write_params (client, prefix, lease)
2437         struct client_state *client;
2438         const char *prefix;
2439         struct client_lease *lease;
2440 {
2441         int i;
2442         struct data_string data;
2443         struct option_cache *oc;
2444         pair *hash;
2445         char *s, *t;
2446         struct envadd_state es;
2447
2448         es.client = client;
2449         es.prefix = prefix;
2450
2451         client_envadd (client,
2452                        prefix, "ip_address", "%s", piaddr (lease -> address));
2453
2454         /* For the benefit of Linux (and operating systems which may
2455            have similar needs), compute the network address based on
2456            the supplied ip address and netmask, if provided.  Also
2457            compute the broadcast address (the host address all ones
2458            broadcast address, not the host address all zeroes
2459            broadcast address). */
2460
2461         memset (&data, 0, sizeof data);
2462         oc = lookup_option (&dhcp_universe, lease -> options, DHO_SUBNET_MASK);
2463         if (oc && evaluate_option_cache (&data, (struct packet *)0,
2464                                          (struct lease *)0, client,
2465                                          (struct option_state *)0,
2466                                          lease -> options,
2467                                          &global_scope, oc, MDL)) {
2468                 if (data.len > 3) {
2469                         struct iaddr netmask, subnet, broadcast;
2470
2471                         memcpy (netmask.iabuf, data.data, data.len);
2472                         netmask.len = data.len;
2473                         data_string_forget (&data, MDL);
2474
2475                         subnet = subnet_number (lease -> address, netmask);
2476                         if (subnet.len) {
2477                             client_envadd (client, prefix, "network_number",
2478                                            "%s", piaddr (subnet));
2479
2480                             oc = lookup_option (&dhcp_universe,
2481                                                 lease -> options,
2482                                                 DHO_BROADCAST_ADDRESS);
2483                             if (!oc ||
2484                                 !(evaluate_option_cache
2485                                   (&data, (struct packet *)0,
2486                                    (struct lease *)0, client,
2487                                    (struct option_state *)0,
2488                                    lease -> options,
2489                                    &global_scope, oc, MDL))) {
2490                                 broadcast = broadcast_addr (subnet, netmask);
2491                                 if (broadcast.len) {
2492                                     client_envadd (client,
2493                                                    prefix, "broadcast_address",
2494                                                    "%s", piaddr (broadcast));
2495                                 }
2496                             }
2497                         }
2498                 }
2499                 data_string_forget (&data, MDL);
2500         }
2501
2502         if (lease -> filename)
2503                 client_envadd (client,
2504                                prefix, "filename", "%s", lease -> filename);
2505         if (lease -> server_name)
2506                 client_envadd (client, prefix, "server_name",
2507                                "%s", lease -> server_name);
2508
2509         for (i = 0; i < lease -> options -> universe_count; i++) {
2510                 option_space_foreach ((struct packet *)0, (struct lease *)0,
2511                                       client, (struct option_state *)0,
2512                                       lease -> options, &global_scope,
2513                                       universes [i],
2514                                       &es, client_option_envadd);
2515         }
2516         client_envadd (client, prefix, "expiry", "%d", (int)(lease -> expiry));
2517 }
2518
2519 int script_go (client)
2520         struct client_state *client;
2521 {
2522         int rval;
2523         char *scriptName;
2524         char *argv [2];
2525         char **envp;
2526         char *epp [3];
2527         char reason [] = "REASON=NBI";
2528         static char client_path [] = CLIENT_PATH;
2529         int i;
2530         struct string_list *sp, *next;
2531         int pid, wpid, wstatus;
2532
2533         if (client)
2534                 scriptName = client -> config -> script_name;
2535         else
2536                 scriptName = top_level_config.script_name;
2537
2538         envp = dmalloc (((client ? client -> envc : 2) +
2539                          client_env_count + 2) * sizeof (char *), MDL);
2540         if (!envp) {
2541                 log_error ("No memory for client script environment.");
2542                 return 0;
2543         }
2544         i = 0;
2545         /* Copy out the environment specified on the command line,
2546            if any. */
2547         for (sp = client_env; sp; sp = sp -> next) {
2548                 envp [i++] = sp -> string;
2549         }
2550         /* Copy out the environment specified by dhclient. */
2551         if (client) {
2552                 for (sp = client -> env; sp; sp = sp -> next) {
2553                         envp [i++] = sp -> string;
2554                 }
2555         } else {
2556                 envp [i++] = reason;
2557         }
2558         /* Set $PATH. */
2559         envp [i++] = client_path;
2560         envp [i] = (char *)0;
2561
2562         argv [0] = scriptName;
2563         argv [1] = (char *)0;
2564
2565         pid = fork ();
2566         if (pid < 0) {
2567                 log_error ("fork: %m");
2568                 wstatus = 0;
2569         } else if (pid) {
2570                 do {
2571                         wpid = wait (&wstatus);
2572                 } while (wpid != pid && wpid > 0);
2573                 if (wpid < 0) {
2574                         log_error ("wait: %m");
2575                         wstatus = 0;
2576                 }
2577         } else {
2578                 if ((i = open(_PATH_DEVNULL, O_RDWR)) != -1) {
2579                         dup2(i, STDIN_FILENO);
2580                         dup2(i, STDOUT_FILENO);
2581                         dup2(i, STDERR_FILENO);
2582                         if (i > STDERR_FILENO)
2583                                 close(i);
2584                 }
2585                 execve (scriptName, argv, envp);
2586                 log_error ("execve (%s, ...): %m", scriptName);
2587                 exit (0);
2588         }
2589
2590         if (client) {
2591                 for (sp = client -> env; sp; sp = next) {
2592                         next = sp -> next;
2593                         dfree (sp, MDL);
2594                 }
2595                 client -> env = (struct string_list *)0;
2596                 client -> envc = 0;
2597         }
2598         dfree (envp, MDL);
2599         GET_TIME (&cur_time);
2600         return (WIFEXITED (wstatus) ?
2601                 WEXITSTATUS (wstatus) : -WTERMSIG (wstatus));
2602 }
2603
2604 void client_envadd (struct client_state *client,
2605                     const char *prefix, const char *name, const char *fmt, ...)
2606 {
2607         char spbuf [1024];
2608         char *s;
2609         unsigned len, i;
2610         struct string_list *val;
2611         va_list list;
2612
2613         va_start (list, fmt);
2614         len = vsnprintf (spbuf, sizeof spbuf, fmt, list);
2615         va_end (list);
2616
2617         val = dmalloc (strlen (prefix) + strlen (name) + 1 /* = */ +
2618                        len + sizeof *val, MDL);
2619         if (!val)
2620                 return;
2621         s = val -> string;
2622         strcpy (s, prefix);
2623         strcat (s, name);
2624         s += strlen (s);
2625         *s++ = '=';
2626         if (len >= sizeof spbuf) {
2627                 va_start (list, fmt);
2628                 vsnprintf (s, len + 1, fmt, list);
2629                 va_end (list);
2630         } else
2631                 strcpy (s, spbuf);
2632         val -> next = client -> env;
2633         client -> env = val;
2634         client -> envc++;
2635 }
2636
2637 int dhcp_option_ev_name (buf, buflen, option)
2638         char *buf;
2639         size_t buflen;
2640         struct option *option;
2641 {
2642         int i, j;
2643         const char *s;
2644
2645         j = 0;
2646         if (option -> universe != &dhcp_universe) {
2647                 s = option -> universe -> name;
2648                 i = 0;
2649         } else { 
2650                 s = option -> name;
2651                 i = 1;
2652         }
2653
2654         do {
2655                 while (*s) {
2656                         if (j + 1 == buflen)
2657                                 return 0;
2658                         if (*s == '-')
2659                                 buf [j++] = '_';
2660                         else
2661                                 buf [j++] = *s;
2662                         ++s;
2663                 }
2664                 if (!i) {
2665                         s = option -> name;
2666                         if (j + 1 == buflen)
2667                                 return 0;
2668                         buf [j++] = '_';
2669                 }
2670                 ++i;
2671         } while (i != 2);
2672
2673         buf [j] = 0;
2674         return 1;
2675 }
2676
2677 void go_daemon ()
2678 {
2679         static int state = 0;
2680         int pid;
2681         int i;
2682
2683         /* Don't become a daemon if the user requested otherwise. */
2684         if (no_daemon) {
2685                 write_client_pid_file ();
2686                 return;
2687         }
2688
2689         /* Only do it once. */
2690         if (state)
2691                 return;
2692         state = 1;
2693
2694         /* Stop logging to stderr... */
2695         log_perror = 0;
2696
2697         /* Become a daemon... */
2698         if ((pid = fork ()) < 0)
2699                 log_fatal ("Can't fork daemon: %m");
2700         else if (pid)
2701                 exit (0);
2702         /* Become session leader and get pid... */
2703         pid = setsid ();
2704
2705         /* Close standard I/O descriptors. */
2706         close(0);
2707         close(1);
2708         close(2);
2709
2710         /* Reopen them on /dev/null. */
2711         i = open ("/dev/null", O_RDWR);
2712         if (i == 0)
2713                 i = open ("/dev/null", O_RDWR);
2714         if (i == 1) {
2715                 i = open ("/dev/null", O_RDWR);
2716                 log_perror = 0; /* No sense logging to /dev/null. */
2717         } else if (i != -1)
2718                 close (i);
2719
2720         write_client_pid_file ();
2721 }
2722
2723 void write_client_pid_file ()
2724 {
2725         FILE *pf;
2726         int pfdesc;
2727
2728         pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY, 0644);
2729
2730         if (pfdesc < 0) {
2731                 log_error ("Can't create %s: %m", path_dhclient_pid);
2732                 return;
2733         }
2734
2735         pf = fdopen (pfdesc, "w");
2736         if (!pf)
2737                 log_error ("Can't fdopen %s: %m", path_dhclient_pid);
2738         else {
2739                 fprintf (pf, "%ld\n", (long)getpid ());
2740                 fclose (pf);
2741         }
2742 }
2743
2744 void client_location_changed ()
2745 {
2746         struct interface_info *ip;
2747         struct client_state *client;
2748
2749         for (ip = interfaces; ip; ip = ip -> next) {
2750                 for (client = ip -> client; client; client = client -> next) {
2751                         switch (client -> state) {
2752                               case S_SELECTING:
2753                                 cancel_timeout (send_discover, client);
2754                                 break;
2755
2756                               case S_BOUND:
2757                                 cancel_timeout (state_bound, client);
2758                                 break;
2759
2760                               case S_REBOOTING:
2761                               case S_REQUESTING:
2762                               case S_RENEWING:
2763                                 cancel_timeout (send_request, client);
2764                                 break;
2765
2766                               case S_INIT:
2767                               case S_REBINDING:
2768                               case S_STOPPED:
2769                                 break;
2770                         }
2771                         client -> state = S_INIT;
2772                         state_reboot (client);
2773                 }
2774         }
2775 }
2776
2777 void do_release(client) 
2778         struct client_state *client;
2779 {
2780         struct data_string ds;
2781         struct option_cache *oc;
2782
2783         /* Pick a random xid. */
2784         client -> xid = random ();
2785
2786         /* is there even a lease to release? */
2787         if (client -> active) {
2788                 /* Make a DHCPRELEASE packet, and set appropriate per-interface
2789                    flags. */
2790                 make_release (client, client -> active);
2791
2792                 memset (&ds, 0, sizeof ds);
2793                 oc = lookup_option (&dhcp_universe,
2794                                     client -> active -> options,
2795                                     DHO_DHCP_SERVER_IDENTIFIER);
2796                 if (oc &&
2797                     evaluate_option_cache (&ds, (struct packet *)0,
2798                                            (struct lease *)0, client,
2799                                            (struct option_state *)0,
2800                                            client -> active -> options,
2801                                            &global_scope, oc, MDL)) {
2802                         if (ds.len > 3) {
2803                                 memcpy (client -> destination.iabuf,
2804                                         ds.data, 4);
2805                                 client -> destination.len = 4;
2806                         } else
2807                                 client -> destination = iaddr_broadcast;
2808                 } else
2809                         client -> destination = iaddr_broadcast;
2810                 client -> first_sending = cur_time;
2811                 client -> interval = client -> config -> initial_interval;
2812         
2813                 /* Zap the medium list... */
2814                 client -> medium = (struct string_list *)0;
2815         
2816                 /* Send out the first and only DHCPRELEASE packet. */
2817                 send_release (client);
2818
2819                 /* Do the client script RELEASE operation. */
2820                 script_init (client,
2821                              "RELEASE", (struct string_list *)0);
2822                 if (client -> alias)
2823                         script_write_params (client, "alias_",
2824                                              client -> alias);
2825                 script_write_params (client, "old_", client -> active);
2826                 script_go (client);
2827         }
2828
2829         /* Cancel any timeouts. */
2830         cancel_timeout (state_bound, client);
2831         cancel_timeout (send_discover, client);
2832         cancel_timeout (state_init, client);
2833         cancel_timeout (send_request, client);
2834         cancel_timeout (state_reboot, client);
2835         client -> state = S_STOPPED;
2836 }
2837
2838 int dhclient_interface_shutdown_hook (struct interface_info *interface)
2839 {
2840         do_release (interface -> client);
2841
2842         return 1;
2843 }
2844
2845 int dhclient_interface_discovery_hook (struct interface_info *tmp)
2846 {
2847         struct interface_info *last, *ip;
2848         /* See if we can find the client from dummy_interfaces */
2849         last = 0;
2850         for (ip = dummy_interfaces; ip; ip = ip -> next) {
2851                 if (!strcmp (ip -> name, tmp -> name)) {
2852                         /* Remove from dummy_interfaces */
2853                         if (last) {
2854                                 ip = (struct interface_info *)0;
2855                                 interface_reference (&ip, last -> next, MDL);
2856                                 interface_dereference (&last -> next, MDL);
2857                                 if (ip -> next) {
2858                                         interface_reference (&last -> next,
2859                                                              ip -> next, MDL);
2860                                         interface_dereference (&ip -> next,
2861                                                                MDL);
2862                                 }
2863                         } else {
2864                                 ip = (struct interface_info *)0;
2865                                 interface_reference (&ip,
2866                                                      dummy_interfaces, MDL);
2867                                 interface_dereference (&dummy_interfaces, MDL);
2868                                 if (ip -> next) {
2869                                         interface_reference (&dummy_interfaces,
2870                                                              ip -> next, MDL);
2871                                         interface_dereference (&ip -> next,
2872                                                                MDL);
2873                                 }
2874                         }
2875                         /* Copy "client" to tmp */
2876                         if (ip -> client) {
2877                                 tmp -> client = ip -> client;
2878                                 tmp -> client -> interface = tmp;
2879                         }
2880                         interface_dereference (&ip, MDL);
2881                         break;
2882                 }
2883                 last = ip;
2884         }
2885         return 1;
2886 }
2887
2888 isc_result_t dhclient_interface_startup_hook (struct interface_info *interface)
2889 {
2890         struct interface_info *ip;
2891         struct client_state *client;
2892
2893         /* This code needs some rethinking.   It doesn't test against
2894            a signal name, and it just kind of bulls into doing something
2895            that may or may not be appropriate. */
2896
2897         if (interfaces) {
2898                 interface_reference (&interface -> next, interfaces, MDL);
2899                 interface_dereference (&interfaces, MDL);
2900         }
2901         interface_reference (&interfaces, interface, MDL);
2902
2903         discover_interfaces (DISCOVER_UNCONFIGURED);
2904
2905         for (ip = interfaces; ip; ip = ip -> next) {
2906                 /* If interfaces were specified, don't configure
2907                    interfaces that weren't specified! */
2908                 if (ip -> flags & INTERFACE_RUNNING ||
2909                    (ip -> flags & (INTERFACE_REQUESTED |
2910                                      INTERFACE_AUTOMATIC)) !=
2911                      INTERFACE_REQUESTED)
2912                         continue;
2913                 script_init (ip -> client,
2914                              "PREINIT", (struct string_list *)0);
2915                 if (ip -> client -> alias)
2916                         script_write_params (ip -> client, "alias_",
2917                                              ip -> client -> alias);
2918                 script_go (ip -> client);
2919         }
2920         
2921         discover_interfaces (interfaces_requested
2922                              ? DISCOVER_REQUESTED
2923                              : DISCOVER_RUNNING);
2924
2925         for (ip = interfaces; ip; ip = ip -> next) {
2926                 if (ip -> flags & INTERFACE_RUNNING)
2927                         continue;
2928                 ip -> flags |= INTERFACE_RUNNING;
2929                 for (client = ip -> client; client; client = client -> next) {
2930                         client -> state = S_INIT;
2931                         /* Set up a timeout to start the initialization
2932                            process. */
2933                         add_timeout (cur_time + random () % 5,
2934                                      state_reboot, client, 0, 0);
2935                 }
2936         }
2937         return ISC_R_SUCCESS;
2938 }
2939
2940 /* The client should never receive a relay agent information option,
2941    so if it does, log it and discard it. */
2942
2943 int parse_agent_information_option (packet, len, data)
2944         struct packet *packet;
2945         int len;
2946         u_int8_t *data;
2947 {
2948         return 1;
2949 }
2950
2951 /* The client never sends relay agent information options. */
2952
2953 unsigned cons_agent_information_options (cfg_options, outpacket,
2954                                          agentix, length)
2955         struct option_state *cfg_options;
2956         struct dhcp_packet *outpacket;
2957         unsigned agentix;
2958         unsigned length;
2959 {
2960         return length;
2961 }
2962
2963 static void shutdown_exit (void *foo)
2964 {
2965         exit (0);
2966 }
2967
2968 isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
2969                                      control_object_state_t newstate)
2970 {
2971         struct interface_info *ip;
2972         struct client_state *client;
2973
2974         /* Do the right thing for each interface. */
2975         for (ip = interfaces; ip; ip = ip -> next) {
2976             for (client = ip -> client; client; client = client -> next) {
2977                 switch (newstate) {
2978                   case server_startup:
2979                     return ISC_R_SUCCESS;
2980
2981                   case server_running:
2982                     return ISC_R_SUCCESS;
2983
2984                   case server_shutdown:
2985                     if (client -> active &&
2986                         client -> active -> expiry > cur_time) {
2987                             if (client -> config -> do_forward_update)
2988                                     client_dns_update (client, 0, 0);
2989                             do_release (client);
2990                     }
2991                     break;
2992
2993                   case server_hibernate:
2994                     state_stop (client);
2995                     break;
2996
2997                   case server_awaken:
2998                     state_reboot (client);
2999                     break;
3000                 }
3001             }
3002         }
3003         if (newstate == server_shutdown)
3004                 add_timeout (cur_time + 1, shutdown_exit, 0, 0, 0);
3005         return ISC_R_SUCCESS;
3006 }
3007
3008 /* Called after a timeout if the DNS update failed on the previous try.
3009    Retries the update, and if it times out, schedules a retry after
3010    ten times as long of a wait. */
3011
3012 void client_dns_update_timeout (void *cp)
3013 {
3014         struct client_state *client = cp;
3015         isc_result_t status;
3016
3017         if (client -> active) {
3018                 status = client_dns_update (client, 1,
3019                                             (client -> active -> renewal -
3020                                              cur_time));
3021                 if (status == ISC_R_TIMEDOUT) {
3022                         client -> dns_update_timeout *= 10;
3023                         add_timeout (cur_time + client -> dns_update_timeout,
3024                                      client_dns_update_timeout, client, 0, 0);
3025                 }
3026         }
3027 }
3028                         
3029 /* See if we should do a DNS update, and if so, do it. */
3030
3031 isc_result_t client_dns_update (struct client_state *client, int addp, int ttl)
3032 {
3033         struct data_string ddns_fqdn, ddns_fwd_name,
3034                ddns_dhcid, client_identifier;
3035         struct option_cache *oc;
3036         int ignorep;
3037         int result;
3038         isc_result_t rcode;
3039
3040         /* If we didn't send an FQDN option, we certainly aren't going to
3041            be doing an update. */
3042         if (!client -> sent_options)
3043                 return ISC_R_SUCCESS;
3044
3045         /* If we don't have a lease, we can't do an update. */
3046         if (!client -> active)
3047                 return ISC_R_SUCCESS;
3048
3049         /* If we set the no client update flag, don't do the update. */
3050         if ((oc = lookup_option (&fqdn_universe, client -> sent_options,
3051                                   FQDN_NO_CLIENT_UPDATE)) &&
3052             evaluate_boolean_option_cache (&ignorep, (struct packet *)0,
3053                                            (struct lease *)0, client,
3054                                            client -> sent_options,
3055                                            (struct option_state *)0,
3056                                            &global_scope, oc, MDL))
3057                 return ISC_R_SUCCESS;
3058         
3059         /* If we set the "server, please update" flag, or didn't set it
3060            to false, don't do the update. */
3061         if (!(oc = lookup_option (&fqdn_universe, client -> sent_options,
3062                                   FQDN_SERVER_UPDATE)) ||
3063             evaluate_boolean_option_cache (&ignorep, (struct packet *)0,
3064                                            (struct lease *)0, client,
3065                                            client -> sent_options,
3066                                            (struct option_state *)0,
3067                                            &global_scope, oc, MDL))
3068                 return ISC_R_SUCCESS;
3069         
3070         /* If no FQDN option was supplied, don't do the update. */
3071         memset (&ddns_fwd_name, 0, sizeof ddns_fwd_name);
3072         if (!(oc = lookup_option (&fqdn_universe, client -> sent_options,
3073                                   FQDN_FQDN)) ||
3074             !evaluate_option_cache (&ddns_fwd_name, (struct packet *)0, 
3075                                     (struct lease *)0, client,
3076                                     client -> sent_options,
3077                                     (struct option_state *)0,
3078                                     &global_scope, oc, MDL))
3079                 return ISC_R_SUCCESS;
3080
3081         /* Make a dhcid string out of either the client identifier,
3082            if we are sending one, or the interface's MAC address,
3083            otherwise. */
3084         memset (&ddns_dhcid, 0, sizeof ddns_dhcid);
3085
3086         memset (&client_identifier, 0, sizeof client_identifier);
3087         if ((oc = lookup_option (&dhcp_universe, client -> sent_options,
3088                                  DHO_DHCP_CLIENT_IDENTIFIER)) &&
3089             evaluate_option_cache (&client_identifier, (struct packet *)0, 
3090                                    (struct lease *)0, client,
3091                                    client -> sent_options,
3092                                    (struct option_state *)0,
3093                                    &global_scope, oc, MDL)) {
3094                 result = get_dhcid (&ddns_dhcid,
3095                                     DHO_DHCP_CLIENT_IDENTIFIER,
3096                                     client_identifier.data,
3097                                     client_identifier.len);
3098                 data_string_forget (&client_identifier, MDL);
3099         } else
3100                 result = get_dhcid (&ddns_dhcid, 0,
3101                                     client -> interface -> hw_address.hbuf,
3102                                     client -> interface -> hw_address.hlen);
3103         if (!result) {
3104                 data_string_forget (&ddns_fwd_name, MDL);
3105                 return ISC_R_SUCCESS;
3106         }
3107
3108         /* Start the resolver, if necessary. */
3109         if (!resolver_inited) {
3110                 minires_ninit (&resolver_state);
3111                 resolver_inited = 1;
3112                 resolver_state.retrans = 1;
3113                 resolver_state.retry = 1;
3114         }
3115
3116         /*
3117          * Perform updates.
3118          */
3119         if (ddns_fwd_name.len && ddns_dhcid.len) {
3120                 if (addp)
3121                         rcode = ddns_update_a (&ddns_fwd_name,
3122                                                client -> active -> address,
3123                                                &ddns_dhcid, ttl,
3124                                                1);
3125                 else
3126                         rcode = ddns_remove_a (&ddns_fwd_name,
3127                                                client -> active -> address,
3128                                                &ddns_dhcid);
3129         }
3130         
3131         data_string_forget (&ddns_fwd_name, MDL);
3132         data_string_forget (&ddns_dhcid, MDL);
3133         return rcode;
3134 }