INet4Address.cc
Go to the documentation of this file.
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 #include "INet4Address.hh"
00027
00028
00029
00030 #include <arpa/inet.h>
00031 #include <netdb.h>
00032 #include <sys/socket.h>
00033 #include <boost/lexical_cast.hpp>
00034 #if defined(_REENTRANT) && !defined(__GLIBC__)
00035 #include <boost/thread/mutex.hpp>
00036 #endif
00037 #include <senf/Socket/Protocols/AddressExceptions.hh>
00038
00039
00040 #define prefix_
00041
00042
00043
00044
00045
00046 prefix_ senf::INet4Address::INet4Address(address_type value)
00047 {
00048 iref() = htonl(value);
00049 }
00050
00051 prefix_ senf::INet4Address senf::INet4Address::from_string(std::string const & s)
00052 {
00053 struct in_addr ina;
00054 if (::inet_pton(AF_INET,s.c_str(),&ina) > 0)
00055 return INet4Address::from_inaddr(ina.s_addr);
00056
00057 if (s.empty())
00058 throw AddressSyntaxException() << ": empty string";
00059
00060 int herr (0);
00061
00062
00063
00064
00065 # ifdef __GLIBC__
00066
00067 struct hostent entbuf;
00068 char buffer[4096];
00069 struct hostent * ent (0);
00070 ::gethostbyname2_r(s.c_str(), AF_INET, &entbuf, buffer, sizeof(buffer), &ent, &herr);
00071
00072 # else // ! __GLIBC__
00073
00074 # ifdef _REENTRANT
00075 static boost::mutex mutex;
00076 boost::mutex::scoped_lock lock(mutex);
00077 # endif
00078 struct hostent * ent (::gethostbyname(s.c_str()));
00079 herr = h_errno;
00080
00081 # endif // __GLIBC__
00082
00083 if (!ent)
00084 throw UnknownHostnameException(s);
00085 if (ent->h_addrtype != AF_INET)
00086 throw UnknownHostnameException(s);
00087
00088
00089 return INet4Address::from_inaddr(
00090 reinterpret_cast<in_addr*>(*(ent->h_addr_list))->s_addr);
00091 }
00092
00093 prefix_ bool senf::INet4Address::local()
00094 const
00095 {
00096 address_type l (address());
00097 return
00098 (l & 0xFF000000u) == 0x0A000000u ||
00099 (l & 0xFFF00000u) == 0xAC100000u ||
00100 (l & 0xFFFF0000u) == 0xA9FE0000u ||
00101 (l & 0xFFFF0000u) == 0xC0A80000u;
00102 }
00103
00104 prefix_ bool senf::INet4Address::loopback()
00105 const
00106 {
00107 return (address() & 0xFF000000u) == 0x7F000000u;
00108 }
00109
00110 prefix_ bool senf::INet4Address::multicast()
00111 const
00112 {
00113 return (address() & 0xF0000000u) == 0xE0000000u;
00114 }
00115
00116 prefix_ senf::INet4Address::address_type senf::INet4Address::address()
00117 const
00118 {
00119 return ntohl(iref());
00120 }
00121
00122 senf::INet4Address const senf::INet4Address::None;
00123 senf::INet4Address const senf::INet4Address::Loopback (0x7F000001u);
00124 senf::INet4Address const senf::INet4Address::Broadcast (0xFFFFFFFFu);
00125
00126
00127
00128
00129 prefix_ senf::INet4Network::INet4Network(std::string const & s)
00130 {
00131 std::string::size_type i (s.find('/'));
00132 if (i == std::string::npos)
00133 throw AddressSyntaxException(s);
00134 try {
00135 prefix_len_ = boost::lexical_cast<unsigned>(std::string(s,i+1));
00136 } catch (boost::bad_lexical_cast const &) {
00137 throw AddressSyntaxException(s);
00138 }
00139 address_ = INet4Address(INet4Address::from_string(std::string(s, 0, i)).address() & mask());
00140 }
00141
00142
00143
00144
00145 prefix_ std::ostream & senf::operator<<(std::ostream & os, INet4Address const & addr)
00146 {
00147 ::in_addr ina;
00148 char buffer[16];
00149 ina.s_addr = addr.inaddr();
00150 ::inet_ntop(AF_INET,&ina,buffer,16);
00151 buffer[15] = 0;
00152 os << buffer;
00153 return os;
00154 }
00155
00156 prefix_ std::istream & senf::operator>>(std::istream & is, INet4Address & addr)
00157 {
00158 std::string s;
00159 if (!(is >> s))
00160 return is;
00161 try {
00162 addr = INet4Address::from_string(s);
00163 }
00164 catch (AddressException &) {
00165 is.setstate(std::ios::failbit);
00166 }
00167 return is;
00168 }
00169
00170 prefix_ std::istream & senf::operator>>(std::istream & is, INet4Network & addr)
00171 {
00172 std::string s;
00173 if (!(is >> s))
00174 return is;
00175 try {
00176 addr = INet4Network(s);
00177 }
00178 catch (AddressException &) {
00179 is.setstate(std::ios::failbit);
00180 }
00181 return is;
00182 }
00183
00184
00185 #undef prefix_
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197