Annotation of embedaddon/dhcp/server/dhcp.c, revision 1.1.1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>