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