#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/util.c,v 1.58 1999-10-07 23:47:13 mcr Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/util.c,v 1.76 2002-07-18 00:04:12 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
#endif
#include <sys/types.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
-#endif
#include <pcap.h>
#include <stdio.h>
-#if __STDC__
#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
#include <stdlib.h>
#include <string.h>
#ifdef TIME_WITH_SYS_TIME
ts_print(register const struct timeval *tvp)
{
register int s;
+ struct tm *tm;
+ time_t Time;
+ static unsigned b_sec;
+ static unsigned b_usec;
- if (tflag > 0) {
- /* Default */
+ switch(tflag) {
+ case 1: /* Default */
s = (tvp->tv_sec + thiszone) % 86400;
(void)printf("%02d:%02d:%02d.%06u ",
- s / 3600, (s % 3600) / 60, s % 60, (u_int32_t)tvp->tv_usec);
- } else if (tflag < 0) {
- /* Unix timeval style */
+ s / 3600, (s % 3600) / 60, s % 60,
+ (unsigned)tvp->tv_usec);
+ break;
+ case -1: /* Unix timeval style */
(void)printf("%u.%06u ",
- (u_int32_t)tvp->tv_sec, (u_int32_t)tvp->tv_usec);
+ (unsigned)tvp->tv_sec,
+ (unsigned)tvp->tv_usec);
+ break;
+ case -2:
+ 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;
+ break;
+ case -3: /* 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);
+ break;
+ }
+}
+
+/*
+ * Print a relative number of seconds (e.g. hold time, prune timer)
+ * in the form 5m1s. This does no truncation, so 32230861 seconds
+ * is represented as 1y1w1d1h1m1s.
+ */
+void
+relts_print(int secs)
+{
+ static const char *lengths[] = {"y", "w", "d", "h", "m", "s"};
+ static const int seconds[] = {31536000, 604800, 86400, 3600, 60, 1};
+ const char **l = lengths;
+ const int *s = seconds;
+
+ if (secs == 0) {
+ (void)printf("0s");
+ return;
+ }
+ if (secs < 0) {
+ (void)printf("-");
+ secs = -secs;
+ }
+ while (secs > 0) {
+ if (secs >= *s) {
+ (void)printf("%d%s", secs / *s, *l);
+ secs -= (secs / *s) * *s;
+ }
+ s++;
+ l++;
+ }
+}
+
+/*
+ * this is a generic routine for printing unknown data;
+ * we pass on the linefeed plus indentation string to
+ * get a proper output - returns 0 on error
+ */
+
+int
+print_unknown_data(const u_char *cp,const char *lf,int len)
+{
+ int i;
+
+ 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);
+ }
}
+ return(1); /* everything is ok */
}
/*
}
if (fmt == NULL)
fmt = "#%d";
- (void)sprintf(buf, fmt, v);
+ (void)snprintf(buf, sizeof(buf), fmt, v);
return (buf);
}
+/*
+ * Convert a value to a string using an array; the macro
+ * tok2strary() in <interface.h> is the public interface to
+ * this function and ensures that the second argument is
+ * correct for bounds-checking.
+ */
+const char *
+tok2strary_internal(register const char **lp, int n, register const char *fmt,
+ register int v)
+{
+ static char buf[128];
+
+ if (v >= 0 && v < n && lp[v] != NULL)
+ return lp[v];
+ if (fmt == NULL)
+ fmt = "#%d";
+ (void)snprintf(buf, sizeof(buf), fmt, v);
+ return (buf);
+}
/* VARARGS */
-__dead void
-#if __STDC__
+void
error(const char *fmt, ...)
-#else
-error(fmt, va_alist)
- const char *fmt;
- va_dcl
-#endif
{
va_list ap;
(void)fprintf(stderr, "%s: ", program_name);
-#if __STDC__
va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
(void)vfprintf(stderr, fmt, ap);
va_end(ap);
if (*fmt) {
/* VARARGS */
void
-#if __STDC__
warning(const char *fmt, ...)
-#else
-warning(fmt, va_alist)
- const char *fmt;
- va_dcl
-#endif
{
va_list ap;
(void)fprintf(stderr, "%s: WARNING: ", program_name);
-#if __STDC__
va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
(void)vfprintf(stderr, fmt, ap);
va_end(ap);
if (*fmt) {
error("can't stat %s: %s", fname, pcap_strerror(errno));
cp = malloc((u_int)buf.st_size + 1);
- cc = read(fd, cp, (int)buf.st_size);
+ if (cp == NULL)
+ error("malloc(%d) for %s: %s", (u_int)buf.st_size + 1,
+ fname, pcap_strerror(errno));
+ cc = read(fd, cp, (u_int)buf.st_size);
if (cc < 0)
error("read %s: %s", fname, pcap_strerror(errno));
if (cc != buf.st_size)
return (cp);
}
+
+void
+safeputs(const char *s)
+{
+ while (*s) {
+ safeputchar(*s);
+ s++;
+ }
+}
+
+void
+safeputchar(int c)
+{
+ unsigned char ch;
+
+ ch = (unsigned char)(c & 0xff);
+ if (ch < 0x80 && isprint(ch))
+ printf("%c", ch);
+ else
+ printf("\\%03o", ch);
+}