]> The Tcpdump Group git mirrors - tcpdump/blobdiff - util-print.c
OSPF: Use %zu to print sizeof values
[tcpdump] / util-print.c
index 8806b47599c0c2723cbbbcfaead54ce262074cda..3d3caa5aa79ed0f47fd68f08d40594d051fe342f 100644 (file)
@@ -228,6 +228,28 @@ nd_printzp(netdissect_options *ndo,
        return (n == 0) ? 0 : ret;
 }
 
+/*
+ * Print a null-padded filename (or other ASCII string), part of
+ * the packet buffer, filtering out non-printable characters.
+ * Stop if truncated (via GET_U_1/longjmp) or after n bytes or before
+ * the null char, whichever occurs first.
+ * The suffix comes from: j:longJmp, n:after N bytes, p:null-Padded.
+ */
+void
+nd_printjnp(netdissect_options *ndo, const u_char *s, u_int n)
+{
+       u_char c;
+
+       while (n > 0) {
+               c = GET_U_1(s);
+               if (c == '\0')
+                       break;
+               fn_print_char(ndo, c);
+               n--;
+               s++;
+       }
+}
+
 /*
  * Print the timestamp .FRAC part (Microseconds/nanoseconds)
  */
@@ -473,21 +495,20 @@ void nd_print_invalid(netdissect_options *ndo)
  */
 
 int
-print_unknown_data(netdissect_options *ndo, const u_char *cp,const char *ident,int len)
+print_unknown_data(netdissect_options *ndo, const u_char *cp,
+                   const char *ident, u_int len)
 {
-       if (len < 0) {
-          ND_PRINT("%sDissector error: print_unknown_data called with negative length",
-                   ident);
-               return(0);
-       }
-       if (ndo->ndo_snapend - cp < len)
-               len = ndo->ndo_snapend - cp;
-       if (len < 0) {
-          ND_PRINT("%sDissector error: print_unknown_data called with pointer past end of packet",
+       u_int len_to_print;
+
+       len_to_print = len;
+       if (!ND_TTEST_LEN(cp, 0)) {
+               ND_PRINT("%sDissector error: print_unknown_data called with pointer past end of packet",
                    ident);
                return(0);
        }
-        hex_print(ndo, ident,cp,len);
+       if (ND_BYTES_AVAILABLE_AFTER(cp) < len_to_print)
+               len_to_print = ND_BYTES_AVAILABLE_AFTER(cp);
+       hex_print(ndo, ident, cp, len_to_print);
        return(1); /* everything is ok */
 }
 
@@ -534,6 +555,9 @@ tok2str(const struct tok *lp, const char *fmt,
  * Convert a bit token value to a string; use "fmt" if not found.
  * this is useful for parsing bitfields, the output strings are separated
  * if the s field is positive.
+ *
+ * A token matches iff it has one or more bits set and every bit that is set
+ * in the token is set in v. Consequently, a 0 token never matches.
  */
 static char *
 bittok2str_internal(const struct tok *lp, const char *fmt,
@@ -542,41 +566,29 @@ bittok2str_internal(const struct tok *lp, const char *fmt,
         static char buf[1024+1]; /* our string buffer */
         char *bufp = buf;
         size_t space_left = sizeof(buf), string_size;
-        u_int rotbit; /* this is the bit we rotate through all bitpositions */
-        u_int tokval;
         const char * sepstr = "";
 
-       while (lp != NULL && lp->s != NULL) {
-            tokval=lp->v;   /* load our first value */
-            rotbit=1;
-            while (rotbit != 0) {
-                /*
-                 * lets AND the rotating bit with our token value
-                 * and see if we have got a match
-                 */
-               if (tokval == (v&rotbit)) {
-                    /* ok we have found something */
-                    if (space_left <= 1)
-                        return (buf); /* only enough room left for NUL, if that */
-                    string_size = strlcpy(bufp, sepstr, space_left);
-                    if (string_size >= space_left)
-                        return (buf);    /* we ran out of room */
-                    bufp += string_size;
-                    space_left -= string_size;
-                    if (space_left <= 1)
-                        return (buf); /* only enough room left for NUL, if that */
-                    string_size = strlcpy(bufp, lp->s, space_left);
-                    if (string_size >= space_left)
-                        return (buf);    /* we ran out of room */
-                    bufp += string_size;
-                    space_left -= string_size;
-                    sepstr = sep;
-                    break;
-                }
-                rotbit=rotbit<<1; /* no match - lets shift and try again */
+        while (lp != NULL && lp->s != NULL) {
+            if (lp->v && (v & lp->v) == lp->v) {
+                /* ok we have found something */
+                if (space_left <= 1)
+                    return (buf); /* only enough room left for NUL, if that */
+                string_size = strlcpy(bufp, sepstr, space_left);
+                if (string_size >= space_left)
+                    return (buf);    /* we ran out of room */
+                bufp += string_size;
+                space_left -= string_size;
+                if (space_left <= 1)
+                    return (buf); /* only enough room left for NUL, if that */
+                string_size = strlcpy(bufp, lp->s, space_left);
+                if (string_size >= space_left)
+                    return (buf);    /* we ran out of room */
+                bufp += string_size;
+                space_left -= string_size;
+                sepstr = sep;
             }
             lp++;
-       }
+        }
 
         if (bufp == buf)
             /* bummer - lets print the "unknown" message as advised in the fmt string if we got one */
@@ -626,6 +638,20 @@ tok2strary_internal(const char **lp, int n, const char *fmt,
        return (buf);
 }
 
+const struct tok *
+uint2tokary_internal(const struct uint_tokary dict[], const size_t size,
+                     const u_int val)
+{
+       size_t i;
+       /* Try a direct lookup before the full scan. */
+       if (val < size && dict[val].uintval == val)
+               return dict[val].tokary; /* OK if NULL */
+       for (i = 0; i < size; i++)
+               if (dict[i].uintval == val)
+                       return dict[i].tokary; /* OK if NULL */
+       return NULL;
+}
+
 /*
  * Convert a 32-bit netmask to prefixlen if possible
  * the function returns the prefix-len; if plen == -1
@@ -779,7 +805,6 @@ print_txt_line(netdissect_options *ndo, const char *prefix,
 
        startidx = idx;
        while (idx < len) {
-               ND_TCHECK_1(pptr + idx);
                c = GET_U_1(pptr + idx);
                if (c == '\n') {
                        /*
@@ -796,7 +821,6 @@ print_txt_line(netdissect_options *ndo, const char *prefix,
                                /* not in this packet */
                                return (0);
                        }
-                       ND_TCHECK_1(pptr + idx + 1);
                        if (GET_U_1(pptr + idx + 1) == '\n') {
                                /*
                                 * CR-LF; end of line.
@@ -829,7 +853,6 @@ print_txt_line(netdissect_options *ndo, const char *prefix,
         * All printable ASCII, but no line ending after that point
         * in the buffer; treat this as if it were truncated.
         */
-trunc:
        linelen = idx - startidx;
        ND_PRINT("%s%.*s", prefix, (int)linelen, pptr + startidx);
        nd_print_trunc(ndo);