libassa
3.5.0
|
00001 // -*- c++ -*- 00002 //------------------------------------------------------------------------------ 00003 // INETAddress.cpp 00004 //------------------------------------------------------------------------------ 00005 // Copyright (c) 1999 by Vladislav Grinchenko 00006 // 00007 // This library is free software; you can redistribute it and/or 00008 // modify it under the terms of the GNU Library General Public 00009 // License as published by the Free Software Foundation; either 00010 // version 2 of the License, or (at your option) any later version. 00011 //------------------------------------------------------------------------------ 00012 00013 #include <cstdlib> 00014 #include <string> 00015 00016 #if defined(WIN32) 00017 # include <winsock2.h> 00018 #else 00019 # include <netdb.h> // gethostbyname(3) 00020 // extern int h_errno; // gethostbyname(3) 00021 # include <sys/socket.h> // for AF_INET 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 // trace_with_mask("INETAddress::INETAddress()",SOCKTRACE); 00042 init (); 00043 } 00044 00045 INETAddress:: 00046 INETAddress (const char* host_, int port_) 00047 { 00048 // trace_with_mask("INETAddress::INETAddress(host, port)",SOCKTRACE); 00049 init (); 00050 createHostPort (host_, htons (port_)); 00051 } 00052 00053 INETAddress:: 00054 INETAddress (const char* host_, const char* service_, Protocol protocol_) 00055 { 00056 // trace_with_mask("INETAddress::INETAddress(host, port, protocol)", 00057 // SOCKTRACE); 00058 init (); 00059 createHostPort (host_, getServiceByName (service_,protocol_)); 00060 } 00061 00062 INETAddress:: 00063 INETAddress (int port_) 00064 { 00065 // trace_with_mask("INETAddress::INETAddress(port)",SOCKTRACE); 00066 00067 init (); 00068 createHostPort ("", htons (port_)); 00069 } 00070 00071 INETAddress:: 00072 INETAddress (SA_IN* address_) 00073 { 00074 // trace_with_mask("INETAddress::INETAddress(SA_IN*)",SOCKTRACE); 00075 00076 init (); 00077 ::memcpy ((void*) &m_address, (const void*) address_, sizeof(SA_IN)); 00078 } 00079 00080 INETAddress:: 00081 INETAddress (SA* address_) 00082 { 00083 // trace_with_mask("INETAddress::INETAddress(SA*)",SOCKTRACE); 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 // trace_with_mask("INETAddress::INETAddress(in_addr*,port)",ADDRESS); 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 // trace_with_mask("INETAddress::INETAddress(address, protocol)",ADDRESS); 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]; // 64 on Linux/i386 00115 if (gethostname (buf, HOSTNAMELEN) == 0) { 00116 host = buf; 00117 } 00118 #endif 00119 00120 if ( (r = s.find(':')) > 0 ) { // host:service 00121 host = s.substr(0, r); 00122 sPort = s.substr(r+1); 00123 } 00124 else if ( (r = s.find('@')) > 0 ) { // service@host 00125 sPort = s.substr(0, r); 00126 host = s.substr(r+1); 00127 } 00128 00129 if ( (r = getServiceByName (sPort)) == 0 ) { // service 00130 return; 00131 } 00132 00133 createHostPort (host.c_str(), r); 00134 } 00135 00136 int 00137 INETAddress:: 00138 getServiceByName (string s_, Protocol p_) 00139 { 00140 // trace_with_mask("INETAddress::getServiceByName", ADDRESS); 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 // trace_with_mask("INETAddress::createHostPort(char*,int)", ADDRESS); 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 // trace_with_mask("INETAddress::dump", ADDRESS); 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 // trace_with_mask ("INETAddress::get_fully_qualified_domain_name", ADDRESS); 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 }