6 * Copyright (c) 1995-2002 Internet Software Consortium.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of Internet Software Consortium nor the names
19 * of its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
23 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * This code is based on the original client state machine that was
37 * written by Elliot Poger. The code has been extensively hacked on
38 * by Ted Lemon since then, so any mistakes you find are probably his
39 * fault and not Elliot's.
41 * @(#) Copyright (c) 1995-2002 Internet Software Consortium. All rights reserved.";
42 * $Id: dhclient.c,v 1.129.2.12 2002/11/07 23:26:38 dhankins Exp $
43 * $FreeBSD: src/contrib/isc-dhcp/client/dhclient.c,v 1.9.2.8 2003/03/23 23:33:05 mbr Exp $
44 * $DragonFly: src/contrib/isc-dhcp/client/Attic/dhclient.c,v 1.2 2003/06/17 04:24:02 dillon Exp $
47 static char ocopyright[] = "$Id: dhclient.c,v 1.129.2.12 2002/11/07 23:26:38 dhankins Exp $ Copyright (c) 1995-2002 Internet Software Consortium. All rights reserved.";
53 TIME default_lease_time = 43200; /* 12 hours... */
54 TIME max_lease_time = 86400; /* 24 hours... */
56 const char *path_dhclient_conf = _PATH_DHCLIENT_CONF;
57 const char *path_dhclient_db = _PATH_DHCLIENT_DB;
58 const char *path_dhclient_pid = _PATH_DHCLIENT_PID;
59 static char path_dhclient_script_array [] = _PATH_DHCLIENT_SCRIPT;
60 char *path_dhclient_script = path_dhclient_script_array;
62 int dhcp_max_agent_option_packet_length = 0;
64 int interfaces_requested = 0;
66 struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } };
67 struct iaddr iaddr_any = { 4, { 0, 0, 0, 0 } };
68 struct in_addr inaddr_any;
69 struct sockaddr_in sockaddr_broadcast;
70 struct in_addr giaddr;
72 /* ASSERT_STATE() does nothing now; it used to be
73 assert (state_is == state_shouldbe). */
74 #define ASSERT_STATE(state_is, state_shouldbe) {}
76 static char copyright[] = "Copyright 1995-2002 Internet Software Consortium.";
77 static char arr [] = "All rights reserved.";
78 static char message [] = "Internet Software Consortium DHCP Client";
79 static char url [] = "For info, please visit http://www.isc.org/products/DHCP";
81 u_int16_t local_port=0;
82 u_int16_t remote_port=0;
84 struct string_list *client_env=NULL;
85 int client_env_count=0;
90 static void usage PROTO ((void));
92 void do_release(struct client_state *);
94 int main (argc, argv, envp)
100 struct interface_info *ip;
101 struct client_state *client;
103 char *server = (char *)0;
104 char *relay = (char *)0;
106 int release_mode = 0;
107 omapi_object_t *listener;
111 int no_dhclient_conf = 0;
112 int no_dhclient_db = 0;
113 int no_dhclient_pid = 0;
114 int no_dhclient_script = 0;
120 /* Make sure we have stdin, stdout and stderr. */
121 i = open ("/dev/null", O_RDWR);
123 i = open ("/dev/null", O_RDWR);
125 i = open ("/dev/null", O_RDWR);
126 log_perror = 0; /* No sense logging to /dev/null. */
131 openlog ("dhclient", LOG_NDELAY);
132 log_priority = LOG_DAEMON;
134 openlog ("dhclient", LOG_NDELAY, LOG_DAEMON);
137 #if !(defined (DEBUG) || defined (SYSLOG_4_2) || defined (__CYGWIN32__))
138 setlogmask (LOG_UPTO (LOG_INFO));
141 /* Set up the OMAPI. */
142 status = omapi_init ();
143 if (status != ISC_R_SUCCESS)
144 log_fatal ("Can't initialize OMAPI: %s",
145 isc_result_totext (status));
147 /* Set up the OMAPI wrappers for various server database internal
149 dhcp_common_objects_setup ();
151 dhcp_interface_discovery_hook = dhclient_interface_discovery_hook;
152 dhcp_interface_shutdown_hook = dhclient_interface_shutdown_hook;
153 dhcp_interface_startup_hook = dhclient_interface_startup_hook;
155 for (i = 1; i < argc; i++) {
156 if (!strcmp (argv [i], "-r")) {
159 } else if (!strcmp (argv [i], "-p")) {
162 local_port = htons (atoi (argv [i]));
163 log_debug ("binding to user-specified port %d",
165 } else if (!strcmp (argv [i], "-d")) {
167 } else if (!strcmp (argv [i], "-pf")) {
170 path_dhclient_pid = argv [i];
172 } else if (!strcmp (argv [i], "-cf")) {
175 path_dhclient_conf = argv [i];
176 no_dhclient_conf = 1;
177 } else if (!strcmp (argv [i], "-lf")) {
180 path_dhclient_db = argv [i];
182 } else if (!strcmp (argv [i], "-sf")) {
185 path_dhclient_script = argv [i];
186 no_dhclient_script = 1;
187 } else if (!strcmp (argv [i], "-1")) {
189 } else if (!strcmp (argv [i], "-q")) {
191 quiet_interface_discovery = 1;
192 } else if (!strcmp (argv [i], "-s")) {
196 } else if (!strcmp (argv [i], "-g")) {
200 } else if (!strcmp (argv [i], "-n")) {
201 /* do not start up any interfaces */
202 interfaces_requested = 1;
203 } else if (!strcmp (argv [i], "-w")) {
204 /* do not exit if there are no broadcast interfaces. */
206 } else if (!strcmp (argv [i], "-e")) {
207 struct string_list *tmp;
210 tmp = dmalloc (strlen (argv [i]) + sizeof *tmp, MDL);
212 log_fatal ("No memory for %s", argv [i]);
213 strcpy (tmp -> string, argv [i]);
214 tmp -> next = client_env;
217 } else if (!strcmp (argv [i], "--version")) {
218 log_info ("isc-dhclient-%s", DHCP_VERSION);
220 } else if (!strcmp (argv [i], "-nw")) {
222 } else if (argv [i][0] == '-') {
225 struct interface_info *tmp = (struct interface_info *)0;
226 status = interface_allocate (&tmp, MDL);
227 if (status != ISC_R_SUCCESS)
228 log_fatal ("Can't record interface %s:%s",
229 argv [i], isc_result_totext (status));
230 if (strlen (argv [i]) > sizeof tmp -> name)
231 log_fatal ("%s: interface name too long (max %ld)",
232 argv [i], (long)strlen (argv [i]));
233 strlcpy (tmp -> name, argv [i], IFNAMSIZ);
235 interface_reference (&tmp -> next,
237 interface_dereference (&interfaces, MDL);
239 interface_reference (&interfaces, tmp, MDL);
240 tmp -> flags = INTERFACE_REQUESTED;
241 interfaces_requested = 1;
245 if (!no_dhclient_conf && (s = getenv ("PATH_DHCLIENT_CONF"))) {
246 path_dhclient_conf = s;
248 if (!no_dhclient_db && (s = getenv ("PATH_DHCLIENT_DB"))) {
249 path_dhclient_db = s;
251 if (!no_dhclient_pid && (s = getenv ("PATH_DHCLIENT_PID"))) {
252 path_dhclient_pid = s;
254 if (!no_dhclient_script && (s = getenv ("PATH_DHCLIENT_SCRIPT"))) {
255 path_dhclient_script = s;
258 /* first kill of any currently running client */
261 if ((pidfd = fopen(path_dhclient_pid, "r")) != NULL) {
262 e = fscanf(pidfd, "%d", &oldpid);
264 if (e != 0 && e != EOF) {
266 if (kill(oldpid, SIGKILL) == 0)
267 unlink(path_dhclient_pid);
275 log_info ("%s %s", message, DHCP_VERSION);
276 log_info (copyright);
283 /* If we're given a relay agent address to insert, for testing
284 purposes, figure out what it is. */
286 if (!inet_aton (relay, &giaddr)) {
288 he = gethostbyname (relay);
290 memcpy (&giaddr, he -> h_addr_list [0],
293 log_fatal ("%s: no such host", relay);
298 /* Default to the DHCP/BOOTP port. */
300 /* If we're faking a relay agent, and we're not using loopback,
301 use the server port, not the client port. */
302 if (relay && giaddr.s_addr != htonl (INADDR_LOOPBACK)) {
303 local_port = htons(67);
305 ent = getservbyname ("dhcpc", "udp");
307 local_port = htons (68);
309 local_port = ent -> s_port;
316 /* If we're faking a relay agent, and we're not using loopback,
317 we're using the server port, not the client port. */
318 if (relay && giaddr.s_addr != htonl (INADDR_LOOPBACK)) {
319 remote_port = local_port;
321 remote_port = htons (ntohs (local_port) - 1); /* XXX */
323 /* Get the current time... */
324 GET_TIME (&cur_time);
326 sockaddr_broadcast.sin_family = AF_INET;
327 sockaddr_broadcast.sin_port = remote_port;
329 if (!inet_aton (server, &sockaddr_broadcast.sin_addr)) {
331 he = gethostbyname (server);
333 memcpy (&sockaddr_broadcast.sin_addr,
334 he -> h_addr_list [0],
335 sizeof sockaddr_broadcast.sin_addr);
337 sockaddr_broadcast.sin_addr.s_addr =
341 sockaddr_broadcast.sin_addr.s_addr = INADDR_BROADCAST;
344 inaddr_any.s_addr = INADDR_ANY;
346 /* Discover all the network interfaces. */
347 discover_interfaces (DISCOVER_UNCONFIGURED);
349 /* Parse the dhclient.conf file. */
352 /* Parse the lease database. */
353 read_client_leases ();
355 /* Rewrite the lease database... */
356 rewrite_client_leases ();
359 /* config_counter(&snd_counter, &rcv_counter); */
361 /* If no broadcast interfaces were discovered, call the script
364 /* Call dhclient-script with the NBI flag, in case somebody
366 script_init ((struct client_state *)0, "NBI",
367 (struct string_list *)0);
368 script_go ((struct client_state *)0);
370 /* If we haven't been asked to persist, waiting for new
371 interfaces, then just exit. */
373 /* Nothing more to do. */
374 log_info ("No broadcast interfaces found - exiting.");
377 } else if (!release_mode) {
378 /* Call the script with the list of interfaces. */
379 for (ip = interfaces; ip; ip = ip -> next) {
380 /* If interfaces were specified, don't configure
381 interfaces that weren't specified! */
382 if (interfaces_requested &&
383 ((ip -> flags & (INTERFACE_REQUESTED |
384 INTERFACE_AUTOMATIC)) !=
385 INTERFACE_REQUESTED))
387 script_init (ip -> client,
388 "PREINIT", (struct string_list *)0);
389 if (ip -> client -> alias)
390 script_write_params (ip -> client, "alias_",
391 ip -> client -> alias);
392 script_go (ip -> client);
396 /* At this point, all the interfaces that the script thinks
397 are relevant should be running, so now we once again call
398 discover_interfaces(), and this time ask it to actually set
399 up the interfaces. */
400 discover_interfaces (interfaces_requested
404 /* Make up a seed for the random number generator from current
405 time plus the sum of the last four bytes of each
406 interface's hardware address interpreted as an integer.
407 Not much entropy, but we're booting, so we're not likely to
408 find anything better. */
410 for (ip = interfaces; ip; ip = ip -> next) {
413 &ip -> hw_address.hbuf [ip -> hw_address.hlen -
414 sizeof seed], sizeof seed);
417 srandom (seed + cur_time);
419 /* Start a configuration state machine for each interface. */
420 for (ip = interfaces; ip; ip = ip -> next) {
421 ip -> flags |= INTERFACE_RUNNING;
422 for (client = ip -> client; client; client = client -> next) {
426 client -> state = S_INIT;
427 /* Set up a timeout to start the initialization
429 add_timeout (cur_time + random () % 5,
430 state_reboot, client, 0, 0);
438 /* Start up a listener for the object management API protocol. */
439 if (top_level_config.omapi_port != -1) {
440 listener = (omapi_object_t *)0;
441 result = omapi_generic_new (&listener, MDL);
442 if (result != ISC_R_SUCCESS)
443 log_fatal ("Can't allocate new generic object: %s\n",
444 isc_result_totext (result));
445 result = omapi_protocol_listen (listener,
447 top_level_config.omapi_port,
449 if (result != ISC_R_SUCCESS)
450 log_fatal ("Can't start OMAPI protocol: %s",
451 isc_result_totext (result));
454 /* Set up the bootp packet handler... */
455 bootp_packet_handler = do_packet;
457 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
458 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
459 dmalloc_cutoff_generation = dmalloc_generation;
460 dmalloc_longterm = dmalloc_outstanding;
461 dmalloc_outstanding = 0;
464 /* If we're not supposed to wait before getting the address,
469 /* If we're not going to daemonize, write the pid file
471 if (no_daemon || nowait)
472 write_client_pid_file ();
474 /* Start dispatching packets and timeouts... */
483 log_info ("%s %s", message, DHCP_VERSION);
484 log_info (copyright);
488 log_error ("Usage: dhclient [-1Ddqr] [-nw] [-p <port>] %s",
490 log_error (" [-cf config-file] [-lf lease-file]%s",
491 "[-pf pid-file] [-e VAR=val]");
492 log_fatal (" [-sf script-file] [interface]");
495 isc_result_t find_class (struct class **c,
496 const char *s, const char *file, int line)
501 int check_collection (packet, lease, collection)
502 struct packet *packet;
504 struct collection *collection;
509 void classify (packet, class)
510 struct packet *packet;
515 int unbill_class (lease, class)
522 int find_subnet (struct subnet **sp,
523 struct iaddr addr, const char *file, int line)
528 /* Individual States:
530 * Each routine is called from the dhclient_state_machine() in one of
532 * -> entering INIT state
533 * -> recvpacket_flag == 0: timeout in this state
534 * -> otherwise: received a packet in this state
536 * Return conditions as handled by dhclient_state_machine():
537 * Returns 1, sendpacket_flag = 1: send packet, reset timer.
538 * Returns 1, sendpacket_flag = 0: just reset the timer (wait for a milestone).
539 * Returns 0: finish the nap which was interrupted for no good reason.
541 * Several per-interface variables are used to keep track of the process:
542 * active_lease: the lease that is being used on the interface
543 * (null pointer if not configured yet).
544 * offered_leases: leases corresponding to DHCPOFFER messages that have
545 * been sent to us by DHCP servers.
546 * acked_leases: leases corresponding to DHCPACK messages that have been
547 * sent to us by DHCP servers.
548 * sendpacket: DHCP packet we're trying to send.
549 * destination: IP address to send sendpacket to
550 * In addition, there are several relevant per-lease variables.
551 * T1_expiry, T2_expiry, lease_expiry: lease milestones
552 * In the active lease, these control the process of renewing the lease;
553 * In leases on the acked_leases list, this simply determines when we
554 * can no longer legitimately use the lease.
557 void state_reboot (cpp)
560 struct client_state *client = cpp;
562 /* If we don't remember an active lease, go straight to INIT. */
563 if (!client -> active ||
564 client -> active -> is_bootp ||
565 client -> active -> expiry <= cur_time) {
570 /* We are in the rebooting state. */
571 client -> state = S_REBOOTING;
573 /* make_request doesn't initialize xid because it normally comes
574 from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
575 so pick an xid now. */
576 client -> xid = random ();
578 /* Make a DHCPREQUEST packet, and set appropriate per-interface
580 make_request (client, client -> active);
581 client -> destination = iaddr_broadcast;
582 client -> first_sending = cur_time;
583 client -> interval = client -> config -> initial_interval;
585 /* Zap the medium list... */
586 client -> medium = (struct string_list *)0;
588 /* Send out the first DHCPREQUEST packet. */
589 send_request (client);
592 /* Called when a lease has completely expired and we've been unable to
595 void state_init (cpp)
598 struct client_state *client = cpp;
600 ASSERT_STATE(state, S_INIT);
602 /* Make a DHCPDISCOVER packet, and set appropriate per-interface
604 make_discover (client, client -> active);
605 client -> xid = client -> packet.xid;
606 client -> destination = iaddr_broadcast;
607 client -> state = S_SELECTING;
608 client -> first_sending = cur_time;
609 client -> interval = client -> config -> initial_interval;
611 /* Add an immediate timeout to cause the first DHCPDISCOVER packet
613 send_discover (client);
616 /* state_selecting is called when one or more DHCPOFFER packets have been
617 received and a configurable period of time has passed. */
619 void state_selecting (cpp)
622 struct client_state *client = cpp;
623 struct client_lease *lp, *next, *picked;
626 ASSERT_STATE(state, S_SELECTING);
628 /* Cancel state_selecting and send_discover timeouts, since either
629 one could have got us here. */
630 cancel_timeout (state_selecting, client);
631 cancel_timeout (send_discover, client);
633 /* We have received one or more DHCPOFFER packets. Currently,
634 the only criterion by which we judge leases is whether or
635 not we get a response when we arp for them. */
636 picked = (struct client_lease *)0;
637 for (lp = client -> offered_leases; lp; lp = next) {
640 /* Check to see if we got an ARPREPLY for the address
641 in this particular lease. */
644 picked -> next = (struct client_lease *)0;
647 destroy_client_lease (lp);
650 client -> offered_leases = (struct client_lease *)0;
652 /* If we just tossed all the leases we were offered, go back
655 client -> state = S_INIT;
660 /* If it was a BOOTREPLY, we can just take the address right now. */
661 if (picked -> is_bootp) {
662 client -> new = picked;
664 /* Make up some lease expiry times
665 XXX these should be configurable. */
666 client -> new -> expiry = cur_time + 12000;
667 client -> new -> renewal += cur_time + 8000;
668 client -> new -> rebind += cur_time + 10000;
670 client -> state = S_REQUESTING;
672 /* Bind to the address we received. */
677 /* Go to the REQUESTING state. */
678 client -> destination = iaddr_broadcast;
679 client -> state = S_REQUESTING;
680 client -> first_sending = cur_time;
681 client -> interval = client -> config -> initial_interval;
683 /* Make a DHCPREQUEST packet from the lease we picked. */
684 make_request (client, picked);
685 client -> xid = client -> packet.xid;
687 /* Toss the lease we picked - we'll get it back in a DHCPACK. */
688 destroy_client_lease (picked);
690 /* Add an immediate timeout to send the first DHCPREQUEST packet. */
691 send_request (client);
694 /* state_requesting is called when we receive a DHCPACK message after
695 having sent out one or more DHCPREQUEST packets. */
697 void dhcpack (packet)
698 struct packet *packet;
700 struct interface_info *ip = packet -> interface;
701 struct client_state *client;
702 struct client_lease *lease;
703 struct option_cache *oc;
704 struct data_string ds;
707 /* If we're not receptive to an offer right now, or if the offer
708 has an unrecognizable transaction id, then just drop it. */
709 for (client = ip -> client; client; client = client -> next) {
710 if (client -> xid == packet -> raw -> xid)
714 (packet -> interface -> hw_address.hlen - 1 !=
715 packet -> raw -> hlen) ||
716 (memcmp (&packet -> interface -> hw_address.hbuf [1],
717 packet -> raw -> chaddr, packet -> raw -> hlen))) {
719 log_debug ("DHCPACK in wrong transaction.");
724 if (client -> state != S_REBOOTING &&
725 client -> state != S_REQUESTING &&
726 client -> state != S_RENEWING &&
727 client -> state != S_REBINDING) {
729 log_debug ("DHCPACK in wrong state.");
734 log_info ("DHCPACK from %s", piaddr (packet -> client_addr));
736 lease = packet_to_lease (packet, client);
738 log_info ("packet_to_lease failed.");
742 client -> new = lease;
744 /* Stop resending DHCPREQUEST. */
745 cancel_timeout (send_request, client);
747 /* Figure out the lease time. */
748 oc = lookup_option (&dhcp_universe, client -> new -> options,
749 DHO_DHCP_LEASE_TIME);
750 memset (&ds, 0, sizeof ds);
752 evaluate_option_cache (&ds, packet, (struct lease *)0, client,
753 packet -> options, client -> new -> options,
754 &global_scope, oc, MDL)) {
756 client -> new -> expiry = getULong (ds.data);
758 client -> new -> expiry = 0;
759 data_string_forget (&ds, MDL);
761 client -> new -> expiry = 0;
763 if (!client -> new -> expiry) {
764 log_error ("no expiry time on offered lease.");
765 /* XXX this is going to be bad - if this _does_
766 XXX happen, we should probably dynamically
767 XXX disqualify the DHCP server that gave us the
768 XXX bad packet from future selections and
769 XXX then go back into the init state. */
774 /* A number that looks negative here is really just very large,
775 because the lease expiry offset is unsigned. */
776 if (client -> new -> expiry < 0)
777 client -> new -> expiry = TIME_MAX;
778 /* Take the server-provided renewal time if there is one. */
779 oc = lookup_option (&dhcp_universe, client -> new -> options,
780 DHO_DHCP_RENEWAL_TIME);
782 evaluate_option_cache (&ds, packet, (struct lease *)0, client,
783 packet -> options, client -> new -> options,
784 &global_scope, oc, MDL)) {
786 client -> new -> renewal = getULong (ds.data);
788 client -> new -> renewal = 0;
789 data_string_forget (&ds, MDL);
791 client -> new -> renewal = 0;
793 /* If it wasn't specified by the server, calculate it. */
794 if (!client -> new -> renewal)
795 client -> new -> renewal =
796 client -> new -> expiry / 2;
798 /* Now introduce some randomness to the renewal time: */
799 client -> new -> renewal = (((client -> new -> renewal + 3) * 3 / 4) +
800 (random () % /* XXX NUMS */
801 ((client -> new -> renewal + 3) / 4)));
803 /* Same deal with the rebind time. */
804 oc = lookup_option (&dhcp_universe, client -> new -> options,
805 DHO_DHCP_REBINDING_TIME);
807 evaluate_option_cache (&ds, packet, (struct lease *)0, client,
808 packet -> options, client -> new -> options,
809 &global_scope, oc, MDL)) {
811 client -> new -> rebind = getULong (ds.data);
813 client -> new -> rebind = 0;
814 data_string_forget (&ds, MDL);
816 client -> new -> rebind = 0;
818 if (!client -> new -> rebind)
819 client -> new -> rebind =
820 (client -> new -> expiry * 7) / 8; /* XXX NUMS */
822 /* Make sure our randomness didn't run the renewal time past the
824 if (client -> new -> renewal > client -> new -> rebind)
825 client -> new -> renewal = (client -> new -> rebind * 3) / 4;
827 client -> new -> expiry += cur_time;
828 /* Lease lengths can never be negative. */
829 if (client -> new -> expiry < cur_time)
830 client -> new -> expiry = TIME_MAX;
831 client -> new -> renewal += cur_time;
832 if (client -> new -> renewal < cur_time)
833 client -> new -> renewal = TIME_MAX;
834 client -> new -> rebind += cur_time;
835 if (client -> new -> rebind < cur_time)
836 client -> new -> rebind = TIME_MAX;
841 void bind_lease (client)
842 struct client_state *client;
844 struct interface_info *ip = client -> interface;
846 /* Remember the medium. */
847 client -> new -> medium = client -> medium;
849 /* Run the client script with the new parameters. */
850 script_init (client, (client -> state == S_REQUESTING
852 : (client -> state == S_RENEWING
854 : (client -> state == S_REBOOTING
855 ? "REBOOT" : "REBIND"))),
856 client -> new -> medium);
857 if (client -> active && client -> state != S_REBOOTING)
858 script_write_params (client, "old_", client -> active);
859 script_write_params (client, "new_", client -> new);
861 script_write_params (client, "alias_", client -> alias);
863 /* If the BOUND/RENEW code detects another machine using the
864 offered address, it exits nonzero. We need to send a
865 DHCPDECLINE and toss the lease. */
866 if (script_go (client)) {
867 make_decline (client, client -> new);
868 send_decline (client);
869 destroy_client_lease (client -> new);
870 client -> new = (struct client_lease *)0;
875 /* Write out the new lease. */
876 write_client_lease (client, client -> new, 0, 0);
878 /* Replace the old active lease with the new one. */
879 if (client -> active)
880 destroy_client_lease (client -> active);
881 client -> active = client -> new;
882 client -> new = (struct client_lease *)0;
884 /* Set up a timeout to start the renewal process. */
885 add_timeout (client -> active -> renewal,
886 state_bound, client, 0, 0);
888 log_info ("bound to %s -- renewal in %ld seconds.",
889 piaddr (client -> active -> address),
890 (long)(client -> active -> renewal - cur_time));
891 client -> state = S_BOUND;
892 reinitialize_interfaces ();
894 if (client -> config -> do_forward_update) {
895 client -> dns_update_timeout = 1;
896 add_timeout (cur_time + 1, client_dns_update_timeout,
901 /* state_bound is called when we've successfully bound to a particular
902 lease, but the renewal time on that lease has expired. We are
903 expected to unicast a DHCPREQUEST to the server that gave us our
906 void state_bound (cpp)
909 struct client_state *client = cpp;
911 struct option_cache *oc;
912 struct data_string ds;
914 ASSERT_STATE(state, S_BOUND);
916 /* T1 has expired. */
917 make_request (client, client -> active);
918 client -> xid = client -> packet.xid;
920 memset (&ds, 0, sizeof ds);
921 oc = lookup_option (&dhcp_universe, client -> active -> options,
922 DHO_DHCP_SERVER_IDENTIFIER);
924 evaluate_option_cache (&ds, (struct packet *)0, (struct lease *)0,
925 client, (struct option_state *)0,
926 client -> active -> options,
927 &global_scope, oc, MDL)) {
929 memcpy (client -> destination.iabuf, ds.data, 4);
930 client -> destination.len = 4;
932 client -> destination = iaddr_broadcast;
934 client -> destination = iaddr_broadcast;
936 client -> first_sending = cur_time;
937 client -> interval = client -> config -> initial_interval;
938 client -> state = S_RENEWING;
940 /* Send the first packet immediately. */
941 send_request (client);
944 /* state_stop is called when we've been told to shut down. We unconfigure
945 the interfaces, and then stop operating until told otherwise. */
947 void state_stop (cpp)
950 struct client_state *client = cpp;
953 /* Cancel all timeouts. */
954 cancel_timeout (state_selecting, client);
955 cancel_timeout (send_discover, client);
956 cancel_timeout (send_request, client);
957 cancel_timeout (state_bound, client);
959 /* If we have an address, unconfigure it. */
960 if (client -> active) {
961 script_init (client, "STOP", client -> active -> medium);
962 script_write_params (client, "old_", client -> active);
964 script_write_params (client, "alias_",
975 int write_lease (lease)
981 int write_host (host)
982 struct host_decl *host;
987 void db_startup (testp)
993 struct packet *packet;
995 struct iaddrlist *ap;
997 if (packet -> raw -> op != BOOTREPLY)
1000 /* If there's a reject list, make sure this packet's sender isn't
1002 for (ap = packet -> interface -> client -> config -> reject_list;
1003 ap; ap = ap -> next) {
1004 if (addr_eq (packet -> client_addr, ap -> addr)) {
1005 log_info ("BOOTREPLY from %s rejected.",
1006 piaddr (ap -> addr));
1016 struct packet *packet;
1018 struct iaddrlist *ap;
1019 void (*handler) PROTO ((struct packet *));
1022 switch (packet -> packet_type) {
1024 handler = dhcpoffer;
1042 /* If there's a reject list, make sure this packet's sender isn't
1044 for (ap = packet -> interface -> client -> config -> reject_list;
1045 ap; ap = ap -> next) {
1046 if (addr_eq (packet -> client_addr, ap -> addr)) {
1047 log_info ("%s from %s rejected.",
1048 type, piaddr (ap -> addr));
1052 (*handler) (packet);
1055 void dhcpoffer (packet)
1056 struct packet *packet;
1058 struct interface_info *ip = packet -> interface;
1059 struct client_state *client;
1060 struct client_lease *lease, *lp;
1063 const char *name = packet -> packet_type ? "DHCPOFFER" : "BOOTREPLY";
1064 struct iaddrlist *ap;
1065 struct option_cache *oc;
1069 dump_packet (packet);
1072 /* Find a client state that matches the xid... */
1073 for (client = ip -> client; client; client = client -> next)
1074 if (client -> xid == packet -> raw -> xid)
1077 /* If we're not receptive to an offer right now, or if the offer
1078 has an unrecognizable transaction id, then just drop it. */
1080 client -> state != S_SELECTING ||
1081 (packet -> interface -> hw_address.hlen - 1 !=
1082 packet -> raw -> hlen) ||
1083 (memcmp (&packet -> interface -> hw_address.hbuf [1],
1084 packet -> raw -> chaddr, packet -> raw -> hlen))) {
1086 log_debug ("%s in wrong transaction.", name);
1091 sprintf (obuf, "%s from %s", name, piaddr (packet -> client_addr));
1094 /* If this lease doesn't supply the minimum required parameters,
1096 if (client -> config -> required_options) {
1097 for (i = 0; client -> config -> required_options [i]; i++) {
1099 (&dhcp_universe, packet -> options,
1100 client -> config -> required_options [i])) {
1101 log_info ("%s: no %s option.",
1102 obuf, (dhcp_universe.options
1103 [client -> config -> required_options [i]]
1110 /* If we've already seen this lease, don't record it again. */
1111 for (lease = client -> offered_leases; lease; lease = lease -> next) {
1112 if (lease -> address.len == sizeof packet -> raw -> yiaddr &&
1113 !memcmp (lease -> address.iabuf,
1114 &packet -> raw -> yiaddr, lease -> address.len)) {
1115 log_debug ("%s: already seen.", obuf);
1120 lease = packet_to_lease (packet, client);
1122 log_info ("%s: packet_to_lease failed.", obuf);
1126 /* If this lease was acquired through a BOOTREPLY, record that
1128 if (!packet -> options_valid || !packet -> packet_type)
1129 lease -> is_bootp = 1;
1131 /* Record the medium under which this lease was offered. */
1132 lease -> medium = client -> medium;
1134 /* Figure out when we're supposed to stop selecting. */
1135 stop_selecting = (client -> first_sending +
1136 client -> config -> select_interval);
1138 /* If this is the lease we asked for, put it at the head of the
1139 list, and don't mess with the arp request timeout. */
1140 if (lease -> address.len == client -> requested_address.len &&
1141 !memcmp (lease -> address.iabuf,
1142 client -> requested_address.iabuf,
1143 client -> requested_address.len)) {
1144 lease -> next = client -> offered_leases;
1145 client -> offered_leases = lease;
1147 /* Put the lease at the end of the list. */
1148 lease -> next = (struct client_lease *)0;
1149 if (!client -> offered_leases)
1150 client -> offered_leases = lease;
1152 for (lp = client -> offered_leases; lp -> next;
1159 /* If the selecting interval has expired, go immediately to
1160 state_selecting(). Otherwise, time out into
1161 state_selecting at the select interval. */
1162 if (stop_selecting <= 0)
1163 state_selecting (client);
1165 add_timeout (stop_selecting, state_selecting, client, 0, 0);
1166 cancel_timeout (send_discover, client);
1168 log_info ("%s", obuf);
1171 /* Allocate a client_lease structure and initialize it from the parameters
1172 in the specified packet. */
1174 struct client_lease *packet_to_lease (packet, client)
1175 struct packet *packet;
1176 struct client_state *client;
1178 struct client_lease *lease;
1180 struct option_cache *oc;
1181 struct data_string data;
1183 lease = (struct client_lease *)new_client_lease (MDL);
1186 log_error ("packet_to_lease: no memory to record lease.\n");
1187 return (struct client_lease *)0;
1190 memset (lease, 0, sizeof *lease);
1192 /* Copy the lease options. */
1193 option_state_reference (&lease -> options, packet -> options, MDL);
1195 lease -> address.len = sizeof (packet -> raw -> yiaddr);
1196 memcpy (lease -> address.iabuf, &packet -> raw -> yiaddr,
1197 lease -> address.len);
1199 memset (&data, 0, sizeof data);
1201 if (client -> config -> vendor_space_name) {
1202 i = DHO_VENDOR_ENCAPSULATED_OPTIONS;
1204 /* See if there was a vendor encapsulation option. */
1205 oc = lookup_option (&dhcp_universe, lease -> options, i);
1207 client -> config -> vendor_space_name &&
1208 evaluate_option_cache (&data, packet,
1209 (struct lease *)0, client,
1210 packet -> options, lease -> options,
1211 &global_scope, oc, MDL)) {
1213 parse_encapsulated_suboptions
1214 (packet -> options, &dhcp_options [i],
1215 data.data, data.len, &dhcp_universe,
1216 client -> config -> vendor_space_name
1219 data_string_forget (&data, MDL);
1224 /* Figure out the overload flag. */
1225 oc = lookup_option (&dhcp_universe, lease -> options,
1226 DHO_DHCP_OPTION_OVERLOAD);
1228 evaluate_option_cache (&data, packet, (struct lease *)0, client,
1229 packet -> options, lease -> options,
1230 &global_scope, oc, MDL)) {
1235 data_string_forget (&data, MDL);
1239 /* If the server name was filled out, copy it. */
1240 if (!(i & 2) && packet -> raw -> sname [0]) {
1242 /* Don't count on the NUL terminator. */
1243 for (len = 0; len < 64; len++)
1244 if (!packet -> raw -> sname [len])
1246 lease -> server_name = dmalloc (len + 1, MDL);
1247 if (!lease -> server_name) {
1248 log_error ("dhcpoffer: no memory for filename.\n");
1249 destroy_client_lease (lease);
1250 return (struct client_lease *)0;
1252 memcpy (lease -> server_name,
1253 packet -> raw -> sname, len);
1254 lease -> server_name [len] = 0;
1258 /* Ditto for the filename. */
1259 if (!(i & 1) && packet -> raw -> file [0]) {
1261 /* Don't count on the NUL terminator. */
1262 for (len = 0; len < 64; len++)
1263 if (!packet -> raw -> file [len])
1265 lease -> filename = dmalloc (len + 1, MDL);
1266 if (!lease -> filename) {
1267 log_error ("dhcpoffer: no memory for filename.\n");
1268 destroy_client_lease (lease);
1269 return (struct client_lease *)0;
1271 memcpy (lease -> filename,
1272 packet -> raw -> file, len);
1273 lease -> filename [len] = 0;
1277 execute_statements_in_scope ((struct binding_value **)0,
1278 (struct packet *)packet,
1279 (struct lease *)0, client,
1280 lease -> options, lease -> options,
1282 client -> config -> on_receipt,
1288 void dhcpnak (packet)
1289 struct packet *packet;
1291 struct interface_info *ip = packet -> interface;
1292 struct client_state *client;
1294 /* Find a client state that matches the xid... */
1295 for (client = ip -> client; client; client = client -> next)
1296 if (client -> xid == packet -> raw -> xid)
1299 /* If we're not receptive to an offer right now, or if the offer
1300 has an unrecognizable transaction id, then just drop it. */
1302 (packet -> interface -> hw_address.hlen - 1 !=
1303 packet -> raw -> hlen) ||
1304 (memcmp (&packet -> interface -> hw_address.hbuf [1],
1305 packet -> raw -> chaddr, packet -> raw -> hlen))) {
1307 log_debug ("DHCPNAK in wrong transaction.");
1312 if (client -> state != S_REBOOTING &&
1313 client -> state != S_REQUESTING &&
1314 client -> state != S_RENEWING &&
1315 client -> state != S_REBINDING) {
1317 log_debug ("DHCPNAK in wrong state.");
1322 log_info ("DHCPNAK from %s", piaddr (packet -> client_addr));
1324 if (!client -> active) {
1326 log_info ("DHCPNAK with no active lease.\n");
1331 destroy_client_lease (client -> active);
1332 client -> active = (struct client_lease *)0;
1334 /* Stop sending DHCPREQUEST packets... */
1335 cancel_timeout (send_request, client);
1337 client -> state = S_INIT;
1338 state_init (client);
1341 /* Send out a DHCPDISCOVER packet, and set a timeout to send out another
1342 one after the right interval has expired. If we don't get an offer by
1343 the time we reach the panic interval, call the panic function. */
1345 void send_discover (cpp)
1348 struct client_state *client = cpp;
1354 /* Figure out how long it's been since we started transmitting. */
1355 interval = cur_time - client -> first_sending;
1357 /* If we're past the panic timeout, call the script and tell it
1358 we haven't found anything for this interface yet. */
1359 if (interval > client -> config -> timeout) {
1360 state_panic (client);
1364 /* If we're selecting media, try the whole list before doing
1365 the exponential backoff, but if we've already received an
1366 offer, stop looping, because we obviously have it right. */
1367 if (!client -> offered_leases &&
1368 client -> config -> media) {
1371 if (client -> medium) {
1372 client -> medium = client -> medium -> next;
1375 if (!client -> medium) {
1377 log_fatal ("No valid media types for %s!",
1378 client -> interface -> name);
1380 client -> config -> media;
1384 log_info ("Trying medium \"%s\" %d",
1385 client -> medium -> string, increase);
1386 script_init (client, "MEDIUM", client -> medium);
1387 if (script_go (client)) {
1393 /* If we're supposed to increase the interval, do so. If it's
1394 currently zero (i.e., we haven't sent any packets yet), set
1395 it to one; otherwise, add to it a random number between
1396 zero and two times itself. On average, this means that it
1397 will double with every transmission. */
1399 if (!client -> interval)
1400 client -> interval =
1401 client -> config -> initial_interval;
1403 client -> interval += ((random () >> 2) %
1404 (2 * client -> interval));
1406 /* Don't backoff past cutoff. */
1407 if (client -> interval >
1408 client -> config -> backoff_cutoff)
1409 client -> interval =
1410 ((client -> config -> backoff_cutoff / 2)
1411 + ((random () >> 2) %
1412 client -> config -> backoff_cutoff));
1413 } else if (!client -> interval)
1414 client -> interval = client -> config -> initial_interval;
1416 /* If the backoff would take us to the panic timeout, just use that
1418 if (cur_time + client -> interval >
1419 client -> first_sending + client -> config -> timeout)
1420 client -> interval =
1421 (client -> first_sending +
1422 client -> config -> timeout) - cur_time + 1;
1424 /* Record the number of seconds since we started sending. */
1425 if (interval < 65536)
1426 client -> packet.secs = htons (interval);
1428 client -> packet.secs = htons (65535);
1429 client -> secs = client -> packet.secs;
1431 log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",
1432 client -> name ? client -> name : client -> interface -> name,
1433 inet_ntoa (sockaddr_broadcast.sin_addr),
1434 ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval));
1436 /* Send out a packet. */
1437 result = send_packet (client -> interface, (struct packet *)0,
1439 client -> packet_length,
1440 inaddr_any, &sockaddr_broadcast,
1441 (struct hardware *)0);
1443 add_timeout (cur_time + client -> interval,
1444 send_discover, client, 0, 0);
1447 /* state_panic gets called if we haven't received any offers in a preset
1448 amount of time. When this happens, we try to use existing leases that
1449 haven't yet expired, and failing that, we call the client script and
1450 hope it can do something. */
1452 void state_panic (cpp)
1455 struct client_state *client = cpp;
1456 struct client_lease *loop;
1457 struct client_lease *lp;
1459 loop = lp = client -> active;
1461 log_info ("No DHCPOFFERS received.");
1463 /* We may not have an active lease, but we may have some
1464 predefined leases that we can try. */
1465 if (!client -> active && client -> leases)
1468 /* Run through the list of leases and see if one can be used. */
1469 while (client -> active) {
1470 if (client -> active -> expiry > cur_time) {
1471 log_info ("Trying recorded lease %s",
1472 piaddr (client -> active -> address));
1473 /* Run the client script with the existing
1475 script_init (client, "TIMEOUT",
1476 client -> active -> medium);
1477 script_write_params (client, "new_", client -> active);
1478 if (client -> alias)
1479 script_write_params (client, "alias_",
1482 /* If the old lease is still good and doesn't
1483 yet need renewal, go into BOUND state and
1484 timeout at the renewal time. */
1485 if (!script_go (client)) {
1486 if (cur_time < client -> active -> renewal) {
1487 client -> state = S_BOUND;
1488 log_info ("bound: renewal in %ld %s.",
1489 (long)(client -> active -> renewal -
1490 cur_time), "seconds");
1491 add_timeout (client -> active -> renewal,
1492 state_bound, client, 0, 0);
1494 client -> state = S_BOUND;
1495 log_info ("bound: immediate renewal.");
1496 state_bound (client);
1498 reinitialize_interfaces ();
1504 /* If there are no other leases, give up. */
1505 if (!client -> leases) {
1506 client -> leases = client -> active;
1507 client -> active = (struct client_lease *)0;
1512 /* Otherwise, put the active lease at the end of the
1513 lease list, and try another lease.. */
1514 for (lp = client -> leases; lp -> next; lp = lp -> next)
1516 lp -> next = client -> active;
1518 lp -> next -> next = (struct client_lease *)0;
1520 client -> active = client -> leases;
1521 client -> leases = client -> leases -> next;
1523 /* If we already tried this lease, we've exhausted the
1524 set of leases, so we might as well give up for
1526 if (client -> active == loop)
1529 loop = client -> active;
1532 /* No leases were available, or what was available didn't work, so
1533 tell the shell script that we failed to allocate an address,
1534 and try again later. */
1537 log_info ("Unable to obtain a lease on first try.%s",
1542 log_info ("No working leases in persistent database - sleeping.");
1543 script_init (client, "FAIL", (struct string_list *)0);
1544 if (client -> alias)
1545 script_write_params (client, "alias_", client -> alias);
1547 client -> state = S_INIT;
1548 add_timeout (cur_time +
1549 ((client -> config -> retry_interval + 1) / 2 +
1550 (random () % client -> config -> retry_interval)),
1551 state_init, client, 0, 0);
1555 void send_request (cpp)
1558 struct client_state *client = cpp;
1562 struct sockaddr_in destination;
1563 struct in_addr from;
1565 /* Figure out how long it's been since we started transmitting. */
1566 interval = cur_time - client -> first_sending;
1568 /* If we're in the INIT-REBOOT or REQUESTING state and we're
1569 past the reboot timeout, go to INIT and see if we can
1570 DISCOVER an address... */
1571 /* XXX In the INIT-REBOOT state, if we don't get an ACK, it
1572 means either that we're on a network with no DHCP server,
1573 or that our server is down. In the latter case, assuming
1574 that there is a backup DHCP server, DHCPDISCOVER will get
1575 us a new address, but we could also have successfully
1576 reused our old address. In the former case, we're hosed
1577 anyway. This is not a win-prone situation. */
1578 if ((client -> state == S_REBOOTING ||
1579 client -> state == S_REQUESTING) &&
1580 interval > client -> config -> reboot_timeout) {
1582 client -> state = S_INIT;
1583 cancel_timeout (send_request, client);
1584 state_init (client);
1588 /* If we're in the reboot state, make sure the media is set up
1590 if (client -> state == S_REBOOTING &&
1591 !client -> medium &&
1592 client -> active -> medium ) {
1593 script_init (client, "MEDIUM", client -> active -> medium);
1595 /* If the medium we chose won't fly, go to INIT state. */
1596 if (script_go (client))
1599 /* Record the medium. */
1600 client -> medium = client -> active -> medium;
1603 /* If the lease has expired, relinquish the address and go back
1604 to the INIT state. */
1605 if (client -> state != S_REQUESTING &&
1606 cur_time > client -> active -> expiry) {
1607 /* Run the client script with the new parameters. */
1608 script_init (client, "EXPIRE", (struct string_list *)0);
1609 script_write_params (client, "old_", client -> active);
1610 if (client -> alias)
1611 script_write_params (client, "alias_",
1615 /* Now do a preinit on the interface so that we can
1616 discover a new address. */
1617 script_init (client, "PREINIT", (struct string_list *)0);
1618 if (client -> alias)
1619 script_write_params (client, "alias_",
1623 client -> state = S_INIT;
1624 state_init (client);
1628 /* Do the exponential backoff... */
1629 if (!client -> interval)
1630 client -> interval = client -> config -> initial_interval;
1632 client -> interval += ((random () >> 2) %
1633 (2 * client -> interval));
1636 /* Don't backoff past cutoff. */
1637 if (client -> interval >
1638 client -> config -> backoff_cutoff)
1639 client -> interval =
1640 ((client -> config -> backoff_cutoff / 2)
1641 + ((random () >> 2) % client -> interval));
1643 /* If the backoff would take us to the expiry time, just set the
1644 timeout to the expiry time. */
1645 if (client -> state != S_REQUESTING &&
1646 cur_time + client -> interval > client -> active -> expiry)
1647 client -> interval =
1648 client -> active -> expiry - cur_time + 1;
1650 /* If the lease T2 time has elapsed, or if we're not yet bound,
1651 broadcast the DHCPREQUEST rather than unicasting. */
1652 if (client -> state == S_REQUESTING ||
1653 client -> state == S_REBOOTING ||
1654 cur_time > client -> active -> rebind)
1655 destination.sin_addr = sockaddr_broadcast.sin_addr;
1657 memcpy (&destination.sin_addr.s_addr,
1658 client -> destination.iabuf,
1659 sizeof destination.sin_addr.s_addr);
1660 destination.sin_port = remote_port;
1661 destination.sin_family = AF_INET;
1663 destination.sin_len = sizeof destination;
1666 if (client -> state == S_RENEWING ||
1667 client -> state == S_REBINDING)
1668 memcpy (&from, client -> active -> address.iabuf,
1671 from.s_addr = INADDR_ANY;
1673 /* Record the number of seconds since we started sending. */
1674 if (client -> state == S_REQUESTING)
1675 client -> packet.secs = client -> secs;
1677 if (interval < 65536)
1678 client -> packet.secs = htons (interval);
1680 client -> packet.secs = htons (65535);
1683 log_info ("DHCPREQUEST on %s to %s port %d",
1684 client -> name ? client -> name : client -> interface -> name,
1685 inet_ntoa (destination.sin_addr),
1686 ntohs (destination.sin_port));
1688 if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
1690 result = send_packet (fallback_interface,
1693 client -> packet_length,
1695 (struct hardware *)0);
1697 /* Send out a packet. */
1698 result = send_packet (client -> interface, (struct packet *)0,
1700 client -> packet_length,
1702 (struct hardware *)0);
1704 add_timeout (cur_time + client -> interval,
1705 send_request, client, 0, 0);
1708 void send_decline (cpp)
1711 struct client_state *client = cpp;
1715 log_info ("DHCPDECLINE on %s to %s port %d",
1716 client -> name ? client -> name : client -> interface -> name,
1717 inet_ntoa (sockaddr_broadcast.sin_addr),
1718 ntohs (sockaddr_broadcast.sin_port));
1720 /* Send out a packet. */
1721 result = send_packet (client -> interface, (struct packet *)0,
1723 client -> packet_length,
1724 inaddr_any, &sockaddr_broadcast,
1725 (struct hardware *)0);
1728 void send_release (cpp)
1731 struct client_state *client = cpp;
1734 struct sockaddr_in destination;
1735 struct in_addr from;
1737 memcpy (&from, client -> active -> address.iabuf,
1739 memcpy (&destination.sin_addr.s_addr,
1740 client -> destination.iabuf,
1741 sizeof destination.sin_addr.s_addr);
1742 destination.sin_port = remote_port;
1743 destination.sin_family = AF_INET;
1745 destination.sin_len = sizeof destination;
1748 /* Set the lease to end now, so that we don't accidentally
1749 reuse it if we restart before the old expiry time. */
1750 client -> active -> expiry =
1751 client -> active -> renewal =
1752 client -> active -> rebind = cur_time;
1753 if (!write_client_lease (client, client -> active, 1, 1)) {
1754 log_error ("Can't release lease: lease write failed.");
1758 log_info ("DHCPRELEASE on %s to %s port %d",
1759 client -> name ? client -> name : client -> interface -> name,
1760 inet_ntoa (destination.sin_addr),
1761 ntohs (destination.sin_port));
1763 if (fallback_interface)
1764 result = send_packet (fallback_interface,
1767 client -> packet_length,
1769 (struct hardware *)0);
1771 /* Send out a packet. */
1772 result = send_packet (client -> interface, (struct packet *)0,
1774 client -> packet_length,
1776 (struct hardware *)0);
1779 void make_client_options (client, lease, type, sid, rip, prl, op)
1780 struct client_state *client;
1781 struct client_lease *lease;
1783 struct option_cache *sid;
1786 struct option_state **op;
1789 struct option_cache *oc;
1790 struct buffer *bp = (struct buffer *)0;
1792 /* If there are any leftover options, get rid of them. */
1794 option_state_dereference (op, MDL);
1796 /* Allocate space for options. */
1797 option_state_allocate (op, MDL);
1799 /* Send the server identifier if provided. */
1801 save_option (&dhcp_universe, *op, sid);
1803 oc = (struct option_cache *)0;
1805 /* Send the requested address if provided. */
1807 client -> requested_address = *rip;
1808 if (!(make_const_option_cache
1809 (&oc, (struct buffer **)0, rip -> iabuf, rip -> len,
1810 &dhcp_options [DHO_DHCP_REQUESTED_ADDRESS], MDL)))
1811 log_error ("can't make requested address cache.");
1813 save_option (&dhcp_universe, *op, oc);
1814 option_cache_dereference (&oc, MDL);
1817 client -> requested_address.len = 0;
1820 if (!(make_const_option_cache
1821 (&oc, (struct buffer **)0,
1822 type, 1, &dhcp_options [DHO_DHCP_MESSAGE_TYPE], MDL)))
1823 log_error ("can't make message type.");
1825 save_option (&dhcp_universe, *op, oc);
1826 option_cache_dereference (&oc, MDL);
1830 /* Figure out how many parameters were requested. */
1831 for (i = 0; prl [i]; i++)
1833 if (!buffer_allocate (&bp, i, MDL))
1834 log_error ("can't make parameter list buffer.");
1836 for (i = 0; prl [i]; i++)
1837 bp -> data [i] = prl [i];
1838 if (!(make_const_option_cache
1839 (&oc, &bp, (u_int8_t *)0, i,
1840 &dhcp_options [DHO_DHCP_PARAMETER_REQUEST_LIST],
1842 log_error ("can't make option cache");
1844 save_option (&dhcp_universe, *op, oc);
1845 option_cache_dereference (&oc, MDL);
1850 /* Run statements that need to be run on transmission. */
1851 if (client -> config -> on_transmission)
1852 execute_statements_in_scope
1853 ((struct binding_value **)0,
1854 (struct packet *)0, (struct lease *)0, client,
1855 (lease ? lease -> options : (struct option_state *)0),
1857 client -> config -> on_transmission,
1861 void make_discover (client, lease)
1862 struct client_state *client;
1863 struct client_lease *lease;
1865 unsigned char discover = DHCPDISCOVER;
1867 struct option_state *options = (struct option_state *)0;
1869 memset (&client -> packet, 0, sizeof (client -> packet));
1871 make_client_options (client,
1872 lease, &discover, (struct option_cache *)0,
1873 lease ? &lease -> address : (struct iaddr *)0,
1874 client -> config -> requested_options,
1877 /* Set up the option buffer... */
1878 client -> packet_length =
1879 cons_options ((struct packet *)0, &client -> packet,
1880 (struct lease *)0, client, 0,
1881 (struct option_state *)0, options,
1882 &global_scope, 0, 0, 0, (struct data_string *)0,
1883 client -> config -> vendor_space_name);
1884 option_state_dereference (&options, MDL);
1885 if (client -> packet_length < BOOTP_MIN_LEN)
1886 client -> packet_length = BOOTP_MIN_LEN;
1888 client -> packet.op = BOOTREQUEST;
1889 client -> packet.htype = client -> interface -> hw_address.hbuf [0];
1890 client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
1891 client -> packet.hops = 0;
1892 client -> packet.xid = random ();
1893 client -> packet.secs = 0; /* filled in by send_discover. */
1895 if (can_receive_unicast_unconfigured (client -> interface))
1896 client -> packet.flags = 0;
1898 client -> packet.flags = htons (BOOTP_BROADCAST);
1900 memset (&(client -> packet.ciaddr),
1901 0, sizeof client -> packet.ciaddr);
1902 memset (&(client -> packet.yiaddr),
1903 0, sizeof client -> packet.yiaddr);
1904 memset (&(client -> packet.siaddr),
1905 0, sizeof client -> packet.siaddr);
1906 client -> packet.giaddr = giaddr;
1907 if (client -> interface -> hw_address.hlen > 0)
1908 memcpy (client -> packet.chaddr,
1909 &client -> interface -> hw_address.hbuf [1],
1910 (unsigned)(client -> interface -> hw_address.hlen - 1));
1913 dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
1918 void make_request (client, lease)
1919 struct client_state *client;
1920 struct client_lease *lease;
1922 unsigned char request = DHCPREQUEST;
1924 unsigned char *tmp, *digest;
1925 unsigned char *old_digest_loc;
1926 struct option_cache *oc;
1928 memset (&client -> packet, 0, sizeof (client -> packet));
1930 if (client -> state == S_REQUESTING)
1931 oc = lookup_option (&dhcp_universe, lease -> options,
1932 DHO_DHCP_SERVER_IDENTIFIER);
1934 oc = (struct option_cache *)0;
1936 make_client_options (client, lease, &request, oc,
1937 ((client -> state == S_REQUESTING ||
1938 client -> state == S_REBOOTING)
1940 : (struct iaddr *)0),
1941 client -> config -> requested_options,
1942 &client -> sent_options);
1944 /* Set up the option buffer... */
1945 client -> packet_length =
1946 cons_options ((struct packet *)0, &client -> packet,
1947 (struct lease *)0, client, 0,
1948 (struct option_state *)0, client -> sent_options,
1949 &global_scope, 0, 0, 0, (struct data_string *)0,
1950 client -> config -> vendor_space_name);
1951 option_state_dereference (&client -> sent_options, MDL);
1952 if (client -> packet_length < BOOTP_MIN_LEN)
1953 client -> packet_length = BOOTP_MIN_LEN;
1955 client -> packet.op = BOOTREQUEST;
1956 client -> packet.htype = client -> interface -> hw_address.hbuf [0];
1957 client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
1958 client -> packet.hops = 0;
1959 client -> packet.xid = client -> xid;
1960 client -> packet.secs = 0; /* Filled in by send_request. */
1962 /* If we own the address we're requesting, put it in ciaddr;
1963 otherwise set ciaddr to zero. */
1964 if (client -> state == S_BOUND ||
1965 client -> state == S_RENEWING ||
1966 client -> state == S_REBINDING) {
1967 memcpy (&client -> packet.ciaddr,
1968 lease -> address.iabuf, lease -> address.len);
1969 client -> packet.flags = 0;
1971 memset (&client -> packet.ciaddr, 0,
1972 sizeof client -> packet.ciaddr);
1973 if (can_receive_unicast_unconfigured (client -> interface))
1974 client -> packet.flags = 0;
1976 client -> packet.flags = htons (BOOTP_BROADCAST);
1979 memset (&client -> packet.yiaddr, 0,
1980 sizeof client -> packet.yiaddr);
1981 memset (&client -> packet.siaddr, 0,
1982 sizeof client -> packet.siaddr);
1983 if (client -> state != S_BOUND &&
1984 client -> state != S_RENEWING)
1985 client -> packet.giaddr = giaddr;
1987 memset (&client -> packet.giaddr, 0,
1988 sizeof client -> packet.giaddr);
1989 if (client -> interface -> hw_address.hlen > 0)
1990 memcpy (client -> packet.chaddr,
1991 &client -> interface -> hw_address.hbuf [1],
1992 (unsigned)(client -> interface -> hw_address.hlen - 1));
1995 dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
1999 void make_decline (client, lease)
2000 struct client_state *client;
2001 struct client_lease *lease;
2003 unsigned char decline = DHCPDECLINE;
2005 struct option_cache *oc;
2007 struct option_state *options = (struct option_state *)0;
2009 oc = lookup_option (&dhcp_universe, lease -> options,
2010 DHO_DHCP_SERVER_IDENTIFIER);
2011 make_client_options (client, lease, &decline, oc,
2012 &lease -> address, (u_int32_t *)0, &options);
2014 /* Set up the option buffer... */
2015 memset (&client -> packet, 0, sizeof (client -> packet));
2016 client -> packet_length =
2017 cons_options ((struct packet *)0, &client -> packet,
2018 (struct lease *)0, client, 0,
2019 (struct option_state *)0, options,
2020 &global_scope, 0, 0, 0, (struct data_string *)0,
2021 client -> config -> vendor_space_name);
2022 option_state_dereference (&options, MDL);
2023 if (client -> packet_length < BOOTP_MIN_LEN)
2024 client -> packet_length = BOOTP_MIN_LEN;
2025 option_state_dereference (&options, MDL);
2027 client -> packet.op = BOOTREQUEST;
2028 client -> packet.htype = client -> interface -> hw_address.hbuf [0];
2029 client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
2030 client -> packet.hops = 0;
2031 client -> packet.xid = client -> xid;
2032 client -> packet.secs = 0; /* Filled in by send_request. */
2033 if (can_receive_unicast_unconfigured (client -> interface))
2034 client -> packet.flags = 0;
2036 client -> packet.flags = htons (BOOTP_BROADCAST);
2038 /* ciaddr must always be zero. */
2039 memset (&client -> packet.ciaddr, 0,
2040 sizeof client -> packet.ciaddr);
2041 memset (&client -> packet.yiaddr, 0,
2042 sizeof client -> packet.yiaddr);
2043 memset (&client -> packet.siaddr, 0,
2044 sizeof client -> packet.siaddr);
2045 client -> packet.giaddr = giaddr;
2046 memcpy (client -> packet.chaddr,
2047 &client -> interface -> hw_address.hbuf [1],
2048 client -> interface -> hw_address.hlen);
2051 dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
2055 void make_release (client, lease)
2056 struct client_state *client;
2057 struct client_lease *lease;
2059 unsigned char request = DHCPRELEASE;
2061 struct option_cache *oc;
2063 struct option_state *options = (struct option_state *)0;
2065 memset (&client -> packet, 0, sizeof (client -> packet));
2067 oc = lookup_option (&dhcp_universe, lease -> options,
2068 DHO_DHCP_SERVER_IDENTIFIER);
2069 make_client_options (client, lease, &request, oc,
2070 (struct iaddr *)0, (u_int32_t *)0,
2073 /* Set up the option buffer... */
2074 client -> packet_length =
2075 cons_options ((struct packet *)0, &client -> packet,
2076 (struct lease *)0, client, 0,
2077 (struct option_state *)0, options,
2078 &global_scope, 0, 0, 0, (struct data_string *)0,
2079 client -> config -> vendor_space_name);
2080 if (client -> packet_length < BOOTP_MIN_LEN)
2081 client -> packet_length = BOOTP_MIN_LEN;
2082 option_state_dereference (&options, MDL);
2084 client -> packet.op = BOOTREQUEST;
2085 client -> packet.htype = client -> interface -> hw_address.hbuf [0];
2086 client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
2087 client -> packet.hops = 0;
2088 client -> packet.xid = random ();
2089 client -> packet.secs = 0;
2090 client -> packet.flags = 0;
2091 memcpy (&client -> packet.ciaddr,
2092 lease -> address.iabuf, lease -> address.len);
2093 memset (&client -> packet.yiaddr, 0,
2094 sizeof client -> packet.yiaddr);
2095 memset (&client -> packet.siaddr, 0,
2096 sizeof client -> packet.siaddr);
2097 client -> packet.giaddr = giaddr;
2098 memcpy (client -> packet.chaddr,
2099 &client -> interface -> hw_address.hbuf [1],
2100 client -> interface -> hw_address.hlen);
2103 dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
2107 void destroy_client_lease (lease)
2108 struct client_lease *lease;
2112 if (lease -> server_name)
2113 dfree (lease -> server_name, MDL);
2114 if (lease -> filename)
2115 dfree (lease -> filename, MDL);
2116 option_state_dereference (&lease -> options, MDL);
2117 free_client_lease (lease, MDL);
2122 void rewrite_client_leases ()
2124 struct interface_info *ip;
2125 struct client_state *client;
2126 struct client_lease *lp;
2130 leaseFile = fopen (path_dhclient_db, "w");
2132 log_error ("can't create %s: %m", path_dhclient_db);
2136 /* Write out all the leases attached to configured interfaces that
2138 for (ip = interfaces; ip; ip = ip -> next) {
2139 for (client = ip -> client; client; client = client -> next) {
2140 for (lp = client -> leases; lp; lp = lp -> next) {
2141 write_client_lease (client, lp, 1, 0);
2143 if (client -> active)
2144 write_client_lease (client,
2145 client -> active, 1, 0);
2149 /* Write out any leases that are attached to interfaces that aren't
2150 currently configured. */
2151 for (ip = dummy_interfaces; ip; ip = ip -> next) {
2152 for (client = ip -> client; client; client = client -> next) {
2153 for (lp = client -> leases; lp; lp = lp -> next) {
2154 write_client_lease (client, lp, 1, 0);
2156 if (client -> active)
2157 write_client_lease (client,
2158 client -> active, 1, 0);
2164 void write_lease_option (struct option_cache *oc,
2165 struct packet *packet, struct lease *lease,
2166 struct client_state *client_state,
2167 struct option_state *in_options,
2168 struct option_state *cfg_options,
2169 struct binding_scope **scope,
2170 struct universe *u, void *stuff)
2172 const char *name, *dot;
2173 struct data_string ds;
2175 struct client_state *client;
2177 memset (&ds, 0, sizeof ds);
2179 if (u != &dhcp_universe) {
2186 if (evaluate_option_cache (&ds, packet, lease, client_state,
2187 in_options, cfg_options, scope, oc, MDL)) {
2189 " option %s%s%s %s;\n",
2190 name, dot, oc -> option -> name,
2191 pretty_print_option (oc -> option,
2192 ds.data, ds.len, 1, 1));
2193 data_string_forget (&ds, MDL);
2197 int write_client_lease (client, lease, rewrite, makesure)
2198 struct client_state *client;
2199 struct client_lease *lease;
2205 static int leases_written;
2206 struct option_cache *oc;
2207 struct data_string ds;
2213 if (leases_written++ > 20) {
2214 rewrite_client_leases ();
2219 /* If the lease came from the config file, we don't need to stash
2220 a copy in the lease database. */
2221 if (lease -> is_static)
2224 if (!leaseFile) { /* XXX */
2225 leaseFile = fopen (path_dhclient_db, "w");
2227 log_error ("can't create %s: %m", path_dhclient_db);
2233 fprintf (leaseFile, "lease {\n");
2234 if (lease -> is_bootp) {
2235 fprintf (leaseFile, " bootp;\n");
2241 fprintf (leaseFile, " interface \"%s\";\n",
2242 client -> interface -> name);
2247 if (client -> name) {
2248 fprintf (leaseFile, " name \"%s\";\n", client -> name);
2254 fprintf (leaseFile, " fixed-address %s;\n",
2255 piaddr (lease -> address));
2260 if (lease -> filename) {
2261 s = quotify_string (lease -> filename, MDL);
2263 fprintf (leaseFile, " filename \"%s\";\n", s);
2273 if (lease -> server_name) {
2274 s = quotify_string (lease -> filename, MDL);
2276 fprintf (leaseFile, " server-name \"%s\";\n", s);
2285 if (lease -> medium) {
2286 s = quotify_string (lease -> medium -> string, MDL);
2288 fprintf (leaseFile, " medium \"%s\";\n", s);
2302 memset (&ds, 0, sizeof ds);
2304 for (i = 0; i < lease -> options -> universe_count; i++) {
2305 option_space_foreach ((struct packet *)0, (struct lease *)0,
2306 client, (struct option_state *)0,
2307 lease -> options, &global_scope,
2309 client, write_lease_option);
2312 /* Note: the following is not a Y2K bug - it's a Y1.9K bug. Until
2313 somebody invents a time machine, I think we can safely disregard
2315 t = gmtime (&lease -> renewal);
2317 " renew %d %d/%d/%d %02d:%02d:%02d;\n",
2318 t -> tm_wday, t -> tm_year + 1900,
2319 t -> tm_mon + 1, t -> tm_mday,
2320 t -> tm_hour, t -> tm_min, t -> tm_sec);
2325 t = gmtime (&lease -> rebind);
2327 " rebind %d %d/%d/%d %02d:%02d:%02d;\n",
2328 t -> tm_wday, t -> tm_year + 1900,
2329 t -> tm_mon + 1, t -> tm_mday,
2330 t -> tm_hour, t -> tm_min, t -> tm_sec);
2335 t = gmtime (&lease -> expiry);
2337 " expire %d %d/%d/%d %02d:%02d:%02d;\n",
2338 t -> tm_wday, t -> tm_year + 1900,
2339 t -> tm_mon + 1, t -> tm_mday,
2340 t -> tm_hour, t -> tm_min, t -> tm_sec);
2345 fprintf (leaseFile, "}\n");
2355 if (!errors && makesure) {
2356 if (fsync (fileno (leaseFile)) < 0) {
2357 log_info ("write_client_lease: %m");
2361 return errors ? 0 : 1;
2364 /* Variables holding name of script and file pointer for writing to
2365 script. Needless to say, this is not reentrant - only one script
2366 can be invoked at a time. */
2367 char scriptName [256];
2370 void script_init (client, reason, medium)
2371 struct client_state *client;
2373 struct string_list *medium;
2375 struct string_list *sl, *next;
2378 for (sl = client -> env; sl; sl = next) {
2382 client -> env = (struct string_list *)0;
2385 if (client -> interface) {
2386 client_envadd (client, "", "interface", "%s",
2387 client -> interface -> name);
2390 client_envadd (client,
2391 "", "client", "%s", client -> name);
2393 client_envadd (client,
2394 "", "medium", "%s", medium -> string);
2396 client_envadd (client, "", "reason", "%s", reason);
2397 client_envadd (client, "", "pid", "%ld", (long int)getpid ());
2401 struct envadd_state {
2402 struct client_state *client;
2406 void client_option_envadd (struct option_cache *oc,
2407 struct packet *packet, struct lease *lease,
2408 struct client_state *client_state,
2409 struct option_state *in_options,
2410 struct option_state *cfg_options,
2411 struct binding_scope **scope,
2412 struct universe *u, void *stuff)
2414 struct envadd_state *es = stuff;
2415 struct data_string data;
2416 memset (&data, 0, sizeof data);
2418 if (evaluate_option_cache (&data, packet, lease, client_state,
2419 in_options, cfg_options, scope, oc, MDL)) {
2422 if (dhcp_option_ev_name (name, sizeof name,
2424 client_envadd (es -> client, es -> prefix,
2426 (pretty_print_option
2428 data.data, data.len,
2430 data_string_forget (&data, MDL);
2436 void script_write_params (client, prefix, lease)
2437 struct client_state *client;
2439 struct client_lease *lease;
2442 struct data_string data;
2443 struct option_cache *oc;
2446 struct envadd_state es;
2451 client_envadd (client,
2452 prefix, "ip_address", "%s", piaddr (lease -> address));
2454 /* For the benefit of Linux (and operating systems which may
2455 have similar needs), compute the network address based on
2456 the supplied ip address and netmask, if provided. Also
2457 compute the broadcast address (the host address all ones
2458 broadcast address, not the host address all zeroes
2459 broadcast address). */
2461 memset (&data, 0, sizeof data);
2462 oc = lookup_option (&dhcp_universe, lease -> options, DHO_SUBNET_MASK);
2463 if (oc && evaluate_option_cache (&data, (struct packet *)0,
2464 (struct lease *)0, client,
2465 (struct option_state *)0,
2467 &global_scope, oc, MDL)) {
2469 struct iaddr netmask, subnet, broadcast;
2471 memcpy (netmask.iabuf, data.data, data.len);
2472 netmask.len = data.len;
2473 data_string_forget (&data, MDL);
2475 subnet = subnet_number (lease -> address, netmask);
2477 client_envadd (client, prefix, "network_number",
2478 "%s", piaddr (subnet));
2480 oc = lookup_option (&dhcp_universe,
2482 DHO_BROADCAST_ADDRESS);
2484 !(evaluate_option_cache
2485 (&data, (struct packet *)0,
2486 (struct lease *)0, client,
2487 (struct option_state *)0,
2489 &global_scope, oc, MDL))) {
2490 broadcast = broadcast_addr (subnet, netmask);
2491 if (broadcast.len) {
2492 client_envadd (client,
2493 prefix, "broadcast_address",
2494 "%s", piaddr (broadcast));
2499 data_string_forget (&data, MDL);
2502 if (lease -> filename)
2503 client_envadd (client,
2504 prefix, "filename", "%s", lease -> filename);
2505 if (lease -> server_name)
2506 client_envadd (client, prefix, "server_name",
2507 "%s", lease -> server_name);
2509 for (i = 0; i < lease -> options -> universe_count; i++) {
2510 option_space_foreach ((struct packet *)0, (struct lease *)0,
2511 client, (struct option_state *)0,
2512 lease -> options, &global_scope,
2514 &es, client_option_envadd);
2516 client_envadd (client, prefix, "expiry", "%d", (int)(lease -> expiry));
2519 int script_go (client)
2520 struct client_state *client;
2527 char reason [] = "REASON=NBI";
2528 static char client_path [] = CLIENT_PATH;
2530 struct string_list *sp, *next;
2531 int pid, wpid, wstatus;
2534 scriptName = client -> config -> script_name;
2536 scriptName = top_level_config.script_name;
2538 envp = dmalloc (((client ? client -> envc : 2) +
2539 client_env_count + 2) * sizeof (char *), MDL);
2541 log_error ("No memory for client script environment.");
2545 /* Copy out the environment specified on the command line,
2547 for (sp = client_env; sp; sp = sp -> next) {
2548 envp [i++] = sp -> string;
2550 /* Copy out the environment specified by dhclient. */
2552 for (sp = client -> env; sp; sp = sp -> next) {
2553 envp [i++] = sp -> string;
2556 envp [i++] = reason;
2559 envp [i++] = client_path;
2560 envp [i] = (char *)0;
2562 argv [0] = scriptName;
2563 argv [1] = (char *)0;
2567 log_error ("fork: %m");
2571 wpid = wait (&wstatus);
2572 } while (wpid != pid && wpid > 0);
2574 log_error ("wait: %m");
2578 if ((i = open(_PATH_DEVNULL, O_RDWR)) != -1) {
2579 dup2(i, STDIN_FILENO);
2580 dup2(i, STDOUT_FILENO);
2581 dup2(i, STDERR_FILENO);
2582 if (i > STDERR_FILENO)
2585 execve (scriptName, argv, envp);
2586 log_error ("execve (%s, ...): %m", scriptName);
2591 for (sp = client -> env; sp; sp = next) {
2595 client -> env = (struct string_list *)0;
2599 GET_TIME (&cur_time);
2600 return (WIFEXITED (wstatus) ?
2601 WEXITSTATUS (wstatus) : -WTERMSIG (wstatus));
2604 void client_envadd (struct client_state *client,
2605 const char *prefix, const char *name, const char *fmt, ...)
2610 struct string_list *val;
2613 va_start (list, fmt);
2614 len = vsnprintf (spbuf, sizeof spbuf, fmt, list);
2617 val = dmalloc (strlen (prefix) + strlen (name) + 1 /* = */ +
2618 len + sizeof *val, MDL);
2626 if (len >= sizeof spbuf) {
2627 va_start (list, fmt);
2628 vsnprintf (s, len + 1, fmt, list);
2632 val -> next = client -> env;
2633 client -> env = val;
2637 int dhcp_option_ev_name (buf, buflen, option)
2640 struct option *option;
2646 if (option -> universe != &dhcp_universe) {
2647 s = option -> universe -> name;
2656 if (j + 1 == buflen)
2666 if (j + 1 == buflen)
2679 static int state = 0;
2683 /* Don't become a daemon if the user requested otherwise. */
2685 write_client_pid_file ();
2689 /* Only do it once. */
2694 /* Stop logging to stderr... */
2697 /* Become a daemon... */
2698 if ((pid = fork ()) < 0)
2699 log_fatal ("Can't fork daemon: %m");
2702 /* Become session leader and get pid... */
2705 /* Close standard I/O descriptors. */
2710 /* Reopen them on /dev/null. */
2711 i = open ("/dev/null", O_RDWR);
2713 i = open ("/dev/null", O_RDWR);
2715 i = open ("/dev/null", O_RDWR);
2716 log_perror = 0; /* No sense logging to /dev/null. */
2720 write_client_pid_file ();
2723 void write_client_pid_file ()
2728 pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY, 0644);
2731 log_error ("Can't create %s: %m", path_dhclient_pid);
2735 pf = fdopen (pfdesc, "w");
2737 log_error ("Can't fdopen %s: %m", path_dhclient_pid);
2739 fprintf (pf, "%ld\n", (long)getpid ());
2744 void client_location_changed ()
2746 struct interface_info *ip;
2747 struct client_state *client;
2749 for (ip = interfaces; ip; ip = ip -> next) {
2750 for (client = ip -> client; client; client = client -> next) {
2751 switch (client -> state) {
2753 cancel_timeout (send_discover, client);
2757 cancel_timeout (state_bound, client);
2763 cancel_timeout (send_request, client);
2771 client -> state = S_INIT;
2772 state_reboot (client);
2777 void do_release(client)
2778 struct client_state *client;
2780 struct data_string ds;
2781 struct option_cache *oc;
2783 /* Pick a random xid. */
2784 client -> xid = random ();
2786 /* is there even a lease to release? */
2787 if (client -> active) {
2788 /* Make a DHCPRELEASE packet, and set appropriate per-interface
2790 make_release (client, client -> active);
2792 memset (&ds, 0, sizeof ds);
2793 oc = lookup_option (&dhcp_universe,
2794 client -> active -> options,
2795 DHO_DHCP_SERVER_IDENTIFIER);
2797 evaluate_option_cache (&ds, (struct packet *)0,
2798 (struct lease *)0, client,
2799 (struct option_state *)0,
2800 client -> active -> options,
2801 &global_scope, oc, MDL)) {
2803 memcpy (client -> destination.iabuf,
2805 client -> destination.len = 4;
2807 client -> destination = iaddr_broadcast;
2809 client -> destination = iaddr_broadcast;
2810 client -> first_sending = cur_time;
2811 client -> interval = client -> config -> initial_interval;
2813 /* Zap the medium list... */
2814 client -> medium = (struct string_list *)0;
2816 /* Send out the first and only DHCPRELEASE packet. */
2817 send_release (client);
2819 /* Do the client script RELEASE operation. */
2820 script_init (client,
2821 "RELEASE", (struct string_list *)0);
2822 if (client -> alias)
2823 script_write_params (client, "alias_",
2825 script_write_params (client, "old_", client -> active);
2829 /* Cancel any timeouts. */
2830 cancel_timeout (state_bound, client);
2831 cancel_timeout (send_discover, client);
2832 cancel_timeout (state_init, client);
2833 cancel_timeout (send_request, client);
2834 cancel_timeout (state_reboot, client);
2835 client -> state = S_STOPPED;
2838 int dhclient_interface_shutdown_hook (struct interface_info *interface)
2840 do_release (interface -> client);
2845 int dhclient_interface_discovery_hook (struct interface_info *tmp)
2847 struct interface_info *last, *ip;
2848 /* See if we can find the client from dummy_interfaces */
2850 for (ip = dummy_interfaces; ip; ip = ip -> next) {
2851 if (!strcmp (ip -> name, tmp -> name)) {
2852 /* Remove from dummy_interfaces */
2854 ip = (struct interface_info *)0;
2855 interface_reference (&ip, last -> next, MDL);
2856 interface_dereference (&last -> next, MDL);
2858 interface_reference (&last -> next,
2860 interface_dereference (&ip -> next,
2864 ip = (struct interface_info *)0;
2865 interface_reference (&ip,
2866 dummy_interfaces, MDL);
2867 interface_dereference (&dummy_interfaces, MDL);
2869 interface_reference (&dummy_interfaces,
2871 interface_dereference (&ip -> next,
2875 /* Copy "client" to tmp */
2877 tmp -> client = ip -> client;
2878 tmp -> client -> interface = tmp;
2880 interface_dereference (&ip, MDL);
2888 isc_result_t dhclient_interface_startup_hook (struct interface_info *interface)
2890 struct interface_info *ip;
2891 struct client_state *client;
2893 /* This code needs some rethinking. It doesn't test against
2894 a signal name, and it just kind of bulls into doing something
2895 that may or may not be appropriate. */
2898 interface_reference (&interface -> next, interfaces, MDL);
2899 interface_dereference (&interfaces, MDL);
2901 interface_reference (&interfaces, interface, MDL);
2903 discover_interfaces (DISCOVER_UNCONFIGURED);
2905 for (ip = interfaces; ip; ip = ip -> next) {
2906 /* If interfaces were specified, don't configure
2907 interfaces that weren't specified! */
2908 if (ip -> flags & INTERFACE_RUNNING ||
2909 (ip -> flags & (INTERFACE_REQUESTED |
2910 INTERFACE_AUTOMATIC)) !=
2911 INTERFACE_REQUESTED)
2913 script_init (ip -> client,
2914 "PREINIT", (struct string_list *)0);
2915 if (ip -> client -> alias)
2916 script_write_params (ip -> client, "alias_",
2917 ip -> client -> alias);
2918 script_go (ip -> client);
2921 discover_interfaces (interfaces_requested
2922 ? DISCOVER_REQUESTED
2923 : DISCOVER_RUNNING);
2925 for (ip = interfaces; ip; ip = ip -> next) {
2926 if (ip -> flags & INTERFACE_RUNNING)
2928 ip -> flags |= INTERFACE_RUNNING;
2929 for (client = ip -> client; client; client = client -> next) {
2930 client -> state = S_INIT;
2931 /* Set up a timeout to start the initialization
2933 add_timeout (cur_time + random () % 5,
2934 state_reboot, client, 0, 0);
2937 return ISC_R_SUCCESS;
2940 /* The client should never receive a relay agent information option,
2941 so if it does, log it and discard it. */
2943 int parse_agent_information_option (packet, len, data)
2944 struct packet *packet;
2951 /* The client never sends relay agent information options. */
2953 unsigned cons_agent_information_options (cfg_options, outpacket,
2955 struct option_state *cfg_options;
2956 struct dhcp_packet *outpacket;
2963 static void shutdown_exit (void *foo)
2968 isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
2969 control_object_state_t newstate)
2971 struct interface_info *ip;
2972 struct client_state *client;
2974 /* Do the right thing for each interface. */
2975 for (ip = interfaces; ip; ip = ip -> next) {
2976 for (client = ip -> client; client; client = client -> next) {
2978 case server_startup:
2979 return ISC_R_SUCCESS;
2981 case server_running:
2982 return ISC_R_SUCCESS;
2984 case server_shutdown:
2985 if (client -> active &&
2986 client -> active -> expiry > cur_time) {
2987 if (client -> config -> do_forward_update)
2988 client_dns_update (client, 0, 0);
2989 do_release (client);
2993 case server_hibernate:
2994 state_stop (client);
2998 state_reboot (client);
3003 if (newstate == server_shutdown)
3004 add_timeout (cur_time + 1, shutdown_exit, 0, 0, 0);
3005 return ISC_R_SUCCESS;
3008 /* Called after a timeout if the DNS update failed on the previous try.
3009 Retries the update, and if it times out, schedules a retry after
3010 ten times as long of a wait. */
3012 void client_dns_update_timeout (void *cp)
3014 struct client_state *client = cp;
3015 isc_result_t status;
3017 if (client -> active) {
3018 status = client_dns_update (client, 1,
3019 (client -> active -> renewal -
3021 if (status == ISC_R_TIMEDOUT) {
3022 client -> dns_update_timeout *= 10;
3023 add_timeout (cur_time + client -> dns_update_timeout,
3024 client_dns_update_timeout, client, 0, 0);
3029 /* See if we should do a DNS update, and if so, do it. */
3031 isc_result_t client_dns_update (struct client_state *client, int addp, int ttl)
3033 struct data_string ddns_fqdn, ddns_fwd_name,
3034 ddns_dhcid, client_identifier;
3035 struct option_cache *oc;
3040 /* If we didn't send an FQDN option, we certainly aren't going to
3041 be doing an update. */
3042 if (!client -> sent_options)
3043 return ISC_R_SUCCESS;
3045 /* If we don't have a lease, we can't do an update. */
3046 if (!client -> active)
3047 return ISC_R_SUCCESS;
3049 /* If we set the no client update flag, don't do the update. */
3050 if ((oc = lookup_option (&fqdn_universe, client -> sent_options,
3051 FQDN_NO_CLIENT_UPDATE)) &&
3052 evaluate_boolean_option_cache (&ignorep, (struct packet *)0,
3053 (struct lease *)0, client,
3054 client -> sent_options,
3055 (struct option_state *)0,
3056 &global_scope, oc, MDL))
3057 return ISC_R_SUCCESS;
3059 /* If we set the "server, please update" flag, or didn't set it
3060 to false, don't do the update. */
3061 if (!(oc = lookup_option (&fqdn_universe, client -> sent_options,
3062 FQDN_SERVER_UPDATE)) ||
3063 evaluate_boolean_option_cache (&ignorep, (struct packet *)0,
3064 (struct lease *)0, client,
3065 client -> sent_options,
3066 (struct option_state *)0,
3067 &global_scope, oc, MDL))
3068 return ISC_R_SUCCESS;
3070 /* If no FQDN option was supplied, don't do the update. */
3071 memset (&ddns_fwd_name, 0, sizeof ddns_fwd_name);
3072 if (!(oc = lookup_option (&fqdn_universe, client -> sent_options,
3074 !evaluate_option_cache (&ddns_fwd_name, (struct packet *)0,
3075 (struct lease *)0, client,
3076 client -> sent_options,
3077 (struct option_state *)0,
3078 &global_scope, oc, MDL))
3079 return ISC_R_SUCCESS;
3081 /* Make a dhcid string out of either the client identifier,
3082 if we are sending one, or the interface's MAC address,
3084 memset (&ddns_dhcid, 0, sizeof ddns_dhcid);
3086 memset (&client_identifier, 0, sizeof client_identifier);
3087 if ((oc = lookup_option (&dhcp_universe, client -> sent_options,
3088 DHO_DHCP_CLIENT_IDENTIFIER)) &&
3089 evaluate_option_cache (&client_identifier, (struct packet *)0,
3090 (struct lease *)0, client,
3091 client -> sent_options,
3092 (struct option_state *)0,
3093 &global_scope, oc, MDL)) {
3094 result = get_dhcid (&ddns_dhcid,
3095 DHO_DHCP_CLIENT_IDENTIFIER,
3096 client_identifier.data,
3097 client_identifier.len);
3098 data_string_forget (&client_identifier, MDL);
3100 result = get_dhcid (&ddns_dhcid, 0,
3101 client -> interface -> hw_address.hbuf,
3102 client -> interface -> hw_address.hlen);
3104 data_string_forget (&ddns_fwd_name, MDL);
3105 return ISC_R_SUCCESS;
3108 /* Start the resolver, if necessary. */
3109 if (!resolver_inited) {
3110 minires_ninit (&resolver_state);
3111 resolver_inited = 1;
3112 resolver_state.retrans = 1;
3113 resolver_state.retry = 1;
3119 if (ddns_fwd_name.len && ddns_dhcid.len) {
3121 rcode = ddns_update_a (&ddns_fwd_name,
3122 client -> active -> address,
3126 rcode = ddns_remove_a (&ddns_fwd_name,
3127 client -> active -> address,
3131 data_string_forget (&ddns_fwd_name, MDL);
3132 data_string_forget (&ddns_dhcid, MDL);