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