📄 ntpdate.c
字号:
*/ for(nbsock = 0; (nbsock < MAX_AF) && res ; res = res->ai_next) { /* create a datagram (UDP) socket */ fd[nbsock] = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (fd[nbsock] == SOCKET_ERROR) {#ifndef SYS_WINNT if (errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT || errno == EPFNOSUPPORT)#else int err = WSAGetLastError(); if (err == WSAEPROTONOSUPPORT || err == WSAEAFNOSUPPORT || err == WSAEPFNOSUPPORT)#endif continue; netsyslog(LOG_ERR, "socket() failed: %m"); exit(1); /*NOTREACHED*/ } /* set socket to reuse address */ if (setsockopt(fd[nbsock], SOL_SOCKET, SO_REUSEADDR, (void*) &optval, sizeof(optval)) < 0) { netsyslog(LOG_ERR, "setsockopt() SO_REUSEADDR failed: %m"); exit(1); /*NOTREACHED*/ }#ifdef IPV6_V6ONLY /* Restricts AF_INET6 socket to IPv6 communications (see RFC 2553bis-03) */ if (res->ai_family == AF_INET6) if (setsockopt(fd[nbsock], IPPROTO_IPV6, IPV6_V6ONLY, (void*) &optval, sizeof(optval)) < 0) { netsyslog(LOG_ERR, "setsockopt() IPV6_V6ONLY failed: %m"); exit(1); /*NOTREACHED*/ }#endif /* Remember the socket family in fd_family structure */ fd_family[nbsock] = res->ai_family; /* * bind the socket to the NTP port */ if (!debug && !simple_query && !unpriv_port) { if (bind(fd[nbsock], res->ai_addr, SOCKLEN(res->ai_addr)) < 0) {#ifndef SYS_WINNT if (errno == EADDRINUSE)#else if (WSAGetLastError() == WSAEADDRINUSE)#endif /* SYS_WINNT */ netsyslog(LOG_ERR, "the NTP socket is in use, exiting"); else netsyslog(LOG_ERR, "bind() fails: %m"); exit(1); } }#ifdef HAVE_POLL_H fdmask[nbsock].fd = fd[nbsock]; fdmask[nbsock].events = POLLIN;#else FD_SET(fd[nbsock], &fdmask); if (maxfd < fd[nbsock]+1) { maxfd = fd[nbsock]+1; }#endif /* * set non-blocking, */#ifndef SYS_WINNT# ifdef SYS_VXWORKS { int on = TRUE; if (ioctl(fd[nbsock],FIONBIO, &on) == ERROR) { netsyslog(LOG_ERR, "ioctl(FIONBIO) fails: %m"); exit(1); } }# else /* not SYS_VXWORKS */# if defined(O_NONBLOCK) if (fcntl(fd[nbsock], F_SETFL, O_NONBLOCK) < 0) { netsyslog(LOG_ERR, "fcntl(FNDELAY|FASYNC) fails: %m"); exit(1); /*NOTREACHED*/ }# else /* not O_NONBLOCK */# if defined(FNDELAY) if (fcntl(fd[nbsock], F_SETFL, FNDELAY) < 0) { netsyslog(LOG_ERR, "fcntl(FNDELAY|FASYNC) fails: %m"); exit(1); /*NOTREACHED*/ }# else /* FNDELAY */# include "Bletch: Need non blocking I/O"# endif /* FNDELAY */# endif /* not O_NONBLOCK */# endif /* SYS_VXWORKS */#else /* SYS_WINNT */ if (ioctlsocket(fd[nbsock], FIONBIO, (u_long *) &on) == SOCKET_ERROR) { netsyslog(LOG_ERR, "ioctlsocket(FIONBIO) fails: %m"); exit(1); }#endif /* SYS_WINNT */ nbsock++; } freeaddrinfo(ressave);}/* * sendpkt - send a packet to the specified destination */static voidsendpkt( struct sockaddr_storage *dest, struct pkt *pkt, int len ){ int i; int cc; SOCKET sock = INVALID_SOCKET;#ifdef SYS_WINNT DWORD err;#endif /* SYS_WINNT */ /* Find a local family compatible socket to send ntp packet to ntp server */ for(i = 0; (i < MAX_AF); i++) { if(dest->ss_family == fd_family[i]) { sock = fd[i]; break; } } if ( sock == INVALID_SOCKET ) { netsyslog(LOG_ERR, "cannot find family compatible socket to send ntp packet"); exit(1); /*NOTREACHED*/ } cc = sendto(sock, (char *)pkt, len, 0, (struct sockaddr *)dest, SOCKLEN(dest)); if (cc == SOCKET_ERROR) {#ifndef SYS_WINNT if (errno != EWOULDBLOCK && errno != ENOBUFS)#else err = WSAGetLastError(); if (err != WSAEWOULDBLOCK && err != WSAENOBUFS)#endif /* SYS_WINNT */ netsyslog(LOG_ERR, "sendto(%s): %m", stohost(dest)); }}/* * input_handler - receive packets asynchronously */voidinput_handler(void){ register int n; register struct recvbuf *rb; struct timeval tvzero; int fromlen; l_fp ts; SOCKET i;#ifdef HAVE_POLL_H struct pollfd fds[MAX_AF];#else fd_set fds;#endif int fdc = 0; /* * Do a poll to see if we have data */ for (;;) { tvzero.tv_sec = tvzero.tv_usec = 0;#ifdef HAVE_POLL_H memcpy(fds, fdmask, sizeof(fdmask)); n = poll(fds, (unsigned int)nbsock, tvzero.tv_sec * 1000); /* * Determine which socket received data */ for(i=0; i < nbsock; i++) { if(fds[i].revents & POLLIN) { fdc = fd[i]; break; } }#else fds = fdmask; n = select(maxfd, &fds, (fd_set *)0, (fd_set *)0, &tvzero); /* * Determine which socket received data */ for(i=0; i < maxfd; i++) { if(FD_ISSET(fd[i], &fds)) { fdc = fd[i]; break; } }#endif /* * If nothing to do, just return. If an error occurred, * complain and return. If we've got some, freeze a * timestamp. */ if (n == 0) return; else if (n == -1) { if (errno != EINTR) netsyslog(LOG_ERR,#ifdef HAVE_POLL_H "poll() error: %m"#else "select() error: %m"#endif ); return; } get_systime(&ts); /* * Get a buffer and read the frame. If we * haven't got a buffer, or this is received * on the wild card socket, just dump the packet. */ if (initializing || free_recvbuffs() == 0) { char buf[100];#ifndef SYS_WINNT (void) read(fdc, buf, sizeof buf);#else /* NT's _read does not operate on nonblocking sockets * either recvfrom or ReadFile() has to be used here. * ReadFile is used in [ntpd]ntp_intres() and ntpdc, * just to be different use recvfrom() here */ recvfrom(fdc, buf, sizeof(buf), 0, (struct sockaddr *)0, NULL);#endif /* SYS_WINNT */ continue; } rb = get_free_recv_buffer(); fromlen = sizeof(struct sockaddr_storage); rb->recv_length = recvfrom(fdc, (char *)&rb->recv_pkt, sizeof(rb->recv_pkt), 0, (struct sockaddr *)&rb->recv_srcadr, &fromlen); if (rb->recv_length == -1) { freerecvbuf(rb); continue; } /* * Got one. Mark how and when it got here, * put it on the full list. */ rb->recv_time = ts; add_full_recv_buffer(rb); }}#if !defined SYS_WINNT && !defined SYS_CYGWIN32/* * adj_systime - do a big long slew of the system time */static intl_adj_systime( l_fp *ts ){ struct timeval adjtv, oadjtv; int isneg = 0; l_fp offset;#ifndef STEP_SLEW l_fp overshoot;#endif /* * Take the absolute value of the offset */ offset = *ts; if (L_ISNEG(&offset)) { isneg = 1; L_NEG(&offset); }#ifndef STEP_SLEW /* * Calculate the overshoot. XXX N.B. This code *knows* * ADJ_OVERSHOOT is 1/2. */ overshoot = offset; L_RSHIFTU(&overshoot); if (overshoot.l_ui != 0 || (overshoot.l_uf > ADJ_MAXOVERSHOOT)) { overshoot.l_ui = 0; overshoot.l_uf = ADJ_MAXOVERSHOOT; } L_ADD(&offset, &overshoot);#endif TSTOTV(&offset, &adjtv); if (isneg) { adjtv.tv_sec = -adjtv.tv_sec; adjtv.tv_usec = -adjtv.tv_usec; } if (adjtv.tv_usec != 0 && !debug) { if (adjtime(&adjtv, &oadjtv) < 0) { msyslog(LOG_ERR, "Can't adjust the time of day: %m"); return 0; } } return 1;}#endif /* SYS_WINNT *//* * This fuction is not the same as lib/systime step_systime!!! */static intl_step_systime( l_fp *ts ){ double dtemp;#ifdef SLEWALWAYS#ifdef STEP_SLEW l_fp ftmp; int isneg; int n; if (debug) return 1; /* * Take the absolute value of the offset */ ftmp = *ts; if (L_ISNEG(&ftmp)) { L_NEG(&ftmp); isneg = 1; } else isneg = 0; if (ftmp.l_ui >= 3) { /* Step it and slew - we might win */ LFPTOD(ts, dtemp); n = step_systime(dtemp); if (!n) return n; if (isneg) ts->l_ui = ~0; else ts->l_ui = ~0; } /* * Just add adjustment into the current offset. The update * routine will take care of bringing the system clock into * line. */#endif if (debug) return 1;#ifdef FORCE_NTPDATE_STEP LFPTOD(ts, dtemp); return step_systime(dtemp);#else l_adj_systime(ts); return 1;#endif#else /* SLEWALWAYS */ if (debug) return 1; LFPTOD(ts, dtemp); return step_systime(dtemp);#endif /* SLEWALWAYS */}/* XXX ELIMINATE printserver similar in ntptrace.c, ntpdate.c *//* * printserver - print detail information for a server */static voidprintserver( register struct server *pp, FILE *fp ){ register int i; char junk[5]; char *str; if (!debug) { (void) fprintf(fp, "server %s, stratum %d, offset %s, delay %s\n", stoa(&pp->srcadr), pp->stratum, lfptoa(&pp->offset, 6), fptoa((s_fp)pp->delay, 5)); return; } (void) fprintf(fp, "server %s, port %d\n", stoa(&pp->srcadr), ntohs(((struct sockaddr_in*)&(pp->srcadr))->sin_port)); (void) fprintf(fp, "stratum %d, precision %d, leap %c%c, trust %03o\n", pp->stratum, pp->precision, pp->leap & 0x2 ? '1' : '0', pp->leap & 0x1 ? '1' : '0', pp->trust); if (pp->stratum == 1) { junk[4] = 0; memmove(junk, (char *)&pp->refid, 4); str = junk; } else { str = stoa(&pp->srcadr); } (void) fprintf(fp, "refid [%s], delay %s, dispersion %s\n", str, fptoa((s_fp)pp->delay, 5), ufptoa(pp->dispersion, 5)); (void) fprintf(fp, "transmitted %d, in filter %d\n", pp->xmtcnt, pp->filter_nextpt); (void) fprintf(fp, "reference time: %s\n", prettydate(&pp->reftime)); (void) fprintf(fp, "originate timestamp: %s\n", prettydate(&pp->org)); (void) fprintf(fp, "transmit timestamp: %s\n", prettydate(&pp->xmt)); (void) fprintf(fp, "filter delay: "); for (i = 0; i < NTP_SHIFT; i++) { (void) fprintf(fp, " %-8.8s", fptoa(pp->filter_delay[i], 5)); if (i == (NTP_SHIFT>>1)-1) (void) fprintf(fp, "\n "); } (void) fprintf(fp, "\n"); (void) fprintf(fp, "filter offset:"); for (i = 0; i < PEER_SHIFT; i++) { (void) fprintf(fp, " %-8.8s", lfptoa(&pp->filter_offset[i], 6)); if (i == (PEER_SHIFT>>1)-1) (void) fprintf(fp, "\n "); } (void) fprintf(fp, "\n"); (void) fprintf(fp, "delay %s, dispersion %s\n", fptoa((s_fp)pp->delay, 5), ufptoa(pp->dispersion, 5)); (void) fprintf(fp, "offset %s\n\n", lfptoa(&pp->offset, 6));}#if !defined(HAVE_VSPRINTF)intvsprintf( char *str, const char *fmt, va_list ap ){ FILE f; int len; f._flag = _IOWRT+_IOSTRG; f._ptr = str; f._cnt = 32767; len = _doprnt(fmt, ap, &f); *f._ptr = 0; return (len);}#endif#if 0/* override function in library since SA_RESTART makes ALL syscalls restart */#ifdef SA_RESTARTvoidsignal_no_reset( int sig, void (*func)() ){ int n; struct sigaction vec; vec.sa_handler = func; sigemptyset(&vec.sa_mask); vec.sa_flags = 0; while (1) { n = sigaction(sig, &vec, NULL); if (n == -1 && errno == EINTR) continue; break; } if (n == -1) { perror("sigaction"); exit(1); }}#endif#endif#ifdef HAVE_NETINFOstatic ni_namelist *getnetinfoservers(void){ ni_status status; void *domain; ni_id confdir; ni_namelist *namelist = (ni_namelist*)malloc(sizeof(ni_namelist)); /* Find a time server in NetInfo */ if ((status = ni_open(NULL, ".", &domain)) != NI_OK) return NULL; while (status = ni_pathsearch(domain, &confdir, NETINFO_CONFIG_DIR) == NI_NODIR) { void *next_domain; if (ni_open(domain, "..", &next_domain) != NI_OK) break; ni_free(domain); domain = next_domain; } if (status != NI_OK) return NULL; NI_INIT(namelist); if (ni_lookupprop(domain, &confdir, "server", namelist) != NI_OK) { ni_namelist_free(namelist); free(namelist); return NULL; } return(namelist);}#endif#ifdef SYS_WINNTisc_boolean_t ntp_port_inuse(int af, u_short port){ /* * Check if NTP socket is already in use on this system * This is only for Windows Systems, as they tend not to fail on the real bind() below */ SOCKET checksocket; struct sockaddr_in checkservice; checksocket = socket(af, SOCK_DGRAM, 0); if (checksocket == INVALID_SOCKET) { return (ISC_TRUE); } checkservice.sin_family = (short) AF_INET; checkservice.sin_addr.s_addr = INADDR_LOOPBACK; checkservice.sin_port = htons(port); if (bind(checksocket, (struct sockaddr *)&checkservice, sizeof(checkservice)) == SOCKET_ERROR) { if ( WSAGetLastError() == WSAEADDRINUSE ){ closesocket(checksocket); return (ISC_TRUE); } } closesocket(checksocket); return (ISC_FALSE);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -