mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
import of dnsmasq-2.47.tar.gz
This commit is contained in:
158
src/option.c
158
src/option.c
@@ -1,4 +1,4 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2008 Simon Kelley
|
||||
/* dnsmasq is Copyright (c) 2000-2009 Simon Kelley
|
||||
|
||||
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
|
||||
@@ -10,8 +10,8 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* define this to get facilitynames */
|
||||
@@ -310,7 +310,7 @@ static struct {
|
||||
{ LOPT_MAX_LOGS, ARG_ONE, "[=<log lines>]", gettext_noop("Enable async. logging; optionally set queue length."), NULL },
|
||||
{ LOPT_REBIND, OPT_NO_REBIND, NULL, gettext_noop("Stop DNS rebinding. Filter private IP ranges when resolving."), NULL },
|
||||
{ LOPT_NOLAST, OPT_ALL_SERVERS, NULL, gettext_noop("Always perform DNS queries to all servers."), NULL },
|
||||
{ LOPT_MATCH, ARG_DUP, "<netid>,<opt-no>", gettext_noop("Set tag if client includes option in request."), NULL },
|
||||
{ LOPT_MATCH, ARG_DUP, "<netid>,<optspec>", gettext_noop("Set tag if client includes matching option in request."), NULL },
|
||||
{ LOPT_ALTPORT, ARG_ONE, "[=<ports>]", gettext_noop("Use alternative ports for DHCP."), NULL },
|
||||
{ LOPT_SCRIPTUSR, ARG_ONE, "<username>", gettext_noop("Run lease-change script as this user."), NULL },
|
||||
{ LOPT_NAPTR, ARG_DUP, "<name>,<naptr>", gettext_noop("Specify NAPTR DNS record."), NULL },
|
||||
@@ -391,6 +391,9 @@ static const struct {
|
||||
{ "user-class", 77, 0 },
|
||||
{ "FQDN", 81, OT_INTERNAL },
|
||||
{ "agent-id", 82, OT_INTERNAL },
|
||||
{ "client-arch", 93, 2 },
|
||||
{ "client-interface-id", 94, 0 },
|
||||
{ "client-machine-id", 97, 0 },
|
||||
{ "subnet-select", 118, OT_INTERNAL },
|
||||
{ "domain-search", 119, 0 },
|
||||
{ "sip-server", 120, 0 },
|
||||
@@ -491,11 +494,12 @@ static char *opt_string_alloc(char *cp)
|
||||
|
||||
/* find next comma, split string with zero and eliminate spaces.
|
||||
return start of string following comma */
|
||||
static char *split(char *s)
|
||||
|
||||
static char *split_chr(char *s, char c)
|
||||
{
|
||||
char *comma, *p;
|
||||
|
||||
if (!s || !(comma = strchr(s, ',')))
|
||||
if (!s || !(comma = strchr(s, c)))
|
||||
return NULL;
|
||||
|
||||
p = comma;
|
||||
@@ -509,6 +513,11 @@ static char *split(char *s)
|
||||
return comma;
|
||||
}
|
||||
|
||||
static char *split(char *s)
|
||||
{
|
||||
return split_chr(s, ',');
|
||||
}
|
||||
|
||||
static int canonicalise_opt(char *s)
|
||||
{
|
||||
if (!s)
|
||||
@@ -642,7 +651,6 @@ static char *parse_dhcp_opt(char *arg, int flags)
|
||||
new->flags = flags;
|
||||
new->netid = NULL;
|
||||
new->val = NULL;
|
||||
new->vendor_class = NULL;
|
||||
new->opt = 0;
|
||||
|
||||
while (arg)
|
||||
@@ -675,7 +683,12 @@ static char *parse_dhcp_opt(char *arg, int flags)
|
||||
}
|
||||
else if (strstr(arg, "vendor:") == arg)
|
||||
{
|
||||
new->vendor_class = (unsigned char *)opt_string_alloc(arg+7);
|
||||
new->u.vendor_class = (unsigned char *)opt_string_alloc(arg+7);
|
||||
new->flags |= DHOPT_VENDOR;
|
||||
}
|
||||
else if (strstr(arg, "encap:") == arg)
|
||||
{
|
||||
new->u.encap = atoi(arg+6);
|
||||
new->flags |= DHOPT_ENCAPSULATE;
|
||||
}
|
||||
else
|
||||
@@ -740,7 +753,8 @@ static char *parse_dhcp_opt(char *arg, int flags)
|
||||
else
|
||||
is_dec = 0;
|
||||
if (!((c >='A' && c <= 'F') ||
|
||||
(c >='a' && c <= 'f')))
|
||||
(c >='a' && c <= 'f') ||
|
||||
(c == '*' && (flags & DHOPT_MATCH))))
|
||||
is_hex = 0;
|
||||
}
|
||||
|
||||
@@ -757,7 +771,8 @@ static char *parse_dhcp_opt(char *arg, int flags)
|
||||
{
|
||||
new->len = digs;
|
||||
new->val = opt_malloc(new->len);
|
||||
parse_hex(comma, new->val, digs, NULL, NULL);
|
||||
parse_hex(comma, new->val, digs, (flags & DHOPT_MATCH) ? &new->u.wildcard_mask : NULL, NULL);
|
||||
new->flags |= DHOPT_HEX;
|
||||
}
|
||||
else if (is_dec)
|
||||
{
|
||||
@@ -804,8 +819,7 @@ static char *parse_dhcp_opt(char *arg, int flags)
|
||||
{
|
||||
cp = comma;
|
||||
comma = split(cp);
|
||||
if ((slash = strchr(cp, '/')))
|
||||
*slash++ = 0;
|
||||
slash = split_chr(cp, '/');
|
||||
in.s_addr = inet_addr(cp);
|
||||
if (!slash)
|
||||
{
|
||||
@@ -910,8 +924,23 @@ static char *parse_dhcp_opt(char *arg, int flags)
|
||||
|
||||
if (!problem)
|
||||
{
|
||||
new->next = daemon->dhcp_opts;
|
||||
daemon->dhcp_opts = new;
|
||||
if (flags == DHOPT_MATCH)
|
||||
{
|
||||
if ((new->flags & (DHOPT_ENCAPSULATE | DHOPT_VENDOR)) ||
|
||||
!new->netid ||
|
||||
new->netid->next)
|
||||
problem = _("illegal dhcp-match");
|
||||
else
|
||||
{
|
||||
new->next = daemon->dhcp_match;
|
||||
daemon->dhcp_match = new;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
new->next = daemon->dhcp_opts;
|
||||
daemon->dhcp_opts = new;
|
||||
}
|
||||
}
|
||||
|
||||
return problem;
|
||||
@@ -1149,10 +1178,9 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
||||
{
|
||||
struct cond_domain *new = safe_malloc(sizeof(struct cond_domain));
|
||||
unhide_metas(comma);
|
||||
if ((arg = strchr(comma, '/')))
|
||||
if ((arg = split_chr(comma, '/')))
|
||||
{
|
||||
int mask;
|
||||
*arg++ = 0;
|
||||
if ((new->start.s_addr = inet_addr(comma)) == (in_addr_t)-1 ||
|
||||
!atoi_check(arg, &mask))
|
||||
option = '?';
|
||||
@@ -1292,10 +1320,9 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
||||
{
|
||||
char *end;
|
||||
arg++;
|
||||
while ((end = strchr(arg, '/')))
|
||||
while ((end = split_chr(arg, '/')))
|
||||
{
|
||||
char *domain = NULL;
|
||||
*end = 0;
|
||||
/* # matches everything and becomes a zero length domain string */
|
||||
if (strcmp(arg, "#") == 0)
|
||||
domain = "";
|
||||
@@ -1309,7 +1336,7 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
||||
newlist = serv;
|
||||
serv->domain = domain;
|
||||
serv->flags = domain ? SERV_HAS_DOMAIN : SERV_FOR_NODOTS;
|
||||
arg = end+1;
|
||||
arg = end;
|
||||
}
|
||||
if (!newlist)
|
||||
{
|
||||
@@ -1342,23 +1369,14 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
||||
int source_port = 0, serv_port = NAMESERVER_PORT;
|
||||
char *portno, *source;
|
||||
|
||||
if ((source = strchr(arg, '@'))) /* is there a source. */
|
||||
{
|
||||
*source = 0;
|
||||
if ((portno = strchr(source+1, '#')))
|
||||
{
|
||||
*portno = 0;
|
||||
if (!atoi_check16(portno+1, &source_port))
|
||||
problem = _("bad port");
|
||||
}
|
||||
}
|
||||
|
||||
if ((portno = strchr(arg, '#'))) /* is there a port no. */
|
||||
{
|
||||
*portno = 0;
|
||||
if (!atoi_check16(portno+1, &serv_port))
|
||||
problem = _("bad port");
|
||||
}
|
||||
if ((source = split_chr(arg, '@')) && /* is there a source. */
|
||||
(portno = split_chr(source, '#')) &&
|
||||
!atoi_check16(portno, &source_port))
|
||||
problem = _("bad port");
|
||||
|
||||
if ((portno = split_chr(arg, '#')) && /* is there a port no. */
|
||||
!atoi_check16(portno, &serv_port))
|
||||
problem = _("bad port");
|
||||
|
||||
if ((newlist->addr.in.sin_addr.s_addr = inet_addr(arg)) != (in_addr_t) -1)
|
||||
{
|
||||
@@ -1371,11 +1389,11 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
||||
if (source)
|
||||
{
|
||||
newlist->flags |= SERV_HAS_SOURCE;
|
||||
if ((newlist->source_addr.in.sin_addr.s_addr = inet_addr(source+1)) == (in_addr_t) -1)
|
||||
if ((newlist->source_addr.in.sin_addr.s_addr = inet_addr(source)) == (in_addr_t) -1)
|
||||
{
|
||||
#if defined(SO_BINDTODEVICE)
|
||||
newlist->source_addr.in.sin_addr.s_addr = INADDR_ANY;
|
||||
strncpy(newlist->interface, source+1, IF_NAMESIZE);
|
||||
strncpy(newlist->interface, source, IF_NAMESIZE);
|
||||
#else
|
||||
problem = _("interface binding not supported");
|
||||
#endif
|
||||
@@ -1396,11 +1414,11 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
||||
if (source)
|
||||
{
|
||||
newlist->flags |= SERV_HAS_SOURCE;
|
||||
if (inet_pton(AF_INET6, source+1, &newlist->source_addr.in6.sin6_addr) == 0)
|
||||
if (inet_pton(AF_INET6, source, &newlist->source_addr.in6.sin6_addr) == 0)
|
||||
{
|
||||
#if defined(SO_BINDTODEVICE) || defined(HAVE_SOLARIS_NETWORK)
|
||||
#if defined(SO_BINDTODEVICE)
|
||||
newlist->source_addr.in6.sin6_addr = in6addr_any;
|
||||
strncpy(newlist->interface, source+1, IF_NAMESIZE);
|
||||
strncpy(newlist->interface, source, IF_NAMESIZE);
|
||||
#else
|
||||
problem = _("interface binding not supported");
|
||||
#endif
|
||||
@@ -1455,7 +1473,7 @@ static char *one_opt(int option, char *arg, char *gen_prob, int nest)
|
||||
|
||||
case LOPT_MINPORT: /* --min-port */
|
||||
if (!atoi_check16(arg, &daemon->min_port))
|
||||
option = '?';
|
||||
option = '?';
|
||||
break;
|
||||
|
||||
case '0': /* --dns-forward-max */
|
||||
@@ -1840,12 +1858,14 @@ option = '?';
|
||||
break;
|
||||
}
|
||||
|
||||
case 'O':
|
||||
case LOPT_FORCE:
|
||||
case 'O': /* --dhcp-option */
|
||||
case LOPT_FORCE: /* --dhcp-option-force */
|
||||
case LOPT_OPTS:
|
||||
case LOPT_MATCH: /* --dhcp-match */
|
||||
problem = parse_dhcp_opt(arg,
|
||||
option == LOPT_FORCE ? DHOPT_FORCE :
|
||||
(option == LOPT_OPTS ? DHOPT_BANK : 0));
|
||||
(option == LOPT_MATCH ? DHOPT_MATCH :
|
||||
(option == LOPT_OPTS ? DHOPT_BANK : 0)));
|
||||
break;
|
||||
|
||||
case 'M': /* --dhcp-boot */
|
||||
@@ -1921,7 +1941,6 @@ option = '?';
|
||||
case LOPT_CIRCUIT: /* --dhcp-circuitid */
|
||||
case LOPT_REMOTE: /* --dhcp-remoteid */
|
||||
case LOPT_SUBSCR: /* --dhcp-subscrid */
|
||||
case LOPT_MATCH: /* --dhcp-match */
|
||||
{
|
||||
if (!(comma = split(arg)))
|
||||
option = '?';
|
||||
@@ -1942,9 +1961,7 @@ option = '?';
|
||||
else if (*p != ':')
|
||||
break;
|
||||
unhide_metas(comma);
|
||||
if (option == LOPT_MATCH)
|
||||
new->option = atoi(comma);
|
||||
else if (option == 'U' || option == 'j' || *p || !dig)
|
||||
if (option == 'U' || option == 'j' || *p || !dig)
|
||||
{
|
||||
new->len = strlen(comma);
|
||||
new->data = opt_malloc(new->len);
|
||||
@@ -1974,9 +1991,6 @@ option = '?';
|
||||
case LOPT_SUBSCR:
|
||||
new->match_type = MATCH_SUBSCRIBER;
|
||||
break;
|
||||
case LOPT_MATCH:
|
||||
new->match_type = MATCH_OPTION;
|
||||
break;
|
||||
}
|
||||
new->next = daemon->dhcp_vendors;
|
||||
daemon->dhcp_vendors = new;
|
||||
@@ -2047,13 +2061,14 @@ option = '?';
|
||||
|
||||
case 'V': /* --alias */
|
||||
{
|
||||
char *a[3] = { NULL, NULL, NULL };
|
||||
char *dash, *a[3] = { NULL, NULL, NULL };
|
||||
int k = 0;
|
||||
struct in_addr in, out, mask;
|
||||
struct doctor *new;
|
||||
|
||||
mask.s_addr = 0xffffffff;
|
||||
|
||||
struct doctor *new = opt_malloc(sizeof(struct doctor));
|
||||
new->next = daemon->doctors;
|
||||
daemon->doctors = new;
|
||||
new->mask.s_addr = 0xffffffff;
|
||||
new->end.s_addr = 0;
|
||||
|
||||
if ((a[0] = arg))
|
||||
for (k = 1; k < 3; k++)
|
||||
{
|
||||
@@ -2062,23 +2077,21 @@ option = '?';
|
||||
unhide_metas(a[k]);
|
||||
}
|
||||
|
||||
dash = split_chr(a[0], '-');
|
||||
|
||||
if ((k < 2) ||
|
||||
((in.s_addr = inet_addr(a[0])) == (in_addr_t)-1) ||
|
||||
((out.s_addr = inet_addr(a[1])) == (in_addr_t)-1))
|
||||
{
|
||||
option = '?';
|
||||
break;
|
||||
}
|
||||
((new->in.s_addr = inet_addr(a[0])) == (in_addr_t)-1) ||
|
||||
((new->out.s_addr = inet_addr(a[1])) == (in_addr_t)-1))
|
||||
option = '?';
|
||||
|
||||
if (k == 3)
|
||||
mask.s_addr = inet_addr(a[2]);
|
||||
new->mask.s_addr = inet_addr(a[2]);
|
||||
|
||||
new = opt_malloc(sizeof(struct doctor));
|
||||
new->in = in;
|
||||
new->out = out;
|
||||
new->mask = mask;
|
||||
new->next = daemon->doctors;
|
||||
daemon->doctors = new;
|
||||
if (dash &&
|
||||
((new->end.s_addr = inet_addr(dash)) == (in_addr_t)-1 ||
|
||||
!is_same_net(new->in, new->end, new->mask) ||
|
||||
ntohl(new->in.s_addr) > ntohl(new->end.s_addr)))
|
||||
problem = _("invalid alias range");
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -2513,7 +2526,8 @@ void reread_dhcp(void)
|
||||
|
||||
if (opts->flags & DHOPT_BANK)
|
||||
{
|
||||
free(opts->vendor_class);
|
||||
if ((opts->flags & DHOPT_VENDOR))
|
||||
free(opts->u.vendor_class);
|
||||
free(opts->val);
|
||||
for (id = opts->netid; id; id = next)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user