]> The Tcpdump Group git mirrors - tcpdump/blobdiff - util-print.c
CI: Add warning exemptions for Sun C (suncc-5.14) on Solaris 10
[tcpdump] / util-print.c
index 5d9056a1ebe7cd369de5fb9bfe4346275b8ec876..594327012e8626e7b3cb04f77fdd3120be468308 100644 (file)
  * FOR A PARTICULAR PURPOSE.
  */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
-#endif
 
 #include "netdissect-stdinc.h"
 
 #include <sys/stat.h>
 
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#include <ctype.h>
 #include <stdio.h>
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
 
+#include "netdissect-ctype.h"
+
 #include "netdissect.h"
 #include "extract.h"
 #include "ascii_strcasecmp.h"
@@ -72,7 +68,7 @@ fn_print_char(netdissect_options *ndo, u_char c)
                c = ND_TOASCII(c);
                ND_PRINT("M-");
        }
-       if (!ND_ISPRINT(c)) {
+       if (!ND_ASCII_ISPRINT(c)) {
                c ^= 0x40;      /* DEL to ?, others to alpha */
                ND_PRINT("^");
        }
@@ -93,33 +89,6 @@ fn_print_str(netdissect_options *ndo, const u_char *s)
        }
 }
 
-/*
- * Print out a null-terminated filename (or other ASCII string), part of
- * the packet buffer.
- * If ep is NULL, assume no truncation check is needed.
- * Return true if truncated.
- * Stop at ep (if given) or before the null char, whichever is first.
- */
-int
-nd_print(netdissect_options *ndo,
-         const u_char *s, const u_char *ep)
-{
-       int ret;
-       u_char c;
-
-       ret = 1;                        /* assume truncated */
-       while (ep == NULL || s < ep) {
-               c = EXTRACT_U_1(s);
-               s++;
-               if (c == '\0') {
-                       ret = 0;
-                       break;
-               }
-               fn_print_char(ndo, c);
-       }
-       return(ret);
-}
-
 /*
  * Print out a null-terminated filename (or other ASCII string) from
  * a fixed-length field in the packet buffer, or from what remains of
@@ -162,7 +131,7 @@ nd_printztn(netdissect_options *ndo,
                        break;
                }
 
-               c = EXTRACT_U_1(s);
+               c = GET_U_1(s);
                s++;
                bytes++;
                n--;
@@ -190,7 +159,7 @@ nd_printn(netdissect_options *ndo,
 
        while (n > 0 && (ep == NULL || s < ep)) {
                n--;
-               c = EXTRACT_U_1(s);
+               c = GET_U_1(s);
                s++;
                fn_print_char(ndo, c);
        }
@@ -198,50 +167,63 @@ nd_printn(netdissect_options *ndo,
 }
 
 /*
- * Print out a null-padded filename (or other ASCII string), part of
- * the packet buffer.
- * If ep is NULL, assume no truncation check is needed.
- * Return true if truncated.
- * Stop at ep (if given) or after n bytes or before the null char,
+ * Print a counted 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,
  * whichever is first.
+ * The suffix comes from: j:longJmp, n:after N bytes.
  */
-int
-nd_printzp(netdissect_options *ndo,
-           const u_char *s, u_int n,
-           const u_char *ep)
+void
+nd_printjn(netdissect_options *ndo, const u_char *s, u_int n)
 {
-       int ret;
-       u_char c;
-
-       ret = 1;                        /* assume truncated */
-       while (n > 0 && (ep == NULL || s < ep)) {
+       while (n != 0) {
+               fn_print_char(ndo, GET_U_1(s));
                n--;
-               c = EXTRACT_U_1(s);
                s++;
-               if (c == '\0') {
-                       ret = 0;
+       }
+}
+
+/*
+ * 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++;
        }
-       return (n == 0) ? 0 : ret;
 }
 
 /*
  * Print the timestamp .FRAC part (Microseconds/nanoseconds)
  */
 static void
-ts_frac_print(netdissect_options *ndo, int usec)
+ts_frac_print(netdissect_options *ndo, const struct timeval *tv)
 {
 #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
        switch (ndo->ndo_tstamp_precision) {
 
        case PCAP_TSTAMP_PRECISION_MICRO:
-               ND_PRINT(".%06u", (unsigned)usec);
+               ND_PRINT(".%06u", (unsigned)tv->tv_usec);
+               if ((unsigned)tv->tv_usec > ND_MICRO_PER_SEC - 1)
+                       ND_PRINT(" " ND_INVALID_MICRO_SEC_STR);
                break;
 
        case PCAP_TSTAMP_PRECISION_NANO:
-               ND_PRINT(".%09u", (unsigned)usec);
+               ND_PRINT(".%09u", (unsigned)tv->tv_usec);
+               if ((unsigned)tv->tv_usec > ND_NANO_PER_SEC - 1)
+                       ND_PRINT(" " ND_INVALID_NANO_SEC_STR);
                break;
 
        default:
@@ -249,7 +231,9 @@ ts_frac_print(netdissect_options *ndo, int usec)
                break;
        }
 #else
-       ND_PRINT(".%06u", (unsigned)usec);
+       ND_PRINT(".%06u", (unsigned)tv->tv_usec);
+       if ((unsigned)tv->tv_usec > ND_MICRO_PER_SEC - 1)
+               ND_PRINT(" " ND_INVALID_MICRO_SEC_STR);
 #endif
 }
 
@@ -259,49 +243,64 @@ ts_frac_print(netdissect_options *ndo, int usec)
  *   if date_flag == WITH_DATE print YY:MM:DD before HH:MM:SS.FRAC
  */
 static void
-ts_date_hmsfrac_print(netdissect_options *ndo, int sec, int usec,
+ts_date_hmsfrac_print(netdissect_options *ndo, const struct timeval *tv,
                      enum date_flag date_flag, enum time_flag time_flag)
 {
-       time_t Time = sec;
        struct tm *tm;
-       char timestr[32];
+       char timebuf[32];
+       const char *timestr;
+#ifdef _WIN32
+       time_t sec;
+#endif
 
-       if ((unsigned)sec & 0x80000000) {
-               ND_PRINT("[Error converting time]");
+       if (tv->tv_sec < 0) {
+               ND_PRINT("[timestamp overflow]");
                return;
        }
 
+#ifdef _WIN32
+       /* on Windows tv->tv_sec is a long not a 64-bit time_t. */
+       sec = tv->tv_sec;
+#endif
+
        if (time_flag == LOCAL_TIME)
-               tm = localtime(&Time);
+#ifdef _WIN32
+               tm = localtime(&sec);
+#else
+               tm = localtime(&tv->tv_sec);
+#endif
        else
-               tm = gmtime(&Time);
+#ifdef _WIN32
+               tm = gmtime(&sec);
+#else
+               tm = gmtime(&tv->tv_sec);
+#endif
 
-       if (!tm) {
-               ND_PRINT("[Error converting time]");
-               return;
+       if (date_flag == WITH_DATE) {
+               timestr = nd_format_time(timebuf, sizeof(timebuf),
+                   "%Y-%m-%d %H:%M:%S", tm);
+       } else {
+               timestr = nd_format_time(timebuf, sizeof(timebuf),
+                   "%H:%M:%S", tm);
        }
-       if (date_flag == WITH_DATE)
-               strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", tm);
-       else
-               strftime(timestr, sizeof(timestr), "%H:%M:%S", tm);
        ND_PRINT("%s", timestr);
 
-       ts_frac_print(ndo, usec);
+       ts_frac_print(ndo, tv);
 }
 
 /*
  * Print the timestamp - Unix timeval style, as SECS.FRAC.
  */
 static void
-ts_unix_print(netdissect_options *ndo, int sec, int usec)
+ts_unix_print(netdissect_options *ndo, const struct timeval *tv)
 {
-       if ((unsigned)sec & 0x80000000) {
-               ND_PRINT("[Error converting time]");
+       if (tv->tv_sec < 0) {
+               ND_PRINT("[timestamp overflow]");
                return;
        }
 
-       ND_PRINT("%u", (unsigned)sec);
-       ts_frac_print(ndo, usec);
+       ND_PRINT("%" PRId64, (int64_t)tv->tv_sec);
+       ts_frac_print(ndo, tv);
 }
 
 /*
@@ -319,8 +318,7 @@ ts_print(netdissect_options *ndo,
        switch (ndo->ndo_tflag) {
 
        case 0: /* Default */
-               ts_date_hmsfrac_print(ndo, tvp->tv_sec, tvp->tv_usec,
-                                     WITHOUT_DATE, LOCAL_TIME);
+               ts_date_hmsfrac_print(ndo, tvp, WITHOUT_DATE, LOCAL_TIME);
                ND_PRINT(" ");
                break;
 
@@ -328,7 +326,7 @@ ts_print(netdissect_options *ndo,
                break;
 
        case 2: /* Unix timeval style */
-               ts_unix_print(ndo, tvp->tv_sec, tvp->tv_usec);
+               ts_unix_print(ndo, tvp);
                ND_PRINT(" ");
                break;
 
@@ -359,8 +357,7 @@ ts_print(netdissect_options *ndo,
                        netdissect_timevalsub(tvp, &tv_ref, &tv_result, nano_prec);
 
                ND_PRINT((negative_offset ? "-" : " "));
-               ts_date_hmsfrac_print(ndo, tv_result.tv_sec, tv_result.tv_usec,
-                                     WITHOUT_DATE, UTC_TIME);
+               ts_date_hmsfrac_print(ndo, &tv_result, WITHOUT_DATE, UTC_TIME);
                ND_PRINT(" ");
 
                 if (ndo->ndo_tflag == 3)
@@ -368,8 +365,7 @@ ts_print(netdissect_options *ndo,
                break;
 
        case 4: /* Date + Default */
-               ts_date_hmsfrac_print(ndo, tvp->tv_sec, tvp->tv_usec,
-                                     WITH_DATE, LOCAL_TIME);
+               ts_date_hmsfrac_print(ndo, tvp, WITH_DATE, LOCAL_TIME);
                ND_PRINT(" ");
                break;
        }
@@ -393,7 +389,7 @@ unsigned_relts_print(netdissect_options *ndo,
                ND_PRINT("0s");
                return;
        }
-       while (secs > 0) {
+       while (secs != 0) {
                if (secs >= *s) {
                        ND_PRINT("%u%s", secs / *s, *l);
                        secs -= (secs / *s) * *s;
@@ -439,6 +435,26 @@ signed_relts_print(netdissect_options *ndo,
        unsigned_relts_print(ndo, secs);
 }
 
+/*
+ * Format a struct tm with strftime().
+ * If the pointer to the struct tm is null, that means that the
+ * routine to convert a time_t to a struct tm failed; the localtime()
+ * and gmtime() in the Microsoft Visual Studio C library will fail,
+ * returning null, if the value is before the UNIX Epoch.
+ */
+const char *
+nd_format_time(char *buf, size_t bufsize, const char *format,
+         const struct tm *timeptr)
+{
+       if (timeptr != NULL) {
+               if (strftime(buf, bufsize, format, timeptr) != 0)
+                       return (buf);
+               else
+                       return ("[nd_format_time() buffer is too small]");
+       } else
+               return ("[localtime() or gmtime() couldn't convert the date and time]");
+}
+
 /* Print the truncated string */
 void nd_print_trunc(netdissect_options *ndo)
 {
@@ -451,12 +467,37 @@ void nd_print_protocol(netdissect_options *ndo)
        ND_PRINT("%s", ndo->ndo_protocol);
 }
 
+/* Print the protocol name in caps (uppercases) */
+void nd_print_protocol_caps(netdissect_options *ndo)
+{
+       const char *p;
+        for (p = ndo->ndo_protocol; *p != '\0'; p++)
+                ND_PRINT("%c", ND_ASCII_TOUPPER(*p));
+}
+
 /* Print the invalid string */
 void nd_print_invalid(netdissect_options *ndo)
 {
        ND_PRINT(" (invalid)");
 }
 
+/*
+ * Print a sequence of bytes, separated by a single space.
+ * Stop if truncated (via GET_U_1/longjmp) or after n bytes,
+ * whichever is first.
+ */
+void
+nd_print_bytes_hex(netdissect_options *ndo, const u_char *cp, u_int n)
+{
+       while (n > 0) {
+               ND_PRINT("%02x", GET_U_1(cp));
+               n--;
+               cp++;
+               if (n > 0)
+                       ND_PRINT(" ");
+       }
+}
+
 /*
  *  this is a generic routine for printing unknown data;
  *  we pass on the linefeed plus indentation string to
@@ -464,30 +505,24 @@ 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 *indent, 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",
-                   ident);
+       if (!ND_TTEST_LEN(cp, 0)) {
+               ND_PRINT("%sDissector error: %s() called with pointer past end of packet",
+                   indent, __func__);
                return(0);
        }
-        hex_print(ndo, ident,cp,len);
+       hex_print(ndo, indent, cp, ND_MIN(len, ND_BYTES_AVAILABLE_AFTER(cp)));
        return(1); /* everything is ok */
 }
 
 /*
  * Convert a token value to a string; use "fmt" if not found.
  */
-const char *
+static const char *
 tok2strbuf(const struct tok *lp, const char *fmt,
-          u_int v, char *buf, size_t bufsize)
+          const u_int v, char *buf, const size_t bufsize)
 {
        if (lp != NULL) {
                while (lp->s != NULL) {
@@ -499,7 +534,7 @@ tok2strbuf(const struct tok *lp, const char *fmt,
        if (fmt == NULL)
                fmt = "#%d";
 
-       (void)nd_snprintf(buf, bufsize, fmt, v);
+       (void)snprintf(buf, bufsize, fmt, v);
        return (const char *)buf;
 }
 
@@ -509,8 +544,7 @@ tok2strbuf(const struct tok *lp, const char *fmt,
  * in round-robin fashion.
  */
 const char *
-tok2str(const struct tok *lp, const char *fmt,
-       u_int v)
+tok2str(const struct tok *lp, const char *fmt, const u_int v)
 {
        static char buf[4][TOKBUFSIZE];
        static int idx = 0;
@@ -525,53 +559,44 @@ 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,
-          u_int v, const char *sep)
+                   const u_int v, const char *sep)
 {
         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 */
-            (void)nd_snprintf(buf, sizeof(buf), fmt == NULL ? "#%08x" : fmt, v);
+            (void)snprintf(buf, sizeof(buf), fmt == NULL ? "#%08x" : fmt, v);
         return (buf);
 }
 
@@ -580,8 +605,7 @@ bittok2str_internal(const struct tok *lp, const char *fmt,
  * this is useful for parsing bitfields, the output strings are not separated.
  */
 char *
-bittok2str_nosep(const struct tok *lp, const char *fmt,
-          u_int v)
+bittok2str_nosep(const struct tok *lp, const char *fmt, const u_int v)
 {
     return (bittok2str_internal(lp, fmt, v, ""));
 }
@@ -591,8 +615,7 @@ bittok2str_nosep(const struct tok *lp, const char *fmt,
  * this is useful for parsing bitfields, the output strings are comma separated.
  */
 char *
-bittok2str(const struct tok *lp, const char *fmt,
-          u_int v)
+bittok2str(const struct tok *lp, const char *fmt, const u_int v)
 {
     return (bittok2str_internal(lp, fmt, v, ", "));
 }
@@ -604,8 +627,7 @@ bittok2str(const struct tok *lp, const char *fmt,
  * correct for bounds-checking.
  */
 const char *
-tok2strary_internal(const char **lp, int n, const char *fmt,
-       int v)
+tok2strary_internal(const char **lp, int n, const char *fmt, const int v)
 {
        static char buf[TOKBUFSIZE];
 
@@ -613,10 +635,24 @@ tok2strary_internal(const char **lp, int n, const char *fmt,
                return lp[v];
        if (fmt == NULL)
                fmt = "#%d";
-       (void)nd_snprintf(buf, sizeof(buf), fmt, v);
+       (void)snprintf(buf, sizeof(buf), fmt, v);
        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
@@ -624,9 +660,9 @@ tok2strary_internal(const char **lp, int n, const char *fmt,
  */
 
 int
-mask2plen(uint32_t mask)
+mask2plen(const uint32_t mask)
 {
-       uint32_t bitmasks[33] = {
+       const uint32_t bitmasks[33] = {
                0x00000000,
                0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,
                0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
@@ -690,26 +726,28 @@ mask62plen(const u_char *mask)
  * either a space character at the beginning of the line (this
  * includes a blank line) or no more tokens remaining on the line.
  */
-static int
+static u_int
 fetch_token(netdissect_options *ndo, const u_char *pptr, u_int idx, u_int len,
-    u_char *tbuf, size_t tbuflen)
+           u_char *tbuf, size_t tbuflen)
 {
        size_t toklen = 0;
+       u_char c;
 
        for (; idx < len; idx++) {
                if (!ND_TTEST_1(pptr + idx)) {
                        /* ran past end of captured data */
                        return (0);
                }
-               if (!isascii(EXTRACT_U_1(pptr + idx))) {
+               c = GET_U_1(pptr + idx);
+               if (!ND_ISASCII(c)) {
                        /* not an ASCII character */
                        return (0);
                }
-               if (isspace(EXTRACT_U_1(pptr + idx))) {
+               if (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
                        /* end of token */
                        break;
                }
-               if (!isprint(EXTRACT_U_1(pptr + idx))) {
+               if (!ND_ASCII_ISPRINT(c)) {
                        /* not part of a command token or response code */
                        return (0);
                }
@@ -717,7 +755,7 @@ fetch_token(netdissect_options *ndo, const u_char *pptr, u_int idx, u_int len,
                        /* no room for this character and terminating '\0' */
                        return (0);
                }
-               tbuf[toklen] = EXTRACT_U_1(pptr + idx);
+               tbuf[toklen] = c;
                toklen++;
        }
        if (toklen == 0) {
@@ -735,15 +773,16 @@ fetch_token(netdissect_options *ndo, const u_char *pptr, u_int idx, u_int len,
                        /* ran past end of captured data */
                        break;
                }
-               if (EXTRACT_U_1(pptr + idx) == '\r' || EXTRACT_U_1(pptr + idx) == '\n') {
+               c = GET_U_1(pptr + idx);
+               if (c == '\r' || c == '\n') {
                        /* end of line */
                        break;
                }
-               if (!isascii(EXTRACT_U_1(pptr + idx)) || !isprint(EXTRACT_U_1(pptr + idx))) {
+               if (!ND_ASCII_ISPRINT(c)) {
                        /* not a printable ASCII character */
                        break;
                }
-               if (!isspace(EXTRACT_U_1(pptr + idx))) {
+               if (c != ' ' && c != '\t' && c != '\r' && c != '\n') {
                        /* beginning of next token */
                        break;
                }
@@ -763,11 +802,12 @@ print_txt_line(netdissect_options *ndo, const char *prefix,
 {
        u_int startidx;
        u_int linelen;
+       u_char c;
 
        startidx = idx;
        while (idx < len) {
-               ND_TCHECK_1(pptr + idx);
-               if (EXTRACT_U_1(pptr + idx) == '\n') {
+               c = GET_U_1(pptr + idx);
+               if (c == '\n') {
                        /*
                         * LF without CR; end of line.
                         * Skip the LF and print the line, with the
@@ -776,14 +816,13 @@ print_txt_line(netdissect_options *ndo, const char *prefix,
                        linelen = idx - startidx;
                        idx++;
                        goto print;
-               } else if (EXTRACT_U_1(pptr + idx) == '\r') {
+               } else if (c == '\r') {
                        /* CR - any LF? */
                        if ((idx+1) >= len) {
                                /* not in this packet */
                                return (0);
                        }
-                       ND_TCHECK_1(pptr + idx + 1);
-                       if (EXTRACT_U_1(pptr + idx + 1) == '\n') {
+                       if (GET_U_1(pptr + idx + 1) == '\n') {
                                /*
                                 * CR-LF; end of line.
                                 * Skip the CR-LF and print the line, with
@@ -800,9 +839,7 @@ print_txt_line(netdissect_options *ndo, const char *prefix,
                         * it.
                         */
                        return (0);
-               } else if (!isascii(EXTRACT_U_1(pptr + idx)) ||
-                          (!isprint(EXTRACT_U_1(pptr + idx)) &&
-                           EXTRACT_U_1(pptr + idx) != '\t')) {
+               } else if (!ND_ASCII_ISPRINT(c) && c != '\t') {
                        /*
                         * Not a printable ASCII character and not a tab;
                         * treat this as if it were binary data, and
@@ -815,12 +852,10 @@ 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.
+        * in the buffer.
         */
-trunc:
        linelen = idx - startidx;
        ND_PRINT("%s%.*s", prefix, (int)linelen, pptr + startidx);
-       nd_print_trunc(ndo);
        return (0);
 
 print:
@@ -837,7 +872,6 @@ txtproto_print(netdissect_options *ndo, const u_char *pptr, u_int len,
        u_char token[MAX_TOKEN+1];
        const char *cmd;
        int print_this = 0;
-       const char *pnp;
 
        if (cmds != NULL) {
                /*
@@ -877,8 +911,8 @@ txtproto_print(netdissect_options *ndo, const u_char *pptr, u_int len,
                                    sizeof(token));
                        }
                        if (idx != 0) {
-                               if (isdigit(token[0]) && isdigit(token[1]) &&
-                                   isdigit(token[2]) && token[3] == '\0') {
+                               if (ND_ASCII_ISDIGIT(token[0]) && ND_ASCII_ISDIGIT(token[1]) &&
+                                   ND_ASCII_ISDIGIT(token[2]) && token[3] == '\0') {
                                        /* Yes. */
                                        print_this = 1;
                                }
@@ -902,9 +936,7 @@ txtproto_print(netdissect_options *ndo, const u_char *pptr, u_int len,
                print_this = 1;
        }
 
-       /* Capitalize the protocol name */
-       for (pnp = ndo->ndo_protocol; *pnp != '\0'; pnp++)
-               ND_PRINT("%c", ND_TOUPPER((u_char)*pnp));
+       nd_print_protocol_caps(ndo);
 
        if (print_this) {
                /*
@@ -942,7 +974,7 @@ txtproto_print(netdissect_options *ndo, const u_char *pptr, u_int len,
     (defined(__s390__) || defined(__s390x__) || defined(__zarch__)) || \
     defined(__vax__)
 /*
- * The procesor natively handles unaligned loads, so just use memcpy()
+ * The processor natively handles unaligned loads, so just use memcpy()
  * and memcmp(), to enable those optimizations.
  *
  * XXX - are those all the x86 tests we need?