📄 ntp_control.c
字号:
if (gotvar) { for (i = 1; i <= CC_MAXCODE; i++) if (wants[i]) ctl_putclock(i, &clock_stat, 1); for (i = 0; clock_stat.kv_list && !(clock_stat.kv_list[i].flags & EOV); i++) if (wants[i + CC_MAXCODE + 1]) ctl_putdata(clock_stat.kv_list[i].text, strlen(clock_stat.kv_list[i].text), 0); } else { register u_char *cc; register struct ctl_var *kv; for (cc = def_clock_var; *cc != 0; cc++) ctl_putclock((int)*cc, &clock_stat, 0); for (kv = clock_stat.kv_list; kv && !(kv->flags & EOV); kv++) if (kv->flags & DEF) ctl_putdata(kv->text, strlen(kv->text), 0); } free((char*)wants); free_varlist(clock_stat.kv_list); ctl_flushpkt(0);#endif}/* * write_clock_status - we don't do this *//*ARGSUSED*/static voidwrite_clock_status( struct recvbuf *rbufp, int restrict_mask ){ ctl_error(CERR_PERMISSION);}/* * Trap support from here on down. We send async trap messages when the * upper levels report trouble. Traps can by set either by control * messages or by configuration. *//* * set_trap - set a trap in response to a control message */static voidset_trap( struct recvbuf *rbufp, int restrict_mask ){ int traptype; /* * See if this guy is allowed */ if (restrict_mask & RES_NOTRAP) { ctl_error(CERR_PERMISSION); return; } /* * Determine his allowed trap type. */ traptype = TRAP_TYPE_PRIO; if (restrict_mask & RES_LPTRAP) traptype = TRAP_TYPE_NONPRIO; /* * Call ctlsettrap() to do the work. Return * an error if it can't assign the trap. */ if (!ctlsettrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype, (int)res_version)) ctl_error(CERR_NORESOURCE); ctl_flushpkt(0);}/* * unset_trap - unset a trap in response to a control message */static voidunset_trap( struct recvbuf *rbufp, int restrict_mask ){ int traptype; /* * We don't prevent anyone from removing his own trap unless the * trap is configured. Note we also must be aware of the * possibility that restriction flags were changed since this * guy last set his trap. Set the trap type based on this. */ traptype = TRAP_TYPE_PRIO; if (restrict_mask & RES_LPTRAP) traptype = TRAP_TYPE_NONPRIO; /* * Call ctlclrtrap() to clear this out. */ if (!ctlclrtrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype)) ctl_error(CERR_BADASSOC); ctl_flushpkt(0);}/* * ctlsettrap - called to set a trap */intctlsettrap( struct sockaddr_storage *raddr, struct interface *linter, int traptype, int version ){ register struct ctl_trap *tp; register struct ctl_trap *tptouse; /* * See if we can find this trap. If so, we only need update * the flags and the time. */ if ((tp = ctlfindtrap(raddr, linter)) != NULL) { switch (traptype) { case TRAP_TYPE_CONFIG: tp->tr_flags = TRAP_INUSE|TRAP_CONFIGURED; break; case TRAP_TYPE_PRIO: if (tp->tr_flags & TRAP_CONFIGURED) return (1); /* don't change anything */ tp->tr_flags = TRAP_INUSE; break; case TRAP_TYPE_NONPRIO: if (tp->tr_flags & TRAP_CONFIGURED) return (1); /* don't change anything */ tp->tr_flags = TRAP_INUSE|TRAP_NONPRIO; break; } tp->tr_settime = current_time; tp->tr_resets++; return (1); } /* * First we heard of this guy. Try to find a trap structure * for him to use, clearing out lesser priority guys if we * have to. Clear out anyone who's expired while we're at it. */ tptouse = NULL; for (tp = ctl_trap; tp < &ctl_trap[CTL_MAXTRAPS]; tp++) { if ((tp->tr_flags & TRAP_INUSE) && !(tp->tr_flags & TRAP_CONFIGURED) && ((tp->tr_settime + CTL_TRAPTIME) > current_time)) { tp->tr_flags = 0; num_ctl_traps--; } if (!(tp->tr_flags & TRAP_INUSE)) { tptouse = tp; } else if (!(tp->tr_flags & TRAP_CONFIGURED)) { switch (traptype) { case TRAP_TYPE_CONFIG: if (tptouse == NULL) { tptouse = tp; break; } if (tptouse->tr_flags & TRAP_NONPRIO && !(tp->tr_flags & TRAP_NONPRIO)) break; if (!(tptouse->tr_flags & TRAP_NONPRIO) && tp->tr_flags & TRAP_NONPRIO) { tptouse = tp; break; } if (tptouse->tr_origtime < tp->tr_origtime) tptouse = tp; break; case TRAP_TYPE_PRIO: if (tp->tr_flags & TRAP_NONPRIO) { if (tptouse == NULL || (tptouse->tr_flags & TRAP_INUSE && tptouse->tr_origtime < tp->tr_origtime)) tptouse = tp; } break; case TRAP_TYPE_NONPRIO: break; } } } /* * If we don't have room for him return an error. */ if (tptouse == NULL) return (0); /* * Set up this structure for him. */ tptouse->tr_settime = tptouse->tr_origtime = current_time; tptouse->tr_count = tptouse->tr_resets = 0; tptouse->tr_sequence = 1; tptouse->tr_addr = *raddr; tptouse->tr_localaddr = linter; tptouse->tr_version = (u_char) version; tptouse->tr_flags = TRAP_INUSE; if (traptype == TRAP_TYPE_CONFIG) tptouse->tr_flags |= TRAP_CONFIGURED; else if (traptype == TRAP_TYPE_NONPRIO) tptouse->tr_flags |= TRAP_NONPRIO; num_ctl_traps++; return (1);}/* * ctlclrtrap - called to clear a trap */intctlclrtrap( struct sockaddr_storage *raddr, struct interface *linter, int traptype ){ register struct ctl_trap *tp; if ((tp = ctlfindtrap(raddr, linter)) == NULL) return (0); if (tp->tr_flags & TRAP_CONFIGURED && traptype != TRAP_TYPE_CONFIG) return (0); tp->tr_flags = 0; num_ctl_traps--; return (1);}/* * ctlfindtrap - find a trap given the remote and local addresses */static struct ctl_trap *ctlfindtrap( struct sockaddr_storage *raddr, struct interface *linter ){ register struct ctl_trap *tp; for (tp = ctl_trap; tp < &ctl_trap[CTL_MAXTRAPS]; tp++) { if ((tp->tr_flags & TRAP_INUSE) && (NSRCPORT(raddr) == NSRCPORT(&tp->tr_addr)) && SOCKCMP(raddr, &tp->tr_addr) && (linter == tp->tr_localaddr) ) return (tp); } return (struct ctl_trap *)NULL;}/* * report_event - report an event to the trappers */voidreport_event( int err, struct peer *peer ){ register int i; /* * Record error code in proper spots, but have mercy on the * log file. */ if (!(err & (PEER_EVENT | CRPT_EVENT))) { if (ctl_sys_num_events < CTL_SYS_MAXEVENTS) ctl_sys_num_events++; if (ctl_sys_last_event != (u_char)err) { NLOG(NLOG_SYSEVENT) msyslog(LOG_INFO, "system event '%s' (0x%02x) status '%s' (0x%02x)", eventstr(err), err, sysstatstr(ctlsysstatus()), ctlsysstatus());#ifdef DEBUG if (debug) printf("report_event: system event '%s' (0x%02x) status '%s' (0x%02x)\n", eventstr(err), err, sysstatstr(ctlsysstatus()), ctlsysstatus());#endif ctl_sys_last_event = (u_char)err; } } else if (peer != 0) { char *src;#ifdef REFCLOCK if (ISREFCLOCKADR(&peer->srcadr)) src = refnumtoa(&peer->srcadr); else#endif src = stoa(&peer->srcadr); peer->last_event = (u_char)(err & ~PEER_EVENT); if (peer->num_events < CTL_PEER_MAXEVENTS) peer->num_events++; NLOG(NLOG_PEEREVENT) msyslog(LOG_INFO, "peer %s event '%s' (0x%02x) status '%s' (0x%02x)", src, eventstr(err), err, peerstatstr(ctlpeerstatus(peer)), ctlpeerstatus(peer));#ifdef DEBUG if (debug) printf( "peer %s event '%s' (0x%02x) status '%s' (0x%02x)\n", src, eventstr(err), err, peerstatstr(ctlpeerstatus(peer)), ctlpeerstatus(peer));#endif } else { msyslog(LOG_ERR, "report_event: err '%s' (0x%02x), no peer", eventstr(err), err);#ifdef DEBUG printf( "report_event: peer event '%s' (0x%02x), no peer\n", eventstr(err), err);#endif return; } /* * If no trappers, return. */ if (num_ctl_traps <= 0) return; /* * Set up the outgoing packet variables */ res_opcode = CTL_OP_ASYNCMSG; res_offset = 0; res_async = 1; res_authenticate = 0; datapt = rpkt.data; dataend = &(rpkt.data[CTL_MAX_DATA_LEN]); if (!(err & PEER_EVENT)) { rpkt.associd = 0; rpkt.status = htons(ctlsysstatus()); /* * For now, put everything we know about system * variables. Don't send crypto strings. */ for (i = 1; i <= CS_MAXCODE; i++) {#ifdef OPENSSL if (i > CS_VARLIST) continue;#endif /* OPENSSL */ ctl_putsys(i); }#ifdef REFCLOCK /* * for clock exception events: add clock variables to * reflect info on exception */ if (err == EVNT_CLOCKEXCPT) { struct refclockstat clock_stat; struct ctl_var *kv; clock_stat.kv_list = (struct ctl_var *)0; refclock_control(&peer->srcadr, (struct refclockstat *)0, &clock_stat); ctl_puthex("refclockstatus", ctlclkstatus(&clock_stat)); for (i = 1; i <= CC_MAXCODE; i++) ctl_putclock(i, &clock_stat, 0); for (kv = clock_stat.kv_list; kv && !(kv->flags & EOV); kv++) if (kv->flags & DEF) ctl_putdata(kv->text, strlen(kv->text), 0); free_varlist(clock_stat.kv_list); }#endif /* REFCLOCK */ } else { rpkt.associd = htons(peer->associd); rpkt.status = htons(ctlpeerstatus(peer)); /* * Dump it all. Later, maybe less. */ for (i = 1; i <= CP_MAXCODE; i++) {#ifdef OPENSSL if (i > CP_VARLIST) continue;#endif /* OPENSSL */ ctl_putpeer(i, peer); }#ifdef REFCLOCK /* * for clock exception events: add clock variables to * reflect info on exception */ if (err == EVNT_PEERCLOCK) { struct refclockstat clock_stat; struct ctl_var *kv; clock_stat.kv_list = (struct ctl_var *)0; refclock_control(&peer->srcadr, (struct refclockstat *)0, &clock_stat); ctl_puthex("refclockstatus", ctlclkstatus(&clock_stat)); for (i = 1; i <= CC_MAXCODE; i++) ctl_putclock(i, &clock_stat, 0); for (kv = clock_stat.kv_list; kv && !(kv->flags & EOV); kv++) if (kv->flags & DEF) ctl_putdata(kv->text, strlen(kv->text), 0); free_varlist(clock_stat.kv_list); }#endif /* REFCLOCK */ } /* * We're done, return. */ ctl_flushpkt(0);}/* * ctl_clr_stats - clear stat counters */voidctl_clr_stats(void){ ctltimereset = current_time; numctlreq = 0; numctlbadpkts = 0; numctlresponses = 0; numctlfrags = 0; numctlerrors = 0; numctlfrags = 0; numctltooshort = 0; numctlinputresp = 0; numctlinputfrag = 0; numctlinputerr = 0; numctlbadoffset = 0; numctlbadversion = 0; numctldatatooshort = 0; numctlbadop = 0; numasyncmsgs = 0;}static u_longcount_var( struct ctl_var *k ){ register u_long c; if (!k) return (0); c = 0; while (!(k++->flags & EOV)) c++; return (c);}char *add_var( struct ctl_var **kv, u_long size, u_short def ){ register u_long c; register struct ctl_var *k; c = count_var(*kv); k = *kv; *kv = (struct ctl_var *)emalloc((c+2)*sizeof(struct ctl_var)); if (k) { memmove((char *)*kv, (char *)k, sizeof(struct ctl_var)*c); free((char *)k); } (*kv)[c].code = (u_short) c; (*kv)[c].text = (char *)emalloc(size); (*kv)[c].flags = def; (*kv)[c+1].code = 0; (*kv)[c+1].text = (char *)0; (*kv)[c+1].flags = EOV; return (char *)(*kv)[c].text;}voidset_var( struct ctl_var **kv, const char *data, u_long size, u_short def ){ register struct ctl_var *k; register const char *s; register const char *t; char *td; if (!data || !size) return; k = *kv; if (k != NULL) { while (!(k->flags & EOV)) { s = data; t = k->text; if (t) { while (*t != '=' && *s - *t == 0) { s++; t++; } if (*s == *t && ((*t == '=') || !*t)) { free((void *)k->text); td = (char *)emalloc(size); memmove(td, data, size); k->text =td; k->flags = def; return; } } else { td = (char *)emalloc(size); memmove(td, data, size); k->text = td; k->flags = def; return; } k++; } } td = add_var(kv, size, def); memmove(td, data, size);}voidset_sys_var( char *data, u_long size, u_short def ){ set_var(&ext_sys_var, data, size, def);}voidfree_varlist( struct ctl_var *kv ){ struct ctl_var *k; if (kv) { for (k = kv; !(k->flags & EOV); k++) free((void *)k->text); free((void *)kv); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -