mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-20 02:38:32 +00:00
dhcp-ignore and dhcp-match implemented for DHCPv6 now.
This commit is contained in:
@@ -209,5 +209,35 @@ void log_tags(struct dhcp_netid *netid, u32 xid)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int match_bytes(struct dhcp_opt *o, unsigned char *p, int len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (o->len > len)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (o->len == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (o->flags & DHOPT_HEX)
|
||||||
|
{
|
||||||
|
if (memcmp_masked(o->val, p, o->len, o->u.wildcard_mask))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
for (i = 0; i <= (len - o->len); )
|
||||||
|
{
|
||||||
|
if (memcmp(o->val, p + i, o->len) == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (o->flags & DHOPT_STRING)
|
||||||
|
i++;
|
||||||
|
else
|
||||||
|
i += o->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -695,7 +695,7 @@ extern struct daemon {
|
|||||||
struct hostsfile *addn_hosts;
|
struct hostsfile *addn_hosts;
|
||||||
struct dhcp_context *dhcp, *dhcp6;
|
struct dhcp_context *dhcp, *dhcp6;
|
||||||
struct dhcp_config *dhcp_conf;
|
struct dhcp_config *dhcp_conf;
|
||||||
struct dhcp_opt *dhcp_opts, *dhcp_match, *dhcp_opts6;
|
struct dhcp_opt *dhcp_opts, *dhcp_match, *dhcp_opts6, *dhcp_match6;
|
||||||
struct dhcp_vendor *dhcp_vendors;
|
struct dhcp_vendor *dhcp_vendors;
|
||||||
struct dhcp_mac *dhcp_macs;
|
struct dhcp_mac *dhcp_macs;
|
||||||
struct dhcp_boot *boot_config;
|
struct dhcp_boot *boot_config;
|
||||||
@@ -1043,3 +1043,4 @@ struct dhcp_netid *option_filter(struct dhcp_netid *tags, struct dhcp_netid *con
|
|||||||
int match_netid(struct dhcp_netid *check, struct dhcp_netid *pool, int negonly);
|
int match_netid(struct dhcp_netid *check, struct dhcp_netid *pool, int negonly);
|
||||||
char *strip_hostname(char *hostname);
|
char *strip_hostname(char *hostname);
|
||||||
void log_tags(struct dhcp_netid *netid, u32 xid);
|
void log_tags(struct dhcp_netid *netid, u32 xid);
|
||||||
|
int match_bytes(struct dhcp_opt *o, unsigned char *p, int len);
|
||||||
|
|||||||
@@ -1333,6 +1333,11 @@ static char *parse_dhcp_opt(char *arg, int flags)
|
|||||||
!new->netid ||
|
!new->netid ||
|
||||||
new->netid->next)
|
new->netid->next)
|
||||||
problem = _("illegal dhcp-match");
|
problem = _("illegal dhcp-match");
|
||||||
|
else if (is6)
|
||||||
|
{
|
||||||
|
new->next = daemon->dhcp_match6;
|
||||||
|
daemon->dhcp_match6 = new;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
new->next = daemon->dhcp_match;
|
new->next = daemon->dhcp_match;
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ static void add_extradata_data(struct dhcp_lease *lease, unsigned char *data, si
|
|||||||
static void add_extradata_opt(struct dhcp_lease *lease, unsigned char *opt);
|
static void add_extradata_opt(struct dhcp_lease *lease, unsigned char *opt);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int match_bytes(struct dhcp_opt *o, unsigned char *p, int len);
|
|
||||||
static int sanitise(unsigned char *opt, char *buf);
|
static int sanitise(unsigned char *opt, char *buf);
|
||||||
static struct in_addr server_id(struct dhcp_context *context, struct in_addr override, struct in_addr fallback);
|
static struct in_addr server_id(struct dhcp_context *context, struct in_addr override, struct in_addr fallback);
|
||||||
static unsigned int calc_time(struct dhcp_context *context, struct dhcp_config *config, unsigned char *opt);
|
static unsigned int calc_time(struct dhcp_context *context, struct dhcp_config *config, unsigned char *opt);
|
||||||
@@ -1400,37 +1399,6 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int match_bytes(struct dhcp_opt *o, unsigned char *p, int len)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (o->len > len)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (o->len == 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (o->flags & DHOPT_HEX)
|
|
||||||
{
|
|
||||||
if (memcmp_masked(o->val, p, o->len, o->u.wildcard_mask))
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
for (i = 0; i <= (len - o->len); )
|
|
||||||
{
|
|
||||||
if (memcmp(o->val, p + i, o->len) == 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (o->flags & DHOPT_STRING)
|
|
||||||
i++;
|
|
||||||
else
|
|
||||||
i += o->len;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* find a good value to use as MAC address for logging and address-allocation hashing.
|
/* find a good value to use as MAC address for logging and address-allocation hashing.
|
||||||
This is normally just the chaddr field from the DHCP packet,
|
This is normally just the chaddr field from the DHCP packet,
|
||||||
but eg Firewire will have hlen == 0 and use the client-id instead.
|
but eg Firewire will have hlen == 0 and use the client-id instead.
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ static int dhcp6_no_relay(int msg_type, struct dhcp_netid *tags,
|
|||||||
struct dhcp_opt *opt_cfg;
|
struct dhcp_opt *opt_cfg;
|
||||||
struct dhcp_vendor *vendor;
|
struct dhcp_vendor *vendor;
|
||||||
struct dhcp_context *context_tmp;
|
struct dhcp_context *context_tmp;
|
||||||
unsigned int xid;
|
unsigned int xid, ignore = 0;
|
||||||
unsigned int fqdn_flags = 0x01; /* default to send if we recieve no FQDN option */
|
unsigned int fqdn_flags = 0x01; /* default to send if we recieve no FQDN option */
|
||||||
|
|
||||||
/* copy over transaction-id, and save pointer to message type */
|
/* copy over transaction-id, and save pointer to message type */
|
||||||
@@ -275,6 +275,48 @@ static int dhcp6_no_relay(int msg_type, struct dhcp_netid *tags,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* dhcp-match. If we have hex-and-wildcards, look for a left-anchored match.
|
||||||
|
Otherwise assume the option is an array, and look for a matching element.
|
||||||
|
If no data given, existance of the option is enough. This code handles
|
||||||
|
V-I opts too. */
|
||||||
|
for (opt_cfg = daemon->dhcp_match6; opt_cfg; opt_cfg = opt_cfg->next)
|
||||||
|
{
|
||||||
|
unsigned int len, elen, match = 0;
|
||||||
|
size_t offset, o2;
|
||||||
|
|
||||||
|
if (opt_cfg->flags & DHOPT_RFC3925)
|
||||||
|
{
|
||||||
|
for (opt = opt6_find(packet_options, end, OPTION6_VENDOR_OPTS, 4);
|
||||||
|
opt;
|
||||||
|
opt = opt6_find(opt6_next(opt, end), end, OPTION6_VENDOR_OPTS, 4))
|
||||||
|
{
|
||||||
|
void *vopt;
|
||||||
|
void *vend = opt6_ptr(opt, opt6_len(opt));
|
||||||
|
|
||||||
|
for (vopt = opt6_find(opt6_ptr(opt, 4), vend, opt_cfg->opt, 0);
|
||||||
|
vopt;
|
||||||
|
vopt = opt6_find(opt6_next(vopt, vend), vend, opt_cfg->opt, 0))
|
||||||
|
if (match = match_bytes(opt_cfg, opt6_ptr(vopt, 0), opt6_len(vopt)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (match)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(opt = opt6_find(packet_options, end, opt_cfg->opt, 1)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
match = match_bytes(opt_cfg, opt6_ptr(opt, 0), opt6_len(opt));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match)
|
||||||
|
{
|
||||||
|
opt_cfg->netid->next = tags;
|
||||||
|
tags = opt_cfg->netid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((opt = opt6_find(packet_options, end, OPTION6_FQDN, 1)))
|
if ((opt = opt6_find(packet_options, end, OPTION6_FQDN, 1)))
|
||||||
{
|
{
|
||||||
/* RFC4704 refers */
|
/* RFC4704 refers */
|
||||||
@@ -359,9 +401,22 @@ static int dhcp6_no_relay(int msg_type, struct dhcp_netid *tags,
|
|||||||
known_id.net = "known";
|
known_id.net = "known";
|
||||||
known_id.next = tags;
|
known_id.next = tags;
|
||||||
tags = &known_id;
|
tags = &known_id;
|
||||||
|
|
||||||
|
if (have_config(config, CONFIG_DISABLE))
|
||||||
|
ignore = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if all the netids in the ignore list are present, ignore this client */
|
||||||
|
if (daemon->dhcp_ignore)
|
||||||
|
{
|
||||||
|
struct dhcp_netid_list *id_list;
|
||||||
|
|
||||||
|
tagif = run_tag_if(tags);
|
||||||
|
|
||||||
|
for (id_list = daemon->dhcp_ignore; id_list; id_list = id_list->next)
|
||||||
|
if (match_netid(id_list->list, tagif, 0))
|
||||||
|
ignore = 1;
|
||||||
|
}
|
||||||
|
|
||||||
switch (msg_type)
|
switch (msg_type)
|
||||||
{
|
{
|
||||||
@@ -385,7 +440,10 @@ static int dhcp6_no_relay(int msg_type, struct dhcp_netid *tags,
|
|||||||
*outmsgtypep = make_lease ? DHCP6REPLY : DHCP6ADVERTISE;
|
*outmsgtypep = make_lease ? DHCP6REPLY : DHCP6ADVERTISE;
|
||||||
|
|
||||||
log6_packet(msg_type == DHCP6SOLICIT ? "DHCPSOLICIT" : "DHCPREQUEST",
|
log6_packet(msg_type == DHCP6SOLICIT ? "DHCPSOLICIT" : "DHCPREQUEST",
|
||||||
clid, clid_len, NULL, xid, iface_name, NULL);
|
clid, clid_len, NULL, xid, iface_name, ignore ? "ignored" : NULL);
|
||||||
|
|
||||||
|
if (ignore)
|
||||||
|
return 0;
|
||||||
|
|
||||||
for (opt = packet_options; opt; opt = opt6_next(opt, end))
|
for (opt = packet_options; opt; opt = opt6_next(opt, end))
|
||||||
{
|
{
|
||||||
@@ -791,6 +849,8 @@ static int dhcp6_no_relay(int msg_type, struct dhcp_netid *tags,
|
|||||||
|
|
||||||
case DHCP6IREQ:
|
case DHCP6IREQ:
|
||||||
{
|
{
|
||||||
|
if (ignore)
|
||||||
|
return 0;
|
||||||
*outmsgtypep = DHCP6REPLY;
|
*outmsgtypep = DHCP6REPLY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user