xref: /dragonfly/usr.sbin/rtadvd/rtadvd.h (revision c17e6018cab90fba83aa80d4974cfbeb9a5e75ca)
1 /*        $FreeBSD: stable/10/usr.sbin/rtadvd/rtadvd.h 253970 2013-08-05 20:13:02Z hrs $  */
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 
57 extern struct sockaddr_in6 sin6_linklocal_allnodes;
58 extern struct sockaddr_in6 sin6_linklocal_allrouters;
59 extern 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 
106 struct 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 
128 struct 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 
137 struct rdnss_addr {
138           TAILQ_ENTRY(rdnss_addr)       ra_next;
139 
140           struct in6_addr ra_dns;       /* DNS server entry */
141 };
142 
143 struct 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 
161 struct 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 
168 struct 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 
175 struct soliciter {
176           TAILQ_ENTRY(soliciter)        sol_next;
177 
178           struct sockaddr_in6 sol_addr;
179 };
180 
181 struct    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 */
222 extern 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 
254 struct    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 timespec               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 */
284 extern TAILQ_HEAD(ifilist_head_t, ifinfo) ifilist;
285 
286 extern char *mcastif;
287 
288 struct rtadvd_timer *ra_timeout(void *);
289 void                          ra_timer_update(void *, struct timespec *);
290 void                          ra_output(struct ifinfo *);
291 
292 int                           prefix_match(struct in6_addr *, int,
293                                   struct in6_addr *, int);
294 struct ifinfo                 *if_indextoifinfo(int);
295 struct prefix                 *find_prefix(struct rainfo *,
296                                   struct in6_addr *, int);
297 void                          rtadvd_set_reload(int);
298 void                          rtadvd_set_shutdown(int);
299