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