* Compress/encrypt a packet and put the result in a new mbuf at *resultp. * The original mbuf is not free'd. */
| 379 | * The original mbuf is not free'd. |
| 380 | */ |
| 381 | static int |
| 382 | ng_pred1_compress(node_p node, struct mbuf *m, struct mbuf **resultp) |
| 383 | { |
| 384 | const priv_p priv = NG_NODE_PRIVATE(node); |
| 385 | int outlen, inlen; |
| 386 | u_char *out; |
| 387 | uint16_t fcs, lenn; |
| 388 | int len; |
| 389 | |
| 390 | /* Initialize. */ |
| 391 | *resultp = NULL; |
| 392 | |
| 393 | inlen = m->m_pkthdr.len; |
| 394 | |
| 395 | priv->stats.FramesPlain++; |
| 396 | priv->stats.InOctets += inlen; |
| 397 | |
| 398 | /* Reserve space for expansion. */ |
| 399 | if (inlen > (PRED1_BUF_SIZE*8/9 + 1 + 4)) { |
| 400 | priv->stats.Errors++; |
| 401 | NG_FREE_M(m); |
| 402 | return (ENOMEM); |
| 403 | } |
| 404 | |
| 405 | /* We must own the mbuf chain exclusively to modify it. */ |
| 406 | m = m_unshare(m, M_NOWAIT); |
| 407 | if (m == NULL) { |
| 408 | priv->stats.Errors++; |
| 409 | return (ENOMEM); |
| 410 | } |
| 411 | |
| 412 | /* Work with contiguous regions of memory. */ |
| 413 | m_copydata(m, 0, inlen, (caddr_t)(priv->inbuf + 2)); |
| 414 | |
| 415 | lenn = htons(inlen & 0x7FFF); |
| 416 | |
| 417 | /* Compute FCS. */ |
| 418 | fcs = Crc16(PPP_INITFCS, (u_char *)&lenn, 2); |
| 419 | fcs = Crc16(fcs, priv->inbuf + 2, inlen); |
| 420 | fcs = ~fcs; |
| 421 | |
| 422 | /* Compress data. */ |
| 423 | len = Pred1Compress(node, priv->inbuf + 2, priv->outbuf + 2, inlen); |
| 424 | |
| 425 | /* What happened? */ |
| 426 | if (len < inlen) { |
| 427 | out = priv->outbuf; |
| 428 | outlen = 2 + len; |
| 429 | *(uint16_t *)out = lenn; |
| 430 | *out |= 0x80; |
| 431 | priv->stats.FramesComp++; |
| 432 | } else { |
| 433 | out = priv->inbuf; |
| 434 | outlen = 2 + inlen; |
| 435 | *(uint16_t *)out = lenn; |
| 436 | priv->stats.FramesUncomp++; |
| 437 | } |
| 438 |
no test coverage detected