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