print-ntp.c revision 56896
117680Spst/* 239300Sfenner * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 317680Spst * The Regents of the University of California. All rights reserved. 417680Spst * 517680Spst * Redistribution and use in source and binary forms, with or without 617680Spst * modification, are permitted provided that: (1) source code distributions 717680Spst * retain the above copyright notice and this paragraph in its entirety, (2) 817680Spst * distributions including binary code include the above copyright notice and 917680Spst * this paragraph in its entirety in the documentation or other materials 1017680Spst * provided with the distribution, and (3) all advertising materials mentioning 1117680Spst * features or use of this software display the following acknowledgement: 1217680Spst * ``This product includes software developed by the University of California, 1317680Spst * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1417680Spst * the University nor the names of its contributors may be used to endorse 1517680Spst * or promote products derived from this software without specific prior 1617680Spst * written permission. 1717680Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1817680Spst * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1917680Spst * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2017680Spst * 2117680Spst * Format and print ntp packets. 2217680Spst * By Jeffrey Mogul/DECWRL 2317680Spst * loosely based on print-bootp.c 2456896Sfenner * 2556896Sfenner * $FreeBSD: head/contrib/tcpdump/print-ntp.c 56896 2000-01-30 01:05:24Z fenner $ 2617680Spst */ 2717680Spst 2817680Spst#ifndef lint 2926183Sfennerstatic const char rcsid[] = 3056896Sfenner "@(#) $Header: /tcpdump/master/tcpdump/print-ntp.c,v 1.27 1999/11/21 09:36:57 fenner Exp $ (LBL)"; 3117680Spst#endif 3217680Spst 3356896Sfenner#ifdef HAVE_CONFIG_H 3456896Sfenner#include "config.h" 3556896Sfenner#endif 3656896Sfenner 3717680Spst#include <sys/param.h> 3817680Spst#include <sys/time.h> 3917680Spst#include <sys/socket.h> 4017680Spst 4117680Spst#if __STDC__ 4217680Spststruct mbuf; 4317680Spststruct rtentry; 4417680Spst#endif 4517680Spst#include <net/if.h> 4617680Spst 4717680Spst#include <netinet/in.h> 4821262Swollman#include <net/ethernet.h> 4917680Spst 5017680Spst#include <ctype.h> 5117680Spst#include <stdio.h> 5217680Spst#include <string.h> 5317680Spst 5417680Spst#include "interface.h" 5517680Spst#include "addrtoname.h" 5639300Sfenner#ifdef MODEMASK 5717680Spst#undef MODEMASK /* Solaris sucks */ 5839300Sfenner#endif 5917680Spst#include "ntp.h" 6017680Spst 6117680Spststatic void p_sfix(const struct s_fixedpt *); 6217680Spststatic void p_ntp_time(const struct l_fixedpt *); 6317680Spststatic void p_ntp_delta(const struct l_fixedpt *, const struct l_fixedpt *); 6417680Spst 6517680Spst/* 6617680Spst * Print ntp requests 6717680Spst */ 6817680Spstvoid 6917680Spstntp_print(register const u_char *cp, u_int length) 7017680Spst{ 7117680Spst register const struct ntpdata *bp; 7217680Spst int mode, version, leapind; 7317680Spst static char rclock[5]; 7417680Spst 7517680Spst bp = (struct ntpdata *)cp; 7617680Spst /* Note funny sized packets */ 7717680Spst if (length != sizeof(struct ntpdata)) 7817680Spst (void)printf(" [len=%d]", length); 7917680Spst 8017680Spst TCHECK(bp->status); 8117680Spst 8226183Sfenner version = (int)(bp->status & VERSIONMASK) >> 3; 8317680Spst printf(" v%d", version); 8417680Spst 8517680Spst leapind = bp->status & LEAPMASK; 8617680Spst switch (leapind) { 8717680Spst 8817680Spst case NO_WARNING: 8917680Spst break; 9017680Spst 9117680Spst case PLUS_SEC: 9217680Spst fputs(" +1s", stdout); 9317680Spst break; 9417680Spst 9517680Spst case MINUS_SEC: 9617680Spst fputs(" -1s", stdout); 9717680Spst break; 9817680Spst } 9917680Spst 10017680Spst mode = bp->status & MODEMASK; 10117680Spst switch (mode) { 10217680Spst 10317680Spst case MODE_UNSPEC: /* unspecified */ 10417680Spst fputs(" unspec", stdout); 10517680Spst break; 10617680Spst 10717680Spst case MODE_SYM_ACT: /* symmetric active */ 10817680Spst fputs(" sym_act", stdout); 10917680Spst break; 11017680Spst 11117680Spst case MODE_SYM_PAS: /* symmetric passive */ 11217680Spst fputs(" sym_pas", stdout); 11317680Spst break; 11417680Spst 11517680Spst case MODE_CLIENT: /* client */ 11617680Spst fputs(" client", stdout); 11717680Spst break; 11817680Spst 11917680Spst case MODE_SERVER: /* server */ 12017680Spst fputs(" server", stdout); 12117680Spst break; 12217680Spst 12317680Spst case MODE_BROADCAST: /* broadcast */ 12417680Spst fputs(" bcast", stdout); 12517680Spst break; 12617680Spst 12717680Spst case MODE_RES1: /* reserved */ 12817680Spst fputs(" res1", stdout); 12917680Spst break; 13017680Spst 13117680Spst case MODE_RES2: /* reserved */ 13217680Spst fputs(" res2", stdout); 13317680Spst break; 13417680Spst 13517680Spst } 13617680Spst 13717680Spst TCHECK(bp->stratum); 13817680Spst printf(" strat %d", bp->stratum); 13917680Spst 14017680Spst TCHECK(bp->ppoll); 14117680Spst printf(" poll %d", bp->ppoll); 14217680Spst 14317680Spst /* Can't TCHECK bp->precision bitfield so bp->distance + 0 instead */ 14417680Spst TCHECK2(bp->distance, 0); 14517680Spst printf(" prec %d", bp->precision); 14617680Spst 14717680Spst if (!vflag) 14817680Spst return; 14917680Spst 15017680Spst TCHECK(bp->distance); 15117680Spst fputs(" dist ", stdout); 15217680Spst p_sfix(&bp->distance); 15317680Spst 15417680Spst TCHECK(bp->dispersion); 15517680Spst fputs(" disp ", stdout); 15617680Spst p_sfix(&bp->dispersion); 15717680Spst 15817680Spst TCHECK(bp->refid); 15917680Spst fputs(" ref ", stdout); 16017680Spst /* Interpretation depends on stratum */ 16117680Spst switch (bp->stratum) { 16217680Spst 16317680Spst case UNSPECIFIED: 16417680Spst printf("(unspec)"); 16517680Spst break; 16617680Spst 16717680Spst case PRIM_REF: 16817680Spst strncpy(rclock, (char *)&(bp->refid), 4); 16917680Spst rclock[4] = '\0'; 17017680Spst fputs(rclock, stdout); 17117680Spst break; 17217680Spst 17317680Spst case INFO_QUERY: 17417680Spst printf("%s INFO_QUERY", ipaddr_string(&(bp->refid))); 17517680Spst /* this doesn't have more content */ 17617680Spst return; 17717680Spst 17817680Spst case INFO_REPLY: 17917680Spst printf("%s INFO_REPLY", ipaddr_string(&(bp->refid))); 18017680Spst /* this is too complex to be worth printing */ 18117680Spst return; 18217680Spst 18317680Spst default: 18417680Spst printf("%s", ipaddr_string(&(bp->refid))); 18517680Spst break; 18617680Spst } 18717680Spst 18817680Spst TCHECK(bp->reftime); 18917680Spst putchar('@'); 19017680Spst p_ntp_time(&(bp->reftime)); 19117680Spst 19217680Spst TCHECK(bp->org); 19317680Spst fputs(" orig ", stdout); 19417680Spst p_ntp_time(&(bp->org)); 19517680Spst 19617680Spst TCHECK(bp->rec); 19717680Spst fputs(" rec ", stdout); 19817680Spst p_ntp_delta(&(bp->org), &(bp->rec)); 19917680Spst 20017680Spst TCHECK(bp->xmt); 20117680Spst fputs(" xmt ", stdout); 20217680Spst p_ntp_delta(&(bp->org), &(bp->xmt)); 20317680Spst 20417680Spst return; 20517680Spst 20617680Spsttrunc: 20717680Spst fputs(" [|ntp]", stdout); 20817680Spst} 20917680Spst 21017680Spststatic void 21117680Spstp_sfix(register const struct s_fixedpt *sfp) 21217680Spst{ 21317680Spst register int i; 21417680Spst register int f; 21517680Spst register float ff; 21617680Spst 21717680Spst i = ntohs(sfp->int_part); 21817680Spst f = ntohs(sfp->fraction); 21917680Spst ff = f / 65536.0; /* shift radix point by 16 bits */ 22017680Spst f = ff * 1000000.0; /* Treat fraction as parts per million */ 22117680Spst printf("%d.%06d", i, f); 22217680Spst} 22317680Spst 22417680Spst#define FMAXINT (4294967296.0) /* floating point rep. of MAXINT */ 22517680Spst 22617680Spststatic void 22717680Spstp_ntp_time(register const struct l_fixedpt *lfp) 22817680Spst{ 22917680Spst register int32_t i; 23017680Spst register u_int32_t uf; 23117680Spst register u_int32_t f; 23217680Spst register float ff; 23317680Spst 23417680Spst i = ntohl(lfp->int_part); 23517680Spst uf = ntohl(lfp->fraction); 23617680Spst ff = uf; 23717680Spst if (ff < 0.0) /* some compilers are buggy */ 23817680Spst ff += FMAXINT; 23917680Spst ff = ff / FMAXINT; /* shift radix point by 32 bits */ 24017680Spst f = ff * 1000000000.0; /* treat fraction as parts per billion */ 24117680Spst printf("%u.%09d", i, f); 24217680Spst} 24317680Spst 24417680Spst/* Prints time difference between *lfp and *olfp */ 24517680Spststatic void 24617680Spstp_ntp_delta(register const struct l_fixedpt *olfp, 24717680Spst register const struct l_fixedpt *lfp) 24817680Spst{ 24917680Spst register int32_t i; 25017680Spst register u_int32_t uf; 25117680Spst register u_int32_t ouf; 25217680Spst register u_int32_t f; 25317680Spst register float ff; 25417680Spst int signbit; 25517680Spst 25617680Spst i = ntohl(lfp->int_part) - ntohl(olfp->int_part); 25717680Spst 25817680Spst uf = ntohl(lfp->fraction); 25917680Spst ouf = ntohl(olfp->fraction); 26017680Spst 26117680Spst if (i > 0) { /* new is definitely greater than old */ 26217680Spst signbit = 0; 26317680Spst f = uf - ouf; 26417680Spst if (ouf > uf) /* must borrow from high-order bits */ 26517680Spst i -= 1; 26617680Spst } else if (i < 0) { /* new is definitely less than old */ 26717680Spst signbit = 1; 26817680Spst f = ouf - uf; 26917680Spst if (uf > ouf) /* must carry into the high-order bits */ 27017680Spst i += 1; 27117680Spst i = -i; 27217680Spst } else { /* int_part is zero */ 27317680Spst if (uf > ouf) { 27417680Spst signbit = 0; 27517680Spst f = uf - ouf; 27617680Spst } else { 27717680Spst signbit = 1; 27817680Spst f = ouf - uf; 27917680Spst } 28017680Spst } 28117680Spst 28217680Spst ff = f; 28317680Spst if (ff < 0.0) /* some compilers are buggy */ 28417680Spst ff += FMAXINT; 28517680Spst ff = ff / FMAXINT; /* shift radix point by 32 bits */ 28617680Spst f = ff * 1000000000.0; /* treat fraction as parts per billion */ 28717680Spst if (signbit) 28817680Spst putchar('-'); 28917680Spst else 29017680Spst putchar('+'); 29117680Spst printf("%d.%09d", i, f); 29217680Spst} 293