1 /*----------------------------------------------------------------------------*/
2 /* Xymon RRD handler module.                                                  */
3 /*                                                                            */
4 /* Copyright (C) 2004-2011 Henrik Storner <henrik@hswn.dk>                    */
5 /*                                                                            */
6 /* This program is released under the GNU General Public License (GPL),       */
7 /* version 2. See the file "COPYING" for details.                             */
8 /*                                                                            */
9 /*----------------------------------------------------------------------------*/
10 
11 static char do_net_rcsid[] = "$Id: do_net.c 7676 2015-10-01 05:31:49Z jccleaver $";
12 
do_net_rrd(char * hostname,char * testname,char * classname,char * pagepaths,char * msg,time_t tstamp)13 int do_net_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp)
14 {
15 	static char *xymonnet_params[]       = { "DS:sec:GAUGE:600:0:U", NULL };
16 	static void *xymonnet_tpl            = NULL;
17 
18 	char *p;
19 	float seconds = 0.0;
20 	int do_default = 1;
21 
22 	if (xymonnet_tpl == NULL) xymonnet_tpl = setup_template(xymonnet_params);
23 
24 	if (strcmp(testname, "http") == 0) {
25 		char *line1, *url = NULL, *eoln;
26 
27 		do_default = 0;
28 
29 		line1 = msg;
30 		while ((line1 = strchr(line1, '\n')) != NULL) {
31 			line1++; /* Skip the newline */
32 			eoln = strchr(line1, '\n'); if (eoln) *eoln = '\0';
33 
34 			if ( (strncmp(line1, "&green", 6) == 0) ||
35 			     (strncmp(line1, "&yellow", 7) == 0) ||
36 			     (strncmp(line1, "&red", 4) == 0) ) {
37 				p = strstr(line1, "http");
38 				if (p) {
39 					url = xstrdup(p);
40 					p = strchr(url, ' ');
41 					if (p) *p = '\0';
42 				}
43 			}
44 			else if (url && ((p = strstr(line1, "Seconds:")) != NULL) && (sscanf(p, "Seconds: %f", &seconds) == 1)) {
45 				char *urlfn = url;
46 
47 				if (strncmp(urlfn, "http://", 7) == 0) urlfn += 7;
48 				p = urlfn; while ((p = strchr(p, '/')) != NULL) *p = ',';
49 				setupfn3("%s.%s.%s.rrd", "tcp", "http", urlfn);
50 				snprintf(rrdvalues, sizeof(rrdvalues), "%d:%.2f", (int)tstamp, seconds);
51 				create_and_update_rrd(hostname, testname, classname, pagepaths, xymonnet_params, xymonnet_tpl);
52 				xfree(url); url = NULL;
53 			}
54 
55 			if (eoln) *eoln = '\n';
56 		}
57 
58 		if (url) xfree(url);
59 	}
60 	else if (strcmp(testname, xgetenv("PINGCOLUMN")) == 0) {
61 		/*
62 		 * Ping-tests, possibly using fping.
63 		 */
64 		char *tmod = "ms";
65 
66 		do_default = 0;
67 
68 		if ((p = strstr(msg, "time=")) != NULL) {
69 			/* Standard ping, reports ".... time=0.2 ms" */
70 			seconds = atof(p+5);
71 			tmod = p + 5; tmod += strspn(tmod, "0123456789. ");
72 		}
73 		else if ((p = strstr(msg, "alive")) != NULL) {
74 			/* fping, reports ".... alive (0.43 ms)" */
75 			seconds = atof(p+7);
76 			tmod = p + 7; tmod += strspn(tmod, "0123456789. ");
77 		}
78 
79 		if (strncmp(tmod, "ms", 2) == 0) seconds = seconds / 1000.0;
80 		else if (strncmp(tmod, "usec", 4) == 0) seconds = seconds / 1000000.0;
81 
82 		setupfn2("%s.%s.rrd", "tcp", testname);
83 		snprintf(rrdvalues, sizeof(rrdvalues), "%d:%.6f", (int)tstamp, seconds);
84 		return create_and_update_rrd(hostname, testname, classname, pagepaths, xymonnet_params, xymonnet_tpl);
85 	}
86 	else if (strcmp(testname, "ntp") == 0) {
87 		/*
88 		 * sntp output:
89 		 *    2009 Nov 13 11:29:10.000313 + 0.038766 +/- 0.052900 secs
90 		 * ntpdate output:
91 		 *    server 172.16.10.2, stratum 3, offset -0.040324, delay 0.02568
92 		 *    13 Nov 11:29:06 ntpdate[7038]: adjust time server 172.16.10.2 offset -0.040324 sec
93 		 */
94 
95 		char dataforntpstat[100];
96 		char *offsetval = NULL;
97 		char offsetbuf[40];
98 		char *msgcopy = strdup(msg);
99 
100 		if (strstr(msgcopy, "ntpdate") != NULL) {
101 			/* Old-style "ntpdate" output */
102 			char *p;
103 
104 			p = strstr(msgcopy, "offset ");
105 			if (p) {
106 				p += 7;
107 				offsetval = strtok(p, " \r\n\t");
108 			}
109 		}
110 		else if (strstr(msgcopy, " secs") != NULL) {
111 			/* Probably new "sntp" output */
112 			char *year, *tm, *offsetdirection, *offset, *plusminus, *errorbound, *secs;
113 
114 			tm = offsetdirection = plusminus = errorbound = secs = NULL;
115 			year = strtok(msgcopy, " ");
116 			tm = year ? strtok(NULL, " ") : NULL;
117 			offsetdirection = tm ? strtok(NULL, " ") : NULL;
118 			offset = offsetdirection ? strtok(NULL, " ") : NULL;
119 			plusminus = offset ? strtok(NULL, " ") : NULL;
120 			errorbound = plusminus ? strtok(NULL, " ") : NULL;
121 			secs = errorbound ? strtok(NULL, " ") : NULL;
122 
123 			if ( offsetdirection && ((strcmp(offsetdirection, "+") == 0) || (strcmp(offsetdirection, "-") == 0)) &&
124 			     plusminus && (strcmp(plusminus, "+/-") == 0) &&
125 			     secs && (strcmp(secs, "secs") == 0) ) {
126 				/* Looks sane */
127 				snprintf(offsetbuf, sizeof(offsetbuf), "%s%s", offsetdirection, offset);
128 				offsetval = offsetbuf;
129 			}
130 		}
131 
132 		if (offsetval) {
133 			snprintf(dataforntpstat, sizeof(dataforntpstat), "offset=%s", offsetval);
134 			do_ntpstat_rrd(hostname, testname, classname, pagepaths, dataforntpstat, tstamp);
135 		}
136 
137 		xfree(msgcopy);
138 	}
139 
140 
141 	if (do_default) {
142 		/*
143 		 * Normal network tests - pick up the "Seconds:" value
144 		 */
145 		p = strstr(msg, "\nSeconds:");
146 		if (p && (sscanf(p+1, "Seconds: %f", &seconds) == 1)) {
147 			setupfn2("%s.%s.rrd", "tcp", testname);
148 			snprintf(rrdvalues, sizeof(rrdvalues), "%d:%f", (int)tstamp, seconds);
149 			return create_and_update_rrd(hostname, testname, classname, pagepaths, xymonnet_params, xymonnet_tpl);
150 		}
151 	}
152 
153 	return 0;
154 }
155 
156