]> git.ipfire.org Git - thirdparty/dhcp.git/blob - client/dhclient.c
Go back to the BSD license.
[thirdparty/dhcp.git] / client / dhclient.c
1 /* dhclient.c
2
3 DHCP Client. */
4
5 /*
6 * Copyright (c) 1995-2000 Internet Software Consortium.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of The Internet Software Consortium nor the names
19 * of its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
23 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
30 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * This code was originally written by Ted Lemon. Elliot Poger wrote
37 * a state machine to fully implement the client side of the DHCP
38 * protocol. Ted Lemon then added the configuration file, stuffed the
39 * state machine into its own data structure so there could be more
40 * than one, and added the client scripting code to produce the first
41 * ISC release (2.0b1pl0) of the client.
42 */
43
44 #ifndef lint
45 static char ocopyright[] =
46 "$Id: dhclient.c,v 1.98 2000/03/17 03:58:56 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
47 #endif /* not lint */
48
49 #include "dhcpd.h"
50 #include "version.h"
51
52 TIME cur_time;
53 TIME default_lease_time = 43200; /* 12 hours... */
54 TIME max_lease_time = 86400; /* 24 hours... */
55
56 const char *path_dhclient_conf = _PATH_DHCLIENT_CONF;
57 const char *path_dhclient_db = _PATH_DHCLIENT_DB;
58 const char *path_dhclient_pid = _PATH_DHCLIENT_PID;
59
60 int dhcp_max_agent_option_packet_length = 0;
61
62 int interfaces_requested = 0;
63
64 struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } };
65 struct iaddr iaddr_any = { 4, { 0, 0, 0, 0 } };
66 struct in_addr inaddr_any;
67 struct sockaddr_in sockaddr_broadcast;
68 struct in_addr giaddr;
69
70 struct binding_scope global_scope;
71
72 /* ASSERT_STATE() does nothing now; it used to be
73 assert (state_is == state_shouldbe). */
74 #define ASSERT_STATE(state_is, state_shouldbe) {}
75
76 static char copyright[] =
77 "Copyright 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium.";
78 static char arr [] = "All rights reserved.";
79 static char message [] = "Internet Software Consortium DHCP Client";
80 static char contrib [] = "\nPlease contribute if you find this software useful.";
81 static char url [] = "For info, please visit http://www.isc.org/dhcp-contrib.html\n";
82
83 u_int16_t local_port;
84 u_int16_t remote_port;
85 int no_daemon;
86 int save_scripts;
87
88 static void usage PROTO ((void));
89
90 void do_release(struct client_state *);
91
92 int main (argc, argv, envp)
93 int argc;
94 char **argv, **envp;
95 {
96 int i;
97 struct servent *ent;
98 struct interface_info *ip;
99 struct client_state *client;
100 unsigned seed;
101 int quiet = 0;
102 char *server = (char *)0;
103 char *relay = (char *)0;
104 isc_result_t status;
105 int release_mode = 0;
106 omapi_object_t *listener;
107 isc_result_t result;
108
109 #ifdef SYSLOG_4_2
110 openlog ("dhclient", LOG_NDELAY);
111 log_priority = LOG_DAEMON;
112 #else
113 openlog ("dhclient", LOG_NDELAY, LOG_DAEMON);
114 #endif
115
116 #if !(defined (DEBUG) || defined (SYSLOG_4_2) || defined (__CYGWIN32__))
117 setlogmask (LOG_UPTO (LOG_INFO));
118 #endif
119
120 for (i = 1; i < argc; i++) {
121 if (!strcmp (argv [i], "-r")) {
122 release_mode = 1;
123 no_daemon = 1;
124 } else if (!strcmp (argv [i], "-p")) {
125 if (++i == argc)
126 usage ();
127 local_port = htons (atoi (argv [i]));
128 log_debug ("binding to user-specified port %d",
129 ntohs (local_port));
130 } else if (!strcmp (argv [i], "-d")) {
131 no_daemon = 1;
132 } else if (!strcmp (argv [i], "-D")) {
133 save_scripts = 1;
134 } else if (!strcmp (argv [i], "-pf")) {
135 if (++i == argc)
136 usage ();
137 path_dhclient_pid = argv [i];
138 } else if (!strcmp (argv [i], "-cf")) {
139 if (++i == argc)
140 usage ();
141 path_dhclient_conf = argv [i];
142 } else if (!strcmp (argv [i], "-lf")) {
143 if (++i == argc)
144 usage ();
145 path_dhclient_db = argv [i];
146 } else if (!strcmp (argv [i], "-q")) {
147 quiet = 1;
148 quiet_interface_discovery = 1;
149 } else if (!strcmp (argv [i], "-s")) {
150 if (++i == argc)
151 usage ();
152 server = argv [i];
153 } else if (!strcmp (argv [i], "-g")) {
154 if (++i == argc)
155 usage ();
156 relay = argv [i];
157 } else if (!strcmp (argv [i], "-n")) {
158 /* do not start up any interfaces */
159 interfaces_requested = 1;
160 } else if (argv [i][0] == '-') {
161 usage ();
162 } else {
163 struct interface_info *tmp = ((struct interface_info *)
164 dmalloc (sizeof *tmp, MDL));
165 if (!tmp)
166 log_fatal ("Insufficient memory to %s %s",
167 "record interface", argv [i]);
168 memset (tmp, 0, sizeof *tmp);
169 strcpy (tmp -> name, argv [i]);
170 tmp -> next = interfaces;
171 tmp -> flags = INTERFACE_REQUESTED;
172 interfaces_requested = 1;
173 interfaces = tmp;
174 }
175 }
176
177 /* first kill of any currently running client */
178 if (release_mode) {
179 /* XXX inelegant hack to prove concept */
180 char command[1024];
181
182 #if !defined (NO_SNPRINTF)
183 snprintf (command, 1024, "kill `cat %s`", path_dhclient_pid);
184 #else
185 sprintf (command, "kill `cat %s`", path_dhclient_pid);
186 #endif
187 system (command);
188 }
189
190 if (!quiet) {
191 log_info ("%s %s", message, DHCP_VERSION);
192 log_info (copyright);
193 log_info (arr);
194 log_info (contrib);
195 log_info (url);
196 } else
197 log_perror = 0;
198
199 /* If we're given a relay agent address to insert, for testing
200 purposes, figure out what it is. */
201 if (relay) {
202 if (!inet_aton (relay, &giaddr)) {
203 struct hostent *he;
204 he = gethostbyname (relay);
205 if (he) {
206 memcpy (&giaddr, he -> h_addr_list [0],
207 sizeof giaddr);
208 } else {
209 log_fatal ("%s: no such host", relay);
210 }
211 }
212 }
213
214 /* Default to the DHCP/BOOTP port. */
215 if (!local_port) {
216 if (relay && giaddr.s_addr != INADDR_LOOPBACK) {
217 local_port = 67;
218 } else {
219 ent = getservbyname ("dhcpc", "udp");
220 if (!ent)
221 local_port = htons (68);
222 else
223 local_port = ent -> s_port;
224 #ifndef __CYGWIN32__
225 endservent ();
226 #endif
227 }
228 }
229
230 /* If we're faking a relay agent, and we're not using loopback,
231 use the server port, not the client port. */
232 if (relay && giaddr.s_addr != INADDR_LOOPBACK)
233 remote_port = 67;
234 else
235 remote_port = htons (ntohs (local_port) - 1); /* XXX */
236
237 /* Get the current time... */
238 GET_TIME (&cur_time);
239
240 sockaddr_broadcast.sin_family = AF_INET;
241 sockaddr_broadcast.sin_port = remote_port;
242 if (server) {
243 if (!inet_aton (server, &sockaddr_broadcast.sin_addr)) {
244 struct hostent *he;
245 he = gethostbyname (server);
246 if (he) {
247 memcpy (&sockaddr_broadcast.sin_addr,
248 he -> h_addr_list [0],
249 sizeof sockaddr_broadcast.sin_addr);
250 } else
251 sockaddr_broadcast.sin_addr.s_addr =
252 INADDR_BROADCAST;
253 }
254 } else {
255 sockaddr_broadcast.sin_addr.s_addr = INADDR_BROADCAST;
256 }
257
258 inaddr_any.s_addr = INADDR_ANY;
259
260 /* Set up the OMAPI. */
261 status = omapi_init ();
262 if (status != ISC_R_SUCCESS)
263 log_fatal ("Can't initialize OMAPI: %s",
264 isc_result_totext (status));
265
266 /* Set up the OMAPI wrappers for various server database internal
267 objects. */
268 dhclient_db_objects_setup ();
269
270 /* Discover all the network interfaces. */
271 discover_interfaces (DISCOVER_UNCONFIGURED);
272
273 /* Parse the dhclient.conf file. */
274 read_client_conf ();
275
276 /* Parse the lease database. */
277 read_client_leases ();
278
279 /* Rewrite the lease database... */
280 rewrite_client_leases ();
281
282 /* XXX */
283 /* config_counter(&snd_counter, &rcv_counter); */
284
285 /* If no broadcast interfaces were discovered, call the script
286 and tell it so. */
287 if (!interfaces) {
288 script_init ((struct client_state *)0, "NBI",
289 (struct string_list *)0);
290 script_go ((struct client_state *)0);
291
292 log_info ("No broadcast interfaces found - exiting.");
293
294 /* Nothing more to do. */
295 exit (0);
296 } else if (!release_mode) {
297 /* Call the script with the list of interfaces. */
298 for (ip = interfaces; ip; ip = ip -> next) {
299 /* If interfaces were specified, don't configure
300 interfaces that weren't specified! */
301 if (interfaces_requested &&
302 ((ip -> flags & (INTERFACE_REQUESTED |
303 INTERFACE_AUTOMATIC)) !=
304 INTERFACE_REQUESTED))
305 continue;
306 script_init (ip -> client,
307 "PREINIT", (struct string_list *)0);
308 if (ip -> client -> alias)
309 script_write_params (ip -> client, "alias_",
310 ip -> client -> alias);
311 script_go (ip -> client);
312 }
313 }
314
315 /* At this point, all the interfaces that the script thinks
316 are relevant should be running, so now we once again call
317 discover_interfaces(), and this time ask it to actually set
318 up the interfaces. */
319 discover_interfaces (interfaces_requested
320 ? DISCOVER_REQUESTED
321 : DISCOVER_RUNNING);
322
323 /* Make up a seed for the random number generator from current
324 time plus the sum of the last four bytes of each
325 interface's hardware address interpreted as an integer.
326 Not much entropy, but we're booting, so we're not likely to
327 find anything better. */
328 seed = 0;
329 for (ip = interfaces; ip; ip = ip -> next) {
330 int junk;
331 memcpy (&junk,
332 &ip -> hw_address.hbuf [ip -> hw_address.hlen -
333 sizeof seed], sizeof seed);
334 seed += junk;
335 }
336 srandom (seed + cur_time);
337
338 /* Start a configuration state machine for each interface. */
339 for (ip = interfaces; ip; ip = ip -> next) {
340 ip -> flags |= INTERFACE_RUNNING;
341 for (client = ip -> client; client; client = client -> next) {
342 if (release_mode)
343 do_release (client);
344 else {
345 client -> state = S_INIT;
346 /* Set up a timeout to start the initialization
347 process. */
348 add_timeout (cur_time + random () % 5,
349 state_reboot, client);
350 }
351 }
352 }
353
354 if (release_mode)
355 return 0;
356
357 /* Start up a listener for the object management API protocol. */
358 listener = (omapi_object_t *)0;
359 result = omapi_generic_new (&listener, MDL);
360 if (result != ISC_R_SUCCESS)
361 log_fatal ("Can't allocate new generic object: %s\n",
362 isc_result_totext (result));
363 result = omapi_protocol_listen (listener,
364 OMAPI_PROTOCOL_PORT, 1);
365 if (result != ISC_R_SUCCESS)
366 log_fatal ("Can't start OMAPI protocol: %s",
367 isc_result_totext (result));
368
369 /* Set up the bootp packet handler... */
370 bootp_packet_handler = do_packet;
371
372 /* Start dispatching packets and timeouts... */
373 dispatch ();
374
375 /*NOTREACHED*/
376 return 0;
377 }
378
379 static void usage ()
380 {
381 log_error ("Usage: dhclient [-d] [-D] [-q] [-p <port>] %s",
382 "[-s server]");
383 log_error (" [-lf lease-file] [-pf pid-file]%s",
384 "[-cf config-file] [interface]");
385 }
386
387 struct class *find_class (s)
388 const char *s;
389 {
390 return (struct class *)0;
391 }
392
393 int check_collection (packet, lease, collection)
394 struct packet *packet;
395 struct lease *lease;
396 struct collection *collection;
397 {
398 return 0;
399 }
400
401 void classify (packet, class)
402 struct packet *packet;
403 struct class *class;
404 {
405 }
406
407 int unbill_class (lease, class)
408 struct lease *lease;
409 struct class *class;
410 {
411 return 0;
412 }
413
414 struct subnet *find_subnet (addr)
415 struct iaddr addr;
416 {
417 return (struct subnet *)0;
418 }
419
420 /* Individual States:
421 *
422 * Each routine is called from the dhclient_state_machine() in one of
423 * these conditions:
424 * -> entering INIT state
425 * -> recvpacket_flag == 0: timeout in this state
426 * -> otherwise: received a packet in this state
427 *
428 * Return conditions as handled by dhclient_state_machine():
429 * Returns 1, sendpacket_flag = 1: send packet, reset timer.
430 * Returns 1, sendpacket_flag = 0: just reset the timer (wait for a milestone).
431 * Returns 0: finish the nap which was interrupted for no good reason.
432 *
433 * Several per-interface variables are used to keep track of the process:
434 * active_lease: the lease that is being used on the interface
435 * (null pointer if not configured yet).
436 * offered_leases: leases corresponding to DHCPOFFER messages that have
437 * been sent to us by DHCP servers.
438 * acked_leases: leases corresponding to DHCPACK messages that have been
439 * sent to us by DHCP servers.
440 * sendpacket: DHCP packet we're trying to send.
441 * destination: IP address to send sendpacket to
442 * In addition, there are several relevant per-lease variables.
443 * T1_expiry, T2_expiry, lease_expiry: lease milestones
444 * In the active lease, these control the process of renewing the lease;
445 * In leases on the acked_leases list, this simply determines when we
446 * can no longer legitimately use the lease.
447 */
448
449 void state_reboot (cpp)
450 void *cpp;
451 {
452 struct client_state *client = cpp;
453
454 /* If we don't remember an active lease, go straight to INIT. */
455 if (!client -> active ||
456 client -> active -> is_bootp) {
457 state_init (client);
458 return;
459 }
460
461 /* We are in the rebooting state. */
462 client -> state = S_REBOOTING;
463
464 /* make_request doesn't initialize xid because it normally comes
465 from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
466 so pick an xid now. */
467 client -> xid = random ();
468
469 /* Make a DHCPREQUEST packet, and set appropriate per-interface
470 flags. */
471 make_request (client, client -> active);
472 client -> destination = iaddr_broadcast;
473 client -> first_sending = cur_time;
474 client -> interval = client -> config -> initial_interval;
475
476 /* Zap the medium list... */
477 client -> medium = (struct string_list *)0;
478
479 /* Send out the first DHCPREQUEST packet. */
480 send_request (client);
481 }
482
483 /* Called when a lease has completely expired and we've been unable to
484 renew it. */
485
486 void state_init (cpp)
487 void *cpp;
488 {
489 struct client_state *client = cpp;
490
491 ASSERT_STATE(state, S_INIT);
492
493 /* Make a DHCPDISCOVER packet, and set appropriate per-interface
494 flags. */
495 make_discover (client, client -> active);
496 client -> xid = client -> packet.xid;
497 client -> destination = iaddr_broadcast;
498 client -> state = S_SELECTING;
499 client -> first_sending = cur_time;
500 client -> interval = client -> config -> initial_interval;
501
502 /* Add an immediate timeout to cause the first DHCPDISCOVER packet
503 to go out. */
504 send_discover (client);
505 }
506
507 /* state_selecting is called when one or more DHCPOFFER packets have been
508 received and a configurable period of time has passed. */
509
510 void state_selecting (cpp)
511 void *cpp;
512 {
513 struct client_state *client = cpp;
514 struct client_lease *lp, *next, *picked;
515
516
517 ASSERT_STATE(state, S_SELECTING);
518
519 /* Cancel state_selecting and send_discover timeouts, since either
520 one could have got us here. */
521 cancel_timeout (state_selecting, client);
522 cancel_timeout (send_discover, client);
523
524 /* We have received one or more DHCPOFFER packets. Currently,
525 the only criterion by which we judge leases is whether or
526 not we get a response when we arp for them. */
527 picked = (struct client_lease *)0;
528 for (lp = client -> offered_leases; lp; lp = next) {
529 next = lp -> next;
530
531 /* Check to see if we got an ARPREPLY for the address
532 in this particular lease. */
533 if (!picked) {
534 picked = lp;
535 picked -> next = (struct client_lease *)0;
536 } else {
537 freeit:
538 destroy_client_lease (lp);
539 }
540 }
541 client -> offered_leases = (struct client_lease *)0;
542
543 /* If we just tossed all the leases we were offered, go back
544 to square one. */
545 if (!picked) {
546 client -> state = S_INIT;
547 state_init (client);
548 return;
549 }
550
551 /* If it was a BOOTREPLY, we can just take the address right now. */
552 if (picked -> is_bootp) {
553 client -> new = picked;
554
555 /* Make up some lease expiry times
556 XXX these should be configurable. */
557 client -> new -> expiry = cur_time + 12000;
558 client -> new -> renewal += cur_time + 8000;
559 client -> new -> rebind += cur_time + 10000;
560
561 client -> state = S_REQUESTING;
562
563 /* Bind to the address we received. */
564 bind_lease (client);
565 return;
566 }
567
568 /* Go to the REQUESTING state. */
569 client -> destination = iaddr_broadcast;
570 client -> state = S_REQUESTING;
571 client -> first_sending = cur_time;
572 client -> interval = client -> config -> initial_interval;
573
574 /* Make a DHCPREQUEST packet from the lease we picked. */
575 make_request (client, picked);
576 client -> xid = client -> packet.xid;
577
578 /* Toss the lease we picked - we'll get it back in a DHCPACK. */
579 destroy_client_lease (picked);
580
581 /* Add an immediate timeout to send the first DHCPREQUEST packet. */
582 send_request (client);
583 }
584
585 /* state_requesting is called when we receive a DHCPACK message after
586 having sent out one or more DHCPREQUEST packets. */
587
588 void dhcpack (packet)
589 struct packet *packet;
590 {
591 struct interface_info *ip = packet -> interface;
592 struct client_state *client;
593 struct client_lease *lease;
594 struct option_cache *oc;
595 struct data_string ds;
596 int i;
597
598 /* If we're not receptive to an offer right now, or if the offer
599 has an unrecognizable transaction id, then just drop it. */
600 for (client = ip -> client; client; client = client -> next) {
601 if (client -> xid == packet -> raw -> xid)
602 break;
603 }
604 if (!client ||
605 (packet -> interface -> hw_address.hlen - 1 !=
606 packet -> raw -> hlen) ||
607 (memcmp (&packet -> interface -> hw_address.hbuf [1],
608 packet -> raw -> chaddr, packet -> raw -> hlen))) {
609 #if defined (DEBUG)
610 log_debug ("DHCPACK in wrong transaction.");
611 #endif
612 return;
613 }
614
615 if (client -> state != S_REBOOTING &&
616 client -> state != S_REQUESTING &&
617 client -> state != S_RENEWING &&
618 client -> state != S_REBINDING) {
619 #if defined (DEBUG)
620 log_debug ("DHCPACK in wrong state.");
621 #endif
622 return;
623 }
624
625 log_info ("DHCPACK from %s", piaddr (packet -> client_addr));
626
627 lease = packet_to_lease (packet);
628 if (!lease) {
629 log_info ("packet_to_lease failed.");
630 return;
631 }
632
633 client -> new = lease;
634
635 /* Stop resending DHCPREQUEST. */
636 cancel_timeout (send_request, client);
637
638 /* Figure out the lease time. */
639 oc = lookup_option (&dhcp_universe, client -> new -> options,
640 DHO_DHCP_LEASE_TIME);
641 memset (&ds, 0, sizeof ds);
642 if (oc &&
643 evaluate_option_cache (&ds, packet, (struct lease *)0,
644 packet -> options, client -> new -> options,
645 &global_scope, oc, MDL)) {
646 if (ds.len > 3)
647 client -> new -> expiry = getULong (ds.data);
648 else
649 client -> new -> expiry = 0;
650 data_string_forget (&ds, MDL);
651 } else
652 client -> new -> expiry = 0;
653
654 if (!client -> new -> expiry) {
655 log_error ("no expiry time on offered lease.");
656 /* XXX this is going to be bad - if this _does_
657 XXX happen, we should probably dynamically
658 XXX disqualify the DHCP server that gave us the
659 XXX bad packet from future selections and
660 XXX then go back into the init state. */
661 state_init (client);
662 return;
663 }
664
665 /* A number that looks negative here is really just very large,
666 because the lease expiry offset is unsigned. */
667 if (client -> new -> expiry < 0)
668 client -> new -> expiry = TIME_MAX;
669 /* Take the server-provided renewal time if there is one. */
670 oc = lookup_option (&dhcp_universe, client -> new -> options,
671 DHO_DHCP_RENEWAL_TIME);
672 if (oc &&
673 evaluate_option_cache (&ds, packet, (struct lease *)0,
674 packet -> options, client -> new -> options,
675 &global_scope, oc, MDL)) {
676 if (ds.len > 3)
677 client -> new -> renewal = getULong (ds.data);
678 else
679 client -> new -> renewal = 0;
680 data_string_forget (&ds, MDL);
681 } else
682 client -> new -> renewal = 0;
683
684 /* If it wasn't specified by the server, calculate it. */
685 if (!client -> new -> renewal)
686 client -> new -> renewal =
687 client -> new -> expiry / 2;
688
689 /* Now introduce some randomness to the renewal time: */
690 client -> new -> renewal = (((client -> new -> renewal + 3) * 3 / 4) +
691 (random () % /* XXX NUMS */
692 ((client -> new -> renewal + 3) / 4)));
693
694 /* Same deal with the rebind time. */
695 oc = lookup_option (&dhcp_universe, client -> new -> options,
696 DHO_DHCP_REBINDING_TIME);
697 if (oc &&
698 evaluate_option_cache (&ds, packet, (struct lease *)0,
699 packet -> options, client -> new -> options,
700 &global_scope, oc, MDL)) {
701 if (ds.len > 3)
702 client -> new -> rebind = getULong (ds.data);
703 else
704 client -> new -> rebind = 0;
705 data_string_forget (&ds, MDL);
706 } else
707 client -> new -> rebind = 0;
708
709 if (!client -> new -> rebind)
710 client -> new -> rebind =
711 (client -> new -> expiry * 7) / 8; /* XXX NUMS */
712
713 /* Make sure our randomness didn't run the renewal time past the
714 rebind time. */
715 if (client -> new -> renewal > client -> new -> rebind)
716 client -> new -> renewal = (client -> new -> rebind * 3) / 4;
717
718 client -> new -> expiry += cur_time;
719 /* Lease lengths can never be negative. */
720 if (client -> new -> expiry < cur_time)
721 client -> new -> expiry = TIME_MAX;
722 client -> new -> renewal += cur_time;
723 if (client -> new -> renewal < cur_time)
724 client -> new -> renewal = TIME_MAX;
725 client -> new -> rebind += cur_time;
726 if (client -> new -> rebind < cur_time)
727 client -> new -> rebind = TIME_MAX;
728
729 bind_lease (client);
730 }
731
732 void bind_lease (client)
733 struct client_state *client;
734 {
735 struct interface_info *ip = client -> interface;
736
737 /* Remember the medium. */
738 client -> new -> medium = client -> medium;
739
740 /* Run the client script with the new parameters. */
741 script_init (client, (client -> state == S_REQUESTING
742 ? "BOUND"
743 : (client -> state == S_RENEWING
744 ? "RENEW"
745 : (client -> state == S_REBOOTING
746 ? "REBOOT" : "REBIND"))),
747 client -> new -> medium);
748 if (client -> active && client -> state != S_REBOOTING)
749 script_write_params (client, "old_", client -> active);
750 script_write_params (client, "new_", client -> new);
751 if (client -> alias)
752 script_write_params (client, "alias_", client -> alias);
753
754 /* If the BOUND/RENEW code detects another machine using the
755 offered address, it exits nonzero. We need to send a
756 DHCPDECLINE and toss the lease. */
757 if (script_go (client)) {
758 make_decline (client, client -> new);
759 send_decline (client);
760 destroy_client_lease (client -> new);
761 client -> new = (struct client_lease *)0;
762 state_init (client);
763 return;
764 }
765
766 /* Write out the new lease. */
767 write_client_lease (client, client -> new, 0);
768
769 /* Replace the old active lease with the new one. */
770 if (client -> active)
771 destroy_client_lease (client -> active);
772 client -> active = client -> new;
773 client -> new = (struct client_lease *)0;
774
775 /* Set up a timeout to start the renewal process. */
776 add_timeout (client -> active -> renewal,
777 state_bound, client);
778
779 log_info ("bound to %s -- renewal in %ld seconds.",
780 piaddr (client -> active -> address),
781 (long)(client -> active -> renewal - cur_time));
782 client -> state = S_BOUND;
783 reinitialize_interfaces ();
784 go_daemon ();
785 }
786
787 /* state_bound is called when we've successfully bound to a particular
788 lease, but the renewal time on that lease has expired. We are
789 expected to unicast a DHCPREQUEST to the server that gave us our
790 original lease. */
791
792 void state_bound (cpp)
793 void *cpp;
794 {
795 struct client_state *client = cpp;
796 int i;
797 struct option_cache *oc;
798 struct data_string ds;
799
800 ASSERT_STATE(state, S_BOUND);
801
802 /* T1 has expired. */
803 make_request (client, client -> active);
804 client -> xid = client -> packet.xid;
805
806 memset (&ds, 0, sizeof ds);
807 oc = lookup_option (&dhcp_universe, client -> active -> options,
808 DHO_DHCP_SERVER_IDENTIFIER);
809 if (oc &&
810 evaluate_option_cache (&ds, (struct packet *)0, (struct lease *)0,
811 (struct option_state *)0,
812 client -> active -> options,
813 &global_scope, oc, MDL)) {
814 if (ds.len > 3) {
815 memcpy (client -> destination.iabuf, ds.data, 4);
816 client -> destination.len = 4;
817 } else
818 client -> destination = iaddr_broadcast;
819 } else
820 client -> destination = iaddr_broadcast;
821
822 client -> first_sending = cur_time;
823 client -> interval = client -> config -> initial_interval;
824 client -> state = S_RENEWING;
825
826 /* Send the first packet immediately. */
827 send_request (client);
828 }
829
830 int commit_leases ()
831 {
832 return 0;
833 }
834
835 int write_lease (lease)
836 struct lease *lease;
837 {
838 return 0;
839 }
840
841 int write_host (host)
842 struct host_decl *host;
843 {
844 return 0;
845 }
846
847 void db_startup (testp)
848 int testp;
849 {
850 }
851
852 void bootp (packet)
853 struct packet *packet;
854 {
855 struct iaddrlist *ap;
856
857 if (packet -> raw -> op != BOOTREPLY)
858 return;
859
860 /* If there's a reject list, make sure this packet's sender isn't
861 on it. */
862 for (ap = packet -> interface -> client -> config -> reject_list;
863 ap; ap = ap -> next) {
864 if (addr_eq (packet -> client_addr, ap -> addr)) {
865 log_info ("BOOTREPLY from %s rejected.",
866 piaddr (ap -> addr));
867 return;
868 }
869 }
870
871 dhcpoffer (packet);
872
873 }
874
875 void dhcp (packet)
876 struct packet *packet;
877 {
878 struct iaddrlist *ap;
879 void (*handler) PROTO ((struct packet *));
880 const char *type;
881
882 switch (packet -> packet_type) {
883 case DHCPOFFER:
884 handler = dhcpoffer;
885 type = "DHCPOFFER";
886 break;
887
888 case DHCPNAK:
889 handler = dhcpnak;
890 type = "DHCPNACK";
891 break;
892
893 case DHCPACK:
894 handler = dhcpack;
895 type = "DHCPACK";
896 break;
897
898 default:
899 return;
900 }
901
902 /* If there's a reject list, make sure this packet's sender isn't
903 on it. */
904 for (ap = packet -> interface -> client -> config -> reject_list;
905 ap; ap = ap -> next) {
906 if (addr_eq (packet -> client_addr, ap -> addr)) {
907 log_info ("%s from %s rejected.",
908 type, piaddr (ap -> addr));
909 return;
910 }
911 }
912 (*handler) (packet);
913 }
914
915 void dhcpoffer (packet)
916 struct packet *packet;
917 {
918 struct interface_info *ip = packet -> interface;
919 struct client_state *client;
920 struct client_lease *lease, *lp;
921 int i;
922 int stop_selecting;
923 const char *name = packet -> packet_type ? "DHCPOFFER" : "BOOTREPLY";
924 struct iaddrlist *ap;
925 struct option_cache *oc;
926
927 #ifdef DEBUG_PACKET
928 dump_packet (packet);
929 #endif
930
931 /* Find a client state that matches the xid... */
932 for (client = ip -> client; client; client = client -> next)
933 if (client -> xid == packet -> raw -> xid)
934 break;
935
936 /* If we're not receptive to an offer right now, or if the offer
937 has an unrecognizable transaction id, then just drop it. */
938 if (!client ||
939 client -> state != S_SELECTING ||
940 (packet -> interface -> hw_address.hlen - 1 !=
941 packet -> raw -> hlen) ||
942 (memcmp (&packet -> interface -> hw_address.hbuf [1],
943 packet -> raw -> chaddr, packet -> raw -> hlen))) {
944 #if defined (DEBUG)
945 log_debug ("%s in wrong transaction.", name);
946 #endif
947 return;
948 }
949
950 log_info ("%s from %s", name, piaddr (packet -> client_addr));
951
952
953 /* If this lease doesn't supply the minimum required parameters,
954 blow it off. */
955 if (client -> config -> required_options) {
956 for (i = 0; client -> config -> required_options [i]; i++) {
957 if (!lookup_option
958 (&dhcp_universe, packet -> options,
959 client -> config -> required_options [i])) {
960 log_info ("%s isn't satisfactory.", name);
961 return;
962 }
963 }
964 }
965
966 /* If we've already seen this lease, don't record it again. */
967 for (lease = client -> offered_leases; lease; lease = lease -> next) {
968 if (lease -> address.len == sizeof packet -> raw -> yiaddr &&
969 !memcmp (lease -> address.iabuf,
970 &packet -> raw -> yiaddr, lease -> address.len)) {
971 log_debug ("%s already seen.", name);
972 return;
973 }
974 }
975
976 lease = packet_to_lease (packet);
977 if (!lease) {
978 log_info ("packet_to_lease failed.");
979 return;
980 }
981
982 /* If this lease was acquired through a BOOTREPLY, record that
983 fact. */
984 if (!packet -> options_valid || !packet -> packet_type)
985 lease -> is_bootp = 1;
986
987 /* Record the medium under which this lease was offered. */
988 lease -> medium = client -> medium;
989
990 /* Figure out when we're supposed to stop selecting. */
991 stop_selecting = (client -> first_sending +
992 client -> config -> select_interval);
993
994 /* If this is the lease we asked for, put it at the head of the
995 list, and don't mess with the arp request timeout. */
996 if (lease -> address.len == client -> requested_address.len &&
997 !memcmp (lease -> address.iabuf,
998 client -> requested_address.iabuf,
999 client -> requested_address.len)) {
1000 lease -> next = client -> offered_leases;
1001 client -> offered_leases = lease;
1002 } else {
1003 /* Put the lease at the end of the list. */
1004 lease -> next = (struct client_lease *)0;
1005 if (!client -> offered_leases)
1006 client -> offered_leases = lease;
1007 else {
1008 for (lp = client -> offered_leases; lp -> next;
1009 lp = lp -> next)
1010 ;
1011 lp -> next = lease;
1012 }
1013 }
1014
1015 /* If the selecting interval has expired, go immediately to
1016 state_selecting(). Otherwise, time out into
1017 state_selecting at the select interval. */
1018 if (stop_selecting <= 0)
1019 state_selecting (ip);
1020 else {
1021 add_timeout (stop_selecting, state_selecting, client);
1022 cancel_timeout (send_discover, client);
1023 }
1024 }
1025
1026 /* Allocate a client_lease structure and initialize it from the parameters
1027 in the specified packet. */
1028
1029 struct client_lease *packet_to_lease (packet)
1030 struct packet *packet;
1031 {
1032 struct client_lease *lease;
1033 int i;
1034 struct option_cache *oc;
1035 struct data_string data;
1036
1037 lease = (struct client_lease *)new_client_lease (MDL);
1038
1039 if (!lease) {
1040 log_error ("dhcpoffer: no memory to record lease.\n");
1041 return (struct client_lease *)0;
1042 }
1043
1044 memset (lease, 0, sizeof *lease);
1045
1046 /* Copy the lease options. */
1047 option_state_reference (&lease -> options, packet -> options, MDL);
1048
1049 lease -> address.len = sizeof (packet -> raw -> yiaddr);
1050 memcpy (lease -> address.iabuf, &packet -> raw -> yiaddr,
1051 lease -> address.len);
1052
1053 /* Figure out the overload flag. */
1054 oc = lookup_option (&dhcp_universe, lease -> options,
1055 DHO_DHCP_OPTION_OVERLOAD);
1056 memset (&data, 0, sizeof data);
1057 if (oc &&
1058 evaluate_option_cache (&data, packet, (struct lease *)0,
1059 packet -> options, lease -> options,
1060 &global_scope, oc, MDL)) {
1061 if (data.len > 0)
1062 i = data.data [0];
1063 else
1064 i = 0;
1065 data_string_forget (&data, MDL);
1066 } else
1067 i = 0;
1068
1069 /* If the server name was filled out, copy it. */
1070 if (!(i & 2) && packet -> raw -> sname [0]) {
1071 unsigned len;
1072 /* Don't count on the NUL terminator. */
1073 for (len = 0; len < 64; len++)
1074 if (!packet -> raw -> sname [len])
1075 break;
1076 lease -> server_name = dmalloc (len + 1, MDL);
1077 if (!lease -> server_name) {
1078 log_error ("dhcpoffer: no memory for filename.\n");
1079 destroy_client_lease (lease);
1080 return (struct client_lease *)0;
1081 } else {
1082 memcpy (lease -> server_name,
1083 packet -> raw -> sname, len);
1084 lease -> server_name [len] = 0;
1085 }
1086 }
1087
1088 /* Ditto for the filename. */
1089 if (!(i & 1) && packet -> raw -> file [0]) {
1090 unsigned len;
1091 /* Don't count on the NUL terminator. */
1092 for (len = 0; len < 64; len++)
1093 if (!packet -> raw -> file [len])
1094 break;
1095 lease -> filename = dmalloc (len + 1, MDL);
1096 if (!lease -> filename) {
1097 log_error ("dhcpoffer: no memory for filename.\n");
1098 destroy_client_lease (lease);
1099 return (struct client_lease *)0;
1100 } else {
1101 memcpy (lease -> filename,
1102 packet -> raw -> file, len);
1103 lease -> filename [len] = 0;
1104 }
1105 }
1106 return lease;
1107 }
1108
1109 void dhcpnak (packet)
1110 struct packet *packet;
1111 {
1112 struct interface_info *ip = packet -> interface;
1113 struct client_state *client;
1114
1115 /* Find a client state that matches the xid... */
1116 for (client = ip -> client; client; client = client -> next)
1117 if (client -> xid == packet -> raw -> xid)
1118 break;
1119
1120 /* If we're not receptive to an offer right now, or if the offer
1121 has an unrecognizable transaction id, then just drop it. */
1122 if (!client ||
1123 (packet -> interface -> hw_address.hlen - 1 !=
1124 packet -> raw -> hlen) ||
1125 (memcmp (&packet -> interface -> hw_address.hbuf [1],
1126 packet -> raw -> chaddr, packet -> raw -> hlen))) {
1127 #if defined (DEBUG)
1128 log_debug ("DHCPNAK in wrong transaction.");
1129 #endif
1130 return;
1131 }
1132
1133 if (client -> state != S_REBOOTING &&
1134 client -> state != S_REQUESTING &&
1135 client -> state != S_RENEWING &&
1136 client -> state != S_REBINDING) {
1137 #if defined (DEBUG)
1138 log_debug ("DHCPNAK in wrong state.");
1139 #endif
1140 return;
1141 }
1142
1143 log_info ("DHCPNAK from %s", piaddr (packet -> client_addr));
1144
1145 if (!client -> active) {
1146 #if defined (DEBUG)
1147 log_info ("DHCPNAK with no active lease.\n");
1148 #endif
1149 return;
1150 }
1151
1152 destroy_client_lease (client -> active);
1153 client -> active = (struct client_lease *)0;
1154
1155 /* Stop sending DHCPREQUEST packets... */
1156 cancel_timeout (send_request, client);
1157
1158 client -> state = S_INIT;
1159 state_init (client);
1160 }
1161
1162 /* Send out a DHCPDISCOVER packet, and set a timeout to send out another
1163 one after the right interval has expired. If we don't get an offer by
1164 the time we reach the panic interval, call the panic function. */
1165
1166 void send_discover (cpp)
1167 void *cpp;
1168 {
1169 struct client_state *client = cpp;
1170
1171 int result;
1172 int interval;
1173 int increase = 1;
1174
1175 /* Figure out how long it's been since we started transmitting. */
1176 interval = cur_time - client -> first_sending;
1177
1178 /* If we're past the panic timeout, call the script and tell it
1179 we haven't found anything for this interface yet. */
1180 if (interval > client -> config -> timeout) {
1181 state_panic (client);
1182 return;
1183 }
1184
1185 /* If we're selecting media, try the whole list before doing
1186 the exponential backoff, but if we've already received an
1187 offer, stop looping, because we obviously have it right. */
1188 if (!client -> offered_leases &&
1189 client -> config -> media) {
1190 int fail = 0;
1191 again:
1192 if (client -> medium) {
1193 client -> medium = client -> medium -> next;
1194 increase = 0;
1195 }
1196 if (!client -> medium) {
1197 if (fail)
1198 log_fatal ("No valid media types for %s!",
1199 client -> interface -> name);
1200 client -> medium =
1201 client -> config -> media;
1202 increase = 1;
1203 }
1204
1205 log_info ("Trying medium \"%s\" %d",
1206 client -> medium -> string, increase);
1207 script_init (client, "MEDIUM", client -> medium);
1208 if (script_go (client)) {
1209 goto again;
1210 }
1211 }
1212
1213 /* If we're supposed to increase the interval, do so. If it's
1214 currently zero (i.e., we haven't sent any packets yet), set
1215 it to one; otherwise, add to it a random number between
1216 zero and two times itself. On average, this means that it
1217 will double with every transmission. */
1218 if (increase) {
1219 if (!client -> interval)
1220 client -> interval =
1221 client -> config -> initial_interval;
1222 else {
1223 client -> interval +=
1224 ((random () >> 2) %
1225 (2 * client -> interval));
1226 }
1227
1228 /* Don't backoff past cutoff. */
1229 if (client -> interval >
1230 client -> config -> backoff_cutoff)
1231 client -> interval =
1232 ((client -> config -> backoff_cutoff / 2)
1233 + ((random () >> 2) %
1234 client -> config -> backoff_cutoff));
1235 } else if (!client -> interval)
1236 client -> interval = client -> config -> initial_interval;
1237
1238 /* If the backoff would take us to the panic timeout, just use that
1239 as the interval. */
1240 if (cur_time + client -> interval >
1241 client -> first_sending + client -> config -> timeout)
1242 client -> interval =
1243 (client -> first_sending +
1244 client -> config -> timeout) - cur_time + 1;
1245
1246 /* Record the number of seconds since we started sending. */
1247 if (interval < 65536)
1248 client -> packet.secs = htons (interval);
1249 else
1250 client -> packet.secs = htons (65535);
1251 client -> secs = client -> packet.secs;
1252
1253 log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",
1254 client -> name ? client -> name : client -> interface -> name,
1255 inet_ntoa (sockaddr_broadcast.sin_addr),
1256 ntohs (sockaddr_broadcast.sin_port), client -> interval);
1257
1258 /* Send out a packet. */
1259 result = send_packet (client -> interface, (struct packet *)0,
1260 &client -> packet,
1261 client -> packet_length,
1262 inaddr_any, &sockaddr_broadcast,
1263 (struct hardware *)0);
1264
1265 add_timeout (cur_time + client -> interval, send_discover, client);
1266 }
1267
1268 /* state_panic gets called if we haven't received any offers in a preset
1269 amount of time. When this happens, we try to use existing leases that
1270 haven't yet expired, and failing that, we call the client script and
1271 hope it can do something. */
1272
1273 void state_panic (cpp)
1274 void *cpp;
1275 {
1276 struct client_state *client = cpp;
1277 struct client_lease *loop;
1278 struct client_lease *lp;
1279
1280 loop = lp = client -> active;
1281
1282 log_info ("No DHCPOFFERS received.");
1283
1284 /* We may not have an active lease, but we may have some
1285 predefined leases that we can try. */
1286 if (!client -> active && client -> leases)
1287 goto activate_next;
1288
1289 /* Run through the list of leases and see if one can be used. */
1290 while (client -> active) {
1291 if (client -> active -> expiry > cur_time) {
1292 log_info ("Trying recorded lease %s",
1293 piaddr (client -> active -> address));
1294 /* Run the client script with the existing
1295 parameters. */
1296 script_init (client, "TIMEOUT",
1297 client -> active -> medium);
1298 script_write_params (client, "new_", client -> active);
1299 if (client -> alias)
1300 script_write_params (client, "alias_",
1301 client -> alias);
1302
1303 /* If the old lease is still good and doesn't
1304 yet need renewal, go into BOUND state and
1305 timeout at the renewal time. */
1306 if (!script_go (client)) {
1307 if (cur_time < client -> active -> renewal) {
1308 client -> state = S_BOUND;
1309 log_info ("bound: renewal in %ld %s.",
1310 (long)(client -> active -> renewal -
1311 cur_time), "seconds");
1312 add_timeout (client -> active -> renewal,
1313 state_bound, client);
1314 } else {
1315 client -> state = S_BOUND;
1316 log_info ("bound: immediate renewal.");
1317 state_bound (client);
1318 }
1319 reinitialize_interfaces ();
1320 go_daemon ();
1321 return;
1322 }
1323 }
1324
1325 /* If there are no other leases, give up. */
1326 if (!client -> leases) {
1327 client -> leases = client -> active;
1328 client -> active = (struct client_lease *)0;
1329 break;
1330 }
1331
1332 activate_next:
1333 /* Otherwise, put the active lease at the end of the
1334 lease list, and try another lease.. */
1335 for (lp = client -> leases; lp -> next; lp = lp -> next)
1336 ;
1337 lp -> next = client -> active;
1338 if (lp -> next) {
1339 lp -> next -> next = (struct client_lease *)0;
1340 }
1341 client -> active = client -> leases;
1342 client -> leases = client -> leases -> next;
1343
1344 /* If we already tried this lease, we've exhausted the
1345 set of leases, so we might as well give up for
1346 now. */
1347 if (client -> active == loop)
1348 break;
1349 else if (!loop)
1350 loop = client -> active;
1351 }
1352
1353 /* No leases were available, or what was available didn't work, so
1354 tell the shell script that we failed to allocate an address,
1355 and try again later. */
1356 log_info ("No working leases in persistent database - sleeping.");
1357 script_init (client, "FAIL", (struct string_list *)0);
1358 if (client -> alias)
1359 script_write_params (client, "alias_", client -> alias);
1360 script_go (client);
1361 client -> state = S_INIT;
1362 add_timeout (cur_time +
1363 ((client -> config -> retry_interval + 1) / 2 +
1364 (random () % client -> config -> retry_interval)),
1365 state_init, client);
1366 go_daemon ();
1367 }
1368
1369 void send_request (cpp)
1370 void *cpp;
1371 {
1372 struct client_state *client = cpp;
1373
1374 int result;
1375 int interval;
1376 struct sockaddr_in destination;
1377 struct in_addr from;
1378
1379 /* Figure out how long it's been since we started transmitting. */
1380 interval = cur_time - client -> first_sending;
1381
1382 /* If we're in the INIT-REBOOT or REQUESTING state and we're
1383 past the reboot timeout, go to INIT and see if we can
1384 DISCOVER an address... */
1385 /* XXX In the INIT-REBOOT state, if we don't get an ACK, it
1386 means either that we're on a network with no DHCP server,
1387 or that our server is down. In the latter case, assuming
1388 that there is a backup DHCP server, DHCPDISCOVER will get
1389 us a new address, but we could also have successfully
1390 reused our old address. In the former case, we're hosed
1391 anyway. This is not a win-prone situation. */
1392 if ((client -> state == S_REBOOTING ||
1393 client -> state == S_REQUESTING) &&
1394 interval > client -> config -> reboot_timeout) {
1395 cancel:
1396 client -> state = S_INIT;
1397 cancel_timeout (send_request, client);
1398 state_init (client);
1399 return;
1400 }
1401
1402 /* If we're in the reboot state, make sure the media is set up
1403 correctly. */
1404 if (client -> state == S_REBOOTING &&
1405 !client -> medium &&
1406 client -> active -> medium ) {
1407 script_init (client, "MEDIUM", client -> active -> medium);
1408
1409 /* If the medium we chose won't fly, go to INIT state. */
1410 if (script_go (client))
1411 goto cancel;
1412
1413 /* Record the medium. */
1414 client -> medium = client -> active -> medium;
1415 }
1416
1417 /* If the lease has expired, relinquish the address and go back
1418 to the INIT state. */
1419 if (client -> state != S_REQUESTING &&
1420 cur_time > client -> active -> expiry) {
1421 /* Run the client script with the new parameters. */
1422 script_init (client, "EXPIRE", (struct string_list *)0);
1423 script_write_params (client, "old_", client -> active);
1424 if (client -> alias)
1425 script_write_params (client, "alias_",
1426 client -> alias);
1427 script_go (client);
1428
1429 /* Now do a preinit on the interface so that we can
1430 discover a new address. */
1431 script_init (client, "PREINIT", (struct string_list *)0);
1432 if (client -> alias)
1433 script_write_params (client, "alias_",
1434 client -> alias);
1435 script_go (client);
1436
1437 client -> state = S_INIT;
1438 state_init (client);
1439 return;
1440 }
1441
1442 /* Do the exponential backoff... */
1443 if (!client -> interval)
1444 client -> interval = client -> config -> initial_interval;
1445 else {
1446 client -> interval += ((random () >> 2) %
1447 (2 * client -> interval));
1448 }
1449
1450 /* Don't backoff past cutoff. */
1451 if (client -> interval >
1452 client -> config -> backoff_cutoff)
1453 client -> interval =
1454 ((client -> config -> backoff_cutoff / 2)
1455 + ((random () >> 2) % client -> interval));
1456
1457 /* If the backoff would take us to the expiry time, just set the
1458 timeout to the expiry time. */
1459 if (client -> state != S_REQUESTING &&
1460 cur_time + client -> interval > client -> active -> expiry)
1461 client -> interval =
1462 client -> active -> expiry - cur_time + 1;
1463
1464 /* If the lease T2 time has elapsed, or if we're not yet bound,
1465 broadcast the DHCPREQUEST rather than unicasting. */
1466 if (client -> state == S_REQUESTING ||
1467 client -> state == S_REBOOTING ||
1468 cur_time > client -> active -> rebind)
1469 destination.sin_addr = sockaddr_broadcast.sin_addr;
1470 else
1471 memcpy (&destination.sin_addr.s_addr,
1472 client -> destination.iabuf,
1473 sizeof destination.sin_addr.s_addr);
1474 destination.sin_port = remote_port;
1475 destination.sin_family = AF_INET;
1476 #ifdef HAVE_SA_LEN
1477 destination.sin_len = sizeof destination;
1478 #endif
1479
1480 if (client -> state == S_RENEWING ||
1481 client -> state == S_REBINDING)
1482 memcpy (&from, client -> active -> address.iabuf,
1483 sizeof from);
1484 else
1485 from.s_addr = INADDR_ANY;
1486
1487 /* Record the number of seconds since we started sending. */
1488 if (client -> state == S_REQUESTING)
1489 client -> packet.secs = client -> secs;
1490 else {
1491 if (interval < 65536)
1492 client -> packet.secs = htons (interval);
1493 else
1494 client -> packet.secs = htons (65535);
1495 }
1496
1497 log_info ("DHCPREQUEST on %s to %s port %d",
1498 client -> name ? client -> name : client -> interface -> name,
1499 inet_ntoa (destination.sin_addr),
1500 ntohs (destination.sin_port));
1501
1502 if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
1503 fallback_interface)
1504 result = send_packet (fallback_interface,
1505 (struct packet *)0,
1506 &client -> packet,
1507 client -> packet_length,
1508 from, &destination,
1509 (struct hardware *)0);
1510 else
1511 /* Send out a packet. */
1512 result = send_packet (client -> interface, (struct packet *)0,
1513 &client -> packet,
1514 client -> packet_length,
1515 from, &destination,
1516 (struct hardware *)0);
1517
1518 add_timeout (cur_time + client -> interval,
1519 send_request, client);
1520 }
1521
1522 void send_decline (cpp)
1523 void *cpp;
1524 {
1525 struct client_state *client = cpp;
1526
1527 int result;
1528
1529 log_info ("DHCPDECLINE on %s to %s port %d",
1530 client -> name ? client -> name : client -> interface -> name,
1531 inet_ntoa (sockaddr_broadcast.sin_addr),
1532 ntohs (sockaddr_broadcast.sin_port));
1533
1534 /* Send out a packet. */
1535 result = send_packet (client -> interface, (struct packet *)0,
1536 &client -> packet,
1537 client -> packet_length,
1538 inaddr_any, &sockaddr_broadcast,
1539 (struct hardware *)0);
1540 }
1541
1542 void send_release (cpp)
1543 void *cpp;
1544 {
1545 struct client_state *client = cpp;
1546
1547 int result;
1548
1549 log_info ("DHCPRELEASE on %s to %s port %d",
1550 client -> name ? client -> name : client -> interface -> name,
1551 inet_ntoa (sockaddr_broadcast.sin_addr),
1552 ntohs (sockaddr_broadcast.sin_port));
1553
1554 /* Send out a packet. */
1555 result = send_packet (client -> interface, (struct packet *)0,
1556 &client -> packet,
1557 client -> packet_length,
1558 inaddr_any, &sockaddr_broadcast,
1559 (struct hardware *)0);
1560 }
1561
1562 void make_client_options (client, lease, type, sid, rip, prl, op)
1563 struct client_state *client;
1564 struct client_lease *lease;
1565 u_int8_t *type;
1566 struct option_cache *sid;
1567 struct iaddr *rip;
1568 u_int32_t *prl;
1569 struct option_state **op;
1570 {
1571 unsigned i;
1572 struct option_cache *oc;
1573 struct buffer *bp = (struct buffer *)0;
1574
1575 /* Allocate space for options. */
1576 option_state_allocate (op, MDL);
1577
1578 /* Send the server identifier if provided. */
1579 if (sid)
1580 save_option (&dhcp_universe, *op, sid);
1581
1582 oc = (struct option_cache *)0;
1583
1584 /* Send the requested address if provided. */
1585 if (rip) {
1586 client -> requested_address = *rip;
1587 if (!(make_const_option_cache
1588 (&oc, (struct buffer **)0, rip -> iabuf, rip -> len,
1589 &dhcp_options [DHO_DHCP_REQUESTED_ADDRESS], MDL)))
1590 log_error ("can't make requested address cache.");
1591 else {
1592 save_option (&dhcp_universe, *op, oc);
1593 option_cache_dereference (&oc, MDL);
1594 }
1595 } else {
1596 client -> requested_address.len = 0;
1597 }
1598
1599 if (!(make_const_option_cache
1600 (&oc, (struct buffer **)0,
1601 type, 1, &dhcp_options [DHO_DHCP_MESSAGE_TYPE], MDL)))
1602 log_error ("can't make message type.");
1603 else {
1604 save_option (&dhcp_universe, *op, oc);
1605 option_cache_dereference (&oc, MDL);
1606 }
1607
1608 if (prl) {
1609 /* Figure out how many parameters were requested. */
1610 for (i = 0; prl [i]; i++)
1611 ;
1612 if (!buffer_allocate (&bp, i, MDL))
1613 log_error ("can't make parameter list buffer.");
1614 else {
1615 for (i = 0; prl [i]; i++)
1616 bp -> data [i] = prl [i];
1617 if (!(make_const_option_cache
1618 (&oc, &bp, (u_int8_t *)0, i,
1619 &dhcp_options [DHO_DHCP_PARAMETER_REQUEST_LIST],
1620 MDL)))
1621 log_error ("can't make option cache");
1622 else {
1623 save_option (&dhcp_universe, *op, oc);
1624 option_cache_dereference (&oc, MDL);
1625 }
1626 }
1627 }
1628
1629 /* Run statements that need to be run on transmission. */
1630 if (client -> config -> on_transmission)
1631 execute_statements_in_scope
1632 ((struct packet *)0, (struct lease *)0,
1633 (lease ? lease -> options : (struct option_state *)0),
1634 *op, &global_scope,
1635 client -> config -> on_transmission,
1636 (struct group *)0);
1637 }
1638
1639 void make_discover (client, lease)
1640 struct client_state *client;
1641 struct client_lease *lease;
1642 {
1643 struct dhcp_packet *raw;
1644 unsigned char discover = DHCPDISCOVER;
1645 int i;
1646 struct option_state *options = (struct option_state *)0;
1647
1648 memset (&client -> packet, 0, sizeof (client -> packet));
1649
1650 make_client_options (client,
1651 lease, &discover, (struct option_cache *)0,
1652 lease ? &lease -> address : (struct iaddr *)0,
1653 client -> config -> requested_options,
1654 &options);
1655
1656 /* Set up the option buffer... */
1657 client -> packet_length =
1658 cons_options ((struct packet *)0, &client -> packet,
1659 (struct lease *)0, 0,
1660 (struct option_state *)0, options,
1661 &global_scope, 0, 0, 0, (struct data_string *)0);
1662 if (client -> packet_length < BOOTP_MIN_LEN)
1663 client -> packet_length = BOOTP_MIN_LEN;
1664
1665 client -> packet.op = BOOTREQUEST;
1666 client -> packet.htype = client -> interface -> hw_address.hbuf [0];
1667 client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
1668 client -> packet.hops = 0;
1669 client -> packet.xid = random ();
1670 client -> packet.secs = 0; /* filled in by send_discover. */
1671
1672 if (can_receive_unicast_unconfigured (client -> interface))
1673 client -> packet.flags = 0;
1674 else
1675 client -> packet.flags = htons (BOOTP_BROADCAST);
1676
1677 memset (&(client -> packet.ciaddr),
1678 0, sizeof client -> packet.ciaddr);
1679 memset (&(client -> packet.yiaddr),
1680 0, sizeof client -> packet.yiaddr);
1681 memset (&(client -> packet.siaddr),
1682 0, sizeof client -> packet.siaddr);
1683 client -> packet.giaddr = giaddr;
1684 if (client -> interface -> hw_address.hlen > 0)
1685 memcpy (client -> packet.chaddr,
1686 &client -> interface -> hw_address.hbuf [1],
1687 (unsigned)(client -> interface -> hw_address.hlen - 1));
1688
1689 #ifdef DEBUG_PACKET
1690 dump_packet (sendpkt);
1691 dump_raw ((unsigned char *)client -> packet,
1692 sendpkt->packet_length);
1693 #endif
1694 }
1695
1696
1697 void make_request (client, lease)
1698 struct client_state *client;
1699 struct client_lease *lease;
1700 {
1701 unsigned char request = DHCPREQUEST;
1702 int i, j;
1703 unsigned char *tmp, *digest;
1704 unsigned char *old_digest_loc;
1705 struct option_state *options = (struct option_state *)0;
1706 struct option_cache *oc;
1707
1708 memset (&client -> packet, 0, sizeof (client -> packet));
1709
1710 if (client -> state == S_REQUESTING)
1711 oc = lookup_option (&dhcp_universe, lease -> options,
1712 DHO_DHCP_SERVER_IDENTIFIER);
1713 else
1714 oc = (struct option_cache *)0;
1715
1716 make_client_options (client, lease, &request, oc,
1717 ((client -> state == S_REQUESTING ||
1718 client -> state == S_REBOOTING)
1719 ? &lease -> address
1720 : (struct iaddr *)0),
1721 client -> config -> requested_options,
1722 &options);
1723
1724 /* Set up the option buffer... */
1725 client -> packet_length =
1726 cons_options ((struct packet *)0, &client -> packet,
1727 (struct lease *)0, 0,
1728 (struct option_state *)0, options,
1729 &global_scope, 0, 0, 0, (struct data_string *)0);
1730 if (client -> packet_length < BOOTP_MIN_LEN)
1731 client -> packet_length = BOOTP_MIN_LEN;
1732
1733 client -> packet.op = BOOTREQUEST;
1734 client -> packet.htype = client -> interface -> hw_address.hbuf [0];
1735 client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
1736 client -> packet.hops = 0;
1737 client -> packet.xid = client -> xid;
1738 client -> packet.secs = 0; /* Filled in by send_request. */
1739
1740 /* If we own the address we're requesting, put it in ciaddr;
1741 otherwise set ciaddr to zero. */
1742 if (client -> state == S_BOUND ||
1743 client -> state == S_RENEWING ||
1744 client -> state == S_REBINDING) {
1745 memcpy (&client -> packet.ciaddr,
1746 lease -> address.iabuf, lease -> address.len);
1747 client -> packet.flags = 0;
1748 } else {
1749 memset (&client -> packet.ciaddr, 0,
1750 sizeof client -> packet.ciaddr);
1751 if (can_receive_unicast_unconfigured (client -> interface))
1752 client -> packet.flags = 0;
1753 else
1754 client -> packet.flags = htons (BOOTP_BROADCAST);
1755 }
1756
1757 memset (&client -> packet.yiaddr, 0,
1758 sizeof client -> packet.yiaddr);
1759 memset (&client -> packet.siaddr, 0,
1760 sizeof client -> packet.siaddr);
1761 client -> packet.giaddr = giaddr;
1762 if (client -> interface -> hw_address.hlen > 0)
1763 memcpy (client -> packet.chaddr,
1764 &client -> interface -> hw_address.hbuf [1],
1765 (unsigned)(client -> interface -> hw_address.hlen - 1));
1766
1767 #ifdef DEBUG_PACKET
1768 dump_packet (sendpkt);
1769 dump_raw ((unsigned char *)client -> packet, sendpkt->packet_length);
1770 #endif
1771 }
1772
1773 void make_decline (client, lease)
1774 struct client_state *client;
1775 struct client_lease *lease;
1776 {
1777 unsigned char decline = DHCPDECLINE;
1778 int i;
1779 struct option_cache *oc;
1780
1781 struct option_state *options = (struct option_state *)0;
1782
1783 oc = lookup_option (&dhcp_universe, lease -> options,
1784 DHO_DHCP_SERVER_IDENTIFIER);
1785 make_client_options (client, lease, &decline, oc,
1786 &lease -> address, (u_int32_t *)0, &options);
1787
1788 /* Set up the option buffer... */
1789 memset (&client -> packet, 0, sizeof (client -> packet));
1790 client -> packet_length =
1791 cons_options ((struct packet *)0, &client -> packet,
1792 (struct lease *)0, 0,
1793 (struct option_state *)0, options,
1794 &global_scope, 0, 0, 0, (struct data_string *)0);
1795 if (client -> packet_length < BOOTP_MIN_LEN)
1796 client -> packet_length = BOOTP_MIN_LEN;
1797 option_state_dereference (&options, MDL);
1798
1799 client -> packet.op = BOOTREQUEST;
1800 client -> packet.htype = client -> interface -> hw_address.hbuf [0];
1801 client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
1802 client -> packet.hops = 0;
1803 client -> packet.xid = client -> xid;
1804 client -> packet.secs = 0; /* Filled in by send_request. */
1805 if (can_receive_unicast_unconfigured (client -> interface))
1806 client -> packet.flags = 0;
1807 else
1808 client -> packet.flags = htons (BOOTP_BROADCAST);
1809
1810 /* ciaddr must always be zero. */
1811 memset (&client -> packet.ciaddr, 0,
1812 sizeof client -> packet.ciaddr);
1813 memset (&client -> packet.yiaddr, 0,
1814 sizeof client -> packet.yiaddr);
1815 memset (&client -> packet.siaddr, 0,
1816 sizeof client -> packet.siaddr);
1817 client -> packet.giaddr = giaddr;
1818 memcpy (client -> packet.chaddr,
1819 &client -> interface -> hw_address.hbuf [1],
1820 client -> interface -> hw_address.hlen);
1821
1822 #ifdef DEBUG_PACKET
1823 dump_packet (sendpkt);
1824 dump_raw ((unsigned char *)client -> packet, sendpkt->packet_length);
1825 #endif
1826 }
1827
1828 void make_release (client, lease)
1829 struct client_state *client;
1830 struct client_lease *lease;
1831 {
1832 unsigned char request = DHCPRELEASE;
1833 int i;
1834 struct option_cache *oc;
1835
1836 struct option_state *options = (struct option_state *)0;
1837
1838 memset (&client -> packet, 0, sizeof (client -> packet));
1839
1840 oc = lookup_option (&dhcp_universe, lease -> options,
1841 DHO_DHCP_SERVER_IDENTIFIER);
1842 make_client_options (client, lease, &request, oc,
1843 (struct iaddr *)0, (u_int32_t *)0,
1844 &options);
1845
1846 /* Set up the option buffer... */
1847 client -> packet_length =
1848 cons_options ((struct packet *)0, &client -> packet,
1849 (struct lease *)0, 0,
1850 (struct option_state *)0, options,
1851 &global_scope, 0, 0, 0, (struct data_string *)0);
1852 if (client -> packet_length < BOOTP_MIN_LEN)
1853 client -> packet_length = BOOTP_MIN_LEN;
1854 option_state_dereference (&options, MDL);
1855
1856 client -> packet.op = BOOTREQUEST;
1857 client -> packet.htype = client -> interface -> hw_address.hbuf [0];
1858 client -> packet.hlen = client -> interface -> hw_address.hlen - 1;
1859 client -> packet.hops = 0;
1860 client -> packet.xid = random ();
1861 client -> packet.secs = 0;
1862 client -> packet.flags = 0;
1863 memcpy (&client -> packet.ciaddr,
1864 lease -> address.iabuf, lease -> address.len);
1865 memset (&client -> packet.yiaddr, 0,
1866 sizeof client -> packet.yiaddr);
1867 memset (&client -> packet.siaddr, 0,
1868 sizeof client -> packet.siaddr);
1869 client -> packet.giaddr = giaddr;
1870 memcpy (client -> packet.chaddr,
1871 &client -> interface -> hw_address.hbuf [1],
1872 client -> interface -> hw_address.hlen);
1873
1874 #ifdef DEBUG_PACKET
1875 dump_packet (sendpkt);
1876 dump_raw ((unsigned char *)client -> packet,
1877 client -> packet_length);
1878 #endif
1879 }
1880
1881 void destroy_client_lease (lease)
1882 struct client_lease *lease;
1883 {
1884 int i;
1885
1886 if (lease -> server_name)
1887 dfree (lease -> server_name, MDL);
1888 if (lease -> filename)
1889 dfree (lease -> filename, MDL);
1890 option_state_dereference (&lease -> options, MDL);
1891 free_client_lease (lease, MDL);
1892 }
1893
1894 FILE *leaseFile;
1895
1896 void rewrite_client_leases ()
1897 {
1898 struct interface_info *ip;
1899 struct client_state *client;
1900 struct client_lease *lp;
1901
1902 if (leaseFile)
1903 fclose (leaseFile);
1904 leaseFile = fopen (path_dhclient_db, "w");
1905 if (!leaseFile)
1906 log_fatal ("can't create %s: %m", path_dhclient_db);
1907
1908 /* Write out all the leases attached to configured interfaces that
1909 we know about. */
1910 for (ip = interfaces; ip; ip = ip -> next) {
1911 for (client = ip -> client; client; client = client -> next) {
1912 for (lp = client -> leases; lp; lp = lp -> next) {
1913 write_client_lease (client, lp, 1);
1914 }
1915 if (client -> active)
1916 write_client_lease (client,
1917 client -> active, 1);
1918 }
1919 }
1920
1921 /* Write out any leases that are attached to interfaces that aren't
1922 currently configured. */
1923 for (ip = dummy_interfaces; ip; ip = ip -> next) {
1924 for (client = ip -> client; client; client = client -> next) {
1925 for (lp = client -> leases; lp; lp = lp -> next) {
1926 write_client_lease (client, lp, 1);
1927 }
1928 if (client -> active)
1929 write_client_lease (client,
1930 client -> active, 1);
1931 }
1932 }
1933 fflush (leaseFile);
1934 }
1935
1936 void write_client_lease (client, lease, rewrite)
1937 struct client_state *client;
1938 struct client_lease *lease;
1939 int rewrite;
1940 {
1941 int i;
1942 struct tm *t;
1943 static int leases_written;
1944 struct option_cache *oc;
1945 struct data_string ds;
1946 pair *hash;
1947
1948 if (!rewrite) {
1949 if (leases_written++ > 20) {
1950 rewrite_client_leases ();
1951 leases_written = 0;
1952 }
1953 }
1954
1955 /* If the lease came from the config file, we don't need to stash
1956 a copy in the lease database. */
1957 if (lease -> is_static)
1958 return;
1959
1960 if (!leaseFile) { /* XXX */
1961 leaseFile = fopen (path_dhclient_db, "w");
1962 if (!leaseFile)
1963 log_fatal ("can't create %s: %m", path_dhclient_db);
1964 }
1965
1966 fprintf (leaseFile, "lease {\n");
1967 if (lease -> is_bootp)
1968 fprintf (leaseFile, " bootp;\n");
1969 fprintf (leaseFile, " interface \"%s\";\n",
1970 client -> interface -> name);
1971 if (client -> name)
1972 fprintf (leaseFile, " name \"%s\";\n", client -> name);
1973 fprintf (leaseFile, " fixed-address %s;\n",
1974 piaddr (lease -> address));
1975 if (lease -> filename)
1976 fprintf (leaseFile, " filename \"%s\";\n",
1977 lease -> filename);
1978 if (lease -> server_name)
1979 fprintf (leaseFile, " server-name \"%s\";\n",
1980 lease -> server_name);
1981 if (lease -> medium)
1982 fprintf (leaseFile, " medium \"%s\";\n",
1983 lease -> medium -> string);
1984
1985 memset (&ds, 0, sizeof ds);
1986
1987 hash = lease -> options -> universes [dhcp_universe.index];
1988 for (i = 0; i < OPTION_HASH_SIZE; i++) {
1989 pair p;
1990 /* XXX save _all_ options! XXX */
1991 for (p = hash [i]; p; p = p -> cdr) {
1992 oc = (struct option_cache *)p -> car;
1993 if (evaluate_option_cache (&ds, (struct packet *)0,
1994 (struct lease *)0,
1995 (struct option_state *)0,
1996 lease -> options,
1997 &global_scope, oc, MDL)) {
1998 fprintf (leaseFile,
1999 " option %s %s;\n",
2000 oc -> option -> name,
2001 pretty_print_option
2002 (oc -> option -> code,
2003 ds.data, ds.len, 1, 1));
2004 data_string_forget (&ds, MDL);
2005 }
2006 }
2007 }
2008
2009 /* Note: the following is not a Y2K bug - it's a Y1.9K bug. Until
2010 somebody invents a time machine, I think we can safely disregard
2011 it. */
2012 t = gmtime (&lease -> renewal);
2013 fprintf (leaseFile,
2014 " renew %d %d/%d/%d %02d:%02d:%02d;\n",
2015 t -> tm_wday, t -> tm_year + 1900,
2016 t -> tm_mon + 1, t -> tm_mday,
2017 t -> tm_hour, t -> tm_min, t -> tm_sec);
2018 t = gmtime (&lease -> rebind);
2019 fprintf (leaseFile,
2020 " rebind %d %d/%d/%d %02d:%02d:%02d;\n",
2021 t -> tm_wday, t -> tm_year + 1900,
2022 t -> tm_mon + 1, t -> tm_mday,
2023 t -> tm_hour, t -> tm_min, t -> tm_sec);
2024 t = gmtime (&lease -> expiry);
2025 fprintf (leaseFile,
2026 " expire %d %d/%d/%d %02d:%02d:%02d;\n",
2027 t -> tm_wday, t -> tm_year + 1900,
2028 t -> tm_mon + 1, t -> tm_mday,
2029 t -> tm_hour, t -> tm_min, t -> tm_sec);
2030 fprintf (leaseFile, "}\n");
2031 fflush (leaseFile);
2032 }
2033
2034 /* Variables holding name of script and file pointer for writing to
2035 script. Needless to say, this is not reentrant - only one script
2036 can be invoked at a time. */
2037 char scriptName [256];
2038 FILE *scriptFile;
2039
2040 void script_init (client, reason, medium)
2041 struct client_state *client;
2042 const char *reason;
2043 struct string_list *medium;
2044 {
2045 int fd;
2046 #ifndef HAVE_MKSTEMP
2047
2048 do {
2049 #endif
2050 strcpy (scriptName, "/tmp/dcsXXXXXX");
2051 #ifdef HAVE_MKSTEMP
2052 fd = mkstemp (scriptName);
2053 #else
2054 if (!mktemp (scriptName))
2055 log_fatal ("can't create temporary script %s: %m",
2056 scriptName);
2057 fd = open (scriptName, O_EXCL | O_CREAT | O_WRONLY, 0600);
2058 } while (fd < 0 && errno == EEXIST);
2059 #endif
2060 if (fd < 0)
2061 log_fatal ("can't create temporary script %s: %m", scriptName);
2062
2063
2064 scriptFile = fdopen (fd, "w");
2065 if (!scriptFile)
2066 log_fatal ("can't write script file: %m");
2067 fprintf (scriptFile, "#!/bin/sh\n\n");
2068 if (client) {
2069 if (client -> interface) {
2070 fprintf (scriptFile, "interface=\"%s\"\n",
2071 client -> interface -> name);
2072 fprintf (scriptFile, "export interface\n");
2073 }
2074 if (client -> name)
2075 fprintf (scriptFile, "client=\"%s\"\n",
2076 client -> name);
2077 fprintf (scriptFile, "export client\n");
2078 }
2079 if (medium) {
2080 fprintf (scriptFile, "medium=\"%s\"\n", medium -> string);
2081 fprintf (scriptFile, "export medium\n");
2082 }
2083 fprintf (scriptFile, "reason=\"%s\"\n", reason);
2084 fprintf (scriptFile, "export reason\n");
2085 }
2086
2087 void script_write_params (client, prefix, lease)
2088 struct client_state *client;
2089 const char *prefix;
2090 struct client_lease *lease;
2091 {
2092 int i;
2093 struct data_string data;
2094 struct option_cache *oc;
2095 pair *hash;
2096
2097 fprintf (scriptFile, "%sip_address=\"%s\"\n",
2098 prefix, piaddr (lease -> address));
2099 fprintf (scriptFile, "export %sip_address\n", prefix);
2100
2101 /* For the benefit of Linux (and operating systems which may
2102 have similar needs), compute the network address based on
2103 the supplied ip address and netmask, if provided. Also
2104 compute the broadcast address (the host address all ones
2105 broadcast address, not the host address all zeroes
2106 broadcast address). */
2107
2108 memset (&data, 0, sizeof data);
2109 oc = lookup_option (&dhcp_universe, lease -> options, DHO_SUBNET_MASK);
2110 if (oc && evaluate_option_cache (&data,
2111 (struct packet *)0,
2112 (struct lease *)0,
2113 (struct option_state *)0,
2114 lease -> options,
2115 &global_scope, oc, MDL)) {
2116 if (data.len > 3) {
2117 struct iaddr netmask, subnet, broadcast;
2118
2119 memcpy (netmask.iabuf, data.data, data.len);
2120 netmask.len = data.len;
2121 data_string_forget (&data, MDL);
2122
2123 subnet = subnet_number (lease -> address, netmask);
2124 if (subnet.len) {
2125 fprintf (scriptFile,
2126 "%snetwork_number=\"%s\";\n",
2127 prefix, piaddr (subnet));
2128 fprintf (scriptFile,
2129 "export %snetwork_number\n", prefix);
2130
2131 oc = lookup_option (&dhcp_universe,
2132 lease -> options,
2133 DHO_BROADCAST_ADDRESS);
2134 if (!oc ||
2135 !(evaluate_option_cache
2136 (&data, (struct packet *)0,
2137 (struct lease *)0,
2138 (struct option_state *)0,
2139 lease -> options,
2140 &global_scope, oc, MDL))) {
2141 broadcast = broadcast_addr (subnet,
2142 netmask);
2143 if (broadcast.len) {
2144 fprintf (scriptFile,
2145 "%s%s=\"%s\";\n",
2146 prefix,
2147 "broadcast_address",
2148 piaddr (broadcast));
2149 fprintf (scriptFile,
2150 "export %s%s\n",
2151 prefix,
2152 "broadcast_address");
2153 }
2154 }
2155 }
2156 }
2157 data_string_forget (&data, MDL);
2158 }
2159
2160 if (lease -> filename) {
2161 fprintf (scriptFile, "%sfilename=\"%s\";\n",
2162 prefix, lease -> filename);
2163 fprintf (scriptFile, "export %sfilename\n", prefix);
2164 }
2165 if (lease -> server_name) {
2166 fprintf (scriptFile, "%sserver_name=\"%s\";\n",
2167 prefix, lease -> server_name);
2168 fprintf (scriptFile, "export %sserver_name\n", prefix);
2169 }
2170
2171 execute_statements_in_scope ((struct packet *)0,
2172 (struct lease *)0, lease -> options,
2173 lease -> options, &global_scope,
2174 client -> config -> on_receipt,
2175 (struct group *)0);
2176
2177 hash = lease -> options -> universes [dhcp_universe.index];
2178 for (i = 0; i < OPTION_HASH_SIZE; i++) {
2179 pair hp;
2180
2181 for (hp = hash [i]; hp; hp = hp -> cdr) {
2182 oc = (struct option_cache *)hp -> car;
2183
2184 if (evaluate_option_cache (&data,
2185 (struct packet *)0,
2186 (struct lease *)0,
2187 (struct option_state *)0,
2188 lease -> options,
2189 &global_scope, oc, MDL)) {
2190
2191 if (data.len) {
2192 char *s = (dhcp_option_ev_name
2193 (oc -> option));
2194
2195 fprintf (scriptFile,
2196 "%s%s=\"%s\"\n", prefix, s,
2197 (pretty_print_option
2198 (oc -> option -> code,
2199 data.data, data.len,
2200 0, 0)));
2201 fprintf (scriptFile,
2202 "export %s%s\n", prefix, s);
2203 }
2204 data_string_forget (&data, MDL);
2205 }
2206 }
2207 }
2208 fprintf (scriptFile, "%sexpiry=\"%d\"\n",
2209 prefix, (int)lease -> expiry); /* XXX */
2210 fprintf (scriptFile, "export %sexpiry\n", prefix);
2211 }
2212
2213 int script_go (client)
2214 struct client_state *client;
2215 {
2216 int rval;
2217
2218 if (client)
2219 fprintf (scriptFile, "%s\n",
2220 client -> config -> script_name);
2221 else
2222 fprintf (scriptFile, "%s\n",
2223 top_level_config.script_name);
2224 fprintf (scriptFile, "exit $?\n");
2225 fclose (scriptFile);
2226 chmod (scriptName, 0700);
2227 rval = system (scriptName);
2228 if (!save_scripts)
2229 unlink (scriptName);
2230 return rval;
2231 }
2232
2233 char *dhcp_option_ev_name (option)
2234 struct option *option;
2235 {
2236 static char evbuf [256];
2237 int i;
2238
2239 if (strlen (option -> name) + 1 > sizeof evbuf)
2240 log_fatal ("option %s name is larger than static buffer.",
2241 option -> name);
2242 for (i = 0; option -> name [i]; i++) {
2243 if (option -> name [i] == '-')
2244 evbuf [i] = '_';
2245 else
2246 evbuf [i] = option -> name [i];
2247 }
2248
2249 evbuf [i] = 0;
2250 return evbuf;
2251 }
2252
2253 void go_daemon ()
2254 {
2255 static int state = 0;
2256 int pid;
2257
2258 /* Don't become a daemon if the user requested otherwise. */
2259 if (no_daemon) {
2260 write_client_pid_file ();
2261 return;
2262 }
2263
2264 /* Only do it once. */
2265 if (state)
2266 return;
2267 state = 1;
2268
2269 /* Stop logging to stderr... */
2270 log_perror = 0;
2271
2272 /* Become a daemon... */
2273 if ((pid = fork ()) < 0)
2274 log_fatal ("Can't fork daemon: %m");
2275 else if (pid)
2276 exit (0);
2277 /* Become session leader and get pid... */
2278 pid = setsid ();
2279
2280 /* Close standard I/O descriptors. */
2281 close(0);
2282 close(1);
2283 close(2);
2284
2285 write_client_pid_file ();
2286 }
2287
2288 void write_client_pid_file ()
2289 {
2290 FILE *pf;
2291 int pfdesc;
2292
2293 pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY, 0644);
2294
2295 if (pfdesc < 0) {
2296 log_error ("Can't create %s: %m", path_dhclient_pid);
2297 return;
2298 }
2299
2300 pf = fdopen (pfdesc, "w");
2301 if (!pf)
2302 log_error ("Can't fdopen %s: %m", path_dhclient_pid);
2303 else {
2304 fprintf (pf, "%ld\n", (long)getpid ());
2305 fclose (pf);
2306 }
2307 }
2308
2309 void client_location_changed ()
2310 {
2311 struct interface_info *ip;
2312 struct client_state *client;
2313
2314 for (ip = interfaces; ip; ip = ip -> next) {
2315 for (client = ip -> client; client; client = client -> next) {
2316 switch (client -> state) {
2317 case S_SELECTING:
2318 cancel_timeout (send_discover, client);
2319 break;
2320
2321 case S_BOUND:
2322 cancel_timeout (state_bound, client);
2323 break;
2324
2325 case S_REBOOTING:
2326 case S_REQUESTING:
2327 case S_RENEWING:
2328 cancel_timeout (send_request, client);
2329 break;
2330
2331 case S_INIT:
2332 case S_REBINDING:
2333 break;
2334 }
2335 client -> state = S_INIT;
2336 state_reboot (client);
2337 }
2338 }
2339 }
2340
2341 void do_release(client)
2342 struct client_state *client;
2343 {
2344 /* make_request doesn't initialize xid because it normally comes
2345 from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
2346 so pick an xid now. */
2347 client -> xid = random ();
2348
2349 /* is there even a lease to release? */
2350 if (client -> active) {
2351 /* Make a DHCPRELEASE packet, and set appropriate per-interface
2352 flags. */
2353 make_release (client, client -> active);
2354 client -> destination = iaddr_broadcast;
2355 client -> first_sending = cur_time;
2356 client -> interval = client -> config -> initial_interval;
2357
2358 /* Zap the medium list... */
2359 client -> medium = (struct string_list *)0;
2360
2361 /* Send out the first and only DHCPRELEASE packet. */
2362 send_release (client);
2363 }
2364
2365 /* remove the timeouts for this client */
2366 cancel_timeout (NULL, client);
2367
2368 /* if there was no lease, nothing to "do" */
2369 if (client -> active) {
2370 script_init (client,
2371 "RELEASE", (struct string_list *)0);
2372 if (client -> alias)
2373 script_write_params (client, "alias_",
2374 client -> alias);
2375 script_go (client);
2376 }
2377 }
2378
2379
2380
2381 /* The client should never receive a relay agent information option,
2382 so if it does, log it and discard it. */
2383
2384 int parse_agent_information_option (packet, len, data)
2385 struct packet *packet;
2386 int len;
2387 u_int8_t *data;
2388 {
2389 log_info ("relay agent information option received.");
2390 return 1;
2391 }
2392
2393 /* The client never sends relay agent information options. */
2394
2395 unsigned cons_agent_information_options (cfg_options, outpacket,
2396 agentix, length)
2397 struct option_state *cfg_options;
2398 struct dhcp_packet *outpacket;
2399 unsigned agentix;
2400 unsigned length;
2401 {
2402 return length;
2403 }