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