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