mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-06 15:51:41 +00:00
Compare commits
25
Commits
v2.66test14
...
v2.66rc3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ac9787350 | ||
|
|
9f9bd08af8 | ||
|
|
4c985dac39 | ||
|
|
3d77c0460d | ||
|
|
3ddad24608 | ||
|
|
6e37ab595c | ||
|
|
a1a79edaea | ||
|
|
49333cbdbe | ||
|
|
de92b479d9 | ||
|
|
0f128eb58c | ||
|
|
c630924d66 | ||
|
|
ff59fc82b3 | ||
|
|
52a1ae72f0 | ||
|
|
3a654c506f | ||
|
|
2763d4b51a | ||
|
|
e28836bf45 | ||
|
|
a6ebfacf7b | ||
|
|
c7961075c4 | ||
|
|
ab6ede7e04 | ||
|
|
b3538f1100 | ||
|
|
3b323bda58 | ||
|
|
13d86c7372 | ||
|
|
208fb610a6 | ||
|
|
4038ae2005 | ||
|
|
dd1721c799 |
No files matched your search
@@ -31,6 +31,27 @@ version 2.66
|
|||||||
the local DNS server if dnsmasq is configured to not act
|
the local DNS server if dnsmasq is configured to not act
|
||||||
as DNS server, or it's configured to a non-standard port.
|
as DNS server, or it's configured to a non-standard port.
|
||||||
|
|
||||||
|
Add DNSMASQ_CIRCUIT_ID, DNSMASQ_SUBCRIBER_ID,
|
||||||
|
DNSMASQ_REMOTE_ID variables to the environment of the
|
||||||
|
lease-change script (and the corresponding Lua). These hold
|
||||||
|
information inserted into the DHCP request by a DHCP relay
|
||||||
|
agent. Thanks to Lakefield Communications for providing a
|
||||||
|
bounty for this addition.
|
||||||
|
|
||||||
|
Fixed crash, introduced in 2.64, whilst handling DHCPv6
|
||||||
|
information-requests with some common configurations.
|
||||||
|
Thanks to Robert M. Albrecht for the bug report and
|
||||||
|
chasing the problem.
|
||||||
|
|
||||||
|
Add --ipset option. Thanks to Jason A. Donenfeld for the
|
||||||
|
patch.
|
||||||
|
|
||||||
|
Don't erroneously reject some option names in --dhcp-match
|
||||||
|
options. Thanks to Benedikt Hochstrasser for the bug report.
|
||||||
|
|
||||||
|
Allow a trailing '*' wildcard in all interface-name
|
||||||
|
configurations. Thanks to Christian Parpart for the patch.
|
||||||
|
|
||||||
|
|
||||||
version 2.65
|
version 2.65
|
||||||
Fix regression which broke forwarding of queries sent via
|
Fix regression which broke forwarding of queries sent via
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ version = -DVERSION='\"`$(top)/bld/get-version $(top)`\"'
|
|||||||
objs = cache.o rfc1035.o util.o option.o forward.o network.o \
|
objs = cache.o rfc1035.o util.o option.o forward.o network.o \
|
||||||
dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o \
|
dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o \
|
||||||
helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o \
|
helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o \
|
||||||
dhcp-common.o outpacket.o radv.o slaac.o auth.o
|
dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o
|
||||||
|
|
||||||
hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
|
hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
|
||||||
dns-protocol.h radv-protocol.h
|
dns-protocol.h radv-protocol.h
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ LOCAL_SRC_FILES := bpf.c cache.c dbus.c dhcp.c dnsmasq.c \
|
|||||||
netlink.c network.c option.c rfc1035.c \
|
netlink.c network.c option.c rfc1035.c \
|
||||||
rfc2131.c tftp.c util.c conntrack.c \
|
rfc2131.c tftp.c util.c conntrack.c \
|
||||||
dhcp6.c rfc3315.c dhcp-common.c outpacket.c \
|
dhcp6.c rfc3315.c dhcp-common.c outpacket.c \
|
||||||
radv.c slaac.c auth.c
|
radv.c slaac.c auth.c ipset.c
|
||||||
|
|
||||||
LOCAL_MODULE := dnsmasq
|
LOCAL_MODULE := dnsmasq
|
||||||
|
|
||||||
|
|||||||
Vendored
+2
-1
@@ -1,8 +1,9 @@
|
|||||||
dnsmasq (2.66-1) unstable; urgency=low
|
dnsmasq (2.66-1) unstable; urgency=low
|
||||||
|
|
||||||
* New upstream.
|
* New upstream.
|
||||||
|
* Add support for noipset in DEB_BUILD_OPTIONS.
|
||||||
|
|
||||||
-- Simon Kelley <simon@thekelleys.org.uk> Fri, 14 Dec 2012 11:58:41 +0000
|
-- Simon Kelley <simon@thekelleys.org.uk> Fri, 22 Feb 2013 21:52:13 +0000
|
||||||
|
|
||||||
dnsmasq (2.65-1) unstable; urgency=low
|
dnsmasq (2.65-1) unstable; urgency=low
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
@@ -59,6 +59,7 @@ Notes on configuring dnsmasq as packaged for Debian.
|
|||||||
noipv6 : omit IPv6 support.
|
noipv6 : omit IPv6 support.
|
||||||
nodbus : omit DBus support.
|
nodbus : omit DBus support.
|
||||||
noconntrack : omit connection tracking support.
|
noconntrack : omit connection tracking support.
|
||||||
|
noipset : omit IPset support.
|
||||||
nortc : compile alternate mode suitable for systems without an RTC.
|
nortc : compile alternate mode suitable for systems without an RTC.
|
||||||
noi18n : omit translations and internationalisation support.
|
noi18n : omit translations and internationalisation support.
|
||||||
noidn : omit international domain name support, must be
|
noidn : omit international domain name support, must be
|
||||||
|
|||||||
Vendored
+4
@@ -33,6 +33,10 @@ ifeq ($(DEB_BUILD_ARCH_OS),linux)
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq (,$(filter noipset,$(DEB_BUILD_OPTIONS)))
|
||||||
|
COPTS += -DNO_IPSET
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter nodhcp6,$(DEB_BUILD_OPTIONS)))
|
ifneq (,$(filter nodhcp6,$(DEB_BUILD_OPTIONS)))
|
||||||
COPTS += -DNO_DHCP6
|
COPTS += -DNO_DHCP6
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -69,6 +69,10 @@
|
|||||||
# --address (and --server) work with IPv6 addresses too.
|
# --address (and --server) work with IPv6 addresses too.
|
||||||
#address=/www.thekelleys.org.uk/fe80::20d:60ff:fe36:f83
|
#address=/www.thekelleys.org.uk/fe80::20d:60ff:fe36:f83
|
||||||
|
|
||||||
|
# Add the IPs of all queries to yahoo.com, google.com, and their
|
||||||
|
# subdomains to the vpn and search ipsets:
|
||||||
|
#ipset=/yahoo.com/google.com/vpn,search
|
||||||
|
|
||||||
# You can control how dnsmasq talks to a server: this forces
|
# You can control how dnsmasq talks to a server: this forces
|
||||||
# queries to 10.1.2.3 to be routed via eth1
|
# queries to 10.1.2.3 to be routed via eth1
|
||||||
# server=10.1.2.3@eth1
|
# server=10.1.2.3@eth1
|
||||||
|
|||||||
+33
-6
@@ -171,7 +171,12 @@ options. IP alias interfaces (eg "eth1:0") cannot be used with
|
|||||||
.B --interface
|
.B --interface
|
||||||
or
|
or
|
||||||
.B --except-interface
|
.B --except-interface
|
||||||
options, use --listen-address instead.
|
options, use --listen-address instead. A simple wildcard, consisting
|
||||||
|
of a trailing '*', can be used in
|
||||||
|
.B \--interface
|
||||||
|
and
|
||||||
|
.B \--except-interface
|
||||||
|
options.
|
||||||
.TP
|
.TP
|
||||||
.B \-I, --except-interface=<interface name>
|
.B \-I, --except-interface=<interface name>
|
||||||
Do not listen on the specified interface. Note that the order of
|
Do not listen on the specified interface. Note that the order of
|
||||||
@@ -412,6 +417,12 @@ additional facility that /#/ matches any domain. Thus
|
|||||||
answered from /etc/hosts or DHCP and not sent to an upstream
|
answered from /etc/hosts or DHCP and not sent to an upstream
|
||||||
nameserver by a more specific --server directive.
|
nameserver by a more specific --server directive.
|
||||||
.TP
|
.TP
|
||||||
|
.B --ipset=/<domain>/[domain/]<ipset>[,<ipset>]
|
||||||
|
Places the resolved IP addresses of queries for the specified domains
|
||||||
|
in the specified netfilter ip sets. Domains and subdomains are matched
|
||||||
|
in the same way as --address. These ip sets must already exist. See
|
||||||
|
ipset(8) for more details.
|
||||||
|
.TP
|
||||||
.B \-m, --mx-host=<mx name>[[,<hostname>],<preference>]
|
.B \-m, --mx-host=<mx name>[[,<hostname>],<preference>]
|
||||||
Return an MX record named <mx name> pointing to the given hostname (if
|
Return an MX record named <mx name> pointing to the given hostname (if
|
||||||
given), or
|
given), or
|
||||||
@@ -547,7 +558,8 @@ Define a DNS zone for which dnsmasq acts as authoritative server. Locally define
|
|||||||
will be served, except that A and AAAA records must be in one of the
|
will be served, except that A and AAAA records must be in one of the
|
||||||
specified subnets, or in a subnet corresponding to a contructed DHCP
|
specified subnets, or in a subnet corresponding to a contructed DHCP
|
||||||
range. The subnet(s) are also used to define in-addr.arpa and
|
range. The subnet(s) are also used to define in-addr.arpa and
|
||||||
ipv6.arpa domains which are served for reverse-DNS queries.
|
ipv6.arpa domains which are served for reverse-DNS queries. For IPv4
|
||||||
|
subnets, the prefix length is limited to the values 8, 16 or 24.
|
||||||
.TP
|
.TP
|
||||||
.B --auth-soa=<serial>[,<hostmaster>[,<refresh>[,<retry>[,<expiry>]]]]
|
.B --auth-soa=<serial>[,<hostmaster>[,<refresh>[,<retry>[,<expiry>]]]]
|
||||||
Specify fields in the SOA record associated with authoritative
|
Specify fields in the SOA record associated with authoritative
|
||||||
@@ -1230,6 +1242,9 @@ For IPv4 only:
|
|||||||
|
|
||||||
DNSMASQ_CLIENT_ID if the host provided a client-id.
|
DNSMASQ_CLIENT_ID if the host provided a client-id.
|
||||||
|
|
||||||
|
DNSMASQ_CIRCUIT_ID, DNSMASQ_SUBSCRIBER_ID, DNSMASQ_REMOTE_ID if a
|
||||||
|
DHCP relay-agent added any of these options.
|
||||||
|
|
||||||
If the client provides vendor-class, DNSMASQ_VENDOR_CLASS.
|
If the client provides vendor-class, DNSMASQ_VENDOR_CLASS.
|
||||||
|
|
||||||
For IPv6 only:
|
For IPv6 only:
|
||||||
@@ -1744,7 +1759,7 @@ we have
|
|||||||
.fi
|
.fi
|
||||||
|
|
||||||
.nf
|
.nf
|
||||||
our.zone.com A 192.0.43.10
|
our.zone.com A 1.2.3.4
|
||||||
our.zone.com NS our.zone.com
|
our.zone.com NS our.zone.com
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
@@ -1757,11 +1772,23 @@ record. If the external address is static, this can be done with an
|
|||||||
.B /etc/hosts
|
.B /etc/hosts
|
||||||
entry or
|
entry or
|
||||||
.B --host-record.
|
.B --host-record.
|
||||||
If the external address is dynamic,
|
|
||||||
then it must be done using something like
|
|
||||||
|
|
||||||
.nf
|
.nf
|
||||||
.B --interface-name=our.zone.com,eth0
|
.B auth-server=our.zone.com,eth0
|
||||||
|
.B host-record=our.zone.com,1.2.3.4
|
||||||
|
.B auth-zone=our.zone.com,1.2.3.0/24
|
||||||
|
.fi
|
||||||
|
|
||||||
|
If the external address is dynamic, the address
|
||||||
|
associated with our.zone.com must be derived from the address of the
|
||||||
|
relvant interface. This is done using
|
||||||
|
.B interface-name
|
||||||
|
Something like:
|
||||||
|
|
||||||
|
.nf
|
||||||
|
.B auth-server=our.zone.com,eth0
|
||||||
|
.B interface-name=our.zone.com,eth0
|
||||||
|
.B auth-zone=our.zone.com,1.2.3.0/24
|
||||||
.fi
|
.fi
|
||||||
|
|
||||||
Our final configuration builds on that above, but also adds a
|
Our final configuration builds on that above, but also adds a
|
||||||
|
|||||||
+600
-405
File diff suppressed because it is too large.
Load diff
+1
-1
@@ -724,7 +724,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* done all questions, set up header and return length of result */
|
/* done all questions, set up header and return length of result */
|
||||||
/* clear authoritative and truncated flags, set QR flag */
|
/* clear authoritative and truncated flags, set QR flag */
|
||||||
|
|||||||
+13
-1
@@ -97,6 +97,10 @@ HAVE_CONNTRACK
|
|||||||
a build-dependency on libnetfilter_conntrack, but the resulting binary will
|
a build-dependency on libnetfilter_conntrack, but the resulting binary will
|
||||||
still run happily on a kernel without conntrack support.
|
still run happily on a kernel without conntrack support.
|
||||||
|
|
||||||
|
HAVE_IPSET
|
||||||
|
define this to include the ability to selectively add resolved ip addresses
|
||||||
|
to given ipsets.
|
||||||
|
|
||||||
HAVE_AUTH
|
HAVE_AUTH
|
||||||
define this to include the facility to act as an authoritative DNS
|
define this to include the facility to act as an authoritative DNS
|
||||||
server for one or more zones.
|
server for one or more zones.
|
||||||
@@ -131,6 +135,7 @@ RESOLVFILE
|
|||||||
#define HAVE_TFTP
|
#define HAVE_TFTP
|
||||||
#define HAVE_SCRIPT
|
#define HAVE_SCRIPT
|
||||||
#define HAVE_AUTH
|
#define HAVE_AUTH
|
||||||
|
#define HAVE_IPSET
|
||||||
/* #define HAVE_LUASCRIPT */
|
/* #define HAVE_LUASCRIPT */
|
||||||
/* #define HAVE_BROKEN_RTC */
|
/* #define HAVE_BROKEN_RTC */
|
||||||
/* #define HAVE_DBUS */
|
/* #define HAVE_DBUS */
|
||||||
@@ -138,7 +143,6 @@ RESOLVFILE
|
|||||||
/* #define HAVE_CONNTRACK */
|
/* #define HAVE_CONNTRACK */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Default locations for important system files. */
|
/* Default locations for important system files. */
|
||||||
|
|
||||||
#ifndef LEASEFILE
|
#ifndef LEASEFILE
|
||||||
@@ -323,6 +327,10 @@ HAVE_SOCKADDR_SA_LEN
|
|||||||
#undef HAVE_AUTH
|
#undef HAVE_AUTH
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(NO_IPSET) || !defined(HAVE_LINUX_NETWORK)
|
||||||
|
#undef HAVE_IPSET
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Define a string indicating which options are in use.
|
/* Define a string indicating which options are in use.
|
||||||
DNSMASQP_COMPILE_OPTS is only defined in dnsmasq.c */
|
DNSMASQP_COMPILE_OPTS is only defined in dnsmasq.c */
|
||||||
|
|
||||||
@@ -381,6 +389,10 @@ static char *compile_opts =
|
|||||||
"no-"
|
"no-"
|
||||||
#endif
|
#endif
|
||||||
"conntrack "
|
"conntrack "
|
||||||
|
#ifndef HAVE_IPSET
|
||||||
|
"no-"
|
||||||
|
#endif
|
||||||
|
"ipset "
|
||||||
#ifndef HAVE_AUTH
|
#ifndef HAVE_AUTH
|
||||||
"no-"
|
"no-"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+4
-11
@@ -518,8 +518,7 @@ u16 lookup_dhcp_opt(int prot, char *name)
|
|||||||
t = opttab;
|
t = opttab;
|
||||||
|
|
||||||
for (i = 0; t[i].name; i++)
|
for (i = 0; t[i].name; i++)
|
||||||
if (!(t[i].size & OT_INTERNAL) &&
|
if (strcasecmp(t[i].name, name) == 0)
|
||||||
strcasecmp(t[i].name, name) == 0)
|
|
||||||
return t[i].val;
|
return t[i].val;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -539,14 +538,9 @@ u16 lookup_dhcp_len(int prot, u16 val)
|
|||||||
|
|
||||||
for (i = 0; t[i].name; i++)
|
for (i = 0; t[i].name; i++)
|
||||||
if (val == t[i].val)
|
if (val == t[i].val)
|
||||||
{
|
return t[i].size & ~OT_DEC;
|
||||||
if (t[i].size & OT_INTERNAL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return t[i].size & ~OT_DEC;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *option_string(int prot, unsigned int opt, unsigned char *val, int opt_len, char *buf, int buf_len)
|
char *option_string(int prot, unsigned int opt, unsigned char *val, int opt_len, char *buf, int buf_len)
|
||||||
@@ -720,8 +714,7 @@ void log_context(int family, struct dhcp_context *context)
|
|||||||
template = p;
|
template = p;
|
||||||
p += sprintf(p, ", ");
|
p += sprintf(p, ", ");
|
||||||
|
|
||||||
sprintf(p, "template for %s%s", context->template_interface,
|
sprintf(p, "template for %s", context->template_interface);
|
||||||
(context->flags & CONTEXT_WILDCARD) ? "*" : "");
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -252,7 +252,7 @@ void dhcp_packet(time_t now, int pxe_fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||||
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
|
if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* unlinked contexts are marked by context->current == context */
|
/* unlinked contexts are marked by context->current == context */
|
||||||
|
|||||||
@@ -59,6 +59,11 @@
|
|||||||
#define OPTION6_SUBSCRIBER_ID 38
|
#define OPTION6_SUBSCRIBER_ID 38
|
||||||
#define OPTION6_FQDN 39
|
#define OPTION6_FQDN 39
|
||||||
|
|
||||||
|
/* replace this with the real number when allocated.
|
||||||
|
defining this also enables the relevant code. */
|
||||||
|
/* #define OPTION6_PREFIX_CLASS 99 */
|
||||||
|
|
||||||
|
|
||||||
#define DHCP6SUCCESS 0
|
#define DHCP6SUCCESS 0
|
||||||
#define DHCP6UNSPEC 1
|
#define DHCP6UNSPEC 1
|
||||||
#define DHCP6NOADDRS 2
|
#define DHCP6NOADDRS 2
|
||||||
|
|||||||
+36
-57
@@ -120,11 +120,11 @@ void dhcp6_packet(time_t now)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for (tmp = daemon->if_except; tmp; tmp = tmp->next)
|
for (tmp = daemon->if_except; tmp; tmp = tmp->next)
|
||||||
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
|
if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||||
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
|
if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
parm.current = NULL;
|
parm.current = NULL;
|
||||||
@@ -153,7 +153,7 @@ void dhcp6_packet(time_t now)
|
|||||||
{
|
{
|
||||||
|
|
||||||
for (tmp = daemon->if_names; tmp; tmp = tmp->next)
|
for (tmp = daemon->if_names; tmp; tmp = tmp->next)
|
||||||
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
|
if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!tmp && !parm.addr_match)
|
if (!tmp && !parm.addr_match)
|
||||||
@@ -265,8 +265,8 @@ struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int address6_allocate(struct dhcp_context *context, unsigned char *clid, int clid_len,
|
struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned char *clid, int clid_len,
|
||||||
int serial, struct dhcp_netid *netids, struct in6_addr *ans)
|
int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans)
|
||||||
{
|
{
|
||||||
/* Find a free address: exclude anything in use and anything allocated to
|
/* Find a free address: exclude anything in use and anything allocated to
|
||||||
a particular hwaddr/clientid/hostname in our configuration.
|
a particular hwaddr/clientid/hostname in our configuration.
|
||||||
@@ -283,12 +283,12 @@ int address6_allocate(struct dhcp_context *context, unsigned char *clid, int cl
|
|||||||
|
|
||||||
/* hash hwaddr: use the SDBM hashing algorithm. This works
|
/* hash hwaddr: use the SDBM hashing algorithm. This works
|
||||||
for MAC addresses, let's see how it manages with client-ids! */
|
for MAC addresses, let's see how it manages with client-ids! */
|
||||||
for (j = 0, i = 0; i < clid_len; i++)
|
for (j = iaid, i = 0; i < clid_len; i++)
|
||||||
j += clid[i] + (j << 6) + (j << 16) - j;
|
j += clid[i] + (j << 6) + (j << 16) - j;
|
||||||
|
|
||||||
for (pass = 0; pass <= 1; pass++)
|
for (pass = 0; pass <= plain_range ? 1 : 0; pass++)
|
||||||
for (c = context; c; c = c->current)
|
for (c = context; c; c = c->current)
|
||||||
if (c->flags & (CONTEXT_DEPRECATE | CONTEXT_STATIC | CONTEXT_RA_STATELESS))
|
if (c->flags & (CONTEXT_DEPRECATE | CONTEXT_STATIC | CONTEXT_RA_STATELESS | CONTEXT_USED))
|
||||||
continue;
|
continue;
|
||||||
else if (!match_netid(c->filter, netids, pass))
|
else if (!match_netid(c->filter, netids, pass))
|
||||||
continue;
|
continue;
|
||||||
@@ -298,7 +298,7 @@ int address6_allocate(struct dhcp_context *context, unsigned char *clid, int cl
|
|||||||
/* seed is largest extant lease addr in this context */
|
/* seed is largest extant lease addr in this context */
|
||||||
start = lease_find_max_addr6(c) + serial;
|
start = lease_find_max_addr6(c) + serial;
|
||||||
else
|
else
|
||||||
start = addr6part(&c->start6) + ((j + c->addr_epoch + serial) % (1 + addr6part(&c->end6) - addr6part(&c->start6)));
|
start = addr6part(&c->start6) + ((j + c->addr_epoch) % (1 + addr6part(&c->end6) - addr6part(&c->start6)));
|
||||||
|
|
||||||
/* iterate until we find a free address. */
|
/* iterate until we find a free address. */
|
||||||
addr = start;
|
addr = start;
|
||||||
@@ -315,7 +315,7 @@ int address6_allocate(struct dhcp_context *context, unsigned char *clid, int cl
|
|||||||
{
|
{
|
||||||
*ans = c->start6;
|
*ans = c->start6;
|
||||||
setaddr6part (ans, addr);
|
setaddr6part (ans, addr);
|
||||||
return 1;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr++;
|
addr++;
|
||||||
@@ -332,7 +332,8 @@ int address6_allocate(struct dhcp_context *context, unsigned char *clid, int cl
|
|||||||
/* can dynamically allocate addr */
|
/* can dynamically allocate addr */
|
||||||
struct dhcp_context *address6_available(struct dhcp_context *context,
|
struct dhcp_context *address6_available(struct dhcp_context *context,
|
||||||
struct in6_addr *taddr,
|
struct in6_addr *taddr,
|
||||||
struct dhcp_netid *netids)
|
struct dhcp_netid *netids,
|
||||||
|
int plain_range)
|
||||||
{
|
{
|
||||||
u64 start, end, addr = addr6part(taddr);
|
u64 start, end, addr = addr6part(taddr);
|
||||||
struct dhcp_context *tmp;
|
struct dhcp_context *tmp;
|
||||||
@@ -347,7 +348,7 @@ struct dhcp_context *address6_available(struct dhcp_context *context,
|
|||||||
is_same_net6(&tmp->end6, taddr, tmp->prefix) &&
|
is_same_net6(&tmp->end6, taddr, tmp->prefix) &&
|
||||||
addr >= start &&
|
addr >= start &&
|
||||||
addr <= end &&
|
addr <= end &&
|
||||||
match_netid(tmp->filter, netids, 1))
|
match_netid(tmp->filter, netids, plain_range))
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,70 +357,50 @@ struct dhcp_context *address6_available(struct dhcp_context *context,
|
|||||||
|
|
||||||
/* address OK if configured */
|
/* address OK if configured */
|
||||||
struct dhcp_context *address6_valid(struct dhcp_context *context,
|
struct dhcp_context *address6_valid(struct dhcp_context *context,
|
||||||
struct in6_addr *taddr,
|
struct in6_addr *taddr,
|
||||||
struct dhcp_netid *netids)
|
struct dhcp_netid *netids,
|
||||||
|
int plain_range)
|
||||||
{
|
{
|
||||||
struct dhcp_context *tmp;
|
struct dhcp_context *tmp;
|
||||||
|
|
||||||
for (tmp = context; tmp; tmp = tmp->current)
|
for (tmp = context; tmp; tmp = tmp->current)
|
||||||
if (is_same_net6(&tmp->start6, taddr, tmp->prefix) &&
|
if (is_same_net6(&tmp->start6, taddr, tmp->prefix) &&
|
||||||
match_netid(tmp->filter, netids, 1))
|
match_netid(tmp->filter, netids, plain_range))
|
||||||
return tmp;
|
return tmp;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dhcp_context *narrow_context6(struct dhcp_context *context,
|
int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr)
|
||||||
struct in6_addr *taddr,
|
|
||||||
struct dhcp_netid *netids)
|
|
||||||
{
|
{
|
||||||
/* We start of with a set of possible contexts, all on the current physical interface.
|
if (!config || !(config->flags & CONFIG_ADDR6))
|
||||||
These are chained on ->current.
|
return 0;
|
||||||
Here we have an address, and return the actual context correponding to that
|
|
||||||
address. Note that none may fit, if the address came a dhcp-host and is outside
|
|
||||||
any dhcp-range. In that case we return a static range if possible, or failing that,
|
|
||||||
any context on the correct subnet. (If there's more than one, this is a dodgy
|
|
||||||
configuration: maybe there should be a warning.) */
|
|
||||||
|
|
||||||
struct dhcp_context *tmp;
|
if ((config->flags & CONFIG_WILDCARD) && context->prefix == 64)
|
||||||
|
|
||||||
if (!(tmp = address6_available(context, taddr, netids)) &&
|
|
||||||
!(tmp = address6_valid(context, taddr, netids)))
|
|
||||||
for (tmp = context; tmp; tmp = tmp->current)
|
|
||||||
if (match_netid(tmp->filter, netids, 1) &&
|
|
||||||
is_same_net6(taddr, &tmp->start6, tmp->prefix))
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Only one context allowed now */
|
|
||||||
if (tmp)
|
|
||||||
tmp->current = NULL;
|
|
||||||
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int is_config_in_context6(struct dhcp_context *context, struct dhcp_config *config)
|
|
||||||
{
|
|
||||||
/* expand wildcard on contructed contexts */
|
|
||||||
if ((config->flags & CONFIG_WILDCARD) &&
|
|
||||||
(context->flags & CONTEXT_CONSTRUCTED))
|
|
||||||
{
|
{
|
||||||
u64 addrpart = addr6part(&config->addr6);
|
*addr = context->start6;
|
||||||
config->addr6 = context->start6;
|
setaddr6part(addr, addr6part(&config->addr6));
|
||||||
setaddr6part(&config->addr6, addrpart);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(config->flags & CONFIG_ADDR6) || is_addr_in_context6(context, &config->addr6))
|
if (is_same_net6(&context->start6, &config->addr6, context->prefix))
|
||||||
return 1;
|
{
|
||||||
|
*addr = config->addr6;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int is_config_in_context6(struct dhcp_context *context, struct dhcp_config *config)
|
||||||
int is_addr_in_context6(struct dhcp_context *context, struct in6_addr *addr)
|
|
||||||
{
|
{
|
||||||
|
if (!(config->flags & CONFIG_ADDR6) ||
|
||||||
|
(config->flags & CONFIG_WILDCARD))
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
for (; context; context = context->current)
|
for (; context; context = context->current)
|
||||||
if (is_same_net6(addr, &context->start6, context->prefix))
|
if (is_same_net6(&config->addr6, &context->start6, context->prefix))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -549,9 +530,7 @@ static int construct_worker(struct in6_addr *local, int prefix,
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (addr6part(local) == addr6part(&template->start6) &&
|
else if (addr6part(local) == addr6part(&template->start6) && wildcard_match(template->template_interface, ifrn_name))
|
||||||
strncmp(template->template_interface, ifrn_name, strlen(template->template_interface)) == 0 &&
|
|
||||||
(strlen(template->template_interface) == strlen(ifrn_name) || (template->flags & CONTEXT_WILDCARD)))
|
|
||||||
{
|
{
|
||||||
start6 = *local;
|
start6 = *local;
|
||||||
setaddr6part(&start6, addr6part(&template->start6));
|
setaddr6part(&start6, addr6part(&template->start6));
|
||||||
|
|||||||
@@ -213,6 +213,11 @@ int main (int argc, char **argv)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_IPSET
|
||||||
|
if (daemon->ipsets)
|
||||||
|
ipset_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_LINUX_NETWORK
|
#ifdef HAVE_LINUX_NETWORK
|
||||||
netlink_init();
|
netlink_init();
|
||||||
|
|
||||||
|
|||||||
+39
-11
@@ -430,6 +430,12 @@ struct server {
|
|||||||
struct server *next;
|
struct server *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ipsets {
|
||||||
|
char **sets;
|
||||||
|
char *domain;
|
||||||
|
struct ipsets *next;
|
||||||
|
};
|
||||||
|
|
||||||
struct irec {
|
struct irec {
|
||||||
union mysockaddr addr;
|
union mysockaddr addr;
|
||||||
struct in_addr netmask; /* only valid for IPv4 */
|
struct in_addr netmask; /* only valid for IPv4 */
|
||||||
@@ -675,6 +681,14 @@ struct cond_domain {
|
|||||||
struct cond_domain *next;
|
struct cond_domain *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef OPTION6_PREFIX_CLASS
|
||||||
|
struct prefix_class {
|
||||||
|
int class;
|
||||||
|
struct dhcp_netid tag;
|
||||||
|
struct prefix_class *next;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
struct dhcp_context {
|
struct dhcp_context {
|
||||||
unsigned int lease_time, addr_epoch;
|
unsigned int lease_time, addr_epoch;
|
||||||
struct in_addr netmask, broadcast;
|
struct in_addr netmask, broadcast;
|
||||||
@@ -707,7 +721,8 @@ struct dhcp_context {
|
|||||||
#define CONTEXT_CONSTRUCTED 2048
|
#define CONTEXT_CONSTRUCTED 2048
|
||||||
#define CONTEXT_GC 4096
|
#define CONTEXT_GC 4096
|
||||||
#define CONTEXT_RA 8192
|
#define CONTEXT_RA 8192
|
||||||
#define CONTEXT_WILDCARD 16384
|
#define CONTEXT_CONF_USED 16384
|
||||||
|
#define CONTEXT_USED 32768
|
||||||
|
|
||||||
struct ping_result {
|
struct ping_result {
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
@@ -779,6 +794,7 @@ extern struct daemon {
|
|||||||
struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers;
|
struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers;
|
||||||
struct bogus_addr *bogus_addr;
|
struct bogus_addr *bogus_addr;
|
||||||
struct server *servers;
|
struct server *servers;
|
||||||
|
struct ipsets *ipsets;
|
||||||
int log_fac; /* log facility */
|
int log_fac; /* log facility */
|
||||||
char *log_file; /* optional log file */
|
char *log_file; /* optional log file */
|
||||||
int max_logs; /* queue limit */
|
int max_logs; /* queue limit */
|
||||||
@@ -813,6 +829,9 @@ extern struct daemon {
|
|||||||
unsigned char *duid_config;
|
unsigned char *duid_config;
|
||||||
char *dbus_name;
|
char *dbus_name;
|
||||||
unsigned long soa_sn, soa_refresh, soa_retry, soa_expiry;
|
unsigned long soa_sn, soa_refresh, soa_retry, soa_expiry;
|
||||||
|
#ifdef OPTION6_PREFIX_CLASS
|
||||||
|
struct prefix_class *prefix_classes;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* globally used stuff for DNS */
|
/* globally used stuff for DNS */
|
||||||
char *packet; /* packet buffer */
|
char *packet; /* packet buffer */
|
||||||
@@ -903,7 +922,8 @@ size_t setup_reply(struct dns_header *header, size_t qlen,
|
|||||||
struct all_addr *addrp, unsigned int flags,
|
struct all_addr *addrp, unsigned int flags,
|
||||||
unsigned long local_ttl);
|
unsigned long local_ttl);
|
||||||
int extract_addresses(struct dns_header *header, size_t qlen, char *namebuff,
|
int extract_addresses(struct dns_header *header, size_t qlen, char *namebuff,
|
||||||
time_t now, int is_sign, int checkrebind, int checking_disabled);
|
time_t now, char **ipsets, int is_sign, int checkrebind,
|
||||||
|
int checking_disabled);
|
||||||
size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||||
struct in_addr local_addr, struct in_addr local_netmask, time_t now);
|
struct in_addr local_addr, struct in_addr local_netmask, time_t now);
|
||||||
int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
|
int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
|
||||||
@@ -959,6 +979,8 @@ char *print_mac(char *buff, unsigned char *mac, int len);
|
|||||||
void bump_maxfd(int fd, int *max);
|
void bump_maxfd(int fd, int *max);
|
||||||
int read_write(int fd, unsigned char *packet, int size, int rw);
|
int read_write(int fd, unsigned char *packet, int size, int rw);
|
||||||
|
|
||||||
|
int wildcard_match(const char* wildcard, const char* match);
|
||||||
|
|
||||||
/* log.c */
|
/* log.c */
|
||||||
void die(char *message, char *arg1, int exit_code);
|
void die(char *message, char *arg1, int exit_code);
|
||||||
int log_start(struct passwd *ent_pw, int errfd);
|
int log_start(struct passwd *ent_pw, int errfd);
|
||||||
@@ -1047,7 +1069,8 @@ struct dhcp_lease *lease4_allocate(struct in_addr addr);
|
|||||||
struct dhcp_lease *lease6_allocate(struct in6_addr *addrp, int lease_type);
|
struct dhcp_lease *lease6_allocate(struct in6_addr *addrp, int lease_type);
|
||||||
struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len,
|
struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len,
|
||||||
int lease_type, int iaid, struct in6_addr *addr);
|
int lease_type, int iaid, struct in6_addr *addr);
|
||||||
void lease6_filter(int lease_type, int iaid, struct dhcp_context *context);
|
void lease6_reset(void);
|
||||||
|
struct dhcp_lease *lease6_find_by_client(struct dhcp_lease *first, int lease_type, unsigned char *clid, int clid_len, int iaid);
|
||||||
struct dhcp_lease *lease6_find_by_addr(struct in6_addr *net, int prefix, u64 addr);
|
struct dhcp_lease *lease6_find_by_addr(struct in6_addr *net, int prefix, u64 addr);
|
||||||
u64 lease_find_max_addr6(struct dhcp_context *context);
|
u64 lease_find_max_addr6(struct dhcp_context *context);
|
||||||
void lease_ping_reply(struct in6_addr *sender, unsigned char *packet, char *interface);
|
void lease_ping_reply(struct in6_addr *sender, unsigned char *packet, char *interface);
|
||||||
@@ -1117,6 +1140,12 @@ void emit_dbus_signal(int action, struct dhcp_lease *lease, char *hostname);
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* ipset.c */
|
||||||
|
#ifdef HAVE_IPSET
|
||||||
|
void ipset_init(void);
|
||||||
|
int add_to_ipset(const char *setname, const struct all_addr *ipaddr, int flags, int remove);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* helper.c */
|
/* helper.c */
|
||||||
#if defined(HAVE_SCRIPT)
|
#if defined(HAVE_SCRIPT)
|
||||||
int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd);
|
int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd);
|
||||||
@@ -1146,18 +1175,17 @@ int get_incoming_mark(union mysockaddr *peer_addr, struct all_addr *local_addr,
|
|||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
void dhcp6_init(void);
|
void dhcp6_init(void);
|
||||||
void dhcp6_packet(time_t now);
|
void dhcp6_packet(time_t now);
|
||||||
int address6_allocate(struct dhcp_context *context, unsigned char *clid, int clid_len,
|
struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned char *clid, int clid_len,
|
||||||
int serial, struct dhcp_netid *netids, struct in6_addr *ans);
|
int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans);
|
||||||
int is_addr_in_context6(struct dhcp_context *context, struct in6_addr *addr);
|
int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr);
|
||||||
struct dhcp_context *address6_available(struct dhcp_context *context,
|
struct dhcp_context *address6_available(struct dhcp_context *context,
|
||||||
struct in6_addr *taddr,
|
struct in6_addr *taddr,
|
||||||
struct dhcp_netid *netids);
|
struct dhcp_netid *netids,
|
||||||
|
int plain_range);
|
||||||
struct dhcp_context *address6_valid(struct dhcp_context *context,
|
struct dhcp_context *address6_valid(struct dhcp_context *context,
|
||||||
struct in6_addr *taddr,
|
struct in6_addr *taddr,
|
||||||
struct dhcp_netid *netids);
|
struct dhcp_netid *netids,
|
||||||
struct dhcp_context *narrow_context6(struct dhcp_context *context,
|
int plain_range);
|
||||||
struct in6_addr *taddr,
|
|
||||||
struct dhcp_netid *netids);
|
|
||||||
struct dhcp_config *find_config6(struct dhcp_config *configs,
|
struct dhcp_config *find_config6(struct dhcp_config *configs,
|
||||||
struct dhcp_context *context,
|
struct dhcp_context *context,
|
||||||
unsigned char *duid, int duid_len,
|
unsigned char *duid, int duid_len,
|
||||||
|
|||||||
+20
-1
@@ -439,9 +439,28 @@ static size_t process_reply(struct dns_header *header, time_t now,
|
|||||||
struct server *server, size_t n, int check_rebind, int checking_disabled)
|
struct server *server, size_t n, int check_rebind, int checking_disabled)
|
||||||
{
|
{
|
||||||
unsigned char *pheader, *sizep;
|
unsigned char *pheader, *sizep;
|
||||||
|
char **sets = 0;
|
||||||
int munged = 0, is_sign;
|
int munged = 0, is_sign;
|
||||||
size_t plen;
|
size_t plen;
|
||||||
|
|
||||||
|
#ifdef HAVE_IPSET
|
||||||
|
/* Similar algorithm to search_servers. */
|
||||||
|
struct ipsets *ipset_pos;
|
||||||
|
unsigned int namelen = strlen(daemon->namebuff);
|
||||||
|
unsigned int matchlen = 0;
|
||||||
|
for (ipset_pos = daemon->ipsets; ipset_pos; ipset_pos = ipset_pos->next)
|
||||||
|
{
|
||||||
|
unsigned int domainlen = strlen(ipset_pos->domain);
|
||||||
|
char *matchstart = daemon->namebuff + namelen - domainlen;
|
||||||
|
if (namelen >= domainlen && hostname_isequal(matchstart, ipset_pos->domain) &&
|
||||||
|
(domainlen == 0 || namelen == domainlen || *(matchstart - 1) == '.' ) &&
|
||||||
|
domainlen >= matchlen) {
|
||||||
|
matchlen = domainlen;
|
||||||
|
sets = ipset_pos->sets;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* If upstream is advertising a larger UDP packet size
|
/* If upstream is advertising a larger UDP packet size
|
||||||
than we allow, trim it so that we don't get overlarge
|
than we allow, trim it so that we don't get overlarge
|
||||||
requests for the client. We can't do this for signed packets. */
|
requests for the client. We can't do this for signed packets. */
|
||||||
@@ -494,7 +513,7 @@ static size_t process_reply(struct dns_header *header, time_t now,
|
|||||||
SET_RCODE(header, NOERROR);
|
SET_RCODE(header, NOERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extract_addresses(header, n, daemon->namebuff, now, is_sign, check_rebind, checking_disabled))
|
if (extract_addresses(header, n, daemon->namebuff, now, sets, is_sign, check_rebind, checking_disabled))
|
||||||
{
|
{
|
||||||
my_syslog(LOG_WARNING, _("possible DNS-rebind attack detected: %s"), daemon->namebuff);
|
my_syslog(LOG_WARNING, _("possible DNS-rebind attack detected: %s"), daemon->namebuff);
|
||||||
munged = 1;
|
munged = 1;
|
||||||
|
|||||||
+8
-7
@@ -229,13 +229,6 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* expiry or length into dhcp_buff2 */
|
|
||||||
#ifdef HAVE_BROKEN_RTC
|
|
||||||
sprintf(daemon->dhcp_buff2, "%u", data.length);
|
|
||||||
#else
|
|
||||||
sprintf(daemon->dhcp_buff2, "%lu", (unsigned long)data.expires);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* supplied data may just exceed normal buffer (unlikely) */
|
/* supplied data may just exceed normal buffer (unlikely) */
|
||||||
if ((data.hostname_len + data.ed_len + data.clid_len) > MAXDNAME &&
|
if ((data.hostname_len + data.ed_len + data.clid_len) > MAXDNAME &&
|
||||||
!(alloc_buff = buf = malloc(data.hostname_len + data.ed_len + data.clid_len)))
|
!(alloc_buff = buf = malloc(data.hostname_len + data.ed_len + data.clid_len)))
|
||||||
@@ -397,6 +390,9 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
buf = grab_extradata_lua(buf, end, "cpewan_oui");
|
buf = grab_extradata_lua(buf, end, "cpewan_oui");
|
||||||
buf = grab_extradata_lua(buf, end, "cpewan_serial");
|
buf = grab_extradata_lua(buf, end, "cpewan_serial");
|
||||||
buf = grab_extradata_lua(buf, end, "cpewan_class");
|
buf = grab_extradata_lua(buf, end, "cpewan_class");
|
||||||
|
buf = grab_extradata_lua(buf, end, "circuit_id");
|
||||||
|
buf = grab_extradata_lua(buf, end, "subscriber_id");
|
||||||
|
buf = grab_extradata_lua(buf, end, "remote_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = grab_extradata_lua(buf, end, "tags");
|
buf = grab_extradata_lua(buf, end, "tags");
|
||||||
@@ -493,8 +489,10 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
my_setenv("DNSMASQ_INTERFACE", data.interface, &err);
|
my_setenv("DNSMASQ_INTERFACE", data.interface, &err);
|
||||||
|
|
||||||
#ifdef HAVE_BROKEN_RTC
|
#ifdef HAVE_BROKEN_RTC
|
||||||
|
sprintf(daemon->dhcp_buff2, "%u", data.length);
|
||||||
my_setenv("DNSMASQ_LEASE_LENGTH", daemon->dhcp_buff2, &err);
|
my_setenv("DNSMASQ_LEASE_LENGTH", daemon->dhcp_buff2, &err);
|
||||||
#else
|
#else
|
||||||
|
sprintf(daemon->dhcp_buff2, "%lu", (unsigned long)data.expires);
|
||||||
my_setenv("DNSMASQ_LEASE_EXPIRES", daemon->dhcp_buff2, &err);
|
my_setenv("DNSMASQ_LEASE_EXPIRES", daemon->dhcp_buff2, &err);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -528,6 +526,9 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
buf = grab_extradata(buf, end, "DNSMASQ_CPEWAN_OUI", &err);
|
buf = grab_extradata(buf, end, "DNSMASQ_CPEWAN_OUI", &err);
|
||||||
buf = grab_extradata(buf, end, "DNSMASQ_CPEWAN_SERIAL", &err);
|
buf = grab_extradata(buf, end, "DNSMASQ_CPEWAN_SERIAL", &err);
|
||||||
buf = grab_extradata(buf, end, "DNSMASQ_CPEWAN_CLASS", &err);
|
buf = grab_extradata(buf, end, "DNSMASQ_CPEWAN_CLASS", &err);
|
||||||
|
buf = grab_extradata(buf, end, "DNSMASQ_CIRCUIT_ID", &err);
|
||||||
|
buf = grab_extradata(buf, end, "DNSMASQ_SUBSCRIBER_ID", &err);
|
||||||
|
buf = grab_extradata(buf, end, "DNSMASQ_REMOTE_ID", &err);
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = grab_extradata(buf, end, "DNSMASQ_TAGS", &err);
|
buf = grab_extradata(buf, end, "DNSMASQ_TAGS", &err);
|
||||||
|
|||||||
+205
@@ -0,0 +1,205 @@
|
|||||||
|
/* ipset.c is Copyright (c) 2013 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
||||||
|
|
||||||
|
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
|
||||||
|
the Free Software Foundation; version 2 dated June, 1991, or
|
||||||
|
(at your option) version 3 dated 29 June, 2007.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dnsmasq.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_IPSET
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <linux/version.h>
|
||||||
|
#include <linux/netlink.h>
|
||||||
|
#include <linux/netfilter/nfnetlink.h>
|
||||||
|
#ifndef NFNL_SUBSYS_IPSET
|
||||||
|
#define NFNL_SUBSYS_IPSET 6
|
||||||
|
#define IPSET_ATTR_DATA 7
|
||||||
|
#define IPSET_ATTR_IP 1
|
||||||
|
#define IPSET_ATTR_IPADDR_IPV4 1
|
||||||
|
#define IPSET_ATTR_IPADDR_IPV6 2
|
||||||
|
#define IPSET_ATTR_PROTOCOL 1
|
||||||
|
#define IPSET_ATTR_SETNAME 2
|
||||||
|
#define IPSET_CMD_ADD 9
|
||||||
|
#define IPSET_CMD_DEL 10
|
||||||
|
#define IPSET_MAXNAMELEN 32
|
||||||
|
#define IPSET_PROTOCOL 6
|
||||||
|
#else
|
||||||
|
#include <linux/netfilter/ipset/ip_set.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* data structure size in here is fixed */
|
||||||
|
#define BUFF_SZ 256
|
||||||
|
|
||||||
|
#define NL_ALIGN(len) (((len)+3) & ~(3))
|
||||||
|
static const struct sockaddr_nl snl = { .nl_family = AF_NETLINK };
|
||||||
|
static int ipset_sock, old_kernel;
|
||||||
|
static char *buffer;
|
||||||
|
|
||||||
|
static inline void add_attr(struct nlmsghdr *nlh, uint16_t type, size_t len, const void *data)
|
||||||
|
{
|
||||||
|
struct nlattr *attr = (void *)nlh + NL_ALIGN(nlh->nlmsg_len);
|
||||||
|
uint16_t payload_len = NL_ALIGN(sizeof(struct nlattr)) + len;
|
||||||
|
attr->nla_type = type;
|
||||||
|
attr->nla_len = payload_len;
|
||||||
|
memcpy((void *)attr + NL_ALIGN(sizeof(struct nlattr)), data, len);
|
||||||
|
nlh->nlmsg_len += NL_ALIGN(payload_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ipset_init(void)
|
||||||
|
{
|
||||||
|
struct utsname utsname;
|
||||||
|
int version;
|
||||||
|
char *split;
|
||||||
|
|
||||||
|
if (uname(&utsname) < 0)
|
||||||
|
die(_("failed to find kernel version: %s"), NULL, EC_MISC);
|
||||||
|
|
||||||
|
split = strtok(utsname.release, ".");
|
||||||
|
version = (split ? atoi(split) : 0);
|
||||||
|
split = strtok(NULL, ".");
|
||||||
|
version = version * 256 + (split ? atoi(split) : 0);
|
||||||
|
split = strtok(NULL, ".");
|
||||||
|
version = version * 256 + (split ? atoi(split) : 0);
|
||||||
|
old_kernel = (version < KERNEL_VERSION(2,6,32));
|
||||||
|
|
||||||
|
if (old_kernel && (ipset_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) != -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!old_kernel &&
|
||||||
|
(buffer = safe_malloc(BUFF_SZ)) &&
|
||||||
|
(ipset_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER)) != -1 &&
|
||||||
|
(bind(ipset_sock, (struct sockaddr *)&snl, sizeof(snl)) != -1))
|
||||||
|
return;
|
||||||
|
|
||||||
|
die (_("failed to create IPset control socket: %s"), NULL, EC_MISC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int new_add_to_ipset(const char *setname, const struct all_addr *ipaddr, int af, int remove)
|
||||||
|
{
|
||||||
|
struct nlmsghdr *nlh;
|
||||||
|
struct nfgenmsg *nfg;
|
||||||
|
struct nlattr *nested[2];
|
||||||
|
uint8_t proto;
|
||||||
|
int addrsz = INADDRSZ;
|
||||||
|
ssize_t rc;
|
||||||
|
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
if (af == AF_INET6)
|
||||||
|
addrsz = IN6ADDRSZ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (strlen(setname) >= IPSET_MAXNAMELEN)
|
||||||
|
{
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(buffer, 0, sizeof(buffer));
|
||||||
|
|
||||||
|
nlh = (struct nlmsghdr *)buffer;
|
||||||
|
nlh->nlmsg_len = NL_ALIGN(sizeof(struct nlmsghdr));
|
||||||
|
nlh->nlmsg_type = (remove ? IPSET_CMD_DEL : IPSET_CMD_ADD) | (NFNL_SUBSYS_IPSET << 8);
|
||||||
|
nlh->nlmsg_flags = NLM_F_REQUEST;
|
||||||
|
|
||||||
|
nfg = (struct nfgenmsg *)(buffer + nlh->nlmsg_len);
|
||||||
|
nlh->nlmsg_len += NL_ALIGN(sizeof(struct nfgenmsg));
|
||||||
|
nfg->nfgen_family = af;
|
||||||
|
nfg->version = NFNETLINK_V0;
|
||||||
|
nfg->res_id = htons(0);
|
||||||
|
|
||||||
|
proto = IPSET_PROTOCOL;
|
||||||
|
add_attr(nlh, IPSET_ATTR_PROTOCOL, sizeof(proto), &proto);
|
||||||
|
add_attr(nlh, IPSET_ATTR_SETNAME, strlen(setname) + 1, setname);
|
||||||
|
nested[0] = (struct nlattr *)(buffer + NL_ALIGN(nlh->nlmsg_len));
|
||||||
|
nlh->nlmsg_len += NL_ALIGN(sizeof(struct nlattr));
|
||||||
|
nested[0]->nla_type = NLA_F_NESTED | IPSET_ATTR_DATA;
|
||||||
|
nested[1] = (struct nlattr *)(buffer + NL_ALIGN(nlh->nlmsg_len));
|
||||||
|
nlh->nlmsg_len += NL_ALIGN(sizeof(struct nlattr));
|
||||||
|
nested[1]->nla_type = NLA_F_NESTED | IPSET_ATTR_IP;
|
||||||
|
add_attr(nlh,
|
||||||
|
(af == AF_INET ? IPSET_ATTR_IPADDR_IPV4 : IPSET_ATTR_IPADDR_IPV6) | NLA_F_NET_BYTEORDER,
|
||||||
|
addrsz, &ipaddr->addr);
|
||||||
|
nested[1]->nla_len = (void *)buffer + NL_ALIGN(nlh->nlmsg_len) - (void *)nested[1];
|
||||||
|
nested[0]->nla_len = (void *)buffer + NL_ALIGN(nlh->nlmsg_len) - (void *)nested[0];
|
||||||
|
|
||||||
|
while ((rc = sendto(ipset_sock, buffer, nlh->nlmsg_len, 0,
|
||||||
|
(struct sockaddr *)&snl, sizeof(snl))) == -1 && retry_send());
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int old_add_to_ipset(const char *setname, const struct all_addr *ipaddr, int remove)
|
||||||
|
{
|
||||||
|
socklen_t size;
|
||||||
|
struct ip_set_req_adt_get {
|
||||||
|
unsigned op;
|
||||||
|
unsigned version;
|
||||||
|
union {
|
||||||
|
char name[IPSET_MAXNAMELEN];
|
||||||
|
uint16_t index;
|
||||||
|
} set;
|
||||||
|
char typename[IPSET_MAXNAMELEN];
|
||||||
|
} req_adt_get;
|
||||||
|
struct ip_set_req_adt {
|
||||||
|
unsigned op;
|
||||||
|
uint16_t index;
|
||||||
|
uint32_t ip;
|
||||||
|
} req_adt;
|
||||||
|
|
||||||
|
if (strlen(setname) >= sizeof(req_adt_get.set.name))
|
||||||
|
{
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
req_adt_get.op = 0x10;
|
||||||
|
req_adt_get.version = 3;
|
||||||
|
strcpy(req_adt_get.set.name, setname);
|
||||||
|
size = sizeof(req_adt_get);
|
||||||
|
if (getsockopt(ipset_sock, SOL_IP, 83, &req_adt_get, &size) < 0)
|
||||||
|
return -1;
|
||||||
|
req_adt.op = remove ? 0x102 : 0x101;
|
||||||
|
req_adt.index = req_adt_get.set.index;
|
||||||
|
req_adt.ip = ntohl(ipaddr->addr.addr4.s_addr);
|
||||||
|
if (setsockopt(ipset_sock, SOL_IP, 83, &req_adt, sizeof(req_adt)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int add_to_ipset(const char *setname, const struct all_addr *ipaddr, int flags, int remove)
|
||||||
|
{
|
||||||
|
int af = AF_INET;
|
||||||
|
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
if (flags & F_IPV6)
|
||||||
|
{
|
||||||
|
af = AF_INET6;
|
||||||
|
/* old method only supports IPv4 */
|
||||||
|
if (old_kernel)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return old_kernel ? old_add_to_ipset(setname, ipaddr, remove) : new_add_to_ipset(setname, ipaddr, af, remove);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
+26
-15
@@ -555,8 +555,7 @@ struct dhcp_lease *lease_find_by_addr(struct in_addr addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
/* addr or clid may be NULL for "don't care, both NULL resets "USED" flags both
|
/* find address for {CLID, IAID, address} */
|
||||||
set activates USED check */
|
|
||||||
struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len,
|
struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len,
|
||||||
int lease_type, int iaid, struct in6_addr *addr)
|
int lease_type, int iaid, struct in6_addr *addr)
|
||||||
{
|
{
|
||||||
@@ -567,40 +566,52 @@ struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len,
|
|||||||
if (!(lease->flags & lease_type) || lease->hwaddr_type != iaid)
|
if (!(lease->flags & lease_type) || lease->hwaddr_type != iaid)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (clid && addr && (lease->flags & LEASE_USED))
|
if (memcmp(lease->hwaddr, addr, IN6ADDRSZ) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (addr && memcmp(lease->hwaddr, addr, IN6ADDRSZ) != 0)
|
if ((clid_len != lease->clid_len ||
|
||||||
continue;
|
|
||||||
|
|
||||||
if (clid &&
|
|
||||||
(clid_len != lease->clid_len ||
|
|
||||||
memcmp(clid, lease->clid, clid_len) != 0))
|
memcmp(clid, lease->clid, clid_len) != 0))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
lease->flags |= LEASE_USED;
|
|
||||||
return lease;
|
return lease;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lease6_filter(int lease_type, int iaid, struct dhcp_context *context)
|
/* reset "USED flags */
|
||||||
|
void lease6_reset(void)
|
||||||
{
|
{
|
||||||
struct dhcp_lease *lease;
|
struct dhcp_lease *lease;
|
||||||
|
|
||||||
for (lease = leases; lease; lease = lease->next)
|
for (lease = leases; lease; lease = lease->next)
|
||||||
|
lease->flags &= ~LEASE_USED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enumerate all leases belonging to {CLID, IAID} */
|
||||||
|
struct dhcp_lease *lease6_find_by_client(struct dhcp_lease *first, int lease_type, unsigned char *clid, int clid_len, int iaid)
|
||||||
|
{
|
||||||
|
struct dhcp_lease *lease;
|
||||||
|
|
||||||
|
if (!first)
|
||||||
|
first = leases;
|
||||||
|
|
||||||
|
for (lease = first; lease; lease = lease->next)
|
||||||
{
|
{
|
||||||
/* reset "USED flag */
|
if (lease->flags & LEASE_USED)
|
||||||
lease->flags &= ~LEASE_USED;
|
continue;
|
||||||
|
|
||||||
if (!(lease->flags & lease_type) || lease->hwaddr_type != iaid)
|
if (!(lease->flags & lease_type) || lease->hwaddr_type != iaid)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* leases on the wrong interface get filtered out here */
|
if ((clid_len != lease->clid_len ||
|
||||||
if (!is_addr_in_context6(context, (struct in6_addr *)&lease->hwaddr))
|
memcmp(clid, lease->clid, clid_len) != 0))
|
||||||
lease->flags |= LEASE_USED;
|
continue;
|
||||||
|
|
||||||
|
return lease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dhcp_lease *lease6_find_by_addr(struct in6_addr *net, int prefix, u64 addr)
|
struct dhcp_lease *lease6_find_by_addr(struct in6_addr *net, int prefix, u64 addr)
|
||||||
|
|||||||
+3
-3
@@ -123,7 +123,7 @@ int iface_check(int family, struct all_addr *addr, char *name, int *auth)
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
for (tmp = daemon->if_names; tmp; tmp = tmp->next)
|
for (tmp = daemon->if_names; tmp; tmp = tmp->next)
|
||||||
if (tmp->name && (strcmp(tmp->name, name) == 0))
|
if (tmp->name && wildcard_match(tmp->name, name))
|
||||||
ret = tmp->used = 1;
|
ret = tmp->used = 1;
|
||||||
|
|
||||||
if (addr)
|
if (addr)
|
||||||
@@ -143,7 +143,7 @@ int iface_check(int family, struct all_addr *addr, char *name, int *auth)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (tmp = daemon->if_except; tmp; tmp = tmp->next)
|
for (tmp = daemon->if_except; tmp; tmp = tmp->next)
|
||||||
if (tmp->name && (strcmp(tmp->name, name) == 0))
|
if (tmp->name && wildcard_match(tmp->name, name))
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
|
|
||||||
@@ -291,7 +291,7 @@ static int iface_allowed(struct irec **irecp, int if_index,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||||
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
|
if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
|
||||||
{
|
{
|
||||||
tftp_ok = 0;
|
tftp_ok = 0;
|
||||||
dhcp_ok = 0;
|
dhcp_ok = 0;
|
||||||
|
|||||||
+102
-5
@@ -127,6 +127,10 @@ struct myoption {
|
|||||||
#define LOPT_AUTHSOA 316
|
#define LOPT_AUTHSOA 316
|
||||||
#define LOPT_AUTHSFS 317
|
#define LOPT_AUTHSFS 317
|
||||||
#define LOPT_AUTHPEER 318
|
#define LOPT_AUTHPEER 318
|
||||||
|
#define LOPT_IPSET 319
|
||||||
|
#ifdef OPTION6_PREFIX_CLASS
|
||||||
|
#define LOPT_PREF_CLSS 320
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_GETOPT_LONG
|
#ifdef HAVE_GETOPT_LONG
|
||||||
static const struct option opts[] =
|
static const struct option opts[] =
|
||||||
@@ -259,6 +263,10 @@ static const struct myoption opts[] =
|
|||||||
{ "auth-soa", 1, 0, LOPT_AUTHSOA },
|
{ "auth-soa", 1, 0, LOPT_AUTHSOA },
|
||||||
{ "auth-sec-servers", 1, 0, LOPT_AUTHSFS },
|
{ "auth-sec-servers", 1, 0, LOPT_AUTHSFS },
|
||||||
{ "auth-peer", 1, 0, LOPT_AUTHPEER },
|
{ "auth-peer", 1, 0, LOPT_AUTHPEER },
|
||||||
|
{ "ipset", 1, 0, LOPT_IPSET },
|
||||||
|
#ifdef OPTION6_PREFIX_CLASS
|
||||||
|
{ "dhcp-prefix-class", 1, 0, LOPT_PREF_CLSS },
|
||||||
|
#endif
|
||||||
{ NULL, 0, 0, 0 }
|
{ NULL, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -397,6 +405,10 @@ static struct {
|
|||||||
{ LOPT_AUTHSOA, ARG_ONE, "<serial>[,...]", gettext_noop("Set authoritive zone information"), NULL },
|
{ LOPT_AUTHSOA, ARG_ONE, "<serial>[,...]", gettext_noop("Set authoritive zone information"), NULL },
|
||||||
{ LOPT_AUTHSFS, ARG_DUP, "<NS>[,<NS>...]", gettext_noop("Secondary authoritative nameservers for forward domains"), NULL },
|
{ LOPT_AUTHSFS, ARG_DUP, "<NS>[,<NS>...]", gettext_noop("Secondary authoritative nameservers for forward domains"), NULL },
|
||||||
{ LOPT_AUTHPEER, ARG_DUP, "<ipaddr>[,<ipaddr>...]", gettext_noop("Peers which are allowed to do zone transfer"), NULL },
|
{ LOPT_AUTHPEER, ARG_DUP, "<ipaddr>[,<ipaddr>...]", gettext_noop("Peers which are allowed to do zone transfer"), NULL },
|
||||||
|
{ LOPT_IPSET, ARG_DUP, "/<domain>/<ipset>[,<ipset>...]", gettext_noop("Specify ipsets to which matching domains should be added"), NULL },
|
||||||
|
#ifdef OPTION6_PREFIX_CLASS
|
||||||
|
{ LOPT_PREF_CLSS, ARG_DUP, "set:tag,<class>", gettext_noop("Specify DHCPv6 prefix class"), NULL },
|
||||||
|
#endif
|
||||||
{ 0, 0, NULL, NULL, NULL }
|
{ 0, 0, NULL, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -765,6 +777,8 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
|
|||||||
new->opt = lookup_dhcp_opt(AF_INET, arg+7);
|
new->opt = lookup_dhcp_opt(AF_INET, arg+7);
|
||||||
opt_len = lookup_dhcp_len(AF_INET, new->opt);
|
opt_len = lookup_dhcp_len(AF_INET, new->opt);
|
||||||
/* option:<optname> must follow tag and vendor string. */
|
/* option:<optname> must follow tag and vendor string. */
|
||||||
|
if ((opt_len & OT_INTERNAL) && flags != DHOPT_MATCH)
|
||||||
|
new->opt = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
@@ -783,6 +797,8 @@ static int parse_dhcp_opt(char *errstr, char *arg, int flags)
|
|||||||
{
|
{
|
||||||
new->opt = lookup_dhcp_opt(AF_INET6, arg+8);
|
new->opt = lookup_dhcp_opt(AF_INET6, arg+8);
|
||||||
opt_len = lookup_dhcp_len(AF_INET6, new->opt);
|
opt_len = lookup_dhcp_len(AF_INET6, new->opt);
|
||||||
|
if ((opt_len & OT_INTERNAL) && flags != DHOPT_MATCH)
|
||||||
|
new->opt = 0;
|
||||||
}
|
}
|
||||||
/* option6:<opt>|<optname> must follow tag and vendor string. */
|
/* option6:<opt>|<optname> must follow tag and vendor string. */
|
||||||
is6 = 1;
|
is6 = 1;
|
||||||
@@ -2022,6 +2038,74 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case LOPT_IPSET: /* --ipset */
|
||||||
|
#ifndef HAVE_IPSET
|
||||||
|
ret_err(_("recompile with HAVE_IPSET defined to enable ipset directives"));
|
||||||
|
break;
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
struct ipsets ipsets_head;
|
||||||
|
struct ipsets *ipsets = &ipsets_head;
|
||||||
|
int size;
|
||||||
|
char *end;
|
||||||
|
char **sets, **sets_pos;
|
||||||
|
memset(ipsets, 0, sizeof(struct ipsets));
|
||||||
|
unhide_metas(arg);
|
||||||
|
if (arg && *arg == '/')
|
||||||
|
{
|
||||||
|
arg++;
|
||||||
|
while ((end = split_chr(arg, '/')))
|
||||||
|
{
|
||||||
|
char *domain = NULL;
|
||||||
|
/* elide leading dots - they are implied in the search algorithm */
|
||||||
|
while (*arg == '.')
|
||||||
|
arg++;
|
||||||
|
/* # matches everything and becomes a zero length domain string */
|
||||||
|
if (strcmp(arg, "#") == 0 || !*arg)
|
||||||
|
domain = "";
|
||||||
|
else if (strlen(arg) != 0 && !(domain = canonicalise_opt(arg)))
|
||||||
|
option = '?';
|
||||||
|
ipsets->next = opt_malloc(sizeof(struct ipsets));
|
||||||
|
ipsets = ipsets->next;
|
||||||
|
memset(ipsets, 0, sizeof(struct ipsets));
|
||||||
|
ipsets->domain = domain;
|
||||||
|
arg = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ipsets->next = opt_malloc(sizeof(struct ipsets));
|
||||||
|
ipsets = ipsets->next;
|
||||||
|
memset(ipsets, 0, sizeof(struct ipsets));
|
||||||
|
ipsets->domain = "";
|
||||||
|
}
|
||||||
|
if (!arg || !*arg)
|
||||||
|
{
|
||||||
|
option = '?';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
size = 2;
|
||||||
|
for (end = arg; *end; ++end)
|
||||||
|
if (*end == ',')
|
||||||
|
++size;
|
||||||
|
|
||||||
|
sets = sets_pos = opt_malloc(sizeof(char *) * size);
|
||||||
|
|
||||||
|
do {
|
||||||
|
end = split(arg);
|
||||||
|
*sets_pos++ = opt_string_alloc(arg);
|
||||||
|
arg = end;
|
||||||
|
} while (end);
|
||||||
|
*sets_pos = 0;
|
||||||
|
for (ipsets = &ipsets_head; ipsets->next; ipsets = ipsets->next)
|
||||||
|
ipsets->next->sets = sets;
|
||||||
|
ipsets->next = daemon->ipsets;
|
||||||
|
daemon->ipsets = ipsets_head.next;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
case 'c': /* --cache-size */
|
case 'c': /* --cache-size */
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
@@ -2291,11 +2375,6 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
new->flags |= CONTEXT_DHCP;
|
new->flags |= CONTEXT_DHCP;
|
||||||
else if (strstr(a[leasepos], "constructor:") == a[leasepos])
|
else if (strstr(a[leasepos], "constructor:") == a[leasepos])
|
||||||
{
|
{
|
||||||
if (a[leasepos][strlen(a[leasepos])-1] == '*')
|
|
||||||
{
|
|
||||||
a[leasepos][strlen(a[leasepos])-1] = 0;
|
|
||||||
new->flags |= CONTEXT_WILDCARD;
|
|
||||||
}
|
|
||||||
new->template_interface = opt_string_alloc(a[leasepos] + 12);
|
new->template_interface = opt_string_alloc(a[leasepos] + 12);
|
||||||
new->flags |= CONTEXT_TEMPLATE;
|
new->flags |= CONTEXT_TEMPLATE;
|
||||||
}
|
}
|
||||||
@@ -2869,6 +2948,24 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifdef OPTION6_PREFIX_CLASS
|
||||||
|
case LOPT_PREF_CLSS: /* --dhcp-prefix-class */
|
||||||
|
{
|
||||||
|
struct prefix_class *new = opt_malloc(sizeof(struct prefix_class));
|
||||||
|
|
||||||
|
if (!(comma = split(arg)) ||
|
||||||
|
!atoi_check16(comma, &new->class))
|
||||||
|
ret_err(gen_err);
|
||||||
|
|
||||||
|
new->tag.net = opt_string_alloc(set_prefix(arg));
|
||||||
|
new->next = daemon->prefix_classes;
|
||||||
|
daemon->prefix_classes = new;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
case 'U': /* --dhcp-vendorclass */
|
case 'U': /* --dhcp-vendorclass */
|
||||||
case 'j': /* --dhcp-userclass */
|
case 'j': /* --dhcp-userclass */
|
||||||
case LOPT_CIRCUIT: /* --dhcp-circuitid */
|
case LOPT_CIRCUIT: /* --dhcp-circuitid */
|
||||||
|
|||||||
+2
-2
@@ -158,7 +158,7 @@ void icmp6_packet(time_t now)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||||
if (tmp->name && (strcmp(tmp->name, interface) == 0))
|
if (tmp->name && wildcard_match(tmp->name, interface))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (packet[1] != 0)
|
if (packet[1] != 0)
|
||||||
@@ -533,7 +533,7 @@ time_t periodic_ra(time_t now)
|
|||||||
{
|
{
|
||||||
struct iname *tmp;
|
struct iname *tmp;
|
||||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||||
if (tmp->name && (strcmp(tmp->name, interface) == 0))
|
if (tmp->name && wildcard_match(tmp->name, interface))
|
||||||
break;
|
break;
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
send_ra(now, param.iface, interface, NULL);
|
send_ra(now, param.iface, interface, NULL);
|
||||||
|
|||||||
+15
-1
@@ -777,12 +777,17 @@ static int find_soa(struct dns_header *header, size_t qlen, char *name)
|
|||||||
expired and cleaned out that way.
|
expired and cleaned out that way.
|
||||||
Return 1 if we reject an address because it look like part of dns-rebinding attack. */
|
Return 1 if we reject an address because it look like part of dns-rebinding attack. */
|
||||||
int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t now,
|
int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t now,
|
||||||
int is_sign, int check_rebind, int checking_disabled)
|
char **ipsets, int is_sign, int check_rebind, int checking_disabled)
|
||||||
{
|
{
|
||||||
unsigned char *p, *p1, *endrr, *namep;
|
unsigned char *p, *p1, *endrr, *namep;
|
||||||
int i, j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0;
|
int i, j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0;
|
||||||
unsigned long ttl = 0;
|
unsigned long ttl = 0;
|
||||||
struct all_addr addr;
|
struct all_addr addr;
|
||||||
|
#ifdef HAVE_IPSET
|
||||||
|
char **ipsets_cur;
|
||||||
|
#else
|
||||||
|
(void)ipsets; /* unused */
|
||||||
|
#endif
|
||||||
|
|
||||||
cache_start_insert();
|
cache_start_insert();
|
||||||
|
|
||||||
@@ -967,6 +972,15 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
|
|||||||
private_net(addr.addr.addr4, !option_bool(OPT_LOCAL_REBIND)))
|
private_net(addr.addr.addr4, !option_bool(OPT_LOCAL_REBIND)))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
#ifdef HAVE_IPSET
|
||||||
|
if (ipsets && (flags & (F_IPV4 | F_IPV6)))
|
||||||
|
{
|
||||||
|
ipsets_cur = ipsets;
|
||||||
|
while (*ipsets_cur)
|
||||||
|
add_to_ipset(*ipsets_cur++, &addr, flags, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD);
|
newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD);
|
||||||
if (newc && cpp)
|
if (newc && cpp)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1257,6 +1257,19 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
|
|||||||
add_extradata_opt(lease, serial);
|
add_extradata_opt(lease, serial);
|
||||||
add_extradata_opt(lease, class);
|
add_extradata_opt(lease, class);
|
||||||
|
|
||||||
|
if ((opt = option_find(mess, sz, OPTION_AGENT_ID, 1)))
|
||||||
|
{
|
||||||
|
add_extradata_opt(lease, option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)), SUBOPT_CIRCUIT_ID, 1));
|
||||||
|
add_extradata_opt(lease, option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)), SUBOPT_SUBSCR_ID, 1));
|
||||||
|
add_extradata_opt(lease, option_find1(option_ptr(opt, 0), option_ptr(opt, option_len(opt)), SUBOPT_REMOTE_ID, 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
add_extradata_opt(lease, NULL);
|
||||||
|
add_extradata_opt(lease, NULL);
|
||||||
|
add_extradata_opt(lease, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* space-concat tag set */
|
/* space-concat tag set */
|
||||||
if (!tagif_netid)
|
if (!tagif_netid)
|
||||||
add_extradata_opt(lease, NULL);
|
add_extradata_opt(lease, NULL);
|
||||||
|
|||||||
+876
-578
File diff suppressed because it is too large.
Load diff
+1
-1
@@ -209,7 +209,7 @@ void tftp_request(struct listener *listen, time_t now)
|
|||||||
#ifdef HAVE_DHCP
|
#ifdef HAVE_DHCP
|
||||||
/* allowed interfaces are the same as for DHCP */
|
/* allowed interfaces are the same as for DHCP */
|
||||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||||
if (tmp->name && (strcmp(tmp->name, name) == 0))
|
if (tmp->name && wildcard_match(tmp->name, name))
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+17
@@ -581,3 +581,20 @@ int read_write(int fd, unsigned char *packet, int size, int rw)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Basically match a string value against a wildcard pattern. */
|
||||||
|
int wildcard_match(const char* wildcard, const char* match)
|
||||||
|
{
|
||||||
|
while (*wildcard && *match)
|
||||||
|
{
|
||||||
|
if (*wildcard == '*')
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (*wildcard != *match)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
++wildcard;
|
||||||
|
++match;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *wildcard == *match;
|
||||||
|
}
|
||||||
Reference in new issue
Block a user