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