⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ntpdc.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * ntpdc - control and monitor your ntpd daemon */#include <stdio.h>#include <ctype.h>#include <signal.h>#include <setjmp.h>#include "ntpdc.h"#include "ntp_select.h"#include "ntp_io.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 now potentially understand a lot of commands (and * it requires a lot of commands to talk to ntpd) we will run * interactive if connected to a terminal. */static	int	interactive = 0;	/* set to 1 when we should prompt */static	const char *	prompt = "ntpdc> ";	/* prompt to ask him about *//* * Keyid used for authenticated requests.  Obtained on the fly. */static	u_long	info_auth_keyid;/* * 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 */int		ntpdcmain	P((int,	char **));/* * Built in command handler declarations */static	int	openhost	P((const char *));static	int	sendpkt		P((char *, int));static	void	growpktdata	P((void));static	int	getresponse	P((int, int, int *, int *, char **, int));static	int	sendrequest	P((int, int, int, int, int, char *));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	getnetnum	P((const char *, struct sockaddr_storage *, char *, int));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	my_delay	P((struct parse *, FILE *));static	void	host		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	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 *));/* * Built-in commands we understand */static	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",	my_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" },	{ "passwd",	passwd,		{ OPT|NTP_STR, 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 ntpdc" },	{ "exit",	quit,		{ NO, NO, NO, NO },	  { "", "", "", "" },	  "exit ntpdc" },	{ "keyid",	keyid,		{ OPT|NTP_UINT, NO, NO, NO },	  { "key#", "", "", "" },	  "set/show keyid to use for authenticated requests" },	{ "keytype",	keytype,	{ OPT|NTP_STR, NO, NO, NO },	  { "(md5|des)", "", "", "" },	  "set/show key authentication type for authenticated requests (des|md5)" },	{ "version",	version,	{ NO, NO, NO, NO },	  { "", "", "", "" },	  "print version number" },	{ 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+1+MAXARGS+2)	/* maximum number of usable tokens */#define	SCREENWIDTH  	78		/* nominal screen width in columns *//* * Some variables used and manipulated locally */static	struct timeval tvout = { DEFTIMEOUT, 0 };	/* time out for reads */static	struct timeval tvsout = { DEFSTIMEOUT, 0 };	/* secondary time out */static	l_fp delay_time;				/* delay time */static	char currenthost[LENHOSTNAME];			/* current host name */int showhostnames = 1;					/* show host names by default */static	int ai_fam_templ;				/* address family */static	int ai_fam_default;				/* default address family */static	SOCKET sockfd;					/* fd socket is opened on */static	int havehost = 0;				/* set to 1 when host open */int s_port = 0;#if defined (SYS_WINNT) || defined (SYS_VXWORKS)char password[9];#endif /* SYS_WINNT || SYS_VXWORKS */#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 *//* * Holds data returned from queries.  We allocate INITDATASIZE * octets to begin with, increasing this as we need to. */#define	INITDATASIZE	(sizeof(struct resp_pkt) * 16)#define	INCDATASIZE	(sizeof(struct resp_pkt) * 8)static	char *pktdata;static	int pktdatasize;/* * These are used to help the magic with old and new versions of ntpd. */int impl_ver = IMPL_XNTPD;static int req_pkt_size = REQ_LEN_NOMAC;/* * For commands typed on the command line (with the -c option) */static	int numcmds = 0;static	const char *ccmds[MAXCMDS];#define	ADDCMD(cp)	if (numcmds < MAXCMDS) ccmds[numcmds++] = (cp)/* * When multiple hosts are specified. */static	int numhosts = 0;static	const char *chosts[MAXHOSTS];#define	ADDHOST(cp)	if (numhosts < MAXHOSTS) chosts[numhosts++] = (cp)/* * Error codes for internal use */#define	ERR_INCOMPLETE		16#define	ERR_TIMEOUT		17/* * 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)/* * For converting time stamps to dates */#define	JAN_1970	2208988800	/* 1970 - 1900 in seconds *//* * Jump buffer for longjumping back to the command level */static	jmp_buf interrupt_buf;static  volatile int jump = 0;/* * Pointer to current output unit */static	FILE *current_output;/* * Command table imported from ntpdc_ops.c */extern struct xcmd opcmds[];char *progname;volatile int debug;#ifdef NO_MAIN_ALLOWEDCALL(ntpdc,"ntpdc",ntpdcmain);#elseintmain(	int argc,	char *argv[]	){	return ntpdcmain(argc, argv);}#endif#ifdef SYS_VXWORKSvoid clear_globals(void){    extern int ntp_optind;    extern char *ntp_optarg;    showhostnames = 0;              /* show host names by default */    ntp_optind = 0;    ntp_optarg = 0;    havehost = 0;                   /* set to 1 when host open */    numcmds = 0;    numhosts = 0;}#endif/* * main - parse arguments and handle options */intntpdcmain(	int argc,	char *argv[]	){	int c;	int errflg = 0;	extern int ntp_optind;	extern char *ntp_optarg;	delay_time.l_ui = 0;	delay_time.l_uf = DEFDELAY;#ifdef SYS_VXWORKS	clear_globals();	taskPrioritySet(taskIdSelf(), 100 );#endif#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:dilnps")) != 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 'l':		    ADDCMD("listpeers");		    break;		case 'n':		    showhostnames = 0;		    break;		case 'p':		    ADDCMD("peers");		    break;		case 's':		    ADDCMD("dmpeers");		    break;		default:		    errflg++;		    break;	    }	if (errflg) {		(void) fprintf(stderr,			       "usage: %s [-46dilnps] [-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 */	/*	 * Initialize the packet data buffer	 */	pktdata = (char *)malloc(INITDATASIZE);	if (pktdata == NULL) {		(void) fprintf(stderr, "%s: malloc() failed!\n", progname);		exit(1);	}	pktdatasize = INITDATASIZE;	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++) {				    if (numhosts > 1) 					printf ("--- %s ---\n",chosts[ihost]);				    docmd(ccmds[icmd]);			    }		}	}#ifdef SYS_WINNT	WSACleanup();#endif	return(0);} /* main end *//* * 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;	}		/*	 * First try to resolve it as an ip address and if that fails,	 * do a fullblown (dns) lookup. That way we only use the dns	 * when it is needed and work around some implementations that	 * will return an "IPv4-mapped IPv6 address" address if you	 * give it an IPv4 address to lookup.	 */	strcpy(service, "ntp");	memset((char *)&hints, 0, sizeof(struct addrinfo));	hints.ai_family = ai_fam_templ;	hints.ai_protocol = IPPROTO_UDP;	hints.ai_socktype = SOCK_DGRAM;	hints.ai_flags = AI_NUMERICHOST;	a_info = getaddrinfo(hname, service, &hints, &ai);	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(hname, service, &hints, &ai);		}	/* Some older implementations don't like AI_ADDRCONFIG. */	if (a_info == EAI_BADFLAGS) {		hints.ai_flags = AI_CANONNAME;		a_info = getaddrinfo(hname, service, &hints, &ai);		}	if (a_info != 0) {		(void) fprintf(stderr, "%s\n", gai_strerror(a_info));		return 0;	}	if (ai->ai_canonname == NULL) {		strncpy(temphost, stoa((struct sockaddr_storage *)ai->ai_addr),		    LENHOSTNAME);		temphost[LENHOSTNAME-1] = '\0';	} else {		strncpy(temphost, ai->ai_canonname, LENHOSTNAME);		temphost[LENHOSTNAME-1] = '\0';	}	if (debug > 2)	    printf("Opening host %s\n", temphost);	if (havehost == 1) {		if (debug > 2)		    printf("Closing old host %s\n", currenthost);		(void) closesocket(sockfd);		havehost = 0;	}	(void) strcpy(currenthost, temphost);		/* port maps to the same in both families */	s_port = ((struct sockaddr_in6 *)ai->ai_addr)->sin6_port; #ifdef SYS_VXWORKS	((struct sockaddr_in6 *)&hostaddr)->sin6_port = htons(SERVER_PORT_NUM);	if (ai->ai_family == AF_INET)		*(struct sockaddr_in *)&hostaddr= 			*((struct sockaddr_in *)ai->ai_addr);	else 		*(struct sockaddr_in6 *)&hostaddr= 			*((struct sockaddr_in6 *)ai->ai_addr);#endif /* SYS_VXWORKS */#ifdef SYS_WINNT	{		int optionValue = SO_SYNCHRONOUS_NONALERT;		int err;		err = setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *)&optionValue, sizeof(optionValue));		if (err != NO_ERROR) {			(void) fprintf(stderr, "cannot open nonoverlapped sockets\n");			exit(1);		}	}	sockfd = socket(ai->ai_family, SOCK_DGRAM, 0);	if (sockfd == INVALID_SOCKET) {		error("socket", "", "");		exit(-1);	}#else	sockfd = socket(ai->ai_family, SOCK_DGRAM, 0);	if (sockfd == -1)	    error("socket", "", "");#endif /* SYS_WINNT */	#ifdef NEED_RCVBUF_SLOP# ifdef SO_RCVBUF	{		int rbufsize = INITDATASIZE + 2048; /* 2K for slop */		if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF,			       &rbufsize, sizeof(int)) == -1)		    error("setsockopt", "", "");	}# endif#endif#ifdef SYS_VXWORKS	if (connect(sockfd, (struct sockaddr *)&hostaddr, 		    sizeof(hostaddr)) == -1)#else	if (connect(sockfd, (struct sockaddr *)ai->ai_addr,		    ai->ai_addrlen) == -1)#endif /* SYS_VXWORKS */	    error("connect", "", "");	if (a_info)		freeaddrinfo(ai);	havehost = 1;	req_pkt_size = REQ_LEN_NOMAC;	impl_ver = IMPL_XNTPD;	return 1;}/* XXX ELIMINATE sendpkt similar in ntpq.c, ntpdc.c, ntp_io.c, ntptrace.c *//* * sendpkt - send a packet to the remote host */static intsendpkt(	char *xdata,	int xdatalen	){	if (send(sockfd, xdata, (size_t)xdatalen, 0) == -1) {		warning("write to %s failed", currenthost, "");		return -1;	}	return 0;}/* * growpktdata - grow the packet data area */static voidgrowpktdata(void){	pktdatasize += INCDATASIZE;	pktdata = (char *)realloc(pktdata, (unsigned)pktdatasize);	if (pktdata == 0) {		(void) fprintf(stderr, "%s: realloc() failed!\n", progname);		exit(1);	}}/* * getresponse - get a (series of) response packet(s) and return the data */static intgetresponse(	int implcode,	int reqcode,	int *ritems,	int *rsize,	char **rdata,	int esize	){	struct resp_pkt rpkt;	struct timeval tvo;	int items;	int i;	int size;	int datasize;	char *datap;	char *tmp_data;	char haveseq[MAXSEQ+1];	int firstpkt;	int lastseq;	int numrecv;	int seq;	fd_set fds;	int n;	int pad;	/*	 * This is pretty tricky.  We may get between 1 and many packets	 * back in response to the request.  We peel the data out of	 * each packet and collect it in one long block.  When the last	 * packet in the sequence is received we'll know how many we	 * should have had.  Note we use one long time out, should reconsider.	 */	*ritems = 0;	*rsize = 0;	firstpkt = 1;	numrecv = 0;	*rdata = datap = pktdata;	lastseq = 999;	/* too big to be a sequence number */	memset(haveseq, 0, sizeof(haveseq));	FD_ZERO(&fds);    again:	if (firstpkt)	    tvo = tvout;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -