crp->crp_opaque2 = (caddr_t) skip; crp->crp_opaque3 = (caddr_t) protoff;
(long) crp->crp_opaque2 = skip; (long) crp->crp_opaque3 = protoff;
esp_input(struct mbuf *m, struct tdb *tdb, int skip, int protoff){    struct auth_hash *esph = (struct auth_hash *) tdb->tdb_authalgxform;    struct enc_xform *espx = (struct enc_xform *) tdb->tdb_encalgxform;    int plen, alen, hlen;    u_int32_t btsx;    struct cryptodesc *crde = NULL, *crda = NULL;    struct cryptop *crp;    /* Determine the ESP header length */    if (tdb->tdb_flags & TDBF_NOREPLAY)      hlen = sizeof(u_int32_t) + tdb->tdb_ivlen; /* "old" ESP */    else      hlen = 2 * sizeof(u_int32_t) + tdb->tdb_ivlen; /* "new" ESP */    if (esph)      alen = AH_HMAC_HASHLEN;    else      alen = 0;    if (espx)    {	/*	 * Verify payload length is multiple of encryption algorithm	 * block size.	 */	plen = m->m_pkthdr.len - (skip + hlen + alen);	if ((plen & (espx->blocksize - 1)) || (plen <= 0))	{	    DPRINTF(("esp_input(): payload not a multiple of %d octets, SA %s/%08x\n", espx->blocksize, ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));	    espstat.esps_badilen++;	    m_freem(m);	    return EINVAL;	}    }    /* Replay window checking, if appropriate */    if ((tdb->tdb_wnd > 0) && (!(tdb->tdb_flags & TDBF_NOREPLAY)))    {	m_copydata(m, skip + sizeof(u_int32_t), sizeof(u_int32_t),		   (unsigned char *) &btsx);	btsx = ntohl(btsx);	switch (checkreplaywindow32(btsx, 0, &(tdb->tdb_rpl), tdb->tdb_wnd,				    &(tdb->tdb_bitmap)))	{	    case 0: /* All's well */		break;	    case 1:		DPRINTF(("esp_input(): replay counter wrapped for SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));		espstat.esps_wrap++;		m_freem(m);		return EACCES;	    case 2:	    case 3:		DPRINTF(("esp_input(): duplicate packet received in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));		espstat.esps_replay++;		m_freem(m);		return EACCES;	    default:		DPRINTF(("esp_input(): bogus value from checkreplaywindow32() in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));		espstat.esps_replay++;		m_freem(m);		return EACCES;	}    }    /* Update the counters */    tdb->tdb_cur_bytes += m->m_pkthdr.len - skip - hlen - alen;    espstat.esps_ibytes += m->m_pkthdr.len - skip - hlen - alen;    /* Hard expiration */    if ((tdb->tdb_flags & TDBF_BYTES) &&	(tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes))    {	pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_HARD);	tdb_delete(tdb, 0, TDBEXP_TIMEOUT);	m_freem(m);	return ENXIO;    }    /* Notify on soft expiration */    if ((tdb->tdb_flags & TDBF_SOFT_BYTES) &&	(tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes))    {	pfkeyv2_expire(tdb, SADB_EXT_LIFETIME_SOFT);	tdb->tdb_flags &= ~TDBF_SOFT_BYTES;       /* Turn off checking */    }    /* Get crypto descriptors */    crp = crypto_getreq(esph && espx ? 2 : 1);    if (crp == NULL)    {	m_freem(m);	DPRINTF(("esp_input(): failed to acquire crypto descriptors\n"));	espstat.esps_crypto++;	return ENOBUFS;    }    if (esph)    {	crda = crp->crp_desc;	crde = crda->crd_next;	/* Authentication descriptor */	crda->crd_skip = skip;	crda->crd_len = m->m_pkthdr.len - (skip + alen);	crda->crd_inject = m->m_pkthdr.len - alen;	crda->crd_alg = esph->type;	crda->crd_key = tdb->tdb_amxkey;	crda->crd_klen = tdb->tdb_amxkeylen * 8;    }    else      crde = crp->crp_desc;    tdb->tdb_ref++;    /* Crypto operation descriptor */    crp->crp_ilen = m->m_pkthdr.len; /* Total input length */    crp->crp_flags = CRYPTO_F_IMBUF;    crp->crp_buf = (caddr_t) m;    crp->crp_callback = (int (*) (struct cryptop *)) esp_input_cb;    crp->crp_sid = tdb->tdb_cryptoid;    /* These are passed as-is to the callback */    crp->crp_opaque1 = (caddr_t) tdb;    crp->crp_opaque2 = (caddr_t) skip;    crp->crp_opaque3 = (caddr_t) protoff;    /* Decryption descriptor */    if (espx)    {	crde->crd_skip = skip + hlen;	crde->crd_len = m->m_pkthdr.len - (skip + hlen + alen);	crde->crd_inject = skip + hlen - tdb->tdb_ivlen;        if (tdb->tdb_flags & TDBF_HALFIV)	  crde->crd_flags |= CRD_F_HALFIV;	crde->crd_alg = espx->type;	crde->crd_key = tdb->tdb_emxkey;	crde->crd_klen = tdb->tdb_emxkeylen * 8;	/* XXX Rounds ? */    }    MALLOC(crp->crp_opaque4, caddr_t, alen, M_XDATA, M_DONTWAIT);    if (crp->crp_opaque4 == 0)    {	m_freem(m);	crypto_freereq(crp);	DPRINTF(("esp_input(): failed to allocate auth array\n"));	espstat.esps_crypto++;	return ENOBUFS;    }    /* Copy the authenticator */    m_copydata(m, m->m_pkthdr.len - alen, alen, crp->crp_opaque4);    return crypto_dispatch(crp);}