INETAddress.cpp

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

Generated on Sat Dec 31 19:52:09 2005 for libassa by  doxygen 1.4.5