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