X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Socket%2FProtocols%2FINet%2FINet6Address.cci;h=f94c0d77fe137f44e06c5220755965cf84bc9958;hb=5443435c4c2b6e4386c5334b5b8358273f2bae93;hp=c3072b0c59825f6844523389883963bbcdbe19f0;hpb=ced8f321adf904c31149162de5f6258c971c7466;p=senf.git diff --git a/Socket/Protocols/INet/INet6Address.cci b/Socket/Protocols/INet/INet6Address.cci index c3072b0..f94c0d7 100644 --- a/Socket/Protocols/INet/INet6Address.cci +++ b/Socket/Protocols/INet/INet6Address.cci @@ -1,8 +1,8 @@ // $Id$ // -// Copyright (C) 2007 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Copyright (C) 2007 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY // Stefan Bund // // This program is free software; you can redistribute it and/or modify @@ -23,6 +23,8 @@ /** \file \brief INet6Address inline non-template implementation */ +#include "INet6Address.ih" + // Custom includes #include #include @@ -30,7 +32,7 @@ #define prefix_ inline ///////////////////////////////cci.p/////////////////////////////////////// -prefix_ senf::INet6Address::INet6Address(NoInit_t) +prefix_ senf::INet6Address::INet6Address(senf::NoInit_t) {} prefix_ senf::INet6Address::INet6Address(boost::uint16_t a0, boost::uint16_t a1, @@ -56,7 +58,12 @@ prefix_ senf::INet6Address::INet6Address(boost::uint16_t a0, boost::uint16_t a1, (*this)[15] = boost::uint8_t(a7); } -prefix_ senf::INet6Address senf::INet6Address::from_inet4address(INet4Address addr4) +prefix_ senf::INet6Address senf::INet6Address::from_in6addr(in6_addr const & in6addr) +{ + return senf::INet6Address::from_data(&in6addr.s6_addr[0]); +} + +prefix_ senf::INet6Address senf::INet6Address::from_inet4address(INet4Address const & addr4) { INet6Address addr; addr[10] = 0xffu; @@ -65,38 +72,41 @@ prefix_ senf::INet6Address senf::INet6Address::from_inet4address(INet4Address ad return addr; } -prefix_ boost::uint64_t senf::INet6Address::network() - const +prefix_ senf::INet6Address senf::INet6Address::from_mac(senf::MACAddress const & mac) { - return - ((boost::uint64_t((*this)[0]) & 0xff) << 56 ) | - ((boost::uint64_t((*this)[1]) & 0xff) << 48 ) | - ((boost::uint64_t((*this)[2]) & 0xff) << 40 ) | - ((boost::uint64_t((*this)[3]) & 0xff) << 32 ) | - ((boost::uint64_t((*this)[4]) & 0xff) << 24 ) | - ((boost::uint64_t((*this)[5]) & 0xff) << 16 ) | - ((boost::uint64_t((*this)[6]) & 0xff) << 8 ) | - ((boost::uint64_t((*this)[7]) & 0xff) ); + INet6Address addr; + addr[0] = 0xfe; + addr[1] = 0x80; + addr[8] = mac[0]; + addr[9] = mac[1]; + addr[10] = mac[2]; + addr[11] = 0xff; + addr[12] = 0xfe; + addr[13] = mac[3]; + addr[14] = mac[4]; + addr[15] = mac[5]; + return addr; +} + +prefix_ senf::INet6Address senf::INet6Address::from_eui64(senf::EUI64 const & eui) +{ + INet6Address addr; + addr[0] = 0xfe; + addr[1] = 0x80; + std::copy(eui.begin(), eui.end(), addr.begin()+8); + return addr; } -prefix_ bool senf::INet6Address::hasEuid64() +prefix_ senf::INet6Network senf::INet6Address::network() const { - return unicast() && ((*this)[0]&0xE0u) != 0u; + return senf::INet6Network(*this, 64); } -prefix_ boost::uint64_t senf::INet6Address::id() +prefix_ senf::EUI64 senf::INet6Address::id() const { - return - ((boost::uint64_t((*this)[ 8]) & 0xff) << 56 ) | - ((boost::uint64_t((*this)[ 9]) & 0xff) << 48 ) | - ((boost::uint64_t((*this)[10]) & 0xff) << 40 ) | - ((boost::uint64_t((*this)[11]) & 0xff) << 32 ) | - ((boost::uint64_t((*this)[12]) & 0xff) << 24 ) | - ((boost::uint64_t((*this)[13]) & 0xff) << 16 ) | - ((boost::uint64_t((*this)[14]) & 0xff) << 8 ) | - ((boost::uint64_t((*this)[15]) & 0xff) ); + return senf::EUI64::from_data(begin()+8); } prefix_ bool senf::INet6Address::universalId() @@ -111,16 +121,22 @@ prefix_ bool senf::INet6Address::groupId() return (*this)[8] & 1u; } -prefix_ bool senf::INet6Address::unicast() +prefix_ senf::INet4Address senf::INet6Address::inet4address() const { - return ! multicast(); + return INet4Address::from_data(&(*this)[12]); +} + +prefix_ bool senf::INet6Address::inet4Mapped() + const +{ + return CheckINet6Network<0u,0u,0u,0u,0u,0xFFFFu,96>::match(*this); } prefix_ bool senf::INet6Address::multicast() const { - return (*this)[0] == 0xFFu; + return (*this)[0] == 0xFFu || (inet4Mapped() && inet4address().multicast()); } prefix_ senf::INet6Address::ScopeId senf::INet6Address::scope() @@ -131,40 +147,40 @@ prefix_ senf::INet6Address::ScopeId senf::INet6Address::scope() AdminScope, SiteScope, UnassignedScope, UnassignedScope, OrganizationScope, UnassignedScope, UnassignedScope, UnassignedScope, UnassignedScope, UnassignedScope, GlobalScope, ReservedScope }; - return multicast() ? scopeMap[(*this)[1] & 0x0Fu] : - (*this)[0] == 0xFEu ? (((*this)[1]&0xC0) == 0x80 ? LinkScope : - ((*this)[1]&0xC0) == 0xC0 ? SiteScope : GlobalScope ) + return multicast() ? scopeMap[(*this)[1] & 0x0Fu] : + (*this)[0] == 0xFEu ? (((*this)[1]&0xC0) == 0x80 ? LinkScope : + ((*this)[1]&0xC0) == 0xC0 ? SiteScope : GlobalScope ) : GlobalScope; } -prefix_ bool senf::INet6Address::globalScope() +prefix_ bool senf::INet6Address::unicast() const { - return scope() == GlobalScope; + return ! multicast(); } - -prefix_ bool senf::INet6Address::linkScope() + +prefix_ bool senf::INet6Address::hasEUI64() const { - return scope() == LinkScope; + return unicast() && ((*this)[0]&0xE0u) != 0u; } -prefix_ senf::INet4Address senf::INet6Address::inet4address() +prefix_ bool senf::INet6Address::globalScope() const { - return INet4Address::from_data(&(*this)[12]); + return scope() == GlobalScope; } -prefix_ bool senf::INet6Address::ipv4Compatible() +prefix_ bool senf::INet6Address::linkScope() const { - return CheckINet6Network<0u,96>::match(*this); + return scope() == LinkScope; } -prefix_ bool senf::INet6Address::ipv4Mapped() +prefix_ bool senf::INet6Address::inet4Compatible() const { - return CheckINet6Network<0u,0u,0u,0u,0u,0xFFFFu,96>::match(*this); + return CheckINet6Network<0u,96>::match(*this); } prefix_ bool senf::INet6Address::globalMulticastAddr() @@ -216,10 +232,100 @@ prefix_ void senf::INet6Address::id(boost::uint64_t id) (*this)[15] = id ; } +/////////////////////////////////////////////////////////////////////////// +// senf::INet6Network + +prefix_ senf::INet6Network::INet6Network() + : prefix_len_(), address_() +{} + +prefix_ senf::INet6Network::INet6Network(INet6Address const & address, unsigned prefix_len) + : prefix_len_(prefix_len), address_(address) +{ + using boost::lambda::_1; + using boost::lambda::_2; + detail::apply_mask(prefix_len_, address_.begin(), address_.end(), _1 &= _2); +} + +prefix_ senf::INet6Address const & senf::INet6Network::address() + const +{ + return address_; +} + +prefix_ unsigned senf::INet6Network::prefix_len() + const +{ + return prefix_len_; +} + +prefix_ bool senf::INet6Network::boolean_test() + const +{ + return prefix_len() && address(); +} + +prefix_ bool senf::INet6Network::operator==(INet6Network const & other) + const +{ + return prefix_len() == other.prefix_len() && address() == other.address(); +} + +prefix_ bool senf::INet6Network::match(INet6Address const & addr) + const +{ + using boost::lambda::_1; + using boost::lambda::_2; + using boost::lambda::_3; + return detail::find_if_mask(prefix_len_, address_.begin(), address_.end(), addr.begin(), + _1 != (_2 & _3)) == address_.end(); +} + +prefix_ bool senf::INet6Network::match(INet6Network const & net) + const +{ + return net.prefix_len() >= prefix_len() && match(net.address()); +} + +prefix_ senf::INet6Address senf::INet6Network::host(boost::uint64_t id) +{ + INet6Address addr (address()); + addr.id(id); + return addr; +} + +prefix_ senf::INet6Network senf::INet6Network::subnet(boost::uint64_t net, unsigned prefix_len) +{ + using boost::lambda::_1; + using boost::lambda::_2; + using boost::lambda::var; + using boost::lambda::ret; + INet6Address addr (address()); + net <<= (64-prefix_len); + detail::apply_mask(prefix_len, addr.begin(), addr.end(), + ( ( _1 |= ret((var(net) >> 56) & _2) ), + ( var(net) <<= 8 ) )); + return INet6Network(addr, prefix_len); +} + +prefix_ std::ostream & senf::operator<<(std::ostream & os, INet6Network const & addr) +{ + os << addr.address() << '/' << addr.prefix_len(); + return os; +} + +/////////////////////////////////////////////////////////////////////////// +// namespace senf::detail members + +prefix_ boost::uint8_t senf::detail::low_bits_mask(unsigned bits) +{ + return ((1<