// -*- c++ -*- //------------------------------------------------------------------------------ // INETAddress.cpp //------------------------------------------------------------------------------ // Copyright (c) 1999 by Vladislav Grinchenko // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public // License as published by the Free Software Foundation; either // version 2 of the License, or (at your option) any later version. //------------------------------------------------------------------------------ #include #if defined(WIN32) # include #else # include // gethostbyname(3) extern int h_errno; // gethostbyname(3) # include // for AF_INET # include // for AF_INET # include # include #endif #include "assa/INETAddress.h" using namespace ASSA; string INETAddress::m_fqdn_cache; void INETAddress:: init () { ::memset ((char*) &m_address, 0, sizeof(m_address)); } INETAddress:: INETAddress () { // trace_with_mask("INETAddress::INETAddress()",SOCKTRACE); init (); } INETAddress:: INETAddress (const char* host_, int port_) { // trace_with_mask("INETAddress::INETAddress(host, port)",SOCKTRACE); init (); createHostPort (host_, htons (port_)); } INETAddress:: INETAddress (const char* host_, const char* service_, Protocol protocol_) { // trace_with_mask("INETAddress::INETAddress(host, port, protocol)", // SOCKTRACE); init (); createHostPort (host_, getServiceByName (service_,protocol_)); } INETAddress:: INETAddress (int port_) { // trace_with_mask("INETAddress::INETAddress(port)",SOCKTRACE); init (); createHostPort ("", htons (port_)); } INETAddress:: INETAddress (SA_IN* address_) { // trace_with_mask("INETAddress::INETAddress(SA_IN*)",SOCKTRACE); init (); ::memcpy ((void*) &m_address, (const void*) address_, sizeof(SA_IN)); } INETAddress:: INETAddress (SA* address_) { // trace_with_mask("INETAddress::INETAddress(SA*)",SOCKTRACE); init (); ::memcpy ((void*) &m_address, (const void*) address_, sizeof(SA_IN)); } INETAddress:: INETAddress (struct in_addr * haddr_, int port_) { // trace_with_mask("INETAddress::INETAddress(in_addr*,port)",ADDRESS); init (); m_address.sin_addr = *haddr_; m_address.sin_family = AF_INET; m_address.sin_port = htons(port_); } INETAddress:: INETAddress (const char* address_, Protocol protocol_) { // trace_with_mask("INETAddress::INETAddress(address, protocol)",ADDRESS); init (); string s(address_); string sPort(s); int r = 0; string host; #ifdef BLOCKED const u_int HOSTNAMELEN = 64; char buf[HOSTNAMELEN]; // 64 on Linux/i386 if (gethostname (buf, HOSTNAMELEN) == 0) { host = buf; } #endif if ( (r = s.find(':')) > 0 ) { // host:service host = s.substr(0, r); sPort = s.substr(r+1); } else if ( (r = s.find('@')) > 0 ) { // service@host sPort = s.substr(0, r); host = s.substr(r+1); } if ( (r = getServiceByName (sPort)) == 0 ) { // service return; } createHostPort (host.c_str(), r); } int INETAddress:: getServiceByName (string s_, Protocol p_) { // trace_with_mask("INETAddress::getServiceByName", ADDRESS); long l = 0; struct servent* sp = NULL; if ((l = strtol (s_.c_str(), (char**) NULL, 10))) { return htons ((unsigned short int) l); } if ((sp = getservbyname (s_.c_str(), (p_==TCP ? "tcp" : "udp")))) { return sp->s_port; } setstate (Address::badbit); return 0; } void INETAddress:: createHostPort (const char* host_, int port_) { // trace_with_mask("INETAddress::createHostPort(char*,int)", ADDRESS); struct hostent* hp = 0; if (strlen (host_) == 0) { m_address.sin_addr.s_addr = htonl(INADDR_ANY); goto done; } if ((hp = gethostbyname (host_)) == NULL) { setstate (Address::badbit); errno = h_errno; EL((ASSAERR,"gethostbyname (\"%s\") failed\n", host_)); return; } memcpy ((char*) &m_address.sin_addr, hp->h_addr_list[0], hp->h_length); done: m_address.sin_family = AF_INET; m_address.sin_port = port_; } string INETAddress:: getHostName () { if (m_address.sin_addr.s_addr == htonl(INADDR_ANY)) { return (""); } struct hostent* hentry; hentry = gethostbyaddr ((const char*) &m_address.sin_addr, sizeof(m_address.sin_addr), AF_INET); if (hentry == NULL) { errno = h_errno; setstate (Address::badbit); EL((ASSAERR,"gethostbyaddr() failed\n")); return (""); } return hentry->h_name; } void INETAddress:: dump () { // trace_with_mask("INETAddress::dump", ADDRESS); Address::dump (); DL((ADDRESS,"Family - %s\n", ntohs(m_address.sin_family) == AF_INET ? "AF_INET" : "AF_UNIX")); DL((ADDRESS,"host - %s\n", getHostName ().c_str())); DL((ADDRESS,"port - %d\n", getPort ())); DL((ADDRESS,"address - %s\n", inet_ntoa (m_address.sin_addr))); } #if defined(WIN32) struct utsname { char sysname[20]; char nodename[20]; char release[20]; char version[20]; char machine[20]; }; #endif string INETAddress:: get_fully_qualified_domain_name (vector& aliases_) { // trace_with_mask ("INETAddress::get_fully_qualified_domain_name", ADDRESS); if (m_fqdn_cache.length ()) { return m_fqdn_cache; } struct utsname myname; struct hostent* hptr = NULL; #if defined(WIN32) DWORD slen; slen = sizeof (myname.nodename) - 1; GetComputerNameA (myname.nodename, &slen); #else if (::uname (&myname) < 0) { EL((ADDRESS,"Hostname is not set!\n")); return m_fqdn_cache; } #endif if ((hptr = ::gethostbyname (myname.nodename)) == NULL) { errno = h_errno; EL((ADDRESS,"gethostbyname (%s) failed\n", myname.nodename)); return m_fqdn_cache; } m_fqdn_cache = hptr->h_name; char** pptr = hptr->h_aliases; while (*pptr != NULL) { aliases_.push_back (*pptr); pptr++; } return m_fqdn_cache; }