1/*	$KAME: rtadvd.h,v 1.26 2003/08/05 12:34:23 itojun Exp $	*/
2
3/*-
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 * Copyright (C) 1998 WIDE Project.
7 * Copyright (C) 2011 Hiroki Sato <hrs@FreeBSD.org>
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the project nor the names of its contributors
19 *    may be used to endorse or promote products derived from this software
20 *    without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#include <stdbool.h>
36
37#define	ELM_MALLOC(p,error_action)					\
38	do {								\
39		p = malloc(sizeof(*p));					\
40		if (p == NULL) {					\
41			syslog(LOG_ERR, "<%s> malloc failed: %s",	\
42			    __func__, strerror(errno));			\
43			error_action;					\
44		}							\
45		memset(p, 0, sizeof(*p));				\
46	} while(0)
47
48#define IN6ADDR_LINKLOCAL_ALLNODES_INIT				\
49	{{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	\
50	    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
51
52#define IN6ADDR_LINKLOCAL_ALLROUTERS_INIT			\
53	{{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	\
54	    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}}
55
56#define IN6ADDR_SITELOCAL_ALLROUTERS_INIT			\
57	{{{ 0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	\
58	    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}}
59
60extern struct sockaddr_in6 sin6_linklocal_allnodes;
61extern struct sockaddr_in6 sin6_linklocal_allrouters;
62extern struct sockaddr_in6 sin6_sitelocal_allrouters;
63
64/*
65 * RFC 3542 API deprecates IPV6_PKTINFO in favor of
66 * IPV6_RECVPKTINFO
67 */
68#ifndef IPV6_RECVPKTINFO
69#ifdef IPV6_PKTINFO
70#define IPV6_RECVPKTINFO	IPV6_PKTINFO
71#endif
72#endif
73
74/*
75 * RFC 3542 API deprecates IPV6_HOPLIMIT in favor of
76 * IPV6_RECVHOPLIMIT
77 */
78#ifndef IPV6_RECVHOPLIMIT
79#ifdef IPV6_HOPLIMIT
80#define IPV6_RECVHOPLIMIT	IPV6_HOPLIMIT
81#endif
82#endif
83
84/* protocol constants and default values */
85#define DEF_MAXRTRADVINTERVAL 600
86#define DEF_ADVLINKMTU 0
87#define DEF_ADVREACHABLETIME 0
88#define DEF_ADVRETRANSTIMER 0
89#define DEF_ADVCURHOPLIMIT 64
90#define DEF_ADVVALIDLIFETIME 2592000
91#define DEF_ADVPREFERREDLIFETIME 604800
92
93#define MAXROUTERLIFETIME 9000
94#define MIN_MAXINTERVAL 4
95#define MAX_MAXINTERVAL 1800
96#define MIN_MININTERVAL 3
97#define MAXREACHABLETIME 3600000
98
99#define MAX_INITIAL_RTR_ADVERT_INTERVAL  16
100#define MAX_INITIAL_RTR_ADVERTISEMENTS    3
101#define MAX_FINAL_RTR_ADVERTISEMENTS      3
102#define MIN_DELAY_BETWEEN_RAS             3
103#define MAX_RA_DELAY_TIME                 500000 /* usec */
104
105#define PREFIX_FROM_KERNEL 1
106#define PREFIX_FROM_CONFIG 2
107#define PREFIX_FROM_DYNAMIC 3
108
109struct prefix {
110	TAILQ_ENTRY(prefix)	pfx_next;
111
112	struct rainfo *pfx_rainfo;	/* back pointer to the interface */
113	/*
114	 * Expiration timer.  This is used when a prefix derived from
115	 * the kernel is deleted.
116	 */
117	struct rtadvd_timer *pfx_timer;
118
119	uint32_t	pfx_validlifetime;	/* AdvValidLifetime */
120	uint32_t       	pfx_vltimeexpire;	/* Expiration of vltime */
121	uint32_t	pfx_preflifetime;	/* AdvPreferredLifetime */
122	uint32_t	pfx_pltimeexpire;	/* Expiration of pltime */
123	int		pfx_onlinkflg;		/* bool: AdvOnLinkFlag */
124	int		pfx_autoconfflg;	/* bool: AdvAutonomousFlag */
125	int		pfx_prefixlen;
126	int		pfx_origin;		/* From kernel or config */
127
128	struct in6_addr	pfx_prefix;
129};
130
131struct rtinfo {
132	TAILQ_ENTRY(rtinfo)	rti_next;
133
134	uint32_t	rti_ltime;	/* route lifetime */
135	int		rti_rtpref;	/* route preference */
136	int		rti_prefixlen;
137	struct in6_addr	rti_prefix;
138};
139
140struct rdnss_addr {
141	TAILQ_ENTRY(rdnss_addr)	ra_next;
142
143	struct in6_addr ra_dns;	/* DNS server entry */
144};
145
146struct rdnss {
147	TAILQ_ENTRY(rdnss) rd_next;
148
149	TAILQ_HEAD(, rdnss_addr) rd_list;	/* list of DNS servers */
150	uint32_t rd_ltime;	/* number of seconds valid */
151};
152
153struct pref64 {
154	TAILQ_ENTRY(pref64) p64_next;
155	bool		p64_enabled;
156	uint16_t	p64_plc;	/* prefix length code */
157	uint16_t	p64_sl;		/* scaled lifetime */
158	struct in6_addr	p64_prefix;
159};
160
161/*
162 * The maximum length of a domain name in a DNS search list is calculated
163 * by a domain name + length fields per 63 octets + a zero octet at
164 * the tail and adding 8 octet boundary padding.
165 */
166#define _DNAME_LABELENC_MAXLEN \
167	(NI_MAXHOST + (NI_MAXHOST / 64 + 1) + 1)
168
169#define DNAME_LABELENC_MAXLEN \
170	(_DNAME_LABELENC_MAXLEN + 8 - _DNAME_LABELENC_MAXLEN % 8)
171
172struct dnssl_addr {
173	TAILQ_ENTRY(dnssl_addr)	da_next;
174
175	int da_len;				/* length of entry */
176	char da_dom[DNAME_LABELENC_MAXLEN];	/* search domain name entry */
177};
178
179struct dnssl {
180	TAILQ_ENTRY(dnssl)	dn_next;
181
182	TAILQ_HEAD(, dnssl_addr) dn_list;	/* list of search domains */
183	uint32_t dn_ltime;			/* number of seconds valid */
184};
185
186struct soliciter {
187	TAILQ_ENTRY(soliciter)	sol_next;
188
189	struct sockaddr_in6	sol_addr;
190};
191
192struct	rainfo {
193	/* pointer for list */
194	TAILQ_ENTRY(rainfo)	rai_next;
195
196	/* interface information */
197	struct ifinfo *rai_ifinfo;
198
199	int	rai_advlinkopt;		/* bool: whether include link-layer addr opt */
200	int	rai_advifprefix;	/* bool: gather IF prefixes? */
201
202	/* Router configuration variables */
203	uint16_t	rai_lifetime;		/* AdvDefaultLifetime */
204	uint16_t	rai_maxinterval;	/* MaxRtrAdvInterval */
205	uint16_t	rai_mininterval;	/* MinRtrAdvInterval */
206	int 	rai_managedflg;		/* AdvManagedFlag */
207	int	rai_otherflg;		/* AdvOtherConfigFlag */
208#ifdef DRAFT_IETF_6MAN_IPV6ONLY_FLAG
209	int	rai_ipv6onlyflg;	/* AdvIPv6OnlyFlag */
210#endif
211
212	int	rai_rtpref;		/* router preference */
213	uint32_t	rai_linkmtu;		/* AdvLinkMTU */
214	uint32_t	rai_reachabletime;	/* AdvReachableTime */
215	uint32_t	rai_retranstimer;	/* AdvRetransTimer */
216	uint8_t	rai_hoplimit;		/* AdvCurHopLimit */
217
218	TAILQ_HEAD(, prefix) rai_prefix;/* AdvPrefixList(link head) */
219	int	rai_pfxs;		/* number of prefixes */
220
221	uint16_t	rai_clockskew;	/* used for consisitency check of lifetimes */
222
223	TAILQ_HEAD(, rdnss) rai_rdnss;	/* DNS server list */
224	TAILQ_HEAD(, dnssl) rai_dnssl;	/* search domain list */
225	TAILQ_HEAD(, rtinfo) rai_route;	/* route information option (link head) */
226	int	rai_routes;		/* number of route information options */
227	/* actual RA packet data and its length */
228	size_t	rai_ra_datalen;
229	char	*rai_ra_data;
230	struct pref64 rai_pref64;	/* PREF64 option */
231
232	/* info about soliciter */
233	TAILQ_HEAD(, soliciter) rai_soliciter;	/* recent solication source */
234};
235
236/* RA information list */
237extern TAILQ_HEAD(railist_head_t, rainfo) railist;
238
239/*
240 * ifi_state:
241 *
242 *           (INIT)
243 *              |
244 *              | update_ifinfo()
245 *              | update_persist_ifinfo()
246 *              v
247 *         UNCONFIGURED
248 *               |  ^
249 *   loadconfig()|  |rm_ifinfo(), ra_output()
250 *      (MC join)|  |(MC leave)
251 *               |  |
252 *               |  |
253 *               v  |
254 *         TRANSITIVE
255 *               |  ^
256 *    ra_output()|  |getconfig()
257 *               |  |
258 *               |  |
259 *               |  |
260 *               v  |
261 *         CONFIGURED
262 *
263 *
264 */
265#define	IFI_STATE_UNCONFIGURED	0
266#define	IFI_STATE_CONFIGURED	1
267#define	IFI_STATE_TRANSITIVE	2
268
269struct	ifinfo {
270	TAILQ_ENTRY(ifinfo)	ifi_next;
271
272	uint16_t	ifi_state;
273	uint16_t	ifi_persist;
274	uint16_t	ifi_ifindex;
275	char	ifi_ifname[IFNAMSIZ];
276	uint8_t	ifi_type;
277	uint16_t	ifi_flags;
278	uint32_t	ifi_nd_flags;
279	uint32_t	ifi_phymtu;
280	struct sockaddr_dl	ifi_sdl;
281
282	struct rainfo	*ifi_rainfo;
283	struct rainfo	*ifi_rainfo_trans;
284	uint16_t	ifi_burstcount;
285	uint32_t	ifi_burstinterval;
286	struct rtadvd_timer	*ifi_ra_timer;
287	/* timestamp when the latest RA was sent */
288	struct timespec		ifi_ra_lastsent;
289	uint16_t	ifi_rs_waitcount;
290
291	/* statistics */
292	uint64_t ifi_raoutput;		/* # of RAs sent */
293	uint64_t ifi_rainput;		/* # of RAs received */
294	uint64_t ifi_rainconsistent;	/* # of inconsistent recv'd RAs  */
295	uint64_t ifi_rsinput;		/* # of RSs received */
296};
297
298/* Interface list */
299extern TAILQ_HEAD(ifilist_head_t, ifinfo) ifilist;
300
301extern char *mcastif;
302
303struct rtadvd_timer	*ra_timeout(void *);
304void			ra_timer_update(void *, struct timespec *);
305void			ra_output(struct ifinfo *);
306
307int			prefix_match(struct in6_addr *, int,
308			    struct in6_addr *, int);
309struct ifinfo		*if_indextoifinfo(int);
310struct prefix		*find_prefix(struct rainfo *,
311			    struct in6_addr *, int);
312void			rtadvd_set_reload(int);
313void			rtadvd_set_shutdown(int);
314