6 * Copyright (c) 1995-2000 Internet Software Consortium.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
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.
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";
53 TIME default_lease_time
= 43200; /* 12 hours... */
54 TIME max_lease_time
= 86400; /* 24 hours... */
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
;
60 int dhcp_max_agent_option_packet_length
= 0;
62 int interfaces_requested
= 0;
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
;
70 struct binding_scope global_scope
;
72 /* ASSERT_STATE() does nothing now; it used to be
73 assert (state_is == state_shouldbe). */
74 #define ASSERT_STATE(state_is, state_shouldbe) {}
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";
84 u_int16_t remote_port
;
88 static void usage
PROTO ((void));
90 void do_release(struct client_state
*);
92 int main (argc
, argv
, envp
)
98 struct interface_info
*ip
;
99 struct client_state
*client
;
102 char *server
= (char *)0;
103 char *relay
= (char *)0;
105 int release_mode
= 0;
106 omapi_object_t
*listener
;
110 openlog ("dhclient", LOG_NDELAY
);
111 log_priority
= LOG_DAEMON
;
113 openlog ("dhclient", LOG_NDELAY
, LOG_DAEMON
);
116 #if !(defined (DEBUG) || defined (SYSLOG_4_2) || defined (__CYGWIN32__))
117 setlogmask (LOG_UPTO (LOG_INFO
));
120 for (i
= 1; i
< argc
; i
++) {
121 if (!strcmp (argv
[i
], "-r")) {
124 } else if (!strcmp (argv
[i
], "-p")) {
127 local_port
= htons (atoi (argv
[i
]));
128 log_debug ("binding to user-specified port %d",
130 } else if (!strcmp (argv
[i
], "-d")) {
132 } else if (!strcmp (argv
[i
], "-D")) {
134 } else if (!strcmp (argv
[i
], "-pf")) {
137 path_dhclient_pid
= argv
[i
];
138 } else if (!strcmp (argv
[i
], "-cf")) {
141 path_dhclient_conf
= argv
[i
];
142 } else if (!strcmp (argv
[i
], "-lf")) {
145 path_dhclient_db
= argv
[i
];
146 } else if (!strcmp (argv
[i
], "-q")) {
148 quiet_interface_discovery
= 1;
149 } else if (!strcmp (argv
[i
], "-s")) {
153 } else if (!strcmp (argv
[i
], "-g")) {
157 } else if (!strcmp (argv
[i
], "-n")) {
158 /* do not start up any interfaces */
159 interfaces_requested
= 1;
160 } else if (argv
[i
][0] == '-') {
163 struct interface_info
*tmp
= ((struct interface_info
*)
164 dmalloc (sizeof *tmp
, MDL
));
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;
177 /* first kill of any currently running client */
179 /* XXX inelegant hack to prove concept */
182 #if !defined (NO_SNPRINTF)
183 snprintf (command
, 1024, "kill `cat %s`", path_dhclient_pid
);
185 sprintf (command
, "kill `cat %s`", path_dhclient_pid
);
191 log_info ("%s %s", message
, DHCP_VERSION
);
192 log_info (copyright
);
199 /* If we're given a relay agent address to insert, for testing
200 purposes, figure out what it is. */
202 if (!inet_aton (relay
, &giaddr
)) {
204 he
= gethostbyname (relay
);
206 memcpy (&giaddr
, he
-> h_addr_list
[0],
209 log_fatal ("%s: no such host", relay
);
214 /* Default to the DHCP/BOOTP port. */
216 if (relay
&& giaddr
.s_addr
!= INADDR_LOOPBACK
) {
219 ent
= getservbyname ("dhcpc", "udp");
221 local_port
= htons (68);
223 local_port
= ent
-> s_port
;
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
)
235 remote_port
= htons (ntohs (local_port
) - 1); /* XXX */
237 /* Get the current time... */
238 GET_TIME (&cur_time
);
240 sockaddr_broadcast
.sin_family
= AF_INET
;
241 sockaddr_broadcast
.sin_port
= remote_port
;
243 if (!inet_aton (server
, &sockaddr_broadcast
.sin_addr
)) {
245 he
= gethostbyname (server
);
247 memcpy (&sockaddr_broadcast
.sin_addr
,
248 he
-> h_addr_list
[0],
249 sizeof sockaddr_broadcast
.sin_addr
);
251 sockaddr_broadcast
.sin_addr
.s_addr
=
255 sockaddr_broadcast
.sin_addr
.s_addr
= INADDR_BROADCAST
;
258 inaddr_any
.s_addr
= INADDR_ANY
;
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
));
266 /* Set up the OMAPI wrappers for various server database internal
268 dhclient_db_objects_setup ();
270 /* Discover all the network interfaces. */
271 discover_interfaces (DISCOVER_UNCONFIGURED
);
273 /* Parse the dhclient.conf file. */
276 /* Parse the lease database. */
277 read_client_leases ();
279 /* Rewrite the lease database... */
280 rewrite_client_leases ();
283 /* config_counter(&snd_counter, &rcv_counter); */
285 /* If no broadcast interfaces were discovered, call the script
288 script_init ((struct client_state
*)0, "NBI",
289 (struct string_list
*)0);
290 script_go ((struct client_state
*)0);
292 log_info ("No broadcast interfaces found - exiting.");
294 /* Nothing more to do. */
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
))
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
);
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
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. */
329 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
332 &ip
-> hw_address
.hbuf
[ip
-> hw_address
.hlen
-
333 sizeof seed
], sizeof seed
);
336 srandom (seed
+ cur_time
);
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
) {
345 client
-> state
= S_INIT
;
346 /* Set up a timeout to start the initialization
348 add_timeout (cur_time
+ random () % 5,
349 state_reboot
, client
);
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
));
369 /* Set up the bootp packet handler... */
370 bootp_packet_handler
= do_packet
;
372 /* Start dispatching packets and timeouts... */
381 log_error ("Usage: dhclient [-d] [-D] [-q] [-p <port>] %s",
383 log_error (" [-lf lease-file] [-pf pid-file]%s",
384 "[-cf config-file] [interface]");
387 struct class *find_class (s
)
390 return (struct class *)0;
393 int check_collection (packet
, lease
, collection
)
394 struct packet
*packet
;
396 struct collection
*collection
;
401 void classify (packet
, class)
402 struct packet
*packet
;
407 int unbill_class (lease
, class)
414 struct subnet
*find_subnet (addr
)
417 return (struct subnet
*)0;
420 /* Individual States:
422 * Each routine is called from the dhclient_state_machine() in one of
424 * -> entering INIT state
425 * -> recvpacket_flag == 0: timeout in this state
426 * -> otherwise: received a packet in this state
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.
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.
449 void state_reboot (cpp
)
452 struct client_state
*client
= cpp
;
454 /* If we don't remember an active lease, go straight to INIT. */
455 if (!client
-> active
||
456 client
-> active
-> is_bootp
) {
461 /* We are in the rebooting state. */
462 client
-> state
= S_REBOOTING
;
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 ();
469 /* Make a DHCPREQUEST packet, and set appropriate per-interface
471 make_request (client
, client
-> active
);
472 client
-> destination
= iaddr_broadcast
;
473 client
-> first_sending
= cur_time
;
474 client
-> interval
= client
-> config
-> initial_interval
;
476 /* Zap the medium list... */
477 client
-> medium
= (struct string_list
*)0;
479 /* Send out the first DHCPREQUEST packet. */
480 send_request (client
);
483 /* Called when a lease has completely expired and we've been unable to
486 void state_init (cpp
)
489 struct client_state
*client
= cpp
;
491 ASSERT_STATE(state
, S_INIT
);
493 /* Make a DHCPDISCOVER packet, and set appropriate per-interface
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
;
502 /* Add an immediate timeout to cause the first DHCPDISCOVER packet
504 send_discover (client
);
507 /* state_selecting is called when one or more DHCPOFFER packets have been
508 received and a configurable period of time has passed. */
510 void state_selecting (cpp
)
513 struct client_state
*client
= cpp
;
514 struct client_lease
*lp
, *next
, *picked
;
517 ASSERT_STATE(state
, S_SELECTING
);
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
);
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
) {
531 /* Check to see if we got an ARPREPLY for the address
532 in this particular lease. */
535 picked
-> next
= (struct client_lease
*)0;
538 destroy_client_lease (lp
);
541 client
-> offered_leases
= (struct client_lease
*)0;
543 /* If we just tossed all the leases we were offered, go back
546 client
-> state
= S_INIT
;
551 /* If it was a BOOTREPLY, we can just take the address right now. */
552 if (picked
-> is_bootp
) {
553 client
-> new = picked
;
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;
561 client
-> state
= S_REQUESTING
;
563 /* Bind to the address we received. */
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
;
574 /* Make a DHCPREQUEST packet from the lease we picked. */
575 make_request (client
, picked
);
576 client
-> xid
= client
-> packet
.xid
;
578 /* Toss the lease we picked - we'll get it back in a DHCPACK. */
579 destroy_client_lease (picked
);
581 /* Add an immediate timeout to send the first DHCPREQUEST packet. */
582 send_request (client
);
585 /* state_requesting is called when we receive a DHCPACK message after
586 having sent out one or more DHCPREQUEST packets. */
588 void dhcpack (packet
)
589 struct packet
*packet
;
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
;
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
)
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
))) {
610 log_debug ("DHCPACK in wrong transaction.");
615 if (client
-> state
!= S_REBOOTING
&&
616 client
-> state
!= S_REQUESTING
&&
617 client
-> state
!= S_RENEWING
&&
618 client
-> state
!= S_REBINDING
) {
620 log_debug ("DHCPACK in wrong state.");
625 log_info ("DHCPACK from %s", piaddr (packet
-> client_addr
));
627 lease
= packet_to_lease (packet
);
629 log_info ("packet_to_lease failed.");
633 client
-> new = lease
;
635 /* Stop resending DHCPREQUEST. */
636 cancel_timeout (send_request
, client
);
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
);
643 evaluate_option_cache (&ds
, packet
, (struct lease
*)0,
644 packet
-> options
, client
-> new -> options
,
645 &global_scope
, oc
, MDL
)) {
647 client
-> new -> expiry
= getULong (ds
.data
);
649 client
-> new -> expiry
= 0;
650 data_string_forget (&ds
, MDL
);
652 client
-> new -> expiry
= 0;
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. */
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
);
673 evaluate_option_cache (&ds
, packet
, (struct lease
*)0,
674 packet
-> options
, client
-> new -> options
,
675 &global_scope
, oc
, MDL
)) {
677 client
-> new -> renewal
= getULong (ds
.data
);
679 client
-> new -> renewal
= 0;
680 data_string_forget (&ds
, MDL
);
682 client
-> new -> renewal
= 0;
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;
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)));
694 /* Same deal with the rebind time. */
695 oc
= lookup_option (&dhcp_universe
, client
-> new -> options
,
696 DHO_DHCP_REBINDING_TIME
);
698 evaluate_option_cache (&ds
, packet
, (struct lease
*)0,
699 packet
-> options
, client
-> new -> options
,
700 &global_scope
, oc
, MDL
)) {
702 client
-> new -> rebind
= getULong (ds
.data
);
704 client
-> new -> rebind
= 0;
705 data_string_forget (&ds
, MDL
);
707 client
-> new -> rebind
= 0;
709 if (!client
-> new -> rebind
)
710 client
-> new -> rebind
=
711 (client
-> new -> expiry
* 7) / 8; /* XXX NUMS */
713 /* Make sure our randomness didn't run the renewal time past the
715 if (client
-> new -> renewal
> client
-> new -> rebind
)
716 client
-> new -> renewal
= (client
-> new -> rebind
* 3) / 4;
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
;
732 void bind_lease (client
)
733 struct client_state
*client
;
735 struct interface_info
*ip
= client
-> interface
;
737 /* Remember the medium. */
738 client
-> new -> medium
= client
-> medium
;
740 /* Run the client script with the new parameters. */
741 script_init (client
, (client
-> state
== S_REQUESTING
743 : (client
-> state
== S_RENEWING
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);
752 script_write_params (client
, "alias_", client
-> alias
);
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;
766 /* Write out the new lease. */
767 write_client_lease (client
, client
-> new, 0);
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;
775 /* Set up a timeout to start the renewal process. */
776 add_timeout (client
-> active
-> renewal
,
777 state_bound
, client
);
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 ();
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
792 void state_bound (cpp
)
795 struct client_state
*client
= cpp
;
797 struct option_cache
*oc
;
798 struct data_string ds
;
800 ASSERT_STATE(state
, S_BOUND
);
802 /* T1 has expired. */
803 make_request (client
, client
-> active
);
804 client
-> xid
= client
-> packet
.xid
;
806 memset (&ds
, 0, sizeof ds
);
807 oc
= lookup_option (&dhcp_universe
, client
-> active
-> options
,
808 DHO_DHCP_SERVER_IDENTIFIER
);
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
)) {
815 memcpy (client
-> destination
.iabuf
, ds
.data
, 4);
816 client
-> destination
.len
= 4;
818 client
-> destination
= iaddr_broadcast
;
820 client
-> destination
= iaddr_broadcast
;
822 client
-> first_sending
= cur_time
;
823 client
-> interval
= client
-> config
-> initial_interval
;
824 client
-> state
= S_RENEWING
;
826 /* Send the first packet immediately. */
827 send_request (client
);
835 int write_lease (lease
)
841 int write_host (host
)
842 struct host_decl
*host
;
847 void db_startup (testp
)
853 struct packet
*packet
;
855 struct iaddrlist
*ap
;
857 if (packet
-> raw
-> op
!= BOOTREPLY
)
860 /* If there's a reject list, make sure this packet's sender isn't
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
));
876 struct packet
*packet
;
878 struct iaddrlist
*ap
;
879 void (*handler
) PROTO ((struct packet
*));
882 switch (packet
-> packet_type
) {
902 /* If there's a reject list, make sure this packet's sender isn't
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
));
915 void dhcpoffer (packet
)
916 struct packet
*packet
;
918 struct interface_info
*ip
= packet
-> interface
;
919 struct client_state
*client
;
920 struct client_lease
*lease
, *lp
;
923 const char *name
= packet
-> packet_type
? "DHCPOFFER" : "BOOTREPLY";
924 struct iaddrlist
*ap
;
925 struct option_cache
*oc
;
928 dump_packet (packet
);
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
)
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. */
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
))) {
945 log_debug ("%s in wrong transaction.", name
);
950 log_info ("%s from %s", name
, piaddr (packet
-> client_addr
));
953 /* If this lease doesn't supply the minimum required parameters,
955 if (client
-> config
-> required_options
) {
956 for (i
= 0; client
-> config
-> required_options
[i
]; i
++) {
958 (&dhcp_universe
, packet
-> options
,
959 client
-> config
-> required_options
[i
])) {
960 log_info ("%s isn't satisfactory.", name
);
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
);
976 lease
= packet_to_lease (packet
);
978 log_info ("packet_to_lease failed.");
982 /* If this lease was acquired through a BOOTREPLY, record that
984 if (!packet
-> options_valid
|| !packet
-> packet_type
)
985 lease
-> is_bootp
= 1;
987 /* Record the medium under which this lease was offered. */
988 lease
-> medium
= client
-> medium
;
990 /* Figure out when we're supposed to stop selecting. */
991 stop_selecting
= (client
-> first_sending
+
992 client
-> config
-> select_interval
);
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
;
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
;
1008 for (lp
= client
-> offered_leases
; lp
-> next
;
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
);
1021 add_timeout (stop_selecting
, state_selecting
, client
);
1022 cancel_timeout (send_discover
, client
);
1026 /* Allocate a client_lease structure and initialize it from the parameters
1027 in the specified packet. */
1029 struct client_lease
*packet_to_lease (packet
)
1030 struct packet
*packet
;
1032 struct client_lease
*lease
;
1034 struct option_cache
*oc
;
1035 struct data_string data
;
1037 lease
= (struct client_lease
*)new_client_lease (MDL
);
1040 log_error ("dhcpoffer: no memory to record lease.\n");
1041 return (struct client_lease
*)0;
1044 memset (lease
, 0, sizeof *lease
);
1046 /* Copy the lease options. */
1047 option_state_reference (&lease
-> options
, packet
-> options
, MDL
);
1049 lease
-> address
.len
= sizeof (packet
-> raw
-> yiaddr
);
1050 memcpy (lease
-> address
.iabuf
, &packet
-> raw
-> yiaddr
,
1051 lease
-> address
.len
);
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
);
1058 evaluate_option_cache (&data
, packet
, (struct lease
*)0,
1059 packet
-> options
, lease
-> options
,
1060 &global_scope
, oc
, MDL
)) {
1065 data_string_forget (&data
, MDL
);
1069 /* If the server name was filled out, copy it. */
1070 if (!(i
& 2) && packet
-> raw
-> sname
[0]) {
1072 /* Don't count on the NUL terminator. */
1073 for (len
= 0; len
< 64; len
++)
1074 if (!packet
-> raw
-> sname
[len
])
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;
1082 memcpy (lease
-> server_name
,
1083 packet
-> raw
-> sname
, len
);
1084 lease
-> server_name
[len
] = 0;
1088 /* Ditto for the filename. */
1089 if (!(i
& 1) && packet
-> raw
-> file
[0]) {
1091 /* Don't count on the NUL terminator. */
1092 for (len
= 0; len
< 64; len
++)
1093 if (!packet
-> raw
-> file
[len
])
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;
1101 memcpy (lease
-> filename
,
1102 packet
-> raw
-> file
, len
);
1103 lease
-> filename
[len
] = 0;
1109 void dhcpnak (packet
)
1110 struct packet
*packet
;
1112 struct interface_info
*ip
= packet
-> interface
;
1113 struct client_state
*client
;
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
)
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. */
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
))) {
1128 log_debug ("DHCPNAK in wrong transaction.");
1133 if (client
-> state
!= S_REBOOTING
&&
1134 client
-> state
!= S_REQUESTING
&&
1135 client
-> state
!= S_RENEWING
&&
1136 client
-> state
!= S_REBINDING
) {
1138 log_debug ("DHCPNAK in wrong state.");
1143 log_info ("DHCPNAK from %s", piaddr (packet
-> client_addr
));
1145 if (!client
-> active
) {
1147 log_info ("DHCPNAK with no active lease.\n");
1152 destroy_client_lease (client
-> active
);
1153 client
-> active
= (struct client_lease
*)0;
1155 /* Stop sending DHCPREQUEST packets... */
1156 cancel_timeout (send_request
, client
);
1158 client
-> state
= S_INIT
;
1159 state_init (client
);
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. */
1166 void send_discover (cpp
)
1169 struct client_state
*client
= cpp
;
1175 /* Figure out how long it's been since we started transmitting. */
1176 interval
= cur_time
- client
-> first_sending
;
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
);
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
) {
1192 if (client
-> medium
) {
1193 client
-> medium
= client
-> medium
-> next
;
1196 if (!client
-> medium
) {
1198 log_fatal ("No valid media types for %s!",
1199 client
-> interface
-> name
);
1201 client
-> config
-> media
;
1205 log_info ("Trying medium \"%s\" %d",
1206 client
-> medium
-> string
, increase
);
1207 script_init (client
, "MEDIUM", client
-> medium
);
1208 if (script_go (client
)) {
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. */
1219 if (!client
-> interval
)
1220 client
-> interval
=
1221 client
-> config
-> initial_interval
;
1223 client
-> interval
+=
1225 (2 * client
-> interval
));
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
;
1238 /* If the backoff would take us to the panic timeout, just use that
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;
1246 /* Record the number of seconds since we started sending. */
1247 if (interval
< 65536)
1248 client
-> packet
.secs
= htons (interval
);
1250 client
-> packet
.secs
= htons (65535);
1251 client
-> secs
= client
-> packet
.secs
;
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
);
1258 /* Send out a packet. */
1259 result
= send_packet (client
-> interface
, (struct packet
*)0,
1261 client
-> packet_length
,
1262 inaddr_any
, &sockaddr_broadcast
,
1263 (struct hardware
*)0);
1265 add_timeout (cur_time
+ client
-> interval
, send_discover
, client
);
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. */
1273 void state_panic (cpp
)
1276 struct client_state
*client
= cpp
;
1277 struct client_lease
*loop
;
1278 struct client_lease
*lp
;
1280 loop
= lp
= client
-> active
;
1282 log_info ("No DHCPOFFERS received.");
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
)
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
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_",
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
);
1315 client
-> state
= S_BOUND
;
1316 log_info ("bound: immediate renewal.");
1317 state_bound (client
);
1319 reinitialize_interfaces ();
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;
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
)
1337 lp
-> next
= client
-> active
;
1339 lp
-> next
-> next
= (struct client_lease
*)0;
1341 client
-> active
= client
-> leases
;
1342 client
-> leases
= client
-> leases
-> next
;
1344 /* If we already tried this lease, we've exhausted the
1345 set of leases, so we might as well give up for
1347 if (client
-> active
== loop
)
1350 loop
= client
-> active
;
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
);
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
);
1369 void send_request (cpp
)
1372 struct client_state
*client
= cpp
;
1376 struct sockaddr_in destination
;
1377 struct in_addr from
;
1379 /* Figure out how long it's been since we started transmitting. */
1380 interval
= cur_time
- client
-> first_sending
;
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
) {
1396 client
-> state
= S_INIT
;
1397 cancel_timeout (send_request
, client
);
1398 state_init (client
);
1402 /* If we're in the reboot state, make sure the media is set up
1404 if (client
-> state
== S_REBOOTING
&&
1405 !client
-> medium
&&
1406 client
-> active
-> medium
) {
1407 script_init (client
, "MEDIUM", client
-> active
-> medium
);
1409 /* If the medium we chose won't fly, go to INIT state. */
1410 if (script_go (client
))
1413 /* Record the medium. */
1414 client
-> medium
= client
-> active
-> medium
;
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_",
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_",
1437 client
-> state
= S_INIT
;
1438 state_init (client
);
1442 /* Do the exponential backoff... */
1443 if (!client
-> interval
)
1444 client
-> interval
= client
-> config
-> initial_interval
;
1446 client
-> interval
+= ((random () >> 2) %
1447 (2 * client
-> interval
));
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
));
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;
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
;
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
;
1477 destination
.sin_len
= sizeof destination
;
1480 if (client
-> state
== S_RENEWING
||
1481 client
-> state
== S_REBINDING
)
1482 memcpy (&from
, client
-> active
-> address
.iabuf
,
1485 from
.s_addr
= INADDR_ANY
;
1487 /* Record the number of seconds since we started sending. */
1488 if (client
-> state
== S_REQUESTING
)
1489 client
-> packet
.secs
= client
-> secs
;
1491 if (interval
< 65536)
1492 client
-> packet
.secs
= htons (interval
);
1494 client
-> packet
.secs
= htons (65535);
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
));
1502 if (destination
.sin_addr
.s_addr
!= INADDR_BROADCAST
&&
1504 result
= send_packet (fallback_interface
,
1507 client
-> packet_length
,
1509 (struct hardware
*)0);
1511 /* Send out a packet. */
1512 result
= send_packet (client
-> interface
, (struct packet
*)0,
1514 client
-> packet_length
,
1516 (struct hardware
*)0);
1518 add_timeout (cur_time
+ client
-> interval
,
1519 send_request
, client
);
1522 void send_decline (cpp
)
1525 struct client_state
*client
= cpp
;
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
));
1534 /* Send out a packet. */
1535 result
= send_packet (client
-> interface
, (struct packet
*)0,
1537 client
-> packet_length
,
1538 inaddr_any
, &sockaddr_broadcast
,
1539 (struct hardware
*)0);
1542 void send_release (cpp
)
1545 struct client_state
*client
= cpp
;
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
));
1554 /* Send out a packet. */
1555 result
= send_packet (client
-> interface
, (struct packet
*)0,
1557 client
-> packet_length
,
1558 inaddr_any
, &sockaddr_broadcast
,
1559 (struct hardware
*)0);
1562 void make_client_options (client
, lease
, type
, sid
, rip
, prl
, op
)
1563 struct client_state
*client
;
1564 struct client_lease
*lease
;
1566 struct option_cache
*sid
;
1569 struct option_state
**op
;
1572 struct option_cache
*oc
;
1573 struct buffer
*bp
= (struct buffer
*)0;
1575 /* Allocate space for options. */
1576 option_state_allocate (op
, MDL
);
1578 /* Send the server identifier if provided. */
1580 save_option (&dhcp_universe
, *op
, sid
);
1582 oc
= (struct option_cache
*)0;
1584 /* Send the requested address if provided. */
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.");
1592 save_option (&dhcp_universe
, *op
, oc
);
1593 option_cache_dereference (&oc
, MDL
);
1596 client
-> requested_address
.len
= 0;
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.");
1604 save_option (&dhcp_universe
, *op
, oc
);
1605 option_cache_dereference (&oc
, MDL
);
1609 /* Figure out how many parameters were requested. */
1610 for (i
= 0; prl
[i
]; i
++)
1612 if (!buffer_allocate (&bp
, i
, MDL
))
1613 log_error ("can't make parameter list buffer.");
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
],
1621 log_error ("can't make option cache");
1623 save_option (&dhcp_universe
, *op
, oc
);
1624 option_cache_dereference (&oc
, MDL
);
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),
1635 client
-> config
-> on_transmission
,
1639 void make_discover (client
, lease
)
1640 struct client_state
*client
;
1641 struct client_lease
*lease
;
1643 struct dhcp_packet
*raw
;
1644 unsigned char discover
= DHCPDISCOVER
;
1646 struct option_state
*options
= (struct option_state
*)0;
1648 memset (&client
-> packet
, 0, sizeof (client
-> packet
));
1650 make_client_options (client
,
1651 lease
, &discover
, (struct option_cache
*)0,
1652 lease
? &lease
-> address
: (struct iaddr
*)0,
1653 client
-> config
-> requested_options
,
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
;
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. */
1672 if (can_receive_unicast_unconfigured (client
-> interface
))
1673 client
-> packet
.flags
= 0;
1675 client
-> packet
.flags
= htons (BOOTP_BROADCAST
);
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));
1690 dump_packet (sendpkt
);
1691 dump_raw ((unsigned char *)client
-> packet
,
1692 sendpkt
->packet_length
);
1697 void make_request (client
, lease
)
1698 struct client_state
*client
;
1699 struct client_lease
*lease
;
1701 unsigned char request
= DHCPREQUEST
;
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
;
1708 memset (&client
-> packet
, 0, sizeof (client
-> packet
));
1710 if (client
-> state
== S_REQUESTING
)
1711 oc
= lookup_option (&dhcp_universe
, lease
-> options
,
1712 DHO_DHCP_SERVER_IDENTIFIER
);
1714 oc
= (struct option_cache
*)0;
1716 make_client_options (client
, lease
, &request
, oc
,
1717 ((client
-> state
== S_REQUESTING
||
1718 client
-> state
== S_REBOOTING
)
1720 : (struct iaddr
*)0),
1721 client
-> config
-> requested_options
,
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
;
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. */
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;
1749 memset (&client
-> packet
.ciaddr
, 0,
1750 sizeof client
-> packet
.ciaddr
);
1751 if (can_receive_unicast_unconfigured (client
-> interface
))
1752 client
-> packet
.flags
= 0;
1754 client
-> packet
.flags
= htons (BOOTP_BROADCAST
);
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));
1768 dump_packet (sendpkt
);
1769 dump_raw ((unsigned char *)client
-> packet
, sendpkt
->packet_length
);
1773 void make_decline (client
, lease
)
1774 struct client_state
*client
;
1775 struct client_lease
*lease
;
1777 unsigned char decline
= DHCPDECLINE
;
1779 struct option_cache
*oc
;
1781 struct option_state
*options
= (struct option_state
*)0;
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
);
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
);
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;
1808 client
-> packet
.flags
= htons (BOOTP_BROADCAST
);
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
);
1823 dump_packet (sendpkt
);
1824 dump_raw ((unsigned char *)client
-> packet
, sendpkt
->packet_length
);
1828 void make_release (client
, lease
)
1829 struct client_state
*client
;
1830 struct client_lease
*lease
;
1832 unsigned char request
= DHCPRELEASE
;
1834 struct option_cache
*oc
;
1836 struct option_state
*options
= (struct option_state
*)0;
1838 memset (&client
-> packet
, 0, sizeof (client
-> packet
));
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,
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
);
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
);
1875 dump_packet (sendpkt
);
1876 dump_raw ((unsigned char *)client
-> packet
,
1877 client
-> packet_length
);
1881 void destroy_client_lease (lease
)
1882 struct client_lease
*lease
;
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
);
1896 void rewrite_client_leases ()
1898 struct interface_info
*ip
;
1899 struct client_state
*client
;
1900 struct client_lease
*lp
;
1904 leaseFile
= fopen (path_dhclient_db
, "w");
1906 log_fatal ("can't create %s: %m", path_dhclient_db
);
1908 /* Write out all the leases attached to configured interfaces that
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);
1915 if (client
-> active
)
1916 write_client_lease (client
,
1917 client
-> active
, 1);
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);
1928 if (client
-> active
)
1929 write_client_lease (client
,
1930 client
-> active
, 1);
1936 void write_client_lease (client
, lease
, rewrite
)
1937 struct client_state
*client
;
1938 struct client_lease
*lease
;
1943 static int leases_written
;
1944 struct option_cache
*oc
;
1945 struct data_string ds
;
1949 if (leases_written
++ > 20) {
1950 rewrite_client_leases ();
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
)
1960 if (!leaseFile
) { /* XXX */
1961 leaseFile
= fopen (path_dhclient_db
, "w");
1963 log_fatal ("can't create %s: %m", path_dhclient_db
);
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
);
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",
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
);
1985 memset (&ds
, 0, sizeof ds
);
1987 hash
= lease
-> options
-> universes
[dhcp_universe
.index
];
1988 for (i
= 0; i
< OPTION_HASH_SIZE
; i
++) {
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,
1995 (struct option_state
*)0,
1997 &global_scope
, oc
, MDL
)) {
2000 oc
-> option
-> name
,
2002 (oc
-> option
-> code
,
2003 ds
.data
, ds
.len
, 1, 1));
2004 data_string_forget (&ds
, MDL
);
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
2012 t
= gmtime (&lease
-> renewal
);
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
);
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
);
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");
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];
2040 void script_init (client
, reason
, medium
)
2041 struct client_state
*client
;
2043 struct string_list
*medium
;
2046 #ifndef HAVE_MKSTEMP
2050 strcpy (scriptName
, "/tmp/dcsXXXXXX");
2052 fd
= mkstemp (scriptName
);
2054 if (!mktemp (scriptName
))
2055 log_fatal ("can't create temporary script %s: %m",
2057 fd
= open (scriptName
, O_EXCL
| O_CREAT
| O_WRONLY
, 0600);
2058 } while (fd
< 0 && errno
== EEXIST
);
2061 log_fatal ("can't create temporary script %s: %m", scriptName
);
2064 scriptFile
= fdopen (fd
, "w");
2066 log_fatal ("can't write script file: %m");
2067 fprintf (scriptFile
, "#!/bin/sh\n\n");
2069 if (client
-> interface
) {
2070 fprintf (scriptFile
, "interface=\"%s\"\n",
2071 client
-> interface
-> name
);
2072 fprintf (scriptFile
, "export interface\n");
2075 fprintf (scriptFile
, "client=\"%s\"\n",
2077 fprintf (scriptFile
, "export client\n");
2080 fprintf (scriptFile
, "medium=\"%s\"\n", medium
-> string
);
2081 fprintf (scriptFile
, "export medium\n");
2083 fprintf (scriptFile
, "reason=\"%s\"\n", reason
);
2084 fprintf (scriptFile
, "export reason\n");
2087 void script_write_params (client
, prefix
, lease
)
2088 struct client_state
*client
;
2090 struct client_lease
*lease
;
2093 struct data_string data
;
2094 struct option_cache
*oc
;
2097 fprintf (scriptFile
, "%sip_address=\"%s\"\n",
2098 prefix
, piaddr (lease
-> address
));
2099 fprintf (scriptFile
, "export %sip_address\n", prefix
);
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). */
2108 memset (&data
, 0, sizeof data
);
2109 oc
= lookup_option (&dhcp_universe
, lease
-> options
, DHO_SUBNET_MASK
);
2110 if (oc
&& evaluate_option_cache (&data
,
2113 (struct option_state
*)0,
2115 &global_scope
, oc
, MDL
)) {
2117 struct iaddr netmask
, subnet
, broadcast
;
2119 memcpy (netmask
.iabuf
, data
.data
, data
.len
);
2120 netmask
.len
= data
.len
;
2121 data_string_forget (&data
, MDL
);
2123 subnet
= subnet_number (lease
-> address
, netmask
);
2125 fprintf (scriptFile
,
2126 "%snetwork_number=\"%s\";\n",
2127 prefix
, piaddr (subnet
));
2128 fprintf (scriptFile
,
2129 "export %snetwork_number\n", prefix
);
2131 oc
= lookup_option (&dhcp_universe
,
2133 DHO_BROADCAST_ADDRESS
);
2135 !(evaluate_option_cache
2136 (&data
, (struct packet
*)0,
2138 (struct option_state
*)0,
2140 &global_scope
, oc
, MDL
))) {
2141 broadcast
= broadcast_addr (subnet
,
2143 if (broadcast
.len
) {
2144 fprintf (scriptFile
,
2147 "broadcast_address",
2148 piaddr (broadcast
));
2149 fprintf (scriptFile
,
2152 "broadcast_address");
2157 data_string_forget (&data
, MDL
);
2160 if (lease
-> filename
) {
2161 fprintf (scriptFile
, "%sfilename=\"%s\";\n",
2162 prefix
, lease
-> filename
);
2163 fprintf (scriptFile
, "export %sfilename\n", prefix
);
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
);
2171 execute_statements_in_scope ((struct packet
*)0,
2172 (struct lease
*)0, lease
-> options
,
2173 lease
-> options
, &global_scope
,
2174 client
-> config
-> on_receipt
,
2177 hash
= lease
-> options
-> universes
[dhcp_universe
.index
];
2178 for (i
= 0; i
< OPTION_HASH_SIZE
; i
++) {
2181 for (hp
= hash
[i
]; hp
; hp
= hp
-> cdr
) {
2182 oc
= (struct option_cache
*)hp
-> car
;
2184 if (evaluate_option_cache (&data
,
2187 (struct option_state
*)0,
2189 &global_scope
, oc
, MDL
)) {
2192 char *s
= (dhcp_option_ev_name
2195 fprintf (scriptFile
,
2196 "%s%s=\"%s\"\n", prefix
, s
,
2197 (pretty_print_option
2198 (oc
-> option
-> code
,
2199 data
.data
, data
.len
,
2201 fprintf (scriptFile
,
2202 "export %s%s\n", prefix
, s
);
2204 data_string_forget (&data
, MDL
);
2208 fprintf (scriptFile
, "%sexpiry=\"%d\"\n",
2209 prefix
, (int)lease
-> expiry
); /* XXX */
2210 fprintf (scriptFile
, "export %sexpiry\n", prefix
);
2213 int script_go (client
)
2214 struct client_state
*client
;
2219 fprintf (scriptFile
, "%s\n",
2220 client
-> config
-> script_name
);
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
);
2229 unlink (scriptName
);
2233 char *dhcp_option_ev_name (option
)
2234 struct option
*option
;
2236 static char evbuf
[256];
2239 if (strlen (option
-> name
) + 1 > sizeof evbuf
)
2240 log_fatal ("option %s name is larger than static buffer.",
2242 for (i
= 0; option
-> name
[i
]; i
++) {
2243 if (option
-> name
[i
] == '-')
2246 evbuf
[i
] = option
-> name
[i
];
2255 static int state
= 0;
2258 /* Don't become a daemon if the user requested otherwise. */
2260 write_client_pid_file ();
2264 /* Only do it once. */
2269 /* Stop logging to stderr... */
2272 /* Become a daemon... */
2273 if ((pid
= fork ()) < 0)
2274 log_fatal ("Can't fork daemon: %m");
2277 /* Become session leader and get pid... */
2280 /* Close standard I/O descriptors. */
2285 write_client_pid_file ();
2288 void write_client_pid_file ()
2293 pfdesc
= open (path_dhclient_pid
, O_CREAT
| O_TRUNC
| O_WRONLY
, 0644);
2296 log_error ("Can't create %s: %m", path_dhclient_pid
);
2300 pf
= fdopen (pfdesc
, "w");
2302 log_error ("Can't fdopen %s: %m", path_dhclient_pid
);
2304 fprintf (pf
, "%ld\n", (long)getpid ());
2309 void client_location_changed ()
2311 struct interface_info
*ip
;
2312 struct client_state
*client
;
2314 for (ip
= interfaces
; ip
; ip
= ip
-> next
) {
2315 for (client
= ip
-> client
; client
; client
= client
-> next
) {
2316 switch (client
-> state
) {
2318 cancel_timeout (send_discover
, client
);
2322 cancel_timeout (state_bound
, client
);
2328 cancel_timeout (send_request
, client
);
2335 client
-> state
= S_INIT
;
2336 state_reboot (client
);
2341 void do_release(client
)
2342 struct client_state
*client
;
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 ();
2349 /* is there even a lease to release? */
2350 if (client
-> active
) {
2351 /* Make a DHCPRELEASE packet, and set appropriate per-interface
2353 make_release (client
, client
-> active
);
2354 client
-> destination
= iaddr_broadcast
;
2355 client
-> first_sending
= cur_time
;
2356 client
-> interval
= client
-> config
-> initial_interval
;
2358 /* Zap the medium list... */
2359 client
-> medium
= (struct string_list
*)0;
2361 /* Send out the first and only DHCPRELEASE packet. */
2362 send_release (client
);
2365 /* remove the timeouts for this client */
2366 cancel_timeout (NULL
, client
);
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_",
2381 /* The client should never receive a relay agent information option,
2382 so if it does, log it and discard it. */
2384 int parse_agent_information_option (packet
, len
, data
)
2385 struct packet
*packet
;
2389 log_info ("relay agent information option received.");
2393 /* The client never sends relay agent information options. */
2395 unsigned cons_agent_information_options (cfg_options
, outpacket
,
2397 struct option_state
*cfg_options
;
2398 struct dhcp_packet
*outpacket
;