]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Clean up the TLV processing loop.
authorGuy Harris <[email protected]>
Mon, 3 Feb 2014 10:14:24 +0000 (02:14 -0800)
committerGuy Harris <[email protected]>
Mon, 3 Feb 2014 10:14:24 +0000 (02:14 -0800)
We want to process TLVs until we run out of data, so make the main loop
condition "length > 0".  Break out of the loop if we see an
NFULA_PAYLOAD TLV.

Add in a bunch of length checks, and make those and existing length
checks report "[|nflog]".

print-nflog.c

index f53b48e6f09fe1d273d387d29393e885d143eacb..94dee188e655b2a7a05fbec5e3930d804e8dfce1 100644 (file)
@@ -90,34 +90,55 @@ nflog_if_print(struct netdissect_options *ndo,
        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);
-       p += sizeof(nflog_hdr_t);
 
-       do {
+       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;
 
-               h_size = h_size + size;
-
-               /* wrong size of the packet */
-               if (size > length || size == 0)
+               /* 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;
+               }
 
-               p += size;
-               length = length - size;
-               caplen = caplen - size;
+               /* Do we have enough data for the full TLV? */
+               if (caplen < size || length < size) {
+                       /* No. */
+                       ND_PRINT((ndo, "[|nflog]"));
+                       return h_size;
+               }
 
-       } while (tlv->tlv_type != NFULA_PAYLOAD);
+               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;
+               }
 
-       /* dont skip payload just tlv length and type */
-       p = p - size + 4;
-       length += size - 4;
-       caplen += size - 4;
-       h_size -= length;
+               p += size;
+               h_size += size;
+               length -= size;
+               caplen -= size;
+       }
 
        switch (hdr->nflog_family) {