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

📄 ntp_control.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 5 页
字号:
				    (u_int32)clock_stat->fudgeval2, NULL);			else				ctl_putid(clock_var[CC_FUDGEVAL2].text,				    (char *)&clock_stat->fudgeval2);		}		break;	case CC_FLAGS:		if (mustput || (clock_stat->haveflags &	(CLK_HAVEFLAG1 |		    CLK_HAVEFLAG2 | CLK_HAVEFLAG3 | CLK_HAVEFLAG4)))			ctl_putuint(clock_var[CC_FLAGS].text,			    clock_stat->flags);		break;	case CC_DEVICE:		if (clock_stat->clockdesc == NULL ||		    *(clock_stat->clockdesc) == '\0') {			if (mustput)				ctl_putstr(clock_var[CC_DEVICE].text,				    "", 0);		} else {			ctl_putstr(clock_var[CC_DEVICE].text,			    clock_stat->clockdesc,			    strlen(clock_stat->clockdesc));		}		break;	case CC_VARLIST:		{			char buf[CTL_MAX_DATA_LEN];			register char *s, *t, *be;			register const char *ss;			register int i;			register struct ctl_var *k;			s = buf;			be = buf + sizeof(buf);			if (s + strlen(clock_var[CC_VARLIST].text) + 4 >			    be)				break;	/* really long var name */			strcpy(s, clock_var[CC_VARLIST].text);			strcat(s, "=\"");			s += strlen(s);			t = s;			for (k = clock_var; !(k->flags &EOV); k++) {				if (k->flags & PADDING)					continue;				i = strlen(k->text);				if (s + i + 1 >= be)					break;				if (s != t)				*s++ = ',';				strcpy(s, k->text);				s += i;			}			for (k = clock_stat->kv_list; k && !(k->flags &			    EOV); k++) {				if (k->flags & PADDING)					continue;				ss = k->text;				if (!ss)					continue;				while (*ss && *ss != '=')					ss++;				i = ss - k->text;				if (s+i+1 >= be)					break;				if (s != t)					*s++ = ',';				strncpy(s, k->text, (unsigned)i);				s += i;				*s = '\0';			}			if (s+2 >= be)				break;			*s++ = '"';			*s = '\0';			ctl_putdata(buf, (unsigned)( s - buf ), 0);		}		break;	}}#endif/* * ctl_getitem - get the next data item from the incoming packet */static struct ctl_var *ctl_getitem(	struct ctl_var *var_list,	char **data	){	register struct ctl_var *v;	register char *cp;	register char *tp;	static struct ctl_var eol = { 0, EOV, };	static char buf[128];	/*	 * Delete leading commas and white space	 */	while (reqpt < reqend && (*reqpt == ',' ||	    isspace((unsigned char)*reqpt)))		reqpt++;	if (reqpt >= reqend)		return (0);	if (var_list == (struct ctl_var *)0)		return (&eol);	/*	 * Look for a first character match on the tag.  If we find	 * one, see if it is a full match.	 */	v = var_list;	cp = reqpt;	while (!(v->flags & EOV)) {		if (!(v->flags & PADDING) && *cp == *(v->text)) {			tp = v->text;			while (*tp != '\0' && *tp != '=' && cp <			    reqend && *cp == *tp) {				cp++;				tp++;			}			if ((*tp == '\0') || (*tp == '=')) {				while (cp < reqend && isspace((unsigned char)*cp))					cp++;				if (cp == reqend || *cp == ',') {					buf[0] = '\0';					*data = buf;					if (cp < reqend)						cp++;					reqpt = cp;					return v;				}				if (*cp == '=') {					cp++;					tp = buf;					while (cp < reqend && isspace((unsigned char)*cp))						cp++;					while (cp < reqend && *cp != ',') {						*tp++ = *cp++;						if (tp >= buf + sizeof(buf)) {							ctl_error(CERR_BADFMT);							numctlbadpkts++;#if 0	/* Avoid possible DOS attack *//* If we get a smarter msyslog we can re-enable this */							msyslog(LOG_WARNING,		"Possible 'ntpdx' exploit from %s:%d (possibly spoofed)\n",		stoa(rmt_addr), SRCPORT(rmt_addr)								);#endif							return (0);						}					}					if (cp < reqend)						cp++;					*tp-- = '\0';					while (tp >= buf) {						if (!isspace((unsigned int)(*tp)))							break;						*tp-- = '\0';					}					reqpt = cp;					*data = buf;					return (v);				}			}			cp = reqpt;		}		v++;	}	return v;}/* * control_unspec - response to an unspecified op-code *//*ARGSUSED*/static voidcontrol_unspec(	struct recvbuf *rbufp,	int restrict_mask	){	struct peer *peer;	/*	 * What is an appropriate response to an unspecified op-code?	 * I return no errors and no data, unless a specified assocation	 * doesn't exist.	 */	if (res_associd != 0) {		if ((peer = findpeerbyassoc(res_associd)) == 0) {			ctl_error(CERR_BADASSOC);			return;		}		rpkt.status = htons(ctlpeerstatus(peer));	} else {		rpkt.status = htons(ctlsysstatus());	}	ctl_flushpkt(0);}/* * read_status - return either a list of associd's, or a particular * peer's status. *//*ARGSUSED*/static voidread_status(	struct recvbuf *rbufp,	int restrict_mask	){	register int i;	register struct peer *peer;	u_short ass_stat[CTL_MAX_DATA_LEN / sizeof(u_short)];#ifdef DEBUG	if (debug > 2)		printf("read_status: ID %d\n", res_associd);#endif	/*	 * Two choices here. If the specified association ID is	 * zero we return all known assocation ID's.  Otherwise	 * we return a bunch of stuff about the particular peer.	 */	if (res_associd == 0) {		register int n;		n = 0;		rpkt.status = htons(ctlsysstatus());		for (i = 0; i < NTP_HASH_SIZE; i++) {			for (peer = assoc_hash[i]; peer != 0;				peer = peer->ass_next) {				ass_stat[n++] = htons(peer->associd);				ass_stat[n++] =				    htons(ctlpeerstatus(peer));				if (n ==				    CTL_MAX_DATA_LEN/sizeof(u_short)) {					ctl_putdata((char *)ass_stat,					    n * sizeof(u_short), 1);					n = 0;				}			}		}		if (n != 0)			ctl_putdata((char *)ass_stat, n *			    sizeof(u_short), 1);		ctl_flushpkt(0);	} else {		peer = findpeerbyassoc(res_associd);		if (peer == 0) {			ctl_error(CERR_BADASSOC);		} else {			register u_char *cp;			rpkt.status = htons(ctlpeerstatus(peer));			if (res_authokay)				peer->num_events = 0;			/*			 * For now, output everything we know about the			 * peer. May be more selective later.			 */			for (cp = def_peer_var; *cp != 0; cp++)				ctl_putpeer((int)*cp, peer);			ctl_flushpkt(0);		}	}}/* * read_variables - return the variables the caller asks for *//*ARGSUSED*/static voidread_variables(	struct recvbuf *rbufp,	int restrict_mask	){	register struct ctl_var *v;	register int i;	char *valuep;	u_char *wants;	unsigned int gotvar = (CS_MAXCODE > CP_MAXCODE) ? (CS_MAXCODE +	    1) : (CP_MAXCODE + 1);	if (res_associd == 0) {		/*		 * Wants system variables. Figure out which he wants		 * and give them to him.		 */		rpkt.status = htons(ctlsysstatus());		if (res_authokay)			ctl_sys_num_events = 0;		gotvar += count_var(ext_sys_var);		wants = (u_char *)emalloc(gotvar);		memset((char *)wants, 0, gotvar);		gotvar = 0;		while ((v = ctl_getitem(sys_var, &valuep)) != 0) {			if (v->flags & EOV) {				if ((v = ctl_getitem(ext_sys_var,				    &valuep)) != 0) {					if (v->flags & EOV) {						ctl_error(CERR_UNKNOWNVAR);						free((char *)wants);						return;					}					wants[CS_MAXCODE + 1 +					    v->code] = 1;					gotvar = 1;					continue;				} else {					break; /* shouldn't happen ! */				}			}			wants[v->code] = 1;			gotvar = 1;		}		if (gotvar) {			for (i = 1; i <= CS_MAXCODE; i++)				if (wants[i])					ctl_putsys(i);			for (i = 0; ext_sys_var &&			    !(ext_sys_var[i].flags & EOV); i++)				if (wants[i + CS_MAXCODE + 1])					ctl_putdata(ext_sys_var[i].text,					    strlen(ext_sys_var[i].text),					    0);		} else {			register u_char *cs;			register struct ctl_var *kv;			for (cs = def_sys_var; *cs != 0; cs++)				ctl_putsys((int)*cs);			for (kv = ext_sys_var; kv && !(kv->flags & EOV);			    kv++)				if (kv->flags & DEF)					ctl_putdata(kv->text,					    strlen(kv->text), 0);		}		free((char *)wants);	} else {		register struct peer *peer;		/*		 * Wants info for a particular peer. See if we know		 * the guy.		 */		peer = findpeerbyassoc(res_associd);		if (peer == 0) {			ctl_error(CERR_BADASSOC);			return;		}		rpkt.status = htons(ctlpeerstatus(peer));		if (res_authokay)			peer->num_events = 0;		wants = (u_char *)emalloc(gotvar);		memset((char*)wants, 0, gotvar);		gotvar = 0;		while ((v = ctl_getitem(peer_var, &valuep)) != 0) {			if (v->flags & EOV) {				ctl_error(CERR_UNKNOWNVAR);				free((char *)wants);				return;			}			wants[v->code] = 1;			gotvar = 1;		}		if (gotvar) {			for (i = 1; i <= CP_MAXCODE; i++)				if (wants[i])					ctl_putpeer(i, peer);		} else {			register u_char *cp;			for (cp = def_peer_var; *cp != 0; cp++)				ctl_putpeer((int)*cp, peer);		}		free((char *)wants);	}	ctl_flushpkt(0);}/* * write_variables - write into variables. We only allow leap bit * writing this way. *//*ARGSUSED*/static voidwrite_variables(	struct recvbuf *rbufp,	int restrict_mask	){	register struct ctl_var *v;	register int ext_var;	char *valuep;	long val = 0;	/*	 * If he's trying to write into a peer tell him no way	 */	if (res_associd != 0) {		ctl_error(CERR_PERMISSION);		return;	}	/*	 * Set status	 */	rpkt.status = htons(ctlsysstatus());	/*	 * Look through the variables. Dump out at the first sign of	 * trouble.	 */	while ((v = ctl_getitem(sys_var, &valuep)) != 0) {		ext_var = 0;		if (v->flags & EOV) {			if ((v = ctl_getitem(ext_sys_var, &valuep)) !=			    0) {				if (v->flags & EOV) {					ctl_error(CERR_UNKNOWNVAR);					return;				}				ext_var = 1;			} else {				break;			}		}		if (!(v->flags & CAN_WRITE)) {			ctl_error(CERR_PERMISSION);			return;		}		if (!ext_var && (*valuep == '\0' || !atoint(valuep,		    &val))) {			ctl_error(CERR_BADFMT);			return;		}		if (!ext_var && (val & ~LEAP_NOTINSYNC) != 0) {			ctl_error(CERR_BADVALUE);			return;		}		if (ext_var) {			char *s = (char *)emalloc(strlen(v->text) +			    strlen(valuep) + 2);			const char *t;			char *tt = s;			t = v->text;			while (*t && *t != '=')				*tt++ = *t++;			*tt++ = '=';			strcat(tt, valuep);			set_sys_var(s, strlen(s)+1, v->flags);			free(s);		} else {			/*			 * This one seems sane. Save it.			 */			switch(v->code) {			case CS_LEAP:			default:				ctl_error(CERR_UNSPEC); /* really */				return;			}		}	}	/*	 * If we got anything, do it. xxx nothing to do ***	 */	/*	  if (leapind != ~0 || leapwarn != ~0) {	  	if (!leap_setleap((int)leapind, (int)leapwarn)) {	  		ctl_error(CERR_PERMISSION);	  		return;	  	}	  }	*/	ctl_flushpkt(0);}/* * read_clock_status - return clock radio status *//*ARGSUSED*/static voidread_clock_status(	struct recvbuf *rbufp,	int restrict_mask	){#ifndef REFCLOCK	/*	 * If no refclock support, no data to return	 */	ctl_error(CERR_BADASSOC);#else	register struct ctl_var *v;	register int i;	register struct peer *peer;	char *valuep;	u_char *wants;	unsigned int gotvar;	struct refclockstat clock_stat;	if (res_associd == 0) {		/*		 * Find a clock for this jerk.	If the system peer		 * is a clock use it, else search the hash tables		 * for one.		 */		if (sys_peer != 0 && (sys_peer->flags & FLAG_REFCLOCK))		    {			peer = sys_peer;		} else {			peer = 0;			for (i = 0; peer == 0 && i < NTP_HASH_SIZE; i++) {				for (peer = assoc_hash[i]; peer != 0;					peer = peer->ass_next) {					if (peer->flags & FLAG_REFCLOCK)						break;				}			}			if (peer == 0) {				ctl_error(CERR_BADASSOC);				return;			}		}	} else {		peer = findpeerbyassoc(res_associd);		if (peer == 0 || !(peer->flags & FLAG_REFCLOCK)) {			ctl_error(CERR_BADASSOC);			return;		}	}	/*	 * If we got here we have a peer which is a clock. Get his	 * status.	 */	clock_stat.kv_list = (struct ctl_var *)0;	refclock_control(&peer->srcadr, (struct refclockstat *)0,	    &clock_stat);	/*	 * Look for variables in the packet.	 */	rpkt.status = htons(ctlclkstatus(&clock_stat));	gotvar = CC_MAXCODE + 1 + count_var(clock_stat.kv_list);	wants = (u_char *)emalloc(gotvar);	memset((char*)wants, 0, gotvar);	gotvar = 0;	while ((v = ctl_getitem(clock_var, &valuep)) != 0) {		if (v->flags & EOV) {			if ((v = ctl_getitem(clock_stat.kv_list,			    &valuep)) != 0) {				if (v->flags & EOV) {					ctl_error(CERR_UNKNOWNVAR);					free((char*)wants);					free_varlist(clock_stat.kv_list);					return;				}				wants[CC_MAXCODE + 1 + v->code] = 1;				gotvar = 1;				continue;			} else {				break; /* shouldn't happen ! */			}		}		wants[v->code] = 1;		gotvar = 1;	}

⌨️ 快捷键说明

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