1 /* $NetBSD: ip6_input.c,v 1.25 2000/07/06 12:36:19 itojun Exp $ */ 2 /* $KAME: ip6_input.c,v 1.95 2000/07/02 07:49:37 jinmei 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 IPV6FIREWALL 111 #include <netinet6/ip6_fw.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 IPV6FIREWALL 138 /* firewall hooks */ 139 ip6_fw_chk_t *ip6_fw_chk_ptr; 140 ip6_fw_ctl_t *ip6_fw_ctl_ptr; 141 #endif 142 143 struct ip6stat ip6stat; 144 145 static void ip6_init2 __P((void *)); 146 147 static int ip6_hopopts_input __P((u_int32_t *, u_int32_t *, struct mbuf **, int *)); 148 149 /* 150 * IP6 initialization: fill in IP6 protocol switch table. 151 * All protocols not implemented in kernel go to raw IP6 protocol handler. 152 */ 153 void 154 ip6_init() 155 { 156 register struct ip6protosw *pr; 157 register int i; 158 struct timeval tv; 159 160 pr = (struct ip6protosw *)pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW); 161 if (pr == 0) 162 panic("ip6_init"); 163 for (i = 0; i < IPPROTO_MAX; i++) 164 ip6_protox[i] = pr - inet6sw; 165 for (pr = (struct ip6protosw *)inet6domain.dom_protosw; 166 pr < (struct ip6protosw *)inet6domain.dom_protoswNPROTOSW; pr++) 167 if (pr->pr_domain->dom_family == PF_INET6 && 168 pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW) 169 ip6_protox[pr->pr_protocol] = pr - inet6sw; 170 ip6intrq.ifq_maxlen = ip6qmaxlen; 171 nd6_init(); 172 frag6_init(); 173 #ifdef IPV6FIREWALL 174 ip6_fw_init(); 175 #endif 176 /* 177 * in many cases, random() here does NOT return random number 178 * as initialization during bootstrap time occur in fixed order. 179 */ 180 microtime(&tv); 181 ip6_flow_seq = random() ^ tv.tv_usec; 182 183 ip6_init2((void *)0); 184 } 185 186 static void 187 ip6_init2(dummy) 188 void *dummy; 189 { 190 /* 191 * to route local address of p2p link to loopback, 192 * assign loopback address first. 193 */ 194 in6_ifattach(&loif[0], NULL); 195 196 /* nd6_timer_init */ 197 callout_init(&nd6_timer_ch); 198 callout_reset(&nd6_timer_ch, hz, nd6_timer, NULL); 199 /* router renumbering prefix list maintenance */ 200 callout_init(&in6_rr_timer_ch); 201 callout_reset(&in6_rr_timer_ch, hz, in6_rr_timer, NULL); 202 } 203 204 /* 205 * IP6 input interrupt handling. Just pass the packet to ip6_input. 206 */ 207 void 208 ip6intr() 209 { 210 int s; 211 struct mbuf *m; 212 213 for (;;) { 214 s = splimp(); 215 IF_DEQUEUE(&ip6intrq, m); 216 splx(s); 217 if (m == 0) 218 return; 219 ip6_input(m); 220 } 221 } 222 223 extern struct route_in6 ip6_forward_rt; 224 225 void 226 ip6_input(m) 227 struct mbuf *m; 228 { 229 struct ip6_hdr *ip6; 230 int off = sizeof(struct ip6_hdr), nest; 231 u_int32_t plen; 232 u_int32_t rtalert = ~0; 233 int nxt, ours = 0; 234 struct ifnet *deliverifp = NULL; 235 #ifdef PFIL_HOOKS 236 struct packet_filter_hook *pfh; 237 struct mbuf *m0; 238 int rv; 239 #endif /* PFIL_HOOKS */ 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 m0 = m; 307 pfh = pfil_hook_get(PFIL_IN, &inetsw[ip_protox[IPPROTO_IPV6]].pr_pfh); 308 for (; pfh; pfh = pfh->pfil_link.tqe_next) 309 if (pfh->pfil_func) { 310 rv = pfh->pfil_func(ip6, sizeof(*ip6), 311 m->m_pkthdr.rcvif, 0, &m0); 312 if (rv) 313 return; 314 m = m0; 315 if (m == NULL) 316 return; 317 ip6 = mtod(m, struct ip6_hdr *); 318 } 319 #endif /* PFIL_HOOKS */ 320 321 322 ip6stat.ip6s_nxthist[ip6->ip6_nxt]++; 323 324 #ifdef IPV6FIREWALL 325 /* 326 * Check with the firewall... 327 */ 328 if (ip6_fw_chk_ptr) { 329 u_short port = 0; 330 /* If ipfw says divert, we have to just drop packet */ 331 /* use port as a dummy argument */ 332 if ((*ip6_fw_chk_ptr)(&ip6, NULL, &port, &m)) { 333 m_freem(m); 334 m = NULL; 335 } 336 if (!m) 337 return; 338 } 339 #endif 340 341 /* 342 * Scope check 343 */ 344 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src) || 345 IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst)) { 346 ip6stat.ip6s_badscope++; 347 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); 348 goto bad; 349 } 350 /* 351 * The following check is not documented in the spec. Malicious party 352 * may be able to use IPv4 mapped addr to confuse tcp/udp stack and 353 * bypass security checks (act as if it was from 127.0.0.1 by using 354 * IPv6 src ::ffff:127.0.0.1). Be cautious. 355 */ 356 if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || 357 IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { 358 ip6stat.ip6s_badscope++; 359 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); 360 goto bad; 361 } 362 #if 0 363 /* 364 * Reject packets with IPv4 compatible addresses (auto tunnel). 365 * 366 * The code forbids auto tunnel relay case in RFC1933 (the check is 367 * stronger than RFC1933). We may want to re-enable it if mech-xx 368 * is revised to forbid relaying case. 369 */ 370 if (IN6_IS_ADDR_V4COMPAT(&ip6->ip6_src) || 371 IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) { 372 ip6stat.ip6s_badscope++; 373 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); 374 goto bad; 375 } 376 #endif 377 if (IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) || 378 IN6_IS_ADDR_LOOPBACK(&ip6->ip6_dst)) { 379 if (m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) { 380 ours = 1; 381 deliverifp = m->m_pkthdr.rcvif; 382 goto hbhcheck; 383 } else { 384 ip6stat.ip6s_badscope++; 385 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); 386 goto bad; 387 } 388 } 389 390 #ifndef FAKE_LOOPBACK_IF 391 if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) 392 #else 393 if (1) 394 #endif 395 { 396 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) 397 ip6->ip6_src.s6_addr16[1] 398 = htons(m->m_pkthdr.rcvif->if_index); 399 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) 400 ip6->ip6_dst.s6_addr16[1] 401 = htons(m->m_pkthdr.rcvif->if_index); 402 } 403 404 /* 405 * XXX we need this since we do not have "goto ours" hack route 406 * for some of our ifaddrs on loopback interface. 407 * we should correct it by changing in6_ifattach to install 408 * "goto ours" hack route. 409 */ 410 if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) != 0) { 411 if (IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_dst)) { 412 ours = 1; 413 deliverifp = m->m_pkthdr.rcvif; 414 goto hbhcheck; 415 } 416 } 417 418 /* 419 * Multicast check 420 */ 421 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { 422 struct in6_multi *in6m = 0; 423 424 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mcast); 425 /* 426 * See if we belong to the destination multicast group on the 427 * arrival interface. 428 */ 429 IN6_LOOKUP_MULTI(ip6->ip6_dst, m->m_pkthdr.rcvif, in6m); 430 if (in6m) 431 ours = 1; 432 else if (!ip6_mrouter) { 433 ip6stat.ip6s_notmember++; 434 ip6stat.ip6s_cantforward++; 435 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); 436 goto bad; 437 } 438 deliverifp = m->m_pkthdr.rcvif; 439 goto hbhcheck; 440 } 441 442 /* 443 * Unicast check 444 */ 445 if (ip6_forward_rt.ro_rt != NULL && 446 (ip6_forward_rt.ro_rt->rt_flags & RTF_UP) != 0 && 447 IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, 448 &ip6_forward_rt.ro_dst.sin6_addr)) 449 ip6stat.ip6s_forward_cachehit++; 450 else { 451 if (ip6_forward_rt.ro_rt) { 452 /* route is down or destination is different */ 453 ip6stat.ip6s_forward_cachemiss++; 454 RTFREE(ip6_forward_rt.ro_rt); 455 ip6_forward_rt.ro_rt = 0; 456 } 457 458 bzero(&ip6_forward_rt.ro_dst, sizeof(struct sockaddr_in6)); 459 ip6_forward_rt.ro_dst.sin6_len = sizeof(struct sockaddr_in6); 460 ip6_forward_rt.ro_dst.sin6_family = AF_INET6; 461 ip6_forward_rt.ro_dst.sin6_addr = ip6->ip6_dst; 462 463 rtalloc((struct route *)&ip6_forward_rt); 464 } 465 466 #define rt6_key(r) ((struct sockaddr_in6 *)((r)->rt_nodes->rn_key)) 467 468 /* 469 * Accept the packet if the forwarding interface to the destination 470 * according to the routing table is the loopback interface, 471 * unless the associated route has a gateway. 472 * Note that this approach causes to accept a packet if there is a 473 * route to the loopback interface for the destination of the packet. 474 * But we think it's even useful in some situations, e.g. when using 475 * a special daemon which wants to intercept the packet. 476 */ 477 if (ip6_forward_rt.ro_rt && 478 (ip6_forward_rt.ro_rt->rt_flags & 479 (RTF_HOST|RTF_GATEWAY)) == RTF_HOST && 480 #if 0 481 /* 482 * The check below is redundant since the comparison of 483 * the destination and the key of the rtentry has 484 * already done through looking up the routing table. 485 */ 486 IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, 487 &rt6_key(ip6_forward_rt.ro_rt)->sin6_addr) && 488 #endif 489 ip6_forward_rt.ro_rt->rt_ifp->if_type == IFT_LOOP) { 490 struct in6_ifaddr *ia6 = 491 (struct in6_ifaddr *)ip6_forward_rt.ro_rt->rt_ifa; 492 if (ia6->ia6_flags & IN6_IFF_ANYCAST) 493 m->m_flags |= M_ANYCAST6; 494 /* 495 * packets to a tentative, duplicated, or somehow invalid 496 * address must not be accepted. 497 */ 498 if (!(ia6->ia6_flags & IN6_IFF_NOTREADY)) { 499 /* this address is ready */ 500 ours = 1; 501 deliverifp = ia6->ia_ifp; /* correct? */ 502 goto hbhcheck; 503 } else { 504 /* address is not ready, so discard the packet. */ 505 log(LOG_INFO, 506 "ip6_input: packet to an unready address %s->%s", 507 ip6_sprintf(&ip6->ip6_src), 508 ip6_sprintf(&ip6->ip6_dst)); 509 510 goto bad; 511 } 512 } 513 514 /* 515 * FAITH(Firewall Aided Internet Translator) 516 */ 517 #if defined(NFAITH) && 0 < NFAITH 518 if (ip6_keepfaith) { 519 if (ip6_forward_rt.ro_rt && ip6_forward_rt.ro_rt->rt_ifp 520 && ip6_forward_rt.ro_rt->rt_ifp->if_type == IFT_FAITH) { 521 /* XXX do we need more sanity checks? */ 522 ours = 1; 523 deliverifp = ip6_forward_rt.ro_rt->rt_ifp; /*faith*/ 524 goto hbhcheck; 525 } 526 } 527 #endif 528 529 #if 0 530 { 531 /* 532 * Last resort: check in6_ifaddr for incoming interface. 533 * The code is here until I update the "goto ours hack" code above 534 * working right. 535 */ 536 struct ifaddr *ifa; 537 for (ifa = m->m_pkthdr.rcvif->if_addrlist.tqh_first; 538 ifa; 539 ifa = ifa->ifa_list.tqe_next) { 540 if (ifa->ifa_addr == NULL) 541 continue; /* just for safety */ 542 if (ifa->ifa_addr->sa_family != AF_INET6) 543 continue; 544 if (IN6_ARE_ADDR_EQUAL(IFA_IN6(ifa), &ip6->ip6_dst)) { 545 ours = 1; 546 deliverifp = ifa->ifa_ifp; 547 goto hbhcheck; 548 } 549 } 550 } 551 #endif 552 553 /* 554 * Now there is no reason to process the packet if it's not our own 555 * and we're not a router. 556 */ 557 if (!ip6_forwarding) { 558 ip6stat.ip6s_cantforward++; 559 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); 560 goto bad; 561 } 562 563 hbhcheck: 564 /* 565 * Process Hop-by-Hop options header if it's contained. 566 * m may be modified in ip6_hopopts_input(). 567 * If a JumboPayload option is included, plen will also be modified. 568 */ 569 plen = (u_int32_t)ntohs(ip6->ip6_plen); 570 if (ip6->ip6_nxt == IPPROTO_HOPOPTS) { 571 struct ip6_hbh *hbh; 572 573 if (ip6_hopopts_input(&plen, &rtalert, &m, &off)) { 574 #if 0 /*touches NULL pointer*/ 575 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); 576 #endif 577 return; /* m have already been freed */ 578 } 579 580 /* adjust pointer */ 581 ip6 = mtod(m, struct ip6_hdr *); 582 583 /* 584 * if the payload length field is 0 and the next header field 585 * indicates Hop-by-Hop Options header, then a Jumbo Payload 586 * option MUST be included. 587 */ 588 if (ip6->ip6_plen == 0 && plen == 0) { 589 /* 590 * Note that if a valid jumbo payload option is 591 * contained, ip6_hoptops_input() must set a valid 592 * (non-zero) payload length to the variable plen. 593 */ 594 ip6stat.ip6s_badoptions++; 595 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); 596 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); 597 icmp6_error(m, ICMP6_PARAM_PROB, 598 ICMP6_PARAMPROB_HEADER, 599 (caddr_t)&ip6->ip6_plen - (caddr_t)ip6); 600 return; 601 } 602 #ifndef PULLDOWN_TEST 603 /* ip6_hopopts_input() ensures that mbuf is contiguous */ 604 hbh = (struct ip6_hbh *)(ip6 + 1); 605 #else 606 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr), 607 sizeof(struct ip6_hbh)); 608 if (hbh == NULL) { 609 ip6stat.ip6s_tooshort++; 610 return; 611 } 612 #endif 613 nxt = hbh->ip6h_nxt; 614 615 /* 616 * accept the packet if a router alert option is included 617 * and we act as an IPv6 router. 618 */ 619 if (rtalert != ~0 && ip6_forwarding) 620 ours = 1; 621 } else 622 nxt = ip6->ip6_nxt; 623 624 /* 625 * Check that the amount of data in the buffers 626 * is as at least much as the IPv6 header would have us expect. 627 * Trim mbufs if longer than we expect. 628 * Drop packet if shorter than we expect. 629 */ 630 if (m->m_pkthdr.len - sizeof(struct ip6_hdr) < plen) { 631 ip6stat.ip6s_tooshort++; 632 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated); 633 goto bad; 634 } 635 if (m->m_pkthdr.len > sizeof(struct ip6_hdr) + plen) { 636 if (m->m_len == m->m_pkthdr.len) { 637 m->m_len = sizeof(struct ip6_hdr) + plen; 638 m->m_pkthdr.len = sizeof(struct ip6_hdr) + plen; 639 } else 640 m_adj(m, sizeof(struct ip6_hdr) + plen - m->m_pkthdr.len); 641 } 642 643 /* 644 * Forward if desirable. 645 */ 646 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { 647 /* 648 * If we are acting as a multicast router, all 649 * incoming multicast packets are passed to the 650 * kernel-level multicast forwarding function. 651 * The packet is returned (relatively) intact; if 652 * ip6_mforward() returns a non-zero value, the packet 653 * must be discarded, else it may be accepted below. 654 */ 655 if (ip6_mrouter && ip6_mforward(ip6, m->m_pkthdr.rcvif, m)) { 656 ip6stat.ip6s_cantforward++; 657 m_freem(m); 658 return; 659 } 660 if (!ours) { 661 m_freem(m); 662 return; 663 } 664 } else if (!ours) { 665 ip6_forward(m, 0); 666 return; 667 } 668 669 ip6 = mtod(m, struct ip6_hdr *); 670 671 /* 672 * Malicious party may be able to use IPv4 mapped addr to confuse 673 * tcp/udp stack and bypass security checks (act as if it was from 674 * 127.0.0.1 by using IPv6 src ::ffff:127.0.0.1). Be cautious. 675 * 676 * For SIIT end node behavior, you may want to disable the check. 677 * However, you will become vulnerable to attacks using IPv4 mapped 678 * source. 679 */ 680 if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || 681 IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { 682 ip6stat.ip6s_badscope++; 683 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); 684 goto bad; 685 } 686 687 /* 688 * Tell launch routine the next header 689 */ 690 #ifdef IFA_STATS 691 if (IFA_STATS && deliverifp != NULL) { 692 struct in6_ifaddr *ia6; 693 ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst); 694 if (ia6) 695 ia6->ia_ifa.ifa_data.ifad_inbytes += m->m_pkthdr.len; 696 } 697 #endif 698 ip6stat.ip6s_delivered++; 699 in6_ifstat_inc(deliverifp, ifs6_in_deliver); 700 nest = 0; 701 while (nxt != IPPROTO_DONE) { 702 if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) { 703 ip6stat.ip6s_toomanyhdr++; 704 goto bad; 705 } 706 707 /* 708 * protection against faulty packet - there should be 709 * more sanity checks in header chain processing. 710 */ 711 if (m->m_pkthdr.len < off) { 712 ip6stat.ip6s_tooshort++; 713 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated); 714 goto bad; 715 } 716 717 nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt); 718 } 719 return; 720 bad: 721 m_freem(m); 722 } 723 724 /* 725 * Hop-by-Hop options header processing. If a valid jumbo payload option is 726 * included, the real payload length will be stored in plenp. 727 */ 728 static int 729 ip6_hopopts_input(plenp, rtalertp, mp, offp) 730 u_int32_t *plenp; 731 u_int32_t *rtalertp; /* XXX: should be stored more smart way */ 732 struct mbuf **mp; 733 int *offp; 734 { 735 register struct mbuf *m = *mp; 736 int off = *offp, hbhlen; 737 struct ip6_hbh *hbh; 738 u_int8_t *opt; 739 740 /* validation of the length of the header */ 741 #ifndef PULLDOWN_TEST 742 IP6_EXTHDR_CHECK(m, off, sizeof(*hbh), -1); 743 hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off); 744 hbhlen = (hbh->ip6h_len + 1) << 3; 745 746 IP6_EXTHDR_CHECK(m, off, hbhlen, -1); 747 hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off); 748 #else 749 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, 750 sizeof(struct ip6_hdr), sizeof(struct ip6_hbh)); 751 if (hbh == NULL) { 752 ip6stat.ip6s_tooshort++; 753 return -1; 754 } 755 hbhlen = (hbh->ip6h_len + 1) << 3; 756 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr), 757 hbhlen); 758 if (hbh == NULL) { 759 ip6stat.ip6s_tooshort++; 760 return -1; 761 } 762 #endif 763 off += hbhlen; 764 hbhlen -= sizeof(struct ip6_hbh); 765 opt = (u_int8_t *)hbh + sizeof(struct ip6_hbh); 766 767 if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh), 768 hbhlen, rtalertp, plenp) < 0) 769 return(-1); 770 771 *offp = off; 772 *mp = m; 773 return(0); 774 } 775 776 /* 777 * Search header for all Hop-by-hop options and process each option. 778 * This function is separate from ip6_hopopts_input() in order to 779 * handle a case where the sending node itself process its hop-by-hop 780 * options header. In such a case, the function is called from ip6_output(). 781 */ 782 int 783 ip6_process_hopopts(m, opthead, hbhlen, rtalertp, plenp) 784 struct mbuf *m; 785 u_int8_t *opthead; 786 int hbhlen; 787 u_int32_t *rtalertp; 788 u_int32_t *plenp; 789 { 790 struct ip6_hdr *ip6; 791 int optlen = 0; 792 u_int8_t *opt = opthead; 793 u_int16_t rtalert_val; 794 u_int32_t jumboplen; 795 796 for (; hbhlen > 0; hbhlen -= optlen, opt += optlen) { 797 switch(*opt) { 798 case IP6OPT_PAD1: 799 optlen = 1; 800 break; 801 case IP6OPT_PADN: 802 if (hbhlen < IP6OPT_MINLEN) { 803 ip6stat.ip6s_toosmall++; 804 goto bad; 805 } 806 optlen = *(opt + 1) + 2; 807 break; 808 case IP6OPT_RTALERT: 809 /* XXX may need check for alignment */ 810 if (hbhlen < IP6OPT_RTALERT_LEN) { 811 ip6stat.ip6s_toosmall++; 812 goto bad; 813 } 814 if (*(opt + 1) != IP6OPT_RTALERT_LEN - 2) 815 /* XXX: should we discard the packet? */ 816 log(LOG_ERR, "length of router alert opt is inconsitent(%d)", 817 *(opt + 1)); 818 optlen = IP6OPT_RTALERT_LEN; 819 bcopy((caddr_t)(opt + 2), (caddr_t)&rtalert_val, 2); 820 *rtalertp = ntohs(rtalert_val); 821 break; 822 case IP6OPT_JUMBO: 823 /* XXX may need check for alignment */ 824 if (hbhlen < IP6OPT_JUMBO_LEN) { 825 ip6stat.ip6s_toosmall++; 826 goto bad; 827 } 828 if (*(opt + 1) != IP6OPT_JUMBO_LEN - 2) 829 /* XXX: should we discard the packet? */ 830 log(LOG_ERR, "length of jumbopayload opt " 831 "is inconsistent(%d)", 832 *(opt + 1)); 833 optlen = IP6OPT_JUMBO_LEN; 834 835 /* 836 * IPv6 packets that have non 0 payload length 837 * must not contain a jumbo paylod option. 838 */ 839 ip6 = mtod(m, struct ip6_hdr *); 840 if (ip6->ip6_plen) { 841 ip6stat.ip6s_badoptions++; 842 icmp6_error(m, ICMP6_PARAM_PROB, 843 ICMP6_PARAMPROB_HEADER, 844 sizeof(struct ip6_hdr) + 845 sizeof(struct ip6_hbh) + 846 opt - opthead); 847 return(-1); 848 } 849 850 /* 851 * We may see jumbolen in unaligned location, so 852 * we'd need to perform bcopy(). 853 */ 854 bcopy(opt + 2, &jumboplen, sizeof(jumboplen)); 855 jumboplen = (u_int32_t)htonl(jumboplen); 856 857 #if 1 858 /* 859 * if there are multiple jumbo payload options, 860 * *plenp will be non-zero and the packet will be 861 * rejected. 862 * the behavior may need some debate in ipngwg - 863 * multiple options does not make sense, however, 864 * there's no explicit mention in specification. 865 */ 866 if (*plenp != 0) { 867 ip6stat.ip6s_badoptions++; 868 icmp6_error(m, ICMP6_PARAM_PROB, 869 ICMP6_PARAMPROB_HEADER, 870 sizeof(struct ip6_hdr) + 871 sizeof(struct ip6_hbh) + 872 opt + 2 - opthead); 873 return(-1); 874 } 875 #endif 876 877 /* 878 * jumbo payload length must be larger than 65535. 879 */ 880 if (jumboplen <= IPV6_MAXPACKET) { 881 ip6stat.ip6s_badoptions++; 882 icmp6_error(m, ICMP6_PARAM_PROB, 883 ICMP6_PARAMPROB_HEADER, 884 sizeof(struct ip6_hdr) + 885 sizeof(struct ip6_hbh) + 886 opt + 2 - opthead); 887 return(-1); 888 } 889 *plenp = jumboplen; 890 891 break; 892 default: /* unknown option */ 893 if (hbhlen < IP6OPT_MINLEN) { 894 ip6stat.ip6s_toosmall++; 895 goto bad; 896 } 897 if ((optlen = ip6_unknown_opt(opt, m, 898 sizeof(struct ip6_hdr) + 899 sizeof(struct ip6_hbh) + 900 opt - opthead)) == -1) 901 return(-1); 902 optlen += 2; 903 break; 904 } 905 } 906 907 return(0); 908 909 bad: 910 m_freem(m); 911 return(-1); 912 } 913 914 /* 915 * Unknown option processing. 916 * The third argument `off' is the offset from the IPv6 header to the option, 917 * which is necessary if the IPv6 header the and option header and IPv6 header 918 * is not continuous in order to return an ICMPv6 error. 919 */ 920 int 921 ip6_unknown_opt(optp, m, off) 922 u_int8_t *optp; 923 struct mbuf *m; 924 int off; 925 { 926 struct ip6_hdr *ip6; 927 928 switch(IP6OPT_TYPE(*optp)) { 929 case IP6OPT_TYPE_SKIP: /* ignore the option */ 930 return((int)*(optp + 1)); 931 case IP6OPT_TYPE_DISCARD: /* silently discard */ 932 m_freem(m); 933 return(-1); 934 case IP6OPT_TYPE_FORCEICMP: /* send ICMP even if multicasted */ 935 ip6stat.ip6s_badoptions++; 936 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, off); 937 return(-1); 938 case IP6OPT_TYPE_ICMP: /* send ICMP if not multicasted */ 939 ip6stat.ip6s_badoptions++; 940 ip6 = mtod(m, struct ip6_hdr *); 941 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || 942 (m->m_flags & (M_BCAST|M_MCAST))) 943 m_freem(m); 944 else 945 icmp6_error(m, ICMP6_PARAM_PROB, 946 ICMP6_PARAMPROB_OPTION, off); 947 return(-1); 948 } 949 950 m_freem(m); /* XXX: NOTREACHED */ 951 return(-1); 952 } 953 954 /* 955 * Create the "control" list for this pcb. 956 * 957 * The routine will be called from upper layer handlers like tcp6_input(). 958 * Thus the routine assumes that the caller (tcp6_input) have already 959 * called IP6_EXTHDR_CHECK() and all the extension headers are located in the 960 * very first mbuf on the mbuf chain. 961 * We may want to add some infinite loop prevention or sanity checks for safety. 962 * (This applies only when you are using KAME mbuf chain restriction, i.e. 963 * you are using IP6_EXTHDR_CHECK() not m_pulldown()) 964 */ 965 void 966 ip6_savecontrol(in6p, mp, ip6, m) 967 register struct in6pcb *in6p; 968 register struct mbuf **mp; 969 register struct ip6_hdr *ip6; 970 register struct mbuf *m; 971 { 972 struct proc *p = curproc; /* XXX */ 973 int privileged; 974 975 privileged = 0; 976 if (p && !suser(p->p_ucred, &p->p_acflag)) 977 privileged++; 978 979 #ifdef SO_TIMESTAMP 980 if (in6p->in6p_socket->so_options & SO_TIMESTAMP) { 981 struct timeval tv; 982 983 microtime(&tv); 984 *mp = sbcreatecontrol((caddr_t) &tv, sizeof(tv), 985 SCM_TIMESTAMP, SOL_SOCKET); 986 if (*mp) 987 mp = &(*mp)->m_next; 988 } 989 #endif 990 if (in6p->in6p_flags & IN6P_RECVDSTADDR) { 991 *mp = sbcreatecontrol((caddr_t) &ip6->ip6_dst, 992 sizeof(struct in6_addr), IPV6_RECVDSTADDR, 993 IPPROTO_IPV6); 994 if (*mp) 995 mp = &(*mp)->m_next; 996 } 997 998 #ifdef noyet 999 /* options were tossed above */ 1000 if (in6p->in6p_flags & IN6P_RECVOPTS) 1001 /* broken */ 1002 /* ip6_srcroute doesn't do what we want here, need to fix */ 1003 if (in6p->in6p_flags & IPV6P_RECVRETOPTS) 1004 /* broken */ 1005 #endif 1006 1007 /* RFC 2292 sec. 5 */ 1008 if (in6p->in6p_flags & IN6P_PKTINFO) { 1009 struct in6_pktinfo pi6; 1010 bcopy(&ip6->ip6_dst, &pi6.ipi6_addr, sizeof(struct in6_addr)); 1011 if (IN6_IS_SCOPE_LINKLOCAL(&pi6.ipi6_addr)) 1012 pi6.ipi6_addr.s6_addr16[1] = 0; 1013 pi6.ipi6_ifindex = (m && m->m_pkthdr.rcvif) 1014 ? m->m_pkthdr.rcvif->if_index 1015 : 0; 1016 *mp = sbcreatecontrol((caddr_t) &pi6, 1017 sizeof(struct in6_pktinfo), IPV6_PKTINFO, 1018 IPPROTO_IPV6); 1019 if (*mp) 1020 mp = &(*mp)->m_next; 1021 } 1022 if (in6p->in6p_flags & IN6P_HOPLIMIT) { 1023 int hlim = ip6->ip6_hlim & 0xff; 1024 *mp = sbcreatecontrol((caddr_t) &hlim, 1025 sizeof(int), IPV6_HOPLIMIT, IPPROTO_IPV6); 1026 if (*mp) 1027 mp = &(*mp)->m_next; 1028 } 1029 /* IN6P_NEXTHOP - for outgoing packet only */ 1030 1031 /* 1032 * IPV6_HOPOPTS socket option. We require super-user privilege 1033 * for the option, but it might be too strict, since there might 1034 * be some hop-by-hop options which can be returned to normal user. 1035 * See RFC 2292 section 6. 1036 */ 1037 if ((in6p->in6p_flags & IN6P_HOPOPTS) && privileged) { 1038 /* 1039 * Check if a hop-by-hop options header is contatined in the 1040 * received packet, and if so, store the options as ancillary 1041 * data. Note that a hop-by-hop options header must be 1042 * just after the IPv6 header, which fact is assured through 1043 * the IPv6 input processing. 1044 */ 1045 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 1046 if (ip6->ip6_nxt == IPPROTO_HOPOPTS) { 1047 struct ip6_hbh *hbh; 1048 int hbhlen; 1049 1050 #ifndef PULLDOWN_TEST 1051 hbh = (struct ip6_hbh *)(ip6 + 1); 1052 hbhlen = (hbh->ip6h_len + 1) << 3; 1053 #else 1054 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, 1055 sizeof(struct ip6_hdr), sizeof(struct ip6_hbh)); 1056 if (hbh == NULL) { 1057 ip6stat.ip6s_tooshort++; 1058 return; 1059 } 1060 hbhlen = (hbh->ip6h_len + 1) << 3; 1061 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, 1062 sizeof(struct ip6_hdr), hbhlen); 1063 if (hbh == NULL) { 1064 ip6stat.ip6s_tooshort++; 1065 return; 1066 } 1067 #endif 1068 1069 /* 1070 * XXX: We copy whole the header even if a jumbo 1071 * payload option is included, which option is to 1072 * be removed before returning in the RFC 2292. 1073 * But it's too painful operation... 1074 */ 1075 *mp = sbcreatecontrol((caddr_t)hbh, hbhlen, 1076 IPV6_HOPOPTS, IPPROTO_IPV6); 1077 if (*mp) 1078 mp = &(*mp)->m_next; 1079 } 1080 } 1081 1082 /* IPV6_DSTOPTS and IPV6_RTHDR socket options */ 1083 if (in6p->in6p_flags & (IN6P_DSTOPTS | IN6P_RTHDR)) { 1084 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 1085 int nxt = ip6->ip6_nxt, off = sizeof(struct ip6_hdr);; 1086 1087 /* 1088 * Search for destination options headers or routing 1089 * header(s) through the header chain, and stores each 1090 * header as ancillary data. 1091 * Note that the order of the headers remains in 1092 * the chain of ancillary data. 1093 */ 1094 while(1) { /* is explicit loop prevention necessary? */ 1095 struct ip6_ext *ip6e; 1096 int elen; 1097 1098 #ifndef PULLDOWN_TEST 1099 ip6e = (struct ip6_ext *)(mtod(m, caddr_t) + off); 1100 if (nxt == IPPROTO_AH) 1101 elen = (ip6e->ip6e_len + 2) << 2; 1102 else 1103 elen = (ip6e->ip6e_len + 1) << 3; 1104 #else 1105 IP6_EXTHDR_GET(ip6e, struct ip6_ext *, m, off, 1106 sizeof(struct ip6_ext)); 1107 if (ip6e == NULL) { 1108 ip6stat.ip6s_tooshort++; 1109 return; 1110 } 1111 if (nxt == IPPROTO_AH) 1112 elen = (ip6e->ip6e_len + 2) << 2; 1113 else 1114 elen = (ip6e->ip6e_len + 1) << 3; 1115 IP6_EXTHDR_GET(ip6e, struct ip6_ext *, m, off, elen); 1116 if (ip6e == NULL) { 1117 ip6stat.ip6s_tooshort++; 1118 return; 1119 } 1120 #endif 1121 1122 switch(nxt) { 1123 case IPPROTO_DSTOPTS: 1124 if (!in6p->in6p_flags & IN6P_DSTOPTS) 1125 break; 1126 1127 /* 1128 * We also require super-user privilege for 1129 * the option. 1130 * See the comments on IN6_HOPOPTS. 1131 */ 1132 if (!privileged) 1133 break; 1134 1135 *mp = sbcreatecontrol((caddr_t)ip6e, elen, 1136 IPV6_DSTOPTS, 1137 IPPROTO_IPV6); 1138 if (*mp) 1139 mp = &(*mp)->m_next; 1140 break; 1141 1142 case IPPROTO_ROUTING: 1143 if (!in6p->in6p_flags & IN6P_RTHDR) 1144 break; 1145 1146 *mp = sbcreatecontrol((caddr_t)ip6e, elen, 1147 IPV6_RTHDR, 1148 IPPROTO_IPV6); 1149 if (*mp) 1150 mp = &(*mp)->m_next; 1151 break; 1152 1153 case IPPROTO_UDP: 1154 case IPPROTO_TCP: 1155 case IPPROTO_ICMPV6: 1156 default: 1157 /* 1158 * stop search if we encounter an upper 1159 * layer protocol headers. 1160 */ 1161 goto loopend; 1162 1163 case IPPROTO_HOPOPTS: 1164 case IPPROTO_AH: /* is it possible? */ 1165 break; 1166 } 1167 1168 /* proceed with the next header. */ 1169 off += elen; 1170 nxt = ip6e->ip6e_nxt; 1171 } 1172 loopend: 1173 } 1174 if ((in6p->in6p_flags & IN6P_HOPOPTS) && privileged) { 1175 /* to be done */ 1176 } 1177 if ((in6p->in6p_flags & IN6P_DSTOPTS) && privileged) { 1178 /* to be done */ 1179 } 1180 /* IN6P_RTHDR - to be done */ 1181 1182 } 1183 1184 /* 1185 * Get pointer to the previous header followed by the header 1186 * currently processed. 1187 * XXX: This function supposes that 1188 * M includes all headers, 1189 * the next header field and the header length field of each header 1190 * are valid, and 1191 * the sum of each header length equals to OFF. 1192 * Because of these assumptions, this function must be called very 1193 * carefully. Moreover, it will not be used in the near future when 1194 * we develop `neater' mechanism to process extension headers. 1195 */ 1196 char * 1197 ip6_get_prevhdr(m, off) 1198 struct mbuf *m; 1199 int off; 1200 { 1201 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 1202 1203 if (off == sizeof(struct ip6_hdr)) 1204 return(&ip6->ip6_nxt); 1205 else { 1206 int len, nxt; 1207 struct ip6_ext *ip6e = NULL; 1208 1209 nxt = ip6->ip6_nxt; 1210 len = sizeof(struct ip6_hdr); 1211 while (len < off) { 1212 ip6e = (struct ip6_ext *)(mtod(m, caddr_t) + len); 1213 1214 switch(nxt) { 1215 case IPPROTO_FRAGMENT: 1216 len += sizeof(struct ip6_frag); 1217 break; 1218 case IPPROTO_AH: 1219 len += (ip6e->ip6e_len + 2) << 2; 1220 break; 1221 default: 1222 len += (ip6e->ip6e_len + 1) << 3; 1223 break; 1224 } 1225 nxt = ip6e->ip6e_nxt; 1226 } 1227 if (ip6e) 1228 return(&ip6e->ip6e_nxt); 1229 else 1230 return NULL; 1231 } 1232 } 1233 1234 /* 1235 * get next header offset. m will be retained. 1236 */ 1237 int 1238 ip6_nexthdr(m, off, proto, nxtp) 1239 struct mbuf *m; 1240 int off; 1241 int proto; 1242 int *nxtp; 1243 { 1244 struct ip6_hdr ip6; 1245 struct ip6_ext ip6e; 1246 struct ip6_frag fh; 1247 1248 /* just in case */ 1249 if (m == NULL) 1250 panic("ip6_nexthdr: m == NULL"); 1251 if ((m->m_flags & M_PKTHDR) == 0 || m->m_pkthdr.len < off) 1252 return -1; 1253 1254 switch (proto) { 1255 case IPPROTO_IPV6: 1256 if (m->m_pkthdr.len < off + sizeof(ip6)) 1257 return -1; 1258 m_copydata(m, off, sizeof(ip6), (caddr_t)&ip6); 1259 if (nxtp) 1260 *nxtp = ip6.ip6_nxt; 1261 off += sizeof(ip6); 1262 return off; 1263 1264 case IPPROTO_FRAGMENT: 1265 /* 1266 * terminate parsing if it is not the first fragment, 1267 * it does not make sense to parse through it. 1268 */ 1269 if (m->m_pkthdr.len < off + sizeof(fh)) 1270 return -1; 1271 m_copydata(m, off, sizeof(fh), (caddr_t)&fh); 1272 if ((ntohs(fh.ip6f_offlg) & IP6F_OFF_MASK) != 0) 1273 return -1; 1274 if (nxtp) 1275 *nxtp = fh.ip6f_nxt; 1276 off += sizeof(struct ip6_frag); 1277 return off; 1278 1279 case IPPROTO_AH: 1280 if (m->m_pkthdr.len < off + sizeof(ip6e)) 1281 return -1; 1282 m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e); 1283 if (nxtp) 1284 *nxtp = ip6e.ip6e_nxt; 1285 off += (ip6e.ip6e_len + 2) << 2; 1286 return off; 1287 1288 case IPPROTO_HOPOPTS: 1289 case IPPROTO_ROUTING: 1290 case IPPROTO_DSTOPTS: 1291 if (m->m_pkthdr.len < off + sizeof(ip6e)) 1292 return -1; 1293 m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e); 1294 if (nxtp) 1295 *nxtp = ip6e.ip6e_nxt; 1296 off += (ip6e.ip6e_len + 1) << 3; 1297 return off; 1298 1299 case IPPROTO_NONE: 1300 case IPPROTO_ESP: 1301 case IPPROTO_IPCOMP: 1302 /* give up */ 1303 return -1; 1304 1305 default: 1306 return -1; 1307 } 1308 1309 return -1; 1310 } 1311 1312 /* 1313 * get offset for the last header in the chain. m will be kept untainted. 1314 */ 1315 int 1316 ip6_lasthdr(m, off, proto, nxtp) 1317 struct mbuf *m; 1318 int off; 1319 int proto; 1320 int *nxtp; 1321 { 1322 int newoff; 1323 int nxt; 1324 1325 if (!nxtp) { 1326 nxt = -1; 1327 nxtp = &nxt; 1328 } 1329 while (1) { 1330 newoff = ip6_nexthdr(m, off, proto, nxtp); 1331 if (newoff < 0) 1332 return off; 1333 else if (newoff < off) 1334 return -1; /* invalid */ 1335 else if (newoff == off) 1336 return newoff; 1337 1338 off = newoff; 1339 proto = *nxtp; 1340 } 1341 } 1342 1343 /* 1344 * System control for IP6 1345 */ 1346 1347 u_char inet6ctlerrmap[PRC_NCMDS] = { 1348 0, 0, 0, 0, 1349 0, EMSGSIZE, EHOSTDOWN, EHOSTUNREACH, 1350 EHOSTUNREACH, EHOSTUNREACH, ECONNREFUSED, ECONNREFUSED, 1351 EMSGSIZE, EHOSTUNREACH, 0, 0, 1352 0, 0, 0, 0, 1353 ENOPROTOOPT 1354 }; 1355 1356 #include <uvm/uvm_extern.h> 1357 #include <sys/sysctl.h> 1358 1359 int 1360 ip6_sysctl(name, namelen, oldp, oldlenp, newp, newlen) 1361 int *name; 1362 u_int namelen; 1363 void *oldp; 1364 size_t *oldlenp; 1365 void *newp; 1366 size_t newlen; 1367 { 1368 /* All sysctl names at this level are terminal. */ 1369 if (namelen != 1) 1370 return ENOTDIR; 1371 1372 switch (name[0]) { 1373 1374 case IPV6CTL_FORWARDING: 1375 return sysctl_int(oldp, oldlenp, newp, newlen, 1376 &ip6_forwarding); 1377 case IPV6CTL_SENDREDIRECTS: 1378 return sysctl_int(oldp, oldlenp, newp, newlen, 1379 &ip6_sendredirects); 1380 case IPV6CTL_DEFHLIM: 1381 return sysctl_int(oldp, oldlenp, newp, newlen, &ip6_defhlim); 1382 case IPV6CTL_MAXFRAGPACKETS: 1383 return sysctl_int(oldp, oldlenp, newp, newlen, 1384 &ip6_maxfragpackets); 1385 case IPV6CTL_ACCEPT_RTADV: 1386 return sysctl_int(oldp, oldlenp, newp, newlen, 1387 &ip6_accept_rtadv); 1388 case IPV6CTL_KEEPFAITH: 1389 return sysctl_int(oldp, oldlenp, newp, newlen, &ip6_keepfaith); 1390 case IPV6CTL_LOG_INTERVAL: 1391 return sysctl_int(oldp, oldlenp, newp, newlen, 1392 &ip6_log_interval); 1393 case IPV6CTL_HDRNESTLIMIT: 1394 return sysctl_int(oldp, oldlenp, newp, newlen, 1395 &ip6_hdrnestlimit); 1396 case IPV6CTL_DAD_COUNT: 1397 return sysctl_int(oldp, oldlenp, newp, newlen, &ip6_dad_count); 1398 case IPV6CTL_AUTO_FLOWLABEL: 1399 return sysctl_int(oldp, oldlenp, newp, newlen, 1400 &ip6_auto_flowlabel); 1401 case IPV6CTL_DEFMCASTHLIM: 1402 return sysctl_int(oldp, oldlenp, newp, newlen, 1403 &ip6_defmcasthlim); 1404 case IPV6CTL_GIF_HLIM: 1405 return sysctl_int(oldp, oldlenp, newp, newlen, 1406 &ip6_gif_hlim); 1407 case IPV6CTL_KAME_VERSION: 1408 return sysctl_rdstring(oldp, oldlenp, newp, __KAME_VERSION); 1409 case IPV6CTL_USE_DEPRECATED: 1410 return sysctl_int(oldp, oldlenp, newp, newlen, 1411 &ip6_use_deprecated); 1412 case IPV6CTL_RR_PRUNE: 1413 return sysctl_int(oldp, oldlenp, newp, newlen, &ip6_rr_prune); 1414 #ifndef INET6_BINDV6ONLY 1415 case IPV6CTL_BINDV6ONLY: 1416 return sysctl_int(oldp, oldlenp, newp, newlen, 1417 &ip6_bindv6only); 1418 #endif 1419 default: 1420 return EOPNOTSUPP; 1421 } 1422 /* NOTREACHED */ 1423 } 1424