diff options
-rw-r--r-- | .travis.yml | 2 | ||||
-rw-r--r-- | NEWS | 8 | ||||
-rw-r--r-- | THANKS.in | 1 | ||||
-rw-r--r-- | plugins-root/check_dhcp.c | 2 | ||||
-rw-r--r-- | plugins/check_apt.c | 15 | ||||
-rw-r--r-- | plugins/check_dns.c | 44 | ||||
-rw-r--r-- | plugins/t/NPTest.cache.travis | 4 | ||||
-rw-r--r-- | plugins/t/check_apt.t | 18 | ||||
-rw-r--r-- | plugins/t/check_dns.t | 26 |
9 files changed, 103 insertions, 17 deletions
diff --git a/.travis.yml b/.travis.yml index 02a0eff3..78ebc30b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -54,7 +54,7 @@ install: - sudo apt-get install -qq --no-install-recommends autoconf automake - sudo apt-get install -qq --no-install-recommends faketime # Trusty related dependencies (not yet provided) - - sudo apt-get install -qq --no-install-recommends mariadb-client mariadb-server + - 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 before_script: # ensure we have a test database in place for tests @@ -1,5 +1,13 @@ This file documents the major additions and syntax changes between releases. +2.3 [...] + ENHANCEMENTS + check_dns: allow 'expected address' (-a) to be specified in CIDR notation + (IPv4 only). + + FIXES + Fix regression where check_dhcp was rereading response in a tight loop + 2.2 29th November 2016 ENHANCEMENTS The check_http -S/--ssl option now accepts the arguments "1.1" and "1.2" @@ -355,3 +355,4 @@ Michael Melcher Sven Geggus Thomas Kurschel Yannick Charton +Nicolai Søborg diff --git a/plugins-root/check_dhcp.c b/plugins-root/check_dhcp.c index 88b7ca10..f4c2dafd 100644 --- a/plugins-root/check_dhcp.c +++ b/plugins-root/check_dhcp.c @@ -693,7 +693,7 @@ int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, st else{ bzero(&source_address,sizeof(source_address)); address_size=sizeof(source_address); - recv_result=recvfrom(sock,(char *)buffer,buffer_size,MSG_PEEK,(struct sockaddr *)&source_address,&address_size); + recv_result=recvfrom(sock,(char *)buffer,buffer_size,0,(struct sockaddr *)&source_address,&address_size); if(verbose) printf("recv_result: %d\n",recv_result); diff --git a/plugins/check_apt.c b/plugins/check_apt.c index a639a411..c90b3df7 100644 --- a/plugins/check_apt.c +++ b/plugins/check_apt.c @@ -73,6 +73,7 @@ char* add_to_regexp(char *expr, const char *next); /* configuration variables */ static int verbose = 0; /* -v */ static int do_update = 0; /* whether to call apt-get update */ +static int only_critical = 0; /* whether to warn about non-critical updates */ static upgrade_type upgrade = UPGRADE; /* which type of upgrade to do */ static char *upgrade_opts = NULL; /* options to override defaults for upgrade */ static char *update_opts = NULL; /* options to override defaults for update */ @@ -110,7 +111,7 @@ int main (int argc, char **argv) { if(sec_count > 0){ result = max_state(result, STATE_CRITICAL); - } else if(packages_available > 0){ + } else if(packages_available > 0 && only_critical == 0){ result = max_state(result, STATE_WARNING); } else if(result > STATE_UNKNOWN){ result = STATE_UNKNOWN; @@ -148,12 +149,13 @@ int process_arguments (int argc, char **argv) { {"include", required_argument, 0, 'i'}, {"exclude", required_argument, 0, 'e'}, {"critical", required_argument, 0, 'c'}, + {"only-critical", no_argument, 0, 'o'}, {"input-file", required_argument, 0, INPUT_FILE_OPT}, {0, 0, 0, 0} }; while(1) { - c = getopt_long(argc, argv, "hVvt:u::U::d::ni:e:c:", longopts, NULL); + c = getopt_long(argc, argv, "hVvt:u::U::d::ni:e:c:o", longopts, NULL); if(c == -1 || c == EOF || c == 1) break; @@ -203,6 +205,9 @@ int process_arguments (int argc, char **argv) { case 'c': do_critical=add_to_regexp(do_critical, optarg); break; + case 'o': + only_critical=1; + break; case INPUT_FILE_OPT: input_filename = optarg; break; @@ -463,7 +468,11 @@ print_help (void) printf (" %s\n", _("upgrades for Debian and Ubuntu:")); printf (" \t\%s\n", SECURITY_RE); printf (" %s\n", _("Note that the package must first match the include list before its")); - printf (" %s\n\n", _("information is compared against the critical list.")); + printf (" %s\n", _("information is compared against the critical list.")); + printf (" %s\n", "-o, --only-critical"); + printf (" %s\n", _("Only warn about upgrades matching the critical list. The total number")); + printf (" %s\n", _("of upgrades will be printed, but any non-critical upgrades will not cause")); + printf (" %s\n\n", _("the plugin to return WARNING status.")); printf ("%s\n\n", _("The following options require root privileges and should be used with care:")); printf (" %s\n", "-u, --update=OPTS"); diff --git a/plugins/check_dns.c b/plugins/check_dns.c index 54ce7d16..5feafc80 100644 --- a/plugins/check_dns.c +++ b/plugins/check_dns.c @@ -42,6 +42,8 @@ const char *email = "devel@monitoring-plugins.org"; int process_arguments (int, char **); int validate_arguments (void); int error_scan (char *); +int ip_match_cidr(const char *, const char *); +unsigned long ip2long(const char *); void print_help (void); void print_usage (void); @@ -126,7 +128,7 @@ main (int argc, char **argv) if (verbose) puts(chld_out.line[i]); - if (strcasestr (chld_out.line[i], ".in-addr.arpa")) { + if (strcasestr (chld_out.line[i], ".in-addr.arpa") || strcasestr (chld_out.line[i], ".ip6.arpa")) { if ((temp_buffer = strstr (chld_out.line[i], "name = "))) addresses[n_addresses++] = strdup (temp_buffer + 7); else { @@ -226,9 +228,14 @@ main (int argc, char **argv) if (result == STATE_OK && expected_address_cnt > 0) { result = STATE_CRITICAL; temp_buffer = ""; + for (i=0; i<expected_address_cnt; i++) { - /* check if we get a match and prepare an error string */ - if (strcmp(address, expected_address[i]) == 0) result = STATE_OK; + /* 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; + + /* prepare an error string */ xasprintf(&temp_buffer, "%s%s; ", temp_buffer, expected_address[i]); } if (result == STATE_CRITICAL) { @@ -289,7 +296,32 @@ main (int argc, char **argv) return result; } +int +ip_match_cidr(const char *addr, const char *cidr_ro) +{ + char *subnet, *mask_c, *cidr = strdup(cidr_ro); + int mask; + subnet = strtok(cidr, "/"); + mask_c = strtok(NULL, "\0"); + if (!subnet || !mask_c) + return FALSE; + mask = atoi(mask_c); + + /* https://www.cryptobells.com/verifying-ips-in-a-subnet-in-php/ */ + return (ip2long(addr) & ~((1 << (32 - mask)) - 1)) == (ip2long(subnet) >> (32 - mask)) << (32 - mask); +} +unsigned long +ip2long(const char* src) { + unsigned long ip[4]; + /* http://computer-programming-forum.com/47-c-language/1376ffb92a12c471.htm */ + return (sscanf(src, "%3lu.%3lu.%3lu.%3lu", + &ip[0], &ip[1], &ip[2], &ip[3]) == 4 && + ip[0] < 256 && ip[1] < 256 && + ip[2] < 256 && ip[3] < 256) + ? ip[0] << 24 | ip[1] << 16 | ip[2] << 8 | ip[3] + : 0; +} int error_scan (char *input_buffer) @@ -494,9 +526,9 @@ print_help (void) printf (" %s\n", _("The name or address you want to query")); printf (" -s, --server=HOST\n"); printf (" %s\n", _("Optional DNS server you want to use for the lookup")); - printf (" -a, --expected-address=IP-ADDRESS|HOST\n"); - printf (" %s\n", _("Optional IP-ADDRESS you expect the DNS server to return. HOST must end with")); - printf (" %s\n", _("a dot (.). This option can be repeated multiple times (Returns OK if any")); + 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 (" -A, --expect-authority\n"); diff --git a/plugins/t/NPTest.cache.travis b/plugins/t/NPTest.cache.travis index bcec9855..38c0a6b2 100644 --- a/plugins/t/NPTest.cache.travis +++ b/plugins/t/NPTest.cache.travis @@ -4,8 +4,10 @@ 'NP_DNS_SERVER' => '8.8.8.8', 'NP_GOOD_NTP_SERVICE' => '', 'NP_HOSTNAME_INVALID' => 'nosuchhost', - 'NP_HOSTNAME_VALID' => 'monitoringplugins.org', + 'NP_HOSTNAME_VALID' => 'monitoring-plugins.org', 'NP_HOSTNAME_VALID_IP' => '130.133.8.40', + 'NP_HOSTNAME_VALID_CIDR' => '130.133.8.41/30', + 'NP_HOSTNAME_INVALID_CIDR' => '130.133.8.39/30', 'NP_HOSTNAME_VALID_REVERSE' => 'orwell.monitoring-plugins.org.', 'NP_HOST_DHCP_RESPONSIVE' => '', 'NP_HOST_NONRESPONSIVE' => '10.0.0.1', diff --git a/plugins/t/check_apt.t b/plugins/t/check_apt.t index 9ba0ff8e..430eb53e 100644 --- a/plugins/t/check_apt.t +++ b/plugins/t/check_apt.t @@ -23,7 +23,7 @@ sub make_result_regexp { } if (-x "./check_apt") { - plan tests => 28; + plan tests => 36; } else { plan skip_all => "No check_apt compiled"; } @@ -40,10 +40,18 @@ $result = NPTest->testCmd( sprintf($testfile_command, "", "debian2") ); is( $result->return_code, 1, "Debian apt output, warning" ); like( $result->output, make_result_regexp(13, 0), "Output correct" ); +$result = NPTest->testCmd( sprintf($testfile_command, "-o", "debian2") ); +is( $result->return_code, 0, "Debian apt output, no critical" ); +like( $result->output, make_result_regexp(13, 0), "Output correct" ); + $result = NPTest->testCmd( sprintf($testfile_command, "", "debian3") ); is( $result->return_code, 2, "Debian apt output, some critical" ); like( $result->output, make_result_regexp(19, 4), "Output correct" ); +$result = NPTest->testCmd( sprintf($testfile_command, "-o", "debian3") ); +is( $result->return_code, 2, "Debian apt output, some critical" ); +like( $result->output, make_result_regexp(19, 4), "Output correct" ); + $result = NPTest->testCmd( sprintf($testfile_command, "-c '^[^\\(]*\\(.* (Debian-Security:|Ubuntu:[^/]*/[^-]*-security)'", "debian3") ); is( $result->return_code, 2, "Debian apt output - should have same result when default security regexp specified via -c" ); like( $result->output, make_result_regexp(19, 4), "Output correct" ); @@ -52,6 +60,10 @@ $result = NPTest->testCmd( sprintf($testfile_command, "-i libc6", "debian3") ); is( $result->return_code, 1, "Debian apt output, filter for libc6" ); like( $result->output, make_result_regexp(3, 0), "Output correct" ); +$result = NPTest->testCmd( sprintf($testfile_command, "-i libc6", "debian3") ); +is( $result->return_code, 1, "Debian apt output, filter for libc6, not critical" ); +like( $result->output, make_result_regexp(3, 0), "Output correct" ); + $result = NPTest->testCmd( sprintf($testfile_command, "-i libc6 -i xen", "debian3") ); is( $result->return_code, 2, "Debian apt output, filter for libc6 and xen" ); like( $result->output, make_result_regexp(9, 4), "Output correct" ); @@ -64,6 +76,10 @@ $result = NPTest->testCmd( sprintf($testfile_command, "-e libc6", "debian3") ); is( $result->return_code, 2, "Debian apt output, filter out libc6" ); like( $result->output, make_result_regexp(16, 4), "Output correct" ); +$result = NPTest->testCmd( sprintf($testfile_command, "-e libc6 -o", "debian3") ); +is( $result->return_code, 2, "Debian apt output, filter out libc6, critical" ); +like( $result->output, make_result_regexp(16, 4), "Output correct" ); + $result = NPTest->testCmd( sprintf($testfile_command, "-e libc6 -e xen", "debian3") ); is( $result->return_code, 1, "Debian apt output, filter out libc6 and xen" ); like( $result->output, make_result_regexp(10, 0), "Output correct" ); diff --git a/plugins/t/check_dns.t b/plugins/t/check_dns.t index 035e7682..cdfbe60d 100644 --- a/plugins/t/check_dns.t +++ b/plugins/t/check_dns.t @@ -10,26 +10,38 @@ use NPTest; plan skip_all => "check_dns not compiled" unless (-x "check_dns"); -plan tests => 16; +plan tests => 19; my $successOutput = '/DNS OK: [\.0-9]+ seconds? response time/'; my $hostname_valid = getTestParameter( "NP_HOSTNAME_VALID", "A valid (known to DNS) hostname", - "monitoring-plugins.org" + "monitoring-plugins.org", ); my $hostname_valid_ip = getTestParameter( "NP_HOSTNAME_VALID_IP", "The IP address of the valid hostname $hostname_valid", - "66.118.156.50", + "130.133.8.40", + ); + +my $hostname_valid_cidr = getTestParameter( + "NP_HOSTNAME_VALID_CIDR", + "An valid CIDR range containing $hostname_valid_ip", + "130.133.8.41/30", + ); + +my $hostname_invalid_cidr = getTestParameter( + "NP_HOSTNAME_INVALID_CIDR", + "An (valid) CIDR range NOT containing $hostname_valid_ip", + "130.133.8.39/30", ); my $hostname_valid_reverse = getTestParameter( "NP_HOSTNAME_VALID_REVERSE", "The hostname of $hostname_valid_ip", - "66-118-156-50.static.sagonet.net.", + "orwell.monitoring-plugins.org.", ); my $hostname_invalid = getTestParameter( @@ -87,3 +99,9 @@ $res = NPTest->testCmd("./check_dns -H $hostname_valid_ip -a $hostname_valid_rev cmp_ok( $res->return_code, '==', 0, "Got expected fqdn"); like ( $res->output, $successOutput, "Output OK"); +$res = NPTest->testCmd("./check_dns -H $hostname_valid -a $hostname_valid_cidr -t 5"); +cmp_ok( $res->return_code, '==', 0, "Got expected address"); + +$res = NPTest->testCmd("./check_dns -H $hostname_valid -a $hostname_invalid_cidr -t 5"); +cmp_ok( $res->return_code, '==', 2, "Got wrong address"); +like ( $res->output, "/^DNS CRITICAL.*expected '$hostname_invalid_cidr' but got '$hostname_valid_ip'".'$/', "Output OK"); |