4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 \brief INet6Address inline non-template implementation */
26 #include "INet6Address.ih"
30 #include <boost/lambda/lambda.hpp>
32 #define prefix_ inline
33 ///////////////////////////////cci.p///////////////////////////////////////
35 prefix_ senf::INet6Address::INet6Address(senf::NoInit_t)
38 prefix_ senf::INet6Address::INet6Address(boost::uint16_t a0, boost::uint16_t a1,
39 boost::uint16_t a2, boost::uint16_t a3,
40 boost::uint16_t a4, boost::uint16_t a5,
41 boost::uint16_t a6, boost::uint16_t a7)
43 (*this)[ 0] = boost::uint8_t(a0>>8);
44 (*this)[ 1] = boost::uint8_t(a0);
45 (*this)[ 2] = boost::uint8_t(a1>>8);
46 (*this)[ 3] = boost::uint8_t(a1);
47 (*this)[ 4] = boost::uint8_t(a2>>8);
48 (*this)[ 5] = boost::uint8_t(a2);
49 (*this)[ 6] = boost::uint8_t(a3>>8);
50 (*this)[ 7] = boost::uint8_t(a3);
51 (*this)[ 8] = boost::uint8_t(a4>>8);
52 (*this)[ 9] = boost::uint8_t(a4);
53 (*this)[10] = boost::uint8_t(a5>>8);
54 (*this)[11] = boost::uint8_t(a5);
55 (*this)[12] = boost::uint8_t(a6>>8);
56 (*this)[13] = boost::uint8_t(a6);
57 (*this)[14] = boost::uint8_t(a7>>8);
58 (*this)[15] = boost::uint8_t(a7);
61 prefix_ senf::INet6Address senf::INet6Address::from_in6addr(in6_addr const & in6addr)
63 return senf::INet6Address::from_data(&in6addr.s6_addr[0]);
66 prefix_ senf::INet6Address senf::INet6Address::from_inet4address(INet4Address const & addr4)
71 std::copy(addr4.begin(), addr4.end(), addr.begin()+12);
75 prefix_ senf::INet6Address senf::INet6Address::from_mac(senf::MACAddress const & mac)
91 prefix_ senf::INet6Address senf::INet6Address::from_eui64(senf::EUI64 const & eui)
96 std::copy(eui.begin(), eui.end(), addr.begin()+8);
100 prefix_ senf::INet6Network senf::INet6Address::network()
103 return senf::INet6Network(*this, 64);
106 prefix_ senf::EUI64 senf::INet6Address::id()
109 return senf::EUI64::from_data(begin()+8);
112 prefix_ bool senf::INet6Address::universalId()
115 return (*this)[8] & 2u;
118 prefix_ bool senf::INet6Address::groupId()
121 return (*this)[8] & 1u;
124 prefix_ senf::INet4Address senf::INet6Address::inet4address()
127 return INet4Address::from_data(&(*this)[12]);
130 prefix_ bool senf::INet6Address::inet4Mapped()
133 return CheckINet6Network<0u,0u,0u,0u,0u,0xFFFFu,96>::match(*this);
136 prefix_ bool senf::INet6Address::multicast()
139 return (*this)[0] == 0xFFu || (inet4Mapped() && inet4address().multicast());
142 prefix_ senf::INet6Address::ScopeId senf::INet6Address::scope()
145 static ScopeId const scopeMap[]
146 = { ReservedScope, InterfaceScope, LinkScope, ReservedScope,
147 AdminScope, SiteScope, UnassignedScope, UnassignedScope,
148 OrganizationScope, UnassignedScope, UnassignedScope, UnassignedScope,
149 UnassignedScope, UnassignedScope, GlobalScope, ReservedScope };
150 return multicast() ? scopeMap[(*this)[1] & 0x0Fu] :
151 (*this)[0] == 0xFEu ? (((*this)[1]&0xC0) == 0x80 ? LinkScope :
152 ((*this)[1]&0xC0) == 0xC0 ? SiteScope : GlobalScope )
156 prefix_ bool senf::INet6Address::unicast()
159 return ! multicast();
162 prefix_ bool senf::INet6Address::hasEUI64()
165 return unicast() && ((*this)[0]&0xE0u) != 0u;
168 prefix_ bool senf::INet6Address::globalScope()
171 return scope() == GlobalScope;
174 prefix_ bool senf::INet6Address::linkScope()
177 return scope() == LinkScope;
180 prefix_ bool senf::INet6Address::inet4Compatible()
183 return CheckINet6Network<0u,96>::match(*this);
186 prefix_ bool senf::INet6Address::globalMulticastAddr()
189 return multicast() && ! ((*this)[1] & 0x10u);
192 prefix_ bool senf::INet6Address::prefixMulticastAddr()
195 return multicast() && ((*this)[1] & 0x20u);
198 prefix_ bool senf::INet6Address::embeddedRpAddr()
201 return multicast() && ((*this)[1] & 0x40u);
204 prefix_ bool senf::INet6Address::boolean_test()
207 using boost::lambda::_1;
208 return std::find_if(begin(),end(), _1 != 0x00) != end();
211 prefix_ void senf::INet6Address::network(boost::uint64_t net)
213 (*this)[ 0] = net >> 56;
214 (*this)[ 1] = net >> 48;
215 (*this)[ 2] = net >> 40;
216 (*this)[ 3] = net >> 32;
217 (*this)[ 4] = net >> 24;
218 (*this)[ 5] = net >> 16;
219 (*this)[ 6] = net >> 8;
223 prefix_ void senf::INet6Address::id(boost::uint64_t id)
225 (*this)[ 8] = id >> 56;
226 (*this)[ 9] = id >> 48;
227 (*this)[10] = id >> 40;
228 (*this)[11] = id >> 32;
229 (*this)[12] = id >> 24;
230 (*this)[13] = id >> 16;
231 (*this)[14] = id >> 8;
235 ///////////////////////////////////////////////////////////////////////////
236 // senf::INet6Network
238 prefix_ senf::INet6Network::INet6Network()
239 : prefix_len_(), address_()
242 prefix_ senf::INet6Network::INet6Network(INet6Address const & address, unsigned prefix_len)
243 : prefix_len_(prefix_len), address_(address)
245 using boost::lambda::_1;
246 using boost::lambda::_2;
247 detail::apply_mask(prefix_len_, address_.begin(), address_.end(), _1 &= _2);
250 prefix_ senf::INet6Address const & senf::INet6Network::address()
256 prefix_ unsigned senf::INet6Network::prefix_len()
262 prefix_ bool senf::INet6Network::boolean_test()
265 return prefix_len() && address();
268 prefix_ bool senf::INet6Network::operator==(INet6Network const & other)
271 return prefix_len() == other.prefix_len() && address() == other.address();
274 prefix_ bool senf::INet6Network::match(INet6Address const & addr)
277 using boost::lambda::_1;
278 using boost::lambda::_2;
279 using boost::lambda::_3;
280 return detail::find_if_mask(prefix_len_, address_.begin(), address_.end(), addr.begin(),
281 _1 != (_2 & _3)) == address_.end();
284 prefix_ bool senf::INet6Network::match(INet6Network const & net)
287 return net.prefix_len() >= prefix_len() && match(net.address());
290 prefix_ senf::INet6Address senf::INet6Network::host(boost::uint64_t id)
292 INet6Address addr (address());
297 prefix_ senf::INet6Network senf::INet6Network::subnet(boost::uint64_t net, unsigned prefix_len)
299 using boost::lambda::_1;
300 using boost::lambda::_2;
301 using boost::lambda::var;
302 using boost::lambda::ret;
303 INet6Address addr (address());
304 net <<= (64-prefix_len);
305 detail::apply_mask(prefix_len, addr.begin(), addr.end(),
306 ( ( _1 |= ret<boost::uint8_t>((var(net) >> 56) & _2) ),
307 ( var(net) <<= 8 ) ));
308 return INet6Network(addr, prefix_len);
311 prefix_ std::ostream & senf::operator<<(std::ostream & os, INet6Network const & addr)
313 os << addr.address() << '/' << addr.prefix_len();
317 ///////////////////////////////////////////////////////////////////////////
318 // namespace senf::detail members
320 prefix_ boost::uint8_t senf::detail::low_bits_mask(unsigned bits)
322 return ((1<<bits)-1);
325 ///////////////////////////////cci.e///////////////////////////////////////
332 // comment-column: 40
333 // c-file-style: "senf"
334 // indent-tabs-mode: nil
335 // ispell-local-dictionary: "american"
336 // compile-command: "scons -u test"