root/netinet/ip_esp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. esp_attach
  2. esp_init
  3. esp_zeroize
  4. esp_input
  5. esp_input_cb
  6. esp_output
  7. esp_output_cb
  8. checkreplaywindow32
  9. m_pad

    1 /*      $OpenBSD: ip_esp.c,v 1.100 2006/12/15 09:32:30 otto 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  * The original version of this code was written by John Ioannidis
    8  * for BSD/OS in Athens, Greece, 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 "pfsync.h"
   39 
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/mbuf.h>
   43 #include <sys/socket.h>
   44 
   45 #include <net/if.h>
   46 #include <net/bpf.h>
   47 
   48 #include <dev/rndvar.h>
   49 
   50 #ifdef INET
   51 #include <netinet/in.h>
   52 #include <netinet/in_systm.h>
   53 #include <netinet/ip.h>
   54 #include <netinet/ip_var.h>
   55 #endif /* INET */
   56 
   57 #ifdef INET6
   58 #ifndef INET
   59 #include <netinet/in.h>
   60 #endif
   61 #include <netinet/ip6.h>
   62 #endif /* INET6 */
   63 
   64 #include <netinet/ip_ipsp.h>
   65 #include <netinet/ip_esp.h>
   66 #include <net/pfkeyv2.h>
   67 #include <net/if_enc.h>
   68 
   69 #if NPFSYNC > 0
   70 #include <net/pfvar.h>
   71 #include <net/if_pfsync.h>
   72 #endif /* NPFSYNC > 0 */
   73 
   74 #include <crypto/cryptodev.h>
   75 #include <crypto/xform.h>
   76 
   77 #include "bpfilter.h"
   78 
   79 #ifdef ENCDEBUG
   80 #define DPRINTF(x)      if (encdebug) printf x
   81 #else
   82 #define DPRINTF(x)
   83 #endif
   84 
   85 struct espstat espstat;
   86 
   87 /*
   88  * esp_attach() is called from the transformation initialization code.
   89  */
   90 int
   91 esp_attach()
   92 {
   93         return 0;
   94 }
   95 
   96 /*
   97  * esp_init() is called when an SPI is being set up.
   98  */
   99 int
  100 esp_init(struct tdb *tdbp, struct xformsw *xsp, struct ipsecinit *ii)
  101 {
  102         struct enc_xform *txform = NULL;
  103         struct auth_hash *thash = NULL;
  104         struct cryptoini cria, crie;
  105 
  106         if (!ii->ii_encalg && !ii->ii_authalg) {
  107                 DPRINTF(("esp_init(): neither authentication nor encryption "
  108                     "algorithm given"));
  109                 return EINVAL;
  110         }
  111 
  112         if (ii->ii_encalg) {
  113                 switch (ii->ii_encalg) {
  114                 case SADB_EALG_NULL:
  115                         txform = &enc_xform_null;
  116                         break;
  117 
  118                 case SADB_EALG_DESCBC:
  119                         txform = &enc_xform_des;
  120                         break;
  121 
  122                 case SADB_EALG_3DESCBC:
  123                         txform = &enc_xform_3des;
  124                         break;
  125 
  126                 case SADB_X_EALG_AES:
  127                         txform = &enc_xform_rijndael128;
  128                         break;
  129 
  130                 case SADB_X_EALG_AESCTR:
  131                         txform = &enc_xform_aes_ctr;
  132                         break;
  133 
  134                 case SADB_X_EALG_BLF:
  135                         txform = &enc_xform_blf;
  136                         break;
  137 
  138                 case SADB_X_EALG_CAST:
  139                         txform = &enc_xform_cast5;
  140                         break;
  141 
  142                 case SADB_X_EALG_SKIPJACK:
  143                         txform = &enc_xform_skipjack;
  144                         break;
  145 
  146                 default:
  147                         DPRINTF(("esp_init(): unsupported encryption algorithm %d specified\n", ii->ii_encalg));
  148                         return EINVAL;
  149                 }
  150 
  151                 if (ii->ii_enckeylen < txform->minkey) {
  152                         DPRINTF(("esp_init(): keylength %d too small (min length is %d) for algorithm %s\n", ii->ii_enckeylen, txform->minkey, txform->name));
  153                         return EINVAL;
  154                 }
  155 
  156                 if (ii->ii_enckeylen > txform->maxkey) {
  157                         DPRINTF(("esp_init(): keylength %d too large (max length is %d) for algorithm %s\n", ii->ii_enckeylen, txform->maxkey, txform->name));
  158                         return EINVAL;
  159                 }
  160 
  161                 tdbp->tdb_encalgxform = txform;
  162 
  163                 DPRINTF(("esp_init(): initialized TDB with enc algorithm %s\n",
  164                     txform->name));
  165 
  166                 tdbp->tdb_ivlen = txform->ivsize;
  167                 if (tdbp->tdb_flags & TDBF_HALFIV)
  168                         tdbp->tdb_ivlen /= 2;
  169         }
  170 
  171         if (ii->ii_authalg) {
  172                 switch (ii->ii_authalg) {
  173                 case SADB_AALG_MD5HMAC:
  174                         thash = &auth_hash_hmac_md5_96;
  175                         break;
  176 
  177                 case SADB_AALG_SHA1HMAC:
  178                         thash = &auth_hash_hmac_sha1_96;
  179                         break;
  180 
  181                 case SADB_X_AALG_RIPEMD160HMAC:
  182                         thash = &auth_hash_hmac_ripemd_160_96;
  183                         break;
  184 
  185                 case SADB_X_AALG_SHA2_256:
  186                         thash = &auth_hash_hmac_sha2_256_96;
  187                         break;
  188 
  189                 case SADB_X_AALG_SHA2_384:
  190                         thash = &auth_hash_hmac_sha2_384_96;
  191                         break;
  192 
  193                 case SADB_X_AALG_SHA2_512:
  194                         thash = &auth_hash_hmac_sha2_512_96;
  195                         break;
  196 
  197                 default:
  198                         DPRINTF(("esp_init(): unsupported authentication algorithm %d specified\n", ii->ii_authalg));
  199                         return EINVAL;
  200                 }
  201 
  202                 if (ii->ii_authkeylen != thash->keysize) {
  203                         DPRINTF(("esp_init(): keylength %d doesn't match algorithm %s keysize (%d)\n", ii->ii_authkeylen, thash->name, thash->keysize));
  204                         return EINVAL;
  205                 }
  206 
  207                 tdbp->tdb_authalgxform = thash;
  208 
  209                 DPRINTF(("esp_init(): initialized TDB with hash algorithm %s\n",
  210                     thash->name));
  211         }
  212 
  213         tdbp->tdb_xform = xsp;
  214         tdbp->tdb_bitmap = 0;
  215         tdbp->tdb_rpl = AH_HMAC_INITIAL_RPL;
  216 
  217         /* Initialize crypto session */
  218         if (tdbp->tdb_encalgxform) {
  219                 /* Save the raw keys */
  220                 tdbp->tdb_emxkeylen = ii->ii_enckeylen;
  221                 MALLOC(tdbp->tdb_emxkey, u_int8_t *, tdbp->tdb_emxkeylen,
  222                     M_XDATA, M_WAITOK);
  223                 bcopy(ii->ii_enckey, tdbp->tdb_emxkey, tdbp->tdb_emxkeylen);
  224 
  225                 bzero(&crie, sizeof(crie));
  226 
  227                 crie.cri_alg = tdbp->tdb_encalgxform->type;
  228 
  229                 if (tdbp->tdb_authalgxform)
  230                         crie.cri_next = &cria;
  231                 else
  232                         crie.cri_next = NULL;
  233 
  234                 crie.cri_klen = ii->ii_enckeylen * 8;
  235                 crie.cri_key = ii->ii_enckey;
  236                 /* XXX Rounds ? */
  237         }
  238 
  239         if (tdbp->tdb_authalgxform) {
  240                 /* Save the raw keys */
  241                 tdbp->tdb_amxkeylen = ii->ii_authkeylen;
  242                 MALLOC(tdbp->tdb_amxkey, u_int8_t *, tdbp->tdb_amxkeylen, M_XDATA,
  243                     M_WAITOK);
  244                 bcopy(ii->ii_authkey, tdbp->tdb_amxkey, tdbp->tdb_amxkeylen);
  245 
  246                 bzero(&cria, sizeof(cria));
  247 
  248                 cria.cri_alg = tdbp->tdb_authalgxform->type;
  249                 cria.cri_next = NULL;
  250                 cria.cri_klen = ii->ii_authkeylen * 8;
  251                 cria.cri_key = ii->ii_authkey;
  252         }
  253 
  254         return crypto_newsession(&tdbp->tdb_cryptoid,
  255             (tdbp->tdb_encalgxform ? &crie : &cria), 0);
  256 }
  257 
  258 /*
  259  * Paranoia.
  260  */
  261 int
  262 esp_zeroize(struct tdb *tdbp)
  263 {
  264         int err;
  265 
  266         if (tdbp->tdb_amxkey) {
  267                 bzero(tdbp->tdb_amxkey, tdbp->tdb_amxkeylen);
  268                 FREE(tdbp->tdb_amxkey, M_XDATA);
  269                 tdbp->tdb_amxkey = NULL;
  270         }
  271 
  272         if (tdbp->tdb_emxkey) {
  273                 bzero(tdbp->tdb_emxkey, tdbp->tdb_emxkeylen);
  274                 FREE(tdbp->tdb_emxkey, M_XDATA);
  275                 tdbp->tdb_emxkey = NULL;
  276         }
  277 
  278         err = crypto_freesession(tdbp->tdb_cryptoid);
  279         tdbp->tdb_cryptoid = 0;
  280         return err;
  281 }
  282 
  283 #define MAXBUFSIZ (AH_ALEN_MAX > ESP_MAX_IVS ? AH_ALEN_MAX : ESP_MAX_IVS)
  284 
  285 /*
  286  * ESP input processing, called (eventually) through the protocol switch.
  287  */
  288 int
  289 esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff)
  290 {
  291         struct auth_hash *esph = (struct auth_hash *) tdb->tdb_authalgxform;
  292         struct enc_xform *espx = (struct enc_xform *) tdb->tdb_encalgxform;
  293         struct tdb_crypto *tc;
  294         int plen, alen, hlen;
  295         struct m_tag *mtag;
  296         u_int32_t btsx;
  297 
  298         struct cryptodesc *crde = NULL, *crda = NULL;
  299         struct cryptop *crp;
  300 
  301         /* Determine the ESP header length */
  302         if (tdb->tdb_flags & TDBF_NOREPLAY)
  303                 hlen = sizeof(u_int32_t) + tdb->tdb_ivlen; /* "old" ESP */
  304         else
  305                 hlen = 2 * sizeof(u_int32_t) + tdb->tdb_ivlen; /* "new" ESP */
  306 
  307         if (esph)
  308                 alen = AH_HMAC_HASHLEN;
  309         else
  310                 alen = 0;
  311 
  312         plen = m->m_pkthdr.len - (skip + hlen + alen);
  313         if (plen <= 0) {
  314                 DPRINTF(("esp_input: invalid payload length\n"));
  315                 espstat.esps_badilen++;
  316                 m_freem(m);
  317                 return EINVAL;
  318         }
  319 
  320         if (espx) {
  321                 /*
  322                  * Verify payload length is multiple of encryption algorithm
  323                  * block size.
  324                  */
  325                 if (plen & (espx->blocksize - 1)) {
  326                         DPRINTF(("esp_input(): payload of %d octets not a multiple of %d octets, SA %s/%08x\n", plen, espx->blocksize, ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
  327                         espstat.esps_badilen++;
  328                         m_freem(m);
  329                         return EINVAL;
  330                 }
  331         }
  332 
  333         /* Replay window checking, if appropriate -- no value commitment. */
  334         if ((tdb->tdb_wnd > 0) && (!(tdb->tdb_flags & TDBF_NOREPLAY))) {
  335                 m_copydata(m, skip + sizeof(u_int32_t), sizeof(u_int32_t),
  336                     (unsigned char *) &btsx);
  337                 btsx = ntohl(btsx);
  338 
  339                 switch (checkreplaywindow32(btsx, 0, &(tdb->tdb_rpl),
  340                     tdb->tdb_wnd, &(tdb->tdb_bitmap), 0)) {
  341                 case 0: /* All's well */
  342                         break;
  343 
  344                 case 1:
  345                         m_freem(m);
  346                         DPRINTF(("esp_input(): replay counter wrapped for SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
  347                         espstat.esps_wrap++;
  348                         return EACCES;
  349 
  350                 case 2:
  351                 case 3:
  352                         DPRINTF(("esp_input(): duplicate packet received in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
  353                         m_freem(m);
  354                         return EACCES;
  355 
  356                 default:
  357                         m_freem(m);
  358                         DPRINTF(("esp_input(): bogus value from checkreplaywindow32() in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
  359                         espstat.esps_replay++;
  360                         return EACCES;
  361                 }
  362         }
  363 
  364         /* Update the counters */
  365         tdb->tdb_cur_bytes += m->m_pkthdr.len - skip - hlen - alen;
  366         espstat.esps_ibytes += m->m_pkthdr.len - skip - hlen - alen;
  367 
  368         /* Hard expiration */
  369         if ((tdb->tdb_flags & TDBF_BYTES) &&
  370             (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes)) {
  371                 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
  372                 tdb_delete(tdb);
  373                 m_freem(m);
  374                 return ENXIO;
  375         }
  376 
  377         /* Notify on soft expiration */
  378         if ((tdb->tdb_flags & TDBF_SOFT_BYTES) &&
  379             (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes)) {
  380                 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
  381                 tdb->tdb_flags &= ~TDBF_SOFT_BYTES;       /* Turn off checking */
  382         }
  383 
  384 #ifdef notyet
  385         /* Find out if we've already done crypto */
  386         for (mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, NULL);
  387              mtag != NULL;
  388              mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_CRYPTO_DONE, mtag)) {
  389                 struct tdb_ident *tdbi;
  390 
  391                 tdbi = (struct tdb_ident *) (mtag + 1);
  392                 if (tdbi->proto == tdb->tdb_sproto && tdbi->spi == tdb->tdb_spi &&
  393                     !bcmp(&tdbi->dst, &tdb->tdb_dst, sizeof(union sockaddr_union)))
  394                         break;
  395         }
  396 #else
  397         mtag = NULL;
  398 #endif
  399 
  400         /* Get crypto descriptors */
  401         crp = crypto_getreq(esph && espx ? 2 : 1);
  402         if (crp == NULL) {
  403                 m_freem(m);
  404                 DPRINTF(("esp_input(): failed to acquire crypto descriptors\n"));
  405                 espstat.esps_crypto++;
  406                 return ENOBUFS;
  407         }
  408 
  409         /* Get IPsec-specific opaque pointer */
  410         if (esph == NULL || mtag != NULL)
  411                 MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto),
  412                     M_XDATA, M_NOWAIT);
  413         else
  414                 MALLOC(tc, struct tdb_crypto *,
  415                     sizeof(struct tdb_crypto) + alen, M_XDATA, M_NOWAIT);
  416         if (tc == NULL) {
  417                 m_freem(m);
  418                 crypto_freereq(crp);
  419                 DPRINTF(("esp_input(): failed to allocate tdb_crypto\n"));
  420                 espstat.esps_crypto++;
  421                 return ENOBUFS;
  422         }
  423 
  424         bzero(tc, sizeof(struct tdb_crypto));
  425         tc->tc_ptr = (caddr_t) mtag;
  426 
  427         if (esph) {
  428                 crda = crp->crp_desc;
  429                 crde = crda->crd_next;
  430 
  431                 /* Authentication descriptor */
  432                 crda->crd_skip = skip;
  433                 crda->crd_len = m->m_pkthdr.len - (skip + alen);
  434                 crda->crd_inject = m->m_pkthdr.len - alen;
  435 
  436                 crda->crd_alg = esph->type;
  437                 crda->crd_key = tdb->tdb_amxkey;
  438                 crda->crd_klen = tdb->tdb_amxkeylen * 8;
  439 
  440                 /* Copy the authenticator */
  441                 if (mtag == NULL)
  442                         m_copydata(m, m->m_pkthdr.len - alen, alen, (caddr_t) (tc + 1));
  443         } else
  444                 crde = crp->crp_desc;
  445 
  446         /* Crypto operation descriptor */
  447         crp->crp_ilen = m->m_pkthdr.len; /* Total input length */
  448         crp->crp_flags = CRYPTO_F_IMBUF;
  449         crp->crp_buf = (caddr_t) m;
  450         crp->crp_callback = (int (*) (struct cryptop *)) esp_input_cb;
  451         crp->crp_sid = tdb->tdb_cryptoid;
  452         crp->crp_opaque = (caddr_t) tc;
  453 
  454         /* These are passed as-is to the callback */
  455         tc->tc_skip = skip;
  456         tc->tc_protoff = protoff;
  457         tc->tc_spi = tdb->tdb_spi;
  458         tc->tc_proto = tdb->tdb_sproto;
  459         bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
  460 
  461         /* Decryption descriptor */
  462         if (espx) {
  463                 crde->crd_skip = skip + hlen;
  464                 crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen);
  465                 crde->crd_inject = skip + hlen - tdb->tdb_ivlen;
  466 
  467                 if (tdb->tdb_flags & TDBF_HALFIV) {
  468                         /* Copy half-IV from packet */
  469                         m_copydata(m, crde->crd_inject, tdb->tdb_ivlen, crde->crd_iv);
  470 
  471                         /* Cook IV */
  472                         for (btsx = 0; btsx < tdb->tdb_ivlen; btsx++)
  473                                 crde->crd_iv[tdb->tdb_ivlen + btsx] = ~crde->crd_iv[btsx];
  474 
  475                         crde->crd_flags |= CRD_F_IV_EXPLICIT;
  476                 }
  477 
  478                 crde->crd_alg = espx->type;
  479                 crde->crd_key = tdb->tdb_emxkey;
  480                 crde->crd_klen = tdb->tdb_emxkeylen * 8;
  481                 /* XXX Rounds ? */
  482         }
  483 
  484         if (mtag == NULL)
  485                 return crypto_dispatch(crp);
  486         else
  487                 return esp_input_cb(crp);
  488 }
  489 
  490 /*
  491  * ESP input callback, called directly by the crypto driver.
  492  */
  493 int
  494 esp_input_cb(void *op)
  495 {
  496         u_int8_t lastthree[3], aalg[AH_HMAC_HASHLEN];
  497         int s, hlen, roff, skip, protoff, error;
  498         struct mbuf *m1, *mo, *m;
  499         struct auth_hash *esph;
  500         struct tdb_crypto *tc;
  501         struct cryptop *crp;
  502         struct m_tag *mtag;
  503         struct tdb *tdb;
  504         u_int32_t btsx;
  505         caddr_t ptr;
  506 
  507         crp = (struct cryptop *) op;
  508 
  509         tc = (struct tdb_crypto *) crp->crp_opaque;
  510         skip = tc->tc_skip;
  511         protoff = tc->tc_protoff;
  512         mtag = (struct m_tag *) tc->tc_ptr;
  513 
  514         m = (struct mbuf *) crp->crp_buf;
  515         if (m == NULL) {
  516                 /* Shouldn't happen... */
  517                 FREE(tc, M_XDATA);
  518                 crypto_freereq(crp);
  519                 espstat.esps_crypto++;
  520                 DPRINTF(("esp_input_cb(): bogus returned buffer from crypto\n"));
  521                 return (EINVAL);
  522         }
  523 
  524         s = spltdb();
  525 
  526         tdb = gettdb(tc->tc_spi, &tc->tc_dst, tc->tc_proto);
  527         if (tdb == NULL) {
  528                 FREE(tc, M_XDATA);
  529                 espstat.esps_notdb++;
  530                 DPRINTF(("esp_input_cb(): TDB is expired while in crypto"));
  531                 error = EPERM;
  532                 goto baddone;
  533         }
  534 
  535         esph = (struct auth_hash *) tdb->tdb_authalgxform;
  536 
  537         /* Check for crypto errors */
  538         if (crp->crp_etype) {
  539                 if (crp->crp_etype == EAGAIN) {
  540                         /* Reset the session ID */
  541                         if (tdb->tdb_cryptoid != 0)
  542                                 tdb->tdb_cryptoid = crp->crp_sid;
  543                         splx(s);
  544                         return crypto_dispatch(crp);
  545                 }
  546                 FREE(tc, M_XDATA);
  547                 espstat.esps_noxform++;
  548                 DPRINTF(("esp_input_cb(): crypto error %d\n", crp->crp_etype));
  549                 error = crp->crp_etype;
  550                 goto baddone;
  551         }
  552 
  553         /* If authentication was performed, check now. */
  554         if (esph != NULL) {
  555                 /*
  556                  * If we have a tag, it means an IPsec-aware NIC did the verification
  557                  * for us.
  558                  */
  559                 if (mtag == NULL) {
  560                         /* Copy the authenticator from the packet */
  561                         m_copydata(m, m->m_pkthdr.len - esph->authsize,
  562                             esph->authsize, aalg);
  563 
  564                         ptr = (caddr_t) (tc + 1);
  565 
  566                         /* Verify authenticator */
  567                         if (bcmp(ptr, aalg, esph->authsize)) {
  568                                 FREE(tc, M_XDATA);
  569                                 DPRINTF(("esp_input_cb(): authentication failed for packet in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
  570                                 espstat.esps_badauth++;
  571                                 error = EACCES;
  572                                 goto baddone;
  573                         }
  574                 }
  575 
  576                 /* Remove trailing authenticator */
  577                 m_adj(m, -(esph->authsize));
  578         }
  579         FREE(tc, M_XDATA);
  580 
  581         /* Replay window checking, if appropriate */
  582         if ((tdb->tdb_wnd > 0) && (!(tdb->tdb_flags & TDBF_NOREPLAY))) {
  583                 m_copydata(m, skip + sizeof(u_int32_t), sizeof(u_int32_t),
  584                     (unsigned char *) &btsx);
  585                 btsx = ntohl(btsx);
  586 
  587                 switch (checkreplaywindow32(btsx, 0, &(tdb->tdb_rpl),
  588                     tdb->tdb_wnd, &(tdb->tdb_bitmap), 1)) {
  589                 case 0: /* All's well */
  590 #if NPFSYNC > 0
  591                         pfsync_update_tdb(tdb,0);
  592 #endif
  593                         break;
  594 
  595                 case 1:
  596                         DPRINTF(("esp_input_cb(): replay counter wrapped for SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
  597                         espstat.esps_wrap++;
  598                         error = EACCES;
  599                         goto baddone;
  600 
  601                 case 2:
  602                 case 3:
  603                         DPRINTF(("esp_input_cb(): duplicate packet received in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
  604                         error = EACCES;
  605                         goto baddone;
  606 
  607                 default:
  608                         DPRINTF(("esp_input_cb(): bogus value from checkreplaywindow32() in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
  609                         espstat.esps_replay++;
  610                         error = EACCES;
  611                         goto baddone;
  612                 }
  613         }
  614 
  615         /* Release the crypto descriptors */
  616         crypto_freereq(crp);
  617 
  618         /* Determine the ESP header length */
  619         if (tdb->tdb_flags & TDBF_NOREPLAY)
  620                 hlen = sizeof(u_int32_t) + tdb->tdb_ivlen; /* "old" ESP */
  621         else
  622                 hlen = 2 * sizeof(u_int32_t) + tdb->tdb_ivlen; /* "new" ESP */
  623 
  624         /* Find beginning of ESP header */
  625         m1 = m_getptr(m, skip, &roff);
  626         if (m1 == NULL) {
  627                 espstat.esps_hdrops++;
  628                 splx(s);
  629                 DPRINTF(("esp_input_cb(): bad mbuf chain, SA %s/%08x\n",
  630                     ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
  631                 m_freem(m);
  632                 return EINVAL;
  633         }
  634 
  635         /* Remove the ESP header and IV from the mbuf. */
  636         if (roff == 0) {
  637                 /* The ESP header was conveniently at the beginning of the mbuf */
  638                 m_adj(m1, hlen);
  639                 if (!(m1->m_flags & M_PKTHDR))
  640                         m->m_pkthdr.len -= hlen;
  641         } else if (roff + hlen >= m1->m_len) {
  642                 /*
  643                  * Part or all of the ESP header is at the end of this mbuf, so
  644                  * first let's remove the remainder of the ESP header from the
  645                  * beginning of the remainder of the mbuf chain, if any.
  646                  */
  647                 if (roff + hlen > m1->m_len) {
  648                         /* Adjust the next mbuf by the remainder */
  649                         m_adj(m1->m_next, roff + hlen - m1->m_len);
  650 
  651                         /* The second mbuf is guaranteed not to have a pkthdr... */
  652                         m->m_pkthdr.len -= (roff + hlen - m1->m_len);
  653                 }
  654 
  655                 /* Now, let's unlink the mbuf chain for a second...*/
  656                 mo = m1->m_next;
  657                 m1->m_next = NULL;
  658 
  659                 /* ...and trim the end of the first part of the chain...sick */
  660                 m_adj(m1, -(m1->m_len - roff));
  661                 if (!(m1->m_flags & M_PKTHDR))
  662                         m->m_pkthdr.len -= (m1->m_len - roff);
  663 
  664                 /* Finally, let's relink */
  665                 m1->m_next = mo;
  666         } else {
  667                 /*
  668                  * The ESP header lies in the "middle" of the mbuf...do an
  669                  * overlapping copy of the remainder of the mbuf over the ESP
  670                  * header.
  671                  */
  672                 bcopy(mtod(m1, u_char *) + roff + hlen,
  673                     mtod(m1, u_char *) + roff, m1->m_len - (roff + hlen));
  674                 m1->m_len -= hlen;
  675                 m->m_pkthdr.len -= hlen;
  676         }
  677 
  678         /* Save the last three bytes of decrypted data */
  679         m_copydata(m, m->m_pkthdr.len - 3, 3, lastthree);
  680 
  681         /* Verify pad length */
  682         if (lastthree[1] + 2 > m->m_pkthdr.len - skip) {
  683                 espstat.esps_badilen++;
  684                 splx(s);
  685                 DPRINTF(("esp_input_cb(): invalid padding length %d for packet in SA %s/%08x\n", lastthree[1], ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
  686                 m_freem(m);
  687                 return EINVAL;
  688         }
  689 
  690         /* Verify correct decryption by checking the last padding bytes */
  691         if (!(tdb->tdb_flags & TDBF_RANDOMPADDING)) {
  692                 if ((lastthree[1] != lastthree[0]) && (lastthree[1] != 0)) {
  693                         espstat.esps_badenc++;
  694                         splx(s);
  695                         DPRINTF(("esp_input(): decryption failed for packet in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
  696                         m_freem(m);
  697                         return EINVAL;
  698                 }
  699         }
  700 
  701         /* Trim the mbuf chain to remove the trailing authenticator and padding */
  702         m_adj(m, -(lastthree[1] + 2));
  703 
  704         /* Restore the Next Protocol field */
  705         m_copyback(m, protoff, sizeof(u_int8_t), lastthree + 2);
  706 
  707         /* Back to generic IPsec input processing */
  708         error = ipsec_common_input_cb(m, tdb, skip, protoff, mtag);
  709         splx(s);
  710         return (error);
  711 
  712  baddone:
  713         splx(s);
  714 
  715         if (m != NULL)
  716                 m_freem(m);
  717 
  718         crypto_freereq(crp);
  719 
  720         return (error);
  721 }
  722 
  723 /*
  724  * ESP output routine, called by ipsp_process_packet().
  725  */
  726 int
  727 esp_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int skip,
  728     int protoff)
  729 {
  730         struct enc_xform *espx = (struct enc_xform *) tdb->tdb_encalgxform;
  731         struct auth_hash *esph = (struct auth_hash *) tdb->tdb_authalgxform;
  732         int ilen, hlen, rlen, padding, blks, alen;
  733         struct mbuf *mi, *mo = (struct mbuf *) NULL;
  734         struct tdb_crypto *tc;
  735         unsigned char *pad;
  736         u_int8_t prot;
  737 
  738         struct cryptodesc *crde = NULL, *crda = NULL;
  739         struct cryptop *crp;
  740 #if NBPFILTER > 0
  741         struct ifnet *ifn = &(encif[0].sc_if);
  742 
  743         ifn->if_opackets++;
  744         ifn->if_obytes += m->m_pkthdr.len;
  745 
  746         if (ifn->if_bpf) {
  747                 struct enchdr hdr;
  748 
  749                 bzero (&hdr, sizeof(hdr));
  750 
  751                 hdr.af = tdb->tdb_dst.sa.sa_family;
  752                 hdr.spi = tdb->tdb_spi;
  753                 if (espx)
  754                         hdr.flags |= M_CONF;
  755                 if (esph)
  756                         hdr.flags |= M_AUTH;
  757 
  758                 bpf_mtap_hdr(ifn->if_bpf, (char *)&hdr, ENC_HDRLEN, m,
  759                     BPF_DIRECTION_OUT);
  760         }
  761 #endif
  762 
  763         if (tdb->tdb_flags & TDBF_NOREPLAY)
  764                 hlen = sizeof(u_int32_t) + tdb->tdb_ivlen;
  765         else
  766                 hlen = 2 * sizeof(u_int32_t) + tdb->tdb_ivlen;
  767 
  768         rlen = m->m_pkthdr.len - skip; /* Raw payload length. */
  769         if (espx)
  770                 blks = espx->blocksize;
  771         else
  772                 blks = 4; /* If no encryption, we have to be 4-byte aligned. */
  773 
  774         padding = ((blks - ((rlen + 2) % blks)) % blks) + 2;
  775 
  776         if (esph)
  777                 alen = AH_HMAC_HASHLEN;
  778         else
  779                 alen = 0;
  780 
  781         espstat.esps_output++;
  782 
  783         switch (tdb->tdb_dst.sa.sa_family) {
  784 #ifdef INET
  785         case AF_INET:
  786                 /* Check for IP maximum packet size violations. */
  787                 if (skip + hlen + rlen + padding + alen > IP_MAXPACKET) {
  788                         DPRINTF(("esp_output(): packet in SA %s/%08x got "
  789                             "too big\n", ipsp_address(tdb->tdb_dst),
  790                             ntohl(tdb->tdb_spi)));
  791                         m_freem(m);
  792                         espstat.esps_toobig++;
  793                         return EMSGSIZE;
  794                 }
  795                 break;
  796 #endif /* INET */
  797 
  798 #ifdef INET6
  799         case AF_INET6:
  800                 /* Check for IPv6 maximum packet size violations. */
  801                 if (skip + hlen + rlen + padding + alen > IPV6_MAXPACKET) {
  802                         DPRINTF(("esp_output(): packet in SA %s/%08x got too "
  803                             "big\n", ipsp_address(tdb->tdb_dst),
  804                             ntohl(tdb->tdb_spi)));
  805                         m_freem(m);
  806                         espstat.esps_toobig++;
  807                         return EMSGSIZE;
  808                 }
  809                 break;
  810 #endif /* INET6 */
  811 
  812         default:
  813                 DPRINTF(("esp_output(): unknown/unsupported protocol "
  814                     "family %d, SA %s/%08x\n", tdb->tdb_dst.sa.sa_family
  815                     , ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
  816                 m_freem(m);
  817                 espstat.esps_nopf++;
  818                 return EPFNOSUPPORT;
  819         }
  820 
  821         /* Update the counters. */
  822         tdb->tdb_cur_bytes += m->m_pkthdr.len - skip;
  823         espstat.esps_obytes += m->m_pkthdr.len - skip;
  824 
  825         /* Hard byte expiration. */
  826         if (tdb->tdb_flags & TDBF_BYTES &&
  827             tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) {
  828                 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);
  829                 tdb_delete(tdb);
  830                 m_freem(m);
  831                 return EINVAL;
  832         }
  833 
  834         /* Soft byte expiration. */
  835         if (tdb->tdb_flags & TDBF_SOFT_BYTES &&
  836             tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) {
  837                 pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);
  838                 tdb->tdb_flags &= ~TDBF_SOFT_BYTES;    /* Turn off checking. */
  839         }
  840 
  841         /*
  842          * Loop through mbuf chain; if we find a readonly mbuf,
  843          * replace the rest of the chain.
  844          */
  845         mo = NULL;
  846         mi = m;
  847         while (mi != NULL && !M_READONLY(mi)) {
  848                 mo = mi;
  849                 mi = mi->m_next;
  850         }
  851 
  852         if (mi != NULL) {
  853                 /* Replace the rest of the mbuf chain. */
  854                 struct mbuf *n = m_copym2(mi, 0, M_COPYALL, M_DONTWAIT);
  855 
  856                 if (n == NULL) {
  857                         DPRINTF(("esp_output(): bad mbuf chain, SA %s/%08x\n",
  858                             ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
  859                         espstat.esps_hdrops++;
  860                         m_freem(m);
  861                         return ENOBUFS;
  862                 }
  863 
  864                 if (mo != NULL)
  865                         mo->m_next = n;
  866                 else
  867                         m = n;
  868 
  869                 m_freem(mi);
  870         }
  871 
  872         /* Inject ESP header. */
  873         mo = m_inject(m, skip, hlen, M_DONTWAIT);
  874         if (mo == NULL) {
  875                 DPRINTF(("esp_output(): failed to inject ESP header for "
  876                     "SA %s/%08x\n", ipsp_address(tdb->tdb_dst),
  877                     ntohl(tdb->tdb_spi)));
  878                 m_freem(m);
  879                 espstat.esps_hdrops++;
  880                 return ENOBUFS;
  881         }
  882 
  883         /* Initialize ESP header. */
  884         bcopy((caddr_t) &tdb->tdb_spi, mtod(mo, caddr_t), sizeof(u_int32_t));
  885         if (!(tdb->tdb_flags & TDBF_NOREPLAY)) {
  886                 u_int32_t replay = htonl(tdb->tdb_rpl++);
  887                 bcopy((caddr_t) &replay, mtod(mo, caddr_t) + sizeof(u_int32_t),
  888                     sizeof(u_int32_t));
  889 #if NPFSYNC > 0
  890                 pfsync_update_tdb(tdb,1);
  891 #endif
  892         }
  893 
  894         /*
  895          * Add padding -- better to do it ourselves than use the crypto engine,
  896          * although if/when we support compression, we'd have to do that.
  897          */
  898         pad = (u_char *) m_pad(m, padding + alen);
  899         if (pad == NULL) {
  900                 DPRINTF(("esp_output(): m_pad() failed for SA %s/%08x\n",
  901                     ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));
  902                 return ENOBUFS;
  903         }
  904 
  905         /* Self-describing or random padding ? */
  906         if (!(tdb->tdb_flags & TDBF_RANDOMPADDING))
  907                 for (ilen = 0; ilen < padding - 2; ilen++)
  908                         pad[ilen] = ilen + 1;
  909         else
  910                 arc4random_bytes((void *) pad, padding - 2);
  911 
  912         /* Fix padding length and Next Protocol in padding itself. */
  913         pad[padding - 2] = padding - 2;
  914         m_copydata(m, protoff, sizeof(u_int8_t), pad + padding - 1);
  915 
  916         /* Fix Next Protocol in IPv4/IPv6 header. */
  917         prot = IPPROTO_ESP;
  918         m_copyback(m, protoff, sizeof(u_int8_t), &prot);
  919 
  920         /* Get crypto descriptors. */
  921         crp = crypto_getreq(esph && espx ? 2 : 1);
  922         if (crp == NULL) {
  923                 m_freem(m);
  924                 DPRINTF(("esp_output(): failed to acquire crypto "
  925                     "descriptors\n"));
  926                 espstat.esps_crypto++;
  927                 return ENOBUFS;
  928         }
  929 
  930         if (espx) {
  931                 crde = crp->crp_desc;
  932                 crda = crde->crd_next;
  933 
  934                 /* Encryption descriptor. */
  935                 crde->crd_skip = skip + hlen;
  936                 crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen);
  937                 crde->crd_flags = CRD_F_ENCRYPT;
  938                 crde->crd_inject = skip + hlen - tdb->tdb_ivlen;
  939 
  940                 if (tdb->tdb_flags & TDBF_HALFIV) {
  941                         /* Copy half-iv in the packet. */
  942                         m_copyback(m, crde->crd_inject, tdb->tdb_ivlen,
  943                             tdb->tdb_iv);
  944 
  945                         /* Cook half-iv. */
  946                         bcopy(tdb->tdb_iv, crde->crd_iv, tdb->tdb_ivlen);
  947                         for (ilen = 0; ilen < tdb->tdb_ivlen; ilen++)
  948                                 crde->crd_iv[tdb->tdb_ivlen + ilen] =
  949                                     ~crde->crd_iv[ilen];
  950 
  951                         crde->crd_flags |=
  952                             CRD_F_IV_PRESENT | CRD_F_IV_EXPLICIT;
  953                 }
  954 
  955                 /* Encryption operation. */
  956                 crde->crd_alg = espx->type;
  957                 crde->crd_key = tdb->tdb_emxkey;
  958                 crde->crd_klen = tdb->tdb_emxkeylen * 8;
  959                 /* XXX Rounds ? */
  960         } else
  961                 crda = crp->crp_desc;
  962 
  963         /* IPsec-specific opaque crypto info. */
  964         MALLOC(tc, struct tdb_crypto *, sizeof(struct tdb_crypto),
  965             M_XDATA, M_NOWAIT);
  966         if (tc == NULL) {
  967                 m_freem(m);
  968                 crypto_freereq(crp);
  969                 DPRINTF(("esp_output(): failed to allocate tdb_crypto\n"));
  970                 espstat.esps_crypto++;
  971                 return ENOBUFS;
  972         }
  973 
  974         bzero(tc, sizeof(struct tdb_crypto));
  975         tc->tc_spi = tdb->tdb_spi;
  976         tc->tc_proto = tdb->tdb_sproto;
  977         bcopy(&tdb->tdb_dst, &tc->tc_dst, sizeof(union sockaddr_union));
  978 
  979         /* Crypto operation descriptor. */
  980         crp->crp_ilen = m->m_pkthdr.len; /* Total input length. */
  981         crp->crp_flags = CRYPTO_F_IMBUF;
  982         crp->crp_buf = (caddr_t) m;
  983         crp->crp_callback = (int (*) (struct cryptop *)) esp_output_cb;
  984         crp->crp_opaque = (caddr_t) tc;
  985         crp->crp_sid = tdb->tdb_cryptoid;
  986 
  987         if (esph) {
  988                 /* Authentication descriptor. */
  989                 crda->crd_skip = skip;
  990                 crda->crd_len = m->m_pkthdr.len - (skip + alen);
  991                 crda->crd_inject = m->m_pkthdr.len - alen;
  992 
  993                 /* Authentication operation. */
  994                 crda->crd_alg = esph->type;
  995                 crda->crd_key = tdb->tdb_amxkey;
  996                 crda->crd_klen = tdb->tdb_amxkeylen * 8;
  997         }
  998 
  999         if ((tdb->tdb_flags & TDBF_SKIPCRYPTO) == 0)
 1000                 return crypto_dispatch(crp);
 1001         else
 1002                 return esp_output_cb(crp);
 1003 }
 1004 
 1005 /*
 1006  * ESP output callback, called directly by the crypto driver.
 1007  */
 1008 int
 1009 esp_output_cb(void *op)
 1010 {
 1011         struct cryptop *crp = (struct cryptop *) op;
 1012         struct tdb_crypto *tc;
 1013         struct tdb *tdb;
 1014         struct mbuf *m;
 1015         int error, s;
 1016 
 1017         tc = (struct tdb_crypto *) crp->crp_opaque;
 1018 
 1019         m = (struct mbuf *) crp->crp_buf;
 1020         if (m == NULL) {
 1021                 /* Shouldn't happen... */
 1022                 FREE(tc, M_XDATA);
 1023                 crypto_freereq(crp);
 1024                 espstat.esps_crypto++;
 1025                 DPRINTF(("esp_output_cb(): bogus returned buffer from "
 1026                     "crypto\n"));
 1027                 return (EINVAL);
 1028         }
 1029 
 1030 
 1031         s = spltdb();
 1032 
 1033         tdb = gettdb(tc->tc_spi, &tc->tc_dst, tc->tc_proto);
 1034         if (tdb == NULL) {
 1035                 FREE(tc, M_XDATA);
 1036                 espstat.esps_notdb++;
 1037                 DPRINTF(("esp_output_cb(): TDB is expired while in crypto\n"));
 1038                 error = EPERM;
 1039                 goto baddone;
 1040         }
 1041 
 1042         /* Check for crypto errors. */
 1043         if (crp->crp_etype) {
 1044                 if (crp->crp_etype == EAGAIN) {
 1045                         /* Reset the session ID */
 1046                         if (tdb->tdb_cryptoid != 0)
 1047                                 tdb->tdb_cryptoid = crp->crp_sid;
 1048                         splx(s);
 1049                         return crypto_dispatch(crp);
 1050                 }
 1051                 FREE(tc, M_XDATA);
 1052                 espstat.esps_noxform++;
 1053                 DPRINTF(("esp_output_cb(): crypto error %d\n",
 1054                     crp->crp_etype));
 1055                 error = crp->crp_etype;
 1056                 goto baddone;
 1057         }
 1058         FREE(tc, M_XDATA);
 1059 
 1060         /* Release crypto descriptors. */
 1061         crypto_freereq(crp);
 1062 
 1063         /*
 1064          * If we're doing half-iv, keep a copy of the last few bytes of the
 1065          * encrypted part, for use as the next IV. Note that HALF-IV is only
 1066          * supposed to be used without authentication (the old ESP specs).
 1067          */
 1068         if (tdb->tdb_flags & TDBF_HALFIV)
 1069                 m_copydata(m, m->m_pkthdr.len - tdb->tdb_ivlen, tdb->tdb_ivlen,
 1070                     tdb->tdb_iv);
 1071 
 1072         /* Call the IPsec input callback. */
 1073         error = ipsp_process_done(m, tdb);
 1074         splx(s);
 1075         return error;
 1076 
 1077  baddone:
 1078         splx(s);
 1079 
 1080         if (m != NULL)
 1081                 m_freem(m);
 1082 
 1083         crypto_freereq(crp);
 1084 
 1085         return error;
 1086 }
 1087 
 1088 /*
 1089  * return 0 on success
 1090  * return 1 for counter == 0
 1091  * return 2 for very old packet
 1092  * return 3 for packet within current window but already received
 1093  */
 1094 int
 1095 checkreplaywindow32(u_int32_t seq, u_int32_t initial, u_int32_t *lastseq,
 1096     u_int32_t window, u_int32_t *bitmap, int commit)
 1097 {
 1098         u_int32_t diff, llseq, lbitmap;
 1099 
 1100         /* Just do the checking, without "committing" any changes. */
 1101         if (commit == 0) {
 1102                 llseq = *lastseq;
 1103                 lbitmap = *bitmap;
 1104 
 1105                 lastseq = &llseq;
 1106                 bitmap = &lbitmap;
 1107         }
 1108 
 1109         seq -= initial;
 1110 
 1111         if (seq == 0)
 1112                 return 1;
 1113 
 1114         if (seq > *lastseq - initial) {
 1115                 diff = seq - (*lastseq - initial);
 1116                 if (diff < window)
 1117                         *bitmap = ((*bitmap) << diff) | 1;
 1118                 else
 1119                         *bitmap = 1;
 1120                 *lastseq = seq + initial;
 1121                 return 0;
 1122         }
 1123 
 1124         diff = *lastseq - initial - seq;
 1125         if (diff >= window) {
 1126                 espstat.esps_wrap++;
 1127                 return 2;
 1128         }
 1129 
 1130         if ((*bitmap) & (((u_int32_t) 1) << diff)) {
 1131                 espstat.esps_replay++;
 1132                 return 3;
 1133         }
 1134 
 1135         *bitmap |= (((u_int32_t) 1) << diff);
 1136         return 0;
 1137 }
 1138 
 1139 /*
 1140  * m_pad(m, n) pads <m> with <n> bytes at the end. The packet header
 1141  * length is updated, and a pointer to the first byte of the padding
 1142  * (which is guaranteed to be all in one mbuf) is returned.
 1143  */
 1144 
 1145 caddr_t
 1146 m_pad(struct mbuf *m, int n)
 1147 {
 1148         struct mbuf *m0, *m1;
 1149         int len, pad;
 1150         caddr_t retval;
 1151 
 1152         if (n <= 0) {  /* No stupid arguments. */
 1153                 DPRINTF(("m_pad(): pad length invalid (%d)\n", n));
 1154                 m_freem(m);
 1155                 return NULL;
 1156         }
 1157 
 1158         len = m->m_pkthdr.len;
 1159         pad = n;
 1160         m0 = m;
 1161 
 1162         while (m0->m_len < len) {
 1163                 len -= m0->m_len;
 1164                 m0 = m0->m_next;
 1165         }
 1166 
 1167         if (m0->m_len != len) {
 1168                 DPRINTF(("m_pad(): length mismatch (should be %d instead of "
 1169                     "%d)\n", m->m_pkthdr.len,
 1170                     m->m_pkthdr.len + m0->m_len - len));
 1171 
 1172                 m_freem(m);
 1173                 return NULL;
 1174         }
 1175 
 1176         /* Check for zero-length trailing mbufs, and find the last one. */
 1177         for (m1 = m0; m1->m_next; m1 = m1->m_next) {
 1178                 if (m1->m_next->m_len != 0) {
 1179                         DPRINTF(("m_pad(): length mismatch (should be %d "
 1180                             "instead of %d)\n", m->m_pkthdr.len,
 1181                             m->m_pkthdr.len + m1->m_next->m_len));
 1182 
 1183                         m_freem(m);
 1184                         return NULL;
 1185                 }
 1186 
 1187                 m0 = m1->m_next;
 1188         }
 1189 
 1190         if ((m0->m_flags & M_EXT) ||
 1191             m0->m_data + m0->m_len + pad >= &(m0->m_dat[MLEN])) {
 1192                 /* Add an mbuf to the chain. */
 1193                 MGET(m1, M_DONTWAIT, MT_DATA);
 1194                 if (m1 == 0) {
 1195                         m_freem(m0);
 1196                         DPRINTF(("m_pad(): cannot append\n"));
 1197                         return NULL;
 1198                 }
 1199 
 1200                 m0->m_next = m1;
 1201                 m0 = m1;
 1202                 m0->m_len = 0;
 1203         }
 1204 
 1205         retval = m0->m_data + m0->m_len;
 1206         m0->m_len += pad;
 1207         m->m_pkthdr.len += pad;
 1208 
 1209         return retval;
 1210 }

/* [<][>][^][v][top][bottom][index][help] */