From e368ef68d4668726b5f3e068c39c31720c0902ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20M=C3=BCcklich=20ITO?= Date: Thu, 9 Jul 2026 14:17:14 +0200 Subject: [PATCH 1/3] perfdata: add --legacy-perfdata flag to restore pre-1.4.4 format v1.4.4 changed the perfdata output (added checktime=, the ", of which X matched the regex" text, and inBitps/outBitps per interface) under the label "general linter and style fixes", which broke existing RRD graph definitions that expect the old field layout. This adds an opt-in --legacy-perfdata flag that restores the exact pre-1.4.4 output for users who need to keep existing RRDs working, while leaving the new, richer default format untouched for everyone else. No change to default behavior when the flag is not given. --- check_interfaces.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/check_interfaces.c b/check_interfaces.c index 5496c5f..2797768 100644 --- a/check_interfaces.c +++ b/check_interfaces.c @@ -81,6 +81,8 @@ static char *oid_vals_cisco[] = {".1.3.6.1.2.1.2.2.1.7", /* ifAdminStatus * */ static const char *modes[] = {"default", "cisco", "nonbulk", "bintec", NULL}; +static bool legacy_perfdata_flag = false; + #ifdef DEBUG static char *implode_result; #endif @@ -953,12 +955,18 @@ returncode_t print_output(struct configuration_struct *config, struct ifStruct * } /* now print performance data */ - + if (legacy_perfdata_flag) { + printf("%*s | interfaces::check_multi::plugins=%d time=%.2Lf", (int)out->len, + out->text, number_of_matched_interfaces, + (((long double)time_value->tv_sec + ((long double)time_value->tv_usec / 1000000)) - + starttime)); + } else { printf("%*s | interfaces::check_multi::plugins=%d time=%.2Lf checktime=%ld", (int)out->len, out->text, number_of_matched_interfaces, (((long double)time_value->tv_sec + ((long double)time_value->tv_usec / 1000000)) - starttime), time_value->tv_sec); + } if (uptime) { printf(" %sdevice::check_snmp::uptime=%us", config->prefix ? config->prefix : "", uptime); } @@ -980,8 +988,10 @@ returncode_t print_output(struct configuration_struct *config, struct ifStruct * } else { printf(" %s=%llu", if_vars[8], interfaces[i].speed); } + if (!legacy_perfdata_flag) { printf(" %s=%llub %s=%llub", if_vars[9], interfaces[i].inbitps, if_vars[10], interfaces[i].outbitps); + } } } printf("\n%*s", (int)perf.len, perf.text); @@ -1289,6 +1299,7 @@ void parse_and_check_commandline(int argc, char **argv, struct configuration_str {"sleep", required_argument, NULL, 3}, {"retries", required_argument, NULL, 4}, {"max-repetitions", required_argument, NULL, 5}, + {"legacy-perfdata", no_argument, NULL, 6}, {"version", no_argument, NULL, VERSION_OPTION}, {NULL, 0, NULL, 0}}; @@ -1388,6 +1399,9 @@ void parse_and_check_commandline(int argc, char **argv, struct configuration_str case 5: config->pdu_max_repetitions = strtol(optarg, NULL, 10); break; + case 6: + legacy_perfdata_flag = true; + break; case VERSION_OPTION: print_version(); case '?': @@ -1512,6 +1526,8 @@ int usage(char *progname) { printf(" --retries\t\thow often to retry before giving up\n"); printf(" --max-repetitions\t\tsee " "\n"); + printf(" --legacy-perfdata\t\tuse the pre-1.4.4 perfdata format " + "(no checktime=, no \", of which X matched\", no inBitps/outBitps)\n"); printf(" --port\t\tPort (default 161)\n"); printf(" --version\t\tPrint program version\n"); printf("\n"); From 4f253bc4035e0dbf821c833d6295affe4a054d54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20M=C3=BCcklich=20ITO?= Date: Thu, 9 Jul 2026 14:27:38 +0200 Subject: [PATCH 2/3] perfdata: fix plugins= count to match actually printed blocks plugins= in the check_multi header used number_of_matched_interfaces (i.e. how many interfaces matched the regex), but the loop below only prints a check_snmp block for interfaces that are neither ignored nor administratively down. This mismatch (e.g. plugins=44 while only 4 blocks are actually printed, because 40 of the 44 matched interfaces are administratively down) can confuse RRD/check_multi consumers that rely on this count to know how many data sources to expect. plugins= now reflects the actual number of printed blocks, independent of --legacy-perfdata. The ", of which X matched the regex" status text is unaffected, since that's meant to report the raw regex match count regardless of admin-down status. --- check_interfaces.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/check_interfaces.c b/check_interfaces.c index 2797768..0584d4c 100644 --- a/check_interfaces.c +++ b/check_interfaces.c @@ -733,6 +733,14 @@ returncode_t print_output(struct configuration_struct *config, struct ifStruct * unsigned int parsed_lastcheck = 0; + unsigned int printed_count = 0; + + for (int i = 0; i < ifNumber; i++) { + if (!interfaces[i].ignore && (!interfaces[i].admin_down || config->print_all_flag)) { + printed_count++; + } + } + if (config->oldperfdatap && config->oldperfdatap[0]) { parse_perfdata(config->oldperfdatap, oldperfdata, config->prefix, &parsed_lastcheck, ifNumber, if_vars); @@ -957,12 +965,12 @@ returncode_t print_output(struct configuration_struct *config, struct ifStruct * /* now print performance data */ if (legacy_perfdata_flag) { printf("%*s | interfaces::check_multi::plugins=%d time=%.2Lf", (int)out->len, - out->text, number_of_matched_interfaces, + out->text, printed_count, (((long double)time_value->tv_sec + ((long double)time_value->tv_usec / 1000000)) - starttime)); } else { printf("%*s | interfaces::check_multi::plugins=%d time=%.2Lf checktime=%ld", (int)out->len, - out->text, number_of_matched_interfaces, + out->text, printed_count, (((long double)time_value->tv_sec + ((long double)time_value->tv_usec / 1000000)) - starttime), time_value->tv_sec); From a88500ef48f0c7d403cd18811600b1dd36524ee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20M=C3=BCcklich=20ITO?= Date: Thu, 9 Jul 2026 14:37:50 +0200 Subject: [PATCH 3/3] docs: document --legacy-perfdata flag and plugins= count fix --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 203e1fb..8609d20 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,12 @@ sudo make install ## optional --timeout sets the SNMP timeout (in ms) -m|--mode special operating mode (default,cisco,nonbulk,bintec) Workarounds for various hardware - + --legacy-perfdata restore the pre-1.4.4 performance data format + Omits checktime=, the ", of which X matched the regex" status + text, and per-interface inBitps/outBitps fields, matching the + exact output of versions before 1.4.4. Use this if you have + existing RRD/PNP4Nagios graph definitions that expect the old + field layout and would otherwise break on upgrade. ### Modes