/* * peers - print a peer spreadsheet */ static void dopeers( int showall, FILE *fp, int af ) { int i; char fullname[LENHOSTNAME]; sockaddr_u netnum; char * name_or_num; size_t sl; if (!dogetassoc(fp)) return; for (i = 0; i < numhosts; ++i) { if (getnetnum(chosts[i], &netnum, fullname, af)) { name_or_num = nntohost(&netnum); sl = strlen(name_or_num); maxhostlen = max(maxhostlen, (int)sl); } } if (numhosts > 1) fprintf(fp, "%-*.*s ", maxhostlen, maxhostlen, "server (local)"); fprintf(fp, " remote refid st t when poll reach delay offset jitter\n"); if (numhosts > 1) for (i = 0; i <= maxhostlen; ++i) fprintf(fp, "="); fprintf(fp, "==============================================================================\n"); for (i = 0; i < numassoc; i++) { if (!showall && !(CTL_PEER_STATVAL(assoc_cache[i].status) & (CTL_PST_CONFIG|CTL_PST_REACH))) continue; if (!dogetpeers(peervarlist, (int)assoc_cache[i].assid, fp, af)) { return; } } return; }
/* * statustoa - return a descriptive string for a peer status */ char * statustoa( int type, int st ) { char * cb; char * cc; u_char pst; LIB_GETBUF(cb); switch (type) { case TYPE_SYS: snprintf(cb, LIB_BUFLENGTH, "%s, %s, %s, %s", getcode(CTL_SYS_LI(st), leap_codes), getcode(CTL_SYS_SOURCE(st), sync_codes), getevents(CTL_SYS_NEVNT(st)), getcode(CTL_SYS_EVENT(st), sys_codes)); break; case TYPE_PEER: pst = (u_char)CTL_PEER_STATVAL(st); snprintf(cb, LIB_BUFLENGTH, "%s, %s, %s", peer_st_flags(pst), getcode(pst & 0x7, select_codes), getevents(CTL_PEER_NEVNT(st))); if (CTL_PEER_EVENT(st) != EVNT_UNSPEC) { cc = cb + strlen(cb); snprintf(cc, LIB_BUFLENGTH - (cc - cb), ", %s", getcode(CTL_PEER_EVENT(st), peer_codes)); } break; case TYPE_CLOCK: snprintf(cb, LIB_BUFLENGTH, "%s, %s", getevents(CTL_SYS_NEVNT(st)), getcode((st) & 0xf, clock_codes)); break; } return cb; }
/* * opeers - print a peer spreadsheet */ static void doopeers( int showall, FILE *fp, int af ) { register int i; char fullname[LENHOSTNAME]; sockaddr_u netnum; if (!dogetassoc(fp)) return; for (i = 0; i < numhosts; ++i) { if (getnetnum(chosts[i], &netnum, fullname, af)) if ((int)strlen(fullname) > maxhostlen) maxhostlen = strlen(fullname); } if (numhosts > 1) (void) fprintf(fp, "%-*.*s ", maxhostlen, maxhostlen, "server"); (void) fprintf(fp, " remote local st t when poll reach delay offset disp\n"); if (numhosts > 1) for (i = 0; i <= maxhostlen; ++i) (void) fprintf(fp, "="); (void) fprintf(fp, "==============================================================================\n"); for (i = 0; i < numassoc; i++) { if (!showall && !(CTL_PEER_STATVAL(assoc_cache[i].status) & (CTL_PST_CONFIG|CTL_PST_REACH))) continue; if (!dogetpeers(opeervarlist, (int)assoc_cache[i].assid, fp, af)) { return; } } return; }
/* * statustoa - return a descriptive string for a peer status */ char * statustoa( int type, int st ) { char *cb; u_char pst; LIB_GETBUF(cb); switch (type) { case TYPE_SYS: strcpy(cb, getcode(CTL_SYS_LI(st), leap_codes)); strcat(cb, ", "); strcat(cb, getcode(CTL_SYS_SOURCE(st), sync_codes)); strcat(cb, ", "); strcat(cb, getevents(CTL_SYS_NEVNT(st))); strcat(cb, ", "); strcat(cb, getcode(CTL_SYS_EVENT(st), sys_codes)); break; case TYPE_PEER: /* * Handcraft the bits */ pst = (u_char) CTL_PEER_STATVAL(st); if (pst & CTL_PST_CONFIG) strcpy(cb, "conf"); if (pst & CTL_PST_AUTHENABLE) { if (pst & CTL_PST_CONFIG) strcat(cb, ", authenb"); else strcat(cb, "authenb"); } if (pst & CTL_PST_AUTHENTIC) { if (pst & (CTL_PST_CONFIG | CTL_PST_AUTHENABLE)) strcat(cb, ", auth"); else strcat(cb, "auth"); } if (pst & CTL_PST_REACH) { if (pst & (CTL_PST_CONFIG | CTL_PST_AUTHENABLE | CTL_PST_AUTHENTIC)) strcat(cb, ", reach"); else strcat(cb, "reach"); } if (pst & CTL_PST_BCAST) { if (pst & (CTL_PST_CONFIG | CTL_PST_AUTHENABLE | CTL_PST_AUTHENTIC | CTL_PST_REACH)) strcat(cb, ", bcst"); else strcat(cb, "bcst"); } /* * Now the codes */ strcat(cb, ", "); strcat(cb, getcode(pst & 0x7, select_codes)); strcat(cb, ", "); strcat(cb, getevents(CTL_PEER_NEVNT(st))); if (CTL_PEER_EVENT(st) != EVNT_UNSPEC) { strcat(cb, ", "); strcat(cb, getcode(CTL_PEER_EVENT(st), peer_codes)); } break; case TYPE_CLOCK: strcat(cb, ", "); strcat(cb, getevents(CTL_SYS_NEVNT(st))); strcat(cb, ", "); strcat(cb, getcode((st) & 0xf, clock_codes)); break; } return cb; }
/* * printassoc - print the current list of associations */ static void printassoc( int showall, FILE *fp ) { register char *bp; int i; u_char statval; int event; u_long event_count; const char *conf; const char *reach; const char *auth; const char *condition = ""; const char *last_event; const char *cnt; char buf[128]; if (numassoc == 0) { (void) fprintf(fp, "No association ID's in list\n"); return; } /* * Output a header */ (void) fprintf(fp, "\nind assid status conf reach auth condition last_event cnt\n"); (void) fprintf(fp, "===========================================================\n"); for (i = 0; i < numassoc; i++) { statval = (u_char) CTL_PEER_STATVAL(assoc_cache[i].status); if (!showall && !(statval & (CTL_PST_CONFIG|CTL_PST_REACH))) continue; event = CTL_PEER_EVENT(assoc_cache[i].status); event_count = CTL_PEER_NEVNT(assoc_cache[i].status); if (statval & CTL_PST_CONFIG) conf = "yes"; else conf = "no"; if (statval & CTL_PST_BCAST) { reach = "none"; if (statval & CTL_PST_AUTHENABLE) auth = "yes"; else auth = "none"; } else { if (statval & CTL_PST_REACH) reach = "yes"; else reach = "no"; if (statval & CTL_PST_AUTHENABLE) { if (statval & CTL_PST_AUTHENTIC) auth = "ok "; else auth = "bad"; } else { auth = "none"; } } if (pktversion > NTP_OLDVERSION) { switch (statval & 0x7) { case CTL_PST_SEL_REJECT: condition = "reject"; break; case CTL_PST_SEL_SANE: condition = "falsetick"; break; case CTL_PST_SEL_CORRECT: condition = "excess"; break; case CTL_PST_SEL_SELCAND: condition = "outlyer"; break; case CTL_PST_SEL_SYNCCAND: condition = "candidate"; break; case CTL_PST_SEL_EXCESS: condition = "backup"; break; case CTL_PST_SEL_SYSPEER: condition = "sys.peer"; break; case CTL_PST_SEL_PPS: condition = "pps.peer"; break; } } else { switch (statval & 0x3) { case OLD_CTL_PST_SEL_REJECT: if (!(statval & OLD_CTL_PST_SANE)) condition = "insane"; else if (!(statval & OLD_CTL_PST_DISP)) condition = "hi_disp"; else condition = ""; break; case OLD_CTL_PST_SEL_SELCAND: condition = "sel_cand"; break; case OLD_CTL_PST_SEL_SYNCCAND: condition = "sync_cand"; break; case OLD_CTL_PST_SEL_SYSPEER: condition = "sys_peer"; break; } } switch (PEER_EVENT|event) { case PEVNT_MOBIL: last_event = "mobilize"; break; case PEVNT_DEMOBIL: last_event = "demobilize"; break; case PEVNT_REACH: last_event = "reachable"; break; case PEVNT_UNREACH: last_event = "unreachable"; break; case PEVNT_RESTART: last_event = "restart"; break; case PEVNT_REPLY: last_event = "no_reply"; break; case PEVNT_RATE: last_event = "rate_exceeded"; break; case PEVNT_DENY: last_event = "access_denied"; break; case PEVNT_ARMED: last_event = "leap_armed"; break; case PEVNT_NEWPEER: last_event = "sys_peer"; break; case PEVNT_CLOCK: last_event = "clock_alarm"; break; default: last_event = ""; break; } cnt = uinttoa(event_count); snprintf(buf, sizeof(buf), "%3d %5u %04x %3.3s %4s %4.4s %9.9s %11s %2s", i + 1, assoc_cache[i].assid, assoc_cache[i].status, conf, reach, auth, condition, last_event, cnt); bp = buf + strlen(buf); while (bp > buf && ' ' == bp[-1]) --bp; bp[0] = '\0'; fprintf(fp, "%s\n", buf); } }
/* * 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); }