00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "config.h"
00040 #include "NetUtils.h"
00041 #include "compat/inet_aton.h"
00042 #include "debug/DebugUtils.h"
00043 #include "debug/Log.h"
00044 #include "thread/SpinLock.h"
00045 #include <stdlib.h>
00046 #include <string.h>
00047 #include <sys/socket.h>
00048 #include <netdb.h>
00049
00050 namespace oasys {
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 const char *
00061 _intoa(u_int32_t addr, char* buf, size_t bufsize)
00062 {
00063 register char *cp;
00064 register u_int byte;
00065 register int n;
00066
00067 addr = ntohl(addr);
00068 cp = &buf[bufsize];
00069 *--cp = '\0';
00070
00071 n = 4;
00072 do {
00073 byte = addr & 0xff;
00074 *--cp = byte % 10 + '0';
00075 byte /= 10;
00076 if (byte > 0) {
00077 *--cp = byte % 10 + '0';
00078 byte /= 10;
00079 if (byte > 0)
00080 *--cp = byte + '0';
00081 }
00082 *--cp = '.';
00083 addr >>= 8;
00084 } while (--n > 0);
00085
00086 return cp + 1;
00087 }
00088
00089 int
00090 gethostbyname(const char* name, in_addr_t* addr)
00091 {
00092 ASSERT(addr);
00093
00094
00095 if (inet_aton(name, (struct in_addr*)addr) != 0) {
00096 return 0;
00097 }
00098
00099 #if defined(HAVE_GETHOSTBYNAME_R)
00100
00101 struct hostent h;
00102 char buf[2048];
00103 struct hostent* ret = 0;
00104 (void)ret;
00105 int h_err;
00106
00107
00108 #if defined(__sun__) // solaris has different args
00109 if (::gethostbyname_r(name, &h, buf, sizeof(buf), &h_err) < 0) {
00110 logf("/oasys/net", LOG_ERR, "error return from gethostbyname_r(%s): %s",
00111 name, strerror(h_err));
00112 return -1;
00113 }
00114 #else
00115 if (::gethostbyname_r(name, &h, buf, sizeof(buf), &ret, &h_err) < 0) {
00116 logf("/oasys/net", LOG_ERR, "error return from gethostbyname_r(%s): %s",
00117 name, strerror(h_err));
00118 return -1;
00119 }
00120 if (ret == NULL) {
00121 return -1;
00122 }
00123 #endif
00124
00125 *addr = ((struct in_addr**)h.h_addr_list)[0]->s_addr;
00126
00127 if (*addr == INADDR_NONE) {
00128 logf("/oasys/net", LOG_ERR, "gethostbyname_r(%s) returned INADDR_NONE", name);
00129 return -1;
00130 }
00131 return 0;
00132
00133 #elif defined(HAVE_GETADDRINFO)
00134
00135 struct addrinfo hints;
00136 struct addrinfo *res;
00137 int err;
00138
00139 memset(&hints, 0, sizeof(hints));
00140 hints.ai_family = PF_INET;
00141
00142 err = getaddrinfo(name, 0, &hints, &res);
00143 if(err != 0)
00144 return -1;
00145
00146 ASSERT(res != 0);
00147 ASSERT(res->ai_family == PF_INET);
00148 *addr = ((struct sockaddr_in*) res->ai_addr)->sin_addr.s_addr;
00149
00150 freeaddrinfo(res);
00151
00152 if (*addr == INADDR_NONE) {
00153 logf("/oasys/net", LOG_ERR, "getaddrinfo(%s) returned INADDR_NONE", name);
00154 return -1;
00155 }
00156 return 0;
00157
00158 #elif defined(HAVE_GETHOSTBYNAME)
00159
00160 static SpinLock gethostbyname_lock;
00161 ScopeLock l(&gethostbyname_lock, "gethostbyname");
00162
00163 struct hostent *hent;
00164 hent = ::gethostbyname(name);
00165 if (hent == NULL) {
00166 logf("/net", LOG_ERR, "error return from gethostbyname(%s): %s",
00167 name, strerror(h_errno));
00168 return -1;
00169 }
00170
00171 *addr = ((struct in_addr**)hent->h_addr_list)[0]->s_addr;
00172
00173 if (*addr == INADDR_NONE) {
00174 logf("/oasys/net", LOG_ERR, "gethostbyname(%s) returned INADDR_NONE", name);
00175 return -1;
00176 }
00177
00178 return 0;
00179
00180 #else
00181 #error No gethostbyname equivalent available for this platform
00182 #endif
00183 }
00184
00185 }