1 /* 2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the project nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $FreeBSD$ 30 */ 31 32 #ifndef _NETINET6_ND6_H_ 33 #define _NETINET6_ND6_H_ 34 35 #include <sys/queue.h> 36 37 struct llinfo_nd6 { 38 struct llinfo_nd6 *ln_next; 39 struct llinfo_nd6 *ln_prev; 40 struct rtentry *ln_rt; 41 struct mbuf *ln_hold; /* last packet until resolved/timeout */ 42 long ln_asked; /* number of queries already sent for this addr */ 43 u_long ln_expire; /* lifetime for NDP state transition */ 44 short ln_state; /* reachability state */ 45 short ln_router; /* 2^0: ND6 router bit */ 46 }; 47 48 #define ND6_LLINFO_NOSTATE -2 49 #define ND6_LLINFO_WAITDELETE -1 50 #define ND6_LLINFO_INCOMPLETE 0 51 #define ND6_LLINFO_REACHABLE 1 52 #define ND6_LLINFO_STALE 2 53 #define ND6_LLINFO_DELAY 3 54 #define ND6_LLINFO_PROBE 4 55 56 struct nd_ifinfo { 57 u_int32_t linkmtu; /* LinkMTU */ 58 u_int32_t maxmtu; /* Upper bound of LinkMTU */ 59 u_int32_t basereachable; /* BaseReachableTime */ 60 u_int32_t reachable; /* Reachable Time */ 61 u_int32_t retrans; /* Retrans Timer */ 62 int recalctm; /* BaseReacable re-calculation timer */ 63 u_int8_t chlim; /* CurHopLimit */ 64 u_int8_t receivedra; 65 }; 66 67 struct in6_nbrinfo { 68 char ifname[IFNAMSIZ]; /* if name, e.g. "en0" */ 69 struct in6_addr addr; /* IPv6 address of the neighbor */ 70 long asked; /* number of queries already sent for this addr */ 71 int isrouter; /* if it acts as a router */ 72 int state; /* reachability state */ 73 int expire; /* lifetime for NDP state transition */ 74 }; 75 76 #define DRLSTSIZ 10 77 #define PRLSTSIZ 10 78 struct in6_drlist { 79 char ifname[IFNAMSIZ]; 80 struct { 81 struct in6_addr rtaddr; 82 u_char flags; 83 u_short rtlifetime; 84 u_long expire; 85 u_short if_index; 86 } defrouter[DRLSTSIZ]; 87 }; 88 89 struct in6_prlist { 90 char ifname[IFNAMSIZ]; 91 struct { 92 struct in6_addr prefix; 93 struct prf_ra raflags; 94 u_char prefixlen; 95 u_long vltime; 96 u_long pltime; 97 u_long expire; 98 u_short if_index; 99 u_short advrtrs; /* number of advertisement routers */ 100 struct in6_addr advrtr[DRLSTSIZ]; /* XXX: explicit limit */ 101 } prefix[PRLSTSIZ]; 102 }; 103 104 struct in6_ndireq { 105 char ifname[IFNAMSIZ]; 106 struct nd_ifinfo ndi; 107 }; 108 109 /* protocol constants */ 110 #define MAX_RTR_SOLICITATION_DELAY 1 /*1sec*/ 111 #define RTR_SOLICITATION_INTERVAL 4 /*4sec*/ 112 #define MAX_RTR_SOLICITATIONS 3 113 114 #define ND6_INFINITE_LIFETIME 0xffffffff 115 116 #ifdef _KERNEL 117 /* node constants */ 118 #define MAX_REACHABLE_TIME 3600000 /* msec */ 119 #define REACHABLE_TIME 30000 /* msec */ 120 #define RETRANS_TIMER 1000 /* msec */ 121 #define MIN_RANDOM_FACTOR 512 /* 1024 * 0.5 */ 122 #define MAX_RANDOM_FACTOR 1536 /* 1024 * 1.5 */ 123 #define ND_COMPUTE_RTIME(x) \ 124 (((MIN_RANDOM_FACTOR * (x >> 10)) + (random() & \ 125 ((MAX_RANDOM_FACTOR - MIN_RANDOM_FACTOR) * (x >> 10)))) /1000) 126 127 struct nd_defrouter { 128 LIST_ENTRY(nd_defrouter) dr_entry; 129 struct in6_addr rtaddr; 130 u_char flags; 131 u_short rtlifetime; 132 u_long expire; 133 struct ifnet *ifp; 134 }; 135 136 struct nd_prefix { 137 struct ifnet *ndpr_ifp; 138 LIST_ENTRY(nd_prefix) ndpr_entry; 139 struct sockaddr_in6 ndpr_prefix; /* prefix */ 140 struct in6_addr ndpr_mask; /* netmask derived from the prefix */ 141 struct in6_addr ndpr_addr; /* address that is derived from the prefix */ 142 u_int32_t ndpr_vltime; /* advertised valid lifetime */ 143 u_int32_t ndpr_pltime; /* advertised preferred lifetime */ 144 time_t ndpr_expire; /* expiration time of the prefix */ 145 time_t ndpr_preferred; /* preferred time of the prefix */ 146 struct prf_ra ndpr_flags; 147 /* list of routers that advertise the prefix: */ 148 LIST_HEAD(pr_rtrhead, nd_pfxrouter) ndpr_advrtrs; 149 u_char ndpr_plen; 150 struct ndpr_stateflags { 151 /* if this prefix can be regarded as on-link */ 152 u_char onlink : 1; 153 } ndpr_stateflags; 154 }; 155 156 #define ndpr_raf ndpr_flags 157 #define ndpr_raf_onlink ndpr_flags.onlink 158 #define ndpr_raf_auto ndpr_flags.autonomous 159 160 #define ndpr_statef_onlink ndpr_stateflags.onlink 161 #define ndpr_statef_addmark ndpr_stateflags.addmark 162 163 /* 164 * We keep expired prefix for certain amount of time, for validation purposes. 165 * 1800s = MaxRtrAdvInterval 166 */ 167 #define NDPR_KEEP_EXPIRED (1800 * 2) 168 169 /* 170 * Message format for use in obtaining information about prefixes 171 * from inet6 sysctl function 172 */ 173 struct inet6_ndpr_msghdr { 174 u_short inpm_msglen; /* to skip over non-understood messages */ 175 u_char inpm_version; /* future binary compatability */ 176 u_char inpm_type; /* message type */ 177 struct in6_addr inpm_prefix; 178 u_long prm_vltim; 179 u_long prm_pltime; 180 u_long prm_expire; 181 u_long prm_preferred; 182 struct in6_prflags prm_flags; 183 u_short prm_index; /* index for associated ifp */ 184 u_char prm_plen; /* length of prefix in bits */ 185 }; 186 187 #define prm_raf_onlink prm_flags.prf_ra.onlink 188 #define prm_raf_auto prm_flags.prf_ra.autonomous 189 190 #define prm_statef_onlink prm_flags.prf_state.onlink 191 192 #define prm_rrf_decrvalid prm_flags.prf_rr.decrvalid 193 #define prm_rrf_decrprefd prm_flags.prf_rr.decrprefd 194 195 #define ifpr2ndpr(ifpr) ((struct nd_prefix *)(ifpr)) 196 #define ndpr2ifpr(ndpr) ((struct ifprefix *)(ndpr)) 197 198 struct nd_pfxrouter { 199 LIST_ENTRY(nd_pfxrouter) pfr_entry; 200 struct nd_defrouter *router; 201 }; 202 203 LIST_HEAD(nd_drhead, nd_defrouter); 204 LIST_HEAD(nd_prhead, nd_prefix); 205 206 /* nd6.c */ 207 extern int nd6_prune; 208 extern int nd6_delay; 209 extern int nd6_umaxtries; 210 extern int nd6_mmaxtries; 211 extern int nd6_useloopback; 212 extern int nd6_proxyall; 213 extern struct llinfo_nd6 llinfo_nd6; 214 extern struct nd_ifinfo *nd_ifinfo; 215 extern struct nd_drhead nd_defrouter; 216 extern struct nd_prhead nd_prefix; 217 218 union nd_opts { 219 struct nd_opt_hdr *nd_opt_array[9]; 220 struct { 221 struct nd_opt_hdr *zero; 222 struct nd_opt_hdr *src_lladdr; 223 struct nd_opt_hdr *tgt_lladdr; 224 struct nd_opt_prefix_info *pi_beg;/* multiple opts, start */ 225 struct nd_opt_rd_hdr *rh; 226 struct nd_opt_mtu *mtu; 227 struct nd_opt_hdr *search; /* multiple opts */ 228 struct nd_opt_hdr *last; /* multiple opts */ 229 int done; 230 struct nd_opt_prefix_info *pi_end;/* multiple opts, end */ 231 } nd_opt_each; 232 }; 233 #define nd_opts_src_lladdr nd_opt_each.src_lladdr 234 #define nd_opts_tgt_lladdr nd_opt_each.tgt_lladdr 235 #define nd_opts_pi nd_opt_each.pi_beg 236 #define nd_opts_pi_end nd_opt_each.pi_end 237 #define nd_opts_rh nd_opt_each.rh 238 #define nd_opts_mtu nd_opt_each.mtu 239 #define nd_opts_search nd_opt_each.search 240 #define nd_opts_last nd_opt_each.last 241 #define nd_opts_done nd_opt_each.done 242 243 /* XXX: need nd6_var.h?? */ 244 /* nd6.c */ 245 void nd6_init __P((void)); 246 void nd6_ifattach __P((struct ifnet *)); 247 int nd6_is_addr_neighbor __P((struct in6_addr *, struct ifnet *)); 248 void nd6_option_init __P((void *, int, union nd_opts *)); 249 struct nd_opt_hdr *nd6_option __P((union nd_opts *)); 250 int nd6_options __P((union nd_opts *)); 251 struct rtentry *nd6_lookup __P((struct in6_addr *, int, struct ifnet *)); 252 void nd6_setmtu __P((struct ifnet *)); 253 void nd6_timer __P((void *)); 254 void nd6_free __P((struct rtentry *)); 255 void nd6_nud_hint __P((struct rtentry *, struct in6_addr *)); 256 int nd6_resolve __P((struct ifnet *, struct rtentry *, 257 struct mbuf *, struct sockaddr *, u_char *)); 258 void nd6_rtrequest __P((int, struct rtentry *, struct sockaddr *)); 259 void nd6_p2p_rtrequest __P((int, struct rtentry *, struct sockaddr *)); 260 int nd6_ioctl __P((u_long, caddr_t, struct ifnet *)); 261 struct rtentry *nd6_cache_lladdr __P((struct ifnet *, struct in6_addr *, 262 char *, int, int, int)); 263 /* for test */ 264 int nd6_output __P((struct ifnet *, struct mbuf *, struct sockaddr_in6 *, 265 struct rtentry *)); 266 int nd6_storelladdr __P((struct ifnet *, struct rtentry *, struct mbuf *, 267 struct sockaddr *, u_char *)); 268 269 /* nd6_nbr.c */ 270 void nd6_na_input __P((struct mbuf *, int, int)); 271 void nd6_na_output __P((struct ifnet *, struct in6_addr *, 272 struct in6_addr *, u_long, int)); 273 void nd6_ns_input __P((struct mbuf *, int, int)); 274 void nd6_ns_output __P((struct ifnet *, struct in6_addr *, 275 struct in6_addr *, struct llinfo_nd6 *, int)); 276 caddr_t nd6_ifptomac __P((struct ifnet *)); 277 void nd6_dad_start __P((struct ifaddr *, int *)); 278 void nd6_dad_duplicated __P((struct ifaddr *)); 279 280 /* nd6_rtr.c */ 281 void nd6_rs_input __P((struct mbuf *, int, int)); 282 void nd6_ra_input __P((struct mbuf *, int, int)); 283 void prelist_del __P((struct nd_prefix *)); 284 void defrouter_addreq __P((struct nd_defrouter *)); 285 void defrouter_delreq __P((struct nd_defrouter *, int)); 286 void defrtrlist_del __P((struct nd_defrouter *)); 287 void prelist_remove __P((struct nd_prefix *)); 288 int prelist_update __P((struct nd_prefix *, struct nd_defrouter *, 289 struct mbuf *)); 290 struct nd_defrouter *defrouter_lookup __P((struct in6_addr *, 291 struct ifnet *)); 292 int in6_ifdel __P((struct ifnet *, struct in6_addr *)); 293 int in6_init_prefix_ltimes __P((struct nd_prefix *ndpr)); 294 void rt6_flush __P((struct in6_addr *, struct ifnet *)); 295 296 #endif /* _KERNEL */ 297 298 #endif /* _NETINET6_ND6_H_ */ 299