]> The Tcpdump Group git mirrors - tcpdump/blobdiff - util.c
Don't dump core if a null "struct tok" array pointer is passed to
[tcpdump] / util.c
diff --git a/util.c b/util.c
index a1c9f094c66673cb302836eba6cc7f62efc20c3c..47d7a136c462d05968e46a3167f09cb291ad5df6 100644 (file)
--- a/util.c
+++ b/util.c
@@ -20,8 +20,8 @@
  */
 
 #ifndef lint
-static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/util.c,v 1.82 2002-12-22 01:26:49 hannes Exp $ (LBL)";
+static const char rcsid[] _U_ =
+    "@(#) $Header: /tcpdump/master/tcpdump/util.c,v 1.95.2.1 2005-04-25 16:15:07 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -85,15 +85,10 @@ int
 fn_printn(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 (ep == NULL || s < ep) {
-               if (n-- <= 0) {
-                       ret = 0;
-                       break;
-               }
+       while (n > 0 && (ep == NULL || s < ep)) {
+               n--;
                c = *s++;
                if (!isascii(c)) {
                        c = toascii(c);
@@ -106,7 +101,7 @@ fn_printn(register const u_char *s, register u_int n,
                }
                putchar(c);
        }
-       return(ret);
+       return (n == 0) ? 0 : 1;
 }
 
 /*
@@ -121,19 +116,25 @@ ts_print(register const struct timeval *tvp)
        static unsigned b_sec;
        static unsigned b_usec;
 
-       switch(tflag) {
-       case 1: /* Default */
+       switch (tflag) {
+
+       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);
                break;
-       case -1: /* Unix timeval style */
+
+       case 1: /* No time stamp */
+               break;
+
+       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 */
                if (b_sec == 0) {
                        printf("000000 ");
                } else {
@@ -151,15 +152,18 @@ ts_print(register const struct timeval *tvp)
                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);
-               (void)printf("%02d/%02d/%04d %02d:%02d:%02d.%06u ",
-                            tm->tm_mon+1, tm->tm_mday,
-                            tm->tm_year+1900,
-                            s / 3600, (s % 3600) / 60,
-                            s % 60, (unsigned)tvp->tv_usec);
+               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);
                break;
        }
 }
@@ -202,28 +206,31 @@ 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);
+        hex_print(ident,cp,len);
+       return(1); /* everything is ok */
+}
 
-       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);
-           }
+/*
+ * Convert a token value to a string; use "fmt" if not found.
+ */
+const char *
+tok2strbuf(register const struct tok *lp, register const char *fmt,
+          register int v, char *buf, size_t bufsize)
+{
+       if (lp != NULL) {
+               while (lp->s != NULL) {
+                       if (lp->v == v)
+                               return (lp->s);
+                       ++lp;
+               }
        }
-       return(1); /* everything is ok */
+       if (fmt == NULL)
+               fmt = "#%d";
+
+       (void)snprintf(buf, bufsize, fmt, v);
+       return (const char *)buf;
 }
 
 /*
@@ -233,17 +240,13 @@ const char *
 tok2str(register const struct tok *lp, register const char *fmt,
        register int v)
 {
-       static char buf[128];
+       static char buf[4][128];
+       static int idx = 0;
+       char *ret;
 
-       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);
+       ret = buf[idx];
+       idx = (idx+1) & 3;
+       return tok2strbuf(lp, fmt, v, ret, sizeof(buf[0]));
 }
 
 /*
@@ -252,14 +255,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) {
@@ -331,15 +334,15 @@ mask2plen (u_int32_t mask)
                0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,
                0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff
        };
-       int prefix_len = 33;
+       int prefix_len = 32;
 
-        /* lets see if we can transform the mask into a prefixlen */
-        while (prefix_len >= 0) {
-            if (bitmasks[prefix_len] == mask)
-                break;
-            prefix_len--;
-        }
-        return (prefix_len);
+       /* let's see if we can transform the mask into a prefixlen */
+       while (prefix_len >= 0) {
+               if (bitmasks[prefix_len] == mask)
+                       break;
+               prefix_len--;
+       }
+       return (prefix_len);
 }
 
 /* VARARGS */
@@ -412,14 +415,24 @@ copy_argv(register char **argv)
        return buf;
 }
 
+/*
+ * On Windows, we need to open the file in binary mode, so that
+ * we get all the bytes specified by the size we get from "fstat()".
+ * On UNIX, that's not necessary.  O_BINARY is defined on Windows;
+ * we define it as 0 if it's not defined, so it does nothing.
+ */
+#ifndef O_BINARY
+#define O_BINARY       0
+#endif
+
 char *
 read_infile(char *fname)
 {
-       register int fd, cc;
+       register int i, fd, cc;
        register char *cp;
        struct stat buf;
 
-       fd = open(fname, O_RDONLY);
+       fd = open(fname, O_RDONLY|O_BINARY);
        if (fd < 0)
                error("can't open %s: %s", fname, pcap_strerror(errno));
 
@@ -434,18 +447,16 @@ read_infile(char *fname)
        if (cc < 0)
                error("read %s: %s", fname, pcap_strerror(errno));
        if (cc != buf.st_size)
-#ifndef WIN32
                error("short read %s (%d != %d)", fname, cc, (int)buf.st_size);
-#else
-/* Windows seems not to like the final \xa character */
-       {
-               char *pdest;
-               pdest=strchr( cp, '\xa');
-               *pdest=0;
-       }
-#endif /* WIN32 */
-       cp[(int)buf.st_size] = '\0';
 
+       close(fd);
+       /* replace "# comment" with spaces */
+       for (i = 0; i < cc; i++) {
+               if (cp[i] == '#')
+                       while (i < cc && cp[i] != '\n')
+                               cp[i++] = ' ';
+       }
+       cp[cc] = '\0';
        return (cp);
 }