Fix SCons 1.2.0 build failure
[senf.git] / senf / Socket / Protocols / INet / INet6Address.cci
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
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.
12 //
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.
17 //
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.
22
23 /** \file
24     \brief INet6Address inline non-template implementation */
25
26 #include "INet6Address.ih"
27
28 // Custom includes
29 #include <algorithm>
30 #include <boost/lambda/lambda.hpp>
31
32 #define prefix_ inline
33 ///////////////////////////////cci.p///////////////////////////////////////
34
35 prefix_ senf::INet6Address::INet6Address(senf::NoInit_t)
36 {}
37
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)
42 {
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);
59 }
60
61 prefix_ senf::INet6Address senf::INet6Address::from_in6addr(in6_addr const & in6addr)
62 {
63     return senf::INet6Address::from_data(&in6addr.s6_addr[0]);
64 }
65
66 prefix_ senf::INet6Address senf::INet6Address::from_inet4address(INet4Address const & addr4)
67 {
68     INet6Address addr;
69     addr[10] = 0xffu;
70     addr[11] = 0xffu;
71     std::copy(addr4.begin(), addr4.end(), addr.begin()+12);
72     return addr;
73 }
74
75 prefix_ senf::INet6Address senf::INet6Address::from_mac(senf::MACAddress const & mac)
76 {
77     INet6Address addr;
78     addr[0] = 0xfe;
79     addr[1] = 0x80;
80     addr[8] = mac[0];
81     addr[9] = mac[1];
82     addr[10] = mac[2];
83     addr[11] = 0xff;
84     addr[12] = 0xfe;
85     addr[13] = mac[3];
86     addr[14] = mac[4];
87     addr[15] = mac[5];
88     return addr;
89 }
90
91 prefix_ senf::INet6Address senf::INet6Address::from_eui64(senf::EUI64 const & eui)
92 {
93     INet6Address addr;
94     addr[0] = 0xfe;
95     addr[1] = 0x80;
96     std::copy(eui.begin(), eui.end(), addr.begin()+8);
97     return addr;
98 }
99
100 prefix_ senf::INet6Network senf::INet6Address::network()
101     const
102 {
103     return senf::INet6Network(*this, 64);
104 }
105
106 prefix_ senf::EUI64 senf::INet6Address::id()
107     const
108 {
109     return senf::EUI64::from_data(begin()+8);
110 }
111
112 prefix_ bool senf::INet6Address::universalId()
113     const
114 {
115     return (*this)[8] & 2u;
116 }
117
118 prefix_ bool senf::INet6Address::groupId()
119     const
120 {
121     return (*this)[8] & 1u;
122 }
123
124 prefix_ senf::INet4Address senf::INet6Address::inet4address()
125     const
126 {
127     return INet4Address::from_data(&(*this)[12]);
128 }
129
130 prefix_ bool senf::INet6Address::inet4Mapped()
131     const
132 {
133     return CheckINet6Network<0u,0u,0u,0u,0u,0xFFFFu,96>::match(*this);
134 }
135
136 prefix_ bool senf::INet6Address::multicast()
137     const
138 {
139     return (*this)[0] == 0xFFu || (inet4Mapped() && inet4address().multicast());
140 }
141
142 prefix_ senf::INet6Address::ScopeId senf::INet6Address::scope()
143     const
144 {
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 )
153         : GlobalScope;
154 }
155
156 prefix_ bool senf::INet6Address::unicast()
157     const
158 {
159     return ! multicast();
160 }
161
162 prefix_ bool senf::INet6Address::hasEUI64()
163     const
164 {
165     return unicast() && ((*this)[0]&0xE0u) != 0u;
166 }
167
168 prefix_ bool senf::INet6Address::globalScope()
169     const
170 {
171     return scope() == GlobalScope;
172 }
173
174 prefix_ bool senf::INet6Address::linkScope()
175     const
176 {
177     return scope() == LinkScope;
178 }
179
180 prefix_ bool senf::INet6Address::inet4Compatible()
181     const
182 {
183     return CheckINet6Network<0u,96>::match(*this);
184 }
185
186 prefix_ bool senf::INet6Address::globalMulticastAddr()
187     const
188 {
189     return multicast() && ! ((*this)[1] & 0x10u);
190 }
191
192 prefix_ bool senf::INet6Address::prefixMulticastAddr()
193     const
194 {
195     return multicast() && ((*this)[1] & 0x20u);
196 }
197
198 prefix_ bool senf::INet6Address::embeddedRpAddr()
199     const
200 {
201     return multicast() && ((*this)[1] & 0x40u);
202 }
203
204 prefix_ bool senf::INet6Address::boolean_test()
205     const
206 {
207     using boost::lambda::_1;
208     return std::find_if(begin(),end(), _1 != 0x00) != end();
209 }
210
211 prefix_ void senf::INet6Address::network(boost::uint64_t net)
212 {
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;
220     (*this)[ 7] = net      ;
221 }
222
223 prefix_ void senf::INet6Address::id(boost::uint64_t id)
224 {
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;
232     (*this)[15] = id      ;
233 }
234
235 ///////////////////////////////////////////////////////////////////////////
236 // senf::INet6Network
237
238 prefix_ senf::INet6Network::INet6Network()
239     : prefix_len_(), address_()
240 {}
241
242 prefix_ senf::INet6Network::INet6Network(INet6Address const & address, unsigned prefix_len)
243     : prefix_len_(prefix_len), address_(address)
244 {
245     using boost::lambda::_1;
246     using boost::lambda::_2;
247     detail::apply_mask(prefix_len_, address_.begin(), address_.end(), _1 &= _2);
248 }
249
250 prefix_ senf::INet6Address const & senf::INet6Network::address()
251     const
252 {
253     return address_;
254 }
255
256 prefix_ unsigned senf::INet6Network::prefix_len()
257     const
258 {
259     return prefix_len_;
260 }
261
262 prefix_ bool senf::INet6Network::boolean_test()
263     const
264 {
265     return prefix_len() && address();
266 }
267
268 prefix_ bool senf::INet6Network::operator==(INet6Network const & other)
269     const
270 {
271     return prefix_len() == other.prefix_len() && address() == other.address();
272 }
273
274 prefix_ bool senf::INet6Network::match(INet6Address const & addr)
275     const
276 {
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();
282 }
283
284 prefix_ bool senf::INet6Network::match(INet6Network const & net)
285     const
286 {
287     return net.prefix_len() >= prefix_len() && match(net.address());
288 }
289
290 prefix_ senf::INet6Address senf::INet6Network::host(boost::uint64_t id)
291 {
292     INet6Address addr (address());
293     addr.id(id);
294     return addr;
295 }
296
297 prefix_ senf::INet6Network senf::INet6Network::subnet(boost::uint64_t net, unsigned prefix_len)
298 {
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);
309 }
310
311 prefix_ std::ostream & senf::operator<<(std::ostream & os, INet6Network const & addr)
312 {
313     os << addr.address() << '/' << addr.prefix_len();
314     return os;
315 }
316
317 ///////////////////////////////////////////////////////////////////////////
318 // namespace senf::detail members
319
320 prefix_ boost::uint8_t senf::detail::low_bits_mask(unsigned bits)
321 {
322     return ((1<<bits)-1);
323 }
324
325 ///////////////////////////////cci.e///////////////////////////////////////
326 #undef prefix_
327
328
329 // Local Variables:
330 // mode: c++
331 // fill-column: 100
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"
337 // End: