print-nflog.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. * Copyright (c) 2013, Petar Alilovic,
  3. * Faculty of Electrical Engineering and Computing, University of Zagreb
  4. * All rights reserved
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. *
  9. * * Redistributions of source code must retain the above copyright notice,
  10. * this list of conditions and the following disclaimer.
  11. * * Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
  16. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
  19. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  20. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  21. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  22. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  23. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  24. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  25. * DAMAGE.
  26. */
  27. /* \summary: DLT_NFLOG printer */
  28. #ifdef HAVE_CONFIG_H
  29. #include "config.h"
  30. #endif
  31. #include <netdissect-stdinc.h>
  32. #include "netdissect.h"
  33. #if defined(DLT_NFLOG) && defined(HAVE_PCAP_NFLOG_H)
  34. #include <pcap/nflog.h>
  35. static const struct tok nflog_values[] = {
  36. { AF_INET, "IPv4" },
  37. #ifdef AF_INET6
  38. { AF_INET6, "IPv6" },
  39. #endif /*AF_INET6*/
  40. { 0, NULL }
  41. };
  42. static inline void
  43. nflog_hdr_print(netdissect_options *ndo, const nflog_hdr_t *hdr, u_int length)
  44. {
  45. ND_PRINT((ndo, "version %d, resource ID %d", hdr->nflog_version, ntohs(hdr->nflog_rid)));
  46. if (!ndo->ndo_qflag) {
  47. ND_PRINT((ndo,", family %s (%d)",
  48. tok2str(nflog_values, "Unknown",
  49. hdr->nflog_family),
  50. hdr->nflog_family));
  51. } else {
  52. ND_PRINT((ndo,", %s",
  53. tok2str(nflog_values,
  54. "Unknown NFLOG (0x%02x)",
  55. hdr->nflog_family)));
  56. }
  57. ND_PRINT((ndo, ", length %u: ", length));
  58. }
  59. u_int
  60. nflog_if_print(netdissect_options *ndo,
  61. const struct pcap_pkthdr *h, const u_char *p)
  62. {
  63. const nflog_hdr_t *hdr = (const nflog_hdr_t *)p;
  64. const nflog_tlv_t *tlv;
  65. uint16_t size;
  66. uint16_t h_size = sizeof(nflog_hdr_t);
  67. u_int caplen = h->caplen;
  68. u_int length = h->len;
  69. if (caplen < (int) sizeof(nflog_hdr_t) || length < (int) sizeof(nflog_hdr_t)) {
  70. ND_PRINT((ndo, "[|nflog]"));
  71. return h_size;
  72. }
  73. if (hdr->nflog_version != 0) {
  74. ND_PRINT((ndo, "version %u (unknown)", hdr->nflog_version));
  75. return h_size;
  76. }
  77. if (ndo->ndo_eflag)
  78. nflog_hdr_print(ndo, hdr, length);
  79. p += sizeof(nflog_hdr_t);
  80. length -= sizeof(nflog_hdr_t);
  81. caplen -= sizeof(nflog_hdr_t);
  82. while (length > 0) {
  83. /* We have some data. Do we have enough for the TLV header? */
  84. if (caplen < sizeof(nflog_tlv_t) || length < sizeof(nflog_tlv_t)) {
  85. /* No. */
  86. ND_PRINT((ndo, "[|nflog]"));
  87. return h_size;
  88. }
  89. tlv = (const nflog_tlv_t *) p;
  90. size = tlv->tlv_length;
  91. if (size % 4 != 0)
  92. size += 4 - size % 4;
  93. /* Is the TLV's length less than the minimum? */
  94. if (size < sizeof(nflog_tlv_t)) {
  95. /* Yes. Give up now. */
  96. ND_PRINT((ndo, "[|nflog]"));
  97. return h_size;
  98. }
  99. /* Do we have enough data for the full TLV? */
  100. if (caplen < size || length < size) {
  101. /* No. */
  102. ND_PRINT((ndo, "[|nflog]"));
  103. return h_size;
  104. }
  105. if (tlv->tlv_type == NFULA_PAYLOAD) {
  106. /*
  107. * This TLV's data is the packet payload.
  108. * Skip past the TLV header, and break out
  109. * of the loop so we print the packet data.
  110. */
  111. p += sizeof(nflog_tlv_t);
  112. h_size += sizeof(nflog_tlv_t);
  113. length -= sizeof(nflog_tlv_t);
  114. caplen -= sizeof(nflog_tlv_t);
  115. break;
  116. }
  117. p += size;
  118. h_size += size;
  119. length -= size;
  120. caplen -= size;
  121. }
  122. switch (hdr->nflog_family) {
  123. case AF_INET:
  124. ip_print(ndo, p, length);
  125. break;
  126. #ifdef AF_INET6
  127. case AF_INET6:
  128. ip6_print(ndo, p, length);
  129. break;
  130. #endif /* AF_INET6 */
  131. default:
  132. if (!ndo->ndo_eflag)
  133. nflog_hdr_print(ndo, hdr,
  134. length + sizeof(nflog_hdr_t));
  135. if (!ndo->ndo_suppress_default_print)
  136. ND_DEFAULTPRINT(p, caplen);
  137. break;
  138. }
  139. return h_size;
  140. }
  141. #endif /* defined(DLT_NFLOG) && defined(HAVE_PCAP_NFLOG_H) */