6 * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 1995-2003 by Internet Software Consortium
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 * Internet Systems Consortium, Inc.
23 * Redwood City, CA 94063
27 * This code is based on the original client state machine that was
28 * written by Elliot Poger. The code has been extensively hacked on
29 * by Ted Lemon since then, so any mistakes you find are probably his
30 * fault and not Elliot's.
34 static char ocopyright
[] =
35 "$Id: dhclient.c,v 1.133 2006/02/24 23:16:27 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
41 TIME default_lease_time
= 43200; /* 12 hours... */
42 TIME max_lease_time
= 86400; /* 24 hours... */
44 const char *path_dhclient_conf
= _PATH_DHCLIENT_CONF
;
45 const char *path_dhclient_db
= _PATH_DHCLIENT_DB
;
46 const char *path_dhclient_pid
= _PATH_DHCLIENT_PID
;
47 static char path_dhclient_script_array
[] = _PATH_DHCLIENT_SCRIPT
;
48 char *path_dhclient_script
= path_dhclient_script_array
;
50 int dhcp_max_agent_option_packet_length
= 0;
52 int interfaces_requested
= 0;
54 struct iaddr iaddr_broadcast
= { 4, { 255, 255, 255, 255 } };
55 struct iaddr iaddr_any
= { 4, { 0, 0, 0, 0 } };
56 struct in_addr inaddr_any
;
57 struct sockaddr_in sockaddr_broadcast
;
58 struct in_addr giaddr
;
60 /* ASSERT_STATE() does nothing now; it used to be
61 assert (state_is == state_shouldbe). */
62 #define ASSERT_STATE(state_is, state_shouldbe) {}
64 static char copyright
[] = "Copyright 2004-2005 Internet Systems Consortium.";
65 static char arr
[] = "All rights reserved.";
66 static char message
[] = "Internet Systems Consortium DHCP Client";
67 static char url
[] = "For info, please visit http://www.isc.org/products/DHCP";
69 u_int16_t local_port
=0;
70 u_int16_t remote_port
=0;
72 struct string_list
*client_env
=NULL
;
73 int client_env_count
=0;
78 static void usage
PROTO ((void));
80 void do_release(struct client_state
*);
82 int main (argc
, argv
, envp
)
88 struct interface_info
*ip
;
89 struct client_state
*client
;
91 char *server
= (char *)0;
92 char *relay
= (char *)0;
95 omapi_object_t
*listener
;
99 int no_dhclient_conf
= 0;
100 int no_dhclient_db
= 0;
101 int no_dhclient_pid
= 0;
102 int no_dhclient_script
= 0;
105 /* Make sure we have stdin, stdout and stderr. */
106 i
= open ("/dev/null", O_RDWR
);
108 i
= open ("/dev/null", O_RDWR
);
110 i
= open ("/dev/null", O_RDWR
);
111 log_perror
= 0; /* No sense logging to /dev/null. */
116 openlog ("dhclient", LOG_NDELAY
);
117 log_priority
= LOG_DAEMON
;
119 openlog ("dhclient", LOG_NDELAY
, LOG_DAEMON
);
122 #if !(defined (DEBUG) || defined (SYSLOG_4_2) || defined (__CYGWIN32__))
123 setlogmask (LOG_UPTO (LOG_INFO
));
126 /* Set up the OMAPI. */
127 status
= omapi_init ();
128 if (status
!= ISC_R_SUCCESS
)
129 log_fatal ("Can't initialize OMAPI: %s",
130 isc_result_totext (status
));
132 /* Set up the OMAPI wrappers for various server database internal
134 dhcp_common_objects_setup ();
136 dhcp_interface_discovery_hook
= dhclient_interface_discovery_hook
;
137 dhcp_interface_shutdown_hook
= dhclient_interface_shutdown_hook
;
138 dhcp_interface_startup_hook
= dhclient_interface_startup_hook
;
140 for (i
= 1; i
< argc
; i
++) {
141 if (!strcmp (argv
[i
], "-r")) {
144 } else if (!strcmp (argv
[i
], "-p")) {
147 local_port
= htons (atoi (argv
[i
]));
148 log_debug ("binding to user-specified port %d",
150 } else if (!strcmp (argv
[i
], "-d")) {
152 } else if (!strcmp (argv
[i
], "-pf")) {
155 path_dhclient_pid
= argv
[i
];
157 } else if (!strcmp (argv
[i
], "-cf")) {
160 path_dhclient_conf
= argv
[i
];
161 no_dhclient_conf
= 1;
162 } else if (!strcmp (argv
[i
], "-lf")) {
165 path_dhclient_db
= argv
[i
];
167 } else if (!strcmp (argv
[i
], "-sf")) {
170 path_dhclient_script
= argv
[i
];
171 no_dhclient_script
= 1;
172 } else if (!strcmp (argv
[i
], "-1")) {
174 } else if (!strcmp (argv
[i
], "-q")) {
176 quiet_interface_discovery
= 1;
177 } else if (!strcmp (argv
[i
], "-s")) {
181 } else if (!strcmp (argv
[i
], "-g")) {
185 } else if (!strcmp (argv
[i
], "-nw")) {
187 } else if (!strcmp (argv
[i
], "-n")) {
188 /* do not start up any interfaces */
189 interfaces_requested
= 1;
190 } else if (!strcmp (argv
[i
], "-w")) {
191 /* do not exit if there are no broadcast interfaces. */
193 } else if (!strcmp (argv
[i
], "-e")) {
194 struct string_list
*tmp
;
197 tmp
= dmalloc (strlen (argv
[i
]) + sizeof *tmp
, MDL
);
199 log_fatal ("No memory for %s", argv
[i
]);
200 strcpy (tmp
-> string
, argv
[i
]);
201 tmp
-> next
= client_env
;
204 } else if (!strcmp (argv
[i
], "--version")) {
205 log_info ("isc-dhclient-%s", DHCP_VERSION
);
207 } else if (argv
[i
][0] == '-') {
210 struct interface_info
*tmp
= (struct interface_info
*)0;
211 status
= interface_allocate (&tmp
, MDL
);
212 if (status
!= ISC_R_SUCCESS
)
213 log_fatal ("Can't record interface %s:%s",
214 argv
[i
], isc_result_totext (status
));
215 if (strlen(argv
[i
]) >= sizeof(tmp
->name
))
216 log_fatal("%s: interface name too long (is %ld)",
217 argv
[i
], (long)strlen(argv
[i
]));
218 strcpy(tmp
->name
, argv
[i
]);
220 interface_reference (&tmp
-> next
,
222 interface_dereference (&interfaces
, MDL
);
224 interface_reference (&interfaces
, tmp
, MDL
);
225 tmp
-> flags
= INTERFACE_REQUESTED
;
226 interfaces_requested
= 1;
230 if (!no_dhclient_conf
&& (s
= getenv ("PATH_DHCLIENT_CONF"))) {
231 path_dhclient_conf
= s
;
233 if (!no_dhclient_db
&& (s
= getenv ("PATH_DHCLIENT_DB"))) {
234 path_dhclient_db
= s
;
236 if (!no_dhclient_pid
&& (s
= getenv ("PATH_DHCLIENT_PID"))) {
237 path_dhclient_pid
= s
;
239 if (!no_dhclient_script
&& (s
= getenv ("PATH_DHCLIENT_SCRIPT"))) {
240 path_dhclient_script
= s
;
243 /* first kill of any currently running client */
251 if ((pidfd
= fopen(path_dhclient_pid
, "r")) != NULL
) {
252 e
= fscanf(pidfd
, "%ld\n", &temp
);
253 oldpid
= (pid_t
)temp
;
255 if (e
!= 0 && e
!= EOF
) {
257 if (kill(oldpid
, SIGTERM
) == 0)
258 unlink(path_dhclient_pid
);
266 log_info ("%s %s", message
, DHCP_VERSION
);
267 log_info (copyright
);
274 /* If we're given a relay agent address to insert, for testing
275 purposes, figure out what it is. */
277 if (!inet_aton (relay
, &giaddr
)) {
279 he
= gethostbyname (relay
);
281 memcpy (&giaddr
, he
-> h_addr_list
[0],
284 log_fatal ("%s: no such host", relay
);
289 /* Default to the DHCP/BOOTP port. */
291 /* If we're faking a relay agent, and we're not using loopback,
292 use the server port, not the client port. */
293 if (relay
&& giaddr
.s_addr
!= htonl (INADDR_LOOPBACK
)) {
294 local_port
= htons(67);
296 ent
= getservbyname ("dhcpc", "udp");
298 local_port
= htons (68);
300 local_port
= ent
-> s_port
;
307 /* If we're faking a relay agent, and we're not using loopback,
308 we're using the server port, not the client port. */
309 if (relay
&& giaddr
.s_addr
!= htonl (INADDR_LOOPBACK
)) {
310 remote_port
= local_port
;
312 remote_port
= htons (ntohs (local_port
) - 1); /* XXX */
314 /* Get the current time... */
315 GET_TIME (&cur_time
);
317 sockaddr_broadcast
.sin_family
= AF_INET
;
318 sockaddr_broadcast
.sin_port
= remote_port
;
320 if (!inet_aton (server
, &sockaddr_broadcast
.sin_addr
)) {
322 he
= gethostbyname (server
);
324 memcpy (&sockaddr_broadcast
.sin_addr
,
325 he
-> h_addr_list
[0],
326 sizeof sockaddr_broadcast
.sin_addr
);
328 sockaddr_broadcast
.sin_addr
.s_addr
=
332 sockaddr_broadcast
.sin_addr
.s_addr
= INADDR_BROADCAST
;
335 inaddr_any
.s_addr
= INADDR_ANY
;
337 /* Discover all the network interfaces. */
338 discover_interfaces (DISCOVER_UNCONFIGURED
);
340 /* Parse the dhclient.conf file. */
343 /* Parse the lease database. */
344 read_client_leases ();
346 /* Rewrite the lease database... */
347 rewrite_client_leases ();
350 /* config_counter(&snd_counter, &rcv_counter); */
352 /* If no broadcast interfaces were discovered, call the script
355 /* Call dhclient-script with the NBI flag, in case somebody
357 script_init ((struct client_state
*)0, "NBI",
358 (struct string_list
*)0);
359 script_go ((struct client_state
*)0);
361 /* If we haven't been asked to persist, waiting for new
362 interfaces, then just exit. */
364 /* Nothing more to do. */
365 log_info ("No broadcast interfaces found - exiting.");
368 } else if (!release_mode
) {
369 /* Call the script with the list of interfaces. */
370 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
371 /* If interfaces were specified, don't configure
372 interfaces that weren't specified! */
373 if (interfaces_requested
&&
374 ((ip
-> flags
& (INTERFACE_REQUESTED
|
375 INTERFACE_AUTOMATIC
)) !=
376 INTERFACE_REQUESTED
))
378 script_init (ip
-> client
,
379 "PREINIT", (struct string_list
*)0);
380 if (ip
-> client
-> alias
)
381 script_write_params (ip
-> client
, "alias_",
382 ip
-> client
-> alias
);
383 script_go (ip
-> client
);
387 /* At this point, all the interfaces that the script thinks
388 are relevant should be running, so now we once again call
389 discover_interfaces(), and this time ask it to actually set
390 up the interfaces. */
391 discover_interfaces (interfaces_requested
395 /* Make up a seed for the random number generator from current
396 time plus the sum of the last four bytes of each
397 interface's hardware address interpreted as an integer.
398 Not much entropy, but we're booting, so we're not likely to
399 find anything better. */
401 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
404 &ip
-> hw_address
.hbuf
[ip
-> hw_address
.hlen
-
405 sizeof seed
], sizeof seed
);
408 srandom (seed
+ cur_time
);
410 /* Start a configuration state machine for each interface. */
411 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
412 ip
-> flags
|= INTERFACE_RUNNING
;
413 for (client
= ip
-> client
; client
; client
= client
-> next
) {
417 client
-> state
= S_INIT
;
418 /* Set up a timeout to start the initialization
420 add_timeout (cur_time
+ random () % 5,
421 state_reboot
, client
, 0, 0);
429 /* Start up a listener for the object management API protocol. */
430 if (top_level_config
.omapi_port
!= -1) {
431 listener
= (omapi_object_t
*)0;
432 result
= omapi_generic_new (&listener
, MDL
);
433 if (result
!= ISC_R_SUCCESS
)
434 log_fatal ("Can't allocate new generic object: %s\n",
435 isc_result_totext (result
));
436 result
= omapi_protocol_listen (listener
,
438 top_level_config
.omapi_port
,
440 if (result
!= ISC_R_SUCCESS
)
441 log_fatal ("Can't start OMAPI protocol: %s",
442 isc_result_totext (result
));
445 /* Set up the bootp packet handler... */
446 bootp_packet_handler
= do_packet
;
448 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
449 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
450 dmalloc_cutoff_generation
= dmalloc_generation
;
451 dmalloc_longterm
= dmalloc_outstanding
;
452 dmalloc_outstanding
= 0;
455 /* If we're not supposed to wait before getting the address,
460 /* If we're not going to daemonize, write the pid file
462 if (no_daemon
|| nowait
)
463 write_client_pid_file ();
465 /* Start dispatching packets and timeouts... */
474 log_info ("%s %s", message
, DHCP_VERSION
);
475 log_info (copyright
);
479 log_error ("Usage: dhclient [-1dqr] [-nw] [-p <port>] %s",
481 log_error (" [-cf config-file] [-lf lease-file]%s",
482 "[-pf pid-file] [-e VAR=val]");
483 log_fatal (" [-sf script-file] [interface]");
486 isc_result_t
find_class (struct class **c
,
487 const char *s
, const char *file
, int line
)
492 int check_collection (packet
, lease
, collection
)
493 struct packet
*packet
;
495 struct collection
*collection
;
500 void classify (packet
, class)
501 struct packet
*packet
;
506 int unbill_class (lease
, class)
513 int find_subnet (struct subnet
**sp
,
514 struct iaddr addr
, const char *file
, int line
)
519 /* Individual States:
521 * Each routine is called from the dhclient_state_machine() in one of
523 * -> entering INIT state
524 * -> recvpacket_flag == 0: timeout in this state
525 * -> otherwise: received a packet in this state
527 * Return conditions as handled by dhclient_state_machine():
528 * Returns 1, sendpacket_flag = 1: send packet, reset timer.
529 * Returns 1, sendpacket_flag = 0: just reset the timer (wait for a milestone).
530 * Returns 0: finish the nap which was interrupted for no good reason.
532 * Several per-interface variables are used to keep track of the process:
533 * active_lease: the lease that is being used on the interface
534 * (null pointer if not configured yet).
535 * offered_leases: leases corresponding to DHCPOFFER messages that have
536 * been sent to us by DHCP servers.
537 * acked_leases: leases corresponding to DHCPACK messages that have been
538 * sent to us by DHCP servers.
539 * sendpacket: DHCP packet we're trying to send.
540 * destination: IP address to send sendpacket to
541 * In addition, there are several relevant per-lease variables.
542 * T1_expiry, T2_expiry, lease_expiry: lease milestones
543 * In the active lease, these control the process of renewing the lease;
544 * In leases on the acked_leases list, this simply determines when we
545 * can no longer legitimately use the lease.
548 void state_reboot (cpp
)
551 struct client_state
*client
= cpp
;
553 /* If we don't remember an active lease, go straight to INIT. */
554 if (!client
-> active
||
555 client
-> active
-> is_bootp
||
556 client
-> active
-> expiry
<= cur_time
) {
561 /* We are in the rebooting state. */
562 client
-> state
= S_REBOOTING
;
564 /* make_request doesn't initialize xid because it normally comes
565 from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
566 so pick an xid now. */
567 client
-> xid
= random ();
569 /* Make a DHCPREQUEST packet, and set appropriate per-interface
571 make_request (client
, client
-> active
);
572 client
-> destination
= iaddr_broadcast
;
573 client
-> first_sending
= cur_time
;
574 client
-> interval
= client
-> config
-> initial_interval
;
576 /* Zap the medium list... */
577 client
-> medium
= (struct string_list
*)0;
579 /* Send out the first DHCPREQUEST packet. */
580 send_request (client
);
583 /* Called when a lease has completely expired and we've been unable to
586 void state_init (cpp
)
589 struct client_state
*client
= cpp
;
591 ASSERT_STATE(state
, S_INIT
);
593 /* Make a DHCPDISCOVER packet, and set appropriate per-interface
595 make_discover (client
, client
-> active
);
596 client
-> xid
= client
-> packet
.xid
;
597 client
-> destination
= iaddr_broadcast
;
598 client
-> state
= S_SELECTING
;
599 client
-> first_sending
= cur_time
;
600 client
-> interval
= client
-> config
-> initial_interval
;
602 /* Add an immediate timeout to cause the first DHCPDISCOVER packet
604 send_discover (client
);
607 /* state_selecting is called when one or more DHCPOFFER packets have been
608 received and a configurable period of time has passed. */
610 void state_selecting (cpp
)
613 struct client_state
*client
= cpp
;
614 struct client_lease
*lp
, *next
, *picked
;
617 ASSERT_STATE(state
, S_SELECTING
);
619 /* Cancel state_selecting and send_discover timeouts, since either
620 one could have got us here. */
621 cancel_timeout (state_selecting
, client
);
622 cancel_timeout (send_discover
, client
);
624 /* We have received one or more DHCPOFFER packets. Currently,
625 the only criterion by which we judge leases is whether or
626 not we get a response when we arp for them. */
627 picked
= (struct client_lease
*)0;
628 for (lp
= client
-> offered_leases
; lp
; lp
= next
) {
631 /* Check to see if we got an ARPREPLY for the address
632 in this particular lease. */
635 picked
-> next
= (struct client_lease
*)0;
638 destroy_client_lease (lp
);
641 client
-> offered_leases
= (struct client_lease
*)0;
643 /* If we just tossed all the leases we were offered, go back
646 client
-> state
= S_INIT
;
651 /* If it was a BOOTREPLY, we can just take the address right now. */
652 if (picked
-> is_bootp
) {
653 client
-> new = picked
;
655 /* Make up some lease expiry times
656 XXX these should be configurable. */
657 client
-> new -> expiry
= cur_time
+ 12000;
658 client
-> new -> renewal
+= cur_time
+ 8000;
659 client
-> new -> rebind
+= cur_time
+ 10000;
661 client
-> state
= S_REQUESTING
;
663 /* Bind to the address we received. */
668 /* Go to the REQUESTING state. */
669 client
-> destination
= iaddr_broadcast
;
670 client
-> state
= S_REQUESTING
;
671 client
-> first_sending
= cur_time
;
672 client
-> interval
= client
-> config
-> initial_interval
;
674 /* Make a DHCPREQUEST packet from the lease we picked. */
675 make_request (client
, picked
);
676 client
-> xid
= client
-> packet
.xid
;
678 /* Toss the lease we picked - we'll get it back in a DHCPACK. */
679 destroy_client_lease (picked
);
681 /* Add an immediate timeout to send the first DHCPREQUEST packet. */
682 send_request (client
);
685 /* state_requesting is called when we receive a DHCPACK message after
686 having sent out one or more DHCPREQUEST packets. */
688 void dhcpack (packet
)
689 struct packet
*packet
;
691 struct interface_info
*ip
= packet
-> interface
;
692 struct client_state
*client
;
693 struct client_lease
*lease
;
694 struct option_cache
*oc
;
695 struct data_string ds
;
698 /* If we're not receptive to an offer right now, or if the offer
699 has an unrecognizable transaction id, then just drop it. */
700 for (client
= ip
-> client
; client
; client
= client
-> next
) {
701 if (client
-> xid
== packet
-> raw
-> xid
)
705 (packet
-> interface
-> hw_address
.hlen
- 1 !=
706 packet
-> raw
-> hlen
) ||
707 (memcmp (&packet
-> interface
-> hw_address
.hbuf
[1],
708 packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
))) {
710 log_debug ("DHCPACK in wrong transaction.");
715 if (client
-> state
!= S_REBOOTING
&&
716 client
-> state
!= S_REQUESTING
&&
717 client
-> state
!= S_RENEWING
&&
718 client
-> state
!= S_REBINDING
) {
720 log_debug ("DHCPACK in wrong state.");
725 log_info ("DHCPACK from %s", piaddr (packet
-> client_addr
));
727 lease
= packet_to_lease (packet
, client
);
729 log_info ("packet_to_lease failed.");
733 client
-> new = lease
;
735 /* Stop resending DHCPREQUEST. */
736 cancel_timeout (send_request
, client
);
738 /* Figure out the lease time. */
739 oc
= lookup_option (&dhcp_universe
, client
-> new -> options
,
740 DHO_DHCP_LEASE_TIME
);
741 memset (&ds
, 0, sizeof ds
);
743 evaluate_option_cache (&ds
, packet
, (struct lease
*)0, client
,
744 packet
-> options
, client
-> new -> options
,
745 &global_scope
, oc
, MDL
)) {
747 client
-> new -> expiry
= getULong (ds
.data
);
749 client
-> new -> expiry
= 0;
750 data_string_forget (&ds
, MDL
);
752 client
-> new -> expiry
= 0;
754 if (!client
-> new -> expiry
) {
755 log_error ("no expiry time on offered lease.");
756 /* XXX this is going to be bad - if this _does_
757 XXX happen, we should probably dynamically
758 XXX disqualify the DHCP server that gave us the
759 XXX bad packet from future selections and
760 XXX then go back into the init state. */
765 /* A number that looks negative here is really just very large,
766 because the lease expiry offset is unsigned. */
767 if (client
-> new -> expiry
< 0)
768 client
-> new -> expiry
= TIME_MAX
;
769 /* Take the server-provided renewal time if there is one. */
770 oc
= lookup_option (&dhcp_universe
, client
-> new -> options
,
771 DHO_DHCP_RENEWAL_TIME
);
773 evaluate_option_cache (&ds
, packet
, (struct lease
*)0, client
,
774 packet
-> options
, client
-> new -> options
,
775 &global_scope
, oc
, MDL
)) {
777 client
-> new -> renewal
= getULong (ds
.data
);
779 client
-> new -> renewal
= 0;
780 data_string_forget (&ds
, MDL
);
782 client
-> new -> renewal
= 0;
784 /* If it wasn't specified by the server, calculate it. */
785 if (!client
-> new -> renewal
)
786 client
-> new -> renewal
= client
-> new -> expiry
/ 2 + 1;
788 if (client
-> new -> renewal
<= 0)
789 client
-> new -> renewal
= TIME_MAX
;
791 /* Now introduce some randomness to the renewal time: */
792 if (client
->new->renewal
<= ((TIME_MAX
/ 3) - 3))
793 client
->new->renewal
= (((client
->new->renewal
* 3) + 3) / 4) +
794 (((random() % client
->new->renewal
) + 3) / 4);
796 /* Same deal with the rebind time. */
797 oc
= lookup_option (&dhcp_universe
, client
-> new -> options
,
798 DHO_DHCP_REBINDING_TIME
);
800 evaluate_option_cache (&ds
, packet
, (struct lease
*)0, client
,
801 packet
-> options
, client
-> new -> options
,
802 &global_scope
, oc
, MDL
)) {
804 client
-> new -> rebind
= getULong (ds
.data
);
806 client
-> new -> rebind
= 0;
807 data_string_forget (&ds
, MDL
);
809 client
-> new -> rebind
= 0;
811 if (client
-> new -> rebind
<= 0) {
812 if (client
-> new -> expiry
<= TIME_MAX
/ 7)
813 client
-> new -> rebind
=
814 client
-> new -> expiry
* 7 / 8;
816 client
-> new -> rebind
=
817 client
-> new -> expiry
/ 8 * 7;
820 /* Make sure our randomness didn't run the renewal time past the
822 if (client
-> new -> renewal
> client
-> new -> rebind
) {
823 if (client
-> new -> rebind
<= TIME_MAX
/ 3)
824 client
-> new -> renewal
=
825 client
-> new -> rebind
* 3 / 4;
827 client
-> new -> renewal
=
828 client
-> new -> rebind
/ 4 * 3;
831 client
-> new -> expiry
+= cur_time
;
832 /* Lease lengths can never be negative. */
833 if (client
-> new -> expiry
< cur_time
)
834 client
-> new -> expiry
= TIME_MAX
;
835 client
-> new -> renewal
+= cur_time
;
836 if (client
-> new -> renewal
< cur_time
)
837 client
-> new -> renewal
= TIME_MAX
;
838 client
-> new -> rebind
+= cur_time
;
839 if (client
-> new -> rebind
< cur_time
)
840 client
-> new -> rebind
= TIME_MAX
;
845 void bind_lease (client
)
846 struct client_state
*client
;
848 struct interface_info
*ip
= client
-> interface
;
850 /* Remember the medium. */
851 client
-> new -> medium
= client
-> medium
;
853 /* Run the client script with the new parameters. */
854 script_init (client
, (client
-> state
== S_REQUESTING
856 : (client
-> state
== S_RENEWING
858 : (client
-> state
== S_REBOOTING
859 ? "REBOOT" : "REBIND"))),
860 client
-> new -> medium
);
861 if (client
-> active
&& client
-> state
!= S_REBOOTING
)
862 script_write_params (client
, "old_", client
-> active
);
863 script_write_params (client
, "new_", client
-> new);
865 script_write_params (client
, "alias_", client
-> alias
);
867 /* If the BOUND/RENEW code detects another machine using the
868 offered address, it exits nonzero. We need to send a
869 DHCPDECLINE and toss the lease. */
870 if (script_go (client
)) {
871 make_decline (client
, client
-> new);
872 send_decline (client
);
873 destroy_client_lease (client
-> new);
874 client
-> new = (struct client_lease
*)0;
879 /* Write out the new lease. */
880 write_client_lease (client
, client
-> new, 0, 0);
882 /* Replace the old active lease with the new one. */
883 if (client
-> active
)
884 destroy_client_lease (client
-> active
);
885 client
-> active
= client
-> new;
886 client
-> new = (struct client_lease
*)0;
888 /* Set up a timeout to start the renewal process. */
889 add_timeout (client
-> active
-> renewal
,
890 state_bound
, client
, 0, 0);
892 log_info ("bound to %s -- renewal in %ld seconds.",
893 piaddr (client
-> active
-> address
),
894 (long)(client
-> active
-> renewal
- cur_time
));
895 client
-> state
= S_BOUND
;
896 reinitialize_interfaces ();
898 if (client
-> config
-> do_forward_update
) {
899 client
-> dns_update_timeout
= 1;
900 add_timeout (cur_time
+ 1, client_dns_update_timeout
,
905 /* state_bound is called when we've successfully bound to a particular
906 lease, but the renewal time on that lease has expired. We are
907 expected to unicast a DHCPREQUEST to the server that gave us our
910 void state_bound (cpp
)
913 struct client_state
*client
= cpp
;
915 struct option_cache
*oc
;
916 struct data_string ds
;
918 ASSERT_STATE(state
, S_BOUND
);
920 /* T1 has expired. */
921 make_request (client
, client
-> active
);
922 client
-> xid
= client
-> packet
.xid
;
924 memset (&ds
, 0, sizeof ds
);
925 oc
= lookup_option (&dhcp_universe
, client
-> active
-> options
,
926 DHO_DHCP_SERVER_IDENTIFIER
);
928 evaluate_option_cache (&ds
, (struct packet
*)0, (struct lease
*)0,
929 client
, (struct option_state
*)0,
930 client
-> active
-> options
,
931 &global_scope
, oc
, MDL
)) {
933 memcpy (client
-> destination
.iabuf
, ds
.data
, 4);
934 client
-> destination
.len
= 4;
936 client
-> destination
= iaddr_broadcast
;
938 data_string_forget (&ds
, MDL
);
940 client
-> destination
= iaddr_broadcast
;
942 client
-> first_sending
= cur_time
;
943 client
-> interval
= client
-> config
-> initial_interval
;
944 client
-> state
= S_RENEWING
;
946 /* Send the first packet immediately. */
947 send_request (client
);
950 /* state_stop is called when we've been told to shut down. We unconfigure
951 the interfaces, and then stop operating until told otherwise. */
953 void state_stop (cpp
)
956 struct client_state
*client
= cpp
;
959 /* Cancel all timeouts. */
960 cancel_timeout (state_selecting
, client
);
961 cancel_timeout (send_discover
, client
);
962 cancel_timeout (send_request
, client
);
963 cancel_timeout (state_bound
, client
);
965 /* If we have an address, unconfigure it. */
966 if (client
-> active
) {
967 script_init (client
, "STOP", client
-> active
-> medium
);
968 script_write_params (client
, "old_", client
-> active
);
970 script_write_params (client
, "alias_",
981 int write_lease (lease
)
987 int write_host (host
)
988 struct host_decl
*host
;
993 void db_startup (testp
)
999 struct packet
*packet
;
1001 struct iaddrlist
*ap
;
1003 if (packet
-> raw
-> op
!= BOOTREPLY
)
1006 /* If there's a reject list, make sure this packet's sender isn't
1008 for (ap
= packet
-> interface
-> client
-> config
-> reject_list
;
1009 ap
; ap
= ap
-> next
) {
1010 if (addr_eq (packet
-> client_addr
, ap
-> addr
)) {
1011 log_info ("BOOTREPLY from %s rejected.",
1012 piaddr (ap
-> addr
));
1022 struct packet
*packet
;
1024 struct iaddrlist
*ap
;
1025 void (*handler
) PROTO ((struct packet
*));
1028 switch (packet
-> packet_type
) {
1030 handler
= dhcpoffer
;
1048 /* If there's a reject list, make sure this packet's sender isn't
1050 for (ap
= packet
-> interface
-> client
-> config
-> reject_list
;
1051 ap
; ap
= ap
-> next
) {
1052 if (addr_eq (packet
-> client_addr
, ap
-> addr
)) {
1053 log_info ("%s from %s rejected.",
1054 type
, piaddr (ap
-> addr
));
1058 (*handler
) (packet
);
1061 void dhcpoffer (packet
)
1062 struct packet
*packet
;
1064 struct interface_info
*ip
= packet
-> interface
;
1065 struct client_state
*client
;
1066 struct client_lease
*lease
, *lp
;
1069 const char *name
= packet
-> packet_type
? "DHCPOFFER" : "BOOTREPLY";
1070 struct iaddrlist
*ap
;
1071 struct option_cache
*oc
;
1075 dump_packet (packet
);
1078 /* Find a client state that matches the xid... */
1079 for (client
= ip
-> client
; client
; client
= client
-> next
)
1080 if (client
-> xid
== packet
-> raw
-> xid
)
1083 /* If we're not receptive to an offer right now, or if the offer
1084 has an unrecognizable transaction id, then just drop it. */
1086 client
-> state
!= S_SELECTING
||
1087 (packet
-> interface
-> hw_address
.hlen
- 1 !=
1088 packet
-> raw
-> hlen
) ||
1089 (memcmp (&packet
-> interface
-> hw_address
.hbuf
[1],
1090 packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
))) {
1092 log_debug ("%s in wrong transaction.", name
);
1097 sprintf (obuf
, "%s from %s", name
, piaddr (packet
-> client_addr
));
1100 /* If this lease doesn't supply the minimum required parameters,
1102 if (client
-> config
-> required_options
) {
1103 for (i
= 0; client
-> config
-> required_options
[i
]; i
++) {
1105 (&dhcp_universe
, packet
-> options
,
1106 client
-> config
-> required_options
[i
])) {
1107 log_info ("%s: no %s option.",
1108 obuf
, (dhcp_universe
.options
1109 [client
-> config
-> required_options
[i
]]
1116 /* If we've already seen this lease, don't record it again. */
1117 for (lease
= client
-> offered_leases
; lease
; lease
= lease
-> next
) {
1118 if (lease
-> address
.len
== sizeof packet
-> raw
-> yiaddr
&&
1119 !memcmp (lease
-> address
.iabuf
,
1120 &packet
-> raw
-> yiaddr
, lease
-> address
.len
)) {
1121 log_debug ("%s: already seen.", obuf
);
1126 lease
= packet_to_lease (packet
, client
);
1128 log_info ("%s: packet_to_lease failed.", obuf
);
1132 /* If this lease was acquired through a BOOTREPLY, record that
1134 if (!packet
-> options_valid
|| !packet
-> packet_type
)
1135 lease
-> is_bootp
= 1;
1137 /* Record the medium under which this lease was offered. */
1138 lease
-> medium
= client
-> medium
;
1140 /* Figure out when we're supposed to stop selecting. */
1141 stop_selecting
= (client
-> first_sending
+
1142 client
-> config
-> select_interval
);
1144 /* If this is the lease we asked for, put it at the head of the
1145 list, and don't mess with the arp request timeout. */
1146 if (lease
-> address
.len
== client
-> requested_address
.len
&&
1147 !memcmp (lease
-> address
.iabuf
,
1148 client
-> requested_address
.iabuf
,
1149 client
-> requested_address
.len
)) {
1150 lease
-> next
= client
-> offered_leases
;
1151 client
-> offered_leases
= lease
;
1153 /* Put the lease at the end of the list. */
1154 lease
-> next
= (struct client_lease
*)0;
1155 if (!client
-> offered_leases
)
1156 client
-> offered_leases
= lease
;
1158 for (lp
= client
-> offered_leases
; lp
-> next
;
1165 /* If the selecting interval has expired, go immediately to
1166 state_selecting(). Otherwise, time out into
1167 state_selecting at the select interval. */
1168 if (stop_selecting
<= 0)
1169 state_selecting (client
);
1171 add_timeout (stop_selecting
, state_selecting
, client
, 0, 0);
1172 cancel_timeout (send_discover
, client
);
1174 log_info ("%s", obuf
);
1177 /* Allocate a client_lease structure and initialize it from the parameters
1178 in the specified packet. */
1180 struct client_lease
*packet_to_lease (packet
, client
)
1181 struct packet
*packet
;
1182 struct client_state
*client
;
1184 struct client_lease
*lease
;
1186 struct option_cache
*oc
;
1187 struct data_string data
;
1189 lease
= (struct client_lease
*)new_client_lease (MDL
);
1192 log_error ("packet_to_lease: no memory to record lease.\n");
1193 return (struct client_lease
*)0;
1196 memset (lease
, 0, sizeof *lease
);
1198 /* Copy the lease options. */
1199 option_state_reference (&lease
-> options
, packet
-> options
, MDL
);
1201 lease
-> address
.len
= sizeof (packet
-> raw
-> yiaddr
);
1202 memcpy (lease
-> address
.iabuf
, &packet
-> raw
-> yiaddr
,
1203 lease
-> address
.len
);
1205 memset (&data
, 0, sizeof data
);
1207 if (client
-> config
-> vendor_space_name
) {
1208 i
= DHO_VENDOR_ENCAPSULATED_OPTIONS
;
1210 /* See if there was a vendor encapsulation option. */
1211 oc
= lookup_option (&dhcp_universe
, lease
-> options
, i
);
1213 client
-> config
-> vendor_space_name
&&
1214 evaluate_option_cache (&data
, packet
,
1215 (struct lease
*)0, client
,
1216 packet
-> options
, lease
-> options
,
1217 &global_scope
, oc
, MDL
)) {
1219 parse_encapsulated_suboptions
1220 (packet
-> options
, &dhcp_options
[i
],
1221 data
.data
, data
.len
, &dhcp_universe
,
1222 client
-> config
-> vendor_space_name
1225 data_string_forget (&data
, MDL
);
1230 /* Figure out the overload flag. */
1231 oc
= lookup_option (&dhcp_universe
, lease
-> options
,
1232 DHO_DHCP_OPTION_OVERLOAD
);
1234 evaluate_option_cache (&data
, packet
, (struct lease
*)0, client
,
1235 packet
-> options
, lease
-> options
,
1236 &global_scope
, oc
, MDL
)) {
1241 data_string_forget (&data
, MDL
);
1245 /* If the server name was filled out, copy it. */
1246 if (!(i
& 2) && packet
-> raw
-> sname
[0]) {
1248 /* Don't count on the NUL terminator. */
1249 for (len
= 0; len
< 64; len
++)
1250 if (!packet
-> raw
-> sname
[len
])
1252 lease
-> server_name
= dmalloc (len
+ 1, MDL
);
1253 if (!lease
-> server_name
) {
1254 log_error ("dhcpoffer: no memory for server name.\n");
1255 destroy_client_lease (lease
);
1256 return (struct client_lease
*)0;
1258 memcpy (lease
-> server_name
,
1259 packet
-> raw
-> sname
, len
);
1260 lease
-> server_name
[len
] = 0;
1264 /* Ditto for the filename. */
1265 if (!(i
& 1) && packet
-> raw
-> file
[0]) {
1267 /* Don't count on the NUL terminator. */
1268 for (len
= 0; len
< 64; len
++)
1269 if (!packet
-> raw
-> file
[len
])
1271 lease
-> filename
= dmalloc (len
+ 1, MDL
);
1272 if (!lease
-> filename
) {
1273 log_error ("dhcpoffer: no memory for filename.\n");
1274 destroy_client_lease (lease
);
1275 return (struct client_lease
*)0;
1277 memcpy (lease
-> filename
,
1278 packet
-> raw
-> file
, len
);
1279 lease
-> filename
[len
] = 0;
1283 execute_statements_in_scope ((struct binding_value
**)0,
1284 (struct packet
*)packet
,
1285 (struct lease
*)0, client
,
1286 lease
-> options
, lease
-> options
,
1288 client
-> config
-> on_receipt
,
1294 void dhcpnak (packet
)
1295 struct packet
*packet
;
1297 struct interface_info
*ip
= packet
-> interface
;
1298 struct client_state
*client
;
1300 /* Find a client state that matches the xid... */
1301 for (client
= ip
-> client
; client
; client
= client
-> next
)
1302 if (client
-> xid
== packet
-> raw
-> xid
)
1305 /* If we're not receptive to an offer right now, or if the offer
1306 has an unrecognizable transaction id, then just drop it. */
1308 (packet
-> interface
-> hw_address
.hlen
- 1 !=
1309 packet
-> raw
-> hlen
) ||
1310 (memcmp (&packet
-> interface
-> hw_address
.hbuf
[1],
1311 packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
))) {
1313 log_debug ("DHCPNAK in wrong transaction.");
1318 if (client
-> state
!= S_REBOOTING
&&
1319 client
-> state
!= S_REQUESTING
&&
1320 client
-> state
!= S_RENEWING
&&
1321 client
-> state
!= S_REBINDING
) {
1323 log_debug ("DHCPNAK in wrong state.");
1328 log_info ("DHCPNAK from %s", piaddr (packet
-> client_addr
));
1330 if (!client
-> active
) {
1332 log_info ("DHCPNAK with no active lease.\n");
1337 destroy_client_lease (client
-> active
);
1338 client
-> active
= (struct client_lease
*)0;
1340 /* Stop sending DHCPREQUEST packets... */
1341 cancel_timeout (send_request
, client
);
1343 client
-> state
= S_INIT
;
1344 state_init (client
);
1347 /* Send out a DHCPDISCOVER packet, and set a timeout to send out another
1348 one after the right interval has expired. If we don't get an offer by
1349 the time we reach the panic interval, call the panic function. */
1351 void send_discover (cpp
)
1354 struct client_state
*client
= cpp
;
1360 /* Figure out how long it's been since we started transmitting. */
1361 interval
= cur_time
- client
-> first_sending
;
1363 /* If we're past the panic timeout, call the script and tell it
1364 we haven't found anything for this interface yet. */
1365 if (interval
> client
-> config
-> timeout
) {
1366 state_panic (client
);
1370 /* If we're selecting media, try the whole list before doing
1371 the exponential backoff, but if we've already received an
1372 offer, stop looping, because we obviously have it right. */
1373 if (!client
-> offered_leases
&&
1374 client
-> config
-> media
) {
1377 if (client
-> medium
) {
1378 client
-> medium
= client
-> medium
-> next
;
1381 if (!client
-> medium
) {
1383 log_fatal ("No valid media types for %s!",
1384 client
-> interface
-> name
);
1386 client
-> config
-> media
;
1390 log_info ("Trying medium \"%s\" %d",
1391 client
-> medium
-> string
, increase
);
1392 script_init (client
, "MEDIUM", client
-> medium
);
1393 if (script_go (client
)) {
1399 /* If we're supposed to increase the interval, do so. If it's
1400 currently zero (i.e., we haven't sent any packets yet), set
1401 it to initial_interval; otherwise, add to it a random number
1402 between zero and two times itself. On average, this means
1403 that it will double with every transmission. */
1405 if (!client
->interval
)
1406 client
->interval
= client
->config
->initial_interval
;
1408 client
->interval
+= random() % (2 * client
->interval
);
1410 /* Don't backoff past cutoff. */
1411 if (client
->interval
> client
->config
->backoff_cutoff
)
1412 client
->interval
= (client
->config
->backoff_cutoff
/ 2)
1413 + (random() % client
->config
->backoff_cutoff
);
1414 } else if (!client
->interval
)
1415 client
->interval
= client
->config
->initial_interval
;
1417 /* If the backoff would take us to the panic timeout, just use that
1419 if (cur_time
+ client
-> interval
>
1420 client
-> first_sending
+ client
-> config
-> timeout
)
1421 client
-> interval
=
1422 (client
-> first_sending
+
1423 client
-> config
-> timeout
) - cur_time
+ 1;
1425 /* Record the number of seconds since we started sending. */
1426 if (interval
< 65536)
1427 client
-> packet
.secs
= htons (interval
);
1429 client
-> packet
.secs
= htons (65535);
1430 client
-> secs
= client
-> packet
.secs
;
1432 log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",
1433 client
-> name
? client
-> name
: client
-> interface
-> name
,
1434 inet_ntoa (sockaddr_broadcast
.sin_addr
),
1435 ntohs (sockaddr_broadcast
.sin_port
), (long)(client
-> interval
));
1437 /* Send out a packet. */
1438 result
= send_packet (client
-> interface
, (struct packet
*)0,
1440 client
-> packet_length
,
1441 inaddr_any
, &sockaddr_broadcast
,
1442 (struct hardware
*)0);
1444 add_timeout (cur_time
+ client
-> interval
,
1445 send_discover
, client
, 0, 0);
1448 /* state_panic gets called if we haven't received any offers in a preset
1449 amount of time. When this happens, we try to use existing leases that
1450 haven't yet expired, and failing that, we call the client script and
1451 hope it can do something. */
1453 void state_panic (cpp
)
1456 struct client_state
*client
= cpp
;
1457 struct client_lease
*loop
;
1458 struct client_lease
*lp
;
1460 loop
= lp
= client
-> active
;
1462 log_info ("No DHCPOFFERS received.");
1464 /* We may not have an active lease, but we may have some
1465 predefined leases that we can try. */
1466 if (!client
-> active
&& client
-> leases
)
1469 /* Run through the list of leases and see if one can be used. */
1470 while (client
-> active
) {
1471 if (client
-> active
-> expiry
> cur_time
) {
1472 log_info ("Trying recorded lease %s",
1473 piaddr (client
-> active
-> address
));
1474 /* Run the client script with the existing
1476 script_init (client
, "TIMEOUT",
1477 client
-> active
-> medium
);
1478 script_write_params (client
, "new_", client
-> active
);
1479 if (client
-> alias
)
1480 script_write_params (client
, "alias_",
1483 /* If the old lease is still good and doesn't
1484 yet need renewal, go into BOUND state and
1485 timeout at the renewal time. */
1486 if (!script_go (client
)) {
1487 if (cur_time
< client
-> active
-> renewal
) {
1488 client
-> state
= S_BOUND
;
1489 log_info ("bound: renewal in %ld %s.",
1490 (long)(client
-> active
-> renewal
-
1491 cur_time
), "seconds");
1492 add_timeout (client
-> active
-> renewal
,
1493 state_bound
, client
, 0, 0);
1495 client
-> state
= S_BOUND
;
1496 log_info ("bound: immediate renewal.");
1497 state_bound (client
);
1499 reinitialize_interfaces ();
1505 /* If there are no other leases, give up. */
1506 if (!client
-> leases
) {
1507 client
-> leases
= client
-> active
;
1508 client
-> active
= (struct client_lease
*)0;
1513 /* Otherwise, put the active lease at the end of the
1514 lease list, and try another lease.. */
1515 for (lp
= client
-> leases
; lp
-> next
; lp
= lp
-> next
)
1517 lp
-> next
= client
-> active
;
1519 lp
-> next
-> next
= (struct client_lease
*)0;
1521 client
-> active
= client
-> leases
;
1522 client
-> leases
= client
-> leases
-> next
;
1524 /* If we already tried this lease, we've exhausted the
1525 set of leases, so we might as well give up for
1527 if (client
-> active
== loop
)
1530 loop
= client
-> active
;
1533 /* No leases were available, or what was available didn't work, so
1534 tell the shell script that we failed to allocate an address,
1535 and try again later. */
1538 log_info ("Unable to obtain a lease on first try.%s",
1543 log_info ("No working leases in persistent database - sleeping.");
1544 script_init (client
, "FAIL", (struct string_list
*)0);
1545 if (client
-> alias
)
1546 script_write_params (client
, "alias_", client
-> alias
);
1548 client
-> state
= S_INIT
;
1549 add_timeout (cur_time
+
1550 ((client
-> config
-> retry_interval
+ 1) / 2 +
1551 (random () % client
-> config
-> retry_interval
)),
1552 state_init
, client
, 0, 0);
1556 void send_request (cpp
)
1559 struct client_state
*client
= cpp
;
1563 struct sockaddr_in destination
;
1564 struct in_addr from
;
1566 /* Figure out how long it's been since we started transmitting. */
1567 interval
= cur_time
- client
-> first_sending
;
1569 /* If we're in the INIT-REBOOT or REQUESTING state and we're
1570 past the reboot timeout, go to INIT and see if we can
1571 DISCOVER an address... */
1572 /* XXX In the INIT-REBOOT state, if we don't get an ACK, it
1573 means either that we're on a network with no DHCP server,
1574 or that our server is down. In the latter case, assuming
1575 that there is a backup DHCP server, DHCPDISCOVER will get
1576 us a new address, but we could also have successfully
1577 reused our old address. In the former case, we're hosed
1578 anyway. This is not a win-prone situation. */
1579 if ((client
-> state
== S_REBOOTING
||
1580 client
-> state
== S_REQUESTING
) &&
1581 interval
> client
-> config
-> reboot_timeout
) {
1583 client
-> state
= S_INIT
;
1584 cancel_timeout (send_request
, client
);
1585 state_init (client
);
1589 /* If we're in the reboot state, make sure the media is set up
1591 if (client
-> state
== S_REBOOTING
&&
1592 !client
-> medium
&&
1593 client
-> active
-> medium
) {
1594 script_init (client
, "MEDIUM", client
-> active
-> medium
);
1596 /* If the medium we chose won't fly, go to INIT state. */
1597 if (script_go (client
))
1600 /* Record the medium. */
1601 client
-> medium
= client
-> active
-> medium
;
1604 /* If the lease has expired, relinquish the address and go back
1605 to the INIT state. */
1606 if (client
-> state
!= S_REQUESTING
&&
1607 cur_time
> client
-> active
-> expiry
) {
1608 /* Run the client script with the new parameters. */
1609 script_init (client
, "EXPIRE", (struct string_list
*)0);
1610 script_write_params (client
, "old_", client
-> active
);
1611 if (client
-> alias
)
1612 script_write_params (client
, "alias_",
1616 /* Now do a preinit on the interface so that we can
1617 discover a new address. */
1618 script_init (client
, "PREINIT", (struct string_list
*)0);
1619 if (client
-> alias
)
1620 script_write_params (client
, "alias_",
1624 client
-> state
= S_INIT
;
1625 state_init (client
);
1629 /* Do the exponential backoff... */
1630 if (!client
-> interval
)
1631 client
-> interval
= client
-> config
-> initial_interval
;
1633 client
-> interval
+= ((random () >> 2) %
1634 (2 * client
-> interval
));
1637 /* Don't backoff past cutoff. */
1638 if (client
-> interval
>
1639 client
-> config
-> backoff_cutoff
)
1640 client
-> interval
=
1641 ((client
-> config
-> backoff_cutoff
/ 2)
1642 + ((random () >> 2) %
1643 client
-> config
-> backoff_cutoff
));
1645 /* If the backoff would take us to the expiry time, just set the
1646 timeout to the expiry time. */
1647 if (client
-> state
!= S_REQUESTING
&&
1648 cur_time
+ client
-> interval
> client
-> active
-> expiry
)
1649 client
-> interval
=
1650 client
-> active
-> expiry
- cur_time
+ 1;
1652 /* If the lease T2 time has elapsed, or if we're not yet bound,
1653 broadcast the DHCPREQUEST rather than unicasting. */
1654 if (client
-> state
== S_REQUESTING
||
1655 client
-> state
== S_REBOOTING
||
1656 cur_time
> client
-> active
-> rebind
)
1657 destination
.sin_addr
= sockaddr_broadcast
.sin_addr
;
1659 memcpy (&destination
.sin_addr
.s_addr
,
1660 client
-> destination
.iabuf
,
1661 sizeof destination
.sin_addr
.s_addr
);
1662 destination
.sin_port
= remote_port
;
1663 destination
.sin_family
= AF_INET
;
1665 destination
.sin_len
= sizeof destination
;
1668 if (client
-> state
== S_RENEWING
||
1669 client
-> state
== S_REBINDING
)
1670 memcpy (&from
, client
-> active
-> address
.iabuf
,
1673 from
.s_addr
= INADDR_ANY
;
1675 /* Record the number of seconds since we started sending. */
1676 if (client
-> state
== S_REQUESTING
)
1677 client
-> packet
.secs
= client
-> secs
;
1679 if (interval
< 65536)
1680 client
-> packet
.secs
= htons (interval
);
1682 client
-> packet
.secs
= htons (65535);
1685 log_info ("DHCPREQUEST on %s to %s port %d",
1686 client
-> name
? client
-> name
: client
-> interface
-> name
,
1687 inet_ntoa (destination
.sin_addr
),
1688 ntohs (destination
.sin_port
));
1690 if (destination
.sin_addr
.s_addr
!= INADDR_BROADCAST
&&
1692 result
= send_packet (fallback_interface
,
1695 client
-> packet_length
,
1697 (struct hardware
*)0);
1699 /* Send out a packet. */
1700 result
= send_packet (client
-> interface
, (struct packet
*)0,
1702 client
-> packet_length
,
1704 (struct hardware
*)0);
1706 add_timeout (cur_time
+ client
-> interval
,
1707 send_request
, client
, 0, 0);
1710 void send_decline (cpp
)
1713 struct client_state
*client
= cpp
;
1717 log_info ("DHCPDECLINE on %s to %s port %d",
1718 client
-> name
? client
-> name
: client
-> interface
-> name
,
1719 inet_ntoa (sockaddr_broadcast
.sin_addr
),
1720 ntohs (sockaddr_broadcast
.sin_port
));
1722 /* Send out a packet. */
1723 result
= send_packet (client
-> interface
, (struct packet
*)0,
1725 client
-> packet_length
,
1726 inaddr_any
, &sockaddr_broadcast
,
1727 (struct hardware
*)0);
1730 void send_release (cpp
)
1733 struct client_state
*client
= cpp
;
1736 struct sockaddr_in destination
;
1737 struct in_addr from
;
1739 memcpy (&from
, client
-> active
-> address
.iabuf
,
1741 memcpy (&destination
.sin_addr
.s_addr
,
1742 client
-> destination
.iabuf
,
1743 sizeof destination
.sin_addr
.s_addr
);
1744 destination
.sin_port
= remote_port
;
1745 destination
.sin_family
= AF_INET
;
1747 destination
.sin_len
= sizeof destination
;
1750 /* Set the lease to end now, so that we don't accidentally
1751 reuse it if we restart before the old expiry time. */
1752 client
-> active
-> expiry
=
1753 client
-> active
-> renewal
=
1754 client
-> active
-> rebind
= cur_time
;
1755 if (!write_client_lease (client
, client
-> active
, 1, 1)) {
1756 log_error ("Can't release lease: lease write failed.");
1760 log_info ("DHCPRELEASE on %s to %s port %d",
1761 client
-> name
? client
-> name
: client
-> interface
-> name
,
1762 inet_ntoa (destination
.sin_addr
),
1763 ntohs (destination
.sin_port
));
1765 if (fallback_interface
)
1766 result
= send_packet (fallback_interface
,
1769 client
-> packet_length
,
1771 (struct hardware
*)0);
1773 /* Send out a packet. */
1774 result
= send_packet (client
-> interface
, (struct packet
*)0,
1776 client
-> packet_length
,
1778 (struct hardware
*)0);
1781 void make_client_options (client
, lease
, type
, sid
, rip
, prl
, op
)
1782 struct client_state
*client
;
1783 struct client_lease
*lease
;
1785 struct option_cache
*sid
;
1788 struct option_state
**op
;
1791 struct option_cache
*oc
;
1792 struct buffer
*bp
= (struct buffer
*)0;
1794 /* If there are any leftover options, get rid of them. */
1796 option_state_dereference (op
, MDL
);
1798 /* Allocate space for options. */
1799 option_state_allocate (op
, MDL
);
1801 /* Send the server identifier if provided. */
1803 save_option (&dhcp_universe
, *op
, sid
);
1805 oc
= (struct option_cache
*)0;
1807 /* Send the requested address if provided. */
1809 client
-> requested_address
= *rip
;
1810 if (!(make_const_option_cache
1811 (&oc
, (struct buffer
**)0, rip
-> iabuf
, rip
-> len
,
1812 &dhcp_options
[DHO_DHCP_REQUESTED_ADDRESS
], MDL
)))
1813 log_error ("can't make requested address cache.");
1815 save_option (&dhcp_universe
, *op
, oc
);
1816 option_cache_dereference (&oc
, MDL
);
1819 client
-> requested_address
.len
= 0;
1822 if (!(make_const_option_cache
1823 (&oc
, (struct buffer
**)0,
1824 type
, 1, &dhcp_options
[DHO_DHCP_MESSAGE_TYPE
], MDL
)))
1825 log_error ("can't make message type.");
1827 save_option (&dhcp_universe
, *op
, oc
);
1828 option_cache_dereference (&oc
, MDL
);
1832 /* Figure out how many parameters were requested. */
1833 for (i
= 0; prl
[i
]; i
++)
1835 if (!buffer_allocate (&bp
, i
, MDL
))
1836 log_error ("can't make parameter list buffer.");
1838 for (i
= 0; prl
[i
]; i
++)
1839 bp
-> data
[i
] = prl
[i
];
1840 if (!(make_const_option_cache
1841 (&oc
, &bp
, (u_int8_t
*)0, i
,
1842 &dhcp_options
[DHO_DHCP_PARAMETER_REQUEST_LIST
],
1844 log_error ("can't make option cache");
1846 save_option (&dhcp_universe
, *op
, oc
);
1847 option_cache_dereference (&oc
, MDL
);
1852 /* Run statements that need to be run on transmission. */
1853 if (client
-> config
-> on_transmission
)
1854 execute_statements_in_scope
1855 ((struct binding_value
**)0,
1856 (struct packet
*)0, (struct lease
*)0, client
,
1857 (lease
? lease
-> options
: (struct option_state
*)0),
1859 client
-> config
-> on_transmission
,
1863 void make_discover (client
, lease
)
1864 struct client_state
*client
;
1865 struct client_lease
*lease
;
1867 unsigned char discover
= DHCPDISCOVER
;
1869 struct option_state
*options
= (struct option_state
*)0;
1871 memset (&client
-> packet
, 0, sizeof (client
-> packet
));
1873 make_client_options (client
,
1874 lease
, &discover
, (struct option_cache
*)0,
1875 lease
? &lease
-> address
: (struct iaddr
*)0,
1876 client
-> config
-> requested_options
,
1879 /* Set up the option buffer... */
1880 client
-> packet_length
=
1881 cons_options ((struct packet
*)0, &client
-> packet
,
1882 (struct lease
*)0, client
,
1883 /* maximum packet size */1500,
1884 (struct option_state
*)0,
1886 /* scope */ &global_scope
,
1890 (struct data_string
*)0,
1891 client
-> config
-> vendor_space_name
);
1893 option_state_dereference (&options
, MDL
);
1894 if (client
-> packet_length
< BOOTP_MIN_LEN
)
1895 client
-> packet_length
= BOOTP_MIN_LEN
;
1897 client
-> packet
.op
= BOOTREQUEST
;
1898 client
-> packet
.htype
= client
-> interface
-> hw_address
.hbuf
[0];
1899 client
-> packet
.hlen
= client
-> interface
-> hw_address
.hlen
- 1;
1900 client
-> packet
.hops
= 0;
1901 client
-> packet
.xid
= random ();
1902 client
-> packet
.secs
= 0; /* filled in by send_discover. */
1904 if (can_receive_unicast_unconfigured (client
-> interface
))
1905 client
-> packet
.flags
= 0;
1907 client
-> packet
.flags
= htons (BOOTP_BROADCAST
);
1909 memset (&(client
-> packet
.ciaddr
),
1910 0, sizeof client
-> packet
.ciaddr
);
1911 memset (&(client
-> packet
.yiaddr
),
1912 0, sizeof client
-> packet
.yiaddr
);
1913 memset (&(client
-> packet
.siaddr
),
1914 0, sizeof client
-> packet
.siaddr
);
1915 client
-> packet
.giaddr
= giaddr
;
1916 if (client
-> interface
-> hw_address
.hlen
> 0)
1917 memcpy (client
-> packet
.chaddr
,
1918 &client
-> interface
-> hw_address
.hbuf
[1],
1919 (unsigned)(client
-> interface
-> hw_address
.hlen
- 1));
1922 dump_raw ((unsigned char *)&client
-> packet
, client
-> packet_length
);
1927 void make_request (client
, lease
)
1928 struct client_state
*client
;
1929 struct client_lease
*lease
;
1931 unsigned char request
= DHCPREQUEST
;
1933 unsigned char *tmp
, *digest
;
1934 unsigned char *old_digest_loc
;
1935 struct option_cache
*oc
;
1937 memset (&client
-> packet
, 0, sizeof (client
-> packet
));
1939 if (client
-> state
== S_REQUESTING
)
1940 oc
= lookup_option (&dhcp_universe
, lease
-> options
,
1941 DHO_DHCP_SERVER_IDENTIFIER
);
1943 oc
= (struct option_cache
*)0;
1945 if (client
-> sent_options
)
1946 option_state_dereference (&client
-> sent_options
, MDL
);
1948 make_client_options (client
, lease
, &request
, oc
,
1949 ((client
-> state
== S_REQUESTING
||
1950 client
-> state
== S_REBOOTING
)
1952 : (struct iaddr
*)0),
1953 client
-> config
-> requested_options
,
1954 &client
-> sent_options
);
1956 /* Set up the option buffer... */
1957 client
-> packet_length
=
1958 cons_options ((struct packet
*)0, &client
-> packet
,
1959 (struct lease
*)0, client
,
1960 /* maximum packet size */1500,
1961 (struct option_state
*)0,
1962 client
-> sent_options
,
1963 /* scope */ &global_scope
,
1967 (struct data_string
*)0,
1968 client
-> config
-> vendor_space_name
);
1970 if (client
-> packet_length
< BOOTP_MIN_LEN
)
1971 client
-> packet_length
= BOOTP_MIN_LEN
;
1973 client
-> packet
.op
= BOOTREQUEST
;
1974 client
-> packet
.htype
= client
-> interface
-> hw_address
.hbuf
[0];
1975 client
-> packet
.hlen
= client
-> interface
-> hw_address
.hlen
- 1;
1976 client
-> packet
.hops
= 0;
1977 client
-> packet
.xid
= client
-> xid
;
1978 client
-> packet
.secs
= 0; /* Filled in by send_request. */
1980 /* If we own the address we're requesting, put it in ciaddr;
1981 otherwise set ciaddr to zero. */
1982 if (client
-> state
== S_BOUND
||
1983 client
-> state
== S_RENEWING
||
1984 client
-> state
== S_REBINDING
) {
1985 memcpy (&client
-> packet
.ciaddr
,
1986 lease
-> address
.iabuf
, lease
-> address
.len
);
1987 client
-> packet
.flags
= 0;
1989 memset (&client
-> packet
.ciaddr
, 0,
1990 sizeof client
-> packet
.ciaddr
);
1991 if (can_receive_unicast_unconfigured (client
-> interface
))
1992 client
-> packet
.flags
= 0;
1994 client
-> packet
.flags
= htons (BOOTP_BROADCAST
);
1997 memset (&client
-> packet
.yiaddr
, 0,
1998 sizeof client
-> packet
.yiaddr
);
1999 memset (&client
-> packet
.siaddr
, 0,
2000 sizeof client
-> packet
.siaddr
);
2001 if (client
-> state
!= S_BOUND
&&
2002 client
-> state
!= S_RENEWING
)
2003 client
-> packet
.giaddr
= giaddr
;
2005 memset (&client
-> packet
.giaddr
, 0,
2006 sizeof client
-> packet
.giaddr
);
2007 if (client
-> interface
-> hw_address
.hlen
> 0)
2008 memcpy (client
-> packet
.chaddr
,
2009 &client
-> interface
-> hw_address
.hbuf
[1],
2010 (unsigned)(client
-> interface
-> hw_address
.hlen
- 1));
2013 dump_raw ((unsigned char *)&client
-> packet
, client
-> packet_length
);
2017 void make_decline (client
, lease
)
2018 struct client_state
*client
;
2019 struct client_lease
*lease
;
2021 unsigned char decline
= DHCPDECLINE
;
2023 struct option_cache
*oc
;
2025 struct option_state
*options
= (struct option_state
*)0;
2027 oc
= lookup_option (&dhcp_universe
, lease
-> options
,
2028 DHO_DHCP_SERVER_IDENTIFIER
);
2029 make_client_options (client
, lease
, &decline
, oc
,
2030 &lease
-> address
, (u_int32_t
*)0, &options
);
2032 /* Set up the option buffer... */
2033 memset (&client
-> packet
, 0, sizeof (client
-> packet
));
2034 client
-> packet_length
=
2035 cons_options ((struct packet
*)0, &client
-> packet
,
2036 (struct lease
*)0, client
, 0,
2037 (struct option_state
*)0, options
,
2038 &global_scope
, 0, 0, 0, (struct data_string
*)0,
2039 client
-> config
-> vendor_space_name
);
2040 option_state_dereference (&options
, MDL
);
2041 if (client
-> packet_length
< BOOTP_MIN_LEN
)
2042 client
-> packet_length
= BOOTP_MIN_LEN
;
2043 option_state_dereference (&options
, MDL
);
2045 client
-> packet
.op
= BOOTREQUEST
;
2046 client
-> packet
.htype
= client
-> interface
-> hw_address
.hbuf
[0];
2047 client
-> packet
.hlen
= client
-> interface
-> hw_address
.hlen
- 1;
2048 client
-> packet
.hops
= 0;
2049 client
-> packet
.xid
= client
-> xid
;
2050 client
-> packet
.secs
= 0; /* Filled in by send_request. */
2051 if (can_receive_unicast_unconfigured (client
-> interface
))
2052 client
-> packet
.flags
= 0;
2054 client
-> packet
.flags
= htons (BOOTP_BROADCAST
);
2056 /* ciaddr must always be zero. */
2057 memset (&client
-> packet
.ciaddr
, 0,
2058 sizeof client
-> packet
.ciaddr
);
2059 memset (&client
-> packet
.yiaddr
, 0,
2060 sizeof client
-> packet
.yiaddr
);
2061 memset (&client
-> packet
.siaddr
, 0,
2062 sizeof client
-> packet
.siaddr
);
2063 client
-> packet
.giaddr
= giaddr
;
2064 memcpy (client
-> packet
.chaddr
,
2065 &client
-> interface
-> hw_address
.hbuf
[1],
2066 client
-> interface
-> hw_address
.hlen
);
2069 dump_raw ((unsigned char *)&client
-> packet
, client
-> packet_length
);
2073 void make_release (client
, lease
)
2074 struct client_state
*client
;
2075 struct client_lease
*lease
;
2077 unsigned char request
= DHCPRELEASE
;
2079 struct option_cache
*oc
;
2081 struct option_state
*options
= (struct option_state
*)0;
2083 memset (&client
-> packet
, 0, sizeof (client
-> packet
));
2085 oc
= lookup_option (&dhcp_universe
, lease
-> options
,
2086 DHO_DHCP_SERVER_IDENTIFIER
);
2087 make_client_options (client
, lease
, &request
, oc
,
2088 (struct iaddr
*)0, (u_int32_t
*)0,
2091 /* Set up the option buffer... */
2092 client
-> packet_length
=
2093 cons_options ((struct packet
*)0, &client
-> packet
,
2094 (struct lease
*)0, client
,
2095 /* maximum packet size */1500,
2096 (struct option_state
*)0,
2098 /* scope */ &global_scope
,
2102 (struct data_string
*)0,
2103 client
-> config
-> vendor_space_name
);
2105 if (client
-> packet_length
< BOOTP_MIN_LEN
)
2106 client
-> packet_length
= BOOTP_MIN_LEN
;
2107 option_state_dereference (&options
, MDL
);
2109 client
-> packet
.op
= BOOTREQUEST
;
2110 client
-> packet
.htype
= client
-> interface
-> hw_address
.hbuf
[0];
2111 client
-> packet
.hlen
= client
-> interface
-> hw_address
.hlen
- 1;
2112 client
-> packet
.hops
= 0;
2113 client
-> packet
.xid
= random ();
2114 client
-> packet
.secs
= 0;
2115 client
-> packet
.flags
= 0;
2116 memcpy (&client
-> packet
.ciaddr
,
2117 lease
-> address
.iabuf
, lease
-> address
.len
);
2118 memset (&client
-> packet
.yiaddr
, 0,
2119 sizeof client
-> packet
.yiaddr
);
2120 memset (&client
-> packet
.siaddr
, 0,
2121 sizeof client
-> packet
.siaddr
);
2122 client
-> packet
.giaddr
= giaddr
;
2123 memcpy (client
-> packet
.chaddr
,
2124 &client
-> interface
-> hw_address
.hbuf
[1],
2125 client
-> interface
-> hw_address
.hlen
);
2128 dump_raw ((unsigned char *)&client
-> packet
, client
-> packet_length
);
2132 void destroy_client_lease (lease
)
2133 struct client_lease
*lease
;
2137 if (lease
-> server_name
)
2138 dfree (lease
-> server_name
, MDL
);
2139 if (lease
-> filename
)
2140 dfree (lease
-> filename
, MDL
);
2141 option_state_dereference (&lease
-> options
, MDL
);
2142 free_client_lease (lease
, MDL
);
2147 void rewrite_client_leases ()
2149 struct interface_info
*ip
;
2150 struct client_state
*client
;
2151 struct client_lease
*lp
;
2155 leaseFile
= fopen (path_dhclient_db
, "w");
2157 log_error ("can't create %s: %m", path_dhclient_db
);
2161 /* Write out all the leases attached to configured interfaces that
2163 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
2164 for (client
= ip
-> client
; client
; client
= client
-> next
) {
2165 for (lp
= client
-> leases
; lp
; lp
= lp
-> next
) {
2166 write_client_lease (client
, lp
, 1, 0);
2168 if (client
-> active
)
2169 write_client_lease (client
,
2170 client
-> active
, 1, 0);
2174 /* Write out any leases that are attached to interfaces that aren't
2175 currently configured. */
2176 for (ip
= dummy_interfaces
; ip
; ip
= ip
-> next
) {
2177 for (client
= ip
-> client
; client
; client
= client
-> next
) {
2178 for (lp
= client
-> leases
; lp
; lp
= lp
-> next
) {
2179 write_client_lease (client
, lp
, 1, 0);
2181 if (client
-> active
)
2182 write_client_lease (client
,
2183 client
-> active
, 1, 0);
2189 void write_lease_option (struct option_cache
*oc
,
2190 struct packet
*packet
, struct lease
*lease
,
2191 struct client_state
*client_state
,
2192 struct option_state
*in_options
,
2193 struct option_state
*cfg_options
,
2194 struct binding_scope
**scope
,
2195 struct universe
*u
, void *stuff
)
2197 const char *name
, *dot
;
2198 struct data_string ds
;
2200 struct client_state
*client
;
2202 memset (&ds
, 0, sizeof ds
);
2204 if (u
!= &dhcp_universe
) {
2211 if (evaluate_option_cache (&ds
, packet
, lease
, client_state
,
2212 in_options
, cfg_options
, scope
, oc
, MDL
)) {
2214 " option %s%s%s %s;\n",
2215 name
, dot
, oc
-> option
-> name
,
2216 pretty_print_option (oc
-> option
,
2217 ds
.data
, ds
.len
, 1, 1));
2218 data_string_forget (&ds
, MDL
);
2222 int write_client_lease (client
, lease
, rewrite
, makesure
)
2223 struct client_state
*client
;
2224 struct client_lease
*lease
;
2230 static int leases_written
;
2231 struct option_cache
*oc
;
2232 struct data_string ds
;
2238 if (leases_written
++ > 20) {
2239 rewrite_client_leases ();
2244 /* If the lease came from the config file, we don't need to stash
2245 a copy in the lease database. */
2246 if (lease
-> is_static
)
2249 if (!leaseFile
) { /* XXX */
2250 leaseFile
= fopen (path_dhclient_db
, "w");
2252 log_error ("can't create %s: %m", path_dhclient_db
);
2258 fprintf (leaseFile
, "lease {\n");
2259 if (lease
-> is_bootp
) {
2260 fprintf (leaseFile
, " bootp;\n");
2266 fprintf (leaseFile
, " interface \"%s\";\n",
2267 client
-> interface
-> name
);
2272 if (client
-> name
) {
2273 fprintf (leaseFile
, " name \"%s\";\n", client
-> name
);
2279 fprintf (leaseFile
, " fixed-address %s;\n",
2280 piaddr (lease
-> address
));
2285 if (lease
-> filename
) {
2286 s
= quotify_string (lease
-> filename
, MDL
);
2288 fprintf (leaseFile
, " filename \"%s\";\n", s
);
2298 if (lease
-> server_name
) {
2299 s
= quotify_string (lease
-> filename
, MDL
);
2301 fprintf (leaseFile
, " server-name \"%s\";\n", s
);
2310 if (lease
-> medium
) {
2311 s
= quotify_string (lease
-> medium
-> string
, MDL
);
2313 fprintf (leaseFile
, " medium \"%s\";\n", s
);
2327 memset (&ds
, 0, sizeof ds
);
2329 for (i
= 0; i
< lease
-> options
-> universe_count
; i
++) {
2330 option_space_foreach ((struct packet
*)0, (struct lease
*)0,
2331 client
, (struct option_state
*)0,
2332 lease
-> options
, &global_scope
,
2334 client
, write_lease_option
);
2337 /* Note: the following is not a Y2K bug - it's a Y1.9K bug. Until
2338 somebody invents a time machine, I think we can safely disregard
2340 t
= gmtime (&lease
-> renewal
);
2342 " renew %d %d/%d/%d %02d:%02d:%02d;\n",
2343 t
-> tm_wday
, t
-> tm_year
+ 1900,
2344 t
-> tm_mon
+ 1, t
-> tm_mday
,
2345 t
-> tm_hour
, t
-> tm_min
, t
-> tm_sec
);
2350 t
= gmtime (&lease
-> rebind
);
2352 " rebind %d %d/%d/%d %02d:%02d:%02d;\n",
2353 t
-> tm_wday
, t
-> tm_year
+ 1900,
2354 t
-> tm_mon
+ 1, t
-> tm_mday
,
2355 t
-> tm_hour
, t
-> tm_min
, t
-> tm_sec
);
2360 t
= gmtime (&lease
-> expiry
);
2362 " expire %d %d/%d/%d %02d:%02d:%02d;\n",
2363 t
-> tm_wday
, t
-> tm_year
+ 1900,
2364 t
-> tm_mon
+ 1, t
-> tm_mday
,
2365 t
-> tm_hour
, t
-> tm_min
, t
-> tm_sec
);
2370 fprintf (leaseFile
, "}\n");
2380 if (!errors
&& makesure
) {
2381 if (fsync (fileno (leaseFile
)) < 0) {
2382 log_info ("write_client_lease: %m");
2386 return errors
? 0 : 1;
2389 /* Variables holding name of script and file pointer for writing to
2390 script. Needless to say, this is not reentrant - only one script
2391 can be invoked at a time. */
2392 char scriptName
[256];
2395 void script_init (client
, reason
, medium
)
2396 struct client_state
*client
;
2398 struct string_list
*medium
;
2400 struct string_list
*sl
, *next
;
2403 for (sl
= client
-> env
; sl
; sl
= next
) {
2407 client
-> env
= (struct string_list
*)0;
2410 if (client
-> interface
) {
2411 client_envadd (client
, "", "interface", "%s",
2412 client
-> interface
-> name
);
2415 client_envadd (client
,
2416 "", "client", "%s", client
-> name
);
2418 client_envadd (client
,
2419 "", "medium", "%s", medium
-> string
);
2421 client_envadd (client
, "", "reason", "%s", reason
);
2422 client_envadd (client
, "", "pid", "%ld", (long int)getpid ());
2426 struct envadd_state
{
2427 struct client_state
*client
;
2431 void client_option_envadd (struct option_cache
*oc
,
2432 struct packet
*packet
, struct lease
*lease
,
2433 struct client_state
*client_state
,
2434 struct option_state
*in_options
,
2435 struct option_state
*cfg_options
,
2436 struct binding_scope
**scope
,
2437 struct universe
*u
, void *stuff
)
2439 struct envadd_state
*es
= stuff
;
2440 struct data_string data
;
2441 memset (&data
, 0, sizeof data
);
2443 if (evaluate_option_cache (&data
, packet
, lease
, client_state
,
2444 in_options
, cfg_options
, scope
, oc
, MDL
)) {
2447 if (dhcp_option_ev_name (name
, sizeof name
,
2449 client_envadd (es
-> client
, es
-> prefix
,
2451 (pretty_print_option
2453 data
.data
, data
.len
,
2455 data_string_forget (&data
, MDL
);
2461 void script_write_params (client
, prefix
, lease
)
2462 struct client_state
*client
;
2464 struct client_lease
*lease
;
2467 struct data_string data
;
2468 struct option_cache
*oc
;
2471 struct envadd_state es
;
2476 client_envadd (client
,
2477 prefix
, "ip_address", "%s", piaddr (lease
-> address
));
2479 /* For the benefit of Linux (and operating systems which may
2480 have similar needs), compute the network address based on
2481 the supplied ip address and netmask, if provided. Also
2482 compute the broadcast address (the host address all ones
2483 broadcast address, not the host address all zeroes
2484 broadcast address). */
2486 memset (&data
, 0, sizeof data
);
2487 oc
= lookup_option (&dhcp_universe
, lease
-> options
, DHO_SUBNET_MASK
);
2488 if (oc
&& evaluate_option_cache (&data
, (struct packet
*)0,
2489 (struct lease
*)0, client
,
2490 (struct option_state
*)0,
2492 &global_scope
, oc
, MDL
)) {
2494 struct iaddr netmask
, subnet
, broadcast
;
2496 memcpy (netmask
.iabuf
, data
.data
, data
.len
);
2497 netmask
.len
= data
.len
;
2498 data_string_forget (&data
, MDL
);
2500 subnet
= subnet_number (lease
-> address
, netmask
);
2502 client_envadd (client
, prefix
, "network_number",
2503 "%s", piaddr (subnet
));
2505 oc
= lookup_option (&dhcp_universe
,
2507 DHO_BROADCAST_ADDRESS
);
2509 !(evaluate_option_cache
2510 (&data
, (struct packet
*)0,
2511 (struct lease
*)0, client
,
2512 (struct option_state
*)0,
2514 &global_scope
, oc
, MDL
))) {
2515 broadcast
= broadcast_addr (subnet
, netmask
);
2516 if (broadcast
.len
) {
2517 client_envadd (client
,
2518 prefix
, "broadcast_address",
2519 "%s", piaddr (broadcast
));
2524 data_string_forget (&data
, MDL
);
2527 if (lease
-> filename
)
2528 client_envadd (client
,
2529 prefix
, "filename", "%s", lease
-> filename
);
2530 if (lease
-> server_name
)
2531 client_envadd (client
, prefix
, "server_name",
2532 "%s", lease
-> server_name
);
2534 for (i
= 0; i
< lease
-> options
-> universe_count
; i
++) {
2535 option_space_foreach ((struct packet
*)0, (struct lease
*)0,
2536 client
, (struct option_state
*)0,
2537 lease
-> options
, &global_scope
,
2539 &es
, client_option_envadd
);
2541 client_envadd (client
, prefix
, "expiry", "%d", (int)(lease
-> expiry
));
2544 int script_go (client
)
2545 struct client_state
*client
;
2552 char reason
[] = "REASON=NBI";
2553 static char client_path
[] = CLIENT_PATH
;
2555 struct string_list
*sp
, *next
;
2556 int pid
, wpid
, wstatus
;
2559 scriptName
= client
-> config
-> script_name
;
2561 scriptName
= top_level_config
.script_name
;
2563 envp
= dmalloc (((client
? client
-> envc
: 2) +
2564 client_env_count
+ 2) * sizeof (char *), MDL
);
2566 log_error ("No memory for client script environment.");
2570 /* Copy out the environment specified on the command line,
2572 for (sp
= client_env
; sp
; sp
= sp
-> next
) {
2573 envp
[i
++] = sp
-> string
;
2575 /* Copy out the environment specified by dhclient. */
2577 for (sp
= client
-> env
; sp
; sp
= sp
-> next
) {
2578 envp
[i
++] = sp
-> string
;
2581 envp
[i
++] = reason
;
2584 envp
[i
++] = client_path
;
2585 envp
[i
] = (char *)0;
2587 argv
[0] = scriptName
;
2588 argv
[1] = (char *)0;
2592 log_error ("fork: %m");
2596 wpid
= wait (&wstatus
);
2597 } while (wpid
!= pid
&& wpid
> 0);
2599 log_error ("wait: %m");
2603 execve (scriptName
, argv
, envp
);
2604 log_error ("execve (%s, ...): %m", scriptName
);
2609 for (sp
= client
-> env
; sp
; sp
= next
) {
2613 client
-> env
= (struct string_list
*)0;
2617 GET_TIME (&cur_time
);
2618 return (WIFEXITED (wstatus
) ?
2619 WEXITSTATUS (wstatus
) : -WTERMSIG (wstatus
));
2622 void client_envadd (struct client_state
*client
,
2623 const char *prefix
, const char *name
, const char *fmt
, ...)
2628 struct string_list
*val
;
2631 va_start (list
, fmt
);
2632 len
= vsnprintf (spbuf
, sizeof spbuf
, fmt
, list
);
2635 val
= dmalloc (strlen (prefix
) + strlen (name
) + 1 /* = */ +
2636 len
+ sizeof *val
, MDL
);
2644 if (len
>= sizeof spbuf
) {
2645 va_start (list
, fmt
);
2646 vsnprintf (s
, len
+ 1, fmt
, list
);
2650 val
-> next
= client
-> env
;
2651 client
-> env
= val
;
2655 int dhcp_option_ev_name (buf
, buflen
, option
)
2658 struct option
*option
;
2664 if (option
-> universe
!= &dhcp_universe
) {
2665 s
= option
-> universe
-> name
;
2674 if (j
+ 1 == buflen
)
2684 if (j
+ 1 == buflen
)
2697 static int state
= 0;
2701 /* Don't become a daemon if the user requested otherwise. */
2703 write_client_pid_file ();
2707 /* Only do it once. */
2712 /* Stop logging to stderr... */
2715 /* Become a daemon... */
2716 if ((pid
= fork ()) < 0)
2717 log_fatal ("Can't fork daemon: %m");
2720 /* Become session leader and get pid... */
2723 /* Close standard I/O descriptors. */
2728 /* Reopen them on /dev/null. */
2729 i
= open ("/dev/null", O_RDWR
);
2731 i
= open ("/dev/null", O_RDWR
);
2733 i
= open ("/dev/null", O_RDWR
);
2734 log_perror
= 0; /* No sense logging to /dev/null. */
2738 write_client_pid_file ();
2741 void write_client_pid_file ()
2746 pfdesc
= open (path_dhclient_pid
, O_CREAT
| O_TRUNC
| O_WRONLY
, 0644);
2749 log_error ("Can't create %s: %m", path_dhclient_pid
);
2753 pf
= fdopen (pfdesc
, "w");
2755 log_error ("Can't fdopen %s: %m", path_dhclient_pid
);
2757 fprintf (pf
, "%ld\n", (long)getpid ());
2762 void client_location_changed ()
2764 struct interface_info
*ip
;
2765 struct client_state
*client
;
2767 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
2768 for (client
= ip
-> client
; client
; client
= client
-> next
) {
2769 switch (client
-> state
) {
2771 cancel_timeout (send_discover
, client
);
2775 cancel_timeout (state_bound
, client
);
2781 cancel_timeout (send_request
, client
);
2789 client
-> state
= S_INIT
;
2790 state_reboot (client
);
2795 void do_release(client
)
2796 struct client_state
*client
;
2798 struct data_string ds
;
2799 struct option_cache
*oc
;
2801 /* Pick a random xid. */
2802 client
-> xid
= random ();
2804 /* is there even a lease to release? */
2805 if (client
-> active
) {
2806 /* Make a DHCPRELEASE packet, and set appropriate per-interface
2808 make_release (client
, client
-> active
);
2810 memset (&ds
, 0, sizeof ds
);
2811 oc
= lookup_option (&dhcp_universe
,
2812 client
-> active
-> options
,
2813 DHO_DHCP_SERVER_IDENTIFIER
);
2815 evaluate_option_cache (&ds
, (struct packet
*)0,
2816 (struct lease
*)0, client
,
2817 (struct option_state
*)0,
2818 client
-> active
-> options
,
2819 &global_scope
, oc
, MDL
)) {
2821 memcpy (client
-> destination
.iabuf
,
2823 client
-> destination
.len
= 4;
2825 client
-> destination
= iaddr_broadcast
;
2827 data_string_forget (&ds
, MDL
);
2829 client
-> destination
= iaddr_broadcast
;
2830 client
-> first_sending
= cur_time
;
2831 client
-> interval
= client
-> config
-> initial_interval
;
2833 /* Zap the medium list... */
2834 client
-> medium
= (struct string_list
*)0;
2836 /* Send out the first and only DHCPRELEASE packet. */
2837 send_release (client
);
2839 /* Do the client script RELEASE operation. */
2840 script_init (client
,
2841 "RELEASE", (struct string_list
*)0);
2842 if (client
-> alias
)
2843 script_write_params (client
, "alias_",
2845 script_write_params (client
, "old_", client
-> active
);
2849 /* Cancel any timeouts. */
2850 cancel_timeout (state_bound
, client
);
2851 cancel_timeout (send_discover
, client
);
2852 cancel_timeout (state_init
, client
);
2853 cancel_timeout (send_request
, client
);
2854 cancel_timeout (state_reboot
, client
);
2855 client
-> state
= S_STOPPED
;
2858 int dhclient_interface_shutdown_hook (struct interface_info
*interface
)
2860 do_release (interface
-> client
);
2865 int dhclient_interface_discovery_hook (struct interface_info
*tmp
)
2867 struct interface_info
*last
, *ip
;
2868 /* See if we can find the client from dummy_interfaces */
2870 for (ip
= dummy_interfaces
; ip
; ip
= ip
-> next
) {
2871 if (!strcmp (ip
-> name
, tmp
-> name
)) {
2872 /* Remove from dummy_interfaces */
2874 ip
= (struct interface_info
*)0;
2875 interface_reference (&ip
, last
-> next
, MDL
);
2876 interface_dereference (&last
-> next
, MDL
);
2878 interface_reference (&last
-> next
,
2880 interface_dereference (&ip
-> next
,
2884 ip
= (struct interface_info
*)0;
2885 interface_reference (&ip
,
2886 dummy_interfaces
, MDL
);
2887 interface_dereference (&dummy_interfaces
, MDL
);
2889 interface_reference (&dummy_interfaces
,
2891 interface_dereference (&ip
-> next
,
2895 /* Copy "client" to tmp */
2897 tmp
-> client
= ip
-> client
;
2898 tmp
-> client
-> interface
= tmp
;
2900 interface_dereference (&ip
, MDL
);
2908 isc_result_t
dhclient_interface_startup_hook (struct interface_info
*interface
)
2910 struct interface_info
*ip
;
2911 struct client_state
*client
;
2913 /* This code needs some rethinking. It doesn't test against
2914 a signal name, and it just kind of bulls into doing something
2915 that may or may not be appropriate. */
2918 interface_reference (&interface
-> next
, interfaces
, MDL
);
2919 interface_dereference (&interfaces
, MDL
);
2921 interface_reference (&interfaces
, interface
, MDL
);
2923 discover_interfaces (DISCOVER_UNCONFIGURED
);
2925 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
2926 /* If interfaces were specified, don't configure
2927 interfaces that weren't specified! */
2928 if (ip
-> flags
& INTERFACE_RUNNING
||
2929 (ip
-> flags
& (INTERFACE_REQUESTED
|
2930 INTERFACE_AUTOMATIC
)) !=
2931 INTERFACE_REQUESTED
)
2933 script_init (ip
-> client
,
2934 "PREINIT", (struct string_list
*)0);
2935 if (ip
-> client
-> alias
)
2936 script_write_params (ip
-> client
, "alias_",
2937 ip
-> client
-> alias
);
2938 script_go (ip
-> client
);
2941 discover_interfaces (interfaces_requested
2942 ? DISCOVER_REQUESTED
2943 : DISCOVER_RUNNING
);
2945 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
2946 if (ip
-> flags
& INTERFACE_RUNNING
)
2948 ip
-> flags
|= INTERFACE_RUNNING
;
2949 for (client
= ip
-> client
; client
; client
= client
-> next
) {
2950 client
-> state
= S_INIT
;
2951 /* Set up a timeout to start the initialization
2953 add_timeout (cur_time
+ random () % 5,
2954 state_reboot
, client
, 0, 0);
2957 return ISC_R_SUCCESS
;
2960 /* The client should never receive a relay agent information option,
2961 so if it does, log it and discard it. */
2963 int parse_agent_information_option (packet
, len
, data
)
2964 struct packet
*packet
;
2971 /* The client never sends relay agent information options. */
2973 unsigned cons_agent_information_options (cfg_options
, outpacket
,
2975 struct option_state
*cfg_options
;
2976 struct dhcp_packet
*outpacket
;
2983 static void shutdown_exit (void *foo
)
2988 isc_result_t
dhcp_set_control_state (control_object_state_t oldstate
,
2989 control_object_state_t newstate
)
2991 struct interface_info
*ip
;
2992 struct client_state
*client
;
2994 /* Do the right thing for each interface. */
2995 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
2996 for (client
= ip
-> client
; client
; client
= client
-> next
) {
2998 case server_startup
:
2999 return ISC_R_SUCCESS
;
3001 case server_running
:
3002 return ISC_R_SUCCESS
;
3004 case server_shutdown
:
3005 if (client
-> active
&&
3006 client
-> active
-> expiry
> cur_time
) {
3007 if (client
-> config
-> do_forward_update
)
3008 client_dns_update (client
, 0, 0);
3009 do_release (client
);
3013 case server_hibernate
:
3014 state_stop (client
);
3018 state_reboot (client
);
3023 if (newstate
== server_shutdown
)
3024 add_timeout (cur_time
+ 1, shutdown_exit
, 0, 0, 0);
3025 return ISC_R_SUCCESS
;
3028 /* Called after a timeout if the DNS update failed on the previous try.
3029 Retries the update, and if it times out, schedules a retry after
3030 ten times as long of a wait. */
3032 void client_dns_update_timeout (void *cp
)
3034 struct client_state
*client
= cp
;
3035 isc_result_t status
;
3037 if (client
-> active
) {
3038 status
= client_dns_update (client
, 1,
3039 (client
-> active
-> renewal
-
3041 if (status
== ISC_R_TIMEDOUT
) {
3042 client
-> dns_update_timeout
*= 10;
3043 add_timeout (cur_time
+ client
-> dns_update_timeout
,
3044 client_dns_update_timeout
, client
, 0, 0);
3049 /* See if we should do a DNS update, and if so, do it. */
3051 isc_result_t
client_dns_update (struct client_state
*client
, int addp
, int ttl
)
3053 struct data_string ddns_fqdn
, ddns_fwd_name
,
3054 ddns_dhcid
, client_identifier
;
3055 struct option_cache
*oc
;
3060 /* If we didn't send an FQDN option, we certainly aren't going to
3061 be doing an update. */
3062 if (!client
-> sent_options
)
3063 return ISC_R_SUCCESS
;
3065 /* If we don't have a lease, we can't do an update. */
3066 if (!client
-> active
)
3067 return ISC_R_SUCCESS
;
3069 /* If we set the no client update flag, don't do the update. */
3070 if ((oc
= lookup_option (&fqdn_universe
, client
-> sent_options
,
3071 FQDN_NO_CLIENT_UPDATE
)) &&
3072 evaluate_boolean_option_cache (&ignorep
, (struct packet
*)0,
3073 (struct lease
*)0, client
,
3074 client
-> sent_options
,
3075 (struct option_state
*)0,
3076 &global_scope
, oc
, MDL
))
3077 return ISC_R_SUCCESS
;
3079 /* If we set the "server, please update" flag, or didn't set it
3080 to false, don't do the update. */
3081 if (!(oc
= lookup_option (&fqdn_universe
, client
-> sent_options
,
3082 FQDN_SERVER_UPDATE
)) ||
3083 evaluate_boolean_option_cache (&ignorep
, (struct packet
*)0,
3084 (struct lease
*)0, client
,
3085 client
-> sent_options
,
3086 (struct option_state
*)0,
3087 &global_scope
, oc
, MDL
))
3088 return ISC_R_SUCCESS
;
3090 /* If no FQDN option was supplied, don't do the update. */
3091 memset (&ddns_fwd_name
, 0, sizeof ddns_fwd_name
);
3092 if (!(oc
= lookup_option (&fqdn_universe
, client
-> sent_options
,
3094 !evaluate_option_cache (&ddns_fwd_name
, (struct packet
*)0,
3095 (struct lease
*)0, client
,
3096 client
-> sent_options
,
3097 (struct option_state
*)0,
3098 &global_scope
, oc
, MDL
))
3099 return ISC_R_SUCCESS
;
3101 /* Make a dhcid string out of either the client identifier,
3102 if we are sending one, or the interface's MAC address,
3104 memset (&ddns_dhcid
, 0, sizeof ddns_dhcid
);
3106 memset (&client_identifier
, 0, sizeof client_identifier
);
3107 if ((oc
= lookup_option (&dhcp_universe
, client
-> sent_options
,
3108 DHO_DHCP_CLIENT_IDENTIFIER
)) &&
3109 evaluate_option_cache (&client_identifier
, (struct packet
*)0,
3110 (struct lease
*)0, client
,
3111 client
-> sent_options
,
3112 (struct option_state
*)0,
3113 &global_scope
, oc
, MDL
)) {
3114 result
= get_dhcid (&ddns_dhcid
,
3115 DHO_DHCP_CLIENT_IDENTIFIER
,
3116 client_identifier
.data
,
3117 client_identifier
.len
);
3118 data_string_forget (&client_identifier
, MDL
);
3120 result
= get_dhcid (&ddns_dhcid
, 0,
3121 client
-> interface
-> hw_address
.hbuf
,
3122 client
-> interface
-> hw_address
.hlen
);
3124 data_string_forget (&ddns_fwd_name
, MDL
);
3125 return ISC_R_SUCCESS
;
3128 /* Start the resolver, if necessary. */
3129 if (!resolver_inited
) {
3130 minires_ninit (&resolver_state
);
3131 resolver_inited
= 1;
3132 resolver_state
.retrans
= 1;
3133 resolver_state
.retry
= 1;
3139 if (ddns_fwd_name
.len
&& ddns_dhcid
.len
) {
3141 rcode
= ddns_update_a (&ddns_fwd_name
,
3142 client
-> active
-> address
,
3146 rcode
= ddns_remove_a (&ddns_fwd_name
,
3147 client
-> active
-> address
,
3150 rcode
= ISC_R_FAILURE
;
3152 data_string_forget (&ddns_fwd_name
, MDL
);
3153 data_string_forget (&ddns_dhcid
, MDL
);