6 * Copyright (c) 2004 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.129.2.23 2004/11/24 17:39:14 dhankins Exp $ Copyright (c) 2004 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 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 (max %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
=
794 (((client
-> new -> renewal
+ 3) * 3 / 4) +
795 (random () % /* XXX NUMS */
796 ((client
-> new -> renewal
+ 3) / 4)));
798 /* Same deal with the rebind time. */
799 oc
= lookup_option (&dhcp_universe
, client
-> new -> options
,
800 DHO_DHCP_REBINDING_TIME
);
802 evaluate_option_cache (&ds
, packet
, (struct lease
*)0, client
,
803 packet
-> options
, client
-> new -> options
,
804 &global_scope
, oc
, MDL
)) {
806 client
-> new -> rebind
= getULong (ds
.data
);
808 client
-> new -> rebind
= 0;
809 data_string_forget (&ds
, MDL
);
811 client
-> new -> rebind
= 0;
813 if (client
-> new -> rebind
<= 0) {
814 if (client
-> new -> expiry
<= TIME_MAX
/ 7)
815 client
-> new -> rebind
=
816 client
-> new -> expiry
* 7 / 8;
818 client
-> new -> rebind
=
819 client
-> new -> expiry
/ 8 * 7;
822 /* Make sure our randomness didn't run the renewal time past the
824 if (client
-> new -> renewal
> client
-> new -> rebind
) {
825 if (client
-> new -> rebind
<= TIME_MAX
/ 3)
826 client
-> new -> renewal
=
827 client
-> new -> rebind
* 3 / 4;
829 client
-> new -> renewal
=
830 client
-> new -> rebind
/ 4 * 3;
833 client
-> new -> expiry
+= cur_time
;
834 /* Lease lengths can never be negative. */
835 if (client
-> new -> expiry
< cur_time
)
836 client
-> new -> expiry
= TIME_MAX
;
837 client
-> new -> renewal
+= cur_time
;
838 if (client
-> new -> renewal
< cur_time
)
839 client
-> new -> renewal
= TIME_MAX
;
840 client
-> new -> rebind
+= cur_time
;
841 if (client
-> new -> rebind
< cur_time
)
842 client
-> new -> rebind
= TIME_MAX
;
847 void bind_lease (client
)
848 struct client_state
*client
;
850 struct interface_info
*ip
= client
-> interface
;
852 /* Remember the medium. */
853 client
-> new -> medium
= client
-> medium
;
855 /* Run the client script with the new parameters. */
856 script_init (client
, (client
-> state
== S_REQUESTING
858 : (client
-> state
== S_RENEWING
860 : (client
-> state
== S_REBOOTING
861 ? "REBOOT" : "REBIND"))),
862 client
-> new -> medium
);
863 if (client
-> active
&& client
-> state
!= S_REBOOTING
)
864 script_write_params (client
, "old_", client
-> active
);
865 script_write_params (client
, "new_", client
-> new);
867 script_write_params (client
, "alias_", client
-> alias
);
869 /* If the BOUND/RENEW code detects another machine using the
870 offered address, it exits nonzero. We need to send a
871 DHCPDECLINE and toss the lease. */
872 if (script_go (client
)) {
873 make_decline (client
, client
-> new);
874 send_decline (client
);
875 destroy_client_lease (client
-> new);
876 client
-> new = (struct client_lease
*)0;
881 /* Write out the new lease. */
882 write_client_lease (client
, client
-> new, 0, 0);
884 /* Replace the old active lease with the new one. */
885 if (client
-> active
)
886 destroy_client_lease (client
-> active
);
887 client
-> active
= client
-> new;
888 client
-> new = (struct client_lease
*)0;
890 /* Set up a timeout to start the renewal process. */
891 add_timeout (client
-> active
-> renewal
,
892 state_bound
, client
, 0, 0);
894 log_info ("bound to %s -- renewal in %ld seconds.",
895 piaddr (client
-> active
-> address
),
896 (long)(client
-> active
-> renewal
- cur_time
));
897 client
-> state
= S_BOUND
;
898 reinitialize_interfaces ();
900 if (client
-> config
-> do_forward_update
) {
901 client
-> dns_update_timeout
= 1;
902 add_timeout (cur_time
+ 1, client_dns_update_timeout
,
907 /* state_bound is called when we've successfully bound to a particular
908 lease, but the renewal time on that lease has expired. We are
909 expected to unicast a DHCPREQUEST to the server that gave us our
912 void state_bound (cpp
)
915 struct client_state
*client
= cpp
;
917 struct option_cache
*oc
;
918 struct data_string ds
;
920 ASSERT_STATE(state
, S_BOUND
);
922 /* T1 has expired. */
923 make_request (client
, client
-> active
);
924 client
-> xid
= client
-> packet
.xid
;
926 memset (&ds
, 0, sizeof ds
);
927 oc
= lookup_option (&dhcp_universe
, client
-> active
-> options
,
928 DHO_DHCP_SERVER_IDENTIFIER
);
930 evaluate_option_cache (&ds
, (struct packet
*)0, (struct lease
*)0,
931 client
, (struct option_state
*)0,
932 client
-> active
-> options
,
933 &global_scope
, oc
, MDL
)) {
935 memcpy (client
-> destination
.iabuf
, ds
.data
, 4);
936 client
-> destination
.len
= 4;
938 client
-> destination
= iaddr_broadcast
;
940 data_string_forget (&ds
, MDL
);
942 client
-> destination
= iaddr_broadcast
;
944 client
-> first_sending
= cur_time
;
945 client
-> interval
= client
-> config
-> initial_interval
;
946 client
-> state
= S_RENEWING
;
948 /* Send the first packet immediately. */
949 send_request (client
);
952 /* state_stop is called when we've been told to shut down. We unconfigure
953 the interfaces, and then stop operating until told otherwise. */
955 void state_stop (cpp
)
958 struct client_state
*client
= cpp
;
961 /* Cancel all timeouts. */
962 cancel_timeout (state_selecting
, client
);
963 cancel_timeout (send_discover
, client
);
964 cancel_timeout (send_request
, client
);
965 cancel_timeout (state_bound
, client
);
967 /* If we have an address, unconfigure it. */
968 if (client
-> active
) {
969 script_init (client
, "STOP", client
-> active
-> medium
);
970 script_write_params (client
, "old_", client
-> active
);
972 script_write_params (client
, "alias_",
983 int write_lease (lease
)
989 int write_host (host
)
990 struct host_decl
*host
;
995 void db_startup (testp
)
1001 struct packet
*packet
;
1003 struct iaddrlist
*ap
;
1005 if (packet
-> raw
-> op
!= BOOTREPLY
)
1008 /* If there's a reject list, make sure this packet's sender isn't
1010 for (ap
= packet
-> interface
-> client
-> config
-> reject_list
;
1011 ap
; ap
= ap
-> next
) {
1012 if (addr_eq (packet
-> client_addr
, ap
-> addr
)) {
1013 log_info ("BOOTREPLY from %s rejected.",
1014 piaddr (ap
-> addr
));
1024 struct packet
*packet
;
1026 struct iaddrlist
*ap
;
1027 void (*handler
) PROTO ((struct packet
*));
1030 switch (packet
-> packet_type
) {
1032 handler
= dhcpoffer
;
1050 /* If there's a reject list, make sure this packet's sender isn't
1052 for (ap
= packet
-> interface
-> client
-> config
-> reject_list
;
1053 ap
; ap
= ap
-> next
) {
1054 if (addr_eq (packet
-> client_addr
, ap
-> addr
)) {
1055 log_info ("%s from %s rejected.",
1056 type
, piaddr (ap
-> addr
));
1060 (*handler
) (packet
);
1063 void dhcpoffer (packet
)
1064 struct packet
*packet
;
1066 struct interface_info
*ip
= packet
-> interface
;
1067 struct client_state
*client
;
1068 struct client_lease
*lease
, *lp
;
1071 const char *name
= packet
-> packet_type
? "DHCPOFFER" : "BOOTREPLY";
1072 struct iaddrlist
*ap
;
1073 struct option_cache
*oc
;
1077 dump_packet (packet
);
1080 /* Find a client state that matches the xid... */
1081 for (client
= ip
-> client
; client
; client
= client
-> next
)
1082 if (client
-> xid
== packet
-> raw
-> xid
)
1085 /* If we're not receptive to an offer right now, or if the offer
1086 has an unrecognizable transaction id, then just drop it. */
1088 client
-> state
!= S_SELECTING
||
1089 (packet
-> interface
-> hw_address
.hlen
- 1 !=
1090 packet
-> raw
-> hlen
) ||
1091 (memcmp (&packet
-> interface
-> hw_address
.hbuf
[1],
1092 packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
))) {
1094 log_debug ("%s in wrong transaction.", name
);
1099 sprintf (obuf
, "%s from %s", name
, piaddr (packet
-> client_addr
));
1102 /* If this lease doesn't supply the minimum required parameters,
1104 if (client
-> config
-> required_options
) {
1105 for (i
= 0; client
-> config
-> required_options
[i
]; i
++) {
1107 (&dhcp_universe
, packet
-> options
,
1108 client
-> config
-> required_options
[i
])) {
1109 log_info ("%s: no %s option.",
1110 obuf
, (dhcp_universe
.options
1111 [client
-> config
-> required_options
[i
]]
1118 /* If we've already seen this lease, don't record it again. */
1119 for (lease
= client
-> offered_leases
; lease
; lease
= lease
-> next
) {
1120 if (lease
-> address
.len
== sizeof packet
-> raw
-> yiaddr
&&
1121 !memcmp (lease
-> address
.iabuf
,
1122 &packet
-> raw
-> yiaddr
, lease
-> address
.len
)) {
1123 log_debug ("%s: already seen.", obuf
);
1128 lease
= packet_to_lease (packet
, client
);
1130 log_info ("%s: packet_to_lease failed.", obuf
);
1134 /* If this lease was acquired through a BOOTREPLY, record that
1136 if (!packet
-> options_valid
|| !packet
-> packet_type
)
1137 lease
-> is_bootp
= 1;
1139 /* Record the medium under which this lease was offered. */
1140 lease
-> medium
= client
-> medium
;
1142 /* Figure out when we're supposed to stop selecting. */
1143 stop_selecting
= (client
-> first_sending
+
1144 client
-> config
-> select_interval
);
1146 /* If this is the lease we asked for, put it at the head of the
1147 list, and don't mess with the arp request timeout. */
1148 if (lease
-> address
.len
== client
-> requested_address
.len
&&
1149 !memcmp (lease
-> address
.iabuf
,
1150 client
-> requested_address
.iabuf
,
1151 client
-> requested_address
.len
)) {
1152 lease
-> next
= client
-> offered_leases
;
1153 client
-> offered_leases
= lease
;
1155 /* Put the lease at the end of the list. */
1156 lease
-> next
= (struct client_lease
*)0;
1157 if (!client
-> offered_leases
)
1158 client
-> offered_leases
= lease
;
1160 for (lp
= client
-> offered_leases
; lp
-> next
;
1167 /* If the selecting interval has expired, go immediately to
1168 state_selecting(). Otherwise, time out into
1169 state_selecting at the select interval. */
1170 if (stop_selecting
<= 0)
1171 state_selecting (client
);
1173 add_timeout (stop_selecting
, state_selecting
, client
, 0, 0);
1174 cancel_timeout (send_discover
, client
);
1176 log_info ("%s", obuf
);
1179 /* Allocate a client_lease structure and initialize it from the parameters
1180 in the specified packet. */
1182 struct client_lease
*packet_to_lease (packet
, client
)
1183 struct packet
*packet
;
1184 struct client_state
*client
;
1186 struct client_lease
*lease
;
1188 struct option_cache
*oc
;
1189 struct data_string data
;
1191 lease
= (struct client_lease
*)new_client_lease (MDL
);
1194 log_error ("packet_to_lease: no memory to record lease.\n");
1195 return (struct client_lease
*)0;
1198 memset (lease
, 0, sizeof *lease
);
1200 /* Copy the lease options. */
1201 option_state_reference (&lease
-> options
, packet
-> options
, MDL
);
1203 lease
-> address
.len
= sizeof (packet
-> raw
-> yiaddr
);
1204 memcpy (lease
-> address
.iabuf
, &packet
-> raw
-> yiaddr
,
1205 lease
-> address
.len
);
1207 memset (&data
, 0, sizeof data
);
1209 if (client
-> config
-> vendor_space_name
) {
1210 i
= DHO_VENDOR_ENCAPSULATED_OPTIONS
;
1212 /* See if there was a vendor encapsulation option. */
1213 oc
= lookup_option (&dhcp_universe
, lease
-> options
, i
);
1215 client
-> config
-> vendor_space_name
&&
1216 evaluate_option_cache (&data
, packet
,
1217 (struct lease
*)0, client
,
1218 packet
-> options
, lease
-> options
,
1219 &global_scope
, oc
, MDL
)) {
1221 parse_encapsulated_suboptions
1222 (packet
-> options
, &dhcp_options
[i
],
1223 data
.data
, data
.len
, &dhcp_universe
,
1224 client
-> config
-> vendor_space_name
1227 data_string_forget (&data
, MDL
);
1232 /* Figure out the overload flag. */
1233 oc
= lookup_option (&dhcp_universe
, lease
-> options
,
1234 DHO_DHCP_OPTION_OVERLOAD
);
1236 evaluate_option_cache (&data
, packet
, (struct lease
*)0, client
,
1237 packet
-> options
, lease
-> options
,
1238 &global_scope
, oc
, MDL
)) {
1243 data_string_forget (&data
, MDL
);
1247 /* If the server name was filled out, copy it. */
1248 if (!(i
& 2) && packet
-> raw
-> sname
[0]) {
1250 /* Don't count on the NUL terminator. */
1251 for (len
= 0; len
< 64; len
++)
1252 if (!packet
-> raw
-> sname
[len
])
1254 lease
-> server_name
= dmalloc (len
+ 1, MDL
);
1255 if (!lease
-> server_name
) {
1256 log_error ("dhcpoffer: no memory for filename.\n");
1257 destroy_client_lease (lease
);
1258 return (struct client_lease
*)0;
1260 memcpy (lease
-> server_name
,
1261 packet
-> raw
-> sname
, len
);
1262 lease
-> server_name
[len
] = 0;
1266 /* Ditto for the filename. */
1267 if (!(i
& 1) && packet
-> raw
-> file
[0]) {
1269 /* Don't count on the NUL terminator. */
1270 for (len
= 0; len
< 64; len
++)
1271 if (!packet
-> raw
-> file
[len
])
1273 lease
-> filename
= dmalloc (len
+ 1, MDL
);
1274 if (!lease
-> filename
) {
1275 log_error ("dhcpoffer: no memory for filename.\n");
1276 destroy_client_lease (lease
);
1277 return (struct client_lease
*)0;
1279 memcpy (lease
-> filename
,
1280 packet
-> raw
-> file
, len
);
1281 lease
-> filename
[len
] = 0;
1285 execute_statements_in_scope ((struct binding_value
**)0,
1286 (struct packet
*)packet
,
1287 (struct lease
*)0, client
,
1288 lease
-> options
, lease
-> options
,
1290 client
-> config
-> on_receipt
,
1296 void dhcpnak (packet
)
1297 struct packet
*packet
;
1299 struct interface_info
*ip
= packet
-> interface
;
1300 struct client_state
*client
;
1302 /* Find a client state that matches the xid... */
1303 for (client
= ip
-> client
; client
; client
= client
-> next
)
1304 if (client
-> xid
== packet
-> raw
-> xid
)
1307 /* If we're not receptive to an offer right now, or if the offer
1308 has an unrecognizable transaction id, then just drop it. */
1310 (packet
-> interface
-> hw_address
.hlen
- 1 !=
1311 packet
-> raw
-> hlen
) ||
1312 (memcmp (&packet
-> interface
-> hw_address
.hbuf
[1],
1313 packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
))) {
1315 log_debug ("DHCPNAK in wrong transaction.");
1320 if (client
-> state
!= S_REBOOTING
&&
1321 client
-> state
!= S_REQUESTING
&&
1322 client
-> state
!= S_RENEWING
&&
1323 client
-> state
!= S_REBINDING
) {
1325 log_debug ("DHCPNAK in wrong state.");
1330 log_info ("DHCPNAK from %s", piaddr (packet
-> client_addr
));
1332 if (!client
-> active
) {
1334 log_info ("DHCPNAK with no active lease.\n");
1339 destroy_client_lease (client
-> active
);
1340 client
-> active
= (struct client_lease
*)0;
1342 /* Stop sending DHCPREQUEST packets... */
1343 cancel_timeout (send_request
, client
);
1345 client
-> state
= S_INIT
;
1346 state_init (client
);
1349 /* Send out a DHCPDISCOVER packet, and set a timeout to send out another
1350 one after the right interval has expired. If we don't get an offer by
1351 the time we reach the panic interval, call the panic function. */
1353 void send_discover (cpp
)
1356 struct client_state
*client
= cpp
;
1362 /* Figure out how long it's been since we started transmitting. */
1363 interval
= cur_time
- client
-> first_sending
;
1365 /* If we're past the panic timeout, call the script and tell it
1366 we haven't found anything for this interface yet. */
1367 if (interval
> client
-> config
-> timeout
) {
1368 state_panic (client
);
1372 /* If we're selecting media, try the whole list before doing
1373 the exponential backoff, but if we've already received an
1374 offer, stop looping, because we obviously have it right. */
1375 if (!client
-> offered_leases
&&
1376 client
-> config
-> media
) {
1379 if (client
-> medium
) {
1380 client
-> medium
= client
-> medium
-> next
;
1383 if (!client
-> medium
) {
1385 log_fatal ("No valid media types for %s!",
1386 client
-> interface
-> name
);
1388 client
-> config
-> media
;
1392 log_info ("Trying medium \"%s\" %d",
1393 client
-> medium
-> string
, increase
);
1394 script_init (client
, "MEDIUM", client
-> medium
);
1395 if (script_go (client
)) {
1401 /* If we're supposed to increase the interval, do so. If it's
1402 currently zero (i.e., we haven't sent any packets yet), set
1403 it to initial_interval; otherwise, add to it a random number
1404 between zero and two times itself. On average, this means
1405 that it will double with every transmission. */
1407 if (!client
-> interval
)
1408 client
-> interval
=
1409 client
-> config
-> initial_interval
;
1411 client
-> interval
+= ((random () >> 2) %
1412 (2 * client
-> interval
));
1414 /* Don't backoff past cutoff. */
1415 if (client
-> interval
>
1416 client
-> config
-> backoff_cutoff
)
1417 client
-> interval
=
1418 ((client
-> config
-> backoff_cutoff
/ 2)
1419 + ((random () >> 2) %
1420 client
-> config
-> backoff_cutoff
));
1421 } else if (!client
-> interval
)
1422 client
-> interval
= client
-> config
-> initial_interval
;
1424 /* If the backoff would take us to the panic timeout, just use that
1426 if (cur_time
+ client
-> interval
>
1427 client
-> first_sending
+ client
-> config
-> timeout
)
1428 client
-> interval
=
1429 (client
-> first_sending
+
1430 client
-> config
-> timeout
) - cur_time
+ 1;
1432 /* Record the number of seconds since we started sending. */
1433 if (interval
< 65536)
1434 client
-> packet
.secs
= htons (interval
);
1436 client
-> packet
.secs
= htons (65535);
1437 client
-> secs
= client
-> packet
.secs
;
1439 log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",
1440 client
-> name
? client
-> name
: client
-> interface
-> name
,
1441 inet_ntoa (sockaddr_broadcast
.sin_addr
),
1442 ntohs (sockaddr_broadcast
.sin_port
), (long)(client
-> interval
));
1444 /* Send out a packet. */
1445 result
= send_packet (client
-> interface
, (struct packet
*)0,
1447 client
-> packet_length
,
1448 inaddr_any
, &sockaddr_broadcast
,
1449 (struct hardware
*)0);
1451 add_timeout (cur_time
+ client
-> interval
,
1452 send_discover
, client
, 0, 0);
1455 /* state_panic gets called if we haven't received any offers in a preset
1456 amount of time. When this happens, we try to use existing leases that
1457 haven't yet expired, and failing that, we call the client script and
1458 hope it can do something. */
1460 void state_panic (cpp
)
1463 struct client_state
*client
= cpp
;
1464 struct client_lease
*loop
;
1465 struct client_lease
*lp
;
1467 loop
= lp
= client
-> active
;
1469 log_info ("No DHCPOFFERS received.");
1471 /* We may not have an active lease, but we may have some
1472 predefined leases that we can try. */
1473 if (!client
-> active
&& client
-> leases
)
1476 /* Run through the list of leases and see if one can be used. */
1477 while (client
-> active
) {
1478 if (client
-> active
-> expiry
> cur_time
) {
1479 log_info ("Trying recorded lease %s",
1480 piaddr (client
-> active
-> address
));
1481 /* Run the client script with the existing
1483 script_init (client
, "TIMEOUT",
1484 client
-> active
-> medium
);
1485 script_write_params (client
, "new_", client
-> active
);
1486 if (client
-> alias
)
1487 script_write_params (client
, "alias_",
1490 /* If the old lease is still good and doesn't
1491 yet need renewal, go into BOUND state and
1492 timeout at the renewal time. */
1493 if (!script_go (client
)) {
1494 if (cur_time
< client
-> active
-> renewal
) {
1495 client
-> state
= S_BOUND
;
1496 log_info ("bound: renewal in %ld %s.",
1497 (long)(client
-> active
-> renewal
-
1498 cur_time
), "seconds");
1499 add_timeout (client
-> active
-> renewal
,
1500 state_bound
, client
, 0, 0);
1502 client
-> state
= S_BOUND
;
1503 log_info ("bound: immediate renewal.");
1504 state_bound (client
);
1506 reinitialize_interfaces ();
1512 /* If there are no other leases, give up. */
1513 if (!client
-> leases
) {
1514 client
-> leases
= client
-> active
;
1515 client
-> active
= (struct client_lease
*)0;
1520 /* Otherwise, put the active lease at the end of the
1521 lease list, and try another lease.. */
1522 for (lp
= client
-> leases
; lp
-> next
; lp
= lp
-> next
)
1524 lp
-> next
= client
-> active
;
1526 lp
-> next
-> next
= (struct client_lease
*)0;
1528 client
-> active
= client
-> leases
;
1529 client
-> leases
= client
-> leases
-> next
;
1531 /* If we already tried this lease, we've exhausted the
1532 set of leases, so we might as well give up for
1534 if (client
-> active
== loop
)
1537 loop
= client
-> active
;
1540 /* No leases were available, or what was available didn't work, so
1541 tell the shell script that we failed to allocate an address,
1542 and try again later. */
1545 log_info ("Unable to obtain a lease on first try.%s",
1550 log_info ("No working leases in persistent database - sleeping.");
1551 script_init (client
, "FAIL", (struct string_list
*)0);
1552 if (client
-> alias
)
1553 script_write_params (client
, "alias_", client
-> alias
);
1555 client
-> state
= S_INIT
;
1556 add_timeout (cur_time
+
1557 ((client
-> config
-> retry_interval
+ 1) / 2 +
1558 (random () % client
-> config
-> retry_interval
)),
1559 state_init
, client
, 0, 0);
1563 void send_request (cpp
)
1566 struct client_state
*client
= cpp
;
1570 struct sockaddr_in destination
;
1571 struct in_addr from
;
1573 /* Figure out how long it's been since we started transmitting. */
1574 interval
= cur_time
- client
-> first_sending
;
1576 /* If we're in the INIT-REBOOT or REQUESTING state and we're
1577 past the reboot timeout, go to INIT and see if we can
1578 DISCOVER an address... */
1579 /* XXX In the INIT-REBOOT state, if we don't get an ACK, it
1580 means either that we're on a network with no DHCP server,
1581 or that our server is down. In the latter case, assuming
1582 that there is a backup DHCP server, DHCPDISCOVER will get
1583 us a new address, but we could also have successfully
1584 reused our old address. In the former case, we're hosed
1585 anyway. This is not a win-prone situation. */
1586 if ((client
-> state
== S_REBOOTING
||
1587 client
-> state
== S_REQUESTING
) &&
1588 interval
> client
-> config
-> reboot_timeout
) {
1590 client
-> state
= S_INIT
;
1591 cancel_timeout (send_request
, client
);
1592 state_init (client
);
1596 /* If we're in the reboot state, make sure the media is set up
1598 if (client
-> state
== S_REBOOTING
&&
1599 !client
-> medium
&&
1600 client
-> active
-> medium
) {
1601 script_init (client
, "MEDIUM", client
-> active
-> medium
);
1603 /* If the medium we chose won't fly, go to INIT state. */
1604 if (script_go (client
))
1607 /* Record the medium. */
1608 client
-> medium
= client
-> active
-> medium
;
1611 /* If the lease has expired, relinquish the address and go back
1612 to the INIT state. */
1613 if (client
-> state
!= S_REQUESTING
&&
1614 cur_time
> client
-> active
-> expiry
) {
1615 /* Run the client script with the new parameters. */
1616 script_init (client
, "EXPIRE", (struct string_list
*)0);
1617 script_write_params (client
, "old_", client
-> active
);
1618 if (client
-> alias
)
1619 script_write_params (client
, "alias_",
1623 /* Now do a preinit on the interface so that we can
1624 discover a new address. */
1625 script_init (client
, "PREINIT", (struct string_list
*)0);
1626 if (client
-> alias
)
1627 script_write_params (client
, "alias_",
1631 client
-> state
= S_INIT
;
1632 state_init (client
);
1636 /* Do the exponential backoff... */
1637 if (!client
-> interval
)
1638 client
-> interval
= client
-> config
-> initial_interval
;
1640 client
-> interval
+= ((random () >> 2) %
1641 (2 * client
-> interval
));
1644 /* Don't backoff past cutoff. */
1645 if (client
-> interval
>
1646 client
-> config
-> backoff_cutoff
)
1647 client
-> interval
=
1648 ((client
-> config
-> backoff_cutoff
/ 2)
1649 + ((random () >> 2) %
1650 client
-> config
-> backoff_cutoff
));
1652 /* If the backoff would take us to the expiry time, just set the
1653 timeout to the expiry time. */
1654 if (client
-> state
!= S_REQUESTING
&&
1655 cur_time
+ client
-> interval
> client
-> active
-> expiry
)
1656 client
-> interval
=
1657 client
-> active
-> expiry
- cur_time
+ 1;
1659 /* If the lease T2 time has elapsed, or if we're not yet bound,
1660 broadcast the DHCPREQUEST rather than unicasting. */
1661 if (client
-> state
== S_REQUESTING
||
1662 client
-> state
== S_REBOOTING
||
1663 cur_time
> client
-> active
-> rebind
)
1664 destination
.sin_addr
= sockaddr_broadcast
.sin_addr
;
1666 memcpy (&destination
.sin_addr
.s_addr
,
1667 client
-> destination
.iabuf
,
1668 sizeof destination
.sin_addr
.s_addr
);
1669 destination
.sin_port
= remote_port
;
1670 destination
.sin_family
= AF_INET
;
1672 destination
.sin_len
= sizeof destination
;
1675 if (client
-> state
== S_RENEWING
||
1676 client
-> state
== S_REBINDING
)
1677 memcpy (&from
, client
-> active
-> address
.iabuf
,
1680 from
.s_addr
= INADDR_ANY
;
1682 /* Record the number of seconds since we started sending. */
1683 if (client
-> state
== S_REQUESTING
)
1684 client
-> packet
.secs
= client
-> secs
;
1686 if (interval
< 65536)
1687 client
-> packet
.secs
= htons (interval
);
1689 client
-> packet
.secs
= htons (65535);
1692 log_info ("DHCPREQUEST on %s to %s port %d",
1693 client
-> name
? client
-> name
: client
-> interface
-> name
,
1694 inet_ntoa (destination
.sin_addr
),
1695 ntohs (destination
.sin_port
));
1697 if (destination
.sin_addr
.s_addr
!= INADDR_BROADCAST
&&
1699 result
= send_packet (fallback_interface
,
1702 client
-> packet_length
,
1704 (struct hardware
*)0);
1706 /* Send out a packet. */
1707 result
= send_packet (client
-> interface
, (struct packet
*)0,
1709 client
-> packet_length
,
1711 (struct hardware
*)0);
1713 add_timeout (cur_time
+ client
-> interval
,
1714 send_request
, client
, 0, 0);
1717 void send_decline (cpp
)
1720 struct client_state
*client
= cpp
;
1724 log_info ("DHCPDECLINE on %s to %s port %d",
1725 client
-> name
? client
-> name
: client
-> interface
-> name
,
1726 inet_ntoa (sockaddr_broadcast
.sin_addr
),
1727 ntohs (sockaddr_broadcast
.sin_port
));
1729 /* Send out a packet. */
1730 result
= send_packet (client
-> interface
, (struct packet
*)0,
1732 client
-> packet_length
,
1733 inaddr_any
, &sockaddr_broadcast
,
1734 (struct hardware
*)0);
1737 void send_release (cpp
)
1740 struct client_state
*client
= cpp
;
1743 struct sockaddr_in destination
;
1744 struct in_addr from
;
1746 memcpy (&from
, client
-> active
-> address
.iabuf
,
1748 memcpy (&destination
.sin_addr
.s_addr
,
1749 client
-> destination
.iabuf
,
1750 sizeof destination
.sin_addr
.s_addr
);
1751 destination
.sin_port
= remote_port
;
1752 destination
.sin_family
= AF_INET
;
1754 destination
.sin_len
= sizeof destination
;
1757 /* Set the lease to end now, so that we don't accidentally
1758 reuse it if we restart before the old expiry time. */
1759 client
-> active
-> expiry
=
1760 client
-> active
-> renewal
=
1761 client
-> active
-> rebind
= cur_time
;
1762 if (!write_client_lease (client
, client
-> active
, 1, 1)) {
1763 log_error ("Can't release lease: lease write failed.");
1767 log_info ("DHCPRELEASE on %s to %s port %d",
1768 client
-> name
? client
-> name
: client
-> interface
-> name
,
1769 inet_ntoa (destination
.sin_addr
),
1770 ntohs (destination
.sin_port
));
1772 if (fallback_interface
)
1773 result
= send_packet (fallback_interface
,
1776 client
-> packet_length
,
1778 (struct hardware
*)0);
1780 /* Send out a packet. */
1781 result
= send_packet (client
-> interface
, (struct packet
*)0,
1783 client
-> packet_length
,
1785 (struct hardware
*)0);
1788 void make_client_options (client
, lease
, type
, sid
, rip
, prl
, op
)
1789 struct client_state
*client
;
1790 struct client_lease
*lease
;
1792 struct option_cache
*sid
;
1795 struct option_state
**op
;
1798 struct option_cache
*oc
;
1799 struct buffer
*bp
= (struct buffer
*)0;
1801 /* If there are any leftover options, get rid of them. */
1803 option_state_dereference (op
, MDL
);
1805 /* Allocate space for options. */
1806 option_state_allocate (op
, MDL
);
1808 /* Send the server identifier if provided. */
1810 save_option (&dhcp_universe
, *op
, sid
);
1812 oc
= (struct option_cache
*)0;
1814 /* Send the requested address if provided. */
1816 client
-> requested_address
= *rip
;
1817 if (!(make_const_option_cache
1818 (&oc
, (struct buffer
**)0, rip
-> iabuf
, rip
-> len
,
1819 &dhcp_options
[DHO_DHCP_REQUESTED_ADDRESS
], MDL
)))
1820 log_error ("can't make requested address cache.");
1822 save_option (&dhcp_universe
, *op
, oc
);
1823 option_cache_dereference (&oc
, MDL
);
1826 client
-> requested_address
.len
= 0;
1829 if (!(make_const_option_cache
1830 (&oc
, (struct buffer
**)0,
1831 type
, 1, &dhcp_options
[DHO_DHCP_MESSAGE_TYPE
], MDL
)))
1832 log_error ("can't make message type.");
1834 save_option (&dhcp_universe
, *op
, oc
);
1835 option_cache_dereference (&oc
, MDL
);
1839 /* Figure out how many parameters were requested. */
1840 for (i
= 0; prl
[i
]; i
++)
1842 if (!buffer_allocate (&bp
, i
, MDL
))
1843 log_error ("can't make parameter list buffer.");
1845 for (i
= 0; prl
[i
]; i
++)
1846 bp
-> data
[i
] = prl
[i
];
1847 if (!(make_const_option_cache
1848 (&oc
, &bp
, (u_int8_t
*)0, i
,
1849 &dhcp_options
[DHO_DHCP_PARAMETER_REQUEST_LIST
],
1851 log_error ("can't make option cache");
1853 save_option (&dhcp_universe
, *op
, oc
);
1854 option_cache_dereference (&oc
, MDL
);
1859 /* Run statements that need to be run on transmission. */
1860 if (client
-> config
-> on_transmission
)
1861 execute_statements_in_scope
1862 ((struct binding_value
**)0,
1863 (struct packet
*)0, (struct lease
*)0, client
,
1864 (lease
? lease
-> options
: (struct option_state
*)0),
1866 client
-> config
-> on_transmission
,
1870 void make_discover (client
, lease
)
1871 struct client_state
*client
;
1872 struct client_lease
*lease
;
1874 unsigned char discover
= DHCPDISCOVER
;
1876 struct option_state
*options
= (struct option_state
*)0;
1878 memset (&client
-> packet
, 0, sizeof (client
-> packet
));
1880 make_client_options (client
,
1881 lease
, &discover
, (struct option_cache
*)0,
1882 lease
? &lease
-> address
: (struct iaddr
*)0,
1883 client
-> config
-> requested_options
,
1886 /* Set up the option buffer... */
1887 client
-> packet_length
=
1888 cons_options ((struct packet
*)0, &client
-> packet
,
1889 (struct lease
*)0, client
,
1890 /* maximum packet size */1500,
1891 (struct option_state
*)0,
1893 /* scope */ &global_scope
,
1897 (struct data_string
*)0,
1898 client
-> config
-> vendor_space_name
);
1900 option_state_dereference (&options
, MDL
);
1901 if (client
-> packet_length
< BOOTP_MIN_LEN
)
1902 client
-> packet_length
= BOOTP_MIN_LEN
;
1904 client
-> packet
.op
= BOOTREQUEST
;
1905 client
-> packet
.htype
= client
-> interface
-> hw_address
.hbuf
[0];
1906 client
-> packet
.hlen
= client
-> interface
-> hw_address
.hlen
- 1;
1907 client
-> packet
.hops
= 0;
1908 client
-> packet
.xid
= random ();
1909 client
-> packet
.secs
= 0; /* filled in by send_discover. */
1911 if (can_receive_unicast_unconfigured (client
-> interface
))
1912 client
-> packet
.flags
= 0;
1914 client
-> packet
.flags
= htons (BOOTP_BROADCAST
);
1916 memset (&(client
-> packet
.ciaddr
),
1917 0, sizeof client
-> packet
.ciaddr
);
1918 memset (&(client
-> packet
.yiaddr
),
1919 0, sizeof client
-> packet
.yiaddr
);
1920 memset (&(client
-> packet
.siaddr
),
1921 0, sizeof client
-> packet
.siaddr
);
1922 client
-> packet
.giaddr
= giaddr
;
1923 if (client
-> interface
-> hw_address
.hlen
> 0)
1924 memcpy (client
-> packet
.chaddr
,
1925 &client
-> interface
-> hw_address
.hbuf
[1],
1926 (unsigned)(client
-> interface
-> hw_address
.hlen
- 1));
1929 dump_raw ((unsigned char *)&client
-> packet
, client
-> packet_length
);
1934 void make_request (client
, lease
)
1935 struct client_state
*client
;
1936 struct client_lease
*lease
;
1938 unsigned char request
= DHCPREQUEST
;
1940 unsigned char *tmp
, *digest
;
1941 unsigned char *old_digest_loc
;
1942 struct option_cache
*oc
;
1944 memset (&client
-> packet
, 0, sizeof (client
-> packet
));
1946 if (client
-> state
== S_REQUESTING
)
1947 oc
= lookup_option (&dhcp_universe
, lease
-> options
,
1948 DHO_DHCP_SERVER_IDENTIFIER
);
1950 oc
= (struct option_cache
*)0;
1952 if (client
-> sent_options
)
1953 option_state_dereference (&client
-> sent_options
, MDL
);
1955 make_client_options (client
, lease
, &request
, oc
,
1956 ((client
-> state
== S_REQUESTING
||
1957 client
-> state
== S_REBOOTING
)
1959 : (struct iaddr
*)0),
1960 client
-> config
-> requested_options
,
1961 &client
-> sent_options
);
1963 /* Set up the option buffer... */
1964 client
-> packet_length
=
1965 cons_options ((struct packet
*)0, &client
-> packet
,
1966 (struct lease
*)0, client
,
1967 /* maximum packet size */1500,
1968 (struct option_state
*)0,
1969 client
-> sent_options
,
1970 /* scope */ &global_scope
,
1974 (struct data_string
*)0,
1975 client
-> config
-> vendor_space_name
);
1977 if (client
-> packet_length
< BOOTP_MIN_LEN
)
1978 client
-> packet_length
= BOOTP_MIN_LEN
;
1980 client
-> packet
.op
= BOOTREQUEST
;
1981 client
-> packet
.htype
= client
-> interface
-> hw_address
.hbuf
[0];
1982 client
-> packet
.hlen
= client
-> interface
-> hw_address
.hlen
- 1;
1983 client
-> packet
.hops
= 0;
1984 client
-> packet
.xid
= client
-> xid
;
1985 client
-> packet
.secs
= 0; /* Filled in by send_request. */
1987 /* If we own the address we're requesting, put it in ciaddr;
1988 otherwise set ciaddr to zero. */
1989 if (client
-> state
== S_BOUND
||
1990 client
-> state
== S_RENEWING
||
1991 client
-> state
== S_REBINDING
) {
1992 memcpy (&client
-> packet
.ciaddr
,
1993 lease
-> address
.iabuf
, lease
-> address
.len
);
1994 client
-> packet
.flags
= 0;
1996 memset (&client
-> packet
.ciaddr
, 0,
1997 sizeof client
-> packet
.ciaddr
);
1998 if (can_receive_unicast_unconfigured (client
-> interface
))
1999 client
-> packet
.flags
= 0;
2001 client
-> packet
.flags
= htons (BOOTP_BROADCAST
);
2004 memset (&client
-> packet
.yiaddr
, 0,
2005 sizeof client
-> packet
.yiaddr
);
2006 memset (&client
-> packet
.siaddr
, 0,
2007 sizeof client
-> packet
.siaddr
);
2008 if (client
-> state
!= S_BOUND
&&
2009 client
-> state
!= S_RENEWING
)
2010 client
-> packet
.giaddr
= giaddr
;
2012 memset (&client
-> packet
.giaddr
, 0,
2013 sizeof client
-> packet
.giaddr
);
2014 if (client
-> interface
-> hw_address
.hlen
> 0)
2015 memcpy (client
-> packet
.chaddr
,
2016 &client
-> interface
-> hw_address
.hbuf
[1],
2017 (unsigned)(client
-> interface
-> hw_address
.hlen
- 1));
2020 dump_raw ((unsigned char *)&client
-> packet
, client
-> packet_length
);
2024 void make_decline (client
, lease
)
2025 struct client_state
*client
;
2026 struct client_lease
*lease
;
2028 unsigned char decline
= DHCPDECLINE
;
2030 struct option_cache
*oc
;
2032 struct option_state
*options
= (struct option_state
*)0;
2034 oc
= lookup_option (&dhcp_universe
, lease
-> options
,
2035 DHO_DHCP_SERVER_IDENTIFIER
);
2036 make_client_options (client
, lease
, &decline
, oc
,
2037 &lease
-> address
, (u_int32_t
*)0, &options
);
2039 /* Set up the option buffer... */
2040 memset (&client
-> packet
, 0, sizeof (client
-> packet
));
2041 client
-> packet_length
=
2042 cons_options ((struct packet
*)0, &client
-> packet
,
2043 (struct lease
*)0, client
, 0,
2044 (struct option_state
*)0, options
,
2045 &global_scope
, 0, 0, 0, (struct data_string
*)0,
2046 client
-> config
-> vendor_space_name
);
2047 option_state_dereference (&options
, MDL
);
2048 if (client
-> packet_length
< BOOTP_MIN_LEN
)
2049 client
-> packet_length
= BOOTP_MIN_LEN
;
2050 option_state_dereference (&options
, MDL
);
2052 client
-> packet
.op
= BOOTREQUEST
;
2053 client
-> packet
.htype
= client
-> interface
-> hw_address
.hbuf
[0];
2054 client
-> packet
.hlen
= client
-> interface
-> hw_address
.hlen
- 1;
2055 client
-> packet
.hops
= 0;
2056 client
-> packet
.xid
= client
-> xid
;
2057 client
-> packet
.secs
= 0; /* Filled in by send_request. */
2058 if (can_receive_unicast_unconfigured (client
-> interface
))
2059 client
-> packet
.flags
= 0;
2061 client
-> packet
.flags
= htons (BOOTP_BROADCAST
);
2063 /* ciaddr must always be zero. */
2064 memset (&client
-> packet
.ciaddr
, 0,
2065 sizeof client
-> packet
.ciaddr
);
2066 memset (&client
-> packet
.yiaddr
, 0,
2067 sizeof client
-> packet
.yiaddr
);
2068 memset (&client
-> packet
.siaddr
, 0,
2069 sizeof client
-> packet
.siaddr
);
2070 client
-> packet
.giaddr
= giaddr
;
2071 memcpy (client
-> packet
.chaddr
,
2072 &client
-> interface
-> hw_address
.hbuf
[1],
2073 client
-> interface
-> hw_address
.hlen
);
2076 dump_raw ((unsigned char *)&client
-> packet
, client
-> packet_length
);
2080 void make_release (client
, lease
)
2081 struct client_state
*client
;
2082 struct client_lease
*lease
;
2084 unsigned char request
= DHCPRELEASE
;
2086 struct option_cache
*oc
;
2088 struct option_state
*options
= (struct option_state
*)0;
2090 memset (&client
-> packet
, 0, sizeof (client
-> packet
));
2092 oc
= lookup_option (&dhcp_universe
, lease
-> options
,
2093 DHO_DHCP_SERVER_IDENTIFIER
);
2094 make_client_options (client
, lease
, &request
, oc
,
2095 (struct iaddr
*)0, (u_int32_t
*)0,
2098 /* Set up the option buffer... */
2099 client
-> packet_length
=
2100 cons_options ((struct packet
*)0, &client
-> packet
,
2101 (struct lease
*)0, client
,
2102 /* maximum packet size */1500,
2103 (struct option_state
*)0,
2105 /* scope */ &global_scope
,
2109 (struct data_string
*)0,
2110 client
-> config
-> vendor_space_name
);
2112 if (client
-> packet_length
< BOOTP_MIN_LEN
)
2113 client
-> packet_length
= BOOTP_MIN_LEN
;
2114 option_state_dereference (&options
, MDL
);
2116 client
-> packet
.op
= BOOTREQUEST
;
2117 client
-> packet
.htype
= client
-> interface
-> hw_address
.hbuf
[0];
2118 client
-> packet
.hlen
= client
-> interface
-> hw_address
.hlen
- 1;
2119 client
-> packet
.hops
= 0;
2120 client
-> packet
.xid
= random ();
2121 client
-> packet
.secs
= 0;
2122 client
-> packet
.flags
= 0;
2123 memcpy (&client
-> packet
.ciaddr
,
2124 lease
-> address
.iabuf
, lease
-> address
.len
);
2125 memset (&client
-> packet
.yiaddr
, 0,
2126 sizeof client
-> packet
.yiaddr
);
2127 memset (&client
-> packet
.siaddr
, 0,
2128 sizeof client
-> packet
.siaddr
);
2129 client
-> packet
.giaddr
= giaddr
;
2130 memcpy (client
-> packet
.chaddr
,
2131 &client
-> interface
-> hw_address
.hbuf
[1],
2132 client
-> interface
-> hw_address
.hlen
);
2135 dump_raw ((unsigned char *)&client
-> packet
, client
-> packet_length
);
2139 void destroy_client_lease (lease
)
2140 struct client_lease
*lease
;
2144 if (lease
-> server_name
)
2145 dfree (lease
-> server_name
, MDL
);
2146 if (lease
-> filename
)
2147 dfree (lease
-> filename
, MDL
);
2148 option_state_dereference (&lease
-> options
, MDL
);
2149 free_client_lease (lease
, MDL
);
2154 void rewrite_client_leases ()
2156 struct interface_info
*ip
;
2157 struct client_state
*client
;
2158 struct client_lease
*lp
;
2162 leaseFile
= fopen (path_dhclient_db
, "w");
2164 log_error ("can't create %s: %m", path_dhclient_db
);
2168 /* Write out all the leases attached to configured interfaces that
2170 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
2171 for (client
= ip
-> client
; client
; client
= client
-> next
) {
2172 for (lp
= client
-> leases
; lp
; lp
= lp
-> next
) {
2173 write_client_lease (client
, lp
, 1, 0);
2175 if (client
-> active
)
2176 write_client_lease (client
,
2177 client
-> active
, 1, 0);
2181 /* Write out any leases that are attached to interfaces that aren't
2182 currently configured. */
2183 for (ip
= dummy_interfaces
; ip
; ip
= ip
-> next
) {
2184 for (client
= ip
-> client
; client
; client
= client
-> next
) {
2185 for (lp
= client
-> leases
; lp
; lp
= lp
-> next
) {
2186 write_client_lease (client
, lp
, 1, 0);
2188 if (client
-> active
)
2189 write_client_lease (client
,
2190 client
-> active
, 1, 0);
2196 void write_lease_option (struct option_cache
*oc
,
2197 struct packet
*packet
, struct lease
*lease
,
2198 struct client_state
*client_state
,
2199 struct option_state
*in_options
,
2200 struct option_state
*cfg_options
,
2201 struct binding_scope
**scope
,
2202 struct universe
*u
, void *stuff
)
2204 const char *name
, *dot
;
2205 struct data_string ds
;
2207 struct client_state
*client
;
2209 memset (&ds
, 0, sizeof ds
);
2211 if (u
!= &dhcp_universe
) {
2218 if (evaluate_option_cache (&ds
, packet
, lease
, client_state
,
2219 in_options
, cfg_options
, scope
, oc
, MDL
)) {
2221 " option %s%s%s %s;\n",
2222 name
, dot
, oc
-> option
-> name
,
2223 pretty_print_option (oc
-> option
,
2224 ds
.data
, ds
.len
, 1, 1));
2225 data_string_forget (&ds
, MDL
);
2229 int write_client_lease (client
, lease
, rewrite
, makesure
)
2230 struct client_state
*client
;
2231 struct client_lease
*lease
;
2237 static int leases_written
;
2238 struct option_cache
*oc
;
2239 struct data_string ds
;
2245 if (leases_written
++ > 20) {
2246 rewrite_client_leases ();
2251 /* If the lease came from the config file, we don't need to stash
2252 a copy in the lease database. */
2253 if (lease
-> is_static
)
2256 if (!leaseFile
) { /* XXX */
2257 leaseFile
= fopen (path_dhclient_db
, "w");
2259 log_error ("can't create %s: %m", path_dhclient_db
);
2265 fprintf (leaseFile
, "lease {\n");
2266 if (lease
-> is_bootp
) {
2267 fprintf (leaseFile
, " bootp;\n");
2273 fprintf (leaseFile
, " interface \"%s\";\n",
2274 client
-> interface
-> name
);
2279 if (client
-> name
) {
2280 fprintf (leaseFile
, " name \"%s\";\n", client
-> name
);
2286 fprintf (leaseFile
, " fixed-address %s;\n",
2287 piaddr (lease
-> address
));
2292 if (lease
-> filename
) {
2293 s
= quotify_string (lease
-> filename
, MDL
);
2295 fprintf (leaseFile
, " filename \"%s\";\n", s
);
2305 if (lease
-> server_name
) {
2306 s
= quotify_string (lease
-> filename
, MDL
);
2308 fprintf (leaseFile
, " server-name \"%s\";\n", s
);
2317 if (lease
-> medium
) {
2318 s
= quotify_string (lease
-> medium
-> string
, MDL
);
2320 fprintf (leaseFile
, " medium \"%s\";\n", s
);
2334 memset (&ds
, 0, sizeof ds
);
2336 for (i
= 0; i
< lease
-> options
-> universe_count
; i
++) {
2337 option_space_foreach ((struct packet
*)0, (struct lease
*)0,
2338 client
, (struct option_state
*)0,
2339 lease
-> options
, &global_scope
,
2341 client
, write_lease_option
);
2344 /* Note: the following is not a Y2K bug - it's a Y1.9K bug. Until
2345 somebody invents a time machine, I think we can safely disregard
2347 t
= gmtime (&lease
-> renewal
);
2349 " renew %d %d/%d/%d %02d:%02d:%02d;\n",
2350 t
-> tm_wday
, t
-> tm_year
+ 1900,
2351 t
-> tm_mon
+ 1, t
-> tm_mday
,
2352 t
-> tm_hour
, t
-> tm_min
, t
-> tm_sec
);
2357 t
= gmtime (&lease
-> rebind
);
2359 " rebind %d %d/%d/%d %02d:%02d:%02d;\n",
2360 t
-> tm_wday
, t
-> tm_year
+ 1900,
2361 t
-> tm_mon
+ 1, t
-> tm_mday
,
2362 t
-> tm_hour
, t
-> tm_min
, t
-> tm_sec
);
2367 t
= gmtime (&lease
-> expiry
);
2369 " expire %d %d/%d/%d %02d:%02d:%02d;\n",
2370 t
-> tm_wday
, t
-> tm_year
+ 1900,
2371 t
-> tm_mon
+ 1, t
-> tm_mday
,
2372 t
-> tm_hour
, t
-> tm_min
, t
-> tm_sec
);
2377 fprintf (leaseFile
, "}\n");
2387 if (!errors
&& makesure
) {
2388 if (fsync (fileno (leaseFile
)) < 0) {
2389 log_info ("write_client_lease: %m");
2393 return errors
? 0 : 1;
2396 /* Variables holding name of script and file pointer for writing to
2397 script. Needless to say, this is not reentrant - only one script
2398 can be invoked at a time. */
2399 char scriptName
[256];
2402 void script_init (client
, reason
, medium
)
2403 struct client_state
*client
;
2405 struct string_list
*medium
;
2407 struct string_list
*sl
, *next
;
2410 for (sl
= client
-> env
; sl
; sl
= next
) {
2414 client
-> env
= (struct string_list
*)0;
2417 if (client
-> interface
) {
2418 client_envadd (client
, "", "interface", "%s",
2419 client
-> interface
-> name
);
2422 client_envadd (client
,
2423 "", "client", "%s", client
-> name
);
2425 client_envadd (client
,
2426 "", "medium", "%s", medium
-> string
);
2428 client_envadd (client
, "", "reason", "%s", reason
);
2429 client_envadd (client
, "", "pid", "%ld", (long int)getpid ());
2433 struct envadd_state
{
2434 struct client_state
*client
;
2438 void client_option_envadd (struct option_cache
*oc
,
2439 struct packet
*packet
, struct lease
*lease
,
2440 struct client_state
*client_state
,
2441 struct option_state
*in_options
,
2442 struct option_state
*cfg_options
,
2443 struct binding_scope
**scope
,
2444 struct universe
*u
, void *stuff
)
2446 struct envadd_state
*es
= stuff
;
2447 struct data_string data
;
2448 memset (&data
, 0, sizeof data
);
2450 if (evaluate_option_cache (&data
, packet
, lease
, client_state
,
2451 in_options
, cfg_options
, scope
, oc
, MDL
)) {
2454 if (dhcp_option_ev_name (name
, sizeof name
,
2456 client_envadd (es
-> client
, es
-> prefix
,
2458 (pretty_print_option
2460 data
.data
, data
.len
,
2462 data_string_forget (&data
, MDL
);
2468 void script_write_params (client
, prefix
, lease
)
2469 struct client_state
*client
;
2471 struct client_lease
*lease
;
2474 struct data_string data
;
2475 struct option_cache
*oc
;
2478 struct envadd_state es
;
2483 client_envadd (client
,
2484 prefix
, "ip_address", "%s", piaddr (lease
-> address
));
2486 /* For the benefit of Linux (and operating systems which may
2487 have similar needs), compute the network address based on
2488 the supplied ip address and netmask, if provided. Also
2489 compute the broadcast address (the host address all ones
2490 broadcast address, not the host address all zeroes
2491 broadcast address). */
2493 memset (&data
, 0, sizeof data
);
2494 oc
= lookup_option (&dhcp_universe
, lease
-> options
, DHO_SUBNET_MASK
);
2495 if (oc
&& evaluate_option_cache (&data
, (struct packet
*)0,
2496 (struct lease
*)0, client
,
2497 (struct option_state
*)0,
2499 &global_scope
, oc
, MDL
)) {
2501 struct iaddr netmask
, subnet
, broadcast
;
2503 memcpy (netmask
.iabuf
, data
.data
, data
.len
);
2504 netmask
.len
= data
.len
;
2505 data_string_forget (&data
, MDL
);
2507 subnet
= subnet_number (lease
-> address
, netmask
);
2509 client_envadd (client
, prefix
, "network_number",
2510 "%s", piaddr (subnet
));
2512 oc
= lookup_option (&dhcp_universe
,
2514 DHO_BROADCAST_ADDRESS
);
2516 !(evaluate_option_cache
2517 (&data
, (struct packet
*)0,
2518 (struct lease
*)0, client
,
2519 (struct option_state
*)0,
2521 &global_scope
, oc
, MDL
))) {
2522 broadcast
= broadcast_addr (subnet
, netmask
);
2523 if (broadcast
.len
) {
2524 client_envadd (client
,
2525 prefix
, "broadcast_address",
2526 "%s", piaddr (broadcast
));
2531 data_string_forget (&data
, MDL
);
2534 if (lease
-> filename
)
2535 client_envadd (client
,
2536 prefix
, "filename", "%s", lease
-> filename
);
2537 if (lease
-> server_name
)
2538 client_envadd (client
, prefix
, "server_name",
2539 "%s", lease
-> server_name
);
2541 for (i
= 0; i
< lease
-> options
-> universe_count
; i
++) {
2542 option_space_foreach ((struct packet
*)0, (struct lease
*)0,
2543 client
, (struct option_state
*)0,
2544 lease
-> options
, &global_scope
,
2546 &es
, client_option_envadd
);
2548 client_envadd (client
, prefix
, "expiry", "%d", (int)(lease
-> expiry
));
2551 int script_go (client
)
2552 struct client_state
*client
;
2559 char reason
[] = "REASON=NBI";
2560 static char client_path
[] = CLIENT_PATH
;
2562 struct string_list
*sp
, *next
;
2563 int pid
, wpid
, wstatus
;
2566 scriptName
= client
-> config
-> script_name
;
2568 scriptName
= top_level_config
.script_name
;
2570 envp
= dmalloc (((client
? client
-> envc
: 2) +
2571 client_env_count
+ 2) * sizeof (char *), MDL
);
2573 log_error ("No memory for client script environment.");
2577 /* Copy out the environment specified on the command line,
2579 for (sp
= client_env
; sp
; sp
= sp
-> next
) {
2580 envp
[i
++] = sp
-> string
;
2582 /* Copy out the environment specified by dhclient. */
2584 for (sp
= client
-> env
; sp
; sp
= sp
-> next
) {
2585 envp
[i
++] = sp
-> string
;
2588 envp
[i
++] = reason
;
2591 envp
[i
++] = client_path
;
2592 envp
[i
] = (char *)0;
2594 argv
[0] = scriptName
;
2595 argv
[1] = (char *)0;
2599 log_error ("fork: %m");
2603 wpid
= wait (&wstatus
);
2604 } while (wpid
!= pid
&& wpid
> 0);
2606 log_error ("wait: %m");
2610 execve (scriptName
, argv
, envp
);
2611 log_error ("execve (%s, ...): %m", scriptName
);
2616 for (sp
= client
-> env
; sp
; sp
= next
) {
2620 client
-> env
= (struct string_list
*)0;
2624 GET_TIME (&cur_time
);
2625 return (WIFEXITED (wstatus
) ?
2626 WEXITSTATUS (wstatus
) : -WTERMSIG (wstatus
));
2629 void client_envadd (struct client_state
*client
,
2630 const char *prefix
, const char *name
, const char *fmt
, ...)
2635 struct string_list
*val
;
2638 va_start (list
, fmt
);
2639 len
= vsnprintf (spbuf
, sizeof spbuf
, fmt
, list
);
2642 val
= dmalloc (strlen (prefix
) + strlen (name
) + 1 /* = */ +
2643 len
+ sizeof *val
, MDL
);
2651 if (len
>= sizeof spbuf
) {
2652 va_start (list
, fmt
);
2653 vsnprintf (s
, len
+ 1, fmt
, list
);
2657 val
-> next
= client
-> env
;
2658 client
-> env
= val
;
2662 int dhcp_option_ev_name (buf
, buflen
, option
)
2665 struct option
*option
;
2671 if (option
-> universe
!= &dhcp_universe
) {
2672 s
= option
-> universe
-> name
;
2681 if (j
+ 1 == buflen
)
2691 if (j
+ 1 == buflen
)
2704 static int state
= 0;
2708 /* Don't become a daemon if the user requested otherwise. */
2710 write_client_pid_file ();
2714 /* Only do it once. */
2719 /* Stop logging to stderr... */
2722 /* Become a daemon... */
2723 if ((pid
= fork ()) < 0)
2724 log_fatal ("Can't fork daemon: %m");
2727 /* Become session leader and get pid... */
2730 /* Close standard I/O descriptors. */
2735 /* Reopen them on /dev/null. */
2736 i
= open ("/dev/null", O_RDWR
);
2738 i
= open ("/dev/null", O_RDWR
);
2740 i
= open ("/dev/null", O_RDWR
);
2741 log_perror
= 0; /* No sense logging to /dev/null. */
2745 write_client_pid_file ();
2748 void write_client_pid_file ()
2753 pfdesc
= open (path_dhclient_pid
, O_CREAT
| O_TRUNC
| O_WRONLY
, 0644);
2756 log_error ("Can't create %s: %m", path_dhclient_pid
);
2760 pf
= fdopen (pfdesc
, "w");
2762 log_error ("Can't fdopen %s: %m", path_dhclient_pid
);
2764 fprintf (pf
, "%ld\n", (long)getpid ());
2769 void client_location_changed ()
2771 struct interface_info
*ip
;
2772 struct client_state
*client
;
2774 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
2775 for (client
= ip
-> client
; client
; client
= client
-> next
) {
2776 switch (client
-> state
) {
2778 cancel_timeout (send_discover
, client
);
2782 cancel_timeout (state_bound
, client
);
2788 cancel_timeout (send_request
, client
);
2796 client
-> state
= S_INIT
;
2797 state_reboot (client
);
2802 void do_release(client
)
2803 struct client_state
*client
;
2805 struct data_string ds
;
2806 struct option_cache
*oc
;
2808 /* Pick a random xid. */
2809 client
-> xid
= random ();
2811 /* is there even a lease to release? */
2812 if (client
-> active
) {
2813 /* Make a DHCPRELEASE packet, and set appropriate per-interface
2815 make_release (client
, client
-> active
);
2817 memset (&ds
, 0, sizeof ds
);
2818 oc
= lookup_option (&dhcp_universe
,
2819 client
-> active
-> options
,
2820 DHO_DHCP_SERVER_IDENTIFIER
);
2822 evaluate_option_cache (&ds
, (struct packet
*)0,
2823 (struct lease
*)0, client
,
2824 (struct option_state
*)0,
2825 client
-> active
-> options
,
2826 &global_scope
, oc
, MDL
)) {
2828 memcpy (client
-> destination
.iabuf
,
2830 client
-> destination
.len
= 4;
2832 client
-> destination
= iaddr_broadcast
;
2834 data_string_forget (&ds
, MDL
);
2836 client
-> destination
= iaddr_broadcast
;
2837 client
-> first_sending
= cur_time
;
2838 client
-> interval
= client
-> config
-> initial_interval
;
2840 /* Zap the medium list... */
2841 client
-> medium
= (struct string_list
*)0;
2843 /* Send out the first and only DHCPRELEASE packet. */
2844 send_release (client
);
2846 /* Do the client script RELEASE operation. */
2847 script_init (client
,
2848 "RELEASE", (struct string_list
*)0);
2849 if (client
-> alias
)
2850 script_write_params (client
, "alias_",
2852 script_write_params (client
, "old_", client
-> active
);
2856 /* Cancel any timeouts. */
2857 cancel_timeout (state_bound
, client
);
2858 cancel_timeout (send_discover
, client
);
2859 cancel_timeout (state_init
, client
);
2860 cancel_timeout (send_request
, client
);
2861 cancel_timeout (state_reboot
, client
);
2862 client
-> state
= S_STOPPED
;
2865 int dhclient_interface_shutdown_hook (struct interface_info
*interface
)
2867 do_release (interface
-> client
);
2872 int dhclient_interface_discovery_hook (struct interface_info
*tmp
)
2874 struct interface_info
*last
, *ip
;
2875 /* See if we can find the client from dummy_interfaces */
2877 for (ip
= dummy_interfaces
; ip
; ip
= ip
-> next
) {
2878 if (!strcmp (ip
-> name
, tmp
-> name
)) {
2879 /* Remove from dummy_interfaces */
2881 ip
= (struct interface_info
*)0;
2882 interface_reference (&ip
, last
-> next
, MDL
);
2883 interface_dereference (&last
-> next
, MDL
);
2885 interface_reference (&last
-> next
,
2887 interface_dereference (&ip
-> next
,
2891 ip
= (struct interface_info
*)0;
2892 interface_reference (&ip
,
2893 dummy_interfaces
, MDL
);
2894 interface_dereference (&dummy_interfaces
, MDL
);
2896 interface_reference (&dummy_interfaces
,
2898 interface_dereference (&ip
-> next
,
2902 /* Copy "client" to tmp */
2904 tmp
-> client
= ip
-> client
;
2905 tmp
-> client
-> interface
= tmp
;
2907 interface_dereference (&ip
, MDL
);
2915 isc_result_t
dhclient_interface_startup_hook (struct interface_info
*interface
)
2917 struct interface_info
*ip
;
2918 struct client_state
*client
;
2920 /* This code needs some rethinking. It doesn't test against
2921 a signal name, and it just kind of bulls into doing something
2922 that may or may not be appropriate. */
2925 interface_reference (&interface
-> next
, interfaces
, MDL
);
2926 interface_dereference (&interfaces
, MDL
);
2928 interface_reference (&interfaces
, interface
, MDL
);
2930 discover_interfaces (DISCOVER_UNCONFIGURED
);
2932 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
2933 /* If interfaces were specified, don't configure
2934 interfaces that weren't specified! */
2935 if (ip
-> flags
& INTERFACE_RUNNING
||
2936 (ip
-> flags
& (INTERFACE_REQUESTED
|
2937 INTERFACE_AUTOMATIC
)) !=
2938 INTERFACE_REQUESTED
)
2940 script_init (ip
-> client
,
2941 "PREINIT", (struct string_list
*)0);
2942 if (ip
-> client
-> alias
)
2943 script_write_params (ip
-> client
, "alias_",
2944 ip
-> client
-> alias
);
2945 script_go (ip
-> client
);
2948 discover_interfaces (interfaces_requested
2949 ? DISCOVER_REQUESTED
2950 : DISCOVER_RUNNING
);
2952 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
2953 if (ip
-> flags
& INTERFACE_RUNNING
)
2955 ip
-> flags
|= INTERFACE_RUNNING
;
2956 for (client
= ip
-> client
; client
; client
= client
-> next
) {
2957 client
-> state
= S_INIT
;
2958 /* Set up a timeout to start the initialization
2960 add_timeout (cur_time
+ random () % 5,
2961 state_reboot
, client
, 0, 0);
2964 return ISC_R_SUCCESS
;
2967 /* The client should never receive a relay agent information option,
2968 so if it does, log it and discard it. */
2970 int parse_agent_information_option (packet
, len
, data
)
2971 struct packet
*packet
;
2978 /* The client never sends relay agent information options. */
2980 unsigned cons_agent_information_options (cfg_options
, outpacket
,
2982 struct option_state
*cfg_options
;
2983 struct dhcp_packet
*outpacket
;
2990 static void shutdown_exit (void *foo
)
2995 isc_result_t
dhcp_set_control_state (control_object_state_t oldstate
,
2996 control_object_state_t newstate
)
2998 struct interface_info
*ip
;
2999 struct client_state
*client
;
3001 /* Do the right thing for each interface. */
3002 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
3003 for (client
= ip
-> client
; client
; client
= client
-> next
) {
3005 case server_startup
:
3006 return ISC_R_SUCCESS
;
3008 case server_running
:
3009 return ISC_R_SUCCESS
;
3011 case server_shutdown
:
3012 if (client
-> active
&&
3013 client
-> active
-> expiry
> cur_time
) {
3014 if (client
-> config
-> do_forward_update
)
3015 client_dns_update (client
, 0, 0);
3016 do_release (client
);
3020 case server_hibernate
:
3021 state_stop (client
);
3025 state_reboot (client
);
3030 if (newstate
== server_shutdown
)
3031 add_timeout (cur_time
+ 1, shutdown_exit
, 0, 0, 0);
3032 return ISC_R_SUCCESS
;
3035 /* Called after a timeout if the DNS update failed on the previous try.
3036 Retries the update, and if it times out, schedules a retry after
3037 ten times as long of a wait. */
3039 void client_dns_update_timeout (void *cp
)
3041 struct client_state
*client
= cp
;
3042 isc_result_t status
;
3044 if (client
-> active
) {
3045 status
= client_dns_update (client
, 1,
3046 (client
-> active
-> renewal
-
3048 if (status
== ISC_R_TIMEDOUT
) {
3049 client
-> dns_update_timeout
*= 10;
3050 add_timeout (cur_time
+ client
-> dns_update_timeout
,
3051 client_dns_update_timeout
, client
, 0, 0);
3056 /* See if we should do a DNS update, and if so, do it. */
3058 isc_result_t
client_dns_update (struct client_state
*client
, int addp
, int ttl
)
3060 struct data_string ddns_fqdn
, ddns_fwd_name
,
3061 ddns_dhcid
, client_identifier
;
3062 struct option_cache
*oc
;
3067 /* If we didn't send an FQDN option, we certainly aren't going to
3068 be doing an update. */
3069 if (!client
-> sent_options
)
3070 return ISC_R_SUCCESS
;
3072 /* If we don't have a lease, we can't do an update. */
3073 if (!client
-> active
)
3074 return ISC_R_SUCCESS
;
3076 /* If we set the no client update flag, don't do the update. */
3077 if ((oc
= lookup_option (&fqdn_universe
, client
-> sent_options
,
3078 FQDN_NO_CLIENT_UPDATE
)) &&
3079 evaluate_boolean_option_cache (&ignorep
, (struct packet
*)0,
3080 (struct lease
*)0, client
,
3081 client
-> sent_options
,
3082 (struct option_state
*)0,
3083 &global_scope
, oc
, MDL
))
3084 return ISC_R_SUCCESS
;
3086 /* If we set the "server, please update" flag, or didn't set it
3087 to false, don't do the update. */
3088 if (!(oc
= lookup_option (&fqdn_universe
, client
-> sent_options
,
3089 FQDN_SERVER_UPDATE
)) ||
3090 evaluate_boolean_option_cache (&ignorep
, (struct packet
*)0,
3091 (struct lease
*)0, client
,
3092 client
-> sent_options
,
3093 (struct option_state
*)0,
3094 &global_scope
, oc
, MDL
))
3095 return ISC_R_SUCCESS
;
3097 /* If no FQDN option was supplied, don't do the update. */
3098 memset (&ddns_fwd_name
, 0, sizeof ddns_fwd_name
);
3099 if (!(oc
= lookup_option (&fqdn_universe
, client
-> sent_options
,
3101 !evaluate_option_cache (&ddns_fwd_name
, (struct packet
*)0,
3102 (struct lease
*)0, client
,
3103 client
-> sent_options
,
3104 (struct option_state
*)0,
3105 &global_scope
, oc
, MDL
))
3106 return ISC_R_SUCCESS
;
3108 /* Make a dhcid string out of either the client identifier,
3109 if we are sending one, or the interface's MAC address,
3111 memset (&ddns_dhcid
, 0, sizeof ddns_dhcid
);
3113 memset (&client_identifier
, 0, sizeof client_identifier
);
3114 if ((oc
= lookup_option (&dhcp_universe
, client
-> sent_options
,
3115 DHO_DHCP_CLIENT_IDENTIFIER
)) &&
3116 evaluate_option_cache (&client_identifier
, (struct packet
*)0,
3117 (struct lease
*)0, client
,
3118 client
-> sent_options
,
3119 (struct option_state
*)0,
3120 &global_scope
, oc
, MDL
)) {
3121 result
= get_dhcid (&ddns_dhcid
,
3122 DHO_DHCP_CLIENT_IDENTIFIER
,
3123 client_identifier
.data
,
3124 client_identifier
.len
);
3125 data_string_forget (&client_identifier
, MDL
);
3127 result
= get_dhcid (&ddns_dhcid
, 0,
3128 client
-> interface
-> hw_address
.hbuf
,
3129 client
-> interface
-> hw_address
.hlen
);
3131 data_string_forget (&ddns_fwd_name
, MDL
);
3132 return ISC_R_SUCCESS
;
3135 /* Start the resolver, if necessary. */
3136 if (!resolver_inited
) {
3137 minires_ninit (&resolver_state
);
3138 resolver_inited
= 1;
3139 resolver_state
.retrans
= 1;
3140 resolver_state
.retry
= 1;
3146 if (ddns_fwd_name
.len
&& ddns_dhcid
.len
) {
3148 rcode
= ddns_update_a (&ddns_fwd_name
,
3149 client
-> active
-> address
,
3153 rcode
= ddns_remove_a (&ddns_fwd_name
,
3154 client
-> active
-> address
,
3157 rcode
= ISC_R_FAILURE
;
3159 data_string_forget (&ddns_fwd_name
, MDL
);
3160 data_string_forget (&ddns_dhcid
, MDL
);