1 /* $OpenBSD: ip_ipip.c,v 1.101 2024/02/11 01:27:45 bluhm 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 "bpfilter.h" 43 #include "gif.h" 44 #include "pf.h" 45 46 #include <sys/param.h> 47 #include <sys/systm.h> 48 #include <sys/mbuf.h> 49 #include <sys/socket.h> 50 #include <sys/sysctl.h> 51 52 #include <net/if.h> 53 #include <net/if_types.h> 54 #include <net/if_var.h> 55 #include <net/route.h> 56 #include <net/netisr.h> 57 #include <net/bpf.h> 58 59 #include <netinet/in.h> 60 #include <netinet/ip.h> 61 #include <netinet/in_pcb.h> 62 #include <netinet/ip_var.h> 63 #include <netinet6/ip6_var.h> 64 #include <netinet/ip_ecn.h> 65 #include <netinet/ip_ipip.h> 66 67 #ifdef MROUTING 68 #include <netinet/ip_mroute.h> 69 #endif 70 71 #if NPF > 0 72 #include <net/pfvar.h> 73 #endif 74 75 #ifdef ENCDEBUG 76 #define DPRINTF(fmt, args...) \ 77 do { \ 78 if (encdebug) \ 79 printf("%s: " fmt "\n", __func__, ## args); \ 80 } while (0) 81 #else 82 #define DPRINTF(fmt, args...) \ 83 do { } while (0) 84 #endif 85 86 /* 87 * We can control the acceptance of IP4 packets by altering the sysctl 88 * net.inet.ipip.allow value. Zero means drop them, all else is acceptance. 89 */ 90 int ipip_allow = 0; 91 92 struct cpumem *ipipcounters; 93 94 void 95 ipip_init(void) 96 { 97 ipipcounters = counters_alloc(ipips_ncounters); 98 } 99 100 /* 101 * Really only a wrapper for ipip_input_if(), for use with pr_input. 102 */ 103 int 104 ipip_input(struct mbuf **mp, int *offp, int nxt, int af) 105 { 106 struct ifnet *ifp; 107 108 /* If we do not accept IP-in-IP explicitly, drop. */ 109 if (!ipip_allow && ((*mp)->m_flags & (M_AUTH|M_CONF)) == 0) { 110 DPRINTF("dropped due to policy"); 111 ipipstat_inc(ipips_pdrops); 112 m_freemp(mp); 113 return IPPROTO_DONE; 114 } 115 116 ifp = if_get((*mp)->m_pkthdr.ph_ifidx); 117 if (ifp == NULL) { 118 m_freemp(mp); 119 return IPPROTO_DONE; 120 } 121 nxt = ipip_input_if(mp, offp, nxt, af, ifp); 122 if_put(ifp); 123 124 return nxt; 125 } 126 127 /* 128 * ipip_input gets called when we receive an IP{46} encapsulated packet, 129 * either because we got it at a real interface, or because AH or ESP 130 * were being used in tunnel mode (in which case the ph_ifidx element 131 * will contain the index of the encX interface associated with the 132 * tunnel. 133 */ 134 135 int 136 ipip_input_if(struct mbuf **mp, int *offp, int proto, int oaf, 137 struct ifnet *ifp) 138 { 139 struct mbuf *m = *mp; 140 struct sockaddr_in *sin; 141 struct ip *ip; 142 #ifdef INET6 143 struct sockaddr_in6 *sin6; 144 struct ip6_hdr *ip6; 145 #endif 146 int mode, hlen; 147 u_int8_t itos, otos; 148 sa_family_t iaf; 149 150 ipipstat_inc(ipips_ipackets); 151 152 switch (oaf) { 153 case AF_INET: 154 hlen = sizeof(struct ip); 155 break; 156 #ifdef INET6 157 case AF_INET6: 158 hlen = sizeof(struct ip6_hdr); 159 break; 160 #endif 161 default: 162 unhandled_af(oaf); 163 } 164 165 /* Bring the IP header in the first mbuf, if not there already */ 166 if (m->m_len < hlen) { 167 if ((m = *mp = m_pullup(m, hlen)) == NULL) { 168 DPRINTF("m_pullup() failed"); 169 ipipstat_inc(ipips_hdrops); 170 goto bad; 171 } 172 } 173 174 /* Keep outer ecn field. */ 175 switch (oaf) { 176 case AF_INET: 177 ip = mtod(m, struct ip *); 178 otos = ip->ip_tos; 179 break; 180 #ifdef INET6 181 case AF_INET6: 182 ip6 = mtod(m, struct ip6_hdr *); 183 otos = (ntohl(ip6->ip6_flow) >> 20) & 0xff; 184 break; 185 #endif 186 } 187 188 /* Remove outer IP header */ 189 KASSERT(*offp > 0); 190 m_adj(m, *offp); 191 *offp = 0; 192 ip = NULL; 193 #ifdef INET6 194 ip6 = NULL; 195 #endif 196 197 switch (proto) { 198 case IPPROTO_IPV4: 199 hlen = sizeof(struct ip); 200 break; 201 202 #ifdef INET6 203 case IPPROTO_IPV6: 204 hlen = sizeof(struct ip6_hdr); 205 break; 206 #endif 207 default: 208 ipipstat_inc(ipips_family); 209 goto bad; 210 } 211 212 /* Sanity check */ 213 if (m->m_pkthdr.len < hlen) { 214 ipipstat_inc(ipips_hdrops); 215 goto bad; 216 } 217 218 /* 219 * Bring the inner header into the first mbuf, if not there already. 220 */ 221 if (m->m_len < hlen) { 222 if ((m = *mp = m_pullup(m, hlen)) == NULL) { 223 DPRINTF("m_pullup() failed"); 224 ipipstat_inc(ipips_hdrops); 225 goto bad; 226 } 227 } 228 229 /* 230 * RFC 1853 specifies that the inner TTL should not be touched on 231 * decapsulation. There's no reason this comment should be here, but 232 * this is as good as any a position. 233 */ 234 235 /* Some sanity checks in the inner IP header */ 236 switch (proto) { 237 case IPPROTO_IPV4: 238 iaf = AF_INET; 239 ip = mtod(m, struct ip *); 240 hlen = ip->ip_hl << 2; 241 if (m->m_pkthdr.len < hlen) { 242 ipipstat_inc(ipips_hdrops); 243 goto bad; 244 } 245 itos = ip->ip_tos; 246 mode = m->m_flags & (M_AUTH|M_CONF) ? 247 ECN_ALLOWED_IPSEC : ECN_ALLOWED; 248 if (!ip_ecn_egress(mode, &otos, &itos)) { 249 DPRINTF("ip_ecn_egress() failed"); 250 ipipstat_inc(ipips_pdrops); 251 goto bad; 252 } 253 /* re-calculate the checksum if ip_tos was changed */ 254 if (itos != ip->ip_tos) 255 ip_tos_patch(ip, itos); 256 break; 257 #ifdef INET6 258 case IPPROTO_IPV6: 259 iaf = AF_INET6; 260 ip6 = mtod(m, struct ip6_hdr *); 261 itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff; 262 if (!ip_ecn_egress(ECN_ALLOWED, &otos, &itos)) { 263 DPRINTF("ip_ecn_egress() failed"); 264 ipipstat_inc(ipips_pdrops); 265 goto bad; 266 } 267 ip6->ip6_flow &= ~htonl(0xff << 20); 268 ip6->ip6_flow |= htonl((u_int32_t) itos << 20); 269 break; 270 #endif 271 } 272 273 /* Check for local address spoofing. */ 274 if (!(ifp->if_flags & IFF_LOOPBACK) && ipip_allow != 2) { 275 struct sockaddr_storage ss; 276 struct rtentry *rt; 277 278 memset(&ss, 0, sizeof(ss)); 279 280 if (ip) { 281 sin = (struct sockaddr_in *)&ss; 282 sin->sin_family = AF_INET; 283 sin->sin_len = sizeof(*sin); 284 sin->sin_addr = ip->ip_src; 285 #ifdef INET6 286 } else if (ip6) { 287 sin6 = (struct sockaddr_in6 *)&ss; 288 sin6->sin6_family = AF_INET6; 289 sin6->sin6_len = sizeof(*sin6); 290 sin6->sin6_addr = ip6->ip6_src; 291 #endif /* INET6 */ 292 } 293 rt = rtalloc(sstosa(&ss), 0, m->m_pkthdr.ph_rtableid); 294 if ((rt != NULL) && (rt->rt_flags & RTF_LOCAL)) { 295 ipipstat_inc(ipips_spoof); 296 rtfree(rt); 297 goto bad; 298 } 299 rtfree(rt); 300 } 301 302 /* Statistics */ 303 ipipstat_add(ipips_ibytes, m->m_pkthdr.len - hlen); 304 305 #if NBPFILTER > 0 && NGIF > 0 306 if (ifp->if_type == IFT_GIF && ifp->if_bpf != NULL) 307 bpf_mtap_af(ifp->if_bpf, iaf, m, BPF_DIRECTION_IN); 308 #endif 309 #if NPF > 0 310 pf_pkt_addr_changed(m); 311 #endif 312 313 /* 314 * Interface pointer stays the same; if no IPsec processing has 315 * been done (or will be done), this will point to a normal 316 * interface. Otherwise, it'll point to an enc interface, which 317 * will allow a packet filter to distinguish between secure and 318 * untrusted packets. 319 */ 320 321 switch (proto) { 322 case IPPROTO_IPV4: 323 return ip_input_if(mp, offp, proto, oaf, ifp); 324 #ifdef INET6 325 case IPPROTO_IPV6: 326 return ip6_input_if(mp, offp, proto, oaf, ifp); 327 #endif 328 } 329 bad: 330 m_freemp(mp); 331 return IPPROTO_DONE; 332 } 333 334 int 335 ipip_output(struct mbuf **mp, struct tdb *tdb) 336 { 337 struct mbuf *m = *mp; 338 u_int8_t tp, otos, itos; 339 u_int64_t obytes; 340 struct ip *ipo; 341 #ifdef INET6 342 struct ip6_hdr *ip6, *ip6o; 343 #endif /* INET6 */ 344 #ifdef ENCDEBUG 345 char buf[INET6_ADDRSTRLEN]; 346 #endif 347 int error; 348 349 /* XXX Deal with empty TDB source/destination addresses. */ 350 351 m_copydata(m, 0, 1, &tp); 352 tp = (tp >> 4) & 0xff; /* Get the IP version number. */ 353 354 switch (tdb->tdb_dst.sa.sa_family) { 355 case AF_INET: 356 if (tdb->tdb_src.sa.sa_family != AF_INET || 357 tdb->tdb_src.sin.sin_addr.s_addr == INADDR_ANY || 358 tdb->tdb_dst.sin.sin_addr.s_addr == INADDR_ANY) { 359 360 DPRINTF("unspecified tunnel endpoint address " 361 "in SA %s/%08x", 362 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)), 363 ntohl(tdb->tdb_spi)); 364 365 ipipstat_inc(ipips_unspec); 366 error = EINVAL; 367 goto drop; 368 } 369 370 M_PREPEND(*mp, sizeof(struct ip), M_DONTWAIT); 371 if (*mp == NULL) { 372 DPRINTF("M_PREPEND failed"); 373 ipipstat_inc(ipips_hdrops); 374 error = ENOBUFS; 375 goto drop; 376 } 377 m = *mp; 378 379 ipo = mtod(m, struct ip *); 380 381 ipo->ip_v = IPVERSION; 382 ipo->ip_hl = 5; 383 ipo->ip_len = htons(m->m_pkthdr.len); 384 ipo->ip_ttl = ip_defttl; 385 ipo->ip_sum = 0; 386 ipo->ip_src = tdb->tdb_src.sin.sin_addr; 387 ipo->ip_dst = tdb->tdb_dst.sin.sin_addr; 388 389 /* 390 * We do the htons() to prevent snoopers from determining our 391 * endianness. 392 */ 393 ipo->ip_id = htons(ip_randomid()); 394 395 /* If the inner protocol is IP... */ 396 if (tp == IPVERSION) { 397 /* Save ECN notification */ 398 m_copydata(m, sizeof(struct ip) + 399 offsetof(struct ip, ip_tos), 400 sizeof(u_int8_t), (caddr_t) &itos); 401 402 ipo->ip_p = IPPROTO_IPIP; 403 404 /* 405 * We should be keeping tunnel soft-state and 406 * send back ICMPs if needed. 407 */ 408 m_copydata(m, sizeof(struct ip) + 409 offsetof(struct ip, ip_off), 410 sizeof(u_int16_t), (caddr_t) &ipo->ip_off); 411 ipo->ip_off = ntohs(ipo->ip_off); 412 ipo->ip_off &= ~(IP_DF | IP_MF | IP_OFFMASK); 413 ipo->ip_off = htons(ipo->ip_off); 414 } 415 #ifdef INET6 416 else if (tp == (IPV6_VERSION >> 4)) { 417 u_int32_t itos32; 418 419 /* Save ECN notification. */ 420 m_copydata(m, sizeof(struct ip) + 421 offsetof(struct ip6_hdr, ip6_flow), 422 sizeof(u_int32_t), (caddr_t) &itos32); 423 itos = ntohl(itos32) >> 20; 424 ipo->ip_p = IPPROTO_IPV6; 425 ipo->ip_off = 0; 426 } 427 #endif /* INET6 */ 428 else { 429 ipipstat_inc(ipips_family); 430 error = EAFNOSUPPORT; 431 goto drop; 432 } 433 434 otos = 0; 435 ip_ecn_ingress(ECN_ALLOWED, &otos, &itos); 436 ipo->ip_tos = otos; 437 438 obytes = m->m_pkthdr.len - sizeof(struct ip); 439 if (tdb->tdb_xform->xf_type == XF_IP4) 440 tdb->tdb_cur_bytes += obytes; 441 break; 442 443 #ifdef INET6 444 case AF_INET6: 445 if (IN6_IS_ADDR_UNSPECIFIED(&tdb->tdb_dst.sin6.sin6_addr) || 446 tdb->tdb_src.sa.sa_family != AF_INET6 || 447 IN6_IS_ADDR_UNSPECIFIED(&tdb->tdb_src.sin6.sin6_addr)) { 448 449 DPRINTF("unspecified tunnel endpoint address " 450 "in SA %s/%08x", 451 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)), 452 ntohl(tdb->tdb_spi)); 453 454 ipipstat_inc(ipips_unspec); 455 error = EINVAL; 456 goto drop; 457 } 458 459 /* If the inner protocol is IPv6, clear link local scope */ 460 if (tp == (IPV6_VERSION >> 4)) { 461 /* scoped address handling */ 462 ip6 = mtod(m, struct ip6_hdr *); 463 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src)) 464 ip6->ip6_src.s6_addr16[1] = 0; 465 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)) 466 ip6->ip6_dst.s6_addr16[1] = 0; 467 } 468 469 M_PREPEND(*mp, sizeof(struct ip6_hdr), M_DONTWAIT); 470 if (*mp == NULL) { 471 DPRINTF("M_PREPEND failed"); 472 ipipstat_inc(ipips_hdrops); 473 error = ENOBUFS; 474 goto drop; 475 } 476 m = *mp; 477 478 /* Initialize IPv6 header */ 479 ip6o = mtod(m, struct ip6_hdr *); 480 ip6o->ip6_flow = 0; 481 ip6o->ip6_vfc &= ~IPV6_VERSION_MASK; 482 ip6o->ip6_vfc |= IPV6_VERSION; 483 ip6o->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6o)); 484 ip6o->ip6_hlim = ip_defttl; 485 in6_embedscope(&ip6o->ip6_src, &tdb->tdb_src.sin6, NULL, NULL); 486 in6_embedscope(&ip6o->ip6_dst, &tdb->tdb_dst.sin6, NULL, NULL); 487 488 if (tp == IPVERSION) { 489 /* Save ECN notification */ 490 m_copydata(m, sizeof(struct ip6_hdr) + 491 offsetof(struct ip, ip_tos), sizeof(u_int8_t), 492 (caddr_t) &itos); 493 494 /* This is really IPVERSION. */ 495 ip6o->ip6_nxt = IPPROTO_IPIP; 496 } 497 else 498 if (tp == (IPV6_VERSION >> 4)) { 499 u_int32_t itos32; 500 501 /* Save ECN notification. */ 502 m_copydata(m, sizeof(struct ip6_hdr) + 503 offsetof(struct ip6_hdr, ip6_flow), 504 sizeof(u_int32_t), (caddr_t) &itos32); 505 itos = ntohl(itos32) >> 20; 506 507 ip6o->ip6_nxt = IPPROTO_IPV6; 508 } else { 509 ipipstat_inc(ipips_family); 510 error = EAFNOSUPPORT; 511 goto drop; 512 } 513 514 otos = 0; 515 ip_ecn_ingress(ECN_ALLOWED, &otos, &itos); 516 ip6o->ip6_flow |= htonl((u_int32_t) otos << 20); 517 518 obytes = m->m_pkthdr.len - sizeof(struct ip6_hdr); 519 if (tdb->tdb_xform->xf_type == XF_IP4) 520 tdb->tdb_cur_bytes += obytes; 521 break; 522 #endif /* INET6 */ 523 524 default: 525 DPRINTF("unsupported protocol family %d", 526 tdb->tdb_dst.sa.sa_family); 527 ipipstat_inc(ipips_family); 528 error = EPFNOSUPPORT; 529 goto drop; 530 } 531 532 ipipstat_pkt(ipips_opackets, ipips_obytes, obytes); 533 return 0; 534 535 drop: 536 m_freemp(mp); 537 return error; 538 } 539 540 #ifdef IPSEC 541 int 542 ipe4_attach(void) 543 { 544 return 0; 545 } 546 547 int 548 ipe4_init(struct tdb *tdbp, const struct xformsw *xsp, struct ipsecinit *ii) 549 { 550 tdbp->tdb_xform = xsp; 551 return 0; 552 } 553 554 int 555 ipe4_zeroize(struct tdb *tdbp) 556 { 557 return 0; 558 } 559 560 int 561 ipe4_input(struct mbuf **mp, struct tdb *tdb, int hlen, int proto) 562 { 563 /* This is a rather serious mistake, so no conditional printing. */ 564 printf("%s: should never be called\n", __func__); 565 m_freemp(mp); 566 return EINVAL; 567 } 568 #endif /* IPSEC */ 569 570 int 571 ipip_sysctl_ipipstat(void *oldp, size_t *oldlenp, void *newp) 572 { 573 struct ipipstat ipipstat; 574 575 CTASSERT(sizeof(ipipstat) == (ipips_ncounters * sizeof(uint64_t))); 576 memset(&ipipstat, 0, sizeof ipipstat); 577 counters_read(ipipcounters, (uint64_t *)&ipipstat, ipips_ncounters, 578 NULL); 579 return (sysctl_rdstruct(oldp, oldlenp, newp, 580 &ipipstat, sizeof(ipipstat))); 581 } 582 583 int 584 ipip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 585 size_t newlen) 586 { 587 int error; 588 589 /* All sysctl names at this level are terminal. */ 590 if (namelen != 1) 591 return (ENOTDIR); 592 593 switch (name[0]) { 594 case IPIPCTL_ALLOW: 595 NET_LOCK(); 596 error = sysctl_int_bounded(oldp, oldlenp, newp, newlen, 597 &ipip_allow, 0, 2); 598 NET_UNLOCK(); 599 return (error); 600 case IPIPCTL_STATS: 601 return (ipip_sysctl_ipipstat(oldp, oldlenp, newp)); 602 default: 603 return (ENOPROTOOPT); 604 } 605 /* NOTREACHED */ 606 } 607