1 1.258 rin /* $NetBSD: icmp6.c,v 1.258 2024/07/05 04:31:54 rin Exp $ */ 2 1.66 itojun /* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */ 3 1.3 thorpej 4 1.2 itojun /* 5 1.2 itojun * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 1.2 itojun * All rights reserved. 7 1.29 itojun * 8 1.2 itojun * Redistribution and use in source and binary forms, with or without 9 1.2 itojun * modification, are permitted provided that the following conditions 10 1.2 itojun * are met: 11 1.2 itojun * 1. Redistributions of source code must retain the above copyright 12 1.2 itojun * notice, this list of conditions and the following disclaimer. 13 1.2 itojun * 2. Redistributions in binary form must reproduce the above copyright 14 1.2 itojun * notice, this list of conditions and the following disclaimer in the 15 1.2 itojun * documentation and/or other materials provided with the distribution. 16 1.2 itojun * 3. Neither the name of the project nor the names of its contributors 17 1.2 itojun * may be used to endorse or promote products derived from this software 18 1.2 itojun * without specific prior written permission. 19 1.29 itojun * 20 1.2 itojun * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 1.2 itojun * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 1.2 itojun * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 1.2 itojun * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 1.2 itojun * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 1.2 itojun * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 1.2 itojun * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 1.2 itojun * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 1.2 itojun * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 1.2 itojun * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 1.2 itojun * SUCH DAMAGE. 31 1.2 itojun */ 32 1.2 itojun 33 1.2 itojun /* 34 1.2 itojun * Copyright (c) 1982, 1986, 1988, 1993 35 1.2 itojun * The Regents of the University of California. All rights reserved. 36 1.2 itojun * 37 1.2 itojun * Redistribution and use in source and binary forms, with or without 38 1.2 itojun * modification, are permitted provided that the following conditions 39 1.2 itojun * are met: 40 1.2 itojun * 1. Redistributions of source code must retain the above copyright 41 1.2 itojun * notice, this list of conditions and the following disclaimer. 42 1.2 itojun * 2. Redistributions in binary form must reproduce the above copyright 43 1.2 itojun * notice, this list of conditions and the following disclaimer in the 44 1.2 itojun * documentation and/or other materials provided with the distribution. 45 1.96 agc * 3. Neither the name of the University nor the names of its contributors 46 1.2 itojun * may be used to endorse or promote products derived from this software 47 1.2 itojun * without specific prior written permission. 48 1.2 itojun * 49 1.2 itojun * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 50 1.2 itojun * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 1.2 itojun * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 1.2 itojun * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 53 1.2 itojun * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 1.2 itojun * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 1.2 itojun * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 1.2 itojun * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 1.2 itojun * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 1.2 itojun * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 1.2 itojun * SUCH DAMAGE. 60 1.2 itojun * 61 1.2 itojun * @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94 62 1.2 itojun */ 63 1.71 lukem 64 1.71 lukem #include <sys/cdefs.h> 65 1.258 rin __KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.258 2024/07/05 04:31:54 rin Exp $"); 66 1.2 itojun 67 1.175 pooka #ifdef _KERNEL_OPT 68 1.245 roy #include "opt_compat_netbsd.h" 69 1.2 itojun #include "opt_inet.h" 70 1.6 thorpej #include "opt_ipsec.h" 71 1.175 pooka #endif 72 1.2 itojun 73 1.2 itojun #include <sys/param.h> 74 1.2 itojun #include <sys/systm.h> 75 1.167 rmind #include <sys/kmem.h> 76 1.2 itojun #include <sys/mbuf.h> 77 1.2 itojun #include <sys/protosw.h> 78 1.2 itojun #include <sys/socket.h> 79 1.2 itojun #include <sys/socketvar.h> 80 1.2 itojun #include <sys/time.h> 81 1.2 itojun #include <sys/kernel.h> 82 1.2 itojun #include <sys/syslog.h> 83 1.12 itojun #include <sys/domain.h> 84 1.70 simonb #include <sys/sysctl.h> 85 1.2 itojun 86 1.2 itojun #include <net/if.h> 87 1.2 itojun #include <net/route.h> 88 1.2 itojun #include <net/if_dl.h> 89 1.2 itojun #include <net/if_types.h> 90 1.247 roy #include <net/nd.h> 91 1.2 itojun 92 1.2 itojun #include <netinet/in.h> 93 1.253 ozaki #include <netinet/in_pcb.h> 94 1.2 itojun #include <netinet/in_var.h> 95 1.19 itojun #include <netinet/ip6.h> 96 1.207 ozaki #include <netinet/wqinput.h> 97 1.2 itojun #include <netinet6/ip6_var.h> 98 1.145 thorpej #include <netinet6/ip6_private.h> 99 1.19 itojun #include <netinet/icmp6.h> 100 1.145 thorpej #include <netinet6/icmp6_private.h> 101 1.2 itojun #include <netinet6/mld6_var.h> 102 1.2 itojun #include <netinet6/in6_pcb.h> 103 1.2 itojun #include <netinet6/in6_ifattach.h> 104 1.10 itojun #include <netinet6/ip6protosw.h> 105 1.247 roy #include <netinet6/nd6.h> 106 1.113 rpaulo #include <netinet6/scope6_var.h> 107 1.12 itojun 108 1.162 christos #ifdef IPSEC 109 1.129 degroote #include <netipsec/ipsec.h> 110 1.213 ozaki #include <netipsec/ipsec6.h> 111 1.129 degroote #include <netipsec/key.h> 112 1.129 degroote #endif 113 1.129 degroote 114 1.2 itojun #include "faith.h" 115 1.64 itojun #if defined(NFAITH) && 0 < NFAITH 116 1.64 itojun #include <net/if_faith.h> 117 1.64 itojun #endif 118 1.2 itojun 119 1.246 roy /* Ensure that non packed structures are the desired size. */ 120 1.246 roy __CTASSERT(sizeof(struct icmp6_hdr) == 8); 121 1.246 roy __CTASSERT(sizeof(struct icmp6_nodeinfo) == 16); 122 1.246 roy __CTASSERT(sizeof(struct icmp6_namelookup) == 20); 123 1.246 roy __CTASSERT(sizeof(struct icmp6_router_renum) == 16); 124 1.246 roy 125 1.246 roy __CTASSERT(sizeof(struct nd_router_solicit) == 8); 126 1.246 roy __CTASSERT(sizeof(struct nd_router_advert) == 16); 127 1.246 roy __CTASSERT(sizeof(struct nd_neighbor_solicit) == 24); 128 1.246 roy __CTASSERT(sizeof(struct nd_neighbor_advert) == 24); 129 1.246 roy __CTASSERT(sizeof(struct nd_redirect) == 40); 130 1.246 roy __CTASSERT(sizeof(struct nd_opt_hdr) == 2); 131 1.246 roy __CTASSERT(sizeof(struct nd_opt_route_info) == 8); 132 1.246 roy __CTASSERT(sizeof(struct nd_opt_prefix_info) == 32); 133 1.246 roy __CTASSERT(sizeof(struct nd_opt_rd_hdr) == 8); 134 1.246 roy __CTASSERT(sizeof(struct nd_opt_mtu) == 8); 135 1.246 roy __CTASSERT(sizeof(struct nd_opt_nonce) == 2 + ND_OPT_NONCE_LEN); 136 1.246 roy __CTASSERT(sizeof(struct nd_opt_rdnss) == 8); 137 1.246 roy __CTASSERT(sizeof(struct nd_opt_dnssl) == 8); 138 1.246 roy 139 1.246 roy __CTASSERT(sizeof(struct mld_hdr) == 24); 140 1.246 roy __CTASSERT(sizeof(struct ni_reply_fqdn) == 8); 141 1.246 roy __CTASSERT(sizeof(struct rr_pco_match) == 24); 142 1.246 roy __CTASSERT(sizeof(struct rr_pco_use) == 32); 143 1.246 roy __CTASSERT(sizeof(struct rr_result) == 24); 144 1.246 roy 145 1.12 itojun extern struct domain inet6domain; 146 1.2 itojun 147 1.145 thorpej percpu_t *icmp6stat_percpu; 148 1.2 itojun 149 1.101 itojun extern struct inpcbtable raw6cbtable; 150 1.35 itojun extern int icmp6errppslim; 151 1.35 itojun static int icmp6errpps_count = 0; 152 1.37 itojun static struct timeval icmp6errppslim_last; 153 1.14 itojun extern int icmp6_nodeinfo; 154 1.46 itojun 155 1.252 knakahar bool icmp6_dynamic_rt_msg = false; 156 1.252 knakahar 157 1.46 itojun /* 158 1.46 itojun * List of callbacks to notify when Path MTU changes are made. 159 1.46 itojun */ 160 1.46 itojun struct icmp6_mtudisc_callback { 161 1.46 itojun LIST_ENTRY(icmp6_mtudisc_callback) mc_list; 162 1.140 dyoung void (*mc_func)(struct in6_addr *); 163 1.46 itojun }; 164 1.46 itojun 165 1.46 itojun LIST_HEAD(, icmp6_mtudisc_callback) icmp6_mtudisc_callbacks = 166 1.46 itojun LIST_HEAD_INITIALIZER(&icmp6_mtudisc_callbacks); 167 1.46 itojun 168 1.8 itojun static struct rttimer_queue *icmp6_mtudisc_timeout_q = NULL; 169 1.8 itojun extern int pmtu_expire; 170 1.8 itojun 171 1.48 itojun /* XXX do these values make any sense? */ 172 1.55 itojun static int icmp6_mtudisc_hiwat = 1280; 173 1.55 itojun static int icmp6_mtudisc_lowat = 256; 174 1.55 itojun 175 1.55 itojun /* 176 1.55 itojun * keep track of # of redirect routes. 177 1.55 itojun */ 178 1.55 itojun static struct rttimer_queue *icmp6_redirect_timeout_q = NULL; 179 1.55 itojun 180 1.55 itojun /* XXX experimental, turned off */ 181 1.55 itojun static int icmp6_redirect_hiwat = -1; 182 1.55 itojun static int icmp6_redirect_lowat = -1; 183 1.48 itojun 184 1.209 ozaki /* Protect mtudisc and redirect stuffs */ 185 1.209 ozaki static kmutex_t icmp6_mtx __cacheline_aligned; 186 1.209 ozaki 187 1.251 knakahar static bool icmp6_reflect_pmtu = false; 188 1.251 knakahar 189 1.145 thorpej static void icmp6_errcount(u_int, int, int); 190 1.140 dyoung static int icmp6_rip6_input(struct mbuf **, int); 191 1.219 maxv static void icmp6_reflect(struct mbuf *, size_t); 192 1.140 dyoung static int icmp6_ratelimit(const struct in6_addr *, const int, const int); 193 1.205 ryo static const char *icmp6_redirect_diag(char *, size_t, struct in6_addr *, 194 1.219 maxv struct in6_addr *, struct in6_addr *); 195 1.219 maxv static void icmp6_redirect_input(struct mbuf *, int); 196 1.140 dyoung static struct mbuf *ni6_input(struct mbuf *, int); 197 1.140 dyoung static struct mbuf *ni6_nametodns(const char *, int, int); 198 1.140 dyoung static int ni6_dnsmatch(const char *, int, const char *, int); 199 1.219 maxv static int ni6_addrs(struct icmp6_nodeinfo *, struct ifnet **, char *, 200 1.219 maxv struct psref *); 201 1.140 dyoung static int ni6_store_addrs(struct icmp6_nodeinfo *, struct icmp6_nodeinfo *, 202 1.219 maxv struct ifnet *, int); 203 1.140 dyoung static int icmp6_notify_error(struct mbuf *, int, int, int); 204 1.140 dyoung static struct rtentry *icmp6_mtudisc_clone(struct sockaddr *); 205 1.140 dyoung static void icmp6_mtudisc_timeout(struct rtentry *, struct rttimer *); 206 1.140 dyoung static void icmp6_redirect_timeout(struct rtentry *, struct rttimer *); 207 1.153 pooka static void sysctl_net_inet6_icmp6_setup(struct sysctllog **); 208 1.2 itojun 209 1.207 ozaki /* workqueue-based pr_input */ 210 1.207 ozaki static struct wqinput *icmp6_wqinput; 211 1.207 ozaki static void _icmp6_input(struct mbuf *m, int off, int proto); 212 1.116 christos 213 1.2 itojun void 214 1.142 matt icmp6_init(void) 215 1.2 itojun { 216 1.153 pooka 217 1.153 pooka sysctl_net_inet6_icmp6_setup(NULL); 218 1.115 rpaulo mld_init(); 219 1.209 ozaki 220 1.209 ozaki mutex_init(&icmp6_mtx, MUTEX_DEFAULT, IPL_NONE); 221 1.209 ozaki mutex_enter(&icmp6_mtx); 222 1.8 itojun icmp6_mtudisc_timeout_q = rt_timer_queue_create(pmtu_expire); 223 1.55 itojun icmp6_redirect_timeout_q = rt_timer_queue_create(icmp6_redirtimeout); 224 1.209 ozaki mutex_exit(&icmp6_mtx); 225 1.145 thorpej 226 1.145 thorpej icmp6stat_percpu = percpu_alloc(sizeof(uint64_t) * ICMP6_NSTATS); 227 1.207 ozaki 228 1.207 ozaki icmp6_wqinput = wqinput_create("icmp6", _icmp6_input); 229 1.2 itojun } 230 1.2 itojun 231 1.35 itojun static void 232 1.145 thorpej icmp6_errcount(u_int base, int type, int code) 233 1.35 itojun { 234 1.56 itojun switch (type) { 235 1.35 itojun case ICMP6_DST_UNREACH: 236 1.35 itojun switch (code) { 237 1.35 itojun case ICMP6_DST_UNREACH_NOROUTE: 238 1.145 thorpej ICMP6_STATINC(base + ICMP6_ERRSTAT_DST_UNREACH_NOROUTE); 239 1.35 itojun return; 240 1.35 itojun case ICMP6_DST_UNREACH_ADMIN: 241 1.145 thorpej ICMP6_STATINC(base + ICMP6_ERRSTAT_DST_UNREACH_ADMIN); 242 1.35 itojun return; 243 1.35 itojun case ICMP6_DST_UNREACH_BEYONDSCOPE: 244 1.145 thorpej ICMP6_STATINC(base + 245 1.145 thorpej ICMP6_ERRSTAT_DST_UNREACH_BEYONDSCOPE); 246 1.35 itojun return; 247 1.35 itojun case ICMP6_DST_UNREACH_ADDR: 248 1.145 thorpej ICMP6_STATINC(base + ICMP6_ERRSTAT_DST_UNREACH_ADDR); 249 1.35 itojun return; 250 1.35 itojun case ICMP6_DST_UNREACH_NOPORT: 251 1.145 thorpej ICMP6_STATINC(base + ICMP6_ERRSTAT_DST_UNREACH_NOPORT); 252 1.35 itojun return; 253 1.35 itojun } 254 1.35 itojun break; 255 1.35 itojun case ICMP6_PACKET_TOO_BIG: 256 1.145 thorpej ICMP6_STATINC(base + ICMP6_ERRSTAT_PACKET_TOO_BIG); 257 1.35 itojun return; 258 1.35 itojun case ICMP6_TIME_EXCEEDED: 259 1.56 itojun switch (code) { 260 1.35 itojun case ICMP6_TIME_EXCEED_TRANSIT: 261 1.145 thorpej ICMP6_STATINC(base + ICMP6_ERRSTAT_TIME_EXCEED_TRANSIT); 262 1.35 itojun return; 263 1.35 itojun case ICMP6_TIME_EXCEED_REASSEMBLY: 264 1.145 thorpej ICMP6_STATINC(base + 265 1.145 thorpej ICMP6_ERRSTAT_TIME_EXCEED_REASSEMBLY); 266 1.35 itojun return; 267 1.35 itojun } 268 1.35 itojun break; 269 1.35 itojun case ICMP6_PARAM_PROB: 270 1.56 itojun switch (code) { 271 1.35 itojun case ICMP6_PARAMPROB_HEADER: 272 1.145 thorpej ICMP6_STATINC(base + ICMP6_ERRSTAT_PARAMPROB_HEADER); 273 1.35 itojun return; 274 1.35 itojun case ICMP6_PARAMPROB_NEXTHEADER: 275 1.145 thorpej ICMP6_STATINC(base + 276 1.145 thorpej ICMP6_ERRSTAT_PARAMPROB_NEXTHEADER); 277 1.35 itojun return; 278 1.35 itojun case ICMP6_PARAMPROB_OPTION: 279 1.145 thorpej ICMP6_STATINC(base + ICMP6_ERRSTAT_PARAMPROB_OPTION); 280 1.35 itojun return; 281 1.35 itojun } 282 1.35 itojun break; 283 1.35 itojun case ND_REDIRECT: 284 1.145 thorpej ICMP6_STATINC(base + ICMP6_ERRSTAT_REDIRECT); 285 1.35 itojun return; 286 1.35 itojun } 287 1.145 thorpej ICMP6_STATINC(base + ICMP6_ERRSTAT_UNKNOWN); 288 1.35 itojun } 289 1.35 itojun 290 1.2 itojun /* 291 1.46 itojun * Register a Path MTU Discovery callback. 292 1.46 itojun */ 293 1.46 itojun void 294 1.140 dyoung icmp6_mtudisc_callback_register(void (*func)(struct in6_addr *)) 295 1.46 itojun { 296 1.209 ozaki struct icmp6_mtudisc_callback *mc, *new; 297 1.209 ozaki 298 1.209 ozaki new = kmem_alloc(sizeof(*mc), KM_SLEEP); 299 1.46 itojun 300 1.209 ozaki mutex_enter(&icmp6_mtx); 301 1.46 itojun for (mc = LIST_FIRST(&icmp6_mtudisc_callbacks); mc != NULL; 302 1.46 itojun mc = LIST_NEXT(mc, mc_list)) { 303 1.209 ozaki if (mc->mc_func == func) { 304 1.209 ozaki mutex_exit(&icmp6_mtx); 305 1.209 ozaki kmem_free(new, sizeof(*mc)); 306 1.46 itojun return; 307 1.209 ozaki } 308 1.46 itojun } 309 1.46 itojun 310 1.209 ozaki new->mc_func = func; 311 1.209 ozaki LIST_INSERT_HEAD(&icmp6_mtudisc_callbacks, new, mc_list); 312 1.209 ozaki mutex_exit(&icmp6_mtx); 313 1.46 itojun } 314 1.46 itojun 315 1.46 itojun /* 316 1.113 rpaulo * A wrapper function for icmp6_error() necessary when the erroneous packet 317 1.113 rpaulo * may not contain enough scope zone information. 318 1.113 rpaulo */ 319 1.113 rpaulo void 320 1.219 maxv icmp6_error2(struct mbuf *m, int type, int code, int param, 321 1.244 roy struct ifnet *ifp, struct in6_addr *src) 322 1.113 rpaulo { 323 1.113 rpaulo struct ip6_hdr *ip6; 324 1.113 rpaulo 325 1.215 maxv KASSERT(ifp != NULL); 326 1.113 rpaulo 327 1.113 rpaulo if (m->m_len < sizeof(struct ip6_hdr)) { 328 1.113 rpaulo m = m_pullup(m, sizeof(struct ip6_hdr)); 329 1.113 rpaulo if (m == NULL) 330 1.113 rpaulo return; 331 1.113 rpaulo } 332 1.113 rpaulo 333 1.113 rpaulo ip6 = mtod(m, struct ip6_hdr *); 334 1.113 rpaulo 335 1.113 rpaulo if (in6_setscope(&ip6->ip6_src, ifp, NULL) != 0) 336 1.215 maxv goto out; 337 1.113 rpaulo if (in6_setscope(&ip6->ip6_dst, ifp, NULL) != 0) 338 1.215 maxv goto out; 339 1.113 rpaulo 340 1.244 roy *src = ip6->ip6_src; 341 1.113 rpaulo icmp6_error(m, type, code, param); 342 1.215 maxv return; 343 1.215 maxv 344 1.215 maxv out: 345 1.215 maxv m_freem(m); 346 1.113 rpaulo } 347 1.113 rpaulo 348 1.113 rpaulo /* 349 1.2 itojun * Generate an error packet of type error in response to bad IP6 packet. 350 1.2 itojun */ 351 1.2 itojun void 352 1.133 christos icmp6_error(struct mbuf *m, int type, int code, int param) 353 1.2 itojun { 354 1.2 itojun struct ip6_hdr *oip6, *nip6; 355 1.2 itojun struct icmp6_hdr *icmp6; 356 1.17 itohy u_int preplen; 357 1.2 itojun int off; 358 1.27 itojun int nxt; 359 1.2 itojun 360 1.145 thorpej ICMP6_STATINC(ICMP6_STAT_ERROR); 361 1.2 itojun 362 1.35 itojun /* count per-type-code statistics */ 363 1.145 thorpej icmp6_errcount(ICMP6_STAT_OUTERRHIST, type, code); 364 1.35 itojun 365 1.23 itojun if (m->m_flags & M_DECRYPTED) { 366 1.145 thorpej ICMP6_STATINC(ICMP6_STAT_CANTERROR); 367 1.2 itojun goto freeit; 368 1.23 itojun } 369 1.2 itojun 370 1.134 dyoung if (M_UNWRITABLE(m, sizeof(struct ip6_hdr)) && 371 1.134 dyoung (m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) 372 1.134 dyoung return; 373 1.2 itojun oip6 = mtod(m, struct ip6_hdr *); 374 1.2 itojun 375 1.2 itojun /* 376 1.67 itojun * If the destination address of the erroneous packet is a multicast 377 1.67 itojun * address, or the packet was sent using link-layer multicast, 378 1.67 itojun * we should basically suppress sending an error (RFC 2463, Section 379 1.67 itojun * 2.4). 380 1.67 itojun * We have two exceptions (the item e.2 in that section): 381 1.215 maxv * - the Packet Too Big message can be sent for path MTU discovery. 382 1.67 itojun * - the Parameter Problem Message that can be allowed an icmp6 error 383 1.67 itojun * in the option type field. This check has been done in 384 1.67 itojun * ip6_unknown_opt(), so we can just check the type and code. 385 1.2 itojun */ 386 1.2 itojun if ((m->m_flags & (M_BCAST|M_MCAST) || 387 1.2 itojun IN6_IS_ADDR_MULTICAST(&oip6->ip6_dst)) && 388 1.2 itojun (type != ICMP6_PACKET_TOO_BIG && 389 1.2 itojun (type != ICMP6_PARAM_PROB || 390 1.2 itojun code != ICMP6_PARAMPROB_OPTION))) 391 1.2 itojun goto freeit; 392 1.2 itojun 393 1.67 itojun /* 394 1.67 itojun * RFC 2463, 2.4 (e.5): source address check. 395 1.67 itojun * XXX: the case of anycast source? 396 1.67 itojun */ 397 1.2 itojun if (IN6_IS_ADDR_UNSPECIFIED(&oip6->ip6_src) || 398 1.2 itojun IN6_IS_ADDR_MULTICAST(&oip6->ip6_src)) 399 1.2 itojun goto freeit; 400 1.2 itojun 401 1.2 itojun /* 402 1.27 itojun * If we are about to send ICMPv6 against ICMPv6 error/redirect, 403 1.27 itojun * don't do it. 404 1.2 itojun */ 405 1.27 itojun nxt = -1; 406 1.28 itojun off = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nxt); 407 1.27 itojun if (off >= 0 && nxt == IPPROTO_ICMPV6) { 408 1.2 itojun struct icmp6_hdr *icp; 409 1.2 itojun 410 1.27 itojun IP6_EXTHDR_GET(icp, struct icmp6_hdr *, m, off, 411 1.27 itojun sizeof(*icp)); 412 1.27 itojun if (icp == NULL) { 413 1.145 thorpej ICMP6_STATINC(ICMP6_STAT_TOOSHORT); 414 1.27 itojun return; 415 1.27 itojun } 416 1.27 itojun if (icp->icmp6_type < ICMP6_ECHO_REQUEST || 417 1.27 itojun icp->icmp6_type == ND_REDIRECT) { 418 1.27 itojun /* 419 1.27 itojun * ICMPv6 error 420 1.27 itojun * Special case: for redirect (which is 421 1.27 itojun * informational) we must not send icmp6 error. 422 1.27 itojun */ 423 1.145 thorpej ICMP6_STATINC(ICMP6_STAT_CANTERROR); 424 1.27 itojun goto freeit; 425 1.27 itojun } else { 426 1.27 itojun /* ICMPv6 informational - send the error */ 427 1.2 itojun } 428 1.215 maxv } else { 429 1.27 itojun /* non-ICMPv6 - send the error */ 430 1.2 itojun } 431 1.2 itojun 432 1.2 itojun oip6 = mtod(m, struct ip6_hdr *); /* adjust pointer */ 433 1.2 itojun 434 1.2 itojun /* Finally, do rate limitation check. */ 435 1.2 itojun if (icmp6_ratelimit(&oip6->ip6_src, type, code)) { 436 1.145 thorpej ICMP6_STATINC(ICMP6_STAT_TOOFREQ); 437 1.2 itojun goto freeit; 438 1.2 itojun } 439 1.2 itojun 440 1.2 itojun /* 441 1.2 itojun * OK, ICMP6 can be generated. 442 1.2 itojun */ 443 1.2 itojun 444 1.2 itojun if (m->m_pkthdr.len >= ICMPV6_PLD_MAXLEN) 445 1.2 itojun m_adj(m, ICMPV6_PLD_MAXLEN - m->m_pkthdr.len); 446 1.2 itojun 447 1.17 itohy preplen = sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr); 448 1.17 itohy M_PREPEND(m, preplen, M_DONTWAIT); 449 1.134 dyoung if (m && M_UNWRITABLE(m, preplen)) 450 1.17 itohy m = m_pullup(m, preplen); 451 1.2 itojun if (m == NULL) { 452 1.180 ozaki nd6log(LOG_DEBUG, "ENOBUFS in icmp6_error %d\n", __LINE__); 453 1.2 itojun return; 454 1.2 itojun } 455 1.2 itojun 456 1.2 itojun nip6 = mtod(m, struct ip6_hdr *); 457 1.2 itojun nip6->ip6_src = oip6->ip6_src; 458 1.2 itojun nip6->ip6_dst = oip6->ip6_dst; 459 1.2 itojun 460 1.113 rpaulo in6_clearscope(&oip6->ip6_src); 461 1.113 rpaulo in6_clearscope(&oip6->ip6_dst); 462 1.2 itojun 463 1.2 itojun icmp6 = (struct icmp6_hdr *)(nip6 + 1); 464 1.2 itojun icmp6->icmp6_type = type; 465 1.2 itojun icmp6->icmp6_code = code; 466 1.7 itojun icmp6->icmp6_pptr = htonl((u_int32_t)param); 467 1.63 itojun 468 1.63 itojun /* 469 1.63 itojun * icmp6_reflect() is designed to be in the input path. 470 1.114 rpaulo * icmp6_error() can be called from both input and output path, 471 1.63 itojun * and if we are in output path rcvif could contain bogus value. 472 1.63 itojun * clear m->m_pkthdr.rcvif for safety, we should have enough scope 473 1.63 itojun * information in ip header (nip6). 474 1.63 itojun */ 475 1.187 ozaki m_reset_rcvif(m); 476 1.2 itojun 477 1.145 thorpej ICMP6_STATINC(ICMP6_STAT_OUTHIST + type); 478 1.215 maxv 479 1.215 maxv /* header order: IPv6 - ICMPv6 */ 480 1.215 maxv icmp6_reflect(m, sizeof(struct ip6_hdr)); 481 1.27 itojun 482 1.27 itojun return; 483 1.27 itojun 484 1.215 maxv freeit: 485 1.27 itojun /* 486 1.114 rpaulo * If we can't tell whether or not we can generate ICMP6, free it. 487 1.27 itojun */ 488 1.27 itojun m_freem(m); 489 1.2 itojun } 490 1.2 itojun 491 1.2 itojun /* 492 1.2 itojun * Process a received ICMP6 message. 493 1.2 itojun */ 494 1.207 ozaki static void 495 1.207 ozaki _icmp6_input(struct mbuf *m, int off, int proto) 496 1.2 itojun { 497 1.207 ozaki struct mbuf *n; 498 1.2 itojun struct ip6_hdr *ip6, *nip6; 499 1.2 itojun struct icmp6_hdr *icmp6, *nicmp6; 500 1.204 ozaki int icmp6len = m->m_pkthdr.len - off; 501 1.215 maxv int code, sum; 502 1.188 ozaki struct ifnet *rcvif; 503 1.188 ozaki struct psref psref; 504 1.205 ryo char ip6buf[INET6_ADDRSTRLEN], ip6buf2[INET6_ADDRSTRLEN]; 505 1.2 itojun 506 1.188 ozaki rcvif = m_get_rcvif_psref(m, &psref); 507 1.190 ozaki if (__predict_false(rcvif == NULL)) 508 1.190 ozaki goto freeit; 509 1.190 ozaki 510 1.116 christos #define ICMP6_MAXLEN (sizeof(*nip6) + sizeof(*nicmp6) + 4) 511 1.116 christos KASSERT(ICMP6_MAXLEN < MCLBYTES); 512 1.185 ozaki icmp6_ifstat_inc(rcvif, ifs6_in_msg); 513 1.72 itojun 514 1.2 itojun /* 515 1.2 itojun * Locate icmp6 structure in mbuf, and check 516 1.2 itojun * that not corrupted and of at least minimum length 517 1.2 itojun */ 518 1.2 itojun 519 1.2 itojun if (icmp6len < sizeof(struct icmp6_hdr)) { 520 1.145 thorpej ICMP6_STATINC(ICMP6_STAT_TOOSHORT); 521 1.185 ozaki icmp6_ifstat_inc(rcvif, ifs6_in_error); 522 1.2 itojun goto freeit; 523 1.2 itojun } 524 1.2 itojun 525 1.212 knakahar if (m->m_len < sizeof(struct ip6_hdr)) { 526 1.212 knakahar m = m_pullup(m, sizeof(struct ip6_hdr)); 527 1.212 knakahar if (m == NULL) { 528 1.212 knakahar ICMP6_STATINC(ICMP6_STAT_TOOSHORT); 529 1.212 knakahar icmp6_ifstat_inc(rcvif, ifs6_in_error); 530 1.212 knakahar goto freeit; 531 1.212 knakahar } 532 1.212 knakahar } 533 1.212 knakahar 534 1.196 roy ip6 = mtod(m, struct ip6_hdr *); 535 1.196 roy IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, sizeof(*icmp6)); 536 1.196 roy if (icmp6 == NULL) { 537 1.148 bouyer ICMP6_STATINC(ICMP6_STAT_TOOSHORT); 538 1.185 ozaki icmp6_ifstat_inc(rcvif, ifs6_in_error); 539 1.148 bouyer goto freeit; 540 1.148 bouyer } 541 1.215 maxv 542 1.201 mlelstv /* 543 1.201 mlelstv * Enforce alignment requirements that are violated in 544 1.201 mlelstv * some cases, see kern/50766 for details. 545 1.201 mlelstv */ 546 1.250 christos if (ACCESSIBLE_POINTER(icmp6, struct ip6_hdr) == 0) { 547 1.201 mlelstv m = m_copyup(m, off + sizeof(struct icmp6_hdr), 0); 548 1.201 mlelstv if (m == NULL) { 549 1.201 mlelstv ICMP6_STATINC(ICMP6_STAT_TOOSHORT); 550 1.201 mlelstv icmp6_ifstat_inc(rcvif, ifs6_in_error); 551 1.201 mlelstv goto freeit; 552 1.201 mlelstv } 553 1.201 mlelstv ip6 = mtod(m, struct ip6_hdr *); 554 1.215 maxv icmp6 = (struct icmp6_hdr *)(mtod(m, char *) + off); 555 1.201 mlelstv } 556 1.250 christos KASSERT(ACCESSIBLE_POINTER(icmp6, struct ip6_hdr)); 557 1.196 roy 558 1.2 itojun /* 559 1.2 itojun * calculate the checksum 560 1.2 itojun */ 561 1.2 itojun if ((sum = in6_cksum(m, IPPROTO_ICMPV6, off, icmp6len)) != 0) { 562 1.180 ozaki nd6log(LOG_ERR, "ICMP6 checksum error(%d|%x) %s\n", 563 1.206 christos icmp6->icmp6_type, sum, IN6_PRINT(ip6buf, &ip6->ip6_src)); 564 1.145 thorpej ICMP6_STATINC(ICMP6_STAT_CHECKSUM); 565 1.185 ozaki icmp6_ifstat_inc(rcvif, ifs6_in_error); 566 1.2 itojun goto freeit; 567 1.2 itojun } 568 1.2 itojun 569 1.2 itojun #if defined(NFAITH) && 0 < NFAITH 570 1.64 itojun if (faithprefix(&ip6->ip6_dst)) { 571 1.2 itojun /* 572 1.2 itojun * Deliver very specific ICMP6 type only. 573 1.114 rpaulo * This is important to deliver TOOBIG. Otherwise PMTUD 574 1.2 itojun * will not work. 575 1.2 itojun */ 576 1.2 itojun switch (icmp6->icmp6_type) { 577 1.2 itojun case ICMP6_DST_UNREACH: 578 1.2 itojun case ICMP6_PACKET_TOO_BIG: 579 1.2 itojun case ICMP6_TIME_EXCEEDED: 580 1.2 itojun break; 581 1.2 itojun default: 582 1.2 itojun goto freeit; 583 1.2 itojun } 584 1.2 itojun } 585 1.2 itojun #endif 586 1.2 itojun 587 1.196 roy code = icmp6->icmp6_code; 588 1.145 thorpej ICMP6_STATINC(ICMP6_STAT_INHIST + icmp6->icmp6_type); 589 1.2 itojun 590 1.2 itojun switch (icmp6->icmp6_type) { 591 1.2 itojun case ICMP6_DST_UNREACH: 592 1.185 ozaki icmp6_ifstat_inc(rcvif, ifs6_in_dstunreach); 593 1.2 itojun switch (code) { 594 1.2 itojun case ICMP6_DST_UNREACH_NOROUTE: 595 1.2 itojun code = PRC_UNREACH_NET; 596 1.2 itojun break; 597 1.2 itojun case ICMP6_DST_UNREACH_ADMIN: 598 1.185 ozaki icmp6_ifstat_inc(rcvif, ifs6_in_adminprohib); 599 1.23 itojun code = PRC_UNREACH_PROTOCOL; /* is this a good code? */ 600 1.23 itojun break; 601 1.2 itojun case ICMP6_DST_UNREACH_ADDR: 602 1.23 itojun code = PRC_HOSTDEAD; 603 1.2 itojun break; 604 1.23 itojun case ICMP6_DST_UNREACH_BEYONDSCOPE: 605 1.23 itojun /* I mean "source address was incorrect." */ 606 1.67 itojun code = PRC_UNREACH_NET; 607 1.23 itojun break; 608 1.2 itojun case ICMP6_DST_UNREACH_NOPORT: 609 1.2 itojun code = PRC_UNREACH_PORT; 610 1.2 itojun break; 611 1.2 itojun default: 612 1.2 itojun goto badcode; 613 1.2 itojun } 614 1.2 itojun goto deliver; 615 1.2 itojun 616 1.2 itojun case ICMP6_PACKET_TOO_BIG: 617 1.185 ozaki icmp6_ifstat_inc(rcvif, ifs6_in_pkttoobig); 618 1.2 itojun 619 1.150 adrianp /* 620 1.150 adrianp * MTU is checked in icmp6_mtudisc. 621 1.150 adrianp */ 622 1.2 itojun code = PRC_MSGSIZE; 623 1.2 itojun 624 1.23 itojun /* 625 1.23 itojun * Updating the path MTU will be done after examining 626 1.23 itojun * intermediate extension headers. 627 1.23 itojun */ 628 1.2 itojun goto deliver; 629 1.2 itojun 630 1.2 itojun case ICMP6_TIME_EXCEEDED: 631 1.185 ozaki icmp6_ifstat_inc(rcvif, ifs6_in_timeexceed); 632 1.2 itojun switch (code) { 633 1.2 itojun case ICMP6_TIME_EXCEED_TRANSIT: 634 1.67 itojun code = PRC_TIMXCEED_INTRANS; 635 1.67 itojun break; 636 1.2 itojun case ICMP6_TIME_EXCEED_REASSEMBLY: 637 1.67 itojun code = PRC_TIMXCEED_REASS; 638 1.2 itojun break; 639 1.2 itojun default: 640 1.2 itojun goto badcode; 641 1.2 itojun } 642 1.2 itojun goto deliver; 643 1.2 itojun 644 1.2 itojun case ICMP6_PARAM_PROB: 645 1.185 ozaki icmp6_ifstat_inc(rcvif, ifs6_in_paramprob); 646 1.2 itojun switch (code) { 647 1.2 itojun case ICMP6_PARAMPROB_NEXTHEADER: 648 1.2 itojun code = PRC_UNREACH_PROTOCOL; 649 1.2 itojun break; 650 1.2 itojun case ICMP6_PARAMPROB_HEADER: 651 1.2 itojun case ICMP6_PARAMPROB_OPTION: 652 1.2 itojun code = PRC_PARAMPROB; 653 1.2 itojun break; 654 1.2 itojun default: 655 1.2 itojun goto badcode; 656 1.2 itojun } 657 1.2 itojun goto deliver; 658 1.2 itojun 659 1.2 itojun case ICMP6_ECHO_REQUEST: 660 1.185 ozaki icmp6_ifstat_inc(rcvif, ifs6_in_echo); 661 1.2 itojun if (code != 0) 662 1.2 itojun goto badcode; 663 1.67 itojun /* 664 1.67 itojun * Copy mbuf to send to two data paths: userland socket(s), 665 1.67 itojun * and to the querier (echo reply). 666 1.67 itojun * m: a copy for socket, n: a copy for querier 667 1.120 dyoung * 668 1.120 dyoung * If the first mbuf is shared, or the first mbuf is too short, 669 1.120 dyoung * copy the first part of the data into a fresh mbuf. 670 1.120 dyoung * Otherwise, we will wrongly overwrite both copies. 671 1.67 itojun */ 672 1.235 maxv if ((n = m_copypacket(m, M_DONTWAIT)) == NULL) { 673 1.67 itojun /* Give up local */ 674 1.67 itojun n = m; 675 1.67 itojun m = NULL; 676 1.231 maxv } else if (M_UNWRITABLE(n, off + sizeof(struct icmp6_hdr))) { 677 1.2 itojun struct mbuf *n0 = n; 678 1.2 itojun 679 1.2 itojun /* 680 1.67 itojun * Prepare an internal mbuf. m_pullup() doesn't 681 1.2 itojun * always copy the length we specified. 682 1.2 itojun */ 683 1.121 dyoung if ((n = m_dup(n0, 0, M_COPYALL, M_DONTWAIT)) == NULL) { 684 1.67 itojun /* Give up local */ 685 1.67 itojun n = m; 686 1.67 itojun m = NULL; 687 1.2 itojun } 688 1.120 dyoung m_freem(n0); 689 1.2 itojun } 690 1.127 dyoung IP6_EXTHDR_GET(nicmp6, struct icmp6_hdr *, n, off, 691 1.127 dyoung sizeof(*nicmp6)); 692 1.164 joerg if (nicmp6 == NULL) 693 1.164 joerg goto freeit; 694 1.2 itojun nicmp6->icmp6_type = ICMP6_ECHO_REPLY; 695 1.2 itojun nicmp6->icmp6_code = 0; 696 1.10 itojun if (n) { 697 1.257 riastrad net_stat_ref_t icmp6s = ICMP6_STAT_GETREF(); 698 1.257 riastrad _NET_STATINC_REF(icmp6s, ICMP6_STAT_REFLECT); 699 1.257 riastrad _NET_STATINC_REF(icmp6s, 700 1.257 riastrad ICMP6_STAT_OUTHIST + ICMP6_ECHO_REPLY); 701 1.145 thorpej ICMP6_STAT_PUTREF(); 702 1.120 dyoung icmp6_reflect(n, off); 703 1.10 itojun } 704 1.67 itojun if (!m) 705 1.67 itojun goto freeit; 706 1.2 itojun break; 707 1.2 itojun 708 1.2 itojun case ICMP6_ECHO_REPLY: 709 1.185 ozaki icmp6_ifstat_inc(rcvif, ifs6_in_echoreply); 710 1.2 itojun if (code != 0) 711 1.2 itojun goto badcode; 712 1.2 itojun break; 713 1.2 itojun 714 1.92 itojun case MLD_LISTENER_QUERY: 715 1.92 itojun case MLD_LISTENER_REPORT: 716 1.92 itojun if (icmp6len < sizeof(struct mld_hdr)) 717 1.2 itojun goto badlen; 718 1.92 itojun if (icmp6->icmp6_type == MLD_LISTENER_QUERY) /* XXX: ugly... */ 719 1.185 ozaki icmp6_ifstat_inc(rcvif, ifs6_in_mldquery); 720 1.12 itojun else 721 1.185 ozaki icmp6_ifstat_inc(rcvif, ifs6_in_mldreport); 722 1.235 maxv if ((n = m_copypacket(m, M_DONTWAIT)) == NULL) { 723 1.23 itojun /* give up local */ 724 1.115 rpaulo mld_input(m, off); 725 1.23 itojun m = NULL; 726 1.23 itojun goto freeit; 727 1.23 itojun } 728 1.115 rpaulo mld_input(n, off); 729 1.2 itojun /* m stays. */ 730 1.2 itojun break; 731 1.2 itojun 732 1.92 itojun case MLD_LISTENER_DONE: 733 1.185 ozaki icmp6_ifstat_inc(rcvif, ifs6_in_mlddone); 734 1.92 itojun if (icmp6len < sizeof(struct mld_hdr)) /* necessary? */ 735 1.2 itojun goto badlen; 736 1.2 itojun break; /* nothing to be done in kernel */ 737 1.2 itojun 738 1.92 itojun case MLD_MTRACE_RESP: 739 1.92 itojun case MLD_MTRACE: 740 1.74 itojun /* XXX: these two are experimental. not officially defined. */ 741 1.12 itojun /* XXX: per-interface statistics? */ 742 1.23 itojun break; /* just pass it to applications */ 743 1.12 itojun 744 1.2 itojun case ICMP6_WRUREQUEST: /* ICMP6_FQDN_QUERY */ 745 1.2 itojun { 746 1.2 itojun enum { WRU, FQDN } mode; 747 1.2 itojun 748 1.14 itojun if (!icmp6_nodeinfo) 749 1.14 itojun break; 750 1.14 itojun 751 1.2 itojun if (icmp6len == sizeof(struct icmp6_hdr) + 4) 752 1.2 itojun mode = WRU; 753 1.31 itojun else if (icmp6len >= sizeof(struct icmp6_nodeinfo)) 754 1.2 itojun mode = FQDN; 755 1.2 itojun else 756 1.2 itojun goto badlen; 757 1.2 itojun 758 1.2 itojun if (mode == FQDN) { 759 1.235 maxv n = m_copypacket(m, M_DONTWAIT); 760 1.14 itojun if (n) 761 1.14 itojun n = ni6_input(n, off); 762 1.14 itojun } else { 763 1.2 itojun u_char *p; 764 1.116 christos int maxhlen; 765 1.2 itojun 766 1.81 itojun if ((icmp6_nodeinfo & 5) != 5) 767 1.67 itojun break; 768 1.67 itojun 769 1.31 itojun if (code != 0) 770 1.31 itojun goto badcode; 771 1.2 itojun MGETHDR(n, M_DONTWAIT, m->m_type); 772 1.116 christos if (n && ICMP6_MAXLEN > MHLEN) { 773 1.23 itojun MCLGET(n, M_DONTWAIT); 774 1.23 itojun if ((n->m_flags & M_EXT) == 0) { 775 1.23 itojun m_free(n); 776 1.23 itojun n = NULL; 777 1.23 itojun } 778 1.23 itojun } 779 1.2 itojun if (n == NULL) { 780 1.2 itojun /* Give up remote */ 781 1.2 itojun break; 782 1.2 itojun } 783 1.187 ozaki m_reset_rcvif(n); 784 1.23 itojun n->m_len = 0; 785 1.116 christos maxhlen = M_TRAILINGSPACE(n) - ICMP6_MAXLEN; 786 1.215 maxv if (maxhlen < 0) { 787 1.215 maxv m_free(n); 788 1.170 christos break; 789 1.215 maxv } 790 1.23 itojun if (maxhlen > hostnamelen) 791 1.23 itojun maxhlen = hostnamelen; 792 1.2 itojun /* 793 1.2 itojun * Copy IPv6 and ICMPv6 only. 794 1.2 itojun */ 795 1.2 itojun nip6 = mtod(n, struct ip6_hdr *); 796 1.215 maxv memcpy(nip6, ip6, sizeof(struct ip6_hdr)); 797 1.2 itojun nicmp6 = (struct icmp6_hdr *)(nip6 + 1); 798 1.215 maxv memcpy(nicmp6, icmp6, sizeof(struct icmp6_hdr)); 799 1.215 maxv 800 1.2 itojun p = (u_char *)(nicmp6 + 1); 801 1.152 cegger memset(p, 0, 4); 802 1.215 maxv memcpy(p + 4, hostname, maxhlen); /* meaningless TTL */ 803 1.215 maxv 804 1.242 maxv m_copy_pkthdr(n, m); 805 1.2 itojun n->m_pkthdr.len = n->m_len = sizeof(struct ip6_hdr) + 806 1.23 itojun sizeof(struct icmp6_hdr) + 4 + maxhlen; 807 1.2 itojun nicmp6->icmp6_type = ICMP6_WRUREPLY; 808 1.2 itojun nicmp6->icmp6_code = 0; 809 1.2 itojun } 810 1.2 itojun if (n) { 811 1.257 riastrad net_stat_ref_t icmp6s = ICMP6_STAT_GETREF(); 812 1.257 riastrad _NET_STATINC_REF(icmp6s, ICMP6_STAT_REFLECT); 813 1.257 riastrad _NET_STATINC_REF(icmp6s, 814 1.257 riastrad ICMP6_STAT_OUTHIST + ICMP6_WRUREPLY); 815 1.145 thorpej ICMP6_STAT_PUTREF(); 816 1.215 maxv icmp6_reflect(n, sizeof(struct ip6_hdr)); 817 1.2 itojun } 818 1.2 itojun break; 819 1.2 itojun } 820 1.2 itojun 821 1.2 itojun case ICMP6_WRUREPLY: 822 1.2 itojun if (code != 0) 823 1.2 itojun goto badcode; 824 1.2 itojun break; 825 1.2 itojun 826 1.2 itojun case ND_ROUTER_SOLICIT: 827 1.185 ozaki icmp6_ifstat_inc(rcvif, ifs6_in_routersolicit); 828 1.245 roy /* FALLTHROUGH */ 829 1.2 itojun case ND_ROUTER_ADVERT: 830 1.245 roy if (icmp6->icmp6_type == ND_ROUTER_ADVERT) 831 1.245 roy icmp6_ifstat_inc(rcvif, ifs6_in_routeradvert); 832 1.2 itojun if (code != 0) 833 1.2 itojun goto badcode; 834 1.245 roy if ((icmp6->icmp6_type == ND_ROUTER_SOLICIT && 835 1.245 roy icmp6len < sizeof(struct nd_router_solicit)) || 836 1.245 roy (icmp6->icmp6_type == ND_ROUTER_ADVERT && 837 1.245 roy icmp6len < sizeof(struct nd_router_advert))) 838 1.2 itojun goto badlen; 839 1.235 maxv if ((n = m_copypacket(m, M_DONTWAIT)) == NULL) { 840 1.23 itojun /* give up local */ 841 1.245 roy nd6_rtr_cache(m, off, icmp6len, icmp6->icmp6_type); 842 1.23 itojun m = NULL; 843 1.23 itojun goto freeit; 844 1.23 itojun } 845 1.245 roy nd6_rtr_cache(n, off, icmp6len, icmp6->icmp6_type); 846 1.2 itojun /* m stays. */ 847 1.2 itojun break; 848 1.2 itojun 849 1.2 itojun case ND_NEIGHBOR_SOLICIT: 850 1.185 ozaki icmp6_ifstat_inc(rcvif, ifs6_in_neighborsolicit); 851 1.2 itojun if (code != 0) 852 1.2 itojun goto badcode; 853 1.2 itojun if (icmp6len < sizeof(struct nd_neighbor_solicit)) 854 1.2 itojun goto badlen; 855 1.235 maxv if ((n = m_copypacket(m, M_DONTWAIT)) == NULL) { 856 1.23 itojun /* give up local */ 857 1.23 itojun nd6_ns_input(m, off, icmp6len); 858 1.23 itojun m = NULL; 859 1.23 itojun goto freeit; 860 1.23 itojun } 861 1.23 itojun nd6_ns_input(n, off, icmp6len); 862 1.2 itojun /* m stays. */ 863 1.2 itojun break; 864 1.2 itojun 865 1.2 itojun case ND_NEIGHBOR_ADVERT: 866 1.185 ozaki icmp6_ifstat_inc(rcvif, ifs6_in_neighboradvert); 867 1.2 itojun if (code != 0) 868 1.2 itojun goto badcode; 869 1.2 itojun if (icmp6len < sizeof(struct nd_neighbor_advert)) 870 1.2 itojun goto badlen; 871 1.235 maxv if ((n = m_copypacket(m, M_DONTWAIT)) == NULL) { 872 1.23 itojun /* give up local */ 873 1.23 itojun nd6_na_input(m, off, icmp6len); 874 1.23 itojun m = NULL; 875 1.23 itojun goto freeit; 876 1.23 itojun } 877 1.23 itojun nd6_na_input(n, off, icmp6len); 878 1.2 itojun /* m stays. */ 879 1.2 itojun break; 880 1.2 itojun 881 1.2 itojun case ND_REDIRECT: 882 1.185 ozaki icmp6_ifstat_inc(rcvif, ifs6_in_redirect); 883 1.2 itojun if (code != 0) 884 1.2 itojun goto badcode; 885 1.2 itojun if (icmp6len < sizeof(struct nd_redirect)) 886 1.2 itojun goto badlen; 887 1.235 maxv if ((n = m_copypacket(m, M_DONTWAIT)) == NULL) { 888 1.23 itojun /* give up local */ 889 1.23 itojun icmp6_redirect_input(m, off); 890 1.23 itojun m = NULL; 891 1.23 itojun goto freeit; 892 1.23 itojun } 893 1.23 itojun icmp6_redirect_input(n, off); 894 1.2 itojun /* m stays. */ 895 1.2 itojun break; 896 1.2 itojun 897 1.2 itojun case ICMP6_ROUTER_RENUMBERING: 898 1.2 itojun if (code != ICMP6_ROUTER_RENUMBERING_COMMAND && 899 1.2 itojun code != ICMP6_ROUTER_RENUMBERING_RESULT) 900 1.2 itojun goto badcode; 901 1.2 itojun if (icmp6len < sizeof(struct icmp6_router_renum)) 902 1.2 itojun goto badlen; 903 1.2 itojun break; 904 1.2 itojun 905 1.2 itojun default: 906 1.205 ryo nd6log(LOG_DEBUG, 907 1.205 ryo "unknown type %d(src=%s, dst=%s, ifid=%d)\n", 908 1.205 ryo icmp6->icmp6_type, 909 1.206 christos IN6_PRINT(ip6buf, &ip6->ip6_src), 910 1.206 christos IN6_PRINT(ip6buf2, &ip6->ip6_dst), 911 1.185 ozaki rcvif ? rcvif->if_index : 0); 912 1.2 itojun if (icmp6->icmp6_type < ICMP6_ECHO_REQUEST) { 913 1.2 itojun /* ICMPv6 error: MUST deliver it by spec... */ 914 1.2 itojun code = PRC_NCMDS; 915 1.2 itojun /* deliver */ 916 1.2 itojun } else { 917 1.2 itojun /* ICMPv6 informational: MUST not deliver */ 918 1.2 itojun break; 919 1.2 itojun } 920 1.2 itojun deliver: 921 1.58 itojun if (icmp6_notify_error(m, off, icmp6len, code)) { 922 1.58 itojun /* In this case, m should've been freed. */ 923 1.188 ozaki m_put_rcvif_psref(rcvif, &psref); 924 1.207 ozaki return; 925 1.2 itojun } 926 1.58 itojun break; 927 1.58 itojun 928 1.58 itojun badcode: 929 1.145 thorpej ICMP6_STATINC(ICMP6_STAT_BADCODE); 930 1.58 itojun break; 931 1.58 itojun 932 1.58 itojun badlen: 933 1.145 thorpej ICMP6_STATINC(ICMP6_STAT_BADLEN); 934 1.58 itojun break; 935 1.58 itojun } 936 1.188 ozaki m_put_rcvif_psref(rcvif, &psref); 937 1.58 itojun 938 1.58 itojun /* deliver the packet to appropriate sockets */ 939 1.204 ozaki icmp6_rip6_input(&m, off); 940 1.58 itojun 941 1.207 ozaki return; 942 1.58 itojun 943 1.219 maxv freeit: 944 1.188 ozaki m_put_rcvif_psref(rcvif, &psref); 945 1.58 itojun m_freem(m); 946 1.207 ozaki return; 947 1.207 ozaki } 948 1.207 ozaki 949 1.207 ozaki int 950 1.207 ozaki icmp6_input(struct mbuf **mp, int *offp, int proto) 951 1.207 ozaki { 952 1.207 ozaki 953 1.207 ozaki wqinput_input(icmp6_wqinput, *mp, *offp, proto); 954 1.207 ozaki 955 1.58 itojun return IPPROTO_DONE; 956 1.58 itojun } 957 1.58 itojun 958 1.58 itojun static int 959 1.133 christos icmp6_notify_error(struct mbuf *m, int off, int icmp6len, int code) 960 1.58 itojun { 961 1.58 itojun struct icmp6_hdr *icmp6; 962 1.58 itojun struct ip6_hdr *eip6; 963 1.58 itojun u_int32_t notifymtu; 964 1.58 itojun struct sockaddr_in6 icmp6src, icmp6dst; 965 1.58 itojun 966 1.58 itojun if (icmp6len < sizeof(struct icmp6_hdr) + sizeof(struct ip6_hdr)) { 967 1.145 thorpej ICMP6_STATINC(ICMP6_STAT_TOOSHORT); 968 1.58 itojun goto freeit; 969 1.58 itojun } 970 1.58 itojun IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, 971 1.219 maxv sizeof(*icmp6) + sizeof(struct ip6_hdr)); 972 1.58 itojun if (icmp6 == NULL) { 973 1.145 thorpej ICMP6_STATINC(ICMP6_STAT_TOOSHORT); 974 1.86 itojun return (-1); 975 1.58 itojun } 976 1.58 itojun eip6 = (struct ip6_hdr *)(icmp6 + 1); 977 1.2 itojun 978 1.58 itojun /* Detect the upper level protocol */ 979 1.58 itojun { 980 1.243 uwe void *(*ctlfunc)(int, const struct sockaddr *, void *); 981 1.2 itojun u_int8_t nxt = eip6->ip6_nxt; 982 1.2 itojun int eoff = off + sizeof(struct icmp6_hdr) + 983 1.2 itojun sizeof(struct ip6_hdr); 984 1.12 itojun struct ip6ctlparam ip6cp; 985 1.23 itojun struct in6_addr *finaldst = NULL; 986 1.58 itojun int icmp6type = icmp6->icmp6_type; 987 1.23 itojun struct ip6_frag *fh; 988 1.23 itojun struct ip6_rthdr *rth; 989 1.188 ozaki struct ifnet *rcvif; 990 1.188 ozaki int s; 991 1.2 itojun 992 1.67 itojun while (1) { /* XXX: should avoid infinite loop explicitly? */ 993 1.2 itojun struct ip6_ext *eh; 994 1.2 itojun 995 1.56 itojun switch (nxt) { 996 1.2 itojun case IPPROTO_HOPOPTS: 997 1.2 itojun case IPPROTO_DSTOPTS: 998 1.2 itojun case IPPROTO_AH: 999 1.12 itojun IP6_EXTHDR_GET(eh, struct ip6_ext *, m, 1000 1.229 maxv eoff, sizeof(*eh)); 1001 1.12 itojun if (eh == NULL) { 1002 1.145 thorpej ICMP6_STATINC(ICMP6_STAT_TOOSHORT); 1003 1.86 itojun return (-1); 1004 1.12 itojun } 1005 1.82 itojun 1006 1.2 itojun if (nxt == IPPROTO_AH) 1007 1.2 itojun eoff += (eh->ip6e_len + 2) << 2; 1008 1.2 itojun else 1009 1.2 itojun eoff += (eh->ip6e_len + 1) << 3; 1010 1.2 itojun nxt = eh->ip6e_nxt; 1011 1.2 itojun break; 1012 1.23 itojun case IPPROTO_ROUTING: 1013 1.228 maxv /* Ignore the option. */ 1014 1.23 itojun IP6_EXTHDR_GET(rth, struct ip6_rthdr *, m, 1015 1.229 maxv eoff, sizeof(*rth)); 1016 1.23 itojun if (rth == NULL) { 1017 1.145 thorpej ICMP6_STATINC(ICMP6_STAT_TOOSHORT); 1018 1.86 itojun return (-1); 1019 1.23 itojun } 1020 1.228 maxv 1021 1.228 maxv eoff += (rth->ip6r_len + 1) << 3; 1022 1.23 itojun nxt = rth->ip6r_nxt; 1023 1.23 itojun break; 1024 1.23 itojun case IPPROTO_FRAGMENT: 1025 1.23 itojun IP6_EXTHDR_GET(fh, struct ip6_frag *, m, 1026 1.229 maxv eoff, sizeof(*fh)); 1027 1.23 itojun if (fh == NULL) { 1028 1.145 thorpej ICMP6_STATINC(ICMP6_STAT_TOOSHORT); 1029 1.86 itojun return (-1); 1030 1.23 itojun } 1031 1.23 itojun /* 1032 1.23 itojun * Data after a fragment header is meaningless 1033 1.23 itojun * unless it is the first fragment, but 1034 1.23 itojun * we'll go to the notify label for path MTU 1035 1.23 itojun * discovery. 1036 1.23 itojun */ 1037 1.23 itojun if (fh->ip6f_offlg & IP6F_OFF_MASK) 1038 1.23 itojun goto notify; 1039 1.23 itojun 1040 1.23 itojun eoff += sizeof(struct ip6_frag); 1041 1.23 itojun nxt = fh->ip6f_nxt; 1042 1.23 itojun break; 1043 1.2 itojun default: 1044 1.23 itojun /* 1045 1.23 itojun * This case includes ESP and the No Next 1046 1.67 itojun * Header. In such cases going to the notify 1047 1.23 itojun * label does not have any meaning 1048 1.23 itojun * (i.e. ctlfunc will be NULL), but we go 1049 1.23 itojun * anyway since we might have to update 1050 1.23 itojun * path MTU information. 1051 1.23 itojun */ 1052 1.2 itojun goto notify; 1053 1.2 itojun } 1054 1.2 itojun } 1055 1.58 itojun notify: 1056 1.12 itojun IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, 1057 1.229 maxv sizeof(*icmp6) + sizeof(struct ip6_hdr)); 1058 1.12 itojun if (icmp6 == NULL) { 1059 1.145 thorpej ICMP6_STATINC(ICMP6_STAT_TOOSHORT); 1060 1.86 itojun return (-1); 1061 1.58 itojun } 1062 1.58 itojun 1063 1.113 rpaulo /* 1064 1.113 rpaulo * retrieve parameters from the inner IPv6 header, and convert 1065 1.113 rpaulo * them into sockaddr structures. 1066 1.113 rpaulo * XXX: there is no guarantee that the source or destination 1067 1.113 rpaulo * addresses of the inner packet are in the same scope zone as 1068 1.113 rpaulo * the addresses of the icmp packet. But there is no other 1069 1.113 rpaulo * way to determine the zone. 1070 1.113 rpaulo */ 1071 1.58 itojun eip6 = (struct ip6_hdr *)(icmp6 + 1); 1072 1.113 rpaulo 1073 1.188 ozaki rcvif = m_get_rcvif(m, &s); 1074 1.208 ozaki if (__predict_false(rcvif == NULL)) 1075 1.208 ozaki goto freeit; 1076 1.138 dyoung sockaddr_in6_init(&icmp6dst, 1077 1.138 dyoung (finaldst == NULL) ? &eip6->ip6_dst : finaldst, 0, 0, 0); 1078 1.188 ozaki if (in6_setscope(&icmp6dst.sin6_addr, rcvif, NULL)) { 1079 1.188 ozaki m_put_rcvif(rcvif, &s); 1080 1.58 itojun goto freeit; 1081 1.188 ozaki } 1082 1.138 dyoung sockaddr_in6_init(&icmp6src, &eip6->ip6_src, 0, 0, 0); 1083 1.188 ozaki if (in6_setscope(&icmp6src.sin6_addr, rcvif, NULL)) { 1084 1.188 ozaki m_put_rcvif(rcvif, &s); 1085 1.58 itojun goto freeit; 1086 1.188 ozaki } 1087 1.188 ozaki m_put_rcvif(rcvif, &s); 1088 1.188 ozaki 1089 1.58 itojun icmp6src.sin6_flowinfo = 1090 1.58 itojun (eip6->ip6_flow & IPV6_FLOWLABEL_MASK); 1091 1.58 itojun 1092 1.46 itojun if (finaldst == NULL) 1093 1.58 itojun finaldst = &eip6->ip6_dst; 1094 1.46 itojun ip6cp.ip6c_m = m; 1095 1.46 itojun ip6cp.ip6c_icmp6 = icmp6; 1096 1.46 itojun ip6cp.ip6c_ip6 = (struct ip6_hdr *)(icmp6 + 1); 1097 1.46 itojun ip6cp.ip6c_off = eoff; 1098 1.46 itojun ip6cp.ip6c_finaldst = finaldst; 1099 1.58 itojun ip6cp.ip6c_src = &icmp6src; 1100 1.58 itojun ip6cp.ip6c_nxt = nxt; 1101 1.58 itojun 1102 1.58 itojun if (icmp6type == ICMP6_PACKET_TOO_BIG) { 1103 1.58 itojun notifymtu = ntohl(icmp6->icmp6_mtu); 1104 1.58 itojun ip6cp.ip6c_cmdarg = (void *)¬ifymtu; 1105 1.58 itojun } 1106 1.23 itojun 1107 1.243 uwe ctlfunc = inet6sw[ip6_protox[nxt]].pr_ctlinput; 1108 1.12 itojun if (ctlfunc) { 1109 1.219 maxv (void)(*ctlfunc)(code, sin6tosa(&icmp6dst), &ip6cp); 1110 1.12 itojun } 1111 1.2 itojun } 1112 1.86 itojun return (0); 1113 1.2 itojun 1114 1.219 maxv freeit: 1115 1.2 itojun m_freem(m); 1116 1.86 itojun return (-1); 1117 1.2 itojun } 1118 1.2 itojun 1119 1.46 itojun void 1120 1.133 christos icmp6_mtudisc_update(struct ip6ctlparam *ip6cp, int validated) 1121 1.23 itojun { 1122 1.48 itojun unsigned long rtcount; 1123 1.46 itojun struct icmp6_mtudisc_callback *mc; 1124 1.46 itojun struct in6_addr *dst = ip6cp->ip6c_finaldst; 1125 1.46 itojun struct icmp6_hdr *icmp6 = ip6cp->ip6c_icmp6; 1126 1.46 itojun struct mbuf *m = ip6cp->ip6c_m; /* will be necessary for scope issue */ 1127 1.23 itojun u_int mtu = ntohl(icmp6->icmp6_mtu); 1128 1.23 itojun struct rtentry *rt = NULL; 1129 1.23 itojun struct sockaddr_in6 sin6; 1130 1.188 ozaki struct ifnet *rcvif; 1131 1.188 ozaki int s; 1132 1.23 itojun 1133 1.48 itojun /* 1134 1.150 adrianp * The MTU should not be less than the minimal IPv6 MTU except for the 1135 1.150 adrianp * hack in ip6_output/ip6_setpmtu where we always include a frag header. 1136 1.219 maxv * In that one case, the MTU might be less than 1280. 1137 1.150 adrianp */ 1138 1.150 adrianp if (__predict_false(mtu < IPV6_MMTU - sizeof(struct ip6_frag))) { 1139 1.150 adrianp /* is the mtu even sane? */ 1140 1.150 adrianp if (mtu < sizeof(struct ip6_hdr) + sizeof(struct ip6_frag) + 8) 1141 1.150 adrianp return; 1142 1.150 adrianp if (!validated) 1143 1.150 adrianp return; 1144 1.150 adrianp mtu = IPV6_MMTU - sizeof(struct ip6_frag); 1145 1.150 adrianp } 1146 1.150 adrianp 1147 1.150 adrianp /* 1148 1.48 itojun * allow non-validated cases if memory is plenty, to make traffic 1149 1.48 itojun * from non-connected pcb happy. 1150 1.48 itojun */ 1151 1.209 ozaki mutex_enter(&icmp6_mtx); 1152 1.48 itojun rtcount = rt_timer_count(icmp6_mtudisc_timeout_q); 1153 1.48 itojun if (validated) { 1154 1.209 ozaki if (0 <= icmp6_mtudisc_hiwat && rtcount > icmp6_mtudisc_hiwat) { 1155 1.209 ozaki mutex_exit(&icmp6_mtx); 1156 1.48 itojun return; 1157 1.215 maxv } else if (0 <= icmp6_mtudisc_lowat && 1158 1.55 itojun rtcount > icmp6_mtudisc_lowat) { 1159 1.48 itojun /* 1160 1.48 itojun * XXX nuke a victim, install the new one. 1161 1.48 itojun */ 1162 1.48 itojun } 1163 1.48 itojun } else { 1164 1.209 ozaki if (0 <= icmp6_mtudisc_lowat && rtcount > icmp6_mtudisc_lowat) { 1165 1.209 ozaki mutex_exit(&icmp6_mtx); 1166 1.48 itojun return; 1167 1.209 ozaki } 1168 1.48 itojun } 1169 1.209 ozaki mutex_exit(&icmp6_mtx); 1170 1.48 itojun 1171 1.152 cegger memset(&sin6, 0, sizeof(sin6)); 1172 1.23 itojun sin6.sin6_family = PF_INET6; 1173 1.23 itojun sin6.sin6_len = sizeof(struct sockaddr_in6); 1174 1.23 itojun sin6.sin6_addr = *dst; 1175 1.188 ozaki rcvif = m_get_rcvif(m, &s); 1176 1.208 ozaki if (__predict_false(rcvif == NULL)) 1177 1.208 ozaki return; 1178 1.188 ozaki if (in6_setscope(&sin6.sin6_addr, rcvif, NULL)) { 1179 1.188 ozaki m_put_rcvif(rcvif, &s); 1180 1.113 rpaulo return; 1181 1.188 ozaki } 1182 1.188 ozaki m_put_rcvif(rcvif, &s); 1183 1.113 rpaulo 1184 1.194 ozaki rt = icmp6_mtudisc_clone(sin6tosa(&sin6)); 1185 1.23 itojun 1186 1.80 itojun if (rt && (rt->rt_flags & RTF_HOST) && 1187 1.80 itojun !(rt->rt_rmx.rmx_locks & RTV_MTU) && 1188 1.80 itojun (rt->rt_rmx.rmx_mtu > mtu || rt->rt_rmx.rmx_mtu == 0)) { 1189 1.245 roy if (mtu < rt->rt_ifp->if_mtu) { 1190 1.145 thorpej ICMP6_STATINC(ICMP6_STAT_PMTUCHG); 1191 1.23 itojun rt->rt_rmx.rmx_mtu = mtu; 1192 1.23 itojun } 1193 1.23 itojun } 1194 1.169 rmind if (rt) { 1195 1.203 ozaki rt_unref(rt); 1196 1.67 itojun } 1197 1.46 itojun 1198 1.46 itojun /* 1199 1.46 itojun * Notify protocols that the MTU for this destination 1200 1.46 itojun * has changed. 1201 1.46 itojun */ 1202 1.209 ozaki mutex_enter(&icmp6_mtx); 1203 1.46 itojun for (mc = LIST_FIRST(&icmp6_mtudisc_callbacks); mc != NULL; 1204 1.46 itojun mc = LIST_NEXT(mc, mc_list)) 1205 1.46 itojun (*mc->mc_func)(&sin6.sin6_addr); 1206 1.209 ozaki mutex_exit(&icmp6_mtx); 1207 1.23 itojun } 1208 1.23 itojun 1209 1.2 itojun /* 1210 1.40 itojun * Process a Node Information Query packet, based on 1211 1.47 itojun * draft-ietf-ipngwg-icmp-name-lookups-07. 1212 1.81 itojun * 1213 1.31 itojun * Spec incompatibilities: 1214 1.31 itojun * - IPv6 Subject address handling 1215 1.31 itojun * - IPv4 Subject address handling support missing 1216 1.31 itojun * - Proxy reply (answer even if it's not for me) 1217 1.31 itojun * - joins NI group address at in6_ifattach() time only, does not cope 1218 1.31 itojun * with hostname changes by sethostname(3) 1219 1.2 itojun */ 1220 1.2 itojun static struct mbuf * 1221 1.133 christos ni6_input(struct mbuf *m, int off) 1222 1.2 itojun { 1223 1.12 itojun struct icmp6_nodeinfo *ni6, *nni6; 1224 1.2 itojun struct mbuf *n = NULL; 1225 1.12 itojun u_int16_t qtype; 1226 1.31 itojun int subjlen; 1227 1.2 itojun int replylen = sizeof(struct ip6_hdr) + sizeof(struct icmp6_nodeinfo); 1228 1.2 itojun struct ni_reply_fqdn *fqdn; 1229 1.2 itojun int addrs; /* for NI_QTYPE_NODEADDR */ 1230 1.2 itojun struct ifnet *ifp = NULL; /* for NI_QTYPE_NODEADDR */ 1231 1.113 rpaulo struct sockaddr_in6 sin6; /* ip6_dst */ 1232 1.113 rpaulo struct in6_addr in6_subj; /* subject address */ 1233 1.31 itojun struct ip6_hdr *ip6; 1234 1.31 itojun int oldfqdn = 0; /* if 1, return pascal string (03 draft) */ 1235 1.47 itojun char *subj = NULL; 1236 1.188 ozaki struct ifnet *rcvif; 1237 1.195 ozaki int s, ss; 1238 1.195 ozaki struct ifaddr *ifa; 1239 1.195 ozaki struct psref psref; 1240 1.2 itojun 1241 1.31 itojun ip6 = mtod(m, struct ip6_hdr *); 1242 1.14 itojun IP6_EXTHDR_GET(ni6, struct icmp6_nodeinfo *, m, off, sizeof(*ni6)); 1243 1.14 itojun if (ni6 == NULL) { 1244 1.14 itojun /* m is already reclaimed */ 1245 1.12 itojun return NULL; 1246 1.14 itojun } 1247 1.219 maxv KASSERT((m->m_flags & M_PKTHDR) != 0); 1248 1.31 itojun 1249 1.31 itojun /* 1250 1.31 itojun * Validate IPv6 destination address. 1251 1.31 itojun * 1252 1.47 itojun * The Responder must discard the Query without further processing 1253 1.47 itojun * unless it is one of the Responder's unicast or anycast addresses, or 1254 1.47 itojun * a link-local scope multicast address which the Responder has joined. 1255 1.47 itojun * [icmp-name-lookups-07, Section 4.] 1256 1.31 itojun */ 1257 1.138 dyoung sockaddr_in6_init(&sin6, &ip6->ip6_dst, 0, 0, 0); 1258 1.31 itojun /* XXX scopeid */ 1259 1.195 ozaki ss = pserialize_read_enter(); 1260 1.195 ozaki ifa = ifa_ifwithaddr(sin6tosa(&sin6)); 1261 1.229 maxv if (ifa != NULL) { 1262 1.47 itojun ; /* unicast/anycast, fine */ 1263 1.229 maxv } else if (IN6_IS_ADDR_MC_LINKLOCAL(&sin6.sin6_addr)) { 1264 1.47 itojun ; /* link-local multicast, fine */ 1265 1.229 maxv } else { 1266 1.195 ozaki pserialize_read_exit(ss); 1267 1.31 itojun goto bad; 1268 1.195 ozaki } 1269 1.195 ozaki pserialize_read_exit(ss); 1270 1.31 itojun 1271 1.47 itojun /* validate query Subject field. */ 1272 1.12 itojun qtype = ntohs(ni6->ni_qtype); 1273 1.31 itojun subjlen = m->m_pkthdr.len - off - sizeof(struct icmp6_nodeinfo); 1274 1.31 itojun switch (qtype) { 1275 1.31 itojun case NI_QTYPE_NOOP: 1276 1.31 itojun case NI_QTYPE_SUPTYPES: 1277 1.47 itojun /* 07 draft */ 1278 1.40 itojun if (ni6->ni_code == ICMP6_NI_SUBJ_FQDN && subjlen == 0) 1279 1.40 itojun break; 1280 1.67 itojun /* FALLTHROUGH */ 1281 1.31 itojun case NI_QTYPE_FQDN: 1282 1.31 itojun case NI_QTYPE_NODEADDR: 1283 1.115 rpaulo case NI_QTYPE_IPV4ADDR: 1284 1.31 itojun switch (ni6->ni_code) { 1285 1.31 itojun case ICMP6_NI_SUBJ_IPV6: 1286 1.31 itojun #if ICMP6_NI_SUBJ_IPV6 != 0 1287 1.31 itojun case 0: 1288 1.31 itojun #endif 1289 1.31 itojun /* 1290 1.31 itojun * backward compatibility - try to accept 03 draft 1291 1.31 itojun * format, where no Subject is present. 1292 1.31 itojun */ 1293 1.40 itojun if (qtype == NI_QTYPE_FQDN && ni6->ni_code == 0 && 1294 1.40 itojun subjlen == 0) { 1295 1.31 itojun oldfqdn++; 1296 1.31 itojun break; 1297 1.31 itojun } 1298 1.40 itojun #if ICMP6_NI_SUBJ_IPV6 != 0 1299 1.40 itojun if (ni6->ni_code != ICMP6_NI_SUBJ_IPV6) 1300 1.40 itojun goto bad; 1301 1.40 itojun #endif 1302 1.31 itojun 1303 1.31 itojun if (subjlen != sizeof(sin6.sin6_addr)) 1304 1.31 itojun goto bad; 1305 1.31 itojun 1306 1.31 itojun /* 1307 1.31 itojun * Validate Subject address. 1308 1.31 itojun * 1309 1.53 itojun * Not sure what exactly "address belongs to the node" 1310 1.53 itojun * means in the spec, is it just unicast, or what? 1311 1.31 itojun * 1312 1.31 itojun * At this moment we consider Subject address as 1313 1.31 itojun * "belong to the node" if the Subject address equals 1314 1.31 itojun * to the IPv6 destination address; validation for 1315 1.31 itojun * IPv6 destination address should have done enough 1316 1.31 itojun * check for us. 1317 1.31 itojun * 1318 1.31 itojun * We do not do proxy at this moment. 1319 1.31 itojun */ 1320 1.31 itojun /* m_pulldown instead of copy? */ 1321 1.31 itojun m_copydata(m, off + sizeof(struct icmp6_nodeinfo), 1322 1.131 christos subjlen, (void *)&in6_subj); 1323 1.188 ozaki rcvif = m_get_rcvif(m, &s); 1324 1.208 ozaki if (__predict_false(rcvif == NULL)) 1325 1.208 ozaki goto bad; 1326 1.188 ozaki if (in6_setscope(&in6_subj, rcvif, NULL)) { 1327 1.188 ozaki m_put_rcvif(rcvif, &s); 1328 1.113 rpaulo goto bad; 1329 1.188 ozaki } 1330 1.188 ozaki m_put_rcvif(rcvif, &s); 1331 1.113 rpaulo 1332 1.113 rpaulo subj = (char *)&in6_subj; 1333 1.113 rpaulo if (IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &in6_subj)) 1334 1.31 itojun break; 1335 1.47 itojun 1336 1.31 itojun /* 1337 1.31 itojun * XXX if we are to allow other cases, we should really 1338 1.31 itojun * be careful about scope here. 1339 1.31 itojun * basically, we should disallow queries toward IPv6 1340 1.31 itojun * destination X with subject Y, if scope(X) > scope(Y). 1341 1.31 itojun * if we allow scope(X) > scope(Y), it will result in 1342 1.31 itojun * information leakage across scope boundary. 1343 1.31 itojun */ 1344 1.31 itojun goto bad; 1345 1.31 itojun 1346 1.31 itojun case ICMP6_NI_SUBJ_FQDN: 1347 1.31 itojun /* 1348 1.31 itojun * Validate Subject name with gethostname(3). 1349 1.31 itojun * 1350 1.31 itojun * The behavior may need some debate, since: 1351 1.31 itojun * - we are not sure if the node has FQDN as 1352 1.31 itojun * hostname (returned by gethostname(3)). 1353 1.31 itojun * - the code does wildcard match for truncated names. 1354 1.31 itojun * however, we are not sure if we want to perform 1355 1.31 itojun * wildcard match, if gethostname(3) side has 1356 1.31 itojun * truncated hostname. 1357 1.31 itojun */ 1358 1.31 itojun n = ni6_nametodns(hostname, hostnamelen, 0); 1359 1.31 itojun if (!n || n->m_next || n->m_len == 0) 1360 1.31 itojun goto bad; 1361 1.31 itojun IP6_EXTHDR_GET(subj, char *, m, 1362 1.31 itojun off + sizeof(struct icmp6_nodeinfo), subjlen); 1363 1.31 itojun if (subj == NULL) 1364 1.31 itojun goto bad; 1365 1.31 itojun if (!ni6_dnsmatch(subj, subjlen, mtod(n, const char *), 1366 1.229 maxv n->m_len)) { 1367 1.31 itojun goto bad; 1368 1.31 itojun } 1369 1.31 itojun m_freem(n); 1370 1.31 itojun n = NULL; 1371 1.31 itojun break; 1372 1.31 itojun 1373 1.47 itojun case ICMP6_NI_SUBJ_IPV4: /* XXX: to be implemented? */ 1374 1.31 itojun default: 1375 1.31 itojun goto bad; 1376 1.31 itojun } 1377 1.31 itojun break; 1378 1.2 itojun } 1379 1.2 itojun 1380 1.67 itojun /* refuse based on configuration. XXX ICMP6_NI_REFUSED? */ 1381 1.67 itojun switch (qtype) { 1382 1.67 itojun case NI_QTYPE_FQDN: 1383 1.67 itojun if ((icmp6_nodeinfo & 1) == 0) 1384 1.67 itojun goto bad; 1385 1.67 itojun break; 1386 1.67 itojun case NI_QTYPE_NODEADDR: 1387 1.115 rpaulo case NI_QTYPE_IPV4ADDR: 1388 1.67 itojun if ((icmp6_nodeinfo & 2) == 0) 1389 1.67 itojun goto bad; 1390 1.67 itojun break; 1391 1.67 itojun } 1392 1.67 itojun 1393 1.47 itojun /* guess reply length */ 1394 1.47 itojun switch (qtype) { 1395 1.47 itojun case NI_QTYPE_NOOP: 1396 1.47 itojun break; /* no reply data */ 1397 1.47 itojun case NI_QTYPE_SUPTYPES: 1398 1.47 itojun replylen += sizeof(u_int32_t); 1399 1.47 itojun break; 1400 1.47 itojun case NI_QTYPE_FQDN: 1401 1.219 maxv /* will append an mbuf */ 1402 1.47 itojun replylen += offsetof(struct ni_reply_fqdn, ni_fqdn_namelen); 1403 1.47 itojun break; 1404 1.47 itojun case NI_QTYPE_NODEADDR: 1405 1.219 maxv addrs = ni6_addrs(ni6, &ifp, subj, &psref); 1406 1.219 maxv replylen += addrs * 1407 1.219 maxv (sizeof(struct in6_addr) + sizeof(u_int32_t)); 1408 1.219 maxv if (replylen > MCLBYTES) 1409 1.47 itojun replylen = MCLBYTES; /* XXX: will truncate pkt later */ 1410 1.47 itojun break; 1411 1.115 rpaulo case NI_QTYPE_IPV4ADDR: 1412 1.115 rpaulo /* unsupported - should respond with unknown Qtype? */ 1413 1.115 rpaulo goto bad; 1414 1.47 itojun default: 1415 1.47 itojun /* 1416 1.47 itojun * XXX: We must return a reply with the ICMP6 code 1417 1.67 itojun * `unknown Qtype' in this case. However we regard the case 1418 1.47 itojun * as an FQDN query for backward compatibility. 1419 1.47 itojun * Older versions set a random value to this field, 1420 1.47 itojun * so it rarely varies in the defined qtypes. 1421 1.47 itojun * But the mechanism is not reliable... 1422 1.47 itojun * maybe we should obsolete older versions. 1423 1.47 itojun */ 1424 1.47 itojun qtype = NI_QTYPE_FQDN; 1425 1.219 maxv /* will append an mbuf */ 1426 1.47 itojun replylen += offsetof(struct ni_reply_fqdn, ni_fqdn_namelen); 1427 1.47 itojun oldfqdn++; 1428 1.47 itojun break; 1429 1.47 itojun } 1430 1.47 itojun 1431 1.47 itojun /* allocate an mbuf to reply. */ 1432 1.2 itojun MGETHDR(n, M_DONTWAIT, m->m_type); 1433 1.14 itojun if (n == NULL) { 1434 1.219 maxv goto bad; 1435 1.14 itojun } 1436 1.241 maxv m_move_pkthdr(n, m); 1437 1.2 itojun if (replylen > MHLEN) { 1438 1.31 itojun if (replylen > MCLBYTES) { 1439 1.53 itojun /* 1440 1.53 itojun * XXX: should we try to allocate more? But MCLBYTES 1441 1.53 itojun * is probably much larger than IPV6_MMTU... 1442 1.53 itojun */ 1443 1.2 itojun goto bad; 1444 1.31 itojun } 1445 1.2 itojun MCLGET(n, M_DONTWAIT); 1446 1.2 itojun if ((n->m_flags & M_EXT) == 0) { 1447 1.2 itojun goto bad; 1448 1.2 itojun } 1449 1.2 itojun } 1450 1.2 itojun n->m_pkthdr.len = n->m_len = replylen; 1451 1.2 itojun 1452 1.2 itojun /* copy mbuf header and IPv6 + Node Information base headers */ 1453 1.131 christos bcopy(mtod(m, void *), mtod(n, void *), sizeof(struct ip6_hdr)); 1454 1.29 itojun nni6 = (struct icmp6_nodeinfo *)(mtod(n, struct ip6_hdr *) + 1); 1455 1.131 christos bcopy((void *)ni6, (void *)nni6, sizeof(struct icmp6_nodeinfo)); 1456 1.2 itojun 1457 1.2 itojun /* qtype dependent procedure */ 1458 1.2 itojun switch (qtype) { 1459 1.31 itojun case NI_QTYPE_NOOP: 1460 1.40 itojun nni6->ni_code = ICMP6_NI_SUCCESS; 1461 1.31 itojun nni6->ni_flags = 0; 1462 1.31 itojun break; 1463 1.31 itojun case NI_QTYPE_SUPTYPES: 1464 1.42 itojun { 1465 1.42 itojun u_int32_t v; 1466 1.40 itojun nni6->ni_code = ICMP6_NI_SUCCESS; 1467 1.40 itojun nni6->ni_flags = htons(0x0000); /* raw bitmap */ 1468 1.40 itojun /* supports NOOP, SUPTYPES, FQDN, and NODEADDR */ 1469 1.42 itojun v = (u_int32_t)htonl(0x0000000f); 1470 1.220 maxv memcpy(nni6 + 1, &v, sizeof(u_int32_t)); 1471 1.31 itojun break; 1472 1.42 itojun } 1473 1.31 itojun case NI_QTYPE_FQDN: 1474 1.40 itojun nni6->ni_code = ICMP6_NI_SUCCESS; 1475 1.131 christos fqdn = (struct ni_reply_fqdn *)(mtod(n, char *) + 1476 1.229 maxv sizeof(struct ip6_hdr) + sizeof(struct icmp6_nodeinfo)); 1477 1.31 itojun nni6->ni_flags = 0; /* XXX: meaningless TTL */ 1478 1.31 itojun fqdn->ni_fqdn_ttl = 0; /* ditto. */ 1479 1.31 itojun /* 1480 1.31 itojun * XXX do we really have FQDN in variable "hostname"? 1481 1.31 itojun */ 1482 1.31 itojun n->m_next = ni6_nametodns(hostname, hostnamelen, oldfqdn); 1483 1.31 itojun if (n->m_next == NULL) 1484 1.31 itojun goto bad; 1485 1.31 itojun /* XXX we assume that n->m_next is not a chain */ 1486 1.31 itojun if (n->m_next->m_next != NULL) 1487 1.31 itojun goto bad; 1488 1.31 itojun n->m_pkthdr.len += n->m_next->m_len; 1489 1.31 itojun break; 1490 1.31 itojun case NI_QTYPE_NODEADDR: 1491 1.31 itojun { 1492 1.31 itojun int lenlim, copied; 1493 1.31 itojun 1494 1.40 itojun nni6->ni_code = ICMP6_NI_SUCCESS; 1495 1.229 maxv n->m_pkthdr.len = n->m_len = sizeof(struct ip6_hdr) + 1496 1.229 maxv sizeof(struct icmp6_nodeinfo); 1497 1.42 itojun lenlim = M_TRAILINGSPACE(n); 1498 1.31 itojun copied = ni6_store_addrs(ni6, nni6, ifp, lenlim); 1499 1.195 ozaki if_put(ifp, &psref); 1500 1.195 ozaki ifp = NULL; 1501 1.229 maxv /* update mbuf length */ 1502 1.31 itojun n->m_pkthdr.len = n->m_len = sizeof(struct ip6_hdr) + 1503 1.229 maxv sizeof(struct icmp6_nodeinfo) + copied; 1504 1.31 itojun break; 1505 1.31 itojun } 1506 1.31 itojun default: 1507 1.219 maxv panic("%s: impossible", __func__); 1508 1.219 maxv break; 1509 1.2 itojun } 1510 1.2 itojun 1511 1.2 itojun nni6->ni_type = ICMP6_NI_REPLY; 1512 1.14 itojun m_freem(m); 1513 1.219 maxv return n; 1514 1.2 itojun 1515 1.219 maxv bad: 1516 1.195 ozaki if_put(ifp, &psref); 1517 1.14 itojun m_freem(m); 1518 1.258 rin m_freem(n); 1519 1.219 maxv return NULL; 1520 1.2 itojun } 1521 1.2 itojun 1522 1.76 itojun #define isupper(x) ('A' <= (x) && (x) <= 'Z') 1523 1.76 itojun #define isalpha(x) (('A' <= (x) && (x) <= 'Z') || ('a' <= (x) && (x) <= 'z')) 1524 1.76 itojun #define isalnum(x) (isalpha(x) || ('0' <= (x) && (x) <= '9')) 1525 1.76 itojun #define tolower(x) (isupper(x) ? (x) + 'a' - 'A' : (x)) 1526 1.76 itojun 1527 1.2 itojun /* 1528 1.31 itojun * make a mbuf with DNS-encoded string. no compression support. 1529 1.31 itojun * 1530 1.31 itojun * XXX names with less than 2 dots (like "foo" or "foo.section") will be 1531 1.31 itojun * treated as truncated name (two \0 at the end). this is a wild guess. 1532 1.133 christos * 1533 1.133 christos * old - return pascal string if non-zero 1534 1.31 itojun */ 1535 1.31 itojun static struct mbuf * 1536 1.133 christos ni6_nametodns(const char *name, int namelen, int old) 1537 1.31 itojun { 1538 1.31 itojun struct mbuf *m; 1539 1.31 itojun char *cp, *ep; 1540 1.31 itojun const char *p, *q; 1541 1.31 itojun int i, len, nterm; 1542 1.31 itojun 1543 1.31 itojun if (old) 1544 1.31 itojun len = namelen + 1; 1545 1.31 itojun else 1546 1.31 itojun len = MCLBYTES; 1547 1.31 itojun 1548 1.31 itojun /* because MAXHOSTNAMELEN is usually 256, we use cluster mbuf */ 1549 1.31 itojun MGET(m, M_DONTWAIT, MT_DATA); 1550 1.31 itojun if (m && len > MLEN) { 1551 1.31 itojun MCLGET(m, M_DONTWAIT); 1552 1.31 itojun if ((m->m_flags & M_EXT) == 0) 1553 1.31 itojun goto fail; 1554 1.31 itojun } 1555 1.31 itojun if (!m) 1556 1.31 itojun goto fail; 1557 1.31 itojun m->m_next = NULL; 1558 1.31 itojun 1559 1.31 itojun if (old) { 1560 1.31 itojun m->m_len = len; 1561 1.31 itojun *mtod(m, char *) = namelen; 1562 1.220 maxv memcpy(mtod(m, char *) + 1, name, namelen); 1563 1.31 itojun return m; 1564 1.31 itojun } else { 1565 1.31 itojun m->m_len = 0; 1566 1.31 itojun cp = mtod(m, char *); 1567 1.31 itojun ep = mtod(m, char *) + M_TRAILINGSPACE(m); 1568 1.31 itojun 1569 1.31 itojun /* if not certain about my name, return empty buffer */ 1570 1.31 itojun if (namelen == 0) 1571 1.31 itojun return m; 1572 1.31 itojun 1573 1.31 itojun /* 1574 1.31 itojun * guess if it looks like shortened hostname, or FQDN. 1575 1.31 itojun * shortened hostname needs two trailing "\0". 1576 1.31 itojun */ 1577 1.31 itojun i = 0; 1578 1.31 itojun for (p = name; p < name + namelen; p++) { 1579 1.197 dholland if (*p == '.') 1580 1.31 itojun i++; 1581 1.31 itojun } 1582 1.31 itojun if (i < 2) 1583 1.31 itojun nterm = 2; 1584 1.31 itojun else 1585 1.31 itojun nterm = 1; 1586 1.31 itojun 1587 1.31 itojun p = name; 1588 1.31 itojun while (cp < ep && p < name + namelen) { 1589 1.31 itojun i = 0; 1590 1.31 itojun for (q = p; q < name + namelen && *q && *q != '.'; q++) 1591 1.31 itojun i++; 1592 1.31 itojun /* result does not fit into mbuf */ 1593 1.31 itojun if (cp + i + 1 >= ep) 1594 1.31 itojun goto fail; 1595 1.67 itojun /* 1596 1.67 itojun * DNS label length restriction, RFC1035 page 8. 1597 1.67 itojun * "i == 0" case is included here to avoid returning 1598 1.67 itojun * 0-length label on "foo..bar". 1599 1.67 itojun */ 1600 1.67 itojun if (i <= 0 || i >= 64) 1601 1.31 itojun goto fail; 1602 1.31 itojun *cp++ = i; 1603 1.76 itojun if (!isalpha(p[0]) || !isalnum(p[i - 1])) 1604 1.76 itojun goto fail; 1605 1.76 itojun while (i > 0) { 1606 1.76 itojun if (!isalnum(*p) && *p != '-') 1607 1.76 itojun goto fail; 1608 1.84 itojun if (isupper(*p)) { 1609 1.84 itojun *cp++ = tolower(*p); 1610 1.84 itojun p++; 1611 1.84 itojun } else 1612 1.76 itojun *cp++ = *p++; 1613 1.76 itojun i--; 1614 1.76 itojun } 1615 1.31 itojun p = q; 1616 1.31 itojun if (p < name + namelen && *p == '.') 1617 1.31 itojun p++; 1618 1.31 itojun } 1619 1.31 itojun /* termination */ 1620 1.31 itojun if (cp + nterm >= ep) 1621 1.31 itojun goto fail; 1622 1.31 itojun while (nterm-- > 0) 1623 1.31 itojun *cp++ = '\0'; 1624 1.31 itojun m->m_len = cp - mtod(m, char *); 1625 1.31 itojun return m; 1626 1.31 itojun } 1627 1.31 itojun 1628 1.31 itojun panic("should not reach here"); 1629 1.67 itojun /* NOTREACHED */ 1630 1.31 itojun 1631 1.219 maxv fail: 1632 1.258 rin m_freem(m); 1633 1.31 itojun return NULL; 1634 1.31 itojun } 1635 1.31 itojun 1636 1.31 itojun /* 1637 1.31 itojun * check if two DNS-encoded string matches. takes care of truncated 1638 1.31 itojun * form (with \0\0 at the end). no compression support. 1639 1.40 itojun * XXX upper/lowercase match (see RFC2065) 1640 1.31 itojun */ 1641 1.31 itojun static int 1642 1.133 christos ni6_dnsmatch(const char *a, int alen, const char *b, int blen) 1643 1.31 itojun { 1644 1.31 itojun const char *a0, *b0; 1645 1.31 itojun int l; 1646 1.31 itojun 1647 1.31 itojun /* simplest case - need validation? */ 1648 1.151 cegger if (alen == blen && memcmp(a, b, alen) == 0) 1649 1.31 itojun return 1; 1650 1.31 itojun 1651 1.31 itojun a0 = a; 1652 1.31 itojun b0 = b; 1653 1.31 itojun 1654 1.31 itojun /* termination is mandatory */ 1655 1.31 itojun if (alen < 2 || blen < 2) 1656 1.31 itojun return 0; 1657 1.31 itojun if (a0[alen - 1] != '\0' || b0[blen - 1] != '\0') 1658 1.31 itojun return 0; 1659 1.31 itojun alen--; 1660 1.31 itojun blen--; 1661 1.31 itojun 1662 1.31 itojun while (a - a0 < alen && b - b0 < blen) { 1663 1.31 itojun if (a - a0 + 1 > alen || b - b0 + 1 > blen) 1664 1.31 itojun return 0; 1665 1.31 itojun 1666 1.33 itojun if ((signed char)a[0] < 0 || (signed char)b[0] < 0) 1667 1.31 itojun return 0; 1668 1.31 itojun /* we don't support compression yet */ 1669 1.31 itojun if (a[0] >= 64 || b[0] >= 64) 1670 1.31 itojun return 0; 1671 1.31 itojun 1672 1.31 itojun /* truncated case */ 1673 1.31 itojun if (a[0] == 0 && a - a0 == alen - 1) 1674 1.31 itojun return 1; 1675 1.31 itojun if (b[0] == 0 && b - b0 == blen - 1) 1676 1.31 itojun return 1; 1677 1.31 itojun if (a[0] == 0 || b[0] == 0) 1678 1.31 itojun return 0; 1679 1.31 itojun 1680 1.31 itojun if (a[0] != b[0]) 1681 1.31 itojun return 0; 1682 1.31 itojun l = a[0]; 1683 1.31 itojun if (a - a0 + 1 + l > alen || b - b0 + 1 + l > blen) 1684 1.31 itojun return 0; 1685 1.151 cegger if (memcmp(a + 1, b + 1, l) != 0) 1686 1.31 itojun return 0; 1687 1.31 itojun 1688 1.31 itojun a += 1 + l; 1689 1.31 itojun b += 1 + l; 1690 1.31 itojun } 1691 1.31 itojun 1692 1.31 itojun if (a - a0 == alen && b - b0 == blen) 1693 1.31 itojun return 1; 1694 1.31 itojun else 1695 1.31 itojun return 0; 1696 1.31 itojun } 1697 1.31 itojun 1698 1.31 itojun /* 1699 1.2 itojun * calculate the number of addresses to be returned in the node info reply. 1700 1.2 itojun */ 1701 1.2 itojun static int 1702 1.219 maxv ni6_addrs(struct icmp6_nodeinfo *ni6, struct ifnet **ifpp, char *subj, 1703 1.219 maxv struct psref *psref) 1704 1.2 itojun { 1705 1.53 itojun struct ifnet *ifp; 1706 1.191 ozaki struct in6_ifaddr *ia6; 1707 1.53 itojun struct ifaddr *ifa; 1708 1.47 itojun struct sockaddr_in6 *subj_ip6 = NULL; /* XXX pedant */ 1709 1.2 itojun int addrs = 0, addrsofif, iffound = 0; 1710 1.47 itojun int niflags = ni6->ni_flags; 1711 1.195 ozaki int s; 1712 1.47 itojun 1713 1.47 itojun if ((niflags & NI_NODEADDR_FLAG_ALL) == 0) { 1714 1.56 itojun switch (ni6->ni_code) { 1715 1.47 itojun case ICMP6_NI_SUBJ_IPV6: 1716 1.47 itojun if (subj == NULL) /* must be impossible... */ 1717 1.229 maxv return 0; 1718 1.47 itojun subj_ip6 = (struct sockaddr_in6 *)subj; 1719 1.47 itojun break; 1720 1.47 itojun default: 1721 1.47 itojun /* 1722 1.47 itojun * XXX: we only support IPv6 subject address for 1723 1.47 itojun * this Qtype. 1724 1.47 itojun */ 1725 1.229 maxv return 0; 1726 1.47 itojun } 1727 1.47 itojun } 1728 1.2 itojun 1729 1.195 ozaki s = pserialize_read_enter(); 1730 1.183 ozaki IFNET_READER_FOREACH(ifp) { 1731 1.2 itojun addrsofif = 0; 1732 1.192 ozaki IFADDR_READER_FOREACH(ifa, ifp) { 1733 1.2 itojun if (ifa->ifa_addr->sa_family != AF_INET6) 1734 1.2 itojun continue; 1735 1.191 ozaki ia6 = (struct in6_ifaddr *)ifa; 1736 1.2 itojun 1737 1.47 itojun if ((niflags & NI_NODEADDR_FLAG_ALL) == 0 && 1738 1.47 itojun IN6_ARE_ADDR_EQUAL(&subj_ip6->sin6_addr, 1739 1.229 maxv &ia6->ia_addr.sin6_addr)) 1740 1.2 itojun iffound = 1; 1741 1.24 itojun 1742 1.24 itojun /* 1743 1.24 itojun * IPv4-mapped addresses can only be returned by a 1744 1.24 itojun * Node Information proxy, since they represent 1745 1.24 itojun * addresses of IPv4-only nodes, which perforce do 1746 1.24 itojun * not implement this protocol. 1747 1.47 itojun * [icmp-name-lookups-07, Section 5.4] 1748 1.24 itojun * So we don't support NI_NODEADDR_FLAG_COMPAT in 1749 1.24 itojun * this function at this moment. 1750 1.24 itojun */ 1751 1.2 itojun 1752 1.2 itojun /* What do we have to do about ::1? */ 1753 1.191 ozaki switch (in6_addrscope(&ia6->ia_addr.sin6_addr)) { 1754 1.47 itojun case IPV6_ADDR_SCOPE_LINKLOCAL: 1755 1.53 itojun if ((niflags & NI_NODEADDR_FLAG_LINKLOCAL) == 0) 1756 1.47 itojun continue; 1757 1.2 itojun break; 1758 1.47 itojun case IPV6_ADDR_SCOPE_SITELOCAL: 1759 1.53 itojun if ((niflags & NI_NODEADDR_FLAG_SITELOCAL) == 0) 1760 1.47 itojun continue; 1761 1.47 itojun break; 1762 1.47 itojun case IPV6_ADDR_SCOPE_GLOBAL: 1763 1.53 itojun if ((niflags & NI_NODEADDR_FLAG_GLOBAL) == 0) 1764 1.47 itojun continue; 1765 1.2 itojun break; 1766 1.47 itojun default: 1767 1.47 itojun continue; 1768 1.2 itojun } 1769 1.47 itojun 1770 1.47 itojun /* 1771 1.47 itojun * check if anycast is okay. 1772 1.67 itojun * XXX: just experimental. not in the spec. 1773 1.47 itojun */ 1774 1.191 ozaki if ((ia6->ia6_flags & IN6_IFF_ANYCAST) != 0 && 1775 1.47 itojun (niflags & NI_NODEADDR_FLAG_ANYCAST) == 0) 1776 1.47 itojun continue; /* we need only unicast addresses */ 1777 1.47 itojun 1778 1.47 itojun addrsofif++; /* count the address */ 1779 1.2 itojun } 1780 1.2 itojun if (iffound) { 1781 1.210 ozaki if_acquire(ifp, psref); 1782 1.195 ozaki pserialize_read_exit(s); 1783 1.2 itojun *ifpp = ifp; 1784 1.229 maxv return addrsofif; 1785 1.2 itojun } 1786 1.2 itojun 1787 1.2 itojun addrs += addrsofif; 1788 1.2 itojun } 1789 1.195 ozaki pserialize_read_exit(s); 1790 1.2 itojun 1791 1.229 maxv return addrs; 1792 1.2 itojun } 1793 1.2 itojun 1794 1.2 itojun static int 1795 1.219 maxv ni6_store_addrs(struct icmp6_nodeinfo *ni6, 1796 1.133 christos struct icmp6_nodeinfo *nni6, struct ifnet *ifp0, 1797 1.133 christos int resid) 1798 1.2 itojun { 1799 1.195 ozaki struct ifnet *ifp; 1800 1.191 ozaki struct in6_ifaddr *ia6; 1801 1.53 itojun struct ifaddr *ifa; 1802 1.47 itojun struct ifnet *ifp_dep = NULL; 1803 1.47 itojun int copied = 0, allow_deprecated = 0; 1804 1.2 itojun u_char *cp = (u_char *)(nni6 + 1); 1805 1.47 itojun int niflags = ni6->ni_flags; 1806 1.47 itojun u_int32_t ltime; 1807 1.195 ozaki int s; 1808 1.2 itojun 1809 1.47 itojun if (ifp0 == NULL && !(niflags & NI_NODEADDR_FLAG_ALL)) 1810 1.229 maxv return 0; /* needless to copy */ 1811 1.2 itojun 1812 1.195 ozaki s = pserialize_read_enter(); 1813 1.195 ozaki ifp = ifp0 ? ifp0 : IFNET_READER_FIRST(); 1814 1.219 maxv again: 1815 1.47 itojun 1816 1.183 ozaki for (; ifp; ifp = IFNET_READER_NEXT(ifp)) 1817 1.2 itojun { 1818 1.192 ozaki IFADDR_READER_FOREACH(ifa, ifp) { 1819 1.2 itojun if (ifa->ifa_addr->sa_family != AF_INET6) 1820 1.2 itojun continue; 1821 1.191 ozaki ia6 = (struct in6_ifaddr *)ifa; 1822 1.2 itojun 1823 1.191 ozaki if ((ia6->ia6_flags & IN6_IFF_DEPRECATED) != 0 && 1824 1.47 itojun allow_deprecated == 0) { 1825 1.47 itojun /* 1826 1.47 itojun * prefererred address should be put before 1827 1.47 itojun * deprecated addresses. 1828 1.47 itojun */ 1829 1.47 itojun 1830 1.47 itojun /* record the interface for later search */ 1831 1.47 itojun if (ifp_dep == NULL) 1832 1.47 itojun ifp_dep = ifp; 1833 1.47 itojun 1834 1.47 itojun continue; 1835 1.12 itojun } 1836 1.191 ozaki else if ((ia6->ia6_flags & IN6_IFF_DEPRECATED) == 0 && 1837 1.47 itojun allow_deprecated != 0) 1838 1.47 itojun continue; /* we now collect deprecated addrs */ 1839 1.2 itojun 1840 1.2 itojun /* What do we have to do about ::1? */ 1841 1.191 ozaki switch (in6_addrscope(&ia6->ia_addr.sin6_addr)) { 1842 1.47 itojun case IPV6_ADDR_SCOPE_LINKLOCAL: 1843 1.53 itojun if ((niflags & NI_NODEADDR_FLAG_LINKLOCAL) == 0) 1844 1.47 itojun continue; 1845 1.2 itojun break; 1846 1.47 itojun case IPV6_ADDR_SCOPE_SITELOCAL: 1847 1.53 itojun if ((niflags & NI_NODEADDR_FLAG_SITELOCAL) == 0) 1848 1.47 itojun continue; 1849 1.47 itojun break; 1850 1.47 itojun case IPV6_ADDR_SCOPE_GLOBAL: 1851 1.53 itojun if ((niflags & NI_NODEADDR_FLAG_GLOBAL) == 0) 1852 1.47 itojun continue; 1853 1.2 itojun break; 1854 1.47 itojun default: 1855 1.47 itojun continue; 1856 1.47 itojun } 1857 1.47 itojun 1858 1.47 itojun /* 1859 1.47 itojun * check if anycast is okay. 1860 1.67 itojun * XXX: just experimental. not in the spec. 1861 1.47 itojun */ 1862 1.191 ozaki if ((ia6->ia6_flags & IN6_IFF_ANYCAST) != 0 && 1863 1.47 itojun (niflags & NI_NODEADDR_FLAG_ANYCAST) == 0) 1864 1.47 itojun continue; 1865 1.47 itojun 1866 1.47 itojun /* now we can copy the address */ 1867 1.47 itojun if (resid < sizeof(struct in6_addr) + 1868 1.47 itojun sizeof(u_int32_t)) { 1869 1.47 itojun /* 1870 1.47 itojun * We give up much more copy. 1871 1.47 itojun * Set the truncate flag and return. 1872 1.47 itojun */ 1873 1.115 rpaulo nni6->ni_flags |= NI_NODEADDR_FLAG_TRUNCATE; 1874 1.195 ozaki goto out; 1875 1.2 itojun } 1876 1.2 itojun 1877 1.47 itojun /* 1878 1.47 itojun * Set the TTL of the address. 1879 1.47 itojun * The TTL value should be one of the following 1880 1.47 itojun * according to the specification: 1881 1.47 itojun * 1882 1.47 itojun * 1. The remaining lifetime of a DHCP lease on the 1883 1.47 itojun * address, or 1884 1.47 itojun * 2. The remaining Valid Lifetime of a prefix from 1885 1.47 itojun * which the address was derived through Stateless 1886 1.47 itojun * Autoconfiguration. 1887 1.47 itojun * 1888 1.47 itojun * Note that we currently do not support stateful 1889 1.47 itojun * address configuration by DHCPv6, so the former 1890 1.47 itojun * case can't happen. 1891 1.67 itojun * 1892 1.67 itojun * TTL must be 2^31 > TTL >= 0. 1893 1.47 itojun */ 1894 1.191 ozaki if (ia6->ia6_lifetime.ia6t_expire == 0) 1895 1.47 itojun ltime = ND6_INFINITE_LIFETIME; 1896 1.47 itojun else { 1897 1.191 ozaki if (ia6->ia6_lifetime.ia6t_expire > 1898 1.173 ozaki time_uptime) 1899 1.191 ozaki ltime = ia6->ia6_lifetime.ia6t_expire - 1900 1.173 ozaki time_uptime; 1901 1.47 itojun else 1902 1.47 itojun ltime = 0; 1903 1.2 itojun } 1904 1.67 itojun if (ltime > 0x7fffffff) 1905 1.67 itojun ltime = 0x7fffffff; 1906 1.67 itojun ltime = htonl(ltime); 1907 1.82 itojun 1908 1.220 maxv memcpy(cp, <ime, sizeof(u_int32_t)); 1909 1.47 itojun cp += sizeof(u_int32_t); 1910 1.47 itojun 1911 1.47 itojun /* copy the address itself */ 1912 1.191 ozaki bcopy(&ia6->ia_addr.sin6_addr, cp, 1913 1.47 itojun sizeof(struct in6_addr)); 1914 1.113 rpaulo in6_clearscope((struct in6_addr *)cp); /* XXX */ 1915 1.47 itojun cp += sizeof(struct in6_addr); 1916 1.82 itojun 1917 1.47 itojun resid -= (sizeof(struct in6_addr) + sizeof(u_int32_t)); 1918 1.115 rpaulo copied += (sizeof(struct in6_addr) + sizeof(u_int32_t)); 1919 1.2 itojun } 1920 1.2 itojun if (ifp0) /* we need search only on the specified IF */ 1921 1.2 itojun break; 1922 1.47 itojun } 1923 1.47 itojun 1924 1.47 itojun if (allow_deprecated == 0 && ifp_dep != NULL) { 1925 1.47 itojun ifp = ifp_dep; 1926 1.47 itojun allow_deprecated = 1; 1927 1.47 itojun 1928 1.47 itojun goto again; 1929 1.2 itojun } 1930 1.195 ozaki out: 1931 1.195 ozaki pserialize_read_exit(s); 1932 1.229 maxv return copied; 1933 1.2 itojun } 1934 1.2 itojun 1935 1.2 itojun /* 1936 1.2 itojun * XXX almost dup'ed code with rip6_input. 1937 1.2 itojun */ 1938 1.2 itojun static int 1939 1.133 christos icmp6_rip6_input(struct mbuf **mp, int off) 1940 1.2 itojun { 1941 1.2 itojun struct mbuf *m = *mp; 1942 1.53 itojun struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 1943 1.253 ozaki struct inpcb *inp; 1944 1.253 ozaki struct inpcb *last = NULL; 1945 1.2 itojun struct sockaddr_in6 rip6src; 1946 1.2 itojun struct icmp6_hdr *icmp6; 1947 1.226 maxv struct mbuf *n, *opts = NULL; 1948 1.2 itojun 1949 1.23 itojun IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, sizeof(*icmp6)); 1950 1.23 itojun if (icmp6 == NULL) { 1951 1.23 itojun /* m is already reclaimed */ 1952 1.23 itojun return IPPROTO_DONE; 1953 1.23 itojun } 1954 1.2 itojun 1955 1.113 rpaulo /* 1956 1.113 rpaulo * XXX: the address may have embedded scope zone ID, which should be 1957 1.113 rpaulo * hidden from applications. 1958 1.113 rpaulo */ 1959 1.138 dyoung sockaddr_in6_init(&rip6src, &ip6->ip6_src, 0, 0, 0); 1960 1.113 rpaulo if (sa6_recoverscope(&rip6src)) { 1961 1.113 rpaulo m_freem(m); 1962 1.229 maxv return IPPROTO_DONE; 1963 1.113 rpaulo } 1964 1.2 itojun 1965 1.253 ozaki TAILQ_FOREACH(inp, &raw6cbtable.inpt_queue, inp_queue) { 1966 1.253 ozaki if (inp->inp_af != AF_INET6) 1967 1.101 itojun continue; 1968 1.254 ozaki if (in6p_ip6(inp).ip6_nxt != IPPROTO_ICMPV6) 1969 1.2 itojun continue; 1970 1.254 ozaki if (!IN6_IS_ADDR_UNSPECIFIED(&in6p_laddr(inp)) && 1971 1.254 ozaki !IN6_ARE_ADDR_EQUAL(&in6p_laddr(inp), &ip6->ip6_dst)) 1972 1.2 itojun continue; 1973 1.254 ozaki if (!IN6_IS_ADDR_UNSPECIFIED(&in6p_faddr(inp)) && 1974 1.254 ozaki !IN6_ARE_ADDR_EQUAL(&in6p_faddr(inp), &ip6->ip6_src)) 1975 1.2 itojun continue; 1976 1.254 ozaki if (in6p_icmp6filt(inp) && 1977 1.226 maxv ICMP6_FILTER_WILLBLOCK(icmp6->icmp6_type, 1978 1.254 ozaki in6p_icmp6filt(inp))) 1979 1.2 itojun continue; 1980 1.226 maxv 1981 1.226 maxv if (last == NULL) { 1982 1.226 maxv ; 1983 1.226 maxv } 1984 1.213 ozaki #ifdef IPSEC 1985 1.226 maxv else if (ipsec_used && ipsec_in_reject(m, last)) { 1986 1.226 maxv /* do not inject data into pcb */ 1987 1.226 maxv } 1988 1.216 maxv #endif 1989 1.235 maxv else if ((n = m_copypacket(m, M_DONTWAIT)) != NULL) { 1990 1.256 mlelstv if (last->inp_flags & IN6P_CONTROLOPTS || 1991 1.256 mlelstv SOOPT_TIMESTAMP(last->inp_socket->so_options)) 1992 1.226 maxv ip6_savecontrol(last, &opts, ip6, n); 1993 1.226 maxv /* strip intermediate headers */ 1994 1.226 maxv m_adj(n, off); 1995 1.253 ozaki if (sbappendaddr(&last->inp_socket->so_rcv, 1996 1.226 maxv sin6tosa(&rip6src), n, opts) == 0) { 1997 1.253 ozaki soroverflow(last->inp_socket); 1998 1.226 maxv m_freem(n); 1999 1.258 rin m_freem(opts); 2000 1.226 maxv } else { 2001 1.253 ozaki sorwakeup(last->inp_socket); 2002 1.2 itojun } 2003 1.226 maxv opts = NULL; 2004 1.2 itojun } 2005 1.226 maxv 2006 1.253 ozaki last = inp; 2007 1.2 itojun } 2008 1.216 maxv 2009 1.213 ozaki #ifdef IPSEC 2010 1.221 maxv if (ipsec_used && last && ipsec_in_reject(m, last)) { 2011 1.213 ozaki m_freem(m); 2012 1.216 maxv IP6_STATDEC(IP6_STAT_DELIVERED); 2013 1.216 maxv /* do not inject data into pcb */ 2014 1.216 maxv } else 2015 1.216 maxv #endif 2016 1.2 itojun if (last) { 2017 1.256 mlelstv if (last->inp_flags & IN6P_CONTROLOPTS || 2018 1.256 mlelstv SOOPT_TIMESTAMP(last->inp_socket->so_options)) 2019 1.2 itojun ip6_savecontrol(last, &opts, ip6, m); 2020 1.2 itojun /* strip intermediate headers */ 2021 1.2 itojun m_adj(m, off); 2022 1.253 ozaki if (sbappendaddr(&last->inp_socket->so_rcv, 2023 1.194 ozaki sin6tosa(&rip6src), m, opts) == 0) { 2024 1.253 ozaki soroverflow(last->inp_socket); 2025 1.2 itojun m_freem(m); 2026 1.258 rin m_freem(opts); 2027 1.229 maxv } else { 2028 1.253 ozaki sorwakeup(last->inp_socket); 2029 1.229 maxv } 2030 1.2 itojun } else { 2031 1.2 itojun m_freem(m); 2032 1.145 thorpej IP6_STATDEC(IP6_STAT_DELIVERED); 2033 1.2 itojun } 2034 1.2 itojun return IPPROTO_DONE; 2035 1.2 itojun } 2036 1.2 itojun 2037 1.2 itojun /* 2038 1.2 itojun * Reflect the ip6 packet back to the source. 2039 1.14 itojun * OFF points to the icmp6 header, counted from the top of the mbuf. 2040 1.66 itojun * 2041 1.66 itojun * Note: RFC 1885 required that an echo reply should be truncated if it 2042 1.66 itojun * did not fit in with (return) path MTU, and KAME code supported the 2043 1.66 itojun * behavior. However, as a clarification after the RFC, this limitation 2044 1.66 itojun * was removed in a revised version of the spec, RFC 2463. We had kept the 2045 1.66 itojun * old behavior, with a (non-default) ifdef block, while the new version of 2046 1.66 itojun * the spec was an internet-draft status, and even after the new RFC was 2047 1.66 itojun * published. But it would rather make sense to clean the obsoleted part 2048 1.66 itojun * up, and to make the code simpler at this stage. 2049 1.2 itojun */ 2050 1.219 maxv static void 2051 1.130 dyoung icmp6_reflect(struct mbuf *m, size_t off) 2052 1.2 itojun { 2053 1.12 itojun struct ip6_hdr *ip6; 2054 1.2 itojun struct icmp6_hdr *icmp6; 2055 1.139 dyoung const struct in6_ifaddr *ia; 2056 1.139 dyoung const struct ip6aux *ip6a; 2057 1.12 itojun int plen; 2058 1.12 itojun int type, code; 2059 1.12 itojun struct ifnet *outif = NULL; 2060 1.139 dyoung struct in6_addr origdst; 2061 1.188 ozaki struct ifnet *rcvif; 2062 1.188 ozaki int s; 2063 1.200 ozaki bool ip6_src_filled = false; 2064 1.251 knakahar int flags; 2065 1.2 itojun 2066 1.12 itojun /* too short to reflect */ 2067 1.12 itojun if (off < sizeof(struct ip6_hdr)) { 2068 1.180 ozaki nd6log(LOG_DEBUG, 2069 1.53 itojun "sanity fail: off=%lx, sizeof(ip6)=%lx in %s:%d\n", 2070 1.53 itojun (u_long)off, (u_long)sizeof(struct ip6_hdr), 2071 1.180 ozaki __FILE__, __LINE__); 2072 1.12 itojun goto bad; 2073 1.12 itojun } 2074 1.12 itojun 2075 1.2 itojun /* 2076 1.2 itojun * If there are extra headers between IPv6 and ICMPv6, strip 2077 1.2 itojun * off that header first. 2078 1.2 itojun */ 2079 1.211 ozaki CTASSERT(sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr) <= MHLEN); 2080 1.12 itojun if (off > sizeof(struct ip6_hdr)) { 2081 1.12 itojun size_t l; 2082 1.12 itojun struct ip6_hdr nip6; 2083 1.12 itojun 2084 1.12 itojun l = off - sizeof(struct ip6_hdr); 2085 1.131 christos m_copydata(m, 0, sizeof(nip6), (void *)&nip6); 2086 1.12 itojun m_adj(m, l); 2087 1.12 itojun l = sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr); 2088 1.12 itojun if (m->m_len < l) { 2089 1.12 itojun if ((m = m_pullup(m, l)) == NULL) 2090 1.12 itojun return; 2091 1.12 itojun } 2092 1.220 maxv memcpy(mtod(m, void *), (void *)&nip6, sizeof(nip6)); 2093 1.215 maxv } else { 2094 1.215 maxv size_t l = sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr); 2095 1.12 itojun if (m->m_len < l) { 2096 1.12 itojun if ((m = m_pullup(m, l)) == NULL) 2097 1.12 itojun return; 2098 1.2 itojun } 2099 1.2 itojun } 2100 1.215 maxv 2101 1.12 itojun plen = m->m_pkthdr.len - sizeof(struct ip6_hdr); 2102 1.12 itojun ip6 = mtod(m, struct ip6_hdr *); 2103 1.12 itojun ip6->ip6_nxt = IPPROTO_ICMPV6; 2104 1.2 itojun icmp6 = (struct icmp6_hdr *)(ip6 + 1); 2105 1.12 itojun type = icmp6->icmp6_type; /* keep type for statistics */ 2106 1.12 itojun code = icmp6->icmp6_code; /* ditto. */ 2107 1.2 itojun 2108 1.113 rpaulo origdst = ip6->ip6_dst; 2109 1.2 itojun /* 2110 1.2 itojun * ip6_input() drops a packet if its src is multicast. 2111 1.2 itojun * So, the src is never multicast. 2112 1.2 itojun */ 2113 1.2 itojun ip6->ip6_dst = ip6->ip6_src; 2114 1.2 itojun 2115 1.55 itojun /* 2116 1.67 itojun * If the incoming packet was addressed directly to us (i.e. unicast), 2117 1.2 itojun * use dst as the src for the reply. 2118 1.114 rpaulo * The IN6_IFF_NOTREADY case should be VERY rare, but is possible 2119 1.23 itojun * (for example) when we encounter an error while forwarding procedure 2120 1.23 itojun * destined to a duplicated address of ours. 2121 1.113 rpaulo * Note that ip6_getdstifaddr() may fail if we are in an error handling 2122 1.113 rpaulo * procedure of an outgoing packet of our own, in which case we need 2123 1.113 rpaulo * to search in the ifaddr list. 2124 1.2 itojun */ 2125 1.229 maxv if (IN6_IS_ADDR_MULTICAST(&origdst)) { 2126 1.139 dyoung ; 2127 1.229 maxv } else if ((ip6a = ip6_getdstifaddr(m)) != NULL) { 2128 1.139 dyoung if ((ip6a->ip6a_flags & 2129 1.200 ozaki (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY)) == 0) { 2130 1.200 ozaki ip6->ip6_src = ip6a->ip6a_src; 2131 1.200 ozaki ip6_src_filled = true; 2132 1.200 ozaki } 2133 1.139 dyoung } else { 2134 1.139 dyoung union { 2135 1.139 dyoung struct sockaddr_in6 sin6; 2136 1.139 dyoung struct sockaddr sa; 2137 1.139 dyoung } u; 2138 1.195 ozaki int _s; 2139 1.195 ozaki struct ifaddr *ifa; 2140 1.139 dyoung 2141 1.139 dyoung sockaddr_in6_init(&u.sin6, &origdst, 0, 0, 0); 2142 1.139 dyoung 2143 1.195 ozaki _s = pserialize_read_enter(); 2144 1.195 ozaki ifa = ifa_ifwithaddr(&u.sa); 2145 1.139 dyoung 2146 1.195 ozaki if (ifa != NULL) { 2147 1.195 ozaki ia = ifatoia6(ifa); 2148 1.195 ozaki if ((ia->ia6_flags & 2149 1.200 ozaki (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY)) == 0) { 2150 1.200 ozaki ip6->ip6_src = ia->ia_addr.sin6_addr; 2151 1.200 ozaki ip6_src_filled = true; 2152 1.200 ozaki } 2153 1.195 ozaki } 2154 1.195 ozaki pserialize_read_exit(_s); 2155 1.2 itojun } 2156 1.2 itojun 2157 1.200 ozaki if (!ip6_src_filled) { 2158 1.55 itojun int e; 2159 1.113 rpaulo struct sockaddr_in6 sin6; 2160 1.132 dyoung struct route ro; 2161 1.55 itojun 2162 1.2 itojun /* 2163 1.23 itojun * This case matches to multicasts, our anycast, or unicasts 2164 1.67 itojun * that we do not own. Select a source address based on the 2165 1.55 itojun * source address of the erroneous packet. 2166 1.2 itojun */ 2167 1.138 dyoung /* zone ID should be embedded */ 2168 1.138 dyoung sockaddr_in6_init(&sin6, &ip6->ip6_dst, 0, 0, 0); 2169 1.113 rpaulo 2170 1.128 dyoung memset(&ro, 0, sizeof(ro)); 2171 1.200 ozaki e = in6_selectsrc(&sin6, NULL, NULL, &ro, NULL, NULL, NULL, 2172 1.200 ozaki &ip6->ip6_src); 2173 1.132 dyoung rtcache_free(&ro); 2174 1.200 ozaki if (e != 0) { 2175 1.205 ryo char ip6buf[INET6_ADDRSTRLEN]; 2176 1.180 ozaki nd6log(LOG_DEBUG, 2177 1.180 ozaki "source can't be determined: " 2178 1.55 itojun "dst=%s, error=%d\n", 2179 1.206 christos IN6_PRINT(ip6buf, &sin6.sin6_addr), e); 2180 1.55 itojun goto bad; 2181 1.55 itojun } 2182 1.55 itojun } 2183 1.2 itojun 2184 1.2 itojun ip6->ip6_flow = 0; 2185 1.13 itojun ip6->ip6_vfc &= ~IPV6_VERSION_MASK; 2186 1.13 itojun ip6->ip6_vfc |= IPV6_VERSION; 2187 1.2 itojun ip6->ip6_nxt = IPPROTO_ICMPV6; 2188 1.188 ozaki rcvif = m_get_rcvif(m, &s); 2189 1.188 ozaki if (rcvif) { 2190 1.2 itojun /* XXX: This may not be the outgoing interface */ 2191 1.188 ozaki ip6->ip6_hlim = ND_IFINFO(rcvif)->chlim; 2192 1.229 maxv } else { 2193 1.65 itojun ip6->ip6_hlim = ip6_defhlim; 2194 1.229 maxv } 2195 1.188 ozaki m_put_rcvif(rcvif, &s); 2196 1.2 itojun 2197 1.118 tron m->m_pkthdr.csum_flags = 0; 2198 1.2 itojun icmp6->icmp6_cksum = 0; 2199 1.2 itojun icmp6->icmp6_cksum = in6_cksum(m, IPPROTO_ICMPV6, 2200 1.229 maxv sizeof(struct ip6_hdr), plen); 2201 1.2 itojun 2202 1.2 itojun /* 2203 1.67 itojun * XXX option handling 2204 1.2 itojun */ 2205 1.2 itojun 2206 1.2 itojun m->m_flags &= ~(M_BCAST|M_MCAST); 2207 1.2 itojun 2208 1.73 itojun /* 2209 1.251 knakahar * Note for icmp6_reflect_pmtu == false 2210 1.73 itojun * To avoid a "too big" situation at an intermediate router 2211 1.73 itojun * and the path MTU discovery process, specify the IPV6_MINMTU flag. 2212 1.73 itojun * Note that only echo and node information replies are affected, 2213 1.73 itojun * since the length of ICMP6 errors is limited to the minimum MTU. 2214 1.73 itojun */ 2215 1.251 knakahar flags = icmp6_reflect_pmtu ? 0 : IPV6_MINMTU; 2216 1.251 knakahar if (ip6_output(m, NULL, NULL, flags, NULL, NULL, &outif) != 0 && 2217 1.229 maxv outif) 2218 1.72 itojun icmp6_ifstat_inc(outif, ifs6_out_error); 2219 1.12 itojun if (outif) 2220 1.12 itojun icmp6_ifoutstat_inc(outif, type, code); 2221 1.2 itojun 2222 1.2 itojun return; 2223 1.2 itojun 2224 1.2 itojun bad: 2225 1.2 itojun m_freem(m); 2226 1.2 itojun return; 2227 1.2 itojun } 2228 1.2 itojun 2229 1.12 itojun static const char * 2230 1.219 maxv icmp6_redirect_diag(char *buf, size_t buflen, struct in6_addr *src6, 2231 1.219 maxv struct in6_addr *dst6, struct in6_addr *tgt6) 2232 1.11 itojun { 2233 1.205 ryo char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN]; 2234 1.205 ryo char ip6buft[INET6_ADDRSTRLEN]; 2235 1.205 ryo 2236 1.205 ryo snprintf(buf, buflen, "(src=%s dst=%s tgt=%s)", 2237 1.206 christos IN6_PRINT(ip6bufs, src6), IN6_PRINT(ip6bufd, dst6), 2238 1.206 christos IN6_PRINT(ip6buft, tgt6)); 2239 1.12 itojun return buf; 2240 1.11 itojun } 2241 1.11 itojun 2242 1.219 maxv static void 2243 1.133 christos icmp6_redirect_input(struct mbuf *m, int off) 2244 1.2 itojun { 2245 1.188 ozaki struct ifnet *ifp; 2246 1.2 itojun struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 2247 1.23 itojun struct nd_redirect *nd_rd; 2248 1.230 maxv int icmp6len = m->m_pkthdr.len - off; 2249 1.2 itojun char *lladdr = NULL; 2250 1.2 itojun int lladdrlen = 0; 2251 1.2 itojun struct rtentry *rt = NULL; 2252 1.2 itojun int is_router; 2253 1.2 itojun int is_onlink; 2254 1.2 itojun struct in6_addr src6 = ip6->ip6_src; 2255 1.23 itojun struct in6_addr redtgt6; 2256 1.23 itojun struct in6_addr reddst6; 2257 1.2 itojun union nd_opts ndopts; 2258 1.188 ozaki struct psref psref; 2259 1.205 ryo char ip6buf[INET6_ADDRSTRLEN]; 2260 1.205 ryo char diagbuf[256]; 2261 1.2 itojun 2262 1.188 ozaki ifp = m_get_rcvif_psref(m, &psref); 2263 1.184 ozaki if (ifp == NULL) 2264 1.184 ozaki goto freeit; 2265 1.2 itojun 2266 1.2 itojun /* XXX if we are router, we don't update route by icmp6 redirect */ 2267 1.2 itojun if (ip6_forwarding) 2268 1.23 itojun goto freeit; 2269 1.2 itojun if (!icmp6_rediraccept) 2270 1.23 itojun goto freeit; 2271 1.2 itojun 2272 1.23 itojun IP6_EXTHDR_GET(nd_rd, struct nd_redirect *, m, off, icmp6len); 2273 1.23 itojun if (nd_rd == NULL) { 2274 1.145 thorpej ICMP6_STATINC(ICMP6_STAT_TOOSHORT); 2275 1.188 ozaki m_put_rcvif_psref(ifp, &psref); 2276 1.23 itojun return; 2277 1.23 itojun } 2278 1.23 itojun redtgt6 = nd_rd->nd_rd_target; 2279 1.23 itojun reddst6 = nd_rd->nd_rd_dst; 2280 1.25 itojun 2281 1.185 ozaki if (in6_setscope(&redtgt6, ifp, NULL) || 2282 1.185 ozaki in6_setscope(&reddst6, ifp, NULL)) { 2283 1.113 rpaulo goto freeit; 2284 1.113 rpaulo } 2285 1.23 itojun 2286 1.2 itojun /* validation */ 2287 1.2 itojun if (!IN6_IS_ADDR_LINKLOCAL(&src6)) { 2288 1.180 ozaki nd6log(LOG_ERR, 2289 1.180 ozaki "ICMP6 redirect sent from %s rejected; " 2290 1.206 christos "must be from linklocal\n", IN6_PRINT(ip6buf, &src6)); 2291 1.53 itojun goto bad; 2292 1.2 itojun } 2293 1.2 itojun if (ip6->ip6_hlim != 255) { 2294 1.180 ozaki nd6log(LOG_ERR, 2295 1.180 ozaki "ICMP6 redirect sent from %s rejected; " 2296 1.180 ozaki "hlim=%d (must be 255)\n", 2297 1.206 christos IN6_PRINT(ip6buf, &src6), ip6->ip6_hlim); 2298 1.53 itojun goto bad; 2299 1.2 itojun } 2300 1.219 maxv 2301 1.2 itojun { 2302 1.2 itojun /* ip6->ip6_src must be equal to gw for icmp6->icmp6_reddst */ 2303 1.2 itojun struct sockaddr_in6 sin6; 2304 1.2 itojun struct in6_addr *gw6; 2305 1.2 itojun 2306 1.138 dyoung sockaddr_in6_init(&sin6, &reddst6, 0, 0, 0); 2307 1.194 ozaki rt = rtalloc1(sin6tosa(&sin6), 0); 2308 1.2 itojun if (rt) { 2309 1.43 itojun if (rt->rt_gateway == NULL || 2310 1.43 itojun rt->rt_gateway->sa_family != AF_INET6) { 2311 1.180 ozaki nd6log(LOG_ERR, 2312 1.43 itojun "ICMP6 redirect rejected; no route " 2313 1.43 itojun "with inet6 gateway found for redirect dst: %s\n", 2314 1.205 ryo icmp6_redirect_diag(diagbuf, sizeof(diagbuf), 2315 1.205 ryo &src6, &reddst6, &redtgt6)); 2316 1.203 ozaki rt_unref(rt); 2317 1.53 itojun goto bad; 2318 1.43 itojun } 2319 1.43 itojun 2320 1.2 itojun gw6 = &(((struct sockaddr_in6 *)rt->rt_gateway)->sin6_addr); 2321 1.151 cegger if (memcmp(&src6, gw6, sizeof(struct in6_addr)) != 0) { 2322 1.180 ozaki nd6log(LOG_ERR, 2323 1.180 ozaki "ICMP6 redirect rejected; " 2324 1.180 ozaki "not equal to gw-for-src=%s (must be same): %s\n", 2325 1.206 christos IN6_PRINT(ip6buf, gw6), 2326 1.205 ryo icmp6_redirect_diag(diagbuf, sizeof(diagbuf), 2327 1.205 ryo &src6, &reddst6, &redtgt6)); 2328 1.203 ozaki rt_unref(rt); 2329 1.53 itojun goto bad; 2330 1.2 itojun } 2331 1.2 itojun } else { 2332 1.180 ozaki nd6log(LOG_ERR, "ICMP6 redirect rejected; " 2333 1.180 ozaki "no route found for redirect dst: %s\n", 2334 1.205 ryo icmp6_redirect_diag(diagbuf, sizeof(diagbuf), 2335 1.205 ryo &src6, &reddst6, &redtgt6)); 2336 1.53 itojun goto bad; 2337 1.2 itojun } 2338 1.203 ozaki rt_unref(rt); 2339 1.2 itojun rt = NULL; 2340 1.2 itojun } 2341 1.219 maxv 2342 1.2 itojun if (IN6_IS_ADDR_MULTICAST(&reddst6)) { 2343 1.180 ozaki nd6log(LOG_ERR, "ICMP6 redirect rejected; " 2344 1.180 ozaki "redirect dst must be unicast: %s\n", 2345 1.205 ryo icmp6_redirect_diag(diagbuf, sizeof(diagbuf), 2346 1.205 ryo &src6, &reddst6, &redtgt6)); 2347 1.53 itojun goto bad; 2348 1.2 itojun } 2349 1.2 itojun 2350 1.2 itojun is_router = is_onlink = 0; 2351 1.2 itojun if (IN6_IS_ADDR_LINKLOCAL(&redtgt6)) 2352 1.2 itojun is_router = 1; /* router case */ 2353 1.151 cegger if (memcmp(&redtgt6, &reddst6, sizeof(redtgt6)) == 0) 2354 1.2 itojun is_onlink = 1; /* on-link destination case */ 2355 1.2 itojun if (!is_router && !is_onlink) { 2356 1.180 ozaki nd6log(LOG_ERR, "ICMP6 redirect rejected; " 2357 1.180 ozaki "neither router case nor onlink case: %s\n", 2358 1.205 ryo icmp6_redirect_diag(diagbuf, sizeof(diagbuf), 2359 1.205 ryo &src6, &reddst6, &redtgt6)); 2360 1.53 itojun goto bad; 2361 1.2 itojun } 2362 1.2 itojun /* validation passed */ 2363 1.2 itojun 2364 1.2 itojun icmp6len -= sizeof(*nd_rd); 2365 1.2 itojun nd6_option_init(nd_rd + 1, icmp6len, &ndopts); 2366 1.2 itojun if (nd6_options(&ndopts) < 0) { 2367 1.180 ozaki nd6log(LOG_INFO, "invalid ND option, rejected: %s\n", 2368 1.205 ryo icmp6_redirect_diag(diagbuf, sizeof(diagbuf), 2369 1.205 ryo &src6, &reddst6, &redtgt6)); 2370 1.53 itojun /* nd6_options have incremented stats */ 2371 1.23 itojun goto freeit; 2372 1.2 itojun } 2373 1.2 itojun 2374 1.2 itojun if (ndopts.nd_opts_tgt_lladdr) { 2375 1.2 itojun lladdr = (char *)(ndopts.nd_opts_tgt_lladdr + 1); 2376 1.2 itojun lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3; 2377 1.2 itojun } 2378 1.2 itojun 2379 1.2 itojun if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { 2380 1.180 ozaki nd6log(LOG_INFO, "lladdrlen mismatch for %s " 2381 1.180 ozaki "(if %d, icmp6 packet %d): %s\n", 2382 1.206 christos IN6_PRINT(ip6buf, &redtgt6), 2383 1.205 ryo ifp->if_addrlen, lladdrlen - 2, 2384 1.205 ryo icmp6_redirect_diag(diagbuf, sizeof(diagbuf), 2385 1.205 ryo &src6, &reddst6, &redtgt6)); 2386 1.53 itojun goto bad; 2387 1.2 itojun } 2388 1.2 itojun 2389 1.2 itojun /* RFC 2461 8.3 */ 2390 1.10 itojun nd6_cache_lladdr(ifp, &redtgt6, lladdr, lladdrlen, ND_REDIRECT, 2391 1.229 maxv is_onlink ? ND_REDIRECT_ONLINK : ND_REDIRECT_ROUTER); 2392 1.2 itojun 2393 1.188 ozaki m_put_rcvif_psref(ifp, &psref); 2394 1.188 ozaki ifp = NULL; 2395 1.188 ozaki 2396 1.67 itojun if (!is_onlink) { /* better router case. perform rtredirect. */ 2397 1.2 itojun /* perform rtredirect */ 2398 1.2 itojun struct sockaddr_in6 sdst; 2399 1.2 itojun struct sockaddr_in6 sgw; 2400 1.2 itojun struct sockaddr_in6 ssrc; 2401 1.55 itojun unsigned long rtcount; 2402 1.55 itojun struct rtentry *newrt = NULL; 2403 1.55 itojun 2404 1.55 itojun /* 2405 1.55 itojun * do not install redirect route, if the number of entries 2406 1.55 itojun * is too much (> hiwat). note that, the node (= host) will 2407 1.55 itojun * work just fine even if we do not install redirect route 2408 1.55 itojun * (there will be additional hops, though). 2409 1.55 itojun */ 2410 1.209 ozaki mutex_enter(&icmp6_mtx); 2411 1.55 itojun rtcount = rt_timer_count(icmp6_redirect_timeout_q); 2412 1.209 ozaki if (0 <= ip6_maxdynroutes && rtcount >= ip6_maxdynroutes) { 2413 1.209 ozaki mutex_exit(&icmp6_mtx); 2414 1.161 christos goto freeit; 2415 1.209 ozaki } 2416 1.209 ozaki if (0 <= icmp6_redirect_hiwat && rtcount > icmp6_redirect_hiwat) { 2417 1.209 ozaki mutex_exit(&icmp6_mtx); 2418 1.184 ozaki goto freeit; 2419 1.209 ozaki } else if (0 <= icmp6_redirect_lowat && 2420 1.55 itojun rtcount > icmp6_redirect_lowat) { 2421 1.55 itojun /* 2422 1.55 itojun * XXX nuke a victim, install the new one. 2423 1.55 itojun */ 2424 1.55 itojun } 2425 1.2 itojun 2426 1.152 cegger memset(&sdst, 0, sizeof(sdst)); 2427 1.152 cegger memset(&sgw, 0, sizeof(sgw)); 2428 1.152 cegger memset(&ssrc, 0, sizeof(ssrc)); 2429 1.2 itojun sdst.sin6_family = sgw.sin6_family = ssrc.sin6_family = AF_INET6; 2430 1.2 itojun sdst.sin6_len = sgw.sin6_len = ssrc.sin6_len = 2431 1.229 maxv sizeof(struct sockaddr_in6); 2432 1.2 itojun bcopy(&redtgt6, &sgw.sin6_addr, sizeof(struct in6_addr)); 2433 1.2 itojun bcopy(&reddst6, &sdst.sin6_addr, sizeof(struct in6_addr)); 2434 1.2 itojun bcopy(&src6, &ssrc.sin6_addr, sizeof(struct in6_addr)); 2435 1.194 ozaki rtredirect(sin6tosa(&sdst), sin6tosa(&sgw), NULL, 2436 1.219 maxv RTF_GATEWAY | RTF_HOST, sin6tosa(&ssrc), &newrt); 2437 1.55 itojun 2438 1.55 itojun if (newrt) { 2439 1.55 itojun (void)rt_timer_add(newrt, icmp6_redirect_timeout, 2440 1.55 itojun icmp6_redirect_timeout_q); 2441 1.203 ozaki rt_unref(newrt); 2442 1.55 itojun } 2443 1.209 ozaki mutex_exit(&icmp6_mtx); 2444 1.2 itojun } 2445 1.2 itojun /* finally update cached route in each socket via pfctlinput */ 2446 1.74 itojun { 2447 1.74 itojun struct sockaddr_in6 sdst; 2448 1.2 itojun 2449 1.138 dyoung sockaddr_in6_init(&sdst, &reddst6, 0, 0, 0); 2450 1.194 ozaki pfctlinput(PRC_REDIRECT_HOST, sin6tosa(&sdst)); 2451 1.162 christos #if defined(IPSEC) 2452 1.168 christos if (ipsec_used) 2453 1.194 ozaki key_sa_routechange(sin6tosa(&sdst)); 2454 1.2 itojun #endif 2455 1.74 itojun } 2456 1.23 itojun 2457 1.219 maxv freeit: 2458 1.188 ozaki if (ifp != NULL) 2459 1.188 ozaki m_put_rcvif_psref(ifp, &psref); 2460 1.23 itojun m_freem(m); 2461 1.53 itojun return; 2462 1.53 itojun 2463 1.219 maxv bad: 2464 1.188 ozaki m_put_rcvif_psref(ifp, &psref); 2465 1.145 thorpej ICMP6_STATINC(ICMP6_STAT_BADREDIRECT); 2466 1.53 itojun m_freem(m); 2467 1.2 itojun } 2468 1.2 itojun 2469 1.2 itojun void 2470 1.133 christos icmp6_redirect_output(struct mbuf *m0, struct rtentry *rt) 2471 1.2 itojun { 2472 1.2 itojun struct ifnet *ifp; /* my outgoing interface */ 2473 1.2 itojun struct in6_addr *ifp_ll6; 2474 1.75 itojun struct in6_addr *nexthop; 2475 1.2 itojun struct ip6_hdr *sip6; /* m0 as struct ip6_hdr */ 2476 1.2 itojun struct mbuf *m = NULL; /* newly allocated one */ 2477 1.2 itojun struct ip6_hdr *ip6; /* m as struct ip6_hdr */ 2478 1.2 itojun struct nd_redirect *nd_rd; 2479 1.2 itojun size_t maxlen; 2480 1.2 itojun u_char *p; 2481 1.29 itojun struct sockaddr_in6 src_sa; 2482 1.2 itojun 2483 1.145 thorpej icmp6_errcount(ICMP6_STAT_OUTERRHIST, ND_REDIRECT, 0); 2484 1.35 itojun 2485 1.2 itojun /* if we are not router, we don't send icmp6 redirect */ 2486 1.94 itojun if (!ip6_forwarding) 2487 1.2 itojun goto fail; 2488 1.2 itojun 2489 1.2 itojun /* sanity check */ 2490 1.202 ozaki KASSERT(m0 != NULL); 2491 1.202 ozaki KASSERT(rt != NULL); 2492 1.202 ozaki 2493 1.202 ozaki ifp = rt->rt_ifp; 2494 1.5 itojun 2495 1.5 itojun /* 2496 1.5 itojun * Address check: 2497 1.5 itojun * the source address must identify a neighbor, and 2498 1.5 itojun * the destination address must not be a multicast address 2499 1.5 itojun * [RFC 2461, sec 8.2] 2500 1.5 itojun */ 2501 1.2 itojun sip6 = mtod(m0, struct ip6_hdr *); 2502 1.138 dyoung sockaddr_in6_init(&src_sa, &sip6->ip6_src, 0, 0, 0); 2503 1.29 itojun if (nd6_is_addr_neighbor(&src_sa, ifp) == 0) 2504 1.5 itojun goto fail; 2505 1.2 itojun if (IN6_IS_ADDR_MULTICAST(&sip6->ip6_dst)) 2506 1.2 itojun goto fail; /* what should we do here? */ 2507 1.2 itojun 2508 1.2 itojun /* rate limit */ 2509 1.2 itojun if (icmp6_ratelimit(&sip6->ip6_src, ND_REDIRECT, 0)) 2510 1.2 itojun goto fail; 2511 1.2 itojun 2512 1.2 itojun /* 2513 1.2 itojun * Since we are going to append up to 1280 bytes (= IPV6_MMTU), 2514 1.2 itojun * we almost always ask for an mbuf cluster for simplicity. 2515 1.2 itojun * (MHLEN < IPV6_MMTU is almost always true) 2516 1.2 itojun */ 2517 1.154 christos MGETHDR(m, M_DONTWAIT, MT_HEADER); 2518 1.154 christos if (m && IPV6_MMTU >= MHLEN) { 2519 1.23 itojun #if IPV6_MMTU >= MCLBYTES 2520 1.233 maxv MEXTMALLOC(m, IPV6_MMTU, M_NOWAIT); 2521 1.154 christos #else 2522 1.154 christos MCLGET(m, M_DONTWAIT); 2523 1.23 itojun #endif 2524 1.154 christos } 2525 1.154 christos 2526 1.2 itojun if (!m) 2527 1.2 itojun goto fail; 2528 1.187 ozaki m_reset_rcvif(m); 2529 1.42 itojun m->m_len = 0; 2530 1.42 itojun maxlen = M_TRAILINGSPACE(m); 2531 1.239 riastrad maxlen = uimin(IPV6_MMTU, maxlen); 2532 1.218 maxv 2533 1.2 itojun /* just for safety */ 2534 1.218 maxv if (maxlen < sizeof(struct ip6_hdr) + sizeof(struct nd_redirect) + 2535 1.23 itojun ((sizeof(struct nd_opt_hdr) + ifp->if_addrlen + 7) & ~7)) { 2536 1.2 itojun goto fail; 2537 1.23 itojun } 2538 1.2 itojun 2539 1.2 itojun { 2540 1.2 itojun /* get ip6 linklocal address for ifp(my outgoing interface). */ 2541 1.23 itojun struct in6_ifaddr *ia; 2542 1.195 ozaki int s = pserialize_read_enter(); 2543 1.23 itojun if ((ia = in6ifa_ifpforlinklocal(ifp, 2544 1.23 itojun IN6_IFF_NOTREADY| 2545 1.195 ozaki IN6_IFF_ANYCAST)) == NULL) { 2546 1.195 ozaki pserialize_read_exit(s); 2547 1.2 itojun goto fail; 2548 1.195 ozaki } 2549 1.2 itojun ifp_ll6 = &ia->ia_addr.sin6_addr; 2550 1.195 ozaki pserialize_read_exit(s); 2551 1.2 itojun } 2552 1.2 itojun 2553 1.2 itojun /* get ip6 linklocal address for the router. */ 2554 1.2 itojun if (rt->rt_gateway && (rt->rt_flags & RTF_GATEWAY)) { 2555 1.2 itojun struct sockaddr_in6 *sin6; 2556 1.2 itojun sin6 = (struct sockaddr_in6 *)rt->rt_gateway; 2557 1.75 itojun nexthop = &sin6->sin6_addr; 2558 1.75 itojun if (!IN6_IS_ADDR_LINKLOCAL(nexthop)) 2559 1.75 itojun nexthop = NULL; 2560 1.2 itojun } else 2561 1.75 itojun nexthop = NULL; 2562 1.2 itojun 2563 1.2 itojun /* ip6 */ 2564 1.2 itojun ip6 = mtod(m, struct ip6_hdr *); 2565 1.2 itojun ip6->ip6_flow = 0; 2566 1.13 itojun ip6->ip6_vfc &= ~IPV6_VERSION_MASK; 2567 1.13 itojun ip6->ip6_vfc |= IPV6_VERSION; 2568 1.2 itojun /* ip6->ip6_plen will be set later */ 2569 1.2 itojun ip6->ip6_nxt = IPPROTO_ICMPV6; 2570 1.2 itojun ip6->ip6_hlim = 255; 2571 1.2 itojun /* ip6->ip6_src must be linklocal addr for my outgoing if. */ 2572 1.2 itojun bcopy(ifp_ll6, &ip6->ip6_src, sizeof(struct in6_addr)); 2573 1.2 itojun bcopy(&sip6->ip6_src, &ip6->ip6_dst, sizeof(struct in6_addr)); 2574 1.2 itojun 2575 1.2 itojun /* ND Redirect */ 2576 1.2 itojun nd_rd = (struct nd_redirect *)(ip6 + 1); 2577 1.2 itojun nd_rd->nd_rd_type = ND_REDIRECT; 2578 1.2 itojun nd_rd->nd_rd_code = 0; 2579 1.2 itojun nd_rd->nd_rd_reserved = 0; 2580 1.2 itojun if (rt->rt_flags & RTF_GATEWAY) { 2581 1.2 itojun /* 2582 1.2 itojun * nd_rd->nd_rd_target must be a link-local address in 2583 1.2 itojun * better router cases. 2584 1.2 itojun */ 2585 1.75 itojun if (!nexthop) 2586 1.2 itojun goto fail; 2587 1.75 itojun bcopy(nexthop, &nd_rd->nd_rd_target, 2588 1.2 itojun sizeof(nd_rd->nd_rd_target)); 2589 1.2 itojun bcopy(&sip6->ip6_dst, &nd_rd->nd_rd_dst, 2590 1.2 itojun sizeof(nd_rd->nd_rd_dst)); 2591 1.2 itojun } else { 2592 1.2 itojun /* make sure redtgt == reddst */ 2593 1.75 itojun nexthop = &sip6->ip6_dst; 2594 1.2 itojun bcopy(&sip6->ip6_dst, &nd_rd->nd_rd_target, 2595 1.2 itojun sizeof(nd_rd->nd_rd_target)); 2596 1.2 itojun bcopy(&sip6->ip6_dst, &nd_rd->nd_rd_dst, 2597 1.2 itojun sizeof(nd_rd->nd_rd_dst)); 2598 1.2 itojun } 2599 1.2 itojun 2600 1.2 itojun p = (u_char *)(nd_rd + 1); 2601 1.2 itojun 2602 1.75 itojun { 2603 1.75 itojun /* target lladdr option */ 2604 1.182 ozaki struct llentry *ln = NULL; 2605 1.217 maxv int len, pad; 2606 1.75 itojun struct nd_opt_hdr *nd_opt; 2607 1.75 itojun char *lladdr; 2608 1.75 itojun 2609 1.182 ozaki ln = nd6_lookup(nexthop, ifp, false); 2610 1.182 ozaki if (ln == NULL) 2611 1.75 itojun goto nolladdropt; 2612 1.75 itojun len = sizeof(*nd_opt) + ifp->if_addrlen; 2613 1.75 itojun len = (len + 7) & ~7; /* round by 8 */ 2614 1.217 maxv pad = len - (sizeof(*nd_opt) + ifp->if_addrlen); 2615 1.217 maxv 2616 1.75 itojun /* safety check */ 2617 1.171 ozaki if (len + (p - (u_char *)ip6) > maxlen) { 2618 1.182 ozaki LLE_RUNLOCK(ln); 2619 1.75 itojun goto nolladdropt; 2620 1.171 ozaki } 2621 1.217 maxv 2622 1.182 ozaki if (ln->la_flags & LLE_VALID) { 2623 1.75 itojun nd_opt = (struct nd_opt_hdr *)p; 2624 1.75 itojun nd_opt->nd_opt_type = ND_OPT_TARGET_LINKADDR; 2625 1.75 itojun nd_opt->nd_opt_len = len >> 3; 2626 1.75 itojun lladdr = (char *)(nd_opt + 1); 2627 1.182 ozaki memcpy(lladdr, &ln->ll_addr, ifp->if_addrlen); 2628 1.217 maxv memset(lladdr + ifp->if_addrlen, 0, pad); 2629 1.75 itojun p += len; 2630 1.75 itojun } 2631 1.182 ozaki LLE_RUNLOCK(ln); 2632 1.2 itojun } 2633 1.219 maxv nolladdropt: 2634 1.2 itojun 2635 1.2 itojun m->m_pkthdr.len = m->m_len = p - (u_char *)ip6; 2636 1.2 itojun 2637 1.2 itojun /* just to be safe */ 2638 1.2 itojun if (m0->m_flags & M_DECRYPTED) 2639 1.2 itojun goto noredhdropt; 2640 1.23 itojun if (p - (u_char *)ip6 > maxlen) 2641 1.23 itojun goto noredhdropt; 2642 1.2 itojun 2643 1.91 itojun { 2644 1.91 itojun /* redirected header option */ 2645 1.91 itojun int len; 2646 1.91 itojun struct nd_opt_rd_hdr *nd_opt_rh; 2647 1.2 itojun 2648 1.91 itojun /* 2649 1.91 itojun * compute the maximum size for icmp6 redirect header option. 2650 1.91 itojun * XXX room for auth header? 2651 1.91 itojun */ 2652 1.91 itojun len = maxlen - (p - (u_char *)ip6); 2653 1.91 itojun len &= ~7; 2654 1.2 itojun 2655 1.218 maxv if (len < sizeof(*nd_opt_rh)) { 2656 1.218 maxv goto noredhdropt; 2657 1.218 maxv } 2658 1.218 maxv 2659 1.91 itojun /* 2660 1.91 itojun * Redirected header option spec (RFC2461 4.6.3) talks nothing 2661 1.91 itojun * about padding/truncate rule for the original IP packet. 2662 1.91 itojun * From the discussion on IPv6imp in Feb 1999, 2663 1.91 itojun * the consensus was: 2664 1.91 itojun * - "attach as much as possible" is the goal 2665 1.91 itojun * - pad if not aligned (original size can be guessed by 2666 1.91 itojun * original ip6 header) 2667 1.91 itojun * Following code adds the padding if it is simple enough, 2668 1.91 itojun * and truncates if not. 2669 1.91 itojun */ 2670 1.91 itojun if (len - sizeof(*nd_opt_rh) < m0->m_pkthdr.len) { 2671 1.91 itojun /* not enough room, truncate */ 2672 1.91 itojun m_adj(m0, (len - sizeof(*nd_opt_rh)) - 2673 1.91 itojun m0->m_pkthdr.len); 2674 1.91 itojun } else { 2675 1.91 itojun /* 2676 1.115 rpaulo * enough room, truncate if not aligned. 2677 1.91 itojun * we don't pad here for simplicity. 2678 1.91 itojun */ 2679 1.219 maxv int extra; 2680 1.2 itojun 2681 1.91 itojun extra = m0->m_pkthdr.len % 8; 2682 1.91 itojun if (extra) { 2683 1.2 itojun /* truncate */ 2684 1.91 itojun m_adj(m0, -extra); 2685 1.2 itojun } 2686 1.91 itojun len = m0->m_pkthdr.len + sizeof(*nd_opt_rh); 2687 1.2 itojun } 2688 1.91 itojun 2689 1.91 itojun nd_opt_rh = (struct nd_opt_rd_hdr *)p; 2690 1.152 cegger memset(nd_opt_rh, 0, sizeof(*nd_opt_rh)); 2691 1.91 itojun nd_opt_rh->nd_opt_rh_type = ND_OPT_REDIRECTED_HEADER; 2692 1.91 itojun nd_opt_rh->nd_opt_rh_len = len >> 3; 2693 1.91 itojun p += sizeof(*nd_opt_rh); 2694 1.91 itojun m->m_pkthdr.len = m->m_len = p - (u_char *)ip6; 2695 1.91 itojun 2696 1.91 itojun /* connect m0 to m */ 2697 1.95 itojun m->m_pkthdr.len += m0->m_pkthdr.len; 2698 1.91 itojun m_cat(m, m0); 2699 1.91 itojun m0 = NULL; 2700 1.2 itojun } 2701 1.91 itojun noredhdropt: 2702 1.258 rin m_freem(m0); 2703 1.258 rin m0 = NULL; 2704 1.2 itojun 2705 1.113 rpaulo /* XXX: clear embedded link IDs in the inner header */ 2706 1.113 rpaulo in6_clearscope(&sip6->ip6_src); 2707 1.113 rpaulo in6_clearscope(&sip6->ip6_dst); 2708 1.113 rpaulo in6_clearscope(&nd_rd->nd_rd_target); 2709 1.113 rpaulo in6_clearscope(&nd_rd->nd_rd_dst); 2710 1.2 itojun 2711 1.2 itojun ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr)); 2712 1.2 itojun 2713 1.2 itojun nd_rd->nd_rd_cksum = 0; 2714 1.219 maxv nd_rd->nd_rd_cksum = 2715 1.219 maxv in6_cksum(m, IPPROTO_ICMPV6, sizeof(*ip6), ntohs(ip6->ip6_plen)); 2716 1.2 itojun 2717 1.2 itojun /* send the packet to outside... */ 2718 1.157 plunky if (ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL) != 0) 2719 1.72 itojun icmp6_ifstat_inc(ifp, ifs6_out_error); 2720 1.72 itojun 2721 1.68 itojun icmp6_ifstat_inc(ifp, ifs6_out_msg); 2722 1.68 itojun icmp6_ifstat_inc(ifp, ifs6_out_redirect); 2723 1.145 thorpej ICMP6_STATINC(ICMP6_STAT_OUTHIST + ND_REDIRECT); 2724 1.2 itojun 2725 1.2 itojun return; 2726 1.2 itojun 2727 1.2 itojun fail: 2728 1.258 rin m_freem(m); 2729 1.258 rin m_freem(m0); 2730 1.2 itojun } 2731 1.2 itojun 2732 1.2 itojun /* 2733 1.2 itojun * ICMPv6 socket option processing. 2734 1.2 itojun */ 2735 1.2 itojun int 2736 1.149 plunky icmp6_ctloutput(int op, struct socket *so, struct sockopt *sopt) 2737 1.2 itojun { 2738 1.2 itojun int error = 0; 2739 1.253 ozaki struct inpcb *inp = sotoinpcb(so); 2740 1.2 itojun 2741 1.149 plunky if (sopt->sopt_level != IPPROTO_ICMPV6) 2742 1.149 plunky return rip6_ctloutput(op, so, sopt); 2743 1.56 itojun 2744 1.56 itojun switch (op) { 2745 1.56 itojun case PRCO_SETOPT: 2746 1.149 plunky switch (sopt->sopt_name) { 2747 1.56 itojun case ICMP6_FILTER: 2748 1.56 itojun { 2749 1.149 plunky struct icmp6_filter fil; 2750 1.56 itojun 2751 1.149 plunky error = sockopt_get(sopt, &fil, sizeof(fil)); 2752 1.149 plunky if (error) 2753 1.56 itojun break; 2754 1.254 ozaki memcpy(in6p_icmp6filt(inp), &fil, 2755 1.149 plunky sizeof(struct icmp6_filter)); 2756 1.56 itojun error = 0; 2757 1.56 itojun break; 2758 1.56 itojun } 2759 1.56 itojun 2760 1.56 itojun default: 2761 1.56 itojun error = ENOPROTOOPT; 2762 1.56 itojun break; 2763 1.56 itojun } 2764 1.56 itojun break; 2765 1.56 itojun 2766 1.56 itojun case PRCO_GETOPT: 2767 1.149 plunky switch (sopt->sopt_name) { 2768 1.56 itojun case ICMP6_FILTER: 2769 1.56 itojun { 2770 1.254 ozaki if (in6p_icmp6filt(inp) == NULL) { 2771 1.56 itojun error = EINVAL; 2772 1.56 itojun break; 2773 1.56 itojun } 2774 1.254 ozaki error = sockopt_set(sopt, in6p_icmp6filt(inp), 2775 1.149 plunky sizeof(struct icmp6_filter)); 2776 1.56 itojun break; 2777 1.56 itojun } 2778 1.56 itojun 2779 1.56 itojun default: 2780 1.56 itojun error = ENOPROTOOPT; 2781 1.56 itojun break; 2782 1.56 itojun } 2783 1.56 itojun break; 2784 1.2 itojun } 2785 1.2 itojun 2786 1.229 maxv return error; 2787 1.2 itojun } 2788 1.2 itojun 2789 1.2 itojun /* 2790 1.2 itojun * Perform rate limit check. 2791 1.2 itojun * Returns 0 if it is okay to send the icmp6 packet. 2792 1.2 itojun * Returns 1 if the router SHOULD NOT send this icmp6 packet due to rate 2793 1.2 itojun * limitation. 2794 1.35 itojun * 2795 1.2 itojun * XXX per-destination/type check necessary? 2796 1.2 itojun */ 2797 1.2 itojun static int 2798 1.122 christos icmp6_ratelimit( 2799 1.123 christos const struct in6_addr *dst, /* not used at this moment */ 2800 1.123 christos const int type, /* not used at this moment */ 2801 1.123 christos const int code) /* not used at this moment */ 2802 1.2 itojun { 2803 1.35 itojun int ret; 2804 1.35 itojun 2805 1.67 itojun ret = 0; /* okay to send */ 2806 1.2 itojun 2807 1.35 itojun /* PPS limit */ 2808 1.37 itojun if (!ppsratecheck(&icmp6errppslim_last, &icmp6errpps_count, 2809 1.37 itojun icmp6errppslim)) { 2810 1.37 itojun /* The packet is subject to rate limit */ 2811 1.35 itojun ret++; 2812 1.35 itojun } 2813 1.35 itojun 2814 1.35 itojun return ret; 2815 1.2 itojun } 2816 1.8 itojun 2817 1.8 itojun static struct rtentry * 2818 1.133 christos icmp6_mtudisc_clone(struct sockaddr *dst) 2819 1.8 itojun { 2820 1.8 itojun struct rtentry *rt; 2821 1.8 itojun int error; 2822 1.8 itojun 2823 1.8 itojun rt = rtalloc1(dst, 1); 2824 1.229 maxv if (rt == NULL) 2825 1.8 itojun return NULL; 2826 1.29 itojun 2827 1.8 itojun /* If we didn't get a host route, allocate one */ 2828 1.8 itojun if ((rt->rt_flags & RTF_HOST) == 0) { 2829 1.8 itojun struct rtentry *nrt; 2830 1.8 itojun 2831 1.181 ozaki error = rtrequest(RTM_ADD, dst, rt->rt_gateway, NULL, 2832 1.8 itojun RTF_GATEWAY | RTF_HOST | RTF_DYNAMIC, &nrt); 2833 1.8 itojun if (error) { 2834 1.203 ozaki rt_unref(rt); 2835 1.8 itojun return NULL; 2836 1.8 itojun } 2837 1.8 itojun nrt->rt_rmx = rt->rt_rmx; 2838 1.252 knakahar rt_newmsg_dynamic(RTM_ADD, nrt); 2839 1.203 ozaki rt_unref(rt); 2840 1.8 itojun rt = nrt; 2841 1.8 itojun } 2842 1.209 ozaki 2843 1.209 ozaki mutex_enter(&icmp6_mtx); 2844 1.8 itojun error = rt_timer_add(rt, icmp6_mtudisc_timeout, 2845 1.8 itojun icmp6_mtudisc_timeout_q); 2846 1.209 ozaki mutex_exit(&icmp6_mtx); 2847 1.209 ozaki 2848 1.8 itojun if (error) { 2849 1.203 ozaki rt_unref(rt); 2850 1.8 itojun return NULL; 2851 1.8 itojun } 2852 1.8 itojun 2853 1.8 itojun return rt; /* caller need to call rtfree() */ 2854 1.8 itojun } 2855 1.8 itojun 2856 1.8 itojun static void 2857 1.123 christos icmp6_mtudisc_timeout(struct rtentry *rt, struct rttimer *r) 2858 1.8 itojun { 2859 1.238 ozaki struct rtentry *retrt; 2860 1.176 ozaki 2861 1.176 ozaki KASSERT(rt != NULL); 2862 1.176 ozaki rt_assert_referenced(rt); 2863 1.176 ozaki 2864 1.29 itojun if ((rt->rt_flags & (RTF_DYNAMIC | RTF_HOST)) == 2865 1.8 itojun (RTF_DYNAMIC | RTF_HOST)) { 2866 1.181 ozaki rtrequest(RTM_DELETE, rt_getkey(rt), 2867 1.238 ozaki rt->rt_gateway, rt_mask(rt), rt->rt_flags, &retrt); 2868 1.252 knakahar rt_newmsg_dynamic(RTM_DELETE, retrt); 2869 1.238 ozaki rt_unref(rt); 2870 1.238 ozaki rt_free(retrt); 2871 1.8 itojun } else { 2872 1.78 itojun if (!(rt->rt_rmx.rmx_locks & RTV_MTU)) 2873 1.78 itojun rt->rt_rmx.rmx_mtu = 0; 2874 1.55 itojun } 2875 1.55 itojun } 2876 1.55 itojun 2877 1.55 itojun static void 2878 1.123 christos icmp6_redirect_timeout(struct rtentry *rt, struct rttimer *r) 2879 1.55 itojun { 2880 1.238 ozaki struct rtentry *retrt; 2881 1.176 ozaki 2882 1.176 ozaki KASSERT(rt != NULL); 2883 1.176 ozaki rt_assert_referenced(rt); 2884 1.176 ozaki 2885 1.55 itojun if ((rt->rt_flags & (RTF_GATEWAY | RTF_DYNAMIC | RTF_HOST)) == 2886 1.55 itojun (RTF_GATEWAY | RTF_DYNAMIC | RTF_HOST)) { 2887 1.181 ozaki rtrequest(RTM_DELETE, rt_getkey(rt), 2888 1.238 ozaki rt->rt_gateway, rt_mask(rt), rt->rt_flags, &retrt); 2889 1.252 knakahar rt_newmsg_dynamic(RTM_DELETE, retrt); 2890 1.238 ozaki rt_unref(rt); 2891 1.238 ozaki rt_free(retrt); 2892 1.8 itojun } 2893 1.8 itojun } 2894 1.34 mrg 2895 1.145 thorpej static int 2896 1.145 thorpej sysctl_net_inet6_icmp6_stats(SYSCTLFN_ARGS) 2897 1.145 thorpej { 2898 1.145 thorpej 2899 1.147 thorpej return (NETSTAT_SYSCTL(icmp6stat_percpu, ICMP6_NSTATS)); 2900 1.145 thorpej } 2901 1.145 thorpej 2902 1.177 ozaki static int 2903 1.177 ozaki sysctl_net_inet6_icmp6_redirtimeout(SYSCTLFN_ARGS) 2904 1.177 ozaki { 2905 1.177 ozaki int error, tmp; 2906 1.177 ozaki struct sysctlnode node; 2907 1.177 ozaki 2908 1.209 ozaki mutex_enter(&icmp6_mtx); 2909 1.209 ozaki 2910 1.177 ozaki node = *rnode; 2911 1.177 ozaki node.sysctl_data = &tmp; 2912 1.177 ozaki tmp = icmp6_redirtimeout; 2913 1.177 ozaki error = sysctl_lookup(SYSCTLFN_CALL(&node)); 2914 1.177 ozaki if (error || newp == NULL) 2915 1.209 ozaki goto out; 2916 1.209 ozaki if (tmp < 0) { 2917 1.209 ozaki error = EINVAL; 2918 1.209 ozaki goto out; 2919 1.209 ozaki } 2920 1.177 ozaki icmp6_redirtimeout = tmp; 2921 1.177 ozaki 2922 1.177 ozaki if (icmp6_redirect_timeout_q != NULL) { 2923 1.177 ozaki if (icmp6_redirtimeout == 0) { 2924 1.199 ozaki rt_timer_queue_destroy(icmp6_redirect_timeout_q); 2925 1.177 ozaki } else { 2926 1.177 ozaki rt_timer_queue_change(icmp6_redirect_timeout_q, 2927 1.177 ozaki icmp6_redirtimeout); 2928 1.177 ozaki } 2929 1.177 ozaki } else if (icmp6_redirtimeout > 0) { 2930 1.177 ozaki icmp6_redirect_timeout_q = 2931 1.177 ozaki rt_timer_queue_create(icmp6_redirtimeout); 2932 1.177 ozaki } 2933 1.209 ozaki error = 0; 2934 1.209 ozaki out: 2935 1.209 ozaki mutex_exit(&icmp6_mtx); 2936 1.209 ozaki return error; 2937 1.177 ozaki } 2938 1.177 ozaki 2939 1.153 pooka static void 2940 1.153 pooka sysctl_net_inet6_icmp6_setup(struct sysctllog **clog) 2941 1.103 atatat { 2942 1.2 itojun 2943 1.105 atatat sysctl_createv(clog, 0, NULL, NULL, 2944 1.105 atatat CTLFLAG_PERMANENT, 2945 1.103 atatat CTLTYPE_NODE, "inet6", NULL, 2946 1.103 atatat NULL, 0, NULL, 0, 2947 1.103 atatat CTL_NET, PF_INET6, CTL_EOL); 2948 1.105 atatat sysctl_createv(clog, 0, NULL, NULL, 2949 1.105 atatat CTLFLAG_PERMANENT, 2950 1.107 atatat CTLTYPE_NODE, "icmp6", 2951 1.107 atatat SYSCTL_DESCR("ICMPv6 related settings"), 2952 1.103 atatat NULL, 0, NULL, 0, 2953 1.103 atatat CTL_NET, PF_INET6, IPPROTO_ICMPV6, CTL_EOL); 2954 1.103 atatat 2955 1.105 atatat sysctl_createv(clog, 0, NULL, NULL, 2956 1.105 atatat CTLFLAG_PERMANENT, 2957 1.107 atatat CTLTYPE_STRUCT, "stats", 2958 1.107 atatat SYSCTL_DESCR("ICMPv6 transmission statistics"), 2959 1.145 thorpej sysctl_net_inet6_icmp6_stats, 0, NULL, 0, 2960 1.103 atatat CTL_NET, PF_INET6, IPPROTO_ICMPV6, 2961 1.103 atatat ICMPV6CTL_STATS, CTL_EOL); 2962 1.105 atatat sysctl_createv(clog, 0, NULL, NULL, 2963 1.105 atatat CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2964 1.107 atatat CTLTYPE_INT, "rediraccept", 2965 1.107 atatat SYSCTL_DESCR("Accept and process redirect messages"), 2966 1.103 atatat NULL, 0, &icmp6_rediraccept, 0, 2967 1.103 atatat CTL_NET, PF_INET6, IPPROTO_ICMPV6, 2968 1.103 atatat ICMPV6CTL_REDIRACCEPT, CTL_EOL); 2969 1.105 atatat sysctl_createv(clog, 0, NULL, NULL, 2970 1.105 atatat CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2971 1.107 atatat CTLTYPE_INT, "redirtimeout", 2972 1.107 atatat SYSCTL_DESCR("Redirect generated route lifetime"), 2973 1.177 ozaki sysctl_net_inet6_icmp6_redirtimeout, 0, 2974 1.177 ozaki &icmp6_redirtimeout, 0, 2975 1.103 atatat CTL_NET, PF_INET6, IPPROTO_ICMPV6, 2976 1.103 atatat ICMPV6CTL_REDIRTIMEOUT, CTL_EOL); 2977 1.103 atatat #if 0 /* obsoleted */ 2978 1.105 atatat sysctl_createv(clog, 0, NULL, NULL, 2979 1.105 atatat CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2980 1.103 atatat CTLTYPE_INT, "errratelimit", NULL, 2981 1.103 atatat NULL, 0, &icmp6_errratelimit, 0, 2982 1.103 atatat CTL_NET, PF_INET6, IPPROTO_ICMPV6, 2983 1.103 atatat ICMPV6CTL_ERRRATELIMIT, CTL_EOL); 2984 1.103 atatat #endif 2985 1.105 atatat sysctl_createv(clog, 0, NULL, NULL, 2986 1.105 atatat CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2987 1.107 atatat CTLTYPE_INT, "nd6_prune", 2988 1.107 atatat SYSCTL_DESCR("Neighbor discovery prune interval"), 2989 1.103 atatat NULL, 0, &nd6_prune, 0, 2990 1.103 atatat CTL_NET, PF_INET6, IPPROTO_ICMPV6, 2991 1.103 atatat ICMPV6CTL_ND6_PRUNE, CTL_EOL); 2992 1.105 atatat sysctl_createv(clog, 0, NULL, NULL, 2993 1.105 atatat CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2994 1.107 atatat CTLTYPE_INT, "nd6_delay", 2995 1.107 atatat SYSCTL_DESCR("First probe delay time"), 2996 1.247 roy NULL, 0, &nd6_nd_domain.nd_delay, 0, 2997 1.103 atatat CTL_NET, PF_INET6, IPPROTO_ICMPV6, 2998 1.103 atatat ICMPV6CTL_ND6_DELAY, CTL_EOL); 2999 1.105 atatat sysctl_createv(clog, 0, NULL, NULL, 3000 1.105 atatat CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 3001 1.247 roy CTLTYPE_INT, "nd6_mmaxtries", 3002 1.247 roy SYSCTL_DESCR("Number of multicast discovery attempts"), 3003 1.247 roy NULL, 0, &nd6_nd_domain.nd_mmaxtries, 0, 3004 1.247 roy CTL_NET, PF_INET6, IPPROTO_ICMPV6, 3005 1.247 roy ICMPV6CTL_ND6_MMAXTRIES, CTL_EOL); 3006 1.247 roy sysctl_createv(clog, 0, NULL, NULL, 3007 1.247 roy CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 3008 1.107 atatat CTLTYPE_INT, "nd6_umaxtries", 3009 1.107 atatat SYSCTL_DESCR("Number of unicast discovery attempts"), 3010 1.247 roy NULL, 0, &nd6_nd_domain.nd_umaxtries, 0, 3011 1.103 atatat CTL_NET, PF_INET6, IPPROTO_ICMPV6, 3012 1.103 atatat ICMPV6CTL_ND6_UMAXTRIES, CTL_EOL); 3013 1.105 atatat sysctl_createv(clog, 0, NULL, NULL, 3014 1.105 atatat CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 3015 1.247 roy CTLTYPE_INT, "nd6_maxnudhint", 3016 1.247 roy SYSCTL_DESCR("Maximum neighbor unreachable hint count"), 3017 1.247 roy NULL, 0, &nd6_nd_domain.nd_maxnudhint, 0, 3018 1.247 roy CTL_NET, PF_INET6, IPPROTO_ICMPV6, 3019 1.247 roy ICMPV6CTL_ND6_MAXNUDHINT, CTL_EOL); 3020 1.247 roy sysctl_createv(clog, 0, NULL, NULL, 3021 1.247 roy CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 3022 1.247 roy CTLTYPE_INT, "maxqueuelen", 3023 1.247 roy SYSCTL_DESCR("max packet queue len for a unresolved ND"), 3024 1.247 roy NULL, 1, &nd6_nd_domain.nd_maxqueuelen, 0, 3025 1.103 atatat CTL_NET, PF_INET6, IPPROTO_ICMPV6, 3026 1.247 roy ICMPV6CTL_ND6_MAXQLEN, CTL_EOL); 3027 1.105 atatat sysctl_createv(clog, 0, NULL, NULL, 3028 1.105 atatat CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 3029 1.107 atatat CTLTYPE_INT, "nd6_useloopback", 3030 1.107 atatat SYSCTL_DESCR("Use loopback interface for local traffic"), 3031 1.103 atatat NULL, 0, &nd6_useloopback, 0, 3032 1.103 atatat CTL_NET, PF_INET6, IPPROTO_ICMPV6, 3033 1.103 atatat ICMPV6CTL_ND6_USELOOPBACK, CTL_EOL); 3034 1.103 atatat #if 0 /* obsoleted */ 3035 1.105 atatat sysctl_createv(clog, 0, NULL, NULL, 3036 1.105 atatat CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 3037 1.103 atatat CTLTYPE_INT, "nd6_proxyall", NULL, 3038 1.103 atatat NULL, 0, &nd6_proxyall, 0, 3039 1.103 atatat CTL_NET, PF_INET6, IPPROTO_ICMPV6, 3040 1.103 atatat ICMPV6CTL_ND6_PROXYALL, CTL_EOL); 3041 1.103 atatat #endif 3042 1.105 atatat sysctl_createv(clog, 0, NULL, NULL, 3043 1.105 atatat CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 3044 1.107 atatat CTLTYPE_INT, "nodeinfo", 3045 1.107 atatat SYSCTL_DESCR("Respond to node information requests"), 3046 1.103 atatat NULL, 0, &icmp6_nodeinfo, 0, 3047 1.103 atatat CTL_NET, PF_INET6, IPPROTO_ICMPV6, 3048 1.103 atatat ICMPV6CTL_NODEINFO, CTL_EOL); 3049 1.105 atatat sysctl_createv(clog, 0, NULL, NULL, 3050 1.105 atatat CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 3051 1.107 atatat CTLTYPE_INT, "errppslimit", 3052 1.107 atatat SYSCTL_DESCR("Maximum ICMP errors sent per second"), 3053 1.103 atatat NULL, 0, &icmp6errppslim, 0, 3054 1.103 atatat CTL_NET, PF_INET6, IPPROTO_ICMPV6, 3055 1.103 atatat ICMPV6CTL_ERRPPSLIMIT, CTL_EOL); 3056 1.105 atatat sysctl_createv(clog, 0, NULL, NULL, 3057 1.105 atatat CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 3058 1.107 atatat CTLTYPE_INT, "mtudisc_hiwat", 3059 1.107 atatat SYSCTL_DESCR("Low mark on MTU Discovery route timers"), 3060 1.103 atatat NULL, 0, &icmp6_mtudisc_hiwat, 0, 3061 1.103 atatat CTL_NET, PF_INET6, IPPROTO_ICMPV6, 3062 1.103 atatat ICMPV6CTL_MTUDISC_HIWAT, CTL_EOL); 3063 1.105 atatat sysctl_createv(clog, 0, NULL, NULL, 3064 1.105 atatat CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 3065 1.107 atatat CTLTYPE_INT, "mtudisc_lowat", 3066 1.107 atatat SYSCTL_DESCR("Low mark on MTU Discovery route timers"), 3067 1.103 atatat NULL, 0, &icmp6_mtudisc_lowat, 0, 3068 1.103 atatat CTL_NET, PF_INET6, IPPROTO_ICMPV6, 3069 1.103 atatat ICMPV6CTL_MTUDISC_LOWAT, CTL_EOL); 3070 1.105 atatat sysctl_createv(clog, 0, NULL, NULL, 3071 1.105 atatat CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 3072 1.107 atatat CTLTYPE_INT, "nd6_debug", 3073 1.107 atatat SYSCTL_DESCR("Enable neighbor discovery debug output"), 3074 1.103 atatat NULL, 0, &nd6_debug, 0, 3075 1.103 atatat CTL_NET, PF_INET6, IPPROTO_ICMPV6, 3076 1.103 atatat ICMPV6CTL_ND6_DEBUG, CTL_EOL); 3077 1.251 knakahar sysctl_createv(clog, 0, NULL, NULL, 3078 1.251 knakahar CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 3079 1.251 knakahar CTLTYPE_BOOL, "reflect_pmtu", 3080 1.251 knakahar SYSCTL_DESCR("Use path MTU Discovery for icmpv6 reflect"), 3081 1.251 knakahar NULL, 0, &icmp6_reflect_pmtu, 0, 3082 1.251 knakahar CTL_NET, PF_INET6, IPPROTO_ICMPV6, 3083 1.251 knakahar ICMPV6CTL_REFLECT_PMTU, CTL_EOL); 3084 1.252 knakahar sysctl_createv(clog, 0, NULL, NULL, 3085 1.252 knakahar CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 3086 1.252 knakahar CTLTYPE_BOOL, "dynamic_rt_msg", 3087 1.252 knakahar SYSCTL_DESCR("Send routing message for RTF_DYNAMIC"), 3088 1.252 knakahar NULL, 0, &icmp6_dynamic_rt_msg, 0, 3089 1.252 knakahar CTL_NET, PF_INET6, IPPROTO_ICMPV6, 3090 1.252 knakahar ICMPV6CTL_DYNAMIC_RT_MSG, CTL_EOL); 3091 1.2 itojun } 3092 1.145 thorpej 3093 1.145 thorpej void 3094 1.145 thorpej icmp6_statinc(u_int stat) 3095 1.145 thorpej { 3096 1.145 thorpej 3097 1.145 thorpej KASSERT(stat < ICMP6_NSTATS); 3098 1.145 thorpej ICMP6_STATINC(stat); 3099 1.145 thorpej } 3100