* ipcomp_input() gets called to uncompress an input packet */
| 193 | * ipcomp_input() gets called to uncompress an input packet |
| 194 | */ |
| 195 | static int |
| 196 | ipcomp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff) |
| 197 | { |
| 198 | struct xform_data *xd; |
| 199 | struct cryptop *crp; |
| 200 | struct ipcomp *ipcomp; |
| 201 | crypto_session_t cryptoid; |
| 202 | caddr_t addr; |
| 203 | int error, hlen = IPCOMP_HLENGTH; |
| 204 | |
| 205 | /* |
| 206 | * Check that the next header of the IPComp is not IPComp again, before |
| 207 | * doing any real work. Given it is not possible to do double |
| 208 | * compression it means someone is playing tricks on us. |
| 209 | */ |
| 210 | error = ENOBUFS; |
| 211 | if (m->m_len < skip + hlen && (m = m_pullup(m, skip + hlen)) == NULL) { |
| 212 | IPCOMPSTAT_INC(ipcomps_hdrops); /*XXX*/ |
| 213 | DPRINTF(("%s: m_pullup failed\n", __func__)); |
| 214 | key_freesav(&sav); |
| 215 | return (error); |
| 216 | } |
| 217 | addr = (caddr_t) mtod(m, struct ip *) + skip; |
| 218 | ipcomp = (struct ipcomp *)addr; |
| 219 | if (ipcomp->comp_nxt == IPPROTO_IPCOMP) { |
| 220 | IPCOMPSTAT_INC(ipcomps_pdrops); /* XXX have our own stats? */ |
| 221 | DPRINTF(("%s: recursive compression detected\n", __func__)); |
| 222 | error = EINVAL; |
| 223 | goto bad; |
| 224 | } |
| 225 | |
| 226 | SECASVAR_LOCK(sav); |
| 227 | cryptoid = sav->tdb_cryptoid; |
| 228 | SECASVAR_UNLOCK(sav); |
| 229 | |
| 230 | /* Get crypto descriptors */ |
| 231 | crp = crypto_getreq(cryptoid, M_NOWAIT); |
| 232 | if (crp == NULL) { |
| 233 | DPRINTF(("%s: no crypto descriptors\n", __func__)); |
| 234 | IPCOMPSTAT_INC(ipcomps_crypto); |
| 235 | goto bad; |
| 236 | } |
| 237 | /* Get IPsec-specific opaque pointer */ |
| 238 | xd = malloc(sizeof(*xd), M_XDATA, M_NOWAIT | M_ZERO); |
| 239 | if (xd == NULL) { |
| 240 | DPRINTF(("%s: cannot allocate xform_data\n", __func__)); |
| 241 | IPCOMPSTAT_INC(ipcomps_crypto); |
| 242 | crypto_freereq(crp); |
| 243 | goto bad; |
| 244 | } |
| 245 | |
| 246 | /* Decompression operation */ |
| 247 | crp->crp_op = CRYPTO_OP_DECOMPRESS; |
| 248 | crp->crp_payload_start = skip + hlen; |
| 249 | crp->crp_payload_length = m->m_pkthdr.len - (skip + hlen); |
| 250 | |
| 251 | /* Crypto operation descriptor */ |
| 252 | crp->crp_flags = CRYPTO_F_CBIFSYNC; |
nothing calls this directly
no test coverage detected