/***************************************************************************** * * ntpq_get_assoc_clocktype * * This function returns a clocktype value for a given association number * (not ID!): * * NTP_CLOCKTYPE_UNKNOWN Unknown clock type * NTP_CLOCKTYPE_BROADCAST Broadcast server * NTP_CLOCKTYPE_LOCAL Local clock * NTP_CLOCKTYPE_UNICAST Unicast server * NTP_CLOCKTYPE_MULTICAST Multicast server * ****************************************************************************/ int ntpq_get_assoc_clocktype( int assoc_index ) { associd_t associd; int i; int rc; sockaddr_u dum_store; char dstadr[LENHOSTNAME]; char resultbuf[NTPQ_BUFLEN]; if (assoc_index < 0 || assoc_index >= numassoc) return -1; associd = assoc_cache[assoc_index].assid; if (associd == peervar_assoc) { rc = ntpq_get_peervar("dstadr", dstadr, sizeof(dstadr)); } else { i = ntpq_read_assoc_peervars(associd, resultbuf, sizeof(resultbuf)); if (i <= 0) return -1; rc = ntpq_getvar(resultbuf, i, "dstadr", dstadr, sizeof(dstadr)); } if (0 != rc && decodenetnum(dstadr, &dum_store)) return ntpq_decodeaddrtype(&dum_store); return -1; }
void test_IllegalAddress(void) { const char *str = "192.0.2.270:2000"; sockaddr_u actual; TEST_ASSERT_FALSE(decodenetnum(str, &actual)); }
void test_IPv4AddressWithPort(void) { const char *str = "192.0.2.2:2000"; sockaddr_u actual; sockaddr_u expected; expected.sa4.sin_family = AF_INET; expected.sa4.sin_addr.s_addr = inet_addr("192.0.2.2"); SET_PORT(&expected, 2000); TEST_ASSERT_TRUE(decodenetnum(str, &actual)); TEST_ASSERT_TRUE(IsEqual(expected, actual)); }
void test_IllegalCharInPort(void) { /* An illegal port does not make the decodenetnum fail, but instead * makes it use the standard port. */ const char *str = "192.0.2.1:a700"; sockaddr_u actual; sockaddr_u expected; expected.sa4.sin_family = AF_INET; expected.sa4.sin_addr.s_addr = inet_addr("192.0.2.1"); SET_PORT(&expected, NTP_PORT); TEST_ASSERT_TRUE(decodenetnum(str, &actual)); TEST_ASSERT_TRUE(IsEqual(expected, actual)); }
/* * getnetnum - given a host name, return its net number * and (optional) full name */ static int getnetnum( const char *hname, sockaddr_u *num, char *fullhost, int af ) { struct addrinfo hints, *ai = NULL; ZERO(hints); hints.ai_flags = AI_CANONNAME; #ifdef AI_ADDRCONFIG hints.ai_flags |= AI_ADDRCONFIG; #endif /* * decodenetnum only works with addresses, but handles syntax * that getaddrinfo doesn't: [2001::1]:1234 */ if (decodenetnum(hname, num)) { if (fullhost != NULL) getnameinfo(&num->sa, SOCKLEN(num), fullhost, LENHOSTNAME, NULL, 0, 0); return 1; } else if (getaddrinfo(hname, "ntp", &hints, &ai) == 0) { INSIST(sizeof(*num) >= ai->ai_addrlen); memcpy(num, ai->ai_addr, ai->ai_addrlen); if (fullhost != NULL) { if (ai->ai_canonname != NULL) strlcpy(fullhost, ai->ai_canonname, LENHOSTNAME); else getnameinfo(&num->sa, SOCKLEN(num), fullhost, LENHOSTNAME, NULL, 0, 0); } return 1; } fprintf(stderr, "***Can't find host %s\n", hname); return 0; }
/* * getnetnum - given a host name, return its net number * and (optional) full name */ static int getnetnum( const char *hname, sockaddr_u *num, char *fullhost, int af ) { int sockaddr_len; struct addrinfo hints, *ai = NULL; sockaddr_len = SIZEOF_SOCKADDR(af); memset((char *)&hints, 0, sizeof(struct addrinfo)); hints.ai_flags = AI_CANONNAME; #ifdef AI_ADDRCONFIG hints.ai_flags |= AI_ADDRCONFIG; #endif /* decodenetnum only works with addresses */ if (decodenetnum(hname, num)) { if (fullhost != 0) { getnameinfo(&num->sa, sockaddr_len, fullhost, sizeof(fullhost), NULL, 0, NI_NUMERICHOST); } return 1; } else if (getaddrinfo(hname, "ntp", &hints, &ai) == 0) { memmove((char *)num, ai->ai_addr, ai->ai_addrlen); if (fullhost != 0) (void) strcpy(fullhost, ai->ai_canonname); return 1; } else { (void) fprintf(stderr, "***Can't find host %s\n", hname); return 0; } /*NOTREACHED*/ }
/* * 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); }