]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/tcpdump/print-ntp.c
Catch up with "base" telnet.
[FreeBSD/FreeBSD.git] / contrib / tcpdump / print-ntp.c
1 /*
2  * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that: (1) source code distributions
7  * retain the above copyright notice and this paragraph in its entirety, (2)
8  * distributions including binary code include the above copyright notice and
9  * this paragraph in its entirety in the documentation or other materials
10  * provided with the distribution, and (3) all advertising materials mentioning
11  * features or use of this software display the following acknowledgement:
12  * ``This product includes software developed by the University of California,
13  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14  * the University nor the names of its contributors may be used to endorse
15  * or promote products derived from this software without specific prior
16  * written permission.
17  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20  *
21  * Format and print ntp packets.
22  *      By Jeffrey Mogul/DECWRL
23  *      loosely based on print-bootp.c
24  *
25  * $FreeBSD$
26  */
27
28 #ifndef lint
29 static const char rcsid[] =
30     "@(#) $Header: /tcpdump/master/tcpdump/print-ntp.c,v 1.32 2001/08/20 15:36:57 fenner Exp $ (LBL)";
31 #endif
32
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
36
37 #include <sys/param.h>
38 #include <sys/time.h>
39 #include <sys/socket.h>
40
41 #include <netinet/in.h>
42
43 #include <ctype.h>
44 #include <stdio.h>
45 #include <string.h>
46
47 #include "interface.h"
48 #include "addrtoname.h"
49 #ifdef MODEMASK
50 #undef MODEMASK                                 /* Solaris sucks */
51 #endif
52 #include "ntp.h"
53
54 static void p_sfix(const struct s_fixedpt *);
55 static void p_ntp_time(const struct l_fixedpt *);
56 static void p_ntp_delta(const struct l_fixedpt *, const struct l_fixedpt *);
57
58 /*
59  * Print ntp requests
60  */
61 void
62 ntp_print(register const u_char *cp, u_int length)
63 {
64         register const struct ntpdata *bp;
65         int mode, version, leapind;
66
67         bp = (struct ntpdata *)cp;
68         /* Note funny sized packets */
69         if (length != sizeof(struct ntpdata))
70                 (void)printf(" [len=%d]", length);
71
72         TCHECK(bp->status);
73
74         version = (int)(bp->status & VERSIONMASK) >> 3;
75         printf(" v%d", version);
76
77         leapind = bp->status & LEAPMASK;
78         switch (leapind) {
79
80         case NO_WARNING:
81                 break;
82
83         case PLUS_SEC:
84                 fputs(" +1s", stdout);
85                 break;
86
87         case MINUS_SEC:
88                 fputs(" -1s", stdout);
89                 break;
90         }
91
92         mode = bp->status & MODEMASK;
93         switch (mode) {
94
95         case MODE_UNSPEC:       /* unspecified */
96                 fputs(" unspec", stdout);
97                 break;
98
99         case MODE_SYM_ACT:      /* symmetric active */
100                 fputs(" sym_act", stdout);
101                 break;
102
103         case MODE_SYM_PAS:      /* symmetric passive */
104                 fputs(" sym_pas", stdout);
105                 break;
106
107         case MODE_CLIENT:       /* client */
108                 fputs(" client", stdout);
109                 break;
110
111         case MODE_SERVER:       /* server */
112                 fputs(" server", stdout);
113                 break;
114
115         case MODE_BROADCAST:    /* broadcast */
116                 fputs(" bcast", stdout);
117                 break;
118
119         case MODE_RES1:         /* reserved */
120                 fputs(" res1", stdout);
121                 break;
122
123         case MODE_RES2:         /* reserved */
124                 fputs(" res2", stdout);
125                 break;
126
127         }
128
129         TCHECK(bp->stratum);
130         printf(" strat %d", bp->stratum);
131
132         TCHECK(bp->ppoll);
133         printf(" poll %d", bp->ppoll);
134
135         /* Can't TCHECK bp->precision bitfield so bp->distance + 0 instead */
136         TCHECK2(bp->distance, 0);
137         printf(" prec %d", bp->precision);
138
139         if (!vflag)
140                 return;
141
142         TCHECK(bp->distance);
143         fputs(" dist ", stdout);
144         p_sfix(&bp->distance);
145
146         TCHECK(bp->dispersion);
147         fputs(" disp ", stdout);
148         p_sfix(&bp->dispersion);
149
150         TCHECK(bp->refid);
151         fputs(" ref ", stdout);
152         /* Interpretation depends on stratum */
153         switch (bp->stratum) {
154
155         case UNSPECIFIED:
156                 printf("(unspec)");
157                 break;
158
159         case PRIM_REF:
160                 fn_printn((char *)&(bp->refid), 4, NULL);
161                 break;
162
163         case INFO_QUERY:
164                 printf("%s INFO_QUERY", ipaddr_string(&(bp->refid)));
165                 /* this doesn't have more content */
166                 return;
167
168         case INFO_REPLY:
169                 printf("%s INFO_REPLY", ipaddr_string(&(bp->refid)));
170                 /* this is too complex to be worth printing */
171                 return;
172
173         default:
174                 printf("%s", ipaddr_string(&(bp->refid)));
175                 break;
176         }
177
178         TCHECK(bp->reftime);
179         putchar('@');
180         p_ntp_time(&(bp->reftime));
181
182         TCHECK(bp->org);
183         fputs(" orig ", stdout);
184         p_ntp_time(&(bp->org));
185
186         TCHECK(bp->rec);
187         fputs(" rec ", stdout);
188         p_ntp_delta(&(bp->org), &(bp->rec));
189
190         TCHECK(bp->xmt);
191         fputs(" xmt ", stdout);
192         p_ntp_delta(&(bp->org), &(bp->xmt));
193
194         return;
195
196 trunc:
197         fputs(" [|ntp]", stdout);
198 }
199
200 static void
201 p_sfix(register const struct s_fixedpt *sfp)
202 {
203         register int i;
204         register int f;
205         register float ff;
206
207         i = ntohs(sfp->int_part);
208         f = ntohs(sfp->fraction);
209         ff = f / 65536.0;       /* shift radix point by 16 bits */
210         f = ff * 1000000.0;     /* Treat fraction as parts per million */
211         printf("%d.%06d", i, f);
212 }
213
214 #define FMAXINT (4294967296.0)  /* floating point rep. of MAXINT */
215
216 static void
217 p_ntp_time(register const struct l_fixedpt *lfp)
218 {
219         register int32_t i;
220         register u_int32_t uf;
221         register u_int32_t f;
222         register float ff;
223
224         i = ntohl(lfp->int_part);
225         uf = ntohl(lfp->fraction);
226         ff = uf;
227         if (ff < 0.0)           /* some compilers are buggy */
228                 ff += FMAXINT;
229         ff = ff / FMAXINT;      /* shift radix point by 32 bits */
230         f = ff * 1000000000.0;  /* treat fraction as parts per billion */
231         printf("%u.%09d", i, f);
232 }
233
234 /* Prints time difference between *lfp and *olfp */
235 static void
236 p_ntp_delta(register const struct l_fixedpt *olfp,
237             register const struct l_fixedpt *lfp)
238 {
239         register int32_t i;
240         register u_int32_t uf;
241         register u_int32_t ouf;
242         register u_int32_t f;
243         register float ff;
244         int signbit;
245
246         i = ntohl(lfp->int_part) - ntohl(olfp->int_part);
247
248         uf = ntohl(lfp->fraction);
249         ouf = ntohl(olfp->fraction);
250
251         if (i > 0) {            /* new is definitely greater than old */
252                 signbit = 0;
253                 f = uf - ouf;
254                 if (ouf > uf)   /* must borrow from high-order bits */
255                         i -= 1;
256         } else if (i < 0) {     /* new is definitely less than old */
257                 signbit = 1;
258                 f = ouf - uf;
259                 if (uf > ouf)   /* must carry into the high-order bits */
260                         i += 1;
261                 i = -i;
262         } else {                /* int_part is zero */
263                 if (uf > ouf) {
264                         signbit = 0;
265                         f = uf - ouf;
266                 } else {
267                         signbit = 1;
268                         f = ouf - uf;
269                 }
270         }
271
272         ff = f;
273         if (ff < 0.0)           /* some compilers are buggy */
274                 ff += FMAXINT;
275         ff = ff / FMAXINT;      /* shift radix point by 32 bits */
276         f = ff * 1000000000.0;  /* treat fraction as parts per billion */
277         if (signbit)
278                 putchar('-');
279         else
280                 putchar('+');
281         printf("%d.%09d", i, f);
282 }