171333Sitojun/*	$FreeBSD$	*/
2118968Sume/*	$KAME: rtadvd.h,v 1.26 2003/08/05 12:34:23 itojun Exp $	*/
362656Skris
455505Sshin/*
555505Sshin * Copyright (C) 1998 WIDE Project.
6224144Shrs * Copyright (C) 2011 Hiroki Sato <hrs@FreeBSD.org>
755505Sshin * All rights reserved.
8222732Shrs *
955505Sshin * Redistribution and use in source and binary forms, with or without
1055505Sshin * modification, are permitted provided that the following conditions
1155505Sshin * are met:
1255505Sshin * 1. Redistributions of source code must retain the above copyright
1355505Sshin *    notice, this list of conditions and the following disclaimer.
1455505Sshin * 2. Redistributions in binary form must reproduce the above copyright
1555505Sshin *    notice, this list of conditions and the following disclaimer in the
1655505Sshin *    documentation and/or other materials provided with the distribution.
1755505Sshin * 3. Neither the name of the project nor the names of its contributors
1855505Sshin *    may be used to endorse or promote products derived from this software
1955505Sshin *    without specific prior written permission.
20222732Shrs *
2155505Sshin * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
2255505Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2355505Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2455505Sshin * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
2555505Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2655505Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2755505Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2855505Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2955505Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3055505Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3155505Sshin * SUCH DAMAGE.
3255505Sshin */
3355505Sshin
34224144Shrs#define	ELM_MALLOC(p,error_action)					\
35224144Shrs	do {								\
36224144Shrs		p = malloc(sizeof(*p));					\
37224144Shrs		if (p == NULL) {					\
38224144Shrs			syslog(LOG_ERR, "<%s> malloc failed: %s",	\
39224144Shrs			    __func__, strerror(errno));			\
40224144Shrs			error_action;					\
41224144Shrs		}							\
42224144Shrs		memset(p, 0, sizeof(*p));				\
43224144Shrs	} while(0)
44224144Shrs
45222732Shrs#define IN6ADDR_LINKLOCAL_ALLNODES_INIT				\
46222732Shrs	{{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	\
47222732Shrs	    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
4855505Sshin
49222732Shrs#define IN6ADDR_LINKLOCAL_ALLROUTERS_INIT			\
50222732Shrs	{{{ 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	\
51222732Shrs	    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}}
52222732Shrs
53222732Shrs#define IN6ADDR_SITELOCAL_ALLROUTERS_INIT			\
54222732Shrs	{{{ 0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	\
55222732Shrs	    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}}
56222732Shrs
57222732Shrsextern struct sockaddr_in6 sin6_linklocal_allnodes;
58222732Shrsextern struct sockaddr_in6 sin6_linklocal_allrouters;
59222732Shrsextern struct sockaddr_in6 sin6_sitelocal_allrouters;
60222732Shrs
61222732Shrs/*
62222732Shrs * RFC 3542 API deprecates IPV6_PKTINFO in favor of
63222732Shrs * IPV6_RECVPKTINFO
64222732Shrs */
65222732Shrs#ifndef IPV6_RECVPKTINFO
66222732Shrs#ifdef IPV6_PKTINFO
67222732Shrs#define IPV6_RECVPKTINFO	IPV6_PKTINFO
68222732Shrs#endif
69222732Shrs#endif
70222732Shrs
71222732Shrs/*
72222732Shrs * RFC 3542 API deprecates IPV6_HOPLIMIT in favor of
73222732Shrs * IPV6_RECVHOPLIMIT
74222732Shrs */
75222732Shrs#ifndef IPV6_RECVHOPLIMIT
76222732Shrs#ifdef IPV6_HOPLIMIT
77222732Shrs#define IPV6_RECVHOPLIMIT	IPV6_HOPLIMIT
78222732Shrs#endif
79222732Shrs#endif
80222732Shrs
8155505Sshin/* protocol constants and default values */
8262656Skris#define DEF_MAXRTRADVINTERVAL 600
8362656Skris#define DEF_ADVLINKMTU 0
8462656Skris#define DEF_ADVREACHABLETIME 0
8562656Skris#define DEF_ADVRETRANSTIMER 0
8662656Skris#define DEF_ADVCURHOPLIMIT 64
8762656Skris#define DEF_ADVVALIDLIFETIME 2592000
8862656Skris#define DEF_ADVPREFERREDLIFETIME 604800
8955505Sshin
9062656Skris#define MAXROUTERLIFETIME 9000
91118968Sume#define MIN_MAXINTERVAL 4
9262656Skris#define MAX_MAXINTERVAL 1800
93118672Sume#define MIN_MININTERVAL 3
9462656Skris#define MAXREACHABLETIME 3600000
9555505Sshin
9662656Skris#define MAX_INITIAL_RTR_ADVERT_INTERVAL  16
9762656Skris#define MAX_INITIAL_RTR_ADVERTISEMENTS    3
9862656Skris#define MAX_FINAL_RTR_ADVERTISEMENTS      3
9962656Skris#define MIN_DELAY_BETWEEN_RAS             3
10062656Skris#define MAX_RA_DELAY_TIME                 500000 /* usec */
10162656Skris
10262656Skris#define PREFIX_FROM_KERNEL 1
10362656Skris#define PREFIX_FROM_CONFIG 2
10462656Skris#define PREFIX_FROM_DYNAMIC 3
10562656Skris
10655505Sshinstruct prefix {
107222732Shrs	TAILQ_ENTRY(prefix)	pfx_next;
10855505Sshin
109222732Shrs	struct rainfo *pfx_rainfo;	/* back pointer to the interface */
110222732Shrs	/*
111222732Shrs	 * Expiration timer.  This is used when a prefix derived from
112222732Shrs	 * the kernel is deleted.
113222732Shrs	 */
114222732Shrs	struct rtadvd_timer *pfx_timer;
11598172Sume
116224144Shrs	uint32_t	pfx_validlifetime;	/* AdvValidLifetime */
117224144Shrs	uint32_t       	pfx_vltimeexpire;	/* Expiration of vltime */
118224144Shrs	uint32_t	pfx_preflifetime;	/* AdvPreferredLifetime */
119224144Shrs	uint32_t	pfx_pltimeexpire;	/* Expiration of pltime */
120224144Shrs	int		pfx_onlinkflg;		/* bool: AdvOnLinkFlag */
121224144Shrs	int		pfx_autoconfflg;	/* bool: AdvAutonomousFlag */
122222732Shrs	int		pfx_prefixlen;
123222732Shrs	int		pfx_origin;		/* From kernel or config */
12498172Sume
125222732Shrs	struct in6_addr	pfx_prefix;
12655505Sshin};
12755505Sshin
12878064Sumestruct rtinfo {
129222732Shrs	TAILQ_ENTRY(rtinfo)	rti_next;
13078064Sume
131224144Shrs	uint32_t	rti_ltime;	/* route lifetime */
132224144Shrs	int		rti_rtpref;	/* route preference */
133222732Shrs	int		rti_prefixlen;
134222732Shrs	struct in6_addr	rti_prefix;
13578064Sume};
13678064Sume
137222732Shrsstruct rdnss_addr {
138222732Shrs	TAILQ_ENTRY(rdnss_addr)	ra_next;
139222732Shrs
140222732Shrs	struct in6_addr ra_dns;	/* DNS server entry */
141222732Shrs};
142222732Shrs
143222732Shrsstruct rdnss {
144222732Shrs	TAILQ_ENTRY(rdnss) rd_next;
145222732Shrs
146222732Shrs	TAILQ_HEAD(, rdnss_addr) rd_list;	/* list of DNS servers */
147224144Shrs	uint32_t rd_ltime;	/* number of seconds valid */
148222732Shrs};
149222732Shrs
150222732Shrs/*
151222732Shrs * The maximum length of a domain name in a DNS search list is calculated
152222732Shrs * by a domain name + length fields per 63 octets + a zero octet at
153222732Shrs * the tail and adding 8 octet boundary padding.
154222732Shrs */
155222732Shrs#define _DNAME_LABELENC_MAXLEN \
156222732Shrs	(NI_MAXHOST + (NI_MAXHOST / 64 + 1) + 1)
157222732Shrs
158222732Shrs#define DNAME_LABELENC_MAXLEN \
159222732Shrs	(_DNAME_LABELENC_MAXLEN + 8 - _DNAME_LABELENC_MAXLEN % 8)
160222732Shrs
161222732Shrsstruct dnssl_addr {
162222732Shrs	TAILQ_ENTRY(dnssl_addr)	da_next;
163222732Shrs
164222732Shrs	int da_len;				/* length of entry */
165222732Shrs	char da_dom[DNAME_LABELENC_MAXLEN];	/* search domain name entry */
166222732Shrs};
167222732Shrs
168222732Shrsstruct dnssl {
169222732Shrs	TAILQ_ENTRY(dnssl)	dn_next;
170222732Shrs
171222732Shrs	TAILQ_HEAD(, dnssl_addr) dn_list;	/* list of search domains */
172224144Shrs	uint32_t dn_ltime;			/* number of seconds valid */
173222732Shrs};
174222732Shrs
17562656Skrisstruct soliciter {
176222732Shrs	TAILQ_ENTRY(soliciter)	sol_next;
177222732Shrs
178222732Shrs	struct sockaddr_in6	sol_addr;
17962656Skris};
18062656Skris
18155505Sshinstruct	rainfo {
18255505Sshin	/* pointer for list */
183222732Shrs	TAILQ_ENTRY(rainfo)	rai_next;
18455505Sshin
185224144Shrs	/* interface information */
186224144Shrs	struct ifinfo *rai_ifinfo;
18755505Sshin
188224144Shrs	int	rai_advlinkopt;		/* bool: whether include link-layer addr opt */
189222732Shrs	int	rai_advifprefix;	/* bool: gather IF prefixes? */
19055505Sshin
19155505Sshin	/* Router configuration variables */
192224144Shrs	uint16_t	rai_lifetime;		/* AdvDefaultLifetime */
193224144Shrs	uint16_t	rai_maxinterval;	/* MaxRtrAdvInterval */
194224144Shrs	uint16_t	rai_mininterval;	/* MinRtrAdvInterval */
195222732Shrs	int 	rai_managedflg;		/* AdvManagedFlag */
196222732Shrs	int	rai_otherflg;		/* AdvOtherConfigFlag */
197118664Sume
198222732Shrs	int	rai_rtpref;		/* router preference */
199224144Shrs	uint32_t	rai_linkmtu;		/* AdvLinkMTU */
200224144Shrs	uint32_t	rai_reachabletime;	/* AdvReachableTime */
201224144Shrs	uint32_t	rai_retranstimer;	/* AdvRetransTimer */
202224144Shrs	uint8_t	rai_hoplimit;		/* AdvCurHopLimit */
20355505Sshin
204222732Shrs	TAILQ_HEAD(, prefix) rai_prefix;/* AdvPrefixList(link head) */
205222732Shrs	int	rai_pfxs;		/* number of prefixes */
206222732Shrs
207224144Shrs	uint16_t	rai_clockskew;	/* used for consisitency check of lifetimes */
208222732Shrs
209222732Shrs	TAILQ_HEAD(, rdnss) rai_rdnss;	/* DNS server list */
210222732Shrs	TAILQ_HEAD(, dnssl) rai_dnssl;	/* search domain list */
211222732Shrs	TAILQ_HEAD(, rtinfo) rai_route;	/* route information option (link head) */
212222732Shrs	int	rai_routes;		/* number of route information options */
21355505Sshin	/* actual RA packet data and its length */
214222732Shrs	size_t	rai_ra_datalen;
215224144Shrs	char	*rai_ra_data;
21662656Skris
21762656Skris	/* info about soliciter */
218222732Shrs	TAILQ_HEAD(, soliciter) rai_soliciter;	/* recent solication source */
21955505Sshin};
22055505Sshin
221224144Shrs/* RA information list */
222222732Shrsextern TAILQ_HEAD(railist_head_t, rainfo) railist;
22362656Skris
224224144Shrs/*
225224144Shrs * ifi_state:
226224144Shrs *
227224144Shrs *           (INIT)
228224144Shrs *              |
229224144Shrs *              | update_ifinfo()
230224144Shrs *              | update_persist_ifinfo()
231224144Shrs *              v
232224144Shrs *         UNCONFIGURED
233224144Shrs *               |  ^
234224144Shrs *   loadconfig()|  |rm_ifinfo(), ra_output()
235224144Shrs *      (MC join)|  |(MC leave)
236224144Shrs *               |  |
237224144Shrs *               |  |
238224144Shrs *               v  |
239224144Shrs *         TRANSITIVE
240224144Shrs *               |  ^
241224144Shrs *    ra_output()|  |getconfig()
242224144Shrs *               |  |
243224144Shrs *               |  |
244224144Shrs *               |  |
245224144Shrs *               v  |
246224144Shrs *         CONFIGURED
247224144Shrs *
248224144Shrs *
249224144Shrs */
250224144Shrs#define	IFI_STATE_UNCONFIGURED	0
251224144Shrs#define	IFI_STATE_CONFIGURED	1
252224144Shrs#define	IFI_STATE_TRANSITIVE	2
253224144Shrs
254224144Shrsstruct	ifinfo {
255224144Shrs	TAILQ_ENTRY(ifinfo)	ifi_next;
256224144Shrs
257224144Shrs	uint16_t	ifi_state;
258224144Shrs	uint16_t	ifi_persist;
259224144Shrs	uint16_t	ifi_ifindex;
260224144Shrs	char	ifi_ifname[IFNAMSIZ];
261224144Shrs	uint8_t	ifi_type;
262224144Shrs	uint16_t	ifi_flags;
263224144Shrs	uint32_t	ifi_nd_flags;
264224144Shrs	uint32_t	ifi_phymtu;
265224144Shrs	struct sockaddr_dl	ifi_sdl;
266224144Shrs
267224144Shrs	struct rainfo	*ifi_rainfo;
268224144Shrs	struct rainfo	*ifi_rainfo_trans;
269224144Shrs	uint16_t	ifi_burstcount;
270224144Shrs	uint32_t	ifi_burstinterval;
271224144Shrs	struct rtadvd_timer	*ifi_ra_timer;
272224144Shrs	/* timestamp when the latest RA was sent */
273253970Shrs	struct timespec		ifi_ra_lastsent;
274224144Shrs	uint16_t	ifi_rs_waitcount;
275224144Shrs
276224144Shrs	/* statistics */
277224144Shrs	uint64_t ifi_raoutput;		/* # of RAs sent */
278224144Shrs	uint64_t ifi_rainput;		/* # of RAs received */
279224144Shrs	uint64_t ifi_rainconsistent;	/* # of inconsistent recv'd RAs  */
280224144Shrs	uint64_t ifi_rsinput;		/* # of RSs received */
281224144Shrs};
282224144Shrs
283224144Shrs/* Interface list */
284224144Shrsextern TAILQ_HEAD(ifilist_head_t, ifinfo) ifilist;
285224144Shrs
286224144Shrsextern char *mcastif;
287224144Shrs
288222732Shrsstruct rtadvd_timer	*ra_timeout(void *);
289253970Shrsvoid			ra_timer_update(void *, struct timespec *);
290224144Shrsvoid			ra_output(struct ifinfo *);
29178064Sume
292222732Shrsint			prefix_match(struct in6_addr *, int,
293222732Shrs			    struct in6_addr *, int);
294224144Shrsstruct ifinfo		*if_indextoifinfo(int);
295222732Shrsstruct prefix		*find_prefix(struct rainfo *,
296222732Shrs			    struct in6_addr *, int);
297224144Shrsvoid			rtadvd_set_reload(int);
298224144Shrsvoid			rtadvd_set_shutdown(int);
299