summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2023-10-15 20:07:33 (GMT)
committerLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2023-10-15 20:07:33 (GMT)
commit685c2931dfc3cb67b7605eba143598512a66c037 (patch)
tree4d73bf71eb19e7c63f3d649fa969c63104a4b456
parent0875351a8385d6587133c2af541d102f31c17a46 (diff)
parentbf70f5f847e3407af572d1768cca747af270b993 (diff)
downloadmonitoring-plugins-685c2931dfc3cb67b7605eba143598512a66c037.tar.gz
Merge branch 'master' into dev/check_ssh-patches
-rw-r--r--.github/workflows/test.yml6
-rw-r--r--.gitignore2
-rw-r--r--configure.ac17
-rw-r--r--lib/Makefile.am2
-rw-r--r--lib/maxfd.c26
-rw-r--r--lib/maxfd.h9
-rw-r--r--lib/utils_base.c33
-rw-r--r--lib/utils_base.h4
-rw-r--r--lib/utils_cmd.c29
-rw-r--r--lib/utils_cmd.h13
-rw-r--r--lib/utils_disk.c61
-rw-r--r--lib/utils_disk.h8
-rw-r--r--m4/np_mysqlclient.m42
-rw-r--r--plugins-root/check_dhcp.c671
-rw-r--r--plugins-root/check_icmp.c684
-rw-r--r--plugins-root/t/check_icmp.t58
-rw-r--r--plugins-scripts/check_disk_smb.pl3
-rwxr-xr-xplugins-scripts/check_ircd.pl4
-rw-r--r--plugins/check_disk.c48
-rw-r--r--plugins/check_mysql.c35
-rw-r--r--plugins/check_ntp.c2
-rw-r--r--plugins/check_snmp.c10
-rw-r--r--plugins/common.h14
-rw-r--r--plugins/netutils.h2
-rw-r--r--plugins/popen.c16
-rw-r--r--plugins/popen.h2
-rw-r--r--plugins/runcmd.c12
-rw-r--r--plugins/sslutils.c77
-rw-r--r--plugins/t/check_imap.t2
-rw-r--r--plugins/t/check_users.t2
-rwxr-xr-xplugins/tests/check_curl.t2
-rw-r--r--plugins/utils.c16
-rw-r--r--plugins/utils.h2
-rw-r--r--po/de.po60
-rw-r--r--po/fr.po69
-rw-r--r--po/monitoring-plugins.pot60
36 files changed, 1412 insertions, 651 deletions
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 77b09f4..ea0b38b 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -21,7 +21,7 @@ jobs:
21 uses: codespell-project/actions-codespell@v2 21 uses: codespell-project/actions-codespell@v2
22 with: 22 with:
23 skip: "./.git,./.gitignore,./ABOUT-NLS,*.po,./gl,./po,./tools/squid.conf,./build-aux/ltmain.sh" 23 skip: "./.git,./.gitignore,./ABOUT-NLS,*.po,./gl,./po,./tools/squid.conf,./build-aux/ltmain.sh"
24 ignore_words_list: allright,gord,didi,hda,nd,alis,clen,scrit,ser,fot,te,parm,isnt,consol,oneliners 24 ignore_words_list: allright,gord,didi,hda,nd,alis,clen,scrit,ser,fot,te,parm,isnt,consol,oneliners,esponse,slac
25 check_filenames: true 25 check_filenames: true
26 check_hidden: true 26 check_hidden: true
27# super-linter: 27# super-linter:
@@ -49,10 +49,10 @@ jobs:
49 fail-fast: false 49 fail-fast: false
50 matrix: 50 matrix:
51 distro: 51 distro:
52 - 'debian:testing' 52 - 'debian:stable'
53 #... 53 #...
54 include: 54 include:
55 - distro: 'debian:testing' 55 - distro: 'debian:stable'
56 prepare: .github/prepare_debian.sh 56 prepare: .github/prepare_debian.sh
57 #... 57 #...
58 steps: 58 steps:
diff --git a/.gitignore b/.gitignore
index 02ca61e..6f903d6 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/configure.ac b/configure.ac
index a294b00..b5374b2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -621,7 +621,6 @@ AC_C_CONST
621AC_STRUCT_TM 621AC_STRUCT_TM
622AC_TYPE_PID_T 622AC_TYPE_PID_T
623AC_TYPE_SIZE_T 623AC_TYPE_SIZE_T
624AC_TYPE_SIGNAL
625 624
626AC_CACHE_CHECK([for va_copy],ac_cv_HAVE_VA_COPY,[ 625AC_CACHE_CHECK([for va_copy],ac_cv_HAVE_VA_COPY,[
627AC_TRY_LINK([#include <stdarg.h> 626AC_TRY_LINK([#include <stdarg.h>
@@ -645,12 +644,16 @@ AC_TRY_COMPILE([#include <sys/time.h>],
645 [struct timeval *tv; 644 [struct timeval *tv;
646 struct timezone *tz;], 645 struct timezone *tz;],
647 AC_DEFINE(HAVE_STRUCT_TIMEVAL,1,[Define if we have a timeval structure]) 646 AC_DEFINE(HAVE_STRUCT_TIMEVAL,1,[Define if we have a timeval structure])
648 AC_TRY_COMPILE([#include <sys/time.h>], 647 FOUND_STRUCT_TIMEVAL="yes")
649 [struct timeval *tv; 648
650 struct timezone *tz; 649if test x"$FOUND_STRUCT_TIMEVAL" = x"yes"; then
651 gettimeofday(tv, tz);], 650 AC_TRY_COMPILE([#include <sys/time.h>],
652 AC_DEFINE(HAVE_GETTIMEOFDAY,1,[Define if gettimeofday is found]), 651 [struct timeval *tv;
653 AC_DEFINE(NEED_GETTIMEOFDAY,1,[Define if gettimeofday is needed]))) 652 struct timezone *tz;
653 gettimeofday(tv, tz);],
654 AC_DEFINE(HAVE_GETTIMEOFDAY,1,[Define if gettimeofday is found]),
655 AC_DEFINE(NEED_GETTIMEOFDAY,1,[Define if gettimeofday is needed]))
656fi
654 657
655dnl Checks for library functions. 658dnl Checks for library functions.
656AC_CHECK_FUNCS(memmove select socket strdup strstr strtol strtoul floor) 659AC_CHECK_FUNCS(memmove select socket strdup strstr strtol strtoul floor)
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 01d73a6..1a47395 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -7,7 +7,7 @@ noinst_LIBRARIES = libmonitoringplug.a
7AM_CPPFLAGS = -DNP_STATE_DIR_PREFIX=\"$(localstatedir)\" \ 7AM_CPPFLAGS = -DNP_STATE_DIR_PREFIX=\"$(localstatedir)\" \
8 -I$(srcdir) -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/plugins 8 -I$(srcdir) -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/plugins
9 9
10libmonitoringplug_a_SOURCES = utils_base.c utils_disk.c utils_tcp.c utils_cmd.c 10libmonitoringplug_a_SOURCES = utils_base.c utils_disk.c utils_tcp.c utils_cmd.c maxfd.c
11EXTRA_DIST = utils_base.h utils_disk.h utils_tcp.h utils_cmd.h parse_ini.h extra_opts.h 11EXTRA_DIST = utils_base.h utils_disk.h utils_tcp.h utils_cmd.h parse_ini.h extra_opts.h
12 12
13if USE_PARSE_INI 13if USE_PARSE_INI
diff --git a/lib/maxfd.c b/lib/maxfd.c
new file mode 100644
index 0000000..529b356
--- /dev/null
+++ b/lib/maxfd.c
@@ -0,0 +1,26 @@
1#include "./maxfd.h"
2#include <errno.h>
3
4long mp_open_max (void) {
5 long maxfd = 0L;
6 /* Try sysconf(_SC_OPEN_MAX) first, as it can be higher than OPEN_MAX.
7 * If that fails and the macro isn't defined, we fall back to an educated
8 * guess. There's no guarantee that our guess is adequate and the program
9 * will die with SIGSEGV if it isn't and the upper boundary is breached. */
10
11#ifdef _SC_OPEN_MAX
12 errno = 0;
13 if ((maxfd = sysconf (_SC_OPEN_MAX)) < 0) {
14 if (errno == 0)
15 maxfd = DEFAULT_MAXFD; /* it's indeterminate */
16 else
17 die (STATE_UNKNOWN, _("sysconf error for _SC_OPEN_MAX\n"));
18 }
19#elif defined(OPEN_MAX)
20 return OPEN_MAX
21#else /* sysconf macro unavailable, so guess (may be wildly inaccurate) */
22 return DEFAULT_MAXFD;
23#endif
24
25 return(maxfd);
26}
diff --git a/lib/maxfd.h b/lib/maxfd.h
new file mode 100644
index 0000000..45218d0
--- /dev/null
+++ b/lib/maxfd.h
@@ -0,0 +1,9 @@
1#ifndef _MAXFD_
2#define _MAXFD_
3
4#define DEFAULT_MAXFD 256 /* fallback value if no max open files value is set */
5#define MAXFD_LIMIT 8192 /* upper limit of open files */
6
7long mp_open_max (void);
8
9#endif // _MAXFD_
diff --git a/lib/utils_base.c b/lib/utils_base.c
index c458cf6..0f52126 100644
--- a/lib/utils_base.c
+++ b/lib/utils_base.c
@@ -402,26 +402,45 @@ int mp_translate_state (char *state_text) {
402 * parse of argv, so that uniqueness in parameters are reflected there. 402 * parse of argv, so that uniqueness in parameters are reflected there.
403 */ 403 */
404char *_np_state_generate_key() { 404char *_np_state_generate_key() {
405 struct sha256_ctx ctx;
406 int i; 405 int i;
407 char **argv = this_monitoring_plugin->argv; 406 char **argv = this_monitoring_plugin->argv;
408 unsigned char result[20];
409 char keyname[41]; 407 char keyname[41];
410 char *p=NULL; 408 char *p=NULL;
411 409
412 sha256_init_ctx(&ctx); 410 unsigned char result[256];
413 411
412#ifdef USE_OPENSSL
413 /*
414 * This code path is chosen if openssl is available (which should be the most common
415 * scenario). Alternatively, the gnulib implementation/
416 *
417 */
418 EVP_MD_CTX *ctx = EVP_MD_CTX_new();
419
420 EVP_DigestInit(ctx, EVP_sha256());
421
422 for(i=0; i<this_monitoring_plugin->argc; i++) {
423 EVP_DigestUpdate(ctx, argv[i], strlen(argv[i]));
424 }
425
426 EVP_DigestFinal(ctx, result, NULL);
427#else
428
429 struct sha256_ctx ctx;
430
414 for(i=0; i<this_monitoring_plugin->argc; i++) { 431 for(i=0; i<this_monitoring_plugin->argc; i++) {
415 sha256_process_bytes(argv[i], strlen(argv[i]), &ctx); 432 sha256_process_bytes(argv[i], strlen(argv[i]), &ctx);
416 } 433 }
417 434
418 sha256_finish_ctx(&ctx, &result); 435 sha256_finish_ctx(&ctx, result);
419 436#endif // FOUNDOPENSSL
437
420 for (i=0; i<20; ++i) { 438 for (i=0; i<20; ++i) {
421 sprintf(&keyname[2*i], "%02x", result[i]); 439 sprintf(&keyname[2*i], "%02x", result[i]);
422 } 440 }
441
423 keyname[40]='\0'; 442 keyname[40]='\0';
424 443
425 p = strdup(keyname); 444 p = strdup(keyname);
426 if(p==NULL) { 445 if(p==NULL) {
427 die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); 446 die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
diff --git a/lib/utils_base.h b/lib/utils_base.h
index 5906550..9cb4276 100644
--- a/lib/utils_base.h
+++ b/lib/utils_base.h
@@ -2,7 +2,9 @@
2#define _UTILS_BASE_ 2#define _UTILS_BASE_
3/* Header file for Monitoring Plugins utils_base.c */ 3/* Header file for Monitoring Plugins utils_base.c */
4 4
5#include "sha256.h" 5#ifndef USE_OPENSSL
6# include "sha256.h"
7#endif
6 8
7/* This file holds header information for thresholds - use this in preference to 9/* This file holds header information for thresholds - use this in preference to
8 individual plugin logic */ 10 individual plugin logic */
diff --git a/lib/utils_cmd.c b/lib/utils_cmd.c
index 8b8e570..f66fd57 100644
--- a/lib/utils_cmd.c
+++ b/lib/utils_cmd.c
@@ -42,7 +42,20 @@
42#include "common.h" 42#include "common.h"
43#include "utils.h" 43#include "utils.h"
44#include "utils_cmd.h" 44#include "utils_cmd.h"
45/* This variable must be global, since there's no way the caller
46 * can forcibly slay a dead or ungainly running program otherwise.
47 * Multithreading apps and plugins can initialize it (via CMD_INIT)
48 * in an async safe manner PRIOR to calling cmd_run() or cmd_run_array()
49 * for the first time.
50 *
51 * The check for initialized values is atomic and can
52 * occur in any number of threads simultaneously. */
53static pid_t *_cmd_pids = NULL;
54
45#include "utils_base.h" 55#include "utils_base.h"
56
57#include "./maxfd.h"
58
46#include <fcntl.h> 59#include <fcntl.h>
47 60
48#ifdef HAVE_SYS_WAIT_H 61#ifdef HAVE_SYS_WAIT_H
@@ -86,13 +99,7 @@ extern void die (int, const char *, ...)
86void 99void
87cmd_init (void) 100cmd_init (void)
88{ 101{
89#ifndef maxfd 102 long maxfd = mp_open_max();
90 if (!maxfd && (maxfd = sysconf (_SC_OPEN_MAX)) < 0) {
91 /* possibly log or emit a warning here, since there's no
92 * guarantee that our guess at maxfd will be adequate */
93 maxfd = DEFAULT_MAXFD;
94 }
95#endif
96 103
97 /* if maxfd is unnaturally high, we force it to a lower value 104 /* if maxfd is unnaturally high, we force it to a lower value
98 * ( e.g. on SunOS, when ulimit is set to unlimited: 2147483647 this would cause 105 * ( e.g. on SunOS, when ulimit is set to unlimited: 2147483647 this would cause
@@ -118,10 +125,6 @@ _cmd_open (char *const *argv, int *pfd, int *pfderr)
118 125
119 int i = 0; 126 int i = 0;
120 127
121 /* if no command was passed, return with no error */
122 if (argv == NULL)
123 return -1;
124
125 if (!_cmd_pids) 128 if (!_cmd_pids)
126 CMD_INIT; 129 CMD_INIT;
127 130
@@ -152,6 +155,7 @@ _cmd_open (char *const *argv, int *pfd, int *pfderr)
152 /* close all descriptors in _cmd_pids[] 155 /* close all descriptors in _cmd_pids[]
153 * This is executed in a separate address space (pure child), 156 * This is executed in a separate address space (pure child),
154 * so we don't have to worry about async safety */ 157 * so we don't have to worry about async safety */
158 long maxfd = mp_open_max();
155 for (i = 0; i < maxfd; i++) 159 for (i = 0; i < maxfd; i++)
156 if (_cmd_pids[i] > 0) 160 if (_cmd_pids[i] > 0)
157 close (i); 161 close (i);
@@ -178,6 +182,7 @@ _cmd_close (int fd)
178 pid_t pid; 182 pid_t pid;
179 183
180 /* make sure the provided fd was opened */ 184 /* make sure the provided fd was opened */
185 long maxfd = mp_open_max();
181 if (fd < 0 || fd > maxfd || !_cmd_pids || (pid = _cmd_pids[fd]) == 0) 186 if (fd < 0 || fd > maxfd || !_cmd_pids || (pid = _cmd_pids[fd]) == 0)
182 return -1; 187 return -1;
183 188
@@ -269,7 +274,6 @@ _cmd_fetch_output (int fd, output * op, int flags)
269int 274int
270cmd_run (const char *cmdstring, output * out, output * err, int flags) 275cmd_run (const char *cmdstring, output * out, output * err, int flags)
271{ 276{
272 int fd, pfd_out[2], pfd_err[2];
273 int i = 0, argc; 277 int i = 0, argc;
274 size_t cmdlen; 278 size_t cmdlen;
275 char **argv = NULL; 279 char **argv = NULL;
@@ -391,6 +395,7 @@ timeout_alarm_handler (int signo)
391 printf (_("%s - Plugin timed out after %d seconds\n"), 395 printf (_("%s - Plugin timed out after %d seconds\n"),
392 state_text(timeout_state), timeout_interval); 396 state_text(timeout_state), timeout_interval);
393 397
398 long maxfd = mp_open_max();
394 if(_cmd_pids) for(i = 0; i < maxfd; i++) { 399 if(_cmd_pids) for(i = 0; i < maxfd; i++) {
395 if(_cmd_pids[i] != 0) kill(_cmd_pids[i], SIGKILL); 400 if(_cmd_pids[i] != 0) kill(_cmd_pids[i], SIGKILL);
396 } 401 }
diff --git a/lib/utils_cmd.h b/lib/utils_cmd.h
index 6f3aeb8..f1b06c8 100644
--- a/lib/utils_cmd.h
+++ b/lib/utils_cmd.h
@@ -32,17 +32,8 @@ void cmd_init (void);
32#define CMD_NO_ARRAYS 0x01 /* don't populate arrays at all */ 32#define CMD_NO_ARRAYS 0x01 /* don't populate arrays at all */
33#define CMD_NO_ASSOC 0x02 /* output.line won't point to buf */ 33#define CMD_NO_ASSOC 0x02 /* output.line won't point to buf */
34 34
35/* This variable must be global, since there's no way the caller 35
36 * can forcibly slay a dead or ungainly running program otherwise. 36void timeout_alarm_handler (int);
37 * Multithreading apps and plugins can initialize it (via CMD_INIT)
38 * in an async safe manner PRIOR to calling cmd_run() or cmd_run_array()
39 * for the first time.
40 *
41 * The check for initialized values is atomic and can
42 * occur in any number of threads simultaneously. */
43static pid_t *_cmd_pids = NULL;
44
45RETSIGTYPE timeout_alarm_handler (int);
46 37
47 38
48#endif /* _UTILS_CMD_ */ 39#endif /* _UTILS_CMD_ */
diff --git a/lib/utils_disk.c b/lib/utils_disk.c
index 582d3ea..f5ac0b3 100644
--- a/lib/utils_disk.c
+++ b/lib/utils_disk.c
@@ -29,6 +29,7 @@
29#include "common.h" 29#include "common.h"
30#include "utils_disk.h" 30#include "utils_disk.h"
31#include "gl/fsusage.h" 31#include "gl/fsusage.h"
32#include <string.h>
32 33
33void 34void
34np_add_name (struct name_list **list, const char *name) 35np_add_name (struct name_list **list, const char *name)
@@ -40,6 +41,42 @@ np_add_name (struct name_list **list, const char *name)
40 *list = new_entry; 41 *list = new_entry;
41} 42}
42 43
44/* @brief Initialises a new regex at the begin of list via regcomp(3)
45 *
46 * @details if the regex fails to compile the error code of regcomp(3) is returned
47 * and list is not modified, otherwise list is modified to point to the new
48 * element
49 * @param list Pointer to a linked list of regex_list elements
50 * @param regex the string containing the regex which should be inserted into the list
51 * @param clags the cflags parameter for regcomp(3)
52 */
53int
54np_add_regex (struct regex_list **list, const char *regex, int cflags)
55{
56 struct regex_list *new_entry = (struct regex_list *) malloc (sizeof *new_entry);
57
58 if (new_entry == NULL) {
59 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
60 strerror(errno));
61 }
62
63 int regcomp_result = regcomp(&new_entry->regex, regex, cflags);
64
65 if (!regcomp_result) {
66 // regcomp succeeded
67 new_entry->next = *list;
68 *list = new_entry;
69
70 return 0;
71 } else {
72 // regcomp failed
73 free(new_entry);
74
75 return regcomp_result;
76 }
77
78}
79
43/* Initialises a new parameter at the end of list */ 80/* Initialises a new parameter at the end of list */
44struct parameter_list * 81struct parameter_list *
45np_add_parameter(struct parameter_list **list, const char *name) 82np_add_parameter(struct parameter_list **list, const char *name)
@@ -196,6 +233,30 @@ np_find_name (struct name_list *list, const char *name)
196 return FALSE; 233 return FALSE;
197} 234}
198 235
236/* Returns TRUE if name is in list */
237bool
238np_find_regmatch (struct regex_list *list, const char *name)
239{
240 int len;
241 regmatch_t m;
242
243 if (name == NULL) {
244 return false;
245 }
246
247 len = strlen(name);
248
249 for (; list; list = list->next) {
250 /* Emulate a full match as if surrounded with ^( )$
251 by checking whether the match spans the whole name */
252 if (!regexec(&list->regex, name, 1, &m, 0) && m.rm_so == 0 && m.rm_eo == len) {
253 return true;
254 }
255 }
256
257 return false;
258}
259
199int 260int
200np_seen_name(struct name_list *list, const char *name) 261np_seen_name(struct name_list *list, const char *name)
201{ 262{
diff --git a/lib/utils_disk.h b/lib/utils_disk.h
index 3b5a45f..6b83ac7 100644
--- a/lib/utils_disk.h
+++ b/lib/utils_disk.h
@@ -10,6 +10,12 @@ struct name_list
10 struct name_list *next; 10 struct name_list *next;
11}; 11};
12 12
13struct regex_list
14{
15 regex_t regex;
16 struct regex_list *next;
17};
18
13struct parameter_list 19struct parameter_list
14{ 20{
15 char *name; 21 char *name;
@@ -35,6 +41,8 @@ struct parameter_list
35void np_add_name (struct name_list **list, const char *name); 41void np_add_name (struct name_list **list, const char *name);
36int np_find_name (struct name_list *list, const char *name); 42int np_find_name (struct name_list *list, const char *name);
37int np_seen_name (struct name_list *list, const char *name); 43int np_seen_name (struct name_list *list, const char *name);
44int np_add_regex (struct regex_list **list, const char *regex, int cflags);
45bool np_find_regmatch (struct regex_list *list, const char *name);
38struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name); 46struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name);
39struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name); 47struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name);
40struct parameter_list *np_del_parameter(struct parameter_list *item, struct parameter_list *prev); 48struct parameter_list *np_del_parameter(struct parameter_list *item, struct parameter_list *prev);
diff --git a/m4/np_mysqlclient.m4 b/m4/np_mysqlclient.m4
index 9f533ea..9fe38ac 100644
--- a/m4/np_mysqlclient.m4
+++ b/m4/np_mysqlclient.m4
@@ -13,7 +13,7 @@ dnl np_mysql_libs = flags for libs, from mysql_config --libs
13dnl np_mysql_cflags = flags for cflags, from mysql_config --cflags 13dnl np_mysql_cflags = flags for cflags, from mysql_config --cflags
14dnl Also sets in config.h: 14dnl Also sets in config.h:
15dnl HAVE_MYSQLCLIENT 15dnl HAVE_MYSQLCLIENT
16dnl Copile your code with: 16dnl Compile your code with:
17dnl $(CC) $(np_mysql_include) code.c $(np_mysql_libs) 17dnl $(CC) $(np_mysql_include) code.c $(np_mysql_libs)
18 18
19AC_DEFUN([np_mysqlclient], 19AC_DEFUN([np_mysqlclient],
diff --git a/plugins-root/check_dhcp.c b/plugins-root/check_dhcp.c
index 2d22619..0ddace5 100644
--- a/plugins-root/check_dhcp.c
+++ b/plugins-root/check_dhcp.c
@@ -1,40 +1,40 @@
1/***************************************************************************** 1/*****************************************************************************
2* 2 *
3* Monitoring check_dhcp plugin 3 * Monitoring check_dhcp plugin
4* 4 *
5* License: GPL 5 * License: GPL
6* Copyright (c) 2001-2004 Ethan Galstad (nagios@nagios.org) 6 * Copyright (c) 2001-2004 Ethan Galstad (nagios@nagios.org)
7* Copyright (c) 2001-2007 Monitoring Plugins Development Team 7 * Copyright (c) 2001-2007 Monitoring Plugins Development Team
8* 8 *
9* Description: 9 * Description:
10* 10 *
11* This file contains the check_dhcp plugin 11 * This file contains the check_dhcp plugin
12* 12 *
13* This plugin tests the availability of DHCP servers on a network. 13 * This plugin tests the availability of DHCP servers on a network.
14* 14 *
15* Unicast mode was originally implemented by Heiti of Boras Kommun with 15 * Unicast mode was originally implemented by Heiti of Boras Kommun with
16* general improvements as well as usability fixes and "forward"-porting by 16 * general improvements as well as usability fixes and "forward"-porting by
17* Andreas Ericsson of OP5 AB. 17 * Andreas Ericsson of OP5 AB.
18* 18 *
19* 19 *
20* This program is free software: you can redistribute it and/or modify 20 * This program is free software: you can redistribute it and/or modify
21* it under the terms of the GNU General Public License as published by 21 * it under the terms of the GNU General Public License as published by
22* the Free Software Foundation, either version 3 of the License, or 22 * the Free Software Foundation, either version 3 of the License, or
23* (at your option) any later version. 23 * (at your option) any later version.
24* 24 *
25* This program is distributed in the hope that it will be useful, 25 * This program is distributed in the hope that it will be useful,
26* but WITHOUT ANY WARRANTY; without even the implied warranty of 26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28* GNU General Public License for more details. 28 * GNU General Public License for more details.
29* 29 *
30* You should have received a copy of the GNU General Public License 30 * You should have received a copy of the GNU General Public License
31* along with this program. If not, see <http://www.gnu.org/licenses/>. 31 * along with this program. If not, see <http://www.gnu.org/licenses/>.
32* 32 *
33* 33 *
34*****************************************************************************/ 34 *****************************************************************************/
35 35
36const char *progname = "check_dhcp"; 36const char *progname = "check_dhcp";
37const char *copyright = "2001-2007"; 37const char *copyright = "2001-2023";
38const char *email = "devel@monitoring-plugins.org"; 38const char *email = "devel@monitoring-plugins.org";
39 39
40#include "common.h" 40#include "common.h"
@@ -57,9 +57,10 @@ const char *email = "devel@monitoring-plugins.org";
57#include <netinet/in.h> 57#include <netinet/in.h>
58#include <net/if.h> 58#include <net/if.h>
59#include <arpa/inet.h> 59#include <arpa/inet.h>
60
60#if HAVE_SYS_SOCKIO_H 61#if HAVE_SYS_SOCKIO_H
61#include <sys/sockio.h> 62#include <sys/sockio.h>
62#endif 63#endif // HAVE_SYS_SOCKIO_H
63 64
64#if defined( __linux__ ) 65#if defined( __linux__ )
65 66
@@ -98,10 +99,6 @@ static struct strbuf dat = {AREA_SZ, 0, (char *)dat_area};
98#define GOT_INTR 4 99#define GOT_INTR 4
99#define GOT_ERR 128 100#define GOT_ERR 128
100 101
101#define u_int8_t uint8_t
102#define u_int16_t uint16_t
103#define u_int32_t uint32_t
104
105static int get_msg(int); 102static int get_msg(int);
106static int check_ctrl(int); 103static int check_ctrl(int);
107static int put_ctrl(int, int, int); 104static int put_ctrl(int, int, int);
@@ -110,7 +107,7 @@ static int dl_open(const char *, int, int *);
110static int dl_bind(int, int, u_char *); 107static int dl_bind(int, int, u_char *);
111long mac_addr_dlpi( const char *, int, u_char *); 108long mac_addr_dlpi( const char *, int, u_char *);
112 109
113#endif 110#endif // __sun__ || __solaris__ || __hpux
114 111
115 112
116 113
@@ -119,9 +116,6 @@ long mac_addr_dlpi( const char *, int, u_char *);
119#define OK 0 116#define OK 0
120#define ERROR -1 117#define ERROR -1
121 118
122#define FALSE 0
123#define TRUE 1
124
125 119
126/**** DHCP definitions ****/ 120/**** DHCP definitions ****/
127 121
@@ -132,39 +126,39 @@ long mac_addr_dlpi( const char *, int, u_char *);
132 126
133 127
134typedef struct dhcp_packet_struct{ 128typedef struct dhcp_packet_struct{
135 u_int8_t op; /* packet type */ 129 uint8_t op; /* packet type */
136 u_int8_t htype; /* type of hardware address for this machine (Ethernet, etc) */ 130 uint8_t htype; /* type of hardware address for this machine (Ethernet, etc) */
137 u_int8_t hlen; /* length of hardware address (of this machine) */ 131 uint8_t hlen; /* length of hardware address (of this machine) */
138 u_int8_t hops; /* hops */ 132 uint8_t hops; /* hops */
139 u_int32_t xid; /* random transaction id number - chosen by this machine */ 133 uint32_t xid; /* random transaction id number - chosen by this machine */
140 u_int16_t secs; /* seconds used in timing */ 134 uint16_t secs; /* seconds used in timing */
141 u_int16_t flags; /* flags */ 135 uint16_t flags; /* flags */
142 struct in_addr ciaddr; /* IP address of this machine (if we already have one) */ 136 struct in_addr ciaddr; /* IP address of this machine (if we already have one) */
143 struct in_addr yiaddr; /* IP address of this machine (offered by the DHCP server) */ 137 struct in_addr yiaddr; /* IP address of this machine (offered by the DHCP server) */
144 struct in_addr siaddr; /* IP address of next server */ 138 struct in_addr siaddr; /* IP address of next server */
145 struct in_addr giaddr; /* IP address of DHCP relay */ 139 struct in_addr giaddr; /* IP address of DHCP relay */
146 unsigned char chaddr [MAX_DHCP_CHADDR_LENGTH]; /* hardware address of this machine */ 140 unsigned char chaddr [MAX_DHCP_CHADDR_LENGTH]; /* hardware address of this machine */
147 char sname [MAX_DHCP_SNAME_LENGTH]; /* name of DHCP server */ 141 char sname [MAX_DHCP_SNAME_LENGTH]; /* name of DHCP server */
148 char file [MAX_DHCP_FILE_LENGTH]; /* boot file name (used for diskless booting?) */ 142 char file [MAX_DHCP_FILE_LENGTH]; /* boot file name (used for diskless booting?) */
149 char options[MAX_DHCP_OPTIONS_LENGTH]; /* options */ 143 char options[MAX_DHCP_OPTIONS_LENGTH]; /* options */
150 }dhcp_packet; 144}dhcp_packet;
151 145
152 146
153typedef struct dhcp_offer_struct{ 147typedef struct dhcp_offer_struct{
154 struct in_addr server_address; /* address of DHCP server that sent this offer */ 148 struct in_addr server_address; /* address of DHCP server that sent this offer */
155 struct in_addr offered_address; /* the IP address that was offered to us */ 149 struct in_addr offered_address; /* the IP address that was offered to us */
156 u_int32_t lease_time; /* lease time in seconds */ 150 uint32_t lease_time; /* lease time in seconds */
157 u_int32_t renewal_time; /* renewal time in seconds */ 151 uint32_t renewal_time; /* renewal time in seconds */
158 u_int32_t rebinding_time; /* rebinding time in seconds */ 152 uint32_t rebinding_time; /* rebinding time in seconds */
159 struct dhcp_offer_struct *next; 153 struct dhcp_offer_struct *next;
160 }dhcp_offer; 154}dhcp_offer;
161 155
162 156
163typedef struct requested_server_struct{ 157typedef struct requested_server_struct{
164 struct in_addr server_address; 158 struct in_addr server_address;
165 int answered; 159 bool answered;
166 struct requested_server_struct *next; 160 struct requested_server_struct *next;
167 }requested_server; 161}requested_server;
168 162
169 163
170#define BOOTREQUEST 1 164#define BOOTREQUEST 1
@@ -198,7 +192,7 @@ typedef struct requested_server_struct{
198#define ETHERNET_HARDWARE_ADDRESS 1 /* used in htype field of dhcp packet */ 192#define ETHERNET_HARDWARE_ADDRESS 1 /* used in htype field of dhcp packet */
199#define ETHERNET_HARDWARE_ADDRESS_LENGTH 6 /* length of Ethernet hardware addresses */ 193#define ETHERNET_HARDWARE_ADDRESS_LENGTH 6 /* length of Ethernet hardware addresses */
200 194
201u_int8_t unicast = 0; /* unicast mode: mimic a DHCP relay */ 195uint8_t unicast = 0; /* unicast mode: mimic a DHCP relay */
202struct in_addr my_ip; /* our address (required for relay) */ 196struct in_addr my_ip; /* our address (required for relay) */
203struct in_addr dhcp_ip; /* server to query (if in unicast mode) */ 197struct in_addr dhcp_ip; /* server to query (if in unicast mode) */
204unsigned char client_hardware_address[MAX_DHCP_CHADDR_LENGTH]=""; 198unsigned char client_hardware_address[MAX_DHCP_CHADDR_LENGTH]="";
@@ -206,11 +200,11 @@ unsigned char *user_specified_mac=NULL;
206 200
207char network_interface_name[IFNAMSIZ]="eth0"; 201char network_interface_name[IFNAMSIZ]="eth0";
208 202
209u_int32_t packet_xid=0; 203uint32_t packet_xid=0;
210 204
211u_int32_t dhcp_lease_time=0; 205uint32_t dhcp_lease_time=0;
212u_int32_t dhcp_renewal_time=0; 206uint32_t dhcp_renewal_time=0;
213u_int32_t dhcp_rebinding_time=0; 207uint32_t dhcp_rebinding_time=0;
214 208
215int dhcpoffer_timeout=2; 209int dhcpoffer_timeout=2;
216 210
@@ -221,8 +215,8 @@ int valid_responses=0; /* number of valid DHCPOFFERs we received */
221int requested_servers=0; 215int requested_servers=0;
222int requested_responses=0; 216int requested_responses=0;
223 217
224int request_specific_address=FALSE; 218bool request_specific_address=false;
225int received_requested_address=FALSE; 219bool received_requested_address=false;
226int verbose=0; 220int verbose=0;
227struct in_addr requested_address; 221struct in_addr requested_address;
228 222
@@ -268,7 +262,7 @@ int main(int argc, char **argv){
268 262
269 if(process_arguments(argc,argv)!=OK){ 263 if(process_arguments(argc,argv)!=OK){
270 usage4 (_("Could not parse arguments")); 264 usage4 (_("Could not parse arguments"));
271 } 265 }
272 266
273 /* create socket for DHCP communications */ 267 /* create socket for DHCP communications */
274 dhcp_socket=create_dhcp_socket(); 268 dhcp_socket=create_dhcp_socket();
@@ -299,7 +293,7 @@ int main(int argc, char **argv){
299 free_requested_server_list(); 293 free_requested_server_list();
300 294
301 return result; 295 return result;
302 } 296}
303 297
304 298
305 299
@@ -314,83 +308,83 @@ int get_hardware_address(int sock,char *interface_name){
314 308
315 /* try and grab hardware address of requested interface */ 309 /* try and grab hardware address of requested interface */
316 if(ioctl(sock,SIOCGIFHWADDR,&ifr)<0){ 310 if(ioctl(sock,SIOCGIFHWADDR,&ifr)<0){
317 printf(_("Error: Could not get hardware address of interface '%s'\n"),interface_name); 311 printf(_("Error: Could not get hardware address of interface '%s'\n"),interface_name);
318 exit(STATE_UNKNOWN); 312 exit(STATE_UNKNOWN);
319 } 313 }
320 314
321 memcpy(&client_hardware_address[0],&ifr.ifr_hwaddr.sa_data,6); 315 memcpy(&client_hardware_address[0],&ifr.ifr_hwaddr.sa_data,6);
322 316
323#elif defined(__bsd__) 317#elif defined(__bsd__)
324 /* King 2004 see ACKNOWLEDGEMENTS */ 318 /* King 2004 see ACKNOWLEDGEMENTS */
325 319
326 size_t len; 320 size_t len;
327 int mib[6]; 321 int mib[6];
328 char *buf; 322 char *buf;
329 unsigned char *ptr; 323 unsigned char *ptr;
330 struct if_msghdr *ifm; 324 struct if_msghdr *ifm;
331 struct sockaddr_dl *sdl; 325 struct sockaddr_dl *sdl;
332 326
333 mib[0] = CTL_NET; 327 mib[0] = CTL_NET;
334 mib[1] = AF_ROUTE; 328 mib[1] = AF_ROUTE;
335 mib[2] = 0; 329 mib[2] = 0;
336 mib[3] = AF_LINK; 330 mib[3] = AF_LINK;
337 mib[4] = NET_RT_IFLIST; 331 mib[4] = NET_RT_IFLIST;
338 332
339 if((mib[5] = if_nametoindex(interface_name)) == 0){ 333 if((mib[5] = if_nametoindex(interface_name)) == 0){
340 printf(_("Error: if_nametoindex error - %s.\n"), strerror(errno)); 334 printf(_("Error: if_nametoindex error - %s.\n"), strerror(errno));
341 exit(STATE_UNKNOWN); 335 exit(STATE_UNKNOWN);
342 } 336 }
343 337
344 if(sysctl(mib, 6, NULL, &len, NULL, 0) < 0){ 338 if(sysctl(mib, 6, NULL, &len, NULL, 0) < 0){
345 printf(_("Error: Couldn't get hardware address from %s. sysctl 1 error - %s.\n"), interface_name, strerror(errno)); 339 printf(_("Error: Couldn't get hardware address from %s. sysctl 1 error - %s.\n"), interface_name, strerror(errno));
346 exit(STATE_UNKNOWN); 340 exit(STATE_UNKNOWN);
347 } 341 }
348 342
349 if((buf = malloc(len)) == NULL){ 343 if((buf = malloc(len)) == NULL){
350 printf(_("Error: Couldn't get hardware address from interface %s. malloc error - %s.\n"), interface_name, strerror(errno)); 344 printf(_("Error: Couldn't get hardware address from interface %s. malloc error - %s.\n"), interface_name, strerror(errno));
351 exit(4); 345 exit(4);
352 } 346 }
353 347
354 if(sysctl(mib, 6, buf, &len, NULL, 0) < 0){ 348 if(sysctl(mib, 6, buf, &len, NULL, 0) < 0){
355 printf(_("Error: Couldn't get hardware address from %s. sysctl 2 error - %s.\n"), interface_name, strerror(errno)); 349 printf(_("Error: Couldn't get hardware address from %s. sysctl 2 error - %s.\n"), interface_name, strerror(errno));
356 exit(STATE_UNKNOWN); 350 exit(STATE_UNKNOWN);
357 } 351 }
358 352
359 ifm = (struct if_msghdr *)buf; 353 ifm = (struct if_msghdr *)buf;
360 sdl = (struct sockaddr_dl *)(ifm + 1); 354 sdl = (struct sockaddr_dl *)(ifm + 1);
361 ptr = (unsigned char *)LLADDR(sdl); 355 ptr = (unsigned char *)LLADDR(sdl);
362 memcpy(&client_hardware_address[0], ptr, 6) ; 356 memcpy(&client_hardware_address[0], ptr, 6) ;
363 /* King 2004 */ 357 /* King 2004 */
364 358
365#elif defined(__sun__) || defined(__solaris__) 359#elif defined(__sun__) || defined(__solaris__)
366 360
367 /* Kompf 2000-2003 see ACKNOWLEDGEMENTS */ 361 /* Kompf 2000-2003 see ACKNOWLEDGEMENTS */
368 long stat; 362 long stat;
369 char dev[20] = "/dev/"; 363 char dev[20] = "/dev/";
370 char *p; 364 char *p;
371 int unit; 365 int unit;
372 366
373 /* get last number from interfacename, eg lnc0, e1000g0*/ 367 /* get last number from interfacename, eg lnc0, e1000g0*/
374 int i; 368 int i;
375 p = interface_name + strlen(interface_name) -1; 369 p = interface_name + strlen(interface_name) -1;
376 for(i = strlen(interface_name) -1; i > 0; p--) { 370 for(i = strlen(interface_name) -1; i > 0; p--) {
377 if(isalpha(*p)) 371 if(isalpha(*p))
378 break; 372 break;
379 } 373 }
380 p++; 374 p++;
381 if( p != interface_name ){ 375 if( p != interface_name ){
382 unit = atoi(p) ; 376 unit = atoi(p) ;
383 strncat(dev, interface_name, 6) ; 377 strncat(dev, interface_name, 6) ;
384 } 378 }
385 else{ 379 else{
386 printf(_("Error: can't find unit number in interface_name (%s) - expecting TypeNumber eg lnc0.\n"), interface_name); 380 printf(_("Error: can't find unit number in interface_name (%s) - expecting TypeNumber eg lnc0.\n"), interface_name);
387 exit(STATE_UNKNOWN); 381 exit(STATE_UNKNOWN);
388 } 382 }
389 stat = mac_addr_dlpi(dev, unit, client_hardware_address); 383 stat = mac_addr_dlpi(dev, unit, client_hardware_address);
390 if(stat != 0){ 384 if(stat != 0){
391 printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), dev, unit); 385 printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), dev, unit);
392 exit(STATE_UNKNOWN); 386 exit(STATE_UNKNOWN);
393 } 387 }
394 388
395#elif defined(__hpux__) 389#elif defined(__hpux__)
396 390
@@ -402,8 +396,8 @@ int get_hardware_address(int sock,char *interface_name){
402 if(stat != 0){ 396 if(stat != 0){
403 printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), dev, unit); 397 printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), dev, unit);
404 exit(STATE_UNKNOWN); 398 exit(STATE_UNKNOWN);
405 } 399 }
406 /* Kompf 2000-2003 */ 400 /* Kompf 2000-2003 */
407 401
408#else 402#else
409 printf(_("Error: can't get MAC address for this architecture. Use the --mac option.\n")); 403 printf(_("Error: can't get MAC address for this architecture. Use the --mac option.\n"));
@@ -414,7 +408,7 @@ int get_hardware_address(int sock,char *interface_name){
414 print_hardware_address(client_hardware_address); 408 print_hardware_address(client_hardware_address);
415 409
416 return OK; 410 return OK;
417 } 411}
418 412
419/* determines IP address of the client interface */ 413/* determines IP address of the client interface */
420int get_ip_address(int sock,char *interface_name){ 414int get_ip_address(int sock,char *interface_name){
@@ -426,9 +420,9 @@ int get_ip_address(int sock,char *interface_name){
426 420
427 if(ioctl(sock,SIOCGIFADDR,&ifr)<0){ 421 if(ioctl(sock,SIOCGIFADDR,&ifr)<0){
428 printf(_("Error: Cannot determine IP address of interface %s\n"), 422 printf(_("Error: Cannot determine IP address of interface %s\n"),
429 interface_name); 423 interface_name);
430 exit(STATE_UNKNOWN); 424 exit(STATE_UNKNOWN);
431 } 425 }
432 426
433 my_ip=((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr; 427 my_ip=((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
434 428
@@ -441,13 +435,13 @@ int get_ip_address(int sock,char *interface_name){
441 printf(_("Pretending to be relay client %s\n"),inet_ntoa(my_ip)); 435 printf(_("Pretending to be relay client %s\n"),inet_ntoa(my_ip));
442 436
443 return OK; 437 return OK;
444 } 438}
445 439
446/* sends a DHCPDISCOVER broadcast message in an attempt to find DHCP servers */ 440/* sends a DHCPDISCOVER broadcast message in an attempt to find DHCP servers */
447int send_dhcp_discover(int sock){ 441int send_dhcp_discover(int sock){
448 dhcp_packet discover_packet; 442 dhcp_packet discover_packet;
449 struct sockaddr_in sockaddr_broadcast; 443 struct sockaddr_in sockaddr_broadcast;
450 unsigned short opts; 444 unsigned short opts;
451 445
452 446
453 /* clear the packet data structure */ 447 /* clear the packet data structure */
@@ -488,19 +482,19 @@ int send_dhcp_discover(int sock){
488 discover_packet.options[2]='\x53'; 482 discover_packet.options[2]='\x53';
489 discover_packet.options[3]='\x63'; 483 discover_packet.options[3]='\x63';
490 484
491 opts = 4; 485 opts = 4;
492 /* DHCP message type is embedded in options field */ 486 /* DHCP message type is embedded in options field */
493 discover_packet.options[opts++]=DHCP_OPTION_MESSAGE_TYPE; /* DHCP message type option identifier */ 487 discover_packet.options[opts++]=DHCP_OPTION_MESSAGE_TYPE; /* DHCP message type option identifier */
494 discover_packet.options[opts++]='\x01'; /* DHCP message option length in bytes */ 488 discover_packet.options[opts++]='\x01'; /* DHCP message option length in bytes */
495 discover_packet.options[opts++]=DHCPDISCOVER; 489 discover_packet.options[opts++]=DHCPDISCOVER;
496 490
497 /* the IP address we're requesting */ 491 /* the IP address we're requesting */
498 if(request_specific_address==TRUE){ 492 if(request_specific_address){
499 discover_packet.options[opts++]=DHCP_OPTION_REQUESTED_ADDRESS; 493 discover_packet.options[opts++]=DHCP_OPTION_REQUESTED_ADDRESS;
500 discover_packet.options[opts++]='\x04'; 494 discover_packet.options[opts++]='\x04';
501 memcpy(&discover_packet.options[opts],&requested_address,sizeof(requested_address)); 495 memcpy(&discover_packet.options[opts],&requested_address,sizeof(requested_address));
502 opts += sizeof(requested_address); 496 opts += sizeof(requested_address);
503 } 497 }
504 discover_packet.options[opts++]=DHCP_OPTION_END; 498 discover_packet.options[opts++]=DHCP_OPTION_END;
505 499
506 /* unicast fields */ 500 /* unicast fields */
@@ -511,8 +505,8 @@ int send_dhcp_discover(int sock){
511 discover_packet.hops = unicast ? 1 : 0; 505 discover_packet.hops = unicast ? 1 : 0;
512 506
513 /* send the DHCPDISCOVER packet to broadcast address */ 507 /* send the DHCPDISCOVER packet to broadcast address */
514 sockaddr_broadcast.sin_family=AF_INET; 508 sockaddr_broadcast.sin_family=AF_INET;
515 sockaddr_broadcast.sin_port=htons(DHCP_SERVER_PORT); 509 sockaddr_broadcast.sin_port=htons(DHCP_SERVER_PORT);
516 sockaddr_broadcast.sin_addr.s_addr = unicast ? dhcp_ip.s_addr : INADDR_BROADCAST; 510 sockaddr_broadcast.sin_addr.s_addr = unicast ? dhcp_ip.s_addr : INADDR_BROADCAST;
517 bzero(&sockaddr_broadcast.sin_zero,sizeof(sockaddr_broadcast.sin_zero)); 511 bzero(&sockaddr_broadcast.sin_zero,sizeof(sockaddr_broadcast.sin_zero));
518 512
@@ -524,7 +518,7 @@ int send_dhcp_discover(int sock){
524 printf("DHCDISCOVER yiaddr: %s\n",inet_ntoa(discover_packet.yiaddr)); 518 printf("DHCDISCOVER yiaddr: %s\n",inet_ntoa(discover_packet.yiaddr));
525 printf("DHCDISCOVER siaddr: %s\n",inet_ntoa(discover_packet.siaddr)); 519 printf("DHCDISCOVER siaddr: %s\n",inet_ntoa(discover_packet.siaddr));
526 printf("DHCDISCOVER giaddr: %s\n",inet_ntoa(discover_packet.giaddr)); 520 printf("DHCDISCOVER giaddr: %s\n",inet_ntoa(discover_packet.giaddr));
527 } 521 }
528 522
529 /* send the DHCPDISCOVER packet out */ 523 /* send the DHCPDISCOVER packet out */
530 send_dhcp_packet(&discover_packet,sizeof(discover_packet),sock,&sockaddr_broadcast); 524 send_dhcp_packet(&discover_packet,sizeof(discover_packet),sock,&sockaddr_broadcast);
@@ -533,7 +527,7 @@ int send_dhcp_discover(int sock){
533 printf("\n\n"); 527 printf("\n\n");
534 528
535 return OK; 529 return OK;
536 } 530}
537 531
538 532
539 533
@@ -573,13 +567,13 @@ int get_dhcp_offer(int sock){
573 printf(_("Result=ERROR\n")); 567 printf(_("Result=ERROR\n"));
574 568
575 continue; 569 continue;
576 } 570 }
577 else{ 571 else{
578 if(verbose) 572 if(verbose)
579 printf(_("Result=OK\n")); 573 printf(_("Result=OK\n"));
580 574
581 responses++; 575 responses++;
582 } 576 }
583 577
584 /* The "source" is either a server or a relay. */ 578 /* The "source" is either a server or a relay. */
585 /* Save a copy of "source" into "via" even if it's via itself */ 579 /* Save a copy of "source" into "via" even if it's via itself */
@@ -589,7 +583,7 @@ int get_dhcp_offer(int sock){
589 printf(_("DHCPOFFER from IP address %s"),inet_ntoa(source.sin_addr)); 583 printf(_("DHCPOFFER from IP address %s"),inet_ntoa(source.sin_addr));
590 printf(_(" via %s\n"),inet_ntoa(via.sin_addr)); 584 printf(_(" via %s\n"),inet_ntoa(via.sin_addr));
591 printf("DHCPOFFER XID: %u (0x%X)\n",ntohl(offer_packet.xid),ntohl(offer_packet.xid)); 585 printf("DHCPOFFER XID: %u (0x%X)\n",ntohl(offer_packet.xid),ntohl(offer_packet.xid));
592 } 586 }
593 587
594 /* check packet xid to see if its the same as the one we used in the discover packet */ 588 /* check packet xid to see if its the same as the one we used in the discover packet */
595 if(ntohl(offer_packet.xid)!=packet_xid){ 589 if(ntohl(offer_packet.xid)!=packet_xid){
@@ -597,7 +591,7 @@ int get_dhcp_offer(int sock){
597 printf(_("DHCPOFFER XID (%u) did not match DHCPDISCOVER XID (%u) - ignoring packet\n"),ntohl(offer_packet.xid),packet_xid); 591 printf(_("DHCPOFFER XID (%u) did not match DHCPDISCOVER XID (%u) - ignoring packet\n"),ntohl(offer_packet.xid),packet_xid);
598 592
599 continue; 593 continue;
600 } 594 }
601 595
602 /* check hardware address */ 596 /* check hardware address */
603 result=OK; 597 result=OK;
@@ -610,7 +604,7 @@ int get_dhcp_offer(int sock){
610 604
611 if(offer_packet.chaddr[x]!=client_hardware_address[x]) 605 if(offer_packet.chaddr[x]!=client_hardware_address[x])
612 result=ERROR; 606 result=ERROR;
613 } 607 }
614 if(verbose) 608 if(verbose)
615 printf("\n"); 609 printf("\n");
616 610
@@ -619,27 +613,27 @@ int get_dhcp_offer(int sock){
619 printf(_("DHCPOFFER hardware address did not match our own - ignoring packet\n")); 613 printf(_("DHCPOFFER hardware address did not match our own - ignoring packet\n"));
620 614
621 continue; 615 continue;
622 } 616 }
623 617
624 if(verbose){ 618 if(verbose){
625 printf("DHCPOFFER ciaddr: %s\n",inet_ntoa(offer_packet.ciaddr)); 619 printf("DHCPOFFER ciaddr: %s\n",inet_ntoa(offer_packet.ciaddr));
626 printf("DHCPOFFER yiaddr: %s\n",inet_ntoa(offer_packet.yiaddr)); 620 printf("DHCPOFFER yiaddr: %s\n",inet_ntoa(offer_packet.yiaddr));
627 printf("DHCPOFFER siaddr: %s\n",inet_ntoa(offer_packet.siaddr)); 621 printf("DHCPOFFER siaddr: %s\n",inet_ntoa(offer_packet.siaddr));
628 printf("DHCPOFFER giaddr: %s\n",inet_ntoa(offer_packet.giaddr)); 622 printf("DHCPOFFER giaddr: %s\n",inet_ntoa(offer_packet.giaddr));
629 } 623 }
630 624
631 add_dhcp_offer(source.sin_addr,&offer_packet); 625 add_dhcp_offer(source.sin_addr,&offer_packet);
632 626
633 valid_responses++; 627 valid_responses++;
634 } 628 }
635 629
636 if(verbose){ 630 if(verbose){
637 printf(_("Total responses seen on the wire: %d\n"),responses); 631 printf(_("Total responses seen on the wire: %d\n"),responses);
638 printf(_("Valid responses for this machine: %d\n"),valid_responses); 632 printf(_("Valid responses for this machine: %d\n"),valid_responses);
639 } 633 }
640 634
641 return OK; 635 return OK;
642 } 636}
643 637
644 638
645 639
@@ -656,14 +650,14 @@ int send_dhcp_packet(void *buffer, int buffer_size, int sock, struct sockaddr_in
656 return ERROR; 650 return ERROR;
657 651
658 return OK; 652 return OK;
659 } 653}
660 654
661 655
662 656
663/* receives a DHCP packet */ 657/* receives a DHCP packet */
664int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, struct sockaddr_in *address){ 658int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, struct sockaddr_in *address){
665 struct timeval tv; 659 struct timeval tv;
666 fd_set readfds; 660 fd_set readfds;
667 fd_set oobfds; 661 fd_set oobfds;
668 int recv_result; 662 int recv_result;
669 socklen_t address_size; 663 socklen_t address_size;
@@ -671,88 +665,88 @@ int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, st
671 int nfound; 665 int nfound;
672 666
673 667
674 /* wait for data to arrive (up time timeout) */ 668 /* wait for data to arrive (up time timeout) */
675 tv.tv_sec=timeout; 669 tv.tv_sec=timeout;
676 tv.tv_usec=0; 670 tv.tv_usec=0;
677 FD_ZERO(&readfds); 671 FD_ZERO(&readfds);
678 FD_ZERO(&oobfds); 672 FD_ZERO(&oobfds);
679 FD_SET(sock,&readfds); 673 FD_SET(sock,&readfds);
680 FD_SET(sock,&oobfds); 674 FD_SET(sock,&oobfds);
681 nfound = select(sock+1,&readfds,NULL,&oobfds,&tv); 675 nfound = select(sock+1,&readfds,NULL,&oobfds,&tv);
682 676
683 /* make sure some data has arrived */ 677 /* make sure some data has arrived */
684 if(!FD_ISSET(sock,&readfds)){ 678 if(!FD_ISSET(sock,&readfds)){
685 if(verbose) 679 if(verbose)
686 printf(_("No (more) data received (nfound: %d)\n"), nfound); 680 printf(_("No (more) data received (nfound: %d)\n"), nfound);
687 return ERROR; 681 return ERROR;
688 } 682 }
689 683
690 else{ 684 else{
691 bzero(&source_address,sizeof(source_address)); 685 bzero(&source_address,sizeof(source_address));
692 address_size=sizeof(source_address); 686 address_size=sizeof(source_address);
693 recv_result=recvfrom(sock,(char *)buffer,buffer_size,0,(struct sockaddr *)&source_address,&address_size); 687 recv_result=recvfrom(sock,(char *)buffer,buffer_size,0,(struct sockaddr *)&source_address,&address_size);
694 if(verbose) 688 if(verbose)
695 printf("recv_result: %d\n",recv_result); 689 printf("recv_result: %d\n",recv_result);
696 690
697 if(recv_result==-1){ 691 if(recv_result==-1){
698 if(verbose){ 692 if(verbose){
699 printf(_("recvfrom() failed, ")); 693 printf(_("recvfrom() failed, "));
700 printf("errno: (%d) -> %s\n",errno,strerror(errno)); 694 printf("errno: (%d) -> %s\n",errno,strerror(errno));
701 } 695 }
702 return ERROR; 696 return ERROR;
703 } 697 }
704 else{ 698 else{
705 if(verbose){ 699 if(verbose){
706 printf(_("receive_dhcp_packet() result: %d\n"),recv_result); 700 printf(_("receive_dhcp_packet() result: %d\n"),recv_result);
707 printf(_("receive_dhcp_packet() source: %s\n"),inet_ntoa(source_address.sin_addr)); 701 printf(_("receive_dhcp_packet() source: %s\n"),inet_ntoa(source_address.sin_addr));
708 } 702 }
709 703
710 memcpy(address,&source_address,sizeof(source_address)); 704 memcpy(address,&source_address,sizeof(source_address));
711 return OK; 705 return OK;
712 } 706 }
713 } 707 }
714 708
715 return OK; 709 return OK;
716 } 710}
717 711
718 712
719/* creates a socket for DHCP communication */ 713/* creates a socket for DHCP communication */
720int create_dhcp_socket(void){ 714int create_dhcp_socket(void){
721 struct sockaddr_in myname; 715 struct sockaddr_in myname;
722 struct ifreq interface; 716 struct ifreq interface;
723 int sock; 717 int sock;
724 int flag=1; 718 int flag=1;
725 719
726 /* Set up the address we're going to bind to. */ 720 /* Set up the address we're going to bind to. */
727 bzero(&myname,sizeof(myname)); 721 bzero(&myname,sizeof(myname));
728 myname.sin_family=AF_INET; 722 myname.sin_family=AF_INET;
729 /* listen to DHCP server port if we're in unicast mode */ 723 /* listen to DHCP server port if we're in unicast mode */
730 myname.sin_port = htons(unicast ? DHCP_SERVER_PORT : DHCP_CLIENT_PORT); 724 myname.sin_port = htons(unicast ? DHCP_SERVER_PORT : DHCP_CLIENT_PORT);
731 myname.sin_addr.s_addr = unicast ? my_ip.s_addr : INADDR_ANY; 725 myname.sin_addr.s_addr = unicast ? my_ip.s_addr : INADDR_ANY;
732 bzero(&myname.sin_zero,sizeof(myname.sin_zero)); 726 bzero(&myname.sin_zero,sizeof(myname.sin_zero));
733 727
734 /* create a socket for DHCP communications */ 728 /* create a socket for DHCP communications */
735 sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); 729 sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
736 if(sock<0){ 730 if(sock<0){
737 printf(_("Error: Could not create socket!\n")); 731 printf(_("Error: Could not create socket!\n"));
738 exit(STATE_UNKNOWN); 732 exit(STATE_UNKNOWN);
739 } 733 }
740 734
741 if(verbose) 735 if(verbose)
742 printf("DHCP socket: %d\n",sock); 736 printf("DHCP socket: %d\n",sock);
743 737
744 /* set the reuse address flag so we don't get errors when restarting */ 738 /* set the reuse address flag so we don't get errors when restarting */
745 flag=1; 739 flag=1;
746 if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&flag,sizeof(flag))<0){ 740 if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&flag,sizeof(flag))<0){
747 printf(_("Error: Could not set reuse address option on DHCP socket!\n")); 741 printf(_("Error: Could not set reuse address option on DHCP socket!\n"));
748 exit(STATE_UNKNOWN); 742 exit(STATE_UNKNOWN);
749 } 743 }
750 744
751 /* set the broadcast option - we need this to listen to DHCP broadcast messages */ 745 /* set the broadcast option - we need this to listen to DHCP broadcast messages */
752 if(!unicast && setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(char *)&flag,sizeof flag)<0){ 746 if(!unicast && setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(char *)&flag,sizeof flag)<0){
753 printf(_("Error: Could not set broadcast option on DHCP socket!\n")); 747 printf(_("Error: Could not set broadcast option on DHCP socket!\n"));
754 exit(STATE_UNKNOWN); 748 exit(STATE_UNKNOWN);
755 } 749 }
756 750
757 /* bind socket to interface */ 751 /* bind socket to interface */
758#if defined(__linux__) 752#if defined(__linux__)
@@ -761,21 +755,21 @@ int create_dhcp_socket(void){
761 if(setsockopt(sock,SOL_SOCKET,SO_BINDTODEVICE,(char *)&interface,sizeof(interface))<0){ 755 if(setsockopt(sock,SOL_SOCKET,SO_BINDTODEVICE,(char *)&interface,sizeof(interface))<0){
762 printf(_("Error: Could not bind socket to interface %s. Check your privileges...\n"),network_interface_name); 756 printf(_("Error: Could not bind socket to interface %s. Check your privileges...\n"),network_interface_name);
763 exit(STATE_UNKNOWN); 757 exit(STATE_UNKNOWN);
764 } 758 }
765 759
766#else 760#else
767 strncpy(interface.ifr_name,network_interface_name,IFNAMSIZ-1); 761 strncpy(interface.ifr_name,network_interface_name,IFNAMSIZ-1);
768 interface.ifr_name[IFNAMSIZ-1]='\0'; 762 interface.ifr_name[IFNAMSIZ-1]='\0';
769#endif 763#endif
770 764
771 /* bind the socket */ 765 /* bind the socket */
772 if(bind(sock,(struct sockaddr *)&myname,sizeof(myname))<0){ 766 if(bind(sock,(struct sockaddr *)&myname,sizeof(myname))<0){
773 printf(_("Error: Could not bind to DHCP socket (port %d)! Check your privileges...\n"),DHCP_CLIENT_PORT); 767 printf(_("Error: Could not bind to DHCP socket (port %d)! Check your privileges...\n"),DHCP_CLIENT_PORT);
774 exit(STATE_UNKNOWN); 768 exit(STATE_UNKNOWN);
775 } 769 }
776 770
777 return sock; 771 return sock;
778 } 772}
779 773
780 774
781/* closes DHCP socket */ 775/* closes DHCP socket */
@@ -784,7 +778,7 @@ int close_dhcp_socket(int sock){
784 close(sock); 778 close(sock);
785 779
786 return OK; 780 return OK;
787 } 781}
788 782
789 783
790/* adds a requested server address to list in memory */ 784/* adds a requested server address to list in memory */
@@ -796,7 +790,7 @@ int add_requested_server(struct in_addr server_address){
796 return ERROR; 790 return ERROR;
797 791
798 new_server->server_address=server_address; 792 new_server->server_address=server_address;
799 new_server->answered=FALSE; 793 new_server->answered=false;
800 794
801 new_server->next=requested_server_list; 795 new_server->next=requested_server_list;
802 requested_server_list=new_server; 796 requested_server_list=new_server;
@@ -807,7 +801,7 @@ int add_requested_server(struct in_addr server_address){
807 printf(_("Requested server address: %s\n"),inet_ntoa(new_server->server_address)); 801 printf(_("Requested server address: %s\n"),inet_ntoa(new_server->server_address));
808 802
809 return OK; 803 return OK;
810 } 804}
811 805
812 806
813 807
@@ -840,29 +834,29 @@ int add_dhcp_offer(struct in_addr source,dhcp_packet *offer_packet){
840 834
841 /* get option data */ 835 /* get option data */
842 switch(option_type){ 836 switch(option_type){
843 case DHCP_OPTION_LEASE_TIME: 837 case DHCP_OPTION_LEASE_TIME:
844 memcpy(&dhcp_lease_time, &offer_packet->options[x],sizeof(dhcp_lease_time)); 838 memcpy(&dhcp_lease_time, &offer_packet->options[x],sizeof(dhcp_lease_time));
845 dhcp_lease_time = ntohl(dhcp_lease_time); 839 dhcp_lease_time = ntohl(dhcp_lease_time);
846 break; 840 break;
847 case DHCP_OPTION_RENEWAL_TIME: 841 case DHCP_OPTION_RENEWAL_TIME:
848 memcpy(&dhcp_renewal_time, &offer_packet->options[x],sizeof(dhcp_renewal_time)); 842 memcpy(&dhcp_renewal_time, &offer_packet->options[x],sizeof(dhcp_renewal_time));
849 dhcp_renewal_time = ntohl(dhcp_renewal_time); 843 dhcp_renewal_time = ntohl(dhcp_renewal_time);
850 break; 844 break;
851 case DHCP_OPTION_REBINDING_TIME: 845 case DHCP_OPTION_REBINDING_TIME:
852 memcpy(&dhcp_rebinding_time, &offer_packet->options[x],sizeof(dhcp_rebinding_time)); 846 memcpy(&dhcp_rebinding_time, &offer_packet->options[x],sizeof(dhcp_rebinding_time));
853 dhcp_rebinding_time = ntohl(dhcp_rebinding_time); 847 dhcp_rebinding_time = ntohl(dhcp_rebinding_time);
854 break; 848 break;
855 case DHCP_OPTION_SERVER_IDENTIFIER: 849 case DHCP_OPTION_SERVER_IDENTIFIER:
856 memcpy(&serv_ident.s_addr, &offer_packet->options[x],sizeof(serv_ident.s_addr)); 850 memcpy(&serv_ident.s_addr, &offer_packet->options[x],sizeof(serv_ident.s_addr));
857 break; 851 break;
858 } 852 }
859 853
860 /* skip option data we're ignoring */ 854 /* skip option data we're ignoring */
861 if(option_type==0) /* "pad" option, see RFC 2132 (3.1) */ 855 if(option_type==0) /* "pad" option, see RFC 2132 (3.1) */
862 x+=1; 856 x+=1;
863 else 857 else
864 x+=option_length; 858 x+=option_length;
865 } 859 }
866 860
867 if(verbose){ 861 if(verbose){
868 if(dhcp_lease_time==DHCP_INFINITE_TIME) 862 if(dhcp_lease_time==DHCP_INFINITE_TIME)
@@ -876,7 +870,7 @@ int add_dhcp_offer(struct in_addr source,dhcp_packet *offer_packet){
876 if(dhcp_rebinding_time==DHCP_INFINITE_TIME) 870 if(dhcp_rebinding_time==DHCP_INFINITE_TIME)
877 printf(_("Rebinding Time: Infinite\n")); 871 printf(_("Rebinding Time: Infinite\n"));
878 printf(_("Rebinding Time: %lu seconds\n"),(unsigned long)dhcp_rebinding_time); 872 printf(_("Rebinding Time: %lu seconds\n"),(unsigned long)dhcp_rebinding_time);
879 } 873 }
880 874
881 new_offer=(dhcp_offer *)malloc(sizeof(dhcp_offer)); 875 new_offer=(dhcp_offer *)malloc(sizeof(dhcp_offer));
882 876
@@ -905,14 +899,14 @@ int add_dhcp_offer(struct in_addr source,dhcp_packet *offer_packet){
905 if(verbose){ 899 if(verbose){
906 printf(_("Added offer from server @ %s"),inet_ntoa(new_offer->server_address)); 900 printf(_("Added offer from server @ %s"),inet_ntoa(new_offer->server_address));
907 printf(_(" of IP address %s\n"),inet_ntoa(new_offer->offered_address)); 901 printf(_(" of IP address %s\n"),inet_ntoa(new_offer->offered_address));
908 } 902 }
909 903
910 /* add new offer to head of list */ 904 /* add new offer to head of list */
911 new_offer->next=dhcp_offer_list; 905 new_offer->next=dhcp_offer_list;
912 dhcp_offer_list=new_offer; 906 dhcp_offer_list=new_offer;
913 907
914 return OK; 908 return OK;
915 } 909}
916 910
917 911
918/* frees memory allocated to DHCP OFFER list */ 912/* frees memory allocated to DHCP OFFER list */
@@ -923,10 +917,10 @@ int free_dhcp_offer_list(void){
923 for(this_offer=dhcp_offer_list;this_offer!=NULL;this_offer=next_offer){ 917 for(this_offer=dhcp_offer_list;this_offer!=NULL;this_offer=next_offer){
924 next_offer=this_offer->next; 918 next_offer=this_offer->next;
925 free(this_offer); 919 free(this_offer);
926 } 920 }
927 921
928 return OK; 922 return OK;
929 } 923}
930 924
931 925
932/* frees memory allocated to requested server list */ 926/* frees memory allocated to requested server list */
@@ -937,10 +931,10 @@ int free_requested_server_list(void){
937 for(this_server=requested_server_list;this_server!=NULL;this_server=next_server){ 931 for(this_server=requested_server_list;this_server!=NULL;this_server=next_server){
938 next_server=this_server->next; 932 next_server=this_server->next;
939 free(this_server); 933 free(this_server);
940 } 934 }
941 935
942 return OK; 936 return OK;
943 } 937}
944 938
945 939
946/* gets state and plugin output to return */ 940/* gets state and plugin output to return */
@@ -948,9 +942,9 @@ int get_results(void){
948 dhcp_offer *temp_offer; 942 dhcp_offer *temp_offer;
949 requested_server *temp_server; 943 requested_server *temp_server;
950 int result; 944 int result;
951 u_int32_t max_lease_time=0; 945 uint32_t max_lease_time=0;
952 946
953 received_requested_address=FALSE; 947 received_requested_address=false;
954 948
955 /* checks responses from requested servers */ 949 /* checks responses from requested servers */
956 requested_responses=0; 950 requested_responses=0;
@@ -966,7 +960,7 @@ int get_results(void){
966 960
967 /* see if we got the address we requested */ 961 /* see if we got the address we requested */
968 if(!memcmp(&requested_address,&temp_offer->offered_address,sizeof(requested_address))) 962 if(!memcmp(&requested_address,&temp_offer->offered_address,sizeof(requested_address)))
969 received_requested_address=TRUE; 963 received_requested_address=true;
970 964
971 /* see if the servers we wanted a response from talked to us or not */ 965 /* see if the servers we wanted a response from talked to us or not */
972 if(!memcmp(&temp_offer->server_address,&temp_server->server_address,sizeof(temp_server->server_address))){ 966 if(!memcmp(&temp_offer->server_address,&temp_server->server_address,sizeof(temp_server->server_address))){
@@ -976,16 +970,16 @@ int get_results(void){
976 if(temp_server->answered) 970 if(temp_server->answered)
977 printf(_(" (duplicate)")); 971 printf(_(" (duplicate)"));
978 printf(_("\n")); 972 printf(_("\n"));
979 } 973 }
980 if(temp_server->answered == FALSE){ 974 if(!temp_server->answered){
981 requested_responses++; 975 requested_responses++;
982 temp_server->answered=TRUE; 976 temp_server->answered=true;
983 } 977 }
984 } 978 }
985 } 979 }
986 } 980 }
987 981
988 } 982 }
989 983
990 /* else check and see if we got our requested address from any server */ 984 /* else check and see if we got our requested address from any server */
991 else{ 985 else{
@@ -998,9 +992,9 @@ int get_results(void){
998 992
999 /* see if we got the address we requested */ 993 /* see if we got the address we requested */
1000 if(!memcmp(&requested_address,&temp_offer->offered_address,sizeof(requested_address))) 994 if(!memcmp(&requested_address,&temp_offer->offered_address,sizeof(requested_address)))
1001 received_requested_address=TRUE; 995 received_requested_address=true;
1002 } 996 }
1003 } 997 }
1004 998
1005 result=STATE_OK; 999 result=STATE_OK;
1006 if(valid_responses==0) 1000 if(valid_responses==0)
@@ -1009,7 +1003,7 @@ int get_results(void){
1009 result=STATE_CRITICAL; 1003 result=STATE_CRITICAL;
1010 else if(requested_responses<requested_servers) 1004 else if(requested_responses<requested_servers)
1011 result=STATE_WARNING; 1005 result=STATE_WARNING;
1012 else if(request_specific_address==TRUE && received_requested_address==FALSE) 1006 else if(request_specific_address && !received_requested_address)
1013 result=STATE_WARNING; 1007 result=STATE_WARNING;
1014 1008
1015 if(result==0) /* garrett honeycutt 2005 */ 1009 if(result==0) /* garrett honeycutt 2005 */
@@ -1025,15 +1019,15 @@ int get_results(void){
1025 if(dhcp_offer_list==NULL){ 1019 if(dhcp_offer_list==NULL){
1026 printf(_("No DHCPOFFERs were received.\n")); 1020 printf(_("No DHCPOFFERs were received.\n"));
1027 return result; 1021 return result;
1028 } 1022 }
1029 1023
1030 printf(_("Received %d DHCPOFFER(s)"),valid_responses); 1024 printf(_("Received %d DHCPOFFER(s)"),valid_responses);
1031 1025
1032 if(requested_servers>0) 1026 if(requested_servers>0)
1033 printf(_(", %s%d of %d requested servers responded"),((requested_responses<requested_servers) && requested_responses>0)?"only ":"",requested_responses,requested_servers); 1027 printf(_(", %s%d of %d requested servers responded"),((requested_responses<requested_servers) && requested_responses>0)?"only ":"",requested_responses,requested_servers);
1034 1028
1035 if(request_specific_address==TRUE) 1029 if(request_specific_address)
1036 printf(_(", requested address (%s) was %soffered"),inet_ntoa(requested_address),(received_requested_address==TRUE)?"":_("not ")); 1030 printf(_(", requested address (%s) was %soffered"),inet_ntoa(requested_address),(received_requested_address)?"":_("not "));
1037 1031
1038 printf(_(", max lease time = ")); 1032 printf(_(", max lease time = "));
1039 if(max_lease_time==DHCP_INFINITE_TIME) 1033 if(max_lease_time==DHCP_INFINITE_TIME)
@@ -1044,7 +1038,7 @@ int get_results(void){
1044 printf(".\n"); 1038 printf(".\n");
1045 1039
1046 return result; 1040 return result;
1047 } 1041}
1048 1042
1049 1043
1050/* process command-line arguments */ 1044/* process command-line arguments */
@@ -1087,71 +1081,71 @@ int call_getopt(int argc, char **argv){
1087 1081
1088 switch(c){ 1082 switch(c){
1089 1083
1090 case 's': /* DHCP server address */ 1084 case 's': /* DHCP server address */
1091 resolve_host(optarg,&dhcp_ip); 1085 resolve_host(optarg,&dhcp_ip);
1092 add_requested_server(dhcp_ip); 1086 add_requested_server(dhcp_ip);
1093 break; 1087 break;
1094 1088
1095 case 'r': /* address we are requested from DHCP servers */ 1089 case 'r': /* address we are requested from DHCP servers */
1096 resolve_host(optarg,&requested_address); 1090 resolve_host(optarg,&requested_address);
1097 request_specific_address=TRUE; 1091 request_specific_address=true;
1098 break; 1092 break;
1099 1093
1100 case 't': /* timeout */ 1094 case 't': /* timeout */
1101
1102 /*
1103 if(is_intnonneg(optarg))
1104 */
1105 if(atoi(optarg)>0)
1106 dhcpoffer_timeout=atoi(optarg);
1107 /*
1108 else
1109 usage("Time interval must be a nonnegative integer\n");
1110 */
1111 break;
1112 1095
1113 case 'm': /* MAC address */ 1096 /*
1097 if(is_intnonneg(optarg))
1098 */
1099 if(atoi(optarg)>0)
1100 dhcpoffer_timeout=atoi(optarg);
1101 /*
1102 else
1103 usage("Time interval must be a nonnegative integer\n");
1104 */
1105 break;
1114 1106
1115 if((user_specified_mac=mac_aton(optarg)) == NULL) 1107 case 'm': /* MAC address */
1116 usage("Cannot parse MAC address.\n");
1117 if(verbose)
1118 print_hardware_address(user_specified_mac);
1119 1108
1120 break; 1109 if((user_specified_mac=mac_aton(optarg)) == NULL)
1110 usage("Cannot parse MAC address.\n");
1111 if(verbose)
1112 print_hardware_address(user_specified_mac);
1121 1113
1122 case 'i': /* interface name */ 1114 break;
1123 1115
1124 strncpy(network_interface_name,optarg,sizeof(network_interface_name)-1); 1116 case 'i': /* interface name */
1125 network_interface_name[sizeof(network_interface_name)-1]='\x0';
1126 1117
1127 break; 1118 strncpy(network_interface_name,optarg,sizeof(network_interface_name)-1);
1119 network_interface_name[sizeof(network_interface_name)-1]='\x0';
1128 1120
1129 case 'u': /* unicast testing */ 1121 break;
1130 unicast=1;
1131 break;
1132 1122
1133 case 'V': /* version */ 1123 case 'u': /* unicast testing */
1134 print_revision(progname, NP_VERSION); 1124 unicast=1;
1135 exit(STATE_UNKNOWN); 1125 break;
1136 1126
1137 case 'h': /* help */ 1127 case 'V': /* version */
1138 print_help(); 1128 print_revision(progname, NP_VERSION);
1139 exit(STATE_UNKNOWN); 1129 exit(STATE_UNKNOWN);
1140 1130
1141 case 'v': /* verbose */ 1131 case 'h': /* help */
1142 verbose=1; 1132 print_help();
1143 break; 1133 exit(STATE_UNKNOWN);
1144 1134
1145 case '?': /* help */ 1135 case 'v': /* verbose */
1146 usage5 (); 1136 verbose=1;
1147 break; 1137 break;
1148 1138
1149 default: 1139 case '?': /* help */
1150 break; 1140 usage5 ();
1151 } 1141 break;
1152 } 1142
1143 default:
1144 break;
1145 }
1146 }
1153 return optind; 1147 return optind;
1154 } 1148}
1155 1149
1156 1150
1157int validate_arguments(int argc){ 1151int validate_arguments(int argc){
@@ -1178,21 +1172,21 @@ static int get_msg(int fd){
1178 if(res < 0){ 1172 if(res < 0){
1179 if(errno == EINTR){ 1173 if(errno == EINTR){
1180 return(GOT_INTR); 1174 return(GOT_INTR);
1181 } 1175 }
1182 else{ 1176 else{
1183 printf("%s\n", "get_msg FAILED."); 1177 printf("%s\n", "get_msg FAILED.");
1184 return(GOT_ERR); 1178 return(GOT_ERR);
1185 }
1186 } 1179 }
1180 }
1187 if(ctl.len > 0){ 1181 if(ctl.len > 0){
1188 ret |= GOT_CTRL; 1182 ret |= GOT_CTRL;
1189 } 1183 }
1190 if(dat.len > 0){ 1184 if(dat.len > 0){
1191 ret |= GOT_DATA; 1185 ret |= GOT_DATA;
1192 } 1186 }
1193 1187
1194 return(ret); 1188 return(ret);
1195 } 1189}
1196 1190
1197/* verify that dl_primitive in ctl_area = prim */ 1191/* verify that dl_primitive in ctl_area = prim */
1198static int check_ctrl(int prim){ 1192static int check_ctrl(int prim){
@@ -1201,10 +1195,10 @@ static int check_ctrl(int prim){
1201 if(err_ack->dl_primitive != prim){ 1195 if(err_ack->dl_primitive != prim){
1202 printf(_("Error: DLPI stream API failed to get MAC in check_ctrl: %s.\n"), strerror(errno)); 1196 printf(_("Error: DLPI stream API failed to get MAC in check_ctrl: %s.\n"), strerror(errno));
1203 exit(STATE_UNKNOWN); 1197 exit(STATE_UNKNOWN);
1204 } 1198 }
1205 1199
1206 return 0; 1200 return 0;
1207 } 1201}
1208 1202
1209/* put a control message on a stream */ 1203/* put a control message on a stream */
1210static int put_ctrl(int fd, int len, int pri){ 1204static int put_ctrl(int fd, int len, int pri){
@@ -1213,10 +1207,10 @@ static int put_ctrl(int fd, int len, int pri){
1213 if(putmsg(fd, &ctl, 0, pri) < 0){ 1207 if(putmsg(fd, &ctl, 0, pri) < 0){
1214 printf(_("Error: DLPI stream API failed to get MAC in put_ctrl/putmsg(): %s.\n"), strerror(errno)); 1208 printf(_("Error: DLPI stream API failed to get MAC in put_ctrl/putmsg(): %s.\n"), strerror(errno));
1215 exit(STATE_UNKNOWN); 1209 exit(STATE_UNKNOWN);
1216 } 1210 }
1217 1211
1218 return 0; 1212 return 0;
1219 } 1213}
1220 1214
1221/* put a control + data message on a stream */ 1215/* put a control + data message on a stream */
1222static int put_both(int fd, int clen, int dlen, int pri){ 1216static int put_both(int fd, int clen, int dlen, int pri){
@@ -1226,10 +1220,10 @@ static int put_both(int fd, int clen, int dlen, int pri){
1226 if(putmsg(fd, &ctl, &dat, pri) < 0){ 1220 if(putmsg(fd, &ctl, &dat, pri) < 0){
1227 printf(_("Error: DLPI stream API failed to get MAC in put_both/putmsg().\n"), strerror(errno)); 1221 printf(_("Error: DLPI stream API failed to get MAC in put_both/putmsg().\n"), strerror(errno));
1228 exit(STATE_UNKNOWN); 1222 exit(STATE_UNKNOWN);
1229 } 1223 }
1230 1224
1231 return 0; 1225 return 0;
1232 } 1226}
1233 1227
1234/* open file descriptor and attach */ 1228/* open file descriptor and attach */
1235static int dl_open(const char *dev, int unit, int *fd){ 1229static int dl_open(const char *dev, int unit, int *fd){
@@ -1238,13 +1232,13 @@ static int dl_open(const char *dev, int unit, int *fd){
1238 if((*fd = open(dev, O_RDWR)) == -1){ 1232 if((*fd = open(dev, O_RDWR)) == -1){
1239 printf(_("Error: DLPI stream API failed to get MAC in dl_attach_req/open(%s..): %s.\n"), dev, strerror(errno)); 1233 printf(_("Error: DLPI stream API failed to get MAC in dl_attach_req/open(%s..): %s.\n"), dev, strerror(errno));
1240 exit(STATE_UNKNOWN); 1234 exit(STATE_UNKNOWN);
1241 } 1235 }
1242 attach_req->dl_primitive = DL_ATTACH_REQ; 1236 attach_req->dl_primitive = DL_ATTACH_REQ;
1243 attach_req->dl_ppa = unit; 1237 attach_req->dl_ppa = unit;
1244 put_ctrl(*fd, sizeof(dl_attach_req_t), 0); 1238 put_ctrl(*fd, sizeof(dl_attach_req_t), 0);
1245 get_msg(*fd); 1239 get_msg(*fd);
1246 return check_ctrl(DL_OK_ACK); 1240 return check_ctrl(DL_OK_ACK);
1247 } 1241}
1248 1242
1249/* send DL_BIND_REQ */ 1243/* send DL_BIND_REQ */
1250static int dl_bind(int fd, int sap, u_char *addr){ 1244static int dl_bind(int fd, int sap, u_char *addr){
@@ -1262,12 +1256,12 @@ static int dl_bind(int fd, int sap, u_char *addr){
1262 if (GOT_ERR == check_ctrl(DL_BIND_ACK)){ 1256 if (GOT_ERR == check_ctrl(DL_BIND_ACK)){
1263 printf(_("Error: DLPI stream API failed to get MAC in dl_bind/check_ctrl(): %s.\n"), strerror(errno)); 1257 printf(_("Error: DLPI stream API failed to get MAC in dl_bind/check_ctrl(): %s.\n"), strerror(errno));
1264 exit(STATE_UNKNOWN); 1258 exit(STATE_UNKNOWN);
1265 } 1259 }
1266 bcopy((u_char *)bind_ack + bind_ack->dl_addr_offset, addr, 1260 bcopy((u_char *)bind_ack + bind_ack->dl_addr_offset, addr,
1267 bind_ack->dl_addr_length); 1261 bind_ack->dl_addr_length);
1268 1262
1269 return 0; 1263 return 0;
1270 } 1264}
1271 1265
1272/*********************************************************************** 1266/***********************************************************************
1273 * interface: 1267 * interface:
@@ -1286,15 +1280,15 @@ long mac_addr_dlpi( const char *dev, int unit, u_char *addr){
1286 u_char mac_addr[25]; 1280 u_char mac_addr[25];
1287 1281
1288 if(GOT_ERR != dl_open(dev, unit, &fd)){ 1282 if(GOT_ERR != dl_open(dev, unit, &fd)){
1289 if(GOT_ERR != dl_bind(fd, INSAP, mac_addr)){ 1283 if(GOT_ERR != dl_bind(fd, INSAP, mac_addr)){
1290 bcopy( mac_addr, addr, 6); 1284 bcopy( mac_addr, addr, 6);
1291 return 0; 1285 return 0;
1292 }
1293 } 1286 }
1294 close(fd); 1287 }
1288 close(fd);
1295 1289
1296 return -1; 1290 return -1;
1297 } 1291}
1298 1292
1299/* Kompf 2000-2003 */ 1293/* Kompf 2000-2003 */
1300#endif 1294#endif
@@ -1311,7 +1305,7 @@ void resolve_host(const char *in,struct in_addr *out){
1311 1305
1312 memcpy(out,&((struct sockaddr_in *)ai->ai_addr)->sin_addr,sizeof(*out)); 1306 memcpy(out,&((struct sockaddr_in *)ai->ai_addr)->sin_addr,sizeof(*out));
1313 freeaddrinfo(ai); 1307 freeaddrinfo(ai);
1314 } 1308}
1315 1309
1316 1310
1317/* parse MAC address string, return 6 bytes (unterminated) or NULL */ 1311/* parse MAC address string, return 6 bytes (unterminated) or NULL */
@@ -1330,10 +1324,10 @@ unsigned char *mac_aton(const char *string){
1330 result[j]=strtol(tmp,(char **)NULL,16); 1324 result[j]=strtol(tmp,(char **)NULL,16);
1331 i++; 1325 i++;
1332 j++; 1326 j++;
1333 } 1327 }
1334 1328
1335 return (j==6) ? result : NULL; 1329 return (j==6) ? result : NULL;
1336 } 1330}
1337 1331
1338 1332
1339void print_hardware_address(const unsigned char *address){ 1333void print_hardware_address(const unsigned char *address){
@@ -1344,7 +1338,7 @@ void print_hardware_address(const unsigned char *address){
1344 printf("%2.2x:", address[i]); 1338 printf("%2.2x:", address[i]);
1345 printf("%2.2x", address[i]); 1339 printf("%2.2x", address[i]);
1346 putchar('\n'); 1340 putchar('\n');
1347 } 1341}
1348 1342
1349 1343
1350/* print usage help */ 1344/* print usage help */
@@ -1357,7 +1351,7 @@ void print_help(void){
1357 1351
1358 printf("%s\n", _("This plugin tests the availability of DHCP servers on a network.")); 1352 printf("%s\n", _("This plugin tests the availability of DHCP servers on a network."));
1359 1353
1360 printf ("\n\n"); 1354 printf ("\n\n");
1361 1355
1362 print_usage(); 1356 print_usage();
1363 1357
@@ -1367,32 +1361,29 @@ void print_help(void){
1367 printf (UT_VERBOSE); 1361 printf (UT_VERBOSE);
1368 1362
1369 printf (" %s\n", "-s, --serverip=IPADDRESS"); 1363 printf (" %s\n", "-s, --serverip=IPADDRESS");
1370 printf (" %s\n", _("IP address of DHCP server that we must hear from")); 1364 printf (" %s\n", _("IP address of DHCP server that we must hear from"));
1371 printf (" %s\n", "-r, --requestedip=IPADDRESS"); 1365 printf (" %s\n", "-r, --requestedip=IPADDRESS");
1372 printf (" %s\n", _("IP address that should be offered by at least one DHCP server")); 1366 printf (" %s\n", _("IP address that should be offered by at least one DHCP server"));
1373 printf (" %s\n", "-t, --timeout=INTEGER"); 1367 printf (" %s\n", "-t, --timeout=INTEGER");
1374 printf (" %s\n", _("Seconds to wait for DHCPOFFER before timeout occurs")); 1368 printf (" %s\n", _("Seconds to wait for DHCPOFFER before timeout occurs"));
1375 printf (" %s\n", "-i, --interface=STRING"); 1369 printf (" %s\n", "-i, --interface=STRING");
1376 printf (" %s\n", _("Interface to to use for listening (i.e. eth0)")); 1370 printf (" %s\n", _("Interface to to use for listening (i.e. eth0)"));
1377 printf (" %s\n", "-m, --mac=STRING"); 1371 printf (" %s\n", "-m, --mac=STRING");
1378 printf (" %s\n", _("MAC address to use in the DHCP request")); 1372 printf (" %s\n", _("MAC address to use in the DHCP request"));
1379 printf (" %s\n", "-u, --unicast"); 1373 printf (" %s\n", "-u, --unicast");
1380 printf (" %s\n", _("Unicast testing: mimic a DHCP relay, requires -s")); 1374 printf (" %s\n", _("Unicast testing: mimic a DHCP relay, requires -s"));
1381 1375
1382 printf (UT_SUPPORT); 1376 printf (UT_SUPPORT);
1383 return; 1377 return;
1384 } 1378}
1385 1379
1386 1380
1387void 1381void
1388print_usage(void){ 1382print_usage(void){
1389 1383
1390 printf ("%s\n", _("Usage:")); 1384 printf ("%s\n", _("Usage:"));
1391 printf (" %s [-v] [-u] [-s serverip] [-r requestedip] [-t timeout]\n",progname); 1385 printf (" %s [-v] [-u] [-s serverip] [-r requestedip] [-t timeout]\n",progname);
1392 printf (" [-i interface] [-m mac]\n"); 1386 printf (" [-i interface] [-m mac]\n");
1393 1387
1394 return; 1388 return;
1395 } 1389}
1396
1397
1398
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c
index 1d47e9f..303241d 100644
--- a/plugins-root/check_icmp.c
+++ b/plugins-root/check_icmp.c
@@ -43,7 +43,7 @@ const char *copyright = "2005-2008";
43const char *email = "devel@monitoring-plugins.org"; 43const char *email = "devel@monitoring-plugins.org";
44 44
45/** Monitoring Plugins basic includes */ 45/** Monitoring Plugins basic includes */
46#include "common.h" 46#include "../plugins/common.h"
47#include "netutils.h" 47#include "netutils.h"
48#include "utils.h" 48#include "utils.h"
49 49
@@ -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; // check result for RTA checks
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; // check result for Jitter checks
117 double jitter_max; /* jitter rtt maximum */
118 double jitter_min; /* jitter rtt minimum */
119 double EffectiveLatency;
120 double mos; /* Mean opnion score */
121 int mos_status; // check result for MOS checks
122 double score; /* score */
123 int score_status; // check result for score checks
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; // check result for packet loss checks
115 struct rta_host *next; /* linked list */ 128 struct rta_host *next; /* linked list */
129 int order_status; // check result for packet order checks
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 */
@@ -159,6 +176,16 @@ typedef union icmp_packet {
159#define MODE_ALL 2 176#define MODE_ALL 2
160#define MODE_ICMP 3 177#define MODE_ICMP 3
161 178
179enum enum_threshold_mode {
180 const_rta_mode,
181 const_packet_loss_mode,
182 const_jitter_mode,
183 const_mos_mode,
184 const_score_mode
185};
186
187typedef enum enum_threshold_mode threshold_mode;
188
162/* the different ping types we can do 189/* the different ping types we can do
163 * TODO: investigate ARP ping as well */ 190 * TODO: investigate ARP ping as well */
164#define HAVE_ICMP 1 191#define HAVE_ICMP 1
@@ -188,6 +215,8 @@ static int wait_for_reply(int, u_int);
188static int recvfrom_wto(int, void *, unsigned int, struct sockaddr *, u_int *, struct timeval*); 215static int recvfrom_wto(int, void *, unsigned int, struct sockaddr *, u_int *, struct timeval*);
189static int send_icmp_ping(int, struct rta_host *); 216static int send_icmp_ping(int, struct rta_host *);
190static int get_threshold(char *str, threshold *th); 217static int get_threshold(char *str, threshold *th);
218static bool get_threshold2(char *str, size_t length, threshold *, threshold *, threshold_mode mode);
219static bool parse_threshold2_helper(char *s, size_t length, threshold *thr, threshold_mode mode);
191static void run_checks(void); 220static void run_checks(void);
192static void set_source_ip(char *); 221static void set_source_ip(char *);
193static int add_target(char *); 222static int add_target(char *);
@@ -199,13 +228,28 @@ static void finish(int);
199static void crash(const char *, ...); 228static void crash(const char *, ...);
200 229
201/** external **/ 230/** external **/
202extern int optind, opterr, optopt; 231extern int optind;
203extern char *optarg; 232extern char *optarg;
204extern char **environ; 233extern char **environ;
205 234
206/** global variables **/ 235/** global variables **/
207static struct rta_host **table, *cursor, *list; 236static struct rta_host **table, *cursor, *list;
208static threshold crit = {80, 500000}, warn = {40, 200000}; 237
238static threshold crit = {
239 .pl = 80,
240 .rta = 500000,
241 .jitter = 0.0,
242 .mos = 0.0,
243 .score = 0.0
244};
245static threshold warn = {
246 .pl = 40,
247 .rta = 200000,
248 .jitter = 0.0,
249 .mos = 0.0,
250 .score = 0.0
251};
252
209static int mode, protocols, sockets, debug = 0, timeout = 10; 253static int mode, protocols, sockets, debug = 0, timeout = 10;
210static unsigned short icmp_data_size = DEFAULT_PING_DATA_SIZE; 254static unsigned short icmp_data_size = DEFAULT_PING_DATA_SIZE;
211static unsigned short icmp_pkt_size = DEFAULT_PING_DATA_SIZE + ICMP_MINLEN; 255static unsigned short icmp_pkt_size = DEFAULT_PING_DATA_SIZE + ICMP_MINLEN;
@@ -224,6 +268,12 @@ static unsigned int warn_down = 1, crit_down = 1; /* host down threshold values
224static int min_hosts_alive = -1; 268static int min_hosts_alive = -1;
225float pkt_backoff_factor = 1.5; 269float pkt_backoff_factor = 1.5;
226float target_backoff_factor = 1.5; 270float target_backoff_factor = 1.5;
271bool rta_mode=false;
272bool pl_mode=false;
273bool jitter_mode=false;
274bool score_mode=false;
275bool mos_mode=false;
276bool order_mode=false;
227 277
228/** code start **/ 278/** code start **/
229static void 279static void
@@ -393,12 +443,14 @@ main(int argc, char **argv)
393 int icmp_sockerrno, udp_sockerrno, tcp_sockerrno; 443 int icmp_sockerrno, udp_sockerrno, tcp_sockerrno;
394 int result; 444 int result;
395 struct rta_host *host; 445 struct rta_host *host;
446#ifdef HAVE_SIGACTION
447 struct sigaction sig_action;
448#endif
396#ifdef SO_TIMESTAMP 449#ifdef SO_TIMESTAMP
397 int on = 1; 450 int on = 1;
398#endif 451#endif
399 char *source_ip = NULL; 452 char *source_ip = NULL;
400 char * opts_str = "vhVw:c:n:p:t:H:s:i:b:I:l:m:64"; 453 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, ""); 454 setlocale (LC_ALL, "");
403 bindtextdomain (PACKAGE, LOCALEDIR); 455 bindtextdomain (PACKAGE, LOCALEDIR);
404 textdomain (PACKAGE); 456 textdomain (PACKAGE);
@@ -407,7 +459,7 @@ main(int argc, char **argv)
407 * that before pointer magic (esp. on network data) */ 459 * that before pointer magic (esp. on network data) */
408 icmp_sockerrno = udp_sockerrno = tcp_sockerrno = sockets = 0; 460 icmp_sockerrno = udp_sockerrno = tcp_sockerrno = sockets = 0;
409 461
410 address_family = -1; 462 address_family = -1;
411 int icmp_proto = IPPROTO_ICMP; 463 int icmp_proto = IPPROTO_ICMP;
412 464
413 /* get calling name the old-fashioned way for portability instead 465 /* get calling name the old-fashioned way for portability instead
@@ -422,10 +474,19 @@ main(int argc, char **argv)
422 table = NULL; 474 table = NULL;
423 475
424 mode = MODE_RTA; 476 mode = MODE_RTA;
477 /* Default critical thresholds */
425 crit.rta = 500000; 478 crit.rta = 500000;
426 crit.pl = 80; 479 crit.pl = 80;
480 crit.jitter = 50;
481 crit.mos= 3;
482 crit.score=70;
483 /* Default warning thresholds */
427 warn.rta = 200000; 484 warn.rta = 200000;
428 warn.pl = 40; 485 warn.pl = 40;
486 warn.jitter = 40;
487 warn.mos= 3.5;
488 warn.score=80;
489
429 protocols = HAVE_ICMP | HAVE_UDP | HAVE_TCP; 490 protocols = HAVE_ICMP | HAVE_UDP | HAVE_TCP;
430 pkt_interval = 80000; /* 80 msec packet interval by default */ 491 pkt_interval = 80000; /* 80 msec packet interval by default */
431 packets = 5; 492 packets = 5;
@@ -481,7 +542,8 @@ main(int argc, char **argv)
481 /* Reset argument scanning */ 542 /* Reset argument scanning */
482 optind = 1; 543 optind = 1;
483 544
484 unsigned short size; 545 unsigned long size;
546 bool err;
485 /* parse the arguments */ 547 /* parse the arguments */
486 for(i = 1; i < argc; i++) { 548 for(i = 1; i < argc; i++) {
487 while((arg = getopt(argc, argv, opts_str)) != EOF) { 549 while((arg = getopt(argc, argv, opts_str)) != EOF) {
@@ -490,7 +552,7 @@ main(int argc, char **argv)
490 debug++; 552 debug++;
491 break; 553 break;
492 case 'b': 554 case 'b':
493 size = (unsigned short)strtol(optarg,NULL,0); 555 size = strtol(optarg,NULL,0);
494 if (size >= (sizeof(struct icmp) + sizeof(struct icmp_ping_data)) && 556 if (size >= (sizeof(struct icmp) + sizeof(struct icmp_ping_data)) &&
495 size < MAX_PING_DATA) { 557 size < MAX_PING_DATA) {
496 icmp_data_size = size; 558 icmp_data_size = size;
@@ -545,6 +607,49 @@ main(int argc, char **argv)
545 print_help (); 607 print_help ();
546 exit (STATE_UNKNOWN); 608 exit (STATE_UNKNOWN);
547 break; 609 break;
610 case 'R': /* RTA mode */
611 err = get_threshold2(optarg, strlen(optarg), &warn, &crit, const_rta_mode);
612 if (!err) {
613 crash("Failed to parse RTA threshold");
614 }
615
616 rta_mode=true;
617 break;
618 case 'P': /* packet loss mode */
619 err = get_threshold2(optarg, strlen(optarg), &warn, &crit, const_packet_loss_mode);
620 if (!err) {
621 crash("Failed to parse packet loss threshold");
622 }
623
624 pl_mode=true;
625 break;
626 case 'J': /* jitter mode */
627 err = get_threshold2(optarg, strlen(optarg), &warn, &crit, const_jitter_mode);
628 if (!err) {
629 crash("Failed to parse jitter threshold");
630 }
631
632 jitter_mode=true;
633 break;
634 case 'M': /* MOS mode */
635 err = get_threshold2(optarg, strlen(optarg), &warn, &crit, const_mos_mode);
636 if (!err) {
637 crash("Failed to parse MOS threshold");
638 }
639
640 mos_mode=true;
641 break;
642 case 'S': /* score mode */
643 err = get_threshold2(optarg, strlen(optarg), &warn, &crit, const_score_mode);
644 if (!err) {
645 crash("Failed to parse score threshold");
646 }
647
648 score_mode=true;
649 break;
650 case 'O': /* out of order mode */
651 order_mode=true;
652 break;
548 } 653 }
549 } 654 }
550 } 655 }
@@ -565,10 +670,10 @@ main(int argc, char **argv)
565 add_target(*argv); 670 add_target(*argv);
566 argv++; 671 argv++;
567 } 672 }
673
568 if(!targets) { 674 if(!targets) {
569 errno = 0; 675 errno = 0;
570 crash("No hosts to check"); 676 crash("No hosts to check");
571 exit(3);
572 } 677 }
573 678
574 // add_target might change address_family 679 // add_target might change address_family
@@ -631,11 +736,25 @@ main(int argc, char **argv)
631 if(warn.pl > crit.pl) warn.pl = crit.pl; 736 if(warn.pl > crit.pl) warn.pl = crit.pl;
632 if(warn.rta > crit.rta) warn.rta = crit.rta; 737 if(warn.rta > crit.rta) warn.rta = crit.rta;
633 if(warn_down > crit_down) crit_down = warn_down; 738 if(warn_down > crit_down) crit_down = warn_down;
634 739 if(warn.jitter > crit.jitter) crit.jitter = warn.jitter;
740 if(warn.mos < crit.mos) warn.mos = crit.mos;
741 if(warn.score < crit.score) warn.score = crit.score;
742
743#ifdef HAVE_SIGACTION
744 sig_action.sa_sigaction = NULL;
745 sig_action.sa_handler = finish;
746 sigfillset(&sig_action.sa_mask);
747 sig_action.sa_flags = SA_NODEFER|SA_RESTART;
748 sigaction(SIGINT, &sig_action, NULL);
749 sigaction(SIGHUP, &sig_action, NULL);
750 sigaction(SIGTERM, &sig_action, NULL);
751 sigaction(SIGALRM, &sig_action, NULL);
752#else /* HAVE_SIGACTION */
635 signal(SIGINT, finish); 753 signal(SIGINT, finish);
636 signal(SIGHUP, finish); 754 signal(SIGHUP, finish);
637 signal(SIGTERM, finish); 755 signal(SIGTERM, finish);
638 signal(SIGALRM, finish); 756 signal(SIGALRM, finish);
757#endif /* HAVE_SIGACTION */
639 if(debug) printf("Setting alarm timeout to %u seconds\n", timeout); 758 if(debug) printf("Setting alarm timeout to %u seconds\n", timeout);
640 alarm(timeout); 759 alarm(timeout);
641 760
@@ -685,7 +804,11 @@ main(int argc, char **argv)
685 } 804 }
686 805
687 host = list; 806 host = list;
688 table = (struct rta_host**)malloc(sizeof(struct rta_host **) * targets); 807 table = malloc(sizeof(struct rta_host *) * targets);
808 if(!table) {
809 crash("main(): malloc failed for host table");
810 }
811
689 i = 0; 812 i = 0;
690 while(host) { 813 while(host) {
691 host->id = i*packets; 814 host->id = i*packets;
@@ -772,6 +895,7 @@ wait_for_reply(int sock, u_int t)
772 struct icmp_ping_data data; 895 struct icmp_ping_data data;
773 struct timeval wait_start, now; 896 struct timeval wait_start, now;
774 u_int tdiff, i, per_pkt_wait; 897 u_int tdiff, i, per_pkt_wait;
898 double jitter_tmp;
775 899
776 if (!(packet.buf = malloc(icmp_pkt_size))) { 900 if (!(packet.buf = malloc(icmp_pkt_size))) {
777 crash("send_icmp_ping(): failed to malloc %d bytes for send buffer", 901 crash("send_icmp_ping(): failed to malloc %d bytes for send buffer",
@@ -890,12 +1014,44 @@ wait_for_reply(int sock, u_int t)
890 1014
891 tdiff = get_timevaldiff(&data.stime, &now); 1015 tdiff = get_timevaldiff(&data.stime, &now);
892 1016
1017 if (host->last_tdiff>0) {
1018 /* Calculate jitter */
1019 if (host->last_tdiff > tdiff) {
1020 jitter_tmp = host->last_tdiff - tdiff;
1021 } else {
1022 jitter_tmp = tdiff - host->last_tdiff;
1023 }
1024
1025 if (host->jitter==0) {
1026 host->jitter=jitter_tmp;
1027 host->jitter_max=jitter_tmp;
1028 host->jitter_min=jitter_tmp;
1029 } else {
1030 host->jitter+=jitter_tmp;
1031
1032 if (jitter_tmp < host->jitter_min) {
1033 host->jitter_min=jitter_tmp;
1034 }
1035
1036 if (jitter_tmp > host->jitter_max) {
1037 host->jitter_max=jitter_tmp;
1038 }
1039 }
1040
1041 /* Check if packets in order */
1042 if (host->last_icmp_seq >= packet.icp->icmp_seq)
1043 host->order_status=STATE_CRITICAL;
1044 }
1045 host->last_tdiff=tdiff;
1046
1047 host->last_icmp_seq=packet.icp->icmp_seq;
1048
893 host->time_waited += tdiff; 1049 host->time_waited += tdiff;
894 host->icmp_recv++; 1050 host->icmp_recv++;
895 icmp_recv++; 1051 icmp_recv++;
896 if (tdiff > host->rtmax) 1052 if (tdiff > (unsigned int)host->rtmax)
897 host->rtmax = tdiff; 1053 host->rtmax = tdiff;
898 if (tdiff < host->rtmin) 1054 if (tdiff < (unsigned int)host->rtmin)
899 host->rtmin = tdiff; 1055 host->rtmin = tdiff;
900 1056
901 if(debug) { 1057 if(debug) {
@@ -1056,7 +1212,9 @@ recvfrom_wto(int sock, void *buf, unsigned int len, struct sockaddr *saddr,
1056 int n, ret; 1212 int n, ret;
1057 struct timeval to, then, now; 1213 struct timeval to, then, now;
1058 fd_set rd, wr; 1214 fd_set rd, wr;
1215#ifdef HAVE_MSGHDR_MSG_CONTROL
1059 char ans_data[4096]; 1216 char ans_data[4096];
1217#endif // HAVE_MSGHDR_MSG_CONTROL
1060 struct msghdr hdr; 1218 struct msghdr hdr;
1061 struct iovec iov; 1219 struct iovec iov;
1062#ifdef SO_TIMESTAMP 1220#ifdef SO_TIMESTAMP
@@ -1094,8 +1252,10 @@ recvfrom_wto(int sock, void *buf, unsigned int len, struct sockaddr *saddr,
1094 hdr.msg_namelen = slen; 1252 hdr.msg_namelen = slen;
1095 hdr.msg_iov = &iov; 1253 hdr.msg_iov = &iov;
1096 hdr.msg_iovlen = 1; 1254 hdr.msg_iovlen = 1;
1255#ifdef HAVE_MSGHDR_MSG_CONTROL
1097 hdr.msg_control = ans_data; 1256 hdr.msg_control = ans_data;
1098 hdr.msg_controllen = sizeof(ans_data); 1257 hdr.msg_controllen = sizeof(ans_data);
1258#endif
1099 1259
1100 ret = recvmsg(sock, &hdr, 0); 1260 ret = recvmsg(sock, &hdr, 0);
1101#ifdef SO_TIMESTAMP 1261#ifdef SO_TIMESTAMP
@@ -1125,6 +1285,8 @@ finish(int sig)
1125 {"OK", "WARNING", "CRITICAL", "UNKNOWN", "DEPENDENT"}; 1285 {"OK", "WARNING", "CRITICAL", "UNKNOWN", "DEPENDENT"};
1126 int hosts_ok = 0; 1286 int hosts_ok = 0;
1127 int hosts_warn = 0; 1287 int hosts_warn = 0;
1288 int this_status;
1289 double R;
1128 1290
1129 alarm(0); 1291 alarm(0);
1130 if(debug > 1) printf("finish(%d) called\n", sig); 1292 if(debug > 1) printf("finish(%d) called\n", sig);
@@ -1140,9 +1302,12 @@ finish(int sig)
1140 } 1302 }
1141 1303
1142 /* iterate thrice to calculate values, give output, and print perfparse */ 1304 /* iterate thrice to calculate values, give output, and print perfparse */
1305 status=STATE_OK;
1143 host = list; 1306 host = list;
1144 1307
1145 while(host) { 1308 while(host) {
1309 this_status = STATE_OK;
1310
1146 if(!host->icmp_recv) { 1311 if(!host->icmp_recv) {
1147 /* rta 0 is ofcourse not entirely correct, but will still show up 1312 /* rta 0 is ofcourse not entirely correct, but will still show up
1148 * conspicuously as missing entries in perfparse and cacti */ 1313 * conspicuously as missing entries in perfparse and cacti */
@@ -1151,26 +1316,138 @@ finish(int sig)
1151 status = STATE_CRITICAL; 1316 status = STATE_CRITICAL;
1152 /* up the down counter if not already counted */ 1317 /* up the down counter if not already counted */
1153 if(!(host->flags & FLAG_LOST_CAUSE) && targets_alive) targets_down++; 1318 if(!(host->flags & FLAG_LOST_CAUSE) && targets_alive) targets_down++;
1154 } 1319 } else {
1155 else {
1156 pl = ((host->icmp_sent - host->icmp_recv) * 100) / host->icmp_sent; 1320 pl = ((host->icmp_sent - host->icmp_recv) * 100) / host->icmp_sent;
1157 rta = (double)host->time_waited / host->icmp_recv; 1321 rta = (double)host->time_waited / host->icmp_recv;
1158 } 1322 }
1323
1324 if (host->icmp_recv>1) {
1325 /*
1326 * This algorithm is probably pretty much blindly copied from
1327 * locations like this one: https://www.slac.stanford.edu/comp/net/wan-mon/tutorial.html#mos
1328 * It calculates a MOS value (range of 1 to 5, where 1 is bad and 5 really good).
1329 * According to some quick research MOS originates from the Audio/Video transport network area.
1330 * Whether it can and should be computed from ICMP data, I can not say.
1331 *
1332 * Anyway the basic idea is to map a value "R" with a range of 0-100 to the MOS value
1333 *
1334 * MOS stands likely for Mean Opinion Score ( https://en.wikipedia.org/wiki/Mean_Opinion_Score )
1335 *
1336 * More links:
1337 * - https://confluence.slac.stanford.edu/display/IEPM/MOS
1338 */
1339 host->jitter=(host->jitter / (host->icmp_recv - 1)/1000);
1340
1341 /*
1342 * Take the average round trip latency (in milliseconds), add
1343 * round trip jitter, but double the impact to latency
1344 * then add 10 for protocol latencies (in milliseconds).
1345 */
1346 host->EffectiveLatency = (rta/1000) + host->jitter * 2 + 10;
1347
1348 if (host->EffectiveLatency < 160) {
1349 R = 93.2 - (host->EffectiveLatency / 40);
1350 } else {
1351 R = 93.2 - ((host->EffectiveLatency - 120) / 10);
1352 }
1353
1354 // Now, let us deduct 2.5 R values per percentage of packet loss (i.e. a
1355 // loss of 5% will be entered as 5).
1356 R = R - (pl * 2.5);
1357
1358 if (R < 0) {
1359 R = 0;
1360 }
1361
1362 host->score = R;
1363 host->mos= 1 + ((0.035) * R) + ((.000007) * R * (R-60) * (100-R));
1364 } else {
1365 host->jitter=0;
1366 host->jitter_min=0;
1367 host->jitter_max=0;
1368 host->mos=0;
1369 }
1370
1159 host->pl = pl; 1371 host->pl = pl;
1160 host->rta = rta; 1372 host->rta = rta;
1161 if(pl >= crit.pl || rta >= crit.rta) { 1373
1162 status = STATE_CRITICAL; 1374 /* if no new mode selected, use old schema */
1375 if (!rta_mode && !pl_mode && !jitter_mode && !score_mode && !mos_mode && !order_mode) {
1376 rta_mode = true;
1377 pl_mode = true;
1163 } 1378 }
1164 else if(!status && (pl >= warn.pl || rta >= warn.rta)) { 1379
1165 status = STATE_WARNING; 1380 /* Check which mode is on and do the warn / Crit stuff */
1166 hosts_warn++; 1381 if (rta_mode) {
1382 if(rta >= crit.rta) {
1383 this_status = STATE_CRITICAL;
1384 status = STATE_CRITICAL;
1385 host->rta_status=STATE_CRITICAL;
1386 } else if(status!=STATE_CRITICAL && (rta >= warn.rta)) {
1387 this_status = (this_status <= STATE_WARNING ? STATE_WARNING : this_status);
1388 status = STATE_WARNING;
1389 host->rta_status=STATE_WARNING;
1390 }
1391 }
1392
1393 if (pl_mode) {
1394 if(pl >= crit.pl) {
1395 this_status = STATE_CRITICAL;
1396 status = STATE_CRITICAL;
1397 host->pl_status=STATE_CRITICAL;
1398 } else if(status!=STATE_CRITICAL && (pl >= warn.pl)) {
1399 this_status = (this_status <= STATE_WARNING ? STATE_WARNING : this_status);
1400 status = STATE_WARNING;
1401 host->pl_status=STATE_WARNING;
1402 }
1403 }
1404
1405 if (jitter_mode) {
1406 if(host->jitter >= crit.jitter) {
1407 this_status = STATE_CRITICAL;
1408 status = STATE_CRITICAL;
1409 host->jitter_status=STATE_CRITICAL;
1410 } else if(status!=STATE_CRITICAL && (host->jitter >= warn.jitter)) {
1411 this_status = (this_status <= STATE_WARNING ? STATE_WARNING : this_status);
1412 status = STATE_WARNING;
1413 host->jitter_status=STATE_WARNING;
1414 }
1415 }
1416
1417 if (mos_mode) {
1418 if(host->mos <= crit.mos) {
1419 this_status = STATE_CRITICAL;
1420 status = STATE_CRITICAL;
1421 host->mos_status=STATE_CRITICAL;
1422 } else if(status!=STATE_CRITICAL && (host->mos <= warn.mos)) {
1423 this_status = (this_status <= STATE_WARNING ? STATE_WARNING : this_status);
1424 status = STATE_WARNING;
1425 host->mos_status=STATE_WARNING;
1426 }
1427 }
1428
1429 if (score_mode) {
1430 if(host->score <= crit.score) {
1431 this_status = STATE_CRITICAL;
1432 status = STATE_CRITICAL;
1433 host->score_status=STATE_CRITICAL;
1434 } else if(status!=STATE_CRITICAL && (host->score <= warn.score)) {
1435 this_status = (this_status <= STATE_WARNING ? STATE_WARNING : this_status);
1436 status = STATE_WARNING;
1437 host->score_status=STATE_WARNING;
1438 }
1167 } 1439 }
1168 else { 1440
1441 if (this_status == STATE_WARNING) {
1442 hosts_warn++;
1443 } else if (this_status == STATE_OK) {
1169 hosts_ok++; 1444 hosts_ok++;
1170 } 1445 }
1171 1446
1172 host = host->next; 1447 host = host->next;
1173 } 1448 }
1449
1450
1174 /* this is inevitable */ 1451 /* this is inevitable */
1175 if(!targets_alive) status = STATE_CRITICAL; 1452 if(!targets_alive) status = STATE_CRITICAL;
1176 if(min_hosts_alive > -1) { 1453 if(min_hosts_alive > -1) {
@@ -1181,6 +1458,7 @@ finish(int sig)
1181 1458
1182 host = list; 1459 host = list;
1183 while(host) { 1460 while(host) {
1461
1184 if(debug) puts(""); 1462 if(debug) puts("");
1185 if(i) { 1463 if(i) {
1186 if(i < targets) printf(" :: "); 1464 if(i < targets) printf(" :: ");
@@ -1189,6 +1467,8 @@ finish(int sig)
1189 i++; 1467 i++;
1190 if(!host->icmp_recv) { 1468 if(!host->icmp_recv) {
1191 status = STATE_CRITICAL; 1469 status = STATE_CRITICAL;
1470 host->rtmin=0;
1471 host->jitter_min=0;
1192 if(host->flags & FLAG_LOST_CAUSE) { 1472 if(host->flags & FLAG_LOST_CAUSE) {
1193 char address[INET6_ADDRSTRLEN]; 1473 char address[INET6_ADDRSTRLEN];
1194 parse_address(&host->error_addr, address, sizeof(address)); 1474 parse_address(&host->error_addr, address, sizeof(address));
@@ -1197,31 +1477,117 @@ finish(int sig)
1197 get_icmp_error_msg(host->icmp_type, host->icmp_code), 1477 get_icmp_error_msg(host->icmp_type, host->icmp_code),
1198 address, 1478 address,
1199 100); 1479 100);
1200 } 1480 } else { /* not marked as lost cause, so we have no flags for it */
1201 else { /* not marked as lost cause, so we have no flags for it */
1202 printf("%s: rta nan, lost 100%%", host->name); 1481 printf("%s: rta nan, lost 100%%", host->name);
1203 } 1482 }
1483 } else { /* !icmp_recv */
1484 printf("%s", host->name);
1485 /* rta text output */
1486 if (rta_mode) {
1487 if (status == STATE_OK)
1488 printf(" rta %0.3fms", host->rta / 1000);
1489 else if (status==STATE_WARNING && host->rta_status==status)
1490 printf(" rta %0.3fms > %0.3fms", (float)host->rta / 1000, (float)warn.rta/1000);
1491 else if (status==STATE_CRITICAL && host->rta_status==status)
1492 printf(" rta %0.3fms > %0.3fms", (float)host->rta / 1000, (float)crit.rta/1000);
1493 }
1494 /* pl text output */
1495 if (pl_mode) {
1496 if (status == STATE_OK)
1497 printf(" lost %u%%", host->pl);
1498 else if (status==STATE_WARNING && host->pl_status==status)
1499 printf(" lost %u%% > %u%%", host->pl, warn.pl);
1500 else if (status==STATE_CRITICAL && host->pl_status==status)
1501 printf(" lost %u%% > %u%%", host->pl, crit.pl);
1502 }
1503 /* jitter text output */
1504 if (jitter_mode) {
1505 if (status == STATE_OK)
1506 printf(" jitter %0.3fms", (float)host->jitter);
1507 else if (status==STATE_WARNING && host->jitter_status==status)
1508 printf(" jitter %0.3fms > %0.3fms", (float)host->jitter, warn.jitter);
1509 else if (status==STATE_CRITICAL && host->jitter_status==status)
1510 printf(" jitter %0.3fms > %0.3fms", (float)host->jitter, crit.jitter);
1511 }
1512 /* mos text output */
1513 if (mos_mode) {
1514 if (status == STATE_OK)
1515 printf(" MOS %0.1f", (float)host->mos);
1516 else if (status==STATE_WARNING && host->mos_status==status)
1517 printf(" MOS %0.1f < %0.1f", (float)host->mos, (float)warn.mos);
1518 else if (status==STATE_CRITICAL && host->mos_status==status)
1519 printf(" MOS %0.1f < %0.1f", (float)host->mos, (float)crit.mos);
1520 }
1521 /* score text output */
1522 if (score_mode) {
1523 if (status == STATE_OK)
1524 printf(" Score %u", (int)host->score);
1525 else if (status==STATE_WARNING && host->score_status==status )
1526 printf(" Score %u < %u", (int)host->score, (int)warn.score);
1527 else if (status==STATE_CRITICAL && host->score_status==status )
1528 printf(" Score %u < %u", (int)host->score, (int)crit.score);
1529 }
1530 /* order statis text output */
1531 if (order_mode) {
1532 if (status == STATE_OK)
1533 printf(" Packets in order");
1534 else if (status==STATE_CRITICAL && host->order_status==status)
1535 printf(" Packets out of order");
1536 }
1204 } 1537 }
1205 else { /* !icmp_recv */
1206 printf("%s: rta %0.3fms, lost %u%%",
1207 host->name, host->rta / 1000, host->pl);
1208 }
1209
1210 host = host->next; 1538 host = host->next;
1211 } 1539 }
1212 1540
1213 /* iterate once more for pretty perfparse output */ 1541 /* iterate once more for pretty perfparse output */
1214 printf("|"); 1542 if (!(!rta_mode && !pl_mode && !jitter_mode && !score_mode && !mos_mode && order_mode)) {
1543 printf("|");
1544 }
1215 i = 0; 1545 i = 0;
1216 host = list; 1546 host = list;
1217 while(host) { 1547 while(host) {
1218 if(debug) puts(""); 1548 if(debug) puts("");
1219 printf("%srta=%0.3fms;%0.3f;%0.3f;0; %spl=%u%%;%u;%u;; %srtmax=%0.3fms;;;; %srtmin=%0.3fms;;;; ", 1549
1550 if (rta_mode && host->pl<100) {
1551 printf("%srta=%0.3fms;%0.3f;%0.3f;0; %srtmax=%0.3fms;;;; %srtmin=%0.3fms;;;; ",
1220 (targets > 1) ? host->name : "", 1552 (targets > 1) ? host->name : "",
1221 host->rta / 1000, (float)warn.rta / 1000, (float)crit.rta / 1000, 1553 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, 1554 (targets > 1) ? host->name : "", (float)host->rtmax / 1000,
1224 (targets > 1) ? host->name : "", (host->rtmin < INFINITY) ? (float)host->rtmin / 1000 : (float)0); 1555 (targets > 1) ? host->name : "", (host->rtmin < INFINITY) ? (float)host->rtmin / 1000 : (float)0);
1556 }
1557
1558 if (pl_mode) {
1559 printf("%spl=%u%%;%u;%u;0;100 ", (targets > 1) ? host->name : "", host->pl, warn.pl, crit.pl);
1560 }
1561
1562 if (jitter_mode && host->pl<100) {
1563 printf("%sjitter_avg=%0.3fms;%0.3f;%0.3f;0; %sjitter_max=%0.3fms;;;; %sjitter_min=%0.3fms;;;; ",
1564 (targets > 1) ? host->name : "",
1565 (float)host->jitter,
1566 (float)warn.jitter,
1567 (float)crit.jitter,
1568 (targets > 1) ? host->name : "",
1569 (float)host->jitter_max / 1000, (targets > 1) ? host->name : "",
1570 (float)host->jitter_min / 1000
1571 );
1572 }
1573
1574 if (mos_mode && host->pl<100) {
1575 printf("%smos=%0.1f;%0.1f;%0.1f;0;5 ",
1576 (targets > 1) ? host->name : "",
1577 (float)host->mos,
1578 (float)warn.mos,
1579 (float)crit.mos
1580 );
1581 }
1582
1583 if (score_mode && host->pl<100) {
1584 printf("%sscore=%u;%u;%u;0;100 ",
1585 (targets > 1) ? host->name : "",
1586 (int)host->score,
1587 (int)warn.score,
1588 (int)crit.score
1589 );
1590 }
1225 1591
1226 host = host->next; 1592 host = host->next;
1227 } 1593 }
@@ -1312,6 +1678,7 @@ add_target_ip(char *arg, struct sockaddr_storage *in)
1312 /* set the values. use calling name for output */ 1678 /* set the values. use calling name for output */
1313 host->name = strdup(arg); 1679 host->name = strdup(arg);
1314 1680
1681
1315 /* fill out the sockaddr_storage struct */ 1682 /* fill out the sockaddr_storage struct */
1316 if(address_family == AF_INET) { 1683 if(address_family == AF_INET) {
1317 host_sin = (struct sockaddr_in *)&host->saddr_in; 1684 host_sin = (struct sockaddr_in *)&host->saddr_in;
@@ -1324,7 +1691,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); 1691 memcpy(host_sin6->sin6_addr.s6_addr, sin6->sin6_addr.s6_addr, sizeof host_sin6->sin6_addr.s6_addr);
1325 } 1692 }
1326 1693
1694 /* fill out the sockaddr_in struct */
1327 host->rtmin = INFINITY; 1695 host->rtmin = INFINITY;
1696 host->rtmax = 0;
1697 host->jitter=0;
1698 host->jitter_max=0;
1699 host->jitter_min=INFINITY;
1700 host->last_tdiff=0;
1701 host->order_status=STATE_OK;
1702 host->last_icmp_seq=0;
1703 host->rta_status=0;
1704 host->pl_status=0;
1705 host->jitter_status=0;
1706 host->mos_status=0;
1707 host->score_status=0;
1708 host->pl_status=0;
1709
1328 1710
1329 if(!list) list = cursor = host; 1711 if(!list) list = cursor = host;
1330 else cursor->next = host; 1712 else cursor->next = host;
@@ -1408,7 +1790,7 @@ add_target(char *arg)
1408 } 1790 }
1409 break; 1791 break;
1410 } 1792 }
1411 freeaddrinfo(res); 1793 freeaddrinfo(res);
1412 1794
1413 return 0; 1795 return 0;
1414} 1796}
@@ -1472,7 +1854,7 @@ get_timevar(const char *str)
1472 1854
1473 /* unit might be given as ms|m (millisec), 1855 /* unit might be given as ms|m (millisec),
1474 * us|u (microsec) or just plain s, for seconds */ 1856 * us|u (microsec) or just plain s, for seconds */
1475 u = p = '\0'; 1857 p = '\0';
1476 u = str[len - 1]; 1858 u = str[len - 1];
1477 if(len >= 2 && !isdigit((int)str[len - 2])) p = str[len - 2]; 1859 if(len >= 2 && !isdigit((int)str[len - 2])) p = str[len - 2];
1478 if(p && u == 's') u = p; 1860 if(p && u == 's') u = p;
@@ -1530,6 +1912,81 @@ get_threshold(char *str, threshold *th)
1530 return 0; 1912 return 0;
1531} 1913}
1532 1914
1915/*
1916 * This functions receives a pointer to a string which should contain a threshold for the
1917 * rta, packet_loss, jitter, mos or score mode in the form number,number[m|%]* assigns the
1918 * parsed number to the corresponding threshold variable.
1919 * @param[in,out] str String containing the given threshold values
1920 * @param[in] length strlen(str)
1921 * @param[out] warn Pointer to the warn threshold struct to which the values should be assigned
1922 * @param[out] crit Pointer to the crit threshold struct to which the values should be assigned
1923 * @param[in] mode Determines whether this a threshold for rta, packet_loss, jitter, mos or score (exclusively)
1924 */
1925static bool get_threshold2(char *str, size_t length, threshold *warn, threshold *crit, threshold_mode mode) {
1926 if (!str || !length || !warn || !crit) return false;
1927
1928
1929 // p points to the last char in str
1930 char *p = &str[length - 1];
1931
1932 // first_iteration is bof-stop on stupid libc's
1933 bool first_iteration = true;
1934
1935 while(p != &str[0]) {
1936 if( (*p == 'm') || (*p == '%') ) {
1937 *p = '\0';
1938 } else if(*p == ',' && !first_iteration) {
1939 *p = '\0'; /* reset it so get_timevar(str) works nicely later */
1940
1941 char *start_of_value = p + 1;
1942
1943 if (!parse_threshold2_helper(start_of_value, strlen(start_of_value), crit, mode)){
1944 return false;
1945 }
1946
1947 }
1948 first_iteration = false;
1949 p--;
1950 }
1951
1952 return parse_threshold2_helper(p, strlen(p), warn, mode);
1953}
1954
1955static bool parse_threshold2_helper(char *s, size_t length, threshold *thr, threshold_mode mode) {
1956 char *resultChecker = {0};
1957
1958 switch (mode) {
1959 case const_rta_mode:
1960 thr->rta = strtod(s, &resultChecker) * 1000;
1961 break;
1962 case const_packet_loss_mode:
1963 thr->pl = (unsigned char)strtoul(s, &resultChecker, 0);
1964 break;
1965 case const_jitter_mode:
1966 thr->jitter = strtod(s, &resultChecker);
1967
1968 break;
1969 case const_mos_mode:
1970 thr->mos = strtod(s, &resultChecker);
1971 break;
1972 case const_score_mode:
1973 thr->score = strtod(s, &resultChecker);
1974 break;
1975 }
1976
1977 if (resultChecker == s) {
1978 // Failed to parse
1979 return false;
1980 }
1981
1982 if (resultChecker != (s + length)) {
1983 // Trailing symbols
1984 return false;
1985 }
1986
1987 return true;
1988}
1989
1533unsigned short 1990unsigned short
1534icmp_checksum(uint16_t *p, size_t n) 1991icmp_checksum(uint16_t *p, size_t n)
1535{ 1992{
@@ -1555,74 +2012,91 @@ icmp_checksum(uint16_t *p, size_t n)
1555void 2012void
1556print_help(void) 2013print_help(void)
1557{ 2014{
1558 2015 /*print_revision (progname);*/ /* FIXME: Why? */
1559 /*print_revision (progname);*/ /* FIXME: Why? */ 2016 printf ("Copyright (c) 2005 Andreas Ericsson <ae@op5.se>\n");
1560 2017
1561 printf ("Copyright (c) 2005 Andreas Ericsson <ae@op5.se>\n"); 2018 printf (COPYRIGHT, copyright, email);
1562 printf (COPYRIGHT, copyright, email); 2019
1563 2020 printf ("\n\n");
1564 printf ("\n\n"); 2021
1565 2022 print_usage ();
1566 print_usage (); 2023
1567 2024 printf (UT_HELP_VRSN);
1568 printf (UT_HELP_VRSN); 2025 printf (UT_EXTRA_OPTS);
1569 printf (UT_EXTRA_OPTS); 2026
1570 2027 printf (" %s\n", "-H");
1571 printf (" %s\n", "-H"); 2028 printf (" %s\n", _("specify a target"));
1572 printf (" %s\n", _("specify a target")); 2029 printf (" %s\n", "[-4|-6]");
1573 printf (" %s\n", "[-4|-6]"); 2030 printf (" %s\n", _("Use IPv4 (default) or IPv6 to communicate with the targets"));
1574 printf (" %s\n", _("Use IPv4 (default) or IPv6 to communicate with the targets")); 2031 printf (" %s\n", "-w");
1575 printf (" %s\n", "-w"); 2032 printf (" %s", _("warning threshold (currently "));
1576 printf (" %s", _("warning threshold (currently ")); 2033 printf ("%0.3fms,%u%%)\n", (float)warn.rta / 1000, warn.pl);
1577 printf ("%0.3fms,%u%%)\n", (float)warn.rta / 1000, warn.pl); 2034 printf (" %s\n", "-c");
1578 printf (" %s\n", "-c"); 2035 printf (" %s", _("critical threshold (currently "));
1579 printf (" %s", _("critical threshold (currently ")); 2036 printf ("%0.3fms,%u%%)\n", (float)crit.rta / 1000, crit.pl);
1580 printf ("%0.3fms,%u%%)\n", (float)crit.rta / 1000, crit.pl); 2037
1581 printf (" %s\n", "-s"); 2038 printf (" %s\n", "-R");
1582 printf (" %s\n", _("specify a source IP address or device name")); 2039 printf (" %s\n", _("RTA, round trip average, mode warning,critical, ex. 100ms,200ms unit in ms"));
1583 printf (" %s\n", "-n"); 2040 printf (" %s\n", "-P");
1584 printf (" %s", _("number of packets to send (currently ")); 2041 printf (" %s\n", _("packet loss mode, ex. 40%,50% , unit in %"));
1585 printf ("%u)\n",packets); 2042 printf (" %s\n", "-J");
1586 printf (" %s\n", "-i"); 2043 printf (" %s\n", _("jitter mode warning,critical, ex. 40.000ms,50.000ms , unit in ms "));
1587 printf (" %s", _("max packet interval (currently ")); 2044 printf (" %s\n", "-M");
1588 printf ("%0.3fms)\n",(float)pkt_interval / 1000); 2045 printf (" %s\n", _("MOS mode, between 0 and 4.4 warning,critical, ex. 3.5,3.0"));
1589 printf (" %s\n", "-I"); 2046 printf (" %s\n", "-S");
1590 printf (" %s", _("max target interval (currently ")); 2047 printf (" %s\n", _("score mode, max value 100 warning,critical, ex. 80,70 "));
1591 printf ("%0.3fms)\n", (float)target_interval / 1000); 2048 printf (" %s\n", "-O");
1592 printf (" %s\n", "-m"); 2049 printf (" %s\n", _("detect out of order ICMP packts "));
1593 printf (" %s",_("number of alive hosts required for success")); 2050 printf (" %s\n", "-H");
1594 printf ("\n"); 2051 printf (" %s\n", _("specify a target"));
1595 printf (" %s\n", "-l"); 2052 printf (" %s\n", "-s");
1596 printf (" %s", _("TTL on outgoing packets (currently ")); 2053 printf (" %s\n", _("specify a source IP address or device name"));
1597 printf ("%u)\n", ttl); 2054 printf (" %s\n", "-n");
1598 printf (" %s\n", "-t"); 2055 printf (" %s", _("number of packets to send (currently "));
1599 printf (" %s",_("timeout value (seconds, currently ")); 2056 printf ("%u)\n",packets);
1600 printf ("%u)\n", timeout); 2057 printf (" %s\n", "-p");
1601 printf (" %s\n", "-b"); 2058 printf (" %s", _("number of packets to send (currently "));
1602 printf (" %s\n", _("Number of icmp data bytes to send")); 2059 printf ("%u)\n",packets);
1603 printf (" %s %u + %d)\n", _("Packet size will be data bytes + icmp header (currently"),icmp_data_size, ICMP_MINLEN); 2060 printf (" %s\n", "-i");
1604 printf (" %s\n", "-v"); 2061 printf (" %s", _("max packet interval (currently "));
1605 printf (" %s\n", _("verbose")); 2062 printf ("%0.3fms)\n",(float)pkt_interval / 1000);
1606 2063 printf (" %s\n", "-I");
1607 printf ("\n"); 2064 printf (" %s", _("max target interval (currently "));
1608 printf ("%s\n", _("Notes:")); 2065 printf ("%0.3fms)\n", (float)target_interval / 1000);
1609 printf (" %s\n", _("The -H switch is optional. Naming a host (or several) to check is not.")); 2066 printf (" %s\n", "-m");
1610 printf ("\n"); 2067 printf (" %s",_("number of alive hosts required for success"));
1611 printf (" %s\n", _("Threshold format for -w and -c is 200.25,60% for 200.25 msec RTA and 60%")); 2068 printf ("\n");
1612 printf (" %s\n", _("packet loss. The default values should work well for most users.")); 2069 printf (" %s\n", "-l");
1613 printf (" %s\n", _("You can specify different RTA factors using the standardized abbreviations")); 2070 printf (" %s", _("TTL on outgoing packets (currently "));
1614 printf (" %s\n", _("us (microseconds), ms (milliseconds, default) or just plain s for seconds.")); 2071 printf ("%u)\n", ttl);
1615/* -d not yet implemented */ 2072 printf (" %s\n", "-t");
1616/* printf ("%s\n", _("Threshold format for -d is warn,crit. 12,14 means WARNING if >= 12 hops")); 2073 printf (" %s",_("timeout value (seconds, currently "));
1617 printf ("%s\n", _("are spent and CRITICAL if >= 14 hops are spent.")); 2074 printf ("%u)\n", timeout);
1618 printf ("%s\n\n", _("NOTE: Some systems decrease TTL when forming ICMP_ECHOREPLY, others do not."));*/ 2075 printf (" %s\n", "-b");
1619 printf ("\n"); 2076 printf (" %s\n", _("Number of icmp data bytes to send"));
1620 printf (" %s\n", _("The -v switch can be specified several times for increased verbosity.")); 2077 printf (" %s %u + %d)\n", _("Packet size will be data bytes + icmp header (currently"),icmp_data_size, ICMP_MINLEN);
1621/* printf ("%s\n", _("Long options are currently unsupported.")); 2078 printf (" %s\n", "-v");
1622 printf ("%s\n", _("Options marked with * require an argument")); 2079 printf (" %s\n", _("verbose"));
1623*/ 2080 printf ("\n");
1624 2081 printf ("%s\n", _("Notes:"));
1625 printf (UT_SUPPORT); 2082 printf (" %s\n", _("If none of R,P,J,M,S or O is specified, default behavior is -R -P"));
2083 printf (" %s\n", _("The -H switch is optional. Naming a host (or several) to check is not."));
2084 printf ("\n");
2085 printf (" %s\n", _("Threshold format for -w and -c is 200.25,60% for 200.25 msec RTA and 60%"));
2086 printf (" %s\n", _("packet loss. The default values should work well for most users."));
2087 printf (" %s\n", _("You can specify different RTA factors using the standardized abbreviations"));
2088 printf (" %s\n", _("us (microseconds), ms (milliseconds, default) or just plain s for seconds."));
2089 /* -d not yet implemented */
2090 /* printf ("%s\n", _("Threshold format for -d is warn,crit. 12,14 means WARNING if >= 12 hops"));
2091 printf ("%s\n", _("are spent and CRITICAL if >= 14 hops are spent."));
2092 printf ("%s\n\n", _("NOTE: Some systems decrease TTL when forming ICMP_ECHOREPLY, others do not."));*/
2093 printf ("\n");
2094 printf (" %s\n", _("The -v switch can be specified several times for increased verbosity."));
2095 /* printf ("%s\n", _("Long options are currently unsupported."));
2096 printf ("%s\n", _("Options marked with * require an argument"));
2097 */
2098
2099 printf (UT_SUPPORT);
1626} 2100}
1627 2101
1628 2102
@@ -1630,6 +2104,6 @@ print_help(void)
1630void 2104void
1631print_usage (void) 2105print_usage (void)
1632{ 2106{
1633 printf ("%s\n", _("Usage:")); 2107 printf ("%s\n", _("Usage:"));
1634 printf(" %s [options] [-H] host1 host2 hostN\n", progname); 2108 printf(" %s [options] [-H] host1 host2 hostN\n", progname);
1635} 2109}
diff --git a/plugins-root/t/check_icmp.t b/plugins-root/t/check_icmp.t
index 96addd3..4f9db86 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/plugins-scripts/check_disk_smb.pl b/plugins-scripts/check_disk_smb.pl
index f4d33a7..eda8dd4 100644
--- a/plugins-scripts/check_disk_smb.pl
+++ b/plugins-scripts/check_disk_smb.pl
@@ -226,7 +226,8 @@ if (/\s*(\d*) blocks of size (\d*)\. (\d*) blocks available/) {
226 my ($total_bytes) = $1 * $2; 226 my ($total_bytes) = $1 * $2;
227 my ($occupied_bytes) = $1 * $2 - $avail_bytes; 227 my ($occupied_bytes) = $1 * $2 - $avail_bytes;
228 my ($avail) = $avail_bytes/1024; 228 my ($avail) = $avail_bytes/1024;
229 my ($capper) = int(($3/$1)*100); 229 my ($capper);
230 if ($1!=0) { $capper = int(($3/$1)*100) } else { $capper=100 };
230 my ($mountpt) = "\\\\$host\\$share"; 231 my ($mountpt) = "\\\\$host\\$share";
231 232
232 # TODO : why is the kB the standard unit for args ? 233 # TODO : why is the kB the standard unit for args ?
diff --git a/plugins-scripts/check_ircd.pl b/plugins-scripts/check_ircd.pl
index 84f2022..4822fe6 100755
--- a/plugins-scripts/check_ircd.pl
+++ b/plugins-scripts/check_ircd.pl
@@ -146,7 +146,6 @@ sub bindRemote ($$)
146{ 146{
147 my ($in_remotehost, $in_remoteport) = @_; 147 my ($in_remotehost, $in_remoteport) = @_;
148 my $proto = getprotobyname('tcp'); 148 my $proto = getprotobyname('tcp');
149 my $sockaddr;
150 my $that; 149 my $that;
151 my ($name, $aliases,$type,$len,$thataddr) = gethostbyname($in_remotehost); 150 my ($name, $aliases,$type,$len,$thataddr) = gethostbyname($in_remotehost);
152 151
@@ -154,8 +153,7 @@ sub bindRemote ($$)
154 print "IRCD UNKNOWN: Could not start socket ($!)\n"; 153 print "IRCD UNKNOWN: Could not start socket ($!)\n";
155 exit $ERRORS{"UNKNOWN"}; 154 exit $ERRORS{"UNKNOWN"};
156 } 155 }
157 $sockaddr = 'S n a4 x8'; 156 $that = pack_sockaddr_in ($in_remoteport, $thataddr);
158 $that = pack($sockaddr, AF_INET, $in_remoteport, $thataddr);
159 if (!connect(ClientSocket, $that)) { 157 if (!connect(ClientSocket, $that)) {
160 print "IRCD UNKNOWN: Could not connect socket ($!)\n"; 158 print "IRCD UNKNOWN: Could not connect socket ($!)\n";
161 exit $ERRORS{"UNKNOWN"}; 159 exit $ERRORS{"UNKNOWN"};
diff --git a/plugins/check_disk.c b/plugins/check_disk.c
index 05e5502..2f066c7 100644
--- a/plugins/check_disk.c
+++ b/plugins/check_disk.c
@@ -93,11 +93,11 @@ static int stat_remote_fs = 0;
93 93
94/* Linked list of filesystem types to omit. 94/* Linked list of filesystem types to omit.
95 If the list is empty, don't exclude any types. */ 95 If the list is empty, don't exclude any types. */
96static struct name_list *fs_exclude_list; 96static struct regex_list *fs_exclude_list = NULL;
97 97
98/* Linked list of filesystem types to check. 98/* Linked list of filesystem types to check.
99 If the list is empty, include all types. */ 99 If the list is empty, include all types. */
100static struct name_list *fs_include_list; 100static struct regex_list *fs_include_list;
101 101
102static struct name_list *dp_exclude_list; 102static struct name_list *dp_exclude_list;
103 103
@@ -300,7 +300,7 @@ main (int argc, char **argv)
300 } else if (me->me_dummy && !show_all_fs) { 300 } else if (me->me_dummy && !show_all_fs) {
301 continue; 301 continue;
302 /* Skip excluded fstypes */ 302 /* Skip excluded fstypes */
303 } else if (fs_exclude_list && np_find_name (fs_exclude_list, me->me_type)) { 303 } else if (fs_exclude_list && np_find_regmatch (fs_exclude_list, me->me_type)) {
304 continue; 304 continue;
305 /* Skip excluded fs's */ 305 /* Skip excluded fs's */
306 } else if (dp_exclude_list && 306 } else if (dp_exclude_list &&
@@ -308,7 +308,7 @@ main (int argc, char **argv)
308 np_find_name (dp_exclude_list, me->me_mountdir))) { 308 np_find_name (dp_exclude_list, me->me_mountdir))) {
309 continue; 309 continue;
310 /* Skip not included fstypes */ 310 /* Skip not included fstypes */
311 } else if (fs_include_list && !np_find_name (fs_include_list, me->me_type)) { 311 } else if (fs_include_list && !np_find_regmatch(fs_include_list, me->me_type)) {
312 continue; 312 continue;
313 } 313 }
314 } 314 }
@@ -543,7 +543,7 @@ process_arguments (int argc, char **argv)
543 if (argc < 2) 543 if (argc < 2)
544 return ERROR; 544 return ERROR;
545 545
546 np_add_name(&fs_exclude_list, "iso9660"); 546 np_add_regex(&fs_exclude_list, "iso9660", REG_EXTENDED);
547 547
548 for (c = 1; c < argc; c++) 548 for (c = 1; c < argc; c++)
549 if (strcmp ("-to", argv[c]) == 0) 549 if (strcmp ("-to", argv[c]) == 0)
@@ -716,10 +716,18 @@ process_arguments (int argc, char **argv)
716 np_add_name(&dp_exclude_list, optarg); 716 np_add_name(&dp_exclude_list, optarg);
717 break; 717 break;
718 case 'X': /* exclude file system type */ 718 case 'X': /* exclude file system type */
719 np_add_name(&fs_exclude_list, optarg); 719 err = np_add_regex(&fs_exclude_list, optarg, REG_EXTENDED);
720 if (err != 0) {
721 regerror (err, &fs_exclude_list->regex, errbuf, MAX_INPUT_BUFFER);
722 die (STATE_UNKNOWN, "DISK %s: %s - %s\n",_("UNKNOWN"), _("Could not compile regular expression"), errbuf);
723 }
720 break; 724 break;
721 case 'N': /* include file system type */ 725 case 'N': /* include file system type */
722 np_add_name(&fs_include_list, optarg); 726 err = np_add_regex(&fs_include_list, optarg, REG_EXTENDED);
727 if (err != 0) {
728 regerror (err, &fs_exclude_list->regex, errbuf, MAX_INPUT_BUFFER);
729 die (STATE_UNKNOWN, "DISK %s: %s - %s\n",_("UNKNOWN"), _("Could not compile regular expression"), errbuf);
730 }
723 break; 731 break;
724 case 'v': /* verbose */ 732 case 'v': /* verbose */
725 verbose++; 733 verbose++;
@@ -798,7 +806,7 @@ process_arguments (int argc, char **argv)
798 crit_freespace_percent || warn_usedspace_units || crit_usedspace_units || 806 crit_freespace_percent || warn_usedspace_units || crit_usedspace_units ||
799 warn_usedspace_percent || crit_usedspace_percent || warn_usedinodes_percent || 807 warn_usedspace_percent || crit_usedspace_percent || warn_usedinodes_percent ||
800 crit_usedinodes_percent || warn_freeinodes_percent || crit_freeinodes_percent )) { 808 crit_usedinodes_percent || warn_freeinodes_percent || crit_freeinodes_percent )) {
801 die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set a threshold value before using -r/-R\n")); 809 die (STATE_UNKNOWN, "DISK %s: %s", _("UNKNOWN"), _("Must set a threshold value before using -r/-R/-A (--ereg-path/--eregi-path/--all)\n"));
802 } 810 }
803 811
804 err = regcomp(&re, optarg, cflags); 812 err = regcomp(&re, optarg, cflags);
@@ -1003,18 +1011,26 @@ print_help (void)
1003 printf (" %s\n", "-u, --units=STRING"); 1011 printf (" %s\n", "-u, --units=STRING");
1004 printf (" %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)")); 1012 printf (" %s\n", _("Choose bytes, kB, MB, GB, TB (default: MB)"));
1005 printf (UT_VERBOSE); 1013 printf (UT_VERBOSE);
1006 printf (" %s\n", "-X, --exclude-type=TYPE"); 1014 printf (" %s\n", "-X, --exclude-type=TYPE_REGEX");
1007 printf (" %s\n", _("Ignore all filesystems of indicated type (may be repeated)")); 1015 printf (" %s\n", _("Ignore all filesystems of types matching given regex(7) (may be repeated)"));
1008 printf (" %s\n", "-N, --include-type=TYPE"); 1016 printf (" %s\n", "-N, --include-type=TYPE_REGEX");
1009 printf (" %s\n", _("Check only filesystems of indicated type (may be repeated)")); 1017 printf (" %s\n", _("Check only filesystems where the type matches this given regex(7) (may be repeated)"));
1018
1019 printf ("\n");
1020 printf ("%s\n", _("General usage hints:"));
1021 printf (" %s\n", _("- Arguments are positional! \"-w 5 -c 1 -p /foo -w6 -c2 -p /bar\" is not the same as"));
1022 printf (" %s\n", _("\"-w 5 -c 1 -p /bar w6 -c2 -p /foo\"."));
1023 printf (" %s\n", _("- The syntax is broadly: \"{thresholds a} {paths a} -C {thresholds b} {thresholds b} ...\""));
1024
1025
1010 1026
1011 printf ("\n"); 1027 printf ("\n");
1012 printf ("%s\n", _("Examples:")); 1028 printf ("%s\n", _("Examples:"));
1013 printf (" %s\n", "check_disk -w 10% -c 5% -p /tmp -p /var -C -w 100000 -c 50000 -p /"); 1029 printf (" %s\n", "check_disk -w 10% -c 5% -p /tmp -p /var -C -w 100000 -c 50000 -p /");
1014 printf (" %s\n", _("Checks /tmp and /var at 10% and 5%, and / at 100MB and 50MB")); 1030 printf (" %s\n\n", _("Checks /tmp and /var at 10% and 5%, and / at 100MB and 50MB"));
1015 printf (" %s\n", "check_disk -w 100 -c 50 -C -w 1000 -c 500 -g sidDATA -r '^/oracle/SID/data.*$'"); 1031 printf (" %s\n", "check_disk -w 100 -c 50 -C -w 1000 -c 500 -g sidDATA -r '^/oracle/SID/data.*$'");
1016 printf (" %s\n", _("Checks all filesystems not matching -r at 100M and 50M. The fs matching the -r regex")); 1032 printf (" %s\n", _("Checks all filesystems not matching -r at 100M and 50M. The fs matching the -r regex"));
1017 printf (" %s\n", _("are grouped which means the freespace thresholds are applied to all disks together")); 1033 printf (" %s\n\n", _("are grouped which means the freespace thresholds are applied to all disks together"));
1018 printf (" %s\n", "check_disk -w 100 -c 50 -C -w 1000 -c 500 -p /foo -C -w 5% -c 3% -p /bar"); 1034 printf (" %s\n", "check_disk -w 100 -c 50 -C -w 1000 -c 500 -p /foo -C -w 5% -c 3% -p /bar");
1019 printf (" %s\n", _("Checks /foo for 1000M/500M and /bar for 5/3%. All remaining volumes use 100M/50M")); 1035 printf (" %s\n", _("Checks /foo for 1000M/500M and /bar for 5/3%. All remaining volumes use 100M/50M"));
1020 1036
@@ -1027,9 +1043,9 @@ void
1027print_usage (void) 1043print_usage (void)
1028{ 1044{
1029 printf ("%s\n", _("Usage:")); 1045 printf ("%s\n", _("Usage:"));
1030 printf (" %s {-w absolute_limit |-w percentage_limit% | -W inode_percentage_limit } {-c absolute_limit|-c percentage_limit% | -K inode_percentage_limit } {-p path | -x device}\n", progname); 1046 printf (" %s {-w absolute_limit |-w percentage_limit%% | -W inode_percentage_limit } {-c absolute_limit|-c percentage_limit%% | -K inode_percentage_limit } {-p path | -x device}\n", progname);
1031 printf ("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] [-R path ] [-r path ]\n"); 1047 printf ("[-C] [-E] [-e] [-f] [-g group ] [-k] [-l] [-M] [-m] [-R path ] [-r path ]\n");
1032 printf ("[-t timeout] [-u unit] [-v] [-X type] [-N type]\n"); 1048 printf ("[-t timeout] [-u unit] [-v] [-X type_regex] [-N type]\n");
1033} 1049}
1034 1050
1035bool 1051bool
diff --git a/plugins/check_mysql.c b/plugins/check_mysql.c
index 91e150f..7d85554 100644
--- a/plugins/check_mysql.c
+++ b/plugins/check_mysql.c
@@ -34,7 +34,7 @@ const char *progname = "check_mysql";
34const char *copyright = "1999-2011"; 34const char *copyright = "1999-2011";
35const char *email = "devel@monitoring-plugins.org"; 35const char *email = "devel@monitoring-plugins.org";
36 36
37#define SLAVERESULTSIZE 70 37#define SLAVERESULTSIZE 96
38 38
39#include "common.h" 39#include "common.h"
40#include "utils.h" 40#include "utils.h"
@@ -89,6 +89,8 @@ static const char *metric_counter[LENGTH_METRIC_COUNTER] = {
89 "Uptime" 89 "Uptime"
90}; 90};
91 91
92#define MYSQLDUMP_THREADS_QUERY "SELECT COUNT(1) mysqldumpThreads FROM information_schema.processlist WHERE info LIKE 'SELECT /*!40001 SQL_NO_CACHE */%'"
93
92thresholds *my_threshold = NULL; 94thresholds *my_threshold = NULL;
93 95
94int process_arguments (int, char **); 96int process_arguments (int, char **);
@@ -108,7 +110,7 @@ main (int argc, char **argv)
108 110
109 char *result = NULL; 111 char *result = NULL;
110 char *error = NULL; 112 char *error = NULL;
111 char slaveresult[SLAVERESULTSIZE]; 113 char slaveresult[SLAVERESULTSIZE] = { 0 };
112 char* perf; 114 char* perf;
113 115
114 perf = strdup (""); 116 perf = strdup ("");
@@ -278,11 +280,30 @@ main (int argc, char **argv)
278 /* Save slave status in slaveresult */ 280 /* Save slave status in slaveresult */
279 snprintf (slaveresult, SLAVERESULTSIZE, "Slave IO: %s Slave SQL: %s Seconds Behind Master: %s", row[slave_io_field], row[slave_sql_field], seconds_behind_field!=-1?row[seconds_behind_field]:"Unknown"); 281 snprintf (slaveresult, SLAVERESULTSIZE, "Slave IO: %s Slave SQL: %s Seconds Behind Master: %s", row[slave_io_field], row[slave_sql_field], seconds_behind_field!=-1?row[seconds_behind_field]:"Unknown");
280 282
281 /* Raise critical error if SQL THREAD or IO THREAD are stopped */ 283 /* Raise critical error if SQL THREAD or IO THREAD are stopped, but only if there are no mysqldump threads running */
282 if (strcmp (row[slave_io_field], "Yes") != 0 || strcmp (row[slave_sql_field], "Yes") != 0) { 284 if (strcmp (row[slave_io_field], "Yes") != 0 || strcmp (row[slave_sql_field], "Yes") != 0) {
283 mysql_free_result (res); 285 MYSQL_RES *res_mysqldump;
284 mysql_close (&mysql); 286 MYSQL_ROW row_mysqldump;
285 die (STATE_CRITICAL, "%s\n", slaveresult); 287 unsigned int mysqldump_threads = 0;
288
289 if (mysql_query (&mysql, MYSQLDUMP_THREADS_QUERY) == 0) {
290 /* store the result */
291 if ( (res_mysqldump = mysql_store_result (&mysql)) != NULL) {
292 if (mysql_num_rows(res_mysqldump) == 1) {
293 if ( (row_mysqldump = mysql_fetch_row (res_mysqldump)) != NULL) {
294 mysqldump_threads = atoi(row_mysqldump[0]);
295 }
296 }
297 /* free the result */
298 mysql_free_result (res_mysqldump);
299 }
300 mysql_close (&mysql);
301 }
302 if (mysqldump_threads == 0) {
303 die (STATE_CRITICAL, "%s\n", slaveresult);
304 } else {
305 strncat(slaveresult, " Mysqldump: in progress", SLAVERESULTSIZE-1);
306 }
286 } 307 }
287 308
288 if (verbose >=3) { 309 if (verbose >=3) {
@@ -294,7 +315,7 @@ main (int argc, char **argv)
294 } 315 }
295 316
296 /* Check Seconds Behind against threshold */ 317 /* Check Seconds Behind against threshold */
297 if ((seconds_behind_field != -1) && (strcmp (row[seconds_behind_field], "NULL") != 0)) { 318 if ((seconds_behind_field != -1) && (row[seconds_behind_field] != NULL && strcmp (row[seconds_behind_field], "NULL") != 0)) {
298 double value = atof(row[seconds_behind_field]); 319 double value = atof(row[seconds_behind_field]);
299 int status; 320 int status;
300 321
diff --git a/plugins/check_ntp.c b/plugins/check_ntp.c
index 3614650..99537c8 100644
--- a/plugins/check_ntp.c
+++ b/plugins/check_ntp.c
@@ -486,7 +486,7 @@ double offset_request(const char *host, int *status){
486 } 486 }
487 487
488 /* cleanup */ 488 /* cleanup */
489 /* FIXME: Not closing the socket to avoid re-use of the local port 489 /* FIXME: Not closing the socket to avoid reuse of the local port
490 * which can cause old NTP packets to be read instead of NTP control 490 * which can cause old NTP packets to be read instead of NTP control
491 * packets in jitter_request(). THERE MUST BE ANOTHER WAY... 491 * packets in jitter_request(). THERE MUST BE ANOTHER WAY...
492 * for(j=0; j<num_hosts; j++){ close(socklist[j]); } */ 492 * for(j=0; j<num_hosts; j++){ close(socklist[j]); } */
diff --git a/plugins/check_snmp.c b/plugins/check_snmp.c
index 2acada2..56a586a 100644
--- a/plugins/check_snmp.c
+++ b/plugins/check_snmp.c
@@ -159,6 +159,7 @@ int perf_labels = 1;
159char* ip_version = ""; 159char* ip_version = "";
160double multiplier = 1.0; 160double multiplier = 1.0;
161char *fmtstr = ""; 161char *fmtstr = "";
162bool fmtstr_set = false;
162char buffer[DEFAULT_BUFFER_SIZE]; 163char buffer[DEFAULT_BUFFER_SIZE];
163bool ignore_mib_parsing_errors = false; 164bool ignore_mib_parsing_errors = false;
164 165
@@ -437,7 +438,8 @@ main (int argc, char **argv)
437 } 438 }
438 else if (strstr (response, "INTEGER: ")) { 439 else if (strstr (response, "INTEGER: ")) {
439 show = multiply (strstr (response, "INTEGER: ") + 9); 440 show = multiply (strstr (response, "INTEGER: ") + 9);
440 if (fmtstr != "") { 441
442 if (fmtstr_set) {
441 conv = fmtstr; 443 conv = fmtstr;
442 } 444 }
443 } 445 }
@@ -611,8 +613,9 @@ main (int argc, char **argv)
611 len = sizeof(perfstr)-strlen(perfstr)-1; 613 len = sizeof(perfstr)-strlen(perfstr)-1;
612 strncat(perfstr, show, len>ptr-show ? ptr-show : len); 614 strncat(perfstr, show, len>ptr-show ? ptr-show : len);
613 615
614 if (type) 616 if (strcmp(type, "") != 0) {
615 strncat(perfstr, type, sizeof(perfstr)-strlen(perfstr)-1); 617 strncat(perfstr, type, sizeof(perfstr)-strlen(perfstr)-1);
618 }
616 619
617 if (warning_thresholds) { 620 if (warning_thresholds) {
618 strncat(perfstr, ";", sizeof(perfstr)-strlen(perfstr)-1); 621 strncat(perfstr, ";", sizeof(perfstr)-strlen(perfstr)-1);
@@ -988,6 +991,7 @@ process_arguments (int argc, char **argv)
988 case 'f': 991 case 'f':
989 if (multiplier != 1.0) { 992 if (multiplier != 1.0) {
990 fmtstr=optarg; 993 fmtstr=optarg;
994 fmtstr_set = true;
991 } 995 }
992 break; 996 break;
993 case L_IGNORE_MIB_PARSING_ERRORS: 997 case L_IGNORE_MIB_PARSING_ERRORS:
@@ -1204,7 +1208,7 @@ multiply (char *str)
1204 if(verbose>2) 1208 if(verbose>2)
1205 printf(" multiply extracted double: %f\n", val); 1209 printf(" multiply extracted double: %f\n", val);
1206 val *= multiplier; 1210 val *= multiplier;
1207 if (fmtstr != "") { 1211 if (fmtstr_set) {
1208 conv = fmtstr; 1212 conv = fmtstr;
1209 } 1213 }
1210 if (val == (int)val) { 1214 if (val == (int)val) {
diff --git a/plugins/common.h b/plugins/common.h
index 0f08e2f..6bf4fca 100644
--- a/plugins/common.h
+++ b/plugins/common.h
@@ -225,18 +225,4 @@ enum {
225# define __attribute__(x) /* do nothing */ 225# define __attribute__(x) /* do nothing */
226#endif 226#endif
227 227
228/* Try sysconf(_SC_OPEN_MAX) first, as it can be higher than OPEN_MAX.
229 * If that fails and the macro isn't defined, we fall back to an educated
230 * guess. There's no guarantee that our guess is adequate and the program
231 * will die with SIGSEGV if it isn't and the upper boundary is breached. */
232#define DEFAULT_MAXFD 256 /* fallback value if no max open files value is set */
233#define MAXFD_LIMIT 8192 /* upper limit of open files */
234#ifdef _SC_OPEN_MAX
235static long maxfd = 0;
236#elif defined(OPEN_MAX)
237# define maxfd OPEN_MAX
238#else /* sysconf macro unavailable, so guess (may be wildly inaccurate) */
239# define maxfd DEFAULT_MAXFD
240#endif
241
242#endif /* _COMMON_H_ */ 228#endif /* _COMMON_H_ */
diff --git a/plugins/netutils.h b/plugins/netutils.h
index d7ee0dd..ea653e7 100644
--- a/plugins/netutils.h
+++ b/plugins/netutils.h
@@ -92,7 +92,7 @@ extern int econn_refuse_state;
92extern int was_refused; 92extern int was_refused;
93extern int address_family; 93extern int address_family;
94 94
95RETSIGTYPE socket_timeout_alarm_handler (int) __attribute__((noreturn)); 95void socket_timeout_alarm_handler (int) __attribute__((noreturn));
96 96
97/* SSL-Related functionality */ 97/* SSL-Related functionality */
98#ifdef HAVE_SSL 98#ifdef HAVE_SSL
diff --git a/plugins/popen.c b/plugins/popen.c
index 723817d..036bc60 100644
--- a/plugins/popen.c
+++ b/plugins/popen.c
@@ -38,8 +38,9 @@
38* 38*
39*****************************************************************************/ 39*****************************************************************************/
40 40
41#include "common.h" 41#include "./common.h"
42#include "utils.h" 42#include "./utils.h"
43#include "../lib/maxfd.h"
43 44
44/* extern so plugin has pid to kill exec'd process on timeouts */ 45/* extern so plugin has pid to kill exec'd process on timeouts */
45extern pid_t *childpid; 46extern pid_t *childpid;
@@ -49,9 +50,9 @@ extern FILE *child_process;
49FILE *spopen (const char *); 50FILE *spopen (const char *);
50int spclose (FILE *); 51int spclose (FILE *);
51#ifdef REDHAT_SPOPEN_ERROR 52#ifdef REDHAT_SPOPEN_ERROR
52RETSIGTYPE popen_sigchld_handler (int); 53void popen_sigchld_handler (int);
53#endif 54#endif
54RETSIGTYPE popen_timeout_alarm_handler (int); 55void popen_timeout_alarm_handler (int);
55 56
56#include <stdarg.h> /* ANSI C header file */ 57#include <stdarg.h> /* ANSI C header file */
57#include <fcntl.h> 58#include <fcntl.h>
@@ -177,8 +178,7 @@ spopen (const char *cmdstring)
177 } 178 }
178 argv[i] = NULL; 179 argv[i] = NULL;
179 180
180 if(maxfd == 0) 181 long maxfd = mp_open_max();
181 maxfd = open_max();
182 182
183 if (childpid == NULL) { /* first time through */ 183 if (childpid == NULL) { /* first time through */
184 if ((childpid = calloc ((size_t)maxfd, sizeof (pid_t))) == NULL) 184 if ((childpid = calloc ((size_t)maxfd, sizeof (pid_t))) == NULL)
@@ -266,7 +266,7 @@ spclose (FILE * fp)
266} 266}
267 267
268#ifdef REDHAT_SPOPEN_ERROR 268#ifdef REDHAT_SPOPEN_ERROR
269RETSIGTYPE 269void
270popen_sigchld_handler (int signo) 270popen_sigchld_handler (int signo)
271{ 271{
272 if (signo == SIGCHLD) 272 if (signo == SIGCHLD)
@@ -274,7 +274,7 @@ popen_sigchld_handler (int signo)
274} 274}
275#endif 275#endif
276 276
277RETSIGTYPE 277void
278popen_timeout_alarm_handler (int signo) 278popen_timeout_alarm_handler (int signo)
279{ 279{
280 int fh; 280 int fh;
diff --git a/plugins/popen.h b/plugins/popen.h
index a5dd8fa..1ea6963 100644
--- a/plugins/popen.h
+++ b/plugins/popen.h
@@ -5,7 +5,7 @@
5 5
6FILE *spopen (const char *); 6FILE *spopen (const char *);
7int spclose (FILE *); 7int spclose (FILE *);
8RETSIGTYPE popen_timeout_alarm_handler (int); 8void popen_timeout_alarm_handler (int);
9 9
10pid_t *childpid=NULL; 10pid_t *childpid=NULL;
11int *child_stderr_array=NULL; 11int *child_stderr_array=NULL;
diff --git a/plugins/runcmd.c b/plugins/runcmd.c
index c1d675d..4f3e349 100644
--- a/plugins/runcmd.c
+++ b/plugins/runcmd.c
@@ -60,6 +60,8 @@
60# define SIG_ERR ((Sigfunc *)-1) 60# define SIG_ERR ((Sigfunc *)-1)
61#endif 61#endif
62 62
63#include "../lib/maxfd.h"
64
63/* This variable must be global, since there's no way the caller 65/* This variable must be global, since there's no way the caller
64 * can forcibly slay a dead or ungainly running program otherwise. 66 * can forcibly slay a dead or ungainly running program otherwise.
65 * Multithreading apps and plugins can initialize it (via NP_RUNCMD_INIT) 67 * Multithreading apps and plugins can initialize it (via NP_RUNCMD_INIT)
@@ -88,8 +90,7 @@ extern void die (int, const char *, ...)
88 * through this api and thus achieve async-safeness throughout the api */ 90 * through this api and thus achieve async-safeness throughout the api */
89void np_runcmd_init(void) 91void np_runcmd_init(void)
90{ 92{
91 if(maxfd == 0) 93 long maxfd = mp_open_max();
92 maxfd = open_max();
93 if(!np_pids) np_pids = calloc(maxfd, sizeof(pid_t)); 94 if(!np_pids) np_pids = calloc(maxfd, sizeof(pid_t));
94} 95}
95 96
@@ -116,10 +117,6 @@ np_runcmd_open(const char *cmdstring, int *pfd, int *pfderr)
116 env[0] = strdup("LC_ALL=C"); 117 env[0] = strdup("LC_ALL=C");
117 env[1] = '\0'; 118 env[1] = '\0';
118 119
119 /* if no command was passed, return with no error */
120 if (cmdstring == NULL)
121 return -1;
122
123 /* make copy of command string so strtok() doesn't silently modify it */ 120 /* make copy of command string so strtok() doesn't silently modify it */
124 /* (the calling program may want to access it later) */ 121 /* (the calling program may want to access it later) */
125 cmdlen = strlen(cmdstring); 122 cmdlen = strlen(cmdstring);
@@ -196,6 +193,7 @@ np_runcmd_open(const char *cmdstring, int *pfd, int *pfderr)
196 /* close all descriptors in np_pids[] 193 /* close all descriptors in np_pids[]
197 * This is executed in a separate address space (pure child), 194 * This is executed in a separate address space (pure child),
198 * so we don't have to worry about async safety */ 195 * so we don't have to worry about async safety */
196 long maxfd = mp_open_max();
199 for (i = 0; i < maxfd; i++) 197 for (i = 0; i < maxfd; i++)
200 if(np_pids[i] > 0) 198 if(np_pids[i] > 0)
201 close (i); 199 close (i);
@@ -223,6 +221,7 @@ np_runcmd_close(int fd)
223 pid_t pid; 221 pid_t pid;
224 222
225 /* make sure this fd was opened by popen() */ 223 /* make sure this fd was opened by popen() */
224 long maxfd = mp_open_max();
226 if(fd < 0 || fd > maxfd || !np_pids || (pid = np_pids[fd]) == 0) 225 if(fd < 0 || fd > maxfd || !np_pids || (pid = np_pids[fd]) == 0)
227 return -1; 226 return -1;
228 227
@@ -246,6 +245,7 @@ runcmd_timeout_alarm_handler (int signo)
246 if (signo == SIGALRM) 245 if (signo == SIGALRM)
247 puts(_("CRITICAL - Plugin timed out while executing system call")); 246 puts(_("CRITICAL - Plugin timed out while executing system call"));
248 247
248 long maxfd = mp_open_max();
249 if(np_pids) for(i = 0; i < maxfd; i++) { 249 if(np_pids) for(i = 0; i < maxfd; i++) {
250 if(np_pids[i] != 0) kill(np_pids[i], SIGKILL); 250 if(np_pids[i] != 0) kill(np_pids[i], SIGKILL);
251 } 251 }
diff --git a/plugins/sslutils.c b/plugins/sslutils.c
index 666a012..6bc0ba8 100644
--- a/plugins/sslutils.c
+++ b/plugins/sslutils.c
@@ -31,9 +31,8 @@
31#include "netutils.h" 31#include "netutils.h"
32 32
33#ifdef HAVE_SSL 33#ifdef HAVE_SSL
34static SSL_CTX *c=NULL; 34static SSL_CTX *ctx=NULL;
35static SSL *s=NULL; 35static SSL *s=NULL;
36static int initialized=0;
37 36
38int np_net_ssl_init(int sd) { 37int np_net_ssl_init(int sd) {
39 return np_net_ssl_init_with_hostname(sd, NULL); 38 return np_net_ssl_init_with_hostname(sd, NULL);
@@ -48,24 +47,24 @@ int np_net_ssl_init_with_hostname_and_version(int sd, char *host_name, int versi
48} 47}
49 48
50int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int version, char *cert, char *privkey) { 49int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int version, char *cert, char *privkey) {
51 const SSL_METHOD *method = NULL;
52 long options = 0; 50 long options = 0;
53 51
52 if ((ctx = SSL_CTX_new(TLS_client_method())) == NULL) {
53 printf("%s\n", _("CRITICAL - Cannot create SSL context."));
54 return STATE_CRITICAL;
55 }
56
54 switch (version) { 57 switch (version) {
55 case MP_SSLv2: /* SSLv2 protocol */ 58 case MP_SSLv2: /* SSLv2 protocol */
56#if defined(USE_GNUTLS) || defined(OPENSSL_NO_SSL2)
57 printf("%s\n", _("UNKNOWN - SSL protocol version 2 is not supported by your SSL library.")); 59 printf("%s\n", _("UNKNOWN - SSL protocol version 2 is not supported by your SSL library."));
58 return STATE_UNKNOWN; 60 return STATE_UNKNOWN;
59#else
60 method = SSLv2_client_method();
61 break;
62#endif
63 case MP_SSLv3: /* SSLv3 protocol */ 61 case MP_SSLv3: /* SSLv3 protocol */
64#if defined(OPENSSL_NO_SSL3) 62#if defined(OPENSSL_NO_SSL3)
65 printf("%s\n", _("UNKNOWN - SSL protocol version 3 is not supported by your SSL library.")); 63 printf("%s\n", _("UNKNOWN - SSL protocol version 3 is not supported by your SSL library."));
66 return STATE_UNKNOWN; 64 return STATE_UNKNOWN;
67#else 65#else
68 method = SSLv3_client_method(); 66 SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION);
67 SSL_CTX_set_max_proto_version(ctx, SSL3_VERSION);
69 break; 68 break;
70#endif 69#endif
71 case MP_TLSv1: /* TLSv1 protocol */ 70 case MP_TLSv1: /* TLSv1 protocol */
@@ -73,7 +72,8 @@ int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int
73 printf("%s\n", _("UNKNOWN - TLS protocol version 1 is not supported by your SSL library.")); 72 printf("%s\n", _("UNKNOWN - TLS protocol version 1 is not supported by your SSL library."));
74 return STATE_UNKNOWN; 73 return STATE_UNKNOWN;
75#else 74#else
76 method = TLSv1_client_method(); 75 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
76 SSL_CTX_set_max_proto_version(ctx, TLS1_VERSION);
77 break; 77 break;
78#endif 78#endif
79 case MP_TLSv1_1: /* TLSv1.1 protocol */ 79 case MP_TLSv1_1: /* TLSv1.1 protocol */
@@ -81,7 +81,8 @@ int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int
81 printf("%s\n", _("UNKNOWN - TLS protocol version 1.1 is not supported by your SSL library.")); 81 printf("%s\n", _("UNKNOWN - TLS protocol version 1.1 is not supported by your SSL library."));
82 return STATE_UNKNOWN; 82 return STATE_UNKNOWN;
83#else 83#else
84 method = TLSv1_1_client_method(); 84 SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION);
85 SSL_CTX_set_max_proto_version(ctx, TLS1_1_VERSION);
85 break; 86 break;
86#endif 87#endif
87 case MP_TLSv1_2: /* TLSv1.2 protocol */ 88 case MP_TLSv1_2: /* TLSv1.2 protocol */
@@ -89,7 +90,8 @@ int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int
89 printf("%s\n", _("UNKNOWN - TLS protocol version 1.2 is not supported by your SSL library.")); 90 printf("%s\n", _("UNKNOWN - TLS protocol version 1.2 is not supported by your SSL library."));
90 return STATE_UNKNOWN; 91 return STATE_UNKNOWN;
91#else 92#else
92 method = TLSv1_2_client_method(); 93 SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
94 SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION);
93 break; 95 break;
94#endif 96#endif
95 case MP_TLSv1_2_OR_NEWER: 97 case MP_TLSv1_2_OR_NEWER:
@@ -97,56 +99,43 @@ int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int
97 printf("%s\n", _("UNKNOWN - Disabling TLSv1.1 is not supported by your SSL library.")); 99 printf("%s\n", _("UNKNOWN - Disabling TLSv1.1 is not supported by your SSL library."));
98 return STATE_UNKNOWN; 100 return STATE_UNKNOWN;
99#else 101#else
100 options |= SSL_OP_NO_TLSv1_1; 102 SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
103 break;
101#endif 104#endif
102 /* FALLTHROUGH */
103 case MP_TLSv1_1_OR_NEWER: 105 case MP_TLSv1_1_OR_NEWER:
104#if !defined(SSL_OP_NO_TLSv1) 106#if !defined(SSL_OP_NO_TLSv1)
105 printf("%s\n", _("UNKNOWN - Disabling TLSv1 is not supported by your SSL library.")); 107 printf("%s\n", _("UNKNOWN - Disabling TLSv1 is not supported by your SSL library."));
106 return STATE_UNKNOWN; 108 return STATE_UNKNOWN;
107#else 109#else
108 options |= SSL_OP_NO_TLSv1; 110 SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION);
111 break;
109#endif 112#endif
110 /* FALLTHROUGH */
111 case MP_TLSv1_OR_NEWER: 113 case MP_TLSv1_OR_NEWER:
112#if defined(SSL_OP_NO_SSLv3) 114#if defined(SSL_OP_NO_SSLv3)
113 options |= SSL_OP_NO_SSLv3; 115 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
116 break;
114#endif 117#endif
115 /* FALLTHROUGH */
116 case MP_SSLv3_OR_NEWER: 118 case MP_SSLv3_OR_NEWER:
117#if defined(SSL_OP_NO_SSLv2) 119#if defined(SSL_OP_NO_SSLv2)
118 options |= SSL_OP_NO_SSLv2; 120 SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION);
121 break;
119#endif 122#endif
120 case MP_SSLv2_OR_NEWER:
121 /* FALLTHROUGH */
122 default: /* Default to auto negotiation */
123 method = SSLv23_client_method();
124 }
125 if (!initialized) {
126 /* Initialize SSL context */
127 SSLeay_add_ssl_algorithms();
128 SSL_load_error_strings();
129 OpenSSL_add_all_algorithms();
130 initialized = 1;
131 }
132 if ((c = SSL_CTX_new(method)) == NULL) {
133 printf("%s\n", _("CRITICAL - Cannot create SSL context."));
134 return STATE_CRITICAL;
135 } 123 }
124
136 if (cert && privkey) { 125 if (cert && privkey) {
137#ifdef USE_OPENSSL 126#ifdef USE_OPENSSL
138 if (!SSL_CTX_use_certificate_chain_file(c, cert)) { 127 if (!SSL_CTX_use_certificate_chain_file(ctx, cert)) {
139#elif USE_GNUTLS 128#elif USE_GNUTLS
140 if (!SSL_CTX_use_certificate_file(c, cert, SSL_FILETYPE_PEM)) { 129 if (!SSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_PEM)) {
141#else 130#else
142#error Unported for unknown SSL library 131#error Unported for unknown SSL library
143#endif 132#endif
144 printf ("%s\n", _("CRITICAL - Unable to open certificate chain file!\n")); 133 printf ("%s\n", _("CRITICAL - Unable to open certificate chain file!\n"));
145 return STATE_CRITICAL; 134 return STATE_CRITICAL;
146 } 135 }
147 SSL_CTX_use_PrivateKey_file(c, privkey, SSL_FILETYPE_PEM); 136 SSL_CTX_use_PrivateKey_file(ctx, privkey, SSL_FILETYPE_PEM);
148#ifdef USE_OPENSSL 137#ifdef USE_OPENSSL
149 if (!SSL_CTX_check_private_key(c)) { 138 if (!SSL_CTX_check_private_key(ctx)) {
150 printf ("%s\n", _("CRITICAL - Private key does not seem to match certificate!\n")); 139 printf ("%s\n", _("CRITICAL - Private key does not seem to match certificate!\n"));
151 return STATE_CRITICAL; 140 return STATE_CRITICAL;
152 } 141 }
@@ -155,9 +144,9 @@ int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int
155#ifdef SSL_OP_NO_TICKET 144#ifdef SSL_OP_NO_TICKET
156 options |= SSL_OP_NO_TICKET; 145 options |= SSL_OP_NO_TICKET;
157#endif 146#endif
158 SSL_CTX_set_options(c, options); 147 SSL_CTX_set_options(ctx, options);
159 SSL_CTX_set_mode(c, SSL_MODE_AUTO_RETRY); 148 SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
160 if ((s = SSL_new(c)) != NULL) { 149 if ((s = SSL_new(ctx)) != NULL) {
161#ifdef SSL_set_tlsext_host_name 150#ifdef SSL_set_tlsext_host_name
162 if (host_name != NULL) 151 if (host_name != NULL)
163 SSL_set_tlsext_host_name(s, host_name); 152 SSL_set_tlsext_host_name(s, host_name);
@@ -184,9 +173,9 @@ void np_net_ssl_cleanup() {
184#endif 173#endif
185 SSL_shutdown(s); 174 SSL_shutdown(s);
186 SSL_free(s); 175 SSL_free(s);
187 if (c) { 176 if (ctx) {
188 SSL_CTX_free(c); 177 SSL_CTX_free(ctx);
189 c=NULL; 178 ctx=NULL;
190 } 179 }
191 s=NULL; 180 s=NULL;
192 } 181 }
diff --git a/plugins/t/check_imap.t b/plugins/t/check_imap.t
index 7c74e56..cf2f81c 100644
--- a/plugins/t/check_imap.t
+++ b/plugins/t/check_imap.t
@@ -25,7 +25,7 @@ $t = NPTest->testCmd( "./check_imap $host_tcp_imap -p 143 -wt 9 -ct 9 -to 10 -e
25cmp_ok( $t->return_code, '==', 0, "Check old parameter options" ); 25cmp_ok( $t->return_code, '==', 0, "Check old parameter options" );
26 26
27$t = NPTest->testCmd( "./check_imap $host_nonresponsive" ); 27$t = NPTest->testCmd( "./check_imap $host_nonresponsive" );
28cmp_ok( $t->return_code, '==', 2, "Get error with non reponsive host" ); 28cmp_ok( $t->return_code, '==', 2, "Get error with non responsive host" );
29 29
30$t = NPTest->testCmd( "./check_imap $hostname_invalid" ); 30$t = NPTest->testCmd( "./check_imap $hostname_invalid" );
31cmp_ok( $t->return_code, '==', 2, "Invalid hostname" ); 31cmp_ok( $t->return_code, '==', 2, "Invalid hostname" );
diff --git a/plugins/t/check_users.t b/plugins/t/check_users.t
index 088f3b5..9ebc2fc 100644
--- a/plugins/t/check_users.t
+++ b/plugins/t/check_users.t
@@ -2,7 +2,7 @@
2# 2#
3# Logged in Users Tests via check_users 3# Logged in Users Tests via check_users
4# 4#
5# Trick: This ckeck requires at least 1 user logged in. These commands should 5# Trick: This check requires at least 1 user logged in. These commands should
6# leave a session open forever in the background: 6# leave a session open forever in the background:
7# 7#
8# $ ssh -tt localhost </dev/null >/dev/null 2>/dev/null & 8# $ ssh -tt localhost </dev/null >/dev/null 2>/dev/null &
diff --git a/plugins/tests/check_curl.t b/plugins/tests/check_curl.t
index 72f2b7c..3c91483 100755
--- a/plugins/tests/check_curl.t
+++ b/plugins/tests/check_curl.t
@@ -9,7 +9,7 @@
9# Country Name (2 letter code) [AU]:DE 9# Country Name (2 letter code) [AU]:DE
10# State or Province Name (full name) [Some-State]:Bavaria 10# State or Province Name (full name) [Some-State]:Bavaria
11# Locality Name (eg, city) []:Munich 11# Locality Name (eg, city) []:Munich
12# Organization Name (eg, company) [Internet Widgits Pty Ltd]:Monitoring Plugins 12# Organization Name (eg, company) [Internet Widgets Pty Ltd]:Monitoring Plugins
13# Organizational Unit Name (eg, section) []: 13# Organizational Unit Name (eg, section) []:
14# Common Name (e.g. server FQDN or YOUR name) []:Monitoring Plugins 14# Common Name (e.g. server FQDN or YOUR name) []:Monitoring Plugins
15# Email Address []:devel@monitoring-plugins.org 15# Email Address []:devel@monitoring-plugins.org
diff --git a/plugins/utils.c b/plugins/utils.c
index b4214c6..71c0bdd 100644
--- a/plugins/utils.c
+++ b/plugins/utils.c
@@ -804,19 +804,3 @@ char *sperfdata_int (const char *label,
804 804
805 return data; 805 return data;
806} 806}
807
808int
809open_max (void)
810{
811 errno = 0;
812 if (maxfd > 0)
813 return(maxfd);
814
815 if ((maxfd = sysconf (_SC_OPEN_MAX)) < 0) {
816 if (errno == 0)
817 maxfd = DEFAULT_MAXFD; /* it's indeterminate */
818 else
819 die (STATE_UNKNOWN, _("sysconf error for _SC_OPEN_MAX\n"));
820 }
821 return(maxfd);
822}
diff --git a/plugins/utils.h b/plugins/utils.h
index c76b321..cb979ce 100644
--- a/plugins/utils.h
+++ b/plugins/utils.h
@@ -106,8 +106,6 @@ char *sperfdata (const char *, double, const char *, char *, char *,
106char *sperfdata_int (const char *, int, const char *, char *, char *, 106char *sperfdata_int (const char *, int, const char *, char *, char *,
107 int, int, int, int); 107 int, int, int, int);
108 108
109int open_max (void);
110
111/* The idea here is that, although not every plugin will use all of these, 109/* The idea here is that, although not every plugin will use all of these,
112 most will or should. Therefore, for consistency, these very common 110 most will or should. Therefore, for consistency, these very common
113 options should have only these meanings throughout the overall suite */ 111 options should have only these meanings throughout the overall suite */
diff --git a/po/de.po b/po/de.po
index 33225f8..7c36e16 100644
--- a/po/de.po
+++ b/po/de.po
@@ -9,7 +9,7 @@ msgid ""
9msgstr "" 9msgstr ""
10"Project-Id-Version: PACKAGE VERSION\n" 10"Project-Id-Version: PACKAGE VERSION\n"
11"Report-Msgid-Bugs-To: devel@monitoring-plugins.org\n" 11"Report-Msgid-Bugs-To: devel@monitoring-plugins.org\n"
12"POT-Creation-Date: 2023-09-17 23:47+0200\n" 12"POT-Creation-Date: 2023-10-01 00:46+0200\n"
13"PO-Revision-Date: 2004-12-23 17:46+0100\n" 13"PO-Revision-Date: 2004-12-23 17:46+0100\n"
14"Last-Translator: \n" 14"Last-Translator: \n"
15"Language-Team: Monitoring Plugin Development Team <devel@monitoring-plugins." 15"Language-Team: Monitoring Plugin Development Team <devel@monitoring-plugins."
@@ -308,6 +308,9 @@ msgstr "UNKNOWN"
308msgid "Must set a threshold value before using -p\n" 308msgid "Must set a threshold value before using -p\n"
309msgstr "" 309msgstr ""
310 310
311msgid "Could not compile regular expression"
312msgstr ""
313
311msgid "Must set -E before selecting paths\n" 314msgid "Must set -E before selecting paths\n"
312msgstr "" 315msgstr ""
313 316
@@ -319,10 +322,9 @@ msgid ""
319"explicitly" 322"explicitly"
320msgstr "" 323msgstr ""
321 324
322msgid "Could not compile regular expression" 325msgid ""
323msgstr "" 326"Must set a threshold value before using -r/-R/-A (--ereg-path/--eregi-path/--"
324 327"all)\n"
325msgid "Must set a threshold value before using -r/-R\n"
326msgstr "" 328msgstr ""
327 329
328msgid "Regular expression did not match any path or disk" 330msgid "Regular expression did not match any path or disk"
@@ -444,10 +446,29 @@ msgstr ""
444msgid "Choose bytes, kB, MB, GB, TB (default: MB)" 446msgid "Choose bytes, kB, MB, GB, TB (default: MB)"
445msgstr "" 447msgstr ""
446 448
447msgid "Ignore all filesystems of indicated type (may be repeated)" 449msgid ""
450"Ignore all filesystems of types matching given regex(7) (may be repeated)"
451msgstr ""
452
453msgid ""
454"Check only filesystems where the type matches this given regex(7) (may be "
455"repeated)"
456msgstr ""
457
458msgid "General usage hints:"
459msgstr "Allgemeine Nutzungshinweise:"
460
461msgid ""
462"- Arguments are positional! \"-w 5 -c 1 -p /foo -w6 -c2 -p /bar\" is not the "
463"same as"
464msgstr ""
465
466msgid "\"-w 5 -c 1 -p /bar w6 -c2 -p /foo\"."
448msgstr "" 467msgstr ""
449 468
450msgid "Check only filesystems of indicated type (may be repeated)" 469msgid ""
470"- The syntax is broadly: \"{thresholds a} {paths a} -C {thresholds b} "
471"{thresholds b} ...\""
451msgstr "" 472msgstr ""
452 473
453msgid "Checks /tmp and /var at 10% and 5%, and / at 100MB and 50MB" 474msgid "Checks /tmp and /var at 10% and 5%, and / at 100MB and 50MB"
@@ -4687,9 +4708,6 @@ msgstr "konnte keinen Speicher für '%s' reservieren\n"
4687msgid "failed malloc in xvasprintf\n" 4708msgid "failed malloc in xvasprintf\n"
4688msgstr "konnte keinen Speicher für '%s' reservieren\n" 4709msgstr "konnte keinen Speicher für '%s' reservieren\n"
4689 4710
4690msgid "sysconf error for _SC_OPEN_MAX\n"
4691msgstr ""
4692
4693#, c-format 4711#, c-format
4694msgid "" 4712msgid ""
4695" %s (-h | --help) for detailed help\n" 4713" %s (-h | --help) for detailed help\n"
@@ -5052,6 +5070,25 @@ msgstr "Warning threshold Integer sein"
5052msgid "critical threshold (currently " 5070msgid "critical threshold (currently "
5053msgstr "Critical threshold muss ein Integer sein" 5071msgstr "Critical threshold muss ein Integer sein"
5054 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
5055#, fuzzy 5092#, fuzzy
5056msgid "specify a source IP address or device name" 5093msgid "specify a source IP address or device name"
5057msgstr "Hostname oder Serveradresse muss angegeben werden" 5094msgstr "Hostname oder Serveradresse muss angegeben werden"
@@ -5083,6 +5120,9 @@ msgstr ""
5083msgid "verbose" 5120msgid "verbose"
5084msgstr "" 5121msgstr ""
5085 5122
5123msgid "If none of R,P,J,M,S or O is specified, default behavior is -R -P"
5124msgstr ""
5125
5086msgid "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."
5087msgstr "" 5127msgstr ""
5088 5128
diff --git a/po/fr.po b/po/fr.po
index 4c4b937..ef3cddc 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -10,7 +10,7 @@ msgid ""
10msgstr "" 10msgstr ""
11"Project-Id-Version: PACKAGE VERSION\n" 11"Project-Id-Version: PACKAGE VERSION\n"
12"Report-Msgid-Bugs-To: devel@monitoring-plugins.org\n" 12"Report-Msgid-Bugs-To: devel@monitoring-plugins.org\n"
13"POT-Creation-Date: 2023-09-17 23:47+0200\n" 13"POT-Creation-Date: 2023-10-01 00:46+0200\n"
14"PO-Revision-Date: 2010-04-21 23:38-0400\n" 14"PO-Revision-Date: 2010-04-21 23:38-0400\n"
15"Last-Translator: \n" 15"Last-Translator: \n"
16"Language-Team: Monitoring Plugin Development Team <devel@monitoring-plugins." 16"Language-Team: Monitoring Plugin Development Team <devel@monitoring-plugins."
@@ -307,6 +307,9 @@ msgstr "INCONNU"
307msgid "Must set a threshold value before using -p\n" 307msgid "Must set a threshold value before using -p\n"
308msgstr "" 308msgstr ""
309 309
310msgid "Could not compile regular expression"
311msgstr "Impossible de compiler l'expression rationnelle"
312
310msgid "Must set -E before selecting paths\n" 313msgid "Must set -E before selecting paths\n"
311msgstr "" 314msgstr ""
312 315
@@ -318,10 +321,9 @@ msgid ""
318"explicitly" 321"explicitly"
319msgstr "" 322msgstr ""
320 323
321msgid "Could not compile regular expression" 324msgid ""
322msgstr "Impossible de compiler l'expression rationnelle" 325"Must set a threshold value before using -r/-R/-A (--ereg-path/--eregi-path/--"
323 326"all)\n"
324msgid "Must set a threshold value before using -r/-R\n"
325msgstr "" 327msgstr ""
326 328
327msgid "Regular expression did not match any path or disk" 329msgid "Regular expression did not match any path or disk"
@@ -459,17 +461,37 @@ msgstr ""
459msgid "Choose bytes, kB, MB, GB, TB (default: MB)" 461msgid "Choose bytes, kB, MB, GB, TB (default: MB)"
460msgstr "Choisissez octets, kb, MB, GB, TB (par défaut: MB)" 462msgstr "Choisissez octets, kb, MB, GB, TB (par défaut: MB)"
461 463
462msgid "Ignore all filesystems of indicated type (may be repeated)" 464#, fuzzy
465msgid ""
466"Ignore all filesystems of types matching given regex(7) (may be repeated)"
463msgstr "" 467msgstr ""
464"Ignorer tout les systèmes de fichiers qui correspondent au type indiqué " 468"Ignorer tout les systèmes de fichiers qui correspondent au type indiqué "
465"(peut être utilisé plusieurs fois)" 469"(peut être utilisé plusieurs fois)"
466 470
467#, fuzzy 471#, fuzzy
468msgid "Check only filesystems of indicated type (may be repeated)" 472msgid ""
473"Check only filesystems where the type matches this given regex(7) (may be "
474"repeated)"
469msgstr "" 475msgstr ""
470"Ignorer tout les systèmes de fichiers qui correspondent au type indiqué " 476"Ignorer tout les systèmes de fichiers qui correspondent au type indiqué "
471"(peut être utilisé plusieurs fois)" 477"(peut être utilisé plusieurs fois)"
472 478
479msgid "General usage hints:"
480msgstr ""
481
482msgid ""
483"- Arguments are positional! \"-w 5 -c 1 -p /foo -w6 -c2 -p /bar\" is not the "
484"same as"
485msgstr ""
486
487msgid "\"-w 5 -c 1 -p /bar w6 -c2 -p /foo\"."
488msgstr ""
489
490msgid ""
491"- The syntax is broadly: \"{thresholds a} {paths a} -C {thresholds b} "
492"{thresholds b} ...\""
493msgstr ""
494
473msgid "Checks /tmp and /var at 10% and 5%, and / at 100MB and 50MB" 495msgid "Checks /tmp and /var at 10% and 5%, and / at 100MB and 50MB"
474msgstr "Vérifie /tmp à 10% et /var à 5% et / à 100MB et 50MB" 496msgstr "Vérifie /tmp à 10% et /var à 5% et / à 100MB et 50MB"
475 497
@@ -4822,9 +4844,6 @@ msgstr "La fonction malloc à échoué dans strscat\n"
4822msgid "failed malloc in xvasprintf\n" 4844msgid "failed malloc in xvasprintf\n"
4823msgstr "La fonction malloc à échoué dans strscat\n" 4845msgstr "La fonction malloc à échoué dans strscat\n"
4824 4846
4825msgid "sysconf error for _SC_OPEN_MAX\n"
4826msgstr ""
4827
4828#, c-format 4847#, c-format
4829msgid "" 4848msgid ""
4830" %s (-h | --help) for detailed help\n" 4849" %s (-h | --help) for detailed help\n"
@@ -5272,6 +5291,25 @@ msgstr "Valeurs pour le seuil d'avertissement (actuellement "
5272msgid "critical threshold (currently " 5291msgid "critical threshold (currently "
5273msgstr "Valeurs pour le seuil critique (actuellement " 5292msgstr "Valeurs pour le seuil critique (actuellement "
5274 5293
5294msgid ""
5295"RTA, round trip average, mode warning,critical, ex. 100ms,200ms unit in ms"
5296msgstr ""
5297
5298msgid "packet loss mode, ex. 40%,50% , unit in %"
5299msgstr ""
5300
5301msgid "jitter mode warning,critical, ex. 40.000ms,50.000ms , unit in ms "
5302msgstr ""
5303
5304msgid "MOS mode, between 0 and 4.4 warning,critical, ex. 3.5,3.0"
5305msgstr ""
5306
5307msgid "score mode, max value 100 warning,critical, ex. 80,70 "
5308msgstr ""
5309
5310msgid "detect out of order ICMP packts "
5311msgstr ""
5312
5275msgid "specify a source IP address or device name" 5313msgid "specify a source IP address or device name"
5276msgstr "spécifiez une adresse ou un nom d'hôte" 5314msgstr "spécifiez une adresse ou un nom d'hôte"
5277 5315
@@ -5302,6 +5340,9 @@ msgstr ""
5302msgid "verbose" 5340msgid "verbose"
5303msgstr "" 5341msgstr ""
5304 5342
5343msgid "If none of R,P,J,M,S or O is specified, default behavior is -R -P"
5344msgstr ""
5345
5305msgid "The -H switch is optional. Naming a host (or several) to check is not." 5346msgid "The -H switch is optional. Naming a host (or several) to check is not."
5306msgstr "" 5347msgstr ""
5307 5348
@@ -5323,9 +5364,17 @@ msgstr ""
5323msgid "The -v switch can be specified several times for increased verbosity." 5364msgid "The -v switch can be specified several times for increased verbosity."
5324msgstr "" 5365msgstr ""
5325 5366
5367<<<<<<< HEAD
5326#, c-format 5368#, c-format
5327#~ msgid "Server answer: %s" 5369#~ msgid "Server answer: %s"
5328#~ msgstr "Réponse du serveur: %s" 5370#~ msgstr "Réponse du serveur: %s"
5371=======
5372#, fuzzy
5373#~ msgid "Check only filesystems of indicated type (may be repeated)"
5374#~ msgstr ""
5375#~ "Ignorer tout les systèmes de fichiers qui correspondent au type indiqué "
5376#~ "(peut être utilisé plusieurs fois)"
5377>>>>>>> master
5329 5378
5330#~ msgid "Path or partition (may be repeated)" 5379#~ msgid "Path or partition (may be repeated)"
5331#~ msgstr "Répertoire ou partition (peut être utilisé plusieurs fois)" 5380#~ msgstr "Répertoire ou partition (peut être utilisé plusieurs fois)"
diff --git a/po/monitoring-plugins.pot b/po/monitoring-plugins.pot
index 30f0c9a..eacfaff 100644
--- a/po/monitoring-plugins.pot
+++ b/po/monitoring-plugins.pot
@@ -8,7 +8,7 @@ msgid ""
8msgstr "" 8msgstr ""
9"Project-Id-Version: PACKAGE VERSION\n" 9"Project-Id-Version: PACKAGE VERSION\n"
10"Report-Msgid-Bugs-To: devel@monitoring-plugins.org\n" 10"Report-Msgid-Bugs-To: devel@monitoring-plugins.org\n"
11"POT-Creation-Date: 2023-09-17 23:47+0200\n" 11"POT-Creation-Date: 2023-10-01 00:46+0200\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" 13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n" 14"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -291,6 +291,9 @@ msgstr ""
291msgid "Must set a threshold value before using -p\n" 291msgid "Must set a threshold value before using -p\n"
292msgstr "" 292msgstr ""
293 293
294msgid "Could not compile regular expression"
295msgstr ""
296
294msgid "Must set -E before selecting paths\n" 297msgid "Must set -E before selecting paths\n"
295msgstr "" 298msgstr ""
296 299
@@ -302,10 +305,9 @@ msgid ""
302"explicitly" 305"explicitly"
303msgstr "" 306msgstr ""
304 307
305msgid "Could not compile regular expression" 308msgid ""
306msgstr "" 309"Must set a threshold value before using -r/-R/-A (--ereg-path/--eregi-path/--"
307 310"all)\n"
308msgid "Must set a threshold value before using -r/-R\n"
309msgstr "" 311msgstr ""
310 312
311msgid "Regular expression did not match any path or disk" 313msgid "Regular expression did not match any path or disk"
@@ -421,10 +423,29 @@ msgstr ""
421msgid "Choose bytes, kB, MB, GB, TB (default: MB)" 423msgid "Choose bytes, kB, MB, GB, TB (default: MB)"
422msgstr "" 424msgstr ""
423 425
424msgid "Ignore all filesystems of indicated type (may be repeated)" 426msgid ""
427"Ignore all filesystems of types matching given regex(7) (may be repeated)"
425msgstr "" 428msgstr ""
426 429
427msgid "Check only filesystems of indicated type (may be repeated)" 430msgid ""
431"Check only filesystems where the type matches this given regex(7) (may be "
432"repeated)"
433msgstr ""
434
435msgid "General usage hints:"
436msgstr ""
437
438msgid ""
439"- Arguments are positional! \"-w 5 -c 1 -p /foo -w6 -c2 -p /bar\" is not the "
440"same as"
441msgstr ""
442
443msgid "\"-w 5 -c 1 -p /bar w6 -c2 -p /foo\"."
444msgstr ""
445
446msgid ""
447"- The syntax is broadly: \"{thresholds a} {paths a} -C {thresholds b} "
448"{thresholds b} ...\""
428msgstr "" 449msgstr ""
429 450
430msgid "Checks /tmp and /var at 10% and 5%, and / at 100MB and 50MB" 451msgid "Checks /tmp and /var at 10% and 5%, and / at 100MB and 50MB"
@@ -4514,9 +4535,6 @@ msgstr ""
4514msgid "failed malloc in xvasprintf\n" 4535msgid "failed malloc in xvasprintf\n"
4515msgstr "" 4536msgstr ""
4516 4537
4517msgid "sysconf error for _SC_OPEN_MAX\n"
4518msgstr ""
4519
4520#, c-format 4538#, c-format
4521msgid "" 4539msgid ""
4522" %s (-h | --help) for detailed help\n" 4540" %s (-h | --help) for detailed help\n"
@@ -4877,6 +4895,25 @@ msgstr ""
4877msgid "critical threshold (currently " 4895msgid "critical threshold (currently "
4878msgstr "" 4896msgstr ""
4879 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
4880msgid "specify a source IP address or device name" 4917msgid "specify a source IP address or device name"
4881msgstr "" 4918msgstr ""
4882 4919
@@ -4907,6 +4944,9 @@ msgstr ""
4907msgid "verbose" 4944msgid "verbose"
4908msgstr "" 4945msgstr ""
4909 4946
4947msgid "If none of R,P,J,M,S or O is specified, default behavior is -R -P"
4948msgstr ""
4949
4910msgid "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."
4911msgstr "" 4951msgstr ""
4912 4952