Socket/Protocols/INet: Completely new implementation of INet6Address
g0dil [Mon, 30 Jul 2007 22:59:09 +0000 (22:59 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@362 270642c3-0616-0410-b53a-bc976706d245

17 files changed:
Packets/DefaultBundle/IpV6Extensions.test.cc
Packets/DefaultBundle/IpV6Packet.cc
Packets/DefaultBundle/IpV6Packet.test.cc
Socket/Protocols/INet/INet4Address.cc
Socket/Protocols/INet/INet4Address.hh
Socket/Protocols/INet/INet6Address.cc [new file with mode: 0644]
Socket/Protocols/INet/INet6Address.cci [new file with mode: 0644]
Socket/Protocols/INet/INet6Address.ct [moved from Socket/Protocols/INet/INetAddressing.ct with 67% similarity]
Socket/Protocols/INet/INet6Address.cti [new file with mode: 0644]
Socket/Protocols/INet/INet6Address.hh [new file with mode: 0644]
Socket/Protocols/INet/INet6Address.ih [new file with mode: 0644]
Socket/Protocols/INet/INet6Address.test.cc [new file with mode: 0644]
Socket/Protocols/INet/INetAddressing.cc
Socket/Protocols/INet/INetAddressing.cci
Socket/Protocols/INet/INetAddressing.hh
Socket/Protocols/INet/INetAddressing.test.cc
senf.dict

index 728d9fe..457597b 100644 (file)
@@ -69,8 +69,10 @@ BOOST_AUTO_UNIT_TEST(ipv6Extension_Fragment_packet)
     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>());
index 63c341a..520772e 100644 (file)
@@ -52,8 +52,8 @@ prefix_ void senf::IpV6PacketType::dump(packet p, std::ostream & os)
        << "  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////////////////////////////////////////
index 9882ab5..c65b062 100644 (file)
@@ -54,10 +54,10 @@ BOOST_AUTO_UNIT_TEST(ipV6Packet_packet)
     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>() );
index 5495e32..4d29a1d 100644 (file)
@@ -113,8 +113,8 @@ prefix_ senf::INet4Address::address_type senf::INet4Address::address()
 }
 
 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);
 
 
 ///////////////////////////////////////////////////////////////////////////
index f075555..d7b13a1 100644 (file)
@@ -50,6 +50,9 @@ namespace senf {
 
     {
     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;
@@ -61,8 +64,12 @@ namespace senf {
 
         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
 
@@ -104,6 +111,11 @@ namespace senf {
                                              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. */
@@ -125,6 +137,8 @@ namespace senf {
                                              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"; } };
 
diff --git a/Socket/Protocols/INet/INet6Address.cc b/Socket/Protocols/INet/INet6Address.cc
new file mode 100644 (file)
index 0000000..0def041
--- /dev/null
@@ -0,0 +1,109 @@
+// 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:
diff --git a/Socket/Protocols/INet/INet6Address.cci b/Socket/Protocols/INet/INet6Address.cci
new file mode 100644 (file)
index 0000000..029c4e8
--- /dev/null
@@ -0,0 +1,229 @@
+// 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:
similarity index 67%
rename from Socket/Protocols/INet/INetAddressing.ct
rename to Socket/Protocols/INet/INet6Address.ct
index d2782a0..a93e78a 100644 (file)
@@ -1,4 +1,4 @@
-// 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////////////////////////////////////////
@@ -49,9 +49,9 @@ prefix_ senf::INet6Address::INet6Address(Range const & range)
 // 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:
diff --git a/Socket/Protocols/INet/INet6Address.cti b/Socket/Protocols/INet/INet6Address.cti
new file mode 100644 (file)
index 0000000..9ab78ba
--- /dev/null
@@ -0,0 +1,174 @@
+// 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:
diff --git a/Socket/Protocols/INet/INet6Address.hh b/Socket/Protocols/INet/INet6Address.hh
new file mode 100644 (file)
index 0000000..48a2906
--- /dev/null
@@ -0,0 +1,276 @@
+// 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:
diff --git a/Socket/Protocols/INet/INet6Address.ih b/Socket/Protocols/INet/INet6Address.ih
new file mode 100644 (file)
index 0000000..1dc03ff
--- /dev/null
@@ -0,0 +1,203 @@
+// 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:
diff --git a/Socket/Protocols/INet/INet6Address.test.cc b/Socket/Protocols/INet/INet6Address.test.cc
new file mode 100644 (file)
index 0000000..562c8e6
--- /dev/null
@@ -0,0 +1,147 @@
+// 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:
index d768c7d..9ef8c39 100644 (file)
@@ -41,7 +41,7 @@
 ///////////////////////////////cc.p////////////////////////////////////////
 
 ///////////////////////////////////////////////////////////////////////////
-// senf::INet4Address
+// senf::INet4SocketAddress
 
 prefix_ senf::INet4SocketAddress::INet4SocketAddress(std::string const & addr)
 {
@@ -72,46 +72,6 @@ prefix_ void senf::INet4SocketAddress::clear()
 }
 
 ///////////////////////////////////////////////////////////////////////////
-// 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)
index f0e039d..f053e1d 100644 (file)
@@ -97,53 +97,6 @@ prefix_ std::ostream & senf::operator<<(std::ostream & os, INet4SocketAddress co
 }
 
 ///////////////////////////////////////////////////////////////////////////
-// 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()
@@ -166,7 +119,7 @@ prefix_ senf::INet6SocketAddress::INet6SocketAddress(char const * addr)
 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);
 }
 
@@ -174,7 +127,7 @@ prefix_ senf::INet6SocketAddress::INet6SocketAddress(INet6Address const & addr,
                                                      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);
 }
@@ -190,12 +143,12 @@ prefix_ senf::INet6SocketAddress::INet6SocketAddress(std::string const & addr,
 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()
index 79ccb52..7d01b0a 100644 (file)
@@ -37,6 +37,7 @@
 #include "Socket/CommunicationPolicy.hh"
 #include "Socket/Protocols/GenericAddressingPolicy.hh"
 #include "INet4Address.hh"
+#include "INet6Address.hh"
 
 //#include "INetAddressing.mpp"
 ///////////////////////////////hh.p////////////////////////////////////////
@@ -112,75 +113,6 @@ namespace senf {
      */
     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
@@ -342,7 +274,7 @@ namespace senf {
 
 ///////////////////////////////hh.e////////////////////////////////////////
 #include "INetAddressing.cci"
-#include "INetAddressing.ct"
+//#include "INetAddressing.ct"
 //#include "INetAddressing.cti"
 //#include "INetAddressing.mpp"
 #endif
index c8c8024..102b95d 100644 (file)
@@ -34,7 +34,7 @@
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
 
-BOOST_AUTO_UNIT_TEST(inet4Address)
+BOOST_AUTO_UNIT_TEST(inet4SocketAddress)
 {
     using senf::INet4SocketAddress;
     using senf::INet4Address;
@@ -78,84 +78,45 @@ BOOST_AUTO_UNIT_TEST(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" );
index 2d56094..362d243 100644 (file)
--- a/senf.dict
+++ b/senf.dict
@@ -46,9 +46,11 @@ EthernetParser
 ethertype
 EthVLan
 EUI
+EUID
 ExampleListPolicy
 ExampleVectorPolicy
 ExtendedParser
+FFFF
 FileBody
 filebody
 FileHandle
@@ -59,6 +61,7 @@ fokus
 FooParser
 fraunhofer
 fuer
+GlobalScope
 hh
 hideinitializer
 Hmm
@@ -83,11 +86,13 @@ IntField
 InvalidPacketChainException
 ip
 IpV
+ipv
 iterator
 key
 Kommunikationssysteme
 Kompetenzzentrum
 li
+LinkScope
 ListB
 ListN
 ListPolicy
@@ -152,9 +157,12 @@ registerPacketType
 registerSomePacket
 RegistrationProxy
 rerference
+RFC
+RP
 SafePacketParser
 SatCom
 Satelitenkommunikation
+ScopeId
 senf
 ServerSocketHandle
 setBegin
@@ -162,6 +170,7 @@ setEnd
 setFromPosition
 SimplePacketType
 SimpleVectorSizer
+SiteScope
 SizeParser
 skipline
 SocketHandle
@@ -193,6 +202,7 @@ udp
 UDPPacket
 UInt
 UIntField
+unicast
 VectorN
 vlanId
 VLanId