mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
RDNSS and DNSSL data in router advertisements.
This commit is contained in:
@@ -69,9 +69,12 @@ version 2.61
|
|||||||
|
|
||||||
Fix bug in address6_available() which caused DHCPv6 lease
|
Fix bug in address6_available() which caused DHCPv6 lease
|
||||||
aquistion to fail of more than one dhcp-range in use.
|
aquistion to fail of more than one dhcp-range in use.
|
||||||
|
|
||||||
|
Provide RDNSS and DNSSL data in router advertisements,
|
||||||
|
using the settings provided for DHCP options
|
||||||
|
option6:domain-search and option6:dns-server.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
version 2.60
|
version 2.60
|
||||||
Fix compilation problem in Mac OS X Lion. Thanks to Olaf
|
Fix compilation problem in Mac OS X Lion. Thanks to Olaf
|
||||||
Flebbe for the patch.
|
Flebbe for the patch.
|
||||||
|
|||||||
@@ -1343,6 +1343,10 @@ the machine running dnsmasq. By default, he "managed address" bits are set, and
|
|||||||
the "use SLAAC" bit is reset. This can be changed for individual
|
the "use SLAAC" bit is reset. This can be changed for individual
|
||||||
subnets with the mode keywords described in
|
subnets with the mode keywords described in
|
||||||
.B --dhcp-range.
|
.B --dhcp-range.
|
||||||
|
RFC6106 DNS parameters are included in the advertisements. By default,
|
||||||
|
the relevant link-local address of the machine running dnsmasq is sent
|
||||||
|
as recursive DNS server. If provided, the DHCPv6 options dns-server and
|
||||||
|
domain-search are used for RDNSS and DNSSL.
|
||||||
.TP
|
.TP
|
||||||
.B --enable-tftp[=<interface>]
|
.B --enable-tftp[=<interface>]
|
||||||
Enable the TFTP server function. This is deliberately limited to that
|
Enable the TFTP server function. This is deliberately limited to that
|
||||||
|
|||||||
@@ -54,6 +54,7 @@
|
|||||||
#define OPTION6_RECONFIGURE_MSG 19
|
#define OPTION6_RECONFIGURE_MSG 19
|
||||||
#define OPTION6_RECONF_ACCEPT 20
|
#define OPTION6_RECONF_ACCEPT 20
|
||||||
#define OPTION6_DNS_SERVER 23
|
#define OPTION6_DNS_SERVER 23
|
||||||
|
#define OPTION6_DOMAIN_SEARCH 24
|
||||||
#define OPTION6_REMOTE_ID 37
|
#define OPTION6_REMOTE_ID 37
|
||||||
#define OPTION6_SUBSCRIBER_ID 38
|
#define OPTION6_SUBSCRIBER_ID 38
|
||||||
#define OPTION6_FQDN 39
|
#define OPTION6_FQDN 39
|
||||||
|
|||||||
38
src/option.c
38
src/option.c
@@ -1000,6 +1000,7 @@ static char *parse_dhcp_opt(char *arg, int flags)
|
|||||||
while (arg && *arg)
|
while (arg && *arg)
|
||||||
{
|
{
|
||||||
u16 len = strlen(arg);
|
u16 len = strlen(arg);
|
||||||
|
unhide_metas(arg);
|
||||||
PUTSHORT(len, p);
|
PUTSHORT(len, p);
|
||||||
memcpy(p, arg, len);
|
memcpy(p, arg, len);
|
||||||
p += len;
|
p += len;
|
||||||
@@ -1013,29 +1014,40 @@ static char *parse_dhcp_opt(char *arg, int flags)
|
|||||||
}
|
}
|
||||||
else if (comma && (opt_len & OT_RFC1035_NAME))
|
else if (comma && (opt_len & OT_RFC1035_NAME))
|
||||||
{
|
{
|
||||||
int i, commas = 1;
|
unsigned char *p = NULL, *newp, *end;
|
||||||
unsigned char *p, *newp;
|
int len = 0;
|
||||||
|
|
||||||
for (i = 0; comma[i]; i++)
|
|
||||||
if (comma[i] == ',')
|
|
||||||
commas++;
|
|
||||||
|
|
||||||
newp = opt_malloc(strlen(comma)+(2*commas));
|
|
||||||
p = newp;
|
|
||||||
arg = comma;
|
arg = comma;
|
||||||
comma = split(arg);
|
comma = split(arg);
|
||||||
|
|
||||||
while (arg && *arg)
|
while (arg && *arg)
|
||||||
{
|
{
|
||||||
p = do_rfc1035_name(p, arg);
|
char *dom = canonicalise_opt(arg);
|
||||||
*p++ = 0;
|
if (!dom)
|
||||||
|
{
|
||||||
|
problem = _("bad domain in dhcp-option");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
newp = opt_malloc(len + strlen(dom) + 2);
|
||||||
|
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
memcpy(newp, p, len);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
p = newp;
|
||||||
|
end = do_rfc1035_name(p + len, dom);
|
||||||
|
*end++ = 0;
|
||||||
|
len = end - p;
|
||||||
|
free(dom);
|
||||||
|
|
||||||
arg = comma;
|
arg = comma;
|
||||||
comma = split(arg);
|
comma = split(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
new->val = newp;
|
new->val = p;
|
||||||
new->len = p - newp;
|
new->len = len;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ struct prefix_opt {
|
|||||||
#define ICMP6_OPT_PREFIX 3
|
#define ICMP6_OPT_PREFIX 3
|
||||||
#define ICMP6_OPT_MTU 5
|
#define ICMP6_OPT_MTU 5
|
||||||
#define ICMP6_OPT_RDNSS 25
|
#define ICMP6_OPT_RDNSS 25
|
||||||
|
#define ICMP6_OPT_DNSSL 31
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
88
src/radv.c
88
src/radv.c
@@ -29,6 +29,7 @@
|
|||||||
struct ra_param {
|
struct ra_param {
|
||||||
int ind, managed, other, found_context, first;
|
int ind, managed, other, found_context, first;
|
||||||
char *if_name;
|
char *if_name;
|
||||||
|
struct dhcp_netid *tags;
|
||||||
struct in6_addr link_local;
|
struct in6_addr link_local;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -189,7 +190,10 @@ static void send_ra(int iface, char *iface_name, struct in6_addr *dest)
|
|||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
struct sockaddr_in6 addr;
|
struct sockaddr_in6 addr;
|
||||||
struct dhcp_context *context;
|
struct dhcp_context *context;
|
||||||
|
struct dhcp_netid iface_id;
|
||||||
|
struct dhcp_opt *opt_cfg;
|
||||||
|
int done_dns = 0;
|
||||||
|
|
||||||
save_counter(0);
|
save_counter(0);
|
||||||
ra = expand(sizeof(struct ra_packet));
|
ra = expand(sizeof(struct ra_packet));
|
||||||
|
|
||||||
@@ -208,9 +212,17 @@ static void send_ra(int iface, char *iface_name, struct in6_addr *dest)
|
|||||||
parm.if_name = iface_name;
|
parm.if_name = iface_name;
|
||||||
parm.first = 1;
|
parm.first = 1;
|
||||||
|
|
||||||
for (context = daemon->ra_contexts; context; context = context->next)
|
/* set tag with name == interface */
|
||||||
context->flags &= ~CONTEXT_RA_DONE;
|
iface_id.net = iface_name;
|
||||||
|
iface_id.next = NULL;
|
||||||
|
parm.tags = &iface_id;
|
||||||
|
|
||||||
|
for (context = daemon->ra_contexts; context; context = context->next)
|
||||||
|
{
|
||||||
|
context->flags &= ~CONTEXT_RA_DONE;
|
||||||
|
context->netid.next = &context->netid;
|
||||||
|
}
|
||||||
|
|
||||||
if (!iface_enumerate(AF_INET6, &parm, add_prefixes) ||
|
if (!iface_enumerate(AF_INET6, &parm, add_prefixes) ||
|
||||||
!parm.found_context)
|
!parm.found_context)
|
||||||
return;
|
return;
|
||||||
@@ -226,14 +238,63 @@ static void send_ra(int iface, char *iface_name, struct in6_addr *dest)
|
|||||||
}
|
}
|
||||||
|
|
||||||
iface_enumerate(AF_LOCAL, &iface, add_lla);
|
iface_enumerate(AF_LOCAL, &iface, add_lla);
|
||||||
|
|
||||||
|
/* RDNSS, RFC 6106, use relevant DHCP6 options */
|
||||||
|
(void)option_filter(parm.tags, NULL, daemon->dhcp_opts6);
|
||||||
|
|
||||||
/* RDNSS, RFC 6106 */
|
for (opt_cfg = daemon->dhcp_opts6; opt_cfg; opt_cfg = opt_cfg->next)
|
||||||
put_opt6_char(ICMP6_OPT_RDNSS);
|
{
|
||||||
put_opt6_char(3);
|
int i;
|
||||||
put_opt6_short(0);
|
|
||||||
put_opt6_long(1800); /* lifetime - twice RA retransmit */
|
/* netids match and not encapsulated? */
|
||||||
put_opt6(&parm.link_local, IN6ADDRSZ);
|
if (!(opt_cfg->flags & DHOPT_TAGOK))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (opt_cfg->opt == OPTION6_DNS_SERVER)
|
||||||
|
{
|
||||||
|
struct in6_addr *a = (struct in6_addr *)opt_cfg->val;
|
||||||
|
|
||||||
|
done_dns = 1;
|
||||||
|
if (opt_cfg->len == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
put_opt6_char(ICMP6_OPT_RDNSS);
|
||||||
|
put_opt6_char((opt_cfg->len/8) + 1);
|
||||||
|
put_opt6_short(0);
|
||||||
|
put_opt6_long(1800); /* lifetime - twice RA retransmit */
|
||||||
|
/* zero means "self" */
|
||||||
|
for (i = 0; i < opt_cfg->len; i += IN6ADDRSZ, a++)
|
||||||
|
if (IN6_IS_ADDR_UNSPECIFIED(a))
|
||||||
|
put_opt6(&parm.link_local, IN6ADDRSZ);
|
||||||
|
else
|
||||||
|
put_opt6(a, IN6ADDRSZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt_cfg->opt == OPTION6_DOMAIN_SEARCH && opt_cfg->len != 0)
|
||||||
|
{
|
||||||
|
int len = ((opt_cfg->len+7)/8);
|
||||||
|
|
||||||
|
put_opt6_char(ICMP6_OPT_DNSSL);
|
||||||
|
put_opt6_char(len + 1);
|
||||||
|
put_opt6_short(0);
|
||||||
|
put_opt6_long(1800); /* lifetime - twice RA retransmit */
|
||||||
|
put_opt6(opt_cfg->val, opt_cfg->len);
|
||||||
|
|
||||||
|
/* pad */
|
||||||
|
for (i = opt_cfg->len; i < len * 8; i++)
|
||||||
|
put_opt6_char(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!done_dns)
|
||||||
|
{
|
||||||
|
/* default == us. */
|
||||||
|
put_opt6_char(ICMP6_OPT_RDNSS);
|
||||||
|
put_opt6_char(3);
|
||||||
|
put_opt6_short(0);
|
||||||
|
put_opt6_long(1800); /* lifetime - twice RA retransmit */
|
||||||
|
put_opt6(&parm.link_local, IN6ADDRSZ);
|
||||||
|
}
|
||||||
|
|
||||||
/* set managed bits unless we're providing only RA on this link */
|
/* set managed bits unless we're providing only RA on this link */
|
||||||
if (parm.managed)
|
if (parm.managed)
|
||||||
@@ -323,7 +384,14 @@ static int add_prefixes(struct in6_addr *local, int prefix,
|
|||||||
context->ra_time = 0;
|
context->ra_time = 0;
|
||||||
param->first = 0;
|
param->first = 0;
|
||||||
param->found_context = 1;
|
param->found_context = 1;
|
||||||
|
|
||||||
|
/* collect dhcp-range tags */
|
||||||
|
if (context->netid.next == &context->netid && context->netid.net)
|
||||||
|
{
|
||||||
|
context->netid.next = param->tags;
|
||||||
|
param->tags = &context->netid;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(context->flags & CONTEXT_RA_DONE))
|
if (!(context->flags & CONTEXT_RA_DONE))
|
||||||
{
|
{
|
||||||
context->flags |= CONTEXT_RA_DONE;
|
context->flags |= CONTEXT_RA_DONE;
|
||||||
|
|||||||
Reference in New Issue
Block a user