4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at
9 // http://senf.berlios.de/license.html
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on,
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
15 // Software distributed under the License is distributed on an "AS IS" basis,
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
17 // for the specific language governing rights and limitations under the License.
19 // The Original Code is Fraunhofer FOKUS code.
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V.
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
26 // Stefan Bund <g0dil@berlios.de>
29 \brief INet4Address non-inline non-template implementation */
31 #include "INet4Address.hh"
32 //#include "INet4Address.ih"
35 #include <arpa/inet.h>
37 #include <sys/socket.h>
38 #include <boost/lexical_cast.hpp>
39 #if defined(_REENTRANT) && !defined(__GLIBC__)
40 #include <boost/thread/mutex.hpp>
42 #include <senf/Socket/Protocols/AddressExceptions.hh>
44 //#include "INet4Address.mpp"
46 //-/////////////////////////////////////////////////////////////////////////////////////////////////
48 //-/////////////////////////////////////////////////////////////////////////////////////////////////
49 // senf::INet4Address::INet4Address
51 prefix_ senf::INet4Address::INet4Address(address_type value)
53 iref() = htonl(value);
56 prefix_ senf::INet4Address senf::INet4Address::from_string(std::string const & s)
59 if (::inet_pton(AF_INET,s.c_str(),&ina) > 0)
60 return INet4Address::from_inaddr(ina.s_addr);
63 throw AddressSyntaxException() << ": empty string";
67 // If available, we use the reentrant GNU variant. This has the additional advantage, that we
68 // can explicitly ask for IPv4 addresses
72 struct hostent entbuf;
74 struct hostent * ent (0);
75 ::gethostbyname2_r(s.c_str(), AF_INET, &entbuf, buffer, sizeof(buffer), &ent, &herr);
80 static boost::mutex mutex;
81 boost::mutex::scoped_lock lock(mutex);
83 struct hostent * ent (::gethostbyname(s.c_str()));
89 throw UnknownHostnameException(s);
90 if (ent->h_addrtype != AF_INET)
91 throw UnknownHostnameException(s);
93 // We are only interested in the first address ...
94 return INet4Address::from_inaddr(
95 reinterpret_cast<in_addr*>(*(ent->h_addr_list))->s_addr);
98 prefix_ bool senf::INet4Address::local()
101 address_type l (address());
103 (l & 0xFF000000u) == 0x0A000000u ||
104 (l & 0xFFF00000u) == 0xAC100000u ||
105 (l & 0xFFFF0000u) == 0xA9FE0000u ||
106 (l & 0xFFFF0000u) == 0xC0A80000u;
109 prefix_ bool senf::INet4Address::loopback()
112 return (address() & 0xFF000000u) == 0x7F000000u;
115 prefix_ bool senf::INet4Address::multicast()
118 return (address() & 0xF0000000u) == 0xE0000000u;
121 prefix_ senf::INet4Address::address_type senf::INet4Address::address()
124 return ntohl(iref());
127 senf::INet4Address const senf::INet4Address::None;
128 senf::INet4Address const senf::INet4Address::Loopback (0x7F000001u);
129 senf::INet4Address const senf::INet4Address::Broadcast (0xFFFFFFFFu);
131 //-/////////////////////////////////////////////////////////////////////////////////////////////////
132 // senf::INet4Network
134 prefix_ senf::INet4Network::INet4Network(std::string const & s)
136 std::string::size_type i (s.find('/'));
137 if (i == std::string::npos)
138 throw AddressSyntaxException(s);
140 prefix_len_ = boost::lexical_cast<unsigned>(std::string(s,i+1));
141 } catch (boost::bad_lexical_cast const &) {
142 throw AddressSyntaxException(s);
144 address_ = INet4Address(INet4Address::from_string(std::string(s, 0, i)).address() & mask());
147 //-/////////////////////////////////////////////////////////////////////////////////////////////////
150 prefix_ std::ostream & senf::operator<<(std::ostream & os, INet4Address const & addr)
154 ina.s_addr = addr.inaddr();
155 ::inet_ntop(AF_INET,&ina,buffer,16);
161 prefix_ std::istream & senf::operator>>(std::istream & is, INet4Address & addr)
167 addr = INet4Address::from_string(s);
169 catch (AddressException &) {
170 is.setstate(std::ios::failbit);
175 prefix_ std::istream & senf::operator>>(std::istream & is, INet4Network & addr)
181 addr = INet4Network(s);
183 catch (AddressException &) {
184 is.setstate(std::ios::failbit);
189 //-/////////////////////////////////////////////////////////////////////////////////////////////////
191 //#include "INet4Address.mpp"
197 // comment-column: 40
198 // c-file-style: "senf"
199 // indent-tabs-mode: nil
200 // ispell-local-dictionary: "american"
201 // compile-command: "scons -u test"