1 /* $OpenBSD: ipsec_input.c,v 1.89 2008/08/26 12:18:01 henning 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 pf_pkt_addr_changed(m); 567 #endif 568 569 if (tdbp->tdb_flags & TDBF_TUNNELING) 570 m->m_flags |= M_TUNNEL; 571 572 #if NBPFILTER > 0 573 bpfif = &encif[0].sc_if; 574 bpfif->if_ipackets++; 575 bpfif->if_ibytes += m->m_pkthdr.len; 576 577 if (bpfif->if_bpf) { 578 struct enchdr hdr; 579 580 hdr.af = af; 581 hdr.spi = tdbp->tdb_spi; 582 hdr.flags = m->m_flags & (M_AUTH|M_CONF|M_AUTH_AH); 583 584 bpf_mtap_hdr(bpfif->if_bpf, (char *)&hdr, ENC_HDRLEN, m, 585 BPF_DIRECTION_IN); 586 } 587 #endif 588 589 /* Call the appropriate IPsec transform callback. */ 590 switch (af) { 591 #ifdef INET 592 case AF_INET: 593 switch (sproto) 594 { 595 case IPPROTO_ESP: 596 return esp4_input_cb(m); 597 598 case IPPROTO_AH: 599 return ah4_input_cb(m); 600 601 case IPPROTO_IPCOMP: 602 return ipcomp4_input_cb(m); 603 604 default: 605 DPRINTF(("ipsec_common_input_cb(): unknown/unsupported" 606 " security protocol %d\n", sproto)); 607 m_freem(m); 608 return EPFNOSUPPORT; 609 } 610 break; 611 #endif /* INET */ 612 613 #ifdef INET6 614 case AF_INET6: 615 switch (sproto) { 616 case IPPROTO_ESP: 617 return esp6_input_cb(m, skip, protoff); 618 619 case IPPROTO_AH: 620 return ah6_input_cb(m, skip, protoff); 621 622 case IPPROTO_IPCOMP: 623 return ipcomp6_input_cb(m, skip, protoff); 624 625 default: 626 DPRINTF(("ipsec_common_input_cb(): unknown/unsupported" 627 " security protocol %d\n", sproto)); 628 m_freem(m); 629 return EPFNOSUPPORT; 630 } 631 break; 632 #endif /* INET6 */ 633 634 default: 635 DPRINTF(("ipsec_common_input_cb(): unknown/unsupported " 636 "protocol family %d\n", af)); 637 m_freem(m); 638 return EPFNOSUPPORT; 639 } 640 #undef IPSEC_ISTAT 641 } 642 643 int 644 esp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 645 size_t newlen) 646 { 647 /* All sysctl names at this level are terminal. */ 648 if (namelen != 1) 649 return (ENOTDIR); 650 651 switch (name[0]) { 652 case ESPCTL_STATS: 653 if (newp != NULL) 654 return (EPERM); 655 return (sysctl_struct(oldp, oldlenp, newp, newlen, 656 &espstat, sizeof(espstat))); 657 default: 658 if (name[0] < ESPCTL_MAXID) 659 return (sysctl_int_arr(espctl_vars, name, namelen, 660 oldp, oldlenp, newp, newlen)); 661 return (ENOPROTOOPT); 662 } 663 } 664 665 int 666 ah_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 667 size_t newlen) 668 { 669 /* All sysctl names at this level are terminal. */ 670 if (namelen != 1) 671 return (ENOTDIR); 672 673 switch (name[0]) { 674 case AHCTL_STATS: 675 if (newp != NULL) 676 return (EPERM); 677 return (sysctl_struct(oldp, oldlenp, newp, newlen, 678 &ahstat, sizeof(ahstat))); 679 default: 680 if (name[0] < AHCTL_MAXID) 681 return (sysctl_int_arr(ahctl_vars, name, namelen, 682 oldp, oldlenp, newp, newlen)); 683 return (ENOPROTOOPT); 684 } 685 } 686 687 int 688 ipcomp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, 689 size_t newlen) 690 { 691 /* All sysctl names at this level are terminal. */ 692 if (namelen != 1) 693 return (ENOTDIR); 694 695 switch (name[0]) { 696 case IPCOMPCTL_STATS: 697 if (newp != NULL) 698 return (EPERM); 699 return (sysctl_struct(oldp, oldlenp, newp, newlen, 700 &ipcompstat, sizeof(ipcompstat))); 701 default: 702 if (name[0] < IPCOMPCTL_MAXID) 703 return (sysctl_int_arr(ipcompctl_vars, name, namelen, 704 oldp, oldlenp, newp, newlen)); 705 return (ENOPROTOOPT); 706 } 707 } 708 709 #ifdef INET 710 /* IPv4 AH wrapper. */ 711 void 712 ah4_input(struct mbuf *m, ...) 713 { 714 int skip; 715 716 va_list ap; 717 va_start(ap, m); 718 skip = va_arg(ap, int); 719 va_end(ap); 720 721 ipsec_common_input(m, skip, offsetof(struct ip, ip_p), AF_INET, 722 IPPROTO_AH, 0); 723 return; 724 } 725 726 /* IPv4 AH callback. */ 727 int 728 ah4_input_cb(struct mbuf *m, ...) 729 { 730 struct ifqueue *ifq = &ipintrq; 731 int s = splnet(); 732 733 /* 734 * Interface pointer is already in first mbuf; chop off the 735 * `outer' header and reschedule. 736 */ 737 738 if (IF_QFULL(ifq)) { 739 IF_DROP(ifq); 740 ahstat.ahs_qfull++; 741 splx(s); 742 743 m_freem(m); 744 DPRINTF(("ah4_input_cb(): dropped packet because of full " 745 "IP queue\n")); 746 return ENOBUFS; 747 } 748 749 IF_ENQUEUE(ifq, m); 750 schednetisr(NETISR_IP); 751 splx(s); 752 return 0; 753 } 754 755 756 void * 757 ah4_ctlinput(int cmd, struct sockaddr *sa, void *v) 758 { 759 if (sa->sa_family != AF_INET || 760 sa->sa_len != sizeof(struct sockaddr_in)) 761 return (NULL); 762 763 return (ipsec_common_ctlinput(cmd, sa, v, IPPROTO_AH)); 764 } 765 766 /* IPv4 ESP wrapper. */ 767 void 768 esp4_input(struct mbuf *m, ...) 769 { 770 int skip; 771 772 va_list ap; 773 va_start(ap, m); 774 skip = va_arg(ap, int); 775 va_end(ap); 776 777 ipsec_common_input(m, skip, offsetof(struct ip, ip_p), AF_INET, 778 IPPROTO_ESP, 0); 779 } 780 781 /* IPv4 ESP callback. */ 782 int 783 esp4_input_cb(struct mbuf *m, ...) 784 { 785 struct ifqueue *ifq = &ipintrq; 786 int s = splnet(); 787 788 /* 789 * Interface pointer is already in first mbuf; chop off the 790 * `outer' header and reschedule. 791 */ 792 if (IF_QFULL(ifq)) { 793 IF_DROP(ifq); 794 espstat.esps_qfull++; 795 splx(s); 796 797 m_freem(m); 798 DPRINTF(("esp4_input_cb(): dropped packet because of full " 799 "IP queue\n")); 800 return ENOBUFS; 801 } 802 803 IF_ENQUEUE(ifq, m); 804 schednetisr(NETISR_IP); 805 splx(s); 806 return 0; 807 } 808 809 /* IPv4 IPCOMP wrapper */ 810 void 811 ipcomp4_input(struct mbuf *m, ...) 812 { 813 int skip; 814 va_list ap; 815 va_start(ap, m); 816 skip = va_arg(ap, int); 817 va_end(ap); 818 819 ipsec_common_input(m, skip, offsetof(struct ip, ip_p), AF_INET, 820 IPPROTO_IPCOMP, 0); 821 } 822 823 /* IPv4 IPCOMP callback */ 824 int 825 ipcomp4_input_cb(struct mbuf *m, ...) 826 { 827 struct ifqueue *ifq = &ipintrq; 828 int s = splnet(); 829 830 /* 831 * Interface pointer is already in first mbuf; chop off the 832 * `outer' header and reschedule. 833 */ 834 if (IF_QFULL(ifq)) { 835 IF_DROP(ifq); 836 ipcompstat.ipcomps_qfull++; 837 splx(s); 838 839 m_freem(m); 840 DPRINTF(("ipcomp4_input_cb(): dropped packet because of full IP queue\n")); 841 return ENOBUFS; 842 } 843 844 IF_ENQUEUE(ifq, m); 845 schednetisr(NETISR_IP); 846 splx(s); 847 848 return 0; 849 } 850 851 void * 852 ipsec_common_ctlinput(int cmd, struct sockaddr *sa, void *v, int proto) 853 { 854 extern u_int ip_mtudisc_timeout; 855 struct ip *ip = v; 856 int s; 857 858 if (cmd == PRC_MSGSIZE && ip && ip_mtudisc && ip->ip_v == 4) { 859 struct tdb *tdbp; 860 struct sockaddr_in dst; 861 struct icmp *icp; 862 int hlen = ip->ip_hl << 2; 863 u_int32_t spi, mtu; 864 ssize_t adjust; 865 866 /* Find the right MTU. */ 867 icp = (struct icmp *)((caddr_t) ip - 868 offsetof(struct icmp, icmp_ip)); 869 mtu = ntohs(icp->icmp_nextmtu); 870 871 /* 872 * Ignore the packet, if we do not receive a MTU 873 * or the MTU is too small to be acceptable. 874 */ 875 if (mtu < 296) 876 return (NULL); 877 878 bzero(&dst, sizeof(struct sockaddr_in)); 879 dst.sin_family = AF_INET; 880 dst.sin_len = sizeof(struct sockaddr_in); 881 dst.sin_addr.s_addr = ip->ip_dst.s_addr; 882 883 bcopy((caddr_t)ip + hlen, &spi, sizeof(u_int32_t)); 884 885 s = spltdb(); 886 tdbp = gettdb(spi, (union sockaddr_union *)&dst, proto); 887 if (tdbp == NULL || tdbp->tdb_flags & TDBF_INVALID) { 888 splx(s); 889 return (NULL); 890 } 891 892 /* Walk the chain backswards to the first tdb */ 893 for (; tdbp; tdbp = tdbp->tdb_inext) { 894 if (tdbp->tdb_flags & TDBF_INVALID || 895 (adjust = ipsec_hdrsz(tdbp)) == -1) { 896 splx(s); 897 return (NULL); 898 } 899 900 mtu -= adjust; 901 902 /* Store adjusted MTU in tdb */ 903 tdbp->tdb_mtu = mtu; 904 tdbp->tdb_mtutimeout = time_second + 905 ip_mtudisc_timeout; 906 DPRINTF(("ipsec_common_ctlinput: " 907 "spi %08x mtu %d adjust %d\n", 908 ntohl(tdbp->tdb_spi), tdbp->tdb_mtu, 909 adjust)); 910 } 911 splx(s); 912 return (NULL); 913 } 914 return (NULL); 915 } 916 917 void * 918 udpencap_ctlinput(int cmd, struct sockaddr *sa, void *v) 919 { 920 struct ip *ip = v; 921 struct tdb *tdbp; 922 struct icmp *icp; 923 u_int32_t mtu; 924 ssize_t adjust; 925 struct sockaddr_in dst, src; 926 union sockaddr_union *su_dst, *su_src; 927 int s; 928 929 icp = (struct icmp *)((caddr_t) ip - offsetof(struct icmp, icmp_ip)); 930 mtu = ntohs(icp->icmp_nextmtu); 931 932 /* 933 * Ignore the packet, if we do not receive a MTU 934 * or the MTU is too small to be acceptable. 935 */ 936 if (mtu < 296) 937 return (NULL); 938 939 bzero(&dst, sizeof(dst)); 940 dst.sin_family = AF_INET; 941 dst.sin_len = sizeof(struct sockaddr_in); 942 dst.sin_addr.s_addr = ip->ip_dst.s_addr; 943 su_dst = (union sockaddr_union *)&dst; 944 bzero(&src, sizeof(src)); 945 src.sin_family = AF_INET; 946 src.sin_len = sizeof(struct sockaddr_in); 947 src.sin_addr.s_addr = ip->ip_src.s_addr; 948 su_src = (union sockaddr_union *)&src; 949 950 s = spltdb(); 951 tdbp = gettdbbysrcdst(0, su_src, su_dst, IPPROTO_ESP); 952 953 for (; tdbp != NULL; tdbp = tdbp->tdb_snext) { 954 if (tdbp->tdb_sproto == IPPROTO_ESP && 955 ((tdbp->tdb_flags & (TDBF_INVALID|TDBF_UDPENCAP)) 956 == TDBF_UDPENCAP) && 957 !bcmp(&tdbp->tdb_dst, &dst, SA_LEN(&su_dst->sa)) && 958 !bcmp(&tdbp->tdb_src, &src, SA_LEN(&su_src->sa))) { 959 if ((adjust = ipsec_hdrsz(tdbp)) != -1) { 960 /* Store adjusted MTU in tdb */ 961 tdbp->tdb_mtu = mtu - adjust; 962 tdbp->tdb_mtutimeout = time_second + 963 ip_mtudisc_timeout; 964 DPRINTF(("udpencap_ctlinput: " 965 "spi %08x mtu %d adjust %d\n", 966 ntohl(tdbp->tdb_spi), tdbp->tdb_mtu, 967 adjust)); 968 } 969 } 970 } 971 splx(s); 972 return (NULL); 973 } 974 975 void * 976 esp4_ctlinput(int cmd, struct sockaddr *sa, void *v) 977 { 978 if (sa->sa_family != AF_INET || 979 sa->sa_len != sizeof(struct sockaddr_in)) 980 return (NULL); 981 982 return (ipsec_common_ctlinput(cmd, sa, v, IPPROTO_ESP)); 983 } 984 #endif /* INET */ 985 986 #ifdef INET6 987 /* IPv6 AH wrapper. */ 988 int 989 ah6_input(struct mbuf **mp, int *offp, int proto) 990 { 991 int l = 0; 992 int protoff, nxt; 993 struct ip6_ext ip6e; 994 995 if (*offp < sizeof(struct ip6_hdr)) { 996 DPRINTF(("ah6_input(): bad offset\n")); 997 return IPPROTO_DONE; 998 } else if (*offp == sizeof(struct ip6_hdr)) { 999 protoff = offsetof(struct ip6_hdr, ip6_nxt); 1000 } else { 1001 /* Chase down the header chain... */ 1002 protoff = sizeof(struct ip6_hdr); 1003 nxt = (mtod(*mp, struct ip6_hdr *))->ip6_nxt; 1004 1005 do { 1006 protoff += l; 1007 m_copydata(*mp, protoff, sizeof(ip6e), 1008 (caddr_t) &ip6e); 1009 1010 if (nxt == IPPROTO_AH) 1011 l = (ip6e.ip6e_len + 2) << 2; 1012 else 1013 l = (ip6e.ip6e_len + 1) << 3; 1014 #ifdef DIAGNOSTIC 1015 if (l <= 0) 1016 panic("ah6_input: l went zero or negative"); 1017 #endif 1018 1019 nxt = ip6e.ip6e_nxt; 1020 } while (protoff + l < *offp); 1021 1022 /* Malformed packet check */ 1023 if (protoff + l != *offp) { 1024 DPRINTF(("ah6_input(): bad packet header chain\n")); 1025 ahstat.ahs_hdrops++; 1026 m_freem(*mp); 1027 *mp = NULL; 1028 return IPPROTO_DONE; 1029 } 1030 protoff += offsetof(struct ip6_ext, ip6e_nxt); 1031 } 1032 ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto, 0); 1033 return IPPROTO_DONE; 1034 } 1035 1036 /* IPv6 AH callback. */ 1037 int 1038 ah6_input_cb(struct mbuf *m, int off, int protoff) 1039 { 1040 int nxt; 1041 u_int8_t nxt8; 1042 int nest = 0; 1043 1044 /* Retrieve new protocol */ 1045 m_copydata(m, protoff, sizeof(u_int8_t), (caddr_t) &nxt8); 1046 nxt = nxt8; 1047 1048 /* 1049 * see the end of ip6_input for this logic. 1050 * IPPROTO_IPV[46] case will be processed just like other ones 1051 */ 1052 while (nxt != IPPROTO_DONE) { 1053 if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) { 1054 ip6stat.ip6s_toomanyhdr++; 1055 goto bad; 1056 } 1057 1058 /* 1059 * Protection against faulty packet - there should be 1060 * more sanity checks in header chain processing. 1061 */ 1062 if (m->m_pkthdr.len < off) { 1063 ip6stat.ip6s_tooshort++; 1064 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated); 1065 goto bad; 1066 } 1067 nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt); 1068 } 1069 return 0; 1070 1071 bad: 1072 m_freem(m); 1073 return EINVAL; 1074 } 1075 1076 /* IPv6 ESP wrapper. */ 1077 int 1078 esp6_input(struct mbuf **mp, int *offp, int proto) 1079 { 1080 int l = 0; 1081 int protoff, nxt; 1082 struct ip6_ext ip6e; 1083 1084 if (*offp < sizeof(struct ip6_hdr)) { 1085 DPRINTF(("esp6_input(): bad offset\n")); 1086 return IPPROTO_DONE; 1087 } else if (*offp == sizeof(struct ip6_hdr)) { 1088 protoff = offsetof(struct ip6_hdr, ip6_nxt); 1089 } else { 1090 /* Chase down the header chain... */ 1091 protoff = sizeof(struct ip6_hdr); 1092 nxt = (mtod(*mp, struct ip6_hdr *))->ip6_nxt; 1093 1094 do { 1095 protoff += l; 1096 m_copydata(*mp, protoff, sizeof(ip6e), 1097 (caddr_t) &ip6e); 1098 1099 if (nxt == IPPROTO_AH) 1100 l = (ip6e.ip6e_len + 2) << 2; 1101 else 1102 l = (ip6e.ip6e_len + 1) << 3; 1103 #ifdef DIAGNOSTIC 1104 if (l <= 0) 1105 panic("esp6_input: l went zero or negative"); 1106 #endif 1107 1108 nxt = ip6e.ip6e_nxt; 1109 } while (protoff + l < *offp); 1110 1111 /* Malformed packet check */ 1112 if (protoff + l != *offp) { 1113 DPRINTF(("esp6_input(): bad packet header chain\n")); 1114 espstat.esps_hdrops++; 1115 m_freem(*mp); 1116 *mp = NULL; 1117 return IPPROTO_DONE; 1118 } 1119 protoff += offsetof(struct ip6_ext, ip6e_nxt); 1120 } 1121 ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto, 0); 1122 return IPPROTO_DONE; 1123 1124 } 1125 1126 /* IPv6 ESP callback */ 1127 int 1128 esp6_input_cb(struct mbuf *m, int skip, int protoff) 1129 { 1130 return ah6_input_cb(m, skip, protoff); 1131 } 1132 1133 /* IPv6 IPcomp wrapper */ 1134 int 1135 ipcomp6_input(struct mbuf **mp, int *offp, int proto) 1136 { 1137 int l = 0; 1138 int protoff, nxt; 1139 struct ip6_ext ip6e; 1140 1141 if (*offp < sizeof(struct ip6_hdr)) { 1142 DPRINTF(("ipcomp6_input(): bad offset\n")); 1143 return IPPROTO_DONE; 1144 } else if (*offp == sizeof(struct ip6_hdr)) { 1145 protoff = offsetof(struct ip6_hdr, ip6_nxt); 1146 } else { 1147 /* Chase down the header chain... */ 1148 protoff = sizeof(struct ip6_hdr); 1149 nxt = (mtod(*mp, struct ip6_hdr *))->ip6_nxt; 1150 1151 do { 1152 protoff += l; 1153 m_copydata(*mp, protoff, sizeof(ip6e), 1154 (caddr_t) &ip6e); 1155 if (nxt == IPPROTO_AH) 1156 l = (ip6e.ip6e_len + 2) << 2; 1157 else 1158 l = (ip6e.ip6e_len + 1) << 3; 1159 #ifdef DIAGNOSTIC 1160 if (l <= 0) 1161 panic("ipcomp6_input: l went zero or negative"); 1162 #endif 1163 1164 nxt = ip6e.ip6e_nxt; 1165 } while (protoff + l < *offp); 1166 1167 /* Malformed packet check */ 1168 if (protoff + l != *offp) { 1169 DPRINTF(("ipcomp6_input(): bad packet header chain\n")); 1170 ipcompstat.ipcomps_hdrops++; 1171 m_freem(*mp); 1172 *mp = NULL; 1173 return IPPROTO_DONE; 1174 } 1175 1176 protoff += offsetof(struct ip6_ext, ip6e_nxt); 1177 } 1178 ipsec_common_input(*mp, *offp, protoff, AF_INET6, proto, 0); 1179 return IPPROTO_DONE; 1180 } 1181 1182 /* IPv6 IPcomp callback */ 1183 int 1184 ipcomp6_input_cb(struct mbuf *m, int skip, int protoff) 1185 { 1186 return ah6_input_cb(m, skip, protoff); 1187 } 1188 1189 #endif /* INET6 */ 1190