[Patch] IPv6 capable check_* for nagios

Jeremy T. Bouse jeremy+nagios at undergrid.net
Fri Aug 8 17:47:05 CEST 2003


	A look at the CVS HEAD of the nagios plugins would find that
full AF-independent support is already available at this time.

	Regards,
	Jeremy

On Fri, Aug 08, 2003 at 04:36:38PM +0100, Colm MacCarthaigh wrote:
> 
> I don't know if a patch exists already, but since the version of nagios
> plugins I downloaded today (1.3.1) doesnt support IPv6 I've patched 
> plugins/netutils.c to be ipv6 compatible. Patch is attached :)
> 
> This makes many of the check_ plugins for netsaint/nagios work with
> ipv6/v4 , it also handles things like round-robin DNS more properly.
> 
> Please CC on any mails, I'm not on the list :)
> 
> -- 
> Colm MacC?rthaigh  /  HEAnet, Teach Brooklawn,  / Innealt?ir Ghr?as?in
> +353 1 6609040    / B?thar Shelbourne, B?C, IE /   http://www.hea.net/

> diff -ru nagios-plugins-1.3.1/plugins/netutils.c nagios-plugins-1.3.1.heanet/plugins/netutils.c
> --- nagios-plugins-1.3.1/plugins/netutils.c	Thu Feb 28 06:42:59 2002
> +++ nagios-plugins-1.3.1.heanet/plugins/netutils.c	Fri Aug  8 16:28:22 2003
> @@ -48,8 +48,6 @@
>  int my_udp_connect (char *, int, int *);
>  int my_connect (char *, int, int *, char *);
>  
> -int my_inet_aton (register const char *, struct in_addr *);
> -
>  /* handles socket timeouts */
>  void
>  socket_timeout_alarm_handler (int sig)
> @@ -265,45 +263,53 @@
>  int
>  my_connect (char *host_name, int port, int *sd, char *proto)
>  {
> -	struct sockaddr_in servaddr;
> -	struct hostent *hp;
> -	struct protoent *ptrp;
> -	int result;
> +	struct addrinfo	* res, hints;
> +	char   str_port[6];
> +	int   result;
> +
> +	bzero ((char *) &hints, sizeof(hints));
> +	hints.ai_family = PF_UNSPEC;
> +	hints.ai_socktype = (!strcmp (proto, "udp")) ? SOCK_DGRAM : SOCK_STREAM;
> +	snprintf(str_port, sizeof(str_port), "%d", port);
>  
> -	bzero ((char *) &servaddr, sizeof (servaddr));
> -	servaddr.sin_family = AF_INET;
> -	servaddr.sin_port = htons (port);
> +	/* map transport protocol name to protocol number */
> +	if (getprotobyname (proto) == NULL) {
> +		printf ("Cannot map \"%s\" to protocol number\n", proto);
> +		return STATE_UNKNOWN;
> +	}
>  
>  	/* try to bypass using a DNS lookup if this is just an IP address */
> -	if (!my_inet_aton (host_name, &servaddr.sin_addr)) {
> -
> -		/* else do a DNS lookup */
> -		hp = gethostbyname ((const char *) host_name);
> -		if (hp == NULL) {
> +	hints.ai_flags = AI_NUMERICHOST;
> +        if ( getaddrinfo( host_name, str_port, &hints, &res ) < 0 ) {
> +			
> +		hints.ai_flags = 0x0;
> +		
> +		if (getaddrinfo( host_name, str_port, &hints, &res) < 0 ) {
>  			printf ("Invalid host name '%s'\n", host_name);
>  			return STATE_UNKNOWN;
>  		}
> -
> -		memcpy (&servaddr.sin_addr, hp->h_addr, hp->h_length);
> -	}
> -
> -	/* map transport protocol name to protocol number */
> -	if ((ptrp = getprotobyname (proto)) == NULL) {
> -		printf ("Cannot map \"%s\" to protocol number\n", proto);
> -		return STATE_UNKNOWN;
>  	}
>  
>  	/* create a socket */
> -	*sd =
> -		socket (PF_INET, (!strcmp (proto, "udp")) ? SOCK_DGRAM : SOCK_STREAM,
> -						ptrp->p_proto);
> -	if (*sd < 0) {
> -		printf ("Socket creation failed\n");
> -		return STATE_UNKNOWN;
> -	}
> +	do {
> +		*sd = socket (res->ai_family, res->ai_socktype, res->ai_protocol);
> +
> +		if (*sd < 0) {
> +			printf ("Socket creation failed\n");
> +			return STATE_UNKNOWN;
> +		}
> +
> +		/* open a connection */
> +		if ( (result = connect (*sd, (struct sockaddr *) res->ai_addr, 
> +				res->ai_addrlen )) >= 0) {
> +			/* Success */
> +			break;
> +		}
> +
> +		res = res->ai_next;
> +	} while (res);
>  
> -	/* open a connection */
> -	result = connect (*sd, (struct sockaddr *) &servaddr, sizeof (servaddr));
> +	/* None of the records matched */
>  	if (result < 0) {
>  		switch (errno) {
>  		case ECONNREFUSED:
> @@ -323,109 +329,4 @@
>  	}
>  
>  	return STATE_OK;
> -}
> -
> -
> -
> -/* This code was taken from Fyodor's nmap utility, which was originally
> -	 taken from the GLIBC 2.0.6 libraries because Solaris doesn't contain
> -	 the inet_aton() funtion. */
> -int
> -my_inet_aton (register const char *cp, struct in_addr *addr)
> -{
> -	register unsigned int val;		/* changed from u_long --david */
> -	register int base, n;
> -	register char c;
> -	u_int parts[4];
> -	register u_int *pp = parts;
> -
> -	c = *cp;
> -
> -	for (;;) {
> -
> -		/*
> -		 * Collect number up to ``.''.
> -		 * Values are specified as for C:
> -		 * 0x=hex, 0=octal, isdigit=decimal.
> -		 */
> -		if (!isdigit ((int) c))
> -			return (0);
> -		val = 0;
> -		base = 10;
> -
> -		if (c == '0') {
> -			c = *++cp;
> -			if (c == 'x' || c == 'X')
> -				base = 16, c = *++cp;
> -			else
> -				base = 8;
> -		}
> -
> -		for (;;) {
> -			if (isascii ((int) c) && isdigit ((int) c)) {
> -				val = (val * base) + (c - '0');
> -				c = *++cp;
> -			}
> -			else if (base == 16 && isascii ((int) c) && isxdigit ((int) c)) {
> -				val = (val << 4) | (c + 10 - (islower ((int) c) ? 'a' : 'A'));
> -				c = *++cp;
> -			}
> -			else
> -				break;
> -		}
> -
> -		if (c == '.') {
> -
> -			/*
> -			 * Internet format:
> -			 *  a.b.c.d
> -			 *  a.b.c (with c treated as 16 bits)
> -			 *  a.b (with b treated as 24 bits)
> -			 */
> -			if (pp >= parts + 3)
> -				return (0);
> -			*pp++ = val;
> -			c = *++cp;
> -		}
> -		else
> -			break;
> -	}
> -
> -	/* Check for trailing characters */
> -	if (c != '\0' && (!isascii ((int) c) || !isspace ((int) c)))
> -		return (0);
> -
> -	/* Concoct the address according to the number of parts specified */
> -	n = pp - parts + 1;
> -	switch (n) {
> -
> -	case 0:
> -		return (0);									/* initial nondigit */
> -
> -	case 1:											/* a -- 32 bits */
> -		break;
> -
> -	case 2:											/* a.b -- 8.24 bits */
> -		if (val > 0xffffff)
> -			return (0);
> -		val |= parts[0] << 24;
> -		break;
> -
> -	case 3:											/* a.b.c -- 8.8.16 bits */
> -		if (val > 0xffff)
> -			return (0);
> -		val |= (parts[0] << 24) | (parts[1] << 16);
> -		break;
> -
> -	case 4:											/* a.b.c.d -- 8.8.8.8 bits */
> -		if (val > 0xff)
> -			return (0);
> -		val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
> -		break;
> -	}
> -
> -	if (addr)
> -		addr->s_addr = htonl (val);
> -
> -	return (1);
>  }

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <https://www.monitoring-lists.org/archive/developers/attachments/20030808/237fde5d/attachment.sig>


More information about the Developers mailing list