diff options
author | Jacob Hansen <jhansen@op5.com> | 2018-11-29 16:02:10 +0100 |
---|---|---|
committer | Jacob Hansen <jhansen@op5.com> | 2018-12-07 09:51:21 +0000 |
commit | 8edac9421f8ce28ab51917de4e056ac609eadd49 (patch) | |
tree | 18593df5397aa1b266b5230526cb4391fd517e46 | |
parent | 248bebb037b4ac3a184706ec715f82a6ed4749a5 (diff) | |
download | monitoring-plugins-8edac9421f8ce28ab51917de4e056ac609eadd49.tar.gz |
check_icmp: Automatically detect IP protocol
This patch automatically detects whether the protocol version is IPv4 or
IPv6
All credits to: https://github.com/ghciv6
Signed-off-by: Jacob Hansen <jhansen@op5.com>
-rw-r--r-- | plugins-root/check_icmp.c | 71 |
1 files changed, 45 insertions, 26 deletions
diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c index 4c17d239..cab69fda 100644 --- a/plugins-root/check_icmp.c +++ b/plugins-root/check_icmp.c | |||
@@ -419,7 +419,7 @@ main(int argc, char **argv) | |||
419 | * that before pointer magic (esp. on network data) */ | 419 | * that before pointer magic (esp. on network data) */ |
420 | icmp_sockerrno = udp_sockerrno = tcp_sockerrno = sockets = 0; | 420 | icmp_sockerrno = udp_sockerrno = tcp_sockerrno = sockets = 0; |
421 | 421 | ||
422 | address_family = AF_INET; | 422 | address_family = -1; |
423 | int icmp_proto = IPPROTO_ICMP; | 423 | int icmp_proto = IPPROTO_ICMP; |
424 | 424 | ||
425 | /* get calling name the old-fashioned way for portability instead | 425 | /* get calling name the old-fashioned way for portability instead |
@@ -526,12 +526,10 @@ main(int argc, char **argv) | |||
526 | break; | 526 | break; |
527 | case '4': | 527 | case '4': |
528 | address_family = AF_INET; | 528 | address_family = AF_INET; |
529 | icmp_proto = IPPROTO_ICMP; | ||
530 | break; | 529 | break; |
531 | case '6': | 530 | case '6': |
532 | #ifdef USE_IPV6 | 531 | #ifdef USE_IPV6 |
533 | address_family = AF_INET6; | 532 | address_family = AF_INET6; |
534 | icmp_proto = IPPROTO_ICMPV6; | ||
535 | #else | 533 | #else |
536 | usage (_("IPv6 support not available\n")); | 534 | usage (_("IPv6 support not available\n")); |
537 | #endif | 535 | #endif |
@@ -540,29 +538,6 @@ main(int argc, char **argv) | |||
540 | } | 538 | } |
541 | } | 539 | } |
542 | 540 | ||
543 | if((icmp_sock = socket(address_family, SOCK_RAW, icmp_proto)) != -1) | ||
544 | sockets |= HAVE_ICMP; | ||
545 | else icmp_sockerrno = errno; | ||
546 | |||
547 | /* if((udp_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) != -1) */ | ||
548 | /* sockets |= HAVE_UDP; */ | ||
549 | /* else udp_sockerrno = errno; */ | ||
550 | |||
551 | /* if((tcp_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) != -1) */ | ||
552 | /* sockets |= HAVE_TCP; */ | ||
553 | /* else tcp_sockerrno = errno; */ | ||
554 | |||
555 | /* now drop privileges (no effect if not setsuid or geteuid() == 0) */ | ||
556 | if (setuid(getuid()) == -1) { | ||
557 | printf("ERROR: Failed to drop privileges\n"); | ||
558 | return 1; | ||
559 | } | ||
560 | |||
561 | #ifdef SO_TIMESTAMP | ||
562 | if(setsockopt(icmp_sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on))) | ||
563 | if(debug) printf("Warning: no SO_TIMESTAMP support\n"); | ||
564 | #endif // SO_TIMESTAMP | ||
565 | |||
566 | /* POSIXLY_CORRECT might break things, so unset it (the portable way) */ | 541 | /* POSIXLY_CORRECT might break things, so unset it (the portable way) */ |
567 | environ = NULL; | 542 | environ = NULL; |
568 | 543 | ||
@@ -593,6 +568,37 @@ main(int argc, char **argv) | |||
593 | exit(3); | 568 | exit(3); |
594 | } | 569 | } |
595 | 570 | ||
571 | // add_target might change address_family | ||
572 | switch ( address_family ){ | ||
573 | case AF_INET: icmp_proto = IPPROTO_ICMP; | ||
574 | break; | ||
575 | case AF_INET6: icmp_proto = IPPROTO_ICMPV6; | ||
576 | break; | ||
577 | default: crash("Address family not supported"); | ||
578 | } | ||
579 | if((icmp_sock = socket(address_family, SOCK_RAW, icmp_proto)) != -1) | ||
580 | sockets |= HAVE_ICMP; | ||
581 | else icmp_sockerrno = errno; | ||
582 | |||
583 | /* if((udp_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) != -1) */ | ||
584 | /* sockets |= HAVE_UDP; */ | ||
585 | /* else udp_sockerrno = errno; */ | ||
586 | |||
587 | /* if((tcp_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) != -1) */ | ||
588 | /* sockets |= HAVE_TCP; */ | ||
589 | /* else tcp_sockerrno = errno; */ | ||
590 | |||
591 | #ifdef SO_TIMESTAMP | ||
592 | if(setsockopt(icmp_sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on))) | ||
593 | if(debug) printf("Warning: no SO_TIMESTAMP support\n"); | ||
594 | #endif // SO_TIMESTAMP | ||
595 | |||
596 | /* now drop privileges (no effect if not setsuid or geteuid() == 0) */ | ||
597 | if (setuid(getuid()) == -1) { | ||
598 | printf("ERROR: Failed to drop privileges\n"); | ||
599 | return 1; | ||
600 | } | ||
601 | |||
596 | if(!sockets) { | 602 | if(!sockets) { |
597 | if(icmp_sock == -1) { | 603 | if(icmp_sock == -1) { |
598 | errno = icmp_sockerrno; | 604 | errno = icmp_sockerrno; |
@@ -1319,6 +1325,19 @@ add_target(char *arg) | |||
1319 | struct sockaddr_in6 *sin6; | 1325 | struct sockaddr_in6 *sin6; |
1320 | 1326 | ||
1321 | switch (address_family) { | 1327 | switch (address_family) { |
1328 | case -1: | ||
1329 | // -4 and -6 are not specified on cmdline | ||
1330 | address_family = AF_INET; | ||
1331 | sin = (struct sockaddr_in *)&ip; | ||
1332 | result = inet_pton(address_family, arg, &sin->sin_addr); | ||
1333 | #ifdef USE_IPV6 | ||
1334 | if( result != 1 ){ | ||
1335 | address_family = AF_INET6; | ||
1336 | sin6 = (struct sockaddr_in6 *)&ip; | ||
1337 | result = inet_pton(address_family, arg, &sin6->sin6_addr); | ||
1338 | } | ||
1339 | #endif | ||
1340 | break; | ||
1322 | case AF_INET: | 1341 | case AF_INET: |
1323 | sin = (struct sockaddr_in *)&ip; | 1342 | sin = (struct sockaddr_in *)&ip; |
1324 | result = inet_pton(address_family, arg, &sin->sin_addr); | 1343 | result = inet_pton(address_family, arg, &sin->sin_addr); |