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