Diff for /embedaddon/dnsmasq/src/lease.c between versions 1.1 and 1.1.1.5

version 1.1, 2013/07/29 19:37:40 version 1.1.1.5, 2023/09/27 11:02:07
Line 1 Line 1
/* dnsmasq is Copyright (c) 2000-2013 Simon Kelley/* dnsmasq is Copyright (c) 2000-2022 Simon Kelley
   
    This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
Line 21 Line 21
 static struct dhcp_lease *leases = NULL, *old_leases = NULL;  static struct dhcp_lease *leases = NULL, *old_leases = NULL;
 static int dns_dirty, file_dirty, leases_left;  static int dns_dirty, file_dirty, leases_left;
   
void lease_init(time_t now)static int read_leases(time_t now, FILE *leasestream)
 {  {
   unsigned long ei;    unsigned long ei;
  struct all_addr addr;  union all_addr addr;
   struct dhcp_lease *lease;    struct dhcp_lease *lease;
   int clid_len, hw_len, hw_type;    int clid_len, hw_len, hw_type;
  FILE *leasestream;  int items;
    char *domain = NULL;
  leases_left = daemon->dhcp_max;
    *daemon->dhcp_buff3 = *daemon->dhcp_buff2 = '\0';
  if (option_bool(OPT_LEASE_RO))
    {  /* client-id max length is 255 which is 255*2 digits + 254 colons
      /* run "<lease_change_script> init" once to get the     borrow DNS packet buffer which is always larger than 1000 bytes
         initial state of the database. If leasefile-ro is
         set without a script, we just do without any      Check various buffers are big enough for the code below */
         lease database. */
#ifdef HAVE_SCRIPT#if (DHCP_BUFF_SZ < 255) || (MAXDNAME < 64) || (PACKETSZ+MAXDNAME+RRFIXEDSZ  < 764)
      if (daemon->lease_change_command)# error Buffer size breakage in leasefile parsing.
        { 
          strcpy(daemon->dhcp_buff, daemon->lease_change_command); 
          strcat(daemon->dhcp_buff, " init"); 
          leasestream = popen(daemon->dhcp_buff, "r"); 
        } 
      else 
 #endif  #endif
         {  
           file_dirty = dns_dirty = 0;  
           return;  
         }  
   
    }    while ((items=fscanf(leasestream, "%255s %255s", daemon->dhcp_buff3, daemon->dhcp_buff2)) == 2)
  else 
    { 
      /* NOTE: need a+ mode to create file if it doesn't exist */ 
      leasestream = daemon->lease_stream = fopen(daemon->lease_file, "a+"); 
       
      if (!leasestream) 
        die(_("cannot open or create lease file %s: %s"), daemon->lease_file, EC_FILE); 
       
      /* a+ mode leaves pointer at end. */ 
      rewind(leasestream); 
    } 
   
  /* client-id max length is 255 which is 255*2 digits + 254 colons  
     borrow DNS packet buffer which is always larger than 1000 bytes */ 
  if (leasestream) 
    while (fscanf(leasestream, "%255s %255s", daemon->dhcp_buff3, daemon->dhcp_buff2) == 2) 
       {        {
           *daemon->namebuff = *daemon->dhcp_buff = *daemon->packet = '\0';
           hw_len = hw_type = clid_len = 0;
           
 #ifdef HAVE_DHCP6  #ifdef HAVE_DHCP6
         if (strcmp(daemon->dhcp_buff3, "duid") == 0)          if (strcmp(daemon->dhcp_buff3, "duid") == 0)
           {            {
             daemon->duid_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, 130, NULL, NULL);              daemon->duid_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, 130, NULL, NULL);
               if (daemon->duid_len < 0)
                 return 0;
             daemon->duid = safe_malloc(daemon->duid_len);              daemon->duid = safe_malloc(daemon->duid_len);
             memcpy(daemon->duid, daemon->dhcp_buff2, daemon->duid_len);              memcpy(daemon->duid, daemon->dhcp_buff2, daemon->duid_len);
             continue;              continue;
           }            }
 #endif  #endif
   
         ei = atol(daemon->dhcp_buff3);  
                   
         if (fscanf(leasestream, " %64s %255s %764s",          if (fscanf(leasestream, " %64s %255s %764s",
                    daemon->namebuff, daemon->dhcp_buff, daemon->packet) != 3)                     daemon->namebuff, daemon->dhcp_buff, daemon->packet) != 3)
           break;  
           
         clid_len = 0;  
         if (strcmp(daemon->packet, "*") != 0)  
           clid_len = parse_hex(daemon->packet, (unsigned char *)daemon->packet, 255, NULL, NULL);  
           
         if (inet_pton(AF_INET, daemon->namebuff, &addr.addr.addr4) &&  
             (lease = lease4_allocate(addr.addr.addr4)))  
           {            {
               my_syslog(MS_DHCP | LOG_WARNING, _("ignoring invalid line in lease database: %s %s %s %s ..."),
                         daemon->dhcp_buff3, daemon->dhcp_buff2,
                         daemon->namebuff, daemon->dhcp_buff);
               continue;
             }
                   
           if (inet_pton(AF_INET, daemon->namebuff, &addr.addr4))
             {
               if ((lease = lease4_allocate(addr.addr4)))
                 domain = get_domain(lease->addr);
               
             hw_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, DHCP_CHADDR_MAX, NULL, &hw_type);              hw_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, DHCP_CHADDR_MAX, NULL, &hw_type);
            /* For backwards compatibility, no explict MAC address type means ether. */            /* For backwards compatibility, no explicit MAC address type means ether. */
             if (hw_type == 0 && hw_len != 0)              if (hw_type == 0 && hw_len != 0)
               hw_type = ARPHRD_ETHER;                 hw_type = ARPHRD_ETHER; 
   
             lease_set_hwaddr(lease, (unsigned char *)daemon->dhcp_buff2, (unsigned char *)daemon->packet,   
                              hw_len, hw_type, clid_len, now, 0);  
               
             if (strcmp(daemon->dhcp_buff, "*") !=  0)  
               lease_set_hostname(lease, daemon->dhcp_buff, 0, get_domain(lease->addr), NULL);  
           }            }
 #ifdef HAVE_DHCP6  #ifdef HAVE_DHCP6
        else if (inet_pton(AF_INET6, daemon->namebuff, &addr.addr.addr6))        else if (inet_pton(AF_INET6, daemon->namebuff, &addr.addr6))
           {            {
             char *s = daemon->dhcp_buff2;              char *s = daemon->dhcp_buff2;
             int lease_type = LEASE_NA;              int lease_type = LEASE_NA;
Line 115  void lease_init(time_t now) Line 89  void lease_init(time_t now)
                 s++;                  s++;
               }                }
                           
            hw_type = strtoul(s, NULL, 10);            if ((lease = lease6_allocate(&addr.addr6, lease_type)))
             
            if ((lease = lease6_allocate(&addr.addr.addr6, lease_type))) 
               {                {
                lease_set_hwaddr(lease, NULL, (unsigned char *)daemon->packet, 0, hw_type, clid_len, now, 0);                lease_set_iaid(lease, strtoul(s, NULL, 10));
                                domain = get_domain6(&lease->addr6);
                if (strcmp(daemon->dhcp_buff, "*") !=  0) 
                  lease_set_hostname(lease, daemon->dhcp_buff, 0, get_domain6((struct in6_addr *)lease->hwaddr), NULL); 
               }                }
           }            }
 #endif  #endif
         else          else
          break;          {
             my_syslog(MS_DHCP | LOG_WARNING, _("ignoring invalid line in lease database, bad address: %s"),
                       daemon->namebuff);
             continue;
           }
         
   
         if (!lease)          if (!lease)
           die (_("too many stored leases"), NULL, EC_MISC);            die (_("too many stored leases"), NULL, EC_MISC);
        
         if (strcmp(daemon->packet, "*") != 0)
           clid_len = parse_hex(daemon->packet, (unsigned char *)daemon->packet, 255, NULL, NULL);
         
         lease_set_hwaddr(lease, (unsigned char *)daemon->dhcp_buff2, (unsigned char *)daemon->packet, 
                          hw_len, hw_type, clid_len, now, 0);
         
         if (strcmp(daemon->dhcp_buff, "*") !=  0)
           lease_set_hostname(lease, daemon->dhcp_buff, 0, domain, NULL);
 
         ei = atol(daemon->dhcp_buff3);
 
 #ifdef HAVE_BROKEN_RTC  #ifdef HAVE_BROKEN_RTC
         if (ei != 0)          if (ei != 0)
           lease->expires = (time_t)ei + now;            lease->expires = (time_t)ei + now;
Line 147  void lease_init(time_t now) Line 133  void lease_init(time_t now)
         /* set these correctly: the "old" events are generated later from          /* set these correctly: the "old" events are generated later from
            the startup synthesised SIGHUP. */             the startup synthesised SIGHUP. */
         lease->flags &= ~(LEASE_NEW | LEASE_CHANGED);          lease->flags &= ~(LEASE_NEW | LEASE_CHANGED);
           
           *daemon->dhcp_buff3 = *daemon->dhcp_buff2 = '\0';
       }        }
       
       return (items == 0 || items == EOF);
   }
   
   void lease_init(time_t now)
   {
     FILE *leasestream;
   
     leases_left = daemon->dhcp_max;
   
     if (option_bool(OPT_LEASE_RO))
       {
         /* run "<lease_change_script> init" once to get the
            initial state of the database. If leasefile-ro is
            set without a script, we just do without any
            lease database. */
   #ifdef HAVE_SCRIPT
         if (daemon->lease_change_command)
           {
             strcpy(daemon->dhcp_buff, daemon->lease_change_command);
             strcat(daemon->dhcp_buff, " init");
             leasestream = popen(daemon->dhcp_buff, "r");
           }
         else
   #endif
           {
             file_dirty = dns_dirty = 0;
             return;
           }
   
       }
     else
       {
         /* NOTE: need a+ mode to create file if it doesn't exist */
         leasestream = daemon->lease_stream = fopen(daemon->lease_file, "a+");
   
         if (!leasestream)
           die(_("cannot open or create lease file %s: %s"), daemon->lease_file, EC_FILE);
   
         /* a+ mode leaves pointer at end. */
         rewind(leasestream);
       }
   
     if (leasestream)
       {
         if (!read_leases(now, leasestream))
           my_syslog(MS_DHCP | LOG_ERR, _("failed to parse lease database cleanly"));
         
         if (ferror(leasestream))
           die(_("failed to read lease file %s: %s"), daemon->lease_file, EC_FILE);
       }
       
 #ifdef HAVE_SCRIPT  #ifdef HAVE_SCRIPT
   if (!daemon->lease_stream)    if (!daemon->lease_stream)
Line 161  void lease_init(time_t now) Line 200  void lease_init(time_t now)
             errno = ENOENT;              errno = ENOENT;
           else if (WEXITSTATUS(rc) == 126)            else if (WEXITSTATUS(rc) == 126)
             errno = EACCES;              errno = EACCES;
   
           die(_("cannot run lease-init script %s: %s"), daemon->lease_change_command, EC_FILE);            die(_("cannot run lease-init script %s: %s"), daemon->lease_change_command, EC_FILE);
         }          }
               
Line 187  void lease_update_from_configs(void) Line 227  void lease_update_from_configs(void)
   char *name;    char *name;
       
   for (lease = leases; lease; lease = lease->next)    for (lease = leases; lease; lease = lease->next)
    if ((config = find_config(daemon->dhcp_conf, NULL, lease->clid, lease->clid_len,     if (lease->flags & (LEASE_TA | LEASE_NA))
                              lease->hwaddr, lease->hwaddr_len, lease->hwaddr_type, NULL)) &&       continue;
        (config->flags & CONFIG_NAME) &&    else if ((config = find_config(daemon->dhcp_conf, NULL, lease->clid, lease->clid_len, 
        (!(config->flags & CONFIG_ADDR) || config->addr.s_addr == lease->addr.s_addr))                                   lease->hwaddr, lease->hwaddr_len, lease->hwaddr_type, NULL, NULL)) && 
              (config->flags & CONFIG_NAME) &&
              (!(config->flags & CONFIG_ADDR) || config->addr.s_addr == lease->addr.s_addr))
       lease_set_hostname(lease, config->hostname, 1, get_domain(lease->addr), NULL);        lease_set_hostname(lease, config->hostname, 1, get_domain(lease->addr), NULL);
     else if ((name = host_from_dns(lease->addr)))      else if ((name = host_from_dns(lease->addr)))
       lease_set_hostname(lease, name, 1, get_domain(lease->addr), NULL); /* updates auth flag only */        lease_set_hostname(lease, name, 1, get_domain(lease->addr), NULL); /* updates auth flag only */
 }  }
 
 static void ourprintf(int *errp, char *format, ...)  static void ourprintf(int *errp, char *format, ...)
 {  {
   va_list ap;    va_list ap;
Line 277  void lease_update_file(time_t now) Line 319  void lease_update_file(time_t now)
               ourprintf(&err, "%lu ", (unsigned long)lease->expires);                ourprintf(&err, "%lu ", (unsigned long)lease->expires);
 #endif  #endif
           
              inet_ntop(AF_INET6, lease->hwaddr, daemon->addrbuff, ADDRSTRLEN);              inet_ntop(AF_INET6, &lease->addr6, daemon->addrbuff, ADDRSTRLEN);
                     
               ourprintf(&err, "%s%u %s ", (lease->flags & LEASE_TA) ? "T" : "",                ourprintf(&err, "%s%u %s ", (lease->flags & LEASE_TA) ? "T" : "",
                        lease->hwaddr_type, daemon->addrbuff);                        lease->iaid, daemon->addrbuff);
               ourprintf(&err, "%s ", lease->hostname ? lease->hostname : "*");                ourprintf(&err, "%s ", lease->hostname ? lease->hostname : "*");
                               
               if (lease->clid && lease->clid_len != 0)                if (lease->clid && lease->clid_len != 0)
Line 303  void lease_update_file(time_t now) Line 345  void lease_update_file(time_t now)
         file_dirty = 0;          file_dirty = 0;
     }      }
       
  /* Set alarm for when the first lease expires + slop. */  /* Set alarm for when the first lease expires. */
   next_event = 0;    next_event = 0;
   
 #ifdef HAVE_DHCP6  #ifdef HAVE_DHCP6
Line 328  void lease_update_file(time_t now) Line 370  void lease_update_file(time_t now)
   
   for (lease = leases; lease; lease = lease->next)    for (lease = leases; lease; lease = lease->next)
     if (lease->expires != 0 &&      if (lease->expires != 0 &&
        (next_event == 0 || difftime(next_event, lease->expires + 10) > 0.0))        (next_event == 0 || difftime(next_event, lease->expires) > 0.0))
      next_event = lease->expires + 10;      next_event = lease->expires;
         
   if (err)    if (err)
     {      {
       if (next_event == 0 || difftime(next_event, LEASE_RETRY + now) > 0.0)        if (next_event == 0 || difftime(next_event, LEASE_RETRY + now) > 0.0)
         next_event = LEASE_RETRY + now;          next_event = LEASE_RETRY + now;
               
      my_syslog(MS_DHCP | LOG_ERR, _("failed to write %s: %s (retry in %us)"),       my_syslog(MS_DHCP | LOG_ERR, _("failed to write %s: %s (retry in %u s)"), 
                 daemon->lease_file, strerror(err),                  daemon->lease_file, strerror(err),
                 (unsigned int)difftime(next_event, now));                  (unsigned int)difftime(next_event, now));
     }      }
Line 345  void lease_update_file(time_t now) Line 387  void lease_update_file(time_t now)
 }  }
   
   
static int find_interface_v4(struct in_addr local, int if_index, static int find_interface_v4(struct in_addr local, int if_index, char *label,
                              struct in_addr netmask, struct in_addr broadcast, void *vparam)                               struct in_addr netmask, struct in_addr broadcast, void *vparam)
 {  {
   struct dhcp_lease *lease;    struct dhcp_lease *lease;
    int prefix = netmask_length(netmask);
 
   (void) label;
   (void) broadcast;    (void) broadcast;
   (void) vparam;    (void) vparam;
   
   for (lease = leases; lease; lease = lease->next)    for (lease = leases; lease; lease = lease->next)
    if (!(lease->flags & (LEASE_TA | LEASE_NA)))    if (!(lease->flags & (LEASE_TA | LEASE_NA)) &&
      if (is_same_net(local, lease->addr, netmask))        is_same_net(local, lease->addr, netmask) && 
        lease_set_interface(lease, if_index, *((time_t *)vparam));        prefix > lease->new_prefixlen) 
        {
         lease->new_interface = if_index;
         lease->new_prefixlen = prefix;
       }
 
   return 1;    return 1;
 }  }
   
Line 367  static int find_interface_v6(struct in6_addr *local,   Line 415  static int find_interface_v6(struct in6_addr *local,  
                              int preferred, int valid, void *vparam)                               int preferred, int valid, void *vparam)
 {  {
   struct dhcp_lease *lease;    struct dhcp_lease *lease;
  
   (void)scope;    (void)scope;
   (void)flags;    (void)flags;
   (void)preferred;    (void)preferred;
   (void)valid;    (void)valid;
     (void)vparam;
   
   for (lease = leases; lease; lease = lease->next)    for (lease = leases; lease; lease = lease->next)
     if ((lease->flags & (LEASE_TA | LEASE_NA)))      if ((lease->flags & (LEASE_TA | LEASE_NA)))
      if (is_same_net6(local, (struct in6_addr *)&lease->hwaddr, prefix))      if (is_same_net6(local, &lease->addr6, prefix) && prefix > lease->new_prefixlen) {
        lease_set_interface(lease, if_index, *((time_t *)vparam));        /* save prefix length for comparison, as we might get shorter matching
           * prefix in upcoming netlink GETADDR responses
          * */
         lease->new_interface = if_index;
         lease->new_prefixlen = prefix;
       }
 
   return 1;    return 1;
 }  }
   
Line 391  void lease_ping_reply(struct in6_addr *sender, unsigne Line 445  void lease_ping_reply(struct in6_addr *sender, unsigne
   
 void lease_update_slaac(time_t now)  void lease_update_slaac(time_t now)
 {  {
  /* Called when we contruct a new RA-names context, to add putative  /* Called when we construct a new RA-names context, to add putative
      new SLAAC addresses to existing leases. */       new SLAAC addresses to existing leases. */
   
   struct dhcp_lease *lease;    struct dhcp_lease *lease;
Line 410  void lease_update_slaac(time_t now) Line 464  void lease_update_slaac(time_t now)
    start-time. */     start-time. */
 void lease_find_interfaces(time_t now)  void lease_find_interfaces(time_t now)
 {  {
     struct dhcp_lease *lease;
     
     for (lease = leases; lease; lease = lease->next)
       lease->new_prefixlen = lease->new_interface = 0;
   
   iface_enumerate(AF_INET, &now, find_interface_v4);    iface_enumerate(AF_INET, &now, find_interface_v4);
 #ifdef HAVE_DHCP6  #ifdef HAVE_DHCP6
   iface_enumerate(AF_INET6, &now, find_interface_v6);    iface_enumerate(AF_INET6, &now, find_interface_v6);
   #endif
   
     for (lease = leases; lease; lease = lease->next)
       if (lease->new_interface != 0) 
         lease_set_interface(lease, lease->new_interface, now);
   }
   
   #ifdef HAVE_DHCP6
   void lease_make_duid(time_t now)
   {
   /* If we're not doing DHCPv6, and there are not v6 leases, don't add the DUID to the database */    /* If we're not doing DHCPv6, and there are not v6 leases, don't add the DUID to the database */
  if (!daemon->duid && daemon->dhcp6)  if (!daemon->duid && daemon->doing_dhcp6)
     {      {
       file_dirty = 1;        file_dirty = 1;
       make_duid(now);        make_duid(now);
     }      }
 #endif  
 }  }
   #endif
   
   
   
   
 void lease_update_dns(int force)  void lease_update_dns(int force)
 {  {
   struct dhcp_lease *lease;    struct dhcp_lease *lease;
Line 453  void lease_update_dns(int force) Line 522  void lease_update_dns(int force)
                 if (slaac->backoff == 0)                  if (slaac->backoff == 0)
                   {                    {
                     if (lease->fqdn)                      if (lease->fqdn)
                      cache_add_dhcp_entry(lease->fqdn, AF_INET6, (struct all_addr *)&slaac->addr, lease->expires);                      cache_add_dhcp_entry(lease->fqdn, AF_INET6, (union all_addr *)&slaac->addr, lease->expires);
                     if (!option_bool(OPT_DHCP_FQDN) && lease->hostname)                      if (!option_bool(OPT_DHCP_FQDN) && lease->hostname)
                      cache_add_dhcp_entry(lease->hostname, AF_INET6, (struct all_addr *)&slaac->addr, lease->expires);                      cache_add_dhcp_entry(lease->hostname, AF_INET6, (union all_addr *)&slaac->addr, lease->expires);
                   }                    }
             }              }
 #endif  
                       
           if (lease->fqdn)            if (lease->fqdn)
             cache_add_dhcp_entry(lease->fqdn, prot,               cache_add_dhcp_entry(lease->fqdn, prot, 
                                 prot == AF_INET ? (struct all_addr *)&lease->addr : (struct all_addr *)&lease->hwaddr,                                 prot == AF_INET ? (union all_addr *)&lease->addr : (union all_addr *)&lease->addr6,
                                  lease->expires);                                   lease->expires);
                             
           if (!option_bool(OPT_DHCP_FQDN) && lease->hostname)            if (!option_bool(OPT_DHCP_FQDN) && lease->hostname)
             cache_add_dhcp_entry(lease->hostname, prot,               cache_add_dhcp_entry(lease->hostname, prot, 
                                 prot == AF_INET ? (struct all_addr *)&lease->addr : (struct all_addr *)&lease->hwaddr                                 prot == AF_INET ? (union all_addr *)&lease->addr : (union all_addr *)&lease->addr6, 
                                  lease->expires);                                   lease->expires);
          
   #else
             if (lease->fqdn)
               cache_add_dhcp_entry(lease->fqdn, prot, (union all_addr *)&lease->addr, lease->expires);
             
             if (!option_bool(OPT_DHCP_FQDN) && lease->hostname)
               cache_add_dhcp_entry(lease->hostname, prot, (union all_addr *)&lease->addr, lease->expires);
   #endif
         }          }
               
       dns_dirty = 0;        dns_dirty = 0;
Line 482  void lease_prune(struct dhcp_lease *target, time_t now Line 558  void lease_prune(struct dhcp_lease *target, time_t now
   for (lease = leases, up = &leases; lease; lease = tmp)    for (lease = leases, up = &leases; lease; lease = tmp)
     {      {
       tmp = lease->next;        tmp = lease->next;
      if ((lease->expires != 0 && difftime(now, lease->expires) > 0) || lease == target)      if ((lease->expires != 0 && difftime(now, lease->expires) >= 0) || lease == target)
         {          {
           file_dirty = 1;            file_dirty = 1;
           if (lease->hostname)            if (lease->hostname)
             dns_dirty = 1;              dns_dirty = 1;
          
           daemon->metrics[lease->addr.s_addr ? METRIC_LEASES_PRUNED_4 : METRIC_LEASES_PRUNED_6]++;
 
           *up = lease->next; /* unlink */            *up = lease->next; /* unlink */
                       
           /* Put on old_leases list 'till we            /* Put on old_leases list 'till we
Line 557  struct dhcp_lease *lease_find_by_addr(struct in_addr a Line 635  struct dhcp_lease *lease_find_by_addr(struct in_addr a
 #ifdef HAVE_DHCP6  #ifdef HAVE_DHCP6
 /* find address for {CLID, IAID, address} */  /* find address for {CLID, IAID, address} */
 struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len,   struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len, 
                               int lease_type, int iaid, struct in6_addr *addr)                               int lease_type, unsigned int iaid,
                                struct in6_addr *addr)
 {  {
   struct dhcp_lease *lease;    struct dhcp_lease *lease;
       
   for (lease = leases; lease; lease = lease->next)    for (lease = leases; lease; lease = lease->next)
     {      {
      if (!(lease->flags & lease_type) || lease->hwaddr_type != iaid)      if (!(lease->flags & lease_type) || lease->iaid != iaid)
         continue;          continue;
   
      if (memcmp(lease->hwaddr, addr, IN6ADDRSZ) != 0)      if (!IN6_ARE_ADDR_EQUAL(&lease->addr6, addr))
         continue;          continue;
               
       if ((clid_len != lease->clid_len ||        if ((clid_len != lease->clid_len ||
Line 589  void lease6_reset(void) Line 668  void lease6_reset(void)
 }  }
   
 /* enumerate all leases belonging to {CLID, IAID} */  /* enumerate all leases belonging to {CLID, IAID} */
struct dhcp_lease *lease6_find_by_client(struct dhcp_lease *first, int lease_type, unsigned char *clid, int clid_len, int iaid)struct dhcp_lease *lease6_find_by_client(struct dhcp_lease *first, int lease_type,
                                          unsigned char *clid, int clid_len,
                                          unsigned int iaid)
 {  {
   struct dhcp_lease *lease;    struct dhcp_lease *lease;
   
Line 603  struct dhcp_lease *lease6_find_by_client(struct dhcp_l Line 684  struct dhcp_lease *lease6_find_by_client(struct dhcp_l
       if (lease->flags & LEASE_USED)        if (lease->flags & LEASE_USED)
         continue;          continue;
   
      if (!(lease->flags & lease_type) || lease->hwaddr_type != iaid)      if (!(lease->flags & lease_type) || lease->iaid != iaid)
         continue;          continue;
     
       if ((clid_len != lease->clid_len ||        if ((clid_len != lease->clid_len ||
Line 625  struct dhcp_lease *lease6_find_by_addr(struct in6_addr Line 706  struct dhcp_lease *lease6_find_by_addr(struct in6_addr
       if (!(lease->flags & (LEASE_TA | LEASE_NA)))        if (!(lease->flags & (LEASE_TA | LEASE_NA)))
         continue;          continue;
               
      if (is_same_net6((struct in6_addr *)lease->hwaddr, net, prefix) &&      if (is_same_net6(&lease->addr6, net, prefix) &&
          (prefix == 128 || addr6part((struct in6_addr *)lease->hwaddr) == addr))          (prefix == 128 || addr6part(&lease->addr6) == addr))
         return lease;          return lease;
     }      }
       
Line 645  u64 lease_find_max_addr6(struct dhcp_context *context) Line 726  u64 lease_find_max_addr6(struct dhcp_context *context)
         if (!(lease->flags & (LEASE_TA | LEASE_NA)))          if (!(lease->flags & (LEASE_TA | LEASE_NA)))
           continue;            continue;
   
        if (is_same_net6((struct in6_addr *)lease->hwaddr, &context->start6, 64) &&        if (is_same_net6(&lease->addr6, &context->start6, 64) &&
            addr6part((struct in6_addr *)lease->hwaddr) > addr6part(&context->start6) &&            addr6part(&lease->addr6) > addr6part(&context->start6) &&
            addr6part((struct in6_addr *)lease->hwaddr) <= addr6part(&context->end6) &&            addr6part(&lease->addr6) <= addr6part(&context->end6) &&
            addr6part((struct in6_addr *)lease->hwaddr) > addr)            addr6part(&lease->addr6) > addr)
          addr = addr6part((struct in6_addr *)lease->hwaddr);          addr = addr6part(&lease->addr6);
       }        }
       
   return addr;    return addr;
Line 691  static struct dhcp_lease *lease_allocate(void) Line 772  static struct dhcp_lease *lease_allocate(void)
 #ifdef HAVE_BROKEN_RTC  #ifdef HAVE_BROKEN_RTC
   lease->length = 0xffffffff; /* illegal value */    lease->length = 0xffffffff; /* illegal value */
 #endif  #endif
     lease->hwaddr_len = 256; /* illegal value */
   lease->next = leases;    lease->next = leases;
   leases = lease;    leases = lease;
       
Line 706  struct dhcp_lease *lease4_allocate(struct in_addr addr Line 788  struct dhcp_lease *lease4_allocate(struct in_addr addr
   if (lease)    if (lease)
     {      {
       lease->addr = addr;        lease->addr = addr;
      lease->hwaddr_len = 256; /* illegal value */      daemon->metrics[METRIC_LEASES_ALLOCATED_4]++;
     }      }
  
   return lease;    return lease;
 }  }
   
Line 719  struct dhcp_lease *lease6_allocate(struct in6_addr *ad Line 801  struct dhcp_lease *lease6_allocate(struct in6_addr *ad
   
   if (lease)    if (lease)
     {      {
      memcpy(lease->hwaddr, addrp, sizeof(*addrp)) ;      lease->addr6 = *addrp;
       lease->flags |= lease_type;        lease->flags |= lease_type;
         lease->iaid = 0;
   
         daemon->metrics[METRIC_LEASES_ALLOCATED_6]++;
     }      }
   
   return lease;    return lease;
Line 729  struct dhcp_lease *lease6_allocate(struct in6_addr *ad Line 814  struct dhcp_lease *lease6_allocate(struct in6_addr *ad
   
 void lease_set_expires(struct dhcp_lease *lease, unsigned int len, time_t now)  void lease_set_expires(struct dhcp_lease *lease, unsigned int len, time_t now)
 {  {
  time_t exp = now + (time_t)len;  time_t exp;
  
   if (len == 0xffffffff)    if (len == 0xffffffff)
     {      {
       exp = 0;        exp = 0;
       len = 0;        len = 0;
     }      }
    else
     {
       exp = now + (time_t)len;
       /* Check for 2038 overflow. Make the lease
          infinite in that case, as the least disruptive
          thing we can do. */
       if (difftime(exp, now) <= 0.0)
         exp = 0;
     }
 
   if (exp != lease->expires)    if (exp != lease->expires)
     {      {
       dns_dirty = 1;        dns_dirty = 1;
       lease->expires = exp;        lease->expires = exp;
 #ifndef HAVE_BROKEN_RTC  #ifndef HAVE_BROKEN_RTC
      lease->flags |= LEASE_AUX_CHANGED;      lease->flags |= LEASE_AUX_CHANGED | LEASE_EXP_CHANGED;
       file_dirty = 1;        file_dirty = 1;
 #endif  #endif
     }      }
Line 757  void lease_set_expires(struct dhcp_lease *lease, unsig Line 851  void lease_set_expires(struct dhcp_lease *lease, unsig
 #endif  #endif
 }   } 
   
void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,#ifdef HAVE_DHCP6
                      unsigned char *clid, int hw_len, int hw_type, int clid_len, void lease_set_iaid(struct dhcp_lease *lease, unsigned int iaid)
                      time_t now, int force) 
 {  {
     if (lease->iaid != iaid)
       {
         lease->iaid = iaid;
         lease->flags |= LEASE_CHANGED;
       }
   }
   #endif
   
   void lease_set_hwaddr(struct dhcp_lease *lease, const unsigned char *hwaddr,
                         const unsigned char *clid, int hw_len, int hw_type,
                         int clid_len, time_t now, int force)
   {
 #ifdef HAVE_DHCP6  #ifdef HAVE_DHCP6
   int change = force;    int change = force;
   lease->flags |= LEASE_HAVE_HWADDR;    lease->flags |= LEASE_HAVE_HWADDR;
 #endif  #endif
   
   (void)force;    (void)force;
     (void)now;
   
   if (hw_len != lease->hwaddr_len ||    if (hw_len != lease->hwaddr_len ||
       hw_type != lease->hwaddr_type ||         hw_type != lease->hwaddr_type || 
Line 778  void lease_set_hwaddr(struct dhcp_lease *lease, unsign Line 884  void lease_set_hwaddr(struct dhcp_lease *lease, unsign
       lease->hwaddr_type = hw_type;        lease->hwaddr_type = hw_type;
       lease->flags |= LEASE_CHANGED;        lease->flags |= LEASE_CHANGED;
       file_dirty = 1; /* run script on change */        file_dirty = 1; /* run script on change */
 #ifdef HAVE_DHCP6  
       change = 1;  
 #endif  
     }      }
   
   /* only update clid when one is available, stops packets    /* only update clid when one is available, stops packets
Line 843  static void kill_name(struct dhcp_lease *lease) Line 946  static void kill_name(struct dhcp_lease *lease)
   lease->hostname = lease->fqdn = NULL;    lease->hostname = lease->fqdn = NULL;
 }  }
   
void lease_set_hostname(struct dhcp_lease *lease, char *name, int auth, char *domain, char *config_domain)void lease_set_hostname(struct dhcp_lease *lease, const char *name, int auth, char *domain, char *config_domain)
 {  {
   struct dhcp_lease *lease_tmp;    struct dhcp_lease *lease_tmp;
   char *new_name = NULL, *new_fqdn = NULL;    char *new_name = NULL, *new_fqdn = NULL;
Line 918  void lease_set_hostname(struct dhcp_lease *lease, char Line 1021  void lease_set_hostname(struct dhcp_lease *lease, char
             }              }
                   
           kill_name(lease_tmp);            kill_name(lease_tmp);
             lease_tmp->flags |= LEASE_CHANGED; /* run script on change */
           break;            break;
         }          }
     }      }
Line 938  void lease_set_hostname(struct dhcp_lease *lease, char Line 1042  void lease_set_hostname(struct dhcp_lease *lease, char
   
 void lease_set_interface(struct dhcp_lease *lease, int interface, time_t now)  void lease_set_interface(struct dhcp_lease *lease, int interface, time_t now)
 {  {
     (void)now;
   
   if (lease->last_interface == interface)    if (lease->last_interface == interface)
     return;      return;
   
Line 966  int do_script_run(time_t now) Line 1072  int do_script_run(time_t now)
 {  {
   struct dhcp_lease *lease;    struct dhcp_lease *lease;
   
     (void)now;
   
 #ifdef HAVE_DBUS  #ifdef HAVE_DBUS
   /* If we're going to be sending DBus signals, but the connection is not yet up,    /* If we're going to be sending DBus signals, but the connection is not yet up,
      delay everything until it is. */       delay everything until it is. */
Line 1029  int do_script_run(time_t now) Line 1137  int do_script_run(time_t now)
       
   for (lease = leases; lease; lease = lease->next)    for (lease = leases; lease; lease = lease->next)
     if ((lease->flags & (LEASE_NEW | LEASE_CHANGED)) ||       if ((lease->flags & (LEASE_NEW | LEASE_CHANGED)) || 
        ((lease->flags & LEASE_AUX_CHANGED) && option_bool(OPT_LEASE_RO)))        ((lease->flags & LEASE_AUX_CHANGED) && option_bool(OPT_LEASE_RO)) ||
         ((lease->flags & LEASE_EXP_CHANGED) && option_bool(OPT_LEASE_RENEW)))
       {        {
 #ifdef HAVE_SCRIPT  #ifdef HAVE_SCRIPT
         queue_script((lease->flags & LEASE_NEW) ? ACTION_ADD : ACTION_OLD, lease,           queue_script((lease->flags & LEASE_NEW) ? ACTION_ADD : ACTION_OLD, lease, 
Line 1039  int do_script_run(time_t now) Line 1148  int do_script_run(time_t now)
         emit_dbus_signal((lease->flags & LEASE_NEW) ? ACTION_ADD : ACTION_OLD, lease,          emit_dbus_signal((lease->flags & LEASE_NEW) ? ACTION_ADD : ACTION_OLD, lease,
                          lease->fqdn ? lease->fqdn : lease->hostname);                           lease->fqdn ? lease->fqdn : lease->hostname);
 #endif  #endif
        lease->flags &= ~(LEASE_NEW | LEASE_CHANGED | LEASE_AUX_CHANGED);        lease->flags &= ~(LEASE_NEW | LEASE_CHANGED | LEASE_AUX_CHANGED | LEASE_EXP_CHANGED);
                   
         /* this is used for the "add" call, then junked, since they're not in the database */          /* this is used for the "add" call, then junked, since they're not in the database */
         free(lease->extradata);          free(lease->extradata);
Line 1052  int do_script_run(time_t now) Line 1161  int do_script_run(time_t now)
 }  }
   
 #ifdef HAVE_SCRIPT  #ifdef HAVE_SCRIPT
   /* delim == -1 -> delim = 0, but embedded 0s, creating extra records, are OK. */
 void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data, unsigned int len, int delim)  void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data, unsigned int len, int delim)
 {  {
   unsigned int i;    unsigned int i;
       
  /* check for embeded NULLs */  if (delim == -1)
  for (i = 0; i < len; i++)    delim = 0;
    if (data[i] == 0)  else
      {    /* check for embedded NULLs */
        len = i;    for (i = 0; i < len; i++)
        break;      if (data[i] == 0)
      }        {
          len = i;
           break;
         }
   
   if ((lease->extradata_size - lease->extradata_len) < (len + 1))    if ((lease->extradata_size - lease->extradata_len) < (len + 1))
     {      {
       size_t newsz = lease->extradata_len + len + 100;        size_t newsz = lease->extradata_len + len + 100;
      unsigned char *new = whine_malloc(newsz);      unsigned char *new = whine_realloc(lease->extradata, newsz);
       
       if (!new)        if (!new)
         return;          return;
               
       if (lease->extradata)  
         {  
           memcpy(new, lease->extradata, lease->extradata_len);  
           free(lease->extradata);  
         }  
   
       lease->extradata = new;        lease->extradata = new;
       lease->extradata_size = newsz;        lease->extradata_size = newsz;
     }      }
Line 1089  void lease_add_extradata(struct dhcp_lease *lease, uns Line 1196  void lease_add_extradata(struct dhcp_lease *lease, uns
 }  }
 #endif  #endif
   
#endif#endif /* HAVE_DHCP */
           
 
       
 

Removed from v.1.1  
changed lines
  Added in v.1.1.1.5


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