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
89500e31
Commit
89500e31
authored
Sep 20, 2013
by
Simon Kelley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support MAC addresses in dhcp-host and dhcp-mac for DHCPv6.
parent
c8f2dd8b
Changes
14
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
417 additions
and
271 deletions
+417
-271
CHANGELOG
CHANGELOG
+6
-0
man/dnsmasq.8
man/dnsmasq.8
+9
-7
src/dhcp-common.c
src/dhcp-common.c
+104
-0
src/dhcp.c
src/dhcp.c
+0
-83
src/dhcp6-protocol.h
src/dhcp6-protocol.h
+1
-0
src/dhcp6.c
src/dhcp6.c
+85
-46
src/dnsmasq.c
src/dnsmasq.c
+1
-1
src/dnsmasq.h
src/dnsmasq.h
+34
-32
src/helper.c
src/helper.c
+49
-49
src/lease.c
src/lease.c
+41
-31
src/network.c
src/network.c
+3
-1
src/option.c
src/option.c
+1
-0
src/radv.c
src/radv.c
+10
-4
src/rfc3315.c
src/rfc3315.c
+73
-17
No files found.
CHANGELOG
View file @
89500e31
...
...
@@ -114,6 +114,12 @@ version 2.67
Cope with DHCPv6 clients which send REQUESTs without
address options - treat them as SOLICIT with rapid commit.
Support identification of clients by MAC address in
DHCPv6. When using a relay, the relay must support RFC
6939 for this to work. It always works for directly
connected clients. Thanks to Vladislav Grishenko
for prompting this feature.
version 2.66
Add the ability to act as an authoritative DNS
...
...
man/dnsmasq.8
View file @
89500e31
...
...
@@ -766,7 +766,8 @@ the same subnet as some valid dhcp-range. For
subnets which don't need a pool of dynamically allocated addresses,
use the "static" keyword in the dhcp-range declaration.
It is allowed to use client identifiers rather than
It is allowed to use client identifiers (called client
DUID in IPv6-land rather than
hardware addresses to identify hosts by prefixing with 'id:'. Thus:
.B --dhcp-host=id:01:02:03:04,.....
refers to the host with client identifier 01:02:03:04. It is also
...
...
@@ -781,11 +782,12 @@ IPv6 addresses may contain only the host-identifier part:
.B --dhcp-host=laptop,[::56]
in which case they act as wildcards in constructed dhcp ranges, with
the appropriate network part inserted.
Note that in IPv6 DHCP, the hardware address
is not normally
available,
so a client must be identified by client-id (called client
DUID in IPv6-land) or hostname.
Note that in IPv6 DHCP, the hardware address
may not be
available,
though it normally is for direct-connected clients, or
clients using DHCP relays which support RFC 6939.
The special option id:* means "ignore any client-id
For DHCPv4, the special option id:* means "ignore any client-id
and use MAC addresses only." This is useful when a client presents a client-id sometimes
but not others.
...
...
@@ -1033,7 +1035,7 @@ this to set a different printer server for hosts in the class
"accounts" than for hosts in the class "engineering".
.TP
.B \-4, --dhcp-mac=set:<tag>,<MAC address>
(IPv4 only)
Map from a MAC address to a tag. The MAC address may include
Map from a MAC address to a tag. The MAC address may include
wildcards. For example
.B --dhcp-mac=set:3com,01:34:23:*:*:*
will set the tag "3com" for any host whose MAC address matches the pattern.
...
...
@@ -1339,7 +1341,7 @@ every call to the script.
DNSMASQ_IAID containing the IAID for the lease. If the lease is a
temporary allocation, this is prefixed to 'T'.
DNSMASQ_MAC containing the MAC address of the client, if known.
Note that the supplied hostname, vendorclass and userclass data is
only supplied for
...
...
src/dhcp-common.c
View file @
89500e31
...
...
@@ -253,6 +253,110 @@ int match_bytes(struct dhcp_opt *o, unsigned char *p, int len)
return
0
;
}
int
config_has_mac
(
struct
dhcp_config
*
config
,
unsigned
char
*
hwaddr
,
int
len
,
int
type
)
{
struct
hwaddr_config
*
conf_addr
;
for
(
conf_addr
=
config
->
hwaddr
;
conf_addr
;
conf_addr
=
conf_addr
->
next
)
if
(
conf_addr
->
wildcard_mask
==
0
&&
conf_addr
->
hwaddr_len
==
len
&&
(
conf_addr
->
hwaddr_type
==
type
||
conf_addr
->
hwaddr_type
==
0
)
&&
memcmp
(
conf_addr
->
hwaddr
,
hwaddr
,
len
)
==
0
)
return
1
;
return
0
;
}
static
int
is_config_in_context
(
struct
dhcp_context
*
context
,
struct
dhcp_config
*
config
)
{
if
(
!
context
)
/* called via find_config() from lease_update_from_configs() */
return
1
;
if
(
!
(
context
->
flags
&
CONTEXT_V6
))
{
if
(
!
(
config
->
flags
&
CONFIG_ADDR
))
return
1
;
for
(;
context
;
context
=
context
->
current
)
if
(
is_same_net
(
config
->
addr
,
context
->
start
,
context
->
netmask
))
return
1
;
}
#ifdef HAVE_DHCP6
else
{
if
(
!
(
config
->
flags
&
CONFIG_ADDR6
)
||
(
config
->
flags
&
CONFIG_WILDCARD
))
return
1
;
for
(;
context
;
context
=
context
->
current
)
if
(
is_same_net6
(
&
config
->
addr6
,
&
context
->
start6
,
context
->
prefix
))
return
1
;
}
#endif
return
0
;
}
struct
dhcp_config
*
find_config
(
struct
dhcp_config
*
configs
,
struct
dhcp_context
*
context
,
unsigned
char
*
clid
,
int
clid_len
,
unsigned
char
*
hwaddr
,
int
hw_len
,
int
hw_type
,
char
*
hostname
)
{
int
count
,
new
;
struct
dhcp_config
*
config
,
*
candidate
;
struct
hwaddr_config
*
conf_addr
;
if
(
clid
)
for
(
config
=
configs
;
config
;
config
=
config
->
next
)
if
(
config
->
flags
&
CONFIG_CLID
)
{
if
(
config
->
clid_len
==
clid_len
&&
memcmp
(
config
->
clid
,
clid
,
clid_len
)
==
0
&&
is_config_in_context
(
context
,
config
))
return
config
;
/* dhcpcd prefixes ASCII client IDs by zero which is wrong, but we try and
cope with that here */
if
(
!
(
context
->
flags
&
CONTEXT_V6
)
&&
*
clid
==
0
&&
config
->
clid_len
==
clid_len
-
1
&&
memcmp
(
config
->
clid
,
clid
+
1
,
clid_len
-
1
)
==
0
&&
is_config_in_context
(
context
,
config
))
return
config
;
}
if
(
hwaddr
)
for
(
config
=
configs
;
config
;
config
=
config
->
next
)
if
(
config_has_mac
(
config
,
hwaddr
,
hw_len
,
hw_type
)
&&
is_config_in_context
(
context
,
config
))
return
config
;
if
(
hostname
&&
context
)
for
(
config
=
configs
;
config
;
config
=
config
->
next
)
if
((
config
->
flags
&
CONFIG_NAME
)
&&
hostname_isequal
(
config
->
hostname
,
hostname
)
&&
is_config_in_context
(
context
,
config
))
return
config
;
if
(
!
hwaddr
)
return
NULL
;
/* use match with fewest wildcard octets */
for
(
candidate
=
NULL
,
count
=
0
,
config
=
configs
;
config
;
config
=
config
->
next
)
if
(
is_config_in_context
(
context
,
config
))
for
(
conf_addr
=
config
->
hwaddr
;
conf_addr
;
conf_addr
=
conf_addr
->
next
)
if
(
conf_addr
->
wildcard_mask
!=
0
&&
conf_addr
->
hwaddr_len
==
hw_len
&&
(
conf_addr
->
hwaddr_type
==
hw_type
||
conf_addr
->
hwaddr_type
==
0
)
&&
(
new
=
memcmp_masked
(
conf_addr
->
hwaddr
,
hwaddr
,
hw_len
,
conf_addr
->
wildcard_mask
))
>
count
)
{
count
=
new
;
candidate
=
config
;
}
return
candidate
;
}
void
dhcp_update_configs
(
struct
dhcp_config
*
configs
)
{
/* Some people like to keep all static IP addresses in /etc/hosts.
...
...
src/dhcp.c
View file @
89500e31
...
...
@@ -749,89 +749,6 @@ int address_allocate(struct dhcp_context *context,
return
0
;
}
static
int
is_addr_in_context
(
struct
dhcp_context
*
context
,
struct
dhcp_config
*
config
)
{
if
(
!
context
)
/* called via find_config() from lease_update_from_configs() */
return
1
;
if
(
!
(
config
->
flags
&
CONFIG_ADDR
))
return
1
;
for
(;
context
;
context
=
context
->
current
)
if
(
is_same_net
(
config
->
addr
,
context
->
start
,
context
->
netmask
))
return
1
;
return
0
;
}
int
config_has_mac
(
struct
dhcp_config
*
config
,
unsigned
char
*
hwaddr
,
int
len
,
int
type
)
{
struct
hwaddr_config
*
conf_addr
;
for
(
conf_addr
=
config
->
hwaddr
;
conf_addr
;
conf_addr
=
conf_addr
->
next
)
if
(
conf_addr
->
wildcard_mask
==
0
&&
conf_addr
->
hwaddr_len
==
len
&&
(
conf_addr
->
hwaddr_type
==
type
||
conf_addr
->
hwaddr_type
==
0
)
&&
memcmp
(
conf_addr
->
hwaddr
,
hwaddr
,
len
)
==
0
)
return
1
;
return
0
;
}
struct
dhcp_config
*
find_config
(
struct
dhcp_config
*
configs
,
struct
dhcp_context
*
context
,
unsigned
char
*
clid
,
int
clid_len
,
unsigned
char
*
hwaddr
,
int
hw_len
,
int
hw_type
,
char
*
hostname
)
{
int
count
,
new
;
struct
dhcp_config
*
config
,
*
candidate
;
struct
hwaddr_config
*
conf_addr
;
if
(
clid
)
for
(
config
=
configs
;
config
;
config
=
config
->
next
)
if
(
config
->
flags
&
CONFIG_CLID
)
{
if
(
config
->
clid_len
==
clid_len
&&
memcmp
(
config
->
clid
,
clid
,
clid_len
)
==
0
&&
is_addr_in_context
(
context
,
config
))
return
config
;
/* dhcpcd prefixes ASCII client IDs by zero which is wrong, but we try and
cope with that here */
if
(
*
clid
==
0
&&
config
->
clid_len
==
clid_len
-
1
&&
memcmp
(
config
->
clid
,
clid
+
1
,
clid_len
-
1
)
==
0
&&
is_addr_in_context
(
context
,
config
))
return
config
;
}
for
(
config
=
configs
;
config
;
config
=
config
->
next
)
if
(
config_has_mac
(
config
,
hwaddr
,
hw_len
,
hw_type
)
&&
is_addr_in_context
(
context
,
config
))
return
config
;
if
(
hostname
&&
context
)
for
(
config
=
configs
;
config
;
config
=
config
->
next
)
if
((
config
->
flags
&
CONFIG_NAME
)
&&
hostname_isequal
(
config
->
hostname
,
hostname
)
&&
is_addr_in_context
(
context
,
config
))
return
config
;
/* use match with fewest wildcard octets */
for
(
candidate
=
NULL
,
count
=
0
,
config
=
configs
;
config
;
config
=
config
->
next
)
if
(
is_addr_in_context
(
context
,
config
))
for
(
conf_addr
=
config
->
hwaddr
;
conf_addr
;
conf_addr
=
conf_addr
->
next
)
if
(
conf_addr
->
wildcard_mask
!=
0
&&
conf_addr
->
hwaddr_len
==
hw_len
&&
(
conf_addr
->
hwaddr_type
==
hw_type
||
conf_addr
->
hwaddr_type
==
0
)
&&
(
new
=
memcmp_masked
(
conf_addr
->
hwaddr
,
hwaddr
,
hw_len
,
conf_addr
->
wildcard_mask
))
>
count
)
{
count
=
new
;
candidate
=
config
;
}
return
candidate
;
}
void
dhcp_read_ethers
(
void
)
{
FILE
*
f
=
fopen
(
ETHERSFILE
,
"r"
);
...
...
src/dhcp6-protocol.h
View file @
89500e31
...
...
@@ -59,6 +59,7 @@
#define OPTION6_REMOTE_ID 37
#define OPTION6_SUBSCRIBER_ID 38
#define OPTION6_FQDN 39
#define OPTION6_CLIENT_MAC 79
/* replace this with the real number when allocated.
defining this also enables the relevant code. */
...
...
src/dhcp6.c
View file @
89500e31
...
...
@@ -18,6 +18,8 @@
#ifdef HAVE_DHCP6
#include <netinet/icmp6.h>
struct
iface_param
{
struct
dhcp_context
*
current
;
struct
dhcp_relay
*
relay
;
...
...
@@ -25,10 +27,17 @@ struct iface_param {
int
ind
,
addr_match
;
};
struct
mac_param
{
struct
in6_addr
*
target
;
unsigned
char
mac
[
DHCP_CHADDR_MAX
];
unsigned
int
maclen
;
};
static
int
complete_context6
(
struct
in6_addr
*
local
,
int
prefix
,
int
scope
,
int
if_index
,
int
flags
,
unsigned
int
preferred
,
unsigned
int
valid
,
void
*
vparam
);
static
int
find_mac
(
int
family
,
char
*
addrp
,
char
*
mac
,
size_t
maclen
,
void
*
parmv
);
static
int
make_duid1
(
int
index
,
unsigned
int
type
,
char
*
mac
,
size_t
maclen
,
void
*
parm
);
void
dhcp6_init
(
void
)
...
...
@@ -90,6 +99,7 @@ void dhcp6_packet(time_t now)
struct
dhcp_context
*
context
;
struct
dhcp_relay
*
relay
;
struct
iface_param
parm
;
struct
mac_param
mac_param
;
struct
cmsghdr
*
cmptr
;
struct
msghdr
msg
;
int
if_index
=
0
;
...
...
@@ -102,6 +112,7 @@ void dhcp6_packet(time_t now)
struct
ifreq
ifr
;
struct
iname
*
tmp
;
unsigned
short
port
;
struct
in6_addr
dst_addr
;
msg
.
msg_control
=
control_u
.
control6
;
msg
.
msg_controllen
=
sizeof
(
control_u
);
...
...
@@ -124,6 +135,7 @@ void dhcp6_packet(time_t now)
p
.
c
=
CMSG_DATA
(
cmptr
);
if_index
=
p
.
p
->
ipi6_ifindex
;
dst_addr
=
p
.
p
->
ipi6_addr
;
}
if
(
!
indextoname
(
daemon
->
dhcp6fd
,
if_index
,
ifr
.
ifr_name
))
...
...
@@ -131,7 +143,8 @@ void dhcp6_packet(time_t now)
if
((
port
=
relay_reply6
(
&
from
,
sz
,
ifr
.
ifr_name
))
==
0
)
{
int
i
;
for
(
tmp
=
daemon
->
if_except
;
tmp
;
tmp
=
tmp
->
next
)
if
(
tmp
->
name
&&
wildcard_match
(
tmp
->
name
,
ifr
.
ifr_name
))
return
;
...
...
@@ -166,7 +179,48 @@ void dhcp6_packet(time_t now)
if
(
!
iface_enumerate
(
AF_INET6
,
&
parm
,
complete_context6
))
return
;
/* Recieving a packet from a host does not populate the neighbour
cache, so we send a ping to prompt neighbour discovery if we can't
find the sender. Repeat a few times in case of packet loss. */
for
(
i
=
0
;
i
<
5
;
i
++
)
{
struct
timespec
ts
;
struct
ping_packet
*
ping
;
struct
sockaddr_in6
addr
;
mac_param
.
target
=
&
from
.
sin6_addr
;
mac_param
.
maclen
=
0
;
iface_enumerate
(
AF_UNSPEC
,
&
mac_param
,
find_mac
);
if
(
mac_param
.
maclen
!=
0
)
break
;
save_counter
(
0
);
ping
=
expand
(
sizeof
(
struct
ping_packet
));
ping
->
type
=
ICMP6_ECHO_REQUEST
;
ping
->
code
=
0
;
ping
->
identifier
=
1
;
ping
->
sequence_no
=
1
;
memset
(
&
addr
,
0
,
sizeof
(
addr
));
#ifdef HAVE_SOCKADDR_SA_LEN
addr
.
sin6_len
=
sizeof
(
struct
sockaddr_in6
);
#endif
addr
.
sin6_family
=
AF_INET6
;
addr
.
sin6_port
=
htons
(
IPPROTO_ICMPV6
);
addr
.
sin6_addr
=
from
.
sin6_addr
;
sendto
(
daemon
->
icmp6fd
,
daemon
->
outpacket
.
iov_base
,
save_counter
(
0
),
0
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
));
ts
.
tv_sec
=
0
;
ts
.
tv_nsec
=
100000000
;
/* 100ms */
nanosleep
(
&
ts
,
NULL
);
}
if
(
daemon
->
if_names
||
daemon
->
if_addrs
)
{
...
...
@@ -180,7 +234,15 @@ void dhcp6_packet(time_t now)
if
(
parm
.
relay
)
{
relay_upstream6
(
parm
.
relay
,
sz
,
&
from
.
sin6_addr
,
from
.
sin6_scope_id
);
/* Ignore requests sent to the ALL_SERVERS multicast address for relay when
we're listening there for DHCPv6 server reasons. */
struct
in6_addr
all_servers
;
inet_pton
(
AF_INET6
,
ALL_SERVERS
,
&
all_servers
);
if
(
!
IN6_ARE_ADDR_EQUAL
(
&
dst_addr
,
&
all_servers
))
relay_upstream6
(
parm
.
relay
,
sz
,
&
from
.
sin6_addr
,
from
.
sin6_scope_id
,
mac_param
.
maclen
==
0
?
NULL
:
&
mac_param
.
mac
[
0
],
mac_param
.
maclen
,
ARPHRD_ETHER
);
return
;
}
...
...
@@ -191,7 +253,8 @@ void dhcp6_packet(time_t now)
lease_prune
(
NULL
,
now
);
/* lose any expired leases */
port
=
dhcp6_reply
(
parm
.
current
,
if_index
,
ifr
.
ifr_name
,
&
parm
.
fallback
,
sz
,
IN6_IS_ADDR_MULTICAST
(
&
from
.
sin6_addr
),
now
);
sz
,
IN6_IS_ADDR_MULTICAST
(
&
from
.
sin6_addr
),
now
,
mac_param
.
maclen
==
0
?
NULL
:
&
mac_param
.
mac
[
0
],
mac_param
.
maclen
,
ARPHRD_ETHER
);
lease_update_file
(
now
);
lease_update_dns
(
0
);
...
...
@@ -210,6 +273,24 @@ void dhcp6_packet(time_t now)
}
}
static
int
find_mac
(
int
family
,
char
*
addrp
,
char
*
mac
,
size_t
maclen
,
void
*
parmv
)
{
struct
mac_param
*
parm
=
parmv
;
if
(
family
==
AF_INET6
&&
IN6_ARE_ADDR_EQUAL
(
parm
->
target
,
addrp
))
{
if
(
maclen
<=
DHCP_CHADDR_MAX
)
{
parm
->
maclen
=
maclen
;
memcpy
(
parm
->
mac
,
mac
,
maclen
);
}
return
0
;
/* found, abort */
}
return
1
;
}
static
int
complete_context6
(
struct
in6_addr
*
local
,
int
prefix
,
int
scope
,
int
if_index
,
int
flags
,
unsigned
int
preferred
,
unsigned
int
valid
,
void
*
vparam
)
...
...
@@ -435,48 +516,6 @@ int config_valid(struct dhcp_config *config, struct dhcp_context *context, struc
return
0
;
}
static
int
is_config_in_context6
(
struct
dhcp_context
*
context
,
struct
dhcp_config
*
config
)
{
if
(
!
(
config
->
flags
&
CONFIG_ADDR6
)
||
(
config
->
flags
&
CONFIG_WILDCARD
))
return
1
;
for
(;
context
;
context
=
context
->
current
)
if
(
is_same_net6
(
&
config
->
addr6
,
&
context
->
start6
,
context
->
prefix
))
return
1
;
return
0
;
}
struct
dhcp_config
*
find_config6
(
struct
dhcp_config
*
configs
,
struct
dhcp_context
*
context
,
unsigned
char
*
duid
,
int
duid_len
,
char
*
hostname
)
{
struct
dhcp_config
*
config
;
if
(
duid
)
for
(
config
=
configs
;
config
;
config
=
config
->
next
)
if
(
config
->
flags
&
CONFIG_CLID
)
{
if
(
config
->
clid_len
==
duid_len
&&
memcmp
(
config
->
clid
,
duid
,
duid_len
)
==
0
&&
is_config_in_context6
(
context
,
config
))
return
config
;
}
if
(
hostname
&&
context
)
for
(
config
=
configs
;
config
;
config
=
config
->
next
)
if
((
config
->
flags
&
CONFIG_NAME
)
&&
hostname_isequal
(
config
->
hostname
,
hostname
)
&&
is_config_in_context6
(
context
,
config
))
return
config
;
return
NULL
;
}
void
make_duid
(
time_t
now
)
{
if
(
daemon
->
duid_config
)
...
...
src/dnsmasq.c
View file @
89500e31
...
...
@@ -202,7 +202,7 @@ int main (int argc, char **argv)
dhcp_init
();
# ifdef HAVE_DHCP6
if
(
daemon
->
doing_ra
)
if
(
daemon
->
doing_ra
||
daemon
->
doing_dhcp6
||
daemon
->
relay6
)
ra_init
(
now
);
if
(
daemon
->
doing_dhcp6
||
daemon
->
relay6
)
...
...
src/dnsmasq.h
View file @
89500e31
...
...
@@ -539,13 +539,15 @@ struct dhcp_lease {
#ifdef HAVE_BROKEN_RTC
unsigned
int
length
;
#endif
int
hwaddr_len
,
hwaddr_type
;
/* hw_type used for iaid in v6 */
unsigned
char
hwaddr
[
DHCP_CHADDR_MAX
];
/* also IPv6 address */
int
hwaddr_len
,
hwaddr_type
;
unsigned
char
hwaddr
[
DHCP_CHADDR_MAX
];
struct
in_addr
addr
,
override
,
giaddr
;
unsigned
char
*
extradata
;
unsigned
int
extradata_len
,
extradata_size
;
int
last_interface
;
#ifdef HAVE_DHCP6
struct
in6_addr
addr6
;
int
iaid
;
struct
slaac_address
{
struct
in6_addr
addr
,
local
;
time_t
ping_time
;
...
...
@@ -717,24 +719,25 @@ struct dhcp_context {
struct
dhcp_context
*
next
,
*
current
;
};
#define CONTEXT_STATIC 1
#define CONTEXT_NETMASK 2
#define CONTEXT_BRDCAST 4
#define CONTEXT_PROXY 8
#define CONTEXT_RA_ONLY 16
#define CONTEXT_RA_DONE 32
#define CONTEXT_RA_NAME 64
#define CONTEXT_RA_STATELESS 128
#define CONTEXT_DHCP 256
#define CONTEXT_DEPRECATE 512
#define CONTEXT_TEMPLATE 1024
/* create contexts using addresses */
#define CONTEXT_CONSTRUCTED 2048
#define CONTEXT_GC 4096
#define CONTEXT_RA 8192
#define CONTEXT_CONF_USED 16384
#define CONTEXT_USED 32768
#define CONTEXT_NOAUTH 65536
#define CONTEXT_OLD 131072
#define CONTEXT_STATIC (1u<<0)
#define CONTEXT_NETMASK (1u<<1)
#define CONTEXT_BRDCAST (1u<<2)
#define CONTEXT_PROXY (1u<<3)
#define CONTEXT_RA_ONLY (1u<<4)
#define CONTEXT_RA_DONE (1u<<5)
#define CONTEXT_RA_NAME (1u<<6)
#define CONTEXT_RA_STATELESS (1u<<7)
#define CONTEXT_DHCP (1u<<8)
#define CONTEXT_DEPRECATE (1u<<9)
#define CONTEXT_TEMPLATE (1u<<10)
/* create contexts using addresses */
#define CONTEXT_CONSTRUCTED (1u<<11)
#define CONTEXT_GC (1u<<12)
#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)
struct
ping_result
{
...
...
@@ -1072,12 +1075,6 @@ struct dhcp_context *narrow_context(struct dhcp_context *context,
int
address_allocate
(
struct
dhcp_context
*
context
,
struct
in_addr
*
addrp
,
unsigned
char
*
hwaddr
,
int
hw_len
,
struct
dhcp_netid
*
netids
,
time_t
now
);
int
config_has_mac
(
struct
dhcp_config
*
config
,
unsigned
char
*
hwaddr
,
int
len
,
int
type
);
struct
dhcp_config
*
find_config
(
struct
dhcp_config
*
configs
,
struct
dhcp_context
*
context
,
unsigned
char
*
clid
,
int
clid_len
,
unsigned
char
*
hwaddr
,
int
hw_len
,
int
hw_type
,
char
*
hostname
);
void
dhcp_read_ethers
(
void
);
struct
dhcp_config
*
config_find_by_address
(
struct
dhcp_config
*
configs
,
struct
in_addr
addr
);
char
*
host_from_dns
(
struct
in_addr
addr
);
...
...
@@ -1099,6 +1096,7 @@ struct dhcp_lease *lease6_find_by_addr(struct in6_addr *net, int prefix, u64 add
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
);
#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
);
...
...
@@ -1210,10 +1208,6 @@ struct dhcp_context *address6_valid(struct dhcp_context *context,
struct
in6_addr
*
taddr
,
struct
dhcp_netid
*
netids
,
int
plain_range
);
struct
dhcp_config
*
find_config6
(
struct
dhcp_config
*
configs
,
struct
dhcp_context
*
context
,
unsigned
char
*
duid
,
int
duid_len
,
char
*
hostname
);
struct
dhcp_config
*
config_find_by_address6
(
struct
dhcp_config
*
configs
,
struct
in6_addr
*
net
,
int
prefix
,
u64
addr
);
void
make_duid
(
time_t
now
);
...
...
@@ -1223,8 +1217,10 @@ void dhcp_construct_contexts(time_t now);
/* rfc3315.c */
#ifdef HAVE_DHCP6
unsigned
short
dhcp6_reply
(
struct
dhcp_context
*
context
,
int
interface
,
char
*
iface_name
,
struct
in6_addr
*
fallback
,
size_t
sz
,
int
is_multicast
,
time_t
now
);
void
relay_upstream6
(
struct
dhcp_relay
*
relay
,
ssize_t
sz
,
struct
in6_addr
*
peer_address
,
u32
scope_id
);
struct
in6_addr
*
fallback
,
size_t
sz
,
int
is_multicast
,
time_t
now
,
unsigned
char
*
mac
,
unsigned
int
mac_len
,
unsigned
int
mac_type
);
void
relay_upstream6
(
struct
dhcp_relay
*
relay
,
ssize_t
sz
,
struct
in6_addr
*
peer_address
,
u32
scope_id
,
unsigned
char
*
mac
,
unsigned
int
mac_len
,
unsigned
int
mac_type
);
unsigned
short
relay_reply6
(
struct
sockaddr_in6
*
peer
,
ssize_t
sz
,
char
*
arrival_interface
);
#endif
...
...
@@ -1246,6 +1242,12 @@ int lookup_dhcp_opt(int prot, char *name);
int
lookup_dhcp_len
(
int
prot
,
int
val
);
char
*
option_string
(
int
prot
,
unsigned
int
opt
,
unsigned
char
*
val
,
int
opt_len
,
char
*
buf
,
int
buf_len
);
struct
dhcp_config
*
find_config
(
struct
dhcp_config
*
configs
,
struct
dhcp_context
*
context
,
unsigned
char
*
clid
,
int
clid_len
,
unsigned
char
*
hwaddr
,
int
hw_len
,
int
hw_type
,
char
*
hostname
);
int
config_has_mac
(
struct
dhcp_config
*
config
,
unsigned
char
*
hwaddr
,
int
len
,
int
type
);
#ifdef HAVE_LINUX_NETWORK
void
bindtodevice
(
int
fd
);
#endif
...
...
src/helper.c
View file @
89500e31
...
...
@@ -60,10 +60,13 @@ struct script_data
unsigned
int
length
;
#else
time_t
expires
;
#endif
#ifdef HAVE_DHCP6
struct
in6_addr
addr6
;
int
iaid
,
vendorclass_count
;
#endif
unsigned
char
hwaddr
[
DHCP_CHADDR_MAX
];
char
interface
[
IF_NAMESIZE
];
};
static
struct
script_data
*
buf
=
NULL
;
...
...
@@ -215,20 +218,17 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
continue
;
if
(
!
is6
)
/* stringify MAC into dhcp_buff */
p
=
daemon
->
dhcp_buff
;
if
(
data
.
hwaddr_type
!=
ARPHRD_ETHER
||
data
.
hwaddr_len
==
0
)
p
+=
sprintf
(
p
,
"%.2x-"
,
data
.
hwaddr_type
);
for
(
i
=
0
;
(
i
<
data
.
hwaddr_len
)
&&
(
i
<
DHCP_CHADDR_MAX
);
i
++
)
{
/* stringify MAC into dhcp_buff */
p
=
daemon
->
dhcp_buff
;
if
(
data
.
hwaddr_type
!=
ARPHRD_ETHER
||
data
.
hwaddr_len
==
0
)
p
+=
sprintf
(
p
,
"%.2x-"
,
data
.
hwaddr_type
);
for
(
i
=
0
;
(
i
<
data
.
hwaddr_len
)
&&
(
i
<
DHCP_CHADDR_MAX
);
i
++
)
{
p
+=
sprintf
(
p
,
"%.2x"
,
data
.
hwaddr
[
i
]);
if
(
i
!=
data
.
hwaddr_len
-
1
)
p
+=
sprintf
(
p
,
":"
);
}
p
+=
sprintf
(
p
,
"%.2x"
,
data
.
hwaddr
[
i
]);
if
(
i
!=
data
.
hwaddr_len
-
1
)
p
+=
sprintf
(
p
,
":"
);
}
/* supplied data may just exceed normal buffer (unlikely) */
if
((
data
.
hostname_len
+
data
.
ed_len
+
data
.
clid_len
)
>
MAXDNAME
&&
!
(
alloc_buff
=
buf
=
malloc
(
data
.
hostname_len
+
data
.
ed_len
+
data
.
clid_len
)))
...
...
@@ -239,32 +239,25 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
continue
;
/* CLID into packet */
if
(
!
is6
)
for
(
p
=
daemon
->
packet
,
i
=
0
;
i
<
data
.
clid_len
;
i
++
)
{
p
+=
sprintf
(
p
,
"%.2x"
,
buf
[
i
]);
if
(
i
!=
data
.
clid_len
-
1
)
for
(
p
=
daemon
->
packet
,
i
=
0
;
i
<
data
.
clid_len
;
i
++
)
{
p
+=
sprintf
(
p
,
"%.2x"
,
buf
[
i
]);
if
(
i
!=
data
.
clid_len
-
1
)
p
+=
sprintf
(
p
,
":"
);
}
}
#ifdef HAVE_DHCP6
else
if
(
is6
)
{
/* or IAID and server DUID for IPv6 */
sprintf
(
daemon
->
dhcp_buff3
,
"%s%u"
,
data
.
flags
&
LEASE_TA
?
"T"
:
""
,
data
.
hwaddr_type
);
for
(
p
=
daemon
->
packet
,
i
=
0
;
i
<
daemon
->
duid_len
;
i
++
)
sprintf
(
daemon
->
dhcp_buff3
,
"%s%u"
,
data
.
flags
&
LEASE_TA
?
"T"
:
""
,
data
.
iaid
);
for
(
p
=
daemon
->
dhcp_packet
.
iov_base
,
i
=
0
;
i
<
daemon
->
duid_len
;
i
++
)
{
p
+=
sprintf
(
p
,
"%.2x"
,
daemon
->
duid
[
i
]);
if
(
i
!=
daemon
->
duid_len
-
1
)
p
+=
sprintf
(
p
,
":"
);
}
/* duid not MAC for IPv6 */
for
(
p
=
daemon
->
dhcp_buff
,
i
=
0
;
i
<
data
.
clid_len
;
i
++
)
{
p
+=
sprintf
(
p
,
"%.2x"
,
buf
[
i
]);
if
(
i
!=
data
.
clid_len
-
1
)
p
+=
sprintf
(
p
,
":"
);
}
}
#endif
...
...
@@ -293,7 +286,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
inet_ntop
(
AF_INET
,
&
data
.
addr
,
daemon
->
addrbuff
,
ADDRSTRLEN
);
#ifdef HAVE_DHCP6
else
inet_ntop
(
AF_INET6
,
&
data
.
hwaddr
,
daemon
->
addrbuff
,
ADDRSTRLEN
);
inet_ntop
(
AF_INET6
,
&
data
.
addr6
,
daemon
->
addrbuff
,
ADDRSTRLEN
);
#endif
/* file length */
...
...
@@ -329,9 +322,9 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
if
(
is6
)
{
lua_pushstring
(
lua
,
daemon
->
dhcp_buff
);
lua_setfield
(
lua
,
-
2
,
"client_duid"
);
lua_pushstring
(
lua
,
daemon
->
packet
);
lua_setfield
(
lua
,
-
2
,
"client_duid"
);
lua_pushstring
(
lua
,
daemon
->
dhcp_packet
.
iov_base
);
lua_setfield
(
lua
,
-
2
,
"server_duid"
);
lua_pushstring
(
lua
,
daemon
->
dhcp_buff3
);
lua_setfield
(
lua
,
-
2
,
"iaid"
);
...
...
@@ -375,12 +368,16 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
if
(
!
is6
)
buf
=
grab_extradata_lua
(
buf
,
end
,
"vendor_class"
);
#ifdef HAVE_DHCP6
else
for
(
i
=
0
;
i
<
data
.
hwaddr_len
;
i
++
)
{
sprintf
(
daemon
->
dhcp_buff2
,
"vendor_class%i"
,
i
);
buf
=
grab_extradata_lua
(
buf
,
end
,
daemon
->
dhcp_buff2
);
}
else
if
(
data
.
vendorclass_count
!=
0
)
{
sprintf
(
daemon
->
dhcp_buff2
,
"vendor_class_id"
);
buf
=
grab_extradata_lua
(
buf
,
end
,
daemon
->
dhcp_buff2
);
for
(
i
=
0
;
i
<
data
.
vendorclass_count
-
1
;
i
++
)
{
sprintf
(
daemon
->
dhcp_buff2
,
"vendor_class%i"
,
i
);
buf
=
grab_extradata_lua
(
buf
,
end
,
daemon
->
dhcp_buff2
);
}
}
#endif
buf
=
grab_extradata_lua
(
buf
,
end
,
"supplied_hostname"
);
...
...
@@ -423,7 +420,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
lua_setfield
(
lua
,
-
2
,
"old_hostname"
);
}
if
(
!
is6
)
if
(
!
is6
||
data
.
hwaddr_len
!=
0
)
{
lua_pushstring
(
lua
,
daemon
->
dhcp_buff
);
lua_setfield
(
lua
,
-
2
,
"mac_address"
);
...
...
@@ -476,11 +473,15 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
if
(
data
.
action
!=
ACTION_TFTP
)
{
#ifdef HAVE_DHCP6
if
(
is6
)
{
my_setenv
(
"DNSMASQ_IAID"
,
daemon
->
dhcp_buff3
,
&
err
);
my_setenv
(
"DNSMASQ_SERVER_DUID"
,
daemon
->
packet
,
&
err
);
my_setenv
(
"DNSMASQ_SERVER_DUID"
,
daemon
->
dhcp_packet
.
iov_base
,
&
err
);
if
(
data
.
hwaddr_len
!=
0
)
my_setenv
(
"DNSMASQ_MAC"
,
daemon
->
dhcp_buff
,
&
err
);
}
#endif
if
(
!
is6
&&
data
.
clid_len
!=
0
)
my_setenv
(
"DNSMASQ_CLIENT_ID"
,
daemon
->
packet
,
&
err
);
...
...
@@ -507,10 +508,10 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
#ifdef HAVE_DHCP6
else
{
if
(
data
.
hwaddr_len
!=
0
)
if
(
data
.
vendorclass_count
!=
0
)
{
buf
=
grab_extradata
(
buf
,
end
,
"DNSMASQ_VENDOR_CLASS_ID"
,
&
err
);
for
(
i
=
0
;
i
<
data
.
hwaddr_len
-
1
;
i
++
)
for
(
i
=
0
;
i
<
data
.
vendorclass_count
-
1
;
i
++
)
{
sprintf
(
daemon
->
dhcp_buff2
,
"DNSMASQ_VENDOR_CLASS%i"
,
i
);
buf
=
grab_extradata
(
buf
,
end
,
daemon
->
dhcp_buff2
,
&
err
);
...
...
@@ -570,7 +571,8 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
{
execl
(
daemon
->
lease_change_command
,
p
?
p
+
1
:
daemon
->
lease_change_command
,
action_str
,
daemon
->
dhcp_buff
,
daemon
->
addrbuff
,
hostname
,
(
char
*
)
NULL
);
action_str
,
is6
?
daemon
->
packet
:
daemon
->
dhcp_buff
,
daemon
->
addrbuff
,
hostname
,
(
char
*
)
NULL
);
err
=
errno
;
}
/* failed, send event so the main process logs the problem */
...
...
@@ -656,8 +658,6 @@ void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t n
unsigned
int
hostname_len
=
0
,
clid_len
=
0
,
ed_len
=
0
;
int
fd
=
daemon
->
dhcpfd
;
#ifdef HAVE_DHCP6
int
is6
=
!!
(
lease
->
flags
&
(
LEASE_TA
|
LEASE_NA
));
if
(
!
daemon
->
dhcp
)
fd
=
daemon
->
dhcp6fd
;
#endif
...
...
@@ -678,11 +678,11 @@ void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t n
buf
->
action
=
action
;
buf
->
flags
=
lease
->
flags
;
#ifdef HAVE_DHCP6
if
(
is6
)
buf
->
hwaddr_len
=
lease
->
vendorclass_count
;
else
buf
->
vendorclass_count
=
lease
->
vendorclass_count
;
buf
->
addr6
=
lease
->
addr6
;
buf
->
iaid
=
lease
->
iaid
;
#endif
buf
->
hwaddr_len
=
lease
->
hwaddr_len
;
buf
->
hwaddr_len
=
lease
->
hwaddr_len
;
buf
->
hwaddr_type
=
lease
->
hwaddr_type
;
buf
->
clid_len
=
clid_len
;
buf
->
ed_len
=
ed_len
;
...
...
src/lease.c
View file @
89500e31
...
...
@@ -108,6 +108,7 @@ void lease_init(time_t now)
{
char
*
s
=
daemon
->
dhcp_buff2
;
int
lease_type
=
LEASE_NA
;
int
iaid
;
if
(
s
[
0
]
==
'T'
)
{
...
...
@@ -115,12 +116,12 @@ void lease_init(time_t now)
s
++
;
}
hw_type
=
strtoul
(
s
,
NULL
,
10
);
iaid
=
strtoul
(
s
,
NULL
,
10
);
if
((
lease
=
lease6_allocate
(
&
addr
.
addr
.
addr6
,
lease_type
)))
{
lease_set_hwaddr
(
lease
,
NULL
,
(
unsigned
char
*
)
daemon
->
packet
,
0
,
hw_type
,
clid_len
,
now
,
0
);
lease_set_hwaddr
(
lease
,
NULL
,
(
unsigned
char
*
)
daemon
->
packet
,
0
,
0
,
clid_len
,
now
,
0
);
lease_set_iaid
(
lease
,
iaid
);
if
(
strcmp
(
daemon
->
dhcp_buff
,
"*"
)
!=
0
)
lease_set_hostname
(
lease
,
daemon
->
dhcp_buff
,
0
,
get_domain6
((
struct
in6_addr
*
)
lease
->
hwaddr
),
NULL
);
}
...
...
@@ -187,10 +188,12 @@ void lease_update_from_configs(void)
char
*
name
;
for
(
lease
=
leases
;
lease
;
lease
=
lease
->
next
)
if
((
config
=
find_config
(
daemon
->
dhcp_conf
,
NULL
,
lease
->
clid
,
lease
->
clid_len
,
lease
->
hwaddr
,
lease
->
hwaddr_len
,
lease
->
hwaddr_type
,
NULL
))
&&
(
config
->
flags
&
CONFIG_NAME
)
&&
(
!
(
config
->
flags
&
CONFIG_ADDR
)
||
config
->
addr
.
s_addr
==
lease
->
addr
.
s_addr
))
if
(
lease
->
flags
&
(
LEASE_TA
|
LEASE_NA
))
continue
;
else
if
((
config
=
find_config
(
daemon
->
dhcp_conf
,
NULL
,
lease
->
clid
,
lease
->
clid_len
,
lease
->
hwaddr
,
lease
->
hwaddr_len
,
lease
->
hwaddr_type
,
NULL
))
&&
(
config
->
flags
&
CONFIG_NAME
)
&&
(
!
(
config
->
flags
&
CONFIG_ADDR
)
||
config
->
addr
.
s_addr
==
lease
->
addr
.
s_addr
))
lease_set_hostname
(
lease
,
config
->
hostname
,
1
,
get_domain
(
lease
->
addr
),
NULL
);
else
if
((
name
=
host_from_dns
(
lease
->
addr
)))
lease_set_hostname
(
lease
,
name
,
1
,
get_domain
(
lease
->
addr
),
NULL
);
/* updates auth flag only */
...
...
@@ -277,10 +280,10 @@ void lease_update_file(time_t now)
ourprintf
(
&
err
,
"%lu "
,
(
unsigned
long
)
lease
->
expires
);
#endif
inet_ntop
(
AF_INET6
,
lease
->
hwaddr
,
daemon
->
addrbuff
,
ADDRSTRLEN
);
inet_ntop
(
AF_INET6
,
&
lease
->
addr6
,
daemon
->
addrbuff
,
ADDRSTRLEN
);
ourprintf
(
&
err
,
"%s%u %s "
,
(
lease
->
flags
&
LEASE_TA
)
?
"T"
:
""
,
lease
->
hwaddr_type
,
daemon
->
addrbuff
);
lease
->
iaid
,
daemon
->
addrbuff
);
ourprintf
(
&
err
,
"%s "
,
lease
->
hostname
?
lease
->
hostname
:
"*"
);
if
(
lease
->
clid
&&
lease
->
clid_len
!=
0
)
...
...
@@ -376,7 +379,7 @@ static int find_interface_v6(struct in6_addr *local, int prefix,
for
(
lease
=
leases
;
lease
;
lease
=
lease
->
next
)
if
((
lease
->
flags
&
(
LEASE_TA
|
LEASE_NA
)))
if
(
is_same_net6
(
local
,
(
struct
in6_addr
*
)
&
lease
->
hwaddr
,
prefix
))
if
(
is_same_net6
(
local
,
&
lease
->
addr6
,
prefix
))
lease_set_interface
(
lease
,
if_index
,
*
((
time_t
*
)
vparam
));
return
1
;
...
...
@@ -463,12 +466,12 @@ void lease_update_dns(int force)
if
(
lease
->
fqdn
)
cache_add_dhcp_entry
(
lease
->
fqdn
,
prot
,
prot
==
AF_INET
?
(
struct
all_addr
*
)
&
lease
->
addr
:
(
struct
all_addr
*
)
&
lease
->
hwaddr
,
prot
==
AF_INET
?
(
struct
all_addr
*
)
&
lease
->
addr
:
(
struct
all_addr
*
)
&
lease
->
addr6
,
lease
->
expires
);
if
(
!
option_bool
(
OPT_DHCP_FQDN
)
&&
lease
->
hostname
)
cache_add_dhcp_entry
(
lease
->
hostname
,
prot
,
prot
==
AF_INET
?
(
struct
all_addr
*
)
&
lease
->
addr
:
(
struct
all_addr
*
)
&
lease
->
hwaddr
,
prot
==
AF_INET
?
(
struct
all_addr
*
)
&
lease
->
addr
:
(
struct
all_addr
*
)
&
lease
->
addr6
,
lease
->
expires
);
}
...
...
@@ -564,10 +567,10 @@ struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len,
for
(
lease
=
leases
;
lease
;
lease
=
lease
->
next
)
{
if
(
!
(
lease
->
flags
&
lease_type
)
||
lease
->
hwaddr_type
!=
iaid
)
if
(
!
(
lease
->
flags
&
lease_type
)
||
lease
->
iaid
!=
iaid
)
continue
;
if
(
memcmp
(
lease
->
hwaddr
,
addr
,
IN6ADDRSZ
)
!=
0
)
if
(
!
IN6_ARE_ADDR_EQUAL
(
&
lease
->
addr6
,
addr
)
)
continue
;
if
((
clid_len
!=
lease
->
clid_len
||
...
...
@@ -604,7 +607,7 @@ struct dhcp_lease *lease6_find_by_client(struct dhcp_lease *first, int lease_typ
if
(
lease
->
flags
&
LEASE_USED
)
continue
;
if
(
!
(
lease
->
flags
&
lease_type
)
||
lease
->
hwaddr_type
!=
iaid
)
if
(
!
(
lease
->
flags
&
lease_type
)
||
lease
->
iaid
!=
iaid
)
continue
;
if
((
clid_len
!=
lease
->
clid_len
||
...
...
@@ -626,8 +629,8 @@ struct dhcp_lease *lease6_find_by_addr(struct in6_addr *net, int prefix, u64 add
if
(
!
(
lease
->
flags
&
(
LEASE_TA
|
LEASE_NA
)))
continue
;
if
(
is_same_net6
(
(
struct
in6_addr
*
)
lease
->
hwaddr
,
net
,
prefix
)
&&
(
prefix
==
128
||
addr6part
(
(
struct
in6_addr
*
)
lease
->
hwaddr
)
==
addr
))
if
(
is_same_net6
(
&
lease
->
addr6
,
net
,
prefix
)
&&
(
prefix
==
128
||
addr6part
(
&
lease
->
addr6
)
==
addr
))
return
lease
;
}
...
...
@@ -646,11 +649,11 @@ u64 lease_find_max_addr6(struct dhcp_context *context)
if
(
!
(
lease
->
flags
&
(
LEASE_TA
|
LEASE_NA
)))
continue
;
if
(
is_same_net6
(
(
struct
in6_addr
*
)
lease
->
hwaddr
,
&
context
->
start6
,
64
)
&&
addr6part
(
(
struct
in6_addr
*
)
lease
->
hwaddr
)
>
addr6part
(
&
context
->
start6
)
&&
addr6part
(
(
struct
in6_addr
*
)
lease
->
hwaddr
)
<=
addr6part
(
&
context
->
end6
)
&&
addr6part
(
(
struct
in6_addr
*
)
lease
->
hwaddr
)
>
addr
)
addr
=
addr6part
(
(
struct
in6_addr
*
)
lease
->
hwaddr
);
if
(
is_same_net6
(
&
lease
->
addr6
,
&
context
->
start6
,
64
)
&&
addr6part
(
&
lease
->
addr6
)
>
addr6part
(
&
context
->
start6
)
&&
addr6part
(
&
lease
->
addr6
)
<=
addr6part
(
&
context
->
end6
)
&&
addr6part
(
&
lease
->
addr6
)
>
addr
)
addr
=
addr6part
(
&
lease
->
addr6
);
}
return
addr
;
...
...
@@ -692,6 +695,7 @@ static struct dhcp_lease *lease_allocate(void)
#ifdef HAVE_BROKEN_RTC
lease
->
length
=
0xffffffff
;
/* illegal value */
#endif
lease
->
hwaddr_len
=
256
;
/* illegal value */
lease
->
next
=
leases
;
leases
=
lease
;
...
...
@@ -705,11 +709,8 @@ struct dhcp_lease *lease4_allocate(struct in_addr addr)
{
struct
dhcp_lease
*
lease
=
lease_allocate
();
if
(
lease
)
{
lease
->
addr
=
addr
;
lease
->
hwaddr_len
=
256
;
/* illegal value */
}
lease
->
addr
=
addr
;
return
lease
;
}
...
...
@@ -720,8 +721,9 @@ struct dhcp_lease *lease6_allocate(struct in6_addr *addrp, int lease_type)
if
(
lease
)
{
memcpy
(
lease
->
hwaddr
,
addrp
,
sizeof
(
*
addrp
))
;
lease
->
addr6
=
*
addrp
;
lease
->
flags
|=
lease_type
;
lease
->
iaid
=
0
;
}
return
lease
;
...
...
@@ -758,6 +760,17 @@ void lease_set_expires(struct dhcp_lease *lease, unsigned int len, time_t now)
#endif
}
#ifdef HAVE_DHCP6
void
lease_set_iaid
(
struct
dhcp_lease
*
lease
,
int
iaid
)
{
if
(
lease
->
iaid
!=
iaid
)
{
lease
->
iaid
=
iaid
;
lease
->
flags
|=
LEASE_CHANGED
;
}
}
#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
)
...
...
@@ -779,9 +792,6 @@ void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
lease
->
hwaddr_type
=
hw_type
;
lease
->
flags
|=
LEASE_CHANGED
;
file_dirty
=
1
;
/* run script on change */
#ifdef HAVE_DHCP6
change
=
1
;
#endif
}
/* only update clid when one is available, stops packets
...
...
src/network.c
View file @
89500e31
...
...
@@ -115,7 +115,9 @@ int iface_check(int family, struct all_addr *addr, char *name, int *auth)
int
ret
=
1
,
match_addr
=
0
;
/* Note: have to check all and not bail out early, so that we set the
"used" flags. */
"used" flags.
May be called with family == AF_LOCALto check interface by name only. */
if
(
auth
)
*
auth
=
0
;
...
...
src/option.c
View file @
89500e31
...
...
@@ -2404,6 +2404,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
#ifdef HAVE_DHCP6
else
if
(
inet_pton
(
AF_INET6
,
a
[
0
],
&
new
->
start6
))
{
new
->
flags
|=
CONTEXT_V6
;
new
->
prefix
=
64
;
/* default */
new
->
end6
=
new
->
start6
;
new
->
next
=
daemon
->
dhcp6
;
...
...
src/radv.c
View file @
89500e31
...
...
@@ -70,10 +70,15 @@ void ra_init(time_t now)
if
((
context
->
flags
&
CONTEXT_RA_NAME
))
break
;
/* Need ICMP6 socket for transmission for DHCPv6 even when not doing RA. */
ICMP6_FILTER_SETBLOCKALL
(
&
filter
);
ICMP6_FILTER_SETPASS
(
ND_ROUTER_SOLICIT
,
&
filter
);
if
(
context
)
ICMP6_FILTER_SETPASS
(
ICMP6_ECHO_REPLY
,
&
filter
);
if
(
daemon
->
doing_ra
)
{
ICMP6_FILTER_SETPASS
(
ND_ROUTER_SOLICIT
,
&
filter
);
if
(
context
)
ICMP6_FILTER_SETPASS
(
ICMP6_ECHO_REPLY
,
&
filter
);
}
if
((
fd
=
socket
(
PF_INET6
,
SOCK_RAW
,
IPPROTO_ICMPV6
))
==
-
1
||
getsockopt
(
fd
,
IPPROTO_IPV6
,
IPV6_UNICAST_HOPS
,
&
hop_limit
,
&
len
)
||
...
...
@@ -89,7 +94,8 @@ void ra_init(time_t now)
daemon
->
icmp6fd
=
fd
;
ra_start_unsolicted
(
now
,
NULL
);
if
(
daemon
->
doing_ra
)
ra_start_unsolicted
(
now
,
NULL
);
}
void
ra_start_unsolicted
(
time_t
now
,
struct
dhcp_context
*
context
)
...
...
src/rfc3315.c
View file @
89500e31
This diff is collapsed.
Click to expand it.
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