/* * addentry - add an entry to the configuration list */ static void addentry( char *name, int no_needed, int type, int mode, int version, int minpoll, int maxpoll, u_int flags, int ttl, keyid_t keyid, char *keystr ) { register struct conf_entry *ce; #ifdef DEBUG if (debug > 1) msyslog(LOG_INFO, "intres: <%s> %d %d %d %d %d %d %x %d %x %s", name, no_needed, type, mode, version, minpoll, maxpoll, flags, ttl, keyid, keystr); #endif ce = emalloc(sizeof(*ce)); ce->ce_name = estrdup(name); ce->ce_peeraddr = 0; #ifdef ISC_PLATFORM_HAVEIPV6 ce->ce_peeraddr6 = in6addr_any; #endif ZERO_SOCK(&ce->peer_store); ce->ce_hmode = (u_char)mode; ce->ce_version = (u_char)version; ce->ce_minpoll = (u_char)minpoll; ce->ce_maxpoll = (u_char)maxpoll; ce->no_needed = no_needed; /* Not used after here. */ /* Start of fixing bug-975 */ ce->type = type; ce->ce_flags = (u_char)flags; ce->ce_ttl = (u_char)ttl; ce->ce_keyid = keyid; strncpy(ce->ce_keystr, keystr, sizeof(ce->ce_keystr) - 1); ce->ce_keystr[sizeof(ce->ce_keystr) - 1] = 0; ce->ce_next = NULL; if (confentries == NULL) { confentries = ce; } else { register struct conf_entry *cep; for (cep = confentries; cep->ce_next != NULL; cep = cep->ce_next) /* nothing */; cep->ce_next = ce; } }
const char * socktohost( const sockaddr_u *sock ) { const char svc[] = "ntp"; char * pbuf; char * pliar; int gni_flags; struct addrinfo hints; struct addrinfo * alist; struct addrinfo * ai; sockaddr_u addr; size_t octets; int a_info; /* reverse the address to purported DNS name */ LIB_GETBUF(pbuf); gni_flags = NI_DGRAM | NI_NAMEREQD; if (getnameinfo(&sock->sa, SOCKLEN(sock), pbuf, LIB_BUFLENGTH, NULL, 0, gni_flags)) return stoa(sock); /* use address */ TRACE(1, ("%s reversed to %s\n", stoa(sock), pbuf)); /* * Resolve the reversed name and make sure the reversed address * is among the results. */ ZERO(hints); hints.ai_family = AF(sock); hints.ai_protocol = IPPROTO_UDP; hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = 0; alist = NULL; a_info = getaddrinfo(pbuf, svc, &hints, &alist); if (a_info == EAI_NONAME #ifdef EAI_NODATA || a_info == EAI_NODATA #endif ) { hints.ai_flags = AI_CANONNAME; #ifdef AI_ADDRCONFIG hints.ai_flags |= AI_ADDRCONFIG; #endif a_info = getaddrinfo(pbuf, svc, &hints, &alist); } #ifdef AI_ADDRCONFIG /* Some older implementations don't like AI_ADDRCONFIG. */ if (a_info == EAI_BADFLAGS) { hints.ai_flags &= ~AI_ADDRCONFIG; a_info = getaddrinfo(pbuf, svc, &hints, &alist); } #endif if (a_info) goto forward_fail; NTP_INSIST(alist != NULL); for (ai = alist; ai != NULL; ai = ai->ai_next) { /* * Make a convenience sockaddr_u copy from ai->ai_addr * because casting from sockaddr * to sockaddr_u * is * risking alignment problems on platforms where * sockaddr_u has stricter alignment than sockaddr, * such as sparc. */ ZERO_SOCK(&addr); octets = min(sizeof(addr), ai->ai_addrlen); memcpy(&addr, ai->ai_addr, octets); if (SOCK_EQ(sock, &addr)) break; } freeaddrinfo(alist); if (ai != NULL) return pbuf; /* forward check passed */ forward_fail: TRACE(1, ("%s forward check lookup fail: %s\n", pbuf, gai_strerror(a_info))); LIB_GETBUF(pliar); snprintf(pliar, LIB_BUFLENGTH, "%s (%s)", stoa(sock), pbuf); return pliar; }
/* * Decode an incoming data buffer and print a line in the peer list */ static int doprintpeers( struct varlist *pvl, int associd, int rstatus, int datalen, const char *data, FILE *fp, int af ) { char *name; char *value = NULL; int i; int c; sockaddr_u srcadr; sockaddr_u dstadr; sockaddr_u refidadr; u_long srcport = 0; char *dstadr_refid = "0.0.0.0"; char *serverlocal; size_t drlen; u_long stratum = 0; long ppoll = 0; long hpoll = 0; u_long reach = 0; l_fp estoffset; l_fp estdelay; l_fp estjitter; l_fp estdisp; l_fp reftime; l_fp rec; l_fp ts; u_char havevar[MAXHAVE]; u_long poll_sec; char type = '?'; char refid_string[10]; char whenbuf[8], pollbuf[8]; char clock_name[LENHOSTNAME]; memset((char *)havevar, 0, sizeof(havevar)); get_systime(&ts); ZERO_SOCK(&srcadr); ZERO_SOCK(&dstadr); /* Initialize by zeroing out estimate variables */ memset((char *)&estoffset, 0, sizeof(l_fp)); memset((char *)&estdelay, 0, sizeof(l_fp)); memset((char *)&estjitter, 0, sizeof(l_fp)); memset((char *)&estdisp, 0, sizeof(l_fp)); while (nextvar(&datalen, &data, &name, &value)) { sockaddr_u dum_store; i = findvar(name, peer_var, 1); if (i == 0) continue; /* don't know this one */ switch (i) { case CP_SRCADR: if (decodenetnum(value, &srcadr)) { havevar[HAVE_SRCADR] = 1; } break; case CP_DSTADR: if (decodenetnum(value, &dum_store)) { type = decodeaddrtype(&dum_store); havevar[HAVE_DSTADR] = 1; dstadr = dum_store; if (pvl == opeervarlist) { dstadr_refid = trunc_left(stoa(&dstadr), 15); } } break; case CP_REFID: if (pvl == peervarlist) { havevar[HAVE_REFID] = 1; if (*value == '\0') { dstadr_refid = ""; } else if (strlen(value) <= 4) { refid_string[0] = '.'; (void) strcpy(&refid_string[1], value); i = strlen(refid_string); refid_string[i] = '.'; refid_string[i+1] = '\0'; dstadr_refid = refid_string; } else if (decodenetnum(value, &refidadr)) { if (SOCK_UNSPEC(&refidadr)) dstadr_refid = "0.0.0.0"; else if (ISREFCLOCKADR(&refidadr)) dstadr_refid = refnumtoa(&refidadr); else dstadr_refid = stoa(&refidadr); } else { havevar[HAVE_REFID] = 0; } } break; case CP_STRATUM: if (decodeuint(value, &stratum)) havevar[HAVE_STRATUM] = 1; break; case CP_HPOLL: if (decodeint(value, &hpoll)) { havevar[HAVE_HPOLL] = 1; if (hpoll < 0) hpoll = NTP_MINPOLL; } break; case CP_PPOLL: if (decodeint(value, &ppoll)) { havevar[HAVE_PPOLL] = 1; if (ppoll < 0) ppoll = NTP_MINPOLL; } break; case CP_REACH: if (decodeuint(value, &reach)) havevar[HAVE_REACH] = 1; break; case CP_DELAY: if (decodetime(value, &estdelay)) havevar[HAVE_DELAY] = 1; break; case CP_OFFSET: if (decodetime(value, &estoffset)) havevar[HAVE_OFFSET] = 1; break; case CP_JITTER: if (pvl == peervarlist) if (decodetime(value, &estjitter)) havevar[HAVE_JITTER] = 1; break; case CP_DISPERSION: if (decodetime(value, &estdisp)) havevar[HAVE_DISPERSION] = 1; break; case CP_REC: if (decodets(value, &rec)) havevar[HAVE_REC] = 1; break; case CP_SRCPORT: if (decodeuint(value, &srcport)) havevar[HAVE_SRCPORT] = 1; break; case CP_REFTIME: havevar[HAVE_REFTIME] = 1; if (!decodets(value, &reftime)) L_CLR(&reftime); break; default: break; } } /* * Check to see if the srcport is NTP's port. If not this probably * isn't a valid peer association. */ if (havevar[HAVE_SRCPORT] && srcport != NTP_PORT) return (1); /* * Got everything, format the line */ poll_sec = 1<<max(min3(ppoll, hpoll, NTP_MAXPOLL), NTP_MINPOLL); if (pktversion > NTP_OLDVERSION) c = flash3[CTL_PEER_STATVAL(rstatus) & 0x7]; else c = flash2[CTL_PEER_STATVAL(rstatus) & 0x3]; if (numhosts > 1) { if (peervarlist == pvl && havevar[HAVE_DSTADR]) { serverlocal = nntohost_col(&dstadr, (size_t)min(LIB_BUFLENGTH - 1, maxhostlen), TRUE); } else { if (currenthostisnum) serverlocal = trunc_left(currenthost, maxhostlen); else serverlocal = currenthost; } fprintf(fp, "%-*s ", maxhostlen, serverlocal); } if (AF_UNSPEC == af || AF(&srcadr) == af) { strncpy(clock_name, nntohost(&srcadr), sizeof(clock_name)); fprintf(fp, "%c%-15.15s ", c, clock_name); drlen = strlen(dstadr_refid); makeascii(drlen, dstadr_refid, fp); while (drlen++ < 15) fputc(' ', fp); fprintf(fp, " %2ld %c %4.4s %4.4s %3lo %7.7s %8.7s %7.7s\n", stratum, type, prettyinterval(whenbuf, sizeof(whenbuf), when(&ts, &rec, &reftime)), prettyinterval(pollbuf, sizeof(pollbuf), (int)poll_sec), reach, lfptoms(&estdelay, 3), lfptoms(&estoffset, 3), (havevar[HAVE_JITTER]) ? lfptoms(&estjitter, 3) : lfptoms(&estdisp, 3)); return (1); } else return(1); }