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
1ee9be4c
Commit
1ee9be4c
authored
Dec 09, 2013
by
Simon Kelley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement dynamic interface discovery on *BSD
parent
56ad6c9b
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
160 additions
and
43 deletions
+160
-43
CHANGELOG
CHANGELOG
+7
-0
src/bpf.c
src/bpf.c
+102
-4
src/dhcp6.c
src/dhcp6.c
+0
-1
src/dnsmasq.c
src/dnsmasq.c
+16
-8
src/dnsmasq.h
src/dnsmasq.h
+7
-1
src/netlink.c
src/netlink.c
+2
-27
src/network.c
src/network.c
+26
-2
No files found.
CHANGELOG
View file @
1ee9be4c
version 2.69
Implement dynamic interface discovery on *BSD. This allows
the contructor: syntax to be used in dhcp-range for DHCPv6
on the BSD platform. Thanks to Matthias Andree for
valuable research on how to implement this.
version 2.68
Use random addresses for DHCPv6 temporary address
allocations, instead of algorithmically determined stable
...
...
src/bpf.c
View file @
1ee9be4c
...
...
@@ -19,9 +19,9 @@
#if defined(HAVE_BSD_NETWORK) || defined(HAVE_SOLARIS_NETWORK)
#include <ifaddrs.h>
#if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
#include <sys/param.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/route.h>
#include <net/if_dl.h>
#include <netinet/if_ether.h>
...
...
@@ -29,7 +29,9 @@
# include <net/if_var.h>
#endif
#include <netinet/in_var.h>
#include <netinet6/in6_var.h>
#ifdef HAVE_IPV6
# include <netinet6/in6_var.h>
#endif
#ifndef SA_SIZE
#define SA_SIZE(sa) \
...
...
@@ -38,6 +40,13 @@
1 + ( (((struct sockaddr *)(sa))->sa_len - 1) | (sizeof(long) - 1) ) )
#endif
#ifdef HAVE_BSD_NETWORK
static
int
del_family
=
0
;
static
struct
all_addr
del_addr
;
#endif
#if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
int
arp_enumerate
(
void
*
parm
,
int
(
*
callback
)())
{
int
mib
[
6
];
...
...
@@ -88,7 +97,7 @@ int arp_enumerate(void *parm, int (*callback)())
return
1
;
}
#endif
#endif
/* defined(HAVE_BSD_NETWORK) && !defined(__APPLE__) */
int
iface_enumerate
(
int
family
,
void
*
parm
,
int
(
*
callback
)())
...
...
@@ -129,6 +138,10 @@ int iface_enumerate(int family, void *parm, int (*callback)())
{
struct
in_addr
addr
,
netmask
,
broadcast
;
addr
=
((
struct
sockaddr_in
*
)
addrs
->
ifa_addr
)
->
sin_addr
;
#ifdef HAVE_BSD_NETWORK
if
(
del_family
==
AF_INET
&&
del_addr
.
addr
.
addr4
.
s_addr
==
addr
.
s_addr
)
continue
;
#endif
netmask
=
((
struct
sockaddr_in
*
)
addrs
->
ifa_netmask
)
->
sin_addr
;
if
(
addrs
->
ifa_broadaddr
)
broadcast
=
((
struct
sockaddr_in
*
)
addrs
->
ifa_broadaddr
)
->
sin_addr
;
...
...
@@ -146,6 +159,10 @@ int iface_enumerate(int family, void *parm, int (*callback)())
int
i
,
j
,
prefix
=
0
;
u32
valid
=
0xffffffff
,
preferred
=
0xffffffff
;
int
flags
=
0
;
#ifdef HAVE_BSD_NETWORK
if
(
del_family
==
AF_INET6
&&
IN6_ARE_ADDR_EQUAL
(
&
del_addr
.
addr
.
addr6
,
addr
))
continue
;
#endif
#if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
struct
in6_ifreq
ifr6
;
...
...
@@ -226,7 +243,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
return
ret
;
}
#endif
#endif
/* defined(HAVE_BSD_NETWORK) || defined(HAVE_SOLARIS_NETWORK) */
#if defined(HAVE_BSD_NETWORK) && defined(HAVE_DHCP)
...
...
@@ -345,6 +362,87 @@ void send_via_bpf(struct dhcp_packet *mess, size_t len,
while
(
writev
(
daemon
->
dhcp_raw_fd
,
iov
,
4
)
==
-
1
&&
retry_send
());
}
#endif
/* defined(HAVE_BSD_NETWORK) && defined(HAVE_DHCP) */
#ifdef HAVE_BSD_NETWORK
void
route_init
(
void
)
{
/* AF_UNSPEC: all addr families */
daemon
->
routefd
=
socket
(
PF_ROUTE
,
SOCK_RAW
,
AF_UNSPEC
);
if
(
daemon
->
routefd
==
-
1
||
!
fix_fd
(
daemon
->
routefd
))
die
(
_
(
"cannot create PF_ROUTE socket: %s"
),
NULL
,
EC_BADNET
);
}
void
route_sock
(
time_t
now
)
{
struct
if_msghdr
*
msg
;
int
rc
=
recv
(
daemon
->
routefd
,
daemon
->
packet
,
daemon
->
packet_buff_sz
,
0
);
if
(
rc
<
4
)
return
;
msg
=
(
struct
if_msghdr
*
)
daemon
->
packet
;
if
(
rc
<
msg
->
ifm_msglen
)
return
;
if
(
msg
->
ifm_version
!=
RTM_VERSION
)
{
static
int
warned
=
0
;
if
(
!
warned
)
{
my_syslog
(
LOG_WARNING
,
_
(
"Unknown protocol version from route socket"
));
warned
=
1
;
}
}
else
if
(
msg
->
ifm_type
==
RTM_NEWADDR
)
{
del_family
=
0
;
newaddress
(
now
);
}
else
if
(
msg
->
ifm_type
==
RTM_DELADDR
)
{
/* There's a race in the kernel, such that if we run iface_enumerate() immediately
we get a DELADDR event, the deleted address still appears. Here we store the deleted address
in a static variable, and omit it from the set returned by iface_enumerate() */
int
mask
=
((
struct
ifa_msghdr
*
)
msg
)
->
ifam_addrs
;
int
maskvec
[]
=
{
RTA_DST
,
RTA_GATEWAY
,
RTA_NETMASK
,
RTA_GENMASK
,
RTA_IFP
,
RTA_IFA
,
RTA_AUTHOR
,
RTA_BRD
};
int
of
;
unsigned
int
i
;
for
(
i
=
0
,
of
=
sizeof
(
struct
ifa_msghdr
);
of
<
rc
&&
i
<
sizeof
(
maskvec
)
/
sizeof
(
maskvec
[
0
]);
i
++
)
if
(
mask
&
maskvec
[
i
])
{
struct
sockaddr
*
sa
=
(
struct
sockaddr
*
)((
char
*
)
msg
+
of
);
size_t
diff
=
(
sa
->
sa_len
!=
0
)
?
sa
->
sa_len
:
sizeof
(
long
);
if
(
maskvec
[
i
]
==
RTA_IFA
)
{
del_family
=
sa
->
sa_family
;
if
(
del_family
==
AF_INET
)
del_addr
.
addr
.
addr4
=
((
struct
sockaddr_in
*
)
sa
)
->
sin_addr
;
#ifdef HAVE_IPV6
else
if
(
del_family
==
AF_INET6
)
del_addr
.
addr
.
addr6
=
((
struct
sockaddr_in6
*
)
sa
)
->
sin6_addr
;
#endif
else
del_family
=
0
;
}
of
+=
diff
;
/* round up as needed */
if
(
diff
&
(
sizeof
(
long
)
-
1
))
of
+=
sizeof
(
long
)
-
(
diff
&
(
sizeof
(
long
)
-
1
));
}
newaddress
(
now
);
}
}
#endif
/* HAVE_BSD_NETWORK */
src/dhcp6.c
View file @
1ee9be4c
...
...
@@ -720,7 +720,6 @@ void dhcp_construct_contexts(time_t now)
if
(
context
->
flags
&
CONTEXT_GC
&&
!
(
context
->
flags
&
CONTEXT_OLD
))
{
if
((
context
->
flags
&
(
CONTEXT_RA_ONLY
|
CONTEXT_RA_NAME
|
CONTEXT_RA_STATELESS
))
||
option_bool
(
OPT_RA
))
{
...
...
src/dnsmasq.c
View file @
1ee9be4c
...
...
@@ -182,7 +182,7 @@ int main (int argc, char **argv)
daemon
->
doing_dhcp6
=
1
;
if
(
context
->
flags
&
CONTEXT_RA
)
daemon
->
doing_ra
=
1
;
#if
ndef HAVE_LINUX_NETWORK
#if
!defined(HAVE_LINUX_NETWORK) && !defined(HAVE_BSD_NETWORK)
if
(
context
->
flags
&
CONTEXT_TEMPLATE
)
die
(
_
(
"dhcp-range constructor not available on this platform"
),
NULL
,
EC_BADCONF
);
#endif
...
...
@@ -220,13 +220,15 @@ int main (int argc, char **argv)
ipset_init
();
#endif
#if
def HAVE_LINUX_NETWORK
#if
defined(HAVE_LINUX_NETWORK)
netlink_init
();
if
(
option_bool
(
OPT_NOWILD
)
&&
option_bool
(
OPT_CLEVERBIND
))
die
(
_
(
"cannot set --bind-interfaces and --bind-dynamic"
),
NULL
,
EC_BADCONF
);
#elif defined(HAVE_BSD_NETWORK)
route_init
();
#endif
if
(
option_bool
(
OPT_NOWILD
)
&&
option_bool
(
OPT_CLEVERBIND
))
die
(
_
(
"cannot set --bind-interfaces and --bind-dynamic"
),
NULL
,
EC_BADCONF
);
if
(
!
enumerate_interfaces
(
1
)
||
!
enumerate_interfaces
(
0
))
die
(
_
(
"failed to find list of interfaces: %s"
),
NULL
,
EC_MISC
);
...
...
@@ -808,11 +810,14 @@ int main (int argc, char **argv)
}
#endif
#if
def HAVE_LINUX_NETWORK
#if
defined(HAVE_LINUX_NETWORK)
FD_SET
(
daemon
->
netlinkfd
,
&
rset
);
bump_maxfd
(
daemon
->
netlinkfd
,
&
maxfd
);
#elif defined(HAVE_BSD_NETWORK)
FD_SET
(
daemon
->
routefd
,
&
rset
);
bump_maxfd
(
daemon
->
routefd
,
&
maxfd
);
#endif
FD_SET
(
piperead
,
&
rset
);
bump_maxfd
(
piperead
,
&
maxfd
);
...
...
@@ -867,9 +872,12 @@ int main (int argc, char **argv)
warn_bound_listeners
();
}
#if
def HAVE_LINUX_NETWORK
#if
defined(HAVE_LINUX_NETWORK)
if
(
FD_ISSET
(
daemon
->
netlinkfd
,
&
rset
))
netlink_multicast
(
now
);
#elif defined(HAVE_BSD_NETWORK)
if
(
FD_ISSET
(
daemon
->
routefd
,
&
rset
))
route_sock
(
now
);
#endif
/* Check for changes to resolv files once per second max. */
...
...
src/dnsmasq.h
View file @
1ee9be4c
...
...
@@ -900,7 +900,7 @@ extern struct daemon {
#if defined(HAVE_LINUX_NETWORK)
int
netlinkfd
;
#elif defined(HAVE_BSD_NETWORK)
int
dhcp_raw_fd
,
dhcp_icmp_fd
;
int
dhcp_raw_fd
,
dhcp_icmp_fd
,
routefd
;
#endif
struct
iovec
dhcp_packet
;
char
*
dhcp_buff
,
*
dhcp_buff2
,
*
dhcp_buff3
;
...
...
@@ -1090,6 +1090,10 @@ int set_ipv6pktinfo(int fd);
#ifdef HAVE_DHCP6
void
join_multicast
(
int
dienow
);
#endif
#if defined(HAVE_LINUX_NETWORK) || defined(HAVE_BSD_NETWORK)
void
newaddress
(
time_t
now
);
#endif
/* dhcp.c */
#ifdef HAVE_DHCP
...
...
@@ -1177,6 +1181,8 @@ void netlink_multicast(time_t now);
void
init_bpf
(
void
);
void
send_via_bpf
(
struct
dhcp_packet
*
mess
,
size_t
len
,
struct
in_addr
iface_addr
,
struct
ifreq
*
ifr
);
void
route_init
(
void
);
void
route_sock
(
time_t
now
);
#endif
/* bpf.c or netlink.c */
...
...
src/netlink.c
View file @
1ee9be4c
...
...
@@ -39,7 +39,6 @@ static struct iovec iov;
static
u32
netlink_pid
;
static
int
nl_async
(
struct
nlmsghdr
*
h
);
static
void
nl_newaddress
(
time_t
now
);
void
netlink_init
(
void
)
{
...
...
@@ -203,7 +202,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
/* handle async new interface address arrivals, these have to be done
after we complete as we're not re-entrant */
if
(
newaddr
)
n
l_n
ewaddress
(
dnsmasq_time
());
newaddress
(
dnsmasq_time
());
return
callback_ok
;
}
...
...
@@ -351,7 +350,7 @@ void netlink_multicast(time_t now)
fcntl
(
daemon
->
netlinkfd
,
F_SETFL
,
flags
);
if
(
newaddr
)
n
l_n
ewaddress
(
now
);
newaddress
(
now
);
}
static
int
nl_async
(
struct
nlmsghdr
*
h
)
...
...
@@ -399,30 +398,6 @@ static int nl_async(struct nlmsghdr *h)
return
0
;
}
static
void
nl_newaddress
(
time_t
now
)
{
(
void
)
now
;
if
(
option_bool
(
OPT_CLEVERBIND
)
||
daemon
->
doing_dhcp6
||
daemon
->
relay6
||
daemon
->
doing_ra
)
enumerate_interfaces
(
0
);
if
(
option_bool
(
OPT_CLEVERBIND
))
create_bound_listeners
(
0
);
#ifdef HAVE_DHCP6
if
(
daemon
->
doing_dhcp6
||
daemon
->
relay6
||
daemon
->
doing_ra
)
join_multicast
(
0
);
if
(
daemon
->
doing_dhcp6
||
daemon
->
doing_ra
)
dhcp_construct_contexts
(
now
);
if
(
daemon
->
doing_dhcp6
)
lease_find_interfaces
(
now
);
#endif
}
#endif
src/network.c
View file @
1ee9be4c
...
...
@@ -489,7 +489,7 @@ static int iface_allowed_v6(struct in6_addr *local, int prefix,
addr
.
in6
.
sin6_scope_id
=
if_index
;
else
addr
.
in6
.
sin6_scope_id
=
0
;
return
iface_allowed
((
struct
iface_param
*
)
vparam
,
if_index
,
NULL
,
&
addr
,
netmask
,
prefix
,
!!
(
flags
&
IFACE_TENTATIVE
));
}
#endif
...
...
@@ -681,7 +681,7 @@ static int make_sock(union mysockaddr *addr, int type, int dienow)
close
(
fd
);
errno
=
errsav
;
if
(
dienow
)
{
/* failure to bind addresses given by --listen-address at this point
...
...
@@ -1470,7 +1470,31 @@ int reload_servers(char *fname)
return
gotone
;
}
#if defined(HAVE_LINUX_NETWORK) || defined(HAVE_BSD_NETWORK)
/* Called when addresses are added or deleted from an interface */
void
newaddress
(
time_t
now
)
{
(
void
)
now
;
if
(
option_bool
(
OPT_CLEVERBIND
)
||
daemon
->
doing_dhcp6
||
daemon
->
relay6
||
daemon
->
doing_ra
)
enumerate_interfaces
(
0
);
if
(
option_bool
(
OPT_CLEVERBIND
))
create_bound_listeners
(
0
);
#ifdef HAVE_DHCP6
if
(
daemon
->
doing_dhcp6
||
daemon
->
relay6
||
daemon
->
doing_ra
)
join_multicast
(
0
);
if
(
daemon
->
doing_dhcp6
||
daemon
->
doing_ra
)
dhcp_construct_contexts
(
now
);
if
(
daemon
->
doing_dhcp6
)
lease_find_interfaces
(
now
);
#endif
}
#endif
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment