00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <cstdlib>
00014 #include <string>
00015
00016 #if defined(WIN32)
00017 # include <winsock2.h>
00018 #else
00019 # include <netdb.h>
00020 extern int h_errno;
00021 # include <sys/socket.h>
00022 # include <unistd.h>
00023 # include <sys/utsname.h>
00024 #endif
00025
00026 #include "assa/INETAddress.h"
00027 using namespace ASSA;
00028
00029 string INETAddress::m_fqdn_cache;
00030
00031 void
00032 INETAddress::
00033 init ()
00034 {
00035 ::memset ((char*) &m_address, 0, sizeof(m_address));
00036 }
00037
00038 INETAddress::
00039 INETAddress ()
00040 {
00041
00042 init ();
00043 }
00044
00045 INETAddress::
00046 INETAddress (const char* host_, int port_)
00047 {
00048
00049 init ();
00050 createHostPort (host_, htons (port_));
00051 }
00052
00053 INETAddress::
00054 INETAddress (const char* host_, const char* service_, Protocol protocol_)
00055 {
00056
00057
00058 init ();
00059 createHostPort (host_, getServiceByName (service_,protocol_));
00060 }
00061
00062 INETAddress::
00063 INETAddress (int port_)
00064 {
00065
00066
00067 init ();
00068 createHostPort ("", htons (port_));
00069 }
00070
00071 INETAddress::
00072 INETAddress (SA_IN* address_)
00073 {
00074
00075
00076 init ();
00077 ::memcpy ((void*) &m_address, (const void*) address_, sizeof(SA_IN));
00078 }
00079
00080 INETAddress::
00081 INETAddress (SA* address_)
00082 {
00083
00084
00085 init ();
00086 ::memcpy ((void*) &m_address, (const void*) address_, sizeof(SA_IN));
00087 }
00088
00089 INETAddress::
00090 INETAddress (struct in_addr * haddr_, int port_)
00091 {
00092
00093
00094 init ();
00095 m_address.sin_addr = *haddr_;
00096 m_address.sin_family = AF_INET;
00097 m_address.sin_port = htons(port_);
00098 }
00099
00100 INETAddress::
00101 INETAddress (const char* address_, Protocol protocol_)
00102 {
00103
00104
00105 init ();
00106
00107 string s(address_);
00108 string sPort(s);
00109 int r = 0;
00110 string host;
00111
00112 #ifdef BLOCKED
00113 const u_int HOSTNAMELEN = 64;
00114 char buf[HOSTNAMELEN];
00115 if (gethostname (buf, HOSTNAMELEN) == 0) {
00116 host = buf;
00117 }
00118 #endif
00119
00120 if ( (r = s.find(':')) > 0 ) {
00121 host = s.substr(0, r);
00122 sPort = s.substr(r+1);
00123 }
00124 else if ( (r = s.find('@')) > 0 ) {
00125 sPort = s.substr(0, r);
00126 host = s.substr(r+1);
00127 }
00128
00129 if ( (r = getServiceByName (sPort)) == 0 ) {
00130 return;
00131 }
00132
00133 createHostPort (host.c_str(), r);
00134 }
00135
00136 int
00137 INETAddress::
00138 getServiceByName (string s_, Protocol p_)
00139 {
00140
00141
00142 long l = 0;
00143 struct servent* sp = NULL;
00144
00145 if ((l = strtol (s_.c_str(), (char**) NULL, 10))) {
00146 return htons ((unsigned short int) l);
00147 }
00148
00149 if ((sp = getservbyname (s_.c_str(), (p_==TCP ? "tcp" : "udp")))) {
00150 return sp->s_port;
00151 }
00152
00153 setstate (Address::badbit);
00154 return 0;
00155 }
00156
00157 void
00158 INETAddress::
00159 createHostPort (const char* host_, int port_)
00160 {
00161
00162
00163 struct hostent* hp = 0;
00164
00165 if (strlen (host_) == 0) {
00166 m_address.sin_addr.s_addr = htonl(INADDR_ANY);
00167 goto done;
00168 }
00169
00170 if ((hp = gethostbyname (host_)) == NULL) {
00171 setstate (Address::badbit);
00172 errno = h_errno;
00173 EL((ASSAERR,"gethostbyname (\"%s\") failed\n", host_));
00174 return;
00175 }
00176 memcpy ((char*) &m_address.sin_addr, hp->h_addr_list[0], hp->h_length);
00177
00178 done:
00179 m_address.sin_family = AF_INET;
00180 m_address.sin_port = port_;
00181 }
00182
00183 string
00184 INETAddress::
00185 getHostName ()
00186 {
00187 if (m_address.sin_addr.s_addr == htonl(INADDR_ANY)) {
00188 return ("");
00189 }
00190
00191 struct hostent* hentry;
00192 hentry = gethostbyaddr ((const char*) &m_address.sin_addr,
00193 sizeof(m_address.sin_addr),
00194 AF_INET);
00195 if (hentry == NULL) {
00196 errno = h_errno;
00197 setstate (Address::badbit);
00198 EL((ASSAERR,"gethostbyaddr() failed\n"));
00199 return ("");
00200 }
00201 return hentry->h_name;
00202 }
00203
00204 void
00205 INETAddress::
00206 dump ()
00207 {
00208
00209
00210 Address::dump ();
00211 DL((ADDRESS,"Family - %s\n", ntohs(m_address.sin_family) == AF_INET ?
00212 "AF_INET" : "AF_UNIX"));
00213 DL((ADDRESS,"host - %s\n", getHostName ().c_str()));
00214 DL((ADDRESS,"port - %d\n", getPort ()));
00215 DL((ADDRESS,"address - %s\n", inet_ntoa (m_address.sin_addr)));
00216 }
00217
00218 #if defined(WIN32)
00219 struct utsname
00220 {
00221 char sysname[20];
00222 char nodename[20];
00223 char release[20];
00224 char version[20];
00225 char machine[20];
00226 };
00227 #endif
00228
00229 string
00230 INETAddress::
00231 get_fully_qualified_domain_name (vector<string>& aliases_)
00232 {
00233
00234
00235 if (m_fqdn_cache.length ()) {
00236 return m_fqdn_cache;
00237 }
00238
00239 struct utsname myname;
00240 struct hostent* hptr = NULL;
00241
00242 #if defined(WIN32)
00243 DWORD slen;
00244 slen = sizeof (myname.nodename) - 1;
00245 GetComputerNameA (myname.nodename, &slen);
00246 #else
00247 if (::uname (&myname) < 0) {
00248 EL((ADDRESS,"Hostname is not set!\n"));
00249 return m_fqdn_cache;
00250 }
00251 #endif
00252
00253 if ((hptr = ::gethostbyname (myname.nodename)) == NULL) {
00254 errno = h_errno;
00255 EL((ADDRESS,"gethostbyname (%s) failed\n", myname.nodename));
00256 return m_fqdn_cache;
00257 }
00258 m_fqdn_cache = hptr->h_name;
00259 char** pptr = hptr->h_aliases;
00260 while (*pptr != NULL) {
00261 aliases_.push_back (*pptr);
00262 pptr++;
00263 }
00264
00265 return m_fqdn_cache;
00266 }