mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Add tag filtering of dhcp-host directives.
This commit is contained in:
@@ -78,6 +78,9 @@ version 2.81
|
|||||||
boot. Many thanks to Harald Jensås for his work on this idea and
|
boot. Many thanks to Harald Jensås for his work on this idea and
|
||||||
earlier patches.
|
earlier patches.
|
||||||
|
|
||||||
|
Add filtering by tag of --dhcp-host directives. Based on a patch
|
||||||
|
by Harald Jensås.
|
||||||
|
|
||||||
|
|
||||||
version 2.80
|
version 2.80
|
||||||
Add support for RFC 4039 DHCP rapid commit. Thanks to Ashram Method
|
Add support for RFC 4039 DHCP rapid commit. Thanks to Ashram Method
|
||||||
|
|||||||
@@ -975,7 +975,7 @@ is also included, as described in RFC-3775 section 7.3.
|
|||||||
tells dnsmasq to advertise the prefix without the on-link (aka L) bit set.
|
tells dnsmasq to advertise the prefix without the on-link (aka L) bit set.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B \-G, --dhcp-host=[<hwaddr>][,id:<client_id>|*][,set:<tag>][,<ipaddr>][,<hostname>][,<lease_time>][,ignore]
|
.B \-G, --dhcp-host=[<hwaddr>][,id:<client_id>|*][,set:<tag>][tag:<tag>][,<ipaddr>][,<hostname>][,<lease_time>][,ignore]
|
||||||
Specify per host parameters for the DHCP server. This allows a machine
|
Specify per host parameters for the DHCP server. This allows a machine
|
||||||
with a particular hardware address to be always allocated the same
|
with a particular hardware address to be always allocated the same
|
||||||
hostname, IP address and lease time. A hostname specified like this
|
hostname, IP address and lease time. A hostname specified like this
|
||||||
@@ -1060,6 +1060,9 @@ ignore requests from unknown machines using
|
|||||||
.B --dhcp-ignore=tag:!known
|
.B --dhcp-ignore=tag:!known
|
||||||
If the host matches only a \fB--dhcp-host\fP directive which cannot
|
If the host matches only a \fB--dhcp-host\fP directive which cannot
|
||||||
be used because it specifies an address on different subnet, the tag "known-othernet" is set.
|
be used because it specifies an address on different subnet, the tag "known-othernet" is set.
|
||||||
|
|
||||||
|
The tag:<tag> construct filters which dhcp-host directives are used. Tagged directives are used in preference to untagged ones.
|
||||||
|
|
||||||
Ethernet addresses (but not client-ids) may have
|
Ethernet addresses (but not client-ids) may have
|
||||||
wildcard bytes, so for example
|
wildcard bytes, so for example
|
||||||
.B --dhcp-host=00:20:e0:3b:13:*,ignore
|
.B --dhcp-host=00:20:e0:3b:13:*,ignore
|
||||||
|
|||||||
@@ -304,11 +304,12 @@ static int is_config_in_context(struct dhcp_context *context, struct dhcp_config
|
|||||||
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;
|
||||||
@@ -320,7 +321,9 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
|
|||||||
{
|
{
|
||||||
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
|
||||||
@@ -328,7 +331,8 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
|
|||||||
see lease_update_from_configs() */
|
see lease_update_from_configs() */
|
||||||
if ((!context || !(context->flags & CONTEXT_V6)) && *clid == 0 && config->clid_len == clid_len-1 &&
|
if ((!context || !(context->flags & CONTEXT_V6)) && *clid == 0 && config->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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,14 +340,16 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
|
|||||||
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;
|
||||||
|
|
||||||
|
|
||||||
@@ -352,7 +358,8 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
|
|||||||
|
|
||||||
/* use match with fewest wildcard octets */
|
/* use match with fewest wildcard octets */
|
||||||
for (candidate = NULL, count = 0, config = configs; config; config = config->next)
|
for (candidate = NULL, count = 0, config = configs; config; config = config->next)
|
||||||
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 &&
|
||||||
@@ -366,6 +373,21 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
|
|||||||
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 *tags)
|
||||||
|
{
|
||||||
|
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.
|
||||||
|
|||||||
@@ -767,6 +767,7 @@ struct dhcp_config {
|
|||||||
unsigned char *clid; /* clientid */
|
unsigned char *clid; /* clientid */
|
||||||
char *hostname, *domain;
|
char *hostname, *domain;
|
||||||
struct dhcp_netid_list *netid;
|
struct dhcp_netid_list *netid;
|
||||||
|
struct dhcp_netid *filter;
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
struct addrlist *addr6;
|
struct addrlist *addr6;
|
||||||
#endif
|
#endif
|
||||||
@@ -1555,7 +1556,8 @@ struct dhcp_config *find_config(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 *filter);
|
||||||
int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type);
|
int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type);
|
||||||
#ifdef HAVE_LINUX_NETWORK
|
#ifdef HAVE_LINUX_NETWORK
|
||||||
char *whichdevice(void);
|
char *whichdevice(void);
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ void lease_update_from_configs(void)
|
|||||||
if (lease->flags & (LEASE_TA | LEASE_NA))
|
if (lease->flags & (LEASE_TA | LEASE_NA))
|
||||||
continue;
|
continue;
|
||||||
else if ((config = find_config(daemon->dhcp_conf, NULL, lease->clid, lease->clid_len,
|
else if ((config = find_config(daemon->dhcp_conf, NULL, lease->clid, lease->clid_len,
|
||||||
lease->hwaddr, lease->hwaddr_len, lease->hwaddr_type, NULL)) &&
|
lease->hwaddr, lease->hwaddr_len, lease->hwaddr_type, NULL, NULL)) &&
|
||||||
(config->flags & CONFIG_NAME) &&
|
(config->flags & CONFIG_NAME) &&
|
||||||
(!(config->flags & CONFIG_ADDR) || config->addr.s_addr == lease->addr.s_addr))
|
(!(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);
|
||||||
|
|||||||
10
src/option.c
10
src/option.c
@@ -963,8 +963,7 @@ static char *set_prefix(char *arg)
|
|||||||
return arg;
|
return arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dhcp_netid *
|
static struct dhcp_netid *dhcp_netid_create(const char *net, struct dhcp_netid *next)
|
||||||
dhcp_netid_create(const char *net, struct dhcp_netid *next)
|
|
||||||
{
|
{
|
||||||
struct dhcp_netid *tt;
|
struct dhcp_netid *tt;
|
||||||
tt = opt_malloc(sizeof (struct dhcp_netid));
|
tt = opt_malloc(sizeof (struct dhcp_netid));
|
||||||
@@ -1029,6 +1028,7 @@ static void dhcp_config_free(struct dhcp_config *config)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dhcp_netid_list_free(config->netid);
|
dhcp_netid_list_free(config->netid);
|
||||||
|
dhcp_netid_free(config->filter);
|
||||||
|
|
||||||
if (config->flags & CONFIG_CLID)
|
if (config->flags & CONFIG_CLID)
|
||||||
free(config->clid);
|
free(config->clid);
|
||||||
@@ -3217,6 +3217,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
new->flags = (option == LOPT_BANK) ? CONFIG_BANK : 0;
|
new->flags = (option == LOPT_BANK) ? CONFIG_BANK : 0;
|
||||||
new->hwaddr = NULL;
|
new->hwaddr = NULL;
|
||||||
new->netid = NULL;
|
new->netid = NULL;
|
||||||
|
new->filter = NULL;
|
||||||
new->clid = NULL;
|
new->clid = NULL;
|
||||||
new->addr6 = NULL;
|
new->addr6 = NULL;
|
||||||
|
|
||||||
@@ -3265,11 +3266,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
newlist->list = dhcp_netid_create(arg+4, NULL);
|
newlist->list = dhcp_netid_create(arg+4, NULL);
|
||||||
}
|
}
|
||||||
else if (strstr(arg, "tag:") == arg)
|
else if (strstr(arg, "tag:") == arg)
|
||||||
{
|
new->filter = dhcp_netid_create(arg+4, new->filter);
|
||||||
|
|
||||||
dhcp_config_free(new);
|
|
||||||
ret_err(_("cannot match tags in --dhcp-host"));
|
|
||||||
}
|
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
else if (arg[0] == '[' && arg[strlen(arg)-1] == ']')
|
else if (arg[0] == '[' && arg[strlen(arg)-1] == ']')
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -504,7 +504,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
mess->op = BOOTREPLY;
|
mess->op = BOOTREPLY;
|
||||||
|
|
||||||
config = find_config(daemon->dhcp_conf, context, clid, clid_len,
|
config = find_config(daemon->dhcp_conf, context, clid, clid_len,
|
||||||
mess->chaddr, mess->hlen, mess->htype, NULL);
|
mess->chaddr, mess->hlen, mess->htype, NULL, run_tag_if(netid));
|
||||||
|
|
||||||
/* set "known" tag for known hosts */
|
/* set "known" tag for known hosts */
|
||||||
if (config)
|
if (config)
|
||||||
@@ -514,7 +514,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
netid = &known_id;
|
netid = &known_id;
|
||||||
}
|
}
|
||||||
else if (find_config(daemon->dhcp_conf, NULL, clid, clid_len,
|
else if (find_config(daemon->dhcp_conf, NULL, clid, clid_len,
|
||||||
mess->chaddr, mess->hlen, mess->htype, NULL))
|
mess->chaddr, mess->hlen, mess->htype, NULL, run_tag_if(netid)))
|
||||||
{
|
{
|
||||||
known_id.net = "known-othernet";
|
known_id.net = "known-othernet";
|
||||||
known_id.next = netid;
|
known_id.next = netid;
|
||||||
@@ -781,7 +781,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
to avoid impersonation by name. */
|
to avoid impersonation by name. */
|
||||||
struct dhcp_config *new = find_config(daemon->dhcp_conf, context, NULL, 0,
|
struct dhcp_config *new = find_config(daemon->dhcp_conf, context, NULL, 0,
|
||||||
mess->chaddr, mess->hlen,
|
mess->chaddr, mess->hlen,
|
||||||
mess->htype, hostname);
|
mess->htype, hostname, run_tag_if(netid));
|
||||||
if (new && !have_config(new, CONFIG_CLID) && !new->hwaddr)
|
if (new && !have_config(new, CONFIG_CLID) && !new->hwaddr)
|
||||||
{
|
{
|
||||||
config = new;
|
config = new;
|
||||||
|
|||||||
@@ -526,7 +526,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (state->clid &&
|
if (state->clid &&
|
||||||
(config = find_config(daemon->dhcp_conf, state->context, state->clid, state->clid_len, state->mac, state->mac_len, state->mac_type, NULL)) &&
|
(config = find_config(daemon->dhcp_conf, state->context, state->clid, state->clid_len,
|
||||||
|
state->mac, state->mac_len, state->mac_type, NULL, run_tag_if(state->tags))) &&
|
||||||
have_config(config, CONFIG_NAME))
|
have_config(config, CONFIG_NAME))
|
||||||
{
|
{
|
||||||
state->hostname = config->hostname;
|
state->hostname = config->hostname;
|
||||||
@@ -546,7 +547,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
|||||||
/* Search again now we have a hostname.
|
/* Search again now we have a hostname.
|
||||||
Only accept configs without CLID here, (it won't match)
|
Only accept configs without CLID here, (it won't match)
|
||||||
to avoid impersonation by name. */
|
to avoid impersonation by name. */
|
||||||
struct dhcp_config *new = find_config(daemon->dhcp_conf, state->context, NULL, 0, NULL, 0, 0, state->hostname);
|
struct dhcp_config *new = find_config(daemon->dhcp_conf, state->context, NULL, 0, NULL, 0, 0, state->hostname, run_tag_if(state->tags));
|
||||||
if (new && !have_config(new, CONFIG_CLID) && !new->hwaddr)
|
if (new && !have_config(new, CONFIG_CLID) && !new->hwaddr)
|
||||||
config = new;
|
config = new;
|
||||||
}
|
}
|
||||||
@@ -572,7 +573,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
|||||||
ignore = 1;
|
ignore = 1;
|
||||||
}
|
}
|
||||||
else if (state->clid &&
|
else if (state->clid &&
|
||||||
find_config(daemon->dhcp_conf, NULL, state->clid, state->clid_len, state->mac, state->mac_len, state->mac_type, NULL))
|
find_config(daemon->dhcp_conf, NULL, state->clid, state->clid_len,
|
||||||
|
state->mac, state->mac_len, state->mac_type, NULL, run_tag_if(state->tags)))
|
||||||
{
|
{
|
||||||
known_id.net = "known-othernet";
|
known_id.net = "known-othernet";
|
||||||
known_id.next = state->tags;
|
known_id.next = state->tags;
|
||||||
|
|||||||
Reference in New Issue
Block a user