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