aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml14
-rw-r--r--NEWS2
-rw-r--r--THANKS.in1
-rw-r--r--lib/utils_base.c19
-rw-r--r--lib/utils_base.h5
-rw-r--r--lib/utils_cmd.c42
-rw-r--r--lib/utils_cmd.h13
-rw-r--r--plugins-root/check_icmp.c465
-rw-r--r--plugins/check_dbi.c1
-rw-r--r--plugins/check_dns.c36
-rw-r--r--plugins/check_hpjd.c12
-rw-r--r--plugins/check_http.c2
-rw-r--r--plugins/check_pgsql.c1
-rw-r--r--plugins/check_smtp.c1
-rw-r--r--plugins/common.h14
-rw-r--r--plugins/popen.c29
-rw-r--r--plugins/runcmd.c13
-rw-r--r--plugins/t/NPTest.cache.travis2
-rw-r--r--plugins/tests/certs/server-cert.pem41
-rw-r--r--plugins/tests/certs/server-key.pem43
-rwxr-xr-xplugins/tests/check_http.t16
-rwxr-xr-xplugins/tests/check_snmp.t110
-rw-r--r--plugins/utils.c31
-rw-r--r--plugins/utils.h9
24 files changed, 572 insertions, 350 deletions
diff --git a/.travis.yml b/.travis.yml
index 712f2475..946345c4 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,5 @@
sudo: required
-dist: trusty
+dist: xenial
language: c
env:
@@ -39,7 +39,6 @@ before_install:
- "sudo killall -9 ntpd ||:"
# Trusty has no swap, lets create some
- sudo fallocate -l 20M /swapfile; sudo chmod 600 /swapfile; sudo mkswap /swapfile; sudo swapon /swapfile
- - sudo add-apt-repository -y ppa:waja/trusty-backports
- sudo apt-get update -qq
- sudo apt-get purge -qq gawk
@@ -52,7 +51,7 @@ install:
- sudo apt-get install -qq --no-install-recommends autoconf automake
- sudo apt-get install -qq --no-install-recommends faketime
- sudo apt-get install -qq --no-install-recommends libmonitoring-plugin-perl
- - sudo apt-get install -qq --no-install-recommends squid3
+ - sudo apt-get install -qq --no-install-recommends squid
# Trusty related dependencies (not yet provided)
- test "$(dpkg -l | grep -E "mysql-(client|server)-[0-9].[0-9]" | grep -c ^ii)" -gt 0 || sudo apt-get install -qq --no-install-recommends mariadb-client mariadb-server
# enable ssl apache
@@ -60,8 +59,9 @@ install:
- sudo a2ensite default-ssl
- sudo make-ssl-cert generate-default-snakeoil --force-overwrite
- sudo service apache2 reload
- - sudo cp tools/squid.conf /etc/squid3/squid.conf
- - sudo service squid3 reload
+ - sudo cp tools/squid.conf /etc/squid/squid.conf
+ - sudo service squid reload
+ - sudo service mysql restart
before_script:
# ensure we have a test database in place for tests
@@ -73,8 +73,8 @@ before_script:
- make
- export NPTEST_ACCEPTDEFAULT=1
- export NPTEST_CACHE="$(pwd)/plugins/t/NPTest.cache.travis"
- - ssh-keygen -t dsa -N "" -f ~/.ssh/id_dsa
- - cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
+ - ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
+ - cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
- ssh-keyscan localhost >> ~/.ssh/known_hosts
- touch ~/.ssh/config
- sudo rm -f /usr/share/mibs/ietf/SNMPv2-PDU /usr/share/mibs/ietf/IPSEC-SPD-MIB /usr/share/mibs/ietf/IPATM-IPMC-MIB /usr/share/mibs/iana/IANA-IPPM-METRICS-REGISTRY-MIB
diff --git a/NEWS b/NEWS
index 2db2a2cb..0848705c 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,8 @@ This file documents the major additions and syntax changes between releases.
check_dns: allow 'expected address' (-a) to be specified in CIDR notation
(IPv4 only).
check_dns: allow for IPv6 RDNS
+ check_dns: allow unsorted addresses
+ check_dns: allow forcing complete match of all addresses
check_apt: add --only-critical switch
check_apt: add -l/--list option to print packages
diff --git a/THANKS.in b/THANKS.in
index ebc81556..9bb43828 100644
--- a/THANKS.in
+++ b/THANKS.in
@@ -356,3 +356,4 @@ Sven Geggus
Thomas Kurschel
Yannick Charton
Nicolai Søborg
+Rolf Eike Beer
diff --git a/lib/utils_base.c b/lib/utils_base.c
index 19a531f5..fd7058da 100644
--- a/lib/utils_base.c
+++ b/lib/utils_base.c
@@ -37,6 +37,9 @@
monitoring_plugin *this_monitoring_plugin=NULL;
+unsigned int timeout_state = STATE_CRITICAL;
+unsigned int timeout_interval = DEFAULT_SOCKET_TIMEOUT;
+
int _np_state_read_file(FILE *);
void np_init( char *plugin_name, int argc, char **argv ) {
@@ -359,6 +362,22 @@ char *np_extract_value(const char *varlist, const char *name, char sep) {
return value;
}
+const char *
+state_text (int result)
+{
+ switch (result) {
+ case STATE_OK:
+ return "OK";
+ case STATE_WARNING:
+ return "WARNING";
+ case STATE_CRITICAL:
+ return "CRITICAL";
+ case STATE_DEPENDENT:
+ return "DEPENDENT";
+ default:
+ return "UNKNOWN";
+ }
+}
/*
* Read a string representing a state (ok, warning... or numeric: 0, 1) and
diff --git a/lib/utils_base.h b/lib/utils_base.h
index 42ae0c09..d7e7dffa 100644
--- a/lib/utils_base.h
+++ b/lib/utils_base.h
@@ -61,6 +61,10 @@ void print_thresholds(const char *, thresholds *);
int check_range(double, range *);
int get_status(double, thresholds *);
+/* Handle timeouts */
+extern unsigned int timeout_state;
+extern unsigned int timeout_interval;
+
/* All possible characters in a threshold range */
#define NP_THRESHOLDS_CHARS "-0123456789.:@~"
@@ -107,5 +111,6 @@ void np_state_write_string(time_t, char *);
void np_init(char *, int argc, char **argv);
void np_set_args(int argc, char **argv);
void np_cleanup();
+const char *state_text (int);
#endif /* _UTILS_BASE_ */
diff --git a/lib/utils_cmd.c b/lib/utils_cmd.c
index 7eb9a3a0..795840d3 100644
--- a/lib/utils_cmd.c
+++ b/lib/utils_cmd.c
@@ -40,6 +40,7 @@
/** includes **/
#include "common.h"
+#include "utils.h"
#include "utils_cmd.h"
#include "utils_base.h"
#include <fcntl.h>
@@ -65,31 +66,6 @@ extern char **environ;
# define SIG_ERR ((Sigfunc *)-1)
#endif
-/* This variable must be global, since there's no way the caller
- * can forcibly slay a dead or ungainly running program otherwise.
- * Multithreading apps and plugins can initialize it (via CMD_INIT)
- * in an async safe manner PRIOR to calling cmd_run() or cmd_run_array()
- * for the first time.
- *
- * The check for initialized values is atomic and can
- * occur in any number of threads simultaneously. */
-static pid_t *_cmd_pids = NULL;
-
-/* Try sysconf(_SC_OPEN_MAX) first, as it can be higher than OPEN_MAX.
- * If that fails and the macro isn't defined, we fall back to an educated
- * guess. There's no guarantee that our guess is adequate and the program
- * will die with SIGSEGV if it isn't and the upper boundary is breached. */
-#define DEFAULT_MAXFD 256 /* fallback value if no max open files value is set */
-#define MAXFD_LIMIT 8192 /* upper limit of open files */
-#ifdef _SC_OPEN_MAX
-static long maxfd = 0;
-#elif defined(OPEN_MAX)
-# define maxfd OPEN_MAX
-#else /* sysconf macro unavailable, so guess (may be wildly inaccurate) */
-# define maxfd DEFAULT_MAXFD
-#endif
-
-
/** prototypes **/
static int _cmd_open (char *const *, int *, int *)
__attribute__ ((__nonnull__ (1, 2, 3)));
@@ -406,3 +382,19 @@ cmd_file_read ( char *filename, output *out, int flags)
return 0;
}
+
+void
+timeout_alarm_handler (int signo)
+{
+ size_t i;
+ if (signo == SIGALRM) {
+ printf (_("%s - Plugin timed out after %d seconds\n"),
+ state_text(timeout_state), timeout_interval);
+
+ if(_cmd_pids) for(i = 0; i < maxfd; i++) {
+ if(_cmd_pids[i] != 0) kill(_cmd_pids[i], SIGKILL);
+ }
+
+ exit (timeout_state);
+ }
+}
diff --git a/lib/utils_cmd.h b/lib/utils_cmd.h
index ebaf15be..6f3aeb81 100644
--- a/lib/utils_cmd.h
+++ b/lib/utils_cmd.h
@@ -32,4 +32,17 @@ void cmd_init (void);
#define CMD_NO_ARRAYS 0x01 /* don't populate arrays at all */
#define CMD_NO_ASSOC 0x02 /* output.line won't point to buf */
+/* This variable must be global, since there's no way the caller
+ * can forcibly slay a dead or ungainly running program otherwise.
+ * Multithreading apps and plugins can initialize it (via CMD_INIT)
+ * in an async safe manner PRIOR to calling cmd_run() or cmd_run_array()
+ * for the first time.
+ *
+ * The check for initialized values is atomic and can
+ * occur in any number of threads simultaneously. */
+static pid_t *_cmd_pids = NULL;
+
+RETSIGTYPE timeout_alarm_handler (int);
+
+
#endif /* _UTILS_CMD_ */
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c
index 4098874c..e45fdf60 100644
--- a/plugins-root/check_icmp.c
+++ b/plugins-root/check_icmp.c
@@ -67,7 +67,9 @@ const char *email = "devel@monitoring-plugins.org";
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
+#include <netinet/ip6.h>
#include <netinet/ip_icmp.h>
+#include <netinet/icmp6.h>
#include <arpa/inet.h>
#include <signal.h>
#include <float.h>
@@ -113,8 +115,8 @@ typedef struct rta_host {
unsigned short id; /* id in **table, and icmp pkts */
char *name; /* arg used for adding this host */
char *msg; /* icmp error message, if any */
- struct sockaddr_in saddr_in; /* the address of this host */
- struct in_addr error_addr; /* stores address of error replies */
+ struct sockaddr_storage saddr_in; /* the address of this host */
+ struct sockaddr_storage error_addr; /* stores address of error replies */
unsigned long long time_waited; /* total time waited, in usecs */
unsigned int icmp_sent, icmp_recv, icmp_lost; /* counters */
unsigned char icmp_type, icmp_code; /* type and code from errors */
@@ -140,6 +142,18 @@ typedef struct icmp_ping_data {
unsigned short ping_id;
} icmp_ping_data;
+typedef union ip_hdr {
+ struct ip ip;
+ struct ip6_hdr ip6;
+} ip_hdr;
+
+typedef union icmp_packet {
+ void *buf;
+ struct icmp *icp;
+ struct icmp6_hdr *icp6;
+ u_short *cksum_in;
+} icmp_packet;
+
/* the different modes of this program are as follows:
* MODE_RTA: send all packets no matter what (mimic check_icmp and check_ping)
* MODE_HOSTCHECK: Return immediately upon any sign of life
@@ -190,8 +204,9 @@ static int get_threshold(char *str, threshold *th);
static void run_checks(void);
static void set_source_ip(char *);
static int add_target(char *);
-static int add_target_ip(char *, struct in_addr *);
-static int handle_random_icmp(unsigned char *, struct sockaddr_in *);
+static int add_target_ip(char *, struct sockaddr_storage *);
+static int handle_random_icmp(unsigned char *, struct sockaddr_storage *);
+static void parse_address(struct sockaddr_storage *, char *, int);
static unsigned short icmp_checksum(unsigned short *, int);
static void finish(int);
static void crash(const char *, ...);
@@ -300,7 +315,7 @@ get_icmp_error_msg(unsigned char icmp_type, unsigned char icmp_code)
}
static int
-handle_random_icmp(unsigned char *packet, struct sockaddr_in *addr)
+handle_random_icmp(unsigned char *packet, struct sockaddr_storage *addr)
{
struct icmp p, sent_icmp;
struct rta_host *host = NULL;
@@ -342,9 +357,11 @@ handle_random_icmp(unsigned char *packet, struct sockaddr_in *addr)
/* it is indeed a response for us */
host = table[ntohs(sent_icmp.icmp_seq)/packets];
if(debug) {
+ char address[INET6_ADDRSTRLEN];
+ parse_address(addr, address, sizeof(address));
printf("Received \"%s\" from %s for ICMP ECHO sent to %s.\n",
- get_icmp_error_msg(p.icmp_type, p.icmp_code),
- inet_ntoa(addr->sin_addr), host->name);
+ get_icmp_error_msg(p.icmp_type, p.icmp_code),
+ address, host->name);
}
icmp_lost++;
@@ -364,11 +381,23 @@ handle_random_icmp(unsigned char *packet, struct sockaddr_in *addr)
}
host->icmp_type = p.icmp_type;
host->icmp_code = p.icmp_code;
- host->error_addr.s_addr = addr->sin_addr.s_addr;
+ host->error_addr = *addr;
return 0;
}
+void parse_address(struct sockaddr_storage *addr, char *address, int size)
+{
+ switch (address_family) {
+ case AF_INET:
+ inet_ntop(address_family, &((struct sockaddr_in *)addr)->sin_addr, address, size);
+ break;
+ case AF_INET6:
+ inet_ntop(address_family, &((struct sockaddr_in6 *)addr)->sin6_addr, address, size);
+ break;
+ }
+}
+
int
main(int argc, char **argv)
{
@@ -381,6 +410,7 @@ main(int argc, char **argv)
#ifdef SO_TIMESTAMP
int on = 1;
#endif
+ char * opts_str = "vhVw:c:n:p:t:H:s:i:b:I:l:m:64";
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
@@ -390,33 +420,8 @@ main(int argc, char **argv)
* that before pointer magic (esp. on network data) */
icmp_sockerrno = udp_sockerrno = tcp_sockerrno = sockets = 0;
- if((icmp_sock = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP)) != -1)
- sockets |= HAVE_ICMP;
- else icmp_sockerrno = errno;
-
- /* if((udp_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) != -1) */
- /* sockets |= HAVE_UDP; */
- /* else udp_sockerrno = errno; */
-
- /* if((tcp_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) != -1) */
- /* sockets |= HAVE_TCP; */
- /* else tcp_sockerrno = errno; */
-
- /* now drop privileges (no effect if not setsuid or geteuid() == 0) */
- setuid(getuid());
-
-#ifdef SO_TIMESTAMP
- if(setsockopt(icmp_sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)))
- if(debug) printf("Warning: no SO_TIMESTAMP support\n");
-#endif // SO_TIMESTAMP
-
- /* POSIXLY_CORRECT might break things, so unset it (the portable way) */
- environ = NULL;
-
- /* use the pid to mark packets as ours */
- /* Some systems have 32-bit pid_t so mask off only 16 bits */
- pid = getpid() & 0xffff;
- /* printf("pid = %u\n", pid); */
+ address_family = -1;
+ int icmp_proto = IPPROTO_ICMP;
/* get calling name the old-fashioned way for portability instead
* of relying on the glibc-ism __progname */
@@ -456,20 +461,35 @@ main(int argc, char **argv)
packets = 5;
}
- /* Parse extra opts if any */
- argv=np_extra_opts(&argc, argv, progname);
-
- /* support "--help" and "--version" */
- if(argc == 2) {
- if(!strcmp(argv[1], "--help"))
- strcpy(argv[1], "-h");
- if(!strcmp(argv[1], "--version"))
- strcpy(argv[1], "-V");
+ /* Parse protocol arguments first */
+ for(i = 1; i < argc; i++) {
+ while((arg = getopt(argc, argv, opts_str)) != EOF) {
+ unsigned short size;
+ switch(arg) {
+ case '4':
+ if (address_family != -1)
+ crash("Multiple protocol versions not supported");
+ address_family = AF_INET;
+ break;
+ case '6':
+#ifdef USE_IPV6
+ if (address_family != -1)
+ crash("Multiple protocol versions not supported");
+ address_family = AF_INET6;
+#else
+ usage (_("IPv6 support not available\n"));
+#endif
+ break;
+ }
+ }
}
+ /* Reset argument scanning */
+ optind = 1;
+
/* parse the arguments */
for(i = 1; i < argc; i++) {
- while((arg = getopt(argc, argv, "vhVw:c:n:p:t:H:s:i:b:I:l:m:")) != EOF) {
+ while((arg = getopt(argc, argv, opts_str)) != EOF) {
unsigned short size;
switch(arg) {
case 'v':
@@ -530,10 +550,30 @@ main(int argc, char **argv)
case 'h': /* help */
print_help ();
exit (STATE_UNKNOWN);
+ break;
}
}
}
+ /* POSIXLY_CORRECT might break things, so unset it (the portable way) */
+ environ = NULL;
+
+ /* use the pid to mark packets as ours */
+ /* Some systems have 32-bit pid_t so mask off only 16 bits */
+ pid = getpid() & 0xffff;
+ /* printf("pid = %u\n", pid); */
+
+ /* Parse extra opts if any */
+ argv=np_extra_opts(&argc, argv, progname);
+
+ /* support "--help" and "--version" */
+ if(argc == 2) {
+ if(!strcmp(argv[1], "--help"))
+ strcpy(argv[1], "-h");
+ if(!strcmp(argv[1], "--version"))
+ strcpy(argv[1], "-V");
+ }
+
argv = &argv[optind];
while(*argv) {
add_target(*argv);
@@ -545,6 +585,30 @@ main(int argc, char **argv)
exit(3);
}
+ // add_target might change address_family
+ switch ( address_family ){
+ case AF_INET: icmp_proto = IPPROTO_ICMP;
+ break;
+ case AF_INET6: icmp_proto = IPPROTO_ICMPV6;
+ break;
+ default: crash("Address family not supported");
+ }
+ if((icmp_sock = socket(address_family, SOCK_RAW, icmp_proto)) != -1)
+ sockets |= HAVE_ICMP;
+ else icmp_sockerrno = errno;
+
+
+#ifdef SO_TIMESTAMP
+ if(setsockopt(icmp_sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)))
+ if(debug) printf("Warning: no SO_TIMESTAMP support\n");
+#endif // SO_TIMESTAMP
+
+ /* now drop privileges (no effect if not setsuid or geteuid() == 0) */
+ if (setuid(getuid()) == -1) {
+ printf("ERROR: Failed to drop privileges\n");
+ return 1;
+ }
+
if(!sockets) {
if(icmp_sock == -1) {
errno = icmp_sockerrno;
@@ -633,7 +697,7 @@ main(int argc, char **argv)
}
host = list;
- table = malloc(sizeof(struct rta_host **) * targets);
+ table = (struct rta_host**)malloc(sizeof(struct rta_host **) * targets);
i = 0;
while(host) {
host->id = i*packets;
@@ -697,9 +761,15 @@ run_checks()
}
}
+
/* response structure:
+ * IPv4:
* ip header : 20 bytes
* icmp header : 28 bytes
+ * IPv6:
+ * ip header : 40 bytes
+ * icmp header : 28 bytes
+ * both:
* icmp echo reply : the rest
*/
static int
@@ -707,16 +777,27 @@ wait_for_reply(int sock, u_int t)
{
int n, hlen;
static unsigned char buf[4096];
- struct sockaddr_in resp_addr;
- struct ip *ip;
- struct icmp icp;
+ struct sockaddr_storage resp_addr;
+ union ip_hdr *ip;
+ union icmp_packet packet;
struct rta_host *host;
struct icmp_ping_data data;
struct timeval wait_start, now;
u_int tdiff, i, per_pkt_wait;
+ if (!(packet.buf = malloc(icmp_pkt_size))) {
+ crash("send_icmp_ping(): failed to malloc %d bytes for send buffer",
+ icmp_pkt_size);
+ return -1; /* might be reached if we're in debug mode */
+ }
+
+ memset(packet.buf, 0, icmp_pkt_size);
+
/* if we can't listen or don't have anything to listen to, just return */
- if(!t || !icmp_pkts_en_route) return 0;
+ if(!t || !icmp_pkts_en_route) {
+ free(packet.buf);
+ return 0;
+ }
gettimeofday(&wait_start, &tz);
@@ -735,7 +816,7 @@ wait_for_reply(int sock, u_int t)
/* reap responses until we hit a timeout */
n = recvfrom_wto(sock, buf, sizeof(buf),
- (struct sockaddr *)&resp_addr, &t, &now);
+ (struct sockaddr *)&resp_addr, &t, &now);
if(!n) {
if(debug > 1) {
printf("recvfrom_wto() timed out during a %u usecs wait\n",
@@ -745,12 +826,23 @@ wait_for_reply(int sock, u_int t)
}
if(n < 0) {
if(debug) printf("recvfrom_wto() returned errors\n");
+ free(packet.buf);
return n;
}
- ip = (struct ip *)buf;
- if(debug > 1) printf("received %u bytes from %s\n",
- ntohs(ip->ip_len), inet_ntoa(resp_addr.sin_addr));
+ // FIXME: with ipv6 we don't have an ip header here
+ if (address_family != AF_INET6) {
+ ip = (union ip_hdr *)buf;
+
+ if(debug > 1) {
+ char address[INET6_ADDRSTRLEN];
+ parse_address(&resp_addr, address, sizeof(address));
+ printf("received %u bytes from %s\n",
+ address_family == AF_INET6 ? ntohs(ip->ip6.ip6_plen)
+ : ntohs(ip->ip.ip_len),
+ address);
+ }
+ }
/* obsolete. alpha on tru64 provides the necessary defines, but isn't broken */
/* #if defined( __alpha__ ) && __STDC__ && !defined( __GLIBC__ ) */
@@ -759,12 +851,14 @@ wait_for_reply(int sock, u_int t)
* off the bottom 4 bits */
/* hlen = (ip->ip_vhl & 0x0f) << 2; */
/* #else */
- hlen = ip->ip_hl << 2;
+ hlen = (address_family == AF_INET6) ? 0 : ip->ip.ip_hl << 2;
/* #endif */
if(n < (hlen + ICMP_MINLEN)) {
+ char address[INET6_ADDRSTRLEN];
+ parse_address(&resp_addr, address, sizeof(address));
crash("received packet too short for ICMP (%d bytes, expected %d) from %s\n",
- n, hlen + icmp_pkt_size, inet_ntoa(resp_addr.sin_addr));
+ n, hlen + icmp_pkt_size, address);
}
/* else if(debug) { */
/* printf("ip header size: %u, packet size: %u (expected %u, %u)\n", */
@@ -773,23 +867,39 @@ wait_for_reply(int sock, u_int t)
/* } */
/* check the response */
- memcpy(&icp, buf + hlen, sizeof(icp));
- if(ntohs(icp.icmp_id) != pid || icp.icmp_type != ICMP_ECHOREPLY ||
- ntohs(icp.icmp_seq) >= targets*packets) {
+ memcpy(packet.buf, buf + hlen, icmp_pkt_size);
+/* address_family == AF_INET6 ? sizeof(struct icmp6_hdr)
+ : sizeof(struct icmp));*/
+
+ if( (address_family == PF_INET &&
+ (ntohs(packet.icp->icmp_id) != pid || packet.icp->icmp_type != ICMP_ECHOREPLY
+ || ntohs(packet.icp->icmp_seq) >= targets * packets))
+ || (address_family == PF_INET6 &&
+ (ntohs(packet.icp6->icmp6_id) != pid || packet.icp6->icmp6_type != ICMP6_ECHO_REPLY
+ || ntohs(packet.icp6->icmp6_seq) >= targets * packets))) {
if(debug > 2) printf("not a proper ICMP_ECHOREPLY\n");
handle_random_icmp(buf + hlen, &resp_addr);
continue;
}
/* this is indeed a valid response */
- memcpy(&data, icp.icmp_data, sizeof(data));
- if (debug > 2)
- printf("ICMP echo-reply of len %lu, id %u, seq %u, cksum 0x%X\n",
- (unsigned long)sizeof(data), ntohs(icp.icmp_id),
- ntohs(icp.icmp_seq), icp.icmp_cksum);
+ if (address_family == PF_INET) {
+ memcpy(&data, packet.icp->icmp_data, sizeof(data));
+ if (debug > 2)
+ printf("ICMP echo-reply of len %lu, id %u, seq %u, cksum 0x%X\n",
+ (unsigned long)sizeof(data), ntohs(packet.icp->icmp_id),
+ ntohs(packet.icp->icmp_seq), packet.icp->icmp_cksum);
+ host = table[ntohs(packet.icp->icmp_seq)/packets];
+ } else {
+ memcpy(&data, &packet.icp6->icmp6_dataun.icmp6_un_data8[4], sizeof(data));
+ if (debug > 2)
+ printf("ICMP echo-reply of len %lu, id %u, seq %u, cksum 0x%X\n",
+ (unsigned long)sizeof(data), ntohs(packet.icp6->icmp6_id),
+ ntohs(packet.icp6->icmp6_seq), packet.icp6->icmp6_cksum);
+ host = table[ntohs(packet.icp6->icmp6_seq)/packets];
+ }
- host = table[ntohs(icp.icmp_seq)/packets];
tdiff = get_timevaldiff(&data.stime, &now);
host->time_waited += tdiff;
@@ -801,22 +911,25 @@ wait_for_reply(int sock, u_int t)
host->rtmin = tdiff;
if(debug) {
+ char address[INET6_ADDRSTRLEN];
+ parse_address(&resp_addr, address, sizeof(address));
printf("%0.3f ms rtt from %s, outgoing ttl: %u, incoming ttl: %u, max: %0.3f, min: %0.3f\n",
- (float)tdiff / 1000, inet_ntoa(resp_addr.sin_addr),
- ttl, ip->ip_ttl, (float)host->rtmax / 1000, (float)host->rtmin / 1000);
+ (float)tdiff / 1000, address,
+ ttl, ip->ip.ip_ttl, (float)host->rtmax / 1000, (float)host->rtmin / 1000);
}
/* if we're in hostcheck mode, exit with limited printouts */
if(mode == MODE_HOSTCHECK) {
printf("OK - %s responds to ICMP. Packet %u, rta %0.3fms|"
- "pkt=%u;;0;%u rta=%0.3f;%0.3f;%0.3f;;\n",
- host->name, icmp_recv, (float)tdiff / 1000,
- icmp_recv, packets, (float)tdiff / 1000,
- (float)warn.rta / 1000, (float)crit.rta / 1000);
+ "pkt=%u;;0;%u rta=%0.3f;%0.3f;%0.3f;;\n",
+ host->name, icmp_recv, (float)tdiff / 1000,
+ icmp_recv, packets, (float)tdiff / 1000,
+ (float)warn.rta / 1000, (float)crit.rta / 1000);
exit(STATE_OK);
}
}
+ free(packet.buf);
return 0;
}
@@ -824,62 +937,81 @@ wait_for_reply(int sock, u_int t)
static int
send_icmp_ping(int sock, struct rta_host *host)
{
- static union {
- void *buf; /* re-use so we prevent leaks */
- struct icmp *icp;
- u_short *cksum_in;
- } packet = { NULL };
long int len;
struct icmp_ping_data data;
struct msghdr hdr;
struct iovec iov;
struct timeval tv;
- struct sockaddr *addr;
+ void *buf = NULL;
if(sock == -1) {
errno = 0;
crash("Attempt to send on bogus socket");
return -1;
}
- addr = (struct sockaddr *)&host->saddr_in;
- if(!packet.buf) {
- if (!(packet.buf = malloc(icmp_pkt_size))) {
+ if(!buf) {
+ if (!(buf = malloc(icmp_pkt_size))) {
crash("send_icmp_ping(): failed to malloc %d bytes for send buffer",
icmp_pkt_size);
return -1; /* might be reached if we're in debug mode */
}
}
- memset(packet.buf, 0, icmp_pkt_size);
+ memset(buf, 0, icmp_pkt_size);
- if((gettimeofday(&tv, &tz)) == -1) return -1;
+ if((gettimeofday(&tv, &tz)) == -1) {
+ free(buf);
+ return -1;
+ }
data.ping_id = 10; /* host->icmp.icmp_sent; */
memcpy(&data.stime, &tv, sizeof(tv));
- memcpy(&packet.icp->icmp_data, &data, sizeof(data));
- packet.icp->icmp_type = ICMP_ECHO;
- packet.icp->icmp_code = 0;
- packet.icp->icmp_cksum = 0;
- packet.icp->icmp_id = htons(pid);
- packet.icp->icmp_seq = htons(host->id++);
- packet.icp->icmp_cksum = icmp_checksum(packet.cksum_in, icmp_pkt_size);
-
- if (debug > 2)
- printf("Sending ICMP echo-request of len %lu, id %u, seq %u, cksum 0x%X to host %s\n",
- (unsigned long)sizeof(data), ntohs(packet.icp->icmp_id),
- ntohs(packet.icp->icmp_seq), packet.icp->icmp_cksum,
- host->name);
+
+ if (address_family == AF_INET) {
+ struct icmp *icp = (struct icmp*)buf;
+
+ memcpy(&icp->icmp_data, &data, sizeof(data));
+
+ icp->icmp_type = ICMP_ECHO;
+ icp->icmp_code = 0;
+ icp->icmp_cksum = 0;
+ icp->icmp_id = htons(pid);
+ icp->icmp_seq = htons(host->id++);
+ icp->icmp_cksum = icmp_checksum((unsigned short*)buf, icmp_pkt_size);
+
+ if (debug > 2)
+ printf("Sending ICMP echo-request of len %lu, id %u, seq %u, cksum 0x%X to host %s\n",
+ (unsigned long)sizeof(data), ntohs(icp->icmp_id), ntohs(icp->icmp_seq), icp->icmp_cksum, host->name);
+ }
+ else {
+ struct icmp6_hdr *icp6 = (struct icmp6_hdr*)buf;
+ memcpy(&icp6->icmp6_dataun.icmp6_un_data8[4], &data, sizeof(data));
+ icp6->icmp6_type = ICMP6_ECHO_REQUEST;
+ icp6->icmp6_code = 0;
+ icp6->icmp6_cksum = 0;
+ icp6->icmp6_id = htons(pid);
+ icp6->icmp6_seq = htons(host->id++);
+ // let checksum be calculated automatically
+
+ if (debug > 2) {
+ printf("Sending ICMP echo-request of len %lu, id %u, seq %u, cksum 0x%X to host %s\n",
+ (unsigned long)sizeof(data), ntohs(icp6->icmp6_id),
+ ntohs(icp6->icmp6_seq), icp6->icmp6_cksum, host->name);
+ }
+ }
memset(&iov, 0, sizeof(iov));
- iov.iov_base = packet.buf;
+ iov.iov_base = buf;
iov.iov_len = icmp_pkt_size;
memset(&hdr, 0, sizeof(hdr));
- hdr.msg_name = addr;
- hdr.msg_namelen = sizeof(struct sockaddr);
+ hdr.msg_name = (struct sockaddr *)&host->saddr_in;
+ hdr.msg_namelen = sizeof(struct sockaddr_storage);
hdr.msg_iov = &iov;
hdr.msg_iovlen = 1;
+ errno = 0;
+
/* MSG_CONFIRM is a linux thing and only available on linux kernels >= 2.3.15, see send(2) */
#ifdef MSG_CONFIRM
len = sendmsg(sock, &hdr, MSG_CONFIRM);
@@ -887,9 +1019,15 @@ send_icmp_ping(int sock, struct rta_host *host)
len = sendmsg(sock, &hdr, 0);
#endif
+ free(buf);
+
if(len < 0 || (unsigned int)len != icmp_pkt_size) {
- if(debug) printf("Failed to send ping to %s\n",
- inet_ntoa(host->saddr_in.sin_addr));
+ if(debug) {
+ char address[INET6_ADDRSTRLEN];
+ parse_address((struct sockaddr_storage *)&host->saddr_in, address, sizeof(address));
+ printf("Failed to send ping to %s: %s\n", address, strerror(errno));
+ }
+ errno = 0;
return -1;
}
@@ -934,7 +1072,7 @@ recvfrom_wto(int sock, void *buf, unsigned int len, struct sockaddr *saddr,
if(!n) return 0; /* timeout */
- slen = sizeof(struct sockaddr);
+ slen = sizeof(struct sockaddr_storage);
memset(&iov, 0, sizeof(iov));
iov.iov_base = buf;
@@ -958,6 +1096,7 @@ recvfrom_wto(int sock, void *buf, unsigned int len, struct sockaddr *saddr,
break ;
}
}
+
if (!chdr)
#endif // SO_TIMESTAMP
gettimeofday(tv, &tz);
@@ -991,6 +1130,7 @@ finish(int sig)
/* iterate thrice to calculate values, give output, and print perfparse */
host = list;
+
while(host) {
if(!host->icmp_recv) {
/* rta 0 is ofcourse not entirely correct, but will still show up
@@ -1039,10 +1179,12 @@ finish(int sig)
if(!host->icmp_recv) {
status = STATE_CRITICAL;
if(host->flags & FLAG_LOST_CAUSE) {
+ char address[INET6_ADDRSTRLEN];
+ parse_address(&host->error_addr, address, sizeof(address));
printf("%s: %s @ %s. rta nan, lost %d%%",
host->name,
get_icmp_error_msg(host->icmp_type, host->icmp_code),
- inet_ntoa(host->error_addr),
+ address,
100);
}
else { /* not marked as lost cause, so we have no flags for it */
@@ -1104,7 +1246,6 @@ get_timevaldiff(struct timeval *early, struct timeval *later)
{
return 0;
}
-
ret = (later->tv_sec - early->tv_sec) * 1000000;
ret += later->tv_usec - early->tv_usec;
@@ -1112,18 +1253,35 @@ get_timevaldiff(struct timeval *early, struct timeval *later)
}
static int
-add_target_ip(char *arg, struct in_addr *in)
+add_target_ip(char *arg, struct sockaddr_storage *in)
{
struct rta_host *host;
+ struct sockaddr_in *sin, *host_sin;
+ struct sockaddr_in6 *sin6, *host_sin6;
+
+ if (address_family == AF_INET)
+ sin = (struct sockaddr_in *)in;
+ else
+ sin6 = (struct sockaddr_in6 *)in;
- /* disregard obviously stupid addresses */
- if(in->s_addr == INADDR_NONE || in->s_addr == INADDR_ANY)
+
+
+ /* disregard obviously stupid addresses
+ * (I didn't find an ipv6 equivalent to INADDR_NONE) */
+ if (((address_family == AF_INET && (sin->sin_addr.s_addr == INADDR_NONE
+ || sin->sin_addr.s_addr == INADDR_ANY)))
+ || (address_family == AF_INET6 && (sin6->sin6_addr.s6_addr == in6addr_any.s6_addr))) {
return -1;
+ }
/* no point in adding two identical IP's, so don't. ;) */
host = list;
while(host) {
- if(host->saddr_in.sin_addr.s_addr == in->s_addr) {
+ host_sin = (struct sockaddr_in *)&host->saddr_in;
+ host_sin6 = (struct sockaddr_in6 *)&host->saddr_in;
+
+ if( (address_family == AF_INET && host_sin->sin_addr.s_addr == sin->sin_addr.s_addr)
+ || (address_family == AF_INET6 && host_sin6->sin6_addr.s6_addr == sin6->sin6_addr.s6_addr)) {
if(debug) printf("Identical IP already exists. Not adding %s\n", arg);
return -1;
}
@@ -1131,19 +1289,29 @@ add_target_ip(char *arg, struct in_addr *in)
}
/* add the fresh ip */
- host = malloc(sizeof(struct rta_host));
+ host = (struct rta_host*)malloc(sizeof(struct rta_host));
if(!host) {
+ char straddr[INET6_ADDRSTRLEN];
+ parse_address((struct sockaddr_storage*)&in, straddr, sizeof(straddr));
crash("add_target_ip(%s, %s): malloc(%d) failed",
- arg, inet_ntoa(*in), sizeof(struct rta_host));
+ arg, straddr, sizeof(struct rta_host));
}
memset(host, 0, sizeof(struct rta_host));
/* set the values. use calling name for output */
host->name = strdup(arg);
- /* fill out the sockaddr_in struct */
- host->saddr_in.sin_family = AF_INET;
- host->saddr_in.sin_addr.s_addr = in->s_addr;
+ /* fill out the sockaddr_storage struct */
+ if(address_family == AF_INET) {
+ host_sin = (struct sockaddr_in *)&host->saddr_in;
+ host_sin->sin_family = AF_INET;
+ host_sin->sin_addr.s_addr = sin->sin_addr.s_addr;
+ }
+ else {
+ host_sin6 = (struct sockaddr_in6 *)&host->saddr_in;
+ host_sin6->sin6_family = AF_INET6;
+ memcpy(host_sin6->sin6_addr.s6_addr, sin6->sin6_addr.s6_addr, sizeof host_sin6->sin6_addr.s6_addr);
+ }
host->rtmin = DBL_MAX;
@@ -1160,31 +1328,67 @@ add_target_ip(char *arg, struct in_addr *in)
static int
add_target(char *arg)
{
- int i;
- struct hostent *he;
- struct in_addr *in, ip;
+ int error, result;
+ struct sockaddr_storage ip;
+ struct addrinfo hints, *res, *p;
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+
+ switch (address_family) {
+ case -1:
+ /* -4 and -6 are not specified on cmdline */
+ address_family = AF_INET;
+ sin = (struct sockaddr_in *)&ip;
+ result = inet_pton(address_family, arg, &sin->sin_addr);
+#ifdef USE_IPV6
+ if( result != 1 ){
+ address_family = AF_INET6;
+ sin6 = (struct sockaddr_in6 *)&ip;
+ result = inet_pton(address_family, arg, &sin6->sin6_addr);
+ }
+#endif
+ /* If we don't find any valid addresses, we still don't know the address_family */
+ if ( result != 1) {
+ address_family = -1;
+ }
+ break;
+ case AF_INET:
+ sin = (struct sockaddr_in *)&ip;
+ result = inet_pton(address_family, arg, &sin->sin_addr);
+ break;
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *)&ip;
+ result = inet_pton(address_family, arg, &sin6->sin6_addr);
+ break;
+ default: crash("Address family not supported");
+ }
/* don't resolve if we don't have to */
- if((ip.s_addr = inet_addr(arg)) != INADDR_NONE) {
+ if(result == 1) {
/* don't add all ip's if we were given a specific one */
return add_target_ip(arg, &ip);
- /* he = gethostbyaddr((char *)in, sizeof(struct in_addr), AF_INET); */
- /* if(!he) return add_target_ip(arg, in); */
}
else {
errno = 0;
- he = gethostbyname(arg);
- if(!he) {
+ memset(&hints, 0, sizeof(hints));
+ if (address_family == -1) {
+ hints.ai_family = AF_UNSPEC;
+ } else {
+ hints.ai_family = address_family == AF_INET ? PF_INET : PF_INET6;
+ }
+ hints.ai_socktype = SOCK_RAW;
+ if((error = getaddrinfo(arg, NULL, &hints, &res)) != 0) {
errno = 0;
- crash("Failed to resolve %s", arg);
+ crash("Failed to resolve %s: %s", arg, gai_strerror(error));
return -1;
}
+ address_family = res->ai_family;
}
/* possibly add all the IP's as targets */
- for(i = 0; he->h_addr_list[i]; i++) {
- in = (struct in_addr *)he->h_addr_list[i];
- add_target_ip(arg, in);
+ for(p = res; p != NULL; p = p->ai_next) {
+ memcpy(&ip, p->ai_addr, p->ai_addrlen);
+ add_target_ip(arg, &ip);
/* this is silly, but it works */
if(mode == MODE_HOSTCHECK || mode == MODE_ALL) {
@@ -1193,6 +1397,7 @@ add_target(char *arg)
}
break;
}
+ freeaddrinfo(res);
return 0;
}
@@ -1203,7 +1408,7 @@ set_source_ip(char *arg)
struct sockaddr_in src;
memset(&src, 0, sizeof(src));
- src.sin_family = AF_INET;
+ src.sin_family = address_family;
if((src.sin_addr.s_addr = inet_addr(arg)) == INADDR_NONE)
src.sin_addr.s_addr = get_ip_address(arg);
if(bind(icmp_sock, (struct sockaddr *)&src, sizeof(src)) == -1)
@@ -1311,12 +1516,12 @@ get_threshold(char *str, threshold *th)
unsigned short
icmp_checksum(unsigned short *p, int n)
{
- register unsigned short cksum;
- register long sum = 0;
+ unsigned short cksum;
+ long sum = 0;
- while(n > 1) {
+ while(n > 2) {
sum += *p++;
- n -= 2;
+ n -= sizeof(unsigned short);
}
/* mop up the occasional odd byte */
@@ -1347,6 +1552,8 @@ print_help(void)
printf (" %s\n", "-H");
printf (" %s\n", _("specify a target"));
+ printf (" %s\n", "[-4|-6]");
+ printf (" %s\n", _("Use IPv4 (default) or IPv6 to communicate with the targets"));
printf (" %s\n", "-w");
printf (" %s", _("warning threshold (currently "));
printf ("%0.3fms,%u%%)\n", (float)warn.rta / 1000, warn.pl);
diff --git a/plugins/check_dbi.c b/plugins/check_dbi.c
index 826eb8d9..ced13d05 100644
--- a/plugins/check_dbi.c
+++ b/plugins/check_dbi.c
@@ -35,6 +35,7 @@ const char *email = "devel@monitoring-plugins.org";
#include "common.h"
#include "utils.h"
+#include "utils_cmd.h"
#include "netutils.h"
diff --git a/plugins/check_dns.c b/plugins/check_dns.c
index f2061636..d4d0b885 100644
--- a/plugins/check_dns.c
+++ b/plugins/check_dns.c
@@ -56,6 +56,7 @@ char **expected_address = NULL;
int expected_address_cnt = 0;
int expect_authority = FALSE;
+int all_match = FALSE;
thresholds *time_thresholds = NULL;
static int
@@ -168,8 +169,8 @@ main (int argc, char **argv)
temp_buffer++;
/* Strip leading spaces */
- for (; *temp_buffer != '\0' && *temp_buffer == ' '; temp_buffer++)
- /* NOOP */;
+ while (*temp_buffer == ' ')
+ temp_buffer++;
strip(temp_buffer);
if (temp_buffer==NULL || strlen(temp_buffer)==0) {
@@ -228,16 +229,27 @@ main (int argc, char **argv)
if (result == STATE_OK && expected_address_cnt > 0) {
result = STATE_CRITICAL;
temp_buffer = "";
+ unsigned long expect_match = (1 << expected_address_cnt) - 1;
+ unsigned long addr_match = (1 << n_addresses) - 1;
for (i=0; i<expected_address_cnt; i++) {
+ int j;
/* check if we get a match on 'raw' ip or cidr */
- if ( strcmp(address, expected_address[i]) == 0
- || ip_match_cidr(address, expected_address[i]) )
- result = STATE_OK;
+ for (j=0; j<n_addresses; j++) {
+ if ( strcmp(addresses[j], expected_address[i]) == 0
+ || ip_match_cidr(addresses[j], expected_address[i]) ) {
+ result = STATE_OK;
+ addr_match &= ~(1 << j);
+ expect_match &= ~(1 << i);
+ }
+ }
/* prepare an error string */
xasprintf(&temp_buffer, "%s%s; ", temp_buffer, expected_address[i]);
}
+ /* check if expected_address must cover all in addresses and none may be missing */
+ if (all_match && (expect_match != 0 || addr_match != 0))
+ result = STATE_CRITICAL;
if (result == STATE_CRITICAL) {
/* Strip off last semicolon... */
temp_buffer[strlen(temp_buffer)-2] = '\0';
@@ -401,6 +413,7 @@ process_arguments (int argc, char **argv)
{"reverse-server", required_argument, 0, 'r'},
{"expected-address", required_argument, 0, 'a'},
{"expect-authority", no_argument, 0, 'A'},
+ {"all", no_argument, 0, 'L'},
{"warning", required_argument, 0, 'w'},
{"critical", required_argument, 0, 'c'},
{0, 0, 0, 0}
@@ -414,7 +427,7 @@ process_arguments (int argc, char **argv)
strcpy (argv[c], "-t");
while (1) {
- c = getopt_long (argc, argv, "hVvAt:H:s:r:a:w:c:", long_opts, &opt_index);
+ c = getopt_long (argc, argv, "hVvALt:H:s:r:a:w:c:", long_opts, &opt_index);
if (c == -1 || c == EOF)
break;
@@ -462,6 +475,9 @@ process_arguments (int argc, char **argv)
case 'A': /* expect authority */
expect_authority = TRUE;
break;
+ case 'L': /* all must match */
+ all_match = TRUE;
+ break;
case 'w':
warning = optarg;
break;
@@ -530,14 +546,16 @@ print_help (void)
printf (" -a, --expected-address=IP-ADDRESS|CIDR|HOST\n");
printf (" %s\n", _("Optional IP-ADDRESS/CIDR you expect the DNS server to return. HOST must end"));
printf (" %s\n", _("with a dot (.). This option can be repeated multiple times (Returns OK if any"));
- printf (" %s\n", _("value match). If multiple addresses are returned at once, you have to match"));
- printf (" %s\n", _("the whole string of addresses separated with commas (sorted alphabetically)."));
+ printf (" %s\n", _("value matches)."));
printf (" -A, --expect-authority\n");
printf (" %s\n", _("Optionally expect the DNS server to be authoritative for the lookup"));
printf (" -w, --warning=seconds\n");
printf (" %s\n", _("Return warning if elapsed time exceeds value. Default off"));
printf (" -c, --critical=seconds\n");
printf (" %s\n", _("Return critical if elapsed time exceeds value. Default off"));
+ printf (" -L, --all\n");
+ printf (" %s\n", _("Return critical if the list of expected addresses does not match all addresses"));
+ printf (" %s\n", _("returned. Default off"));
printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
@@ -549,5 +567,5 @@ void
print_usage (void)
{
printf ("%s\n", _("Usage:"));
- printf ("%s -H host [-s server] [-a expected-address] [-A] [-t timeout] [-w warn] [-c crit]\n", progname);
+ printf ("%s -H host [-s server] [-a expected-address] [-A] [-t timeout] [-w warn] [-c crit] [-L]\n", progname);
}
diff --git a/plugins/check_hpjd.c b/plugins/check_hpjd.c
index f159f5a2..65465567 100644
--- a/plugins/check_hpjd.c
+++ b/plugins/check_hpjd.c
@@ -67,6 +67,7 @@ void print_usage (void);
char *community = NULL;
char *address = NULL;
char *port = NULL;
+int check_paper_out = 1;
int
main (int argc, char **argv)
@@ -240,7 +241,8 @@ main (int argc, char **argv)
strcpy (errmsg, _("Paper Jam"));
}
else if (paper_out) {
- result = STATE_WARNING;
+ if (check_paper_out)
+ result = STATE_WARNING;
strcpy (errmsg, _("Out of Paper"));
}
else if (line_status == OFFLINE) {
@@ -325,7 +327,7 @@ process_arguments (int argc, char **argv)
while (1) {
- c = getopt_long (argc, argv, "+hVH:C:p:", longopts, &option);
+ c = getopt_long (argc, argv, "+hVH:C:p:D", longopts, &option);
if (c == -1 || c == EOF || c == 1)
break;
@@ -347,6 +349,8 @@ process_arguments (int argc, char **argv)
usage2 (_("Port must be a positive short integer"), optarg);
else
port = atoi(optarg);
+ case 'D': /* disable paper out check*/
+ check_paper_out = 0;
break;
case 'V': /* version */
print_revision (progname, NP_VERSION);
@@ -420,6 +424,8 @@ print_help (void)
printf (" %s", _("Specify the port to check "));
printf (_("(default=%s)"), DEFAULT_PORT);
printf ("\n");
+ printf (" %s\n", "-D");
+ printf (" %s", _("Disable paper check "));
printf (UT_SUPPORT);
}
@@ -430,5 +436,5 @@ void
print_usage (void)
{
printf ("%s\n", _("Usage:"));
- printf ("%s -H host [-C community] [-p port]\n", progname);
+ printf ("%s -H host [-C community] [-p port] [-D]\n", progname);
}
diff --git a/plugins/check_http.c b/plugins/check_http.c
index 856e1e90..de59a068 100644
--- a/plugins/check_http.c
+++ b/plugins/check_http.c
@@ -1155,6 +1155,8 @@ check_http (void)
xasprintf (&msg,
_("Invalid HTTP response received from host on port %d: %s\n"),
server_port, status_line);
+ if (show_body)
+ xasprintf (&msg, _("%s\n%s"), msg, page);
die (STATE_CRITICAL, "HTTP CRITICAL - %s", msg);
}
diff --git a/plugins/check_pgsql.c b/plugins/check_pgsql.c
index 5cd47093..11ce6916 100644
--- a/plugins/check_pgsql.c
+++ b/plugins/check_pgsql.c
@@ -34,6 +34,7 @@ const char *email = "devel@monitoring-plugins.org";
#include "common.h"
#include "utils.h"
+#include "utils_cmd.h"
#include "netutils.h"
#include <libpq-fe.h>
diff --git a/plugins/check_smtp.c b/plugins/check_smtp.c
index 0fcf4c68..d37c57c8 100644
--- a/plugins/check_smtp.c
+++ b/plugins/check_smtp.c
@@ -293,6 +293,7 @@ main (int argc, char **argv)
printf("%s", buffer);
}
+ n = 0;
while (n < ncommands) {
xasprintf (&cmd_str, "%s%s", commands[n], "\r\n");
my_send(cmd_str, strlen(cmd_str));
diff --git a/plugins/common.h b/plugins/common.h
index 6bf4fca4..0f08e2f6 100644
--- a/plugins/common.h
+++ b/plugins/common.h
@@ -225,4 +225,18 @@ enum {
# define __attribute__(x) /* do nothing */
#endif
+/* Try sysconf(_SC_OPEN_MAX) first, as it can be higher than OPEN_MAX.
+ * If that fails and the macro isn't defined, we fall back to an educated
+ * guess. There's no guarantee that our guess is adequate and the program
+ * will die with SIGSEGV if it isn't and the upper boundary is breached. */
+#define DEFAULT_MAXFD 256 /* fallback value if no max open files value is set */
+#define MAXFD_LIMIT 8192 /* upper limit of open files */
+#ifdef _SC_OPEN_MAX
+static long maxfd = 0;
+#elif defined(OPEN_MAX)
+# define maxfd OPEN_MAX
+#else /* sysconf macro unavailable, so guess (may be wildly inaccurate) */
+# define maxfd DEFAULT_MAXFD
+#endif
+
#endif /* _COMMON_H_ */
diff --git a/plugins/popen.c b/plugins/popen.c
index 592263fd..116d168d 100644
--- a/plugins/popen.c
+++ b/plugins/popen.c
@@ -78,7 +78,6 @@ RETSIGTYPE popen_timeout_alarm_handler (int);
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
-int open_max (void); /* {Prog openmax} */
static void err_sys (const char *, ...) __attribute__((noreturn,format(printf, 1, 2)));
char *rtrim (char *, const char *);
@@ -86,7 +85,6 @@ char *pname = NULL; /* caller can set this from argv[0] */
/*int *childerr = NULL;*//* ptr to array allocated at run-time */
/*extern pid_t *childpid = NULL; *//* ptr to array allocated at run-time */
-static int maxfd; /* from our open_max(), {Prog openmax} */
#ifdef REDHAT_SPOPEN_ERROR
static volatile int childtermd = 0;
@@ -187,13 +185,11 @@ spopen (const char *cmdstring)
argv[i] = NULL;
if (childpid == NULL) { /* first time through */
- maxfd = open_max (); /* allocate zeroed out array for child pids */
if ((childpid = calloc ((size_t)maxfd, sizeof (pid_t))) == NULL)
return (NULL);
}
if (child_stderr_array == NULL) { /* first time through */
- maxfd = open_max (); /* allocate zeroed out array for child pids */
if ((child_stderr_array = calloc ((size_t)maxfd, sizeof (int))) == NULL)
return (NULL);
}
@@ -273,15 +269,6 @@ spclose (FILE * fp)
return (1);
}
-#ifdef OPEN_MAX
-static int openmax = OPEN_MAX;
-#else
-static int openmax = 0;
-#endif
-
-#define OPEN_MAX_GUESS 256 /* if OPEN_MAX is indeterminate */
- /* no guarantee this is adequate */
-
#ifdef REDHAT_SPOPEN_ERROR
RETSIGTYPE
popen_sigchld_handler (int signo)
@@ -311,22 +298,6 @@ popen_timeout_alarm_handler (int signo)
}
-int
-open_max (void)
-{
- if (openmax == 0) { /* first time through */
- errno = 0;
- if ((openmax = sysconf (_SC_OPEN_MAX)) < 0) {
- if (errno == 0)
- openmax = OPEN_MAX_GUESS; /* it's indeterminate */
- else
- err_sys (_("sysconf error for _SC_OPEN_MAX"));
- }
- }
- return (openmax);
-}
-
-
/* Fatal error related to a system call.
* Print a message and die. */
diff --git a/plugins/runcmd.c b/plugins/runcmd.c
index 1a7c904f..c3828678 100644
--- a/plugins/runcmd.c
+++ b/plugins/runcmd.c
@@ -67,19 +67,6 @@
* occur in any number of threads simultaneously. */
static pid_t *np_pids = NULL;
-/* Try sysconf(_SC_OPEN_MAX) first, as it can be higher than OPEN_MAX.
- * If that fails and the macro isn't defined, we fall back to an educated
- * guess. There's no guarantee that our guess is adequate and the program
- * will die with SIGSEGV if it isn't and the upper boundary is breached. */
-#ifdef _SC_OPEN_MAX
-static long maxfd = 0;
-#elif defined(OPEN_MAX)
-# define maxfd OPEN_MAX
-#else /* sysconf macro unavailable, so guess (may be wildly inaccurate) */
-# define maxfd 256
-#endif
-
-
/** prototypes **/
static int np_runcmd_open(const char *, int *, int *)
__attribute__((__nonnull__(1, 2, 3)));
diff --git a/plugins/t/NPTest.cache.travis b/plugins/t/NPTest.cache.travis
index 6ee45053..9b9f8059 100644
--- a/plugins/t/NPTest.cache.travis
+++ b/plugins/t/NPTest.cache.travis
@@ -50,5 +50,5 @@
'NP_SNMP_USER' => '',
'NP_SSH_CONFIGFILE' => '~/.ssh/config',
'NP_SSH_HOST' => 'localhost',
- 'NP_SSH_IDENTITY' => '~/.ssh/id_dsa'
+ 'NP_SSH_IDENTITY' => '~/.ssh/id_rsa'
}
diff --git a/plugins/tests/certs/server-cert.pem b/plugins/tests/certs/server-cert.pem
index 549e4f7e..b84b91d2 100644
--- a/plugins/tests/certs/server-cert.pem
+++ b/plugins/tests/certs/server-cert.pem
@@ -1,21 +1,24 @@
-----BEGIN CERTIFICATE-----
-MIIDYzCCAsygAwIBAgIJAL8LkpNwzYdxMA0GCSqGSIb3DQEBBAUAMH8xCzAJBgNV
-BAYTAlVLMRMwEQYDVQQIEwpEZXJieXNoaXJlMQ8wDQYDVQQHEwZCZWxwZXIxFzAV
-BgNVBAoTDk5hZ2lvcyBQbHVnaW5zMREwDwYDVQQDEwhUb24gVm9vbjEeMBwGCSqG
-SIb3DQEJARYPdG9udm9vbkBtYWMuY29tMB4XDTA5MDMwNTIxNDEyOFoXDTE5MDMw
-MzIxNDEyOFowfzELMAkGA1UEBhMCVUsxEzARBgNVBAgTCkRlcmJ5c2hpcmUxDzAN
-BgNVBAcTBkJlbHBlcjEXMBUGA1UEChMOTmFnaW9zIFBsdWdpbnMxETAPBgNVBAMT
-CFRvbiBWb29uMR4wHAYJKoZIhvcNAQkBFg90b252b29uQG1hYy5jb20wgZ8wDQYJ
-KoZIhvcNAQEBBQADgY0AMIGJAoGBAKcWMBtNtfY8vZXk0SN6/EYTVN/LOvaOSegy
-oVdLoGwuwjagk+XmCzvCqHZRp8lnCLay7AO8AQI7TSN02ihCcSrgGA9OT+HciIJ1
-l5/kEYUAuA1PR6YKK/T713zUAlMzy2tsugx5+xSsSEwsXkmne52jJiG/wuE5CLT0
-9pF8HQqHAgMBAAGjgeYwgeMwHQYDVR0OBBYEFGioSPQ/rdE19+zaeY2YvHTXlUDI
-MIGzBgNVHSMEgaswgaiAFGioSPQ/rdE19+zaeY2YvHTXlUDIoYGEpIGBMH8xCzAJ
-BgNVBAYTAlVLMRMwEQYDVQQIEwpEZXJieXNoaXJlMQ8wDQYDVQQHEwZCZWxwZXIx
-FzAVBgNVBAoTDk5hZ2lvcyBQbHVnaW5zMREwDwYDVQQDEwhUb24gVm9vbjEeMBwG
-CSqGSIb3DQEJARYPdG9udm9vbkBtYWMuY29tggkAvwuSk3DNh3EwDAYDVR0TBAUw
-AwEB/zANBgkqhkiG9w0BAQQFAAOBgQCdqasaIO6JiV5ONFG6Tr1++85UfEdZKMUX
-N2NHiNNUunolIZEYR+dW99ezKmHlDiQ/tMgoLVYpl2Ubho2pAkLGQR+W0ZASgWQ1
-NjfV27Rv0y6lYQMTA0lVAU93L1x9reo3FMedmL5+H+lIEpLCxEPtAJNISrJOneZB
-W5jDadwkoQ==
+MIIEBjCCAu6gAwIBAgIJANbQ5QQrKhUGMA0GCSqGSIb3DQEBCwUAMIGXMQswCQYD
+VQQGEwJERTEQMA4GA1UECAwHQmF2YXJpYTEPMA0GA1UEBwwGTXVuaWNoMRswGQYD
+VQQKDBJNb25pdG9yaW5nIFBsdWdpbnMxGzAZBgNVBAMMEk1vbml0b3JpbmcgUGx1
+Z2luczErMCkGCSqGSIb3DQEJARYcZGV2ZWxAbW9uaXRvcmluZy1wbHVnaW5zLm9y
+ZzAeFw0xOTAyMTkxNTMxNDRaFw0yOTAyMTYxNTMxNDRaMIGXMQswCQYDVQQGEwJE
+RTEQMA4GA1UECAwHQmF2YXJpYTEPMA0GA1UEBwwGTXVuaWNoMRswGQYDVQQKDBJN
+b25pdG9yaW5nIFBsdWdpbnMxGzAZBgNVBAMMEk1vbml0b3JpbmcgUGx1Z2luczEr
+MCkGCSqGSIb3DQEJARYcZGV2ZWxAbW9uaXRvcmluZy1wbHVnaW5zLm9yZzCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKgV2yp8pQvJuN+aJGdAe6Hd0tja
+uteCPcNIcM92WLOF69TLTSYon1XDon4tHTh4Z5d4lD8bfsGzFVBmDSgWidhAUf+v
+EqEXwbp293ej/Frc0pXCvmrz6kI1tWrLtQhL/VdbxFYxhV7JjKb+PY3SxGFpSLPe
+PQ/5SwVndv7rZIwcjseL22K5Uy2TIrkgzzm2pRs/IvoxRybYr/+LGoHyrtJC6AO8
+ylp8A/etL0gwtUvRnrnZeTQ2pA1uZ5QN3anTL8JP/ZRZYNegIkaawqMtTKbhM6pi
+u3/4a3Uppvt0y7vmGfQlYejxCpICnMrvHMpw8L58zv/98AbCGjDU3UwCt6MCAwEA
+AaNTMFEwHQYDVR0OBBYEFG/UH6nGYPlVcM75UXzXBF5GZyrcMB8GA1UdIwQYMBaA
+FG/UH6nGYPlVcM75UXzXBF5GZyrcMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN
+AQELBQADggEBAGwitJPOnlIKLndNf+iCLMIs0dxsl8kAaejFcjoT0n4ja7Y6Zrqz
+VSIidzz9vQWvy24xKJpAOdj/iLRHCUOG+Pf5fA6+/FiuqXr6gE2/lm0eC58BNONr
+E5OzjQ/VoQ8RX4hDntgu6FYbaVa/vhwn16igt9qmdNGGZXf2/+DM3JADwyaA4EK8
+vm7KdofX9zkxXecHPNvf3jiVLPiDDt6tkGpHPEsyP/yc+RUdltUeZvHfliV0cCuC
+jJX+Fm9ysjSpHIFFr+jUMuMHibWoOD8iy3eYxfCDoWsH488pCbj8MNuAq6vd6DBk
+bOZxDz43vjWuYMkwXJTxJQh7Pne6kK0vE1g=
-----END CERTIFICATE-----
diff --git a/plugins/tests/certs/server-key.pem b/plugins/tests/certs/server-key.pem
index eacaeaa3..11947555 100644
--- a/plugins/tests/certs/server-key.pem
+++ b/plugins/tests/certs/server-key.pem
@@ -1,15 +1,28 @@
------BEGIN RSA PRIVATE KEY-----
-MIICWwIBAAKBgQCnFjAbTbX2PL2V5NEjevxGE1Tfyzr2jknoMqFXS6BsLsI2oJPl
-5gs7wqh2UafJZwi2suwDvAECO00jdNooQnEq4BgPTk/h3IiCdZef5BGFALgNT0em
-Civ0+9d81AJTM8trbLoMefsUrEhMLF5Jp3udoyYhv8LhOQi09PaRfB0KhwIDAQAB
-AoGAfpxclcP8N3vteXErXURrd7pcXT0GECDgNjhvc9PV20RPXM+vYs1AA+fMeeQE
-TaRqwO6x016aMRO4rz5ztYArecTBznkds1k59pkN/Ne/nsueU4tvGK8MNyS2o986
-Voohqkaq4Lcy1bcHJb9su1ELjegEr1R76Mz452Hsy+uTbAECQQDcg/tZWKVeh5CQ
-dOEB3YWHwfn0NDgfPm/X2i2kAZ7n7URaUy/ffdlfsrr1mBtHCfedLoOxmmlNfEpM
-hXAAurSHAkEAwfk7fEb0iN0Sj9gTozO7c6Ky10KwePZyjVzqSQIiJq3NX8BEaIeb
-51TXxE5VxaLjjMLRkA0hWTYXClgERFZ6AQJAN7ChPqwzf08PRFwwIw911JY5cOHr
-NoDHMCUql5vNLNdwBruxgGjBB/kUXEfgw60RusFvgt/zLh1wiii844JDawJAGQBF
-sYP3urg7zzx7c3qUe5gJ0wLuefjR1PSX4ecbfb7DDMdcSdjIuG1QDiZGmd2f1KG7
-nwSCOtxk5dloW2KGAQJAQh/iBn0QhfKLFAP5eZBVk8E8XlZuw+S2DLy5SnBlIiYJ
-GB5I2OClgtudXMv1labFrcST8O9eFrtsrhU1iUGUOw==
------END RSA PRIVATE KEY-----
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCoFdsqfKULybjf
+miRnQHuh3dLY2rrXgj3DSHDPdlizhevUy00mKJ9Vw6J+LR04eGeXeJQ/G37BsxVQ
+Zg0oFonYQFH/rxKhF8G6dvd3o/xa3NKVwr5q8+pCNbVqy7UIS/1XW8RWMYVeyYym
+/j2N0sRhaUiz3j0P+UsFZ3b+62SMHI7Hi9tiuVMtkyK5IM85tqUbPyL6MUcm2K//
+ixqB8q7SQugDvMpafAP3rS9IMLVL0Z652Xk0NqQNbmeUDd2p0y/CT/2UWWDXoCJG
+msKjLUym4TOqYrt/+Gt1Kab7dMu75hn0JWHo8QqSApzK7xzKcPC+fM7//fAGwhow
+1N1MArejAgMBAAECggEANuvdTwanTzC8jaNqHaq+OuemS2E9B8nwsGxtH/zFgvNR
+WZiMPtmrJnTkFWJcV+VPw/iMSAqN4nDHmBugVOb4Z4asxGTKK4T9shXJSnh0rqPU
+00ZsvbmxY6z0+E5TesCJqQ+9GYTY1V357V7JchvaOxIRxWPqg9urHbru8OCtW/I5
+Fh5HPUZlgCvlMpjlhyjydIf/oXyVA3RNsXlwe8+2cKuGIrjEzm2j9o3VF0sctTX0
+ItP8A9qDmDQN7GIWX0MW6gncojpS1omC2wcFsdjj/xfPyiDal1X4aq/2YqG8351c
+YlM/+6Va0u9WWE/i64gASTAVqpMV4Yg8y0gGycuA0QKBgQDbgI2QeLd3FvMcURiU
+l3w9qJgw/Jp3jaNC/9LkVGGz4f4lKKB67lPZvI4noMK8GqO/LcXgqP/RY1oJojoA
+/6JKVvzYGASZ7VgMoG9bk1AneP1PGdibuTUEwimGlcObxnDFIC/yjwPFu3jIdqdS
+zZi1RZzyqAogN5y3SBEypSmn9wKBgQDECKsqqlcizmCl8v5aVk875AzGN+DOHZqx
+bkmztlnLO/2e2Fmk3G5Vvnui0FYisf8Eq19tUTQCF6lSfJlGQeFAT119wkFZhLu+
+FfLGqoEMH0ijJg/8PpdpFRK3I94YcISoTNN6yxMvE6xdDGfKCt5a+IX5bwQi9Zdc
+B242gEc6tQKBgA6tM8n7KFlAIZU9HuWgk2AUC8kKutFPmSD7tgAqXDYI4FNfugs+
+MEEYyHCB4UNujJBV4Ss6YZCAkh6eyD4U2aca1eElCfm40vBVMdzvpqZdAqLtWXxg
+D9l3mgszrFaYGCY2Fr6jLV9lP5g3xsxUjudf9jSLY9HvpfzjRrMaNATVAoGBALTl
+/vYfPMucwKlC5B7++J0e4/7iv6vUu9SyHocdZh1anb9AjPDKjXLIlZT4RhQ8R0XK
+0wOw5JpttU2uN08TKkbLNk3/vYhbKVjPLjrQSseh8sjDLgsqw1QwIxYnniLVakVY
+p+rvjSNrNyqicQCMKQavwgocvSd5lJRTMwxOMezlAoGBAKWj71BX+0CK00/2S6lC
+TcNcuUPG0d8y1czZ4q6tUlG4htwq1FMOpaghATXjkdsOGTLS+H1aA0Kt7Ai9zDhc
+/bzOJEJ+jvBXV4Gcs7jl1r/HTKv0tT9ZSI5Vzkida0rfqxDGzcMVlLuCdH0cb8Iu
+N0wdmCAqlQwHR13+F1zrAD7V
+-----END PRIVATE KEY-----
diff --git a/plugins/tests/check_http.t b/plugins/tests/check_http.t
index d6d31de1..006f1339 100755
--- a/plugins/tests/check_http.t
+++ b/plugins/tests/check_http.t
@@ -4,13 +4,13 @@
#
# To create the https server certificate:
# openssl req -new -x509 -keyout server-key.pem -out server-cert.pem -days 3650 -nodes
-# Country Name (2 letter code) [AU]:UK
-# State or Province Name (full name) [Some-State]:Derbyshire
-# Locality Name (eg, city) []:Belper
+# Country Name (2 letter code) [AU]:DE
+# State or Province Name (full name) [Some-State]:Bavaria
+# Locality Name (eg, city) []:Munich
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:Monitoring Plugins
# Organizational Unit Name (eg, section) []:
-# Common Name (eg, YOUR name) []:Ton Voon
-# Email Address []:tonvoon@mac.com
+# Common Name (e.g. server FQDN or YOUR name) []:Monitoring Plugins
+# Email Address []:devel@monitoring-plugins.org
use strict;
use Test::More;
@@ -194,16 +194,16 @@ SKIP: {
$result = NPTest->testCmd( "$command -p $port_https -S -C 14" );
is( $result->return_code, 0, "$command -p $port_https -S -C 14" );
- is( $result->output, 'OK - Certificate \'Ton Voon\' will expire on Sun Mar 3 21:41:28 2019 +0000.', "output ok" );
+ is( $result->output, "OK - Certificate 'Monitoring Plugins' will expire on Fri Feb 16 15:31:44 2029 +0000.", "output ok" );
$result = NPTest->testCmd( "$command -p $port_https -S -C 14000" );
is( $result->return_code, 1, "$command -p $port_https -S -C 14000" );
- like( $result->output, '/WARNING - Certificate \'Ton Voon\' expires in \d+ day\(s\) \(Sun Mar 3 21:41:28 2019 \+0000\)./', "output ok" );
+ like( $result->output, '/WARNING - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(Fri Feb 16 15:31:44 2029 \+0000\)./', "output ok" );
# Expired cert tests
$result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" );
is( $result->return_code, 2, "$command -p $port_https -S -C 13960,14000" );
- like( $result->output, '/CRITICAL - Certificate \'Ton Voon\' expires in \d+ day\(s\) \(Sun Mar 3 21:41:28 2019 \+0000\)./', "output ok" );
+ like( $result->output, '/CRITICAL - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(Fri Feb 16 15:31:44 2029 \+0000\)./', "output ok" );
$result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" );
is( $result->return_code, 2, "$command -p $port_https_expired -S -C 7" );
diff --git a/plugins/tests/check_snmp.t b/plugins/tests/check_snmp.t
index 73a68b20..85d6bf55 100755
--- a/plugins/tests/check_snmp.t
+++ b/plugins/tests/check_snmp.t
@@ -7,6 +7,7 @@ use strict;
use Test::More;
use NPTest;
use FindBin qw($Bin);
+use POSIX qw/strftime/;
my $tests = 67;
# Check that all dependent modules are available
@@ -37,6 +38,7 @@ if ($@) {
my $port_snmp = 16100 + int(rand(100));
+my $faketime = -x '/usr/bin/faketime' ? 1 : 0;
# Start up server
my @pids;
@@ -118,77 +120,81 @@ like($res->output, '/'.quotemeta('SNMP OK - And now have fun with with this: \"C
"And now have fun with with this: \"C:\\\\\"
because we\'re not done yet!"').'/m', "Attempt to confuse parser No.3");
-system("rm -f ".$ENV{'MP_STATE_PATH'}."/check_snmp/*");
-$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -w 600" );
-is($res->return_code, 0, "Returns OK");
-is($res->output, "No previous data to calculate rate - assume okay");
+system("rm -f ".$ENV{'MP_STATE_PATH'}."/*/check_snmp/*");
-# Need to sleep, otherwise duration=0
-sleep 1;
+# run rate checks with faketime. rate checks depend on the exact amount of time spend between the
+# plugin runs which may fail on busy machines.
+# using faketime removes this race condition and also saves all the sleeps in between.
+SKIP: {
+ skip "No faketime binary found", 28 if !$faketime;
-$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -w 600" );
-is($res->return_code, 1, "WARNING - due to going above rate calculation" );
-is($res->output, "SNMP RATE WARNING - *666* | iso.3.6.1.4.1.8072.3.2.67.10=666;600 ");
+ my $ts = time();
+ $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -w 600" );
+ is($res->return_code, 0, "Returns OK");
+ is($res->output, "No previous data to calculate rate - assume okay");
-$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -w 600" );
-is($res->return_code, 3, "UNKNOWN - basically the divide by zero error" );
-is($res->output, "Time duration between plugin calls is invalid");
+ # test rate 1 second later
+ $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+1))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -w 600" );
+ is($res->return_code, 1, "WARNING - due to going above rate calculation" );
+ is($res->output, "SNMP RATE WARNING - *666* | iso.3.6.1.4.1.8072.3.2.67.10=666;600 ");
+ # test rate with same time
+ $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+1))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -w 600" );
+ is($res->return_code, 3, "UNKNOWN - basically the divide by zero error" );
+ is($res->output, "Time duration between plugin calls is invalid");
-$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets" );
-is($res->return_code, 0, "OK for first call" );
-is($res->output, "No previous data to calculate rate - assume okay" );
-# Need to sleep, otherwise duration=0
-sleep 1;
+ $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets" );
+ is($res->return_code, 0, "OK for first call" );
+ is($res->output, "No previous data to calculate rate - assume okay" );
-$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets" );
-is($res->return_code, 0, "OK as no thresholds" );
-is($res->output, "SNMP RATE OK - inoctets 666 | inoctets=666 ", "Check label");
+ # test rate 1 second later
+ $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+1))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets" );
+ is($res->return_code, 0, "OK as no thresholds" );
+ is($res->output, "SNMP RATE OK - inoctets 666 | inoctets=666 ", "Check label");
-sleep 2;
+ # test rate 3 seconds later
+ $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+3))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets" );
+ is($res->return_code, 0, "OK as no thresholds" );
+ is($res->output, "SNMP RATE OK - inoctets 333 | inoctets=333 ", "Check rate decreases due to longer interval");
-$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets" );
-is($res->return_code, 0, "OK as no thresholds" );
-is($res->output, "SNMP RATE OK - inoctets 333 | inoctets=333 ", "Check rate decreases due to longer interval");
+ # label performance data check
+ $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l test" );
+ is($res->return_code, 0, "OK as no thresholds" );
+ is($res->output, "SNMP OK - test 67996 | test=67996c ", "Check label");
-# label performance data check
-$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l test" );
-is($res->return_code, 0, "OK as no thresholds" );
-is($res->output, "SNMP OK - test 67996 | test=67996c ", "Check label");
+ $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l \"test'test\"" );
+ is($res->return_code, 0, "OK as no thresholds" );
+ is($res->output, "SNMP OK - test'test 68662 | \"test'test\"=68662c ", "Check label");
-$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l \"test'test\"" );
-is($res->return_code, 0, "OK as no thresholds" );
-is($res->output, "SNMP OK - test'test 68662 | \"test'test\"=68662c ", "Check label");
+ $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l 'test\"test'" );
+ is($res->return_code, 0, "OK as no thresholds" );
+ is($res->output, "SNMP OK - test\"test 69328 | 'test\"test'=69328c ", "Check label");
-$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l 'test\"test'" );
-is($res->return_code, 0, "OK as no thresholds" );
-is($res->output, "SNMP OK - test\"test 69328 | 'test\"test'=69328c ", "Check label");
+ $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l test -O" );
+ is($res->return_code, 0, "OK as no thresholds" );
+ is($res->output, "SNMP OK - test 69994 | iso.3.6.1.4.1.8072.3.2.67.10=69994c ", "Check label");
-$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l test -O" );
-is($res->return_code, 0, "OK as no thresholds" );
-is($res->output, "SNMP OK - test 69994 | iso.3.6.1.4.1.8072.3.2.67.10=69994c ", "Check label");
+ $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10" );
+ is($res->return_code, 0, "OK as no thresholds" );
+ is($res->output, "SNMP OK - 70660 | iso.3.6.1.4.1.8072.3.2.67.10=70660c ", "Check label");
-$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10" );
-is($res->return_code, 0, "OK as no thresholds" );
-is($res->output, "SNMP OK - 70660 | iso.3.6.1.4.1.8072.3.2.67.10=70660c ", "Check label");
+ $res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l 'test test'" );
+ is($res->return_code, 0, "OK as no thresholds" );
+ is($res->output, "SNMP OK - test test 71326 | 'test test'=71326c ", "Check label");
-$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 -l 'test test'" );
-is($res->return_code, 0, "OK as no thresholds" );
-is($res->output, "SNMP OK - test test 71326 | 'test test'=71326c ", "Check label");
+ $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets_per_minute --rate-multiplier=60" );
+ is($res->return_code, 0, "OK for first call" );
+ is($res->output, "No previous data to calculate rate - assume okay" );
-$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets_per_minute --rate-multiplier=60" );
-is($res->return_code, 0, "OK for first call" );
-is($res->output, "No previous data to calculate rate - assume okay" );
-
-# Need to sleep, otherwise duration=0
-sleep 1;
+ # test 1 second later
+ $res = NPTest->testCmd("LC_TIME=C TZ=UTC faketime -f '".strftime("%Y-%m-%d %H:%M:%S", localtime($ts+1))."' ./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets_per_minute --rate-multiplier=60" );
+ is($res->return_code, 0, "OK as no thresholds" );
+ is($res->output, "SNMP RATE OK - inoctets_per_minute 39960 | inoctets_per_minute=39960 ", "Checking multiplier");
+};
-$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.10 --rate -l inoctets_per_minute --rate-multiplier=60" );
-is($res->return_code, 0, "OK as no thresholds" );
-is($res->output, "SNMP RATE OK - inoctets_per_minute 39960 | inoctets_per_minute=39960 ", "Checking multiplier");
$res = NPTest->testCmd( "./check_snmp -H 127.0.0.1 -C public -p $port_snmp -o .1.3.6.1.4.1.8072.3.2.67.11 -s '\"stringtests\"'" );
diff --git a/plugins/utils.c b/plugins/utils.c
index 231af92b..ee620133 100644
--- a/plugins/utils.c
+++ b/plugins/utils.c
@@ -36,9 +36,6 @@ extern const char *progname;
#define STRLEN 64
#define TXTBLK 128
-unsigned int timeout_state = STATE_CRITICAL;
-unsigned int timeout_interval = DEFAULT_SOCKET_TIMEOUT;
-
time_t start_time, end_time;
/* **************************************************************************
@@ -148,33 +145,6 @@ print_revision (const char *command_name, const char *revision)
command_name, revision, PACKAGE, VERSION);
}
-const char *
-state_text (int result)
-{
- switch (result) {
- case STATE_OK:
- return "OK";
- case STATE_WARNING:
- return "WARNING";
- case STATE_CRITICAL:
- return "CRITICAL";
- case STATE_DEPENDENT:
- return "DEPENDENT";
- default:
- return "UNKNOWN";
- }
-}
-
-void
-timeout_alarm_handler (int signo)
-{
- if (signo == SIGALRM) {
- printf (_("%s - Plugin timed out after %d seconds\n"),
- state_text(timeout_state), timeout_interval);
- exit (timeout_state);
- }
-}
-
int
is_numeric (char *number)
{
@@ -708,4 +678,3 @@ char *sperfdata_int (const char *label,
return data;
}
-
diff --git a/plugins/utils.h b/plugins/utils.h
index a436e1ca..6aa316fe 100644
--- a/plugins/utils.h
+++ b/plugins/utils.h
@@ -29,13 +29,6 @@ suite of plugins. */
void support (void);
void print_revision (const char *, const char *);
-/* Handle timeouts */
-
-extern unsigned int timeout_state;
-extern unsigned int timeout_interval;
-
-RETSIGTYPE timeout_alarm_handler (int);
-
extern time_t start_time, end_time;
/* Test input types */
@@ -89,8 +82,6 @@ void usage4(const char *) __attribute__((noreturn));
void usage5(void) __attribute__((noreturn));
void usage_va(const char *fmt, ...) __attribute__((noreturn));
-const char *state_text (int);
-
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))