Annotation of embedaddon/ntp/ntpd/ntp_request.c, revision 1.1.1.1
1.1 misho 1: /*
2: * ntp_request.c - respond to information requests
3: */
4:
5: #ifdef HAVE_CONFIG_H
6: # include <config.h>
7: #endif
8:
9: #include "ntpd.h"
10: #include "ntp_io.h"
11: #include "ntp_request.h"
12: #include "ntp_control.h"
13: #include "ntp_refclock.h"
14: #include "ntp_if.h"
15: #include "ntp_stdlib.h"
16: #include "ntp_assert.h"
17:
18: #include <stdio.h>
19: #include <stddef.h>
20: #include <signal.h>
21: #ifdef HAVE_NETINET_IN_H
22: #include <netinet/in.h>
23: #endif
24: #include <arpa/inet.h>
25:
26: #include "recvbuff.h"
27:
28: #ifdef KERNEL_PLL
29: #include "ntp_syscall.h"
30: #endif /* KERNEL_PLL */
31:
32: /*
33: * Structure to hold request procedure information
34: */
35: #define NOAUTH 0
36: #define AUTH 1
37:
38: #define NO_REQUEST (-1)
39: /*
40: * Because we now have v6 addresses in the messages, we need to compensate
41: * for the larger size. Therefore, we introduce the alternate size to
42: * keep us friendly with older implementations. A little ugly.
43: */
44: static int client_v6_capable = 0; /* the client can handle longer messages */
45:
46: #define v6sizeof(type) (client_v6_capable ? sizeof(type) : v4sizeof(type))
47:
48: struct req_proc {
49: short request_code; /* defined request code */
50: short needs_auth; /* true when authentication needed */
51: short sizeofitem; /* size of request data item (older size)*/
52: short v6_sizeofitem; /* size of request data item (new size)*/
53: void (*handler) (sockaddr_u *, struct interface *,
54: struct req_pkt *); /* routine to handle request */
55: };
56:
57: /*
58: * Universal request codes
59: */
60: static struct req_proc univ_codes[] = {
61: { NO_REQUEST, NOAUTH, 0, 0 }
62: };
63:
64: static void req_ack (sockaddr_u *, struct interface *, struct req_pkt *, int);
65: static char * prepare_pkt (sockaddr_u *, struct interface *,
66: struct req_pkt *, size_t);
67: static char * more_pkt (void);
68: static void flush_pkt (void);
69: static void peer_list (sockaddr_u *, struct interface *, struct req_pkt *);
70: static void peer_list_sum (sockaddr_u *, struct interface *, struct req_pkt *);
71: static void peer_info (sockaddr_u *, struct interface *, struct req_pkt *);
72: static void peer_stats (sockaddr_u *, struct interface *, struct req_pkt *);
73: static void sys_info (sockaddr_u *, struct interface *, struct req_pkt *);
74: static void sys_stats (sockaddr_u *, struct interface *, struct req_pkt *);
75: static void mem_stats (sockaddr_u *, struct interface *, struct req_pkt *);
76: static void io_stats (sockaddr_u *, struct interface *, struct req_pkt *);
77: static void timer_stats (sockaddr_u *, struct interface *, struct req_pkt *);
78: static void loop_info (sockaddr_u *, struct interface *, struct req_pkt *);
79: static void do_conf (sockaddr_u *, struct interface *, struct req_pkt *);
80: static void do_unconf (sockaddr_u *, struct interface *, struct req_pkt *);
81: static void set_sys_flag (sockaddr_u *, struct interface *, struct req_pkt *);
82: static void clr_sys_flag (sockaddr_u *, struct interface *, struct req_pkt *);
83: static void setclr_flags (sockaddr_u *, struct interface *, struct req_pkt *, u_long);
84: static void list_restrict (sockaddr_u *, struct interface *, struct req_pkt *);
85: static void do_resaddflags (sockaddr_u *, struct interface *, struct req_pkt *);
86: static void do_ressubflags (sockaddr_u *, struct interface *, struct req_pkt *);
87: static void do_unrestrict (sockaddr_u *, struct interface *, struct req_pkt *);
88: static void do_restrict (sockaddr_u *, struct interface *, struct req_pkt *, int);
89: static void mon_getlist_0 (sockaddr_u *, struct interface *, struct req_pkt *);
90: static void mon_getlist_1 (sockaddr_u *, struct interface *, struct req_pkt *);
91: static void reset_stats (sockaddr_u *, struct interface *, struct req_pkt *);
92: static void reset_peer (sockaddr_u *, struct interface *, struct req_pkt *);
93: static void do_key_reread (sockaddr_u *, struct interface *, struct req_pkt *);
94: static void trust_key (sockaddr_u *, struct interface *, struct req_pkt *);
95: static void untrust_key (sockaddr_u *, struct interface *, struct req_pkt *);
96: static void do_trustkey (sockaddr_u *, struct interface *, struct req_pkt *, u_long);
97: static void get_auth_info (sockaddr_u *, struct interface *, struct req_pkt *);
98: static void reset_auth_stats (void);
99: static void req_get_traps (sockaddr_u *, struct interface *, struct req_pkt *);
100: static void req_set_trap (sockaddr_u *, struct interface *, struct req_pkt *);
101: static void req_clr_trap (sockaddr_u *, struct interface *, struct req_pkt *);
102: static void do_setclr_trap (sockaddr_u *, struct interface *, struct req_pkt *, int);
103: static void set_request_keyid (sockaddr_u *, struct interface *, struct req_pkt *);
104: static void set_control_keyid (sockaddr_u *, struct interface *, struct req_pkt *);
105: static void get_ctl_stats (sockaddr_u *, struct interface *, struct req_pkt *);
106: static void get_if_stats (sockaddr_u *, struct interface *, struct req_pkt *);
107: static void do_if_reload (sockaddr_u *, struct interface *, struct req_pkt *);
108: #ifdef KERNEL_PLL
109: static void get_kernel_info (sockaddr_u *, struct interface *, struct req_pkt *);
110: #endif /* KERNEL_PLL */
111: #ifdef REFCLOCK
112: static void get_clock_info (sockaddr_u *, struct interface *, struct req_pkt *);
113: static void set_clock_fudge (sockaddr_u *, struct interface *, struct req_pkt *);
114: #endif /* REFCLOCK */
115: #ifdef REFCLOCK
116: static void get_clkbug_info (sockaddr_u *, struct interface *, struct req_pkt *);
117: #endif /* REFCLOCK */
118:
119: /*
120: * ntpd request codes
121: */
122: static struct req_proc ntp_codes[] = {
123: { REQ_PEER_LIST, NOAUTH, 0, 0, peer_list },
124: { REQ_PEER_LIST_SUM, NOAUTH, 0, 0, peer_list_sum },
125: { REQ_PEER_INFO, NOAUTH, v4sizeof(struct info_peer_list),
126: sizeof(struct info_peer_list), peer_info},
127: { REQ_PEER_STATS, NOAUTH, v4sizeof(struct info_peer_list),
128: sizeof(struct info_peer_list), peer_stats},
129: { REQ_SYS_INFO, NOAUTH, 0, 0, sys_info },
130: { REQ_SYS_STATS, NOAUTH, 0, 0, sys_stats },
131: { REQ_IO_STATS, NOAUTH, 0, 0, io_stats },
132: { REQ_MEM_STATS, NOAUTH, 0, 0, mem_stats },
133: { REQ_LOOP_INFO, NOAUTH, 0, 0, loop_info },
134: { REQ_TIMER_STATS, NOAUTH, 0, 0, timer_stats },
135: { REQ_CONFIG, AUTH, v4sizeof(struct conf_peer),
136: sizeof(struct conf_peer), do_conf },
137: { REQ_UNCONFIG, AUTH, v4sizeof(struct conf_unpeer),
138: sizeof(struct conf_unpeer), do_unconf },
139: { REQ_SET_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags),
140: sizeof(struct conf_sys_flags), set_sys_flag },
141: { REQ_CLR_SYS_FLAG, AUTH, sizeof(struct conf_sys_flags),
142: sizeof(struct conf_sys_flags), clr_sys_flag },
143: { REQ_GET_RESTRICT, NOAUTH, 0, 0, list_restrict },
144: { REQ_RESADDFLAGS, AUTH, v4sizeof(struct conf_restrict),
145: sizeof(struct conf_restrict), do_resaddflags },
146: { REQ_RESSUBFLAGS, AUTH, v4sizeof(struct conf_restrict),
147: sizeof(struct conf_restrict), do_ressubflags },
148: { REQ_UNRESTRICT, AUTH, v4sizeof(struct conf_restrict),
149: sizeof(struct conf_restrict), do_unrestrict },
150: { REQ_MON_GETLIST, NOAUTH, 0, 0, mon_getlist_0 },
151: { REQ_MON_GETLIST_1, NOAUTH, 0, 0, mon_getlist_1 },
152: { REQ_RESET_STATS, AUTH, sizeof(struct reset_flags), 0, reset_stats },
153: { REQ_RESET_PEER, AUTH, v4sizeof(struct conf_unpeer),
154: sizeof(struct conf_unpeer), reset_peer },
155: { REQ_REREAD_KEYS, AUTH, 0, 0, do_key_reread },
156: { REQ_TRUSTKEY, AUTH, sizeof(u_long), sizeof(u_long), trust_key },
157: { REQ_UNTRUSTKEY, AUTH, sizeof(u_long), sizeof(u_long), untrust_key },
158: { REQ_AUTHINFO, NOAUTH, 0, 0, get_auth_info },
159: { REQ_TRAPS, NOAUTH, 0, 0, req_get_traps },
160: { REQ_ADD_TRAP, AUTH, v4sizeof(struct conf_trap),
161: sizeof(struct conf_trap), req_set_trap },
162: { REQ_CLR_TRAP, AUTH, v4sizeof(struct conf_trap),
163: sizeof(struct conf_trap), req_clr_trap },
164: { REQ_REQUEST_KEY, AUTH, sizeof(u_long), sizeof(u_long),
165: set_request_keyid },
166: { REQ_CONTROL_KEY, AUTH, sizeof(u_long), sizeof(u_long),
167: set_control_keyid },
168: { REQ_GET_CTLSTATS, NOAUTH, 0, 0, get_ctl_stats },
169: #ifdef KERNEL_PLL
170: { REQ_GET_KERNEL, NOAUTH, 0, 0, get_kernel_info },
171: #endif
172: #ifdef REFCLOCK
173: { REQ_GET_CLOCKINFO, NOAUTH, sizeof(u_int32), sizeof(u_int32),
174: get_clock_info },
175: { REQ_SET_CLKFUDGE, AUTH, sizeof(struct conf_fudge),
176: sizeof(struct conf_fudge), set_clock_fudge },
177: { REQ_GET_CLKBUGINFO, NOAUTH, sizeof(u_int32), sizeof(u_int32),
178: get_clkbug_info },
179: #endif
180: { REQ_IF_STATS, AUTH, 0, 0, get_if_stats },
181: { REQ_IF_RELOAD, AUTH, 0, 0, do_if_reload },
182:
183: { NO_REQUEST, NOAUTH, 0, 0, 0 }
184: };
185:
186:
187: /*
188: * Authentication keyid used to authenticate requests. Zero means we
189: * don't allow writing anything.
190: */
191: keyid_t info_auth_keyid;
192:
193: /*
194: * Statistic counters to keep track of requests and responses.
195: */
196: u_long numrequests; /* number of requests we've received */
197: u_long numresppkts; /* number of resp packets sent with data */
198:
199: u_long errorcounter[INFO_ERR_AUTH+1]; /* lazy way to count errors, indexed */
200: /* by the error code */
201:
202: /*
203: * A hack. To keep the authentication module clear of ntp-ism's, we
204: * include a time reset variable for its stats here.
205: */
206: static u_long auth_timereset;
207:
208: /*
209: * Response packet used by these routines. Also some state information
210: * so that we can handle packet formatting within a common set of
211: * subroutines. Note we try to enter data in place whenever possible,
212: * but the need to set the more bit correctly means we occasionally
213: * use the extra buffer and copy.
214: */
215: static struct resp_pkt rpkt;
216: static int reqver;
217: static int seqno;
218: static int nitems;
219: static int itemsize;
220: static int databytes;
221: static char exbuf[RESP_DATA_SIZE];
222: static int usingexbuf;
223: static sockaddr_u *toaddr;
224: static struct interface *frominter;
225:
226: /*
227: * init_request - initialize request data
228: */
229: void
230: init_request (void)
231: {
232: int i;
233:
234: numrequests = 0;
235: numresppkts = 0;
236: auth_timereset = 0;
237: info_auth_keyid = 0; /* by default, can't do this */
238:
239: for (i = 0; i < sizeof(errorcounter)/sizeof(errorcounter[0]); i++)
240: errorcounter[i] = 0;
241: }
242:
243:
244: /*
245: * req_ack - acknowledge request with no data
246: */
247: static void
248: req_ack(
249: sockaddr_u *srcadr,
250: struct interface *inter,
251: struct req_pkt *inpkt,
252: int errcode
253: )
254: {
255: /*
256: * fill in the fields
257: */
258: rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, 0, reqver);
259: rpkt.auth_seq = AUTH_SEQ(0, 0);
260: rpkt.implementation = inpkt->implementation;
261: rpkt.request = inpkt->request;
262: rpkt.err_nitems = ERR_NITEMS(errcode, 0);
263: rpkt.mbz_itemsize = MBZ_ITEMSIZE(0);
264:
265: /*
266: * send packet and bump counters
267: */
268: sendpkt(srcadr, inter, -1, (struct pkt *)&rpkt, RESP_HEADER_SIZE);
269: errorcounter[errcode]++;
270: }
271:
272:
273: /*
274: * prepare_pkt - prepare response packet for transmission, return pointer
275: * to storage for data item.
276: */
277: static char *
278: prepare_pkt(
279: sockaddr_u *srcadr,
280: struct interface *inter,
281: struct req_pkt *pkt,
282: size_t structsize
283: )
284: {
285: DPRINTF(4, ("request: preparing pkt\n"));
286:
287: /*
288: * Fill in the implementation, request and itemsize fields
289: * since these won't change.
290: */
291: rpkt.implementation = pkt->implementation;
292: rpkt.request = pkt->request;
293: rpkt.mbz_itemsize = MBZ_ITEMSIZE(structsize);
294:
295: /*
296: * Compute the static data needed to carry on.
297: */
298: toaddr = srcadr;
299: frominter = inter;
300: seqno = 0;
301: nitems = 0;
302: itemsize = structsize;
303: databytes = 0;
304: usingexbuf = 0;
305:
306: /*
307: * return the beginning of the packet buffer.
308: */
309: return &rpkt.data[0];
310: }
311:
312:
313: /*
314: * more_pkt - return a data pointer for a new item.
315: */
316: static char *
317: more_pkt(void)
318: {
319: /*
320: * If we were using the extra buffer, send the packet.
321: */
322: if (usingexbuf) {
323: DPRINTF(3, ("request: sending pkt\n"));
324: rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, MORE_BIT, reqver);
325: rpkt.auth_seq = AUTH_SEQ(0, seqno);
326: rpkt.err_nitems = htons((u_short)nitems);
327: sendpkt(toaddr, frominter, -1, (struct pkt *)&rpkt,
328: RESP_HEADER_SIZE + databytes);
329: numresppkts++;
330:
331: /*
332: * Copy data out of exbuf into the packet.
333: */
334: memcpy(&rpkt.data[0], exbuf, (unsigned)itemsize);
335: seqno++;
336: databytes = 0;
337: nitems = 0;
338: usingexbuf = 0;
339: }
340:
341: databytes += itemsize;
342: nitems++;
343: if (databytes + itemsize <= RESP_DATA_SIZE) {
344: DPRINTF(4, ("request: giving him more data\n"));
345: /*
346: * More room in packet. Give him the
347: * next address.
348: */
349: return &rpkt.data[databytes];
350: } else {
351: /*
352: * No room in packet. Give him the extra
353: * buffer unless this was the last in the sequence.
354: */
355: DPRINTF(4, ("request: into extra buffer\n"));
356: if (seqno == MAXSEQ)
357: return NULL;
358: else {
359: usingexbuf = 1;
360: return exbuf;
361: }
362: }
363: }
364:
365:
366: /*
367: * flush_pkt - we're done, return remaining information.
368: */
369: static void
370: flush_pkt(void)
371: {
372: DPRINTF(3, ("request: flushing packet, %d items\n", nitems));
373: /*
374: * Must send the last packet. If nothing in here and nothing
375: * has been sent, send an error saying no data to be found.
376: */
377: if (seqno == 0 && nitems == 0)
378: req_ack(toaddr, frominter, (struct req_pkt *)&rpkt,
379: INFO_ERR_NODATA);
380: else {
381: rpkt.rm_vn_mode = RM_VN_MODE(RESP_BIT, 0, reqver);
382: rpkt.auth_seq = AUTH_SEQ(0, seqno);
383: rpkt.err_nitems = htons((u_short)nitems);
384: sendpkt(toaddr, frominter, -1, (struct pkt *)&rpkt,
385: RESP_HEADER_SIZE+databytes);
386: numresppkts++;
387: }
388: }
389:
390:
391:
392: /*
393: * Given a buffer, return the packet mode
394: */
395: int
396: get_packet_mode(struct recvbuf *rbufp)
397: {
398: struct req_pkt *inpkt = (struct req_pkt *)&rbufp->recv_pkt;
399: return (INFO_MODE(inpkt->rm_vn_mode));
400: }
401:
402:
403: /*
404: * process_private - process private mode (7) packets
405: */
406: void
407: process_private(
408: struct recvbuf *rbufp,
409: int mod_okay
410: )
411: {
412: static u_long quiet_until;
413: struct req_pkt *inpkt;
414: struct req_pkt_tail *tailinpkt;
415: sockaddr_u *srcadr;
416: struct interface *inter;
417: struct req_proc *proc;
418: int ec;
419: short temp_size;
420: l_fp ftmp;
421: double dtemp;
422: size_t recv_len;
423: size_t noslop_len;
424: size_t mac_len;
425:
426: /*
427: * Initialize pointers, for convenience
428: */
429: recv_len = rbufp->recv_length;
430: inpkt = (struct req_pkt *)&rbufp->recv_pkt;
431: srcadr = &rbufp->recv_srcadr;
432: inter = rbufp->dstadr;
433:
434: DPRINTF(3, ("process_private: impl %d req %d\n",
435: inpkt->implementation, inpkt->request));
436:
437: /*
438: * Do some sanity checks on the packet. Return a format
439: * error if it fails.
440: */
441: ec = 0;
442: if ( (++ec, ISRESPONSE(inpkt->rm_vn_mode))
443: || (++ec, ISMORE(inpkt->rm_vn_mode))
444: || (++ec, INFO_VERSION(inpkt->rm_vn_mode) > NTP_VERSION)
445: || (++ec, INFO_VERSION(inpkt->rm_vn_mode) < NTP_OLDVERSION)
446: || (++ec, INFO_SEQ(inpkt->auth_seq) != 0)
447: || (++ec, INFO_ERR(inpkt->err_nitems) != 0)
448: || (++ec, INFO_MBZ(inpkt->mbz_itemsize) != 0)
449: || (++ec, rbufp->recv_length < REQ_LEN_HDR)
450: ) {
451: NLOG(NLOG_SYSEVENT)
452: if (current_time >= quiet_until) {
453: msyslog(LOG_ERR,
454: "process_private: drop test %d"
455: " failed, pkt from %s",
456: ec, stoa(srcadr));
457: quiet_until = current_time + 60;
458: }
459: return;
460: }
461:
462: reqver = INFO_VERSION(inpkt->rm_vn_mode);
463:
464: /*
465: * Get the appropriate procedure list to search.
466: */
467: if (inpkt->implementation == IMPL_UNIV)
468: proc = univ_codes;
469: else if ((inpkt->implementation == IMPL_XNTPD) ||
470: (inpkt->implementation == IMPL_XNTPD_OLD))
471: proc = ntp_codes;
472: else {
473: req_ack(srcadr, inter, inpkt, INFO_ERR_IMPL);
474: return;
475: }
476:
477: /*
478: * Search the list for the request codes. If it isn't one
479: * we know, return an error.
480: */
481: while (proc->request_code != NO_REQUEST) {
482: if (proc->request_code == (short) inpkt->request)
483: break;
484: proc++;
485: }
486: if (proc->request_code == NO_REQUEST) {
487: req_ack(srcadr, inter, inpkt, INFO_ERR_REQ);
488: return;
489: }
490:
491: DPRINTF(4, ("found request in tables\n"));
492:
493: /*
494: * If we need data, check to see if we have some. If we
495: * don't, check to see that there is none (picky, picky).
496: */
497:
498: /* This part is a bit tricky, we want to be sure that the size
499: * returned is either the old or the new size. We also can find
500: * out if the client can accept both types of messages this way.
501: *
502: * Handle the exception of REQ_CONFIG. It can have two data sizes.
503: */
504: temp_size = INFO_ITEMSIZE(inpkt->mbz_itemsize);
505: if ((temp_size != proc->sizeofitem &&
506: temp_size != proc->v6_sizeofitem) &&
507: !(inpkt->implementation == IMPL_XNTPD &&
508: inpkt->request == REQ_CONFIG &&
509: temp_size == sizeof(struct old_conf_peer))) {
510: DPRINTF(3, ("process_private: wrong item size, received %d, should be %d or %d\n",
511: temp_size, proc->sizeofitem, proc->v6_sizeofitem));
512: req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
513: return;
514: }
515: if ((proc->sizeofitem != 0) &&
516: ((size_t)(temp_size * INFO_NITEMS(inpkt->err_nitems)) >
517: (recv_len - REQ_LEN_HDR))) {
518: DPRINTF(3, ("process_private: not enough data\n"));
519: req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
520: return;
521: }
522:
523: switch (inpkt->implementation) {
524: case IMPL_XNTPD:
525: client_v6_capable = 1;
526: break;
527: case IMPL_XNTPD_OLD:
528: client_v6_capable = 0;
529: break;
530: default:
531: req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
532: return;
533: }
534:
535: /*
536: * If we need to authenticate, do so. Note that an
537: * authenticatable packet must include a mac field, must
538: * have used key info_auth_keyid and must have included
539: * a time stamp in the appropriate field. The time stamp
540: * must be within INFO_TS_MAXSKEW of the receive
541: * time stamp.
542: */
543: if (proc->needs_auth && sys_authenticate) {
544:
545: if (recv_len < (REQ_LEN_HDR +
546: (INFO_ITEMSIZE(inpkt->mbz_itemsize) *
547: INFO_NITEMS(inpkt->err_nitems)) +
548: REQ_TAIL_MIN)) {
549: req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
550: return;
551: }
552:
553: /*
554: * For 16-octet digests, regardless of itemsize and
555: * nitems, authenticated requests are a fixed size
556: * with the timestamp, key ID, and digest located
557: * at the end of the packet. Because the key ID
558: * determining the digest size precedes the digest,
559: * for larger digests the fixed size request scheme
560: * is abandoned and the timestamp, key ID, and digest
561: * are located relative to the start of the packet,
562: * with the digest size determined by the packet size.
563: */
564: noslop_len = REQ_LEN_HDR
565: + INFO_ITEMSIZE(inpkt->mbz_itemsize) *
566: INFO_NITEMS(inpkt->err_nitems)
567: + sizeof(inpkt->tstamp);
568: /* 32-bit alignment */
569: noslop_len = (noslop_len + 3) & ~3;
570: if (recv_len > (noslop_len + MAX_MAC_LEN))
571: mac_len = 20;
572: else
573: mac_len = recv_len - noslop_len;
574:
575: tailinpkt = (void *)((char *)inpkt + recv_len -
576: (mac_len + sizeof(inpkt->tstamp)));
577:
578: /*
579: * If this guy is restricted from doing this, don't let
580: * him. If the wrong key was used, or packet doesn't
581: * have mac, return.
582: */
583: if (!INFO_IS_AUTH(inpkt->auth_seq) || !info_auth_keyid
584: || ntohl(tailinpkt->keyid) != info_auth_keyid) {
585: DPRINTF(5, ("failed auth %d info_auth_keyid %u pkt keyid %u maclen %lu\n",
586: INFO_IS_AUTH(inpkt->auth_seq),
587: info_auth_keyid,
588: ntohl(tailinpkt->keyid), (u_long)mac_len));
589: #ifdef DEBUG
590: msyslog(LOG_DEBUG,
591: "process_private: failed auth %d info_auth_keyid %u pkt keyid %u maclen %lu\n",
592: INFO_IS_AUTH(inpkt->auth_seq),
593: info_auth_keyid,
594: ntohl(tailinpkt->keyid), (u_long)mac_len);
595: #endif
596: req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
597: return;
598: }
599: if (recv_len > REQ_LEN_NOMAC + MAX_MAC_LEN) {
600: DPRINTF(5, ("bad pkt length %lu\n",
601: (u_long)recv_len));
602: msyslog(LOG_ERR,
603: "process_private: bad pkt length %lu",
604: (u_long)recv_len);
605: req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
606: return;
607: }
608: if (!mod_okay || !authhavekey(info_auth_keyid)) {
609: DPRINTF(5, ("failed auth mod_okay %d\n",
610: mod_okay));
611: #ifdef DEBUG
612: msyslog(LOG_DEBUG,
613: "process_private: failed auth mod_okay %d\n",
614: mod_okay);
615: #endif
616: req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
617: return;
618: }
619:
620: /*
621: * calculate absolute time difference between xmit time stamp
622: * and receive time stamp. If too large, too bad.
623: */
624: NTOHL_FP(&tailinpkt->tstamp, &ftmp);
625: L_SUB(&ftmp, &rbufp->recv_time);
626: LFPTOD(&ftmp, dtemp);
627: if (fabs(dtemp) > INFO_TS_MAXSKEW) {
628: /*
629: * He's a loser. Tell him.
630: */
631: DPRINTF(5, ("xmit/rcv timestamp delta %g > INFO_TS_MAXSKEW %g\n",
632: dtemp, INFO_TS_MAXSKEW));
633: req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
634: return;
635: }
636:
637: /*
638: * So far so good. See if decryption works out okay.
639: */
640: if (!authdecrypt(info_auth_keyid, (u_int32 *)inpkt,
641: recv_len - mac_len, mac_len)) {
642: DPRINTF(5, ("authdecrypt failed\n"));
643: req_ack(srcadr, inter, inpkt, INFO_ERR_AUTH);
644: return;
645: }
646: }
647:
648: DPRINTF(3, ("process_private: all okay, into handler\n"));
649: /*
650: * Packet is okay. Call the handler to send him data.
651: */
652: (proc->handler)(srcadr, inter, inpkt);
653: }
654:
655:
656: /*
657: * peer_list - send a list of the peers
658: */
659: static void
660: peer_list(
661: sockaddr_u *srcadr,
662: struct interface *inter,
663: struct req_pkt *inpkt
664: )
665: {
666: register struct info_peer_list *ip;
667: register struct peer *pp;
668: register int i;
669: register int skip = 0;
670:
671: ip = (struct info_peer_list *)prepare_pkt(srcadr, inter, inpkt,
672: v6sizeof(struct info_peer_list));
673: for (i = 0; i < NTP_HASH_SIZE && ip != 0; i++) {
674: pp = peer_hash[i];
675: while (pp != 0 && ip != 0) {
676: if (IS_IPV6(&pp->srcadr)) {
677: if (client_v6_capable) {
678: ip->addr6 = SOCK_ADDR6(&pp->srcadr);
679: ip->v6_flag = 1;
680: skip = 0;
681: } else {
682: skip = 1;
683: break;
684: }
685: } else {
686: ip->addr = NSRCADR(&pp->srcadr);
687: if (client_v6_capable)
688: ip->v6_flag = 0;
689: skip = 0;
690: }
691:
692: if(!skip) {
693: ip->port = NSRCPORT(&pp->srcadr);
694: ip->hmode = pp->hmode;
695: ip->flags = 0;
696: if (pp->flags & FLAG_CONFIG)
697: ip->flags |= INFO_FLAG_CONFIG;
698: if (pp == sys_peer)
699: ip->flags |= INFO_FLAG_SYSPEER;
700: if (pp->status == CTL_PST_SEL_SYNCCAND)
701: ip->flags |= INFO_FLAG_SEL_CANDIDATE;
702: if (pp->status >= CTL_PST_SEL_SYSPEER)
703: ip->flags |= INFO_FLAG_SHORTLIST;
704: ip = (struct info_peer_list *)more_pkt();
705: }
706: pp = pp->next;
707: }
708: }
709: flush_pkt();
710: }
711:
712:
713: /*
714: * peer_list_sum - return extended peer list
715: */
716: static void
717: peer_list_sum(
718: sockaddr_u *srcadr,
719: struct interface *inter,
720: struct req_pkt *inpkt
721: )
722: {
723: register struct info_peer_summary *ips;
724: register struct peer *pp;
725: register int i;
726: l_fp ltmp;
727: register int skip;
728:
729: #ifdef DEBUG
730: if (debug > 2)
731: printf("wants peer list summary\n");
732: #endif
733: ips = (struct info_peer_summary *)prepare_pkt(srcadr, inter, inpkt,
734: v6sizeof(struct info_peer_summary));
735: for (i = 0; i < NTP_HASH_SIZE && ips != 0; i++) {
736: pp = peer_hash[i];
737: while (pp != 0 && ips != 0) {
738: #ifdef DEBUG
739: if (debug > 3)
740: printf("sum: got one\n");
741: #endif
742: /*
743: * Be careful here not to return v6 peers when we
744: * want only v4.
745: */
746: if (IS_IPV6(&pp->srcadr)) {
747: if (client_v6_capable) {
748: ips->srcadr6 = SOCK_ADDR6(&pp->srcadr);
749: ips->v6_flag = 1;
750: if (pp->dstadr)
751: ips->dstadr6 = SOCK_ADDR6(&pp->dstadr->sin);
752: else
753: memset(&ips->dstadr6, 0, sizeof(ips->dstadr6));
754: skip = 0;
755: } else {
756: skip = 1;
757: break;
758: }
759: } else {
760: ips->srcadr = NSRCADR(&pp->srcadr);
761: if (client_v6_capable)
762: ips->v6_flag = 0;
763:
764: if (pp->dstadr) {
765: if (!pp->processed)
766: ips->dstadr = NSRCADR(&pp->dstadr->sin);
767: else {
768: if (MDF_BCAST == pp->cast_flags)
769: ips->dstadr = NSRCADR(&pp->dstadr->bcast);
770: else if (pp->cast_flags) {
771: ips->dstadr = NSRCADR(&pp->dstadr->sin);
772: if (!ips->dstadr)
773: ips->dstadr = NSRCADR(&pp->dstadr->bcast);
774: }
775: }
776: } else
777: ips->dstadr = 0;
778:
779: skip = 0;
780: }
781:
782: if (!skip){
783: ips->srcport = NSRCPORT(&pp->srcadr);
784: ips->stratum = pp->stratum;
785: ips->hpoll = pp->hpoll;
786: ips->ppoll = pp->ppoll;
787: ips->reach = pp->reach;
788: ips->flags = 0;
789: if (pp == sys_peer)
790: ips->flags |= INFO_FLAG_SYSPEER;
791: if (pp->flags & FLAG_CONFIG)
792: ips->flags |= INFO_FLAG_CONFIG;
793: if (pp->flags & FLAG_REFCLOCK)
794: ips->flags |= INFO_FLAG_REFCLOCK;
795: if (pp->flags & FLAG_PREFER)
796: ips->flags |= INFO_FLAG_PREFER;
797: if (pp->flags & FLAG_BURST)
798: ips->flags |= INFO_FLAG_BURST;
799: if (pp->status == CTL_PST_SEL_SYNCCAND)
800: ips->flags |= INFO_FLAG_SEL_CANDIDATE;
801: if (pp->status >= CTL_PST_SEL_SYSPEER)
802: ips->flags |= INFO_FLAG_SHORTLIST;
803: ips->hmode = pp->hmode;
804: ips->delay = HTONS_FP(DTOFP(pp->delay));
805: DTOLFP(pp->offset, <mp);
806: HTONL_FP(<mp, &ips->offset);
807: ips->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp)));
808: }
809: pp = pp->next;
810: ips = (struct info_peer_summary *)more_pkt();
811: }
812: }
813: flush_pkt();
814: }
815:
816:
817: /*
818: * peer_info - send information for one or more peers
819: */
820: static void
821: peer_info (
822: sockaddr_u *srcadr,
823: struct interface *inter,
824: struct req_pkt *inpkt
825: )
826: {
827: register struct info_peer_list *ipl;
828: register struct peer *pp;
829: register struct info_peer *ip;
830: register int items;
831: register int i, j;
832: sockaddr_u addr;
833: extern struct peer *sys_peer;
834: l_fp ltmp;
835:
836: items = INFO_NITEMS(inpkt->err_nitems);
837: ipl = (struct info_peer_list *) inpkt->data;
838:
839: ip = (struct info_peer *)prepare_pkt(srcadr, inter, inpkt,
840: v6sizeof(struct info_peer));
841: while (items-- > 0 && ip != 0) {
842: ZERO_SOCK(&addr);
843: NSRCPORT(&addr) = ipl->port;
844: if (client_v6_capable && ipl->v6_flag) {
845: AF(&addr) = AF_INET6;
846: SOCK_ADDR6(&addr) = ipl->addr6;
847: } else {
848: AF(&addr) = AF_INET;
849: NSRCADR(&addr) = ipl->addr;
850: }
851: #ifdef ISC_PLATFORM_HAVESALEN
852: addr.sa.sa_len = SOCKLEN(&addr);
853: #endif
854: ipl++;
855: pp = findexistingpeer(&addr, NULL, -1, 0);
856: if (NULL == pp)
857: continue;
858: if (IS_IPV6(srcadr)) {
859: if (pp->dstadr)
860: ip->dstadr6 =
861: (MDF_BCAST == pp->cast_flags)
862: ? SOCK_ADDR6(&pp->dstadr->bcast)
863: : SOCK_ADDR6(&pp->dstadr->sin);
864: else
865: memset(&ip->dstadr6, 0, sizeof(ip->dstadr6));
866:
867: ip->srcadr6 = SOCK_ADDR6(&pp->srcadr);
868: ip->v6_flag = 1;
869: } else {
870: if (pp->dstadr) {
871: if (!pp->processed)
872: ip->dstadr = NSRCADR(&pp->dstadr->sin);
873: else {
874: if (MDF_BCAST == pp->cast_flags)
875: ip->dstadr = NSRCADR(&pp->dstadr->bcast);
876: else if (pp->cast_flags) {
877: ip->dstadr = NSRCADR(&pp->dstadr->sin);
878: if (!ip->dstadr)
879: ip->dstadr = NSRCADR(&pp->dstadr->bcast);
880: }
881: }
882: } else
883: ip->dstadr = 0;
884:
885: ip->srcadr = NSRCADR(&pp->srcadr);
886: if (client_v6_capable)
887: ip->v6_flag = 0;
888: }
889: ip->srcport = NSRCPORT(&pp->srcadr);
890: ip->flags = 0;
891: if (pp == sys_peer)
892: ip->flags |= INFO_FLAG_SYSPEER;
893: if (pp->flags & FLAG_CONFIG)
894: ip->flags |= INFO_FLAG_CONFIG;
895: if (pp->flags & FLAG_REFCLOCK)
896: ip->flags |= INFO_FLAG_REFCLOCK;
897: if (pp->flags & FLAG_PREFER)
898: ip->flags |= INFO_FLAG_PREFER;
899: if (pp->flags & FLAG_BURST)
900: ip->flags |= INFO_FLAG_BURST;
901: if (pp->status == CTL_PST_SEL_SYNCCAND)
902: ip->flags |= INFO_FLAG_SEL_CANDIDATE;
903: if (pp->status >= CTL_PST_SEL_SYSPEER)
904: ip->flags |= INFO_FLAG_SHORTLIST;
905: ip->leap = pp->leap;
906: ip->hmode = pp->hmode;
907: ip->keyid = pp->keyid;
908: ip->stratum = pp->stratum;
909: ip->ppoll = pp->ppoll;
910: ip->hpoll = pp->hpoll;
911: ip->precision = pp->precision;
912: ip->version = pp->version;
913: ip->reach = pp->reach;
914: ip->unreach = (u_char) pp->unreach;
915: ip->flash = (u_char)pp->flash;
916: ip->flash2 = (u_short) pp->flash;
917: ip->estbdelay = HTONS_FP(DTOFP(pp->delay));
918: ip->ttl = pp->ttl;
919: ip->associd = htons(pp->associd);
920: ip->rootdelay = HTONS_FP(DTOUFP(pp->rootdelay));
921: ip->rootdispersion = HTONS_FP(DTOUFP(pp->rootdisp));
922: ip->refid = pp->refid;
923: HTONL_FP(&pp->reftime, &ip->reftime);
924: HTONL_FP(&pp->aorg, &ip->org);
925: HTONL_FP(&pp->rec, &ip->rec);
926: HTONL_FP(&pp->xmt, &ip->xmt);
927: j = pp->filter_nextpt - 1;
928: for (i = 0; i < NTP_SHIFT; i++, j--) {
929: if (j < 0)
930: j = NTP_SHIFT-1;
931: ip->filtdelay[i] = HTONS_FP(DTOFP(pp->filter_delay[j]));
932: DTOLFP(pp->filter_offset[j], <mp);
933: HTONL_FP(<mp, &ip->filtoffset[i]);
934: ip->order[i] = (u_char)((pp->filter_nextpt+NTP_SHIFT-1)
935: - pp->filter_order[i]);
936: if (ip->order[i] >= NTP_SHIFT)
937: ip->order[i] -= NTP_SHIFT;
938: }
939: DTOLFP(pp->offset, <mp);
940: HTONL_FP(<mp, &ip->offset);
941: ip->delay = HTONS_FP(DTOFP(pp->delay));
942: ip->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp)));
943: ip->selectdisp = HTONS_FP(DTOUFP(SQRT(pp->jitter)));
944: ip = (struct info_peer *)more_pkt();
945: }
946: flush_pkt();
947: }
948:
949:
950: /*
951: * peer_stats - send statistics for one or more peers
952: */
953: static void
954: peer_stats (
955: sockaddr_u *srcadr,
956: struct interface *inter,
957: struct req_pkt *inpkt
958: )
959: {
960: register struct info_peer_list *ipl;
961: register struct peer *pp;
962: register struct info_peer_stats *ip;
963: register int items;
964: sockaddr_u addr;
965: extern struct peer *sys_peer;
966:
967: #ifdef DEBUG
968: if (debug)
969: printf("peer_stats: called\n");
970: #endif
971: items = INFO_NITEMS(inpkt->err_nitems);
972: ipl = (struct info_peer_list *) inpkt->data;
973: ip = (struct info_peer_stats *)prepare_pkt(srcadr, inter, inpkt,
974: v6sizeof(struct info_peer_stats));
975: while (items-- > 0 && ip != 0) {
976: memset((char *)&addr, 0, sizeof(addr));
977: NSRCPORT(&addr) = ipl->port;
978: if (client_v6_capable && ipl->v6_flag) {
979: AF(&addr) = AF_INET6;
980: SOCK_ADDR6(&addr) = ipl->addr6;
981: } else {
982: AF(&addr) = AF_INET;
983: NSRCADR(&addr) = ipl->addr;
984: }
985: #ifdef ISC_PLATFORM_HAVESALEN
986: addr.sa.sa_len = SOCKLEN(&addr);
987: #endif
988: DPRINTF(1, ("peer_stats: looking for %s, %d, %d\n",
989: stoa(&addr), ipl->port, NSRCPORT(&addr)));
990:
991: ipl = (struct info_peer_list *)((char *)ipl +
992: INFO_ITEMSIZE(inpkt->mbz_itemsize));
993:
994: pp = findexistingpeer(&addr, NULL, -1, 0);
995: if (NULL == pp)
996: continue;
997:
998: DPRINTF(1, ("peer_stats: found %s\n", stoa(&addr)));
999:
1000: if (IS_IPV4(&pp->srcadr)) {
1001: if (pp->dstadr) {
1002: if (!pp->processed)
1003: ip->dstadr = NSRCADR(&pp->dstadr->sin);
1004: else {
1005: if (MDF_BCAST == pp->cast_flags)
1006: ip->dstadr = NSRCADR(&pp->dstadr->bcast);
1007: else if (pp->cast_flags) {
1008: ip->dstadr = NSRCADR(&pp->dstadr->sin);
1009: if (!ip->dstadr)
1010: ip->dstadr = NSRCADR(&pp->dstadr->bcast);
1011: }
1012: }
1013: } else
1014: ip->dstadr = 0;
1015:
1016: ip->srcadr = NSRCADR(&pp->srcadr);
1017: if (client_v6_capable)
1018: ip->v6_flag = 0;
1019: } else {
1020: if (pp->dstadr)
1021: ip->dstadr6 =
1022: (MDF_BCAST == pp->cast_flags)
1023: ? SOCK_ADDR6(&pp->dstadr->bcast)
1024: : SOCK_ADDR6(&pp->dstadr->sin);
1025: else
1026: memset(&ip->dstadr6, 0, sizeof(ip->dstadr6));
1027:
1028: ip->srcadr6 = SOCK_ADDR6(&pp->srcadr);
1029: ip->v6_flag = 1;
1030: }
1031: ip->srcport = NSRCPORT(&pp->srcadr);
1032: ip->flags = 0;
1033: if (pp == sys_peer)
1034: ip->flags |= INFO_FLAG_SYSPEER;
1035: if (pp->flags & FLAG_CONFIG)
1036: ip->flags |= INFO_FLAG_CONFIG;
1037: if (pp->flags & FLAG_REFCLOCK)
1038: ip->flags |= INFO_FLAG_REFCLOCK;
1039: if (pp->flags & FLAG_PREFER)
1040: ip->flags |= INFO_FLAG_PREFER;
1041: if (pp->flags & FLAG_BURST)
1042: ip->flags |= INFO_FLAG_BURST;
1043: if (pp->flags & FLAG_IBURST)
1044: ip->flags |= INFO_FLAG_IBURST;
1045: if (pp->status == CTL_PST_SEL_SYNCCAND)
1046: ip->flags |= INFO_FLAG_SEL_CANDIDATE;
1047: if (pp->status >= CTL_PST_SEL_SYSPEER)
1048: ip->flags |= INFO_FLAG_SHORTLIST;
1049: ip->flags = htons(ip->flags);
1050: ip->timereceived = htonl((u_int32)(current_time - pp->timereceived));
1051: ip->timetosend = htonl(pp->nextdate - current_time);
1052: ip->timereachable = htonl((u_int32)(current_time - pp->timereachable));
1053: ip->sent = htonl((u_int32)(pp->sent));
1054: ip->processed = htonl((u_int32)(pp->processed));
1055: ip->badauth = htonl((u_int32)(pp->badauth));
1056: ip->bogusorg = htonl((u_int32)(pp->bogusorg));
1057: ip->oldpkt = htonl((u_int32)(pp->oldpkt));
1058: ip->seldisp = htonl((u_int32)(pp->seldisptoolarge));
1059: ip->selbroken = htonl((u_int32)(pp->selbroken));
1060: ip->candidate = pp->status;
1061: ip = (struct info_peer_stats *)more_pkt();
1062: }
1063: flush_pkt();
1064: }
1065:
1066:
1067: /*
1068: * sys_info - return system info
1069: */
1070: static void
1071: sys_info(
1072: sockaddr_u *srcadr,
1073: struct interface *inter,
1074: struct req_pkt *inpkt
1075: )
1076: {
1077: register struct info_sys *is;
1078:
1079: is = (struct info_sys *)prepare_pkt(srcadr, inter, inpkt,
1080: v6sizeof(struct info_sys));
1081:
1082: if (sys_peer) {
1083: if (IS_IPV4(&sys_peer->srcadr)) {
1084: is->peer = NSRCADR(&sys_peer->srcadr);
1085: if (client_v6_capable)
1086: is->v6_flag = 0;
1087: } else if (client_v6_capable) {
1088: is->peer6 = SOCK_ADDR6(&sys_peer->srcadr);
1089: is->v6_flag = 1;
1090: }
1091: is->peer_mode = sys_peer->hmode;
1092: } else {
1093: is->peer = 0;
1094: if (client_v6_capable) {
1095: is->v6_flag = 0;
1096: }
1097: is->peer_mode = 0;
1098: }
1099:
1100: is->leap = sys_leap;
1101: is->stratum = sys_stratum;
1102: is->precision = sys_precision;
1103: is->rootdelay = htonl(DTOFP(sys_rootdelay));
1104: is->rootdispersion = htonl(DTOUFP(sys_rootdisp));
1105: is->frequency = htonl(DTOFP(sys_jitter));
1106: is->stability = htonl(DTOUFP(clock_stability));
1107: is->refid = sys_refid;
1108: HTONL_FP(&sys_reftime, &is->reftime);
1109:
1110: is->poll = sys_poll;
1111:
1112: is->flags = 0;
1113: if (sys_authenticate)
1114: is->flags |= INFO_FLAG_AUTHENTICATE;
1115: if (sys_bclient)
1116: is->flags |= INFO_FLAG_BCLIENT;
1117: #ifdef REFCLOCK
1118: if (cal_enable)
1119: is->flags |= INFO_FLAG_CAL;
1120: #endif /* REFCLOCK */
1121: if (kern_enable)
1122: is->flags |= INFO_FLAG_KERNEL;
1123: if (mon_enabled != MON_OFF)
1124: is->flags |= INFO_FLAG_MONITOR;
1125: if (ntp_enable)
1126: is->flags |= INFO_FLAG_NTP;
1127: if (pps_enable)
1128: is->flags |= INFO_FLAG_PPS_SYNC;
1129: if (stats_control)
1130: is->flags |= INFO_FLAG_FILEGEN;
1131: is->bdelay = HTONS_FP(DTOFP(sys_bdelay));
1132: HTONL_UF(sys_authdelay.l_f, &is->authdelay);
1133: (void) more_pkt();
1134: flush_pkt();
1135: }
1136:
1137:
1138: /*
1139: * sys_stats - return system statistics
1140: */
1141: static void
1142: sys_stats(
1143: sockaddr_u *srcadr,
1144: struct interface *inter,
1145: struct req_pkt *inpkt
1146: )
1147: {
1148: register struct info_sys_stats *ss;
1149:
1150: /*
1151: * Importations from the protocol module
1152: */
1153: ss = (struct info_sys_stats *)prepare_pkt(srcadr, inter, inpkt,
1154: sizeof(struct info_sys_stats));
1155: ss->timeup = htonl((u_int32)current_time);
1156: ss->timereset = htonl((u_int32)(current_time - sys_stattime));
1157: ss->denied = htonl((u_int32)sys_restricted);
1158: ss->oldversionpkt = htonl((u_int32)sys_oldversion);
1159: ss->newversionpkt = htonl((u_int32)sys_newversion);
1160: ss->unknownversion = htonl((u_int32)sys_declined);
1161: ss->badlength = htonl((u_int32)sys_badlength);
1162: ss->processed = htonl((u_int32)sys_processed);
1163: ss->badauth = htonl((u_int32)sys_badauth);
1164: ss->limitrejected = htonl((u_int32)sys_limitrejected);
1165: ss->received = htonl((u_int32)sys_received);
1166: (void) more_pkt();
1167: flush_pkt();
1168: }
1169:
1170:
1171: /*
1172: * mem_stats - return memory statistics
1173: */
1174: static void
1175: mem_stats(
1176: sockaddr_u *srcadr,
1177: struct interface *inter,
1178: struct req_pkt *inpkt
1179: )
1180: {
1181: register struct info_mem_stats *ms;
1182: register int i;
1183:
1184: /*
1185: * Importations from the peer module
1186: */
1187: extern int peer_hash_count[NTP_HASH_SIZE];
1188: extern int peer_free_count;
1189: extern u_long peer_timereset;
1190: extern u_long findpeer_calls;
1191: extern u_long peer_allocations;
1192: extern u_long peer_demobilizations;
1193: extern int total_peer_structs;
1194:
1195: ms = (struct info_mem_stats *)prepare_pkt(srcadr, inter, inpkt,
1196: sizeof(struct info_mem_stats));
1197:
1198: ms->timereset = htonl((u_int32)(current_time - peer_timereset));
1199: ms->totalpeermem = htons((u_short)total_peer_structs);
1200: ms->freepeermem = htons((u_short)peer_free_count);
1201: ms->findpeer_calls = htonl((u_int32)findpeer_calls);
1202: ms->allocations = htonl((u_int32)peer_allocations);
1203: ms->demobilizations = htonl((u_int32)peer_demobilizations);
1204:
1205: for (i = 0; i < NTP_HASH_SIZE; i++) {
1206: if (peer_hash_count[i] > 255)
1207: ms->hashcount[i] = 255;
1208: else
1209: ms->hashcount[i] = (u_char)peer_hash_count[i];
1210: }
1211:
1212: (void) more_pkt();
1213: flush_pkt();
1214: }
1215:
1216:
1217: /*
1218: * io_stats - return io statistics
1219: */
1220: static void
1221: io_stats(
1222: sockaddr_u *srcadr,
1223: struct interface *inter,
1224: struct req_pkt *inpkt
1225: )
1226: {
1227: register struct info_io_stats *io;
1228:
1229: /*
1230: * Importations from the io module
1231: */
1232: extern u_long io_timereset;
1233:
1234: io = (struct info_io_stats *)prepare_pkt(srcadr, inter, inpkt,
1235: sizeof(struct info_io_stats));
1236:
1237: io->timereset = htonl((u_int32)(current_time - io_timereset));
1238: io->totalrecvbufs = htons((u_short) total_recvbuffs());
1239: io->freerecvbufs = htons((u_short) free_recvbuffs());
1240: io->fullrecvbufs = htons((u_short) full_recvbuffs());
1241: io->lowwater = htons((u_short) lowater_additions());
1242: io->dropped = htonl((u_int32)packets_dropped);
1243: io->ignored = htonl((u_int32)packets_ignored);
1244: io->received = htonl((u_int32)packets_received);
1245: io->sent = htonl((u_int32)packets_sent);
1246: io->notsent = htonl((u_int32)packets_notsent);
1247: io->interrupts = htonl((u_int32)handler_calls);
1248: io->int_received = htonl((u_int32)handler_pkts);
1249:
1250: (void) more_pkt();
1251: flush_pkt();
1252: }
1253:
1254:
1255: /*
1256: * timer_stats - return timer statistics
1257: */
1258: static void
1259: timer_stats(
1260: sockaddr_u * srcadr,
1261: struct interface * inter,
1262: struct req_pkt * inpkt
1263: )
1264: {
1265: struct info_timer_stats * ts;
1266: u_long sincereset;
1267:
1268: ts = (struct info_timer_stats *)prepare_pkt(srcadr, inter,
1269: inpkt, sizeof(*ts));
1270:
1271: sincereset = current_time - timer_timereset;
1272: ts->timereset = htonl((u_int32)sincereset);
1273: ts->alarms = ts->timereset;
1274: ts->overflows = htonl((u_int32)alarm_overflow);
1275: ts->xmtcalls = htonl((u_int32)timer_xmtcalls);
1276:
1277: (void) more_pkt();
1278: flush_pkt();
1279: }
1280:
1281:
1282: /*
1283: * loop_info - return the current state of the loop filter
1284: */
1285: static void
1286: loop_info(
1287: sockaddr_u *srcadr,
1288: struct interface *inter,
1289: struct req_pkt *inpkt
1290: )
1291: {
1292: register struct info_loop *li;
1293: l_fp ltmp;
1294:
1295: /*
1296: * Importations from the loop filter module
1297: */
1298: extern double last_offset;
1299: extern double drift_comp;
1300: extern int tc_counter;
1301: extern u_long sys_epoch;
1302:
1303: li = (struct info_loop *)prepare_pkt(srcadr, inter, inpkt,
1304: sizeof(struct info_loop));
1305:
1306: DTOLFP(last_offset, <mp);
1307: HTONL_FP(<mp, &li->last_offset);
1308: DTOLFP(drift_comp * 1e6, <mp);
1309: HTONL_FP(<mp, &li->drift_comp);
1310: li->compliance = htonl((u_int32)(tc_counter));
1311: li->watchdog_timer = htonl((u_int32)(current_time - sys_epoch));
1312:
1313: (void) more_pkt();
1314: flush_pkt();
1315: }
1316:
1317:
1318: /*
1319: * do_conf - add a peer to the configuration list
1320: */
1321: static void
1322: do_conf(
1323: sockaddr_u *srcadr,
1324: struct interface *inter,
1325: struct req_pkt *inpkt
1326: )
1327: {
1328: static u_long soonest_ifrescan_time = 0;
1329: int items;
1330: u_int fl;
1331: struct conf_peer *cp;
1332: struct conf_peer temp_cp;
1333: sockaddr_u peeraddr;
1334:
1335: /*
1336: * Do a check of everything to see that it looks
1337: * okay. If not, complain about it. Note we are
1338: * very picky here.
1339: */
1340: items = INFO_NITEMS(inpkt->err_nitems);
1341: cp = (struct conf_peer *)inpkt->data;
1342: memset(&temp_cp, 0, sizeof(struct conf_peer));
1343: memcpy(&temp_cp, (char *)cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
1344:
1345: #if 0 /* paranoid checking - these are done in newpeer() */
1346: fl = 0;
1347: while (items-- > 0 && !fl) {
1348: if (((temp_cp.version) > NTP_VERSION)
1349: || ((temp_cp.version) < NTP_OLDVERSION))
1350: fl = 1;
1351: if (temp_cp.hmode != MODE_ACTIVE
1352: && temp_cp.hmode != MODE_CLIENT
1353: && temp_cp.hmode != MODE_BROADCAST)
1354: fl = 1;
1355: if (temp_cp.flags & ~(CONF_FLAG_PREFER | CONF_FLAG_BURST |
1356: CONF_FLAG_IBURST | CONF_FLAG_SKEY))
1357: fl = 1;
1358: cp = (struct conf_peer *)
1359: ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
1360: }
1361:
1362: if (fl) {
1363: req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1364: return;
1365: }
1366: #endif /* end paranoid checking */
1367:
1368: /*
1369: * Looks okay, try it out
1370: */
1371: items = INFO_NITEMS(inpkt->err_nitems);
1372: cp = (struct conf_peer *)inpkt->data;
1373:
1374: while (items-- > 0) {
1375: memset(&temp_cp, 0, sizeof(struct conf_peer));
1376: memcpy(&temp_cp, (char *)cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
1377: ZERO_SOCK(&peeraddr);
1378:
1379: fl = 0;
1380: if (temp_cp.flags & CONF_FLAG_PREFER)
1381: fl |= FLAG_PREFER;
1382: if (temp_cp.flags & CONF_FLAG_BURST)
1383: fl |= FLAG_BURST;
1384: if (temp_cp.flags & CONF_FLAG_IBURST)
1385: fl |= FLAG_IBURST;
1386: #ifdef OPENSSL
1387: if (temp_cp.flags & CONF_FLAG_SKEY)
1388: fl |= FLAG_SKEY;
1389: #endif /* OPENSSL */
1390: if (client_v6_capable && temp_cp.v6_flag != 0) {
1391: AF(&peeraddr) = AF_INET6;
1392: SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6;
1393: } else {
1394: AF(&peeraddr) = AF_INET;
1395: NSRCADR(&peeraddr) = temp_cp.peeraddr;
1396: /*
1397: * Make sure the address is valid
1398: */
1399: if (!ISREFCLOCKADR(&peeraddr) &&
1400: ISBADADR(&peeraddr)) {
1401: req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1402: return;
1403: }
1404:
1405: }
1406: NSRCPORT(&peeraddr) = htons(NTP_PORT);
1407: #ifdef ISC_PLATFORM_HAVESALEN
1408: peeraddr.sa.sa_len = SOCKLEN(&peeraddr);
1409: #endif
1410:
1411: /* XXX W2DO? minpoll/maxpoll arguments ??? */
1412: if (peer_config(&peeraddr, (struct interface *)0,
1413: temp_cp.hmode, temp_cp.version, temp_cp.minpoll,
1414: temp_cp.maxpoll, fl, temp_cp.ttl, temp_cp.keyid,
1415: NULL) == 0) {
1416: req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1417: return;
1418: }
1419:
1420: /*
1421: * ntp_intres.c uses REQ_CONFIG/doconf() to add each
1422: * server after its name is resolved. If we have been
1423: * disconnected from the network, it may notice the
1424: * network has returned and add the first server while
1425: * the relevant interface is still disabled, awaiting
1426: * the next interface rescan. To get things moving
1427: * more quickly, trigger an interface scan now, except
1428: * if we have done so in the last half minute.
1429: */
1430: if (soonest_ifrescan_time < current_time) {
1431: soonest_ifrescan_time = current_time + 30;
1432: timer_interfacetimeout(current_time);
1433: DPRINTF(1, ("do_conf triggering interface rescan\n"));
1434: }
1435:
1436: cp = (struct conf_peer *)
1437: ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
1438: }
1439:
1440: req_ack(srcadr, inter, inpkt, INFO_OKAY);
1441: }
1442:
1443: #if 0
1444: /* XXX */
1445: /*
1446: * dns_a - Snarf DNS info for an association ID
1447: */
1448: static void
1449: dns_a(
1450: sockaddr_u *srcadr,
1451: struct interface *inter,
1452: struct req_pkt *inpkt
1453: )
1454: {
1455: register struct info_dns_assoc *dp;
1456: register int items;
1457: struct sockaddr_in peeraddr;
1458:
1459: /*
1460: * Do a check of everything to see that it looks
1461: * okay. If not, complain about it. Note we are
1462: * very picky here.
1463: */
1464: items = INFO_NITEMS(inpkt->err_nitems);
1465: dp = (struct info_dns_assoc *)inpkt->data;
1466:
1467: /*
1468: * Looks okay, try it out
1469: */
1470: items = INFO_NITEMS(inpkt->err_nitems);
1471: dp = (struct info_dns_assoc *)inpkt->data;
1472: memset((char *)&peeraddr, 0, sizeof(struct sockaddr_in));
1473: peeraddr.sin_family = AF_INET;
1474: peeraddr.sin_port = htons(NTP_PORT);
1475:
1476: /*
1477: * Make sure the address is valid
1478: */
1479: if (!ISREFCLOCKADR(&peeraddr) && ISBADADR(&peeraddr)) {
1480: msyslog(LOG_ERR, "dns_a: !ISREFCLOCKADR && ISBADADR");
1481: req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1482: return;
1483: }
1484:
1485: while (items-- > 0) {
1486: associd_t associd;
1487: size_t hnl;
1488: struct peer *peer;
1489: int bogon = 0;
1490:
1491: associd = dp->associd;
1492: peer = findpeerbyassoc(associd);
1493: if (peer == 0 || peer->flags & FLAG_REFCLOCK) {
1494: msyslog(LOG_ERR, "dns_a: %s",
1495: (peer == 0)
1496: ? "peer == 0"
1497: : "peer->flags & FLAG_REFCLOCK");
1498: ++bogon;
1499: }
1500: peeraddr.sin_addr.s_addr = dp->peeraddr;
1501: for (hnl = 0; dp->hostname[hnl] && hnl < sizeof dp->hostname; ++hnl) ;
1502: if (hnl >= sizeof dp->hostname) {
1503: msyslog(LOG_ERR, "dns_a: hnl (%ld) >= %ld",
1504: (long)hnl, (long)sizeof dp->hostname);
1505: ++bogon;
1506: }
1507:
1508: msyslog(LOG_INFO, "dns_a: <%s> for %s, AssocID %d, bogon %d",
1509: dp->hostname,
1510: stoa((sockaddr_u *)&peeraddr), associd,
1511: bogon);
1512:
1513: if (bogon) {
1514: /* If it didn't work */
1515: req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1516: return;
1517: } else {
1518: #if 0
1519: #ifdef PUBKEY
1520: crypto_public(peer, dp->hostname);
1521: #endif /* PUBKEY */
1522: #endif
1523: }
1524:
1525: dp++;
1526: }
1527:
1528: req_ack(srcadr, inter, inpkt, INFO_OKAY);
1529: }
1530: #endif /* 0 */
1531:
1532: /*
1533: * do_unconf - remove a peer from the configuration list
1534: */
1535: static void
1536: do_unconf(
1537: sockaddr_u *srcadr,
1538: struct interface *inter,
1539: struct req_pkt *inpkt
1540: )
1541: {
1542: register struct conf_unpeer *cp;
1543: struct conf_unpeer temp_cp;
1544: register int items;
1545: register struct peer *peer;
1546: sockaddr_u peeraddr;
1547: int bad, found;
1548:
1549: /*
1550: * This is a bit unstructured, but I like to be careful.
1551: * We check to see that every peer exists and is actually
1552: * configured. If so, we remove them. If not, we return
1553: * an error.
1554: */
1555: items = INFO_NITEMS(inpkt->err_nitems);
1556: cp = (struct conf_unpeer *)inpkt->data;
1557:
1558: bad = 0;
1559: while (items-- > 0 && !bad) {
1560: memset(&temp_cp, 0, sizeof(temp_cp));
1561: ZERO_SOCK(&peeraddr);
1562: memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
1563: if (client_v6_capable && temp_cp.v6_flag) {
1564: AF(&peeraddr) = AF_INET6;
1565: SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6;
1566: } else {
1567: AF(&peeraddr) = AF_INET;
1568: NSRCADR(&peeraddr) = temp_cp.peeraddr;
1569: }
1570: SET_PORT(&peeraddr, NTP_PORT);
1571: #ifdef ISC_PLATFORM_HAVESALEN
1572: peeraddr.sa.sa_len = SOCKLEN(&peeraddr);
1573: #endif
1574: found = 0;
1575: peer = NULL;
1576:
1577: DPRINTF(1, ("searching for %s\n", stoa(&peeraddr)));
1578:
1579: while (!found) {
1580: peer = findexistingpeer(&peeraddr, peer, -1, 0);
1581: if (!peer)
1582: break;
1583: if (peer->flags & FLAG_CONFIG)
1584: found = 1;
1585: }
1586: if (!found)
1587: bad = 1;
1588: cp = (struct conf_unpeer *)
1589: ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
1590: }
1591:
1592: if (bad) {
1593: req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1594: return;
1595: }
1596:
1597: /*
1598: * Now do it in earnest.
1599: */
1600:
1601: items = INFO_NITEMS(inpkt->err_nitems);
1602: cp = (struct conf_unpeer *)inpkt->data;
1603:
1604: while (items-- > 0) {
1605: memset(&temp_cp, 0, sizeof(temp_cp));
1606: memset(&peeraddr, 0, sizeof(peeraddr));
1607: memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize));
1608: if (client_v6_capable && temp_cp.v6_flag) {
1609: AF(&peeraddr) = AF_INET6;
1610: SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6;
1611: } else {
1612: AF(&peeraddr) = AF_INET;
1613: NSRCADR(&peeraddr) = temp_cp.peeraddr;
1614: }
1615: SET_PORT(&peeraddr, NTP_PORT);
1616: #ifdef ISC_PLATFORM_HAVESALEN
1617: peeraddr.sa.sa_len = SOCKLEN(&peeraddr);
1618: #endif
1619: found = 0;
1620: peer = NULL;
1621:
1622: while (!found) {
1623: peer = findexistingpeer(&peeraddr, peer, -1, 0);
1624: if (!peer)
1625: break;
1626: if (peer->flags & FLAG_CONFIG)
1627: found = 1;
1628: }
1629: NTP_INSIST(found);
1630: NTP_INSIST(peer);
1631:
1632: peer_clear(peer, "GONE");
1633: unpeer(peer);
1634:
1635: cp = (struct conf_unpeer *)
1636: ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
1637: }
1638:
1639: req_ack(srcadr, inter, inpkt, INFO_OKAY);
1640: }
1641:
1642:
1643: /*
1644: * set_sys_flag - set system flags
1645: */
1646: static void
1647: set_sys_flag(
1648: sockaddr_u *srcadr,
1649: struct interface *inter,
1650: struct req_pkt *inpkt
1651: )
1652: {
1653: setclr_flags(srcadr, inter, inpkt, 1);
1654: }
1655:
1656:
1657: /*
1658: * clr_sys_flag - clear system flags
1659: */
1660: static void
1661: clr_sys_flag(
1662: sockaddr_u *srcadr,
1663: struct interface *inter,
1664: struct req_pkt *inpkt
1665: )
1666: {
1667: setclr_flags(srcadr, inter, inpkt, 0);
1668: }
1669:
1670:
1671: /*
1672: * setclr_flags - do the grunge work of flag setting/clearing
1673: */
1674: static void
1675: setclr_flags(
1676: sockaddr_u *srcadr,
1677: struct interface *inter,
1678: struct req_pkt *inpkt,
1679: u_long set
1680: )
1681: {
1682: struct conf_sys_flags *sf;
1683: u_int32 flags;
1684: int prev_kern_enable;
1685:
1686: prev_kern_enable = kern_enable;
1687: if (INFO_NITEMS(inpkt->err_nitems) > 1) {
1688: msyslog(LOG_ERR, "setclr_flags: err_nitems > 1");
1689: req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1690: return;
1691: }
1692:
1693: sf = (struct conf_sys_flags *)inpkt->data;
1694: flags = ntohl(sf->flags);
1695:
1696: if (flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_PPS |
1697: SYS_FLAG_NTP | SYS_FLAG_KERNEL | SYS_FLAG_MONITOR |
1698: SYS_FLAG_FILEGEN | SYS_FLAG_AUTH | SYS_FLAG_CAL)) {
1699: msyslog(LOG_ERR, "setclr_flags: extra flags: %#x",
1700: flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_PPS |
1701: SYS_FLAG_NTP | SYS_FLAG_KERNEL |
1702: SYS_FLAG_MONITOR | SYS_FLAG_FILEGEN |
1703: SYS_FLAG_AUTH | SYS_FLAG_CAL));
1704: req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1705: return;
1706: }
1707:
1708: if (flags & SYS_FLAG_BCLIENT)
1709: proto_config(PROTO_BROADCLIENT, set, 0., NULL);
1710: if (flags & SYS_FLAG_PPS)
1711: proto_config(PROTO_PPS, set, 0., NULL);
1712: if (flags & SYS_FLAG_NTP)
1713: proto_config(PROTO_NTP, set, 0., NULL);
1714: if (flags & SYS_FLAG_KERNEL)
1715: proto_config(PROTO_KERNEL, set, 0., NULL);
1716: if (flags & SYS_FLAG_MONITOR)
1717: proto_config(PROTO_MONITOR, set, 0., NULL);
1718: if (flags & SYS_FLAG_FILEGEN)
1719: proto_config(PROTO_FILEGEN, set, 0., NULL);
1720: if (flags & SYS_FLAG_AUTH)
1721: proto_config(PROTO_AUTHENTICATE, set, 0., NULL);
1722: if (flags & SYS_FLAG_CAL)
1723: proto_config(PROTO_CAL, set, 0., NULL);
1724: req_ack(srcadr, inter, inpkt, INFO_OKAY);
1725:
1726: /* Reset the kernel ntp parameters if the kernel flag changed. */
1727: if (prev_kern_enable && !kern_enable)
1728: loop_config(LOOP_KERN_CLEAR, 0.0);
1729: if (!prev_kern_enable && kern_enable)
1730: loop_config(LOOP_DRIFTCOMP, drift_comp);
1731: }
1732:
1733: /*
1734: * list_restrict4 - recursive helper for list_restrict dumps IPv4
1735: * restriction list in reverse order.
1736: */
1737: static void
1738: list_restrict4(
1739: restrict_u * res,
1740: struct info_restrict ** ppir
1741: )
1742: {
1743: struct info_restrict * pir;
1744:
1745: if (res->link != NULL)
1746: list_restrict4(res->link, ppir);
1747:
1748: pir = *ppir;
1749: pir->addr = htonl(res->u.v4.addr);
1750: if (client_v6_capable)
1751: pir->v6_flag = 0;
1752: pir->mask = htonl(res->u.v4.mask);
1753: pir->count = htonl(res->count);
1754: pir->flags = htons(res->flags);
1755: pir->mflags = htons(res->mflags);
1756: *ppir = (struct info_restrict *)more_pkt();
1757: }
1758:
1759:
1760: /*
1761: * list_restrict6 - recursive helper for list_restrict dumps IPv6
1762: * restriction list in reverse order.
1763: */
1764: static void
1765: list_restrict6(
1766: restrict_u * res,
1767: struct info_restrict ** ppir
1768: )
1769: {
1770: struct info_restrict * pir;
1771:
1772: if (res->link != NULL)
1773: list_restrict6(res->link, ppir);
1774:
1775: pir = *ppir;
1776: pir->addr6 = res->u.v6.addr;
1777: pir->mask6 = res->u.v6.mask;
1778: pir->v6_flag = 1;
1779: pir->count = htonl(res->count);
1780: pir->flags = htons(res->flags);
1781: pir->mflags = htons(res->mflags);
1782: *ppir = (struct info_restrict *)more_pkt();
1783: }
1784:
1785:
1786: /*
1787: * list_restrict - return the restrict list
1788: */
1789: static void
1790: list_restrict(
1791: sockaddr_u *srcadr,
1792: struct interface *inter,
1793: struct req_pkt *inpkt
1794: )
1795: {
1796: struct info_restrict *ir;
1797:
1798: DPRINTF(3, ("wants restrict list summary\n"));
1799:
1800: ir = (struct info_restrict *)prepare_pkt(srcadr, inter, inpkt,
1801: v6sizeof(struct info_restrict));
1802:
1803: /*
1804: * The restriction lists are kept sorted in the reverse order
1805: * than they were originally. To preserve the output semantics,
1806: * dump each list in reverse order. A recursive helper function
1807: * achieves that.
1808: */
1809: list_restrict4(restrictlist4, &ir);
1810: if (client_v6_capable)
1811: list_restrict6(restrictlist6, &ir);
1812: flush_pkt();
1813: }
1814:
1815:
1816: /*
1817: * do_resaddflags - add flags to a restrict entry (or create one)
1818: */
1819: static void
1820: do_resaddflags(
1821: sockaddr_u *srcadr,
1822: struct interface *inter,
1823: struct req_pkt *inpkt
1824: )
1825: {
1826: do_restrict(srcadr, inter, inpkt, RESTRICT_FLAGS);
1827: }
1828:
1829:
1830:
1831: /*
1832: * do_ressubflags - remove flags from a restrict entry
1833: */
1834: static void
1835: do_ressubflags(
1836: sockaddr_u *srcadr,
1837: struct interface *inter,
1838: struct req_pkt *inpkt
1839: )
1840: {
1841: do_restrict(srcadr, inter, inpkt, RESTRICT_UNFLAG);
1842: }
1843:
1844:
1845: /*
1846: * do_unrestrict - remove a restrict entry from the list
1847: */
1848: static void
1849: do_unrestrict(
1850: sockaddr_u *srcadr,
1851: struct interface *inter,
1852: struct req_pkt *inpkt
1853: )
1854: {
1855: do_restrict(srcadr, inter, inpkt, RESTRICT_REMOVE);
1856: }
1857:
1858:
1859: /*
1860: * do_restrict - do the dirty stuff of dealing with restrictions
1861: */
1862: static void
1863: do_restrict(
1864: sockaddr_u *srcadr,
1865: struct interface *inter,
1866: struct req_pkt *inpkt,
1867: int op
1868: )
1869: {
1870: register struct conf_restrict *cr;
1871: register int items;
1872: sockaddr_u matchaddr;
1873: sockaddr_u matchmask;
1874: int bad;
1875:
1876: /*
1877: * Do a check of the flags to make sure that only
1878: * the NTPPORT flag is set, if any. If not, complain
1879: * about it. Note we are very picky here.
1880: */
1881: items = INFO_NITEMS(inpkt->err_nitems);
1882: cr = (struct conf_restrict *)inpkt->data;
1883:
1884: bad = 0;
1885: cr->flags = ntohs(cr->flags);
1886: cr->mflags = ntohs(cr->mflags);
1887: while (items-- > 0 && !bad) {
1888: if (cr->mflags & ~(RESM_NTPONLY))
1889: bad |= 1;
1890: if (cr->flags & ~(RES_ALLFLAGS))
1891: bad |= 2;
1892: if (cr->mask != htonl(INADDR_ANY)) {
1893: if (client_v6_capable && cr->v6_flag != 0) {
1894: if (IN6_IS_ADDR_UNSPECIFIED(&cr->addr6))
1895: bad |= 4;
1896: } else
1897: if (cr->addr == htonl(INADDR_ANY))
1898: bad |= 8;
1899: }
1900: cr = (struct conf_restrict *)((char *)cr +
1901: INFO_ITEMSIZE(inpkt->mbz_itemsize));
1902: }
1903:
1904: if (bad) {
1905: msyslog(LOG_ERR, "do_restrict: bad = %#x", bad);
1906: req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1907: return;
1908: }
1909:
1910: /*
1911: * Looks okay, try it out
1912: */
1913: items = INFO_NITEMS(inpkt->err_nitems);
1914: cr = (struct conf_restrict *)inpkt->data;
1915: ZERO_SOCK(&matchaddr);
1916: ZERO_SOCK(&matchmask);
1917:
1918: while (items-- > 0) {
1919: if (client_v6_capable && cr->v6_flag) {
1920: AF(&matchaddr) = AF_INET6;
1921: AF(&matchmask) = AF_INET6;
1922: SOCK_ADDR6(&matchaddr) = cr->addr6;
1923: SOCK_ADDR6(&matchmask) = cr->mask6;
1924: } else {
1925: AF(&matchaddr) = AF_INET;
1926: AF(&matchmask) = AF_INET;
1927: NSRCADR(&matchaddr) = cr->addr;
1928: NSRCADR(&matchmask) = cr->mask;
1929: }
1930: hack_restrict(op, &matchaddr, &matchmask, cr->mflags,
1931: cr->flags);
1932: cr++;
1933: }
1934:
1935: req_ack(srcadr, inter, inpkt, INFO_OKAY);
1936: }
1937:
1938:
1939: /*
1940: * mon_getlist - return monitor data
1941: */
1942: static void
1943: mon_getlist_0(
1944: sockaddr_u *srcadr,
1945: struct interface *inter,
1946: struct req_pkt *inpkt
1947: )
1948: {
1949: register struct info_monitor *im;
1950: register struct mon_data *md;
1951: extern struct mon_data mon_mru_list;
1952: extern int mon_enabled;
1953:
1954: #ifdef DEBUG
1955: if (debug > 2)
1956: printf("wants monitor 0 list\n");
1957: #endif
1958: if (!mon_enabled) {
1959: req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
1960: return;
1961: }
1962: im = (struct info_monitor *)prepare_pkt(srcadr, inter, inpkt,
1963: v6sizeof(struct info_monitor));
1964: for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0;
1965: md = md->mru_next) {
1966: im->lasttime = htonl((u_int32)((current_time -
1967: md->firsttime) / md->count));
1968: im->firsttime = htonl((u_int32)(current_time - md->lasttime));
1969: im->restr = htonl((u_int32)md->flags);
1970: im->count = htonl((u_int32)(md->count));
1971: if (IS_IPV6(&md->rmtadr)) {
1972: if (!client_v6_capable)
1973: continue;
1974: im->addr6 = SOCK_ADDR6(&md->rmtadr);
1975: im->v6_flag = 1;
1976: } else {
1977: im->addr = NSRCADR(&md->rmtadr);
1978: if (client_v6_capable)
1979: im->v6_flag = 0;
1980: }
1981: im->port = md->rmtport;
1982: im->mode = md->mode;
1983: im->version = md->version;
1984: im = (struct info_monitor *)more_pkt();
1985: }
1986: flush_pkt();
1987: }
1988:
1989: /*
1990: * mon_getlist - return monitor data
1991: */
1992: static void
1993: mon_getlist_1(
1994: sockaddr_u *srcadr,
1995: struct interface *inter,
1996: struct req_pkt *inpkt
1997: )
1998: {
1999: register struct info_monitor_1 *im;
2000: register struct mon_data *md;
2001: extern struct mon_data mon_mru_list;
2002: extern int mon_enabled;
2003:
2004: if (!mon_enabled) {
2005: req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2006: return;
2007: }
2008: im = (struct info_monitor_1 *)prepare_pkt(srcadr, inter, inpkt,
2009: v6sizeof(struct info_monitor_1));
2010: for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0;
2011: md = md->mru_next) {
2012: im->lasttime = htonl((u_int32)((current_time -
2013: md->firsttime) / md->count));
2014: im->firsttime = htonl((u_int32)(current_time - md->lasttime));
2015: im->restr = htonl((u_int32)md->flags);
2016: im->count = htonl((u_int32)md->count);
2017: if (IS_IPV6(&md->rmtadr)) {
2018: if (!client_v6_capable)
2019: continue;
2020: im->addr6 = SOCK_ADDR6(&md->rmtadr);
2021: im->v6_flag = 1;
2022: im->daddr6 = SOCK_ADDR6(&md->interface->sin);
2023: } else {
2024: im->addr = NSRCADR(&md->rmtadr);
2025: if (client_v6_capable)
2026: im->v6_flag = 0;
2027: if (MDF_BCAST == md->cast_flags)
2028: im->daddr = NSRCADR(&md->interface->bcast);
2029: else if (md->cast_flags) {
2030: im->daddr = NSRCADR(&md->interface->sin);
2031: if (!im->daddr)
2032: im->daddr = NSRCADR(&md->interface->bcast);
2033: } else
2034: im->daddr = 4;
2035: }
2036: im->flags = htonl(md->cast_flags);
2037: im->port = md->rmtport;
2038: im->mode = md->mode;
2039: im->version = md->version;
2040: im = (struct info_monitor_1 *)more_pkt();
2041: }
2042: flush_pkt();
2043: }
2044:
2045: /*
2046: * Module entry points and the flags they correspond with
2047: */
2048: struct reset_entry {
2049: int flag; /* flag this corresponds to */
2050: void (*handler) (void); /* routine to handle request */
2051: };
2052:
2053: struct reset_entry reset_entries[] = {
2054: { RESET_FLAG_ALLPEERS, peer_all_reset },
2055: { RESET_FLAG_IO, io_clr_stats },
2056: { RESET_FLAG_SYS, proto_clr_stats },
2057: { RESET_FLAG_MEM, peer_clr_stats },
2058: { RESET_FLAG_TIMER, timer_clr_stats },
2059: { RESET_FLAG_AUTH, reset_auth_stats },
2060: { RESET_FLAG_CTL, ctl_clr_stats },
2061: { 0, 0 }
2062: };
2063:
2064: /*
2065: * reset_stats - reset statistic counters here and there
2066: */
2067: static void
2068: reset_stats(
2069: sockaddr_u *srcadr,
2070: struct interface *inter,
2071: struct req_pkt *inpkt
2072: )
2073: {
2074: struct reset_flags *rflags;
2075: u_long flags;
2076: struct reset_entry *rent;
2077:
2078: if (INFO_NITEMS(inpkt->err_nitems) > 1) {
2079: msyslog(LOG_ERR, "reset_stats: err_nitems > 1");
2080: req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2081: return;
2082: }
2083:
2084: rflags = (struct reset_flags *)inpkt->data;
2085: flags = ntohl(rflags->flags);
2086:
2087: if (flags & ~RESET_ALLFLAGS) {
2088: msyslog(LOG_ERR, "reset_stats: reset leaves %#lx",
2089: flags & ~RESET_ALLFLAGS);
2090: req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2091: return;
2092: }
2093:
2094: for (rent = reset_entries; rent->flag != 0; rent++) {
2095: if (flags & rent->flag)
2096: (*rent->handler)();
2097: }
2098: req_ack(srcadr, inter, inpkt, INFO_OKAY);
2099: }
2100:
2101:
2102: /*
2103: * reset_peer - clear a peer's statistics
2104: */
2105: static void
2106: reset_peer(
2107: sockaddr_u *srcadr,
2108: struct interface *inter,
2109: struct req_pkt *inpkt
2110: )
2111: {
2112: struct conf_unpeer *cp;
2113: int items;
2114: struct peer *peer;
2115: sockaddr_u peeraddr;
2116: int bad;
2117:
2118: /*
2119: * We check first to see that every peer exists. If not,
2120: * we return an error.
2121: */
2122:
2123: items = INFO_NITEMS(inpkt->err_nitems);
2124: cp = (struct conf_unpeer *)inpkt->data;
2125:
2126: bad = 0;
2127: while (items-- > 0 && !bad) {
2128: ZERO_SOCK(&peeraddr);
2129: if (client_v6_capable && cp->v6_flag) {
2130: AF(&peeraddr) = AF_INET6;
2131: SOCK_ADDR6(&peeraddr) = cp->peeraddr6;
2132: } else {
2133: AF(&peeraddr) = AF_INET;
2134: NSRCADR(&peeraddr) = cp->peeraddr;
2135: }
2136:
2137: #ifdef ISC_PLATFORM_HAVESALEN
2138: peeraddr.sa.sa_len = SOCKLEN(&peeraddr);
2139: #endif
2140: peer = findexistingpeer(&peeraddr, NULL, -1, 0);
2141: if (NULL == peer)
2142: bad++;
2143: cp = (struct conf_unpeer *)((char *)cp +
2144: INFO_ITEMSIZE(inpkt->mbz_itemsize));
2145: }
2146:
2147: if (bad) {
2148: req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2149: return;
2150: }
2151:
2152: /*
2153: * Now do it in earnest.
2154: */
2155:
2156: items = INFO_NITEMS(inpkt->err_nitems);
2157: cp = (struct conf_unpeer *)inpkt->data;
2158: while (items-- > 0) {
2159: ZERO_SOCK(&peeraddr);
2160: if (client_v6_capable && cp->v6_flag) {
2161: AF(&peeraddr) = AF_INET6;
2162: SOCK_ADDR6(&peeraddr) = cp->peeraddr6;
2163: } else {
2164: AF(&peeraddr) = AF_INET;
2165: NSRCADR(&peeraddr) = cp->peeraddr;
2166: }
2167: SET_PORT(&peeraddr, 123);
2168: #ifdef ISC_PLATFORM_HAVESALEN
2169: peeraddr.sa.sa_len = SOCKLEN(&peeraddr);
2170: #endif
2171: peer = findexistingpeer(&peeraddr, NULL, -1, 0);
2172: while (peer != NULL) {
2173: peer_reset(peer);
2174: peer = findexistingpeer(&peeraddr, peer, -1, 0);
2175: }
2176: cp = (struct conf_unpeer *)((char *)cp +
2177: INFO_ITEMSIZE(inpkt->mbz_itemsize));
2178: }
2179:
2180: req_ack(srcadr, inter, inpkt, INFO_OKAY);
2181: }
2182:
2183:
2184: /*
2185: * do_key_reread - reread the encryption key file
2186: */
2187: static void
2188: do_key_reread(
2189: sockaddr_u *srcadr,
2190: struct interface *inter,
2191: struct req_pkt *inpkt
2192: )
2193: {
2194: rereadkeys();
2195: req_ack(srcadr, inter, inpkt, INFO_OKAY);
2196: }
2197:
2198:
2199: /*
2200: * trust_key - make one or more keys trusted
2201: */
2202: static void
2203: trust_key(
2204: sockaddr_u *srcadr,
2205: struct interface *inter,
2206: struct req_pkt *inpkt
2207: )
2208: {
2209: do_trustkey(srcadr, inter, inpkt, 1);
2210: }
2211:
2212:
2213: /*
2214: * untrust_key - make one or more keys untrusted
2215: */
2216: static void
2217: untrust_key(
2218: sockaddr_u *srcadr,
2219: struct interface *inter,
2220: struct req_pkt *inpkt
2221: )
2222: {
2223: do_trustkey(srcadr, inter, inpkt, 0);
2224: }
2225:
2226:
2227: /*
2228: * do_trustkey - make keys either trustable or untrustable
2229: */
2230: static void
2231: do_trustkey(
2232: sockaddr_u *srcadr,
2233: struct interface *inter,
2234: struct req_pkt *inpkt,
2235: u_long trust
2236: )
2237: {
2238: register u_long *kp;
2239: register int items;
2240:
2241: items = INFO_NITEMS(inpkt->err_nitems);
2242: kp = (u_long *)inpkt->data;
2243: while (items-- > 0) {
2244: authtrust(*kp, trust);
2245: kp++;
2246: }
2247:
2248: req_ack(srcadr, inter, inpkt, INFO_OKAY);
2249: }
2250:
2251:
2252: /*
2253: * get_auth_info - return some stats concerning the authentication module
2254: */
2255: static void
2256: get_auth_info(
2257: sockaddr_u *srcadr,
2258: struct interface *inter,
2259: struct req_pkt *inpkt
2260: )
2261: {
2262: register struct info_auth *ia;
2263:
2264: /*
2265: * Importations from the authentication module
2266: */
2267: extern u_long authnumkeys;
2268: extern int authnumfreekeys;
2269: extern u_long authkeylookups;
2270: extern u_long authkeynotfound;
2271: extern u_long authencryptions;
2272: extern u_long authdecryptions;
2273: extern u_long authkeyuncached;
2274: extern u_long authkeyexpired;
2275:
2276: ia = (struct info_auth *)prepare_pkt(srcadr, inter, inpkt,
2277: sizeof(struct info_auth));
2278:
2279: ia->numkeys = htonl((u_int32)authnumkeys);
2280: ia->numfreekeys = htonl((u_int32)authnumfreekeys);
2281: ia->keylookups = htonl((u_int32)authkeylookups);
2282: ia->keynotfound = htonl((u_int32)authkeynotfound);
2283: ia->encryptions = htonl((u_int32)authencryptions);
2284: ia->decryptions = htonl((u_int32)authdecryptions);
2285: ia->keyuncached = htonl((u_int32)authkeyuncached);
2286: ia->expired = htonl((u_int32)authkeyexpired);
2287: ia->timereset = htonl((u_int32)(current_time - auth_timereset));
2288:
2289: (void) more_pkt();
2290: flush_pkt();
2291: }
2292:
2293:
2294:
2295: /*
2296: * reset_auth_stats - reset the authentication stat counters. Done here
2297: * to keep ntp-isms out of the authentication module
2298: */
2299: static void
2300: reset_auth_stats(void)
2301: {
2302: /*
2303: * Importations from the authentication module
2304: */
2305: extern u_long authkeylookups;
2306: extern u_long authkeynotfound;
2307: extern u_long authencryptions;
2308: extern u_long authdecryptions;
2309: extern u_long authkeyuncached;
2310:
2311: authkeylookups = 0;
2312: authkeynotfound = 0;
2313: authencryptions = 0;
2314: authdecryptions = 0;
2315: authkeyuncached = 0;
2316: auth_timereset = current_time;
2317: }
2318:
2319:
2320: /*
2321: * req_get_traps - return information about current trap holders
2322: */
2323: static void
2324: req_get_traps(
2325: sockaddr_u *srcadr,
2326: struct interface *inter,
2327: struct req_pkt *inpkt
2328: )
2329: {
2330: register struct info_trap *it;
2331: register struct ctl_trap *tr;
2332: register int i;
2333:
2334: /*
2335: * Imported from the control module
2336: */
2337: extern struct ctl_trap ctl_trap[];
2338: extern int num_ctl_traps;
2339:
2340: if (num_ctl_traps == 0) {
2341: req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2342: return;
2343: }
2344:
2345: it = (struct info_trap *)prepare_pkt(srcadr, inter, inpkt,
2346: v6sizeof(struct info_trap));
2347:
2348: for (i = 0, tr = ctl_trap; i < CTL_MAXTRAPS; i++, tr++) {
2349: if (tr->tr_flags & TRAP_INUSE) {
2350: if (IS_IPV4(&tr->tr_addr)) {
2351: if (tr->tr_localaddr == any_interface)
2352: it->local_address = 0;
2353: else
2354: it->local_address
2355: = NSRCADR(&tr->tr_localaddr->sin);
2356: it->trap_address = NSRCADR(&tr->tr_addr);
2357: if (client_v6_capable)
2358: it->v6_flag = 0;
2359: } else {
2360: if (!client_v6_capable)
2361: continue;
2362: it->local_address6
2363: = SOCK_ADDR6(&tr->tr_localaddr->sin);
2364: it->trap_address6 = SOCK_ADDR6(&tr->tr_addr);
2365: it->v6_flag = 1;
2366: }
2367: it->trap_port = NSRCPORT(&tr->tr_addr);
2368: it->sequence = htons(tr->tr_sequence);
2369: it->settime = htonl((u_int32)(current_time - tr->tr_settime));
2370: it->origtime = htonl((u_int32)(current_time - tr->tr_origtime));
2371: it->resets = htonl((u_int32)tr->tr_resets);
2372: it->flags = htonl((u_int32)tr->tr_flags);
2373: it = (struct info_trap *)more_pkt();
2374: }
2375: }
2376: flush_pkt();
2377: }
2378:
2379:
2380: /*
2381: * req_set_trap - configure a trap
2382: */
2383: static void
2384: req_set_trap(
2385: sockaddr_u *srcadr,
2386: struct interface *inter,
2387: struct req_pkt *inpkt
2388: )
2389: {
2390: do_setclr_trap(srcadr, inter, inpkt, 1);
2391: }
2392:
2393:
2394:
2395: /*
2396: * req_clr_trap - unconfigure a trap
2397: */
2398: static void
2399: req_clr_trap(
2400: sockaddr_u *srcadr,
2401: struct interface *inter,
2402: struct req_pkt *inpkt
2403: )
2404: {
2405: do_setclr_trap(srcadr, inter, inpkt, 0);
2406: }
2407:
2408:
2409:
2410: /*
2411: * do_setclr_trap - do the grunge work of (un)configuring a trap
2412: */
2413: static void
2414: do_setclr_trap(
2415: sockaddr_u *srcadr,
2416: struct interface *inter,
2417: struct req_pkt *inpkt,
2418: int set
2419: )
2420: {
2421: register struct conf_trap *ct;
2422: register struct interface *linter;
2423: int res;
2424: sockaddr_u laddr;
2425:
2426: /*
2427: * Prepare sockaddr
2428: */
2429: ZERO_SOCK(&laddr);
2430: AF(&laddr) = AF(srcadr);
2431: SET_PORT(&laddr, NTP_PORT);
2432:
2433: /*
2434: * Restrict ourselves to one item only. This eliminates
2435: * the error reporting problem.
2436: */
2437: if (INFO_NITEMS(inpkt->err_nitems) > 1) {
2438: msyslog(LOG_ERR, "do_setclr_trap: err_nitems > 1");
2439: req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2440: return;
2441: }
2442: ct = (struct conf_trap *)inpkt->data;
2443:
2444: /*
2445: * Look for the local interface. If none, use the default.
2446: */
2447: if (ct->local_address == 0) {
2448: linter = any_interface;
2449: } else {
2450: if (IS_IPV4(&laddr))
2451: NSRCADR(&laddr) = ct->local_address;
2452: else
2453: SOCK_ADDR6(&laddr) = ct->local_address6;
2454: linter = findinterface(&laddr);
2455: if (NULL == linter) {
2456: req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2457: return;
2458: }
2459: }
2460:
2461: if (IS_IPV4(&laddr))
2462: NSRCADR(&laddr) = ct->trap_address;
2463: else
2464: SOCK_ADDR6(&laddr) = ct->trap_address6;
2465: if (ct->trap_port)
2466: NSRCPORT(&laddr) = ct->trap_port;
2467: else
2468: SET_PORT(&laddr, TRAPPORT);
2469:
2470: if (set) {
2471: res = ctlsettrap(&laddr, linter, 0,
2472: INFO_VERSION(inpkt->rm_vn_mode));
2473: } else {
2474: res = ctlclrtrap(&laddr, linter, 0);
2475: }
2476:
2477: if (!res) {
2478: req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2479: } else {
2480: req_ack(srcadr, inter, inpkt, INFO_OKAY);
2481: }
2482: return;
2483: }
2484:
2485:
2486:
2487: /*
2488: * set_request_keyid - set the keyid used to authenticate requests
2489: */
2490: static void
2491: set_request_keyid(
2492: sockaddr_u *srcadr,
2493: struct interface *inter,
2494: struct req_pkt *inpkt
2495: )
2496: {
2497: keyid_t *pkeyid;
2498:
2499: /*
2500: * Restrict ourselves to one item only.
2501: */
2502: if (INFO_NITEMS(inpkt->err_nitems) > 1) {
2503: msyslog(LOG_ERR, "set_request_keyid: err_nitems > 1");
2504: req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2505: return;
2506: }
2507:
2508: pkeyid = (keyid_t *)inpkt->data;
2509: info_auth_keyid = ntohl(*pkeyid);
2510: req_ack(srcadr, inter, inpkt, INFO_OKAY);
2511: }
2512:
2513:
2514:
2515: /*
2516: * set_control_keyid - set the keyid used to authenticate requests
2517: */
2518: static void
2519: set_control_keyid(
2520: sockaddr_u *srcadr,
2521: struct interface *inter,
2522: struct req_pkt *inpkt
2523: )
2524: {
2525: keyid_t *pkeyid;
2526: extern keyid_t ctl_auth_keyid;
2527:
2528: /*
2529: * Restrict ourselves to one item only.
2530: */
2531: if (INFO_NITEMS(inpkt->err_nitems) > 1) {
2532: msyslog(LOG_ERR, "set_control_keyid: err_nitems > 1");
2533: req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2534: return;
2535: }
2536:
2537: pkeyid = (keyid_t *)inpkt->data;
2538: ctl_auth_keyid = ntohl(*pkeyid);
2539: req_ack(srcadr, inter, inpkt, INFO_OKAY);
2540: }
2541:
2542:
2543:
2544: /*
2545: * get_ctl_stats - return some stats concerning the control message module
2546: */
2547: static void
2548: get_ctl_stats(
2549: sockaddr_u *srcadr,
2550: struct interface *inter,
2551: struct req_pkt *inpkt
2552: )
2553: {
2554: register struct info_control *ic;
2555:
2556: /*
2557: * Importations from the control module
2558: */
2559: extern u_long ctltimereset;
2560: extern u_long numctlreq;
2561: extern u_long numctlbadpkts;
2562: extern u_long numctlresponses;
2563: extern u_long numctlfrags;
2564: extern u_long numctlerrors;
2565: extern u_long numctltooshort;
2566: extern u_long numctlinputresp;
2567: extern u_long numctlinputfrag;
2568: extern u_long numctlinputerr;
2569: extern u_long numctlbadoffset;
2570: extern u_long numctlbadversion;
2571: extern u_long numctldatatooshort;
2572: extern u_long numctlbadop;
2573: extern u_long numasyncmsgs;
2574:
2575: ic = (struct info_control *)prepare_pkt(srcadr, inter, inpkt,
2576: sizeof(struct info_control));
2577:
2578: ic->ctltimereset = htonl((u_int32)(current_time - ctltimereset));
2579: ic->numctlreq = htonl((u_int32)numctlreq);
2580: ic->numctlbadpkts = htonl((u_int32)numctlbadpkts);
2581: ic->numctlresponses = htonl((u_int32)numctlresponses);
2582: ic->numctlfrags = htonl((u_int32)numctlfrags);
2583: ic->numctlerrors = htonl((u_int32)numctlerrors);
2584: ic->numctltooshort = htonl((u_int32)numctltooshort);
2585: ic->numctlinputresp = htonl((u_int32)numctlinputresp);
2586: ic->numctlinputfrag = htonl((u_int32)numctlinputfrag);
2587: ic->numctlinputerr = htonl((u_int32)numctlinputerr);
2588: ic->numctlbadoffset = htonl((u_int32)numctlbadoffset);
2589: ic->numctlbadversion = htonl((u_int32)numctlbadversion);
2590: ic->numctldatatooshort = htonl((u_int32)numctldatatooshort);
2591: ic->numctlbadop = htonl((u_int32)numctlbadop);
2592: ic->numasyncmsgs = htonl((u_int32)numasyncmsgs);
2593:
2594: (void) more_pkt();
2595: flush_pkt();
2596: }
2597:
2598:
2599: #ifdef KERNEL_PLL
2600: /*
2601: * get_kernel_info - get kernel pll/pps information
2602: */
2603: static void
2604: get_kernel_info(
2605: sockaddr_u *srcadr,
2606: struct interface *inter,
2607: struct req_pkt *inpkt
2608: )
2609: {
2610: register struct info_kernel *ik;
2611: struct timex ntx;
2612:
2613: if (!pll_control) {
2614: req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2615: return;
2616: }
2617:
2618: memset((char *)&ntx, 0, sizeof(ntx));
2619: if (ntp_adjtime(&ntx) < 0)
2620: msyslog(LOG_ERR, "get_kernel_info: ntp_adjtime() failed: %m");
2621: ik = (struct info_kernel *)prepare_pkt(srcadr, inter, inpkt,
2622: sizeof(struct info_kernel));
2623:
2624: /*
2625: * pll variables
2626: */
2627: ik->offset = htonl((u_int32)ntx.offset);
2628: ik->freq = htonl((u_int32)ntx.freq);
2629: ik->maxerror = htonl((u_int32)ntx.maxerror);
2630: ik->esterror = htonl((u_int32)ntx.esterror);
2631: ik->status = htons(ntx.status);
2632: ik->constant = htonl((u_int32)ntx.constant);
2633: ik->precision = htonl((u_int32)ntx.precision);
2634: ik->tolerance = htonl((u_int32)ntx.tolerance);
2635:
2636: /*
2637: * pps variables
2638: */
2639: ik->ppsfreq = htonl((u_int32)ntx.ppsfreq);
2640: ik->jitter = htonl((u_int32)ntx.jitter);
2641: ik->shift = htons(ntx.shift);
2642: ik->stabil = htonl((u_int32)ntx.stabil);
2643: ik->jitcnt = htonl((u_int32)ntx.jitcnt);
2644: ik->calcnt = htonl((u_int32)ntx.calcnt);
2645: ik->errcnt = htonl((u_int32)ntx.errcnt);
2646: ik->stbcnt = htonl((u_int32)ntx.stbcnt);
2647:
2648: (void) more_pkt();
2649: flush_pkt();
2650: }
2651: #endif /* KERNEL_PLL */
2652:
2653:
2654: #ifdef REFCLOCK
2655: /*
2656: * get_clock_info - get info about a clock
2657: */
2658: static void
2659: get_clock_info(
2660: sockaddr_u *srcadr,
2661: struct interface *inter,
2662: struct req_pkt *inpkt
2663: )
2664: {
2665: register struct info_clock *ic;
2666: register u_int32 *clkaddr;
2667: register int items;
2668: struct refclockstat clock_stat;
2669: sockaddr_u addr;
2670: l_fp ltmp;
2671:
2672: ZERO_SOCK(&addr);
2673: AF(&addr) = AF_INET;
2674: #ifdef ISC_PLATFORM_HAVESALEN
2675: addr.sa.sa_len = SOCKLEN(&addr);
2676: #endif
2677: SET_PORT(&addr, NTP_PORT);
2678: items = INFO_NITEMS(inpkt->err_nitems);
2679: clkaddr = (u_int32 *) inpkt->data;
2680:
2681: ic = (struct info_clock *)prepare_pkt(srcadr, inter, inpkt,
2682: sizeof(struct info_clock));
2683:
2684: while (items-- > 0) {
2685: NSRCADR(&addr) = *clkaddr++;
2686: if (!ISREFCLOCKADR(&addr) ||
2687: findexistingpeer(&addr, NULL, -1, 0) == NULL) {
2688: req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2689: return;
2690: }
2691:
2692: clock_stat.kv_list = (struct ctl_var *)0;
2693:
2694: refclock_control(&addr, NULL, &clock_stat);
2695:
2696: ic->clockadr = NSRCADR(&addr);
2697: ic->type = clock_stat.type;
2698: ic->flags = clock_stat.flags;
2699: ic->lastevent = clock_stat.lastevent;
2700: ic->currentstatus = clock_stat.currentstatus;
2701: ic->polls = htonl((u_int32)clock_stat.polls);
2702: ic->noresponse = htonl((u_int32)clock_stat.noresponse);
2703: ic->badformat = htonl((u_int32)clock_stat.badformat);
2704: ic->baddata = htonl((u_int32)clock_stat.baddata);
2705: ic->timestarted = htonl((u_int32)clock_stat.timereset);
2706: DTOLFP(clock_stat.fudgetime1, <mp);
2707: HTONL_FP(<mp, &ic->fudgetime1);
2708: DTOLFP(clock_stat.fudgetime2, <mp);
2709: HTONL_FP(<mp, &ic->fudgetime2);
2710: ic->fudgeval1 = htonl((u_int32)clock_stat.fudgeval1);
2711: ic->fudgeval2 = htonl(clock_stat.fudgeval2);
2712:
2713: free_varlist(clock_stat.kv_list);
2714:
2715: ic = (struct info_clock *)more_pkt();
2716: }
2717: flush_pkt();
2718: }
2719:
2720:
2721:
2722: /*
2723: * set_clock_fudge - get a clock's fudge factors
2724: */
2725: static void
2726: set_clock_fudge(
2727: sockaddr_u *srcadr,
2728: struct interface *inter,
2729: struct req_pkt *inpkt
2730: )
2731: {
2732: register struct conf_fudge *cf;
2733: register int items;
2734: struct refclockstat clock_stat;
2735: sockaddr_u addr;
2736: l_fp ltmp;
2737:
2738: ZERO_SOCK(&addr);
2739: memset((char *)&clock_stat, 0, sizeof clock_stat);
2740: items = INFO_NITEMS(inpkt->err_nitems);
2741: cf = (struct conf_fudge *) inpkt->data;
2742:
2743: while (items-- > 0) {
2744: AF(&addr) = AF_INET;
2745: NSRCADR(&addr) = cf->clockadr;
2746: #ifdef ISC_PLATFORM_HAVESALEN
2747: addr.sa.sa_len = SOCKLEN(&addr);
2748: #endif
2749: SET_PORT(&addr, NTP_PORT);
2750: if (!ISREFCLOCKADR(&addr) ||
2751: findexistingpeer(&addr, NULL, -1, 0) == 0) {
2752: req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2753: return;
2754: }
2755:
2756: switch(ntohl(cf->which)) {
2757: case FUDGE_TIME1:
2758: NTOHL_FP(&cf->fudgetime, <mp);
2759: LFPTOD(<mp, clock_stat.fudgetime1);
2760: clock_stat.haveflags = CLK_HAVETIME1;
2761: break;
2762: case FUDGE_TIME2:
2763: NTOHL_FP(&cf->fudgetime, <mp);
2764: LFPTOD(<mp, clock_stat.fudgetime2);
2765: clock_stat.haveflags = CLK_HAVETIME2;
2766: break;
2767: case FUDGE_VAL1:
2768: clock_stat.fudgeval1 = ntohl(cf->fudgeval_flags);
2769: clock_stat.haveflags = CLK_HAVEVAL1;
2770: break;
2771: case FUDGE_VAL2:
2772: clock_stat.fudgeval2 = ntohl(cf->fudgeval_flags);
2773: clock_stat.haveflags = CLK_HAVEVAL2;
2774: break;
2775: case FUDGE_FLAGS:
2776: clock_stat.flags = (u_char) (ntohl(cf->fudgeval_flags) & 0xf);
2777: clock_stat.haveflags =
2778: (CLK_HAVEFLAG1|CLK_HAVEFLAG2|CLK_HAVEFLAG3|CLK_HAVEFLAG4);
2779: break;
2780: default:
2781: msyslog(LOG_ERR, "set_clock_fudge: default!");
2782: req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
2783: return;
2784: }
2785:
2786: refclock_control(&addr, &clock_stat, (struct refclockstat *)0);
2787: }
2788:
2789: req_ack(srcadr, inter, inpkt, INFO_OKAY);
2790: }
2791: #endif
2792:
2793: #ifdef REFCLOCK
2794: /*
2795: * get_clkbug_info - get debugging info about a clock
2796: */
2797: static void
2798: get_clkbug_info(
2799: sockaddr_u *srcadr,
2800: struct interface *inter,
2801: struct req_pkt *inpkt
2802: )
2803: {
2804: register int i;
2805: register struct info_clkbug *ic;
2806: register u_int32 *clkaddr;
2807: register int items;
2808: struct refclockbug bug;
2809: sockaddr_u addr;
2810:
2811: ZERO_SOCK(&addr);
2812: AF(&addr) = AF_INET;
2813: #ifdef ISC_PLATFORM_HAVESALEN
2814: addr.sa.sa_len = SOCKLEN(&addr);
2815: #endif
2816: SET_PORT(&addr, NTP_PORT);
2817: items = INFO_NITEMS(inpkt->err_nitems);
2818: clkaddr = (u_int32 *) inpkt->data;
2819:
2820: ic = (struct info_clkbug *)prepare_pkt(srcadr, inter, inpkt,
2821: sizeof(struct info_clkbug));
2822:
2823: while (items-- > 0) {
2824: NSRCADR(&addr) = *clkaddr++;
2825: if (!ISREFCLOCKADR(&addr) ||
2826: findexistingpeer(&addr, NULL, -1, 0) == 0) {
2827: req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2828: return;
2829: }
2830:
2831: memset((char *)&bug, 0, sizeof bug);
2832: refclock_buginfo(&addr, &bug);
2833: if (bug.nvalues == 0 && bug.ntimes == 0) {
2834: req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA);
2835: return;
2836: }
2837:
2838: ic->clockadr = NSRCADR(&addr);
2839: i = bug.nvalues;
2840: if (i > NUMCBUGVALUES)
2841: i = NUMCBUGVALUES;
2842: ic->nvalues = (u_char)i;
2843: ic->svalues = htons((u_short) (bug.svalues & ((1<<i)-1)));
2844: while (--i >= 0)
2845: ic->values[i] = htonl(bug.values[i]);
2846:
2847: i = bug.ntimes;
2848: if (i > NUMCBUGTIMES)
2849: i = NUMCBUGTIMES;
2850: ic->ntimes = (u_char)i;
2851: ic->stimes = htonl(bug.stimes);
2852: while (--i >= 0) {
2853: HTONL_FP(&bug.times[i], &ic->times[i]);
2854: }
2855:
2856: ic = (struct info_clkbug *)more_pkt();
2857: }
2858: flush_pkt();
2859: }
2860: #endif
2861:
2862: /*
2863: * receiver of interface structures
2864: */
2865: static void
2866: fill_info_if_stats(void *data, interface_info_t *interface_info)
2867: {
2868: struct info_if_stats **ifsp = (struct info_if_stats **)data;
2869: struct info_if_stats *ifs = *ifsp;
2870: endpt *ep = interface_info->ep;
2871:
2872: memset(ifs, 0, sizeof(*ifs));
2873:
2874: if (IS_IPV6(&ep->sin)) {
2875: if (!client_v6_capable) {
2876: return;
2877: }
2878: ifs->v6_flag = 1;
2879: ifs->unaddr.addr6 = SOCK_ADDR6(&ep->sin);
2880: ifs->unbcast.addr6 = SOCK_ADDR6(&ep->bcast);
2881: ifs->unmask.addr6 = SOCK_ADDR6(&ep->mask);
2882: } else {
2883: ifs->v6_flag = 0;
2884: ifs->unaddr.addr = SOCK_ADDR4(&ep->sin);
2885: ifs->unbcast.addr = SOCK_ADDR4(&ep->bcast);
2886: ifs->unmask.addr = SOCK_ADDR4(&ep->mask);
2887: }
2888: ifs->v6_flag = htonl(ifs->v6_flag);
2889: strncpy(ifs->name, ep->name, sizeof(ifs->name));
2890: ifs->family = htons(ep->family);
2891: ifs->flags = htonl(ep->flags);
2892: ifs->last_ttl = htonl(ep->last_ttl);
2893: ifs->num_mcast = htonl(ep->num_mcast);
2894: ifs->received = htonl(ep->received);
2895: ifs->sent = htonl(ep->sent);
2896: ifs->notsent = htonl(ep->notsent);
2897: ifs->ifindex = htonl(ep->ifindex);
2898: /* scope no longer in struct interface, in in6_addr typically */
2899: ifs->scopeid = ifs->ifindex;
2900: ifs->ifnum = htonl(ep->ifnum);
2901: ifs->uptime = htonl(current_time - ep->starttime);
2902: ifs->ignore_packets = ep->ignore_packets;
2903: ifs->peercnt = htonl(ep->peercnt);
2904: ifs->action = interface_info->action;
2905:
2906: *ifsp = (struct info_if_stats *)more_pkt();
2907: }
2908:
2909: /*
2910: * get_if_stats - get interface statistics
2911: */
2912: static void
2913: get_if_stats(
2914: sockaddr_u *srcadr,
2915: struct interface *inter,
2916: struct req_pkt *inpkt
2917: )
2918: {
2919: struct info_if_stats *ifs;
2920:
2921: DPRINTF(3, ("wants interface statistics\n"));
2922:
2923: ifs = (struct info_if_stats *)prepare_pkt(srcadr, inter, inpkt,
2924: v6sizeof(struct info_if_stats));
2925:
2926: interface_enumerate(fill_info_if_stats, &ifs);
2927:
2928: flush_pkt();
2929: }
2930:
2931: static void
2932: do_if_reload(
2933: sockaddr_u *srcadr,
2934: struct interface *inter,
2935: struct req_pkt *inpkt
2936: )
2937: {
2938: struct info_if_stats *ifs;
2939:
2940: DPRINTF(3, ("wants interface reload\n"));
2941:
2942: ifs = (struct info_if_stats *)prepare_pkt(srcadr, inter, inpkt,
2943: v6sizeof(struct info_if_stats));
2944:
2945: interface_update(fill_info_if_stats, &ifs);
2946:
2947: flush_pkt();
2948: }
2949:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>