#include <ws2tcpip.h> //define getnameinfo on windows
#endif
-void ip2name(char *ip,int ip_len)
+//! The possible return code of ip2name subfunctions.
+enum ip2name_retcode
+{
+ //! Error encountered during the
+ INRC_Error=-1,
+ //! No match found.
+ INRC_NotFound,
+ //! A match was found.
+ INRC_Found,
+};
+
+/*!
+Resolve the IP address using a reverse DNS entry.
+
+\param ip The IP address. It is replaced by the corresponding name if one
+can be found.
+\param ip_len The length of the \c ip buffer.
+
+\return One of the ::ip2name_retcode value.
+*/
+static enum ip2name_retcode ip2name_dns(char *ip,int ip_len)
{
#ifdef HAVE_GETNAMEINFO
struct sockaddr_storage sa;
memset(&sa,0,sizeof(sa));
if (sscanf(ip,"%d.%d.%d.%d%n",&n1,&n2,&n3,&n4,&next)==4 && ip[next]=='\0') {
struct sockaddr_in *s4=(struct sockaddr_in *)&sa;
- if (inet_pton(AF_INET,ip,&s4->sin_addr)!=1) return;
+ if (inet_pton(AF_INET,ip,&s4->sin_addr)!=1) return(INRC_Error);
sa.ss_family=AF_INET;
sockaddr_size=sizeof(*s4);
} else {
struct sockaddr_in6 *s6=(struct sockaddr_in6 *)&sa;
- if (inet_pton(AF_INET6,ip,&s6->sin6_addr)!=1) return;
+ if (inet_pton(AF_INET6,ip,&s6->sin6_addr)!=1) return(INRC_Error);
sa.ss_family=AF_INET6;
sockaddr_size=sizeof(*s6);
}
#ifdef HAVE_SOCKADDR_SA_LEN
sa.ss_len=sockaddr_size;
#endif
- error=getnameinfo((struct sockaddr *)&sa,sockaddr_size,host,sizeof(host),NULL,0,0);
+ error=getnameinfo((struct sockaddr *)&sa,sockaddr_size,host,sizeof(host),NULL,0,NI_NAMEREQD);
if (error==EAI_AGAIN) {
/*
This is a temporary failure. According to the man page we should try again but
of serious consequences should some IP fail to be resolved properly, it is best
not waste too much time on this.
*/
- error=getnameinfo((struct sockaddr *)&sa,sizeof(sa),host,sizeof(host),NULL,0,0);
+ error=getnameinfo((struct sockaddr *)&sa,sizeof(sa),host,sizeof(host),NULL,0,NI_NAMEREQD);
}
- if (error==0) {
- safe_strcpy(ip,host,ip_len);
- } else {
+ if (error==EAI_NONAME)
+ return(INRC_NotFound);
+ if (error!=0) {
debuga(_("IP to name resolution (getnameinfo) on IP address %s failed with error %d - %s\n"),ip,error,gai_strerror(error));
+ return(INRC_Error);
}
-#else
+ safe_strcpy(ip,host,ip_len);
+#else //HAVE_GETNAMEINFO
struct in_addr addr;
struct hostent *hp;
char **p;
+ extern int h_errno;
#ifdef HAVE_INET_ATON
if (inet_aton(ip,&addr) == 0)
- return;
+ return(INRC_Error);
#else
addr.s_addr=inet_addr(ip);
- if (addr.s_addr==-1) return;
+ if (addr.s_addr==-1) return(INRC_Error);
#endif
hp = gethostbyaddr((void *)&addr, sizeof (addr), AF_INET);
- if (hp == NULL)
- return;
+ if (hp == NULL) {
+ if (h_errno==HOST_NOT_FOUND)
+ return(INRC_NotFound);
+ return(INRC_Error);
+ }
for (p = hp->h_addr_list; *p != 0; p++) {
struct in_addr in;
safe_strcpy(ip,hp->h_name,ip_len);
}
#endif
- return;
+ return(INRC_Found);
+}
+
+/*!
+Convert an IP address into a name.
+
+\param ip The IP address. It is replaced by the corresponding name if one
+can be found.
+\param ip_len The length of the \c ip buffer.
+*/
+void ip2name(char *ip,int ip_len)
+{
+ enum ip2name_retcode Status;
+
+ Status=ip2name_dns(ip,ip_len);
+ if (Status==INRC_Found) return;
}
void name2ip(char *name,int name_size)