#ifndef __JSYSTEM__JNETWORK__ #define __JSYSTEM__JNETWORK__ #include #include #include #include #include #include #include #include #include "JLang/JException.hh" /** * \file * Hostname and IP address functions. * \author mdejong */ namespace JSYSTEM {} namespace JPP { using namespace JSYSTEM; } namespace JSYSTEM { namespace { using JLANG::JSystemException; /** * Auxiliary class to compare endianess of network and system. */ class JCompareEndian { public: /** * Default constructor. */ JCompareEndian() : endian(ntohs(0x1234) == 0x1234) {} /** * Function object operator. * * \return true if network and system endianess same; else false */ bool operator()() const { return endian; } private: const bool endian; }; } /** * Function object operator. * * \return true if network and system endianess same; else false */ static const JCompareEndian compareEndian; /** * Get host name. * * Note that to obtain a host name including the domain name, * JSYSTEM::getHostname(JSYSTEM::getIPnumber()) should be used. * * \return host name */ inline std::string getHostname() { const size_t MAXIMUM_LENGTH = 256; char buffer[MAXIMUM_LENGTH]; if (gethostname(buffer, MAXIMUM_LENGTH) == 0) return std::string(buffer); else throw JSystemException("Unknown host name."); } /** * Get host name. * * \param ip IP number * \return host name */ inline std::string getHostname(const int ip) { in_addr buffer; buffer.s_addr = ip; hostent* p = gethostbyaddr(&buffer, sizeof(in_addr), AF_INET); if (p != NULL) return std::string(p->h_name); else throw JSystemException("Unknown IP address."); } /** * Get IP number. * * \param host_name host name * \return IP number */ inline int getIPnumber(const std::string& host_name) { int ip = -1; std::string buffer = host_name; if (buffer == "" || buffer == "localhost") { buffer = getHostname(); } const hostent* hp = gethostbyname(buffer.c_str()); if (hp != NULL) { memcpy((char *) &ip, hp->h_addr, sizeof(int)); } return ip; } /** * Get IP number. * * \return IP number */ inline int getIPnumber() { return getIPnumber(getHostname()); } /** * Get IP address (decimal-dot notation). * * \param ip IP number * \return IP address */ inline std::string getIPaddress(const int ip) { std::ostringstream os; if (compareEndian()) os << ((ip >> 24) & 0xFF) << '.' << ((ip >> 16) & 0xFF) << '.' << ((ip >> 8) & 0xFF) << '.' << ((ip >> 0) & 0xFF); else os << ((ip >> 0) & 0xFF) << '.' << ((ip >> 8) & 0xFF) << '.' << ((ip >> 16) & 0xFF) << '.' << ((ip >> 24) & 0xFF); return os.str(); } /** * Get IP address (decimal-dot notation). * * \return IP address */ inline std::string getIPaddress() { return getIPaddress(getIPnumber()); } /** * Get host identifier within network. * * \param ip IP number * \return ID */ inline unsigned short getSubaddress(const int ip) { if (compareEndian()) return (unsigned short) (ip & 0x0000FFFF); else return (unsigned short) (((ip & 0xFF000000) >> 24) | ((ip & 0x00FF0000) >> 8) ); } /** * Get host identifier within network. * * \return ID */ inline unsigned short getSubaddress() { return getSubaddress(getIPnumber()); } /** * Get list of IP address (decimal-dot notation). * * \return IP address */ inline std::vector getListOfIPaddresses() { using namespace std; const size_t MAXIMUM_LENGTH = 256; char buffer[MAXIMUM_LENGTH]; vector result; struct ifaddrs *p = NULL; if (getifaddrs(&p) == 0) { for ( ; p != NULL; p = p->ifa_next) { if (p->ifa_addr != NULL) { if (p->ifa_addr->sa_family == AF_INET || p->ifa_addr->sa_family == AF_INET6) { if (getnameinfo( p->ifa_addr, (p->ifa_addr->sa_family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), buffer, MAXIMUM_LENGTH, NULL, 0, NI_NUMERICHOST) == 0) { result.push_back(buffer); } } } } freeifaddrs(p); } return result; } } #endif