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