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
36bec089
Commit
36bec089
authored
Dec 04, 2012
by
Simon Kelley
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'auth'
parents
29d28dda
45dd1fec
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
900 additions
and
190 deletions
+900
-190
Makefile
Makefile
+1
-1
bld/Android.mk
bld/Android.mk
+1
-1
src/auth.c
src/auth.c
+499
-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
+122
-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 @
36bec089
...
@@ -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
dhcp-common.o outpacket.o radv.o slaac.o
auth.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
...
...
bld/Android.mk
View file @
36bec089
...
@@ -8,7 +8,7 @@ LOCAL_SRC_FILES := bpf.c cache.c dbus.c dhcp.c dnsmasq.c \
...
@@ -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
radv.c slaac.c
auth.c
LOCAL_MODULE
:=
dnsmasq
LOCAL_MODULE
:=
dnsmasq
...
...
src/auth.c
0 → 100644
View file @
36bec089
/* 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
struct
subnet
*
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
=
htonl
(
~
((
1
<<
(
32
-
subnet
->
prefixlen
))
-
1
));
if
(
is_same_net
(
addr
,
subnet
->
addr4
,
mask
))
return
subnet
;
}
#ifdef HAVE_IPV6
else
if
(
is_same_net6
(
&
(
addr_u
->
addr
.
addr6
),
&
subnet
->
addr6
,
subnet
->
prefixlen
))
return
subnet
;
#endif
}
return
NULL
;
}
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
,
ns
=
0
;
struct
auth_zone
*
zone
=
NULL
;
struct
subnet
*
subnet
=
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
=
0
;
int
found
=
0
;
struct
mx_srv_record
*
rec
,
*
move
,
**
up
;
struct
txt_record
*
txt
;
struct
interface_name
*
intr
;
struct
naptr
*
na
;
struct
all_addr
addr
;
struct
cname
*
a
;
/* 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
)
{
if
(
!
(
flag
=
in_arpa_name_2_addr
(
name
,
&
addr
)))
continue
;
for
(
zone
=
daemon
->
auth_zones
;
zone
;
zone
=
zone
->
next
)
if
((
subnet
=
filter_zone
(
zone
,
flag
,
&
addr
)))
break
;
if
(
!
zone
)
{
auth
=
0
;
continue
;
}
domainlen
=
strlen
(
zone
->
domain
);
if
(
flag
==
F_IPV4
)
{
for
(
intr
=
daemon
->
int_names
;
intr
;
intr
=
intr
->
next
)
{
if
(
addr
.
addr
.
addr4
.
s_addr
==
get_ifaddr
(
intr
->
intr
).
s_addr
)
break
;
else
while
(
intr
->
next
&&
strcmp
(
intr
->
intr
,
intr
->
next
->
intr
)
==
0
)
intr
=
intr
->
next
;
}
if
(
intr
)
{
namelen
=
strlen
(
intr
->
name
);
if
(
namelen
>=
domainlen
&&
hostname_isequal
(
zone
->
domain
,
&
intr
->
name
[
namelen
-
domainlen
])
&&
(
namelen
==
domainlen
||
intr
->
name
[
namelen
-
domainlen
-
1
]
==
'.'
))
{
found
=
1
;
log_query
(
F_IPV4
|
F_REVERSE
|
F_CONFIG
,
intr
->
name
,
&
addr
,
NULL
);
if
(
add_resource_record
(
header
,
limit
,
&
trunc
,
nameoffset
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
T_PTR
,
C_IN
,
"d"
,
intr
->
name
))
anscount
++
;
}
}
}
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
));
found
=
1
;
if
(
add_resource_record
(
header
,
limit
,
&
trunc
,
nameoffset
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
T_PTR
,
C_IN
,
"d"
,
name
))
anscount
++
;
}
else
if
(
crecp
->
flags
&
(
F_DHCP
|
F_HOSTS
))
{
namelen
=
strlen
(
name
);
if
(
namelen
>
domainlen
+
1
&&
name
[
namelen
-
domainlen
-
1
]
!=
'.'
)
continue
;
if
(
namelen
<
domainlen
||
!
hostname_isequal
(
zone
->
domain
,
&
name
[
namelen
-
domainlen
]))
continue
;
/* wrong domain */
log_query
(
crecp
->
flags
&
~
F_FORWARD
,
name
,
&
addr
,
record_source
(
crecp
->
uid
));
found
=
1
;
if
(
add_resource_record
(
header
,
limit
,
&
trunc
,
nameoffset
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
T_PTR
,
C_IN
,
"d"
,
name
))
anscount
++
;
}
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
;
}
cname_restart:
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
])
&&
(
namelen
==
domainlen
||
name
[
namelen
-
domainlen
-
1
]
==
'.'
))
break
;
}
if
(
!
zone
)
{
auth
=
0
;
continue
;
}
for
(
rec
=
daemon
->
mxnames
;
rec
;
rec
=
rec
->
next
)
if
(
!
rec
->
issrv
&&
hostname_isequal
(
name
,
rec
->
name
))
{
nxdomain
=
0
;
if
(
qtype
==
T_MX
)
{
found
=
1
;
log_query
(
F_CONFIG
|
F_RRNAME
,
name
,
NULL
,
"<MX>"
);
if
(
add_resource_record
(
header
,
limit
,
&
trunc
,
nameoffset
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
T_MX
,
C_IN
,
"sd"
,
rec
->
weight
,
rec
->
target
))
anscount
++
;
}
}
for
(
move
=
NULL
,
up
=
&
daemon
->
mxnames
,
rec
=
daemon
->
mxnames
;
rec
;
rec
=
rec
->
next
)
if
(
rec
->
issrv
&&
hostname_isequal
(
name
,
rec
->
name
))
{
nxdomain
=
0
;
if
(
qtype
==
T_SRV
)
{
found
=
1
;
log_query
(
F_CONFIG
|
F_RRNAME
,
name
,
NULL
,
"<SRV>"
);
if
(
add_resource_record
(
header
,
limit
,
&
trunc
,
nameoffset
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
T_SRV
,
C_IN
,
"sssd"
,
rec
->
priority
,
rec
->
weight
,
rec
->
srvport
,
rec
->
target
))
anscount
++
;
}
/* unlink first SRV record found */
if
(
!
move
)
{
move
=
rec
;
*
up
=
rec
->
next
;
}
else
up
=
&
rec
->
next
;
}
else
up
=
&
rec
->
next
;
/* put first SRV record back at the end. */
if
(
move
)
{
*
up
=
move
;
move
->
next
=
NULL
;
}
for
(
txt
=
daemon
->
rr
;
txt
;
txt
=
txt
->
next
)
if
(
hostname_isequal
(
name
,
txt
->
name
))
{
nxdomain
=
0
;
if
(
txt
->
class
==
qtype
)
{
found
=
1
;
log_query
(
F_CONFIG
|
F_RRNAME
,
name
,
NULL
,
"<RR>"
);
if
(
add_resource_record
(
header
,
limit
,
&
trunc
,
nameoffset
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
txt
->
class
,
C_IN
,
"t"
,
txt
->
len
,
txt
->
txt
))
anscount
++
;
}
}
for
(
txt
=
daemon
->
txt
;
txt
;
txt
=
txt
->
next
)
if
(
txt
->
class
==
C_IN
&&
hostname_isequal
(
name
,
txt
->
name
))
{
nxdomain
=
0
;
if
(
qtype
==
T_TXT
)
{
found
=
1
;
log_query
(
F_CONFIG
|
F_RRNAME
,
name
,
NULL
,
"<TXT>"
);
if
(
add_resource_record
(
header
,
limit
,
&
trunc
,
nameoffset
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
T_TXT
,
C_IN
,
"t"
,
txt
->
len
,
txt
->
txt
))
anscount
++
;
}
}
for
(
na
=
daemon
->
naptr
;
na
;
na
=
na
->
next
)
if
(
hostname_isequal
(
name
,
na
->
name
))
{
nxdomain
=
0
;
if
(
qtype
==
T_NAPTR
)
{
found
=
1
;
log_query
(
F_CONFIG
|
F_RRNAME
,
name
,
NULL
,
"<NAPTR>"
);
if
(
add_resource_record
(
header
,
limit
,
&
trunc
,
nameoffset
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
T_NAPTR
,
C_IN
,
"sszzzd"
,
na
->
order
,
na
->
pref
,
na
->
flags
,
na
->
services
,
na
->
regexp
,
na
->
replace
))
anscount
++
;
}
}
for
(
intr
=
daemon
->
int_names
;
intr
;
intr
=
intr
->
next
)
if
(
hostname_isequal
(
name
,
intr
->
name
))
{
nxdomain
=
0
;
if
(
qtype
==
T_A
&&
(
addr
.
addr
.
addr4
=
get_ifaddr
(
intr
->
intr
)).
s_addr
!=
(
in_addr_t
)
-
1
)
{
found
=
1
;
log_query
(
F_FORWARD
|
F_CONFIG
|
F_IPV4
,
name
,
&
addr
,
NULL
);
if
(
add_resource_record
(
header
,
limit
,
&
trunc
,
nameoffset
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
T_A
,
C_IN
,
"4"
,
&
addr
))
anscount
++
;
}
}
for
(
a
=
daemon
->
cnames
;
a
;
a
=
a
->
next
)
if
(
hostname_isequal
(
name
,
a
->
alias
)
)
{
log_query
(
F_CONFIG
|
F_CNAME
,
name
,
NULL
,
NULL
);
strcpy
(
name
,
a
->
target
);
if
(
!
strchr
(
name
,
'.'
))
{
strcat
(
name
,
"."
);
strcat
(
name
,
zone
->
domain
);
}
found
=
1
;
if
(
add_resource_record
(
header
,
limit
,
&
trunc
,
nameoffset
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
T_CNAME
,
C_IN
,
"d"
,
name
))
anscount
++
;
goto
cname_restart
;
}
if
(
qtype
==
T_A
)
flag
=
F_IPV4
;
#ifdef HAVE_IPV6
if
(
qtype
==
T_AAAA
)
flag
=
F_IPV6
;
#endif
if
(
qtype
==
T_SOA
&&
namelen
==
domainlen
)
{
soa
=
1
;
/* inhibits auth section */
found
=
1
;
log_query
(
F_RRNAME
|
F_AUTH
,
zone
->
domain
,
NULL
,
"<SOA>"
);
}
if
(
qtype
==
T_NS
&&
namelen
==
domainlen
)
{
ns
=
1
;
/* inhibits auth section */
found
=
1
;
log_query
(
F_RRNAME
|
F_AUTH
,
zone
->
domain
,
NULL
,
"<NS>"
);
}
if
(
!
option_bool
(
OPT_DHCP_FQDN
)
&&
namelen
>
domainlen
+
1
)
{
name
[
namelen
-
domainlen
-
1
]
=
0
;
/* remove domain part */
if
(
!
strchr
(
name
,
'.'
)
&&
(
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 */
found
=
1
;
if
(
add_resource_record
(
header
,
limit
,
&
trunc
,
nameoffset
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
qtype
,
C_IN
,
qtype
==
T_A
?
"4"
:
"6"
,
&
crecp
->
addr
))
anscount
++
;
}
}
while
((
crecp
=
cache_find_by_name
(
crecp
,
name
,
now
,
F_IPV4
|
F_IPV6
)));
}
name
[
namelen
-
domainlen
-
1
]
=
'.'
;
/* restore domain part */
}
if
((
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
));
found
=
1
;
if
(
add_resource_record
(
header
,
limit
,
&
trunc
,
nameoffset
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
qtype
,
C_IN
,
qtype
==
T_A
?
"4"
:
"6"
,
&
crecp
->
addr
))
anscount
++
;
}
}
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
)
{
if
(
!
subnet
)
name
=
zone
->
domain
;
else
{
/* handle NS and SOA for PTR records */
if
(
!
subnet
->
is6
)
{
in_addr_t
a
=
ntohl
(
subnet
->
addr4
.
s_addr
)
>>
8
;
char
*
p
=
name
;
if
(
subnet
->
prefixlen
==
24
)
p
+=
sprintf
(
p
,
"%d."
,
a
&
0xff
);
a
=
a
>>
8
;
if
(
subnet
->
prefixlen
!=
8
)
p
+=
sprintf
(
p
,
"%d."
,
a
&
0xff
);
a
=
a
>>
8
;
p
+=
sprintf
(
p
,
"%d.in-addr.arpa"
,
a
&
0xff
);
}
#ifdef HAVE_IPV6
else
{
char
*
p
=
name
;
int
i
;
for
(
i
=
subnet
->
prefixlen
-
1
;
i
>=
0
;
i
-=
4
)
{
int
dig
=
((
unsigned
char
*
)
&
subnet
->
addr6
)[
i
>>
3
];
p
+=
sprintf
(
p
,
"%.1x."
,
(
i
>>
2
)
&
1
?
dig
&
15
:
dig
>>
4
);
}
p
+=
sprintf
(
p
,
"ip6.arpa"
);
}
#endif
}
/* handle NS and SOA in auth section or for explicit queries */
if
((
anscount
!=
0
||
ns
)
&&
add_resource_record
(
header
,
limit
,
&
trunc
,
0
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
T_NS
,
C_IN
,
"d"
,
name
,
daemon
->
authserver
))
{
if
(
ns
)
anscount
++
;
else
authcount
++
;
}
if
((
anscount
==
0
||
soa
)
&&
add_resource_record
(
header
,
limit
,
&
trunc
,
0
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
T_SOA
,
C_IN
,
"ddlllll"
,
name
,
daemon
->
authserver
,
daemon
->
hostmaster
,
daemon
->
soa_sn
,
daemon
->
soa_refresh
,
daemon
->
soa_retry
,
daemon
->
soa_expiry
,
daemon
->
auth_ttl
))
{
if
(
soa
)
anscount
++
;
else
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 @
36bec089
...
@@ -1248,14 +1248,14 @@ char *record_source(int index)
...
@@ -1248,14 +1248,14 @@ char *record_source(int index)
return
"<unknown>"
;
return
"<unknown>"
;
}
}
void
querystr
(
char
*
str
,
unsigned
short
type
)
void
querystr
(
char
*
desc
,
char
*
str
,
unsigned
short
type
)
{
{
unsigned
int
i
;
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
++
)
for
(
i
=
0
;
i
<
(
sizeof
(
typestr
)
/
sizeof
(
typestr
[
0
]));
i
++
)
if
(
typestr
[
i
].
type
==
type
)
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
)
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)
...
@@ -1316,6 +1316,8 @@ void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg)
source
=
arg
;
source
=
arg
;
else
if
(
flags
&
F_UPSTREAM
)
else
if
(
flags
&
F_UPSTREAM
)
source
=
"reply"
;
source
=
"reply"
;
else
if
(
flags
&
F_AUTH
)
source
=
"auth"
;
else
if
(
flags
&
F_SERVER
)
else
if
(
flags
&
F_SERVER
)
{
{
source
=
"forwarded"
;
source
=
"forwarded"
;
...
...
src/config.h
View file @
36bec089
...
@@ -42,7 +42,11 @@
...
@@ -42,7 +42,11 @@
#define EDNS0_OPTION_MAC 5
/* dyndns.org temporary assignment */
#define EDNS0_OPTION_MAC 5
/* dyndns.org temporary assignment */
#define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq"
/* Default - may be overridden by config */
#define DNSMASQ_SERVICE "uk.org.thekelleys.dnsmasq"
/* Default - may be overridden by config */
#define DNSMASQ_PATH "/uk/org/thekelleys/dnsmasq"
#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.
/* compile-time options: uncomment below to enable or do eg.
make COPTS=-DHAVE_BROKEN_RTC
make COPTS=-DHAVE_BROKEN_RTC
...
...
src/dhcp-common.c
View file @
36bec089
...
@@ -366,7 +366,7 @@ static int join_multicast_worker(struct in6_addr *local, int prefix,
...
@@ -366,7 +366,7 @@ static int join_multicast_worker(struct in6_addr *local, int prefix,
close
(
fd
);
close
(
fd
);
/* Are we doing DHCP on this interface? */
/* 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
;
return
1
;
for
(
tmp
=
daemon
->
dhcp_except
;
tmp
;
tmp
=
tmp
->
next
)
for
(
tmp
=
daemon
->
dhcp_except
;
tmp
;
tmp
=
tmp
->
next
)
...
...
src/dhcp.c
View file @
36bec089
...
@@ -262,7 +262,7 @@ void dhcp_packet(time_t now, int pxe_fd)
...
@@ -262,7 +262,7 @@ void dhcp_packet(time_t now, int pxe_fd)
parm
.
current
=
NULL
;
parm
.
current
=
NULL
;
parm
.
ind
=
iface_index
;
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
/* If we failed to match the primary address of the interface, see if we've got a --listen-address
for a secondary */
for a secondary */
...
...
src/dnsmasq.c
View file @
36bec089
...
@@ -84,6 +84,7 @@ int main (int argc, char **argv)
...
@@ -84,6 +84,7 @@ int main (int argc, char **argv)
daemon
->
addrbuff
=
safe_malloc
(
ADDRSTRLEN
);
daemon
->
addrbuff
=
safe_malloc
(
ADDRSTRLEN
);
#ifdef HAVE_DHCP
#ifdef HAVE_DHCP
if
(
!
daemon
->
lease_file
)
if
(
!
daemon
->
lease_file
)
{
{
...
@@ -150,6 +151,14 @@ int main (int argc, char **argv)
...
@@ -150,6 +151,14 @@ int main (int argc, char **argv)
rand_init
();
rand_init
();
now
=
dnsmasq_time
();
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
#ifdef HAVE_DHCP
if
(
daemon
->
dhcp
||
daemon
->
dhcp6
)
if
(
daemon
->
dhcp
||
daemon
->
dhcp6
)
...
@@ -1440,11 +1449,18 @@ static void check_dns_listeners(fd_set *set, time_t now)
...
@@ -1440,11 +1449,18 @@ static void check_dns_listeners(fd_set *set, time_t now)
struct
server
*
s
;
struct
server
*
s
;
int
flags
;
int
flags
;
struct
in_addr
netmask
;
struct
in_addr
netmask
;
int
auth_dns
;
if
(
iface
)
if
(
iface
)
netmask
=
iface
->
netmask
;
{
netmask
=
iface
->
netmask
;
auth_dns
=
iface
->
dns_auth
;
}
else
else
netmask
.
s_addr
=
0
;
{
netmask
.
s_addr
=
0
;
auth_dns
=
0
;
}
#ifndef NO_FORK
#ifndef NO_FORK
/* Arrange for SIGALARM after CHILD_LIFETIME seconds to
/* Arrange for SIGALARM after CHILD_LIFETIME seconds to
...
@@ -1463,7 +1479,7 @@ static void check_dns_listeners(fd_set *set, time_t now)
...
@@ -1463,7 +1479,7 @@ static void check_dns_listeners(fd_set *set, time_t now)
if
((
flags
=
fcntl
(
confd
,
F_GETFL
,
0
))
!=
-
1
)
if
((
flags
=
fcntl
(
confd
,
F_GETFL
,
0
))
!=
-
1
)
fcntl
(
confd
,
F_SETFL
,
flags
&
~
O_NONBLOCK
);
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
);
shutdown
(
confd
,
SHUT_RDWR
);
close
(
confd
);
close
(
confd
);
...
...
src/dnsmasq.h
View file @
36bec089
...
@@ -278,6 +278,20 @@ struct cname {
...
@@ -278,6 +278,20 @@ struct cname {
struct
cname
*
next
;
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
host_record
{
struct
name_list
{
struct
name_list
{
char
*
name
;
char
*
name
;
...
@@ -357,6 +371,8 @@ struct crec {
...
@@ -357,6 +371,8 @@ struct crec {
#define F_SERVER (1u<<18)
#define F_SERVER (1u<<18)
#define F_QUERY (1u<<19)
#define F_QUERY (1u<<19)
#define F_NOERR (1u<<20)
#define F_NOERR (1u<<20)
#define F_AUTH (1u<<21)
/* composites */
/* composites */
#define F_TYPE (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS)
/* Only one may be set */
#define F_TYPE (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS)
/* Only one may be set */
...
@@ -412,7 +428,7 @@ struct server {
...
@@ -412,7 +428,7 @@ struct server {
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 */
int
tftp_ok
,
dhcp_ok
,
mtu
,
done
,
dad
;
int
tftp_ok
,
dhcp_ok
,
mtu
,
done
,
dad
,
dns_auth
;
char
*
name
;
char
*
name
;
struct
irec
*
next
;
struct
irec
*
next
;
};
};
...
@@ -733,11 +749,13 @@ extern struct daemon {
...
@@ -733,11 +749,13 @@ extern struct daemon {
struct
ptr_record
*
ptr
;
struct
ptr_record
*
ptr
;
struct
host_record
*
host_records
,
*
host_records_tail
;
struct
host_record
*
host_records
,
*
host_records_tail
;
struct
cname
*
cnames
;
struct
cname
*
cnames
;
struct
auth_zone
*
auth_zones
;
struct
interface_name
*
int_names
;
struct
interface_name
*
int_names
;
char
*
mxtarget
;
char
*
mxtarget
;
char
*
lease_file
;
char
*
lease_file
;
char
*
username
,
*
groupname
,
*
scriptuser
;
char
*
username
,
*
groupname
,
*
scriptuser
;
char
*
luascript
;
char
*
luascript
;
char
*
authserver
,
*
authinterface
,
*
hostmaster
;
int
group_set
,
osport
;
int
group_set
,
osport
;
char
*
domain_suffix
;
char
*
domain_suffix
;
struct
cond_domain
*
cond_domain
;
struct
cond_domain
*
cond_domain
;
...
@@ -751,7 +769,7 @@ extern struct daemon {
...
@@ -751,7 +769,7 @@ extern struct daemon {
int
max_logs
;
/* queue limit */
int
max_logs
;
/* queue limit */
int
cachesize
,
ftabsize
;
int
cachesize
,
ftabsize
;
int
port
,
query_port
,
min_port
;
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
hostsfile
*
addn_hosts
;
struct
dhcp_context
*
dhcp
,
*
dhcp6
,
*
ra_contexts
;
struct
dhcp_context
*
dhcp
,
*
dhcp6
,
*
ra_contexts
;
struct
dhcp_config
*
dhcp_conf
;
struct
dhcp_config
*
dhcp_conf
;
...
@@ -778,6 +796,7 @@ extern struct daemon {
...
@@ -778,6 +796,7 @@ extern struct daemon {
unsigned
int
duid_enterprise
,
duid_config_len
;
unsigned
int
duid_enterprise
,
duid_config_len
;
unsigned
char
*
duid_config
;
unsigned
char
*
duid_config
;
char
*
dbus_name
;
char
*
dbus_name
;
unsigned
long
soa_sn
,
soa_refresh
,
soa_retry
,
soa_expiry
;
/* globally used stuff for DNS */
/* globally used stuff for DNS */
char
*
packet
;
/* packet buffer */
char
*
packet
;
/* packet buffer */
...
@@ -835,7 +854,7 @@ extern struct daemon {
...
@@ -835,7 +854,7 @@ extern struct daemon {
void
cache_init
(
void
);
void
cache_init
(
void
);
void
log_query
(
unsigned
int
flags
,
char
*
name
,
struct
all_addr
*
addr
,
char
*
arg
);
void
log_query
(
unsigned
int
flags
,
char
*
name
,
struct
all_addr
*
addr
,
char
*
arg
);
char
*
record_source
(
int
index
);
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
crec
*
cache_find_by_addr
(
struct
crec
*
crecp
,
struct
all_addr
*
addr
,
time_t
now
,
struct
all_addr
*
addr
,
time_t
now
,
unsigned
short
prot
);
unsigned
short
prot
);
...
@@ -879,6 +898,16 @@ unsigned int questions_crc(struct dns_header *header, size_t plen, char *buff);
...
@@ -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
,
size_t
resize_packet
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
*
pheader
,
size_t
hlen
);
unsigned
char
*
pheader
,
size_t
hlen
);
size_t
add_mac
(
struct
dns_header
*
header
,
size_t
plen
,
char
*
limit
,
union
mysockaddr
*
l3
);
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 */
/* util.c */
void
rand_init
(
void
);
void
rand_init
(
void
);
...
@@ -935,7 +964,7 @@ char *parse_server(char *arg, union mysockaddr *addr,
...
@@ -935,7 +964,7 @@ char *parse_server(char *arg, union mysockaddr *addr,
void
reply_query
(
int
fd
,
int
family
,
time_t
now
);
void
reply_query
(
int
fd
,
int
family
,
time_t
now
);
void
receive_query
(
struct
listener
*
listen
,
time_t
now
);
void
receive_query
(
struct
listener
*
listen
,
time_t
now
);
unsigned
char
*
tcp_request
(
int
confd
,
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
);
void
server_gone
(
struct
server
*
server
);
struct
frec
*
get_new_frec
(
time_t
now
,
int
*
wait
);
struct
frec
*
get_new_frec
(
time_t
now
,
int
*
wait
);
int
send_from
(
int
fd
,
int
nowild
,
char
*
packet
,
size_t
len
,
int
send_from
(
int
fd
,
int
nowild
,
char
*
packet
,
size_t
len
,
...
@@ -953,7 +982,7 @@ int enumerate_interfaces();
...
@@ -953,7 +982,7 @@ int enumerate_interfaces();
void
create_wildcard_listeners
(
void
);
void
create_wildcard_listeners
(
void
);
void
create_bound_listeners
(
int
die
);
void
create_bound_listeners
(
int
die
);
int
is_dad_listeners
(
void
);
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
);
int
fix_fd
(
int
fd
);
struct
in_addr
get_ifaddr
(
char
*
intr
);
struct
in_addr
get_ifaddr
(
char
*
intr
);
#ifdef HAVE_IPV6
#ifdef HAVE_IPV6
...
...
src/forward.c
View file @
36bec089
...
@@ -635,6 +635,7 @@ void receive_query(struct listener *listen, time_t now)
...
@@ -635,6 +635,7 @@ void receive_query(struct listener *listen, time_t now)
size_t
m
;
size_t
m
;
ssize_t
n
;
ssize_t
n
;
int
if_index
=
0
;
int
if_index
=
0
;
int
auth_dns
=
0
;
struct
iovec
iov
[
1
];
struct
iovec
iov
[
1
];
struct
msghdr
msg
;
struct
msghdr
msg
;
struct
cmsghdr
*
cmptr
;
struct
cmsghdr
*
cmptr
;
...
@@ -657,17 +658,20 @@ void receive_query(struct listener *listen, time_t now)
...
@@ -657,17 +658,20 @@ void receive_query(struct listener *listen, time_t now)
/* packet buffer overwritten */
/* packet buffer overwritten */
daemon
->
srv_save
=
NULL
;
daemon
->
srv_save
=
NULL
;
if
(
listen
->
iface
&&
listen
->
family
==
AF_INET
&&
option_bool
(
OPT_NOWILD
))
dst_addr_4
.
s_addr
=
0
;
{
netmask
.
s_addr
=
0
;
dst_addr_4
=
listen
->
iface
->
addr
.
in
.
sin_addr
;
netmask
=
listen
->
iface
->
netmask
;
if
(
listen
->
iface
&&
option_bool
(
OPT_NOWILD
))
}
else
{
{
dst_addr_4
.
s_addr
=
0
;
auth_dns
=
listen
->
iface
->
dns_auth
;
netmask
.
s_addr
=
0
;
if
(
listen
->
family
==
AF_INET
)
{
dst_addr_4
=
listen
->
iface
->
addr
.
in
.
sin_addr
;
netmask
=
listen
->
iface
->
netmask
;
}
}
}
iov
[
0
].
iov_base
=
daemon
->
packet
;
iov
[
0
].
iov_base
=
daemon
->
packet
;
iov
[
0
].
iov_len
=
daemon
->
edns_pktsz
;
iov
[
0
].
iov_len
=
daemon
->
edns_pktsz
;
...
@@ -760,7 +764,7 @@ void receive_query(struct listener *listen, time_t now)
...
@@ -760,7 +764,7 @@ void receive_query(struct listener *listen, time_t now)
/* enforce available interface configuration */
/* enforce available interface configuration */
if
(
!
indextoname
(
listen
->
fd
,
if_index
,
ifr
.
ifr_name
)
||
if
(
!
indextoname
(
listen
->
fd
,
if_index
,
ifr
.
ifr_name
)
||
!
iface_check
(
listen
->
family
,
&
dst_addr
,
ifr
.
ifr_name
))
!
iface_check
(
listen
->
family
,
&
dst_addr
,
ifr
.
ifr_name
,
&
auth_dns
))
return
;
return
;
if
(
listen
->
family
==
AF_INET
&&
option_bool
(
OPT_LOCALISE
))
if
(
listen
->
family
==
AF_INET
&&
option_bool
(
OPT_LOCALISE
))
...
@@ -796,7 +800,7 @@ void receive_query(struct listener *listen, time_t now)
...
@@ -796,7 +800,7 @@ void receive_query(struct listener *listen, time_t now)
{
{
char
types
[
20
];
char
types
[
20
];
querystr
(
types
,
type
);
querystr
(
auth_dns
?
"auth"
:
"query"
,
types
,
type
);
if
(
listen
->
family
==
AF_INET
)
if
(
listen
->
family
==
AF_INET
)
log_query
(
F_QUERY
|
F_IPV4
|
F_FORWARD
,
daemon
->
namebuff
,
log_query
(
F_QUERY
|
F_IPV4
|
F_FORWARD
,
daemon
->
namebuff
,
...
@@ -808,19 +812,30 @@ void receive_query(struct listener *listen, time_t now)
...
@@ -808,19 +812,30 @@ void receive_query(struct listener *listen, time_t now)
#endif
#endif
}
}
m
=
answer_request
(
header
,
((
char
*
)
header
)
+
PACKETSZ
,
(
size_t
)
n
,
if
(
auth_dns
)
dst_addr_4
,
netmask
,
now
);
if
(
m
>=
1
)
{
{
send_from
(
listen
->
fd
,
option_bool
(
OPT_NOWILD
)
||
option_bool
(
OPT_CLEVERBIND
),
m
=
answer_auth
(
header
,
((
char
*
)
header
)
+
PACKETSZ
,
(
size_t
)
n
,
now
);
(
char
*
)
header
,
m
,
&
source_addr
,
&
dst_addr
,
if_index
);
if
(
m
>=
1
)
daemon
->
local_answer
++
;
send_from
(
listen
->
fd
,
option_bool
(
OPT_NOWILD
)
||
option_bool
(
OPT_CLEVERBIND
),
(
char
*
)
header
,
m
,
&
source_addr
,
&
dst_addr
,
if_index
);
}
}
else
if
(
forward_query
(
listen
->
fd
,
&
source_addr
,
&
dst_addr
,
if_index
,
header
,
(
size_t
)
n
,
now
,
NULL
))
daemon
->
queries_forwarded
++
;
else
else
daemon
->
local_answer
++
;
{
m
=
answer_request
(
header
,
((
char
*
)
header
)
+
PACKETSZ
,
(
size_t
)
n
,
dst_addr_4
,
netmask
,
now
);
if
(
m
>=
1
)
{
send_from
(
listen
->
fd
,
option_bool
(
OPT_NOWILD
)
||
option_bool
(
OPT_CLEVERBIND
),
(
char
*
)
header
,
m
,
&
source_addr
,
&
dst_addr
,
if_index
);
daemon
->
local_answer
++
;
}
else
if
(
forward_query
(
listen
->
fd
,
&
source_addr
,
&
dst_addr
,
if_index
,
header
,
(
size_t
)
n
,
now
,
NULL
))
daemon
->
queries_forwarded
++
;
else
daemon
->
local_answer
++
;
}
}
}
/* The daemon forks before calling this: it should deal with one connection,
/* The daemon forks before calling this: it should deal with one connection,
...
@@ -828,7 +843,7 @@ void receive_query(struct listener *listen, time_t now)
...
@@ -828,7 +843,7 @@ void receive_query(struct listener *listen, time_t now)
about resources for debug mode, when the fork is suppressed: that's
about resources for debug mode, when the fork is suppressed: that's
done by the caller. */
done by the caller. */
unsigned
char
*
tcp_request
(
int
confd
,
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
)
{
{
size_t
size
=
0
;
size_t
size
=
0
;
int
norebind
=
0
;
int
norebind
=
0
;
...
@@ -870,7 +885,7 @@ unsigned char *tcp_request(int confd, time_t now,
...
@@ -870,7 +885,7 @@ unsigned char *tcp_request(int confd, time_t now,
{
{
char
types
[
20
];
char
types
[
20
];
querystr
(
types
,
qtype
);
querystr
(
auth_dns
?
"auth"
:
"query"
,
types
,
qtype
);
if
(
peer_addr
.
sa
.
sa_family
==
AF_INET
)
if
(
peer_addr
.
sa
.
sa_family
==
AF_INET
)
log_query
(
F_QUERY
|
F_IPV4
|
F_FORWARD
,
daemon
->
namebuff
,
log_query
(
F_QUERY
|
F_IPV4
|
F_FORWARD
,
daemon
->
namebuff
,
...
@@ -887,137 +902,142 @@ unsigned char *tcp_request(int confd, time_t now,
...
@@ -887,137 +902,142 @@ unsigned char *tcp_request(int confd, time_t now,
else
else
dst_addr_4
.
s_addr
=
0
;
dst_addr_4
.
s_addr
=
0
;
/* m > 0 if answered from cache */
if
(
auth_dns
)
m
=
answer_request
(
header
,
((
char
*
)
header
)
+
65536
,
(
unsigned
int
)
size
,
m
=
answer_auth
(
header
,
((
char
*
)
header
)
+
65536
,
(
size_t
)
size
,
now
);
dst_addr_4
,
netmask
,
now
);
else
/* Do this by steam now we're not in the select() loop */
check_log_writer
(
NULL
);
if
(
m
==
0
)
{
{
unsigned
int
flags
=
0
;
/* m > 0 if answered from cache */
struct
all_addr
*
addrp
=
NULL
;
m
=
answer_request
(
header
,
((
char
*
)
header
)
+
65536
,
(
size_t
)
size
,
int
type
=
0
;
dst_addr_4
,
netmask
,
now
);
char
*
domain
=
NULL
;
if
(
option_bool
(
OPT_ADD_MAC
))
size
=
add_mac
(
header
,
size
,
((
char
*
)
header
)
+
65536
,
&
peer_addr
);
if
(
gotname
)
flags
=
search_servers
(
now
,
&
addrp
,
gotname
,
daemon
->
namebuff
,
&
type
,
&
domain
,
&
norebind
);
if
(
type
!=
0
||
option_bool
(
OPT_ORDER
)
||
!
daemon
->
last_server
)
/* Do this by steam now we're not in the select() loop */
last_server
=
daemon
->
servers
;
check_log_writer
(
NULL
);
else
last_server
=
daemon
->
last_server
;
if
(
m
==
0
)
if
(
!
flags
&&
last_server
)
{
{
struct
server
*
firstsendto
=
NULL
;
unsigned
int
flags
=
0
;
unsigned
int
crc
=
questions_crc
(
header
,
(
unsigned
int
)
size
,
daemon
->
namebuff
);
struct
all_addr
*
addrp
=
NULL
;
int
type
=
0
;
/* Loop round available servers until we succeed in connecting to one.
char
*
domain
=
NULL
;
Note that this code subtley ensures that consecutive queries on this connection
which can go to the same server, do so. */
while
(
1
)
{
if
(
!
firstsendto
)
firstsendto
=
last_server
;
else
{
if
(
!
(
last_server
=
last_server
->
next
))
last_server
=
daemon
->
servers
;
if
(
last_server
==
firstsendto
)
break
;
}
/* server for wrong domain */
if
(
option_bool
(
OPT_ADD_MAC
))
if
(
type
!=
(
last_server
->
flags
&
SERV_TYPE
)
||
size
=
add_mac
(
header
,
size
,
((
char
*
)
header
)
+
65536
,
&
peer_addr
);
(
type
==
SERV_HAS_DOMAIN
&&
!
hostname_isequal
(
domain
,
last_server
->
domain
)))
continue
;
if
(
gotname
)
flags
=
search_servers
(
now
,
&
addrp
,
gotname
,
daemon
->
namebuff
,
&
type
,
&
domain
,
&
norebind
);
if
(
last_server
->
tcpfd
==
-
1
)
if
(
type
!=
0
||
option_bool
(
OPT_ORDER
)
||
!
daemon
->
last_server
)
last_server
=
daemon
->
servers
;
else
last_server
=
daemon
->
last_server
;
if
(
!
flags
&&
last_server
)
{
struct
server
*
firstsendto
=
NULL
;
unsigned
int
crc
=
questions_crc
(
header
,
(
unsigned
int
)
size
,
daemon
->
namebuff
);
/* Loop round available servers until we succeed in connecting to one.
Note that this code subtley ensures that consecutive queries on this connection
which can go to the same server, do so. */
while
(
1
)
{
{
if
((
last_server
->
tcpfd
=
socket
(
last_server
->
addr
.
sa
.
sa_family
,
SOCK_STREAM
,
0
))
==
-
1
)
if
(
!
firstsendto
)
firstsendto
=
last_server
;
else
{
if
(
!
(
last_server
=
last_server
->
next
))
last_server
=
daemon
->
servers
;
if
(
last_server
==
firstsendto
)
break
;
}
/* server for wrong domain */
if
(
type
!=
(
last_server
->
flags
&
SERV_TYPE
)
||
(
type
==
SERV_HAS_DOMAIN
&&
!
hostname_isequal
(
domain
,
last_server
->
domain
)))
continue
;
continue
;
if
((
!
local_bind
(
last_server
->
tcpfd
,
&
last_server
->
source_addr
,
last_server
->
interface
,
1
)
||
if
(
last_server
->
tcpfd
==
-
1
)
connect
(
last_server
->
tcpfd
,
&
last_server
->
addr
.
sa
,
sa_len
(
&
last_server
->
addr
))
==
-
1
))
{
{
close
(
last_server
->
tcpfd
);
if
((
last_server
->
tcpfd
=
socket
(
last_server
->
addr
.
sa
.
sa_family
,
SOCK_STREAM
,
0
))
==
-
1
)
last_server
->
tcpfd
=
-
1
;
continue
;
continue
;
}
if
((
!
local_bind
(
last_server
->
tcpfd
,
&
last_server
->
source_addr
,
last_server
->
interface
,
1
)
||
connect
(
last_server
->
tcpfd
,
&
last_server
->
addr
.
sa
,
sa_len
(
&
last_server
->
addr
))
==
-
1
))
{
close
(
last_server
->
tcpfd
);
last_server
->
tcpfd
=
-
1
;
continue
;
}
#ifdef HAVE_CONNTRACK
#ifdef HAVE_CONNTRACK
/* Copy connection mark of incoming query to outgoing connection. */
/* Copy connection mark of incoming query to outgoing connection. */
if
(
option_bool
(
OPT_CONNTRACK
))
if
(
option_bool
(
OPT_CONNTRACK
))
{
{
unsigned
int
mark
;
unsigned
int
mark
;
struct
all_addr
local
;
struct
all_addr
local
;
#ifdef HAVE_IPV6
#ifdef HAVE_IPV6
if
(
local_addr
->
sa
.
sa_family
==
AF_INET6
)
if
(
local_addr
->
sa
.
sa_family
==
AF_INET6
)
local
.
addr
.
addr6
=
local_addr
->
in6
.
sin6_addr
;
local
.
addr
.
addr6
=
local_addr
->
in6
.
sin6_addr
;
else
else
#endif
#endif
local
.
addr
.
addr4
=
local_addr
->
in
.
sin_addr
;
local
.
addr
.
addr4
=
local_addr
->
in
.
sin_addr
;
if
(
get_incoming_mark
(
&
peer_addr
,
&
local
,
1
,
&
mark
))
if
(
get_incoming_mark
(
&
peer_addr
,
&
local
,
1
,
&
mark
))
setsockopt
(
last_server
->
tcpfd
,
SOL_SOCKET
,
SO_MARK
,
&
mark
,
sizeof
(
unsigned
int
));
setsockopt
(
last_server
->
tcpfd
,
SOL_SOCKET
,
SO_MARK
,
&
mark
,
sizeof
(
unsigned
int
));
}
}
#endif
#endif
}
}
c1
=
size
>>
8
;
c1
=
size
>>
8
;
c2
=
size
;
c2
=
size
;
if
(
!
read_write
(
last_server
->
tcpfd
,
&
c1
,
1
,
0
)
||
if
(
!
read_write
(
last_server
->
tcpfd
,
&
c1
,
1
,
0
)
||
!
read_write
(
last_server
->
tcpfd
,
&
c2
,
1
,
0
)
||
!
read_write
(
last_server
->
tcpfd
,
&
c2
,
1
,
0
)
||
!
read_write
(
last_server
->
tcpfd
,
packet
,
size
,
0
)
||
!
read_write
(
last_server
->
tcpfd
,
packet
,
size
,
0
)
||
!
read_write
(
last_server
->
tcpfd
,
&
c1
,
1
,
1
)
||
!
read_write
(
last_server
->
tcpfd
,
&
c1
,
1
,
1
)
||
!
read_write
(
last_server
->
tcpfd
,
&
c2
,
1
,
1
))
!
read_write
(
last_server
->
tcpfd
,
&
c2
,
1
,
1
))
{
{
close
(
last_server
->
tcpfd
);
close
(
last_server
->
tcpfd
);
last_server
->
tcpfd
=
-
1
;
last_server
->
tcpfd
=
-
1
;
continue
;
continue
;
}
}
m
=
(
c1
<<
8
)
|
c2
;
m
=
(
c1
<<
8
)
|
c2
;
if
(
!
read_write
(
last_server
->
tcpfd
,
packet
,
m
,
1
))
if
(
!
read_write
(
last_server
->
tcpfd
,
packet
,
m
,
1
))
return
packet
;
return
packet
;
if
(
!
gotname
)
if
(
!
gotname
)
strcpy
(
daemon
->
namebuff
,
"query"
);
strcpy
(
daemon
->
namebuff
,
"query"
);
if
(
last_server
->
addr
.
sa
.
sa_family
==
AF_INET
)
if
(
last_server
->
addr
.
sa
.
sa_family
==
AF_INET
)
log_query
(
F_SERVER
|
F_IPV4
|
F_FORWARD
,
daemon
->
namebuff
,
log_query
(
F_SERVER
|
F_IPV4
|
F_FORWARD
,
daemon
->
namebuff
,
(
struct
all_addr
*
)
&
last_server
->
addr
.
in
.
sin_addr
,
NULL
);
(
struct
all_addr
*
)
&
last_server
->
addr
.
in
.
sin_addr
,
NULL
);
#ifdef HAVE_IPV6
#ifdef HAVE_IPV6
else
else
log_query
(
F_SERVER
|
F_IPV6
|
F_FORWARD
,
daemon
->
namebuff
,
log_query
(
F_SERVER
|
F_IPV6
|
F_FORWARD
,
daemon
->
namebuff
,
(
struct
all_addr
*
)
&
last_server
->
addr
.
in6
.
sin6_addr
,
NULL
);
(
struct
all_addr
*
)
&
last_server
->
addr
.
in6
.
sin6_addr
,
NULL
);
#endif
#endif
/* There's no point in updating the cache, since this process will exit and
/* There's no point in updating the cache, since this process will exit and
lose the information after a few queries. We make this call for the alias and
lose the information after a few queries. We make this call for the alias and
bogus-nxdomain side-effects. */
bogus-nxdomain side-effects. */
/* If the crc of the question section doesn't match the crc we sent, then
/* If the crc of the question section doesn't match the crc we sent, then
someone might be attempting to insert bogus values into the cache by
someone might be attempting to insert bogus values into the cache by
sending replies containing questions and bogus answers. */
sending replies containing questions and bogus answers. */
if
(
crc
==
questions_crc
(
header
,
(
unsigned
int
)
m
,
daemon
->
namebuff
))
if
(
crc
==
questions_crc
(
header
,
(
unsigned
int
)
m
,
daemon
->
namebuff
))
m
=
process_reply
(
header
,
now
,
last_server
,
(
unsigned
int
)
m
,
m
=
process_reply
(
header
,
now
,
last_server
,
(
unsigned
int
)
m
,
option_bool
(
OPT_NO_REBIND
)
&&
!
norebind
,
checking_disabled
);
option_bool
(
OPT_NO_REBIND
)
&&
!
norebind
,
checking_disabled
);
break
;
break
;
}
}
}
/* In case of local answer or no connections made. */
if
(
m
==
0
)
m
=
setup_reply
(
header
,
(
unsigned
int
)
size
,
addrp
,
flags
,
daemon
->
local_ttl
);
}
}
/* In case of local answer or no connections made. */
if
(
m
==
0
)
m
=
setup_reply
(
header
,
(
unsigned
int
)
size
,
addrp
,
flags
,
daemon
->
local_ttl
);
}
}
check_log_writer
(
NULL
);
check_log_writer
(
NULL
);
c1
=
m
>>
8
;
c1
=
m
>>
8
;
...
...
src/network.c
View file @
36bec089
...
@@ -107,13 +107,24 @@ int indextoname(int fd, int index, char *name)
...
@@ -107,13 +107,24 @@ int indextoname(int fd, int index, char *name)
#endif
#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
;
struct
iname
*
tmp
;
int
ret
=
1
;
int
ret
=
1
;
/* Note: have to check all and not bail out early, so that we set the
/* Note: have to check all and not bail out early, so that we set the
"used" flags. */
"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
)
if
(
daemon
->
if_names
||
daemon
->
if_addrs
)
{
{
...
@@ -153,6 +164,7 @@ static int iface_allowed(struct irec **irecp, int if_index,
...
@@ -153,6 +164,7 @@ static int iface_allowed(struct irec **irecp, int if_index,
struct
ifreq
ifr
;
struct
ifreq
ifr
;
int
tftp_ok
=
!!
option_bool
(
OPT_TFTP
);
int
tftp_ok
=
!!
option_bool
(
OPT_TFTP
);
int
dhcp_ok
=
1
;
int
dhcp_ok
=
1
;
int
auth_dns
=
0
;
#ifdef HAVE_DHCP
#ifdef HAVE_DHCP
struct
iname
*
tmp
;
struct
iname
*
tmp
;
#endif
#endif
...
@@ -210,25 +222,31 @@ static int iface_allowed(struct irec **irecp, int if_index,
...
@@ -210,25 +222,31 @@ static int iface_allowed(struct irec **irecp, int if_index,
}
}
if
(
addr
->
sa
.
sa_family
==
AF_INET
&&
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
;
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
#ifdef HAVE_IPV6
if
(
addr
->
sa
.
sa_family
==
AF_INET6
&&
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
;
return
1
;
#endif
#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 */
/* add to list */
if
((
iface
=
whine_malloc
(
sizeof
(
struct
irec
))))
if
((
iface
=
whine_malloc
(
sizeof
(
struct
irec
))))
{
{
...
@@ -236,6 +254,7 @@ static int iface_allowed(struct irec **irecp, int if_index,
...
@@ -236,6 +254,7 @@ static int iface_allowed(struct irec **irecp, int if_index,
iface
->
netmask
=
netmask
;
iface
->
netmask
=
netmask
;
iface
->
tftp_ok
=
tftp_ok
;
iface
->
tftp_ok
=
tftp_ok
;
iface
->
dhcp_ok
=
dhcp_ok
;
iface
->
dhcp_ok
=
dhcp_ok
;
iface
->
dns_auth
=
auth_dns
;
iface
->
mtu
=
mtu
;
iface
->
mtu
=
mtu
;
iface
->
dad
=
dad
;
iface
->
dad
=
dad
;
iface
->
done
=
0
;
iface
->
done
=
0
;
...
...
src/option.c
View file @
36bec089
...
@@ -121,6 +121,10 @@ struct myoption {
...
@@ -121,6 +121,10 @@ struct myoption {
#define LOPT_RR 310
#define LOPT_RR 310
#define LOPT_CLVERBIND 311
#define LOPT_CLVERBIND 311
#define LOPT_MAXCTTL 312
#define LOPT_MAXCTTL 312
#define LOPT_AUTHZONE 313
#define LOPT_AUTHSERV 314
#define LOPT_AUTHTTL 315
#define LOPT_AUTHSOA 316
#ifdef HAVE_GETOPT_LONG
#ifdef HAVE_GETOPT_LONG
static
const
struct
option
opts
[]
=
static
const
struct
option
opts
[]
=
...
@@ -247,6 +251,10 @@ static const struct myoption opts[] =
...
@@ -247,6 +251,10 @@ static const struct myoption opts[] =
{
"dhcp-duid"
,
1
,
0
,
LOPT_DUID
},
{
"dhcp-duid"
,
1
,
0
,
LOPT_DUID
},
{
"host-record"
,
1
,
0
,
LOPT_HOST_REC
},
{
"host-record"
,
1
,
0
,
LOPT_HOST_REC
},
{
"bind-dynamic"
,
0
,
0
,
LOPT_CLVERBIND
},
{
"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
}
{
NULL
,
0
,
0
,
0
}
};
};
...
@@ -378,7 +386,11 @@ static struct {
...
@@ -378,7 +386,11 @@ static struct {
{
LOPT_DUID
,
ARG_ONE
,
"<enterprise>,<duid>"
,
gettext_noop
(
"Specify DUID_EN-type DHCPv6 server DUID"
),
NULL
},
{
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_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_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
,
"<NS>,<interface>"
,
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
}
{
0
,
0
,
NULL
,
NULL
,
NULL
}
};
};
...
@@ -1521,6 +1533,99 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
...
@@ -1521,6 +1533,99 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
break
;
break
;
}
}
case
LOPT_AUTHSERV
:
/* --auth-server */
if
(
!
(
comma
=
split
(
arg
)))
ret_err
(
gen_err
);
daemon
->
authserver
=
opt_string_alloc
(
arg
);
daemon
->
authinterface
=
opt_string_alloc
(
comma
);
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
))
{
if
((
prefixlen
&
0x07
)
!=
0
||
prefixlen
>
24
)
ret_err
(
_
(
"bad prefix"
));
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
)
{
char
*
cp
;
arg
=
comma
;
comma
=
split
(
arg
);
daemon
->
hostmaster
=
opt_string_alloc
(
arg
);
for
(
cp
=
daemon
->
hostmaster
;
*
cp
;
cp
++
)
if
(
*
cp
==
'@'
)
*
cp
=
'.'
;
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 */
case
's'
:
/* --domain */
if
(
strcmp
(
arg
,
"#"
)
==
0
)
if
(
strcmp
(
arg
,
"#"
)
==
0
)
set_option_bool
(
OPT_RESOLV_DOMAIN
);
set_option_bool
(
OPT_RESOLV_DOMAIN
);
...
@@ -1933,6 +2038,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
...
@@ -1933,6 +2038,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
case
LOPT_NEGTTL
:
/* --neg-ttl */
case
LOPT_NEGTTL
:
/* --neg-ttl */
case
LOPT_MAXTTL
:
/* --max-ttl */
case
LOPT_MAXTTL
:
/* --max-ttl */
case
LOPT_MAXCTTL
:
/* --max-cache-ttl */
case
LOPT_MAXCTTL
:
/* --max-cache-ttl */
case
LOPT_AUTHTTL
:
/* --auth-ttl */
{
{
int
ttl
;
int
ttl
;
if
(
!
atoi_check
(
arg
,
&
ttl
))
if
(
!
atoi_check
(
arg
,
&
ttl
))
...
@@ -1943,6 +2049,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
...
@@ -1943,6 +2049,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
daemon
->
max_ttl
=
(
unsigned
long
)
ttl
;
daemon
->
max_ttl
=
(
unsigned
long
)
ttl
;
else
if
(
option
==
LOPT_MAXCTTL
)
else
if
(
option
==
LOPT_MAXCTTL
)
daemon
->
max_cache_ttl
=
(
unsigned
long
)
ttl
;
daemon
->
max_cache_ttl
=
(
unsigned
long
)
ttl
;
else
if
(
option
==
LOPT_AUTHTTL
)
daemon
->
auth_ttl
=
(
unsigned
long
)
ttl
;
else
else
daemon
->
local_ttl
=
(
unsigned
long
)
ttl
;
daemon
->
local_ttl
=
(
unsigned
long
)
ttl
;
break
;
break
;
...
@@ -3613,6 +3721,10 @@ void read_opts(int argc, char **argv, char *compile_opts)
...
@@ -3613,6 +3721,10 @@ void read_opts(int argc, char **argv, char *compile_opts)
daemon
->
tftp_max
=
TFTP_MAX_CONNECTIONS
;
daemon
->
tftp_max
=
TFTP_MAX_CONNECTIONS
;
daemon
->
edns_pktsz
=
EDNS_PKTSZ
;
daemon
->
edns_pktsz
=
EDNS_PKTSZ
;
daemon
->
log_fac
=
-
1
;
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
(
"version.bind"
,
"dnsmasq-"
VERSION
);
add_txt
(
"authors.bind"
,
"Simon Kelley"
);
add_txt
(
"authors.bind"
,
"Simon Kelley"
);
add_txt
(
"copyright.bind"
,
COPYRIGHT
);
add_txt
(
"copyright.bind"
,
COPYRIGHT
);
...
@@ -3720,7 +3832,15 @@ void read_opts(int argc, char **argv, char *compile_opts)
...
@@ -3720,7 +3832,15 @@ void read_opts(int argc, char **argv, char *compile_opts)
tmp
->
addr
.
in6
.
sin6_port
=
htons
(
daemon
->
port
);
tmp
->
addr
.
in6
.
sin6_port
=
htons
(
daemon
->
port
);
#endif
/* IPv6 */
#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 */
/* only one of these need be specified: the other defaults to the host-name */
if
(
option_bool
(
OPT_LOCALMX
)
||
daemon
->
mxnames
||
daemon
->
mxtarget
)
if
(
option_bool
(
OPT_LOCALMX
)
||
daemon
->
mxnames
||
daemon
->
mxtarget
)
{
{
...
...
src/radv.c
View file @
36bec089
...
@@ -149,7 +149,7 @@ void icmp6_packet(void)
...
@@ -149,7 +149,7 @@ void icmp6_packet(void)
if
(
!
indextoname
(
daemon
->
icmp6fd
,
if_index
,
interface
))
if
(
!
indextoname
(
daemon
->
icmp6fd
,
if_index
,
interface
))
return
;
return
;
if
(
!
iface_check
(
AF_LOCAL
,
NULL
,
interface
))
if
(
!
iface_check
(
AF_LOCAL
,
NULL
,
interface
,
NULL
))
return
;
return
;
for
(
tmp
=
daemon
->
dhcp_except
;
tmp
;
tmp
=
tmp
->
next
)
for
(
tmp
=
daemon
->
dhcp_except
;
tmp
;
tmp
=
tmp
->
next
)
...
...
src/rfc1035.c
View file @
36bec089
...
@@ -16,10 +16,6 @@
...
@@ -16,10 +16,6 @@
#include "dnsmasq.h"
#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) \
#define CHECK_LEN(header, pp, plen, len) \
((size_t)((pp) - (unsigned char *)(header) + (len)) <= (plen))
((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
...
@@ -27,8 +23,8 @@ static int add_resource_record(struct dns_header *header, char *limit, int *trun
#define ADD_RDLEN(header, pp, plen, len) \
#define ADD_RDLEN(header, pp, plen, len) \
(!CHECK_LEN(header, pp, plen, len) ? 0 : (((pp) += (len)), 1))
(!CHECK_LEN(header, pp, plen, len) ? 0 : (((pp) += (len)), 1))
static
int
extract_name
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
**
pp
,
int
extract_name
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
**
pp
,
char
*
name
,
int
isExtract
,
int
extrabytes
)
char
*
name
,
int
isExtract
,
int
extrabytes
)
{
{
unsigned
char
*
cp
=
(
unsigned
char
*
)
name
,
*
p
=
*
pp
,
*
p1
=
NULL
;
unsigned
char
*
cp
=
(
unsigned
char
*
)
name
,
*
p
=
*
pp
,
*
p1
=
NULL
;
unsigned
int
j
,
l
,
hops
=
0
;
unsigned
int
j
,
l
,
hops
=
0
;
...
@@ -173,7 +169,7 @@ static int extract_name(struct dns_header *header, size_t plen, unsigned char **
...
@@ -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.) */
/* Max size of input string (for IPv6) is 75 chars.) */
#define MAXARPANAME 75
#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
;
int
j
;
char
name
[
MAXARPANAME
+
1
],
*
cp1
;
char
name
[
MAXARPANAME
+
1
],
*
cp1
;
...
@@ -333,7 +329,7 @@ static unsigned char *skip_name(unsigned char *ansp, struct dns_header *header,
...
@@ -333,7 +329,7 @@ static unsigned char *skip_name(unsigned char *ansp, struct dns_header *header,
return
ansp
;
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
;
int
q
;
unsigned
char
*
ansp
=
(
unsigned
char
*
)(
header
+
1
);
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,
...
@@ -1189,8 +1185,8 @@ int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
return
0
;
return
0
;
}
}
static
int
add_resource_record
(
struct
dns_header
*
header
,
char
*
limit
,
int
*
truncp
,
unsigned
int
nameoffset
,
unsigned
char
**
pp
,
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
long
ttl
,
unsigned
int
*
offset
,
unsigned
short
type
,
unsigned
short
class
,
char
*
format
,
...)
{
{
va_list
ap
;
va_list
ap
;
unsigned
char
*
sav
,
*
p
=
*
pp
;
unsigned
char
*
sav
,
*
p
=
*
pp
;
...
@@ -1201,8 +1197,19 @@ static int add_resource_record(struct dns_header *header, char *limit, int *trun
...
@@ -1201,8 +1197,19 @@ static int add_resource_record(struct dns_header *header, char *limit, int *trun
if
(
truncp
&&
*
truncp
)
if
(
truncp
&&
*
truncp
)
return
0
;
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
(
type
,
p
);
PUTSHORT
(
class
,
p
);
PUTSHORT
(
class
,
p
);
PUTLONG
(
ttl
,
p
);
/* TTL */
PUTLONG
(
ttl
,
p
);
/* TTL */
...
@@ -1210,8 +1217,6 @@ static int add_resource_record(struct dns_header *header, char *limit, int *trun
...
@@ -1210,8 +1217,6 @@ static int add_resource_record(struct dns_header *header, char *limit, int *trun
sav
=
p
;
/* Save pointer to RDLength field */
sav
=
p
;
/* Save pointer to RDLength field */
PUTSHORT
(
0
,
p
);
/* Placeholder RDLength */
PUTSHORT
(
0
,
p
);
/* Placeholder RDLength */
va_start
(
ap
,
format
);
/* make ap point to 1st unamed argument */
for
(;
*
format
;
format
++
)
for
(;
*
format
;
format
++
)
switch
(
*
format
)
switch
(
*
format
)
{
{
...
@@ -1857,7 +1862,3 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
...
@@ -1857,7 +1862,3 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
return
ansp
-
(
unsigned
char
*
)
header
;
return
ansp
-
(
unsigned
char
*
)
header
;
}
}
src/tftp.c
View file @
36bec089
...
@@ -193,12 +193,12 @@ void tftp_request(struct listener *listen, time_t now)
...
@@ -193,12 +193,12 @@ void tftp_request(struct listener *listen, time_t now)
#ifdef HAVE_IPV6
#ifdef HAVE_IPV6
if
(
listen
->
family
==
AF_INET6
)
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
;
return
;
}
}
else
else
#endif
#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
;
return
;
#ifdef HAVE_DHCP
#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