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