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