@Juan Since you're concerned about the performance, which is valid, I've also removed all the string-conversions. Important question: Is 1.0.0.127 a valid public IP-Adress? If yes, I'd have to furtherly change the code, adding some htonl, ntohl, or similar.
greetings, David
Index: dlls/winsock/socket.c =================================================================== RCS file: /home/wine/wine/dlls/winsock/socket.c,v retrieving revision 1.204 diff -b -B -c -r1.204 socket.c *** dlls/winsock/socket.c 12 Dec 2005 17:15:09 -0000 1.204 --- dlls/winsock/socket.c 14 Dec 2005 18:48:56 -0000 *************** *** 2927,2932 **** --- 2927,2989 ---- return retval; } + + /*********************************************************************** + * getpublicIP (Internal) + * + * Tries to guess the public IP-Adress by enumerating the available Interfaces + * target needs to be a buffer with the maximum size given in "size" + * + */ + + + BOOL get_public_ip(DWORD* target) + { + char buff[1024]; + struct ifconf ifc; + struct ifreq *ifr; + int skfd; + int i; + + skfd = socket(AF_INET, SOCK_DGRAM, 0); + if (skfd < 0) + { + WARN("A socket could not be created"); + return FALSE; + } + + ifc.ifc_len = sizeof(buff); + ifc.ifc_buf = buff; + if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) + { + WARN("ioctl(SIOCGIFCONF) failed"); + close(skfd); + return FALSE; + } + + close(skfd); + + ifr = ifc.ifc_req; + + for (i = 0; i < ifc.ifc_len / sizeof(struct ifreq); i++) + { + struct sockaddr_in* addr=(struct sockaddr_in*)&ifr[i].ifr_addr; + DWORD* ip = ((DWORD*)&addr->sin_addr); + + if(strcmp(ifr[i].ifr_name, "lo") == 0)continue; /*Exclude loopback-device by Name "lo"*/ + + if(*ip==0x7F000001 || *ip==0x0100007F)continue; /*Exclude 127.0.0.1, for both Endianesses. Effectively this excludes 127.0.0.1 and 1.0.0.127. Is that bad?*/ + + *target = *ip; + + return TRUE; + } + + return FALSE; + } + + + /*********************************************************************** * gethostbyname (WS2_32.52) */ *************** *** 2963,2969 **** host = gethostbyname(name); if (!host) SetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno(h_errno)); #endif ! if (host) retval = WS_dup_he(host); #ifdef HAVE_LINUX_GETHOSTBYNAME_R_6 HeapFree(GetProcessHeap(),0,extrabuf); #else --- 3023,3050 ---- host = gethostbyname(name); if (!host) SetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno(h_errno)); #endif ! if (host && host->h_addr_list[0] != NULL){ ! ! if(*((DWORD*)host->h_addr_list[0])==0x7F000001 || /*Effectively this includes 127.0.0.1 and 1.0.0.127. */ ! *((DWORD*)host->h_addr_list[0])==0x0100007F) /*Is that bad? This takes both endianesses into account*/ ! { ! char myname[256]; ! ! gethostname(myname, (size_t)256); ! ! if(strcmp(myname,name)==0){ /*Only replace the IP if the local hosts publib name was given*/ ! ! if(host->h_length == 4 && get_public_ip( (DWORD*)host->h_addr_list[0] )) /*Make sure that it really is an IPv4 adress by checking h_length==4*/ ! { ! TRACE("Using %s as public adress for local host %s\n",inet_ntoa( *((struct in_addr *)host->h_addr_list[0])), name); ! }else{ ! WARN("Public IP-adress of local host could not be recognized"); ! } ! } ! } ! ! retval = WS_dup_he(host); ! } #ifdef HAVE_LINUX_GETHOSTBYNAME_R_6 HeapFree(GetProcessHeap(),0,extrabuf); #else