00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 #include "INet6Address.ih"
00027
00028
00029 #include <algorithm>
00030 #include <boost/lambda/lambda.hpp>
00031
00032 #define prefix_ inline
00033
00034
00035 prefix_ senf::INet6Address::INet6Address(senf::NoInit_t)
00036 {}
00037
00038 prefix_ senf::INet6Address::INet6Address(boost::uint16_t a0, boost::uint16_t a1,
00039 boost::uint16_t a2, boost::uint16_t a3,
00040 boost::uint16_t a4, boost::uint16_t a5,
00041 boost::uint16_t a6, boost::uint16_t a7)
00042 {
00043 (*this)[ 0] = boost::uint8_t(a0>>8);
00044 (*this)[ 1] = boost::uint8_t(a0);
00045 (*this)[ 2] = boost::uint8_t(a1>>8);
00046 (*this)[ 3] = boost::uint8_t(a1);
00047 (*this)[ 4] = boost::uint8_t(a2>>8);
00048 (*this)[ 5] = boost::uint8_t(a2);
00049 (*this)[ 6] = boost::uint8_t(a3>>8);
00050 (*this)[ 7] = boost::uint8_t(a3);
00051 (*this)[ 8] = boost::uint8_t(a4>>8);
00052 (*this)[ 9] = boost::uint8_t(a4);
00053 (*this)[10] = boost::uint8_t(a5>>8);
00054 (*this)[11] = boost::uint8_t(a5);
00055 (*this)[12] = boost::uint8_t(a6>>8);
00056 (*this)[13] = boost::uint8_t(a6);
00057 (*this)[14] = boost::uint8_t(a7>>8);
00058 (*this)[15] = boost::uint8_t(a7);
00059 }
00060
00061 prefix_ senf::INet6Address senf::INet6Address::from_in6addr(in6_addr const & in6addr)
00062 {
00063 return senf::INet6Address::from_data(&in6addr.s6_addr[0]);
00064 }
00065
00066 prefix_ senf::INet6Address senf::INet6Address::from_inet4address(INet4Address const & addr4)
00067 {
00068 INet6Address addr;
00069 addr[10] = 0xffu;
00070 addr[11] = 0xffu;
00071 std::copy(addr4.begin(), addr4.end(), addr.begin()+12);
00072 return addr;
00073 }
00074
00075 prefix_ senf::INet6Network senf::INet6Address::network()
00076 const
00077 {
00078 return senf::INet6Network(*this, 64);
00079 }
00080
00081 prefix_ bool senf::INet6Address::universalId()
00082 const
00083 {
00084 return (*this)[8] & 2u;
00085 }
00086
00087 prefix_ bool senf::INet6Address::groupId()
00088 const
00089 {
00090 return (*this)[8] & 1u;
00091 }
00092
00093 prefix_ senf::INet4Address senf::INet6Address::inet4address()
00094 const
00095 {
00096 return INet4Address::from_data(&(*this)[12]);
00097 }
00098
00099 prefix_ bool senf::INet6Address::inet4Mapped()
00100 const
00101 {
00102 return CheckINet6Network<0u,0u,0u,0u,0u,0xFFFFu,96>::match(*this);
00103 }
00104
00105 prefix_ bool senf::INet6Address::multicast()
00106 const
00107 {
00108 return (*this)[0] == 0xFFu || (inet4Mapped() && inet4address().multicast());
00109 }
00110
00111 prefix_ senf::INet6Address::ScopeId senf::INet6Address::scope()
00112 const
00113 {
00114 static ScopeId const scopeMap[]
00115 = { ReservedScope, InterfaceScope, LinkScope, ReservedScope,
00116 AdminScope, SiteScope, UnassignedScope, UnassignedScope,
00117 OrganizationScope, UnassignedScope, UnassignedScope, UnassignedScope,
00118 UnassignedScope, UnassignedScope, GlobalScope, ReservedScope };
00119 return multicast() ? scopeMap[(*this)[1] & 0x0Fu] :
00120 (*this)[0] == 0xFEu ? (((*this)[1]&0xC0) == 0x80 ? LinkScope :
00121 ((*this)[1]&0xC0) == 0xC0 ? SiteScope : GlobalScope )
00122 : GlobalScope;
00123 }
00124
00125 prefix_ bool senf::INet6Address::unicast()
00126 const
00127 {
00128 return ! multicast();
00129 }
00130
00131 prefix_ bool senf::INet6Address::hasEUI64()
00132 const
00133 {
00134 return unicast() && ((*this)[0]&0xE0u) != 0u;
00135 }
00136
00137 prefix_ bool senf::INet6Address::globalScope()
00138 const
00139 {
00140 return scope() == GlobalScope;
00141 }
00142
00143 prefix_ bool senf::INet6Address::linkScope()
00144 const
00145 {
00146 return scope() == LinkScope;
00147 }
00148
00149 prefix_ bool senf::INet6Address::inet4Compatible()
00150 const
00151 {
00152 return CheckINet6Network<0u,96>::match(*this);
00153 }
00154
00155 prefix_ bool senf::INet6Address::globalMulticastAddr()
00156 const
00157 {
00158 return multicast() && ! ((*this)[1] & 0x10u);
00159 }
00160
00161 prefix_ bool senf::INet6Address::prefixMulticastAddr()
00162 const
00163 {
00164 return multicast() && ((*this)[1] & 0x20u);
00165 }
00166
00167 prefix_ bool senf::INet6Address::embeddedRpAddr()
00168 const
00169 {
00170 return multicast() && ((*this)[1] & 0x40u);
00171 }
00172
00173 prefix_ bool senf::INet6Address::boolean_test()
00174 const
00175 {
00176 using boost::lambda::_1;
00177 return std::find_if(begin(),end(), _1 != 0x00) != end();
00178 }
00179
00180 prefix_ void senf::INet6Address::network(boost::uint64_t net)
00181 {
00182 (*this)[ 0] = net >> 56;
00183 (*this)[ 1] = net >> 48;
00184 (*this)[ 2] = net >> 40;
00185 (*this)[ 3] = net >> 32;
00186 (*this)[ 4] = net >> 24;
00187 (*this)[ 5] = net >> 16;
00188 (*this)[ 6] = net >> 8;
00189 (*this)[ 7] = net ;
00190 }
00191
00192 prefix_ void senf::INet6Address::id(boost::uint64_t id)
00193 {
00194 (*this)[ 8] = id >> 56;
00195 (*this)[ 9] = id >> 48;
00196 (*this)[10] = id >> 40;
00197 (*this)[11] = id >> 32;
00198 (*this)[12] = id >> 24;
00199 (*this)[13] = id >> 16;
00200 (*this)[14] = id >> 8;
00201 (*this)[15] = id ;
00202 }
00203
00204
00205
00206
00207 prefix_ senf::INet6Network::INet6Network()
00208 : prefix_len_(), address_()
00209 {}
00210
00211 prefix_ senf::INet6Network::INet6Network(INet6Address const & address, unsigned prefix_len)
00212 : prefix_len_(prefix_len), address_(address)
00213 {
00214 using boost::lambda::_1;
00215 using boost::lambda::_2;
00216 detail::apply_mask(prefix_len_, address_.begin(), address_.end(), _1 &= _2);
00217 }
00218
00219 prefix_ senf::INet6Address const & senf::INet6Network::address()
00220 const
00221 {
00222 return address_;
00223 }
00224
00225 prefix_ unsigned senf::INet6Network::prefix_len()
00226 const
00227 {
00228 return prefix_len_;
00229 }
00230
00231 prefix_ bool senf::INet6Network::boolean_test()
00232 const
00233 {
00234 return prefix_len() && address();
00235 }
00236
00237 prefix_ bool senf::INet6Network::operator==(INet6Network const & other)
00238 const
00239 {
00240 return prefix_len() == other.prefix_len() && address() == other.address();
00241 }
00242
00243 prefix_ bool senf::INet6Network::match(INet6Address const & addr)
00244 const
00245 {
00246 using boost::lambda::_1;
00247 using boost::lambda::_2;
00248 using boost::lambda::_3;
00249 return detail::find_if_mask(prefix_len_, address_.begin(), address_.end(), addr.begin(),
00250 _1 != (_2 & _3)) == address_.end();
00251 }
00252
00253 prefix_ bool senf::INet6Network::match(INet6Network const & net)
00254 const
00255 {
00256 return net.prefix_len() >= prefix_len() && match(net.address());
00257 }
00258
00259 prefix_ senf::INet6Address senf::INet6Network::host(boost::uint64_t id)
00260 {
00261 INet6Address addr (address());
00262 addr.id(id);
00263 return addr;
00264 }
00265
00266 prefix_ senf::INet6Network senf::INet6Network::subnet(boost::uint64_t net, unsigned prefix_len)
00267 {
00268 using boost::lambda::_1;
00269 using boost::lambda::_2;
00270 using boost::lambda::var;
00271 using boost::lambda::ret;
00272 INet6Address addr (address());
00273 net <<= (64-prefix_len);
00274 detail::apply_mask(prefix_len, addr.begin(), addr.end(),
00275 ( ( _1 |= ret<boost::uint8_t>((var(net) >> 56) & _2) ),
00276 ( var(net) <<= 8 ) ));
00277 return INet6Network(addr, prefix_len);
00278 }
00279
00280 prefix_ std::ostream & senf::operator<<(std::ostream & os, INet6Network const & addr)
00281 {
00282 os << addr.address() << '/' << addr.prefix_len();
00283 return os;
00284 }
00285
00286
00287
00288
00289 prefix_ boost::uint8_t senf::detail::low_bits_mask(unsigned bits)
00290 {
00291 return ((1<<bits)-1);
00292 }
00293
00294
00295 #undef prefix_
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306