/* * record_crypto_stats - write crypto statistics to file * * file format: * day (mjd) * time (s past midnight) * peer ip address * text message */ void record_crypto_stats( sockaddr_u *addr, const char *text /* text message */ ) { l_fp now; u_long day; if (!stats_control) return; get_systime(&now); filegen_setup(&cryptostats, now.l_ui); day = now.l_ui / 86400 + MJD_1900; now.l_ui %= 86400; if (cryptostats.fp != NULL) { if (addr == NULL) fprintf(cryptostats.fp, "%lu %s 0.0.0.0 %s\n", day, ulfptoa(&now, 3), text); else fprintf(cryptostats.fp, "%lu %s %s %s\n", day, ulfptoa(&now, 3), stoa(addr), text); fflush(cryptostats.fp); } }
/* * record_sys_stats - write system statistics to file * * file format * day (MJD) * time (s past midnight) * time since reset * packets recieved * packets for this host * current version * old version * access denied * bad length or format * bad authentication * declined * rate exceeded * KoD sent */ void record_sys_stats(void) { l_fp now; u_long day; if (!stats_control) return; get_systime(&now); filegen_setup(&sysstats, now.l_ui); day = now.l_ui / 86400 + MJD_1900; now.l_ui %= 86400; if (sysstats.fp != NULL) { fprintf(sysstats.fp, "%lu %s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n", day, ulfptoa(&now, 3), current_time - sys_stattime, sys_received, sys_processed, sys_newversion, sys_oldversion, sys_restricted, sys_badlength, sys_badauth, sys_declined, sys_limitrejected, sys_kodsent); fflush(sysstats.fp); proto_clr_stats(); } }
/* * record_loop_stats - write loop filter statistics to file * * file format: * day (MJD) * time (s past midnight) * offset * frequency (PPM) * jitter * wnder (PPM) * time constant (log2) */ void record_loop_stats( double offset, /* offset */ double freq, /* frequency (PPM) */ double jitter, /* jitter */ double wander, /* wander (PPM) */ int spoll ) { l_fp now; u_long day; if (!stats_control) return; get_systime(&now); filegen_setup(&loopstats, now.l_ui); day = now.l_ui / 86400 + MJD_1900; now.l_ui %= 86400; if (loopstats.fp != NULL) { fprintf(loopstats.fp, "%lu %s %.9f %.3f %.9f %.6f %d\n", day, ulfptoa(&now, 3), offset, freq * 1e6, jitter, wander * 1e6, spoll); fflush(loopstats.fp); } }
/* * record_raw_stats - write raw timestamps to file * * file format * day (MJD) * time (s past midnight) * peer ip address * IP address * t1 t2 t3 t4 timestamps */ void record_raw_stats( sockaddr_u *srcadr, sockaddr_u *dstadr, l_fp *t1, /* originate timestamp */ l_fp *t2, /* receive timestamp */ l_fp *t3, /* transmit timestamp */ l_fp *t4 /* destination timestamp */ ) { l_fp now; u_long day; if (!stats_control) return; get_systime(&now); filegen_setup(&rawstats, now.l_ui); day = now.l_ui / 86400 + MJD_1900; now.l_ui %= 86400; if (rawstats.fp != NULL) { fprintf(rawstats.fp, "%lu %s %s %s %s %s %s %s\n", day, ulfptoa(&now, 3), stoa(srcadr), dstadr ? stoa(dstadr) : "-", ulfptoa(t1, 9), ulfptoa(t2, 9), ulfptoa(t3, 9), ulfptoa(t4, 9)); fflush(rawstats.fp); } }
/* * record_peer_stats - write peer statistics to file * * file format: * day (MJD) * time (s past UTC midnight) * IP address * status word (hex) * offset * delay * dispersion * jitter */ void record_peer_stats( sockaddr_u *addr, int status, double offset, /* offset */ double delay, /* delay */ double dispersion, /* dispersion */ double jitter /* jitter */ ) { l_fp now; u_long day; if (!stats_control) return; get_systime(&now); filegen_setup(&peerstats, now.l_ui); day = now.l_ui / 86400 + MJD_1900; now.l_ui %= 86400; if (peerstats.fp != NULL) { fprintf(peerstats.fp, "%lu %s %s %x %.9f %.9f %.9f %.9f\n", day, ulfptoa(&now, 3), stoa(addr), status, offset, delay, dispersion, jitter); fflush(peerstats.fp); } }
/* * record_proto_stats - write system statistics to file * * file format * day (MJD) * time (s past midnight) * text message */ void record_proto_stats( char *str /* text string */ ) { l_fp now; u_long day; if (!stats_control) return; get_systime(&now); filegen_setup(&protostats, now.l_ui); day = now.l_ui / 86400 + MJD_1900; now.l_ui %= 86400; if (protostats.fp != NULL) { fprintf(protostats.fp, "%lu %s %s\n", day, ulfptoa(&now, 3), str); fflush(protostats.fp); } }
/* * record_raw_stats - write raw timestamps to file * * file format * day (MJD) * time (s past midnight) * peer ip address * IP address * t1 t2 t3 t4 timestamps */ void record_raw_stats( sockaddr_u *srcadr, sockaddr_u *dstadr, l_fp *t1, /* originate timestamp */ l_fp *t2, /* receive timestamp */ l_fp *t3, /* transmit timestamp */ l_fp *t4, /* destination timestamp */ int leap, int version, int mode, int stratum, int ppoll, int precision, double root_delay, /* seconds */ double root_dispersion,/* seconds */ u_int32 refid ) { l_fp now; u_long day; if (!stats_control) return; get_systime(&now); filegen_setup(&rawstats, now.l_ui); day = now.l_ui / 86400 + MJD_1900; now.l_ui %= 86400; if (rawstats.fp != NULL) { fprintf(rawstats.fp, "%lu %s %s %s %s %s %s %s %d %d %d %d %d %d %.6f %.6f %s\n", day, ulfptoa(&now, 3), stoa(srcadr), dstadr ? stoa(dstadr) : "-", ulfptoa(t1, 9), ulfptoa(t2, 9), ulfptoa(t3, 9), ulfptoa(t4, 9), leap, version, mode, stratum, ppoll, precision, root_delay, root_dispersion, refid_str(refid, stratum)); fflush(rawstats.fp); } }
/* * record_clock_stats - write clock statistics to file * * file format: * day (MJD) * time (s past midnight) * IP address * text message */ void record_clock_stats( sockaddr_u *addr, const char *text /* timecode string */ ) { l_fp now; u_long day; if (!stats_control) return; get_systime(&now); filegen_setup(&clockstats, now.l_ui); day = now.l_ui / 86400 + MJD_1900; now.l_ui %= 86400; if (clockstats.fp != NULL) { fprintf(clockstats.fp, "%lu %s %s %s\n", day, ulfptoa(&now, 3), stoa(addr), text); fflush(clockstats.fp); } }
/* * record_timing_stats - write timing statistics to file * * file format: * day (mjd) * time (s past midnight) * text message */ void record_timing_stats( const char *text /* text message */ ) { static unsigned int flshcnt; l_fp now; u_long day; if (!stats_control) return; get_systime(&now); filegen_setup(&timingstats, now.l_ui); day = now.l_ui / 86400 + MJD_1900; now.l_ui %= 86400; if (timingstats.fp != NULL) { fprintf(timingstats.fp, "%lu %s %s\n", day, lfptoa(&now, 3), text); if (++flshcnt % 100 == 0) fflush(timingstats.fp); } }
/* * stats_config - configure the stats operation */ void stats_config( int item, const char *invalue /* only one type so far */ ) { FILE *fp; const char *value; int len; char tbuf[80]; char str1[20], str2[20]; #ifndef VMS const char temp_ext[] = ".TEMP"; #else const char temp_ext[] = "-TEMP"; #endif /* * Expand environment strings under Windows NT, since the * command interpreter doesn't do this, the program must. */ #ifdef SYS_WINNT char newvalue[MAX_PATH], parameter[MAX_PATH]; if (!ExpandEnvironmentStrings(invalue, newvalue, MAX_PATH)) { switch(item) { case STATS_FREQ_FILE: strcpy(parameter,"STATS_FREQ_FILE"); break; case STATS_LEAP_FILE: strcpy(parameter,"STATS_LEAP_FILE"); break; case STATS_STATSDIR: strcpy(parameter,"STATS_STATSDIR"); break; case STATS_PID_FILE: strcpy(parameter,"STATS_PID_FILE"); break; default: strcpy(parameter,"UNKNOWN"); break; } value = invalue; msyslog(LOG_ERR, "ExpandEnvironmentStrings(%s) failed: %m\n", parameter); } else { value = newvalue; } #else value = invalue; #endif /* SYS_WINNT */ switch(item) { /* * Open and read frequency file. */ case STATS_FREQ_FILE: if (!value || (len = strlen(value)) == 0) break; stats_drift_file = erealloc(stats_drift_file, len + 1); stats_temp_file = erealloc(stats_temp_file, len + sizeof(".TEMP")); memcpy(stats_drift_file, value, (unsigned)(len+1)); memcpy(stats_temp_file, value, (unsigned)len); memcpy(stats_temp_file + len, temp_ext, sizeof(temp_ext)); /* * Open drift file and read frequency. If the file is * missing or contains errors, tell the loop to reset. */ if ((fp = fopen(stats_drift_file, "r")) == NULL) break; if (fscanf(fp, "%lf", &old_drift) != 1) { msyslog(LOG_ERR, "format error frequency file %s", stats_drift_file); fclose(fp); break; } fclose(fp); old_drift /= 1e6; prev_drift_comp = old_drift; break; /* * Specify statistics directory. */ case STATS_STATSDIR: /* * HMS: the following test is insufficient: * - value may be missing the DIR_SEP * - we still need the filename after it */ if (strlen(value) >= sizeof(statsdir)) { msyslog(LOG_ERR, "statsdir too long (>%d, sigh)", (int)sizeof(statsdir) - 1); } else { l_fp now; int add_dir_sep; int value_l = strlen(value); /* Add a DIR_SEP unless we already have one. */ if (value_l == 0) add_dir_sep = 0; else add_dir_sep = (DIR_SEP != value[value_l - 1]); if (add_dir_sep) snprintf(statsdir, sizeof(statsdir), "%s%c", value, DIR_SEP); else snprintf(statsdir, sizeof(statsdir), "%s", value); get_systime(&now); if(peerstats.prefix == &statsdir[0] && peerstats.fp != NULL) { fclose(peerstats.fp); peerstats.fp = NULL; filegen_setup(&peerstats, now.l_ui); } if(loopstats.prefix == &statsdir[0] && loopstats.fp != NULL) { fclose(loopstats.fp); loopstats.fp = NULL; filegen_setup(&loopstats, now.l_ui); } if(clockstats.prefix == &statsdir[0] && clockstats.fp != NULL) { fclose(clockstats.fp); clockstats.fp = NULL; filegen_setup(&clockstats, now.l_ui); } if(rawstats.prefix == &statsdir[0] && rawstats.fp != NULL) { fclose(rawstats.fp); rawstats.fp = NULL; filegen_setup(&rawstats, now.l_ui); } if(sysstats.prefix == &statsdir[0] && sysstats.fp != NULL) { fclose(sysstats.fp); sysstats.fp = NULL; filegen_setup(&sysstats, now.l_ui); } if(protostats.prefix == &statsdir[0] && protostats.fp != NULL) { fclose(protostats.fp); protostats.fp = NULL; filegen_setup(&protostats, now.l_ui); } #ifdef OPENSSL if(cryptostats.prefix == &statsdir[0] && cryptostats.fp != NULL) { fclose(cryptostats.fp); cryptostats.fp = NULL; filegen_setup(&cryptostats, now.l_ui); } #endif /* OPENSSL */ #ifdef DEBUG_TIMING if(timingstats.prefix == &statsdir[0] && timingstats.fp != NULL) { fclose(timingstats.fp); timingstats.fp = NULL; filegen_setup(&timingstats, now.l_ui); } #endif /* DEBUG_TIMING */ } break; /* * Open pid file. */ case STATS_PID_FILE: if ((fp = fopen(value, "w")) == NULL) { msyslog(LOG_ERR, "pid file %s: %m", value); break; } fprintf(fp, "%d", (int)getpid()); fclose(fp);; break; /* * Read leapseconds file. */ case STATS_LEAP_FILE: if ((fp = fopen(value, "r")) == NULL) { msyslog(LOG_ERR, "leapseconds file %s: %m", value); break; } if (leap_file(fp) < 0) { msyslog(LOG_ERR, "format error leapseconds file %s", value); } else { strcpy(str1, fstostr(leap_sec)); strcpy(str2, fstostr(leap_expire)); snprintf(tbuf, sizeof(tbuf), "%d leap %s expire %s", leap_tai, str1, str2); report_event(EVNT_TAI, NULL, tbuf); } fclose(fp); break; default: /* oh well */ break; } }
/* * change settings for filegen files */ void filegen_config( FILEGEN * gen, const char * dir, const char * fname, u_int type, u_int flag ) { int file_existed; l_fp now; /* * if nothing would be changed... */ if (strcmp(dir, gen->dir) == 0 && strcmp(fname, gen->fname) == 0 && type == gen->type && flag == gen->flag) return; /* * validate parameters */ if (!valid_fileref(dir, fname)) return; if (NULL != gen->fp) { fclose(gen->fp); gen->fp = NULL; file_existed = TRUE; } else { file_existed = FALSE; } DPRINTF(3, ("configuring filegen:\n" "\tdir:\t%s -> %s\n" "\tfname:\t%s -> %s\n" "\ttype:\t%d -> %d\n" "\tflag: %x -> %x\n", gen->dir, dir, gen->fname, fname, gen->type, type, gen->flag, flag)); if (strcmp(gen->dir, dir) != 0) { free(gen->dir); gen->dir = estrdup(dir); } if (strcmp(gen->fname, fname) != 0) { free(gen->fname); gen->fname = estrdup(fname); } gen->type = (u_char)type; gen->flag = (u_char)flag; /* * make filegen use the new settings * special action is only required when a generation file * is currently open * otherwise the new settings will be used anyway at the next open */ if (file_existed) { get_systime(&now); filegen_setup(gen, now.l_ui); } }