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