6 * Copyright (c) 2004-2005 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.
33 const char dhcp_ocopyright
[] =
34 "$Id$ Copyright (c) 2004-2005 Internet Systems Consortium. All rights reserved.\n";
40 #include <proto/dos.h>
41 #include <proto/exec.h>
45 struct Library
*MiamiBase
= NULL
;
46 struct Library
*SocketBase
= NULL
;
48 static void __close_bsdsocket()
52 CloseLibrary(MiamiBase
);
57 CloseLibrary(SocketBase
);
62 void openlog(const char *ident
, int logstat
, int logfac
)
64 log_debug("openlog %s %d %d\n", ident
, logstat
, logfac
);
67 int setlogmask(int pmask
)
69 log_debug("setlogmask %d\n", pmask
);
74 TIME default_lease_time
= 43200; /* 12 hours... */
75 TIME max_lease_time
= 86400; /* 24 hours... */
77 const char *path_dhclient_conf
= _PATH_DHCLIENT_CONF
;
78 const char *path_dhclient_db
= _PATH_DHCLIENT_DB
;
79 const char *path_dhclient_pid
= _PATH_DHCLIENT_PID
;
80 static char path_dhclient_script_array
[] = _PATH_DHCLIENT_SCRIPT
;
81 char *path_dhclient_script
= path_dhclient_script_array
;
83 int dhcp_max_agent_option_packet_length
= 0;
85 int interfaces_requested
= 0;
87 struct iaddr iaddr_broadcast
= { 4, { 255, 255, 255, 255 } };
88 struct iaddr iaddr_any
= { 4, { 0, 0, 0, 0 } };
89 struct in_addr inaddr_any
;
90 struct sockaddr_in sockaddr_broadcast
;
91 struct in_addr giaddr
;
93 /* ASSERT_STATE() does nothing now; it used to be
94 assert (state_is == state_shouldbe). */
95 #define ASSERT_STATE(state_is, state_shouldbe) {}
97 static char copyright
[] = "Copyright 2004-2005 Internet Systems Consortium.";
98 static char arr
[] = "All rights reserved.";
99 static char message
[] = "Internet Systems Consortium DHCP Client";
100 static char url
[] = "For info, please visit http://www.isc.org/products/DHCP";
102 u_int16_t local_port
=0;
103 u_int16_t remote_port
=0;
105 struct string_list
*client_env
=NULL
;
106 int client_env_count
=0;
111 static void usage
PROTO ((void));
113 void do_release(struct client_state
*);
116 static inline u_long
ia2ulong(struct iaddr
*ia
) { u_long
*p
= (u_long
*)&ia
->iabuf
[0]; return *p
; }
118 #define ia2ulong(x) (*(u_long *)((x)->iabuf))
120 void interface_preinit (struct client_state
*);
121 int interface_medium (struct client_state
*, char *);
122 int interface_bind (struct client_state
*);
123 /*void interface_expire (struct client_state *);
124 void interface_fail (struct client_state *);
125 void interface_release (struct client_state *);*/
126 #define interface_expire interface_stop
127 #define interface_fail interface_stop
128 #define interface_release interface_stop
129 void interface_stop (struct client_state
*);
130 int interface_timeout (struct client_state
*);
132 int main (argc
, argv
, envp
)
138 struct interface_info
*ip
;
139 struct client_state
*client
;
141 char *server
= (char *)0;
142 char *relay
= (char *)0;
144 int release_mode
= 0;
145 omapi_object_t
*listener
;
148 int no_dhclient_conf
= 0;
149 int no_dhclient_db
= 0;
150 int no_dhclient_pid
= 0;
151 int no_dhclient_script
= 0;
154 /* Make sure we have stdin, stdout and stderr. */
158 me
= (struct Process
*)FindTask(NULL
);
162 i
= open ("/dev/null", O_RDWR
);
164 i
= open ("/dev/null", O_RDWR
);
166 i
= open ("/dev/null", O_RDWR
);
167 log_perror
= 0; /* No sense logging to /dev/null. */
173 if (!(SocketBase
= OpenLibrary("bsdsocket.library", 4)))
175 fprintf(stderr
, "No TCP/IP Stack running!\n");
178 if (!(MiamiBase
= OpenLibrary("miami.library", 0)))
180 fprintf(stderr
, "No miami available!\n");
183 atexit(__close_bsdsocket
);
184 SetErrnoPtr(&errno
, sizeof(errno
));
186 static TEXT dh_conf
[256];
187 static TEXT dh_db
[288];
190 dh_conf
[0] = dh_db
[0] = '\0';
192 if ((len
= GetVar("AROSTCP/Config", dh_conf
, 256, 0)) > 0)
194 sprintf(dh_db
, "%s/dhclient.lease", dh_conf
);
195 strcpy(dh_conf
+ len
, "/dhclient.conf");
197 path_dhclient_conf
= dh_conf
;
198 path_dhclient_db
= dh_db
;
204 openlog ("dhclient", LOG_NDELAY
);
205 log_priority
= LOG_DAEMON
;
207 openlog ("dhclient", LOG_NDELAY
, LOG_DAEMON
);
210 #if !(defined (DEBUG) || defined (SYSLOG_4_2) || defined (__CYGWIN32__))
211 setlogmask (LOG_UPTO (LOG_INFO
));
215 log_debug("conf: %s", path_dhclient_conf
);
216 log_debug("db: %s", path_dhclient_db
);
219 /* Set up the OMAPI. */
220 status
= omapi_init ();
221 if (status
!= ISC_R_SUCCESS
)
222 log_fatal ("Can't initialize OMAPI: %s",
223 isc_result_totext (status
));
225 /* Set up the OMAPI wrappers for various server database internal
227 dhcp_common_objects_setup ();
229 dhcp_interface_discovery_hook
= dhclient_interface_discovery_hook
;
230 dhcp_interface_shutdown_hook
= dhclient_interface_shutdown_hook
;
231 dhcp_interface_startup_hook
= dhclient_interface_startup_hook
;
233 for (i
= 1; i
< argc
; i
++) {
234 if (!strcmp (argv
[i
], "-r")) {
237 } else if (!strcmp (argv
[i
], "-p")) {
240 local_port
= htons (atoi (argv
[i
]));
241 log_debug ("binding to user-specified port %d",
243 } else if (!strcmp (argv
[i
], "-d")) {
245 } else if (!strcmp (argv
[i
], "-pf")) {
248 path_dhclient_pid
= argv
[i
];
250 } else if (!strcmp (argv
[i
], "-cf")) {
253 path_dhclient_conf
= argv
[i
];
254 no_dhclient_conf
= 1;
255 } else if (!strcmp (argv
[i
], "-lf")) {
258 path_dhclient_db
= argv
[i
];
260 } else if (!strcmp (argv
[i
], "-sf")) {
263 path_dhclient_script
= argv
[i
];
264 no_dhclient_script
= 1;
265 } else if (!strcmp (argv
[i
], "-1")) {
267 } else if (!strcmp (argv
[i
], "-q")) {
269 quiet_interface_discovery
= 1;
270 } else if (!strcmp (argv
[i
], "-s")) {
274 } else if (!strcmp (argv
[i
], "-g")) {
278 } else if (!strcmp (argv
[i
], "-nw")) {
280 } else if (!strcmp (argv
[i
], "-n")) {
281 /* do not start up any interfaces */
282 interfaces_requested
= 1;
283 } else if (!strcmp (argv
[i
], "-w")) {
284 /* do not exit if there are no broadcast interfaces. */
286 } else if (!strcmp (argv
[i
], "-e")) {
287 struct string_list
*tmp
;
290 tmp
= dmalloc (strlen (argv
[i
]) + sizeof *tmp
, MDL
);
292 log_fatal ("No memory for %s", argv
[i
]);
293 strcpy (tmp
-> string
, argv
[i
]);
294 tmp
-> next
= client_env
;
297 } else if (!strcmp (argv
[i
], "--version")) {
298 log_info ("isc-dhclient-%s", DHCP_VERSION
);
300 } else if (argv
[i
][0] == '-') {
303 struct interface_info
*tmp
= (struct interface_info
*)0;
304 status
= interface_allocate (&tmp
, MDL
);
305 if (status
!= ISC_R_SUCCESS
)
306 log_fatal ("Can't record interface %s:%s",
307 argv
[i
], isc_result_totext (status
));
308 if (strlen (argv
[i
]) > sizeof tmp
-> name
)
309 log_fatal ("%s: interface name too long (max %ld)",
310 argv
[i
], (long)strlen (argv
[i
]));
311 strcpy (tmp
-> name
, argv
[i
]);
313 interface_reference (&tmp
-> next
,
315 interface_dereference (&interfaces
, MDL
);
317 interface_reference (&interfaces
, tmp
, MDL
);
318 tmp
-> flags
= INTERFACE_REQUESTED
;
319 interfaces_requested
= 1;
323 if (!no_dhclient_conf
&& (s
= getenv ("PATH_DHCLIENT_CONF"))) {
324 path_dhclient_conf
= s
;
326 if (!no_dhclient_db
&& (s
= getenv ("PATH_DHCLIENT_DB"))) {
327 path_dhclient_db
= s
;
329 if (!no_dhclient_pid
&& (s
= getenv ("PATH_DHCLIENT_PID"))) {
330 path_dhclient_pid
= s
;
332 if (!no_dhclient_script
&& (s
= getenv ("PATH_DHCLIENT_SCRIPT"))) {
333 path_dhclient_script
= s
;
336 /* first kill of any currently running client */
344 if ((pidfd
= fopen(path_dhclient_pid
, "r")) != NULL
) {
345 e
= fscanf(pidfd
, "%ld\n", &temp
);
346 oldpid
= (pid_t
)temp
;
348 if (e
!= 0 && e
!= EOF
) {
350 if (kill(oldpid
, SIGTERM
) == 0)
351 unlink(path_dhclient_pid
);
359 log_info ("%s %s", message
, DHCP_VERSION
);
360 log_info ("%s", copyright
);
361 log_info ("%s", arr
);
362 log_info ("%s", url
);
367 /* If we're given a relay agent address to insert, for testing
368 purposes, figure out what it is. */
370 if (!inet_aton (relay
, &giaddr
)) {
372 he
= gethostbyname (relay
);
374 memcpy (&giaddr
, he
-> h_addr_list
[0],
377 log_fatal ("%s: no such host", relay
);
382 /* Default to the DHCP/BOOTP port. */
384 /* If we're faking a relay agent, and we're not using loopback,
385 use the server port, not the client port. */
386 if (relay
&& giaddr
.s_addr
!= htonl (INADDR_LOOPBACK
)) {
387 local_port
= htons(67);
389 ent
= getservbyname ("dhcpc", "udp");
391 local_port
= htons (68);
393 local_port
= ent
-> s_port
;
402 /* If we're faking a relay agent, and we're not using loopback,
403 we're using the server port, not the client port. */
404 if (relay
&& giaddr
.s_addr
!= htonl (INADDR_LOOPBACK
)) {
405 remote_port
= local_port
;
407 remote_port
= htons (ntohs (local_port
) - 1); /* XXX */
409 /* Get the current time... */
410 GET_TIME (&cur_time
);
412 sockaddr_broadcast
.sin_family
= AF_INET
;
413 sockaddr_broadcast
.sin_port
= remote_port
;
415 if (!inet_aton (server
, &sockaddr_broadcast
.sin_addr
)) {
417 he
= gethostbyname (server
);
419 memcpy (&sockaddr_broadcast
.sin_addr
,
420 he
-> h_addr_list
[0],
421 sizeof sockaddr_broadcast
.sin_addr
);
423 sockaddr_broadcast
.sin_addr
.s_addr
=
427 sockaddr_broadcast
.sin_addr
.s_addr
= INADDR_BROADCAST
;
430 inaddr_any
.s_addr
= INADDR_ANY
;
432 /* Discover all the network interfaces. */
433 discover_interfaces (DISCOVER_UNCONFIGURED
);
435 /* Parse the dhclient.conf file. */
438 /* Parse the lease database. */
439 read_client_leases ();
441 /* Rewrite the lease database... */
442 rewrite_client_leases ();
445 /* config_counter(&snd_counter, &rcv_counter); */
447 /* If no broadcast interfaces were discovered, call the script
450 #ifndef BUILTIN_IFCONFIG
451 /* Call dhclient-script with the NBI flag, in case somebody
453 script_init ((struct client_state
*)0, "NBI",
454 (struct string_list
*)0);
455 script_go ((struct client_state
*)0);
457 /* If we haven't been asked to persist, waiting for new
458 interfaces, then just exit. */
460 /* Nothing more to do. */
461 log_info ("No broadcast interfaces found - exiting.");
464 } else if (!release_mode
) {
465 /* Call the script with the list of interfaces. */
466 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
467 /* If interfaces were specified, don't configure
468 interfaces that weren't specified! */
469 if (interfaces_requested
&&
470 ((ip
-> flags
& (INTERFACE_REQUESTED
|
471 INTERFACE_AUTOMATIC
)) !=
472 INTERFACE_REQUESTED
))
474 #ifdef BUILTIN_IFCONFIG
475 interface_preinit (ip
->client
);
477 script_init (ip
-> client
,
478 "PREINIT", (struct string_list
*)0);
479 if (ip
-> client
-> alias
)
480 script_write_params (ip
-> client
, "alias_",
481 ip
-> client
-> alias
);
482 script_go (ip
-> client
);
487 /* At this point, all the interfaces that the script thinks
488 are relevant should be running, so now we once again call
489 discover_interfaces(), and this time ask it to actually set
490 up the interfaces. */
491 discover_interfaces (interfaces_requested
495 /* Make up a seed for the random number generator from current
496 time plus the sum of the last four bytes of each
497 interface's hardware address interpreted as an integer.
498 Not much entropy, but we're booting, so we're not likely to
499 find anything better. */
501 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
504 &ip
-> hw_address
.hbuf
[ip
-> hw_address
.hlen
-
505 sizeof seed
], sizeof seed
);
508 srandom (seed
+ cur_time
);
510 /* Start a configuration state machine for each interface. */
511 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
512 ip
-> flags
|= INTERFACE_RUNNING
;
513 for (client
= ip
-> client
; client
; client
= client
-> next
) {
517 client
-> state
= S_INIT
;
518 /* Set up a timeout to start the initialization
520 add_timeout (cur_time
+ random () % 5,
521 state_reboot
, client
, 0, 0);
529 /* Start up a listener for the object management API protocol. */
530 if (top_level_config
.omapi_port
!= -1) {
531 listener
= (omapi_object_t
*)0;
532 result
= omapi_generic_new (&listener
, MDL
);
533 if (result
!= ISC_R_SUCCESS
)
534 log_fatal ("Can't allocate new generic object: %s\n",
535 isc_result_totext (result
));
536 result
= omapi_protocol_listen (listener
,
538 top_level_config
.omapi_port
,
540 if (result
!= ISC_R_SUCCESS
)
541 log_fatal ("Can't start OMAPI protocol: %s",
542 isc_result_totext (result
));
545 /* Set up the bootp packet handler... */
546 bootp_packet_handler
= do_packet
;
548 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
549 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
550 dmalloc_cutoff_generation
= dmalloc_generation
;
551 dmalloc_longterm
= dmalloc_outstanding
;
552 dmalloc_outstanding
= 0;
555 /* If we're not supposed to wait before getting the address,
560 /* If we're not going to daemonize, write the pid file
562 if (no_daemon
|| nowait
)
563 write_client_pid_file ();
565 /* Start dispatching packets and timeouts... */
574 log_info ("%s %s", message
, DHCP_VERSION
);
575 log_info ("%s", copyright
);
576 log_info ("%s", arr
);
577 log_info ("%s", url
);
579 log_error ("Usage: dhclient [-1dqr] [-nw] [-p <port>] %s",
581 log_error (" [-cf config-file] [-lf lease-file]%s",
582 "[-pf pid-file] [-e VAR=val]");
583 log_fatal (" [-sf script-file] [interface]");
586 isc_result_t
find_class (struct class **c
,
587 const char *s
, const char *file
, int line
)
592 int check_collection (packet
, lease
, collection
)
593 struct packet
*packet
;
595 struct collection
*collection
;
600 void classify (packet
, class)
601 struct packet
*packet
;
606 int unbill_class (lease
, class)
613 int find_subnet (struct subnet
**sp
,
614 struct iaddr addr
, const char *file
, int line
)
619 /* Individual States:
621 * Each routine is called from the dhclient_state_machine() in one of
623 * -> entering INIT state
624 * -> recvpacket_flag == 0: timeout in this state
625 * -> otherwise: received a packet in this state
627 * Return conditions as handled by dhclient_state_machine():
628 * Returns 1, sendpacket_flag = 1: send packet, reset timer.
629 * Returns 1, sendpacket_flag = 0: just reset the timer (wait for a milestone).
630 * Returns 0: finish the nap which was interrupted for no good reason.
632 * Several per-interface variables are used to keep track of the process:
633 * active_lease: the lease that is being used on the interface
634 * (null pointer if not configured yet).
635 * offered_leases: leases corresponding to DHCPOFFER messages that have
636 * been sent to us by DHCP servers.
637 * acked_leases: leases corresponding to DHCPACK messages that have been
638 * sent to us by DHCP servers.
639 * sendpacket: DHCP packet we're trying to send.
640 * destination: IP address to send sendpacket to
641 * In addition, there are several relevant per-lease variables.
642 * T1_expiry, T2_expiry, lease_expiry: lease milestones
643 * In the active lease, these control the process of renewing the lease;
644 * In leases on the acked_leases list, this simply determines when we
645 * can no longer legitimately use the lease.
648 void state_reboot (cpp
)
651 struct client_state
*client
= cpp
;
653 /* If we don't remember an active lease, go straight to INIT. */
654 if (!client
-> active
||
655 client
-> active
-> is_bootp
||
656 client
-> active
-> expiry
<= cur_time
) {
661 /* We are in the rebooting state. */
662 client
-> state
= S_REBOOTING
;
664 /* make_request doesn't initialize xid because it normally comes
665 from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
666 so pick an xid now. */
667 client
-> xid
= random ();
669 /* Make a DHCPREQUEST packet, and set appropriate per-interface
671 make_request (client
, client
-> active
);
672 client
-> destination
= iaddr_broadcast
;
673 client
-> first_sending
= cur_time
;
674 client
-> interval
= client
-> config
-> initial_interval
;
676 /* Zap the medium list... */
677 client
-> medium
= (struct string_list
*)0;
679 /* Send out the first DHCPREQUEST packet. */
680 send_request (client
);
683 /* Called when a lease has completely expired and we've been unable to
686 void state_init (cpp
)
689 struct client_state
*client
= cpp
;
691 ASSERT_STATE(state
, S_INIT
);
693 /* Make a DHCPDISCOVER packet, and set appropriate per-interface
695 make_discover (client
, client
-> active
);
696 client
-> xid
= client
-> packet
.xid
;
697 client
-> destination
= iaddr_broadcast
;
698 client
-> state
= S_SELECTING
;
699 client
-> first_sending
= cur_time
;
700 client
-> interval
= client
-> config
-> initial_interval
;
702 /* Add an immediate timeout to cause the first DHCPDISCOVER packet
704 send_discover (client
);
707 /* state_selecting is called when one or more DHCPOFFER packets have been
708 received and a configurable period of time has passed. */
710 void state_selecting (cpp
)
713 struct client_state
*client
= cpp
;
714 struct client_lease
*lp
, *next
, *picked
;
717 ASSERT_STATE(state
, S_SELECTING
);
719 /* Cancel state_selecting and send_discover timeouts, since either
720 one could have got us here. */
721 cancel_timeout (state_selecting
, client
);
722 cancel_timeout (send_discover
, client
);
724 /* We have received one or more DHCPOFFER packets. Currently,
725 the only criterion by which we judge leases is whether or
726 not we get a response when we arp for them. */
727 picked
= (struct client_lease
*)0;
728 for (lp
= client
-> offered_leases
; lp
; lp
= next
) {
731 /* Check to see if we got an ARPREPLY for the address
732 in this particular lease. */
735 picked
-> next
= (struct client_lease
*)0;
737 destroy_client_lease (lp
);
740 client
-> offered_leases
= (struct client_lease
*)0;
742 /* If we just tossed all the leases we were offered, go back
745 client
-> state
= S_INIT
;
750 /* If it was a BOOTREPLY, we can just take the address right now. */
751 if (picked
-> is_bootp
) {
752 client
-> new = picked
;
754 /* Make up some lease expiry times
755 XXX these should be configurable. */
756 client
-> new -> expiry
= cur_time
+ 12000;
757 client
-> new -> renewal
+= cur_time
+ 8000;
758 client
-> new -> rebind
+= cur_time
+ 10000;
760 client
-> state
= S_REQUESTING
;
762 /* Bind to the address we received. */
767 /* Go to the REQUESTING state. */
768 client
-> destination
= iaddr_broadcast
;
769 client
-> state
= S_REQUESTING
;
770 client
-> first_sending
= cur_time
;
771 client
-> interval
= client
-> config
-> initial_interval
;
773 /* Make a DHCPREQUEST packet from the lease we picked. */
774 make_request (client
, picked
);
775 client
-> xid
= client
-> packet
.xid
;
777 /* Toss the lease we picked - we'll get it back in a DHCPACK. */
778 destroy_client_lease (picked
);
780 /* Add an immediate timeout to send the first DHCPREQUEST packet. */
781 send_request (client
);
784 /* state_requesting is called when we receive a DHCPACK message after
785 having sent out one or more DHCPREQUEST packets. */
787 void dhcpack (packet
)
788 struct packet
*packet
;
790 struct interface_info
*ip
= packet
-> interface
;
791 struct client_state
*client
;
792 struct client_lease
*lease
;
793 struct option_cache
*oc
;
794 struct data_string ds
;
796 /* If we're not receptive to an offer right now, or if the offer
797 has an unrecognizable transaction id, then just drop it. */
798 for (client
= ip
-> client
; client
; client
= client
-> next
) {
799 if (client
-> xid
== packet
-> raw
-> xid
)
803 (packet
-> interface
-> hw_address
.hlen
- 1 !=
804 packet
-> raw
-> hlen
) ||
805 (memcmp (&packet
-> interface
-> hw_address
.hbuf
[1],
806 packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
))) {
808 log_debug ("DHCPACK in wrong transaction.");
813 if (client
-> state
!= S_REBOOTING
&&
814 client
-> state
!= S_REQUESTING
&&
815 client
-> state
!= S_RENEWING
&&
816 client
-> state
!= S_REBINDING
) {
818 log_debug ("DHCPACK in wrong state.");
823 log_info ("DHCPACK from %s", piaddr (packet
-> client_addr
));
825 lease
= packet_to_lease (packet
, client
);
827 log_info ("packet_to_lease failed.");
831 client
-> new = lease
;
833 /* Stop resending DHCPREQUEST. */
834 cancel_timeout (send_request
, client
);
836 /* Figure out the lease time. */
837 oc
= lookup_option (&dhcp_universe
, client
-> new -> options
,
838 DHO_DHCP_LEASE_TIME
);
839 memset (&ds
, 0, sizeof ds
);
841 evaluate_option_cache (&ds
, packet
, (struct lease
*)0, client
,
842 packet
-> options
, client
-> new -> options
,
843 &global_scope
, oc
, MDL
)) {
845 client
-> new -> expiry
= getULong (ds
.data
);
847 client
-> new -> expiry
= 0;
848 data_string_forget (&ds
, MDL
);
850 client
-> new -> expiry
= 0;
852 if (!client
-> new -> expiry
) {
853 log_error ("no expiry time on offered lease.");
854 /* XXX this is going to be bad - if this _does_
855 XXX happen, we should probably dynamically
856 XXX disqualify the DHCP server that gave us the
857 XXX bad packet from future selections and
858 XXX then go back into the init state. */
863 /* A number that looks negative here is really just very large,
864 because the lease expiry offset is unsigned. */
865 if (client
-> new -> expiry
< 0)
866 client
-> new -> expiry
= TIME_MAX
;
867 /* Take the server-provided renewal time if there is one. */
868 oc
= lookup_option (&dhcp_universe
, client
-> new -> options
,
869 DHO_DHCP_RENEWAL_TIME
);
871 evaluate_option_cache (&ds
, packet
, (struct lease
*)0, client
,
872 packet
-> options
, client
-> new -> options
,
873 &global_scope
, oc
, MDL
)) {
875 client
-> new -> renewal
= getULong (ds
.data
);
877 client
-> new -> renewal
= 0;
878 data_string_forget (&ds
, MDL
);
880 client
-> new -> renewal
= 0;
882 /* If it wasn't specified by the server, calculate it. */
883 if (!client
-> new -> renewal
)
884 client
-> new -> renewal
= client
-> new -> expiry
/ 2 + 1;
886 if (client
-> new -> renewal
<= 0)
887 client
-> new -> renewal
= TIME_MAX
;
889 /* Now introduce some randomness to the renewal time: */
890 if (client
-> new -> renewal
<= TIME_MAX
/ 3 - 3)
891 client
-> new -> renewal
=
892 (((client
-> new -> renewal
+ 3) * 3 / 4) +
893 (random () % /* XXX NUMS */
894 ((client
-> new -> renewal
+ 3) / 4)));
896 /* Same deal with the rebind time. */
897 oc
= lookup_option (&dhcp_universe
, client
-> new -> options
,
898 DHO_DHCP_REBINDING_TIME
);
900 evaluate_option_cache (&ds
, packet
, (struct lease
*)0, client
,
901 packet
-> options
, client
-> new -> options
,
902 &global_scope
, oc
, MDL
)) {
904 client
-> new -> rebind
= getULong (ds
.data
);
906 client
-> new -> rebind
= 0;
907 data_string_forget (&ds
, MDL
);
909 client
-> new -> rebind
= 0;
911 if (client
-> new -> rebind
<= 0) {
912 if (client
-> new -> expiry
<= TIME_MAX
/ 7)
913 client
-> new -> rebind
=
914 client
-> new -> expiry
* 7 / 8;
916 client
-> new -> rebind
=
917 client
-> new -> expiry
/ 8 * 7;
920 /* Make sure our randomness didn't run the renewal time past the
922 if (client
-> new -> renewal
> client
-> new -> rebind
) {
923 if (client
-> new -> rebind
<= TIME_MAX
/ 3)
924 client
-> new -> renewal
=
925 client
-> new -> rebind
* 3 / 4;
927 client
-> new -> renewal
=
928 client
-> new -> rebind
/ 4 * 3;
931 client
-> new -> expiry
+= cur_time
;
932 /* Lease lengths can never be negative. */
933 if (client
-> new -> expiry
< cur_time
)
934 client
-> new -> expiry
= TIME_MAX
;
935 client
-> new -> renewal
+= cur_time
;
936 if (client
-> new -> renewal
< cur_time
)
937 client
-> new -> renewal
= TIME_MAX
;
938 client
-> new -> rebind
+= cur_time
;
939 if (client
-> new -> rebind
< cur_time
)
940 client
-> new -> rebind
= TIME_MAX
;
945 void bind_lease (client
)
946 struct client_state
*client
;
948 /* Remember the medium. */
949 client
-> new -> medium
= client
-> medium
;
951 #ifdef BUILTIN_IFCONFIG
952 if (interface_bind (client
)) {
954 /* Run the client script with the new parameters. */
955 script_init (client
, (client
-> state
== S_REQUESTING
957 : (client
-> state
== S_RENEWING
959 : (client
-> state
== S_REBOOTING
960 ? "REBOOT" : "REBIND"))),
961 client
-> new -> medium
);
962 if (client
-> active
&& client
-> state
!= S_REBOOTING
)
963 script_write_params (client
, "old_", client
-> active
);
964 script_write_params (client
, "new_", client
-> new);
966 script_write_params (client
, "alias_", client
-> alias
);
968 /* If the BOUND/RENEW code detects another machine using the
969 offered address, it exits nonzero. We need to send a
970 DHCPDECLINE and toss the lease. */
971 if (script_go (client
)) {
973 make_decline (client
, client
-> new);
974 send_decline (client
);
975 destroy_client_lease (client
-> new);
976 client
-> new = (struct client_lease
*)0;
981 /* Write out the new lease. */
982 write_client_lease (client
, client
-> new, 0, 0);
984 /* Replace the old active lease with the new one. */
985 if (client
-> active
)
986 destroy_client_lease (client
-> active
);
987 client
-> active
= client
-> new;
988 client
-> new = (struct client_lease
*)0;
990 /* Set up a timeout to start the renewal process. */
991 add_timeout (client
-> active
-> renewal
,
992 state_bound
, client
, 0, 0);
994 log_info ("bound to %s -- renewal in %ld seconds.",
995 piaddr (client
-> active
-> address
),
996 (long)(client
-> active
-> renewal
- cur_time
));
997 client
-> state
= S_BOUND
;
998 reinitialize_interfaces ();
1000 if (client
-> config
-> do_forward_update
) {
1001 client
-> dns_update_timeout
= 1;
1002 add_timeout (cur_time
+ 1, client_dns_update_timeout
,
1007 /* state_bound is called when we've successfully bound to a particular
1008 lease, but the renewal time on that lease has expired. We are
1009 expected to unicast a DHCPREQUEST to the server that gave us our
1012 void state_bound (cpp
)
1015 struct client_state
*client
= cpp
;
1016 struct option_cache
*oc
;
1017 struct data_string ds
;
1019 ASSERT_STATE(state
, S_BOUND
);
1021 /* T1 has expired. */
1022 make_request (client
, client
-> active
);
1023 client
-> xid
= client
-> packet
.xid
;
1025 memset (&ds
, 0, sizeof ds
);
1026 oc
= lookup_option (&dhcp_universe
, client
-> active
-> options
,
1027 DHO_DHCP_SERVER_IDENTIFIER
);
1029 evaluate_option_cache (&ds
, (struct packet
*)0, (struct lease
*)0,
1030 client
, (struct option_state
*)0,
1031 client
-> active
-> options
,
1032 &global_scope
, oc
, MDL
)) {
1034 memcpy (client
-> destination
.iabuf
, ds
.data
, 4);
1035 client
-> destination
.len
= 4;
1037 client
-> destination
= iaddr_broadcast
;
1039 data_string_forget (&ds
, MDL
);
1041 client
-> destination
= iaddr_broadcast
;
1043 client
-> first_sending
= cur_time
;
1044 client
-> interval
= client
-> config
-> initial_interval
;
1045 client
-> state
= S_RENEWING
;
1047 /* Send the first packet immediately. */
1048 send_request (client
);
1051 /* state_stop is called when we've been told to shut down. We unconfigure
1052 the interfaces, and then stop operating until told otherwise. */
1054 void state_stop (cpp
)
1057 struct client_state
*client
= cpp
;
1059 /* Cancel all timeouts. */
1060 cancel_timeout (state_selecting
, client
);
1061 cancel_timeout (send_discover
, client
);
1062 cancel_timeout (send_request
, client
);
1063 cancel_timeout (state_bound
, client
);
1065 /* If we have an address, unconfigure it. */
1066 if (client
-> active
) {
1067 #ifdef BUILTIN_IFCONFIG
1068 interface_stop (client
);
1070 script_init (client
, "STOP", client
-> active
-> medium
);
1071 script_write_params (client
, "old_", client
-> active
);
1072 if (client
-> alias
)
1073 script_write_params (client
, "alias_",
1080 int commit_leases ()
1085 int write_lease (lease
)
1086 struct lease
*lease
;
1091 int write_host (host
)
1092 struct host_decl
*host
;
1097 void db_startup (testp
)
1103 struct packet
*packet
;
1105 struct iaddrlist
*ap
;
1107 if (packet
-> raw
-> op
!= BOOTREPLY
)
1110 /* If there's a reject list, make sure this packet's sender isn't
1112 for (ap
= packet
-> interface
-> client
-> config
-> reject_list
;
1113 ap
; ap
= ap
-> next
) {
1114 if (addr_eq (packet
-> client_addr
, ap
-> addr
)) {
1115 log_info ("BOOTREPLY from %s rejected.",
1116 piaddr (ap
-> addr
));
1126 struct packet
*packet
;
1128 struct iaddrlist
*ap
;
1129 void (*handler
) PROTO ((struct packet
*));
1132 switch (packet
-> packet_type
) {
1134 handler
= dhcpoffer
;
1152 /* If there's a reject list, make sure this packet's sender isn't
1154 for (ap
= packet
-> interface
-> client
-> config
-> reject_list
;
1155 ap
; ap
= ap
-> next
) {
1156 if (addr_eq (packet
-> client_addr
, ap
-> addr
)) {
1157 log_info ("%s from %s rejected.",
1158 type
, piaddr (ap
-> addr
));
1162 (*handler
) (packet
);
1165 void dhcpoffer (packet
)
1166 struct packet
*packet
;
1168 struct interface_info
*ip
= packet
-> interface
;
1169 struct client_state
*client
;
1170 struct client_lease
*lease
, *lp
;
1173 const char *name
= packet
-> packet_type
? "DHCPOFFER" : "BOOTREPLY";
1177 dump_packet (packet
);
1180 /* Find a client state that matches the xid... */
1181 for (client
= ip
-> client
; client
; client
= client
-> next
)
1182 if (client
-> xid
== packet
-> raw
-> xid
)
1185 /* If we're not receptive to an offer right now, or if the offer
1186 has an unrecognizable transaction id, then just drop it. */
1188 client
-> state
!= S_SELECTING
||
1189 (packet
-> interface
-> hw_address
.hlen
- 1 !=
1190 packet
-> raw
-> hlen
) ||
1191 (memcmp (&packet
-> interface
-> hw_address
.hbuf
[1],
1192 packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
))) {
1194 log_debug ("%s in wrong transaction.", name
);
1199 sprintf (obuf
, "%s from %s", name
, piaddr (packet
-> client_addr
));
1202 /* If this lease doesn't supply the minimum required parameters,
1204 if (client
-> config
-> required_options
) {
1205 for (i
= 0; client
-> config
-> required_options
[i
]; i
++) {
1207 (&dhcp_universe
, packet
-> options
,
1208 client
-> config
-> required_options
[i
])) {
1209 log_info ("%s: no %s option.",
1210 obuf
, (dhcp_universe
.options
1211 [client
-> config
-> required_options
[i
]]
1218 /* If we've already seen this lease, don't record it again. */
1219 for (lease
= client
-> offered_leases
; lease
; lease
= lease
-> next
) {
1220 if (lease
-> address
.len
== sizeof packet
-> raw
-> yiaddr
&&
1221 !memcmp (lease
-> address
.iabuf
,
1222 &packet
-> raw
-> yiaddr
, lease
-> address
.len
)) {
1223 log_debug ("%s: already seen.", obuf
);
1228 lease
= packet_to_lease (packet
, client
);
1230 log_info ("%s: packet_to_lease failed.", obuf
);
1234 /* If this lease was acquired through a BOOTREPLY, record that
1236 if (!packet
-> options_valid
|| !packet
-> packet_type
)
1237 lease
-> is_bootp
= 1;
1239 /* Record the medium under which this lease was offered. */
1240 lease
-> medium
= client
-> medium
;
1242 /* Figure out when we're supposed to stop selecting. */
1243 stop_selecting
= (client
-> first_sending
+
1244 client
-> config
-> select_interval
);
1246 /* If this is the lease we asked for, put it at the head of the
1247 list, and don't mess with the arp request timeout. */
1248 if (lease
-> address
.len
== client
-> requested_address
.len
&&
1249 !memcmp (lease
-> address
.iabuf
,
1250 client
-> requested_address
.iabuf
,
1251 client
-> requested_address
.len
)) {
1252 lease
-> next
= client
-> offered_leases
;
1253 client
-> offered_leases
= lease
;
1255 /* Put the lease at the end of the list. */
1256 lease
-> next
= (struct client_lease
*)0;
1257 if (!client
-> offered_leases
)
1258 client
-> offered_leases
= lease
;
1260 for (lp
= client
-> offered_leases
; lp
-> next
;
1267 /* If the selecting interval has expired, go immediately to
1268 state_selecting(). Otherwise, time out into
1269 state_selecting at the select interval. */
1270 if (stop_selecting
<= 0)
1271 state_selecting (client
);
1273 add_timeout (stop_selecting
, state_selecting
, client
, 0, 0);
1274 cancel_timeout (send_discover
, client
);
1276 log_info ("%s", obuf
);
1279 /* Allocate a client_lease structure and initialize it from the parameters
1280 in the specified packet. */
1282 struct client_lease
*packet_to_lease (packet
, client
)
1283 struct packet
*packet
;
1284 struct client_state
*client
;
1286 struct client_lease
*lease
;
1288 struct option_cache
*oc
;
1289 struct data_string data
;
1291 lease
= (struct client_lease
*)new_client_lease (MDL
);
1294 log_error ("packet_to_lease: no memory to record lease.\n");
1295 return (struct client_lease
*)0;
1298 memset (lease
, 0, sizeof *lease
);
1300 /* Copy the lease options. */
1301 option_state_reference (&lease
-> options
, packet
-> options
, MDL
);
1303 lease
-> address
.len
= sizeof (packet
-> raw
-> yiaddr
);
1304 memcpy (lease
-> address
.iabuf
, &packet
-> raw
-> yiaddr
,
1305 lease
-> address
.len
);
1307 memset (&data
, 0, sizeof data
);
1309 if (client
-> config
-> vendor_space_name
) {
1310 i
= DHO_VENDOR_ENCAPSULATED_OPTIONS
;
1312 /* See if there was a vendor encapsulation option. */
1313 oc
= lookup_option (&dhcp_universe
, lease
-> options
, i
);
1315 client
-> config
-> vendor_space_name
&&
1316 evaluate_option_cache (&data
, packet
,
1317 (struct lease
*)0, client
,
1318 packet
-> options
, lease
-> options
,
1319 &global_scope
, oc
, MDL
)) {
1321 parse_encapsulated_suboptions
1322 (packet
-> options
, &dhcp_options
[i
],
1323 data
.data
, data
.len
, &dhcp_universe
,
1324 client
-> config
-> vendor_space_name
1327 data_string_forget (&data
, MDL
);
1332 /* Figure out the overload flag. */
1333 oc
= lookup_option (&dhcp_universe
, lease
-> options
,
1334 DHO_DHCP_OPTION_OVERLOAD
);
1336 evaluate_option_cache (&data
, packet
, (struct lease
*)0, client
,
1337 packet
-> options
, lease
-> options
,
1338 &global_scope
, oc
, MDL
)) {
1343 data_string_forget (&data
, MDL
);
1347 /* If the server name was filled out, copy it. */
1348 if (!(i
& 2) && packet
-> raw
-> sname
[0]) {
1350 /* Don't count on the NUL terminator. */
1351 for (len
= 0; len
< 64; len
++)
1352 if (!packet
-> raw
-> sname
[len
])
1354 lease
-> server_name
= dmalloc (len
+ 1, MDL
);
1355 if (!lease
-> server_name
) {
1356 log_error ("dhcpoffer: no memory for server name.\n");
1357 destroy_client_lease (lease
);
1358 return (struct client_lease
*)0;
1360 memcpy (lease
-> server_name
,
1361 packet
-> raw
-> sname
, len
);
1362 lease
-> server_name
[len
] = 0;
1366 /* Ditto for the filename. */
1367 if (!(i
& 1) && packet
-> raw
-> file
[0]) {
1369 /* Don't count on the NUL terminator. */
1370 for (len
= 0; len
< 64; len
++)
1371 if (!packet
-> raw
-> file
[len
])
1373 lease
-> filename
= dmalloc (len
+ 1, MDL
);
1374 if (!lease
-> filename
) {
1375 log_error ("dhcpoffer: no memory for filename.\n");
1376 destroy_client_lease (lease
);
1377 return (struct client_lease
*)0;
1379 memcpy (lease
-> filename
,
1380 packet
-> raw
-> file
, len
);
1381 lease
-> filename
[len
] = 0;
1385 execute_statements_in_scope ((struct binding_value
**)0,
1386 (struct packet
*)packet
,
1387 (struct lease
*)0, client
,
1388 lease
-> options
, lease
-> options
,
1390 client
-> config
-> on_receipt
,
1396 void dhcpnak (packet
)
1397 struct packet
*packet
;
1399 struct interface_info
*ip
= packet
-> interface
;
1400 struct client_state
*client
;
1402 /* Find a client state that matches the xid... */
1403 for (client
= ip
-> client
; client
; client
= client
-> next
)
1404 if (client
-> xid
== packet
-> raw
-> xid
)
1407 /* If we're not receptive to an offer right now, or if the offer
1408 has an unrecognizable transaction id, then just drop it. */
1410 (packet
-> interface
-> hw_address
.hlen
- 1 !=
1411 packet
-> raw
-> hlen
) ||
1412 (memcmp (&packet
-> interface
-> hw_address
.hbuf
[1],
1413 packet
-> raw
-> chaddr
, packet
-> raw
-> hlen
))) {
1415 log_debug ("DHCPNAK in wrong transaction.");
1420 if (client
-> state
!= S_REBOOTING
&&
1421 client
-> state
!= S_REQUESTING
&&
1422 client
-> state
!= S_RENEWING
&&
1423 client
-> state
!= S_REBINDING
) {
1425 log_debug ("DHCPNAK in wrong state.");
1430 log_info ("DHCPNAK from %s", piaddr (packet
-> client_addr
));
1432 if (!client
-> active
) {
1434 log_info ("DHCPNAK with no active lease.\n");
1439 destroy_client_lease (client
-> active
);
1440 client
-> active
= (struct client_lease
*)0;
1442 /* Stop sending DHCPREQUEST packets... */
1443 cancel_timeout (send_request
, client
);
1445 client
-> state
= S_INIT
;
1446 state_init (client
);
1449 /* Send out a DHCPDISCOVER packet, and set a timeout to send out another
1450 one after the right interval has expired. If we don't get an offer by
1451 the time we reach the panic interval, call the panic function. */
1453 void send_discover (cpp
)
1456 struct client_state
*client
= cpp
;
1462 /* Figure out how long it's been since we started transmitting. */
1463 interval
= cur_time
- client
-> first_sending
;
1465 /* If we're past the panic timeout, call the script and tell it
1466 we haven't found anything for this interface yet. */
1467 if (interval
> client
-> config
-> timeout
) {
1468 state_panic (client
);
1472 /* If we're selecting media, try the whole list before doing
1473 the exponential backoff, but if we've already received an
1474 offer, stop looping, because we obviously have it right. */
1475 if (!client
-> offered_leases
&&
1476 client
-> config
-> media
) {
1479 if (client
-> medium
) {
1480 client
-> medium
= client
-> medium
-> next
;
1483 if (!client
-> medium
) {
1485 log_fatal ("No valid media types for %s!",
1486 client
-> interface
-> name
);
1488 client
-> config
-> media
;
1492 log_info ("Trying medium \"%s\" %d",
1493 client
-> medium
-> string
, increase
);
1494 #ifdef BUILTIN_IFCONFIG
1495 if (interface_medium (client
, client
-> medium
-> string
)) {
1497 script_init (client
, "MEDIUM", client
-> medium
);
1498 if (script_go (client
)) {
1505 /* If we're supposed to increase the interval, do so. If it's
1506 currently zero (i.e., we haven't sent any packets yet), set
1507 it to initial_interval; otherwise, add to it a random number
1508 between zero and two times itself. On average, this means
1509 that it will double with every transmission. */
1511 if (!client
-> interval
)
1512 client
-> interval
=
1513 client
-> config
-> initial_interval
;
1515 client
-> interval
+= ((random () >> 2) %
1516 (2 * client
-> interval
));
1518 /* Don't backoff past cutoff. */
1519 if (client
-> interval
>
1520 client
-> config
-> backoff_cutoff
)
1521 client
-> interval
=
1522 ((client
-> config
-> backoff_cutoff
/ 2)
1523 + ((random () >> 2) %
1524 client
-> config
-> backoff_cutoff
));
1525 } else if (!client
-> interval
)
1526 client
-> interval
= client
-> config
-> initial_interval
;
1528 /* If the backoff would take us to the panic timeout, just use that
1530 if (cur_time
+ client
-> interval
>
1531 client
-> first_sending
+ client
-> config
-> timeout
)
1532 client
-> interval
=
1533 (client
-> first_sending
+
1534 client
-> config
-> timeout
) - cur_time
+ 1;
1536 /* Record the number of seconds since we started sending. */
1537 if (interval
< 65536)
1538 client
-> packet
.secs
= htons (interval
);
1540 client
-> packet
.secs
= htons (65535);
1541 client
-> secs
= client
-> packet
.secs
;
1543 log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",
1544 client
-> name
? client
-> name
: client
-> interface
-> name
,
1545 inet_ntoa (sockaddr_broadcast
.sin_addr
),
1546 ntohs (sockaddr_broadcast
.sin_port
), (long)(client
-> interval
));
1548 /* Send out a packet. */
1549 result
= send_packet (client
-> interface
, (struct packet
*)0,
1551 client
-> packet_length
,
1552 inaddr_any
, &sockaddr_broadcast
,
1553 (struct hardware
*)0);
1556 /* FIXME: Shouldn't we log an error here? */
1559 add_timeout (cur_time
+ client
-> interval
,
1560 send_discover
, client
, 0, 0);
1563 /* state_panic gets called if we haven't received any offers in a preset
1564 amount of time. When this happens, we try to use existing leases that
1565 haven't yet expired, and failing that, we call the client script and
1566 hope it can do something. */
1568 void state_panic (cpp
)
1571 struct client_state
*client
= cpp
;
1572 struct client_lease
*loop
;
1573 struct client_lease
*lp
;
1575 loop
= lp
= client
-> active
;
1577 log_info ("No DHCPOFFERS received.");
1579 /* We may not have an active lease, but we may have some
1580 predefined leases that we can try. */
1581 if (!client
-> active
&& client
-> leases
)
1584 /* Run through the list of leases and see if one can be used. */
1585 while (client
-> active
) {
1586 if (client
-> active
-> expiry
> cur_time
) {
1587 log_info ("Trying recorded lease %s",
1588 piaddr (client
-> active
-> address
));
1589 #ifdef BUILTIN_IFCONFIG
1590 if (interface_timeout (client
)) {
1592 /* Run the client script with the existing
1594 script_init (client
, "TIMEOUT",
1595 client
-> active
-> medium
);
1596 script_write_params (client
, "new_", client
-> active
);
1597 if (client
-> alias
)
1598 script_write_params (client
, "alias_",
1601 /* If the old lease is still good and doesn't
1602 yet need renewal, go into BOUND state and
1603 timeout at the renewal time. */
1604 if (!script_go (client
)) {
1606 if (cur_time
< client
-> active
-> renewal
) {
1607 client
-> state
= S_BOUND
;
1608 log_info ("bound: renewal in %ld %s.",
1609 (long)(client
-> active
-> renewal
-
1610 cur_time
), "seconds");
1611 add_timeout (client
-> active
-> renewal
,
1612 state_bound
, client
, 0, 0);
1614 client
-> state
= S_BOUND
;
1615 log_info ("bound: immediate renewal.");
1616 state_bound (client
);
1618 reinitialize_interfaces ();
1624 /* If there are no other leases, give up. */
1625 if (!client
-> leases
) {
1626 client
-> leases
= client
-> active
;
1627 client
-> active
= (struct client_lease
*)0;
1632 /* Otherwise, put the active lease at the end of the
1633 lease list, and try another lease.. */
1634 for (lp
= client
-> leases
; lp
-> next
; lp
= lp
-> next
)
1636 lp
-> next
= client
-> active
;
1638 lp
-> next
-> next
= (struct client_lease
*)0;
1640 client
-> active
= client
-> leases
;
1641 client
-> leases
= client
-> leases
-> next
;
1643 /* If we already tried this lease, we've exhausted the
1644 set of leases, so we might as well give up for
1646 if (client
-> active
== loop
)
1649 loop
= client
-> active
;
1652 /* No leases were available, or what was available didn't work, so
1653 tell the shell script that we failed to allocate an address,
1654 and try again later. */
1657 log_info ("Unable to obtain a lease on first try.%s",
1662 log_info ("No working leases in persistent database - sleeping.");
1663 #ifdef BUILTIN_IFCONFIG
1664 interface_fail (client
);
1666 script_init (client
, "FAIL", (struct string_list
*)0);
1667 if (client
-> alias
)
1668 script_write_params (client
, "alias_", client
-> alias
);
1671 client
-> state
= S_INIT
;
1672 add_timeout (cur_time
+
1673 ((client
-> config
-> retry_interval
+ 1) / 2 +
1674 (random () % client
-> config
-> retry_interval
)),
1675 state_init
, client
, 0, 0);
1679 void send_request (cpp
)
1682 struct client_state
*client
= cpp
;
1686 struct sockaddr_in destination
;
1687 struct in_addr from
;
1689 /* Figure out how long it's been since we started transmitting. */
1690 interval
= cur_time
- client
-> first_sending
;
1692 /* If we're in the INIT-REBOOT or REQUESTING state and we're
1693 past the reboot timeout, go to INIT and see if we can
1694 DISCOVER an address... */
1695 /* XXX In the INIT-REBOOT state, if we don't get an ACK, it
1696 means either that we're on a network with no DHCP server,
1697 or that our server is down. In the latter case, assuming
1698 that there is a backup DHCP server, DHCPDISCOVER will get
1699 us a new address, but we could also have successfully
1700 reused our old address. In the former case, we're hosed
1701 anyway. This is not a win-prone situation. */
1702 if ((client
-> state
== S_REBOOTING
||
1703 client
-> state
== S_REQUESTING
) &&
1704 interval
> client
-> config
-> reboot_timeout
) {
1706 client
-> state
= S_INIT
;
1707 cancel_timeout (send_request
, client
);
1708 state_init (client
);
1712 /* If we're in the reboot state, make sure the media is set up
1714 if (client
-> state
== S_REBOOTING
&&
1715 !client
-> medium
&&
1716 client
-> active
-> medium
) {
1717 #ifdef BUILTIN_IFCONFIG
1718 if (interface_medium (client
, client
-> active
-> medium
-> string
))
1720 script_init (client
, "MEDIUM", client
-> active
-> medium
);
1722 /* If the medium we chose won't fly, go to INIT state. */
1723 if (script_go (client
))
1727 /* Record the medium. */
1728 client
-> medium
= client
-> active
-> medium
;
1731 /* If the lease has expired, relinquish the address and go back
1732 to the INIT state. */
1733 if (client
-> state
!= S_REQUESTING
&&
1734 cur_time
> client
-> active
-> expiry
) {
1735 #ifdef BUILTIN_IFCONFIG
1736 interface_expire (client
);
1737 interface_preinit (client
);
1739 /* Run the client script with the new parameters. */
1740 script_init (client
, "EXPIRE", (struct string_list
*)0);
1741 script_write_params (client
, "old_", client
-> active
);
1742 if (client
-> alias
)
1743 script_write_params (client
, "alias_",
1747 /* Now do a preinit on the interface so that we can
1748 discover a new address. */
1749 script_init (client
, "PREINIT", (struct string_list
*)0);
1750 if (client
-> alias
)
1751 script_write_params (client
, "alias_",
1756 client
-> state
= S_INIT
;
1757 state_init (client
);
1761 /* Do the exponential backoff... */
1762 if (!client
-> interval
)
1763 client
-> interval
= client
-> config
-> initial_interval
;
1765 client
-> interval
+= ((random () >> 2) %
1766 (2 * client
-> interval
));
1769 /* Don't backoff past cutoff. */
1770 if (client
-> interval
>
1771 client
-> config
-> backoff_cutoff
)
1772 client
-> interval
=
1773 ((client
-> config
-> backoff_cutoff
/ 2)
1774 + ((random () >> 2) %
1775 client
-> config
-> backoff_cutoff
));
1777 /* If the backoff would take us to the expiry time, just set the
1778 timeout to the expiry time. */
1779 if (client
-> state
!= S_REQUESTING
&&
1780 cur_time
+ client
-> interval
> client
-> active
-> expiry
)
1781 client
-> interval
=
1782 client
-> active
-> expiry
- cur_time
+ 1;
1784 /* If the lease T2 time has elapsed, or if we're not yet bound,
1785 broadcast the DHCPREQUEST rather than unicasting. */
1786 if (client
-> state
== S_REQUESTING
||
1787 client
-> state
== S_REBOOTING
||
1788 cur_time
> client
-> active
-> rebind
)
1789 destination
.sin_addr
= sockaddr_broadcast
.sin_addr
;
1791 memcpy (&destination
.sin_addr
.s_addr
,
1792 client
-> destination
.iabuf
,
1793 sizeof destination
.sin_addr
.s_addr
);
1794 destination
.sin_port
= remote_port
;
1795 destination
.sin_family
= AF_INET
;
1797 destination
.sin_len
= sizeof destination
;
1800 if (client
-> state
== S_RENEWING
||
1801 client
-> state
== S_REBINDING
)
1802 memcpy (&from
, client
-> active
-> address
.iabuf
,
1805 from
.s_addr
= INADDR_ANY
;
1807 /* Record the number of seconds since we started sending. */
1808 if (client
-> state
== S_REQUESTING
)
1809 client
-> packet
.secs
= client
-> secs
;
1811 if (interval
< 65536)
1812 client
-> packet
.secs
= htons (interval
);
1814 client
-> packet
.secs
= htons (65535);
1817 log_info ("DHCPREQUEST on %s to %s port %d",
1818 client
-> name
? client
-> name
: client
-> interface
-> name
,
1819 inet_ntoa (destination
.sin_addr
),
1820 ntohs (destination
.sin_port
));
1822 if (destination
.sin_addr
.s_addr
!= INADDR_BROADCAST
&&
1824 result
= send_packet (fallback_interface
,
1827 client
-> packet_length
,
1829 (struct hardware
*)0);
1831 /* Send out a packet. */
1832 result
= send_packet (client
-> interface
, (struct packet
*)0,
1834 client
-> packet_length
,
1836 (struct hardware
*)0);
1839 /* FIXME: Shouldn't an error be logged here? */
1842 add_timeout (cur_time
+ client
-> interval
,
1843 send_request
, client
, 0, 0);
1846 void send_decline (cpp
)
1849 struct client_state
*client
= cpp
;
1853 log_info ("DHCPDECLINE on %s to %s port %d",
1854 client
-> name
? client
-> name
: client
-> interface
-> name
,
1855 inet_ntoa (sockaddr_broadcast
.sin_addr
),
1856 ntohs (sockaddr_broadcast
.sin_port
));
1858 /* Send out a packet. */
1859 result
= send_packet (client
-> interface
, (struct packet
*)0,
1861 client
-> packet_length
,
1862 inaddr_any
, &sockaddr_broadcast
,
1863 (struct hardware
*)0);
1866 /* FIXME: Shouldn't an error be logged here? */
1870 void send_release (cpp
)
1873 struct client_state
*client
= cpp
;
1876 struct sockaddr_in destination
;
1877 struct in_addr from
;
1879 memcpy (&from
, client
-> active
-> address
.iabuf
,
1881 memcpy (&destination
.sin_addr
.s_addr
,
1882 client
-> destination
.iabuf
,
1883 sizeof destination
.sin_addr
.s_addr
);
1884 destination
.sin_port
= remote_port
;
1885 destination
.sin_family
= AF_INET
;
1887 destination
.sin_len
= sizeof destination
;
1890 /* Set the lease to end now, so that we don't accidentally
1891 reuse it if we restart before the old expiry time. */
1892 client
-> active
-> expiry
=
1893 client
-> active
-> renewal
=
1894 client
-> active
-> rebind
= cur_time
;
1895 if (!write_client_lease (client
, client
-> active
, 1, 1)) {
1896 log_error ("Can't release lease: lease write failed.");
1900 log_info ("DHCPRELEASE on %s to %s port %d",
1901 client
-> name
? client
-> name
: client
-> interface
-> name
,
1902 inet_ntoa (destination
.sin_addr
),
1903 ntohs (destination
.sin_port
));
1905 if (fallback_interface
)
1906 result
= send_packet (fallback_interface
,
1909 client
-> packet_length
,
1911 (struct hardware
*)0);
1913 /* Send out a packet. */
1914 result
= send_packet (client
-> interface
, (struct packet
*)0,
1916 client
-> packet_length
,
1918 (struct hardware
*)0);
1921 /* FIXME: Shouldn't an error be logged here? */
1925 void make_client_options (client
, lease
, type
, sid
, rip
, prl
, op
)
1926 struct client_state
*client
;
1927 struct client_lease
*lease
;
1929 struct option_cache
*sid
;
1932 struct option_state
**op
;
1935 struct option_cache
*oc
;
1936 struct buffer
*bp
= (struct buffer
*)0;
1938 /* If there are any leftover options, get rid of them. */
1940 option_state_dereference (op
, MDL
);
1942 /* Allocate space for options. */
1943 option_state_allocate (op
, MDL
);
1945 /* Send the server identifier if provided. */
1947 save_option (&dhcp_universe
, *op
, sid
);
1949 oc
= (struct option_cache
*)0;
1951 /* Send the requested address if provided. */
1953 client
-> requested_address
= *rip
;
1954 if (!(make_const_option_cache
1955 (&oc
, (struct buffer
**)0, rip
-> iabuf
, rip
-> len
,
1956 &dhcp_options
[DHO_DHCP_REQUESTED_ADDRESS
], MDL
)))
1957 log_error ("can't make requested address cache.");
1959 save_option (&dhcp_universe
, *op
, oc
);
1960 option_cache_dereference (&oc
, MDL
);
1963 client
-> requested_address
.len
= 0;
1966 if (!(make_const_option_cache
1967 (&oc
, (struct buffer
**)0,
1968 type
, 1, &dhcp_options
[DHO_DHCP_MESSAGE_TYPE
], MDL
)))
1969 log_error ("can't make message type.");
1971 save_option (&dhcp_universe
, *op
, oc
);
1972 option_cache_dereference (&oc
, MDL
);
1976 /* Figure out how many parameters were requested. */
1977 for (i
= 0; prl
[i
]; i
++)
1979 if (!buffer_allocate (&bp
, i
, MDL
))
1980 log_error ("can't make parameter list buffer.");
1982 for (i
= 0; prl
[i
]; i
++)
1983 bp
-> data
[i
] = prl
[i
];
1984 if (!(make_const_option_cache
1985 (&oc
, &bp
, (u_int8_t
*)0, i
,
1986 &dhcp_options
[DHO_DHCP_PARAMETER_REQUEST_LIST
],
1988 log_error ("can't make option cache");
1990 save_option (&dhcp_universe
, *op
, oc
);
1991 option_cache_dereference (&oc
, MDL
);
1996 /* Run statements that need to be run on transmission. */
1997 if (client
-> config
-> on_transmission
)
1998 execute_statements_in_scope
1999 ((struct binding_value
**)0,
2000 (struct packet
*)0, (struct lease
*)0, client
,
2001 (lease
? lease
-> options
: (struct option_state
*)0),
2003 client
-> config
-> on_transmission
,
2007 void make_discover (client
, lease
)
2008 struct client_state
*client
;
2009 struct client_lease
*lease
;
2011 unsigned char discover
= DHCPDISCOVER
;
2012 struct option_state
*options
= (struct option_state
*)0;
2014 memset (&client
-> packet
, 0, sizeof (client
-> packet
));
2016 make_client_options (client
,
2017 lease
, &discover
, (struct option_cache
*)0,
2018 lease
? &lease
-> address
: (struct iaddr
*)0,
2019 client
-> config
-> requested_options
,
2022 /* Set up the option buffer... */
2023 client
-> packet_length
=
2024 cons_options ((struct packet
*)0, &client
-> packet
,
2025 (struct lease
*)0, client
,
2026 /* maximum packet size */1500,
2027 (struct option_state
*)0,
2029 /* scope */ &global_scope
,
2033 (struct data_string
*)0,
2034 client
-> config
-> vendor_space_name
);
2036 option_state_dereference (&options
, MDL
);
2037 if (client
-> packet_length
< BOOTP_MIN_LEN
)
2038 client
-> packet_length
= BOOTP_MIN_LEN
;
2040 client
-> packet
.op
= BOOTREQUEST
;
2041 client
-> packet
.htype
= client
-> interface
-> hw_address
.hbuf
[0];
2042 client
-> packet
.hlen
= client
-> interface
-> hw_address
.hlen
- 1;
2043 client
-> packet
.hops
= 0;
2044 client
-> packet
.xid
= random ();
2045 client
-> packet
.secs
= 0; /* filled in by send_discover. */
2047 if (can_receive_unicast_unconfigured (client
-> interface
))
2048 client
-> packet
.flags
= 0;
2050 client
-> packet
.flags
= htons (BOOTP_BROADCAST
);
2052 memset (&(client
-> packet
.ciaddr
),
2053 0, sizeof client
-> packet
.ciaddr
);
2054 memset (&(client
-> packet
.yiaddr
),
2055 0, sizeof client
-> packet
.yiaddr
);
2056 memset (&(client
-> packet
.siaddr
),
2057 0, sizeof client
-> packet
.siaddr
);
2058 client
-> packet
.giaddr
= giaddr
;
2059 if (client
-> interface
-> hw_address
.hlen
> 0)
2060 memcpy (client
-> packet
.chaddr
,
2061 &client
-> interface
-> hw_address
.hbuf
[1],
2062 (unsigned)(client
-> interface
-> hw_address
.hlen
- 1));
2065 dump_raw ((unsigned char *)&client
-> packet
, client
-> packet_length
);
2070 void make_request (client
, lease
)
2071 struct client_state
*client
;
2072 struct client_lease
*lease
;
2074 unsigned char request
= DHCPREQUEST
;
2075 struct option_cache
*oc
;
2077 memset (&client
-> packet
, 0, sizeof (client
-> packet
));
2079 if (client
-> state
== S_REQUESTING
)
2080 oc
= lookup_option (&dhcp_universe
, lease
-> options
,
2081 DHO_DHCP_SERVER_IDENTIFIER
);
2083 oc
= (struct option_cache
*)0;
2085 if (client
-> sent_options
)
2086 option_state_dereference (&client
-> sent_options
, MDL
);
2088 make_client_options (client
, lease
, &request
, oc
,
2089 ((client
-> state
== S_REQUESTING
||
2090 client
-> state
== S_REBOOTING
)
2092 : (struct iaddr
*)0),
2093 client
-> config
-> requested_options
,
2094 &client
-> sent_options
);
2096 /* Set up the option buffer... */
2097 client
-> packet_length
=
2098 cons_options ((struct packet
*)0, &client
-> packet
,
2099 (struct lease
*)0, client
,
2100 /* maximum packet size */1500,
2101 (struct option_state
*)0,
2102 client
-> sent_options
,
2103 /* scope */ &global_scope
,
2107 (struct data_string
*)0,
2108 client
-> config
-> vendor_space_name
);
2110 if (client
-> packet_length
< BOOTP_MIN_LEN
)
2111 client
-> packet_length
= BOOTP_MIN_LEN
;
2113 client
-> packet
.op
= BOOTREQUEST
;
2114 client
-> packet
.htype
= client
-> interface
-> hw_address
.hbuf
[0];
2115 client
-> packet
.hlen
= client
-> interface
-> hw_address
.hlen
- 1;
2116 client
-> packet
.hops
= 0;
2117 client
-> packet
.xid
= client
-> xid
;
2118 client
-> packet
.secs
= 0; /* Filled in by send_request. */
2120 /* If we own the address we're requesting, put it in ciaddr;
2121 otherwise set ciaddr to zero. */
2122 if (client
-> state
== S_BOUND
||
2123 client
-> state
== S_RENEWING
||
2124 client
-> state
== S_REBINDING
) {
2125 memcpy (&client
-> packet
.ciaddr
,
2126 lease
-> address
.iabuf
, lease
-> address
.len
);
2127 client
-> packet
.flags
= 0;
2129 memset (&client
-> packet
.ciaddr
, 0,
2130 sizeof client
-> packet
.ciaddr
);
2131 if (can_receive_unicast_unconfigured (client
-> interface
))
2132 client
-> packet
.flags
= 0;
2134 client
-> packet
.flags
= htons (BOOTP_BROADCAST
);
2137 memset (&client
-> packet
.yiaddr
, 0,
2138 sizeof client
-> packet
.yiaddr
);
2139 memset (&client
-> packet
.siaddr
, 0,
2140 sizeof client
-> packet
.siaddr
);
2141 if (client
-> state
!= S_BOUND
&&
2142 client
-> state
!= S_RENEWING
)
2143 client
-> packet
.giaddr
= giaddr
;
2145 memset (&client
-> packet
.giaddr
, 0,
2146 sizeof client
-> packet
.giaddr
);
2147 if (client
-> interface
-> hw_address
.hlen
> 0)
2148 memcpy (client
-> packet
.chaddr
,
2149 &client
-> interface
-> hw_address
.hbuf
[1],
2150 (unsigned)(client
-> interface
-> hw_address
.hlen
- 1));
2153 dump_raw ((unsigned char *)&client
-> packet
, client
-> packet_length
);
2157 void make_decline (client
, lease
)
2158 struct client_state
*client
;
2159 struct client_lease
*lease
;
2161 unsigned char decline
= DHCPDECLINE
;
2162 struct option_cache
*oc
;
2164 struct option_state
*options
= (struct option_state
*)0;
2166 oc
= lookup_option (&dhcp_universe
, lease
-> options
,
2167 DHO_DHCP_SERVER_IDENTIFIER
);
2168 make_client_options (client
, lease
, &decline
, oc
,
2169 &lease
-> address
, (u_int32_t
*)0, &options
);
2171 /* Set up the option buffer... */
2172 memset (&client
-> packet
, 0, sizeof (client
-> packet
));
2173 client
-> packet_length
=
2174 cons_options ((struct packet
*)0, &client
-> packet
,
2175 (struct lease
*)0, client
, 0,
2176 (struct option_state
*)0, options
,
2177 &global_scope
, 0, 0, 0, (struct data_string
*)0,
2178 client
-> config
-> vendor_space_name
);
2179 option_state_dereference (&options
, MDL
);
2180 if (client
-> packet_length
< BOOTP_MIN_LEN
)
2181 client
-> packet_length
= BOOTP_MIN_LEN
;
2182 option_state_dereference (&options
, MDL
);
2184 client
-> packet
.op
= BOOTREQUEST
;
2185 client
-> packet
.htype
= client
-> interface
-> hw_address
.hbuf
[0];
2186 client
-> packet
.hlen
= client
-> interface
-> hw_address
.hlen
- 1;
2187 client
-> packet
.hops
= 0;
2188 client
-> packet
.xid
= client
-> xid
;
2189 client
-> packet
.secs
= 0; /* Filled in by send_request. */
2190 if (can_receive_unicast_unconfigured (client
-> interface
))
2191 client
-> packet
.flags
= 0;
2193 client
-> packet
.flags
= htons (BOOTP_BROADCAST
);
2195 /* ciaddr must always be zero. */
2196 memset (&client
-> packet
.ciaddr
, 0,
2197 sizeof client
-> packet
.ciaddr
);
2198 memset (&client
-> packet
.yiaddr
, 0,
2199 sizeof client
-> packet
.yiaddr
);
2200 memset (&client
-> packet
.siaddr
, 0,
2201 sizeof client
-> packet
.siaddr
);
2202 client
-> packet
.giaddr
= giaddr
;
2203 memcpy (client
-> packet
.chaddr
,
2204 &client
-> interface
-> hw_address
.hbuf
[1],
2205 client
-> interface
-> hw_address
.hlen
);
2208 dump_raw ((unsigned char *)&client
-> packet
, client
-> packet_length
);
2212 void make_release (client
, lease
)
2213 struct client_state
*client
;
2214 struct client_lease
*lease
;
2216 unsigned char request
= DHCPRELEASE
;
2217 struct option_cache
*oc
;
2219 struct option_state
*options
= (struct option_state
*)0;
2221 memset (&client
-> packet
, 0, sizeof (client
-> packet
));
2223 oc
= lookup_option (&dhcp_universe
, lease
-> options
,
2224 DHO_DHCP_SERVER_IDENTIFIER
);
2225 make_client_options (client
, lease
, &request
, oc
,
2226 (struct iaddr
*)0, (u_int32_t
*)0,
2229 /* Set up the option buffer... */
2230 client
-> packet_length
=
2231 cons_options ((struct packet
*)0, &client
-> packet
,
2232 (struct lease
*)0, client
,
2233 /* maximum packet size */1500,
2234 (struct option_state
*)0,
2236 /* scope */ &global_scope
,
2240 (struct data_string
*)0,
2241 client
-> config
-> vendor_space_name
);
2243 if (client
-> packet_length
< BOOTP_MIN_LEN
)
2244 client
-> packet_length
= BOOTP_MIN_LEN
;
2245 option_state_dereference (&options
, MDL
);
2247 client
-> packet
.op
= BOOTREQUEST
;
2248 client
-> packet
.htype
= client
-> interface
-> hw_address
.hbuf
[0];
2249 client
-> packet
.hlen
= client
-> interface
-> hw_address
.hlen
- 1;
2250 client
-> packet
.hops
= 0;
2251 client
-> packet
.xid
= random ();
2252 client
-> packet
.secs
= 0;
2253 client
-> packet
.flags
= 0;
2254 memcpy (&client
-> packet
.ciaddr
,
2255 lease
-> address
.iabuf
, lease
-> address
.len
);
2256 memset (&client
-> packet
.yiaddr
, 0,
2257 sizeof client
-> packet
.yiaddr
);
2258 memset (&client
-> packet
.siaddr
, 0,
2259 sizeof client
-> packet
.siaddr
);
2260 client
-> packet
.giaddr
= giaddr
;
2261 memcpy (client
-> packet
.chaddr
,
2262 &client
-> interface
-> hw_address
.hbuf
[1],
2263 client
-> interface
-> hw_address
.hlen
);
2266 dump_raw ((unsigned char *)&client
-> packet
, client
-> packet_length
);
2270 void destroy_client_lease (lease
)
2271 struct client_lease
*lease
;
2273 if (lease
-> server_name
)
2274 dfree (lease
-> server_name
, MDL
);
2275 if (lease
-> filename
)
2276 dfree (lease
-> filename
, MDL
);
2277 option_state_dereference (&lease
-> options
, MDL
);
2278 free_client_lease (lease
, MDL
);
2283 void rewrite_client_leases ()
2285 struct interface_info
*ip
;
2286 struct client_state
*client
;
2287 struct client_lease
*lp
;
2291 leaseFile
= fopen (path_dhclient_db
, "w");
2293 log_error ("can't create %s: %m", path_dhclient_db
);
2297 /* Write out all the leases attached to configured interfaces that
2299 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
2300 for (client
= ip
-> client
; client
; client
= client
-> next
) {
2301 for (lp
= client
-> leases
; lp
; lp
= lp
-> next
) {
2302 write_client_lease (client
, lp
, 1, 0);
2304 if (client
-> active
)
2305 write_client_lease (client
,
2306 client
-> active
, 1, 0);
2310 /* Write out any leases that are attached to interfaces that aren't
2311 currently configured. */
2312 for (ip
= dummy_interfaces
; ip
; ip
= ip
-> next
) {
2313 for (client
= ip
-> client
; client
; client
= client
-> next
) {
2314 for (lp
= client
-> leases
; lp
; lp
= lp
-> next
) {
2315 write_client_lease (client
, lp
, 1, 0);
2317 if (client
-> active
)
2318 write_client_lease (client
,
2319 client
-> active
, 1, 0);
2325 void write_lease_option (struct option_cache
*oc
,
2326 struct packet
*packet
, struct lease
*lease
,
2327 struct client_state
*client_state
,
2328 struct option_state
*in_options
,
2329 struct option_state
*cfg_options
,
2330 struct binding_scope
**scope
,
2331 struct universe
*u
, void *stuff
)
2333 const char *name
, *dot
;
2334 struct data_string ds
;
2336 memset (&ds
, 0, sizeof ds
);
2338 if (u
!= &dhcp_universe
) {
2345 if (evaluate_option_cache (&ds
, packet
, lease
, client_state
,
2346 in_options
, cfg_options
, scope
, oc
, MDL
)) {
2348 " option %s%s%s %s;\n",
2349 name
, dot
, oc
-> option
-> name
,
2350 pretty_print_option (oc
-> option
,
2351 ds
.data
, ds
.len
, 1, 1));
2352 data_string_forget (&ds
, MDL
);
2356 int write_client_lease (client
, lease
, rewrite
, makesure
)
2357 struct client_state
*client
;
2358 struct client_lease
*lease
;
2364 static int leases_written
;
2365 struct data_string ds
;
2370 if (leases_written
++ > 20) {
2371 rewrite_client_leases ();
2376 /* If the lease came from the config file, we don't need to stash
2377 a copy in the lease database. */
2378 if (lease
-> is_static
)
2381 if (!leaseFile
) { /* XXX */
2382 leaseFile
= fopen (path_dhclient_db
, "w");
2384 log_error ("can't create %s: %m", path_dhclient_db
);
2390 fprintf (leaseFile
, "lease {\n");
2391 if (lease
-> is_bootp
) {
2392 fprintf (leaseFile
, " bootp;\n");
2398 fprintf (leaseFile
, " interface \"%s\";\n",
2399 client
-> interface
-> name
);
2404 if (client
-> name
) {
2405 fprintf (leaseFile
, " name \"%s\";\n", client
-> name
);
2411 fprintf (leaseFile
, " fixed-address %s;\n",
2412 piaddr (lease
-> address
));
2417 if (lease
-> filename
) {
2418 s
= quotify_string (lease
-> filename
, MDL
);
2420 fprintf (leaseFile
, " filename \"%s\";\n", s
);
2430 if (lease
-> server_name
) {
2431 s
= quotify_string (lease
-> filename
, MDL
);
2433 fprintf (leaseFile
, " server-name \"%s\";\n", s
);
2442 if (lease
-> medium
) {
2443 s
= quotify_string (lease
-> medium
-> string
, MDL
);
2445 fprintf (leaseFile
, " medium \"%s\";\n", s
);
2459 memset (&ds
, 0, sizeof ds
);
2461 for (i
= 0; i
< lease
-> options
-> universe_count
; i
++) {
2462 option_space_foreach ((struct packet
*)0, (struct lease
*)0,
2463 client
, (struct option_state
*)0,
2464 lease
-> options
, &global_scope
,
2466 client
, write_lease_option
);
2469 /* Note: the following is not a Y2K bug - it's a Y1.9K bug. Until
2470 somebody invents a time machine, I think we can safely disregard
2472 t
= gmtime (&lease
-> renewal
);
2474 " renew %d %d/%d/%d %02d:%02d:%02d;\n",
2475 t
-> tm_wday
, t
-> tm_year
+ 1900,
2476 t
-> tm_mon
+ 1, t
-> tm_mday
,
2477 t
-> tm_hour
, t
-> tm_min
, t
-> tm_sec
);
2482 t
= gmtime (&lease
-> rebind
);
2484 " rebind %d %d/%d/%d %02d:%02d:%02d;\n",
2485 t
-> tm_wday
, t
-> tm_year
+ 1900,
2486 t
-> tm_mon
+ 1, t
-> tm_mday
,
2487 t
-> tm_hour
, t
-> tm_min
, t
-> tm_sec
);
2492 t
= gmtime (&lease
-> expiry
);
2494 " expire %d %d/%d/%d %02d:%02d:%02d;\n",
2495 t
-> tm_wday
, t
-> tm_year
+ 1900,
2496 t
-> tm_mon
+ 1, t
-> tm_mday
,
2497 t
-> tm_hour
, t
-> tm_min
, t
-> tm_sec
);
2502 fprintf (leaseFile
, "}\n");
2512 #ifndef FSYNC_MISSING
2513 if (!errors
&& makesure
) {
2514 if (fsync (fileno (leaseFile
)) < 0) {
2515 log_info ("write_client_lease: %m");
2520 return errors
? 0 : 1;
2523 #ifdef BUILTIN_IFCONFIG
2524 #ifndef SOCKET_IS_NOT_A_FILE
2525 #define IoctlSocket ioctl
2526 #define CloseSocket close
2529 static inline void setaddr (struct sockaddr_in
*sa
, u_long addr
, u_short af
)
2531 sa
->sin_len
= sizeof (struct sockaddr_in
);
2532 sa
->sin_family
= af
;
2533 sa
->sin_addr
.s_addr
= addr
;
2536 void ifconfig (char *name
, u_long addr
, u_long mask
, u_long bcast
)
2539 struct ifaliasreq req
;
2541 s
= socket (AF_INET
, SOCK_DGRAM
, 0);
2543 log_error ("Can't create configuration socket: %m");
2546 memset (&req
, 0, sizeof (req
));
2547 strncpy (req
.ifra_name
, name
, sizeof (req
.ifra_name
) - 1);
2548 IoctlSocket (s
, SIOCDIFADDR
, (char *)&req
);
2549 setaddr ((struct sockaddr_in
*)&req
.ifra_addr
, addr
, AF_INET
);
2550 setaddr ((struct sockaddr_in
*)&req
.ifra_mask
, mask
, AF_UNSPEC
);
2552 setaddr ((struct sockaddr_in
*)&req
.ifra_broadaddr
, bcast
, AF_INET
);
2553 if (IoctlSocket (s
, SIOCAIFADDR
, (char *)&req
) < 0)
2554 log_error ("Can't set interface configuration: %m");
2558 void ifdeconfig (char *name
)
2561 struct ifaliasreq req
;
2563 s
= socket (AF_INET
, SOCK_DGRAM
, 0);
2565 log_error ("Can't create configuration socket: %m");
2568 memset (&req
, 0, sizeof (req
));
2569 strncpy (req
.ifra_name
, name
, sizeof (req
.ifra_name
) - 1);
2570 IoctlSocket (s
, SIOCDIFADDR
, (char *)&req
);
2574 void addroute (u_long dest
, u_long gate
, short flags
)
2577 struct ortentry route
;
2579 s
= socket (AF_INET
, SOCK_RAW
, 0);
2581 log_error ("Can't create route socket: %m");
2584 memset (&route
, 0, sizeof (route
));
2585 setaddr ((struct sockaddr_in
*)&route
.rt_dst
, dest
, AF_INET
);
2586 setaddr ((struct sockaddr_in
*)&route
.rt_gateway
, gate
, AF_INET
);
2587 route
.rt_flags
= flags
;
2588 IoctlSocket (s
, SIOCADDRT
, (char *)&route
);
2592 void delroute (u_long dest
)
2595 struct ortentry route
;
2597 s
= socket (AF_INET
, SOCK_RAW
, 0);
2599 log_error ("Can't create route socket: %m");
2602 memset (&route
, 0, sizeof (route
));
2603 setaddr ((struct sockaddr_in
*)&route
.rt_dst
, dest
, AF_INET
);
2604 IoctlSocket (s
, SIOCDELRT
, (char *)&route
);
2608 void interface_preinit (struct client_state
*client
)
2610 log_debug ("PREINIT %s", client
->interface
->name
);
2611 if (client
-> alias
) {
2612 log_debug ("Alias IP: %s", piaddr (client
->alias
->address
));
2613 /* TODO: remove alias and its routes */
2615 /* TODO: clear ARP cache and remove old interface's routes (ifdown ???) */
2616 ifconfig (client
->interface
->name
, INADDR_ANY
, INADDR_ANY
, INADDR_BROADCAST
);
2617 addroute (INADDR_BROADCAST
, INADDR_ANY
, RTF_UP
|RTF_HOST
);
2620 int interface_medium (struct client_state
*client
, char *medium
)
2622 log_debug ("MEDIUM %s %s", client
->interface
->name
, medium
);
2627 void client_option_dump (struct option_cache
*oc
,
2628 struct packet
*packet
, struct lease
*lease
,
2629 struct client_state
*client_state
,
2630 struct option_state
*in_options
,
2631 struct option_state
*cfg_options
,
2632 struct binding_scope
**scope
,
2633 struct universe
*u
, void *stuff
)
2635 struct data_string data
;
2636 memset (&data
, 0, sizeof data
);
2638 if (evaluate_option_cache (&data
, packet
, lease
, client_state
,
2639 in_options
, cfg_options
, scope
, oc
, MDL
)) {
2642 if (dhcp_option_ev_name (name
, sizeof name
,
2644 log_debug ("%s: %s", name
,
2645 (pretty_print_option
2647 data
.data
, data
.len
,
2649 data_string_forget (&data
, MDL
);
2655 void dump_params (struct client_state
*client
, struct client_lease
*lease
)
2659 log_debug ("ip_address: %s", piaddr (lease
-> address
));
2661 if (lease
-> filename
)
2662 log_debug ("filename: %s", lease
-> filename
);
2664 if (lease
-> server_name
)
2665 log_debug ("server_name: %s", lease
-> server_name
);
2667 for (i
= 0; i
< lease
-> options
-> universe_count
; i
++) {
2668 option_space_foreach ((struct packet
*)0, (struct lease
*)0,
2669 client
, (struct option_state
*)0,
2670 lease
-> options
, &global_scope
,
2672 0, client_option_dump
);
2674 log_debug ("expiry: %d", (int)(lease
-> expiry
));
2677 int data_cmp (struct data_string
*d1
, struct data_string
*d2
)
2679 if (d1
->len
!= d2
->len
)
2683 return memcmp (d1
->data
, d2
->data
, d1
->len
);
2689 int interface_bind (struct client_state
*client
)
2691 struct data_string data
= {0};
2692 struct option_cache
*oc
;
2694 u_long old_netmask
= INADDR_ANY
;
2695 u_long old_broadcast
= INADDR_ANY
;
2696 struct data_string old_gateways_data
= {0};
2697 struct data_string old_hostname_data
= {0};
2698 struct data_string old_dns_data
= {0};
2699 struct data_string old_domain_data
= {0};
2700 u_long new_netmask
= INADDR_ANY
;
2701 u_long new_broadcast
= INADDR_ANY
;
2702 struct data_string new_gateways_data
= {0};
2703 struct data_string new_hostname_data
= {0};
2704 struct data_string new_dns_data
= {0};
2705 struct data_string new_domain_data
= {0};
2706 short new_ifconfig
= 1;
2707 short new_gateways
= 1;
2708 short new_hostname
= 1;
2709 short new_routes
= 1;
2711 short new_domain
= 1;
2713 log_debug ("%s %s", (client
-> state
== S_REQUESTING
2715 : (client
-> state
== S_RENEWING
2717 : (client
-> state
== S_REBOOTING
2719 : (client
-> state
== S_REBINDING
2720 ? "REBIND" : "BAD STATE")))), client
->interface
->name
);
2721 if (client
-> alias
) {
2722 log_debug ("Alias parameters:");
2723 dump_params (client
, client
-> alias
);
2724 /* TODO: process alias */
2727 /* Parse new options */
2728 oc
= lookup_option (&dhcp_universe
, client
-> new -> options
, DHO_SUBNET_MASK
);
2729 if (oc
&& evaluate_option_cache (&data
, (struct packet
*)0,
2730 (struct lease
*)0, client
,
2731 (struct option_state
*)0,
2732 client
-> new -> options
,
2733 &global_scope
, oc
, MDL
)) {
2734 memcpy (&new_netmask
, data
.data
, 4);
2735 data_string_forget (&data
, MDL
);
2737 oc
= lookup_option (&dhcp_universe
, client
-> new -> options
, DHO_BROADCAST_ADDRESS
);
2738 if (oc
&& evaluate_option_cache (&data
, (struct packet
*)0,
2739 (struct lease
*)0, client
,
2740 (struct option_state
*)0,
2741 client
-> new -> options
,
2742 &global_scope
, oc
, MDL
)) {
2743 memcpy (&new_broadcast
, data
.data
, 4);
2744 data_string_forget (&data
, MDL
);
2746 oc
= lookup_option (&dhcp_universe
, client
-> new -> options
, DHO_ROUTERS
);
2748 evaluate_option_cache (&new_gateways_data
, (struct packet
*)0,
2749 (struct lease
*)0, client
,
2750 (struct option_state
*)0,
2751 client
-> new -> options
,
2752 &global_scope
, oc
, MDL
);
2753 oc
= lookup_option (&dhcp_universe
, client
-> new -> options
, DHO_HOST_NAME
);
2755 evaluate_option_cache (&new_hostname_data
, (struct packet
*)0,
2756 (struct lease
*)0, client
,
2757 (struct option_state
*)0,
2758 client
-> new -> options
,
2759 &global_scope
, oc
, MDL
);
2760 oc
= lookup_option (&dhcp_universe
, client
-> new -> options
, DHO_DOMAIN_NAME_SERVERS
);
2762 evaluate_option_cache (&new_dns_data
, (struct packet
*)0,
2763 (struct lease
*)0, client
,
2764 (struct option_state
*)0,
2765 client
-> new -> options
,
2766 &global_scope
, oc
, MDL
);
2767 oc
= lookup_option (&dhcp_universe
, client
-> new -> options
, DHO_DOMAIN_NAME
);
2769 evaluate_option_cache (&new_domain_data
, (struct packet
*)0,
2770 (struct lease
*)0, client
,
2771 (struct option_state
*)0,
2772 client
-> new -> options
,
2773 &global_scope
, oc
, MDL
);
2774 /* Perform actions depending on our state */
2775 switch (client
->state
) {
2779 if (client
-> active
) {
2780 log_debug ("Old parameters:");
2781 dump_params (client
, client
-> active
);
2783 log_fatal ("Inconsistent state: old parameters not specified");
2785 oc
= lookup_option (&dhcp_universe
, client
-> active
-> options
, DHO_SUBNET_MASK
);
2786 if (oc
&& evaluate_option_cache (&data
, (struct packet
*)0,
2787 (struct lease
*)0, client
,
2788 (struct option_state
*)0,
2789 client
-> active
-> options
,
2790 &global_scope
, oc
, MDL
)) {
2791 memcpy (&old_netmask
, data
.data
, 4);
2792 data_string_forget (&data
, MDL
);
2794 oc
= lookup_option (&dhcp_universe
, client
-> active
-> options
, DHO_BROADCAST_ADDRESS
);
2795 if (oc
&& evaluate_option_cache (&data
, (struct packet
*)0,
2796 (struct lease
*)0, client
,
2797 (struct option_state
*)0,
2798 client
-> active
-> options
,
2799 &global_scope
, oc
, MDL
)) {
2800 memcpy (&old_broadcast
, data
.data
, 4);
2801 data_string_forget (&data
, MDL
);
2803 if ((addr_eq(client
->active
->address
, client
->new->address
)) &&
2804 (old_netmask
== new_netmask
) && (old_broadcast
== new_broadcast
))
2807 oc
= lookup_option (&dhcp_universe
, client
-> active
-> options
, DHO_ROUTERS
);
2808 if (oc
&& evaluate_option_cache (&old_gateways_data
, (struct packet
*)0,
2809 (struct lease
*)0, client
,
2810 (struct option_state
*)0,
2811 client
-> active
-> options
,
2812 &global_scope
, oc
, MDL
)) {
2813 if (!(data_cmp (&new_gateways_data
, &old_gateways_data
)))
2815 data_string_forget (&old_gateways_data
, MDL
);
2817 oc
= lookup_option (&dhcp_universe
, client
-> active
-> options
, DHO_HOST_NAME
);
2818 if (oc
&& evaluate_option_cache (&old_hostname_data
, (struct packet
*)0,
2819 (struct lease
*)0, client
,
2820 (struct option_state
*)0,
2821 client
-> active
-> options
,
2822 &global_scope
, oc
, MDL
)) {
2823 if (!(data_cmp (&new_hostname_data
, &old_hostname_data
)))
2825 data_string_forget (&old_hostname_data
, MDL
);
2827 oc
= lookup_option (&dhcp_universe
, client
-> active
-> options
, DHO_DOMAIN_NAME_SERVERS
);
2828 if (oc
&& evaluate_option_cache (&old_dns_data
, (struct packet
*)0,
2829 (struct lease
*)0, client
,
2830 (struct option_state
*)0,
2831 client
-> active
-> options
,
2832 &global_scope
, oc
, MDL
)) {
2833 if (!(data_cmp (&new_dns_data
, &old_dns_data
)))
2835 data_string_forget (&old_dns_data
, MDL
);
2837 oc
= lookup_option (&dhcp_universe
, client
-> active
-> options
, DHO_DOMAIN_NAME
);
2838 if (oc
&& evaluate_option_cache (&old_domain_data
, (struct packet
*)0,
2839 (struct lease
*)0, client
,
2840 (struct option_state
*)0,
2841 client
-> active
-> options
,
2842 &global_scope
, oc
, MDL
)) {
2843 if (!(data_cmp (&new_domain_data
, &old_domain_data
)))
2845 data_string_forget (&old_domain_data
, MDL
);
2849 log_debug ("New parameters:");
2850 dump_params (client
, client
-> new);
2852 delroute (INADDR_BROADCAST
);
2853 ifconfig (client
->interface
->name
, ia2ulong(&client
->new->address
), new_netmask
, new_broadcast
);
2856 delroute (INADDR_ANY
);
2857 if (new_gateways_data
.data
)
2858 addroute (INADDR_ANY
, htonl(getULong(new_gateways_data
.data
)), RTF_UP
| RTF_GATEWAY
);
2859 /* TODO: process all gateways not only first one */
2861 if (new_hostname
&& new_hostname_data
.data
) {
2862 log_debug ("New hostname: %s", new_hostname_data
.data
);
2863 sethostname (new_hostname_data
.data
, new_hostname_data
.len
);
2866 /* TODO: add new static routes */
2870 if (new_dns_data
.data
) {
2871 struct sockaddr_in ns_addr
;
2872 u_long
*addrs
= (u_long
*)new_dns_data
.data
;
2873 int len
= new_dns_data
.len
/4;
2874 ns_addr
.sin_len
= sizeof(ns_addr
);
2875 ns_addr
.sin_family
= AF_INET
;
2876 for (i
=0; i
<len
; i
++) {
2877 log_debug ("New DNS server: %s", Inet_NtoA(addrs
[i
]));
2878 ns_addr
.sin_addr
.s_addr
= addrs
[i
];
2879 AddDynNameServ((struct sockaddr
*)&ns_addr
);
2886 if (new_domain_data
.data
) {
2887 log_debug ("New domain name: %s", new_domain_data
.data
);
2888 AddDynDomain((unsigned char *)new_domain_data
.data
);
2892 /* TODO: do something with other options (place to some file ?) */
2893 data_string_forget (&new_gateways_data
, MDL
);
2894 data_string_forget (&new_hostname_data
, MDL
);
2895 data_string_forget (&new_dns_data
, MDL
);
2896 data_string_forget (&new_domain_data
, MDL
);
2899 log_debug ("Inconsistent state: %d", client
->state
);
2904 void interface_expire (struct client_state *client)
2906 log_debug ("EXPIRE %s", client->interface->name);
2910 void interface_fail (struct client_state *client)
2912 log_debug ("FAIL %s", client->interface->name);
2916 void interface_release (struct client_state *client)
2918 log_debug ("RELEASE %s", client->interface->name);
2922 void interface_stop (struct client_state
*client
)
2924 log_debug ("STOP %s", client
->interface
->name
);
2925 ifdeconfig (client
->interface
->name
);
2926 delroute (INADDR_ANY
);
2933 int interface_timeout (struct client_state
*client
)
2935 log_debug ("TIMEOUT %s", client
->interface
->name
);
2942 /* Variables holding name of script and file pointer for writing to
2943 script. Needless to say, this is not reentrant - only one script
2944 can be invoked at a time. */
2945 char scriptName
[256];
2948 void script_init (client
, reason
, medium
)
2949 struct client_state
*client
;
2951 struct string_list
*medium
;
2953 struct string_list
*sl
, *next
;
2956 for (sl
= client
-> env
; sl
; sl
= next
) {
2960 client
-> env
= (struct string_list
*)0;
2963 if (client
-> interface
) {
2964 client_envadd (client
, "", "interface", "%s",
2965 client
-> interface
-> name
);
2968 client_envadd (client
,
2969 "", "client", "%s", client
-> name
);
2971 client_envadd (client
,
2972 "", "medium", "%s", medium
-> string
);
2974 client_envadd (client
, "", "reason", "%s", reason
);
2975 client_envadd (client
, "", "pid", "%ld", (long int)getpid ());
2979 struct envadd_state
{
2980 struct client_state
*client
;
2984 void client_option_envadd (struct option_cache
*oc
,
2985 struct packet
*packet
, struct lease
*lease
,
2986 struct client_state
*client_state
,
2987 struct option_state
*in_options
,
2988 struct option_state
*cfg_options
,
2989 struct binding_scope
**scope
,
2990 struct universe
*u
, void *stuff
)
2992 struct envadd_state
*es
= stuff
;
2993 struct data_string data
;
2994 memset (&data
, 0, sizeof data
);
2996 if (evaluate_option_cache (&data
, packet
, lease
, client_state
,
2997 in_options
, cfg_options
, scope
, oc
, MDL
)) {
3000 if (dhcp_option_ev_name (name
, sizeof name
,
3002 client_envadd (es
-> client
, es
-> prefix
,
3004 (pretty_print_option
3006 data
.data
, data
.len
,
3008 data_string_forget (&data
, MDL
);
3014 void script_write_params (client
, prefix
, lease
)
3015 struct client_state
*client
;
3017 struct client_lease
*lease
;
3020 struct data_string data
;
3021 struct option_cache
*oc
;
3024 struct envadd_state es
;
3029 client_envadd (client
,
3030 prefix
, "ip_address", "%s", piaddr (lease
-> address
));
3032 /* For the benefit of Linux (and operating systems which may
3033 have similar needs), compute the network address based on
3034 the supplied ip address and netmask, if provided. Also
3035 compute the broadcast address (the host address all ones
3036 broadcast address, not the host address all zeroes
3037 broadcast address). */
3039 memset (&data
, 0, sizeof data
);
3040 oc
= lookup_option (&dhcp_universe
, lease
-> options
, DHO_SUBNET_MASK
);
3041 if (oc
&& evaluate_option_cache (&data
, (struct packet
*)0,
3042 (struct lease
*)0, client
,
3043 (struct option_state
*)0,
3045 &global_scope
, oc
, MDL
)) {
3047 struct iaddr netmask
, subnet
, broadcast
;
3049 memcpy (netmask
.iabuf
, data
.data
, data
.len
);
3050 netmask
.len
= data
.len
;
3051 data_string_forget (&data
, MDL
);
3053 subnet
= subnet_number (lease
-> address
, netmask
);
3055 client_envadd (client
, prefix
, "network_number",
3056 "%s", piaddr (subnet
));
3058 oc
= lookup_option (&dhcp_universe
,
3060 DHO_BROADCAST_ADDRESS
);
3062 !(evaluate_option_cache
3063 (&data
, (struct packet
*)0,
3064 (struct lease
*)0, client
,
3065 (struct option_state
*)0,
3067 &global_scope
, oc
, MDL
))) {
3068 broadcast
= broadcast_addr (subnet
, netmask
);
3069 if (broadcast
.len
) {
3070 client_envadd (client
,
3071 prefix
, "broadcast_address",
3072 "%s", piaddr (broadcast
));
3077 data_string_forget (&data
, MDL
);
3080 if (lease
-> filename
)
3081 client_envadd (client
,
3082 prefix
, "filename", "%s", lease
-> filename
);
3083 if (lease
-> server_name
)
3084 client_envadd (client
, prefix
, "server_name",
3085 "%s", lease
-> server_name
);
3087 for (i
= 0; i
< lease
-> options
-> universe_count
; i
++) {
3088 option_space_foreach ((struct packet
*)0, (struct lease
*)0,
3089 client
, (struct option_state
*)0,
3090 lease
-> options
, &global_scope
,
3092 &es
, client_option_envadd
);
3094 client_envadd (client
, prefix
, "expiry", "%d", (int)(lease
-> expiry
));
3097 int script_go (client
)
3098 struct client_state
*client
;
3105 char reason
[] = "REASON=NBI";
3106 static char client_path
[] = CLIENT_PATH
;
3108 struct string_list
*sp
, *next
;
3109 int pid
, wpid
, wstatus
;
3112 scriptName
= client
-> config
-> script_name
;
3114 scriptName
= top_level_config
.script_name
;
3116 envp
= dmalloc (((client
? client
-> envc
: 2) +
3117 client_env_count
+ 2) * sizeof (char *), MDL
);
3119 log_error ("No memory for client script environment.");
3123 /* Copy out the environment specified on the command line,
3125 for (sp
= client_env
; sp
; sp
= sp
-> next
) {
3126 envp
[i
++] = sp
-> string
;
3128 /* Copy out the environment specified by dhclient. */
3130 for (sp
= client
-> env
; sp
; sp
= sp
-> next
) {
3131 envp
[i
++] = sp
-> string
;
3134 envp
[i
++] = reason
;
3137 envp
[i
++] = client_path
;
3138 envp
[i
] = (char *)0;
3140 argv
[0] = scriptName
;
3141 argv
[1] = (char *)0;
3145 log_error ("fork: %m");
3149 wpid
= wait (&wstatus
);
3150 } while (wpid
!= pid
&& wpid
> 0);
3152 log_error ("wait: %m");
3156 execve (scriptName
, argv
, envp
);
3157 log_error ("execve (%s, ...): %m", scriptName
);
3162 for (sp
= client
-> env
; sp
; sp
= next
) {
3166 client
-> env
= (struct string_list
*)0;
3170 GET_TIME (&cur_time
);
3171 return (WIFEXITED (wstatus
) ?
3172 WEXITSTATUS (wstatus
) : -WTERMSIG (wstatus
));
3175 void client_envadd (struct client_state
*client
,
3176 const char *prefix
, const char *name
, const char *fmt
, ...)
3181 struct string_list
*val
;
3184 va_start (list
, fmt
);
3185 len
= vsnprintf (spbuf
, sizeof spbuf
, fmt
, list
);
3188 val
= dmalloc (strlen (prefix
) + strlen (name
) + 1 /* = */ +
3189 len
+ sizeof *val
, MDL
);
3197 if (len
>= sizeof spbuf
) {
3198 va_start (list
, fmt
);
3199 vsnprintf (s
, len
+ 1, fmt
, list
);
3203 val
-> next
= client
-> env
;
3204 client
-> env
= val
;
3209 int dhcp_option_ev_name (buf
, buflen
, option
)
3212 struct option
*option
;
3218 if (option
-> universe
!= &dhcp_universe
) {
3219 s
= option
-> universe
-> name
;
3228 if (j
+ 1 == buflen
)
3238 if (j
+ 1 == buflen
)
3251 #ifndef FORK_MISSING
3252 static int state
= 0;
3256 /* Don't become a daemon if the user requested otherwise. */
3258 write_client_pid_file ();
3262 /* Only do it once. */
3267 /* Stop logging to stderr... */
3270 /* Become a daemon... */
3271 if ((pid
= fork ()) < 0)
3272 log_fatal ("Can't fork daemon: %m");
3275 /* Become session leader and get pid... */
3278 /* Close standard I/O descriptors. */
3283 /* Reopen them on /dev/null. */
3284 i
= open ("/dev/null", O_RDWR
);
3286 i
= open ("/dev/null", O_RDWR
);
3288 i
= open ("/dev/null", O_RDWR
);
3289 log_perror
= 0; /* No sense logging to /dev/null. */
3293 write_client_pid_file ();
3296 void write_client_pid_file ()
3301 pfdesc
= open (path_dhclient_pid
, O_CREAT
| O_TRUNC
| O_WRONLY
, 0644);
3304 log_error ("Can't create %s: %m", path_dhclient_pid
);
3308 pf
= fdopen (pfdesc
, "w");
3310 log_error ("Can't fdopen %s: %m", path_dhclient_pid
);
3312 fprintf (pf
, "%ld\n", (long)getpid ());
3317 void client_location_changed ()
3319 struct interface_info
*ip
;
3320 struct client_state
*client
;
3322 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
3323 for (client
= ip
-> client
; client
; client
= client
-> next
) {
3324 switch (client
-> state
) {
3326 cancel_timeout (send_discover
, client
);
3330 cancel_timeout (state_bound
, client
);
3336 cancel_timeout (send_request
, client
);
3344 client
-> state
= S_INIT
;
3345 state_reboot (client
);
3350 void do_release(client
)
3351 struct client_state
*client
;
3353 struct data_string ds
;
3354 struct option_cache
*oc
;
3356 /* Pick a random xid. */
3357 client
-> xid
= random ();
3359 /* is there even a lease to release? */
3360 if (client
-> active
) {
3361 /* Make a DHCPRELEASE packet, and set appropriate per-interface
3363 make_release (client
, client
-> active
);
3365 memset (&ds
, 0, sizeof ds
);
3366 oc
= lookup_option (&dhcp_universe
,
3367 client
-> active
-> options
,
3368 DHO_DHCP_SERVER_IDENTIFIER
);
3370 evaluate_option_cache (&ds
, (struct packet
*)0,
3371 (struct lease
*)0, client
,
3372 (struct option_state
*)0,
3373 client
-> active
-> options
,
3374 &global_scope
, oc
, MDL
)) {
3376 memcpy (client
-> destination
.iabuf
,
3378 client
-> destination
.len
= 4;
3380 client
-> destination
= iaddr_broadcast
;
3382 data_string_forget (&ds
, MDL
);
3384 client
-> destination
= iaddr_broadcast
;
3385 client
-> first_sending
= cur_time
;
3386 client
-> interval
= client
-> config
-> initial_interval
;
3388 /* Zap the medium list... */
3389 client
-> medium
= (struct string_list
*)0;
3391 /* Send out the first and only DHCPRELEASE packet. */
3392 send_release (client
);
3394 #ifdef BUILTIN_IFCONFIG
3395 interface_release (client
);
3397 /* Do the client script RELEASE operation. */
3398 script_init (client
,
3399 "RELEASE", (struct string_list
*)0);
3400 if (client
-> alias
)
3401 script_write_params (client
, "alias_",
3403 script_write_params (client
, "old_", client
-> active
);
3408 /* Cancel any timeouts. */
3409 cancel_timeout (state_bound
, client
);
3410 cancel_timeout (send_discover
, client
);
3411 cancel_timeout (state_init
, client
);
3412 cancel_timeout (send_request
, client
);
3413 cancel_timeout (state_reboot
, client
);
3414 client
-> state
= S_STOPPED
;
3417 int dhclient_interface_shutdown_hook (struct interface_info
*interface
)
3419 do_release (interface
-> client
);
3424 int dhclient_interface_discovery_hook (struct interface_info
*tmp
)
3426 struct interface_info
*last
, *ip
;
3427 /* See if we can find the client from dummy_interfaces */
3429 for (ip
= dummy_interfaces
; ip
; ip
= ip
-> next
) {
3430 if (!strcmp (ip
-> name
, tmp
-> name
)) {
3431 /* Remove from dummy_interfaces */
3433 ip
= (struct interface_info
*)0;
3434 interface_reference (&ip
, last
-> next
, MDL
);
3435 interface_dereference (&last
-> next
, MDL
);
3437 interface_reference (&last
-> next
,
3439 interface_dereference (&ip
-> next
,
3443 ip
= (struct interface_info
*)0;
3444 interface_reference (&ip
,
3445 dummy_interfaces
, MDL
);
3446 interface_dereference (&dummy_interfaces
, MDL
);
3448 interface_reference (&dummy_interfaces
,
3450 interface_dereference (&ip
-> next
,
3454 /* Copy "client" to tmp */
3456 tmp
-> client
= ip
-> client
;
3457 tmp
-> client
-> interface
= tmp
;
3459 interface_dereference (&ip
, MDL
);
3467 isc_result_t
dhclient_interface_startup_hook (struct interface_info
*interface
)
3469 struct interface_info
*ip
;
3470 struct client_state
*client
;
3472 /* This code needs some rethinking. It doesn't test against
3473 a signal name, and it just kind of bulls into doing something
3474 that may or may not be appropriate. */
3477 interface_reference (&interface
-> next
, interfaces
, MDL
);
3478 interface_dereference (&interfaces
, MDL
);
3480 interface_reference (&interfaces
, interface
, MDL
);
3482 discover_interfaces (DISCOVER_UNCONFIGURED
);
3484 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
3485 /* If interfaces were specified, don't configure
3486 interfaces that weren't specified! */
3487 if (ip
-> flags
& INTERFACE_RUNNING
||
3488 (ip
-> flags
& (INTERFACE_REQUESTED
|
3489 INTERFACE_AUTOMATIC
)) !=
3490 INTERFACE_REQUESTED
)
3492 #ifdef BUILTIN_IFCONFIG
3493 interface_preinit (ip
-> client
);
3495 script_init (ip
-> client
,
3496 "PREINIT", (struct string_list
*)0);
3497 if (ip
-> client
-> alias
)
3498 script_write_params (ip
-> client
, "alias_",
3499 ip
-> client
-> alias
);
3500 script_go (ip
-> client
);
3504 discover_interfaces (interfaces_requested
3505 ? DISCOVER_REQUESTED
3506 : DISCOVER_RUNNING
);
3508 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
3509 if (ip
-> flags
& INTERFACE_RUNNING
)
3511 ip
-> flags
|= INTERFACE_RUNNING
;
3512 for (client
= ip
-> client
; client
; client
= client
-> next
) {
3513 client
-> state
= S_INIT
;
3514 /* Set up a timeout to start the initialization
3516 add_timeout (cur_time
+ random () % 5,
3517 state_reboot
, client
, 0, 0);
3520 return ISC_R_SUCCESS
;
3523 /* The client should never receive a relay agent information option,
3524 so if it does, log it and discard it. */
3526 int parse_agent_information_option (packet
, len
, data
)
3527 struct packet
*packet
;
3534 /* The client never sends relay agent information options. */
3536 unsigned cons_agent_information_options (cfg_options
, outpacket
,
3538 struct option_state
*cfg_options
;
3539 struct dhcp_packet
*outpacket
;
3546 static void shutdown_exit (void *foo
)
3551 isc_result_t
dhcp_set_control_state (control_object_state_t oldstate
,
3552 control_object_state_t newstate
)
3554 struct interface_info
*ip
;
3555 struct client_state
*client
;
3557 /* Do the right thing for each interface. */
3558 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
3559 for (client
= ip
-> client
; client
; client
= client
-> next
) {
3561 case server_startup
:
3562 return ISC_R_SUCCESS
;
3564 case server_running
:
3565 return ISC_R_SUCCESS
;
3567 case server_shutdown
:
3568 if (client
-> active
&&
3569 client
-> active
-> expiry
> cur_time
) {
3570 if (client
-> config
-> do_forward_update
)
3571 client_dns_update (client
, 0, 0);
3572 do_release (client
);
3576 case server_hibernate
:
3577 state_stop (client
);
3581 state_reboot (client
);
3586 if (newstate
== server_shutdown
)
3587 add_timeout (cur_time
+ 1, shutdown_exit
, 0, 0, 0);
3588 return ISC_R_SUCCESS
;
3591 /* Called after a timeout if the DNS update failed on the previous try.
3592 Retries the update, and if it times out, schedules a retry after
3593 ten times as long of a wait. */
3595 void client_dns_update_timeout (void *cp
)
3597 struct client_state
*client
= cp
;
3598 isc_result_t status
;
3600 if (client
-> active
) {
3601 status
= client_dns_update (client
, 1,
3602 (client
-> active
-> renewal
-
3604 if (status
== ISC_R_TIMEDOUT
) {
3605 client
-> dns_update_timeout
*= 10;
3606 add_timeout (cur_time
+ client
-> dns_update_timeout
,
3607 client_dns_update_timeout
, client
, 0, 0);
3612 /* See if we should do a DNS update, and if so, do it. */
3614 isc_result_t
client_dns_update (struct client_state
*client
, int addp
, int ttl
)
3616 struct data_string ddns_fwd_name
,
3617 ddns_dhcid
, client_identifier
;
3618 struct option_cache
*oc
;
3623 /* If we didn't send an FQDN option, we certainly aren't going to
3624 be doing an update. */
3625 if (!client
-> sent_options
)
3626 return ISC_R_SUCCESS
;
3628 /* If we don't have a lease, we can't do an update. */
3629 if (!client
-> active
)
3630 return ISC_R_SUCCESS
;
3632 /* If we set the no client update flag, don't do the update. */
3633 if ((oc
= lookup_option (&fqdn_universe
, client
-> sent_options
,
3634 FQDN_NO_CLIENT_UPDATE
)) &&
3635 evaluate_boolean_option_cache (&ignorep
, (struct packet
*)0,
3636 (struct lease
*)0, client
,
3637 client
-> sent_options
,
3638 (struct option_state
*)0,
3639 &global_scope
, oc
, MDL
))
3640 return ISC_R_SUCCESS
;
3642 /* If we set the "server, please update" flag, or didn't set it
3643 to false, don't do the update. */
3644 if (!(oc
= lookup_option (&fqdn_universe
, client
-> sent_options
,
3645 FQDN_SERVER_UPDATE
)) ||
3646 evaluate_boolean_option_cache (&ignorep
, (struct packet
*)0,
3647 (struct lease
*)0, client
,
3648 client
-> sent_options
,
3649 (struct option_state
*)0,
3650 &global_scope
, oc
, MDL
))
3651 return ISC_R_SUCCESS
;
3653 /* If no FQDN option was supplied, don't do the update. */
3654 memset (&ddns_fwd_name
, 0, sizeof ddns_fwd_name
);
3655 if (!(oc
= lookup_option (&fqdn_universe
, client
-> sent_options
,
3657 !evaluate_option_cache (&ddns_fwd_name
, (struct packet
*)0,
3658 (struct lease
*)0, client
,
3659 client
-> sent_options
,
3660 (struct option_state
*)0,
3661 &global_scope
, oc
, MDL
))
3662 return ISC_R_SUCCESS
;
3664 /* Make a dhcid string out of either the client identifier,
3665 if we are sending one, or the interface's MAC address,
3667 memset (&ddns_dhcid
, 0, sizeof ddns_dhcid
);
3669 memset (&client_identifier
, 0, sizeof client_identifier
);
3670 if ((oc
= lookup_option (&dhcp_universe
, client
-> sent_options
,
3671 DHO_DHCP_CLIENT_IDENTIFIER
)) &&
3672 evaluate_option_cache (&client_identifier
, (struct packet
*)0,
3673 (struct lease
*)0, client
,
3674 client
-> sent_options
,
3675 (struct option_state
*)0,
3676 &global_scope
, oc
, MDL
)) {
3677 result
= get_dhcid (&ddns_dhcid
,
3678 DHO_DHCP_CLIENT_IDENTIFIER
,
3679 client_identifier
.data
,
3680 client_identifier
.len
);
3681 data_string_forget (&client_identifier
, MDL
);
3683 result
= get_dhcid (&ddns_dhcid
, 0,
3684 client
-> interface
-> hw_address
.hbuf
,
3685 client
-> interface
-> hw_address
.hlen
);
3687 data_string_forget (&ddns_fwd_name
, MDL
);
3688 return ISC_R_SUCCESS
;
3691 /* Start the resolver, if necessary. */
3692 if (!resolver_inited
) {
3693 minires_ninit (&resolver_state
);
3694 resolver_inited
= 1;
3695 resolver_state
.retrans
= 1;
3696 resolver_state
.retry
= 1;
3702 if (ddns_fwd_name
.len
&& ddns_dhcid
.len
) {
3704 rcode
= ddns_update_a (&ddns_fwd_name
,
3705 client
-> active
-> address
,
3709 rcode
= ddns_remove_a (&ddns_fwd_name
,
3710 client
-> active
-> address
,
3713 rcode
= ISC_R_FAILURE
;
3715 data_string_forget (&ddns_fwd_name
, MDL
);
3716 data_string_forget (&ddns_dhcid
, MDL
);