📄 ntpq.c
字号:
/* * ntpq - query an NTP server using mode 6 commands */#include <stdio.h>#include <ctype.h>#include <signal.h>#include <setjmp.h>#include <sys/types.h>#include <sys/time.h>#include "ntpq.h"#include "ntp_unixtime.h"#include "ntp_calendar.h"#include "ntp_io.h"#include "ntp_select.h"#include "ntp_stdlib.h"/* Don't include ISC's version of IPv6 variables and structures */#define ISC_IPV6_H 1#include "isc/net.h"#include "isc/result.h"#ifdef SYS_WINNT#include <Mswsock.h># include <io.h>#else#define closesocket close#endif /* SYS_WINNT */#if defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDIT)# include <readline/readline.h># include <readline/history.h>#endif /* HAVE_LIBREADLINE || HAVE_LIBEDIT */#ifdef SYS_VXWORKS/* vxWorks needs mode flag -casey*/#define open(name, flags) open(name, flags, 0777)#define SERVER_PORT_NUM 123#endif/* * Because we potentially understand a lot of commands we will run * interactive if connected to a terminal. */int interactive = 0; /* set to 1 when we should prompt */const char *prompt = "ntpq> "; /* prompt to ask him about *//* * Keyid used for authenticated requests. Obtained on the fly. */u_long info_auth_keyid = 0;/* * Type of key md5 */#define KEY_TYPE_MD5 4static int info_auth_keytype = KEY_TYPE_MD5; /* MD5 */u_long current_time; /* needed by authkeys; not used *//* * Flag which indicates we should always send authenticated requests */int always_auth = 0;/* * Flag which indicates raw mode output. */int rawmode = 0;/* * Packet version number we use */u_char pktversion = NTP_OLDVERSION + 1;/* * Don't jump if no set jmp. */volatile int jump = 0;/* * Format values */#define PADDING 0#define TS 1 /* time stamp */#define FL 2 /* l_fp type value */#define FU 3 /* u_fp type value */#define FS 4 /* s_fp type value */#define UI 5 /* unsigned integer value */#define SI 6 /* signed integer value */#define HA 7 /* host address */#define NA 8 /* network address */#define ST 9 /* string value */#define RF 10 /* refid (sometimes string, sometimes not) */#define LP 11 /* leap (print in binary) */#define OC 12 /* integer, print in octal */#define MD 13 /* mode */#define AR 14 /* array of times */#define FX 15 /* test flags */#define EOV 255 /* end of table *//* * System variable values. The array can be indexed by * the variable index to find the textual name. */struct ctl_var sys_var[] = { { 0, PADDING, "" }, /* 0 */ { CS_LEAP, LP, "leap" }, /* 1 */ { CS_STRATUM, UI, "stratum" }, /* 2 */ { CS_PRECISION, SI, "precision" }, /* 3 */ { CS_ROOTDELAY, FS, "rootdelay" }, /* 4 */ { CS_ROOTDISPERSION, FU, "rootdispersion" }, /* 5 */ { CS_REFID, RF, "refid" }, /* 6 */ { CS_REFTIME, TS, "reftime" }, /* 7 */ { CS_POLL, UI, "poll" }, /* 8 */ { CS_PEERID, UI, "peer" }, /* 9 */ { CS_STATE, UI, "state" }, /* 10 */ { CS_OFFSET, FL, "offset" }, /* 11 */ { CS_DRIFT, FS, "frequency" }, /* 12 */ { CS_JITTER, FU, "jitter" }, /* 13 */ { CS_CLOCK, TS, "clock" }, /* 14 */ { CS_PROCESSOR, ST, "processor" }, /* 15 */ { CS_SYSTEM, ST, "system" }, /* 16 */ { CS_VERSION, ST, "version" }, /* 17 */ { CS_STABIL, FS, "stability" }, /* 18 */ { CS_VARLIST, ST, "sys_var_list" }, /* 19 */ { 0, EOV, "" }};/* * Peer variable list */struct ctl_var peer_var[] = { { 0, PADDING, "" }, /* 0 */ { CP_CONFIG, UI, "config" }, /* 1 */ { CP_AUTHENABLE, UI, "authenable" }, /* 2 */ { CP_AUTHENTIC, UI, "authentic" }, /* 3 */ { CP_SRCADR, HA, "srcadr" }, /* 4 */ { CP_SRCPORT, UI, "srcport" }, /* 5 */ { CP_DSTADR, NA, "dstadr" }, /* 6 */ { CP_DSTPORT, UI, "dstport" }, /* 7 */ { CP_LEAP, LP, "leap" }, /* 8 */ { CP_HMODE, MD, "hmode" }, /* 9 */ { CP_STRATUM, UI, "stratum" }, /* 10 */ { CP_PPOLL, UI, "ppoll" }, /* 11 */ { CP_HPOLL, UI, "hpoll" }, /* 12 */ { CP_PRECISION, SI, "precision" }, /* 13 */ { CP_ROOTDELAY, FS, "rootdelay" }, /* 14 */ { CP_ROOTDISPERSION, FU, "rootdispersion" }, /* 15 */ { CP_REFID, RF, "refid" }, /* 16 */ { CP_REFTIME, TS, "reftime" }, /* 17 */ { CP_ORG, TS, "org" }, /* 18 */ { CP_REC, TS, "rec" }, /* 19 */ { CP_XMT, TS, "xmt" }, /* 20 */ { CP_REACH, OC, "reach" }, /* 21 */ { CP_UNREACH, UI, "unreach" }, /* 22 */ { CP_TIMER, UI, "timer" }, /* 23 */ { CP_DELAY, FS, "delay" }, /* 24 */ { CP_OFFSET, FL, "offset" }, /* 25 */ { CP_JITTER, FU, "jitter" }, /* 26 */ { CP_DISPERSION, FU, "dispersion" }, /* 27 */ { CP_KEYID, UI, "keyid" }, /* 28 */ { CP_FILTDELAY, AR, "filtdelay" }, /* 29 */ { CP_FILTOFFSET, AR, "filtoffset" }, /* 30 */ { CP_PMODE, ST, "pmode" }, /* 31 */ { CP_RECEIVED, UI, "received" }, /* 32 */ { CP_SENT, UI, "sent" }, /* 33 */ { CP_FILTERROR, AR, "filtdisp" }, /* 34 */ { CP_FLASH, FX, "flash" }, /* 35 */ { CP_TTL, UI, "ttl" }, /* 36 */ /* * These are duplicate entries so that we can * process deviant version of the ntp protocol. */ { CP_SRCADR, HA, "peeraddr" }, /* 4 */ { CP_SRCPORT, UI, "peerport" }, /* 5 */ { CP_PPOLL, UI, "peerpoll" }, /* 11 */ { CP_HPOLL, UI, "hostpoll" }, /* 12 */ { CP_FILTERROR, AR, "filterror" }, /* 34 */ { 0, EOV, "" }};/* * Clock variable list */struct ctl_var clock_var[] = { { 0, PADDING, "" }, /* 0 */ { CC_TYPE, UI, "type" }, /* 1 */ { CC_TIMECODE, ST, "timecode" }, /* 2 */ { CC_POLL, UI, "poll" }, /* 3 */ { CC_NOREPLY, UI, "noreply" }, /* 4 */ { CC_BADFORMAT, UI, "badformat" }, /* 5 */ { CC_BADDATA, UI, "baddata" }, /* 6 */ { CC_FUDGETIME1, FL, "fudgetime1" }, /* 7 */ { CC_FUDGETIME2, FL, "fudgetime2" }, /* 8 */ { CC_FUDGEVAL1, UI, "stratum" }, /* 9 */ { CC_FUDGEVAL2, RF, "refid" }, /* 10 */ { CC_FLAGS, UI, "flags" }, /* 11 */ { CC_DEVICE, ST, "device" }, /* 12 */ { 0, EOV, "" }};/* * flasher bits */static const char *tstflagnames[] = { "pkt_dup", /* TEST1 */ "pkt_bogus", /* TEST2 */ "pkt_proto", /* TEST3 */ "pkt_denied", /* TEST4 */ "pkt_auth", /* TEST5 */ "pkt_synch", /* TEST6 */ "pkt_dist", /* TEST7 */ "pkt_autokey", /* TEST8 */ "pkt_crypto", /* TEST9 */ "peer_stratum", /* TEST10 */ "peer_dist", /* TEST11 */ "peer_loop", /* TEST12 */ "peer_unfit" /* TEST13 */};int ntpqmain P((int, char **));/* * Built in command handler declarations */static int openhost P((const char *));static int sendpkt P((char *, int));static int getresponse P((int, int, u_short *, int *, char **, int));static int sendrequest P((int, int, int, int, char *));static char * tstflags P((u_long));static void getcmds P((void));static RETSIGTYPE abortcmd P((int));static void docmd P((const char *));static void tokenize P((const char *, char **, int *));static int findcmd P((char *, struct xcmd *, struct xcmd *, struct xcmd **));static int getarg P((char *, int, arg_v *));static int rtdatetolfp P((char *, l_fp *));static int decodearr P((char *, int *, l_fp *));static void help P((struct parse *, FILE *));#ifdef QSORT_USES_VOID_Pstatic int helpsort P((const void *, const void *));#elsestatic int helpsort P((char **, char **));#endifstatic void printusage P((struct xcmd *, FILE *));static void timeout P((struct parse *, FILE *));static void auth_delay P((struct parse *, FILE *));static void host P((struct parse *, FILE *));static void ntp_poll P((struct parse *, FILE *));static void keyid P((struct parse *, FILE *));static void keytype P((struct parse *, FILE *));static void passwd P((struct parse *, FILE *));static void hostnames P((struct parse *, FILE *));static void setdebug P((struct parse *, FILE *));static void quit P((struct parse *, FILE *));static void version P((struct parse *, FILE *));static void raw P((struct parse *, FILE *));static void cooked P((struct parse *, FILE *));static void authenticate P((struct parse *, FILE *));static void ntpversion P((struct parse *, FILE *));static void warning P((const char *, const char *, const char *));static void error P((const char *, const char *, const char *));static u_long getkeyid P((const char *));static void atoascii P((int, char *, char *));static void makeascii P((int, char *, FILE *));static void rawprint P((int, int, char *, int, FILE *));static void startoutput P((void));static void output P((FILE *, char *, char *));static void endoutput P((FILE *));static void outputarr P((FILE *, char *, int, l_fp *));static void cookedprint P((int, int, char *, int, FILE *));#ifdef QSORT_USES_VOID_Pstatic int assoccmp P((const void *, const void *));#elsestatic int assoccmp P((struct association *, struct association *));#endif /* sgi || bsdi *//* * Built-in commands we understand */struct xcmd builtins[] = { { "?", help, { OPT|NTP_STR, NO, NO, NO }, { "command", "", "", "" }, "tell the use and syntax of commands" }, { "help", help, { OPT|NTP_STR, NO, NO, NO }, { "command", "", "", "" }, "tell the use and syntax of commands" }, { "timeout", timeout, { OPT|NTP_UINT, NO, NO, NO }, { "msec", "", "", "" }, "set the primary receive time out" }, { "delay", auth_delay, { OPT|NTP_INT, NO, NO, NO }, { "msec", "", "", "" }, "set the delay added to encryption time stamps" }, { "host", host, { OPT|NTP_STR, OPT|NTP_STR, NO, NO }, { "-4|-6", "hostname", "", "" }, "specify the host whose NTP server we talk to" }, { "poll", ntp_poll, { OPT|NTP_UINT, OPT|NTP_STR, NO, NO }, { "n", "verbose", "", "" }, "poll an NTP server in client mode `n' times" }, { "passwd", passwd, { NO, NO, NO, NO }, { "", "", "", "" }, "specify a password to use for authenticated requests"}, { "hostnames", hostnames, { OPT|NTP_STR, NO, NO, NO }, { "yes|no", "", "", "" }, "specify whether hostnames or net numbers are printed"}, { "debug", setdebug, { OPT|NTP_STR, NO, NO, NO }, { "no|more|less", "", "", "" }, "set/change debugging level" }, { "quit", quit, { NO, NO, NO, NO }, { "", "", "", "" }, "exit ntpq" }, { "exit", quit, { NO, NO, NO, NO }, { "", "", "", "" }, "exit ntpq" }, { "keyid", keyid, { OPT|NTP_UINT, NO, NO, NO }, { "key#", "", "", "" }, "set keyid to use for authenticated requests" }, { "version", version, { NO, NO, NO, NO }, { "", "", "", "" }, "print version number" }, { "raw", raw, { NO, NO, NO, NO }, { "", "", "", "" }, "do raw mode variable output" }, { "cooked", cooked, { NO, NO, NO, NO }, { "", "", "", "" }, "do cooked mode variable output" }, { "authenticate", authenticate, { OPT|NTP_STR, NO, NO, NO }, { "yes|no", "", "", "" }, "always authenticate requests to this server" }, { "ntpversion", ntpversion, { OPT|NTP_UINT, NO, NO, NO }, { "version number", "", "", "" }, "set the NTP version number to use for requests" }, { "keytype", keytype, { OPT|NTP_STR, NO, NO, NO }, { "key type (md5|des)", "", "", "" }, "set key type to use for authenticated requests (des|md5)" }, { 0, 0, { NO, NO, NO, NO }, { "", "", "", "" }, "" }};/* * Default values we use. */#define DEFTIMEOUT (5) /* 5 second time out */#define DEFSTIMEOUT (2) /* 2 second time out after first */#define DEFDELAY 0x51EB852 /* 20 milliseconds, l_fp fraction */#define DEFHOST "localhost" /* default host name */#define LENHOSTNAME 256 /* host name is 256 characters long */#define MAXCMDS 100 /* maximum commands on cmd line */#define MAXHOSTS 200 /* maximum hosts on cmd line */#define MAXLINE 512 /* maximum line length */#define MAXTOKENS (1+MAXARGS+2) /* maximum number of usable tokens */#define MAXVARLEN 256 /* maximum length of a variable name */#define MAXVALLEN 400 /* maximum length of a variable value */#define MAXOUTLINE 72 /* maximum length of an output line */#define SCREENWIDTH 76 /* nominal screen width in columns *//* * Some variables used and manipulated locally */struct timeval tvout = { DEFTIMEOUT, 0 }; /* time out for reads */struct timeval tvsout = { DEFSTIMEOUT, 0 }; /* secondary time out */l_fp delay_time; /* delay time */char currenthost[LENHOSTNAME]; /* current host name */struct sockaddr_in hostaddr = { 0 }; /* host address */int showhostnames = 1; /* show host names by default */int ai_fam_templ; /* address family */int ai_fam_default; /* default address family */SOCKET sockfd; /* fd socket is opened on */int havehost = 0; /* set to 1 when host open */int s_port = 0;struct servent *server_entry = NULL; /* server entry for ntp */#ifdef SYS_WINNTDWORD NumberOfBytesWritten;HANDLE TimerThreadHandle = NULL; /* 1998/06/03 - Used in ntplib/machines.c */void timer(void) { ; }; /* 1998/06/03 - Used in ntplib/machines.c */#endif /* SYS_WINNT *//* * Sequence number used for requests. It is incremented before * it is used. */u_short sequence;/* * Holds data returned from queries. Declare buffer long to be sure of * alignment. */#define MAXFRAGS 24 /* maximum number of fragments */#define DATASIZE (MAXFRAGS*480) /* maximum amount of data */long pktdata[DATASIZE/sizeof(long)];/* * Holds association data for use with the &n operator. */struct association assoc_cache[MAXASSOC];int numassoc = 0; /* number of cached associations *//* * For commands typed on the command line (with the -c option) */int numcmds = 0;const char *ccmds[MAXCMDS];#define ADDCMD(cp) if (numcmds < MAXCMDS) ccmds[numcmds++] = (cp)/* * When multiple hosts are specified. */int numhosts = 0;const char *chosts[MAXHOSTS];#define ADDHOST(cp) if (numhosts < MAXHOSTS) chosts[numhosts++] = (cp)/* * Error codes for internal use */#define ERR_UNSPEC 256#define ERR_INCOMPLETE 257#define ERR_TIMEOUT 258#define ERR_TOOMUCH 259/* * Macro definitions we use */#define ISSPACE(c) ((c) == ' ' || (c) == '\t')#define ISEOL(c) ((c) == '\n' || (c) == '\r' || (c) == '\0')#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)/* * Jump buffer for longjumping back to the command level */jmp_buf interrupt_buf;/* * Points at file being currently printed into */FILE *current_output;/* * Command table imported from ntpdc_ops.c */extern struct xcmd opcmds[];char *progname;volatile int debug;#ifdef NO_MAIN_ALLOWEDCALL(ntpq,"ntpq",ntpqmain);void clear_globals(void){ extern int ntp_optind; extern char *ntp_optarg; showhostnames = 0; /* don'tshow host names by default */ ntp_optind = 0; ntp_optarg = 0; server_entry = NULL; /* server entry for ntp */ havehost = 0; /* set to 1 when host open */ numassoc = 0; /* number of cached associations */ numcmds = 0; numhosts = 0;}#endif/* * main - parse arguments and handle options */#ifndef NO_MAIN_ALLOWEDintmain( int argc, char *argv[] ){ return ntpqmain(argc, argv);}#endifintntpqmain( int argc, char *argv[] ){ int c; int errflg = 0; extern int ntp_optind; extern char *ntp_optarg;#ifdef SYS_VXWORKS clear_globals(); taskPrioritySet(taskIdSelf(), 100 );#endif delay_time.l_ui = 0; delay_time.l_uf = DEFDELAY;#ifdef SYS_WINNT if (!Win32InitSockets()) { fprintf(stderr, "No useable winsock.dll:"); exit(1); }#endif /* SYS_WINNT */ /* Check to see if we have IPv6. Otherwise force the -4 flag */ if (isc_net_probeipv6() != ISC_R_SUCCESS) { ai_fam_default = AF_INET; } progname = argv[0]; ai_fam_templ = ai_fam_default; while ((c = ntp_getopt(argc, argv, "46c:dinp")) != EOF) switch (c) { case '4': ai_fam_templ = AF_INET; break; case '6': ai_fam_templ = AF_INET6; break; case 'c': ADDCMD(ntp_optarg); break; case 'd': ++debug; break; case 'i': interactive = 1; break; case 'n': showhostnames = 0; break; case 'p': ADDCMD("peers"); break; default: errflg++; break; } if (errflg) { (void) fprintf(stderr, "usage: %s [-46dinp] [-c cmd] host ...\n", progname); exit(2); } if (ntp_optind == argc) { ADDHOST(DEFHOST); } else { for (; ntp_optind < argc; ntp_optind++) ADDHOST(argv[ntp_optind]); } if (numcmds == 0 && interactive == 0 && isatty(fileno(stdin)) && isatty(fileno(stderr))) { interactive = 1; }#ifndef SYS_WINNT /* Under NT cannot handle SIGINT, WIN32 spawns a handler */ if (interactive) (void) signal_no_reset(SIGINT, abortcmd);#endif /* SYS_WINNT */ if (numcmds == 0) { (void) openhost(chosts[0]); getcmds(); } else { int ihost; int icmd; for (ihost = 0; ihost < numhosts; ihost++) { if (openhost(chosts[ihost])) for (icmd = 0; icmd < numcmds; icmd++) docmd(ccmds[icmd]); } }#ifdef SYS_WINNT WSACleanup();#endif /* SYS_WINNT */ return 0;}/* * openhost - open a socket to a host */static intopenhost( const char *hname ){ char temphost[LENHOSTNAME]; int a_info, i; struct addrinfo hints, *ai = NULL; register const char *cp; char name[LENHOSTNAME]; char service[5]; /* * We need to get by the [] if they were entered */ cp = hname; if(*cp == '[') { cp++; for(i = 0; *cp != ']'; cp++, i++) name[i] = *cp; name[i] = '\0'; hname = name; } /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -