diff --git a/contrib/ntp/ntpd/ntp_control.c b/contrib/ntp/ntpd/ntp_control.c index a44c8be7d992..af667b5eda3c 100644 --- a/contrib/ntp/ntpd/ntp_control.c +++ b/contrib/ntp/ntpd/ntp_control.c @@ -400,6 +400,9 @@ static u_char clocktypes[] = { CTL_SST_TS_LF, /* REFCLK_FG (37) */ CTL_SST_TS_UHF, /* REFCLK_HOPF_SERIAL (38) */ CTL_SST_TS_UHF, /* REFCLK_HOPF_PCI (39) */ + CTL_SST_TS_LF, /* REFCLK_JJY (40) */ + CTL_SST_TS_UHF, /* REFCLK_TT560 (41) */ + CTL_SST_TS_UHF, /* REFCLK_ZYFER (42) */ }; diff --git a/contrib/ntp/ntpd/ntp_proto.c b/contrib/ntp/ntpd/ntp_proto.c index 2374afa9c053..da47e0fb9e28 100644 --- a/contrib/ntp/ntpd/ntp_proto.c +++ b/contrib/ntp/ntpd/ntp_proto.c @@ -311,11 +311,7 @@ receive( #endif if (restrict_mask & RES_IGNORE) return; /* no anything */ - if (!(SRCPORT(&rbufp->recv_srcadr) == NTP_PORT || - SRCPORT(&rbufp->recv_srcadr) >= IPPORT_RESERVED)) { - sys_badlength++; - return; /* invalid port */ - } + pkt = &rbufp->recv_pkt; if (PKT_VERSION(pkt->li_vn_mode) == NTP_VERSION) { sys_newversionpkt++; /* new version */ @@ -2508,7 +2504,8 @@ int default_get_precision(void) { struct timeval tp; -#if !defined(SYS_WINNT) && !defined(VMS) && !defined(_SEQUENT_) +#if !defined(SYS_WINNT) && !defined(VMS) && !defined(_SEQUENT_) && \ + !defined(MPE) struct timezone tzp; #elif defined(VMS) || defined(_SEQUENT_) struct timezone { diff --git a/contrib/ntp/ntpd/ntp_resolver.c b/contrib/ntp/ntpd/ntp_resolver.c deleted file mode 100644 index 84b25838e481..000000000000 --- a/contrib/ntp/ntpd/ntp_resolver.c +++ /dev/null @@ -1,987 +0,0 @@ -/* -** Ancestor was ripped off from ../ntpres/ntpres.c by Greg Troxel 4/2/92 -** -** The previous resolver only needed to do forward lookups, and all names -** were known before we started the resolver process. -** -** The new code must be able to handle reverse lookups, and the requests can -** show up at any time. -** -** Here's the drill for the new logic. -** -** We want to be able to do forward or reverse lookups. Forward lookups -** require one set of information to be sent back to the daemon, reverse -** lookups require a different set of information. The caller knows this. -** -** The daemon must not block. This includes communicating with the resolver -** process (if the resolver process is a separate task). -** -** Current resolver code blocks waiting for the response, so the -** alternatives are: -** -** - Find a nonblocking resolver library -** - Do each (initial) lookup in a separate process -** - - subsequent lookups *could* be handled by a different process that has -** a queue of pending requests -** -** We could use nonblocking lookups in a separate process (just to help out -** with timers). -** -** If we don't have nonblocking resolver calls we have more opportunities -** for denial-of-service problems. -** -** - too many fork()s -** - communications path -** -*/ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "ntpd.h" -#include "ntp_io.h" -#include "ntp_request.h" -#include "ntp_stdlib.h" -#include "ntp_syslog.h" - -#include -#include -#include -#include - -#include -#include - -#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) - -/* - * Each item we are to resolve and configure gets one of these - * structures defined for it. - */ -struct dns_entry { - int de_done; -#define DE_NAME 001 -#define DE_ADDR 002 -#define DE_NA (DE_NAME | DE_ADDR) -#define DE_PENDING 000 -#define DE_GOT 010 -#define DE_FAIL 020 -#define DE_RESULT (DE_PENDING | DE_GOT | DE_FAIL) - struct dns_entry *de_next; - struct info_dns_assoc de_info; /* DNS info for peer */ -}; -#define de_associd de_info.associd -#define de_peeraddr de_info.peeraddr -#define de_hostname de_info.hostname - -/* - * dns_entries is a pointer to the list of configuration entries - * we have left to do. - */ -static struct dns_entry *dns_entries = NULL; - -/* - * We take an interrupt every thirty seconds, at which time we decrement - * config_timer and resolve_timer. The former is set to 2, so we retry - * unsucessful reconfigurations every minute. The latter is set to - * an exponentially increasing value which starts at 2 and increases to - * 32. When this expires we retry failed name resolutions. - * - * We sleep SLEEPTIME seconds before doing anything, to give the server - * time to arrange itself. - */ -#define MINRESOLVE 2 -#define MAXRESOLVE 32 -#define CONFIG_TIME 2 -#define ALARM_TIME 30 - -#define SLEEPTIME 2 - -static volatile int config_timer = 0; -static volatile int resolve_timer = 0; - -static int resolve_value; /* next value of resolve timer */ - -/* - * Big hack attack - */ -#define LOCALHOST 0x7f000001 /* 127.0.0.1, in hex, of course */ -#define SKEWTIME 0x08000000 /* 0.03125 seconds as a l_fp fraction */ - -/* - * Select time out. Set to 2 seconds. The server is on the local machine, - * after all. - */ -#define TIMEOUT_SEC 2 -#define TIMEOUT_USEC 0 - -/* - * File descriptor for ntp request code. - */ -static int sockfd = -1; - -/* - * Pipe descriptors - */ -int p_fd[2] = { -1, -1 }; - -/* stuff to be filled in by caller */ - -extern keyid_t req_keyid; /* request keyid */ - -/* end stuff to be filled in */ - -void ntp_res P((void)); -static RETSIGTYPE bong P((int)); -static void checkparent P((void)); -static void removeentry P((struct dns_entry *)); -static void addentry P((char *, u_int32, u_short)); -static void findhostaddr P((struct dns_entry *)); -static void openntp P((void)); -static int tell_ntpd P((struct info_dns_assoc *)); -static void doconfigure P((int)); - -struct ntp_res_t_pkt { /* Tagged packet: */ - void *tag; /* For the caller */ - u_int32 paddr; /* IP to look up, or 0 */ - char name[NTP_MAXHOSTNAME]; /* Name to look up (if 1st byte is not 0) */ -}; - -struct ntp_res_c_pkt { /* Control packet: */ - char name[NTP_MAXHOSTNAME]; - u_int32 paddr; - int mode; - int version; - int minpoll; - int maxpoll; - int flags; - int ttl; - keyid_t keyid; - u_char keystr[MAXFILENAME]; -}; - -/* - * ntp_res_name - */ - -void -ntp_res_name( - u_int32 paddr, /* Address to resolve */ - u_short associd /* Association ID */ - ) -{ - pid_t pid; - - /* - * fork. - * - parent returns - * - child stuffs data and calls ntp_res() - */ - - for (pid = -1; pid == -1;) { -#ifdef RES_TEST - pid = 0; -#else - pid = fork(); -#endif - if (pid == -1) { - msyslog(LOG_ERR, "ntp_res_name: fork() failed: %m"); - sleep(2); - } - } - switch (pid) { - case -1: /* Error */ - msyslog(LOG_INFO, "ntp_res_name: error..."); - /* Can't happen */ - break; - - case 0: /* Child */ - closelog(); - kill_asyncio(); - (void) signal_no_reset(SIGCHLD, SIG_DFL); -#ifndef LOG_DAEMON - openlog("ntp_res", LOG_PID); -# else /* LOG_DAEMON */ -# ifndef LOG_NTP -# define LOG_NTP LOG_DAEMON -# endif - openlog("ntp_res_name", LOG_PID | LOG_NDELAY, LOG_NTP); -#endif - - addentry(NULL, paddr, associd); - ntp_res(); - break; - - default: /* Parent */ - /* Nothing to do. (In Real Life, this never happens.) */ - return; - } -} - -/* - * ntp_res needs; - * - * req_key(???), req_keyid valid - * syslog still open - */ - -void -ntp_res(void) -{ -#ifdef HAVE_SIGSUSPEND - sigset_t set; - - sigemptyset(&set); -#endif /* HAVE_SIGSUSPEND */ - -#ifdef DEBUG - if (debug) { - msyslog(LOG_INFO, "NTP_RESOLVER running"); - } -#endif - - /* check out auth stuff */ - if (sys_authenticate) { - if (!authistrusted(req_keyid)) { - msyslog(LOG_ERR, "invalid request keyid %08x", - req_keyid ); - exit(1); - } - } - - /* - * Make a first cut at resolving the bunch - */ - doconfigure(1); - if (dns_entries == NULL) { - if (debug) { - msyslog(LOG_INFO, "NTP_RESOLVER done!"); - } -#if defined SYS_WINNT - ExitThread(0); /* Don't want to kill whole NT process */ -#else - exit(0); /* done that quick */ -#endif - } - - /* - * Here we've got some problem children. Set up the timer - * and wait for it. - */ - resolve_value = resolve_timer = MINRESOLVE; - config_timer = CONFIG_TIME; -#ifndef SYS_WINNT - (void) signal_no_reset(SIGALRM, bong); - alarm(ALARM_TIME); -#endif /* SYS_WINNT */ - - for (;;) { - if (dns_entries == NULL) - exit(0); - - checkparent(); - - if (resolve_timer == 0) { - if (resolve_value < MAXRESOLVE) - resolve_value <<= 1; - resolve_timer = resolve_value; -#ifdef DEBUG - msyslog(LOG_INFO, "resolve_timer: 0->%d", resolve_timer); -#endif - config_timer = CONFIG_TIME; - doconfigure(1); - continue; - } else if (config_timer == 0) { - config_timer = CONFIG_TIME; -#ifdef DEBUG - msyslog(LOG_INFO, "config_timer: 0->%d", config_timer); -#endif - doconfigure(0); - continue; - } -#ifndef SYS_WINNT - /* - * There is a race in here. Is okay, though, since - * all it does is delay things by 30 seconds. - */ -# ifdef HAVE_SIGSUSPEND - sigsuspend(&set); -# else - sigpause(0); -# endif /* HAVE_SIGSUSPEND */ -#else - if (config_timer > 0) - config_timer--; - if (resolve_timer > 0) - resolve_timer--; - sleep(ALARM_TIME); -#endif /* SYS_WINNT */ - } -} - - -#ifndef SYS_WINNT -/* - * bong - service and reschedule an alarm() interrupt - */ -static RETSIGTYPE -bong( - int sig - ) -{ - if (config_timer > 0) - config_timer--; - if (resolve_timer > 0) - resolve_timer--; - alarm(ALARM_TIME); -} -#endif /* SYS_WINNT */ - -/* - * checkparent - see if our parent process is still running - * - * No need to worry in the Windows NT environment whether the - * main thread is still running, because if it goes - * down it takes the whole process down with it (in - * which case we won't be running this thread either) - * Turn function into NOP; - */ - -static void -checkparent(void) -{ -#if !defined (SYS_WINNT) && !defined (SYS_VXWORKS) - - /* - * If our parent (the server) has died we will have been - * inherited by init. If so, exit. - */ - if (getppid() == 1) { - msyslog(LOG_INFO, "parent died before we finished, exiting"); - exit(0); - } -#endif /* SYS_WINNT && SYS_VXWORKS*/ -} - - -/* - * removeentry - we are done with an entry, remove it from the list - */ -static void -removeentry( - struct dns_entry *entry - ) -{ - register struct dns_entry *de; - - de = dns_entries; - if (de == entry) { - dns_entries = de->de_next; - return; - } - - while (de != NULL) { - if (de->de_next == entry) { - de->de_next = entry->de_next; - return; - } - de = de->de_next; - } -} - - -/* - * addentry - add an entry to the configuration list - */ -static void -addentry( - char *name, - u_int32 paddr, - u_short associd - ) -{ - register struct dns_entry *de; - -#ifdef DEBUG - if (debug > 1) { - struct in_addr si; - - si.s_addr = paddr; - msyslog(LOG_INFO, - "ntp_res_name: <%s> %s associd %d\n", - (name) ? name : "", inet_ntoa(si), associd); - } -#endif - - de = (struct dns_entry *)emalloc(sizeof(struct dns_entry)); - if (name) { - strncpy(de->de_hostname, name, sizeof de->de_hostname); - de->de_done = DE_PENDING | DE_ADDR; - } else { - de->de_hostname[0] = 0; - de->de_done = DE_PENDING | DE_NAME; - } - de->de_peeraddr = paddr; - de->de_associd = associd; - de->de_next = NULL; - - if (dns_entries == NULL) { - dns_entries = de; - } else { - register struct dns_entry *dep; - - for (dep = dns_entries; dep->de_next != NULL; - dep = dep->de_next) - /* nothing */; - dep->de_next = de; - } -} - - -/* - * findhostaddr - resolve a host name into an address (Or vice-versa) - * - * sets entry->de_done appropriately when we're finished. We're finished if - * we either successfully look up the missing name or address, or if we get a - * "permanent" failure on the lookup. - * - */ -static void -findhostaddr( - struct dns_entry *entry - ) -{ - struct hostent *hp; - - checkparent(); /* make sure our guy is still running */ - - /* - * The following should never trip - this subroutine isn't - * called if hostname and peeraddr are "filled". - */ - if (entry->de_hostname[0] && entry->de_peeraddr) { - struct in_addr si; - - si.s_addr = entry->de_peeraddr; - msyslog(LOG_ERR, "findhostaddr: both de_hostname and de_peeraddr are defined: <%s>/%s: state %#x", - &entry->de_hostname[0], inet_ntoa(si), entry->de_done); - return; - } - - /* - * The following should never trip. - */ - if (!entry->de_hostname[0] && !entry->de_peeraddr) { - msyslog(LOG_ERR, "findhostaddr: both de_hostname and de_peeraddr are undefined!"); - entry->de_done |= DE_FAIL; - return; - } - - if (entry->de_hostname[0]) { -#ifdef DEBUG - if (debug > 2) - msyslog(LOG_INFO, "findhostaddr: Resolving <%s>", - &entry->de_hostname[0]); -#endif /* DEBUG */ - hp = gethostbyname(&entry->de_hostname[0]); - } else { -#ifdef DEBUG - if (debug > 2) { - struct in_addr si; - - si.s_addr = entry->de_peeraddr; - msyslog(LOG_INFO, "findhostaddr: Resolving %s", - inet_ntoa(si)); - } -#endif - hp = gethostbyaddr((const char *)&entry->de_peeraddr, - sizeof entry->de_peeraddr, - AF_INET); - } - - if (hp == NULL) { - /* - * Bail if we should TRY_AGAIN. - * Otherwise, we have a permanent failure. - */ - if (h_errno == TRY_AGAIN) - return; - entry->de_done |= DE_FAIL; - } else { - entry->de_done |= DE_GOT; - } - - if (entry->de_done & DE_GOT) { - switch (entry->de_done & DE_NA) { - case DE_NAME: -#ifdef DEBUG - if (debug > 2) - msyslog(LOG_INFO, - "findhostaddr: name resolved."); -#endif - /* - * Use the first address. We don't have any way to - * tell preferences and older gethostbyname() - * implementations only return one. - */ - memmove((char *)&(entry->de_peeraddr), - (char *)hp->h_addr, - sizeof(struct in_addr)); - break; - case DE_ADDR: -#ifdef DEBUG - if (debug > 2) - msyslog(LOG_INFO, - "findhostaddr: address resolved."); -#endif - strncpy(&entry->de_hostname[0], hp->h_name, - sizeof entry->de_hostname); - break; - default: - msyslog(LOG_ERR, "findhostaddr: Bogus de_done: %#x", - entry->de_done); - break; - } - } else { -#ifdef DEBUG - if (debug > 2) { - struct in_addr si; - const char *hes; -#ifndef HAVE_HSTRERROR - char hnum[20]; - - switch (h_errno) { - case HOST_NOT_FOUND: - hes = "Authoritive Answer Host not found"; - break; - case TRY_AGAIN: - hes = "Non-Authoritative Host not found, or SERVERFAIL"; - break; - case NO_RECOVERY: - hes = "Non recoverable errors, FORMERR, REFUSED, NOTIMP"; - break; - case NO_DATA: - hes = "Valid name, no data record of requested type"; - break; - default: - snprintf(hnum, sizeof hnum, "%d", h_errno); - hes = hnum; - break; - } -#else - hes = hstrerror(h_errno); -#endif - - si.s_addr = entry->de_peeraddr; - msyslog(LOG_INFO, - "findhostaddr: Failed resolution on <%s>/%s: %s", - entry->de_hostname, inet_ntoa(si), hes); - } -#endif - /* Send a NAK message back to the daemon */ - } - return; -} - - -/* - * openntp - open a socket to the ntp server - */ -static void -openntp(void) -{ - struct sockaddr_in saddr; - - if (sockfd >= 0) - return; - - sockfd = socket(AF_INET, SOCK_DGRAM, 0); - if (sockfd == -1) { - msyslog(LOG_ERR, "socket() failed: %m"); - exit(1); - } - - memset((char *)&saddr, 0, sizeof(saddr)); - saddr.sin_family = AF_INET; - saddr.sin_port = htons(NTP_PORT); /* trash */ - saddr.sin_addr.s_addr = htonl(LOCALHOST); /* garbage */ - - /* - * Make the socket non-blocking. We'll wait with select() - */ -#ifndef SYS_WINNT -# if defined(O_NONBLOCK) - if (fcntl(sockfd, F_SETFL, O_NONBLOCK) == -1) { - msyslog(LOG_ERR, "fcntl(O_NONBLOCK) failed: %m"); - exit(1); - } -# else -# if defined(FNDELAY) - if (fcntl(sockfd, F_SETFL, FNDELAY) == -1) { - msyslog(LOG_ERR, "fcntl(FNDELAY) failed: %m"); - exit(1); - } -# else -# include "Bletch: NEED NON BLOCKING IO" -# endif /* FNDDELAY */ -# endif /* O_NONBLOCK */ -#else /* SYS_WINNT */ - { - int on = 1; - - if (ioctlsocket(sockfd,FIONBIO,(u_long *) &on) == SOCKET_ERROR) { - msyslog(LOG_ERR, "ioctlsocket(FIONBIO) fails: %m"); - exit(1); /* Windows NT - set socket in non-blocking mode */ - } - } -#endif /* SYS_WINNT */ - - if (connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) == -1) { - msyslog(LOG_ERR, "openntp: connect() failed: %m"); - exit(1); - } -} - - -/* - * tell_ntpd: Tell ntpd what we discovered. - */ -static int -tell_ntpd( - struct info_dns_assoc *conf - ) -{ - fd_set fdset; - struct timeval tvout; - struct req_pkt reqpkt; - l_fp ts; - int n; -#ifdef SYS_WINNT - HANDLE hReadWriteEvent = NULL; - BOOL ret; - DWORD NumberOfBytesWritten, NumberOfBytesRead, dwWait; - OVERLAPPED overlap; -#endif /* SYS_WINNT */ - - checkparent(); /* make sure our guy is still running */ - - if (sockfd < 0) - openntp(); - -#ifdef SYS_WINNT - hReadWriteEvent = CreateEvent(NULL, FALSE, FALSE, NULL); -#endif /* SYS_WINNT */ - - /* - * Try to clear out any previously received traffic so it - * doesn't fool us. Note the socket is nonblocking. - */ - tvout.tv_sec = 0; - tvout.tv_usec = 0; - FD_ZERO(&fdset); - FD_SET(sockfd, &fdset); - while (select(sockfd + 1, &fdset, (fd_set *)0, (fd_set *)0, &tvout) > - 0) { - recv(sockfd, (char *)&reqpkt, REQ_LEN_MAC, 0); - FD_ZERO(&fdset); - FD_SET(sockfd, &fdset); - } - - /* - * Make up a request packet with the configuration info - */ - memset((char *)&reqpkt, 0, sizeof(reqpkt)); - - reqpkt.rm_vn_mode = RM_VN_MODE(0, 0, 0); - reqpkt.auth_seq = AUTH_SEQ(1, 0); /* authenticated, no seq */ - reqpkt.implementation = IMPL_XNTPD; /* local implementation */ - reqpkt.request = REQ_HOSTNAME_ASSOCID; /* Hostname for associd */ - reqpkt.err_nitems = ERR_NITEMS(0, 1); /* one item */ - reqpkt.mbz_itemsize = MBZ_ITEMSIZE(sizeof(struct info_dns_assoc)); - memmove(reqpkt.data, (char *)conf, sizeof(struct info_dns_assoc)); - reqpkt.keyid = htonl(req_keyid); - - get_systime(&ts); - L_ADDUF(&ts, SKEWTIME); - HTONL_FP(&ts, &reqpkt.tstamp); - n = 0; - if (sys_authenticate) - n = authencrypt(req_keyid, (u_int32 *)&reqpkt, REQ_LEN_NOMAC); - - /* - * Done. Send it. - */ -#ifndef SYS_WINNT - n = send(sockfd, (char *)&reqpkt, (unsigned)(REQ_LEN_NOMAC + n), 0); - if (n < 0) { - msyslog(LOG_ERR, "send to NTP server failed: %m"); - return 0; /* maybe should exit */ - } -#else - /* In the NT world, documentation seems to indicate that there - * exist _write and _read routines that can be used to do blocking - * I/O on sockets. Problem is these routines require a socket - * handle obtained through the _open_osf_handle C run-time API - * of which there is no explanation in the documentation. We need - * nonblocking write's and read's anyway for our purpose here. - * We're therefore forced to deviate a little bit from the Unix - * model here and use the ReadFile and WriteFile Win32 I/O API's - * on the socket - */ - overlap.Offset = overlap.OffsetHigh = (DWORD)0; - overlap.hEvent = hReadWriteEvent; - ret = WriteFile((HANDLE)sockfd, (char *)&reqpkt, REQ_LEN_NOMAC + n, - (LPDWORD)&NumberOfBytesWritten, (LPOVERLAPPED)&overlap); - if ((ret == FALSE) && (GetLastError() != ERROR_IO_PENDING)) { - msyslog(LOG_ERR, "send to NTP server failed: %m"); - return 0; - } - dwWait = WaitForSingleObject(hReadWriteEvent, (DWORD) TIMEOUT_SEC * 1000); - if ((dwWait == WAIT_FAILED) || (dwWait == WAIT_TIMEOUT)) { - if (dwWait == WAIT_FAILED) - msyslog(LOG_ERR, "WaitForSingleObject failed: %m"); - return 0; - } -#endif /* SYS_WINNT */ - - - /* - * Wait for a response. A weakness of the mode 7 protocol used - * is that there is no way to associate a response with a - * particular request, i.e. the response to this configuration - * request is indistinguishable from that to any other. I should - * fix this some day. In any event, the time out is fairly - * pessimistic to make sure that if an answer is coming back - * at all, we get it. - */ - for (;;) { - FD_ZERO(&fdset); - FD_SET(sockfd, &fdset); - tvout.tv_sec = TIMEOUT_SEC; - tvout.tv_usec = TIMEOUT_USEC; - - n = select(sockfd + 1, &fdset, (fd_set *)0, - (fd_set *)0, &tvout); - - if (n < 0) - { - msyslog(LOG_ERR, "select() fails: %m"); - return 0; - } - else if (n == 0) - { - if(debug) - msyslog(LOG_INFO, "select() returned 0."); - return 0; - } - -#ifndef SYS_WINNT - n = recv(sockfd, (char *)&reqpkt, REQ_LEN_MAC, 0); - if (n <= 0) { - if (n < 0) { - msyslog(LOG_ERR, "recv() fails: %m"); - return 0; - } - continue; - } -#else /* Overlapped I/O used on non-blocking sockets on Windows NT */ - ret = ReadFile((HANDLE)sockfd, (char *)&reqpkt, (DWORD)REQ_LEN_MAC, - (LPDWORD)&NumberOfBytesRead, (LPOVERLAPPED)&overlap); - if ((ret == FALSE) && (GetLastError() != ERROR_IO_PENDING)) { - msyslog(LOG_ERR, "ReadFile() fails: %m"); - return 0; - } - dwWait = WaitForSingleObject(hReadWriteEvent, (DWORD) TIMEOUT_SEC * 1000); - if ((dwWait == WAIT_FAILED) || (dwWait == WAIT_TIMEOUT)) { - if (dwWait == WAIT_FAILED) { - msyslog(LOG_ERR, "WaitForSingleObject fails: %m"); - return 0; - } - continue; - } - n = NumberOfBytesRead; -#endif /* SYS_WINNT */ - - /* - * Got one. Check through to make sure it is what - * we expect. - */ - if (n < RESP_HEADER_SIZE) { - msyslog(LOG_ERR, "received runt response (%d octets)", - n); - continue; - } - - if (!ISRESPONSE(reqpkt.rm_vn_mode)) { -#ifdef DEBUG - if (debug > 1) - msyslog(LOG_INFO, "received non-response packet"); -#endif - continue; - } - - if (ISMORE(reqpkt.rm_vn_mode)) { -#ifdef DEBUG - if (debug > 1) - msyslog(LOG_INFO, "received fragmented packet"); -#endif - continue; - } - - if ( ( (INFO_VERSION(reqpkt.rm_vn_mode) < 2) - || (INFO_VERSION(reqpkt.rm_vn_mode) > NTP_VERSION)) - || INFO_MODE(reqpkt.rm_vn_mode) != MODE_PRIVATE) { -#ifdef DEBUG - if (debug > 1) - msyslog(LOG_INFO, - "version (%d/%d) or mode (%d/%d) incorrect", - INFO_VERSION(reqpkt.rm_vn_mode), - NTP_VERSION, - INFO_MODE(reqpkt.rm_vn_mode), - MODE_PRIVATE); -#endif - continue; - } - - if (INFO_SEQ(reqpkt.auth_seq) != 0) { -#ifdef DEBUG - if (debug > 1) - msyslog(LOG_INFO, - "nonzero sequence number (%d)", - INFO_SEQ(reqpkt.auth_seq)); -#endif - continue; - } - - if (reqpkt.implementation != IMPL_XNTPD || - reqpkt.request != REQ_HOSTNAME_ASSOCID) { -#ifdef DEBUG - if (debug > 1) - msyslog(LOG_INFO, - "implementation (%d/%d) or request (%d/%d) incorrect", - reqpkt.implementation, IMPL_XNTPD, - reqpkt.request, REQ_HOSTNAME_ASSOCID); -#endif - continue; - } - - if (INFO_NITEMS(reqpkt.err_nitems) != 0 || - INFO_MBZ(reqpkt.mbz_itemsize) != 0 || - INFO_ITEMSIZE(reqpkt.mbz_itemsize) != 0) { -#ifdef DEBUG - if (debug > 1) - msyslog(LOG_INFO, - "nitems (%d) mbz (%d) or itemsize (%d) nonzero", - INFO_NITEMS(reqpkt.err_nitems), - INFO_MBZ(reqpkt.mbz_itemsize), - INFO_ITEMSIZE(reqpkt.mbz_itemsize)); -#endif - continue; - } - - n = INFO_ERR(reqpkt.err_nitems); - switch (n) { - case INFO_OKAY: - /* success */ - return 1; - - case INFO_ERR_IMPL: - msyslog(LOG_ERR, - "server reports implementation mismatch!!"); - return 0; - - case INFO_ERR_REQ: - msyslog(LOG_ERR, - "server claims configuration request is unknown"); - return 0; - - case INFO_ERR_FMT: - msyslog(LOG_ERR, - "server indicates a format error occurred(!!)"); - return 0; - - case INFO_ERR_NODATA: - msyslog(LOG_ERR, - "server indicates no data available (shouldn't happen)"); - return 0; - - case INFO_ERR_AUTH: - msyslog(LOG_ERR, - "server returns a permission denied error"); - return 0; - - default: - msyslog(LOG_ERR, - "server returns unknown error code %d", n); - return 0; - } - } -} - - -/* - * doconfigure - attempt to resolve names/addresses - */ -static void -doconfigure( - int dores - ) -{ - register struct dns_entry *de; - register struct dns_entry *deremove; - char *done_msg = ""; - - de = dns_entries; - while (de != NULL) { -#ifdef DEBUG - if (debug > 1) { - struct in_addr si; - - si.s_addr = de->de_peeraddr; - msyslog(LOG_INFO, - "doconfigure: name: <%s> peeraddr: %s", - de->de_hostname, inet_ntoa(si)); - } -#endif - if (dores && (de->de_hostname[0] == 0 || de->de_peeraddr == 0)) { - findhostaddr(de); - } - - switch (de->de_done & DE_RESULT) { - case DE_PENDING: - done_msg = ""; - break; - case DE_GOT: - done_msg = "succeeded"; - break; - case DE_FAIL: - done_msg = "failed"; - break; - default: - done_msg = "(error - shouldn't happen)"; - break; - } - if (done_msg[0]) { - /* Send the answer */ - if (tell_ntpd(&de->de_info)) { - struct in_addr si; - - si.s_addr = de->de_peeraddr; -#ifdef DEBUG - if (debug > 1) { - msyslog(LOG_INFO, - "DNS resolution on <%s>/%s %s", - de->de_hostname, inet_ntoa(si), - done_msg); - } -#endif - deremove = de; - de = deremove->de_next; - removeentry(deremove); - } - } else { - de = de->de_next; - } - } -}