Diff for /embedaddon/dnsmasq/src/lease.c between versions 1.1.1.1 and 1.1.1.3

version 1.1.1.1, 2013/07/29 19:37:40 version 1.1.1.3, 2016/11/02 09:57:01
Line 1 Line 1
/* dnsmasq is Copyright (c) 2000-2013 Simon Kelley/* dnsmasq is Copyright (c) 2000-2016 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 108  void lease_init(time_t now) Line 108  void lease_init(time_t now)
           {            {
             char *s = daemon->dhcp_buff2;              char *s = daemon->dhcp_buff2;
             int lease_type = LEASE_NA;              int lease_type = LEASE_NA;
               int iaid;
   
             if (s[0] == 'T')              if (s[0] == 'T')
               {                {
Line 115  void lease_init(time_t now) Line 116  void lease_init(time_t now)
                 s++;                  s++;
               }                }
                           
            hw_type = strtoul(s, NULL, 10);            iaid = strtoul(s, NULL, 10);
                           
             if ((lease = lease6_allocate(&addr.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_hwaddr(lease, NULL, (unsigned char *)daemon->packet, 0, 0, clid_len, now, 0);
                                lease_set_iaid(lease, iaid);
                 if (strcmp(daemon->dhcp_buff, "*") !=  0)                  if (strcmp(daemon->dhcp_buff, "*") !=  0)
                   lease_set_hostname(lease, daemon->dhcp_buff, 0, get_domain6((struct in6_addr *)lease->hwaddr), NULL);                    lease_set_hostname(lease, daemon->dhcp_buff, 0, get_domain6((struct in6_addr *)lease->hwaddr), NULL);
               }                }
Line 187  void lease_update_from_configs(void) Line 188  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)) && 
              (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 */
Line 277  void lease_update_file(time_t now) Line 280  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 306  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 331  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)
     {      {
Line 345  void lease_update_file(time_t now) Line 348  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 376  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 410  void lease_update_slaac(time_t now) Line 425  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 458  void lease_update_dns(int force) Line 488  void lease_update_dns(int force)
                       cache_add_dhcp_entry(lease->hostname, AF_INET6, (struct all_addr *)&slaac->addr, lease->expires);                        cache_add_dhcp_entry(lease->hostname, AF_INET6, (struct 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 ? (struct all_addr *)&lease->addr : (struct 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 ? (struct all_addr *)&lease->addr : (struct all_addr *)&lease->addr6, 
                                  lease->expires);                                   lease->expires);
          
   #else
             if (lease->fqdn)
               cache_add_dhcp_entry(lease->fqdn, prot, (struct all_addr *)&lease->addr, lease->expires);
             
             if (!option_bool(OPT_DHCP_FQDN) && lease->hostname)
               cache_add_dhcp_entry(lease->hostname, prot, (struct all_addr *)&lease->addr, lease->expires);
   #endif
         }          }
               
       dns_dirty = 0;        dns_dirty = 0;
Line 563  struct dhcp_lease *lease6_find(unsigned char *clid, in Line 600  struct dhcp_lease *lease6_find(unsigned char *clid, in
       
   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 603  struct dhcp_lease *lease6_find_by_client(struct dhcp_l Line 640  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 662  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 682  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 728  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 704  struct dhcp_lease *lease4_allocate(struct in_addr addr Line 742  struct dhcp_lease *lease4_allocate(struct in_addr addr
 {  {
   struct dhcp_lease *lease = lease_allocate();    struct dhcp_lease *lease = lease_allocate();
   if (lease)    if (lease)
    {    lease->addr = addr;
      lease->addr = addr;  
      lease->hwaddr_len = 256; /* illegal value */ 
    } 
 
   return lease;    return lease;
 }  }
   
Line 719  struct dhcp_lease *lease6_allocate(struct in6_addr *ad Line 754  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;
     }      }
   
   return lease;    return lease;
Line 729  struct dhcp_lease *lease6_allocate(struct in6_addr *ad Line 765  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
          inifinite 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;
Line 757  void lease_set_expires(struct dhcp_lease *lease, unsig Line 802  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, 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 835  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 897  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 938  void lease_set_hostname(struct dhcp_lease *lease, char Line 992  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 1022  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 1052  int do_script_run(time_t now) Line 1110  int do_script_run(time_t now)
 }  }
   
 #ifdef HAVE_SCRIPT  #ifdef HAVE_SCRIPT
   /* delim == -1 -> delim = 0, but embeded 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 embeded 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;

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.3


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