Back to index

nagios-plugins  1.4.16
Classes | Defines | Functions | Variables
check_ntp.c File Reference
#include "common.h"
#include "netutils.h"
#include "utils.h"

Go to the source code of this file.


struct  ntp_message
struct  ntp_server_results
struct  ntp_control_message
struct  ntp_assoc_status_pair


#define AVG_NUM   4
#define MAX_CM_SIZE   468
#define LI_MASK   0xc0
#define LI(x)   ((x&LI_MASK)>>6)
#define LI_SET(x, y)   do{ x |= ((y<<6)&LI_MASK); }while(0)
#define LI_NOWARNING   0x00
#define LI_EXTRASEC   0x01
#define LI_MISSINGSEC   0x02
#define LI_ALARM   0x03
#define VN_MASK   0x38
#define VN(x)   ((x&VN_MASK)>>3)
#define VN_SET(x, y)   do{ x |= ((y<<3)&VN_MASK); }while(0)
#define VN_RESERVED   0x02
#define MODE_MASK   0x07
#define MODE(x)   (x&MODE_MASK)
#define MODE_SET(x, y)   do{ x |= (y&MODE_MASK); }while(0)
#define MODE_CLIENT   0x03
#define MODE_CONTROLMSG   0x06
#define REM_MASK   0xe0
#define REM_RESP   0x80
#define REM_ERROR   0x40
#define REM_MORE   0x20
#define OP_MASK   0x1f
#define OP_SET(x, y)   do{ x |= (y&OP_MASK); }while(0)
#define OP_READSTAT   0x01
#define OP_READVAR   0x02
#define PEER_SEL(x)   ((ntohs(x)>>8)&0x07)
#define PEER_INCLUDED   0x04
#define PEER_SYNCSOURCE   0x06
#define L16(x)   (((uint16_t*)&x)[0])
 a note about the 32-bit "fixed point" numbers:
#define R16(x)   (((uint16_t*)&x)[1])
#define L32(x)   (((uint32_t*)&x)[0])
#define R32(x)   (((uint32_t*)&x)[1])
#define EPOCHDIFF   0x83aa7e80UL
#define NTP32asDOUBLE(x)   (ntohs(L16(x)) + (double)ntohs(R16(x))/65536.0)
#define NTP64asDOUBLE(n)
#define TVasDOUBLE(x)   (double)(x.tv_sec+(0.000001*x.tv_usec))
#define NTP64toTV(n, t)
#define TVtoNTP64(t, n)
#define SIZEOF_NTPCM(m)   (12+ntohs(m.count)+((ntohs(m.count)%4)?4-(ntohs(m.count)%4):0))
#define DBG(x)   do{if(verbose>1){ x; }}while(0);


int process_arguments (int, char **)
void print_help (void)
void print_usage (void)
static double calc_offset (const ntp_message *m, const struct timeval *t)
void print_ntp_message (const ntp_message *p)
void print_ntp_control_message (const ntp_control_message *p)
void setup_request (ntp_message *p)
int best_offset_server (const ntp_server_results *slist, int nservers)
double offset_request (const char *host, int *status)
void setup_control_request (ntp_control_message *p, uint8_t opcode, uint16_t seq)
double jitter_request (const char *host, int *status)
char * perfd_offset (double offset)
char * perfd_jitter (double jitter)
int main (int argc, char *argv[])


const char * progname = "check_ntp"
const char * copyright = "2006-2008"
const char * email = ""
static char * server_address = NULL
static int verbose = 0
static short do_offset = 0
static char * owarn = "60"
static char * ocrit = "120"
static short do_jitter = 0
static char * jwarn = "5000"
static char * jcrit = "10000"
thresholdsoffset_thresholds = NULL
thresholdsjitter_thresholds = NULL

Class Documentation

struct ntp_message

Definition at line 63 of file check_ntp.c.

Class Members
uint8_t flags
uint64_t origts
int8_t poll
int8_t precision
uint32_t refid
uint64_t refts
int32_t rtdelay
uint32_t rtdisp
uint64_t rxts
uint8_t stratum
uint64_t txts
struct ntp_server_results

Definition at line 78 of file check_ntp.c.

Class Members
uint8_t flags
int num_responses
double offset
double rtdelay
double rtdisp
uint8_t stratum
time_t waiting
struct ntp_control_message

Definition at line 89 of file check_ntp.c.

Class Members
uint16_t assoc
uint16_t count
char data
uint8_t flags
uint16_t offset
uint8_t op
uint16_t seq
uint16_t status
struct ntp_assoc_status_pair

Definition at line 102 of file check_ntp.c.

Class Members
uint16_t assoc
uint16_t status

Define Documentation

#define AVG_NUM   4

Definition at line 57 of file check_ntp.c.

#define DBG (   x)    do{if(verbose>1){ x; }}while(0);

Definition at line 200 of file check_ntp.c.

#define EPOCHDIFF   0x83aa7e80UL

Definition at line 162 of file check_ntp.c.

#define L16 (   x)    (((uint16_t*)&x)[0])

a note about the 32-bit "fixed point" numbers:

they are divided into halves, each being a 16-bit int in network byte order:

  • the first 16 bits are an int on the left side of a decimal point.
  • the second 16 bits represent a fraction n/(2^16) likewise for the 64-bit "fixed point" numbers with everything doubled :)

Definition at line 154 of file check_ntp.c.

#define L32 (   x)    (((uint32_t*)&x)[0])

Definition at line 158 of file check_ntp.c.

#define LI (   x)    ((x&LI_MASK)>>6)

Definition at line 109 of file check_ntp.c.

#define LI_ALARM   0x03

Definition at line 115 of file check_ntp.c.

#define LI_EXTRASEC   0x01

Definition at line 113 of file check_ntp.c.

#define LI_MASK   0xc0

Definition at line 108 of file check_ntp.c.

#define LI_MISSINGSEC   0x02

Definition at line 114 of file check_ntp.c.

#define LI_NOWARNING   0x00

Definition at line 112 of file check_ntp.c.

#define LI_SET (   x,
)    do{ x |= ((y<<6)&LI_MASK); }while(0)

Definition at line 110 of file check_ntp.c.

#define MAX_CM_SIZE   468

Definition at line 60 of file check_ntp.c.

#define MODE (   x)    (x&MODE_MASK)

Definition at line 123 of file check_ntp.c.

#define MODE_CLIENT   0x03

Definition at line 126 of file check_ntp.c.

#define MODE_CONTROLMSG   0x06

Definition at line 127 of file check_ntp.c.

#define MODE_MASK   0x07

Definition at line 122 of file check_ntp.c.

#define MODE_SET (   x,
)    do{ x |= (y&MODE_MASK); }while(0)

Definition at line 124 of file check_ntp.c.

#define NTP32asDOUBLE (   x)    (ntohs(L16(x)) + (double)ntohs(R16(x))/65536.0)

Definition at line 165 of file check_ntp.c.

#define NTP64asDOUBLE (   n)
                         (ntohl(L32(n))-EPOCHDIFF) + \

Definition at line 168 of file check_ntp.c.

#define NTP64toTV (   n,
do{ if(!n) t.tv_sec = t.tv_usec = 0; \
           else { \
                     t.tv_sec=ntohl(L32(n))-EPOCHDIFF; \
                     t.tv_usec=(int)(0.5+(double)(ntohl(R32(n))/4294.967296)); \
              } \

Definition at line 177 of file check_ntp.c.

#define OP_MASK   0x1f

Definition at line 134 of file check_ntp.c.

#define OP_READSTAT   0x01

Definition at line 136 of file check_ntp.c.

#define OP_READVAR   0x02

Definition at line 137 of file check_ntp.c.

#define OP_SET (   x,
)    do{ x |= (y&OP_MASK); }while(0)

Definition at line 135 of file check_ntp.c.

#define PEER_INCLUDED   0x04

Definition at line 140 of file check_ntp.c.

#define PEER_SEL (   x)    ((ntohs(x)>>8)&0x07)

Definition at line 139 of file check_ntp.c.

#define PEER_SYNCSOURCE   0x06

Definition at line 141 of file check_ntp.c.

#define PRINTSOCKADDR (   x)
do{ \
              printf("%u.%u.%u.%u", (x>>24)&0xff, (x>>16)&0xff, (x>>8)&0xff, x&0xff);\

Definition at line 201 of file check_ntp.c.

#define R16 (   x)    (((uint16_t*)&x)[1])

Definition at line 155 of file check_ntp.c.

#define R32 (   x)    (((uint32_t*)&x)[1])

Definition at line 159 of file check_ntp.c.

#define REM_ERROR   0x40

Definition at line 131 of file check_ntp.c.

#define REM_MASK   0xe0

Definition at line 129 of file check_ntp.c.

#define REM_MORE   0x20

Definition at line 132 of file check_ntp.c.

#define REM_RESP   0x80

Definition at line 130 of file check_ntp.c.

#define SIZEOF_NTPCM (   m)    (12+ntohs(m.count)+((ntohs(m.count)%4)?4-(ntohs(m.count)%4):0))

Definition at line 197 of file check_ntp.c.

#define TVasDOUBLE (   x)    (double)(x.tv_sec+(0.000001*x.tv_usec))

Definition at line 174 of file check_ntp.c.

#define TVtoNTP64 (   t,
do{ if(!t.tv_usec && !t.tv_sec) n=0x0UL; \
              else { \
                     L32(n)=htonl(t.tv_sec + EPOCHDIFF); \
                     R32(n)=htonl((uint64_t)((4294.967296*t.tv_usec)+.5)); \
              } \
       } while(0)

Definition at line 186 of file check_ntp.c.

#define VN (   x)    ((x&VN_MASK)>>3)

Definition at line 118 of file check_ntp.c.

#define VN_MASK   0x38

Definition at line 117 of file check_ntp.c.

#define VN_RESERVED   0x02

Definition at line 120 of file check_ntp.c.

#define VN_SET (   x,
)    do{ x |= ((y<<3)&VN_MASK); }while(0)

Definition at line 119 of file check_ntp.c.

Function Documentation

int best_offset_server ( const ntp_server_results slist,
int  nservers 

Definition at line 297 of file check_ntp.c.

       int i=0, cserver=0, best_server=-1;

       /* for each server */
       for(cserver=0; cserver<nservers; cserver++){
              /* We don't want any servers that fails these tests */
              /* Sort out servers that didn't respond or responede with a 0 stratum;
               * stratum 0 is for reference clocks so no NTP server should ever report
               * a stratum 0 */
              if ( slist[cserver].stratum == 0){
                     if (verbose) printf("discarding peer %d: stratum=%d\n", cserver, slist[cserver].stratum);
              /* Sort out servers with error flags */
              if ( LI(slist[cserver].flags) == LI_ALARM ){
                     if (verbose) printf("discarding peer %d: flags=%d\n", cserver, LI(slist[cserver].flags));

              /* If we don't have a server yet, use the first one */
              if (best_server == -1) {
                     best_server = cserver;
                     DBG(printf("using peer %d as our first candidate\n", best_server));

              /* compare the server to the best one we've seen so far */
              /* does it have an equal or better stratum? */
              DBG(printf("comparing peer %d with peer %d\n", cserver, best_server));
              if(slist[cserver].stratum <= slist[best_server].stratum){
                     DBG(printf("stratum for peer %d <= peer %d\n", cserver, best_server));
                     /* does it have an equal or better dispersion? */
                     if(slist[cserver].rtdisp <= slist[best_server].rtdisp){
                            DBG(printf("dispersion for peer %d <= peer %d\n", cserver, best_server));
                            /* does it have a better rtdelay? */
                            if(slist[cserver].rtdelay < slist[best_server].rtdelay){
                                   DBG(printf("rtdelay for peer %d < peer %d\n", cserver, best_server));
                                   best_server = cserver;
                                   DBG(printf("peer %d is now our best candidate\n", best_server));

       if(best_server >= 0) {
              DBG(printf("best server selected: peer %d\n", best_server));
              return best_server;
       } else {
              DBG(printf("no peers meeting synchronization criteria :(\n"));
              return -1;

Here is the caller graph for this function:

static double calc_offset ( const ntp_message m,
const struct timeval t 
) [inline, static]

Definition at line 207 of file check_ntp.c.

       double client_tx, peer_rx, peer_tx, client_rx;
       client_tx = NTP64asDOUBLE(m->origts);
       peer_rx = NTP64asDOUBLE(m->rxts);
       peer_tx = NTP64asDOUBLE(m->txts);
       return (.5*((peer_tx-client_rx)+(peer_rx-client_tx)));

Here is the caller graph for this function:

double jitter_request ( const char *  host,
int *  status 

Definition at line 511 of file check_ntp.c.

       int conn=-1, i, npeers=0, num_candidates=0, syncsource_found=0;
       int run=0, min_peer_sel=PEER_INCLUDED, num_selected=0, num_valid=0;
       int peers_size=0, peer_offset=0;
       ntp_assoc_status_pair *peers=NULL;
       ntp_control_message req;
       const char *getvar = "jitter";
       double rval = 0.0, jitter = -1.0;
       char *startofvalue=NULL, *nptr=NULL;
       void *tmp;

       /* Long-winded explanation:
        * Getting the jitter requires a number of steps:
        * 1) Send a READSTAT request.
        * 2) Interpret the READSTAT reply
        *  a) The data section contains a list of peer identifiers (16 bits)
        *     and associated status words (16 bits)
        *  b) We want the value of 0x06 in the SEL (peer selection) value,
        *     which means "current synchronizatin source".  If that's missing,
        *     we take anything better than 0x04 (see the rfc for details) but
        *     set a minimum of warning.
        * 3) Send a READVAR request for information on each peer identified
        *    in 2b greater than the minimum selection value.
        * 4) Extract the jitter value from the data[] (it's ASCII)
       my_udp_connect(server_address, 123, &conn);

       /* keep sending requests until the server stops setting the
        * REM_MORE bit, though usually this is only 1 packet. */
              setup_control_request(&req, OP_READSTAT, 1);
              DBG(printf("sending READSTAT request"));
              write(conn, &req, SIZEOF_NTPCM(req));
              /* Attempt to read the largest size packet possible */
              DBG(printf("recieving READSTAT response"))
              read(conn, &req, SIZEOF_NTPCM(req));
              /* Each peer identifier is 4 bytes in the data section, which
               * we represent as a ntp_assoc_status_pair datatype.
              if((tmp=realloc(peers, peers_size)) == NULL)
                     free(peers), die(STATE_UNKNOWN, "can not (re)allocate 'peers' buffer\n");
              memcpy((void*)((ptrdiff_t)peers+peer_offset), (void*), ntohs(req.count));
       } while(req.op&REM_MORE);

       /* first, let's find out if we have a sync source, or if there are
        * at least some candidates.  in the case of the latter we'll issue
        * a warning but go ahead with the check on them. */
       for (i = 0; i < npeers; i++){
              if (PEER_SEL(peers[i].status) >= PEER_INCLUDED){
                     if(PEER_SEL(peers[i].status) >= PEER_SYNCSOURCE){
       if(verbose) printf("%d candiate peers available\n", num_candidates);
       if(verbose && syncsource_found) printf("synchronization source found\n");
       if(! syncsource_found){
              *status = STATE_UNKNOWN;
              if(verbose) printf("warning: no synchronization source found\n");

       for (run=0; run<AVG_NUM; run++){
              if(verbose) printf("jitter run %d of %d\n", run+1, AVG_NUM);
              for (i = 0; i < npeers; i++){
                     /* Only query this server if it is the current sync source */
                     if (PEER_SEL(peers[i].status) >= min_peer_sel){
                            setup_control_request(&req, OP_READVAR, 2);
                            req.assoc = peers[i].assoc;
                            /* By spec, putting the variable name "jitter"  in the request
                             * should cause the server to provide _only_ the jitter value.
                             * thus reducing net traffic, guaranteeing us only a single
                             * datagram in reply, and making intepretation much simpler
                            /* Older servers doesn't know what jitter is, so if we get an
                             * error on the first pass we redo it with "dispersion" */
                            strncpy(, getvar, MAX_CM_SIZE-1);
                            req.count = htons(strlen(getvar));
                            DBG(printf("sending READVAR request...\n"));
                            write(conn, &req, SIZEOF_NTPCM(req));

                            req.count = htons(MAX_CM_SIZE);
                            DBG(printf("recieving READVAR response...\n"));
                            read(conn, &req, SIZEOF_NTPCM(req));

                            if(req.op&REM_ERROR && strstr(getvar, "jitter")) {
                                   if(verbose) printf("The 'jitter' command failed (old ntp server?)\nRestarting with 'dispersion'...\n");
                                   getvar = "dispersion";

                            /* get to the float value */
                            if(verbose) {
                                   printf("parsing jitter from peer %.2x: ", ntohs(peers[i].assoc));
                            startofvalue = strchr(, '=');
                            if(startofvalue != NULL) {
                                   jitter = strtod(startofvalue, &nptr);
                            if(startofvalue == NULL || startofvalue==nptr){
                                   printf("warning: unable to read server jitter response.\n");
                                   *status = STATE_UNKNOWN;
                            } else {
                                   if(verbose) printf("%g\n", jitter);
                                   rval += jitter;
                     printf("jitter parsed from %d/%d peers\n", num_valid, num_selected);

       rval = num_valid ? rval / num_valid : -1.0;

       if(peers!=NULL) free(peers);
       /* If we return -1.0, it means no synchronization source was found */
       return rval;

Here is the call graph for this function:

Here is the caller graph for this function:

int main ( int  argc,
char *  argv[] 

Definition at line 751 of file check_ntp.c.

       int result, offset_result, jitter_result;
       double offset=0, jitter=0;
       char *result_line, *perfdata_line;

       setlocale (LC_ALL, "");
       bindtextdomain (PACKAGE, LOCALEDIR);
       textdomain (PACKAGE);

       result = offset_result = jitter_result = STATE_OK;

       /* Parse extra opts if any */
       argv=np_extra_opts (&argc, argv, progname);

       if (process_arguments (argc, argv) == ERROR)
              usage4 (_("Could not parse arguments"));

       set_thresholds(&offset_thresholds, owarn, ocrit);
       set_thresholds(&jitter_thresholds, jwarn, jcrit);

       /* initialize alarm signal handling */
       signal (SIGALRM, socket_timeout_alarm_handler);

       /* set socket timeout */
       alarm (socket_timeout);

       offset = offset_request(server_address, &offset_result);
       /* check_ntp used to always return CRITICAL if offset_result == STATE_UNKNOWN.
        * Now we'll only do that is the offset thresholds were set */
       if (do_offset && offset_result == STATE_UNKNOWN) {
              result = STATE_CRITICAL;
       } else {
              result = get_status(fabs(offset), offset_thresholds);

       /* If not told to check the jitter, we don't even send packets.
        * jitter is checked using NTP control packets, which not all
        * servers recognize.  Trying to check the jitter on OpenNTPD
        * (for example) will result in an error
              jitter=jitter_request(server_address, &jitter_result);
              result = max_state_alt(result, get_status(jitter, jitter_thresholds));
              /* -1 indicates that we couldn't calculate the jitter
               * Only overrides STATE_OK from the offset */
              if(jitter == -1.0 && result == STATE_OK)
                     result = STATE_UNKNOWN;
       result = max_state_alt(result, jitter_result);

       switch (result) {
              case STATE_CRITICAL :
                     asprintf(&result_line, _("NTP CRITICAL:"));
              case STATE_WARNING :
                     asprintf(&result_line, _("NTP WARNING:"));
              case STATE_OK :
                     asprintf(&result_line, _("NTP OK:"));
              default :
                     asprintf(&result_line, _("NTP UNKNOWN:"));
       if(offset_result == STATE_UNKNOWN){
              asprintf(&result_line, "%s %s", result_line, _("Offset unknown"));
              asprintf(&perfdata_line, "");
       } else {
              asprintf(&result_line, "%s %s %.10g secs", result_line, _("Offset"), offset);
              asprintf(&perfdata_line, "%s", perfd_offset(offset));
       if (do_jitter) {
              asprintf(&result_line, "%s, jitter=%f", result_line, jitter);
              asprintf(&perfdata_line, "%s %s", perfdata_line,  perfd_jitter(jitter));
       printf("%s|%s\n", result_line, perfdata_line);

       if(server_address!=NULL) free(server_address);
       return result;

Here is the call graph for this function:

double offset_request ( const char *  host,
int *  status 

Definition at line 355 of file check_ntp.c.

       int i=0, j=0, ga_result=0, num_hosts=0, *socklist=NULL, respnum=0;
       int servers_completed=0, one_written=0, one_read=0, servers_readable=0, best_index=-1;
       time_t now_time=0, start_ts=0;
       ntp_message *req=NULL;
       double avg_offset=0.;
       struct timeval recv_time;
       struct addrinfo *ai=NULL, *ai_tmp=NULL, hints;
       struct pollfd *ufds=NULL;
       ntp_server_results *servers=NULL;

       /* setup hints to only return results from getaddrinfo that we'd like */
       memset(&hints, 0, sizeof(struct addrinfo));
       hints.ai_family = address_family;
       hints.ai_protocol = IPPROTO_UDP;
       hints.ai_socktype = SOCK_DGRAM;

       /* fill in ai with the list of hosts resolved by the host name */
       ga_result = getaddrinfo(host, "123", &hints, &ai);
              die(STATE_UNKNOWN, "error getting address for %s: %s\n",
                  host, gai_strerror(ga_result));

       /* count the number of returned hosts, and allocate stuff accordingly */
       for(ai_tmp=ai; ai_tmp!=NULL; ai_tmp=ai_tmp->ai_next){ num_hosts++; }
       if(req==NULL) die(STATE_UNKNOWN, "can not allocate ntp message array");
       if(socklist==NULL) die(STATE_UNKNOWN, "can not allocate socket array");
       ufds=(struct pollfd*)malloc(sizeof(struct pollfd)*num_hosts);
       if(ufds==NULL) die(STATE_UNKNOWN, "can not allocate socket array");
       if(servers==NULL) die(STATE_UNKNOWN, "can not allocate server array");
       memset(servers, 0, sizeof(ntp_server_results)*num_hosts);
       DBG(printf("Found %d peers to check\n", num_hosts));

       /* setup each socket for writing, and the corresponding struct pollfd */
              socklist[i]=socket(ai_tmp->ai_family, SOCK_DGRAM, IPPROTO_UDP);
              if(socklist[i] == -1) {
                     die(STATE_UNKNOWN, "can not create new socket");
              if(connect(socklist[i], ai_tmp->ai_addr, ai_tmp->ai_addrlen)){
                     die(STATE_UNKNOWN, "can't create socket connection");
              } else {
              ai_tmp = ai_tmp->ai_next;

       /* now do AVG_NUM checks to each host.  we stop before timeout/2 seconds
        * have passed in order to ensure post-processing and jitter time. */
       while(servers_completed<num_hosts && now_time-start_ts <= socket_timeout/2){
              /* loop through each server and find each one which hasn't
               * been touched in the past second or so and is still lacking
               * some responses.  for each of these servers, send a new request,
               * and update the "waiting" timestamp with the current time. */

              for(i=0; i<num_hosts; i++){
                     if(servers[i].waiting<now_time && servers[i].num_responses<AVG_NUM){
                            if(verbose && servers[i].waiting != 0) printf("re-");
                            if(verbose) printf("sending request to peer %d\n", i);
                            write(socklist[i], &req[i], sizeof(ntp_message));

              /* quickly poll for any sockets with pending data */
              servers_readable=poll(ufds, num_hosts, 100);
                     perror("polling ntp sockets");
                     die(STATE_UNKNOWN, "communication errors");

              /* read from any sockets with pending data */
              for(i=0; servers_readable && i<num_hosts; i++){
                     if(ufds[i].revents&POLLIN && servers[i].num_responses < AVG_NUM){
                            if(verbose) {
                                   printf("response from peer %d: ", i);

                            read(ufds[i].fd, &req[i], sizeof(ntp_message));
                            gettimeofday(&recv_time, NULL);
                            servers[i].offset[respnum]=calc_offset(&req[i], &recv_time);
                            if(verbose) {
                                   printf("offset %.10g\n", servers[i].offset[respnum]);
                            one_read = 1;
                            if(servers[i].num_responses==AVG_NUM) servers_completed++;
              /* lather, rinse, repeat. */

       if (one_read == 0) {
              die(STATE_CRITICAL, "NTP CRITICAL: No response from NTP server\n");

       /* now, pick the best server from the list */
       best_index=best_offset_server(servers, num_hosts);
       if(best_index < 0){
       } else {
              /* finally, calculate the average offset */
              for(i=0; i<servers[best_index].num_responses;i++){

       /* cleanup */
       /* FIXME: Not closing the socket to avoid re-use of the local port
        * which can cause old NTP packets to be read instead of NTP control
        * pactets in jitter_request(). THERE MUST BE ANOTHER WAY...
        * for(j=0; j<num_hosts; j++){ close(socklist[j]); } */

       if(verbose) printf("overall average offset: %.10g\n", avg_offset);
       return avg_offset;

Here is the call graph for this function:

Here is the caller graph for this function:

char* perfd_jitter ( double  jitter)

Definition at line 743 of file check_ntp.c.

       return fperfdata ("jitter", jitter, "s",
              do_jitter, jitter_thresholds->warning->end,
              do_jitter, jitter_thresholds->critical->end,
              TRUE, 0, FALSE, 0);

Here is the call graph for this function:

Here is the caller graph for this function:

char* perfd_offset ( double  offset)

Definition at line 735 of file check_ntp.c.

       return fperfdata ("offset", offset, "s",
              TRUE, offset_thresholds->warning->end,
              TRUE, offset_thresholds->critical->end,
              FALSE, 0, FALSE, 0);

Here is the call graph for this function:

Here is the caller graph for this function:

void print_help ( void  )

Definition at line 242 of file check_ntp.c.

       int i=0, numpeers=0;
       const ntp_assoc_status_pair *peer=NULL;

       printf("control packet contents:\n");
       printf("\tflags: 0x%.2x , 0x%.2x\n", p->flags, p->op);
       printf("\t  li=%d (0x%.2x)\n", LI(p->flags), p->flags&LI_MASK);
       printf("\t  vn=%d (0x%.2x)\n", VN(p->flags), p->flags&VN_MASK);
       printf("\t  mode=%d (0x%.2x)\n", MODE(p->flags), p->flags&MODE_MASK);
       printf("\t  response=%d (0x%.2x)\n", (p->op&REM_RESP)>0, p->op&REM_RESP);
       printf("\t  more=%d (0x%.2x)\n", (p->op&REM_MORE)>0, p->op&REM_MORE);
       printf("\t  error=%d (0x%.2x)\n", (p->op&REM_ERROR)>0, p->op&REM_ERROR);
       printf("\t  op=%d (0x%.2x)\n", p->op&OP_MASK, p->op&OP_MASK);
       printf("\tsequence: %d (0x%.2x)\n", ntohs(p->seq), ntohs(p->seq));
       printf("\tstatus: %d (0x%.2x)\n", ntohs(p->status), ntohs(p->status));
       printf("\tassoc: %d (0x%.2x)\n", ntohs(p->assoc), ntohs(p->assoc));
       printf("\toffset: %d (0x%.2x)\n", ntohs(p->offset), ntohs(p->offset));
       printf("\tcount: %d (0x%.2x)\n", ntohs(p->count), ntohs(p->count));
       if(p->op&REM_RESP && p->op&OP_READSTAT){
                     printf("\tpeer id %.2x status %.2x",
                            ntohs(peer[i].assoc), ntohs(peer[i].status));
                     if (PEER_SEL(peer[i].status) >= PEER_INCLUDED){
                            if(PEER_SEL(peer[i].status) >= PEER_SYNCSOURCE){
                                   printf(" <-- current sync source");
                            } else {
                                   printf(" <-- current sync candidate");

Here is the caller graph for this function:

Definition at line 217 of file check_ntp.c.

       struct timeval ref, orig, rx, tx;


       printf("packet contents:\n");
       printf("\tflags: 0x%.2x\n", p->flags);
       printf("\t  li=%d (0x%.2x)\n", LI(p->flags), p->flags&LI_MASK);
       printf("\t  vn=%d (0x%.2x)\n", VN(p->flags), p->flags&VN_MASK);
       printf("\t  mode=%d (0x%.2x)\n", MODE(p->flags), p->flags&MODE_MASK);
       printf("\tstratum = %d\n", p->stratum);
       printf("\tpoll = %g\n", pow(2, p->poll));
       printf("\tprecision = %g\n", pow(2, p->precision));
       printf("\trtdelay = %-.16g\n", NTP32asDOUBLE(p->rtdelay));
       printf("\trtdisp = %-.16g\n", NTP32asDOUBLE(p->rtdisp));
       printf("\trefid = %x\n", p->refid);
       printf("\trefts = %-.16g\n", NTP64asDOUBLE(p->refts));
       printf("\torigts = %-.16g\n", NTP64asDOUBLE(p->origts));
       printf("\trxts = %-.16g\n", NTP64asDOUBLE(p->rxts));
       printf("\ttxts = %-.16g\n", NTP64asDOUBLE(p->txts));

Here is the caller graph for this function:

void print_usage ( void  )

Definition at line 389 of file check_cpqarray.c.

  printf("cpqarrayd [options]\n");
  printf("   -h         prints this text\n");
  printf("   -d         enables debugging\n");
int process_arguments ( int  argc,
char **  argv 
void setup_control_request ( ntp_control_message p,
uint8_t  opcode,
uint16_t  seq 

Definition at line 500 of file check_ntp.c.

       memset(p, 0, sizeof(ntp_control_message));
       LI_SET(p->flags, LI_NOWARNING);
       VN_SET(p->flags, VN_RESERVED);
       MODE_SET(p->flags, MODE_CONTROLMSG);
       OP_SET(p->op, opcode);
       p->seq = htons(seq);
       /* Remaining fields are zero for requests */

Here is the caller graph for this function:

void setup_request ( ntp_message p)

Definition at line 278 of file check_ntp.c.

       struct timeval t;

       memset(p, 0, sizeof(ntp_message));
       LI_SET(p->flags, LI_ALARM);
       VN_SET(p->flags, 4);
       MODE_SET(p->flags, MODE_CLIENT);

       gettimeofday(&t, NULL);

Here is the call graph for this function:

Here is the caller graph for this function:

Variable Documentation

const char* copyright = "2006-2008"

Definition at line 34 of file check_ntp.c.

short do_jitter = 0 [static]

Definition at line 46 of file check_ntp.c.

short do_offset = 0 [static]

Definition at line 43 of file check_ntp.c.

const char* email = ""

Definition at line 35 of file check_ntp.c.

char* jcrit = "10000" [static]

Definition at line 48 of file check_ntp.c.

Definition at line 52 of file check_ntp.c.

char* jwarn = "5000" [static]

Definition at line 47 of file check_ntp.c.

char* ocrit = "120" [static]

Definition at line 45 of file check_ntp.c.

Definition at line 51 of file check_ntp.c.

char* owarn = "60" [static]

Definition at line 44 of file check_ntp.c.

const char* progname = "check_ntp"

Definition at line 33 of file check_ntp.c.

char* server_address = NULL [static]

Definition at line 41 of file check_ntp.c.

int verbose = 0 [static]

Definition at line 42 of file check_ntp.c.