File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dnsmasq / src / rfc3315.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 16:31:38 2014 UTC (10 years ago) by misho
Branches: elwix, dnsmasq, MAIN
CVS tags: v2_71, HEAD
dnsmasq 2.71

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

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