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