Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
D
Dnsmasq
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nanahira
Dnsmasq
Commits
13d86c73
Commit
13d86c73
authored
Feb 22, 2013
by
Jason A. Donenfeld
Committed by
Simon Kelley
Feb 22, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add --ipset option.
parent
208fb610
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
359 additions
and
6 deletions
+359
-6
CHANGELOG
CHANGELOG
+3
-0
Makefile
Makefile
+1
-1
dnsmasq.conf.example
dnsmasq.conf.example
+4
-0
man/dnsmasq.8
man/dnsmasq.8
+6
-0
src/config.h
src/config.h
+13
-1
src/dnsmasq.c
src/dnsmasq.c
+5
-0
src/dnsmasq.h
src/dnsmasq.h
+15
-1
src/forward.c
src/forward.c
+20
-1
src/ipset.c
src/ipset.c
+205
-0
src/option.c
src/option.c
+71
-0
src/rfc1035.c
src/rfc1035.c
+16
-2
No files found.
CHANGELOG
View file @
13d86c73
...
@@ -43,6 +43,9 @@ version 2.66
...
@@ -43,6 +43,9 @@ version 2.66
Thanks to Robert M. Albrecht for the bug report and
Thanks to Robert M. Albrecht for the bug report and
chasing the problem.
chasing the problem.
Add --ipset option. Thanks to Jason A. Donenfeld 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
...
...
Makefile
View file @
13d86c73
...
@@ -65,7 +65,7 @@ version = -DVERSION='\"`$(top)/bld/get-version $(top)`\"'
...
@@ -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
...
...
dnsmasq.conf.example
View file @
13d86c73
...
@@ -69,6 +69,10 @@
...
@@ -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
...
...
man/dnsmasq.8
View file @
13d86c73
...
@@ -412,6 +412,12 @@ additional facility that /#/ matches any domain. Thus
...
@@ -412,6 +412,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
...
...
src/config.h
View file @
13d86c73
...
@@ -97,6 +97,10 @@ HAVE_CONNTRACK
...
@@ -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.
...
@@ -136,7 +140,7 @@ RESOLVFILE
...
@@ -136,7 +140,7 @@ RESOLVFILE
/* #define HAVE_DBUS */
/* #define HAVE_DBUS */
/* #define HAVE_IDN */
/* #define HAVE_IDN */
/* #define HAVE_CONNTRACK */
/* #define HAVE_CONNTRACK */
/* #define HAVE_IPSET */
/* Default locations for important system files. */
/* Default locations for important system files. */
...
@@ -323,6 +327,10 @@ HAVE_SOCKADDR_SA_LEN
...
@@ -323,6 +327,10 @@ HAVE_SOCKADDR_SA_LEN
#undef HAVE_AUTH
#undef HAVE_AUTH
#endif
#endif
#ifndef 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 =
...
@@ -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
...
...
src/dnsmasq.c
View file @
13d86c73
...
@@ -213,6 +213,11 @@ int main (int argc, char **argv)
...
@@ -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
();
...
...
src/dnsmasq.h
View file @
13d86c73
...
@@ -430,6 +430,12 @@ struct server {
...
@@ -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 */
...
@@ -779,6 +785,7 @@ extern struct daemon {
...
@@ -779,6 +785,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 */
...
@@ -903,7 +910,8 @@ size_t setup_reply(struct dns_header *header, size_t qlen,
...
@@ -903,7 +910,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
,
...
@@ -1117,6 +1125,12 @@ void emit_dbus_signal(int action, struct dhcp_lease *lease, char *hostname);
...
@@ -1117,6 +1125,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
);
...
...
src/forward.c
View file @
13d86c73
...
@@ -439,9 +439,28 @@ static size_t process_reply(struct dns_header *header, time_t now,
...
@@ -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,
...
@@ -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
;
...
...
src/ipset.c
0 → 100644
View file @
13d86c73
/* 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
;
#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
];
if
(
sendto
(
ipset_sock
,
buffer
,
nlh
->
nlmsg_len
,
0
,
(
struct
sockaddr
*
)
&
snl
,
sizeof
(
snl
))
<
0
)
return
-
1
;
return
0
;
}
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
src/option.c
View file @
13d86c73
...
@@ -127,6 +127,7 @@ struct myoption {
...
@@ -127,6 +127,7 @@ 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 HAVE_GETOPT_LONG
#ifdef HAVE_GETOPT_LONG
static
const
struct
option
opts
[]
=
static
const
struct
option
opts
[]
=
...
@@ -259,6 +260,7 @@ static const struct myoption opts[] =
...
@@ -259,6 +260,7 @@ 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
},
{
NULL
,
0
,
0
,
0
}
{
NULL
,
0
,
0
,
0
}
};
};
...
@@ -397,6 +399,7 @@ static struct {
...
@@ -397,6 +399,7 @@ 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
},
{
0
,
0
,
NULL
,
NULL
,
NULL
}
{
0
,
0
,
NULL
,
NULL
,
NULL
}
};
};
...
@@ -2021,6 +2024,74 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
...
@@ -2021,6 +2024,74 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
daemon
->
servers
=
newlist
;
daemon
->
servers
=
newlist
;
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 */
{
{
...
...
src/rfc1035.c
View file @
13d86c73
...
@@ -777,13 +777,18 @@ static int find_soa(struct dns_header *header, size_t qlen, char *name)
...
@@ -777,13 +777,18 @@ 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
();
/* find_soa is needed for dns_doctor and logging side-effects, so don't call it lazily if there are any. */
/* find_soa is needed for dns_doctor and logging side-effects, so don't call it lazily if there are any. */
...
@@ -966,6 +971,15 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
...
@@ -966,6 +971,15 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
(
flags
&
F_IPV4
)
&&
(
flags
&
F_IPV4
)
&&
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
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment