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