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
33702ab1
Commit
33702ab1
authored
Dec 28, 2015
by
Simon Kelley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
First complete version of DNS-client-id EDNS0 and ARP tracking code.
parent
11867dc2
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
308 additions
and
161 deletions
+308
-161
src/arp.c
src/arp.c
+89
-59
src/config.h
src/config.h
+1
-1
src/dhcp6.c
src/dhcp6.c
+3
-3
src/dns-protocol.h
src/dns-protocol.h
+2
-0
src/dnsmasq.c
src/dnsmasq.c
+14
-9
src/dnsmasq.h
src/dnsmasq.h
+16
-9
src/dnssec.c
src/dnssec.c
+1
-1
src/edns0.c
src/edns0.c
+60
-12
src/forward.c
src/forward.c
+51
-56
src/helper.c
src/helper.c
+58
-8
src/option.c
src/option.c
+9
-0
src/rfc3315.c
src/rfc3315.c
+4
-3
No files found.
src/arp.c
View file @
33702ab1
...
@@ -16,26 +16,31 @@
...
@@ -16,26 +16,31 @@
#include "dnsmasq.h"
#include "dnsmasq.h"
#define ARP_FREE 0
/* Time between forced re-loads from kernel. */
#define ARP_FOUND 1
#define INTERVAL 90
#define ARP_NEW 2
#define ARP_EMPTY 3
#define ARP_MARK 0
#define ARP_FOUND 1
/* Confirmed */
#define ARP_NEW 2
/* Newly created */
#define ARP_EMPTY 3
/* No MAC addr */
struct
arp_record
{
struct
arp_record
{
short
hwlen
,
status
;
unsigned
short
hwlen
,
status
;
int
family
;
int
family
;
unsigned
char
hwaddr
[
DHCP_CHADDR_MAX
];
unsigned
char
hwaddr
[
DHCP_CHADDR_MAX
];
struct
all_addr
addr
;
struct
all_addr
addr
;
struct
arp_record
*
next
;
struct
arp_record
*
next
;
};
};
static
struct
arp_record
*
arps
=
NULL
,
*
old
=
NULL
;
static
struct
arp_record
*
arps
=
NULL
,
*
old
=
NULL
,
*
freelist
=
NULL
;
static
time_t
last
=
0
;
static
int
filter_mac
(
int
family
,
char
*
addrp
,
char
*
mac
,
size_t
maclen
,
void
*
parmv
)
static
int
filter_mac
(
int
family
,
char
*
addrp
,
char
*
mac
,
size_t
maclen
,
void
*
parmv
)
{
{
int
match
=
0
;
struct
arp_record
*
arp
;
struct
arp_record
*
arp
;
(
void
)
parmv
;
if
(
maclen
>
DHCP_CHADDR_MAX
)
if
(
maclen
>
DHCP_CHADDR_MAX
)
return
1
;
return
1
;
...
@@ -58,16 +63,18 @@ static int filter_mac(int family, char *addrp, char *mac, size_t maclen, void *p
...
@@ -58,16 +63,18 @@ static int filter_mac(int family, char *addrp, char *mac, size_t maclen, void *p
}
}
#endif
#endif
if
(
arp
->
status
!=
ARP_EMPTY
&&
arp
->
hwlen
==
maclen
&&
memcmp
(
arp
->
hwaddr
,
mac
,
maclen
)
==
0
)
if
(
arp
->
status
==
ARP_EMPTY
)
arp
->
status
=
ARP_FOUND
;
else
{
{
/* existing address,
MAC changed or arrived new
. */
/* existing address,
was negative
. */
arp
->
status
=
ARP_NEW
;
arp
->
status
=
ARP_NEW
;
arp
->
hwlen
=
maclen
;
arp
->
hwlen
=
maclen
;
arp
->
family
=
family
;
memcpy
(
arp
->
hwaddr
,
mac
,
maclen
);
memcpy
(
arp
->
hwaddr
,
mac
,
maclen
);
}
}
else
if
(
arp
->
hwlen
==
maclen
&&
memcmp
(
arp
->
hwaddr
,
mac
,
maclen
)
==
0
)
/* Existing entry matches - confirm. */
arp
->
status
=
ARP_FOUND
;
else
continue
;
break
;
break
;
}
}
...
@@ -75,10 +82,10 @@ static int filter_mac(int family, char *addrp, char *mac, size_t maclen, void *p
...
@@ -75,10 +82,10 @@ static int filter_mac(int family, char *addrp, char *mac, size_t maclen, void *p
if
(
!
arp
)
if
(
!
arp
)
{
{
/* New entry */
/* New entry */
if
(
old
)
if
(
freelist
)
{
{
arp
=
old
;
arp
=
freelist
;
old
=
old
->
next
;
freelist
=
freelist
->
next
;
}
}
else
if
(
!
(
arp
=
whine_malloc
(
sizeof
(
struct
arp_record
))))
else
if
(
!
(
arp
=
whine_malloc
(
sizeof
(
struct
arp_record
))))
return
1
;
return
1
;
...
@@ -101,81 +108,72 @@ static int filter_mac(int family, char *addrp, char *mac, size_t maclen, void *p
...
@@ -101,81 +108,72 @@ static int filter_mac(int family, char *addrp, char *mac, size_t maclen, void *p
}
}
/* If in lazy mode, we cache absence of ARP entries. */
/* If in lazy mode, we cache absence of ARP entries. */
int
find_mac
(
union
mysockaddr
*
addr
,
unsigned
char
*
mac
,
int
lazy
)
int
find_mac
(
union
mysockaddr
*
addr
,
unsigned
char
*
mac
,
int
lazy
,
time_t
now
)
{
{
struct
arp_record
*
arp
,
**
up
;
struct
arp_record
*
arp
,
**
up
;
int
updated
=
0
;
int
updated
=
0
;
again:
again:
for
(
arp
=
arps
;
arp
;
arp
=
arp
->
next
)
/* If the database is less then INTERVAL old, look in there */
{
if
(
difftime
(
now
,
last
)
<
INTERVAL
)
if
(
addr
->
sa
.
sa_family
==
arp
->
family
)
for
(
arp
=
arps
;
arp
;
arp
=
arp
->
next
)
{
{
if
(
arp
->
addr
.
addr
.
addr4
.
s_addr
!=
addr
->
in
.
sin_addr
.
s_addr
)
if
(
addr
->
sa
.
sa_family
==
arp
->
family
)
continue
;
{
}
if
(
arp
->
addr
.
addr
.
addr4
.
s_addr
!=
addr
->
in
.
sin_addr
.
s_addr
)
continue
;
}
#ifdef HAVE_IPV6
#ifdef HAVE_IPV6
else
else
{
{
if
(
!
IN6_ARE_ADDR_EQUAL
(
&
arp
->
addr
.
addr
.
addr6
,
&
addr
->
in6
.
sin6_addr
))
if
(
!
IN6_ARE_ADDR_EQUAL
(
&
arp
->
addr
.
addr
.
addr6
,
&
addr
->
in6
.
sin6_addr
))
continue
;
continue
;
}
}
#endif
#endif
/* Only accept poitive entries unless in lazy mode. */
/* Only accept poitive entries unless in lazy mode. */
if
(
arp
->
status
!=
ARP_EMPTY
||
lazy
||
updated
)
if
(
arp
->
status
!=
ARP_EMPTY
||
lazy
||
updated
)
{
{
if
(
mac
&&
arp
->
hwlen
!=
0
)
if
(
mac
&&
arp
->
hwlen
!=
0
)
memcpy
(
mac
,
arp
->
hwaddr
,
arp
->
hwlen
);
memcpy
(
mac
,
arp
->
hwaddr
,
arp
->
hwlen
);
return
arp
->
hwlen
;
return
arp
->
hwlen
;
}
}
}
}
/* Not found, try the kernel */
/* Not found, try the kernel */
if
(
!
updated
)
if
(
!
updated
)
{
{
updated
=
1
;
updated
=
1
;
last
=
now
;
/* Mark all non-negative entries */
/* Mark all non-negative entries */
for
(
arp
=
arps
,
up
=
&
arps
;
arp
;
arp
=
arp
->
next
)
for
(
arp
=
arps
,
up
=
&
arps
;
arp
;
arp
=
arp
->
next
)
if
(
arp
->
status
!=
ARP_EMPTY
)
if
(
arp
->
status
!=
ARP_EMPTY
)
arp
->
status
=
ARP_
FREE
;
arp
->
status
=
ARP_
MARK
;
iface_enumerate
(
AF_UNSPEC
,
NULL
,
filter_mac
);
iface_enumerate
(
AF_UNSPEC
,
NULL
,
filter_mac
);
/* Remove all unconfirmed entries to old list
, announce new ones
. */
/* Remove all unconfirmed entries to old list. */
for
(
arp
=
arps
,
up
=
&
arps
;
arp
;
arp
=
arp
->
next
)
for
(
arp
=
arps
,
up
=
&
arps
;
arp
;
arp
=
arp
->
next
)
if
(
arp
->
status
==
ARP_
FREE
)
if
(
arp
->
status
==
ARP_
MARK
)
{
{
*
up
=
arp
->
next
;
*
up
=
arp
->
next
;
arp
->
next
=
old
;
arp
->
next
=
old
;
old
=
arp
;
old
=
arp
;
}
}
else
else
{
up
=
&
arp
->
next
;
up
=
&
arp
->
next
;
if
(
arp
->
status
==
ARP_NEW
)
{
char
a
[
ADDRSTRLEN
],
m
[
ADDRSTRLEN
];
union
mysockaddr
pa
;
pa
.
sa
.
sa_family
=
arp
->
family
;
pa
.
in
.
sin_addr
.
s_addr
=
arp
->
addr
.
addr
.
addr4
.
s_addr
;
prettyprint_addr
(
&
pa
,
a
);
print_mac
(
m
,
arp
->
hwaddr
,
arp
->
hwlen
);
my_syslog
(
LOG_INFO
,
_
(
"new arp: %s %s"
),
a
,
m
);
}
}
goto
again
;
goto
again
;
}
}
/* record failure, so we don't consult the kernel each time
/* record failure, so we don't consult the kernel each time
we're asked for this address */
we're asked for this address */
if
(
old
)
if
(
freelist
)
{
{
arp
=
old
;
arp
=
freelist
;
old
=
old
->
next
;
freelist
=
freelist
->
next
;
}
}
else
else
arp
=
whine_malloc
(
sizeof
(
struct
arp_record
));
arp
=
whine_malloc
(
sizeof
(
struct
arp_record
));
...
@@ -198,4 +196,36 @@ int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy)
...
@@ -198,4 +196,36 @@ int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy)
return
0
;
return
0
;
}
}
int
do_arp_script_run
(
void
)
{
struct
arp_record
*
arp
;
/* Notify any which went, then move to free list */
if
(
old
)
{
#ifdef HAVE_SCRIPT
if
(
option_bool
(
OPT_DNS_CLIENT
))
queue_arp
(
ACTION_ARP_OLD
,
old
->
hwaddr
,
old
->
hwlen
,
old
->
family
,
&
old
->
addr
);
#endif
arp
=
old
;
old
=
arp
->
next
;
arp
->
next
=
freelist
;
freelist
=
arp
;
return
1
;
}
for
(
arp
=
arps
;
arp
;
arp
=
arp
->
next
)
if
(
arp
->
status
==
ARP_NEW
)
{
#ifdef HAVE_SCRIPT
if
(
option_bool
(
OPT_DNS_CLIENT
))
queue_arp
(
ACTION_ARP
,
arp
->
hwaddr
,
arp
->
hwlen
,
arp
->
family
,
&
arp
->
addr
);
#endif
arp
->
status
=
ARP_FOUND
;
return
1
;
}
return
0
;
}
src/config.h
View file @
33702ab1
...
@@ -337,7 +337,7 @@ HAVE_SOCKADDR_SA_LEN
...
@@ -337,7 +337,7 @@ HAVE_SOCKADDR_SA_LEN
#define HAVE_DHCP
#define HAVE_DHCP
#endif
#endif
#if defined(NO_SCRIPT) ||
!defined(HAVE_DHCP) ||
defined(NO_FORK)
#if defined(NO_SCRIPT) || defined(NO_FORK)
#undef HAVE_SCRIPT
#undef HAVE_SCRIPT
#undef HAVE_LUASCRIPT
#undef HAVE_LUASCRIPT
#endif
#endif
...
...
src/dhcp6.c
View file @
33702ab1
...
@@ -220,7 +220,7 @@ void dhcp6_packet(time_t now)
...
@@ -220,7 +220,7 @@ void dhcp6_packet(time_t now)
inet_pton
(
AF_INET6
,
ALL_SERVERS
,
&
all_servers
);
inet_pton
(
AF_INET6
,
ALL_SERVERS
,
&
all_servers
);
if
(
!
IN6_ARE_ADDR_EQUAL
(
&
dst_addr
,
&
all_servers
))
if
(
!
IN6_ARE_ADDR_EQUAL
(
&
dst_addr
,
&
all_servers
))
relay_upstream6
(
parm
.
relay
,
sz
,
&
from
.
sin6_addr
,
from
.
sin6_scope_id
);
relay_upstream6
(
parm
.
relay
,
sz
,
&
from
.
sin6_addr
,
from
.
sin6_scope_id
,
now
);
return
;
return
;
}
}
...
@@ -250,7 +250,7 @@ void dhcp6_packet(time_t now)
...
@@ -250,7 +250,7 @@ void dhcp6_packet(time_t now)
}
}
}
}
void
get_client_mac
(
struct
in6_addr
*
client
,
int
iface
,
unsigned
char
*
mac
,
unsigned
int
*
maclenp
,
unsigned
int
*
mactypep
)
void
get_client_mac
(
struct
in6_addr
*
client
,
int
iface
,
unsigned
char
*
mac
,
unsigned
int
*
maclenp
,
unsigned
int
*
mactypep
,
time_t
now
)
{
{
/* Recieving a packet from a host does not populate the neighbour
/* Recieving a packet from a host does not populate the neighbour
cache, so we send a neighbour discovery request if we can't
cache, so we send a neighbour discovery request if we can't
...
@@ -280,7 +280,7 @@ void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac, unsi
...
@@ -280,7 +280,7 @@ void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac, unsi
{
{
struct
timespec
ts
;
struct
timespec
ts
;
if
((
maclen
=
find_mac
(
&
addr
,
mac
,
0
))
!=
0
)
if
((
maclen
=
find_mac
(
&
addr
,
mac
,
0
,
now
))
!=
0
)
break
;
break
;
sendto
(
daemon
->
icmp6fd
,
&
neigh
,
sizeof
(
neigh
),
0
,
&
addr
.
sa
,
sizeof
(
addr
));
sendto
(
daemon
->
icmp6fd
,
&
neigh
,
sizeof
(
neigh
),
0
,
&
addr
.
sa
,
sizeof
(
addr
));
...
...
src/dns-protocol.h
View file @
33702ab1
...
@@ -77,6 +77,8 @@
...
@@ -77,6 +77,8 @@
#define EDNS0_OPTION_MAC 65001
/* dyndns.org temporary assignment */
#define EDNS0_OPTION_MAC 65001
/* dyndns.org temporary assignment */
#define EDNS0_OPTION_CLIENT_SUBNET 8
/* IANA */
#define EDNS0_OPTION_CLIENT_SUBNET 8
/* IANA */
#define EDNS0_OPTION_NOMDEVICEID 65073
/* Nominum temporary assignment */
#define EDNS0_OPTION_NOMCPEID 65074
/* Nominum temporary assignment */
struct
dns_header
{
struct
dns_header
{
u16
id
;
u16
id
;
...
...
src/dnsmasq.c
View file @
33702ab1
...
@@ -245,8 +245,11 @@ int main (int argc, char **argv)
...
@@ -245,8 +245,11 @@ int main (int argc, char **argv)
/* Note that order matters here, we must call lease_init before
/* Note that order matters here, we must call lease_init before
creating any file descriptors which shouldn't be leaked
creating any file descriptors which shouldn't be leaked
to the lease-script init process. We need to call common_init
to the lease-script init process. We need to call common_init
before lease_init to allocate buffers it uses.*/
before lease_init to allocate buffers it uses.
if
(
daemon
->
dhcp
||
daemon
->
doing_dhcp6
||
daemon
->
relay4
||
daemon
->
relay6
)
The script subsystrm relies on DHCP buffers, hence the last two
conditions below. */
if
(
daemon
->
dhcp
||
daemon
->
doing_dhcp6
||
daemon
->
relay4
||
daemon
->
relay6
||
option_bool
(
OPT_TFTP
)
||
option_bool
(
OPT_ADD_MAC
))
{
{
dhcp_common_init
();
dhcp_common_init
();
if
(
daemon
->
dhcp
||
daemon
->
doing_dhcp6
)
if
(
daemon
->
dhcp
||
daemon
->
doing_dhcp6
)
...
@@ -553,8 +556,9 @@ int main (int argc, char **argv)
...
@@ -553,8 +556,9 @@ int main (int argc, char **argv)
/* if we are to run scripts, we need to fork a helper before dropping root. */
/* if we are to run scripts, we need to fork a helper before dropping root. */
daemon
->
helperfd
=
-
1
;
daemon
->
helperfd
=
-
1
;
#ifdef HAVE_SCRIPT
#ifdef HAVE_SCRIPT
if
((
daemon
->
dhcp
||
daemon
->
dhcp6
)
&&
(
daemon
->
lease_change_command
||
daemon
->
luascript
))
if
((
daemon
->
dhcp
||
daemon
->
dhcp6
||
option_bool
(
OPT_TFTP
)
||
option_bool
(
OPT_ADD_MAC
))
&&
daemon
->
helperfd
=
create_helper
(
pipewrite
,
err_pipe
[
1
],
script_uid
,
script_gid
,
max_fd
);
(
daemon
->
lease_change_command
||
daemon
->
luascript
))
daemon
->
helperfd
=
create_helper
(
pipewrite
,
err_pipe
[
1
],
script_uid
,
script_gid
,
max_fd
);
#endif
#endif
if
(
!
option_bool
(
OPT_DEBUG
)
&&
getuid
()
==
0
)
if
(
!
option_bool
(
OPT_DEBUG
)
&&
getuid
()
==
0
)
...
@@ -914,9 +918,9 @@ int main (int argc, char **argv)
...
@@ -914,9 +918,9 @@ int main (int argc, char **argv)
poll_listen
(
piperead
,
POLLIN
);
poll_listen
(
piperead
,
POLLIN
);
#ifdef HAVE_
DHCP
#ifdef HAVE_
SCRIPT
# ifdef HAVE_SCRIPT
while
(
helper_buf_empty
()
&&
do_script_run
(
now
));
while
(
helper_buf_empty
()
&&
do_
script_run
(
now
));
while
(
helper_buf_empty
()
&&
do_
arp_script_run
(
));
# ifdef HAVE_TFTP
# ifdef HAVE_TFTP
while
(
helper_buf_empty
()
&&
do_tftp_script_run
());
while
(
helper_buf_empty
()
&&
do_tftp_script_run
());
...
@@ -924,16 +928,17 @@ int main (int argc, char **argv)
...
@@ -924,16 +928,17 @@ int main (int argc, char **argv)
if
(
!
helper_buf_empty
())
if
(
!
helper_buf_empty
())
poll_listen
(
daemon
->
helperfd
,
POLLOUT
);
poll_listen
(
daemon
->
helperfd
,
POLLOUT
);
#
else
#else
/* need this for other side-effects */
/* need this for other side-effects */
while
(
do_script_run
(
now
));
while
(
do_script_run
(
now
));
while
(
do_arp_script_run
(
now
));
# ifdef HAVE_TFTP
# ifdef HAVE_TFTP
while
(
do_tftp_script_run
());
while
(
do_tftp_script_run
());
# endif
# endif
# endif
#endif
#endif
/* must do this just before select(), when we know no
/* must do this just before select(), when we know no
more calls to my_syslog() can occur */
more calls to my_syslog() can occur */
...
...
src/dnsmasq.h
View file @
33702ab1
...
@@ -235,7 +235,8 @@ struct event_desc {
...
@@ -235,7 +235,8 @@ struct event_desc {
#define OPT_LOOP_DETECT 50
#define OPT_LOOP_DETECT 50
#define OPT_EXTRALOG 51
#define OPT_EXTRALOG 51
#define OPT_TFTP_NO_FAIL 52
#define OPT_TFTP_NO_FAIL 52
#define OPT_LAST 53
#define OPT_DNS_CLIENT 53
#define OPT_LAST 54
/* extra flags for my_syslog, we use a couple of facilities since they are known
/* extra flags for my_syslog, we use a couple of facilities since they are known
not to occupy the same bits as priorities, no matter how syslog.h is set up. */
not to occupy the same bits as priorities, no matter how syslog.h is set up. */
...
@@ -633,6 +634,8 @@ struct frec {
...
@@ -633,6 +634,8 @@ struct frec {
#define ACTION_OLD 3
#define ACTION_OLD 3
#define ACTION_ADD 4
#define ACTION_ADD 4
#define ACTION_TFTP 5
#define ACTION_TFTP 5
#define ACTION_ARP 6
#define ACTION_ARP_OLD 7
#define LEASE_NEW 1
/* newly created */
#define LEASE_NEW 1
/* newly created */
#define LEASE_CHANGED 2
/* modified */
#define LEASE_CHANGED 2
/* modified */
...
@@ -948,6 +951,7 @@ extern struct daemon {
...
@@ -948,6 +951,7 @@ extern struct daemon {
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
,
min_cache_ttl
,
max_cache_ttl
,
auth_ttl
;
unsigned
long
local_ttl
,
neg_ttl
,
max_ttl
,
min_cache_ttl
,
max_cache_ttl
,
auth_ttl
;
char
*
dns_client_id
;
struct
hostsfile
*
addn_hosts
;
struct
hostsfile
*
addn_hosts
;
struct
dhcp_context
*
dhcp
,
*
dhcp6
;
struct
dhcp_context
*
dhcp
,
*
dhcp6
;
struct
ra_interface
*
ra_interfaces
;
struct
ra_interface
*
ra_interfaces
;
...
@@ -1135,7 +1139,7 @@ int in_zone(struct auth_zone *zone, char *name, char **cut);
...
@@ -1135,7 +1139,7 @@ int in_zone(struct auth_zone *zone, char *name, char **cut);
#endif
#endif
/* dnssec.c */
/* dnssec.c */
size_t
dnssec_generate_query
(
struct
dns_header
*
header
,
char
*
end
,
char
*
name
,
int
class
,
int
type
,
union
mysockaddr
*
addr
,
int
edns_pktsz
);
size_t
dnssec_generate_query
(
struct
dns_header
*
header
,
unsigned
char
*
end
,
char
*
name
,
int
class
,
int
type
,
union
mysockaddr
*
addr
,
int
edns_pktsz
);
int
dnssec_validate_by_ds
(
time_t
now
,
struct
dns_header
*
header
,
size_t
n
,
char
*
name
,
char
*
keyname
,
int
class
);
int
dnssec_validate_by_ds
(
time_t
now
,
struct
dns_header
*
header
,
size_t
n
,
char
*
name
,
char
*
keyname
,
int
class
);
int
dnssec_validate_ds
(
time_t
now
,
struct
dns_header
*
header
,
size_t
plen
,
char
*
name
,
char
*
keyname
,
int
class
);
int
dnssec_validate_ds
(
time_t
now
,
struct
dns_header
*
header
,
size_t
plen
,
char
*
name
,
char
*
keyname
,
int
class
);
int
dnssec_validate_reply
(
time_t
now
,
struct
dns_header
*
header
,
size_t
plen
,
char
*
name
,
char
*
keyname
,
int
*
class
,
int
dnssec_validate_reply
(
time_t
now
,
struct
dns_header
*
header
,
size_t
plen
,
char
*
name
,
char
*
keyname
,
int
*
class
,
...
@@ -1372,6 +1376,8 @@ void queue_script(int action, struct dhcp_lease *lease,
...
@@ -1372,6 +1376,8 @@ void queue_script(int action, struct dhcp_lease *lease,
#ifdef HAVE_TFTP
#ifdef HAVE_TFTP
void
queue_tftp
(
off_t
file_len
,
char
*
filename
,
union
mysockaddr
*
peer
);
void
queue_tftp
(
off_t
file_len
,
char
*
filename
,
union
mysockaddr
*
peer
);
#endif
#endif
void
queue_arp
(
int
action
,
unsigned
char
*
mac
,
int
maclen
,
int
family
,
struct
all_addr
*
addr
);
int
helper_buf_empty
(
void
);
int
helper_buf_empty
(
void
);
#endif
#endif
...
@@ -1408,7 +1414,7 @@ struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct
...
@@ -1408,7 +1414,7 @@ struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct
void
make_duid
(
time_t
now
);
void
make_duid
(
time_t
now
);
void
dhcp_construct_contexts
(
time_t
now
);
void
dhcp_construct_contexts
(
time_t
now
);
void
get_client_mac
(
struct
in6_addr
*
client
,
int
iface
,
unsigned
char
*
mac
,
void
get_client_mac
(
struct
in6_addr
*
client
,
int
iface
,
unsigned
char
*
mac
,
unsigned
int
*
maclenp
,
unsigned
int
*
mactypep
);
unsigned
int
*
maclenp
,
unsigned
int
*
mactypep
,
time_t
now
);
#endif
#endif
/* rfc3315.c */
/* rfc3315.c */
...
@@ -1416,7 +1422,8 @@ void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac,
...
@@ -1416,7 +1422,8 @@ void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac,
unsigned
short
dhcp6_reply
(
struct
dhcp_context
*
context
,
int
interface
,
char
*
iface_name
,
unsigned
short
dhcp6_reply
(
struct
dhcp_context
*
context
,
int
interface
,
char
*
iface_name
,
struct
in6_addr
*
fallback
,
struct
in6_addr
*
ll_addr
,
struct
in6_addr
*
ula_addr
,
struct
in6_addr
*
fallback
,
struct
in6_addr
*
ll_addr
,
struct
in6_addr
*
ula_addr
,
size_t
sz
,
struct
in6_addr
*
client_addr
,
time_t
now
);
size_t
sz
,
struct
in6_addr
*
client_addr
,
time_t
now
);
void
relay_upstream6
(
struct
dhcp_relay
*
relay
,
ssize_t
sz
,
struct
in6_addr
*
peer_address
,
u32
scope_id
);
void
relay_upstream6
(
struct
dhcp_relay
*
relay
,
ssize_t
sz
,
struct
in6_addr
*
peer_address
,
u32
scope_id
,
time_t
now
);
unsigned
short
relay_reply6
(
struct
sockaddr_in6
*
peer
,
ssize_t
sz
,
char
*
arrival_interface
);
unsigned
short
relay_reply6
(
struct
sockaddr_in6
*
peer
,
ssize_t
sz
,
char
*
arrival_interface
);
#endif
#endif
...
@@ -1512,11 +1519,11 @@ unsigned char *find_pseudoheader(struct dns_header *header, size_t plen,
...
@@ -1512,11 +1519,11 @@ unsigned char *find_pseudoheader(struct dns_header *header, size_t plen,
size_t
*
len
,
unsigned
char
**
p
,
int
*
is_sign
,
int
*
is_last
);
size_t
*
len
,
unsigned
char
**
p
,
int
*
is_sign
,
int
*
is_last
);
size_t
add_pseudoheader
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
*
limit
,
size_t
add_pseudoheader
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
*
limit
,
unsigned
short
udp_sz
,
int
optno
,
unsigned
char
*
opt
,
size_t
optlen
,
int
set_do
);
unsigned
short
udp_sz
,
int
optno
,
unsigned
char
*
opt
,
size_t
optlen
,
int
set_do
);
size_t
add_
mac
(
struct
dns_header
*
header
,
size_t
plen
,
char
*
limit
,
union
mysockaddr
*
l3
);
size_t
add_
do_bit
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
*
limit
);
size_t
add_
source_addr
(
struct
dns_header
*
header
,
size_t
plen
,
char
*
limit
,
union
mysockaddr
*
source
);
size_t
add_
edns0_config
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
*
limit
,
size_t
add_do_bit
(
struct
dns_header
*
header
,
size_t
plen
,
char
*
limi
t
);
union
mysockaddr
*
source
,
time_t
now
,
int
*
check_subne
t
);
int
check_source
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
*
pseudoheader
,
union
mysockaddr
*
peer
);
int
check_source
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
*
pseudoheader
,
union
mysockaddr
*
peer
);
/* arp.c */
/* arp.c */
int
find_mac
(
union
mysockaddr
*
addr
,
unsigned
char
*
mac
,
int
lazy
);
int
find_mac
(
union
mysockaddr
*
addr
,
unsigned
char
*
mac
,
int
lazy
,
time_t
now
);
int
do_arp_script_run
(
void
);
src/dnssec.c
View file @
33702ab1
...
@@ -2173,7 +2173,7 @@ int dnskey_keytag(int alg, int flags, unsigned char *key, int keylen)
...
@@ -2173,7 +2173,7 @@ int dnskey_keytag(int alg, int flags, unsigned char *key, int keylen)
}
}
}
}
size_t
dnssec_generate_query
(
struct
dns_header
*
header
,
char
*
end
,
char
*
name
,
int
class
,
size_t
dnssec_generate_query
(
struct
dns_header
*
header
,
unsigned
char
*
end
,
char
*
name
,
int
class
,
int
type
,
union
mysockaddr
*
addr
,
int
edns_pktsz
)
int
type
,
union
mysockaddr
*
addr
,
int
edns_pktsz
)
{
{
unsigned
char
*
p
;
unsigned
char
*
p
;
...
...
src/edns0.c
View file @
33702ab1
...
@@ -94,13 +94,6 @@ unsigned char *find_pseudoheader(struct dns_header *header, size_t plen, size_t
...
@@ -94,13 +94,6 @@ unsigned char *find_pseudoheader(struct dns_header *header, size_t plen, size_t
return
ret
;
return
ret
;
}
}
struct
macparm
{
unsigned
char
*
limit
;
struct
dns_header
*
header
;
size_t
plen
;
union
mysockaddr
*
l3
;
};
size_t
add_pseudoheader
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
*
limit
,
size_t
add_pseudoheader
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
*
limit
,
unsigned
short
udp_sz
,
int
optno
,
unsigned
char
*
opt
,
size_t
optlen
,
int
set_do
)
unsigned
short
udp_sz
,
int
optno
,
unsigned
char
*
opt
,
size_t
optlen
,
int
set_do
)
...
@@ -208,19 +201,54 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
...
@@ -208,19 +201,54 @@ size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *l
return
p
-
(
unsigned
char
*
)
header
;
return
p
-
(
unsigned
char
*
)
header
;
}
}
size_t
add_do_bit
(
struct
dns_header
*
header
,
size_t
plen
,
char
*
limit
)
size_t
add_do_bit
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
*
limit
)
{
{
return
add_pseudoheader
(
header
,
plen
,
(
unsigned
char
*
)
limit
,
PACKETSZ
,
0
,
NULL
,
0
,
1
);
return
add_pseudoheader
(
header
,
plen
,
(
unsigned
char
*
)
limit
,
PACKETSZ
,
0
,
NULL
,
0
,
1
);
}
}
size_t
add_mac
(
struct
dns_header
*
header
,
size_t
plen
,
char
*
limit
,
union
mysockaddr
*
l3
)
static
unsigned
char
char64
(
unsigned
char
c
)
{
return
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
[
c
&
0x3f
];
}
static
void
encoder
(
unsigned
char
*
in
,
char
*
out
)
{
out
[
0
]
=
char64
(
in
[
0
]
>>
2
);
out
[
1
]
=
char64
((
in
[
0
]
<<
4
)
|
(
in
[
1
]
>>
4
));
out
[
2
]
=
char64
((
in
[
1
]
<<
2
)
|
(
in
[
2
]
>>
6
));
out
[
3
]
=
char64
(
in
[
2
]);
}
static
size_t
add_dns_client
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
*
limit
,
union
mysockaddr
*
l3
,
time_t
now
)
{
{
int
maclen
;
int
maclen
;
unsigned
char
mac
[
DHCP_CHADDR_MAX
];
unsigned
char
mac
[
DHCP_CHADDR_MAX
];
char
encode
[
8
];
/* handle 6 byte MACs */
if
((
maclen
=
find_mac
(
l3
,
mac
,
1
,
now
))
==
6
)
{
encoder
(
mac
,
encode
);
encoder
(
mac
+
3
,
encode
+
4
);
plen
=
add_pseudoheader
(
header
,
plen
,
limit
,
PACKETSZ
,
EDNS0_OPTION_NOMDEVICEID
,
(
unsigned
char
*
)
encode
,
8
,
0
);
}
if
(
daemon
->
dns_client_id
)
plen
=
add_pseudoheader
(
header
,
plen
,
limit
,
PACKETSZ
,
EDNS0_OPTION_NOMCPEID
,
(
unsigned
char
*
)
daemon
->
dns_client_id
,
strlen
(
daemon
->
dns_client_id
),
0
);
return
plen
;
}
if
((
maclen
=
find_mac
(
l3
,
mac
,
1
))
!=
0
)
static
size_t
add_mac
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
*
limit
,
union
mysockaddr
*
l3
,
time_t
now
)
{
int
maclen
;
unsigned
char
mac
[
DHCP_CHADDR_MAX
];
if
((
maclen
=
find_mac
(
l3
,
mac
,
1
,
now
))
!=
0
)
plen
=
add_pseudoheader
(
header
,
plen
,
limit
,
PACKETSZ
,
EDNS0_OPTION_MAC
,
mac
,
maclen
,
0
);
plen
=
add_pseudoheader
(
header
,
plen
,
limit
,
PACKETSZ
,
EDNS0_OPTION_MAC
,
mac
,
maclen
,
0
);
return
plen
;
return
plen
;
}
}
...
@@ -296,7 +324,7 @@ static size_t calc_subnet_opt(struct subnet_opt *opt, union mysockaddr *source)
...
@@ -296,7 +324,7 @@ static size_t calc_subnet_opt(struct subnet_opt *opt, union mysockaddr *source)
return
len
+
4
;
return
len
+
4
;
}
}
s
ize_t
add_source_addr
(
struct
dns_header
*
header
,
size_t
plen
,
char
*
limit
,
union
mysockaddr
*
source
)
s
tatic
size_t
add_source_addr
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
*
limit
,
union
mysockaddr
*
source
)
{
{
/* http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02 */
/* http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02 */
...
@@ -344,3 +372,23 @@ int check_source(struct dns_header *header, size_t plen, unsigned char *pseudohe
...
@@ -344,3 +372,23 @@ int check_source(struct dns_header *header, size_t plen, unsigned char *pseudohe
return
1
;
return
1
;
}
}
size_t
add_edns0_config
(
struct
dns_header
*
header
,
size_t
plen
,
unsigned
char
*
limit
,
union
mysockaddr
*
source
,
time_t
now
,
int
*
check_subnet
)
{
*
check_subnet
=
0
;
if
(
option_bool
(
OPT_ADD_MAC
))
plen
=
add_mac
(
header
,
plen
,
limit
,
source
,
now
);
if
(
option_bool
(
OPT_DNS_CLIENT
))
plen
=
add_dns_client
(
header
,
plen
,
limit
,
source
,
now
);
if
(
option_bool
(
OPT_CLIENT_SUBNET
))
{
plen
=
add_source_addr
(
header
,
plen
,
limit
,
source
);
*
check_subnet
=
1
;
}
return
plen
;
}
src/forward.c
View file @
33702ab1
...
@@ -388,36 +388,27 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
...
@@ -388,36 +388,27 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
if
(
!
flags
&&
forward
)
if
(
!
flags
&&
forward
)
{
{
struct
server
*
firstsentto
=
start
;
struct
server
*
firstsentto
=
start
;
int
forwarded
=
0
;
int
subnet
,
forwarded
=
0
;
size_t
edns0_len
;
size_t
edns0_len
;
/* If a query is retried, use the log_id for the retry when logging the answer. */
/* If a query is retried, use the log_id for the retry when logging the answer. */
forward
->
log_id
=
daemon
->
log_id
;
forward
->
log_id
=
daemon
->
log_id
;
if
(
option_bool
(
OPT_ADD_MAC
))
edns0_len
=
add_edns0_config
(
header
,
plen
,
((
unsigned
char
*
)
header
)
+
PACKETSZ
,
&
forward
->
source
,
now
,
&
subnet
);
{
size_t
new
=
add_mac
(
header
,
plen
,
((
char
*
)
header
)
+
PACKETSZ
,
&
forward
->
source
);
if
(
edns0_len
!=
plen
)
if
(
new
!=
plen
)
{
plen
=
new
;
forward
->
flags
|=
FREC_ADDED_PHEADER
;
}
}
if
(
option_bool
(
OPT_CLIENT_SUBNET
))
{
{
size_t
new
=
add_source_addr
(
header
,
plen
,
((
char
*
)
header
)
+
PACKETSZ
,
&
forward
->
source
);
plen
=
edns0_len
;
if
(
new
!=
plen
)
forward
->
flags
|=
FREC_ADDED_PHEADER
;
{
plen
=
new
;
if
(
subnet
)
forward
->
flags
|=
FREC_HAS_SUBNET
|
FREC_ADDED_PHEADER
;
forward
->
flags
|=
FREC_HAS_SUBNET
;
}
}
}
#ifdef HAVE_DNSSEC
#ifdef HAVE_DNSSEC
if
(
option_bool
(
OPT_DNSSEC_VALID
))
if
(
option_bool
(
OPT_DNSSEC_VALID
))
{
{
size_t
new
=
add_do_bit
(
header
,
plen
,
((
char
*
)
header
)
+
PACKETSZ
);
size_t
new
=
add_do_bit
(
header
,
plen
,
((
unsigned
char
*
)
header
)
+
PACKETSZ
);
if
(
new
!=
plen
)
if
(
new
!=
plen
)
forward
->
flags
|=
FREC_ADDED_PHEADER
;
forward
->
flags
|=
FREC_ADDED_PHEADER
;
...
@@ -607,15 +598,30 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
...
@@ -607,15 +598,30 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
}
}
else
else
{
{
unsigned
short
udpsz
;
/* If upstream is advertising a larger UDP packet size
/* If upstream is advertising a larger UDP packet size
than we allow, trim it so that we don't get overlarge
than we allow, trim it so that we don't get overlarge
requests for the client. We can't do this for signed packets. */
requests for the client. We can't do this for signed packets. */
unsigned
short
udpsz
;
unsigned
char
*
psave
=
sizep
;
GETSHORT
(
udpsz
,
sizep
);
GETSHORT
(
udpsz
,
sizep
);
if
(
udpsz
>
daemon
->
edns_pktsz
)
if
(
udpsz
>
daemon
->
edns_pktsz
)
PUTSHORT
(
daemon
->
edns_pktsz
,
psave
);
{
sizep
-=
2
;
PUTSHORT
(
daemon
->
edns_pktsz
,
sizep
);
}
#ifdef HAVE_DNSSEC
/* If the client didn't set the do bit, but we did, reset it. */
if
(
option_bool
(
OPT_DNSSEC_VALID
)
&&
!
do_bit
)
{
unsigned
short
flags
;
sizep
+=
2
;
/* skip RCODE */
GETSHORT
(
flags
,
sizep
);
flags
&=
~
0x8000
;
sizep
-=
2
;
PUTSHORT
(
flags
,
sizep
);
}
#endif
}
}
}
}
}
}
...
@@ -674,14 +680,11 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
...
@@ -674,14 +680,11 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
}
}
#ifdef HAVE_DNSSEC
#ifdef HAVE_DNSSEC
if
(
bogusanswer
&&
!
(
header
->
hb4
&
HB4_CD
)
)
if
(
bogusanswer
&&
!
(
header
->
hb4
&
HB4_CD
)
&&
!
option_bool
(
OPT_DNSSEC_DEBUG
))
{
{
if
(
!
option_bool
(
OPT_DNSSEC_DEBUG
))
/* Bogus reply, turn into SERVFAIL */
{
SET_RCODE
(
header
,
SERVFAIL
);
/* Bogus reply, turn into SERVFAIL */
munged
=
1
;
SET_RCODE
(
header
,
SERVFAIL
);
munged
=
1
;
}
}
}
if
(
option_bool
(
OPT_DNSSEC_VALID
))
if
(
option_bool
(
OPT_DNSSEC_VALID
))
...
@@ -802,7 +805,7 @@ void reply_query(int fd, int family, time_t now)
...
@@ -802,7 +805,7 @@ void reply_query(int fd, int family, time_t now)
if
(
forward
->
flags
|=
FREC_AD_QUESTION
)
if
(
forward
->
flags
|=
FREC_AD_QUESTION
)
header
->
hb4
|=
HB4_AD
;
header
->
hb4
|=
HB4_AD
;
if
(
forward
->
flags
&
FREC_DO_QUESTION
)
if
(
forward
->
flags
&
FREC_DO_QUESTION
)
add_do_bit
(
header
,
nn
,
(
char
*
)
pheader
+
plen
);
add_do_bit
(
header
,
nn
,
(
unsigned
char
*
)
pheader
+
plen
);
forward_query
(
-
1
,
NULL
,
NULL
,
0
,
header
,
nn
,
now
,
forward
,
forward
->
flags
&
FREC_AD_QUESTION
,
forward
->
flags
&
FREC_DO_QUESTION
);
forward_query
(
-
1
,
NULL
,
NULL
,
0
,
header
,
nn
,
now
,
forward
,
forward
->
flags
&
FREC_AD_QUESTION
,
forward
->
flags
&
FREC_DO_QUESTION
);
return
;
return
;
}
}
...
@@ -927,13 +930,13 @@ void reply_query(int fd, int family, time_t now)
...
@@ -927,13 +930,13 @@ void reply_query(int fd, int family, time_t now)
if
(
status
==
STAT_NEED_KEY
)
if
(
status
==
STAT_NEED_KEY
)
{
{
new
->
flags
|=
FREC_DNSKEY_QUERY
;
new
->
flags
|=
FREC_DNSKEY_QUERY
;
nn
=
dnssec_generate_query
(
header
,
((
char
*
)
header
)
+
server
->
edns_pktsz
,
nn
=
dnssec_generate_query
(
header
,
((
unsigned
char
*
)
header
)
+
server
->
edns_pktsz
,
daemon
->
keyname
,
forward
->
class
,
T_DNSKEY
,
&
server
->
addr
,
server
->
edns_pktsz
);
daemon
->
keyname
,
forward
->
class
,
T_DNSKEY
,
&
server
->
addr
,
server
->
edns_pktsz
);
}
}
else
else
{
{
new
->
flags
|=
FREC_DS_QUERY
;
new
->
flags
|=
FREC_DS_QUERY
;
nn
=
dnssec_generate_query
(
header
,((
char
*
)
header
)
+
server
->
edns_pktsz
,
nn
=
dnssec_generate_query
(
header
,((
unsigned
char
*
)
header
)
+
server
->
edns_pktsz
,
daemon
->
keyname
,
forward
->
class
,
T_DS
,
&
server
->
addr
,
server
->
edns_pktsz
);
daemon
->
keyname
,
forward
->
class
,
T_DS
,
&
server
->
addr
,
server
->
edns_pktsz
);
}
}
if
((
hash
=
hash_questions
(
header
,
nn
,
daemon
->
namebuff
)))
if
((
hash
=
hash_questions
(
header
,
nn
,
daemon
->
namebuff
)))
...
@@ -1434,7 +1437,7 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
...
@@ -1434,7 +1437,7 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
break
;
break
;
}
}
m
=
dnssec_generate_query
(
new_header
,
((
char
*
)
new_header
)
+
65536
,
keyname
,
class
,
m
=
dnssec_generate_query
(
new_header
,
((
unsigned
char
*
)
new_header
)
+
65536
,
keyname
,
class
,
new_status
==
STAT_NEED_KEY
?
T_DNSKEY
:
T_DS
,
&
server
->
addr
,
server
->
edns_pktsz
);
new_status
==
STAT_NEED_KEY
?
T_DNSKEY
:
T_DS
,
&
server
->
addr
,
server
->
edns_pktsz
);
*
length
=
htons
(
m
);
*
length
=
htons
(
m
);
...
@@ -1548,8 +1551,6 @@ unsigned char *tcp_request(int confd, time_t now,
...
@@ -1548,8 +1551,6 @@ unsigned char *tcp_request(int confd, time_t now,
daemon
->
log_display_id
=
++
daemon
->
log_id
;
daemon
->
log_display_id
=
++
daemon
->
log_id
;
daemon
->
log_source_addr
=
&
peer_addr
;
daemon
->
log_source_addr
=
&
peer_addr
;
check_subnet
=
0
;
/* save state of "cd" flag in query */
/* save state of "cd" flag in query */
if
((
checking_disabled
=
header
->
hb4
&
HB4_CD
))
if
((
checking_disabled
=
header
->
hb4
&
HB4_CD
))
no_cache_dnssec
=
1
;
no_cache_dnssec
=
1
;
...
@@ -1627,20 +1628,14 @@ unsigned char *tcp_request(int confd, time_t now,
...
@@ -1627,20 +1628,14 @@ unsigned char *tcp_request(int confd, time_t now,
struct
all_addr
*
addrp
=
NULL
;
struct
all_addr
*
addrp
=
NULL
;
int
type
=
0
;
int
type
=
0
;
char
*
domain
=
NULL
;
char
*
domain
=
NULL
;
size_t
new_size
=
add_edns0_config
(
header
,
size
,
((
unsigned
char
*
)
header
)
+
65536
,
&
peer_addr
,
now
,
&
check_subnet
);
if
(
option_bool
(
OPT_ADD_MAC
))
size
=
add_mac
(
header
,
size
,
((
char
*
)
header
)
+
65536
,
&
peer_addr
);
if
(
size
!=
new_size
)
if
(
option_bool
(
OPT_CLIENT_SUBNET
))
{
{
size_t
new
=
add_source_addr
(
header
,
size
,
((
char
*
)
header
)
+
65536
,
&
peer_addr
);
added_pheader
=
1
;
if
(
size
!=
new
)
size
=
new_size
;
{
size
=
new
;
check_subnet
=
1
;
}
}
}
if
(
gotname
)
if
(
gotname
)
flags
=
search_servers
(
now
,
&
addrp
,
gotname
,
daemon
->
namebuff
,
&
type
,
&
domain
,
&
norebind
);
flags
=
search_servers
(
now
,
&
addrp
,
gotname
,
daemon
->
namebuff
,
&
type
,
&
domain
,
&
norebind
);
...
@@ -1715,20 +1710,20 @@ unsigned char *tcp_request(int confd, time_t now,
...
@@ -1715,20 +1710,20 @@ unsigned char *tcp_request(int confd, time_t now,
}
}
#ifdef HAVE_DNSSEC
#ifdef HAVE_DNSSEC
added_pheader
=
0
;
if
(
option_bool
(
OPT_DNSSEC_VALID
))
if
(
option_bool
(
OPT_DNSSEC_VALID
))
{
{
size_t
new_size
=
add_do_bit
(
header
,
size
,
((
char
*
)
header
)
+
65536
);
new_size
=
add_do_bit
(
header
,
size
,
((
unsigned
char
*
)
header
)
+
65536
);
if
(
size
!=
new_size
)
{
added_pheader
=
1
;
size
=
new_size
;
}
/* For debugging, set Checking Disabled, otherwise, have the upstream check too,
/* For debugging, set Checking Disabled, otherwise, have the upstream check too,
this allows it to select auth servers when one is returning bad data. */
this allows it to select auth servers when one is returning bad data. */
if
(
option_bool
(
OPT_DNSSEC_DEBUG
))
if
(
option_bool
(
OPT_DNSSEC_DEBUG
))
header
->
hb4
|=
HB4_CD
;
header
->
hb4
|=
HB4_CD
;
if
(
size
!=
new_size
)
added_pheader
=
1
;
size
=
new_size
;
}
}
#endif
#endif
}
}
...
...
src/helper.c
View file @
33702ab1
...
@@ -219,7 +219,18 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
...
@@ -219,7 +219,18 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
action_str
=
"tftp"
;
action_str
=
"tftp"
;
is6
=
(
data
.
flags
!=
AF_INET
);
is6
=
(
data
.
flags
!=
AF_INET
);
}
}
else
else
if
(
data
.
action
==
ACTION_ARP
)
{
action_str
=
"arp"
;
is6
=
(
data
.
flags
!=
AF_INET
);
}
else
if
(
data
.
action
==
ACTION_ARP_OLD
)
{
action_str
=
"arp-old"
;
is6
=
(
data
.
flags
!=
AF_INET
);
data
.
action
=
ACTION_ARP
;
}
else
continue
;
continue
;
...
@@ -321,6 +332,22 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
...
@@ -321,6 +332,22 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
lua_call
(
lua
,
2
,
0
);
/* pass 2 values, expect 0 */
lua_call
(
lua
,
2
,
0
);
/* pass 2 values, expect 0 */
}
}
}
}
else
if
(
data
.
action
==
ACTION_ARP
)
{
lua_getglobal
(
lua
,
"arp"
);
if
(
lua_type
(
lua
,
-
1
)
!=
LUA_TFUNCTION
)
lua_pop
(
lua
,
1
);
/* arp function optional */
else
{
lua_pushstring
(
lua
,
action_str
);
/* arg1 - action */
lua_newtable
(
lua
);
/* arg2 - data table */
lua_pushstring
(
lua
,
daemon
->
addrbuff
);
lua_setfield
(
lua
,
-
2
,
"client_address"
);
lua_pushstring
(
lua
,
daemon
->
dhcp_buff
);
lua_setfield
(
lua
,
-
2
,
"mac_address"
);
lua_call
(
lua
,
2
,
0
);
/* pass 2 values, expect 0 */
}
}
else
else
{
{
lua_getglobal
(
lua
,
"lease"
);
/* function to call */
lua_getglobal
(
lua
,
"lease"
);
/* function to call */
...
@@ -478,7 +505,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
...
@@ -478,7 +505,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
continue
;
continue
;
}
}
if
(
data
.
action
!=
ACTION_TFTP
)
if
(
data
.
action
!=
ACTION_TFTP
&&
data
.
action
!=
ACTION_ARP
)
{
{
#ifdef HAVE_DHCP6
#ifdef HAVE_DHCP6
my_setenv
(
"DNSMASQ_IAID"
,
is6
?
daemon
->
dhcp_buff3
:
NULL
,
&
err
);
my_setenv
(
"DNSMASQ_IAID"
,
is6
?
daemon
->
dhcp_buff3
:
NULL
,
&
err
);
...
@@ -550,10 +577,9 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
...
@@ -550,10 +577,9 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
my_setenv
(
"DNSMASQ_OLD_HOSTNAME"
,
data
.
action
==
ACTION_OLD_HOSTNAME
?
hostname
:
NULL
,
&
err
);
my_setenv
(
"DNSMASQ_OLD_HOSTNAME"
,
data
.
action
==
ACTION_OLD_HOSTNAME
?
hostname
:
NULL
,
&
err
);
if
(
data
.
action
==
ACTION_OLD_HOSTNAME
)
if
(
data
.
action
==
ACTION_OLD_HOSTNAME
)
hostname
=
NULL
;
hostname
=
NULL
;
}
my_setenv
(
"DNSMASQ_LOG_DHCP"
,
option_bool
(
OPT_LOG_OPTS
)
?
"1"
:
NULL
,
&
err
);
my_setenv
(
"DNSMASQ_LOG_DHCP"
,
option_bool
(
OPT_LOG_OPTS
)
?
"1"
:
NULL
,
&
err
);
}
/* we need to have the event_fd around if exec fails */
/* we need to have the event_fd around if exec fails */
if
((
i
=
fcntl
(
event_fd
,
F_GETFD
))
!=
-
1
)
if
((
i
=
fcntl
(
event_fd
,
F_GETFD
))
!=
-
1
)
fcntl
(
event_fd
,
F_SETFD
,
i
|
FD_CLOEXEC
);
fcntl
(
event_fd
,
F_SETFD
,
i
|
FD_CLOEXEC
);
...
@@ -563,8 +589,8 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
...
@@ -563,8 +589,8 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
if
(
err
==
0
)
if
(
err
==
0
)
{
{
execl
(
daemon
->
lease_change_command
,
execl
(
daemon
->
lease_change_command
,
p
?
p
+
1
:
daemon
->
lease_change_command
,
p
?
p
+
1
:
daemon
->
lease_change_command
,
action_str
,
action_str
,
is6
?
daemon
->
packet
:
daemon
->
dhcp_buff
,
(
is6
&&
data
.
action
!=
ACTION_ARP
)
?
daemon
->
packet
:
daemon
->
dhcp_buff
,
daemon
->
addrbuff
,
hostname
,
(
char
*
)
NULL
);
daemon
->
addrbuff
,
hostname
,
(
char
*
)
NULL
);
err
=
errno
;
err
=
errno
;
}
}
...
@@ -760,6 +786,30 @@ void queue_tftp(off_t file_len, char *filename, union mysockaddr *peer)
...
@@ -760,6 +786,30 @@ void queue_tftp(off_t file_len, char *filename, union mysockaddr *peer)
}
}
#endif
#endif
void
queue_arp
(
int
action
,
unsigned
char
*
mac
,
int
maclen
,
int
family
,
struct
all_addr
*
addr
)
{
/* no script */
if
(
daemon
->
helperfd
==
-
1
)
return
;
buff_alloc
(
sizeof
(
struct
script_data
));
memset
(
buf
,
0
,
sizeof
(
struct
script_data
));
buf
->
action
=
action
;
buf
->
hwaddr_len
=
maclen
;
buf
->
hwaddr_type
=
ARPHRD_ETHER
;
if
((
buf
->
flags
=
family
)
==
AF_INET
)
buf
->
addr
=
addr
->
addr
.
addr4
;
#ifdef HAVE_IPV6
else
buf
->
addr6
=
addr
->
addr
.
addr6
;
#endif
memcpy
(
buf
->
hwaddr
,
mac
,
maclen
);
bytes_in_buf
=
sizeof
(
struct
script_data
);
}
int
helper_buf_empty
(
void
)
int
helper_buf_empty
(
void
)
{
{
return
bytes_in_buf
==
0
;
return
bytes_in_buf
==
0
;
...
...
src/option.c
View file @
33702ab1
...
@@ -154,6 +154,7 @@ struct myoption {
...
@@ -154,6 +154,7 @@ struct myoption {
#define LOPT_HOST_INOTIFY 342
#define LOPT_HOST_INOTIFY 342
#define LOPT_DNSSEC_STAMP 343
#define LOPT_DNSSEC_STAMP 343
#define LOPT_TFTP_NO_FAIL 344
#define LOPT_TFTP_NO_FAIL 344
#define LOPT_DNS_CLIENT_ID 355
#ifdef HAVE_GETOPT_LONG
#ifdef HAVE_GETOPT_LONG
static
const
struct
option
opts
[]
=
static
const
struct
option
opts
[]
=
...
@@ -281,6 +282,7 @@ static const struct myoption opts[] =
...
@@ -281,6 +282,7 @@ static const struct myoption opts[] =
{
"rebind-localhost-ok"
,
0
,
0
,
LOPT_LOC_REBND
},
{
"rebind-localhost-ok"
,
0
,
0
,
LOPT_LOC_REBND
},
{
"add-mac"
,
0
,
0
,
LOPT_ADD_MAC
},
{
"add-mac"
,
0
,
0
,
LOPT_ADD_MAC
},
{
"add-subnet"
,
2
,
0
,
LOPT_ADD_SBNET
},
{
"add-subnet"
,
2
,
0
,
LOPT_ADD_SBNET
},
{
"add-dns-client"
,
2
,
0
,
LOPT_DNS_CLIENT_ID
},
{
"proxy-dnssec"
,
0
,
0
,
LOPT_DNSSEC
},
{
"proxy-dnssec"
,
0
,
0
,
LOPT_DNSSEC
},
{
"dhcp-sequential-ip"
,
0
,
0
,
LOPT_INCR_ADDR
},
{
"dhcp-sequential-ip"
,
0
,
0
,
LOPT_INCR_ADDR
},
{
"conntrack"
,
0
,
0
,
LOPT_CONNTRACK
},
{
"conntrack"
,
0
,
0
,
LOPT_CONNTRACK
},
...
@@ -446,6 +448,7 @@ static struct {
...
@@ -446,6 +448,7 @@ static struct {
{
LOPT_TEST
,
0
,
NULL
,
gettext_noop
(
"Check configuration syntax."
),
NULL
},
{
LOPT_TEST
,
0
,
NULL
,
gettext_noop
(
"Check configuration syntax."
),
NULL
},
{
LOPT_ADD_MAC
,
OPT_ADD_MAC
,
NULL
,
gettext_noop
(
"Add requestor's MAC address to forwarded DNS queries."
),
NULL
},
{
LOPT_ADD_MAC
,
OPT_ADD_MAC
,
NULL
,
gettext_noop
(
"Add requestor's MAC address to forwarded DNS queries."
),
NULL
},
{
LOPT_ADD_SBNET
,
ARG_ONE
,
"<v4 pref>[,<v6 pref>]"
,
gettext_noop
(
"Add specified IP subnet to forwarded DNS queries."
),
NULL
},
{
LOPT_ADD_SBNET
,
ARG_ONE
,
"<v4 pref>[,<v6 pref>]"
,
gettext_noop
(
"Add specified IP subnet to forwarded DNS queries."
),
NULL
},
{
LOPT_DNS_CLIENT_ID
,
ARG_ONE
,
"<proxyname>"
,
gettext_noop
(
"Add client identification to forwarded DNS queries."
),
NULL
},
{
LOPT_DNSSEC
,
OPT_DNSSEC_PROXY
,
NULL
,
gettext_noop
(
"Proxy DNSSEC validation results from upstream nameservers."
),
NULL
},
{
LOPT_DNSSEC
,
OPT_DNSSEC_PROXY
,
NULL
,
gettext_noop
(
"Proxy DNSSEC validation results from upstream nameservers."
),
NULL
},
{
LOPT_INCR_ADDR
,
OPT_CONSEC_ADDR
,
NULL
,
gettext_noop
(
"Attempt to allocate sequential IP addresses to DHCP clients."
),
NULL
},
{
LOPT_INCR_ADDR
,
OPT_CONSEC_ADDR
,
NULL
,
gettext_noop
(
"Attempt to allocate sequential IP addresses to DHCP clients."
),
NULL
},
{
LOPT_CONNTRACK
,
OPT_CONNTRACK
,
NULL
,
gettext_noop
(
"Copy connection-track mark from queries to upstream connections."
),
NULL
},
{
LOPT_CONNTRACK
,
OPT_CONNTRACK
,
NULL
,
gettext_noop
(
"Copy connection-track mark from queries to upstream connections."
),
NULL
},
...
@@ -2150,6 +2153,12 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
...
@@ -2150,6 +2153,12 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
}
}
break
;
break
;
case
LOPT_DNS_CLIENT_ID
:
/* --add-dns-client */
set_option_bool
(
OPT_DNS_CLIENT
);
if
(
arg
)
daemon
->
dns_client_id
=
opt_string_alloc
(
arg
);
break
;
case
'u'
:
/* --user */
case
'u'
:
/* --user */
daemon
->
username
=
opt_string_alloc
(
arg
);
daemon
->
username
=
opt_string_alloc
(
arg
);
break
;
break
;
...
...
src/rfc3315.c
View file @
33702ab1
...
@@ -130,7 +130,7 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
...
@@ -130,7 +130,7 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
MAC address from the local ND cache. */
MAC address from the local ND cache. */
if
(
!
state
->
link_address
)
if
(
!
state
->
link_address
)
get_client_mac
(
client_addr
,
state
->
interface
,
state
->
mac
,
&
state
->
mac_len
,
&
state
->
mac_type
);
get_client_mac
(
client_addr
,
state
->
interface
,
state
->
mac
,
&
state
->
mac_len
,
&
state
->
mac_type
,
now
);
else
else
{
{
struct
dhcp_context
*
c
;
struct
dhcp_context
*
c
;
...
@@ -2054,7 +2054,8 @@ static unsigned int opt6_uint(unsigned char *opt, int offset, int size)
...
@@ -2054,7 +2054,8 @@ static unsigned int opt6_uint(unsigned char *opt, int offset, int size)
return
ret
;
return
ret
;
}
}
void
relay_upstream6
(
struct
dhcp_relay
*
relay
,
ssize_t
sz
,
struct
in6_addr
*
peer_address
,
u32
scope_id
)
void
relay_upstream6
(
struct
dhcp_relay
*
relay
,
ssize_t
sz
,
struct
in6_addr
*
peer_address
,
u32
scope_id
,
time_t
now
)
{
{
/* ->local is same value for all relays on ->current chain */
/* ->local is same value for all relays on ->current chain */
...
@@ -2068,7 +2069,7 @@ void relay_upstream6(struct dhcp_relay *relay, ssize_t sz, struct in6_addr *peer
...
@@ -2068,7 +2069,7 @@ void relay_upstream6(struct dhcp_relay *relay, ssize_t sz, struct in6_addr *peer
unsigned
char
mac
[
DHCP_CHADDR_MAX
];
unsigned
char
mac
[
DHCP_CHADDR_MAX
];
inet_pton
(
AF_INET6
,
ALL_SERVERS
,
&
multicast
);
inet_pton
(
AF_INET6
,
ALL_SERVERS
,
&
multicast
);
get_client_mac
(
peer_address
,
scope_id
,
mac
,
&
maclen
,
&
mactype
);
get_client_mac
(
peer_address
,
scope_id
,
mac
,
&
maclen
,
&
mactype
,
now
);
/* source address == relay address */
/* source address == relay address */
from
.
addr
.
addr6
=
relay
->
local
.
addr
.
addr6
;
from
.
addr
.
addr6
=
relay
->
local
.
addr
.
addr6
;
...
...
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