Hi,

the attached 700+ lines monstrosity implements IPv6 support for nrpe
and check_nrpe by switching socket related code to getaddrinfo.

As getaddrinfo expects a char* as second argument for the service name
from /etc/services or decimal port it's more convenient to treat the
port as string from configure.in downwards.

Because of the switch to getaddrinfo in wait_for_connections
(src/nrpe.c) it's now possible to configure a name for
server_address. However depending on you DNS configuration this might
not result in what you expect. If you have an AAAA and A
record for the name you will only get an IPv6 socket because
wait_for_connections only accepts on the *first* addrinfo to which it
can bind.
There is a similar problem with leaving server_address empty. This
will result in a socket listening on in6addr_any. On a default
GNU/Linux installation you get a socket listening on IPv4 and IPv6
because IPv4 connects are mapped to the IPv6 socket. This behavior can
be changed in /proc. On systems like OpenBSD which by choice do not
implement this mapping you will only get an IPv6 socket.
In any case it appears to be best to configure an explicit IP address
for server_address.

is_an_allowed_host (src/nrpe.c) now compares sockaddr structs using
new helper function sockaddr_equal (src/utils.c).

get_ip_str and get_port helper functions (src/utils.c) were taken from
/ inspired by Owen DeLong's IPv6 Porting Information
( http://owend.corp.he.net/ipv6/ ).
sockaddr_equal was inspired by similar code in samba

The patch tries to mimic the style of the surrounding code, e.g. no
line breaks after 80 characters, closing brackets on the same level as
the containing block.

We are using the patch in production at the company I work for since
about a week. We are monitoring approximately 400 hosts and each host
has at least four check_nrpe checks. We replaced the check_nrpe binary
with the patched version so all check_nrpe checks use the patch.
We are using the patched nrpe daemon on three IPv6 only hosts and on
one dual stacked host. All other hosts use the unpatched nrpe daemon
from nagios.
So far we didn't see any problems.

The patch was tested on OpenBSD 4.7 and Debian Lenny. Additionally 10k
checks were send to the nrpe daemon in a tight loop and no memory leak
was observed. (If there are leaks they should be contained in forked
processes which die quickly.)

I tried to send the patch inline and while my mail client didn't touch
the long lines it non the less managed to mangle the patch in ways
that it would no longer apply. If the attachment is filtered / lost
you can pull from:
git://github.com/fobser/icinga-nrpe-ipv6.git

Best regards,

Florian
diff --git a/configure b/configure
index 40c5730..d18cc51 100755
--- a/configure
+++ b/configure
@@ -7224,7 +7224,7 @@ NRPE_INSTALL_OPTS="-o $nrpe_user -g $nrpe_group"
 
 
 cat >>confdefs.h <<_ACEOF
-#define DEFAULT_SERVER_PORT $nrpe_port
+#define DEFAULT_SERVER_PORT "$nrpe_port"
 _ACEOF
 
 
diff --git a/configure.in b/configure.in
index b3db2cf..0d3043c 100644
--- a/configure.in
+++ b/configure.in
@@ -352,7 +352,7 @@ AC_SUBST(nrpe_group)
 NRPE_INSTALL_OPTS="-o $nrpe_user -g $nrpe_group"
 AC_SUBST(NRPE_INSTALL_OPTS)
 AC_SUBST(nrpe_port)
-AC_DEFINE_UNQUOTED(DEFAULT_SERVER_PORT,$nrpe_port)
+AC_DEFINE_UNQUOTED(DEFAULT_SERVER_PORT,["$nrpe_port"])
 
 AC_ARG_WITH(icinga_user,--with-icinga-user=<user> sets user name for file permissions,icinga_user=$withval,icinga_user=icinga)
 AC_ARG_WITH(icinga_group,--with-icinga-group=<grp> sets group name file permissions,icinga_group=$withval,icinga_group=icinga)
diff --git a/include/nrpe.h b/include/nrpe.h
index bb4a383..4d6c574 100644
--- a/include/nrpe.h
+++ b/include/nrpe.h
@@ -47,7 +47,7 @@ int write_pid_file(void);
 int remove_pid_file(void);
 
 void free_memory(void);
-int is_an_allowed_host(char *);
+int is_an_allowed_host(const struct sockaddr *);
 int validate_request(packet *);
 int contains_nasty_metachars(char *);
 int process_macros(char *,char *,int);
@@ -57,5 +57,3 @@ void my_connection_sighandler(int);			/* handles timeouts of connection */
 
 void sighandler(int);
 void child_sighandler(int);
-
-
diff --git a/include/utils.h b/include/utils.h
index 7666f38..2c6b1a5 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -40,10 +40,7 @@ unsigned long calculate_crc32(char *, int);
 
 void randomize_buffer(char *,int);
 
-int my_tcp_connect(char *,int,int *);
-int my_connect(char *,int,int *,char *);
-
-int my_inet_aton(register const char *,struct in_addr *);
+int my_tcp_connect(char *,char *,int *);
 
 void strip(char *);
 
@@ -54,9 +51,7 @@ char *my_strsep(char **,const char *);
 
 void display_license(void);
 
+char *get_ip_str(const struct sockaddr *, char *, size_t);
+int get_port(const struct sockaddr *);
+int sockaddr_equal(const struct sockaddr *, const struct sockaddr *);
 #endif
-
-
-
-
-
diff --git a/src/check_nrpe.c b/src/check_nrpe.c
index 47e4eea..c4e5fe8 100644
--- a/src/check_nrpe.c
+++ b/src/check_nrpe.c
@@ -24,7 +24,7 @@
 
 #define DEFAULT_NRPE_COMMAND	"_NRPE_CHECK"  /* check version of NRPE daemon */
 
-int server_port=DEFAULT_SERVER_PORT;
+char *server_port=DEFAULT_SERVER_PORT;
 char *server_name=NULL;
 char *command_name=NULL;
 int socket_timeout=DEFAULT_SOCKET_TIMEOUT;
@@ -366,9 +366,7 @@ int process_arguments(int argc, char **argv){
 				return ERROR;
 			break;
 		case 'p':
-			server_port=atoi(optarg);
-			if(server_port<=0)
-				return ERROR;
+			server_port=strdup(optarg);
 			break;
 		case 'H':
 			server_name=strdup(optarg);
diff --git a/src/nrpe.c b/src/nrpe.c
index 4a4adbb..22d2efc 100644
--- a/src/nrpe.c
+++ b/src/nrpe.c
@@ -44,13 +44,17 @@ int use_ssl=FALSE;
 #define MAXFD                   64
 #define NASTY_METACHARS         "|`&><'\"\\[]{};"
 
+#define BUFLEN 16384
+char buf[BUFLEN];
+
 char    *command_name=NULL;
 char    *macro_argv[MAX_COMMAND_ARGUMENTS];
 
 char    config_file[MAX_INPUT_BUFFER]="nrpe.cfg";
 int     log_facility=LOG_DAEMON;
-int     server_port=DEFAULT_SERVER_PORT;
-char    server_address[16]="0.0.0.0";
+
+char    *server_port=DEFAULT_SERVER_PORT;
+char    *server_address=NULL;
 int     socket_timeout=DEFAULT_SOCKET_TIMEOUT;
 int     command_timeout=DEFAULT_COMMAND_TIMEOUT;
 int     connection_timeout=DEFAULT_CONNECTION_TIMEOUT;
@@ -435,19 +439,14 @@ int read_config_file(char *filename){
 				syslog(LOG_ERR,"Continuing with errors...");
 		        }
 
-		else if(!strcmp(varname,"server_port")){
-			server_port=atoi(varvalue);
-			if(server_port<1024){
-				syslog(LOG_ERR,"Invalid port number specified in config file '%s' - Line %d\n",filename,line);
-				return ERROR;
-			        }
-		        }
+		else if(!strcmp(varname,"server_port"))
+			server_port=strdup(varvalue);
+
 		else if(!strcmp(varname,"command_prefix"))
 			command_prefix=strdup(varvalue);
 
 		else if(!strcmp(varname,"server_address")){
-                        strncpy(server_address,varvalue,sizeof(server_address) - 1);
-                        server_address[sizeof(server_address)-1]='\0';
+			server_address=strdup(varvalue);
                         }
 
                 else if(!strcmp(varname,"allowed_hosts"))
@@ -700,12 +699,12 @@ command *find_command(char *command_name){
 
 /* wait for incoming connection requests */
 void wait_for_connections(void){
-	struct sockaddr_in myname;
-	struct sockaddr_in *nptr;
-	struct sockaddr addr;
+	struct sockaddr_in6 myname6;
+	struct sockaddr_in6 src_sin;
+	socklen_t socklen = sizeof(src_sin);
+	struct sockaddr *remoteaddr = (struct sockaddr *)&src_sin;
 	int rc;
 	int sock, new_sd;
-	socklen_t addrlen;
 	pid_t pid;
 	int flag=1;
 	fd_set fdread;
@@ -715,43 +714,49 @@ void wait_for_connections(void){
 	struct request_info req;
 #endif
 
-	/* create a socket for listening */
-	sock=socket(AF_INET,SOCK_STREAM,0);
+	int rval;
+	int success=0;
+	struct addrinfo addrinfo;
+	struct addrinfo *res, *r;
 
-	/* exit if we couldn't create the socket */
-	if(sock<0){
-	        syslog(LOG_ERR,"Network server socket failure (%d: %s)",errno,strerror(errno));
-	        exit(STATE_CRITICAL);
-		}
+	memset(&addrinfo, 0, sizeof(addrinfo));
+	addrinfo.ai_family=PF_UNSPEC;
+	addrinfo.ai_socktype=SOCK_STREAM;
+	addrinfo.ai_protocol=IPPROTO_TCP;
 
-	/* socket should be non-blocking */
-	fcntl(sock,F_SETFL,O_NONBLOCK);
-
-        /* set the reuse address flag so we don't get errors when restarting */
-        flag=1;
-        if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&flag,sizeof(flag))<0){
-		syslog(LOG_ERR,"Could not set reuse address option on socket!\n");
-		exit(STATE_UNKNOWN);
-	        }
-
-	myname.sin_family=AF_INET;
-	myname.sin_port=htons(server_port);
- 	bzero(&myname.sin_zero,8);
-
-	/* what address should we bind to? */
-        if(!strlen(server_address))
-		myname.sin_addr.s_addr=INADDR_ANY;
-
-	else if(!my_inet_aton(server_address,&myname.sin_addr)){
-		syslog(LOG_ERR,"Server address is not a valid IP address\n");
+	if(!server_address || !strlen(server_address)) {
+		server_address = NULL;
+		addrinfo.ai_flags=AI_PASSIVE;
+		}
+	if (rval = getaddrinfo(server_address, server_port, &addrinfo, &res) != 0) {
+		syslog(LOG_ERR,"Invalid server_address (%d: %s)",errno,strerror(errno));
 		exit(STATE_CRITICAL);
-                }
-
-	/* bind the address to the Internet socket */
-	if(bind(sock,(struct sockaddr *)&myname,sizeof(myname))<0){
-		syslog(LOG_ERR,"Network server bind failure (%d: %s)\n",errno,strerror(errno));
-	        exit(STATE_CRITICAL);
-	        }
+		}
+	else {
+		for (r=res; r; r = r->ai_next) {   
+			sock = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
+			/* socket should be non-blocking */
+			fcntl(sock,F_SETFL,O_NONBLOCK);
+			/* set the reuse address flag so we don't get errors when restarting */
+			flag=1;
+			if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&flag,sizeof(flag))<0){
+				syslog(LOG_ERR,"Could not set reuse address option on socket!\n");
+				exit(STATE_UNKNOWN);
+				}
+			if(bind(sock, r->ai_addr, r->ai_addrlen) < 0) {
+				syslog(LOG_ERR,"Network server bind failure (%d: %s)\n",errno,strerror(errno));
+				(void) close(sock);
+				}
+			else {
+				success=1;
+				break;
+				}
+			}
+		freeaddrinfo(res);
+		if(success == 0) {
+			exit(STATE_CRITICAL);
+			}
+		}
 
 	/* open the socket for listening */
 	if(listen(sock,5)<0){
@@ -765,7 +770,7 @@ void wait_for_connections(void){
 		syslog(LOG_NOTICE,"Warning: Daemon is configured to accept command arguments from clients!");
 #endif
 
-	syslog(LOG_INFO,"Listening for connections on port %d\n",htons(myname.sin_port));
+	syslog(LOG_INFO,"Listening for connections on port %s\n",server_port);
 
 	if(allowed_hosts)
 		syslog(LOG_INFO,"Allowing connections from: %s\n",allowed_hosts);
@@ -792,8 +797,7 @@ void wait_for_connections(void){
 				continue;
 
 			/* accept a new connection request */
-			new_sd=accept(sock,0,0);
-
+			new_sd=accept(sock, remoteaddr, &socklen);
 			/* some kind of error occurred... */
 			if(new_sd<0){
 
@@ -832,7 +836,6 @@ void wait_for_connections(void){
 			/* fork again so we don't create zombies */
 			pid=fork();
 			if(pid==0){
-
 				/* hey, there was an error... */
 				if(new_sd<0){
 
@@ -853,38 +856,20 @@ void wait_for_connections(void){
 				/* grandchild does not need to listen for connections, so close the socket */
 				close(sock);  
 
-				/* find out who just connected... */
-				addrlen=sizeof(addr);
-				rc=getpeername(new_sd,&addr,&addrlen);
-
-				if(rc<0){
-
-				        /* log error to syslog facility */
-					syslog(LOG_ERR,"Error: Network server getpeername() failure (%d: %s)",errno,strerror(errno));
-
-				        /* close socket prior to exiting */
-					close(new_sd);
-
-					return;
-		                        }
-
-				nptr=(struct sockaddr_in *)&addr;
-
 				/* log info to syslog facility */
 				if(debug==TRUE)
-					syslog(LOG_DEBUG,"Connection from %s port %d",inet_ntoa(nptr->sin_addr),nptr->sin_port);
+				  syslog(LOG_DEBUG,"Connection from %s port %d",get_ip_str(remoteaddr, buf, BUFLEN),get_port(remoteaddr));
 
                                 /* is this is a blessed machine? */
 				if(allowed_hosts){
-
-					if(!is_an_allowed_host(inet_ntoa(nptr->sin_addr))){
+				  if(!is_an_allowed_host(remoteaddr)){
 
                                                /* log error to syslog facility */
-                                               syslog(LOG_ERR,"Host %s is not allowed to talk to us!",inet_ntoa(nptr->sin_addr));
+						syslog(LOG_ERR,"Host %s is not allowed to talk to us!",get_ip_str(remoteaddr, buf, BUFLEN));
 
                                                /* log info to syslog facility */
 					       if(debug==TRUE)
-						       syslog(LOG_DEBUG,"Connection from %s closed.",inet_ntoa(nptr->sin_addr));
+						       syslog(LOG_DEBUG,"Connection from %s closed.",get_ip_str(remoteaddr, buf, BUFLEN));
 
 					       /* close socket prior to exiting */
                                                close(new_sd);
@@ -924,7 +909,7 @@ void wait_for_connections(void){
 
 				/* log info to syslog facility */
 				if(debug==TRUE)
-					syslog(LOG_DEBUG,"Connection from %s closed.",inet_ntoa(nptr->sin_addr));
+					syslog(LOG_DEBUG,"Connection from %s closed.",get_ip_str(remoteaddr, buf, BUFLEN));
 
 				/* close socket prior to exiting */
 				close(new_sd);
@@ -956,70 +941,47 @@ void wait_for_connections(void){
 
 
 /* checks to see if a given host is allowed to talk to us */
-int is_an_allowed_host(char *connecting_host){
+int is_an_allowed_host(const struct sockaddr *connecting_host){
 	char *temp_buffer=NULL;
 	char *temp_ptr=NULL;
+	struct addrinfo addrinfo;
+	struct addrinfo *res, *r;
 	int result=0;
-        struct hostent *myhost;
-	char **pptr=NULL;
-	char *save_connecting_host=NULL;
-	struct in_addr addr;
-	
+	int rval;
+
 	/* make sure we have something */
 	if(connecting_host==NULL)
 		return 0;
 	if(allowed_hosts==NULL)
 		return 1;
-
 	if((temp_buffer=strdup(allowed_hosts))==NULL)
 		return 0;
-	
+  
 	/* try and match IP addresses first */
-	for(temp_ptr=strtok(temp_buffer,",");temp_ptr!=NULL;temp_ptr=strtok(NULL,",")){
-
-		if(!strcmp(connecting_host,temp_ptr)){
-			result=1;
-			break;
-		        }
-	        }
-
-	/* try DNS lookups if needed */
-	if(result==0){
-
-		free(temp_buffer);
-		if((temp_buffer=strdup(allowed_hosts))==NULL)
-			return 0;
-
-		save_connecting_host=strdup(connecting_host);
-		for(temp_ptr=strtok(temp_buffer,",");temp_ptr!=NULL;temp_ptr=strtok(NULL,",")){
-
-			myhost=gethostbyname(temp_ptr);
-			if(myhost!=NULL){
-
-				/* check all addresses for the host... */
-				for(pptr=myhost->h_addr_list;*pptr!=NULL;pptr++){
-					memcpy(&addr, *pptr, sizeof(addr));
-					if(!strcmp(save_connecting_host, inet_ntoa(addr))){
-						result=1;
-						break;
-					        }
-				        }
-			        }
-
-			if(result==1)
+	for(temp_ptr=strtok(temp_buffer,",");
+		temp_ptr!=NULL;temp_ptr=strtok(NULL,",")){
+		memset(&addrinfo, 0, sizeof(addrinfo));
+		addrinfo.ai_family=PF_UNSPEC;
+		addrinfo.ai_socktype=SOCK_STREAM;
+		addrinfo.ai_protocol=IPPROTO_TCP;
+		if (rval = getaddrinfo(temp_ptr, NULL, &addrinfo, &res) != 0) {
+			syslog(LOG_DEBUG,"Invalid host name in allowed_hosts '%s'\n",temp_ptr);
+			}
+		else {
+			for (r=res; r; r = r->ai_next) {	
+				if(sockaddr_equal(r->ai_addr, connecting_host)) {
+				result = 1;
 				break;
-		        }
-
-		strcpy(connecting_host, save_connecting_host);
-		free(save_connecting_host);
-	        }
-
-	free(temp_buffer);
-
+				}
+			}
+		}
+		if(result == 1) {
+			break;
+			}
+		}
+	freeaddrinfo(res);
 	return result;
-        }
-
-
+	}
 
 /* handles a client connection */
 void handle_connection(int sock){
@@ -1971,4 +1933,3 @@ int process_arguments(int argc, char **argv){
 
 	return OK;
         }
-
diff --git a/src/utils.c b/src/utils.c
index 48d7e58..8b1a7d5 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -110,177 +110,55 @@ void randomize_buffer(char *buffer,int buffer_size){
 
 
 /* opens a connection to a remote host/tcp port */
-int my_tcp_connect(char *host_name,int port,int *sd){
+int my_tcp_connect(char *host_name,char *port,int *sd6){
 	int result;
-
-	result=my_connect(host_name,port,sd,"tcp");
-
-	return result;
-        }
-
-
-/* opens a tcp or udp connection to a remote host */
-int my_connect(char *host_name,int port,int *sd,char *proto){
-	struct sockaddr_in servaddr;
-	struct hostent *hp;
-	struct protoent *ptrp;
-	int result;
-
-	bzero((char *)&servaddr,sizeof(servaddr));
-	servaddr.sin_family=AF_INET;
-	servaddr.sin_port=htons(port);
-
-	/* 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){
-			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");
+	int rval;
+	int success=0;
+	struct addrinfo addrinfo;
+	struct addrinfo *res, *r;
+
+	memset(&addrinfo, 0, sizeof(addrinfo));
+	addrinfo.ai_family=PF_UNSPEC;
+	addrinfo.ai_socktype=SOCK_STREAM;
+	addrinfo.ai_protocol=IPPROTO_TCP;
+	if (rval = getaddrinfo(host_name, port, &addrinfo, &res) != 0) {
+		printf("Invalid host name '%s'\n",host_name);
 		return STATE_UNKNOWN;
-	        }
+		}
 
-	/* open a connection */
-	result=connect(*sd,(struct sockaddr *)&servaddr,sizeof(servaddr));
-	if(result<0){
-		switch(errno){  
-		case ECONNREFUSED:
-			printf("Connection refused by host\n");
-			break;
-		case ETIMEDOUT:
-			printf("Timeout while attempting connection\n");
-			break;
-		case ENETUNREACH:
-			printf("Network is unreachable\n");
+	for (r=res; r; r = r->ai_next) {   
+		*sd6 = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
+		result=connect(*sd6, r->ai_addr, r->ai_addrlen);
+
+		if(result<0){    
+			switch(errno){  
+				case ECONNREFUSED:
+					printf("Connection refused by host\n");
+					break;
+				case ETIMEDOUT:
+					printf("Timeout while attempting connection\n");
+					break;
+				case ENETUNREACH:
+					printf("Network is unreachable\n");
+					break;
+				default:
+					printf("Connection refused or timed out\n");
+				}
+			(void) close(*sd6);            
+			}
+		else {
+			success++;
 			break;
-		default:
-			printf("Connection refused or timed out\n");
-		        }
-
+			}
+		}
+	if (success == 0) {
+		printf("Socket creation failed\n");
+		freeaddrinfo(res);
 		return STATE_CRITICAL;
-	        }
-
+		}
+	freeaddrinfo(res);
 	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);
-        }
-
+	}
 
 void strip(char *buffer){
 	int x;
@@ -436,5 +314,45 @@ void display_license(void){
 	return;
         }
 
+char *get_ip_str(const struct sockaddr *sa, char *s, size_t maxlen){
+	switch(sa->sa_family) {
+		case AF_INET:
+			inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr), s, maxlen);
+			break;
+		case AF_INET6:
+			inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr), s, maxlen);
+			break;
+		default:
+			strncpy(s, "Unknown AF", maxlen);
+			return s;
+		}
+	return s;
+	}
 
+int get_port(const struct sockaddr *sa){
+	switch(sa->sa_family) {
+		case AF_INET:
+			return ((struct sockaddr_in *)sa)->sin_port;
+		case AF_INET6:
+			return ((struct sockaddr_in6 *)sa)->sin6_port;
+		default:
+			return -1;
+		}
+	}
 
+int sockaddr_equal(const struct sockaddr *ip1, const struct sockaddr *ip2){
+	if (ip1->sa_family != ip2->sa_family) {  
+		return 0;
+		}
+	if (ip1->sa_family == AF_INET6) {
+		return (memcmp(&((const struct sockaddr_in6 *)ip1)->sin6_addr,
+			&((const struct sockaddr_in6 *)ip2)->sin6_addr,
+			sizeof(struct in6_addr)) == 0);    
+		}
+	if (ip1->sa_family == AF_INET) {
+		return (memcmp(&((const struct sockaddr_in *)ip1)->sin_addr,
+			&((const struct sockaddr_in *)ip2)->sin_addr,
+			sizeof(struct in_addr)) == 0);
+		}
+	return 0;
+	}
------------------------------------------------------------------------------
This SF.net email is sponsored by 

Make an app they can't live without
Enter the BlackBerry Developer Challenge
http://p.sf.net/sfu/RIM-dev2dev 
_______________________________________________
icinga-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/icinga-devel

Reply via email to