File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dhcp / server / dhcp.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Oct 9 09:06:55 2012 UTC (11 years, 9 months ago) by misho
Branches: dhcp, MAIN
CVS tags: v4_1_R7p0, v4_1_R7, v4_1_R4, HEAD
dhcp 4.1 r7

    1: /* dhcp.c
    2: 
    3:    DHCP Protocol engine. */
    4: 
    5: /*
    6:  * Copyright (c) 2004-2012 by Internet Systems Consortium, Inc. ("ISC")
    7:  * Copyright (c) 1995-2003 by Internet Software Consortium
    8:  *
    9:  * Permission to use, copy, modify, and distribute this software for any
   10:  * purpose with or without fee is hereby granted, provided that the above
   11:  * copyright notice and this permission notice appear in all copies.
   12:  *
   13:  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
   14:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   15:  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
   16:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   17:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   18:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
   19:  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   20:  *
   21:  *   Internet Systems Consortium, Inc.
   22:  *   950 Charter Street
   23:  *   Redwood City, CA 94063
   24:  *   <info@isc.org>
   25:  *   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;
  954: 	struct interface_info *interface;
  955: 	int result;
  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;
 1154: 
 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;
 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: 
 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) {
 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: 
 1473: 			return;
 1474: 		}
 1475: 	} else {
 1476: 		to.sin_addr = limited_broadcast;
 1477: 		to.sin_port = remote_port;
 1478: 	}
 1479: 
 1480: 	errno = 0;
 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: 	}
 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) {
 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: 
 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) {
 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: 
 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: 
 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: 
 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>