Example #1
0
File: dhcp.c Project: NieHao/R7000
static void process_lease(struct crec **empty_cache, char *host_name, 
			  struct in_addr host_address, time_t ttd, int flags) 
{
  struct crec *crec;
  
  if ((crec = cache_find_by_name(NULL, host_name, 0, F_IPV4)))
    {
      if (crec->flags & F_HOSTS)
	syslog(LOG_WARNING, "Ignoring DHCP lease for %s because it clashes with an /etc/hosts entry.", cache_get_name(crec));
      else if (!(crec->flags & F_DHCP))
	{
	  if (crec->flags & F_NEG)
	    {
	      /* name may have been searched for before being allocated to DHCP and 
		 therefore got a negative cache entry. If so delete it and continue. */
	      crec->flags &= ~F_FORWARD;
	      goto newrec;
	    }
	  else
	    syslog(LOG_WARNING, "Ignoring DHCP lease for %s because it clashes with a cached name.", cache_get_name(crec));
	}
      else if (ttd > crec->ttd || ttd == (time_t)-1)
	{
	  /* simply a later entry in the leases file which supercedes and earlier one. */
	  memcpy(&crec->addr, &host_address, INADDRSZ);
	  if (ttd == (time_t)-1)
	    crec->flags |= F_IMMORTAL;
	  else
	    crec->ttd = ttd;
	}
    }
  else
    { /* can't find it in cache. */
    newrec:
      crec = *empty_cache;
      if ((strlen (host_name) < SMALLDNAME-1) && crec) 
	/* old entries to reuse (will not fit large names) */
	*empty_cache =(*empty_cache)->next;
      else /* need new one */
	{
	  if ((strlen(host_name) < SMALLDNAME-1))
	    crec = safe_malloc(sizeof(struct crec));
	  else
	    crec = safe_malloc(sizeof(struct crec) +
			  strlen(host_name)+1-SMALLDNAME);
	}
      
      if (crec) /* malloc may fail */
	{
	  crec->flags = F_DHCP | F_FORWARD | F_IPV4 | flags;
	  if (ttd == (time_t)-1)
	    crec->flags |= F_IMMORTAL;
	  else
	    crec->ttd = ttd;
	  memcpy(&crec->addr, &host_address, INADDRSZ);
	  strcpy(cache_get_name(crec), host_name);
	  cache_link(crec);
	}
    }
}
Example #2
0
void dhcp_update_configs(struct dhcp_config *configs)
{
    /* Some people like to keep all static IP addresses in /etc/hosts.
       This goes through /etc/hosts and sets static addresses for any DHCP config
       records which don't have an address and whose name matches.
       We take care to maintain the invariant that any IP address can appear
       in at most one dhcp-host. Since /etc/hosts can be re-read by SIGHUP,
       restore the status-quo ante first. */

    struct dhcp_config *config, *conf_tmp;
    struct crec *crec;
    int prot = AF_INET;

    for (config = configs; config; config = config->next)
        if (config->flags & CONFIG_ADDR_HOSTS)
            config->flags &= ~(CONFIG_ADDR | CONFIG_ADDR6 | CONFIG_ADDR_HOSTS);

#ifdef HAVE_DHCP6
again:
#endif

    if (daemon->port != 0)
        for (config = configs; config; config = config->next)
        {
            int conflags = CONFIG_ADDR;
            int cacheflags = F_IPV4;

#ifdef HAVE_DHCP6
            if (prot == AF_INET6)
            {
                conflags = CONFIG_ADDR6;
                cacheflags = F_IPV6;
            }
#endif
            if (!(config->flags & conflags) &&
                    (config->flags & CONFIG_NAME) &&
                    (crec = cache_find_by_name(NULL, config->hostname, 0, cacheflags)) &&
                    (crec->flags & F_HOSTS))
            {
                if (cache_find_by_name(crec, config->hostname, 0, cacheflags))
                {
                    /* use primary (first) address */
                    while (crec && !(crec->flags & F_REVERSE))
                        crec = cache_find_by_name(crec, config->hostname, 0, cacheflags);
                    if (!crec)
                        continue; /* should be never */
                    inet_ntop(prot, &crec->addr.addr, daemon->addrbuff, ADDRSTRLEN);
                    my_syslog(MS_DHCP | LOG_WARNING, _("%s has more than one address in hostsfile, using %s for DHCP"),
                              config->hostname, daemon->addrbuff);
                }

                if (prot == AF_INET &&
                        (!(conf_tmp = config_find_by_address(configs, crec->addr.addr.addr.addr4)) || conf_tmp == config))
                {
                    config->addr = crec->addr.addr.addr.addr4;
                    config->flags |= CONFIG_ADDR | CONFIG_ADDR_HOSTS;
                    continue;
                }

#ifdef HAVE_DHCP6
                if (prot == AF_INET6 &&
                        (!(conf_tmp = config_find_by_address6(configs, &crec->addr.addr.addr.addr6, 128, 0)) || conf_tmp == config))
                {
                    memcpy(&config->addr6, &crec->addr.addr.addr.addr6, IN6ADDRSZ);
                    config->flags |= CONFIG_ADDR6 | CONFIG_ADDR_HOSTS;
                    continue;
                }
#endif

                inet_ntop(prot, &crec->addr.addr, daemon->addrbuff, ADDRSTRLEN);
                my_syslog(MS_DHCP | LOG_WARNING, _("duplicate IP address %s (%s) in dhcp-config directive"),
                          daemon->addrbuff, config->hostname);


            }
        }

#ifdef HAVE_DHCP6
    if (prot == AF_INET)
    {
        prot = AF_INET6;
        goto again;
    }
#endif

}