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 INet6Address inline non-template implementation */
31 #include "INet6Address.ih"
35 #include <boost/lambda/lambda.hpp>
37 #define prefix_ inline
38 //-/////////////////////////////////////////////////////////////////////////////////////////////////
40 prefix_ senf::INet6Address::INet6Address(senf::NoInit_t)
43 prefix_ senf::INet6Address::INet6Address(boost::uint16_t a0, boost::uint16_t a1,
44 boost::uint16_t a2, boost::uint16_t a3,
45 boost::uint16_t a4, boost::uint16_t a5,
46 boost::uint16_t a6, boost::uint16_t a7)
48 (*this)[ 0] = boost::uint8_t(a0>>8);
49 (*this)[ 1] = boost::uint8_t(a0);
50 (*this)[ 2] = boost::uint8_t(a1>>8);
51 (*this)[ 3] = boost::uint8_t(a1);
52 (*this)[ 4] = boost::uint8_t(a2>>8);
53 (*this)[ 5] = boost::uint8_t(a2);
54 (*this)[ 6] = boost::uint8_t(a3>>8);
55 (*this)[ 7] = boost::uint8_t(a3);
56 (*this)[ 8] = boost::uint8_t(a4>>8);
57 (*this)[ 9] = boost::uint8_t(a4);
58 (*this)[10] = boost::uint8_t(a5>>8);
59 (*this)[11] = boost::uint8_t(a5);
60 (*this)[12] = boost::uint8_t(a6>>8);
61 (*this)[13] = boost::uint8_t(a6);
62 (*this)[14] = boost::uint8_t(a7>>8);
63 (*this)[15] = boost::uint8_t(a7);
66 prefix_ senf::INet6Address senf::INet6Address::from_in6addr(in6_addr const & in6addr)
68 return senf::INet6Address::from_data(&in6addr.s6_addr[0]);
71 prefix_ senf::INet6Address senf::INet6Address::from_inet4address(INet4Address const & addr4)
76 std::copy(addr4.begin(), addr4.end(), addr.begin()+12);
80 prefix_ senf::INet6Network senf::INet6Address::network()
83 return senf::INet6Network(*this, 64);
86 prefix_ bool senf::INet6Address::universalId()
89 return (*this)[8] & 2u;
92 prefix_ bool senf::INet6Address::groupId()
95 return (*this)[8] & 1u;
98 prefix_ senf::INet4Address senf::INet6Address::inet4address()
101 return INet4Address::from_data(&(*this)[12]);
104 prefix_ bool senf::INet6Address::inet4Mapped()
107 return CheckINet6Network<0u,0u,0u,0u,0u,0xFFFFu,96>::match(*this);
110 prefix_ bool senf::INet6Address::multicast()
113 return (*this)[0] == 0xFFu || (inet4Mapped() && inet4address().multicast());
116 prefix_ senf::INet6Address::ScopeId senf::INet6Address::scope()
119 static ScopeId const scopeMap[]
120 = { ReservedScope, InterfaceScope, LinkScope, ReservedScope,
121 AdminScope, SiteScope, UnassignedScope, UnassignedScope,
122 OrganizationScope, UnassignedScope, UnassignedScope, UnassignedScope,
123 UnassignedScope, UnassignedScope, GlobalScope, ReservedScope };
124 return multicast() ? scopeMap[(*this)[1] & 0x0Fu] :
125 (*this)[0] == 0xFEu ? (((*this)[1]&0xC0) == 0x80 ? LinkScope :
126 ((*this)[1]&0xC0) == 0xC0 ? SiteScope : GlobalScope )
130 prefix_ bool senf::INet6Address::unicast()
133 return ! multicast();
136 prefix_ bool senf::INet6Address::hasEUI64()
139 return unicast() && ((*this)[0]&0xE0u) != 0u;
142 prefix_ bool senf::INet6Address::globalScope()
145 return scope() == GlobalScope;
148 prefix_ bool senf::INet6Address::linkScope()
151 return scope() == LinkScope;
154 prefix_ bool senf::INet6Address::inet4Compatible()
157 return CheckINet6Network<0u,96>::match(*this);
160 prefix_ bool senf::INet6Address::globalMulticastAddr()
163 return multicast() && ! ((*this)[1] & 0x10u);
166 prefix_ bool senf::INet6Address::prefixMulticastAddr()
169 return multicast() && ((*this)[1] & 0x20u);
172 prefix_ bool senf::INet6Address::embeddedRpAddr()
175 return multicast() && ((*this)[1] & 0x40u);
178 prefix_ bool senf::INet6Address::boolean_test()
181 using boost::lambda::_1;
182 return std::find_if(begin(),end(), _1 != 0x00) != end();
185 prefix_ void senf::INet6Address::network(boost::uint64_t net)
187 (*this)[ 0] = net >> 56;
188 (*this)[ 1] = net >> 48;
189 (*this)[ 2] = net >> 40;
190 (*this)[ 3] = net >> 32;
191 (*this)[ 4] = net >> 24;
192 (*this)[ 5] = net >> 16;
193 (*this)[ 6] = net >> 8;
197 prefix_ void senf::INet6Address::id(boost::uint64_t id)
199 (*this)[ 8] = id >> 56;
200 (*this)[ 9] = id >> 48;
201 (*this)[10] = id >> 40;
202 (*this)[11] = id >> 32;
203 (*this)[12] = id >> 24;
204 (*this)[13] = id >> 16;
205 (*this)[14] = id >> 8;
209 //-/////////////////////////////////////////////////////////////////////////////////////////////////
210 // senf::INet6Network
212 prefix_ senf::INet6Network::INet6Network()
213 : prefix_len_(), address_()
216 prefix_ senf::INet6Network::INet6Network(INet6Address const & address, unsigned prefix_len)
217 : prefix_len_(prefix_len), address_(address)
219 using boost::lambda::_1;
220 using boost::lambda::_2;
221 detail::apply_mask(prefix_len_, address_.begin(), address_.end(), _1 &= _2);
224 prefix_ senf::INet6Address const & senf::INet6Network::address()
230 prefix_ unsigned senf::INet6Network::prefix_len()
236 prefix_ bool senf::INet6Network::boolean_test()
239 return prefix_len() && address();
242 prefix_ bool senf::INet6Network::operator==(INet6Network const & other)
245 return prefix_len() == other.prefix_len() && address() == other.address();
248 prefix_ bool senf::INet6Network::match(INet6Address const & addr)
251 using boost::lambda::_1;
252 using boost::lambda::_2;
253 using boost::lambda::_3;
254 return detail::find_if_mask(prefix_len_, address_.begin(), address_.end(), addr.begin(),
255 _1 != (_2 & _3)) == address_.end();
258 prefix_ bool senf::INet6Network::match(INet6Network const & net)
261 return net.prefix_len() >= prefix_len() && match(net.address());
264 prefix_ senf::INet6Address senf::INet6Network::host(boost::uint64_t id)
266 INet6Address addr (address());
271 prefix_ senf::INet6Network senf::INet6Network::subnet(boost::uint64_t net, unsigned prefix_len)
273 using boost::lambda::_1;
274 using boost::lambda::_2;
275 using boost::lambda::var;
276 using boost::lambda::ret;
277 INet6Address addr (address());
278 net <<= (64-prefix_len);
279 detail::apply_mask(prefix_len, addr.begin(), addr.end(),
280 ( ( _1 |= ret<boost::uint8_t>((var(net) >> 56) & _2) ),
281 ( var(net) <<= 8 ) ));
282 return INet6Network(addr, prefix_len);
285 prefix_ std::ostream & senf::operator<<(std::ostream & os, INet6Network const & addr)
287 os << addr.address() << '/' << addr.prefix_len();
291 //-/////////////////////////////////////////////////////////////////////////////////////////////////
292 // namespace senf::detail members
294 prefix_ boost::uint8_t senf::detail::low_bits_mask(unsigned bits)
296 return ((1<<bits)-1);
299 //-/////////////////////////////////////////////////////////////////////////////////////////////////
306 // comment-column: 40
307 // c-file-style: "senf"
308 // indent-tabs-mode: nil
309 // ispell-local-dictionary: "american"
310 // compile-command: "scons -u test"