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 * $Id: dhclient.c,v 1.129.2.16 2003/04/26 21:51:39 dhankins Exp $ Copyright (c) 1995-2002 Internet Software Consortium. All rights reserved.
42 * $FreeBSD: src/contrib/isc-dhcp/client/dhclient.c,v 1.34 2003/09/02 11:09:45 mbr Exp $
43 * $DragonFly: src/contrib/isc-dhcp/client/Attic/dhclient.c,v 1.4 2003/12/31 03:22:57 drhodus Exp $
50 #include <sys/ioctl.h>
51 #include <net/if_media.h>
52 #if defined(DRAGONFLY_FUTURE)
53 #include <net80211/ieee80211_ioctl.h>
54 #include <net80211/ieee80211.h>
59 TIME default_lease_time = 43200; /* 12 hours... */
60 TIME max_lease_time = 86400; /* 24 hours... */
62 const char *path_dhclient_conf = _PATH_DHCLIENT_CONF;
63 const char *path_dhclient_db = _PATH_DHCLIENT_DB;
64 const char *path_dhclient_pid = _PATH_DHCLIENT_PID;
65 static char path_dhclient_script_array [] = _PATH_DHCLIENT_SCRIPT;
66 char *path_dhclient_script = path_dhclient_script_array;
68 int dhcp_max_agent_option_packet_length = 0;
70 int interfaces_requested = 0;
72 struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } };
73 struct iaddr iaddr_any = { 4, { 0, 0, 0, 0 } };
74 struct in_addr inaddr_any;
75 struct sockaddr_in sockaddr_broadcast;
76 struct in_addr giaddr;
78 /* ASSERT_STATE() does nothing now; it used to be
79 assert (state_is == state_shouldbe). */
80 #define ASSERT_STATE(state_is, state_shouldbe) {}
82 static char copyright[] = "Copyright 1995-2002 Internet Software Consortium.";
83 static char arr [] = "All rights reserved.";
84 static char message [] = "Internet Software Consortium DHCP Client";
85 static char url [] = "For info, please visit http://www.isc.org/products/DHCP";
87 u_int16_t local_port=0;
88 u_int16_t remote_port=0;
90 struct string_list *client_env=NULL;
91 int client_env_count=0;
96 #ifdef ENABLE_POLLING_MODE
97 int polling_interval = 5;
100 static void usage PROTO ((void));
102 void do_release(struct client_state *);
104 int main (argc, argv, envp)
110 struct interface_info *ip;
111 struct client_state *client;
113 char *server = (char *)0;
114 char *relay = (char *)0;
116 int release_mode = 0;
117 omapi_object_t *listener;
121 int no_dhclient_conf = 0;
122 int no_dhclient_db = 0;
123 int no_dhclient_pid = 0;
124 int no_dhclient_script = 0;
127 /* Make sure we have stdin, stdout and stderr. */
128 i = open ("/dev/null", O_RDWR);
130 i = open ("/dev/null", O_RDWR);
132 i = open ("/dev/null", O_RDWR);
133 log_perror = 0; /* No sense logging to /dev/null. */
138 openlog ("dhclient", LOG_NDELAY);
139 log_priority = LOG_DAEMON;
141 openlog ("dhclient", LOG_NDELAY, LOG_DAEMON);
144 #if !(defined (DEBUG) || defined (SYSLOG_4_2) || defined (__CYGWIN32__))
145 setlogmask (LOG_UPTO (LOG_INFO));
148 /* Set up the OMAPI. */
149 status = omapi_init ();
150 if (status != ISC_R_SUCCESS)
151 log_fatal ("Can't initialize OMAPI: %s",
152 isc_result_totext (status));
154 /* Set up the OMAPI wrappers for various server database internal
156 dhcp_common_objects_setup ();
158 dhcp_interface_discovery_hook = dhclient_interface_discovery_hook;
159 dhcp_interface_shutdown_hook = dhclient_interface_shutdown_hook;
160 dhcp_interface_startup_hook = dhclient_interface_startup_hook;
162 for (i = 1; i < argc; i++) {
163 if (!strcmp (argv [i], "-r")) {
166 } else if (!strcmp (argv [i], "-p")) {
169 local_port = htons (atoi (argv [i]));
170 log_debug ("binding to user-specified port %d",
172 } else if (!strcmp (argv [i], "-d")) {
174 } else if (!strcmp (argv [i], "-pf")) {
177 path_dhclient_pid = argv [i];
179 } else if (!strcmp (argv [i], "-cf")) {
182 path_dhclient_conf = argv [i];
183 no_dhclient_conf = 1;
184 } else if (!strcmp (argv [i], "-lf")) {
187 path_dhclient_db = argv [i];
189 } else if (!strcmp (argv [i], "-sf")) {
192 path_dhclient_script = argv [i];
193 no_dhclient_script = 1;
194 } else if (!strcmp (argv [i], "-1")) {
196 } else if (!strcmp (argv [i], "-q")) {
198 quiet_interface_discovery = 1;
199 } else if (!strcmp (argv [i], "-v")) {
201 quiet_interface_discovery = 0;
202 } else if (!strcmp (argv [i], "-s")) {
206 } else if (!strcmp (argv [i], "-g")) {
210 } else if (!strcmp (argv [i], "-nw")) {
212 } else if (!strcmp (argv [i], "-n")) {
213 /* do not start up any interfaces */
214 interfaces_requested = 1;
215 #ifdef ENABLE_POLLING_MODE
216 } else if (!strcmp (argv [i], "-i")) {
219 polling_interval = (int)strtol (argv [i],
221 if (polling_interval <= 0) {
222 log_info ("Incorrect polling interval %d",
224 log_info ("Using a default of 5 seconds");
225 polling_interval = 5;
228 } else if (!strcmp (argv [i], "-w")) {
229 /* do not exit if there are no broadcast interfaces. */
231 } else if (!strcmp (argv [i], "-e")) {
232 struct string_list *tmp;
235 tmp = dmalloc (strlen (argv [i]) + sizeof *tmp, MDL);
237 log_fatal ("No memory for %s", argv [i]);
238 strcpy (tmp -> string, argv [i]);
239 tmp -> next = client_env;
242 } else if (!strcmp (argv [i], "--version")) {
243 log_info ("isc-dhclient-%s", DHCP_VERSION);
245 } else if (argv [i][0] == '-') {
248 struct interface_info *tmp = (struct interface_info *)0;
249 status = interface_allocate (&tmp, MDL);
250 if (status != ISC_R_SUCCESS)
251 log_fatal ("Can't record interface %s:%s",
252 argv [i], isc_result_totext (status));
253 if (strlen (argv [i]) > sizeof tmp -> name)
254 log_fatal ("%s: interface name too long (max %ld)",
255 argv [i], (long)strlen (argv [i]));
256 strlcpy (tmp -> name, argv [i], IFNAMSIZ);
258 #if defined(DRAGONFLY_FUTURE)
262 /* Init some interface vars, enable polling */
263 #ifdef ENABLE_POLLING_MODE
264 tmp -> forcediscover = 0;
265 tmp -> linkstate = HAVELINK;
267 #endif /* ifdef ENABLE_POLLING_MODE */
270 interface_reference (&tmp -> next,
272 interface_dereference (&interfaces, MDL);
274 interface_reference (&interfaces, tmp, MDL);
275 tmp -> flags = INTERFACE_REQUESTED;
276 interfaces_requested = 1;
280 if (!no_dhclient_conf && (s = getenv ("PATH_DHCLIENT_CONF"))) {
281 path_dhclient_conf = s;
283 if (!no_dhclient_db && (s = getenv ("PATH_DHCLIENT_DB"))) {
284 path_dhclient_db = s;
286 if (!no_dhclient_pid && (s = getenv ("PATH_DHCLIENT_PID"))) {
287 path_dhclient_pid = s;
289 if (!no_dhclient_script && (s = getenv ("PATH_DHCLIENT_SCRIPT"))) {
290 path_dhclient_script = s;
293 /* first kill of any currently running client */
302 if ((pidfd = fopen(path_dhclient_pid, "r")) != NULL) {
303 e = fscanf(pidfd, "%ld\n", &temp);
304 oldpid = (pid_t)temp;
306 if (e != 0 && e != EOF) {
308 if (kill(oldpid, SIGTERM) == 0)
309 unlink(path_dhclient_pid);
317 log_info ("%s %s", message, DHCP_VERSION);
318 log_info (copyright);
325 /* If we're given a relay agent address to insert, for testing
326 purposes, figure out what it is. */
328 if (!inet_aton (relay, &giaddr)) {
330 he = gethostbyname (relay);
332 memcpy (&giaddr, he -> h_addr_list [0],
335 log_fatal ("%s: no such host", relay);
340 /* Default to the DHCP/BOOTP port. */
342 /* If we're faking a relay agent, and we're not using loopback,
343 use the server port, not the client port. */
344 if (relay && giaddr.s_addr != htonl (INADDR_LOOPBACK)) {
345 local_port = htons(67);
347 ent = getservbyname ("dhcpc", "udp");
349 local_port = htons (68);
351 local_port = ent -> s_port;
358 /* If we're faking a relay agent, and we're not using loopback,
359 we're using the server port, not the client port. */
360 if (relay && giaddr.s_addr != htonl (INADDR_LOOPBACK)) {
361 remote_port = local_port;
363 remote_port = htons (ntohs (local_port) - 1); /* XXX */
365 /* Get the current time... */
366 GET_TIME (&cur_time);
368 sockaddr_broadcast.sin_family = AF_INET;
369 sockaddr_broadcast.sin_port = remote_port;
371 if (!inet_aton (server, &sockaddr_broadcast.sin_addr)) {
373 he = gethostbyname (server);
375 memcpy (&sockaddr_broadcast.sin_addr,
376 he -> h_addr_list [0],
377 sizeof sockaddr_broadcast.sin_addr);
379 sockaddr_broadcast.sin_addr.s_addr =
383 sockaddr_broadcast.sin_addr.s_addr = INADDR_BROADCAST;
386 inaddr_any.s_addr = INADDR_ANY;
388 /* Discover all the network interfaces. */
389 discover_interfaces (DISCOVER_UNCONFIGURED);
391 /* Parse the dhclient.conf file. */
394 /* Parse the lease database. */
395 read_client_leases ();
397 /* Rewrite the lease database... */
398 rewrite_client_leases ();
401 /* config_counter(&snd_counter, &rcv_counter); */
403 /* If no broadcast interfaces were discovered, call the script
406 /* Call dhclient-script with the NBI flag, in case somebody
408 script_init ((struct client_state *)0, "NBI",
409 (struct string_list *)0);
410 script_go ((struct client_state *)0);
412 /* If we haven't been asked to persist, waiting for new
413 interfaces, then just exit. */
415 /* Nothing more to do. */
416 log_info ("No broadcast interfaces found - exiting.");
419 } else if (!release_mode) {
420 /* Call the script with the list of interfaces. */
421 for (ip = interfaces; ip; ip = ip -> next) {
422 /* If interfaces were specified, don't configure
423 interfaces that weren't specified! */
424 if (interfaces_requested &&
425 ((ip -> flags & (INTERFACE_REQUESTED |
426 INTERFACE_AUTOMATIC)) !=
427 INTERFACE_REQUESTED))
430 #if defined(DRAGONFLY_FUTURE)
434 #ifdef ENABLE_POLLING_MODE
435 ip -> forcediscover = 0;
436 if (ip -> client -> config -> media != NULL)
441 script_init (ip -> client,
442 "PREINIT", (struct string_list *)0);
443 if (ip -> client -> alias)
444 script_write_params (ip -> client, "alias_",
445 ip -> client -> alias);
446 script_go (ip -> client);
450 /* At this point, all the interfaces that the script thinks
451 are relevant should be running, so now we once again call
452 discover_interfaces(), and this time ask it to actually set
453 up the interfaces. */
454 discover_interfaces (interfaces_requested
458 /* Make up a seed for the random number generator from current
459 time plus the sum of the last four bytes of each
460 interface's hardware address interpreted as an integer.
461 Not much entropy, but we're booting, so we're not likely to
462 find anything better. */
464 for (ip = interfaces; ip; ip = ip -> next) {
467 &ip -> hw_address.hbuf [ip -> hw_address.hlen -
468 sizeof seed], sizeof seed);
471 srandom (seed + cur_time);
473 /* Start a configuration state machine for each interface. */
474 for (ip = interfaces; ip; ip = ip -> next) {
475 ip -> flags |= INTERFACE_RUNNING;
476 for (client = ip -> client; client; client = client -> next) {
480 client -> state = S_INIT;
481 /* Set up a timeout to start the initialization
483 #ifdef ENABLE_POLLING_MODE
484 add_timeout (cur_time + random () % 5 + 2,
485 state_polling, client, 0, 0);
487 add_timeout (cur_time + random () % 5,
488 state_reboot, client, 0, 0);
497 /* Start up a listener for the object management API protocol. */
498 if (top_level_config.omapi_port != -1) {
499 listener = (omapi_object_t *)0;
500 result = omapi_generic_new (&listener, MDL);
501 if (result != ISC_R_SUCCESS)
502 log_fatal ("Can't allocate new generic object: %s\n",
503 isc_result_totext (result));
504 result = omapi_protocol_listen (listener,
506 top_level_config.omapi_port,
508 if (result != ISC_R_SUCCESS)
509 log_fatal ("Can't start OMAPI protocol: %s",
510 isc_result_totext (result));
513 /* Set up the bootp packet handler... */
514 bootp_packet_handler = do_packet;
516 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
517 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
518 dmalloc_cutoff_generation = dmalloc_generation;
519 dmalloc_longterm = dmalloc_outstanding;
520 dmalloc_outstanding = 0;
523 /* If we're not supposed to wait before getting the address,
528 /* If we're not going to daemonize, write the pid file
530 if (no_daemon || nowait)
531 write_client_pid_file ();
533 /* Start dispatching packets and timeouts... */
542 log_info ("%s %s", message, DHCP_VERSION);
543 log_info (copyright);
547 log_error ("Usage: dhclient [-1dqr] [-nw] [-p <port>] %s",
549 log_error (" [-cf config-file] [-lf lease-file]%s",
550 "[-pf pid-file] [-e VAR=val]");
551 log_fatal (" [-sf script-file] [interface]");
554 isc_result_t find_class (struct class **c,
555 const char *s, const char *file, int line)
560 int check_collection (packet, lease, collection)
561 struct packet *packet;
563 struct collection *collection;
568 void classify (packet, class)
569 struct packet *packet;
574 int unbill_class (lease, class)
581 int find_subnet (struct subnet **sp,
582 struct iaddr addr, const char *file, int line)
587 /* Individual States:
589 * Each routine is called from the dhclient_state_machine() in one of
591 * -> entering INIT state
592 * -> recvpacket_flag == 0: timeout in this state
593 * -> otherwise: received a packet in this state
595 * Return conditions as handled by dhclient_state_machine():
596 * Returns 1, sendpacket_flag = 1: send packet, reset timer.
597 * Returns 1, sendpacket_flag = 0: just reset the timer (wait for a milestone).
598 * Returns 0: finish the nap which was interrupted for no good reason.
600 * Several per-interface variables are used to keep track of the process:
601 * active_lease: the lease that is being used on the interface
602 * (null pointer if not configured yet).
603 * offered_leases: leases corresponding to DHCPOFFER messages that have
604 * been sent to us by DHCP servers.
605 * acked_leases: leases corresponding to DHCPACK messages that have been
606 * sent to us by DHCP servers.
607 * sendpacket: DHCP packet we're trying to send.
608 * destination: IP address to send sendpacket to
609 * In addition, there are several relevant per-lease variables.
610 * T1_expiry, T2_expiry, lease_expiry: lease milestones
611 * In the active lease, these control the process of renewing the lease;
612 * In leases on the acked_leases list, this simply determines when we
613 * can no longer legitimately use the lease.
616 void state_reboot (cpp)
619 struct client_state *client = cpp;
621 /* If we don't remember an active lease, go straight to INIT. */
622 if (!client -> active ||
623 client -> active -> is_bootp ||
624 client -> active -> expiry <= cur_time) {
629 /* We are in the rebooting state. */
630 client -> state = S_REBOOTING;
632 /* make_request doesn't initialize xid because it normally comes
633 from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
634 so pick an xid now. */
635 client -> xid = random ();
637 /* Make a DHCPREQUEST packet, and set appropriate per-interface
639 make_request (client, client -> active);
640 client -> destination = iaddr_broadcast;
641 client -> first_sending = cur_time;
642 client -> interval = client -> config -> initial_interval;
644 /* Zap the medium list... */
645 client -> medium = (struct string_list *)0;
647 /* Send out the first DHCPREQUEST packet. */
648 send_request (client);
651 /* Called when a lease has completely expired and we've been unable to
654 void state_init (cpp)
657 struct client_state *client = cpp;
659 ASSERT_STATE(state, S_INIT);
661 /* Make a DHCPDISCOVER packet, and set appropriate per-interface
663 make_discover (client, client -> active);
664 client -> xid = client -> packet.xid;
665 client -> destination = iaddr_broadcast;
666 client -> state = S_SELECTING;
667 client -> first_sending = cur_time;
668 client -> interval = client -> config -> initial_interval;
670 /* Add an immediate timeout to cause the first DHCPDISCOVER packet
672 send_discover (client);
675 /* state_selecting is called when one or more DHCPOFFER packets have been
676 received and a configurable period of time has passed. */
678 void state_selecting (cpp)
681 struct client_state *client = cpp;
682 struct client_lease *lp, *next, *picked;
685 ASSERT_STATE(state, S_SELECTING);
687 /* Cancel state_selecting and send_discover timeouts, since either
688 one could have got us here. */
689 cancel_timeout (state_selecting, client);
690 cancel_timeout (send_discover, client);
692 /* We have received one or more DHCPOFFER packets. Currently,
693 the only criterion by which we judge leases is whether or
694 not we get a response when we arp for them. */
695 picked = (struct client_lease *)0;
696 for (lp = client -> offered_leases; lp; lp = next) {
699 /* Check to see if we got an ARPREPLY for the address
700 in this particular lease. */
703 picked -> next = (struct client_lease *)0;
706 destroy_client_lease (lp);
709 client -> offered_leases = (struct client_lease *)0;
711 /* If we just tossed all the leases we were offered, go back
714 client -> state = S_INIT;
719 /* If it was a BOOTREPLY, we can just take the address right now. */
720 if (picked -> is_bootp) {
721 client -> new = picked;
723 /* Make up some lease expiry times
724 XXX these should be configurable. */
725 client -> new -> expiry = cur_time + 12000;
726 client -> new -> renewal += cur_time + 8000;
727 client -> new -> rebind += cur_time + 10000;
729 client -> state = S_REQUESTING;
731 /* Bind to the address we received. */
736 /* Go to the REQUESTING state. */
737 client -> destination = iaddr_broadcast;
738 client -> state = S_REQUESTING;
739 client -> first_sending = cur_time;
740 client -> interval = client -> config -> initial_interval;
742 /* Make a DHCPREQUEST packet from the lease we picked. */
743 make_request (client, picked);
744 client -> xid = client -> packet.xid;
746 /* Toss the lease we picked - we'll get it back in a DHCPACK. */
747 destroy_client_lease (picked);
749 /* Add an immediate timeout to send the first DHCPREQUEST packet. */
750 send_request (client);
753 /* state_requesting is called when we receive a DHCPACK message after
754 having sent out one or more DHCPREQUEST packets. */
756 void dhcpack (packet)
757 struct packet *packet;
759 struct interface_info *ip = packet -> interface;
760 struct client_state *client;
761 struct client_lease *lease;
762 struct option_cache *oc;
763 struct data_string ds;
766 /* If we're not receptive to an offer right now, or if the offer
767 has an unrecognizable transaction id, then just drop it. */
768 for (client = ip -> client; client; client = client -> next) {
769 if (client -> xid == packet -> raw -> xid)
773 (packet -> interface -> hw_address.hlen - 1 !=
774 packet -> raw -> hlen) ||
775 (memcmp (&packet -> interface -> hw_address.hbuf [1],
776 packet -> raw -> chaddr, packet -> raw -> hlen))) {
778 log_debug ("DHCPACK in wrong transaction.");
783 if (client -> state != S_REBOOTING &&
784 client -> state != S_REQUESTING &&
785 client -> state != S_RENEWING &&
786 client -> state != S_REBINDING) {
788 log_debug ("DHCPACK in wrong state.");
793 log_info ("DHCPACK from %s", piaddr (packet -> client_addr));
795 lease = packet_to_lease (packet, client);
797 log_info ("packet_to_lease failed.");
801 client -> new = lease;
803 /* Stop resending DHCPREQUEST. */
804 cancel_timeout (send_request, client);
806 /* Figure out the lease time. */
807 oc = lookup_option (&dhcp_universe, client -> new -> options,
808 DHO_DHCP_LEASE_TIME);
809 memset (&ds, 0, sizeof ds);
811 evaluate_option_cache (&ds, packet, (struct lease *)0, client,
812 packet -> options, client -> new -> options,
813 &global_scope, oc, MDL)) {
815 client -> new -> expiry = getULong (ds.data);
817 client -> new -> expiry = 0;
818 data_string_forget (&ds, MDL);
820 client -> new -> expiry = 0;
822 if (!client -> new -> expiry) {
823 log_error ("no expiry time on offered lease.");
824 /* XXX this is going to be bad - if this _does_
825 XXX happen, we should probably dynamically
826 XXX disqualify the DHCP server that gave us the
827 XXX bad packet from future selections and
828 XXX then go back into the init state. */
833 /* A number that looks negative here is really just very large,
834 because the lease expiry offset is unsigned. */
835 if (client -> new -> expiry < 0)
836 client -> new -> expiry = TIME_MAX;
837 /* Take the server-provided renewal time if there is one. */
838 oc = lookup_option (&dhcp_universe, client -> new -> options,
839 DHO_DHCP_RENEWAL_TIME);
841 evaluate_option_cache (&ds, packet, (struct lease *)0, client,
842 packet -> options, client -> new -> options,
843 &global_scope, oc, MDL)) {
845 client -> new -> renewal = getULong (ds.data);
847 client -> new -> renewal = 0;
848 data_string_forget (&ds, MDL);
850 client -> new -> renewal = 0;
852 /* If it wasn't specified by the server, calculate it. */
853 if (!client -> new -> renewal)
854 client -> new -> renewal =
855 client -> new -> expiry / 2;
857 /* Now introduce some randomness to the renewal time: */
858 client -> new -> renewal = (((client -> new -> renewal + 3) * 3 / 4) +
859 (random () % /* XXX NUMS */
860 ((client -> new -> renewal + 3) / 4)));
862 /* Same deal with the rebind time. */
863 oc = lookup_option (&dhcp_universe, client -> new -> options,
864 DHO_DHCP_REBINDING_TIME);
866 evaluate_option_cache (&ds, packet, (struct lease *)0, client,
867 packet -> options, client -> new -> options,
868 &global_scope, oc, MDL)) {
870 client -> new -> rebind = getULong (ds.data);
872 client -> new -> rebind = 0;
873 data_string_forget (&ds, MDL);
875 client -> new -> rebind = 0;
877 if (!client -> new -> rebind)
878 client -> new -> rebind =
879 (client -> new -> expiry * 7) / 8; /* XXX NUMS */
881 /* Make sure our randomness didn't run the renewal time past the
883 if (client -> new -> renewal > client -> new -> rebind)
884 client -> new -> renewal = (client -> new -> rebind * 3) / 4;
886 client -> new -> expiry += cur_time;
887 /* Lease lengths can never be negative. */
888 if (client -> new -> expiry < cur_time)
889 client -> new -> expiry = TIME_MAX;
890 client -> new -> renewal += cur_time;
891 if (client -> new -> renewal < cur_time)
892 client -> new -> renewal = TIME_MAX;
893 client -> new -> rebind += cur_time;
894 if (client -> new -> rebind < cur_time)
895 client -> new -> rebind = TIME_MAX;
900 void bind_lease (client)
901 struct client_state *client;
903 struct interface_info *ip = client -> interface;
905 /* Remember the medium. */
906 client -> new -> medium = client -> medium;
908 /* Run the client script with the new parameters. */
909 script_init (client, (client -> state == S_REQUESTING
911 : (client -> state == S_RENEWING
913 : (client -> state == S_REBOOTING
914 ? "REBOOT" : "REBIND"))),
915 client -> new -> medium);
916 if (client -> active && client -> state != S_REBOOTING)
917 script_write_params (client, "old_", client -> active);
918 script_write_params (client, "new_", client -> new);
920 script_write_params (client, "alias_", client -> alias);
922 /* If the BOUND/RENEW code detects another machine using the
923 offered address, it exits nonzero. We need to send a
924 DHCPDECLINE and toss the lease. */
925 if (script_go (client)) {
926 make_decline (client, client -> new);
927 send_decline (client);
928 destroy_client_lease (client -> new);
929 client -> new = (struct client_lease *)0;
934 /* Write out the new lease. */
935 write_client_lease (client, client -> new, 0, 0);
938 * It's now possible that state_reboot can be called
939 * after a interface link went down and is up again.
940 * To prevent tons of equal leases saved on disk, we rewrite
943 read_client_leases ();
944 rewrite_client_leases ();
946 /* Replace the old active lease with the new one. */
947 if (client -> active)
948 destroy_client_lease (client -> active);
949 client -> active = client -> new;
950 client -> new = (struct client_lease *)0;
952 /* Set up a timeout to start the renewal process. */
953 add_timeout (client -> active -> renewal,
954 state_bound, client, 0, 0);
956 log_info ("bound to %s -- renewal in %ld seconds.",
957 piaddr (client -> active -> address),
958 (long)(client -> active -> renewal - cur_time));
959 client -> state = S_BOUND;
960 #ifdef ENABLE_POLLING_MODE
961 /* Init some interface vars, enable polling */
962 client -> interface -> linkstate = HAVELINK;
963 client -> interface -> forcediscover = 0;
964 client -> interface -> polling = 1;
965 #endif /* ifdef ENABLE_POLLING_MODE */
966 reinitialize_interfaces ();
968 if (client -> config -> do_forward_update) {
969 client -> dns_update_timeout = 1;
970 add_timeout (cur_time + 1, client_dns_update_timeout,
975 /* state_bound is called when we've successfully bound to a particular
976 lease, but the renewal time on that lease has expired. We are
977 expected to unicast a DHCPREQUEST to the server that gave us our
980 void state_bound (cpp)
983 struct client_state *client = cpp;
985 struct option_cache *oc;
986 struct data_string ds;
988 ASSERT_STATE(state, S_BOUND);
990 /* T1 has expired. */
991 make_request (client, client -> active);
992 client -> xid = client -> packet.xid;
994 memset (&ds, 0, sizeof ds);
995 oc = lookup_option (&dhcp_universe, client -> active -> options,
996 DHO_DHCP_SERVER_IDENTIFIER);
998 evaluate_option_cache (&ds, (struct packet *)0, (struct lease *)0,
999 client, (struct option_state *)0,
1000 client -> active -> options,
1001 &global_scope, oc, MDL)) {
1003 memcpy (client -> destination.iabuf, ds.data, 4);
1004 client -> destination.len = 4;
1006 client -> destination = iaddr_broadcast;
1008 client -> destination = iaddr_broadcast;
1010 client -> first_sending = cur_time;
1011 client -> interval = client -> config -> initial_interval;
1012 client -> state = S_RENEWING;
1014 /* Send the first packet immediately. */
1015 send_request (client);
1018 /* state_stop is called when we've been told to shut down. We unconfigure
1019 the interfaces, and then stop operating until told otherwise. */
1021 void state_stop (cpp)
1024 struct client_state *client = cpp;
1027 /* Cancel all timeouts. */
1028 cancel_timeout (state_selecting, client);
1029 cancel_timeout (send_discover, client);
1030 cancel_timeout (send_request, client);
1031 cancel_timeout (state_bound, client);
1033 /* If we have an address, unconfigure it. */
1034 if (client -> active) {
1035 script_init (client, "STOP", client -> active -> medium);
1036 script_write_params (client, "old_", client -> active);
1037 if (client -> alias)
1038 script_write_params (client, "alias_",
1044 int commit_leases ()
1049 int write_lease (lease)
1050 struct lease *lease;
1055 int write_host (host)
1056 struct host_decl *host;
1061 void db_startup (testp)
1067 struct packet *packet;
1069 struct iaddrlist *ap;
1071 if (packet -> raw -> op != BOOTREPLY)
1074 /* If there's a reject list, make sure this packet's sender isn't
1076 for (ap = packet -> interface -> client -> config -> reject_list;
1077 ap; ap = ap -> next) {
1078 if (addr_eq (packet -> client_addr, ap -> addr)) {
1079 log_info ("BOOTREPLY from %s rejected.",
1080 piaddr (ap -> addr));
1090 struct packet *packet;
1092 struct iaddrlist *ap;
1093 void (*handler) PROTO ((struct packet *));
1096 switch (packet -> packet_type) {
1098 handler = dhcpoffer;
1116 /* If there's a reject list, make sure this packet's sender isn't
1118 for (ap = packet -> interface -> client -> config -> reject_list;
1119 ap; ap = ap -> next) {
1120 if (addr_eq (packet -> client_addr, ap -> addr)) {
1121 log_info ("%s from %s rejected.",
1122 type, piaddr (ap -> addr));
1126 (*handler) (packet);
1129 void dhcpoffer (packet)
1130 struct packet *packet;
1132 struct interface_info *ip = packet -> interface;
1133 struct client_state *client;
1134 struct client_lease *lease, *lp;
1137 const char *name = packet -> packet_type ? "DHCPOFFER" : "BOOTREPLY";
1138 struct iaddrlist *ap;
1139 struct option_cache *oc;
1143 dump_packet (packet);
1146 /* Find a client state that matches the xid... */
1147 for (client = ip -> client; client; client = client -> next)
1148 if (client -> xid == packet -> raw -> xid)
1151 /* If we're not receptive to an offer right now, or if the offer
1152 has an unrecognizable transaction id, then just drop it. */
1154 client -> state != S_SELECTING ||
1155 (packet -> interface -> hw_address.hlen - 1 !=
1156 packet -> raw -> hlen) ||
1157 (memcmp (&packet -> interface -> hw_address.hbuf [1],
1158 packet -> raw -> chaddr, packet -> raw -> hlen))) {
1160 log_debug ("%s in wrong transaction.", name);
1165 sprintf (obuf, "%s from %s", name, piaddr (packet -> client_addr));
1168 /* If this lease doesn't supply the minimum required parameters,
1170 if (client -> config -> required_options) {
1171 for (i = 0; client -> config -> required_options [i]; i++) {
1173 (&dhcp_universe, packet -> options,
1174 client -> config -> required_options [i])) {
1175 log_info ("%s: no %s option.",
1176 obuf, (dhcp_universe.options
1177 [client -> config -> required_options [i]]
1184 /* If we've already seen this lease, don't record it again. */
1185 for (lease = client -> offered_leases; lease; lease = lease -> next) {
1186 if (lease -> address.len == sizeof packet -> raw -> yiaddr &&
1187 !memcmp (lease -> address.iabuf,
1188 &packet -> raw -> yiaddr, lease -> address.len)) {
1189 log_debug ("%s: already seen.", obuf);
1194 lease = packet_to_lease (packet, client);
1196 log_info ("%s: packet_to_lease failed.", obuf);
1200 /* If this lease was acquired through a BOOTREPLY, record that
1202 if (!packet -> options_valid || !packet -> packet_type)
1203 lease -> is_bootp = 1;
1205 /* Record the medium under which this lease was offered. */
1206 lease -> medium = client -> medium;
1208 /* Figure out when we're supposed to stop selecting. */
1209 stop_selecting = (client -> first_sending +
1210 client -> config -> select_interval);
1212 /* If this is the lease we asked for, put it at the head of the
1213 list, and don't mess with the arp request timeout. */
1214 if (lease -> address.len == client -> requested_address.len &&
1215 !memcmp (lease -> address.iabuf,
1216 client -> requested_address.iabuf,
1217 client -> requested_address.len)) {
1218 lease -> next = client -> offered_leases;
1219 client -> offered_leases = lease;
1221 /* Put the lease at the end of the list. */
1222 lease -> next = (struct client_lease *)0;
1223 if (!client -> offered_leases)
1224 client -> offered_leases = lease;
1226 for (lp = client -> offered_leases; lp -> next;
1233 /* If the selecting interval has expired, go immediately to
1234 state_selecting(). Otherwise, time out into
1235 state_selecting at the select interval. */
1236 if (stop_selecting <= 0)
1237 state_selecting (client);
1239 add_timeout (stop_selecting, state_selecting, client, 0, 0);
1240 cancel_timeout (send_discover, client);
1242 log_info ("%s", obuf);
1245 /* Allocate a client_lease structure and initialize it from the parameters
1246 in the specified packet. */
1248 struct client_lease *packet_to_lease (packet, client)
1249 struct packet *packet;
1250 struct client_state *client;
1252 struct client_lease *lease;
1254 struct option_cache *oc;
1255 struct data_string data;
1257 lease = (struct client_lease *)new_client_lease (MDL);
1260 log_error ("packet_to_lease: no memory to record lease.\n");
1261 return (struct client_lease *)0;
1264 memset (lease, 0, sizeof *lease);
1266 /* Copy the lease options. */
1267 option_state_reference (&lease -> options, packet -> options, MDL);
1269 lease -> address.len = sizeof (packet -> raw -> yiaddr);
1270 memcpy (lease -> address.iabuf, &packet -> raw -> yiaddr,
1271 lease -> address.len);
1273 memset (&data, 0, sizeof data);
1275 if (client -> config -> vendor_space_name) {
1276 i = DHO_VENDOR_ENCAPSULATED_OPTIONS;
1278 /* See if there was a vendor encapsulation option. */
1279 oc = lookup_option (&dhcp_universe, lease -> options, i);
1281 client -> config -> vendor_space_name &&
1282 evaluate_option_cache (&data, packet,
1283 (struct lease *)0, client,
1284 packet -> options, lease -> options,
1285 &global_scope, oc, MDL)) {
1287 parse_encapsulated_suboptions
1288 (packet -> options, &dhcp_options [i],
1289 data.data, data.len, &dhcp_universe,
1290 client -> config -> vendor_space_name
1293 data_string_forget (&data, MDL);
1298 /* Figure out the overload flag. */
1299 oc = lookup_option (&dhcp_universe, lease -> options,
1300 DHO_DHCP_OPTION_OVERLOAD);
1302 evaluate_option_cache (&data, packet, (struct lease *)0, client,
1303 packet -> options, lease -> options,
1304 &global_scope, oc, MDL)) {
1309 data_string_forget (&data, MDL);
1313 /* If the server name was filled out, copy it. */
1314 if (!(i & 2) && packet -> raw -> sname [0]) {
1316 /* Don't count on the NUL terminator. */
1317 for (len = 0; len < 64; len++)
1318 if (!packet -> raw -> sname [len])
1320 lease -> server_name = dmalloc (len + 1, MDL);
1321 if (!lease -> server_name) {
1322 log_error ("dhcpoffer: no memory for filename.\n");
1323 destroy_client_lease (lease);
1324 return (struct client_lease *)0;
1326 memcpy (lease -> server_name,
1327 packet -> raw -> sname, len);
1328 lease -> server_name [len] = 0;
1332 /* Ditto for the filename. */
1333 if (!(i & 1) && packet -> raw -> file [0]) {
1335 /* Don't count on the NUL terminator. */
1336 for (len = 0; len < 64; len++)
1337 if (!packet -> raw -> file [len])
1339 lease -> filename = dmalloc (len + 1, MDL);
1340 if (!lease -> filename) {
1341 log_error ("dhcpoffer: no memory for filename.\n");
1342 destroy_client_lease (lease);
1343 return (struct client_lease *)0;
1345 memcpy (lease -> filename,
1346 packet -> raw -> file, len);
1347 lease -> filename [len] = 0;
1351 execute_statements_in_scope ((struct binding_value **)0,
1352 (struct packet *)packet,
1353 (struct lease *)0, client,
1354 lease -> options, lease -> options,
1356 client -> config -> on_receipt,
1362 void dhcpnak (packet)
1363 struct packet *packet;
1365 struct interface_info *ip = packet -> interface;
1366 struct client_state *client;
1368 /* Find a client state that matches the xid... */
1369 for (client = ip -> client; client; client = client -> next)
1370 if (client -> xid == packet -> raw -> xid)
1373 /* If we're not receptive to an offer right now, or if the offer
1374 has an unrecognizable transaction id, then just drop it. */
1376 (packet -> interface -> hw_address.hlen - 1 !=
1377 packet -> raw -> hlen) ||
1378 (memcmp (&packet -> interface -> hw_address.hbuf [1],
1379 packet -> raw -> chaddr, packet -> raw -> hlen))) {
1381 log_debug ("DHCPNAK in wrong transaction.");
1386 if (client -> state != S_REBOOTING &&
1387 client -> state != S_REQUESTING &&
1388 client -> state != S_RENEWING &&
1389 client -> state != S_REBINDING) {
1391 log_debug ("DHCPNAK in wrong state.");
1396 log_info ("DHCPNAK from %s", piaddr (packet -> client_addr));
1398 if (!client -> active) {
1400 log_info ("DHCPNAK with no active lease.\n");
1405 destroy_client_lease (client -> active);
1406 client -> active = (struct client_lease *)0;
1408 /* Stop sending DHCPREQUEST packets... */
1409 cancel_timeout (send_request, client);
1411 client -> state = S_INIT;
1412 state_init (client);
1415 /* Send out a DHCPDISCOVER packet, and set a timeout to send out another
1416 one after the right interval has expired. If we don't get an offer by
1417 the time we reach the panic interval, call the panic function. */
1419 void send_discover (cpp)
1422 struct client_state *client = cpp;
1428 #ifdef ENABLE_POLLING_MODE
1429 /* Disable polling for this interface */
1430 client -> interface -> polling = 0;
1433 /* Figure out how long it's been since we started transmitting. */
1434 interval = cur_time - client -> first_sending;
1436 /* If we're past the panic timeout, call the script and tell it
1437 we haven't found anything for this interface yet. */
1438 if (interval > client -> config -> timeout) {
1439 state_panic (client);
1443 /* If we're selecting media, try the whole list before doing
1444 the exponential backoff, but if we've already received an
1445 offer, stop looping, because we obviously have it right. */
1446 if (!client -> offered_leases &&
1447 client -> config -> media) {
1450 if (client -> medium) {
1451 client -> medium = client -> medium -> next;
1454 if (!client -> medium) {
1456 log_fatal ("No valid media types for %s!",
1457 client -> interface -> name);
1459 client -> config -> media;
1463 log_info ("Trying medium \"%s\" %d",
1464 client -> medium -> string, increase);
1465 script_init (client, "MEDIUM", client -> medium);
1466 if (script_go (client)) {
1472 /* If we're supposed to increase the interval, do so. If it's
1473 currently zero (i.e., we haven't sent any packets yet), set
1474 it to one; otherwise, add to it a random number between
1475 zero and two times itself. On average, this means that it
1476 will double with every transmission. */
1478 if (!client -> interval)
1479 client -> interval =
1480 client -> config -> initial_interval;
1482 client -> interval += ((random () >> 2) %
1483 (2 * client -> interval));
1485 /* Don't backoff past cutoff. */
1486 if (client -> interval >
1487 client -> config -> backoff_cutoff)
1488 client -> interval =
1489 ((client -> config -> backoff_cutoff / 2)
1490 + ((random () >> 2) %
1491 client -> config -> backoff_cutoff));
1492 } else if (!client -> interval)
1493 client -> interval = client -> config -> initial_interval;
1495 /* If the backoff would take us to the panic timeout, just use that
1497 if (cur_time + client -> interval >
1498 client -> first_sending + client -> config -> timeout)
1499 client -> interval =
1500 (client -> first_sending +
1501 client -> config -> timeout) - cur_time + 1;
1503 /* Record the number of seconds since we started sending. */
1504 if (interval < 65536)
1505 client -> packet.secs = htons (interval);
1507 client -> packet.secs = htons (65535);
1508 client -> secs = client -> packet.secs;
1510 log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",
1511 client -> name ? client -> name : client -> interface -> name,
1512 inet_ntoa (sockaddr_broadcast.sin_addr),
1513 ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval));
1515 /* Send out a packet. */
1516 result = send_packet (client -> interface, (struct packet *)0,
1518 client -> packet_length,
1519 inaddr_any, &sockaddr_broadcast,
1520 (struct hardware *)0);
1522 add_timeout (cur_time + client -> interval,
1523 send_discover, client, 0, 0);
1526 /* state_panic gets called if we haven't received any offers in a preset
1527 amount of time. When this happens, we try to use existing leases that
1528 haven't yet expired, and failing that, we call the client script and
1529 hope it can do something. */
1531 void state_panic (cpp)
1534 struct client_state *client = cpp;
1535 struct client_lease *loop;
1536 struct client_lease *lp;
1538 if (client -> interface -> linkstate == NOLINK)
1541 loop = lp = client -> active;
1543 log_info ("No DHCPOFFERS received.");
1545 /* We may not have an active lease, but we may have some
1546 predefined leases that we can try. */
1547 if (!client -> active && client -> leases)
1550 /* Run through the list of leases and see if one can be used. */
1551 while (client -> active) {
1552 if (client -> active -> expiry > cur_time) {
1553 log_info ("Trying recorded lease %s",
1554 piaddr (client -> active -> address));
1555 /* Run the client script with the existing
1557 script_init (client, "TIMEOUT",
1558 client -> active -> medium);
1559 script_write_params (client, "new_", client -> active);
1560 if (client -> alias)
1561 script_write_params (client, "alias_",
1564 /* If the old lease is still good and doesn't
1565 yet need renewal, go into BOUND state and
1566 timeout at the renewal time. */
1567 if (!script_go (client)) {
1568 if (cur_time < client -> active -> renewal) {
1569 client -> state = S_BOUND;
1570 log_info ("bound: renewal in %ld %s.",
1571 (long)(client -> active -> renewal -
1572 cur_time), "seconds");
1573 #ifdef ENABLE_POLLING_MODE
1574 /* Enable polling for this interface */
1575 client -> interface -> polling = 1;
1577 add_timeout (client -> active -> renewal,
1578 state_bound, client, 0, 0);
1580 client -> state = S_BOUND;
1581 log_info ("bound: immediate renewal.");
1582 state_bound (client);
1585 * Set the link status back to nolink, even
1586 * if we have media settings.
1588 client -> interface -> linkstate = NOLINK;
1589 reinitialize_interfaces ();
1595 /* If there are no other leases, give up. */
1596 if (!client -> leases) {
1597 client -> leases = client -> active;
1598 client -> active = (struct client_lease *)0;
1603 /* Otherwise, put the active lease at the end of the
1604 lease list, and try another lease.. */
1605 for (lp = client -> leases; lp -> next; lp = lp -> next)
1607 lp -> next = client -> active;
1609 lp -> next -> next = (struct client_lease *)0;
1611 client -> active = client -> leases;
1612 client -> leases = client -> leases -> next;
1614 /* If we already tried this lease, we've exhausted the
1615 set of leases, so we might as well give up for
1617 if (client -> active == loop)
1620 loop = client -> active;
1623 /* No leases were available, or what was available didn't work, so
1624 tell the shell script that we failed to allocate an address,
1625 and try again later. */
1628 log_info ("Unable to obtain a lease on first try.%s",
1633 log_info ("No working leases in persistent database - sleeping.");
1635 #ifdef ENABLE_POLLING_MODE
1636 /* Enable polling for this interface */
1637 client -> interface -> polling = 1;
1640 script_init (client, "FAIL", (struct string_list *)0);
1641 if (client -> alias)
1642 script_write_params (client, "alias_", client -> alias);
1644 client -> state = S_INIT;
1645 add_timeout (cur_time +
1646 ((client -> config -> retry_interval + 1) / 2 +
1647 (random () % client -> config -> retry_interval)),
1648 state_init, client, 0, 0);
1652 void send_request (cpp)
1655 struct client_state *client = cpp;
1659 struct sockaddr_in destination;
1660 struct in_addr from;
1662 /* Figure out how long it's been since we started transmitting. */
1663 interval = cur_time - client -> first_sending;
1665 /* If we're in the INIT-REBOOT or REQUESTING state and we're
1666 past the reboot timeout, go to INIT and see if we can
1667 DISCOVER an address... */
1668 /* XXX In the INIT-REBOOT state, if we don't get an ACK, it
1669 means either that we're on a network with no DHCP server,
1670 or that our server is down. In the latter case, assuming
1671 that there is a backup DHCP server, DHCPDISCOVER will get
1672 us a new address, but we could also have successfully
1673 reused our old address. In the former case, we're hosed
1674 anyway. This is not a win-prone situation. */
1675 if ((client -> state == S_REBOOTING ||
1676 client -> state == S_REQUESTING) &&
1677 interval > client -> config -> reboot_timeout) {
1679 client -> state = S_INIT;
1680 cancel_timeout (send_request, client);
1681 state_init (client);
1685 /* If we're in the reboot state, make sure the media is set up
1687 if (client -> state == S_REBOOTING &&
1688 !client -> medium &&
1689 client -> active -> medium ) {
1690 script_init (client, "MEDIUM", client -> active -> medium);
1692 /* If the medium we chose won't fly, go to INIT state. */
1693 if (script_go (client))
1696 /* Record the medium. */
1697 client -> medium = client -> active -> medium;
1700 /* If the lease has expired, relinquish the address and go back
1701 to the INIT state. */
1702 if (client -> state != S_REQUESTING &&
1703 cur_time > client -> active -> expiry) {
1704 /* Run the client script with the new parameters. */
1705 script_init (client, "EXPIRE", (struct string_list *)0);
1706 script_write_params (client, "old_", client -> active);
1707 if (client -> alias)
1708 script_write_params (client, "alias_",
1712 /* Now do a preinit on the interface so that we can
1713 discover a new address. */
1714 script_init (client, "PREINIT", (struct string_list *)0);
1715 if (client -> alias)
1716 script_write_params (client, "alias_",
1720 client -> state = S_INIT;
1721 state_init (client);
1725 /* Do the exponential backoff... */
1726 if (!client -> interval)
1727 client -> interval = client -> config -> initial_interval;
1729 client -> interval += ((random () >> 2) %
1730 (2 * client -> interval));
1733 /* Don't backoff past cutoff. */
1734 if (client -> interval >
1735 client -> config -> backoff_cutoff)
1736 client -> interval =
1737 ((client -> config -> backoff_cutoff / 2)
1738 + ((random () >> 2) % client -> interval));
1740 /* If the backoff would take us to the expiry time, just set the
1741 timeout to the expiry time. */
1742 if (client -> state != S_REQUESTING &&
1743 cur_time + client -> interval > client -> active -> expiry)
1744 client -> interval =
1745 client -> active -> expiry - cur_time + 1;
1747 /* If the lease T2 time has elapsed, or if we're not yet bound,
1748 broadcast the DHCPREQUEST rather than unicasting. */
1749 if (client -> state == S_REQUESTING ||
1750 client -> state == S_REBOOTING ||
1751 cur_time > client -> active -> rebind)
1752 destination.sin_addr = sockaddr_broadcast.sin_addr;
1754 memcpy (&destination.sin_addr.s_addr,
1755 client -> destination.iabuf,
1756 sizeof destination.sin_addr.s_addr);
1757 destination.sin_port = remote_port;
1758 destination.sin_family = AF_INET;
1760 destination.sin_len = sizeof destination;
1763 if (client -> state == S_RENEWING ||
1764 client -> state == S_REBINDING)
1765 memcpy (&from, client -> active -> address.iabuf,
1768 from.s_addr = INADDR_ANY;
1770 /* Record the number of seconds since we started sending. */
1771 if (client -> state == S_REQUESTING)
1772 client -> packet.secs = client -> secs;
1774 if (interval < 65536)
1775 client -> packet.secs = htons (interval);
1777 client -> packet.secs = htons (65535);
1780 log_info ("DHCPREQUEST on %s to %s port %d",
1781 client -> name ? client -> name : client -> interface -> name,
1782 inet_ntoa (destination.sin_addr),
1783 ntohs (destination.sin_port));
1785 if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
1787 result = send_packet (fallback_interface,
1790 client -> packet_length,
1792 (struct hardware *)0);
1794 /* Send out a packet. */
1795 result = send_packet (client -> interface, (struct packet *)0,
1797 client -> packet_length,
1799 (struct hardware *)0);
1801 add_timeout (cur_time + client -> interval,
1802 send_request, client, 0, 0);
1805 void send_decline (cpp)
1808 struct client_state *client = cpp;
1812 log_info ("DHCPDECLINE on %s to %s port %d",
1813 client -> name ? client -> name : client -> interface -> name,
1814 inet_ntoa (sockaddr_broadcast.sin_addr),
1815 ntohs (sockaddr_broadcast.sin_port));
1817 /* Send out a packet. */
1818 result = send_packet (client -> interface, (struct packet *)0,
1820 client -> packet_length,
1821 inaddr_any, &sockaddr_broadcast,
1822 (struct hardware *)0);
1825 void send_release (cpp)
1828 struct client_state *client = cpp;
1831 struct sockaddr_in destination;
1832 struct in_addr from;
1834 memcpy (&from, client -> active -> address.iabuf,
1836 memcpy (&destination.sin_addr.s_addr,
1837 client -> destination.iabuf,
1838 sizeof destination.sin_addr.s_addr);
1839 destination.sin_port = remote_port;
1840 destination.sin_family = AF_INET;
1842 destination.sin_len = sizeof destination;
1845 /* Set the lease to end now, so that we don't accidentally
1846 reuse it if we restart before the old expiry time. */
1847 client -> active -> expiry =
1848 client -> active -> renewal =
1849 client -> active -> rebind = cur_time;
1850 if (!write_client_lease (client, client -> active, 1, 1)) {
1851 log_error ("Can't release lease: lease write failed.");
1855 log_info ("DHCPRELEASE on %s to %s port %d",
1856 client -> name ? client -> name : client -> interface -> name,
1857 inet_ntoa (destination.sin_addr),
1858 ntohs (destination.sin_port));
1860 if (fallback_interface)
1861 result = send_packet (fallback_interface,
1864 client -> packet_length,
1866 (struct hardware *)0);
1868 /* Send out a packet. */
1869 result = send_packet (client -> interface, (struct packet *)0,
1871 client -> packet_length,
1873 (struct hardware *)0);
1876 void make_client_options (client, lease, type, sid, rip, prl, op)
1877 struct client_state *client;
1878 struct client_lease *lease;
1880 struct option_cache *sid;
1883 struct option_state **op;
1886 struct option_cache *oc;
1887 struct buffer *bp = (struct buffer *)0;
1889 /* If there are any leftover options, get rid of them. */
1891 option_state_dereference (op, MDL);
1893 /* Allocate space for options. */
1894 option_state_allocate (op, MDL);
1896 /* Send the server identifier if provided. */
1898 save_option (&dhcp_universe, *op, sid);
1900 oc = (struct option_cache *)0;
1902 /* Send the requested address if provided. */
1904 client -> requested_address = *rip;
1905 if (!(make_const_option_cache
1906 (&oc, (struct buffer **)0, rip -> iabuf, rip -> len,
1907 &dhcp_options [DHO_DHCP_REQUESTED_ADDRESS], MDL)))
1908 log_error ("can't make requested address cache.");
1910 save_option (&dhcp_universe, *op, oc);
1911 option_cache_dereference (&oc, MDL);
1914 client -> requested_address.len = 0;
1917 if (!(make_const_option_cache
1918 (&oc, (struct buffer **)0,
1919 type, 1, &dhcp_options [DHO_DHCP_MESSAGE_TYPE], MDL)))
1920 log_error ("can't make message type.");
1922 save_option (&dhcp_universe, *op, oc);
1923 option_cache_dereference (&oc, MDL);
1927 /* Figure out how many parameters were requested. */
1928 for (i = 0; prl [i]; i++)
1930 if (!buffer_allocate (&bp, i, MDL))
1931 log_error ("can't make parameter list buffer.");
1933 for (i = 0; prl [i]; i++)
1934 bp -> data [i] = prl [i];
1935 if (!(make_const_option_cache
1936 (&oc, &bp, (u_int8_t *)0, i,
1937 &dhcp_options [DHO_DHCP_PARAMETER_REQUEST_LIST],
1939 log_error ("can't make option cache");
1941 save_option (&dhcp_universe, *op, oc);
1942 option_cache_dereference (&oc, MDL);
1947 /* Run statements that need to be run on transmission. */
1948 if (client -> config -> on_transmission)
1949 execute_statements_in_scope
1950 ((struct binding_value **)0,
1951 (struct packet *)0, (struct lease *)0, client,
1952 (lease ? lease -> options : (struct option_state *)0),
1954 client -> config -> on_transmission,
1958 void make_discover (client, lease)
1959 struct client_state *client;
1960 struct client_lease *lease;
1962 unsigned char discover = DHCPDISCOVER;
1964 struct option_state *options = (struct option_state *)0;
1966 memset (&client -> packet, 0, sizeof (client -> packet));
1968 make_client_options (client,
1969 lease, &discover, (struct option_cache *)0,
1970 lease ? &lease -> address : (struct iaddr *)0,
1971 client -> config -> requested_options,
1974 /* Set up the option buffer... */
1975 client -> packet_length =
1976 cons_options ((struct packet *)0, &client -> packet,
1977 (struct lease *)0, client,
1978 /* maximum packet size */1500,
1979 (struct option_state *)0,
1981 /* scope */ &global_scope,
1985 (struct data_string *)0,
1986 client -> config -> vendor_space_name);
1988 option_state_dereference (&options, MDL);
1989 if (client -> packet_length < BOOTP_MIN_LEN)
1990 client -> packet_length = BOOTP_MIN_LEN;
1992 client -> packet.op = BOOTREQUEST;
1993 client -> packet.htype = client -> interface -> hw_address.hbuf [0];
1994 client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
1995 client -> packet.hops = 0;
1996 client -> packet.xid = random ();
1997 client -> packet.secs = 0; /* filled in by send_discover. */
1999 if (can_receive_unicast_unconfigured (client -> interface))
2000 client -> packet.flags = 0;
2002 client -> packet.flags = htons (BOOTP_BROADCAST);
2004 memset (&(client -> packet.ciaddr),
2005 0, sizeof client -> packet.ciaddr);
2006 memset (&(client -> packet.yiaddr),
2007 0, sizeof client -> packet.yiaddr);
2008 memset (&(client -> packet.siaddr),
2009 0, sizeof client -> packet.siaddr);
2010 client -> packet.giaddr = giaddr;
2011 if (client -> interface -> hw_address.hlen > 0)
2012 memcpy (client -> packet.chaddr,
2013 &client -> interface -> hw_address.hbuf [1],
2014 (unsigned)(client -> interface -> hw_address.hlen - 1));
2017 dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
2022 void make_request (client, lease)
2023 struct client_state *client;
2024 struct client_lease *lease;
2026 unsigned char request = DHCPREQUEST;
2028 unsigned char *tmp, *digest;
2029 unsigned char *old_digest_loc;
2030 struct option_cache *oc;
2032 memset (&client -> packet, 0, sizeof (client -> packet));
2034 if (client -> state == S_REQUESTING)
2035 oc = lookup_option (&dhcp_universe, lease -> options,
2036 DHO_DHCP_SERVER_IDENTIFIER);
2038 oc = (struct option_cache *)0;
2040 make_client_options (client, lease, &request, oc,
2041 ((client -> state == S_REQUESTING ||
2042 client -> state == S_REBOOTING)
2044 : (struct iaddr *)0),
2045 client -> config -> requested_options,
2046 &client -> sent_options);
2048 /* Set up the option buffer... */
2049 client -> packet_length =
2050 cons_options ((struct packet *)0, &client -> packet,
2051 (struct lease *)0, client,
2052 /* maximum packet size */1500,
2053 (struct option_state *)0,
2054 client -> sent_options,
2055 /* scope */ &global_scope,
2059 (struct data_string *)0,
2060 client -> config -> vendor_space_name);
2062 option_state_dereference (&client -> sent_options, MDL);
2063 if (client -> packet_length < BOOTP_MIN_LEN)
2064 client -> packet_length = BOOTP_MIN_LEN;
2066 client -> packet.op = BOOTREQUEST;
2067 client -> packet.htype = client -> interface -> hw_address.hbuf [0];
2068 client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
2069 client -> packet.hops = 0;
2070 client -> packet.xid = client -> xid;
2071 client -> packet.secs = 0; /* Filled in by send_request. */
2073 /* If we own the address we're requesting, put it in ciaddr;
2074 otherwise set ciaddr to zero. */
2075 if (client -> state == S_BOUND ||
2076 client -> state == S_RENEWING ||
2077 client -> state == S_REBINDING) {
2078 memcpy (&client -> packet.ciaddr,
2079 lease -> address.iabuf, lease -> address.len);
2080 client -> packet.flags = 0;
2082 memset (&client -> packet.ciaddr, 0,
2083 sizeof client -> packet.ciaddr);
2084 if (can_receive_unicast_unconfigured (client -> interface))
2085 client -> packet.flags = 0;
2087 client -> packet.flags = htons (BOOTP_BROADCAST);
2090 memset (&client -> packet.yiaddr, 0,
2091 sizeof client -> packet.yiaddr);
2092 memset (&client -> packet.siaddr, 0,
2093 sizeof client -> packet.siaddr);
2094 if (client -> state != S_BOUND &&
2095 client -> state != S_RENEWING)
2096 client -> packet.giaddr = giaddr;
2098 memset (&client -> packet.giaddr, 0,
2099 sizeof client -> packet.giaddr);
2100 if (client -> interface -> hw_address.hlen > 0)
2101 memcpy (client -> packet.chaddr,
2102 &client -> interface -> hw_address.hbuf [1],
2103 (unsigned)(client -> interface -> hw_address.hlen - 1));
2106 dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
2110 void make_decline (client, lease)
2111 struct client_state *client;
2112 struct client_lease *lease;
2114 unsigned char decline = DHCPDECLINE;
2116 struct option_cache *oc;
2118 struct option_state *options = (struct option_state *)0;
2120 oc = lookup_option (&dhcp_universe, lease -> options,
2121 DHO_DHCP_SERVER_IDENTIFIER);
2122 make_client_options (client, lease, &decline, oc,
2123 &lease -> address, (u_int32_t *)0, &options);
2125 /* Set up the option buffer... */
2126 memset (&client -> packet, 0, sizeof (client -> packet));
2127 client -> packet_length =
2128 cons_options ((struct packet *)0, &client -> packet,
2129 (struct lease *)0, client, 0,
2130 (struct option_state *)0, options,
2131 &global_scope, 0, 0, 0, (struct data_string *)0,
2132 client -> config -> vendor_space_name);
2133 option_state_dereference (&options, MDL);
2134 if (client -> packet_length < BOOTP_MIN_LEN)
2135 client -> packet_length = BOOTP_MIN_LEN;
2136 option_state_dereference (&options, MDL);
2138 client -> packet.op = BOOTREQUEST;
2139 client -> packet.htype = client -> interface -> hw_address.hbuf [0];
2140 client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
2141 client -> packet.hops = 0;
2142 client -> packet.xid = client -> xid;
2143 client -> packet.secs = 0; /* Filled in by send_request. */
2144 if (can_receive_unicast_unconfigured (client -> interface))
2145 client -> packet.flags = 0;
2147 client -> packet.flags = htons (BOOTP_BROADCAST);
2149 /* ciaddr must always be zero. */
2150 memset (&client -> packet.ciaddr, 0,
2151 sizeof client -> packet.ciaddr);
2152 memset (&client -> packet.yiaddr, 0,
2153 sizeof client -> packet.yiaddr);
2154 memset (&client -> packet.siaddr, 0,
2155 sizeof client -> packet.siaddr);
2156 client -> packet.giaddr = giaddr;
2157 memcpy (client -> packet.chaddr,
2158 &client -> interface -> hw_address.hbuf [1],
2159 client -> interface -> hw_address.hlen);
2162 dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
2166 void make_release (client, lease)
2167 struct client_state *client;
2168 struct client_lease *lease;
2170 unsigned char request = DHCPRELEASE;
2172 struct option_cache *oc;
2174 struct option_state *options = (struct option_state *)0;
2176 memset (&client -> packet, 0, sizeof (client -> packet));
2178 oc = lookup_option (&dhcp_universe, lease -> options,
2179 DHO_DHCP_SERVER_IDENTIFIER);
2180 make_client_options (client, lease, &request, oc,
2181 (struct iaddr *)0, (u_int32_t *)0,
2184 /* Set up the option buffer... */
2185 client -> packet_length =
2186 cons_options ((struct packet *)0, &client -> packet,
2187 (struct lease *)0, client,
2188 /* maximum packet size */1500,
2189 (struct option_state *)0,
2191 /* scope */ &global_scope,
2195 (struct data_string *)0,
2196 client -> config -> vendor_space_name);
2198 if (client -> packet_length < BOOTP_MIN_LEN)
2199 client -> packet_length = BOOTP_MIN_LEN;
2200 option_state_dereference (&options, MDL);
2202 client -> packet.op = BOOTREQUEST;
2203 client -> packet.htype = client -> interface -> hw_address.hbuf [0];
2204 client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
2205 client -> packet.hops = 0;
2206 client -> packet.xid = random ();
2207 client -> packet.secs = 0;
2208 client -> packet.flags = 0;
2209 memcpy (&client -> packet.ciaddr,
2210 lease -> address.iabuf, lease -> address.len);
2211 memset (&client -> packet.yiaddr, 0,
2212 sizeof client -> packet.yiaddr);
2213 memset (&client -> packet.siaddr, 0,
2214 sizeof client -> packet.siaddr);
2215 client -> packet.giaddr = giaddr;
2216 memcpy (client -> packet.chaddr,
2217 &client -> interface -> hw_address.hbuf [1],
2218 client -> interface -> hw_address.hlen);
2221 dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
2225 void destroy_client_lease (lease)
2226 struct client_lease *lease;
2230 if (lease -> server_name)
2231 dfree (lease -> server_name, MDL);
2232 if (lease -> filename)
2233 dfree (lease -> filename, MDL);
2234 option_state_dereference (&lease -> options, MDL);
2235 free_client_lease (lease, MDL);
2240 void rewrite_client_leases ()
2242 struct interface_info *ip;
2243 struct client_state *client;
2244 struct client_lease *lp;
2248 leaseFile = fopen (path_dhclient_db, "w");
2250 log_error ("can't create %s: %m", path_dhclient_db);
2254 /* Write out all the leases attached to configured interfaces that
2256 for (ip = interfaces; ip; ip = ip -> next) {
2257 for (client = ip -> client; client; client = client -> next) {
2258 for (lp = client -> leases; lp; lp = lp -> next) {
2259 write_client_lease (client, lp, 1, 0);
2261 if (client -> active)
2262 write_client_lease (client,
2263 client -> active, 1, 0);
2267 /* Write out any leases that are attached to interfaces that aren't
2268 currently configured. */
2269 for (ip = dummy_interfaces; ip; ip = ip -> next) {
2270 for (client = ip -> client; client; client = client -> next) {
2271 for (lp = client -> leases; lp; lp = lp -> next) {
2272 write_client_lease (client, lp, 1, 0);
2274 if (client -> active)
2275 write_client_lease (client,
2276 client -> active, 1, 0);
2282 void write_lease_option (struct option_cache *oc,
2283 struct packet *packet, struct lease *lease,
2284 struct client_state *client_state,
2285 struct option_state *in_options,
2286 struct option_state *cfg_options,
2287 struct binding_scope **scope,
2288 struct universe *u, void *stuff)
2290 const char *name, *dot;
2291 struct data_string ds;
2293 struct client_state *client;
2295 memset (&ds, 0, sizeof ds);
2297 if (u != &dhcp_universe) {
2304 if (evaluate_option_cache (&ds, packet, lease, client_state,
2305 in_options, cfg_options, scope, oc, MDL)) {
2307 " option %s%s%s %s;\n",
2308 name, dot, oc -> option -> name,
2309 pretty_print_option (oc -> option,
2310 ds.data, ds.len, 1, 1));
2311 data_string_forget (&ds, MDL);
2315 int write_client_lease (client, lease, rewrite, makesure)
2316 struct client_state *client;
2317 struct client_lease *lease;
2323 static int leases_written;
2324 struct option_cache *oc;
2325 struct data_string ds;
2331 if (leases_written++ > 20) {
2332 rewrite_client_leases ();
2337 /* If the lease came from the config file, we don't need to stash
2338 a copy in the lease database. */
2339 if (lease -> is_static)
2342 if (!leaseFile) { /* XXX */
2343 leaseFile = fopen (path_dhclient_db, "w");
2345 log_error ("can't create %s: %m", path_dhclient_db);
2351 fprintf (leaseFile, "lease {\n");
2352 if (lease -> is_bootp) {
2353 fprintf (leaseFile, " bootp;\n");
2359 fprintf (leaseFile, " interface \"%s\";\n",
2360 client -> interface -> name);
2365 if (client -> name) {
2366 fprintf (leaseFile, " name \"%s\";\n", client -> name);
2372 fprintf (leaseFile, " fixed-address %s;\n",
2373 piaddr (lease -> address));
2378 if (lease -> filename) {
2379 s = quotify_string (lease -> filename, MDL);
2381 fprintf (leaseFile, " filename \"%s\";\n", s);
2391 if (lease -> server_name) {
2392 s = quotify_string (lease -> filename, MDL);
2394 fprintf (leaseFile, " server-name \"%s\";\n", s);
2403 if (lease -> medium) {
2404 s = quotify_string (lease -> medium -> string, MDL);
2406 fprintf (leaseFile, " medium \"%s\";\n", s);
2420 memset (&ds, 0, sizeof ds);
2422 for (i = 0; i < lease -> options -> universe_count; i++) {
2423 option_space_foreach ((struct packet *)0, (struct lease *)0,
2424 client, (struct option_state *)0,
2425 lease -> options, &global_scope,
2427 client, write_lease_option);
2430 /* Note: the following is not a Y2K bug - it's a Y1.9K bug. Until
2431 somebody invents a time machine, I think we can safely disregard
2433 t = gmtime (&lease -> renewal);
2435 " renew %d %d/%d/%d %02d:%02d:%02d;\n",
2436 t -> tm_wday, t -> tm_year + 1900,
2437 t -> tm_mon + 1, t -> tm_mday,
2438 t -> tm_hour, t -> tm_min, t -> tm_sec);
2443 t = gmtime (&lease -> rebind);
2445 " rebind %d %d/%d/%d %02d:%02d:%02d;\n",
2446 t -> tm_wday, t -> tm_year + 1900,
2447 t -> tm_mon + 1, t -> tm_mday,
2448 t -> tm_hour, t -> tm_min, t -> tm_sec);
2453 t = gmtime (&lease -> expiry);
2455 " expire %d %d/%d/%d %02d:%02d:%02d;\n",
2456 t -> tm_wday, t -> tm_year + 1900,
2457 t -> tm_mon + 1, t -> tm_mday,
2458 t -> tm_hour, t -> tm_min, t -> tm_sec);
2463 fprintf (leaseFile, "}\n");
2473 if (!errors && makesure) {
2474 if (fsync (fileno (leaseFile)) < 0) {
2475 log_info ("write_client_lease: %m");
2479 return errors ? 0 : 1;
2482 /* Variables holding name of script and file pointer for writing to
2483 script. Needless to say, this is not reentrant - only one script
2484 can be invoked at a time. */
2485 char scriptName [256];
2488 void script_init (client, reason, medium)
2489 struct client_state *client;
2491 struct string_list *medium;
2493 struct string_list *sl, *next;
2496 for (sl = client -> env; sl; sl = next) {
2500 client -> env = (struct string_list *)0;
2503 if (client -> interface) {
2504 client_envadd (client, "", "interface", "%s",
2505 client -> interface -> name);
2508 client_envadd (client,
2509 "", "client", "%s", client -> name);
2511 client_envadd (client,
2512 "", "medium", "%s", medium -> string);
2514 client_envadd (client, "", "reason", "%s", reason);
2515 client_envadd (client, "", "pid", "%ld", (long int)getpid ());
2519 struct envadd_state {
2520 struct client_state *client;
2524 void client_option_envadd (struct option_cache *oc,
2525 struct packet *packet, struct lease *lease,
2526 struct client_state *client_state,
2527 struct option_state *in_options,
2528 struct option_state *cfg_options,
2529 struct binding_scope **scope,
2530 struct universe *u, void *stuff)
2532 struct envadd_state *es = stuff;
2533 struct data_string data;
2534 memset (&data, 0, sizeof data);
2536 if (evaluate_option_cache (&data, packet, lease, client_state,
2537 in_options, cfg_options, scope, oc, MDL)) {
2540 if (dhcp_option_ev_name (name, sizeof name,
2542 client_envadd (es -> client, es -> prefix,
2544 (pretty_print_option
2546 data.data, data.len,
2548 data_string_forget (&data, MDL);
2554 void script_write_params (client, prefix, lease)
2555 struct client_state *client;
2557 struct client_lease *lease;
2560 struct data_string data;
2561 struct option_cache *oc;
2564 struct envadd_state es;
2569 client_envadd (client,
2570 prefix, "ip_address", "%s", piaddr (lease -> address));
2572 /* For the benefit of Linux (and operating systems which may
2573 have similar needs), compute the network address based on
2574 the supplied ip address and netmask, if provided. Also
2575 compute the broadcast address (the host address all ones
2576 broadcast address, not the host address all zeroes
2577 broadcast address). */
2579 memset (&data, 0, sizeof data);
2580 oc = lookup_option (&dhcp_universe, lease -> options, DHO_SUBNET_MASK);
2581 if (oc && evaluate_option_cache (&data, (struct packet *)0,
2582 (struct lease *)0, client,
2583 (struct option_state *)0,
2585 &global_scope, oc, MDL)) {
2587 struct iaddr netmask, subnet, broadcast;
2589 memcpy (netmask.iabuf, data.data, data.len);
2590 netmask.len = data.len;
2591 data_string_forget (&data, MDL);
2593 subnet = subnet_number (lease -> address, netmask);
2595 client_envadd (client, prefix, "network_number",
2596 "%s", piaddr (subnet));
2598 oc = lookup_option (&dhcp_universe,
2600 DHO_BROADCAST_ADDRESS);
2602 !(evaluate_option_cache
2603 (&data, (struct packet *)0,
2604 (struct lease *)0, client,
2605 (struct option_state *)0,
2607 &global_scope, oc, MDL))) {
2608 broadcast = broadcast_addr (subnet, netmask);
2609 if (broadcast.len) {
2610 client_envadd (client,
2611 prefix, "broadcast_address",
2612 "%s", piaddr (broadcast));
2617 data_string_forget (&data, MDL);
2620 if (lease -> filename)
2621 client_envadd (client,
2622 prefix, "filename", "%s", lease -> filename);
2623 if (lease -> server_name)
2624 client_envadd (client, prefix, "server_name",
2625 "%s", lease -> server_name);
2627 for (i = 0; i < lease -> options -> universe_count; i++) {
2628 option_space_foreach ((struct packet *)0, (struct lease *)0,
2629 client, (struct option_state *)0,
2630 lease -> options, &global_scope,
2632 &es, client_option_envadd);
2634 client_envadd (client, prefix, "expiry", "%d", (int)(lease -> expiry));
2637 int script_go (client)
2638 struct client_state *client;
2645 char reason [] = "REASON=NBI";
2646 static char client_path [] = CLIENT_PATH;
2648 struct string_list *sp, *next;
2649 int pid, wpid, wstatus;
2652 scriptName = client -> config -> script_name;
2654 scriptName = top_level_config.script_name;
2656 envp = dmalloc (((client ? client -> envc : 2) +
2657 client_env_count + 2) * sizeof (char *), MDL);
2659 log_error ("No memory for client script environment.");
2663 /* Copy out the environment specified on the command line,
2665 for (sp = client_env; sp; sp = sp -> next) {
2666 envp [i++] = sp -> string;
2668 /* Copy out the environment specified by dhclient. */
2670 for (sp = client -> env; sp; sp = sp -> next) {
2671 envp [i++] = sp -> string;
2674 envp [i++] = reason;
2677 envp [i++] = client_path;
2678 envp [i] = (char *)0;
2680 argv [0] = scriptName;
2681 argv [1] = (char *)0;
2685 log_error ("fork: %m");
2689 wpid = wait (&wstatus);
2690 } while (wpid != pid && wpid > 0);
2692 log_error ("wait: %m");
2696 if ((i = open(_PATH_DEVNULL, O_RDWR)) != -1) {
2697 dup2(i, STDIN_FILENO);
2698 dup2(i, STDOUT_FILENO);
2699 dup2(i, STDERR_FILENO);
2700 if (i > STDERR_FILENO)
2703 execve (scriptName, argv, envp);
2704 log_error ("execve (%s, ...): %m", scriptName);
2709 for (sp = client -> env; sp; sp = next) {
2713 client -> env = (struct string_list *)0;
2717 GET_TIME (&cur_time);
2718 return (WIFEXITED (wstatus) ?
2719 WEXITSTATUS (wstatus) : -WTERMSIG (wstatus));
2722 void client_envadd (struct client_state *client,
2723 const char *prefix, const char *name, const char *fmt, ...)
2728 struct string_list *val;
2731 va_start (list, fmt);
2732 len = vsnprintf (spbuf, sizeof spbuf, fmt, list);
2735 val = dmalloc (strlen (prefix) + strlen (name) + 1 /* = */ +
2736 len + sizeof *val, MDL);
2744 if (len >= sizeof spbuf) {
2745 va_start (list, fmt);
2746 vsnprintf (s, len + 1, fmt, list);
2750 val -> next = client -> env;
2751 client -> env = val;
2755 int dhcp_option_ev_name (buf, buflen, option)
2758 struct option *option;
2764 if (option -> universe != &dhcp_universe) {
2765 s = option -> universe -> name;
2774 if (j + 1 == buflen)
2784 if (j + 1 == buflen)
2797 static int state = 0;
2801 /* Don't become a daemon if the user requested otherwise. */
2803 write_client_pid_file ();
2807 /* Only do it once. */
2812 /* Stop logging to stderr... */
2815 /* Become a daemon... */
2816 if ((pid = fork ()) < 0)
2817 log_fatal ("Can't fork daemon: %m");
2820 /* Become session leader and get pid... */
2823 /* Close standard I/O descriptors. */
2828 /* Reopen them on /dev/null. */
2829 i = open ("/dev/null", O_RDWR);
2831 i = open ("/dev/null", O_RDWR);
2833 i = open ("/dev/null", O_RDWR);
2834 log_perror = 0; /* No sense logging to /dev/null. */
2838 write_client_pid_file ();
2841 void write_client_pid_file ()
2846 pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY, 0644);
2849 log_error ("Can't create %s: %m", path_dhclient_pid);
2853 pf = fdopen (pfdesc, "w");
2855 log_error ("Can't fdopen %s: %m", path_dhclient_pid);
2857 fprintf (pf, "%ld\n", (long)getpid ());
2862 void client_location_changed ()
2864 struct interface_info *ip;
2865 struct client_state *client;
2867 for (ip = interfaces; ip; ip = ip -> next) {
2868 for (client = ip -> client; client; client = client -> next) {
2869 switch (client -> state) {
2871 cancel_timeout (send_discover, client);
2875 cancel_timeout (state_bound, client);
2881 cancel_timeout (send_request, client);
2889 #ifndef ENABLE_POLLING_MODE
2890 client -> state = S_INIT;
2891 state_reboot (client);
2897 void do_release(client)
2898 struct client_state *client;
2900 struct data_string ds;
2901 struct option_cache *oc;
2903 /* Pick a random xid. */
2904 client -> xid = random ();
2906 /* is there even a lease to release? */
2907 if (client -> active) {
2908 /* Make a DHCPRELEASE packet, and set appropriate per-interface
2910 make_release (client, client -> active);
2912 memset (&ds, 0, sizeof ds);
2913 oc = lookup_option (&dhcp_universe,
2914 client -> active -> options,
2915 DHO_DHCP_SERVER_IDENTIFIER);
2917 evaluate_option_cache (&ds, (struct packet *)0,
2918 (struct lease *)0, client,
2919 (struct option_state *)0,
2920 client -> active -> options,
2921 &global_scope, oc, MDL)) {
2923 memcpy (client -> destination.iabuf,
2925 client -> destination.len = 4;
2927 client -> destination = iaddr_broadcast;
2929 client -> destination = iaddr_broadcast;
2930 client -> first_sending = cur_time;
2931 client -> interval = client -> config -> initial_interval;
2933 /* Zap the medium list... */
2934 client -> medium = (struct string_list *)0;
2936 /* Send out the first and only DHCPRELEASE packet. */
2937 send_release (client);
2939 /* Do the client script RELEASE operation. */
2940 script_init (client,
2941 "RELEASE", (struct string_list *)0);
2942 if (client -> alias)
2943 script_write_params (client, "alias_",
2945 script_write_params (client, "old_", client -> active);
2949 /* Cancel any timeouts. */
2950 cancel_timeout (state_bound, client);
2951 cancel_timeout (send_discover, client);
2952 cancel_timeout (state_init, client);
2953 cancel_timeout (send_request, client);
2954 cancel_timeout (state_reboot, client);
2955 client -> state = S_STOPPED;
2958 int dhclient_interface_shutdown_hook (struct interface_info *interface)
2960 do_release (interface -> client);
2965 int dhclient_interface_discovery_hook (struct interface_info *tmp)
2967 struct interface_info *last, *ip;
2968 /* See if we can find the client from dummy_interfaces */
2970 for (ip = dummy_interfaces; ip; ip = ip -> next) {
2971 if (!strcmp (ip -> name, tmp -> name)) {
2972 /* Remove from dummy_interfaces */
2974 ip = (struct interface_info *)0;
2975 interface_reference (&ip, last -> next, MDL);
2976 interface_dereference (&last -> next, MDL);
2978 interface_reference (&last -> next,
2980 interface_dereference (&ip -> next,
2984 ip = (struct interface_info *)0;
2985 interface_reference (&ip,
2986 dummy_interfaces, MDL);
2987 interface_dereference (&dummy_interfaces, MDL);
2989 interface_reference (&dummy_interfaces,
2991 interface_dereference (&ip -> next,
2995 /* Copy "client" to tmp */
2997 tmp -> client = ip -> client;
2998 tmp -> client -> interface = tmp;
3000 interface_dereference (&ip, MDL);
3008 isc_result_t dhclient_interface_startup_hook (struct interface_info *interface)
3010 struct interface_info *ip;
3011 struct client_state *client;
3013 /* This code needs some rethinking. It doesn't test against
3014 a signal name, and it just kind of bulls into doing something
3015 that may or may not be appropriate. */
3018 interface_reference (&interface -> next, interfaces, MDL);
3019 interface_dereference (&interfaces, MDL);
3021 interface_reference (&interfaces, interface, MDL);
3023 discover_interfaces (DISCOVER_UNCONFIGURED);
3025 for (ip = interfaces; ip; ip = ip -> next) {
3026 /* If interfaces were specified, don't configure
3027 interfaces that weren't specified! */
3028 if (ip -> flags & INTERFACE_RUNNING ||
3029 (ip -> flags & (INTERFACE_REQUESTED |
3030 INTERFACE_AUTOMATIC)) !=
3031 INTERFACE_REQUESTED)
3033 script_init (ip -> client,
3034 "PREINIT", (struct string_list *)0);
3035 if (ip -> client -> alias)
3036 script_write_params (ip -> client, "alias_",
3037 ip -> client -> alias);
3038 script_go (ip -> client);
3041 discover_interfaces (interfaces_requested
3042 ? DISCOVER_REQUESTED
3043 : DISCOVER_RUNNING);
3045 for (ip = interfaces; ip; ip = ip -> next) {
3046 if (ip -> flags & INTERFACE_RUNNING)
3048 ip -> flags |= INTERFACE_RUNNING;
3049 for (client = ip -> client; client; client = client -> next) {
3050 client -> state = S_INIT;
3051 /* Set up a timeout to start the initialization
3053 add_timeout (cur_time + random () % 5,
3054 state_reboot, client, 0, 0);
3057 return ISC_R_SUCCESS;
3060 /* The client should never receive a relay agent information option,
3061 so if it does, log it and discard it. */
3063 int parse_agent_information_option (packet, len, data)
3064 struct packet *packet;
3071 /* The client never sends relay agent information options. */
3073 unsigned cons_agent_information_options (cfg_options, outpacket,
3075 struct option_state *cfg_options;
3076 struct dhcp_packet *outpacket;
3083 static void shutdown_exit (void *foo)
3088 isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
3089 control_object_state_t newstate)
3091 struct interface_info *ip;
3092 struct client_state *client;
3094 /* Do the right thing for each interface. */
3095 for (ip = interfaces; ip; ip = ip -> next) {
3096 for (client = ip -> client; client; client = client -> next) {
3098 case server_startup:
3099 return ISC_R_SUCCESS;
3101 case server_running:
3102 return ISC_R_SUCCESS;
3104 case server_shutdown:
3105 if (client -> active &&
3106 client -> active -> expiry > cur_time) {
3107 if (client -> config -> do_forward_update)
3108 client_dns_update (client, 0, 0);
3109 do_release (client);
3113 case server_hibernate:
3114 state_stop (client);
3118 #ifndef ENABLE_POLLING_MODE
3119 state_reboot (client);
3125 if (newstate == server_shutdown)
3126 add_timeout (cur_time + 1, shutdown_exit, 0, 0, 0);
3127 return ISC_R_SUCCESS;
3130 /* Called after a timeout if the DNS update failed on the previous try.
3131 Retries the update, and if it times out, schedules a retry after
3132 ten times as long of a wait. */
3134 void client_dns_update_timeout (void *cp)
3136 struct client_state *client = cp;
3137 isc_result_t status;
3139 if (client -> active) {
3140 status = client_dns_update (client, 1,
3141 (client -> active -> renewal -
3143 if (status == ISC_R_TIMEDOUT) {
3144 client -> dns_update_timeout *= 10;
3145 add_timeout (cur_time + client -> dns_update_timeout,
3146 client_dns_update_timeout, client, 0, 0);
3151 /* See if we should do a DNS update, and if so, do it. */
3153 isc_result_t client_dns_update (struct client_state *client, int addp, int ttl)
3155 struct data_string ddns_fqdn, ddns_fwd_name,
3156 ddns_dhcid, client_identifier;
3157 struct option_cache *oc;
3162 /* If we didn't send an FQDN option, we certainly aren't going to
3163 be doing an update. */
3164 if (!client -> sent_options)
3165 return ISC_R_SUCCESS;
3167 /* If we don't have a lease, we can't do an update. */
3168 if (!client -> active)
3169 return ISC_R_SUCCESS;
3171 /* If we set the no client update flag, don't do the update. */
3172 if ((oc = lookup_option (&fqdn_universe, client -> sent_options,
3173 FQDN_NO_CLIENT_UPDATE)) &&
3174 evaluate_boolean_option_cache (&ignorep, (struct packet *)0,
3175 (struct lease *)0, client,
3176 client -> sent_options,
3177 (struct option_state *)0,
3178 &global_scope, oc, MDL))
3179 return ISC_R_SUCCESS;
3181 /* If we set the "server, please update" flag, or didn't set it
3182 to false, don't do the update. */
3183 if (!(oc = lookup_option (&fqdn_universe, client -> sent_options,
3184 FQDN_SERVER_UPDATE)) ||
3185 evaluate_boolean_option_cache (&ignorep, (struct packet *)0,
3186 (struct lease *)0, client,
3187 client -> sent_options,
3188 (struct option_state *)0,
3189 &global_scope, oc, MDL))
3190 return ISC_R_SUCCESS;
3192 /* If no FQDN option was supplied, don't do the update. */
3193 memset (&ddns_fwd_name, 0, sizeof ddns_fwd_name);
3194 if (!(oc = lookup_option (&fqdn_universe, client -> sent_options,
3196 !evaluate_option_cache (&ddns_fwd_name, (struct packet *)0,
3197 (struct lease *)0, client,
3198 client -> sent_options,
3199 (struct option_state *)0,
3200 &global_scope, oc, MDL))
3201 return ISC_R_SUCCESS;
3203 /* Make a dhcid string out of either the client identifier,
3204 if we are sending one, or the interface's MAC address,
3206 memset (&ddns_dhcid, 0, sizeof ddns_dhcid);
3208 memset (&client_identifier, 0, sizeof client_identifier);
3209 if ((oc = lookup_option (&dhcp_universe, client -> sent_options,
3210 DHO_DHCP_CLIENT_IDENTIFIER)) &&
3211 evaluate_option_cache (&client_identifier, (struct packet *)0,
3212 (struct lease *)0, client,
3213 client -> sent_options,
3214 (struct option_state *)0,
3215 &global_scope, oc, MDL)) {
3216 result = get_dhcid (&ddns_dhcid,
3217 DHO_DHCP_CLIENT_IDENTIFIER,
3218 client_identifier.data,
3219 client_identifier.len);
3220 data_string_forget (&client_identifier, MDL);
3222 result = get_dhcid (&ddns_dhcid, 0,
3223 client -> interface -> hw_address.hbuf,
3224 client -> interface -> hw_address.hlen);
3226 data_string_forget (&ddns_fwd_name, MDL);
3227 return ISC_R_SUCCESS;
3230 /* Start the resolver, if necessary. */
3231 if (!resolver_inited) {
3232 minires_ninit (&resolver_state);
3233 resolver_inited = 1;
3234 resolver_state.retrans = 1;
3235 resolver_state.retry = 1;
3241 if (ddns_fwd_name.len && ddns_dhcid.len) {
3243 rcode = ddns_update_a (&ddns_fwd_name,
3244 client -> active -> address,
3248 rcode = ddns_remove_a (&ddns_fwd_name,
3249 client -> active -> address,
3253 data_string_forget (&ddns_fwd_name, MDL);
3254 data_string_forget (&ddns_dhcid, MDL);
3258 /* Check to see if there's a wire plugged in */
3260 interface_active(struct interface_info *ip) {
3262 struct ifmediareq ifmr;
3267 ifname = ip -> name;
3269 if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
3270 log_fatal ("Can't create interface_active socket");
3272 (void) memset (&ifmr, 0, sizeof (ifmr));
3273 (void) strncpy (ifmr.ifm_name, ifname, sizeof (ifmr.ifm_name));
3275 if (ioctl (sock, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
3277 * Interface doesn't support SIOCGIFMEDIA, presume okay
3284 if (ifmr.ifm_count == 0) {
3286 * Assume that this means interface
3287 * does not support SIOCGIFMEDIA
3289 log_fatal ("%s: no media types?", ifname);
3293 if (ifmr.ifm_status & IFM_AVALID) {
3294 if (ip -> ieee80211) {
3296 * Wavelan devices need to be checked if they are
3299 if ((IFM_TYPE(ifmr.ifm_active) == IFM_IEEE80211) &&
3300 (ifmr.ifm_status & IFM_ACTIVE)) {
3304 if (ifmr.ifm_status & IFM_ACTIVE) {
3309 * We really have no link.
3314 * IFM_AVALID is not set. We cannot check
3315 * the link state. Assume HAVELINK.
3318 #endif /* Other OSs */
3320 * Always return a successful link if the OS
3327 #if defined(DRAGONFLY_FUTURE)
3329 set_ieee80211 (struct interface_info *ip) {
3331 struct ieee80211req ireq;
3338 ifname = ip -> name;
3340 if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
3341 log_fatal ("Can't create interface_active socket");
3343 (void) memset (&ireq, 0, sizeof (ireq));
3344 (void) strncpy (ireq.i_name, ifname, sizeof (ireq.i_name));
3345 ireq.i_data = &data;
3346 ireq.i_type = IEEE80211_IOC_SSID;
3349 * If we can't get the SSID,
3350 * this isn't an 802.11 device.
3352 if (ioctl (sock, SIOCG80211, &ireq) < 0)
3353 ip -> ieee80211 = 0;
3356 printf ("Device %s has 802.11\n", ifname);
3358 ip -> ieee80211 = 1;
3362 #endif /* __FreeBSD__ */
3365 #ifdef ENABLE_POLLING_MODE
3366 /* Go to background after some time */
3367 void state_background (cpp)
3373 /* Check the state of the NICs if we have link */
3374 void state_polling (cpp)
3377 struct interface_info *ip;
3378 struct client_state *client;
3381 for (ip = interfaces; ip; ip = ip -> next) {
3382 if (! ip -> polling)
3385 printf ("%s: Polling interface state\n", ip -> name);
3386 for (client = ip -> client;
3387 client; client = client -> next) {
3388 printf ("%s: client state of %d\n", ip -> name, ip -> client -> state);
3389 printf ("%s: link = %d\n", ip -> name, ip -> linkstate);
3393 result = interface_active (ip);
3395 * If dhclient.conf contains media settings, we cannot
3396 * abort if the interface is not set to active mode.
3398 if (ip -> havemedia && ip -> client -> state != S_BOUND) {
3399 if (result == HAVELINK)
3400 ip -> forcediscover = 1;
3405 * The last status of the interface tells us
3406 * the we've got no link ...
3408 if (ip -> linkstate == NOLINK || ! doinitcheck) {
3410 * ... but we have now link. Let's send
3413 if (result == HAVELINK) {
3415 if (ip -> havemedia)
3416 printf ("%s: Trying media settings on interface\n",
3419 printf ("%s: Found Link on interface\n", ip -> name);
3422 * Set the interface to state_reboot. But of
3423 * course we can not be sure that we really got link,
3424 * we just assume it.
3426 for (client = ip -> client;
3427 client; client = client -> next) {
3428 cancel_timeout (state_init, client);
3429 cancel_timeout (state_reboot, client);
3430 cancel_timeout (state_selecting, client);
3431 add_timeout (cur_time + random () % 5,
3432 state_reboot, client, 0, 0);
3434 ip -> linkstate = HAVELINK;
3437 printf ("%s: No link on interface\n", ip -> name);
3439 for (client = ip -> client;
3440 client; client = client -> next) {
3442 * Without this add_timout(), dhclient does
3443 * not poll on a interface if there
3444 * is no cable plugged in at startup
3445 * time. Because we add one additional second
3446 * to the time of a normal timeout, we always
3447 * skip and block a running one. This prevents
3448 * that polling is done twice at the same time.
3450 if (client -> state == S_INIT) {
3451 add_timeout (cur_time + (polling_interval + 1),
3452 state_polling, client, 0, 0);
3455 ip -> linkstate = NOLINK;
3457 * Automatically go into the background after
3458 * some time. Do this only if there are no
3459 * media options available for a interface.
3461 if (! ip -> havemedia && ! doinitcheck) {
3462 add_timeout (cur_time + (polling_interval * 2),
3463 state_background, client, 0, 0);
3469 * The last status of the interface tells us
3470 * the we previously had link.
3472 if (ip -> linkstate == HAVELINK && doinitcheck) {
3473 if (result == NOLINK) {
3475 * We lost link on the interface, or it isn't
3476 * associated anymore.
3479 printf ("%s: Lost Link on interface\n", ip -> name);
3482 * After we lost link, cycle again through the
3483 * different media settings if available. Else
3486 if (ip -> havemedia)
3487 ip -> forcediscover = 1;
3489 ip -> linkstate = NOLINK;
3492 * If we happen to have a real link, but no
3493 * active lease, force the interface into
3494 * state_reboot. Do the same if media settings
3497 if (ip -> forcediscover) {
3498 for (client = ip -> client;
3499 client; client = client -> next) {
3500 if (client -> state != S_REBOOTING &&
3501 client -> state != S_SELECTING) {
3502 add_timeout (cur_time + random () % 5,
3503 state_reboot, client, 0, 0);
3506 ip -> forcediscover = 0;
3507 ip -> linkstate = HAVELINK;
3509 /* We still have link, do nothing. */
3514 #endif /* ifdef ENABLE_POLLING_MODE */