Standardize License information
[openafs.git] / src / ntp / ntpsubs.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #ifndef lint
11 #endif /* lint */
12 /*
13  * Revision 2.1  90/08/07  19:23:23
14  * Start with clean version to sync test and dev trees.
15  * 
16  * Revision 1.7  89/12/22  20:33:21
17  * hp/ux specific (initial port to it); Added <afs/param.h> and special include files for HPUX and misc other changes
18  * 
19  * Revision 1.6  89/12/11  14:26:16
20  * Added code to support AIX 2.2.1.
21  * 
22  * Revision 1.5  89/05/24  12:27:44
23  * Latest May 18, Version 4.3 release from UMD.
24  * 
25  * Revision 3.4.1.3  89/05/18  18:33:50
26  * Added support few a new type of unsigned long to double compiler brokenness,
27  * called GENERIC_UNS_BUG.  If this is defined, then the unsigned long is
28  * shifted right one bit, the high-order bit of the result is cleared, then
29  * converted to a double.  The double is multiplied by 2.0, and the a 1.0 is
30  * optionall added to it if the low order bit of the original unsigned long
31  * was set.  Whew!
32  * 
33  * Revision 3.4.1.2  89/03/29  12:46:02
34  * Check for success sending query before trying to listen for answers.  Will 
35  * catch case of no server running and an ICMP port unreachable being returned.
36  * 
37  * Revision 3.4.1.1  89/03/22  18:32:19
38  * patch3: Use new RCS headers.
39  * 
40  * Revision 3.4  89/03/17  18:37:18
41  * Latest test release.
42  * 
43  * Revision 3.3  89/03/15  14:20:03
44  * New baseline for next release.
45  * 
46  * Revision 3.2  89/03/07  18:29:22
47  * New version of UNIX NTP daemon based on the 6 March 1989 draft of the new
48  * NTP protocol spec.  This module has mostly cosmetic changes.
49  * 
50  * Revision 3.1.1.1  89/02/15  08:59:27
51  * *** empty log message ***
52  * 
53  * 
54  * Revision 3.1  89/01/30  14:43:18
55  * Second UNIX NTP test release.
56  * 
57  * Revision 3.0  88/12/12  15:58:59
58  * Test release of new UNIX NTP software.  This version should conform to the
59  * revised NTP protocol specification.
60  * 
61  */
62
63 #include <afs/param.h>
64 #include <stdio.h>
65 #include <sys/types.h>
66 #include <sys/param.h>
67 #include <sys/time.h>
68 #include <sys/uio.h>
69 #include <sys/socket.h>
70 #include <netinet/in.h>
71 #include <arpa/inet.h>
72 #include <errno.h>
73 #if defined(AIX)
74 #include <sys/syslog.h>
75 #else
76 #include <syslog.h>
77 #endif
78 #include "ntp.h"
79
80 extern int errno;
81
82 #define TRUE    1
83 #define FALSE   0
84
85 /*
86  *  The nice thing here is that the quantity is NEVER signed.
87  */
88 double
89 ul_fixed_to_double(t)
90         struct l_fixedpt *t;
91 {
92         double a, b;
93 #ifdef  GENERIC_UNS_BUG
94         register int i;
95
96         i = ntohl(t->fraction);
97         a = (afs_int32)((i >> 1) & 0x7fffffff);
98         a *= 2.0;
99         if (i & 1)
100                 a += 1.0;
101         a = a / (4.294967296e9);        /* shift dec point over by 32 bits */
102         i = ntohl(t->int_part);
103         b = (afs_int32)((i >> 1) & 0x7fffffff);
104         b *= 2.0;
105         if (i & 1)
106                 b += 1.0;
107 #else   /* GENERIC_UNS_BUG */
108         a = (afs_uint32) ntohl(t->fraction);
109 #ifdef  VAX_COMPILER_FLT_BUG
110         if (a < 0.0) a += 4.294967296e9;
111 #endif
112         a = a / (4.294967296e9);/* shift dec point over by 32 bits */
113         b = (afs_uint32) ntohl(t->int_part);
114 #ifdef  VAX_COMPILER_FLT_BUG
115         if (b < 0.0) b += 4.294967296e9;
116 #endif
117 #endif  /* GENERIC_UNS_BUG */
118         return (a + b);
119 }
120
121 /*
122  *  Here we have to worry about the high order bit being signed
123  */
124
125 #if     0
126 double
127 l_fixed_to_double(t)
128         struct l_fixedpt *t;
129 {
130         double a,b;
131
132         if (ntohl(t->int_part) & 0x80000000) {
133                 a = ntohl(~t->fraction);
134 #ifdef  VAX_COMPILER_FLT_BUG
135                 if (a < 0.0) a += 4.294967296e9;
136 #endif
137                 a = a / (4.294967296e9);
138                 b = ntohl(~t->int_part);
139 #ifdef  VAX_COMPILER_FLT_BUG
140                 if (b < 0.0) b += 4.294967296e9;
141 #endif
142                 a += b;
143                 a = -a;
144         } else {
145                 a = ntohl(t->fraction);
146 #ifdef  VAX_COMPILER_FLT_BUG
147                 if (a < 0.0) a += 4.294967296e9;
148 #endif
149                 a = a / (4.294967296e9);
150                 b = ntohl(t->int_part);
151 #ifdef  VAX_COMPILER_FLT_BUG
152                 if (b < 0.0) b += 4.294967296e9;
153 #endif
154                 a += b;
155         }
156         return (a);
157 }
158 #endif
159
160 /*
161  *  Here we have to worry about the high order bit being signed
162  */
163 double
164 s_fixed_to_double(t)
165         struct s_fixedpt *t;
166 {
167         double a;
168
169         if (ntohs(t->int_part) & 0x8000) {
170                 a = ntohs(~t->fraction & 0xFFFF);
171                 a = a / 65536.0;        /* shift dec point over by 16 bits */
172                 a +=  ntohs(~t->int_part & 0xFFFF);
173                 a = -a;
174         } else {
175                 a = ntohs(t->fraction);
176                 a = a / 65536.0;        /* shift dec point over by 16 bits */
177                 a += ntohs(t->int_part);
178         }
179         return (a);
180 }
181
182 void
183 double_to_l_fixed(t, value)
184         struct l_fixedpt *t;
185         double value;
186 {
187         double temp;
188
189         if (value >= (double) 0.0) {
190                 t->int_part = value;
191                 temp = value - t->int_part;
192                 temp *= 4.294967296e9;
193                 t->fraction = temp;
194                 t->int_part = htonl(t->int_part);
195                 t->fraction = htonl(t->fraction);
196         } else {
197                 value = -value;
198                 t->int_part = value;
199                 temp = value - t->int_part;
200                 temp *= 4.294967296e9;
201                 t->fraction = temp;
202                 t->int_part = htonl(~t->int_part);
203                 t->fraction = htonl(~t->fraction);
204         }
205 }
206
207 void
208 double_to_s_fixed(t, value)
209         struct s_fixedpt *t;
210         double value;
211 {
212         double temp;
213
214         if (value >= (double) 0.0) {
215                 t->int_part = value;
216                 temp = value - t->int_part;
217                 temp *= 65536.0;
218                 t->fraction = temp;
219                 t->int_part = htons(t->int_part);
220                 t->fraction = htons(t->fraction);
221         } else {
222                 value = -value;
223                 t->int_part = value;
224                 temp = value - t->int_part;
225                 temp *= 65536.0;
226                 t->fraction = temp;
227                 t->int_part = htons(~t->int_part);
228                 t->fraction = htons(~t->fraction);
229         }
230 }
231 /*
232         in the sun, trying to assign a float between 2^31 and 2^32
233         results in the value 2^31.  Neither 4.2bsd nor VMS have this
234         problem.  Reported it to Bob O'Brien of SMI
235 */
236 #ifdef  SUN_FLT_BUG
237 tstamp(stampp, tvp)
238         struct l_fixedpt *stampp;
239         struct timeval *tvp;
240 {
241         int tt;
242         double dd;
243
244         stampp->int_part = ntohl(JAN_1970 + tvp->tv_sec);
245         dd = (float) tvp->tv_usec / 1000000.0;
246         tt = dd * 2147483648.0;
247         stampp->fraction = ntohl((tt << 1));
248 }
249 #else
250 tstamp(stampp, tvp)
251         struct l_fixedpt *stampp;
252         struct timeval *tvp;
253 {
254         stampp->int_part = ntohl((afs_uint32) (JAN_1970 + tvp->tv_sec));
255         stampp->fraction = ntohl((afs_uint32) ((float) tvp->tv_usec * 4294.967295));
256 }
257 #endif
258
259 /*
260  * ntoa is similar to inet_ntoa, but cycles through a set of 8 buffers
261  * so it can be invoked several times in a function parameter list.
262  */
263
264 char *
265 ntoa (in_addr)
266 struct in_addr in_addr;
267 {
268         static int i = 0;
269         static char bufs[8][20];
270         unsigned char *p = (unsigned char *) &in_addr.s_addr;
271
272         i = (i + 1) % (sizeof bufs / sizeof bufs[0]);
273         sprintf (bufs[i], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
274         return bufs[i];
275 }
276
277 /* calculate effective precision, but repeated calls to gettimeofday */
278
279 int MeasurePrecision (intervalP)
280   int *intervalP;
281 {
282 #if     defined(AFS_SUN5_ENV)
283 #define MAXTIMEDIFFS 100
284 #else
285 #define MAXTIMEDIFFS 10
286 #endif
287
288     int diff[MAXTIMEDIFFS];
289     int nDiff;
290     int interval;
291     int i;
292     int q;
293     struct timeval tv0;
294
295     gettimeofday (&tv0, 0);
296     nDiff = 0;
297     while (nDiff < MAXTIMEDIFFS) {
298         struct timeval tv, ntv;
299         int counting = 2;               /* a counting kernel */
300         gettimeofday (&tv, 0);
301         do {
302             gettimeofday (&ntv, 0);
303
304             /*
305              * Bail if we are taking too long -- 30 seconds is arbitrary,
306              * but better than the previous approach, which was to bail
307              * after an arbitrary count of calls to gettimeofday().  This
308              * caused problems because the machines kept getting faster
309              * and the count kept getting exceeded.
310              */
311             if (ntv.tv_sec - tv0.tv_sec > 30) return 0;
312
313             interval = (ntv.tv_sec - tv.tv_sec)*1000000 +
314                 ntv.tv_usec - tv.tv_usec;
315             if (interval <= counting) counting = interval+2;
316         } while (interval <= counting); /* RT & sun4/280 kernels count */
317         if (interval < 0) return 0;     /* shouldn't happen but who knows... */
318         if (interval > 0) diff[nDiff++] = interval;
319     }
320
321     /* find average interval */
322     interval = 0;
323     for (i=0; i<MAXTIMEDIFFS; i++)
324         interval += diff[i];
325     interval = (interval + (MAXTIMEDIFFS/2)) / MAXTIMEDIFFS; /* round */
326     if (interval == 0) return 0;        /* some problem... */
327     if (intervalP) *intervalP = interval;
328
329     /* calculate binary exponent of interval in seconds */
330     q = 1000000;
331     i = 0;
332     while (q > interval) {
333         q >>= 1;
334         i--;
335     }
336     return i;
337 }