1 /* $OpenBSD: ipsec_input.c,v 1.145 2017/02/28 09:59:34 mpi 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 * This code was written by John Ioannidis for BSD/OS in Athens, Greece, 8 * 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 #include "pf.h" 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/protosw.h> 43 #include <sys/mbuf.h> 44 #include <sys/socket.h> 45 #include <sys/sysctl.h> 46 #include <sys/kernel.h> 47 #include <sys/timeout.h> 48 49 #include <net/if.h> 50 #include <net/if_var.h> 51 #include <net/netisr.h> 52 #include <net/bpf.h> 53 #include <net/route.h> 54 55 #include <netinet/in.h> 56 #include <netinet/ip.h> 57 #include <netinet/ip_var.h> 58 #include <netinet/ip_icmp.h> 59 #include <netinet/tcp.h> 60 #include <netinet/udp.h> 61 62 #if NPF > 0 63 #include <net/pfvar.h> 64 #endif 65 66 #ifdef INET6 67 #include <netinet6/in6_var.h> 68 #include <netinet/ip6.h> 69 #include <netinet6/ip6_var.h> 70 #include <netinet6/ip6protosw.h> 71 #endif /* INET6 */ 72 73 #include <netinet/ip_ipsp.h> 74 #include <netinet/ip_esp.h> 75 #include <netinet/ip_ah.h> 76 #include <netinet/ip_ipcomp.h> 77 78 #include <net/if_enc.h> 79 80 #include "bpfilter.h" 81 82 void ipsec_common_ctlinput(u_int, int, struct sockaddr *, void *, int); 83 84 #ifdef ENCDEBUG 85 #define DPRINTF(x) if (encdebug) printf x 86 #else 87 #define DPRINTF(x) 88 #endif 89 90 /* sysctl variables */ 91 int esp_enable = 1; 92 int ah_enable = 1; 93 int ipcomp_enable = 0; 94 95 int *espctl_vars[ESPCTL_MAXID] = ESPCTL_VARS; 96 int *ahctl_vars[AHCTL_MAXID] = AHCTL_VARS; 97 int *ipcompctl_vars[IPCOMPCTL_MAXID] = IPCOMPCTL_VARS; 98 99 /* 100 * ipsec_common_input() gets called when we receive an IPsec-protected packet 101 * in IPv4 or IPv6. All it does is find the right TDB and call the appropriate 102 * transform. The callback takes care of further processing (like ingress 103 * filtering). 104 */ 105 int 106 ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto, 107 int udpencap) 108 { 109 #define IPSEC_ISTAT(x,y,z) (sproto == IPPROTO_ESP ? (x)++ : \ 110 sproto == IPPROTO_AH ? (y)++ : (z)++) 111 112 union sockaddr_union dst_address; 113 struct tdb *tdbp; 114 struct ifnet *encif; 115 u_int32_t spi; 116 u_int16_t cpi; 117 int error; 118 #ifdef ENCDEBUG 119 char buf[INET6_ADDRSTRLEN]; 120 #endif 121 122 splsoftassert(IPL_SOFTNET); 123 124 IPSEC_ISTAT(espstat.esps_input, ahstat.ahs_input, 125 ipcompstat.ipcomps_input); 126 127 if (m == NULL) { 128 DPRINTF(("ipsec_common_input(): NULL packet received\n")); 129 IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops, 130 ipcompstat.ipcomps_hdrops); 131 return EINVAL; 132 } 133 134 if ((sproto == IPPROTO_ESP && !esp_enable) || 135 (sproto == IPPROTO_AH && !ah_enable) || 136 #if NPF > 0 137 (m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) || 138 #endif 139 (sproto == IPPROTO_IPCOMP && !ipcomp_enable)) { 140 switch (af) { 141 case AF_INET: 142 rip_input(&m, &skip, sproto); 143 break; 144 #ifdef INET6 145 case AF_INET6: 146 rip6_input(&m, &skip, sproto); 147 break; 148 #endif /* INET6 */ 149 default: 150 DPRINTF(("ipsec_common_input(): unsupported protocol " 151 "family %d\n", af)); 152 m_freem(m); 153 IPSEC_ISTAT(espstat.esps_nopf, ahstat.ahs_nopf, 154 ipcompstat.ipcomps_nopf); 155 return EPFNOSUPPORT; 156 } 157 return 0; 158 } 159 if ((sproto == IPPROTO_IPCOMP) && (m->m_flags & M_COMP)) { 160 m_freem(m); 161 ipcompstat.ipcomps_pdrops++; 162 DPRINTF(("ipsec_common_input(): repeated decompression\n")); 163 return EINVAL; 164 } 165 166 if (m->m_pkthdr.len - skip < 2 * sizeof(u_int32_t)) { 167 m_freem(m); 168 IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops, 169 ipcompstat.ipcomps_hdrops); 170 DPRINTF(("ipsec_common_input(): packet too small\n")); 171 return EINVAL; 172 } 173 174 /* Retrieve the SPI from the relevant IPsec header */ 175 if (sproto == IPPROTO_ESP) 176 m_copydata(m, skip, sizeof(u_int32_t), (caddr_t) &spi); 177 else if (sproto == IPPROTO_AH) 178 m_copydata(m, skip + sizeof(u_int32_t), sizeof(u_int32_t), 179 (caddr_t) &spi); 180 else if (sproto == IPPROTO_IPCOMP) { 181 m_copydata(m, skip + sizeof(u_int16_t), sizeof(u_int16_t), 182 (caddr_t) &cpi); 183 spi = ntohl(htons(cpi)); 184 } 185 186 /* 187 * Find tunnel control block and (indirectly) call the appropriate 188 * kernel crypto routine. The resulting mbuf chain is a valid 189 * IP packet ready to go through input processing. 190 */ 191 192 memset(&dst_address, 0, sizeof(dst_address)); 193 dst_address.sa.sa_family = af; 194 195 switch (af) { 196 case AF_INET: 197 dst_address.sin.sin_len = sizeof(struct sockaddr_in); 198 m_copydata(m, offsetof(struct ip, ip_dst), 199 sizeof(struct in_addr), 200 (caddr_t) &(dst_address.sin.sin_addr)); 201 break; 202 203 #ifdef INET6 204 case AF_INET6: 205 dst_address.sin6.sin6_len = sizeof(struct sockaddr_in6); 206 m_copydata(m, offsetof(struct ip6_hdr, ip6_dst), 207 sizeof(struct in6_addr), 208 (caddr_t) &(dst_address.sin6.sin6_addr)); 209 in6_recoverscope(&dst_address.sin6, 210 &dst_address.sin6.sin6_addr); 211 break; 212 #endif /* INET6 */ 213 214 default: 215 DPRINTF(("ipsec_common_input(): unsupported protocol " 216 "family %d\n", af)); 217 m_freem(m); 218 IPSEC_ISTAT(espstat.esps_nopf, ahstat.ahs_nopf, 219 ipcompstat.ipcomps_nopf); 220 return EPFNOSUPPORT; 221 } 222 223 tdbp = gettdb(rtable_l2(m->m_pkthdr.ph_rtableid), 224 spi, &dst_address, sproto); 225 if (tdbp == NULL) { 226 DPRINTF(("ipsec_common_input(): could not find SA for " 227 "packet to %s, spi %08x\n", 228 ipsp_address(&dst_address, buf, sizeof(buf)), ntohl(spi))); 229 m_freem(m); 230 IPSEC_ISTAT(espstat.esps_notdb, ahstat.ahs_notdb, 231 ipcompstat.ipcomps_notdb); 232 return ENOENT; 233 } 234 235 if (tdbp->tdb_flags & TDBF_INVALID) { 236 DPRINTF(("ipsec_common_input(): attempted to use invalid " 237 "SA %s/%08x/%u\n", ipsp_address(&dst_address, buf, 238 sizeof(buf)), ntohl(spi), tdbp->tdb_sproto)); 239 m_freem(m); 240 IPSEC_ISTAT(espstat.esps_invalid, ahstat.ahs_invalid, 241 ipcompstat.ipcomps_invalid); 242 return EINVAL; 243 } 244 245 if (udpencap && !(tdbp->tdb_flags & TDBF_UDPENCAP)) { 246 DPRINTF(("ipsec_common_input(): attempted to use non-udpencap " 247 "SA %s/%08x/%u\n", ipsp_address(&dst_address, buf, 248 sizeof(buf)), ntohl(spi), tdbp->tdb_sproto)); 249 m_freem(m); 250 espstat.esps_udpinval++; 251 return EINVAL; 252 } 253 254 if (!udpencap && (tdbp->tdb_flags & TDBF_UDPENCAP)) { 255 DPRINTF(("ipsec_common_input(): attempted to use udpencap " 256 "SA %s/%08x/%u\n", ipsp_address(&dst_address, buf, 257 sizeof(buf)), ntohl(spi), tdbp->tdb_sproto)); 258 m_freem(m); 259 espstat.esps_udpneeded++; 260 return EINVAL; 261 } 262 263 if (tdbp->tdb_xform == NULL) { 264 DPRINTF(("ipsec_common_input(): attempted to use uninitialized " 265 "SA %s/%08x/%u\n", ipsp_address(&dst_address, buf, 266 sizeof(buf)), ntohl(spi), tdbp->tdb_sproto)); 267 m_freem(m); 268 IPSEC_ISTAT(espstat.esps_noxform, ahstat.ahs_noxform, 269 ipcompstat.ipcomps_noxform); 270 return ENXIO; 271 } 272 273 if (sproto != IPPROTO_IPCOMP) { 274 if ((encif = enc_getif(tdbp->tdb_rdomain, 275 tdbp->tdb_tap)) == NULL) { 276 DPRINTF(("ipsec_common_input(): " 277 "no enc%u interface for SA %s/%08x/%u\n", 278 tdbp->tdb_tap, ipsp_address(&dst_address, buf, 279 sizeof(buf)), ntohl(spi), tdbp->tdb_sproto)); 280 m_freem(m); 281 282 IPSEC_ISTAT(espstat.esps_pdrops, 283 ahstat.ahs_pdrops, 284 ipcompstat.ipcomps_pdrops); 285 return EACCES; 286 } 287 288 /* XXX This conflicts with the scoped nature of IPv6 */ 289 m->m_pkthdr.ph_ifidx = encif->if_index; 290 } 291 292 /* Register first use, setup expiration timer. */ 293 if (tdbp->tdb_first_use == 0) { 294 tdbp->tdb_first_use = time_second; 295 if (tdbp->tdb_flags & TDBF_FIRSTUSE) 296 timeout_add_sec(&tdbp->tdb_first_tmo, 297 tdbp->tdb_exp_first_use); 298 if (tdbp->tdb_flags & TDBF_SOFT_FIRSTUSE) 299 timeout_add_sec(&tdbp->tdb_sfirst_tmo, 300 tdbp->tdb_soft_first_use); 301 } 302 303 /* 304 * Call appropriate transform and return -- callback takes care of 305 * everything else. 306 */ 307 error = (*(tdbp->tdb_xform->xf_input))(m, tdbp, skip, protoff); 308 return error; 309 } 310 311 /* 312 * IPsec input callback, called by the transform callback. Takes care of 313 * filtering and other sanity checks on the processed packet. 314 */ 315 void 316 ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff) 317 { 318 int af, sproto; 319 u_int8_t prot; 320 321 #if NBPFILTER > 0 322 struct ifnet *encif; 323 #endif 324 325 struct ip *ip, ipn; 326 327 #ifdef INET6 328 struct ip6_hdr *ip6, ip6n; 329 #endif /* INET6 */ 330 struct m_tag *mtag; 331 struct tdb_ident *tdbi; 332 333 #ifdef ENCDEBUG 334 char buf[INET6_ADDRSTRLEN]; 335 #endif 336 337 af = tdbp->tdb_dst.sa.sa_family; 338 sproto = tdbp->tdb_sproto; 339 340 tdbp->tdb_last_used = time_second; 341 342 /* Sanity check */ 343 if (m == NULL) { 344 /* The called routine will print a message if necessary */ 345 IPSEC_ISTAT(espstat.esps_badkcr, ahstat.ahs_badkcr, 346 ipcompstat.ipcomps_badkcr); 347 return; 348 } 349 350 /* Fix IPv4 header */ 351 if (af == AF_INET) { 352 if ((m->m_len < skip) && ((m = m_pullup(m, skip)) == NULL)) { 353 DPRINTF(("ipsec_common_input_cb(): processing failed " 354 "for SA %s/%08x\n", ipsp_address(&tdbp->tdb_dst, 355 buf, sizeof(buf)), ntohl(tdbp->tdb_spi))); 356 IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops, 357 ipcompstat.ipcomps_hdrops); 358 return; 359 } 360 361 ip = mtod(m, struct ip *); 362 ip->ip_len = htons(m->m_pkthdr.len); 363 ip->ip_sum = 0; 364 ip->ip_sum = in_cksum(m, ip->ip_hl << 2); 365 prot = ip->ip_p; 366 367 /* IP-in-IP encapsulation */ 368 if (prot == IPPROTO_IPIP) { 369 if (m->m_pkthdr.len - skip < sizeof(struct ip)) { 370 m_freem(m); 371 IPSEC_ISTAT(espstat.esps_hdrops, 372 ahstat.ahs_hdrops, 373 ipcompstat.ipcomps_hdrops); 374 return; 375 } 376 /* ipn will now contain the inner IPv4 header */ 377 m_copydata(m, skip, sizeof(struct ip), 378 (caddr_t) &ipn); 379 } 380 381 #ifdef INET6 382 /* IPv6-in-IP encapsulation. */ 383 if (prot == IPPROTO_IPV6) { 384 if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) { 385 m_freem(m); 386 IPSEC_ISTAT(espstat.esps_hdrops, 387 ahstat.ahs_hdrops, 388 ipcompstat.ipcomps_hdrops); 389 return; 390 } 391 /* ip6n will now contain the inner IPv6 header. */ 392 m_copydata(m, skip, sizeof(struct ip6_hdr), 393 (caddr_t) &ip6n); 394 } 395 #endif /* INET6 */ 396 } 397 398 #ifdef INET6 399 /* Fix IPv6 header */ 400 if (af == AF_INET6) 401 { 402 if (m->m_len < sizeof(struct ip6_hdr) && 403 (m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { 404 405 DPRINTF(("ipsec_common_input_cb(): processing failed " 406 "for SA %s/%08x\n", ipsp_address(&tdbp->tdb_dst, 407 buf, sizeof(buf)), ntohl(tdbp->tdb_spi))); 408 409 IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops, 410 ipcompstat.ipcomps_hdrops); 411 return; 412 } 413 414 ip6 = mtod(m, struct ip6_hdr *); 415 ip6->ip6_plen = htons(m->m_pkthdr.len - skip); 416 417 /* Save protocol */ 418 m_copydata(m, protoff, 1, (caddr_t) &prot); 419 420 /* IP-in-IP encapsulation */ 421 if (prot == IPPROTO_IPIP) { 422 if (m->m_pkthdr.len - skip < sizeof(struct ip)) { 423 m_freem(m); 424 IPSEC_ISTAT(espstat.esps_hdrops, 425 ahstat.ahs_hdrops, 426 ipcompstat.ipcomps_hdrops); 427 return; 428 } 429 /* ipn will now contain the inner IPv4 header */ 430 m_copydata(m, skip, sizeof(struct ip), (caddr_t) &ipn); 431 } 432 433 /* IPv6-in-IP encapsulation */ 434 if (prot == IPPROTO_IPV6) { 435 if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) { 436 m_freem(m); 437 IPSEC_ISTAT(espstat.esps_hdrops, 438 ahstat.ahs_hdrops, 439 ipcompstat.ipcomps_hdrops); 440 return; 441 } 442 /* ip6n will now contain the inner IPv6 header. */ 443 m_copydata(m, skip, sizeof(struct ip6_hdr), 444 (caddr_t) &ip6n); 445 } 446 } 447 #endif /* INET6 */ 448 449 /* 450 * Fix TCP/UDP checksum of UDP encapsulated transport mode ESP packet. 451 * (RFC3948 3.1.2) 452 */ 453 if ((af == AF_INET || af == AF_INET6) && 454 (tdbp->tdb_flags & TDBF_UDPENCAP) && 455 (tdbp->tdb_flags & TDBF_TUNNELING) == 0) { 456 u_int16_t cksum; 457 458 switch (prot) { 459 case IPPROTO_UDP: 460 if (m->m_pkthdr.len < skip + sizeof(struct udphdr)) { 461 m_freem(m); 462 IPSEC_ISTAT(espstat.esps_hdrops, 463 ahstat.ahs_hdrops, 464 ipcompstat.ipcomps_hdrops); 465 return; 466 } 467 cksum = 0; 468 m_copyback(m, skip + offsetof(struct udphdr, uh_sum), 469 sizeof(cksum), &cksum, M_NOWAIT); 470 #ifdef INET6 471 if (af == AF_INET6) { 472 cksum = in6_cksum(m, IPPROTO_UDP, skip, 473 m->m_pkthdr.len - skip); 474 m_copyback(m, skip + offsetof(struct udphdr, 475 uh_sum), sizeof(cksum), &cksum, M_NOWAIT); 476 } 477 #endif 478 break; 479 case IPPROTO_TCP: 480 if (m->m_pkthdr.len < skip + sizeof(struct tcphdr)) { 481 m_freem(m); 482 IPSEC_ISTAT(espstat.esps_hdrops, 483 ahstat.ahs_hdrops, 484 ipcompstat.ipcomps_hdrops); 485 return; 486 } 487 cksum = 0; 488 m_copyback(m, skip + offsetof(struct tcphdr, th_sum), 489 sizeof(cksum), &cksum, M_NOWAIT); 490 if (af == AF_INET) 491 cksum = in4_cksum(m, IPPROTO_TCP, skip, 492 m->m_pkthdr.len - skip); 493 #ifdef INET6 494 else if (af == AF_INET6) 495 cksum = in6_cksum(m, IPPROTO_TCP, skip, 496 m->m_pkthdr.len - skip); 497 #endif 498 m_copyback(m, skip + offsetof(struct tcphdr, th_sum), 499 sizeof(cksum), &cksum, M_NOWAIT); 500 break; 501 } 502 } 503 504 /* 505 * Record what we've done to the packet (under what SA it was 506 * processed). 507 */ 508 if (tdbp->tdb_sproto != IPPROTO_IPCOMP) { 509 mtag = m_tag_get(PACKET_TAG_IPSEC_IN_DONE, 510 sizeof(struct tdb_ident), M_NOWAIT); 511 if (mtag == NULL) { 512 m_freem(m); 513 DPRINTF(("ipsec_common_input_cb(): failed to " 514 "get tag\n")); 515 IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops, 516 ipcompstat.ipcomps_hdrops); 517 return; 518 } 519 520 tdbi = (struct tdb_ident *)(mtag + 1); 521 bcopy(&tdbp->tdb_dst, &tdbi->dst, 522 sizeof(union sockaddr_union)); 523 tdbi->proto = tdbp->tdb_sproto; 524 tdbi->spi = tdbp->tdb_spi; 525 tdbi->rdomain = tdbp->tdb_rdomain; 526 527 m_tag_prepend(m, mtag); 528 } 529 530 if (sproto == IPPROTO_ESP) { 531 /* Packet is confidential ? */ 532 if (tdbp->tdb_encalgxform) 533 m->m_flags |= M_CONF; 534 535 /* Check if we had authenticated ESP. */ 536 if (tdbp->tdb_authalgxform) 537 m->m_flags |= M_AUTH; 538 } else if (sproto == IPPROTO_AH) { 539 m->m_flags |= M_AUTH; 540 } else if (sproto == IPPROTO_IPCOMP) { 541 m->m_flags |= M_COMP; 542 } 543 544 #if NPF > 0 545 /* Add pf tag if requested. */ 546 pf_tag_packet(m, tdbp->tdb_tag, -1); 547 pf_pkt_addr_changed(m); 548 #endif 549 550 if (tdbp->tdb_flags & TDBF_TUNNELING) 551 m->m_flags |= M_TUNNEL; 552 553 #if NBPFILTER > 0 554 if ((encif = enc_getif(tdbp->tdb_rdomain, tdbp->tdb_tap)) != NULL) { 555 encif->if_ipackets++; 556 encif->if_ibytes += m->m_pkthdr.len; 557 558 if (encif->if_bpf) { 559 struct enchdr hdr; 560 561 hdr.af = af; 562 hdr.spi = tdbp->tdb_spi; 563 hdr.flags = m->m_flags & (M_AUTH|M_CONF); 564 565 bpf_mtap_hdr(encif->if_bpf, (char *)&hdr, 566 ENC_HDRLEN, m, BPF_DIRECTION_IN, NULL); 567 } 568 } 569 #endif 570 571 switch (sproto) { 572 case IPPROTO_ESP: 573 case IPPROTO_AH: 574 case IPPROTO_IPCOMP: 575 break; 576 default: 577 DPRINTF(("ipsec_common_input_cb(): unknown/unsupported" 578 " security protocol %d\n", sproto)); 579 m_freem(m); 580 return; 581 } 582 583 /* Call the appropriate IPsec transform callback. */ 584 switch (af) { 585 case AF_INET: 586 if (niq_enqueue(&ipintrq, m) != 0) { 587 DPRINTF(("ipsec_common_input_cb(): dropped packet " 588 "because of full IP queue\n")); 589 IPSEC_ISTAT(espstat.esps_qfull, ahstat.ahs_qfull, 590 ipcompstat.ipcomps_qfull); 591 } 592 return; 593 #ifdef INET6 594 case AF_INET6: 595 ip6_local(m, skip, prot); 596 return; 597 #endif /* INET6 */ 598 default: 599 DPRINTF(("ipsec_common_input_cb(): unknown/unsupported " 600 "protocol family %d\n", af)); 601 m_freem(m); 602 return; 603 } 604 #undef IPSEC_ISTAT 605 } 606 607 int 608 esp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 609 size_t newlen) 610 { 611 /* All sysctl names at this level are terminal. */ 612 if (namelen != 1) 613 return (ENOTDIR); 614 615 switch (name[0]) { 616 case ESPCTL_STATS: 617 if (newp != NULL) 618 return (EPERM); 619 return (sysctl_struct(oldp, oldlenp, newp, newlen, 620 &espstat, sizeof(espstat))); 621 default: 622 if (name[0] < ESPCTL_MAXID) 623 return (sysctl_int_arr(espctl_vars, name, namelen, 624 oldp, oldlenp, newp, newlen)); 625 return (ENOPROTOOPT); 626 } 627 } 628 629 int 630 ah_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 631 size_t newlen) 632 { 633 /* All sysctl names at this level are terminal. */ 634 if (namelen != 1) 635 return (ENOTDIR); 636 637 switch (name[0]) { 638 case AHCTL_STATS: 639 if (newp != NULL) 640 return (EPERM); 641 return (sysctl_struct(oldp, oldlenp, newp, newlen, 642 &ahstat, sizeof(ahstat))); 643 default: 644 if (name[0] < AHCTL_MAXID) 645 return (sysctl_int_arr(ahctl_vars, name, namelen, 646 oldp, oldlenp, newp, newlen)); 647 return (ENOPROTOOPT); 648 } 649 } 650 651 int 652 ipcomp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 653 size_t newlen) 654 { 655 /* All sysctl names at this level are terminal. */ 656 if (namelen != 1) 657 return (ENOTDIR); 658 659 switch (name[0]) { 660 case IPCOMPCTL_STATS: 661 if (newp != NULL) 662 return (EPERM); 663 return (sysctl_struct(oldp, oldlenp, newp, newlen, 664 &ipcompstat, sizeof(ipcompstat))); 665 default: 666 if (name[0] < IPCOMPCTL_MAXID) 667 return (sysctl_int_arr(ipcompctl_vars, name, namelen, 668 oldp, oldlenp, newp, newlen)); 669 return (ENOPROTOOPT); 670 } 671 } 672 673 /* IPv4 AH wrapper. */ 674 int 675 ah4_input(struct mbuf **mp, int *offp, int proto) 676 { 677 ipsec_common_input(*mp, *offp, offsetof(struct ip, ip_p), AF_INET, 678 proto, 0); 679 return IPPROTO_DONE; 680 } 681 682 /* XXX rdomain */ 683 void 684 ah4_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v) 685 { 686 if (sa->sa_family != AF_INET || 687 sa->sa_len != sizeof(struct sockaddr_in)) 688 return; 689 690 ipsec_common_ctlinput(rdomain, cmd, sa, v, IPPROTO_AH); 691 } 692 693 /* IPv4 ESP wrapper. */ 694 int 695 esp4_input(struct mbuf **mp, int *offp, int proto) 696 { 697 ipsec_common_input(*mp, *offp, offsetof(struct ip, ip_p), AF_INET, 698 proto, 0); 699 return IPPROTO_DONE; 700 } 701 702 /* IPv4 IPCOMP wrapper */ 703 int 704 ipcomp4_input(struct mbuf **mp, int *offp, int proto) 705 { 706 ipsec_common_input(*mp, *offp, offsetof(struct ip, ip_p), AF_INET, 707 proto, 0); 708 return IPPROTO_DONE; 709 } 710 711 void 712 ipsec_common_ctlinput(u_int rdomain, int cmd, struct sockaddr *sa, 713 void *v, int proto) 714 { 715 struct ip *ip = v; 716 717 if (cmd == PRC_MSGSIZE && ip && ip_mtudisc && ip->ip_v == 4) { 718 struct tdb *tdbp; 719 struct sockaddr_in dst; 720 struct icmp *icp; 721 int hlen = ip->ip_hl << 2; 722 u_int32_t spi, mtu; 723 ssize_t adjust; 724 725 /* Find the right MTU. */ 726 icp = (struct icmp *)((caddr_t) ip - 727 offsetof(struct icmp, icmp_ip)); 728 mtu = ntohs(icp->icmp_nextmtu); 729 730 /* 731 * Ignore the packet, if we do not receive a MTU 732 * or the MTU is too small to be acceptable. 733 */ 734 if (mtu < 296) 735 return; 736 737 memset(&dst, 0, sizeof(struct sockaddr_in)); 738 dst.sin_family = AF_INET; 739 dst.sin_len = sizeof(struct sockaddr_in); 740 dst.sin_addr.s_addr = ip->ip_dst.s_addr; 741 742 bcopy((caddr_t)ip + hlen, &spi, sizeof(u_int32_t)); 743 744 tdbp = gettdb(rdomain, spi, (union sockaddr_union *)&dst, 745 proto); 746 if (tdbp == NULL || tdbp->tdb_flags & TDBF_INVALID) 747 return; 748 749 /* Walk the chain backwards to the first tdb */ 750 for (; tdbp; tdbp = tdbp->tdb_inext) { 751 if (tdbp->tdb_flags & TDBF_INVALID || 752 (adjust = ipsec_hdrsz(tdbp)) == -1) 753 return; 754 755 mtu -= adjust; 756 757 /* Store adjusted MTU in tdb */ 758 tdbp->tdb_mtu = mtu; 759 tdbp->tdb_mtutimeout = time_second + 760 ip_mtudisc_timeout; 761 DPRINTF(("ipsec_common_ctlinput: " 762 "spi %08x mtu %d adjust %ld\n", 763 ntohl(tdbp->tdb_spi), tdbp->tdb_mtu, 764 adjust)); 765 } 766 } 767 } 768 769 /* XXX rdomain */ 770 void 771 udpencap_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v) 772 { 773 struct ip *ip = v; 774 struct tdb *tdbp; 775 struct icmp *icp; 776 u_int32_t mtu; 777 ssize_t adjust; 778 struct sockaddr_in dst, src; 779 union sockaddr_union *su_dst, *su_src; 780 781 splsoftassert(IPL_SOFTNET); 782 783 icp = (struct icmp *)((caddr_t) ip - offsetof(struct icmp, icmp_ip)); 784 mtu = ntohs(icp->icmp_nextmtu); 785 786 /* 787 * Ignore the packet, if we do not receive a MTU 788 * or the MTU is too small to be acceptable. 789 */ 790 if (mtu < 296) 791 return; 792 793 memset(&dst, 0, sizeof(dst)); 794 dst.sin_family = AF_INET; 795 dst.sin_len = sizeof(struct sockaddr_in); 796 dst.sin_addr.s_addr = ip->ip_dst.s_addr; 797 su_dst = (union sockaddr_union *)&dst; 798 memset(&src, 0, sizeof(src)); 799 src.sin_family = AF_INET; 800 src.sin_len = sizeof(struct sockaddr_in); 801 src.sin_addr.s_addr = ip->ip_src.s_addr; 802 su_src = (union sockaddr_union *)&src; 803 804 tdbp = gettdbbysrcdst(rdomain, 0, su_src, su_dst, IPPROTO_ESP); 805 806 for (; tdbp != NULL; tdbp = tdbp->tdb_snext) { 807 if (tdbp->tdb_sproto == IPPROTO_ESP && 808 ((tdbp->tdb_flags & (TDBF_INVALID|TDBF_UDPENCAP)) == 809 TDBF_UDPENCAP) && 810 !memcmp(&tdbp->tdb_dst, &dst, SA_LEN(&su_dst->sa)) && 811 !memcmp(&tdbp->tdb_src, &src, SA_LEN(&su_src->sa))) { 812 if ((adjust = ipsec_hdrsz(tdbp)) != -1) { 813 /* Store adjusted MTU in tdb */ 814 tdbp->tdb_mtu = mtu - adjust; 815 tdbp->tdb_mtutimeout = time_second + 816 ip_mtudisc_timeout; 817 DPRINTF(("udpencap_ctlinput: " 818 "spi %08x mtu %d adjust %ld\n", 819 ntohl(tdbp->tdb_spi), tdbp->tdb_mtu, 820 adjust)); 821 } 822 } 823 } 824 } 825 826 /* XXX rdomain */ 827 void 828 esp4_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v) 829 { 830 if (sa->sa_family != AF_INET || 831 sa->sa_len != sizeof(struct sockaddr_in)) 832 return; 833 834 ipsec_common_ctlinput(rdomain, cmd, sa, v, IPPROTO_ESP); 835 } 836 837 #ifdef INET6 838 /* IPv6 AH wrapper. */ 839 int 840 ah6_input(struct mbuf **mp, int *offp, int proto) 841 { 842 int l = 0; 843 int protoff, nxt; 844 struct ip6_ext ip6e; 845 846 if (*offp < sizeof(struct ip6_hdr)) { 847 DPRINTF(("ah6_input(): bad offset\n")); 848 ahstat.ahs_hdrops++; 849 m_freem(*mp); 850 *mp = NULL; 851 return IPPROTO_DONE; 852 } else if (*offp == sizeof(struct ip6_hdr)) { 853 protoff = offsetof(struct ip6_hdr, ip6_nxt); 854 } else { 855 /* Chase down the header chain... */ 856 protoff = sizeof(struct ip6_hdr); 857 nxt = (mtod(*mp, struct ip6_hdr *))->ip6_nxt; 858 859 do { 860 protoff += l; 861 m_copydata(*mp, protoff, sizeof(ip6e), 862 (caddr_t) &ip6e); 863 864 if (nxt == IPPROTO_AH) 865 l = (ip6e.ip6e_len + 2) << 2; 866 else 867 l = (ip6e.ip6e_len + 1) << 3; 868 #ifdef DIAGNOSTIC 869 if (l <= 0) 870 panic("ah6_input: l went zero or negative"); 871 #endif 872 873 nxt = ip6e.ip6e_nxt; 874 } while (protoff + l < *offp); 875 876 /* Malformed packet check */ 877 if (protoff + l != *offp) { 878 DPRINTF(("ah6_input(): bad packet header chain\n")); 879 ahstat.ahs_hdrops++; 880 m_freem(*mp); 881 *mp = NULL; 882 return IPPROTO_DONE; 883 } 884 protoff += offsetof(struct ip6_ext, ip6e_nxt); 885 } 886 ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto, 0); 887 return IPPROTO_DONE; 888 } 889 890 /* IPv6 ESP wrapper. */ 891 int 892 esp6_input(struct mbuf **mp, int *offp, int proto) 893 { 894 int l = 0; 895 int protoff, nxt; 896 struct ip6_ext ip6e; 897 898 if (*offp < sizeof(struct ip6_hdr)) { 899 DPRINTF(("esp6_input(): bad offset\n")); 900 espstat.esps_hdrops++; 901 m_freem(*mp); 902 *mp = NULL; 903 return IPPROTO_DONE; 904 } else if (*offp == sizeof(struct ip6_hdr)) { 905 protoff = offsetof(struct ip6_hdr, ip6_nxt); 906 } else { 907 /* Chase down the header chain... */ 908 protoff = sizeof(struct ip6_hdr); 909 nxt = (mtod(*mp, struct ip6_hdr *))->ip6_nxt; 910 911 do { 912 protoff += l; 913 m_copydata(*mp, protoff, sizeof(ip6e), 914 (caddr_t) &ip6e); 915 916 if (nxt == IPPROTO_AH) 917 l = (ip6e.ip6e_len + 2) << 2; 918 else 919 l = (ip6e.ip6e_len + 1) << 3; 920 #ifdef DIAGNOSTIC 921 if (l <= 0) 922 panic("esp6_input: l went zero or negative"); 923 #endif 924 925 nxt = ip6e.ip6e_nxt; 926 } while (protoff + l < *offp); 927 928 /* Malformed packet check */ 929 if (protoff + l != *offp) { 930 DPRINTF(("esp6_input(): bad packet header chain\n")); 931 espstat.esps_hdrops++; 932 m_freem(*mp); 933 *mp = NULL; 934 return IPPROTO_DONE; 935 } 936 protoff += offsetof(struct ip6_ext, ip6e_nxt); 937 } 938 ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto, 0); 939 return IPPROTO_DONE; 940 941 } 942 943 /* IPv6 IPcomp wrapper */ 944 int 945 ipcomp6_input(struct mbuf **mp, int *offp, int proto) 946 { 947 int l = 0; 948 int protoff, nxt; 949 struct ip6_ext ip6e; 950 951 if (*offp < sizeof(struct ip6_hdr)) { 952 DPRINTF(("ipcomp6_input(): bad offset\n")); 953 ipcompstat.ipcomps_hdrops++; 954 m_freem(*mp); 955 *mp = NULL; 956 return IPPROTO_DONE; 957 } else if (*offp == sizeof(struct ip6_hdr)) { 958 protoff = offsetof(struct ip6_hdr, ip6_nxt); 959 } else { 960 /* Chase down the header chain... */ 961 protoff = sizeof(struct ip6_hdr); 962 nxt = (mtod(*mp, struct ip6_hdr *))->ip6_nxt; 963 964 do { 965 protoff += l; 966 m_copydata(*mp, protoff, sizeof(ip6e), 967 (caddr_t) &ip6e); 968 if (nxt == IPPROTO_AH) 969 l = (ip6e.ip6e_len + 2) << 2; 970 else 971 l = (ip6e.ip6e_len + 1) << 3; 972 #ifdef DIAGNOSTIC 973 if (l <= 0) 974 panic("ipcomp6_input: l went zero or negative"); 975 #endif 976 977 nxt = ip6e.ip6e_nxt; 978 } while (protoff + l < *offp); 979 980 /* Malformed packet check */ 981 if (protoff + l != *offp) { 982 DPRINTF(("ipcomp6_input(): bad packet header chain\n")); 983 ipcompstat.ipcomps_hdrops++; 984 m_freem(*mp); 985 *mp = NULL; 986 return IPPROTO_DONE; 987 } 988 989 protoff += offsetof(struct ip6_ext, ip6e_nxt); 990 } 991 ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto, 0); 992 return IPPROTO_DONE; 993 } 994 #endif /* INET6 */ 995