]> The Tcpdump Group git mirrors - tcpdump/blobdiff - util-print.c
Revert partially the commit 21b1273
[tcpdump] / util-print.c
index 06844898d9caa28a4e592689fe91ce2fcdfd89b9..e22e535e8d2b2d62c9ead781614180d9f0301567 100644 (file)
 #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"
 #include "timeval-operations.h"
 
-/* invalid string to print '(invalid)' for malformed or corrupted packets */
-const char istr[] = " (invalid)";
-
 #define TOKBUFSIZE 128
 
-
 enum date_flag { WITHOUT_DATE = 0, WITH_DATE = 1 };
 enum time_flag { UTC_TIME = 0, LOCAL_TIME = 1 };
 
@@ -76,7 +73,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("^");
        }
@@ -113,7 +110,7 @@ nd_print(netdissect_options *ndo,
 
        ret = 1;                        /* assume truncated */
        while (ep == NULL || s < ep) {
-               c = EXTRACT_U_1(s);
+               c = GET_U_1(s);
                s++;
                if (c == '\0') {
                        ret = 0;
@@ -166,7 +163,7 @@ nd_printztn(netdissect_options *ndo,
                        break;
                }
 
-               c = EXTRACT_U_1(s);
+               c = GET_U_1(s);
                s++;
                bytes++;
                n--;
@@ -194,7 +191,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);
        }
@@ -220,7 +217,7 @@ nd_printzp(netdissect_options *ndo,
        ret = 1;                        /* assume truncated */
        while (n > 0 && (ep == NULL || s < ep)) {
                n--;
-               c = EXTRACT_U_1(s);
+               c = GET_U_1(s);
                s++;
                if (c == '\0') {
                        ret = 0;
@@ -231,19 +228,50 @@ nd_printzp(netdissect_options *ndo,
        return (n == 0) ? 0 : ret;
 }
 
+/*
+ * Print the timestamp .FRAC part (Microseconds/nanoseconds)
+ */
+static void
+ts_frac_print(netdissect_options *ndo, long usec)
+{
+#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
+       switch (ndo->ndo_tstamp_precision) {
+
+       case PCAP_TSTAMP_PRECISION_MICRO:
+               ND_PRINT(".%06u", (unsigned)usec);
+               break;
+
+       case PCAP_TSTAMP_PRECISION_NANO:
+               ND_PRINT(".%09u", (unsigned)usec);
+               break;
+
+       default:
+               ND_PRINT(".{unknown}");
+               break;
+       }
+#else
+       ND_PRINT(".%06u", (unsigned)usec);
+#endif
+}
+
 /*
  * Print the timestamp as [YY:MM:DD] HH:MM:SS.FRAC.
  *   if time_flag == LOCAL_TIME print local time else UTC/GMT time
  *   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, long sec, long usec,
                      enum date_flag date_flag, enum time_flag time_flag)
 {
        time_t Time = sec;
        struct tm *tm;
        char timestr[32];
 
+       if ((unsigned)sec & 0x80000000) {
+               ND_PRINT("[Error converting time]");
+               return;
+       }
+
        if (time_flag == LOCAL_TIME)
                tm = localtime(&Time);
        else
@@ -259,50 +287,22 @@ ts_date_hmsfrac_print(netdissect_options *ndo, int sec, int usec,
                strftime(timestr, sizeof(timestr), "%H:%M:%S", tm);
        ND_PRINT("%s", timestr);
 
-#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
-       switch (ndo->ndo_tstamp_precision) {
-
-       case PCAP_TSTAMP_PRECISION_MICRO:
-               ND_PRINT(".%06u", usec);
-               break;
-
-       case PCAP_TSTAMP_PRECISION_NANO:
-               ND_PRINT(".%09u", usec);
-               break;
-
-       default:
-               ND_PRINT(".{unknown}");
-               break;
-       }
-#else
-       ND_PRINT(".%06u", usec);
-#endif
+       ts_frac_print(ndo, usec);
 }
 
 /*
  * 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, long sec, long usec)
 {
-#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
-       switch (ndo->ndo_tstamp_precision) {
-
-       case PCAP_TSTAMP_PRECISION_MICRO:
-               ND_PRINT("%u.%06u", (unsigned)sec, (unsigned)usec);
-               break;
-
-       case PCAP_TSTAMP_PRECISION_NANO:
-               ND_PRINT("%u.%09u", (unsigned)sec, (unsigned)usec);
-               break;
-
-       default:
-               ND_PRINT("%u.{unknown}", (unsigned)sec);
-               break;
+       if ((unsigned)sec & 0x80000000) {
+               ND_PRINT("[Error converting time]");
+               return;
        }
-#else
-       ND_PRINT("%u.%06u", (unsigned)sec, (unsigned)usec);
-#endif
+
+       ND_PRINT("%u", (unsigned)sec);
+       ts_frac_print(ndo, usec);
 }
 
 /*
@@ -446,6 +446,26 @@ void nd_print_trunc(netdissect_options *ndo)
        ND_PRINT(" [|%s]", ndo->ndo_protocol);
 }
 
+/* Print the protocol name */
+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)");
+}
+
 /*
  *  this is a generic routine for printing unknown data;
  *  we pass on the linefeed plus indentation string to
@@ -453,21 +473,20 @@ void nd_print_trunc(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 */
 }
 
@@ -488,7 +507,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;
 }
 
@@ -560,7 +579,7 @@ bittok2str_internal(const struct tok *lp, const char *fmt,
 
         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);
 }
 
@@ -602,7 +621,7 @@ 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);
 }
 
@@ -684,21 +703,23 @@ fetch_token(netdissect_options *ndo, const u_char *pptr, u_int idx, u_int len,
     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);
                }
@@ -706,7 +727,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) {
@@ -724,15 +745,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;
                }
@@ -747,16 +769,17 @@ fetch_token(netdissect_options *ndo, const u_char *pptr, u_int idx, u_int len,
  * the line ending.
  */
 static u_int
-print_txt_line(netdissect_options *ndo, const char *protoname,
-    const char *prefix, const u_char *pptr, u_int idx, u_int len)
+print_txt_line(netdissect_options *ndo, const char *prefix,
+              const u_char *pptr, u_int idx, u_int len)
 {
        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
@@ -765,14 +788,13 @@ print_txt_line(netdissect_options *ndo, const char *protoname,
                        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
@@ -789,9 +811,7 @@ print_txt_line(netdissect_options *ndo, const char *protoname,
                         * 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
@@ -806,10 +826,9 @@ print_txt_line(netdissect_options *ndo, const char *protoname,
         * 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[!%s]", prefix, (int)linelen, pptr + startidx,
-           protoname);
+       ND_PRINT("%s%.*s", prefix, (int)linelen, pptr + startidx);
+       nd_print_trunc(ndo);
        return (0);
 
 print:
@@ -817,15 +836,15 @@ print:
        return (idx);
 }
 
+/* Assign needed before calling txtproto_print(): ndo->ndo_protocol = "proto" */
 void
 txtproto_print(netdissect_options *ndo, const u_char *pptr, u_int len,
-    const char *protoname, const char **cmds, u_int flags)
+              const char **cmds, u_int flags)
 {
        u_int idx, eol;
        u_char token[MAX_TOKEN+1];
        const char *cmd;
        int print_this = 0;
-       const char *pnp;
 
        if (cmds != NULL) {
                /*
@@ -865,8 +884,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;
                                }
@@ -890,9 +909,7 @@ txtproto_print(netdissect_options *ndo, const u_char *pptr, u_int len,
                print_this = 1;
        }
 
-       /* Capitalize the protocol name */
-       for (pnp = protoname; *pnp != '\0'; pnp++)
-               ND_PRINT("%c", toupper((u_char)*pnp));
+       nd_print_protocol_caps(ndo);
 
        if (print_this) {
                /*
@@ -911,14 +928,14 @@ txtproto_print(netdissect_options *ndo, const u_char *pptr, u_int len,
                         */
                        ND_PRINT(", length: %u", len);
                        for (idx = 0;
-                           idx < len && (eol = print_txt_line(ndo, protoname, "\n\t", pptr, idx, len)) != 0;
+                           idx < len && (eol = print_txt_line(ndo, "\n\t", pptr, idx, len)) != 0;
                            idx = eol)
                                ;
                } else {
                        /*
                         * Just print the first text line.
                         */
-                       print_txt_line(ndo, protoname, ": ", pptr, 0, len);
+                       print_txt_line(ndo, ": ", pptr, 0, len);
                }
        }
 }