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