summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--plugins-root/check_icmp.c412
-rw-r--r--plugins-root/t/check_icmp.t58
-rw-r--r--po/de.po22
-rw-r--r--po/fr.po22
-rw-r--r--po/monitoring-plugins.pot22
6 files changed, 505 insertions, 33 deletions
diff --git a/.gitignore b/.gitignore
index 02ca61e1..6f903d61 100644
--- a/.gitignore
+++ b/.gitignore
@@ -94,7 +94,7 @@ NP-VERSION-FILE
94/gl/limits.h 94/gl/limits.h
95/gl/malloc/dynarray-skeleton.gl.h 95/gl/malloc/dynarray-skeleton.gl.h
96/gl/malloc/dynarray.gl.h 96/gl/malloc/dynarray.gl.h
97/gl/stdckdint. 97/gl/stdckdint.h
98 98
99# /lib/ 99# /lib/
100/lib/.deps 100/lib/.deps
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c
index 1d47e9fc..197ce32f 100644
--- a/plugins-root/check_icmp.c
+++ b/plugins-root/check_icmp.c
@@ -109,18 +109,35 @@ typedef struct rta_host {
109 unsigned char icmp_type, icmp_code; /* type and code from errors */ 109 unsigned char icmp_type, icmp_code; /* type and code from errors */
110 unsigned short flags; /* control/status flags */ 110 unsigned short flags; /* control/status flags */
111 double rta; /* measured RTA */ 111 double rta; /* measured RTA */
112 int rta_status;
112 double rtmax; /* max rtt */ 113 double rtmax; /* max rtt */
113 double rtmin; /* min rtt */ 114 double rtmin; /* min rtt */
115 double jitter; /* measured jitter */
116 int jitter_status;
117 double jitter_max; /* jitter rtt */
118 double jitter_min; /* jitter rtt */
119 double EffectiveLatency;
120 double mos; /* Mean opnion score */
121 int mos_status;
122 double score; /* score */
123 int score_status;
124 u_int last_tdiff;
125 u_int last_icmp_seq; /* Last ICMP_SEQ to check out of order pkts */
114 unsigned char pl; /* measured packet loss */ 126 unsigned char pl; /* measured packet loss */
127 int pl_status;
115 struct rta_host *next; /* linked list */ 128 struct rta_host *next; /* linked list */
129 int order_status;
116} rta_host; 130} rta_host;
117 131
118#define FLAG_LOST_CAUSE 0x01 /* decidedly dead target. */ 132#define FLAG_LOST_CAUSE 0x01 /* decidedly dead target. */
119 133
120/* threshold structure. all values are maximum allowed, exclusive */ 134/* threshold structure. all values are maximum allowed, exclusive */
121typedef struct threshold { 135typedef struct threshold {
122 unsigned char pl; /* max allowed packet loss in percent */ 136 unsigned char pl; /* max allowed packet loss in percent */
123 unsigned int rta; /* roundtrip time average, microseconds */ 137 unsigned int rta; /* roundtrip time average, microseconds */
138 double jitter; /* jitter time average, microseconds */
139 double mos; /* MOS */
140 double score; /* Score */
124} threshold; 141} threshold;
125 142
126/* the data structure */ 143/* the data structure */
@@ -188,6 +205,7 @@ static int wait_for_reply(int, u_int);
188static int recvfrom_wto(int, void *, unsigned int, struct sockaddr *, u_int *, struct timeval*); 205static int recvfrom_wto(int, void *, unsigned int, struct sockaddr *, u_int *, struct timeval*);
189static int send_icmp_ping(int, struct rta_host *); 206static int send_icmp_ping(int, struct rta_host *);
190static int get_threshold(char *str, threshold *th); 207static int get_threshold(char *str, threshold *th);
208static int get_threshold2(char *str, threshold *, threshold *, int type);
191static void run_checks(void); 209static void run_checks(void);
192static void set_source_ip(char *); 210static void set_source_ip(char *);
193static int add_target(char *); 211static int add_target(char *);
@@ -224,6 +242,12 @@ static unsigned int warn_down = 1, crit_down = 1; /* host down threshold values
224static int min_hosts_alive = -1; 242static int min_hosts_alive = -1;
225float pkt_backoff_factor = 1.5; 243float pkt_backoff_factor = 1.5;
226float target_backoff_factor = 1.5; 244float target_backoff_factor = 1.5;
245bool rta_mode=false;
246bool pl_mode=false;
247bool jitter_mode=false;
248bool score_mode=false;
249bool mos_mode=false;
250bool order_mode=false;
227 251
228/** code start **/ 252/** code start **/
229static void 253static void
@@ -393,12 +417,14 @@ main(int argc, char **argv)
393 int icmp_sockerrno, udp_sockerrno, tcp_sockerrno; 417 int icmp_sockerrno, udp_sockerrno, tcp_sockerrno;
394 int result; 418 int result;
395 struct rta_host *host; 419 struct rta_host *host;
420#ifdef HAVE_SIGACTION
421 struct sigaction sig_action;
422#endif
396#ifdef SO_TIMESTAMP 423#ifdef SO_TIMESTAMP
397 int on = 1; 424 int on = 1;
398#endif 425#endif
399 char *source_ip = NULL; 426 char *source_ip = NULL;
400 char * opts_str = "vhVw:c:n:p:t:H:s:i:b:I:l:m:64"; 427 char * opts_str = "vhVw:c:n:p:t:H:s:i:b:I:l:m:P:R:J:S:M:O64";
401
402 setlocale (LC_ALL, ""); 428 setlocale (LC_ALL, "");
403 bindtextdomain (PACKAGE, LOCALEDIR); 429 bindtextdomain (PACKAGE, LOCALEDIR);
404 textdomain (PACKAGE); 430 textdomain (PACKAGE);
@@ -422,10 +448,19 @@ main(int argc, char **argv)
422 table = NULL; 448 table = NULL;
423 449
424 mode = MODE_RTA; 450 mode = MODE_RTA;
451 /* Default critical thresholds */
425 crit.rta = 500000; 452 crit.rta = 500000;
426 crit.pl = 80; 453 crit.pl = 80;
454 crit.jitter = 50;
455 crit.mos= 3;
456 crit.score=70;
457 /* Default warning thresholds */
427 warn.rta = 200000; 458 warn.rta = 200000;
428 warn.pl = 40; 459 warn.pl = 40;
460 warn.jitter = 40;
461 warn.mos= 3.5;
462 warn.score=80;
463
429 protocols = HAVE_ICMP | HAVE_UDP | HAVE_TCP; 464 protocols = HAVE_ICMP | HAVE_UDP | HAVE_TCP;
430 pkt_interval = 80000; /* 80 msec packet interval by default */ 465 pkt_interval = 80000; /* 80 msec packet interval by default */
431 packets = 5; 466 packets = 5;
@@ -481,7 +516,7 @@ main(int argc, char **argv)
481 /* Reset argument scanning */ 516 /* Reset argument scanning */
482 optind = 1; 517 optind = 1;
483 518
484 unsigned short size; 519 unsigned long size;
485 /* parse the arguments */ 520 /* parse the arguments */
486 for(i = 1; i < argc; i++) { 521 for(i = 1; i < argc; i++) {
487 while((arg = getopt(argc, argv, opts_str)) != EOF) { 522 while((arg = getopt(argc, argv, opts_str)) != EOF) {
@@ -490,7 +525,7 @@ main(int argc, char **argv)
490 debug++; 525 debug++;
491 break; 526 break;
492 case 'b': 527 case 'b':
493 size = (unsigned short)strtol(optarg,NULL,0); 528 size = strtol(optarg,NULL,0);
494 if (size >= (sizeof(struct icmp) + sizeof(struct icmp_ping_data)) && 529 if (size >= (sizeof(struct icmp) + sizeof(struct icmp_ping_data)) &&
495 size < MAX_PING_DATA) { 530 size < MAX_PING_DATA) {
496 icmp_data_size = size; 531 icmp_data_size = size;
@@ -545,6 +580,29 @@ main(int argc, char **argv)
545 print_help (); 580 print_help ();
546 exit (STATE_UNKNOWN); 581 exit (STATE_UNKNOWN);
547 break; 582 break;
583 case 'R': /* RTA mode */
584 get_threshold2(optarg, &warn, &crit,1);
585 rta_mode=true;
586 break;
587 case 'P': /* packet loss mode */
588 get_threshold2(optarg, &warn, &crit,2);
589 pl_mode=true;
590 break;
591 case 'J': /* jitter mode */
592 get_threshold2(optarg, &warn, &crit,3);
593 jitter_mode=true;
594 break;
595 case 'M': /* MOS mode */
596 get_threshold2(optarg, &warn, &crit,4);
597 mos_mode=true;
598 break;
599 case 'S': /* score mode */
600 get_threshold2(optarg, &warn, &crit,5);
601 score_mode=true;
602 break;
603 case 'O': /* out of order mode */
604 order_mode=true;
605 break;
548 } 606 }
549 } 607 }
550 } 608 }
@@ -631,11 +689,25 @@ main(int argc, char **argv)
631 if(warn.pl > crit.pl) warn.pl = crit.pl; 689 if(warn.pl > crit.pl) warn.pl = crit.pl;
632 if(warn.rta > crit.rta) warn.rta = crit.rta; 690 if(warn.rta > crit.rta) warn.rta = crit.rta;
633 if(warn_down > crit_down) crit_down = warn_down; 691 if(warn_down > crit_down) crit_down = warn_down;
634 692 if(warn.jitter > crit.jitter) crit.jitter = warn.jitter;
693 if(warn.mos < crit.mos) warn.mos = crit.mos;
694 if(warn.score < crit.score) warn.score = crit.score;
695
696#ifdef HAVE_SIGACTION
697 sig_action.sa_sigaction = NULL;
698 sig_action.sa_handler = finish;
699 sigfillset(&sig_action.sa_mask);
700 sig_action.sa_flags = SA_NODEFER|SA_RESTART;
701 sigaction(SIGINT, &sig_action, NULL);
702 sigaction(SIGHUP, &sig_action, NULL);
703 sigaction(SIGTERM, &sig_action, NULL);
704 sigaction(SIGALRM, &sig_action, NULL);
705#else /* HAVE_SIGACTION */
635 signal(SIGINT, finish); 706 signal(SIGINT, finish);
636 signal(SIGHUP, finish); 707 signal(SIGHUP, finish);
637 signal(SIGTERM, finish); 708 signal(SIGTERM, finish);
638 signal(SIGALRM, finish); 709 signal(SIGALRM, finish);
710#endif /* HAVE_SIGACTION */
639 if(debug) printf("Setting alarm timeout to %u seconds\n", timeout); 711 if(debug) printf("Setting alarm timeout to %u seconds\n", timeout);
640 alarm(timeout); 712 alarm(timeout);
641 713
@@ -685,7 +757,12 @@ main(int argc, char **argv)
685 } 757 }
686 758
687 host = list; 759 host = list;
688 table = (struct rta_host**)malloc(sizeof(struct rta_host **) * targets); 760 table = malloc(sizeof(struct rta_host *) * targets);
761 if(!table) {
762 crash("main(): malloc failed for host table");
763 return 3;
764 }
765
689 i = 0; 766 i = 0;
690 while(host) { 767 while(host) {
691 host->id = i*packets; 768 host->id = i*packets;
@@ -772,6 +849,7 @@ wait_for_reply(int sock, u_int t)
772 struct icmp_ping_data data; 849 struct icmp_ping_data data;
773 struct timeval wait_start, now; 850 struct timeval wait_start, now;
774 u_int tdiff, i, per_pkt_wait; 851 u_int tdiff, i, per_pkt_wait;
852 double jitter_tmp;
775 853
776 if (!(packet.buf = malloc(icmp_pkt_size))) { 854 if (!(packet.buf = malloc(icmp_pkt_size))) {
777 crash("send_icmp_ping(): failed to malloc %d bytes for send buffer", 855 crash("send_icmp_ping(): failed to malloc %d bytes for send buffer",
@@ -890,12 +968,43 @@ wait_for_reply(int sock, u_int t)
890 968
891 tdiff = get_timevaldiff(&data.stime, &now); 969 tdiff = get_timevaldiff(&data.stime, &now);
892 970
971 if (host->last_tdiff>0) {
972 /* Calculate jitter */
973 if (host->last_tdiff > tdiff) {
974 jitter_tmp = host->last_tdiff - tdiff;
975 }
976 else {
977 jitter_tmp = tdiff - host->last_tdiff;
978 }
979 if (host->jitter==0) {
980 host->jitter=jitter_tmp;
981 host->jitter_max=jitter_tmp;
982 host->jitter_min=jitter_tmp;
983 }
984 else {
985 host->jitter+=jitter_tmp;
986 if (jitter_tmp < host->jitter_min)
987 host->jitter_min=jitter_tmp;
988 if (jitter_tmp > host->jitter_max)
989 host->jitter_max=jitter_tmp;
990 }
991
992 /* Check if packets in order */
993 if (host->last_icmp_seq >= packet.icp->icmp_seq)
994 host->order_status=STATE_CRITICAL;
995 }
996 host->last_tdiff=tdiff;
997
998 host->last_icmp_seq=packet.icp->icmp_seq;
999
1000 //printf("%d tdiff %d host->jitter %u host->last_tdiff %u\n", icp.icmp_seq, tdiff, host->jitter, host->last_tdiff);
1001
893 host->time_waited += tdiff; 1002 host->time_waited += tdiff;
894 host->icmp_recv++; 1003 host->icmp_recv++;
895 icmp_recv++; 1004 icmp_recv++;
896 if (tdiff > host->rtmax) 1005 if (tdiff > (int)host->rtmax)
897 host->rtmax = tdiff; 1006 host->rtmax = tdiff;
898 if (tdiff < host->rtmin) 1007 if (tdiff < (int)host->rtmin)
899 host->rtmin = tdiff; 1008 host->rtmin = tdiff;
900 1009
901 if(debug) { 1010 if(debug) {
@@ -1094,8 +1203,10 @@ recvfrom_wto(int sock, void *buf, unsigned int len, struct sockaddr *saddr,
1094 hdr.msg_namelen = slen; 1203 hdr.msg_namelen = slen;
1095 hdr.msg_iov = &iov; 1204 hdr.msg_iov = &iov;
1096 hdr.msg_iovlen = 1; 1205 hdr.msg_iovlen = 1;
1206#ifdef HAVE_MSGHDR_MSG_CONTROL
1097 hdr.msg_control = ans_data; 1207 hdr.msg_control = ans_data;
1098 hdr.msg_controllen = sizeof(ans_data); 1208 hdr.msg_controllen = sizeof(ans_data);
1209#endif
1099 1210
1100 ret = recvmsg(sock, &hdr, 0); 1211 ret = recvmsg(sock, &hdr, 0);
1101#ifdef SO_TIMESTAMP 1212#ifdef SO_TIMESTAMP
@@ -1125,6 +1236,8 @@ finish(int sig)
1125 {"OK", "WARNING", "CRITICAL", "UNKNOWN", "DEPENDENT"}; 1236 {"OK", "WARNING", "CRITICAL", "UNKNOWN", "DEPENDENT"};
1126 int hosts_ok = 0; 1237 int hosts_ok = 0;
1127 int hosts_warn = 0; 1238 int hosts_warn = 0;
1239 int this_status;
1240 double R;
1128 1241
1129 alarm(0); 1242 alarm(0);
1130 if(debug > 1) printf("finish(%d) called\n", sig); 1243 if(debug > 1) printf("finish(%d) called\n", sig);
@@ -1140,9 +1253,11 @@ finish(int sig)
1140 } 1253 }
1141 1254
1142 /* iterate thrice to calculate values, give output, and print perfparse */ 1255 /* iterate thrice to calculate values, give output, and print perfparse */
1256 status=STATE_OK;
1143 host = list; 1257 host = list;
1144 1258
1145 while(host) { 1259 while(host) {
1260 this_status = STATE_OK;
1146 if(!host->icmp_recv) { 1261 if(!host->icmp_recv) {
1147 /* rta 0 is ofcourse not entirely correct, but will still show up 1262 /* rta 0 is ofcourse not entirely correct, but will still show up
1148 * conspicuously as missing entries in perfparse and cacti */ 1263 * conspicuously as missing entries in perfparse and cacti */
@@ -1156,21 +1271,107 @@ finish(int sig)
1156 pl = ((host->icmp_sent - host->icmp_recv) * 100) / host->icmp_sent; 1271 pl = ((host->icmp_sent - host->icmp_recv) * 100) / host->icmp_sent;
1157 rta = (double)host->time_waited / host->icmp_recv; 1272 rta = (double)host->time_waited / host->icmp_recv;
1158 } 1273 }
1274 if (host->icmp_recv>1) {
1275 host->jitter=(host->jitter / (host->icmp_recv - 1)/1000);
1276 host->EffectiveLatency = (rta/1000) + host->jitter * 2 + 10;
1277 if (host->EffectiveLatency < 160)
1278 R = 93.2 - (host->EffectiveLatency / 40);
1279 else
1280 R = 93.2 - ((host->EffectiveLatency - 120) / 10);
1281 R = R - (pl * 2.5);
1282 if (R<0) R=0;
1283 host->score = R;
1284 host->mos= 1 + ((0.035) * R) + ((.000007) * R * (R-60) * (100-R));
1285 }
1286 else {
1287 host->jitter=0;
1288 host->jitter_min=0;
1289 host->jitter_max=0;
1290 host->mos=0;
1291 }
1159 host->pl = pl; 1292 host->pl = pl;
1160 host->rta = rta; 1293 host->rta = rta;
1161 if(pl >= crit.pl || rta >= crit.rta) { 1294
1162 status = STATE_CRITICAL; 1295 /* if no new mode selected, use old schema */
1296 if (!rta_mode && !pl_mode && !jitter_mode && !score_mode && !mos_mode && !order_mode) {
1297 rta_mode=1;
1298 pl_mode=1;
1299 }
1300
1301#define THIS_STATUS_WARNING this_status = (this_status <= STATE_WARNING ? STATE_WARNING : this_status)
1302 /* Check which mode is on and do the warn / Crit stuff */
1303 if (rta_mode) {
1304 if(rta >= crit.rta) {
1305 this_status = STATE_CRITICAL;
1306 status = STATE_CRITICAL;
1307 host->rta_status=STATE_CRITICAL;
1308 }
1309 else if(status!=STATE_CRITICAL && (rta >= warn.rta)) {
1310 THIS_STATUS_WARNING;
1311 status = STATE_WARNING;
1312 host->rta_status=STATE_WARNING;
1313 }
1314 }
1315 if (pl_mode) {
1316 if(pl >= crit.pl) {
1317 this_status = STATE_CRITICAL;
1318 status = STATE_CRITICAL;
1319 host->pl_status=STATE_CRITICAL;
1320 }
1321 else if(status!=STATE_CRITICAL && (pl >= warn.pl)) {
1322 THIS_STATUS_WARNING;
1323 status = STATE_WARNING;
1324 host->pl_status=STATE_WARNING;
1325 }
1326 }
1327 if (jitter_mode) {
1328 if(host->jitter >= crit.jitter) {
1329 this_status = STATE_CRITICAL;
1330 status = STATE_CRITICAL;
1331 host->jitter_status=STATE_CRITICAL;
1332 }
1333 else if(status!=STATE_CRITICAL && (host->jitter >= warn.jitter)) {
1334 THIS_STATUS_WARNING;
1335 status = STATE_WARNING;
1336 host->jitter_status=STATE_WARNING;
1337 }
1163 } 1338 }
1164 else if(!status && (pl >= warn.pl || rta >= warn.rta)) { 1339 if (mos_mode) {
1165 status = STATE_WARNING; 1340 if(host->mos <= crit.mos) {
1341 this_status = STATE_CRITICAL;
1342 status = STATE_CRITICAL;
1343 host->mos_status=STATE_CRITICAL;
1344 }
1345 else if(status!=STATE_CRITICAL && (host->mos <= warn.mos)) {
1346 THIS_STATUS_WARNING;
1347 status = STATE_WARNING;
1348 host->mos_status=STATE_WARNING;
1349 }
1350 }
1351 if (score_mode) {
1352 if(host->score <= crit.score) {
1353 this_status = STATE_CRITICAL;
1354 status = STATE_CRITICAL;
1355 host->score_status=STATE_CRITICAL;
1356 }
1357 else if(status!=STATE_CRITICAL && (host->score <= warn.score)) {
1358 THIS_STATUS_WARNING;
1359 status = STATE_WARNING;
1360 host->score_status=STATE_WARNING;
1361 }
1362 }
1363
1364 if (this_status == STATE_WARNING) {
1166 hosts_warn++; 1365 hosts_warn++;
1167 } 1366 }
1168 else { 1367 else if (this_status == STATE_OK) {
1169 hosts_ok++; 1368 hosts_ok++;
1170 } 1369 }
1171 1370
1172 host = host->next; 1371 host = host->next;
1173 } 1372 }
1373
1374
1174 /* this is inevitable */ 1375 /* this is inevitable */
1175 if(!targets_alive) status = STATE_CRITICAL; 1376 if(!targets_alive) status = STATE_CRITICAL;
1176 if(min_hosts_alive > -1) { 1377 if(min_hosts_alive > -1) {
@@ -1181,6 +1382,7 @@ finish(int sig)
1181 1382
1182 host = list; 1383 host = list;
1183 while(host) { 1384 while(host) {
1385
1184 if(debug) puts(""); 1386 if(debug) puts("");
1185 if(i) { 1387 if(i) {
1186 if(i < targets) printf(" :: "); 1388 if(i < targets) printf(" :: ");
@@ -1189,6 +1391,8 @@ finish(int sig)
1189 i++; 1391 i++;
1190 if(!host->icmp_recv) { 1392 if(!host->icmp_recv) {
1191 status = STATE_CRITICAL; 1393 status = STATE_CRITICAL;
1394 host->rtmin=0;
1395 host->jitter_min=0;
1192 if(host->flags & FLAG_LOST_CAUSE) { 1396 if(host->flags & FLAG_LOST_CAUSE) {
1193 char address[INET6_ADDRSTRLEN]; 1397 char address[INET6_ADDRSTRLEN];
1194 parse_address(&host->error_addr, address, sizeof(address)); 1398 parse_address(&host->error_addr, address, sizeof(address));
@@ -1203,26 +1407,108 @@ finish(int sig)
1203 } 1407 }
1204 } 1408 }
1205 else { /* !icmp_recv */ 1409 else { /* !icmp_recv */
1206 printf("%s: rta %0.3fms, lost %u%%", 1410 printf("%s", host->name);
1207 host->name, host->rta / 1000, host->pl); 1411 /* rta text output */
1412 if (rta_mode) {
1413 if (status == STATE_OK)
1414 printf(" rta %0.3fms", host->rta / 1000);
1415 else if (status==STATE_WARNING && host->rta_status==status)
1416 printf(" rta %0.3fms > %0.3fms", (float)host->rta / 1000, (float)warn.rta/1000);
1417 else if (status==STATE_CRITICAL && host->rta_status==status)
1418 printf(" rta %0.3fms > %0.3fms", (float)host->rta / 1000, (float)crit.rta/1000);
1419 }
1420 /* pl text output */
1421 if (pl_mode) {
1422 if (status == STATE_OK)
1423 printf(" lost %u%%", host->pl);
1424 else if (status==STATE_WARNING && host->pl_status==status)
1425 printf(" lost %u%% > %u%%", host->pl, warn.pl);
1426 else if (status==STATE_CRITICAL && host->pl_status==status)
1427 printf(" lost %u%% > %u%%", host->pl, crit.pl);
1428 }
1429 /* jitter text output */
1430 if (jitter_mode) {
1431 if (status == STATE_OK)
1432 printf(" jitter %0.3fms", (float)host->jitter);
1433 else if (status==STATE_WARNING && host->jitter_status==status)
1434 printf(" jitter %0.3fms > %0.3fms", (float)host->jitter, warn.jitter);
1435 else if (status==STATE_CRITICAL && host->jitter_status==status)
1436 printf(" jitter %0.3fms > %0.3fms", (float)host->jitter, crit.jitter);
1437 }
1438 /* mos text output */
1439 if (mos_mode) {
1440 if (status == STATE_OK)
1441 printf(" MOS %0.1f", (float)host->mos);
1442 else if (status==STATE_WARNING && host->mos_status==status)
1443 printf(" MOS %0.1f < %0.1f", (float)host->mos, (float)warn.mos);
1444 else if (status==STATE_CRITICAL && host->mos_status==status)
1445 printf(" MOS %0.1f < %0.1f", (float)host->mos, (float)crit.mos);
1446 }
1447 /* score text output */
1448 if (score_mode) {
1449 if (status == STATE_OK)
1450 printf(" Score %u", (int)host->score);
1451 else if (status==STATE_WARNING && host->score_status==status )
1452 printf(" Score %u < %u", (int)host->score, (int)warn.score);
1453 else if (status==STATE_CRITICAL && host->score_status==status )
1454 printf(" Score %u < %u", (int)host->score, (int)crit.score);
1455 }
1456 /* order statis text output */
1457 if (order_mode) {
1458 if (status == STATE_OK)
1459 printf(" Packets in order");
1460 else if (status==STATE_CRITICAL && host->order_status==status)
1461 printf(" Packets out of order");
1462 }
1208 } 1463 }
1209
1210 host = host->next; 1464 host = host->next;
1211 } 1465 }
1212 1466
1213 /* iterate once more for pretty perfparse output */ 1467 /* iterate once more for pretty perfparse output */
1214 printf("|"); 1468 if (!(!rta_mode && !pl_mode && !jitter_mode && !score_mode && !mos_mode && order_mode)) {
1469 printf("|");
1470 }
1215 i = 0; 1471 i = 0;
1216 host = list; 1472 host = list;
1217 while(host) { 1473 while(host) {
1218 if(debug) puts(""); 1474 if(debug) puts("");
1219 printf("%srta=%0.3fms;%0.3f;%0.3f;0; %spl=%u%%;%u;%u;; %srtmax=%0.3fms;;;; %srtmin=%0.3fms;;;; ", 1475 if (rta_mode && host->pl<100) {
1476 printf("%srta=%0.3fms;%0.3f;%0.3f;0; %srtmax=%0.3fms;;;; %srtmin=%0.3fms;;;; ",
1220 (targets > 1) ? host->name : "", 1477 (targets > 1) ? host->name : "",
1221 host->rta / 1000, (float)warn.rta / 1000, (float)crit.rta / 1000, 1478 host->rta / 1000, (float)warn.rta / 1000, (float)crit.rta / 1000,
1222 (targets > 1) ? host->name : "", host->pl, warn.pl, crit.pl,
1223 (targets > 1) ? host->name : "", (float)host->rtmax / 1000, 1479 (targets > 1) ? host->name : "", (float)host->rtmax / 1000,
1224 (targets > 1) ? host->name : "", (host->rtmin < INFINITY) ? (float)host->rtmin / 1000 : (float)0); 1480 (targets > 1) ? host->name : "", (host->rtmin < INFINITY) ? (float)host->rtmin / 1000 : (float)0);
1225 1481 }
1482 if (pl_mode) {
1483 printf("%spl=%u%%;%u;%u;0;100 ", (targets > 1) ? host->name : "", host->pl, warn.pl, crit.pl);
1484 }
1485 if (jitter_mode && host->pl<100) {
1486 printf("%sjitter_avg=%0.3fms;%0.3f;%0.3f;0; %sjitter_max=%0.3fms;;;; %sjitter_min=%0.3fms;;;; ",
1487 (targets > 1) ? host->name : "",
1488 (float)host->jitter,
1489 (float)warn.jitter,
1490 (float)crit.jitter,
1491 (targets > 1) ? host->name : "",
1492 (float)host->jitter_max / 1000, (targets > 1) ? host->name : "",
1493 (float)host->jitter_min / 1000
1494 );
1495 }
1496 if (mos_mode && host->pl<100) {
1497 printf("%smos=%0.1f;%0.1f;%0.1f;0;5 ",
1498 (targets > 1) ? host->name : "",
1499 (float)host->mos,
1500 (float)warn.mos,
1501 (float)crit.mos
1502 );
1503 }
1504 if (score_mode && host->pl<100) {
1505 printf("%sscore=%u;%u;%u;0;100 ",
1506 (targets > 1) ? host->name : "",
1507 (int)host->score,
1508 (int)warn.score,
1509 (int)crit.score
1510 );
1511 }
1226 host = host->next; 1512 host = host->next;
1227 } 1513 }
1228 1514
@@ -1312,6 +1598,7 @@ add_target_ip(char *arg, struct sockaddr_storage *in)
1312 /* set the values. use calling name for output */ 1598 /* set the values. use calling name for output */
1313 host->name = strdup(arg); 1599 host->name = strdup(arg);
1314 1600
1601
1315 /* fill out the sockaddr_storage struct */ 1602 /* fill out the sockaddr_storage struct */
1316 if(address_family == AF_INET) { 1603 if(address_family == AF_INET) {
1317 host_sin = (struct sockaddr_in *)&host->saddr_in; 1604 host_sin = (struct sockaddr_in *)&host->saddr_in;
@@ -1324,7 +1611,22 @@ add_target_ip(char *arg, struct sockaddr_storage *in)
1324 memcpy(host_sin6->sin6_addr.s6_addr, sin6->sin6_addr.s6_addr, sizeof host_sin6->sin6_addr.s6_addr); 1611 memcpy(host_sin6->sin6_addr.s6_addr, sin6->sin6_addr.s6_addr, sizeof host_sin6->sin6_addr.s6_addr);
1325 } 1612 }
1326 1613
1614 /* fill out the sockaddr_in struct */
1327 host->rtmin = INFINITY; 1615 host->rtmin = INFINITY;
1616 host->rtmax = 0;
1617 host->jitter=0;
1618 host->jitter_max=0;
1619 host->jitter_min=INFINITY;
1620 host->last_tdiff=0;
1621 host->order_status=STATE_OK;
1622 host->last_icmp_seq=0;
1623 host->rta_status=0;
1624 host->pl_status=0;
1625 host->jitter_status=0;
1626 host->mos_status=0;
1627 host->score_status=0;
1628 host->pl_status=0;
1629
1328 1630
1329 if(!list) list = cursor = host; 1631 if(!list) list = cursor = host;
1330 else cursor->next = host; 1632 else cursor->next = host;
@@ -1472,7 +1774,7 @@ get_timevar(const char *str)
1472 1774
1473 /* unit might be given as ms|m (millisec), 1775 /* unit might be given as ms|m (millisec),
1474 * us|u (microsec) or just plain s, for seconds */ 1776 * us|u (microsec) or just plain s, for seconds */
1475 u = p = '\0'; 1777 p = '\0';
1476 u = str[len - 1]; 1778 u = str[len - 1];
1477 if(len >= 2 && !isdigit((int)str[len - 2])) p = str[len - 2]; 1779 if(len >= 2 && !isdigit((int)str[len - 2])) p = str[len - 2];
1478 if(p && u == 's') u = p; 1780 if(p && u == 's') u = p;
@@ -1530,6 +1832,47 @@ get_threshold(char *str, threshold *th)
1530 return 0; 1832 return 0;
1531} 1833}
1532 1834
1835/* not too good at checking errors, but it'll do (main() should barfe on -1) */
1836static int
1837get_threshold2(char *str, threshold *warn, threshold *crit, int type)
1838{
1839 char *p = NULL;
1840 bool i = false;
1841
1842 if(!str || !strlen(str) || !warn || !crit) return -1;
1843 /* pointer magic slims code by 10 lines. i is bof-stop on stupid libc's */
1844 p = &str[strlen(str) - 1];
1845 while(p != &str[0]) {
1846 if( (*p == 'm') || (*p == '%') ) *p = '\0';
1847 else if(*p == ',' && i) {
1848 *p = '\0'; /* reset it so get_timevar(str) works nicely later */
1849 if (type==1)
1850 crit->rta = atof(p+1)*1000;
1851 else if (type==2)
1852 crit->pl = (unsigned char)strtoul(p+1, NULL, 0);
1853 else if (type==3)
1854 crit->jitter = atof(p+1);
1855 else if (type==4)
1856 crit->mos = atof(p+1);
1857 else if (type==5)
1858 crit->score = atof(p+1);
1859 }
1860 i = true;
1861 p--;
1862 }
1863 if (type==1)
1864 warn->rta = atof(p)*1000;
1865 else if (type==2)
1866 warn->pl = (unsigned char)strtoul(p, NULL, 0);
1867 if (type==3)
1868 warn->jitter = atof(p);
1869 else if (type==4)
1870 warn->mos = atof(p);
1871 else if (type==5)
1872 warn->score = atof(p);
1873 return 0;
1874}
1875
1533unsigned short 1876unsigned short
1534icmp_checksum(uint16_t *p, size_t n) 1877icmp_checksum(uint16_t *p, size_t n)
1535{ 1878{
@@ -1555,10 +1898,9 @@ icmp_checksum(uint16_t *p, size_t n)
1555void 1898void
1556print_help(void) 1899print_help(void)
1557{ 1900{
1558
1559 /*print_revision (progname);*/ /* FIXME: Why? */ 1901 /*print_revision (progname);*/ /* FIXME: Why? */
1560
1561 printf ("Copyright (c) 2005 Andreas Ericsson <ae@op5.se>\n"); 1902 printf ("Copyright (c) 2005 Andreas Ericsson <ae@op5.se>\n");
1903
1562 printf (COPYRIGHT, copyright, email); 1904 printf (COPYRIGHT, copyright, email);
1563 1905
1564 printf ("\n\n"); 1906 printf ("\n\n");
@@ -1578,11 +1920,29 @@ print_help(void)
1578 printf (" %s\n", "-c"); 1920 printf (" %s\n", "-c");
1579 printf (" %s", _("critical threshold (currently ")); 1921 printf (" %s", _("critical threshold (currently "));
1580 printf ("%0.3fms,%u%%)\n", (float)crit.rta / 1000, crit.pl); 1922 printf ("%0.3fms,%u%%)\n", (float)crit.rta / 1000, crit.pl);
1923
1924 printf (" %s\n", "-R");
1925 printf (" %s\n", _("RTA, round trip average, mode warning,critical, ex. 100ms,200ms unit in ms"));
1926 printf (" %s\n", "-P");
1927 printf (" %s\n", _("packet loss mode, ex. 40%,50% , unit in %"));
1928 printf (" %s\n", "-J");
1929 printf (" %s\n", _("jitter mode warning,critical, ex. 40.000ms,50.000ms , unit in ms "));
1930 printf (" %s\n", "-M");
1931 printf (" %s\n", _("MOS mode, between 0 and 4.4 warning,critical, ex. 3.5,3.0"));
1932 printf (" %s\n", "-S");
1933 printf (" %s\n", _("score mode, max value 100 warning,critical, ex. 80,70 "));
1934 printf (" %s\n", "-O");
1935 printf (" %s\n", _("detect out of order ICMP packts "));
1936 printf (" %s\n", "-H");
1937 printf (" %s\n", _("specify a target"));
1581 printf (" %s\n", "-s"); 1938 printf (" %s\n", "-s");
1582 printf (" %s\n", _("specify a source IP address or device name")); 1939 printf (" %s\n", _("specify a source IP address or device name"));
1583 printf (" %s\n", "-n"); 1940 printf (" %s\n", "-n");
1584 printf (" %s", _("number of packets to send (currently ")); 1941 printf (" %s", _("number of packets to send (currently "));
1585 printf ("%u)\n",packets); 1942 printf ("%u)\n",packets);
1943 printf (" %s\n", "-p");
1944 printf (" %s", _("number of packets to send (currently "));
1945 printf ("%u)\n",packets);
1586 printf (" %s\n", "-i"); 1946 printf (" %s\n", "-i");
1587 printf (" %s", _("max packet interval (currently ")); 1947 printf (" %s", _("max packet interval (currently "));
1588 printf ("%0.3fms)\n",(float)pkt_interval / 1000); 1948 printf ("%0.3fms)\n",(float)pkt_interval / 1000);
@@ -1603,9 +1963,9 @@ print_help(void)
1603 printf (" %s %u + %d)\n", _("Packet size will be data bytes + icmp header (currently"),icmp_data_size, ICMP_MINLEN); 1963 printf (" %s %u + %d)\n", _("Packet size will be data bytes + icmp header (currently"),icmp_data_size, ICMP_MINLEN);
1604 printf (" %s\n", "-v"); 1964 printf (" %s\n", "-v");
1605 printf (" %s\n", _("verbose")); 1965 printf (" %s\n", _("verbose"));
1606
1607 printf ("\n"); 1966 printf ("\n");
1608 printf ("%s\n", _("Notes:")); 1967 printf ("%s\n", _("Notes:"));
1968 printf (" %s\n", _("If none of R,P,J,M,S or O is specified, default behavior is -R -P"));
1609 printf (" %s\n", _("The -H switch is optional. Naming a host (or several) to check is not.")); 1969 printf (" %s\n", _("The -H switch is optional. Naming a host (or several) to check is not."));
1610 printf ("\n"); 1970 printf ("\n");
1611 printf (" %s\n", _("Threshold format for -w and -c is 200.25,60% for 200.25 msec RTA and 60%")); 1971 printf (" %s\n", _("Threshold format for -w and -c is 200.25,60% for 200.25 msec RTA and 60%"));
diff --git a/plugins-root/t/check_icmp.t b/plugins-root/t/check_icmp.t
index 96addd3b..4f9db868 100644
--- a/plugins-root/t/check_icmp.t
+++ b/plugins-root/t/check_icmp.t
@@ -12,14 +12,14 @@ my $allow_sudo = getTestParameter( "NP_ALLOW_SUDO",
12 "no" ); 12 "no" );
13 13
14if ($allow_sudo eq "yes" or $> == 0) { 14if ($allow_sudo eq "yes" or $> == 0) {
15 plan tests => 20; 15 plan tests => 39;
16} else { 16} else {
17 plan skip_all => "Need sudo to test check_icmp"; 17 plan skip_all => "Need sudo to test check_icmp";
18} 18}
19my $sudo = $> == 0 ? '' : 'sudo'; 19my $sudo = $> == 0 ? '' : 'sudo';
20 20
21my $successOutput = '/OK - .*?: rta (?:[\d\.]+ms)|(?:nan), lost \d+%/'; 21my $successOutput = '/OK - .*? rta (?:[\d\.]+ms)|(?:nan), lost \d+%/';
22my $failureOutput = '/(WARNING|CRITICAL) - .*?: rta [\d\.]+ms, lost \d%/'; 22my $failureOutput = '/(WARNING|CRITICAL) - .*? rta (?:[\d\.]+ms > [\d\.]+ms|nan)/';
23 23
24my $host_responsive = getTestParameter( "NP_HOST_RESPONSIVE", 24my $host_responsive = getTestParameter( "NP_HOST_RESPONSIVE",
25 "The hostname of system responsive to network requests", 25 "The hostname of system responsive to network requests",
@@ -54,7 +54,7 @@ is( $res->return_code, 2, "Syntax ok, with forced critical" );
54like( $res->output, $failureOutput, "Output OK" ); 54like( $res->output, $failureOutput, "Output OK" );
55 55
56$res = NPTest->testCmd( 56$res = NPTest->testCmd(
57 "$sudo ./check_icmp -H $host_nonresponsive -w 10000ms,100% -c 10000ms,100%" 57 "$sudo ./check_icmp -H $host_nonresponsive -w 10000ms,100% -c 10000ms,100% -t 2"
58 ); 58 );
59is( $res->return_code, 2, "Timeout - host nonresponsive" ); 59is( $res->return_code, 2, "Timeout - host nonresponsive" );
60like( $res->output, '/100%/', "Error contains '100%' string (for 100% packet loss)" ); 60like( $res->output, '/100%/', "Error contains '100%' string (for 100% packet loss)" );
@@ -66,13 +66,13 @@ is( $res->return_code, 3, "No hostname" );
66like( $res->output, '/No hosts to check/', "Output with appropriate error message"); 66like( $res->output, '/No hosts to check/', "Output with appropriate error message");
67 67
68$res = NPTest->testCmd( 68$res = NPTest->testCmd(
69 "$sudo ./check_icmp -H $host_nonresponsive -w 10000ms,100% -c 10000ms,100% -n 1 -m 0" 69 "$sudo ./check_icmp -H $host_nonresponsive -w 10000ms,100% -c 10000ms,100% -n 1 -m 0 -t 2"
70 ); 70 );
71is( $res->return_code, 0, "One host nonresponsive - zero required" ); 71is( $res->return_code, 0, "One host nonresponsive - zero required" );
72like( $res->output, $successOutput, "Output OK" ); 72like( $res->output, $successOutput, "Output OK" );
73 73
74$res = NPTest->testCmd( 74$res = NPTest->testCmd(
75 "$sudo ./check_icmp -H $host_responsive -H $host_nonresponsive -w 10000ms,100% -c 10000ms,100% -n 1 -m 1" 75 "$sudo ./check_icmp -H $host_responsive -H $host_nonresponsive -w 10000ms,100% -c 10000ms,100% -n 1 -m 1 -t 2"
76 ); 76 );
77is( $res->return_code, 0, "One of two host nonresponsive - one required" ); 77is( $res->return_code, 0, "One of two host nonresponsive - one required" );
78like( $res->output, $successOutput, "Output OK" ); 78like( $res->output, $successOutput, "Output OK" );
@@ -94,3 +94,49 @@ $res = NPTest->testCmd(
94 ); 94 );
95is( $res->return_code, 0, "Try max packet size" ); 95is( $res->return_code, 0, "Try max packet size" );
96like( $res->output, $successOutput, "Output OK - Didn't overflow" ); 96like( $res->output, $successOutput, "Output OK - Didn't overflow" );
97
98$res = NPTest->testCmd(
99 "$sudo ./check_icmp -H $host_responsive -R 100,100 -n 1 -t 2"
100 );
101is( $res->return_code, 0, "rta works" );
102like( $res->output, $successOutput, "Output OK" );
103$res = NPTest->testCmd(
104 "$sudo ./check_icmp -H $host_responsive -P 80,90 -n 1 -t 2"
105 );
106is( $res->return_code, 0, "pl works" );
107like( $res->output, '/lost 0%/', "Output OK" );
108
109$res = NPTest->testCmd(
110 "$sudo ./check_icmp -H $host_responsive -J 80,90 -t 2"
111 );
112is( $res->return_code, 0, "jitter works" );
113like( $res->output, '/jitter \d/', "Output OK" );
114
115$res = NPTest->testCmd(
116 "$sudo ./check_icmp -H $host_responsive -M 4,3 -t 2"
117 );
118is( $res->return_code, 0, "mos works" );
119like( $res->output, '/MOS \d/', "Output OK" );
120
121$res = NPTest->testCmd(
122 "$sudo ./check_icmp -H $host_responsive -S 80,70 -t 2"
123 );
124is( $res->return_code, 0, "score works" );
125like( $res->output, '/Score \d/', "Output OK" );
126
127$res = NPTest->testCmd(
128 "$sudo ./check_icmp -H $host_responsive -O -t 2"
129 );
130is( $res->return_code, 0, "order works" );
131like( $res->output, '/Packets in order/', "Output OK" );
132
133$res = NPTest->testCmd(
134 "$sudo ./check_icmp -H $host_responsive -O -S 80,70 -M 4,3 -J 80,90 -P 80,90 -R 100,100 -t 2"
135 );
136is( $res->return_code, 0, "order works" );
137like( $res->output, '/Packets in order/', "Output OK" );
138like( $res->output, '/Score \d/', "Output OK" );
139like( $res->output, '/MOS \d/', "Output OK" );
140like( $res->output, '/jitter \d/', "Output OK" );
141like( $res->output, '/lost 0%/', "Output OK" );
142like( $res->output, $successOutput, "Output OK" );
diff --git a/po/de.po b/po/de.po
index c25a2b47..6d79f9d1 100644
--- a/po/de.po
+++ b/po/de.po
@@ -5070,6 +5070,25 @@ msgstr "Warning threshold Integer sein"
5070msgid "critical threshold (currently " 5070msgid "critical threshold (currently "
5071msgstr "Critical threshold muss ein Integer sein" 5071msgstr "Critical threshold muss ein Integer sein"
5072 5072
5073msgid ""
5074"RTA, round trip average, mode warning,critical, ex. 100ms,200ms unit in ms"
5075msgstr ""
5076
5077msgid "packet loss mode, ex. 40%,50% , unit in %"
5078msgstr ""
5079
5080msgid "jitter mode warning,critical, ex. 40.000ms,50.000ms , unit in ms "
5081msgstr ""
5082
5083msgid "MOS mode, between 0 and 4.4 warning,critical, ex. 3.5,3.0"
5084msgstr ""
5085
5086msgid "score mode, max value 100 warning,critical, ex. 80,70 "
5087msgstr ""
5088
5089msgid "detect out of order ICMP packts "
5090msgstr ""
5091
5073#, fuzzy 5092#, fuzzy
5074msgid "specify a source IP address or device name" 5093msgid "specify a source IP address or device name"
5075msgstr "Hostname oder Serveradresse muss angegeben werden" 5094msgstr "Hostname oder Serveradresse muss angegeben werden"
@@ -5101,6 +5120,9 @@ msgstr ""
5101msgid "verbose" 5120msgid "verbose"
5102msgstr "" 5121msgstr ""
5103 5122
5123msgid "If none of R,P,J,M,S or O is specified, default behavior is -R -P"
5124msgstr ""
5125
5104msgid "The -H switch is optional. Naming a host (or several) to check is not." 5126msgid "The -H switch is optional. Naming a host (or several) to check is not."
5105msgstr "" 5127msgstr ""
5106 5128
diff --git a/po/fr.po b/po/fr.po
index 321a2304..c59042dd 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -5290,6 +5290,25 @@ msgstr "Valeurs pour le seuil d'avertissement (actuellement "
5290msgid "critical threshold (currently " 5290msgid "critical threshold (currently "
5291msgstr "Valeurs pour le seuil critique (actuellement " 5291msgstr "Valeurs pour le seuil critique (actuellement "
5292 5292
5293msgid ""
5294"RTA, round trip average, mode warning,critical, ex. 100ms,200ms unit in ms"
5295msgstr ""
5296
5297msgid "packet loss mode, ex. 40%,50% , unit in %"
5298msgstr ""
5299
5300msgid "jitter mode warning,critical, ex. 40.000ms,50.000ms , unit in ms "
5301msgstr ""
5302
5303msgid "MOS mode, between 0 and 4.4 warning,critical, ex. 3.5,3.0"
5304msgstr ""
5305
5306msgid "score mode, max value 100 warning,critical, ex. 80,70 "
5307msgstr ""
5308
5309msgid "detect out of order ICMP packts "
5310msgstr ""
5311
5293msgid "specify a source IP address or device name" 5312msgid "specify a source IP address or device name"
5294msgstr "spécifiez une adresse ou un nom d'hôte" 5313msgstr "spécifiez une adresse ou un nom d'hôte"
5295 5314
@@ -5320,6 +5339,9 @@ msgstr ""
5320msgid "verbose" 5339msgid "verbose"
5321msgstr "" 5340msgstr ""
5322 5341
5342msgid "If none of R,P,J,M,S or O is specified, default behavior is -R -P"
5343msgstr ""
5344
5323msgid "The -H switch is optional. Naming a host (or several) to check is not." 5345msgid "The -H switch is optional. Naming a host (or several) to check is not."
5324msgstr "" 5346msgstr ""
5325 5347
diff --git a/po/monitoring-plugins.pot b/po/monitoring-plugins.pot
index 54d79fe2..90424b73 100644
--- a/po/monitoring-plugins.pot
+++ b/po/monitoring-plugins.pot
@@ -4895,6 +4895,25 @@ msgstr ""
4895msgid "critical threshold (currently " 4895msgid "critical threshold (currently "
4896msgstr "" 4896msgstr ""
4897 4897
4898msgid ""
4899"RTA, round trip average, mode warning,critical, ex. 100ms,200ms unit in ms"
4900msgstr ""
4901
4902msgid "packet loss mode, ex. 40%,50% , unit in %"
4903msgstr ""
4904
4905msgid "jitter mode warning,critical, ex. 40.000ms,50.000ms , unit in ms "
4906msgstr ""
4907
4908msgid "MOS mode, between 0 and 4.4 warning,critical, ex. 3.5,3.0"
4909msgstr ""
4910
4911msgid "score mode, max value 100 warning,critical, ex. 80,70 "
4912msgstr ""
4913
4914msgid "detect out of order ICMP packts "
4915msgstr ""
4916
4898msgid "specify a source IP address or device name" 4917msgid "specify a source IP address or device name"
4899msgstr "" 4918msgstr ""
4900 4919
@@ -4925,6 +4944,9 @@ msgstr ""
4925msgid "verbose" 4944msgid "verbose"
4926msgstr "" 4945msgstr ""
4927 4946
4947msgid "If none of R,P,J,M,S or O is specified, default behavior is -R -P"
4948msgstr ""
4949
4928msgid "The -H switch is optional. Naming a host (or several) to check is not." 4950msgid "The -H switch is optional. Naming a host (or several) to check is not."
4929msgstr "" 4951msgstr ""
4930 4952