diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2020-02-13 15:28:56 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2020-02-13 15:28:56 +0200 |
commit | 4263bf8b57b7d8a0b5f73a586c55e9ee2a07b6ca (patch) | |
tree | 8489b1f0ec53564fc780f480a3a75804e9d4e6e2 /src/ping903q.c | |
parent | 47bed8e5bc0e1a58e10c6237d27ce578bb50d7d6 (diff) | |
download | ping903-4263bf8b57b7d8a0b5f73a586c55e9ee2a07b6ca.tar.gz ping903-4263bf8b57b7d8a0b5f73a586c55e9ee2a07b6ca.tar.bz2 |
Implement IP lookup and match mode.
* src/ping903.c: Implement two new endpoints: /ip and /match, for
IP lookup and match mode.
* src/ping903.h (get_ipaddr_stat)
(get_host_matches): New protos.
* src/pinger.c (get_ipaddr_stat)
(get_host_matches): New functions.
* src/ping903q.c (resolve_ip): New global.
(query_host): Use /host or /ip depending on the value of resolve_ip.
(match_host): New function.
* doc/ping903q.1: Update.
Diffstat (limited to 'src/ping903q.c')
-rw-r--r-- | src/ping903q.c | 120 |
1 files changed, 109 insertions, 11 deletions
diff --git a/src/ping903q.c b/src/ping903q.c index fdef668..7007745 100644 --- a/src/ping903q.c +++ b/src/ping903q.c @@ -17,6 +17,7 @@ static char *config_file = DEFAULT_CONFIG_FILE; FILE *http; int verbose; +int resolve_ip; char const http_version[] = "HTTP/1.1"; enum { @@ -487,7 +488,12 @@ query_host(char const *name, int (*report)(struct json_value *, void *), char *ipstr = resolve_host(name); ssize_t n; - n = snprintf(url, sizeof(url), "/host/%s", ipstr); + if (resolve_ip) { + n = snprintf(url, sizeof(url), "/ip/%s", ipstr); + } else { + n = snprintf(url, sizeof(url), "/host/%s", name); + } + if (n < 0 || n == sizeof(url)) { abend("bad host name or IP"); } @@ -514,6 +520,56 @@ query_host(char const *name, int (*report)(struct json_value *, void *), } static void +match_host(char const *name) +{ + int rc; + struct http_resp resp; + struct json_value *obj; + char url[1024]; + char const *hval; + char *p; + ssize_t n; + size_t i, len; + + n = snprintf(url, sizeof(url), "/match/%s", name); + http_query("GET", url, std_headers); + http_resp_init(&resp); + http_recv(&resp); + if (resp.code != 200) { + abend("%s", resp.reason); + } + + hval = http_resp_get_header(&resp, "content-type"); + if (!hval || strcmp(hval, "application/json")) { + abend("missing or unsupported content type"); + } + + rc = json_parse_string(resp.content, &obj, &p); + if (rc != JSON_E_NOERR) + abend("%s near %s", json_strerror(rc), p); + if (obj->type != json_array) + abend("returned entity has wrong type"); + + len = json_array_length(obj); + if (json_array_length(obj) == 0) { + if (verbose) + error("no matching hosts found"); + exit(EX_NAGIOS_CRITICAL); + } + + for (i = 0; i < len; i++) { + struct json_value *jv; + if (json_array_get(obj, i, &jv)) { + abend("can't get element %lu", (unsigned long) i); + } + if (jv->type != json_string) + abend("bad type of element %lu", (unsigned long) i); + printf("%s\n", jv->v.s); + } + exit(EX_NAGIOS_OK); +} + +static void query_all(void) { int rc; @@ -643,13 +699,15 @@ nagios_check(struct json_value *obj, void *data) void usage(void) { - printf("Usage: %s [-hVv] [-f FILE] [HOST]\n", progname); + printf("Usage: %s [-hrVv] [-f FILE] [HOST]\n", progname); printf(" or: %s -H HOST -c RTA,PCT%% -w RTA,PCT%%\n", progname); + printf(" or: %s -m HOST\n", progname); printf("Query ping903 daemon.\n"); printf("\n"); printf("Options:\n\n"); printf(" -f FILE read configuration from FILE\n"); printf(" -h print this help test\n"); + printf(" -r resolve HOST to IP address\n"); printf(" -V print program version and exit\n"); printf(" -v additional verbosity\n"); printf("\nNagios check mode:\n\n"); @@ -657,6 +715,8 @@ usage(void) printf(" -c RTA,PCT%% set critical threshold\n"); printf(" -w RTA,PCT%% set warning threshold\n"); printf("\n(all three must be given in this mode)\n"); + printf("\nMatch mode:\n\n"); + printf(" -m check whether HOST is monitored\n"); printf("\n"); printf("Report bugs to <%s>.\n", PACKAGE_BUGREPORT); printf("%s home page: <%s>\n", PACKAGE_NAME, PACKAGE_URL); @@ -669,12 +729,29 @@ version(void) printf("%s", COPYLEFT); } +enum { + MODE_DEFAULT, + MODE_NAGIOS_CHECK, + MODE_MATCH +}; + +static int mode = MODE_DEFAULT; +static int mode_opt = 0; +static inline void +setmode(int newmode, int opt) +{ + if (mode != MODE_DEFAULT && mode != newmode) + abend("option -%d conflicts with -%d", opt, mode_opt); + mode = newmode; + mode_opt = opt; +} + + int main(int argc, char **argv) { int c; char *p, *node, *service; - int nagios_check_mode = 0; char const *host = NULL; char *c_opt = NULL; char *w_opt = NULL; @@ -692,22 +769,28 @@ main(int argc, char **argv) exit(0); } } - while ((c = getopt(argc, argv, "c:f:H:hVvw:")) != EOF) { + while ((c = getopt(argc, argv, "c:f:H:hmrVvw:")) != EOF) { switch (c) { case 'c': c_opt = optarg; - nagios_check_mode = 1; + setmode(MODE_NAGIOS_CHECK, c); break; case 'f': config_file = optarg; break; case 'H': host = optarg; - nagios_check_mode = 1; + setmode(MODE_NAGIOS_CHECK, c); break; case 'h': usage(); exit(0); + case 'm': + setmode(MODE_MATCH, c); + break; + case 'r': + resolve_ip = 1; + break; case 'V': version(); exit(0); @@ -716,7 +799,7 @@ main(int argc, char **argv) break; case 'w': w_opt = optarg; - nagios_check_mode = 1; + setmode(MODE_NAGIOS_CHECK, c); break; default: exit(EX_NAGIOS_UNKNOWN); @@ -725,7 +808,10 @@ main(int argc, char **argv) argc -= optind; argv += optind; - if (nagios_check_mode) { + switch (mode) { + case MODE_DEFAULT: + break; + case MODE_NAGIOS_CHECK: if (argc != 0) { abend("bad number of arguments"); } @@ -738,6 +824,11 @@ main(int argc, char **argv) if (!w_opt) abend("warning threshold missing; use -w option"); parse_nagios_threshold(w_opt, &chkdata.wth); + break; + case MODE_MATCH: + if (argc != 1) + abend("-m requires exactly one command line argument"); + break; } p = node = read_listen(&service); @@ -748,9 +839,8 @@ main(int argc, char **argv) http_connect(node, service); free(p); - if (nagios_check_mode) - query_host(host, nagios_check, &chkdata); - else { + switch (mode) { + case MODE_DEFAULT: switch (argc) { case 0: query_all(); @@ -759,6 +849,14 @@ main(int argc, char **argv) default: abend("bad number of arguments"); } + break; + + case MODE_NAGIOS_CHECK: + query_host(host, nagios_check, &chkdata); + break; + + case MODE_MATCH: + match_host(argv[0]); } exit(EX_NAGIOS_UNKNOWN); } |