]> The Tcpdump Group git mirrors - tcpdump/blobdiff - util.c
add a maxlen boundary check to safeputs, print unprintable chars as hex in safeputchar
[tcpdump] / util.c
diff --git a/util.c b/util.c
index 8137538ee2b875ef271b0771bbc54203de24354d..cb4f2aaa768ce16a5fd07261f14c6d0ee4b1e9cd 100644 (file)
--- a/util.c
+++ b/util.c
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/util.c,v 1.89 2003-11-16 09:36:44 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/util.c,v 1.106 2006-02-08 01:38:16 hannes Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -44,8 +44,10 @@ static const char rcsid[] _U_ =
 
 #include "interface.h"
 
+char * ts_format(register int, register int);
+
 /*
- * Print out a filename (or other ascii string).
+ * Print out a null-terminated filename (or other ascii string).
  * If ep is NULL, assume no truncation check is needed.
  * Return true if truncated.
  */
@@ -104,6 +106,53 @@ fn_printn(register const u_char *s, register u_int n,
        return (n == 0) ? 0 : 1;
 }
 
+/*
+ * Print out a null-padded filename (or other ascii string).
+ * If ep is NULL, assume no truncation check is needed.
+ * Return true if truncated.
+ */
+int
+fn_printzp(register const u_char *s, register u_int n,
+         register const u_char *ep)
+{
+       register int ret;
+       register u_char c;
+
+       ret = 1;                        /* assume truncated */
+       while (n > 0 && (ep == NULL || s < ep)) {
+               n--;
+               c = *s++;
+               if (c == '\0') {
+                       ret = 0;
+                       break;
+               }
+               if (!isascii(c)) {
+                       c = toascii(c);
+                       putchar('M');
+                       putchar('-');
+               }
+               if (!isprint(c)) {
+                       c ^= 0x40;      /* DEL to ?, others to alpha */
+                       putchar('^');
+               }
+               putchar(c);
+       }
+       return (n == 0) ? 0 : ret;
+}
+
+/*
+ * Format the timestamp
+ */
+char *
+ts_format(register int sec, register int usec)
+{
+        static char buf[sizeof("00:00:00.000000")];
+        (void)snprintf(buf, sizeof(buf), "%02d:%02d:%02d.%06u",
+               sec / 3600, (sec % 3600) / 60, sec % 60, usec);
+
+        return buf;
+}
+
 /*
  * Print the timestamp
  */
@@ -115,48 +164,59 @@ ts_print(register const struct timeval *tvp)
        time_t Time;
        static unsigned b_sec;
        static unsigned b_usec;
+       int d_usec;
+       int d_sec;
+
+       switch (tflag) {
 
-       switch(tflag) {
-       case 1: /* Default */
+       case 0: /* Default */
                s = (tvp->tv_sec + thiszone) % 86400;
-               (void)printf("%02d:%02d:%02d.%06u ",
-                            s / 3600, (s % 3600) / 60, s % 60,
-                            (unsigned)tvp->tv_usec);
+                (void)printf("%s ", ts_format(s, tvp->tv_usec));
+               break;
+
+       case 1: /* No time stamp */
                break;
-       case -1: /* Unix timeval style */
+
+       case 2: /* Unix timeval style */
                (void)printf("%u.%06u ",
                             (unsigned)tvp->tv_sec,
                             (unsigned)tvp->tv_usec);
                break;
-       case -2:
+
+       case 3: /* Microseconds since previous packet */
+        case 5: /* Microseconds since first packet */
                if (b_sec == 0) {
-                       printf("000000 ");
-               } else {
-                       int d_usec = tvp->tv_usec - b_usec;
-                       int d_sec = tvp->tv_sec - b_sec;
-
-                       while (d_usec < 0) {
-                               d_usec += 1000000;
-                               d_sec--;
-                       }
-                       if (d_sec)
-                               printf("%d. ", d_sec);
-                       printf("%06d ", d_usec);
-               }
-               b_sec = tvp->tv_sec;
-               b_usec = tvp->tv_usec;
+                        /* init timestamp for first packet */
+                        b_usec = tvp->tv_usec;
+                        b_sec = tvp->tv_sec;                        
+                }
+
+                d_usec = tvp->tv_usec - b_usec;
+                d_sec = tvp->tv_sec - b_sec;
+                
+                while (d_usec < 0) {
+                    d_usec += 1000000;
+                    d_sec--;
+                }
+
+                (void)printf("%s ", ts_format(d_sec, d_usec));
+
+                if (tflag == 3) { /* set timestamp for last packet */
+                    b_sec = tvp->tv_sec;
+                    b_usec = tvp->tv_usec;
+                }
                break;
-       case -3: /* Default + Date*/
+
+       case 4: /* Default + Date*/
                s = (tvp->tv_sec + thiszone) % 86400;
                Time = (tvp->tv_sec + thiszone) - s;
                tm = gmtime (&Time);
                if (!tm)
                        printf("Date fail  ");
                else
-                       printf("%04d-%02d-%02d ",
-                                  tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
-               printf("%02d:%02d:%02d.%06u ",
-                          s / 3600, (s % 3600) / 60, s % 60, (unsigned)tvp->tv_usec);
+                       printf("%04d-%02d-%02d %s ",
+                               tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
+                               ts_format(s, tvp->tv_usec));
                break;
        }
 }
@@ -199,27 +259,21 @@ relts_print(int secs)
  */
 
 int
-print_unknown_data(const u_char *cp,const char *lf,int len)
+print_unknown_data(const u_char *cp,const char *ident,int len)
 {
-        int i;
-
-        if (len ==0)
-           return(0);
-
-       printf("%s0x0000: ",lf);
-       for(i=0;i<len;i++) {
-           if (!TTEST2(*(cp+i), 1)) {
-              printf("%spacket exceeded snapshot",lf);
-              return(0);
-            }
-           printf("%02x",*(cp+i));
-           if (i%2)
-               printf(" ");
-           if (i/16!=(i+1)/16) {
-               if (i<(len-1))
-                   printf("%s0x%04x: ",lf,i+1);
-           }
+       if (len < 0) {
+               printf("%sDissector error: print_unknown_data called with negative length",
+                   ident);
+               return(0);
+       }
+       if (snapend - cp < len)
+               len = snapend - cp;
+       if (len < 0) {
+               printf("%sDissector error: print_unknown_data called with pointer past end of packet",
+                   ident);
+               return(0);
        }
+        hex_print(ident,cp,len);
        return(1); /* everything is ok */
 }
 
@@ -227,20 +281,37 @@ print_unknown_data(const u_char *cp,const char *lf,int len)
  * Convert a token value to a string; use "fmt" if not found.
  */
 const char *
-tok2str(register const struct tok *lp, register const char *fmt,
-       register int v)
+tok2strbuf(register const struct tok *lp, register const char *fmt,
+          register int v, char *buf, size_t bufsize)
 {
-       static char buf[128];
-
-       while (lp->s != NULL) {
-               if (lp->v == v)
-                       return (lp->s);
-               ++lp;
+       if (lp != NULL) {
+               while (lp->s != NULL) {
+                       if (lp->v == v)
+                               return (lp->s);
+                       ++lp;
+               }
        }
        if (fmt == NULL)
                fmt = "#%d";
-       (void)snprintf(buf, sizeof(buf), fmt, v);
-       return (buf);
+
+       (void)snprintf(buf, bufsize, fmt, v);
+       return (const char *)buf;
+}
+
+/*
+ * Convert a token value to a string; use "fmt" if not found.
+ */
+const char *
+tok2str(register const struct tok *lp, register const char *fmt,
+       register int v)
+{
+       static char buf[4][128];
+       static int idx = 0;
+       char *ret;
+
+       ret = buf[idx];
+       idx = (idx+1) & 3;
+       return tok2strbuf(lp, fmt, v, ret, sizeof(buf[0]));
 }
 
 /*
@@ -249,14 +320,14 @@ tok2str(register const struct tok *lp, register const char *fmt,
  */
 char *
 bittok2str(register const struct tok *lp, register const char *fmt,
-       register int v)
+          register int v)
 {
         static char buf[256]; /* our stringbuffer */
         int buflen=0;
         register int rotbit; /* this is the bit we rotate through all bitpositions */
         register int tokval;
 
-       while (lp->s != NULL) {
+       while (lp->s != NULL && lp != NULL) {
             tokval=lp->v;   /* load our first value */
             rotbit=1;
             while (rotbit != 0) {
@@ -455,10 +526,12 @@ read_infile(char *fname)
 }
 
 void
-safeputs(const char *s)
+safeputs(const char *s, int maxlen)
 {
-       while (*s) {
+    int idx = 0;
+       while (*s && idx < maxlen) {
                safeputchar(*s);
+                idx++;
                s++;
        }
 }
@@ -472,5 +545,5 @@ safeputchar(int c)
        if (ch < 0x80 && isprint(ch))
                printf("%c", ch);
        else
-               printf("\\%03o", ch);
+               printf("\\0x%02x ", ch);
 }