1 /* $NetBSD: ip6_input.c,v 1.37 2001/03/01 16:31:41 itojun Exp $ */ 2 /* $KAME: ip6_input.c,v 1.183 2001/03/01 15:15:23 itojun Exp $ */ 3 4 /* 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 /* 34 * Copyright (c) 1982, 1986, 1988, 1993 35 * The Regents of the University of California. All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 3. All advertising materials mentioning features or use of this software 46 * must display the following acknowledgement: 47 * This product includes software developed by the University of 48 * California, Berkeley and its contributors. 49 * 4. Neither the name of the University nor the names of its contributors 50 * may be used to endorse or promote products derived from this software 51 * without specific prior written permission. 52 * 53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 63 * SUCH DAMAGE. 64 * 65 * @(#)ip_input.c 8.2 (Berkeley) 1/4/94 66 */ 67 68 #include "opt_inet.h" 69 #include "opt_ipsec.h" 70 #include "opt_pfil_hooks.h" 71 72 #include <sys/param.h> 73 #include <sys/systm.h> 74 #include <sys/malloc.h> 75 #include <sys/mbuf.h> 76 #include <sys/domain.h> 77 #include <sys/protosw.h> 78 #include <sys/socket.h> 79 #include <sys/socketvar.h> 80 #include <sys/errno.h> 81 #include <sys/time.h> 82 #include <sys/kernel.h> 83 #include <sys/syslog.h> 84 #include <sys/proc.h> 85 86 #include <net/if.h> 87 #include <net/if_types.h> 88 #include <net/if_dl.h> 89 #include <net/route.h> 90 #include <net/netisr.h> 91 #ifdef PFIL_HOOKS 92 #include <net/pfil.h> 93 #endif 94 95 #include <netinet/in.h> 96 #include <netinet/in_systm.h> 97 #ifdef INET 98 #include <netinet/ip.h> 99 #include <netinet/ip_icmp.h> 100 #endif /*INET*/ 101 #include <netinet/ip6.h> 102 #include <netinet6/in6_var.h> 103 #include <netinet6/ip6_var.h> 104 #include <netinet6/in6_pcb.h> 105 #include <netinet/icmp6.h> 106 #include <netinet6/in6_ifattach.h> 107 #include <netinet6/nd6.h> 108 #include <netinet6/in6_prefix.h> 109 110 #ifdef IPSEC 111 #include <netinet6/ipsec.h> 112 #endif 113 114 #include <netinet6/ip6protosw.h> 115 116 /* we need it for NLOOP. */ 117 #include "loop.h" 118 #include "faith.h" 119 120 #include "gif.h" 121 #include "bpfilter.h" 122 123 #include <net/net_osdep.h> 124 125 extern struct domain inet6domain; 126 127 u_char ip6_protox[IPPROTO_MAX]; 128 static int ip6qmaxlen = IFQ_MAXLEN; 129 struct in6_ifaddr *in6_ifaddr; 130 struct ifqueue ip6intrq; 131 132 extern struct ifnet loif[NLOOP]; 133 int ip6_forward_srcrt; /* XXX */ 134 int ip6_sourcecheck; /* XXX */ 135 int ip6_sourcecheck_interval; /* XXX */ 136 137 #ifdef PFIL_HOOKS 138 struct pfil_head inet6_pfil_hook; 139 #endif 140 141 struct ip6stat ip6stat; 142 143 static void ip6_init2 __P((void *)); 144 145 static int ip6_hopopts_input __P((u_int32_t *, u_int32_t *, struct mbuf **, int *)); 146 147 /* 148 * IP6 initialization: fill in IP6 protocol switch table. 149 * All protocols not implemented in kernel go to raw IP6 protocol handler. 150 */ 151 void 152 ip6_init() 153 { 154 struct ip6protosw *pr; 155 int i; 156 struct timeval tv; 157 158 pr = (struct ip6protosw *)pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW); 159 if (pr == 0) 160 panic("ip6_init"); 161 for (i = 0; i < IPPROTO_MAX; i++) 162 ip6_protox[i] = pr - inet6sw; 163 for (pr = (struct ip6protosw *)inet6domain.dom_protosw; 164 pr < (struct ip6protosw *)inet6domain.dom_protoswNPROTOSW; pr++) 165 if (pr->pr_domain->dom_family == PF_INET6 && 166 pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW) 167 ip6_protox[pr->pr_protocol] = pr - inet6sw; 168 ip6intrq.ifq_maxlen = ip6qmaxlen; 169 nd6_init(); 170 frag6_init(); 171 /* 172 * in many cases, random() here does NOT return random number 173 * as initialization during bootstrap time occur in fixed order. 174 */ 175 microtime(&tv); 176 ip6_flow_seq = random() ^ tv.tv_usec; 177 178 ip6_init2((void *)0); 179 180 #ifdef PFIL_HOOKS 181 /* Register our Packet Filter hook. */ 182 inet6_pfil_hook.ph_type = PFIL_TYPE_AF; 183 inet6_pfil_hook.ph_af = AF_INET6; 184 i = pfil_head_register(&inet6_pfil_hook); 185 if (i != 0) 186 printf("ip6_init: WARNING: unable to register pfil hook, " 187 "error %d\n", i); 188 #endif /* PFIL_HOOKS */ 189 } 190 191 static void 192 ip6_init2(dummy) 193 void *dummy; 194 { 195 /* 196 * to route local address of p2p link to loopback, 197 * assign loopback address first. 198 */ 199 in6_ifattach(&loif[0], NULL); 200 201 /* nd6_timer_init */ 202 callout_init(&nd6_timer_ch); 203 callout_reset(&nd6_timer_ch, hz, nd6_timer, NULL); 204 /* router renumbering prefix list maintenance */ 205 callout_init(&in6_rr_timer_ch); 206 callout_reset(&in6_rr_timer_ch, hz, in6_rr_timer, NULL); 207 } 208 209 /* 210 * IP6 input interrupt handling. Just pass the packet to ip6_input. 211 */ 212 void 213 ip6intr() 214 { 215 int s; 216 struct mbuf *m; 217 218 for (;;) { 219 s = splimp(); 220 IF_DEQUEUE(&ip6intrq, m); 221 splx(s); 222 if (m == 0) 223 return; 224 ip6_input(m); 225 } 226 } 227 228 extern struct route_in6 ip6_forward_rt; 229 230 void 231 ip6_input(m) 232 struct mbuf *m; 233 { 234 struct ip6_hdr *ip6; 235 int off = sizeof(struct ip6_hdr), nest; 236 u_int32_t plen; 237 u_int32_t rtalert = ~0; 238 int nxt, ours = 0; 239 struct ifnet *deliverifp = NULL; 240 241 #ifdef IPSEC 242 /* 243 * should the inner packet be considered authentic? 244 * see comment in ah4_input(). 245 */ 246 if (m) { 247 m->m_flags &= ~M_AUTHIPHDR; 248 m->m_flags &= ~M_AUTHIPDGM; 249 } 250 #endif 251 252 /* 253 * mbuf statistics by kazu 254 */ 255 if (m->m_flags & M_EXT) { 256 if (m->m_next) 257 ip6stat.ip6s_mext2m++; 258 else 259 ip6stat.ip6s_mext1++; 260 } else { 261 if (m->m_next) { 262 if (m->m_flags & M_LOOP) { 263 ip6stat.ip6s_m2m[loif[0].if_index]++; /*XXX*/ 264 } else if (m->m_pkthdr.rcvif->if_index <= 31) 265 ip6stat.ip6s_m2m[m->m_pkthdr.rcvif->if_index]++; 266 else 267 ip6stat.ip6s_m2m[0]++; 268 } else 269 ip6stat.ip6s_m1++; 270 } 271 272 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_receive); 273 ip6stat.ip6s_total++; 274 275 #ifndef PULLDOWN_TEST 276 /* XXX is the line really necessary? */ 277 IP6_EXTHDR_CHECK(m, 0, sizeof(struct ip6_hdr), /*nothing*/); 278 #endif 279 280 if (m->m_len < sizeof(struct ip6_hdr)) { 281 struct ifnet *inifp; 282 inifp = m->m_pkthdr.rcvif; 283 if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == 0) { 284 ip6stat.ip6s_toosmall++; 285 in6_ifstat_inc(inifp, ifs6_in_hdrerr); 286 return; 287 } 288 } 289 290 ip6 = mtod(m, struct ip6_hdr *); 291 292 if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { 293 ip6stat.ip6s_badvers++; 294 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); 295 goto bad; 296 } 297 298 #ifdef PFIL_HOOKS 299 /* 300 * Run through list of hooks for input packets. If there are any 301 * filters which require that additional packets in the flow are 302 * not fast-forwarded, they must clear the M_CANFASTFWD flag. 303 * Note that filters must _never_ set this flag, as another filter 304 * in the list may have previously cleared it. 305 */ 306 if (pfil_run_hooks(&inet6_pfil_hook, &m, m->m_pkthdr.rcvif, 307 PFIL_IN) != 0) 308 return; 309 if (m == NULL) 310 return; 311 ip6 = mtod(m, struct ip6_hdr *); 312 #endif /* PFIL_HOOKS */ 313 314 315 ip6stat.ip6s_nxthist[ip6->ip6_nxt]++; 316 317 #ifdef ALTQ 318 /* XXX Temporary until ALTQ is changed to use a pfil hook */ 319 if (altq_input != NULL && (*altq_input)(m, AF_INET6) == 0) { 320 /* packet is dropped by traffic conditioner */ 321 return; 322 } 323 #endif 324 325 /* 326 * Scope check 327 */ 328 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src) || 329 IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst)) { 330 ip6stat.ip6s_badscope++; 331 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); 332 goto bad; 333 } 334 /* 335 * The following check is not documented in the spec. Malicious party 336 * may be able to use IPv4 mapped addr to confuse tcp/udp stack and 337 * bypass security checks (act as if it was from 127.0.0.1 by using 338 * IPv6 src ::ffff:127.0.0.1). Be cautious. 339 * 340 * This check chokes if we are in SIIT cloud. As none of BSDs support 341 * IPv4-less kernel compilation, we cannot support SIIT environment 342 * at all. So, it makes more sense for us to reject any malicious 343 * packets for non-SIIT environment, than try to do a partical support 344 * for SIIT environment. 345 */ 346 if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || 347 IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { 348 ip6stat.ip6s_badscope++; 349 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); 350 goto bad; 351 } 352 #if 0 353 /* 354 * Reject packets with IPv4 compatible addresses (auto tunnel). 355 * 356 * The code forbids auto tunnel relay case in RFC1933 (the check is 357 * stronger than RFC1933). We may want to re-enable it if mech-xx 358 * is revised to forbid relaying case. 359 */ 360 if (IN6_IS_ADDR_V4COMPAT(&ip6->ip6_src) || 361 IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) { 362 ip6stat.ip6s_badscope++; 363 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); 364 goto bad; 365 } 366 #endif 367 368 if (IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) || 369 IN6_IS_ADDR_LOOPBACK(&ip6->ip6_dst)) { 370 if (m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) { 371 ours = 1; 372 deliverifp = m->m_pkthdr.rcvif; 373 goto hbhcheck; 374 } else { 375 ip6stat.ip6s_badscope++; 376 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); 377 goto bad; 378 } 379 } 380 381 #ifndef FAKE_LOOPBACK_IF 382 if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) 383 #else 384 if (1) 385 #endif 386 { 387 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) 388 ip6->ip6_src.s6_addr16[1] 389 = htons(m->m_pkthdr.rcvif->if_index); 390 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) 391 ip6->ip6_dst.s6_addr16[1] 392 = htons(m->m_pkthdr.rcvif->if_index); 393 } 394 395 /* 396 * XXX we need this since we do not have "goto ours" hack route 397 * for some of our ifaddrs on loopback interface. 398 * we should correct it by changing in6_ifattach to install 399 * "goto ours" hack route. 400 */ 401 if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) != 0) { 402 if (IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_dst)) { 403 ours = 1; 404 deliverifp = m->m_pkthdr.rcvif; 405 goto hbhcheck; 406 } 407 } 408 409 /* 410 * Multicast check 411 */ 412 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { 413 struct in6_multi *in6m = 0; 414 415 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mcast); 416 /* 417 * See if we belong to the destination multicast group on the 418 * arrival interface. 419 */ 420 IN6_LOOKUP_MULTI(ip6->ip6_dst, m->m_pkthdr.rcvif, in6m); 421 if (in6m) 422 ours = 1; 423 else if (!ip6_mrouter) { 424 ip6stat.ip6s_notmember++; 425 ip6stat.ip6s_cantforward++; 426 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); 427 goto bad; 428 } 429 deliverifp = m->m_pkthdr.rcvif; 430 goto hbhcheck; 431 } 432 433 /* 434 * Unicast check 435 */ 436 if (ip6_forward_rt.ro_rt != NULL && 437 (ip6_forward_rt.ro_rt->rt_flags & RTF_UP) != 0 && 438 IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, 439 &((struct sockaddr_in6 *)(&ip6_forward_rt.ro_dst))->sin6_addr)) 440 ip6stat.ip6s_forward_cachehit++; 441 else { 442 struct sockaddr_in6 *dst6; 443 444 if (ip6_forward_rt.ro_rt) { 445 /* route is down or destination is different */ 446 ip6stat.ip6s_forward_cachemiss++; 447 RTFREE(ip6_forward_rt.ro_rt); 448 ip6_forward_rt.ro_rt = 0; 449 } 450 451 bzero(&ip6_forward_rt.ro_dst, sizeof(struct sockaddr_in6)); 452 dst6 = (struct sockaddr_in6 *)&ip6_forward_rt.ro_dst; 453 dst6->sin6_len = sizeof(struct sockaddr_in6); 454 dst6->sin6_family = AF_INET6; 455 dst6->sin6_addr = ip6->ip6_dst; 456 457 rtalloc((struct route *)&ip6_forward_rt); 458 } 459 460 #define rt6_key(r) ((struct sockaddr_in6 *)((r)->rt_nodes->rn_key)) 461 462 /* 463 * Accept the packet if the forwarding interface to the destination 464 * according to the routing table is the loopback interface, 465 * unless the associated route has a gateway. 466 * Note that this approach causes to accept a packet if there is a 467 * route to the loopback interface for the destination of the packet. 468 * But we think it's even useful in some situations, e.g. when using 469 * a special daemon which wants to intercept the packet. 470 */ 471 if (ip6_forward_rt.ro_rt && 472 (ip6_forward_rt.ro_rt->rt_flags & 473 (RTF_HOST|RTF_GATEWAY)) == RTF_HOST && 474 #if 0 475 /* 476 * The check below is redundant since the comparison of 477 * the destination and the key of the rtentry has 478 * already done through looking up the routing table. 479 */ 480 IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, 481 &rt6_key(ip6_forward_rt.ro_rt)->sin6_addr) && 482 #endif 483 ip6_forward_rt.ro_rt->rt_ifp->if_type == IFT_LOOP) { 484 struct in6_ifaddr *ia6 = 485 (struct in6_ifaddr *)ip6_forward_rt.ro_rt->rt_ifa; 486 if (ia6->ia6_flags & IN6_IFF_ANYCAST) 487 m->m_flags |= M_ANYCAST6; 488 /* 489 * packets to a tentative, duplicated, or somehow invalid 490 * address must not be accepted. 491 */ 492 if (!(ia6->ia6_flags & IN6_IFF_NOTREADY)) { 493 /* this address is ready */ 494 ours = 1; 495 deliverifp = ia6->ia_ifp; /* correct? */ 496 goto hbhcheck; 497 } else { 498 /* address is not ready, so discard the packet. */ 499 nd6log((LOG_INFO, 500 "ip6_input: packet to an unready address %s->%s\n", 501 ip6_sprintf(&ip6->ip6_src), 502 ip6_sprintf(&ip6->ip6_dst))); 503 504 goto bad; 505 } 506 } 507 508 /* 509 * FAITH(Firewall Aided Internet Translator) 510 */ 511 #if defined(NFAITH) && 0 < NFAITH 512 if (ip6_keepfaith) { 513 if (ip6_forward_rt.ro_rt && ip6_forward_rt.ro_rt->rt_ifp 514 && ip6_forward_rt.ro_rt->rt_ifp->if_type == IFT_FAITH) { 515 /* XXX do we need more sanity checks? */ 516 ours = 1; 517 deliverifp = ip6_forward_rt.ro_rt->rt_ifp; /*faith*/ 518 goto hbhcheck; 519 } 520 } 521 #endif 522 523 #if 0 524 { 525 /* 526 * Last resort: check in6_ifaddr for incoming interface. 527 * The code is here until I update the "goto ours hack" code above 528 * working right. 529 */ 530 struct ifaddr *ifa; 531 for (ifa = m->m_pkthdr.rcvif->if_addrlist.tqh_first; 532 ifa; 533 ifa = ifa->ifa_list.tqe_next) { 534 if (ifa->ifa_addr == NULL) 535 continue; /* just for safety */ 536 if (ifa->ifa_addr->sa_family != AF_INET6) 537 continue; 538 if (IN6_ARE_ADDR_EQUAL(IFA_IN6(ifa), &ip6->ip6_dst)) { 539 ours = 1; 540 deliverifp = ifa->ifa_ifp; 541 goto hbhcheck; 542 } 543 } 544 } 545 #endif 546 547 /* 548 * Now there is no reason to process the packet if it's not our own 549 * and we're not a router. 550 */ 551 if (!ip6_forwarding) { 552 ip6stat.ip6s_cantforward++; 553 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); 554 goto bad; 555 } 556 557 hbhcheck: 558 /* 559 * Process Hop-by-Hop options header if it's contained. 560 * m may be modified in ip6_hopopts_input(). 561 * If a JumboPayload option is included, plen will also be modified. 562 */ 563 plen = (u_int32_t)ntohs(ip6->ip6_plen); 564 if (ip6->ip6_nxt == IPPROTO_HOPOPTS) { 565 struct ip6_hbh *hbh; 566 567 if (ip6_hopopts_input(&plen, &rtalert, &m, &off)) { 568 #if 0 /*touches NULL pointer*/ 569 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); 570 #endif 571 return; /* m have already been freed */ 572 } 573 574 /* adjust pointer */ 575 ip6 = mtod(m, struct ip6_hdr *); 576 577 /* 578 * if the payload length field is 0 and the next header field 579 * indicates Hop-by-Hop Options header, then a Jumbo Payload 580 * option MUST be included. 581 */ 582 if (ip6->ip6_plen == 0 && plen == 0) { 583 /* 584 * Note that if a valid jumbo payload option is 585 * contained, ip6_hoptops_input() must set a valid 586 * (non-zero) payload length to the variable plen. 587 */ 588 ip6stat.ip6s_badoptions++; 589 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); 590 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); 591 icmp6_error(m, ICMP6_PARAM_PROB, 592 ICMP6_PARAMPROB_HEADER, 593 (caddr_t)&ip6->ip6_plen - (caddr_t)ip6); 594 return; 595 } 596 #ifndef PULLDOWN_TEST 597 /* ip6_hopopts_input() ensures that mbuf is contiguous */ 598 hbh = (struct ip6_hbh *)(ip6 + 1); 599 #else 600 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr), 601 sizeof(struct ip6_hbh)); 602 if (hbh == NULL) { 603 ip6stat.ip6s_tooshort++; 604 return; 605 } 606 #endif 607 nxt = hbh->ip6h_nxt; 608 609 /* 610 * accept the packet if a router alert option is included 611 * and we act as an IPv6 router. 612 */ 613 if (rtalert != ~0 && ip6_forwarding) 614 ours = 1; 615 } else 616 nxt = ip6->ip6_nxt; 617 618 /* 619 * Check that the amount of data in the buffers 620 * is as at least much as the IPv6 header would have us expect. 621 * Trim mbufs if longer than we expect. 622 * Drop packet if shorter than we expect. 623 */ 624 if (m->m_pkthdr.len - sizeof(struct ip6_hdr) < plen) { 625 ip6stat.ip6s_tooshort++; 626 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated); 627 goto bad; 628 } 629 if (m->m_pkthdr.len > sizeof(struct ip6_hdr) + plen) { 630 if (m->m_len == m->m_pkthdr.len) { 631 m->m_len = sizeof(struct ip6_hdr) + plen; 632 m->m_pkthdr.len = sizeof(struct ip6_hdr) + plen; 633 } else 634 m_adj(m, sizeof(struct ip6_hdr) + plen - m->m_pkthdr.len); 635 } 636 637 /* 638 * Forward if desirable. 639 */ 640 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { 641 /* 642 * If we are acting as a multicast router, all 643 * incoming multicast packets are passed to the 644 * kernel-level multicast forwarding function. 645 * The packet is returned (relatively) intact; if 646 * ip6_mforward() returns a non-zero value, the packet 647 * must be discarded, else it may be accepted below. 648 */ 649 if (ip6_mrouter && ip6_mforward(ip6, m->m_pkthdr.rcvif, m)) { 650 ip6stat.ip6s_cantforward++; 651 m_freem(m); 652 return; 653 } 654 if (!ours) { 655 m_freem(m); 656 return; 657 } 658 } else if (!ours) { 659 ip6_forward(m, 0); 660 return; 661 } 662 663 ip6 = mtod(m, struct ip6_hdr *); 664 665 /* 666 * Malicious party may be able to use IPv4 mapped addr to confuse 667 * tcp/udp stack and bypass security checks (act as if it was from 668 * 127.0.0.1 by using IPv6 src ::ffff:127.0.0.1). Be cautious. 669 * 670 * For SIIT end node behavior, you may want to disable the check. 671 * However, you will become vulnerable to attacks using IPv4 mapped 672 * source. 673 */ 674 if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || 675 IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { 676 ip6stat.ip6s_badscope++; 677 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); 678 goto bad; 679 } 680 681 /* 682 * Tell launch routine the next header 683 */ 684 #ifdef IFA_STATS 685 if (deliverifp != NULL) { 686 struct in6_ifaddr *ia6; 687 ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst); 688 if (ia6) 689 ia6->ia_ifa.ifa_data.ifad_inbytes += m->m_pkthdr.len; 690 } 691 #endif 692 ip6stat.ip6s_delivered++; 693 in6_ifstat_inc(deliverifp, ifs6_in_deliver); 694 nest = 0; 695 while (nxt != IPPROTO_DONE) { 696 if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) { 697 ip6stat.ip6s_toomanyhdr++; 698 goto bad; 699 } 700 701 /* 702 * protection against faulty packet - there should be 703 * more sanity checks in header chain processing. 704 */ 705 if (m->m_pkthdr.len < off) { 706 ip6stat.ip6s_tooshort++; 707 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated); 708 goto bad; 709 } 710 711 #ifdef IPSEC 712 /* 713 * enforce IPsec policy checking if we are seeing last header. 714 * note that we do not visit this with protocols with pcb layer 715 * code - like udp/tcp/raw ip. 716 */ 717 if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0 && 718 ipsec6_in_reject(m, NULL)) { 719 ipsec6stat.in_polvio++; 720 goto bad; 721 } 722 #endif 723 724 nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt); 725 } 726 return; 727 bad: 728 m_freem(m); 729 } 730 731 /* 732 * Hop-by-Hop options header processing. If a valid jumbo payload option is 733 * included, the real payload length will be stored in plenp. 734 */ 735 static int 736 ip6_hopopts_input(plenp, rtalertp, mp, offp) 737 u_int32_t *plenp; 738 u_int32_t *rtalertp; /* XXX: should be stored more smart way */ 739 struct mbuf **mp; 740 int *offp; 741 { 742 struct mbuf *m = *mp; 743 int off = *offp, hbhlen; 744 struct ip6_hbh *hbh; 745 u_int8_t *opt; 746 747 /* validation of the length of the header */ 748 #ifndef PULLDOWN_TEST 749 IP6_EXTHDR_CHECK(m, off, sizeof(*hbh), -1); 750 hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off); 751 hbhlen = (hbh->ip6h_len + 1) << 3; 752 753 IP6_EXTHDR_CHECK(m, off, hbhlen, -1); 754 hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off); 755 #else 756 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, 757 sizeof(struct ip6_hdr), sizeof(struct ip6_hbh)); 758 if (hbh == NULL) { 759 ip6stat.ip6s_tooshort++; 760 return -1; 761 } 762 hbhlen = (hbh->ip6h_len + 1) << 3; 763 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr), 764 hbhlen); 765 if (hbh == NULL) { 766 ip6stat.ip6s_tooshort++; 767 return -1; 768 } 769 #endif 770 off += hbhlen; 771 hbhlen -= sizeof(struct ip6_hbh); 772 opt = (u_int8_t *)hbh + sizeof(struct ip6_hbh); 773 774 if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh), 775 hbhlen, rtalertp, plenp) < 0) 776 return(-1); 777 778 *offp = off; 779 *mp = m; 780 return(0); 781 } 782 783 /* 784 * Search header for all Hop-by-hop options and process each option. 785 * This function is separate from ip6_hopopts_input() in order to 786 * handle a case where the sending node itself process its hop-by-hop 787 * options header. In such a case, the function is called from ip6_output(). 788 */ 789 int 790 ip6_process_hopopts(m, opthead, hbhlen, rtalertp, plenp) 791 struct mbuf *m; 792 u_int8_t *opthead; 793 int hbhlen; 794 u_int32_t *rtalertp; 795 u_int32_t *plenp; 796 { 797 struct ip6_hdr *ip6; 798 int optlen = 0; 799 u_int8_t *opt = opthead; 800 u_int16_t rtalert_val; 801 u_int32_t jumboplen; 802 803 for (; hbhlen > 0; hbhlen -= optlen, opt += optlen) { 804 switch (*opt) { 805 case IP6OPT_PAD1: 806 optlen = 1; 807 break; 808 case IP6OPT_PADN: 809 if (hbhlen < IP6OPT_MINLEN) { 810 ip6stat.ip6s_toosmall++; 811 goto bad; 812 } 813 optlen = *(opt + 1) + 2; 814 break; 815 case IP6OPT_RTALERT: 816 /* XXX may need check for alignment */ 817 if (hbhlen < IP6OPT_RTALERT_LEN) { 818 ip6stat.ip6s_toosmall++; 819 goto bad; 820 } 821 if (*(opt + 1) != IP6OPT_RTALERT_LEN - 2) { 822 /* XXX: should we discard the packet? */ 823 log(LOG_ERR, "length of router alert opt is inconsitent(%d)", 824 *(opt + 1)); 825 } 826 optlen = IP6OPT_RTALERT_LEN; 827 bcopy((caddr_t)(opt + 2), (caddr_t)&rtalert_val, 2); 828 *rtalertp = ntohs(rtalert_val); 829 break; 830 case IP6OPT_JUMBO: 831 /* XXX may need check for alignment */ 832 if (hbhlen < IP6OPT_JUMBO_LEN) { 833 ip6stat.ip6s_toosmall++; 834 goto bad; 835 } 836 if (*(opt + 1) != IP6OPT_JUMBO_LEN - 2) { 837 /* XXX: should we discard the packet? */ 838 log(LOG_ERR, "length of jumbopayload opt " 839 "is inconsistent(%d)\n", 840 *(opt + 1)); 841 } 842 optlen = IP6OPT_JUMBO_LEN; 843 844 /* 845 * IPv6 packets that have non 0 payload length 846 * must not contain a jumbo payload option. 847 */ 848 ip6 = mtod(m, struct ip6_hdr *); 849 if (ip6->ip6_plen) { 850 ip6stat.ip6s_badoptions++; 851 icmp6_error(m, ICMP6_PARAM_PROB, 852 ICMP6_PARAMPROB_HEADER, 853 sizeof(struct ip6_hdr) + 854 sizeof(struct ip6_hbh) + 855 opt - opthead); 856 return(-1); 857 } 858 859 /* 860 * We may see jumbolen in unaligned location, so 861 * we'd need to perform bcopy(). 862 */ 863 bcopy(opt + 2, &jumboplen, sizeof(jumboplen)); 864 jumboplen = (u_int32_t)htonl(jumboplen); 865 866 #if 1 867 /* 868 * if there are multiple jumbo payload options, 869 * *plenp will be non-zero and the packet will be 870 * rejected. 871 * the behavior may need some debate in ipngwg - 872 * multiple options does not make sense, however, 873 * there's no explicit mention in specification. 874 */ 875 if (*plenp != 0) { 876 ip6stat.ip6s_badoptions++; 877 icmp6_error(m, ICMP6_PARAM_PROB, 878 ICMP6_PARAMPROB_HEADER, 879 sizeof(struct ip6_hdr) + 880 sizeof(struct ip6_hbh) + 881 opt + 2 - opthead); 882 return(-1); 883 } 884 #endif 885 886 /* 887 * jumbo payload length must be larger than 65535. 888 */ 889 if (jumboplen <= IPV6_MAXPACKET) { 890 ip6stat.ip6s_badoptions++; 891 icmp6_error(m, ICMP6_PARAM_PROB, 892 ICMP6_PARAMPROB_HEADER, 893 sizeof(struct ip6_hdr) + 894 sizeof(struct ip6_hbh) + 895 opt + 2 - opthead); 896 return(-1); 897 } 898 *plenp = jumboplen; 899 900 break; 901 default: /* unknown option */ 902 if (hbhlen < IP6OPT_MINLEN) { 903 ip6stat.ip6s_toosmall++; 904 goto bad; 905 } 906 if ((optlen = ip6_unknown_opt(opt, m, 907 sizeof(struct ip6_hdr) + 908 sizeof(struct ip6_hbh) + 909 opt - opthead)) == -1) 910 return(-1); 911 optlen += 2; 912 break; 913 } 914 } 915 916 return(0); 917 918 bad: 919 m_freem(m); 920 return(-1); 921 } 922 923 /* 924 * Unknown option processing. 925 * The third argument `off' is the offset from the IPv6 header to the option, 926 * which is necessary if the IPv6 header the and option header and IPv6 header 927 * is not continuous in order to return an ICMPv6 error. 928 */ 929 int 930 ip6_unknown_opt(optp, m, off) 931 u_int8_t *optp; 932 struct mbuf *m; 933 int off; 934 { 935 struct ip6_hdr *ip6; 936 937 switch (IP6OPT_TYPE(*optp)) { 938 case IP6OPT_TYPE_SKIP: /* ignore the option */ 939 return((int)*(optp + 1)); 940 case IP6OPT_TYPE_DISCARD: /* silently discard */ 941 m_freem(m); 942 return(-1); 943 case IP6OPT_TYPE_FORCEICMP: /* send ICMP even if multicasted */ 944 ip6stat.ip6s_badoptions++; 945 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, off); 946 return(-1); 947 case IP6OPT_TYPE_ICMP: /* send ICMP if not multicasted */ 948 ip6stat.ip6s_badoptions++; 949 ip6 = mtod(m, struct ip6_hdr *); 950 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || 951 (m->m_flags & (M_BCAST|M_MCAST))) 952 m_freem(m); 953 else 954 icmp6_error(m, ICMP6_PARAM_PROB, 955 ICMP6_PARAMPROB_OPTION, off); 956 return(-1); 957 } 958 959 m_freem(m); /* XXX: NOTREACHED */ 960 return(-1); 961 } 962 963 /* 964 * Create the "control" list for this pcb. 965 * 966 * The routine will be called from upper layer handlers like tcp6_input(). 967 * Thus the routine assumes that the caller (tcp6_input) have already 968 * called IP6_EXTHDR_CHECK() and all the extension headers are located in the 969 * very first mbuf on the mbuf chain. 970 * We may want to add some infinite loop prevention or sanity checks for safety. 971 * (This applies only when you are using KAME mbuf chain restriction, i.e. 972 * you are using IP6_EXTHDR_CHECK() not m_pulldown()) 973 */ 974 void 975 ip6_savecontrol(in6p, mp, ip6, m) 976 struct in6pcb *in6p; 977 struct mbuf **mp; 978 struct ip6_hdr *ip6; 979 struct mbuf *m; 980 { 981 struct proc *p = curproc; /* XXX */ 982 int privileged; 983 984 privileged = 0; 985 if (p && !suser(p->p_ucred, &p->p_acflag)) 986 privileged++; 987 988 #ifdef SO_TIMESTAMP 989 if (in6p->in6p_socket->so_options & SO_TIMESTAMP) { 990 struct timeval tv; 991 992 microtime(&tv); 993 *mp = sbcreatecontrol((caddr_t) &tv, sizeof(tv), 994 SCM_TIMESTAMP, SOL_SOCKET); 995 if (*mp) 996 mp = &(*mp)->m_next; 997 } 998 #endif 999 if (in6p->in6p_flags & IN6P_RECVDSTADDR) { 1000 *mp = sbcreatecontrol((caddr_t) &ip6->ip6_dst, 1001 sizeof(struct in6_addr), IPV6_RECVDSTADDR, 1002 IPPROTO_IPV6); 1003 if (*mp) 1004 mp = &(*mp)->m_next; 1005 } 1006 1007 #ifdef noyet 1008 /* options were tossed above */ 1009 if (in6p->in6p_flags & IN6P_RECVOPTS) 1010 /* broken */ 1011 /* ip6_srcroute doesn't do what we want here, need to fix */ 1012 if (in6p->in6p_flags & IPV6P_RECVRETOPTS) 1013 /* broken */ 1014 #endif 1015 1016 /* RFC 2292 sec. 5 */ 1017 if ((in6p->in6p_flags & IN6P_PKTINFO) != 0) { 1018 struct in6_pktinfo pi6; 1019 bcopy(&ip6->ip6_dst, &pi6.ipi6_addr, sizeof(struct in6_addr)); 1020 if (IN6_IS_SCOPE_LINKLOCAL(&pi6.ipi6_addr)) 1021 pi6.ipi6_addr.s6_addr16[1] = 0; 1022 pi6.ipi6_ifindex = (m && m->m_pkthdr.rcvif) 1023 ? m->m_pkthdr.rcvif->if_index 1024 : 0; 1025 *mp = sbcreatecontrol((caddr_t) &pi6, 1026 sizeof(struct in6_pktinfo), IPV6_PKTINFO, 1027 IPPROTO_IPV6); 1028 if (*mp) 1029 mp = &(*mp)->m_next; 1030 } 1031 if (in6p->in6p_flags & IN6P_HOPLIMIT) { 1032 int hlim = ip6->ip6_hlim & 0xff; 1033 *mp = sbcreatecontrol((caddr_t) &hlim, 1034 sizeof(int), IPV6_HOPLIMIT, IPPROTO_IPV6); 1035 if (*mp) 1036 mp = &(*mp)->m_next; 1037 } 1038 /* IN6P_NEXTHOP - for outgoing packet only */ 1039 1040 /* 1041 * IPV6_HOPOPTS socket option. We require super-user privilege 1042 * for the option, but it might be too strict, since there might 1043 * be some hop-by-hop options which can be returned to normal user. 1044 * See RFC 2292 section 6. 1045 */ 1046 if ((in6p->in6p_flags & IN6P_HOPOPTS) != 0 && privileged) { 1047 /* 1048 * Check if a hop-by-hop options header is contatined in the 1049 * received packet, and if so, store the options as ancillary 1050 * data. Note that a hop-by-hop options header must be 1051 * just after the IPv6 header, which fact is assured through 1052 * the IPv6 input processing. 1053 */ 1054 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 1055 if (ip6->ip6_nxt == IPPROTO_HOPOPTS) { 1056 struct ip6_hbh *hbh; 1057 int hbhlen; 1058 1059 #ifndef PULLDOWN_TEST 1060 hbh = (struct ip6_hbh *)(ip6 + 1); 1061 hbhlen = (hbh->ip6h_len + 1) << 3; 1062 #else 1063 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, 1064 sizeof(struct ip6_hdr), sizeof(struct ip6_hbh)); 1065 if (hbh == NULL) { 1066 ip6stat.ip6s_tooshort++; 1067 return; 1068 } 1069 hbhlen = (hbh->ip6h_len + 1) << 3; 1070 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, 1071 sizeof(struct ip6_hdr), hbhlen); 1072 if (hbh == NULL) { 1073 ip6stat.ip6s_tooshort++; 1074 return; 1075 } 1076 #endif 1077 1078 /* 1079 * XXX: We copy whole the header even if a jumbo 1080 * payload option is included, which option is to 1081 * be removed before returning in the RFC 2292. 1082 * But it's too painful operation... 1083 */ 1084 *mp = sbcreatecontrol((caddr_t)hbh, hbhlen, 1085 IPV6_HOPOPTS, IPPROTO_IPV6); 1086 if (*mp) 1087 mp = &(*mp)->m_next; 1088 } 1089 } 1090 1091 /* IPV6_DSTOPTS and IPV6_RTHDR socket options */ 1092 if (in6p->in6p_flags & (IN6P_DSTOPTS | IN6P_RTHDR)) { 1093 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 1094 int nxt = ip6->ip6_nxt, off = sizeof(struct ip6_hdr);; 1095 1096 /* 1097 * Search for destination options headers or routing 1098 * header(s) through the header chain, and stores each 1099 * header as ancillary data. 1100 * Note that the order of the headers remains in 1101 * the chain of ancillary data. 1102 */ 1103 while (1) { /* is explicit loop prevention necessary? */ 1104 struct ip6_ext *ip6e; 1105 int elen; 1106 1107 #ifndef PULLDOWN_TEST 1108 ip6e = (struct ip6_ext *)(mtod(m, caddr_t) + off); 1109 if (nxt == IPPROTO_AH) 1110 elen = (ip6e->ip6e_len + 2) << 2; 1111 else 1112 elen = (ip6e->ip6e_len + 1) << 3; 1113 #else 1114 IP6_EXTHDR_GET(ip6e, struct ip6_ext *, m, off, 1115 sizeof(struct ip6_ext)); 1116 if (ip6e == NULL) { 1117 ip6stat.ip6s_tooshort++; 1118 return; 1119 } 1120 if (nxt == IPPROTO_AH) 1121 elen = (ip6e->ip6e_len + 2) << 2; 1122 else 1123 elen = (ip6e->ip6e_len + 1) << 3; 1124 IP6_EXTHDR_GET(ip6e, struct ip6_ext *, m, off, elen); 1125 if (ip6e == NULL) { 1126 ip6stat.ip6s_tooshort++; 1127 return; 1128 } 1129 #endif 1130 1131 switch (nxt) { 1132 case IPPROTO_DSTOPTS: 1133 if (!in6p->in6p_flags & IN6P_DSTOPTS) 1134 break; 1135 1136 /* 1137 * We also require super-user privilege for 1138 * the option. 1139 * See the comments on IN6_HOPOPTS. 1140 */ 1141 if (!privileged) 1142 break; 1143 1144 *mp = sbcreatecontrol((caddr_t)ip6e, elen, 1145 IPV6_DSTOPTS, 1146 IPPROTO_IPV6); 1147 if (*mp) 1148 mp = &(*mp)->m_next; 1149 break; 1150 1151 case IPPROTO_ROUTING: 1152 if (!in6p->in6p_flags & IN6P_RTHDR) 1153 break; 1154 1155 *mp = sbcreatecontrol((caddr_t)ip6e, elen, 1156 IPV6_RTHDR, 1157 IPPROTO_IPV6); 1158 if (*mp) 1159 mp = &(*mp)->m_next; 1160 break; 1161 1162 case IPPROTO_UDP: 1163 case IPPROTO_TCP: 1164 case IPPROTO_ICMPV6: 1165 default: 1166 /* 1167 * stop search if we encounter an upper 1168 * layer protocol headers. 1169 */ 1170 goto loopend; 1171 1172 case IPPROTO_HOPOPTS: 1173 case IPPROTO_AH: /* is it possible? */ 1174 break; 1175 } 1176 1177 /* proceed with the next header. */ 1178 off += elen; 1179 nxt = ip6e->ip6e_nxt; 1180 } 1181 loopend: 1182 ; 1183 } 1184 if ((in6p->in6p_flags & IN6P_HOPOPTS) && privileged) { 1185 /* to be done */ 1186 } 1187 if ((in6p->in6p_flags & IN6P_DSTOPTS) && privileged) { 1188 /* to be done */ 1189 } 1190 /* IN6P_RTHDR - to be done */ 1191 1192 } 1193 1194 /* 1195 * Get pointer to the previous header followed by the header 1196 * currently processed. 1197 * XXX: This function supposes that 1198 * M includes all headers, 1199 * the next header field and the header length field of each header 1200 * are valid, and 1201 * the sum of each header length equals to OFF. 1202 * Because of these assumptions, this function must be called very 1203 * carefully. Moreover, it will not be used in the near future when 1204 * we develop `neater' mechanism to process extension headers. 1205 */ 1206 char * 1207 ip6_get_prevhdr(m, off) 1208 struct mbuf *m; 1209 int off; 1210 { 1211 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 1212 1213 if (off == sizeof(struct ip6_hdr)) 1214 return(&ip6->ip6_nxt); 1215 else { 1216 int len, nxt; 1217 struct ip6_ext *ip6e = NULL; 1218 1219 nxt = ip6->ip6_nxt; 1220 len = sizeof(struct ip6_hdr); 1221 while (len < off) { 1222 ip6e = (struct ip6_ext *)(mtod(m, caddr_t) + len); 1223 1224 switch (nxt) { 1225 case IPPROTO_FRAGMENT: 1226 len += sizeof(struct ip6_frag); 1227 break; 1228 case IPPROTO_AH: 1229 len += (ip6e->ip6e_len + 2) << 2; 1230 break; 1231 default: 1232 len += (ip6e->ip6e_len + 1) << 3; 1233 break; 1234 } 1235 nxt = ip6e->ip6e_nxt; 1236 } 1237 if (ip6e) 1238 return(&ip6e->ip6e_nxt); 1239 else 1240 return NULL; 1241 } 1242 } 1243 1244 /* 1245 * get next header offset. m will be retained. 1246 */ 1247 int 1248 ip6_nexthdr(m, off, proto, nxtp) 1249 struct mbuf *m; 1250 int off; 1251 int proto; 1252 int *nxtp; 1253 { 1254 struct ip6_hdr ip6; 1255 struct ip6_ext ip6e; 1256 struct ip6_frag fh; 1257 1258 /* just in case */ 1259 if (m == NULL) 1260 panic("ip6_nexthdr: m == NULL"); 1261 if ((m->m_flags & M_PKTHDR) == 0 || m->m_pkthdr.len < off) 1262 return -1; 1263 1264 switch (proto) { 1265 case IPPROTO_IPV6: 1266 if (m->m_pkthdr.len < off + sizeof(ip6)) 1267 return -1; 1268 m_copydata(m, off, sizeof(ip6), (caddr_t)&ip6); 1269 if (nxtp) 1270 *nxtp = ip6.ip6_nxt; 1271 off += sizeof(ip6); 1272 return off; 1273 1274 case IPPROTO_FRAGMENT: 1275 /* 1276 * terminate parsing if it is not the first fragment, 1277 * it does not make sense to parse through it. 1278 */ 1279 if (m->m_pkthdr.len < off + sizeof(fh)) 1280 return -1; 1281 m_copydata(m, off, sizeof(fh), (caddr_t)&fh); 1282 if ((ntohs(fh.ip6f_offlg) & IP6F_OFF_MASK) != 0) 1283 return -1; 1284 if (nxtp) 1285 *nxtp = fh.ip6f_nxt; 1286 off += sizeof(struct ip6_frag); 1287 return off; 1288 1289 case IPPROTO_AH: 1290 if (m->m_pkthdr.len < off + sizeof(ip6e)) 1291 return -1; 1292 m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e); 1293 if (nxtp) 1294 *nxtp = ip6e.ip6e_nxt; 1295 off += (ip6e.ip6e_len + 2) << 2; 1296 return off; 1297 1298 case IPPROTO_HOPOPTS: 1299 case IPPROTO_ROUTING: 1300 case IPPROTO_DSTOPTS: 1301 if (m->m_pkthdr.len < off + sizeof(ip6e)) 1302 return -1; 1303 m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e); 1304 if (nxtp) 1305 *nxtp = ip6e.ip6e_nxt; 1306 off += (ip6e.ip6e_len + 1) << 3; 1307 return off; 1308 1309 case IPPROTO_NONE: 1310 case IPPROTO_ESP: 1311 case IPPROTO_IPCOMP: 1312 /* give up */ 1313 return -1; 1314 1315 default: 1316 return -1; 1317 } 1318 1319 return -1; 1320 } 1321 1322 /* 1323 * get offset for the last header in the chain. m will be kept untainted. 1324 */ 1325 int 1326 ip6_lasthdr(m, off, proto, nxtp) 1327 struct mbuf *m; 1328 int off; 1329 int proto; 1330 int *nxtp; 1331 { 1332 int newoff; 1333 int nxt; 1334 1335 if (!nxtp) { 1336 nxt = -1; 1337 nxtp = &nxt; 1338 } 1339 while (1) { 1340 newoff = ip6_nexthdr(m, off, proto, nxtp); 1341 if (newoff < 0) 1342 return off; 1343 else if (newoff < off) 1344 return -1; /* invalid */ 1345 else if (newoff == off) 1346 return newoff; 1347 1348 off = newoff; 1349 proto = *nxtp; 1350 } 1351 } 1352 1353 /* 1354 * System control for IP6 1355 */ 1356 1357 u_char inet6ctlerrmap[PRC_NCMDS] = { 1358 0, 0, 0, 0, 1359 0, EMSGSIZE, EHOSTDOWN, EHOSTUNREACH, 1360 EHOSTUNREACH, EHOSTUNREACH, ECONNREFUSED, ECONNREFUSED, 1361 EMSGSIZE, EHOSTUNREACH, 0, 0, 1362 0, 0, 0, 0, 1363 ENOPROTOOPT 1364 }; 1365 1366 #include <uvm/uvm_extern.h> 1367 #include <sys/sysctl.h> 1368 1369 int 1370 ip6_sysctl(name, namelen, oldp, oldlenp, newp, newlen) 1371 int *name; 1372 u_int namelen; 1373 void *oldp; 1374 size_t *oldlenp; 1375 void *newp; 1376 size_t newlen; 1377 { 1378 int old, error; 1379 1380 /* All sysctl names at this level are terminal. */ 1381 if (namelen != 1) 1382 return ENOTDIR; 1383 1384 switch (name[0]) { 1385 1386 case IPV6CTL_FORWARDING: 1387 return sysctl_int(oldp, oldlenp, newp, newlen, 1388 &ip6_forwarding); 1389 case IPV6CTL_SENDREDIRECTS: 1390 return sysctl_int(oldp, oldlenp, newp, newlen, 1391 &ip6_sendredirects); 1392 case IPV6CTL_DEFHLIM: 1393 return sysctl_int(oldp, oldlenp, newp, newlen, &ip6_defhlim); 1394 case IPV6CTL_MAXFRAGPACKETS: 1395 return sysctl_int(oldp, oldlenp, newp, newlen, 1396 &ip6_maxfragpackets); 1397 case IPV6CTL_ACCEPT_RTADV: 1398 return sysctl_int(oldp, oldlenp, newp, newlen, 1399 &ip6_accept_rtadv); 1400 case IPV6CTL_KEEPFAITH: 1401 return sysctl_int(oldp, oldlenp, newp, newlen, &ip6_keepfaith); 1402 case IPV6CTL_LOG_INTERVAL: 1403 return sysctl_int(oldp, oldlenp, newp, newlen, 1404 &ip6_log_interval); 1405 case IPV6CTL_HDRNESTLIMIT: 1406 return sysctl_int(oldp, oldlenp, newp, newlen, 1407 &ip6_hdrnestlimit); 1408 case IPV6CTL_DAD_COUNT: 1409 return sysctl_int(oldp, oldlenp, newp, newlen, &ip6_dad_count); 1410 case IPV6CTL_AUTO_FLOWLABEL: 1411 return sysctl_int(oldp, oldlenp, newp, newlen, 1412 &ip6_auto_flowlabel); 1413 case IPV6CTL_DEFMCASTHLIM: 1414 return sysctl_int(oldp, oldlenp, newp, newlen, 1415 &ip6_defmcasthlim); 1416 case IPV6CTL_GIF_HLIM: 1417 return sysctl_int(oldp, oldlenp, newp, newlen, 1418 &ip6_gif_hlim); 1419 case IPV6CTL_KAME_VERSION: 1420 return sysctl_rdstring(oldp, oldlenp, newp, __KAME_VERSION); 1421 case IPV6CTL_USE_DEPRECATED: 1422 return sysctl_int(oldp, oldlenp, newp, newlen, 1423 &ip6_use_deprecated); 1424 case IPV6CTL_RR_PRUNE: 1425 return sysctl_int(oldp, oldlenp, newp, newlen, &ip6_rr_prune); 1426 #ifndef INET6_BINDV6ONLY 1427 case IPV6CTL_BINDV6ONLY: 1428 return sysctl_int(oldp, oldlenp, newp, newlen, 1429 &ip6_bindv6only); 1430 #endif 1431 case IPV6CTL_ANONPORTMIN: 1432 old = ip6_anonportmin; 1433 error = sysctl_int(oldp, oldlenp, newp, newlen, 1434 &ip6_anonportmin); 1435 if (ip6_anonportmin >= ip6_anonportmax || ip6_anonportmin < 0 || 1436 ip6_anonportmin > 65535 1437 #ifndef IPNOPRIVPORTS 1438 || ip6_anonportmin < IPV6PORT_RESERVED 1439 #endif 1440 ) { 1441 ip6_anonportmin = old; 1442 return (EINVAL); 1443 } 1444 return (error); 1445 case IPV6CTL_ANONPORTMAX: 1446 old = ip6_anonportmax; 1447 error = sysctl_int(oldp, oldlenp, newp, newlen, 1448 &ip6_anonportmax); 1449 if (ip6_anonportmin >= ip6_anonportmax || ip6_anonportmax < 0 || 1450 ip6_anonportmax > 65535 1451 #ifndef IPNOPRIVPORTS 1452 || ip6_anonportmax < IPV6PORT_RESERVED 1453 #endif 1454 ) { 1455 ip6_anonportmax = old; 1456 return (EINVAL); 1457 } 1458 return (error); 1459 #ifndef IPNOPRIVPORTS 1460 case IPV6CTL_LOWPORTMIN: 1461 old = ip6_lowportmin; 1462 error = sysctl_int(oldp, oldlenp, newp, newlen, 1463 &ip6_lowportmin); 1464 if (ip6_lowportmin >= ip6_lowportmax || 1465 ip6_lowportmin > IPV6PORT_RESERVEDMAX || 1466 ip6_lowportmin < IPV6PORT_RESERVEDMIN) { 1467 ip6_lowportmin = old; 1468 return (EINVAL); 1469 } 1470 return (error); 1471 case IPV6CTL_LOWPORTMAX: 1472 old = ip6_lowportmax; 1473 error = sysctl_int(oldp, oldlenp, newp, newlen, 1474 &ip6_lowportmax); 1475 if (ip6_lowportmin >= ip6_lowportmax || 1476 ip6_lowportmax > IPV6PORT_RESERVEDMAX || 1477 ip6_lowportmax < IPV6PORT_RESERVEDMIN) { 1478 ip6_lowportmax = old; 1479 return (EINVAL); 1480 } 1481 return (error); 1482 #endif 1483 default: 1484 return EOPNOTSUPP; 1485 } 1486 /* NOTREACHED */ 1487 } 1488