Home | History | Annotate | Download | only in src
      1 /* dnsmasq is Copyright (c) 2000-2009 Simon Kelley
      2 
      3    This program is free software; you can redistribute it and/or modify
      4    it under the terms of the GNU General Public License as published by
      5    the Free Software Foundation; version 2 dated June, 1991, or
      6    (at your option) version 3 dated 29 June, 2007.
      7 
      8    This program is distributed in the hope that it will be useful,
      9    but WITHOUT ANY WARRANTY; without even the implied warranty of
     10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11    GNU General Public License for more details.
     12 
     13    You should have received a copy of the GNU General Public License
     14    along with this program.  If not, see <http://www.gnu.org/licenses/>.
     15 */
     16 
     17 #include "dnsmasq.h"
     18 
     19 #ifdef HAVE_DHCP
     20 
     21 #define BOOTREQUEST              1
     22 #define BOOTREPLY                2
     23 #define DHCP_COOKIE              0x63825363
     24 
     25 /* The Linux in-kernel DHCP client silently ignores any packet
     26    smaller than this. Sigh...........   */
     27 #define MIN_PACKETSZ             300
     28 
     29 #define OPTION_PAD               0
     30 #define OPTION_NETMASK           1
     31 #define OPTION_ROUTER            3
     32 #define OPTION_DNSSERVER         6
     33 #define OPTION_HOSTNAME          12
     34 #define OPTION_DOMAINNAME        15
     35 #define OPTION_BROADCAST         28
     36 #define OPTION_VENDOR_CLASS_OPT  43
     37 #define OPTION_REQUESTED_IP      50
     38 #define OPTION_LEASE_TIME        51
     39 #define OPTION_OVERLOAD          52
     40 #define OPTION_MESSAGE_TYPE      53
     41 #define OPTION_SERVER_IDENTIFIER 54
     42 #define OPTION_REQUESTED_OPTIONS 55
     43 #define OPTION_MESSAGE           56
     44 #define OPTION_MAXMESSAGE        57
     45 #define OPTION_T1                58
     46 #define OPTION_T2                59
     47 #define OPTION_VENDOR_ID         60
     48 #define OPTION_CLIENT_ID         61
     49 #define OPTION_SNAME             66
     50 #define OPTION_FILENAME          67
     51 #define OPTION_USER_CLASS        77
     52 #define OPTION_CLIENT_FQDN       81
     53 #define OPTION_AGENT_ID          82
     54 #define OPTION_ARCH              93
     55 #define OPTION_PXE_UUID          97
     56 #define OPTION_SUBNET_SELECT     118
     57 #define OPTION_END               255
     58 
     59 #define SUBOPT_CIRCUIT_ID        1
     60 #define SUBOPT_REMOTE_ID         2
     61 #define SUBOPT_SUBNET_SELECT     5     /* RFC 3527 */
     62 #define SUBOPT_SUBSCR_ID         6     /* RFC 3393 */
     63 #define SUBOPT_SERVER_OR         11    /* RFC 5107 */
     64 
     65 #define SUBOPT_PXE_BOOT_ITEM     71    /* PXE standard */
     66 #define SUBOPT_PXE_DISCOVERY     6
     67 #define SUBOPT_PXE_SERVERS       8
     68 #define SUBOPT_PXE_MENU          9
     69 #define SUBOPT_PXE_MENU_PROMPT   10
     70 
     71 #define DHCPDISCOVER             1
     72 #define DHCPOFFER                2
     73 #define DHCPREQUEST              3
     74 #define DHCPDECLINE              4
     75 #define DHCPACK                  5
     76 #define DHCPNAK                  6
     77 #define DHCPRELEASE              7
     78 #define DHCPINFORM               8
     79 
     80 #define have_config(config, mask) ((config) && ((config)->flags & (mask)))
     81 #define option_len(opt) ((int)(((unsigned char *)(opt))[1]))
     82 #define option_ptr(opt, i) ((void *)&(((unsigned char *)(opt))[2u+(unsigned int)(i)]))
     83 
     84 static int sanitise(unsigned char *opt, char *buf);
     85 static struct in_addr server_id(struct dhcp_context *context, struct in_addr override, struct in_addr fallback);
     86 static unsigned int calc_time(struct dhcp_context *context, struct dhcp_config *config, unsigned char *opt);
     87 static void option_put(struct dhcp_packet *mess, unsigned char *end, int opt, int len, unsigned int val);
     88 static void option_put_string(struct dhcp_packet *mess, unsigned char *end,
     89 			      int opt, char *string, int null_term);
     90 static struct in_addr option_addr(unsigned char *opt);
     91 static struct in_addr option_addr_arr(unsigned char *opt, int offset);
     92 static unsigned int option_uint(unsigned char *opt, int i, int size);
     93 static void log_packet(char *type, void *addr, unsigned char *ext_mac,
     94 		       int mac_len, char *interface, char *string, u32 xid);
     95 static unsigned char *option_find(struct dhcp_packet *mess, size_t size, int opt_type, int minsize);
     96 static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt, int minsize);
     97 static size_t dhcp_packet_size(struct dhcp_packet *mess, struct dhcp_netid *netid,
     98 			       unsigned char *agent_id, unsigned char *real_end);
     99 static void clear_packet(struct dhcp_packet *mess, unsigned char *end);
    100 static void do_options(struct dhcp_context *context,
    101 		       struct dhcp_packet *mess,
    102 		       unsigned char *real_end,
    103 		       unsigned char *req_options,
    104 		       char *hostname,
    105 		       char *domain, char *config_domain,
    106 		       struct dhcp_netid *netid,
    107 		       struct in_addr subnet_addr,
    108 		       unsigned char fqdn_flags,
    109 		       int null_term, int pxearch,
    110 		       unsigned char *uuid);
    111 
    112 
    113 static void match_vendor_opts(unsigned char *opt, struct dhcp_opt *dopt);
    114 static void do_encap_opts(struct dhcp_opt *opts, int encap, int flag, struct dhcp_packet *mess, unsigned char *end, int null_term);
    115 static void pxe_misc(struct dhcp_packet *mess, unsigned char *end, unsigned char *uuid);
    116 static int prune_vendor_opts(struct dhcp_netid *netid);
    117 static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid);
    118 struct dhcp_boot *find_boot(struct dhcp_netid *netid);
    119 
    120 
    121 size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
    122 		  size_t sz, time_t now, int unicast_dest, int *is_inform)
    123 {
    124   unsigned char *opt, *clid = NULL;
    125   struct dhcp_lease *ltmp, *lease = NULL;
    126   struct dhcp_vendor *vendor;
    127   struct dhcp_mac *mac;
    128   struct dhcp_netid_list *id_list;
    129   int clid_len = 0, ignore = 0, do_classes = 0, selecting = 0, pxearch = -1;
    130   struct dhcp_packet *mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
    131   unsigned char *end = (unsigned char *)(mess + 1);
    132   unsigned char *real_end = (unsigned char *)(mess + 1);
    133   char *hostname = NULL, *offer_hostname = NULL, *client_hostname = NULL, *domain = NULL;
    134   int hostname_auth = 0, borken_opt = 0;
    135   unsigned char *req_options = NULL;
    136   char *message = NULL;
    137   unsigned int time;
    138   struct dhcp_config *config;
    139   struct dhcp_netid *netid;
    140   struct in_addr subnet_addr, fallback, override;
    141   unsigned short fuzz = 0;
    142   unsigned int mess_type = 0;
    143   unsigned char fqdn_flags = 0;
    144   unsigned char *agent_id = NULL, *uuid = NULL;
    145   unsigned char *emac = NULL;
    146   int emac_len = 0;
    147   struct dhcp_netid known_id, iface_id;
    148   struct dhcp_opt *o;
    149   unsigned char pxe_uuid[17];
    150 
    151   subnet_addr.s_addr = override.s_addr = 0;
    152 
    153   /* set tag with name == interface */
    154   iface_id.net = iface_name;
    155   iface_id.next = NULL;
    156   netid = &iface_id;
    157 
    158   if (mess->op != BOOTREQUEST || mess->hlen > DHCP_CHADDR_MAX)
    159     return 0;
    160 
    161   if (mess->htype == 0 && mess->hlen != 0)
    162     return 0;
    163 
    164   /* check for DHCP rather than BOOTP */
    165   if ((opt = option_find(mess, sz, OPTION_MESSAGE_TYPE, 1)))
    166     {
    167       mess_type = option_uint(opt, 0, 1);
    168 
    169       /* only insist on a cookie for DHCP. */
    170       if (*((u32 *)&mess->options) != htonl(DHCP_COOKIE))
    171 	return 0;
    172 
    173       /* two things to note here: expand_buf may move the packet,
    174 	 so reassign mess from daemon->packet. Also, the size
    175 	 sent includes the IP and UDP headers, hence the magic "-28" */
    176       if ((opt = option_find(mess, sz, OPTION_MAXMESSAGE, 2)))
    177 	{
    178 	  size_t size = (size_t)option_uint(opt, 0, 2) - 28;
    179 
    180 	  if (size > DHCP_PACKET_MAX)
    181 	    size = DHCP_PACKET_MAX;
    182 	  else if (size < sizeof(struct dhcp_packet))
    183 	    size = sizeof(struct dhcp_packet);
    184 
    185 	  if (expand_buf(&daemon->dhcp_packet, size))
    186 	    {
    187 	      mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
    188 	      real_end = end = ((unsigned char *)mess) + size;
    189 	    }
    190 	}
    191 
    192       /* Some buggy clients set ciaddr when they shouldn't, so clear that here since
    193 	 it can affect the context-determination code. */
    194       if ((option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ) || mess_type == DHCPDISCOVER))
    195 	mess->ciaddr.s_addr = 0;
    196 
    197       if ((opt = option_find(mess, sz, OPTION_AGENT_ID, 1)))
    198 	{
    199 	  /* Any agent-id needs to be copied back out, verbatim, as the last option
    200 	     in the packet. Here, we shift it to the very end of the buffer, if it doesn't
    201 	     get overwritten, then it will be shuffled back at the end of processing.
    202 	     Note that the incoming options must not be overwritten here, so there has to
    203 	     be enough free space at the end of the packet to copy the option. */
    204 	  unsigned char *sopt;
    205 	  unsigned int total = option_len(opt) + 2;
    206 	  unsigned char *last_opt = option_find(mess, sz, OPTION_END, 0);
    207 	  if (last_opt && last_opt < end - total)
    208 	    {
    209 	      end -= total;
    210 	      agent_id = end;
    211 	      memcpy(agent_id, opt, total);
    212 	    }
    213 
    214 	  /* look for RFC3527 Link selection sub-option */
    215 	  if ((sopt = option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)), SUBOPT_SUBNET_SELECT, INADDRSZ)))
    216 	    subnet_addr = option_addr(sopt);
    217 
    218 	  /* look for RFC5107 server-identifier-override */
    219 	  if ((sopt = option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)), SUBOPT_SERVER_OR, INADDRSZ)))
    220 	    override = option_addr(sopt);
    221 
    222 	  /* if a circuit-id or remote-is option is provided, exact-match to options. */
    223 	  for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
    224 	    {
    225 	      int search;
    226 
    227 	      if (vendor->match_type == MATCH_CIRCUIT)
    228 		search = SUBOPT_CIRCUIT_ID;
    229 	      else if (vendor->match_type == MATCH_REMOTE)
    230 		search = SUBOPT_REMOTE_ID;
    231 	      else if (vendor->match_type == MATCH_SUBSCRIBER)
    232 		search = SUBOPT_SUBSCR_ID;
    233 	      else
    234 		continue;
    235 
    236 	      if ((sopt = option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)), search, 1)) &&
    237 		  vendor->len == option_len(sopt) &&
    238 		  memcmp(option_ptr(sopt, 0), vendor->data, vendor->len) == 0)
    239 		{
    240 		  vendor->netid.next = netid;
    241 		  netid = &vendor->netid;
    242 		  break;
    243 		}
    244 	    }
    245 	}
    246 
    247       /* Check for RFC3011 subnet selector - only if RFC3527 one not present */
    248       if (subnet_addr.s_addr == 0 && (opt = option_find(mess, sz, OPTION_SUBNET_SELECT, INADDRSZ)))
    249 	subnet_addr = option_addr(opt);
    250 
    251       /* If there is no client identifier option, use the hardware address */
    252       if ((opt = option_find(mess, sz, OPTION_CLIENT_ID, 1)))
    253 	{
    254 	  clid_len = option_len(opt);
    255 	  clid = option_ptr(opt, 0);
    256 	}
    257 
    258       /* do we have a lease in store? */
    259       lease = lease_find_by_client(mess->chaddr, mess->hlen, mess->htype, clid, clid_len);
    260 
    261       /* If this request is missing a clid, but we've seen one before,
    262 	 use it again for option matching etc. */
    263       if (lease && !clid && lease->clid)
    264 	{
    265 	  clid_len = lease->clid_len;
    266 	  clid = lease->clid;
    267 	}
    268 
    269       /* find mac to use for logging and hashing */
    270       emac = extended_hwaddr(mess->htype, mess->hlen, mess->chaddr, clid_len, clid, &emac_len);
    271     }
    272 
    273   for (mac = daemon->dhcp_macs; mac; mac = mac->next)
    274     if (mac->hwaddr_len == mess->hlen &&
    275 	(mac->hwaddr_type == mess->htype || mac->hwaddr_type == 0) &&
    276 	memcmp_masked(mac->hwaddr, mess->chaddr, mess->hlen, mac->mask))
    277       {
    278 	mac->netid.next = netid;
    279 	netid = &mac->netid;
    280       }
    281 
    282   /* Determine network for this packet. Our caller will have already linked all the
    283      contexts which match the addresses of the receiving interface but if the
    284      machine has an address already, or came via a relay, or we have a subnet selector,
    285      we search again. If we don't have have a giaddr or explicit subnet selector,
    286      use the ciaddr. This is necessary because a  machine which got a lease via a
    287      relay won't use the relay to renew. If matching a ciaddr fails but we have a context
    288      from the physical network, continue using that to allow correct DHCPNAK generation later. */
    289   if (mess->giaddr.s_addr || subnet_addr.s_addr || mess->ciaddr.s_addr)
    290     {
    291       struct dhcp_context *context_tmp, *context_new = NULL;
    292       struct in_addr addr;
    293       int force = 0;
    294 
    295       if (subnet_addr.s_addr)
    296 	{
    297 	  addr = subnet_addr;
    298 	  force = 1;
    299 	}
    300       else if (mess->giaddr.s_addr)
    301 	{
    302 	  addr = mess->giaddr;
    303 	  force = 1;
    304 	}
    305       else
    306 	{
    307 	  /* If ciaddr is in the hardware derived set of contexts, leave that unchanged */
    308 	  addr = mess->ciaddr;
    309 	  for (context_tmp = context; context_tmp; context_tmp = context_tmp->current)
    310 	    if (context_tmp->netmask.s_addr &&
    311 		is_same_net(addr, context_tmp->start, context_tmp->netmask) &&
    312 		is_same_net(addr, context_tmp->end, context_tmp->netmask))
    313 	      {
    314 		context_new = context;
    315 		break;
    316 	      }
    317 	}
    318 
    319       if (!context_new)
    320 	for (context_tmp = daemon->dhcp; context_tmp; context_tmp = context_tmp->next)
    321 	  if (context_tmp->netmask.s_addr  &&
    322 	      is_same_net(addr, context_tmp->start, context_tmp->netmask) &&
    323 	      is_same_net(addr, context_tmp->end, context_tmp->netmask))
    324 	    {
    325 	      context_tmp->current = context_new;
    326 	      context_new = context_tmp;
    327 	    }
    328 
    329       if (context_new || force)
    330 	context = context_new;
    331 
    332     }
    333 
    334   if (!context)
    335     {
    336 //      my_syslog(MS_DHCP | LOG_WARNING, _("no address range available for DHCP request %s %s"),
    337 //		subnet_addr.s_addr ? _("with subnet selector") : _("via"),
    338 //		subnet_addr.s_addr ? inet_ntoa(subnet_addr) : (mess->giaddr.s_addr ? inet_ntoa(mess->giaddr) : iface_name));
    339       return 0;
    340     }
    341 
    342   /* keep _a_ local address available. */
    343   fallback = context->local;
    344 
    345   if (daemon->options & OPT_LOG_OPTS)
    346     {
    347       struct dhcp_context *context_tmp;
    348       for (context_tmp = context; context_tmp; context_tmp = context_tmp->current)
    349 	{
    350 	  strcpy(daemon->namebuff, inet_ntoa(context_tmp->start));
    351 	  if (context_tmp->flags & (CONTEXT_STATIC | CONTEXT_PROXY))
    352 	    my_syslog(MS_DHCP | LOG_INFO, _("%u Available DHCP subnet: %s/%s"),
    353 		      ntohl(mess->xid), daemon->namebuff, inet_ntoa(context_tmp->netmask));
    354 	  else
    355 	    my_syslog(MS_DHCP | LOG_INFO, _("%u Available DHCP range: %s -- %s"),
    356 		      ntohl(mess->xid), daemon->namebuff, inet_ntoa(context_tmp->end));
    357 	}
    358     }
    359 
    360   mess->op = BOOTREPLY;
    361 
    362   config = find_config(daemon->dhcp_conf, context, clid, clid_len,
    363 		       mess->chaddr, mess->hlen, mess->htype, NULL);
    364 
    365   /* set "known" tag for known hosts */
    366   if (config)
    367     {
    368       known_id.net = "known";
    369       known_id.next = netid;
    370       netid = &known_id;
    371     }
    372 
    373   if (mess_type == 0)
    374     {
    375       /* BOOTP request */
    376       struct dhcp_netid id, bootp_id;
    377       struct in_addr *logaddr = NULL;
    378 
    379       /* must have a MAC addr for bootp */
    380       if (mess->htype == 0 || mess->hlen == 0 || (context->flags & CONTEXT_PROXY))
    381 	return 0;
    382 
    383       if (have_config(config, CONFIG_DISABLE))
    384 	message = _("disabled");
    385 
    386       end = mess->options + 64; /* BOOTP vend area is only 64 bytes */
    387 
    388       if (have_config(config, CONFIG_NAME))
    389 	{
    390 	  hostname = config->hostname;
    391 	  domain = config->domain;
    392 	}
    393 
    394       if (have_config(config, CONFIG_NETID))
    395 	{
    396 	  config->netid.next = netid;
    397 	  netid = &config->netid;
    398 	}
    399 
    400       /* Match incoming filename field as a netid. */
    401       if (mess->file[0])
    402 	{
    403 	  memcpy(daemon->dhcp_buff2, mess->file, sizeof(mess->file));
    404 	  daemon->dhcp_buff2[sizeof(mess->file) + 1] = 0; /* ensure zero term. */
    405 	  id.net = (char *)daemon->dhcp_buff2;
    406 	  id.next = netid;
    407 	  netid = &id;
    408 	}
    409 
    410       /* Add "bootp" as a tag to allow different options, address ranges etc
    411 	 for BOOTP clients */
    412       bootp_id.net = "bootp";
    413       bootp_id.next = netid;
    414       netid = &bootp_id;
    415 
    416       for (id_list = daemon->dhcp_ignore; id_list; id_list = id_list->next)
    417 	if (match_netid(id_list->list, netid, 0))
    418 	  message = _("ignored");
    419 
    420       if (!message)
    421 	{
    422 	  int nailed = 0;
    423 
    424 	  if (have_config(config, CONFIG_ADDR))
    425 	    {
    426 	      nailed = 1;
    427 	      logaddr = &config->addr;
    428 	      mess->yiaddr = config->addr;
    429 	      if ((lease = lease_find_by_addr(config->addr)) &&
    430 		  (lease->hwaddr_len != mess->hlen ||
    431 		   lease->hwaddr_type != mess->htype ||
    432 		   memcmp(lease->hwaddr, mess->chaddr, lease->hwaddr_len) != 0))
    433 		message = _("address in use");
    434 	    }
    435 	  else
    436 	    {
    437 	      if (!(lease = lease_find_by_client(mess->chaddr, mess->hlen, mess->htype, NULL, 0)) ||
    438 		  !address_available(context, lease->addr, netid))
    439 		{
    440 		   if (lease)
    441 		     {
    442 		       /* lease exists, wrong network. */
    443 		       lease_prune(lease, now);
    444 		       lease = NULL;
    445 		     }
    446 		   if (!address_allocate(context, &mess->yiaddr, mess->chaddr, mess->hlen, netid, now))
    447 		     message = _("no address available");
    448 		}
    449 	      else
    450 		mess->yiaddr = lease->addr;
    451 	    }
    452 
    453 	  if (!message && !(context = narrow_context(context, mess->yiaddr, netid)))
    454 	    message = _("wrong network");
    455 	  else if (context->netid.net)
    456 	    {
    457 	      context->netid.next = netid;
    458 	      netid = &context->netid;
    459 	    }
    460 
    461 	  if (!message && !nailed)
    462 	    {
    463 	      for (id_list = daemon->bootp_dynamic; id_list; id_list = id_list->next)
    464 		if ((!id_list->list) || match_netid(id_list->list, netid, 0))
    465 		  break;
    466 	      if (!id_list)
    467 		message = _("no address configured");
    468 	    }
    469 
    470 	  if (!message &&
    471 	      !lease &&
    472 	      (!(lease = lease_allocate(mess->yiaddr))))
    473 	    message = _("no leases left");
    474 
    475 	  if (!message)
    476 	    {
    477 	      logaddr = &mess->yiaddr;
    478 
    479 	      lease_set_hwaddr(lease, mess->chaddr, NULL, mess->hlen, mess->htype, 0);
    480 	      if (hostname)
    481 		lease_set_hostname(lease, hostname, 1);
    482 	      /* infinite lease unless nailed in dhcp-host line. */
    483 	      lease_set_expires(lease,
    484 				have_config(config, CONFIG_TIME) ? config->lease_time : 0xffffffff,
    485 				now);
    486 	      lease_set_interface(lease, int_index);
    487 
    488 	      clear_packet(mess, end);
    489 	      do_options(context, mess, end, NULL, hostname, get_domain(mess->yiaddr),
    490 			 domain, netid, subnet_addr, 0, 0, 0, NULL);
    491 	    }
    492 	}
    493 
    494       log_packet("BOOTP", logaddr, mess->chaddr, mess->hlen, iface_name, message, mess->xid);
    495 
    496       return message ? 0 : dhcp_packet_size(mess, netid, agent_id, real_end);
    497     }
    498 
    499   if ((opt = option_find(mess, sz, OPTION_CLIENT_FQDN, 4)))
    500     {
    501       /* http://tools.ietf.org/wg/dhc/draft-ietf-dhc-fqdn-option/draft-ietf-dhc-fqdn-option-10.txt */
    502       int len = option_len(opt);
    503       char *pq = daemon->dhcp_buff;
    504       unsigned char *pp, *op = option_ptr(opt, 0);
    505 
    506       fqdn_flags = *op;
    507       len -= 3;
    508       op += 3;
    509       pp = op;
    510 
    511       /* Always force update, since the client has no way to do it itself. */
    512       if (!(fqdn_flags & 0x01))
    513 	fqdn_flags |= 0x02;
    514 
    515       fqdn_flags &= ~0x08;
    516       fqdn_flags |= 0x01;
    517 
    518       if (fqdn_flags & 0x04)
    519 	while (*op != 0 && ((op + (*op) + 1) - pp) < len)
    520 	  {
    521 	    memcpy(pq, op+1, *op);
    522 	    pq += *op;
    523 	    op += (*op)+1;
    524 	    *(pq++) = '.';
    525 	  }
    526       else
    527 	{
    528 	  memcpy(pq, op, len);
    529 	  if (len > 0 && op[len-1] == 0)
    530 	    borken_opt = 1;
    531 	  pq += len + 1;
    532 	}
    533 
    534       if (pq != daemon->dhcp_buff)
    535 	pq--;
    536 
    537       *pq = 0;
    538 
    539       if (legal_hostname(daemon->dhcp_buff))
    540 	offer_hostname = client_hostname = daemon->dhcp_buff;
    541     }
    542   else if ((opt = option_find(mess, sz, OPTION_HOSTNAME, 1)))
    543     {
    544       int len = option_len(opt);
    545       memcpy(daemon->dhcp_buff, option_ptr(opt, 0), len);
    546       /* Microsoft clients are broken, and need zero-terminated strings
    547 	 in options. We detect this state here, and do the same in
    548 	 any options we send */
    549       if (len > 0 && daemon->dhcp_buff[len-1] == 0)
    550 	borken_opt = 1;
    551       else
    552 	daemon->dhcp_buff[len] = 0;
    553       if (legal_hostname(daemon->dhcp_buff))
    554 	client_hostname = daemon->dhcp_buff;
    555     }
    556 
    557   if (client_hostname && daemon->options & OPT_LOG_OPTS)
    558     my_syslog(MS_DHCP | LOG_INFO, _("%u client provides name: %s"), ntohl(mess->xid), client_hostname);
    559 
    560   if (have_config(config, CONFIG_NAME))
    561     {
    562       hostname = config->hostname;
    563       domain = config->domain;
    564       hostname_auth = 1;
    565       /* be careful not to send an OFFER with a hostname not matching the DISCOVER. */
    566       if (fqdn_flags != 0 || !client_hostname || hostname_isequal(hostname, client_hostname))
    567         offer_hostname = hostname;
    568     }
    569   else if (client_hostname)
    570     {
    571       domain = strip_hostname(client_hostname);
    572 
    573       if (strlen(client_hostname) != 0)
    574 	{
    575 	  hostname = client_hostname;
    576 	  if (!config)
    577 	    {
    578 	      /* Search again now we have a hostname.
    579 		 Only accept configs without CLID and HWADDR here, (they won't match)
    580 		 to avoid impersonation by name. */
    581 	      struct dhcp_config *new = find_config(daemon->dhcp_conf, context, NULL, 0,
    582 						    mess->chaddr, mess->hlen,
    583 						    mess->htype, hostname);
    584 	      if (new && !have_config(new, CONFIG_CLID) && !new->hwaddr)
    585 		{
    586 		  config = new;
    587 		  /* set "known" tag for known hosts */
    588 		  known_id.net = "known";
    589 		  known_id.next = netid;
    590 		  netid = &known_id;
    591 		}
    592 	    }
    593 	}
    594     }
    595 
    596   if (have_config(config, CONFIG_NETID))
    597     {
    598       config->netid.next = netid;
    599       netid = &config->netid;
    600     }
    601 
    602   /* dhcp-match. If we have hex-and-wildcards, look for a left-anchored match.
    603      Otherwise assume the option is an array, and look for a matching element.
    604      If no data given, existance of the option is enough. */
    605   for (o = daemon->dhcp_match; o; o = o->next)
    606     {
    607       int i, matched = 0;
    608 
    609       if (!(opt = option_find(mess, sz, o->opt, 1)) ||
    610 	  o->len > option_len(opt))
    611 	continue;
    612 
    613       if (o->len == 0)
    614 	matched = 1;
    615       else if (o->flags & DHOPT_HEX)
    616 	{
    617 	  if (memcmp_masked(o->val, option_ptr(opt, 0), o->len, o->u.wildcard_mask))
    618 	    matched = 1;
    619 	}
    620       else
    621 	for (i = 0; i <= (option_len(opt) - o->len); )
    622 	  {
    623 	    if (memcmp(o->val, option_ptr(opt, i), o->len) == 0)
    624 	      {
    625 		matched = 1;
    626 		break;
    627 	      }
    628 
    629 	    if (o->flags & DHOPT_STRING)
    630 	      i++;
    631 	    else
    632 	      i += o->len;
    633 	  }
    634 
    635       if (matched)
    636 	{
    637 	  o->netid->next = netid;
    638 	  netid = o->netid;
    639 	}
    640     }
    641 
    642   /* user-class options are, according to RFC3004, supposed to contain
    643      a set of counted strings. Here we check that this is so (by seeing
    644      if the counts are consistent with the overall option length) and if
    645      so zero the counts so that we don't get spurious matches between
    646      the vendor string and the counts. If the lengths don't add up, we
    647      assume that the option is a single string and non RFC3004 compliant
    648      and just do the substring match. dhclient provides these broken options.
    649      The code, later, which sends user-class data to the lease-change script
    650      relies on the transformation done here.
    651   */
    652 
    653   if ((opt = option_find(mess, sz, OPTION_USER_CLASS, 1)))
    654     {
    655       unsigned char *ucp = option_ptr(opt, 0);
    656       int tmp, j;
    657       for (j = 0; j < option_len(opt); j += ucp[j] + 1);
    658       if (j == option_len(opt))
    659 	for (j = 0; j < option_len(opt); j = tmp)
    660 	  {
    661 	    tmp = j + ucp[j] + 1;
    662 	    ucp[j] = 0;
    663 	  }
    664     }
    665 
    666   for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
    667     {
    668       int mopt;
    669 
    670       if (vendor->match_type == MATCH_VENDOR)
    671 	mopt = OPTION_VENDOR_ID;
    672       else if (vendor->match_type == MATCH_USER)
    673 	mopt = OPTION_USER_CLASS;
    674       else
    675 	continue;
    676 
    677       if ((opt = option_find(mess, sz, mopt, 1)))
    678 	{
    679 	  int i;
    680 	  for (i = 0; i <= (option_len(opt) - vendor->len); i++)
    681 	    if (memcmp(vendor->data, option_ptr(opt, i), vendor->len) == 0)
    682 	      {
    683 		vendor->netid.next = netid;
    684 		netid = &vendor->netid;
    685 		break;
    686 	      }
    687 	}
    688     }
    689 
    690   /* mark vendor-encapsulated options which match the client-supplied vendor class */
    691   match_vendor_opts(option_find(mess, sz, OPTION_VENDOR_ID, 1), daemon->dhcp_opts);
    692 
    693   if (daemon->options & OPT_LOG_OPTS)
    694     {
    695       if (sanitise(option_find(mess, sz, OPTION_VENDOR_ID, 1), daemon->namebuff))
    696 	my_syslog(MS_DHCP | LOG_INFO, _("%u Vendor class: %s"), ntohl(mess->xid), daemon->namebuff);
    697       if (sanitise(option_find(mess, sz, OPTION_USER_CLASS, 1), daemon->namebuff))
    698 	my_syslog(MS_DHCP | LOG_INFO, _("%u User class: %s"), ntohl(mess->xid), daemon->namebuff);
    699     }
    700 
    701   /* if all the netids in the ignore list are present, ignore this client */
    702   for (id_list = daemon->dhcp_ignore; id_list; id_list = id_list->next)
    703     if (match_netid(id_list->list, netid, 0))
    704       ignore = 1;
    705 
    706   /* Can have setting to ignore the client ID for a particular MAC address or hostname */
    707   if (have_config(config, CONFIG_NOCLID))
    708     clid = NULL;
    709 
    710   /* Check if client is PXE client. */
    711   if (daemon->enable_pxe &&
    712       (opt = option_find(mess, sz, OPTION_VENDOR_ID, 9)) &&
    713       strncmp(option_ptr(opt, 0), "PXEClient", 9) == 0)
    714     {
    715       if ((opt = option_find(mess, sz, OPTION_PXE_UUID, 17)))
    716 	{
    717 	  memcpy(pxe_uuid, option_ptr(opt, 0), 17);
    718 	  uuid = pxe_uuid;
    719 	}
    720 
    721       /* Check if this is really a PXE bootserver request, and handle specially if so. */
    722       if ((mess_type == DHCPREQUEST || mess_type == DHCPINFORM) &&
    723 	  (opt = option_find(mess, sz, OPTION_VENDOR_CLASS_OPT, 1)) &&
    724 	  (opt = option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)), SUBOPT_PXE_BOOT_ITEM, 4)))
    725 	{
    726 	  struct pxe_service *service;
    727 	  int type = option_uint(opt, 0, 2);
    728 	  int layer = option_uint(opt, 2, 2);
    729 	  unsigned char save71[4];
    730 	  struct dhcp_opt opt71;
    731 
    732 	  if (ignore)
    733 	    return 0;
    734 
    735 	  if (layer & 0x8000)
    736 	    {
    737 	      my_syslog(MS_DHCP | LOG_ERR, _("PXE BIS not supported"));
    738 	      return 0;
    739 	    }
    740 
    741 	  memcpy(save71, option_ptr(opt, 0), 4);
    742 
    743 	  for (service = daemon->pxe_services; service; service = service->next)
    744 	    if (service->type == type)
    745 	      break;
    746 
    747 	  if (!service || !service->basename)
    748 	    return 0;
    749 
    750 	  clear_packet(mess, end);
    751 
    752 	  mess->yiaddr = mess->ciaddr;
    753 	  mess->ciaddr.s_addr = 0;
    754 	  if (service->server.s_addr != 0)
    755 	    mess->siaddr = service->server;
    756 	  else
    757 	    mess->siaddr = context->local;
    758 
    759 	  snprintf((char *)mess->file, sizeof(mess->file), "%s.%d", service->basename, layer);
    760 	  option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
    761 	  option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, htonl(context->local.s_addr));
    762 	  pxe_misc(mess, end, uuid);
    763 
    764 	  prune_vendor_opts(netid);
    765 	  opt71.val = save71;
    766 	  opt71.opt = SUBOPT_PXE_BOOT_ITEM;
    767 	  opt71.len = 4;
    768 	  opt71.flags = DHOPT_VENDOR_MATCH;
    769 	  opt71.netid = NULL;
    770 	  opt71.next = daemon->dhcp_opts;
    771 	  do_encap_opts(&opt71, OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0);
    772 
    773 	  log_packet("PXE", &mess->yiaddr, emac, emac_len, iface_name, (char *)mess->file, mess->xid);
    774 	  return dhcp_packet_size(mess, netid, agent_id, real_end);
    775 	}
    776 
    777       if ((opt = option_find(mess, sz, OPTION_ARCH, 2)))
    778 	{
    779 	  pxearch = option_uint(opt, 0, 2);
    780 
    781 	  /* proxy DHCP here. The DHCPREQUEST stuff is for gPXE */
    782 	  if ((mess_type == DHCPDISCOVER || mess_type == DHCPREQUEST) &&
    783 	      (context->flags & CONTEXT_PROXY))
    784 	    {
    785 	      struct dhcp_boot *boot = find_boot(netid);
    786 
    787 	      mess->yiaddr.s_addr = 0;
    788 	      if  (mess_type == DHCPDISCOVER || mess->ciaddr.s_addr == 0)
    789 		{
    790 		  mess->ciaddr.s_addr = 0;
    791 		  mess->flags |= htons(0x8000); /* broadcast */
    792 		}
    793 
    794 	      clear_packet(mess, end);
    795 
    796 	      /* Provide the bootfile here, for gPXE, and in case we have no menu items
    797 		 and set discovery_control = 8 */
    798 	      if (boot)
    799 		{
    800 		  if (boot->next_server.s_addr)
    801 		    mess->siaddr = boot->next_server;
    802 
    803 		  if (boot->file)
    804 		    strncpy((char *)mess->file, boot->file, sizeof(mess->file)-1);
    805 		}
    806 
    807 	      option_put(mess, end, OPTION_MESSAGE_TYPE, 1,
    808 			 mess_type == DHCPDISCOVER ? DHCPOFFER : DHCPACK);
    809 	      option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, htonl(context->local.s_addr));
    810 	      pxe_misc(mess, end, uuid);
    811 	      prune_vendor_opts(netid);
    812 	      do_encap_opts(pxe_opts(pxearch, netid), OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, 0);
    813 
    814 	      log_packet("PXE", NULL, emac, emac_len, iface_name, ignore ? "proxy" : "proxy-ignored", mess->xid);
    815 	      return ignore ? 0 : dhcp_packet_size(mess, netid, agent_id, real_end);
    816 	    }
    817 	}
    818     }
    819 
    820   /* if we're just a proxy server, go no further */
    821   if (context->flags & CONTEXT_PROXY)
    822     return 0;
    823 
    824   if ((opt = option_find(mess, sz, OPTION_REQUESTED_OPTIONS, 0)))
    825     {
    826       req_options = (unsigned char *)daemon->dhcp_buff2;
    827       memcpy(req_options, option_ptr(opt, 0), option_len(opt));
    828       req_options[option_len(opt)] = OPTION_END;
    829     }
    830 
    831   switch (mess_type)
    832     {
    833     case DHCPDECLINE:
    834       if (!(opt = option_find(mess, sz, OPTION_SERVER_IDENTIFIER, INADDRSZ)) ||
    835 	  option_addr(opt).s_addr != server_id(context, override, fallback).s_addr)
    836 	return 0;
    837 
    838       /* sanitise any message. Paranoid? Moi? */
    839       sanitise(option_find(mess, sz, OPTION_MESSAGE, 1), daemon->dhcp_buff);
    840 
    841       if (!(opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ)))
    842 	return 0;
    843 
    844       log_packet("DHCPDECLINE", option_ptr(opt, 0), emac, emac_len, iface_name, daemon->dhcp_buff, mess->xid);
    845 
    846       if (lease && lease->addr.s_addr == option_addr(opt).s_addr)
    847 	lease_prune(lease, now);
    848 
    849       if (have_config(config, CONFIG_ADDR) &&
    850 	  config->addr.s_addr == option_addr(opt).s_addr)
    851 	{
    852 	  prettyprint_time(daemon->dhcp_buff, DECLINE_BACKOFF);
    853 	  my_syslog(MS_DHCP | LOG_WARNING, _("disabling DHCP static address %s for %s"),
    854 		    inet_ntoa(config->addr), daemon->dhcp_buff);
    855 	  config->flags |= CONFIG_DECLINED;
    856 	  config->decline_time = now;
    857 	}
    858       else
    859 	/* make sure this host gets a different address next time. */
    860 	for (; context; context = context->current)
    861 	  context->addr_epoch++;
    862 
    863       return 0;
    864 
    865     case DHCPRELEASE:
    866       if (!(context = narrow_context(context, mess->ciaddr, netid)) ||
    867 	  !(opt = option_find(mess, sz, OPTION_SERVER_IDENTIFIER, INADDRSZ)) ||
    868 	  option_addr(opt).s_addr != server_id(context, override, fallback).s_addr)
    869 	return 0;
    870 
    871       if (lease && lease->addr.s_addr == mess->ciaddr.s_addr)
    872 	lease_prune(lease, now);
    873       else
    874 	message = _("unknown lease");
    875 
    876       log_packet("DHCPRELEASE", &mess->ciaddr, emac, emac_len, iface_name, message, mess->xid);
    877 
    878       return 0;
    879 
    880     case DHCPDISCOVER:
    881       if (ignore || have_config(config, CONFIG_DISABLE))
    882 	{
    883 	  message = _("ignored");
    884 	  opt = NULL;
    885 	}
    886       else
    887 	{
    888 	  struct in_addr addr, conf;
    889 
    890 	  addr.s_addr = conf.s_addr = 0;
    891 
    892 	  if ((opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ)))
    893 	    addr = option_addr(opt);
    894 
    895 	  if (have_config(config, CONFIG_ADDR))
    896 	    {
    897 	      char *addrs = inet_ntoa(config->addr);
    898 
    899 	      if ((ltmp = lease_find_by_addr(config->addr)) &&
    900 		  ltmp != lease &&
    901 		  !config_has_mac(config, ltmp->hwaddr, ltmp->hwaddr_len, ltmp->hwaddr_type))
    902 		{
    903 		  int len;
    904 		  unsigned char *mac = extended_hwaddr(ltmp->hwaddr_type, ltmp->hwaddr_len,
    905 						       ltmp->hwaddr, ltmp->clid_len, ltmp->clid, &len);
    906 		  my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it is leased to %s"),
    907 			    addrs, print_mac(daemon->namebuff, mac, len));
    908 		}
    909 	      else
    910 		{
    911 		  struct dhcp_context *tmp;
    912 		  for (tmp = context; tmp; tmp = tmp->current)
    913 		    if (context->router.s_addr == config->addr.s_addr)
    914 		      break;
    915 		  if (tmp)
    916 		    my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it is in use by the server or relay"), addrs);
    917 		  else if (have_config(config, CONFIG_DECLINED) &&
    918 			   difftime(now, config->decline_time) < (float)DECLINE_BACKOFF)
    919 		    my_syslog(MS_DHCP | LOG_WARNING, _("not using configured address %s because it was previously declined"), addrs);
    920 		  else
    921 		    conf = config->addr;
    922 		}
    923 	    }
    924 
    925 	  if (conf.s_addr)
    926 	    mess->yiaddr = conf;
    927 	  else if (lease &&
    928 		   address_available(context, lease->addr, netid) &&
    929 		   !config_find_by_address(daemon->dhcp_conf, lease->addr))
    930 	    mess->yiaddr = lease->addr;
    931 	  else if (opt && address_available(context, addr, netid) && !lease_find_by_addr(addr) &&
    932 		   !config_find_by_address(daemon->dhcp_conf, addr))
    933 	    mess->yiaddr = addr;
    934 	  else if (emac_len == 0)
    935 	    message = _("no unique-id");
    936 	  else if (!address_allocate(context, &mess->yiaddr, emac, emac_len, netid, now))
    937 	    message = _("no address available");
    938 	}
    939 
    940       log_packet("DHCPDISCOVER", opt ? option_ptr(opt, 0) : NULL, emac, emac_len, iface_name, message, mess->xid);
    941 
    942       if (message || !(context = narrow_context(context, mess->yiaddr, netid)))
    943 	return 0;
    944 
    945       log_packet("DHCPOFFER" , &mess->yiaddr, emac, emac_len, iface_name, NULL, mess->xid);
    946 
    947       if (context->netid.net)
    948 	{
    949 	  context->netid.next = netid;
    950 	  netid = &context->netid;
    951 	}
    952 
    953       time = calc_time(context, config, option_find(mess, sz, OPTION_LEASE_TIME, 4));
    954       clear_packet(mess, end);
    955       option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPOFFER);
    956       option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
    957       option_put(mess, end, OPTION_LEASE_TIME, 4, time);
    958       /* T1 and T2 are required in DHCPOFFER by HP's wacky Jetdirect client. */
    959       if (time != 0xffffffff)
    960 	{
    961 	  option_put(mess, end, OPTION_T1, 4, (time/2));
    962 	  option_put(mess, end, OPTION_T2, 4, (time*7)/8);
    963 	}
    964       do_options(context, mess, end, req_options, offer_hostname, get_domain(mess->yiaddr),
    965 		 domain, netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid);
    966 
    967       return dhcp_packet_size(mess, netid, agent_id, real_end);
    968 
    969     case DHCPREQUEST:
    970       if (ignore || have_config(config, CONFIG_DISABLE))
    971 	return 0;
    972       if ((opt = option_find(mess, sz, OPTION_REQUESTED_IP, INADDRSZ)))
    973 	{
    974 	  /* SELECTING  or INIT_REBOOT */
    975 	  mess->yiaddr = option_addr(opt);
    976 
    977 	  /* send vendor and user class info for new or recreated lease */
    978 	  do_classes = 1;
    979 
    980 	  if ((opt = option_find(mess, sz, OPTION_SERVER_IDENTIFIER, INADDRSZ)))
    981 	    {
    982 	      /* SELECTING */
    983 	      selecting = 1;
    984 
    985 	      if (override.s_addr != 0)
    986 		{
    987 		  if (option_addr(opt).s_addr != override.s_addr)
    988 		    return 0;
    989 		}
    990 	      else
    991 		{
    992 		  for (; context; context = context->current)
    993 		    if (context->local.s_addr == option_addr(opt).s_addr)
    994 		      break;
    995 
    996 		  if (!context)
    997 		    {
    998 		      /* In auth mode, a REQUEST sent to the wrong server
    999 			 should be faulted, so that the client establishes
   1000 			 communication with us, otherwise, silently ignore. */
   1001 		      if (!(daemon->options & OPT_AUTHORITATIVE))
   1002 			return 0;
   1003 		      message = _("wrong server-ID");
   1004 		    }
   1005 		}
   1006 
   1007 	      /* If a lease exists for this host and another address, squash it. */
   1008 	      if (lease && lease->addr.s_addr != mess->yiaddr.s_addr)
   1009 		{
   1010 		  lease_prune(lease, now);
   1011 		  lease = NULL;
   1012 		}
   1013 	    }
   1014 	  else
   1015 	    {
   1016 	      /* INIT-REBOOT */
   1017 	      if (!lease && !(daemon->options & OPT_AUTHORITATIVE))
   1018 		return 0;
   1019 
   1020 	      if (lease && lease->addr.s_addr != mess->yiaddr.s_addr)
   1021 		{
   1022 		  message = _("wrong address");
   1023 		  /* avoid loops when client brain-dead */
   1024 		  lease_prune(lease, now);
   1025 		  lease = NULL;
   1026 		}
   1027 	    }
   1028 	}
   1029       else
   1030 	{
   1031 	  /* RENEWING or REBINDING */
   1032 	  /* Check existing lease for this address.
   1033 	     We allow it to be missing if dhcp-authoritative mode
   1034 	     as long as we can allocate the lease now - checked below.
   1035 	     This makes for a smooth recovery from a lost lease DB */
   1036 	  if ((lease && mess->ciaddr.s_addr != lease->addr.s_addr) ||
   1037 	      (!lease && !(daemon->options & OPT_AUTHORITATIVE)))
   1038 	    {
   1039 	      message = _("lease not found");
   1040 	      /* ensure we broadcast NAK */
   1041 	      unicast_dest = 0;
   1042 	    }
   1043 	  /* desynchronise renewals */
   1044 	  fuzz = rand16();
   1045 	  mess->yiaddr = mess->ciaddr;
   1046 	}
   1047 
   1048       log_packet("DHCPREQUEST", &mess->yiaddr, emac, emac_len, iface_name, NULL, mess->xid);
   1049 
   1050       if (!message)
   1051 	{
   1052 	  struct dhcp_config *addr_config;
   1053 	  struct dhcp_context *tmp = NULL;
   1054 
   1055 	  if (have_config(config, CONFIG_ADDR))
   1056 	    for (tmp = context; tmp; tmp = tmp->current)
   1057 	      if (context->router.s_addr == config->addr.s_addr)
   1058 		break;
   1059 
   1060 	  if (!(context = narrow_context(context, mess->yiaddr, netid)))
   1061 	    {
   1062 	      /* If a machine moves networks whilst it has a lease, we catch that here. */
   1063 	      message = _("wrong network");
   1064 	      /* ensure we broadcast NAK */
   1065 	      unicast_dest = 0;
   1066 	    }
   1067 
   1068 	  /* Check for renewal of a lease which is outside the allowed range. */
   1069 	  else if (!address_available(context, mess->yiaddr, netid) &&
   1070 		   (!have_config(config, CONFIG_ADDR) || config->addr.s_addr != mess->yiaddr.s_addr))
   1071 	    message = _("address not available");
   1072 
   1073 	  /* Check if a new static address has been configured. Be very sure that
   1074 	     when the client does DISCOVER, it will get the static address, otherwise
   1075 	     an endless protocol loop will ensue. */
   1076 	  else if (!tmp && !selecting &&
   1077 		   have_config(config, CONFIG_ADDR) &&
   1078 		   (!have_config(config, CONFIG_DECLINED) ||
   1079 		    difftime(now, config->decline_time) > (float)DECLINE_BACKOFF) &&
   1080 		   config->addr.s_addr != mess->yiaddr.s_addr &&
   1081 		   (!(ltmp = lease_find_by_addr(config->addr)) || ltmp == lease))
   1082 	    message = _("static lease available");
   1083 
   1084 	  /* Check to see if the address is reserved as a static address for another host */
   1085 	  else if ((addr_config = config_find_by_address(daemon->dhcp_conf, mess->yiaddr)) && addr_config != config)
   1086 	    message = _("address reserved");
   1087 
   1088 	  else if (!lease && (ltmp = lease_find_by_addr(mess->yiaddr)))
   1089 	    {
   1090 	      /* If a host is configured with more than one MAC address, it's OK to 'nix
   1091 		 a lease from one of it's MACs to give the address to another. */
   1092 	      if (config && config_has_mac(config, ltmp->hwaddr, ltmp->hwaddr_len, ltmp->hwaddr_type))
   1093 		{
   1094 		  my_syslog(MS_DHCP | LOG_INFO, _("abandoning lease to %s of %s"),
   1095 			    print_mac(daemon->namebuff, ltmp->hwaddr, ltmp->hwaddr_len),
   1096 			    inet_ntoa(ltmp->addr));
   1097 		  lease = ltmp;
   1098 		}
   1099 	      else
   1100 		message = _("address in use");
   1101 	    }
   1102 
   1103 	  if (!message)
   1104 	    {
   1105 	      if (emac_len == 0)
   1106 		message = _("no unique-id");
   1107 
   1108 	      else if (!lease)
   1109 		{
   1110 		  if ((lease = lease_allocate(mess->yiaddr)))
   1111 		    do_classes = 1;
   1112 		  else
   1113 		    message = _("no leases left");
   1114 		}
   1115 	    }
   1116 	}
   1117 
   1118       if (message)
   1119 	{
   1120 	  log_packet("DHCPNAK", &mess->yiaddr, emac, emac_len, iface_name, message, mess->xid);
   1121 
   1122 	  mess->yiaddr.s_addr = 0;
   1123 	  clear_packet(mess, end);
   1124 	  option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPNAK);
   1125 	  option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
   1126 	  option_put_string(mess, end, OPTION_MESSAGE, message, borken_opt);
   1127 	  /* This fixes a problem with the DHCP spec, broadcasting a NAK to a host on
   1128 	     a distant subnet which unicast a REQ to us won't work. */
   1129 	  if (!unicast_dest || mess->giaddr.s_addr != 0 ||
   1130 	      mess->ciaddr.s_addr == 0 || is_same_net(context->local, mess->ciaddr, context->netmask))
   1131 	    {
   1132 	      mess->flags |= htons(0x8000); /* broadcast */
   1133 	      mess->ciaddr.s_addr = 0;
   1134 	    }
   1135 	}
   1136       else
   1137 	{
   1138 	   if (do_classes)
   1139 	     {
   1140 	       if (mess->giaddr.s_addr)
   1141 		 lease->giaddr = mess->giaddr;
   1142 
   1143 	       lease->changed = 1;
   1144 	       /* copy user-class and vendor class into new lease, for the script */
   1145 	       if ((opt = option_find(mess, sz, OPTION_USER_CLASS, 1)))
   1146 		 {
   1147 		   int len = option_len(opt);
   1148 		   unsigned char *ucp = option_ptr(opt, 0);
   1149 		   /* If the user-class option started as counted strings, the first byte will be zero. */
   1150 		   if (len != 0 && ucp[0] == 0)
   1151 		     ucp++, len--;
   1152 		   free(lease->userclass);
   1153 		   if ((lease->userclass = whine_malloc(len+1)))
   1154 		     {
   1155 		       memcpy(lease->userclass, ucp, len);
   1156 		       lease->userclass[len] = 0;
   1157 		       lease->userclass_len = len+1;
   1158 		     }
   1159 		 }
   1160 	       if ((opt = option_find(mess, sz, OPTION_VENDOR_ID, 1)))
   1161 		 {
   1162 		   int len = option_len(opt);
   1163 		   unsigned char *ucp = option_ptr(opt, 0);
   1164 		   free(lease->vendorclass);
   1165 		   if ((lease->vendorclass = whine_malloc(len+1)))
   1166 		     {
   1167 		       memcpy(lease->vendorclass, ucp, len);
   1168 		       lease->vendorclass[len] = 0;
   1169 		       lease->vendorclass_len = len+1;
   1170 		     }
   1171 		 }
   1172 	       if ((opt = option_find(mess, sz, OPTION_HOSTNAME, 1)))
   1173 		 {
   1174 		   int len = option_len(opt);
   1175 		   unsigned char *ucp = option_ptr(opt, 0);
   1176 		   free(lease->supplied_hostname);
   1177 		   if ((lease->supplied_hostname = whine_malloc(len+1)))
   1178 		     {
   1179 		       memcpy(lease->supplied_hostname, ucp, len);
   1180 		       lease->supplied_hostname[len] = 0;
   1181 		       lease->supplied_hostname_len = len+1;
   1182 		     }
   1183 		 }
   1184 	     }
   1185 
   1186 	   if (!hostname_auth && (client_hostname = host_from_dns(mess->yiaddr)))
   1187 	     {
   1188 	      hostname = client_hostname;
   1189 	      hostname_auth = 1;
   1190 	    }
   1191 
   1192 	  if (context->netid.net)
   1193 	    {
   1194 	      context->netid.next = netid;
   1195 	      netid = &context->netid;
   1196 	    }
   1197 
   1198 	  time = calc_time(context, config, option_find(mess, sz, OPTION_LEASE_TIME, 4));
   1199 	  lease_set_hwaddr(lease, mess->chaddr, clid, mess->hlen, mess->htype, clid_len);
   1200 
   1201 	  /* if all the netids in the ignore_name list are present, ignore client-supplied name */
   1202 	  if (!hostname_auth)
   1203 	    {
   1204 	      for (id_list = daemon->dhcp_ignore_names; id_list; id_list = id_list->next)
   1205 		if ((!id_list->list) || match_netid(id_list->list, netid, 0))
   1206 		  break;
   1207 	      if (id_list)
   1208 		hostname = NULL;
   1209 	    }
   1210 	  if (hostname)
   1211 	    lease_set_hostname(lease, hostname, hostname_auth);
   1212 
   1213 	  lease_set_expires(lease, time, now);
   1214 	  lease_set_interface(lease, int_index);
   1215 
   1216 	  if (override.s_addr != 0)
   1217 	    lease->override = override;
   1218 	  else
   1219 	    override = lease->override;
   1220 
   1221 	  log_packet("DHCPACK", &mess->yiaddr, emac, emac_len, iface_name, hostname, mess->xid);
   1222 
   1223 	  clear_packet(mess, end);
   1224 	  option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
   1225 	  option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
   1226 	  option_put(mess, end, OPTION_LEASE_TIME, 4, time);
   1227 	  if (time != 0xffffffff)
   1228 	    {
   1229 	      while (fuzz > (time/16))
   1230 		fuzz = fuzz/2;
   1231 	      option_put(mess, end, OPTION_T1, 4, (time/2) - fuzz);
   1232 	      option_put(mess, end, OPTION_T2, 4, ((time/8)*7) - fuzz);
   1233 	    }
   1234 	  do_options(context, mess, end, req_options, hostname, get_domain(mess->yiaddr),
   1235 		     domain, netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid);
   1236 	}
   1237 
   1238       return dhcp_packet_size(mess, netid, agent_id, real_end);
   1239 
   1240     case DHCPINFORM:
   1241       if (ignore || have_config(config, CONFIG_DISABLE))
   1242 	message = _("ignored");
   1243 
   1244       log_packet("DHCPINFORM", &mess->ciaddr, emac, emac_len, iface_name, message, mess->xid);
   1245 
   1246       if (message || mess->ciaddr.s_addr == 0)
   1247 	return 0;
   1248 
   1249       /* For DHCPINFORM only, cope without a valid context */
   1250       context = narrow_context(context, mess->ciaddr, netid);
   1251 
   1252       /* Find a least based on IP address if we didn't
   1253 	 get one from MAC address/client-d */
   1254       if (!lease &&
   1255 	  (lease = lease_find_by_addr(mess->ciaddr)) &&
   1256 	  lease->hostname)
   1257 	hostname = lease->hostname;
   1258 
   1259       if (!hostname)
   1260 	hostname = host_from_dns(mess->ciaddr);
   1261 
   1262       log_packet("DHCPACK", &mess->ciaddr, emac, emac_len, iface_name, hostname, mess->xid);
   1263 
   1264       if (context && context->netid.net)
   1265 	{
   1266 	  context->netid.next = netid;
   1267 	  netid = &context->netid;
   1268 	}
   1269 
   1270       if (lease)
   1271 	{
   1272 	  if (override.s_addr != 0)
   1273 	    lease->override = override;
   1274 	  else
   1275 	    override = lease->override;
   1276 	}
   1277 
   1278       clear_packet(mess, end);
   1279       option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
   1280       option_put(mess, end, OPTION_SERVER_IDENTIFIER, INADDRSZ, ntohl(server_id(context, override, fallback).s_addr));
   1281 
   1282       if (lease)
   1283 	{
   1284 	  if (lease->expires == 0)
   1285 	    time = 0xffffffff;
   1286 	  else
   1287 	    time = (unsigned int)difftime(lease->expires, now);
   1288 	  option_put(mess, end, OPTION_LEASE_TIME, 4, time);
   1289 	  lease_set_interface(lease, int_index);
   1290 	}
   1291 
   1292       do_options(context, mess, end, req_options, hostname, get_domain(mess->ciaddr),
   1293 		 domain, netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid);
   1294 
   1295       *is_inform = 1; /* handle reply differently */
   1296       return dhcp_packet_size(mess, netid, agent_id, real_end);
   1297     }
   1298 
   1299   return 0;
   1300 }
   1301 
   1302 /* find a good value to use as MAC address for logging and address-allocation hashing.
   1303    This is normally just the chaddr field from the DHCP packet,
   1304    but eg Firewire will have hlen == 0 and use the client-id instead.
   1305    This could be anything, but will normally be EUI64 for Firewire.
   1306    We assume that if the first byte of the client-id equals the htype byte
   1307    then the client-id is using the usual encoding and use the rest of the
   1308    client-id: if not we can use the whole client-id. This should give
   1309    sane MAC address logs. */
   1310 unsigned char *extended_hwaddr(int hwtype, int hwlen, unsigned char *hwaddr,
   1311 				      int clid_len, unsigned char *clid, int *len_out)
   1312 {
   1313   if (hwlen == 0 && clid && clid_len > 3)
   1314     {
   1315       if (clid[0]  == hwtype)
   1316 	{
   1317 	  *len_out = clid_len - 1 ;
   1318 	  return clid + 1;
   1319 	}
   1320 
   1321 #if defined(ARPHRD_EUI64) && defined(ARPHRD_IEEE1394)
   1322       if (clid[0] ==  ARPHRD_EUI64 && hwtype == ARPHRD_IEEE1394)
   1323 	{
   1324 	  *len_out = clid_len - 1 ;
   1325 	  return clid + 1;
   1326 	}
   1327 #endif
   1328 
   1329       *len_out = clid_len;
   1330       return clid;
   1331     }
   1332 
   1333   *len_out = hwlen;
   1334   return hwaddr;
   1335 }
   1336 
   1337 static unsigned int calc_time(struct dhcp_context *context, struct dhcp_config *config, unsigned char *opt)
   1338 {
   1339   unsigned int time = have_config(config, CONFIG_TIME) ? config->lease_time : context->lease_time;
   1340 
   1341   if (opt)
   1342     {
   1343       unsigned int req_time = option_uint(opt, 0, 4);
   1344       if (req_time < 120 )
   1345 	req_time = 120; /* sanity */
   1346       if (time == 0xffffffff || (req_time != 0xffffffff && req_time < time))
   1347 	time = req_time;
   1348     }
   1349 
   1350   return time;
   1351 }
   1352 
   1353 static struct in_addr server_id(struct dhcp_context *context, struct in_addr override, struct in_addr fallback)
   1354 {
   1355   if (override.s_addr != 0)
   1356     return override;
   1357   else if (context)
   1358     return context->local;
   1359   else
   1360     return fallback;
   1361 }
   1362 
   1363 static int sanitise(unsigned char *opt, char *buf)
   1364 {
   1365   char *p;
   1366   int i;
   1367 
   1368   *buf = 0;
   1369 
   1370   if (!opt)
   1371     return 0;
   1372 
   1373   p = option_ptr(opt, 0);
   1374 
   1375   for (i = option_len(opt); i > 0; i--)
   1376     {
   1377       char c = *p++;
   1378       if (isprint((int)c))
   1379 	*buf++ = c;
   1380     }
   1381   *buf = 0; /* add terminator */
   1382 
   1383   return 1;
   1384 }
   1385 
   1386 static void log_packet(char *type, void *addr, unsigned char *ext_mac,
   1387 		       int mac_len, char *interface, char *string, u32 xid)
   1388 {
   1389   struct in_addr a;
   1390 
   1391   /* addr may be misaligned */
   1392   if (addr)
   1393     memcpy(&a, addr, sizeof(a));
   1394 
   1395   print_mac(daemon->namebuff, ext_mac, mac_len);
   1396 
   1397   if(daemon->options & OPT_LOG_OPTS)
   1398      my_syslog(MS_DHCP | LOG_INFO, "%u %s(%s) %s%s%s %s",
   1399 	       ntohl(xid),
   1400 	       type,
   1401 	       interface,
   1402 	       addr ? inet_ntoa(a) : "",
   1403 	       addr ? " " : "",
   1404 	       daemon->namebuff,
   1405 	       string ? string : "");
   1406   else
   1407     my_syslog(MS_DHCP | LOG_INFO, "%s(%s) %s%s%s %s",
   1408 	      type,
   1409 	      interface,
   1410 	      addr ? inet_ntoa(a) : "",
   1411 	      addr ? " " : "",
   1412 	      daemon->namebuff,
   1413 	      string ? string : "");
   1414 }
   1415 
   1416 static void log_options(unsigned char *start, u32 xid)
   1417 {
   1418   while (*start != OPTION_END)
   1419     {
   1420       int is_ip, is_name, i;
   1421       char *text = option_string(start[0], &is_ip, &is_name);
   1422       unsigned char trunc = option_len(start);
   1423 
   1424       if (is_ip)
   1425 	for (daemon->namebuff[0]= 0, i = 0; i <= trunc - INADDRSZ; i += INADDRSZ)
   1426 	  {
   1427 	    if (i != 0)
   1428 	      strncat(daemon->namebuff, ", ", 256 - strlen(daemon->namebuff));
   1429 	    strncat(daemon->namebuff, inet_ntoa(option_addr_arr(start, i)), 256 - strlen(daemon->namebuff));
   1430 	  }
   1431       else if (!is_name || !sanitise(start, daemon->namebuff))
   1432 	{
   1433 	  if (trunc > 13)
   1434 	    trunc = 13;
   1435 	  print_mac(daemon->namebuff, option_ptr(start, 0), trunc);
   1436 	}
   1437 
   1438       my_syslog(MS_DHCP | LOG_INFO, "%u sent size:%3d option:%3d%s%s%s%s%s",
   1439 		ntohl(xid), option_len(start), start[0],
   1440 		text ? ":" : "", text ? text : "",
   1441 		trunc == 0 ? "" : "  ",
   1442 		trunc == 0 ? "" : daemon->namebuff,
   1443 		trunc == option_len(start) ? "" : "...");
   1444       start += start[1] + 2;
   1445     }
   1446 }
   1447 
   1448 static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt, int minsize)
   1449 {
   1450   while (1)
   1451     {
   1452       if (p > end)
   1453 	return NULL;
   1454       else if (*p == OPTION_END)
   1455 	return opt == OPTION_END ? p : NULL;
   1456       else if (*p == OPTION_PAD)
   1457 	p++;
   1458       else
   1459 	{
   1460 	  int opt_len;
   1461 	  if (p > end - 2)
   1462 	    return NULL; /* malformed packet */
   1463 	  opt_len = option_len(p);
   1464 	  if (p > end - (2 + opt_len))
   1465 	    return NULL; /* malformed packet */
   1466 	  if (*p == opt && opt_len >= minsize)
   1467 	    return p;
   1468 	  p += opt_len + 2;
   1469 	}
   1470     }
   1471 }
   1472 
   1473 static unsigned char *option_find(struct dhcp_packet *mess, size_t size, int opt_type, int minsize)
   1474 {
   1475   unsigned char *ret, *overload;
   1476 
   1477   /* skip over DHCP cookie; */
   1478   if ((ret = option_find1(&mess->options[0] + sizeof(u32), ((unsigned char *)mess) + size, opt_type, minsize)))
   1479     return ret;
   1480 
   1481   /* look for overload option. */
   1482   if (!(overload = option_find1(&mess->options[0] + sizeof(u32), ((unsigned char *)mess) + size, OPTION_OVERLOAD, 1)))
   1483     return NULL;
   1484 
   1485   /* Can we look in filename area ? */
   1486   if ((overload[2] & 1) &&
   1487       (ret = option_find1(&mess->file[0], &mess->file[128], opt_type, minsize)))
   1488     return ret;
   1489 
   1490   /* finally try sname area */
   1491   if ((overload[2] & 2) &&
   1492       (ret = option_find1(&mess->sname[0], &mess->sname[64], opt_type, minsize)))
   1493     return ret;
   1494 
   1495   return NULL;
   1496 }
   1497 
   1498 static struct in_addr option_addr_arr(unsigned char *opt, int offset)
   1499 {
   1500   /* this worries about unaligned data in the option. */
   1501   /* struct in_addr is network byte order */
   1502   struct in_addr ret;
   1503 
   1504   memcpy(&ret, option_ptr(opt, offset), INADDRSZ);
   1505 
   1506   return ret;
   1507 }
   1508 
   1509 static struct in_addr option_addr(unsigned char *opt)
   1510 {
   1511   return option_addr_arr(opt, 0);
   1512 }
   1513 
   1514 static unsigned int option_uint(unsigned char *opt, int offset, int size)
   1515 {
   1516   /* this worries about unaligned data and byte order */
   1517   unsigned int ret = 0;
   1518   int i;
   1519   unsigned char *p = option_ptr(opt, offset);
   1520 
   1521   for (i = 0; i < size; i++)
   1522     ret = (ret << 8) | *p++;
   1523 
   1524   return ret;
   1525 }
   1526 
   1527 static unsigned char *dhcp_skip_opts(unsigned char *start)
   1528 {
   1529   while (*start != 0)
   1530     start += start[1] + 2;
   1531   return start;
   1532 }
   1533 
   1534 /* only for use when building packet: doesn't check for bad data. */
   1535 static unsigned char *find_overload(struct dhcp_packet *mess)
   1536 {
   1537   unsigned char *p = &mess->options[0] + sizeof(u32);
   1538 
   1539   while (*p != 0)
   1540     {
   1541       if (*p == OPTION_OVERLOAD)
   1542 	return p;
   1543       p += p[1] + 2;
   1544     }
   1545   return NULL;
   1546 }
   1547 
   1548 static size_t dhcp_packet_size(struct dhcp_packet *mess, struct dhcp_netid *netid,
   1549 			       unsigned char *agent_id, unsigned char *real_end)
   1550 {
   1551   unsigned char *p = dhcp_skip_opts(&mess->options[0] + sizeof(u32));
   1552   unsigned char *overload;
   1553   size_t ret;
   1554   struct dhcp_netid_list *id_list;
   1555   struct dhcp_netid *n;
   1556 
   1557   /* move agent_id back down to the end of the packet */
   1558   if (agent_id)
   1559     {
   1560       memmove(p, agent_id, real_end - agent_id);
   1561       p += real_end - agent_id;
   1562       memset(p, 0, real_end - p); /* in case of overlap */
   1563     }
   1564 
   1565   /* We do logging too */
   1566   if (netid && (daemon->options & OPT_LOG_OPTS))
   1567     {
   1568       char *s = daemon->namebuff;
   1569       for (*s = 0; netid; netid = netid->next)
   1570 	{
   1571 	  /* kill dupes. */
   1572 	  for (n = netid->next; n; n = n->next)
   1573 	    if (strcmp(netid->net, n->net) == 0)
   1574 	      break;
   1575 
   1576 	  if (!n)
   1577 	    {
   1578 	      strncat (s, netid->net, (MAXDNAME-1) - strlen(s));
   1579 	      if (netid->next)
   1580 		strncat (s, ", ", (MAXDNAME-1) - strlen(s));
   1581 	    }
   1582 	}
   1583       my_syslog(MS_DHCP | LOG_INFO, _("%u tags: %s"), ntohl(mess->xid), s);
   1584     }
   1585 
   1586   /* add END options to the regions. */
   1587   overload = find_overload(mess);
   1588 
   1589   if (overload && (option_uint(overload, 0, 1) & 1))
   1590     {
   1591       *dhcp_skip_opts(mess->file) = OPTION_END;
   1592       if (daemon->options & OPT_LOG_OPTS)
   1593 	log_options(mess->file, mess->xid);
   1594     }
   1595   else if ((daemon->options & OPT_LOG_OPTS) && strlen((char *)mess->file) != 0)
   1596     my_syslog(MS_DHCP | LOG_INFO, _("%u bootfile name: %s"), ntohl(mess->xid), (char *)mess->file);
   1597 
   1598   if (overload && (option_uint(overload, 0, 1) & 2))
   1599     {
   1600       *dhcp_skip_opts(mess->sname) = OPTION_END;
   1601       if (daemon->options & OPT_LOG_OPTS)
   1602 	log_options(mess->sname, mess->xid);
   1603     }
   1604   else if ((daemon->options & OPT_LOG_OPTS) && strlen((char *)mess->sname) != 0)
   1605     my_syslog(MS_DHCP | LOG_INFO, _("%u server name: %s"), ntohl(mess->xid), (char *)mess->sname);
   1606 
   1607 
   1608   *p++ = OPTION_END;
   1609 
   1610   if (daemon->options & OPT_LOG_OPTS)
   1611     {
   1612       if (mess->siaddr.s_addr != 0)
   1613 	my_syslog(MS_DHCP | LOG_INFO, _("%u next server: %s"), ntohl(mess->xid), inet_ntoa(mess->siaddr));
   1614 
   1615       log_options(&mess->options[0] + sizeof(u32), mess->xid);
   1616     }
   1617 
   1618   for (id_list = daemon->force_broadcast; id_list; id_list = id_list->next)
   1619     if (match_netid(id_list->list, netid, 0))
   1620       mess->flags |= htons(0x8000); /* force broadcast */
   1621 
   1622   ret = (size_t)(p - (unsigned char *)mess);
   1623 
   1624   if (ret < MIN_PACKETSZ)
   1625     ret = MIN_PACKETSZ;
   1626 
   1627   return ret;
   1628 }
   1629 
   1630 static unsigned char *free_space(struct dhcp_packet *mess, unsigned char *end, int opt, int len)
   1631 {
   1632   unsigned char *p = dhcp_skip_opts(&mess->options[0] + sizeof(u32));
   1633 
   1634   if (p + len + 3 >= end)
   1635     /* not enough space in options area, try and use overload, if poss */
   1636     {
   1637       unsigned char *overload;
   1638 
   1639       if (!(overload = find_overload(mess)) &&
   1640 	  (mess->file[0] == 0 || mess->sname[0] == 0))
   1641 	{
   1642 	  /* attempt to overload fname and sname areas, we've reserved space for the
   1643 	     overflow option previuously. */
   1644 	  overload = p;
   1645 	  *(p++) = OPTION_OVERLOAD;
   1646 	  *(p++) = 1;
   1647 	}
   1648 
   1649       p = NULL;
   1650 
   1651       /* using filename field ? */
   1652       if (overload)
   1653 	{
   1654 	  if (mess->file[0] == 0)
   1655 	    overload[2] |= 1;
   1656 
   1657 	  if (overload[2] & 1)
   1658 	    {
   1659 	      p = dhcp_skip_opts(mess->file);
   1660 	      if (p + len + 3 >= mess->file + sizeof(mess->file))
   1661 		p = NULL;
   1662 	    }
   1663 
   1664 	  if (!p)
   1665 	    {
   1666 	      /* try to bring sname into play (it may be already) */
   1667 	      if (mess->sname[0] == 0)
   1668 		overload[2] |= 2;
   1669 
   1670 	      if (overload[2] & 2)
   1671 		{
   1672 		  p = dhcp_skip_opts(mess->sname);
   1673 		  if (p + len + 3 >= mess->sname + sizeof(mess->file))
   1674 		    p = NULL;
   1675 		}
   1676 	    }
   1677 	}
   1678 
   1679       if (!p)
   1680 	my_syslog(MS_DHCP | LOG_WARNING, _("cannot send DHCP/BOOTP option %d: no space left in packet"), opt);
   1681     }
   1682 
   1683   if (p)
   1684     {
   1685       *(p++) = opt;
   1686       *(p++) = len;
   1687     }
   1688 
   1689   return p;
   1690 }
   1691 
   1692 static void option_put(struct dhcp_packet *mess, unsigned char *end, int opt, int len, unsigned int val)
   1693 {
   1694   int i;
   1695   unsigned char *p = free_space(mess, end, opt, len);
   1696 
   1697   if (p)
   1698     for (i = 0; i < len; i++)
   1699       *(p++) = val >> (8 * (len - (i + 1)));
   1700 }
   1701 
   1702 static void option_put_string(struct dhcp_packet *mess, unsigned char *end, int opt,
   1703 			      char *string, int null_term)
   1704 {
   1705   unsigned char *p;
   1706   size_t len = strlen(string);
   1707 
   1708   if (null_term && len != 255)
   1709     len++;
   1710 
   1711   if ((p = free_space(mess, end, opt, len)))
   1712     memcpy(p, string, len);
   1713 }
   1714 
   1715 /* return length, note this only does the data part */
   1716 static int do_opt(struct dhcp_opt *opt, unsigned char *p, struct dhcp_context *context, int null_term)
   1717 {
   1718   int len = opt->len;
   1719 
   1720   if ((opt->flags & DHOPT_STRING) && null_term && len != 255)
   1721     len++;
   1722 
   1723   if (p && len != 0)
   1724     {
   1725       if (context && (opt->flags & DHOPT_ADDR))
   1726 	{
   1727 	  int j;
   1728 	  struct in_addr *a = (struct in_addr *)opt->val;
   1729 	  for (j = 0; j < opt->len; j+=INADDRSZ, a++)
   1730 	    {
   1731 	      /* zero means "self" (but not in vendorclass options.) */
   1732 	      if (a->s_addr == 0)
   1733 		memcpy(p, &context->local, INADDRSZ);
   1734 	      else
   1735 		memcpy(p, a, INADDRSZ);
   1736 	      p += INADDRSZ;
   1737 	    }
   1738 	}
   1739       else
   1740 	memcpy(p, opt->val, len);
   1741     }
   1742   return len;
   1743 }
   1744 
   1745 static int in_list(unsigned char *list, int opt)
   1746 {
   1747   int i;
   1748 
   1749    /* If no requested options, send everything, not nothing. */
   1750   if (!list)
   1751     return 1;
   1752 
   1753   for (i = 0; list[i] != OPTION_END; i++)
   1754     if (opt == list[i])
   1755       return 1;
   1756 
   1757   return 0;
   1758 }
   1759 
   1760 static struct dhcp_opt *option_find2(struct dhcp_netid *netid, struct dhcp_opt *opts, int opt)
   1761 {
   1762   struct dhcp_opt *tmp;
   1763   for (tmp = opts; tmp; tmp = tmp->next)
   1764     if (tmp->opt == opt && !(tmp->flags & (DHOPT_ENCAPSULATE | DHOPT_VENDOR)))
   1765       if (match_netid(tmp->netid, netid, netid ? 0 : 1))
   1766 	return tmp;
   1767 
   1768   return netid ? option_find2(NULL, opts, opt) : NULL;
   1769 }
   1770 
   1771 /* mark vendor-encapsulated options which match the client-supplied  or
   1772    config-supplied vendor class */
   1773 static void match_vendor_opts(unsigned char *opt, struct dhcp_opt *dopt)
   1774 {
   1775   for (; dopt; dopt = dopt->next)
   1776     {
   1777       dopt->flags &= ~DHOPT_VENDOR_MATCH;
   1778       if (opt && (dopt->flags & DHOPT_VENDOR))
   1779 	{
   1780 	  int i, len = 0;
   1781 	  if (dopt->u.vendor_class)
   1782 	    len = strlen((char *)dopt->u.vendor_class);
   1783 	  for (i = 0; i <= (option_len(opt) - len); i++)
   1784 	    if (len == 0 || memcmp(dopt->u.vendor_class, option_ptr(opt, i), len) == 0)
   1785 	      {
   1786 		dopt->flags |= DHOPT_VENDOR_MATCH;
   1787 		break;
   1788 	      }
   1789 	}
   1790     }
   1791 }
   1792 
   1793 static void do_encap_opts(struct dhcp_opt *opt, int encap, int flag,
   1794 			  struct dhcp_packet *mess, unsigned char *end, int null_term)
   1795 {
   1796   int len, enc_len;
   1797   struct dhcp_opt *start;
   1798   unsigned char *p;
   1799 
   1800   /* find size in advance */
   1801   for (enc_len = 0, start = opt; opt; opt = opt->next)
   1802     if (opt->flags & flag)
   1803       {
   1804 	int new = do_opt(opt, NULL, NULL, null_term) + 2;
   1805 	if (enc_len + new <= 255)
   1806 	  enc_len += new;
   1807 	else
   1808 	  {
   1809 	    p = free_space(mess, end, encap, enc_len);
   1810 	    for (; start && start != opt; start = start->next)
   1811 	      if (p && (start->flags & flag))
   1812 		{
   1813 		  len = do_opt(start, p + 2, NULL, null_term);
   1814 		  *(p++) = start->opt;
   1815 		  *(p++) = len;
   1816 		  p += len;
   1817 		}
   1818 	    enc_len = new;
   1819 	    start = opt;
   1820 	  }
   1821       }
   1822 
   1823   if (enc_len != 0 &&
   1824       (p = free_space(mess, end, encap, enc_len + 1)))
   1825     {
   1826       for (; start; start = start->next)
   1827 	if (start->flags & flag)
   1828 	  {
   1829 	    len = do_opt(start, p + 2, NULL, null_term);
   1830 	    *(p++) = start->opt;
   1831 	    *(p++) = len;
   1832 	    p += len;
   1833 	  }
   1834       *p = OPTION_END;
   1835     }
   1836 }
   1837 
   1838 static void pxe_misc(struct dhcp_packet *mess, unsigned char *end, unsigned char *uuid)
   1839 {
   1840   unsigned char *p;
   1841 
   1842   option_put_string(mess, end, OPTION_VENDOR_ID, "PXEClient", 0);
   1843   if (uuid && (p = free_space(mess, end, OPTION_PXE_UUID, 17)))
   1844     memcpy(p, uuid, 17);
   1845 }
   1846 
   1847 static int prune_vendor_opts(struct dhcp_netid *netid)
   1848 {
   1849   int force = 0;
   1850   struct dhcp_opt *opt;
   1851 
   1852   /* prune vendor-encapsulated options based on netid, and look if we're forcing them to be sent */
   1853   for (opt = daemon->dhcp_opts; opt; opt = opt->next)
   1854     if (opt->flags & DHOPT_VENDOR_MATCH)
   1855       {
   1856 	if (!match_netid(opt->netid, netid, 1))
   1857 	  opt->flags &= ~DHOPT_VENDOR_MATCH;
   1858 	else if (opt->flags & DHOPT_FORCE)
   1859 	  force = 1;
   1860       }
   1861   return force;
   1862 }
   1863 
   1864 static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid)
   1865 {
   1866 #define NUM_OPTS 4
   1867 
   1868   unsigned  char *p, *q;
   1869   struct pxe_service *service;
   1870   static struct dhcp_opt *o, *ret;
   1871   int i, j = NUM_OPTS - 1;
   1872 
   1873   /* We pass back references to these, hence they are declared static */
   1874   static unsigned char discovery_control;
   1875   static unsigned char fake_prompt[] = { 0, 'P', 'X', 'E' };
   1876   static struct dhcp_opt *fake_opts = NULL;
   1877 
   1878   /* We are found by broadcast, so disable multicast. It gets switched on again
   1879      if we point to other servers and don't give a unicast address. Note that
   1880      we don't provide our own address for services we are the boot server for because unicast
   1881      discovery is to port 4011 and we don't listen there. If you are using proxy DHCP
   1882      and DHCP relays, the relay will need to forward to the proxy too. */
   1883   discovery_control = 2;
   1884 
   1885   ret = daemon->dhcp_opts;
   1886 
   1887   if (!fake_opts && !(fake_opts = whine_malloc(NUM_OPTS * sizeof(struct dhcp_opt))))
   1888     return ret;
   1889 
   1890   for (i = 0; i < NUM_OPTS; i++)
   1891     {
   1892       fake_opts[i].flags = DHOPT_VENDOR_MATCH;
   1893       fake_opts[i].netid = NULL;
   1894       fake_opts[i].next = i == (NUM_OPTS - 1) ? ret : &fake_opts[i+1];
   1895     }
   1896 
   1897   /* create the data for the PXE_MENU and PXE_SERVERS options. */
   1898   p = (unsigned char *)daemon->dhcp_buff;
   1899   q = (unsigned char *)daemon->dhcp_buff2;
   1900 
   1901   for (i = 0, service = daemon->pxe_services; service; service = service->next)
   1902     if (pxe_arch == service->CSA && match_netid(service->netid, netid, 1))
   1903       {
   1904 	size_t len = strlen(service->menu);
   1905 	/* opt 43 max size is 255. encapsulated option has type and length
   1906 	   bytes, so its max size is 253. */
   1907 	if (p - (unsigned char *)daemon->dhcp_buff + len + 3 < 253)
   1908 	  {
   1909 	    *(p++) = service->type >> 8;
   1910 	    *(p++) = service->type;
   1911 	    *(p++) = len;
   1912 	    memcpy(p, service->menu, len);
   1913 	    p += len;
   1914 	    i++;
   1915 	  }
   1916 	else
   1917 	  {
   1918 	  toobig:
   1919 	    my_syslog(MS_DHCP | LOG_ERR, _("PXE menu too large"));
   1920 	    return daemon->dhcp_opts;
   1921 	  }
   1922 
   1923 	if (!service->basename)
   1924 	  {
   1925 	    if (service->server.s_addr != 0)
   1926 	      {
   1927 		if (q - (unsigned char *)daemon->dhcp_buff2 + 3 + INADDRSZ >= 253)
   1928 		  goto toobig;
   1929 
   1930 		/* Boot service with known address - give it */
   1931 		*(q++) = service->type >> 8;
   1932 		*(q++) = service->type;
   1933 		*(q++) = 1;
   1934 		/* dest misaligned */
   1935 		memcpy(q, &service->server.s_addr, INADDRSZ);
   1936 		q += INADDRSZ;
   1937 	      }
   1938 	    else if (service->type != 0)
   1939 	      /* We're not supplying a server, so let the client multicast.
   1940 		 type zero is "local boot" so no need for M/C on that. */
   1941 	      discovery_control = 0;
   1942 	  }
   1943       }
   1944 
   1945   /* if no prompt, wait forever if there's a choice */
   1946   fake_prompt[0] = (i > 1) ? 255 : 0;
   1947 
   1948   if (i == 0)
   1949     discovery_control = 8; /* no menu - just use use mess->filename */
   1950   else
   1951     {
   1952       ret = &fake_opts[j--];
   1953       ret->len = p - (unsigned char *)daemon->dhcp_buff;
   1954       ret->val = (unsigned char *)daemon->dhcp_buff;
   1955       ret->opt = SUBOPT_PXE_MENU;
   1956 
   1957       if (q - (unsigned char *)daemon->dhcp_buff2 != 0)
   1958 	{
   1959 	  ret = &fake_opts[j--];
   1960 	  ret->len = q - (unsigned char *)daemon->dhcp_buff2;
   1961 	  ret->val = (unsigned char *)daemon->dhcp_buff2;
   1962 	  ret->opt = SUBOPT_PXE_SERVERS;
   1963 	}
   1964     }
   1965 
   1966   for (o = daemon->dhcp_opts; o; o = o->next)
   1967     if ((o->flags & DHOPT_VENDOR_MATCH) && o->opt == SUBOPT_PXE_MENU_PROMPT)
   1968       break;
   1969 
   1970   if (!o)
   1971     {
   1972       ret = &fake_opts[j--];
   1973       ret->len = sizeof(fake_prompt);
   1974       ret->val = fake_prompt;
   1975       ret->opt = SUBOPT_PXE_MENU_PROMPT;
   1976     }
   1977 
   1978   if (discovery_control != 0)
   1979     {
   1980       ret = &fake_opts[j--];
   1981       ret->len = 1;
   1982       ret->opt = SUBOPT_PXE_DISCOVERY;
   1983       ret->val= &discovery_control;
   1984     }
   1985 
   1986   return ret;
   1987 }
   1988 
   1989 static void clear_packet(struct dhcp_packet *mess, unsigned char *end)
   1990 {
   1991   memset(mess->sname, 0, sizeof(mess->sname));
   1992   memset(mess->file, 0, sizeof(mess->file));
   1993   memset(&mess->options[0] + sizeof(u32), 0, end - (&mess->options[0] + sizeof(u32)));
   1994   mess->siaddr.s_addr = 0;
   1995 }
   1996 
   1997 struct dhcp_boot *find_boot(struct dhcp_netid *netid)
   1998 {
   1999   struct dhcp_boot *boot;
   2000 
   2001   /* decide which dhcp-boot option we're using */
   2002   for (boot = daemon->boot_config; boot; boot = boot->next)
   2003     if (match_netid(boot->netid, netid, 0))
   2004       break;
   2005   if (!boot)
   2006     /* No match, look for one without a netid */
   2007     for (boot = daemon->boot_config; boot; boot = boot->next)
   2008       if (match_netid(boot->netid, netid, 1))
   2009 	break;
   2010 
   2011   return boot;
   2012 }
   2013 
   2014 static void do_options(struct dhcp_context *context,
   2015 		       struct dhcp_packet *mess,
   2016 		       unsigned char *end,
   2017 		       unsigned char *req_options,
   2018 		       char *hostname,
   2019 		       char *domain, char *config_domain,
   2020 		       struct dhcp_netid *netid,
   2021 		       struct in_addr subnet_addr,
   2022 		       unsigned char fqdn_flags,
   2023 		       int null_term, int pxe_arch,
   2024 		       unsigned char *uuid)
   2025 {
   2026   struct dhcp_opt *opt, *config_opts = daemon->dhcp_opts;
   2027   struct dhcp_boot *boot;
   2028   unsigned char *p;
   2029   int i, len, force_encap = 0;
   2030   unsigned char f0 = 0, s0 = 0;
   2031   int done_file = 0, done_server = 0;
   2032 
   2033   if (config_domain && (!domain || !hostname_isequal(domain, config_domain)))
   2034     my_syslog(MS_DHCP | LOG_WARNING, _("Ignoring domain %s for DHCP host name %s"), config_domain, hostname);
   2035 
   2036   /* logging */
   2037   if ((daemon->options & OPT_LOG_OPTS) && req_options)
   2038     {
   2039       char *q = daemon->namebuff;
   2040       for (i = 0; req_options[i] != OPTION_END; i++)
   2041 	{
   2042 	  char *s = option_string(req_options[i], NULL, NULL);
   2043 	  q += snprintf(q, MAXDNAME - (q - daemon->namebuff),
   2044 			"%d%s%s%s",
   2045 			req_options[i],
   2046 			s ? ":" : "",
   2047 			s ? s : "",
   2048 			req_options[i+1] == OPTION_END ? "" : ", ");
   2049 	  if (req_options[i+1] == OPTION_END || (q - daemon->namebuff) > 40)
   2050 	    {
   2051 	      q = daemon->namebuff;
   2052 	      my_syslog(MS_DHCP | LOG_INFO, _("%u requested options: %s"), ntohl(mess->xid), daemon->namebuff);
   2053 	    }
   2054 	}
   2055     }
   2056 
   2057   if (context)
   2058     mess->siaddr = context->local;
   2059 
   2060   /* See if we can send the boot stuff as options.
   2061      To do this we need a requested option list, BOOTP
   2062      and very old DHCP clients won't have this, we also
   2063      provide an manual option to disable it.
   2064      Some PXE ROMs have bugs (surprise!) and need zero-terminated
   2065      names, so we always send those.  */
   2066   if ((boot = find_boot(netid)))
   2067     {
   2068       if (boot->sname)
   2069 	{
   2070 	  if (!(daemon->options & OPT_NO_OVERRIDE) &&
   2071 	      req_options &&
   2072 	      in_list(req_options, OPTION_SNAME))
   2073 	    option_put_string(mess, end, OPTION_SNAME, boot->sname, 1);
   2074 	  else
   2075 	    strncpy((char *)mess->sname, boot->sname, sizeof(mess->sname)-1);
   2076 	}
   2077 
   2078       if (boot->file)
   2079 	{
   2080 	  if (!(daemon->options & OPT_NO_OVERRIDE) &&
   2081 	      req_options &&
   2082 	      in_list(req_options, OPTION_FILENAME))
   2083 	    option_put_string(mess, end, OPTION_FILENAME, boot->file, 1);
   2084 	  else
   2085 	    strncpy((char *)mess->file, boot->file, sizeof(mess->file)-1);
   2086 	}
   2087 
   2088       if (boot->next_server.s_addr)
   2089 	mess->siaddr = boot->next_server;
   2090     }
   2091   else
   2092     /* Use the values of the relevant options if no dhcp-boot given and
   2093        they're not explicitly asked for as options. OPTION_END is used
   2094        as an internal way to specify siaddr without using dhcp-boot, for use in
   2095        dhcp-optsfile. */
   2096     {
   2097       if ((!req_options || !in_list(req_options, OPTION_FILENAME)) && mess->file[0] == 0 &&
   2098 	  (opt = option_find2(netid, config_opts, OPTION_FILENAME)) && !(opt->flags & DHOPT_FORCE))
   2099 	{
   2100 	  strncpy((char *)mess->file, (char *)opt->val, sizeof(mess->file)-1);
   2101 	  done_file = 1;
   2102 	}
   2103 
   2104       if ((!req_options || !in_list(req_options, OPTION_SNAME)) &&
   2105 	  (opt = option_find2(netid, config_opts, OPTION_SNAME)) && !(opt->flags & DHOPT_FORCE))
   2106 	{
   2107 	  strncpy((char *)mess->sname, (char *)opt->val, sizeof(mess->sname)-1);
   2108 	  done_server = 1;
   2109 	}
   2110 
   2111       if ((opt = option_find2(netid, config_opts, OPTION_END)))
   2112 	mess->siaddr.s_addr = ((struct in_addr *)opt->val)->s_addr;
   2113     }
   2114 
   2115   /* We don't want to do option-overload for BOOTP, so make the file and sname
   2116      fields look like they are in use, even when they aren't. This gets restored
   2117      at the end of this function. */
   2118 
   2119   if (!req_options || (daemon->options & OPT_NO_OVERRIDE))
   2120     {
   2121       f0 = mess->file[0];
   2122       mess->file[0] = 1;
   2123       s0 = mess->sname[0];
   2124       mess->sname[0] = 1;
   2125     }
   2126 
   2127   /* At this point, if mess->sname or mess->file are zeroed, they are available
   2128      for option overload, reserve space for the overload option. */
   2129   if (mess->file[0] == 0 || mess->sname[0] == 0)
   2130     end -= 3;
   2131 
   2132   /* rfc3011 says this doesn't need to be in the requested options list. */
   2133   if (subnet_addr.s_addr)
   2134     option_put(mess, end, OPTION_SUBNET_SELECT, INADDRSZ, ntohl(subnet_addr.s_addr));
   2135 
   2136   /* replies to DHCPINFORM may not have a valid context */
   2137   if (context)
   2138     {
   2139       if (!option_find2(netid, config_opts, OPTION_NETMASK))
   2140 	option_put(mess, end, OPTION_NETMASK, INADDRSZ, ntohl(context->netmask.s_addr));
   2141 
   2142       /* May not have a "guessed" broadcast address if we got no packets via a relay
   2143 	 from this net yet (ie just unicast renewals after a restart */
   2144       if (context->broadcast.s_addr &&
   2145 	  !option_find2(netid, config_opts, OPTION_BROADCAST))
   2146 	option_put(mess, end, OPTION_BROADCAST, INADDRSZ, ntohl(context->broadcast.s_addr));
   2147 
   2148       /* Same comments as broadcast apply, and also may not be able to get a sensible
   2149 	 default when using subnet select.  User must configure by steam in that case. */
   2150       if (context->router.s_addr &&
   2151 	  in_list(req_options, OPTION_ROUTER) &&
   2152 	  !option_find2(netid, config_opts, OPTION_ROUTER))
   2153 	option_put(mess, end, OPTION_ROUTER, INADDRSZ, ntohl(context->router.s_addr));
   2154 
   2155       if (in_list(req_options, OPTION_DNSSERVER) &&
   2156 	  !option_find2(netid, config_opts, OPTION_DNSSERVER))
   2157 	option_put(mess, end, OPTION_DNSSERVER, INADDRSZ, ntohl(context->local.s_addr));
   2158     }
   2159 
   2160   if (domain && in_list(req_options, OPTION_DOMAINNAME) &&
   2161       !option_find2(netid, config_opts, OPTION_DOMAINNAME))
   2162     option_put_string(mess, end, OPTION_DOMAINNAME, domain, null_term);
   2163 
   2164   /* Note that we ignore attempts to set the fqdn using --dhc-option=81,<name> */
   2165   if (hostname)
   2166     {
   2167       if (in_list(req_options, OPTION_HOSTNAME) &&
   2168 	  !option_find2(netid, config_opts, OPTION_HOSTNAME))
   2169 	option_put_string(mess, end, OPTION_HOSTNAME, hostname, null_term);
   2170 
   2171       if (fqdn_flags != 0)
   2172 	{
   2173 	  len = strlen(hostname) + 3;
   2174 
   2175 	  if (fqdn_flags & 0x04)
   2176 	    len += 2;
   2177 	  else if (null_term)
   2178 	    len++;
   2179 
   2180 	  if (domain)
   2181 	    len += strlen(domain) + 1;
   2182 
   2183 	  if ((p = free_space(mess, end, OPTION_CLIENT_FQDN, len)))
   2184 	    {
   2185 	      *(p++) = fqdn_flags;
   2186 	      *(p++) = 255;
   2187 	      *(p++) = 255;
   2188 
   2189 	      if (fqdn_flags & 0x04)
   2190 		{
   2191 		  p = do_rfc1035_name(p, hostname);
   2192 		  if (domain)
   2193 		    p = do_rfc1035_name(p, domain);
   2194 		  *p++ = 0;
   2195 		}
   2196 	      else
   2197 		{
   2198 		  memcpy(p, hostname, strlen(hostname));
   2199 		  p += strlen(hostname);
   2200 		  if (domain)
   2201 		    {
   2202 		      *(p++) = '.';
   2203 		      memcpy(p, domain, strlen(domain));
   2204 		      p += strlen(domain);
   2205 		    }
   2206 		  if (null_term)
   2207 		    *(p++) = 0;
   2208 		}
   2209 	    }
   2210 	}
   2211     }
   2212 
   2213   for (opt = config_opts; opt; opt = opt->next)
   2214     {
   2215       int optno = opt->opt;
   2216 
   2217       /* was it asked for, or are we sending it anyway? */
   2218       if (!(opt->flags & DHOPT_FORCE) && !in_list(req_options, optno))
   2219 	continue;
   2220 
   2221       /* prohibit some used-internally options */
   2222       if (optno == OPTION_CLIENT_FQDN ||
   2223 	  optno == OPTION_MAXMESSAGE ||
   2224 	  optno == OPTION_OVERLOAD ||
   2225 	  optno == OPTION_PAD ||
   2226 	  optno == OPTION_END)
   2227 	continue;
   2228 
   2229       if (optno == OPTION_SNAME && done_server)
   2230 	continue;
   2231 
   2232       if (optno == OPTION_FILENAME && done_file)
   2233 	continue;
   2234 
   2235       /* netids match and not encapsulated? */
   2236       if (opt != option_find2(netid, config_opts, optno))
   2237 	continue;
   2238 
   2239       /* For the options we have default values on
   2240 	 dhc-option=<optionno> means "don't include this option"
   2241 	 not "include a zero-length option" */
   2242       if (opt->len == 0 &&
   2243 	  (optno == OPTION_NETMASK ||
   2244 	   optno == OPTION_BROADCAST ||
   2245 	   optno == OPTION_ROUTER ||
   2246 	   optno == OPTION_DNSSERVER ||
   2247 	   optno == OPTION_DOMAINNAME ||
   2248 	   optno == OPTION_HOSTNAME))
   2249 	continue;
   2250 
   2251       /* vendor-class comes from elsewhere for PXE */
   2252       if (pxe_arch != -1 && optno == OPTION_VENDOR_ID)
   2253 	continue;
   2254 
   2255       /* always force null-term for filename and servername - buggy PXE again. */
   2256       len = do_opt(opt, NULL, context,
   2257 		   (optno == OPTION_SNAME || optno == OPTION_FILENAME) ? 1 : null_term);
   2258 
   2259       if ((p = free_space(mess, end, optno, len)))
   2260 	{
   2261 	  do_opt(opt, p, context,
   2262 		 (optno == OPTION_SNAME || optno == OPTION_FILENAME) ? 1 : null_term);
   2263 
   2264 	  /* If we send a vendor-id, revisit which vendor-ops we consider
   2265 	     it appropriate to send. */
   2266 	  if (optno == OPTION_VENDOR_ID)
   2267 	    match_vendor_opts(p - 2, config_opts);
   2268 	}
   2269     }
   2270 
   2271   /* Now send options to be encapsulated in arbitrary options,
   2272      eg dhcp-option=encap:172,17,.......
   2273      The may be more that one "outer" to do, so group
   2274      all the options which match each outer in turn. */
   2275   for (opt = config_opts; opt; opt = opt->next)
   2276     opt->flags &= ~DHOPT_ENCAP_DONE;
   2277 
   2278   for (opt = config_opts; opt; opt = opt->next)
   2279     if ((opt->flags & (DHOPT_ENCAPSULATE | DHOPT_ENCAP_DONE)) ==  DHOPT_ENCAPSULATE)
   2280       {
   2281 	struct dhcp_opt *o;
   2282 	int found = 0;
   2283 
   2284 	for (o = config_opts; o; o = o->next)
   2285 	  {
   2286 	    o->flags &= ~DHOPT_ENCAP_MATCH;
   2287 	    if ((o->flags & DHOPT_ENCAPSULATE) && opt->u.encap == o->u.encap)
   2288 	      {
   2289 		o->flags |= DHOPT_ENCAP_DONE;
   2290 		if (match_netid(o->netid, netid, 1) &&
   2291 		    (o->flags & DHOPT_FORCE || in_list(req_options, o->u.encap)))
   2292 		  {
   2293 		    o->flags |= DHOPT_ENCAP_MATCH;
   2294 		    found = 1;
   2295 		  }
   2296 	      }
   2297 	  }
   2298 
   2299 	if (found)
   2300 	  do_encap_opts(config_opts, opt->u.encap, DHOPT_ENCAP_MATCH, mess, end, null_term);
   2301       }
   2302 
   2303   /* Must precede pxe_opts, since it overwrites req_options */
   2304   force_encap = prune_vendor_opts(netid);
   2305   if (in_list(req_options, OPTION_VENDOR_CLASS_OPT))
   2306     force_encap = 1;
   2307 
   2308   if (pxe_arch != -1)
   2309     {
   2310       pxe_misc(mess, end, uuid);
   2311       config_opts = pxe_opts(pxe_arch, netid);
   2312     }
   2313 
   2314   if (force_encap)
   2315     do_encap_opts(config_opts, OPTION_VENDOR_CLASS_OPT, DHOPT_VENDOR_MATCH, mess, end, null_term);
   2316 
   2317    /* restore BOOTP anti-overload hack */
   2318   if (!req_options || (daemon->options & OPT_NO_OVERRIDE))
   2319     {
   2320       mess->file[0] = f0;
   2321       mess->sname[0] = s0;
   2322     }
   2323 }
   2324 
   2325 #endif
   2326