]> The Tcpdump Group git mirrors - tcpdump/blob - print-ntp.c
s/u_short/u_int16_t/ for KAME-origin source codes
[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
26 #ifndef lint
27 static const char rcsid[] =
28 "@(#) $Header: /tcpdump/master/tcpdump/print-ntp.c,v 1.27 1999-11-21 09:36:57 fenner Exp $ (LBL)";
29 #endif
30
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34
35 #include <sys/param.h>
36 #include <sys/time.h>
37 #include <sys/socket.h>
38
39 #if __STDC__
40 struct mbuf;
41 struct rtentry;
42 #endif
43 #include <net/if.h>
44
45 #include <netinet/in.h>
46 #include <netinet/if_ether.h>
47
48 #include <ctype.h>
49 #include <stdio.h>
50 #include <string.h>
51
52 #include "interface.h"
53 #include "addrtoname.h"
54 #ifdef MODEMASK
55 #undef MODEMASK /* Solaris sucks */
56 #endif
57 #include "ntp.h"
58
59 static void p_sfix(const struct s_fixedpt *);
60 static void p_ntp_time(const struct l_fixedpt *);
61 static void p_ntp_delta(const struct l_fixedpt *, const struct l_fixedpt *);
62
63 /*
64 * Print ntp requests
65 */
66 void
67 ntp_print(register const u_char *cp, u_int length)
68 {
69 register const struct ntpdata *bp;
70 int mode, version, leapind;
71 static char rclock[5];
72
73 bp = (struct ntpdata *)cp;
74 /* Note funny sized packets */
75 if (length != sizeof(struct ntpdata))
76 (void)printf(" [len=%d]", length);
77
78 TCHECK(bp->status);
79
80 version = (int)(bp->status & VERSIONMASK) >> 3;
81 printf(" v%d", version);
82
83 leapind = bp->status & LEAPMASK;
84 switch (leapind) {
85
86 case NO_WARNING:
87 break;
88
89 case PLUS_SEC:
90 fputs(" +1s", stdout);
91 break;
92
93 case MINUS_SEC:
94 fputs(" -1s", stdout);
95 break;
96 }
97
98 mode = bp->status & MODEMASK;
99 switch (mode) {
100
101 case MODE_UNSPEC: /* unspecified */
102 fputs(" unspec", stdout);
103 break;
104
105 case MODE_SYM_ACT: /* symmetric active */
106 fputs(" sym_act", stdout);
107 break;
108
109 case MODE_SYM_PAS: /* symmetric passive */
110 fputs(" sym_pas", stdout);
111 break;
112
113 case MODE_CLIENT: /* client */
114 fputs(" client", stdout);
115 break;
116
117 case MODE_SERVER: /* server */
118 fputs(" server", stdout);
119 break;
120
121 case MODE_BROADCAST: /* broadcast */
122 fputs(" bcast", stdout);
123 break;
124
125 case MODE_RES1: /* reserved */
126 fputs(" res1", stdout);
127 break;
128
129 case MODE_RES2: /* reserved */
130 fputs(" res2", stdout);
131 break;
132
133 }
134
135 TCHECK(bp->stratum);
136 printf(" strat %d", bp->stratum);
137
138 TCHECK(bp->ppoll);
139 printf(" poll %d", bp->ppoll);
140
141 /* Can't TCHECK bp->precision bitfield so bp->distance + 0 instead */
142 TCHECK2(bp->distance, 0);
143 printf(" prec %d", bp->precision);
144
145 if (!vflag)
146 return;
147
148 TCHECK(bp->distance);
149 fputs(" dist ", stdout);
150 p_sfix(&bp->distance);
151
152 TCHECK(bp->dispersion);
153 fputs(" disp ", stdout);
154 p_sfix(&bp->dispersion);
155
156 TCHECK(bp->refid);
157 fputs(" ref ", stdout);
158 /* Interpretation depends on stratum */
159 switch (bp->stratum) {
160
161 case UNSPECIFIED:
162 printf("(unspec)");
163 break;
164
165 case PRIM_REF:
166 strncpy(rclock, (char *)&(bp->refid), 4);
167 rclock[4] = '\0';
168 fputs(rclock, stdout);
169 break;
170
171 case INFO_QUERY:
172 printf("%s INFO_QUERY", ipaddr_string(&(bp->refid)));
173 /* this doesn't have more content */
174 return;
175
176 case INFO_REPLY:
177 printf("%s INFO_REPLY", ipaddr_string(&(bp->refid)));
178 /* this is too complex to be worth printing */
179 return;
180
181 default:
182 printf("%s", ipaddr_string(&(bp->refid)));
183 break;
184 }
185
186 TCHECK(bp->reftime);
187 putchar('@');
188 p_ntp_time(&(bp->reftime));
189
190 TCHECK(bp->org);
191 fputs(" orig ", stdout);
192 p_ntp_time(&(bp->org));
193
194 TCHECK(bp->rec);
195 fputs(" rec ", stdout);
196 p_ntp_delta(&(bp->org), &(bp->rec));
197
198 TCHECK(bp->xmt);
199 fputs(" xmt ", stdout);
200 p_ntp_delta(&(bp->org), &(bp->xmt));
201
202 return;
203
204 trunc:
205 fputs(" [|ntp]", stdout);
206 }
207
208 static void
209 p_sfix(register const struct s_fixedpt *sfp)
210 {
211 register int i;
212 register int f;
213 register float ff;
214
215 i = ntohs(sfp->int_part);
216 f = ntohs(sfp->fraction);
217 ff = f / 65536.0; /* shift radix point by 16 bits */
218 f = ff * 1000000.0; /* Treat fraction as parts per million */
219 printf("%d.%06d", i, f);
220 }
221
222 #define FMAXINT (4294967296.0) /* floating point rep. of MAXINT */
223
224 static void
225 p_ntp_time(register const struct l_fixedpt *lfp)
226 {
227 register int32_t i;
228 register u_int32_t uf;
229 register u_int32_t f;
230 register float ff;
231
232 i = ntohl(lfp->int_part);
233 uf = ntohl(lfp->fraction);
234 ff = uf;
235 if (ff < 0.0) /* some compilers are buggy */
236 ff += FMAXINT;
237 ff = ff / FMAXINT; /* shift radix point by 32 bits */
238 f = ff * 1000000000.0; /* treat fraction as parts per billion */
239 printf("%u.%09d", i, f);
240 }
241
242 /* Prints time difference between *lfp and *olfp */
243 static void
244 p_ntp_delta(register const struct l_fixedpt *olfp,
245 register const struct l_fixedpt *lfp)
246 {
247 register int32_t i;
248 register u_int32_t uf;
249 register u_int32_t ouf;
250 register u_int32_t f;
251 register float ff;
252 int signbit;
253
254 i = ntohl(lfp->int_part) - ntohl(olfp->int_part);
255
256 uf = ntohl(lfp->fraction);
257 ouf = ntohl(olfp->fraction);
258
259 if (i > 0) { /* new is definitely greater than old */
260 signbit = 0;
261 f = uf - ouf;
262 if (ouf > uf) /* must borrow from high-order bits */
263 i -= 1;
264 } else if (i < 0) { /* new is definitely less than old */
265 signbit = 1;
266 f = ouf - uf;
267 if (uf > ouf) /* must carry into the high-order bits */
268 i += 1;
269 i = -i;
270 } else { /* int_part is zero */
271 if (uf > ouf) {
272 signbit = 0;
273 f = uf - ouf;
274 } else {
275 signbit = 1;
276 f = ouf - uf;
277 }
278 }
279
280 ff = f;
281 if (ff < 0.0) /* some compilers are buggy */
282 ff += FMAXINT;
283 ff = ff / FMAXINT; /* shift radix point by 32 bits */
284 f = ff * 1000000000.0; /* treat fraction as parts per billion */
285 if (signbit)
286 putchar('-');
287 else
288 putchar('+');
289 printf("%d.%09d", i, f);
290 }