* (NOTE: we don't use gethostbyname as a * fallback!)
* (NOTE: we don't use gethostbyname as a fallback!)
SockAddr sk_namelookup(const char *host, char **canonicalname){    SockAddr ret = snew(struct SockAddr_tag);    unsigned long a;    struct hostent *h = NULL;    char realhost[8192];    /* Clear the structure and default to IPv4. */    memset(ret, 0, sizeof(struct SockAddr_tag));    ret->family = 0;		       /* We set this one when we have resolved the host. */    *realhost = '\0';    if ((a = p_inet_addr(host)) == (unsigned long) INADDR_NONE) {#ifdef IPV6	/* Try to get the getaddrinfo() function from wship6.dll */	/* This way one doesn't need to have IPv6 dll's to use PuTTY and	 * it will fallback to IPv4. */	typedef int (CALLBACK * FGETADDRINFO) (const char *nodename,					       const char *servname,					       const struct addrinfo *					       hints,					       struct addrinfo ** res);	FGETADDRINFO fGetAddrInfo = NULL;	HINSTANCE dllWSHIP6 = LoadLibrary("wship6.dll");	if (dllWSHIP6)	    fGetAddrInfo = (FGETADDRINFO) GetProcAddress(dllWSHIP6,							 "getaddrinfo");	/*	 * Use fGetAddrInfo when it's available (which usually also	 * means IPv6 is installed...)	 */	if (fGetAddrInfo) {	    /*debug(("Resolving \"%s\" with getaddrinfo()  (IPv4+IPv6 capable)...\n", host)); */	    if (fGetAddrInfo(host, NULL, NULL, &ret->ai) == 0)		ret->family = ret->ai->ai_family;	} else#endif	{	    /*	     * Otherwise use the IPv4-only gethostbyname...	     * (NOTE: we don't use gethostbyname as a	     * fallback!)	     */	    if (ret->family == 0) {		/*debug(("Resolving \"%s\" with gethostbyname() (IPv4 only)...\n", host)); */		if ( (h = p_gethostbyname(host)) )		    ret->family = AF_INET;	    }	}	/*debug(("Done resolving...(family is %d) AF_INET = %d, AF_INET6 = %d\n", ret->family, AF_INET, AF_INET6)); */	if (ret->family == 0) {	    DWORD err = p_WSAGetLastError();	    ret->error = (err == WSAENETDOWN ? "Network is down" :			  err ==			  WSAHOST_NOT_FOUND ? "Host does not exist" : err			  == WSATRY_AGAIN ? "Host not found" :#ifdef IPV6			  fGetAddrInfo ? "getaddrinfo: unknown error" :#endif			  "gethostbyname: unknown error");#ifdef DEBUG	    {		LPVOID lpMsgBuf;		FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |			      FORMAT_MESSAGE_FROM_SYSTEM |			      FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err,			      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),			      (LPTSTR) & lpMsgBuf, 0, NULL);		/*debug(("Error %ld: %s (h=%lx)\n", err, lpMsgBuf, h)); */		/* Free the buffer. */		LocalFree(lpMsgBuf);	    }#endif	} else {	    ret->error = NULL;#ifdef IPV6	    /* If we got an address info use that... */	    if (ret->ai) {		typedef int (CALLBACK * FGETNAMEINFO)		 (const struct sockaddr FAR * sa, socklen_t salen,		  char FAR * host, size_t hostlen, char FAR * serv,		  size_t servlen, int flags);		FGETNAMEINFO fGetNameInfo = NULL;		/* Are we in IPv4 fallback mode? */		/* We put the IPv4 address into the a variable so we can further-on use the IPv4 code... */		if (ret->family == AF_INET)		    memcpy(&a,			   (char *) &((SOCKADDR_IN *) ret->ai->				      ai_addr)->sin_addr, sizeof(a));		/* Now let's find that canonicalname... */		if ((dllWSHIP6)		    && (fGetNameInfo =			(FGETNAMEINFO) GetProcAddress(dllWSHIP6,						      "getnameinfo"))) {		    if (fGetNameInfo			((struct sockaddr *) ret->ai->ai_addr,			 ret->family ==			 AF_INET ? sizeof(SOCKADDR_IN) :			 sizeof(SOCKADDR_IN6), realhost,			 sizeof(realhost), NULL, 0, 0) != 0) {			strncpy(realhost, host, sizeof(realhost));		    }		}	    }	    /* We used the IPv4-only gethostbyname()... */	    else#endif	    {		memcpy(&a, h->h_addr, sizeof(a));		/* This way we are always sure the h->h_name is valid :) */		strncpy(realhost, h->h_name, sizeof(realhost));	    }	}#ifdef IPV6	FreeLibrary(dllWSHIP6);#endif    } else {	/*	 * This must be a numeric IPv4 address because it caused a	 * success return from inet_addr.	 */	ret->family = AF_INET;	strncpy(realhost, host, sizeof(realhost));    }    ret->address = p_ntohl(a);    realhost[lenof(realhost)-1] = '\0';    *canonicalname = snewn(1+strlen(realhost), char);    strcpy(*canonicalname, realhost);    return ret;}