INet6Address.cci

Go to the documentation of this file.
00001 // $Id: INet6Address.cci 1742 2010-11-04 14:51:56Z g0dil $
00002 //
00003 // Copyright (C) 2007
00004 // Fraunhofer (FOKUS)
00005 // Competence Center NETwork research (NET), St. Augustin, GERMANY
00006 //     Stefan Bund <g0dil@berlios.de>
00007 //
00008 // This program is free software; you can redistribute it and/or modify
00009 // it under the terms of the GNU General Public License as published by
00010 // the Free Software Foundation; either version 2 of the License, or
00011 // (at your option) any later version.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the
00020 // Free Software Foundation, Inc.,
00021 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00026 #include "INet6Address.ih"
00027 
00028 // Custom includes
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 // senf::INet6Network
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 // namespace senf::detail members
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 // Local Variables:
00299 // mode: c++
00300 // fill-column: 100
00301 // comment-column: 40
00302 // c-file-style: "senf"
00303 // indent-tabs-mode: nil
00304 // ispell-local-dictionary: "american"
00305 // compile-command: "scons -u test"
00306 // End: