summaryrefslogtreecommitdiffstats
path: root/contrib/ntp/ntpd/ntp_resolver.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ntp/ntpd/ntp_resolver.c')
-rw-r--r--contrib/ntp/ntpd/ntp_resolver.c987
1 files changed, 0 insertions, 987 deletions
diff --git a/contrib/ntp/ntpd/ntp_resolver.c b/contrib/ntp/ntpd/ntp_resolver.c
deleted file mode 100644
index 84b2583..0000000
--- 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 <config.h>
-#endif
-
-#include "ntpd.h"
-#include "ntp_io.h"
-#include "ntp_request.h"
-#include "ntp_stdlib.h"
-#include "ntp_syslog.h"
-
-#include <stdio.h>
-#include <ctype.h>
-#include <netdb.h>
-#include <signal.h>
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#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;
- }
- }
-}
OpenPOWER on IntegriCloud