Socket/Protocols/INet: Completely new implementation of INet6Address
[senf.git] / Socket / Protocols / INet / INet6Address.cci
1 // Copyright (C) 2007 
2 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
3 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
4 //     Stefan Bund <g0dil@berlios.de>
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the
18 // Free Software Foundation, Inc.,
19 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
21 /** \file
22     \brief INet6Address inline non-template implementation */
23
24 // Custom includes
25 #include <algorithm>
26 #include <boost/lambda/lambda.hpp>
27
28 #define prefix_ inline
29 ///////////////////////////////cci.p///////////////////////////////////////
30
31 prefix_ senf::INet6Address::INet6Address(NoInit_t)
32 {}
33
34 prefix_ senf::INet6Address::INet6Address(boost::uint16_t a0, boost::uint16_t a1,
35                                          boost::uint16_t a2, boost::uint16_t a3,
36                                          boost::uint16_t a4, boost::uint16_t a5,
37                                          boost::uint16_t a6, boost::uint16_t a7)
38 {
39     (*this)[ 0] = boost::uint8_t(a0>>8);
40     (*this)[ 1] = boost::uint8_t(a0);
41     (*this)[ 2] = boost::uint8_t(a1>>8);
42     (*this)[ 3] = boost::uint8_t(a1);
43     (*this)[ 4] = boost::uint8_t(a2>>8);
44     (*this)[ 5] = boost::uint8_t(a2);
45     (*this)[ 6] = boost::uint8_t(a3>>8);
46     (*this)[ 7] = boost::uint8_t(a3);
47     (*this)[ 8] = boost::uint8_t(a4>>8);
48     (*this)[ 9] = boost::uint8_t(a4);
49     (*this)[10] = boost::uint8_t(a5>>8);
50     (*this)[11] = boost::uint8_t(a5);
51     (*this)[12] = boost::uint8_t(a6>>8);
52     (*this)[13] = boost::uint8_t(a6);
53     (*this)[14] = boost::uint8_t(a7>>8);
54     (*this)[15] = boost::uint8_t(a7);
55 }
56
57 prefix_ senf::INet6Address senf::INet6Address::from_inet4address(INet4Address addr4)
58 {
59     INet6Address addr;
60     addr[10] = 0xffu;
61     addr[11] = 0xffu;
62     std::copy(addr4.begin(), addr4.end(), addr.begin()+12);
63     return addr;
64 }
65
66 prefix_ boost::uint64_t senf::INet6Address::network()
67     const
68 {
69     return 
70         ((boost::uint64_t((*this)[0]) & 0xff) << 56 ) |
71         ((boost::uint64_t((*this)[1]) & 0xff) << 48 ) |
72         ((boost::uint64_t((*this)[2]) & 0xff) << 40 ) |
73         ((boost::uint64_t((*this)[3]) & 0xff) << 32 ) |
74         ((boost::uint64_t((*this)[4]) & 0xff) << 24 ) |
75         ((boost::uint64_t((*this)[5]) & 0xff) << 16 ) |
76         ((boost::uint64_t((*this)[6]) & 0xff) <<  8 ) |
77         ((boost::uint64_t((*this)[7]) & 0xff)       );
78 }
79
80 prefix_ bool senf::INet6Address::hasEuid64()
81     const
82 {
83     return unicast() && ((*this)[0]&0xE0u) != 0u;
84 }
85
86 prefix_ boost::uint64_t senf::INet6Address::id()
87     const
88 {
89     return 
90         ((boost::uint64_t((*this)[ 8]) & 0xff) << 56 ) |
91         ((boost::uint64_t((*this)[ 9]) & 0xff) << 48 ) |
92         ((boost::uint64_t((*this)[10]) & 0xff) << 40 ) |
93         ((boost::uint64_t((*this)[11]) & 0xff) << 32 ) |
94         ((boost::uint64_t((*this)[12]) & 0xff) << 24 ) |
95         ((boost::uint64_t((*this)[13]) & 0xff) << 16 ) |
96         ((boost::uint64_t((*this)[14]) & 0xff) <<  8 ) |
97         ((boost::uint64_t((*this)[15]) & 0xff)       );
98 }
99
100 prefix_ bool senf::INet6Address::universalId()
101     const
102 {
103     return (*this)[8] & 2u;
104 }
105
106 prefix_ bool senf::INet6Address::groupId()
107     const
108 {
109     return (*this)[8] & 1u;
110 }
111
112 prefix_ bool senf::INet6Address::unicast()
113     const
114 {
115     return ! multicast();
116 }
117
118 prefix_ bool senf::INet6Address::multicast()
119     const
120 {
121     return (*this)[0] == 0xFFu;
122 }
123
124 prefix_ senf::INet6Address::ScopeId senf::INet6Address::scope()
125     const
126 {
127     static ScopeId const scopeMap[]
128         = { ReservedScope, InterfaceScope, LinkScope, ReservedScope,
129             AdminScope, SiteScope, UnassignedScope, UnassignedScope,
130             OrganizationScope, UnassignedScope, UnassignedScope, UnassignedScope,
131             UnassignedScope, UnassignedScope, GlobalScope, ReservedScope };
132     return multicast() ? scopeMap[(*this)[1] & 0x0Fu] : 
133         (*this)[0] == 0xFEu ? (((*this)[1]&0xC0) == 0x80 ? LinkScope : 
134                                ((*this)[1]&0xC0) == 0xC0 ? SiteScope : GlobalScope ) 
135         : GlobalScope;
136 }
137
138 prefix_ bool senf::INet6Address::globalScope()
139     const
140 {
141     return scope() == GlobalScope;
142 }
143  
144 prefix_ bool senf::INet6Address::linkScope()
145     const
146 {
147     return scope() == LinkScope;
148 }
149
150 prefix_ senf::INet4Address senf::INet6Address::inet4address()
151     const
152 {
153     return INet4Address::from_data(&(*this)[12]);
154 }
155
156 prefix_ bool senf::INet6Address::ipv4Compatible()
157     const
158 {
159     return CheckINet6Network<0u,96>::match(*this);
160 }
161
162 prefix_ bool senf::INet6Address::ipv4Mapped()
163     const
164 {
165     return CheckINet6Network<0u,0u,0u,0u,0u,0xFFFFu,96>::match(*this);
166 }
167
168 prefix_ bool senf::INet6Address::globalMulticastAddr()
169     const
170 {
171     return multicast() && ! ((*this)[1] & 0x10u);
172 }
173
174 prefix_ bool senf::INet6Address::prefixMulticastAddr()
175     const
176 {
177     return multicast() && ((*this)[1] & 0x20u);
178 }
179
180 prefix_ bool senf::INet6Address::embeddedRpAddr()
181     const
182 {
183     return multicast() && ((*this)[1] & 0x40u);
184 }
185
186 prefix_ bool senf::INet6Address::boolean_test()
187     const
188 {
189     using boost::lambda::_1;
190     return std::find_if(begin(),end(), _1 != 0x00) != end();
191 }
192
193 prefix_ void senf::INet6Address::network(boost::uint64_t net)
194 {
195     (*this)[ 0] = net >> 56;
196     (*this)[ 1] = net >> 48;
197     (*this)[ 2] = net >> 40;
198     (*this)[ 3] = net >> 32;
199     (*this)[ 4] = net >> 24;
200     (*this)[ 5] = net >> 16;
201     (*this)[ 6] = net >>  8;
202     (*this)[ 7] = net      ;
203 }
204
205 prefix_ void senf::INet6Address::id(boost::uint64_t id)
206 {
207     (*this)[ 8] = id >> 56;
208     (*this)[ 9] = id >> 48;
209     (*this)[10] = id >> 40;
210     (*this)[11] = id >> 32;
211     (*this)[12] = id >> 24;
212     (*this)[13] = id >> 16;
213     (*this)[14] = id >>  8;
214     (*this)[15] = id      ;
215 }
216
217 ///////////////////////////////cci.e///////////////////////////////////////
218 #undef prefix_
219
220 \f
221 // Local Variables:
222 // mode: c++
223 // fill-column: 100
224 // comment-column: 40
225 // c-file-style: "senf"
226 // indent-tabs-mode: nil
227 // ispell-local-dictionary: "american"
228 // compile-command: "scons -u test"
229 // End: