Import initial version of 1:1 pthread library.
[dragonfly.git] / contrib / dhcp-3.0 / server / dhcp.c
1 /* dhcp.c
2
3    DHCP Protocol engine. */
4
5 /*
6  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
7  * Copyright (c) 1995-2003 by Internet Software Consortium
8  *
9  * Permission to use, copy, modify, and distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
19  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  *
21  *   Internet Systems Consortium, Inc.
22  *   950 Charter Street
23  *   Redwood City, CA 94063
24  *   <info@isc.org>
25  *   http://www.isc.org/
26  *
27  * This software has been written for Internet Systems Consortium
28  * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
29  * To learn more about Internet Systems Consortium, see
30  * ``http://www.isc.org/''.  To learn more about Vixie Enterprises,
31  * see ``http://www.vix.com''.   To learn more about Nominum, Inc., see
32  * ``http://www.nominum.com''.
33  */
34
35 #ifndef lint
36 static char copyright[] =
37 "$Id: dhcp.c,v 1.192.2.44 2004/11/24 17:39:19 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium.  All rights reserved.\n";
38 #endif /* not lint */
39
40 #include "dhcpd.h"
41
42 int outstanding_pings;
43
44 static char dhcp_message [256];
45
46 static const char *dhcp_type_names [] = { 
47         "DHCPDISCOVER",
48         "DHCPOFFER",
49         "DHCPREQUEST",
50         "DHCPDECLINE",
51         "DHCPACK",
52         "DHCPNAK",
53         "DHCPRELEASE",
54         "DHCPINFORM"
55 };
56 const int dhcp_type_name_max = ((sizeof dhcp_type_names) / sizeof (char *));
57
58 #if defined (TRACING)
59 # define send_packet trace_packet_send
60 #endif
61
62 void dhcp (packet)
63         struct packet *packet;
64 {
65         int ms_nulltp = 0;
66         struct option_cache *oc;
67         struct lease *lease = (struct lease *)0;
68         const char *errmsg;
69         struct data_string data;
70
71         if (!locate_network (packet) &&
72             packet -> packet_type != DHCPREQUEST &&
73             packet -> packet_type != DHCPINFORM) {
74                 const char *s;
75                 char typebuf [32];
76                 errmsg = "unknown network segment";
77               bad_packet:
78                 
79                 if (packet -> packet_type > 0 &&
80                     packet -> packet_type < dhcp_type_name_max - 1) {
81                         s = dhcp_type_names [packet -> packet_type - 1];
82                 } else {
83                         /* %Audit% Cannot exceed 28 bytes. %2004.06.17,Safe% */
84                         sprintf (typebuf, "type %d", packet -> packet_type);
85                         s = typebuf;
86                 }
87                 
88                 log_info ("%s from %s via %s: %s", s,
89                           (packet -> raw -> htype
90                            ? print_hw_addr (packet -> raw -> htype,
91                                             packet -> raw -> hlen,
92                                             packet -> raw -> chaddr)
93                            : "<no identifier>"),
94                           packet -> raw -> giaddr.s_addr
95                           ? inet_ntoa (packet -> raw -> giaddr)
96                           : packet -> interface -> name, errmsg);
97                 goto out;
98         }
99
100         /* There is a problem with the relay agent information option,
101            which is that in order for a normal relay agent to append
102            this option, the relay agent has to have been involved in
103            getting the packet from the client to the server.  Note
104            that this is the software entity known as the relay agent,
105            _not_ the hardware entity known as a router in which the
106            relay agent may be running, so the fact that a router has
107            forwarded a packet does not mean that the relay agent in
108            the router was involved.
109
110            So when the client is in INIT or INIT-REBOOT or REBINDING
111            state, the relay agent gets to tack on its options, but
112            when it's not, the relay agent doesn't get to do this,
113            which means that any decisions the DHCP server may make
114            based on the agent options will be made incorrectly.  
115
116            We work around this in the following way: if this is a
117            DHCPREQUEST and doesn't have relay agent information
118            options, we see if there's an existing lease for this IP
119            address and this client that _does_ have stashed agent
120            options.   If so, then we tack those options onto the
121            packet as if they came from the client.   Later on, when we
122            are deciding whether to steal the agent options from the
123            packet, if the agent options stashed on the lease are the
124            same as those stashed on the packet, we don't steal them -
125            this ensures that the client never receives its agent
126            options. */
127
128         if (packet -> packet_type == DHCPREQUEST &&
129             packet -> raw -> ciaddr.s_addr &&
130             !packet -> raw -> giaddr.s_addr &&
131             (packet -> options -> universe_count < agent_universe.index ||
132              !packet -> options -> universes [agent_universe.index]))
133         {
134                 struct iaddr cip;
135
136                 cip.len = sizeof packet -> raw -> ciaddr;
137                 memcpy (cip.iabuf, &packet -> raw -> ciaddr,
138                         sizeof packet -> raw -> ciaddr);
139                 if (!find_lease_by_ip_addr (&lease, cip, MDL))
140                         goto nolease;
141
142                 /* If there are no agent options on the lease, it's not
143                    interesting. */
144                 if (!lease -> agent_options)
145                         goto nolease;
146
147                 /* The client should not be unicasting a renewal if its lease
148                    has expired, so make it go through the process of getting
149                    its agent options legally. */
150                 if (lease -> ends < cur_time)
151                         goto nolease;
152
153                 if (lease -> uid_len) {
154                         oc = lookup_option (&dhcp_universe, packet -> options,
155                                             DHO_DHCP_CLIENT_IDENTIFIER);
156                         if (!oc)
157                                 goto nolease;
158
159                         memset (&data, 0, sizeof data);
160                         if (!evaluate_option_cache (&data,
161                                                     packet, (struct lease *)0,
162                                                     (struct client_state *)0,
163                                                     packet -> options,
164                                                     (struct option_state *)0,
165                                                     &global_scope, oc, MDL))
166                                 goto nolease;
167                         if (lease -> uid_len != data.len ||
168                             memcmp (lease -> uid, data.data, data.len)) {
169                                 data_string_forget (&data, MDL);
170                                 goto nolease;
171                         }
172                         data_string_forget (&data, MDL);
173                 } else
174                         if ((lease -> hardware_addr.hbuf [0] !=
175                              packet -> raw -> htype) ||
176                             (lease -> hardware_addr.hlen - 1 !=
177                              packet -> raw -> hlen) ||
178                             memcmp (&lease -> hardware_addr.hbuf [1],
179                                     packet -> raw -> chaddr,
180                                     packet -> raw -> hlen))
181                                 goto nolease;
182
183                 /* Okay, so we found a lease that matches the client. */
184                 option_chain_head_reference ((struct option_chain_head **)
185                                              &(packet -> options -> universes
186                                                [agent_universe.index]),
187                                              lease -> agent_options, MDL);
188         }
189       nolease:
190
191         /* Classify the client. */
192         if ((oc = lookup_option (&dhcp_universe, packet -> options,
193                                  DHO_HOST_NAME))) {
194                 if (!oc -> expression)
195                         while (oc -> data.len &&
196                                oc -> data.data [oc -> data.len - 1] == 0) {
197                                 ms_nulltp = 1;
198                                 oc -> data.len--;
199                         }
200         }
201
202         classify_client (packet);
203
204         switch (packet -> packet_type) {
205               case DHCPDISCOVER:
206                 dhcpdiscover (packet, ms_nulltp);
207                 break;
208
209               case DHCPREQUEST:
210                 dhcprequest (packet, ms_nulltp, lease);
211                 break;
212
213               case DHCPRELEASE:
214                 dhcprelease (packet, ms_nulltp);
215                 break;
216
217               case DHCPDECLINE:
218                 dhcpdecline (packet, ms_nulltp);
219                 break;
220
221               case DHCPINFORM:
222                 dhcpinform (packet, ms_nulltp);
223                 break;
224
225
226               case DHCPACK:
227               case DHCPOFFER:
228               case DHCPNAK:
229                 break;
230
231               default:
232                 errmsg = "unknown packet type";
233                 goto bad_packet;
234         }
235       out:
236         if (lease)
237                 lease_dereference (&lease, MDL);
238 }
239
240 void dhcpdiscover (packet, ms_nulltp)
241         struct packet *packet;
242         int ms_nulltp;
243 {
244         struct lease *lease = (struct lease *)0;
245         char msgbuf [1024]; /* XXX */
246         TIME when;
247         const char *s;
248         int allocatedp = 0;
249         int peer_has_leases = 0;
250         int alloc_lease_called = 0;
251 #if defined (FAILOVER_PROTOCOL)
252         dhcp_failover_state_t *peer;
253 #endif
254
255         find_lease (&lease, packet, packet -> shared_network,
256                     0, &allocatedp, (struct lease *)0, MDL);
257
258         if (lease && lease -> client_hostname) {
259                 if ((strlen (lease -> client_hostname) <= 64) &&
260                     db_printable (lease -> client_hostname))
261                         s = lease -> client_hostname;
262                 else
263                         s = "Hostname Unsuitable for Printing";
264         } else
265                 s = (char *)0;
266
267         /* %Audit% This is log output. %2004.06.17,Safe%
268          * If we truncate we hope the user can get a hint from the log.
269          */
270         snprintf (msgbuf, sizeof msgbuf, "DHCPDISCOVER from %s %s%s%svia %s",
271                  (packet -> raw -> htype
272                   ? print_hw_addr (packet -> raw -> htype,
273                                    packet -> raw -> hlen,
274                                    packet -> raw -> chaddr)
275                   : (lease
276                      ? print_hex_1 (lease -> uid_len, lease -> uid, 
277                                     lease -> uid_len)
278                      : "<no identifier>")),
279                   s ? "(" : "", s ? s : "", s ? ") " : "",
280                   packet -> raw -> giaddr.s_addr
281                   ? inet_ntoa (packet -> raw -> giaddr)
282                   : packet -> interface -> name);
283
284         /* Sourceless packets don't make sense here. */
285         if (!packet -> shared_network) {
286                 log_info ("Packet from unknown subnet: %s",
287                       inet_ntoa (packet -> raw -> giaddr));
288                 goto out;
289         }
290
291 #if defined (FAILOVER_PROTOCOL)
292         if (lease && lease -> pool && lease -> pool -> failover_peer) {
293                 peer = lease -> pool -> failover_peer;
294
295                 /* If the lease is ours to allocate, then allocate it,
296                    but set the allocatedp flag. */
297                 if (lease_mine_to_reallocate (lease))
298                         allocatedp = 1;
299
300                 /* If the lease is active, do load balancing to see who
301                    allocates the lease (if it's active, it already belongs
302                    to the client, or we wouldn't have gotten it from
303                    find_lease (). */
304                 else if (lease -> binding_state == FTS_ACTIVE &&
305                          (peer -> service_state != cooperating ||
306                           load_balance_mine (packet, peer)))
307                         ;
308
309                 /* Otherwise, we can't let the client have this lease. */
310                 else {
311 #if defined (DEBUG_FIND_LEASE)
312                     log_debug ("discarding %s - %s",
313                                piaddr (lease -> ip_addr),
314                                binding_state_print (lease -> binding_state));
315 #endif
316                     lease_dereference (&lease, MDL);
317                 }
318         }
319 #endif
320
321         /* If we didn't find a lease, try to allocate one... */
322         if (!lease) {
323                 if (!allocate_lease (&lease, packet,
324                                      packet -> shared_network -> pools, 
325                                      &peer_has_leases)) {
326                         if (peer_has_leases)
327                                 log_error ("%s: peer holds all free leases",
328                                            msgbuf);
329                         else
330                                 log_error ("%s: network %s: no free leases",
331                                            msgbuf,
332                                            packet -> shared_network -> name);
333                         return;
334                 }
335 #if defined (FAILOVER_PROTOCOL)
336                 if (lease -> pool && lease -> pool -> failover_peer)
337                         dhcp_failover_pool_check (lease -> pool);
338 #endif
339                 allocatedp = 1;
340                 alloc_lease_called = 1;
341         }
342
343 #if defined (FAILOVER_PROTOCOL)
344         if (lease && lease -> pool && lease -> pool -> failover_peer) {
345                 peer = lease -> pool -> failover_peer;
346                 if (peer -> service_state == not_responding ||
347                     peer -> service_state == service_startup) {
348                         log_info ("%s: not responding%s",
349                                   msgbuf, peer -> nrr);
350                         goto out;
351                 }
352         } else
353                 peer = (dhcp_failover_state_t *)0;
354
355         /* Do load balancing if configured. */
356         /* If the lease is newly allocated, and we're not the server that
357            the client would normally get with load balancing, and the
358            failover protocol state is normal, let the other server get this.
359            XXX Check protocol spec to make sure that predicating this on
360            XXX allocatedp is okay - I'm doing this so that the client won't
361            XXX be forced to switch servers (and IP addresses) just because
362            XXX of bad luck, when it's possible for it to get the address it
363            XXX is requesting.    Not sure this is allowed.  */
364         if (allocatedp && peer && (peer -> service_state == cooperating) &&
365             !load_balance_mine (packet, peer)) {
366                 /* peer_has_leases only has a chance to be set if we called
367                  * allocate_lease() above.
368                  */
369                 if (!alloc_lease_called || peer_has_leases) {
370                         log_debug ("%s: load balance to peer %s",
371                                    msgbuf, peer -> name);
372                         goto out;
373                 } else {
374                         log_debug ("cancel load balance to peer %s - %s",
375                                    peer -> name, "no free leases");
376                 }
377         }
378 #endif
379
380         /* If it's an expired lease, get rid of any bindings. */
381         if (lease -> ends < cur_time && lease -> scope)
382                 binding_scope_dereference (&lease -> scope, MDL);
383
384         /* Set the lease to really expire in 2 minutes, unless it has
385            not yet expired, in which case leave its expiry time alone. */
386         when = cur_time + 120;
387         if (when < lease -> ends)
388                 when = lease -> ends;
389
390         ack_lease (packet, lease, DHCPOFFER, when, msgbuf, ms_nulltp);
391       out:
392         if (lease)
393                 lease_dereference (&lease, MDL);
394 }
395
396 void dhcprequest (packet, ms_nulltp, ip_lease)
397         struct packet *packet;
398         int ms_nulltp;
399         struct lease *ip_lease;
400 {
401         struct lease *lease;
402         struct iaddr cip;
403         struct iaddr sip;
404         struct subnet *subnet;
405         int ours = 0;
406         struct option_cache *oc;
407         struct data_string data;
408         int status;
409         char msgbuf [1024]; /* XXX */
410         const char *s;
411         char smbuf [19];
412 #if defined (FAILOVER_PROTOCOL)
413         dhcp_failover_state_t *peer;
414 #endif
415         int have_server_identifier = 0;
416         int have_requested_addr = 0;
417
418         oc = lookup_option (&dhcp_universe, packet -> options,
419                             DHO_DHCP_REQUESTED_ADDRESS);
420         memset (&data, 0, sizeof data);
421         if (oc &&
422             evaluate_option_cache (&data, packet, (struct lease *)0,
423                                    (struct client_state *)0,
424                                    packet -> options, (struct option_state *)0,
425                                    &global_scope, oc, MDL)) {
426                 cip.len = 4;
427                 memcpy (cip.iabuf, data.data, 4);
428                 data_string_forget (&data, MDL);
429                 have_requested_addr = 1;
430         } else {
431                 oc = (struct option_cache *)0;
432                 cip.len = 4;
433                 memcpy (cip.iabuf, &packet -> raw -> ciaddr.s_addr, 4);
434         }
435
436         /* Find the lease that matches the address requested by the
437            client. */
438
439         subnet = (struct subnet *)0;
440         lease = (struct lease *)0;
441         if (find_subnet (&subnet, cip, MDL))
442                 find_lease (&lease, packet,
443                             subnet -> shared_network, &ours, 0, ip_lease, MDL);
444         /* XXX consider using allocatedp arg to find_lease to see
445            XXX that this isn't a compliant DHCPREQUEST. */
446
447         if (lease && lease -> client_hostname) {
448                 if ((strlen (lease -> client_hostname) <= 64) &&
449                     db_printable (lease -> client_hostname))
450                         s = lease -> client_hostname;
451                 else
452                         s = "Hostname Unsuitable for Printing";
453         } else
454                 s = (char *)0;
455
456         oc = lookup_option (&dhcp_universe, packet -> options,
457                             DHO_DHCP_SERVER_IDENTIFIER);
458         memset (&data, 0, sizeof data);
459         if (oc &&
460             evaluate_option_cache (&data, packet, (struct lease *)0,
461                                    (struct client_state *)0,
462                                    packet -> options, (struct option_state *)0,
463                                    &global_scope, oc, MDL)) {
464                 sip.len = 4;
465                 memcpy (sip.iabuf, data.data, 4);
466                 data_string_forget (&data, MDL);
467                 /* piaddr() should not return more than a 15 byte string.
468                  * safe.
469                  */
470                 sprintf (smbuf, " (%s)", piaddr (sip));
471                 have_server_identifier = 1;
472         } else
473                 smbuf [0] = 0;
474
475         /* %Audit% This is log output. %2004.06.17,Safe%
476          * If we truncate we hope the user can get a hint from the log.
477          */
478         snprintf (msgbuf, sizeof msgbuf,
479                  "DHCPREQUEST for %s%s from %s %s%s%svia %s",
480                  piaddr (cip), smbuf,
481                  (packet -> raw -> htype
482                   ? print_hw_addr (packet -> raw -> htype,
483                                    packet -> raw -> hlen,
484                                    packet -> raw -> chaddr)
485                   : (lease
486                      ? print_hex_1 (lease -> uid_len, lease -> uid, 
487                                     lease -> uid_len)
488                      : "<no identifier>")),
489                  s ? "(" : "", s ? s : "", s ? ") " : "",
490                   packet -> raw -> giaddr.s_addr
491                   ? inet_ntoa (packet -> raw -> giaddr)
492                   : packet -> interface -> name);
493
494 #if defined (FAILOVER_PROTOCOL)
495         if (lease && lease -> pool && lease -> pool -> failover_peer) {
496                 peer = lease -> pool -> failover_peer;
497                 if (peer -> service_state == not_responding ||
498                     peer -> service_state == service_startup) {
499                         log_info ("%s: not responding%s",
500                                   msgbuf, peer -> nrr);
501                         goto out;
502                 }
503                 /* Don't load balance if the client is RENEWING or REBINDING.
504                    If it's RENEWING, we are the only server to hear it, so
505                    we have to serve it.   If it's REBINDING, it's out of
506                    communication with the other server, so there's no point
507                    in waiting to serve it.    However, if the lease we're
508                    offering is not a free lease, then we may be the only
509                    server that can offer it, so we can't load balance if
510                    the lease isn't in the free or backup state. */
511                 if (peer -> service_state == cooperating &&
512                     !packet -> raw -> ciaddr.s_addr &&
513                     (lease -> binding_state == FTS_FREE ||
514                      lease -> binding_state == FTS_BACKUP)) {
515                         if (!load_balance_mine (packet, peer)) {
516                                 log_debug ("%s: load balance to peer %s",
517                                            msgbuf, peer -> name);
518                                 goto out;
519                         }
520                 }
521
522                 /* Don't let a client allocate a lease using DHCPREQUEST
523                    if the lease isn't ours to allocate. */
524                 if ((lease -> binding_state == FTS_FREE ||
525                      lease -> binding_state == FTS_BACKUP) &&
526                     !lease_mine_to_reallocate (lease)) {
527                         log_debug ("%s: lease owned by peer", msgbuf);
528                         goto out;
529                 }
530
531                 /* If the lease is in a transitional state, we can't
532                    renew it. */
533                 if ((lease -> binding_state == FTS_RELEASED ||
534                      lease -> binding_state == FTS_EXPIRED) &&
535                     !lease_mine_to_reallocate (lease)) {
536                         log_debug ("%s: lease in transition state %s", msgbuf,
537                                    lease -> binding_state == FTS_RELEASED
538                                    ? "released" : "expired");
539                         goto out;
540                 }
541
542                 /* It's actually very unlikely that we'll ever get here,
543                    but if we do, tell the client to stop using the lease,
544                    because the administrator reset it. */
545                 if (lease -> binding_state == FTS_RESET &&
546                     !lease_mine_to_reallocate (lease)) {
547                         log_debug ("%s: lease reset by administrator", msgbuf);
548                         nak_lease (packet, &cip);
549                         goto out;
550                 }
551
552                 /* At this point it's possible that we will get a broadcast
553                    DHCPREQUEST for a lease that we didn't offer, because
554                    both we and the peer are in a position to offer it.
555                    In that case, we probably shouldn't answer.   In order
556                    to not answer, we would have to compare the server
557                    identifier sent by the client with the list of possible
558                    server identifiers we can send, and if the client's
559                    identifier isn't on the list, drop the DHCPREQUEST.
560                    We aren't currently doing that for two reasons - first,
561                    it's not clear that all clients do the right thing
562                    with respect to sending the client identifier, which
563                    could mean that we might simply not respond to a client
564                    that is depending on us to respond.   Secondly, we allow
565                    the user to specify the server identifier to send, and
566                    we don't enforce that the server identifier should be
567                    one of our IP addresses.   This is probably not a big
568                    deal, but it's theoretically an issue.
569
570                    The reason we care about this is that if both servers
571                    send a DHCPACK to the DHCPREQUEST, they are then going
572                    to send dueling BNDUPD messages, which could cause
573                    trouble.   I think it causes no harm, but it seems
574                    wrong. */
575         } else
576                 peer = (dhcp_failover_state_t *)0;
577 #endif
578
579         /* If a client on a given network REQUESTs a lease on an
580            address on a different network, NAK it.  If the Requested
581            Address option was used, the protocol says that it must
582            have been broadcast, so we can trust the source network
583            information.
584
585            If ciaddr was specified and Requested Address was not, then
586            we really only know for sure what network a packet came from
587            if it came through a BOOTP gateway - if it came through an
588            IP router, we'll just have to assume that it's cool.
589
590            If we don't think we know where the packet came from, it
591            came through a gateway from an unknown network, so it's not
592            from a RENEWING client.  If we recognize the network it
593            *thinks* it's on, we can NAK it even though we don't
594            recognize the network it's *actually* on; otherwise we just
595            have to ignore it.
596
597            We don't currently try to take advantage of access to the
598            raw packet, because it's not available on all platforms.
599            So a packet that was unicast to us through a router from a
600            RENEWING client is going to look exactly like a packet that
601            was broadcast to us from an INIT-REBOOT client.
602
603            Since we can't tell the difference between these two kinds
604            of packets, if the packet appears to have come in off the
605            local wire, we have to treat it as if it's a RENEWING
606            client.  This means that we can't NAK a RENEWING client on
607            the local wire that has a bogus address.  The good news is
608            that we won't ACK it either, so it should revert to INIT
609            state and send us a DHCPDISCOVER, which we *can* work with.
610
611            Because we can't detect that a RENEWING client is on the
612            wrong wire, it's going to sit there trying to renew until
613            it gets to the REBIND state, when we *can* NAK it because
614            the packet will get to us through a BOOTP gateway.  We
615            shouldn't actually see DHCPREQUEST packets from RENEWING
616            clients on the wrong wire anyway, since their idea of their
617            local router will be wrong.  In any case, the protocol
618            doesn't really allow us to NAK a DHCPREQUEST from a
619            RENEWING client, so we can punt on this issue. */
620
621         if (!packet -> shared_network ||
622             (packet -> raw -> ciaddr.s_addr &&
623              packet -> raw -> giaddr.s_addr) ||
624             (have_requested_addr && !packet -> raw -> ciaddr.s_addr)) {
625                 
626                 /* If we don't know where it came from but we do know
627                    where it claims to have come from, it didn't come
628                    from there. */
629                 if (!packet -> shared_network) {
630                         if (subnet && subnet -> group -> authoritative) {
631                                 log_info ("%s: wrong network.", msgbuf);
632                                 nak_lease (packet, &cip);
633                                 goto out;
634                         }
635                         /* Otherwise, ignore it. */
636                         log_info ("%s: ignored (%s).", msgbuf,
637                                   (subnet
638                                    ? "not authoritative" : "unknown subnet"));
639                         goto out;
640                 }
641
642                 /* If we do know where it came from and it asked for an
643                    address that is not on that shared network, nak it. */
644                 if (subnet)
645                         subnet_dereference (&subnet, MDL);
646                 if (!find_grouped_subnet (&subnet, packet -> shared_network,
647                                           cip, MDL)) {
648                         if (packet -> shared_network -> group -> authoritative)
649                         {
650                                 log_info ("%s: wrong network.", msgbuf);
651                                 nak_lease (packet, &cip);
652                                 goto out;
653                         }
654                         log_info ("%s: ignored (not authoritative).", msgbuf);
655                         return;
656                 }
657         }
658
659         /* If the address the client asked for is ours, but it wasn't
660            available for the client, NAK it. */
661         if (!lease && ours) {
662                 log_info ("%s: lease %s unavailable.", msgbuf, piaddr (cip));
663                 nak_lease (packet, &cip);
664                 goto out;
665         }
666
667         /* Otherwise, send the lease to the client if we found one. */
668         if (lease) {
669                 ack_lease (packet, lease, DHCPACK, 0, msgbuf, ms_nulltp);
670         } else
671                 log_info ("%s: unknown lease %s.", msgbuf, piaddr (cip));
672
673       out:
674         if (subnet)
675                 subnet_dereference (&subnet, MDL);
676         if (lease)
677                 lease_dereference (&lease, MDL);
678         return;
679 }
680
681 void dhcprelease (packet, ms_nulltp)
682         struct packet *packet;
683         int ms_nulltp;
684 {
685         struct lease *lease = (struct lease *)0, *next = (struct lease *)0;
686         struct iaddr cip;
687         struct option_cache *oc;
688         struct data_string data;
689         const char *s;
690         char msgbuf [1024], cstr[16]; /* XXX */
691
692
693         /* DHCPRELEASE must not specify address in requested-address
694            option, but old protocol specs weren't explicit about this,
695            so let it go. */
696         if ((oc = lookup_option (&dhcp_universe, packet -> options,
697                                  DHO_DHCP_REQUESTED_ADDRESS))) {
698                 log_info ("DHCPRELEASE from %s specified requested-address.",
699                       print_hw_addr (packet -> raw -> htype,
700                                      packet -> raw -> hlen,
701                                      packet -> raw -> chaddr));
702         }
703
704         oc = lookup_option (&dhcp_universe, packet -> options,
705                             DHO_DHCP_CLIENT_IDENTIFIER);
706         memset (&data, 0, sizeof data);
707         if (oc &&
708             evaluate_option_cache (&data, packet, (struct lease *)0,
709                                    (struct client_state *)0,
710                                    packet -> options, (struct option_state *)0,
711                                    &global_scope, oc, MDL)) {
712                 find_lease_by_uid (&lease, data.data, data.len, MDL);
713                 data_string_forget (&data, MDL);
714
715                 /* See if we can find a lease that matches the IP address
716                    the client is claiming. */
717                 while (lease) {
718                         if (lease -> n_uid)
719                                 lease_reference (&next, lease -> n_uid, MDL);
720                         if (!memcmp (&packet -> raw -> ciaddr,
721                                      lease -> ip_addr.iabuf, 4)) {
722                                 break;
723                         }
724                         lease_dereference (&lease, MDL);
725                         if (next) {
726                                 lease_reference (&lease, next, MDL);
727                                 lease_dereference (&next, MDL);
728                         }
729                 }
730                 if (next)
731                         lease_dereference (&next, MDL);
732         }
733
734         /* The client is supposed to pass a valid client-identifier,
735            but the spec on this has changed historically, so try the
736            IP address in ciaddr if the client-identifier fails. */
737         if (!lease) {
738                 cip.len = 4;
739                 memcpy (cip.iabuf, &packet -> raw -> ciaddr, 4);
740                 find_lease_by_ip_addr (&lease, cip, MDL);
741         }
742
743
744         /* If the hardware address doesn't match, don't do the release. */
745         if (lease &&
746             (lease -> hardware_addr.hlen != packet -> raw -> hlen + 1 ||
747              lease -> hardware_addr.hbuf [0] != packet -> raw -> htype ||
748              memcmp (&lease -> hardware_addr.hbuf [1],
749                      packet -> raw -> chaddr, packet -> raw -> hlen)))
750                 lease_dereference (&lease, MDL);
751
752         if (lease && lease -> client_hostname) {
753                 if ((strlen (lease -> client_hostname) <= 64) &&
754                     db_printable (lease -> client_hostname))
755                         s = lease -> client_hostname;
756                 else
757                         s = "Hostname Unsuitable for Printing";
758         } else
759                 s = (char *)0;
760
761         /* %Audit% Cannot exceed 16 bytes. %2004.06.17,Safe%
762          * We copy this out to stack because we actually want to log two
763          * inet_ntoa()'s in this message.
764          */
765         strncpy(cstr, inet_ntoa (packet -> raw -> ciaddr), 15);
766         cstr[15] = '\0';
767
768         /* %Audit% This is log output. %2004.06.17,Safe%
769          * If we truncate we hope the user can get a hint from the log.
770          */
771         snprintf (msgbuf, sizeof msgbuf,
772                  "DHCPRELEASE of %s from %s %s%s%svia %s (%sfound)",
773                  cstr,
774                  (packet -> raw -> htype
775                   ? print_hw_addr (packet -> raw -> htype,
776                                    packet -> raw -> hlen,
777                                    packet -> raw -> chaddr)
778                   : (lease
779                      ? print_hex_1 (lease -> uid_len, lease -> uid, 
780                                     lease -> uid_len)
781                      : "<no identifier>")),
782                  s ? "(" : "", s ? s : "", s ? ") " : "",
783                  packet -> raw -> giaddr.s_addr
784                  ? inet_ntoa (packet -> raw -> giaddr)
785                  : packet -> interface -> name,
786                  lease ? "" : "not ");
787
788 #if defined (FAILOVER_PROTOCOL)
789         if (lease && lease -> pool && lease -> pool -> failover_peer) {
790                 dhcp_failover_state_t *peer = lease -> pool -> failover_peer;
791                 if (peer -> service_state == not_responding ||
792                     peer -> service_state == service_startup) {
793                         log_info ("%s: ignored%s",
794                                   peer -> name, peer -> nrr);
795                         goto out;
796                 }
797
798                 /* DHCPRELEASE messages are unicast, so if the client
799                    sent the DHCPRELEASE to us, it's not going to send it
800                    to the peer.   Not sure why this would happen, and
801                    if it does happen I think we still have to change the
802                    lease state, so that's what we're doing.
803                    XXX See what it says in the draft about this. */
804         }
805 #endif
806
807         /* If we found a lease, release it. */
808         if (lease && lease -> ends > cur_time) {
809                 release_lease (lease, packet);
810         } 
811         log_info ("%s", msgbuf);
812       out:
813         if (lease)
814                 lease_dereference (&lease, MDL);
815 }
816
817 void dhcpdecline (packet, ms_nulltp)
818         struct packet *packet;
819         int ms_nulltp;
820 {
821         struct lease *lease = (struct lease *)0;
822         struct option_state *options = (struct option_state *)0;
823         int ignorep = 0;
824         int i;
825         const char *status;
826         const char *s;
827         char msgbuf [1024]; /* XXX */
828         struct iaddr cip;
829         struct option_cache *oc;
830         struct data_string data;
831
832         /* DHCPDECLINE must specify address. */
833         if (!(oc = lookup_option (&dhcp_universe, packet -> options,
834                                   DHO_DHCP_REQUESTED_ADDRESS)))
835                 return;
836         memset (&data, 0, sizeof data);
837         if (!evaluate_option_cache (&data, packet, (struct lease *)0,
838                                     (struct client_state *)0,
839                                     packet -> options,
840                                     (struct option_state *)0,
841                                     &global_scope, oc, MDL))
842                 return;
843
844         cip.len = 4;
845         memcpy (cip.iabuf, data.data, 4);
846         data_string_forget (&data, MDL);
847         find_lease_by_ip_addr (&lease, cip, MDL);
848
849         if (lease && lease -> client_hostname) {
850                 if ((strlen (lease -> client_hostname) <= 64) &&
851                     db_printable (lease -> client_hostname))
852                         s = lease -> client_hostname;
853                 else
854                         s = "Hostname Unsuitable for Printing";
855         } else
856                 s = (char *)0;
857
858         /* %Audit% This is log output. %2004.06.17,Safe%
859          * If we truncate we hope the user can get a hint from the log.
860          */
861         snprintf (msgbuf, sizeof msgbuf,
862                  "DHCPDECLINE of %s from %s %s%s%svia %s",
863                  piaddr (cip),
864                  (packet -> raw -> htype
865                   ? print_hw_addr (packet -> raw -> htype,
866                                    packet -> raw -> hlen,
867                                    packet -> raw -> chaddr)
868                   : (lease
869                      ? print_hex_1 (lease -> uid_len, lease -> uid, 
870                                     lease -> uid_len)
871                      : "<no identifier>")),
872                  s ? "(" : "", s ? s : "", s ? ") " : "",
873                  packet -> raw -> giaddr.s_addr
874                  ? inet_ntoa (packet -> raw -> giaddr)
875                  : packet -> interface -> name);
876
877         option_state_allocate (&options, MDL);
878
879         /* Execute statements in scope starting with the subnet scope. */
880         if (lease)
881                 execute_statements_in_scope ((struct binding_value **)0,
882                                              packet, (struct lease *)0,
883                                              (struct client_state *)0,
884                                              packet -> options, options,
885                                              &global_scope,
886                                              lease -> subnet -> group,
887                                              (struct group *)0);
888
889         /* Execute statements in the class scopes. */
890         for (i = packet -> class_count; i > 0; i--) {
891                 execute_statements_in_scope
892                         ((struct binding_value **)0, packet, (struct lease *)0,
893                          (struct client_state *)0, packet -> options, options,
894                          &global_scope, packet -> classes [i - 1] -> group,
895                          lease ? lease -> subnet -> group : (struct group *)0);
896         }
897
898         /* Drop the request if dhcpdeclines are being ignored. */
899         oc = lookup_option (&server_universe, options, SV_DECLINES);
900         if (!oc ||
901             evaluate_boolean_option_cache (&ignorep, packet, lease,
902                                            (struct client_state *)0,
903                                            packet -> options, options,
904                                            &lease -> scope, oc, MDL)) {
905             /* If we found a lease, mark it as unusable and complain. */
906             if (lease) {
907 #if defined (FAILOVER_PROTOCOL)
908                 if (lease -> pool && lease -> pool -> failover_peer) {
909                     dhcp_failover_state_t *peer =
910                             lease -> pool -> failover_peer;
911                     if (peer -> service_state == not_responding ||
912                         peer -> service_state == service_startup) {
913                         if (!ignorep)
914                             log_info ("%s: ignored%s",
915                                       peer -> name, peer -> nrr);
916                         goto out;
917                     }
918
919                     /* DHCPDECLINE messages are broadcast, so we can safely
920                        ignore the DHCPDECLINE if the peer has the lease.
921                        XXX Of course, at this point that information has been
922                        lost. */
923                 }
924 #endif
925
926                 abandon_lease (lease, "declined.");
927                 status = "abandoned";
928             }
929             status = "not found";
930         } else
931             status = "ignored";
932
933         if (!ignorep)
934                 log_info ("%s: %s", msgbuf, status);
935                 
936       out:
937         if (options)
938                 option_state_dereference (&options, MDL);
939         if (lease)
940                 lease_dereference (&lease, MDL);
941 }
942
943 void dhcpinform (packet, ms_nulltp)
944         struct packet *packet;
945         int ms_nulltp;
946 {
947         char msgbuf [1024];
948         struct data_string d1, prl;
949         struct option_cache *oc;
950         struct expression *expr;
951         struct option_state *options = (struct option_state *)0;
952         struct dhcp_packet raw;
953         struct packet outgoing;
954         unsigned char dhcpack = DHCPACK;
955         struct subnet *subnet = (struct subnet *)0;
956         struct iaddr cip;
957         unsigned i, j;
958         int nulltp;
959         struct sockaddr_in to;
960         struct in_addr from;
961
962         /* The client should set ciaddr to its IP address, but apparently
963            it's common for clients not to do this, so we'll use their IP
964            source address if they didn't set ciaddr. */
965         if (!packet -> raw -> ciaddr.s_addr) {
966                 cip.len = 4;
967                 memcpy (cip.iabuf, &packet -> client_addr.iabuf, 4);
968         } else {
969                 cip.len = 4;
970                 memcpy (cip.iabuf, &packet -> raw -> ciaddr, 4);
971         }
972
973         /* %Audit% This is log output. %2004.06.17,Safe%
974          * If we truncate we hope the user can get a hint from the log.
975          */
976         snprintf (msgbuf, sizeof msgbuf, "DHCPINFORM from %s via %s",
977                  piaddr (cip), packet -> interface -> name);
978
979         /* If the IP source address is zero, don't respond. */
980         if (!memcmp (cip.iabuf, "\0\0\0", 4)) {
981                 log_info ("%s: ignored (null source address).", msgbuf);
982                 return;
983         }
984
985         /* Find the subnet that the client is on. */
986         oc = (struct option_cache *)0;
987         find_subnet (&subnet , cip, MDL);
988
989         /* Sourceless packets don't make sense here. */
990         if (!subnet) {
991                 log_info ("%s: unknown subnet %s",
992                           msgbuf, inet_ntoa (packet -> raw -> giaddr));
993                 return;
994         }
995
996         /* We don't respond to DHCPINFORM packets if we're not authoritative.
997            It would be nice if a per-host value could override this, but
998            there's overhead involved in checking this, so let's see how people
999            react first. */
1000         if (subnet && !subnet -> group -> authoritative) {
1001                 static int eso = 0;
1002                 log_info ("%s: not authoritative for subnet %s",
1003                           msgbuf, piaddr (subnet -> net));
1004                 if (!eso) {
1005                         log_info ("If this DHCP server is authoritative for%s",
1006                                   " that subnet,");
1007                         log_info ("please write an `authoritative;' directi%s",
1008                                   "ve either in the");
1009                         log_info ("subnet declaration or in some scope that%s",
1010                                   " encloses the");
1011                         log_info ("subnet declaration - for example, write %s",
1012                                   "it at the top");
1013                         log_info ("of the dhcpd.conf file.");
1014                 }
1015                 if (eso++ == 100)
1016                         eso = 0;
1017                 subnet_dereference (&subnet, MDL);
1018                 return;
1019         }
1020
1021         memset (&d1, 0, sizeof d1);
1022         option_state_allocate (&options, MDL);
1023         memset (&outgoing, 0, sizeof outgoing);
1024         memset (&raw, 0, sizeof raw);
1025         outgoing.raw = &raw;
1026
1027         /* Execute statements in scope starting with the subnet scope. */
1028         if (subnet)
1029                 execute_statements_in_scope ((struct binding_value **)0,
1030                                              packet, (struct lease *)0,
1031                                              (struct client_state *)0,
1032                                              packet -> options, options,
1033                                              &global_scope, subnet -> group,
1034                                              (struct group *)0);
1035
1036         /* Execute statements in the class scopes. */
1037         for (i = packet -> class_count; i > 0; i--) {
1038                 execute_statements_in_scope
1039                         ((struct binding_value **)0, packet, (struct lease *)0,
1040                          (struct client_state *)0, packet -> options, options,
1041                          &global_scope, packet -> classes [i - 1] -> group,
1042                          subnet ? subnet -> group : (struct group *)0);
1043         }
1044
1045         /* Figure out the filename. */
1046         memset (&d1, 0, sizeof d1);
1047         oc = lookup_option (&server_universe, options, SV_FILENAME);
1048         if (oc &&
1049             evaluate_option_cache (&d1, packet, (struct lease *)0,
1050                                    (struct client_state *)0,
1051                                    packet -> options, (struct option_state *)0,
1052                                    &global_scope, oc, MDL)) {
1053                 i = d1.len;
1054                 if (i > sizeof raw.file)
1055                         i = sizeof raw.file;
1056                 else
1057                         raw.file [i] = 0;
1058                 memcpy (raw.file, d1.data, i);
1059                 data_string_forget (&d1, MDL);
1060         }
1061
1062         /* Choose a server name as above. */
1063         oc = lookup_option (&server_universe, options, SV_SERVER_NAME);
1064         if (oc &&
1065             evaluate_option_cache (&d1, packet, (struct lease *)0,
1066                                    (struct client_state *)0,
1067                                    packet -> options, (struct option_state *)0,
1068                                    &global_scope, oc, MDL)) {
1069                 i = d1.len;
1070                 if (i > sizeof raw.sname)
1071                         i = sizeof raw.sname;
1072                 else
1073                         raw.sname [i] = 0;
1074                 memcpy (raw.sname, d1.data, i);
1075                 data_string_forget (&d1, MDL);
1076         }
1077
1078         /* Set a flag if this client is a lame Microsoft client that NUL
1079            terminates string options and expects us to do likewise. */
1080         nulltp = 0;
1081         if ((oc = lookup_option (&dhcp_universe, packet -> options,
1082                                  DHO_HOST_NAME))) {
1083                 if (evaluate_option_cache (&d1, packet, (struct lease *)0,
1084                                            (struct client_state *)0,
1085                                            packet -> options, options,
1086                                            &global_scope, oc, MDL)) {
1087                         if (d1.data [d1.len - 1] == '\0')
1088                                 nulltp = 1;
1089                         data_string_forget (&d1, MDL);
1090                 }
1091         }
1092
1093         /* Put in DHCP-specific options. */
1094         i = DHO_DHCP_MESSAGE_TYPE;
1095         oc = (struct option_cache *)0;
1096         if (option_cache_allocate (&oc, MDL)) {
1097                 if (make_const_data (&oc -> expression,
1098                                      &dhcpack, 1, 0, 0, MDL)) {
1099                         oc -> option = dhcp_universe.options [i];
1100                         save_option (&dhcp_universe, options, oc);
1101                 }
1102                 option_cache_dereference (&oc, MDL);
1103         }
1104
1105         i = DHO_DHCP_SERVER_IDENTIFIER;
1106         if (!(oc = lookup_option (&dhcp_universe, options, i))) {
1107               use_primary:
1108                 oc = (struct option_cache *)0;
1109                 if (option_cache_allocate (&oc, MDL)) {
1110                         if (make_const_data
1111                             (&oc -> expression,
1112                              ((unsigned char *)
1113                               &packet -> interface -> primary_address),
1114                              sizeof packet -> interface -> primary_address,
1115                              0, 0, MDL)) {
1116                                 oc -> option =
1117                                         dhcp_universe.options [i];
1118                                 save_option (&dhcp_universe,
1119                                              options, oc);
1120                         }
1121                         option_cache_dereference (&oc, MDL);
1122                 }
1123                 from = packet -> interface -> primary_address;
1124         } else {
1125                 if (evaluate_option_cache (&d1, packet, (struct lease *)0,
1126                                            (struct client_state *)0,
1127                                            packet -> options, options,
1128                                            &global_scope, oc, MDL)) {
1129                         if (!d1.len || d1.len != sizeof from) {
1130                                 data_string_forget (&d1, MDL);
1131                                 goto use_primary;
1132                         }
1133                         memcpy (&from, d1.data, sizeof from);
1134                         data_string_forget (&d1, MDL);
1135                 } else
1136                         goto use_primary;
1137         }
1138
1139         /* Use the subnet mask from the subnet declaration if no other
1140            mask has been provided. */
1141         i = DHO_SUBNET_MASK;
1142         if (subnet && !lookup_option (&dhcp_universe, options, i)) {
1143                 oc = (struct option_cache *)0;
1144                 if (option_cache_allocate (&oc, MDL)) {
1145                         if (make_const_data (&oc -> expression,
1146                                              subnet -> netmask.iabuf,
1147                                              subnet -> netmask.len,
1148                                              0, 0, MDL)) {
1149                                 oc -> option = dhcp_universe.options [i];
1150                                 save_option (&dhcp_universe, options, oc);
1151                         }
1152                         option_cache_dereference (&oc, MDL);
1153                 }
1154         }
1155
1156         /* If a site option space has been specified, use that for
1157            site option codes. */
1158         i = SV_SITE_OPTION_SPACE;
1159         if ((oc = lookup_option (&server_universe, options, i)) &&
1160             evaluate_option_cache (&d1, packet, (struct lease *)0,
1161                                    (struct client_state *)0,
1162                                    packet -> options, options,
1163                                    &global_scope, oc, MDL)) {
1164                 struct universe *u = (struct universe *)0;
1165                 
1166                 if (!universe_hash_lookup (&u, universe_hash,
1167                                            (const char *)d1.data, d1.len,
1168                                            MDL)) {
1169                         log_error ("unknown option space %s.", d1.data);
1170                         option_state_dereference (&options, MDL);
1171                         if (subnet)
1172                                 subnet_dereference (&subnet, MDL);
1173                         return;
1174                 }
1175
1176                 options -> site_universe = u -> index;
1177                 options -> site_code_min = 128; /* XXX */
1178                 data_string_forget (&d1, MDL);
1179         } else {
1180                 options -> site_universe = dhcp_universe.index;
1181                 options -> site_code_min = 0; /* Trust me, it works. */
1182         }
1183
1184         memset (&prl, 0, sizeof prl);
1185
1186         /* Use the parameter list from the scope if there is one. */
1187         oc = lookup_option (&dhcp_universe, options,
1188                             DHO_DHCP_PARAMETER_REQUEST_LIST);
1189
1190         /* Otherwise, if the client has provided a list of options
1191            that it wishes returned, use it to prioritize.  Otherwise,
1192            prioritize based on the default priority list. */
1193
1194         if (!oc)
1195                 oc = lookup_option (&dhcp_universe, packet -> options,
1196                                     DHO_DHCP_PARAMETER_REQUEST_LIST);
1197
1198         if (oc)
1199                 evaluate_option_cache (&prl, packet, (struct lease *)0,
1200                                        (struct client_state *)0,
1201                                        packet -> options, options,
1202                                        &global_scope, oc, MDL);
1203
1204 #ifdef DEBUG_PACKET
1205         dump_packet (packet);
1206         dump_raw ((unsigned char *)packet -> raw, packet -> packet_length);
1207 #endif
1208
1209         log_info ("%s", msgbuf);
1210
1211         /* Figure out the address of the boot file server. */
1212         raw.siaddr = from;
1213         if ((oc =
1214              lookup_option (&server_universe, options, SV_NEXT_SERVER))) {
1215                 if (evaluate_option_cache (&d1, packet, (struct lease *)0,
1216                                            (struct client_state *)0,
1217                                            packet -> options, options,
1218                                            &global_scope, oc, MDL)) {
1219                         /* If there was more than one answer,
1220                            take the first. */
1221                         if (d1.len >= 4 && d1.data)
1222                                 memcpy (&raw.siaddr, d1.data, 4);
1223                         data_string_forget (&d1, MDL);
1224                 }
1225         }
1226
1227         /* Set up the option buffer... */
1228         outgoing.packet_length =
1229                 cons_options (packet, outgoing.raw, (struct lease *)0,
1230                               (struct client_state *)0,
1231                               0, packet -> options, options, &global_scope,
1232                               0, nulltp, 0,
1233                               prl.len ? &prl : (struct data_string *)0,
1234                               (char *)0);
1235         option_state_dereference (&options, MDL);
1236         data_string_forget (&prl, MDL);
1237
1238         /* Make sure that the packet is at least as big as a BOOTP packet. */
1239         if (outgoing.packet_length < BOOTP_MIN_LEN)
1240                 outgoing.packet_length = BOOTP_MIN_LEN;
1241
1242         raw.giaddr = packet -> raw -> giaddr;
1243         raw.ciaddr = packet -> raw -> ciaddr;
1244         memcpy (raw.chaddr, packet -> raw -> chaddr, sizeof raw.chaddr);
1245         raw.hlen = packet -> raw -> hlen;
1246         raw.htype = packet -> raw -> htype;
1247
1248         raw.xid = packet -> raw -> xid;
1249         raw.secs = packet -> raw -> secs;
1250         raw.flags = packet -> raw -> flags;
1251         raw.hops = packet -> raw -> hops;
1252         raw.op = BOOTREPLY;
1253
1254         /* Report what we're sending... */
1255         log_info ("DHCPACK to %s", inet_ntoa (raw.ciaddr));
1256
1257 #ifdef DEBUG_PACKET
1258         dump_packet (&outgoing);
1259         dump_raw ((unsigned char *)&raw, outgoing.packet_length);
1260 #endif
1261
1262         /* Set up the common stuff... */
1263         to.sin_family = AF_INET;
1264 #ifdef HAVE_SA_LEN
1265         to.sin_len = sizeof to;
1266 #endif
1267         memset (to.sin_zero, 0, sizeof to.sin_zero);
1268
1269         /* Use the IP address we derived for the client. */
1270         memcpy (&to.sin_addr, cip.iabuf, 4);
1271         to.sin_port = remote_port;
1272
1273         errno = 0;
1274         send_packet ((fallback_interface
1275                       ? fallback_interface : packet -> interface),
1276                      &outgoing, &raw, outgoing.packet_length,
1277                      from, &to, (struct hardware *)0);
1278         if (subnet)
1279                 subnet_dereference (&subnet, MDL);
1280 }
1281
1282 void nak_lease (packet, cip)
1283         struct packet *packet;
1284         struct iaddr *cip;
1285 {
1286         struct sockaddr_in to;
1287         struct in_addr from;
1288         int result;
1289         struct dhcp_packet raw;
1290         unsigned char nak = DHCPNAK;
1291         struct packet outgoing;
1292         struct hardware hto;
1293         unsigned i;
1294         struct data_string data;
1295         struct option_state *options = (struct option_state *)0;
1296         struct expression *expr;
1297         struct option_cache *oc = (struct option_cache *)0;
1298         struct iaddr myfrom;
1299
1300         option_state_allocate (&options, MDL);
1301         memset (&outgoing, 0, sizeof outgoing);
1302         memset (&raw, 0, sizeof raw);
1303         outgoing.raw = &raw;
1304
1305         /* Set DHCP_MESSAGE_TYPE to DHCPNAK */
1306         if (!option_cache_allocate (&oc, MDL)) {
1307                 log_error ("No memory for DHCPNAK message type.");
1308                 option_state_dereference (&options, MDL);
1309                 return;
1310         }
1311         if (!make_const_data (&oc -> expression, &nak, sizeof nak,
1312                               0, 0, MDL)) {
1313                 log_error ("No memory for expr_const expression.");
1314                 option_cache_dereference (&oc, MDL);
1315                 option_state_dereference (&options, MDL);
1316                 return;
1317         }
1318         oc -> option = dhcp_universe.options [DHO_DHCP_MESSAGE_TYPE];
1319         save_option (&dhcp_universe, options, oc);
1320         option_cache_dereference (&oc, MDL);
1321                      
1322         /* Set DHCP_MESSAGE to whatever the message is */
1323         if (!option_cache_allocate (&oc, MDL)) {
1324                 log_error ("No memory for DHCPNAK message type.");
1325                 option_state_dereference (&options, MDL);
1326                 return;
1327         }
1328         if (!make_const_data (&oc -> expression,
1329                               (unsigned char *)dhcp_message,
1330                               strlen (dhcp_message), 1, 0, MDL)) {
1331                 log_error ("No memory for expr_const expression.");
1332                 option_cache_dereference (&oc, MDL);
1333                 option_state_dereference (&options, MDL);
1334                 return;
1335         }
1336         oc -> option = dhcp_universe.options [DHO_DHCP_MESSAGE];
1337         save_option (&dhcp_universe, options, oc);
1338         option_cache_dereference (&oc, MDL);
1339                      
1340         i = DHO_DHCP_SERVER_IDENTIFIER;
1341         if (!(oc = lookup_option (&dhcp_universe, options, i))) {
1342               use_primary:
1343                 oc = (struct option_cache *)0;
1344                 if (option_cache_allocate (&oc, MDL)) {
1345                         if (make_const_data
1346                             (&oc -> expression,
1347                              ((unsigned char *)
1348                               &packet -> interface -> primary_address),
1349                              sizeof packet -> interface -> primary_address,
1350                              0, 0, MDL)) {
1351                                 oc -> option =
1352                                         dhcp_universe.options [i];
1353                                 save_option (&dhcp_universe, options, oc);
1354                         }
1355                         option_cache_dereference (&oc, MDL);
1356                 }
1357                 myfrom.len = sizeof packet -> interface -> primary_address;
1358                 memcpy (myfrom.iabuf,
1359                         &packet -> interface -> primary_address, myfrom.len);
1360         } else {
1361                 memset (&data, 0, sizeof data);
1362                 if (evaluate_option_cache (&data, packet, (struct lease *)0,
1363                                            (struct client_state *)0,
1364                                            packet -> options, options,
1365                                            &global_scope, oc, MDL)) {
1366                         if (!data.len ||
1367                             data.len > sizeof myfrom.iabuf) {
1368                                 data_string_forget (&data, MDL);
1369                                 goto use_primary;
1370                         }
1371                         memcpy (myfrom.iabuf, data.data, data.len);
1372                         myfrom.len = data.len;
1373                         data_string_forget (&data, MDL);
1374                 } else
1375                         goto use_primary;
1376         }
1377
1378         /* If there were agent options in the incoming packet, return
1379            them. */
1380         if (packet -> raw -> giaddr.s_addr &&
1381             packet -> options -> universe_count > agent_universe.index &&
1382             packet -> options -> universes [agent_universe.index]) {
1383                 option_chain_head_reference
1384                     ((struct option_chain_head **)
1385                      &(options -> universes [agent_universe.index]),
1386                      (struct option_chain_head *)
1387                      packet -> options -> universes [agent_universe.index],
1388                      MDL);
1389         }
1390
1391         /* Do not use the client's requested parameter list. */
1392         delete_option (&dhcp_universe, packet -> options,
1393                        DHO_DHCP_PARAMETER_REQUEST_LIST);
1394
1395         /* Set up the option buffer... */
1396         outgoing.packet_length =
1397                 cons_options (packet, outgoing.raw, (struct lease *)0,
1398                               (struct client_state *)0,
1399                               0, packet -> options, options, &global_scope,
1400                               0, 0, 0, (struct data_string *)0, (char *)0);
1401         option_state_dereference (&options, MDL);
1402
1403 /*      memset (&raw.ciaddr, 0, sizeof raw.ciaddr);*/
1404         raw.siaddr = packet -> interface -> primary_address;
1405         raw.giaddr = packet -> raw -> giaddr;
1406         memcpy (raw.chaddr, packet -> raw -> chaddr, sizeof raw.chaddr);
1407         raw.hlen = packet -> raw -> hlen;
1408         raw.htype = packet -> raw -> htype;
1409
1410         raw.xid = packet -> raw -> xid;
1411         raw.secs = packet -> raw -> secs;
1412         raw.flags = packet -> raw -> flags | htons (BOOTP_BROADCAST);
1413         raw.hops = packet -> raw -> hops;
1414         raw.op = BOOTREPLY;
1415
1416         /* Report what we're sending... */
1417         log_info ("DHCPNAK on %s to %s via %s",
1418               piaddr (*cip),
1419               print_hw_addr (packet -> raw -> htype,
1420                              packet -> raw -> hlen,
1421                              packet -> raw -> chaddr),
1422               packet -> raw -> giaddr.s_addr
1423               ? inet_ntoa (packet -> raw -> giaddr)
1424               : packet -> interface -> name);
1425
1426
1427
1428 #ifdef DEBUG_PACKET
1429         dump_packet (packet);
1430         dump_raw ((unsigned char *)packet -> raw, packet -> packet_length);
1431         dump_packet (&outgoing);
1432         dump_raw ((unsigned char *)&raw, outgoing.packet_length);
1433 #endif
1434
1435 #if 0
1436         hto.hbuf [0] = packet -> raw -> htype;
1437         hto.hlen = packet -> raw -> hlen;
1438         memcpy (&hto.hbuf [1], packet -> raw -> chaddr, hto.hlen);
1439         hto.hlen++;
1440 #endif
1441
1442         /* Set up the common stuff... */
1443         to.sin_family = AF_INET;
1444 #ifdef HAVE_SA_LEN
1445         to.sin_len = sizeof to;
1446 #endif
1447         memset (to.sin_zero, 0, sizeof to.sin_zero);
1448
1449         memcpy (&from, myfrom.iabuf, sizeof from);
1450
1451         /* Make sure that the packet is at least as big as a BOOTP packet. */
1452         if (outgoing.packet_length < BOOTP_MIN_LEN)
1453                 outgoing.packet_length = BOOTP_MIN_LEN;
1454
1455         /* If this was gatewayed, send it back to the gateway.
1456            Otherwise, broadcast it on the local network. */
1457         if (raw.giaddr.s_addr) {
1458                 to.sin_addr = raw.giaddr;
1459                 if (raw.giaddr.s_addr != htonl (INADDR_LOOPBACK))
1460                         to.sin_port = local_port;
1461                 else
1462                         to.sin_port = remote_port; /* for testing. */
1463
1464                 if (fallback_interface) {
1465                         result = send_packet (fallback_interface,
1466                                               packet, &raw,
1467                                               outgoing.packet_length,
1468                                               from, &to, &hto);
1469                         return;
1470                 }
1471         } else {
1472                 to.sin_addr = limited_broadcast;
1473                 to.sin_port = remote_port;
1474         }
1475
1476         errno = 0;
1477         result = send_packet (packet -> interface,
1478                               packet, &raw, outgoing.packet_length,
1479                               from, &to, (struct hardware *)0);
1480 }
1481
1482 void ack_lease (packet, lease, offer, when, msg, ms_nulltp)
1483         struct packet *packet;
1484         struct lease *lease;
1485         unsigned int offer;
1486         TIME when;
1487         char *msg;
1488         int ms_nulltp;
1489 {
1490         struct lease *lt;
1491         struct lease_state *state;
1492         struct lease *next;
1493         struct host_decl *host = (struct host_decl *)0;
1494         TIME lease_time;
1495         TIME offered_lease_time;
1496         struct data_string d1;
1497         TIME min_lease_time;
1498         TIME max_lease_time;
1499         TIME default_lease_time;
1500         struct option_cache *oc;
1501         struct expression *expr;
1502         int status;
1503         isc_result_t result;
1504         int did_ping = 0;
1505         TIME ping_timeout;
1506
1507         unsigned i, j;
1508         int s1, s2;
1509         int val;
1510         int ignorep;
1511
1512         /* If we're already acking this lease, don't do it again. */
1513         if (lease -> state)
1514                 return;
1515
1516         /* If the lease carries a host record, remember it. */
1517         if (lease -> host)
1518                 host_reference (&host, lease -> host, MDL);
1519
1520         /* Allocate a lease state structure... */
1521         state = new_lease_state (MDL);
1522         if (!state)
1523                 log_fatal ("unable to allocate lease state!");
1524         state -> got_requested_address = packet -> got_requested_address;
1525         shared_network_reference (&state -> shared_network,
1526                                   packet -> interface -> shared_network, MDL);
1527
1528         /* See if we got a server identifier option. */
1529         if (lookup_option (&dhcp_universe,
1530                            packet -> options, DHO_DHCP_SERVER_IDENTIFIER))
1531                 state -> got_server_identifier = 1;
1532
1533         /* If there were agent options in the incoming packet, return
1534            them.  Do not return the agent options if they were stashed
1535            on the lease. */
1536         if (packet -> raw -> giaddr.s_addr &&
1537             packet -> options -> universe_count > agent_universe.index &&
1538             packet -> options -> universes [agent_universe.index] &&
1539             (state -> options -> universe_count <= agent_universe.index ||
1540              !state -> options -> universes [agent_universe.index]) &&
1541             lease -> agent_options !=
1542             ((struct option_chain_head *)
1543              packet -> options -> universes [agent_universe.index])) {
1544                 option_chain_head_reference
1545                     ((struct option_chain_head **)
1546                      &(state -> options -> universes [agent_universe.index]),
1547                      (struct option_chain_head *)
1548                      packet -> options -> universes [agent_universe.index],
1549                      MDL);
1550         }
1551
1552         /* If we are offering a lease that is still currently valid, preserve
1553            the events.  We need to do this because if the client does not
1554            REQUEST our offer, it will expire in 2 minutes, overriding the
1555            expire time in the currently in force lease.  We want the expire
1556            events to be executed at that point. */
1557         if (lease -> ends <= cur_time && offer != DHCPOFFER) {
1558                 /* Get rid of any old expiry or release statements - by
1559                    executing the statements below, we will be inserting new
1560                    ones if there are any to insert. */
1561                 if (lease -> on_expiry)
1562                         executable_statement_dereference (&lease -> on_expiry,
1563                                                           MDL);
1564                 if (lease -> on_commit)
1565                         executable_statement_dereference (&lease -> on_commit,
1566                                                           MDL);
1567                 if (lease -> on_release)
1568                         executable_statement_dereference (&lease -> on_release,
1569                                                           MDL);
1570         }
1571
1572         /* Execute statements in scope starting with the subnet scope. */
1573         execute_statements_in_scope ((struct binding_value **)0,
1574                                      packet, lease, (struct client_state *)0,
1575                                      packet -> options,
1576                                      state -> options, &lease -> scope,
1577                                      lease -> subnet -> group,
1578                                      (struct group *)0);
1579
1580         /* If the lease is from a pool, run the pool scope. */
1581         if (lease -> pool)
1582                 (execute_statements_in_scope
1583                  ((struct binding_value **)0, packet, lease,
1584                   (struct client_state *)0, packet -> options,
1585                   state -> options, &lease -> scope, lease -> pool -> group,
1586                   lease -> pool -> shared_network -> group));
1587
1588         /* Execute statements from class scopes. */
1589         for (i = packet -> class_count; i > 0; i--) {
1590                 execute_statements_in_scope
1591                         ((struct binding_value **)0,
1592                          packet, lease, (struct client_state *)0,
1593                          packet -> options, state -> options,
1594                          &lease -> scope, packet -> classes [i - 1] -> group,
1595                          (lease -> pool
1596                           ? lease -> pool -> group
1597                           : lease -> subnet -> group));
1598         }
1599
1600         /* See if the client is only supposed to have one lease at a time,
1601            and if so, find its other leases and release them.    We can only
1602            do this on DHCPREQUEST.    It's a little weird to do this before
1603            looking at permissions, because the client might not actually
1604            _get_ a lease after we've done the permission check, but the
1605            assumption for this option is that the client has exactly one
1606            network interface, and will only ever remember one lease.   So
1607            if it sends a DHCPREQUEST, and doesn't get the lease, it's already
1608            forgotten about its old lease, so we can too. */
1609         if (packet -> packet_type == DHCPREQUEST &&
1610             (oc = lookup_option (&server_universe, state -> options,
1611                                  SV_ONE_LEASE_PER_CLIENT)) &&
1612             evaluate_boolean_option_cache (&ignorep,
1613                                            packet, lease,
1614                                            (struct client_state *)0,
1615                                            packet -> options,
1616                                            state -> options, &lease -> scope,
1617                                            oc, MDL)) {
1618             struct lease *seek;
1619             if (lease -> uid_len) {
1620                 do {
1621                     seek = (struct lease *)0;
1622                     find_lease_by_uid (&seek, lease -> uid,
1623                                        lease -> uid_len, MDL);
1624                     if (!seek)
1625                         break;
1626                     if (seek == lease && !seek -> n_uid) {
1627                         lease_dereference (&seek, MDL);
1628                         break;
1629                     }
1630                     next = (struct lease *)0;
1631
1632                     /* Don't release expired leases, and don't
1633                        release the lease we're going to assign. */
1634                     next = (struct lease *)0;
1635                     while (seek) {
1636                         if (seek -> n_uid)
1637                             lease_reference (&next, seek -> n_uid, MDL);
1638                         if (seek != lease &&
1639                             seek -> binding_state != FTS_RELEASED &&
1640                             seek -> binding_state != FTS_EXPIRED &&
1641                             seek -> binding_state != FTS_RESET &&
1642                             seek -> binding_state != FTS_FREE &&
1643                             seek -> binding_state != FTS_BACKUP)
1644                                 break;
1645                         lease_dereference (&seek, MDL);
1646                         if (next) {
1647                             lease_reference (&seek, next, MDL);
1648                             lease_dereference (&next, MDL);
1649                         }
1650                     }
1651                     if (next)
1652                         lease_dereference (&next, MDL);
1653                     if (seek) {
1654                         release_lease (seek, packet);
1655                         lease_dereference (&seek, MDL);
1656                     } else
1657                         break;
1658                 } while (1);
1659             }
1660             if (!lease -> uid_len ||
1661                 (host &&
1662                  !host -> client_identifier.len &&
1663                  (oc = lookup_option (&server_universe, state -> options,
1664                                       SV_DUPLICATES)) &&
1665                  !evaluate_boolean_option_cache (&ignorep, packet, lease,
1666                                                  (struct client_state *)0,
1667                                                  packet -> options,
1668                                                  state -> options,
1669                                                  &lease -> scope,
1670                                                  oc, MDL))) {
1671                 do {
1672                     seek = (struct lease *)0;
1673                     find_lease_by_hw_addr
1674                             (&seek, lease -> hardware_addr.hbuf,
1675                              lease -> hardware_addr.hlen, MDL);
1676                     if (!seek)
1677                             break;
1678                     if (seek == lease && !seek -> n_hw) {
1679                             lease_dereference (&seek, MDL);
1680                             break;
1681                     }
1682                     next = (struct lease *)0;
1683                     while (seek) {
1684                         if (seek -> n_hw)
1685                             lease_reference (&next, seek -> n_hw, MDL);
1686                         if (seek != lease &&
1687                             seek -> binding_state != FTS_RELEASED &&
1688                             seek -> binding_state != FTS_EXPIRED &&
1689                             seek -> binding_state != FTS_RESET &&
1690                             seek -> binding_state != FTS_FREE &&
1691                             seek -> binding_state != FTS_BACKUP)
1692                                 break;
1693                         lease_dereference (&seek, MDL);
1694                         if (next) {
1695                             lease_reference (&seek, next, MDL);
1696                             lease_dereference (&next, MDL);
1697                         }
1698                     }
1699                     if (next)
1700                         lease_dereference (&next, MDL);
1701                     if (seek) {
1702                         release_lease (seek, packet);
1703                         lease_dereference (&seek, MDL);
1704                     } else
1705                         break;
1706                 } while (1);
1707             }
1708         }
1709         
1710
1711         /* Make sure this packet satisfies the configured minimum
1712            number of seconds. */
1713         memset (&d1, 0, sizeof d1);
1714         if (offer == DHCPOFFER &&
1715             (oc = lookup_option (&server_universe, state -> options,
1716                                  SV_MIN_SECS))) {
1717                 if (evaluate_option_cache (&d1, packet, lease,
1718                                            (struct client_state *)0,
1719                                            packet -> options, state -> options,
1720                                            &lease -> scope, oc, MDL)) {
1721                         if (d1.len &&
1722                             ntohs (packet -> raw -> secs) < d1.data [0]) {
1723                                 log_info ("%s: %d secs < %d", msg,
1724                                           ntohs (packet -> raw -> secs),
1725                                           d1.data [0]);
1726                                 data_string_forget (&d1, MDL);
1727                                 free_lease_state (state, MDL);
1728                                 if (host)
1729                                         host_dereference (&host, MDL);
1730                                 return;
1731                         }
1732                         data_string_forget (&d1, MDL);
1733                 }
1734         }
1735
1736         /* Try to find a matching host declaration for this lease.
1737          */
1738         if (!host) {
1739                 struct host_decl *hp = (struct host_decl *)0;
1740                 struct host_decl *h;
1741
1742                 /* Try to find a host_decl that matches the client
1743                    identifier or hardware address on the packet, and
1744                    has no fixed IP address.   If there is one, hang
1745                    it off the lease so that its option definitions
1746                    can be used. */
1747                 oc = lookup_option (&dhcp_universe, packet -> options,
1748                                     DHO_DHCP_CLIENT_IDENTIFIER);
1749                 if (oc &&
1750                     evaluate_option_cache (&d1, packet, lease,
1751                                            (struct client_state *)0,
1752                                            packet -> options, state -> options,
1753                                            &lease -> scope, oc, MDL)) {
1754                         find_hosts_by_uid (&hp, d1.data, d1.len, MDL);
1755                         data_string_forget (&d1, MDL);
1756                         if (hp)
1757                                 host_reference (&host, hp, MDL);
1758                 }
1759                 if (!hp) {
1760                         find_hosts_by_haddr (&hp,
1761                                              packet -> raw -> htype,
1762                                              packet -> raw -> chaddr,
1763                                              packet -> raw -> hlen,
1764                                              MDL);
1765                         for (h = hp; h; h = h -> n_ipaddr) {
1766                                 if (!h -> fixed_addr)
1767                                         break;
1768                         }
1769                         if (h)
1770                                 host_reference (&host, h, MDL);
1771                 }
1772                 if (hp)
1773                         host_dereference (&hp, MDL);
1774         }
1775
1776         /* If we have a host_decl structure, run the options associated
1777            with its group.  Wether the host decl struct is old or not. */
1778         if (host)
1779                 execute_statements_in_scope ((struct binding_value **)0,
1780                                              packet, lease,
1781                                              (struct client_state *)0,
1782                                              packet -> options,
1783                                              state -> options, &lease -> scope,
1784                                              host -> group,
1785                                              (lease -> pool
1786                                               ? lease -> pool -> group
1787                                               : lease -> subnet -> group));
1788
1789         /* Drop the request if it's not allowed for this client.   By
1790            default, unknown clients are allowed. */
1791         if (!host &&
1792             (oc = lookup_option (&server_universe, state -> options,
1793                                  SV_BOOT_UNKNOWN_CLIENTS)) &&
1794             !evaluate_boolean_option_cache (&ignorep,
1795                                             packet, lease,
1796                                             (struct client_state *)0,
1797                                             packet -> options,
1798                                             state -> options,
1799                                             &lease -> scope, oc, MDL)) {
1800                 if (!ignorep)
1801                         log_info ("%s: unknown client", msg);
1802                 free_lease_state (state, MDL);
1803                 if (host)
1804                         host_dereference (&host, MDL);
1805                 return;
1806         } 
1807
1808         /* Drop the request if it's not allowed for this client. */
1809         if (!offer &&
1810             (oc = lookup_option (&server_universe, state -> options,
1811                                    SV_ALLOW_BOOTP)) &&
1812             !evaluate_boolean_option_cache (&ignorep,
1813                                             packet, lease,
1814                                             (struct client_state *)0,
1815                                             packet -> options,
1816                                             state -> options,
1817                                             &lease -> scope, oc, MDL)) {
1818                 if (!ignorep)
1819                         log_info ("%s: bootp disallowed", msg);
1820                 free_lease_state (state, MDL);
1821                 if (host)
1822                         host_dereference (&host, MDL);
1823                 return;
1824         } 
1825
1826         /* Drop the request if booting is specifically denied. */
1827         oc = lookup_option (&server_universe, state -> options,
1828                             SV_ALLOW_BOOTING);
1829         if (oc &&
1830             !evaluate_boolean_option_cache (&ignorep,
1831                                             packet, lease,
1832                                             (struct client_state *)0,
1833                                             packet -> options,
1834                                             state -> options,
1835                                             &lease -> scope, oc, MDL)) {
1836                 if (!ignorep)
1837                         log_info ("%s: booting disallowed", msg);
1838                 free_lease_state (state, MDL);
1839                 if (host)
1840                         host_dereference (&host, MDL);
1841                 return;
1842         }
1843
1844         /* If we are configured to do per-class billing, do it. */
1845         if (have_billing_classes && !(lease -> flags & STATIC_LEASE)) {
1846                 /* See if the lease is currently being billed to a
1847                    class, and if so, whether or not it can continue to
1848                    be billed to that class. */
1849                 if (lease -> billing_class) {
1850                         for (i = 0; i < packet -> class_count; i++)
1851                                 if (packet -> classes [i] ==
1852                                     lease -> billing_class)
1853                                         break;
1854                         if (i == packet -> class_count)
1855                                 unbill_class (lease, lease -> billing_class);
1856                 }
1857                 
1858                 /* If we don't have an active billing, see if we need
1859                    one, and if we do, try to do so. */
1860                 if (!lease -> billing_class) {
1861                         for (i = 0; i < packet -> class_count; i++) {
1862                                 if (packet -> classes [i] -> lease_limit)
1863                                         break;
1864                         }
1865                         if (i != packet -> class_count) {
1866                                 for (i = 0; i < packet -> class_count; i++)
1867                                         if ((packet -> 
1868                                              classes [i] -> lease_limit) &&
1869                                             bill_class (lease,
1870                                                         packet -> classes [i]))
1871                                                 break;
1872                                 if (i == packet -> class_count) {
1873                                         log_info ("%s: no available billing",
1874                                                   msg);
1875                                         free_lease_state (state, MDL);
1876                                         if (host)
1877                                                 host_dereference (&host, MDL);
1878                                         /* XXX possibly not necessary: */
1879                                         return;
1880                                 }
1881                         }
1882                 }
1883         }
1884
1885         /* Figure out the filename. */
1886         oc = lookup_option (&server_universe, state -> options, SV_FILENAME);
1887         if (oc)
1888                 evaluate_option_cache (&state -> filename, packet, lease,
1889                                        (struct client_state *)0,
1890                                        packet -> options, state -> options,
1891                                        &lease -> scope, oc, MDL);
1892
1893         /* Choose a server name as above. */
1894         oc = lookup_option (&server_universe, state -> options,
1895                             SV_SERVER_NAME);
1896         if (oc)
1897                 evaluate_option_cache (&state -> server_name, packet, lease,
1898                                        (struct client_state *)0,
1899                                        packet -> options, state -> options,
1900                                        &lease -> scope, oc, MDL);
1901
1902         /* At this point, we have a lease that we can offer the client.
1903            Now we construct a lease structure that contains what we want,
1904            and call supersede_lease to do the right thing with it. */
1905         lt = (struct lease *)0;
1906         result = lease_allocate (&lt, MDL);
1907         if (result != ISC_R_SUCCESS) {
1908                 log_info ("%s: can't allocate temporary lease structure: %s",
1909                           msg, isc_result_totext (result));
1910                 free_lease_state (state, MDL);
1911                 if (host)
1912                         host_dereference (&host, MDL);
1913                 return;
1914         }
1915                 
1916         /* Use the ip address of the lease that we finally found in
1917            the database. */
1918         lt -> ip_addr = lease -> ip_addr;
1919
1920         /* Start now. */
1921         lt -> starts = cur_time;
1922
1923         /* Figure out how long a lease to assign.    If this is a
1924            dynamic BOOTP lease, its duration must be infinite. */
1925         if (offer) {
1926                 default_lease_time = DEFAULT_DEFAULT_LEASE_TIME;
1927                 if ((oc = lookup_option (&server_universe, state -> options,
1928                                          SV_DEFAULT_LEASE_TIME))) {
1929                         if (evaluate_option_cache (&d1, packet, lease,
1930                                                    (struct client_state *)0,
1931                                                    packet -> options,
1932                                                    state -> options,
1933                                                    &lease -> scope, oc, MDL)) {
1934                                 if (d1.len == sizeof (u_int32_t))
1935                                         default_lease_time =
1936                                                 getULong (d1.data);
1937                                 data_string_forget (&d1, MDL);
1938                         }
1939                 }
1940
1941                 if ((oc = lookup_option (&dhcp_universe, packet -> options,
1942                                          DHO_DHCP_LEASE_TIME)))
1943                         s1 = evaluate_option_cache (&d1, packet, lease,
1944                                                     (struct client_state *)0,
1945                                                     packet -> options,
1946                                                     state -> options,
1947                                                     &lease -> scope, oc, MDL);
1948                 else
1949                         s1 = 0;
1950
1951                 if (s1 && d1.len == sizeof (u_int32_t)) {
1952                         lease_time = getULong (d1.data);
1953                         data_string_forget (&d1, MDL);
1954                 } else {
1955                         if (s1)
1956                                 data_string_forget (&d1, MDL);
1957                         lease_time = default_lease_time;
1958                 }
1959
1960                 /* See if there's a maximum lease time. */
1961                 max_lease_time = DEFAULT_MAX_LEASE_TIME;
1962                 if ((oc = lookup_option (&server_universe, state -> options,
1963                                          SV_MAX_LEASE_TIME))) {
1964                         if (evaluate_option_cache (&d1, packet, lease,
1965                                                    (struct client_state *)0,
1966                                                    packet -> options,
1967                                                    state -> options,
1968                                                    &lease -> scope, oc, MDL)) {
1969                                 if (d1.len == sizeof (u_int32_t))
1970                                         max_lease_time =
1971                                                 getULong (d1.data);
1972                                 data_string_forget (&d1, MDL);
1973                         }
1974                 }
1975
1976                 /* Enforce the maximum lease length. */
1977                 if (lease_time < 0 /* XXX */
1978                     || lease_time > max_lease_time)
1979                         lease_time = max_lease_time;
1980                         
1981                 min_lease_time = DEFAULT_MIN_LEASE_TIME;
1982                 if (min_lease_time > max_lease_time)
1983                         min_lease_time = max_lease_time;
1984
1985                 if ((oc = lookup_option (&server_universe, state -> options,
1986                                          SV_MIN_LEASE_TIME))) {
1987                         if (evaluate_option_cache (&d1, packet, lease,
1988                                                    (struct client_state *)0,
1989                                                    packet -> options,
1990                                                    state -> options,
1991                                                    &lease -> scope, oc, MDL)) {
1992                                 if (d1.len == sizeof (u_int32_t))
1993                                         min_lease_time = getULong (d1.data);
1994                                 data_string_forget (&d1, MDL);
1995                         }
1996                 }
1997
1998                 if (lease_time < min_lease_time) {
1999                         if (min_lease_time)
2000                                 lease_time = min_lease_time;
2001                         else
2002                                 lease_time = default_lease_time;
2003                 }
2004
2005 #if defined (FAILOVER_PROTOCOL)
2006                 /* Okay, we know the lease duration.   Now check the
2007                    failover state, if any. */
2008                 if (lease -> tsfp) {
2009                         lt ->tsfp = lease ->tsfp;
2010                 }
2011                 if (lease -> pool && lease -> pool -> failover_peer) {
2012                         dhcp_failover_state_t *peer =
2013                             lease -> pool -> failover_peer;
2014
2015                         /* If the lease time we arrived at exceeds what
2016                            the peer has, we can only issue a lease of
2017                            peer -> mclt, but we can tell the peer we
2018                            want something longer in the future. */
2019                         /* XXX This may result in updates that only push
2020                            XXX the peer's expiry time for this lease up
2021                            XXX by a few seconds - think about this again
2022                            XXX later. */
2023                         if (lease_time > peer -> mclt &&
2024                             cur_time + lease_time > lease -> tsfp) {
2025                                 /* Here we're assuming that if we don't have
2026                                    to update tstp, there's already an update
2027                                    queued.   May want to revisit this.  */
2028                                 if (peer -> me.state != partner_down &&
2029                                     cur_time + lease_time > lease -> tstp)
2030                                         lt -> tstp = (cur_time + lease_time +
2031                                                       peer -> mclt / 2);
2032
2033                                 /* Now choose a lease time that is either
2034                                    MCLT, for a lease that's never before been
2035                                    assigned, or TSFP + MCLT for a lease that
2036                                    has.
2037                                    XXX Note that TSFP may be < cur_time.
2038                                    XXX What do we do in this case?
2039                                    XXX should the expiry timer on the lease
2040                                    XXX set tsfp and tstp to zero? */
2041                                 if (lease -> tsfp < cur_time) {
2042                                         lease_time = peer -> mclt;
2043                                 } else {
2044                                         lease_time = (lease -> tsfp  - cur_time
2045                                                       + peer -> mclt);
2046                                 }
2047                         } else {
2048                                 if (cur_time + lease_time > lease -> tsfp &&
2049                                     lease_time > peer -> mclt / 2) {
2050                                         lt -> tstp = (cur_time + lease_time +
2051                                                       peer -> mclt / 2);
2052                                 } else { 
2053                                         lt -> tstp = (cur_time + lease_time +
2054                                                       lease_time / 2);
2055                                 }
2056                         }
2057
2058                         lt -> cltt = cur_time;
2059                 }
2060 #endif /* FAILOVER_PROTOCOL */
2061
2062                 /* If the lease duration causes the time value to wrap,
2063                    use the maximum expiry time. */
2064                 if (cur_time + lease_time < cur_time)
2065                         state -> offered_expiry = MAX_TIME - 1;
2066                 else
2067                         state -> offered_expiry = cur_time + lease_time;
2068                 if (when)
2069                         lt -> ends = when;
2070                 else
2071                         lt -> ends = state -> offered_expiry;
2072
2073                 /* Don't make lease active until we actually get a
2074                    DHCPREQUEST. */
2075                 if (offer == DHCPACK)
2076                         lt -> next_binding_state = FTS_ACTIVE;
2077                 else
2078                         lt -> next_binding_state = lease -> binding_state;
2079         } else {
2080                 lease_time = MAX_TIME - cur_time;
2081
2082                 if ((oc = lookup_option (&server_universe, state -> options,
2083                                          SV_BOOTP_LEASE_LENGTH))) {
2084                         if (evaluate_option_cache (&d1, packet, lease,
2085                                                    (struct client_state *)0,
2086                                                    packet -> options,
2087                                                    state -> options,
2088                                                    &lease -> scope, oc, MDL)) {
2089                                 if (d1.len == sizeof (u_int32_t))
2090                                         lease_time = getULong (d1.data);
2091                                 data_string_forget (&d1, MDL);
2092                         }
2093                 }
2094
2095                 if ((oc = lookup_option (&server_universe, state -> options,
2096                                          SV_BOOTP_LEASE_CUTOFF))) {
2097                         if (evaluate_option_cache (&d1, packet, lease,
2098                                                    (struct client_state *)0,
2099                                                    packet -> options,
2100                                                    state -> options,
2101                                                    &lease -> scope, oc, MDL)) {
2102                                 if (d1.len == sizeof (u_int32_t))
2103                                         lease_time = (getULong (d1.data) -
2104                                                       cur_time);
2105                                 data_string_forget (&d1, MDL);
2106                         }
2107                 }
2108
2109                 lt -> ends = state -> offered_expiry = cur_time + lease_time;
2110                 lt -> next_binding_state = FTS_ACTIVE;
2111         }
2112
2113         lt -> timestamp = cur_time;
2114
2115         /* Record the uid, if given... */
2116         oc = lookup_option (&dhcp_universe, packet -> options,
2117                             DHO_DHCP_CLIENT_IDENTIFIER);
2118         if (oc &&
2119             evaluate_option_cache (&d1, packet, lease,
2120                                    (struct client_state *)0,
2121                                    packet -> options, state -> options,
2122                                    &lease -> scope, oc, MDL)) {
2123                 if (d1.len <= sizeof lt -> uid_buf) {
2124                         memcpy (lt -> uid_buf, d1.data, d1.len);
2125                         lt -> uid = lt -> uid_buf;
2126                         lt -> uid_max = sizeof lt -> uid_buf;
2127                         lt -> uid_len = d1.len;
2128                 } else {
2129                         unsigned char *tuid;
2130                         lt -> uid_max = d1.len;
2131                         lt -> uid_len = d1.len;
2132                         tuid = (unsigned char *)dmalloc (lt -> uid_max, MDL);
2133                         /* XXX inelegant */
2134                         if (!tuid)
2135                                 log_fatal ("no memory for large uid.");
2136                         memcpy (tuid, d1.data, lt -> uid_len);
2137                         lt -> uid = tuid;
2138                 }
2139                 data_string_forget (&d1, MDL);
2140         }
2141
2142         if (host) {
2143                 host_reference (&lt -> host, host, MDL);
2144                 host_dereference (&host, MDL);
2145         }
2146         if (lease -> subnet)
2147                 subnet_reference (&lt -> subnet, lease -> subnet, MDL);
2148         if (lease -> billing_class)
2149                 class_reference (&lt -> billing_class,
2150                                  lease -> billing_class, MDL);
2151
2152         /* Set a flag if this client is a broken client that NUL
2153            terminates string options and expects us to do likewise. */
2154         if (ms_nulltp)
2155                 lease -> flags |= MS_NULL_TERMINATION;
2156         else
2157                 lease -> flags &= ~MS_NULL_TERMINATION;
2158
2159         /* Save any bindings. */
2160         if (lease -> scope) {
2161                 binding_scope_reference (&lt -> scope, lease -> scope, MDL);
2162                 binding_scope_dereference (&lease -> scope, MDL);
2163         }
2164         if (lease -> agent_options)
2165                 option_chain_head_reference (&lt -> agent_options,
2166                                              lease -> agent_options, MDL);
2167
2168         /* If we got relay agent information options, and the packet really
2169            looks like it came through a relay agent, and if this feature is
2170            not disabled, save the relay agent information options that came
2171            in with the packet, so that we can use them at renewal time when
2172            the packet won't have gone through a relay agent. */
2173         if (packet -> raw -> giaddr.s_addr &&
2174             packet -> options -> universe_count > agent_universe.index &&
2175             packet -> options -> universes [agent_universe.index] &&
2176             (state -> options -> universe_count <= agent_universe.index ||
2177              state -> options -> universes [agent_universe.index] ==
2178              packet -> options -> universes [agent_universe.index])) {
2179             oc = lookup_option (&server_universe, state -> options,
2180                                 SV_STASH_AGENT_OPTIONS);
2181             if (!oc ||
2182                 evaluate_boolean_option_cache (&ignorep, packet, lease,
2183                                                (struct client_state *)0,
2184                                                packet -> options,
2185                                                state -> options,
2186                                                &lease -> scope, oc, MDL)) {
2187                 if (lt -> agent_options)
2188                     option_chain_head_dereference (&lt -> agent_options, MDL);
2189                 option_chain_head_reference
2190                         (&lt -> agent_options,
2191                          (struct option_chain_head *)
2192                          packet -> options -> universes [agent_universe.index],
2193                          MDL);
2194             }
2195         }
2196
2197         /* Replace the old lease hostname with the new one, if it's changed. */
2198         oc = lookup_option (&dhcp_universe, packet -> options, DHO_HOST_NAME);
2199         if (oc)
2200                 s1 = evaluate_option_cache (&d1, packet, (struct lease *)0,
2201                                             (struct client_state *)0,
2202                                             packet -> options,
2203                                             (struct option_state *)0,
2204                                             &global_scope, oc, MDL);
2205         else
2206                 s1 = 0;
2207
2208         if (oc && s1 &&
2209             lease -> client_hostname &&
2210             strlen (lease -> client_hostname) == d1.len &&
2211             !memcmp (lease -> client_hostname, d1.data, d1.len)) {
2212                 /* Hasn't changed. */
2213                 data_string_forget (&d1, MDL);
2214                 lt -> client_hostname = lease -> client_hostname;
2215                 lease -> client_hostname = (char *)0;
2216         } else if (oc && s1) {
2217                 lt -> client_hostname = dmalloc (d1.len + 1, MDL);
2218                 if (!lt -> client_hostname)
2219                         log_error ("no memory for client hostname.");
2220                 else {
2221                         memcpy (lt -> client_hostname, d1.data, d1.len);
2222                         lt -> client_hostname [d1.len] = 0;
2223                 }
2224                 data_string_forget (&d1, MDL);
2225         }
2226
2227         /* Record the hardware address, if given... */
2228         lt -> hardware_addr.hlen = packet -> raw -> hlen + 1;
2229         lt -> hardware_addr.hbuf [0] = packet -> raw -> htype;
2230         memcpy (&lt -> hardware_addr.hbuf [1], packet -> raw -> chaddr,
2231                 sizeof packet -> raw -> chaddr);
2232
2233         lt -> flags = lease -> flags & ~PERSISTENT_FLAGS;
2234
2235         /* If there are statements to execute when the lease is
2236            committed, execute them. */
2237         if (lease -> on_commit && (!offer || offer == DHCPACK)) {
2238                 execute_statements ((struct binding_value **)0,
2239                                     packet, lt, (struct client_state *)0,
2240                                     packet -> options,
2241                                     state -> options, &lt -> scope,
2242                                     lease -> on_commit);
2243                 if (lease -> on_commit)
2244                         executable_statement_dereference (&lease -> on_commit,
2245                                                           MDL);
2246         }
2247
2248 #ifdef NSUPDATE
2249         /* Perform DDNS updates, if configured to. */
2250         if ((!offer || offer == DHCPACK) &&
2251             (!(oc = lookup_option (&server_universe, state -> options,
2252                                    SV_DDNS_UPDATES)) ||
2253              evaluate_boolean_option_cache (&ignorep, packet, lt,
2254                                             (struct client_state *)0,
2255                                             packet -> options,
2256                                             state -> options,
2257                                             &lt -> scope, oc, MDL))) {
2258                 ddns_updates (packet, lt, lease, state);
2259         }
2260 #endif /* NSUPDATE */
2261
2262         /* Don't call supersede_lease on a mocked-up lease. */
2263         if (lease -> flags & STATIC_LEASE) {
2264                 /* Copy the hardware address into the static lease
2265                    structure. */
2266                 lease -> hardware_addr.hlen = packet -> raw -> hlen + 1;
2267                 lease -> hardware_addr.hbuf [0] = packet -> raw -> htype;
2268                 memcpy (&lease -> hardware_addr.hbuf [1],
2269                         packet -> raw -> chaddr,
2270                         sizeof packet -> raw -> chaddr); /* XXX */
2271         } else {
2272                 /* Install the new information about this lease in the
2273                    database.  If this is a DHCPACK or a dynamic BOOTREPLY
2274                    and we can't write the lease, don't ACK it (or BOOTREPLY
2275                    it) either. */
2276
2277                 if (!supersede_lease (lease, lt, !offer || offer == DHCPACK,
2278                                       offer == DHCPACK, offer == DHCPACK)) {
2279                         log_info ("%s: database update failed", msg);
2280                         free_lease_state (state, MDL);
2281                         lease_dereference (&lt, MDL);
2282                         return;
2283                 }
2284         }
2285         lease_dereference (&lt, MDL);
2286
2287         /* Remember the interface on which the packet arrived. */
2288         state -> ip = packet -> interface;
2289
2290         /* Remember the giaddr, xid, secs, flags and hops. */
2291         state -> giaddr = packet -> raw -> giaddr;
2292         state -> ciaddr = packet -> raw -> ciaddr;
2293         state -> xid = packet -> raw -> xid;
2294         state -> secs = packet -> raw -> secs;
2295         state -> bootp_flags = packet -> raw -> flags;
2296         state -> hops = packet -> raw -> hops;
2297         state -> offer = offer;
2298
2299         /* If we're always supposed to broadcast to this client, set
2300            the broadcast bit in the bootp flags field. */
2301         if ((oc = lookup_option (&server_universe, state -> options,
2302                                 SV_ALWAYS_BROADCAST)) &&
2303             evaluate_boolean_option_cache (&ignorep, packet, lease,
2304                                            (struct client_state *)0,
2305                                            packet -> options, state -> options,
2306                                            &lease -> scope, oc, MDL))
2307                 state -> bootp_flags |= htons (BOOTP_BROADCAST);
2308
2309         /* Get the Maximum Message Size option from the packet, if one
2310            was sent. */
2311         oc = lookup_option (&dhcp_universe, packet -> options,
2312                             DHO_DHCP_MAX_MESSAGE_SIZE);
2313         if (oc &&
2314             evaluate_option_cache (&d1, packet, lease,
2315                                    (struct client_state *)0,
2316                                    packet -> options, state -> options,
2317                                    &lease -> scope, oc, MDL)) {
2318                 if (d1.len == sizeof (u_int16_t))
2319                         state -> max_message_size = getUShort (d1.data);
2320                 data_string_forget (&d1, MDL);
2321         } else {
2322                 oc = lookup_option (&dhcp_universe, state -> options,
2323                                     DHO_DHCP_MAX_MESSAGE_SIZE);
2324                 if (oc &&
2325                     evaluate_option_cache (&d1, packet, lease,
2326                                            (struct client_state *)0,
2327                                            packet -> options, state -> options,
2328                                            &lease -> scope, oc, MDL)) {
2329                         if (d1.len == sizeof (u_int16_t))
2330                                 state -> max_message_size =
2331                                         getUShort (d1.data);
2332                         data_string_forget (&d1, MDL);
2333                 }
2334         }
2335
2336         /* Get the Subnet Selection option from the packet, if one
2337            was sent. */
2338         if ((oc = lookup_option (&dhcp_universe, packet -> options,
2339                                  DHO_SUBNET_SELECTION))) {
2340
2341                 /* Make a copy of the data. */
2342                 struct option_cache *noc = (struct option_cache *)0;
2343                 if (option_cache_allocate (&noc, MDL)) {
2344                         if (oc -> data.len)
2345                                 data_string_copy (&noc -> data,
2346                                                   &oc -> data, MDL);
2347                         if (oc -> expression)
2348                                 expression_reference (&noc -> expression,
2349                                                       oc -> expression, MDL);
2350                         if (oc -> option)
2351                                 noc -> option = oc -> option;
2352                 }
2353
2354                 save_option (&dhcp_universe, state -> options, noc);
2355                 option_cache_dereference (&noc, MDL);
2356         }
2357
2358         /* Now, if appropriate, put in DHCP-specific options that
2359            override those. */
2360         if (state -> offer) {
2361                 i = DHO_DHCP_MESSAGE_TYPE;
2362                 oc = (struct option_cache *)0;
2363                 if (option_cache_allocate (&oc, MDL)) {
2364                         if (make_const_data (&oc -> expression,
2365                                              &state -> offer, 1, 0, 0, MDL)) {
2366                                 oc -> option =
2367                                         dhcp_universe.options [i];
2368                                 save_option (&dhcp_universe,
2369                                              state -> options, oc);
2370                         }
2371                         option_cache_dereference (&oc, MDL);
2372                 }
2373                 i = DHO_DHCP_SERVER_IDENTIFIER;
2374                 if (!(oc = lookup_option (&dhcp_universe,
2375                                           state -> options, i))) {
2376                  use_primary:
2377                         oc = (struct option_cache *)0;
2378                         if (option_cache_allocate (&oc, MDL)) {
2379                                 if (make_const_data
2380                                     (&oc -> expression,
2381                                      ((unsigned char *)
2382                                       &state -> ip -> primary_address),
2383                                      sizeof state -> ip -> primary_address,
2384                                      0, 0, MDL)) {
2385                                         oc -> option =
2386                                                 dhcp_universe.options [i];
2387                                         save_option (&dhcp_universe,
2388                                                      state -> options, oc);
2389                                 }
2390                                 option_cache_dereference (&oc, MDL);
2391                         }
2392                         state -> from.len =
2393                                 sizeof state -> ip -> primary_address;
2394                         memcpy (state -> from.iabuf,
2395                                 &state -> ip -> primary_address,
2396                                 state -> from.len);
2397                 } else {
2398                         if (evaluate_option_cache (&d1, packet, lease,
2399                                                    (struct client_state *)0,
2400                                                    packet -> options,
2401                                                    state -> options,
2402                                                    &lease -> scope, oc, MDL)) {
2403                                 if (!d1.len ||
2404                                     d1.len > sizeof state -> from.iabuf) {
2405                                         data_string_forget (&d1, MDL);
2406                                         goto use_primary;
2407                                 }
2408                                 memcpy (state -> from.iabuf, d1.data, d1.len);
2409                                 state -> from.len = d1.len;
2410                                 data_string_forget (&d1, MDL);
2411                         } else
2412                                 goto use_primary;
2413                 }
2414
2415                 offered_lease_time =
2416                         state -> offered_expiry - cur_time;
2417
2418                 putULong ((unsigned char *)&state -> expiry,
2419                           (unsigned long)offered_lease_time);
2420                 i = DHO_DHCP_LEASE_TIME;
2421                 if (lookup_option (&dhcp_universe, state -> options, i))
2422                         log_error ("dhcp-lease-time option for %s overridden.",
2423                               inet_ntoa (state -> ciaddr));
2424                 oc = (struct option_cache *)0;
2425                 if (option_cache_allocate (&oc, MDL)) {
2426                         if (make_const_data (&oc -> expression,
2427                                              (unsigned char *)&state -> expiry,
2428                                              sizeof state -> expiry,
2429                                              0, 0, MDL)) {
2430                                 oc -> option = dhcp_universe.options [i];
2431                                 save_option (&dhcp_universe,
2432                                              state -> options, oc);
2433                         }
2434                         option_cache_dereference (&oc, MDL);
2435                 }
2436
2437                 /* Renewal time is lease time * 0.5. */
2438                 offered_lease_time /= 2;
2439                 putULong ((unsigned char *)&state -> renewal,
2440                           (unsigned long)offered_lease_time);
2441                 i = DHO_DHCP_RENEWAL_TIME;
2442                 if (lookup_option (&dhcp_universe, state -> options, i))
2443                         log_error ("overriding dhcp-renewal-time for %s.",
2444                                    inet_ntoa (state -> ciaddr));
2445                 oc = (struct option_cache *)0;
2446                 if (option_cache_allocate (&oc, MDL)) {
2447                         if (make_const_data (&oc -> expression,
2448                                              (unsigned char *)
2449                                              &state -> renewal,
2450                                              sizeof state -> renewal,
2451                                              0, 0, MDL)) {
2452                                 oc -> option = dhcp_universe.options [i];
2453                                 save_option (&dhcp_universe,
2454                                              state -> options, oc);
2455                         }
2456                         option_cache_dereference (&oc, MDL);
2457                 }
2458
2459                 /* Rebinding time is lease time * 0.875. */
2460                 offered_lease_time += (offered_lease_time / 2
2461                                        + offered_lease_time / 4);
2462                 putULong ((unsigned char *)&state -> rebind,
2463                           (unsigned)offered_lease_time);
2464                 i = DHO_DHCP_REBINDING_TIME;
2465                 if (lookup_option (&dhcp_universe, state -> options, i))
2466                         log_error ("overriding dhcp-rebinding-time for %s.",
2467                               inet_ntoa (state -> ciaddr));
2468                 oc = (struct option_cache *)0;
2469                 if (option_cache_allocate (&oc, MDL)) {
2470                         if (make_const_data (&oc -> expression,
2471                                              (unsigned char *)&state -> rebind,
2472                                              sizeof state -> rebind,
2473                                              0, 0, MDL)) {
2474                                 oc -> option = dhcp_universe.options [i];
2475                                 save_option (&dhcp_universe,
2476                                              state -> options, oc);
2477                         }
2478                         option_cache_dereference (&oc, MDL);
2479                 }
2480         } else {
2481                 state -> from.len =
2482                         sizeof state -> ip -> primary_address;
2483                 memcpy (state -> from.iabuf,
2484                         &state -> ip -> primary_address,
2485                         state -> from.len);
2486         }
2487
2488         /* Figure out the address of the boot file server. */
2489         memcpy (&state -> siaddr, state -> from.iabuf, sizeof state -> siaddr);
2490         if ((oc =
2491              lookup_option (&server_universe,
2492                             state -> options, SV_NEXT_SERVER))) {
2493                 if (evaluate_option_cache (&d1, packet, lease,
2494                                            (struct client_state *)0,
2495                                            packet -> options, state -> options,
2496                                            &lease -> scope, oc, MDL)) {
2497                         /* If there was more than one answer,
2498                            take the first. */
2499                         if (d1.len >= 4 && d1.data)
2500                                 memcpy (&state -> siaddr, d1.data, 4);
2501                         data_string_forget (&d1, MDL);
2502                 }
2503         }
2504
2505         /* Use the subnet mask from the subnet declaration if no other
2506            mask has been provided. */
2507         i = DHO_SUBNET_MASK;
2508         if (!lookup_option (&dhcp_universe, state -> options, i)) {
2509                 oc = (struct option_cache *)0;
2510                 if (option_cache_allocate (&oc, MDL)) {
2511                         if (make_const_data (&oc -> expression,
2512                                              lease -> subnet -> netmask.iabuf,
2513                                              lease -> subnet -> netmask.len,
2514                                              0, 0, MDL)) {
2515                                 oc -> option = dhcp_universe.options [i];
2516                                 save_option (&dhcp_universe,
2517                                              state -> options, oc);
2518                         }
2519                         option_cache_dereference (&oc, MDL);
2520                 }
2521         }
2522
2523         /* Use the hostname from the host declaration if there is one
2524            and no hostname has otherwise been provided, and if the 
2525            use-host-decl-name flag is set. */
2526         i = DHO_HOST_NAME;
2527         j = SV_USE_HOST_DECL_NAMES;
2528         if (!lookup_option (&dhcp_universe, state -> options, i) &&
2529             lease -> host && lease -> host -> name &&
2530             (evaluate_boolean_option_cache
2531              (&ignorep, packet, lease, (struct client_state *)0,
2532               packet -> options, state -> options, &lease -> scope,
2533               lookup_option (&server_universe, state -> options, j), MDL))) {
2534                 oc = (struct option_cache *)0;
2535                 if (option_cache_allocate (&oc, MDL)) {
2536                         if (make_const_data (&oc -> expression,
2537                                              ((unsigned char *)
2538                                               lease -> host -> name),
2539                                              strlen (lease -> host -> name),
2540                                              1, 0, MDL)) {
2541                                 oc -> option = dhcp_universe.options [i];
2542                                 save_option (&dhcp_universe,
2543                                              state -> options, oc);
2544                         }
2545                         option_cache_dereference (&oc, MDL);
2546                 }
2547         }
2548
2549         /* If we don't have a hostname yet, and we've been asked to do
2550            a reverse lookup to find the hostname, do it. */
2551         j = SV_GET_LEASE_HOSTNAMES;
2552         if (!lookup_option (&server_universe, state -> options, i) &&
2553             (evaluate_boolean_option_cache
2554              (&ignorep, packet, lease, (struct client_state *)0,
2555               packet -> options, state -> options, &lease -> scope,
2556               lookup_option (&server_universe, state -> options, j), MDL))) {
2557                 struct in_addr ia;
2558                 struct hostent *h;
2559                 
2560                 memcpy (&ia, lease -> ip_addr.iabuf, 4);
2561                 
2562                 h = gethostbyaddr ((char *)&ia, sizeof ia, AF_INET);
2563                 if (!h)
2564                         log_error ("No hostname for %s", inet_ntoa (ia));
2565                 else {
2566                         oc = (struct option_cache *)0;
2567                         if (option_cache_allocate (&oc, MDL)) {
2568                                 if (make_const_data (&oc -> expression,
2569                                                      ((unsigned char *)
2570                                                       h -> h_name),
2571                                                      strlen (h -> h_name) + 1,
2572                                                      1, 1, MDL)) {
2573                                         oc -> option =
2574                                                 dhcp_universe.options [i];
2575                                         save_option (&dhcp_universe,
2576                                                      state -> options, oc);
2577                                 }
2578                                 option_cache_dereference (&oc, MDL);
2579                         }
2580                 }
2581         }
2582
2583         /* If so directed, use the leased IP address as the router address.
2584            This supposedly makes Win95 machines ARP for all IP addresses,
2585            so if the local router does proxy arp, you win. */
2586
2587         if (evaluate_boolean_option_cache
2588             (&ignorep, packet, lease, (struct client_state *)0,
2589              packet -> options, state -> options, &lease -> scope,
2590              lookup_option (&server_universe, state -> options,
2591                             SV_USE_LEASE_ADDR_FOR_DEFAULT_ROUTE), MDL)) {
2592                 i = DHO_ROUTERS;
2593                 oc = lookup_option (&dhcp_universe, state -> options, i);
2594                 if (!oc) {
2595                         oc = (struct option_cache *)0;
2596                         if (option_cache_allocate (&oc, MDL)) {
2597                                 if (make_const_data (&oc -> expression,
2598                                                      lease -> ip_addr.iabuf,
2599                                                      lease -> ip_addr.len,
2600                                                      0, 0, MDL)) {
2601                                         oc -> option =
2602                                                 dhcp_universe.options [i];
2603                                         save_option (&dhcp_universe,
2604                                                      state -> options, oc);
2605                                 }
2606                                 option_cache_dereference (&oc, MDL);    
2607                         }
2608                 }
2609         }
2610
2611         /* If a site option space has been specified, use that for
2612            site option codes. */
2613         i = SV_SITE_OPTION_SPACE;
2614         if ((oc = lookup_option (&server_universe, state -> options, i)) &&
2615             evaluate_option_cache (&d1, packet, lease,
2616                                    (struct client_state *)0,
2617                                    packet -> options, state -> options,
2618                                    &lease -> scope, oc, MDL)) {
2619                 struct universe *u = (struct universe *)0;
2620
2621                 if (!universe_hash_lookup (&u, universe_hash,
2622                                            (const char *)d1.data, d1.len,
2623                                            MDL)) {
2624                         log_error ("unknown option space %s.", d1.data);
2625                         return;
2626                 }
2627
2628                 state -> options -> site_universe = u -> index;
2629                 state -> options -> site_code_min = 128; /* XXX */
2630                 data_string_forget (&d1, MDL);
2631         } else {
2632                 state -> options -> site_code_min = 0;
2633                 state -> options -> site_universe = dhcp_universe.index;
2634         }
2635
2636         /* If the client has provided a list of options that it wishes
2637            returned, use it to prioritize.  If there's a parameter
2638            request list in scope, use that in preference.  Otherwise
2639            use the default priority list. */
2640
2641         oc = lookup_option (&dhcp_universe, state -> options,
2642                             DHO_DHCP_PARAMETER_REQUEST_LIST);
2643
2644         if (!oc)
2645                 oc = lookup_option (&dhcp_universe, packet -> options,
2646                                     DHO_DHCP_PARAMETER_REQUEST_LIST);
2647         if (oc)
2648                 evaluate_option_cache (&state -> parameter_request_list,
2649                                        packet, lease, (struct client_state *)0,
2650                                        packet -> options, state -> options,
2651                                        &lease -> scope, oc, MDL);
2652
2653 #ifdef DEBUG_PACKET
2654         dump_packet (packet);
2655         dump_raw ((unsigned char *)packet -> raw, packet -> packet_length);
2656 #endif
2657
2658         lease -> state = state;
2659
2660         log_info ("%s", msg);
2661
2662         /* Hang the packet off the lease state. */
2663         packet_reference (&lease -> state -> packet, packet, MDL);
2664
2665         /* If this is a DHCPOFFER, ping the lease address before actually
2666            sending the offer. */
2667         if (offer == DHCPOFFER && !(lease -> flags & STATIC_LEASE) &&
2668             cur_time - lease -> timestamp > 60 &&
2669             (!(oc = lookup_option (&server_universe, state -> options,
2670                                    SV_PING_CHECKS)) ||
2671              evaluate_boolean_option_cache (&ignorep, packet, lease,
2672                                             (struct client_state *)0,
2673                                             packet -> options,
2674                                             state -> options,
2675                                             &lease -> scope, oc, MDL))) {
2676                 lease -> timestamp = cur_time;
2677                 icmp_echorequest (&lease -> ip_addr);
2678
2679                 /* Determine wether to use configured or default ping timeout.
2680                  */
2681                 if ((oc = lookup_option (&server_universe, state -> options,
2682                                                 SV_PING_TIMEOUT)) &&
2683                     evaluate_option_cache (&d1, packet, lease, NULL,
2684                                                 packet -> options,
2685                                                 state -> options,
2686                                                 &lease -> scope, oc, MDL)) {
2687                         if (d1.len == sizeof (u_int32_t))
2688                                 ping_timeout = getULong (d1.data);
2689                         else
2690                                 ping_timeout = DEFAULT_PING_TIMEOUT;
2691
2692                         data_string_forget (&d1, MDL);
2693                 } else
2694                         ping_timeout = DEFAULT_PING_TIMEOUT;
2695
2696 #ifdef DEBUG
2697                 log_debug ("Ping timeout: %ld", (long)ping_timeout);
2698 #endif
2699
2700                 add_timeout (cur_time + ping_timeout, lease_ping_timeout, lease,
2701                              (tvref_t)lease_reference,
2702                              (tvunref_t)lease_dereference);
2703                 ++outstanding_pings;
2704         } else {
2705                 lease -> timestamp = cur_time;
2706                 dhcp_reply (lease);
2707         }
2708 }
2709
2710 void dhcp_reply (lease)
2711         struct lease *lease;
2712 {
2713         int bufs = 0;
2714         unsigned packet_length;
2715         struct dhcp_packet raw;
2716         struct sockaddr_in to;
2717         struct in_addr from;
2718         struct hardware hto;
2719         int result;
2720         int i;
2721         struct lease_state *state = lease -> state;
2722         int nulltp, bootpp, unicastp = 1;
2723         struct option_tag *ot, *not;
2724         struct data_string d1;
2725         struct option_cache *oc;
2726         const char *s;
2727
2728         if (!state)
2729                 log_fatal ("dhcp_reply was supplied lease with no state!");
2730
2731         /* Compose a response for the client... */
2732         memset (&raw, 0, sizeof raw);
2733         memset (&d1, 0, sizeof d1);
2734
2735         /* Copy in the filename if given; otherwise, flag the filename
2736            buffer as available for options. */
2737         if (state -> filename.len && state -> filename.data) {
2738                 memcpy (raw.file,
2739                         state -> filename.data,
2740                         state -> filename.len > sizeof raw.file
2741                         ? sizeof raw.file : state -> filename.len);
2742                 if (sizeof raw.file > state -> filename.len)
2743                         memset (&raw.file [state -> filename.len], 0,
2744                                 (sizeof raw.file) - state -> filename.len);
2745         } else
2746                 bufs |= 1;
2747
2748         /* Copy in the server name if given; otherwise, flag the
2749            server_name buffer as available for options. */
2750         if (state -> server_name.len && state -> server_name.data) {
2751                 memcpy (raw.sname,
2752                         state -> server_name.data,
2753                         state -> server_name.len > sizeof raw.sname
2754                         ? sizeof raw.sname : state -> server_name.len);
2755                 if (sizeof raw.sname > state -> server_name.len)
2756                         memset (&raw.sname [state -> server_name.len], 0,
2757                                 (sizeof raw.sname) - state -> server_name.len);
2758         } else
2759                 bufs |= 2; /* XXX */
2760
2761         memcpy (raw.chaddr,
2762                 &lease -> hardware_addr.hbuf [1], sizeof raw.chaddr);
2763         raw.hlen = lease -> hardware_addr.hlen - 1;
2764         raw.htype = lease -> hardware_addr.hbuf [0];
2765
2766         /* See if this is a Microsoft client that NUL-terminates its
2767            strings and expects us to do likewise... */
2768         if (lease -> flags & MS_NULL_TERMINATION)
2769                 nulltp = 1;
2770         else
2771                 nulltp = 0;
2772
2773         /* See if this is a bootp client... */
2774         if (state -> offer)
2775                 bootpp = 0;
2776         else
2777                 bootpp = 1;
2778
2779         /* Insert such options as will fit into the buffer. */
2780         packet_length = cons_options (state -> packet, &raw, lease,
2781                                       (struct client_state *)0,
2782                                       state -> max_message_size,
2783                                       state -> packet -> options,
2784                                       state -> options, &global_scope,
2785                                       bufs, nulltp, bootpp,
2786                                       &state -> parameter_request_list,
2787                                       (char *)0);
2788
2789         memcpy (&raw.ciaddr, &state -> ciaddr, sizeof raw.ciaddr);
2790         memcpy (&raw.yiaddr, lease -> ip_addr.iabuf, 4);
2791         raw.siaddr = state -> siaddr;
2792         raw.giaddr = state -> giaddr;
2793
2794         raw.xid = state -> xid;
2795         raw.secs = state -> secs;
2796         raw.flags = state -> bootp_flags;
2797         raw.hops = state -> hops;
2798         raw.op = BOOTREPLY;
2799
2800         if (lease -> client_hostname) {
2801                 if ((strlen (lease -> client_hostname) <= 64) &&
2802                     db_printable (lease -> client_hostname))
2803                         s = lease -> client_hostname;
2804                 else
2805                         s = "Hostname Unsuitable for Printing";
2806         } else
2807                 s = (char *)0;
2808
2809         /* Say what we're doing... */
2810         log_info ("%s on %s to %s %s%s%svia %s",
2811                   (state -> offer
2812                    ? (state -> offer == DHCPACK ? "DHCPACK" : "DHCPOFFER")
2813                    : "BOOTREPLY"),
2814                   piaddr (lease -> ip_addr),
2815                   (lease -> hardware_addr.hlen
2816                    ? print_hw_addr (lease -> hardware_addr.hbuf [0],
2817                                     lease -> hardware_addr.hlen - 1,
2818                                     &lease -> hardware_addr.hbuf [1])
2819                    : print_hex_1 (lease -> uid_len, lease -> uid, 
2820                                   lease -> uid_len)),
2821                   s ? "(" : "", s ? s : "", s ? ") " : "",
2822                   (state -> giaddr.s_addr
2823                    ? inet_ntoa (state -> giaddr)
2824                    : state -> ip -> name));
2825
2826         /* Set up the hardware address... */
2827         hto.hlen = lease -> hardware_addr.hlen;
2828         memcpy (hto.hbuf, lease -> hardware_addr.hbuf, hto.hlen);
2829
2830         to.sin_family = AF_INET;
2831 #ifdef HAVE_SA_LEN
2832         to.sin_len = sizeof to;
2833 #endif
2834         memset (to.sin_zero, 0, sizeof to.sin_zero);
2835
2836 #ifdef DEBUG_PACKET
2837         dump_raw ((unsigned char *)&raw, packet_length);
2838 #endif
2839
2840         /* Make sure outgoing packets are at least as big
2841            as a BOOTP packet. */
2842         if (packet_length < BOOTP_MIN_LEN)
2843                 packet_length = BOOTP_MIN_LEN;
2844
2845         /* If this was gatewayed, send it back to the gateway... */
2846         if (raw.giaddr.s_addr) {
2847                 to.sin_addr = raw.giaddr;
2848                 if (raw.giaddr.s_addr != htonl (INADDR_LOOPBACK))
2849                         to.sin_port = local_port;
2850                 else
2851                         to.sin_port = remote_port; /* For debugging. */
2852
2853                 if (fallback_interface) {
2854                         result = send_packet (fallback_interface,
2855                                               (struct packet *)0,
2856                                               &raw, packet_length,
2857                                               raw.siaddr, &to,
2858                                               (struct hardware *)0);
2859
2860                         free_lease_state (state, MDL);
2861                         lease -> state = (struct lease_state *)0;
2862                         return;
2863                 }
2864
2865         /* If the client is RENEWING, unicast to the client using the
2866            regular IP stack.  Some clients, particularly those that
2867            follow RFC1541, are buggy, and send both ciaddr and server
2868            identifier.  We deal with this situation by assuming that
2869            if we got both dhcp-server-identifier and ciaddr, and
2870            giaddr was not set, then the client is on the local
2871            network, and we can therefore unicast or broadcast to it
2872            successfully.  A client in REQUESTING state on another
2873            network that's making this mistake will have set giaddr,
2874            and will therefore get a relayed response from the above
2875            code. */
2876         } else if (raw.ciaddr.s_addr &&
2877                    !((state -> got_server_identifier ||
2878                       (raw.flags & htons (BOOTP_BROADCAST))) &&
2879                      /* XXX This won't work if giaddr isn't zero, but it is: */
2880                      (state -> shared_network ==
2881                       lease -> subnet -> shared_network)) &&
2882                    state -> offer == DHCPACK) {
2883                 to.sin_addr = raw.ciaddr;
2884                 to.sin_port = remote_port;
2885
2886                 if (fallback_interface) {
2887                         result = send_packet (fallback_interface,
2888                                               (struct packet *)0,
2889                                               &raw, packet_length,
2890                                               raw.siaddr, &to,
2891                                               (struct hardware *)0);
2892                         free_lease_state (state, MDL);
2893                         lease -> state = (struct lease_state *)0;
2894                         return;
2895                 }
2896
2897         /* If it comes from a client that already knows its address
2898            and is not requesting a broadcast response, and we can
2899            unicast to a client without using the ARP protocol, sent it
2900            directly to that client. */
2901         } else if (!(raw.flags & htons (BOOTP_BROADCAST)) &&
2902                    can_unicast_without_arp (state -> ip)) {
2903                 to.sin_addr = raw.yiaddr;
2904                 to.sin_port = remote_port;
2905
2906         /* Otherwise, broadcast it on the local network. */
2907         } else {
2908                 to.sin_addr = limited_broadcast;
2909                 to.sin_port = remote_port;
2910                 if (!(lease -> flags & UNICAST_BROADCAST_HACK))
2911                         unicastp = 0;
2912         }
2913
2914         memcpy (&from, state -> from.iabuf, sizeof from);
2915
2916         result = send_packet (state -> ip,
2917                               (struct packet *)0, &raw, packet_length,
2918                               from, &to,
2919                               unicastp ? &hto : (struct hardware *)0);
2920
2921         /* Free all of the entries in the option_state structure
2922            now that we're done with them. */
2923
2924         free_lease_state (state, MDL);
2925         lease -> state = (struct lease_state *)0;
2926 }
2927
2928 int find_lease (struct lease **lp,
2929                 struct packet *packet, struct shared_network *share, int *ours,
2930                 int *allocatedp, struct lease *ip_lease_in,
2931                 const char *file, int line)
2932 {
2933         struct lease *uid_lease = (struct lease *)0;
2934         struct lease *ip_lease = (struct lease *)0;
2935         struct lease *hw_lease = (struct lease *)0;
2936         struct lease *lease = (struct lease *)0;
2937         struct iaddr cip;
2938         struct host_decl *hp = (struct host_decl *)0;
2939         struct host_decl *host = (struct host_decl *)0;
2940         struct lease *fixed_lease = (struct lease *)0;
2941         struct lease *next = (struct lease *)0;
2942         struct option_cache *oc;
2943         struct data_string d1;
2944         int have_client_identifier = 0;
2945         struct data_string client_identifier;
2946         int status;
2947         struct hardware h;
2948
2949         if (packet -> raw -> ciaddr.s_addr) {
2950                 cip.len = 4;
2951                 memcpy (cip.iabuf, &packet -> raw -> ciaddr, 4);
2952         } else {
2953                 /* Look up the requested address. */
2954                 oc = lookup_option (&dhcp_universe, packet -> options,
2955                                     DHO_DHCP_REQUESTED_ADDRESS);
2956                 memset (&d1, 0, sizeof d1);
2957                 if (oc &&
2958                     evaluate_option_cache (&d1, packet, (struct lease *)0,
2959                                            (struct client_state *)0,
2960                                            packet -> options,
2961                                            (struct option_state *)0,
2962                                            &global_scope, oc, MDL)) {
2963                         packet -> got_requested_address = 1;
2964                         cip.len = 4;
2965                         memcpy (cip.iabuf, d1.data, cip.len);
2966                         data_string_forget (&d1, MDL);
2967                 } else 
2968                         cip.len = 0;
2969         }
2970
2971         /* Try to find a host or lease that's been assigned to the
2972            specified unique client identifier. */
2973         oc = lookup_option (&dhcp_universe, packet -> options,
2974                             DHO_DHCP_CLIENT_IDENTIFIER);
2975         memset (&client_identifier, 0, sizeof client_identifier);
2976         if (oc &&
2977             evaluate_option_cache (&client_identifier,
2978                                    packet, (struct lease *)0,
2979                                    (struct client_state *)0,
2980                                    packet -> options, (struct option_state *)0,
2981                                    &global_scope, oc, MDL)) {
2982                 /* Remember this for later. */
2983                 have_client_identifier = 1;
2984
2985                 /* First, try to find a fixed host entry for the specified
2986                    client identifier... */
2987                 if (find_hosts_by_uid (&hp, client_identifier.data,
2988                                        client_identifier.len, MDL)) {
2989                         /* Remember if we know of this client. */
2990                         packet -> known = 1;
2991                         mockup_lease (&fixed_lease, packet, share, hp);
2992                 }
2993
2994 #if defined (DEBUG_FIND_LEASE)
2995                 if (fixed_lease) {
2996                         log_info ("Found host for client identifier: %s.",
2997                               piaddr (fixed_lease -> ip_addr));
2998                 }
2999 #endif
3000                 if (hp) {
3001                         if (!fixed_lease) /* Save the host if we found one. */
3002                                 host_reference (&host, hp, MDL);
3003                         host_dereference (&hp, MDL);
3004                 }
3005
3006                 find_lease_by_uid (&uid_lease, client_identifier.data,
3007                                    client_identifier.len, MDL);
3008         }
3009
3010         /* If we didn't find a fixed lease using the uid, try doing
3011            it with the hardware address... */
3012         if (!fixed_lease && !host) {
3013                 if (find_hosts_by_haddr (&hp, packet -> raw -> htype,
3014                                          packet -> raw -> chaddr,
3015                                          packet -> raw -> hlen, MDL)) {
3016                         /* Remember if we know of this client. */
3017                         packet -> known = 1;
3018                         if (host)
3019                                 host_dereference (&host, MDL);
3020                         host_reference (&host, hp, MDL);
3021                         host_dereference (&hp, MDL);
3022                         mockup_lease (&fixed_lease, packet, share, host);
3023 #if defined (DEBUG_FIND_LEASE)
3024                         if (fixed_lease) {
3025                                 log_info ("Found host for link address: %s.",
3026                                       piaddr (fixed_lease -> ip_addr));
3027                         }
3028 #endif
3029                 }
3030         }
3031
3032         /* If fixed_lease is present but does not match the requested
3033            IP address, and this is a DHCPREQUEST, then we can't return
3034            any other lease, so we might as well return now. */
3035         if (packet -> packet_type == DHCPREQUEST && fixed_lease &&
3036             (fixed_lease -> ip_addr.len != cip.len ||
3037              memcmp (fixed_lease -> ip_addr.iabuf,
3038                      cip.iabuf, cip.len))) {
3039                 if (ours)
3040                         *ours = 1;
3041                 strcpy (dhcp_message, "requested address is incorrect");
3042 #if defined (DEBUG_FIND_LEASE)
3043                 log_info ("Client's fixed-address %s doesn't match %s%s",
3044                           piaddr (fixed_lease -> ip_addr), "request ",
3045                           print_dotted_quads (cip.len, cip.iabuf));
3046 #endif
3047                 goto out;
3048         }
3049
3050         /* If we found leases matching the client identifier, loop through
3051            the n_uid pointer looking for one that's actually valid.   We
3052            can't do this until we get here because we depend on
3053            packet -> known, which may be set by either the uid host
3054            lookup or the haddr host lookup. */
3055         while (uid_lease) {
3056 #if defined (DEBUG_FIND_LEASE)
3057                 log_info ("trying next lease matching client id: %s",
3058                           piaddr (uid_lease -> ip_addr));
3059 #endif
3060
3061 #if defined (FAILOVER_PROTOCOL)
3062                 /* When failover is active, it's possible that there could
3063                    be two "free" leases for the same uid, but only one of
3064                    them that's available for this failover peer to allocate. */
3065                 if (uid_lease -> binding_state != FTS_ACTIVE &&
3066                     !lease_mine_to_reallocate (uid_lease)) {
3067 #if defined (DEBUG_FIND_LEASE)
3068                         log_info ("not mine to allocate: %s",
3069                                   piaddr (uid_lease -> ip_addr));
3070 #endif
3071                         goto n_uid;
3072                 }
3073 #endif
3074
3075                 if (uid_lease -> subnet -> shared_network != share) {
3076 #if defined (DEBUG_FIND_LEASE)
3077                         log_info ("wrong network segment: %s",
3078                                   piaddr (uid_lease -> ip_addr));
3079 #endif
3080                         goto n_uid;
3081                 }
3082
3083                 if ((uid_lease -> pool -> prohibit_list &&
3084                      permitted (packet, uid_lease -> pool -> prohibit_list)) ||
3085                     (uid_lease -> pool -> permit_list &&
3086                      !permitted (packet, uid_lease -> pool -> permit_list))) {
3087 #if defined (DEBUG_FIND_LEASE)
3088                         log_info ("not permitted: %s",
3089                                   piaddr (uid_lease -> ip_addr));
3090 #endif
3091                        n_uid:
3092                         if (uid_lease -> n_uid)
3093                                 lease_reference (&next,
3094                                                  uid_lease -> n_uid, MDL);
3095                         if (!packet -> raw -> ciaddr.s_addr)
3096                                 release_lease (uid_lease, packet);
3097                         lease_dereference (&uid_lease, MDL);
3098                         if (next) {
3099                                 lease_reference (&uid_lease, next, MDL);
3100                                 lease_dereference (&next, MDL);
3101                         }
3102                         continue;
3103                 }
3104                 break;
3105         }
3106 #if defined (DEBUG_FIND_LEASE)
3107         if (uid_lease)
3108                 log_info ("Found lease for client id: %s.",
3109                       piaddr (uid_lease -> ip_addr));
3110 #endif
3111
3112         /* Find a lease whose hardware address matches, whose client
3113            identifier matches, that's permitted, and that's on the
3114            correct subnet. */
3115         h.hlen = packet -> raw -> hlen + 1;
3116         h.hbuf [0] = packet -> raw -> htype;
3117         memcpy (&h.hbuf [1], packet -> raw -> chaddr, packet -> raw -> hlen);
3118         find_lease_by_hw_addr (&hw_lease, h.hbuf, h.hlen, MDL);
3119         while (hw_lease) {
3120 #if defined (DEBUG_FIND_LEASE)
3121                 log_info ("trying next lease matching hw addr: %s",
3122                           piaddr (hw_lease -> ip_addr));
3123 #endif
3124 #if defined (FAILOVER_PROTOCOL)
3125                 /* When failover is active, it's possible that there could
3126                    be two "free" leases for the same uid, but only one of
3127                    them that's available for this failover peer to allocate. */
3128                 if (hw_lease -> binding_state != FTS_ACTIVE &&
3129                     !lease_mine_to_reallocate (hw_lease)) {
3130 #if defined (DEBUG_FIND_LEASE)
3131                         log_info ("not mine to allocate: %s",
3132                                   piaddr (hw_lease -> ip_addr));
3133 #endif
3134                         goto n_hw;
3135                 }
3136 #endif
3137
3138                 if (hw_lease -> binding_state != FTS_FREE &&
3139                     hw_lease -> binding_state != FTS_BACKUP &&
3140                     hw_lease -> uid &&
3141                     (!have_client_identifier ||
3142                      hw_lease -> uid_len != client_identifier.len ||
3143                      memcmp (hw_lease -> uid, client_identifier.data,
3144                              hw_lease -> uid_len))) {
3145 #if defined (DEBUG_FIND_LEASE)
3146                         log_info ("wrong client identifier: %s",
3147                                   piaddr (hw_lease -> ip_addr));
3148 #endif
3149                         goto n_hw;
3150                         continue;
3151                 }
3152                 if (hw_lease -> subnet -> shared_network != share) {
3153 #if defined (DEBUG_FIND_LEASE)
3154                         log_info ("wrong network segment: %s",
3155                                   piaddr (hw_lease -> ip_addr));
3156 #endif
3157                         goto n_hw;
3158                         continue;
3159                 }
3160                 if ((hw_lease -> pool -> prohibit_list &&
3161                       permitted (packet, hw_lease -> pool -> prohibit_list)) ||
3162                     (hw_lease -> pool -> permit_list &&
3163                      !permitted (packet, hw_lease -> pool -> permit_list))) {
3164 #if defined (DEBUG_FIND_LEASE)
3165                         log_info ("not permitted: %s",
3166                                   piaddr (hw_lease -> ip_addr));
3167 #endif
3168                         if (!packet -> raw -> ciaddr.s_addr)
3169                                 release_lease (hw_lease, packet);
3170                        n_hw:
3171                         if (hw_lease -> n_hw)
3172                                 lease_reference (&next, hw_lease -> n_hw, MDL);
3173                         lease_dereference (&hw_lease, MDL);
3174                         if (next) {
3175                                 lease_reference (&hw_lease, next, MDL);
3176                                 lease_dereference (&next, MDL);
3177                         }
3178                         continue;
3179                 }
3180                 break;
3181         }
3182 #if defined (DEBUG_FIND_LEASE)
3183         if (hw_lease)
3184                 log_info ("Found lease for hardware address: %s.",
3185                       piaddr (hw_lease -> ip_addr));
3186 #endif
3187
3188         /* Try to find a lease that's been allocated to the client's
3189            IP address. */
3190         if (ip_lease_in)
3191                 lease_reference (&ip_lease, ip_lease_in, MDL);
3192         else if (cip.len)
3193                 find_lease_by_ip_addr (&ip_lease, cip, MDL);
3194
3195 #if defined (DEBUG_FIND_LEASE)
3196         if (ip_lease)
3197                 log_info ("Found lease for requested address: %s.",
3198                       piaddr (ip_lease -> ip_addr));
3199 #endif
3200
3201         /* If ip_lease is valid at this point, set ours to one, so that
3202            even if we choose a different lease, we know that the address
3203            the client was requesting was ours, and thus we can NAK it. */
3204         if (ip_lease && ours)
3205                 *ours = 1;
3206
3207         /* If the requested IP address isn't on the network the packet
3208            came from, don't use it.  Allow abandoned leases to be matched
3209            here - if the client is requesting it, there's a decent chance
3210            that it's because the lease database got trashed and a client
3211            that thought it had this lease answered an ARP or PING, causing the
3212            lease to be abandoned.   If so, this request probably came from
3213            that client. */
3214         if (ip_lease && (ip_lease -> subnet -> shared_network != share)) {
3215                 if (ours)
3216                         *ours = 1;
3217 #if defined (DEBUG_FIND_LEASE)
3218                 log_info ("...but it was on the wrong shared network.");
3219 #endif
3220                 strcpy (dhcp_message, "requested address on bad subnet");
3221                 lease_dereference (&ip_lease, MDL);
3222         }
3223
3224         /* Toss ip_lease if it hasn't yet expired and doesn't belong to the
3225            client. */
3226         if (ip_lease &&
3227             (ip_lease -> uid ?
3228              (!have_client_identifier ||
3229               ip_lease -> uid_len != client_identifier.len ||
3230               memcmp (ip_lease -> uid, client_identifier.data,
3231                       ip_lease -> uid_len)) :
3232              (ip_lease -> hardware_addr.hbuf [0] != packet -> raw -> htype ||
3233               ip_lease -> hardware_addr.hlen != packet -> raw -> hlen + 1 ||
3234               memcmp (&ip_lease -> hardware_addr.hbuf [1],
3235                       packet -> raw -> chaddr,
3236                       (unsigned)(ip_lease -> hardware_addr.hlen - 1))))) {
3237                 /* If we're not doing failover, the only state in which
3238                    we can allocate this lease to the client is FTS_FREE.
3239                    If we are doing failover, things are more complicated.
3240                    If the lease is free or backup, we let the caller decide
3241                    whether or not to give it out. */
3242                 if (ip_lease -> binding_state != FTS_FREE &&
3243                     ip_lease -> binding_state != FTS_BACKUP) {
3244 #if defined (DEBUG_FIND_LEASE)
3245                         log_info ("rejecting lease for requested address.");
3246 #endif
3247                         /* If we're rejecting it because the peer has
3248                            it, don't set "ours", because we shouldn't NAK. */
3249                         if (ours && ip_lease -> binding_state != FTS_ACTIVE)
3250                                 *ours = 0;
3251                         lease_dereference (&ip_lease, MDL);
3252                 } else
3253                         if (allocatedp)
3254                                 *allocatedp = 1;
3255         }
3256
3257         /* If we got an ip_lease and a uid_lease or hw_lease, and ip_lease
3258            is not active, and is not ours to reallocate, forget about it. */
3259         if (ip_lease && (uid_lease || hw_lease) &&
3260             ip_lease -> binding_state != FTS_ACTIVE &&
3261             !lease_mine_to_reallocate (ip_lease) &&
3262             packet -> packet_type == DHCPDISCOVER) {
3263 #if defined (DEBUG_FIND_LEASE)
3264                 log_info ("ip lease not ours to offer.");
3265 #endif
3266                 lease_dereference (&ip_lease, MDL);
3267         }
3268
3269         /* If for some reason the client has more than one lease
3270            on the subnet that matches its uid, pick the one that
3271            it asked for and (if we can) free the other. */
3272         if (ip_lease &&
3273             ip_lease -> binding_state == FTS_ACTIVE &&
3274             ip_lease -> uid && ip_lease != uid_lease) {
3275                 if (have_client_identifier &&
3276                     (ip_lease -> uid_len == client_identifier.len) &&
3277                     !memcmp (client_identifier.data,
3278                              ip_lease -> uid, ip_lease -> uid_len)) {
3279                         if (uid_lease) {
3280                             if (uid_lease -> binding_state == FTS_ACTIVE) {
3281                                 log_error ("client %s has duplicate%s on %s",
3282                                            (print_hw_addr
3283                                             (packet -> raw -> htype,
3284                                              packet -> raw -> hlen,
3285                                              packet -> raw -> chaddr)),
3286                                            " leases",
3287                                            (ip_lease -> subnet ->
3288                                             shared_network -> name));
3289
3290                                 /* If the client is REQUESTing the lease,
3291                                    it shouldn't still be using the old
3292                                    one, so we can free it for allocation. */
3293                                 if (uid_lease &&
3294                                     uid_lease -> binding_state == FTS_ACTIVE &&
3295                                     !packet -> raw -> ciaddr.s_addr &&
3296                                     (share ==
3297                                      uid_lease -> subnet -> shared_network) &&
3298                                     packet -> packet_type == DHCPREQUEST)
3299                                         dissociate_lease (uid_lease);
3300                             }
3301                             lease_dereference (&uid_lease, MDL);
3302                             lease_reference (&uid_lease, ip_lease, MDL);
3303                         }
3304                 }
3305
3306                 /* If we get to here and fixed_lease is not null, that means
3307                    that there are both a dynamic lease and a fixed-address
3308                    declaration for the same IP address. */
3309                 if (packet -> packet_type == DHCPREQUEST && fixed_lease) {
3310                         lease_dereference (&fixed_lease, MDL);
3311                       db_conflict:
3312                         log_error ("Dynamic and static leases present for %s.",
3313                                    piaddr (cip));
3314                         log_error ("Remove host declaration %s or remove %s",
3315                                    (fixed_lease && fixed_lease -> host
3316                                     ? (fixed_lease -> host -> name
3317                                        ? fixed_lease -> host -> name
3318                                        : piaddr (cip))
3319                                     : piaddr (cip)),
3320                                     piaddr (cip));
3321                         log_error ("from the dynamic address pool for %s",
3322                                    ip_lease -> subnet -> shared_network -> name
3323                                   );
3324                         if (fixed_lease)
3325                                 lease_dereference (&ip_lease, MDL);
3326                         strcpy (dhcp_message,
3327                                 "database conflict - call for help!");
3328                 }
3329
3330                 if (ip_lease && ip_lease != uid_lease) {
3331 #if defined (DEBUG_FIND_LEASE)
3332                         log_info ("requested address not available.");
3333 #endif
3334                         lease_dereference (&ip_lease, MDL);
3335                 }
3336         }
3337
3338         /* If we get to here with both fixed_lease and ip_lease not
3339            null, then we have a configuration file bug. */
3340         if (packet -> packet_type == DHCPREQUEST && fixed_lease && ip_lease)
3341                 goto db_conflict;
3342
3343         /* Toss extra pointers to the same lease... */
3344         if (hw_lease && hw_lease == uid_lease) {
3345 #if defined (DEBUG_FIND_LEASE)
3346                 log_info ("hardware lease and uid lease are identical.");
3347 #endif
3348                 lease_dereference (&hw_lease, MDL);
3349         }
3350         if (ip_lease && ip_lease == hw_lease) {
3351                 lease_dereference (&hw_lease, MDL);
3352 #if defined (DEBUG_FIND_LEASE)
3353                 log_info ("hardware lease and ip lease are identical.");
3354 #endif
3355         }
3356         if (ip_lease && ip_lease == uid_lease) {
3357                 lease_dereference (&uid_lease, MDL);
3358 #if defined (DEBUG_FIND_LEASE)
3359                 log_info ("uid lease and ip lease are identical.");
3360 #endif
3361         }
3362
3363         /* Make sure the client is permitted to use the requested lease. */
3364         if (ip_lease &&
3365             ((ip_lease -> pool -> prohibit_list &&
3366               permitted (packet, ip_lease -> pool -> prohibit_list)) ||
3367              (ip_lease -> pool -> permit_list &&
3368               !permitted (packet, ip_lease -> pool -> permit_list)))) {
3369                 if (!packet -> raw -> ciaddr.s_addr)
3370                         release_lease (ip_lease, packet);
3371                 lease_dereference (&ip_lease, MDL);
3372         }
3373
3374         if (uid_lease &&
3375             ((uid_lease -> pool -> prohibit_list &&
3376               permitted (packet, uid_lease -> pool -> prohibit_list)) ||
3377              (uid_lease -> pool -> permit_list &&
3378               !permitted (packet, uid_lease -> pool -> permit_list)))) {
3379                 if (!packet -> raw -> ciaddr.s_addr)
3380                         release_lease (uid_lease, packet);
3381                 lease_dereference (&uid_lease, MDL);
3382         }
3383
3384         if (hw_lease &&
3385             ((hw_lease -> pool -> prohibit_list &&
3386               permitted (packet, hw_lease -> pool -> prohibit_list)) ||
3387              (hw_lease -> pool -> permit_list &&
3388               !permitted (packet, hw_lease -> pool -> permit_list)))) {
3389                 if (!packet -> raw -> ciaddr.s_addr)
3390                         release_lease (hw_lease, packet);
3391                 lease_dereference (&hw_lease, MDL);
3392         }
3393
3394         /* If we've already eliminated the lease, it wasn't there to
3395            begin with.   If we have come up with a matching lease,
3396            set the message to bad network in case we have to throw it out. */
3397         if (!ip_lease) {
3398                 strcpy (dhcp_message, "requested address not available");
3399         }
3400
3401         /* If this is a DHCPREQUEST, make sure the lease we're going to return
3402            matches the requested IP address.   If it doesn't, don't return a
3403            lease at all. */
3404         if (packet -> packet_type == DHCPREQUEST &&
3405             !ip_lease && !fixed_lease) {
3406 #if defined (DEBUG_FIND_LEASE)
3407                 log_info ("no applicable lease found for DHCPREQUEST.");
3408 #endif
3409                 goto out;
3410         }
3411
3412         /* At this point, if fixed_lease is nonzero, we can assign it to
3413            this client. */
3414         if (fixed_lease) {
3415                 lease_reference (&lease, fixed_lease, MDL);
3416                 lease_dereference (&fixed_lease, MDL);
3417 #if defined (DEBUG_FIND_LEASE)
3418                 log_info ("choosing fixed address.");
3419 #endif
3420         }
3421
3422         /* If we got a lease that matched the ip address and don't have
3423            a better offer, use that; otherwise, release it. */
3424         if (ip_lease) {
3425                 if (lease) {
3426                         if (!packet -> raw -> ciaddr.s_addr)
3427                                 release_lease (ip_lease, packet);
3428 #if defined (DEBUG_FIND_LEASE)
3429                         log_info ("not choosing requested address (!).");
3430 #endif
3431                 } else {
3432 #if defined (DEBUG_FIND_LEASE)
3433                         log_info ("choosing lease on requested address.");
3434 #endif
3435                         lease_reference (&lease, ip_lease, MDL);
3436                         if (lease -> host)
3437                                 host_dereference (&lease -> host, MDL);
3438                 }
3439                 lease_dereference (&ip_lease, MDL);
3440         }
3441
3442         /* If we got a lease that matched the client identifier, we may want
3443            to use it, but if we already have a lease we like, we must free
3444            the lease that matched the client identifier. */
3445         if (uid_lease) {
3446                 if (lease) {
3447                         if (!packet -> raw -> ciaddr.s_addr &&
3448                             packet -> packet_type == DHCPREQUEST &&
3449                             uid_lease -> binding_state == FTS_ACTIVE)
3450                                 dissociate_lease (uid_lease);
3451 #if defined (DEBUG_FIND_LEASE)
3452                         log_info ("not choosing uid lease.");
3453 #endif
3454                 } else {
3455                         lease_reference (&lease, uid_lease, MDL);
3456                         if (lease -> host)
3457                                 host_dereference (&lease -> host, MDL);
3458 #if defined (DEBUG_FIND_LEASE)
3459                         log_info ("choosing uid lease.");
3460 #endif
3461                 }
3462                 lease_dereference (&uid_lease, MDL);
3463         }
3464
3465         /* The lease that matched the hardware address is treated likewise. */
3466         if (hw_lease) {
3467                 if (lease) {
3468 #if defined (DEBUG_FIND_LEASE)
3469                         log_info ("not choosing hardware lease.");
3470 #endif
3471                 } else {
3472                         /* We're a little lax here - if the client didn't
3473                            send a client identifier and it's a bootp client,
3474                            but the lease has a client identifier, we still
3475                            let the client have a lease. */
3476                         if (!hw_lease -> uid_len ||
3477                             (have_client_identifier
3478                              ? (hw_lease -> uid_len ==
3479                                 client_identifier.len &&
3480                                 !memcmp (hw_lease -> uid,
3481                                          client_identifier.data,
3482                                          client_identifier.len))
3483                              : packet -> packet_type == 0)) {
3484                                 lease_reference (&lease, hw_lease, MDL);
3485                                 if (lease -> host)
3486                                         host_dereference (&lease -> host, MDL);
3487 #if defined (DEBUG_FIND_LEASE)
3488                                 log_info ("choosing hardware lease.");
3489 #endif
3490                         } else {
3491 #if defined (DEBUG_FIND_LEASE)
3492                                 log_info ("not choosing hardware lease: %s.",
3493                                           "uid mismatch");
3494 #endif
3495                         }
3496                 }
3497                 lease_dereference (&hw_lease, MDL);
3498         }
3499
3500         /* If we found a host_decl but no matching address, try to
3501            find a host_decl that has no address, and if there is one,
3502            hang it off the lease so that we can use the supplied
3503            options. */
3504         if (lease && host && !lease -> host) {
3505                 struct host_decl *p = (struct host_decl *)0;
3506                 struct host_decl *n = (struct host_decl *)0;
3507                 host_reference (&p, host, MDL);
3508                 while (p) {
3509                         if (!p -> fixed_addr) {
3510                                 host_reference (&lease -> host, p, MDL);
3511                                 host_dereference (&p, MDL);
3512                                 break;
3513                         }
3514                         if (p -> n_ipaddr)
3515                                 host_reference (&n, p -> n_ipaddr, MDL);
3516                         host_dereference (&p, MDL);
3517                         if (n) {
3518                                 host_reference (&p, n, MDL);
3519                                 host_dereference (&n, MDL);
3520                         }
3521                 }
3522         }
3523
3524         /* If we find an abandoned lease, but it's the one the client
3525            requested, we assume that previous bugginess on the part
3526            of the client, or a server database loss, caused the lease to
3527            be abandoned, so we reclaim it and let the client have it. */
3528         if (lease &&
3529             (lease -> binding_state == FTS_ABANDONED) &&
3530             lease == ip_lease &&
3531             packet -> packet_type == DHCPREQUEST) {
3532                 log_error ("Reclaiming REQUESTed abandoned IP address %s.",
3533                       piaddr (lease -> ip_addr));
3534         } else if (lease && (lease -> binding_state == FTS_ABANDONED)) {
3535         /* Otherwise, if it's not the one the client requested, we do not
3536            return it - instead, we claim it's ours, causing a DHCPNAK to be
3537            sent if this lookup is for a DHCPREQUEST, and force the client
3538            to go back through the allocation process. */
3539                 if (ours)
3540                         *ours = 1;
3541                 lease_dereference (&lease, MDL);
3542         }
3543
3544         if (lease && allocatedp && lease -> ends <= cur_time)
3545                 *allocatedp = 1;
3546
3547       out:
3548         if (have_client_identifier)
3549                 data_string_forget (&client_identifier, MDL);
3550
3551         if (fixed_lease)
3552                 lease_dereference (&fixed_lease, MDL);
3553         if (hw_lease)
3554                 lease_dereference (&hw_lease, MDL);
3555         if (uid_lease)
3556                 lease_dereference (&uid_lease, MDL);
3557         if (ip_lease)
3558                 lease_dereference (&ip_lease, MDL);
3559         if (host)
3560                 host_dereference (&host, MDL);
3561
3562         if (lease) {
3563 #if defined (DEBUG_FIND_LEASE)
3564                 log_info ("Returning lease: %s.",
3565                       piaddr (lease -> ip_addr));
3566 #endif
3567                 lease_reference (lp, lease, file, line);
3568                 lease_dereference (&lease, MDL);
3569                 return 1;
3570         }
3571 #if defined (DEBUG_FIND_LEASE)
3572         log_info ("Not returning a lease.");
3573 #endif
3574         return 0;
3575 }
3576
3577 /* Search the provided host_decl structure list for an address that's on
3578    the specified shared network.  If one is found, mock up and return a
3579    lease structure for it; otherwise return the null pointer. */
3580
3581 int mockup_lease (struct lease **lp, struct packet *packet,
3582                   struct shared_network *share, struct host_decl *hp)
3583 {
3584         struct lease *lease = (struct lease *)0;
3585         const unsigned char **s;
3586         isc_result_t status;
3587         struct host_decl *rhp = (struct host_decl *)0;
3588         
3589         status = lease_allocate (&lease, MDL);
3590         if (status != ISC_R_SUCCESS)
3591                 return 0;
3592         if (host_reference (&rhp, hp, MDL) != ISC_R_SUCCESS)
3593                 return 0;
3594         if (!find_host_for_network (&lease -> subnet,
3595                                     &rhp, &lease -> ip_addr, share)) {
3596                 lease_dereference (&lease, MDL);
3597                 return 0;
3598         }
3599         host_reference (&lease -> host, rhp, MDL);
3600         if (rhp -> client_identifier.len > sizeof lease -> uid_buf)
3601                 lease -> uid = dmalloc (rhp -> client_identifier.len, MDL);
3602         else
3603                 lease -> uid = lease -> uid_buf;
3604         if (!lease -> uid) {
3605                 lease_dereference (&lease, MDL);
3606                 host_dereference (&rhp, MDL);
3607                 return 0;
3608         }
3609         memcpy (lease -> uid, rhp -> client_identifier.data,
3610                 rhp -> client_identifier.len);
3611         lease -> uid_len = rhp -> client_identifier.len;
3612         lease -> hardware_addr = rhp -> interface;
3613         lease -> starts = lease -> timestamp = lease -> ends = MIN_TIME;
3614         lease -> flags = STATIC_LEASE;
3615         lease -> binding_state = FTS_FREE;
3616         lease_reference (lp, lease, MDL);
3617         lease_dereference (&lease, MDL);
3618         host_dereference (&rhp, MDL);
3619         return 1;
3620 }
3621
3622 /* Look through all the pools in a list starting with the specified pool
3623    for a free lease.   We try to find a virgin lease if we can.   If we
3624    don't find a virgin lease, we try to find a non-virgin lease that's
3625    free.   If we can't find one of those, we try to reclaim an abandoned
3626    lease.   If all of these possibilities fail to pan out, we don't return
3627    a lease at all. */
3628
3629 int allocate_lease (struct lease **lp, struct packet *packet,
3630                     struct pool *pool, int *peer_has_leases)
3631 {
3632         struct lease *lease = (struct lease *)0;
3633         struct lease *candl = (struct lease *)0;
3634
3635         for (; pool ; pool = pool -> next) {
3636                 if ((pool -> prohibit_list &&
3637                      permitted (packet, pool -> prohibit_list)) ||
3638                     (pool -> permit_list &&
3639                      !permitted (packet, pool -> permit_list)))
3640                         continue;
3641
3642 #if defined (FAILOVER_PROTOCOL)
3643                 /* Peer_has_leases just says that we found at least one
3644                    free lease.  If no free lease is returned, the caller
3645                    can deduce that this means the peer is hogging all the
3646                    free leases, so we can print a better error message. */
3647                 /* XXX Do we need code here to ignore PEER_IS_OWNER and
3648                  * XXX just check tstp if we're in, e.g., PARTNER_DOWN?
3649                  * XXX Where do we deal with CONFLICT_DETECTED, et al? */
3650                 /* XXX This should be handled by the lease binding "state
3651                  * XXX machine" - that is, when we get here, if a lease
3652                  * XXX could be allocated, it will have the correct
3653                  * XXX binding state so that the following code will
3654                  * XXX result in its being allocated. */
3655                 /* Skip to the most expired lease in the pool that is not
3656                  * owned by a failover peer. */
3657                 if (pool -> failover_peer) {
3658                         if (pool -> failover_peer -> i_am == primary) {
3659                                 if (pool -> backup)
3660                                         *peer_has_leases = 1;
3661                                 candl = pool -> free;
3662                                 if (!candl)
3663                                         candl = pool -> abandoned;
3664                         } else {
3665                                 if (pool -> free)
3666                                         *peer_has_leases = 1;
3667                                 candl = pool -> backup;
3668                         }
3669                 } else
3670 #endif
3671                 {
3672                         if (pool -> free)
3673                                 candl = pool -> free;
3674                         else
3675                                 candl = pool -> abandoned;
3676                 }
3677
3678                 if (!candl || (candl -> ends > cur_time))
3679                         continue;
3680
3681                 if (!lease) {
3682                         lease = candl;
3683                         continue;
3684                 }
3685
3686                 if ((lease -> binding_state == FTS_ABANDONED) &&
3687                     ((candl -> binding_state != FTS_ABANDONED) ||
3688                      (candl -> ends < lease -> ends))) {
3689                         lease = candl;
3690                         continue;
3691                 } else if (candl -> binding_state == FTS_ABANDONED)
3692                         continue;
3693
3694                 if ((lease -> uid_len || lease -> hardware_addr.hlen) &&
3695                     ((!candl -> uid_len && !candl -> hardware_addr.hlen) ||
3696                      (candl -> ends < lease -> ends))) {
3697                         lease = candl;
3698                         continue;
3699                 } else if (candl -> uid_len || candl -> hardware_addr.hlen)
3700                         continue;
3701
3702                 if (candl -> ends < lease -> ends)
3703                         lease = candl;
3704         }
3705
3706         if (lease) {
3707                 if (lease -> binding_state == FTS_ABANDONED)
3708                         log_error ("Reclaiming abandoned lease %s.",
3709                                    piaddr (lease -> ip_addr));
3710
3711                 lease_reference (lp, lease, MDL);
3712                 return 1;
3713         }
3714
3715         return 0;
3716 }
3717
3718 /* Determine whether or not a permit exists on a particular permit list
3719    that matches the specified packet, returning nonzero if so, zero if
3720    not. */
3721
3722 int permitted (packet, permit_list)
3723         struct packet *packet;
3724         struct permit *permit_list;
3725 {
3726         struct permit *p;
3727         int i;
3728
3729         for (p = permit_list; p; p = p -> next) {
3730                 switch (p -> type) {
3731                       case permit_unknown_clients:
3732                         if (!packet -> known)
3733                                 return 1;
3734                         break;
3735
3736                       case permit_known_clients:
3737                         if (packet -> known)
3738                                 return 1;
3739                         break;
3740
3741                       case permit_authenticated_clients:
3742                         if (packet -> authenticated)
3743                                 return 1;
3744                         break;
3745
3746                       case permit_unauthenticated_clients:
3747                         if (!packet -> authenticated)
3748                                 return 1;
3749                         break;
3750
3751                       case permit_all_clients:
3752                         return 1;
3753
3754                       case permit_dynamic_bootp_clients:
3755                         if (!packet -> options_valid ||
3756                             !packet -> packet_type)
3757                                 return 1;
3758                         break;
3759                         
3760                       case permit_class:
3761                         for (i = 0; i < packet -> class_count; i++) {
3762                                 if (p -> class == packet -> classes [i])
3763                                         return 1;
3764                                 if (packet -> classes [i] &&
3765                                     packet -> classes [i] -> superclass &&
3766                                     (packet -> classes [i] -> superclass ==
3767                                      p -> class))
3768                                         return 1;
3769                         }
3770                         break;
3771                 }
3772         }
3773         return 0;
3774 }
3775
3776 int locate_network (packet)
3777         struct packet *packet;
3778 {
3779         struct iaddr ia;
3780         struct data_string data;
3781         struct subnet *subnet = (struct subnet *)0;
3782         struct option_cache *oc;
3783
3784         /* See if there's a subnet selection option. */
3785         oc = lookup_option (&dhcp_universe, packet -> options,
3786                             DHO_SUBNET_SELECTION);
3787
3788         /* If there's no SSO and no giaddr, then use the shared_network
3789            from the interface, if there is one.   If not, fail. */
3790         if (!oc && !packet -> raw -> giaddr.s_addr) {
3791                 if (packet -> interface -> shared_network) {
3792                         shared_network_reference
3793                                 (&packet -> shared_network,
3794                                  packet -> interface -> shared_network, MDL);
3795                         return 1;
3796                 }
3797                 return 0;
3798         }
3799
3800         /* If there's an SSO, and it's valid, use it to figure out the
3801            subnet.    If it's not valid, fail. */
3802         if (oc) {
3803                 memset (&data, 0, sizeof data);
3804                 if (!evaluate_option_cache (&data, packet, (struct lease *)0,
3805                                             (struct client_state *)0,
3806                                             packet -> options,
3807                                             (struct option_state *)0,
3808                                             &global_scope, oc, MDL)) {
3809                         return 0;
3810                 }
3811                 if (data.len != 4) {
3812                         return 0;
3813                 }
3814                 ia.len = 4;
3815                 memcpy (ia.iabuf, data.data, 4);
3816                 data_string_forget (&data, MDL);
3817         } else {
3818                 ia.len = 4;
3819                 memcpy (ia.iabuf, &packet -> raw -> giaddr, 4);
3820         }
3821
3822         /* If we know the subnet on which the IP address lives, use it. */
3823         if (find_subnet (&subnet, ia, MDL)) {
3824                 shared_network_reference (&packet -> shared_network,
3825                                           subnet -> shared_network, MDL);
3826                 subnet_dereference (&subnet, MDL);
3827                 return 1;
3828         }
3829
3830         /* Otherwise, fail. */
3831         return 0;
3832 }