X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/b83e04bd09ac42db9e362a627568a8efbe099c22..c115ab8ae92fd369ac227e93419e76fd6ae8e75c:/util.c diff --git a/util.c b/util.c index 6a827dce..8f5d7283 100644 --- a/util.c +++ b/util.c @@ -53,6 +53,13 @@ #include #include "interface.h" +#include "timeval-operations.h" + +/* + * timestamp display buffer size, the biggest size of both formats is needed + * sizeof("0000000000.000000000") > sizeof("00:00:00.000000000") + */ +#define TS_BUF_SIZE sizeof("0000000000.000000000") /* * Print out a null-terminated filename (or other ascii string). @@ -155,9 +162,8 @@ ts_format(netdissect_options *ndo #ifndef HAVE_PCAP_SET_TSTAMP_PRECISION _U_ #endif -, int sec, int usec) +, int sec, int usec, char *buf) { - static char buf[sizeof("00:00:00.000000000")]; const char *format; #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION @@ -172,19 +178,56 @@ _U_ break; default: - format = "%02d:%02d:%02d.{unknown precision}"; + format = "%02d:%02d:%02d.{unknown}"; break; } #else format = "%02d:%02d:%02d.%06u"; #endif - snprintf(buf, sizeof(buf), format, + snprintf(buf, TS_BUF_SIZE, format, sec / 3600, (sec % 3600) / 60, sec % 60, usec); return buf; } +/* + * Format the timestamp - Unix timeval style + */ +static char * +ts_unix_format(netdissect_options *ndo +#ifndef HAVE_PCAP_SET_TSTAMP_PRECISION +_U_ +#endif +, int sec, int usec, char *buf) +{ + const char *format; + +#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION + switch (ndo->ndo_tstamp_precision) { + + case PCAP_TSTAMP_PRECISION_MICRO: + format = "%u.%06u"; + break; + + case PCAP_TSTAMP_PRECISION_NANO: + format = "%u.%09u"; + break; + + default: + format = "%u.{unknown}"; + break; + } +#else + format = "%u.%06u"; +#endif + + snprintf(buf, TS_BUF_SIZE, format, + (unsigned)sec, (unsigned)usec); + + return buf; +} + /* * Print the timestamp */ @@ -195,52 +238,63 @@ ts_print(netdissect_options *ndo, register int s; struct tm *tm; time_t Time; - static unsigned b_sec; - static unsigned b_usec; - int d_usec; - int d_sec; + char buf[TS_BUF_SIZE]; + static struct timeval tv_ref; + struct timeval tv_result; + int negative_offset; + int nano_prec; switch (ndo->ndo_tflag) { case 0: /* Default */ s = (tvp->tv_sec + thiszone) % 86400; - ND_PRINT((ndo, "%s ", ts_format(ndo, s, tvp->tv_usec))); + ND_PRINT((ndo, "%s ", ts_format(ndo, s, tvp->tv_usec, buf))); break; case 1: /* No time stamp */ break; case 2: /* Unix timeval style */ - ND_PRINT((ndo, "%u.%06u ", - (unsigned)tvp->tv_sec, - (unsigned)tvp->tv_usec)); + ND_PRINT((ndo, "%s ", ts_unix_format(ndo, + tvp->tv_sec, tvp->tv_usec, buf))); break; - case 3: /* Microseconds since previous packet */ - case 5: /* Microseconds since first packet */ - if (b_sec == 0) { - /* init timestamp for first packet */ - b_usec = tvp->tv_usec; - b_sec = tvp->tv_sec; - } + case 3: /* Microseconds/nanoseconds since previous packet */ + case 5: /* Microseconds/nanoseconds since first packet */ +#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION + switch (ndo->ndo_tstamp_precision) { + case PCAP_TSTAMP_PRECISION_MICRO: + nano_prec = 0; + break; + case PCAP_TSTAMP_PRECISION_NANO: + nano_prec = 1; + break; + default: + nano_prec = 0; + break; + } +#else + nano_prec = 0; +#endif + if (!(tcpdump_timevalisset(&tv_ref))) + tv_ref = *tvp; /* set timestamp for first packet */ - d_usec = tvp->tv_usec - b_usec; - d_sec = tvp->tv_sec - b_sec; + negative_offset = tcpdump_timevalcmp(tvp, &tv_ref, <); + if (negative_offset) + tcpdump_timevalsub(&tv_ref, tvp, &tv_result, nano_prec); + else + tcpdump_timevalsub(tvp, &tv_ref, &tv_result, nano_prec); - while (d_usec < 0) { - d_usec += 1000000; - d_sec--; - } + ND_PRINT((ndo, (negative_offset ? "-" : " "))); - ND_PRINT((ndo, "%s ", ts_format(ndo, d_sec, d_usec))); + ND_PRINT((ndo, "%s ", ts_format(ndo, + tv_result.tv_sec, tv_result.tv_usec, buf))); - if (ndo->ndo_tflag == 3) { /* set timestamp for last packet */ - b_sec = tvp->tv_sec; - b_usec = tvp->tv_usec; - } + if (ndo->ndo_tflag == 3) + tv_ref = *tvp; /* set timestamp for previous packet */ break; - case 4: /* Default + Date*/ + case 4: /* Default + Date */ s = (tvp->tv_sec + thiszone) % 86400; Time = (tvp->tv_sec + thiszone) - s; tm = gmtime (&Time); @@ -249,7 +303,7 @@ ts_print(netdissect_options *ndo, else ND_PRINT((ndo, "%04d-%02d-%02d %s ", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, - ts_format(ndo, s, tvp->tv_usec))); + ts_format(ndo, s, tvp->tv_usec, buf))); break; } } @@ -337,7 +391,7 @@ tok2strbuf(register const struct tok *lp, register const char *fmt, */ const char * tok2str(register const struct tok *lp, register const char *fmt, - register int v) + register u_int v) { static char buf[4][128]; static int idx = 0; @@ -355,12 +409,12 @@ tok2str(register const struct tok *lp, register const char *fmt, */ static char * bittok2str_internal(register const struct tok *lp, register const char *fmt, - register int v, register int sep) + register u_int v, const char *sep) { static char buf[256]; /* our stringbuffer */ int buflen=0; - register int rotbit; /* this is the bit we rotate through all bitpositions */ - register int tokval; + register u_int rotbit; /* this is the bit we rotate through all bitpositions */ + register u_int tokval; const char * sepstr = ""; while (lp != NULL && lp->s != NULL) { @@ -375,7 +429,7 @@ bittok2str_internal(register const struct tok *lp, register const char *fmt, /* ok we have found something */ buflen+=snprintf(buf+buflen, sizeof(buf)-buflen, "%s%s", sepstr, lp->s); - sepstr = sep ? ", " : ""; + sepstr = sep; break; } rotbit=rotbit<<1; /* no match - lets shift and try again */ @@ -385,7 +439,7 @@ bittok2str_internal(register const struct tok *lp, register const char *fmt, if (buflen == 0) /* bummer - lets print the "unknown" message as advised in the fmt string if we got one */ - (void)snprintf(buf, sizeof(buf), fmt == NULL ? "#%d" : fmt, v); + (void)snprintf(buf, sizeof(buf), fmt == NULL ? "#%08x" : fmt, v); return (buf); } @@ -395,9 +449,9 @@ bittok2str_internal(register const struct tok *lp, register const char *fmt, */ char * bittok2str_nosep(register const struct tok *lp, register const char *fmt, - register int v) + register u_int v) { - return (bittok2str_internal(lp, fmt, v, 0)); + return (bittok2str_internal(lp, fmt, v, "")); } /* @@ -406,9 +460,9 @@ bittok2str_nosep(register const struct tok *lp, register const char *fmt, */ char * bittok2str(register const struct tok *lp, register const char *fmt, - register int v) + register u_int v) { - return (bittok2str_internal(lp, fmt, v, 1)); + return (bittok2str_internal(lp, fmt, v, ", ")); } /* @@ -633,6 +687,7 @@ print_txt_line(netdissect_options *ndo, const char *protoname, * in the buffer; treat this as if it were truncated. */ trunc: + linelen = idx - startidx; ND_PRINT((ndo, "%s%.*s[!%s]", prefix, (int)linelen, pptr + startidx, protoname)); return (0);