libntpq.c revision 1.1.1.1.6.1 1 1.1.1.1.6.1 yamt /* $NetBSD: libntpq.c,v 1.1.1.1.6.1 2012/04/17 00:03:49 yamt 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.1.6.1 yamt #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.1.6.1 yamt char peervars[NTPQ_BUFLEN];
28 1.1.1.1.6.1 yamt int peervarlen = 0;
29 1.1.1.1.6.1 yamt associd_t peervar_assoc = 0;
30 1.1.1.1.6.1 yamt char clockvars[NTPQ_BUFLEN];
31 1.1.1.1.6.1 yamt int clockvarlen = 0;
32 1.1.1.1.6.1 yamt int clockvar_assoc = 0;
33 1.1.1.1.6.1 yamt char sysvars[NTPQ_BUFLEN];
34 1.1.1.1.6.1 yamt int sysvarlen = 0;
35 1.1.1.1.6.1 yamt char *ntpq_resultbuffer[NTPQ_BUFLEN];
36 1.1.1.1.6.1 yamt 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.1.6.1 yamt * 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.1.6.1 yamt * maxlen size_t Max. number of bytes for varvalue
121 1.1 kardel *
122 1.1 kardel * Returns:
123 1.1.1.1.6.1 yamt * 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.1.6.1 yamt size_t
128 1.1.1.1.6.1 yamt ntpq_getvar(
129 1.1.1.1.6.1 yamt const char * resultbuf,
130 1.1.1.1.6.1 yamt size_t datalen,
131 1.1.1.1.6.1 yamt const char * varname,
132 1.1.1.1.6.1 yamt char * varvalue,
133 1.1.1.1.6.1 yamt size_t maxlen)
134 1.1.1.1.6.1 yamt {
135 1.1.1.1.6.1 yamt char * name;
136 1.1.1.1.6.1 yamt char * value;
137 1.1.1.1.6.1 yamt int idatalen;
138 1.1.1.1.6.1 yamt
139 1.1.1.1.6.1 yamt value = NULL;
140 1.1.1.1.6.1 yamt idatalen = (int)datalen;
141 1.1.1.1.6.1 yamt
142 1.1.1.1.6.1 yamt while (nextvar(&idatalen, &resultbuf, &name, &value)) {
143 1.1.1.1.6.1 yamt if (strcmp(varname, name) == 0) {
144 1.1.1.1.6.1 yamt ntpq_stripquotes(varvalue, value, strlen(value), maxlen);
145 1.1 kardel
146 1.1 kardel return strlen(varvalue);
147 1.1.1.1.6.1 yamt }
148 1.1.1.1.6.1 yamt }
149 1.1 kardel
150 1.1.1.1.6.1 yamt 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.1.6.1 yamt const char *datap;
185 1.1 kardel int res;
186 1.1 kardel int dsize;
187 1.1 kardel 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 kardel *
221 1.1 kardel * Returns:
222 1.1 kardel * int 1 if the host connection could be set up, i.e.
223 1.1 kardel * name resolution was succesful and/or IP address
224 1.1 kardel * has been validated
225 1.1 kardel * - OR -
226 1.1 kardel * 0 (zero) if a failure occured
227 1.1 kardel ****************************************************************************/
228 1.1 kardel
229 1.1 kardel int ntpq_openhost(char *hostname)
230 1.1 kardel {
231 1.1 kardel if ( openhost(hostname) )
232 1.1 kardel {
233 1.1 kardel numhosts = 1;
234 1.1 kardel } else {
235 1.1 kardel numhosts = 0;
236 1.1 kardel }
237 1.1 kardel
238 1.1 kardel return numhosts;
239 1.1 kardel
240 1.1 kardel }
241 1.1 kardel
242 1.1 kardel
243 1.1 kardel /*****************************************************************************
244 1.1 kardel *
245 1.1 kardel * ntpq_closehost
246 1.1 kardel *
247 1.1 kardel * Cleans up a connection by closing the used socket. Should be called
248 1.1 kardel * when no further queries are required for the currently used host.
249 1.1 kardel *
250 1.1 kardel ****************************************************************************
251 1.1 kardel * Parameters:
252 1.1 kardel * - none -
253 1.1 kardel *
254 1.1 kardel * Returns:
255 1.1 kardel * int 0 (zero) if no host has been opened before
256 1.1 kardel * - OR -
257 1.1 kardel * the resultcode from the closesocket function call
258 1.1 kardel ****************************************************************************/
259 1.1 kardel
260 1.1 kardel int ntpq_closehost(void)
261 1.1 kardel {
262 1.1 kardel if ( numhosts )
263 1.1 kardel return closesocket(sockfd);
264 1.1 kardel
265 1.1 kardel return 0;
266 1.1 kardel }
267 1.1 kardel
268 1.1 kardel
269 1.1 kardel /*****************************************************************************
270 1.1 kardel *
271 1.1 kardel * ntpq_read_associations
272 1.1 kardel *
273 1.1 kardel * This function queries the ntp host for its associations and returns the
274 1.1 kardel * number of associations found.
275 1.1 kardel *
276 1.1 kardel * It takes an u_short array as its first parameter, this array holds the
277 1.1 kardel * IDs of the associations,
278 1.1 kardel * the function will not write more entries than specified with the
279 1.1 kardel * max_entries parameter.
280 1.1 kardel *
281 1.1 kardel * However, if more than max_entries associations were found, the return
282 1.1 kardel * value of this function will reflect the real number, even if not all
283 1.1 kardel * associations have been stored in the array.
284 1.1 kardel *
285 1.1 kardel ****************************************************************************
286 1.1 kardel * Parameters:
287 1.1 kardel * resultbuf u_short*Array that should hold the list of
288 1.1 kardel * association IDs
289 1.1 kardel * maxentries int maximum number of association IDs that can
290 1.1 kardel * be stored in resultbuf
291 1.1 kardel *
292 1.1 kardel * Returns:
293 1.1 kardel * int number of association IDs stored in resultbuf
294 1.1 kardel * - OR -
295 1.1 kardel * 0 (zero) if a failure occured or no association has
296 1.1 kardel * been returned.
297 1.1 kardel ****************************************************************************/
298 1.1 kardel
299 1.1 kardel int ntpq_read_associations ( u_short resultbuf[], int max_entries )
300 1.1 kardel {
301 1.1 kardel int i = 0;
302 1.1 kardel
303 1.1 kardel if (ntpq_dogetassoc()) {
304 1.1 kardel
305 1.1 kardel if(numassoc < max_entries)
306 1.1 kardel max_entries = numassoc;
307 1.1 kardel
308 1.1 kardel for (i=0;i<max_entries;i++)
309 1.1 kardel resultbuf[i] = assoc_cache[i].assid;
310 1.1 kardel
311 1.1 kardel return numassoc;
312 1.1 kardel }
313 1.1 kardel
314 1.1 kardel return 0;
315 1.1 kardel }
316 1.1 kardel
317 1.1 kardel
318 1.1 kardel
319 1.1 kardel
320 1.1 kardel /*****************************************************************************
321 1.1 kardel *
322 1.1 kardel * ntpq_get_assocs
323 1.1 kardel *
324 1.1 kardel * This function reads the associations of a previously selected (with
325 1.1 kardel * ntpq_openhost) NTP host into its own (global) array and returns the
326 1.1 kardel * number of associations found.
327 1.1 kardel *
328 1.1 kardel * The obtained association IDs can be read by using the ntpq_get_assoc_id
329 1.1 kardel * function.
330 1.1 kardel *
331 1.1 kardel ****************************************************************************
332 1.1 kardel * Parameters:
333 1.1 kardel * - none -
334 1.1 kardel *
335 1.1 kardel * Returns:
336 1.1 kardel * int number of association IDs stored in resultbuf
337 1.1 kardel * - OR -
338 1.1 kardel * 0 (zero) if a failure occured or no association has
339 1.1 kardel * been returned.
340 1.1 kardel ****************************************************************************/
341 1.1 kardel
342 1.1 kardel int ntpq_get_assocs ( void )
343 1.1 kardel {
344 1.1 kardel return ntpq_read_associations( ntpq_associations, MAXASSOC );
345 1.1 kardel }
346 1.1 kardel
347 1.1 kardel
348 1.1 kardel /*****************************************************************************
349 1.1 kardel *
350 1.1 kardel * ntpq_get_assoc_number
351 1.1 kardel *
352 1.1 kardel * This function returns for a given Association ID the association number
353 1.1 kardel * in the internal association array, which is filled by the ntpq_get_assocs
354 1.1 kardel * function.
355 1.1 kardel *
356 1.1 kardel ****************************************************************************
357 1.1 kardel * Parameters:
358 1.1 kardel * associd int requested associaton ID
359 1.1 kardel *
360 1.1 kardel * Returns:
361 1.1 kardel * int the number of the association array element that is
362 1.1 kardel * representing the given association ID
363 1.1 kardel * - OR -
364 1.1 kardel * -1 if a failure occured or no matching association
365 1.1 kardel * ID has been found
366 1.1 kardel ****************************************************************************/
367 1.1 kardel
368 1.1.1.1.6.1 yamt int ntpq_get_assoc_number ( associd_t associd )
369 1.1 kardel {
370 1.1.1.1.6.1 yamt int i;
371 1.1 kardel
372 1.1.1.1.6.1 yamt for (i=0;i<numassoc;i++) {
373 1.1.1.1.6.1 yamt if (assoc_cache[i].assid == associd)
374 1.1.1.1.6.1 yamt return i;
375 1.1.1.1.6.1 yamt }
376 1.1 kardel
377 1.1.1.1.6.1 yamt return -1;
378 1.1 kardel
379 1.1 kardel }
380 1.1 kardel
381 1.1 kardel
382 1.1 kardel /*****************************************************************************
383 1.1 kardel *
384 1.1 kardel * ntpq_read_assoc_peervars
385 1.1 kardel *
386 1.1 kardel * This function reads the peervars variable-set of a specified association
387 1.1 kardel * from a NTP host and writes it to the result buffer specified, honoring
388 1.1 kardel * the maxsize limit.
389 1.1 kardel *
390 1.1 kardel * It returns the number of bytes written or 0 when the variable-set is
391 1.1 kardel * empty or failed to read.
392 1.1 kardel *
393 1.1 kardel ****************************************************************************
394 1.1 kardel * Parameters:
395 1.1 kardel * associd int requested associaton ID
396 1.1 kardel * resultbuf char* character buffer where the variable set
397 1.1 kardel * should be stored
398 1.1 kardel * maxsize int the maximum number of bytes that can be
399 1.1 kardel * written to resultbuf
400 1.1 kardel *
401 1.1 kardel * Returns:
402 1.1 kardel * int number of chars that have been copied to
403 1.1 kardel * resultbuf
404 1.1 kardel * - OR -
405 1.1 kardel * 0 (zero) if an error occured
406 1.1 kardel ****************************************************************************/
407 1.1 kardel
408 1.1.1.1.6.1 yamt int
409 1.1.1.1.6.1 yamt ntpq_read_assoc_peervars(
410 1.1.1.1.6.1 yamt associd_t associd,
411 1.1.1.1.6.1 yamt char * resultbuf,
412 1.1.1.1.6.1 yamt int maxsize
413 1.1.1.1.6.1 yamt )
414 1.1.1.1.6.1 yamt {
415 1.1.1.1.6.1 yamt const char * datap;
416 1.1.1.1.6.1 yamt int res;
417 1.1.1.1.6.1 yamt int dsize;
418 1.1.1.1.6.1 yamt u_short rstatus;
419 1.1.1.1.6.1 yamt
420 1.1.1.1.6.1 yamt res = doquery(CTL_OP_READVAR, associd, 0, 0, NULL, &rstatus,
421 1.1.1.1.6.1 yamt &dsize, &datap);
422 1.1.1.1.6.1 yamt if (res != 0)
423 1.1.1.1.6.1 yamt return 0;
424 1.1.1.1.6.1 yamt if (dsize <= 0) {
425 1.1.1.1.6.1 yamt if (numhosts > 1)
426 1.1.1.1.6.1 yamt fprintf(stderr, "server=%s ", currenthost);
427 1.1.1.1.6.1 yamt fprintf(stderr,
428 1.1.1.1.6.1 yamt "***No information returned for association %d\n",
429 1.1.1.1.6.1 yamt associd);
430 1.1 kardel
431 1.1.1.1.6.1 yamt return 0;
432 1.1.1.1.6.1 yamt }
433 1.1.1.1.6.1 yamt if (dsize > maxsize)
434 1.1.1.1.6.1 yamt dsize = maxsize;
435 1.1.1.1.6.1 yamt memcpy(resultbuf, datap, dsize);
436 1.1 kardel
437 1.1.1.1.6.1 yamt return dsize;
438 1.1 kardel }
439 1.1 kardel
440 1.1 kardel
441 1.1 kardel
442 1.1 kardel
443 1.1 kardel /*****************************************************************************
444 1.1 kardel *
445 1.1 kardel * ntpq_read_sysvars
446 1.1 kardel *
447 1.1 kardel * This function reads the sysvars variable-set from a NTP host and writes it
448 1.1 kardel * to the result buffer specified, honoring the maxsize limit.
449 1.1 kardel *
450 1.1 kardel * It returns the number of bytes written or 0 when the variable-set is empty
451 1.1 kardel * or could not be read.
452 1.1 kardel *
453 1.1 kardel ****************************************************************************
454 1.1 kardel * Parameters:
455 1.1 kardel * resultbuf char* character buffer where the variable set
456 1.1 kardel * should be stored
457 1.1 kardel * maxsize int the maximum number of bytes that can be
458 1.1 kardel * written to resultbuf
459 1.1 kardel *
460 1.1 kardel * Returns:
461 1.1 kardel * int number of chars that have been copied to
462 1.1 kardel * resultbuf
463 1.1 kardel * - OR -
464 1.1 kardel * 0 (zero) if an error occured
465 1.1 kardel ****************************************************************************/
466 1.1.1.1.6.1 yamt size_t
467 1.1.1.1.6.1 yamt ntpq_read_sysvars(
468 1.1.1.1.6.1 yamt char * resultbuf,
469 1.1.1.1.6.1 yamt size_t maxsize
470 1.1.1.1.6.1 yamt )
471 1.1.1.1.6.1 yamt {
472 1.1.1.1.6.1 yamt const char * datap;
473 1.1.1.1.6.1 yamt int res;
474 1.1.1.1.6.1 yamt int i_dsize;
475 1.1.1.1.6.1 yamt size_t dsize;
476 1.1.1.1.6.1 yamt u_short rstatus;
477 1.1 kardel
478 1.1.1.1.6.1 yamt res = doquery(CTL_OP_READVAR, 0, 0, 0, NULL, &rstatus,
479 1.1.1.1.6.1 yamt &i_dsize, &datap);
480 1.1 kardel
481 1.1.1.1.6.1 yamt if (res != 0)
482 1.1.1.1.6.1 yamt return 0;
483 1.1.1.1.6.1 yamt
484 1.1.1.1.6.1 yamt if (i_dsize == 0) {
485 1.1.1.1.6.1 yamt if (numhosts > 1)
486 1.1.1.1.6.1 yamt fprintf(stderr, "server=%s ", currenthost);
487 1.1.1.1.6.1 yamt fprintf(stderr, "***No sysvar information returned\n");
488 1.1 kardel
489 1.1.1.1.6.1 yamt return 0;
490 1.1.1.1.6.1 yamt } else {
491 1.1.1.1.6.1 yamt dsize = max(0, i_dsize);
492 1.1.1.1.6.1 yamt dsize = min(dsize, maxsize);
493 1.1.1.1.6.1 yamt memcpy(resultbuf, datap, dsize);
494 1.1.1.1.6.1 yamt }
495 1.1 kardel
496 1.1.1.1.6.1 yamt return dsize;
497 1.1 kardel }
498 1.1 kardel
499 1.1 kardel
500 1.1 kardel /*****************************************************************************
501 1.1 kardel * ntpq_get_assoc_allvars
502 1.1 kardel *
503 1.1 kardel * With this function all association variables for the specified association
504 1.1 kardel * ID can be requested from a NTP host. They are stored internally and can be
505 1.1 kardel * read by using the ntpq_get_peervar or ntpq_get_clockvar functions.
506 1.1 kardel *
507 1.1 kardel * Basically this is only a combination of the ntpq_get_assoc_peervars and
508 1.1 kardel * ntpq_get_assoc_clockvars functions.
509 1.1 kardel *
510 1.1 kardel * It returns 1 if both variable-sets (peervars and clockvars) were
511 1.1 kardel * received successfully. If one variable-set or both of them weren't
512 1.1 kardel * received,
513 1.1 kardel *
514 1.1 kardel ****************************************************************************
515 1.1 kardel * Parameters:
516 1.1 kardel * associd int requested associaton ID
517 1.1 kardel *
518 1.1 kardel * Returns:
519 1.1 kardel * int nonzero if at least one variable set could be read
520 1.1 kardel * - OR -
521 1.1 kardel * 0 (zero) if an error occured and both variable sets
522 1.1 kardel * could not be read
523 1.1 kardel ****************************************************************************/
524 1.1.1.1.6.1 yamt int ntpq_get_assoc_allvars( associd_t associd )
525 1.1 kardel {
526 1.1.1.1.6.1 yamt return ntpq_get_assoc_peervars ( associd ) &
527 1.1.1.1.6.1 yamt ntpq_get_assoc_clockvars( associd );
528 1.1 kardel }
529 1.1 kardel
530 1.1 kardel
531 1.1 kardel
532 1.1 kardel
533 1.1 kardel /*****************************************************************************
534 1.1 kardel *
535 1.1 kardel * ntpq_get_sysvars
536 1.1 kardel *
537 1.1 kardel * The system variables of a NTP host can be requested by using this function
538 1.1 kardel * and afterwards using ntpq_get_sysvar to read the single variable values.
539 1.1 kardel *
540 1.1 kardel ****************************************************************************
541 1.1 kardel * Parameters:
542 1.1 kardel * - none -
543 1.1 kardel *
544 1.1 kardel * Returns:
545 1.1 kardel * int nonzero if the variable set could be read
546 1.1 kardel * - OR -
547 1.1 kardel * 0 (zero) if an error occured and the sysvars
548 1.1 kardel * could not be read
549 1.1 kardel ****************************************************************************/
550 1.1.1.1.6.1 yamt int
551 1.1.1.1.6.1 yamt ntpq_get_sysvars(void)
552 1.1 kardel {
553 1.1.1.1.6.1 yamt sysvarlen = ntpq_read_sysvars(sysvars, sizeof(sysvars));
554 1.1.1.1.6.1 yamt if (sysvarlen <= 0)
555 1.1.1.1.6.1 yamt return 0;
556 1.1.1.1.6.1 yamt else
557 1.1.1.1.6.1 yamt return 1;
558 1.1 kardel }
559 1.1 kardel
560 1.1 kardel
561 1.1 kardel /*****************************************************************************
562 1.1 kardel *
563 1.1 kardel * ntp_get_peervar
564 1.1 kardel *
565 1.1 kardel * This function uses the variable-set which was read by using
566 1.1 kardel * ntp_get_peervars and searches for a variable specified with varname. If
567 1.1 kardel * such a variable exists, it writes its value into
568 1.1 kardel * varvalue (maxlen specifies the size of this target buffer).
569 1.1 kardel *
570 1.1 kardel ****************************************************************************
571 1.1 kardel * Parameters:
572 1.1 kardel * varname char* requested variable name
573 1.1 kardel * varvalue char* the buffer where the value should go into
574 1.1 kardel * maxlen int maximum number of bytes that can be copied to
575 1.1 kardel * varvalue
576 1.1 kardel *
577 1.1 kardel * Returns:
578 1.1 kardel * int number of bytes copied to varvalue
579 1.1 kardel * - OR -
580 1.1 kardel * 0 (zero) if an error occured or the variable could
581 1.1 kardel * not be found
582 1.1 kardel ****************************************************************************/
583 1.1 kardel int ntpq_get_peervar( const char *varname, char *varvalue, int maxlen)
584 1.1 kardel {
585 1.1 kardel return ( ntpq_getvar(peervars,peervarlen,varname,varvalue,maxlen) );
586 1.1 kardel }
587 1.1 kardel
588 1.1 kardel
589 1.1 kardel
590 1.1 kardel /*****************************************************************************
591 1.1 kardel *
592 1.1 kardel * ntpq_get_assoc_peervars
593 1.1 kardel *
594 1.1 kardel * This function requests the peer variables of the specified association
595 1.1 kardel * from a NTP host. In order to access the variable values, the function
596 1.1 kardel * ntpq_get_peervar must be used.
597 1.1 kardel *
598 1.1 kardel ****************************************************************************
599 1.1 kardel * Parameters:
600 1.1 kardel * associd int requested associaton ID
601 1.1 kardel *
602 1.1 kardel * Returns:
603 1.1 kardel * int 1 (one) if the peervars have been read
604 1.1 kardel * - OR -
605 1.1 kardel * 0 (zero) if an error occured and the variable set
606 1.1 kardel * could not be read
607 1.1 kardel ****************************************************************************/
608 1.1.1.1.6.1 yamt int
609 1.1.1.1.6.1 yamt ntpq_get_assoc_peervars(
610 1.1.1.1.6.1 yamt associd_t associd
611 1.1.1.1.6.1 yamt )
612 1.1.1.1.6.1 yamt {
613 1.1.1.1.6.1 yamt peervarlen = ntpq_read_assoc_peervars(associd, peervars,
614 1.1.1.1.6.1 yamt sizeof(peervars));
615 1.1.1.1.6.1 yamt if (peervarlen <= 0) {
616 1.1.1.1.6.1 yamt peervar_assoc = 0;
617 1.1.1.1.6.1 yamt
618 1.1.1.1.6.1 yamt return 0;
619 1.1.1.1.6.1 yamt }
620 1.1.1.1.6.1 yamt peervar_assoc = associd;
621 1.1.1.1.6.1 yamt
622 1.1.1.1.6.1 yamt return 1;
623 1.1 kardel }
624 1.1 kardel
625 1.1 kardel
626 1.1 kardel /*****************************************************************************
627 1.1 kardel *
628 1.1 kardel * ntp_read_assoc_clockvars
629 1.1 kardel *
630 1.1 kardel * This function reads the clockvars variable-set of a specified association
631 1.1 kardel * from a NTP host and writes it to the result buffer specified, honoring
632 1.1 kardel * the maxsize limit.
633 1.1 kardel *
634 1.1 kardel * It returns the number of bytes written or 0 when the variable-set is
635 1.1 kardel * empty or failed to read.
636 1.1 kardel *
637 1.1 kardel ****************************************************************************
638 1.1 kardel * Parameters:
639 1.1 kardel * associd int requested associaton ID
640 1.1 kardel * resultbuf char* character buffer where the variable set
641 1.1 kardel * should be stored
642 1.1 kardel * maxsize int the maximum number of bytes that can be
643 1.1 kardel * written to resultbuf
644 1.1 kardel *
645 1.1 kardel * Returns:
646 1.1 kardel * int number of chars that have been copied to
647 1.1 kardel * resultbuf
648 1.1 kardel * - OR -
649 1.1 kardel * 0 (zero) if an error occured
650 1.1 kardel ****************************************************************************/
651 1.1 kardel
652 1.1.1.1.6.1 yamt int
653 1.1.1.1.6.1 yamt ntpq_read_assoc_clockvars(
654 1.1.1.1.6.1 yamt associd_t associd,
655 1.1.1.1.6.1 yamt char * resultbuf,
656 1.1.1.1.6.1 yamt int maxsize
657 1.1.1.1.6.1 yamt )
658 1.1 kardel {
659 1.1.1.1.6.1 yamt const char *datap;
660 1.1.1.1.6.1 yamt int res;
661 1.1.1.1.6.1 yamt int dsize;
662 1.1.1.1.6.1 yamt u_short rstatus;
663 1.1 kardel
664 1.1.1.1.6.1 yamt res = ntpq_doquerylist(ntpq_varlist, CTL_OP_READCLOCK, associd,
665 1.1.1.1.6.1 yamt 0, &rstatus, &dsize, &datap);
666 1.1.1.1.6.1 yamt if (res != 0)
667 1.1.1.1.6.1 yamt return 0;
668 1.1 kardel
669 1.1.1.1.6.1 yamt if (dsize == 0) {
670 1.1.1.1.6.1 yamt if (numhosts > 1) /* no information returned from server */
671 1.1.1.1.6.1 yamt return 0;
672 1.1.1.1.6.1 yamt } else {
673 1.1.1.1.6.1 yamt if (dsize > maxsize)
674 1.1.1.1.6.1 yamt dsize = maxsize;
675 1.1.1.1.6.1 yamt memcpy(resultbuf, datap, dsize);
676 1.1.1.1.6.1 yamt }
677 1.1 kardel
678 1.1.1.1.6.1 yamt return dsize;
679 1.1 kardel }
680 1.1 kardel
681 1.1 kardel
682 1.1 kardel
683 1.1 kardel /*****************************************************************************
684 1.1 kardel *
685 1.1 kardel * ntpq_get_assoc_clocktype
686 1.1 kardel *
687 1.1 kardel * This function returns a clocktype value for a given association number
688 1.1 kardel * (not ID!):
689 1.1 kardel *
690 1.1 kardel * NTP_CLOCKTYPE_UNKNOWN Unknown clock type
691 1.1 kardel * NTP_CLOCKTYPE_BROADCAST Broadcast server
692 1.1 kardel * NTP_CLOCKTYPE_LOCAL Local clock
693 1.1 kardel * NTP_CLOCKTYPE_UNICAST Unicast server
694 1.1 kardel * NTP_CLOCKTYPE_MULTICAST Multicast server
695 1.1 kardel *
696 1.1 kardel ****************************************************************************/
697 1.1.1.1.6.1 yamt int
698 1.1.1.1.6.1 yamt ntpq_get_assoc_clocktype(
699 1.1.1.1.6.1 yamt int assoc_index
700 1.1.1.1.6.1 yamt )
701 1.1.1.1.6.1 yamt {
702 1.1.1.1.6.1 yamt associd_t associd;
703 1.1.1.1.6.1 yamt int i;
704 1.1.1.1.6.1 yamt int rc;
705 1.1.1.1.6.1 yamt sockaddr_u dum_store;
706 1.1.1.1.6.1 yamt char dstadr[LENHOSTNAME];
707 1.1.1.1.6.1 yamt char resultbuf[NTPQ_BUFLEN];
708 1.1.1.1.6.1 yamt
709 1.1.1.1.6.1 yamt if (assoc_index < 0 || assoc_index >= numassoc)
710 1.1.1.1.6.1 yamt return -1;
711 1.1.1.1.6.1 yamt
712 1.1.1.1.6.1 yamt associd = assoc_cache[assoc_index].assid;
713 1.1.1.1.6.1 yamt if (associd == peervar_assoc) {
714 1.1.1.1.6.1 yamt rc = ntpq_get_peervar("dstadr", dstadr, sizeof(dstadr));
715 1.1.1.1.6.1 yamt } else {
716 1.1.1.1.6.1 yamt i = ntpq_read_assoc_peervars(associd, resultbuf,
717 1.1.1.1.6.1 yamt sizeof(resultbuf));
718 1.1.1.1.6.1 yamt if (i <= 0)
719 1.1.1.1.6.1 yamt return -1;
720 1.1.1.1.6.1 yamt rc = ntpq_getvar(resultbuf, i, "dstadr", dstadr,
721 1.1.1.1.6.1 yamt sizeof(dstadr));
722 1.1.1.1.6.1 yamt }
723 1.1 kardel
724 1.1.1.1.6.1 yamt if (0 != rc && decodenetnum(dstadr, &dum_store))
725 1.1.1.1.6.1 yamt return ntpq_decodeaddrtype(&dum_store);
726 1.1 kardel
727 1.1.1.1.6.1 yamt return -1;
728 1.1 kardel }
729 1.1 kardel
730 1.1 kardel
731 1.1 kardel
732 1.1 kardel /*****************************************************************************
733 1.1 kardel *
734 1.1 kardel * ntpq_get_assoc_clockvars
735 1.1 kardel *
736 1.1 kardel * With this function the clock variables of the specified association are
737 1.1 kardel * requested from a NTP host. This makes only sense for associations with
738 1.1 kardel * the type 'l' (Local Clock) and you should check this with
739 1.1 kardel * ntpq_get_assoc_clocktype for each association, before you use this function
740 1.1 kardel * on it.
741 1.1 kardel *
742 1.1 kardel ****************************************************************************
743 1.1 kardel * Parameters:
744 1.1 kardel * associd int requested associaton ID
745 1.1 kardel *
746 1.1 kardel * Returns:
747 1.1 kardel * int 1 (one) if the clockvars have been read
748 1.1 kardel * - OR -
749 1.1 kardel * 0 (zero) if an error occured and the variable set
750 1.1 kardel * could not be read
751 1.1 kardel ****************************************************************************/
752 1.1.1.1.6.1 yamt int ntpq_get_assoc_clockvars( associd_t associd )
753 1.1 kardel {
754 1.1.1.1.6.1 yamt if (NTP_CLOCKTYPE_LOCAL != ntpq_get_assoc_clocktype(
755 1.1.1.1.6.1 yamt ntpq_get_assoc_number(associd)))
756 1.1.1.1.6.1 yamt return 0;
757 1.1.1.1.6.1 yamt clockvarlen = ntpq_read_assoc_clockvars( associd, clockvars,
758 1.1.1.1.6.1 yamt sizeof(clockvars) );
759 1.1.1.1.6.1 yamt if ( clockvarlen <= 0 ) {
760 1.1.1.1.6.1 yamt clockvar_assoc = 0;
761 1.1.1.1.6.1 yamt return 0;
762 1.1.1.1.6.1 yamt } else {
763 1.1.1.1.6.1 yamt clockvar_assoc = associd;
764 1.1.1.1.6.1 yamt return 1;
765 1.1.1.1.6.1 yamt }
766 1.1 kardel }
767 1.1 kardel
768 1.1 kardel
769