mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-03 13:38:32 +00:00
Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d5d35d052 | ||
|
|
843c96b4b3 | ||
|
|
58dc02ebf2 | ||
|
|
c239f7de25 | ||
|
|
ac8540c3c5 | ||
|
|
22d904db95 | ||
|
|
741c2952d4 | ||
|
|
96f6979c4f |
No files matched your search
@@ -58,6 +58,12 @@ version 2.60
|
||||
tested alpha code, it is NOT YET PRODUCTION READY. Test
|
||||
reports would be greatly valued.
|
||||
|
||||
Support IPv6 router advertisements. This is a
|
||||
simple-minded implementation, aimed at providing the
|
||||
vestigial RA needed to go alongside IPv6. Is picks up
|
||||
configuration from the DHCPv6 conf, and should just need
|
||||
enabling with --enable-ra.
|
||||
|
||||
|
||||
version 2.59
|
||||
Fix regression in 2.58 which caused failure to start up
|
||||
|
||||
@@ -50,8 +50,8 @@ OBJS = cache.o rfc1035.o util.o option.o forward.o network.o \
|
||||
helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o \
|
||||
dhcp-common.o outpacket.o radv.o
|
||||
|
||||
HDRS = dnsmasq.h config.h dhcp_protocol.h dhcp6_protocol.h \
|
||||
dns_protocol.h radv_protocol.h
|
||||
HDRS = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
|
||||
dns-protocol.h radv-protocol.h
|
||||
|
||||
|
||||
all : $(BUILDDIR)
|
||||
|
||||
+2
-2
@@ -18,10 +18,10 @@ elif grep '\$Format:%d\$' VERSION >/dev/null 2>&1; then
|
||||
# unsubstituted VERSION, but no git available.
|
||||
echo UNKNOWN
|
||||
else
|
||||
vers=`cat VERSION | sed 's/[(), ]/\n/ g' | grep $v[0-9] | head -n 1`
|
||||
vers=`cat VERSION | sed 's/[(), ]/,/ g' | tr ',' '\n' | grep $v[0-9]`
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo ${vers#v}
|
||||
echo "${vers}" | head -n 1 | tail -c +2
|
||||
else
|
||||
cat VERSION
|
||||
fi
|
||||
|
||||
@@ -157,6 +157,13 @@
|
||||
# an explicit netmask instead.
|
||||
#dhcp-range=192.168.0.0,static
|
||||
|
||||
# Enable DHCPv6. Note that the prefix-length does not need to be specified
|
||||
# and defaults to 64 if missing/
|
||||
#dhcp-range=1234::2, 1234::500, 64, 12h
|
||||
|
||||
# Not Router Advertisements, BUT NOT DHCP for this subnet.
|
||||
#dhcp-range=1234::, ra-only
|
||||
|
||||
# Supply parameters for specified hosts using DHCP. There are lots
|
||||
# of valid alternatives, so we will give examples of each. Note that
|
||||
# IP addresses DO NOT have to be in the range given above, they just
|
||||
@@ -219,6 +226,12 @@
|
||||
# any machine with Ethernet address starting 11:22:33:
|
||||
#dhcp-host=11:22:33:*:*:*,set:red
|
||||
|
||||
# Give a fixed IPv6 address and name to client with
|
||||
# DUID 00:01:00:01:16:d2:83:fc:92:d4:19:e2:d8:b2
|
||||
# Note the MAC addresses CANNOT be used to identify DHCPv6 clients.
|
||||
# Note also the they [] around the IPv6 address are obilgatory.
|
||||
#dhcp-host=id:00:01:00:01:16:d2:83:fc:92:d4:19:e2:d8:b2, fred, [1234::5]
|
||||
|
||||
# Ignore any clients which are not specified in dhcp-host lines
|
||||
# or /etc/ethers. Equivalent to ISC "deny unknown-clients".
|
||||
# This relies on the special "known" tag which is set when
|
||||
@@ -270,6 +283,9 @@
|
||||
# Set the NTP time server addresses to 192.168.0.4 and 10.10.0.5
|
||||
#dhcp-option=option:ntp-server,192.168.0.4,10.10.0.5
|
||||
|
||||
# Send DHCPv6 option. Note [] around IPv6 addresses.
|
||||
dhcp-option=option6:dns-server,[1234::77],[1234::88]
|
||||
|
||||
# Set the NTP time server address to be the same machine as
|
||||
# is running dnsmasq
|
||||
#dhcp-option=42,0.0.0.0
|
||||
|
||||
@@ -358,4 +358,90 @@ void dhcp_update_configs(struct dhcp_config *configs)
|
||||
|
||||
}
|
||||
|
||||
#ifdef HAVE_DHCP6
|
||||
static int join_multicast_worker(struct in6_addr *local, int prefix,
|
||||
int scope, int if_index, int dad, void *vparam)
|
||||
{
|
||||
char ifrn_name[IFNAMSIZ];
|
||||
struct ipv6_mreq mreq;
|
||||
int fd, i, max = *((int *)vparam);
|
||||
struct dhcp_context *context;
|
||||
struct iname *tmp;
|
||||
|
||||
(void)prefix;
|
||||
(void)scope;
|
||||
(void)dad;
|
||||
|
||||
/* record which interfaces we join on, so that we do it at most one per
|
||||
interface, even when they have multiple addresses. Use outpacket
|
||||
as an array of int, since it's always allocated here and easy
|
||||
to expand for theoretical vast numbers of interfaces. */
|
||||
for (i = 0; i < max; i++)
|
||||
if (if_index == ((int *)daemon->outpacket.iov_base)[i])
|
||||
return 1;
|
||||
|
||||
if ((fd = socket(PF_INET6, SOCK_DGRAM, 0)) == -1)
|
||||
return 0;
|
||||
|
||||
if (!indextoname(fd, if_index, ifrn_name))
|
||||
{
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
/* Are we doing DHCP on this interface? */
|
||||
if (!iface_check(AF_INET6, (struct all_addr *)local, ifrn_name))
|
||||
return 1;
|
||||
|
||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||
if (tmp->name && (strcmp(tmp->name, ifrn_name) == 0))
|
||||
return 1;
|
||||
|
||||
/* weird libvirt-inspired access control */
|
||||
for (context = daemon->dhcp6; context; context = context->next)
|
||||
if (!context->interface || strcmp(context->interface, ifrn_name) == 0)
|
||||
break;
|
||||
|
||||
if (!context)
|
||||
return 1;
|
||||
|
||||
mreq.ipv6mr_interface = if_index;
|
||||
|
||||
inet_pton(AF_INET6, ALL_RELAY_AGENTS_AND_SERVERS, &mreq.ipv6mr_multiaddr);
|
||||
|
||||
if (daemon->dhcp6 &&
|
||||
setsockopt(daemon->dhcp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
|
||||
return 0;
|
||||
|
||||
inet_pton(AF_INET6, ALL_SERVERS, &mreq.ipv6mr_multiaddr);
|
||||
|
||||
if (daemon->dhcp6 &&
|
||||
setsockopt(daemon->dhcp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
|
||||
return 0;
|
||||
|
||||
inet_pton(AF_INET6, ALL_ROUTERS, &mreq.ipv6mr_multiaddr);
|
||||
|
||||
if (daemon->ra_contexts &&
|
||||
setsockopt(daemon->icmp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
|
||||
return 0;
|
||||
|
||||
expand_buf(&daemon->outpacket, (max+1) * sizeof(int));
|
||||
((int *)daemon->outpacket.iov_base)[max++] = if_index;
|
||||
|
||||
*((int *)vparam) = max;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void join_multicast(void)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
if (!iface_enumerate(AF_INET6, &count, join_multicast_worker))
|
||||
die(_("failed to join DHCPv6 multicast group: %s"), NULL, EC_BADNET);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File renamed without changes.
File renamed without changes.
-88
@@ -24,14 +24,6 @@ struct iface_param {
|
||||
int ind;
|
||||
};
|
||||
|
||||
struct listen_param {
|
||||
int fd_or_iface;
|
||||
struct listen_param *next;
|
||||
};
|
||||
|
||||
static int join_multicast(struct in6_addr *local, int prefix,
|
||||
int scope, int if_index, int dad, void *vparam);
|
||||
|
||||
static int complete_context6(struct in6_addr *local, int prefix,
|
||||
int scope, int if_index, int dad, void *vparam);
|
||||
|
||||
@@ -41,7 +33,6 @@ void dhcp6_init(void)
|
||||
{
|
||||
int fd;
|
||||
struct sockaddr_in6 saddr;
|
||||
struct listen_param *listenp, listen;
|
||||
#if defined(IP_TOS) && defined(IPTOS_CLASS_CS6)
|
||||
int class = IPTOS_CLASS_CS6;
|
||||
#endif
|
||||
@@ -65,88 +56,9 @@ void dhcp6_init(void)
|
||||
if (bind(fd, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in6)))
|
||||
die(_("failed to bind DHCPv6 server socket: %s"), NULL, EC_BADNET);
|
||||
|
||||
/* join multicast groups on each interface we're interested in */
|
||||
listen.fd_or_iface = fd;
|
||||
listen.next = NULL;
|
||||
if (!iface_enumerate(AF_INET6, &listen, join_multicast))
|
||||
die(_("failed to join DHCPv6 multicast group: %s"), NULL, EC_BADNET);
|
||||
for (listenp = listen.next; listenp; )
|
||||
{
|
||||
struct listen_param *tmp = listenp->next;
|
||||
free(listenp);
|
||||
listenp = tmp;
|
||||
}
|
||||
|
||||
daemon->dhcp6fd = fd;
|
||||
}
|
||||
|
||||
static int join_multicast(struct in6_addr *local, int prefix,
|
||||
int scope, int if_index, int dad, void *vparam)
|
||||
{
|
||||
char ifrn_name[IFNAMSIZ];
|
||||
struct ipv6_mreq mreq;
|
||||
struct listen_param *listenp, *param = vparam;
|
||||
int fd = param->fd_or_iface;
|
||||
struct dhcp_context *context;
|
||||
struct iname *tmp;
|
||||
|
||||
(void)prefix;
|
||||
(void)scope;
|
||||
(void)dad;
|
||||
|
||||
/* record which interfaces we join on, so
|
||||
that we do it at most one per interface, even when they
|
||||
have multiple addresses */
|
||||
for (listenp = param->next; listenp; listenp = listenp->next)
|
||||
if (if_index == listenp->fd_or_iface)
|
||||
return 1;
|
||||
|
||||
if (!indextoname(fd, if_index, ifrn_name))
|
||||
return 0;
|
||||
|
||||
/* Are we doing DHCP on this interface? */
|
||||
if (!iface_check(AF_INET6, (struct all_addr *)local, ifrn_name))
|
||||
return 1;
|
||||
|
||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||
if (tmp->name && (strcmp(tmp->name, ifrn_name) == 0))
|
||||
return 1;
|
||||
|
||||
/* weird libvirt-inspired access control */
|
||||
for (context = daemon->dhcp6; context; context = context->next)
|
||||
if (!context->interface || strcmp(context->interface, ifrn_name) == 0)
|
||||
break;
|
||||
|
||||
if (!context)
|
||||
return 1;
|
||||
|
||||
mreq.ipv6mr_interface = if_index;
|
||||
|
||||
inet_pton(AF_INET6, ALL_RELAY_AGENTS_AND_SERVERS, &mreq.ipv6mr_multiaddr);
|
||||
|
||||
if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
|
||||
return 0;
|
||||
|
||||
inet_pton(AF_INET6, ALL_SERVERS, &mreq.ipv6mr_multiaddr);
|
||||
|
||||
if (setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
|
||||
return 0;
|
||||
|
||||
inet_pton(AF_INET6, ALL_ROUTERS, &mreq.ipv6mr_multiaddr);
|
||||
|
||||
if (daemon->icmp6fd != -1 &&
|
||||
setsockopt(daemon->icmp6fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1)
|
||||
return 0;
|
||||
|
||||
listenp = whine_malloc(sizeof(struct listen_param));
|
||||
listenp->fd_or_iface = if_index;
|
||||
listenp->next = param->next;
|
||||
param->next = listenp;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void dhcp6_packet(time_t now)
|
||||
{
|
||||
struct dhcp_context *context;
|
||||
|
||||
File renamed without changes.
+60
-17
@@ -154,24 +154,41 @@ int main (int argc, char **argv)
|
||||
before lease_init to allocate buffers it uses.*/
|
||||
dhcp_common_init();
|
||||
lease_init(now);
|
||||
|
||||
if (daemon->dhcp)
|
||||
dhcp_init();
|
||||
#ifdef HAVE_DHCP6
|
||||
daemon->icmp6fd = -1;
|
||||
if (daemon->dhcp6)
|
||||
{
|
||||
/* ra_init before dhcp6_init, so dhcp6_init can setup multicast listening */
|
||||
if (option_bool(OPT_RA))
|
||||
ra_init(now);
|
||||
dhcp6_init();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
# ifdef HAVE_DHCP6
|
||||
/* Start RA subsystem if --enable-ra OR dhcp-range=<subnet>, ra-only */
|
||||
if (daemon->ra_contexts || option_bool(OPT_RA))
|
||||
{
|
||||
/* link the DHCP6 contexts to the ra-only ones so we can traverse them all
|
||||
from ->ra_contexts, but only the non-ra-onlies from ->dhcp6 */
|
||||
struct dhcp_context *context;
|
||||
|
||||
if (!daemon->ra_contexts)
|
||||
daemon->ra_contexts = daemon->dhcp6;
|
||||
else
|
||||
{
|
||||
for (context = daemon->ra_contexts; context->next; context = context->next);
|
||||
context->next = daemon->dhcp6;
|
||||
}
|
||||
ra_init(now);
|
||||
}
|
||||
|
||||
if (daemon->dhcp6)
|
||||
dhcp6_init();
|
||||
|
||||
if (daemon->ra_contexts || daemon->dhcp6)
|
||||
join_multicast();
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
if (!enumerate_interfaces())
|
||||
die(_("failed to find list of interfaces: %s"), NULL, EC_MISC);
|
||||
|
||||
|
||||
if (option_bool(OPT_NOWILD))
|
||||
{
|
||||
create_bound_listeners(1);
|
||||
@@ -211,7 +228,8 @@ int main (int argc, char **argv)
|
||||
|
||||
#if defined(HAVE_SCRIPT)
|
||||
/* Note getpwnam returns static storage */
|
||||
if ((daemon->dhcp || daemon->dhcp6) && daemon->scriptuser &&
|
||||
if ((daemon->dhcp || daemon->dhcp6) &&
|
||||
daemon->scriptuser &&
|
||||
(daemon->lease_change_command || daemon->luascript))
|
||||
{
|
||||
if ((ent_pw = getpwnam(daemon->scriptuser)))
|
||||
@@ -502,7 +520,7 @@ int main (int argc, char **argv)
|
||||
if (daemon->max_logs != 0)
|
||||
my_syslog(LOG_INFO, _("asynchronous logging enabled, queue limit is %d messages"), daemon->max_logs);
|
||||
|
||||
if (option_bool(OPT_RA))
|
||||
if (daemon->ra_contexts)
|
||||
my_syslog(MS_DHCP | LOG_INFO, _("IPv6 router advertisement enabled"));
|
||||
|
||||
#ifdef HAVE_DHCP
|
||||
@@ -668,7 +686,7 @@ int main (int argc, char **argv)
|
||||
FD_SET(daemon->dhcp6fd, &rset);
|
||||
bump_maxfd(daemon->dhcp6fd, &maxfd);
|
||||
|
||||
if (daemon->icmp6fd != -1)
|
||||
if (daemon->ra_contexts)
|
||||
{
|
||||
FD_SET(daemon->icmp6fd, &rset);
|
||||
bump_maxfd(daemon->icmp6fd, &maxfd);
|
||||
@@ -777,7 +795,7 @@ int main (int argc, char **argv)
|
||||
if (FD_ISSET(daemon->dhcp6fd, &rset))
|
||||
dhcp6_packet(now);
|
||||
|
||||
if (daemon->icmp6fd != -1 && FD_ISSET(daemon->icmp6fd, &rset))
|
||||
if (daemon->ra_contexts && FD_ISSET(daemon->icmp6fd, &rset))
|
||||
icmp6_packet();
|
||||
}
|
||||
#endif
|
||||
@@ -831,6 +849,11 @@ static void sig_handler(int sig)
|
||||
}
|
||||
}
|
||||
|
||||
void send_alarm(void)
|
||||
{
|
||||
send_event(pipewrite, EVENT_ALARM, 0, NULL);
|
||||
}
|
||||
|
||||
void send_event(int fd, int event, int data, char *msg)
|
||||
{
|
||||
struct event_desc ev;
|
||||
@@ -948,6 +971,16 @@ static void async_event(int pipe, time_t now)
|
||||
lease_prune(NULL, now);
|
||||
lease_update_file(now);
|
||||
}
|
||||
#ifdef HAVE_DHCP6
|
||||
else if (daemon->ra_contexts)
|
||||
{
|
||||
/* Not doing DHCP, so no lease system, manage
|
||||
alarms for ra only */
|
||||
time_t next_event = periodic_ra(now);
|
||||
if (next_event != 0)
|
||||
alarm((unsigned)difftime(next_event, now));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
|
||||
@@ -1112,6 +1145,16 @@ void clear_cache_and_reload(time_t now)
|
||||
lease_update_file(now);
|
||||
lease_update_dns();
|
||||
}
|
||||
#ifdef HAVE_DHCP6
|
||||
else if (daemon->ra_contexts)
|
||||
{
|
||||
/* Not doing DHCP, so no lease system, manage
|
||||
alarms for ra only */
|
||||
time_t next_event = periodic_ra(now);
|
||||
if (next_event != 0)
|
||||
alarm((unsigned)difftime(next_event, now));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1397,7 +1440,7 @@ int icmp_ping(struct in_addr addr)
|
||||
set_log_writer(&wset, &maxfd);
|
||||
|
||||
#ifdef HAVE_DHCP6
|
||||
if (daemon->icmp6fd != -1)
|
||||
if (daemon->ra_contexts)
|
||||
{
|
||||
FD_SET(daemon->icmp6fd, &rset);
|
||||
bump_maxfd(daemon->icmp6fd, &maxfd);
|
||||
@@ -1416,7 +1459,7 @@ int icmp_ping(struct in_addr addr)
|
||||
check_dns_listeners(&rset, now);
|
||||
|
||||
#ifdef HAVE_DHCP6
|
||||
if (daemon->icmp6fd != -1 && FD_ISSET(daemon->icmp6fd, &rset))
|
||||
if (daemon->ra_contexts && FD_ISSET(daemon->icmp6fd, &rset))
|
||||
icmp6_packet();
|
||||
#endif
|
||||
|
||||
|
||||
+8
-4
@@ -56,11 +56,11 @@ typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long long u64;
|
||||
|
||||
#include "dns_protocol.h"
|
||||
#include "dhcp_protocol.h"
|
||||
#include "dns-protocol.h"
|
||||
#include "dhcp-protocol.h"
|
||||
#ifdef HAVE_DHCP6
|
||||
#include "dhcp6_protocol.h"
|
||||
#include "radv_protocol.h"
|
||||
#include "dhcp6-protocol.h"
|
||||
#include "radv-protocol.h"
|
||||
#endif
|
||||
|
||||
#define gettext_noop(S) (S)
|
||||
@@ -967,6 +967,7 @@ unsigned char *extended_hwaddr(int hwtype, int hwlen, unsigned char *hwaddr,
|
||||
int make_icmp_sock(void);
|
||||
int icmp_ping(struct in_addr addr);
|
||||
#endif
|
||||
void send_alarm(void);
|
||||
void send_event(int fd, int event, int data, char *msg);
|
||||
void clear_cache_and_reload(time_t now);
|
||||
void poll_resolv(int force, int do_reload, time_t now);
|
||||
@@ -1058,6 +1059,9 @@ void log_tags(struct dhcp_netid *netid, u32 xid);
|
||||
int match_bytes(struct dhcp_opt *o, unsigned char *p, int len);
|
||||
void dhcp_update_configs(struct dhcp_config *configs);
|
||||
void check_dhcp_hosts(int fatal);
|
||||
# ifdef HAVE_DHCP6
|
||||
void join_multicast(void);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* outpacket.c */
|
||||
|
||||
@@ -106,8 +106,11 @@ void send_from(int fd, int nowild, char *packet, size_t len,
|
||||
msg.msg_controllen = 0;
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (retry_send())
|
||||
goto retry;
|
||||
|
||||
my_syslog(LOG_ERR, _("failed to send packet: %s"), strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -317,7 +317,7 @@ void lease_update_file(time_t now)
|
||||
|
||||
#ifdef HAVE_DHCP6
|
||||
/* do timed RAs and determine when the next is */
|
||||
if (option_bool(OPT_RA))
|
||||
if (daemon->ra_contexts)
|
||||
next_event = periodic_ra(now);
|
||||
#endif
|
||||
|
||||
|
||||
+2
-2
@@ -343,12 +343,12 @@ static void nl_routechange(struct nlmsghdr *h)
|
||||
|
||||
#ifdef HAVE_DHCP6
|
||||
/* force RAs to sync new network and pick up new interfaces. */
|
||||
if (option_bool(OPT_RA))
|
||||
if (daemon->ra_contexts)
|
||||
{
|
||||
ra_start_unsolicted(dnsmasq_time());
|
||||
/* cause lease_update_file to run after we return, in case we were called from
|
||||
iface_enumerate and can't re-enter it now */
|
||||
alarm(1);
|
||||
send_alarm();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2421,6 +2421,16 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_DHCP6
|
||||
/* lifetimes must be min 2 hrs, by RFC 2462.
|
||||
This gets enforced in radv.c for DHCP ranges
|
||||
which are legitimately less. */
|
||||
if ((new->flags & CONTEXT_RA_ONLY) &&
|
||||
new->lease_time < 7200)
|
||||
new->lease_time = 7200;
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
File renamed without changes.
+15
-22
@@ -15,15 +15,17 @@
|
||||
*/
|
||||
|
||||
|
||||
/* NB. This code may be called during a DHCPv4 transaction which is in ping-wait
|
||||
/* NB. This code may be called during a DHCPv4 or transaction which is in ping-wait
|
||||
It therefore cannot use any DHCP buffer resources except outpacket, which is
|
||||
not used by DHCPv4 code. */
|
||||
not used by DHCPv4 code. This code may also be called when DHCP 4 or 6 isn't
|
||||
active, so we ensure that outpacket is allocated here too */
|
||||
|
||||
#include "dnsmasq.h"
|
||||
#include <netinet/icmp6.h>
|
||||
|
||||
#ifdef HAVE_DHCP6
|
||||
|
||||
#include <netinet/icmp6.h>
|
||||
|
||||
struct ra_param {
|
||||
int ind, managed, found_context, first;
|
||||
char *if_name;
|
||||
@@ -46,7 +48,6 @@ static time_t ra_short_period_start;
|
||||
|
||||
void ra_init(time_t now)
|
||||
{
|
||||
struct dhcp_context *context;
|
||||
struct icmp6_filter filter;
|
||||
int fd;
|
||||
#if defined(IP_TOS) && defined(IPTOS_CLASS_CS6)
|
||||
@@ -55,6 +56,9 @@ void ra_init(time_t now)
|
||||
int val = 255; /* radvd uses this value */
|
||||
size_t len = sizeof(int);
|
||||
|
||||
/* ensure this is around even if we're not doing DHCPv6 */
|
||||
expand_buf(&daemon->outpacket, sizeof(struct dhcp_packet));
|
||||
|
||||
ICMP6_FILTER_SETBLOCKALL(&filter);
|
||||
ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter);
|
||||
ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
|
||||
@@ -73,19 +77,6 @@ void ra_init(time_t now)
|
||||
|
||||
daemon->icmp6fd = fd;
|
||||
|
||||
/* link the DHCP6 contexts to the ra-only ones so we can traverse them all
|
||||
from ->ra_contexts, but only the non-ra-onlies from ->dhcp6 */
|
||||
if (!daemon->ra_contexts)
|
||||
daemon->ra_contexts = daemon->dhcp6;
|
||||
else
|
||||
{
|
||||
for (context = daemon->ra_contexts; context->next; context = context->next);
|
||||
context->next = daemon->dhcp6;
|
||||
}
|
||||
|
||||
if (!daemon->dhcp6)
|
||||
die(_("cannot do router advertisement unless DHCPv6 is enabled"), NULL, EC_BADCONF);
|
||||
|
||||
ra_start_unsolicted(now);
|
||||
}
|
||||
|
||||
@@ -102,8 +93,7 @@ void ra_start_unsolicted(time_t now)
|
||||
for (context = daemon->ra_contexts; context; context = context->next)
|
||||
context->ra_time = now + (rand16()/13000);
|
||||
|
||||
/* re-do ras after a short time, in case the first gets lost.
|
||||
This is reset once that's done. */
|
||||
/* re-do frequently for a minute or so, in case the first gets lost. */
|
||||
ra_short_period_start = now;
|
||||
}
|
||||
|
||||
@@ -241,6 +231,9 @@ static void send_ra(int iface, char *iface_name, struct in6_addr *dest)
|
||||
|
||||
/* decide where we're sending */
|
||||
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);
|
||||
if (dest)
|
||||
@@ -251,8 +244,8 @@ static void send_ra(int iface, char *iface_name, struct in6_addr *dest)
|
||||
addr.sin6_scope_id = iface;
|
||||
}
|
||||
else
|
||||
inet_pton(AF_INET6, ALL_HOSTS, &addr.sin6_addr);
|
||||
|
||||
inet_pton(AF_INET6, ALL_HOSTS, &addr.sin6_addr);
|
||||
|
||||
send_from(daemon->icmp6fd, 0, daemon->outpacket.iov_base, save_counter(0),
|
||||
(union mysockaddr *)&addr, (struct all_addr *)&parm.link_local, iface);
|
||||
|
||||
@@ -399,7 +392,7 @@ static int iface_search(struct in6_addr *local, int prefix,
|
||||
int scope, int if_index, int dad, void *vparam)
|
||||
{
|
||||
struct search_param *param = vparam;
|
||||
struct dhcp_context *context, *tmp;
|
||||
struct dhcp_context *context;
|
||||
|
||||
(void)scope;
|
||||
(void)dad;
|
||||
|
||||
+4
-4
@@ -1341,19 +1341,19 @@ static void log6_packet(char *type, unsigned char *clid, int clid_len, struct in
|
||||
daemon->dhcp_buff2[0] = 0;
|
||||
|
||||
if(option_bool(OPT_LOG_OPTS))
|
||||
my_syslog(MS_DHCP | LOG_INFO, "%u %s(%s) %s %s%s",
|
||||
my_syslog(MS_DHCP | LOG_INFO, "%u %s(%s) %s%s %s",
|
||||
xid,
|
||||
type,
|
||||
iface,
|
||||
daemon->namebuff,
|
||||
daemon->dhcp_buff2,
|
||||
daemon->namebuff,
|
||||
string ? string : "");
|
||||
else
|
||||
my_syslog(MS_DHCP | LOG_INFO, "%s(%s) %s %s%s",
|
||||
my_syslog(MS_DHCP | LOG_INFO, "%s(%s) %s%s %s",
|
||||
type,
|
||||
iface,
|
||||
daemon->namebuff,
|
||||
daemon->dhcp_buff2,
|
||||
daemon->namebuff,
|
||||
string ? string : "");
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user