Annotation of embedaddon/dnsmasq/src/rfc3315.c, revision 1.1.1.1

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

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