// $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 <g0dil@berlios.de>
//
// This program is free software; you can redistribute it and/or modify
/** \file
\brief INet6Address inline non-template implementation */
+#include "INet6Address.ih"
+
// Custom includes
#include <algorithm>
#include <boost/lambda/lambda.hpp>
#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,
(*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;
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()
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()
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()
(*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<boost::uint8_t>((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<<bits)-1);
+}
+
///////////////////////////////cci.e///////////////////////////////////////
#undef prefix_
-\f
+
// Local Variables:
// mode: c++
// fill-column: 100