* Decompress/decrypt packet and put the result in a new mbuf at *resultp. * The original mbuf is not free'd. */
| 523 | * The original mbuf is not free'd. |
| 524 | */ |
| 525 | static int |
| 526 | ng_deflate_decompress(node_p node, struct mbuf *m, struct mbuf **resultp) |
| 527 | { |
| 528 | const priv_p priv = NG_NODE_PRIVATE(node); |
| 529 | int outlen, inlen, datalen; |
| 530 | int rtn; |
| 531 | uint16_t proto; |
| 532 | int offset; |
| 533 | uint16_t rseqnum; |
| 534 | u_char headbuf[5]; |
| 535 | static u_char EMPTY_BLOCK[4] = { 0x00, 0x00, 0xff, 0xff }; |
| 536 | |
| 537 | /* Initialize. */ |
| 538 | *resultp = NULL; |
| 539 | |
| 540 | inlen = m->m_pkthdr.len; |
| 541 | |
| 542 | if (inlen > DEFLATE_BUF_SIZE) { |
| 543 | priv->stats.Errors++; |
| 544 | NG_FREE_M(m); |
| 545 | priv->seqnum = 0; |
| 546 | return (ENOMEM); |
| 547 | } |
| 548 | |
| 549 | /* We must own the mbuf chain exclusively to modify it. */ |
| 550 | m = m_unshare(m, M_NOWAIT); |
| 551 | if (m == NULL) { |
| 552 | priv->stats.Errors++; |
| 553 | return (ENOMEM); |
| 554 | } |
| 555 | |
| 556 | /* Work with contiguous regions of memory. */ |
| 557 | m_copydata(m, 0, inlen, (caddr_t)priv->inbuf); |
| 558 | |
| 559 | /* Separate proto. */ |
| 560 | if ((priv->inbuf[0] & 0x01) != 0) { |
| 561 | proto = priv->inbuf[0]; |
| 562 | offset = 1; |
| 563 | } else { |
| 564 | proto = be16dec(priv->inbuf); |
| 565 | offset = 2; |
| 566 | } |
| 567 | |
| 568 | priv->stats.InOctets += inlen; |
| 569 | |
| 570 | /* Packet is compressed, so decompress. */ |
| 571 | if (proto == PROT_COMPD) { |
| 572 | priv->stats.FramesComp++; |
| 573 | |
| 574 | /* Check sequence number. */ |
| 575 | rseqnum = be16dec(priv->inbuf + offset); |
| 576 | offset += 2; |
| 577 | if (rseqnum != priv->seqnum) { |
| 578 | priv->stats.Errors++; |
| 579 | log(LOG_NOTICE, "ng_deflate: wrong sequence: %u " |
| 580 | "instead of %u\n", rseqnum, priv->seqnum); |
| 581 | NG_FREE_M(m); |
| 582 | priv->seqnum = 0; |
no test coverage detected