📄 ntp_control.c
字号:
return; } /* * Pull enough data from the packet to make intelligent * responses */ rpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, res_version, MODE_CONTROL); res_opcode = pkt->r_m_e_op; rpkt.sequence = pkt->sequence; rpkt.associd = pkt->associd; rpkt.status = 0; res_offset = 0; res_associd = htons(pkt->associd); res_async = 0; res_authenticate = 0; res_keyid = 0; res_authokay = 0; req_count = (int)htons(pkt->count); datanotbinflag = 0; datalinelen = 0; datapt = rpkt.data; dataend = &(rpkt.data[CTL_MAX_DATA_LEN]); /* * We're set up now. Make sure we've got at least enough * incoming data space to match the count. */ req_data = rbufp->recv_length - CTL_HEADER_LEN; if (req_data < req_count || rbufp->recv_length & 0x3) { ctl_error(CERR_BADFMT); numctldatatooshort++; return; } properlen = req_count + CTL_HEADER_LEN;#ifdef DEBUG if (debug > 2 && (rbufp->recv_length & 0x3) != 0) printf("Packet length %d unrounded\n", rbufp->recv_length);#endif /* round up proper len to a 8 octet boundary */ properlen = (properlen + 7) & ~7; maclen = rbufp->recv_length - properlen; if ((rbufp->recv_length & (sizeof(u_long) - 1)) == 0 && maclen >= MIN_MAC_LEN && maclen <= MAX_MAC_LEN && sys_authenticate) { res_authenticate = 1; res_keyid = ntohl(*(u_int32 *)((u_char *)pkt + properlen));#ifdef DEBUG if (debug > 2) printf( "recv_len %d, properlen %d, wants auth with keyid %08x, MAC length=%d\n", rbufp->recv_length, properlen, res_keyid, maclen);#endif if (!authistrusted(res_keyid)) {#ifdef DEBUG if (debug > 2) printf("invalid keyid %08x\n", res_keyid);#endif } else if (authdecrypt(res_keyid, (u_int32 *)pkt, rbufp->recv_length - maclen, maclen)) {#ifdef DEBUG if (debug > 2) printf("authenticated okay\n");#endif res_authokay = 1; } else {#ifdef DEBUG if (debug > 2) printf("authentication failed\n");#endif res_keyid = 0; } } /* * Set up translate pointers */ reqpt = (char *)pkt->data; reqend = reqpt + req_count; /* * Look for the opcode processor */ for (cc = control_codes; cc->control_code != NO_REQUEST; cc++) { if (cc->control_code == res_opcode) {#ifdef DEBUG if (debug > 2) printf("opcode %d, found command handler\n", res_opcode);#endif if (cc->flags == AUTH && (!res_authokay || res_keyid != ctl_auth_keyid)) { ctl_error(CERR_PERMISSION); return; } (cc->handler)(rbufp, restrict_mask); return; } } /* * Can't find this one, return an error. */ numctlbadop++; ctl_error(CERR_BADOP); return;}/* * ctlpeerstatus - return a status word for this peer */u_shortctlpeerstatus( register struct peer *peer ){ register u_short status; status = peer->status; if (peer->flags & FLAG_CONFIG) status |= CTL_PST_CONFIG; if (peer->flags & FLAG_AUTHENABLE) status |= CTL_PST_AUTHENABLE; if (peer->flags & FLAG_AUTHENTIC) status |= CTL_PST_AUTHENTIC; if (peer->reach != 0) status |= CTL_PST_REACH; return (u_short)CTL_PEER_STATUS(status, peer->num_events, peer->last_event);}/* * ctlclkstatus - return a status word for this clock */#ifdef REFCLOCKstatic u_shortctlclkstatus( struct refclockstat *this_clock ){ return ((u_short)(((this_clock->currentstatus) << 8) | (this_clock->lastevent)));}#endif/* * ctlsysstatus - return the system status word */u_shortctlsysstatus(void){ register u_char this_clock; this_clock = CTL_SST_TS_UNSPEC;#ifdef REFCLOCK if (sys_peer != 0) { if (sys_peer->sstclktype != CTL_SST_TS_UNSPEC) { this_clock = sys_peer->sstclktype; if (pps_control) this_clock |= CTL_SST_TS_PPS; } else { if (sys_peer->refclktype < sizeof(clocktypes)) this_clock = clocktypes[sys_peer->refclktype]; if (pps_control) this_clock |= CTL_SST_TS_PPS; } }#endif /* REFCLOCK */ return (u_short)CTL_SYS_STATUS(sys_leap, this_clock, ctl_sys_num_events, ctl_sys_last_event);}/* * ctl_flushpkt - write out the current packet and prepare * another if necessary. */static voidctl_flushpkt( int more ){ int dlen; int sendlen; if (!more && datanotbinflag) { /* * Big hack, output a trailing \r\n */ *datapt++ = '\r'; *datapt++ = '\n'; } dlen = datapt - (u_char *)rpkt.data; sendlen = dlen + CTL_HEADER_LEN; /* * Pad to a multiple of 32 bits */ while (sendlen & 0x3) { *datapt++ = '\0'; sendlen++; } /* * Fill in the packet with the current info */ rpkt.r_m_e_op = (u_char)(CTL_RESPONSE|more|(res_opcode & CTL_OP_MASK)); rpkt.count = htons((u_short) dlen); rpkt.offset = htons( (u_short) res_offset); if (res_async) { register int i; for (i = 0; i < CTL_MAXTRAPS; i++) { if (ctl_trap[i].tr_flags & TRAP_INUSE) { rpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, ctl_trap[i].tr_version, MODE_CONTROL); rpkt.sequence = htons(ctl_trap[i].tr_sequence); sendpkt(&ctl_trap[i].tr_addr, ctl_trap[i].tr_localaddr, -4, (struct pkt *)&rpkt, sendlen); if (!more) ctl_trap[i].tr_sequence++; numasyncmsgs++; } } } else { if (res_authenticate && sys_authenticate) { int maclen; int totlen = sendlen; keyid_t keyid = htonl(res_keyid); /* * If we are going to authenticate, then there * is an additional requirement that the MAC * begin on a 64 bit boundary. */ while (totlen & 7) { *datapt++ = '\0'; totlen++; } memcpy(datapt, &keyid, sizeof keyid); maclen = authencrypt(res_keyid, (u_int32 *)&rpkt, totlen); sendpkt(rmt_addr, lcl_inter, -5, (struct pkt *)&rpkt, totlen + maclen); } else { sendpkt(rmt_addr, lcl_inter, -6, (struct pkt *)&rpkt, sendlen); } if (more) numctlfrags++; else numctlresponses++; } /* * Set us up for another go around. */ res_offset += dlen; datapt = (u_char *)rpkt.data;}/* * ctl_putdata - write data into the packet, fragmenting and starting * another if this one is full. */static voidctl_putdata( const char *dp, unsigned int dlen, int bin /* set to 1 when data is binary */ ){ int overhead; overhead = 0; if (!bin) { datanotbinflag = 1; overhead = 3; if (datapt != rpkt.data) { *datapt++ = ','; datalinelen++; if ((dlen + datalinelen + 1) >= MAXDATALINELEN) { *datapt++ = '\r'; *datapt++ = '\n'; datalinelen = 0; } else { *datapt++ = ' '; datalinelen++; } } } /* * Save room for trailing junk */ if (dlen + overhead + datapt > dataend) { /* * Not enough room in this one, flush it out. */ ctl_flushpkt(CTL_MORE); } memmove((char *)datapt, dp, (unsigned)dlen); datapt += dlen; datalinelen += dlen;}/* * ctl_putstr - write a tagged string into the response packet */static voidctl_putstr( const char *tag, const char *data, unsigned int len ){ register char *cp; register const char *cq; char buffer[400]; cp = buffer; cq = tag; while (*cq != '\0') *cp++ = *cq++; if (len > 0) { *cp++ = '='; *cp++ = '"'; if (len > (int) (sizeof(buffer) - (cp - buffer) - 1)) len = sizeof(buffer) - (cp - buffer) - 1; memmove(cp, data, (unsigned)len); cp += len; *cp++ = '"'; } ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);}/* * ctl_putdbl - write a tagged, signed double into the response packet */static voidctl_putdbl( const char *tag, double ts ){ register char *cp; register const char *cq; char buffer[200]; cp = buffer; cq = tag; while (*cq != '\0') *cp++ = *cq++; *cp++ = '='; (void)sprintf(cp, "%.3f", ts); while (*cp != '\0') cp++; ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);}/* * ctl_putuint - write a tagged unsigned integer into the response */static voidctl_putuint( const char *tag, u_long uval ){ register char *cp; register const char *cq; char buffer[200]; cp = buffer; cq = tag; while (*cq != '\0') *cp++ = *cq++; *cp++ = '='; (void) sprintf(cp, "%lu", uval); while (*cp != '\0') cp++; ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);}/* * ctl_putfs - write a decoded filestamp into the response */static voidctl_putfs( const char *tag, tstamp_t uval ){ register char *cp; register const char *cq; char buffer[200]; struct tm *tm = NULL; time_t fstamp; cp = buffer; cq = tag; while (*cq != '\0') *cp++ = *cq++; *cp++ = '='; fstamp = uval - JAN_1970; tm = gmtime(&fstamp); if (tm == NULL) return; sprintf(cp, "%04d%02d%02d%02d%02d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min); while (*cp != '\0') cp++; ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);}/* * ctl_puthex - write a tagged unsigned integer, in hex, into the response */static voidctl_puthex( const char *tag, u_long uval ){ register char *cp; register const char *cq; char buffer[200]; cp = buffer; cq = tag; while (*cq != '\0') *cp++ = *cq++; *cp++ = '='; (void) sprintf(cp, "0x%lx", uval); while (*cp != '\0') cp++; ctl_putdata(buffer,(unsigned)( cp - buffer ), 0);}/* * ctl_putint - write a tagged signed integer into the response */static voidctl_putint( const char *tag, long ival ){ register char *cp; register const char *cq; char buffer[200]; cp = buffer; cq = tag; while (*cq != '\0') *cp++ = *cq++; *cp++ = '='; (void) sprintf(cp, "%ld", ival); while (*cp != '\0') cp++; ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);}/* * ctl_putts - write a tagged timestamp, in hex, into the response */static voidctl_putts( const char *tag, l_fp *ts ){ register char *cp; register const char *cq; char buffer[200]; cp = buffer; cq = tag; while (*cq != '\0') *cp++ = *cq++; *cp++ = '='; (void) sprintf(cp, "0x%08lx.%08lx", ts->l_ui & ULONG_CONST(0xffffffff), ts->l_uf & ULONG_CONST(0xffffffff)); while (*cp != '\0') cp++; ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);}/* * ctl_putadr - write an IP address into the response */static voidctl_putadr( const char *tag, u_int32 addr32, struct sockaddr_storage* addr ){ register char *cp; register const char *cq; char buffer[200]; cp = buffer; cq = tag; while (*cq != '\0') *cp++ = *cq++; *cp++ = '='; if (addr == NULL) cq = numtoa(addr32); else cq = stoa(addr); while (*cq != '\0') *cp++ = *cq++; ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);}/* * ctl_putid - write a tagged clock ID into the response */static voidctl_putid( const char *tag, char *id ){ register char *cp; register const char *cq; char buffer[200]; cp = buffer; cq = tag; while (*cq != '\0') *cp++ = *cq++; *cp++ = '='; cq = id; while (*cq != '\0' && (cq - id) < 4) *cp++ = *cq++; ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);}/* * ctl_putarray - write a tagged eight element double array into the response */static voidctl_putarray( const char *tag, double *arr, int start ){ register char *cp; register const char *cq; char buffer[200]; int i; cp = buffer; cq = tag; while (*cq != '\0') *cp++ = *cq++; i = start; do { if (i == 0) i = NTP_SHIFT; i--; (void)sprintf(cp, " %.2f", arr[i] * 1e3);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -