nd6.h revision 53541
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: head/sys/netinet6/nd6.h 53541 1999-11-22 02:45:11Z shin $ 30 */ 31 32#ifndef _NETINET6_ND6_H_ 33#define _NETINET6_ND6_H_ 34 35#include <sys/queue.h> 36 37struct 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 56struct 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 67struct 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 78struct 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 89struct 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 104struct 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 127struct nd_defrouter { 128 LIST_ENTRY(nd_defrouter) dr_entry; 129#define dr_next dr_entry.le_next 130 struct in6_addr rtaddr; 131 u_char flags; 132 u_short rtlifetime; 133 u_long expire; 134 struct ifnet *ifp; 135}; 136 137struct nd_prefix { 138 struct ifnet *ndpr_ifp; 139 LIST_ENTRY(nd_prefix) ndpr_entry; 140 struct sockaddr_in6 ndpr_prefix; /* prefix */ 141 struct in6_addr ndpr_mask; /* netmask derived from the prefix */ 142 struct in6_addr ndpr_addr; /* address that is derived from the prefix */ 143 u_int32_t ndpr_vltime; /* advertised valid lifetime */ 144 u_int32_t ndpr_pltime; /* advertised preferred lifetime */ 145 time_t ndpr_expire; /* expiration time of the prefix */ 146 time_t ndpr_preferred; /* preferred time of the prefix */ 147 struct prf_ra ndpr_flags; 148 /* list of routers that advertise the prefix: */ 149 LIST_HEAD(pr_rtrhead, nd_pfxrouter) ndpr_advrtrs; 150 u_char ndpr_plen; 151 struct ndpr_stateflags { 152 /* if this prefix can be regarded as on-link */ 153 u_char onlink : 1; 154 } ndpr_stateflags; 155}; 156 157#define ndpr_next ndpr_entry.le_next 158 159#define ndpr_raf ndpr_flags 160#define ndpr_raf_onlink ndpr_flags.onlink 161#define ndpr_raf_auto ndpr_flags.autonomous 162 163#define ndpr_statef_onlink ndpr_stateflags.onlink 164#define ndpr_statef_addmark ndpr_stateflags.addmark 165 166/* 167 * We keep expired prefix for certain amount of time, for validation purposes. 168 * 1800s = MaxRtrAdvInterval 169 */ 170#define NDPR_KEEP_EXPIRED (1800 * 2) 171 172/* 173 * Message format for use in obtaining information about prefixes 174 * from inet6 sysctl function 175 */ 176struct inet6_ndpr_msghdr { 177 u_short inpm_msglen; /* to skip over non-understood messages */ 178 u_char inpm_version; /* future binary compatability */ 179 u_char inpm_type; /* message type */ 180 struct in6_addr inpm_prefix; 181 u_long prm_vltim; 182 u_long prm_pltime; 183 u_long prm_expire; 184 u_long prm_preferred; 185 struct in6_prflags prm_flags; 186 u_short prm_index; /* index for associated ifp */ 187 u_char prm_plen; /* length of prefix in bits */ 188}; 189 190#define prm_raf_onlink prm_flags.prf_ra.onlink 191#define prm_raf_auto prm_flags.prf_ra.autonomous 192 193#define prm_statef_onlink prm_flags.prf_state.onlink 194 195#define prm_rrf_decrvalid prm_flags.prf_rr.decrvalid 196#define prm_rrf_decrprefd prm_flags.prf_rr.decrprefd 197 198#define ifpr2ndpr(ifpr) ((struct nd_prefix *)(ifpr)) 199#define ndpr2ifpr(ndpr) ((struct ifprefix *)(ndpr)) 200 201struct nd_pfxrouter { 202 LIST_ENTRY(nd_pfxrouter) pfr_entry; 203#define pfr_next pfr_entry.le_next 204 struct nd_defrouter *router; 205}; 206 207LIST_HEAD(nd_drhead, nd_defrouter); 208LIST_HEAD(nd_prhead, nd_prefix); 209 210/* nd6.c */ 211extern int nd6_prune; 212extern int nd6_delay; 213extern int nd6_umaxtries; 214extern int nd6_mmaxtries; 215extern int nd6_useloopback; 216extern int nd6_proxyall; 217extern struct llinfo_nd6 llinfo_nd6; 218extern struct nd_ifinfo *nd_ifinfo; 219extern struct nd_drhead nd_defrouter; 220extern struct nd_prhead nd_prefix; 221 222union nd_opts { 223 struct nd_opt_hdr *nd_opt_array[9]; 224 struct { 225 struct nd_opt_hdr *zero; 226 struct nd_opt_hdr *src_lladdr; 227 struct nd_opt_hdr *tgt_lladdr; 228 struct nd_opt_prefix_info *pi_beg;/* multiple opts, start */ 229 struct nd_opt_rd_hdr *rh; 230 struct nd_opt_mtu *mtu; 231 struct nd_opt_hdr *search; /* multiple opts */ 232 struct nd_opt_hdr *last; /* multiple opts */ 233 int done; 234 struct nd_opt_prefix_info *pi_end;/* multiple opts, end */ 235 } nd_opt_each; 236}; 237#define nd_opts_src_lladdr nd_opt_each.src_lladdr 238#define nd_opts_tgt_lladdr nd_opt_each.tgt_lladdr 239#define nd_opts_pi nd_opt_each.pi_beg 240#define nd_opts_pi_end nd_opt_each.pi_end 241#define nd_opts_rh nd_opt_each.rh 242#define nd_opts_mtu nd_opt_each.mtu 243#define nd_opts_search nd_opt_each.search 244#define nd_opts_last nd_opt_each.last 245#define nd_opts_done nd_opt_each.done 246 247/* XXX: need nd6_var.h?? */ 248/* nd6.c */ 249void nd6_init __P((void)); 250void nd6_ifattach __P((struct ifnet *)); 251int nd6_is_addr_neighbor __P((struct in6_addr *, struct ifnet *)); 252void nd6_option_init __P((void *, int, union nd_opts *)); 253struct nd_opt_hdr *nd6_option __P((union nd_opts *)); 254int nd6_options __P((union nd_opts *)); 255struct rtentry *nd6_lookup __P((struct in6_addr *, int, struct ifnet *)); 256void nd6_setmtu __P((struct ifnet *)); 257void nd6_timer __P((void *)); 258void nd6_free __P((struct rtentry *)); 259void nd6_nud_hint __P((struct rtentry *, struct in6_addr *)); 260int nd6_resolve __P((struct ifnet *, struct rtentry *, 261 struct mbuf *, struct sockaddr *, u_char *)); 262void nd6_rtrequest __P((int, struct rtentry *, struct sockaddr *)); 263void nd6_p2p_rtrequest __P((int, struct rtentry *, struct sockaddr *)); 264int nd6_ioctl __P((u_long, caddr_t, struct ifnet *)); 265struct rtentry *nd6_cache_lladdr __P((struct ifnet *, struct in6_addr *, 266 char *, int, int, int)); 267/* for test */ 268int nd6_output __P((struct ifnet *, struct mbuf *, struct sockaddr_in6 *, 269 struct rtentry *)); 270int nd6_storelladdr __P((struct ifnet *, struct rtentry *, struct mbuf *, 271 struct sockaddr *, u_char *)); 272 273/* nd6_nbr.c */ 274void nd6_na_input __P((struct mbuf *, int, int)); 275void nd6_na_output __P((struct ifnet *, struct in6_addr *, 276 struct in6_addr *, u_long, int)); 277void nd6_ns_input __P((struct mbuf *, int, int)); 278void nd6_ns_output __P((struct ifnet *, struct in6_addr *, 279 struct in6_addr *, struct llinfo_nd6 *, int)); 280caddr_t nd6_ifptomac __P((struct ifnet *)); 281void nd6_dad_start __P((struct ifaddr *, int *)); 282void nd6_dad_duplicated __P((struct ifaddr *)); 283 284/* nd6_rtr.c */ 285void nd6_rs_input __P((struct mbuf *, int, int)); 286void nd6_ra_input __P((struct mbuf *, int, int)); 287void prelist_del __P((struct nd_prefix *)); 288void defrouter_addreq __P((struct nd_defrouter *)); 289void defrouter_delreq __P((struct nd_defrouter *, int)); 290void defrtrlist_del __P((struct nd_defrouter *)); 291void prelist_remove __P((struct nd_prefix *)); 292int prelist_update __P((struct nd_prefix *, struct nd_defrouter *, 293 struct mbuf *)); 294struct nd_defrouter *defrouter_lookup __P((struct in6_addr *, 295 struct ifnet *)); 296int in6_ifdel __P((struct ifnet *, struct in6_addr *)); 297int in6_init_prefix_ltimes __P((struct nd_prefix *ndpr)); 298void rt6_flush __P((struct in6_addr *, struct ifnet *)); 299 300#endif /* _KERNEL */ 301 302#endif /* _NETINET6_ND6_H_ */ 303