Implemented IpV6Packet and added raw-data constructor to INet6Address
g0dil [Fri, 16 Feb 2007 14:13:02 +0000 (14:13 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@202 270642c3-0616-0410-b53a-bc976706d245

13 files changed:
Packets/EthernetPacket.hh
Packets/IpV4Packet.cti
Packets/IpV4Packet.hh
Packets/IpV6Packet.cc [new file with mode: 0644]
Packets/IpV6Packet.cti [new file with mode: 0644]
Packets/IpV6Packet.hh [new file with mode: 0644]
Packets/IpV6Packet.test.cc [new file with mode: 0644]
Packets/SConscript
Packets/UDPPacket.cc
Packets/UDPPacket.hh
Socket/INetAddressing.ct [new file with mode: 0644]
Socket/INetAddressing.hh
Socket/INetAddressing.test.cc

index 53d1dca..56b1f49 100644 (file)
@@ -58,6 +58,7 @@ namespace senf {
     };
 
     struct EtherTypes {
+       // See http://www.iana.org/assignments/ethernet-numbers
         typedef boost::uint16_t key_t;
     };
 
index 423be2f..a7a5cf8 100644 (file)
@@ -34,8 +34,6 @@ prefix_ senf::IpV4Packet::IpV4Packet(Arg const & arg)
     : Packet(arg)
 {}
 
-
-
 ///////////////////////////////cti.e///////////////////////////////////////
 #undef prefix_
 
index 0d12628..b801426 100644 (file)
@@ -75,16 +75,18 @@ namespace senf {
         Parse_32bit    destination() const { return Parse_32bit   (this->i() + 16 ); }
     };
 
-    struct IpV4Types {
+    struct IpTypes {
+       // See http://www.iana.org/assignments/protocol-numbers
+       // Also used by IPv6
         typedef boost::uint16_t key_t;
     };
 
     class IpV4Packet
         : public Packet, 
           public Parse_IpV4<Packet::iterator,IpV4Packet>, 
-          public PacketRegistryMixin<IpV4Types,IpV4Packet>
+          public PacketRegistryMixin<IpTypes,IpV4Packet>
     {
-        using PacketRegistryMixin<IpV4Types,IpV4Packet>::registerInterpreter;
+        using PacketRegistryMixin<IpTypes,IpV4Packet>::registerInterpreter;
     public:
         ///////////////////////////////////////////////////////////////////////////
         // Types
diff --git a/Packets/IpV6Packet.cc b/Packets/IpV6Packet.cc
new file mode 100644 (file)
index 0000000..b511d02
--- /dev/null
@@ -0,0 +1,73 @@
+// 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 IpV6Packet non-inline non-template implementation */
+
+#include "IpV6Packet.hh"
+//#include "IpV6Packet.ih"
+
+// Custom includes
+#include "EthernetPacket.hh"
+#include "Socket/INetAddressing.hh"
+
+//#include "IpV6Packet.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace {
+    senf::PacketRegistry<senf::EtherTypes>::RegistrationProxy<senf::IpV6Packet>
+        registerIpV6Packet(0x86dd);
+}
+
+prefix_ void senf::IpV6Packet::v_nextInterpreter()
+    const
+{
+    registerInterpreter(nextHeader(),begin()+bytes(),end());
+}
+
+prefix_ void senf::IpV6Packet::v_finalize()
+{}
+
+prefix_ void senf::IpV6Packet::v_dump(std::ostream & os)
+    const
+{
+    os << "Internet protocol Version 6:\n"
+       << "  version       : " << unsigned(version()) << "\n"
+       << "  traffic class : " << std::hex << unsigned(trafficClass()) << "\n"
+       << "  flow label    : " << std::hex << unsigned(flowLabel()) << "\n"
+       << "  length        : " << std::dec << unsigned(length()) << "\n"
+       << "  next header   : " << unsigned(nextHeader()) << "\n"
+       << "  hop limit     : " << unsigned(hopLimit()) << "\n"
+       << "  source        : " << INet6Address(source().range()) << "\n"
+       << "  destination   : " << INet6Address(destination().range()) << "\n";
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "IpV6Packet.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// ispell-local-dictionary: "american"
+// End:
diff --git a/Packets/IpV6Packet.cti b/Packets/IpV6Packet.cti
new file mode 100644 (file)
index 0000000..a78167b
--- /dev/null
@@ -0,0 +1,45 @@
+// 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 IpV6Packet inline template implementation */
+
+//#include "IpV6Packet.ih"
+
+// Custom includes
+
+#define prefix_ inline
+///////////////////////////////cti.p///////////////////////////////////////
+
+template <class Arg>
+prefix_ senf::IpV6Packet::IpV6Packet(Arg const & arg)
+    : Packet(arg)
+{}
+
+///////////////////////////////cti.e///////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// ispell-local-dictionary: "american"
+// End:
diff --git a/Packets/IpV6Packet.hh b/Packets/IpV6Packet.hh
new file mode 100644 (file)
index 0000000..99d2476
--- /dev/null
@@ -0,0 +1,110 @@
+// 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 IpV6Packet public header */
+
+#ifndef HH_IpV6Packet_
+#define HH_IpV6Packet_ 1
+
+// Custom includes
+#include "Packet.hh"
+#include "ParseInt.hh"
+#include "ParseArray.hh"
+#include "PacketRegistry.hh"
+#include "IpV4Packet.hh"
+
+//#include "IpV6Packet.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+
+    template <class Iterator=nil, class IpV6Packet=nil>
+    struct Parse_IpV6 : public ParserBase<Iterator,IpV6Packet>
+    {
+        template <class I, class P=nil>
+        struct rebind { typedef Parse_IpV6<I,P> parser; };
+        typedef Iterator byte_iterator;
+
+        Parse_IpV6() {}
+        Parse_IpV6(Iterator const & i) : ParserBase<Iterator,IpV6Packet>(i) {}
+
+        static unsigned bytes() { return 40; }
+        
+        ///////////////////////////////////////////////////////////////////////////
+
+       typedef Parse_UIntField <  0,  4, Iterator > Parse_Version;
+       typedef Parse_UIntField <  4, 12, Iterator > Parse_Class;
+       typedef Parse_UIntField < 12, 32, Iterator > Parse_FlowLabel;
+       typedef Parse_UInt8     <         Iterator > Parse_8bit;
+       typedef Parse_UInt16    <         Iterator > Parse_16bit;
+
+       typedef Parse_Array < 16, Parse_8bit, Iterator > Parse_Addr;
+
+       Parse_Version    version()       const { return Parse_Version   (this->i()      ); }
+        Parse_Class      trafficClass()  const { return Parse_Class     (this->i()      ); }
+       Parse_FlowLabel  flowLabel()     const { return Parse_FlowLabel (this->i()      ); }
+       Parse_16bit      length()        const { return Parse_16bit     (this->i() +  4 ); }
+        Parse_8bit       nextHeader()    const { return Parse_8bit      (this->i() +  6 ); }
+       Parse_8bit       hopLimit()      const { return Parse_8bit      (this->i() +  7 ); }
+        Parse_Addr       source()        const { return Parse_Addr      (this->i() +  8 ); }
+       Parse_Addr       destination()   const { return Parse_Addr      (this->i() + 24 ); }
+    };
+
+    class IpV6Packet
+       : public Packet,
+         public Parse_IpV6<Packet::iterator, IpV6Packet>,
+         public PacketRegistryMixin<IpTypes, IpV6Packet>
+    {
+       using PacketRegistryMixin<IpTypes,IpV6Packet>::registerInterpreter;
+    public:
+        ///////////////////////////////////////////////////////////////////////////
+        // Types
+
+        typedef ptr_t<IpV6Packet>::ptr ptr;
+
+        ///////////////////////////////////////////////////////////////////////////
+
+    private:
+        template <class Arg>
+        IpV6Packet(Arg const & arg);
+
+        virtual void v_nextInterpreter() const;
+        virtual void v_finalize();
+        virtual void v_dump(std::ostream & os) const;
+
+        friend class Packet;
+    };
+
+}    
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "IpV6Packet.cci"
+//#include "IpV6Packet.ct"
+#include "IpV6Packet.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// ispell-local-dictionary: "american"
+// End:
diff --git a/Packets/IpV6Packet.test.cc b/Packets/IpV6Packet.test.cc
new file mode 100644 (file)
index 0000000..70008a4
--- /dev/null
@@ -0,0 +1,72 @@
+// 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 IpV6Packet unit tests */
+
+//#include "IpV6Packet.test.hh"
+//#include "IpV6Packet.test.ih"
+
+// Custom includes
+#include "IpV6Packet.hh"
+#include "Socket/INetAddressing.hh"
+
+#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/test_tools.hpp>
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+using namespace senf;
+
+BOOST_AUTO_UNIT_TEST(ipV6Packet_parser)
+{
+    unsigned char data[] = { 0x60, 0x12, 0x20, 0x30,
+                            0x01, 0x02, 0x03, 0x04,
+                            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 
+                            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+                            0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 
+                            0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f };
+
+    typedef unsigned char * iterator;
+    Parse_IpV6<iterator> p(data);
+
+    BOOST_CHECK_EQUAL( unsigned(p.version()),       0x06u      );
+    BOOST_CHECK_EQUAL( unsigned(p.trafficClass()),  0x01u      );
+    BOOST_CHECK_EQUAL( unsigned(p.flowLabel()),     0x22030u   );
+    BOOST_CHECK_EQUAL( unsigned(p.length()),        0x0102u    );
+    BOOST_CHECK_EQUAL( unsigned(p.nextHeader()),    0x03u      );
+    BOOST_CHECK_EQUAL( unsigned(p.hopLimit()),      0x04u      );
+    BOOST_CHECK_EQUAL( INet6Address(p.source().range()).address() , 
+                      "1011:1213:1415:1617:1819:1a1b:1c1d:1e1f" );
+    BOOST_CHECK_EQUAL( INet6Address(p.destination().range()).address() , 
+                      "2021:2223:2425:2627:2829:2a2b:2c2d:2e2f" );
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// ispell-local-dictionary: "american"
+// End:
index 9db975b..b39aa65 100644 (file)
@@ -6,8 +6,14 @@ import SENFSCons
 ###########################################################################
 
 sources = SENFSCons.GlobSources()
+
 SENFSCons.StandardTargets(env)
-SENFSCons.Lib(env, 'Packets',  sources, )
+
+SENFSCons.Lib(env,
+              library = 'Packets',
+              sources = sources,
+              LIBS = [ 'Socket', 'Utils' ])
+
 SENFSCons.Doxygen(env, extra_sources = [
     env.Dia2Png("structure.dia")
-    ])
+])
index e4a48b6..c9c2a22 100644 (file)
@@ -31,8 +31,9 @@
 
 #define prefix_
 ///////////////////////////////cc.p////////////////////////////////////////
+
 namespace {
-    senf::PacketRegistry<senf::IpV4Types>::RegistrationProxy<senf::UDPPacket> 
+    senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::UDPPacket> 
         registerUDPPacket(17);
 }
 
index 54cea7f..e94f9c4 100644 (file)
@@ -33,7 +33,6 @@
 ///////////////////////////////hh.p////////////////////////////////////////
 
 namespace senf {
-
     
     template <class Iterator=nil, class IPacket=nil>
     struct Parse_UDP : public ParserBase<Iterator,IPacket>
diff --git a/Socket/INetAddressing.ct b/Socket/INetAddressing.ct
new file mode 100644 (file)
index 0000000..8e682b0
--- /dev/null
@@ -0,0 +1,54 @@
+// 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 INetAddressing non-inline template implementation  */
+
+//#include "INetAddressing.ih"
+
+// Custom includes
+#include <boost/range.hpp>
+
+#define prefix_
+///////////////////////////////ct.p////////////////////////////////////////
+
+template <class Range>
+prefix_ senf::INet6Address::INet6Address(Range const & range)
+{
+    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 InvalidINetAddressException();
+}
+
+///////////////////////////////ct.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// ispell-local-dictionary: "american"
+// End:
index 4a8deca..9233892 100644 (file)
@@ -128,10 +128,20 @@ namespace senf {
         ///\name Structors and default members
         ///@{
 
-        INet6Address();
-        INet6Address(std::string const & addr);
-       INet6Address(char const * addr);
-       INet6Address(struct in6_addr const & addr);
+        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>
+                                         */
 
         ///@}
         ///////////////////////////////////////////////////////////////////////////
@@ -326,7 +336,7 @@ namespace senf {
 
 ///////////////////////////////hh.e////////////////////////////////////////
 #include "INetAddressing.cci"
-//#include "INetAddressing.ct"
+#include "INetAddressing.ct"
 //#include "INetAddressing.cti"
 //#include "INetAddressing.mpp"
 #endif
index b19990a..f649914 100644 (file)
@@ -111,6 +111,13 @@ BOOST_AUTO_UNIT_TEST(inet6Address)
        BOOST_CHECK_EQUAL( addr1, addr2 );
        BOOST_CHECK_THROW( addr1 = "", InvalidINetAddressException );
        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))), 
+                          InvalidINetAddressException );
+       BOOST_CHECK_THROW( INet6Address(std::make_pair(&data[0],&data[0]+sizeof(data)-2)), 
+                          InvalidINetAddressException );
     }
 
     {