BOOST_CHECK_EQUAL( p->version(), 6u );
BOOST_CHECK_EQUAL( p->length(), 20u );
BOOST_CHECK_EQUAL( p->nextHeader(), 44u );
- BOOST_CHECK_EQUAL( senf::INet6Address(p->source()), "2001::1" );
- BOOST_CHECK_EQUAL( senf::INet6Address(p->destination()), "2001::2" );
+ BOOST_CHECK_EQUAL( senf::INet6Address::from_data(p->source().i()),
+ senf::INet6Address::from_string("2001::1") );
+ BOOST_CHECK_EQUAL( senf::INet6Address::from_data(p->destination().i()),
+ senf::INet6Address::from_string("2001::2") );
BOOST_CHECK( p.next().is<senf::IpV6Extension_Fragment>() );
senf::IpV6Extension_Fragment f (p.next().as<senf::IpV6Extension_Fragment>());
<< " length : " << std::dec << unsigned(p->length()) << "\n"
<< " next header : " << unsigned(p->nextHeader()) << "\n"
<< " hop limit : " << unsigned(p->hopLimit()) << "\n"
- << " source : " << INet6Address(p->source()) << "\n"
- << " destination : " << INet6Address(p->destination()) << "\n";
+ << " source : " << INet6Address::from_data(p->source().i()) << "\n"
+ << " destination : " << INet6Address::from_data(p->destination().i()) << "\n";
}
///////////////////////////////cc.e////////////////////////////////////////
BOOST_CHECK_EQUAL( p->length(), 0x0102u );
BOOST_CHECK_EQUAL( p->nextHeader(), 0x03u );
BOOST_CHECK_EQUAL( p->hopLimit(), 0x04u );
- BOOST_CHECK_EQUAL( senf::INet6Address(p->source()).address() ,
- "1011:1213:1415:1617:1819:1a1b:1c1d:1e1f" );
- BOOST_CHECK_EQUAL( senf::INet6Address(p->destination()).address() ,
- "2021:2223:2425:2627:2829:2a2b:2c2d:2e2f" );
+ BOOST_CHECK_EQUAL( senf::INet6Address::from_data(p->source().i()),
+ senf::INet6Address::from_string("1011:1213:1415:1617:1819:1a1b:1c1d:1e1f") );
+ BOOST_CHECK_EQUAL( senf::INet6Address::from_data(p->destination().i()),
+ senf::INet6Address::from_string("2021:2223:2425:2627:2829:2a2b:2c2d:2e2f") );
BOOST_CHECK( p.next() );
BOOST_CHECK( p.next().is<senf::DataPacket>() );
}
senf::INet4Address const senf::INet4Address::None;
-senf::INet4Address const senf::INet4Address::Loopback = senf::INet4Address(0x7F000001u);
-senf::INet4Address const senf::INet4Address::Broadcast = senf::INet4Address(0xFFFFFFFFu);
+senf::INet4Address const senf::INet4Address::Loopback (0x7F000001u);
+senf::INet4Address const senf::INet4Address::Broadcast (0xFFFFFFFFu);
///////////////////////////////////////////////////////////////////////////
{
public:
+ ///////////////////////////////////////////////////////////////////////////
+ // Types
+
typedef uint32_t address_type; ///< Address representation as number in host byte order
typedef uint32_t inaddr_type; ///< Legacy address representation in network byte order
typedef boost::function<void (INet4Address const &)> Callback;
enum NoInit_t { noinit };
+ ///////////////////////////////////////////////////////////////////////////
+ ///\name Structors and default members
+ ///@{
+
INet4Address(); ///< Construct an empty address
- INet4Address(NoInit_t); ///< Construct uninitialized (!) address
+ explicit INet4Address(NoInit_t); ///< Construct uninitialized (!) address
explicit INet4Address(address_type value);
///< Construct an address constant
code to convert a network byte order address in an
integer number into an INet4Address. */
+ ///@}
+ ///////////////////////////////////////////////////////////////////////////
+ ///\name Accessors
+ ///@{
+
bool local() const; ///< \c true, if address is locally administered
/**< This call checks, if the address is within one of the
IANA private ranges. */
host byte order. This representation allows simple
network math operations. */
+ ////@}
+
struct SyntaxException : public std::exception
{ virtual char const * what() const throw() { return "invalid INet4 address syntax"; } };
--- /dev/null
+// Copyright (C) 2007
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief INet6Address non-inline non-template implementation */
+
+#include "INet6Address.hh"
+#include "INet6Address.ih"
+
+// Custom includes
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+//#include "INet6Address.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////
+// senf::INet6Address
+
+prefix_ senf::INet6Address senf::INet6Address::from_string(std::string const & s)
+{
+ struct in6_addr ina;
+ if (::inet_pton(AF_INET6,s.c_str(),&ina) > 0)
+ return senf::INet6Address::from_data(&ina.s6_addr[0]);
+ int herr (0);
+
+ // If available, we use the reentrant GNU variant. This has the additional advantage, that we
+ // can explicitly ask for IpV4 addresses
+
+# ifdef __GLIBC__
+
+ struct hostent entbuf;
+ char buffer[4096];
+ struct hostent * ent (0);
+ ::gethostbyname2_r(s.c_str(), AF_INET6, &entbuf, buffer, sizeof(buffer), &ent, &herr);
+
+# else // ! __GLIBC__
+
+# ifdef _REENTRANT
+ static boost::mutex mutex;
+ boost::mutex::scoped_lock lock(mutex);
+# endif
+ struct hostent * ent (::gethostbyname(s.c_str()));
+ herr = h_errno;
+
+# endif // __GLIBC__
+
+ if (!ent)
+ ///\fixme Need to give better exception here
+ throw SyntaxException();
+ if (ent->h_addrtype != AF_INET6)
+ throw SyntaxException();
+
+ // We are only interested in the first address ...
+ return senf::INet6Address::from_data(
+ &reinterpret_cast<in6_addr*>(*(ent->h_addr_list))->s6_addr[0]);
+}
+
+prefix_ std::ostream & senf::operator<<(std::ostream & os, INet6Address const & addr)
+{
+ ::in6_addr ina;
+ char buffer[5*8];
+ std::copy(addr.begin(),addr.end(),&ina.s6_addr[0]);
+ ::inet_ntop(AF_INET6,&ina,buffer,sizeof(buffer));
+ buffer[5*8] = 0;
+ os << buffer;
+ return os;
+}
+
+senf::INet6Address const senf::INet6Address::None;
+senf::INet6Address const senf::INet6Address::Loopback (0u,0u,0u,0u,0u,0u,0u,1u);
+senf::INet6Address const senf::INet6Address::AllNodes (0xFF02u,0u,0u,0u,0u,0u,0u,1u);
+senf::INet6Address const senf::INet6Address::AllRouters (0xFF02u,0u,0u,0u,0u,0u,0u,2u);
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "INet6Address.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
--- /dev/null
+// Copyright (C) 2007
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief INet6Address inline non-template implementation */
+
+// Custom includes
+#include <algorithm>
+#include <boost/lambda/lambda.hpp>
+
+#define prefix_ inline
+///////////////////////////////cci.p///////////////////////////////////////
+
+prefix_ senf::INet6Address::INet6Address(NoInit_t)
+{}
+
+prefix_ senf::INet6Address::INet6Address(boost::uint16_t a0, boost::uint16_t a1,
+ boost::uint16_t a2, boost::uint16_t a3,
+ boost::uint16_t a4, boost::uint16_t a5,
+ boost::uint16_t a6, boost::uint16_t a7)
+{
+ (*this)[ 0] = boost::uint8_t(a0>>8);
+ (*this)[ 1] = boost::uint8_t(a0);
+ (*this)[ 2] = boost::uint8_t(a1>>8);
+ (*this)[ 3] = boost::uint8_t(a1);
+ (*this)[ 4] = boost::uint8_t(a2>>8);
+ (*this)[ 5] = boost::uint8_t(a2);
+ (*this)[ 6] = boost::uint8_t(a3>>8);
+ (*this)[ 7] = boost::uint8_t(a3);
+ (*this)[ 8] = boost::uint8_t(a4>>8);
+ (*this)[ 9] = boost::uint8_t(a4);
+ (*this)[10] = boost::uint8_t(a5>>8);
+ (*this)[11] = boost::uint8_t(a5);
+ (*this)[12] = boost::uint8_t(a6>>8);
+ (*this)[13] = boost::uint8_t(a6);
+ (*this)[14] = boost::uint8_t(a7>>8);
+ (*this)[15] = boost::uint8_t(a7);
+}
+
+prefix_ senf::INet6Address senf::INet6Address::from_inet4address(INet4Address addr4)
+{
+ INet6Address addr;
+ addr[10] = 0xffu;
+ addr[11] = 0xffu;
+ std::copy(addr4.begin(), addr4.end(), addr.begin()+12);
+ return addr;
+}
+
+prefix_ boost::uint64_t senf::INet6Address::network()
+ const
+{
+ 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) );
+}
+
+prefix_ bool senf::INet6Address::hasEuid64()
+ const
+{
+ return unicast() && ((*this)[0]&0xE0u) != 0u;
+}
+
+prefix_ boost::uint64_t 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) );
+}
+
+prefix_ bool senf::INet6Address::universalId()
+ const
+{
+ return (*this)[8] & 2u;
+}
+
+prefix_ bool senf::INet6Address::groupId()
+ const
+{
+ return (*this)[8] & 1u;
+}
+
+prefix_ bool senf::INet6Address::unicast()
+ const
+{
+ return ! multicast();
+}
+
+prefix_ bool senf::INet6Address::multicast()
+ const
+{
+ return (*this)[0] == 0xFFu;
+}
+
+prefix_ senf::INet6Address::ScopeId senf::INet6Address::scope()
+ const
+{
+ static ScopeId const scopeMap[]
+ = { ReservedScope, InterfaceScope, LinkScope, ReservedScope,
+ 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 )
+ : GlobalScope;
+}
+
+prefix_ bool senf::INet6Address::globalScope()
+ const
+{
+ return scope() == GlobalScope;
+}
+
+prefix_ bool senf::INet6Address::linkScope()
+ const
+{
+ return scope() == LinkScope;
+}
+
+prefix_ senf::INet4Address senf::INet6Address::inet4address()
+ const
+{
+ return INet4Address::from_data(&(*this)[12]);
+}
+
+prefix_ bool senf::INet6Address::ipv4Compatible()
+ const
+{
+ return CheckINet6Network<0u,96>::match(*this);
+}
+
+prefix_ bool senf::INet6Address::ipv4Mapped()
+ const
+{
+ return CheckINet6Network<0u,0u,0u,0u,0u,0xFFFFu,96>::match(*this);
+}
+
+prefix_ bool senf::INet6Address::globalMulticastAddr()
+ const
+{
+ return multicast() && ! ((*this)[1] & 0x10u);
+}
+
+prefix_ bool senf::INet6Address::prefixMulticastAddr()
+ const
+{
+ return multicast() && ((*this)[1] & 0x20u);
+}
+
+prefix_ bool senf::INet6Address::embeddedRpAddr()
+ const
+{
+ return multicast() && ((*this)[1] & 0x40u);
+}
+
+prefix_ bool senf::INet6Address::boolean_test()
+ const
+{
+ using boost::lambda::_1;
+ return std::find_if(begin(),end(), _1 != 0x00) != end();
+}
+
+prefix_ void senf::INet6Address::network(boost::uint64_t net)
+{
+ (*this)[ 0] = net >> 56;
+ (*this)[ 1] = net >> 48;
+ (*this)[ 2] = net >> 40;
+ (*this)[ 3] = net >> 32;
+ (*this)[ 4] = net >> 24;
+ (*this)[ 5] = net >> 16;
+ (*this)[ 6] = net >> 8;
+ (*this)[ 7] = net ;
+}
+
+prefix_ void senf::INet6Address::id(boost::uint64_t id)
+{
+ (*this)[ 8] = id >> 56;
+ (*this)[ 9] = id >> 48;
+ (*this)[10] = id >> 40;
+ (*this)[11] = id >> 32;
+ (*this)[12] = id >> 24;
+ (*this)[13] = id >> 16;
+ (*this)[14] = id >> 8;
+ (*this)[15] = id ;
+}
+
+///////////////////////////////cci.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
-// Copyright (C) 2007
+// Copyright (C) 2007
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <g0dil@berlios.de>
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/** \file
- \brief INetAddressing non-inline template implementation */
+ \brief INet6Address non-inline template implementation */
-//#include "INetAddressing.ih"
+#include "INet6Address.ih"
// Custom includes
-#include <boost/range.hpp>
#define prefix_
///////////////////////////////ct.p////////////////////////////////////////
-template <class Range>
-prefix_ senf::INet6Address::INet6Address(Range const & range)
+///////////////////////////////////////////////////////////////////////////
+// senf::INet6Address
+
+template <class InputIterator>
+prefix_ senf::INet6Address senf::INet6Address::from_data(InputIterator i)
{
- typename boost::range_const_iterator<Range>::type i ( boost::const_begin(range) );
- typename boost::range_const_iterator<Range>::type const i_end ( boost::const_end(range) );
- unsigned char * p (&addr_.s6_addr[0]);
- unsigned char * p_end (p+sizeof(addr_.s6_addr));
- for (; p!=p_end && i!=i_end; ++p, ++i)
- *p = *i;
- if (p!=p_end || i!=i_end)
- throw SyntaxException();
+ INet6Address addr (INet6Address::noinit);
+ iterator j (addr.begin());
+ iterator const j_end (addr.end());
+ for (;j!=j_end;++j,++i)
+ *j = *i;
+ return addr;
}
///////////////////////////////ct.e////////////////////////////////////////
// Local Variables:
// mode: c++
// fill-column: 100
+// comment-column: 40
// c-file-style: "senf"
// indent-tabs-mode: nil
// ispell-local-dictionary: "american"
// compile-command: "scons -u test"
-// comment-column: 40
// End:
--- /dev/null
+// Copyright (C) 2007
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief INet6Address inline template implementation */
+
+#include "INet6Address.ih"
+
+// Custom includes
+#include <boost/integer/integer_mask.hpp>
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <unsigned a>
+prefix_ bool senf::detail::CheckINet6Network_impl5<a,0,0>::match(boost::uint8_t v0,
+ boost::uint8_t v1)
+{
+ return true;
+}
+
+template <unsigned a, unsigned restbits>
+prefix_ bool senf::detail::CheckINet6Network_impl5<a,0,restbits>::match(boost::uint8_t v0,
+ boost::uint8_t v1)
+{
+ return v0 & ~boost::low_bits_mask_t<8-restbits>::sig_bits
+ == boost::uint8_t(a>>8) & ~boost::low_bits_mask_t<8-restbits>::sig_bits;
+}
+
+template <unsigned a>
+prefix_ bool senf::detail::CheckINet6Network_impl5<a,1,0>::match(boost::uint8_t v0,
+ boost::uint8_t v1)
+{
+ return v0 == boost::uint8_t(a>>8);
+}
+
+template <unsigned a, unsigned restbits>
+prefix_ bool senf::detail::CheckINet6Network_impl5<a,1,restbits>::match(boost::uint8_t v0,
+ boost::uint8_t v1)
+{
+ return v0 == boost::uint8_t(a>>8) &&
+ v1 & ~boost::low_bits_mask_t<8-restbits>::sig_bits
+ == boost::uint8_t(a) & ~boost::low_bits_mask_t<8-restbits>::sig_bits;
+}
+
+template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4, unsigned a5,
+ unsigned a6, unsigned a7, unsigned restbits>
+prefix_ bool senf::detail::CheckINet6Network_impl3<a0,a1,a2,a3,a4,a5,a6,a7,0,restbits>::
+match(INet6Address const & addr)
+{
+ return CheckINet6Network_impl4<a0,restbits>::match(addr[0],addr[1]);
+}
+
+template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4, unsigned a5,
+ unsigned a6, unsigned a7, unsigned restbits>
+prefix_ bool senf::detail::CheckINet6Network_impl3<a0,a1,a2,a3,a4,a5,a6,a7,1,restbits>::
+match(INet6Address const & addr)
+{
+ return
+ addr[0] == boost::uint8_t(a0>>8) && addr[1] == boost::uint8_t(a0) &&
+ CheckINet6Network_impl4<a1,restbits>::match(addr[2],addr[3]);
+}
+
+template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4, unsigned a5,
+ unsigned a6, unsigned a7, unsigned restbits>
+prefix_ bool senf::detail::CheckINet6Network_impl3<a0,a1,a2,a3,a4,a5,a6,a7,2,restbits>::
+match(INet6Address const & addr)
+{
+ return
+ addr[0] == boost::uint8_t(a0>>8) && addr[1] == boost::uint8_t(a0) &&
+ addr[2] == boost::uint8_t(a1>>8) && addr[3] == boost::uint8_t(a1) &&
+ CheckINet6Network_impl4<a1,restbits>::match(addr[4],addr[5]);
+}
+
+template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4, unsigned a5,
+ unsigned a6, unsigned a7, unsigned restbits>
+prefix_ bool senf::detail::CheckINet6Network_impl3<a0,a1,a2,a3,a4,a5,a6,a7,3,restbits>::
+match(INet6Address const & addr)
+{
+ return
+ addr[0] == boost::uint8_t(a0>>8) && addr[1] == boost::uint8_t(a0) &&
+ addr[2] == boost::uint8_t(a1>>8) && addr[3] == boost::uint8_t(a1) &&
+ addr[4] == boost::uint8_t(a2>>8) && addr[5] == boost::uint8_t(a2) &&
+ CheckINet6Network_impl4<a3,restbits>::match(addr[6],addr[7]);
+}
+
+template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4, unsigned a5,
+ unsigned a6, unsigned a7, unsigned restbits>
+prefix_ bool senf::detail::CheckINet6Network_impl3<a0,a1,a2,a3,a4,a5,a6,a7,4,restbits>::
+match(INet6Address const & addr)
+{
+ return
+ addr[0] == boost::uint8_t(a0>>8) && addr[1] == boost::uint8_t(a0) &&
+ addr[2] == boost::uint8_t(a1>>8) && addr[3] == boost::uint8_t(a1) &&
+ addr[4] == boost::uint8_t(a2>>8) && addr[5] == boost::uint8_t(a2) &&
+ addr[6] == boost::uint8_t(a3>>8) && addr[7] == boost::uint8_t(a3) &&
+ CheckINet6Network_impl4<a4,restbits>::match(addr[8],addr[9]);
+}
+
+template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4, unsigned a5,
+ unsigned a6, unsigned a7, unsigned restbits>
+prefix_ bool senf::detail::CheckINet6Network_impl3<a0,a1,a2,a3,a4,a5,a6,a7,5,restbits>::
+match(INet6Address const & addr)
+{
+ return
+ addr[0] == boost::uint8_t(a0>>8) && addr[1] == boost::uint8_t(a0) &&
+ addr[2] == boost::uint8_t(a1>>8) && addr[3] == boost::uint8_t(a1) &&
+ addr[4] == boost::uint8_t(a2>>8) && addr[5] == boost::uint8_t(a2) &&
+ addr[6] == boost::uint8_t(a3>>8) && addr[7] == boost::uint8_t(a3) &&
+ addr[8] == boost::uint8_t(a4>>8) && addr[9] == boost::uint8_t(a4) &&
+ CheckINet6Network_impl4<a5,restbits>::match(addr[10],addr[11]);
+}
+
+template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4, unsigned a5,
+ unsigned a6, unsigned a7, unsigned restbits>
+prefix_ bool senf::detail::CheckINet6Network_impl3<a0,a1,a2,a3,a4,a5,a6,a7,6,restbits>::
+match(INet6Address const & addr)
+{
+ return
+ addr[0] == boost::uint8_t(a0>>8) && addr[1] == boost::uint8_t(a0) &&
+ addr[2] == boost::uint8_t(a1>>8) && addr[3] == boost::uint8_t(a1) &&
+ addr[4] == boost::uint8_t(a2>>8) && addr[5] == boost::uint8_t(a2) &&
+ addr[6] == boost::uint8_t(a3>>8) && addr[7] == boost::uint8_t(a3) &&
+ addr[8] == boost::uint8_t(a4>>8) && addr[9] == boost::uint8_t(a4) &&
+ addr[10] == boost::uint8_t(a5>>8) && addr[11] == boost::uint8_t(a5) &&
+ CheckINet6Network_impl4<a6,restbits>::match(addr[12],addr[13]);
+}
+
+template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4, unsigned a5,
+ unsigned a6, unsigned a7, unsigned restbits>
+prefix_ bool senf::detail::CheckINet6Network_impl3<a0,a1,a2,a3,a4,a5,a6,a7,7,restbits>::
+match(INet6Address const & addr)
+{
+ return
+ addr[0] == boost::uint8_t(a0>>8) && addr[1] == boost::uint8_t(a0) &&
+ addr[2] == boost::uint8_t(a1>>8) && addr[3] == boost::uint8_t(a1) &&
+ addr[4] == boost::uint8_t(a2>>8) && addr[5] == boost::uint8_t(a2) &&
+ addr[6] == boost::uint8_t(a3>>8) && addr[7] == boost::uint8_t(a3) &&
+ addr[8] == boost::uint8_t(a4>>8) && addr[9] == boost::uint8_t(a4) &&
+ addr[10] == boost::uint8_t(a5>>8) && addr[11] == boost::uint8_t(a5) &&
+ addr[12] == boost::uint8_t(a6>>8) && addr[13] == boost::uint8_t(a6) &&
+ CheckINet6Network_impl4<a7,restbits>::match(addr[14],addr[15]);
+}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
--- /dev/null
+// Copyright (C) 2007
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief INet6Address public header */
+
+#ifndef HH_INet6Address_
+#define HH_INet6Address_ 1
+
+// Custom includes
+#include <iostream>
+#include <string>
+#include <boost/cstdint.hpp>
+#include <boost/function.hpp>
+#include <boost/array.hpp>
+#include "Utils/SafeBool.hh"
+#include "INet4Address.hh"
+
+//#include "INet6Address.mpp"
+#include "INet6Address.ih"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+
+ /** \brief IpV6 network address
+
+ This implementation of an IpV6 address is based strictly on RFC 4291: Internet Protocol
+ Version 6 (IPv6) Addressing Architecture. This class provides accessors to all the
+ information fields defined in this document.
+
+ The IpV6 addressing architecture however has several other components defined in other
+ RFC's. These RFC's should be implemented in additional modules:
+
+ \li RFC4193: Unique Local Addresses (ULA). Defines the fc00::/7 prefix
+ \li RFC3306: Unicast-Prefix-based IPv6 Multicast Addresses. Defines the ff30::/12 prefix
+ \li RFC3956: Embedding the Rendezvous Point (RP) Address in an IPv6 Multicast
+ Address. Defines the ff70::/12 prefix
+ \li RFC3056: Connection of IPv6 Domains via IPv4 Clouds. Defines 6to4 tunneling and the
+ 2002::/16 prefix
+ \li RFC3849: IPv6 Address Prefix Reserved for Documentation. Defines the 2001:db8::/32
+ prefix
+
+ Here an overview of well-known prefixes:
+
+ <table class="senf">
+ <tr><th>Prefix</th> <th>Description</th> <th>Definition</th> <th>Note</th></tr>
+ <tr><td><tt>::/96</tt></td> <td>IpV4 compatible IpV6 address</td> <td>RFC4291</td> <td>deprecated</td></tr>
+ <tr><td><tt>::ffff:0:0/96</tt></td> <td>IpV6 mapped IpV4 address</td> <td>RFC4291</td> <td></td></tr>
+ <tr><td><tt>2000::/3</tt></td> <td>Global unicast addresses</td> <td>RFC3587</td> <td>only noted, not defined</td></tr>
+ <tr><td><tt>2001:db8::/32</tt></td> <td>Documentation-only prefix</td> <td>RFC3849</td> <td></td></tr>
+ <tr><td><tt>2002::/16</tt></td> <td>6to4 addressing</td> <td>RFC3056</td> <td></td></tr>
+ <tr><td><tt>fc00::/7</tt></td> <td>ULA</td> <td>RFC4193</td> <td></td></tr>
+ <tr><td><tt>fe80::/64</tt></td> <td>Link-local addresses</td> <td>RFC4291</td> <td></td></tr>
+ <tr><td><tt>fec0::/10</tt></td> <td>Site-local addresses </td> <td>RFC4291</td> <td>deprecated</td></tr>
+ <tr><td><tt>ff00::/8</tt></td> <td>Multicast</td> <td>RFC4291</td> <td></td></tr>
+ <tr><td><tt>ff00::/12</tt></td> <td>Globally allocated multicast</td> <td>RFC4291</td> <td></td></tr>
+ <tr><td><tt>ff10::/12</tt></td> <td>Locally allocated multicast</td> <td>RFC4291</td> <td></td></tr>
+ <tr><td><tt>ff30::/12</tt></td> <td>Unicast prefic based multicast</td> <td>RFC3306</td> <td></td></tr>
+ <tr><td><tt>ff70::/12</tt></td> <td>Multicast address with embedded RP</td> <td>RFC3956</td> <td></td></tr>
+ </table>
+
+ The INet6Address class is based on \c boost::array and is built as a fixed-size sequence of
+ 16 bytes.
+ */
+ class INet6Address
+ : public boost::array<boost::uint8_t,16>,
+ public ComparableSafeBool<INet6Address>
+ {
+ public:
+ ///////////////////////////////////////////////////////////////////////////
+ // Types
+
+ typedef boost::function<void (INet6Address const &)> Callback;
+ ///< Callback for asynchronous from_string call
+
+ static INet6Address const None; ///< The empty (::0) address
+ static INet6Address const Loopback; ///< The loopback (::1) address
+ static INet6Address const AllNodes; ///< The 'all nodes' link-local multicast address
+ static INet6Address const AllRouters; ///< The 'all routers' link-local multicast address
+
+ enum NoInit_t { noinit };
+
+ /** \brief Possible scope values
+
+ List of all possible scope values. This list includes all scope values defined for
+ multicast addresses in RFC4291. The values \ref LinkScope, \ref SiteScope and \ref
+ GlobalScope are also used with unicast addresses.
+ */
+ enum ScopeId {
+ InterfaceScope = 1 /**< Interface only scope */
+ , LinkScope = 2 /**< Link-local scope */
+ , AdminScope = 4 /**< Administration defined local scope */
+ , SiteScope = 5 /**< Site-local scope */
+ , OrganizationScope = 8 /**< Scope covering multiple sites of an organization */
+ , GlobalScope = 14 /**< Global Internet scope */
+
+ , ReservedScope = 0 /**< Reserved scope value */
+ , UnassignedScope = 6 /**< Unassigned scope, may be defined locally */
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ ///\name Structors and default members
+ ///@{
+
+ explicit INet6Address(NoInit_t); ///< Construct uninitialized (!) address
+ INet6Address(boost::uint16_t a0=0u, boost::uint16_t a1=0u, boost::uint16_t a2=0u,
+ boost::uint16_t a3=0u, boost::uint16_t a4=0u, boost::uint16_t a5=0u,
+ boost::uint16_t a6=0u, boost::uint16_t a7=0u);
+ ///< Construct an address constant
+
+ static INet6Address from_string(std::string const & s);
+ ///< Convert string to address
+ /**< This member will try to convert the given string into
+ an IP address. from_string() supports all standard IP
+ literal representations as well es hostnames.
+ \attention This call may block if \a s represents a
+ hostname which must be looked up via some network
+ protocol like DNS or NIS
+ \throws SyntaxException if the address cannot be
+ converted for some reason
+ \param[in] s Address literal or hostname */
+
+ static void from_string(std::string const & s, Callback const & cb);
+ ///< Convert string to address (async/non-blocking)
+ /**< This member works like
+ from_string(std::string const &). However unlike
+ from_string(std::string const &), this call will not
+ block. Instead it will call \a cb passing the
+ INet6Address instance as soon as the address has been
+ resolved (which may be immediate if the address
+ represents an IP literal). \par
+ On error, the address passed to \a cb will be empty.
+ \param[in] s Address literal or hostname
+ \param[in] cb Callback to pass the address to
+ \fixme Implement */
+
+ template <class InputIterator>
+ static INet6Address from_data(InputIterator i);
+ ///< Construct address from 16 bytes of raw data
+ /**< from_data will build an address from 16 bytes of raw
+ data as accessed by the iterator. The data must be in
+ network byte order. */
+
+ static INet6Address from_inet4address(INet4Address addr);
+ ///< Construct an IpV6-mapped IpV4 address
+ /**< This will construct an address of the form
+ <tt>::FFFF::w.x.y.z</tt> where <tt>w.x.y.z</tt> is
+ the INet4Address value. This kind of address is called
+ an IpV6-mapped IpV4 address (see RFC4291). \par
+ IpV4 compatible IpV6 addresses are not directly
+ supported, they are deprecated in the RFC. */
+ ///@}
+ ///////////////////////////////////////////////////////////////////////////
+ ///\name Accessors
+ ///@{
+
+ boost::uint64_t network() const; ///< Return 64bit network part
+ bool hasEuid64() const; ///< \c true, if address is based on an EUID-64
+ boost::uint64_t id() const; ///< Return interface id (EUID-64)
+ bool universalId() const; ///< \c true, if the id() is universally assigned
+ bool groupId() const; ///< \c true, if the id()'s \a group bit is set
+
+ bool unicast() const; ///< \c true, if address is unicast
+ bool multicast() const; ///< \c true, if address is multicast
+
+ ScopeId scope() const; ///< Get address's scope
+ /**< The scope of an address is one of the \ref ScopeId
+ values. We need to differentiate between unicast and
+ multicast addresses: unicast addresses only have local,
+ site or global scope (where site scope is deprecated),
+ multicast address can have a number of scope values of
+ which local, site and global are a few. See the \ref
+ ScopeId enumerators. */
+ bool globalScope() const; ///< \c true, if address is global unicast or multicast
+ bool linkScope() const; ///< \c true, if address is link-local unicast or multicast
+
+ INet4Address inet4address() const; ///< Return embedded IpV4 address
+ /**< Returns the IpV4 address embedded within an IpV4
+ compatible or IpV4 mapped unicast address. This address
+ is given by the last 32 bits of the IpV6 address. \par
+ The value returned is only a valid IpV4 address if
+ either ipv4Compatible() or ipv4Mapped() return \c
+ true. */
+ bool ipv4Compatible() const; ///< \c true, if address is IpV4 compatible
+ /**< IpV4 compatible IpV6 addresses are deprecated. */
+ bool ipv4Mapped() const; ///< \c true, if address is IpV4 mapped
+
+ bool globalMulticastAddr() const; ///< \c true, if T bit is \e not set
+ /**< Any multicast address with a cleared T bit must be
+ globally assigned. See RFC4291. */
+ bool prefixMulticastAddr() const; ///< \c true, if P bit is set
+ /**< In RFC4291, the P bit is specified as defining a
+ unicast prefix based multicast address. See RFC3306. */
+ bool embeddedRpAddr() const; ///< \c true, if R bit is set
+ /** In RFC4291, the R bit is specified as defining a
+ multicast address with embedded rendezvous point. See
+ RFC3956. */
+
+ bool boolean_test() const; ///< \c true, if address != '::' (None)
+
+ ///@}
+ ///\name Mutators
+ ///@{
+
+ void network(boost::uint64_t net); ///< Set network part of address
+ void id(boost::uint64_t id); ///< Set interface id part of address
+
+ ///@}
+
+ /** \brief Invalid IpV6 address syntax */
+ struct SyntaxException : public std::exception
+ { virtual char const * what() const throw() { return "Invalid IpV6 address syntax"; } };
+ };
+
+ /** \brief Output INet6Address instance as it's string representation
+ \related INet6Address
+ */
+ std::ostream & operator<<(std::ostream & os, INet6Address const & addr);
+
+ /** \brief Check address against a fixed network prefix
+
+ This helper allows to easily and efficiently check an address against an arbitrary network
+ prefix:
+ \code
+ if (senf::CheckINet6Network<0x2000u,0xDB8u,32u>::match(addr)) {
+ // 'addr' is within in the 2001:db8::/32 documentation-only network
+ ...
+ }
+ \endcode
+
+ The code generated by this call is highly optimized and as probably as efficient as it can
+ get.
+
+ \related INet6Address
+ */
+ template <unsigned a0, unsigned a1, unsigned a2=0u, unsigned a3=0u, unsigned a4=0u,
+ unsigned a5=0u, unsigned a6=0u, unsigned a7=0u, unsigned a8=0u>
+ struct CheckINet6Network
+ : public detail::CheckINet6Network_impl<a0,a1,a2,a3,a4,a5,a6,a7,a8>
+ {};
+
+}
+
+///////////////////////////////hh.e////////////////////////////////////////
+#include "INet6Address.cci"
+#include "INet6Address.ct"
+#include "INet6Address.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
--- /dev/null
+// Copyright (C) 2007
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief INet6Address internal header */
+
+#ifndef IH_INet6Address_
+#define IH_INet6Address_ 1
+
+// Custom includes
+
+///////////////////////////////ih.p////////////////////////////////////////
+
+namespace senf {
+
+ class INet6Address;
+
+namespace detail {
+
+# ifndef DOXYGEN
+
+ template <unsigned a, unsigned bytes, unsigned restbits>
+ struct CheckINet6Network_impl5
+ {};
+
+ template <unsigned a>
+ struct CheckINet6Network_impl5<a,0,0>
+ {
+ static bool match(boost::uint8_t v0, boost::uint8_t v1);
+ };
+
+ template <unsigned a, unsigned restbits>
+ struct CheckINet6Network_impl5<a,0,restbits>
+ {
+ static bool match(boost::uint8_t v0, boost::uint8_t v1);
+ };
+
+ template <unsigned a>
+ struct CheckINet6Network_impl5<a,1,0>
+ {
+ static bool match(boost::uint8_t v0, boost::uint8_t v1);
+ };
+
+ template <unsigned a, unsigned restbits>
+ struct CheckINet6Network_impl5<a,1,restbits>
+ {
+ static bool match(boost::uint8_t v0, boost::uint8_t v1);
+ };
+
+ template <unsigned a, unsigned bits>
+ struct CheckINet6Network_impl4
+ : public CheckINet6Network_impl5<a,bits/8,bits%8>
+ {};
+
+ template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4,
+ unsigned a5, unsigned a6, unsigned a7, unsigned words, unsigned restbits>
+ struct CheckINet6Network_impl3
+ {};
+
+ template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4,
+ unsigned a5, unsigned a6, unsigned a7, unsigned restbits>
+ struct CheckINet6Network_impl3<a0,a1,a2,a3,a4,a5,a6,a7,0,restbits>
+ {
+ static bool match(INet6Address const & addr);
+ };
+
+ template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4,
+ unsigned a5, unsigned a6, unsigned a7, unsigned restbits>
+ struct CheckINet6Network_impl3<a0,a1,a2,a3,a4,a5,a6,a7,1,restbits>
+ {
+ static bool match(INet6Address const & addr);
+ };
+
+ template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4,
+ unsigned a5, unsigned a6, unsigned a7, unsigned restbits>
+ struct CheckINet6Network_impl3<a0,a1,a2,a3,a4,a5,a6,a7,2,restbits>
+ {
+ static bool match(INet6Address const & addr);
+ };
+
+ template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4,
+ unsigned a5, unsigned a6, unsigned a7, unsigned restbits>
+ struct CheckINet6Network_impl3<a0,a1,a2,a3,a4,a5,a6,a7,3,restbits>
+ {
+ static bool match(INet6Address const & addr);
+ };
+
+ template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4,
+ unsigned a5, unsigned a6, unsigned a7, unsigned restbits>
+ struct CheckINet6Network_impl3<a0,a1,a2,a3,a4,a5,a6,a7,4,restbits>
+ {
+ static bool match(INet6Address const & addr);
+ };
+
+ template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4,
+ unsigned a5, unsigned a6, unsigned a7, unsigned restbits>
+ struct CheckINet6Network_impl3<a0,a1,a2,a3,a4,a5,a6,a7,5,restbits>
+ {
+ static bool match(INet6Address const & addr);
+ };
+
+ template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4,
+ unsigned a5, unsigned a6, unsigned a7, unsigned restbits>
+ struct CheckINet6Network_impl3<a0,a1,a2,a3,a4,a5,a6,a7,6,restbits>
+ {
+ static bool match(INet6Address const & addr);
+ };
+
+ template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4,
+ unsigned a5, unsigned a6, unsigned a7, unsigned restbits>
+ struct CheckINet6Network_impl3<a0,a1,a2,a3,a4,a5,a6,a7,7,restbits>
+ {
+ static bool match(INet6Address const & addr);
+ };
+
+ template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4,
+ unsigned a5, unsigned a6, unsigned a7, unsigned bits>
+ struct CheckINet6Network_impl2
+ : public CheckINet6Network_impl3<a0,a1,a2,a3,a4,a5,a6,a7,bits/16,bits%16>
+ {};
+
+ template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4,
+ unsigned a5, unsigned a6, unsigned a7, unsigned a8>
+ struct CheckINet6Network_impl
+ : public CheckINet6Network_impl2<a0,a1,a2,a3,a4,a5,a6,a7,a8>
+ {};
+
+ template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4,
+ unsigned a5, unsigned a6, unsigned a7>
+ struct CheckINet6Network_impl<a0,a1,a2,a3,a4,a5,a6,a7,0>
+ : public CheckINet6Network_impl2<a0,a1,a2,a3,a4,a5,a6,0,a7>
+ {};
+
+ template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4,
+ unsigned a5, unsigned a6>
+ struct CheckINet6Network_impl<a0,a1,a2,a3,a4,a5,a6,0,0>
+ : public CheckINet6Network_impl2<a0,a1,a2,a3,a4,a5,0,0,a6>
+ {};
+
+ template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4,
+ unsigned a5>
+ struct CheckINet6Network_impl<a0,a1,a2,a3,a4,a5,0,0,0>
+ : public CheckINet6Network_impl2<a0,a1,a2,a3,a4,0,0,0,a5>
+ {};
+
+ template <unsigned a0, unsigned a1, unsigned a2, unsigned a3, unsigned a4>
+ struct CheckINet6Network_impl<a0,a1,a2,a3,a4,0,0,0,0>
+ : public CheckINet6Network_impl2<a0,a1,a2,a3,0,0,0,0,a4>
+ {};
+
+ template <unsigned a0, unsigned a1, unsigned a2, unsigned a3>
+ struct CheckINet6Network_impl<a0,a1,a2,a3,0,0,0,0,0>
+ : public CheckINet6Network_impl2<a0,a1,a2,0,0,0,0,0,a3>
+ {};
+
+ template <unsigned a0, unsigned a1, unsigned a2>
+ struct CheckINet6Network_impl<a0,a1,a2,0,0,0,0,0,0>
+ : public CheckINet6Network_impl2<a0,a1,0,0,0,0,0,0,a2>
+ {};
+
+ template <unsigned a0, unsigned a1>
+ struct CheckINet6Network_impl<a0,a1,0,0,0,0,0,0,0>
+ : public CheckINet6Network_impl2<a0,0,0,0,0,0,0,0,a1>
+ {};
+
+ template <boost::uint64_t net, boost::uint64_t id, unsigned bits, unsigned bytes>
+ struct IsINet6Network_impl
+ {};
+
+# endif
+
+}}
+
+///////////////////////////////ih.e////////////////////////////////////////
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
--- /dev/null
+// Copyright (C) 2007
+// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
+// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief INet6Address.test unit tests */
+
+//#include "INet6Address.test.hh"
+//#include "INet6Address.test.ih"
+
+// Custom includes
+#include <boost/lexical_cast.hpp>
+#include "INet6Address.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+BOOST_AUTO_UNIT_TEST(inet6Address)
+{
+ using senf::INet6Address;
+ using senf::INet4Address;
+
+ {
+ INet6Address addr1 (INet6Address::from_string("0102:0304:0506:0708:090A:0B0C:0D0E:0F00"));
+ BOOST_CHECK_EQUAL( addr1[0], 1 );
+ BOOST_CHECK_EQUAL( addr1[1], 2 );
+ BOOST_CHECK_EQUAL( addr1[2], 3 );
+ BOOST_CHECK_EQUAL( addr1[3], 4 );
+ BOOST_CHECK_EQUAL( addr1[4], 5 );
+ BOOST_CHECK_EQUAL( addr1[5], 6 );
+ BOOST_CHECK_EQUAL( addr1[6], 7 );
+ BOOST_CHECK_EQUAL( addr1[7], 8 );
+ BOOST_CHECK_EQUAL( addr1[8], 9 );
+ BOOST_CHECK_EQUAL( addr1[9], 10 );
+ BOOST_CHECK_EQUAL( addr1[10], 11 );
+ BOOST_CHECK_EQUAL( addr1[11], 12 );
+ BOOST_CHECK_EQUAL( addr1[12], 13 );
+ BOOST_CHECK_EQUAL( addr1[13], 14 );
+ BOOST_CHECK_EQUAL( addr1[14], 15 );
+ BOOST_CHECK_EQUAL( addr1[15], 0 );
+ BOOST_CHECK_EQUAL( INet6Address::from_string("ip6-localhost"), INet6Address::Loopback );
+ INet6Address addr2;
+ BOOST_CHECK_EQUAL( boost::lexical_cast<std::string>(addr2), "::" );
+ addr2 = INet6Address::from_string("::1");
+ BOOST_CHECK( addr1 != addr2 );
+ addr1 =INet6Address::from_string("::1");
+ BOOST_CHECK_EQUAL( addr1, addr2 );
+ addr1 = INet6Address::None;
+ addr2 = INet6Address::from_string("::");
+ BOOST_CHECK_EQUAL( addr1, addr2 );
+ BOOST_CHECK_THROW( INet6Address::from_string(""), INet6Address::SyntaxException );
+ BOOST_CHECK_EQUAL( boost::lexical_cast<std::string>(addr1), "::" );
+ unsigned char data[] = { 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x21, 0 };
+ INet6Address addr3 (INet6Address::from_data(data));
+ BOOST_CHECK_EQUAL( addr3, INet6Address::from_string("1200::21") );
+ BOOST_CHECK_EQUAL( INet6Address::from_inet4address(INet4Address(0x01020304)),
+ INet6Address::from_string("::ffff:1.2.3.4") );
+ }
+
+ {
+ INet6Address addr (INet6Address::from_string("2001:dead:beef::1002:3004"));
+ BOOST_CHECK_EQUAL( addr.network(), 0x2001deadbeef0000llu );
+ BOOST_CHECK_EQUAL( addr.id(), 0x0000000010023004llu );
+ BOOST_CHECK( addr.hasEuid64() );
+ BOOST_CHECK( ! INet6Address::from_inet4address(INet4Address(0x01020304)).hasEuid64() );
+ BOOST_CHECK( ! addr.universalId() );
+ BOOST_CHECK( ! addr.groupId() );
+ BOOST_CHECK( addr.unicast() );
+ BOOST_CHECK( ! addr.multicast() );
+ BOOST_CHECK( ! INet6Address::AllNodes.unicast() );
+ BOOST_CHECK( INet6Address::AllNodes.multicast() );
+ BOOST_CHECK_EQUAL( addr.scope(), INet6Address::GlobalScope );
+ BOOST_CHECK( addr.globalScope() );
+ BOOST_CHECK_EQUAL( INet6Address(0xfe80).scope(), INet6Address::LinkScope );
+ BOOST_CHECK_EQUAL( INet6Address(0xfec0).scope(), INet6Address::SiteScope );
+ BOOST_CHECK_EQUAL( INet6Address(0xff00).scope(), INet6Address::ReservedScope );
+ BOOST_CHECK_EQUAL( INet6Address(0xff01).scope(), INet6Address::InterfaceScope );
+ BOOST_CHECK_EQUAL( INet6Address(0xff02).scope(), INet6Address::LinkScope );
+ BOOST_CHECK_EQUAL( INet6Address(0xff03).scope(), INet6Address::ReservedScope );
+ BOOST_CHECK_EQUAL( INet6Address(0xff04).scope(), INet6Address::AdminScope );
+ BOOST_CHECK_EQUAL( INet6Address(0xff05).scope(), INet6Address::SiteScope );
+ BOOST_CHECK_EQUAL( INet6Address(0xff06).scope(), INet6Address::UnassignedScope );
+ BOOST_CHECK_EQUAL( INet6Address(0xff07).scope(), INet6Address::UnassignedScope );
+ BOOST_CHECK_EQUAL( INet6Address(0xff08).scope(), INet6Address::OrganizationScope );
+ BOOST_CHECK_EQUAL( INet6Address(0xff09).scope(), INet6Address::UnassignedScope );
+ BOOST_CHECK_EQUAL( INet6Address(0xff0a).scope(), INet6Address::UnassignedScope );
+ BOOST_CHECK_EQUAL( INet6Address(0xff0b).scope(), INet6Address::UnassignedScope );
+ BOOST_CHECK_EQUAL( INet6Address(0xff0c).scope(), INet6Address::UnassignedScope );
+ BOOST_CHECK_EQUAL( INet6Address(0xff0d).scope(), INet6Address::UnassignedScope );
+ BOOST_CHECK_EQUAL( INet6Address(0xff0e).scope(), INet6Address::GlobalScope );
+ BOOST_CHECK_EQUAL( INet6Address(0xff0f).scope(), INet6Address::ReservedScope );
+ BOOST_CHECK_EQUAL( INet6Address(0u,0u,0u,0u,0u,0xFFFF,0x0102u,0x0304).inet4address(),
+ INet4Address(0x01020304) );
+ BOOST_CHECK( INet6Address(0u,0u,0u,0u,0u,0u,0x0102u,0x0304).ipv4Compatible() );
+ BOOST_CHECK( INet6Address(0u,0u,0u,0u,0u,0xFFFF,0x0102,0x0304).ipv4Mapped() );
+ BOOST_CHECK( ! addr.ipv4Compatible() );
+ BOOST_CHECK( ! addr.ipv4Mapped() );
+
+ BOOST_CHECK( INet6Address::AllNodes.globalMulticastAddr() );
+ BOOST_CHECK( ! INet6Address::AllNodes.prefixMulticastAddr() );
+ BOOST_CHECK( ! INet6Address::AllNodes.embeddedRpAddr() );
+
+ BOOST_CHECK( INet6Address::Loopback );
+ BOOST_CHECK( ! INet6Address::None );
+ }
+
+ {
+ INet6Address addr;
+ addr.network(0x2000010203040506ull);
+ BOOST_CHECK_EQUAL( addr, INet6Address(0x2000u,0x0102u,0x0304u,0x0506u) );
+ addr.id(1u);
+ BOOST_CHECK_EQUAL( addr, INet6Address(0x2000u,0x0102u,0x0304u,0x0506u,0u,0u,0u,1u) );
+ }
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
///////////////////////////////cc.p////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
-// senf::INet4Address
+// senf::INet4SocketAddress
prefix_ senf::INet4SocketAddress::INet4SocketAddress(std::string const & addr)
{
}
///////////////////////////////////////////////////////////////////////////
-// senf::INet6Address
-
-prefix_ senf::INet6Address::INet6Address(std::string const & addr)
-{
- if (inet_pton(AF_INET6,addr.c_str(),&addr_) <= 0)
- throw SyntaxException();
-}
-
-prefix_ senf::INet6Address::INet6Address(char const * addr)
-{
- if (inet_pton(AF_INET6,addr,&addr_) <= 0)
- throw SyntaxException();
-}
-
-prefix_ void senf::INet6Address::clear()
-{
- ::memset(&addr_,0,sizeof(addr_));
-}
-
-prefix_ std::string senf::INet6Address::address()
- const
-{
- char buffer[8*5];
- BOOST_ASSERT( inet_ntop(AF_INET6, &addr_, buffer, sizeof(buffer)) );
- return std::string(buffer);
-}
-
-prefix_ bool senf::INet6Address::operator==(INet6Address const & other)
- const
-{
- return ::memcmp(&addr_,&other.addr_,sizeof(addr_))==0;
-}
-
-prefix_ bool senf::INet6Address::operator!=(INet6Address const & other)
- const
-{
- return !operator==(other);
-}
-
-///////////////////////////////////////////////////////////////////////////
// senf::INet6SocketAddress
prefix_ bool senf::INet6SocketAddress::operator==(INet6SocketAddress const & other)
}
///////////////////////////////////////////////////////////////////////////
-// senf::INet6Address
-
-prefix_ senf::INet6Address::INet6Address()
-{
- clear();
-}
-
-prefix_ senf::INet6Address::INet6Address(struct in6_addr const & addr)
-{
- addr_ = addr;
-}
-
-prefix_ struct in6_addr & senf::INet6Address::addr()
-{
- return addr_;
-}
-
-prefix_ struct in6_addr const & senf::INet6Address::addr()
- const
-{
- return addr_;
-}
-
-prefix_ struct in6_addr * senf::INet6Address::addr_p()
-{
- return & addr_;
-}
-
-prefix_ struct in6_addr const * senf::INet6Address::addr_p()
- const
-{
- return & addr_;
-}
-
-prefix_ unsigned senf::INet6Address::addr_len()
- const
-{
- return sizeof(addr_);
-}
-
-prefix_ std::ostream & senf::operator<<(std::ostream & os, INet6Address const & addr)
-{
- os << addr.address();
- return os;
-}
-
-///////////////////////////////////////////////////////////////////////////
// senf::INet6SocketAddress
prefix_ senf::INet6SocketAddress::INet6SocketAddress()
prefix_ senf::INet6SocketAddress::INet6SocketAddress(INet6Address const & addr, unsigned port)
{
clear();
- sockaddr_.sin6_addr = addr.addr();
+ std::copy(addr.begin(), addr.end(), &sockaddr_.sin6_addr.s6_addr[0]);
sockaddr_.sin6_port = htons(port);
}
std::string const & iface)
{
clear();
- sockaddr_.sin6_addr = addr.addr();
+ std::copy(addr.begin(), addr.end(), &sockaddr_.sin6_addr.s6_addr[0]);
sockaddr_.sin6_port = htons(port);
assignIface(iface);
}
prefix_ senf::INet6Address senf::INet6SocketAddress::host()
const
{
- return INet6Address(sockaddr_.sin6_addr);
+ return INet6Address::from_data(&sockaddr_.sin6_addr.s6_addr[0]);
}
prefix_ void senf::INet6SocketAddress::host(INet6Address const & addr)
{
- sockaddr_.sin6_addr = addr.addr();
+ std::copy(addr.begin(), addr.end(), &sockaddr_.sin6_addr.s6_addr[0]);
}
prefix_ unsigned senf::INet6SocketAddress::port()
#include "Socket/CommunicationPolicy.hh"
#include "Socket/Protocols/GenericAddressingPolicy.hh"
#include "INet4Address.hh"
+#include "INet6Address.hh"
//#include "INetAddressing.mpp"
///////////////////////////////hh.p////////////////////////////////////////
*/
std::ostream & operator<<(std::ostream & os, INet4SocketAddress const & addr);
- /** \brief IPv6 network address
-
- INet6Address represents a 128bit IPv6 network address. This class supports all standard
- numeric string representations of IPv6 addresses. This class does not integrate with \c
- gethostbyname() and so does not support host names.
-
- The conversion constructors allow the use of string constants wherever an INet6Address is
- expected. Especially, it is possible to assign a string to an address to change it's value.
-
- \implementation The <tt>char const *</tt> constructor overload is needed to support
- string-literals where an INet6Address is expected (the C++ standard does not allow
- chaining conversion constructors like char const * -> std::string -> INet6Address)
- */
- class INet6Address
- {
- public:
- ///////////////////////////////////////////////////////////////////////////
- // Types
-
- ///////////////////////////////////////////////////////////////////////////
- ///\name Structors and default members
- ///@{
-
- INet6Address(); ///< Create empty address
- INet6Address(std::string const & addr); ///< Create address from string representation
- INet6Address(char const * addr); ///< Create address from string representation
- INet6Address(struct in6_addr const & addr); ///< Create address from in6_addr
- template <class Range>
- explicit INet6Address(Range const & range); ///< Create address from arbitrary raw data
- /**< This constructor will copy 16 bytes from the given
- range and interpret them as a IPv6 address in network
- byte order. This constructor is used to read an
- arbitrary address from it's binary representation.
-
- \param range arbitrary range, see <a
- href="http://www.boost.org/libs/range/index.html">Boost.Range</a>
- */
-
- ///@}
- ///////////////////////////////////////////////////////////////////////////
-
- void clear(); ///< Clear address
- std::string address() const; ///< Return printable address representation
-
- bool operator==(INet6Address const & other) const; ///< Compare addresses for equality
- bool operator!=(INet6Address const & other) const; ///< Inverse of above
-
- struct in6_addr & addr(); ///< Access internal address representation
- struct in6_addr const & addr() const;
- ///< Access internal address representation in const context
- struct in6_addr * addr_p(); ///< Get pointer to internal address repr
- struct in6_addr const * addr_p() const;
- ///< Get const pointer to internal address repr
- unsigned addr_len() const; ///< Size of an IPv6 address (16 bytes)
-
- struct SyntaxException : public std::exception
- { virtual char const * what() const throw() { return "Invalid IpV6 address syntax"; } };
-
- protected:
-
- private:
- struct in6_addr addr_;
- };
-
-
- /** \brief Output INet6Address instance as it's string representation
- */
- std::ostream & operator<<(std::ostream & os, INet6Address const & addr);
-
/** \brief IPv6 socket address
This class wraps the standard \c sockaddr_in6 structure. INet6SocketAddress provides access
///////////////////////////////hh.e////////////////////////////////////////
#include "INetAddressing.cci"
-#include "INetAddressing.ct"
+//#include "INetAddressing.ct"
//#include "INetAddressing.cti"
//#include "INetAddressing.mpp"
#endif
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
-BOOST_AUTO_UNIT_TEST(inet4Address)
+BOOST_AUTO_UNIT_TEST(inet4SocketAddress)
{
using senf::INet4SocketAddress;
using senf::INet4Address;
}
}
-BOOST_AUTO_UNIT_TEST(inet6Address)
+BOOST_AUTO_UNIT_TEST(inet6SocketAddress)
{
using senf::INet6Address;
using senf::INet6SocketAddress;
{
- INet6Address addr1 ("0102:0304:0506:0708:090A:0B0C:0D0E:0F00");
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[0], 1 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[1], 2 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[2], 3 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[3], 4 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[4], 5 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[5], 6 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[6], 7 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[7], 8 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[8], 9 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[9], 10 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[10], 11 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[11], 12 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[12], 13 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[13], 14 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[14], 15 );
- BOOST_CHECK_EQUAL( addr1.addr().s6_addr[15], 0 );
- INet6Address addr2;
- BOOST_CHECK_EQUAL( addr2, "::" );
- addr2 = "::1";
- BOOST_CHECK( addr1 != addr2 );
- addr1 ="::1";
- BOOST_CHECK_EQUAL( addr1, addr2 );
- BOOST_CHECK_EQUAL( addr1.address(),"::1" );
- addr1.clear();
- addr2 = "::";
- BOOST_CHECK_EQUAL( addr1, addr2 );
- BOOST_CHECK_THROW( addr1 = "", INet6Address::SyntaxException );
- BOOST_CHECK_EQUAL( boost::lexical_cast<std::string>(addr1), "::" );
- unsigned char data[] = { 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x21, 0 };
- INet6Address addr3 (std::make_pair(&data[0],&data[0]+sizeof(data)-1));
- BOOST_CHECK_EQUAL( addr3, "1200::21" );
- BOOST_CHECK_THROW( INet6Address(std::make_pair(&data[0],&data[0]+sizeof(data))),
- INet6Address::SyntaxException );
- BOOST_CHECK_THROW( INet6Address(std::make_pair(&data[0],&data[0]+sizeof(data)-2)),
- INet6Address::SyntaxException );
- }
-
- {
INet6SocketAddress addr;
- BOOST_CHECK_EQUAL( addr.host(), "::" );
+ BOOST_CHECK_EQUAL( boost::lexical_cast<std::string>(addr.host()), "::" );
BOOST_CHECK_EQUAL( addr.port(), 0u );
BOOST_CHECK_EQUAL( addr.iface(), "" );
addr = "[12::21]:12345";
- BOOST_CHECK_EQUAL( addr.host(), "12::21" );
+ BOOST_CHECK_EQUAL( addr.host(), INet6Address::from_string("12::21") );
BOOST_CHECK_EQUAL( addr.port(), 12345u );
BOOST_CHECK_EQUAL( addr.iface(), "" );
BOOST_CHECK_EQUAL( addr, INet6SocketAddress("[12::21]:12345") );
}
{
- INet6SocketAddress addr ("::1", 1);
+ INet6SocketAddress addr (INet6Address::from_string("::1"), 1);
BOOST_CHECK_EQUAL( addr, "[::1]:1" );
BOOST_CHECK_EQUAL( addr.iface(), "" );
}
{
- INet6SocketAddress addr ("::1", 1, "lo");
+ INet6SocketAddress addr (INet6Address::Loopback, 1, "lo");
BOOST_CHECK_EQUAL( addr, "[::1@lo]:1" );
BOOST_CHECK_EQUAL( addr.iface(), "lo" );
addr.iface("");
BOOST_CHECK_EQUAL( addr.iface(), "" );
addr.port(100u);
BOOST_CHECK_EQUAL( addr.port(), 100u );
- addr.host("::2");
- BOOST_CHECK_EQUAL( addr.host(), "::2" );
+ addr.host(INet6Address::from_string("::2"));
+ BOOST_CHECK_EQUAL( addr.host(), INet6Address::from_string("::2") );
BOOST_CHECK_THROW( addr = "", INet6SocketAddress::SyntaxException );
BOOST_CHECK_THROW( addr = "[::1]", INet6SocketAddress::SyntaxException );
BOOST_CHECK_THROW( addr = "[::1]1234", INet6SocketAddress::SyntaxException );
addr = "[12::21@lo]:12345";
BOOST_CHECK_EQUAL( addr.address(), "[12::21@lo]:12345" );
- BOOST_CHECK_EQUAL( addr.host(), "12::21" );
+ BOOST_CHECK_EQUAL( addr.host(), INet6Address::from_string("12::21") );
BOOST_CHECK_EQUAL( addr.port(), 12345u );
BOOST_CHECK_EQUAL( addr.iface(), "lo" );
BOOST_CHECK_EQUAL( boost::lexical_cast<std::string>(addr), "[12::21@lo]:12345" );
ethertype
EthVLan
EUI
+EUID
ExampleListPolicy
ExampleVectorPolicy
ExtendedParser
+FFFF
FileBody
filebody
FileHandle
FooParser
fraunhofer
fuer
+GlobalScope
hh
hideinitializer
Hmm
InvalidPacketChainException
ip
IpV
+ipv
iterator
key
Kommunikationssysteme
Kompetenzzentrum
li
+LinkScope
ListB
ListN
ListPolicy
registerSomePacket
RegistrationProxy
rerference
+RFC
+RP
SafePacketParser
SatCom
Satelitenkommunikation
+ScopeId
senf
ServerSocketHandle
setBegin
setFromPosition
SimplePacketType
SimpleVectorSizer
+SiteScope
SizeParser
skipline
SocketHandle
UDPPacket
UInt
UIntField
+unicast
VectorN
vlanId
VLanId