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>
43 //#include "INet4Address.mpp"
45 //-/////////////////////////////////////////////////////////////////////////////////////////////////
47 //-/////////////////////////////////////////////////////////////////////////////////////////////////
48 // senf::INet4Address::INet4Address
50 prefix_ senf::INet4Address::INet4Address(address_type value)
52 iref() = htonl(value);
55 prefix_ senf::INet4Address senf::INet4Address::from_string(std::string const & s)
58 if (::inet_pton(AF_INET,s.c_str(),&ina) > 0)
59 return INet4Address::from_inaddr(ina.s_addr);
62 throw AddressSyntaxException() << ": empty string";
66 // If available, we use the reentrant GNU variant. This has the additional advantage, that we
67 // can explicitly ask for IPv4 addresses
71 struct hostent entbuf;
73 struct hostent * ent (0);
74 ::gethostbyname2_r(s.c_str(), AF_INET, &entbuf, buffer, sizeof(buffer), &ent, &herr);
79 static boost::mutex mutex;
80 boost::mutex::scoped_lock lock(mutex);
82 struct hostent * ent (::gethostbyname(s.c_str()));
88 throw UnknownHostnameException(s);
89 if (ent->h_addrtype != AF_INET)
90 throw UnknownHostnameException(s);
92 // We are only interested in the first address ...
93 return INet4Address::from_inaddr(
94 reinterpret_cast<in_addr*>(*(ent->h_addr_list))->s_addr);
97 prefix_ bool senf::INet4Address::local()
100 address_type l (address());
102 (l & 0xFF000000u) == 0x0A000000u ||
103 (l & 0xFFF00000u) == 0xAC100000u ||
104 (l & 0xFFFF0000u) == 0xA9FE0000u ||
105 (l & 0xFFFF0000u) == 0xC0A80000u;
108 prefix_ bool senf::INet4Address::loopback()
111 return (address() & 0xFF000000u) == 0x7F000000u;
114 prefix_ bool senf::INet4Address::multicast()
117 return (address() & 0xF0000000u) == 0xE0000000u;
120 prefix_ senf::INet4Address::address_type senf::INet4Address::address()
123 return ntohl(iref());
126 senf::INet4Address const senf::INet4Address::None;
127 senf::INet4Address const senf::INet4Address::Loopback (0x7F000001u);
128 senf::INet4Address const senf::INet4Address::Broadcast (0xFFFFFFFFu);
130 //-/////////////////////////////////////////////////////////////////////////////////////////////////
131 // senf::INet4Network
133 prefix_ senf::INet4Network::INet4Network(std::string const & s)
135 std::string::size_type i (s.find('/'));
136 if (i == std::string::npos)
137 throw AddressSyntaxException(s);
139 prefix_len_ = prefix_len_checked(boost::lexical_cast<unsigned>(std::string(s,i+1)));
140 } catch (boost::bad_lexical_cast const &) {
141 throw AddressSyntaxException(s);
143 address_ = INet4Address(INet4Address::from_string(std::string(s, 0, i)).address() & mask());
146 //-/////////////////////////////////////////////////////////////////////////////////////////////////
149 prefix_ std::ostream & senf::operator<<(std::ostream & os, INet4Address const & addr)
153 ina.s_addr = addr.inaddr();
154 ::inet_ntop(AF_INET,&ina,buffer,16);
160 prefix_ std::istream & senf::operator>>(std::istream & is, INet4Address & addr)
166 addr = INet4Address::from_string(s);
168 catch (AddressException &) {
169 is.setstate(std::ios::failbit);
174 prefix_ std::istream & senf::operator>>(std::istream & is, INet4Network & addr)
180 addr = INet4Network(s);
182 catch (AddressException &) {
183 is.setstate(std::ios::failbit);
188 //-/////////////////////////////////////////////////////////////////////////////////////////////////
190 //#include "INet4Address.mpp"
196 // comment-column: 40
197 // c-file-style: "senf"
198 // indent-tabs-mode: nil
199 // ispell-local-dictionary: "american"
200 // compile-command: "scons -u test"