1290001Sglebius/***************************************************************************** 2290001Sglebius * 3290001Sglebius * libntpq.c 4290001Sglebius * 5290001Sglebius * This is the wrapper library for ntpq, the NTP query utility. 6290001Sglebius * This library reuses the sourcecode from ntpq and exports a number 7290001Sglebius * of useful functions in a library that can be linked against applications 8290001Sglebius * that need to query the status of a running ntpd. The whole 9290001Sglebius * communcation is based on mode 6 packets. 10290001Sglebius * 11290001Sglebius ****************************************************************************/ 12290001Sglebius#define LIBNTPQ_C 13290001Sglebius#define NO_MAIN_ALLOWED 1 14290001Sglebius/* #define BUILD_AS_LIB Already provided by the Makefile */ 15290001Sglebius 16290001Sglebius#include "ntpq.c" 17290001Sglebius#include "libntpq.h" 18290001Sglebius 19290001Sglebius/* Function Prototypes */ 20290001Sglebius 21290001Sglebius 22290001Sglebiusconst char *Version = "libntpq 0.3beta"; 23290001Sglebius 24290001Sglebius/* global variables used for holding snapshots of data */ 25290001Sglebiuschar peervars[NTPQ_BUFLEN]; 26290001Sglebiusint peervarlen = 0; 27290001Sglebiusassocid_t peervar_assoc = 0; 28290001Sglebiuschar clockvars[NTPQ_BUFLEN]; 29290001Sglebiusint clockvarlen = 0; 30290001Sglebiusint clockvar_assoc = 0; 31290001Sglebiuschar sysvars[NTPQ_BUFLEN]; 32290001Sglebiusint sysvarlen = 0; 33290001Sglebiuschar *ntpq_resultbuffer[NTPQ_BUFLEN]; 34290001Sglebiusunsigned short ntpq_associations[MAXASSOC]; 35290001Sglebiusstruct ntpq_varlist ntpq_varlist[MAXLIST]; 36290001Sglebius 37290001Sglebius/***************************************************************************** 38290001Sglebius * 39290001Sglebius * ntpq_stripquotes 40290001Sglebius * 41290001Sglebius * Parses a given character buffer srcbuf and removes all quoted 42290001Sglebius * characters. The resulting string is copied to the specified 43290001Sglebius * resultbuf character buffer. E.g. \" will be translated into " 44290001Sglebius * 45290001Sglebius **************************************************************************** 46290001Sglebius * Parameters: 47290001Sglebius * resultbuf char* The resulting string without quoted 48290001Sglebius * characters 49290001Sglebius * srcbuf char* The buffer holding the original string 50290001Sglebius * datalen int The number of bytes stored in srcbuf 51290001Sglebius * maxlen int Max. number of bytes for resultbuf 52290001Sglebius * 53290001Sglebius * Returns: 54290001Sglebius * int number of chars that have been copied to 55290001Sglebius * resultbuf 56290001Sglebius ****************************************************************************/ 57290001Sglebius 58290001Sglebiusint ntpq_stripquotes ( char *resultbuf, char *srcbuf, int datalen, int maxlen ) 59290001Sglebius{ 60290001Sglebius char* tmpbuf = srcbuf; 61290001Sglebius 62290001Sglebius while ( *tmpbuf != 0 ) 63290001Sglebius { 64290001Sglebius if ( *tmpbuf == '\"' ) 65290001Sglebius { 66290001Sglebius tmpbuf++; 67290001Sglebius continue; 68290001Sglebius } 69290001Sglebius 70290001Sglebius if ( *tmpbuf == '\\' ) 71290001Sglebius { 72290001Sglebius tmpbuf++; 73290001Sglebius switch ( *tmpbuf ) 74290001Sglebius { 75290001Sglebius /* ignore if end of string */ 76290001Sglebius case 0: 77290001Sglebius continue; 78290001Sglebius /* skip and do not copy */ 79290001Sglebius case '\"': /* quotes */ 80290001Sglebius case 'n': /*newline*/ 81290001Sglebius case 'r': /*carriage return*/ 82290001Sglebius case 'g': /*bell*/ 83290001Sglebius case 't': /*tab*/ 84290001Sglebius tmpbuf++; 85290001Sglebius continue; 86290001Sglebius } 87290001Sglebius } 88290001Sglebius 89290001Sglebius *resultbuf++ = *tmpbuf++; 90290001Sglebius 91290001Sglebius } 92290001Sglebius 93290001Sglebius *resultbuf = 0; 94290001Sglebius return strlen(resultbuf); 95290001Sglebius} 96290001Sglebius 97290001Sglebius 98290001Sglebius/***************************************************************************** 99290001Sglebius * 100290001Sglebius * ntpq_getvar 101290001Sglebius * 102290001Sglebius * This function parses a given buffer for a variable/value pair and 103290001Sglebius * copies the value of the requested variable into the specified 104290001Sglebius * varvalue buffer. 105290001Sglebius * 106290001Sglebius * It returns the number of bytes copied or zero for an empty result 107290001Sglebius * (=no matching variable found or empty value) 108290001Sglebius * 109290001Sglebius **************************************************************************** 110290001Sglebius * Parameters: 111290001Sglebius * resultbuf char* The resulting string without quoted 112290001Sglebius * characters 113290001Sglebius * datalen size_t The number of bytes stored in 114290001Sglebius * resultbuf 115290001Sglebius * varname char* Name of the required variable 116290001Sglebius * varvalue char* Where the value of the variable should 117290001Sglebius * be stored 118290001Sglebius * maxlen size_t Max. number of bytes for varvalue 119290001Sglebius * 120290001Sglebius * Returns: 121290001Sglebius * size_t number of chars that have been copied to 122290001Sglebius * varvalue 123290001Sglebius ****************************************************************************/ 124290001Sglebius 125290001Sglebiussize_t 126290001Sglebiusntpq_getvar( 127290001Sglebius const char * resultbuf, 128290001Sglebius size_t datalen, 129290001Sglebius const char * varname, 130290001Sglebius char * varvalue, 131290001Sglebius size_t maxlen) 132290001Sglebius{ 133290001Sglebius char * name; 134290001Sglebius char * value; 135293896Sglebius size_t idatalen; 136290001Sglebius 137290001Sglebius value = NULL; 138290001Sglebius idatalen = (int)datalen; 139290001Sglebius 140290001Sglebius while (nextvar(&idatalen, &resultbuf, &name, &value)) { 141290001Sglebius if (strcmp(varname, name) == 0) { 142290001Sglebius ntpq_stripquotes(varvalue, value, strlen(value), maxlen); 143290001Sglebius 144290001Sglebius return strlen(varvalue); 145290001Sglebius } 146290001Sglebius } 147290001Sglebius 148290001Sglebius return 0; 149290001Sglebius} 150290001Sglebius 151290001Sglebius 152290001Sglebius/***************************************************************************** 153290001Sglebius * 154290001Sglebius * ntpq_queryhost 155290001Sglebius * 156290001Sglebius * Sends a mode 6 query packet to the current open host (see 157290001Sglebius * ntpq_openhost) and stores the requested variable set in the specified 158290001Sglebius * character buffer. 159290001Sglebius * It returns the number of bytes read or zero for an empty result 160290001Sglebius * (=no answer or empty value) 161290001Sglebius * 162290001Sglebius **************************************************************************** 163290001Sglebius * Parameters: 164290001Sglebius * VARSET u_short Which variable set should be 165290001Sglebius * read (PEERVARS or CLOCKVARS) 166290001Sglebius * association int The association ID that should be read 167290001Sglebius * 0 represents the ntpd instance itself 168290001Sglebius * resultbuf char* The resulting string without quoted 169290001Sglebius * characters 170290001Sglebius * maxlen int Max. number of bytes for varvalue 171290001Sglebius * 172290001Sglebius * Returns: 173290001Sglebius * int number of bytes that have been copied to 174290001Sglebius * resultbuf 175290001Sglebius * - OR - 176290001Sglebius * 0 (zero) if no reply has been received or 177290001Sglebius * another failure occured 178290001Sglebius ****************************************************************************/ 179290001Sglebius 180290001Sglebiusint ntpq_queryhost(unsigned short VARSET, unsigned short association, char *resultbuf, int maxlen) 181290001Sglebius{ 182290001Sglebius const char *datap; 183290001Sglebius int res; 184293896Sglebius size_t dsize; 185293896Sglebius u_short rstatus; 186290001Sglebius 187290001Sglebius if ( numhosts > 0 ) 188290001Sglebius res = doquery(VARSET,association,0,0, (char *)0, &rstatus, &dsize, &datap); 189290001Sglebius else 190290001Sglebius return 0; 191290001Sglebius 192290001Sglebius if ( ( res != 0) || ( dsize == 0 ) ) /* no data */ 193290001Sglebius return 0; 194290001Sglebius 195290001Sglebius if ( dsize > maxlen) 196290001Sglebius dsize = maxlen; 197290001Sglebius 198290001Sglebius 199290001Sglebius /* fill result resultbuf */ 200290001Sglebius memcpy(resultbuf, datap, dsize); 201290001Sglebius 202290001Sglebius return dsize; 203290001Sglebius} 204290001Sglebius 205290001Sglebius 206290001Sglebius 207290001Sglebius/***************************************************************************** 208290001Sglebius * 209290001Sglebius * ntpq_openhost 210290001Sglebius * 211290001Sglebius * Sets up a connection to the ntpd instance of a specified host. Note: 212290001Sglebius * There is no real "connection" established because NTP solely works 213290001Sglebius * based on UDP. 214290001Sglebius * 215290001Sglebius **************************************************************************** 216290001Sglebius * Parameters: 217290001Sglebius * hostname char* Hostname/IP of the host running ntpd 218290001Sglebius * fam int Address Family (AF_INET, AF_INET6, or 0) 219290001Sglebius * 220290001Sglebius * Returns: 221290001Sglebius * int 1 if the host connection could be set up, i.e. 222290001Sglebius * name resolution was succesful and/or IP address 223290001Sglebius * has been validated 224290001Sglebius * - OR - 225290001Sglebius * 0 (zero) if a failure occured 226290001Sglebius ****************************************************************************/ 227290001Sglebius 228290001Sglebiusint 229290001Sglebiusntpq_openhost( 230290001Sglebius char *hostname, 231290001Sglebius int fam 232290001Sglebius ) 233290001Sglebius{ 234290001Sglebius if ( openhost(hostname, fam) ) 235290001Sglebius { 236290001Sglebius numhosts = 1; 237290001Sglebius } else { 238290001Sglebius numhosts = 0; 239290001Sglebius } 240290001Sglebius 241290001Sglebius return numhosts; 242290001Sglebius 243290001Sglebius} 244290001Sglebius 245290001Sglebius 246290001Sglebius/***************************************************************************** 247290001Sglebius * 248290001Sglebius * ntpq_closehost 249290001Sglebius * 250290001Sglebius * Cleans up a connection by closing the used socket. Should be called 251290001Sglebius * when no further queries are required for the currently used host. 252290001Sglebius * 253290001Sglebius **************************************************************************** 254290001Sglebius * Parameters: 255290001Sglebius * - none - 256290001Sglebius * 257290001Sglebius * Returns: 258290001Sglebius * int 0 (zero) if no host has been opened before 259290001Sglebius * - OR - 260290001Sglebius * the resultcode from the closesocket function call 261290001Sglebius ****************************************************************************/ 262290001Sglebius 263290001Sglebiusint ntpq_closehost(void) 264290001Sglebius{ 265290001Sglebius if ( numhosts ) 266290001Sglebius return closesocket(sockfd); 267290001Sglebius 268290001Sglebius return 0; 269290001Sglebius} 270290001Sglebius 271290001Sglebius 272290001Sglebius/***************************************************************************** 273290001Sglebius * 274290001Sglebius * ntpq_read_associations 275290001Sglebius * 276290001Sglebius * This function queries the ntp host for its associations and returns the 277290001Sglebius * number of associations found. 278290001Sglebius * 279290001Sglebius * It takes an u_short array as its first parameter, this array holds the 280290001Sglebius * IDs of the associations, 281290001Sglebius * the function will not write more entries than specified with the 282290001Sglebius * max_entries parameter. 283290001Sglebius * 284290001Sglebius * However, if more than max_entries associations were found, the return 285290001Sglebius * value of this function will reflect the real number, even if not all 286290001Sglebius * associations have been stored in the array. 287290001Sglebius * 288290001Sglebius **************************************************************************** 289290001Sglebius * Parameters: 290290001Sglebius * resultbuf u_short*Array that should hold the list of 291290001Sglebius * association IDs 292290001Sglebius * maxentries int maximum number of association IDs that can 293290001Sglebius * be stored in resultbuf 294290001Sglebius * 295290001Sglebius * Returns: 296290001Sglebius * int number of association IDs stored in resultbuf 297290001Sglebius * - OR - 298290001Sglebius * 0 (zero) if a failure occured or no association has 299290001Sglebius * been returned. 300290001Sglebius ****************************************************************************/ 301290001Sglebius 302290001Sglebius int ntpq_read_associations ( u_short resultbuf[], int max_entries ) 303290001Sglebius{ 304290001Sglebius int i = 0; 305290001Sglebius 306290001Sglebius if (ntpq_dogetassoc()) { 307290001Sglebius 308290001Sglebius if(numassoc < max_entries) 309290001Sglebius max_entries = numassoc; 310290001Sglebius 311290001Sglebius for (i=0;i<max_entries;i++) 312290001Sglebius resultbuf[i] = assoc_cache[i].assid; 313290001Sglebius 314290001Sglebius return numassoc; 315290001Sglebius } 316290001Sglebius 317290001Sglebius return 0; 318290001Sglebius} 319290001Sglebius 320290001Sglebius 321290001Sglebius 322290001Sglebius 323290001Sglebius/***************************************************************************** 324290001Sglebius * 325290001Sglebius * ntpq_get_assocs 326290001Sglebius * 327290001Sglebius * This function reads the associations of a previously selected (with 328290001Sglebius * ntpq_openhost) NTP host into its own (global) array and returns the 329290001Sglebius * number of associations found. 330290001Sglebius * 331290001Sglebius * The obtained association IDs can be read by using the ntpq_get_assoc_id 332290001Sglebius * function. 333290001Sglebius * 334290001Sglebius **************************************************************************** 335290001Sglebius * Parameters: 336290001Sglebius * - none - 337290001Sglebius * 338290001Sglebius * Returns: 339290001Sglebius * int number of association IDs stored in resultbuf 340290001Sglebius * - OR - 341290001Sglebius * 0 (zero) if a failure occured or no association has 342290001Sglebius * been returned. 343290001Sglebius ****************************************************************************/ 344290001Sglebius 345290001Sglebius int ntpq_get_assocs ( void ) 346290001Sglebius{ 347290001Sglebius return ntpq_read_associations( ntpq_associations, MAXASSOC ); 348290001Sglebius} 349290001Sglebius 350290001Sglebius 351290001Sglebius/***************************************************************************** 352290001Sglebius * 353290001Sglebius * ntpq_get_assoc_number 354290001Sglebius * 355290001Sglebius * This function returns for a given Association ID the association number 356290001Sglebius * in the internal association array, which is filled by the ntpq_get_assocs 357290001Sglebius * function. 358290001Sglebius * 359290001Sglebius **************************************************************************** 360290001Sglebius * Parameters: 361290001Sglebius * associd int requested associaton ID 362290001Sglebius * 363290001Sglebius * Returns: 364290001Sglebius * int the number of the association array element that is 365290001Sglebius * representing the given association ID 366290001Sglebius * - OR - 367290001Sglebius * -1 if a failure occured or no matching association 368290001Sglebius * ID has been found 369290001Sglebius ****************************************************************************/ 370290001Sglebius 371290001Sglebiusint ntpq_get_assoc_number ( associd_t associd ) 372290001Sglebius{ 373290001Sglebius int i; 374290001Sglebius 375290001Sglebius for (i=0;i<numassoc;i++) { 376290001Sglebius if (assoc_cache[i].assid == associd) 377290001Sglebius return i; 378290001Sglebius } 379290001Sglebius 380290001Sglebius return -1; 381290001Sglebius 382290001Sglebius} 383290001Sglebius 384290001Sglebius 385290001Sglebius/***************************************************************************** 386290001Sglebius * 387290001Sglebius * ntpq_read_assoc_peervars 388290001Sglebius * 389290001Sglebius * This function reads the peervars variable-set of a specified association 390290001Sglebius * from a NTP host and writes it to the result buffer specified, honoring 391290001Sglebius * the maxsize limit. 392290001Sglebius * 393290001Sglebius * It returns the number of bytes written or 0 when the variable-set is 394290001Sglebius * empty or failed to read. 395290001Sglebius * 396290001Sglebius **************************************************************************** 397290001Sglebius * Parameters: 398290001Sglebius * associd int requested associaton ID 399290001Sglebius * resultbuf char* character buffer where the variable set 400290001Sglebius * should be stored 401290001Sglebius * maxsize int the maximum number of bytes that can be 402290001Sglebius * written to resultbuf 403290001Sglebius * 404290001Sglebius * Returns: 405290001Sglebius * int number of chars that have been copied to 406290001Sglebius * resultbuf 407290001Sglebius * - OR - 408290001Sglebius * 0 (zero) if an error occured 409290001Sglebius ****************************************************************************/ 410290001Sglebius 411290001Sglebiusint 412290001Sglebiusntpq_read_assoc_peervars( 413290001Sglebius associd_t associd, 414290001Sglebius char * resultbuf, 415290001Sglebius int maxsize 416290001Sglebius ) 417290001Sglebius{ 418290001Sglebius const char * datap; 419290001Sglebius int res; 420293896Sglebius size_t dsize; 421290001Sglebius u_short rstatus; 422290001Sglebius 423290001Sglebius res = doquery(CTL_OP_READVAR, associd, 0, 0, NULL, &rstatus, 424290001Sglebius &dsize, &datap); 425290001Sglebius if (res != 0) 426290001Sglebius return 0; 427290001Sglebius if (dsize <= 0) { 428290001Sglebius if (numhosts > 1) 429290001Sglebius fprintf(stderr, "server=%s ", currenthost); 430290001Sglebius fprintf(stderr, 431290001Sglebius "***No information returned for association %d\n", 432290001Sglebius associd); 433290001Sglebius 434290001Sglebius return 0; 435290001Sglebius } 436290001Sglebius if (dsize > maxsize) 437290001Sglebius dsize = maxsize; 438290001Sglebius memcpy(resultbuf, datap, dsize); 439290001Sglebius 440290001Sglebius return dsize; 441290001Sglebius} 442290001Sglebius 443290001Sglebius 444290001Sglebius 445290001Sglebius 446290001Sglebius/***************************************************************************** 447290001Sglebius * 448290001Sglebius * ntpq_read_sysvars 449290001Sglebius * 450290001Sglebius * This function reads the sysvars variable-set from a NTP host and writes it 451290001Sglebius * to the result buffer specified, honoring the maxsize limit. 452290001Sglebius * 453290001Sglebius * It returns the number of bytes written or 0 when the variable-set is empty 454290001Sglebius * or could not be read. 455290001Sglebius * 456290001Sglebius **************************************************************************** 457290001Sglebius * Parameters: 458290001Sglebius * resultbuf char* character buffer where the variable set 459290001Sglebius * should be stored 460290001Sglebius * maxsize int the maximum number of bytes that can be 461290001Sglebius * written to resultbuf 462290001Sglebius * 463290001Sglebius * Returns: 464290001Sglebius * int number of chars that have been copied to 465290001Sglebius * resultbuf 466290001Sglebius * - OR - 467290001Sglebius * 0 (zero) if an error occured 468290001Sglebius ****************************************************************************/ 469290001Sglebiussize_t 470290001Sglebiusntpq_read_sysvars( 471290001Sglebius char * resultbuf, 472290001Sglebius size_t maxsize 473290001Sglebius ) 474290001Sglebius{ 475290001Sglebius const char * datap; 476290001Sglebius int res; 477290001Sglebius size_t dsize; 478290001Sglebius u_short rstatus; 479290001Sglebius 480290001Sglebius res = doquery(CTL_OP_READVAR, 0, 0, 0, NULL, &rstatus, 481293896Sglebius &dsize, &datap); 482290001Sglebius 483290001Sglebius if (res != 0) 484290001Sglebius return 0; 485290001Sglebius 486293896Sglebius if (dsize == 0) { 487290001Sglebius if (numhosts > 1) 488290001Sglebius fprintf(stderr, "server=%s ", currenthost); 489290001Sglebius fprintf(stderr, "***No sysvar information returned\n"); 490290001Sglebius 491290001Sglebius return 0; 492290001Sglebius } else { 493290001Sglebius dsize = min(dsize, maxsize); 494290001Sglebius memcpy(resultbuf, datap, dsize); 495290001Sglebius } 496290001Sglebius 497290001Sglebius return dsize; 498290001Sglebius} 499290001Sglebius 500290001Sglebius 501290001Sglebius/***************************************************************************** 502290001Sglebius * ntpq_get_assoc_allvars 503290001Sglebius * 504290001Sglebius * With this function all association variables for the specified association 505290001Sglebius * ID can be requested from a NTP host. They are stored internally and can be 506290001Sglebius * read by using the ntpq_get_peervar or ntpq_get_clockvar functions. 507290001Sglebius * 508290001Sglebius * Basically this is only a combination of the ntpq_get_assoc_peervars and 509290001Sglebius * ntpq_get_assoc_clockvars functions. 510290001Sglebius * 511290001Sglebius * It returns 1 if both variable-sets (peervars and clockvars) were 512290001Sglebius * received successfully. If one variable-set or both of them weren't 513290001Sglebius * received, 514290001Sglebius * 515290001Sglebius **************************************************************************** 516290001Sglebius * Parameters: 517290001Sglebius * associd int requested associaton ID 518290001Sglebius * 519290001Sglebius * Returns: 520290001Sglebius * int nonzero if at least one variable set could be read 521290001Sglebius * - OR - 522290001Sglebius * 0 (zero) if an error occured and both variable sets 523290001Sglebius * could not be read 524290001Sglebius ****************************************************************************/ 525290001Sglebius int ntpq_get_assoc_allvars( associd_t associd ) 526290001Sglebius{ 527290001Sglebius return ntpq_get_assoc_peervars ( associd ) & 528290001Sglebius ntpq_get_assoc_clockvars( associd ); 529290001Sglebius} 530290001Sglebius 531290001Sglebius 532290001Sglebius 533290001Sglebius 534290001Sglebius/***************************************************************************** 535290001Sglebius * 536290001Sglebius * ntpq_get_sysvars 537290001Sglebius * 538290001Sglebius * The system variables of a NTP host can be requested by using this function 539290001Sglebius * and afterwards using ntpq_get_sysvar to read the single variable values. 540290001Sglebius * 541290001Sglebius **************************************************************************** 542290001Sglebius * Parameters: 543290001Sglebius * - none - 544290001Sglebius * 545290001Sglebius * Returns: 546290001Sglebius * int nonzero if the variable set could be read 547290001Sglebius * - OR - 548290001Sglebius * 0 (zero) if an error occured and the sysvars 549290001Sglebius * could not be read 550290001Sglebius ****************************************************************************/ 551290001Sglebiusint 552290001Sglebiusntpq_get_sysvars(void) 553290001Sglebius{ 554290001Sglebius sysvarlen = ntpq_read_sysvars(sysvars, sizeof(sysvars)); 555290001Sglebius if (sysvarlen <= 0) 556290001Sglebius return 0; 557290001Sglebius else 558290001Sglebius return 1; 559290001Sglebius} 560290001Sglebius 561290001Sglebius 562290001Sglebius/***************************************************************************** 563290001Sglebius * 564290001Sglebius * ntp_get_peervar 565290001Sglebius * 566290001Sglebius * This function uses the variable-set which was read by using 567290001Sglebius * ntp_get_peervars and searches for a variable specified with varname. If 568290001Sglebius * such a variable exists, it writes its value into 569290001Sglebius * varvalue (maxlen specifies the size of this target buffer). 570290001Sglebius * 571290001Sglebius **************************************************************************** 572290001Sglebius * Parameters: 573290001Sglebius * varname char* requested variable name 574290001Sglebius * varvalue char* the buffer where the value should go into 575290001Sglebius * maxlen int maximum number of bytes that can be copied to 576290001Sglebius * varvalue 577290001Sglebius * 578290001Sglebius * Returns: 579290001Sglebius * int number of bytes copied to varvalue 580290001Sglebius * - OR - 581290001Sglebius * 0 (zero) if an error occured or the variable could 582290001Sglebius * not be found 583290001Sglebius ****************************************************************************/ 584290001Sglebiusint ntpq_get_peervar( const char *varname, char *varvalue, int maxlen) 585290001Sglebius{ 586290001Sglebius return ( ntpq_getvar(peervars,peervarlen,varname,varvalue,maxlen) ); 587290001Sglebius} 588290001Sglebius 589290001Sglebius 590290001Sglebius 591290001Sglebius/***************************************************************************** 592290001Sglebius * 593290001Sglebius * ntpq_get_assoc_peervars 594290001Sglebius * 595290001Sglebius * This function requests the peer variables of the specified association 596290001Sglebius * from a NTP host. In order to access the variable values, the function 597290001Sglebius * ntpq_get_peervar must be used. 598290001Sglebius * 599290001Sglebius **************************************************************************** 600290001Sglebius * Parameters: 601290001Sglebius * associd int requested associaton ID 602290001Sglebius * 603290001Sglebius * Returns: 604290001Sglebius * int 1 (one) if the peervars have been read 605290001Sglebius * - OR - 606290001Sglebius * 0 (zero) if an error occured and the variable set 607290001Sglebius * could not be read 608290001Sglebius ****************************************************************************/ 609290001Sglebiusint 610290001Sglebiusntpq_get_assoc_peervars( 611290001Sglebius associd_t associd 612290001Sglebius ) 613290001Sglebius{ 614290001Sglebius peervarlen = ntpq_read_assoc_peervars(associd, peervars, 615290001Sglebius sizeof(peervars)); 616290001Sglebius if (peervarlen <= 0) { 617290001Sglebius peervar_assoc = 0; 618290001Sglebius 619290001Sglebius return 0; 620290001Sglebius } 621290001Sglebius peervar_assoc = associd; 622290001Sglebius 623290001Sglebius return 1; 624290001Sglebius} 625290001Sglebius 626290001Sglebius 627290001Sglebius/***************************************************************************** 628290001Sglebius * 629290001Sglebius * ntp_read_assoc_clockvars 630290001Sglebius * 631290001Sglebius * This function reads the clockvars variable-set of a specified association 632290001Sglebius * from a NTP host and writes it to the result buffer specified, honoring 633290001Sglebius * the maxsize limit. 634290001Sglebius * 635290001Sglebius * It returns the number of bytes written or 0 when the variable-set is 636290001Sglebius * empty or failed to read. 637290001Sglebius * 638290001Sglebius **************************************************************************** 639290001Sglebius * Parameters: 640290001Sglebius * associd int requested associaton ID 641290001Sglebius * resultbuf char* character buffer where the variable set 642290001Sglebius * should be stored 643290001Sglebius * maxsize int the maximum number of bytes that can be 644290001Sglebius * written to resultbuf 645290001Sglebius * 646290001Sglebius * Returns: 647290001Sglebius * int number of chars that have been copied to 648290001Sglebius * resultbuf 649290001Sglebius * - OR - 650290001Sglebius * 0 (zero) if an error occured 651290001Sglebius ****************************************************************************/ 652290001Sglebius 653290001Sglebiusint 654290001Sglebiusntpq_read_assoc_clockvars( 655290001Sglebius associd_t associd, 656290001Sglebius char * resultbuf, 657290001Sglebius int maxsize 658290001Sglebius ) 659290001Sglebius{ 660290001Sglebius const char *datap; 661290001Sglebius int res; 662293896Sglebius size_t dsize; 663290001Sglebius u_short rstatus; 664290001Sglebius 665290001Sglebius res = ntpq_doquerylist(ntpq_varlist, CTL_OP_READCLOCK, associd, 666290001Sglebius 0, &rstatus, &dsize, &datap); 667290001Sglebius if (res != 0) 668290001Sglebius return 0; 669290001Sglebius 670290001Sglebius if (dsize == 0) { 671290001Sglebius if (numhosts > 1) /* no information returned from server */ 672290001Sglebius return 0; 673290001Sglebius } else { 674290001Sglebius if (dsize > maxsize) 675290001Sglebius dsize = maxsize; 676290001Sglebius memcpy(resultbuf, datap, dsize); 677290001Sglebius } 678290001Sglebius 679290001Sglebius return dsize; 680290001Sglebius} 681290001Sglebius 682290001Sglebius 683290001Sglebius 684290001Sglebius/***************************************************************************** 685290001Sglebius * 686290001Sglebius * ntpq_get_assoc_clocktype 687290001Sglebius * 688290001Sglebius * This function returns a clocktype value for a given association number 689290001Sglebius * (not ID!): 690290001Sglebius * 691290001Sglebius * NTP_CLOCKTYPE_UNKNOWN Unknown clock type 692290001Sglebius * NTP_CLOCKTYPE_BROADCAST Broadcast server 693290001Sglebius * NTP_CLOCKTYPE_LOCAL Local clock 694290001Sglebius * NTP_CLOCKTYPE_UNICAST Unicast server 695290001Sglebius * NTP_CLOCKTYPE_MULTICAST Multicast server 696290001Sglebius * 697290001Sglebius ****************************************************************************/ 698290001Sglebiusint 699290001Sglebiusntpq_get_assoc_clocktype( 700290001Sglebius int assoc_index 701290001Sglebius ) 702290001Sglebius{ 703290001Sglebius associd_t associd; 704290001Sglebius int i; 705290001Sglebius int rc; 706290001Sglebius sockaddr_u dum_store; 707290001Sglebius char dstadr[LENHOSTNAME]; 708290001Sglebius char resultbuf[NTPQ_BUFLEN]; 709290001Sglebius 710290001Sglebius if (assoc_index < 0 || assoc_index >= numassoc) 711290001Sglebius return -1; 712290001Sglebius 713290001Sglebius associd = assoc_cache[assoc_index].assid; 714290001Sglebius if (associd == peervar_assoc) { 715290001Sglebius rc = ntpq_get_peervar("dstadr", dstadr, sizeof(dstadr)); 716290001Sglebius } else { 717290001Sglebius i = ntpq_read_assoc_peervars(associd, resultbuf, 718290001Sglebius sizeof(resultbuf)); 719290001Sglebius if (i <= 0) 720290001Sglebius return -1; 721290001Sglebius rc = ntpq_getvar(resultbuf, i, "dstadr", dstadr, 722290001Sglebius sizeof(dstadr)); 723290001Sglebius } 724290001Sglebius 725290001Sglebius if (0 != rc && decodenetnum(dstadr, &dum_store)) 726290001Sglebius return ntpq_decodeaddrtype(&dum_store); 727290001Sglebius 728290001Sglebius return -1; 729290001Sglebius} 730290001Sglebius 731290001Sglebius 732290001Sglebius 733290001Sglebius/***************************************************************************** 734290001Sglebius * 735290001Sglebius * ntpq_get_assoc_clockvars 736290001Sglebius * 737290001Sglebius * With this function the clock variables of the specified association are 738290001Sglebius * requested from a NTP host. This makes only sense for associations with 739290001Sglebius * the type 'l' (Local Clock) and you should check this with 740290001Sglebius * ntpq_get_assoc_clocktype for each association, before you use this function 741290001Sglebius * on it. 742290001Sglebius * 743290001Sglebius **************************************************************************** 744290001Sglebius * Parameters: 745290001Sglebius * associd int requested associaton ID 746290001Sglebius * 747290001Sglebius * Returns: 748290001Sglebius * int 1 (one) if the clockvars have been read 749290001Sglebius * - OR - 750290001Sglebius * 0 (zero) if an error occured and the variable set 751290001Sglebius * could not be read 752290001Sglebius ****************************************************************************/ 753290001Sglebiusint ntpq_get_assoc_clockvars( associd_t associd ) 754290001Sglebius{ 755290001Sglebius if (NTP_CLOCKTYPE_LOCAL != ntpq_get_assoc_clocktype( 756290001Sglebius ntpq_get_assoc_number(associd))) 757290001Sglebius return 0; 758290001Sglebius clockvarlen = ntpq_read_assoc_clockvars( associd, clockvars, 759290001Sglebius sizeof(clockvars) ); 760290001Sglebius if ( clockvarlen <= 0 ) { 761290001Sglebius clockvar_assoc = 0; 762290001Sglebius return 0; 763290001Sglebius } else { 764290001Sglebius clockvar_assoc = associd; 765290001Sglebius return 1; 766290001Sglebius } 767290001Sglebius} 768290001Sglebius 769290001Sglebius 770