libntpq.c revision 1.1.1.7 1 1.1.1.7 christos /* $NetBSD: libntpq.c,v 1.1.1.7 2016/01/08 21:21:27 christos Exp $ */
2 1.1.1.7 christos
3 1.1 kardel /*****************************************************************************
4 1.1 kardel *
5 1.1 kardel * libntpq.c
6 1.1 kardel *
7 1.1 kardel * This is the wrapper library for ntpq, the NTP query utility.
8 1.1 kardel * This library reuses the sourcecode from ntpq and exports a number
9 1.1 kardel * of useful functions in a library that can be linked against applications
10 1.1 kardel * that need to query the status of a running ntpd. The whole
11 1.1 kardel * communcation is based on mode 6 packets.
12 1.1 kardel *
13 1.1 kardel ****************************************************************************/
14 1.1.1.2 kardel #define LIBNTPQ_C
15 1.1 kardel #define NO_MAIN_ALLOWED 1
16 1.1 kardel /* #define BUILD_AS_LIB Already provided by the Makefile */
17 1.1 kardel
18 1.1 kardel #include "ntpq.c"
19 1.1 kardel #include "libntpq.h"
20 1.1 kardel
21 1.1 kardel /* Function Prototypes */
22 1.1 kardel
23 1.1 kardel
24 1.1 kardel const char *Version = "libntpq 0.3beta";
25 1.1 kardel
26 1.1 kardel /* global variables used for holding snapshots of data */
27 1.1.1.2 kardel char peervars[NTPQ_BUFLEN];
28 1.1.1.2 kardel int peervarlen = 0;
29 1.1.1.2 kardel associd_t peervar_assoc = 0;
30 1.1.1.2 kardel char clockvars[NTPQ_BUFLEN];
31 1.1.1.2 kardel int clockvarlen = 0;
32 1.1.1.2 kardel int clockvar_assoc = 0;
33 1.1.1.2 kardel char sysvars[NTPQ_BUFLEN];
34 1.1.1.2 kardel int sysvarlen = 0;
35 1.1.1.2 kardel char *ntpq_resultbuffer[NTPQ_BUFLEN];
36 1.1.1.2 kardel unsigned short ntpq_associations[MAXASSOC];
37 1.1 kardel struct ntpq_varlist ntpq_varlist[MAXLIST];
38 1.1 kardel
39 1.1 kardel /*****************************************************************************
40 1.1 kardel *
41 1.1 kardel * ntpq_stripquotes
42 1.1 kardel *
43 1.1 kardel * Parses a given character buffer srcbuf and removes all quoted
44 1.1 kardel * characters. The resulting string is copied to the specified
45 1.1 kardel * resultbuf character buffer. E.g. \" will be translated into "
46 1.1 kardel *
47 1.1 kardel ****************************************************************************
48 1.1 kardel * Parameters:
49 1.1 kardel * resultbuf char* The resulting string without quoted
50 1.1 kardel * characters
51 1.1 kardel * srcbuf char* The buffer holding the original string
52 1.1 kardel * datalen int The number of bytes stored in srcbuf
53 1.1 kardel * maxlen int Max. number of bytes for resultbuf
54 1.1 kardel *
55 1.1 kardel * Returns:
56 1.1 kardel * int number of chars that have been copied to
57 1.1 kardel * resultbuf
58 1.1 kardel ****************************************************************************/
59 1.1 kardel
60 1.1 kardel int ntpq_stripquotes ( char *resultbuf, char *srcbuf, int datalen, int maxlen )
61 1.1 kardel {
62 1.1 kardel char* tmpbuf = srcbuf;
63 1.1 kardel
64 1.1 kardel while ( *tmpbuf != 0 )
65 1.1 kardel {
66 1.1 kardel if ( *tmpbuf == '\"' )
67 1.1 kardel {
68 1.1 kardel tmpbuf++;
69 1.1 kardel continue;
70 1.1 kardel }
71 1.1 kardel
72 1.1 kardel if ( *tmpbuf == '\\' )
73 1.1 kardel {
74 1.1 kardel tmpbuf++;
75 1.1 kardel switch ( *tmpbuf )
76 1.1 kardel {
77 1.1 kardel /* ignore if end of string */
78 1.1 kardel case 0:
79 1.1 kardel continue;
80 1.1 kardel /* skip and do not copy */
81 1.1 kardel case '\"': /* quotes */
82 1.1 kardel case 'n': /*newline*/
83 1.1 kardel case 'r': /*carriage return*/
84 1.1 kardel case 'g': /*bell*/
85 1.1 kardel case 't': /*tab*/
86 1.1 kardel tmpbuf++;
87 1.1 kardel continue;
88 1.1 kardel }
89 1.1 kardel }
90 1.1 kardel
91 1.1 kardel *resultbuf++ = *tmpbuf++;
92 1.1 kardel
93 1.1 kardel }
94 1.1 kardel
95 1.1 kardel *resultbuf = 0;
96 1.1 kardel return strlen(resultbuf);
97 1.1 kardel }
98 1.1 kardel
99 1.1 kardel
100 1.1 kardel /*****************************************************************************
101 1.1 kardel *
102 1.1 kardel * ntpq_getvar
103 1.1 kardel *
104 1.1 kardel * This function parses a given buffer for a variable/value pair and
105 1.1 kardel * copies the value of the requested variable into the specified
106 1.1 kardel * varvalue buffer.
107 1.1 kardel *
108 1.1 kardel * It returns the number of bytes copied or zero for an empty result
109 1.1 kardel * (=no matching variable found or empty value)
110 1.1 kardel *
111 1.1 kardel ****************************************************************************
112 1.1 kardel * Parameters:
113 1.1 kardel * resultbuf char* The resulting string without quoted
114 1.1 kardel * characters
115 1.1.1.2 kardel * datalen size_t The number of bytes stored in
116 1.1 kardel * resultbuf
117 1.1 kardel * varname char* Name of the required variable
118 1.1 kardel * varvalue char* Where the value of the variable should
119 1.1 kardel * be stored
120 1.1.1.2 kardel * maxlen size_t Max. number of bytes for varvalue
121 1.1 kardel *
122 1.1 kardel * Returns:
123 1.1.1.2 kardel * size_t number of chars that have been copied to
124 1.1 kardel * varvalue
125 1.1 kardel ****************************************************************************/
126 1.1 kardel
127 1.1.1.2 kardel size_t
128 1.1.1.2 kardel ntpq_getvar(
129 1.1.1.2 kardel const char * resultbuf,
130 1.1.1.2 kardel size_t datalen,
131 1.1.1.2 kardel const char * varname,
132 1.1.1.2 kardel char * varvalue,
133 1.1.1.2 kardel size_t maxlen)
134 1.1.1.2 kardel {
135 1.1.1.2 kardel char * name;
136 1.1.1.2 kardel char * value;
137 1.1.1.6 christos size_t idatalen;
138 1.1.1.2 kardel
139 1.1.1.2 kardel value = NULL;
140 1.1.1.2 kardel idatalen = (int)datalen;
141 1.1.1.2 kardel
142 1.1.1.2 kardel while (nextvar(&idatalen, &resultbuf, &name, &value)) {
143 1.1.1.2 kardel if (strcmp(varname, name) == 0) {
144 1.1.1.2 kardel ntpq_stripquotes(varvalue, value, strlen(value), maxlen);
145 1.1 kardel
146 1.1 kardel return strlen(varvalue);
147 1.1.1.2 kardel }
148 1.1.1.2 kardel }
149 1.1 kardel
150 1.1.1.2 kardel return 0;
151 1.1 kardel }
152 1.1 kardel
153 1.1 kardel
154 1.1 kardel /*****************************************************************************
155 1.1 kardel *
156 1.1 kardel * ntpq_queryhost
157 1.1 kardel *
158 1.1 kardel * Sends a mode 6 query packet to the current open host (see
159 1.1 kardel * ntpq_openhost) and stores the requested variable set in the specified
160 1.1 kardel * character buffer.
161 1.1 kardel * It returns the number of bytes read or zero for an empty result
162 1.1 kardel * (=no answer or empty value)
163 1.1 kardel *
164 1.1 kardel ****************************************************************************
165 1.1 kardel * Parameters:
166 1.1 kardel * VARSET u_short Which variable set should be
167 1.1 kardel * read (PEERVARS or CLOCKVARS)
168 1.1 kardel * association int The association ID that should be read
169 1.1 kardel * 0 represents the ntpd instance itself
170 1.1 kardel * resultbuf char* The resulting string without quoted
171 1.1 kardel * characters
172 1.1 kardel * maxlen int Max. number of bytes for varvalue
173 1.1 kardel *
174 1.1 kardel * Returns:
175 1.1 kardel * int number of bytes that have been copied to
176 1.1 kardel * resultbuf
177 1.1 kardel * - OR -
178 1.1 kardel * 0 (zero) if no reply has been received or
179 1.1 kardel * another failure occured
180 1.1 kardel ****************************************************************************/
181 1.1 kardel
182 1.1 kardel int ntpq_queryhost(unsigned short VARSET, unsigned short association, char *resultbuf, int maxlen)
183 1.1 kardel {
184 1.1.1.2 kardel const char *datap;
185 1.1 kardel int res;
186 1.1.1.6 christos size_t dsize;
187 1.1.1.6 christos u_short rstatus;
188 1.1 kardel
189 1.1 kardel if ( numhosts > 0 )
190 1.1 kardel res = doquery(VARSET,association,0,0, (char *)0, &rstatus, &dsize, &datap);
191 1.1 kardel else
192 1.1 kardel return 0;
193 1.1 kardel
194 1.1 kardel if ( ( res != 0) || ( dsize == 0 ) ) /* no data */
195 1.1 kardel return 0;
196 1.1 kardel
197 1.1 kardel if ( dsize > maxlen)
198 1.1 kardel dsize = maxlen;
199 1.1 kardel
200 1.1 kardel
201 1.1 kardel /* fill result resultbuf */
202 1.1 kardel memcpy(resultbuf, datap, dsize);
203 1.1 kardel
204 1.1 kardel return dsize;
205 1.1 kardel }
206 1.1 kardel
207 1.1 kardel
208 1.1 kardel
209 1.1 kardel /*****************************************************************************
210 1.1 kardel *
211 1.1 kardel * ntpq_openhost
212 1.1 kardel *
213 1.1 kardel * Sets up a connection to the ntpd instance of a specified host. Note:
214 1.1 kardel * There is no real "connection" established because NTP solely works
215 1.1 kardel * based on UDP.
216 1.1 kardel *
217 1.1 kardel ****************************************************************************
218 1.1 kardel * Parameters:
219 1.1 kardel * hostname char* Hostname/IP of the host running ntpd
220 1.1.1.3 christos * fam int Address Family (AF_INET, AF_INET6, or 0)
221 1.1 kardel *
222 1.1 kardel * Returns:
223 1.1 kardel * int 1 if the host connection could be set up, i.e.
224 1.1 kardel * name resolution was succesful and/or IP address
225 1.1 kardel * has been validated
226 1.1 kardel * - OR -
227 1.1 kardel * 0 (zero) if a failure occured
228 1.1 kardel ****************************************************************************/
229 1.1 kardel
230 1.1.1.3 christos int
231 1.1.1.3 christos ntpq_openhost(
232 1.1.1.3 christos char *hostname,
233 1.1.1.3 christos int fam
234 1.1.1.3 christos )
235 1.1 kardel {
236 1.1.1.3 christos if ( openhost(hostname, fam) )
237 1.1 kardel {
238 1.1 kardel numhosts = 1;
239 1.1 kardel } else {
240 1.1 kardel numhosts = 0;
241 1.1 kardel }
242 1.1 kardel
243 1.1 kardel return numhosts;
244 1.1 kardel
245 1.1 kardel }
246 1.1 kardel
247 1.1 kardel
248 1.1 kardel /*****************************************************************************
249 1.1 kardel *
250 1.1 kardel * ntpq_closehost
251 1.1 kardel *
252 1.1 kardel * Cleans up a connection by closing the used socket. Should be called
253 1.1 kardel * when no further queries are required for the currently used host.
254 1.1 kardel *
255 1.1 kardel ****************************************************************************
256 1.1 kardel * Parameters:
257 1.1 kardel * - none -
258 1.1 kardel *
259 1.1 kardel * Returns:
260 1.1 kardel * int 0 (zero) if no host has been opened before
261 1.1 kardel * - OR -
262 1.1 kardel * the resultcode from the closesocket function call
263 1.1 kardel ****************************************************************************/
264 1.1 kardel
265 1.1 kardel int ntpq_closehost(void)
266 1.1 kardel {
267 1.1 kardel if ( numhosts )
268 1.1 kardel return closesocket(sockfd);
269 1.1 kardel
270 1.1 kardel return 0;
271 1.1 kardel }
272 1.1 kardel
273 1.1 kardel
274 1.1 kardel /*****************************************************************************
275 1.1 kardel *
276 1.1 kardel * ntpq_read_associations
277 1.1 kardel *
278 1.1 kardel * This function queries the ntp host for its associations and returns the
279 1.1 kardel * number of associations found.
280 1.1 kardel *
281 1.1 kardel * It takes an u_short array as its first parameter, this array holds the
282 1.1 kardel * IDs of the associations,
283 1.1 kardel * the function will not write more entries than specified with the
284 1.1 kardel * max_entries parameter.
285 1.1 kardel *
286 1.1 kardel * However, if more than max_entries associations were found, the return
287 1.1 kardel * value of this function will reflect the real number, even if not all
288 1.1 kardel * associations have been stored in the array.
289 1.1 kardel *
290 1.1 kardel ****************************************************************************
291 1.1 kardel * Parameters:
292 1.1 kardel * resultbuf u_short*Array that should hold the list of
293 1.1 kardel * association IDs
294 1.1 kardel * maxentries int maximum number of association IDs that can
295 1.1 kardel * be stored in resultbuf
296 1.1 kardel *
297 1.1 kardel * Returns:
298 1.1 kardel * int number of association IDs stored in resultbuf
299 1.1 kardel * - OR -
300 1.1 kardel * 0 (zero) if a failure occured or no association has
301 1.1 kardel * been returned.
302 1.1 kardel ****************************************************************************/
303 1.1 kardel
304 1.1 kardel int ntpq_read_associations ( u_short resultbuf[], int max_entries )
305 1.1 kardel {
306 1.1 kardel int i = 0;
307 1.1 kardel
308 1.1 kardel if (ntpq_dogetassoc()) {
309 1.1 kardel
310 1.1 kardel if(numassoc < max_entries)
311 1.1 kardel max_entries = numassoc;
312 1.1 kardel
313 1.1 kardel for (i=0;i<max_entries;i++)
314 1.1 kardel resultbuf[i] = assoc_cache[i].assid;
315 1.1 kardel
316 1.1 kardel return numassoc;
317 1.1 kardel }
318 1.1 kardel
319 1.1 kardel return 0;
320 1.1 kardel }
321 1.1 kardel
322 1.1 kardel
323 1.1 kardel
324 1.1 kardel
325 1.1 kardel /*****************************************************************************
326 1.1 kardel *
327 1.1 kardel * ntpq_get_assocs
328 1.1 kardel *
329 1.1 kardel * This function reads the associations of a previously selected (with
330 1.1 kardel * ntpq_openhost) NTP host into its own (global) array and returns the
331 1.1 kardel * number of associations found.
332 1.1 kardel *
333 1.1 kardel * The obtained association IDs can be read by using the ntpq_get_assoc_id
334 1.1 kardel * function.
335 1.1 kardel *
336 1.1 kardel ****************************************************************************
337 1.1 kardel * Parameters:
338 1.1 kardel * - none -
339 1.1 kardel *
340 1.1 kardel * Returns:
341 1.1 kardel * int number of association IDs stored in resultbuf
342 1.1 kardel * - OR -
343 1.1 kardel * 0 (zero) if a failure occured or no association has
344 1.1 kardel * been returned.
345 1.1 kardel ****************************************************************************/
346 1.1 kardel
347 1.1 kardel int ntpq_get_assocs ( void )
348 1.1 kardel {
349 1.1 kardel return ntpq_read_associations( ntpq_associations, MAXASSOC );
350 1.1 kardel }
351 1.1 kardel
352 1.1 kardel
353 1.1 kardel /*****************************************************************************
354 1.1 kardel *
355 1.1 kardel * ntpq_get_assoc_number
356 1.1 kardel *
357 1.1 kardel * This function returns for a given Association ID the association number
358 1.1 kardel * in the internal association array, which is filled by the ntpq_get_assocs
359 1.1 kardel * function.
360 1.1 kardel *
361 1.1 kardel ****************************************************************************
362 1.1 kardel * Parameters:
363 1.1 kardel * associd int requested associaton ID
364 1.1 kardel *
365 1.1 kardel * Returns:
366 1.1 kardel * int the number of the association array element that is
367 1.1 kardel * representing the given association ID
368 1.1 kardel * - OR -
369 1.1 kardel * -1 if a failure occured or no matching association
370 1.1 kardel * ID has been found
371 1.1 kardel ****************************************************************************/
372 1.1 kardel
373 1.1.1.2 kardel int ntpq_get_assoc_number ( associd_t associd )
374 1.1 kardel {
375 1.1.1.2 kardel int i;
376 1.1 kardel
377 1.1.1.2 kardel for (i=0;i<numassoc;i++) {
378 1.1.1.2 kardel if (assoc_cache[i].assid == associd)
379 1.1.1.2 kardel return i;
380 1.1.1.2 kardel }
381 1.1 kardel
382 1.1.1.2 kardel return -1;
383 1.1 kardel
384 1.1 kardel }
385 1.1 kardel
386 1.1 kardel
387 1.1 kardel /*****************************************************************************
388 1.1 kardel *
389 1.1 kardel * ntpq_read_assoc_peervars
390 1.1 kardel *
391 1.1 kardel * This function reads the peervars variable-set of a specified association
392 1.1 kardel * from a NTP host and writes it to the result buffer specified, honoring
393 1.1 kardel * the maxsize limit.
394 1.1 kardel *
395 1.1 kardel * It returns the number of bytes written or 0 when the variable-set is
396 1.1 kardel * empty or failed to read.
397 1.1 kardel *
398 1.1 kardel ****************************************************************************
399 1.1 kardel * Parameters:
400 1.1 kardel * associd int requested associaton ID
401 1.1 kardel * resultbuf char* character buffer where the variable set
402 1.1 kardel * should be stored
403 1.1 kardel * maxsize int the maximum number of bytes that can be
404 1.1 kardel * written to resultbuf
405 1.1 kardel *
406 1.1 kardel * Returns:
407 1.1 kardel * int number of chars that have been copied to
408 1.1 kardel * resultbuf
409 1.1 kardel * - OR -
410 1.1 kardel * 0 (zero) if an error occured
411 1.1 kardel ****************************************************************************/
412 1.1 kardel
413 1.1.1.2 kardel int
414 1.1.1.2 kardel ntpq_read_assoc_peervars(
415 1.1.1.2 kardel associd_t associd,
416 1.1.1.2 kardel char * resultbuf,
417 1.1.1.2 kardel int maxsize
418 1.1.1.2 kardel )
419 1.1.1.2 kardel {
420 1.1.1.2 kardel const char * datap;
421 1.1.1.2 kardel int res;
422 1.1.1.6 christos size_t dsize;
423 1.1.1.2 kardel u_short rstatus;
424 1.1.1.2 kardel
425 1.1.1.2 kardel res = doquery(CTL_OP_READVAR, associd, 0, 0, NULL, &rstatus,
426 1.1.1.2 kardel &dsize, &datap);
427 1.1.1.2 kardel if (res != 0)
428 1.1.1.2 kardel return 0;
429 1.1.1.2 kardel if (dsize <= 0) {
430 1.1.1.2 kardel if (numhosts > 1)
431 1.1.1.2 kardel fprintf(stderr, "server=%s ", currenthost);
432 1.1.1.2 kardel fprintf(stderr,
433 1.1.1.2 kardel "***No information returned for association %d\n",
434 1.1.1.2 kardel associd);
435 1.1 kardel
436 1.1.1.2 kardel return 0;
437 1.1.1.2 kardel }
438 1.1.1.2 kardel if (dsize > maxsize)
439 1.1.1.2 kardel dsize = maxsize;
440 1.1.1.2 kardel memcpy(resultbuf, datap, dsize);
441 1.1 kardel
442 1.1.1.2 kardel return dsize;
443 1.1 kardel }
444 1.1 kardel
445 1.1 kardel
446 1.1 kardel
447 1.1 kardel
448 1.1 kardel /*****************************************************************************
449 1.1 kardel *
450 1.1 kardel * ntpq_read_sysvars
451 1.1 kardel *
452 1.1 kardel * This function reads the sysvars variable-set from a NTP host and writes it
453 1.1 kardel * to the result buffer specified, honoring the maxsize limit.
454 1.1 kardel *
455 1.1 kardel * It returns the number of bytes written or 0 when the variable-set is empty
456 1.1 kardel * or could not be read.
457 1.1 kardel *
458 1.1 kardel ****************************************************************************
459 1.1 kardel * Parameters:
460 1.1 kardel * resultbuf char* character buffer where the variable set
461 1.1 kardel * should be stored
462 1.1 kardel * maxsize int the maximum number of bytes that can be
463 1.1 kardel * written to resultbuf
464 1.1 kardel *
465 1.1 kardel * Returns:
466 1.1 kardel * int number of chars that have been copied to
467 1.1 kardel * resultbuf
468 1.1 kardel * - OR -
469 1.1 kardel * 0 (zero) if an error occured
470 1.1 kardel ****************************************************************************/
471 1.1.1.2 kardel size_t
472 1.1.1.2 kardel ntpq_read_sysvars(
473 1.1.1.2 kardel char * resultbuf,
474 1.1.1.2 kardel size_t maxsize
475 1.1.1.2 kardel )
476 1.1.1.2 kardel {
477 1.1.1.2 kardel const char * datap;
478 1.1.1.2 kardel int res;
479 1.1.1.2 kardel size_t dsize;
480 1.1.1.2 kardel u_short rstatus;
481 1.1 kardel
482 1.1.1.2 kardel res = doquery(CTL_OP_READVAR, 0, 0, 0, NULL, &rstatus,
483 1.1.1.6 christos &dsize, &datap);
484 1.1 kardel
485 1.1.1.2 kardel if (res != 0)
486 1.1.1.2 kardel return 0;
487 1.1.1.2 kardel
488 1.1.1.6 christos if (dsize == 0) {
489 1.1.1.2 kardel if (numhosts > 1)
490 1.1.1.2 kardel fprintf(stderr, "server=%s ", currenthost);
491 1.1.1.2 kardel fprintf(stderr, "***No sysvar information returned\n");
492 1.1 kardel
493 1.1.1.2 kardel return 0;
494 1.1.1.2 kardel } else {
495 1.1.1.2 kardel dsize = min(dsize, maxsize);
496 1.1.1.2 kardel memcpy(resultbuf, datap, dsize);
497 1.1.1.2 kardel }
498 1.1 kardel
499 1.1.1.2 kardel return dsize;
500 1.1 kardel }
501 1.1 kardel
502 1.1 kardel
503 1.1 kardel /*****************************************************************************
504 1.1 kardel * ntpq_get_assoc_allvars
505 1.1 kardel *
506 1.1 kardel * With this function all association variables for the specified association
507 1.1 kardel * ID can be requested from a NTP host. They are stored internally and can be
508 1.1 kardel * read by using the ntpq_get_peervar or ntpq_get_clockvar functions.
509 1.1 kardel *
510 1.1 kardel * Basically this is only a combination of the ntpq_get_assoc_peervars and
511 1.1 kardel * ntpq_get_assoc_clockvars functions.
512 1.1 kardel *
513 1.1 kardel * It returns 1 if both variable-sets (peervars and clockvars) were
514 1.1 kardel * received successfully. If one variable-set or both of them weren't
515 1.1 kardel * received,
516 1.1 kardel *
517 1.1 kardel ****************************************************************************
518 1.1 kardel * Parameters:
519 1.1 kardel * associd int requested associaton ID
520 1.1 kardel *
521 1.1 kardel * Returns:
522 1.1 kardel * int nonzero if at least one variable set could be read
523 1.1 kardel * - OR -
524 1.1 kardel * 0 (zero) if an error occured and both variable sets
525 1.1 kardel * could not be read
526 1.1 kardel ****************************************************************************/
527 1.1.1.2 kardel int ntpq_get_assoc_allvars( associd_t associd )
528 1.1 kardel {
529 1.1.1.2 kardel return ntpq_get_assoc_peervars ( associd ) &
530 1.1.1.2 kardel ntpq_get_assoc_clockvars( associd );
531 1.1 kardel }
532 1.1 kardel
533 1.1 kardel
534 1.1 kardel
535 1.1 kardel
536 1.1 kardel /*****************************************************************************
537 1.1 kardel *
538 1.1 kardel * ntpq_get_sysvars
539 1.1 kardel *
540 1.1 kardel * The system variables of a NTP host can be requested by using this function
541 1.1 kardel * and afterwards using ntpq_get_sysvar to read the single variable values.
542 1.1 kardel *
543 1.1 kardel ****************************************************************************
544 1.1 kardel * Parameters:
545 1.1 kardel * - none -
546 1.1 kardel *
547 1.1 kardel * Returns:
548 1.1 kardel * int nonzero if the variable set could be read
549 1.1 kardel * - OR -
550 1.1 kardel * 0 (zero) if an error occured and the sysvars
551 1.1 kardel * could not be read
552 1.1 kardel ****************************************************************************/
553 1.1.1.2 kardel int
554 1.1.1.2 kardel ntpq_get_sysvars(void)
555 1.1 kardel {
556 1.1.1.2 kardel sysvarlen = ntpq_read_sysvars(sysvars, sizeof(sysvars));
557 1.1.1.2 kardel if (sysvarlen <= 0)
558 1.1.1.2 kardel return 0;
559 1.1.1.2 kardel else
560 1.1.1.2 kardel return 1;
561 1.1 kardel }
562 1.1 kardel
563 1.1 kardel
564 1.1 kardel /*****************************************************************************
565 1.1 kardel *
566 1.1 kardel * ntp_get_peervar
567 1.1 kardel *
568 1.1 kardel * This function uses the variable-set which was read by using
569 1.1 kardel * ntp_get_peervars and searches for a variable specified with varname. If
570 1.1 kardel * such a variable exists, it writes its value into
571 1.1 kardel * varvalue (maxlen specifies the size of this target buffer).
572 1.1 kardel *
573 1.1 kardel ****************************************************************************
574 1.1 kardel * Parameters:
575 1.1 kardel * varname char* requested variable name
576 1.1 kardel * varvalue char* the buffer where the value should go into
577 1.1 kardel * maxlen int maximum number of bytes that can be copied to
578 1.1 kardel * varvalue
579 1.1 kardel *
580 1.1 kardel * Returns:
581 1.1 kardel * int number of bytes copied to varvalue
582 1.1 kardel * - OR -
583 1.1 kardel * 0 (zero) if an error occured or the variable could
584 1.1 kardel * not be found
585 1.1 kardel ****************************************************************************/
586 1.1 kardel int ntpq_get_peervar( const char *varname, char *varvalue, int maxlen)
587 1.1 kardel {
588 1.1 kardel return ( ntpq_getvar(peervars,peervarlen,varname,varvalue,maxlen) );
589 1.1 kardel }
590 1.1 kardel
591 1.1 kardel
592 1.1 kardel
593 1.1 kardel /*****************************************************************************
594 1.1 kardel *
595 1.1 kardel * ntpq_get_assoc_peervars
596 1.1 kardel *
597 1.1 kardel * This function requests the peer variables of the specified association
598 1.1 kardel * from a NTP host. In order to access the variable values, the function
599 1.1 kardel * ntpq_get_peervar must be used.
600 1.1 kardel *
601 1.1 kardel ****************************************************************************
602 1.1 kardel * Parameters:
603 1.1 kardel * associd int requested associaton ID
604 1.1 kardel *
605 1.1 kardel * Returns:
606 1.1 kardel * int 1 (one) if the peervars have been read
607 1.1 kardel * - OR -
608 1.1 kardel * 0 (zero) if an error occured and the variable set
609 1.1 kardel * could not be read
610 1.1 kardel ****************************************************************************/
611 1.1.1.2 kardel int
612 1.1.1.2 kardel ntpq_get_assoc_peervars(
613 1.1.1.2 kardel associd_t associd
614 1.1.1.2 kardel )
615 1.1.1.2 kardel {
616 1.1.1.2 kardel peervarlen = ntpq_read_assoc_peervars(associd, peervars,
617 1.1.1.2 kardel sizeof(peervars));
618 1.1.1.2 kardel if (peervarlen <= 0) {
619 1.1.1.2 kardel peervar_assoc = 0;
620 1.1.1.2 kardel
621 1.1.1.2 kardel return 0;
622 1.1.1.2 kardel }
623 1.1.1.2 kardel peervar_assoc = associd;
624 1.1.1.2 kardel
625 1.1.1.2 kardel return 1;
626 1.1 kardel }
627 1.1 kardel
628 1.1 kardel
629 1.1 kardel /*****************************************************************************
630 1.1 kardel *
631 1.1 kardel * ntp_read_assoc_clockvars
632 1.1 kardel *
633 1.1 kardel * This function reads the clockvars variable-set of a specified association
634 1.1 kardel * from a NTP host and writes it to the result buffer specified, honoring
635 1.1 kardel * the maxsize limit.
636 1.1 kardel *
637 1.1 kardel * It returns the number of bytes written or 0 when the variable-set is
638 1.1 kardel * empty or failed to read.
639 1.1 kardel *
640 1.1 kardel ****************************************************************************
641 1.1 kardel * Parameters:
642 1.1 kardel * associd int requested associaton ID
643 1.1 kardel * resultbuf char* character buffer where the variable set
644 1.1 kardel * should be stored
645 1.1 kardel * maxsize int the maximum number of bytes that can be
646 1.1 kardel * written to resultbuf
647 1.1 kardel *
648 1.1 kardel * Returns:
649 1.1 kardel * int number of chars that have been copied to
650 1.1 kardel * resultbuf
651 1.1 kardel * - OR -
652 1.1 kardel * 0 (zero) if an error occured
653 1.1 kardel ****************************************************************************/
654 1.1 kardel
655 1.1.1.2 kardel int
656 1.1.1.2 kardel ntpq_read_assoc_clockvars(
657 1.1.1.2 kardel associd_t associd,
658 1.1.1.2 kardel char * resultbuf,
659 1.1.1.2 kardel int maxsize
660 1.1.1.2 kardel )
661 1.1 kardel {
662 1.1.1.2 kardel const char *datap;
663 1.1.1.2 kardel int res;
664 1.1.1.6 christos size_t dsize;
665 1.1.1.2 kardel u_short rstatus;
666 1.1 kardel
667 1.1.1.2 kardel res = ntpq_doquerylist(ntpq_varlist, CTL_OP_READCLOCK, associd,
668 1.1.1.2 kardel 0, &rstatus, &dsize, &datap);
669 1.1.1.2 kardel if (res != 0)
670 1.1.1.2 kardel return 0;
671 1.1 kardel
672 1.1.1.2 kardel if (dsize == 0) {
673 1.1.1.2 kardel if (numhosts > 1) /* no information returned from server */
674 1.1.1.2 kardel return 0;
675 1.1.1.2 kardel } else {
676 1.1.1.2 kardel if (dsize > maxsize)
677 1.1.1.2 kardel dsize = maxsize;
678 1.1.1.2 kardel memcpy(resultbuf, datap, dsize);
679 1.1.1.2 kardel }
680 1.1 kardel
681 1.1.1.2 kardel return dsize;
682 1.1 kardel }
683 1.1 kardel
684 1.1 kardel
685 1.1 kardel
686 1.1 kardel /*****************************************************************************
687 1.1 kardel *
688 1.1 kardel * ntpq_get_assoc_clocktype
689 1.1 kardel *
690 1.1 kardel * This function returns a clocktype value for a given association number
691 1.1 kardel * (not ID!):
692 1.1 kardel *
693 1.1 kardel * NTP_CLOCKTYPE_UNKNOWN Unknown clock type
694 1.1 kardel * NTP_CLOCKTYPE_BROADCAST Broadcast server
695 1.1 kardel * NTP_CLOCKTYPE_LOCAL Local clock
696 1.1 kardel * NTP_CLOCKTYPE_UNICAST Unicast server
697 1.1 kardel * NTP_CLOCKTYPE_MULTICAST Multicast server
698 1.1 kardel *
699 1.1 kardel ****************************************************************************/
700 1.1.1.2 kardel int
701 1.1.1.2 kardel ntpq_get_assoc_clocktype(
702 1.1.1.2 kardel int assoc_index
703 1.1.1.2 kardel )
704 1.1.1.2 kardel {
705 1.1.1.2 kardel associd_t associd;
706 1.1.1.2 kardel int i;
707 1.1.1.2 kardel int rc;
708 1.1.1.2 kardel sockaddr_u dum_store;
709 1.1.1.2 kardel char dstadr[LENHOSTNAME];
710 1.1.1.2 kardel char resultbuf[NTPQ_BUFLEN];
711 1.1.1.2 kardel
712 1.1.1.2 kardel if (assoc_index < 0 || assoc_index >= numassoc)
713 1.1.1.2 kardel return -1;
714 1.1.1.2 kardel
715 1.1.1.2 kardel associd = assoc_cache[assoc_index].assid;
716 1.1.1.2 kardel if (associd == peervar_assoc) {
717 1.1.1.2 kardel rc = ntpq_get_peervar("dstadr", dstadr, sizeof(dstadr));
718 1.1.1.2 kardel } else {
719 1.1.1.2 kardel i = ntpq_read_assoc_peervars(associd, resultbuf,
720 1.1.1.2 kardel sizeof(resultbuf));
721 1.1.1.2 kardel if (i <= 0)
722 1.1.1.2 kardel return -1;
723 1.1.1.2 kardel rc = ntpq_getvar(resultbuf, i, "dstadr", dstadr,
724 1.1.1.2 kardel sizeof(dstadr));
725 1.1.1.2 kardel }
726 1.1 kardel
727 1.1.1.2 kardel if (0 != rc && decodenetnum(dstadr, &dum_store))
728 1.1.1.2 kardel return ntpq_decodeaddrtype(&dum_store);
729 1.1 kardel
730 1.1.1.2 kardel return -1;
731 1.1 kardel }
732 1.1 kardel
733 1.1 kardel
734 1.1 kardel
735 1.1 kardel /*****************************************************************************
736 1.1 kardel *
737 1.1 kardel * ntpq_get_assoc_clockvars
738 1.1 kardel *
739 1.1 kardel * With this function the clock variables of the specified association are
740 1.1 kardel * requested from a NTP host. This makes only sense for associations with
741 1.1 kardel * the type 'l' (Local Clock) and you should check this with
742 1.1 kardel * ntpq_get_assoc_clocktype for each association, before you use this function
743 1.1 kardel * on it.
744 1.1 kardel *
745 1.1 kardel ****************************************************************************
746 1.1 kardel * Parameters:
747 1.1 kardel * associd int requested associaton ID
748 1.1 kardel *
749 1.1 kardel * Returns:
750 1.1 kardel * int 1 (one) if the clockvars have been read
751 1.1 kardel * - OR -
752 1.1 kardel * 0 (zero) if an error occured and the variable set
753 1.1 kardel * could not be read
754 1.1 kardel ****************************************************************************/
755 1.1.1.2 kardel int ntpq_get_assoc_clockvars( associd_t associd )
756 1.1 kardel {
757 1.1.1.2 kardel if (NTP_CLOCKTYPE_LOCAL != ntpq_get_assoc_clocktype(
758 1.1.1.2 kardel ntpq_get_assoc_number(associd)))
759 1.1.1.2 kardel return 0;
760 1.1.1.2 kardel clockvarlen = ntpq_read_assoc_clockvars( associd, clockvars,
761 1.1.1.2 kardel sizeof(clockvars) );
762 1.1.1.2 kardel if ( clockvarlen <= 0 ) {
763 1.1.1.2 kardel clockvar_assoc = 0;
764 1.1.1.2 kardel return 0;
765 1.1.1.2 kardel } else {
766 1.1.1.2 kardel clockvar_assoc = associd;
767 1.1.1.2 kardel return 1;
768 1.1.1.2 kardel }
769 1.1 kardel }
770 1.1 kardel
771 1.1 kardel
772