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
06e54b82
Commit
06e54b82
authored
Nov 14, 2013
by
Simon Kelley
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into dnssec
parents
5a4120db
32b4e4cb
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
353 additions
and
188 deletions
+353
-188
CHANGELOG
CHANGELOG
+31
-0
man/dnsmasq.8
man/dnsmasq.8
+27
-18
src/auth.c
src/auth.c
+31
-50
src/bpf.c
src/bpf.c
+2
-1
src/cache.c
src/cache.c
+1
-1
src/config.h
src/config.h
+4
-1
src/dhcp6.c
src/dhcp6.c
+36
-20
src/dnsmasq.c
src/dnsmasq.c
+3
-0
src/dnsmasq.h
src/dnsmasq.h
+24
-19
src/lease.c
src/lease.c
+8
-2
src/network.c
src/network.c
+95
-25
src/option.c
src/option.c
+38
-20
src/rfc1035.c
src/rfc1035.c
+20
-24
src/rfc3315.c
src/rfc3315.c
+2
-1
src/util.c
src/util.c
+31
-6
No files found.
CHANGELOG
View file @
06e54b82
version 2.68
Use random addresses for DHCPv6 temporary address
allocations, instead of algorithmically determined stable
addresses.
Fix bug which meant that the DHCPv6 DUID was not available
in DHCP script runs during the lifetime of the dnsmasq
process which created the DUID de-novo. Once the DUID was
created and stored in the lease file and dnsmasq
restarted, this bug disappeared.
Fix bug introduced in 2.67 which could result in erroneous
NXDOMAIN returns to CNAME queries.
Fix build failures on MacOS X and openBSD.
Allow subnet specifications in --auth-zone to be interface
names as well as address literals. This makes it possible
to configure authoritative DNS when local address ranges
are dynamic and works much better than the previous
work-around which exempted contructed DHCP ranges from the
IP address filtering. As a consequence, that work-around
is removed. Under certain circumstances, this change wil
break existing configuration: if you're relying on the
contructed-range exception, you need to change --auth-zone
to specify the same interface as is used to construct your
DHCP ranges, probably with a trailing "/6" like this:
--auth-zone=example.com,eth0/6 to limit the addresses to
IPv6 addresses of eth0.
version 2.67
Fix crash if upstream server returns SERVFAIL when
--conntrack in use. Thanks to Giacomo Tazzari for finding
...
...
man/dnsmasq.8
View file @
06e54b82
...
...
@@ -589,10 +589,19 @@ needed for a client to do validation itself.
.B --auth-zone=<domain>[,<subnet>[/<prefix length>][,<subnet>[/<prefix length>].....]]
Define a DNS zone for which dnsmasq acts as authoritative server. Locally defined DNS records which are in the domain
will be served. A and AAAA records must be in one of the
specified subnets, or in a subnet corresponding to a constructed DHCP
range. (This can be overridden with
.B constructor-noauth:
) The subnet(s) are also used to define in-addr.arpa and
specified subnets. As alternative to directly specifying the subnets, it's possible to
give the name of an interface, in which case the subnets implied by
that interface's configured addresses and netmask/prefix-length are
used; this is useful when using constructed DHCP ranges as the actual
address is dynamic and not known when configuring dnsmasq. The
interface addresses may be confined to only IPv6 addresses using
<interface>/6 or to only IPv4 using <interface>/4. This is useful when
an interface has dynamically determined global IPv6 addresses which should
appear in the zone, but RFC1918 IPv4 addresses which should not.
Interface-name and address-literal subnet specifications may be used
freely in the same --auth-zone declaration.
The subnet(s) are also used to define in-addr.arpa and
ipv6.arpa domains which are served for reverse-DNS queries. If not
specified, the prefix length defaults to 24 for IPv4 and 64 for IPv6.
For IPv4 subnets, the prefix length should be have the value 8, 16 or 24
...
...
@@ -680,12 +689,6 @@ then the address can be simply ::
.B --dhcp-range=::,constructor:eth0
There is a variant of the constructor: syntax using the keyword
.B constructor-noauth.
See
.B --auth-zone
for an explanation of this.
The optional
.B set:<tag>
sets an alphanumeric label which marks this network so that
...
...
@@ -1899,9 +1902,13 @@ Something like:
.nf
.B auth-server=our.zone.com,eth0
.B interface-name=our.zone.com,eth0
.B auth-zone=our.zone.com,1.2.3.0/24
.B auth-zone=our.zone.com,1.2.3.0/24
,eth0
.fi
(The "eth0" argument in auth-zone adds the subnet containing eth0's
dynamic address to the zone, so that the interface-name returns the
address in outside queries.)
Our final configuration builds on that above, but also adds a
secondary DNS server. This is another DNS server which learns the DNS data
for the zone by doing zones transfer, and acts as a backup should
...
...
@@ -1959,18 +1966,20 @@ IPv4 and IPv6 addresses from /etc/hosts (and
.B --addn-hosts
) and
.B --host-record
and
.B --interface-name
provided the address falls into one of the subnets specified in the
.B --auth-zone.
.PP
Addresses specified by
.B --interface-name.
In this case, the address is not contrained to a subnet from
.B --auth-zone.
.PP
Addresses of DHCP leases, provided the address falls into one of the subnets specified in the
.B --auth-zone.
(If contructed DHCP ranges are is use, which depend on the address dynamically
assigned to an interface, then the form of
.B --auth-zone
OR a constructed DHCP range. In the default mode, where a DHCP lease
which defines subnets by the dynamic address of an interface should
be used to ensure this condition is met.)
.PP
In the default mode, where a DHCP lease
has an unqualified name, and possibly a qualified name constructed
using
.B --domain
...
...
src/auth.c
View file @
06e54b82
...
...
@@ -18,27 +18,26 @@
#ifdef HAVE_AUTH
static
struct
subne
t
*
filter_zone
(
struct
auth_zone
*
zone
,
int
flag
,
struct
all_addr
*
addr_u
)
static
struct
addrlis
t
*
filter_zone
(
struct
auth_zone
*
zone
,
int
flag
,
struct
all_addr
*
addr_u
)
{
struct
subne
t
*
subnet
;
struct
addrlis
t
*
subnet
;
for
(
subnet
=
zone
->
subnet
;
subnet
;
subnet
=
subnet
->
next
)
{
if
(
subnet
->
is6
&&
(
flag
&
F_IPV4
))
continue
;
if
(
!
subnet
->
is6
)
if
(
!
(
subnet
->
flags
&
ADDRLIST_IPV6
))
{
struct
in_addr
addr
=
addr_u
->
addr
.
addr4
;
struct
in_addr
mask
;
struct
in_addr
netmask
,
addr
=
addr_u
->
addr
.
addr4
;
if
(
!
(
flag
&
F_IPV4
))
continue
;
mask
.
s_addr
=
htonl
(
~
((
1
<<
(
32
-
subnet
->
prefixlen
))
-
1
));
net
mask
.
s_addr
=
htonl
(
~
((
1
<<
(
32
-
subnet
->
prefixlen
))
-
1
));
if
(
is_same_net
(
addr
,
subnet
->
addr
4
,
mask
))
if
(
is_same_net
(
addr
,
subnet
->
addr
.
addr
.
addr4
,
net
mask
))
return
subnet
;
}
#ifdef HAVE_IPV6
else
if
(
is_same_net6
(
&
(
addr_u
->
addr
.
addr6
),
&
subnet
->
addr6
,
subnet
->
prefixlen
))
else
if
(
is_same_net6
(
&
(
addr_u
->
addr
.
addr6
),
&
subnet
->
addr
.
addr
.
addr
6
,
subnet
->
prefixlen
))
return
subnet
;
#endif
...
...
@@ -46,22 +45,6 @@ static struct subnet *filter_zone(struct auth_zone *zone, int flag, struct all_a
return
NULL
;
}
static
int
filter_constructed_dhcp
(
struct
auth_zone
*
zone
,
int
flag
,
struct
all_addr
*
addr_u
)
{
#ifdef HAVE_DHCP6
struct
dhcp_context
*
context
;
if
(
flag
&
F_IPV6
)
for
(
context
=
daemon
->
dhcp6
;
context
;
context
=
context
->
next
)
if
((
context
->
flags
&
CONTEXT_CONSTRUCTED
)
&&
!
(
context
->
flags
&
CONTEXT_NOAUTH
)
&&
is_same_net6
(
&
(
addr_u
->
addr
.
addr6
),
&
context
->
start6
,
context
->
prefix
))
return
1
;
#endif
return
filter_zone
(
zone
,
flag
,
addr_u
)
!=
NULL
;
}
int
in_zone
(
struct
auth_zone
*
zone
,
char
*
name
,
char
**
cut
)
{
size_t
namelen
=
strlen
(
name
);
...
...
@@ -99,7 +82,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
struct
crec
*
crecp
;
int
auth
=
!
local_query
,
trunc
=
0
,
nxdomain
=
1
,
soa
=
0
,
ns
=
0
,
axfr
=
0
;
struct
auth_zone
*
zone
=
NULL
;
struct
subne
t
*
subnet
=
NULL
;
struct
addrlis
t
*
subnet
=
NULL
;
char
*
cut
;
struct
mx_srv_record
*
rec
,
*
move
,
**
up
;
struct
txt_record
*
txt
;
...
...
@@ -164,8 +147,8 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
{
struct
addrlist
*
addrlist
;
for
(
addrlist
=
intr
->
addr
4
;
addrlist
;
addrlist
=
addrlist
->
next
)
if
(
addr
.
addr
.
addr4
.
s_addr
==
addrlist
->
addr
.
addr
.
addr4
.
s_addr
)
for
(
addrlist
=
intr
->
addr
;
addrlist
;
addrlist
=
addrlist
->
next
)
if
(
!
(
addrlist
->
flags
&
ADDRLIST_IPV6
)
&&
addr
.
addr
.
addr4
.
s_addr
==
addrlist
->
addr
.
addr
.
addr4
.
s_addr
)
break
;
if
(
addrlist
)
...
...
@@ -180,8 +163,8 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
{
struct
addrlist
*
addrlist
;
for
(
addrlist
=
intr
->
addr
6
;
addrlist
;
addrlist
=
addrlist
->
next
)
if
(
IN6_ARE_ADDR_EQUAL
(
&
addr
.
addr
.
addr6
,
&
addrlist
->
addr
.
addr
.
addr6
))
for
(
addrlist
=
intr
->
addr
;
addrlist
;
addrlist
=
addrlist
->
next
)
if
(
(
addrlist
->
flags
&
ADDRLIST_IPV6
)
&&
IN6_ARE_ADDR_EQUAL
(
&
addr
.
addr
.
addr6
,
&
addrlist
->
addr
.
addr
.
addr6
))
break
;
if
(
addrlist
)
...
...
@@ -362,16 +345,12 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
{
struct
addrlist
*
addrlist
;
addrlist
=
intr
->
addr4
;
#ifdef HAVE_IPV6
if
(
qtype
==
T_AAAA
)
addrlist
=
intr
->
addr6
;
#endif
nxdomain
=
0
;
if
(
flag
)
for
(;
addrlist
;
addrlist
=
addrlist
->
next
)
if
(
local_query
||
filter_constructed_dhcp
(
zone
,
flag
,
&
addrlist
->
addr
))
for
(
addrlist
=
intr
->
addr
;
addrlist
;
addrlist
=
addrlist
->
next
)
if
(((
addrlist
->
flags
&
ADDRLIST_IPV6
)
?
T_AAAA
:
T_A
)
==
qtype
&&
(
local_query
||
filter_zone
(
zone
,
flag
,
&
addrlist
->
addr
)))
{
found
=
1
;
log_query
(
F_FORWARD
|
F_CONFIG
|
flag
,
name
,
&
addrlist
->
addr
,
NULL
);
...
...
@@ -468,7 +447,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
{
nxdomain
=
0
;
if
((
crecp
->
flags
&
flag
)
&&
(
local_query
||
filter_
constructed_dhcp
(
zone
,
flag
,
&
(
crecp
->
addr
.
addr
))))
(
local_query
||
filter_
zone
(
zone
,
flag
,
&
(
crecp
->
addr
.
addr
))))
{
*
cut
=
'.'
;
/* restore domain part */
log_query
(
crecp
->
flags
,
name
,
&
crecp
->
addr
.
addr
,
record_source
(
crecp
->
uid
));
...
...
@@ -491,7 +470,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
do
{
nxdomain
=
0
;
if
((
crecp
->
flags
&
flag
)
&&
(
local_query
||
filter_
constructed_dhcp
(
zone
,
flag
,
&
(
crecp
->
addr
.
addr
))))
if
((
crecp
->
flags
&
flag
)
&&
(
local_query
||
filter_
zone
(
zone
,
flag
,
&
(
crecp
->
addr
.
addr
))))
{
log_query
(
crecp
->
flags
,
name
,
&
crecp
->
addr
.
addr
,
record_source
(
crecp
->
uid
));
found
=
1
;
...
...
@@ -522,9 +501,9 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
authname
=
name
;
if
(
!
subnet
->
is6
)
if
(
!
(
subnet
->
flags
&
ADDRLIST_IPV6
)
)
{
in_addr_t
a
=
ntohl
(
subnet
->
addr4
.
s_addr
)
>>
8
;
in_addr_t
a
=
ntohl
(
subnet
->
addr
.
addr
.
addr
4
.
s_addr
)
>>
8
;
char
*
p
=
name
;
if
(
subnet
->
prefixlen
>=
24
)
...
...
@@ -544,7 +523,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
for
(
i
=
subnet
->
prefixlen
-
1
;
i
>=
0
;
i
-=
4
)
{
int
dig
=
((
unsigned
char
*
)
&
subnet
->
addr6
)[
i
>>
3
];
int
dig
=
((
unsigned
char
*
)
&
subnet
->
addr
.
addr
.
addr
6
)[
i
>>
3
];
p
+=
sprintf
(
p
,
"%.1x."
,
(
i
>>
2
)
&
1
?
dig
&
15
:
dig
>>
4
);
}
p
+=
sprintf
(
p
,
"ip6.arpa"
);
...
...
@@ -680,15 +659,17 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
if
(
cut
)
*
cut
=
0
;
for
(
addrlist
=
intr
->
addr4
;
addrlist
;
addrlist
=
addrlist
->
next
)
if
((
local_query
||
filter_constructed_dhcp
(
zone
,
F_IPV4
,
&
addrlist
->
addr
))
&&
for
(
addrlist
=
intr
->
addr
;
addrlist
;
addrlist
=
addrlist
->
next
)
if
(
!
(
subnet
->
flags
&
ADDRLIST_IPV6
)
&&
(
local_query
||
filter_zone
(
zone
,
F_IPV4
,
&
addrlist
->
addr
))
&&
add_resource_record
(
header
,
limit
,
&
trunc
,
-
axfroffset
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
T_A
,
C_IN
,
"4"
,
cut
?
intr
->
name
:
NULL
,
&
addrlist
->
addr
))
anscount
++
;
#ifdef HAVE_IPV6
for
(
addrlist
=
intr
->
addr6
;
addrlist
;
addrlist
=
addrlist
->
next
)
if
((
local_query
||
filter_constructed_dhcp
(
zone
,
F_IPV6
,
&
addrlist
->
addr
))
&&
for
(
addrlist
=
intr
->
addr
;
addrlist
;
addrlist
=
addrlist
->
next
)
if
((
subnet
->
flags
&
ADDRLIST_IPV6
)
&&
(
local_query
||
filter_zone
(
zone
,
F_IPV6
,
&
addrlist
->
addr
))
&&
add_resource_record
(
header
,
limit
,
&
trunc
,
-
axfroffset
,
&
ansp
,
daemon
->
auth_ttl
,
NULL
,
T_AAAA
,
C_IN
,
"6"
,
cut
?
intr
->
name
:
NULL
,
&
addrlist
->
addr
))
anscount
++
;
...
...
@@ -729,7 +710,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
{
char
*
cache_name
=
cache_get_name
(
crecp
);
if
(
!
strchr
(
cache_name
,
'.'
)
&&
(
local_query
||
filter_
constructed_dhcp
(
zone
,
(
crecp
->
flags
&
(
F_IPV6
|
F_IPV4
)),
&
(
crecp
->
addr
.
addr
))))
(
local_query
||
filter_
zone
(
zone
,
(
crecp
->
flags
&
(
F_IPV6
|
F_IPV4
)),
&
(
crecp
->
addr
.
addr
))))
{
qtype
=
T_A
;
#ifdef HAVE_IPV6
...
...
@@ -747,7 +728,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
{
strcpy
(
name
,
cache_get_name
(
crecp
));
if
(
in_zone
(
zone
,
name
,
&
cut
)
&&
(
local_query
||
filter_
constructed_dhcp
(
zone
,
(
crecp
->
flags
&
(
F_IPV6
|
F_IPV4
)),
&
(
crecp
->
addr
.
addr
))))
(
local_query
||
filter_
zone
(
zone
,
(
crecp
->
flags
&
(
F_IPV6
|
F_IPV4
)),
&
(
crecp
->
addr
.
addr
))))
{
qtype
=
T_A
;
#ifdef HAVE_IPV6
...
...
src/bpf.c
View file @
06e54b82
...
...
@@ -29,6 +29,7 @@
# include <net/if_var.h>
#endif
#include <netinet/in_var.h>
#include <netinet6/in6_var.h>
#ifndef SA_SIZE
#define SA_SIZE(sa) \
...
...
@@ -145,7 +146,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
int
i
,
j
,
prefix
=
0
;
u32
valid
=
0xffffffff
,
preferred
=
0xffffffff
;
int
flags
=
0
;
#if
def HAVE_BSD_NETWORK
#if
defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
struct
in6_ifreq
ifr6
;
memset
(
&
ifr6
,
0
,
sizeof
(
ifr6
));
...
...
src/cache.c
View file @
06e54b82
...
...
@@ -330,7 +330,7 @@ static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsign
((
flags
&
crecp
->
flags
&
F_TYPE
)
||
((
crecp
->
flags
|
flags
)
&
F_CNAME
))
&&
hostname_isequal
(
cache_get_name
(
crecp
),
name
))
{
if
(
crecp
->
flags
&
(
F_HOSTS
|
F_DHCP
))
if
(
crecp
->
flags
&
(
F_HOSTS
|
F_DHCP
|
F_CONFIG
))
return
0
;
*
up
=
crecp
->
hash_next
;
cache_unlink
(
crecp
);
...
...
src/config.h
View file @
06e54b82
...
...
@@ -255,7 +255,10 @@ HAVE_SOCKADDR_SA_LEN
#define HAVE_SOCKADDR_SA_LEN
/* Define before sys/socket.h is included so we get socklen_t */
#define _BSD_SOCKLEN_T_
/* Select the RFC_3542 version of the IPv6 socket API.
Define before netinet6/in6.h is included. */
#define __APPLE_USE_RFC_3542
#elif defined(__NetBSD__)
#define HAVE_BSD_NETWORK
#define HAVE_GETOPT_LONG
...
...
src/dhcp6.c
View file @
06e54b82
...
...
@@ -394,7 +394,7 @@ struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct
return
NULL
;
}
struct
dhcp_context
*
address6_allocate
(
struct
dhcp_context
*
context
,
unsigned
char
*
clid
,
int
clid_len
,
struct
dhcp_context
*
address6_allocate
(
struct
dhcp_context
*
context
,
unsigned
char
*
clid
,
int
clid_len
,
int
temp_addr
,
int
iaid
,
int
serial
,
struct
dhcp_netid
*
netids
,
int
plain_range
,
struct
in6_addr
*
ans
)
{
/* Find a free address: exclude anything in use and anything allocated to
...
...
@@ -411,9 +411,13 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned c
u64
j
;
/* hash hwaddr: use the SDBM hashing algorithm. This works
for MAC addresses, let's see how it manages with client-ids! */
for
(
j
=
iaid
,
i
=
0
;
i
<
clid_len
;
i
++
)
j
+=
clid
[
i
]
+
(
j
<<
6
)
+
(
j
<<
16
)
-
j
;
for MAC addresses, let's see how it manages with client-ids!
For temporary addresses, we generate a new random one each time. */
if
(
temp_addr
)
j
=
rand64
();
else
for
(
j
=
iaid
,
i
=
0
;
i
<
clid_len
;
i
++
)
j
+=
clid
[
i
]
+
(
j
<<
6
)
+
(
j
<<
16
)
-
j
;
for
(
pass
=
0
;
pass
<=
plain_range
?
1
:
0
;
pass
++
)
for
(
c
=
context
;
c
;
c
=
c
->
current
)
...
...
@@ -423,7 +427,7 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned c
continue
;
else
{
if
(
option_bool
(
OPT_CONSEC_ADDR
))
if
(
!
temp_addr
&&
option_bool
(
OPT_CONSEC_ADDR
))
/* seed is largest extant lease addr in this context */
start
=
lease_find_max_addr6
(
c
)
+
serial
;
else
...
...
@@ -523,6 +527,8 @@ int config_valid(struct dhcp_config *config, struct dhcp_context *context, struc
void
make_duid
(
time_t
now
)
{
(
void
)
now
;
if
(
daemon
->
duid_config
)
{
unsigned
char
*
p
;
...
...
@@ -535,8 +541,14 @@ void make_duid(time_t now)
}
else
{
time_t
newnow
=
0
;
/* If we have no persistent lease database, or a non-stable RTC, use DUID_LL (newnow == 0) */
#ifndef HAVE_BROKEN_RTC
/* rebase epoch to 1/1/2000 */
time_t
newnow
=
now
-
946684800
;
if
(
!
option_bool
(
OPT_LEASE_RO
)
||
daemon
->
lease_change_command
)
newnow
=
now
-
946684800
;
#endif
iface_enumerate
(
AF_LOCAL
,
&
newnow
,
make_duid1
);
...
...
@@ -555,23 +567,27 @@ static int make_duid1(int index, unsigned int type, char *mac, size_t maclen, vo
unsigned
char
*
p
;
(
void
)
index
;
(
void
)
parm
;
time_t
newnow
=
*
((
time_t
*
)
parm
);
if
(
type
>=
256
)
return
1
;
#ifdef HAVE_BROKEN_RTC
daemon
->
duid
=
p
=
safe_malloc
(
maclen
+
4
);
daemon
->
duid_len
=
maclen
+
4
;
PUTSHORT
(
3
,
p
);
/* DUID_LL */
PUTSHORT
(
type
,
p
);
/* address type */
#else
daemon
->
duid
=
p
=
safe_malloc
(
maclen
+
8
);
daemon
->
duid_len
=
maclen
+
8
;
PUTSHORT
(
1
,
p
);
/* DUID_LLT */
PUTSHORT
(
type
,
p
);
/* address type */
PUTLONG
(
*
((
time_t
*
)
parm
),
p
);
/* time */
#endif
if
(
newnow
==
0
)
{
daemon
->
duid
=
p
=
safe_malloc
(
maclen
+
4
);
daemon
->
duid_len
=
maclen
+
4
;
PUTSHORT
(
3
,
p
);
/* DUID_LL */
PUTSHORT
(
type
,
p
);
/* address type */
}
else
{
daemon
->
duid
=
p
=
safe_malloc
(
maclen
+
8
);
daemon
->
duid_len
=
maclen
+
8
;
PUTSHORT
(
1
,
p
);
/* DUID_LLT */
PUTSHORT
(
type
,
p
);
/* address type */
PUTLONG
(
*
((
time_t
*
)
parm
),
p
);
/* time */
}
memcpy
(
p
,
mac
,
maclen
);
return
0
;
...
...
src/dnsmasq.c
View file @
06e54b82
...
...
@@ -274,6 +274,9 @@ int main (int argc, char **argv)
/* after enumerate_interfaces() */
if
(
daemon
->
doing_dhcp6
||
daemon
->
relay6
||
daemon
->
doing_ra
)
join_multicast
(
1
);
/* After netlink_init() and before create_helper() */
lease_make_duid
(
now
);
#endif
if
(
daemon
->
port
!=
0
)
...
...
src/dnsmasq.h
View file @
06e54b82
...
...
@@ -284,18 +284,28 @@ struct ptr_record {
struct
cname
{
char
*
alias
,
*
target
;
struct
cname
*
next
;
};
#define ADDRLIST_LITERAL 1
#define ADDRLIST_IPV6 2
struct
addrlist
{
struct
all_addr
addr
;
int
flags
,
prefixlen
;
struct
addrlist
*
next
;
};
#define AUTH6 1
#define AUTH4 2
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_name_list
{
char
*
name
;
int
flags
;
struct
auth_name_list
*
next
;
}
*
interface_names
;
struct
addrlist
*
subnet
;
struct
auth_zone
*
next
;
};
...
...
@@ -315,13 +325,7 @@ struct host_record {
struct
interface_name
{
char
*
name
;
/* domain name */
char
*
intr
;
/* interface name */
struct
addrlist
{
struct
all_addr
addr
;
struct
addrlist
*
next
;
}
*
addr4
;
#ifdef HAVE_IPV6
struct
addrlist
*
addr6
;
#endif
struct
addrlist
*
addr
;
struct
interface_name
*
next
;
};
...
...
@@ -752,9 +756,8 @@ struct dhcp_context {
#define CONTEXT_RA (1u<<13)
#define CONTEXT_CONF_USED (1u<<14)
#define CONTEXT_USED (1u<<15)
#define CONTEXT_NOAUTH (1u<<16)
#define CONTEXT_OLD (1u<<17)
#define CONTEXT_V6 (1u<<18)
#define CONTEXT_OLD (1u<<16)
#define CONTEXT_V6 (1u<<17)
struct
ping_result
{
...
...
@@ -1012,6 +1015,7 @@ int dnssec_validate(struct dns_header *header, size_t plen);
/* util.c */
void
rand_init
(
void
);
unsigned
short
rand16
(
void
);
u64
rand64
(
void
);
int
legal_hostname
(
char
*
c
);
char
*
canonicalise
(
char
*
s
,
int
*
nomem
);
unsigned
char
*
do_rfc1035_name
(
unsigned
char
*
p
,
char
*
sval
);
...
...
@@ -1132,6 +1136,7 @@ u64 lease_find_max_addr6(struct dhcp_context *context);
void
lease_ping_reply
(
struct
in6_addr
*
sender
,
unsigned
char
*
packet
,
char
*
interface
);
void
lease_update_slaac
(
time_t
now
);
void
lease_set_iaid
(
struct
dhcp_lease
*
lease
,
int
iaid
);
void
lease_make_duid
(
time_t
now
);
#endif
void
lease_set_hwaddr
(
struct
dhcp_lease
*
lease
,
unsigned
char
*
hwaddr
,
unsigned
char
*
clid
,
int
hw_len
,
int
hw_type
,
int
clid_len
,
time_t
now
,
int
force
);
...
...
@@ -1232,7 +1237,7 @@ int get_incoming_mark(union mysockaddr *peer_addr, struct all_addr *local_addr,
#ifdef HAVE_DHCP6
void
dhcp6_init
(
void
);
void
dhcp6_packet
(
time_t
now
);
struct
dhcp_context
*
address6_allocate
(
struct
dhcp_context
*
context
,
unsigned
char
*
clid
,
int
clid_len
,
struct
dhcp_context
*
address6_allocate
(
struct
dhcp_context
*
context
,
unsigned
char
*
clid
,
int
clid_len
,
int
temp_addr
,
int
iaid
,
int
serial
,
struct
dhcp_netid
*
netids
,
int
plain_range
,
struct
in6_addr
*
ans
);
int
config_valid
(
struct
dhcp_config
*
config
,
struct
dhcp_context
*
context
,
struct
in6_addr
*
addr
);
struct
dhcp_context
*
address6_available
(
struct
dhcp_context
*
context
,
...
...
src/lease.c
View file @
06e54b82
...
...
@@ -417,15 +417,21 @@ void lease_find_interfaces(time_t now)
iface_enumerate
(
AF_INET
,
&
now
,
find_interface_v4
);
#ifdef HAVE_DHCP6
iface_enumerate
(
AF_INET6
,
&
now
,
find_interface_v6
);
#endif
}
#ifdef HAVE_DHCP6
void
lease_make_duid
(
time_t
now
)
{
/* If we're not doing DHCPv6, and there are not v6 leases, don't add the DUID to the database */
if
(
!
daemon
->
duid
&&
daemon
->
dhcp6
)
if
(
!
daemon
->
duid
&&
daemon
->
d
oing_d
hcp6
)
{
file_dirty
=
1
;
make_duid
(
now
);
}
#endif
}
#endif
...
...
src/network.c
View file @
06e54b82
...
...
@@ -239,7 +239,7 @@ struct iface_param {
};
static
int
iface_allowed
(
struct
iface_param
*
param
,
int
if_index
,
char
*
label
,
union
mysockaddr
*
addr
,
struct
in_addr
netmask
,
int
dad
)
union
mysockaddr
*
addr
,
struct
in_addr
netmask
,
int
prefixlen
,
int
dad
)
{
struct
irec
*
iface
;
int
mtu
=
0
,
loopback
;
...
...
@@ -267,15 +267,67 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
label
=
ifr
.
ifr_name
;
/* Update addresses from interface_names. These are a set independent
of the set we're listening on. */
#ifdef HAVE_IPV6
if
(
addr
->
sa
.
sa_family
!=
AF_INET6
||
!
IN6_IS_ADDR_LINKLOCAL
(
&
addr
->
in6
.
sin6_addr
))
#endif
{
struct
interface_name
*
int_name
;
struct
addrlist
*
al
;
#ifdef HAVE_AUTH
struct
auth_zone
*
zone
;
struct
auth_name_list
*
name
;
/* Find subnets in auth_zones */
for
(
zone
=
daemon
->
auth_zones
;
zone
;
zone
=
zone
->
next
)
for
(
name
=
zone
->
interface_names
;
name
;
name
=
name
->
next
)
if
(
wildcard_match
(
name
->
name
,
label
))
{
if
(
addr
->
sa
.
sa_family
==
AF_INET
&&
(
name
->
flags
&
AUTH4
))
{
if
(
param
->
spare
)
{
al
=
param
->
spare
;
param
->
spare
=
al
->
next
;
}
else
al
=
whine_malloc
(
sizeof
(
struct
addrlist
));
if
(
al
)
{
al
->
next
=
zone
->
subnet
;
zone
->
subnet
=
al
;
al
->
prefixlen
=
prefixlen
;
al
->
addr
.
addr
.
addr4
=
addr
->
in
.
sin_addr
;
al
->
flags
=
0
;
}
}
#ifdef HAVE_IPV6
if
(
addr
->
sa
.
sa_family
==
AF_INET6
&&
(
name
->
flags
&
AUTH6
))
{
if
(
param
->
spare
)
{
al
=
param
->
spare
;
param
->
spare
=
al
->
next
;
}
else
al
=
whine_malloc
(
sizeof
(
struct
addrlist
));
if
(
al
)
{
al
->
next
=
zone
->
subnet
;
zone
->
subnet
=
al
;
al
->
prefixlen
=
prefixlen
;
al
->
addr
.
addr
.
addr6
=
addr
->
in6
.
sin6_addr
;
al
->
flags
=
ADDRLIST_IPV6
;
}
}
#endif
}
#endif
/* Update addresses from interface_names. These are a set independent
of the set we're listening on. */
for
(
int_name
=
daemon
->
int_names
;
int_name
;
int_name
=
int_name
->
next
)
if
(
strncmp
(
label
,
int_name
->
intr
,
IF_NAMESIZE
)
==
0
)
{
...
...
@@ -289,18 +341,19 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
if
(
al
)
{
al
->
next
=
int_name
->
addr
;
int_name
->
addr
=
al
;
if
(
addr
->
sa
.
sa_family
==
AF_INET
)
{
al
->
addr
.
addr
.
addr4
=
addr
->
in
.
sin_addr
;
al
->
next
=
int_name
->
addr4
;
int_name
->
addr4
=
al
;
al
->
flags
=
0
;
}
#ifdef HAVE_IPV6
else
{
al
->
addr
.
addr
.
addr6
=
addr
->
in6
.
sin6_addr
;
al
->
next
=
int_name
->
addr6
;
int_name
->
addr6
=
al
;
al
->
flags
=
ADDRLIST_IPV6
;
}
#endif
}
...
...
@@ -413,7 +466,6 @@ static int iface_allowed_v6(struct in6_addr *local, int prefix,
struct
in_addr
netmask
;
/* dummy */
netmask
.
s_addr
=
0
;
(
void
)
prefix
;
/* warning */
(
void
)
scope
;
/* warning */
(
void
)
preferred
;
(
void
)
valid
;
...
...
@@ -427,7 +479,7 @@ static int iface_allowed_v6(struct in6_addr *local, int prefix,
addr
.
in6
.
sin6_port
=
htons
(
daemon
->
port
);
addr
.
in6
.
sin6_scope_id
=
if_index
;
return
iface_allowed
((
struct
iface_param
*
)
vparam
,
if_index
,
NULL
,
&
addr
,
netmask
,
!!
(
flags
&
IFACE_TENTATIVE
));
return
iface_allowed
((
struct
iface_param
*
)
vparam
,
if_index
,
NULL
,
&
addr
,
netmask
,
prefix
,
!!
(
flags
&
IFACE_TENTATIVE
));
}
#endif
...
...
@@ -435,6 +487,7 @@ static int iface_allowed_v4(struct in_addr local, int if_index, char *label,
struct
in_addr
netmask
,
struct
in_addr
broadcast
,
void
*
vparam
)
{
union
mysockaddr
addr
;
int
prefix
,
bit
;
memset
(
&
addr
,
0
,
sizeof
(
addr
));
#ifdef HAVE_SOCKADDR_SA_LEN
...
...
@@ -445,7 +498,10 @@ static int iface_allowed_v4(struct in_addr local, int if_index, char *label,
addr
.
in
.
sin_addr
=
local
;
addr
.
in
.
sin_port
=
htons
(
daemon
->
port
);
return
iface_allowed
((
struct
iface_param
*
)
vparam
,
if_index
,
label
,
&
addr
,
netmask
,
0
);
/* determine prefix length from netmask */
for
(
prefix
=
32
,
bit
=
1
;
(
bit
&
ntohl
(
netmask
.
s_addr
))
==
0
&&
prefix
!=
0
;
bit
=
bit
<<
1
,
prefix
--
);
return
iface_allowed
((
struct
iface_param
*
)
vparam
,
if_index
,
label
,
&
addr
,
netmask
,
prefix
,
0
);
}
int
enumerate_interfaces
(
int
reset
)
...
...
@@ -456,7 +512,10 @@ int enumerate_interfaces(int reset)
int
errsave
,
ret
=
1
;
struct
addrlist
*
addr
,
*
tmp
;
struct
interface_name
*
intname
;
#ifdef HAVE_AUTH
struct
auth_zone
*
zone
;
#endif
/* Do this max once per select cycle - also inhibits netlink socket use
in TCP child processes. */
...
...
@@ -480,27 +539,38 @@ int enumerate_interfaces(int reset)
/* remove addresses stored against interface_names */
for
(
intname
=
daemon
->
int_names
;
intname
;
intname
=
intname
->
next
)
{
for
(
addr
=
intname
->
addr
4
;
addr
;
addr
=
tmp
)
for
(
addr
=
intname
->
addr
;
addr
;
addr
=
tmp
)
{
tmp
=
addr
->
next
;
addr
->
next
=
spare
;
spare
=
addr
;
}
intname
->
addr4
=
NULL
;
intname
->
addr
=
NULL
;
}
#ifdef HAVE_IPV6
for
(
addr
=
intname
->
addr6
;
addr
;
addr
=
tmp
)
{
tmp
=
addr
->
next
;
addr
->
next
=
spare
;
spare
=
addr
;
}
intname
->
addr6
=
NULL
;
#ifdef HAVE_AUTH
/* remove addresses stored against auth_zone subnets, but not
ones configured as address literals */
for
(
zone
=
daemon
->
auth_zones
;
zone
;
zone
=
zone
->
next
)
if
(
zone
->
interface_names
)
{
struct
addrlist
**
up
;
for
(
up
=
&
zone
->
subnet
,
addr
=
zone
->
subnet
;
addr
;
addr
=
tmp
)
{
tmp
=
addr
->
next
;
if
(
addr
->
flags
&
ADDRLIST_LITERAL
)
up
=
&
addr
->
next
;
else
{
*
up
=
addr
->
next
;
addr
->
next
=
spare
;
spare
=
addr
;
}
}
}
#endif
}
param
.
spare
=
spare
;
#ifdef HAVE_IPV6
...
...
src/option.c
View file @
06e54b82
...
...
@@ -1654,6 +1654,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
new
=
opt_malloc
(
sizeof
(
struct
auth_zone
));
new
->
domain
=
opt_string_alloc
(
arg
);
new
->
subnet
=
NULL
;
new
->
interface_names
=
NULL
;
new
->
next
=
daemon
->
auth_zones
;
daemon
->
auth_zones
=
new
;
...
...
@@ -1661,10 +1662,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
{
int
prefixlen
=
0
;
char
*
prefix
;
struct
subnet
*
subnet
=
opt_malloc
(
sizeof
(
struct
subnet
));
subnet
->
next
=
new
->
subnet
;
new
->
subnet
=
subnet
;
struct
addrlist
*
subnet
=
NULL
;
struct
all_addr
addr
;
comma
=
split
(
arg
);
prefix
=
split_chr
(
arg
,
'/'
);
...
...
@@ -1672,24 +1671,50 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
if
(
prefix
&&
!
atoi_check
(
prefix
,
&
prefixlen
))
ret_err
(
gen_err
);
if
(
inet_pton
(
AF_INET
,
arg
,
&
subnet
->
addr4
))
if
(
inet_pton
(
AF_INET
,
arg
,
&
addr
.
addr
.
addr4
))
{
subnet
=
opt_malloc
(
sizeof
(
struct
addrlist
));
subnet
->
prefixlen
=
(
prefixlen
==
0
)
?
24
:
prefixlen
;
subnet
->
is6
=
0
;
subnet
->
flags
=
ADDRLIST_LITERAL
;
}
#ifdef HAVE_IPV6
else
if
(
inet_pton
(
AF_INET6
,
arg
,
&
subnet
->
addr6
))
else
if
(
inet_pton
(
AF_INET6
,
arg
,
&
addr
.
addr
.
addr6
))
{
subnet
=
opt_malloc
(
sizeof
(
struct
addrlist
));
subnet
->
prefixlen
=
(
prefixlen
==
0
)
?
64
:
prefixlen
;
subnet
->
is6
=
1
;
subnet
->
flags
=
ADDRLIST_LITERAL
|
ADDRLIST_IPV6
;
}
#endif
else
ret_err
(
gen_err
);
else
{
struct
auth_name_list
*
name
=
opt_malloc
(
sizeof
(
struct
auth_name_list
));
name
->
name
=
opt_string_alloc
(
arg
);
name
->
flags
=
AUTH4
|
AUTH6
;
name
->
next
=
new
->
interface_names
;
new
->
interface_names
=
name
;
if
(
prefix
)
{
if
(
prefixlen
==
4
)
name
->
flags
&=
~
AUTH6
;
#ifdef HAVE_IPV6
else
if
(
prefixlen
==
6
)
name
->
flags
&=
~
AUTH4
;
#endif
else
ret_err
(
gen_err
);
}
}
if
(
subnet
)
{
subnet
->
addr
=
addr
;
subnet
->
next
=
new
->
subnet
;
new
->
subnet
=
subnet
;
}
}
break
;
}
case
LOPT_AUTHSOA
:
/* --auth-soa */
comma
=
split
(
arg
);
daemon
->
soa_sn
=
(
u32
)
atoi
(
arg
);
...
...
@@ -2469,11 +2494,6 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
new
->
template_interface
=
opt_string_alloc
(
a
[
leasepos
]
+
12
);
new
->
flags
|=
CONTEXT_TEMPLATE
;
}
else
if
(
strstr
(
a
[
leasepos
],
"constructor-noauth:"
)
==
a
[
leasepos
])
{
new
->
template_interface
=
opt_string_alloc
(
a
[
leasepos
]
+
19
);
new
->
flags
|=
CONTEXT_TEMPLATE
|
CONTEXT_NOAUTH
;
}
else
break
;
}
...
...
@@ -3340,10 +3360,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
new
=
opt_malloc
(
sizeof
(
struct
interface_name
));
new
->
next
=
NULL
;
new
->
addr4
=
NULL
;
#ifdef HAVE_IPV6
new
->
addr6
=
NULL
;
#endif
new
->
addr
=
NULL
;
/* Add to the end of the list, so that first name
of an interface is used for PTR lookups. */
for
(
up
=
&
daemon
->
int_names
;
*
up
;
up
=
&
((
*
up
)
->
next
));
...
...
src/rfc1035.c
View file @
06e54b82
...
...
@@ -637,7 +637,7 @@ struct subnet_opt {
#endif
};
size_t
calc_subnet_opt
(
struct
subnet_opt
*
opt
,
union
mysockaddr
*
source
)
s
tatic
s
ize_t
calc_subnet_opt
(
struct
subnet_opt
*
opt
,
union
mysockaddr
*
source
)
{
/* http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02 */
...
...
@@ -1221,7 +1221,7 @@ int check_for_local_domain(char *name, time_t now)
struct
naptr
*
naptr
;
if
((
crecp
=
cache_find_by_name
(
NULL
,
name
,
now
,
F_IPV4
|
F_IPV6
|
F_CNAME
))
&&
(
crecp
->
flags
&
(
F_HOSTS
|
F_DHCP
)))
(
crecp
->
flags
&
(
F_HOSTS
|
F_DHCP
|
F_CONFIG
)))
return
1
;
for
(
naptr
=
daemon
->
naptr
;
naptr
;
naptr
=
naptr
->
next
)
...
...
@@ -1550,8 +1550,8 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
{
struct
addrlist
*
addrlist
;
for
(
addrlist
=
intr
->
addr
4
;
addrlist
;
addrlist
=
addrlist
->
next
)
if
(
addr
.
addr
.
addr4
.
s_addr
==
addrlist
->
addr
.
addr
.
addr4
.
s_addr
)
for
(
addrlist
=
intr
->
addr
;
addrlist
;
addrlist
=
addrlist
->
next
)
if
(
!
(
addrlist
->
flags
&
ADDRLIST_IPV6
)
&&
addr
.
addr
.
addr4
.
s_addr
==
addrlist
->
addr
.
addr
.
addr4
.
s_addr
)
break
;
if
(
addrlist
)
...
...
@@ -1566,8 +1566,8 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
{
struct
addrlist
*
addrlist
;
for
(
addrlist
=
intr
->
addr
6
;
addrlist
;
addrlist
=
addrlist
->
next
)
if
(
IN6_ARE_ADDR_EQUAL
(
&
addr
.
addr
.
addr6
,
&
addrlist
->
addr
.
addr
.
addr6
))
for
(
addrlist
=
intr
->
addr
;
addrlist
;
addrlist
=
addrlist
->
next
)
if
(
(
addrlist
->
flags
&
ADDRLIST_IPV6
)
&&
IN6_ARE_ADDR_EQUAL
(
&
addr
.
addr
.
addr6
,
&
addrlist
->
addr
.
addr
.
addr6
))
break
;
if
(
addrlist
)
...
...
@@ -1732,26 +1732,22 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
for
(
intr
=
daemon
->
int_names
;
intr
;
intr
=
intr
->
next
)
if
(
hostname_isequal
(
name
,
intr
->
name
))
{
addrlist
=
intr
->
addr4
;
#ifdef HAVE_IPV6
if
(
type
==
T_AAAA
)
addrlist
=
intr
->
addr6
;
#endif
ans
=
1
;
if
(
!
dryrun
)
{
if
(
addrlist
)
{
gotit
=
1
;
for
(;
addrlist
;
addrlist
=
addrlist
->
next
)
{
log_query
(
F_FORWARD
|
F_CONFIG
|
flag
,
name
,
&
addrlist
->
addr
,
NULL
);
if
(
add_resource_record
(
header
,
limit
,
&
trunc
,
nameoffset
,
&
ansp
,
daemon
->
local_ttl
,
NULL
,
type
,
C_IN
,
type
==
T_A
?
"4"
:
"6"
,
&
addrlist
->
addr
))
anscount
++
;
}
}
for
(
addrlist
=
intr
->
addr
;
addrlist
;
addrlist
=
addrlist
->
next
)
#ifdef HAVE_IPV6
if
(((
addrlist
->
flags
&
ADDRLIST_IPV6
)
?
T_AAAA
:
T_A
)
==
type
)
#endif
{
gotit
=
1
;
log_query
(
F_FORWARD
|
F_CONFIG
|
flag
,
name
,
&
addrlist
->
addr
,
NULL
);
if
(
add_resource_record
(
header
,
limit
,
&
trunc
,
nameoffset
,
&
ansp
,
daemon
->
local_ttl
,
NULL
,
type
,
C_IN
,
type
==
T_A
?
"4"
:
"6"
,
&
addrlist
->
addr
))
anscount
++
;
}
}
}
...
...
@@ -1861,7 +1857,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
if
(
qtype
==
T_CNAME
||
qtype
==
T_ANY
)
{
if
((
crecp
=
cache_find_by_name
(
NULL
,
name
,
now
,
F_CNAME
))
&&
(
qtype
==
T_CNAME
||
(
crecp
->
flags
&
(
F_HOSTS
|
F_DHCP
))))
(
qtype
==
T_CNAME
||
(
crecp
->
flags
&
(
F_HOSTS
|
F_DHCP
|
F_CONFIG
))))
{
ans
=
1
;
if
(
!
dryrun
)
...
...
src/rfc3315.c
View file @
06e54b82
...
...
@@ -764,7 +764,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
}
/* Return addresses for all valid contexts which don't yet have one */
while
((
c
=
address6_allocate
(
state
->
context
,
state
->
clid
,
state
->
clid_len
,
state
->
iaid
,
ia_counter
,
solicit_tags
,
plain_range
,
&
addr
)))
while
((
c
=
address6_allocate
(
state
->
context
,
state
->
clid
,
state
->
clid_len
,
state
->
ia_type
==
OPTION6_IA_TA
,
state
->
iaid
,
ia_counter
,
solicit_tags
,
plain_range
,
&
addr
)))
{
#ifdef OPTION6_PREFIX_CLASS
if
(
dump_all_prefix_classes
&&
state
->
ia_type
==
OPTION6_IA_NA
)
...
...
src/util.c
View file @
06e54b82
...
...
@@ -39,6 +39,15 @@ unsigned short rand16(void)
return
(
unsigned
short
)
(
arc4random
()
>>
15
);
}
u64
rand64
(
void
)
{
u64
ret
;
arc4random_buf
(
&
ret
,
sizeof
(
ret
));
return
ret
;
}
#else
/* SURF random number generator */
...
...
@@ -46,6 +55,7 @@ unsigned short rand16(void)
static
u32
seed
[
32
];
static
u32
in
[
12
];
static
u32
out
[
8
];
static
int
outleft
=
0
;
void
rand_init
()
{
...
...
@@ -82,16 +92,31 @@ static void surf(void)
}
unsigned
short
rand16
(
void
)
{
if
(
!
outleft
)
{
if
(
!++
in
[
0
])
if
(
!++
in
[
1
])
if
(
!++
in
[
2
])
++
in
[
3
];
surf
();
outleft
=
8
;
}
return
(
unsigned
short
)
out
[
--
outleft
];
}
u64
rand64
(
void
)
{
static
int
outleft
=
0
;
if
(
!
outleft
)
{
if
(
!++
in
[
0
])
if
(
!++
in
[
1
])
if
(
!++
in
[
2
])
++
in
[
3
];
surf
();
outleft
=
8
;
}
if
(
outleft
<
2
)
{
if
(
!++
in
[
0
])
if
(
!++
in
[
1
])
if
(
!++
in
[
2
])
++
in
[
3
];
surf
();
outleft
=
8
;
}
outleft
-=
2
;
return
(
u
nsigned
short
)
out
[
--
outleft
]
;
return
(
u
64
)
out
[
outleft
+
1
]
+
(((
u64
)
out
[
outleft
])
<<
32
)
;
}
#endif
...
...
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