+ const nflog_hdr_t *hdr = (const nflog_hdr_t *)p;
+ const nflog_tlv_t *tlv;
+ uint16_t size;
+ uint16_t h_size = sizeof(nflog_hdr_t);
+ u_int caplen = h->caplen;
+ u_int length = h->len;
+
+ if (caplen < (int) sizeof(nflog_hdr_t) || length < (int) sizeof(nflog_hdr_t)) {
+ ND_PRINT((ndo, "[|nflog]"));
+ return h_size;
+ }
+
+ if (!(hdr->nflog_version) == 0) {
+ ND_PRINT((ndo, "version %u (unknown)", hdr->nflog_version));
+ return h_size;
+ }
+
+ if (ndo->ndo_eflag)
+ nflog_hdr_print(ndo, hdr, length);
+
+ p += sizeof(nflog_hdr_t);
+ length -= sizeof(nflog_hdr_t);
+ caplen -= sizeof(nflog_hdr_t);
+
+ while (length > 0) {
+ /* We have some data. Do we have enough for the TLV header? */
+ if (caplen < sizeof(nflog_tlv_t) || length < sizeof(nflog_tlv_t)) {
+ /* No. */
+ ND_PRINT((ndo, "[|nflog]"));
+ return h_size;
+ }
+
+ tlv = (const nflog_tlv_t *) p;
+ size = tlv->tlv_length;
+ if (size % 4 != 0)
+ size += 4 - size % 4;
+
+ /* Is the TLV's length less than the minimum? */
+ if (size < sizeof(nflog_tlv_t)) {
+ /* Yes. Give up now. */
+ ND_PRINT((ndo, "[|nflog]"));
+ return h_size;
+ }
+
+ /* Do we have enough data for the full TLV? */
+ if (caplen < size || length < size) {
+ /* No. */
+ ND_PRINT((ndo, "[|nflog]"));
+ return h_size;
+ }
+
+ if (tlv->tlv_type == NFULA_PAYLOAD) {
+ /*
+ * This TLV's data is the packet payload.
+ * Skip past the TLV header, and break out
+ * of the loop so we print the packet data.
+ */
+ p += sizeof(nflog_tlv_t);
+ h_size += sizeof(nflog_tlv_t);
+ length -= sizeof(nflog_tlv_t);
+ caplen -= sizeof(nflog_tlv_t);
+ break;
+ }
+
+ p += size;
+ h_size += size;
+ length -= size;
+ caplen -= size;