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
);
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
;
270 parm
.found_context
= 1;
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 (!parm
.found_context
)
306 #ifdef HAVE_LINUX_NETWORK
307 /* Note that IPv6 MTU is not necessarilly the same as the IPv4 MTU
308 available from SIOCGIFMTU */
309 sprintf(daemon
->namebuff
, "/proc/sys/net/ipv6/conf/%s/mtu", iface_name
);
310 if ((f
= fopen(daemon
->namebuff
, "r")))
312 if (fgets(daemon
->namebuff
, MAXDNAME
, f
))
314 put_opt6_char(ICMP6_OPT_MTU
);
317 put_opt6_long(atoi(daemon
->namebuff
));
323 iface_enumerate(AF_LOCAL
, &iface
, add_lla
);
325 /* RDNSS, RFC 6106, use relevant DHCP6 options */
326 (void)option_filter(parm
.tags
, NULL
, daemon
->dhcp_opts6
);
328 for (opt_cfg
= daemon
->dhcp_opts6
; opt_cfg
; opt_cfg
= opt_cfg
->next
)
332 /* netids match and not encapsulated? */
333 if (!(opt_cfg
->flags
& DHOPT_TAGOK
))
336 if (opt_cfg
->opt
== OPTION6_DNS_SERVER
)
338 struct in6_addr
*a
= (struct in6_addr
*)opt_cfg
->val
;
341 if (opt_cfg
->len
== 0 || (IN6_IS_ADDR_UNSPECIFIED(a
) && parm
.pref_time
!= 0))
344 put_opt6_char(ICMP6_OPT_RDNSS
);
345 put_opt6_char((opt_cfg
->len
/8) + 1);
347 put_opt6_long(parm
.pref_time
);
348 /* zero means "self" */
349 for (i
= 0; i
< opt_cfg
->len
; i
+= IN6ADDRSZ
, a
++)
350 if (IN6_IS_ADDR_UNSPECIFIED(a
))
351 put_opt6(&parm
.link_global
, IN6ADDRSZ
);
353 put_opt6(a
, IN6ADDRSZ
);
356 if (opt_cfg
->opt
== OPTION6_DOMAIN_SEARCH
&& opt_cfg
->len
!= 0)
358 int len
= ((opt_cfg
->len
+7)/8);
360 put_opt6_char(ICMP6_OPT_DNSSL
);
361 put_opt6_char(len
+ 1);
363 put_opt6_long(parm
.pref_time
);
364 put_opt6(opt_cfg
->val
, opt_cfg
->len
);
367 for (i
= opt_cfg
->len
; i
< len
* 8; i
++)
372 if (daemon
->port
== NAMESERVER_PORT
&& !done_dns
&& parm
.pref_time
!= 0)
374 /* default == us, as long as we are supplying DNS service. */
375 put_opt6_char(ICMP6_OPT_RDNSS
);
378 put_opt6_long(parm
.pref_time
);
379 put_opt6(&parm
.link_local
, IN6ADDRSZ
);
382 /* set managed bits unless we're providing only RA on this link */
384 ra
->flags
|= 0x80; /* M flag, managed, */
386 ra
->flags
|= 0x40; /* O flag, other */
388 /* decide where we're sending */
389 memset(&addr
, 0, sizeof(addr
));
390 #ifdef HAVE_SOCKADDR_SA_LEN
391 addr
.sin6_len
= sizeof(struct sockaddr_in6
);
393 addr
.sin6_family
= AF_INET6
;
394 addr
.sin6_port
= htons(IPPROTO_ICMPV6
);
397 addr
.sin6_addr
= *dest
;
398 if (IN6_IS_ADDR_LINKLOCAL(dest
) ||
399 IN6_IS_ADDR_MC_LINKLOCAL(dest
))
400 addr
.sin6_scope_id
= iface
;
404 inet_pton(AF_INET6
, ALL_NODES
, &addr
.sin6_addr
);
405 setsockopt(daemon
->icmp6fd
, IPPROTO_IPV6
, IPV6_MULTICAST_IF
, &iface
, sizeof(iface
));
408 while (sendto(daemon
->icmp6fd
, daemon
->outpacket
.iov_base
, save_counter(0), 0,
409 (struct sockaddr
*)&addr
, sizeof(addr
)) == -1 && retry_send());
413 static int add_prefixes(struct in6_addr
*local
, int prefix
,
414 int scope
, int if_index
, int flags
,
415 unsigned int preferred
, unsigned int valid
, void *vparam
)
417 struct ra_param
*param
= vparam
;
419 (void)scope
; /* warning */
421 if (if_index
== param
->ind
)
423 if (IN6_IS_ADDR_LINKLOCAL(local
))
424 param
->link_local
= *local
;
425 else if (!IN6_IS_ADDR_LOOPBACK(local
) &&
426 !IN6_IS_ADDR_MULTICAST(local
))
432 unsigned int time
= 0xffffffff;
433 struct dhcp_context
*context
;
435 for (context
= daemon
->dhcp6
; context
; context
= context
->next
)
436 if (!(context
->flags
& (CONTEXT_TEMPLATE
| CONTEXT_OLD
)) &&
437 prefix
<= context
->prefix
&& //KDB
438 is_same_net6(local
, &context
->start6
, prefix
) &&
439 is_same_net6(local
, &context
->end6
, prefix
))
441 context
->saved_valid
= valid
;
443 if ((context
->flags
&
444 (CONTEXT_RA_ONLY
| CONTEXT_RA_NAME
| CONTEXT_RA_STATELESS
)))
447 if (context
->flags
& CONTEXT_DHCP
)
450 if (!(context
->flags
& CONTEXT_RA_STATELESS
))
456 /* don't do RA for non-ra-only unless --enable-ra is set */
457 if (!option_bool(OPT_RA
))
463 /* find floor time, don't reduce below 3 * RA interval. */
464 if (time
> context
->lease_time
)
466 time
= context
->lease_time
;
467 if (time
< ((unsigned int)(3 * param
->adv_interval
)))
468 time
= 3 * param
->adv_interval
;
471 if (context
->flags
& CONTEXT_DEPRECATE
)
474 if (context
->flags
& CONTEXT_CONSTRUCTED
)
478 /* collect dhcp-range tags */
479 if (context
->netid
.next
== &context
->netid
&& context
->netid
.net
)
481 context
->netid
.next
= param
->tags
;
482 param
->tags
= &context
->netid
;
485 /* subsequent prefixes on the same interface
486 and subsequent instances of this prefix don't need timers.
487 Be careful not to find the same prefix twice with different
489 if (!(context
->flags
& CONTEXT_RA_DONE
))
492 context
->ra_time
= 0;
493 context
->flags
|= CONTEXT_RA_DONE
;
494 do_prefix
= context
->prefix
; //KDB
498 param
->found_context
= 1;
501 /* configured time is ceiling */
502 if (!constructed
|| valid
> time
)
505 if (flags
& IFACE_DEPRECATED
)
511 /* configured time is ceiling */
512 if (!constructed
|| preferred
> time
)
515 if (preferred
> param
->pref_time
)
517 param
->pref_time
= preferred
;
518 param
->link_global
= *local
;
523 struct prefix_opt
*opt
;
525 if ((opt
= expand(sizeof(struct prefix_opt
))))
527 prefix
= do_prefix
; //KDB
529 /* zero net part of address */
530 setaddr6part(local
, addr6part(local
) & ~((prefix
== 64) ? (u64
)-1LL : (1LLU << (128 - prefix
)) - 1LLU));
532 opt
->type
= ICMP6_OPT_PREFIX
;
534 opt
->prefix_len
= prefix
;
535 /* autonomous only if we're not doing dhcp, always set "on-link" */
536 opt
->flags
= do_slaac
? 0xC0 : 0x80;
537 opt
->valid_lifetime
= htonl(valid
);
538 opt
->preferred_lifetime
= htonl(preferred
);
540 opt
->prefix
= *local
;
542 inet_ntop(AF_INET6
, local
, daemon
->addrbuff
, ADDRSTRLEN
);
543 if (!option_bool(OPT_QUIET_RA
))
544 my_syslog(MS_DHCP
| LOG_INFO
, "RTR-ADVERT(%s) %s", param
->if_name
, daemon
->addrbuff
);
553 static int add_lla(int index
, unsigned int type
, char *mac
, size_t maclen
, void *parm
)
557 if (index
== *((int *)parm
))
559 /* size is in units of 8 octets and includes type and length (2 bytes)
561 int len
= (maclen
+ 9) >> 3;
562 unsigned char *p
= expand(len
<< 3);
563 memset(p
, 0, len
<< 3);
564 *p
++ = ICMP6_OPT_SOURCE_MAC
;
566 memcpy(p
, mac
, maclen
);
574 time_t periodic_ra(time_t now
)
576 struct search_param param
;
577 struct dhcp_context
*context
;
585 /* find overdue events, and time of first future event */
586 for (next_event
= 0, context
= daemon
->dhcp6
; context
; context
= context
->next
)
587 if (context
->ra_time
!= 0)
589 if (difftime(context
->ra_time
, now
) <= 0.0)
592 if (next_event
== 0 || difftime(next_event
, context
->ra_time
) > 0.0)
593 next_event
= context
->ra_time
;
600 if ((context
->flags
& CONTEXT_OLD
) &&
601 context
->if_index
!= 0 &&
602 indextoname(daemon
->icmp6fd
, param
.iface
, param
.name
))
604 /* A context for an old address. We'll not find the interface by
605 looking for addresses, but we know it anyway, since the context is
607 param
.iface
= context
->if_index
;
608 new_timeout(context
, param
.name
, now
);
610 else if (iface_enumerate(AF_INET6
, ¶m
, iface_search
))
611 /* There's a context overdue, but we can't find an interface
612 associated with it, because it's for a subnet we dont
613 have an interface on. Probably we're doing DHCP on
614 a remote subnet via a relay. Zero the timer, since we won't
615 ever be able to send ra's and satistfy it. */
616 context
->ra_time
= 0;
618 if (param
.iface
!= 0 &&
619 iface_check(AF_LOCAL
, NULL
, param
.name
, NULL
))
622 for (tmp
= daemon
->dhcp_except
; tmp
; tmp
= tmp
->next
)
623 if (tmp
->name
&& wildcard_match(tmp
->name
, param
.name
))
626 send_ra(now
, param
.iface
, param
.name
, NULL
);
632 static int iface_search(struct in6_addr
*local
, int prefix
,
633 int scope
, int if_index
, int flags
,
634 int preferred
, int valid
, void *vparam
)
636 struct search_param
*param
= vparam
;
637 struct dhcp_context
*context
;
643 for (context
= daemon
->dhcp6
; context
; context
= context
->next
)
644 if (!(context
->flags
& (CONTEXT_TEMPLATE
| CONTEXT_OLD
)) &&
645 prefix
<= context
->prefix
&& //KDB
646 is_same_net6(local
, &context
->start6
, prefix
) &&
647 is_same_net6(local
, &context
->end6
, prefix
) &&
648 context
->ra_time
!= 0 &&
649 difftime(context
->ra_time
, param
->now
) <= 0.0)
651 /* found an interface that's overdue for RA determine new
652 timeout value and arrange for RA to be sent unless interface is
655 if (!(flags
& IFACE_TENTATIVE
))
656 param
->iface
= if_index
;
658 /* should never fail */
659 if (!indextoname(daemon
->icmp6fd
, if_index
, param
->name
))
665 new_timeout(context
, param
->name
, param
->now
);
667 /* zero timers for other contexts on the same subnet, so they don't timeout
669 for (context
= context
->next
; context
; context
= context
->next
)
670 if (prefix
<= context
->prefix
&& //KDB
671 is_same_net6(local
, &context
->start6
, prefix
) &&
672 is_same_net6(local
, &context
->end6
, prefix
))
673 context
->ra_time
= 0;
675 return 0; /* found, abort */
678 return 1; /* keep searching */
681 static void new_timeout(struct dhcp_context
*context
, char *iface_name
, time_t now
)
683 if (difftime(now
, context
->ra_short_period_start
) < 60.0)
685 context
->ra_time
= now
+ 5 + (rand16()/4400);
688 /* range 3/4 - 1 times MaxRtrAdvInterval */
689 unsigned int adv_interval
= calc_interval(find_iface_param(iface_name
));
690 context
->ra_time
= now
+ (3 * adv_interval
)/4 + ((adv_interval
* (unsigned int)rand16()) >> 18);
694 static struct ra_interface
*find_iface_param(char *iface
)
696 struct ra_interface
*ra
;
698 for (ra
= daemon
->ra_interfaces
; ra
; ra
= ra
->next
)
699 if (wildcard_match(ra
->name
, iface
))
705 static unsigned int calc_interval(struct ra_interface
*ra
)
709 if (ra
&& ra
->interval
!= 0)
711 interval
= ra
->interval
;
714 else if (interval
< 4)
718 return (unsigned int)interval
;
721 static unsigned int calc_lifetime(struct ra_interface
*ra
)
723 int lifetime
, interval
= (int)calc_interval(ra
);
725 if (!ra
|| ra
->lifetime
== -1) /* not specified */
726 lifetime
= 3 * interval
;
729 lifetime
= ra
->lifetime
;
730 if (lifetime
< interval
&& lifetime
!= 0)
732 else if (lifetime
> 9000)
736 return (unsigned int)lifetime
;
739 static unsigned int calc_prio(struct ra_interface
*ra
)