*/
#ifndef lint
-static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-ntp.c,v 1.31 2000-10-06 04:23:13 guy Exp $ (LBL)";
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ntp.c,v 1.43 2007-11-30 13:45:10 hannes Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/socket.h>
+#include <tcpdump-stdinc.h>
-#include <netinet/in.h>
-
-#include <ctype.h>
#include <stdio.h>
#include <string.h>
+#ifdef HAVE_STRFTIME
+#include <time.h>
+#endif
#include "interface.h"
#include "addrtoname.h"
+#include "extract.h"
#ifdef MODEMASK
#undef MODEMASK /* Solaris sucks */
#endif
static void p_ntp_time(const struct l_fixedpt *);
static void p_ntp_delta(const struct l_fixedpt *, const struct l_fixedpt *);
+static struct tok ntp_mode_values[] = {
+ { MODE_UNSPEC, "unspecified" },
+ { MODE_SYM_ACT, "symmetric active" },
+ { MODE_SYM_PAS, "symmetric passive" },
+ { MODE_CLIENT, "Client" },
+ { MODE_SERVER, "Server" },
+ { MODE_BROADCAST, "Broadcast" },
+ { MODE_RES1, "Reserved" },
+ { MODE_RES2, "Reserved" },
+ { 0, NULL }
+};
+
+static struct tok ntp_leapind_values[] = {
+ { NO_WARNING, "" },
+ { PLUS_SEC, "+1s" },
+ { MINUS_SEC, "-1s" },
+ { ALARM, "clock unsynchronized" },
+ { 0, NULL }
+};
+
+static struct tok ntp_stratum_values[] = {
+ { UNSPECIFIED, "unspecified" },
+ { PRIM_REF, "primary reference" },
+ { 0, NULL }
+};
+
/*
* Print ntp requests
*/
{
register const struct ntpdata *bp;
int mode, version, leapind;
- static char rclock[5];
bp = (struct ntpdata *)cp;
- /* Note funny sized packets */
- if (length != sizeof(struct ntpdata))
- (void)printf(" [len=%d]", length);
TCHECK(bp->status);
version = (int)(bp->status & VERSIONMASK) >> 3;
- printf(" v%d", version);
-
- leapind = bp->status & LEAPMASK;
- switch (leapind) {
-
- case NO_WARNING:
- break;
-
- case PLUS_SEC:
- fputs(" +1s", stdout);
- break;
-
- case MINUS_SEC:
- fputs(" -1s", stdout);
- break;
- }
+ printf("NTPv%d", version);
mode = bp->status & MODEMASK;
- switch (mode) {
-
- case MODE_UNSPEC: /* unspecified */
- fputs(" unspec", stdout);
- break;
-
- case MODE_SYM_ACT: /* symmetric active */
- fputs(" sym_act", stdout);
- break;
-
- case MODE_SYM_PAS: /* symmetric passive */
- fputs(" sym_pas", stdout);
- break;
-
- case MODE_CLIENT: /* client */
- fputs(" client", stdout);
- break;
-
- case MODE_SERVER: /* server */
- fputs(" server", stdout);
- break;
+ if (!vflag) {
+ printf (", %s, length %u",
+ tok2str(ntp_mode_values, "Unknown mode", mode),
+ length);
+ return;
+ }
+
+ printf (", length %u\n\t%s",
+ length,
+ tok2str(ntp_mode_values, "Unknown mode", mode));
- case MODE_BROADCAST: /* broadcast */
- fputs(" bcast", stdout);
- break;
-
- case MODE_RES1: /* reserved */
- fputs(" res1", stdout);
- break;
-
- case MODE_RES2: /* reserved */
- fputs(" res2", stdout);
- break;
-
- }
+ leapind = bp->status & LEAPMASK;
+ printf (", Leap indicator: %s (%u)",
+ tok2str(ntp_leapind_values, "Unknown", leapind),
+ leapind);
TCHECK(bp->stratum);
- printf(" strat %d", bp->stratum);
+ printf(", Stratum %u (%s)",
+ bp->stratum,
+ tok2str(ntp_stratum_values, (bp->stratum >=2 && bp->stratum<=15) ? "secondary reference" : "reserved", bp->stratum));
TCHECK(bp->ppoll);
- printf(" poll %d", bp->ppoll);
+ printf(", poll %us", bp->ppoll);
/* Can't TCHECK bp->precision bitfield so bp->distance + 0 instead */
- TCHECK2(bp->distance, 0);
- printf(" prec %d", bp->precision);
+ TCHECK2(bp->root_delay, 0);
+ printf(", precision %d", bp->precision);
- if (!vflag)
- return;
+ TCHECK(bp->root_delay);
+ fputs("\n\tRoot Delay: ", stdout);
+ p_sfix(&bp->root_delay);
- TCHECK(bp->distance);
- fputs(" dist ", stdout);
- p_sfix(&bp->distance);
-
- TCHECK(bp->dispersion);
- fputs(" disp ", stdout);
- p_sfix(&bp->dispersion);
+ TCHECK(bp->root_dispersion);
+ fputs(", Root dispersion: ", stdout);
+ p_sfix(&bp->root_dispersion);
TCHECK(bp->refid);
- fputs(" ref ", stdout);
+ fputs(", Reference-ID: ", stdout);
/* Interpretation depends on stratum */
switch (bp->stratum) {
break;
case PRIM_REF:
- strncpy(rclock, (char *)&(bp->refid), 4);
- rclock[4] = '\0';
- fputs(rclock, stdout);
+ if (fn_printn((u_char *)&(bp->refid), 4, snapend))
+ goto trunc;
break;
case INFO_QUERY:
break;
}
- TCHECK(bp->reftime);
- putchar('@');
- p_ntp_time(&(bp->reftime));
-
- TCHECK(bp->org);
- fputs(" orig ", stdout);
- p_ntp_time(&(bp->org));
-
- TCHECK(bp->rec);
- fputs(" rec ", stdout);
- p_ntp_delta(&(bp->org), &(bp->rec));
-
- TCHECK(bp->xmt);
- fputs(" xmt ", stdout);
- p_ntp_delta(&(bp->org), &(bp->xmt));
-
+ TCHECK(bp->ref_timestamp);
+ fputs("\n\t Reference Timestamp: ", stdout);
+ p_ntp_time(&(bp->ref_timestamp));
+
+ TCHECK(bp->org_timestamp);
+ fputs("\n\t Originator Timestamp: ", stdout);
+ p_ntp_time(&(bp->org_timestamp));
+
+ TCHECK(bp->rec_timestamp);
+ fputs("\n\t Receive Timestamp: ", stdout);
+ p_ntp_time(&(bp->rec_timestamp));
+
+ TCHECK(bp->xmt_timestamp);
+ fputs("\n\t Transmit Timestamp: ", stdout);
+ p_ntp_time(&(bp->xmt_timestamp));
+
+ fputs("\n\t Originator - Receive Timestamp: ", stdout);
+ p_ntp_delta(&(bp->org_timestamp), &(bp->rec_timestamp));
+
+ fputs("\n\t Originator - Transmit Timestamp: ", stdout);
+ p_ntp_delta(&(bp->org_timestamp), &(bp->xmt_timestamp));
+
+ if ( (sizeof(struct ntpdata) - length) == 16) { /* Optional: key-id */
+ TCHECK(bp->key_id);
+ printf("\n\tKey id: %u", bp->key_id);
+ } else if ( (sizeof(struct ntpdata) - length) == 0) { /* Optional: key-id + authentication */
+ TCHECK(bp->key_id);
+ printf("\n\tKey id: %u", bp->key_id);
+ TCHECK2(bp->message_digest, sizeof (bp->message_digest));
+ printf("\n\tAuthentication: %08x%08x%08x%08x",
+ EXTRACT_32BITS(bp->message_digest),
+ EXTRACT_32BITS(bp->message_digest + 4),
+ EXTRACT_32BITS(bp->message_digest + 8),
+ EXTRACT_32BITS(bp->message_digest + 12));
+ }
return;
trunc:
register int f;
register float ff;
- i = ntohs(sfp->int_part);
- f = ntohs(sfp->fraction);
+ i = EXTRACT_16BITS(&sfp->int_part);
+ f = EXTRACT_16BITS(&sfp->fraction);
ff = f / 65536.0; /* shift radix point by 16 bits */
f = ff * 1000000.0; /* Treat fraction as parts per million */
printf("%d.%06d", i, f);
register u_int32_t f;
register float ff;
- i = ntohl(lfp->int_part);
- uf = ntohl(lfp->fraction);
+ i = EXTRACT_32BITS(&lfp->int_part);
+ uf = EXTRACT_32BITS(&lfp->fraction);
ff = uf;
if (ff < 0.0) /* some compilers are buggy */
ff += FMAXINT;
ff = ff / FMAXINT; /* shift radix point by 32 bits */
f = ff * 1000000000.0; /* treat fraction as parts per billion */
printf("%u.%09d", i, f);
+
+#ifdef HAVE_STRFTIME
+ /*
+ * print the time in human-readable format.
+ */
+ if (i) {
+ time_t seconds = i - JAN_1970;
+ struct tm *tm;
+ char time_buf[128];
+
+ tm = localtime(&seconds);
+ strftime(time_buf, sizeof (time_buf), "%Y/%m/%d %H:%M:%S", tm);
+ printf (" (%s)", time_buf);
+ }
+#endif
}
/* Prints time difference between *lfp and *olfp */
register const struct l_fixedpt *lfp)
{
register int32_t i;
- register u_int32_t uf;
- register u_int32_t ouf;
+ register u_int32_t u, uf;
+ register u_int32_t ou, ouf;
register u_int32_t f;
register float ff;
int signbit;
- i = ntohl(lfp->int_part) - ntohl(olfp->int_part);
+ u = EXTRACT_32BITS(&lfp->int_part);
+ ou = EXTRACT_32BITS(&olfp->int_part);
+ uf = EXTRACT_32BITS(&lfp->fraction);
+ ouf = EXTRACT_32BITS(&olfp->fraction);
+ if (ou == 0 && ouf == 0) {
+ p_ntp_time(lfp);
+ return;
+ }
- uf = ntohl(lfp->fraction);
- ouf = ntohl(olfp->fraction);
+ i = u - ou;
if (i > 0) { /* new is definitely greater than old */
signbit = 0;
putchar('+');
printf("%d.%09d", i, f);
}
+