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
c3a04081
Commit
c3a04081
authored
Jan 11, 2014
by
Simon Kelley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[fd00::} and [fe80::] special addresses in DHCPv6 options.
parent
ae76242f
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
194 additions
and
57 deletions
+194
-57
CHANGELOG
CHANGELOG
+6
-0
man/dnsmasq.8
man/dnsmasq.8
+8
-4
src/dhcp6.c
src/dhcp6.c
+9
-2
src/dnsmasq.h
src/dnsmasq.h
+3
-1
src/ip6addr.h
src/ip6addr.h
+34
-0
src/radv.c
src/radv.c
+83
-25
src/rfc3315.c
src/rfc3315.c
+51
-25
No files found.
CHANGELOG
View file @
c3a04081
...
@@ -11,6 +11,12 @@ version 2.69
...
@@ -11,6 +11,12 @@ version 2.69
--dhcp-option=option6:23,[::] Thanks to Tsachi Kimeldorfer
--dhcp-option=option6:23,[::] Thanks to Tsachi Kimeldorfer
for spotting the problem.
for spotting the problem.
Add [fd00::] and [fe80::] as special addresses in DHCPv6
options, analogous to [::]. [fd00::] is replaced with the
actual ULA of the interface on the machine running
dnsmasq, [fe80::] with the link-local address.
Thanks to Tsachi Kimeldorfer for championing this.
version 2.68
version 2.68
Use random addresses for DHCPv6 temporary address
Use random addresses for DHCPv6 temporary address
...
...
man/dnsmasq.8
View file @
c3a04081
...
@@ -917,9 +917,11 @@ and to set the time-server address to 192.168.0.4, do
...
@@ -917,9 +917,11 @@ and to set the time-server address to 192.168.0.4, do
.B --dhcp-option = 42,192.168.0.4
.B --dhcp-option = 42,192.168.0.4
or
or
.B --dhcp-option = option:ntp-server, 192.168.0.4
.B --dhcp-option = option:ntp-server, 192.168.0.4
The special address 0.0.0.0 (or [::] for DHCPv6) is taken to mean "the address of the
The special address 0.0.0.0 is taken to mean "the address of the
machine running dnsmasq". Data types allowed are comma separated
machine running dnsmasq".
dotted-quad IP addresses, a decimal number, colon-separated hex digits
Data types allowed are comma separated
dotted-quad IPv4 addresses, []-wrapped IPv6 addresses, a decimal number, colon-separated hex digits
and a text string. If the optional tags are given then
and a text string. If the optional tags are given then
this option is only sent when all the tags are matched.
this option is only sent when all the tags are matched.
...
@@ -935,7 +937,9 @@ keyword, followed by the option number or option name. The IPv6 option
...
@@ -935,7 +937,9 @@ keyword, followed by the option number or option name. The IPv6 option
name space is disjoint from the IPv4 option name space. IPv6 addresses
name space is disjoint from the IPv4 option name space. IPv6 addresses
in options must be bracketed with square brackets, eg.
in options must be bracketed with square brackets, eg.
.B --dhcp-option=option6:ntp-server,[1234::56]
.B --dhcp-option=option6:ntp-server,[1234::56]
For IPv6, [::] means "the global address of
the machine running dnsmasq", whilst [fd00::] is replaced with the
ULA, if it exists, and [fe80::] with the link-local address.
Be careful: no checking is done that the correct type of data for the
Be careful: no checking is done that the correct type of data for the
option number is sent, it is quite possible to
option number is sent, it is quite possible to
...
...
src/dhcp6.c
View file @
c3a04081
...
@@ -23,7 +23,7 @@
...
@@ -23,7 +23,7 @@
struct
iface_param
{
struct
iface_param
{
struct
dhcp_context
*
current
;
struct
dhcp_context
*
current
;
struct
dhcp_relay
*
relay
;
struct
dhcp_relay
*
relay
;
struct
in6_addr
fallback
,
relay_local
;
struct
in6_addr
fallback
,
relay_local
,
ll_addr
,
ula_addr
;
int
ind
,
addr_match
;
int
ind
,
addr_match
;
};
};
...
@@ -158,6 +158,8 @@ void dhcp6_packet(time_t now)
...
@@ -158,6 +158,8 @@ void dhcp6_packet(time_t now)
parm
.
ind
=
if_index
;
parm
.
ind
=
if_index
;
parm
.
addr_match
=
0
;
parm
.
addr_match
=
0
;
memset
(
&
parm
.
fallback
,
0
,
IN6ADDRSZ
);
memset
(
&
parm
.
fallback
,
0
,
IN6ADDRSZ
);
memset
(
&
parm
.
ll_addr
,
0
,
IN6ADDRSZ
);
memset
(
&
parm
.
ula_addr
,
0
,
IN6ADDRSZ
);
for
(
context
=
daemon
->
dhcp6
;
context
;
context
=
context
->
next
)
for
(
context
=
daemon
->
dhcp6
;
context
;
context
=
context
->
next
)
if
(
IN6_IS_ADDR_UNSPECIFIED
(
&
context
->
start6
)
&&
context
->
prefix
==
0
)
if
(
IN6_IS_ADDR_UNSPECIFIED
(
&
context
->
start6
)
&&
context
->
prefix
==
0
)
...
@@ -210,7 +212,7 @@ void dhcp6_packet(time_t now)
...
@@ -210,7 +212,7 @@ void dhcp6_packet(time_t now)
lease_prune
(
NULL
,
now
);
/* lose any expired leases */
lease_prune
(
NULL
,
now
);
/* lose any expired leases */
port
=
dhcp6_reply
(
parm
.
current
,
if_index
,
ifr
.
ifr_name
,
&
parm
.
fallback
,
port
=
dhcp6_reply
(
parm
.
current
,
if_index
,
ifr
.
ifr_name
,
&
parm
.
fallback
,
sz
,
&
from
.
sin6_addr
,
now
);
&
parm
.
ll_addr
,
&
parm
.
ula_addr
,
sz
,
&
from
.
sin6_addr
,
now
);
lease_update_file
(
now
);
lease_update_file
(
now
);
lease_update_dns
(
0
);
lease_update_dns
(
0
);
...
@@ -309,6 +311,11 @@ static int complete_context6(struct in6_addr *local, int prefix,
...
@@ -309,6 +311,11 @@ static int complete_context6(struct in6_addr *local, int prefix,
if
(
if_index
==
param
->
ind
)
if
(
if_index
==
param
->
ind
)
{
{
if
(
IN6_IS_ADDR_LINKLOCAL
(
local
))
param
->
ll_addr
=
*
local
;
else
if
(
IN6_IS_ADDR_ULA
(
local
))
param
->
ula_addr
=
*
local
;
if
(
!
IN6_IS_ADDR_LOOPBACK
(
local
)
&&
if
(
!
IN6_IS_ADDR_LOOPBACK
(
local
)
&&
!
IN6_IS_ADDR_LINKLOCAL
(
local
)
&&
!
IN6_IS_ADDR_LINKLOCAL
(
local
)
&&
!
IN6_IS_ADDR_MULTICAST
(
local
))
!
IN6_IS_ADDR_MULTICAST
(
local
))
...
...
src/dnsmasq.h
View file @
c3a04081
...
@@ -50,6 +50,7 @@
...
@@ -50,6 +50,7 @@
#include <getopt.h>
#include <getopt.h>
#include "config.h"
#include "config.h"
#include "ip6addr.h"
typedef
unsigned
char
u8
;
typedef
unsigned
char
u8
;
typedef
unsigned
short
u16
;
typedef
unsigned
short
u16
;
...
@@ -1314,7 +1315,8 @@ void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac,
...
@@ -1314,7 +1315,8 @@ void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac,
/* rfc3315.c */
/* rfc3315.c */
#ifdef HAVE_DHCP6
#ifdef HAVE_DHCP6
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
,
size_t
sz
,
struct
in6_addr
*
client_addr
,
time_t
now
);
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
);
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
);
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
);
...
...
src/ip6addr.h
0 → 100644
View file @
c3a04081
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define IN6_IS_ADDR_ULA(a) \
((((__const uint32_t *) (a))[0] & htonl (0xff000000)) \
== htonl (0xfd000000))
#define IN6_IS_ADDR_ULA_ZERO(a) \
(((__const uint32_t *) (a))[0] == htonl (0xfd000000) \
&& ((__const uint32_t *) (a))[1] == 0 \
&& ((__const uint32_t *) (a))[2] == 0 \
&& ((__const uint32_t *) (a))[3] == 0)
#define IN6_IS_ADDR_LINK_LOCAL_ZERO(a) \
(((__const uint32_t *) (a))[0] == htonl (0xfe800000) \
&& ((__const uint32_t *) (a))[1] == 0 \
&& ((__const uint32_t *) (a))[2] == 0 \
&& ((__const uint32_t *) (a))[3] == 0)
src/radv.c
View file @
c3a04081
...
@@ -31,8 +31,8 @@ struct ra_param {
...
@@ -31,8 +31,8 @@ struct ra_param {
int
ind
,
managed
,
other
,
found_context
,
first
;
int
ind
,
managed
,
other
,
found_context
,
first
;
char
*
if_name
;
char
*
if_name
;
struct
dhcp_netid
*
tags
;
struct
dhcp_netid
*
tags
;
struct
in6_addr
link_local
,
link_global
;
struct
in6_addr
link_local
,
link_global
,
ula
;
unsigned
int
pref_time
,
adv_interval
;
unsigned
int
glob_pref_time
,
link_pref_time
,
ula_
pref_time
,
adv_interval
;
};
};
struct
search_param
{
struct
search_param
{
...
@@ -206,6 +206,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
...
@@ -206,6 +206,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
struct
dhcp_opt
*
opt_cfg
;
struct
dhcp_opt
*
opt_cfg
;
struct
ra_interface
*
ra_param
=
find_iface_param
(
iface_name
);
struct
ra_interface
*
ra_param
=
find_iface_param
(
iface_name
);
int
done_dns
=
0
,
old_prefix
=
0
;
int
done_dns
=
0
,
old_prefix
=
0
;
unsigned
int
min_pref_time
;
#ifdef HAVE_LINUX_NETWORK
#ifdef HAVE_LINUX_NETWORK
FILE
*
f
;
FILE
*
f
;
#endif
#endif
...
@@ -228,7 +229,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
...
@@ -228,7 +229,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
parm
.
if_name
=
iface_name
;
parm
.
if_name
=
iface_name
;
parm
.
first
=
1
;
parm
.
first
=
1
;
parm
.
now
=
now
;
parm
.
now
=
now
;
parm
.
pref_time
=
0
;
parm
.
glob_pref_time
=
parm
.
link_pref_time
=
parm
.
ula_
pref_time
=
0
;
parm
.
adv_interval
=
calc_interval
(
ra_param
);
parm
.
adv_interval
=
calc_interval
(
ra_param
);
/* set tag with name == interface */
/* set tag with name == interface */
...
@@ -245,6 +246,18 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
...
@@ -245,6 +246,18 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
if
(
!
iface_enumerate
(
AF_INET6
,
&
parm
,
add_prefixes
))
if
(
!
iface_enumerate
(
AF_INET6
,
&
parm
,
add_prefixes
))
return
;
return
;
/* Find smallest preferred time within address classes,
to use as lifetime for options. This is a rather arbitrary choice. */
min_pref_time
=
0xffffffff
;
if
(
parm
.
glob_pref_time
!=
0
&&
parm
.
glob_pref_time
<
min_pref_time
)
min_pref_time
=
parm
.
glob_pref_time
;
if
(
parm
.
ula_pref_time
!=
0
&&
parm
.
ula_pref_time
<
min_pref_time
)
min_pref_time
=
parm
.
ula_pref_time
;
if
(
parm
.
link_pref_time
!=
0
&&
parm
.
link_pref_time
<
min_pref_time
)
min_pref_time
=
parm
.
link_pref_time
;
/* Look for constructed contexts associated with addresses which have gone,
/* Look for constructed contexts associated with addresses which have gone,
and advertise them with preferred_time == 0 RFC 6204 4.3 L-13 */
and advertise them with preferred_time == 0 RFC 6204 4.3 L-13 */
for
(
up
=
&
daemon
->
dhcp6
,
context
=
daemon
->
dhcp6
;
context
;
context
=
tmp
)
for
(
up
=
&
daemon
->
dhcp6
,
context
=
daemon
->
dhcp6
;
context
;
context
=
tmp
)
...
@@ -340,23 +353,49 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
...
@@ -340,23 +353,49 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
if
(
opt_cfg
->
opt
==
OPTION6_DNS_SERVER
)
if
(
opt_cfg
->
opt
==
OPTION6_DNS_SERVER
)
{
{
struct
in6_addr
*
a
=
(
struct
in6_addr
*
)
opt_cfg
->
val
;
struct
in6_addr
*
a
;
int
len
;
done_dns
=
1
;
done_dns
=
1
;
if
(
opt_cfg
->
len
==
0
||
(
IN6_IS_ADDR_UNSPECIFIED
(
a
)
&&
parm
.
pref_time
==
0
))
if
(
opt_cfg
->
len
==
0
)
continue
;
continue
;
/* reduce len for any addresses we can't substitute */
for
(
a
=
(
struct
in6_addr
*
)
opt_cfg
->
val
,
len
=
opt_cfg
->
len
,
i
=
0
;
i
<
opt_cfg
->
len
;
i
+=
IN6ADDRSZ
,
a
++
)
if
((
IN6_IS_ADDR_UNSPECIFIED
(
a
)
&&
parm
.
glob_pref_time
==
0
)
||
(
IN6_IS_ADDR_ULA_ZERO
(
a
)
&&
parm
.
ula_pref_time
==
0
)
||
(
IN6_IS_ADDR_LINK_LOCAL_ZERO
(
a
)
&&
parm
.
link_pref_time
==
0
))
len
-=
IN6ADDRSZ
;
if
(
len
!=
0
)
{
put_opt6_char
(
ICMP6_OPT_RDNSS
);
put_opt6_char
(
ICMP6_OPT_RDNSS
);
put_opt6_char
((
opt_cfg
->
len
/
8
)
+
1
);
put_opt6_char
((
len
/
8
)
+
1
);
put_opt6_short
(
0
);
put_opt6_short
(
0
);
put_opt6_long
(
parm
.
pref_time
);
put_opt6_long
(
min_
pref_time
);
/* zero means "self" */
for
(
i
=
0
;
i
<
opt_cfg
->
len
;
i
+=
IN6ADDRSZ
,
a
++
)
for
(
a
=
(
struct
in6_addr
*
)
opt_cfg
->
val
,
i
=
0
;
i
<
opt_cfg
->
len
;
i
+=
IN6ADDRSZ
,
a
++
)
if
(
IN6_IS_ADDR_UNSPECIFIED
(
a
))
if
(
IN6_IS_ADDR_UNSPECIFIED
(
a
))
{
if
(
parm
.
glob_pref_time
!=
0
)
put_opt6
(
&
parm
.
link_global
,
IN6ADDRSZ
);
put_opt6
(
&
parm
.
link_global
,
IN6ADDRSZ
);
}
else
if
(
IN6_IS_ADDR_ULA_ZERO
(
a
))
{
if
(
parm
.
ula_pref_time
!=
0
)
put_opt6
(
&
parm
.
ula
,
IN6ADDRSZ
);
}
else
if
(
IN6_IS_ADDR_LINK_LOCAL_ZERO
(
a
))
{
if
(
parm
.
link_pref_time
!=
0
)
put_opt6
(
&
parm
.
link_local
,
IN6ADDRSZ
);
}
else
else
put_opt6
(
a
,
IN6ADDRSZ
);
put_opt6
(
a
,
IN6ADDRSZ
);
}
}
}
if
(
opt_cfg
->
opt
==
OPTION6_DOMAIN_SEARCH
&&
opt_cfg
->
len
!=
0
)
if
(
opt_cfg
->
opt
==
OPTION6_DOMAIN_SEARCH
&&
opt_cfg
->
len
!=
0
)
{
{
...
@@ -365,7 +404,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
...
@@ -365,7 +404,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
put_opt6_char
(
ICMP6_OPT_DNSSL
);
put_opt6_char
(
ICMP6_OPT_DNSSL
);
put_opt6_char
(
len
+
1
);
put_opt6_char
(
len
+
1
);
put_opt6_short
(
0
);
put_opt6_short
(
0
);
put_opt6_long
(
parm
.
pref_time
);
put_opt6_long
(
min_
pref_time
);
put_opt6
(
opt_cfg
->
val
,
opt_cfg
->
len
);
put_opt6
(
opt_cfg
->
val
,
opt_cfg
->
len
);
/* pad */
/* pad */
...
@@ -374,13 +413,13 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
...
@@ -374,13 +413,13 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
}
}
}
}
if
(
daemon
->
port
==
NAMESERVER_PORT
&&
!
done_dns
&&
parm
.
pref_time
!=
0
)
if
(
daemon
->
port
==
NAMESERVER_PORT
&&
!
done_dns
&&
parm
.
link_
pref_time
!=
0
)
{
{
/* default == us, as long as we are supplying DNS service. */
/* default == us, as long as we are supplying DNS service. */
put_opt6_char
(
ICMP6_OPT_RDNSS
);
put_opt6_char
(
ICMP6_OPT_RDNSS
);
put_opt6_char
(
3
);
put_opt6_char
(
3
);
put_opt6_short
(
0
);
put_opt6_short
(
0
);
put_opt6_long
(
parm
.
pref_time
);
put_opt6_long
(
min_
pref_time
);
put_opt6
(
&
parm
.
link_local
,
IN6ADDRSZ
);
put_opt6
(
&
parm
.
link_local
,
IN6ADDRSZ
);
}
}
...
@@ -426,7 +465,16 @@ static int add_prefixes(struct in6_addr *local, int prefix,
...
@@ -426,7 +465,16 @@ static int add_prefixes(struct in6_addr *local, int prefix,
if
(
if_index
==
param
->
ind
)
if
(
if_index
==
param
->
ind
)
{
{
if
(
IN6_IS_ADDR_LINKLOCAL
(
local
))
if
(
IN6_IS_ADDR_LINKLOCAL
(
local
))
{
/* Can there be more than one LL address?
Select the one with the longest preferred time
if there is. */
if
(
preferred
>
param
->
link_pref_time
)
{
param
->
link_pref_time
=
preferred
;
param
->
link_local
=
*
local
;
param
->
link_local
=
*
local
;
}
}
else
if
(
!
IN6_IS_ADDR_LOOPBACK
(
local
)
&&
else
if
(
!
IN6_IS_ADDR_LOOPBACK
(
local
)
&&
!
IN6_IS_ADDR_MULTICAST
(
local
))
!
IN6_IS_ADDR_MULTICAST
(
local
))
{
{
...
@@ -517,11 +565,22 @@ static int add_prefixes(struct in6_addr *local, int prefix,
...
@@ -517,11 +565,22 @@ static int add_prefixes(struct in6_addr *local, int prefix,
if
(
!
constructed
||
preferred
>
time
)
if
(
!
constructed
||
preferred
>
time
)
preferred
=
time
;
preferred
=
time
;
if
(
preferred
>
param
->
pref_time
)
if
(
IN6_IS_ADDR_ULA
(
local
))
{
if
(
preferred
>
param
->
ula_pref_time
)
{
{
param
->
pref_time
=
preferred
;
param
->
ula_pref_time
=
preferred
;
param
->
ula
=
*
local
;
}
}
else
{
if
(
preferred
>
param
->
glob_pref_time
)
{
param
->
glob_pref_time
=
preferred
;
param
->
link_global
=
*
local
;
param
->
link_global
=
*
local
;
}
}
}
if
(
real_prefix
!=
0
)
if
(
real_prefix
!=
0
)
{
{
...
@@ -546,7 +605,6 @@ static int add_prefixes(struct in6_addr *local, int prefix,
...
@@ -546,7 +605,6 @@ static int add_prefixes(struct in6_addr *local, int prefix,
if
(
!
option_bool
(
OPT_QUIET_RA
))
if
(
!
option_bool
(
OPT_QUIET_RA
))
my_syslog
(
MS_DHCP
|
LOG_INFO
,
"RTR-ADVERT(%s) %s"
,
param
->
if_name
,
daemon
->
addrbuff
);
my_syslog
(
MS_DHCP
|
LOG_INFO
,
"RTR-ADVERT(%s) %s"
,
param
->
if_name
,
daemon
->
addrbuff
);
}
}
}
}
}
}
}
}
...
...
src/rfc3315.c
View file @
c3a04081
...
@@ -24,7 +24,7 @@ struct state {
...
@@ -24,7 +24,7 @@ struct state {
int
clid_len
,
iaid
,
ia_type
,
interface
,
hostname_auth
,
lease_allocate
;
int
clid_len
,
iaid
,
ia_type
,
interface
,
hostname_auth
,
lease_allocate
;
char
*
client_hostname
,
*
hostname
,
*
domain
,
*
send_domain
;
char
*
client_hostname
,
*
hostname
,
*
domain
,
*
send_domain
;
struct
dhcp_context
*
context
;
struct
dhcp_context
*
context
;
struct
in6_addr
*
link_address
,
*
fallback
;
struct
in6_addr
*
link_address
,
*
fallback
,
*
ll_addr
,
*
ula_addr
;
unsigned
int
xid
,
fqdn_flags
;
unsigned
int
xid
,
fqdn_flags
;
char
*
iface_name
;
char
*
iface_name
;
void
*
packet_options
,
*
end
;
void
*
packet_options
,
*
end
;
...
@@ -73,7 +73,8 @@ static void calculate_times(struct dhcp_context *context, unsigned int *min_time
...
@@ -73,7 +73,8 @@ static void calculate_times(struct dhcp_context *context, unsigned int *min_time
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
,
size_t
sz
,
struct
in6_addr
*
client_addr
,
time_t
now
)
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
)
{
{
struct
dhcp_vendor
*
vendor
;
struct
dhcp_vendor
*
vendor
;
int
msg_type
;
int
msg_type
;
...
@@ -93,6 +94,8 @@ unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *if
...
@@ -93,6 +94,8 @@ unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *if
state
.
interface
=
interface
;
state
.
interface
=
interface
;
state
.
iface_name
=
iface_name
;
state
.
iface_name
=
iface_name
;
state
.
fallback
=
fallback
;
state
.
fallback
=
fallback
;
state
.
ll_addr
=
ll_addr
;
state
.
ula_addr
=
ula_addr
;
state
.
mac_len
=
0
;
state
.
mac_len
=
0
;
state
.
tags
=
NULL
;
state
.
tags
=
NULL
;
state
.
link_address
=
NULL
;
state
.
link_address
=
NULL
;
...
@@ -1269,37 +1272,60 @@ static struct dhcp_netid *add_options(struct state *state, int do_refresh)
...
@@ -1269,37 +1272,60 @@ static struct dhcp_netid *add_options(struct state *state, int do_refresh)
continue
;
continue
;
}
}
if
(
opt_cfg
->
opt
==
OPTION6_DNS_SERVER
)
{
done_dns
=
1
;
if
(
opt_cfg
->
len
==
0
)
continue
;
}
if
(
opt_cfg
->
opt
==
OPTION6_REFRESH_TIME
)
if
(
opt_cfg
->
opt
==
OPTION6_REFRESH_TIME
)
done_refresh
=
1
;
done_refresh
=
1
;
o
=
new_opt6
(
opt_cfg
->
opt
);
if
(
opt_cfg
->
flags
&
DHOPT_ADDR6
)
if
(
opt_cfg
->
flags
&
DHOPT_ADDR6
)
{
{
int
j
;
int
len
,
j
;
struct
in6_addr
*
a
=
(
struct
in6_addr
*
)
opt_cfg
->
val
;
struct
in6_addr
*
a
;
for
(
j
=
0
;
j
<
opt_cfg
->
len
;
j
+=
IN6ADDRSZ
,
a
++
)
if
(
opt_cfg
->
opt
==
OPTION6_DNS_SERVER
)
done_dns
=
1
;
for
(
a
=
(
struct
in6_addr
*
)
opt_cfg
->
val
,
len
=
opt_cfg
->
len
,
j
=
0
;
j
<
opt_cfg
->
len
;
j
+=
IN6ADDRSZ
,
a
++
)
if
((
IN6_IS_ADDR_ULA_ZERO
(
a
)
&&
IN6_IS_ADDR_UNSPECIFIED
(
state
->
ula_addr
))
||
(
IN6_IS_ADDR_LINK_LOCAL_ZERO
(
a
)
&&
IN6_IS_ADDR_UNSPECIFIED
(
state
->
ll_addr
)))
len
-=
IN6ADDRSZ
;
if
(
len
!=
0
)
{
o
=
new_opt6
(
opt_cfg
->
opt
);
for
(
a
=
(
struct
in6_addr
*
)
opt_cfg
->
val
,
j
=
0
;
j
<
opt_cfg
->
len
;
j
+=
IN6ADDRSZ
,
a
++
)
{
{
/* zero means "self" (but not in vendorclass options.) */
if
(
IN6_IS_ADDR_UNSPECIFIED
(
a
))
if
(
IN6_IS_ADDR_UNSPECIFIED
(
a
))
{
{
if
(
!
add_local_addrs
(
state
->
context
))
if
(
!
add_local_addrs
(
state
->
context
))
put_opt6
(
state
->
fallback
,
IN6ADDRSZ
);
put_opt6
(
state
->
fallback
,
IN6ADDRSZ
);
}
}
else
if
(
IN6_IS_ADDR_ULA_ZERO
(
a
))
{
if
(
!
IN6_IS_ADDR_UNSPECIFIED
(
state
->
ula_addr
))
put_opt6
(
state
->
ula_addr
,
IN6ADDRSZ
);
}
else
if
(
IN6_IS_ADDR_LINK_LOCAL_ZERO
(
a
))
{
if
(
!
IN6_IS_ADDR_UNSPECIFIED
(
state
->
ll_addr
))
put_opt6
(
state
->
ll_addr
,
IN6ADDRSZ
);
}
else
else
put_opt6
(
a
,
IN6ADDRSZ
);
put_opt6
(
a
,
IN6ADDRSZ
);
}
}
end_opt6
(
o
);
}
}
}
else
if
(
opt_cfg
->
val
)
else
{
o
=
new_opt6
(
opt_cfg
->
opt
);
if
(
opt_cfg
->
val
)
put_opt6
(
opt_cfg
->
val
,
opt_cfg
->
len
);
put_opt6
(
opt_cfg
->
val
,
opt_cfg
->
len
);
end_opt6
(
o
);
end_opt6
(
o
);
}
}
}
if
(
daemon
->
port
==
NAMESERVER_PORT
&&
!
done_dns
)
if
(
daemon
->
port
==
NAMESERVER_PORT
&&
!
done_dns
)
{
{
...
...
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