summaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
authorhugetoad <hugetoad@97f52cf1-0a1b-0410-bd0e-c28be96e8082>2005-10-12 16:13:10 +0000
committerhugetoad <hugetoad@97f52cf1-0a1b-0410-bd0e-c28be96e8082>2005-10-12 16:13:10 +0000
commitdd91b8328832659bd0aa5ed0877ff6a00f0982d8 (patch)
tree630226480a4a8da52d303c0813adb9826e5d24a6 /src/libs
parente39cca6e9d8343d949007c23bb775d077def6489 (diff)
downloadzabbix-dd91b8328832659bd0aa5ed0877ff6a00f0982d8.tar.gz
zabbix-dd91b8328832659bd0aa5ed0877ff6a00f0982d8.tar.xz
zabbix-dd91b8328832659bd0aa5ed0877ff6a00f0982d8.zip
- added support of service.ntp[host,port] (Alexei)
git-svn-id: svn://svn.zabbix.com/trunk@2177 97f52cf1-0a1b-0410-bd0e-c28be96e8082
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/zbxsysinfo/Makefile.am2
-rw-r--r--src/libs/zbxsysinfo/common/common.c5
-rw-r--r--src/libs/zbxsysinfo/common/ntp.c315
3 files changed, 321 insertions, 1 deletions
diff --git a/src/libs/zbxsysinfo/Makefile.am b/src/libs/zbxsysinfo/Makefile.am
index d2b67728..77981f4f 100644
--- a/src/libs/zbxsysinfo/Makefile.am
+++ b/src/libs/zbxsysinfo/Makefile.am
@@ -1,4 +1,4 @@
SUBDIRS=@ARCH@
libzbxsysinfo_a_LIBADD = ../zbxcommon/libzbxcommon.a ../zbxcrypto/libzbxcrypto.a
-libzbxsysinfo_a_SOURCES=common/common.c common/file.c common/system.c @ARCH@/@ARCH@.c
+libzbxsysinfo_a_SOURCES=common/common.c common/file.c common/ntp.c common/system.c @ARCH@/@ARCH@.c
lib_LIBRARIES=libzbxsysinfo.a
diff --git a/src/libs/zbxsysinfo/common/common.c b/src/libs/zbxsysinfo/common/common.c
index 667ab69f..88dae787 100644
--- a/src/libs/zbxsysinfo/common/common.c
+++ b/src/libs/zbxsysinfo/common/common.c
@@ -1808,6 +1808,11 @@ int CHECK_SERVICE(const char *cmd, const char *service_and_ip_and_port,double *
if(port == 0) port=22;
result=check_ssh(ip,port,&value_int);
}
+ else if(strcmp(service,"service.ntp") == 0)
+ {
+ if(port == 0) port=123;
+ result=check_ntp(ip,port,&value_int);
+ }
#ifdef HAVE_LDAP
else if(strcmp(service,"ldap") == 0)
{
diff --git a/src/libs/zbxsysinfo/common/ntp.c b/src/libs/zbxsysinfo/common/ntp.c
new file mode 100644
index 00000000..b9547005
--- /dev/null
+++ b/src/libs/zbxsysinfo/common/ntp.c
@@ -0,0 +1,315 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <errno.h>
+#include <time.h>
+
+#include "common.h"
+#include "sysinfo.h"
+
+#define JAN_1970 2208988800.0 /* 1970 - 1900 in seconds */
+#define NTP_SCALE 4294967296.0 /* 2^32, of course! */
+
+#define NTP_PACKET_MIN 48 /* Without authentication */
+#define NTP_PACKET_MAX 68 /* With authentication (ignored) */
+#define NTP_DISP_FIELD 8 /* Offset of dispersion field */
+#define NTP_REFERENCE 16 /* Offset of reference timestamp */
+#define NTP_ORIGINATE 24 /* Offset of originate timestamp */
+#define NTP_RECEIVE 32 /* Offset of receive timestamp */
+#define NTP_TRANSMIT 40 /* Offset of transmit timestamp */
+
+#define NTP_LI_FUDGE 0 /* The current 'status' */
+#define NTP_VERSION 3 /* The current version */
+#define NTP_VERSION_MAX 4 /* The maximum valid version */
+#define NTP_STRATUM 15 /* The current stratum as a server */
+#define NTP_STRATUM_MAX 15 /* The maximum valid stratum */
+#define NTP_POLLING 8 /* The current 'polling interval' */
+#define NTP_PRECISION 0 /* The current 'precision' - 1 sec. */
+
+#define NTP_ACTIVE 1 /* NTP symmetric active request */
+#define NTP_PASSIVE 2 /* NTP symmetric passive response */
+#define NTP_CLIENT 3 /* NTP client request */
+#define NTP_SERVER 4 /* NTP server response */
+#define NTP_BROADCAST 5 /* NTP server broadcast */
+
+#define NTP_INSANITY 3600.0 /* Errors beyond this are hopeless */
+#define RESET_MIN 15 /* Minimum period between resets */
+#define ABSCISSA 3.0 /* Scale factor for standard errors */
+
+typedef struct NTP_DATA {
+ unsigned char status, version, mode, stratum, polling, precision;
+ double dispersion, reference, originate, receive, transmit, current;
+} ntp_data;
+
+double current_time (double offset) {
+
+/* Get the current UTC time in seconds since the Epoch plus an offset (usually
+the time from the beginning of the century to the Epoch!) */
+
+ struct timeval current;
+
+ errno = 0;
+ if (gettimeofday(&current,NULL))
+ {
+ exit(-1);
+ }
+ return offset+current.tv_sec+1.0e-6*current.tv_usec;
+}
+
+void make_packet (ntp_data *data)
+{
+ data->status = NTP_LI_FUDGE<<6;
+ data->stratum = NTP_STRATUM;
+ data->reference = data->dispersion = 0.0;
+
+ data->version = NTP_VERSION;
+ data->mode = 1;
+ data->polling = NTP_POLLING;
+ data->precision = NTP_PRECISION;
+ data->receive = data->originate = 0.0;
+ data->current = data->transmit = current_time(JAN_1970);
+}
+
+void pack_ntp (unsigned char *packet, int length, ntp_data *data) {
+
+/* Pack the essential data into an NTP packet, bypassing struct layout and
+endian problems. Note that it ignores fields irrelevant to SNTP. */
+
+ int i, k;
+ double d;
+
+ memset(packet,0,(size_t)length);
+ packet[0] = (data->status<<6)|(data->version<<3)|data->mode;
+ packet[1] = data->stratum;
+ packet[2] = data->polling;
+ packet[3] = data->precision;
+ d = data->originate/NTP_SCALE;
+ for (i = 0; i < 8; ++i) {
+ if ((k = (int)(d *= 256.0)) >= 256) k = 255;
+ packet[NTP_ORIGINATE+i] = k;
+ d -= k;
+ }
+ d = data->receive/NTP_SCALE;
+ for (i = 0; i < 8; ++i) {
+ if ((k = (int)(d *= 256.0)) >= 256) k = 255;
+ packet[NTP_RECEIVE+i] = k;
+ d -= k;
+ }
+ d = data->transmit/NTP_SCALE;
+ for (i = 0; i < 8; ++i) {
+ if ((k = (int)(d *= 256.0)) >= 256) k = 255;
+ packet[NTP_TRANSMIT+i] = k;
+ d -= k;
+ }
+}
+
+void unpack_ntp (ntp_data *data, unsigned char *packet, int length) {
+
+/* Unpack the essential data from an NTP packet, bypassing struct layout and
+endian problems. Note that it ignores fields irrelevant to SNTP. */
+
+ int i;
+ double d;
+
+ data->current = current_time(JAN_1970); /* Best to come first */
+ data->status = (packet[0] >> 6);
+ data->version = (packet[0] >> 3)&0x07;
+ data->mode = packet[0]&0x07;
+ data->stratum = packet[1];
+ data->polling = packet[2];
+ data->precision = packet[3];
+ d = 0.0;
+ for (i = 0; i < 4; ++i) d = 256.0*d+packet[NTP_DISP_FIELD+i];
+ data->dispersion = d/65536.0;
+ d = 0.0;
+ for (i = 0; i < 8; ++i) d = 256.0*d+packet[NTP_REFERENCE+i];
+ data->reference = d/NTP_SCALE;
+ d = 0.0;
+ for (i = 0; i < 8; ++i) d = 256.0*d+packet[NTP_ORIGINATE+i];
+ data->originate = d/NTP_SCALE;
+ d = 0.0;
+ for (i = 0; i < 8; ++i) d = 256.0*d+packet[NTP_RECEIVE+i];
+ data->receive = d/NTP_SCALE;
+ d = 0.0;
+ for (i = 0; i < 8; ++i) d = 256.0*d+packet[NTP_TRANSMIT+i];
+ data->transmit = d/NTP_SCALE;
+}
+
+/*
+void display_data (ntp_data *data) {
+
+ printf("sta=%d ver=%d mod=%d str=%d pol=%d dis=%.6f ref=%.6f\n",
+ data->status,data->version,data->mode,data->stratum,data->polling,
+ data->dispersion,data->reference);
+ printf("ori=%.6f rec=%.6f\n",data->originate,data->receive);
+ printf("tra=%.6f cur=%.6f\n",data->transmit,data->current);
+}
+*/
+
+
+time_t convert_time (double value, int *millisecs) {
+
+/* Convert the time to the ANSI C form. */
+
+ time_t result = (time_t)value;
+
+ if ((*millisecs = (int)(1000.0*(value-result))) >= 1000) {
+ *millisecs = 0;
+ ++result;
+ }
+ return result;
+}
+
+int format_time (char *text, int length, double offset, double error,
+ double drift, double drifterr) {
+
+/* Format the current time into a string, with the extra information as
+requested. Note that the rest of the program uses the correction needed, which
+is what is printed for diagnostics, but this formats the error in the local
+system for display to users. So the results from this are the negation of
+those printed by the verbose options. */
+
+ int milli, len;
+ time_t now;
+ struct tm *gmt;
+ static const char *months[] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ };
+
+/* Work out and format the current local time. Note that some semi-ANSI
+systems do not set the return value from (s)printf. */
+
+ now = convert_time(current_time(offset),&milli);
+ errno = 0;
+ if ((gmt = localtime(&now)) == NULL)
+ {
+ printf("unable to work out local time",NULL);
+ return -1;
+ }
+ len = 24;
+ if (length <= len)
+ {
+ printf("internal error calling format_time");
+ return -1;
+ }
+
+ errno = 0;
+ printf("%.4d %s %.2d %.2d:%.2d:%.2d.%.3d\n",
+ gmt->tm_year+1900,months[gmt->tm_mon],gmt->tm_mday,
+ gmt->tm_hour,gmt->tm_min,gmt->tm_sec,milli);
+
+ return now;
+}
+
+int check_ntp(char *host, int port, int *value_int)
+{
+ int s;
+ int len;
+ char c[MAX_STRING_LEN];
+ char *e;
+
+ struct hostent *hp;
+
+ struct sockaddr_in servaddr_in;
+
+ struct linger ling;
+
+ char text[50];
+
+ ntp_data data;
+ unsigned char packet[NTP_PACKET_MIN];
+
+ make_packet(&data);
+
+ servaddr_in.sin_family=AF_INET;
+ hp=gethostbyname(host);
+
+ if(hp==NULL)
+ {
+/* printf("gethostbyname() failed [%s]", hstrerror(h_errno));*/
+ return SYSINFO_RET_FAIL;
+ }
+
+ servaddr_in.sin_addr.s_addr=((struct in_addr *)(hp->h_addr))->s_addr;
+
+ servaddr_in.sin_port=htons(port);
+
+ s=socket(AF_INET,SOCK_DGRAM,0);
+
+ if(s == -1)
+ {
+/* printf("Cannot create socket [%s]", strerror(errno));*/
+ return SYSINFO_RET_FAIL;
+ }
+
+ if( connect(s,(struct sockaddr *)&servaddr_in,sizeof(struct sockaddr_in)) == -1 )
+ {
+ switch (errno)
+ {
+ case EINTR:
+ break;
+ case EHOSTUNREACH:
+ break;
+ default:
+ break;
+ }
+ close(s);
+ return SYSINFO_RET_FAIL;
+ }
+
+ pack_ntp(packet,NTP_PACKET_MIN,&data);
+
+ if( write(s,&packet,NTP_PACKET_MIN) == -1 )
+ {
+ switch (errno)
+ {
+ case EINTR:
+ break;
+ default:
+ break;
+ }
+ close(s);
+ return SYSINFO_RET_FAIL;
+ }
+
+ memset(c,0,MAX_STRING_LEN);
+ len=read(s,c,MAX_STRING_LEN);
+
+ if(len == -1)
+ {
+ switch (errno)
+ {
+ case EINTR:
+ break;
+ case ECONNRESET:
+ break;
+ default:
+ break;
+ }
+ close(s);
+ return SYSINFO_RET_FAIL;
+ }
+ close(s);
+
+ unpack_ntp(&data,c,len);
+
+/* display_data(&data); */
+
+ sprintf(text,"%d",0);
+
+/* format_time(text,75,offset,error,0.0,-1.0);*/
+
+/* if (dispersion < data->dispersion) dispersion = data->dispersion;
+ x = data->receive-data->originate;
+ y = (data->transmit == 0.0 ? 0.0 : data->transmit-data->current);
+ *off = 0.5*(x+y);
+ *err = x-y;
+ x = data->current-data->originate;
+ if (0.5*x > *err) *err = 0.5*x; */
+
+ *value_int = format_time(text,75,0,0,0.0,-1.0);
+
+ return SYSINFO_RET_OK;
+}