File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dnsmasq / src / rfc3315.c
Revision 1.1.1.5 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Sep 27 11:02:07 2023 UTC (9 months, 1 week ago) by misho
Branches: elwix, dnsmasq, MAIN
CVS tags: v8_2p1, HEAD
Version 8.2p1

    1: /* dnsmasq is Copyright (c) 2000-2022 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: 
   18: #include "dnsmasq.h"
   19: 
   20: #ifdef HAVE_DHCP6
   21: 
   22: struct state {
   23:   unsigned char *clid;
   24:   int clid_len, ia_type, interface, hostname_auth, lease_allocate;
   25:   char *client_hostname, *hostname, *domain, *send_domain;
   26:   struct dhcp_context *context;
   27:   struct in6_addr *link_address, *fallback, *ll_addr, *ula_addr;
   28:   unsigned int xid, fqdn_flags, iaid;
   29:   char *iface_name;
   30:   void *packet_options, *end;
   31:   struct dhcp_netid *tags, *context_tags;
   32:   unsigned char mac[DHCP_CHADDR_MAX];
   33:   unsigned int mac_len, mac_type;
   34: };
   35: 
   36: static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t sz, 
   37: 			     struct in6_addr *client_addr, int is_unicast, time_t now);
   38: static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbuff, size_t sz, int is_unicast, time_t now);
   39: static void log6_opts(int nest, unsigned int xid, void *start_opts, void *end_opts);
   40: static void log6_packet(struct state *state, char *type, struct in6_addr *addr, char *string);
   41: static void log6_quiet(struct state *state, char *type, struct in6_addr *addr, char *string);
   42: static void *opt6_find (void *opts, void *end, unsigned int search, unsigned int minsize);
   43: static void *opt6_next(void *opts, void *end);
   44: static unsigned int opt6_uint(unsigned char *opt, int offset, int size);
   45: static void get_context_tag(struct state *state, struct dhcp_context *context);
   46: static int check_ia(struct state *state, void *opt, void **endp, void **ia_option);
   47: static int build_ia(struct state *state, int *t1cntr);
   48: static void end_ia(int t1cntr, unsigned int min_time, int do_fuzz);
   49: static void mark_context_used(struct state *state, struct in6_addr *addr);
   50: static void mark_config_used(struct dhcp_context *context, struct in6_addr *addr);
   51: static int check_address(struct state *state, struct in6_addr *addr);
   52: static int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state, time_t now);
   53: static struct addrlist *config_implies(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr);
   54: static void add_address(struct state *state, struct dhcp_context *context, unsigned int lease_time, void *ia_option, 
   55: 			unsigned int *min_time, struct in6_addr *addr, time_t now);
   56: static void update_leases(struct state *state, struct dhcp_context *context, struct in6_addr *addr, unsigned int lease_time, time_t now);
   57: static int add_local_addrs(struct dhcp_context *context);
   58: static struct dhcp_netid *add_options(struct state *state, int do_refresh);
   59: static void calculate_times(struct dhcp_context *context, unsigned int *min_time, unsigned int *valid_timep, 
   60: 			    unsigned int *preferred_timep, unsigned int lease_time);
   61: 
   62: #define opt6_len(opt) ((int)(opt6_uint(opt, -2, 2)))
   63: #define opt6_type(opt) (opt6_uint(opt, -4, 2))
   64: #define opt6_ptr(opt, i) ((void *)&(((unsigned char *)(opt))[4+(i)]))
   65: 
   66: #define opt6_user_vendor_ptr(opt, i) ((void *)&(((unsigned char *)(opt))[2+(i)]))
   67: #define opt6_user_vendor_len(opt) ((int)(opt6_uint(opt, -4, 2)))
   68: #define opt6_user_vendor_next(opt, end) (opt6_next(((void *) opt) - 2, end))
   69:  
   70: 
   71: unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name,
   72: 			   struct in6_addr *fallback,  struct in6_addr *ll_addr, struct in6_addr *ula_addr,
   73: 			   size_t sz, struct in6_addr *client_addr, time_t now)
   74: {
   75:   struct dhcp_vendor *vendor;
   76:   int msg_type;
   77:   struct state state;
   78:   
   79:   if (sz <= 4)
   80:     return 0;
   81:   
   82:   msg_type = *((unsigned char *)daemon->dhcp_packet.iov_base);
   83:   
   84:   /* Mark these so we only match each at most once, to avoid tangled linked lists */
   85:   for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
   86:     vendor->netid.next = &vendor->netid;
   87:   
   88:   reset_counter();
   89:   state.context = context;
   90:   state.interface = interface;
   91:   state.iface_name = iface_name;
   92:   state.fallback = fallback;
   93:   state.ll_addr = ll_addr;
   94:   state.ula_addr = ula_addr;
   95:   state.mac_len = 0;
   96:   state.tags = NULL;
   97:   state.link_address = NULL;
   98: 
   99:   if (dhcp6_maybe_relay(&state, daemon->dhcp_packet.iov_base, sz, client_addr, 
  100: 			IN6_IS_ADDR_MULTICAST(client_addr), now))
  101:     return msg_type == DHCP6RELAYFORW ? DHCPV6_SERVER_PORT : DHCPV6_CLIENT_PORT;
  102: 
  103:   return 0;
  104: }
  105: 
  106: /* This cost me blood to write, it will probably cost you blood to understand - srk. */
  107: static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t sz, 
  108: 			     struct in6_addr *client_addr, int is_unicast, time_t now)
  109: {
  110:   void *end = inbuff + sz;
  111:   void *opts = inbuff + 34;
  112:   int msg_type = *inbuff;
  113:   unsigned char *outmsgtypep;
  114:   void *opt;
  115:   struct dhcp_vendor *vendor;
  116: 
  117:   /* if not an encapsulated relayed message, just do the stuff */
  118:   if (msg_type != DHCP6RELAYFORW)
  119:     {
  120:       /* if link_address != NULL if points to the link address field of the 
  121: 	 innermost nested RELAYFORW message, which is where we find the
  122: 	 address of the network on which we can allocate an address.
  123: 	 Recalculate the available contexts using that information. 
  124: 
  125:       link_address == NULL means there's no relay in use, so we try and find the client's 
  126:       MAC address from the local ND cache. */
  127:       
  128:       if (!state->link_address)
  129: 	get_client_mac(client_addr, state->interface, state->mac, &state->mac_len, &state->mac_type, now);
  130:       else
  131: 	{
  132: 	  struct dhcp_context *c;
  133: 	  struct shared_network *share = NULL;
  134: 	  state->context = NULL;
  135: 
  136: 	  if (!IN6_IS_ADDR_LOOPBACK(state->link_address) &&
  137: 	      !IN6_IS_ADDR_LINKLOCAL(state->link_address) &&
  138: 	      !IN6_IS_ADDR_MULTICAST(state->link_address))
  139: 	    for (c = daemon->dhcp6; c; c = c->next)
  140: 	      {
  141: 		for (share = daemon->shared_networks; share; share = share->next)
  142: 		  {
  143: 		    if (share->shared_addr.s_addr != 0)
  144: 		      continue;
  145: 		    
  146: 		    if (share->if_index != 0 ||
  147: 			!IN6_ARE_ADDR_EQUAL(state->link_address, &share->match_addr6))
  148: 		      continue;
  149: 		    
  150: 		    if ((c->flags & CONTEXT_DHCP) &&
  151: 			!(c->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
  152: 			is_same_net6(&share->shared_addr6, &c->start6, c->prefix) &&
  153: 			is_same_net6(&share->shared_addr6, &c->end6, c->prefix))
  154: 		      break;
  155: 		  }
  156: 		
  157: 		if (share ||
  158: 		    ((c->flags & CONTEXT_DHCP) &&
  159: 		     !(c->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
  160: 		     is_same_net6(state->link_address, &c->start6, c->prefix) &&
  161: 		     is_same_net6(state->link_address, &c->end6, c->prefix)))
  162: 		  {
  163: 		    c->preferred = c->valid = 0xffffffff;
  164: 		    c->current = state->context;
  165: 		    state->context = c;
  166: 		  }
  167: 	      }
  168: 	  
  169: 	  if (!state->context)
  170: 	    {
  171: 	      inet_ntop(AF_INET6, state->link_address, daemon->addrbuff, ADDRSTRLEN); 
  172: 	      my_syslog(MS_DHCP | LOG_WARNING, 
  173: 			_("no address range available for DHCPv6 request from relay at %s"),
  174: 			daemon->addrbuff);
  175: 	      return 0;
  176: 	    }
  177: 	}
  178: 	  
  179:       if (!state->context)
  180: 	{
  181: 	  my_syslog(MS_DHCP | LOG_WARNING, 
  182: 		    _("no address range available for DHCPv6 request via %s"), state->iface_name);
  183: 	  return 0;
  184: 	}
  185: 
  186:       return dhcp6_no_relay(state, msg_type, inbuff, sz, is_unicast, now);
  187:     }
  188: 
  189:   /* must have at least msg_type+hopcount+link_address+peer_address+minimal size option
  190:      which is               1   +    1   +    16      +     16     + 2 + 2 = 38 */
  191:   if (sz < 38)
  192:     return 0;
  193:   
  194:   /* copy header stuff into reply message and set type to reply */
  195:   if (!(outmsgtypep = put_opt6(inbuff, 34)))
  196:     return 0;
  197:   *outmsgtypep = DHCP6RELAYREPL;
  198: 
  199:   /* look for relay options and set tags if found. */
  200:   for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
  201:     {
  202:       int mopt;
  203:       
  204:       if (vendor->match_type == MATCH_SUBSCRIBER)
  205: 	mopt = OPTION6_SUBSCRIBER_ID;
  206:       else if (vendor->match_type == MATCH_REMOTE)
  207: 	mopt = OPTION6_REMOTE_ID; 
  208:       else
  209: 	continue;
  210: 
  211:       if ((opt = opt6_find(opts, end, mopt, 1)) &&
  212: 	  vendor->len == opt6_len(opt) &&
  213: 	  memcmp(vendor->data, opt6_ptr(opt, 0), vendor->len) == 0 &&
  214: 	  vendor->netid.next != &vendor->netid)
  215: 	{
  216: 	  vendor->netid.next = state->tags;
  217: 	  state->tags = &vendor->netid;
  218: 	  break;
  219: 	}
  220:     }
  221:   
  222:   /* RFC-6939 */
  223:   if ((opt = opt6_find(opts, end, OPTION6_CLIENT_MAC, 3)))
  224:     {
  225:       if (opt6_len(opt) - 2 > DHCP_CHADDR_MAX) {
  226:         return 0;
  227:       }
  228:       state->mac_type = opt6_uint(opt, 0, 2);
  229:       state->mac_len = opt6_len(opt) - 2;
  230:       memcpy(&state->mac[0], opt6_ptr(opt, 2), state->mac_len);
  231:     }
  232:   
  233:   for (opt = opts; opt; opt = opt6_next(opt, end))
  234:     {
  235:       if (opt6_ptr(opt, 0) + opt6_len(opt) > end) 
  236:         return 0;
  237:      
  238:       /* Don't copy MAC address into reply. */
  239:       if (opt6_type(opt) != OPTION6_CLIENT_MAC)
  240: 	{
  241: 	  int o = new_opt6(opt6_type(opt));
  242: 	  if (opt6_type(opt) == OPTION6_RELAY_MSG)
  243: 	    {
  244: 	      struct in6_addr align;
  245: 	      /* the packet data is unaligned, copy to aligned storage */
  246: 	      memcpy(&align, inbuff + 2, IN6ADDRSZ); 
  247: 	      state->link_address = &align;
  248: 	      /* zero is_unicast since that is now known to refer to the 
  249: 		 relayed packet, not the original sent by the client */
  250: 	      if (!dhcp6_maybe_relay(state, opt6_ptr(opt, 0), opt6_len(opt), client_addr, 0, now))
  251: 		return 0;
  252: 	    }
  253: 	  else
  254: 	    put_opt6(opt6_ptr(opt, 0), opt6_len(opt));
  255: 	  end_opt6(o);
  256: 	}
  257:     }
  258:   
  259:   return 1;
  260: }
  261: 
  262: static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbuff, size_t sz, int is_unicast, time_t now)
  263: {
  264:   void *opt;
  265:   int i, o, o1, start_opts, start_msg;
  266:   struct dhcp_opt *opt_cfg;
  267:   struct dhcp_netid *tagif;
  268:   struct dhcp_config *config = NULL;
  269:   struct dhcp_netid known_id, iface_id, v6_id;
  270:   unsigned char outmsgtype;
  271:   struct dhcp_vendor *vendor;
  272:   struct dhcp_context *context_tmp;
  273:   struct dhcp_mac *mac_opt;
  274:   unsigned int ignore = 0;
  275: 
  276:   state->packet_options = inbuff + 4;
  277:   state->end = inbuff + sz;
  278:   state->clid = NULL;
  279:   state->clid_len = 0;
  280:   state->lease_allocate = 0;
  281:   state->context_tags = NULL;
  282:   state->domain = NULL;
  283:   state->send_domain = NULL;
  284:   state->hostname_auth = 0;
  285:   state->hostname = NULL;
  286:   state->client_hostname = NULL;
  287:   state->fqdn_flags = 0x01; /* default to send if we receive no FQDN option */
  288: 
  289:   /* set tag with name == interface */
  290:   iface_id.net = state->iface_name;
  291:   iface_id.next = state->tags;
  292:   state->tags = &iface_id; 
  293: 
  294:   /* set tag "dhcpv6" */
  295:   v6_id.net = "dhcpv6";
  296:   v6_id.next = state->tags;
  297:   state->tags = &v6_id;
  298: 
  299:   start_msg = save_counter(-1);
  300:   /* copy over transaction-id */
  301:   if (!put_opt6(inbuff, 4))
  302:     return 0;
  303:   start_opts = save_counter(-1);
  304:   state->xid = inbuff[3] | inbuff[2] << 8 | inbuff[1] << 16;
  305:     
  306:   /* We're going to be linking tags from all context we use. 
  307:      mark them as unused so we don't link one twice and break the list */
  308:   for (context_tmp = state->context; context_tmp; context_tmp = context_tmp->current)
  309:     {
  310:       context_tmp->netid.next = &context_tmp->netid;
  311: 
  312:       if (option_bool(OPT_LOG_OPTS))
  313: 	{
  314: 	   inet_ntop(AF_INET6, &context_tmp->start6, daemon->dhcp_buff, ADDRSTRLEN); 
  315: 	   inet_ntop(AF_INET6, &context_tmp->end6, daemon->dhcp_buff2, ADDRSTRLEN); 
  316: 	   if (context_tmp->flags & (CONTEXT_STATIC))
  317: 	     my_syslog(MS_DHCP | LOG_INFO, _("%u available DHCPv6 subnet: %s/%d"),
  318: 		       state->xid, daemon->dhcp_buff, context_tmp->prefix);
  319: 	   else
  320: 	     my_syslog(MS_DHCP | LOG_INFO, _("%u available DHCP range: %s -- %s"), 
  321: 		       state->xid, daemon->dhcp_buff, daemon->dhcp_buff2);
  322: 	}
  323:     }
  324: 
  325:   if ((opt = opt6_find(state->packet_options, state->end, OPTION6_CLIENT_ID, 1)))
  326:     {
  327:       state->clid = opt6_ptr(opt, 0);
  328:       state->clid_len = opt6_len(opt);
  329:       o = new_opt6(OPTION6_CLIENT_ID);
  330:       put_opt6(state->clid, state->clid_len);
  331:       end_opt6(o);
  332:     }
  333:   else if (msg_type != DHCP6IREQ)
  334:     return 0;
  335: 
  336:   /* server-id must match except for SOLICIT, CONFIRM and REBIND messages */
  337:   if (msg_type != DHCP6SOLICIT && msg_type != DHCP6CONFIRM && msg_type != DHCP6IREQ && msg_type != DHCP6REBIND &&
  338:       (!(opt = opt6_find(state->packet_options, state->end, OPTION6_SERVER_ID, 1)) ||
  339:        opt6_len(opt) != daemon->duid_len ||
  340:        memcmp(opt6_ptr(opt, 0), daemon->duid, daemon->duid_len) != 0))
  341:     return 0;
  342:   
  343:   o = new_opt6(OPTION6_SERVER_ID);
  344:   put_opt6(daemon->duid, daemon->duid_len);
  345:   end_opt6(o);
  346: 
  347:   if (is_unicast &&
  348:       (msg_type == DHCP6REQUEST || msg_type == DHCP6RENEW || msg_type == DHCP6RELEASE || msg_type == DHCP6DECLINE))
  349:     
  350:     {  
  351:       outmsgtype = DHCP6REPLY;
  352:       o1 = new_opt6(OPTION6_STATUS_CODE);
  353:       put_opt6_short(DHCP6USEMULTI);
  354:       put_opt6_string("Use multicast");
  355:       end_opt6(o1);
  356:       goto done;
  357:     }
  358: 
  359:   /* match vendor and user class options */
  360:   for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
  361:     {
  362:       int mopt;
  363:       
  364:       if (vendor->match_type == MATCH_VENDOR)
  365: 	mopt = OPTION6_VENDOR_CLASS;
  366:       else if (vendor->match_type == MATCH_USER)
  367: 	mopt = OPTION6_USER_CLASS; 
  368:       else
  369: 	continue;
  370: 
  371:       if ((opt = opt6_find(state->packet_options, state->end, mopt, 2)))
  372: 	{
  373: 	  void *enc_opt, *enc_end = opt6_ptr(opt, opt6_len(opt));
  374: 	  int offset = 0;
  375: 	  
  376: 	  if (mopt == OPTION6_VENDOR_CLASS)
  377: 	    {
  378: 	      if (opt6_len(opt) < 4)
  379: 		continue;
  380: 	      
  381: 	      if (vendor->enterprise != opt6_uint(opt, 0, 4))
  382: 		continue;
  383: 	    
  384: 	      offset = 4;
  385: 	    }
  386:  
  387: 	  /* Note that format if user/vendor classes is different to DHCP options - no option types. */
  388: 	  for (enc_opt = opt6_ptr(opt, offset); enc_opt; enc_opt = opt6_user_vendor_next(enc_opt, enc_end))
  389: 	    for (i = 0; i <= (opt6_user_vendor_len(enc_opt) - vendor->len); i++)
  390: 	      if (memcmp(vendor->data, opt6_user_vendor_ptr(enc_opt, i), vendor->len) == 0)
  391: 		{
  392: 		  vendor->netid.next = state->tags;
  393: 		  state->tags = &vendor->netid;
  394: 		  break;
  395: 		}
  396: 	}
  397:     }
  398: 
  399:   if (option_bool(OPT_LOG_OPTS) && (opt = opt6_find(state->packet_options, state->end, OPTION6_VENDOR_CLASS, 4)))
  400:     my_syslog(MS_DHCP | LOG_INFO, _("%u vendor class: %u"), state->xid, opt6_uint(opt, 0, 4));
  401:   
  402:   /* dhcp-match. If we have hex-and-wildcards, look for a left-anchored match.
  403:      Otherwise assume the option is an array, and look for a matching element. 
  404:      If no data given, existence of the option is enough. This code handles 
  405:      V-I opts too. */
  406:   for (opt_cfg = daemon->dhcp_match6; opt_cfg; opt_cfg = opt_cfg->next)
  407:     {
  408:       int match = 0;
  409:       
  410:       if (opt_cfg->flags & DHOPT_RFC3925)
  411: 	{
  412: 	  for (opt = opt6_find(state->packet_options, state->end, OPTION6_VENDOR_OPTS, 4);
  413: 	       opt;
  414: 	       opt = opt6_find(opt6_next(opt, state->end), state->end, OPTION6_VENDOR_OPTS, 4))
  415: 	    {
  416: 	      void *vopt;
  417: 	      void *vend = opt6_ptr(opt, opt6_len(opt));
  418: 	      
  419: 	      for (vopt = opt6_find(opt6_ptr(opt, 4), vend, opt_cfg->opt, 0);
  420: 		   vopt;
  421: 		   vopt = opt6_find(opt6_next(vopt, vend), vend, opt_cfg->opt, 0))
  422: 		if ((match = match_bytes(opt_cfg, opt6_ptr(vopt, 0), opt6_len(vopt))))
  423: 		  break;
  424: 	    }
  425: 	  if (match)
  426: 	    break;
  427: 	}
  428:       else
  429: 	{
  430: 	  if (!(opt = opt6_find(state->packet_options, state->end, opt_cfg->opt, 1)))
  431: 	    continue;
  432: 	  
  433: 	  match = match_bytes(opt_cfg, opt6_ptr(opt, 0), opt6_len(opt));
  434: 	} 
  435:   
  436:       if (match)
  437: 	{
  438: 	  opt_cfg->netid->next = state->tags;
  439: 	  state->tags = opt_cfg->netid;
  440: 	}
  441:     }
  442: 
  443:   if (state->mac_len != 0)
  444:     {
  445:       if (option_bool(OPT_LOG_OPTS))
  446: 	{
  447: 	  print_mac(daemon->dhcp_buff, state->mac, state->mac_len);
  448: 	  my_syslog(MS_DHCP | LOG_INFO, _("%u client MAC address: %s"), state->xid, daemon->dhcp_buff);
  449: 	}
  450: 
  451:       for (mac_opt = daemon->dhcp_macs; mac_opt; mac_opt = mac_opt->next)
  452: 	if ((unsigned)mac_opt->hwaddr_len == state->mac_len &&
  453: 	    ((unsigned)mac_opt->hwaddr_type == state->mac_type || mac_opt->hwaddr_type == 0) &&
  454: 	    memcmp_masked(mac_opt->hwaddr, state->mac, state->mac_len, mac_opt->mask))
  455: 	  {
  456: 	    mac_opt->netid.next = state->tags;
  457: 	    state->tags = &mac_opt->netid;
  458: 	  }
  459:     }
  460:   
  461:   if ((opt = opt6_find(state->packet_options, state->end, OPTION6_FQDN, 1)))
  462:     {
  463:       /* RFC4704 refers */
  464:        int len = opt6_len(opt) - 1;
  465:        
  466:        state->fqdn_flags = opt6_uint(opt, 0, 1);
  467:        
  468:        /* Always force update, since the client has no way to do it itself. */
  469:        if (!option_bool(OPT_FQDN_UPDATE) && !(state->fqdn_flags & 0x01))
  470: 	 state->fqdn_flags |= 0x03;
  471:  
  472:        state->fqdn_flags &= ~0x04;
  473: 
  474:        if (len != 0 && len < 255)
  475: 	 {
  476: 	   unsigned char *pp, *op = opt6_ptr(opt, 1);
  477: 	   char *pq = daemon->dhcp_buff;
  478: 	   
  479: 	   pp = op;
  480: 	   while (*op != 0 && ((op + (*op)) - pp) < len)
  481: 	     {
  482: 	       memcpy(pq, op+1, *op);
  483: 	       pq += *op;
  484: 	       op += (*op)+1;
  485: 	       *(pq++) = '.';
  486: 	     }
  487: 	   
  488: 	   if (pq != daemon->dhcp_buff)
  489: 	     pq--;
  490: 	   *pq = 0;
  491: 	   
  492: 	   if (legal_hostname(daemon->dhcp_buff))
  493: 	     {
  494: 	       struct dhcp_match_name *m;
  495: 	       size_t nl = strlen(daemon->dhcp_buff);
  496: 	       
  497: 	       state->client_hostname = daemon->dhcp_buff;
  498: 	       
  499: 	       if (option_bool(OPT_LOG_OPTS))
  500: 		 my_syslog(MS_DHCP | LOG_INFO, _("%u client provides name: %s"), state->xid, state->client_hostname);
  501: 	       
  502: 	       for (m = daemon->dhcp_name_match; m; m = m->next)
  503: 		 {
  504: 		   size_t ml = strlen(m->name);
  505: 		   char save = 0;
  506: 		   
  507: 		   if (nl < ml)
  508: 		     continue;
  509: 		   if (nl > ml)
  510: 		     {
  511: 		       save = state->client_hostname[ml];
  512: 		       state->client_hostname[ml] = 0;
  513: 		     }
  514: 		   
  515: 		   if (hostname_isequal(state->client_hostname, m->name) &&
  516: 		       (save == 0 || m->wildcard))
  517: 		     {
  518: 		       m->netid->next = state->tags;
  519: 		       state->tags = m->netid;
  520: 		     }
  521: 		   
  522: 		   if (save != 0)
  523: 		     state->client_hostname[ml] = save;
  524: 		 }
  525: 	     }
  526: 	 }
  527:     }	 
  528:   
  529:   if (state->clid &&
  530:       (config = find_config(daemon->dhcp_conf, state->context, state->clid, state->clid_len,
  531: 			    state->mac, state->mac_len, state->mac_type, NULL, run_tag_if(state->tags))) &&
  532:       have_config(config, CONFIG_NAME))
  533:     {
  534:       state->hostname = config->hostname;
  535:       state->domain = config->domain;
  536:       state->hostname_auth = 1;
  537:     }
  538:   else if (state->client_hostname)
  539:     {
  540:       state->domain = strip_hostname(state->client_hostname);
  541:       
  542:       if (strlen(state->client_hostname) != 0)
  543: 	{
  544: 	  state->hostname = state->client_hostname;
  545: 	  
  546: 	  if (!config)
  547: 	    {
  548: 	      /* Search again now we have a hostname. 
  549: 		 Only accept configs without CLID here, (it won't match)
  550: 		 to avoid impersonation by name. */
  551: 	      struct dhcp_config *new = find_config(daemon->dhcp_conf, state->context, NULL, 0, NULL, 0, 0, state->hostname, run_tag_if(state->tags));
  552: 	      if (new && !have_config(new, CONFIG_CLID) && !new->hwaddr)
  553: 		config = new;
  554: 	    }
  555: 	}
  556:     }
  557: 
  558:   if (config)
  559:     {
  560:       struct dhcp_netid_list *list;
  561:       
  562:       for (list = config->netid; list; list = list->next)
  563:         {
  564:           list->list->next = state->tags;
  565:           state->tags = list->list;
  566:         }
  567: 
  568:       /* set "known" tag for known hosts */
  569:       known_id.net = "known";
  570:       known_id.next = state->tags;
  571:       state->tags = &known_id;
  572: 
  573:       if (have_config(config, CONFIG_DISABLE))
  574: 	ignore = 1;
  575:     }
  576:   else if (state->clid &&
  577: 	   find_config(daemon->dhcp_conf, NULL, state->clid, state->clid_len,
  578: 		       state->mac, state->mac_len, state->mac_type, NULL, run_tag_if(state->tags)))
  579:     {
  580:       known_id.net = "known-othernet";
  581:       known_id.next = state->tags;
  582:       state->tags = &known_id;
  583:     }
  584:   
  585:   tagif = run_tag_if(state->tags);
  586:   
  587:   /* if all the netids in the ignore list are present, ignore this client */
  588:   if (daemon->dhcp_ignore)
  589:     {
  590:       struct dhcp_netid_list *id_list;
  591:      
  592:       for (id_list = daemon->dhcp_ignore; id_list; id_list = id_list->next)
  593: 	if (match_netid(id_list->list, tagif, 0))
  594: 	  ignore = 1;
  595:     }
  596:   
  597:   /* if all the netids in the ignore_name list are present, ignore client-supplied name */
  598:   if (!state->hostname_auth)
  599:     {
  600:        struct dhcp_netid_list *id_list;
  601:        
  602:        for (id_list = daemon->dhcp_ignore_names; id_list; id_list = id_list->next)
  603: 	 if ((!id_list->list) || match_netid(id_list->list, tagif, 0))
  604: 	   break;
  605:        if (id_list)
  606: 	 state->hostname = NULL;
  607:     }
  608:   
  609: 
  610:   switch (msg_type)
  611:     {
  612:     default:
  613:       return 0;
  614:       
  615:       
  616:     case DHCP6SOLICIT:
  617:       {
  618:       	int address_assigned = 0;
  619: 	/* tags without all prefix-class tags */
  620: 	struct dhcp_netid *solicit_tags;
  621: 	struct dhcp_context *c;
  622: 	
  623: 	outmsgtype = DHCP6ADVERTISE;
  624: 	
  625: 	if (opt6_find(state->packet_options, state->end, OPTION6_RAPID_COMMIT, 0))
  626: 	  {
  627: 	    outmsgtype = DHCP6REPLY;
  628: 	    state->lease_allocate = 1;
  629: 	    o = new_opt6(OPTION6_RAPID_COMMIT);
  630: 	    end_opt6(o);
  631: 	  }
  632: 	
  633:   	log6_quiet(state, "DHCPSOLICIT", NULL, ignore ? _("ignored") : NULL);
  634: 
  635:       request_no_address:
  636: 	solicit_tags = tagif;
  637: 	
  638: 	if (ignore)
  639: 	  return 0;
  640: 	
  641: 	/* reset USED bits in leases */
  642: 	lease6_reset();
  643: 
  644: 	/* Can use configured address max once per prefix */
  645: 	for (c = state->context; c; c = c->current)
  646: 	  c->flags &= ~CONTEXT_CONF_USED;
  647: 
  648: 	for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
  649: 	  {   
  650: 	    void *ia_option, *ia_end;
  651: 	    unsigned int min_time = 0xffffffff;
  652: 	    int t1cntr;
  653: 	    int ia_counter;
  654: 	    /* set unless we're sending a particular prefix-class, when we
  655: 	       want only dhcp-ranges with the correct tags set and not those without any tags. */
  656: 	    int plain_range = 1;
  657: 	    u32 lease_time;
  658: 	    struct dhcp_lease *ltmp;
  659: 	    struct in6_addr req_addr, addr;
  660: 	    
  661: 	    if (!check_ia(state, opt, &ia_end, &ia_option))
  662: 	      continue;
  663: 	    
  664: 	    /* reset USED bits in contexts - one address per prefix per IAID */
  665: 	    for (c = state->context; c; c = c->current)
  666: 	      c->flags &= ~CONTEXT_USED;
  667: 
  668: 	    o = build_ia(state, &t1cntr);
  669: 	    if (address_assigned)
  670: 		address_assigned = 2;
  671: 
  672: 	    for (ia_counter = 0; ia_option; ia_counter++, ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
  673: 	      {
  674: 		/* worry about alignment here. */
  675: 		memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
  676: 				
  677: 		if ((c = address6_valid(state->context, &req_addr, solicit_tags, plain_range)))
  678: 		  {
  679: 		    lease_time = c->lease_time;
  680: 		    /* If the client asks for an address on the same network as a configured address, 
  681: 		       offer the configured address instead, to make moving to newly-configured
  682: 		       addresses automatic. */
  683: 		    if (!(c->flags & CONTEXT_CONF_USED) && config_valid(config, c, &addr, state, now))
  684: 		      {
  685: 			req_addr = addr;
  686: 			mark_config_used(c, &addr);
  687: 			if (have_config(config, CONFIG_TIME))
  688: 			  lease_time = config->lease_time;
  689: 		      }
  690: 		    else if (!(c = address6_available(state->context, &req_addr, solicit_tags, plain_range)))
  691: 		      continue; /* not an address we're allowed */
  692: 		    else if (!check_address(state, &req_addr))
  693: 		      continue; /* address leased elsewhere */
  694: 		    
  695: 		    /* add address to output packet */
  696: 		    add_address(state, c, lease_time, ia_option, &min_time, &req_addr, now);
  697: 		    mark_context_used(state, &req_addr);
  698: 		    get_context_tag(state, c);
  699: 		    address_assigned = 1;
  700: 		  }
  701: 	      }
  702: 	    
  703: 	    /* Suggest configured address(es) */
  704: 	    for (c = state->context; c; c = c->current) 
  705: 	      if (!(c->flags & CONTEXT_CONF_USED) &&
  706: 		  match_netid(c->filter, solicit_tags, plain_range) &&
  707: 		  config_valid(config, c, &addr, state, now))
  708: 		{
  709: 		  mark_config_used(state->context, &addr);
  710: 		  if (have_config(config, CONFIG_TIME))
  711: 		    lease_time = config->lease_time;
  712: 		  else
  713: 		    lease_time = c->lease_time;
  714: 
  715: 		  /* add address to output packet */
  716: 		  add_address(state, c, lease_time, NULL, &min_time, &addr, now);
  717: 		  mark_context_used(state, &addr);
  718: 		  get_context_tag(state, c);
  719: 		  address_assigned = 1;
  720: 		}
  721: 	    
  722: 	    /* return addresses for existing leases */
  723: 	    ltmp = NULL;
  724: 	    while ((ltmp = lease6_find_by_client(ltmp, state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA, state->clid, state->clid_len, state->iaid)))
  725: 	      {
  726: 		req_addr = ltmp->addr6;
  727: 		if ((c = address6_available(state->context, &req_addr, solicit_tags, plain_range)))
  728: 		  {
  729: 		    add_address(state, c, c->lease_time, NULL, &min_time, &req_addr, now);
  730: 		    mark_context_used(state, &req_addr);
  731: 		    get_context_tag(state, c);
  732: 		    address_assigned = 1;
  733: 		  }
  734: 	      }
  735: 		 	   
  736: 	    /* Return addresses for all valid contexts which don't yet have one */
  737: 	    while ((c = address6_allocate(state->context, state->clid, state->clid_len, state->ia_type == OPTION6_IA_TA,
  738: 					  state->iaid, ia_counter, solicit_tags, plain_range, &addr)))
  739: 	      {
  740: 		add_address(state, c, c->lease_time, NULL, &min_time, &addr, now);
  741: 		mark_context_used(state, &addr);
  742: 		get_context_tag(state, c);
  743: 		address_assigned = 1;
  744: 	      }
  745: 	    
  746: 	    if (address_assigned != 1)
  747: 	      {
  748: 		/* If the server will not assign any addresses to any IAs in a
  749: 		   subsequent Request from the client, the server MUST send an Advertise
  750: 		   message to the client that doesn't include any IA options. */
  751: 		if (!state->lease_allocate)
  752: 		  {
  753: 		    save_counter(o);
  754: 		    continue;
  755: 		  }
  756: 		
  757: 		/* If the server cannot assign any addresses to an IA in the message
  758: 		   from the client, the server MUST include the IA in the Reply message
  759: 		   with no addresses in the IA and a Status Code option in the IA
  760: 		   containing status code NoAddrsAvail. */
  761: 		o1 = new_opt6(OPTION6_STATUS_CODE);
  762: 		put_opt6_short(DHCP6NOADDRS);
  763: 		put_opt6_string(_("address unavailable"));
  764: 		end_opt6(o1);
  765: 	      }
  766: 	    
  767: 	    end_ia(t1cntr, min_time, 0);
  768: 	    end_opt6(o);	
  769: 	  }
  770: 
  771: 	if (address_assigned) 
  772: 	  {
  773: 	    o1 = new_opt6(OPTION6_STATUS_CODE);
  774: 	    put_opt6_short(DHCP6SUCCESS);
  775: 	    put_opt6_string(_("success"));
  776: 	    end_opt6(o1);
  777: 	    
  778: 	    /* If --dhcp-authoritative is set, we can tell client not to wait for
  779: 	       other possible servers */
  780: 	    o = new_opt6(OPTION6_PREFERENCE);
  781: 	    put_opt6_char(option_bool(OPT_AUTHORITATIVE) ? 255 : 0);
  782: 	    end_opt6(o);
  783: 	    tagif = add_options(state, 0);
  784: 	  }
  785: 	else
  786: 	  { 
  787: 	    /* no address, return error */
  788: 	    o1 = new_opt6(OPTION6_STATUS_CODE);
  789: 	    put_opt6_short(DHCP6NOADDRS);
  790: 	    put_opt6_string(_("no addresses available"));
  791: 	    end_opt6(o1);
  792: 
  793: 	    /* Some clients will ask repeatedly when we're not giving
  794: 	       out addresses because we're in stateless mode. Avoid spamming
  795: 	       the log in that case. */
  796: 	    for (c = state->context; c; c = c->current)
  797: 	      if (!(c->flags & CONTEXT_RA_STATELESS))
  798: 		{
  799: 		  log6_packet(state, state->lease_allocate ? "DHCPREPLY" : "DHCPADVERTISE", NULL, _("no addresses available"));
  800: 		  break;
  801: 		}
  802: 	  }
  803: 
  804: 	break;
  805:       }
  806:       
  807:     case DHCP6REQUEST:
  808:       {
  809: 	int address_assigned = 0;
  810: 	int start = save_counter(-1);
  811: 
  812: 	/* set reply message type */
  813: 	outmsgtype = DHCP6REPLY;
  814: 	state->lease_allocate = 1;
  815: 
  816: 	log6_quiet(state, "DHCPREQUEST", NULL, ignore ? _("ignored") : NULL);
  817: 	
  818: 	if (ignore)
  819: 	  return 0;
  820: 	
  821: 	for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
  822: 	  {   
  823: 	    void *ia_option, *ia_end;
  824: 	    unsigned int min_time = 0xffffffff;
  825: 	    int t1cntr;
  826: 	    
  827: 	     if (!check_ia(state, opt, &ia_end, &ia_option))
  828: 	       continue;
  829: 
  830: 	     if (!ia_option)
  831: 	       {
  832: 		 /* If we get a request with an IA_*A without addresses, treat it exactly like
  833: 		    a SOLICT with rapid commit set. */
  834: 		 save_counter(start);
  835: 		 goto request_no_address; 
  836: 	       }
  837: 
  838: 	    o = build_ia(state, &t1cntr);
  839: 	      
  840: 	    for (; ia_option; ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
  841: 	      {
  842: 		struct in6_addr req_addr;
  843: 		struct dhcp_context *dynamic, *c;
  844: 		unsigned int lease_time;
  845: 		int config_ok = 0;
  846: 
  847: 		/* align. */
  848: 		memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
  849: 		
  850: 		if ((c = address6_valid(state->context, &req_addr, tagif, 1)))
  851: 		  config_ok = (config_implies(config, c, &req_addr) != NULL);
  852: 		
  853: 		if ((dynamic = address6_available(state->context, &req_addr, tagif, 1)) || c)
  854: 		  {
  855: 		    if (!dynamic && !config_ok)
  856: 		      {
  857: 			/* Static range, not configured. */
  858: 			o1 = new_opt6(OPTION6_STATUS_CODE);
  859: 			put_opt6_short(DHCP6NOADDRS);
  860: 			put_opt6_string(_("address unavailable"));
  861: 			end_opt6(o1);
  862: 		      }
  863: 		    else if (!check_address(state, &req_addr))
  864: 		      {
  865: 			/* Address leased to another DUID/IAID */
  866: 			o1 = new_opt6(OPTION6_STATUS_CODE);
  867: 			put_opt6_short(DHCP6UNSPEC);
  868: 			put_opt6_string(_("address in use"));
  869: 			end_opt6(o1);
  870: 		      } 
  871: 		    else 
  872: 		      {
  873: 			if (!dynamic)
  874: 			  dynamic = c;
  875: 
  876: 			lease_time = dynamic->lease_time;
  877: 			
  878: 			if (config_ok && have_config(config, CONFIG_TIME))
  879: 			  lease_time = config->lease_time;
  880: 
  881: 			add_address(state, dynamic, lease_time, ia_option, &min_time, &req_addr, now);
  882: 			get_context_tag(state, dynamic);
  883: 			address_assigned = 1;
  884: 		      }
  885: 		  }
  886: 		else 
  887: 		  {
  888: 		    /* requested address not on the correct link */
  889: 		    o1 = new_opt6(OPTION6_STATUS_CODE);
  890: 		    put_opt6_short(DHCP6NOTONLINK);
  891: 		    put_opt6_string(_("not on link"));
  892: 		    end_opt6(o1);
  893: 		  }
  894: 	      }
  895: 	 
  896: 	    end_ia(t1cntr, min_time, 0);
  897: 	    end_opt6(o);	
  898: 	  }
  899: 
  900: 	if (address_assigned) 
  901: 	  {
  902: 	    o1 = new_opt6(OPTION6_STATUS_CODE);
  903: 	    put_opt6_short(DHCP6SUCCESS);
  904: 	    put_opt6_string(_("success"));
  905: 	    end_opt6(o1);
  906: 	  }
  907: 	else
  908: 	  { 
  909: 	    /* no address, return error */
  910: 	    o1 = new_opt6(OPTION6_STATUS_CODE);
  911: 	    put_opt6_short(DHCP6NOADDRS);
  912: 	    put_opt6_string(_("no addresses available"));
  913: 	    end_opt6(o1);
  914: 	    log6_packet(state, "DHCPREPLY", NULL, _("no addresses available"));
  915: 	  }
  916: 
  917: 	tagif = add_options(state, 0);
  918: 	break;
  919:       }
  920:       
  921:   
  922:     case DHCP6RENEW:
  923:     case DHCP6REBIND:
  924:       {
  925: 	int address_assigned = 0;
  926: 
  927: 	/* set reply message type */
  928: 	outmsgtype = DHCP6REPLY;
  929: 	
  930: 	log6_quiet(state, msg_type == DHCP6RENEW ? "DHCPRENEW" : "DHCPREBIND", NULL, NULL);
  931: 
  932: 	for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
  933: 	  {
  934: 	    void *ia_option, *ia_end;
  935: 	    unsigned int min_time = 0xffffffff;
  936: 	    int t1cntr, iacntr;
  937: 	    
  938: 	    if (!check_ia(state, opt, &ia_end, &ia_option))
  939: 	      continue;
  940: 	    
  941: 	    o = build_ia(state, &t1cntr);
  942: 	    iacntr = save_counter(-1); 
  943: 	    
  944: 	    for (; ia_option; ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
  945: 	      {
  946: 		struct dhcp_lease *lease = NULL;
  947: 		struct in6_addr req_addr;
  948: 		unsigned int preferred_time =  opt6_uint(ia_option, 16, 4);
  949: 		unsigned int valid_time =  opt6_uint(ia_option, 20, 4);
  950: 		char *message = NULL;
  951: 		struct dhcp_context *this_context;
  952: 
  953: 		memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ); 
  954: 		
  955: 		if (!(lease = lease6_find(state->clid, state->clid_len,
  956: 					  state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA, 
  957: 					  state->iaid, &req_addr)))
  958: 		  {
  959: 		    if (msg_type == DHCP6REBIND)
  960: 		      {
  961: 			/* When rebinding, we can create a lease if it doesn't exist. */
  962: 			lease = lease6_allocate(&req_addr, state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA);
  963: 			if (lease)
  964: 			  lease_set_iaid(lease, state->iaid);
  965: 			else
  966: 			  break;
  967: 		      }
  968: 		    else
  969: 		      {
  970: 			/* If the server cannot find a client entry for the IA the server
  971: 			   returns the IA containing no addresses with a Status Code option set
  972: 			   to NoBinding in the Reply message. */
  973: 			save_counter(iacntr);
  974: 			t1cntr = 0;
  975: 			
  976: 			log6_packet(state, "DHCPREPLY", &req_addr, _("lease not found"));
  977: 			
  978: 			o1 = new_opt6(OPTION6_STATUS_CODE);
  979: 			put_opt6_short(DHCP6NOBINDING);
  980: 			put_opt6_string(_("no binding found"));
  981: 			end_opt6(o1);
  982: 			
  983: 			preferred_time = valid_time = 0;
  984: 			break;
  985: 		      }
  986: 		  }
  987: 		
  988: 		if ((this_context = address6_available(state->context, &req_addr, tagif, 1)) ||
  989: 		    (this_context = address6_valid(state->context, &req_addr, tagif, 1)))
  990: 		  {
  991: 		    unsigned int lease_time;
  992: 
  993: 		    get_context_tag(state, this_context);
  994: 		    
  995: 		    if (config_implies(config, this_context, &req_addr) && have_config(config, CONFIG_TIME))
  996: 		      lease_time = config->lease_time;
  997: 		    else 
  998: 		      lease_time = this_context->lease_time;
  999: 		    
 1000: 		    calculate_times(this_context, &min_time, &valid_time, &preferred_time, lease_time); 
 1001: 		    
 1002: 		    lease_set_expires(lease, valid_time, now);
 1003: 		    /* Update MAC record in case it's new information. */
 1004: 		    if (state->mac_len != 0)
 1005: 		      lease_set_hwaddr(lease, state->mac, state->clid, state->mac_len, state->mac_type, state->clid_len, now, 0);
 1006: 		    if (state->ia_type == OPTION6_IA_NA && state->hostname)
 1007: 		      {
 1008: 			char *addr_domain = get_domain6(&req_addr);
 1009: 			if (!state->send_domain)
 1010: 			  state->send_domain = addr_domain;
 1011: 			lease_set_hostname(lease, state->hostname, state->hostname_auth, addr_domain, state->domain); 
 1012: 			message = state->hostname;
 1013: 		      }
 1014: 		    
 1015: 		    
 1016: 		    if (preferred_time == 0)
 1017: 		      message = _("deprecated");
 1018: 
 1019: 		    address_assigned = 1;
 1020: 		  }
 1021: 		else
 1022: 		  {
 1023: 		    preferred_time = valid_time = 0;
 1024: 		    message = _("address invalid");
 1025: 		  } 
 1026: 
 1027: 		if (message && (message != state->hostname))
 1028: 		  log6_packet(state, "DHCPREPLY", &req_addr, message);	
 1029: 		else
 1030: 		  log6_quiet(state, "DHCPREPLY", &req_addr, message);
 1031: 	
 1032: 		o1 =  new_opt6(OPTION6_IAADDR);
 1033: 		put_opt6(&req_addr, sizeof(req_addr));
 1034: 		put_opt6_long(preferred_time);
 1035: 		put_opt6_long(valid_time);
 1036: 		end_opt6(o1);
 1037: 	      }
 1038: 	    
 1039: 	    end_ia(t1cntr, min_time, 1);
 1040: 	    end_opt6(o);
 1041: 	  }
 1042: 
 1043: 	if (!address_assigned && msg_type == DHCP6REBIND)
 1044: 	  { 
 1045: 	    /* can't create lease for any address, return error */
 1046: 	    o1 = new_opt6(OPTION6_STATUS_CODE);
 1047: 	    put_opt6_short(DHCP6NOADDRS);
 1048: 	    put_opt6_string(_("no addresses available"));
 1049: 	    end_opt6(o1);
 1050: 	  }
 1051: 	
 1052: 	tagif = add_options(state, 0);
 1053: 	break;
 1054:       }
 1055:       
 1056:     case DHCP6CONFIRM:
 1057:       {
 1058: 	int good_addr = 0;
 1059: 
 1060: 	/* set reply message type */
 1061: 	outmsgtype = DHCP6REPLY;
 1062: 	
 1063: 	log6_quiet(state, "DHCPCONFIRM", NULL, NULL);
 1064: 	
 1065: 	for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
 1066: 	  {
 1067: 	    void *ia_option, *ia_end;
 1068: 	    
 1069: 	    for (check_ia(state, opt, &ia_end, &ia_option);
 1070: 		 ia_option;
 1071: 		 ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
 1072: 	      {
 1073: 		struct in6_addr req_addr;
 1074: 
 1075: 		/* alignment */
 1076: 		memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
 1077: 		
 1078: 		if (!address6_valid(state->context, &req_addr, tagif, 1))
 1079: 		  {
 1080: 		    o1 = new_opt6(OPTION6_STATUS_CODE);
 1081: 		    put_opt6_short(DHCP6NOTONLINK);
 1082: 		    put_opt6_string(_("confirm failed"));
 1083: 		    end_opt6(o1);
 1084: 		    log6_quiet(state, "DHCPREPLY", &req_addr, _("confirm failed"));
 1085: 		    return 1;
 1086: 		  }
 1087: 
 1088: 		good_addr = 1;
 1089: 		log6_quiet(state, "DHCPREPLY", &req_addr, state->hostname);
 1090: 	      }
 1091: 	  }	 
 1092: 	
 1093: 	/* No addresses, no reply: RFC 3315 18.2.2 */
 1094: 	if (!good_addr)
 1095: 	  return 0;
 1096: 
 1097: 	o1 = new_opt6(OPTION6_STATUS_CODE);
 1098: 	put_opt6_short(DHCP6SUCCESS );
 1099: 	put_opt6_string(_("all addresses still on link"));
 1100: 	end_opt6(o1);
 1101: 	break;
 1102:     }
 1103:       
 1104:     case DHCP6IREQ:
 1105:       {
 1106: 	/* We can't discriminate contexts based on address, as we don't know it.
 1107: 	   If there is only one possible context, we can use its tags */
 1108: 	if (state->context && state->context->netid.net && !state->context->current)
 1109: 	  {
 1110: 	    state->context->netid.next = NULL;
 1111: 	    state->context_tags =  &state->context->netid;
 1112: 	  }
 1113: 
 1114: 	/* Similarly, we can't determine domain from address, but if the FQDN is
 1115: 	   given in --dhcp-host, we can use that, and failing that we can use the 
 1116: 	   unqualified configured domain, if any. */
 1117: 	if (state->hostname_auth)
 1118: 	  state->send_domain = state->domain;
 1119: 	else
 1120: 	  state->send_domain = get_domain6(NULL);
 1121: 
 1122: 	log6_quiet(state, "DHCPINFORMATION-REQUEST", NULL, ignore ? _("ignored") : state->hostname);
 1123: 	if (ignore)
 1124: 	  return 0;
 1125: 	outmsgtype = DHCP6REPLY;
 1126: 	tagif = add_options(state, 1);
 1127: 	break;
 1128:       }
 1129:       
 1130:       
 1131:     case DHCP6RELEASE:
 1132:       {
 1133: 	/* set reply message type */
 1134: 	outmsgtype = DHCP6REPLY;
 1135: 
 1136: 	log6_quiet(state, "DHCPRELEASE", NULL, NULL);
 1137: 
 1138: 	for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
 1139: 	  {
 1140: 	    void *ia_option, *ia_end;
 1141: 	    int made_ia = 0;
 1142: 	    	    
 1143: 	    for (check_ia(state, opt, &ia_end, &ia_option);
 1144: 		 ia_option;
 1145: 		 ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24)) 
 1146: 	      {
 1147: 		struct dhcp_lease *lease;
 1148: 		struct in6_addr addr;
 1149: 
 1150: 		/* align */
 1151: 		memcpy(&addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
 1152: 		if ((lease = lease6_find(state->clid, state->clid_len, state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA,
 1153: 					 state->iaid, &addr)))
 1154: 		  lease_prune(lease, now);
 1155: 		else
 1156: 		  {
 1157: 		    if (!made_ia)
 1158: 		      {
 1159: 			o = new_opt6(state->ia_type);
 1160: 			put_opt6_long(state->iaid);
 1161: 			if (state->ia_type == OPTION6_IA_NA)
 1162: 			  {
 1163: 			    put_opt6_long(0);
 1164: 			    put_opt6_long(0); 
 1165: 			  }
 1166: 			made_ia = 1;
 1167: 		      }
 1168: 		    
 1169: 		    o1 = new_opt6(OPTION6_IAADDR);
 1170: 		    put_opt6(&addr, IN6ADDRSZ);
 1171: 		    put_opt6_long(0);
 1172: 		    put_opt6_long(0);
 1173: 		    end_opt6(o1);
 1174: 		  }
 1175: 	      }
 1176: 	    
 1177: 	    if (made_ia)
 1178: 	      {
 1179: 		o1 = new_opt6(OPTION6_STATUS_CODE);
 1180: 		put_opt6_short(DHCP6NOBINDING);
 1181: 		put_opt6_string(_("no binding found"));
 1182: 		end_opt6(o1);
 1183: 		
 1184: 		end_opt6(o);
 1185: 	      }
 1186: 	  }
 1187: 	
 1188: 	o1 = new_opt6(OPTION6_STATUS_CODE);
 1189: 	put_opt6_short(DHCP6SUCCESS);
 1190: 	put_opt6_string(_("release received"));
 1191: 	end_opt6(o1);
 1192: 	
 1193: 	break;
 1194:       }
 1195: 
 1196:     case DHCP6DECLINE:
 1197:       {
 1198: 	/* set reply message type */
 1199: 	outmsgtype = DHCP6REPLY;
 1200: 	
 1201: 	log6_quiet(state, "DHCPDECLINE", NULL, NULL);
 1202: 
 1203: 	for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
 1204: 	  {
 1205: 	    void *ia_option, *ia_end;
 1206: 	    int made_ia = 0;
 1207: 	    	    
 1208: 	    for (check_ia(state, opt, &ia_end, &ia_option);
 1209: 		 ia_option;
 1210: 		 ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24)) 
 1211: 	      {
 1212: 		struct dhcp_lease *lease;
 1213: 		struct in6_addr addr;
 1214: 		struct addrlist *addr_list;
 1215: 		
 1216: 		/* align */
 1217: 		memcpy(&addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
 1218: 
 1219: 		if ((addr_list = config_implies(config, state->context, &addr)))
 1220: 		  {
 1221: 		    prettyprint_time(daemon->dhcp_buff3, DECLINE_BACKOFF);
 1222: 		    inet_ntop(AF_INET6, &addr, daemon->addrbuff, ADDRSTRLEN);
 1223: 		    my_syslog(MS_DHCP | LOG_WARNING, _("disabling DHCP static address %s for %s"), 
 1224: 			      daemon->addrbuff, daemon->dhcp_buff3);
 1225: 		    addr_list->flags |= ADDRLIST_DECLINED;
 1226: 		    addr_list->decline_time = now;
 1227: 		  }
 1228: 		else
 1229: 		  /* make sure this host gets a different address next time. */
 1230: 		  for (context_tmp = state->context; context_tmp; context_tmp = context_tmp->current)
 1231: 		    context_tmp->addr_epoch++;
 1232: 		
 1233: 		if ((lease = lease6_find(state->clid, state->clid_len, state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA,
 1234: 					 state->iaid, &addr)))
 1235: 		  lease_prune(lease, now);
 1236: 		else
 1237: 		  {
 1238: 		    if (!made_ia)
 1239: 		      {
 1240: 			o = new_opt6(state->ia_type);
 1241: 			put_opt6_long(state->iaid);
 1242: 			if (state->ia_type == OPTION6_IA_NA)
 1243: 			  {
 1244: 			    put_opt6_long(0);
 1245: 			    put_opt6_long(0); 
 1246: 			  }
 1247: 			made_ia = 1;
 1248: 		      }
 1249: 		    
 1250: 		    o1 = new_opt6(OPTION6_IAADDR);
 1251: 		    put_opt6(&addr, IN6ADDRSZ);
 1252: 		    put_opt6_long(0);
 1253: 		    put_opt6_long(0);
 1254: 		    end_opt6(o1);
 1255: 		  }
 1256: 	      }
 1257: 	    
 1258: 	    if (made_ia)
 1259: 	      {
 1260: 		o1 = new_opt6(OPTION6_STATUS_CODE);
 1261: 		put_opt6_short(DHCP6NOBINDING);
 1262: 		put_opt6_string(_("no binding found"));
 1263: 		end_opt6(o1);
 1264: 		
 1265: 		end_opt6(o);
 1266: 	      }
 1267: 	    
 1268: 	  }
 1269: 
 1270: 	/* We must answer with 'success' in global section anyway */
 1271: 	o1 = new_opt6(OPTION6_STATUS_CODE);
 1272: 	put_opt6_short(DHCP6SUCCESS);
 1273: 	put_opt6_string(_("success"));
 1274: 	end_opt6(o1);
 1275: 	break;
 1276:       }
 1277: 
 1278:     }
 1279: 
 1280:   log_tags(tagif, state->xid);
 1281: 
 1282:  done:
 1283:   /* Fill in the message type. Note that we store the offset,
 1284:      not a direct pointer, since the packet memory may have been 
 1285:      reallocated. */
 1286:   ((unsigned char *)(daemon->outpacket.iov_base))[start_msg] = outmsgtype;
 1287: 
 1288:   log6_opts(0, state->xid, daemon->outpacket.iov_base + start_opts, daemon->outpacket.iov_base + save_counter(-1));
 1289:   
 1290:   return 1;
 1291: 
 1292: }
 1293: 
 1294: static struct dhcp_netid *add_options(struct state *state, int do_refresh)  
 1295: {
 1296:   void *oro;
 1297:   /* filter options based on tags, those we want get DHOPT_TAGOK bit set */
 1298:   struct dhcp_netid *tagif = option_filter(state->tags, state->context_tags, daemon->dhcp_opts6);
 1299:   struct dhcp_opt *opt_cfg;
 1300:   int done_dns = 0, done_refresh = !do_refresh, do_encap = 0;
 1301:   int i, o, o1;
 1302: 
 1303:   oro = opt6_find(state->packet_options, state->end, OPTION6_ORO, 0);
 1304:   
 1305:   for (opt_cfg = daemon->dhcp_opts6; opt_cfg; opt_cfg = opt_cfg->next)
 1306:     {
 1307:       /* netids match and not encapsulated? */
 1308:       if (!(opt_cfg->flags & DHOPT_TAGOK))
 1309: 	continue;
 1310:       
 1311:       if (!(opt_cfg->flags & DHOPT_FORCE) && oro)
 1312: 	{
 1313: 	  for (i = 0; i <  opt6_len(oro) - 1; i += 2)
 1314: 	    if (opt6_uint(oro, i, 2) == (unsigned)opt_cfg->opt)
 1315: 	      break;
 1316: 	  
 1317: 	  /* option not requested */
 1318: 	  if (i >=  opt6_len(oro) - 1)
 1319: 	    continue;
 1320: 	}
 1321:       
 1322:       if (opt_cfg->opt == OPTION6_REFRESH_TIME)
 1323: 	done_refresh = 1;
 1324:        
 1325:       if (opt_cfg->opt == OPTION6_DNS_SERVER)
 1326: 	done_dns = 1;
 1327:       
 1328:       if (opt_cfg->flags & DHOPT_ADDR6)
 1329: 	{
 1330: 	  int len, j;
 1331: 	  struct in6_addr *a;
 1332: 	  
 1333: 	  for (a = (struct in6_addr *)opt_cfg->val, len = opt_cfg->len, j = 0; 
 1334: 	       j < opt_cfg->len; j += IN6ADDRSZ, a++)
 1335: 	    if ((IN6_IS_ADDR_ULA_ZERO(a) && IN6_IS_ADDR_UNSPECIFIED(state->ula_addr)) ||
 1336: 		(IN6_IS_ADDR_LINK_LOCAL_ZERO(a) && IN6_IS_ADDR_UNSPECIFIED(state->ll_addr)))
 1337: 	      len -= IN6ADDRSZ;
 1338: 	  
 1339: 	  if (len != 0)
 1340: 	    {
 1341: 	      
 1342: 	      o = new_opt6(opt_cfg->opt);
 1343: 	      	  
 1344: 	      for (a = (struct in6_addr *)opt_cfg->val, j = 0; j < opt_cfg->len; j+=IN6ADDRSZ, a++)
 1345: 		{
 1346: 		  struct in6_addr *p = NULL;
 1347: 
 1348: 		  if (IN6_IS_ADDR_UNSPECIFIED(a))
 1349: 		    {
 1350: 		      if (!add_local_addrs(state->context))
 1351: 			p = state->fallback;
 1352: 		    }
 1353: 		  else if (IN6_IS_ADDR_ULA_ZERO(a))
 1354: 		    {
 1355: 		      if (!IN6_IS_ADDR_UNSPECIFIED(state->ula_addr))
 1356: 			p = state->ula_addr;
 1357: 		    }
 1358: 		  else if (IN6_IS_ADDR_LINK_LOCAL_ZERO(a))
 1359: 		    {
 1360: 		      if (!IN6_IS_ADDR_UNSPECIFIED(state->ll_addr))
 1361: 			p = state->ll_addr;
 1362: 		    }
 1363: 		  else
 1364: 		    p = a;
 1365: 
 1366: 		  if (!p)
 1367: 		    continue;
 1368: 		  else if (opt_cfg->opt == OPTION6_NTP_SERVER)
 1369: 		    {
 1370: 		      if (IN6_IS_ADDR_MULTICAST(p))
 1371: 			o1 = new_opt6(NTP_SUBOPTION_MC_ADDR);
 1372: 		      else
 1373: 			o1 = new_opt6(NTP_SUBOPTION_SRV_ADDR);
 1374: 		      put_opt6(p, IN6ADDRSZ);
 1375: 		      end_opt6(o1);
 1376: 		    }
 1377: 		  else
 1378: 		    put_opt6(p, IN6ADDRSZ);
 1379: 		}
 1380: 
 1381: 	      end_opt6(o);
 1382: 	    }
 1383: 	}
 1384:       else
 1385: 	{
 1386: 	  o = new_opt6(opt_cfg->opt);
 1387: 	  if (opt_cfg->val)
 1388: 	    put_opt6(opt_cfg->val, opt_cfg->len);
 1389: 	  end_opt6(o);
 1390: 	}
 1391:     }
 1392:   
 1393:   if (daemon->port == NAMESERVER_PORT && !done_dns)
 1394:     {
 1395:       o = new_opt6(OPTION6_DNS_SERVER);
 1396:       if (!add_local_addrs(state->context))
 1397: 	put_opt6(state->fallback, IN6ADDRSZ);
 1398:       end_opt6(o); 
 1399:     }
 1400: 
 1401:   if (state->context && !done_refresh)
 1402:     {
 1403:       struct dhcp_context *c;
 1404:       unsigned int lease_time = 0xffffffff;
 1405:       
 1406:       /* Find the smallest lease tie of all contexts,
 1407: 	 subject to the RFC-4242 stipulation that this must not 
 1408: 	 be less than 600. */
 1409:       for (c = state->context; c; c = c->next)
 1410: 	if (c->lease_time < lease_time)
 1411: 	  {
 1412: 	    if (c->lease_time < 600)
 1413: 	      lease_time = 600;
 1414: 	    else
 1415: 	      lease_time = c->lease_time;
 1416: 	  }
 1417: 
 1418:       o = new_opt6(OPTION6_REFRESH_TIME);
 1419:       put_opt6_long(lease_time);
 1420:       end_opt6(o); 
 1421:     }
 1422:    
 1423:     /* handle vendor-identifying vendor-encapsulated options,
 1424:        dhcp-option = vi-encap:13,17,....... */
 1425:   for (opt_cfg = daemon->dhcp_opts6; opt_cfg; opt_cfg = opt_cfg->next)
 1426:     opt_cfg->flags &= ~DHOPT_ENCAP_DONE;
 1427:     
 1428:   if (oro)
 1429:     for (i = 0; i <  opt6_len(oro) - 1; i += 2)
 1430:       if (opt6_uint(oro, i, 2) == OPTION6_VENDOR_OPTS)
 1431: 	do_encap = 1;
 1432:   
 1433:   for (opt_cfg = daemon->dhcp_opts6; opt_cfg; opt_cfg = opt_cfg->next)
 1434:     { 
 1435:       if (opt_cfg->flags & DHOPT_RFC3925)
 1436: 	{
 1437: 	  int found = 0;
 1438: 	  struct dhcp_opt *oc;
 1439: 	  
 1440: 	  if (opt_cfg->flags & DHOPT_ENCAP_DONE)
 1441: 	    continue;
 1442: 	  
 1443: 	  for (oc = daemon->dhcp_opts6; oc; oc = oc->next)
 1444: 	    {
 1445: 	      oc->flags &= ~DHOPT_ENCAP_MATCH;
 1446: 	      
 1447: 	      if (!(oc->flags & DHOPT_RFC3925) || opt_cfg->u.encap != oc->u.encap)
 1448: 		continue;
 1449: 	      
 1450: 	      oc->flags |= DHOPT_ENCAP_DONE;
 1451: 	      if (match_netid(oc->netid, tagif, 1))
 1452: 		{
 1453: 		  /* option requested/forced? */
 1454: 		  if (!oro || do_encap || (oc->flags & DHOPT_FORCE))
 1455: 		    {
 1456: 		      oc->flags |= DHOPT_ENCAP_MATCH;
 1457: 		      found = 1;
 1458: 		    }
 1459: 		} 
 1460: 	    }
 1461: 	  
 1462: 	  if (found)
 1463: 	    { 
 1464: 	      o = new_opt6(OPTION6_VENDOR_OPTS);	      
 1465: 	      put_opt6_long(opt_cfg->u.encap);	
 1466: 	     
 1467: 	      for (oc = daemon->dhcp_opts6; oc; oc = oc->next)
 1468: 		if (oc->flags & DHOPT_ENCAP_MATCH)
 1469: 		  {
 1470: 		    o1 = new_opt6(oc->opt);
 1471: 		    put_opt6(oc->val, oc->len);
 1472: 		    end_opt6(o1);
 1473: 		  }
 1474: 	      end_opt6(o);
 1475: 	    }
 1476: 	}
 1477:     }      
 1478: 
 1479: 
 1480:   if (state->hostname)
 1481:     {
 1482:       unsigned char *p;
 1483:       size_t len = strlen(state->hostname);
 1484:       
 1485:       if (state->send_domain)
 1486: 	len += strlen(state->send_domain) + 2;
 1487: 
 1488:       o = new_opt6(OPTION6_FQDN);
 1489:       if ((p = expand(len + 2)))
 1490: 	{
 1491: 	  *(p++) = state->fqdn_flags;
 1492: 	  p = do_rfc1035_name(p, state->hostname, NULL);
 1493: 	  if (state->send_domain)
 1494: 	    {
 1495: 	      p = do_rfc1035_name(p, state->send_domain, NULL);
 1496: 	      *p = 0;
 1497: 	    }
 1498: 	}
 1499:       end_opt6(o);
 1500:     }
 1501: 
 1502: 
 1503:   /* logging */
 1504:   if (option_bool(OPT_LOG_OPTS) && oro)
 1505:     {
 1506:       char *q = daemon->namebuff;
 1507:       for (i = 0; i <  opt6_len(oro) - 1; i += 2)
 1508: 	{
 1509: 	  char *s = option_string(AF_INET6, opt6_uint(oro, i, 2), NULL, 0, NULL, 0);
 1510: 	  q += snprintf(q, MAXDNAME - (q - daemon->namebuff),
 1511: 			"%d%s%s%s", 
 1512: 			opt6_uint(oro, i, 2),
 1513: 			strlen(s) != 0 ? ":" : "",
 1514: 			s, 
 1515: 			(i > opt6_len(oro) - 3) ? "" : ", ");
 1516: 	  if ( i >  opt6_len(oro) - 3 || (q - daemon->namebuff) > 40)
 1517: 	    {
 1518: 	      q = daemon->namebuff;
 1519: 	      my_syslog(MS_DHCP | LOG_INFO, _("%u requested options: %s"), state->xid, daemon->namebuff);
 1520: 	    }
 1521: 	}
 1522:     } 
 1523: 
 1524:   return tagif;
 1525: }
 1526:  
 1527: static int add_local_addrs(struct dhcp_context *context)
 1528: {
 1529:   int done = 0;
 1530:   
 1531:   for (; context; context = context->current)
 1532:     if ((context->flags & CONTEXT_USED) && !IN6_IS_ADDR_UNSPECIFIED(&context->local6))
 1533:       {
 1534: 	/* squash duplicates */
 1535: 	struct dhcp_context *c;
 1536: 	for (c = context->current; c; c = c->current)
 1537: 	  if ((c->flags & CONTEXT_USED) &&
 1538: 	      IN6_ARE_ADDR_EQUAL(&context->local6, &c->local6))
 1539: 	    break;
 1540: 	
 1541: 	if (!c)
 1542: 	  { 
 1543: 	    done = 1;
 1544: 	    put_opt6(&context->local6, IN6ADDRSZ);
 1545: 	  }
 1546:       }
 1547: 
 1548:   return done;
 1549: }
 1550: 
 1551: 
 1552: static void get_context_tag(struct state *state, struct dhcp_context *context)
 1553: {
 1554:   /* get tags from context if we've not used it before */
 1555:   if (context->netid.next == &context->netid && context->netid.net)
 1556:     {
 1557:       context->netid.next = state->context_tags;
 1558:       state->context_tags = &context->netid;
 1559:       if (!state->hostname_auth)
 1560: 	{
 1561: 	  struct dhcp_netid_list *id_list;
 1562: 	  
 1563: 	  for (id_list = daemon->dhcp_ignore_names; id_list; id_list = id_list->next)
 1564: 	    if ((!id_list->list) || match_netid(id_list->list, &context->netid, 0))
 1565: 	      break;
 1566: 	  if (id_list)
 1567: 	    state->hostname = NULL;
 1568: 	}
 1569:     }
 1570: } 
 1571: 
 1572: static int check_ia(struct state *state, void *opt, void **endp, void **ia_option)
 1573: {
 1574:   state->ia_type = opt6_type(opt);
 1575:   *ia_option = NULL;
 1576: 
 1577:   if (state->ia_type != OPTION6_IA_NA && state->ia_type != OPTION6_IA_TA)
 1578:     return 0;
 1579:   
 1580:   if (state->ia_type == OPTION6_IA_NA && opt6_len(opt) < 12)
 1581:     return 0;
 1582: 	    
 1583:   if (state->ia_type == OPTION6_IA_TA && opt6_len(opt) < 4)
 1584:     return 0;
 1585:   
 1586:   *endp = opt6_ptr(opt, opt6_len(opt));
 1587:   state->iaid = opt6_uint(opt, 0, 4);
 1588:   *ia_option = opt6_find(opt6_ptr(opt, state->ia_type == OPTION6_IA_NA ? 12 : 4), *endp, OPTION6_IAADDR, 24);
 1589: 
 1590:   return 1;
 1591: }
 1592: 
 1593: 
 1594: static int build_ia(struct state *state, int *t1cntr)
 1595: {
 1596:   int  o = new_opt6(state->ia_type);
 1597:  
 1598:   put_opt6_long(state->iaid);
 1599:   *t1cntr = 0;
 1600: 	    
 1601:   if (state->ia_type == OPTION6_IA_NA)
 1602:     {
 1603:       /* save pointer */
 1604:       *t1cntr = save_counter(-1);
 1605:       /* so we can fill these in later */
 1606:       put_opt6_long(0);
 1607:       put_opt6_long(0); 
 1608:     }
 1609: 
 1610:   return o;
 1611: }
 1612: 
 1613: static void end_ia(int t1cntr, unsigned int min_time, int do_fuzz)
 1614: {
 1615:   if (t1cntr != 0)
 1616:     {
 1617:       /* go back and fill in fields in IA_NA option */
 1618:       int sav = save_counter(t1cntr);
 1619:       unsigned int t1, t2, fuzz = 0;
 1620: 
 1621:       if (do_fuzz)
 1622: 	{
 1623: 	  fuzz = rand16();
 1624:       
 1625: 	  while (fuzz > (min_time/16))
 1626: 	    fuzz = fuzz/2;
 1627: 	}
 1628:       
 1629:       t1 = (min_time == 0xffffffff) ? 0xffffffff : min_time/2 - fuzz;
 1630:       t2 = (min_time == 0xffffffff) ? 0xffffffff : ((min_time/8)*7) - fuzz;
 1631:       put_opt6_long(t1);
 1632:       put_opt6_long(t2);
 1633:       save_counter(sav);
 1634:     }	
 1635: }
 1636: 
 1637: static void add_address(struct state *state, struct dhcp_context *context, unsigned int lease_time, void *ia_option, 
 1638: 			unsigned int *min_time, struct in6_addr *addr, time_t now)
 1639: {
 1640:   unsigned int valid_time = 0, preferred_time = 0;
 1641:   int o = new_opt6(OPTION6_IAADDR);
 1642:   struct dhcp_lease *lease;
 1643: 
 1644:   /* get client requested times */
 1645:   if (ia_option)
 1646:     {
 1647:       preferred_time =  opt6_uint(ia_option, 16, 4);
 1648:       valid_time =  opt6_uint(ia_option, 20, 4);
 1649:     }
 1650: 
 1651:   calculate_times(context, min_time, &valid_time, &preferred_time, lease_time); 
 1652:   
 1653:   put_opt6(addr, sizeof(*addr));
 1654:   put_opt6_long(preferred_time);
 1655:   put_opt6_long(valid_time); 		    
 1656:   end_opt6(o);
 1657:   
 1658:   if (state->lease_allocate)
 1659:     update_leases(state, context, addr, valid_time, now);
 1660: 
 1661:   if ((lease = lease6_find_by_addr(addr, 128, 0)))
 1662:     lease->flags |= LEASE_USED;
 1663: 
 1664:   /* get tags from context if we've not used it before */
 1665:   if (context->netid.next == &context->netid && context->netid.net)
 1666:     {
 1667:       context->netid.next = state->context_tags;
 1668:       state->context_tags = &context->netid;
 1669:       
 1670:       if (!state->hostname_auth)
 1671: 	{
 1672: 	  struct dhcp_netid_list *id_list;
 1673: 	  
 1674: 	  for (id_list = daemon->dhcp_ignore_names; id_list; id_list = id_list->next)
 1675: 	    if ((!id_list->list) || match_netid(id_list->list, &context->netid, 0))
 1676: 	      break;
 1677: 	  if (id_list)
 1678: 	    state->hostname = NULL;
 1679: 	}
 1680:     }
 1681: 
 1682:   log6_quiet(state, state->lease_allocate ? "DHCPREPLY" : "DHCPADVERTISE", addr, state->hostname);
 1683: 
 1684: }
 1685: 
 1686: static void mark_context_used(struct state *state, struct in6_addr *addr)
 1687: {
 1688:   struct dhcp_context *context;
 1689: 
 1690:   /* Mark that we have an address for this prefix. */
 1691:   for (context = state->context; context; context = context->current)
 1692:     if (is_same_net6(addr, &context->start6, context->prefix))
 1693:       context->flags |= CONTEXT_USED;
 1694: }
 1695: 
 1696: static void mark_config_used(struct dhcp_context *context, struct in6_addr *addr)
 1697: {
 1698:   for (; context; context = context->current)
 1699:     if (is_same_net6(addr, &context->start6, context->prefix))
 1700:       context->flags |= CONTEXT_CONF_USED;
 1701: }
 1702: 
 1703: /* make sure address not leased to another CLID/IAID */
 1704: static int check_address(struct state *state, struct in6_addr *addr)
 1705: { 
 1706:   struct dhcp_lease *lease;
 1707: 
 1708:   if (!(lease = lease6_find_by_addr(addr, 128, 0)))
 1709:     return 1;
 1710: 
 1711:   if (lease->clid_len != state->clid_len || 
 1712:       memcmp(lease->clid, state->clid, state->clid_len) != 0 ||
 1713:       lease->iaid != state->iaid)
 1714:     return 0;
 1715: 
 1716:   return 1;
 1717: }
 1718: 
 1719: 
 1720: /* return true of *addr could have been generated from config. */
 1721: static struct addrlist *config_implies(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr)
 1722: {
 1723:   int prefix;
 1724:   struct in6_addr wild_addr;
 1725:   struct addrlist *addr_list;
 1726:   
 1727:   if (!config || !(config->flags & CONFIG_ADDR6))
 1728:     return NULL;
 1729:   
 1730:   for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
 1731:     {
 1732:       prefix = (addr_list->flags & ADDRLIST_PREFIX) ? addr_list->prefixlen : 128;
 1733:       wild_addr = addr_list->addr.addr6;
 1734:       
 1735:       if ((addr_list->flags & ADDRLIST_WILDCARD) && context->prefix == 64)
 1736: 	{
 1737: 	  wild_addr = context->start6;
 1738: 	  setaddr6part(&wild_addr, addr6part(&addr_list->addr.addr6));
 1739: 	}
 1740:       else if (!is_same_net6(&context->start6, addr, context->prefix))
 1741: 	continue;
 1742:       
 1743:       if (is_same_net6(&wild_addr, addr, prefix))
 1744: 	return addr_list;
 1745:     }
 1746:   
 1747:   return NULL;
 1748: }
 1749: 
 1750: static int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr, struct state *state, time_t now)
 1751: {
 1752:   u64 addrpart, i, addresses;
 1753:   struct addrlist *addr_list;
 1754:   
 1755:   if (!config || !(config->flags & CONFIG_ADDR6))
 1756:     return 0;
 1757: 
 1758:   for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
 1759:     if (!(addr_list->flags & ADDRLIST_DECLINED) ||
 1760: 	difftime(now, addr_list->decline_time) >= (float)DECLINE_BACKOFF)
 1761:       {
 1762: 	addrpart = addr6part(&addr_list->addr.addr6);
 1763: 	addresses = 1;
 1764: 	
 1765: 	if (addr_list->flags & ADDRLIST_PREFIX)
 1766: 	  addresses = (u64)1<<(128-addr_list->prefixlen);
 1767: 	
 1768: 	if ((addr_list->flags & ADDRLIST_WILDCARD))
 1769: 	  {
 1770: 	    if (context->prefix != 64)
 1771: 	      continue;
 1772: 	    
 1773: 	    *addr = context->start6;
 1774: 	  }
 1775: 	else if (is_same_net6(&context->start6, &addr_list->addr.addr6, context->prefix))
 1776: 	  *addr = addr_list->addr.addr6;
 1777: 	else
 1778: 	  continue;
 1779: 	
 1780: 	for (i = 0 ; i < addresses; i++)
 1781: 	  {
 1782: 	    setaddr6part(addr, addrpart+i);
 1783: 	    
 1784: 	    if (check_address(state, addr))
 1785: 	      return 1;
 1786: 	  }
 1787:       }
 1788:   
 1789:   return 0;
 1790: }
 1791: 
 1792: /* Calculate valid and preferred times to send in leases/renewals. 
 1793: 
 1794:    Inputs are:
 1795: 
 1796:    *valid_timep, *preferred_timep - requested times from IAADDR options.
 1797:    context->valid, context->preferred - times associated with subnet address on local interface.
 1798:    context->flags | CONTEXT_DEPRECATE - "deprecated" flag in dhcp-range.
 1799:    lease_time - configured time for context for individual client.
 1800:    *min_time - smallest valid time sent so far.
 1801: 
 1802:    Outputs are :
 1803:    
 1804:    *valid_timep, *preferred_timep - times to be send in IAADDR option.
 1805:    *min_time - smallest valid time sent so far, to calculate T1 and T2.
 1806:    
 1807:    */
 1808: static void calculate_times(struct dhcp_context *context, unsigned int *min_time, unsigned int *valid_timep, 
 1809: 			    unsigned int *preferred_timep, unsigned int lease_time)
 1810: {
 1811:   unsigned int req_preferred = *preferred_timep, req_valid = *valid_timep;
 1812:   unsigned int valid_time = lease_time, preferred_time = lease_time;
 1813:   
 1814:   /* RFC 3315: "A server ignores the lifetimes set
 1815:      by the client if the preferred lifetime is greater than the valid
 1816:      lifetime. */
 1817:   if (req_preferred <= req_valid)
 1818:     {
 1819:       if (req_preferred != 0)
 1820: 	{
 1821: 	  /* 0 == "no preference from client" */
 1822: 	  if (req_preferred < 120u)
 1823: 	    req_preferred = 120u; /* sanity */
 1824: 	  
 1825: 	  if (req_preferred < preferred_time)
 1826: 	    preferred_time = req_preferred;
 1827: 	}
 1828:       
 1829:       if (req_valid != 0)
 1830: 	/* 0 == "no preference from client" */
 1831: 	{
 1832: 	  if (req_valid < 120u)
 1833: 	    req_valid = 120u; /* sanity */
 1834: 	  
 1835: 	  if (req_valid < valid_time)
 1836: 	    valid_time = req_valid;
 1837: 	}
 1838:     }
 1839: 
 1840:   /* deprecate (preferred == 0) which configured, or when local address 
 1841:      is deprecated */
 1842:   if ((context->flags & CONTEXT_DEPRECATE) || context->preferred == 0)
 1843:     preferred_time = 0;
 1844:   
 1845:   if (preferred_time != 0 && preferred_time < *min_time)
 1846:     *min_time = preferred_time;
 1847:   
 1848:   if (valid_time != 0 && valid_time < *min_time)
 1849:     *min_time = valid_time;
 1850:   
 1851:   *valid_timep = valid_time;
 1852:   *preferred_timep = preferred_time;
 1853: }
 1854: 
 1855: static void update_leases(struct state *state, struct dhcp_context *context, struct in6_addr *addr, unsigned int lease_time, time_t now)
 1856: {
 1857:   struct dhcp_lease *lease = lease6_find_by_addr(addr, 128, 0);
 1858: #ifdef HAVE_SCRIPT
 1859:   struct dhcp_netid *tagif = run_tag_if(state->tags);
 1860: #endif
 1861: 
 1862:   (void)context;
 1863: 
 1864:   if (!lease)
 1865:     lease = lease6_allocate(addr, state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA);
 1866:   
 1867:   if (lease)
 1868:     {
 1869:       lease_set_expires(lease, lease_time, now);
 1870:       lease_set_iaid(lease, state->iaid); 
 1871:       lease_set_hwaddr(lease, state->mac, state->clid, state->mac_len, state->mac_type, state->clid_len, now, 0);
 1872:       lease_set_interface(lease, state->interface, now);
 1873:       if (state->hostname && state->ia_type == OPTION6_IA_NA)
 1874: 	{
 1875: 	  char *addr_domain = get_domain6(addr);
 1876: 	  if (!state->send_domain)
 1877: 	    state->send_domain = addr_domain;
 1878: 	  lease_set_hostname(lease, state->hostname, state->hostname_auth, addr_domain, state->domain);
 1879: 	}
 1880:       
 1881: #ifdef HAVE_SCRIPT
 1882:       if (daemon->lease_change_command)
 1883: 	{
 1884: 	  void *opt;
 1885: 	  
 1886: 	  lease->flags |= LEASE_CHANGED;
 1887: 	  free(lease->extradata);
 1888: 	  lease->extradata = NULL;
 1889: 	  lease->extradata_size = lease->extradata_len = 0;
 1890: 	  lease->vendorclass_count = 0; 
 1891: 	  
 1892: 	  if ((opt = opt6_find(state->packet_options, state->end, OPTION6_VENDOR_CLASS, 4)))
 1893: 	    {
 1894: 	      void *enc_opt, *enc_end = opt6_ptr(opt, opt6_len(opt));
 1895: 	      lease->vendorclass_count++;
 1896: 	      /* send enterprise number first  */
 1897: 	      sprintf(daemon->dhcp_buff2, "%u", opt6_uint(opt, 0, 4));
 1898: 	      lease_add_extradata(lease, (unsigned char *)daemon->dhcp_buff2, strlen(daemon->dhcp_buff2), 0);
 1899: 	      
 1900: 	      if (opt6_len(opt) >= 6) 
 1901: 		for (enc_opt = opt6_ptr(opt, 4); enc_opt; enc_opt = opt6_next(enc_opt, enc_end))
 1902: 		  {
 1903: 		    lease->vendorclass_count++;
 1904: 		    lease_add_extradata(lease, opt6_ptr(enc_opt, 0), opt6_len(enc_opt), 0);
 1905: 		  }
 1906: 	    }
 1907: 	  
 1908: 	  lease_add_extradata(lease, (unsigned char *)state->client_hostname, 
 1909: 			      state->client_hostname ? strlen(state->client_hostname) : 0, 0);				
 1910: 	  
 1911: 	  /* DNSMASQ_REQUESTED_OPTIONS */
 1912: 	  if ((opt = opt6_find(state->packet_options, state->end, OPTION6_ORO, 2)))
 1913: 	    {
 1914: 	      int i, len = opt6_len(opt)/2;
 1915: 	      u16 *rop = opt6_ptr(opt, 0);
 1916: 	      
 1917: 	      for (i = 0; i < len; i++)
 1918: 		lease_add_extradata(lease, (unsigned char *)daemon->namebuff,
 1919: 				    sprintf(daemon->namebuff, "%u", ntohs(rop[i])), (i + 1) == len ? 0 : ',');
 1920: 	    }
 1921: 	  else
 1922: 	    lease_add_extradata(lease, NULL, 0, 0);
 1923: 
 1924: 	  if ((opt = opt6_find(state->packet_options, state->end, OPTION6_MUD_URL, 1)))
 1925: 	    lease_add_extradata(lease, opt6_ptr(opt, 0), opt6_len(opt), 0);
 1926: 	  else
 1927: 	    lease_add_extradata(lease, NULL, 0, 0);
 1928: 
 1929: 	  /* space-concat tag set */
 1930: 	  if (!tagif && !context->netid.net)
 1931: 	    lease_add_extradata(lease, NULL, 0, 0);
 1932: 	  else
 1933: 	    {
 1934: 	      if (context->netid.net)
 1935: 		lease_add_extradata(lease, (unsigned char *)context->netid.net, strlen(context->netid.net), tagif ? ' ' : 0);
 1936: 	      
 1937: 	      if (tagif)
 1938: 		{
 1939: 		  struct dhcp_netid *n;
 1940: 		  for (n = tagif; n; n = n->next)
 1941: 		    {
 1942: 		      struct dhcp_netid *n1;
 1943: 		      /* kill dupes */
 1944: 		      for (n1 = n->next; n1; n1 = n1->next)
 1945: 			if (strcmp(n->net, n1->net) == 0)
 1946: 			  break;
 1947: 		      if (!n1)
 1948: 			lease_add_extradata(lease, (unsigned char *)n->net, strlen(n->net), n->next ? ' ' : 0); 
 1949: 		    }
 1950: 		}
 1951: 	    }
 1952: 	  
 1953: 	  if (state->link_address)
 1954: 	    inet_ntop(AF_INET6, state->link_address, daemon->addrbuff, ADDRSTRLEN);
 1955: 	  
 1956: 	  lease_add_extradata(lease, (unsigned char *)daemon->addrbuff, state->link_address ? strlen(daemon->addrbuff) : 0, 0);
 1957: 	  
 1958: 	  if ((opt = opt6_find(state->packet_options, state->end, OPTION6_USER_CLASS, 2)))
 1959: 	    {
 1960: 	      void *enc_opt, *enc_end = opt6_ptr(opt, opt6_len(opt));
 1961: 	      for (enc_opt = opt6_ptr(opt, 0); enc_opt; enc_opt = opt6_next(enc_opt, enc_end))
 1962: 		lease_add_extradata(lease, opt6_ptr(enc_opt, 0), opt6_len(enc_opt), 0);
 1963: 	    }
 1964: 	}
 1965: #endif	
 1966:       
 1967:     }
 1968: }
 1969: 			  
 1970: 			
 1971: 	
 1972: static void log6_opts(int nest, unsigned int xid, void *start_opts, void *end_opts)
 1973: {
 1974:   void *opt;
 1975:   char *desc = nest ? "nest" : "sent";
 1976:   
 1977:   if (!option_bool(OPT_LOG_OPTS) || start_opts == end_opts)
 1978:     return;
 1979:   
 1980:   for (opt = start_opts; opt; opt = opt6_next(opt, end_opts))
 1981:     {
 1982:       int type = opt6_type(opt);
 1983:       void *ia_options = NULL;
 1984:       char *optname;
 1985:       
 1986:       if (type == OPTION6_IA_NA)
 1987: 	{
 1988: 	  sprintf(daemon->namebuff, "IAID=%u T1=%u T2=%u",
 1989: 		  opt6_uint(opt, 0, 4), opt6_uint(opt, 4, 4), opt6_uint(opt, 8, 4));
 1990: 	  optname = "ia-na";
 1991: 	  ia_options = opt6_ptr(opt, 12);
 1992: 	}
 1993:       else if (type == OPTION6_IA_TA)
 1994: 	{
 1995: 	  sprintf(daemon->namebuff, "IAID=%u", opt6_uint(opt, 0, 4));
 1996: 	  optname = "ia-ta";
 1997: 	  ia_options = opt6_ptr(opt, 4);
 1998: 	}
 1999:       else if (type == OPTION6_IAADDR)
 2000: 	{
 2001: 	  struct in6_addr addr;
 2002: 
 2003: 	  /* align */
 2004: 	  memcpy(&addr, opt6_ptr(opt, 0), IN6ADDRSZ);
 2005: 	  inet_ntop(AF_INET6, &addr, daemon->addrbuff, ADDRSTRLEN);
 2006: 	  sprintf(daemon->namebuff, "%s PL=%u VL=%u", 
 2007: 		  daemon->addrbuff, opt6_uint(opt, 16, 4), opt6_uint(opt, 20, 4));
 2008: 	  optname = "iaaddr";
 2009: 	  ia_options = opt6_ptr(opt, 24);
 2010: 	}
 2011:       else if (type == OPTION6_STATUS_CODE)
 2012: 	{
 2013: 	  int len = sprintf(daemon->namebuff, "%u ", opt6_uint(opt, 0, 2));
 2014: 	  memcpy(daemon->namebuff + len, opt6_ptr(opt, 2), opt6_len(opt)-2);
 2015: 	  daemon->namebuff[len + opt6_len(opt) - 2] = 0;
 2016: 	  optname = "status";
 2017: 	}
 2018:       else
 2019: 	{
 2020: 	  /* account for flag byte on FQDN */
 2021: 	  int offset = type == OPTION6_FQDN ? 1 : 0;
 2022: 	  optname = option_string(AF_INET6, type, opt6_ptr(opt, offset), opt6_len(opt) - offset, daemon->namebuff, MAXDNAME);
 2023: 	}
 2024:       
 2025:       my_syslog(MS_DHCP | LOG_INFO, "%u %s size:%3d option:%3d %s  %s", 
 2026: 		xid, desc, opt6_len(opt), type, optname, daemon->namebuff);
 2027:       
 2028:       if (ia_options)
 2029: 	log6_opts(1, xid, ia_options, opt6_ptr(opt, opt6_len(opt)));
 2030:     }
 2031: }		 
 2032:  
 2033: static void log6_quiet(struct state *state, char *type, struct in6_addr *addr, char *string)
 2034: {
 2035:   if (option_bool(OPT_LOG_OPTS) || !option_bool(OPT_QUIET_DHCP6))
 2036:     log6_packet(state, type, addr, string);
 2037: }
 2038: 
 2039: static void log6_packet(struct state *state, char *type, struct in6_addr *addr, char *string)
 2040: {
 2041:   int clid_len = state->clid_len;
 2042: 
 2043:   /* avoid buffer overflow */
 2044:   if (clid_len > 100)
 2045:     clid_len = 100;
 2046:   
 2047:   print_mac(daemon->namebuff, state->clid, clid_len);
 2048: 
 2049:   if (addr)
 2050:     {
 2051:       inet_ntop(AF_INET6, addr, daemon->dhcp_buff2, DHCP_BUFF_SZ - 1);
 2052:       strcat(daemon->dhcp_buff2, " ");
 2053:     }
 2054:   else
 2055:     daemon->dhcp_buff2[0] = 0;
 2056: 
 2057:   if(option_bool(OPT_LOG_OPTS))
 2058:     my_syslog(MS_DHCP | LOG_INFO, "%u %s(%s) %s%s %s",
 2059: 	      state->xid, 
 2060: 	      type,
 2061: 	      state->iface_name, 
 2062: 	      daemon->dhcp_buff2,
 2063: 	      daemon->namebuff,
 2064: 	      string ? string : "");
 2065:   else
 2066:     my_syslog(MS_DHCP | LOG_INFO, "%s(%s) %s%s %s",
 2067: 	      type,
 2068: 	      state->iface_name, 
 2069: 	      daemon->dhcp_buff2,
 2070: 	      daemon->namebuff,
 2071: 	      string ? string : "");
 2072: }
 2073: 
 2074: static void *opt6_find (void *opts, void *end, unsigned int search, unsigned int minsize)
 2075: {
 2076:   u16 opt, opt_len;
 2077:   void *start;
 2078:   
 2079:   if (!opts)
 2080:     return NULL;
 2081:     
 2082:   while (1)
 2083:     {
 2084:       if (end - opts < 4) 
 2085: 	return NULL;
 2086:       
 2087:       start = opts;
 2088:       GETSHORT(opt, opts);
 2089:       GETSHORT(opt_len, opts);
 2090:       
 2091:       if (opt_len > (end - opts))
 2092: 	return NULL;
 2093:       
 2094:       if (opt == search && (opt_len >= minsize))
 2095: 	return start;
 2096:       
 2097:       opts += opt_len;
 2098:     }
 2099: }
 2100: 
 2101: static void *opt6_next(void *opts, void *end)
 2102: {
 2103:   u16 opt_len;
 2104:   
 2105:   if (end - opts < 4) 
 2106:     return NULL;
 2107:   
 2108:   opts += 2;
 2109:   GETSHORT(opt_len, opts);
 2110:   
 2111:   if (opt_len >= (end - opts))
 2112:     return NULL;
 2113:   
 2114:   return opts + opt_len;
 2115: }
 2116: 
 2117: static unsigned int opt6_uint(unsigned char *opt, int offset, int size)
 2118: {
 2119:   /* this worries about unaligned data and byte order */
 2120:   unsigned int ret = 0;
 2121:   int i;
 2122:   unsigned char *p = opt6_ptr(opt, offset);
 2123:   
 2124:   for (i = 0; i < size; i++)
 2125:     ret = (ret << 8) | *p++;
 2126:   
 2127:   return ret;
 2128: } 
 2129: 
 2130: int relay_upstream6(int iface_index, ssize_t sz, 
 2131: 		    struct in6_addr *peer_address, u32 scope_id, time_t now)
 2132: {
 2133:   unsigned char *header;
 2134:   unsigned char *inbuff = daemon->dhcp_packet.iov_base;
 2135:   int msg_type = *inbuff;
 2136:   int hopcount, o;
 2137:   struct in6_addr multicast;
 2138:   unsigned int maclen, mactype;
 2139:   unsigned char mac[DHCP_CHADDR_MAX];
 2140:   struct dhcp_relay *relay;
 2141:   
 2142:   for (relay = daemon->relay6; relay; relay = relay->next)
 2143:     if (relay->iface_index != 0 && relay->iface_index == iface_index)
 2144:       break;
 2145: 
 2146:   /* No relay config. */
 2147:   if (!relay)
 2148:     return 0;
 2149:   
 2150:   inet_pton(AF_INET6, ALL_SERVERS, &multicast);
 2151:   get_client_mac(peer_address, scope_id, mac, &maclen, &mactype, now);
 2152:   
 2153:   /* Get hop count from nested relayed message */ 
 2154:   if (msg_type == DHCP6RELAYFORW)
 2155:     hopcount = *((unsigned char *)inbuff+1) + 1;
 2156:   else
 2157:     hopcount = 0;
 2158: 
 2159:   reset_counter();
 2160: 
 2161:   /* RFC 3315 HOP_COUNT_LIMIT */
 2162:   if (hopcount > 32 || !(header = put_opt6(NULL, 34)))
 2163:     return 1;
 2164:   
 2165:   header[0] = DHCP6RELAYFORW;
 2166:   header[1] = hopcount;
 2167:   memcpy(&header[18], peer_address, IN6ADDRSZ);
 2168:   
 2169:   /* RFC-6939 */
 2170:   if (maclen != 0)
 2171:     {
 2172:       o = new_opt6(OPTION6_CLIENT_MAC);
 2173:       put_opt6_short(mactype);
 2174:       put_opt6(mac, maclen);
 2175:       end_opt6(o);
 2176:     }
 2177:   
 2178:   o = new_opt6(OPTION6_RELAY_MSG);
 2179:   put_opt6(inbuff, sz);
 2180:   end_opt6(o);
 2181:   
 2182:   for (; relay; relay = relay->next)
 2183:     if (relay->iface_index != 0 && relay->iface_index == iface_index)
 2184:       {
 2185: 	union mysockaddr to;
 2186: 
 2187: 	memcpy(&header[2], &relay->local.addr6, IN6ADDRSZ);
 2188: 	
 2189: 	to.sa.sa_family = AF_INET6;
 2190: 	to.in6.sin6_addr = relay->server.addr6;
 2191: 	to.in6.sin6_port = htons(relay->port);
 2192: 	to.in6.sin6_flowinfo = 0;
 2193: 	to.in6.sin6_scope_id = 0;
 2194: 	
 2195: 	if (IN6_ARE_ADDR_EQUAL(&relay->server.addr6, &multicast))
 2196: 	  {
 2197: 	    int multicast_iface;
 2198: 	    if (!relay->interface || strchr(relay->interface, '*') ||
 2199: 		(multicast_iface = if_nametoindex(relay->interface)) == 0 ||
 2200: 		setsockopt(daemon->dhcp6fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &multicast_iface, sizeof(multicast_iface)) == -1)
 2201: 	      {
 2202: 		my_syslog(MS_DHCP | LOG_ERR, _("Cannot multicast DHCP relay via interface %s"), relay->interface);
 2203: 		continue;
 2204: 	      }
 2205: 	  }
 2206: 	
 2207: #ifdef HAVE_DUMPFILE
 2208: 	dump_packet_udp(DUMP_DHCPV6, (void *)daemon->outpacket.iov_base, save_counter(-1), NULL, &to, daemon->dhcp6fd);
 2209: #endif
 2210: 
 2211: 	while (retry_send(sendto(daemon->dhcp6fd, (void *)daemon->outpacket.iov_base, save_counter(-1),
 2212: 				 0, (struct sockaddr *)&to, sa_len(&to))));
 2213: 	
 2214: 	if (option_bool(OPT_LOG_OPTS))
 2215: 	  {
 2216: 	    inet_ntop(AF_INET6, &relay->local, daemon->addrbuff, ADDRSTRLEN);
 2217: 	    if (IN6_ARE_ADDR_EQUAL(&relay->server.addr6, &multicast))
 2218: 	      snprintf(daemon->namebuff, MAXDNAME, _("multicast via %s"), relay->interface);
 2219: 	    else
 2220: 	      inet_ntop(AF_INET6, &relay->server, daemon->namebuff, ADDRSTRLEN);
 2221: 	    my_syslog(MS_DHCP | LOG_INFO, _("DHCP relay at %s -> %s"), daemon->addrbuff, daemon->namebuff);
 2222: 	  }
 2223: 	
 2224:       }
 2225:   
 2226:   return 1;
 2227: }
 2228: 
 2229: int relay_reply6(struct sockaddr_in6 *peer, ssize_t sz, char *arrival_interface)
 2230: {
 2231:   struct dhcp_relay *relay;
 2232:   struct in6_addr link;
 2233:   unsigned char *inbuff = daemon->dhcp_packet.iov_base;
 2234:   
 2235:   /* must have at least msg_type+hopcount+link_address+peer_address+minimal size option
 2236:      which is               1   +    1   +    16      +     16     + 2 + 2 = 38 */
 2237:   
 2238:   if (sz < 38 || *inbuff != DHCP6RELAYREPL)
 2239:     return 0;
 2240:   
 2241:   memcpy(&link, &inbuff[2], IN6ADDRSZ); 
 2242:   
 2243:   for (relay = daemon->relay6; relay; relay = relay->next)
 2244:     if (IN6_ARE_ADDR_EQUAL(&link, &relay->local.addr6) &&
 2245: 	(!relay->interface || wildcard_match(relay->interface, arrival_interface)))
 2246:       break;
 2247:       
 2248:   reset_counter();
 2249: 
 2250:   if (relay)
 2251:     {
 2252:       void *opt, *opts = inbuff + 34;
 2253:       void *end = inbuff + sz;
 2254:       for (opt = opts; opt; opt = opt6_next(opt, end))
 2255: 	if (opt6_type(opt) == OPTION6_RELAY_MSG && opt6_len(opt) > 0)
 2256: 	  {
 2257: 	    int encap_type = *((unsigned char *)opt6_ptr(opt, 0));
 2258: 	    put_opt6(opt6_ptr(opt, 0), opt6_len(opt));
 2259: 	    memcpy(&peer->sin6_addr, &inbuff[18], IN6ADDRSZ); 
 2260: 	    peer->sin6_scope_id = relay->iface_index;
 2261: 
 2262: 	    if (encap_type == DHCP6RELAYREPL)
 2263: 	      {
 2264: 		peer->sin6_port = ntohs(DHCPV6_SERVER_PORT);
 2265: 		return 1;
 2266: 	      }
 2267: 
 2268: 	    peer->sin6_port = ntohs(DHCPV6_CLIENT_PORT);
 2269: 	    
 2270: #ifdef HAVE_SCRIPT
 2271: 	    if (daemon->lease_change_command && encap_type == DHCP6REPLY)
 2272: 	      {
 2273: 		/* decapsulate relayed message */
 2274: 		opts = opt6_ptr(opt, 4);
 2275: 		end = opt6_ptr(opt, opt6_len(opt));
 2276: 
 2277: 		for (opt = opts; opt; opt = opt6_next(opt, end))
 2278: 		  if (opt6_type(opt) == OPTION6_IA_PD && opt6_len(opt) > 12) 
 2279: 		    {
 2280: 		      void *ia_opts = opt6_ptr(opt, 12);
 2281: 		      void *ia_end = opt6_ptr(opt, opt6_len(opt));
 2282: 		      void *ia_opt;
 2283: 		      
 2284: 		      for (ia_opt = ia_opts; ia_opt; ia_opt = opt6_next(ia_opt, ia_end))
 2285: 			/* valid lifetime must not be zero. */
 2286: 			if (opt6_type(ia_opt) == OPTION6_IAPREFIX && opt6_len(ia_opt) >= 25 && opt6_uint(ia_opt, 4, 4) != 0)
 2287: 			  {
 2288: 			    if (daemon->free_snoops ||
 2289: 				(daemon->free_snoops = whine_malloc(sizeof(struct snoop_record))))
 2290: 			      {
 2291: 				struct snoop_record *snoop = daemon->free_snoops;
 2292: 				
 2293: 				daemon->free_snoops = snoop->next;
 2294: 				snoop->client = peer->sin6_addr;
 2295: 				snoop->prefix_len = opt6_uint(ia_opt, 8, 1); 
 2296: 				memcpy(&snoop->prefix, opt6_ptr(ia_opt, 9), IN6ADDRSZ); 
 2297: 				snoop->next = relay->snoop_records;
 2298: 				relay->snoop_records = snoop;
 2299: 			      }
 2300: 			  }
 2301: 		    }
 2302: 	      }
 2303: #endif		
 2304: 	    return 1;
 2305: 	  }
 2306:       
 2307:     }
 2308:   
 2309:   return 0;
 2310: }
 2311: 
 2312: #ifdef HAVE_SCRIPT
 2313: int do_snoop_script_run(void)
 2314: {
 2315:   struct dhcp_relay *relay;
 2316:   struct snoop_record *snoop;
 2317:   
 2318:   for (relay = daemon->relay6; relay; relay = relay->next)
 2319:     if ((snoop = relay->snoop_records))
 2320:       {
 2321: 	relay->snoop_records = snoop->next;
 2322: 	snoop->next = daemon->free_snoops;
 2323: 	daemon->free_snoops = snoop;
 2324: 	
 2325: 	queue_relay_snoop(&snoop->client, relay->iface_index, &snoop->prefix, snoop->prefix_len);
 2326: 	return 1;
 2327:       }
 2328:   
 2329:   return 0;
 2330: }
 2331: #endif
 2332: 
 2333: #endif

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