print-ntp.c revision 39300
169783Smsmith/* 269783Smsmith * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 369783Smsmith * The Regents of the University of California. All rights reserved. 469783Smsmith * 569783Smsmith * Redistribution and use in source and binary forms, with or without 669783Smsmith * modification, are permitted provided that: (1) source code distributions 769783Smsmith * retain the above copyright notice and this paragraph in its entirety, (2) 869783Smsmith * distributions including binary code include the above copyright notice and 969783Smsmith * this paragraph in its entirety in the documentation or other materials 1069783Smsmith * provided with the distribution, and (3) all advertising materials mentioning 1169783Smsmith * features or use of this software display the following acknowledgement: 1269783Smsmith * ``This product includes software developed by the University of California, 1369783Smsmith * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1469783Smsmith * the University nor the names of its contributors may be used to endorse 1569783Smsmith * or promote products derived from this software without specific prior 1669783Smsmith * written permission. 1769783Smsmith * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1869783Smsmith * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1969783Smsmith * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2069783Smsmith * 2169783Smsmith * Format and print ntp packets. 2269783Smsmith * By Jeffrey Mogul/DECWRL 2369783Smsmith * loosely based on print-bootp.c 2469783Smsmith */ 2569783Smsmith 2669783Smsmith#ifndef lint 2769783Smsmithstatic const char rcsid[] = 2869783Smsmith "@(#) $Header: print-ntp.c,v 1.26 97/06/13 12:56:37 leres Exp $ (LBL)"; 2969783Smsmith#endif 3069783Smsmith 31119418Sobrien#include <sys/param.h> 32119418Sobrien#include <sys/time.h> 33119418Sobrien#include <sys/socket.h> 3469783Smsmith 3569783Smsmith#if __STDC__ 3669783Smsmithstruct mbuf; 3769783Smsmithstruct rtentry; 3869783Smsmith#endif 39221393Sjhb#include <net/if.h> 4069783Smsmith 41221393Sjhb#include <netinet/in.h> 42129876Sphk#include <net/ethernet.h> 43107546Simp 44106844Smdodd#include <ctype.h> 45221393Sjhb#include <stdio.h> 4669783Smsmith#include <string.h> 47119285Simp 48119285Simp#include "interface.h" 49211430Sjhb#include "addrtoname.h" 50119285Simp#ifdef MODEMASK 5169783Smsmith#undef MODEMASK /* Solaris sucks */ 5269783Smsmith#endif 5369783Smsmith#include "ntp.h" 5469783Smsmith 55200341Sjkimstatic void p_sfix(const struct s_fixedpt *); 56200341Sjkimstatic void p_ntp_time(const struct l_fixedpt *); 57211430Sjhbstatic void p_ntp_delta(const struct l_fixedpt *, const struct l_fixedpt *); 58211430Sjhb 59264011Srstone/* 60264011Srstone * Print ntp requests 61264011Srstone */ 62264011Srstonevoid 63264011Srstonentp_print(register const u_char *cp, u_int length) 64264011Srstone{ 65264011Srstone register const struct ntpdata *bp; 66264011Srstone int mode, version, leapind; 67279443Srstone static char rclock[5]; 68279443Srstone 69279443Srstone bp = (struct ntpdata *)cp; 7069783Smsmith /* Note funny sized packets */ 7169783Smsmith if (length != sizeof(struct ntpdata)) 7269783Smsmith (void)printf(" [len=%d]", length); 7369783Smsmith 7469783Smsmith TCHECK(bp->status); 75145661Simp 7669783Smsmith version = (int)(bp->status & VERSIONMASK) >> 3; 77200341Sjkim printf(" v%d", version); 78200341Sjkim 7969783Smsmith leapind = bp->status & LEAPMASK; 8069783Smsmith switch (leapind) { 8169783Smsmith 8269783Smsmith case NO_WARNING: 8369783Smsmith break; 84221393Sjhb 85221393Sjhb case PLUS_SEC: 86221393Sjhb fputs(" +1s", stdout); 87221393Sjhb break; 88221324Sjhb 8969783Smsmith case MINUS_SEC: 90221393Sjhb fputs(" -1s", stdout); 9169783Smsmith break; 9269783Smsmith } 9369783Smsmith 9469783Smsmith mode = bp->status & MODEMASK; 9569783Smsmith switch (mode) { 9669783Smsmith 97264011Srstone case MODE_UNSPEC: /* unspecified */ 98264011Srstone fputs(" unspec", stdout); 9969783Smsmith break; 10069783Smsmith 10169783Smsmith case MODE_SYM_ACT: /* symmetric active */ 102164264Sjhb fputs(" sym_act", stdout); 103164264Sjhb break; 104164264Sjhb 105164264Sjhb case MODE_SYM_PAS: /* symmetric passive */ 106169221Sjhb fputs(" sym_pas", stdout); 107211430Sjhb break; 108264011Srstone 109264011Srstone case MODE_CLIENT: /* client */ 110279443Srstone fputs(" client", stdout); 111279443Srstone break; 11269783Smsmith 113227843Smarius case MODE_SERVER: /* server */ 11469783Smsmith fputs(" server", stdout); 11569783Smsmith break; 116154079Sjhb 11769783Smsmith case MODE_BROADCAST: /* broadcast */ 118154079Sjhb fputs(" bcast", stdout); 119253120Smarius break; 12069783Smsmith 121221393Sjhb case MODE_RES1: /* reserved */ 122261527Sjhb fputs(" res1", stdout); 123221393Sjhb break; 124261527Sjhb 125261527Sjhb case MODE_RES2: /* reserved */ 126261527Sjhb fputs(" res2", stdout); 127261527Sjhb break; 128221393Sjhb 129221393Sjhb } 130221393Sjhb 131221393Sjhb TCHECK(bp->stratum); 132221393Sjhb printf(" strat %d", bp->stratum); 133221393Sjhb 134221393Sjhb TCHECK(bp->ppoll); 135221393Sjhb printf(" poll %d", bp->ppoll); 136221393Sjhb 137261790Sjhb /* Can't TCHECK bp->precision bitfield so bp->distance + 0 instead */ 138261790Sjhb TCHECK2(bp->distance, 0); 139261790Sjhb printf(" prec %d", bp->precision); 140261790Sjhb 141221393Sjhb if (!vflag) 142221393Sjhb return; 143221393Sjhb 144221393Sjhb TCHECK(bp->distance); 145221393Sjhb fputs(" dist ", stdout); 146221393Sjhb p_sfix(&bp->distance); 147221393Sjhb 148221393Sjhb TCHECK(bp->dispersion); 149221393Sjhb fputs(" disp ", stdout); 150221393Sjhb p_sfix(&bp->dispersion); 151221393Sjhb 152221393Sjhb TCHECK(bp->refid); 153221393Sjhb fputs(" ref ", stdout); 154221393Sjhb /* Interpretation depends on stratum */ 155221393Sjhb switch (bp->stratum) { 156221393Sjhb 157221393Sjhb case UNSPECIFIED: 158221393Sjhb printf("(unspec)"); 159221393Sjhb break; 160221393Sjhb 161221393Sjhb case PRIM_REF: 162221393Sjhb strncpy(rclock, (char *)&(bp->refid), 4); 163221393Sjhb rclock[4] = '\0'; 164221393Sjhb fputs(rclock, stdout); 165221393Sjhb break; 166221393Sjhb 167221393Sjhb case INFO_QUERY: 168221393Sjhb printf("%s INFO_QUERY", ipaddr_string(&(bp->refid))); 169221393Sjhb /* this doesn't have more content */ 170221393Sjhb return; 171221393Sjhb 172221393Sjhb case INFO_REPLY: 173221393Sjhb printf("%s INFO_REPLY", ipaddr_string(&(bp->refid))); 174221393Sjhb /* this is too complex to be worth printing */ 175221393Sjhb return; 176221393Sjhb 177221393Sjhb default: 178221393Sjhb printf("%s", ipaddr_string(&(bp->refid))); 179221393Sjhb break; 180221393Sjhb } 181221393Sjhb 182221393Sjhb TCHECK(bp->reftime); 183221393Sjhb putchar('@'); 184221393Sjhb p_ntp_time(&(bp->reftime)); 185221393Sjhb 186221393Sjhb TCHECK(bp->org); 187221393Sjhb fputs(" orig ", stdout); 188221393Sjhb p_ntp_time(&(bp->org)); 189221393Sjhb 190221393Sjhb TCHECK(bp->rec); 191221393Sjhb fputs(" rec ", stdout); 192221393Sjhb p_ntp_delta(&(bp->org), &(bp->rec)); 193221393Sjhb 194221393Sjhb TCHECK(bp->xmt); 195221393Sjhb fputs(" xmt ", stdout); 196221393Sjhb p_ntp_delta(&(bp->org), &(bp->xmt)); 197221393Sjhb 198221393Sjhb return; 199221393Sjhb 200221393Sjhbtrunc: 201221393Sjhb fputs(" [|ntp]", stdout); 202221393Sjhb} 203221393Sjhb 204221393Sjhbstatic void 205221393Sjhbp_sfix(register const struct s_fixedpt *sfp) 206221393Sjhb{ 207221393Sjhb register int i; 208221393Sjhb register int f; 209221393Sjhb register float ff; 210253450Sjhb 211253450Sjhb i = ntohs(sfp->int_part); 212253450Sjhb f = ntohs(sfp->fraction); 213253450Sjhb ff = f / 65536.0; /* shift radix point by 16 bits */ 214253450Sjhb f = ff * 1000000.0; /* Treat fraction as parts per million */ 215253450Sjhb printf("%d.%06d", i, f); 216253450Sjhb} 217253450Sjhb 218253450Sjhb#define FMAXINT (4294967296.0) /* floating point rep. of MAXINT */ 219253450Sjhb 220253450Sjhbstatic void 221253450Sjhbp_ntp_time(register const struct l_fixedpt *lfp) 222253450Sjhb{ 223253450Sjhb register int32_t i; 224253450Sjhb register u_int32_t uf; 225253450Sjhb register u_int32_t f; 226253450Sjhb register float ff; 227253450Sjhb 228253450Sjhb i = ntohl(lfp->int_part); 229253450Sjhb uf = ntohl(lfp->fraction); 230253450Sjhb ff = uf; 231253450Sjhb if (ff < 0.0) /* some compilers are buggy */ 232253450Sjhb ff += FMAXINT; 233253450Sjhb ff = ff / FMAXINT; /* shift radix point by 32 bits */ 234253450Sjhb f = ff * 1000000000.0; /* treat fraction as parts per billion */ 235253450Sjhb printf("%u.%09d", i, f); 236253450Sjhb} 237253450Sjhb 238253450Sjhb/* Prints time difference between *lfp and *olfp */ 239253450Sjhbstatic void 240253450Sjhbp_ntp_delta(register const struct l_fixedpt *olfp, 241253450Sjhb register const struct l_fixedpt *lfp) 242253450Sjhb{ 243253450Sjhb register int32_t i; 244253450Sjhb register u_int32_t uf; 245253450Sjhb register u_int32_t ouf; 246253450Sjhb register u_int32_t f; 247253450Sjhb register float ff; 248253450Sjhb int signbit; 249253450Sjhb 250253450Sjhb i = ntohl(lfp->int_part) - ntohl(olfp->int_part); 251253450Sjhb 252253450Sjhb uf = ntohl(lfp->fraction); 253253450Sjhb ouf = ntohl(olfp->fraction); 254221393Sjhb 255253450Sjhb if (i > 0) { /* new is definitely greater than old */ 256253450Sjhb signbit = 0; 257253450Sjhb f = uf - ouf; 258253450Sjhb if (ouf > uf) /* must borrow from high-order bits */ 259253450Sjhb i -= 1; 260253450Sjhb } else if (i < 0) { /* new is definitely less than old */ 261253450Sjhb signbit = 1; 262253450Sjhb f = ouf - uf; 263253450Sjhb if (uf > ouf) /* must carry into the high-order bits */ 264253450Sjhb i += 1; 265253450Sjhb i = -i; 266253450Sjhb } else { /* int_part is zero */ 267253450Sjhb if (uf > ouf) { 268253450Sjhb signbit = 0; 269253450Sjhb f = uf - ouf; 270253450Sjhb } else { 271253450Sjhb signbit = 1; 272253450Sjhb f = ouf - uf; 273253450Sjhb } 274253450Sjhb } 275253450Sjhb 276253450Sjhb ff = f; 277253450Sjhb if (ff < 0.0) /* some compilers are buggy */ 278253450Sjhb ff += FMAXINT; 279253450Sjhb ff = ff / FMAXINT; /* shift radix point by 32 bits */ 280253450Sjhb f = ff * 1000000000.0; /* treat fraction as parts per billion */ 281253450Sjhb if (signbit) 282253450Sjhb putchar('-'); 283253450Sjhb else 284253450Sjhb putchar('+'); 285253450Sjhb printf("%d.%09d", i, f); 286253450Sjhb} 287253450Sjhb