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 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