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
4f7b304f
Commit
4f7b304f
authored
Nov 28, 2012
by
Simon Kelley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Initial code to do authoritative DNS.
parent
8e4b8791
Changes
15
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
704 additions
and
190 deletions
+704
-190
Makefile
Makefile
+1
-1
bld/Android.mk
bld/Android.mk
+1
-1
src/auth.c
src/auth.c
+307
-0
src/cache.c
src/cache.c
+5
-3
src/config.h
src/config.h
+5
-1
src/dhcp-common.c
src/dhcp-common.c
+1
-1
src/dhcp.c
src/dhcp.c
+1
-1
src/dnsmasq.c
src/dnsmasq.c
+19
-3
src/dnsmasq.h
src/dnsmasq.h
+34
-5
src/forward.c
src/forward.c
+157
-137
src/network.c
src/network.c
+34
-15
src/option.c
src/option.c
+118
-2
src/radv.c
src/radv.c
+1
-1
src/rfc1035.c
src/rfc1035.c
+18
-17
src/tftp.c
src/tftp.c
+2
-2
No files found.
Makefile
View file @
4f7b304f
...
...
@@ -65,7 +65,7 @@ version = -DVERSION='\"`$(top)/bld/get-version $(top)`\"'
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
\
helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o
\
dhcp-common.o outpacket.o radv.o slaac.o
dhcp-common.o outpacket.o radv.o slaac.o
auth.o
hdrs
=
dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h
\
dns-protocol.h radv-protocol.h
...
...
bld/Android.mk
View file @
4f7b304f
...
...
@@ -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
\
rfc2131.c tftp.c util.c conntrack.c
\
dhcp6.c rfc3315.c dhcp-common.c outpacket.c
\
radv.c slaac.c
radv.c slaac.c
auth.c
LOCAL_MODULE
:=
dnsmasq
...
...
src/auth.c
0 → 100644
View file @
4f7b304f
/* dnsmasq is Copyright (c) 2000-2012 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
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"
static
int
filter_zone
(
struct
auth_zone
*
zone
,
int
flag
,
struct
all_addr
*
addr_u
)
{
struct
subnet
*
subnet
;
for
(
subnet
=
zone
->
subnet
;
subnet
;
subnet
=
subnet
->
next
)
{
if
(
subnet
->
is6
&&
(
flag
&
F_IPV4
))
continue
;
if
(
!
subnet
->
is6
)
{
struct
in_addr
addr
=
addr_u
->
addr
.
addr4
;
struct
in_addr
mask
;
mask
.
s_addr
=
(
1
<<
(
32
-
subnet
->
prefixlen
))
-
1
;
if
(
is_same_net
(
addr
,
subnet
->
addr4
,
mask
))
return
1
;
}
#ifdef HAVE_IPV6
else
if
(
is_same_net6
(
&
(
addr_u
->
addr
.
addr6
),
&
subnet
->
addr6
,
subnet
->
prefixlen
))
return
1
;
#endif
}
return
0
;
}
size_t
answer_auth
(
struct
dns_header
*
header
,
char
*
limit
,
size_t
qlen
,
time_t
now
)
{
char
*
name
=
daemon
->
namebuff
;
unsigned
char
*
p
,
*
ansp
;
int
qtype
,
qclass
;
unsigned
int
nameoffset
;
int
q
,
anscount
=
0
,
authcount
=
0
;
struct
crec
*
crecp
;
int
auth
=
1
,
trunc
=
0
,
nxdomain
=
1
,
soa
=
0
;
struct
auth_zone
*
zone
=
NULL
;
if
(
ntohs
(
header
->
qdcount
)
==
0
||
OPCODE
(
header
)
!=
QUERY
)
return
0
;
/* determine end of question section (we put answers there) */
if
(
!
(
ansp
=
skip_questions
(
header
,
qlen
)))
return
0
;
/* bad packet */
/* now process each question, answers go in RRs after the question */
p
=
(
unsigned
char
*
)(
header
+
1
);
for
(
q
=
ntohs
(
header
->
qdcount
);
q
!=
0
;
q
--
)
{
size_t
domainlen
,
namelen
;
unsigned
short
flag
;
int
found
=
0
;
/* save pointer to name for copying into answers */
nameoffset
=
p
-
(
unsigned
char
*
)
header
;
/* now extract name as .-concatenated string into name */
if
(
!
extract_name
(
header
,
qlen
,
&
p
,
name
,
1
,
4
))
return
0
;
/* bad packet */
GETSHORT
(
qtype
,
p
);
GETSHORT
(
qclass
,
p
);
if
(
qclass
!=
C_IN
)
continue
;
if
(
qtype
==
T_PTR
)
{
struct
all_addr
addr
;
if
(
!
(
flag
=
in_arpa_name_2_addr
(
name
,
&
addr
)))
continue
;
for
(
zone
=
daemon
->
auth_zones
;
zone
;
zone
=
zone
->
next
)
if
(
filter_zone
(
zone
,
flag
,
&
addr
))
break
;
if
(
!
zone
)
{
auth
=
0
;
continue
;
}
if
((
crecp
=
cache_find_by_addr
(
NULL
,
&
addr
,
now
,
flag
)))
do
{
strcpy
(
name
,
cache_get_name
(
crecp
));
if
(
crecp
->
flags
&
F_DHCP
&&
!
option_bool
(
OPT_DHCP_FQDN
))
{
char
*
p
=
strchr
(
name
,
'.'
);
if
(
p
)
*
p
=
0
;
/* must be bare name */
/* add external domain */
strcat
(
name
,
"."
);
strcat
(
name
,
zone
->
domain
);
log_query
(
flag
|
F_DHCP
|
F_REVERSE
,
name
,
&
addr
,
record_source
(
crecp
->
uid
));
if
(
add_resource_record
(
header
,
limit
,
&
trunc
,
nameoffset
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
T_PTR
,
C_IN
,
"d"
,
name
))
{
anscount
++
;
found
=
1
;
}
}
else
if
(
crecp
->
flags
&
(
F_DHCP
|
F_HOSTS
))
{
domainlen
=
strlen
(
zone
->
domain
);
namelen
=
strlen
(
name
);
if
(
namelen
<=
domainlen
+
1
||
name
[
namelen
-
domainlen
-
1
]
!=
'.'
||
!
hostname_isequal
(
zone
->
domain
,
&
name
[
namelen
-
domainlen
]))
continue
;
/* wrong domain */
log_query
(
crecp
->
flags
&
~
F_FORWARD
,
name
,
&
addr
,
record_source
(
crecp
->
uid
));
if
(
add_resource_record
(
header
,
limit
,
&
trunc
,
nameoffset
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
T_PTR
,
C_IN
,
"d"
,
name
))
{
anscount
++
;
found
=
1
;
}
}
else
continue
;
}
while
((
crecp
=
cache_find_by_addr
(
crecp
,
&
addr
,
now
,
flag
)));
if
(
!
found
)
log_query
(
flag
|
F_NEG
|
F_NXDOMAIN
|
F_REVERSE
|
F_AUTH
,
NULL
,
&
addr
,
NULL
);
continue
;
}
namelen
=
strlen
(
name
);
for
(
zone
=
daemon
->
auth_zones
;
zone
;
zone
=
zone
->
next
)
{
domainlen
=
strlen
(
zone
->
domain
);
if
(
namelen
>=
domainlen
&&
hostname_isequal
(
zone
->
domain
,
&
name
[
namelen
-
domainlen
]))
break
;
}
if
(
!
zone
)
{
auth
=
0
;
continue
;
}
if
(
namelen
>
domainlen
&&
name
[
namelen
-
domainlen
-
1
]
!=
'.'
)
continue
;
if
(
qtype
==
T_A
)
flag
=
F_IPV4
;
#ifdef HAVE_IPV6
else
if
(
qtype
==
T_AAAA
)
flag
=
F_IPV6
;
#endif
else
{
if
(
qtype
==
T_SOA
)
{
soa
=
1
;
/* inhibits auth section */
found
=
1
;
log_query
(
F_RRNAME
|
F_AUTH
,
zone
->
domain
,
NULL
,
"<SOA>"
);
if
(
add_resource_record
(
header
,
limit
,
&
trunc
,
0
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
T_SOA
,
C_IN
,
"ddlllll"
,
zone
->
domain
,
daemon
->
authserver
,
daemon
->
hostmaster
,
daemon
->
soa_sn
,
daemon
->
soa_refresh
,
daemon
->
soa_retry
,
daemon
->
soa_expiry
,
daemon
->
auth_ttl
))
anscount
++
;
}
else
if
(
qtype
==
T_NS
)
{
soa
=
1
;
/* inhibits auth section */
found
=
1
;
log_query
(
F_RRNAME
|
F_AUTH
,
zone
->
domain
,
NULL
,
"<NS>"
);
if
(
add_resource_record
(
header
,
limit
,
&
trunc
,
0
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
T_NS
,
C_IN
,
"d"
,
zone
->
domain
,
daemon
->
authserver
))
anscount
++
;
}
continue
;
}
if
(
!
option_bool
(
OPT_DHCP_FQDN
)
&&
namelen
>
domainlen
+
1
)
{
name
[
namelen
-
domainlen
-
1
]
=
0
;
/* remove domain part */
if
((
crecp
=
cache_find_by_name
(
NULL
,
name
,
now
,
F_IPV4
|
F_IPV6
)))
{
if
(
crecp
->
flags
&
F_DHCP
)
do
{
nxdomain
=
0
;
if
((
crecp
->
flags
&
flag
)
&&
filter_zone
(
zone
,
flag
,
&
(
crecp
->
addr
.
addr
)))
{
name
[
namelen
-
domainlen
-
1
]
=
'.'
;
/* restore domain part */
log_query
(
crecp
->
flags
,
name
,
&
crecp
->
addr
.
addr
,
record_source
(
crecp
->
uid
));
name
[
namelen
-
domainlen
-
1
]
=
0
;
/* remove domain part */
if
(
add_resource_record
(
header
,
limit
,
&
trunc
,
nameoffset
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
qtype
,
C_IN
,
qtype
==
T_A
?
"4"
:
"6"
,
&
crecp
->
addr
))
{
anscount
++
;
found
=
1
;
}
}
}
while
((
crecp
=
cache_find_by_name
(
crecp
,
name
,
now
,
F_IPV4
|
F_IPV6
)));
}
name
[
namelen
-
domainlen
-
1
]
=
'.'
;
/* restore domain part */
}
if
(
!
found
&&
(
crecp
=
cache_find_by_name
(
NULL
,
name
,
now
,
F_IPV4
|
F_IPV6
)))
{
if
((
crecp
->
flags
&
F_HOSTS
)
||
(((
crecp
->
flags
&
F_DHCP
)
&&
option_bool
(
OPT_DHCP_FQDN
))))
do
{
nxdomain
=
0
;
if
((
crecp
->
flags
&
flag
)
&&
filter_zone
(
zone
,
flag
,
&
(
crecp
->
addr
.
addr
)))
{
log_query
(
crecp
->
flags
,
name
,
&
crecp
->
addr
.
addr
,
record_source
(
crecp
->
uid
));
if
(
add_resource_record
(
header
,
limit
,
&
trunc
,
nameoffset
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
qtype
,
C_IN
,
qtype
==
T_A
?
"4"
:
"6"
,
&
crecp
->
addr
))
{
anscount
++
;
found
=
1
;
}
}
}
while
((
crecp
=
cache_find_by_name
(
crecp
,
name
,
now
,
F_IPV4
|
F_IPV6
)));
}
if
(
!
found
)
log_query
(
flag
|
F_NEG
|
(
nxdomain
?
F_NXDOMAIN
:
0
)
|
F_FORWARD
|
F_AUTH
,
name
,
NULL
,
NULL
);
}
/* Add auth section */
if
(
auth
&&
!
soa
)
{
if
(
anscount
!=
0
&&
add_resource_record
(
header
,
limit
,
&
trunc
,
0
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
T_NS
,
C_IN
,
"d"
,
zone
->
domain
,
daemon
->
authserver
))
authcount
++
;
if
(
anscount
==
0
&&
add_resource_record
(
header
,
limit
,
&
trunc
,
0
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
T_SOA
,
C_IN
,
"ddlllll"
,
zone
->
domain
,
daemon
->
authserver
,
daemon
->
hostmaster
,
daemon
->
soa_sn
,
daemon
->
soa_refresh
,
daemon
->
soa_retry
,
daemon
->
soa_expiry
,
daemon
->
auth_ttl
))
authcount
++
;
}
/* done all questions, set up header and return length of result */
/* clear authoritative and truncated flags, set QR flag */
header
->
hb3
=
(
header
->
hb3
&
~
(
HB3_AA
|
HB3_TC
))
|
HB3_QR
;
/* clear RA flag */
header
->
hb4
&=
~
HB4_RA
;
/* authoritive */
if
(
auth
)
header
->
hb3
|=
HB3_AA
;
/* truncation */
if
(
trunc
)
header
->
hb3
|=
HB3_TC
;
if
(
anscount
==
0
&&
auth
&&
nxdomain
)
SET_RCODE
(
header
,
NXDOMAIN
);
else
SET_RCODE
(
header
,
NOERROR
);
/* no error */
header
->
ancount
=
htons
(
anscount
);
header
->
nscount
=
htons
(
authcount
);
return
ansp
-
(
unsigned
char
*
)
header
;
}
src/cache.c
View file @
4f7b304f
...
...
@@ -1248,14 +1248,14 @@ char *record_source(int index)
return
"<unknown>"
;
}
void
querystr
(
char
*
str
,
unsigned
short
type
)
void
querystr
(
char
*
desc
,
char
*
str
,
unsigned
short
type
)
{
unsigned
int
i
;
sprintf
(
str
,
"
query[type=%d]"
,
type
);
sprintf
(
str
,
"
%s[type=%d]"
,
desc
,
type
);
for
(
i
=
0
;
i
<
(
sizeof
(
typestr
)
/
sizeof
(
typestr
[
0
]));
i
++
)
if
(
typestr
[
i
].
type
==
type
)
sprintf
(
str
,
"
query[%s]"
,
typestr
[
i
].
name
);
sprintf
(
str
,
"
%s[%s]"
,
desc
,
typestr
[
i
].
name
);
}
void
log_query
(
unsigned
int
flags
,
char
*
name
,
struct
all_addr
*
addr
,
char
*
arg
)
...
...
@@ -1316,6 +1316,8 @@ void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg)
source
=
arg
;
else
if
(
flags
&
F_UPSTREAM
)
source
=
"reply"
;
else
if
(
flags
&
F_AUTH
)
source
=
"auth"
;
else
if
(
flags
&
F_SERVER
)
{
source
=
"forwarded"
;
...
...
src/config.h
View file @
4f7b304f
...
...
@@ -42,7 +42,11 @@
#define EDNS0_OPTION_MAC 5
/* dyndns.org temporary assignment */
#define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq"
/* Default - may be overridden by config */
#define DNSMASQ_PATH "/uk/org/thekelleys/dnsmasq"
#define AUTH_TTL 600
/* default TTL for auth DNS */
#define SOA_REFRESH 1200
/* SOA refresh default */
#define SOA_RETRY 180
/* SOA retry default */
#define SOA_EXPIRY 1209600
/* SOA expiry default */
/* compile-time options: uncomment below to enable or do eg.
make COPTS=-DHAVE_BROKEN_RTC
...
...
src/dhcp-common.c
View file @
4f7b304f
...
...
@@ -366,7 +366,7 @@ static int join_multicast_worker(struct in6_addr *local, int prefix,
close
(
fd
);
/* Are we doing DHCP on this interface? */
if
(
!
iface_check
(
AF_INET6
,
(
struct
all_addr
*
)
local
,
ifrn_name
))
if
(
!
iface_check
(
AF_INET6
,
(
struct
all_addr
*
)
local
,
ifrn_name
,
NULL
))
return
1
;
for
(
tmp
=
daemon
->
dhcp_except
;
tmp
;
tmp
=
tmp
->
next
)
...
...
src/dhcp.c
View file @
4f7b304f
...
...
@@ -262,7 +262,7 @@ void dhcp_packet(time_t now, int pxe_fd)
parm
.
current
=
NULL
;
parm
.
ind
=
iface_index
;
if
(
!
iface_check
(
AF_INET
,
(
struct
all_addr
*
)
&
iface_addr
,
ifr
.
ifr_name
))
if
(
!
iface_check
(
AF_INET
,
(
struct
all_addr
*
)
&
iface_addr
,
ifr
.
ifr_name
,
NULL
))
{
/* If we failed to match the primary address of the interface, see if we've got a --listen-address
for a secondary */
...
...
src/dnsmasq.c
View file @
4f7b304f
...
...
@@ -84,6 +84,7 @@ int main (int argc, char **argv)
daemon
->
addrbuff
=
safe_malloc
(
ADDRSTRLEN
);
#ifdef HAVE_DHCP
if
(
!
daemon
->
lease_file
)
{
...
...
@@ -150,6 +151,14 @@ int main (int argc, char **argv)
rand_init
();
now
=
dnsmasq_time
();
/* Create a serial at startup is not configured. */
if
(
daemon
->
authinterface
&&
daemon
->
soa_sn
==
0
)
#ifdef HAVE_BROKEN_RTC
die
(
_
(
"zone serial must be configured in --auth-soa"
));
#else
daemon
->
soa_sn
=
now
;
#endif
#ifdef HAVE_DHCP
if
(
daemon
->
dhcp
||
daemon
->
dhcp6
)
...
...
@@ -1440,11 +1449,18 @@ static void check_dns_listeners(fd_set *set, time_t now)
struct
server
*
s
;
int
flags
;
struct
in_addr
netmask
;
int
auth_dns
;
if
(
iface
)
netmask
=
iface
->
netmask
;
{
netmask
=
iface
->
netmask
;
auth_dns
=
iface
->
dns_auth
;
}
else
netmask
.
s_addr
=
0
;
{
netmask
.
s_addr
=
0
;
auth_dns
=
0
;
}
#ifndef NO_FORK
/* Arrange for SIGALARM after CHILD_LIFETIME seconds to
...
...
@@ -1463,7 +1479,7 @@ static void check_dns_listeners(fd_set *set, time_t now)
if
((
flags
=
fcntl
(
confd
,
F_GETFL
,
0
))
!=
-
1
)
fcntl
(
confd
,
F_SETFL
,
flags
&
~
O_NONBLOCK
);
buff
=
tcp_request
(
confd
,
now
,
&
tcp_addr
,
netmask
);
buff
=
tcp_request
(
confd
,
now
,
&
tcp_addr
,
netmask
,
auth_dns
);
shutdown
(
confd
,
SHUT_RDWR
);
close
(
confd
);
...
...
src/dnsmasq.h
View file @
4f7b304f
...
...
@@ -278,6 +278,20 @@ struct cname {
struct
cname
*
next
;
};
struct
auth_zone
{
char
*
domain
;
struct
subnet
{
int
is6
,
prefixlen
;
struct
in_addr
addr4
;
#ifdef HAVE_IPV6
struct
in6_addr
addr6
;
#endif
struct
subnet
*
next
;
}
*
subnet
;
struct
auth_zone
*
next
;
};
struct
host_record
{
struct
name_list
{
char
*
name
;
...
...
@@ -357,6 +371,8 @@ struct crec {
#define F_SERVER (1u<<18)
#define F_QUERY (1u<<19)
#define F_NOERR (1u<<20)
#define F_AUTH (1u<<21)
/* composites */
#define F_TYPE (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS)
/* Only one may be set */
...
...
@@ -412,7 +428,7 @@ struct server {
struct
irec
{
union
mysockaddr
addr
;
struct
in_addr
netmask
;
/* only valid for IPv4 */
int
tftp_ok
,
dhcp_ok
,
mtu
,
done
,
dad
;
int
tftp_ok
,
dhcp_ok
,
mtu
,
done
,
dad
,
dns_auth
;
char
*
name
;
struct
irec
*
next
;
};
...
...
@@ -733,11 +749,13 @@ extern struct daemon {
struct
ptr_record
*
ptr
;
struct
host_record
*
host_records
,
*
host_records_tail
;
struct
cname
*
cnames
;
struct
auth_zone
*
auth_zones
;
struct
interface_name
*
int_names
;
char
*
mxtarget
;
char
*
lease_file
;
char
*
username
,
*
groupname
,
*
scriptuser
;
char
*
luascript
;
char
*
authserver
,
*
authinterface
,
*
hostmaster
;
int
group_set
,
osport
;
char
*
domain_suffix
;
struct
cond_domain
*
cond_domain
;
...
...
@@ -751,7 +769,7 @@ extern struct daemon {
int
max_logs
;
/* queue limit */
int
cachesize
,
ftabsize
;
int
port
,
query_port
,
min_port
;
unsigned
long
local_ttl
,
neg_ttl
,
max_ttl
,
max_cache_ttl
;
unsigned
long
local_ttl
,
neg_ttl
,
max_ttl
,
max_cache_ttl
,
auth_ttl
;
struct
hostsfile
*
addn_hosts
;
struct
dhcp_context
*
dhcp
,
*
dhcp6
,
*
ra_contexts
;
struct
dhcp_config
*
dhcp_conf
;
...
...
@@ -778,6 +796,7 @@ extern struct daemon {
unsigned
int
duid_enterprise
,
duid_config_len
;
unsigned
char
*
duid_config
;
char
*
dbus_name
;
unsigned
long
soa_sn
,
soa_refresh
,
soa_retry
,
soa_expiry
;
/* globally used stuff for DNS */
char
*
packet
;
/* packet buffer */
...
...
@@ -835,7 +854,7 @@ extern struct daemon {
void
cache_init
(
void
);
void
log_query
(
unsigned
int
flags
,
char
*
name
,
struct
all_addr
*
addr
,
char
*
arg
);
char
*
record_source
(
int
index
);
void
querystr
(
char
*
str
,
unsigned
short
type
);
void
querystr
(
char
*
desc
,
char
*
str
,
unsigned
short
type
);
struct
crec
*
cache_find_by_addr
(
struct
crec
*
crecp
,
struct
all_addr
*
addr
,
time_t
now
,
unsigned
short
prot
);
...
...
@@ -879,6 +898,16 @@ unsigned int questions_crc(struct dns_header *header, size_t plen, char *buff);
size_t
resize_packet
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
*
pheader
,
size_t
hlen
);
size_t
add_mac
(
struct
dns_header
*
header
,
size_t
plen
,
char
*
limit
,
union
mysockaddr
*
l3
);
int
add_resource_record
(
struct
dns_header
*
header
,
char
*
limit
,
int
*
truncp
,
unsigned
int
nameoffset
,
unsigned
char
**
pp
,
unsigned
long
ttl
,
unsigned
int
*
offset
,
unsigned
short
type
,
unsigned
short
class
,
char
*
format
,
...);
unsigned
char
*
skip_questions
(
struct
dns_header
*
header
,
size_t
plen
);
int
extract_name
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
**
pp
,
char
*
name
,
int
isExtract
,
int
extrabytes
);
int
in_arpa_name_2_addr
(
char
*
namein
,
struct
all_addr
*
addrp
);
/* auth.c */
size_t
answer_auth
(
struct
dns_header
*
header
,
char
*
limit
,
size_t
qlen
,
time_t
now
);
/* util.c */
void
rand_init
(
void
);
...
...
@@ -935,7 +964,7 @@ char *parse_server(char *arg, union mysockaddr *addr,
void
reply_query
(
int
fd
,
int
family
,
time_t
now
);
void
receive_query
(
struct
listener
*
listen
,
time_t
now
);
unsigned
char
*
tcp_request
(
int
confd
,
time_t
now
,
union
mysockaddr
*
local_addr
,
struct
in_addr
netmask
);
union
mysockaddr
*
local_addr
,
struct
in_addr
netmask
,
int
auth_dns
);
void
server_gone
(
struct
server
*
server
);
struct
frec
*
get_new_frec
(
time_t
now
,
int
*
wait
);
int
send_from
(
int
fd
,
int
nowild
,
char
*
packet
,
size_t
len
,
...
...
@@ -953,7 +982,7 @@ int enumerate_interfaces();
void
create_wildcard_listeners
(
void
);
void
create_bound_listeners
(
int
die
);
int
is_dad_listeners
(
void
);
int
iface_check
(
int
family
,
struct
all_addr
*
addr
,
char
*
name
);
int
iface_check
(
int
family
,
struct
all_addr
*
addr
,
char
*
name
,
int
*
auth_dns
);
int
fix_fd
(
int
fd
);
struct
in_addr
get_ifaddr
(
char
*
intr
);
#ifdef HAVE_IPV6
...
...
src/forward.c
View file @
4f7b304f
This diff is collapsed.
Click to expand it.
src/network.c
View file @
4f7b304f
...
...
@@ -107,13 +107,24 @@ int indextoname(int fd, int index, char *name)
#endif
int
iface_check
(
int
family
,
struct
all_addr
*
addr
,
char
*
name
)
int
iface_check
(
int
family
,
struct
all_addr
*
addr
,
char
*
name
,
int
*
auth
)
{
struct
iname
*
tmp
;
int
ret
=
1
;
/* Note: have to check all and not bail out early, so that we set the
"used" flags. */
if
(
auth
)
{
if
(
daemon
->
authinterface
&&
strcmp
(
daemon
->
authinterface
,
name
)
==
0
)
{
*
auth
=
1
;
return
1
;
}
else
*
auth
=
0
;
}
if
(
daemon
->
if_names
||
daemon
->
if_addrs
)
{
...
...
@@ -153,6 +164,7 @@ static int iface_allowed(struct irec **irecp, int if_index,
struct
ifreq
ifr
;
int
tftp_ok
=
!!
option_bool
(
OPT_TFTP
);
int
dhcp_ok
=
1
;
int
auth_dns
=
0
;
#ifdef HAVE_DHCP
struct
iname
*
tmp
;
#endif
...
...
@@ -210,25 +222,31 @@ static int iface_allowed(struct irec **irecp, int if_index,
}
if
(
addr
->
sa
.
sa_family
==
AF_INET
&&
!
iface_check
(
AF_INET
,
(
struct
all_addr
*
)
&
addr
->
in
.
sin_addr
,
ifr
.
ifr_name
))
!
iface_check
(
AF_INET
,
(
struct
all_addr
*
)
&
addr
->
in
.
sin_addr
,
ifr
.
ifr_name
,
&
auth_dns
))
return
1
;
#ifdef HAVE_DHCP
for
(
tmp
=
daemon
->
dhcp_except
;
tmp
;
tmp
=
tmp
->
next
)
if
(
tmp
->
name
&&
(
strcmp
(
tmp
->
name
,
ifr
.
ifr_name
)
==
0
))
{
tftp_ok
=
0
;
dhcp_ok
=
0
;
}
#endif
#ifdef HAVE_IPV6
if
(
addr
->
sa
.
sa_family
==
AF_INET6
&&
!
iface_check
(
AF_INET6
,
(
struct
all_addr
*
)
&
addr
->
in6
.
sin6_addr
,
ifr
.
ifr_name
))
!
iface_check
(
AF_INET6
,
(
struct
all_addr
*
)
&
addr
->
in6
.
sin6_addr
,
ifr
.
ifr_name
,
&
auth_dns
))
return
1
;
#endif
#ifdef HAVE_DHCP
/* No DHCP where we're doing auth DNS. */
if
(
auth_dns
)
{
tftp_ok
=
0
;
dhcp_ok
=
0
;
}
else
for
(
tmp
=
daemon
->
dhcp_except
;
tmp
;
tmp
=
tmp
->
next
)
if
(
tmp
->
name
&&
(
strcmp
(
tmp
->
name
,
ifr
.
ifr_name
)
==
0
))
{
tftp_ok
=
0
;
dhcp_ok
=
0
;
}
#endif
/* add to list */
if
((
iface
=
whine_malloc
(
sizeof
(
struct
irec
))))
{
...
...
@@ -236,6 +254,7 @@ static int iface_allowed(struct irec **irecp, int if_index,
iface
->
netmask
=
netmask
;
iface
->
tftp_ok
=
tftp_ok
;
iface
->
dhcp_ok
=
dhcp_ok
;
iface
->
dns_auth
=
auth_dns
;
iface
->
mtu
=
mtu
;
iface
->
dad
=
dad
;
iface
->
done
=
0
;
...
...
src/option.c
View file @
4f7b304f
...
...
@@ -121,6 +121,10 @@ struct myoption {
#define LOPT_RR 310
#define LOPT_CLVERBIND 311
#define LOPT_MAXCTTL 312
#define LOPT_AUTHZONE 313
#define LOPT_AUTHSERV 314
#define LOPT_AUTHTTL 315
#define LOPT_AUTHSOA 316
#ifdef HAVE_GETOPT_LONG
static
const
struct
option
opts
[]
=
...
...
@@ -247,6 +251,10 @@ static const struct myoption opts[] =
{
"dhcp-duid"
,
1
,
0
,
LOPT_DUID
},
{
"host-record"
,
1
,
0
,
LOPT_HOST_REC
},
{
"bind-dynamic"
,
0
,
0
,
LOPT_CLVERBIND
},
{
"auth-zone"
,
1
,
0
,
LOPT_AUTHZONE
},
{
"auth-server"
,
1
,
0
,
LOPT_AUTHSERV
},
{
"auth-ttl"
,
1
,
0
,
LOPT_AUTHTTL
},
{
"auth-soa"
,
1
,
0
,
LOPT_AUTHSOA
},
{
NULL
,
0
,
0
,
0
}
};
...
...
@@ -378,7 +386,11 @@ static struct {
{
LOPT_DUID
,
ARG_ONE
,
"<enterprise>,<duid>"
,
gettext_noop
(
"Specify DUID_EN-type DHCPv6 server DUID"
),
NULL
},
{
LOPT_HOST_REC
,
ARG_DUP
,
"<name>,<address>"
,
gettext_noop
(
"Specify host (A/AAAA and PTR) records"
),
NULL
},
{
LOPT_RR
,
ARG_DUP
,
"<name>,<RR-number>,[<data>]"
,
gettext_noop
(
"Specify arbitrary DNS resource record"
),
NULL
},
{
LOPT_CLVERBIND
,
OPT_CLEVERBIND
,
NULL
,
gettext_noop
(
"Bind to interfaces in use - check for new interfaces"
),
NULL
},
{
LOPT_CLVERBIND
,
OPT_CLEVERBIND
,
NULL
,
gettext_noop
(
"Bind to interfaces in use - check for new interfaces"
),
NULL
},
{
LOPT_AUTHSERV
,
ARG_ONE
,
"<interface>,<NS>"
,
gettext_noop
(
"Export local names to global DNS"
),
NULL
},
{
LOPT_AUTHZONE
,
ARG_DUP
,
"<domain>,<subnet>[,<subnet>]"
,
gettext_noop
(
"Domain to export to global DNS"
),
NULL
},
{
LOPT_AUTHTTL
,
ARG_ONE
,
"<integer>"
,
gettext_noop
(
"Set TTL for authoritative replies"
),
NULL
},
{
LOPT_AUTHSOA
,
ARG_ONE
,
"<serial>[,...]"
,
gettext_noop
(
"Set authoritive zone information"
),
NULL
},
{
0
,
0
,
NULL
,
NULL
,
NULL
}
};
...
...
@@ -1521,6 +1533,95 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
break
;
}
case
LOPT_AUTHSERV
:
/* --auth-server */
comma
=
split
(
arg
);
if
(
!
comma
)
ret_err
(
gen_err
);
daemon
->
authinterface
=
opt_string_alloc
(
arg
);
arg
=
comma
;
comma
=
split
(
arg
);
daemon
->
authserver
=
opt_string_alloc
(
arg
);
break
;
case
LOPT_AUTHZONE
:
/* --auth-zone */
{
struct
auth_zone
*
new
;
comma
=
split
(
arg
);
if
(
!
comma
)
ret_err
(
gen_err
);
new
=
safe_malloc
(
sizeof
(
struct
auth_zone
));
new
->
domain
=
opt_string_alloc
(
arg
);
new
->
subnet
=
NULL
;
new
->
next
=
daemon
->
auth_zones
;
daemon
->
auth_zones
=
new
;
while
((
arg
=
comma
))
{
int
prefixlen
=
0
;
char
*
prefix
;
struct
subnet
*
subnet
=
safe_malloc
(
sizeof
(
struct
subnet
));
subnet
->
next
=
new
->
subnet
;
new
->
subnet
=
subnet
;
comma
=
split
(
arg
);
prefix
=
split_chr
(
arg
,
'/'
);
if
(
prefix
&&
!
atoi_check
(
prefix
,
&
prefixlen
))
ret_err
(
gen_err
);
if
(
inet_pton
(
AF_INET
,
arg
,
&
subnet
->
addr4
))
{
subnet
->
prefixlen
=
(
prefixlen
==
0
)
?
24
:
prefixlen
;
subnet
->
is6
=
0
;
}
#ifdef HAVE_IPV6
else
if
(
inet_pton
(
AF_INET6
,
arg
,
&
subnet
->
addr6
))
{
subnet
->
prefixlen
=
(
prefixlen
==
0
)
?
64
:
prefixlen
;
subnet
->
is6
=
1
;
}
#endif
else
ret_err
(
gen_err
);
}
break
;
}
case
LOPT_AUTHSOA
:
/* --auth-soa */
comma
=
split
(
arg
);
atoi_check
(
arg
,
(
int
*
)
&
daemon
->
soa_sn
);
if
(
comma
)
{
arg
=
comma
;
comma
=
split
(
arg
);
daemon
->
hostmaster
=
opt_string_alloc
(
arg
);
if
(
comma
)
{
arg
=
comma
;
comma
=
split
(
arg
);
atoi_check
(
arg
,
(
int
*
)
&
daemon
->
soa_refresh
);
if
(
comma
)
{
arg
=
comma
;
comma
=
split
(
arg
);
atoi_check
(
arg
,
(
int
*
)
&
daemon
->
soa_retry
);
if
(
comma
)
{
arg
=
comma
;
comma
=
split
(
arg
);
atoi_check
(
arg
,
(
int
*
)
&
daemon
->
soa_expiry
);
}
}
}
}
break
;
case
's'
:
/* --domain */
if
(
strcmp
(
arg
,
"#"
)
==
0
)
set_option_bool
(
OPT_RESOLV_DOMAIN
);
...
...
@@ -1933,6 +2034,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
case
LOPT_NEGTTL
:
/* --neg-ttl */
case
LOPT_MAXTTL
:
/* --max-ttl */
case
LOPT_MAXCTTL
:
/* --max-cache-ttl */
case
LOPT_AUTHTTL
:
/* --auth-ttl */
{
int
ttl
;
if
(
!
atoi_check
(
arg
,
&
ttl
))
...
...
@@ -1943,6 +2045,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
daemon
->
max_ttl
=
(
unsigned
long
)
ttl
;
else
if
(
option
==
LOPT_MAXCTTL
)
daemon
->
max_cache_ttl
=
(
unsigned
long
)
ttl
;
else
if
(
option
==
LOPT_AUTHTTL
)
daemon
->
auth_ttl
=
(
unsigned
long
)
ttl
;
else
daemon
->
local_ttl
=
(
unsigned
long
)
ttl
;
break
;
...
...
@@ -3613,6 +3717,10 @@ void read_opts(int argc, char **argv, char *compile_opts)
daemon
->
tftp_max
=
TFTP_MAX_CONNECTIONS
;
daemon
->
edns_pktsz
=
EDNS_PKTSZ
;
daemon
->
log_fac
=
-
1
;
daemon
->
auth_ttl
=
AUTH_TTL
;
daemon
->
soa_refresh
=
SOA_REFRESH
;
daemon
->
soa_retry
=
SOA_RETRY
;
daemon
->
soa_expiry
=
SOA_EXPIRY
;
add_txt
(
"version.bind"
,
"dnsmasq-"
VERSION
);
add_txt
(
"authors.bind"
,
"Simon Kelley"
);
add_txt
(
"copyright.bind"
,
COPYRIGHT
);
...
...
@@ -3720,7 +3828,15 @@ void read_opts(int argc, char **argv, char *compile_opts)
tmp
->
addr
.
in6
.
sin6_port
=
htons
(
daemon
->
port
);
#endif
/* IPv6 */
}
/* create default, if not specified */
if
(
daemon
->
authserver
&&
!
daemon
->
hostmaster
)
{
strcpy
(
buff
,
"hostmaster."
);
strcat
(
buff
,
daemon
->
authserver
);
daemon
->
hostmaster
=
opt_string_alloc
(
buff
);
}
/* only one of these need be specified: the other defaults to the host-name */
if
(
option_bool
(
OPT_LOCALMX
)
||
daemon
->
mxnames
||
daemon
->
mxtarget
)
{
...
...
src/radv.c
View file @
4f7b304f
...
...
@@ -149,7 +149,7 @@ void icmp6_packet(void)
if
(
!
indextoname
(
daemon
->
icmp6fd
,
if_index
,
interface
))
return
;
if
(
!
iface_check
(
AF_LOCAL
,
NULL
,
interface
))
if
(
!
iface_check
(
AF_LOCAL
,
NULL
,
interface
,
NULL
))
return
;
for
(
tmp
=
daemon
->
dhcp_except
;
tmp
;
tmp
=
tmp
->
next
)
...
...
src/rfc1035.c
View file @
4f7b304f
...
...
@@ -16,10 +16,6 @@
#include "dnsmasq.h"
static
int
add_resource_record
(
struct
dns_header
*
header
,
char
*
limit
,
int
*
truncp
,
unsigned
int
nameoffset
,
unsigned
char
**
pp
,
unsigned
long
ttl
,
unsigned
int
*
offset
,
unsigned
short
type
,
unsigned
short
class
,
char
*
format
,
...);
#define CHECK_LEN(header, pp, plen, len) \
((size_t)((pp) - (unsigned char *)(header) + (len)) <= (plen))
...
...
@@ -27,8 +23,8 @@ static int add_resource_record(struct dns_header *header, char *limit, int *trun
#define ADD_RDLEN(header, pp, plen, len) \
(!CHECK_LEN(header, pp, plen, len) ? 0 : (((pp) += (len)), 1))
static
int
extract_name
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
**
pp
,
char
*
name
,
int
isExtract
,
int
extrabytes
)
int
extract_name
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
**
pp
,
char
*
name
,
int
isExtract
,
int
extrabytes
)
{
unsigned
char
*
cp
=
(
unsigned
char
*
)
name
,
*
p
=
*
pp
,
*
p1
=
NULL
;
unsigned
int
j
,
l
,
hops
=
0
;
...
...
@@ -173,7 +169,7 @@ static int extract_name(struct dns_header *header, size_t plen, unsigned char **
/* Max size of input string (for IPv6) is 75 chars.) */
#define MAXARPANAME 75
static
int
in_arpa_name_2_addr
(
char
*
namein
,
struct
all_addr
*
addrp
)
int
in_arpa_name_2_addr
(
char
*
namein
,
struct
all_addr
*
addrp
)
{
int
j
;
char
name
[
MAXARPANAME
+
1
],
*
cp1
;
...
...
@@ -333,7 +329,7 @@ static unsigned char *skip_name(unsigned char *ansp, struct dns_header *header,
return
ansp
;
}
static
unsigned
char
*
skip_questions
(
struct
dns_header
*
header
,
size_t
plen
)
unsigned
char
*
skip_questions
(
struct
dns_header
*
header
,
size_t
plen
)
{
int
q
;
unsigned
char
*
ansp
=
(
unsigned
char
*
)(
header
+
1
);
...
...
@@ -1189,8 +1185,8 @@ int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
return
0
;
}
static
int
add_resource_record
(
struct
dns_header
*
header
,
char
*
limit
,
int
*
truncp
,
unsigned
int
nameoffset
,
unsigned
char
**
pp
,
unsigned
long
ttl
,
unsigned
int
*
offset
,
unsigned
short
type
,
unsigned
short
class
,
char
*
format
,
...)
int
add_resource_record
(
struct
dns_header
*
header
,
char
*
limit
,
int
*
truncp
,
unsigned
int
nameoffset
,
unsigned
char
**
pp
,
unsigned
long
ttl
,
unsigned
int
*
offset
,
unsigned
short
type
,
unsigned
short
class
,
char
*
format
,
...)
{
va_list
ap
;
unsigned
char
*
sav
,
*
p
=
*
pp
;
...
...
@@ -1201,8 +1197,19 @@ static int add_resource_record(struct dns_header *header, char *limit, int *trun
if
(
truncp
&&
*
truncp
)
return
0
;
va_start
(
ap
,
format
);
/* make ap point to 1st unamed argument */
if
(
nameoffset
!=
0
)
{
PUTSHORT
(
nameoffset
|
0xc000
,
p
);
}
else
{
p
=
do_rfc1035_name
(
p
,
va_arg
(
ap
,
char
*
));
*
p
++
=
0
;
}
PUTSHORT
(
nameoffset
|
0xc000
,
p
);
PUTSHORT
(
type
,
p
);
PUTSHORT
(
class
,
p
);
PUTLONG
(
ttl
,
p
);
/* TTL */
...
...
@@ -1210,8 +1217,6 @@ static int add_resource_record(struct dns_header *header, char *limit, int *trun
sav
=
p
;
/* Save pointer to RDLength field */
PUTSHORT
(
0
,
p
);
/* Placeholder RDLength */
va_start
(
ap
,
format
);
/* make ap point to 1st unamed argument */
for
(;
*
format
;
format
++
)
switch
(
*
format
)
{
...
...
@@ -1857,7 +1862,3 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
return
ansp
-
(
unsigned
char
*
)
header
;
}
src/tftp.c
View file @
4f7b304f
...
...
@@ -193,12 +193,12 @@ void tftp_request(struct listener *listen, time_t now)
#ifdef HAVE_IPV6
if
(
listen
->
family
==
AF_INET6
)
{
if
(
!
iface_check
(
AF_INET6
,
(
struct
all_addr
*
)
&
addr
.
in6
.
sin6_addr
,
name
))
if
(
!
iface_check
(
AF_INET6
,
(
struct
all_addr
*
)
&
addr
.
in6
.
sin6_addr
,
name
,
NULL
))
return
;
}
else
#endif
if
(
!
iface_check
(
AF_INET
,
(
struct
all_addr
*
)
&
addr
.
in
.
sin_addr
,
name
))
if
(
!
iface_check
(
AF_INET
,
(
struct
all_addr
*
)
&
addr
.
in
.
sin_addr
,
name
,
NULL
))
return
;
#ifdef HAVE_DHCP
...
...
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