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