diff options
Diffstat (limited to 'contrib/ntp/ntpq/ntpq_ops.c')
-rw-r--r-- | contrib/ntp/ntpq/ntpq_ops.c | 1734 |
1 files changed, 0 insertions, 1734 deletions
diff --git a/contrib/ntp/ntpq/ntpq_ops.c b/contrib/ntp/ntpq/ntpq_ops.c deleted file mode 100644 index c493631..0000000 --- a/contrib/ntp/ntpq/ntpq_ops.c +++ /dev/null @@ -1,1734 +0,0 @@ -/* - * ntpq_ops.c - subroutines which are called to perform operations by ntpq - */ - -#include <stdio.h> -#include <ctype.h> -#include <sys/types.h> -#include <sys/time.h> -#include <netdb.h> - -#include "ntpq.h" -#include "ntp_stdlib.h" - -extern char * chosts[]; -extern char currenthost[]; -extern int numhosts; -int maxhostlen; - -/* - * Declarations for command handlers in here - */ -static int checkassocid P((u_int32)); -static char * strsave P((char *)); -static struct varlist *findlistvar P((struct varlist *, char *)); -static void doaddvlist P((struct varlist *, char *)); -static void dormvlist P((struct varlist *, char *)); -static void doclearvlist P((struct varlist *)); -static void makequerydata P((struct varlist *, int *, char *)); -static int doquerylist P((struct varlist *, int, int, int, u_short *, int *, char **)); -static void doprintvlist P((struct varlist *, FILE *)); -static void addvars P((struct parse *, FILE *)); -static void rmvars P((struct parse *, FILE *)); -static void clearvars P((struct parse *, FILE *)); -static void showvars P((struct parse *, FILE *)); -static int dolist P((struct varlist *, int, int, int, FILE *)); -static void readlist P((struct parse *, FILE *)); -static void writelist P((struct parse *, FILE *)); -static void readvar P((struct parse *, FILE *)); -static void writevar P((struct parse *, FILE *)); -static void clocklist P((struct parse *, FILE *)); -static void clockvar P((struct parse *, FILE *)); -static int findassidrange P((u_int32, u_int32, int *, int *)); -static void mreadlist P((struct parse *, FILE *)); -static void mreadvar P((struct parse *, FILE *)); -static int dogetassoc P((FILE *)); -static void printassoc P((int, FILE *)); -static void associations P((struct parse *, FILE *)); -static void lassociations P((struct parse *, FILE *)); -static void passociations P((struct parse *, FILE *)); -static void lpassociations P((struct parse *, FILE *)); - -#ifdef UNUSED -static void radiostatus P((struct parse *, FILE *)); -#endif /* UNUSED */ - -static void pstatus P((struct parse *, FILE *)); -static long when P((l_fp *, l_fp *, l_fp *)); -static char * prettyinterval P((char *, long)); -static int doprintpeers P((struct varlist *, int, int, int, char *, FILE *, int)); -static int dogetpeers P((struct varlist *, int, FILE *, int)); -static void dopeers P((int, FILE *, int)); -static void peers P((struct parse *, FILE *)); -static void lpeers P((struct parse *, FILE *)); -static void doopeers P((int, FILE *, int)); -static void opeers P((struct parse *, FILE *)); -static void lopeers P((struct parse *, FILE *)); - - -/* - * Commands we understand. Ntpdc imports this. - */ -struct xcmd opcmds[] = { - { "associations", associations, { NO, NO, NO, NO }, - { "", "", "", "" }, - "print list of association ID's and statuses for the server's peers" }, - { "passociations", passociations, { NO, NO, NO, NO }, - { "", "", "", "" }, - "print list of associations returned by last associations command" }, - { "lassociations", lassociations, { NO, NO, NO, NO }, - { "", "", "", "" }, - "print list of associations including all client information" }, - { "lpassociations", lpassociations, { NO, NO, NO, NO }, - { "", "", "", "" }, - "print last obtained list of associations, including client information" }, - { "addvars", addvars, { STR, NO, NO, NO }, - { "name[=value][,...]", "", "", "" }, - "add variables to the variable list or change their values" }, - { "rmvars", rmvars, { STR, NO, NO, NO }, - { "name[,...]", "", "", "" }, - "remove variables from the variable list" }, - { "clearvars", clearvars, { NO, NO, NO, NO }, - { "", "", "", "" }, - "remove all variables from the variable list" }, - { "showvars", showvars, { NO, NO, NO, NO }, - { "", "", "", "" }, - "print variables on the variable list" }, - { "readlist", readlist, { OPT|UINT, NO, NO, NO }, - { "assocID", "", "", "" }, - "read the system or peer variables included in the variable list" }, - { "rl", readlist, { OPT|UINT, NO, NO, NO }, - { "assocID", "", "", "" }, - "read the system or peer variables included in the variable list" }, - { "writelist", writelist, { OPT|UINT, NO, NO, NO }, - { "assocID", "", "", "" }, - "write the system or peer variables included in the variable list" }, - { "readvar", readvar, { OPT|UINT, OPT|STR, NO, NO }, - { "assocID", "name=value[,...]", "", "" }, - "read system or peer variables" }, - { "rv", readvar, { OPT|UINT, OPT|STR, NO, NO }, - { "assocID", "name=value[,...]", "", "" }, - "read system or peer variables" }, - { "writevar", writevar, { UINT, STR, NO, NO }, - { "assocID", "name=value,[...]", "", "" }, - "write system or peer variables" }, - { "mreadlist", mreadlist, { UINT, UINT, NO, NO }, - { "assocID", "assocID", "", "" }, - "read the peer variables in the variable list for multiple peers" }, - { "mrl", mreadlist, { UINT, UINT, NO, NO }, - { "assocID", "assocID", "", "" }, - "read the peer variables in the variable list for multiple peers" }, - { "mreadvar", mreadvar, { UINT, UINT, OPT|STR, NO }, - { "assocID", "assocID", "name=value[,...]", "" }, - "read peer variables from multiple peers" }, - { "mrv", mreadvar, { UINT, UINT, OPT|STR, NO }, - { "assocID", "assocID", "name=value[,...]", "" }, - "read peer variables from multiple peers" }, - { "clocklist", clocklist, { OPT|UINT, NO, NO, NO }, - { "assocID", "", "", "" }, - "read the clock variables included in the variable list" }, - { "cl", clocklist, { OPT|UINT, NO, NO, NO }, - { "assocID", "", "", "" }, - "read the clock variables included in the variable list" }, - { "clockvar", clockvar, { OPT|UINT, OPT|STR, NO, NO }, - { "assocID", "name=value[,...]", "", "" }, - "read clock variables" }, - { "cv", clockvar, { OPT|UINT, OPT|STR, NO, NO }, - { "assocID", "name=value[,...]", "", "" }, - "read clock variables" }, - { "pstatus", pstatus, { UINT, NO, NO, NO }, - { "assocID", "", "", "" }, - "print status information returned for a peer" }, - { "peers", peers, { OPT|IP_VERSION, NO, NO, NO }, - { "-4|-6", "", "", "" }, - "obtain and print a list of the server's peers [IP version]" }, - { "lpeers", lpeers, { OPT|IP_VERSION, NO, NO, NO }, - { "-4|-6", "", "", "" }, - "obtain and print a list of all peers and clients [IP version]" }, - { "opeers", opeers, { OPT|IP_VERSION, NO, NO, NO }, - { "-4|-6", "", "", "" }, - "print peer list the old way, with dstadr shown rather than refid [IP version]" }, - { "lopeers", lopeers, { OPT|IP_VERSION, NO, NO, NO }, - { "-4|-6", "", "", "" }, - "obtain and print a list of all peers and clients showing dstadr [IP version]" }, - { 0, 0, { NO, NO, NO, NO }, - { "-4|-6", "", "", "" }, "" } -}; - - -/* - * Variable list data space - */ -#define MAXLIST 64 /* maximum number of variables in list */ -#define LENHOSTNAME 256 /* host name is 256 characters long */ -/* - * Old CTL_PST defines for version 2. - */ -#define OLD_CTL_PST_CONFIG 0x80 -#define OLD_CTL_PST_AUTHENABLE 0x40 -#define OLD_CTL_PST_AUTHENTIC 0x20 -#define OLD_CTL_PST_REACH 0x10 -#define OLD_CTL_PST_SANE 0x08 -#define OLD_CTL_PST_DISP 0x04 -#define OLD_CTL_PST_SEL_REJECT 0 -#define OLD_CTL_PST_SEL_SELCAND 1 -#define OLD_CTL_PST_SEL_SYNCCAND 2 -#define OLD_CTL_PST_SEL_SYSPEER 3 - - -char flash2[] = " .+* "; /* flash decode for version 2 */ -char flash3[] = " x.-+#*o"; /* flash decode for peer status version 3 */ - -struct varlist { - char *name; - char *value; -} varlist[MAXLIST] = { { 0, 0 } }; - -/* - * Imported from ntpq.c - */ -extern int showhostnames; -extern int rawmode; -extern struct servent *server_entry; -extern struct association assoc_cache[]; -extern int numassoc; -extern u_char pktversion; -extern struct ctl_var peer_var[]; - -/* - * For quick string comparisons - */ -#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) - - -/* - * checkassocid - return the association ID, checking to see if it is valid - */ -static int -checkassocid( - u_int32 value - ) -{ - if (value == 0 || value >= 65536) { - (void) fprintf(stderr, "***Invalid association ID specified\n"); - return 0; - } - return (int)value; -} - - -/* - * strsave - save a string - * XXX - should be in libntp.a - */ -static char * -strsave( - char *str - ) -{ - char *cp; - u_int len; - - len = strlen(str) + 1; - if ((cp = (char *)malloc(len)) == NULL) { - (void) fprintf(stderr, "Malloc failed!!\n"); - exit(1); - } - - memmove(cp, str, len); - return (cp); -} - - -/* - * findlistvar - look for the named variable in a list and return if found - */ -static struct varlist * -findlistvar( - struct varlist *list, - char *name - ) -{ - register struct varlist *vl; - - for (vl = list; vl < list + MAXLIST && vl->name != 0; vl++) - if (STREQ(name, vl->name)) - return vl; - if (vl < list + MAXLIST) - return vl; - return (struct varlist *)0; -} - - -/* - * doaddvlist - add variable(s) to the variable list - */ -static void -doaddvlist( - struct varlist *vlist, - char *vars - ) -{ - register struct varlist *vl; - int len; - char *name; - char *value; - - len = strlen(vars); - while (nextvar(&len, &vars, &name, &value)) { - vl = findlistvar(vlist, name); - if (vl == 0) { - (void) fprintf(stderr, "Variable list full\n"); - return; - } - - if (vl->name == 0) { - vl->name = strsave(name); - } else if (vl->value != 0) { - free(vl->value); - vl->value = 0; - } - - if (value != 0) - vl->value = strsave(value); - } -} - - -/* - * dormvlist - remove variable(s) from the variable list - */ -static void -dormvlist( - struct varlist *vlist, - char *vars - ) -{ - register struct varlist *vl; - int len; - char *name; - char *value; - - len = strlen(vars); - while (nextvar(&len, &vars, &name, &value)) { - vl = findlistvar(vlist, name); - if (vl == 0 || vl->name == 0) { - (void) fprintf(stderr, "Variable `%s' not found\n", - name); - } else { - free((void *)vl->name); - if (vl->value != 0) - free(vl->value); - for ( ; (vl+1) < (varlist+MAXLIST) - && (vl+1)->name != 0; vl++) { - vl->name = (vl+1)->name; - vl->value = (vl+1)->value; - } - vl->name = vl->value = 0; - } - } -} - - -/* - * doclearvlist - clear a variable list - */ -static void -doclearvlist( - struct varlist *vlist - ) -{ - register struct varlist *vl; - - for (vl = vlist; vl < vlist + MAXLIST && vl->name != 0; vl++) { - free((void *)vl->name); - vl->name = 0; - if (vl->value != 0) { - free(vl->value); - vl->value = 0; - } - } -} - - -/* - * makequerydata - form a data buffer to be included with a query - */ -static void -makequerydata( - struct varlist *vlist, - int *datalen, - char *data - ) -{ - register struct varlist *vl; - register char *cp, *cpend; - register int namelen, valuelen; - register int totallen; - - cp = data; - cpend = data + *datalen; - - for (vl = vlist; vl < vlist + MAXLIST && vl->name != 0; vl++) { - namelen = strlen(vl->name); - if (vl->value == 0) - valuelen = 0; - else - valuelen = strlen(vl->value); - totallen = namelen + valuelen + (valuelen != 0) + (cp != data); - if (cp + totallen > cpend) - break; - - if (cp != data) - *cp++ = ','; - memmove(cp, vl->name, (unsigned)namelen); - cp += namelen; - if (valuelen != 0) { - *cp++ = '='; - memmove(cp, vl->value, (unsigned)valuelen); - cp += valuelen; - } - } - *datalen = cp - data; -} - - -/* - * doquerylist - send a message including variables in a list - */ -static int -doquerylist( - struct varlist *vlist, - int op, - int associd, - int auth, - u_short *rstatus, - int *dsize, - char **datap - ) -{ - char data[CTL_MAX_DATA_LEN]; - int datalen; - - datalen = sizeof(data); - makequerydata(vlist, &datalen, data); - - return doquery(op, associd, auth, datalen, data, rstatus, - dsize, datap); -} - - -/* - * doprintvlist - print the variables on a list - */ -static void -doprintvlist( - struct varlist *vlist, - FILE *fp - ) -{ - register struct varlist *vl; - - if (vlist->name == 0) { - (void) fprintf(fp, "No variables on list\n"); - } else { - for (vl = vlist; vl < vlist + MAXLIST && vl->name != 0; vl++) { - if (vl->value == 0) { - (void) fprintf(fp, "%s\n", vl->name); - } else { - (void) fprintf(fp, "%s=%s\n", - vl->name, vl->value); - } - } - } -} - - -/* - * addvars - add variables to the variable list - */ -/*ARGSUSED*/ -static void -addvars( - struct parse *pcmd, - FILE *fp - ) -{ - doaddvlist(varlist, pcmd->argval[0].string); -} - - -/* - * rmvars - remove variables from the variable list - */ -/*ARGSUSED*/ -static void -rmvars( - struct parse *pcmd, - FILE *fp - ) -{ - dormvlist(varlist, pcmd->argval[0].string); -} - - -/* - * clearvars - clear the variable list - */ -/*ARGSUSED*/ -static void -clearvars( - struct parse *pcmd, - FILE *fp - ) -{ - doclearvlist(varlist); -} - - -/* - * showvars - show variables on the variable list - */ -/*ARGSUSED*/ -static void -showvars( - struct parse *pcmd, - FILE *fp - ) -{ - doprintvlist(varlist, fp); -} - - -/* - * dolist - send a request with the given list of variables - */ -static int -dolist( - struct varlist *vlist, - int associd, - int op, - int type, - FILE *fp - ) -{ - char *datap; - int res; - int dsize; - u_short rstatus; - - res = doquerylist(vlist, op, associd, 0, &rstatus, &dsize, &datap); - - if (res != 0) - return 0; - - if (dsize == 0) { - if (associd == 0) - (void) fprintf(fp, "No system%s variables returned\n", - (type == TYPE_CLOCK) ? " clock" : ""); - else - (void) fprintf(fp, - "No information returned for%s association %u\n", - (type == TYPE_CLOCK) ? " clock" : "", associd); - return 1; - } - - printvars(dsize, datap, (int)rstatus, type, fp); - return 1; -} - - -/* - * readlist - send a read variables request with the variables on the list - */ -static void -readlist( - struct parse *pcmd, - FILE *fp - ) -{ - int associd; - - if (pcmd->nargs == 0) { - associd = 0; - } else { - /* HMS: I think we want the u_int32 target here, not the u_long */ - if (pcmd->argval[0].uval == 0) - associd = 0; - else if ((associd = checkassocid(pcmd->argval[0].uval)) == 0) - return; - } - - (void) dolist(varlist, associd, CTL_OP_READVAR, - (associd == 0) ? TYPE_SYS : TYPE_PEER, fp); -} - - -/* - * writelist - send a write variables request with the variables on the list - */ -static void -writelist( - struct parse *pcmd, - FILE *fp - ) -{ - char *datap; - int res; - int associd; - int dsize; - u_short rstatus; - - if (pcmd->nargs == 0) { - associd = 0; - } else { - /* HMS: Do we really want uval here? */ - if (pcmd->argval[0].uval == 0) - associd = 0; - else if ((associd = checkassocid(pcmd->argval[0].uval)) == 0) - return; - } - - res = doquerylist(varlist, CTL_OP_WRITEVAR, associd, 1, &rstatus, - &dsize, &datap); - - if (res != 0) - return; - - if (dsize == 0) - (void) fprintf(fp, "done! (no data returned)\n"); - else - printvars(dsize, datap, (int)rstatus, - (associd != 0) ? TYPE_PEER : TYPE_SYS, fp); - return; -} - - -/* - * readvar - send a read variables request with the specified variables - */ -static void -readvar( - struct parse *pcmd, - FILE *fp - ) -{ - int associd; - struct varlist tmplist[MAXLIST]; - - /* HMS: uval? */ - if (pcmd->nargs == 0 || pcmd->argval[0].uval == 0) - associd = 0; - else if ((associd = checkassocid(pcmd->argval[0].uval)) == 0) - return; - - memset((char *)tmplist, 0, sizeof(tmplist)); - if (pcmd->nargs >= 2) - doaddvlist(tmplist, pcmd->argval[1].string); - - (void) dolist(tmplist, associd, CTL_OP_READVAR, - (associd == 0) ? TYPE_SYS : TYPE_PEER, fp); - - doclearvlist(tmplist); -} - - -/* - * writevar - send a write variables request with the specified variables - */ -static void -writevar( - struct parse *pcmd, - FILE *fp - ) -{ - char *datap; - int res; - int associd; - int dsize; - u_short rstatus; - struct varlist tmplist[MAXLIST]; - - /* HMS: uval? */ - if (pcmd->argval[0].uval == 0) - associd = 0; - else if ((associd = checkassocid(pcmd->argval[0].uval)) == 0) - return; - - memset((char *)tmplist, 0, sizeof(tmplist)); - doaddvlist(tmplist, pcmd->argval[1].string); - - res = doquerylist(tmplist, CTL_OP_WRITEVAR, associd, 1, &rstatus, - &dsize, &datap); - - doclearvlist(tmplist); - - if (res != 0) - return; - - if (dsize == 0) - (void) fprintf(fp, "done! (no data returned)\n"); - else - printvars(dsize, datap, (int)rstatus, - (associd != 0) ? TYPE_PEER : TYPE_SYS, fp); - return; -} - - -/* - * clocklist - send a clock variables request with the variables on the list - */ -static void -clocklist( - struct parse *pcmd, - FILE *fp - ) -{ - int associd; - - /* HMS: uval? */ - if (pcmd->nargs == 0) { - associd = 0; - } else { - if (pcmd->argval[0].uval == 0) - associd = 0; - else if ((associd = checkassocid(pcmd->argval[0].uval)) == 0) - return; - } - - (void) dolist(varlist, associd, CTL_OP_READCLOCK, TYPE_CLOCK, fp); -} - - -/* - * clockvar - send a clock variables request with the specified variables - */ -static void -clockvar( - struct parse *pcmd, - FILE *fp - ) -{ - int associd; - struct varlist tmplist[MAXLIST]; - - /* HMS: uval? */ - if (pcmd->nargs == 0 || pcmd->argval[0].uval == 0) - associd = 0; - else if ((associd = checkassocid(pcmd->argval[0].uval)) == 0) - return; - - memset((char *)tmplist, 0, sizeof(tmplist)); - if (pcmd->nargs >= 2) - doaddvlist(tmplist, pcmd->argval[1].string); - - (void) dolist(tmplist, associd, CTL_OP_READCLOCK, TYPE_CLOCK, fp); - - doclearvlist(tmplist); -} - - -/* - * findassidrange - verify a range of association ID's - */ -static int -findassidrange( - u_int32 assid1, - u_int32 assid2, - int *from, - int *to - ) -{ - register int i; - int f, t; - - if (assid1 == 0 || assid1 > 65535) { - (void) fprintf(stderr, - "***Invalid association ID %lu specified\n", (u_long)assid1); - return 0; - } - - if (assid2 == 0 || assid2 > 65535) { - (void) fprintf(stderr, - "***Invalid association ID %lu specified\n", (u_long)assid2); - return 0; - } - - f = t = -1; - for (i = 0; i < numassoc; i++) { - if (assoc_cache[i].assid == assid1) { - f = i; - if (t != -1) - break; - } - if (assoc_cache[i].assid == assid2) { - t = i; - if (f != -1) - break; - } - } - - if (f == -1 || t == -1) { - (void) fprintf(stderr, - "***Association ID %lu not found in list\n", - (f == -1) ? (u_long)assid1 : (u_long)assid2); - return 0; - } - - if (f < t) { - *from = f; - *to = t; - } else { - *from = t; - *to = f; - } - return 1; -} - - - -/* - * mreadlist - send a read variables request for multiple associations - */ -static void -mreadlist( - struct parse *pcmd, - FILE *fp - ) -{ - int i; - int from; - int to; - - /* HMS: uval? */ - if (!findassidrange(pcmd->argval[0].uval, pcmd->argval[1].uval, - &from, &to)) - return; - - for (i = from; i <= to; i++) { - if (i != from) - (void) fprintf(fp, "\n"); - if (!dolist(varlist, (int)assoc_cache[i].assid, - CTL_OP_READVAR, TYPE_PEER, fp)) - return; - } - return; -} - - -/* - * mreadvar - send a read variables request for multiple associations - */ -static void -mreadvar( - struct parse *pcmd, - FILE *fp - ) -{ - int i; - int from; - int to; - struct varlist tmplist[MAXLIST]; - - /* HMS: uval? */ - if (!findassidrange(pcmd->argval[0].uval, pcmd->argval[1].uval, - &from, &to)) - return; - - memset((char *)tmplist, 0, sizeof(tmplist)); - if (pcmd->nargs >= 3) - doaddvlist(tmplist, pcmd->argval[2].string); - - for (i = from; i <= to; i++) { - if (i != from) - (void) fprintf(fp, "\n"); - if (!dolist(varlist, (int)assoc_cache[i].assid, - CTL_OP_READVAR, TYPE_PEER, fp)) - break; - } - doclearvlist(tmplist); - return; -} - - -/* - * dogetassoc - query the host for its list of associations - */ -static int -dogetassoc( - FILE *fp - ) -{ - u_short *datap; - int res; - int dsize; - u_short rstatus; - - res = doquery(CTL_OP_READSTAT, 0, 0, 0, (char *)0, &rstatus, - &dsize, (void *)&datap); - - if (res != 0) - return 0; - - if (dsize == 0) { - (void) fprintf(fp, "No association ID's returned\n"); - return 0; - } - - if (dsize & 0x3) { - (void) fprintf(stderr, - "***Server returned %d octets, should be multiple of 4\n", - dsize); - return 0; - } - - numassoc = 0; - while (dsize > 0) { - assoc_cache[numassoc].assid = ntohs(*datap); - datap++; - assoc_cache[numassoc].status = ntohs(*datap); - datap++; - if (++numassoc >= MAXASSOC) - break; - dsize -= sizeof(u_short) + sizeof(u_short); - } - sortassoc(); - return 1; -} - - -/* - * 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, - "ind 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_REACH || 1) { - reach = "yes"; - 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 = "candidat"; - break; - case CTL_PST_SEL_DISTSYSPEER: - condition = "selected"; - 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; - } - - } else { - reach = "no"; - auth = condition = ""; - } - - switch (PEER_EVENT|event) { - case EVNT_PEERIPERR: - last_event = "IP error"; - break; - case EVNT_PEERAUTH: - last_event = "auth fail"; - break; - case EVNT_UNREACH: - last_event = "lost reach"; - break; - case EVNT_REACH: - last_event = "reachable"; - break; - case EVNT_PEERCLOCK: - last_event = "clock expt"; - break; -#if 0 - case EVNT_PEERSTRAT: - last_event = "stratum chg"; - break; -#endif - default: - last_event = ""; - break; - } - - if (event_count != 0) - cnt = uinttoa(event_count); - else - cnt = ""; - (void) sprintf(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) = '\0'; - (void) fprintf(fp, "%s\n", buf); - } -} - - - -/* - * associations - get, record and print a list of associations - */ -/*ARGSUSED*/ -static void -associations( - struct parse *pcmd, - FILE *fp - ) -{ - if (dogetassoc(fp)) - printassoc(0, fp); -} - - -/* - * lassociations - get, record and print a long list of associations - */ -/*ARGSUSED*/ -static void -lassociations( - struct parse *pcmd, - FILE *fp - ) -{ - if (dogetassoc(fp)) - printassoc(1, fp); -} - - -/* - * passociations - print the association list - */ -/*ARGSUSED*/ -static void -passociations( - struct parse *pcmd, - FILE *fp - ) -{ - printassoc(0, fp); -} - - -/* - * lpassociations - print the long association list - */ -/*ARGSUSED*/ -static void -lpassociations( - struct parse *pcmd, - FILE *fp - ) -{ - printassoc(1, fp); -} - - -#ifdef UNUSED -/* - * radiostatus - print the radio status returned by the server - */ -/*ARGSUSED*/ -static void -radiostatus( - struct parse *pcmd, - FILE *fp - ) -{ - char *datap; - int res; - int dsize; - u_short rstatus; - - res = doquery(CTL_OP_READCLOCK, 0, 0, 0, (char *)0, &rstatus, - &dsize, &datap); - - if (res != 0) - return; - - if (dsize == 0) { - (void) fprintf(fp, "No radio status string returned\n"); - return; - } - - asciize(dsize, datap, fp); -} -#endif /* UNUSED */ - -/* - * pstatus - print peer status returned by the server - */ -static void -pstatus( - struct parse *pcmd, - FILE *fp - ) -{ - char *datap; - int res; - int associd; - int dsize; - u_short rstatus; - - /* HMS: uval? */ - if ((associd = checkassocid(pcmd->argval[0].uval)) == 0) - return; - - res = doquery(CTL_OP_READSTAT, associd, 0, 0, (char *)0, &rstatus, - &dsize, &datap); - - if (res != 0) - return; - - if (dsize == 0) { - (void) fprintf(fp, - "No information returned for association %u\n", - associd); - return; - } - - printvars(dsize, datap, (int)rstatus, TYPE_PEER, fp); -} - - -/* - * when - print how long its been since his last packet arrived - */ -static long -when( - l_fp *ts, - l_fp *rec, - l_fp *reftime - ) -{ - l_fp *lasttime; - - if (rec->l_ui != 0) - lasttime = rec; - else if (reftime->l_ui != 0) - lasttime = reftime; - else - return 0; - - return (ts->l_ui - lasttime->l_ui); -} - - -/* - * Pretty-print an interval into the given buffer, in a human-friendly format. - */ -static char * -prettyinterval( - char *buf, - long diff - ) -{ - if (diff <= 0) { - buf[0] = '-'; - buf[1] = 0; - return buf; - } - - if (diff <= 2048) { - (void) sprintf(buf, "%ld", (long int)diff); - return buf; - } - - diff = (diff + 29) / 60; - if (diff <= 300) { - (void) sprintf(buf, "%ldm", (long int)diff); - return buf; - } - - diff = (diff + 29) / 60; - if (diff <= 96) { - (void) sprintf(buf, "%ldh", (long int)diff); - return buf; - } - - diff = (diff + 11) / 24; - (void) sprintf(buf, "%ldd", (long int)diff); - return buf; -} - -static char -decodeaddrtype( - struct sockaddr_storage *sock - ) -{ - char ch = '-'; - u_int32 dummy; - struct sockaddr_in6 *sin6; - - switch(sock->ss_family) { - case AF_INET: - dummy = ((struct sockaddr_in *)sock)->sin_addr.s_addr; - dummy = ntohl(dummy); - ch = (char)(((dummy&0xf0000000)==0xe0000000) ? 'm' : - ((dummy&0x000000ff)==0x000000ff) ? 'b' : - ((dummy&0xffffffff)==0x7f000001) ? 'l' : - ((dummy&0xffffffe0)==0x00000000) ? '-' : - 'u'); - break; - case AF_INET6: - sin6 = (struct sockaddr_in6 *)sock; - if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) - ch = 'm'; - else - ch = 'u'; - break; - default: - ch = '-'; - break; - } - return ch; -} - -/* - * A list of variables required by the peers command - */ -struct varlist opeervarlist[] = { - { "srcadr", 0 }, /* 0 */ - { "dstadr", 0 }, /* 1 */ - { "stratum", 0 }, /* 2 */ - { "hpoll", 0 }, /* 3 */ - { "ppoll", 0 }, /* 4 */ - { "reach", 0 }, /* 5 */ - { "delay", 0 }, /* 6 */ - { "offset", 0 }, /* 7 */ - { "jitter", 0 }, /* 8 */ - { "dispersion", 0 }, /* 9 */ - { "rec", 0 }, /* 10 */ - { "reftime", 0 }, /* 11 */ - { "srcport", 0 }, /* 12 */ - { 0, 0 } -}; - -struct varlist peervarlist[] = { - { "srcadr", 0 }, /* 0 */ - { "refid", 0 }, /* 1 */ - { "stratum", 0 }, /* 2 */ - { "hpoll", 0 }, /* 3 */ - { "ppoll", 0 }, /* 4 */ - { "reach", 0 }, /* 5 */ - { "delay", 0 }, /* 6 */ - { "offset", 0 }, /* 7 */ - { "jitter", 0 }, /* 8 */ - { "dispersion", 0 }, /* 9 */ - { "rec", 0 }, /* 10 */ - { "reftime", 0 }, /* 11 */ - { "srcport", 0 }, /* 12 */ - { 0, 0 } -}; - -#define HAVE_SRCADR 0 -#define HAVE_DSTADR 1 -#define HAVE_REFID 1 -#define HAVE_STRATUM 2 -#define HAVE_HPOLL 3 -#define HAVE_PPOLL 4 -#define HAVE_REACH 5 -#define HAVE_DELAY 6 -#define HAVE_OFFSET 7 -#define HAVE_JITTER 8 -#define HAVE_DISPERSION 9 -#define HAVE_REC 10 -#define HAVE_REFTIME 11 -#define HAVE_SRCPORT 12 -#define MAXHAVE 13 - -/* - * 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, - char *data, - FILE *fp, - int af - ) -{ - char *name; - char *value = NULL; - int i; - int c; - - struct sockaddr_storage srcadr; - struct sockaddr_storage dstadr; - u_long srcport = 0; - char *dstadr_refid = "0.0.0.0"; - 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); - - memset((char *)&srcadr, 0, sizeof(struct sockaddr_storage)); - memset((char *)&dstadr, 0, sizeof(struct sockaddr_storage)); - - /* 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)) { - struct sockaddr_storage dum_store; - - i = findvar(name, peer_var); - 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); - if (pvl == opeervarlist) { - if (decodenetnum(value, &dstadr)) { - havevar[HAVE_DSTADR] = 1; - dstadr_refid = stoa(&dstadr); - } - } - break; - case CP_REFID: - if (pvl == peervarlist) { - havevar[HAVE_REFID] = 1; - if (*value == '\0') { - dstadr_refid = "0.0.0.0"; - } else if (decodenetnum(value, &dstadr)) { - if (SOCKNUL(&dstadr)) - dstadr_refid = "0.0.0.0"; - else if ((dstadr.ss_family == AF_INET) - && ISREFCLOCKADR(&dstadr)) - dstadr_refid = - refnumtoa(&dstadr); - else - dstadr_refid = - stoa(&dstadr); - } else if ((int)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 { - 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 (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) - (void) fprintf(fp, "%-*s ", maxhostlen, currenthost); - if (af == 0 || srcadr.ss_family == af){ - strcpy(clock_name, nntohost(&srcadr)); - - (void) fprintf(fp, - "%c%-15.15s %-15.15s %2ld %c %4.4s %4.4s %3lo %7.7s %8.7s %7.7s\n", - c, clock_name, dstadr_refid, stratum, type, - prettyinterval(whenbuf, when(&ts, &rec, &reftime)), - prettyinterval(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); -} - -#undef HAVE_SRCADR -#undef HAVE_DSTADR -#undef HAVE_STRATUM -#undef HAVE_PPOLL -#undef HAVE_HPOLL -#undef HAVE_REACH -#undef HAVE_ESTDELAY -#undef HAVE_ESTOFFSET -#undef HAVE_JITTER -#undef HAVE_ESTDISP -#undef HAVE_REFID -#undef HAVE_REC -#undef HAVE_SRCPORT -#undef HAVE_REFTIME -#undef MAXHAVE - - -/* - * dogetpeers - given an association ID, read and print the spreadsheet - * peer variables. - */ -static int -dogetpeers( - struct varlist *pvl, - int associd, - FILE *fp, - int af - ) -{ - char *datap; - int res; - int dsize; - u_short rstatus; - -#ifdef notdef - res = doquerylist(pvl, CTL_OP_READVAR, associd, 0, &rstatus, - &dsize, &datap); -#else - /* - * Damn fuzzballs - */ - res = doquery(CTL_OP_READVAR, associd, 0, 0, (char *)0, &rstatus, - &dsize, &datap); -#endif - - if (res != 0) - return 0; - - if (dsize == 0) { - (void) fprintf(stderr, - "***No information returned for association %d\n", - associd); - return 0; - } - - return doprintpeers(pvl, associd, (int)rstatus, dsize, datap, fp, af); -} - - -/* - * peers - print a peer spreadsheet - */ -static void -dopeers( - int showall, - FILE *fp, - int af - ) -{ - register int i; - char fullname[LENHOSTNAME]; - struct sockaddr_storage 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, "host"); - (void) fprintf(fp, - " remote refid st t when poll reach delay offset jitter\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(peervarlist, (int)assoc_cache[i].assid, fp, af)) { - return; - } - } - return; -} - - -/* - * peers - print a peer spreadsheet - */ -/*ARGSUSED*/ -static void -peers( - struct parse *pcmd, - FILE *fp - ) -{ - int af = 0; - - if (pcmd->nargs == 1) { - if (pcmd->argval->ival == 6) - af = AF_INET6; - else - af = AF_INET; - } - dopeers(0, fp, af); -} - - -/* - * lpeers - print a peer spreadsheet including all fuzzball peers - */ -/*ARGSUSED*/ -static void -lpeers( - struct parse *pcmd, - FILE *fp - ) -{ - int af = 0; - - if (pcmd->nargs == 1) { - if (pcmd->argval->ival == 6) - af = AF_INET6; - else - af = AF_INET; - } - dopeers(1, fp, af); -} - - -/* - * opeers - print a peer spreadsheet - */ -static void -doopeers( - int showall, - FILE *fp, - int af - ) -{ - register int i; - - if (!dogetassoc(fp)) - return; - - (void) fprintf(fp, - " remote local st t when poll reach delay offset disp\n"); - (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; -} - - -/* - * opeers - print a peer spreadsheet the old way - */ -/*ARGSUSED*/ -static void -opeers( - struct parse *pcmd, - FILE *fp - ) -{ - int af = 0; - - if (pcmd->nargs == 1) { - if (pcmd->argval->ival == 6) - af = AF_INET6; - else - af = AF_INET; - } - doopeers(0, fp, af); -} - - -/* - * lopeers - print a peer spreadsheet including all fuzzball peers - */ -/*ARGSUSED*/ -static void -lopeers( - struct parse *pcmd, - FILE *fp - ) -{ - int af = 0; - - if (pcmd->nargs == 1) { - if (pcmd->argval->ival == 6) - af = AF_INET6; - else - af = AF_INET; - } - doopeers(1, fp, af); -} |