mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Enhance --add-subnet to allow arbitary subnet addresses.
This commit is contained in:
committed by
Simon Kelley
parent
d2aa7dfbb6
commit
a7369bef8a
@@ -541,6 +541,13 @@ struct iname {
|
||||
struct iname *next;
|
||||
};
|
||||
|
||||
/* subnet parameters from command line */
|
||||
struct mysubnet {
|
||||
union mysockaddr addr;
|
||||
int addr_used;
|
||||
int mask;
|
||||
};
|
||||
|
||||
/* resolv-file parms from command-line */
|
||||
struct resolvc {
|
||||
struct resolvc *next;
|
||||
@@ -935,9 +942,9 @@ extern struct daemon {
|
||||
struct auth_zone *auth_zones;
|
||||
struct interface_name *int_names;
|
||||
char *mxtarget;
|
||||
int addr4_netmask;
|
||||
int addr6_netmask;
|
||||
char *lease_file;
|
||||
struct mysubnet *add_subnet4;
|
||||
struct mysubnet *add_subnet6;
|
||||
char *lease_file;
|
||||
char *username, *groupname, *scriptuser;
|
||||
char *luascript;
|
||||
char *authserver, *hostmaster;
|
||||
|
||||
59
src/option.c
59
src/option.c
@@ -445,7 +445,7 @@ static struct {
|
||||
{ LOPT_PXE_SERV, ARG_DUP, "<service>", gettext_noop("Boot service for PXE menu."), NULL },
|
||||
{ LOPT_TEST, 0, NULL, gettext_noop("Check configuration syntax."), NULL },
|
||||
{ LOPT_ADD_MAC, OPT_ADD_MAC, NULL, gettext_noop("Add requestor's MAC address to forwarded DNS queries."), NULL },
|
||||
{ LOPT_ADD_SBNET, ARG_ONE, "<v4 pref>[,<v6 pref>]", gettext_noop("Add requestor's IP subnet to forwarded DNS queries."), NULL },
|
||||
{ LOPT_ADD_SBNET, ARG_ONE, "<v4 pref>[,<v6 pref>]", gettext_noop("Add specified IP subnet to forwarded DNS queries."), NULL },
|
||||
{ LOPT_DNSSEC, OPT_DNSSEC_PROXY, NULL, gettext_noop("Proxy DNSSEC validation results from upstream nameservers."), NULL },
|
||||
{ LOPT_INCR_ADDR, OPT_CONSEC_ADDR, NULL, gettext_noop("Attempt to allocate sequential IP addresses to DHCP clients."), NULL },
|
||||
{ LOPT_CONNTRACK, OPT_CONNTRACK, NULL, gettext_noop("Copy connection-track mark from queries to upstream connections."), NULL },
|
||||
@@ -722,6 +722,20 @@ static void do_usage(void)
|
||||
|
||||
#define ret_err(x) do { strcpy(errstr, (x)); return 0; } while (0)
|
||||
|
||||
static char *parse_mysockaddr(char *arg, union mysockaddr *addr)
|
||||
{
|
||||
if (inet_pton(AF_INET, arg, &addr->in.sin_addr) > 0)
|
||||
addr->sa.sa_family = AF_INET;
|
||||
#ifdef HAVE_IPV6
|
||||
else if (inet_pton(AF_INET6, arg, &addr->in6.sin6_addr) > 0)
|
||||
addr->sa.sa_family = AF_INET6;
|
||||
#endif
|
||||
else
|
||||
return _("bad address");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_addr, char *interface, int *flags)
|
||||
{
|
||||
int source_port = 0, serv_port = NAMESERVER_PORT;
|
||||
@@ -1585,7 +1599,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
li = match_suffix->next;
|
||||
free(match_suffix->suffix);
|
||||
free(match_suffix);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1593,10 +1607,45 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
set_option_bool(OPT_CLIENT_SUBNET);
|
||||
if (arg)
|
||||
{
|
||||
char *err, *end;
|
||||
comma = split(arg);
|
||||
if (!atoi_check(arg, &daemon->addr4_netmask) ||
|
||||
(comma && !atoi_check(comma, &daemon->addr6_netmask)))
|
||||
ret_err(gen_err);
|
||||
|
||||
struct mysubnet* new = opt_malloc(sizeof(struct mysubnet));
|
||||
if ((end = split_chr(arg, '/')))
|
||||
{
|
||||
/* has subnet+len */
|
||||
err = parse_mysockaddr(arg, &new->addr);
|
||||
if (err)
|
||||
ret_err(err);
|
||||
if (!atoi_check(end, &new->mask))
|
||||
ret_err(gen_err);
|
||||
new->addr_used = 1;
|
||||
}
|
||||
else if (!atoi_check(arg, &new->mask))
|
||||
ret_err(gen_err);
|
||||
|
||||
daemon->add_subnet4 = new;
|
||||
|
||||
new = opt_malloc(sizeof(struct mysubnet));
|
||||
if (comma)
|
||||
{
|
||||
if ((end = split_chr(comma, '/')))
|
||||
{
|
||||
/* has subnet+len */
|
||||
err = parse_mysockaddr(comma, &new->addr);
|
||||
if (err)
|
||||
ret_err(err);
|
||||
if (!atoi_check(end, &new->mask))
|
||||
ret_err(gen_err);
|
||||
new->addr_used = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!atoi_check(comma, &new->mask))
|
||||
ret_err(gen_err);
|
||||
}
|
||||
}
|
||||
daemon->add_subnet6 = new;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -629,26 +629,47 @@ struct subnet_opt {
|
||||
#endif
|
||||
};
|
||||
|
||||
static void *get_addrp(union mysockaddr *addr, const short family)
|
||||
{
|
||||
#ifdef HAVE_IPV6
|
||||
if (family == AF_INET6)
|
||||
return &addr->in6.sin6_addr;
|
||||
#endif
|
||||
|
||||
return &addr->in.sin_addr;
|
||||
}
|
||||
|
||||
static size_t calc_subnet_opt(struct subnet_opt *opt, union mysockaddr *source)
|
||||
{
|
||||
/* http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02 */
|
||||
|
||||
int len;
|
||||
void *addrp;
|
||||
int sa_family = source->sa.sa_family;
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
if (source->sa.sa_family == AF_INET6)
|
||||
{
|
||||
opt->family = htons(2);
|
||||
opt->source_netmask = daemon->addr6_netmask;
|
||||
addrp = &source->in6.sin6_addr;
|
||||
opt->source_netmask = daemon->add_subnet6->mask;
|
||||
if (daemon->add_subnet6->addr_used)
|
||||
{
|
||||
sa_family = daemon->add_subnet6->addr.sa.sa_family;
|
||||
addrp = get_addrp(&daemon->add_subnet6->addr, sa_family);
|
||||
}
|
||||
else
|
||||
addrp = &source->in6.sin6_addr;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
opt->family = htons(1);
|
||||
opt->source_netmask = daemon->addr4_netmask;
|
||||
addrp = &source->in.sin_addr;
|
||||
opt->source_netmask = daemon->add_subnet4->mask;
|
||||
if (daemon->add_subnet4->addr_used)
|
||||
{
|
||||
sa_family = daemon->add_subnet4->addr.sa.sa_family;
|
||||
addrp = get_addrp(&daemon->add_subnet4->addr, sa_family);
|
||||
}
|
||||
else
|
||||
addrp = &source->in.sin_addr;
|
||||
}
|
||||
|
||||
opt->scope_netmask = 0;
|
||||
@@ -656,6 +677,11 @@ static size_t calc_subnet_opt(struct subnet_opt *opt, union mysockaddr *source)
|
||||
|
||||
if (opt->source_netmask != 0)
|
||||
{
|
||||
#ifdef HAVE_IPV6
|
||||
opt->family = htons(sa_family == AF_INET6 ? 2 : 1);
|
||||
#else
|
||||
opt->family = htons(1);
|
||||
#endif
|
||||
len = ((opt->source_netmask - 1) >> 3) + 1;
|
||||
memcpy(opt->addr, addrp, len);
|
||||
if (opt->source_netmask & 7)
|
||||
@@ -2335,4 +2361,3 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user