1 /* $OpenBSD: ip_ipip.c,v 1.44 2009/11/03 10:59:04 claudio Exp $ */ 2 /* 3 * The authors of this code are John Ioannidis (ji@tla.org), 4 * Angelos D. Keromytis (kermit@csd.uch.gr) and 5 * Niels Provos (provos@physnet.uni-hamburg.de). 6 * 7 * The original version of this code was written by John Ioannidis 8 * for BSD/OS in Athens, Greece, in November 1995. 9 * 10 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, 11 * by Angelos D. Keromytis. 12 * 13 * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis 14 * and Niels Provos. 15 * 16 * Additional features in 1999 by Angelos D. Keromytis. 17 * 18 * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis, 19 * Angelos D. Keromytis and Niels Provos. 20 * Copyright (c) 2001, Angelos D. Keromytis. 21 * 22 * Permission to use, copy, and modify this software with or without fee 23 * is hereby granted, provided that this entire notice is included in 24 * all copies of any software which is or includes a copy or 25 * modification of this software. 26 * You may use this code under the GNU public license if you so wish. Please 27 * contribute changes back to the authors under this freer than GPL license 28 * so that we may further the use of strong encryption without limitations to 29 * all. 30 * 31 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR 32 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY 33 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE 34 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR 35 * PURPOSE. 36 */ 37 38 /* 39 * IP-inside-IP processing 40 */ 41 42 #include "pf.h" 43 44 #include <sys/param.h> 45 #include <sys/systm.h> 46 #include <sys/mbuf.h> 47 #include <sys/socket.h> 48 #include <sys/sysctl.h> 49 50 #include <net/if.h> 51 #include <net/route.h> 52 #include <net/netisr.h> 53 #include <net/bpf.h> 54 55 #include <netinet/in.h> 56 #include <netinet/in_systm.h> 57 #include <netinet/ip.h> 58 #include <netinet/in_pcb.h> 59 #include <netinet/in_var.h> 60 #include <netinet/ip_var.h> 61 #include <netinet/ip_ecn.h> 62 63 #ifdef MROUTING 64 #include <netinet/ip_mroute.h> 65 #endif 66 67 #include <netinet/ip_ipsp.h> 68 #include <netinet/ip_ipip.h> 69 70 #include "bpfilter.h" 71 72 #if NPF > 0 73 #include <net/pfvar.h> 74 #endif 75 76 #ifdef ENCDEBUG 77 #define DPRINTF(x) if (encdebug) printf x 78 #else 79 #define DPRINTF(x) 80 #endif 81 82 /* 83 * We can control the acceptance of IP4 packets by altering the sysctl 84 * net.inet.ipip.allow value. Zero means drop them, all else is acceptance. 85 */ 86 int ipip_allow = 0; 87 88 struct ipipstat ipipstat; 89 90 #ifdef INET6 91 /* 92 * Really only a wrapper for ipip_input(), for use with IPv6. 93 */ 94 int 95 ip4_input6(struct mbuf **m, int *offp, int proto) 96 { 97 /* If we do not accept IP-in-IP explicitly, drop. */ 98 if (!ipip_allow && ((*m)->m_flags & (M_AUTH|M_CONF)) == 0) { 99 DPRINTF(("ip4_input6(): dropped due to policy\n")); 100 ipipstat.ipips_pdrops++; 101 m_freem(*m); 102 return IPPROTO_DONE; 103 } 104 105 ipip_input(*m, *offp, NULL); 106 return IPPROTO_DONE; 107 } 108 #endif /* INET6 */ 109 110 #ifdef INET 111 /* 112 * Really only a wrapper for ipip_input(), for use with IPv4. 113 */ 114 void 115 ip4_input(struct mbuf *m, ...) 116 { 117 va_list ap; 118 int iphlen; 119 120 /* If we do not accept IP-in-IP explicitly, drop. */ 121 if (!ipip_allow && (m->m_flags & (M_AUTH|M_CONF)) == 0) { 122 DPRINTF(("ip4_input(): dropped due to policy\n")); 123 ipipstat.ipips_pdrops++; 124 m_freem(m); 125 return; 126 } 127 128 va_start(ap, m); 129 iphlen = va_arg(ap, int); 130 va_end(ap); 131 132 ipip_input(m, iphlen, NULL); 133 } 134 #endif /* INET */ 135 136 /* 137 * ipip_input gets called when we receive an IP{46} encapsulated packet, 138 * either because we got it at a real interface, or because AH or ESP 139 * were being used in tunnel mode (in which case the rcvif element will 140 * contain the address of the encX interface associated with the tunnel. 141 */ 142 143 void 144 ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp) 145 { 146 struct sockaddr_in *sin; 147 struct ifnet *ifp; 148 struct ifaddr *ifa; 149 struct ifqueue *ifq = NULL; 150 struct ip *ipo; 151 u_int rdomain; 152 #ifdef INET6 153 struct sockaddr_in6 *sin6; 154 struct ip6_hdr *ip6 = NULL; 155 u_int8_t itos; 156 #endif 157 u_int8_t nxt; 158 int isr; 159 u_int8_t otos; 160 u_int8_t v; 161 int hlen, s; 162 163 ipipstat.ipips_ipackets++; 164 165 m_copydata(m, 0, 1, &v); 166 167 switch (v >> 4) { 168 #ifdef INET 169 case 4: 170 hlen = sizeof(struct ip); 171 break; 172 #endif /* INET */ 173 #ifdef INET6 174 case 6: 175 hlen = sizeof(struct ip6_hdr); 176 break; 177 #endif 178 default: 179 ipipstat.ipips_family++; 180 m_freem(m); 181 return /* EAFNOSUPPORT */; 182 } 183 184 /* Bring the IP header in the first mbuf, if not there already */ 185 if (m->m_len < hlen) { 186 if ((m = m_pullup(m, hlen)) == NULL) { 187 DPRINTF(("ipip_input(): m_pullup() failed\n")); 188 ipipstat.ipips_hdrops++; 189 return; 190 } 191 } 192 193 ipo = mtod(m, struct ip *); 194 195 /* Keep outer ecn field. */ 196 switch (v >> 4) { 197 #ifdef INET 198 case 4: 199 otos = ipo->ip_tos; 200 break; 201 #endif /* INET */ 202 #ifdef INET6 203 case 6: 204 otos = (ntohl(mtod(m, struct ip6_hdr *)->ip6_flow) >> 20) & 0xff; 205 break; 206 #endif 207 default: 208 panic("ipip_input: should never reach here"); 209 } 210 211 /* Remove outer IP header */ 212 m_adj(m, iphlen); 213 214 /* Sanity check */ 215 if (m->m_pkthdr.len < sizeof(struct ip)) { 216 ipipstat.ipips_hdrops++; 217 m_freem(m); 218 return; 219 } 220 221 m_copydata(m, 0, 1, &v); 222 223 switch (v >> 4) { 224 #ifdef INET 225 case 4: 226 hlen = sizeof(struct ip); 227 break; 228 #endif /* INET */ 229 230 #ifdef INET6 231 case 6: 232 hlen = sizeof(struct ip6_hdr); 233 break; 234 #endif 235 default: 236 ipipstat.ipips_family++; 237 m_freem(m); 238 return; /* EAFNOSUPPORT */ 239 } 240 241 /* 242 * Bring the inner IP header in the first mbuf, if not there already. 243 */ 244 if (m->m_len < hlen) { 245 if ((m = m_pullup(m, hlen)) == NULL) { 246 DPRINTF(("ipip_input(): m_pullup() failed\n")); 247 ipipstat.ipips_hdrops++; 248 return; 249 } 250 } 251 252 /* 253 * RFC 1853 specifies that the inner TTL should not be touched on 254 * decapsulation. There's no reason this comment should be here, but 255 * this is as good as any a position. 256 */ 257 258 /* Some sanity checks in the inner IP header */ 259 switch (v >> 4) { 260 #ifdef INET 261 case 4: 262 ipo = mtod(m, struct ip *); 263 nxt = ipo->ip_p; 264 if (!ip_ecn_egress(ECN_ALLOWED, &otos, &ipo->ip_tos)) { 265 m_freem(m); 266 return; 267 } 268 break; 269 #endif /* INET */ 270 #ifdef INET6 271 case 6: 272 ip6 = (struct ip6_hdr *) ipo; 273 nxt = ip6->ip6_nxt; 274 itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff; 275 if (!ip_ecn_egress(ECN_ALLOWED, &otos, &itos)) { 276 m_freem(m); 277 return; 278 } 279 ip6->ip6_flow &= ~htonl(0xff << 20); 280 ip6->ip6_flow |= htonl((u_int32_t) itos << 20); 281 break; 282 #endif 283 default: 284 panic("ipip_input: should never reach here"); 285 } 286 287 /* Check for local address spoofing. */ 288 if ((m->m_pkthdr.rcvif == NULL || 289 !(m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK)) && 290 ipip_allow != 2) { 291 rdomain = rtable_l2(m->m_pkthdr.rdomain); 292 TAILQ_FOREACH(ifp, &ifnet, if_list) { 293 if (ifp->if_rdomain != rdomain) 294 continue; 295 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) { 296 #ifdef INET 297 if (ipo) { 298 if (ifa->ifa_addr->sa_family != 299 AF_INET) 300 continue; 301 302 sin = (struct sockaddr_in *) ifa->ifa_addr; 303 304 if (sin->sin_addr.s_addr == 305 ipo->ip_src.s_addr) { 306 ipipstat.ipips_spoof++; 307 m_freem(m); 308 return; 309 } 310 } 311 #endif /* INET */ 312 313 #ifdef INET6 314 if (ip6) { 315 if (ifa->ifa_addr->sa_family != 316 AF_INET6) 317 continue; 318 319 sin6 = (struct sockaddr_in6 *) ifa->ifa_addr; 320 321 if (IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &ip6->ip6_src)) { 322 ipipstat.ipips_spoof++; 323 m_freem(m); 324 return; 325 } 326 327 } 328 #endif /* INET6 */ 329 } 330 } 331 } 332 333 /* Statistics */ 334 ipipstat.ipips_ibytes += m->m_pkthdr.len - iphlen; 335 336 /* 337 * Interface pointer stays the same; if no IPsec processing has 338 * been done (or will be done), this will point to a normal 339 * interface. Otherwise, it'll point to an enc interface, which 340 * will allow a packet filter to distinguish between secure and 341 * untrusted packets. 342 */ 343 344 switch (v >> 4) { 345 #ifdef INET 346 case 4: 347 ifq = &ipintrq; 348 isr = NETISR_IP; 349 break; 350 #endif 351 #ifdef INET6 352 case 6: 353 ifq = &ip6intrq; 354 isr = NETISR_IPV6; 355 break; 356 #endif 357 default: 358 panic("ipip_input: should never reach here"); 359 } 360 361 #if NBPFILTER > 0 362 if (gifp && gifp->if_bpf) 363 bpf_mtap_af(gifp->if_bpf, ifq == &ipintrq ? AF_INET : AF_INET6, 364 m, BPF_DIRECTION_IN); 365 #endif 366 #if NPF > 0 367 pf_pkt_addr_changed(m); 368 #endif 369 370 s = splnet(); /* isn't it already? */ 371 if (IF_QFULL(ifq)) { 372 IF_DROP(ifq); 373 m_freem(m); 374 ipipstat.ipips_qfull++; 375 376 splx(s); 377 378 DPRINTF(("ipip_input(): packet dropped because of full " 379 "queue\n")); 380 return; 381 } 382 383 IF_ENQUEUE(ifq, m); 384 schednetisr(isr); 385 splx(s); 386 return; 387 } 388 389 int 390 ipip_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int dummy, 391 int dummy2) 392 { 393 u_int8_t tp, otos; 394 395 #ifdef INET 396 u_int8_t itos; 397 struct ip *ipo; 398 #endif /* INET */ 399 400 #ifdef INET6 401 struct ip6_hdr *ip6, *ip6o; 402 #endif /* INET6 */ 403 404 /* XXX Deal with empty TDB source/destination addresses. */ 405 406 m_copydata(m, 0, 1, &tp); 407 tp = (tp >> 4) & 0xff; /* Get the IP version number. */ 408 409 switch (tdb->tdb_dst.sa.sa_family) { 410 #ifdef INET 411 case AF_INET: 412 if (tdb->tdb_src.sa.sa_family != AF_INET || 413 tdb->tdb_src.sin.sin_addr.s_addr == INADDR_ANY || 414 tdb->tdb_dst.sin.sin_addr.s_addr == INADDR_ANY) { 415 416 DPRINTF(("ipip_output(): unspecified tunnel endpoind " 417 "address in SA %s/%08x\n", 418 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); 419 420 ipipstat.ipips_unspec++; 421 m_freem(m); 422 *mp = NULL; 423 return EINVAL; 424 } 425 426 M_PREPEND(m, sizeof(struct ip), M_DONTWAIT); 427 if (m == 0) { 428 DPRINTF(("ipip_output(): M_PREPEND failed\n")); 429 ipipstat.ipips_hdrops++; 430 *mp = NULL; 431 return ENOBUFS; 432 } 433 434 ipo = mtod(m, struct ip *); 435 436 ipo->ip_v = IPVERSION; 437 ipo->ip_hl = 5; 438 ipo->ip_len = htons(m->m_pkthdr.len); 439 ipo->ip_ttl = ip_defttl; 440 ipo->ip_sum = 0; 441 ipo->ip_src = tdb->tdb_src.sin.sin_addr; 442 ipo->ip_dst = tdb->tdb_dst.sin.sin_addr; 443 444 /* 445 * We do the htons() to prevent snoopers from determining our 446 * endianness. 447 */ 448 ipo->ip_id = htons(ip_randomid()); 449 450 /* If the inner protocol is IP... */ 451 if (tp == IPVERSION) { 452 /* Save ECN notification */ 453 m_copydata(m, sizeof(struct ip) + 454 offsetof(struct ip, ip_tos), 455 sizeof(u_int8_t), (caddr_t) &itos); 456 457 ipo->ip_p = IPPROTO_IPIP; 458 459 /* 460 * We should be keeping tunnel soft-state and 461 * send back ICMPs if needed. 462 */ 463 m_copydata(m, sizeof(struct ip) + 464 offsetof(struct ip, ip_off), 465 sizeof(u_int16_t), (caddr_t) &ipo->ip_off); 466 NTOHS(ipo->ip_off); 467 ipo->ip_off &= ~(IP_DF | IP_MF | IP_OFFMASK); 468 HTONS(ipo->ip_off); 469 } 470 #ifdef INET6 471 else if (tp == (IPV6_VERSION >> 4)) { 472 u_int32_t itos32; 473 474 /* Save ECN notification. */ 475 m_copydata(m, sizeof(struct ip) + 476 offsetof(struct ip6_hdr, ip6_flow), 477 sizeof(u_int32_t), (caddr_t) &itos32); 478 itos = ntohl(itos32) >> 20; 479 ipo->ip_p = IPPROTO_IPV6; 480 ipo->ip_off = 0; 481 } 482 #endif /* INET6 */ 483 else { 484 m_freem(m); 485 *mp = NULL; 486 ipipstat.ipips_family++; 487 return EAFNOSUPPORT; 488 } 489 490 otos = 0; 491 ip_ecn_ingress(ECN_ALLOWED, &otos, &itos); 492 ipo->ip_tos = otos; 493 break; 494 #endif /* INET */ 495 496 #ifdef INET6 497 case AF_INET6: 498 if (IN6_IS_ADDR_UNSPECIFIED(&tdb->tdb_dst.sin6.sin6_addr) || 499 tdb->tdb_src.sa.sa_family != AF_INET6 || 500 IN6_IS_ADDR_UNSPECIFIED(&tdb->tdb_src.sin6.sin6_addr)) { 501 502 DPRINTF(("ipip_output(): unspecified tunnel endpoind " 503 "address in SA %s/%08x\n", 504 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi))); 505 506 ipipstat.ipips_unspec++; 507 m_freem(m); 508 *mp = NULL; 509 return ENOBUFS; 510 } 511 512 /* If the inner protocol is IPv6, clear link local scope */ 513 if (tp == (IPV6_VERSION >> 4)) { 514 /* scoped address handling */ 515 ip6 = mtod(m, struct ip6_hdr *); 516 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src)) 517 ip6->ip6_src.s6_addr16[1] = 0; 518 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)) 519 ip6->ip6_dst.s6_addr16[1] = 0; 520 } 521 522 M_PREPEND(m, sizeof(struct ip6_hdr), M_DONTWAIT); 523 if (m == 0) { 524 DPRINTF(("ipip_output(): M_PREPEND failed\n")); 525 ipipstat.ipips_hdrops++; 526 *mp = NULL; 527 return ENOBUFS; 528 } 529 530 /* Initialize IPv6 header */ 531 ip6o = mtod(m, struct ip6_hdr *); 532 ip6o->ip6_flow = 0; 533 ip6o->ip6_vfc &= ~IPV6_VERSION_MASK; 534 ip6o->ip6_vfc |= IPV6_VERSION; 535 ip6o->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6o)); 536 ip6o->ip6_hlim = ip_defttl; 537 in6_embedscope(&ip6o->ip6_src, &tdb->tdb_src.sin6, NULL, NULL); 538 in6_embedscope(&ip6o->ip6_dst, &tdb->tdb_dst.sin6, NULL, NULL); 539 540 #ifdef INET 541 if (tp == IPVERSION) { 542 /* Save ECN notification */ 543 m_copydata(m, sizeof(struct ip6_hdr) + 544 offsetof(struct ip, ip_tos), sizeof(u_int8_t), 545 (caddr_t) &itos); 546 547 /* This is really IPVERSION. */ 548 ip6o->ip6_nxt = IPPROTO_IPIP; 549 } 550 else 551 #endif /* INET */ 552 if (tp == (IPV6_VERSION >> 4)) { 553 u_int32_t itos32; 554 555 /* Save ECN notification. */ 556 m_copydata(m, sizeof(struct ip6_hdr) + 557 offsetof(struct ip6_hdr, ip6_flow), 558 sizeof(u_int32_t), (caddr_t) &itos32); 559 itos = ntohl(itos32) >> 20; 560 561 ip6o->ip6_nxt = IPPROTO_IPV6; 562 } else { 563 m_freem(m); 564 *mp = NULL; 565 ipipstat.ipips_family++; 566 return EAFNOSUPPORT; 567 } 568 569 otos = 0; 570 ip_ecn_ingress(ECN_ALLOWED, &otos, &itos); 571 ip6o->ip6_flow |= htonl((u_int32_t) otos << 20); 572 break; 573 #endif /* INET6 */ 574 575 default: 576 DPRINTF(("ipip_output(): unsupported protocol family %d\n", 577 tdb->tdb_dst.sa.sa_family)); 578 m_freem(m); 579 *mp = NULL; 580 ipipstat.ipips_family++; 581 return EAFNOSUPPORT; 582 } 583 584 ipipstat.ipips_opackets++; 585 *mp = m; 586 587 #ifdef INET 588 if (tdb->tdb_dst.sa.sa_family == AF_INET) { 589 if (tdb->tdb_xform->xf_type == XF_IP4) 590 tdb->tdb_cur_bytes += 591 m->m_pkthdr.len - sizeof(struct ip); 592 593 ipipstat.ipips_obytes += m->m_pkthdr.len - sizeof(struct ip); 594 } 595 #endif /* INET */ 596 597 #ifdef INET6 598 if (tdb->tdb_dst.sa.sa_family == AF_INET6) { 599 if (tdb->tdb_xform->xf_type == XF_IP4) 600 tdb->tdb_cur_bytes += 601 m->m_pkthdr.len - sizeof(struct ip6_hdr); 602 603 ipipstat.ipips_obytes += 604 m->m_pkthdr.len - sizeof(struct ip6_hdr); 605 } 606 #endif /* INET6 */ 607 608 return 0; 609 } 610 611 #ifdef IPSEC 612 int 613 ipe4_attach() 614 { 615 return 0; 616 } 617 618 int 619 ipe4_init(struct tdb *tdbp, struct xformsw *xsp, struct ipsecinit *ii) 620 { 621 tdbp->tdb_xform = xsp; 622 return 0; 623 } 624 625 int 626 ipe4_zeroize(struct tdb *tdbp) 627 { 628 return 0; 629 } 630 631 void 632 ipe4_input(struct mbuf *m, ...) 633 { 634 /* This is a rather serious mistake, so no conditional printing. */ 635 printf("ipe4_input(): should never be called\n"); 636 if (m) 637 m_freem(m); 638 } 639 #endif /* IPSEC */ 640 641 int 642 ipip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 643 size_t newlen) 644 { 645 /* All sysctl names at this level are terminal. */ 646 if (namelen != 1) 647 return (ENOTDIR); 648 649 switch (name[0]) { 650 case IPIPCTL_ALLOW: 651 return (sysctl_int(oldp, oldlenp, newp, newlen, &ipip_allow)); 652 case IPIPCTL_STATS: 653 if (newp != NULL) 654 return (EPERM); 655 return (sysctl_struct(oldp, oldlenp, newp, newlen, 656 &ipipstat, sizeof(ipipstat))); 657 default: 658 return (ENOPROTOOPT); 659 } 660 /* NOTREACHED */ 661 } 662