int main(int argc, char **argv) { struct timeval tv, otv; if (argc != 2) { fprintf(stderr, "%s: use \"%s <delta>\"\n" " <delta> is a floating-point number of seconds\n", argv[0], argv[0]); exit(1); } if (str_to_tv(argv[1], &tv) < 0) { fprintf(stderr, "%s: not a time (float) number \"%s\"\n", argv[0], argv[1]); exit(1); } fprintf(stderr, "Requesting time-jump: %s seconds\n", tv_to_str(&tv)); if (gettimeofday(&otv, NULL) < 0) { fprintf(stderr, "%s: gettimeofday(): %s\n", argv[0], strerror(errno)); exit(1); } otv.tv_sec += tv.tv_sec; otv.tv_usec += tv.tv_usec; if (otv.tv_usec > 1000 * 1000) { otv.tv_usec -= 1000 * 1000; otv.tv_sec++; } if (settimeofday(&otv, NULL) < 0) { fprintf(stderr, "%s: settimeofday(): %s\n", argv[0], strerror(errno)); exit(1); } exit(0); }
int handle_pkt ( int rpktl, struct pkt *rpkt, struct addrinfo *host ) { struct timeval tv_dst; int sw_case, digits; char *hostname = NULL, *ref, *ts_str = NULL; double offset, precision, root_dispersion; char addr_buf[INET6_ADDRSTRLEN]; char *p_SNTP_PRETEND_TIME; if(rpktl > 0) sw_case = 1; else sw_case = rpktl; switch(sw_case) { case SERVER_UNUSEABLE: return -1; break; case PACKET_UNUSEABLE: break; case SERVER_AUTH_FAIL: break; case KOD_DEMOBILIZE: /* Received a DENY or RESTR KOD packet */ hostname = addrinfo_to_str(host); ref = (char *)&rpkt->refid; add_entry(hostname, ref); if (ENABLED_OPT(NORMALVERBOSE)) printf("sntp handle_pkt: Received KOD packet with code: %c%c%c%c from %s, demobilizing all connections\n", ref[0], ref[1], ref[2], ref[3], hostname); msyslog(LOG_WARNING, "Received a KOD packet with code %c%c%c%c from %s, demobilizing all connections", ref[0], ref[1], ref[2], ref[3], hostname); break; case KOD_RATE: /* Hmm... probably we should sleep a bit here */ break; case 1: if (ENABLED_OPT(NORMALVERBOSE)) { getnameinfo(host->ai_addr, host->ai_addrlen, addr_buf, sizeof(addr_buf), NULL, 0, NI_NUMERICHOST); printf("sntp handle_pkt: Received %i bytes from %s\n", rpktl, addr_buf); } GETTIMEOFDAY(&tv_dst, (struct timezone *)NULL); p_SNTP_PRETEND_TIME = getenv("SNTP_PRETEND_TIME"); if (p_SNTP_PRETEND_TIME) { long long input_time; sscanf(p_SNTP_PRETEND_TIME, "%lld", &input_time); tv_dst.tv_sec = (time_t)input_time; } offset_calculation(rpkt, rpktl, &tv_dst, &offset, &precision, &root_dispersion); for (digits = 0; (precision *= 10.) < 1.; ++digits) /* empty */ ; if (digits > 6) digits = 6; ts_str = tv_to_str(&tv_dst); printf("%s ", ts_str); if (offset > 0) printf("+"); printf("%.*f", digits, offset); if (root_dispersion > 0.) printf(" +/- %f secs", root_dispersion); printf("\n"); free(ts_str); if (p_SNTP_PRETEND_TIME) return 0; if (ENABLED_OPT(SETTOD) || ENABLED_OPT(ADJTIME)) return set_time(offset); return 0; } return 1; }
int handle_pkt( int rpktl, struct pkt * rpkt, sockaddr_u * host, const char * hostname ) { char disptxt[32]; const char * addrtxt; struct timeval tv_dst; int cnt; int sw_case; int digits; int stratum; char * ref; char * ts_str; const char * leaptxt; double offset; double precision; double synch_distance; char * p_SNTP_PRETEND_TIME; time_t pretend_time; #if SIZEOF_TIME_T == 8 long long ll; #else long l; #endif ts_str = NULL; if (rpktl > 0) sw_case = 1; else sw_case = rpktl; switch (sw_case) { case SERVER_UNUSEABLE: return -1; break; case PACKET_UNUSEABLE: break; case SERVER_AUTH_FAIL: break; case KOD_DEMOBILIZE: /* Received a DENY or RESTR KOD packet */ addrtxt = stoa(host); ref = (char *)&rpkt->refid; add_entry(addrtxt, ref); msyslog(LOG_WARNING, "KOD code %c%c%c%c from %s %s", ref[0], ref[1], ref[2], ref[3], addrtxt, hostname); break; case KOD_RATE: /* ** Hmm... ** We should probably call add_entry() with an ** expiration timestamp of several seconds in the future, ** and back-off even more if we get more RATE responses. */ break; case 1: TRACE(3, ("handle_pkt: %d bytes from %s %s\n", rpktl, stoa(host), hostname)); gettimeofday_cached(base, &tv_dst); p_SNTP_PRETEND_TIME = getenv("SNTP_PRETEND_TIME"); if (p_SNTP_PRETEND_TIME) { pretend_time = 0; #if SIZEOF_TIME_T == 4 if (1 == sscanf(p_SNTP_PRETEND_TIME, "%ld", &l)) pretend_time = (time_t)l; #elif SIZEOF_TIME_T == 8 if (1 == sscanf(p_SNTP_PRETEND_TIME, "%lld", &ll)) pretend_time = (time_t)ll; #else # include "GRONK: unexpected value for SIZEOF_TIME_T" #endif if (0 != pretend_time) tv_dst.tv_sec = pretend_time; } offset_calculation(rpkt, rpktl, &tv_dst, &offset, &precision, &synch_distance); time_derived = TRUE; for (digits = 0; (precision *= 10.) < 1.; ++digits) /* empty */ ; if (digits > 6) digits = 6; ts_str = tv_to_str(&tv_dst); stratum = rpkt->stratum; if (0 == stratum) stratum = 16; if (synch_distance > 0.) { cnt = snprintf(disptxt, sizeof(disptxt), " +/- %f", synch_distance); if ((size_t)cnt >= sizeof(disptxt)) snprintf(disptxt, sizeof(disptxt), "ERROR %d >= %d", cnt, (int)sizeof(disptxt)); } else { disptxt[0] = '\0'; } switch (PKT_LEAP(rpkt->li_vn_mode)) { case LEAP_NOWARNING: leaptxt = "no-leap"; break; case LEAP_ADDSECOND: leaptxt = "add-leap"; break; case LEAP_DELSECOND: leaptxt = "del-leap"; break; case LEAP_NOTINSYNC: leaptxt = "unsync"; break; default: leaptxt = "LEAP-ERROR"; break; } msyslog(LOG_INFO, "%s %+.*f%s %s s%d %s%s", ts_str, digits, offset, disptxt, hostnameaddr(hostname, host), stratum, leaptxt, (time_adjusted) ? " [excess]" : ""); free(ts_str); if (p_SNTP_PRETEND_TIME) return 0; if (!time_adjusted && (ENABLED_OPT(STEP) || ENABLED_OPT(SLEW))) return set_time(offset); return EX_OK; } return 1; }