📄 ntpclient.c
字号:
prec = Data(0) & 0xff; if (prec & 0x80) prec|=0xffffff00; delay = Data(1); disp = Data(2); refid = Data(3); reftime.coarse = Data(4); reftime.fine = Data(5); orgtime.coarse = Data(6); orgtime.fine = Data(7); rectime.coarse = Data(8); rectime.fine = Data(9); xmttime.coarse = Data(10); xmttime.fine = Data(11);#undef Data if (set_clock) { /* you'd better be root, or ntpclient will crash! */ struct timeval tv_set; /* it would be even better to subtract half the slop */ tv_set.tv_sec = xmttime.coarse - JAN_1970 + SyncTimeZone(); /* divide xmttime.fine by 4294.967296 */ tv_set.tv_usec = USEC(xmttime.fine); if (settimeofday(&tv_set,NULL)<0) { perror("settimeofday"); exit(1); } if (debug) { printf("set time to %lu.%.6lu\n", tv_set.tv_sec, tv_set.tv_usec); } } if (debug) { printf("LI=%d VN=%d Mode=%d Stratum=%d Poll=%d Precision=%d\n", li, vn, mode, stratum, poll, prec); printf("Delay=%.1f Dispersion=%.1f Refid=%u.%u.%u.%u\n", sec2u(delay),sec2u(disp), refid>>24&0xff, refid>>16&0xff, refid>>8&0xff, refid&0xff); printf("Reference %u.%.10u\n", reftime.coarse, reftime.fine); printf("Originate %u.%.10u\n", orgtime.coarse, orgtime.fine); printf("Receive %u.%.10u\n", rectime.coarse, rectime.fine); printf("Transmit %u.%.10u\n", xmttime.coarse, xmttime.fine); printf("Our recv %u.%.10u\n", arrival->coarse, arrival->fine); } el_time=ntpdiff(&orgtime,arrival); /* elapsed */ st_time=ntpdiff(&rectime,&xmttime); /* stall */ skew1=ntpdiff(&orgtime,&rectime); skew2=ntpdiff(&xmttime,arrival); freq=get_current_freq(); if (debug) { printf("Total elapsed: %9.2f\n" "Server stall: %9.2f\n" "Slop: %9.2f\n", el_time, st_time, el_time-st_time); printf("Skew: %9.2f\n" "Frequency: %9d\n" " day second elapsed stall skew dispersion freq\n", (skew1-skew2)/2, freq); } /* Not the ideal order for printing, but we want to be sure * to do all the time-sensitive thinking (and time setting) * before we start the output, especially fflush() (which * could be slow). Of course, if debug is turned on, speed * has gone down the drain anyway. */ if (live) { int new_freq; new_freq = contemplate_data(arrival->coarse, (skew1-skew2)/2, el_time+sec2u(disp), freq); if (!debug && new_freq != freq) set_freq(new_freq); } printf("%d %.5d.%.3d %8.1f %8.1f %8.1f %8.1f %9d\n", arrival->coarse/86400, arrival->coarse%86400, arrival->fine/4294967, el_time, st_time, (skew1-skew2)/2, sec2u(disp), freq); fflush(stdout); return(el_time-st_time);}void stuff_net_addr(struct in_addr *p, char *hostname){ struct hostent *ntpserver; ntpserver=gethostbyname(hostname); if (ntpserver == NULL) { herror(hostname); exit(1); } if (ntpserver->h_length != 4) { fprintf(stderr,"oops %d\n",ntpserver->h_length); exit(1); } memcpy(&(p->s_addr),ntpserver->h_addr_list[0],4);}void setup_receive(int usd, unsigned int interface, short port){ struct sockaddr_in sa_rcvr; bzero((char *) &sa_rcvr, sizeof(sa_rcvr)); sa_rcvr.sin_family=AF_INET; sa_rcvr.sin_addr.s_addr=htonl(interface); sa_rcvr.sin_port=htons(port); if(bind(usd,(struct sockaddr *) &sa_rcvr,sizeof(sa_rcvr)) == -1) { fprintf(stderr,"could not bind to udp port %d\n",port); perror("bind"); exit(1); } listen(usd,3);}void setup_transmit(int usd, char *host, short port){ struct sockaddr_in sa_dest; bzero((char *) &sa_dest, sizeof(sa_dest)); sa_dest.sin_family=AF_INET; stuff_net_addr(&(sa_dest.sin_addr),host); sa_dest.sin_port=htons(port); if (connect(usd,(struct sockaddr *)&sa_dest,sizeof(sa_dest))==-1) {perror("connect");exit(1);}}void primary_loop(int usd, int num_probes, int interval, int goodness){ fd_set fds; struct sockaddr sa_xmit; int i, pack_len, sa_xmit_len, probes_sent, error; struct timeval to; struct ntptime udp_arrival_ntp; if (debug) printf("Listening...\n"); if (debug && getenv("TZ")) printf("TZ is %s\n",getenv("TZ")); probes_sent=0; sa_xmit_len=sizeof(sa_xmit); to.tv_sec=0; to.tv_usec=0; for (;;) { FD_ZERO(&fds); FD_SET(usd,&fds); i=select(usd+1,&fds,NULL,NULL,&to); /* Wait on read or error */ if (debug) printf("select:%d\n",i); if ((i!=1)||(!FD_ISSET(usd,&fds))) { if (debug) printf("complex 1\n"); if (i==EINTR) continue; if (debug) printf("complex 2\n"); if (i<0) perror("select"); if (debug) printf("complex 3,to.tv_sec : %x\n",to.tv_sec); if (to.tv_sec == 0) { if (probes_sent >= num_probes && num_probes != 0) break; send_packet(usd); ++probes_sent; to.tv_sec=interval; to.tv_usec=0; } continue; } pack_len=recvfrom(usd,incoming,sizeof_incoming,0, &sa_xmit,&sa_xmit_len); if (debug) printf("rece pack_len:%d\n",pack_len); error = goodness+1; if (pack_len<0) { perror("recvfrom"); } else if (pack_len>0 && (unsigned)pack_len<sizeof_incoming){ get_packet_timestamp(usd, &udp_arrival_ntp); check_source(pack_len, &sa_xmit, sa_xmit_len); error = rfc1305print(incoming_word, &udp_arrival_ntp); /* udp_handle(usd,incoming,pack_len,&sa_xmit,sa_xmit_len); */ if (debug) printf("Setup time successfully\n"); break; } else { printf("Ooops. pack_len=%d\n",pack_len); fflush(stdout); } if (debug) printf("check error < goodness && goodness != 0\n"); if ( error < goodness && goodness != 0) break; if (debug) printf("check probes_sent >= num_probes && num_probes != 0\n"); if (probes_sent >= num_probes && num_probes != 0) break; } if (debug) printf("exist primary_loop\n");}void do_replay(void){ char line[100]; int n, day, freq, absolute; float sec, el_time, st_time, disp; double skew, errorbar; int simulated_freq = 0; unsigned int last_fake_time = 0; double fake_delta_time = 0.0; while (fgets(line,sizeof(line),stdin)) { n=sscanf(line,"%d %f %f %f %lf %f %d", &day, &sec, &el_time, &st_time, &skew, &disp, &freq); if (n==7) { fputs(line,stdout); absolute=day*86400+(int)sec; errorbar=el_time+disp; if (debug) printf("contemplate %u %.1f %.1f %d\n", absolute,skew,errorbar,freq); if (last_fake_time==0) simulated_freq=freq; fake_delta_time += (absolute-last_fake_time)*((double)(freq-simulated_freq))/65536; if (debug) printf("fake %f %d \n", fake_delta_time, simulated_freq); skew += fake_delta_time; freq = simulated_freq; last_fake_time=absolute; simulated_freq = contemplate_data(absolute, skew, errorbar, freq); } else { fprintf(stderr,"Replay input error\n"); exit(2); } }}void usage(char *argv0){ fprintf(stderr, "Usage: %s [-c count] [-d] [-g goodness] -h hostname [-i interval]\n" "\t[-l] [-p port] [-r] [-s] \n", argv0);}int main(int argc, char *argv[]) { int usd; /* socket */ int c; /* These parameters are settable from the command line the initializations here provide default behavior */ short int udp_local_port=0; /* default of 0 means kernel chooses */ int cycle_time=600; /* seconds */ int probe_count=0; /* default of 0 means loop forever */ /* int debug=0; is a global above */ int goodness=0; char *hostname=NULL; /* must be set */ int replay=0; /* replay mode overrides everything */ for (;;) { c = getopt( argc, argv, "c:" DEBUG_OPTION "g:h:i:lp:rs"); if (c == EOF) break; switch (c) { case 'c': probe_count = atoi(optarg); break;#ifdef ENABLE_DEBUG case 'd': ++debug; break;#endif case 'g': goodness = atoi(optarg); break; case 'h': hostname = optarg; break; case 'i': cycle_time = atoi(optarg); break; case 'l': live++; break; case 'p': udp_local_port = atoi(optarg); break; case 'r': replay++; break; case 's': set_clock++; break; default: usage(argv[0]); exit(1); } } if (replay) { do_replay(); exit(0); } if (hostname == NULL) { usage(argv[0]); exit(1); } if (debug) { printf("Configuration:\n" " -c probe_count %d\n" " -d (debug) %d\n" " -g goodness %d\n" " -h hostname %s\n" " -i interval %d\n" " -l live %d\n" " -p local_port %d\n" " -s set_clock %d\n", probe_count, debug, goodness, hostname, cycle_time, live, udp_local_port, set_clock ); } /* Startup sequence */ if ((usd=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==-1) {perror ("socket");exit(1);} setup_receive(usd, INADDR_ANY, udp_local_port); setup_transmit(usd, hostname, NTP_PORT); primary_loop(usd, probe_count, cycle_time, goodness); close(usd); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -