]> git.ipfire.org Git - thirdparty/dhcp.git/blob - client/dhclient.c
- Merge changes between 3.0.3RC1 and 3.0.4-BETA-3 into HEAD (silence
[thirdparty/dhcp.git] / client / dhclient.c
1 /* dhclient.c
2
3 DHCP Client. */
4
5 /*
6 * Copyright (c) 2004-2006 by Internet Systems Consortium, Inc. ("ISC")
7 * Copyright (c) 1995-2003 by Internet Software Consortium
8 *
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.
12 *
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.
20 *
21 * Internet Systems Consortium, Inc.
22 * 950 Charter Street
23 * Redwood City, CA 94063
24 * <info@isc.org>
25 * http://www.isc.org/
26 *
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.
31 */
32
33 #ifndef lint
34 static char ocopyright[] =
35 "$Id: dhclient.c,v 1.133 2006/02/24 23:16:27 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
36 #endif /* not lint */
37
38 #include "dhcpd.h"
39 #include "version.h"
40
41 TIME default_lease_time = 43200; /* 12 hours... */
42 TIME max_lease_time = 86400; /* 24 hours... */
43
44 const char *path_dhclient_conf = _PATH_DHCLIENT_CONF;
45 const char *path_dhclient_db = _PATH_DHCLIENT_DB;
46 const char *path_dhclient_pid = _PATH_DHCLIENT_PID;
47 static char path_dhclient_script_array [] = _PATH_DHCLIENT_SCRIPT;
48 char *path_dhclient_script = path_dhclient_script_array;
49
50 int dhcp_max_agent_option_packet_length = 0;
51
52 int interfaces_requested = 0;
53
54 struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } };
55 struct iaddr iaddr_any = { 4, { 0, 0, 0, 0 } };
56 struct in_addr inaddr_any;
57 struct sockaddr_in sockaddr_broadcast;
58 struct in_addr giaddr;
59
60 /* ASSERT_STATE() does nothing now; it used to be
61 assert (state_is == state_shouldbe). */
62 #define ASSERT_STATE(state_is, state_shouldbe) {}
63
64 static char copyright[] = "Copyright 2004-2005 Internet Systems Consortium.";
65 static char arr [] = "All rights reserved.";
66 static char message [] = "Internet Systems Consortium DHCP Client";
67 static char url [] = "For info, please visit http://www.isc.org/products/DHCP";
68
69 u_int16_t local_port=0;
70 u_int16_t remote_port=0;
71 int no_daemon=0;
72 struct string_list *client_env=NULL;
73 int client_env_count=0;
74 int onetry=0;
75 int quiet=0;
76 int nowait=0;
77
78 static void usage PROTO ((void));
79
80 void do_release(struct client_state *);
81
82 int main (argc, argv, envp)
83 int argc;
84 char **argv, **envp;
85 {
86 int i;
87 struct servent *ent;
88 struct interface_info *ip;
89 struct client_state *client;
90 unsigned seed;
91 char *server = (char *)0;
92 char *relay = (char *)0;
93 isc_result_t status;
94 int release_mode = 0;
95 omapi_object_t *listener;
96 isc_result_t result;
97 int persist = 0;
98 int omapi_port;
99 int no_dhclient_conf = 0;
100 int no_dhclient_db = 0;
101 int no_dhclient_pid = 0;
102 int no_dhclient_script = 0;
103 char *s;
104
105 /* Make sure we have stdin, stdout and stderr. */
106 i = open ("/dev/null", O_RDWR);
107 if (i == 0)
108 i = open ("/dev/null", O_RDWR);
109 if (i == 1) {
110 i = open ("/dev/null", O_RDWR);
111 log_perror = 0; /* No sense logging to /dev/null. */
112 } else if (i != -1)
113 close (i);
114
115 #ifdef SYSLOG_4_2
116 openlog ("dhclient", LOG_NDELAY);
117 log_priority = LOG_DAEMON;
118 #else
119 openlog ("dhclient", LOG_NDELAY, LOG_DAEMON);
120 #endif
121
122 #if !(defined (DEBUG) || defined (SYSLOG_4_2) || defined (__CYGWIN32__))
123 setlogmask (LOG_UPTO (LOG_INFO));
124 #endif
125
126 /* Set up the OMAPI. */
127 status = omapi_init ();
128 if (status != ISC_R_SUCCESS)
129 log_fatal ("Can't initialize OMAPI: %s",
130 isc_result_totext (status));
131
132 /* Set up the OMAPI wrappers for various server database internal
133 objects. */
134 dhcp_common_objects_setup ();
135
136 dhcp_interface_discovery_hook = dhclient_interface_discovery_hook;
137 dhcp_interface_shutdown_hook = dhclient_interface_shutdown_hook;
138 dhcp_interface_startup_hook = dhclient_interface_startup_hook;
139
140 for (i = 1; i < argc; i++) {
141 if (!strcmp (argv [i], "-r")) {
142 release_mode = 1;
143 no_daemon = 1;
144 } else if (!strcmp (argv [i], "-p")) {
145 if (++i == argc)
146 usage ();
147 local_port = htons (atoi (argv [i]));
148 log_debug ("binding to user-specified port %d",
149 ntohs (local_port));
150 } else if (!strcmp (argv [i], "-d")) {
151 no_daemon = 1;
152 } else if (!strcmp (argv [i], "-pf")) {
153 if (++i == argc)
154 usage ();
155 path_dhclient_pid = argv [i];
156 no_dhclient_pid = 1;
157 } else if (!strcmp (argv [i], "-cf")) {
158 if (++i == argc)
159 usage ();
160 path_dhclient_conf = argv [i];
161 no_dhclient_conf = 1;
162 } else if (!strcmp (argv [i], "-lf")) {
163 if (++i == argc)
164 usage ();
165 path_dhclient_db = argv [i];
166 no_dhclient_db = 1;
167 } else if (!strcmp (argv [i], "-sf")) {
168 if (++i == argc)
169 usage ();
170 path_dhclient_script = argv [i];
171 no_dhclient_script = 1;
172 } else if (!strcmp (argv [i], "-1")) {
173 onetry = 1;
174 } else if (!strcmp (argv [i], "-q")) {
175 quiet = 1;
176 quiet_interface_discovery = 1;
177 } else if (!strcmp (argv [i], "-s")) {
178 if (++i == argc)
179 usage ();
180 server = argv [i];
181 } else if (!strcmp (argv [i], "-g")) {
182 if (++i == argc)
183 usage ();
184 relay = argv [i];
185 } else if (!strcmp (argv [i], "-nw")) {
186 nowait = 1;
187 } else if (!strcmp (argv [i], "-n")) {
188 /* do not start up any interfaces */
189 interfaces_requested = 1;
190 } else if (!strcmp (argv [i], "-w")) {
191 /* do not exit if there are no broadcast interfaces. */
192 persist = 1;
193 } else if (!strcmp (argv [i], "-e")) {
194 struct string_list *tmp;
195 if (++i == argc)
196 usage ();
197 tmp = dmalloc (strlen (argv [i]) + sizeof *tmp, MDL);
198 if (!tmp)
199 log_fatal ("No memory for %s", argv [i]);
200 strcpy (tmp -> string, argv [i]);
201 tmp -> next = client_env;
202 client_env = tmp;
203 client_env_count++;
204 } else if (!strcmp (argv [i], "--version")) {
205 log_info ("isc-dhclient-%s", DHCP_VERSION);
206 exit (0);
207 } else if (argv [i][0] == '-') {
208 usage ();
209 } else {
210 struct interface_info *tmp = (struct interface_info *)0;
211 status = interface_allocate (&tmp, MDL);
212 if (status != ISC_R_SUCCESS)
213 log_fatal ("Can't record interface %s:%s",
214 argv [i], isc_result_totext (status));
215 if (strlen(argv[i]) >= sizeof(tmp->name))
216 log_fatal("%s: interface name too long (is %ld)",
217 argv [i], (long)strlen(argv[i]));
218 strcpy(tmp->name, argv[i]);
219 if (interfaces) {
220 interface_reference (&tmp -> next,
221 interfaces, MDL);
222 interface_dereference (&interfaces, MDL);
223 }
224 interface_reference (&interfaces, tmp, MDL);
225 tmp -> flags = INTERFACE_REQUESTED;
226 interfaces_requested = 1;
227 }
228 }
229
230 if (!no_dhclient_conf && (s = getenv ("PATH_DHCLIENT_CONF"))) {
231 path_dhclient_conf = s;
232 }
233 if (!no_dhclient_db && (s = getenv ("PATH_DHCLIENT_DB"))) {
234 path_dhclient_db = s;
235 }
236 if (!no_dhclient_pid && (s = getenv ("PATH_DHCLIENT_PID"))) {
237 path_dhclient_pid = s;
238 }
239 if (!no_dhclient_script && (s = getenv ("PATH_DHCLIENT_SCRIPT"))) {
240 path_dhclient_script = s;
241 }
242
243 /* first kill of any currently running client */
244 if (release_mode) {
245 FILE *pidfd;
246 pid_t oldpid;
247 long temp;
248 int e;
249
250 oldpid = 0;
251 if ((pidfd = fopen(path_dhclient_pid, "r")) != NULL) {
252 e = fscanf(pidfd, "%ld\n", &temp);
253 oldpid = (pid_t)temp;
254
255 if (e != 0 && e != EOF) {
256 if (oldpid) {
257 if (kill(oldpid, SIGTERM) == 0)
258 unlink(path_dhclient_pid);
259 }
260 }
261 fclose(pidfd);
262 }
263 }
264
265 if (!quiet) {
266 log_info ("%s %s", message, DHCP_VERSION);
267 log_info (copyright);
268 log_info (arr);
269 log_info (url);
270 log_info ("%s", "");
271 } else
272 log_perror = 0;
273
274 /* If we're given a relay agent address to insert, for testing
275 purposes, figure out what it is. */
276 if (relay) {
277 if (!inet_aton (relay, &giaddr)) {
278 struct hostent *he;
279 he = gethostbyname (relay);
280 if (he) {
281 memcpy (&giaddr, he -> h_addr_list [0],
282 sizeof giaddr);
283 } else {
284 log_fatal ("%s: no such host", relay);
285 }
286 }
287 }
288
289 /* Default to the DHCP/BOOTP port. */
290 if (!local_port) {
291 /* If we're faking a relay agent, and we're not using loopback,
292 use the server port, not the client port. */
293 if (relay && giaddr.s_addr != htonl (INADDR_LOOPBACK)) {
294 local_port = htons(67);
295 } else {
296 ent = getservbyname ("dhcpc", "udp");
297 if (!ent)
298 local_port = htons (68);
299 else
300 local_port = ent -> s_port;
301 #ifndef __CYGWIN32__
302 endservent ();
303 #endif
304 }
305 }
306
307 /* If we're faking a relay agent, and we're not using loopback,
308 we're using the server port, not the client port. */
309 if (relay && giaddr.s_addr != htonl (INADDR_LOOPBACK)) {
310 remote_port = local_port;
311 } else
312 remote_port = htons (ntohs (local_port) - 1); /* XXX */
313
314 /* Get the current time... */
315 GET_TIME (&cur_time);
316
317 sockaddr_broadcast.sin_family = AF_INET;
318 sockaddr_broadcast.sin_port = remote_port;
319 if (server) {
320 if (!inet_aton (server, &sockaddr_broadcast.sin_addr)) {
321 struct hostent *he;
322 he = gethostbyname (server);
323 if (he) {
324 memcpy (&sockaddr_broadcast.sin_addr,
325 he -> h_addr_list [0],
326 sizeof sockaddr_broadcast.sin_addr);
327 } else
328 sockaddr_broadcast.sin_addr.s_addr =
329 INADDR_BROADCAST;
330 }
331 } else {
332 sockaddr_broadcast.sin_addr.s_addr = INADDR_BROADCAST;
333 }
334
335 inaddr_any.s_addr = INADDR_ANY;
336
337 /* Discover all the network interfaces. */
338 discover_interfaces (DISCOVER_UNCONFIGURED);
339
340 /* Parse the dhclient.conf file. */
341 read_client_conf ();
342
343 /* Parse the lease database. */
344 read_client_leases ();
345
346 /* Rewrite the lease database... */
347 rewrite_client_leases ();
348
349 /* XXX */
350 /* config_counter(&snd_counter, &rcv_counter); */
351
352 /* If no broadcast interfaces were discovered, call the script
353 and tell it so. */
354 if (!interfaces) {
355 /* Call dhclient-script with the NBI flag, in case somebody
356 cares. */
357 script_init ((struct client_state *)0, "NBI",
358 (struct string_list *)0);
359 script_go ((struct client_state *)0);
360
361 /* If we haven't been asked to persist, waiting for new
362 interfaces, then just exit. */
363 if (!persist) {
364 /* Nothing more to do. */
365 log_info ("No broadcast interfaces found - exiting.");
366 exit (0);
367 }
368 } else if (!release_mode) {
369 /* Call the script with the list of interfaces. */
370 for (ip = interfaces; ip; ip = ip -> next) {
371 /* If interfaces were specified, don't configure
372 interfaces that weren't specified! */
373 if (interfaces_requested &&
374 ((ip -> flags & (INTERFACE_REQUESTED |
375 INTERFACE_AUTOMATIC)) !=
376 INTERFACE_REQUESTED))
377 continue;
378 script_init (ip -> client,
379 "PREINIT", (struct string_list *)0);
380 if (ip -> client -> alias)
381 script_write_params (ip -> client, "alias_",
382 ip -> client -> alias);
383 script_go (ip -> client);
384 }
385 }
386
387 /* At this point, all the interfaces that the script thinks
388 are relevant should be running, so now we once again call
389 discover_interfaces(), and this time ask it to actually set
390 up the interfaces. */
391 discover_interfaces (interfaces_requested
392 ? DISCOVER_REQUESTED
393 : DISCOVER_RUNNING);
394
395 /* Make up a seed for the random number generator from current
396 time plus the sum of the last four bytes of each
397 interface's hardware address interpreted as an integer.
398 Not much entropy, but we're booting, so we're not likely to
399 find anything better. */
400 seed = 0;
401 for (ip = interfaces; ip; ip = ip -> next) {
402 int junk;
403 memcpy (&junk,
404 &ip -> hw_address.hbuf [ip -> hw_address.hlen -
405 sizeof seed], sizeof seed);
406 seed += junk;
407 }
408 srandom (seed + cur_time);
409
410 /* Start a configuration state machine for each interface. */
411 for (ip = interfaces; ip; ip = ip -> next) {
412 ip -> flags |= INTERFACE_RUNNING;
413 for (client = ip -> client; client; client = client -> next) {
414 if (release_mode)
415 do_release (client);
416 else {
417 client -> state = S_INIT;
418 /* Set up a timeout to start the initialization
419 process. */
420 add_timeout (cur_time + random () % 5,
421 state_reboot, client, 0, 0);
422 }
423 }
424 }
425
426 if (release_mode)
427 return 0;
428
429 /* Start up a listener for the object management API protocol. */
430 if (top_level_config.omapi_port != -1) {
431 listener = (omapi_object_t *)0;
432 result = omapi_generic_new (&listener, MDL);
433 if (result != ISC_R_SUCCESS)
434 log_fatal ("Can't allocate new generic object: %s\n",
435 isc_result_totext (result));
436 result = omapi_protocol_listen (listener,
437 (unsigned)
438 top_level_config.omapi_port,
439 1);
440 if (result != ISC_R_SUCCESS)
441 log_fatal ("Can't start OMAPI protocol: %s",
442 isc_result_totext (result));
443 }
444
445 /* Set up the bootp packet handler... */
446 bootp_packet_handler = do_packet;
447
448 #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
449 defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
450 dmalloc_cutoff_generation = dmalloc_generation;
451 dmalloc_longterm = dmalloc_outstanding;
452 dmalloc_outstanding = 0;
453 #endif
454
455 /* If we're not supposed to wait before getting the address,
456 don't. */
457 if (nowait)
458 go_daemon ();
459
460 /* If we're not going to daemonize, write the pid file
461 now. */
462 if (no_daemon || nowait)
463 write_client_pid_file ();
464
465 /* Start dispatching packets and timeouts... */
466 dispatch ();
467
468 /*NOTREACHED*/
469 return 0;
470 }
471
472 static void usage ()
473 {
474 log_info ("%s %s", message, DHCP_VERSION);
475 log_info (copyright);
476 log_info (arr);
477 log_info (url);
478
479 log_error ("Usage: dhclient [-1dqr] [-nw] [-p <port>] %s",
480 "[-s server]");
481 log_error (" [-cf config-file] [-lf lease-file]%s",
482 "[-pf pid-file] [-e VAR=val]");
483 log_fatal (" [-sf script-file] [interface]");
484 }
485
486 isc_result_t find_class (struct class **c,
487 const char *s, const char *file, int line)
488 {
489 return 0;
490 }
491
492 int check_collection (packet, lease, collection)
493 struct packet *packet;
494 struct lease *lease;
495 struct collection *collection;
496 {
497 return 0;
498 }
499
500 void classify (packet, class)
501 struct packet *packet;
502 struct class *class;
503 {
504 }
505
506 int unbill_class (lease, class)
507 struct lease *lease;
508 struct class *class;
509 {
510 return 0;
511 }
512
513 int find_subnet (struct subnet **sp,
514 struct iaddr addr, const char *file, int line)
515 {
516 return 0;
517 }
518
519 /* Individual States:
520 *
521 * Each routine is called from the dhclient_state_machine() in one of
522 * these conditions:
523 * -> entering INIT state
524 * -> recvpacket_flag == 0: timeout in this state
525 * -> otherwise: received a packet in this state
526 *
527 * Return conditions as handled by dhclient_state_machine():
528 * Returns 1, sendpacket_flag = 1: send packet, reset timer.
529 * Returns 1, sendpacket_flag = 0: just reset the timer (wait for a milestone).
530 * Returns 0: finish the nap which was interrupted for no good reason.
531 *
532 * Several per-interface variables are used to keep track of the process:
533 * active_lease: the lease that is being used on the interface
534 * (null pointer if not configured yet).
535 * offered_leases: leases corresponding to DHCPOFFER messages that have
536 * been sent to us by DHCP servers.
537 * acked_leases: leases corresponding to DHCPACK messages that have been
538 * sent to us by DHCP servers.
539 * sendpacket: DHCP packet we're trying to send.
540 * destination: IP address to send sendpacket to
541 * In addition, there are several relevant per-lease variables.
542 * T1_expiry, T2_expiry, lease_expiry: lease milestones
543 * In the active lease, these control the process of renewing the lease;
544 * In leases on the acked_leases list, this simply determines when we
545 * can no longer legitimately use the lease.
546 */
547
548 void state_reboot (cpp)
549 void *cpp;
550 {
551 struct client_state *client = cpp;
552
553 /* If we don't remember an active lease, go straight to INIT. */
554 if (!client -> active ||
555 client -> active -> is_bootp ||
556 client -> active -> expiry <= cur_time) {
557 state_init (client);
558 return;
559 }
560
561 /* We are in the rebooting state. */
562 client -> state = S_REBOOTING;
563
564 /* make_request doesn't initialize xid because it normally comes
565 from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
566 so pick an xid now. */
567 client -> xid = random ();
568
569 /* Make a DHCPREQUEST packet, and set appropriate per-interface
570 flags. */
571 make_request (client, client -> active);
572 client -> destination = iaddr_broadcast;
573 client -> first_sending = cur_time;
574 client -> interval = client -> config -> initial_interval;
575
576 /* Zap the medium list... */
577 client -> medium = (struct string_list *)0;
578
579 /* Send out the first DHCPREQUEST packet. */
580 send_request (client);
581 }
582
583 /* Called when a lease has completely expired and we've been unable to
584 renew it. */
585
586 void state_init (cpp)
587 void *cpp;
588 {
589 struct client_state *client = cpp;
590
591 ASSERT_STATE(state, S_INIT);
592
593 /* Make a DHCPDISCOVER packet, and set appropriate per-interface
594 flags. */
595 make_discover (client, client -> active);
596 client -> xid = client -> packet.xid;
597 client -> destination = iaddr_broadcast;
598 client -> state = S_SELECTING;
599 client -> first_sending = cur_time;
600 client -> interval = client -> config -> initial_interval;
601
602 /* Add an immediate timeout to cause the first DHCPDISCOVER packet
603 to go out. */
604 send_discover (client);
605 }
606
607 /* state_selecting is called when one or more DHCPOFFER packets have been
608 received and a configurable period of time has passed. */
609
610 void state_selecting (cpp)
611 void *cpp;
612 {
613 struct client_state *client = cpp;
614 struct client_lease *lp, *next, *picked;
615
616
617 ASSERT_STATE(state, S_SELECTING);
618
619 /* Cancel state_selecting and send_discover timeouts, since either
620 one could have got us here. */
621 cancel_timeout (state_selecting, client);
622 cancel_timeout (send_discover, client);
623
624 /* We have received one or more DHCPOFFER packets. Currently,
625 the only criterion by which we judge leases is whether or
626 not we get a response when we arp for them. */
627 picked = (struct client_lease *)0;
628 for (lp = client -> offered_leases; lp; lp = next) {
629 next = lp -> next;
630
631 /* Check to see if we got an ARPREPLY for the address
632 in this particular lease. */
633 if (!picked) {
634 picked = lp;
635 picked -> next = (struct client_lease *)0;
636 } else {
637 freeit:
638 destroy_client_lease (lp);
639 }
640 }
641 client -> offered_leases = (struct client_lease *)0;
642
643 /* If we just tossed all the leases we were offered, go back
644 to square one. */
645 if (!picked) {
646 client -> state = S_INIT;
647 state_init (client);
648 return;
649 }
650
651 /* If it was a BOOTREPLY, we can just take the address right now. */
652 if (picked -> is_bootp) {
653 client -> new = picked;
654
655 /* Make up some lease expiry times
656 XXX these should be configurable. */
657 client -> new -> expiry = cur_time + 12000;
658 client -> new -> renewal += cur_time + 8000;
659 client -> new -> rebind += cur_time + 10000;
660
661 client -> state = S_REQUESTING;
662
663 /* Bind to the address we received. */
664 bind_lease (client);
665 return;
666 }
667
668 /* Go to the REQUESTING state. */
669 client -> destination = iaddr_broadcast;
670 client -> state = S_REQUESTING;
671 client -> first_sending = cur_time;
672 client -> interval = client -> config -> initial_interval;
673
674 /* Make a DHCPREQUEST packet from the lease we picked. */
675 make_request (client, picked);
676 client -> xid = client -> packet.xid;
677
678 /* Toss the lease we picked - we'll get it back in a DHCPACK. */
679 destroy_client_lease (picked);
680
681 /* Add an immediate timeout to send the first DHCPREQUEST packet. */
682 send_request (client);
683 }
684
685 /* state_requesting is called when we receive a DHCPACK message after
686 having sent out one or more DHCPREQUEST packets. */
687
688 void dhcpack (packet)
689 struct packet *packet;
690 {
691 struct interface_info *ip = packet -> interface;
692 struct client_state *client;
693 struct client_lease *lease;
694 struct option_cache *oc;
695 struct data_string ds;
696 int i;
697
698 /* If we're not receptive to an offer right now, or if the offer
699 has an unrecognizable transaction id, then just drop it. */
700 for (client = ip -> client; client; client = client -> next) {
701 if (client -> xid == packet -> raw -> xid)
702 break;
703 }
704 if (!client ||
705 (packet -> interface -> hw_address.hlen - 1 !=
706 packet -> raw -> hlen) ||
707 (memcmp (&packet -> interface -> hw_address.hbuf [1],
708 packet -> raw -> chaddr, packet -> raw -> hlen))) {
709 #if defined (DEBUG)
710 log_debug ("DHCPACK in wrong transaction.");
711 #endif
712 return;
713 }
714
715 if (client -> state != S_REBOOTING &&
716 client -> state != S_REQUESTING &&
717 client -> state != S_RENEWING &&
718 client -> state != S_REBINDING) {
719 #if defined (DEBUG)
720 log_debug ("DHCPACK in wrong state.");
721 #endif
722 return;
723 }
724
725 log_info ("DHCPACK from %s", piaddr (packet -> client_addr));
726
727 lease = packet_to_lease (packet, client);
728 if (!lease) {
729 log_info ("packet_to_lease failed.");
730 return;
731 }
732
733 client -> new = lease;
734
735 /* Stop resending DHCPREQUEST. */
736 cancel_timeout (send_request, client);
737
738 /* Figure out the lease time. */
739 oc = lookup_option (&dhcp_universe, client -> new -> options,
740 DHO_DHCP_LEASE_TIME);
741 memset (&ds, 0, sizeof ds);
742 if (oc &&
743 evaluate_option_cache (&ds, packet, (struct lease *)0, client,
744 packet -> options, client -> new -> options,
745 &global_scope, oc, MDL)) {
746 if (ds.len > 3)
747 client -> new -> expiry = getULong (ds.data);
748 else
749 client -> new -> expiry = 0;
750 data_string_forget (&ds, MDL);
751 } else
752 client -> new -> expiry = 0;
753
754 if (!client -> new -> expiry) {
755 log_error ("no expiry time on offered lease.");
756 /* XXX this is going to be bad - if this _does_
757 XXX happen, we should probably dynamically
758 XXX disqualify the DHCP server that gave us the
759 XXX bad packet from future selections and
760 XXX then go back into the init state. */
761 state_init (client);
762 return;
763 }
764
765 /* A number that looks negative here is really just very large,
766 because the lease expiry offset is unsigned. */
767 if (client -> new -> expiry < 0)
768 client -> new -> expiry = TIME_MAX;
769 /* Take the server-provided renewal time if there is one. */
770 oc = lookup_option (&dhcp_universe, client -> new -> options,
771 DHO_DHCP_RENEWAL_TIME);
772 if (oc &&
773 evaluate_option_cache (&ds, packet, (struct lease *)0, client,
774 packet -> options, client -> new -> options,
775 &global_scope, oc, MDL)) {
776 if (ds.len > 3)
777 client -> new -> renewal = getULong (ds.data);
778 else
779 client -> new -> renewal = 0;
780 data_string_forget (&ds, MDL);
781 } else
782 client -> new -> renewal = 0;
783
784 /* If it wasn't specified by the server, calculate it. */
785 if (!client -> new -> renewal)
786 client -> new -> renewal = client -> new -> expiry / 2 + 1;
787
788 if (client -> new -> renewal <= 0)
789 client -> new -> renewal = TIME_MAX;
790
791 /* Now introduce some randomness to the renewal time: */
792 if (client->new->renewal <= ((TIME_MAX / 3) - 3))
793 client->new->renewal = (((client->new->renewal * 3) + 3) / 4) +
794 (((random() % client->new->renewal) + 3) / 4);
795
796 /* Same deal with the rebind time. */
797 oc = lookup_option (&dhcp_universe, client -> new -> options,
798 DHO_DHCP_REBINDING_TIME);
799 if (oc &&
800 evaluate_option_cache (&ds, packet, (struct lease *)0, client,
801 packet -> options, client -> new -> options,
802 &global_scope, oc, MDL)) {
803 if (ds.len > 3)
804 client -> new -> rebind = getULong (ds.data);
805 else
806 client -> new -> rebind = 0;
807 data_string_forget (&ds, MDL);
808 } else
809 client -> new -> rebind = 0;
810
811 if (client -> new -> rebind <= 0) {
812 if (client -> new -> expiry <= TIME_MAX / 7)
813 client -> new -> rebind =
814 client -> new -> expiry * 7 / 8;
815 else
816 client -> new -> rebind =
817 client -> new -> expiry / 8 * 7;
818 }
819
820 /* Make sure our randomness didn't run the renewal time past the
821 rebind time. */
822 if (client -> new -> renewal > client -> new -> rebind) {
823 if (client -> new -> rebind <= TIME_MAX / 3)
824 client -> new -> renewal =
825 client -> new -> rebind * 3 / 4;
826 else
827 client -> new -> renewal =
828 client -> new -> rebind / 4 * 3;
829 }
830
831 client -> new -> expiry += cur_time;
832 /* Lease lengths can never be negative. */
833 if (client -> new -> expiry < cur_time)
834 client -> new -> expiry = TIME_MAX;
835 client -> new -> renewal += cur_time;
836 if (client -> new -> renewal < cur_time)
837 client -> new -> renewal = TIME_MAX;
838 client -> new -> rebind += cur_time;
839 if (client -> new -> rebind < cur_time)
840 client -> new -> rebind = TIME_MAX;
841
842 bind_lease (client);
843 }
844
845 void bind_lease (client)
846 struct client_state *client;
847 {
848 struct interface_info *ip = client -> interface;
849
850 /* Remember the medium. */
851 client -> new -> medium = client -> medium;
852
853 /* Run the client script with the new parameters. */
854 script_init (client, (client -> state == S_REQUESTING
855 ? "BOUND"
856 : (client -> state == S_RENEWING
857 ? "RENEW"
858 : (client -> state == S_REBOOTING
859 ? "REBOOT" : "REBIND"))),
860 client -> new -> medium);
861 if (client -> active && client -> state != S_REBOOTING)
862 script_write_params (client, "old_", client -> active);
863 script_write_params (client, "new_", client -> new);
864 if (client -> alias)
865 script_write_params (client, "alias_", client -> alias);
866
867 /* If the BOUND/RENEW code detects another machine using the
868 offered address, it exits nonzero. We need to send a
869 DHCPDECLINE and toss the lease. */
870 if (script_go (client)) {
871 make_decline (client, client -> new);
872 send_decline (client);
873 destroy_client_lease (client -> new);
874 client -> new = (struct client_lease *)0;
875 state_init (client);
876 return;
877 }
878
879 /* Write out the new lease. */
880 write_client_lease (client, client -> new, 0, 0);
881
882 /* Replace the old active lease with the new one. */
883 if (client -> active)
884 destroy_client_lease (client -> active);
885 client -> active = client -> new;
886 client -> new = (struct client_lease *)0;
887
888 /* Set up a timeout to start the renewal process. */
889 add_timeout (client -> active -> renewal,
890 state_bound, client, 0, 0);
891
892 log_info ("bound to %s -- renewal in %ld seconds.",
893 piaddr (client -> active -> address),
894 (long)(client -> active -> renewal - cur_time));
895 client -> state = S_BOUND;
896 reinitialize_interfaces ();
897 go_daemon ();
898 if (client -> config -> do_forward_update) {
899 client -> dns_update_timeout = 1;
900 add_timeout (cur_time + 1, client_dns_update_timeout,
901 client, 0, 0);
902 }
903 }
904
905 /* state_bound is called when we've successfully bound to a particular
906 lease, but the renewal time on that lease has expired. We are
907 expected to unicast a DHCPREQUEST to the server that gave us our
908 original lease. */
909
910 void state_bound (cpp)
911 void *cpp;
912 {
913 struct client_state *client = cpp;
914 int i;
915 struct option_cache *oc;
916 struct data_string ds;
917
918 ASSERT_STATE(state, S_BOUND);
919
920 /* T1 has expired. */
921 make_request (client, client -> active);
922 client -> xid = client -> packet.xid;
923
924 memset (&ds, 0, sizeof ds);
925 oc = lookup_option (&dhcp_universe, client -> active -> options,
926 DHO_DHCP_SERVER_IDENTIFIER);
927 if (oc &&
928 evaluate_option_cache (&ds, (struct packet *)0, (struct lease *)0,
929 client, (struct option_state *)0,
930 client -> active -> options,
931 &global_scope, oc, MDL)) {
932 if (ds.len > 3) {
933 memcpy (client -> destination.iabuf, ds.data, 4);
934 client -> destination.len = 4;
935 } else
936 client -> destination = iaddr_broadcast;
937
938 data_string_forget (&ds, MDL);
939 } else
940 client -> destination = iaddr_broadcast;
941
942 client -> first_sending = cur_time;
943 client -> interval = client -> config -> initial_interval;
944 client -> state = S_RENEWING;
945
946 /* Send the first packet immediately. */
947 send_request (client);
948 }
949
950 /* state_stop is called when we've been told to shut down. We unconfigure
951 the interfaces, and then stop operating until told otherwise. */
952
953 void state_stop (cpp)
954 void *cpp;
955 {
956 struct client_state *client = cpp;
957 int i;
958
959 /* Cancel all timeouts. */
960 cancel_timeout (state_selecting, client);
961 cancel_timeout (send_discover, client);
962 cancel_timeout (send_request, client);
963 cancel_timeout (state_bound, client);
964
965 /* If we have an address, unconfigure it. */
966 if (client -> active) {
967 script_init (client, "STOP", client -> active -> medium);
968 script_write_params (client, "old_", client -> active);
969 if (client -> alias)
970 script_write_params (client, "alias_",
971 client -> alias);
972 script_go (client);
973 }
974 }
975
976 int commit_leases ()
977 {
978 return 0;
979 }
980
981 int write_lease (lease)
982 struct lease *lease;
983 {
984 return 0;
985 }
986
987 int write_host (host)
988 struct host_decl *host;
989 {
990 return 0;
991 }
992
993 void db_startup (testp)
994 int testp;
995 {
996 }
997
998 void bootp (packet)
999 struct packet *packet;
1000 {
1001 struct iaddrlist *ap;
1002
1003 if (packet -> raw -> op != BOOTREPLY)
1004 return;
1005
1006 /* If there's a reject list, make sure this packet's sender isn't
1007 on it. */
1008 for (ap = packet -> interface -> client -> config -> reject_list;
1009 ap; ap = ap -> next) {
1010 if (addr_eq (packet -> client_addr, ap -> addr)) {
1011 log_info ("BOOTREPLY from %s rejected.",
1012 piaddr (ap -> addr));
1013 return;
1014 }
1015 }
1016
1017 dhcpoffer (packet);
1018
1019 }
1020
1021 void dhcp (packet)
1022 struct packet *packet;
1023 {
1024 struct iaddrlist *ap;
1025 void (*handler) PROTO ((struct packet *));
1026 const char *type;
1027
1028 switch (packet -> packet_type) {
1029 case DHCPOFFER:
1030 handler = dhcpoffer;
1031 type = "DHCPOFFER";
1032 break;
1033
1034 case DHCPNAK:
1035 handler = dhcpnak;
1036 type = "DHCPNACK";
1037 break;
1038
1039 case DHCPACK:
1040 handler = dhcpack;
1041 type = "DHCPACK";
1042 break;
1043
1044 default:
1045 return;
1046 }
1047
1048 /* If there's a reject list, make sure this packet's sender isn't
1049 on it. */
1050 for (ap = packet -> interface -> client -> config -> reject_list;
1051 ap; ap = ap -> next) {
1052 if (addr_eq (packet -> client_addr, ap -> addr)) {
1053 log_info ("%s from %s rejected.",
1054 type, piaddr (ap -> addr));
1055 return;
1056 }
1057 }
1058 (*handler) (packet);
1059 }
1060
1061 void dhcpoffer (packet)
1062 struct packet *packet;
1063 {
1064 struct interface_info *ip = packet -> interface;
1065 struct client_state *client;
1066 struct client_lease *lease, *lp;
1067 int i;
1068 int stop_selecting;
1069 const char *name = packet -> packet_type ? "DHCPOFFER" : "BOOTREPLY";
1070 struct iaddrlist *ap;
1071 struct option_cache *oc;
1072 char obuf [1024];
1073
1074 #ifdef DEBUG_PACKET
1075 dump_packet (packet);
1076 #endif
1077
1078 /* Find a client state that matches the xid... */
1079 for (client = ip -> client; client; client = client -> next)
1080 if (client -> xid == packet -> raw -> xid)
1081 break;
1082
1083 /* If we're not receptive to an offer right now, or if the offer
1084 has an unrecognizable transaction id, then just drop it. */
1085 if (!client ||
1086 client -> state != S_SELECTING ||
1087 (packet -> interface -> hw_address.hlen - 1 !=
1088 packet -> raw -> hlen) ||
1089 (memcmp (&packet -> interface -> hw_address.hbuf [1],
1090 packet -> raw -> chaddr, packet -> raw -> hlen))) {
1091 #if defined (DEBUG)
1092 log_debug ("%s in wrong transaction.", name);
1093 #endif
1094 return;
1095 }
1096
1097 sprintf (obuf, "%s from %s", name, piaddr (packet -> client_addr));
1098
1099
1100 /* If this lease doesn't supply the minimum required parameters,
1101 blow it off. */
1102 if (client -> config -> required_options) {
1103 for (i = 0; client -> config -> required_options [i]; i++) {
1104 if (!lookup_option
1105 (&dhcp_universe, packet -> options,
1106 client -> config -> required_options [i])) {
1107 log_info ("%s: no %s option.",
1108 obuf, (dhcp_universe.options
1109 [client -> config -> required_options [i]]
1110 -> name));
1111 return;
1112 }
1113 }
1114 }
1115
1116 /* If we've already seen this lease, don't record it again. */
1117 for (lease = client -> offered_leases; lease; lease = lease -> next) {
1118 if (lease -> address.len == sizeof packet -> raw -> yiaddr &&
1119 !memcmp (lease -> address.iabuf,
1120 &packet -> raw -> yiaddr, lease -> address.len)) {
1121 log_debug ("%s: already seen.", obuf);
1122 return;
1123 }
1124 }
1125
1126 lease = packet_to_lease (packet, client);
1127 if (!lease) {
1128 log_info ("%s: packet_to_lease failed.", obuf);
1129 return;
1130 }
1131
1132 /* If this lease was acquired through a BOOTREPLY, record that
1133 fact. */
1134 if (!packet -> options_valid || !packet -> packet_type)
1135 lease -> is_bootp = 1;
1136
1137 /* Record the medium under which this lease was offered. */
1138 lease -> medium = client -> medium;
1139
1140 /* Figure out when we're supposed to stop selecting. */
1141 stop_selecting = (client -> first_sending +
1142 client -> config -> select_interval);
1143
1144 /* If this is the lease we asked for, put it at the head of the
1145 list, and don't mess with the arp request timeout. */
1146 if (lease -> address.len == client -> requested_address.len &&
1147 !memcmp (lease -> address.iabuf,
1148 client -> requested_address.iabuf,
1149 client -> requested_address.len)) {
1150 lease -> next = client -> offered_leases;
1151 client -> offered_leases = lease;
1152 } else {
1153 /* Put the lease at the end of the list. */
1154 lease -> next = (struct client_lease *)0;
1155 if (!client -> offered_leases)
1156 client -> offered_leases = lease;
1157 else {
1158 for (lp = client -> offered_leases; lp -> next;
1159 lp = lp -> next)
1160 ;
1161 lp -> next = lease;
1162 }
1163 }
1164
1165 /* If the selecting interval has expired, go immediately to
1166 state_selecting(). Otherwise, time out into
1167 state_selecting at the select interval. */
1168 if (stop_selecting <= 0)
1169 state_selecting (client);
1170 else {
1171 add_timeout (stop_selecting, state_selecting, client, 0, 0);
1172 cancel_timeout (send_discover, client);
1173 }
1174 log_info ("%s", obuf);
1175 }
1176
1177 /* Allocate a client_lease structure and initialize it from the parameters
1178 in the specified packet. */
1179
1180 struct client_lease *packet_to_lease (packet, client)
1181 struct packet *packet;
1182 struct client_state *client;
1183 {
1184 struct client_lease *lease;
1185 unsigned i;
1186 struct option_cache *oc;
1187 struct data_string data;
1188
1189 lease = (struct client_lease *)new_client_lease (MDL);
1190
1191 if (!lease) {
1192 log_error ("packet_to_lease: no memory to record lease.\n");
1193 return (struct client_lease *)0;
1194 }
1195
1196 memset (lease, 0, sizeof *lease);
1197
1198 /* Copy the lease options. */
1199 option_state_reference (&lease -> options, packet -> options, MDL);
1200
1201 lease -> address.len = sizeof (packet -> raw -> yiaddr);
1202 memcpy (lease -> address.iabuf, &packet -> raw -> yiaddr,
1203 lease -> address.len);
1204
1205 memset (&data, 0, sizeof data);
1206
1207 if (client -> config -> vendor_space_name) {
1208 i = DHO_VENDOR_ENCAPSULATED_OPTIONS;
1209
1210 /* See if there was a vendor encapsulation option. */
1211 oc = lookup_option (&dhcp_universe, lease -> options, i);
1212 if (oc &&
1213 client -> config -> vendor_space_name &&
1214 evaluate_option_cache (&data, packet,
1215 (struct lease *)0, client,
1216 packet -> options, lease -> options,
1217 &global_scope, oc, MDL)) {
1218 if (data.len) {
1219 parse_encapsulated_suboptions
1220 (packet -> options, &dhcp_options [i],
1221 data.data, data.len, &dhcp_universe,
1222 client -> config -> vendor_space_name
1223 );
1224 }
1225 data_string_forget (&data, MDL);
1226 }
1227 } else
1228 i = 0;
1229
1230 /* Figure out the overload flag. */
1231 oc = lookup_option (&dhcp_universe, lease -> options,
1232 DHO_DHCP_OPTION_OVERLOAD);
1233 if (oc &&
1234 evaluate_option_cache (&data, packet, (struct lease *)0, client,
1235 packet -> options, lease -> options,
1236 &global_scope, oc, MDL)) {
1237 if (data.len > 0)
1238 i = data.data [0];
1239 else
1240 i = 0;
1241 data_string_forget (&data, MDL);
1242 } else
1243 i = 0;
1244
1245 /* If the server name was filled out, copy it. */
1246 if (!(i & 2) && packet -> raw -> sname [0]) {
1247 unsigned len;
1248 /* Don't count on the NUL terminator. */
1249 for (len = 0; len < 64; len++)
1250 if (!packet -> raw -> sname [len])
1251 break;
1252 lease -> server_name = dmalloc (len + 1, MDL);
1253 if (!lease -> server_name) {
1254 log_error ("dhcpoffer: no memory for server name.\n");
1255 destroy_client_lease (lease);
1256 return (struct client_lease *)0;
1257 } else {
1258 memcpy (lease -> server_name,
1259 packet -> raw -> sname, len);
1260 lease -> server_name [len] = 0;
1261 }
1262 }
1263
1264 /* Ditto for the filename. */
1265 if (!(i & 1) && packet -> raw -> file [0]) {
1266 unsigned len;
1267 /* Don't count on the NUL terminator. */
1268 for (len = 0; len < 64; len++)
1269 if (!packet -> raw -> file [len])
1270 break;
1271 lease -> filename = dmalloc (len + 1, MDL);
1272 if (!lease -> filename) {
1273 log_error ("dhcpoffer: no memory for filename.\n");
1274 destroy_client_lease (lease);
1275 return (struct client_lease *)0;
1276 } else {
1277 memcpy (lease -> filename,
1278 packet -> raw -> file, len);
1279 lease -> filename [len] = 0;
1280 }
1281 }
1282
1283 execute_statements_in_scope ((struct binding_value **)0,
1284 (struct packet *)packet,
1285 (struct lease *)0, client,
1286 lease -> options, lease -> options,
1287 &global_scope,
1288 client -> config -> on_receipt,
1289 (struct group *)0);
1290
1291 return lease;
1292 }
1293
1294 void dhcpnak (packet)
1295 struct packet *packet;
1296 {
1297 struct interface_info *ip = packet -> interface;
1298 struct client_state *client;
1299
1300 /* Find a client state that matches the xid... */
1301 for (client = ip -> client; client; client = client -> next)
1302 if (client -> xid == packet -> raw -> xid)
1303 break;
1304
1305 /* If we're not receptive to an offer right now, or if the offer
1306 has an unrecognizable transaction id, then just drop it. */
1307 if (!client ||
1308 (packet -> interface -> hw_address.hlen - 1 !=
1309 packet -> raw -> hlen) ||
1310 (memcmp (&packet -> interface -> hw_address.hbuf [1],
1311 packet -> raw -> chaddr, packet -> raw -> hlen))) {
1312 #if defined (DEBUG)
1313 log_debug ("DHCPNAK in wrong transaction.");
1314 #endif
1315 return;
1316 }
1317
1318 if (client -> state != S_REBOOTING &&
1319 client -> state != S_REQUESTING &&
1320 client -> state != S_RENEWING &&
1321 client -> state != S_REBINDING) {
1322 #if defined (DEBUG)
1323 log_debug ("DHCPNAK in wrong state.");
1324 #endif
1325 return;
1326 }
1327
1328 log_info ("DHCPNAK from %s", piaddr (packet -> client_addr));
1329
1330 if (!client -> active) {
1331 #if defined (DEBUG)
1332 log_info ("DHCPNAK with no active lease.\n");
1333 #endif
1334 return;
1335 }
1336
1337 destroy_client_lease (client -> active);
1338 client -> active = (struct client_lease *)0;
1339
1340 /* Stop sending DHCPREQUEST packets... */
1341 cancel_timeout (send_request, client);
1342
1343 client -> state = S_INIT;
1344 state_init (client);
1345 }
1346
1347 /* Send out a DHCPDISCOVER packet, and set a timeout to send out another
1348 one after the right interval has expired. If we don't get an offer by
1349 the time we reach the panic interval, call the panic function. */
1350
1351 void send_discover (cpp)
1352 void *cpp;
1353 {
1354 struct client_state *client = cpp;
1355
1356 int result;
1357 int interval;
1358 int increase = 1;
1359
1360 /* Figure out how long it's been since we started transmitting. */
1361 interval = cur_time - client -> first_sending;
1362
1363 /* If we're past the panic timeout, call the script and tell it
1364 we haven't found anything for this interface yet. */
1365 if (interval > client -> config -> timeout) {
1366 state_panic (client);
1367 return;
1368 }
1369
1370 /* If we're selecting media, try the whole list before doing
1371 the exponential backoff, but if we've already received an
1372 offer, stop looping, because we obviously have it right. */
1373 if (!client -> offered_leases &&
1374 client -> config -> media) {
1375 int fail = 0;
1376 again:
1377 if (client -> medium) {
1378 client -> medium = client -> medium -> next;
1379 increase = 0;
1380 }
1381 if (!client -> medium) {
1382 if (fail)
1383 log_fatal ("No valid media types for %s!",
1384 client -> interface -> name);
1385 client -> medium =
1386 client -> config -> media;
1387 increase = 1;
1388 }
1389
1390 log_info ("Trying medium \"%s\" %d",
1391 client -> medium -> string, increase);
1392 script_init (client, "MEDIUM", client -> medium);
1393 if (script_go (client)) {
1394 fail = 1;
1395 goto again;
1396 }
1397 }
1398
1399 /* If we're supposed to increase the interval, do so. If it's
1400 currently zero (i.e., we haven't sent any packets yet), set
1401 it to initial_interval; otherwise, add to it a random number
1402 between zero and two times itself. On average, this means
1403 that it will double with every transmission. */
1404 if (increase) {
1405 if (!client->interval)
1406 client->interval = client->config->initial_interval;
1407 else
1408 client->interval += random() % (2 * client->interval);
1409
1410 /* Don't backoff past cutoff. */
1411 if (client->interval > client->config->backoff_cutoff)
1412 client->interval = (client->config->backoff_cutoff / 2)
1413 + (random() % client->config->backoff_cutoff);
1414 } else if (!client->interval)
1415 client->interval = client->config->initial_interval;
1416
1417 /* If the backoff would take us to the panic timeout, just use that
1418 as the interval. */
1419 if (cur_time + client -> interval >
1420 client -> first_sending + client -> config -> timeout)
1421 client -> interval =
1422 (client -> first_sending +
1423 client -> config -> timeout) - cur_time + 1;
1424
1425 /* Record the number of seconds since we started sending. */
1426 if (interval < 65536)
1427 client -> packet.secs = htons (interval);
1428 else
1429 client -> packet.secs = htons (65535);
1430 client -> secs = client -> packet.secs;
1431
1432 log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",
1433 client -> name ? client -> name : client -> interface -> name,
1434 inet_ntoa (sockaddr_broadcast.sin_addr),
1435 ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval));
1436
1437 /* Send out a packet. */
1438 result = send_packet (client -> interface, (struct packet *)0,
1439 &client -> packet,
1440 client -> packet_length,
1441 inaddr_any, &sockaddr_broadcast,
1442 (struct hardware *)0);
1443
1444 add_timeout (cur_time + client -> interval,
1445 send_discover, client, 0, 0);
1446 }
1447
1448 /* state_panic gets called if we haven't received any offers in a preset
1449 amount of time. When this happens, we try to use existing leases that
1450 haven't yet expired, and failing that, we call the client script and
1451 hope it can do something. */
1452
1453 void state_panic (cpp)
1454 void *cpp;
1455 {
1456 struct client_state *client = cpp;
1457 struct client_lease *loop;
1458 struct client_lease *lp;
1459
1460 loop = lp = client -> active;
1461
1462 log_info ("No DHCPOFFERS received.");
1463
1464 /* We may not have an active lease, but we may have some
1465 predefined leases that we can try. */
1466 if (!client -> active && client -> leases)
1467 goto activate_next;
1468
1469 /* Run through the list of leases and see if one can be used. */
1470 while (client -> active) {
1471 if (client -> active -> expiry > cur_time) {
1472 log_info ("Trying recorded lease %s",
1473 piaddr (client -> active -> address));
1474 /* Run the client script with the existing
1475 parameters. */
1476 script_init (client, "TIMEOUT",
1477 client -> active -> medium);
1478 script_write_params (client, "new_", client -> active);
1479 if (client -> alias)
1480 script_write_params (client, "alias_",
1481 client -> alias);
1482
1483 /* If the old lease is still good and doesn't
1484 yet need renewal, go into BOUND state and
1485 timeout at the renewal time. */
1486 if (!script_go (client)) {
1487 if (cur_time < client -> active -> renewal) {
1488 client -> state = S_BOUND;
1489 log_info ("bound: renewal in %ld %s.",
1490 (long)(client -> active -> renewal -
1491 cur_time), "seconds");
1492 add_timeout (client -> active -> renewal,
1493 state_bound, client, 0, 0);
1494 } else {
1495 client -> state = S_BOUND;
1496 log_info ("bound: immediate renewal.");
1497 state_bound (client);
1498 }
1499 reinitialize_interfaces ();
1500 go_daemon ();
1501 return;
1502 }
1503 }
1504
1505 /* If there are no other leases, give up. */
1506 if (!client -> leases) {
1507 client -> leases = client -> active;
1508 client -> active = (struct client_lease *)0;
1509 break;
1510 }
1511
1512 activate_next:
1513 /* Otherwise, put the active lease at the end of the
1514 lease list, and try another lease.. */
1515 for (lp = client -> leases; lp -> next; lp = lp -> next)
1516 ;
1517 lp -> next = client -> active;
1518 if (lp -> next) {
1519 lp -> next -> next = (struct client_lease *)0;
1520 }
1521 client -> active = client -> leases;
1522 client -> leases = client -> leases -> next;
1523
1524 /* If we already tried this lease, we've exhausted the
1525 set of leases, so we might as well give up for
1526 now. */
1527 if (client -> active == loop)
1528 break;
1529 else if (!loop)
1530 loop = client -> active;
1531 }
1532
1533 /* No leases were available, or what was available didn't work, so
1534 tell the shell script that we failed to allocate an address,
1535 and try again later. */
1536 if (onetry) {
1537 if (!quiet)
1538 log_info ("Unable to obtain a lease on first try.%s",
1539 " Exiting.");
1540 exit (2);
1541 }
1542
1543 log_info ("No working leases in persistent database - sleeping.");
1544 script_init (client, "FAIL", (struct string_list *)0);
1545 if (client -> alias)
1546 script_write_params (client, "alias_", client -> alias);
1547 script_go (client);
1548 client -> state = S_INIT;
1549 add_timeout (cur_time +
1550 ((client -> config -> retry_interval + 1) / 2 +
1551 (random () % client -> config -> retry_interval)),
1552 state_init, client, 0, 0);
1553 go_daemon ();
1554 }
1555
1556 void send_request (cpp)
1557 void *cpp;
1558 {
1559 struct client_state *client = cpp;
1560
1561 int result;
1562 int interval;
1563 struct sockaddr_in destination;
1564 struct in_addr from;
1565
1566 /* Figure out how long it's been since we started transmitting. */
1567 interval = cur_time - client -> first_sending;
1568
1569 /* If we're in the INIT-REBOOT or REQUESTING state and we're
1570 past the reboot timeout, go to INIT and see if we can
1571 DISCOVER an address... */
1572 /* XXX In the INIT-REBOOT state, if we don't get an ACK, it
1573 means either that we're on a network with no DHCP server,
1574 or that our server is down. In the latter case, assuming
1575 that there is a backup DHCP server, DHCPDISCOVER will get
1576 us a new address, but we could also have successfully
1577 reused our old address. In the former case, we're hosed
1578 anyway. This is not a win-prone situation. */
1579 if ((client -> state == S_REBOOTING ||
1580 client -> state == S_REQUESTING) &&
1581 interval > client -> config -> reboot_timeout) {
1582 cancel:
1583 client -> state = S_INIT;
1584 cancel_timeout (send_request, client);
1585 state_init (client);
1586 return;
1587 }
1588
1589 /* If we're in the reboot state, make sure the media is set up
1590 correctly. */
1591 if (client -> state == S_REBOOTING &&
1592 !client -> medium &&
1593 client -> active -> medium ) {
1594 script_init (client, "MEDIUM", client -> active -> medium);
1595
1596 /* If the medium we chose won't fly, go to INIT state. */
1597 if (script_go (client))
1598 goto cancel;
1599
1600 /* Record the medium. */
1601 client -> medium = client -> active -> medium;
1602 }
1603
1604 /* If the lease has expired, relinquish the address and go back
1605 to the INIT state. */
1606 if (client -> state != S_REQUESTING &&
1607 cur_time > client -> active -> expiry) {
1608 /* Run the client script with the new parameters. */
1609 script_init (client, "EXPIRE", (struct string_list *)0);
1610 script_write_params (client, "old_", client -> active);
1611 if (client -> alias)
1612 script_write_params (client, "alias_",
1613 client -> alias);
1614 script_go (client);
1615
1616 /* Now do a preinit on the interface so that we can
1617 discover a new address. */
1618 script_init (client, "PREINIT", (struct string_list *)0);
1619 if (client -> alias)
1620 script_write_params (client, "alias_",
1621 client -> alias);
1622 script_go (client);
1623
1624 client -> state = S_INIT;
1625 state_init (client);
1626 return;
1627 }
1628
1629 /* Do the exponential backoff... */
1630 if (!client -> interval)
1631 client -> interval = client -> config -> initial_interval;
1632 else {
1633 client -> interval += ((random () >> 2) %
1634 (2 * client -> interval));
1635 }
1636
1637 /* Don't backoff past cutoff. */
1638 if (client -> interval >
1639 client -> config -> backoff_cutoff)
1640 client -> interval =
1641 ((client -> config -> backoff_cutoff / 2)
1642 + ((random () >> 2) %
1643 client -> config -> backoff_cutoff));
1644
1645 /* If the backoff would take us to the expiry time, just set the
1646 timeout to the expiry time. */
1647 if (client -> state != S_REQUESTING &&
1648 cur_time + client -> interval > client -> active -> expiry)
1649 client -> interval =
1650 client -> active -> expiry - cur_time + 1;
1651
1652 /* If the lease T2 time has elapsed, or if we're not yet bound,
1653 broadcast the DHCPREQUEST rather than unicasting. */
1654 if (client -> state == S_REQUESTING ||
1655 client -> state == S_REBOOTING ||
1656 cur_time > client -> active -> rebind)
1657 destination.sin_addr = sockaddr_broadcast.sin_addr;
1658 else
1659 memcpy (&destination.sin_addr.s_addr,
1660 client -> destination.iabuf,
1661 sizeof destination.sin_addr.s_addr);
1662 destination.sin_port = remote_port;
1663 destination.sin_family = AF_INET;
1664 #ifdef HAVE_SA_LEN
1665 destination.sin_len = sizeof destination;
1666 #endif
1667
1668 if (client -> state == S_RENEWING ||
1669 client -> state == S_REBINDING)
1670 memcpy (&from, client -> active -> address.iabuf,
1671 sizeof from);
1672 else
1673 from.s_addr = INADDR_ANY;
1674
1675 /* Record the number of seconds since we started sending. */
1676 if (client -> state == S_REQUESTING)
1677 client -> packet.secs = client -> secs;
1678 else {
1679 if (interval < 65536)
1680 client -> packet.secs = htons (interval);
1681 else
1682 client -> packet.secs = htons (65535);
1683 }
1684
1685 log_info ("DHCPREQUEST on %s to %s port %d",
1686 client -> name ? client -> name : client -> interface -> name,
1687 inet_ntoa (destination.sin_addr),
1688 ntohs (destination.sin_port));
1689
1690 if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
1691 fallback_interface)
1692 result = send_packet (fallback_interface,
1693 (struct packet *)0,
1694 &client -> packet,
1695 client -> packet_length,
1696 from, &destination,
1697 (struct hardware *)0);
1698 else
1699 /* Send out a packet. */
1700 result = send_packet (client -> interface, (struct packet *)0,
1701 &client -> packet,
1702 client -> packet_length,
1703 from, &destination,
1704 (struct hardware *)0);
1705
1706 add_timeout (cur_time + client -> interval,
1707 send_request, client, 0, 0);
1708 }
1709
1710 void send_decline (cpp)
1711 void *cpp;
1712 {
1713 struct client_state *client = cpp;
1714
1715 int result;
1716
1717 log_info ("DHCPDECLINE on %s to %s port %d",
1718 client -> name ? client -> name : client -> interface -> name,
1719 inet_ntoa (sockaddr_broadcast.sin_addr),
1720 ntohs (sockaddr_broadcast.sin_port));
1721
1722 /* Send out a packet. */
1723 result = send_packet (client -> interface, (struct packet *)0,
1724 &client -> packet,
1725 client -> packet_length,
1726 inaddr_any, &sockaddr_broadcast,
1727 (struct hardware *)0);
1728 }
1729
1730 void send_release (cpp)
1731 void *cpp;
1732 {
1733 struct client_state *client = cpp;
1734
1735 int result;
1736 struct sockaddr_in destination;
1737 struct in_addr from;
1738
1739 memcpy (&from, client -> active -> address.iabuf,
1740 sizeof from);
1741 memcpy (&destination.sin_addr.s_addr,
1742 client -> destination.iabuf,
1743 sizeof destination.sin_addr.s_addr);
1744 destination.sin_port = remote_port;
1745 destination.sin_family = AF_INET;
1746 #ifdef HAVE_SA_LEN
1747 destination.sin_len = sizeof destination;
1748 #endif
1749
1750 /* Set the lease to end now, so that we don't accidentally
1751 reuse it if we restart before the old expiry time. */
1752 client -> active -> expiry =
1753 client -> active -> renewal =
1754 client -> active -> rebind = cur_time;
1755 if (!write_client_lease (client, client -> active, 1, 1)) {
1756 log_error ("Can't release lease: lease write failed.");
1757 return;
1758 }
1759
1760 log_info ("DHCPRELEASE on %s to %s port %d",
1761 client -> name ? client -> name : client -> interface -> name,
1762 inet_ntoa (destination.sin_addr),
1763 ntohs (destination.sin_port));
1764
1765 if (fallback_interface)
1766 result = send_packet (fallback_interface,
1767 (struct packet *)0,
1768 &client -> packet,
1769 client -> packet_length,
1770 from, &destination,
1771 (struct hardware *)0);
1772 else
1773 /* Send out a packet. */
1774 result = send_packet (client -> interface, (struct packet *)0,
1775 &client -> packet,
1776 client -> packet_length,
1777 from, &destination,
1778 (struct hardware *)0);
1779 }
1780
1781 void make_client_options (client, lease, type, sid, rip, prl, op)
1782 struct client_state *client;
1783 struct client_lease *lease;
1784 u_int8_t *type;
1785 struct option_cache *sid;
1786 struct iaddr *rip;
1787 u_int32_t *prl;
1788 struct option_state **op;
1789 {
1790 unsigned i;
1791 struct option_cache *oc;
1792 struct buffer *bp = (struct buffer *)0;
1793
1794 /* If there are any leftover options, get rid of them. */
1795 if (*op)
1796 option_state_dereference (op, MDL);
1797
1798 /* Allocate space for options. */
1799 option_state_allocate (op, MDL);
1800
1801 /* Send the server identifier if provided. */
1802 if (sid)
1803 save_option (&dhcp_universe, *op, sid);
1804
1805 oc = (struct option_cache *)0;
1806
1807 /* Send the requested address if provided. */
1808 if (rip) {
1809 client -> requested_address = *rip;
1810 if (!(make_const_option_cache
1811 (&oc, (struct buffer **)0, rip -> iabuf, rip -> len,
1812 &dhcp_options [DHO_DHCP_REQUESTED_ADDRESS], MDL)))
1813 log_error ("can't make requested address cache.");
1814 else {
1815 save_option (&dhcp_universe, *op, oc);
1816 option_cache_dereference (&oc, MDL);
1817 }
1818 } else {
1819 client -> requested_address.len = 0;
1820 }
1821
1822 if (!(make_const_option_cache
1823 (&oc, (struct buffer **)0,
1824 type, 1, &dhcp_options [DHO_DHCP_MESSAGE_TYPE], MDL)))
1825 log_error ("can't make message type.");
1826 else {
1827 save_option (&dhcp_universe, *op, oc);
1828 option_cache_dereference (&oc, MDL);
1829 }
1830
1831 if (prl) {
1832 /* Figure out how many parameters were requested. */
1833 for (i = 0; prl [i]; i++)
1834 ;
1835 if (!buffer_allocate (&bp, i, MDL))
1836 log_error ("can't make parameter list buffer.");
1837 else {
1838 for (i = 0; prl [i]; i++)
1839 bp -> data [i] = prl [i];
1840 if (!(make_const_option_cache
1841 (&oc, &bp, (u_int8_t *)0, i,
1842 &dhcp_options [DHO_DHCP_PARAMETER_REQUEST_LIST],
1843 MDL)))
1844 log_error ("can't make option cache");
1845 else {
1846 save_option (&dhcp_universe, *op, oc);
1847 option_cache_dereference (&oc, MDL);
1848 }
1849 }
1850 }
1851
1852 /* Run statements that need to be run on transmission. */
1853 if (client -> config -> on_transmission)
1854 execute_statements_in_scope
1855 ((struct binding_value **)0,
1856 (struct packet *)0, (struct lease *)0, client,
1857 (lease ? lease -> options : (struct option_state *)0),
1858 *op, &global_scope,
1859 client -> config -> on_transmission,
1860 (struct group *)0);
1861 }
1862
1863 void make_discover (client, lease)
1864 struct client_state *client;
1865 struct client_lease *lease;
1866 {
1867 unsigned char discover = DHCPDISCOVER;
1868 int i;
1869 struct option_state *options = (struct option_state *)0;
1870
1871 memset (&client -> packet, 0, sizeof (client -> packet));
1872
1873 make_client_options (client,
1874 lease, &discover, (struct option_cache *)0,
1875 lease ? &lease -> address : (struct iaddr *)0,
1876 client -> config -> requested_options,
1877 &options);
1878
1879 /* Set up the option buffer... */
1880 client -> packet_length =
1881 cons_options ((struct packet *)0, &client -> packet,
1882 (struct lease *)0, client,
1883 /* maximum packet size */1500,
1884 (struct option_state *)0,
1885 options,
1886 /* scope */ &global_scope,
1887 /* overload */ 0,
1888 /* terminate */0,
1889 /* bootpp */0,
1890 (struct data_string *)0,
1891 client -> config -> vendor_space_name);
1892
1893 option_state_dereference (&options, MDL);
1894 if (client -> packet_length < BOOTP_MIN_LEN)
1895 client -> packet_length = BOOTP_MIN_LEN;
1896
1897 client -> packet.op = BOOTREQUEST;
1898 client -> packet.htype = client -> interface -> hw_address.hbuf [0];
1899 client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
1900 client -> packet.hops = 0;
1901 client -> packet.xid = random ();
1902 client -> packet.secs = 0; /* filled in by send_discover. */
1903
1904 if (can_receive_unicast_unconfigured (client -> interface))
1905 client -> packet.flags = 0;
1906 else
1907 client -> packet.flags = htons (BOOTP_BROADCAST);
1908
1909 memset (&(client -> packet.ciaddr),
1910 0, sizeof client -> packet.ciaddr);
1911 memset (&(client -> packet.yiaddr),
1912 0, sizeof client -> packet.yiaddr);
1913 memset (&(client -> packet.siaddr),
1914 0, sizeof client -> packet.siaddr);
1915 client -> packet.giaddr = giaddr;
1916 if (client -> interface -> hw_address.hlen > 0)
1917 memcpy (client -> packet.chaddr,
1918 &client -> interface -> hw_address.hbuf [1],
1919 (unsigned)(client -> interface -> hw_address.hlen - 1));
1920
1921 #ifdef DEBUG_PACKET
1922 dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
1923 #endif
1924 }
1925
1926
1927 void make_request (client, lease)
1928 struct client_state *client;
1929 struct client_lease *lease;
1930 {
1931 unsigned char request = DHCPREQUEST;
1932 int i, j;
1933 unsigned char *tmp, *digest;
1934 unsigned char *old_digest_loc;
1935 struct option_cache *oc;
1936
1937 memset (&client -> packet, 0, sizeof (client -> packet));
1938
1939 if (client -> state == S_REQUESTING)
1940 oc = lookup_option (&dhcp_universe, lease -> options,
1941 DHO_DHCP_SERVER_IDENTIFIER);
1942 else
1943 oc = (struct option_cache *)0;
1944
1945 if (client -> sent_options)
1946 option_state_dereference (&client -> sent_options, MDL);
1947
1948 make_client_options (client, lease, &request, oc,
1949 ((client -> state == S_REQUESTING ||
1950 client -> state == S_REBOOTING)
1951 ? &lease -> address
1952 : (struct iaddr *)0),
1953 client -> config -> requested_options,
1954 &client -> sent_options);
1955
1956 /* Set up the option buffer... */
1957 client -> packet_length =
1958 cons_options ((struct packet *)0, &client -> packet,
1959 (struct lease *)0, client,
1960 /* maximum packet size */1500,
1961 (struct option_state *)0,
1962 client -> sent_options,
1963 /* scope */ &global_scope,
1964 /* overload */ 0,
1965 /* terminate */0,
1966 /* bootpp */0,
1967 (struct data_string *)0,
1968 client -> config -> vendor_space_name);
1969
1970 if (client -> packet_length < BOOTP_MIN_LEN)
1971 client -> packet_length = BOOTP_MIN_LEN;
1972
1973 client -> packet.op = BOOTREQUEST;
1974 client -> packet.htype = client -> interface -> hw_address.hbuf [0];
1975 client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
1976 client -> packet.hops = 0;
1977 client -> packet.xid = client -> xid;
1978 client -> packet.secs = 0; /* Filled in by send_request. */
1979
1980 /* If we own the address we're requesting, put it in ciaddr;
1981 otherwise set ciaddr to zero. */
1982 if (client -> state == S_BOUND ||
1983 client -> state == S_RENEWING ||
1984 client -> state == S_REBINDING) {
1985 memcpy (&client -> packet.ciaddr,
1986 lease -> address.iabuf, lease -> address.len);
1987 client -> packet.flags = 0;
1988 } else {
1989 memset (&client -> packet.ciaddr, 0,
1990 sizeof client -> packet.ciaddr);
1991 if (can_receive_unicast_unconfigured (client -> interface))
1992 client -> packet.flags = 0;
1993 else
1994 client -> packet.flags = htons (BOOTP_BROADCAST);
1995 }
1996
1997 memset (&client -> packet.yiaddr, 0,
1998 sizeof client -> packet.yiaddr);
1999 memset (&client -> packet.siaddr, 0,
2000 sizeof client -> packet.siaddr);
2001 if (client -> state != S_BOUND &&
2002 client -> state != S_RENEWING)
2003 client -> packet.giaddr = giaddr;
2004 else
2005 memset (&client -> packet.giaddr, 0,
2006 sizeof client -> packet.giaddr);
2007 if (client -> interface -> hw_address.hlen > 0)
2008 memcpy (client -> packet.chaddr,
2009 &client -> interface -> hw_address.hbuf [1],
2010 (unsigned)(client -> interface -> hw_address.hlen - 1));
2011
2012 #ifdef DEBUG_PACKET
2013 dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
2014 #endif
2015 }
2016
2017 void make_decline (client, lease)
2018 struct client_state *client;
2019 struct client_lease *lease;
2020 {
2021 unsigned char decline = DHCPDECLINE;
2022 int i;
2023 struct option_cache *oc;
2024
2025 struct option_state *options = (struct option_state *)0;
2026
2027 oc = lookup_option (&dhcp_universe, lease -> options,
2028 DHO_DHCP_SERVER_IDENTIFIER);
2029 make_client_options (client, lease, &decline, oc,
2030 &lease -> address, (u_int32_t *)0, &options);
2031
2032 /* Set up the option buffer... */
2033 memset (&client -> packet, 0, sizeof (client -> packet));
2034 client -> packet_length =
2035 cons_options ((struct packet *)0, &client -> packet,
2036 (struct lease *)0, client, 0,
2037 (struct option_state *)0, options,
2038 &global_scope, 0, 0, 0, (struct data_string *)0,
2039 client -> config -> vendor_space_name);
2040 option_state_dereference (&options, MDL);
2041 if (client -> packet_length < BOOTP_MIN_LEN)
2042 client -> packet_length = BOOTP_MIN_LEN;
2043 option_state_dereference (&options, MDL);
2044
2045 client -> packet.op = BOOTREQUEST;
2046 client -> packet.htype = client -> interface -> hw_address.hbuf [0];
2047 client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
2048 client -> packet.hops = 0;
2049 client -> packet.xid = client -> xid;
2050 client -> packet.secs = 0; /* Filled in by send_request. */
2051 if (can_receive_unicast_unconfigured (client -> interface))
2052 client -> packet.flags = 0;
2053 else
2054 client -> packet.flags = htons (BOOTP_BROADCAST);
2055
2056 /* ciaddr must always be zero. */
2057 memset (&client -> packet.ciaddr, 0,
2058 sizeof client -> packet.ciaddr);
2059 memset (&client -> packet.yiaddr, 0,
2060 sizeof client -> packet.yiaddr);
2061 memset (&client -> packet.siaddr, 0,
2062 sizeof client -> packet.siaddr);
2063 client -> packet.giaddr = giaddr;
2064 memcpy (client -> packet.chaddr,
2065 &client -> interface -> hw_address.hbuf [1],
2066 client -> interface -> hw_address.hlen);
2067
2068 #ifdef DEBUG_PACKET
2069 dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
2070 #endif
2071 }
2072
2073 void make_release (client, lease)
2074 struct client_state *client;
2075 struct client_lease *lease;
2076 {
2077 unsigned char request = DHCPRELEASE;
2078 int i;
2079 struct option_cache *oc;
2080
2081 struct option_state *options = (struct option_state *)0;
2082
2083 memset (&client -> packet, 0, sizeof (client -> packet));
2084
2085 oc = lookup_option (&dhcp_universe, lease -> options,
2086 DHO_DHCP_SERVER_IDENTIFIER);
2087 make_client_options (client, lease, &request, oc,
2088 (struct iaddr *)0, (u_int32_t *)0,
2089 &options);
2090
2091 /* Set up the option buffer... */
2092 client -> packet_length =
2093 cons_options ((struct packet *)0, &client -> packet,
2094 (struct lease *)0, client,
2095 /* maximum packet size */1500,
2096 (struct option_state *)0,
2097 options,
2098 /* scope */ &global_scope,
2099 /* overload */ 0,
2100 /* terminate */0,
2101 /* bootpp */0,
2102 (struct data_string *)0,
2103 client -> config -> vendor_space_name);
2104
2105 if (client -> packet_length < BOOTP_MIN_LEN)
2106 client -> packet_length = BOOTP_MIN_LEN;
2107 option_state_dereference (&options, MDL);
2108
2109 client -> packet.op = BOOTREQUEST;
2110 client -> packet.htype = client -> interface -> hw_address.hbuf [0];
2111 client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
2112 client -> packet.hops = 0;
2113 client -> packet.xid = random ();
2114 client -> packet.secs = 0;
2115 client -> packet.flags = 0;
2116 memcpy (&client -> packet.ciaddr,
2117 lease -> address.iabuf, lease -> address.len);
2118 memset (&client -> packet.yiaddr, 0,
2119 sizeof client -> packet.yiaddr);
2120 memset (&client -> packet.siaddr, 0,
2121 sizeof client -> packet.siaddr);
2122 client -> packet.giaddr = giaddr;
2123 memcpy (client -> packet.chaddr,
2124 &client -> interface -> hw_address.hbuf [1],
2125 client -> interface -> hw_address.hlen);
2126
2127 #ifdef DEBUG_PACKET
2128 dump_raw ((unsigned char *)&client -> packet, client -> packet_length);
2129 #endif
2130 }
2131
2132 void destroy_client_lease (lease)
2133 struct client_lease *lease;
2134 {
2135 int i;
2136
2137 if (lease -> server_name)
2138 dfree (lease -> server_name, MDL);
2139 if (lease -> filename)
2140 dfree (lease -> filename, MDL);
2141 option_state_dereference (&lease -> options, MDL);
2142 free_client_lease (lease, MDL);
2143 }
2144
2145 FILE *leaseFile;
2146
2147 void rewrite_client_leases ()
2148 {
2149 struct interface_info *ip;
2150 struct client_state *client;
2151 struct client_lease *lp;
2152
2153 if (leaseFile)
2154 fclose (leaseFile);
2155 leaseFile = fopen (path_dhclient_db, "w");
2156 if (!leaseFile) {
2157 log_error ("can't create %s: %m", path_dhclient_db);
2158 return;
2159 }
2160
2161 /* Write out all the leases attached to configured interfaces that
2162 we know about. */
2163 for (ip = interfaces; ip; ip = ip -> next) {
2164 for (client = ip -> client; client; client = client -> next) {
2165 for (lp = client -> leases; lp; lp = lp -> next) {
2166 write_client_lease (client, lp, 1, 0);
2167 }
2168 if (client -> active)
2169 write_client_lease (client,
2170 client -> active, 1, 0);
2171 }
2172 }
2173
2174 /* Write out any leases that are attached to interfaces that aren't
2175 currently configured. */
2176 for (ip = dummy_interfaces; ip; ip = ip -> next) {
2177 for (client = ip -> client; client; client = client -> next) {
2178 for (lp = client -> leases; lp; lp = lp -> next) {
2179 write_client_lease (client, lp, 1, 0);
2180 }
2181 if (client -> active)
2182 write_client_lease (client,
2183 client -> active, 1, 0);
2184 }
2185 }
2186 fflush (leaseFile);
2187 }
2188
2189 void write_lease_option (struct option_cache *oc,
2190 struct packet *packet, struct lease *lease,
2191 struct client_state *client_state,
2192 struct option_state *in_options,
2193 struct option_state *cfg_options,
2194 struct binding_scope **scope,
2195 struct universe *u, void *stuff)
2196 {
2197 const char *name, *dot;
2198 struct data_string ds;
2199 int status;
2200 struct client_state *client;
2201
2202 memset (&ds, 0, sizeof ds);
2203
2204 if (u != &dhcp_universe) {
2205 name = u -> name;
2206 dot = ".";
2207 } else {
2208 name = "";
2209 dot = "";
2210 }
2211 if (evaluate_option_cache (&ds, packet, lease, client_state,
2212 in_options, cfg_options, scope, oc, MDL)) {
2213 fprintf (leaseFile,
2214 " option %s%s%s %s;\n",
2215 name, dot, oc -> option -> name,
2216 pretty_print_option (oc -> option,
2217 ds.data, ds.len, 1, 1));
2218 data_string_forget (&ds, MDL);
2219 }
2220 }
2221
2222 int write_client_lease (client, lease, rewrite, makesure)
2223 struct client_state *client;
2224 struct client_lease *lease;
2225 int rewrite;
2226 int makesure;
2227 {
2228 int i;
2229 struct tm *t;
2230 static int leases_written;
2231 struct option_cache *oc;
2232 struct data_string ds;
2233 pair *hash;
2234 int errors = 0;
2235 char *s;
2236
2237 if (!rewrite) {
2238 if (leases_written++ > 20) {
2239 rewrite_client_leases ();
2240 leases_written = 0;
2241 }
2242 }
2243
2244 /* If the lease came from the config file, we don't need to stash
2245 a copy in the lease database. */
2246 if (lease -> is_static)
2247 return 1;
2248
2249 if (!leaseFile) { /* XXX */
2250 leaseFile = fopen (path_dhclient_db, "w");
2251 if (!leaseFile) {
2252 log_error ("can't create %s: %m", path_dhclient_db);
2253 return 0;
2254 }
2255 }
2256
2257 errno = 0;
2258 fprintf (leaseFile, "lease {\n");
2259 if (lease -> is_bootp) {
2260 fprintf (leaseFile, " bootp;\n");
2261 if (errno) {
2262 ++errors;
2263 errno = 0;
2264 }
2265 }
2266 fprintf (leaseFile, " interface \"%s\";\n",
2267 client -> interface -> name);
2268 if (errno) {
2269 ++errors;
2270 errno = 0;
2271 }
2272 if (client -> name) {
2273 fprintf (leaseFile, " name \"%s\";\n", client -> name);
2274 if (errno) {
2275 ++errors;
2276 errno = 0;
2277 }
2278 }
2279 fprintf (leaseFile, " fixed-address %s;\n",
2280 piaddr (lease -> address));
2281 if (errno) {
2282 ++errors;
2283 errno = 0;
2284 }
2285 if (lease -> filename) {
2286 s = quotify_string (lease -> filename, MDL);
2287 if (s) {
2288 fprintf (leaseFile, " filename \"%s\";\n", s);
2289 if (errno) {
2290 ++errors;
2291 errno = 0;
2292 }
2293 dfree (s, MDL);
2294 } else
2295 errors++;
2296
2297 }
2298 if (lease -> server_name) {
2299 s = quotify_string (lease -> filename, MDL);
2300 if (s) {
2301 fprintf (leaseFile, " server-name \"%s\";\n", s);
2302 if (errno) {
2303 ++errors;
2304 errno = 0;
2305 }
2306 dfree (s, MDL);
2307 } else
2308 ++errors;
2309 }
2310 if (lease -> medium) {
2311 s = quotify_string (lease -> medium -> string, MDL);
2312 if (s) {
2313 fprintf (leaseFile, " medium \"%s\";\n", s);
2314 if (errno) {
2315 ++errors;
2316 errno = 0;
2317 }
2318 dfree (s, MDL);
2319 } else
2320 errors++;
2321 }
2322 if (errno != 0) {
2323 errors++;
2324 errno = 0;
2325 }
2326
2327 memset (&ds, 0, sizeof ds);
2328
2329 for (i = 0; i < lease -> options -> universe_count; i++) {
2330 option_space_foreach ((struct packet *)0, (struct lease *)0,
2331 client, (struct option_state *)0,
2332 lease -> options, &global_scope,
2333 universes [i],
2334 client, write_lease_option);
2335 }
2336
2337 /* Note: the following is not a Y2K bug - it's a Y1.9K bug. Until
2338 somebody invents a time machine, I think we can safely disregard
2339 it. */
2340 t = gmtime (&lease -> renewal);
2341 fprintf (leaseFile,
2342 " renew %d %d/%d/%d %02d:%02d:%02d;\n",
2343 t -> tm_wday, t -> tm_year + 1900,
2344 t -> tm_mon + 1, t -> tm_mday,
2345 t -> tm_hour, t -> tm_min, t -> tm_sec);
2346 if (errno != 0) {
2347 errors++;
2348 errno = 0;
2349 }
2350 t = gmtime (&lease -> rebind);
2351 fprintf (leaseFile,
2352 " rebind %d %d/%d/%d %02d:%02d:%02d;\n",
2353 t -> tm_wday, t -> tm_year + 1900,
2354 t -> tm_mon + 1, t -> tm_mday,
2355 t -> tm_hour, t -> tm_min, t -> tm_sec);
2356 if (errno != 0) {
2357 errors++;
2358 errno = 0;
2359 }
2360 t = gmtime (&lease -> expiry);
2361 fprintf (leaseFile,
2362 " expire %d %d/%d/%d %02d:%02d:%02d;\n",
2363 t -> tm_wday, t -> tm_year + 1900,
2364 t -> tm_mon + 1, t -> tm_mday,
2365 t -> tm_hour, t -> tm_min, t -> tm_sec);
2366 if (errno != 0) {
2367 errors++;
2368 errno = 0;
2369 }
2370 fprintf (leaseFile, "}\n");
2371 if (errno != 0) {
2372 errors++;
2373 errno = 0;
2374 }
2375 fflush (leaseFile);
2376 if (errno != 0) {
2377 errors++;
2378 errno = 0;
2379 }
2380 if (!errors && makesure) {
2381 if (fsync (fileno (leaseFile)) < 0) {
2382 log_info ("write_client_lease: %m");
2383 return 0;
2384 }
2385 }
2386 return errors ? 0 : 1;
2387 }
2388
2389 /* Variables holding name of script and file pointer for writing to
2390 script. Needless to say, this is not reentrant - only one script
2391 can be invoked at a time. */
2392 char scriptName [256];
2393 FILE *scriptFile;
2394
2395 void script_init (client, reason, medium)
2396 struct client_state *client;
2397 const char *reason;
2398 struct string_list *medium;
2399 {
2400 struct string_list *sl, *next;
2401
2402 if (client) {
2403 for (sl = client -> env; sl; sl = next) {
2404 next = sl -> next;
2405 dfree (sl, MDL);
2406 }
2407 client -> env = (struct string_list *)0;
2408 client -> envc = 0;
2409
2410 if (client -> interface) {
2411 client_envadd (client, "", "interface", "%s",
2412 client -> interface -> name);
2413 }
2414 if (client -> name)
2415 client_envadd (client,
2416 "", "client", "%s", client -> name);
2417 if (medium)
2418 client_envadd (client,
2419 "", "medium", "%s", medium -> string);
2420
2421 client_envadd (client, "", "reason", "%s", reason);
2422 client_envadd (client, "", "pid", "%ld", (long int)getpid ());
2423 }
2424 }
2425
2426 struct envadd_state {
2427 struct client_state *client;
2428 const char *prefix;
2429 };
2430
2431 void client_option_envadd (struct option_cache *oc,
2432 struct packet *packet, struct lease *lease,
2433 struct client_state *client_state,
2434 struct option_state *in_options,
2435 struct option_state *cfg_options,
2436 struct binding_scope **scope,
2437 struct universe *u, void *stuff)
2438 {
2439 struct envadd_state *es = stuff;
2440 struct data_string data;
2441 memset (&data, 0, sizeof data);
2442
2443 if (evaluate_option_cache (&data, packet, lease, client_state,
2444 in_options, cfg_options, scope, oc, MDL)) {
2445 if (data.len) {
2446 char name [256];
2447 if (dhcp_option_ev_name (name, sizeof name,
2448 oc -> option)) {
2449 client_envadd (es -> client, es -> prefix,
2450 name, "%s",
2451 (pretty_print_option
2452 (oc -> option,
2453 data.data, data.len,
2454 0, 0)));
2455 data_string_forget (&data, MDL);
2456 }
2457 }
2458 }
2459 }
2460
2461 void script_write_params (client, prefix, lease)
2462 struct client_state *client;
2463 const char *prefix;
2464 struct client_lease *lease;
2465 {
2466 int i;
2467 struct data_string data;
2468 struct option_cache *oc;
2469 pair *hash;
2470 char *s, *t;
2471 struct envadd_state es;
2472
2473 es.client = client;
2474 es.prefix = prefix;
2475
2476 client_envadd (client,
2477 prefix, "ip_address", "%s", piaddr (lease -> address));
2478
2479 /* For the benefit of Linux (and operating systems which may
2480 have similar needs), compute the network address based on
2481 the supplied ip address and netmask, if provided. Also
2482 compute the broadcast address (the host address all ones
2483 broadcast address, not the host address all zeroes
2484 broadcast address). */
2485
2486 memset (&data, 0, sizeof data);
2487 oc = lookup_option (&dhcp_universe, lease -> options, DHO_SUBNET_MASK);
2488 if (oc && evaluate_option_cache (&data, (struct packet *)0,
2489 (struct lease *)0, client,
2490 (struct option_state *)0,
2491 lease -> options,
2492 &global_scope, oc, MDL)) {
2493 if (data.len > 3) {
2494 struct iaddr netmask, subnet, broadcast;
2495
2496 memcpy (netmask.iabuf, data.data, data.len);
2497 netmask.len = data.len;
2498 data_string_forget (&data, MDL);
2499
2500 subnet = subnet_number (lease -> address, netmask);
2501 if (subnet.len) {
2502 client_envadd (client, prefix, "network_number",
2503 "%s", piaddr (subnet));
2504
2505 oc = lookup_option (&dhcp_universe,
2506 lease -> options,
2507 DHO_BROADCAST_ADDRESS);
2508 if (!oc ||
2509 !(evaluate_option_cache
2510 (&data, (struct packet *)0,
2511 (struct lease *)0, client,
2512 (struct option_state *)0,
2513 lease -> options,
2514 &global_scope, oc, MDL))) {
2515 broadcast = broadcast_addr (subnet, netmask);
2516 if (broadcast.len) {
2517 client_envadd (client,
2518 prefix, "broadcast_address",
2519 "%s", piaddr (broadcast));
2520 }
2521 }
2522 }
2523 }
2524 data_string_forget (&data, MDL);
2525 }
2526
2527 if (lease -> filename)
2528 client_envadd (client,
2529 prefix, "filename", "%s", lease -> filename);
2530 if (lease -> server_name)
2531 client_envadd (client, prefix, "server_name",
2532 "%s", lease -> server_name);
2533
2534 for (i = 0; i < lease -> options -> universe_count; i++) {
2535 option_space_foreach ((struct packet *)0, (struct lease *)0,
2536 client, (struct option_state *)0,
2537 lease -> options, &global_scope,
2538 universes [i],
2539 &es, client_option_envadd);
2540 }
2541 client_envadd (client, prefix, "expiry", "%d", (int)(lease -> expiry));
2542 }
2543
2544 int script_go (client)
2545 struct client_state *client;
2546 {
2547 int rval;
2548 char *scriptName;
2549 char *argv [2];
2550 char **envp;
2551 char *epp [3];
2552 char reason [] = "REASON=NBI";
2553 static char client_path [] = CLIENT_PATH;
2554 int i;
2555 struct string_list *sp, *next;
2556 int pid, wpid, wstatus;
2557
2558 if (client)
2559 scriptName = client -> config -> script_name;
2560 else
2561 scriptName = top_level_config.script_name;
2562
2563 envp = dmalloc (((client ? client -> envc : 2) +
2564 client_env_count + 2) * sizeof (char *), MDL);
2565 if (!envp) {
2566 log_error ("No memory for client script environment.");
2567 return 0;
2568 }
2569 i = 0;
2570 /* Copy out the environment specified on the command line,
2571 if any. */
2572 for (sp = client_env; sp; sp = sp -> next) {
2573 envp [i++] = sp -> string;
2574 }
2575 /* Copy out the environment specified by dhclient. */
2576 if (client) {
2577 for (sp = client -> env; sp; sp = sp -> next) {
2578 envp [i++] = sp -> string;
2579 }
2580 } else {
2581 envp [i++] = reason;
2582 }
2583 /* Set $PATH. */
2584 envp [i++] = client_path;
2585 envp [i] = (char *)0;
2586
2587 argv [0] = scriptName;
2588 argv [1] = (char *)0;
2589
2590 pid = fork ();
2591 if (pid < 0) {
2592 log_error ("fork: %m");
2593 wstatus = 0;
2594 } else if (pid) {
2595 do {
2596 wpid = wait (&wstatus);
2597 } while (wpid != pid && wpid > 0);
2598 if (wpid < 0) {
2599 log_error ("wait: %m");
2600 wstatus = 0;
2601 }
2602 } else {
2603 execve (scriptName, argv, envp);
2604 log_error ("execve (%s, ...): %m", scriptName);
2605 exit (0);
2606 }
2607
2608 if (client) {
2609 for (sp = client -> env; sp; sp = next) {
2610 next = sp -> next;
2611 dfree (sp, MDL);
2612 }
2613 client -> env = (struct string_list *)0;
2614 client -> envc = 0;
2615 }
2616 dfree (envp, MDL);
2617 GET_TIME (&cur_time);
2618 return (WIFEXITED (wstatus) ?
2619 WEXITSTATUS (wstatus) : -WTERMSIG (wstatus));
2620 }
2621
2622 void client_envadd (struct client_state *client,
2623 const char *prefix, const char *name, const char *fmt, ...)
2624 {
2625 char spbuf [1024];
2626 char *s;
2627 unsigned len, i;
2628 struct string_list *val;
2629 va_list list;
2630
2631 va_start (list, fmt);
2632 len = vsnprintf (spbuf, sizeof spbuf, fmt, list);
2633 va_end (list);
2634
2635 val = dmalloc (strlen (prefix) + strlen (name) + 1 /* = */ +
2636 len + sizeof *val, MDL);
2637 if (!val)
2638 return;
2639 s = val -> string;
2640 strcpy (s, prefix);
2641 strcat (s, name);
2642 s += strlen (s);
2643 *s++ = '=';
2644 if (len >= sizeof spbuf) {
2645 va_start (list, fmt);
2646 vsnprintf (s, len + 1, fmt, list);
2647 va_end (list);
2648 } else
2649 strcpy (s, spbuf);
2650 val -> next = client -> env;
2651 client -> env = val;
2652 client -> envc++;
2653 }
2654
2655 int dhcp_option_ev_name (buf, buflen, option)
2656 char *buf;
2657 size_t buflen;
2658 struct option *option;
2659 {
2660 int i, j;
2661 const char *s;
2662
2663 j = 0;
2664 if (option -> universe != &dhcp_universe) {
2665 s = option -> universe -> name;
2666 i = 0;
2667 } else {
2668 s = option -> name;
2669 i = 1;
2670 }
2671
2672 do {
2673 while (*s) {
2674 if (j + 1 == buflen)
2675 return 0;
2676 if (*s == '-')
2677 buf [j++] = '_';
2678 else
2679 buf [j++] = *s;
2680 ++s;
2681 }
2682 if (!i) {
2683 s = option -> name;
2684 if (j + 1 == buflen)
2685 return 0;
2686 buf [j++] = '_';
2687 }
2688 ++i;
2689 } while (i != 2);
2690
2691 buf [j] = 0;
2692 return 1;
2693 }
2694
2695 void go_daemon ()
2696 {
2697 static int state = 0;
2698 int pid;
2699 int i;
2700
2701 /* Don't become a daemon if the user requested otherwise. */
2702 if (no_daemon) {
2703 write_client_pid_file ();
2704 return;
2705 }
2706
2707 /* Only do it once. */
2708 if (state)
2709 return;
2710 state = 1;
2711
2712 /* Stop logging to stderr... */
2713 log_perror = 0;
2714
2715 /* Become a daemon... */
2716 if ((pid = fork ()) < 0)
2717 log_fatal ("Can't fork daemon: %m");
2718 else if (pid)
2719 exit (0);
2720 /* Become session leader and get pid... */
2721 pid = setsid ();
2722
2723 /* Close standard I/O descriptors. */
2724 close(0);
2725 close(1);
2726 close(2);
2727
2728 /* Reopen them on /dev/null. */
2729 i = open ("/dev/null", O_RDWR);
2730 if (i == 0)
2731 i = open ("/dev/null", O_RDWR);
2732 if (i == 1) {
2733 i = open ("/dev/null", O_RDWR);
2734 log_perror = 0; /* No sense logging to /dev/null. */
2735 } else if (i != -1)
2736 close (i);
2737
2738 write_client_pid_file ();
2739 }
2740
2741 void write_client_pid_file ()
2742 {
2743 FILE *pf;
2744 int pfdesc;
2745
2746 pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY, 0644);
2747
2748 if (pfdesc < 0) {
2749 log_error ("Can't create %s: %m", path_dhclient_pid);
2750 return;
2751 }
2752
2753 pf = fdopen (pfdesc, "w");
2754 if (!pf)
2755 log_error ("Can't fdopen %s: %m", path_dhclient_pid);
2756 else {
2757 fprintf (pf, "%ld\n", (long)getpid ());
2758 fclose (pf);
2759 }
2760 }
2761
2762 void client_location_changed ()
2763 {
2764 struct interface_info *ip;
2765 struct client_state *client;
2766
2767 for (ip = interfaces; ip; ip = ip -> next) {
2768 for (client = ip -> client; client; client = client -> next) {
2769 switch (client -> state) {
2770 case S_SELECTING:
2771 cancel_timeout (send_discover, client);
2772 break;
2773
2774 case S_BOUND:
2775 cancel_timeout (state_bound, client);
2776 break;
2777
2778 case S_REBOOTING:
2779 case S_REQUESTING:
2780 case S_RENEWING:
2781 cancel_timeout (send_request, client);
2782 break;
2783
2784 case S_INIT:
2785 case S_REBINDING:
2786 case S_STOPPED:
2787 break;
2788 }
2789 client -> state = S_INIT;
2790 state_reboot (client);
2791 }
2792 }
2793 }
2794
2795 void do_release(client)
2796 struct client_state *client;
2797 {
2798 struct data_string ds;
2799 struct option_cache *oc;
2800
2801 /* Pick a random xid. */
2802 client -> xid = random ();
2803
2804 /* is there even a lease to release? */
2805 if (client -> active) {
2806 /* Make a DHCPRELEASE packet, and set appropriate per-interface
2807 flags. */
2808 make_release (client, client -> active);
2809
2810 memset (&ds, 0, sizeof ds);
2811 oc = lookup_option (&dhcp_universe,
2812 client -> active -> options,
2813 DHO_DHCP_SERVER_IDENTIFIER);
2814 if (oc &&
2815 evaluate_option_cache (&ds, (struct packet *)0,
2816 (struct lease *)0, client,
2817 (struct option_state *)0,
2818 client -> active -> options,
2819 &global_scope, oc, MDL)) {
2820 if (ds.len > 3) {
2821 memcpy (client -> destination.iabuf,
2822 ds.data, 4);
2823 client -> destination.len = 4;
2824 } else
2825 client -> destination = iaddr_broadcast;
2826
2827 data_string_forget (&ds, MDL);
2828 } else
2829 client -> destination = iaddr_broadcast;
2830 client -> first_sending = cur_time;
2831 client -> interval = client -> config -> initial_interval;
2832
2833 /* Zap the medium list... */
2834 client -> medium = (struct string_list *)0;
2835
2836 /* Send out the first and only DHCPRELEASE packet. */
2837 send_release (client);
2838
2839 /* Do the client script RELEASE operation. */
2840 script_init (client,
2841 "RELEASE", (struct string_list *)0);
2842 if (client -> alias)
2843 script_write_params (client, "alias_",
2844 client -> alias);
2845 script_write_params (client, "old_", client -> active);
2846 script_go (client);
2847 }
2848
2849 /* Cancel any timeouts. */
2850 cancel_timeout (state_bound, client);
2851 cancel_timeout (send_discover, client);
2852 cancel_timeout (state_init, client);
2853 cancel_timeout (send_request, client);
2854 cancel_timeout (state_reboot, client);
2855 client -> state = S_STOPPED;
2856 }
2857
2858 int dhclient_interface_shutdown_hook (struct interface_info *interface)
2859 {
2860 do_release (interface -> client);
2861
2862 return 1;
2863 }
2864
2865 int dhclient_interface_discovery_hook (struct interface_info *tmp)
2866 {
2867 struct interface_info *last, *ip;
2868 /* See if we can find the client from dummy_interfaces */
2869 last = 0;
2870 for (ip = dummy_interfaces; ip; ip = ip -> next) {
2871 if (!strcmp (ip -> name, tmp -> name)) {
2872 /* Remove from dummy_interfaces */
2873 if (last) {
2874 ip = (struct interface_info *)0;
2875 interface_reference (&ip, last -> next, MDL);
2876 interface_dereference (&last -> next, MDL);
2877 if (ip -> next) {
2878 interface_reference (&last -> next,
2879 ip -> next, MDL);
2880 interface_dereference (&ip -> next,
2881 MDL);
2882 }
2883 } else {
2884 ip = (struct interface_info *)0;
2885 interface_reference (&ip,
2886 dummy_interfaces, MDL);
2887 interface_dereference (&dummy_interfaces, MDL);
2888 if (ip -> next) {
2889 interface_reference (&dummy_interfaces,
2890 ip -> next, MDL);
2891 interface_dereference (&ip -> next,
2892 MDL);
2893 }
2894 }
2895 /* Copy "client" to tmp */
2896 if (ip -> client) {
2897 tmp -> client = ip -> client;
2898 tmp -> client -> interface = tmp;
2899 }
2900 interface_dereference (&ip, MDL);
2901 break;
2902 }
2903 last = ip;
2904 }
2905 return 1;
2906 }
2907
2908 isc_result_t dhclient_interface_startup_hook (struct interface_info *interface)
2909 {
2910 struct interface_info *ip;
2911 struct client_state *client;
2912
2913 /* This code needs some rethinking. It doesn't test against
2914 a signal name, and it just kind of bulls into doing something
2915 that may or may not be appropriate. */
2916
2917 if (interfaces) {
2918 interface_reference (&interface -> next, interfaces, MDL);
2919 interface_dereference (&interfaces, MDL);
2920 }
2921 interface_reference (&interfaces, interface, MDL);
2922
2923 discover_interfaces (DISCOVER_UNCONFIGURED);
2924
2925 for (ip = interfaces; ip; ip = ip -> next) {
2926 /* If interfaces were specified, don't configure
2927 interfaces that weren't specified! */
2928 if (ip -> flags & INTERFACE_RUNNING ||
2929 (ip -> flags & (INTERFACE_REQUESTED |
2930 INTERFACE_AUTOMATIC)) !=
2931 INTERFACE_REQUESTED)
2932 continue;
2933 script_init (ip -> client,
2934 "PREINIT", (struct string_list *)0);
2935 if (ip -> client -> alias)
2936 script_write_params (ip -> client, "alias_",
2937 ip -> client -> alias);
2938 script_go (ip -> client);
2939 }
2940
2941 discover_interfaces (interfaces_requested
2942 ? DISCOVER_REQUESTED
2943 : DISCOVER_RUNNING);
2944
2945 for (ip = interfaces; ip; ip = ip -> next) {
2946 if (ip -> flags & INTERFACE_RUNNING)
2947 continue;
2948 ip -> flags |= INTERFACE_RUNNING;
2949 for (client = ip -> client; client; client = client -> next) {
2950 client -> state = S_INIT;
2951 /* Set up a timeout to start the initialization
2952 process. */
2953 add_timeout (cur_time + random () % 5,
2954 state_reboot, client, 0, 0);
2955 }
2956 }
2957 return ISC_R_SUCCESS;
2958 }
2959
2960 /* The client should never receive a relay agent information option,
2961 so if it does, log it and discard it. */
2962
2963 int parse_agent_information_option (packet, len, data)
2964 struct packet *packet;
2965 int len;
2966 u_int8_t *data;
2967 {
2968 return 1;
2969 }
2970
2971 /* The client never sends relay agent information options. */
2972
2973 unsigned cons_agent_information_options (cfg_options, outpacket,
2974 agentix, length)
2975 struct option_state *cfg_options;
2976 struct dhcp_packet *outpacket;
2977 unsigned agentix;
2978 unsigned length;
2979 {
2980 return length;
2981 }
2982
2983 static void shutdown_exit (void *foo)
2984 {
2985 exit (0);
2986 }
2987
2988 isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
2989 control_object_state_t newstate)
2990 {
2991 struct interface_info *ip;
2992 struct client_state *client;
2993
2994 /* Do the right thing for each interface. */
2995 for (ip = interfaces; ip; ip = ip -> next) {
2996 for (client = ip -> client; client; client = client -> next) {
2997 switch (newstate) {
2998 case server_startup:
2999 return ISC_R_SUCCESS;
3000
3001 case server_running:
3002 return ISC_R_SUCCESS;
3003
3004 case server_shutdown:
3005 if (client -> active &&
3006 client -> active -> expiry > cur_time) {
3007 if (client -> config -> do_forward_update)
3008 client_dns_update (client, 0, 0);
3009 do_release (client);
3010 }
3011 break;
3012
3013 case server_hibernate:
3014 state_stop (client);
3015 break;
3016
3017 case server_awaken:
3018 state_reboot (client);
3019 break;
3020 }
3021 }
3022 }
3023 if (newstate == server_shutdown)
3024 add_timeout (cur_time + 1, shutdown_exit, 0, 0, 0);
3025 return ISC_R_SUCCESS;
3026 }
3027
3028 /* Called after a timeout if the DNS update failed on the previous try.
3029 Retries the update, and if it times out, schedules a retry after
3030 ten times as long of a wait. */
3031
3032 void client_dns_update_timeout (void *cp)
3033 {
3034 struct client_state *client = cp;
3035 isc_result_t status;
3036
3037 if (client -> active) {
3038 status = client_dns_update (client, 1,
3039 (client -> active -> renewal -
3040 cur_time));
3041 if (status == ISC_R_TIMEDOUT) {
3042 client -> dns_update_timeout *= 10;
3043 add_timeout (cur_time + client -> dns_update_timeout,
3044 client_dns_update_timeout, client, 0, 0);
3045 }
3046 }
3047 }
3048
3049 /* See if we should do a DNS update, and if so, do it. */
3050
3051 isc_result_t client_dns_update (struct client_state *client, int addp, int ttl)
3052 {
3053 struct data_string ddns_fqdn, ddns_fwd_name,
3054 ddns_dhcid, client_identifier;
3055 struct option_cache *oc;
3056 int ignorep;
3057 int result;
3058 isc_result_t rcode;
3059
3060 /* If we didn't send an FQDN option, we certainly aren't going to
3061 be doing an update. */
3062 if (!client -> sent_options)
3063 return ISC_R_SUCCESS;
3064
3065 /* If we don't have a lease, we can't do an update. */
3066 if (!client -> active)
3067 return ISC_R_SUCCESS;
3068
3069 /* If we set the no client update flag, don't do the update. */
3070 if ((oc = lookup_option (&fqdn_universe, client -> sent_options,
3071 FQDN_NO_CLIENT_UPDATE)) &&
3072 evaluate_boolean_option_cache (&ignorep, (struct packet *)0,
3073 (struct lease *)0, client,
3074 client -> sent_options,
3075 (struct option_state *)0,
3076 &global_scope, oc, MDL))
3077 return ISC_R_SUCCESS;
3078
3079 /* If we set the "server, please update" flag, or didn't set it
3080 to false, don't do the update. */
3081 if (!(oc = lookup_option (&fqdn_universe, client -> sent_options,
3082 FQDN_SERVER_UPDATE)) ||
3083 evaluate_boolean_option_cache (&ignorep, (struct packet *)0,
3084 (struct lease *)0, client,
3085 client -> sent_options,
3086 (struct option_state *)0,
3087 &global_scope, oc, MDL))
3088 return ISC_R_SUCCESS;
3089
3090 /* If no FQDN option was supplied, don't do the update. */
3091 memset (&ddns_fwd_name, 0, sizeof ddns_fwd_name);
3092 if (!(oc = lookup_option (&fqdn_universe, client -> sent_options,
3093 FQDN_FQDN)) ||
3094 !evaluate_option_cache (&ddns_fwd_name, (struct packet *)0,
3095 (struct lease *)0, client,
3096 client -> sent_options,
3097 (struct option_state *)0,
3098 &global_scope, oc, MDL))
3099 return ISC_R_SUCCESS;
3100
3101 /* Make a dhcid string out of either the client identifier,
3102 if we are sending one, or the interface's MAC address,
3103 otherwise. */
3104 memset (&ddns_dhcid, 0, sizeof ddns_dhcid);
3105
3106 memset (&client_identifier, 0, sizeof client_identifier);
3107 if ((oc = lookup_option (&dhcp_universe, client -> sent_options,
3108 DHO_DHCP_CLIENT_IDENTIFIER)) &&
3109 evaluate_option_cache (&client_identifier, (struct packet *)0,
3110 (struct lease *)0, client,
3111 client -> sent_options,
3112 (struct option_state *)0,
3113 &global_scope, oc, MDL)) {
3114 result = get_dhcid (&ddns_dhcid,
3115 DHO_DHCP_CLIENT_IDENTIFIER,
3116 client_identifier.data,
3117 client_identifier.len);
3118 data_string_forget (&client_identifier, MDL);
3119 } else
3120 result = get_dhcid (&ddns_dhcid, 0,
3121 client -> interface -> hw_address.hbuf,
3122 client -> interface -> hw_address.hlen);
3123 if (!result) {
3124 data_string_forget (&ddns_fwd_name, MDL);
3125 return ISC_R_SUCCESS;
3126 }
3127
3128 /* Start the resolver, if necessary. */
3129 if (!resolver_inited) {
3130 minires_ninit (&resolver_state);
3131 resolver_inited = 1;
3132 resolver_state.retrans = 1;
3133 resolver_state.retry = 1;
3134 }
3135
3136 /*
3137 * Perform updates.
3138 */
3139 if (ddns_fwd_name.len && ddns_dhcid.len) {
3140 if (addp)
3141 rcode = ddns_update_a (&ddns_fwd_name,
3142 client -> active -> address,
3143 &ddns_dhcid, ttl,
3144 1);
3145 else
3146 rcode = ddns_remove_a (&ddns_fwd_name,
3147 client -> active -> address,
3148 &ddns_dhcid);
3149 } else
3150 rcode = ISC_R_FAILURE;
3151
3152 data_string_forget (&ddns_fwd_name, MDL);
3153 data_string_forget (&ddns_dhcid, MDL);
3154 return rcode;
3155 }