PageRenderTime 63ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/contrib/ntp/ntpd/ntp_control.c

https://bitbucket.org/freebsd/freebsd-head/
C | 3001 lines | 2635 code | 176 blank | 190 comment | 192 complexity | 8771b3cd377989ab6c93879321f7f61e MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, BSD-3-Clause, LGPL-2.0, LGPL-2.1, BSD-2-Clause, 0BSD, JSON, AGPL-1.0, GPL-2.0
  1. /*
  2. * ntp_control.c - respond to control messages and send async traps
  3. */
  4. /*
  5. * $FreeBSD$
  6. */
  7. #ifdef HAVE_CONFIG_H
  8. #include <config.h>
  9. #endif
  10. #include "ntpd.h"
  11. #include "ntp_io.h"
  12. #include "ntp_refclock.h"
  13. #include "ntp_control.h"
  14. #include "ntp_unixtime.h"
  15. #include "ntp_stdlib.h"
  16. #include <stdio.h>
  17. #include <ctype.h>
  18. #include <signal.h>
  19. #include <netinet/in.h>
  20. #include <arpa/inet.h>
  21. /*
  22. * Structure to hold request procedure information
  23. */
  24. #define NOAUTH 0
  25. #define AUTH 1
  26. #define NO_REQUEST (-1)
  27. struct ctl_proc {
  28. short control_code; /* defined request code */
  29. u_short flags; /* flags word */
  30. void (*handler) P((struct recvbuf *, int)); /* handle request */
  31. };
  32. /*
  33. * Only one flag. Authentication required or not.
  34. */
  35. #define NOAUTH 0
  36. #define AUTH 1
  37. /*
  38. * Request processing routines
  39. */
  40. static void ctl_error P((int));
  41. #ifdef REFCLOCK
  42. static u_short ctlclkstatus P((struct refclockstat *));
  43. #endif
  44. static void ctl_flushpkt P((int));
  45. static void ctl_putdata P((const char *, unsigned int, int));
  46. static void ctl_putstr P((const char *, const char *,
  47. unsigned int));
  48. static void ctl_putdbl P((const char *, double));
  49. static void ctl_putuint P((const char *, u_long));
  50. static void ctl_puthex P((const char *, u_long));
  51. static void ctl_putint P((const char *, long));
  52. static void ctl_putts P((const char *, l_fp *));
  53. static void ctl_putadr P((const char *, u_int32, struct sockaddr_storage*));
  54. static void ctl_putid P((const char *, char *));
  55. static void ctl_putarray P((const char *, double *, int));
  56. static void ctl_putsys P((int));
  57. static void ctl_putpeer P((int, struct peer *));
  58. #ifdef OPENSSL
  59. static void ctl_putfs P((const char *, tstamp_t));
  60. #endif
  61. #ifdef REFCLOCK
  62. static void ctl_putclock P((int, struct refclockstat *, int));
  63. #endif /* REFCLOCK */
  64. static struct ctl_var *ctl_getitem P((struct ctl_var *, char **));
  65. static u_long count_var P((struct ctl_var *));
  66. static void control_unspec P((struct recvbuf *, int));
  67. static void read_status P((struct recvbuf *, int));
  68. static void read_variables P((struct recvbuf *, int));
  69. static void write_variables P((struct recvbuf *, int));
  70. static void read_clock_status P((struct recvbuf *, int));
  71. static void write_clock_status P((struct recvbuf *, int));
  72. static void set_trap P((struct recvbuf *, int));
  73. static void unset_trap P((struct recvbuf *, int));
  74. static struct ctl_trap *ctlfindtrap P((struct sockaddr_storage *,
  75. struct interface *));
  76. static struct ctl_proc control_codes[] = {
  77. { CTL_OP_UNSPEC, NOAUTH, control_unspec },
  78. { CTL_OP_READSTAT, NOAUTH, read_status },
  79. { CTL_OP_READVAR, NOAUTH, read_variables },
  80. { CTL_OP_WRITEVAR, AUTH, write_variables },
  81. { CTL_OP_READCLOCK, NOAUTH, read_clock_status },
  82. { CTL_OP_WRITECLOCK, NOAUTH, write_clock_status },
  83. { CTL_OP_SETTRAP, NOAUTH, set_trap },
  84. { CTL_OP_UNSETTRAP, NOAUTH, unset_trap },
  85. { NO_REQUEST, 0 }
  86. };
  87. /*
  88. * System variable values. The array can be indexed by the variable
  89. * index to find the textual name.
  90. */
  91. static struct ctl_var sys_var[] = {
  92. { 0, PADDING, "" }, /* 0 */
  93. { CS_LEAP, RW, "leap" }, /* 1 */
  94. { CS_STRATUM, RO, "stratum" }, /* 2 */
  95. { CS_PRECISION, RO, "precision" }, /* 3 */
  96. { CS_ROOTDELAY, RO, "rootdelay" }, /* 4 */
  97. { CS_ROOTDISPERSION, RO, "rootdispersion" }, /* 5 */
  98. { CS_REFID, RO, "refid" }, /* 6 */
  99. { CS_REFTIME, RO, "reftime" }, /* 7 */
  100. { CS_POLL, RO, "poll" }, /* 8 */
  101. { CS_PEERID, RO, "peer" }, /* 9 */
  102. { CS_STATE, RO, "state" }, /* 10 */
  103. { CS_OFFSET, RO, "offset" }, /* 11 */
  104. { CS_DRIFT, RO, "frequency" }, /* 12 */
  105. { CS_JITTER, RO, "jitter" }, /* 13 */
  106. { CS_ERROR, RO, "noise" }, /* 14 */
  107. { CS_CLOCK, RO, "clock" }, /* 15 */
  108. { CS_PROCESSOR, RO, "processor" }, /* 16 */
  109. { CS_SYSTEM, RO, "system" }, /* 17 */
  110. { CS_VERSION, RO, "version" }, /* 18 */
  111. { CS_STABIL, RO, "stability" }, /* 19 */
  112. { CS_VARLIST, RO, "sys_var_list" }, /* 20 */
  113. #ifdef OPENSSL
  114. { CS_FLAGS, RO, "flags" }, /* 21 */
  115. { CS_HOST, RO, "hostname" }, /* 22 */
  116. { CS_PUBLIC, RO, "update" }, /* 23 */
  117. { CS_CERTIF, RO, "cert" }, /* 24 */
  118. { CS_REVTIME, RO, "expire" }, /* 25 */
  119. { CS_LEAPTAB, RO, "leapsec" }, /* 26 */
  120. { CS_TAI, RO, "tai" }, /* 27 */
  121. { CS_DIGEST, RO, "signature" }, /* 28 */
  122. { CS_IDENT, RO, "ident" }, /* 29 */
  123. { CS_REVOKE, RO, "expire" }, /* 30 */
  124. #endif /* OPENSSL */
  125. { 0, EOV, "" } /* 21/31 */
  126. };
  127. static struct ctl_var *ext_sys_var = (struct ctl_var *)0;
  128. /*
  129. * System variables we print by default (in fuzzball order,
  130. * more-or-less)
  131. */
  132. static u_char def_sys_var[] = {
  133. CS_VERSION,
  134. CS_PROCESSOR,
  135. CS_SYSTEM,
  136. CS_LEAP,
  137. CS_STRATUM,
  138. CS_PRECISION,
  139. CS_ROOTDELAY,
  140. CS_ROOTDISPERSION,
  141. CS_PEERID,
  142. CS_REFID,
  143. CS_REFTIME,
  144. CS_POLL,
  145. CS_CLOCK,
  146. CS_STATE,
  147. CS_OFFSET,
  148. CS_DRIFT,
  149. CS_JITTER,
  150. CS_ERROR,
  151. CS_STABIL,
  152. #ifdef OPENSSL
  153. CS_HOST,
  154. CS_DIGEST,
  155. CS_FLAGS,
  156. CS_PUBLIC,
  157. CS_IDENT,
  158. CS_LEAPTAB,
  159. CS_TAI,
  160. CS_CERTIF,
  161. #endif /* OPENSSL */
  162. 0
  163. };
  164. /*
  165. * Peer variable list
  166. */
  167. static struct ctl_var peer_var[] = {
  168. { 0, PADDING, "" }, /* 0 */
  169. { CP_CONFIG, RO, "config" }, /* 1 */
  170. { CP_AUTHENABLE, RO, "authenable" }, /* 2 */
  171. { CP_AUTHENTIC, RO, "authentic" }, /* 3 */
  172. { CP_SRCADR, RO, "srcadr" }, /* 4 */
  173. { CP_SRCPORT, RO, "srcport" }, /* 5 */
  174. { CP_DSTADR, RO, "dstadr" }, /* 6 */
  175. { CP_DSTPORT, RO, "dstport" }, /* 7 */
  176. { CP_LEAP, RO, "leap" }, /* 8 */
  177. { CP_HMODE, RO, "hmode" }, /* 9 */
  178. { CP_STRATUM, RO, "stratum" }, /* 10 */
  179. { CP_PPOLL, RO, "ppoll" }, /* 11 */
  180. { CP_HPOLL, RO, "hpoll" }, /* 12 */
  181. { CP_PRECISION, RO, "precision" }, /* 13 */
  182. { CP_ROOTDELAY, RO, "rootdelay" }, /* 14 */
  183. { CP_ROOTDISPERSION, RO, "rootdispersion" }, /* 15 */
  184. { CP_REFID, RO, "refid" }, /* 16 */
  185. { CP_REFTIME, RO, "reftime" }, /* 17 */
  186. { CP_ORG, RO, "org" }, /* 18 */
  187. { CP_REC, RO, "rec" }, /* 19 */
  188. { CP_XMT, RO, "xmt" }, /* 20 */
  189. { CP_REACH, RO, "reach" }, /* 21 */
  190. { CP_UNREACH, RO, "unreach" }, /* 22 */
  191. { CP_TIMER, RO, "timer" }, /* 23 */
  192. { CP_DELAY, RO, "delay" }, /* 24 */
  193. { CP_OFFSET, RO, "offset" }, /* 25 */
  194. { CP_JITTER, RO, "jitter" }, /* 26 */
  195. { CP_DISPERSION, RO, "dispersion" }, /* 27 */
  196. { CP_KEYID, RO, "keyid" }, /* 28 */
  197. { CP_FILTDELAY, RO, "filtdelay=" }, /* 29 */
  198. { CP_FILTOFFSET, RO, "filtoffset=" }, /* 30 */
  199. { CP_PMODE, RO, "pmode" }, /* 31 */
  200. { CP_RECEIVED, RO, "received"}, /* 32 */
  201. { CP_SENT, RO, "sent" }, /* 33 */
  202. { CP_FILTERROR, RO, "filtdisp=" }, /* 34 */
  203. { CP_FLASH, RO, "flash" }, /* 35 */
  204. { CP_TTL, RO, "ttl" }, /* 36 */
  205. { CP_VARLIST, RO, "peer_var_list" }, /* 37 */
  206. #ifdef OPENSSL
  207. { CP_FLAGS, RO, "flags" }, /* 38 */
  208. { CP_HOST, RO, "hostname" }, /* 39 */
  209. { CP_VALID, RO, "valid" }, /* 40 */
  210. { CP_INITSEQ, RO, "initsequence" }, /* 41 */
  211. { CP_INITKEY, RO, "initkey" }, /* 42 */
  212. { CP_INITTSP, RO, "timestamp" }, /* 43 */
  213. { CP_DIGEST, RO, "signature" }, /* 44 */
  214. { CP_IDENT, RO, "trust" }, /* 45 */
  215. #endif /* OPENSSL */
  216. { 0, EOV, "" } /* 38/46 */
  217. };
  218. /*
  219. * Peer variables we print by default
  220. */
  221. static u_char def_peer_var[] = {
  222. CP_SRCADR,
  223. CP_SRCPORT,
  224. CP_DSTADR,
  225. CP_DSTPORT,
  226. CP_LEAP,
  227. CP_STRATUM,
  228. CP_PRECISION,
  229. CP_ROOTDELAY,
  230. CP_ROOTDISPERSION,
  231. CP_REFID,
  232. CP_REACH,
  233. CP_UNREACH,
  234. CP_HMODE,
  235. CP_PMODE,
  236. CP_HPOLL,
  237. CP_PPOLL,
  238. CP_FLASH,
  239. CP_KEYID,
  240. CP_TTL,
  241. CP_OFFSET,
  242. CP_DELAY,
  243. CP_DISPERSION,
  244. CP_JITTER,
  245. CP_REFTIME,
  246. CP_ORG,
  247. CP_REC,
  248. CP_XMT,
  249. CP_FILTDELAY,
  250. CP_FILTOFFSET,
  251. CP_FILTERROR,
  252. #ifdef OPENSSL
  253. CP_HOST,
  254. CP_DIGEST,
  255. CP_VALID,
  256. CP_FLAGS,
  257. CP_IDENT,
  258. CP_INITSEQ,
  259. #endif /* OPENSSL */
  260. 0
  261. };
  262. #ifdef REFCLOCK
  263. /*
  264. * Clock variable list
  265. */
  266. static struct ctl_var clock_var[] = {
  267. { 0, PADDING, "" }, /* 0 */
  268. { CC_TYPE, RO, "type" }, /* 1 */
  269. { CC_TIMECODE, RO, "timecode" }, /* 2 */
  270. { CC_POLL, RO, "poll" }, /* 3 */
  271. { CC_NOREPLY, RO, "noreply" }, /* 4 */
  272. { CC_BADFORMAT, RO, "badformat" }, /* 5 */
  273. { CC_BADDATA, RO, "baddata" }, /* 6 */
  274. { CC_FUDGETIME1, RO, "fudgetime1" }, /* 7 */
  275. { CC_FUDGETIME2, RO, "fudgetime2" }, /* 8 */
  276. { CC_FUDGEVAL1, RO, "stratum" }, /* 9 */
  277. { CC_FUDGEVAL2, RO, "refid" }, /* 10 */
  278. { CC_FLAGS, RO, "flags" }, /* 11 */
  279. { CC_DEVICE, RO, "device" }, /* 12 */
  280. { CC_VARLIST, RO, "clock_var_list" }, /* 13 */
  281. { 0, EOV, "" } /* 14 */
  282. };
  283. /*
  284. * Clock variables printed by default
  285. */
  286. static u_char def_clock_var[] = {
  287. CC_DEVICE,
  288. CC_TYPE, /* won't be output if device = known */
  289. CC_TIMECODE,
  290. CC_POLL,
  291. CC_NOREPLY,
  292. CC_BADFORMAT,
  293. CC_BADDATA,
  294. CC_FUDGETIME1,
  295. CC_FUDGETIME2,
  296. CC_FUDGEVAL1,
  297. CC_FUDGEVAL2,
  298. CC_FLAGS,
  299. 0
  300. };
  301. #endif
  302. /*
  303. * System and processor definitions.
  304. */
  305. #ifndef HAVE_UNAME
  306. # ifndef STR_SYSTEM
  307. # define STR_SYSTEM "UNIX"
  308. # endif
  309. # ifndef STR_PROCESSOR
  310. # define STR_PROCESSOR "unknown"
  311. # endif
  312. static char str_system[] = STR_SYSTEM;
  313. static char str_processor[] = STR_PROCESSOR;
  314. #else
  315. # include <sys/utsname.h>
  316. static struct utsname utsnamebuf;
  317. #endif /* HAVE_UNAME */
  318. /*
  319. * Trap structures. We only allow a few of these, and send a copy of
  320. * each async message to each live one. Traps time out after an hour, it
  321. * is up to the trap receipient to keep resetting it to avoid being
  322. * timed out.
  323. */
  324. /* ntp_request.c */
  325. struct ctl_trap ctl_trap[CTL_MAXTRAPS];
  326. int num_ctl_traps;
  327. /*
  328. * Type bits, for ctlsettrap() call.
  329. */
  330. #define TRAP_TYPE_CONFIG 0 /* used by configuration code */
  331. #define TRAP_TYPE_PRIO 1 /* priority trap */
  332. #define TRAP_TYPE_NONPRIO 2 /* nonpriority trap */
  333. /*
  334. * List relating reference clock types to control message time sources.
  335. * Index by the reference clock type. This list will only be used iff
  336. * the reference clock driver doesn't set peer->sstclktype to something
  337. * different than CTL_SST_TS_UNSPEC.
  338. */
  339. static u_char clocktypes[] = {
  340. CTL_SST_TS_NTP, /* REFCLK_NONE (0) */
  341. CTL_SST_TS_LOCAL, /* REFCLK_LOCALCLOCK (1) */
  342. CTL_SST_TS_UHF, /* deprecated REFCLK_GPS_TRAK (2) */
  343. CTL_SST_TS_HF, /* REFCLK_WWV_PST (3) */
  344. CTL_SST_TS_LF, /* REFCLK_WWVB_SPECTRACOM (4) */
  345. CTL_SST_TS_UHF, /* REFCLK_TRUETIME (5) */
  346. CTL_SST_TS_UHF, /* REFCLK_GOES_TRAK (6) IRIG_AUDIO? */
  347. CTL_SST_TS_HF, /* REFCLK_CHU (7) */
  348. CTL_SST_TS_LF, /* REFCLOCK_PARSE (default) (8) */
  349. CTL_SST_TS_LF, /* REFCLK_GPS_MX4200 (9) */
  350. CTL_SST_TS_UHF, /* REFCLK_GPS_AS2201 (10) */
  351. CTL_SST_TS_UHF, /* REFCLK_GPS_ARBITER (11) */
  352. CTL_SST_TS_UHF, /* REFCLK_IRIG_TPRO (12) */
  353. CTL_SST_TS_ATOM, /* REFCLK_ATOM_LEITCH (13) */
  354. CTL_SST_TS_LF, /* deprecated REFCLK_MSF_EES (14) */
  355. CTL_SST_TS_NTP, /* not used (15) */
  356. CTL_SST_TS_UHF, /* REFCLK_IRIG_BANCOMM (16) */
  357. CTL_SST_TS_UHF, /* REFCLK_GPS_DATU (17) */
  358. CTL_SST_TS_TELEPHONE, /* REFCLK_NIST_ACTS (18) */
  359. CTL_SST_TS_HF, /* REFCLK_WWV_HEATH (19) */
  360. CTL_SST_TS_UHF, /* REFCLK_GPS_NMEA (20) */
  361. CTL_SST_TS_UHF, /* REFCLK_GPS_VME (21) */
  362. CTL_SST_TS_ATOM, /* REFCLK_ATOM_PPS (22) */
  363. CTL_SST_TS_NTP, /* not used (23) */
  364. CTL_SST_TS_NTP, /* not used (24) */
  365. CTL_SST_TS_NTP, /* not used (25) */
  366. CTL_SST_TS_UHF, /* REFCLK_GPS_HP (26) */
  367. CTL_SST_TS_TELEPHONE, /* REFCLK_ARCRON_MSF (27) */
  368. CTL_SST_TS_TELEPHONE, /* REFCLK_SHM (28) */
  369. CTL_SST_TS_UHF, /* REFCLK_PALISADE (29) */
  370. CTL_SST_TS_UHF, /* REFCLK_ONCORE (30) */
  371. CTL_SST_TS_UHF, /* REFCLK_JUPITER (31) */
  372. CTL_SST_TS_LF, /* REFCLK_CHRONOLOG (32) */
  373. CTL_SST_TS_LF, /* REFCLK_DUMBCLOCK (33) */
  374. CTL_SST_TS_LF, /* REFCLK_ULINK (34) */
  375. CTL_SST_TS_LF, /* REFCLK_PCF (35) */
  376. CTL_SST_TS_LF, /* REFCLK_WWV (36) */
  377. CTL_SST_TS_LF, /* REFCLK_FG (37) */
  378. CTL_SST_TS_UHF, /* REFCLK_HOPF_SERIAL (38) */
  379. CTL_SST_TS_UHF, /* REFCLK_HOPF_PCI (39) */
  380. CTL_SST_TS_LF, /* REFCLK_JJY (40) */
  381. CTL_SST_TS_UHF, /* REFCLK_TT560 (41) */
  382. CTL_SST_TS_UHF, /* REFCLK_ZYFER (42) */
  383. CTL_SST_TS_UHF, /* REFCLK_RIPENCC (43) */
  384. CTL_SST_TS_UHF, /* REFCLK_NEOCLOCK4X (44) */
  385. };
  386. /*
  387. * Keyid used for authenticating write requests.
  388. */
  389. keyid_t ctl_auth_keyid;
  390. /*
  391. * We keep track of the last error reported by the system internally
  392. */
  393. static u_char ctl_sys_last_event;
  394. static u_char ctl_sys_num_events;
  395. /*
  396. * Statistic counters to keep track of requests and responses.
  397. */
  398. u_long ctltimereset; /* time stats reset */
  399. u_long numctlreq; /* number of requests we've received */
  400. u_long numctlbadpkts; /* number of bad control packets */
  401. u_long numctlresponses; /* number of resp packets sent with data */
  402. u_long numctlfrags; /* number of fragments sent */
  403. u_long numctlerrors; /* number of error responses sent */
  404. u_long numctltooshort; /* number of too short input packets */
  405. u_long numctlinputresp; /* number of responses on input */
  406. u_long numctlinputfrag; /* number of fragments on input */
  407. u_long numctlinputerr; /* number of input pkts with err bit set */
  408. u_long numctlbadoffset; /* number of input pkts with nonzero offset */
  409. u_long numctlbadversion; /* number of input pkts with unknown version */
  410. u_long numctldatatooshort; /* data too short for count */
  411. u_long numctlbadop; /* bad op code found in packet */
  412. u_long numasyncmsgs; /* number of async messages we've sent */
  413. /*
  414. * Response packet used by these routines. Also some state information
  415. * so that we can handle packet formatting within a common set of
  416. * subroutines. Note we try to enter data in place whenever possible,
  417. * but the need to set the more bit correctly means we occasionally
  418. * use the extra buffer and copy.
  419. */
  420. static struct ntp_control rpkt;
  421. static u_char res_version;
  422. static u_char res_opcode;
  423. static associd_t res_associd;
  424. static int res_offset;
  425. static u_char * datapt;
  426. static u_char * dataend;
  427. static int datalinelen;
  428. static int datanotbinflag;
  429. static struct sockaddr_storage *rmt_addr;
  430. static struct interface *lcl_inter;
  431. static u_char res_authenticate;
  432. static u_char res_authokay;
  433. static keyid_t res_keyid;
  434. #define MAXDATALINELEN (72)
  435. static u_char res_async; /* set to 1 if this is async trap response */
  436. /*
  437. * Pointers for saving state when decoding request packets
  438. */
  439. static char *reqpt;
  440. static char *reqend;
  441. /*
  442. * init_control - initialize request data
  443. */
  444. void
  445. init_control(void)
  446. {
  447. int i;
  448. #ifdef HAVE_UNAME
  449. uname(&utsnamebuf);
  450. #endif /* HAVE_UNAME */
  451. ctl_clr_stats();
  452. ctl_auth_keyid = 0;
  453. ctl_sys_last_event = EVNT_UNSPEC;
  454. ctl_sys_num_events = 0;
  455. num_ctl_traps = 0;
  456. for (i = 0; i < CTL_MAXTRAPS; i++)
  457. ctl_trap[i].tr_flags = 0;
  458. }
  459. /*
  460. * ctl_error - send an error response for the current request
  461. */
  462. static void
  463. ctl_error(
  464. int errcode
  465. )
  466. {
  467. #ifdef DEBUG
  468. if (debug >= 4)
  469. printf("sending control error %d\n", errcode);
  470. #endif
  471. /*
  472. * Fill in the fields. We assume rpkt.sequence and rpkt.associd
  473. * have already been filled in.
  474. */
  475. rpkt.r_m_e_op = (u_char) (CTL_RESPONSE|CTL_ERROR|(res_opcode &
  476. CTL_OP_MASK));
  477. rpkt.status = htons((u_short) ((errcode<<8) & 0xff00));
  478. rpkt.count = 0;
  479. /*
  480. * send packet and bump counters
  481. */
  482. if (res_authenticate && sys_authenticate) {
  483. int maclen;
  484. *(u_int32 *)((u_char *)&rpkt + CTL_HEADER_LEN) =
  485. htonl(res_keyid);
  486. maclen = authencrypt(res_keyid, (u_int32 *)&rpkt,
  487. CTL_HEADER_LEN);
  488. sendpkt(rmt_addr, lcl_inter, -2, (struct pkt *)&rpkt,
  489. CTL_HEADER_LEN + maclen);
  490. } else {
  491. sendpkt(rmt_addr, lcl_inter, -3, (struct pkt *)&rpkt,
  492. CTL_HEADER_LEN);
  493. }
  494. numctlerrors++;
  495. }
  496. /*
  497. * process_control - process an incoming control message
  498. */
  499. void
  500. process_control(
  501. struct recvbuf *rbufp,
  502. int restrict_mask
  503. )
  504. {
  505. register struct ntp_control *pkt;
  506. register int req_count;
  507. register int req_data;
  508. register struct ctl_proc *cc;
  509. int properlen;
  510. int maclen;
  511. #ifdef DEBUG
  512. if (debug > 2)
  513. printf("in process_control()\n");
  514. #endif
  515. /*
  516. * Save the addresses for error responses
  517. */
  518. numctlreq++;
  519. rmt_addr = &rbufp->recv_srcadr;
  520. lcl_inter = rbufp->dstadr;
  521. pkt = (struct ntp_control *)&rbufp->recv_pkt;
  522. /*
  523. * If the length is less than required for the header, or
  524. * it is a response or a fragment, ignore this.
  525. */
  526. if (rbufp->recv_length < CTL_HEADER_LEN
  527. || pkt->r_m_e_op & (CTL_RESPONSE|CTL_MORE|CTL_ERROR)
  528. || pkt->offset != 0) {
  529. #ifdef DEBUG
  530. if (debug)
  531. printf("invalid format in control packet\n");
  532. #endif
  533. if (rbufp->recv_length < CTL_HEADER_LEN)
  534. numctltooshort++;
  535. if (pkt->r_m_e_op & CTL_RESPONSE)
  536. numctlinputresp++;
  537. if (pkt->r_m_e_op & CTL_MORE)
  538. numctlinputfrag++;
  539. if (pkt->r_m_e_op & CTL_ERROR)
  540. numctlinputerr++;
  541. if (pkt->offset != 0)
  542. numctlbadoffset++;
  543. return;
  544. }
  545. res_version = PKT_VERSION(pkt->li_vn_mode);
  546. if (res_version > NTP_VERSION || res_version < NTP_OLDVERSION) {
  547. #ifdef DEBUG
  548. if (debug)
  549. printf("unknown version %d in control packet\n",
  550. res_version);
  551. #endif
  552. numctlbadversion++;
  553. return;
  554. }
  555. /*
  556. * Pull enough data from the packet to make intelligent
  557. * responses
  558. */
  559. rpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap, res_version,
  560. MODE_CONTROL);
  561. res_opcode = pkt->r_m_e_op;
  562. rpkt.sequence = pkt->sequence;
  563. rpkt.associd = pkt->associd;
  564. rpkt.status = 0;
  565. res_offset = 0;
  566. res_associd = htons(pkt->associd);
  567. res_async = 0;
  568. res_authenticate = 0;
  569. res_keyid = 0;
  570. res_authokay = 0;
  571. req_count = (int)htons(pkt->count);
  572. datanotbinflag = 0;
  573. datalinelen = 0;
  574. datapt = rpkt.data;
  575. dataend = &(rpkt.data[CTL_MAX_DATA_LEN]);
  576. /*
  577. * We're set up now. Make sure we've got at least enough
  578. * incoming data space to match the count.
  579. */
  580. req_data = rbufp->recv_length - CTL_HEADER_LEN;
  581. if (req_data < req_count || rbufp->recv_length & 0x3) {
  582. ctl_error(CERR_BADFMT);
  583. numctldatatooshort++;
  584. return;
  585. }
  586. properlen = req_count + CTL_HEADER_LEN;
  587. #ifdef DEBUG
  588. if (debug > 2 && (rbufp->recv_length & 0x3) != 0)
  589. printf("Packet length %d unrounded\n",
  590. rbufp->recv_length);
  591. #endif
  592. /* round up proper len to a 8 octet boundary */
  593. properlen = (properlen + 7) & ~7;
  594. maclen = rbufp->recv_length - properlen;
  595. if ((rbufp->recv_length & (sizeof(u_long) - 1)) == 0 &&
  596. maclen >= MIN_MAC_LEN && maclen <= MAX_MAC_LEN &&
  597. sys_authenticate) {
  598. res_authenticate = 1;
  599. res_keyid = ntohl(*(u_int32 *)((u_char *)pkt +
  600. properlen));
  601. #ifdef DEBUG
  602. if (debug > 2)
  603. printf(
  604. "recv_len %d, properlen %d, wants auth with keyid %08x, MAC length=%d\n",
  605. rbufp->recv_length, properlen, res_keyid, maclen);
  606. #endif
  607. if (!authistrusted(res_keyid)) {
  608. #ifdef DEBUG
  609. if (debug > 2)
  610. printf("invalid keyid %08x\n",
  611. res_keyid);
  612. #endif
  613. } else if (authdecrypt(res_keyid, (u_int32 *)pkt,
  614. rbufp->recv_length - maclen, maclen)) {
  615. #ifdef DEBUG
  616. if (debug > 2)
  617. printf("authenticated okay\n");
  618. #endif
  619. res_authokay = 1;
  620. } else {
  621. #ifdef DEBUG
  622. if (debug > 2)
  623. printf("authentication failed\n");
  624. #endif
  625. res_keyid = 0;
  626. }
  627. }
  628. /*
  629. * Set up translate pointers
  630. */
  631. reqpt = (char *)pkt->data;
  632. reqend = reqpt + req_count;
  633. /*
  634. * Look for the opcode processor
  635. */
  636. for (cc = control_codes; cc->control_code != NO_REQUEST; cc++) {
  637. if (cc->control_code == res_opcode) {
  638. #ifdef DEBUG
  639. if (debug > 2)
  640. printf("opcode %d, found command handler\n",
  641. res_opcode);
  642. #endif
  643. if (cc->flags == AUTH && (!res_authokay ||
  644. res_keyid != ctl_auth_keyid)) {
  645. ctl_error(CERR_PERMISSION);
  646. return;
  647. }
  648. (cc->handler)(rbufp, restrict_mask);
  649. return;
  650. }
  651. }
  652. /*
  653. * Can't find this one, return an error.
  654. */
  655. numctlbadop++;
  656. ctl_error(CERR_BADOP);
  657. return;
  658. }
  659. /*
  660. * ctlpeerstatus - return a status word for this peer
  661. */
  662. u_short
  663. ctlpeerstatus(
  664. register struct peer *peer
  665. )
  666. {
  667. register u_short status;
  668. status = peer->status;
  669. if (peer->flags & FLAG_CONFIG)
  670. status |= CTL_PST_CONFIG;
  671. if (peer->flags & FLAG_AUTHENABLE)
  672. status |= CTL_PST_AUTHENABLE;
  673. if (peer->flags & FLAG_AUTHENTIC)
  674. status |= CTL_PST_AUTHENTIC;
  675. if (peer->reach != 0)
  676. status |= CTL_PST_REACH;
  677. return (u_short)CTL_PEER_STATUS(status, peer->num_events,
  678. peer->last_event);
  679. }
  680. /*
  681. * ctlclkstatus - return a status word for this clock
  682. */
  683. #ifdef REFCLOCK
  684. static u_short
  685. ctlclkstatus(
  686. struct refclockstat *this_clock
  687. )
  688. {
  689. return ((u_short)(((this_clock->currentstatus) << 8) |
  690. (this_clock->lastevent)));
  691. }
  692. #endif
  693. /*
  694. * ctlsysstatus - return the system status word
  695. */
  696. u_short
  697. ctlsysstatus(void)
  698. {
  699. register u_char this_clock;
  700. this_clock = CTL_SST_TS_UNSPEC;
  701. #ifdef REFCLOCK
  702. if (sys_peer != 0) {
  703. if (sys_peer->sstclktype != CTL_SST_TS_UNSPEC) {
  704. this_clock = sys_peer->sstclktype;
  705. if (pps_control)
  706. this_clock |= CTL_SST_TS_PPS;
  707. } else {
  708. if (sys_peer->refclktype < sizeof(clocktypes))
  709. this_clock =
  710. clocktypes[sys_peer->refclktype];
  711. if (pps_control)
  712. this_clock |= CTL_SST_TS_PPS;
  713. }
  714. }
  715. #endif /* REFCLOCK */
  716. return (u_short)CTL_SYS_STATUS(sys_leap, this_clock,
  717. ctl_sys_num_events, ctl_sys_last_event);
  718. }
  719. /*
  720. * ctl_flushpkt - write out the current packet and prepare
  721. * another if necessary.
  722. */
  723. static void
  724. ctl_flushpkt(
  725. int more
  726. )
  727. {
  728. int dlen;
  729. int sendlen;
  730. if (!more && datanotbinflag) {
  731. /*
  732. * Big hack, output a trailing \r\n
  733. */
  734. *datapt++ = '\r';
  735. *datapt++ = '\n';
  736. }
  737. dlen = datapt - (u_char *)rpkt.data;
  738. sendlen = dlen + CTL_HEADER_LEN;
  739. /*
  740. * Pad to a multiple of 32 bits
  741. */
  742. while (sendlen & 0x3) {
  743. *datapt++ = '\0';
  744. sendlen++;
  745. }
  746. /*
  747. * Fill in the packet with the current info
  748. */
  749. rpkt.r_m_e_op = (u_char)(CTL_RESPONSE|more|(res_opcode &
  750. CTL_OP_MASK));
  751. rpkt.count = htons((u_short) dlen);
  752. rpkt.offset = htons( (u_short) res_offset);
  753. if (res_async) {
  754. register int i;
  755. for (i = 0; i < CTL_MAXTRAPS; i++) {
  756. if (ctl_trap[i].tr_flags & TRAP_INUSE) {
  757. rpkt.li_vn_mode =
  758. PKT_LI_VN_MODE(sys_leap,
  759. ctl_trap[i].tr_version,
  760. MODE_CONTROL);
  761. rpkt.sequence =
  762. htons(ctl_trap[i].tr_sequence);
  763. sendpkt(&ctl_trap[i].tr_addr,
  764. ctl_trap[i].tr_localaddr, -4,
  765. (struct pkt *)&rpkt, sendlen);
  766. if (!more)
  767. ctl_trap[i].tr_sequence++;
  768. numasyncmsgs++;
  769. }
  770. }
  771. } else {
  772. if (res_authenticate && sys_authenticate) {
  773. int maclen;
  774. int totlen = sendlen;
  775. keyid_t keyid = htonl(res_keyid);
  776. /*
  777. * If we are going to authenticate, then there
  778. * is an additional requirement that the MAC
  779. * begin on a 64 bit boundary.
  780. */
  781. while (totlen & 7) {
  782. *datapt++ = '\0';
  783. totlen++;
  784. }
  785. memcpy(datapt, &keyid, sizeof keyid);
  786. maclen = authencrypt(res_keyid,
  787. (u_int32 *)&rpkt, totlen);
  788. sendpkt(rmt_addr, lcl_inter, -5,
  789. (struct pkt *)&rpkt, totlen + maclen);
  790. } else {
  791. sendpkt(rmt_addr, lcl_inter, -6,
  792. (struct pkt *)&rpkt, sendlen);
  793. }
  794. if (more)
  795. numctlfrags++;
  796. else
  797. numctlresponses++;
  798. }
  799. /*
  800. * Set us up for another go around.
  801. */
  802. res_offset += dlen;
  803. datapt = (u_char *)rpkt.data;
  804. }
  805. /*
  806. * ctl_putdata - write data into the packet, fragmenting and starting
  807. * another if this one is full.
  808. */
  809. static void
  810. ctl_putdata(
  811. const char *dp,
  812. unsigned int dlen,
  813. int bin /* set to 1 when data is binary */
  814. )
  815. {
  816. int overhead;
  817. overhead = 0;
  818. if (!bin) {
  819. datanotbinflag = 1;
  820. overhead = 3;
  821. if (datapt != rpkt.data) {
  822. *datapt++ = ',';
  823. datalinelen++;
  824. if ((dlen + datalinelen + 1) >= MAXDATALINELEN)
  825. {
  826. *datapt++ = '\r';
  827. *datapt++ = '\n';
  828. datalinelen = 0;
  829. } else {
  830. *datapt++ = ' ';
  831. datalinelen++;
  832. }
  833. }
  834. }
  835. /*
  836. * Save room for trailing junk
  837. */
  838. if (dlen + overhead + datapt > dataend) {
  839. /*
  840. * Not enough room in this one, flush it out.
  841. */
  842. ctl_flushpkt(CTL_MORE);
  843. }
  844. memmove((char *)datapt, dp, (unsigned)dlen);
  845. datapt += dlen;
  846. datalinelen += dlen;
  847. }
  848. /*
  849. * ctl_putstr - write a tagged string into the response packet
  850. */
  851. static void
  852. ctl_putstr(
  853. const char *tag,
  854. const char *data,
  855. unsigned int len
  856. )
  857. {
  858. register char *cp;
  859. register const char *cq;
  860. char buffer[400];
  861. cp = buffer;
  862. cq = tag;
  863. while (*cq != '\0')
  864. *cp++ = *cq++;
  865. if (len > 0) {
  866. *cp++ = '=';
  867. *cp++ = '"';
  868. if (len > (int) (sizeof(buffer) - (cp - buffer) - 1))
  869. len = sizeof(buffer) - (cp - buffer) - 1;
  870. memmove(cp, data, (unsigned)len);
  871. cp += len;
  872. *cp++ = '"';
  873. }
  874. ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
  875. }
  876. /*
  877. * ctl_putdbl - write a tagged, signed double into the response packet
  878. */
  879. static void
  880. ctl_putdbl(
  881. const char *tag,
  882. double ts
  883. )
  884. {
  885. register char *cp;
  886. register const char *cq;
  887. char buffer[200];
  888. cp = buffer;
  889. cq = tag;
  890. while (*cq != '\0')
  891. *cp++ = *cq++;
  892. *cp++ = '=';
  893. (void)sprintf(cp, "%.3f", ts);
  894. while (*cp != '\0')
  895. cp++;
  896. ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
  897. }
  898. /*
  899. * ctl_putuint - write a tagged unsigned integer into the response
  900. */
  901. static void
  902. ctl_putuint(
  903. const char *tag,
  904. u_long uval
  905. )
  906. {
  907. register char *cp;
  908. register const char *cq;
  909. char buffer[200];
  910. cp = buffer;
  911. cq = tag;
  912. while (*cq != '\0')
  913. *cp++ = *cq++;
  914. *cp++ = '=';
  915. (void) sprintf(cp, "%lu", uval);
  916. while (*cp != '\0')
  917. cp++;
  918. ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
  919. }
  920. /*
  921. * ctl_putfs - write a decoded filestamp into the response
  922. */
  923. #ifdef OPENSSL
  924. static void
  925. ctl_putfs(
  926. const char *tag,
  927. tstamp_t uval
  928. )
  929. {
  930. register char *cp;
  931. register const char *cq;
  932. char buffer[200];
  933. struct tm *tm = NULL;
  934. time_t fstamp;
  935. cp = buffer;
  936. cq = tag;
  937. while (*cq != '\0')
  938. *cp++ = *cq++;
  939. *cp++ = '=';
  940. fstamp = uval - JAN_1970;
  941. tm = gmtime(&fstamp);
  942. if (tm == NULL)
  943. return;
  944. sprintf(cp, "%04d%02d%02d%02d%02d", tm->tm_year + 1900,
  945. tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min);
  946. while (*cp != '\0')
  947. cp++;
  948. ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
  949. }
  950. #endif
  951. /*
  952. * ctl_puthex - write a tagged unsigned integer, in hex, into the response
  953. */
  954. static void
  955. ctl_puthex(
  956. const char *tag,
  957. u_long uval
  958. )
  959. {
  960. register char *cp;
  961. register const char *cq;
  962. char buffer[200];
  963. cp = buffer;
  964. cq = tag;
  965. while (*cq != '\0')
  966. *cp++ = *cq++;
  967. *cp++ = '=';
  968. (void) sprintf(cp, "0x%lx", uval);
  969. while (*cp != '\0')
  970. cp++;
  971. ctl_putdata(buffer,(unsigned)( cp - buffer ), 0);
  972. }
  973. /*
  974. * ctl_putint - write a tagged signed integer into the response
  975. */
  976. static void
  977. ctl_putint(
  978. const char *tag,
  979. long ival
  980. )
  981. {
  982. register char *cp;
  983. register const char *cq;
  984. char buffer[200];
  985. cp = buffer;
  986. cq = tag;
  987. while (*cq != '\0')
  988. *cp++ = *cq++;
  989. *cp++ = '=';
  990. (void) sprintf(cp, "%ld", ival);
  991. while (*cp != '\0')
  992. cp++;
  993. ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
  994. }
  995. /*
  996. * ctl_putts - write a tagged timestamp, in hex, into the response
  997. */
  998. static void
  999. ctl_putts(
  1000. const char *tag,
  1001. l_fp *ts
  1002. )
  1003. {
  1004. register char *cp;
  1005. register const char *cq;
  1006. char buffer[200];
  1007. cp = buffer;
  1008. cq = tag;
  1009. while (*cq != '\0')
  1010. *cp++ = *cq++;
  1011. *cp++ = '=';
  1012. (void) sprintf(cp, "0x%08lx.%08lx",
  1013. ts->l_ui & ULONG_CONST(0xffffffff),
  1014. ts->l_uf & ULONG_CONST(0xffffffff));
  1015. while (*cp != '\0')
  1016. cp++;
  1017. ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
  1018. }
  1019. /*
  1020. * ctl_putadr - write an IP address into the response
  1021. */
  1022. static void
  1023. ctl_putadr(
  1024. const char *tag,
  1025. u_int32 addr32,
  1026. struct sockaddr_storage* addr
  1027. )
  1028. {
  1029. register char *cp;
  1030. register const char *cq;
  1031. char buffer[200];
  1032. cp = buffer;
  1033. cq = tag;
  1034. while (*cq != '\0')
  1035. *cp++ = *cq++;
  1036. *cp++ = '=';
  1037. if (addr == NULL)
  1038. cq = numtoa(addr32);
  1039. else
  1040. cq = stoa(addr);
  1041. while (*cq != '\0')
  1042. *cp++ = *cq++;
  1043. ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
  1044. }
  1045. /*
  1046. * ctl_putid - write a tagged clock ID into the response
  1047. */
  1048. static void
  1049. ctl_putid(
  1050. const char *tag,
  1051. char *id
  1052. )
  1053. {
  1054. register char *cp;
  1055. register const char *cq;
  1056. char buffer[200];
  1057. cp = buffer;
  1058. cq = tag;
  1059. while (*cq != '\0')
  1060. *cp++ = *cq++;
  1061. *cp++ = '=';
  1062. cq = id;
  1063. while (*cq != '\0' && (cq - id) < 4)
  1064. *cp++ = *cq++;
  1065. ctl_putdata(buffer, (unsigned)( cp - buffer ), 0);
  1066. }
  1067. /*
  1068. * ctl_putarray - write a tagged eight element double array into the response
  1069. */
  1070. static void
  1071. ctl_putarray(
  1072. const char *tag,
  1073. double *arr,
  1074. int start
  1075. )
  1076. {
  1077. register char *cp;
  1078. register const char *cq;
  1079. char buffer[200];
  1080. int i;
  1081. cp = buffer;
  1082. cq = tag;
  1083. while (*cq != '\0')
  1084. *cp++ = *cq++;
  1085. i = start;
  1086. do {
  1087. if (i == 0)
  1088. i = NTP_SHIFT;
  1089. i--;
  1090. (void)sprintf(cp, " %.2f", arr[i] * 1e3);
  1091. while (*cp != '\0')
  1092. cp++;
  1093. } while(i != start);
  1094. ctl_putdata(buffer, (unsigned)(cp - buffer), 0);
  1095. }
  1096. /*
  1097. * ctl_putsys - output a system variable
  1098. */
  1099. static void
  1100. ctl_putsys(
  1101. int varid
  1102. )
  1103. {
  1104. l_fp tmp;
  1105. char str[256];
  1106. #ifdef OPENSSL
  1107. struct cert_info *cp;
  1108. char cbuf[256];
  1109. #endif /* OPENSSL */
  1110. switch (varid) {
  1111. case CS_LEAP:
  1112. ctl_putuint(sys_var[CS_LEAP].text, sys_leap);
  1113. break;
  1114. case CS_STRATUM:
  1115. ctl_putuint(sys_var[CS_STRATUM].text, sys_stratum);
  1116. break;
  1117. case CS_PRECISION:
  1118. ctl_putint(sys_var[CS_PRECISION].text, sys_precision);
  1119. break;
  1120. case CS_ROOTDELAY:
  1121. ctl_putdbl(sys_var[CS_ROOTDELAY].text, sys_rootdelay *
  1122. 1e3);
  1123. break;
  1124. case CS_ROOTDISPERSION:
  1125. ctl_putdbl(sys_var[CS_ROOTDISPERSION].text,
  1126. sys_rootdispersion * 1e3);
  1127. break;
  1128. case CS_REFID:
  1129. if (sys_stratum > 1 && sys_stratum < STRATUM_UNSPEC)
  1130. ctl_putadr(sys_var[CS_REFID].text, sys_refid, NULL);
  1131. else
  1132. ctl_putid(sys_var[CS_REFID].text,
  1133. (char *)&sys_refid);
  1134. break;
  1135. case CS_REFTIME:
  1136. ctl_putts(sys_var[CS_REFTIME].text, &sys_reftime);
  1137. break;
  1138. case CS_POLL:
  1139. ctl_putuint(sys_var[CS_POLL].text, sys_poll);
  1140. break;
  1141. case CS_PEERID:
  1142. if (sys_peer == NULL)
  1143. ctl_putuint(sys_var[CS_PEERID].text, 0);
  1144. else
  1145. ctl_putuint(sys_var[CS_PEERID].text,
  1146. sys_peer->associd);
  1147. break;
  1148. case CS_STATE:
  1149. ctl_putuint(sys_var[CS_STATE].text, (unsigned)state);
  1150. break;
  1151. case CS_OFFSET:
  1152. ctl_putdbl(sys_var[CS_OFFSET].text, last_offset * 1e3);
  1153. break;
  1154. case CS_DRIFT:
  1155. ctl_putdbl(sys_var[CS_DRIFT].text, drift_comp * 1e6);
  1156. break;
  1157. case CS_JITTER:
  1158. ctl_putdbl(sys_var[CS_JITTER].text, sys_jitter * 1e3);
  1159. break;
  1160. case CS_ERROR:
  1161. ctl_putdbl(sys_var[CS_ERROR].text, clock_jitter * 1e3);
  1162. break;
  1163. case CS_CLOCK:
  1164. get_systime(&tmp);
  1165. ctl_putts(sys_var[CS_CLOCK].text, &tmp);
  1166. break;
  1167. case CS_PROCESSOR:
  1168. #ifndef HAVE_UNAME
  1169. ctl_putstr(sys_var[CS_PROCESSOR].text, str_processor,
  1170. sizeof(str_processor) - 1);
  1171. #else
  1172. ctl_putstr(sys_var[CS_PROCESSOR].text,
  1173. utsnamebuf.machine, strlen(utsnamebuf.machine));
  1174. #endif /* HAVE_UNAME */
  1175. break;
  1176. case CS_SYSTEM:
  1177. #ifndef HAVE_UNAME
  1178. ctl_putstr(sys_var[CS_SYSTEM].text, str_system,
  1179. sizeof(str_system) - 1);
  1180. #else
  1181. sprintf(str, "%s/%s", utsnamebuf.sysname, utsnamebuf.release);
  1182. ctl_putstr(sys_var[CS_SYSTEM].text, str, strlen(str));
  1183. #endif /* HAVE_UNAME */
  1184. break;
  1185. case CS_VERSION:
  1186. ctl_putstr(sys_var[CS_VERSION].text, Version,
  1187. strlen(Version));
  1188. break;
  1189. case CS_STABIL:
  1190. ctl_putdbl(sys_var[CS_STABIL].text, clock_stability *
  1191. 1e6);
  1192. break;
  1193. case CS_VARLIST:
  1194. {
  1195. char buf[CTL_MAX_DATA_LEN];
  1196. register char *s, *t, *be;
  1197. register const char *ss;
  1198. register int i;
  1199. register struct ctl_var *k;
  1200. s = buf;
  1201. be = buf + sizeof(buf) -
  1202. strlen(sys_var[CS_VARLIST].text) - 4;
  1203. if (s > be)
  1204. break; /* really long var name */
  1205. strcpy(s, sys_var[CS_VARLIST].text);
  1206. strcat(s, "=\"");
  1207. s += strlen(s);
  1208. t = s;
  1209. for (k = sys_var; !(k->flags &EOV); k++) {
  1210. if (k->flags & PADDING)
  1211. continue;
  1212. i = strlen(k->text);
  1213. if (s+i+1 >= be)
  1214. break;
  1215. if (s != t)
  1216. *s++ = ',';
  1217. strcpy(s, k->text);
  1218. s += i;
  1219. }
  1220. for (k = ext_sys_var; k && !(k->flags &EOV);
  1221. k++) {
  1222. if (k->flags & PADDING)
  1223. continue;
  1224. ss = k->text;
  1225. if (!ss)
  1226. continue;
  1227. while (*ss && *ss != '=')
  1228. ss++;
  1229. i = ss - k->text;
  1230. if (s + i + 1 >= be)
  1231. break;
  1232. if (s != t)
  1233. *s++ = ',';
  1234. strncpy(s, k->text,
  1235. (unsigned)i);
  1236. s += i;
  1237. }
  1238. if (s+2 >= be)
  1239. break;
  1240. *s++ = '"';
  1241. *s = '\0';
  1242. ctl_putdata(buf, (unsigned)( s - buf ),
  1243. 0);
  1244. }
  1245. break;
  1246. #ifdef OPENSSL
  1247. case CS_FLAGS:
  1248. if (crypto_flags) {
  1249. ctl_puthex(sys_var[CS_FLAGS].text, crypto_flags);
  1250. }
  1251. break;
  1252. case CS_DIGEST:
  1253. if (crypto_flags) {
  1254. const EVP_MD *dp;
  1255. dp = EVP_get_digestbynid(crypto_flags >> 16);
  1256. strcpy(str, OBJ_nid2ln(EVP_MD_pkey_type(dp)));
  1257. ctl_putstr(sys_var[CS_DIGEST].text, str,
  1258. strlen(str));
  1259. }
  1260. break;
  1261. case CS_HOST:
  1262. if (sys_hostname != NULL)
  1263. ctl_putstr(sys_var[CS_HOST].text, sys_hostname,
  1264. strlen(sys_hostname));
  1265. break;
  1266. case CS_CERTIF:
  1267. for (cp = cinfo; cp != NULL; cp = cp->link) {
  1268. sprintf(cbuf, "%s %s 0x%x", cp->subject,
  1269. cp->issuer, cp->flags);
  1270. ctl_putstr(sys_var[CS_CERTIF].text, cbuf,
  1271. strlen(cbuf));
  1272. ctl_putfs(sys_var[CS_REVOKE].text, cp->last);
  1273. }
  1274. break;
  1275. case CS_PUBLIC:
  1276. if (hostval.fstamp != 0)
  1277. ctl_putfs(sys_var[CS_PUBLIC].text,
  1278. ntohl(hostval.tstamp));
  1279. break;
  1280. case CS_REVTIME:
  1281. if (hostval.tstamp != 0)
  1282. ctl_putfs(sys_var[CS_REVTIME].text,
  1283. ntohl(hostval.tstamp));
  1284. break;
  1285. case CS_IDENT:
  1286. if (iffpar_pkey != NULL)
  1287. ctl_putstr(sys_var[CS_IDENT].text,
  1288. iffpar_file, strlen(iffpar_file));
  1289. if (gqpar_pkey != NULL)
  1290. ctl_putstr(sys_var[CS_IDENT].text,
  1291. gqpar_file, strlen(gqpar_file));
  1292. if (mvpar_pkey != NULL)
  1293. ctl_putstr(sys_var[CS_IDENT].text,
  1294. mvpar_file, strlen(mvpar_file));
  1295. break;
  1296. case CS_LEAPTAB:
  1297. if (tai_leap.fstamp != 0)
  1298. ctl_putfs(sys_var[CS_LEAPTAB].text,
  1299. ntohl(tai_leap.fstamp));
  1300. break;
  1301. case CS_TAI:
  1302. ctl_putuint(sys_var[CS_TAI].text, sys_tai);
  1303. break;
  1304. #endif /* OPENSSL */
  1305. }
  1306. }
  1307. /*
  1308. * ctl_putpeer - output a peer variable
  1309. */
  1310. static void
  1311. ctl_putpeer(
  1312. int varid,
  1313. struct peer *peer
  1314. )
  1315. {
  1316. int temp;
  1317. #ifdef OPENSSL
  1318. char str[256];
  1319. struct autokey *ap;
  1320. #endif /* OPENSSL */
  1321. switch (varid) {
  1322. case CP_CONFIG:
  1323. ctl_putuint(peer_var[CP_CONFIG].text,
  1324. (unsigned)((peer->flags & FLAG_CONFIG) != 0));
  1325. break;
  1326. case CP_AUTHENABLE:
  1327. ctl_putuint(peer_var[CP_AUTHENABLE].text,
  1328. (unsigned)((peer->flags & FLAG_AUTHENABLE) != 0));
  1329. break;
  1330. case CP_AUTHENTIC:
  1331. ctl_putuint(peer_var[CP_AUTHENTIC].text,
  1332. (unsigned)((peer->flags & FLAG_AUTHENTIC) != 0));
  1333. break;
  1334. case CP_SRCADR:
  1335. ctl_putadr(peer_var[CP_SRCADR].text, 0,
  1336. &peer->srcadr);
  1337. break;
  1338. case CP_SRCPORT:
  1339. ctl_putuint(peer_var[CP_SRCPORT].text,
  1340. ntohs(((struct sockaddr_in*)&peer->srcadr)->sin_port));
  1341. break;
  1342. case CP_DSTADR:
  1343. if (peer->dstadr) {
  1344. ctl_putadr(peer_var[CP_DSTADR].text, 0,
  1345. &(peer->dstadr->sin));
  1346. } else {
  1347. ctl_putadr(peer_var[CP_DSTADR].text, 0,
  1348. NULL);
  1349. }
  1350. break;
  1351. case CP_DSTPORT:
  1352. ctl_putuint(peer_var[CP_DSTPORT].text,
  1353. (u_long)(peer->dstadr ?
  1354. ntohs(((struct sockaddr_in*)&peer->dstadr->sin)->sin_port) : 0));
  1355. break;
  1356. case CP_LEAP:
  1357. ctl_putuint(peer_var[CP_LEAP].text, peer->leap);
  1358. break;
  1359. case CP_HMODE:
  1360. ctl_putuint(peer_var[CP_HMODE].text, peer->hmode);
  1361. break;
  1362. case CP_STRATUM:
  1363. ctl_putuint(peer_var[CP_STRATUM].text, peer->stratum);
  1364. break;
  1365. case CP_PPOLL:
  1366. ctl_putuint(peer_var[CP_PPOLL].text, peer->ppoll);
  1367. break;
  1368. case CP_HPOLL:
  1369. ctl_putuint(peer_var[CP_HPOLL].text, peer->hpoll);
  1370. break;
  1371. case CP_PRECISION:
  1372. ctl_putint(peer_var[CP_PRECISION].text,
  1373. peer->precision);
  1374. break;
  1375. case CP_ROOTDELAY:
  1376. ctl_putdbl(peer_var[CP_ROOTDELAY].text,
  1377. peer->rootdelay * 1e3);
  1378. break;
  1379. case CP_ROOTDISPERSION:
  1380. ctl_putdbl(peer_var[CP_ROOTDISPERSION].text,
  1381. peer->rootdispersion * 1e3);
  1382. break;
  1383. case CP_REFID:
  1384. if (peer->flags & FLAG_REFCLOCK) {
  1385. ctl_putid(peer_var[CP_REFID].text,
  1386. (char *)&peer->refid);
  1387. } else {
  1388. if (peer->stratum > 1 && peer->stratum <
  1389. STRATUM_UNSPEC)
  1390. ctl_putadr(peer_var[CP_REFID].text,
  1391. peer->refid, NULL);
  1392. else
  1393. ctl_putid(peer_var[CP_REFID].text,
  1394. (char *)&peer->refid);
  1395. }
  1396. break;
  1397. case CP_REFTIME:
  1398. ctl_putts(peer_var[CP_REFTIME].text, &peer->reftime);
  1399. break;
  1400. case CP_ORG:
  1401. ctl_putts(peer_var[CP_ORG].text, &peer->org);
  1402. break;
  1403. case CP_REC:
  1404. ctl_putts(peer_var[CP_REC].text, &peer->rec);
  1405. break;
  1406. case CP_XMT:
  1407. ctl_putts(peer_var[CP_XMT].text, &peer->xmt);
  1408. break;
  1409. case CP_REACH:
  1410. ctl_puthex(peer_var[CP_REACH].text, peer->reach);
  1411. break;
  1412. case CP_FLASH:
  1413. temp = peer->flash;
  1414. ctl_puthex(peer_var[CP_FLASH].text, temp);
  1415. break;
  1416. case CP_TTL:
  1417. ctl_putint(peer_var[CP_TTL].text, sys_ttl[peer->ttl]);
  1418. break;
  1419. case CP_UNREACH:
  1420. ctl_putuint(peer_var[CP_UNREACH].text, peer->unreach);
  1421. break;
  1422. case CP_TIMER:
  1423. ctl_putuint(peer_var[CP_TIMER].text,
  1424. peer->nextdate - current_time);
  1425. break;
  1426. case CP_DELAY:
  1427. ctl_putdbl(peer_var[CP_DELAY].text, peer->delay * 1e3);
  1428. break;
  1429. case CP_OFFSET:
  1430. ctl_putdbl(peer_var[CP_OFFSET].text, peer->offset *
  1431. 1e3);
  1432. break;
  1433. case CP_JITTER:
  1434. ctl_putdbl(peer_var[CP_JITTER].text, peer->jitter * 1e3);
  1435. break;
  1436. case CP_DISPERSION:
  1437. ctl_putdbl(peer_var[CP_DISPERSION].text, peer->disp *
  1438. 1e3);
  1439. break;
  1440. case CP_KEYID:
  1441. ctl_putuint(peer_var[CP_KEYID].text, peer->keyid);
  1442. break;
  1443. case CP_FILTDELAY:
  1444. ctl_putarray(peer_var[CP_FILTDELAY].text,
  1445. peer->filter_delay, (int)peer->filter_nextpt);
  1446. break;
  1447. case CP_FILTOFFSET:
  1448. ctl_putarray(peer_var[CP_FILTOFFSET].text,
  1449. peer->filter_offset, (int)peer->filter_nextpt);
  1450. break;
  1451. case CP_FILTERROR:
  1452. ctl_putarray(peer_var[CP_FILTERROR].text,
  1453. peer->filter_disp, (int)peer->filter_nextpt);
  1454. break;
  1455. case CP_PMODE:
  1456. ctl_putuint(peer_var[CP_PMODE].text, peer->pmode);
  1457. break;
  1458. case CP_RECEIVED:
  1459. ctl_putuint(peer_var[CP_RECEIVED].text, peer->received);
  1460. break;
  1461. case CP_SENT:
  1462. ctl_putuint(peer_var[CP_SENT].text, peer->sent);
  1463. break;
  1464. case CP_VARLIST:
  1465. {
  1466. char buf[CTL_MAX_DATA_LEN];
  1467. register char *s, *t, *be;
  1468. register int i;
  1469. register struct ctl_var *k;
  1470. s = buf;
  1471. be = buf + sizeof(buf) -
  1472. strlen(peer_var[CP_VARLIST].text) - 4;
  1473. if (s > be)
  1474. break; /* really long var name */
  1475. strcpy(s, peer_var[CP_VARLIST].text);
  1476. strcat(s, "=\"");
  1477. s += strlen(s);
  1478. t = s;
  1479. for (k = peer_var; !(k->flags &EOV); k++) {
  1480. if (k->flags & PADDING)
  1481. continue;
  1482. i = strlen(k->text);
  1483. if (s + i + 1 >= be)
  1484. break;
  1485. if (s != t)
  1486. *s++ = ',';
  1487. strcpy(s, k->text);
  1488. s += i;
  1489. }
  1490. if (s+2 >= be)
  1491. break;
  1492. *s++ = '"';
  1493. *s = '\0';
  1494. ctl_putdata(buf, (unsigned)(s - buf), 0);
  1495. }
  1496. break;
  1497. #ifdef OPENSSL
  1498. case CP_FLAGS:
  1499. if (peer->crypto)
  1500. ctl_puthex(peer_var[CP_FLAGS].text, peer->crypto);
  1501. break;
  1502. case CP_DIGEST:
  1503. if (peer->crypto) {
  1504. const EVP_MD *dp;
  1505. dp = EVP_get_digestbynid(peer->crypto >> 16);
  1506. strcpy(str, OBJ_nid2ln(EVP_MD_pkey_type(dp)));
  1507. ctl_putstr(peer_var[CP_DIGEST].text, str,
  1508. strlen(str));
  1509. }
  1510. break;
  1511. case CP_HOST:
  1512. if (peer->subject != NULL)
  1513. ctl_putstr(peer_var[CP_HOST].text,
  1514. peer->subject, strlen(peer->subject));
  1515. break;
  1516. case CP_VALID: /* not used */
  1517. break;
  1518. case CP_IDENT:
  1519. if (peer->issuer != NULL)
  1520. ctl_putstr(peer_var[CP_IDENT].text,
  1521. peer->issuer, strlen(peer->issuer));
  1522. break;
  1523. case CP_INITSEQ:
  1524. if ((ap = (struct autokey *)peer->recval.ptr) == NULL)
  1525. break;
  1526. ctl_putint(peer_var[CP_INITSEQ].text, ap->seq);
  1527. ctl_puthex(peer_var[CP_INITKEY].text, ap->key);
  1528. ctl_putfs(peer_var[CP_INITTSP].text,
  1529. ntohl(peer->recval.tstamp));
  1530. break;
  1531. #endif /* OPENSSL */
  1532. }
  1533. }
  1534. #ifdef REFCLOCK
  1535. /*
  1536. * ctl_putclock - output clock variables
  1537. */
  1538. static void
  1539. ctl_putclock(
  1540. int varid,
  1541. struct refclockstat *clock_stat,
  1542. int mustput
  1543. )
  1544. {
  1545. switch(varid) {
  1546. case CC_TYPE:
  1547. if (mustput || clock_stat->clockdesc == NULL
  1548. || *(clock_stat->clockdesc) == '\0') {
  1549. ctl_putuint(clock_var[CC_TYPE].text, clock_stat->type);
  1550. }
  1551. break;
  1552. case CC_TIMECODE:
  1553. ctl_putstr(clock_var[CC_TIMECODE].text,
  1554. clock_stat->p_lastcode,
  1555. (unsigned)clock_stat->lencode);
  1556. break;
  1557. case CC_POLL:
  1558. ctl_putuint(clock_var[CC_POLL].text, clock_stat->polls);
  1559. break;
  1560. case CC_NOREPLY:
  1561. ctl_putuint(clock_var[CC_NOREPLY].text,
  1562. clock_stat->noresponse);
  1563. break;
  1564. case CC_BADFORMAT:
  1565. ctl_putuint(clock_var[CC_BADFORMAT].text,
  1566. clock_stat->badformat);
  1567. break;
  1568. case CC_BADDATA:
  1569. ctl_putuint(clock_var[CC_BADDATA].text,
  1570. clock_stat->baddata);
  1571. break;
  1572. case CC_FUDGETIME1:
  1573. if (mustput || (clock_stat->haveflags & CLK_HAVETIME1))
  1574. ctl_putdbl(clock_var[CC_FUDGETIME1].text,
  1575. clock_stat->fudgetime1 * 1e3);
  1576. break;
  1577. case CC_FUDGETIME2:
  1578. if (mustput || (clock_stat->haveflags & CLK_HAVETIME2)) ctl_putdbl(clock_var[CC_FUDGETIME2].text,
  1579. clock_stat->fudgetime2 * 1e3);
  1580. break;
  1581. case CC_FUDGEVAL1:
  1582. if (mustput || (clock_stat->haveflags & CLK_HAVEVAL1))
  1583. ctl_putint(clock_var[CC_FUDGEVAL1].text,
  1584. clock_stat->fudgeval1);
  1585. break;
  1586. case CC_FUDGEVAL2:
  1587. if (mustput || (clock_stat->haveflags & CLK_HAVEVAL2)) {
  1588. if (clock_stat->fudgeval1 > 1)
  1589. ctl_putadr(clock_var[CC_FUDGEVAL2].text,
  1590. (u_int32)clock_stat->fudgeval2, NULL);
  1591. else
  1592. ctl_putid(clock_var[CC_FUDGEVAL2].text,
  1593. (char *)&clock_stat->fudgeval2);
  1594. }
  1595. break;
  1596. case CC_FLAGS:
  1597. if (mustput || (clock_stat->haveflags & (CLK_HAVEFLAG1 |
  1598. CLK_HAVEFLAG2 | CLK_HAVEFLAG3 | CLK_HAVEFLAG4)))
  1599. ctl_putuint(clock_var[CC_FLAGS].text,
  1600. clock_stat->flags);
  1601. break;
  1602. case CC_DEVICE:
  1603. if (clock_stat->clockdesc == NULL ||
  1604. *(clock_stat->clockdesc) == '\0') {
  1605. if (mustput)
  1606. ctl_putstr(clock_var[CC_DEVICE].text,
  1607. "", 0);
  1608. } else {
  1609. ctl_putstr(clock_var[CC_DEVICE].text,
  1610. clock_stat->clockdesc,
  1611. strlen(clock_stat->clockdesc));
  1612. }
  1613. break;
  1614. case CC_VARLIST:
  1615. {
  1616. char buf[CTL_MAX_DATA_LEN];
  1617. register char *s, *t, *be;
  1618. register const char *ss;
  1619. register int i;
  1620. register struct ctl_var *k;
  1621. s = buf;
  1622. be = buf + sizeof(buf);
  1623. if (s + strlen(clock_var[CC_VARLIST].text) + 4 >
  1624. be)
  1625. break; /* really long var name */
  1626. strcpy(s, clock_var[CC_VARLIST].text);
  1627. strcat(s, "=\"");
  1628. s += strlen(s);
  1629. t = s;
  1630. for (k = clock_var; !(k->flags &EOV); k++) {
  1631. if (k->flags & PADDING)
  1632. continue;
  1633. i = strlen(k->text);
  1634. if (s + i + 1 >= be)
  1635. break;
  1636. if (s != t)
  1637. *s++ = ',';
  1638. strcpy(s, k->text);
  1639. s += i;
  1640. }
  1641. for (k = clock_stat->kv_list; k && !(k->flags &
  1642. EOV); k++) {
  1643. if (k->flags & PADDING)
  1644. continue;
  1645. ss = k->text;
  1646. if (!ss)
  1647. continue;
  1648. while (*ss && *ss != '=')
  1649. ss++;
  1650. i = ss - k->text;
  1651. if (s+i+1 >= be)
  1652. break;
  1653. if (s != t)
  1654. *s++ = ',';
  1655. strncpy(s, k->text, (unsigned)i);
  1656. s += i;
  1657. *s = '\0';
  1658. }
  1659. if (s+2 >= be)
  1660. break;
  1661. *s++ = '"';
  1662. *s = '\0';
  1663. ctl_putdata(buf, (unsigned)( s - buf ), 0);
  1664. }
  1665. break;
  1666. }
  1667. }
  1668. #endif
  1669. /*
  1670. * ctl_getitem - get the next data item from the incoming packet
  1671. */
  1672. static struct ctl_var *
  1673. ctl_getitem(
  1674. struct ctl_var *var_list,
  1675. char **data
  1676. )
  1677. {
  1678. register struct ctl_var *v;
  1679. register char *cp;
  1680. register char *tp;
  1681. static struct ctl_var eol = { 0, EOV, };
  1682. static char buf[128];
  1683. /*
  1684. * Delete leading commas and white space
  1685. */
  1686. while (reqpt < reqend && (*reqpt == ',' ||
  1687. isspace((unsigned char)*reqpt)))
  1688. reqpt++;
  1689. if (reqpt >= reqend)
  1690. return (0);
  1691. if (var_list == (struct ctl_var *)0)
  1692. return (&eol);
  1693. /*
  1694. * Look for a first character match on the tag. If we find
  1695. * one, see if it is a full match.
  1696. */
  1697. v = var_list;
  1698. cp = reqpt;
  1699. while (!(v->flags & EOV)) {
  1700. if (!(v->flags & PADDING) && *cp == *(v->text)) {
  1701. tp = v->text;
  1702. while (*tp != '\0' && *tp != '=' && cp <
  1703. reqend && *cp == *tp) {
  1704. cp++;
  1705. tp++;
  1706. }
  1707. if ((*tp == '\0') || (*tp == '=')) {
  1708. while (cp < reqend && isspace((unsigned char)*cp))
  1709. cp++;
  1710. if (cp == reqend || *cp == ',') {
  1711. buf[0] = '\0';
  1712. *data = buf;
  1713. if (cp < reqend)
  1714. cp++;
  1715. reqpt = cp;
  1716. return v;
  1717. }
  1718. if (*cp == '=') {
  1719. cp++;
  1720. tp = buf;
  1721. while (cp < reqend && isspace((unsigned char)*cp))
  1722. cp++;
  1723. while (cp < reqend && *cp != ',') {
  1724. *tp++ = *cp++;
  1725. if (tp >= buf + sizeof(buf)) {
  1726. ctl_error(CERR_BADFMT);
  1727. numctlbadpkts++;
  1728. #if 0 /* Avoid possible DOS attack */
  1729. /* If we get a smarter msyslog we can re-enable this */
  1730. msyslog(LOG_WARNING,
  1731. "Possible 'ntpdx' exploit from %s:%d (possibly spoofed)\n",
  1732. stoa(rmt_addr), SRCPORT(rmt_addr)
  1733. );
  1734. #endif
  1735. return (0);
  1736. }
  1737. }
  1738. if (cp < reqend)
  1739. cp++;
  1740. *tp-- = '\0';
  1741. while (tp >= buf) {
  1742. if (!isspace((unsigned int)(*tp)))
  1743. break;
  1744. *tp-- = '\0';
  1745. }
  1746. reqpt = cp;
  1747. *data = buf;
  1748. return (v);
  1749. }
  1750. }
  1751. cp = reqpt;
  1752. }
  1753. v++;
  1754. }
  1755. return v;
  1756. }
  1757. /*
  1758. * control_unspec - response to an unspecified op-code
  1759. */
  1760. /*ARGSUSED*/
  1761. static void
  1762. control_unspec(
  1763. struct recvbuf *rbufp,
  1764. int restrict_mask
  1765. )
  1766. {
  1767. struct peer *peer;
  1768. /*
  1769. * What is an appropriate response to an unspecified op-code?
  1770. * I return no errors and no data, unless a specified assocation
  1771. * doesn't exist.
  1772. */
  1773. if (res_associd != 0) {
  1774. if ((peer = findpeerbyassoc(res_associd)) == 0) {
  1775. ctl_error(CERR_BADASSOC);
  1776. return;
  1777. }
  1778. rpkt.status = htons(ctlpeerstatus(peer));
  1779. } else {
  1780. rpkt.status = htons(ctlsysstatus());
  1781. }
  1782. ctl_flushpkt(0);
  1783. }
  1784. /*
  1785. * read_status - return either a list of associd's, or a particular
  1786. * peer's status.
  1787. */
  1788. /*ARGSUSED*/
  1789. static void
  1790. read_status(
  1791. struct recvbuf *rbufp,
  1792. int restrict_mask
  1793. )
  1794. {
  1795. register int i;
  1796. register struct peer *peer;
  1797. u_short ass_stat[CTL_MAX_DATA_LEN / sizeof(u_short)];
  1798. #ifdef DEBUG
  1799. if (debug > 2)
  1800. printf("read_status: ID %d\n", res_associd);
  1801. #endif
  1802. /*
  1803. * Two choices here. If the specified association ID is
  1804. * zero we return all known assocation ID's. Otherwise
  1805. * we return a bunch of stuff about the particular peer.
  1806. */
  1807. if (res_associd == 0) {
  1808. register int n;
  1809. n = 0;
  1810. rpkt.status = htons(ctlsysstatus());
  1811. for (i = 0; i < NTP_HASH_SIZE; i++) {
  1812. for (peer = assoc_hash[i]; peer != 0;
  1813. peer = peer->ass_next) {
  1814. ass_stat[n++] = htons(peer->associd);
  1815. ass_stat[n++] =
  1816. htons(ctlpeerstatus(peer));
  1817. if (n ==
  1818. CTL_MAX_DATA_LEN/sizeof(u_short)) {
  1819. ctl_putdata((char *)ass_stat,
  1820. n * sizeof(u_short), 1);
  1821. n = 0;
  1822. }
  1823. }
  1824. }
  1825. if (n != 0)
  1826. ctl_putdata((char *)ass_stat, n *
  1827. sizeof(u_short), 1);
  1828. ctl_flushpkt(0);
  1829. } else {
  1830. peer = findpeerbyassoc(res_associd);
  1831. if (peer == 0) {
  1832. ctl_error(CERR_BADASSOC);
  1833. } else {
  1834. register u_char *cp;
  1835. rpkt.status = htons(ctlpeerstatus(peer));
  1836. if (res_authokay)
  1837. peer->num_events = 0;
  1838. /*
  1839. * For now, output everything we know about the
  1840. * peer. May be more selective later.
  1841. */
  1842. for (cp = def_peer_var; *cp != 0; cp++)
  1843. ctl_putpeer((int)*cp, peer);
  1844. ctl_flushpkt(0);
  1845. }
  1846. }
  1847. }
  1848. /*
  1849. * read_variables - return the variables the caller asks for
  1850. */
  1851. /*ARGSUSED*/
  1852. static void
  1853. read_variables(
  1854. struct recvbuf *rbufp,
  1855. int restrict_mask
  1856. )
  1857. {
  1858. register struct ctl_var *v;
  1859. register int i;
  1860. char *valuep;
  1861. u_char *wants;
  1862. unsigned int gotvar = (CS_MAXCODE > CP_MAXCODE) ? (CS_MAXCODE +
  1863. 1) : (CP_MAXCODE + 1);
  1864. if (res_associd == 0) {
  1865. /*
  1866. * Wants system variables. Figure out which he wants
  1867. * and give them to him.
  1868. */
  1869. rpkt.status = htons(ctlsysstatus());
  1870. if (res_authokay)
  1871. ctl_sys_num_events = 0;
  1872. gotvar += count_var(ext_sys_var);
  1873. wants = (u_char *)emalloc(gotvar);
  1874. memset((char *)wants, 0, gotvar);
  1875. gotvar = 0;
  1876. while ((v = ctl_getitem(sys_var, &valuep)) != 0) {
  1877. if (v->flags & EOV) {
  1878. if ((v = ctl_getitem(ext_sys_var,
  1879. &valuep)) != 0) {
  1880. if (v->flags & EOV) {
  1881. ctl_error(CERR_UNKNOWNVAR);
  1882. free((char *)wants);
  1883. return;
  1884. }
  1885. wants[CS_MAXCODE + 1 +
  1886. v->code] = 1;
  1887. gotvar = 1;
  1888. continue;
  1889. } else {
  1890. break; /* shouldn't happen ! */
  1891. }
  1892. }
  1893. wants[v->code] = 1;
  1894. gotvar = 1;
  1895. }
  1896. if (gotvar) {
  1897. for (i = 1; i <= CS_MAXCODE; i++)
  1898. if (wants[i])
  1899. ctl_putsys(i);
  1900. for (i = 0; ext_sys_var &&
  1901. !(ext_sys_var[i].flags & EOV); i++)
  1902. if (wants[i + CS_MAXCODE + 1])
  1903. ctl_putdata(ext_sys_var[i].text,
  1904. strlen(ext_sys_var[i].text),
  1905. 0);
  1906. } else {
  1907. register u_char *cs;
  1908. register struct ctl_var *kv;
  1909. for (cs = def_sys_var; *cs != 0; cs++)
  1910. ctl_putsys((int)*cs);
  1911. for (kv = ext_sys_var; kv && !(kv->flags & EOV);
  1912. kv++)
  1913. if (kv->flags & DEF)
  1914. ctl_putdata(kv->text,
  1915. strlen(kv->text), 0);
  1916. }
  1917. free((char *)wants);
  1918. } else {
  1919. register struct peer *peer;
  1920. /*
  1921. * Wants info for a particular peer. See if we know
  1922. * the guy.
  1923. */
  1924. peer = findpeerbyassoc(res_associd);
  1925. if (peer == 0) {
  1926. ctl_error(CERR_BADASSOC);
  1927. return;
  1928. }
  1929. rpkt.status = htons(ctlpeerstatus(peer));
  1930. if (res_authokay)
  1931. peer->num_events = 0;
  1932. wants = (u_char *)emalloc(gotvar);
  1933. memset((char*)wants, 0, gotvar);
  1934. gotvar = 0;
  1935. while ((v = ctl_getitem(peer_var, &valuep)) != 0) {
  1936. if (v->flags & EOV) {
  1937. ctl_error(CERR_UNKNOWNVAR);
  1938. free((char *)wants);
  1939. return;
  1940. }
  1941. wants[v->code] = 1;
  1942. gotvar = 1;
  1943. }
  1944. if (gotvar) {
  1945. for (i = 1; i <= CP_MAXCODE; i++)
  1946. if (wants[i])
  1947. ctl_putpeer(i, peer);
  1948. } else {
  1949. register u_char *cp;
  1950. for (cp = def_peer_var; *cp != 0; cp++)
  1951. ctl_putpeer((int)*cp, peer);
  1952. }
  1953. free((char *)wants);
  1954. }
  1955. ctl_flushpkt(0);
  1956. }
  1957. /*
  1958. * write_variables - write into variables. We only allow leap bit
  1959. * writing this way.
  1960. */
  1961. /*ARGSUSED*/
  1962. static void
  1963. write_variables(
  1964. struct recvbuf *rbufp,
  1965. int restrict_mask
  1966. )
  1967. {
  1968. register struct ctl_var *v;
  1969. register int ext_var;
  1970. char *valuep;
  1971. long val = 0;
  1972. /*
  1973. * If he's trying to write into a peer tell him no way
  1974. */
  1975. if (res_associd != 0) {
  1976. ctl_error(CERR_PERMISSION);
  1977. return;
  1978. }
  1979. /*
  1980. * Set status
  1981. */
  1982. rpkt.status = htons(ctlsysstatus());
  1983. /*
  1984. * Look through the variables. Dump out at the first sign of
  1985. * trouble.
  1986. */
  1987. while ((v = ctl_getitem(sys_var, &valuep)) != 0) {
  1988. ext_var = 0;
  1989. if (v->flags & EOV) {
  1990. if ((v = ctl_getitem(ext_sys_var, &valuep)) !=
  1991. 0) {
  1992. if (v->flags & EOV) {
  1993. ctl_error(CERR_UNKNOWNVAR);
  1994. return;
  1995. }
  1996. ext_var = 1;
  1997. } else {
  1998. break;
  1999. }
  2000. }
  2001. if (!(v->flags & CAN_WRITE)) {
  2002. ctl_error(CERR_PERMISSION);
  2003. return;
  2004. }
  2005. if (!ext_var && (*valuep == '\0' || !atoint(valuep,
  2006. &val))) {
  2007. ctl_error(CERR_BADFMT);
  2008. return;
  2009. }
  2010. if (!ext_var && (val & ~LEAP_NOTINSYNC) != 0) {
  2011. ctl_error(CERR_BADVALUE);
  2012. return;
  2013. }
  2014. if (ext_var) {
  2015. char *s = (char *)emalloc(strlen(v->text) +
  2016. strlen(valuep) + 2);
  2017. const char *t;
  2018. char *tt = s;
  2019. t = v->text;
  2020. while (*t && *t != '=')
  2021. *tt++ = *t++;
  2022. *tt++ = '=';
  2023. strcat(tt, valuep);
  2024. set_sys_var(s, strlen(s)+1, v->flags);
  2025. free(s);
  2026. } else {
  2027. /*
  2028. * This one seems sane. Save it.
  2029. */
  2030. switch(v->code) {
  2031. case CS_LEAP:
  2032. default:
  2033. ctl_error(CERR_UNSPEC); /* really */
  2034. return;
  2035. }
  2036. }
  2037. }
  2038. /*
  2039. * If we got anything, do it. xxx nothing to do ***
  2040. */
  2041. /*
  2042. if (leapind != ~0 || leapwarn != ~0) {
  2043. if (!leap_setleap((int)leapind, (int)leapwarn)) {
  2044. ctl_error(CERR_PERMISSION);
  2045. return;
  2046. }
  2047. }
  2048. */
  2049. ctl_flushpkt(0);
  2050. }
  2051. /*
  2052. * read_clock_status - return clock radio status
  2053. */
  2054. /*ARGSUSED*/
  2055. static void
  2056. read_clock_status(
  2057. struct recvbuf *rbufp,
  2058. int restrict_mask
  2059. )
  2060. {
  2061. #ifndef REFCLOCK
  2062. /*
  2063. * If no refclock support, no data to return
  2064. */
  2065. ctl_error(CERR_BADASSOC);
  2066. #else
  2067. register struct ctl_var *v;
  2068. register int i;
  2069. register struct peer *peer;
  2070. char *valuep;
  2071. u_char *wants;
  2072. unsigned int gotvar;
  2073. struct refclockstat clock_stat;
  2074. if (res_associd == 0) {
  2075. /*
  2076. * Find a clock for this jerk. If the system peer
  2077. * is a clock use it, else search the hash tables
  2078. * for one.
  2079. */
  2080. if (sys_peer != 0 && (sys_peer->flags & FLAG_REFCLOCK))
  2081. {
  2082. peer = sys_peer;
  2083. } else {
  2084. peer = 0;
  2085. for (i = 0; peer == 0 && i < NTP_HASH_SIZE; i++) {
  2086. for (peer = assoc_hash[i]; peer != 0;
  2087. peer = peer->ass_next) {
  2088. if (peer->flags & FLAG_REFCLOCK)
  2089. break;
  2090. }
  2091. }
  2092. if (peer == 0) {
  2093. ctl_error(CERR_BADASSOC);
  2094. return;
  2095. }
  2096. }
  2097. } else {
  2098. peer = findpeerbyassoc(res_associd);
  2099. if (peer == 0 || !(peer->flags & FLAG_REFCLOCK)) {
  2100. ctl_error(CERR_BADASSOC);
  2101. return;
  2102. }
  2103. }
  2104. /*
  2105. * If we got here we have a peer which is a clock. Get his
  2106. * status.
  2107. */
  2108. clock_stat.kv_list = (struct ctl_var *)0;
  2109. refclock_control(&peer->srcadr, (struct refclockstat *)0,
  2110. &clock_stat);
  2111. /*
  2112. * Look for variables in the packet.
  2113. */
  2114. rpkt.status = htons(ctlclkstatus(&clock_stat));
  2115. gotvar = CC_MAXCODE + 1 + count_var(clock_stat.kv_list);
  2116. wants = (u_char *)emalloc(gotvar);
  2117. memset((char*)wants, 0, gotvar);
  2118. gotvar = 0;
  2119. while ((v = ctl_getitem(clock_var, &valuep)) != 0) {
  2120. if (v->flags & EOV) {
  2121. if ((v = ctl_getitem(clock_stat.kv_list,
  2122. &valuep)) != 0) {
  2123. if (v->flags & EOV) {
  2124. ctl_error(CERR_UNKNOWNVAR);
  2125. free((char*)wants);
  2126. free_varlist(clock_stat.kv_list);
  2127. return;
  2128. }
  2129. wants[CC_MAXCODE + 1 + v->code] = 1;
  2130. gotvar = 1;
  2131. continue;
  2132. } else {
  2133. break; /* shouldn't happen ! */
  2134. }
  2135. }
  2136. wants[v->code] = 1;
  2137. gotvar = 1;
  2138. }
  2139. if (gotvar) {
  2140. for (i = 1; i <= CC_MAXCODE; i++)
  2141. if (wants[i])
  2142. ctl_putclock(i, &clock_stat, 1);
  2143. for (i = 0; clock_stat.kv_list &&
  2144. !(clock_stat.kv_list[i].flags & EOV); i++)
  2145. if (wants[i + CC_MAXCODE + 1])
  2146. ctl_putdata(clock_stat.kv_list[i].text,
  2147. strlen(clock_stat.kv_list[i].text),
  2148. 0);
  2149. } else {
  2150. register u_char *cc;
  2151. register struct ctl_var *kv;
  2152. for (cc = def_clock_var; *cc != 0; cc++)
  2153. ctl_putclock((int)*cc, &clock_stat, 0);
  2154. for (kv = clock_stat.kv_list; kv && !(kv->flags & EOV);
  2155. kv++)
  2156. if (kv->flags & DEF)
  2157. ctl_putdata(kv->text, strlen(kv->text),
  2158. 0);
  2159. }
  2160. free((char*)wants);
  2161. free_varlist(clock_stat.kv_list);
  2162. ctl_flushpkt(0);
  2163. #endif
  2164. }
  2165. /*
  2166. * write_clock_status - we don't do this
  2167. */
  2168. /*ARGSUSED*/
  2169. static void
  2170. write_clock_status(
  2171. struct recvbuf *rbufp,
  2172. int restrict_mask
  2173. )
  2174. {
  2175. ctl_error(CERR_PERMISSION);
  2176. }
  2177. /*
  2178. * Trap support from here on down. We send async trap messages when the
  2179. * upper levels report trouble. Traps can by set either by control
  2180. * messages or by configuration.
  2181. */
  2182. /*
  2183. * set_trap - set a trap in response to a control message
  2184. */
  2185. static void
  2186. set_trap(
  2187. struct recvbuf *rbufp,
  2188. int restrict_mask
  2189. )
  2190. {
  2191. int traptype;
  2192. /*
  2193. * See if this guy is allowed
  2194. */
  2195. if (restrict_mask & RES_NOTRAP) {
  2196. ctl_error(CERR_PERMISSION);
  2197. return;
  2198. }
  2199. /*
  2200. * Determine his allowed trap type.
  2201. */
  2202. traptype = TRAP_TYPE_PRIO;
  2203. if (restrict_mask & RES_LPTRAP)
  2204. traptype = TRAP_TYPE_NONPRIO;
  2205. /*
  2206. * Call ctlsettrap() to do the work. Return
  2207. * an error if it can't assign the trap.
  2208. */
  2209. if (!ctlsettrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype,
  2210. (int)res_version))
  2211. ctl_error(CERR_NORESOURCE);
  2212. ctl_flushpkt(0);
  2213. }
  2214. /*
  2215. * unset_trap - unset a trap in response to a control message
  2216. */
  2217. static void
  2218. unset_trap(
  2219. struct recvbuf *rbufp,
  2220. int restrict_mask
  2221. )
  2222. {
  2223. int traptype;
  2224. /*
  2225. * We don't prevent anyone from removing his own trap unless the
  2226. * trap is configured. Note we also must be aware of the
  2227. * possibility that restriction flags were changed since this
  2228. * guy last set his trap. Set the trap type based on this.
  2229. */
  2230. traptype = TRAP_TYPE_PRIO;
  2231. if (restrict_mask & RES_LPTRAP)
  2232. traptype = TRAP_TYPE_NONPRIO;
  2233. /*
  2234. * Call ctlclrtrap() to clear this out.
  2235. */
  2236. if (!ctlclrtrap(&rbufp->recv_srcadr, rbufp->dstadr, traptype))
  2237. ctl_error(CERR_BADASSOC);
  2238. ctl_flushpkt(0);
  2239. }
  2240. /*
  2241. * ctlsettrap - called to set a trap
  2242. */
  2243. int
  2244. ctlsettrap(
  2245. struct sockaddr_storage *raddr,
  2246. struct interface *linter,
  2247. int traptype,
  2248. int version
  2249. )
  2250. {
  2251. register struct ctl_trap *tp;
  2252. register struct ctl_trap *tptouse;
  2253. /*
  2254. * See if we can find this trap. If so, we only need update
  2255. * the flags and the time.
  2256. */
  2257. if ((tp = ctlfindtrap(raddr, linter)) != NULL) {
  2258. switch (traptype) {
  2259. case TRAP_TYPE_CONFIG:
  2260. tp->tr_flags = TRAP_INUSE|TRAP_CONFIGURED;
  2261. break;
  2262. case TRAP_TYPE_PRIO:
  2263. if (tp->tr_flags & TRAP_CONFIGURED)
  2264. return (1); /* don't change anything */
  2265. tp->tr_flags = TRAP_INUSE;
  2266. break;
  2267. case TRAP_TYPE_NONPRIO:
  2268. if (tp->tr_flags & TRAP_CONFIGURED)
  2269. return (1); /* don't change anything */
  2270. tp->tr_flags = TRAP_INUSE|TRAP_NONPRIO;
  2271. break;
  2272. }
  2273. tp->tr_settime = current_time;
  2274. tp->tr_resets++;
  2275. return (1);
  2276. }
  2277. /*
  2278. * First we heard of this guy. Try to find a trap structure
  2279. * for him to use, clearing out lesser priority guys if we
  2280. * have to. Clear out anyone who's expired while we're at it.
  2281. */
  2282. tptouse = NULL;
  2283. for (tp = ctl_trap; tp < &ctl_trap[CTL_MAXTRAPS]; tp++) {
  2284. if ((tp->tr_flags & TRAP_INUSE) &&
  2285. !(tp->tr_flags & TRAP_CONFIGURED) &&
  2286. ((tp->tr_settime + CTL_TRAPTIME) > current_time)) {
  2287. tp->tr_flags = 0;
  2288. num_ctl_traps--;
  2289. }
  2290. if (!(tp->tr_flags & TRAP_INUSE)) {
  2291. tptouse = tp;
  2292. } else if (!(tp->tr_flags & TRAP_CONFIGURED)) {
  2293. switch (traptype) {
  2294. case TRAP_TYPE_CONFIG:
  2295. if (tptouse == NULL) {
  2296. tptouse = tp;
  2297. break;
  2298. }
  2299. if (tptouse->tr_flags & TRAP_NONPRIO &&
  2300. !(tp->tr_flags & TRAP_NONPRIO))
  2301. break;
  2302. if (!(tptouse->tr_flags & TRAP_NONPRIO)
  2303. && tp->tr_flags & TRAP_NONPRIO) {
  2304. tptouse = tp;
  2305. break;
  2306. }
  2307. if (tptouse->tr_origtime <
  2308. tp->tr_origtime)
  2309. tptouse = tp;
  2310. break;
  2311. case TRAP_TYPE_PRIO:
  2312. if (tp->tr_flags & TRAP_NONPRIO) {
  2313. if (tptouse == NULL ||
  2314. (tptouse->tr_flags &
  2315. TRAP_INUSE &&
  2316. tptouse->tr_origtime <
  2317. tp->tr_origtime))
  2318. tptouse = tp;
  2319. }
  2320. break;
  2321. case TRAP_TYPE_NONPRIO:
  2322. break;
  2323. }
  2324. }
  2325. }
  2326. /*
  2327. * If we don't have room for him return an error.
  2328. */
  2329. if (tptouse == NULL)
  2330. return (0);
  2331. /*
  2332. * Set up this structure for him.
  2333. */
  2334. tptouse->tr_settime = tptouse->tr_origtime = current_time;
  2335. tptouse->tr_count = tptouse->tr_resets = 0;
  2336. tptouse->tr_sequence = 1;
  2337. tptouse->tr_addr = *raddr;
  2338. tptouse->tr_localaddr = linter;
  2339. tptouse->tr_version = (u_char) version;
  2340. tptouse->tr_flags = TRAP_INUSE;
  2341. if (traptype == TRAP_TYPE_CONFIG)
  2342. tptouse->tr_flags |= TRAP_CONFIGURED;
  2343. else if (traptype == TRAP_TYPE_NONPRIO)
  2344. tptouse->tr_flags |= TRAP_NONPRIO;
  2345. num_ctl_traps++;
  2346. return (1);
  2347. }
  2348. /*
  2349. * ctlclrtrap - called to clear a trap
  2350. */
  2351. int
  2352. ctlclrtrap(
  2353. struct sockaddr_storage *raddr,
  2354. struct interface *linter,
  2355. int traptype
  2356. )
  2357. {
  2358. register struct ctl_trap *tp;
  2359. if ((tp = ctlfindtrap(raddr, linter)) == NULL)
  2360. return (0);
  2361. if (tp->tr_flags & TRAP_CONFIGURED
  2362. && traptype != TRAP_TYPE_CONFIG)
  2363. return (0);
  2364. tp->tr_flags = 0;
  2365. num_ctl_traps--;
  2366. return (1);
  2367. }
  2368. /*
  2369. * ctlfindtrap - find a trap given the remote and local addresses
  2370. */
  2371. static struct ctl_trap *
  2372. ctlfindtrap(
  2373. struct sockaddr_storage *raddr,
  2374. struct interface *linter
  2375. )
  2376. {
  2377. register struct ctl_trap *tp;
  2378. for (tp = ctl_trap; tp < &ctl_trap[CTL_MAXTRAPS]; tp++) {
  2379. if ((tp->tr_flags & TRAP_INUSE)
  2380. && (NSRCPORT(raddr) == NSRCPORT(&tp->tr_addr))
  2381. && SOCKCMP(raddr, &tp->tr_addr)
  2382. && (linter == tp->tr_localaddr) )
  2383. return (tp);
  2384. }
  2385. return (struct ctl_trap *)NULL;
  2386. }
  2387. /*
  2388. * report_event - report an event to the trappers
  2389. */
  2390. void
  2391. report_event(
  2392. int err,
  2393. struct peer *peer
  2394. )
  2395. {
  2396. register int i;
  2397. /*
  2398. * Record error code in proper spots, but have mercy on the
  2399. * log file.
  2400. */
  2401. if (!(err & (PEER_EVENT | CRPT_EVENT))) {
  2402. if (ctl_sys_num_events < CTL_SYS_MAXEVENTS)
  2403. ctl_sys_num_events++;
  2404. if (ctl_sys_last_event != (u_char)err) {
  2405. NLOG(NLOG_SYSEVENT)
  2406. msyslog(LOG_INFO, "system event '%s' (0x%02x) status '%s' (0x%02x)",
  2407. eventstr(err), err,
  2408. sysstatstr(ctlsysstatus()), ctlsysstatus());
  2409. #ifdef DEBUG
  2410. if (debug)
  2411. printf("report_event: system event '%s' (0x%02x) status '%s' (0x%02x)\n",
  2412. eventstr(err), err,
  2413. sysstatstr(ctlsysstatus()),
  2414. ctlsysstatus());
  2415. #endif
  2416. ctl_sys_last_event = (u_char)err;
  2417. }
  2418. } else if (peer != 0) {
  2419. char *src;
  2420. #ifdef REFCLOCK
  2421. if (ISREFCLOCKADR(&peer->srcadr))
  2422. src = refnumtoa(&peer->srcadr);
  2423. else
  2424. #endif
  2425. src = stoa(&peer->srcadr);
  2426. peer->last_event = (u_char)(err & ~PEER_EVENT);
  2427. if (peer->num_events < CTL_PEER_MAXEVENTS)
  2428. peer->num_events++;
  2429. NLOG(NLOG_PEEREVENT)
  2430. msyslog(LOG_INFO, "peer %s event '%s' (0x%02x) status '%s' (0x%02x)",
  2431. src, eventstr(err), err,
  2432. peerstatstr(ctlpeerstatus(peer)),
  2433. ctlpeerstatus(peer));
  2434. #ifdef DEBUG
  2435. if (debug)
  2436. printf( "peer %s event '%s' (0x%02x) status '%s' (0x%02x)\n",
  2437. src, eventstr(err), err,
  2438. peerstatstr(ctlpeerstatus(peer)),
  2439. ctlpeerstatus(peer));
  2440. #endif
  2441. } else {
  2442. msyslog(LOG_ERR,
  2443. "report_event: err '%s' (0x%02x), no peer",
  2444. eventstr(err), err);
  2445. #ifdef DEBUG
  2446. printf(
  2447. "report_event: peer event '%s' (0x%02x), no peer\n",
  2448. eventstr(err), err);
  2449. #endif
  2450. return;
  2451. }
  2452. /*
  2453. * If no trappers, return.
  2454. */
  2455. if (num_ctl_traps <= 0)
  2456. return;
  2457. /*
  2458. * Set up the outgoing packet variables
  2459. */
  2460. res_opcode = CTL_OP_ASYNCMSG;
  2461. res_offset = 0;
  2462. res_async = 1;
  2463. res_authenticate = 0;
  2464. datapt = rpkt.data;
  2465. dataend = &(rpkt.data[CTL_MAX_DATA_LEN]);
  2466. if (!(err & PEER_EVENT)) {
  2467. rpkt.associd = 0;
  2468. rpkt.status = htons(ctlsysstatus());
  2469. /*
  2470. * For now, put everything we know about system
  2471. * variables. Don't send crypto strings.
  2472. */
  2473. for (i = 1; i <= CS_MAXCODE; i++) {
  2474. #ifdef OPENSSL
  2475. if (i > CS_VARLIST)
  2476. continue;
  2477. #endif /* OPENSSL */
  2478. ctl_putsys(i);
  2479. }
  2480. #ifdef REFCLOCK
  2481. /*
  2482. * for clock exception events: add clock variables to
  2483. * reflect info on exception
  2484. */
  2485. if (err == EVNT_CLOCKEXCPT) {
  2486. struct refclockstat clock_stat;
  2487. struct ctl_var *kv;
  2488. clock_stat.kv_list = (struct ctl_var *)0;
  2489. refclock_control(&peer->srcadr,
  2490. (struct refclockstat *)0, &clock_stat);
  2491. ctl_puthex("refclockstatus",
  2492. ctlclkstatus(&clock_stat));
  2493. for (i = 1; i <= CC_MAXCODE; i++)
  2494. ctl_putclock(i, &clock_stat, 0);
  2495. for (kv = clock_stat.kv_list; kv &&
  2496. !(kv->flags & EOV); kv++)
  2497. if (kv->flags & DEF)
  2498. ctl_putdata(kv->text,
  2499. strlen(kv->text), 0);
  2500. free_varlist(clock_stat.kv_list);
  2501. }
  2502. #endif /* REFCLOCK */
  2503. } else {
  2504. rpkt.associd = htons(peer->associd);
  2505. rpkt.status = htons(ctlpeerstatus(peer));
  2506. /*
  2507. * Dump it all. Later, maybe less.
  2508. */
  2509. for (i = 1; i <= CP_MAXCODE; i++) {
  2510. #ifdef OPENSSL
  2511. if (i > CP_VARLIST)
  2512. continue;
  2513. #endif /* OPENSSL */
  2514. ctl_putpeer(i, peer);
  2515. }
  2516. #ifdef REFCLOCK
  2517. /*
  2518. * for clock exception events: add clock variables to
  2519. * reflect info on exception
  2520. */
  2521. if (err == EVNT_PEERCLOCK) {
  2522. struct refclockstat clock_stat;
  2523. struct ctl_var *kv;
  2524. clock_stat.kv_list = (struct ctl_var *)0;
  2525. refclock_control(&peer->srcadr,
  2526. (struct refclockstat *)0, &clock_stat);
  2527. ctl_puthex("refclockstatus",
  2528. ctlclkstatus(&clock_stat));
  2529. for (i = 1; i <= CC_MAXCODE; i++)
  2530. ctl_putclock(i, &clock_stat, 0);
  2531. for (kv = clock_stat.kv_list; kv &&
  2532. !(kv->flags & EOV); kv++)
  2533. if (kv->flags & DEF)
  2534. ctl_putdata(kv->text,
  2535. strlen(kv->text), 0);
  2536. free_varlist(clock_stat.kv_list);
  2537. }
  2538. #endif /* REFCLOCK */
  2539. }
  2540. /*
  2541. * We're done, return.
  2542. */
  2543. ctl_flushpkt(0);
  2544. }
  2545. /*
  2546. * ctl_clr_stats - clear stat counters
  2547. */
  2548. void
  2549. ctl_clr_stats(void)
  2550. {
  2551. ctltimereset = current_time;
  2552. numctlreq = 0;
  2553. numctlbadpkts = 0;
  2554. numctlresponses = 0;
  2555. numctlfrags = 0;
  2556. numctlerrors = 0;
  2557. numctlfrags = 0;
  2558. numctltooshort = 0;
  2559. numctlinputresp = 0;
  2560. numctlinputfrag = 0;
  2561. numctlinputerr = 0;
  2562. numctlbadoffset = 0;
  2563. numctlbadversion = 0;
  2564. numctldatatooshort = 0;
  2565. numctlbadop = 0;
  2566. numasyncmsgs = 0;
  2567. }
  2568. static u_long
  2569. count_var(
  2570. struct ctl_var *k
  2571. )
  2572. {
  2573. register u_long c;
  2574. if (!k)
  2575. return (0);
  2576. c = 0;
  2577. while (!(k++->flags & EOV))
  2578. c++;
  2579. return (c);
  2580. }
  2581. char *
  2582. add_var(
  2583. struct ctl_var **kv,
  2584. u_long size,
  2585. u_short def
  2586. )
  2587. {
  2588. register u_long c;
  2589. register struct ctl_var *k;
  2590. c = count_var(*kv);
  2591. k = *kv;
  2592. *kv = (struct ctl_var *)emalloc((c+2)*sizeof(struct ctl_var));
  2593. if (k) {
  2594. memmove((char *)*kv, (char *)k,
  2595. sizeof(struct ctl_var)*c);
  2596. free((char *)k);
  2597. }
  2598. (*kv)[c].code = (u_short) c;
  2599. (*kv)[c].text = (char *)emalloc(size);
  2600. (*kv)[c].flags = def;
  2601. (*kv)[c+1].code = 0;
  2602. (*kv)[c+1].text = (char *)0;
  2603. (*kv)[c+1].flags = EOV;
  2604. return (char *)(*kv)[c].text;
  2605. }
  2606. void
  2607. set_var(
  2608. struct ctl_var **kv,
  2609. const char *data,
  2610. u_long size,
  2611. u_short def
  2612. )
  2613. {
  2614. register struct ctl_var *k;
  2615. register const char *s;
  2616. register const char *t;
  2617. char *td;
  2618. if (!data || !size)
  2619. return;
  2620. k = *kv;
  2621. if (k != NULL) {
  2622. while (!(k->flags & EOV)) {
  2623. s = data;
  2624. t = k->text;
  2625. if (t) {
  2626. while (*t != '=' && *s - *t == 0) {
  2627. s++;
  2628. t++;
  2629. }
  2630. if (*s == *t && ((*t == '=') || !*t)) {
  2631. free((void *)k->text);
  2632. td = (char *)emalloc(size);
  2633. memmove(td, data, size);
  2634. k->text =td;
  2635. k->flags = def;
  2636. return;
  2637. }
  2638. } else {
  2639. td = (char *)emalloc(size);
  2640. memmove(td, data, size);
  2641. k->text = td;
  2642. k->flags = def;
  2643. return;
  2644. }
  2645. k++;
  2646. }
  2647. }
  2648. td = add_var(kv, size, def);
  2649. memmove(td, data, size);
  2650. }
  2651. void
  2652. set_sys_var(
  2653. const char *data,
  2654. u_long size,
  2655. u_short def
  2656. )
  2657. {
  2658. set_var(&ext_sys_var, data, size, def);
  2659. }
  2660. void
  2661. free_varlist(
  2662. struct ctl_var *kv
  2663. )
  2664. {
  2665. struct ctl_var *k;
  2666. if (kv) {
  2667. for (k = kv; !(k->flags & EOV); k++)
  2668. free((void *)k->text);
  2669. free((void *)kv);
  2670. }
  2671. }