Deleted Added
sdiff udiff text old ( 82498 ) new ( 132451 )
full compact
1/*
2 * ntp_util.c - stuff I didn't have any other place for
3 */
4
5#ifdef HAVE_CONFIG_H
6# include <config.h>
7#endif
8

--- 25 unchanged lines hidden (view full) ---

34#endif
35
36#if defined(VMS)
37#include <descrip.h>
38#endif /* VMS */
39
40/*
41 * This contains odds and ends. Right now the only thing you'll find
42 * in here is the hourly stats printer and some code to support
43 * rereading the keys file, but I may eventually put other things in
44 * here such as code to do something with the leap bits.
45 */
46/*
47 * Name of the keys file
48 */
49static char *key_file_name;
50
51/*
52 * The name of the drift_comp file and the temporary.
53 */

--- 16 unchanged lines hidden (view full) ---

70#endif
71
72static char statsdir[MAXPATHLEN] = NTP_VAR;
73
74static FILEGEN peerstats;
75static FILEGEN loopstats;
76static FILEGEN clockstats;
77static FILEGEN rawstats;
78static FILEGEN sysstats;
79#ifdef OPENSSL
80static FILEGEN cryptostats;
81#endif /* OPENSSL */
82
83/*
84 * This controls whether stats are written to the fileset. Provided
85 * so that ntpdc can turn off stats when the file system fills up.
86 */
87int stats_control;
88
89/*

--- 5 unchanged lines hidden (view full) ---

95 stats_drift_file = 0;
96 stats_temp_file = 0;
97 key_file_name = 0;
98
99#define PEERNAME "peerstats"
100#define LOOPNAME "loopstats"
101#define CLOCKNAME "clockstats"
102#define RAWNAME "rawstats"
103#define STANAME "systats"
104#ifdef OPENSSL
105#define CRYPTONAME "cryptostats"
106#endif /* OPENSSL */
107
108 peerstats.fp = NULL;
109 peerstats.prefix = &statsdir[0];
110 peerstats.basename = (char*)emalloc(strlen(PEERNAME)+1);
111 strcpy(peerstats.basename, PEERNAME);
112 peerstats.id = 0;
113 peerstats.type = FILEGEN_DAY;
114 peerstats.flag = FGEN_FLAG_LINK; /* not yet enabled !!*/
115 filegen_register("peerstats", &peerstats);

--- 20 unchanged lines hidden (view full) ---

136 rawstats.prefix = &statsdir[0];
137 rawstats.basename = (char*)emalloc(strlen(RAWNAME)+1);
138 strcpy(rawstats.basename, RAWNAME);
139 rawstats.id = 0;
140 rawstats.type = FILEGEN_DAY;
141 rawstats.flag = FGEN_FLAG_LINK; /* not yet enabled !!*/
142 filegen_register("rawstats", &rawstats);
143
144 sysstats.fp = NULL;
145 sysstats.prefix = &statsdir[0];
146 sysstats.basename = (char*)emalloc(strlen(STANAME)+1);
147 strcpy(sysstats.basename, STANAME);
148 sysstats.id = 0;
149 sysstats.type = FILEGEN_DAY;
150 sysstats.flag = FGEN_FLAG_LINK; /* not yet enabled !!*/
151 filegen_register("sysstats", &sysstats);
152
153#ifdef OPENSSL
154 cryptostats.fp = NULL;
155 cryptostats.prefix = &statsdir[0];
156 cryptostats.basename = (char*)emalloc(strlen(CRYPTONAME)+1);
157 strcpy(cryptostats.basename, CRYPTONAME);
158 cryptostats.id = 0;
159 cryptostats.type = FILEGEN_DAY;
160 cryptostats.flag = FGEN_FLAG_LINK; /* not yet enabled !!*/
161 filegen_register("cryptostats", &cryptostats);
162#endif /* OPENSSL */
163
164#undef PEERNAME
165#undef LOOPNAME
166#undef CLOCKNAME
167#undef RAWNAME
168#undef STANAME
169#ifdef OPENSSL
170#undef CRYPTONAME
171#endif /* OPENSSL */
172}
173
174
175/*
176 * hourly_stats - print some interesting stats
177 */
178void
179hourly_stats(void)

--- 29 unchanged lines hidden (view full) ---

209 *
210 * CAVEAT: settimeofday() steps the sun clock by about 800 us,
211 * so setting DOSYNCTODR seems a bad idea in the
212 * case of us resolution
213 */
214
215#if !defined(VMS)
216 /* (prr) getpriority returns -1 on error, but -1 is also a valid
217 * return value (!), so instead we have to zero errno before the
218 * call and check it for non-zero afterwards.
219 */
220 errno = 0;
221 prio_set = 0;
222 o_prio = getpriority(PRIO_PROCESS,0); /* Save setting */
223
224 /*
225 * (prr) if getpriority succeeded, call setpriority to raise
226 * scheduling priority as high as possible. If that succeeds
227 * as well, set the prio_set flag so we remember to reset
228 * priority to its previous value below. Note that on Solaris
229 * 2.6 (and beyond?), both getpriority and setpriority will fail
230 * with ESRCH, because sched_setscheduler (called from main) put
231 * us in the real-time scheduling class which setpriority
232 * doesn't know about. Being in the real-time class is better
233 * than anything setpriority can do, anyhow, so this error is
234 * silently ignored.
235 */
236 if ((errno == 0) && (setpriority(PRIO_PROCESS,0,-20) == 0))
237 prio_set = 1; /* overdrive */
238#endif /* VMS */
239#ifdef HAVE_GETCLOCK
240 (void) getclock(TIMEOFDAY, &ts);
241 tv.tv_sec = ts.tv_sec;
242 tv.tv_usec = ts.tv_nsec / 1000;
243#else /* not HAVE_GETCLOCK */
244 GETTIMEOFDAY(&tv,(struct timezone *)NULL);
245#endif /* not HAVE_GETCLOCK */
246 if (ntp_set_tod(&tv,(struct timezone *)NULL) != 0) {
247 msyslog(LOG_ERR, "can't sync battery time: %m");
248 }
249#if !defined(VMS)
250 if (prio_set)
251 setpriority(PRIO_PROCESS, 0, o_prio); /* downshift */
252#endif /* VMS */
253#endif /* DOSYNCTODR */
254
255 NLOG(NLOG_SYSSTATIST)
256 msyslog(LOG_INFO,
257 "offset %.6f sec freq %.3f ppm error %.6f poll %d",
258 last_offset, drift_comp * 1e6, sys_jitter,
259 sys_poll);
260
261
262 record_sys_stats();
263 if (stats_drift_file != 0) {
264 if ((fp = fopen(stats_temp_file, "w")) == NULL) {
265 msyslog(LOG_ERR, "can't open %s: %m",
266 stats_temp_file);
267 return;
268 }
269 fprintf(fp, "%.3f\n", drift_comp * 1e6);
270 (void)fclose(fp);
271 /* atomic */
272#ifdef SYS_WINNT
273 (void) _unlink(stats_drift_file); /* rename semantics differ under NT */
274#endif /* SYS_WINNT */
275
276#ifndef NO_RENAME
277 (void) rename(stats_temp_file, stats_drift_file);
278#else
279 /* we have no rename NFS of ftp in use*/
280 if ((fp = fopen(stats_drift_file, "w")) == NULL) {
281 msyslog(LOG_ERR, "can't open %s: %m",

--- 26 unchanged lines hidden (view full) ---

308 char *invalue /* only one type so far */
309 )
310{
311 FILE *fp;
312 char *value;
313 double old_drift;
314 int len;
315
316 /*
317 * Expand environment strings under Windows NT, since the
318 * command interpreter doesn't do this, the program must.
319 */
320#ifdef SYS_WINNT
321 char newvalue[MAX_PATH], parameter[MAX_PATH];
322
323 if (!ExpandEnvironmentStrings(invalue, newvalue, MAX_PATH)) {
324 switch(item) {
325 case STATS_FREQ_FILE:
326 strcpy(parameter,"STATS_FREQ_FILE");
327 break;
328 case STATS_STATSDIR:
329 strcpy(parameter,"STATS_STATSDIR");
330 break;
331 case STATS_PID_FILE:
332 strcpy(parameter,"STATS_PID_FILE");
333 break;
334 default:
335 strcpy(parameter,"UNKNOWN");
336 break;
337 }
338 value = invalue;
339
340 msyslog(LOG_ERR,
341 "ExpandEnvironmentStrings(%s) failed: %m\n", parameter);
342 } else {
343 value = newvalue;
344 }
345#else
346 value = invalue;
347#endif /* SYS_WINNT */
348
349 switch(item) {
350 case STATS_FREQ_FILE:
351 if (stats_drift_file != 0) {
352 (void) free(stats_drift_file);
353 (void) free(stats_temp_file);
354 stats_drift_file = 0;
355 stats_temp_file = 0;
356 }
357
358 if (value == 0 || (len = strlen(value)) == 0)
359 break;
360
361 stats_drift_file = (char*)emalloc((u_int)(len + 1));
362#if !defined(VMS)
363 stats_temp_file = (char*)emalloc((u_int)(len +
364 sizeof(".TEMP")));
365#else
366 stats_temp_file = (char*)emalloc((u_int)(len +
367 sizeof("-TEMP")));
368#endif /* VMS */
369 memmove(stats_drift_file, value, (unsigned)(len+1));
370 memmove(stats_temp_file, value, (unsigned)len);
371#if !defined(VMS)
372 memmove(stats_temp_file + len, ".TEMP",
373 sizeof(".TEMP"));
374#else
375 memmove(stats_temp_file + len, "-TEMP",
376 sizeof("-TEMP"));
377#endif /* VMS */
378
379 /*
380 * Open drift file and read frequency. If the file is
381 * missing or contains errors, tell the loop to reset.
382 */
383 if ((fp = fopen(stats_drift_file, "r")) == NULL) {
384 loop_config(LOOP_DRIFTCOMP, 1e9);
385 break;
386 }
387 if (fscanf(fp, "%lf", &old_drift) != 1) {
388 msyslog(LOG_ERR, "Frequency format error in %s",
389 stats_drift_file);
390 loop_config(LOOP_DRIFTCOMP, 1e9);
391 fclose(fp);
392 break;
393 }
394 fclose(fp);
395 msyslog(LOG_INFO,
396 "frequency initialized %.3f PPM from %s",
397 old_drift, stats_drift_file);
398 loop_config(LOOP_DRIFTCOMP, old_drift / 1e6);
399 break;
400
401 case STATS_STATSDIR:
402 if (strlen(value) >= sizeof(statsdir)) {
403 msyslog(LOG_ERR,
404 "value for statsdir too long (>%d, sigh)",
405 (int)sizeof(statsdir)-1);

--- 21 unchanged lines hidden (view full) ---

427 filegen_setup(&clockstats, now.l_ui);
428 }
429 if(rawstats.prefix == &statsdir[0] &&
430 rawstats.fp != NULL) {
431 fclose(rawstats.fp);
432 rawstats.fp = NULL;
433 filegen_setup(&rawstats, now.l_ui);
434 }
435 if(sysstats.prefix == &statsdir[0] &&
436 sysstats.fp != NULL) {
437 fclose(sysstats.fp);
438 sysstats.fp = NULL;
439 filegen_setup(&sysstats, now.l_ui);
440 }
441#ifdef OPENSSL
442 if(cryptostats.prefix == &statsdir[0] &&
443 cryptostats.fp != NULL) {
444 fclose(cryptostats.fp);
445 cryptostats.fp = NULL;
446 filegen_setup(&cryptostats, now.l_ui);
447 }
448#endif /* OPENSSL */
449 }
450 break;
451
452 case STATS_PID_FILE:
453 if ((fp = fopen(value, "w")) == NULL) {
454 msyslog(LOG_ERR, "Can't open %s: %m", value);
455 break;
456 }

--- 17 unchanged lines hidden (view full) ---

474 * peer status word (hex)
475 * peer offset (s)
476 * peer delay (s)
477 * peer error bound (s)
478 * peer error (s)
479*/
480void
481record_peer_stats(
482 struct sockaddr_storage *addr,
483 int status,
484 double offset,
485 double delay,
486 double dispersion,
487 double skew
488 )
489{
490 l_fp now;
491 u_long day;
492
493 if (!stats_control)
494 return;
495
496 get_systime(&now);
497 filegen_setup(&peerstats, now.l_ui);
498 day = now.l_ui / 86400 + MJD_1900;
499 now.l_ui %= 86400;
500 if (peerstats.fp != NULL) {
501 fprintf(peerstats.fp,
502 "%lu %s %s %x %.9f %.9f %.9f %.9f\n",
503 day, ulfptoa(&now, 3), stoa(addr), status, offset,
504 delay, dispersion, skew);
505 fflush(peerstats.fp);
506 }
507}
508/*
509 * record_loop_stats - write loop filter statistics to file
510 *
511 * file format:
512 * day (mjd)
513 * time (s past midnight)
514 * offset (s)
515 * frequency (approx ppm)
516 * time constant (log base 2)
517 */
518void
519record_loop_stats(
520 double offset,
521 double freq,
522 double jitter,
523 double stability,
524 int spoll
525 )
526{
527 l_fp now;
528 u_long day;
529
530 if (!stats_control)
531 return;
532
533 get_systime(&now);
534 filegen_setup(&loopstats, now.l_ui);
535 day = now.l_ui / 86400 + MJD_1900;
536 now.l_ui %= 86400;
537 if (loopstats.fp != NULL) {
538 fprintf(loopstats.fp, "%lu %s %.9f %.6f %.9f %.6f %d\n",
539 day, ulfptoa(&now, 3), offset, freq * 1e6, jitter,
540 stability * 1e6, spoll);
541 fflush(loopstats.fp);
542 }
543}
544
545/*
546 * record_clock_stats - write clock statistics to file
547 *
548 * file format:
549 * day (mjd)
550 * time (s past midnight)
551 * peer (ip address)
552 * text message
553 */
554void
555record_clock_stats(
556 struct sockaddr_storage *addr,
557 const char *text
558 )
559{
560 l_fp now;
561 u_long day;
562
563 if (!stats_control)
564 return;
565
566 get_systime(&now);
567 filegen_setup(&clockstats, now.l_ui);
568 day = now.l_ui / 86400 + MJD_1900;
569 now.l_ui %= 86400;
570 if (clockstats.fp != NULL) {
571 fprintf(clockstats.fp, "%lu %s %s %s\n",
572 day, ulfptoa(&now, 3), stoa(addr), text);
573 fflush(clockstats.fp);
574 }
575}
576
577/*
578 * record_raw_stats - write raw timestamps to file
579 *
580 *
581 * file format
582 * time (s past midnight)
583 * peer ip address
584 * local ip address
585 * t1 t2 t3 t4 timestamps
586 */
587void
588record_raw_stats(
589 struct sockaddr_storage *srcadr,
590 struct sockaddr_storage *dstadr,
591 l_fp *t1,
592 l_fp *t2,
593 l_fp *t3,
594 l_fp *t4
595 )
596{
597 l_fp now;
598 u_long day;
599
600 if (!stats_control)
601 return;
602
603 get_systime(&now);
604 filegen_setup(&rawstats, now.l_ui);
605 day = now.l_ui / 86400 + MJD_1900;
606 now.l_ui %= 86400;
607 if (rawstats.fp != NULL) {
608 fprintf(rawstats.fp, "%lu %s %s %s %s %s %s %s\n",
609 day, ulfptoa(&now, 3), stoa(srcadr), stoa(dstadr),
610 ulfptoa(t1, 9), ulfptoa(t2, 9), ulfptoa(t3, 9),
611 ulfptoa(t4, 9));
612 fflush(rawstats.fp);
613 }
614}
615
616
617/*
618 * record_sys_stats - write system statistics to file
619 *
620 * file format
621 * time (s past midnight)
622 * time since startup (hr)
623 * packets recieved
624 * packets processed
625 * current version
626 * previous version
627 * bad version
628 * access denied
629 * bad length or format
630 * bad authentication
631 * rate exceeded
632 */
633void
634record_sys_stats(void)
635{
636 l_fp now;
637 u_long day;
638
639 if (!stats_control)
640 return;
641
642 get_systime(&now);
643 filegen_setup(&sysstats, now.l_ui);
644 day = now.l_ui / 86400 + MJD_1900;
645 now.l_ui %= 86400;
646 if (sysstats.fp != NULL) {
647 fprintf(sysstats.fp,
648 "%lu %s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
649 day, ulfptoa(&now, 3), sys_stattime / 3600,
650 sys_received, sys_processed, sys_newversionpkt,
651 sys_oldversionpkt, sys_unknownversion,
652 sys_restricted, sys_badlength, sys_badauth,
653 sys_limitrejected);
654 fflush(sysstats.fp);
655 proto_clr_stats();
656 }
657}
658
659
660#ifdef OPENSSL
661/*
662 * record_crypto_stats - write crypto statistics to file
663 *
664 * file format:
665 * day (mjd)
666 * time (s past midnight)
667 * peer (ip address)
668 * text message
669 */
670void
671record_crypto_stats(
672 struct sockaddr_storage *addr,
673 const char *text
674 )
675{
676 l_fp now;
677 u_long day;
678
679 if (!stats_control)
680 return;
681
682 get_systime(&now);
683 filegen_setup(&cryptostats, now.l_ui);
684 day = now.l_ui / 86400 + MJD_1900;
685 now.l_ui %= 86400;
686 if (cryptostats.fp != NULL) {
687 if (addr == NULL)
688 fprintf(cryptostats.fp, "%lu %s %s\n",
689 day, ulfptoa(&now, 3), text);
690 else
691 fprintf(cryptostats.fp, "%lu %s %s %s\n",
692 day, ulfptoa(&now, 3), stoa(addr), text);
693 fflush(cryptostats.fp);
694 }
695}
696#endif /* OPENSSL */
697
698
699/*
700 * getauthkeys - read the authentication keys from the specified file
701 */
702void
703getauthkeys(
704 char *keyfile
705 )
706{
707 int len;

--- 34 unchanged lines hidden (view full) ---

742 * rereadkeys - read the authentication key file over again.
743 */
744void
745rereadkeys(void)
746{
747 if (key_file_name != 0)
748 authreadkeys(key_file_name);
749}
750
751/*
752 * sock_hash - hash an sockaddr_storage structure
753 */
754int
755sock_hash(
756 struct sockaddr_storage *addr
757 )
758{
759 int hashVal;
760 int i;
761 int len;
762 char *ch;
763
764 hashVal = 0;
765 len = 0;
766 /*
767 * We can't just hash the whole thing because there are hidden
768 * fields in sockaddr_in6 that might be filled in by recvfrom(),
769 * so just use the family, port and address.
770 */
771 ch = (char *)&addr->ss_family;
772 hashVal = 37 * hashVal + (int)*ch;
773 if (sizeof(addr->ss_family) > 1) {
774 ch++;
775 hashVal = 37 * hashVal + (int)*ch;
776 }
777 switch(addr->ss_family) {
778 case AF_INET:
779 ch = (char *)&((struct sockaddr_in *)addr)->sin_addr;
780 len = sizeof(struct in_addr);
781 break;
782 case AF_INET6:
783 ch = (char *)&((struct sockaddr_in6 *)addr)->sin6_addr;
784 len = sizeof(struct in6_addr);
785 break;
786 }
787
788 for (i = 0; i < len ; i++)
789 hashVal = 37 * hashVal + (int)*(ch + i);
790
791 hashVal = hashVal % 128; /* % MON_HASH_SIZE hardcoded */
792
793 if (hashVal < 0)
794 hashVal += 128;
795
796 return hashVal;
797}