1 /* $FreeBSD: src/sys/netinet6/ip6_input.c,v 1.11.2.15 2003/01/24 05:11:35 sam Exp $ */ 2 /* $DragonFly: src/sys/netinet6/ip6_input.c,v 1.10 2003/11/08 07:57:51 dillon Exp $ */ 3 /* $KAME: ip6_input.c,v 1.259 2002/01/21 04:58:09 jinmei Exp $ */ 4 5 /* 6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the project nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 /* 35 * Copyright (c) 1982, 1986, 1988, 1993 36 * The Regents of the University of California. All rights reserved. 37 * 38 * Redistribution and use in source and binary forms, with or without 39 * modification, are permitted provided that the following conditions 40 * are met: 41 * 1. Redistributions of source code must retain the above copyright 42 * notice, this list of conditions and the following disclaimer. 43 * 2. Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in the 45 * documentation and/or other materials provided with the distribution. 46 * 3. All advertising materials mentioning features or use of this software 47 * must display the following acknowledgement: 48 * This product includes software developed by the University of 49 * California, Berkeley and its contributors. 50 * 4. Neither the name of the University nor the names of its contributors 51 * may be used to endorse or promote products derived from this software 52 * without specific prior written permission. 53 * 54 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 57 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 64 * SUCH DAMAGE. 65 * 66 * @(#)ip_input.c 8.2 (Berkeley) 1/4/94 67 */ 68 69 #include "opt_ip6fw.h" 70 #include "opt_inet.h" 71 #include "opt_inet6.h" 72 #include "opt_ipsec.h" 73 74 #include <sys/param.h> 75 #include <sys/systm.h> 76 #include <sys/malloc.h> 77 #include <sys/mbuf.h> 78 #include <sys/domain.h> 79 #include <sys/protosw.h> 80 #include <sys/socket.h> 81 #include <sys/socketvar.h> 82 #include <sys/errno.h> 83 #include <sys/time.h> 84 #include <sys/kernel.h> 85 #include <sys/syslog.h> 86 #include <sys/proc.h> 87 88 #include <net/if.h> 89 #include <net/if_types.h> 90 #include <net/if_dl.h> 91 #include <net/route.h> 92 #include <net/netisr.h> 93 94 #include <netinet/in.h> 95 #include <netinet/in_systm.h> 96 #ifdef INET 97 #include <netinet/ip.h> 98 #include <netinet/ip_icmp.h> 99 #endif /* INET */ 100 #include <netinet/ip6.h> 101 #include <netinet6/in6_var.h> 102 #include <netinet6/ip6_var.h> 103 #include <netinet/in_pcb.h> 104 #include <netinet/icmp6.h> 105 #include <netinet6/in6_ifattach.h> 106 #include <netinet6/nd6.h> 107 #include <netinet6/in6_prefix.h> 108 109 #ifdef IPSEC 110 #include <netinet6/ipsec.h> 111 #ifdef INET6 112 #include <netinet6/ipsec6.h> 113 #endif 114 #endif 115 116 #ifdef FAST_IPSEC 117 #include "ipsec.h" 118 #include "ipsec6.h" 119 #define IPSEC 120 #endif /* FAST_IPSEC */ 121 122 #include <net/ip6fw/ip6_fw.h> 123 124 #include <netinet6/ip6protosw.h> 125 126 /* we need it for NLOOP. */ 127 #include "use_loop.h" 128 129 #include <net/net_osdep.h> 130 131 extern int (*fr_checkp) (struct ip *, int, struct ifnet *, int, struct mbuf **); 132 133 extern struct domain inet6domain; 134 extern struct ip6protosw inet6sw[]; 135 136 u_char ip6_protox[IPPROTO_MAX]; 137 struct in6_ifaddr *in6_ifaddr; 138 139 extern struct callout in6_tmpaddrtimer_ch; 140 141 int ip6_forward_srcrt; /* XXX */ 142 int ip6_sourcecheck; /* XXX */ 143 int ip6_sourcecheck_interval; /* XXX */ 144 145 int ip6_ours_check_algorithm; 146 147 /* firewall hooks */ 148 ip6_fw_chk_t *ip6_fw_chk_ptr; 149 ip6_fw_ctl_t *ip6_fw_ctl_ptr; 150 int ip6_fw_enable = 1; 151 152 struct ip6stat ip6stat; 153 154 static void ip6_init2 (void *); 155 static struct ip6aux *ip6_setdstifaddr (struct mbuf *, struct in6_ifaddr *); 156 static int ip6_hopopts_input (u_int32_t *, u_int32_t *, struct mbuf **, int *); 157 #ifdef PULLDOWN_TEST 158 static struct mbuf *ip6_pullexthdr (struct mbuf *, size_t, int); 159 #endif 160 161 /* 162 * IP6 initialization: fill in IP6 protocol switch table. 163 * All protocols not implemented in kernel go to raw IP6 protocol handler. 164 */ 165 void 166 ip6_init() 167 { 168 struct ip6protosw *pr; 169 int i; 170 struct timeval tv; 171 172 #ifdef DIAGNOSTIC 173 if (sizeof(struct protosw) != sizeof(struct ip6protosw)) 174 panic("sizeof(protosw) != sizeof(ip6protosw)"); 175 #endif 176 pr = (struct ip6protosw *)pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW); 177 if (pr == 0) 178 panic("ip6_init"); 179 for (i = 0; i < IPPROTO_MAX; i++) 180 ip6_protox[i] = pr - inet6sw; 181 for (pr = (struct ip6protosw *)inet6domain.dom_protosw; 182 pr < (struct ip6protosw *)inet6domain.dom_protoswNPROTOSW; pr++) 183 if (pr->pr_domain->dom_family == PF_INET6 && 184 pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW) 185 ip6_protox[pr->pr_protocol] = pr - inet6sw; 186 netisr_register(NETISR_IPV6, cpu0_portfn, ip6_input); 187 nd6_init(); 188 frag6_init(); 189 /* 190 * in many cases, random() here does NOT return random number 191 * as initialization during bootstrap time occur in fixed order. 192 */ 193 microtime(&tv); 194 ip6_flow_seq = random() ^ tv.tv_usec; 195 microtime(&tv); 196 ip6_desync_factor = (random() ^ tv.tv_usec) % MAX_TEMP_DESYNC_FACTOR; 197 } 198 199 static void 200 ip6_init2(dummy) 201 void *dummy; 202 { 203 204 /* 205 * to route local address of p2p link to loopback, 206 * assign loopback address first. 207 */ 208 in6_ifattach(&loif[0], NULL); 209 210 /* nd6_timer_init */ 211 callout_init(&nd6_timer_ch); 212 callout_reset(&nd6_timer_ch, hz, nd6_timer, NULL); 213 214 /* router renumbering prefix list maintenance */ 215 callout_init(&in6_rr_timer_ch); 216 callout_reset(&in6_rr_timer_ch, hz, in6_rr_timer, NULL); 217 218 /* timer for regeneranation of temporary addresses randomize ID */ 219 callout_reset(&in6_tmpaddrtimer_ch, 220 (ip6_temp_preferred_lifetime - ip6_desync_factor - 221 ip6_temp_regen_advance) * hz, 222 in6_tmpaddrtimer, NULL); 223 } 224 225 /* cheat */ 226 /* This must be after route_init(), which is now SI_ORDER_THIRD */ 227 SYSINIT(netinet6init2, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE, ip6_init2, NULL); 228 229 extern struct route_in6 ip6_forward_rt; 230 231 void 232 ip6_input(m) 233 struct mbuf *m; 234 { 235 struct ip6_hdr *ip6; 236 int off = sizeof(struct ip6_hdr), nest; 237 u_int32_t plen; 238 u_int32_t rtalert = ~0; 239 int nxt, ours = 0; 240 struct ifnet *deliverifp = NULL; 241 242 #ifdef IPSEC 243 /* 244 * should the inner packet be considered authentic? 245 * see comment in ah4_input(). 246 */ 247 if (m) { 248 m->m_flags &= ~M_AUTHIPHDR; 249 m->m_flags &= ~M_AUTHIPDGM; 250 } 251 #endif 252 253 /* 254 * make sure we don't have onion peering information into m_aux. 255 */ 256 ip6_delaux(m); 257 258 /* 259 * mbuf statistics 260 */ 261 if (m->m_flags & M_EXT) { 262 if (m->m_next) 263 ip6stat.ip6s_mext2m++; 264 else 265 ip6stat.ip6s_mext1++; 266 } else { 267 #define M2MMAX (sizeof(ip6stat.ip6s_m2m)/sizeof(ip6stat.ip6s_m2m[0])) 268 if (m->m_next) { 269 if (m->m_flags & M_LOOP) { 270 ip6stat.ip6s_m2m[loif[0].if_index]++; /* XXX */ 271 } else if (m->m_pkthdr.rcvif->if_index < M2MMAX) 272 ip6stat.ip6s_m2m[m->m_pkthdr.rcvif->if_index]++; 273 else 274 ip6stat.ip6s_m2m[0]++; 275 } else 276 ip6stat.ip6s_m1++; 277 #undef M2MMAX 278 } 279 280 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_receive); 281 ip6stat.ip6s_total++; 282 283 #ifndef PULLDOWN_TEST 284 /* 285 * L2 bridge code and some other code can return mbuf chain 286 * that does not conform to KAME requirement. too bad. 287 * XXX: fails to join if interface MTU > MCLBYTES. jumbogram? 288 */ 289 if (m && m->m_next != NULL && m->m_pkthdr.len < MCLBYTES) { 290 struct mbuf *n; 291 292 MGETHDR(n, M_DONTWAIT, MT_HEADER); 293 if (n) 294 M_MOVE_PKTHDR(n, m); 295 if (n && n->m_pkthdr.len > MHLEN) { 296 MCLGET(n, M_DONTWAIT); 297 if ((n->m_flags & M_EXT) == 0) { 298 m_freem(n); 299 n = NULL; 300 } 301 } 302 if (n == NULL) { 303 m_freem(m); 304 return; /*ENOBUFS*/ 305 } 306 307 m_copydata(m, 0, n->m_pkthdr.len, mtod(n, caddr_t)); 308 n->m_len = n->m_pkthdr.len; 309 m_freem(m); 310 m = n; 311 } 312 IP6_EXTHDR_CHECK(m, 0, sizeof(struct ip6_hdr), /*nothing*/); 313 #endif 314 315 if (m->m_len < sizeof(struct ip6_hdr)) { 316 struct ifnet *inifp; 317 inifp = m->m_pkthdr.rcvif; 318 if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == 0) { 319 ip6stat.ip6s_toosmall++; 320 in6_ifstat_inc(inifp, ifs6_in_hdrerr); 321 return; 322 } 323 } 324 325 ip6 = mtod(m, struct ip6_hdr *); 326 327 if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { 328 ip6stat.ip6s_badvers++; 329 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); 330 goto bad; 331 } 332 333 /* 334 * Check if we want to allow this packet to be processed. 335 * Consider it to be bad if not. 336 */ 337 if (fr_checkp) { 338 struct mbuf *m1 = m; 339 340 if ((*fr_checkp)((struct ip *)ip6, sizeof(*ip6), 341 m->m_pkthdr.rcvif, 0, &m1) != 0) 342 return; 343 m = m1; 344 if (m == NULL) 345 return; 346 ip6 = mtod(m, struct ip6_hdr *); 347 } 348 349 ip6stat.ip6s_nxthist[ip6->ip6_nxt]++; 350 351 /* 352 * Check with the firewall... 353 */ 354 if (ip6_fw_enable && ip6_fw_chk_ptr) { 355 u_short port = 0; 356 /* If ipfw says divert, we have to just drop packet */ 357 /* use port as a dummy argument */ 358 if ((*ip6_fw_chk_ptr)(&ip6, NULL, &port, &m)) { 359 m_freem(m); 360 m = NULL; 361 } 362 if (!m) 363 return; 364 } 365 366 /* 367 * Check against address spoofing/corruption. 368 */ 369 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src) || 370 IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst)) { 371 /* 372 * XXX: "badscope" is not very suitable for a multicast source. 373 */ 374 ip6stat.ip6s_badscope++; 375 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); 376 goto bad; 377 } 378 if ((IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) || 379 IN6_IS_ADDR_LOOPBACK(&ip6->ip6_dst)) && 380 (m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) { 381 ip6stat.ip6s_badscope++; 382 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); 383 goto bad; 384 } 385 386 /* 387 * The following check is not documented in specs. A malicious 388 * party may be able to use IPv4 mapped addr to confuse tcp/udp stack 389 * and bypass security checks (act as if it was from 127.0.0.1 by using 390 * IPv6 src ::ffff:127.0.0.1). Be cautious. 391 * 392 * This check chokes if we are in an SIIT cloud. As none of BSDs 393 * support IPv4-less kernel compilation, we cannot support SIIT 394 * environment at all. So, it makes more sense for us to reject any 395 * malicious packets for non-SIIT environment, than try to do a 396 * partical support for SIIT environment. 397 */ 398 if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || 399 IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { 400 ip6stat.ip6s_badscope++; 401 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); 402 goto bad; 403 } 404 #if 0 405 /* 406 * Reject packets with IPv4 compatible addresses (auto tunnel). 407 * 408 * The code forbids auto tunnel relay case in RFC1933 (the check is 409 * stronger than RFC1933). We may want to re-enable it if mech-xx 410 * is revised to forbid relaying case. 411 */ 412 if (IN6_IS_ADDR_V4COMPAT(&ip6->ip6_src) || 413 IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) { 414 ip6stat.ip6s_badscope++; 415 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); 416 goto bad; 417 } 418 #endif 419 420 /* drop packets if interface ID portion is already filled */ 421 if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) { 422 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src) && 423 ip6->ip6_src.s6_addr16[1]) { 424 ip6stat.ip6s_badscope++; 425 goto bad; 426 } 427 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst) && 428 ip6->ip6_dst.s6_addr16[1]) { 429 ip6stat.ip6s_badscope++; 430 goto bad; 431 } 432 } 433 434 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) 435 ip6->ip6_src.s6_addr16[1] 436 = htons(m->m_pkthdr.rcvif->if_index); 437 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) 438 ip6->ip6_dst.s6_addr16[1] 439 = htons(m->m_pkthdr.rcvif->if_index); 440 441 #if 0 /* this case seems to be unnecessary. (jinmei, 20010401) */ 442 /* 443 * We use rt->rt_ifp to determine if the address is ours or not. 444 * If rt_ifp is lo0, the address is ours. 445 * The problem here is, rt->rt_ifp for fe80::%lo0/64 is set to lo0, 446 * so any address under fe80::%lo0/64 will be mistakenly considered 447 * local. The special case is supplied to handle the case properly 448 * by actually looking at interface addresses 449 * (using in6ifa_ifpwithaddr). 450 */ 451 if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) != 0 && 452 IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_dst)) { 453 if (!in6ifa_ifpwithaddr(m->m_pkthdr.rcvif, &ip6->ip6_dst)) { 454 icmp6_error(m, ICMP6_DST_UNREACH, 455 ICMP6_DST_UNREACH_ADDR, 0); 456 /* m is already freed */ 457 return; 458 } 459 460 ours = 1; 461 deliverifp = m->m_pkthdr.rcvif; 462 goto hbhcheck; 463 } 464 #endif 465 466 /* 467 * Multicast check 468 */ 469 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { 470 struct in6_multi *in6m = 0; 471 472 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mcast); 473 /* 474 * See if we belong to the destination multicast group on the 475 * arrival interface. 476 */ 477 IN6_LOOKUP_MULTI(ip6->ip6_dst, m->m_pkthdr.rcvif, in6m); 478 if (in6m) 479 ours = 1; 480 else if (!ip6_mrouter) { 481 ip6stat.ip6s_notmember++; 482 ip6stat.ip6s_cantforward++; 483 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); 484 goto bad; 485 } 486 deliverifp = m->m_pkthdr.rcvif; 487 goto hbhcheck; 488 } 489 490 /* 491 * Unicast check 492 */ 493 switch (ip6_ours_check_algorithm) { 494 default: 495 /* 496 * XXX: I intentionally broke our indentation rule here, 497 * since this switch-case is just for measurement and 498 * therefore should soon be removed. 499 */ 500 if (ip6_forward_rt.ro_rt != NULL && 501 (ip6_forward_rt.ro_rt->rt_flags & RTF_UP) != 0 && 502 IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, 503 &((struct sockaddr_in6 *)(&ip6_forward_rt.ro_dst))->sin6_addr)) 504 ip6stat.ip6s_forward_cachehit++; 505 else { 506 struct sockaddr_in6 *dst6; 507 508 if (ip6_forward_rt.ro_rt) { 509 /* route is down or destination is different */ 510 ip6stat.ip6s_forward_cachemiss++; 511 RTFREE(ip6_forward_rt.ro_rt); 512 ip6_forward_rt.ro_rt = 0; 513 } 514 515 bzero(&ip6_forward_rt.ro_dst, sizeof(struct sockaddr_in6)); 516 dst6 = (struct sockaddr_in6 *)&ip6_forward_rt.ro_dst; 517 dst6->sin6_len = sizeof(struct sockaddr_in6); 518 dst6->sin6_family = AF_INET6; 519 dst6->sin6_addr = ip6->ip6_dst; 520 #ifdef SCOPEDROUTING 521 ip6_forward_rt.ro_dst.sin6_scope_id = 522 in6_addr2scopeid(m->m_pkthdr.rcvif, &ip6->ip6_dst); 523 #endif 524 525 rtalloc_ign((struct route *)&ip6_forward_rt, RTF_PRCLONING); 526 } 527 528 #define rt6_key(r) ((struct sockaddr_in6 *)((r)->rt_nodes->rn_key)) 529 530 /* 531 * Accept the packet if the forwarding interface to the destination 532 * according to the routing table is the loopback interface, 533 * unless the associated route has a gateway. 534 * Note that this approach causes to accept a packet if there is a 535 * route to the loopback interface for the destination of the packet. 536 * But we think it's even useful in some situations, e.g. when using 537 * a special daemon which wants to intercept the packet. 538 * 539 * XXX: some OSes automatically make a cloned route for the destination 540 * of an outgoing packet. If the outgoing interface of the packet 541 * is a loopback one, the kernel would consider the packet to be 542 * accepted, even if we have no such address assinged on the interface. 543 * We check the cloned flag of the route entry to reject such cases, 544 * assuming that route entries for our own addresses are not made by 545 * cloning (it should be true because in6_addloop explicitly installs 546 * the host route). However, we might have to do an explicit check 547 * while it would be less efficient. Or, should we rather install a 548 * reject route for such a case? 549 */ 550 if (ip6_forward_rt.ro_rt && 551 (ip6_forward_rt.ro_rt->rt_flags & 552 (RTF_HOST|RTF_GATEWAY)) == RTF_HOST && 553 #ifdef RTF_WASCLONED 554 !(ip6_forward_rt.ro_rt->rt_flags & RTF_WASCLONED) && 555 #endif 556 #ifdef RTF_CLONED 557 !(ip6_forward_rt.ro_rt->rt_flags & RTF_CLONED) && 558 #endif 559 #if 0 560 /* 561 * The check below is redundant since the comparison of 562 * the destination and the key of the rtentry has 563 * already done through looking up the routing table. 564 */ 565 IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, 566 &rt6_key(ip6_forward_rt.ro_rt)->sin6_addr) 567 #endif 568 ip6_forward_rt.ro_rt->rt_ifp->if_type == IFT_LOOP) { 569 struct in6_ifaddr *ia6 = 570 (struct in6_ifaddr *)ip6_forward_rt.ro_rt->rt_ifa; 571 572 /* 573 * record address information into m_aux. 574 */ 575 (void)ip6_setdstifaddr(m, ia6); 576 577 /* 578 * packets to a tentative, duplicated, or somehow invalid 579 * address must not be accepted. 580 */ 581 if (!(ia6->ia6_flags & IN6_IFF_NOTREADY)) { 582 /* this address is ready */ 583 ours = 1; 584 deliverifp = ia6->ia_ifp; /* correct? */ 585 /* Count the packet in the ip address stats */ 586 ia6->ia_ifa.if_ipackets++; 587 ia6->ia_ifa.if_ibytes += m->m_pkthdr.len; 588 goto hbhcheck; 589 } else { 590 /* address is not ready, so discard the packet. */ 591 nd6log((LOG_INFO, 592 "ip6_input: packet to an unready address %s->%s\n", 593 ip6_sprintf(&ip6->ip6_src), 594 ip6_sprintf(&ip6->ip6_dst))); 595 596 goto bad; 597 } 598 } 599 } /* XXX indentation (see above) */ 600 601 /* 602 * FAITH(Firewall Aided Internet Translator) 603 */ 604 if (ip6_keepfaith) { 605 if (ip6_forward_rt.ro_rt && ip6_forward_rt.ro_rt->rt_ifp 606 && ip6_forward_rt.ro_rt->rt_ifp->if_type == IFT_FAITH) { 607 /* XXX do we need more sanity checks? */ 608 ours = 1; 609 deliverifp = ip6_forward_rt.ro_rt->rt_ifp; /* faith */ 610 goto hbhcheck; 611 } 612 } 613 614 /* 615 * Now there is no reason to process the packet if it's not our own 616 * and we're not a router. 617 */ 618 if (!ip6_forwarding) { 619 ip6stat.ip6s_cantforward++; 620 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); 621 goto bad; 622 } 623 624 hbhcheck: 625 /* 626 * record address information into m_aux, if we don't have one yet. 627 * note that we are unable to record it, if the address is not listed 628 * as our interface address (e.g. multicast addresses, addresses 629 * within FAITH prefixes and such). 630 */ 631 if (deliverifp && !ip6_getdstifaddr(m)) { 632 struct in6_ifaddr *ia6; 633 634 ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst); 635 if (ia6) { 636 if (!ip6_setdstifaddr(m, ia6)) { 637 /* 638 * XXX maybe we should drop the packet here, 639 * as we could not provide enough information 640 * to the upper layers. 641 */ 642 } 643 } 644 } 645 646 /* 647 * Process Hop-by-Hop options header if it's contained. 648 * m may be modified in ip6_hopopts_input(). 649 * If a JumboPayload option is included, plen will also be modified. 650 */ 651 plen = (u_int32_t)ntohs(ip6->ip6_plen); 652 if (ip6->ip6_nxt == IPPROTO_HOPOPTS) { 653 struct ip6_hbh *hbh; 654 655 if (ip6_hopopts_input(&plen, &rtalert, &m, &off)) { 656 #if 0 /*touches NULL pointer*/ 657 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); 658 #endif 659 return; /* m have already been freed */ 660 } 661 662 /* adjust pointer */ 663 ip6 = mtod(m, struct ip6_hdr *); 664 665 /* 666 * if the payload length field is 0 and the next header field 667 * indicates Hop-by-Hop Options header, then a Jumbo Payload 668 * option MUST be included. 669 */ 670 if (ip6->ip6_plen == 0 && plen == 0) { 671 /* 672 * Note that if a valid jumbo payload option is 673 * contained, ip6_hoptops_input() must set a valid 674 * (non-zero) payload length to the variable plen. 675 */ 676 ip6stat.ip6s_badoptions++; 677 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard); 678 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); 679 icmp6_error(m, ICMP6_PARAM_PROB, 680 ICMP6_PARAMPROB_HEADER, 681 (caddr_t)&ip6->ip6_plen - (caddr_t)ip6); 682 return; 683 } 684 #ifndef PULLDOWN_TEST 685 /* ip6_hopopts_input() ensures that mbuf is contiguous */ 686 hbh = (struct ip6_hbh *)(ip6 + 1); 687 #else 688 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr), 689 sizeof(struct ip6_hbh)); 690 if (hbh == NULL) { 691 ip6stat.ip6s_tooshort++; 692 return; 693 } 694 #endif 695 nxt = hbh->ip6h_nxt; 696 697 /* 698 * accept the packet if a router alert option is included 699 * and we act as an IPv6 router. 700 */ 701 if (rtalert != ~0 && ip6_forwarding) 702 ours = 1; 703 } else 704 nxt = ip6->ip6_nxt; 705 706 /* 707 * Check that the amount of data in the buffers 708 * is as at least much as the IPv6 header would have us expect. 709 * Trim mbufs if longer than we expect. 710 * Drop packet if shorter than we expect. 711 */ 712 if (m->m_pkthdr.len - sizeof(struct ip6_hdr) < plen) { 713 ip6stat.ip6s_tooshort++; 714 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated); 715 goto bad; 716 } 717 if (m->m_pkthdr.len > sizeof(struct ip6_hdr) + plen) { 718 if (m->m_len == m->m_pkthdr.len) { 719 m->m_len = sizeof(struct ip6_hdr) + plen; 720 m->m_pkthdr.len = sizeof(struct ip6_hdr) + plen; 721 } else 722 m_adj(m, sizeof(struct ip6_hdr) + plen - m->m_pkthdr.len); 723 } 724 725 /* 726 * Forward if desirable. 727 */ 728 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { 729 /* 730 * If we are acting as a multicast router, all 731 * incoming multicast packets are passed to the 732 * kernel-level multicast forwarding function. 733 * The packet is returned (relatively) intact; if 734 * ip6_mforward() returns a non-zero value, the packet 735 * must be discarded, else it may be accepted below. 736 */ 737 if (ip6_mrouter && ip6_mforward(ip6, m->m_pkthdr.rcvif, m)) { 738 ip6stat.ip6s_cantforward++; 739 m_freem(m); 740 return; 741 } 742 if (!ours) { 743 m_freem(m); 744 return; 745 } 746 } else if (!ours) { 747 ip6_forward(m, 0); 748 return; 749 } 750 751 ip6 = mtod(m, struct ip6_hdr *); 752 753 /* 754 * Malicious party may be able to use IPv4 mapped addr to confuse 755 * tcp/udp stack and bypass security checks (act as if it was from 756 * 127.0.0.1 by using IPv6 src ::ffff:127.0.0.1). Be cautious. 757 * 758 * For SIIT end node behavior, you may want to disable the check. 759 * However, you will become vulnerable to attacks using IPv4 mapped 760 * source. 761 */ 762 if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || 763 IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { 764 ip6stat.ip6s_badscope++; 765 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr); 766 goto bad; 767 } 768 769 /* 770 * Tell launch routine the next header 771 */ 772 ip6stat.ip6s_delivered++; 773 in6_ifstat_inc(deliverifp, ifs6_in_deliver); 774 nest = 0; 775 776 while (nxt != IPPROTO_DONE) { 777 if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) { 778 ip6stat.ip6s_toomanyhdr++; 779 goto bad; 780 } 781 782 /* 783 * protection against faulty packet - there should be 784 * more sanity checks in header chain processing. 785 */ 786 if (m->m_pkthdr.len < off) { 787 ip6stat.ip6s_tooshort++; 788 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated); 789 goto bad; 790 } 791 792 #if 0 793 /* 794 * do we need to do it for every header? yeah, other 795 * functions can play with it (like re-allocate and copy). 796 */ 797 mhist = ip6_addaux(m); 798 if (mhist && M_TRAILINGSPACE(mhist) >= sizeof(nxt)) { 799 hist = mtod(mhist, caddr_t) + mhist->m_len; 800 bcopy(&nxt, hist, sizeof(nxt)); 801 mhist->m_len += sizeof(nxt); 802 } else { 803 ip6stat.ip6s_toomanyhdr++; 804 goto bad; 805 } 806 #endif 807 808 #ifdef IPSEC 809 /* 810 * enforce IPsec policy checking if we are seeing last header. 811 * note that we do not visit this with protocols with pcb layer 812 * code - like udp/tcp/raw ip. 813 */ 814 if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0 && 815 ipsec6_in_reject(m, NULL)) { 816 ipsec6stat.in_polvio++; 817 goto bad; 818 } 819 #endif 820 821 nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt); 822 } 823 return; 824 bad: 825 m_freem(m); 826 } 827 828 /* 829 * set/grab in6_ifaddr correspond to IPv6 destination address. 830 * XXX backward compatibility wrapper 831 */ 832 static struct ip6aux * 833 ip6_setdstifaddr(m, ia6) 834 struct mbuf *m; 835 struct in6_ifaddr *ia6; 836 { 837 struct ip6aux *n; 838 839 n = ip6_addaux(m); 840 if (n) 841 n->ip6a_dstia6 = ia6; 842 return n; /* NULL if failed to set */ 843 } 844 845 struct in6_ifaddr * 846 ip6_getdstifaddr(m) 847 struct mbuf *m; 848 { 849 struct ip6aux *n; 850 851 n = ip6_findaux(m); 852 if (n) 853 return n->ip6a_dstia6; 854 else 855 return NULL; 856 } 857 858 /* 859 * Hop-by-Hop options header processing. If a valid jumbo payload option is 860 * included, the real payload length will be stored in plenp. 861 */ 862 static int 863 ip6_hopopts_input(plenp, rtalertp, mp, offp) 864 u_int32_t *plenp; 865 u_int32_t *rtalertp; /* XXX: should be stored more smart way */ 866 struct mbuf **mp; 867 int *offp; 868 { 869 struct mbuf *m = *mp; 870 int off = *offp, hbhlen; 871 struct ip6_hbh *hbh; 872 u_int8_t *opt; 873 874 /* validation of the length of the header */ 875 #ifndef PULLDOWN_TEST 876 IP6_EXTHDR_CHECK(m, off, sizeof(*hbh), -1); 877 hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off); 878 hbhlen = (hbh->ip6h_len + 1) << 3; 879 880 IP6_EXTHDR_CHECK(m, off, hbhlen, -1); 881 hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off); 882 #else 883 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, 884 sizeof(struct ip6_hdr), sizeof(struct ip6_hbh)); 885 if (hbh == NULL) { 886 ip6stat.ip6s_tooshort++; 887 return -1; 888 } 889 hbhlen = (hbh->ip6h_len + 1) << 3; 890 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr), 891 hbhlen); 892 if (hbh == NULL) { 893 ip6stat.ip6s_tooshort++; 894 return -1; 895 } 896 #endif 897 off += hbhlen; 898 hbhlen -= sizeof(struct ip6_hbh); 899 opt = (u_int8_t *)hbh + sizeof(struct ip6_hbh); 900 901 if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh), 902 hbhlen, rtalertp, plenp) < 0) 903 return(-1); 904 905 *offp = off; 906 *mp = m; 907 return(0); 908 } 909 910 /* 911 * Search header for all Hop-by-hop options and process each option. 912 * This function is separate from ip6_hopopts_input() in order to 913 * handle a case where the sending node itself process its hop-by-hop 914 * options header. In such a case, the function is called from ip6_output(). 915 * 916 * The function assumes that hbh header is located right after the IPv6 header 917 * (RFC2460 p7), opthead is pointer into data content in m, and opthead to 918 * opthead + hbhlen is located in continuous memory region. 919 */ 920 int 921 ip6_process_hopopts(m, opthead, hbhlen, rtalertp, plenp) 922 struct mbuf *m; 923 u_int8_t *opthead; 924 int hbhlen; 925 u_int32_t *rtalertp; 926 u_int32_t *plenp; 927 { 928 struct ip6_hdr *ip6; 929 int optlen = 0; 930 u_int8_t *opt = opthead; 931 u_int16_t rtalert_val; 932 u_int32_t jumboplen; 933 const int erroff = sizeof(struct ip6_hdr) + sizeof(struct ip6_hbh); 934 935 for (; hbhlen > 0; hbhlen -= optlen, opt += optlen) { 936 switch (*opt) { 937 case IP6OPT_PAD1: 938 optlen = 1; 939 break; 940 case IP6OPT_PADN: 941 if (hbhlen < IP6OPT_MINLEN) { 942 ip6stat.ip6s_toosmall++; 943 goto bad; 944 } 945 optlen = *(opt + 1) + 2; 946 break; 947 case IP6OPT_RTALERT: 948 /* XXX may need check for alignment */ 949 if (hbhlen < IP6OPT_RTALERT_LEN) { 950 ip6stat.ip6s_toosmall++; 951 goto bad; 952 } 953 if (*(opt + 1) != IP6OPT_RTALERT_LEN - 2) { 954 /* XXX stat */ 955 icmp6_error(m, ICMP6_PARAM_PROB, 956 ICMP6_PARAMPROB_HEADER, 957 erroff + opt + 1 - opthead); 958 return(-1); 959 } 960 optlen = IP6OPT_RTALERT_LEN; 961 bcopy((caddr_t)(opt + 2), (caddr_t)&rtalert_val, 2); 962 *rtalertp = ntohs(rtalert_val); 963 break; 964 case IP6OPT_JUMBO: 965 /* XXX may need check for alignment */ 966 if (hbhlen < IP6OPT_JUMBO_LEN) { 967 ip6stat.ip6s_toosmall++; 968 goto bad; 969 } 970 if (*(opt + 1) != IP6OPT_JUMBO_LEN - 2) { 971 /* XXX stat */ 972 icmp6_error(m, ICMP6_PARAM_PROB, 973 ICMP6_PARAMPROB_HEADER, 974 erroff + opt + 1 - opthead); 975 return(-1); 976 } 977 optlen = IP6OPT_JUMBO_LEN; 978 979 /* 980 * IPv6 packets that have non 0 payload length 981 * must not contain a jumbo payload option. 982 */ 983 ip6 = mtod(m, struct ip6_hdr *); 984 if (ip6->ip6_plen) { 985 ip6stat.ip6s_badoptions++; 986 icmp6_error(m, ICMP6_PARAM_PROB, 987 ICMP6_PARAMPROB_HEADER, 988 erroff + opt - opthead); 989 return(-1); 990 } 991 992 /* 993 * We may see jumbolen in unaligned location, so 994 * we'd need to perform bcopy(). 995 */ 996 bcopy(opt + 2, &jumboplen, sizeof(jumboplen)); 997 jumboplen = (u_int32_t)htonl(jumboplen); 998 999 #if 1 1000 /* 1001 * if there are multiple jumbo payload options, 1002 * *plenp will be non-zero and the packet will be 1003 * rejected. 1004 * the behavior may need some debate in ipngwg - 1005 * multiple options does not make sense, however, 1006 * there's no explicit mention in specification. 1007 */ 1008 if (*plenp != 0) { 1009 ip6stat.ip6s_badoptions++; 1010 icmp6_error(m, ICMP6_PARAM_PROB, 1011 ICMP6_PARAMPROB_HEADER, 1012 erroff + opt + 2 - opthead); 1013 return(-1); 1014 } 1015 #endif 1016 1017 /* 1018 * jumbo payload length must be larger than 65535. 1019 */ 1020 if (jumboplen <= IPV6_MAXPACKET) { 1021 ip6stat.ip6s_badoptions++; 1022 icmp6_error(m, ICMP6_PARAM_PROB, 1023 ICMP6_PARAMPROB_HEADER, 1024 erroff + opt + 2 - opthead); 1025 return(-1); 1026 } 1027 *plenp = jumboplen; 1028 1029 break; 1030 default: /* unknown option */ 1031 if (hbhlen < IP6OPT_MINLEN) { 1032 ip6stat.ip6s_toosmall++; 1033 goto bad; 1034 } 1035 optlen = ip6_unknown_opt(opt, m, 1036 erroff + opt - opthead); 1037 if (optlen == -1) 1038 return(-1); 1039 optlen += 2; 1040 break; 1041 } 1042 } 1043 1044 return(0); 1045 1046 bad: 1047 m_freem(m); 1048 return(-1); 1049 } 1050 1051 /* 1052 * Unknown option processing. 1053 * The third argument `off' is the offset from the IPv6 header to the option, 1054 * which is necessary if the IPv6 header the and option header and IPv6 header 1055 * is not continuous in order to return an ICMPv6 error. 1056 */ 1057 int 1058 ip6_unknown_opt(optp, m, off) 1059 u_int8_t *optp; 1060 struct mbuf *m; 1061 int off; 1062 { 1063 struct ip6_hdr *ip6; 1064 1065 switch (IP6OPT_TYPE(*optp)) { 1066 case IP6OPT_TYPE_SKIP: /* ignore the option */ 1067 return((int)*(optp + 1)); 1068 case IP6OPT_TYPE_DISCARD: /* silently discard */ 1069 m_freem(m); 1070 return(-1); 1071 case IP6OPT_TYPE_FORCEICMP: /* send ICMP even if multicasted */ 1072 ip6stat.ip6s_badoptions++; 1073 icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, off); 1074 return(-1); 1075 case IP6OPT_TYPE_ICMP: /* send ICMP if not multicasted */ 1076 ip6stat.ip6s_badoptions++; 1077 ip6 = mtod(m, struct ip6_hdr *); 1078 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || 1079 (m->m_flags & (M_BCAST|M_MCAST))) 1080 m_freem(m); 1081 else 1082 icmp6_error(m, ICMP6_PARAM_PROB, 1083 ICMP6_PARAMPROB_OPTION, off); 1084 return(-1); 1085 } 1086 1087 m_freem(m); /* XXX: NOTREACHED */ 1088 return(-1); 1089 } 1090 1091 /* 1092 * Create the "control" list for this pcb. 1093 * The function will not modify mbuf chain at all. 1094 * 1095 * with KAME mbuf chain restriction: 1096 * The routine will be called from upper layer handlers like tcp6_input(). 1097 * Thus the routine assumes that the caller (tcp6_input) have already 1098 * called IP6_EXTHDR_CHECK() and all the extension headers are located in the 1099 * very first mbuf on the mbuf chain. 1100 */ 1101 void 1102 ip6_savecontrol(in6p, mp, ip6, m) 1103 struct inpcb *in6p; 1104 struct mbuf **mp; 1105 struct ip6_hdr *ip6; 1106 struct mbuf *m; 1107 { 1108 struct thread *td = curthread; /* XXX */ 1109 int privileged = 0; 1110 int rthdr_exist = 0; 1111 1112 1113 if (suser(td) == 0) 1114 privileged++; 1115 1116 #ifdef SO_TIMESTAMP 1117 if ((in6p->in6p_socket->so_options & SO_TIMESTAMP) != 0) { 1118 struct timeval tv; 1119 1120 microtime(&tv); 1121 *mp = sbcreatecontrol((caddr_t) &tv, sizeof(tv), 1122 SCM_TIMESTAMP, SOL_SOCKET); 1123 if (*mp) { 1124 mp = &(*mp)->m_next; 1125 } 1126 } 1127 #endif 1128 1129 /* RFC 2292 sec. 5 */ 1130 if ((in6p->in6p_flags & IN6P_PKTINFO) != 0) { 1131 struct in6_pktinfo pi6; 1132 bcopy(&ip6->ip6_dst, &pi6.ipi6_addr, sizeof(struct in6_addr)); 1133 if (IN6_IS_SCOPE_LINKLOCAL(&pi6.ipi6_addr)) 1134 pi6.ipi6_addr.s6_addr16[1] = 0; 1135 pi6.ipi6_ifindex = (m && m->m_pkthdr.rcvif) 1136 ? m->m_pkthdr.rcvif->if_index 1137 : 0; 1138 *mp = sbcreatecontrol((caddr_t) &pi6, 1139 sizeof(struct in6_pktinfo), IPV6_PKTINFO, 1140 IPPROTO_IPV6); 1141 if (*mp) 1142 mp = &(*mp)->m_next; 1143 } 1144 1145 if ((in6p->in6p_flags & IN6P_HOPLIMIT) != 0) { 1146 int hlim = ip6->ip6_hlim & 0xff; 1147 *mp = sbcreatecontrol((caddr_t) &hlim, 1148 sizeof(int), IPV6_HOPLIMIT, IPPROTO_IPV6); 1149 if (*mp) 1150 mp = &(*mp)->m_next; 1151 } 1152 1153 /* 1154 * IPV6_HOPOPTS socket option. We require super-user privilege 1155 * for the option, but it might be too strict, since there might 1156 * be some hop-by-hop options which can be returned to normal user. 1157 * See RFC 2292 section 6. 1158 */ 1159 if ((in6p->in6p_flags & IN6P_HOPOPTS) != 0 && privileged) { 1160 /* 1161 * Check if a hop-by-hop options header is contatined in the 1162 * received packet, and if so, store the options as ancillary 1163 * data. Note that a hop-by-hop options header must be 1164 * just after the IPv6 header, which fact is assured through 1165 * the IPv6 input processing. 1166 */ 1167 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 1168 if (ip6->ip6_nxt == IPPROTO_HOPOPTS) { 1169 struct ip6_hbh *hbh; 1170 int hbhlen = 0; 1171 #ifdef PULLDOWN_TEST 1172 struct mbuf *ext; 1173 #endif 1174 1175 #ifndef PULLDOWN_TEST 1176 hbh = (struct ip6_hbh *)(ip6 + 1); 1177 hbhlen = (hbh->ip6h_len + 1) << 3; 1178 #else 1179 ext = ip6_pullexthdr(m, sizeof(struct ip6_hdr), 1180 ip6->ip6_nxt); 1181 if (ext == NULL) { 1182 ip6stat.ip6s_tooshort++; 1183 return; 1184 } 1185 hbh = mtod(ext, struct ip6_hbh *); 1186 hbhlen = (hbh->ip6h_len + 1) << 3; 1187 if (hbhlen != ext->m_len) { 1188 m_freem(ext); 1189 ip6stat.ip6s_tooshort++; 1190 return; 1191 } 1192 #endif 1193 1194 /* 1195 * XXX: We copy whole the header even if a jumbo 1196 * payload option is included, which option is to 1197 * be removed before returning in the RFC 2292. 1198 * Note: this constraint is removed in 2292bis. 1199 */ 1200 *mp = sbcreatecontrol((caddr_t)hbh, hbhlen, 1201 IPV6_HOPOPTS, IPPROTO_IPV6); 1202 if (*mp) 1203 mp = &(*mp)->m_next; 1204 #ifdef PULLDOWN_TEST 1205 m_freem(ext); 1206 #endif 1207 } 1208 } 1209 1210 /* IPV6_DSTOPTS and IPV6_RTHDR socket options */ 1211 if ((in6p->in6p_flags & (IN6P_DSTOPTS | IN6P_RTHDRDSTOPTS)) != 0) { 1212 int proto, off, nxt; 1213 1214 /* 1215 * go through the header chain to see if a routing header is 1216 * contained in the packet. We need this information to store 1217 * destination options headers (if any) properly. 1218 * XXX: performance issue. We should record this info when 1219 * processing extension headers in incoming routine. 1220 * (todo) use m_aux? 1221 */ 1222 proto = IPPROTO_IPV6; 1223 off = 0; 1224 nxt = -1; 1225 while (1) { 1226 int newoff; 1227 1228 newoff = ip6_nexthdr(m, off, proto, &nxt); 1229 if (newoff < 0) 1230 break; 1231 if (newoff < off) /* invalid, check for safety */ 1232 break; 1233 if ((proto = nxt) == IPPROTO_ROUTING) { 1234 rthdr_exist = 1; 1235 break; 1236 } 1237 off = newoff; 1238 } 1239 } 1240 1241 if ((in6p->in6p_flags & 1242 (IN6P_RTHDR | IN6P_DSTOPTS | IN6P_RTHDRDSTOPTS)) != 0) { 1243 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 1244 int nxt = ip6->ip6_nxt, off = sizeof(struct ip6_hdr); 1245 1246 /* 1247 * Search for destination options headers or routing 1248 * header(s) through the header chain, and stores each 1249 * header as ancillary data. 1250 * Note that the order of the headers remains in 1251 * the chain of ancillary data. 1252 */ 1253 while (1) { /* is explicit loop prevention necessary? */ 1254 struct ip6_ext *ip6e = NULL; 1255 int elen; 1256 #ifdef PULLDOWN_TEST 1257 struct mbuf *ext = NULL; 1258 #endif 1259 1260 /* 1261 * if it is not an extension header, don't try to 1262 * pull it from the chain. 1263 */ 1264 switch (nxt) { 1265 case IPPROTO_DSTOPTS: 1266 case IPPROTO_ROUTING: 1267 case IPPROTO_HOPOPTS: 1268 case IPPROTO_AH: /* is it possible? */ 1269 break; 1270 default: 1271 goto loopend; 1272 } 1273 1274 #ifndef PULLDOWN_TEST 1275 if (off + sizeof(*ip6e) > m->m_len) 1276 goto loopend; 1277 ip6e = (struct ip6_ext *)(mtod(m, caddr_t) + off); 1278 if (nxt == IPPROTO_AH) 1279 elen = (ip6e->ip6e_len + 2) << 2; 1280 else 1281 elen = (ip6e->ip6e_len + 1) << 3; 1282 if (off + elen > m->m_len) 1283 goto loopend; 1284 #else 1285 ext = ip6_pullexthdr(m, off, nxt); 1286 if (ext == NULL) { 1287 ip6stat.ip6s_tooshort++; 1288 return; 1289 } 1290 ip6e = mtod(ext, struct ip6_ext *); 1291 if (nxt == IPPROTO_AH) 1292 elen = (ip6e->ip6e_len + 2) << 2; 1293 else 1294 elen = (ip6e->ip6e_len + 1) << 3; 1295 if (elen != ext->m_len) { 1296 m_freem(ext); 1297 ip6stat.ip6s_tooshort++; 1298 return; 1299 } 1300 #endif 1301 1302 switch (nxt) { 1303 case IPPROTO_DSTOPTS: 1304 if ((in6p->in6p_flags & IN6P_DSTOPTS) == 0) 1305 break; 1306 1307 /* 1308 * We also require super-user privilege for 1309 * the option. 1310 * See the comments on IN6_HOPOPTS. 1311 */ 1312 if (!privileged) 1313 break; 1314 1315 *mp = sbcreatecontrol((caddr_t)ip6e, elen, 1316 IPV6_DSTOPTS, 1317 IPPROTO_IPV6); 1318 if (*mp) 1319 mp = &(*mp)->m_next; 1320 break; 1321 case IPPROTO_ROUTING: 1322 if (!in6p->in6p_flags & IN6P_RTHDR) 1323 break; 1324 1325 *mp = sbcreatecontrol((caddr_t)ip6e, elen, 1326 IPV6_RTHDR, 1327 IPPROTO_IPV6); 1328 if (*mp) 1329 mp = &(*mp)->m_next; 1330 break; 1331 case IPPROTO_HOPOPTS: 1332 case IPPROTO_AH: /* is it possible? */ 1333 break; 1334 1335 default: 1336 /* 1337 * other cases have been filtered in the above. 1338 * none will visit this case. here we supply 1339 * the code just in case (nxt overwritten or 1340 * other cases). 1341 */ 1342 #ifdef PULLDOWN_TEST 1343 m_freem(ext); 1344 #endif 1345 goto loopend; 1346 1347 } 1348 1349 /* proceed with the next header. */ 1350 off += elen; 1351 nxt = ip6e->ip6e_nxt; 1352 ip6e = NULL; 1353 #ifdef PULLDOWN_TEST 1354 m_freem(ext); 1355 ext = NULL; 1356 #endif 1357 } 1358 loopend: 1359 ; 1360 } 1361 1362 } 1363 1364 #ifdef PULLDOWN_TEST 1365 /* 1366 * pull single extension header from mbuf chain. returns single mbuf that 1367 * contains the result, or NULL on error. 1368 */ 1369 static struct mbuf * 1370 ip6_pullexthdr(m, off, nxt) 1371 struct mbuf *m; 1372 size_t off; 1373 int nxt; 1374 { 1375 struct ip6_ext ip6e; 1376 size_t elen; 1377 struct mbuf *n; 1378 1379 #ifdef DIAGNOSTIC 1380 switch (nxt) { 1381 case IPPROTO_DSTOPTS: 1382 case IPPROTO_ROUTING: 1383 case IPPROTO_HOPOPTS: 1384 case IPPROTO_AH: /* is it possible? */ 1385 break; 1386 default: 1387 printf("ip6_pullexthdr: invalid nxt=%d\n", nxt); 1388 } 1389 #endif 1390 1391 m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e); 1392 if (nxt == IPPROTO_AH) 1393 elen = (ip6e.ip6e_len + 2) << 2; 1394 else 1395 elen = (ip6e.ip6e_len + 1) << 3; 1396 1397 MGET(n, M_DONTWAIT, MT_DATA); 1398 if (n && elen >= MLEN) { 1399 MCLGET(n, M_DONTWAIT); 1400 if ((n->m_flags & M_EXT) == 0) { 1401 m_free(n); 1402 n = NULL; 1403 } 1404 } 1405 if (!n) 1406 return NULL; 1407 1408 n->m_len = 0; 1409 if (elen >= M_TRAILINGSPACE(n)) { 1410 m_free(n); 1411 return NULL; 1412 } 1413 1414 m_copydata(m, off, elen, mtod(n, caddr_t)); 1415 n->m_len = elen; 1416 return n; 1417 } 1418 #endif 1419 1420 /* 1421 * Get pointer to the previous header followed by the header 1422 * currently processed. 1423 * XXX: This function supposes that 1424 * M includes all headers, 1425 * the next header field and the header length field of each header 1426 * are valid, and 1427 * the sum of each header length equals to OFF. 1428 * Because of these assumptions, this function must be called very 1429 * carefully. Moreover, it will not be used in the near future when 1430 * we develop `neater' mechanism to process extension headers. 1431 */ 1432 char * 1433 ip6_get_prevhdr(m, off) 1434 struct mbuf *m; 1435 int off; 1436 { 1437 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 1438 1439 if (off == sizeof(struct ip6_hdr)) 1440 return(&ip6->ip6_nxt); 1441 else { 1442 int len, nxt; 1443 struct ip6_ext *ip6e = NULL; 1444 1445 nxt = ip6->ip6_nxt; 1446 len = sizeof(struct ip6_hdr); 1447 while (len < off) { 1448 ip6e = (struct ip6_ext *)(mtod(m, caddr_t) + len); 1449 1450 switch (nxt) { 1451 case IPPROTO_FRAGMENT: 1452 len += sizeof(struct ip6_frag); 1453 break; 1454 case IPPROTO_AH: 1455 len += (ip6e->ip6e_len + 2) << 2; 1456 break; 1457 default: 1458 len += (ip6e->ip6e_len + 1) << 3; 1459 break; 1460 } 1461 nxt = ip6e->ip6e_nxt; 1462 } 1463 if (ip6e) 1464 return(&ip6e->ip6e_nxt); 1465 else 1466 return NULL; 1467 } 1468 } 1469 1470 /* 1471 * get next header offset. m will be retained. 1472 */ 1473 int 1474 ip6_nexthdr(m, off, proto, nxtp) 1475 struct mbuf *m; 1476 int off; 1477 int proto; 1478 int *nxtp; 1479 { 1480 struct ip6_hdr ip6; 1481 struct ip6_ext ip6e; 1482 struct ip6_frag fh; 1483 1484 /* just in case */ 1485 if (m == NULL) 1486 panic("ip6_nexthdr: m == NULL"); 1487 if ((m->m_flags & M_PKTHDR) == 0 || m->m_pkthdr.len < off) 1488 return -1; 1489 1490 switch (proto) { 1491 case IPPROTO_IPV6: 1492 if (m->m_pkthdr.len < off + sizeof(ip6)) 1493 return -1; 1494 m_copydata(m, off, sizeof(ip6), (caddr_t)&ip6); 1495 if (nxtp) 1496 *nxtp = ip6.ip6_nxt; 1497 off += sizeof(ip6); 1498 return off; 1499 1500 case IPPROTO_FRAGMENT: 1501 /* 1502 * terminate parsing if it is not the first fragment, 1503 * it does not make sense to parse through it. 1504 */ 1505 if (m->m_pkthdr.len < off + sizeof(fh)) 1506 return -1; 1507 m_copydata(m, off, sizeof(fh), (caddr_t)&fh); 1508 if ((ntohs(fh.ip6f_offlg) & IP6F_OFF_MASK) != 0) 1509 return -1; 1510 if (nxtp) 1511 *nxtp = fh.ip6f_nxt; 1512 off += sizeof(struct ip6_frag); 1513 return off; 1514 1515 case IPPROTO_AH: 1516 if (m->m_pkthdr.len < off + sizeof(ip6e)) 1517 return -1; 1518 m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e); 1519 if (nxtp) 1520 *nxtp = ip6e.ip6e_nxt; 1521 off += (ip6e.ip6e_len + 2) << 2; 1522 return off; 1523 1524 case IPPROTO_HOPOPTS: 1525 case IPPROTO_ROUTING: 1526 case IPPROTO_DSTOPTS: 1527 if (m->m_pkthdr.len < off + sizeof(ip6e)) 1528 return -1; 1529 m_copydata(m, off, sizeof(ip6e), (caddr_t)&ip6e); 1530 if (nxtp) 1531 *nxtp = ip6e.ip6e_nxt; 1532 off += (ip6e.ip6e_len + 1) << 3; 1533 return off; 1534 1535 case IPPROTO_NONE: 1536 case IPPROTO_ESP: 1537 case IPPROTO_IPCOMP: 1538 /* give up */ 1539 return -1; 1540 1541 default: 1542 return -1; 1543 } 1544 1545 return -1; 1546 } 1547 1548 /* 1549 * get offset for the last header in the chain. m will be kept untainted. 1550 */ 1551 int 1552 ip6_lasthdr(m, off, proto, nxtp) 1553 struct mbuf *m; 1554 int off; 1555 int proto; 1556 int *nxtp; 1557 { 1558 int newoff; 1559 int nxt; 1560 1561 if (!nxtp) { 1562 nxt = -1; 1563 nxtp = &nxt; 1564 } 1565 while (1) { 1566 newoff = ip6_nexthdr(m, off, proto, nxtp); 1567 if (newoff < 0) 1568 return off; 1569 else if (newoff < off) 1570 return -1; /* invalid */ 1571 else if (newoff == off) 1572 return newoff; 1573 1574 off = newoff; 1575 proto = *nxtp; 1576 } 1577 } 1578 1579 struct ip6aux * 1580 ip6_addaux(m) 1581 struct mbuf *m; 1582 { 1583 struct m_tag *tag = m_tag_find(m, PACKET_TAG_IPV6_INPUT, NULL); 1584 if (!tag) { 1585 tag = m_tag_get(PACKET_TAG_IPV6_INPUT, 1586 sizeof (struct ip6aux), 1587 M_DONTWAIT); 1588 if (tag) 1589 m_tag_prepend(m, tag); 1590 } 1591 if (tag) 1592 bzero(tag+1, sizeof (struct ip6aux)); 1593 return tag ? (struct ip6aux*)(tag+1) : NULL; 1594 } 1595 1596 struct ip6aux * 1597 ip6_findaux(m) 1598 struct mbuf *m; 1599 { 1600 struct m_tag *tag = m_tag_find(m, PACKET_TAG_IPV6_INPUT, NULL); 1601 return tag ? (struct ip6aux*)(tag+1) : NULL; 1602 } 1603 1604 void 1605 ip6_delaux(m) 1606 struct mbuf *m; 1607 { 1608 struct m_tag *tag = m_tag_find(m, PACKET_TAG_IPV6_INPUT, NULL); 1609 if (tag) 1610 m_tag_delete(m, tag); 1611 } 1612 1613 /* 1614 * System control for IP6 1615 */ 1616 1617 u_char inet6ctlerrmap[PRC_NCMDS] = { 1618 0, 0, 0, 0, 1619 0, EMSGSIZE, EHOSTDOWN, EHOSTUNREACH, 1620 EHOSTUNREACH, EHOSTUNREACH, ECONNREFUSED, ECONNREFUSED, 1621 EMSGSIZE, EHOSTUNREACH, 0, 0, 1622 0, 0, 0, 0, 1623 ENOPROTOOPT 1624 }; 1625