1 /* $OpenBSD: ipsec_input.c,v 1.54 2001/12/06 22:52:10 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 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; 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 if ((*(tdbp->tdb_xform->xf_input))(m, tdbp, skip, protoff) == NULL) { 255 splx(s); 256 return EINVAL; 257 } else { 258 splx(s); 259 return 0; 260 } 261 } 262 263 /* 264 * IPsec input callback, called by the transform callback. Takes care of 265 * filtering and other sanity checks on the processed packet. 266 */ 267 int 268 ipsec_common_input_cb(struct mbuf *m, struct tdb *tdbp, int skip, int protoff, 269 struct m_tag *mt) 270 { 271 int prot, af, sproto; 272 273 #if NBPFILTER > 0 274 struct ifnet *bpfif; 275 #endif 276 277 #ifdef INET 278 struct ip *ip, ipn; 279 #endif /* INET */ 280 281 #ifdef INET6 282 struct ip6_hdr *ip6, ip6n; 283 #endif /* INET6 */ 284 struct m_tag *mtag; 285 struct tdb_ident *tdbi; 286 287 af = tdbp->tdb_dst.sa.sa_family; 288 sproto = tdbp->tdb_sproto; 289 290 tdbp->tdb_last_used = time.tv_sec; 291 292 /* Sanity check */ 293 if (m == NULL) { 294 /* The called routine will print a message if necessary */ 295 IPSEC_ISTAT(espstat.esps_badkcr, ahstat.ahs_badkcr, 296 ipcompstat.ipcomps_badkcr); 297 return EINVAL; 298 } 299 300 #ifdef INET 301 /* Fix IPv4 header */ 302 if (tdbp->tdb_dst.sa.sa_family == AF_INET) { 303 if ((m->m_len < skip) && ((m = m_pullup(m, skip)) == NULL)) { 304 DPRINTF(("ipsec_common_input_cb(): processing failed " 305 "for SA %s/%08x\n", ipsp_address(tdbp->tdb_dst), 306 ntohl(tdbp->tdb_spi))); 307 IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops, 308 ipcompstat.ipcomps_hdrops); 309 return ENOBUFS; 310 } 311 312 ip = mtod(m, struct ip *); 313 ip->ip_len = htons(m->m_pkthdr.len); 314 HTONS(ip->ip_off); 315 ip->ip_sum = 0; 316 ip->ip_sum = in_cksum(m, ip->ip_hl << 2); 317 prot = ip->ip_p; 318 319 /* IP-in-IP encapsulation */ 320 if (prot == IPPROTO_IPIP) { 321 /* ipn will now contain the inner IPv4 header */ 322 m_copydata(m, ip->ip_hl << 2, sizeof(struct ip), 323 (caddr_t) &ipn); 324 325 /* 326 * Check that the inner source address is the same as 327 * the proxy address, if available. 328 */ 329 if ((tdbp->tdb_proxy.sa.sa_family == AF_INET && 330 tdbp->tdb_proxy.sin.sin_addr.s_addr != 331 INADDR_ANY && 332 ipn.ip_src.s_addr != 333 tdbp->tdb_proxy.sin.sin_addr.s_addr) || 334 (tdbp->tdb_proxy.sa.sa_family != AF_INET && 335 tdbp->tdb_proxy.sa.sa_family != 0)) { 336 337 DPRINTF(("ipsec_common_input_cb(): inner " 338 "source address %s doesn't correspond to " 339 "expected proxy source %s, SA %s/%08x\n", 340 inet_ntoa4(ipn.ip_src), 341 ipsp_address(tdbp->tdb_proxy), 342 ipsp_address(tdbp->tdb_dst), 343 ntohl(tdbp->tdb_spi))); 344 345 m_freem(m); 346 IPSEC_ISTAT(espstat.esps_pdrops, 347 ahstat.ahs_pdrops, 348 ipcompstat.ipcomps_pdrops); 349 return EACCES; 350 } 351 } 352 353 #if INET6 354 /* IPv6-in-IP encapsulation. */ 355 if (prot == IPPROTO_IPV6) { 356 /* ip6n will now contain the inner IPv6 header. */ 357 m_copydata(m, ip->ip_hl << 2, sizeof(struct ip6_hdr), 358 (caddr_t) &ip6n); 359 360 /* 361 * Check that the inner source address is the same as 362 * the proxy address, if available. 363 */ 364 if ((tdbp->tdb_proxy.sa.sa_family == AF_INET6 && 365 !IN6_IS_ADDR_UNSPECIFIED(&tdbp->tdb_proxy.sin6.sin6_addr) && 366 !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src, 367 &tdbp->tdb_proxy.sin6.sin6_addr)) || 368 (tdbp->tdb_proxy.sa.sa_family != AF_INET6 && 369 tdbp->tdb_proxy.sa.sa_family != 0)) { 370 371 DPRINTF(("ipsec_common_input_cb(): inner " 372 "source address %s doesn't correspond to " 373 "expected proxy source %s, SA %s/%08x\n", 374 ip6_sprintf(&ip6n.ip6_src), 375 ipsp_address(tdbp->tdb_proxy), 376 ipsp_address(tdbp->tdb_dst), 377 ntohl(tdbp->tdb_spi))); 378 379 m_freem(m); 380 IPSEC_ISTAT(espstat.esps_pdrops, 381 ahstat.ahs_pdrops, 382 ipcompstat.ipcomps_pdrops); 383 return EACCES; 384 } 385 } 386 #endif /* INET6 */ 387 } 388 #endif /* INET */ 389 390 #ifdef INET6 391 /* Fix IPv6 header */ 392 if (af == INET6) 393 { 394 if (m->m_len < sizeof(struct ip6_hdr) && 395 (m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { 396 397 DPRINTF(("ipsec_common_input_cb(): processing failed " 398 "for SA %s/%08x\n", ipsp_address(tdbp->tdb_dst), 399 ntohl(tdbp->tdb_spi))); 400 401 IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops, 402 ipcompstat.ipcomps_hdrops); 403 return EACCES; 404 } 405 406 ip6 = mtod(m, struct ip6_hdr *); 407 ip6->ip6_plen = htons(m->m_pkthdr.len - 408 sizeof(struct ip6_hdr)); 409 410 /* Save protocol */ 411 m_copydata(m, protoff, 1, (unsigned char *) &prot); 412 413 #ifdef INET 414 /* IP-in-IP encapsulation */ 415 if (prot == IPPROTO_IPIP) { 416 /* ipn will now contain the inner IPv4 header */ 417 m_copydata(m, skip, sizeof(struct ip), (caddr_t) &ipn); 418 419 /* 420 * Check that the inner source address is the same as 421 * the proxy address, if available. 422 */ 423 if ((tdbp->tdb_proxy.sa.sa_family == AF_INET && 424 tdbp->tdb_proxy.sin.sin_addr.s_addr != 425 INADDR_ANY && 426 ipn.ip_src.s_addr != 427 tdbp->tdb_proxy.sin.sin_addr.s_addr) || 428 (tdbp->tdb_proxy.sa.sa_family != AF_INET && 429 tdbp->tdb_proxy.sa.sa_family != 0)) { 430 431 DPRINTF(("ipsec_common_input_cb(): inner " 432 "source address %s doesn't correspond to " 433 "expected proxy source %s, SA %s/%08x\n", 434 inet_ntoa4(ipn.ip_src), 435 ipsp_address(tdbp->tdb_proxy), 436 ipsp_address(tdbp->tdb_dst), 437 ntohl(tdbp->tdb_spi))); 438 439 m_freem(m); 440 IPSEC_ISTAT(espstat.esps_pdrops, 441 ahstat.ahs_pdrops, 442 ipcompstat.ipcomps_pdrops); 443 return EACCES; 444 } 445 } 446 #endif /* INET */ 447 448 /* IPv6-in-IP encapsulation */ 449 if (prot == IPPROTO_IPV6) { 450 /* ip6n will now contain the inner IPv6 header. */ 451 m_copydata(m, skip, sizeof(struct ip6_hdr), 452 (caddr_t) &ip6n); 453 454 /* 455 * Check that the inner source address is the same as 456 * the proxy address, if available. 457 */ 458 if ((tdbp->tdb_proxy.sa.sa_family == AF_INET6 && 459 !IN6_IS_ADDR_UNSPECIFIED(&tdbp->tdb_proxy.sin6.sin6_addr) && 460 !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src, 461 &tdbp->tdb_proxy.sin6.sin6_addr)) || 462 (tdbp->tdb_proxy.sa.sa_family != AF_INET6 && 463 tdbp->tdb_proxy.sa.sa_family != 0)) { 464 465 DPRINTF(("ipsec_common_input_cb(): inner " 466 "source address %s doesn't correspond to " 467 "expected proxy source %s, SA %s/%08x\n", 468 ip6_sprintf(&ip6n.ip6_src), 469 ipsp_address(tdbp->tdb_proxy), 470 ipsp_address(tdbp->tdb_dst), 471 ntohl(tdbp->tdb_spi))); 472 473 m_freem(m); 474 IPSEC_ISTAT(espstat.esps_pdrops, 475 ahstat.ahs_pdrops, 476 ipcompstat.ipcomps_pdrops); 477 return EACCES; 478 } 479 } 480 } 481 #endif /* INET6 */ 482 483 /* 484 * Record what we've done to the packet (under what SA it was 485 * processed). If we've been passed an mtag, it means the packet 486 * was already processed by an ethernet/crypto combo card and 487 * thus has a tag attached with all the right information, but 488 * with a PACKET_TAG_IPSEC_IN_CRYPTO_DONE as opposed to 489 * PACKET_TAG_IPSEC_IN_DONE type; in that case, just change the type. 490 */ 491 if (mt == NULL && tdbp->tdb_sproto != IPPROTO_IPCOMP) { 492 mtag = m_tag_get(PACKET_TAG_IPSEC_IN_DONE, 493 sizeof(struct tdb_ident), M_NOWAIT); 494 if (mtag == NULL) { 495 m_freem(m); 496 DPRINTF(("ipsec_common_input_cb(): failed to " 497 "get tag\n")); 498 IPSEC_ISTAT(espstat.esps_hdrops, ahstat.ahs_hdrops, 499 ipcompstat.ipcomps_hdrops); 500 return ENOMEM; 501 } 502 503 tdbi = (struct tdb_ident *)(mtag + 1); 504 bcopy(&tdbp->tdb_dst, &tdbi->dst, 505 sizeof(union sockaddr_union)); 506 tdbi->proto = tdbp->tdb_sproto; 507 tdbi->spi = tdbp->tdb_spi; 508 509 m_tag_prepend(m, mtag); 510 } 511 else 512 mt->m_tag_id = PACKET_TAG_IPSEC_IN_DONE; 513 514 if (sproto == IPPROTO_ESP) { 515 /* Packet is confidential ? */ 516 if (tdbp->tdb_encalgxform) 517 m->m_flags |= M_CONF; 518 519 /* Check if we had authenticated ESP. */ 520 if (tdbp->tdb_authalgxform) 521 m->m_flags |= M_AUTH; 522 } 523 else if (sproto == IPPROTO_IPCOMP) 524 m->m_flags |= M_COMP; 525 else 526 m->m_flags |= M_AUTH; 527 528 #if NBPFILTER > 0 529 bpfif = &encif[0].sc_if; 530 if (bpfif->if_bpf) { 531 /* 532 * We need to prepend the address family as 533 * a four byte field. Cons up a dummy header 534 * to pacify bpf. This is safe because bpf 535 * will only read from the mbuf (i.e., it won't 536 * try to free it or keep a pointer a to it). 537 */ 538 struct mbuf m1; 539 struct enchdr hdr; 540 541 hdr.af = af; 542 hdr.spi = tdbp->tdb_spi; 543 hdr.flags = m->m_flags & (M_AUTH|M_CONF); 544 545 m1.m_next = m; 546 m1.m_len = ENC_HDRLEN; 547 m1.m_data = (char *) &hdr; 548 549 bpf_mtap(bpfif->if_bpf, &m1); 550 } 551 #endif 552 553 /* Call the appropriate IPsec transform callback. */ 554 switch (af) { 555 #ifdef INET 556 case AF_INET: 557 switch (sproto) 558 { 559 case IPPROTO_ESP: 560 return esp4_input_cb(m); 561 562 case IPPROTO_AH: 563 return ah4_input_cb(m); 564 565 case IPPROTO_IPCOMP: 566 return ipcomp4_input_cb(m); 567 568 default: 569 DPRINTF(("ipsec_common_input_cb(): unknown/unsupported" 570 " security protocol %d\n", sproto)); 571 m_freem(m); 572 return EPFNOSUPPORT; 573 } 574 break; 575 #endif /* INET */ 576 577 #ifdef INET6 578 case AF_INET6: 579 switch (sproto) { 580 case IPPROTO_ESP: 581 return esp6_input_cb(m, skip, protoff); 582 583 case IPPROTO_AH: 584 return ah6_input_cb(m, skip, protoff); 585 586 case IPPROTO_IPCOMP: 587 return ipcomp6_input_cb(m, skip, protoff); 588 589 default: 590 DPRINTF(("ipsec_common_input_cb(): unknown/unsupported" 591 " security protocol %d\n", sproto)); 592 m_freem(m); 593 return EPFNOSUPPORT; 594 } 595 break; 596 #endif /* INET6 */ 597 598 default: 599 DPRINTF(("ipsec_common_input_cb(): unknown/unsupported " 600 "protocol family %d\n", af)); 601 m_freem(m); 602 return EPFNOSUPPORT; 603 } 604 #undef IPSEC_ISTAT 605 } 606 607 int 608 esp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlen, 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_ENABLE: 617 return sysctl_int(oldp, oldlen, newp, newlen, &esp_enable); 618 default: 619 return ENOPROTOOPT; 620 } 621 /* NOTREACHED */ 622 } 623 624 int 625 ah_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlen, void *newp, 626 size_t newlen) 627 { 628 /* All sysctl names at this level are terminal. */ 629 if (namelen != 1) 630 return ENOTDIR; 631 632 switch (name[0]) { 633 case AHCTL_ENABLE: 634 return sysctl_int(oldp, oldlen, newp, newlen, &ah_enable); 635 default: 636 return ENOPROTOOPT; 637 } 638 /* NOTREACHED */ 639 } 640 641 int 642 ipcomp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlen, 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 IPCOMPCTL_ENABLE: 651 return sysctl_int(oldp, oldlen, newp, newlen, &ipcomp_enable); 652 default: 653 return ENOPROTOOPT; 654 } 655 /* NOTREACHED */ 656 } 657 658 #ifdef INET 659 /* IPv4 AH wrapper. */ 660 void 661 ah4_input(struct mbuf *m, ...) 662 { 663 int skip; 664 665 va_list ap; 666 va_start(ap, m); 667 skip = va_arg(ap, int); 668 va_end(ap); 669 670 ipsec_common_input(m, skip, offsetof(struct ip, ip_p), AF_INET, 671 IPPROTO_AH); 672 return; 673 } 674 675 /* IPv4 AH callback. */ 676 int 677 ah4_input_cb(struct mbuf *m, ...) 678 { 679 struct ifqueue *ifq = &ipintrq; 680 int s = splimp(); 681 682 /* 683 * Interface pointer is already in first mbuf; chop off the 684 * `outer' header and reschedule. 685 */ 686 687 if (IF_QFULL(ifq)) { 688 IF_DROP(ifq); 689 ahstat.ahs_qfull++; 690 splx(s); 691 692 m_freem(m); 693 DPRINTF(("ah4_input_cb(): dropped packet because of full " 694 "IP queue\n")); 695 return ENOBUFS; 696 } 697 698 IF_ENQUEUE(ifq, m); 699 schednetisr(NETISR_IP); 700 splx(s); 701 return 0; 702 } 703 704 705 void * 706 ah4_ctlinput(int cmd, struct sockaddr *sa, void *v) 707 { 708 if (sa->sa_family != AF_INET || 709 sa->sa_len != sizeof(struct sockaddr_in)) 710 return (NULL); 711 712 return (ipsec_common_ctlinput(cmd, sa, v, IPPROTO_AH)); 713 } 714 715 /* IPv4 ESP wrapper. */ 716 void 717 esp4_input(struct mbuf *m, ...) 718 { 719 int skip; 720 721 va_list ap; 722 va_start(ap, m); 723 skip = va_arg(ap, int); 724 va_end(ap); 725 726 ipsec_common_input(m, skip, offsetof(struct ip, ip_p), AF_INET, 727 IPPROTO_ESP); 728 } 729 730 /* IPv4 ESP callback. */ 731 int 732 esp4_input_cb(struct mbuf *m, ...) 733 { 734 struct ifqueue *ifq = &ipintrq; 735 int s = splimp(); 736 737 /* 738 * Interface pointer is already in first mbuf; chop off the 739 * `outer' header and reschedule. 740 */ 741 if (IF_QFULL(ifq)) { 742 IF_DROP(ifq); 743 espstat.esps_qfull++; 744 splx(s); 745 746 m_freem(m); 747 DPRINTF(("esp4_input_cb(): dropped packet because of full " 748 "IP queue\n")); 749 return ENOBUFS; 750 } 751 752 IF_ENQUEUE(ifq, m); 753 schednetisr(NETISR_IP); 754 splx(s); 755 return 0; 756 } 757 758 /* IPv4 IPCOMP wrapper */ 759 void 760 ipcomp4_input(struct mbuf *m, ...) 761 { 762 int skip; 763 va_list ap; 764 va_start(ap, m); 765 skip = va_arg(ap, int); 766 va_end(ap); 767 768 ipsec_common_input(m, skip, offsetof(struct ip, ip_p), AF_INET, 769 IPPROTO_IPCOMP); 770 } 771 772 /* IPv4 IPCOMP callback */ 773 int 774 ipcomp4_input_cb(struct mbuf *m, ...) 775 { 776 struct ifqueue *ifq = &ipintrq; 777 int s = splimp(); 778 779 /* 780 * Interface pointer is already in first mbuf; chop off the 781 * `outer' header and reschedule. 782 */ 783 if (IF_QFULL(ifq)) { 784 IF_DROP(ifq); 785 ipcompstat.ipcomps_qfull++; 786 splx(s); 787 788 m_freem(m); 789 DPRINTF(("ipcomp4_input_cb(): dropped packet because of full IP queue\n")); 790 return ENOBUFS; 791 } 792 793 IF_ENQUEUE(ifq, m); 794 schednetisr(NETISR_IP); 795 splx(s); 796 797 return 0; 798 } 799 800 void * 801 ipsec_common_ctlinput(int cmd, struct sockaddr *sa, void *v, int proto) 802 { 803 extern u_int ip_mtudisc_timeout; 804 struct ip *ip = v; 805 int s; 806 807 if (cmd == PRC_MSGSIZE && ip && ip->ip_v == 4) { 808 struct tdb *tdbp; 809 struct sockaddr_in dst; 810 struct icmp *icp; 811 int hlen = ip->ip_hl << 2; 812 u_int32_t spi, mtu; 813 ssize_t adjust; 814 815 /* Find the right MTU. */ 816 icp = (struct icmp *)((caddr_t) ip - 817 offsetof(struct icmp, icmp_ip)); 818 mtu = ntohs(icp->icmp_nextmtu); 819 820 /* 821 * Ignore the packet, if we do not receive a MTU 822 * or the MTU is too small to be acceptable. 823 */ 824 if (mtu < 296) 825 return (NULL); 826 827 bzero(&dst, sizeof(struct sockaddr_in)); 828 dst.sin_family = AF_INET; 829 dst.sin_len = sizeof(struct sockaddr_in); 830 dst.sin_addr.s_addr = ip->ip_dst.s_addr; 831 832 bcopy((caddr_t)ip + hlen, &spi, sizeof(u_int32_t)); 833 834 s = spltdb(); 835 tdbp = gettdb(spi, (union sockaddr_union *)&dst, proto); 836 if (tdbp == NULL || tdbp->tdb_flags & TDBF_INVALID) { 837 splx(s); 838 return (NULL); 839 } 840 841 /* Walk the chain backswards to the first tdb */ 842 for (; tdbp; tdbp = tdbp->tdb_inext) { 843 if (tdbp->tdb_flags & TDBF_INVALID || 844 (adjust = ipsec_hdrsz(tdbp)) == -1) { 845 splx(s); 846 return (NULL); 847 } 848 849 mtu -= adjust; 850 851 /* Store adjusted MTU in tdb */ 852 tdbp->tdb_mtu = mtu; 853 tdbp->tdb_mtutimeout = time.tv_sec + 854 ip_mtudisc_timeout; 855 } 856 splx(s); 857 return (NULL); 858 } 859 return (NULL); 860 } 861 862 void * 863 esp4_ctlinput(int cmd, struct sockaddr *sa, void *v) 864 { 865 if (sa->sa_family != AF_INET || 866 sa->sa_len != sizeof(struct sockaddr_in)) 867 return (NULL); 868 869 return (ipsec_common_ctlinput(cmd, sa, v, IPPROTO_ESP)); 870 } 871 #endif /* INET */ 872 873 #ifdef INET6 874 /* IPv6 AH wrapper. */ 875 int 876 ah6_input(struct mbuf **mp, int *offp, int proto) 877 { 878 int l = 0; 879 int protoff; 880 struct ip6_ext ip6e; 881 882 if (*offp < sizeof(struct ip6_hdr)) { 883 DPRINTF(("ah6_input(): bad offset\n")); 884 return IPPROTO_DONE; 885 } else if (*offp == sizeof(struct ip6_hdr)) { 886 protoff = offsetof(struct ip6_hdr, ip6_nxt); 887 } else { 888 /* Chase down the header chain... */ 889 protoff = sizeof(struct ip6_hdr); 890 891 do { 892 protoff += l; 893 m_copydata(*mp, protoff, sizeof(ip6e), 894 (caddr_t) &ip6e); 895 896 if (ip6e.ip6e_nxt == IPPROTO_AH) 897 l = (ip6e.ip6e_len + 2) << 2; 898 else 899 l = (ip6e.ip6e_len + 1) << 3; 900 #ifdef DIAGNOSTIC 901 if (l <= 0) 902 panic("ah6_input: l went zero or negative"); 903 #endif 904 } while (protoff + l < *offp); 905 906 /* Malformed packet check */ 907 if (protoff + l != *offp) { 908 DPRINTF(("ah6_input(): bad packet header chain\n")); 909 ahstat.ahs_hdrops++; 910 m_freem(*mp); 911 *mp = NULL; 912 return IPPROTO_DONE; 913 } 914 protoff += offsetof(struct ip6_ext, ip6e_nxt); 915 } 916 ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto); 917 return IPPROTO_DONE; 918 } 919 920 /* IPv6 AH callback. */ 921 int 922 ah6_input_cb(struct mbuf *m, int off, int protoff) 923 { 924 int nxt; 925 u_int8_t nxt8; 926 int nest = 0; 927 928 /* Retrieve new protocol */ 929 m_copydata(m, protoff, sizeof(u_int8_t), (caddr_t) &nxt8); 930 nxt = nxt8; 931 932 /* 933 * see the end of ip6_input for this logic. 934 * IPPROTO_IPV[46] case will be processed just like other ones 935 */ 936 while (nxt != IPPROTO_DONE) { 937 if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) { 938 ip6stat.ip6s_toomanyhdr++; 939 goto bad; 940 } 941 942 /* 943 * Protection against faulty packet - there should be 944 * more sanity checks in header chain processing. 945 */ 946 if (m->m_pkthdr.len < off) { 947 ip6stat.ip6s_tooshort++; 948 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated); 949 goto bad; 950 } 951 nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt); 952 } 953 return 0; 954 955 bad: 956 m_freem(m); 957 return EINVAL; 958 } 959 960 /* IPv6 ESP wrapper. */ 961 int 962 esp6_input(struct mbuf **mp, int *offp, int proto) 963 { 964 int l = 0; 965 int protoff; 966 struct ip6_ext ip6e; 967 968 if (*offp < sizeof(struct ip6_hdr)) { 969 DPRINTF(("esp6_input(): bad offset\n")); 970 return IPPROTO_DONE; 971 } else if (*offp == sizeof(struct ip6_hdr)) { 972 protoff = offsetof(struct ip6_hdr, ip6_nxt); 973 } else { 974 /* Chase down the header chain... */ 975 protoff = sizeof(struct ip6_hdr); 976 977 do { 978 protoff += l; 979 m_copydata(*mp, protoff, sizeof(ip6e), 980 (caddr_t) &ip6e); 981 982 if (ip6e.ip6e_nxt == IPPROTO_AH) 983 l = (ip6e.ip6e_len + 2) << 2; 984 else 985 l = (ip6e.ip6e_len + 1) << 3; 986 #ifdef DIAGNOSTIC 987 if (l <= 0) 988 panic("esp6_input: l went zero or negative"); 989 #endif 990 } while (protoff + l < *offp); 991 992 /* Malformed packet check */ 993 if (protoff + l != *offp) { 994 DPRINTF(("esp6_input(): bad packet header chain\n")); 995 espstat.esps_hdrops++; 996 m_freem(*mp); 997 *mp = NULL; 998 return IPPROTO_DONE; 999 } 1000 protoff += offsetof(struct ip6_ext, ip6e_nxt); 1001 } 1002 ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto); 1003 return IPPROTO_DONE; 1004 1005 } 1006 1007 /* IPv6 ESP callback */ 1008 int 1009 esp6_input_cb(struct mbuf *m, int skip, int protoff) 1010 { 1011 return ah6_input_cb(m, skip, protoff); 1012 } 1013 1014 /* IPv6 IPcomp wrapper */ 1015 int 1016 ipcomp6_input(struct mbuf **mp, int *offp, int proto) 1017 { 1018 int l = 0; 1019 int protoff; 1020 struct ip6_ext ip6e; 1021 1022 if (*offp < sizeof(struct ip6_hdr)) { 1023 DPRINTF(("ipcomp6_input(): bad offset\n")); 1024 return IPPROTO_DONE; 1025 } else if (*offp == sizeof(struct ip6_hdr)) { 1026 protoff = offsetof(struct ip6_hdr, ip6_nxt); 1027 } else { 1028 /* Chase down the header chain... */ 1029 protoff = sizeof(struct ip6_hdr); 1030 1031 do { 1032 protoff += l; 1033 m_copydata(*mp, protoff, sizeof(ip6e), 1034 (caddr_t) &ip6e); 1035 if (ip6e.ip6e_nxt == IPPROTO_AH) 1036 l = (ip6e.ip6e_len + 2) << 2; 1037 else 1038 l = (ip6e.ip6e_len + 1) << 3; 1039 #ifdef DIAGNOSTIC 1040 if (l <= 0) 1041 panic("ipcomp6_input: l went zero or negative"); 1042 #endif 1043 } while (protoff + l < *offp); 1044 1045 /* Malformed packet check */ 1046 if (protoff + l != *offp) { 1047 DPRINTF(("ipcomp6_input(): bad packet header chain\n")); 1048 ipcompstat.ipcomps_hdrops++; 1049 m_freem(*mp); 1050 *mp = NULL; 1051 return IPPROTO_DONE; 1052 } 1053 1054 protoff += offsetof(struct ip6_ext, ip6e_nxt); 1055 } 1056 ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto); 1057 return IPPROTO_DONE; 1058 } 1059 1060 /* IPv6 IPcomp callback */ 1061 int 1062 ipcomp6_input_cb(struct mbuf *m, int skip, int protoff) 1063 { 1064 return ah6_input_cb(m, skip, protoff); 1065 } 1066 1067 #endif /* INET6 */ 1068 1069 1070 1071