[monitoring-plugins] check_icmp: Automatically detect IP protocol

Jacob Hansen git at monitoring-plugins.org
Tue Feb 19 15:50:16 CET 2019


 Module: monitoring-plugins
 Branch: master
 Commit: 8edac9421f8ce28ab51917de4e056ac609eadd49
 Author: Jacob Hansen <jhansen at op5.com>
   Date: Thu Nov 29 16:02:10 2018 +0100
    URL: https://www.monitoring-plugins.org/repositories/monitoring-plugins/commit/?id=8edac94

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 at op5.com>

---

 plugins-root/check_icmp.c | 71 ++++++++++++++++++++++++++++++-----------------
 1 file changed, 45 insertions(+), 26 deletions(-)

diff --git a/plugins-root/check_icmp.c b/plugins-root/check_icmp.c
index 4c17d23..cab69fd 100644
--- a/plugins-root/check_icmp.c
+++ b/plugins-root/check_icmp.c
@@ -419,7 +419,7 @@ main(int argc, char **argv)
 	 * that before pointer magic (esp. on network data) */
 	icmp_sockerrno = udp_sockerrno = tcp_sockerrno = sockets = 0;
 
-        address_family = AF_INET;
+        address_family = -1;
 	int icmp_proto = IPPROTO_ICMP;
 
 	/* get calling name the old-fashioned way for portability instead
@@ -526,12 +526,10 @@ main(int argc, char **argv)
 				break;
 			case '4':
 				address_family = AF_INET;
-				icmp_proto = IPPROTO_ICMP;
 				break;
 			case '6':
 #ifdef USE_IPV6
 				address_family = AF_INET6;
-				icmp_proto = IPPROTO_ICMPV6;
 #else
 				usage (_("IPv6 support not available\n"));
 #endif
@@ -540,29 +538,6 @@ main(int argc, char **argv)
 		}
 	}
 
-	if((icmp_sock = socket(address_family, SOCK_RAW, icmp_proto)) != -1)
-		sockets |= HAVE_ICMP;
-	else icmp_sockerrno = errno;
-
-	/* if((udp_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) != -1) */
-	/* 	sockets |= HAVE_UDP; */
-	/* else udp_sockerrno = errno; */
-
-	/* if((tcp_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) != -1) */
-	/* 	sockets |= HAVE_TCP; */
-	/* else tcp_sockerrno = errno; */
-
-	/* now drop privileges (no effect if not setsuid or geteuid() == 0) */
-	if (setuid(getuid()) == -1) {
-		printf("ERROR: Failed to drop privileges\n");
-		return 1;
-	}
-
-#ifdef SO_TIMESTAMP
-	if(setsockopt(icmp_sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)))
-	  if(debug) printf("Warning: no SO_TIMESTAMP support\n");
-#endif // SO_TIMESTAMP
-
 	/* POSIXLY_CORRECT might break things, so unset it (the portable way) */
 	environ = NULL;
 
@@ -593,6 +568,37 @@ main(int argc, char **argv)
 		exit(3);
 	}
 
+	// add_target might change address_family
+	switch ( address_family ){
+		case AF_INET:	icmp_proto = IPPROTO_ICMP;
+				break;
+		case AF_INET6:	icmp_proto = IPPROTO_ICMPV6;
+				break;
+		default:	crash("Address family not supported");
+	}
+	if((icmp_sock = socket(address_family, SOCK_RAW, icmp_proto)) != -1)
+		sockets |= HAVE_ICMP;
+	else icmp_sockerrno = errno;
+
+	/* if((udp_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) != -1) */
+	/* 	sockets |= HAVE_UDP; */
+	/* else udp_sockerrno = errno; */
+
+	/* if((tcp_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) != -1) */
+	/* 	sockets |= HAVE_TCP; */
+	/* else tcp_sockerrno = errno; */
+
+#ifdef SO_TIMESTAMP
+	if(setsockopt(icmp_sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)))
+	  if(debug) printf("Warning: no SO_TIMESTAMP support\n");
+#endif // SO_TIMESTAMP
+
+	/* now drop privileges (no effect if not setsuid or geteuid() == 0) */
+	if (setuid(getuid()) == -1) {
+		printf("ERROR: Failed to drop privileges\n");
+		return 1;
+	}
+
 	if(!sockets) {
 		if(icmp_sock == -1) {
 			errno = icmp_sockerrno;
@@ -1319,6 +1325,19 @@ add_target(char *arg)
 	struct sockaddr_in6 *sin6;
 
 	switch (address_family) {
+	case -1:
+		// -4 and -6 are not specified on cmdline
+		address_family = AF_INET;
+		sin = (struct sockaddr_in *)&ip;
+		result = inet_pton(address_family, arg, &sin->sin_addr);
+#ifdef USE_IPV6
+		if( result != 1 ){
+			address_family = AF_INET6;
+			sin6 = (struct sockaddr_in6 *)&ip;
+			result = inet_pton(address_family, arg, &sin6->sin6_addr);
+		}
+#endif
+		break;
 	case AF_INET:
 		sin = (struct sockaddr_in *)&ip;
 		result = inet_pton(address_family, arg, &sin->sin_addr);



More information about the Commits mailing list