1 /* dnsmasq is Copyright (c) 2000-2013 Simon Kelley
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 dated June, 1991, or
6 (at your option) version 3 dated 29 June, 2007.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 /* NB. This code may be called during a DHCPv4 or transaction which is in ping-wait
19 It therefore cannot use any DHCP buffer resources except outpacket, which is
20 not used by DHCPv4 code. This code may also be called when DHCP 4 or 6 isn't
21 active, so we ensure that outpacket is allocated here too */
27 #include <netinet/icmp6.h>
31 int ind
, managed
, other
, found_context
, first
;
33 struct dhcp_netid
*tags
;
34 struct in6_addr link_local
, link_global
;
35 unsigned int pref_time
, adv_interval
;
39 time_t now
; int iface
;
40 char name
[IF_NAMESIZE
+1];
43 static void send_ra(time_t now
, int iface
, char *iface_name
, struct in6_addr
*dest
);
44 static int add_prefixes(struct in6_addr
*local
, int prefix
,
45 int scope
, int if_index
, int flags
,
46 unsigned int preferred
, unsigned int valid
, void *vparam
);
47 static int iface_search(struct in6_addr
*local
, int prefix
,
48 int scope
, int if_index
, int flags
,
49 int prefered
, int valid
, void *vparam
);
50 static int add_lla(int index
, unsigned int type
, char *mac
, size_t maclen
, void *parm
);
51 static void new_timeout(struct dhcp_context
*context
, char *iface_name
, time_t now
);
52 static unsigned int calc_lifetime(struct ra_interface
*ra
);
53 static unsigned int calc_interval(struct ra_interface
*ra
);
54 static unsigned int calc_prio(struct ra_interface
*ra
);
55 static struct ra_interface
*find_iface_param(char *iface
);
59 void ra_init(time_t now
)
61 struct icmp6_filter filter
;
63 #if defined(IPV6_TCLASS) && defined(IPTOS_CLASS_CS6)
64 int class = IPTOS_CLASS_CS6
;
66 int val
= 255; /* radvd uses this value */
67 socklen_t len
= sizeof(int);
68 struct dhcp_context
*context
;
70 /* ensure this is around even if we're not doing DHCPv6 */
71 expand_buf(&daemon
->outpacket
, sizeof(struct dhcp_packet
));
73 /* See if we're guessing SLAAC addresses, if so we need to recieve ping replies */
74 for (context
= daemon
->dhcp6
; context
; context
= context
->next
)
75 if ((context
->flags
& CONTEXT_RA_NAME
))
78 /* Need ICMP6 socket for transmission for DHCPv6 even when not doing RA. */
80 ICMP6_FILTER_SETBLOCKALL(&filter
);
83 ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT
, &filter
);
85 ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY
, &filter
);
88 if ((fd
= socket(PF_INET6
, SOCK_RAW
, IPPROTO_ICMPV6
)) == -1 ||
89 getsockopt(fd
, IPPROTO_IPV6
, IPV6_UNICAST_HOPS
, &hop_limit
, &len
) ||
90 #if defined(IPV6_TCLASS) && defined(IPTOS_CLASS_CS6)
91 setsockopt(fd
, IPPROTO_IPV6
, IPV6_TCLASS
, &class, sizeof(class)) == -1 ||
94 !set_ipv6pktinfo(fd
) ||
95 setsockopt(fd
, IPPROTO_IPV6
, IPV6_UNICAST_HOPS
, &val
, sizeof(val
)) ||
96 setsockopt(fd
, IPPROTO_IPV6
, IPV6_MULTICAST_HOPS
, &val
, sizeof(val
)) ||
97 setsockopt(fd
, IPPROTO_ICMPV6
, ICMP6_FILTER
, &filter
, sizeof(filter
)) == -1)
98 die (_("cannot create ICMPv6 socket: %s"), NULL
, EC_BADNET
);
100 daemon
->icmp6fd
= fd
;
102 if (daemon
->doing_ra
)
103 ra_start_unsolicted(now
, NULL
);
106 void ra_start_unsolicted(time_t now
, struct dhcp_context
*context
)
108 /* init timers so that we do ra's for some/all soon. some ra_times will end up zeroed
109 if it's not appropriate to advertise those contexts.
110 This gets re-called on a netlink route-change to re-do the advertisement
111 and pick up new interfaces */
114 context
->ra_short_period_start
= context
->ra_time
= now
;
116 for (context
= daemon
->dhcp6
; context
; context
= context
->next
)
117 if (!(context
->flags
& CONTEXT_TEMPLATE
))
119 context
->ra_time
= now
+ (rand16()/13000); /* range 0 - 5 */
120 /* re-do frequently for a minute or so, in case the first gets lost. */
121 context
->ra_short_period_start
= now
;
125 void icmp6_packet(time_t now
)
127 char interface
[IF_NAMESIZE
+1];
130 struct cmsghdr
*cmptr
;
133 struct cmsghdr align
; /* this ensures alignment */
134 char control6
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
136 struct sockaddr_in6 from
;
137 unsigned char *packet
;
140 /* Note: use outpacket for input buffer */
141 msg
.msg_control
= control_u
.control6
;
142 msg
.msg_controllen
= sizeof(control_u
);
144 msg
.msg_name
= &from
;
145 msg
.msg_namelen
= sizeof(from
);
146 msg
.msg_iov
= &daemon
->outpacket
;
149 if ((sz
= recv_dhcp_packet(daemon
->icmp6fd
, &msg
)) == -1 || sz
< 8)
152 packet
= (unsigned char *)daemon
->outpacket
.iov_base
;
154 for (cmptr
= CMSG_FIRSTHDR(&msg
); cmptr
; cmptr
= CMSG_NXTHDR(&msg
, cmptr
))
155 if (cmptr
->cmsg_level
== IPPROTO_IPV6
&& cmptr
->cmsg_type
== daemon
->v6pktinfo
)
159 struct in6_pktinfo
*p
;
161 p
.c
= CMSG_DATA(cmptr
);
163 if_index
= p
.p
->ipi6_ifindex
;
166 if (!indextoname(daemon
->icmp6fd
, if_index
, interface
))
169 if (!iface_check(AF_LOCAL
, NULL
, interface
, NULL
))
172 for (tmp
= daemon
->dhcp_except
; tmp
; tmp
= tmp
->next
)
173 if (tmp
->name
&& wildcard_match(tmp
->name
, interface
))
179 if (packet
[0] == ICMP6_ECHO_REPLY
)
180 lease_ping_reply(&from
.sin6_addr
, packet
, interface
);
181 else if (packet
[0] == ND_ROUTER_SOLICIT
)
185 /* look for link-layer address option for logging */
186 if (sz
>= 16 && packet
[8] == ICMP6_OPT_SOURCE_MAC
&& (packet
[9] * 8) + 8 <= sz
)
188 print_mac(daemon
->namebuff
, &packet
[10], (packet
[9] * 8) - 2);
189 mac
= daemon
->namebuff
;
192 if (!option_bool(OPT_QUIET_RA
))
193 my_syslog(MS_DHCP
| LOG_INFO
, "RTR-SOLICIT(%s) %s", interface
, mac
);
194 /* source address may not be valid in solicit request. */
195 send_ra(now
, if_index
, interface
, !IN6_IS_ADDR_UNSPECIFIED(&from
.sin6_addr
) ? &from
.sin6_addr
: NULL
);
199 static void send_ra(time_t now
, int iface
, char *iface_name
, struct in6_addr
*dest
)
201 struct ra_packet
*ra
;
202 struct ra_param parm
;
203 struct sockaddr_in6 addr
;
204 struct dhcp_context
*context
, *tmp
, **up
;
205 struct dhcp_netid iface_id
;
206 struct dhcp_opt
*opt_cfg
;
207 struct ra_interface
*ra_param
= find_iface_param(iface_name
);
208 int done_dns
= 0, old_prefix
= 0;
209 #ifdef HAVE_LINUX_NETWORK
214 ra
= expand(sizeof(struct ra_packet
));
216 ra
->type
= ND_ROUTER_ADVERT
;
218 ra
->hop_limit
= hop_limit
;
219 ra
->flags
= calc_prio(ra_param
);
220 ra
->lifetime
= htons(calc_lifetime(ra_param
));
221 ra
->reachable_time
= 0;
222 ra
->retrans_time
= 0;
227 parm
.found_context
= 0;
228 parm
.if_name
= iface_name
;
232 parm
.adv_interval
= calc_interval(ra_param
);
234 /* set tag with name == interface */
235 iface_id
.net
= iface_name
;
236 iface_id
.next
= NULL
;
237 parm
.tags
= &iface_id
;
239 for (context
= daemon
->dhcp6
; context
; context
= context
->next
)
241 context
->flags
&= ~CONTEXT_RA_DONE
;
242 context
->netid
.next
= &context
->netid
;
245 if (!iface_enumerate(AF_INET6
, &parm
, add_prefixes
))
248 /* Look for constructed contexts associated with addresses which have gone,
249 and advertise them with preferred_time == 0 RFC 6204 4.3 L-13 */
250 for (up
= &daemon
->dhcp6
, context
= daemon
->dhcp6
; context
; context
= tmp
)
254 if (context
->if_index
== iface
&& (context
->flags
& CONTEXT_OLD
))
256 unsigned int old
= difftime(now
, context
->address_lost_time
);
258 if (old
> context
->saved_valid
)
260 /* We've advertised this enough, time to go */
266 struct prefix_opt
*opt
;
267 struct in6_addr local
= context
->start6
;
272 /* zero net part of address */
273 setaddr6part(&local
, addr6part(&local
) & ~((context
->prefix
== 64) ? (u64
)-1LL : (1LLU << (128 - context
->prefix
)) - 1LLU));
275 if ((context
->flags
&
276 (CONTEXT_RA_ONLY
| CONTEXT_RA_NAME
| CONTEXT_RA_STATELESS
)))
279 if ((opt
= expand(sizeof(struct prefix_opt
))))
281 opt
->type
= ICMP6_OPT_PREFIX
;
283 opt
->prefix_len
= context
->prefix
;
284 /* autonomous only if we're not doing dhcp, always set "on-link" */
285 opt
->flags
= do_slaac
? 0xC0 : 0x80;
286 opt
->valid_lifetime
= htonl(context
->saved_valid
- old
);
287 opt
->preferred_lifetime
= htonl(0);
291 inet_ntop(AF_INET6
, &local
, daemon
->addrbuff
, ADDRSTRLEN
);
292 if (!option_bool(OPT_QUIET_RA
))
293 my_syslog(MS_DHCP
| LOG_INFO
, "RTR-ADVERT(%s) %s old prefix", iface_name
, daemon
->addrbuff
);
303 /* If we're advertising only old prefixes, set router lifetime to zero. */
304 if (old_prefix
&& !parm
.found_context
)
305 ra
->lifetime
= htons(0);
307 /* No prefixes to advertise. */
308 if (!old_prefix
&& !parm
.found_context
)
311 #ifdef HAVE_LINUX_NETWORK
312 /* Note that IPv6 MTU is not necessarilly the same as the IPv4 MTU
313 available from SIOCGIFMTU */
314 sprintf(daemon
->namebuff
, "/proc/sys/net/ipv6/conf/%s/mtu", iface_name
);
315 if ((f
= fopen(daemon
->namebuff
, "r")))
317 if (fgets(daemon
->namebuff
, MAXDNAME
, f
))
319 put_opt6_char(ICMP6_OPT_MTU
);
322 put_opt6_long(atoi(daemon
->namebuff
));
328 iface_enumerate(AF_LOCAL
, &iface
, add_lla
);
330 /* RDNSS, RFC 6106, use relevant DHCP6 options */
331 (void)option_filter(parm
.tags
, NULL
, daemon
->dhcp_opts6
);
333 for (opt_cfg
= daemon
->dhcp_opts6
; opt_cfg
; opt_cfg
= opt_cfg
->next
)
337 /* netids match and not encapsulated? */
338 if (!(opt_cfg
->flags
& DHOPT_TAGOK
))
341 if (opt_cfg
->opt
== OPTION6_DNS_SERVER
)
343 struct in6_addr
*a
= (struct in6_addr
*)opt_cfg
->val
;
346 if (opt_cfg
->len
== 0 || (IN6_IS_ADDR_UNSPECIFIED(a
) && parm
.pref_time
!= 0))
349 put_opt6_char(ICMP6_OPT_RDNSS
);
350 put_opt6_char((opt_cfg
->len
/8) + 1);
352 put_opt6_long(parm
.pref_time
);
353 /* zero means "self" */
354 for (i
= 0; i
< opt_cfg
->len
; i
+= IN6ADDRSZ
, a
++)
355 if (IN6_IS_ADDR_UNSPECIFIED(a
))
356 put_opt6(&parm
.link_global
, IN6ADDRSZ
);
358 put_opt6(a
, IN6ADDRSZ
);
361 if (opt_cfg
->opt
== OPTION6_DOMAIN_SEARCH
&& opt_cfg
->len
!= 0)
363 int len
= ((opt_cfg
->len
+7)/8);
365 put_opt6_char(ICMP6_OPT_DNSSL
);
366 put_opt6_char(len
+ 1);
368 put_opt6_long(parm
.pref_time
);
369 put_opt6(opt_cfg
->val
, opt_cfg
->len
);
372 for (i
= opt_cfg
->len
; i
< len
* 8; i
++)
377 if (daemon
->port
== NAMESERVER_PORT
&& !done_dns
&& parm
.pref_time
!= 0)
379 /* default == us, as long as we are supplying DNS service. */
380 put_opt6_char(ICMP6_OPT_RDNSS
);
383 put_opt6_long(parm
.pref_time
);
384 put_opt6(&parm
.link_local
, IN6ADDRSZ
);
387 /* set managed bits unless we're providing only RA on this link */
389 ra
->flags
|= 0x80; /* M flag, managed, */
391 ra
->flags
|= 0x40; /* O flag, other */
393 /* decide where we're sending */
394 memset(&addr
, 0, sizeof(addr
));
395 #ifdef HAVE_SOCKADDR_SA_LEN
396 addr
.sin6_len
= sizeof(struct sockaddr_in6
);
398 addr
.sin6_family
= AF_INET6
;
399 addr
.sin6_port
= htons(IPPROTO_ICMPV6
);
402 addr
.sin6_addr
= *dest
;
403 if (IN6_IS_ADDR_LINKLOCAL(dest
) ||
404 IN6_IS_ADDR_MC_LINKLOCAL(dest
))
405 addr
.sin6_scope_id
= iface
;
409 inet_pton(AF_INET6
, ALL_NODES
, &addr
.sin6_addr
);
410 setsockopt(daemon
->icmp6fd
, IPPROTO_IPV6
, IPV6_MULTICAST_IF
, &iface
, sizeof(iface
));
413 while (sendto(daemon
->icmp6fd
, daemon
->outpacket
.iov_base
, save_counter(0), 0,
414 (struct sockaddr
*)&addr
, sizeof(addr
)) == -1 && retry_send());
418 static int add_prefixes(struct in6_addr
*local
, int prefix
,
419 int scope
, int if_index
, int flags
,
420 unsigned int preferred
, unsigned int valid
, void *vparam
)
422 struct ra_param
*param
= vparam
;
424 (void)scope
; /* warning */
426 if (if_index
== param
->ind
)
428 if (IN6_IS_ADDR_LINKLOCAL(local
))
429 param
->link_local
= *local
;
430 else if (!IN6_IS_ADDR_LOOPBACK(local
) &&
431 !IN6_IS_ADDR_MULTICAST(local
))
437 unsigned int time
= 0xffffffff;
438 struct dhcp_context
*context
;
440 for (context
= daemon
->dhcp6
; context
; context
= context
->next
)
441 if (!(context
->flags
& (CONTEXT_TEMPLATE
| CONTEXT_OLD
)) &&
443 prefix
<= context
->prefix
&&
445 prefix
== context
->prefix
&&
447 is_same_net6(local
, &context
->start6
, prefix
) &&
448 is_same_net6(local
, &context
->end6
, prefix
))
450 context
->saved_valid
= valid
;
452 if ((context
->flags
&
453 (CONTEXT_RA_ONLY
| CONTEXT_RA_NAME
| CONTEXT_RA_STATELESS
)))
456 if (context
->flags
& CONTEXT_DHCP
)
459 if (!(context
->flags
& CONTEXT_RA_STATELESS
))
465 /* don't do RA for non-ra-only unless --enable-ra is set */
466 if (!option_bool(OPT_RA
))
472 /* find floor time, don't reduce below 3 * RA interval. */
473 if (time
> context
->lease_time
)
475 time
= context
->lease_time
;
476 if (time
< ((unsigned int)(3 * param
->adv_interval
)))
477 time
= 3 * param
->adv_interval
;
480 if (context
->flags
& CONTEXT_DEPRECATE
)
483 if (context
->flags
& CONTEXT_CONSTRUCTED
)
487 /* collect dhcp-range tags */
488 if (context
->netid
.next
== &context
->netid
&& context
->netid
.net
)
490 context
->netid
.next
= param
->tags
;
491 param
->tags
= &context
->netid
;
494 /* subsequent prefixes on the same interface
495 and subsequent instances of this prefix don't need timers.
496 Be careful not to find the same prefix twice with different
498 if (!(context
->flags
& CONTEXT_RA_DONE
))
501 context
->ra_time
= 0;
502 context
->flags
|= CONTEXT_RA_DONE
;
504 do_prefix
= context
->prefix
;
511 param
->found_context
= 1;
514 /* configured time is ceiling */
515 if (!constructed
|| valid
> time
)
518 if (flags
& IFACE_DEPRECATED
)
524 /* configured time is ceiling */
525 if (!constructed
|| preferred
> time
)
528 if (preferred
> param
->pref_time
)
530 param
->pref_time
= preferred
;
531 param
->link_global
= *local
;
536 struct prefix_opt
*opt
;
538 if ((opt
= expand(sizeof(struct prefix_opt
))))
544 /* zero net part of address */
545 setaddr6part(local
, addr6part(local
) & ~((prefix
== 64) ? (u64
)-1LL : (1LLU << (128 - prefix
)) - 1LLU));
547 opt
->type
= ICMP6_OPT_PREFIX
;
549 opt
->prefix_len
= prefix
;
550 /* autonomous only if we're not doing dhcp, always set "on-link" */
551 opt
->flags
= do_slaac
? 0xC0 : 0x80;
552 opt
->valid_lifetime
= htonl(valid
);
553 opt
->preferred_lifetime
= htonl(preferred
);
555 opt
->prefix
= *local
;
557 inet_ntop(AF_INET6
, local
, daemon
->addrbuff
, ADDRSTRLEN
);
558 if (!option_bool(OPT_QUIET_RA
))
559 my_syslog(MS_DHCP
| LOG_INFO
, "RTR-ADVERT(%s) %s", param
->if_name
, daemon
->addrbuff
);
568 static int add_lla(int index
, unsigned int type
, char *mac
, size_t maclen
, void *parm
)
572 if (index
== *((int *)parm
))
574 /* size is in units of 8 octets and includes type and length (2 bytes)
576 int len
= (maclen
+ 9) >> 3;
577 unsigned char *p
= expand(len
<< 3);
578 memset(p
, 0, len
<< 3);
579 *p
++ = ICMP6_OPT_SOURCE_MAC
;
581 memcpy(p
, mac
, maclen
);
589 time_t periodic_ra(time_t now
)
591 struct search_param param
;
592 struct dhcp_context
*context
;
600 /* find overdue events, and time of first future event */
601 for (next_event
= 0, context
= daemon
->dhcp6
; context
; context
= context
->next
)
602 if (context
->ra_time
!= 0)
604 if (difftime(context
->ra_time
, now
) <= 0.0)
607 if (next_event
== 0 || difftime(next_event
, context
->ra_time
) > 0.0)
608 next_event
= context
->ra_time
;
615 if ((context
->flags
& CONTEXT_OLD
) &&
616 context
->if_index
!= 0 &&
617 indextoname(daemon
->icmp6fd
, context
->if_index
, param
.name
))
619 /* A context for an old address. We'll not find the interface by
620 looking for addresses, but we know it anyway, since the context is
622 param
.iface
= context
->if_index
;
623 new_timeout(context
, param
.name
, now
);
625 else if (iface_enumerate(AF_INET6
, ¶m
, iface_search
))
626 /* There's a context overdue, but we can't find an interface
627 associated with it, because it's for a subnet we dont
628 have an interface on. Probably we're doing DHCP on
629 a remote subnet via a relay. Zero the timer, since we won't
630 ever be able to send ra's and satistfy it. */
631 context
->ra_time
= 0;
633 if (param
.iface
!= 0 &&
634 iface_check(AF_LOCAL
, NULL
, param
.name
, NULL
))
637 for (tmp
= daemon
->dhcp_except
; tmp
; tmp
= tmp
->next
)
638 if (tmp
->name
&& wildcard_match(tmp
->name
, param
.name
))
641 send_ra(now
, param
.iface
, param
.name
, NULL
);
647 static int iface_search(struct in6_addr
*local
, int prefix
,
648 int scope
, int if_index
, int flags
,
649 int preferred
, int valid
, void *vparam
)
651 struct search_param
*param
= vparam
;
652 struct dhcp_context
*context
;
658 for (context
= daemon
->dhcp6
; context
; context
= context
->next
)
659 if (!(context
->flags
& (CONTEXT_TEMPLATE
| CONTEXT_OLD
)) &&
661 prefix
<= context
->prefix
&&
663 prefix
== context
->prefix
&&
665 is_same_net6(local
, &context
->start6
, prefix
) &&
666 is_same_net6(local
, &context
->end6
, prefix
) &&
667 context
->ra_time
!= 0 &&
668 difftime(context
->ra_time
, param
->now
) <= 0.0)
670 /* found an interface that's overdue for RA determine new
671 timeout value and arrange for RA to be sent unless interface is
674 if (!(flags
& IFACE_TENTATIVE
))
675 param
->iface
= if_index
;
677 /* should never fail */
678 if (!indextoname(daemon
->icmp6fd
, if_index
, param
->name
))
684 new_timeout(context
, param
->name
, param
->now
);
686 /* zero timers for other contexts on the same subnet, so they don't timeout
688 for (context
= context
->next
; context
; context
= context
->next
)
690 if (prefix
<= context
->prefix
&&
692 if (prefix
== context
->prefix
&&
694 is_same_net6(local
, &context
->start6
, prefix
) &&
695 is_same_net6(local
, &context
->end6
, prefix
))
696 context
->ra_time
= 0;
698 return 0; /* found, abort */
701 return 1; /* keep searching */
704 static void new_timeout(struct dhcp_context
*context
, char *iface_name
, time_t now
)
706 if (difftime(now
, context
->ra_short_period_start
) < 60.0)
708 context
->ra_time
= now
+ 5 + (rand16()/4400);
711 /* range 3/4 - 1 times MaxRtrAdvInterval */
712 unsigned int adv_interval
= calc_interval(find_iface_param(iface_name
));
713 context
->ra_time
= now
+ (3 * adv_interval
)/4 + ((adv_interval
* (unsigned int)rand16()) >> 18);
717 static struct ra_interface
*find_iface_param(char *iface
)
719 struct ra_interface
*ra
;
721 for (ra
= daemon
->ra_interfaces
; ra
; ra
= ra
->next
)
722 if (wildcard_match(ra
->name
, iface
))
728 static unsigned int calc_interval(struct ra_interface
*ra
)
732 if (ra
&& ra
->interval
!= 0)
734 interval
= ra
->interval
;
737 else if (interval
< 4)
741 return (unsigned int)interval
;
744 static unsigned int calc_lifetime(struct ra_interface
*ra
)
746 int lifetime
, interval
= (int)calc_interval(ra
);
748 if (!ra
|| ra
->lifetime
== -1) /* not specified */
749 lifetime
= 3 * interval
;
752 lifetime
= ra
->lifetime
;
753 if (lifetime
< interval
&& lifetime
!= 0)
755 else if (lifetime
> 9000)
759 return (unsigned int)lifetime
;
762 static unsigned int calc_prio(struct ra_interface
*ra
)