skip = (int) crp->crp_opaque2; protoff = (int) crp->crp_opaque3;
skip = (long) crp->crp_opaque2; protoff = (long) crp->crp_opaque3;
esp_input_cb(void *op){    u_int8_t lastthree[3], aalg[AH_HMAC_HASHLEN];    int hlen, roff, skip, protoff, error;    struct mbuf *m1, *mo, *m;    struct cryptodesc *crd;    struct auth_hash *esph;    struct enc_xform *espx;    struct cryptop *crp;    struct tdb *tdb;    crp = (struct cryptop *) op;    crd = crp->crp_desc;    tdb = (struct tdb *) crp->crp_opaque1;    esph = (struct auth_hash *) tdb->tdb_authalgxform;    espx = (struct enc_xform *) tdb->tdb_encalgxform;    skip = (int) crp->crp_opaque2;    protoff = (int) crp->crp_opaque3;    m = (struct mbuf *) crp->crp_buf;    tdb->tdb_ref--;    /* Check for crypto errors */    if (crp->crp_etype)    {	/* Reset the session ID */	if (tdb->tdb_cryptoid != 0)	  tdb->tdb_cryptoid = crp->crp_sid;	if (crp->crp_etype == EAGAIN)	{	    tdb->tdb_ref++;	    return crypto_dispatch(crp);	}	espstat.esps_noxform++;	DPRINTF(("esp_input_cb(): crypto error %d\n", crp->crp_etype));	error = crp->crp_etype;	goto baddone;    }    /* Shouldn't happen... */    if (!m)    {	espstat.esps_crypto++;	DPRINTF(("esp_input_cb(): bogus returned buffer from crypto\n"));	error = EINVAL;	goto baddone;    }    /*     * Check that the TDB is still valid -- not really an error, but     * we need to handle it as such. It may happen if the TDB expired     * or was deleted while there was a pending request in the crypto     * queue.     */    if (tdb->tdb_flags & TDBF_INVALID)    {	espstat.esps_invalid++;	tdb_delete(tdb, 0, 0);	error = ENXIO;	DPRINTF(("esp_input_cb(): TDB expired while processing crypto\n"));	goto baddone;    }    /* If authentication was performed, check now */    if (esph)    {	/* Copy the authenticator from the packet */	m_copydata(m, m->m_pkthdr.len - esph->authsize,		   esph->authsize, aalg);	/* Verify authenticator */	if (bcmp(crp->crp_opaque4, aalg, esph->authsize))	{	    DPRINTF(("esp_input_cb(): authentication failed for packet in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));	    espstat.esps_badauth++;	    error = EACCES;	    goto baddone;	}	/* Remove trailing authenticator */	m_adj(m, -(esph->authsize));	/* We have to manually free this */	FREE(crp->crp_opaque4, M_XDATA);    }    /* Release the crypto descriptors */    crypto_freereq(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 */    /* Find beginning of ESP header */    m1 = m_getptr(m, skip, &roff);    if (m1 == NULL)    {	DPRINTF(("esp_input_cb(): bad mbuf chain, SA %s/%08x\n",		 ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));	espstat.esps_hdrops++;	m_freem(m);	return EINVAL;    }    /* Remove the ESP header and IV from the mbuf. */    if (roff == 0)     {	/* The ESP header was conveniently at the beginning of the mbuf */	m_adj(m1, hlen);	if (!(m1->m_flags & M_PKTHDR))	  m->m_pkthdr.len -= hlen;    }    else      if (roff + hlen >= m1->m_len)      {	  /*	   * Part or all of the ESP header is at the end of this mbuf, so	   * first let's remove the remainder of the ESP header from the	   * beginning of the remainder of the mbuf chain, if any.	   */	  if (roff + hlen > m1->m_len)	  {	      /* Adjust the next mbuf by the remainder */	      m_adj(m1->m_next, roff + hlen - m1->m_len);	      /* The second mbuf is guaranteed not to have a pkthdr... */	      m->m_pkthdr.len -= (roff + hlen - m1->m_len);	  }	  /* Now, let's unlink the mbuf chain for a second...*/	  mo = m1->m_next;	  m1->m_next = NULL;	  /* ...and trim the end of the first part of the chain...sick */	  m_adj(m1, -(m1->m_len - roff));	  if (!(m1->m_flags & M_PKTHDR))	    m->m_pkthdr.len -= (m1->m_len - roff);	  /* Finally, let's relink */	  m1->m_next = mo;      }      else      {	  /* 	   * The ESP header lies in the "middle" of the mbuf...do an	   * overlapping copy of the remainder of the mbuf over the ESP	   * header.	   */	  bcopy(mtod(m1, u_char *) + roff + hlen, mtod(m1, u_char *) + roff,		m1->m_len - (roff + hlen));	  m1->m_len -= hlen;	  m->m_pkthdr.len -= hlen;      }    /* Save the last three bytes of decrypted data */    m_copydata(m, m->m_pkthdr.len - 3, 3, lastthree);    /* Verify pad length */    if (lastthree[1] + 2 > m->m_pkthdr.len - skip - hlen)    {	DPRINTF(("esp_input_cb(): invalid padding length %d for packet in SA %s/%08x\n", lastthree[2], ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));	espstat.esps_badilen++;	m_freem(m);	return EINVAL;    }    /* Verify correct decryption by checking the last padding bytes */    if (!(tdb->tdb_flags & TDBF_RANDOMPADDING))    {	if ((lastthree[1] != lastthree[0]) && (lastthree[1] != 0))	{	    DPRINTF(("esp_input(): decryption failed for packet in SA %s/%08x\n", ipsp_address(tdb->tdb_dst), ntohl(tdb->tdb_spi)));	    espstat.esps_badenc++;	    m_freem(m);	    return EINVAL;	}    }    /* Trim the mbuf chain to remove the trailing authenticator and padding */    m_adj(m, -(lastthree[1] + 2));    /* Restore the Next Protocol field */    m_copyback(m, protoff, sizeof(u_int8_t), lastthree + 2);    /* Back to generic IPsec input processing */    return ipsec_common_input_cb(m, tdb, skip, protoff); baddone:    if (m)      m_freem(m);    /* We have to manually free this */    if (crp && crp->crp_opaque4)      FREE(crp->crp_opaque4, M_XDATA);    crypto_freereq(crp);    return error;}