"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/dhcp-common.c" between
dnsmasq-2.80.tar.gz and dnsmasq-2.81.tar.xz

About: Dnsmasq is a lightweight caching DNS forwarder and DHCP server.

dhcp-common.c  (dnsmasq-2.80):dhcp-common.c  (dnsmasq-2.81.tar.xz)
/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley /* dnsmasq is Copyright (c) 2000-2020 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
the Free Software Foundation; version 2 dated June, 1991, or the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007. (at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
skipping to change at line 274 skipping to change at line 274
return 1; return 1;
return 0; return 0;
} }
static int is_config_in_context(struct dhcp_context *context, struct dhcp_config *config) static int is_config_in_context(struct dhcp_context *context, struct dhcp_config *config)
{ {
if (!context) /* called via find_config() from lease_update_from_configs() */ if (!context) /* called via find_config() from lease_update_from_configs() */
return 1; return 1;
if (!(config->flags & (CONFIG_ADDR | CONFIG_ADDR6)))
return 1;
#ifdef HAVE_DHCP6 #ifdef HAVE_DHCP6
if ((context->flags & CONTEXT_V6) && (config->flags & CONFIG_WILDCARD)) if (context->flags & CONTEXT_V6)
return 1; {
#endif struct addrlist *addr_list;
for (; context; context = context->current) if (!(config->flags & CONFIG_ADDR6))
#ifdef HAVE_DHCP6 return 1;
if (context->flags & CONTEXT_V6)
{ for (; context; context = context->current)
if ((config->flags & CONFIG_ADDR6) && is_same_net6(&config->addr6, &conte for (addr_list = config->addr6; addr_list; addr_list = addr_list->next)
xt->start6, context->prefix)) {
return 1; if ((addr_list->flags & ADDRLIST_WILDCARD) && context->prefix == 64
} )
else return 1;
if (is_same_net6(&addr_list->addr.addr6, &context->start6, context-
>prefix))
return 1;
}
}
else
#endif #endif
if ((config->flags & CONFIG_ADDR) && is_same_net(config->addr, context->st {
art, context->netmask)) if (!(config->flags & CONFIG_ADDR))
return 1; return 1;
for (; context; context = context->current)
if ((config->flags & CONFIG_ADDR) && is_same_net(config->addr, context->s
tart, context->netmask))
return 1;
}
return 0; return 0;
} }
struct dhcp_config *find_config(struct dhcp_config *configs, static struct dhcp_config *find_config_match(struct dhcp_config *configs,
struct dhcp_context *context, struct dhcp_context *context,
unsigned char *clid, int clid_len, unsigned char *clid, int clid_len,
unsigned char *hwaddr, int hw_len, unsigned char *hwaddr, int hw_len,
int hw_type, char *hostname) int hw_type, char *hostname,
struct dhcp_netid *tags, int tag_not
_needed)
{ {
int count, new; int count, new;
struct dhcp_config *config, *candidate; struct dhcp_config *config, *candidate;
struct hwaddr_config *conf_addr; struct hwaddr_config *conf_addr;
if (clid) if (clid)
for (config = configs; config; config = config->next) for (config = configs; config; config = config->next)
if (config->flags & CONFIG_CLID) if (config->flags & CONFIG_CLID)
{ {
if (config->clid_len == clid_len && if (config->clid_len == clid_len &&
memcmp(config->clid, clid, clid_len) == 0 && memcmp(config->clid, clid, clid_len) == 0 &&
is_config_in_context(context, config)) is_config_in_context(context, config) &&
match_netid(config->filter, tags, tag_not_needed))
return config; return config;
/* dhcpcd prefixes ASCII client IDs by zero which is wrong, but we try and /* dhcpcd prefixes ASCII client IDs by zero which is wrong, but we try and
cope with that here. This is IPv4 only. context==NULL implies IPv4, cope with that here. This is IPv4 only. context==NULL implies IPv4,
see lease_update_from_configs() */ see lease_update_from_configs() */
if ((!context || !(context->flags & CONTEXT_V6)) && *clid == 0 && confi g->clid_len == clid_len-1 && if ((!context || !(context->flags & CONTEXT_V6)) && *clid == 0 && confi g->clid_len == clid_len-1 &&
memcmp(config->clid, clid+1, clid_len-1) == 0 && memcmp(config->clid, clid+1, clid_len-1) == 0 &&
is_config_in_context(context, config)) is_config_in_context(context, config) &&
match_netid(config->filter, tags, tag_not_needed))
return config; return config;
} }
if (hwaddr) if (hwaddr)
for (config = configs; config; config = config->next) for (config = configs; config; config = config->next)
if (config_has_mac(config, hwaddr, hw_len, hw_type) && if (config_has_mac(config, hwaddr, hw_len, hw_type) &&
is_config_in_context(context, config)) is_config_in_context(context, config) &&
match_netid(config->filter, tags, tag_not_needed))
return config; return config;
if (hostname && context) if (hostname && context)
for (config = configs; config; config = config->next) for (config = configs; config; config = config->next)
if ((config->flags & CONFIG_NAME) && if ((config->flags & CONFIG_NAME) &&
hostname_isequal(config->hostname, hostname) && hostname_isequal(config->hostname, hostname) &&
is_config_in_context(context, config)) is_config_in_context(context, config) &&
match_netid(config->filter, tags, tag_not_needed))
return config; return config;
if (!hwaddr) if (!hwaddr)
return NULL; return NULL;
/* use match with fewest wildcard octets */ /* use match with fewest wildcard octets */
for (candidate = NULL, count = 0, config = configs; config; config = config->n ext) for (candidate = NULL, count = 0, config = configs; config; config = config->n ext)
if (is_config_in_context(context, config)) if (is_config_in_context(context, config) &&
match_netid(config->filter, tags, tag_not_needed))
for (conf_addr = config->hwaddr; conf_addr; conf_addr = conf_addr->next) for (conf_addr = config->hwaddr; conf_addr; conf_addr = conf_addr->next)
if (conf_addr->wildcard_mask != 0 && if (conf_addr->wildcard_mask != 0 &&
conf_addr->hwaddr_len == hw_len && conf_addr->hwaddr_len == hw_len &&
(conf_addr->hwaddr_type == hw_type || conf_addr->hwaddr_type == 0) && (conf_addr->hwaddr_type == hw_type || conf_addr->hwaddr_type == 0) &&
(new = memcmp_masked(conf_addr->hwaddr, hwaddr, hw_len, conf_addr->wi ldcard_mask)) > count) (new = memcmp_masked(conf_addr->hwaddr, hwaddr, hw_len, conf_addr->wi ldcard_mask)) > count)
{ {
count = new; count = new;
candidate = config; candidate = config;
} }
return candidate; return candidate;
} }
/* Find tagged configs first. */
struct dhcp_config *find_config(struct dhcp_config *configs,
struct dhcp_context *context,
unsigned char *clid, int clid_len,
unsigned char *hwaddr, int hw_len,
int hw_type, char *hostname, struct dhcp_netid *t
ags)
{
struct dhcp_config *ret = find_config_match(configs, context, clid, clid_len,
hwaddr, hw_len, hw_type, hostname, tags, 0);
if (!ret)
ret = find_config_match(configs, context, clid, clid_len, hwaddr, hw_len, hw
_type, hostname, tags, 1);
return ret;
}
void dhcp_update_configs(struct dhcp_config *configs) void dhcp_update_configs(struct dhcp_config *configs)
{ {
/* Some people like to keep all static IP addresses in /etc/hosts. /* 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 This goes through /etc/hosts and sets static addresses for any DHCP config
records which don't have an address and whose name matches. records which don't have an address and whose name matches.
We take care to maintain the invariant that any IP address can appear 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, in at most one dhcp-host. Since /etc/hosts can be re-read by SIGHUP,
restore the status-quo ante first. */ restore the status-quo ante first. */
struct dhcp_config *config, *conf_tmp; struct dhcp_config *config, *conf_tmp;
struct crec *crec; struct crec *crec;
int prot = AF_INET; int prot = AF_INET;
for (config = configs; config; config = config->next) for (config = configs; config; config = config->next)
{
if (config->flags & CONFIG_ADDR_HOSTS) if (config->flags & CONFIG_ADDR_HOSTS)
config->flags &= ~(CONFIG_ADDR | CONFIG_ADDR6 | CONFIG_ADDR_HOSTS); config->flags &= ~(CONFIG_ADDR | CONFIG_ADDR_HOSTS);
#ifdef HAVE_DHCP6
if (config->flags & CONFIG_ADDR6_HOSTS)
config->flags &= ~(CONFIG_ADDR6 | CONFIG_ADDR6_HOSTS);
#endif
}
#ifdef HAVE_DHCP6 #ifdef HAVE_DHCP6
again: again:
#endif #endif
if (daemon->port != 0) if (daemon->port != 0)
for (config = configs; config; config = config->next) for (config = configs; config; config = config->next)
{ {
int conflags = CONFIG_ADDR; int conflags = CONFIG_ADDR;
int cacheflags = F_IPV4; int cacheflags = F_IPV4;
skipping to change at line 403 skipping to change at line 440
(crec = cache_find_by_name(NULL, config->hostname, 0, cacheflags)) && (crec = cache_find_by_name(NULL, config->hostname, 0, cacheflags)) &&
(crec->flags & F_HOSTS)) (crec->flags & F_HOSTS))
{ {
if (cache_find_by_name(crec, config->hostname, 0, cacheflags)) if (cache_find_by_name(crec, config->hostname, 0, cacheflags))
{ {
/* use primary (first) address */ /* use primary (first) address */
while (crec && !(crec->flags & F_REVERSE)) while (crec && !(crec->flags & F_REVERSE))
crec = cache_find_by_name(crec, config->hostname, 0, cacheflags ); crec = cache_find_by_name(crec, config->hostname, 0, cacheflags );
if (!crec) if (!crec)
continue; /* should be never */ continue; /* should be never */
inet_ntop(prot, &crec->addr.addr, daemon->addrbuff, ADDRSTRLEN); inet_ntop(prot, &crec->addr, daemon->addrbuff, ADDRSTRLEN);
my_syslog(MS_DHCP | LOG_WARNING, _("%s has more than one address in hostsfile, using %s for DHCP"), my_syslog(MS_DHCP | LOG_WARNING, _("%s has more than one address in hostsfile, using %s for DHCP"),
config->hostname, daemon->addrbuff); config->hostname, daemon->addrbuff);
} }
if (prot == AF_INET && if (prot == AF_INET &&
(!(conf_tmp = config_find_by_address(configs, crec->addr.addr.add r.addr4)) || conf_tmp == config)) (!(conf_tmp = config_find_by_address(configs, crec->addr.addr4)) || conf_tmp == config))
{ {
config->addr = crec->addr.addr.addr.addr4; config->addr = crec->addr.addr4;
config->flags |= CONFIG_ADDR | CONFIG_ADDR_HOSTS; config->flags |= CONFIG_ADDR | CONFIG_ADDR_HOSTS;
continue; continue;
} }
#ifdef HAVE_DHCP6 #ifdef HAVE_DHCP6
if (prot == AF_INET6 && if (prot == AF_INET6 &&
(!(conf_tmp = config_find_by_address6(configs, &crec->addr.addr.a ddr.addr6, 128, 0)) || conf_tmp == config)) (!(conf_tmp = config_find_by_address6(configs, NULL, 0, &crec->ad dr.addr6)) || conf_tmp == config))
{ {
memcpy(&config->addr6, &crec->addr.addr.addr.addr6, IN6ADDRSZ); /* host must have exactly one address if comming from /etc/hosts.
config->flags |= CONFIG_ADDR6 | CONFIG_ADDR_HOSTS; */
if (!config->addr6 && (config->addr6 = whine_malloc(sizeof(struct
addrlist))))
{
config->addr6->next = NULL;
config->addr6->flags = 0;
}
if (config->addr6 && !config->addr6->next && !(config->addr6->fla
gs & (ADDRLIST_WILDCARD|ADDRLIST_PREFIX)))
{
memcpy(&config->addr6->addr.addr6, &crec->addr.addr6, IN6ADDR
SZ);
config->flags |= CONFIG_ADDR6 | CONFIG_ADDR6_HOSTS;
}
continue; continue;
} }
#endif #endif
inet_ntop(prot, &crec->addr.addr, daemon->addrbuff, ADDRSTRLEN); inet_ntop(prot, &crec->addr, daemon->addrbuff, ADDRSTRLEN);
my_syslog(MS_DHCP | LOG_WARNING, _("duplicate IP address %s (%s) in d hcp-config directive"), my_syslog(MS_DHCP | LOG_WARNING, _("duplicate IP address %s (%s) in d hcp-config directive"),
daemon->addrbuff, config->hostname); daemon->addrbuff, config->hostname);
} }
} }
#ifdef HAVE_DHCP6 #ifdef HAVE_DHCP6
if (prot == AF_INET) if (prot == AF_INET)
{ {
prot = AF_INET6; prot = AF_INET6;
skipping to change at line 569 skipping to change at line 617
{ "FQDN", 81, OT_INTERNAL }, { "FQDN", 81, OT_INTERNAL },
{ "agent-id", 82, OT_INTERNAL }, { "agent-id", 82, OT_INTERNAL },
{ "client-arch", 93, 2 | OT_DEC }, { "client-arch", 93, 2 | OT_DEC },
{ "client-interface-id", 94, 0 }, { "client-interface-id", 94, 0 },
{ "client-machine-id", 97, 0 }, { "client-machine-id", 97, 0 },
{ "subnet-select", 118, OT_INTERNAL }, { "subnet-select", 118, OT_INTERNAL },
{ "domain-search", 119, OT_RFC1035_NAME }, { "domain-search", 119, OT_RFC1035_NAME },
{ "sip-server", 120, 0 }, { "sip-server", 120, 0 },
{ "classless-static-route", 121, 0 }, { "classless-static-route", 121, 0 },
{ "vendor-id-encap", 125, 0 }, { "vendor-id-encap", 125, 0 },
{ "tftp-server-address", 150, OT_ADDR_LIST },
{ "server-ip-address", 255, OT_ADDR_LIST }, /* special, internal only, sets si addr */ { "server-ip-address", 255, OT_ADDR_LIST }, /* special, internal only, sets si addr */
{ NULL, 0, 0 } { NULL, 0, 0 }
}; };
#ifdef HAVE_DHCP6 #ifdef HAVE_DHCP6
static const struct opttab_t opttab6[] = { static const struct opttab_t opttab6[] = {
{ "client-id", 1, OT_INTERNAL }, { "client-id", 1, OT_INTERNAL },
{ "server-id", 2, OT_INTERNAL }, { "server-id", 2, OT_INTERNAL },
{ "ia-na", 3, OT_INTERNAL }, { "ia-na", 3, OT_INTERNAL },
{ "ia-ta", 4, OT_INTERNAL }, { "ia-ta", 4, OT_INTERNAL },
skipping to change at line 599 skipping to change at line 648
{ "sip-server", 22, OT_ADDR_LIST }, { "sip-server", 22, OT_ADDR_LIST },
{ "dns-server", 23, OT_ADDR_LIST }, { "dns-server", 23, OT_ADDR_LIST },
{ "domain-search", 24, OT_RFC1035_NAME }, { "domain-search", 24, OT_RFC1035_NAME },
{ "nis-server", 27, OT_ADDR_LIST }, { "nis-server", 27, OT_ADDR_LIST },
{ "nis+-server", 28, OT_ADDR_LIST }, { "nis+-server", 28, OT_ADDR_LIST },
{ "nis-domain", 29, OT_RFC1035_NAME }, { "nis-domain", 29, OT_RFC1035_NAME },
{ "nis+-domain", 30, OT_RFC1035_NAME }, { "nis+-domain", 30, OT_RFC1035_NAME },
{ "sntp-server", 31, OT_ADDR_LIST }, { "sntp-server", 31, OT_ADDR_LIST },
{ "information-refresh-time", 32, OT_TIME }, { "information-refresh-time", 32, OT_TIME },
{ "FQDN", 39, OT_INTERNAL | OT_RFC1035_NAME }, { "FQDN", 39, OT_INTERNAL | OT_RFC1035_NAME },
{ "ntp-server", 56, 0 }, { "ntp-server", 56, 0 /* OT_ADDR_LIST | OT_RFC1035_NAME */ },
{ "bootfile-url", 59, OT_NAME }, { "bootfile-url", 59, OT_NAME },
{ "bootfile-param", 60, OT_CSTRING }, { "bootfile-param", 60, OT_CSTRING },
{ NULL, 0, 0 } { NULL, 0, 0 }
}; };
#endif #endif
void display_opts(void) void display_opts(void)
{ {
int i; int i;
skipping to change at line 690 skipping to change at line 739
for (o = 0; ot[o].name; o++) for (o = 0; ot[o].name; o++)
if (ot[o].val == opt) if (ot[o].val == opt)
{ {
if (buf) if (buf)
{ {
memset(buf, 0, buf_len); memset(buf, 0, buf_len);
if (ot[o].size & OT_ADDR_LIST) if (ot[o].size & OT_ADDR_LIST)
{ {
struct all_addr addr; union all_addr addr;
int addr_len = INADDRSZ; int addr_len = INADDRSZ;
#ifdef HAVE_DHCP6 #ifdef HAVE_DHCP6
if (prot == AF_INET6) if (prot == AF_INET6)
addr_len = IN6ADDRSZ; addr_len = IN6ADDRSZ;
#endif #endif
for (buf[0]= 0, i = 0; i <= opt_len - addr_len; i += addr_len) for (buf[0]= 0, i = 0; i <= opt_len - addr_len; i += addr_len)
{ {
if (i != 0) if (i != 0)
strncat(buf, ", ", buf_len - strlen(buf)); strncat(buf, ", ", buf_len - strlen(buf));
 End of changes. 24 change blocks. 
38 lines changed or deleted 96 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)