Added ICMPv6 types for IPv6 Neighbor Discovery
ssauer [Tue, 20 Apr 2010 14:56:52 +0000 (14:56 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1598 270642c3-0616-0410-b53a-bc976706d245

senf/Packets/DefaultBundle/ICMPv6Packet.test.cc
senf/Packets/DefaultBundle/ICMPv6TypePacket.cc
senf/Packets/DefaultBundle/ICMPv6TypePacket.hh
senf/Packets/DefaultBundle/NDPMessage.test.cc [new file with mode: 0644]
senf/Packets/DefaultBundle/NDPOptions.cc [new file with mode: 0644]
senf/Packets/DefaultBundle/NDPOptions.hh [new file with mode: 0644]

index 695ccae..3502a61 100644 (file)
@@ -27,6 +27,7 @@
 #include <sstream>
 #include "ICMPv6Packet.hh"
 #include "ICMPv6TypePacket.hh"
+#include "NDPOptions.hh"
 
 #include <senf/Utils/auto_unit_test.hh>
 #include <boost/test/test_tools.hpp>
@@ -157,6 +158,106 @@ SENF_AUTO_UNIT_TEST(ICMPv6Packet_packet)
 
     SENF_CHECK_NO_THROW( pErrParamProblem.dump( oss));
     
+    unsigned char dataRouterSolicitation[] = {
+        0x85, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x05, 0x01, 0x00, 0x00,
+        0x12, 0x34, 0x56, 0x78
+    };
+
+    senf::ICMPv6Packet pRouterSolicitation ( senf::ICMPv6Packet::create(dataRouterSolicitation) );
+    BOOST_CHECK_EQUAL( pRouterSolicitation->type(),     0x85   );
+    BOOST_CHECK_EQUAL( pRouterSolicitation->code(),     0x00   );
+    BOOST_CHECK_EQUAL( pRouterSolicitation->checksum(), 0x0000 );
+    BOOST_CHECK( pRouterSolicitation.next() );
+    BOOST_CHECK( pRouterSolicitation.next().is<senf::NDPRouterSolicitationMessage>() );
+    BOOST_CHECK_EQUAL( pRouterSolicitation.next().size(), 12u );
+
+    senf::NDPRouterSolicitationMessage pOption(pRouterSolicitation.next().as<senf::NDPRouterSolicitationMessage>());
+    senf::NDPRouterSolicitationMessage::Parser::options_t::container optC(pOption->options() );
+    senf::NDPRouterSolicitationMessage::Parser::options_t::container::iterator listIter (optC.begin());
+    BOOST_CHECK_EQUAL(listIter->type(),5u);
+    BOOST_CHECK_EQUAL(listIter->length(),1u);
+
+    SENF_CHECK_NO_THROW( pRouterSolicitation.dump( oss));
+
+    unsigned char dataRouterAdvertisement[] = {
+        0x86, 0x00, 0x00, 0x00,
+        0xFF, 0x00, 0x23, 0x28,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+    };
+
+    senf::ICMPv6Packet pRouterAdvertisement ( senf::ICMPv6Packet::create(dataRouterAdvertisement) );
+    BOOST_CHECK_EQUAL( pRouterAdvertisement->type(),     0x86   );
+    BOOST_CHECK_EQUAL( pRouterAdvertisement->code(),     0x00   );
+    BOOST_CHECK_EQUAL( pRouterAdvertisement->checksum(), 0x0000 );
+    BOOST_CHECK( pRouterAdvertisement.next() );
+    BOOST_CHECK( pRouterAdvertisement.next().is<senf::NDPRouterAdvertisementMessage>() );
+    BOOST_CHECK_EQUAL( pRouterAdvertisement.next().size(), 12u );
+
+    SENF_CHECK_NO_THROW( pRouterAdvertisement.dump( oss));
+
+    unsigned char dataNeighborSolicitation[] = {
+        0x87, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00
+    };
+
+    senf::ICMPv6Packet pNeighborSolicitation ( senf::ICMPv6Packet::create(dataNeighborSolicitation) );
+    BOOST_CHECK_EQUAL( pNeighborSolicitation->type(),     0x87   );
+    BOOST_CHECK_EQUAL( pNeighborSolicitation->code(),     0x00   );
+    BOOST_CHECK_EQUAL( pNeighborSolicitation->checksum(), 0x0000 );
+    BOOST_CHECK( pNeighborSolicitation.next() );
+    BOOST_CHECK( pNeighborSolicitation.next().is<senf::NDPNeighborSolicitationMessage>() );
+    BOOST_CHECK_EQUAL( pNeighborSolicitation.next().size(), 20u );
+
+    SENF_CHECK_NO_THROW( pNeighborSolicitation.dump( oss));
+
+    unsigned char dataNeighborAdvertisement[] = {
+        0x88, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00
+    };
+
+    senf::ICMPv6Packet pNeighborAdvertisement ( senf::ICMPv6Packet::create(dataNeighborAdvertisement) );
+    BOOST_CHECK_EQUAL( pNeighborAdvertisement->type(),     0x88   );
+    BOOST_CHECK_EQUAL( pNeighborAdvertisement->code(),     0x00   );
+    BOOST_CHECK_EQUAL( pNeighborAdvertisement->checksum(), 0x0000 );
+    BOOST_CHECK( pNeighborAdvertisement.next() );
+    BOOST_CHECK( pNeighborAdvertisement.next().is<senf::NDPNeighborAdvertisementMessage>() );
+    BOOST_CHECK_EQUAL( pNeighborAdvertisement.next().size(), 20u );
+
+    SENF_CHECK_NO_THROW( pNeighborAdvertisement.dump( oss));
+
+    unsigned char dataRedirect[] = {
+        0x89, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00
+    };
+
+    senf::ICMPv6Packet pRedirect ( senf::ICMPv6Packet::create(dataRedirect) );
+    BOOST_CHECK_EQUAL( pRedirect->type(),     0x89   );
+    BOOST_CHECK_EQUAL( pRedirect->code(),     0x00   );
+    BOOST_CHECK_EQUAL( pRedirect->checksum(), 0x0000 );
+    BOOST_CHECK( pRedirect.next() );
+    BOOST_CHECK( pRedirect.next().is<senf::NDPRedirectMessage>() );
+    BOOST_CHECK_EQUAL( pRedirect.next().size(), 36u );
+
+    SENF_CHECK_NO_THROW( pRedirect.dump( oss));
 }
 
 SENF_AUTO_UNIT_TEST(ICMPv6Packet_create)
index c7f18c0..2cd182b 100644 (file)
 ///////////////////////////////cc.p////////////////////////////////////////
 
 namespace {
-    SENF_PACKET_REGISTRY_REGISTER( senf::ICMPTypes, 1,   senf::ICMPv6ErrDestUnreachable );
-    SENF_PACKET_REGISTRY_REGISTER( senf::ICMPTypes, 2,   senf::ICMPv6ErrTooBig          );
-    SENF_PACKET_REGISTRY_REGISTER( senf::ICMPTypes, 3,   senf::ICMPv6ErrTimeExceeded    );
-    SENF_PACKET_REGISTRY_REGISTER( senf::ICMPTypes, 4,   senf::ICMPv6ErrParamProblem    );
-    SENF_PACKET_REGISTRY_REGISTER( senf::ICMPTypes, 128, senf::ICMPv6EchoRequest        );
-    SENF_PACKET_REGISTRY_REGISTER( senf::ICMPTypes, 129, senf::ICMPv6EchoReply          );
-    SENF_PACKET_REGISTRY_REGISTER( senf::ICMPTypes, 130, senf::MLDv2ListenerQuery       );
-    SENF_PACKET_REGISTRY_REGISTER( senf::ICMPTypes, 143, senf::MLDv2ListenerReport      );
+    SENF_PACKET_REGISTRY_REGISTER( senf::ICMPTypes, 1,   senf::ICMPv6ErrDestUnreachable       );
+    SENF_PACKET_REGISTRY_REGISTER( senf::ICMPTypes, 2,   senf::ICMPv6ErrTooBig                );
+    SENF_PACKET_REGISTRY_REGISTER( senf::ICMPTypes, 3,   senf::ICMPv6ErrTimeExceeded          );
+    SENF_PACKET_REGISTRY_REGISTER( senf::ICMPTypes, 4,   senf::ICMPv6ErrParamProblem          );
+    SENF_PACKET_REGISTRY_REGISTER( senf::ICMPTypes, 128, senf::ICMPv6EchoRequest              );
+    SENF_PACKET_REGISTRY_REGISTER( senf::ICMPTypes, 129, senf::ICMPv6EchoReply                );
+    SENF_PACKET_REGISTRY_REGISTER( senf::ICMPTypes, 130, senf::MLDv2ListenerQuery             );
+    SENF_PACKET_REGISTRY_REGISTER( senf::ICMPTypes, 133, senf::NDPRouterSolicitationMessage   );
+    SENF_PACKET_REGISTRY_REGISTER( senf::ICMPTypes, 134, senf::NDPRouterAdvertisementMessage  );
+    SENF_PACKET_REGISTRY_REGISTER( senf::ICMPTypes, 135, senf::NDPNeighborSolicitationMessage );
+    SENF_PACKET_REGISTRY_REGISTER( senf::ICMPTypes, 136, senf::NDPNeighborAdvertisementMessage);
+    SENF_PACKET_REGISTRY_REGISTER( senf::ICMPTypes, 137, senf::NDPRedirectMessage             );
+    SENF_PACKET_REGISTRY_REGISTER( senf::ICMPTypes, 143, senf::MLDv2ListenerReport            );
 }
 
 prefix_ void senf::ICMPv6EchoRequestType::dump(packet p, std::ostream & os)
@@ -120,5 +125,47 @@ prefix_ void senf::MLDv2ListenerReportType::dump(packet p, std::ostream & os)
     }
 }
 
+prefix_ void senf::NDPRouterSolicitationMessageType::dump(packet p, std::ostream & os)
+{
+    os << "ICMPv6 Neighbor Discovery Router Solicitation Message:\n"
+       << senf::fieldName("Reserved(32Bit)")           << unsigned(p->reserved()) << "\n";
+}
+
+prefix_ void senf::NDPRouterAdvertisementMessageType::dump(packet p, std::ostream & os)
+{
+    os << "ICMPv6 Neighbor Discovery Router Advertisement Message:\n"
+       << senf::fieldName("Current Hop Limit")             << unsigned(p->curHopLimit()) << "\n"
+       << senf::fieldName("Managed Address Configuration") << unsigned(p->m()) << "\n"
+       << senf::fieldName("Other Configuration")           << unsigned(p->o()) << "\n"
+       << senf::fieldName("Reserved(6Bit)")                << unsigned(p->reserved()) << "\n"
+       << senf::fieldName("Router Lifetime")               << unsigned(p->routerLifetime()) << "\n"
+       << senf::fieldName("Reachable Time")                << unsigned(p->reachableTime()) << "\n"
+       << senf::fieldName("Retrans Timer")                 << unsigned(p->retransTimer()) << "\n";
+}
+
+prefix_ void senf::NDPNeighborSolicitationMessageType::dump(packet p, std::ostream & os)
+{
+    os << "ICMPv6 Neighbor Discovery Neighbor Solicitation Message:\n"
+       << senf::fieldName("Reserved(32Bit)")          << unsigned(p->reserved()) << "\n"
+       << senf::fieldName("Target Address")           << p->target() << "\n";
+}
+
+prefix_ void senf::NDPNeighborAdvertisementMessageType::dump(packet p, std::ostream & os)
+{
+    os << "ICMPv6 Neighbor Discovery Neighbor Advertisement Message:\n"
+       << senf::fieldName("Router Flag")           << unsigned(p->r()) << "\n"
+       << senf::fieldName("Solicited Flag")        << unsigned(p->s()) << "\n"
+       << senf::fieldName("Override Flag")         << unsigned(p->o()) << "\n"
+       << senf::fieldName("Reserved(29Bit)")       << unsigned(p->reserved()) << "\n"
+       << senf::fieldName("Target Address")        << p->target() << "\n";
+}
+
+prefix_ void senf::NDPRedirectMessageType::dump(packet p, std::ostream & os)
+{
+    os << "ICMPv6 Neighbor Discovery Redirect Message:\n"
+       << senf::fieldName("Reserved(32Bit)")       << unsigned(p->reserved()) << "\n"
+       << senf::fieldName("Target Address")        << p->target() << "\n"
+       << senf::fieldName("Destination Address")   << p->destination() << "\n";
+}
 ///////////////////////////////cc.e////////////////////////////////////////
 #undef prefix_
index e1b1c02..4561fd8 100644 (file)
@@ -29,6 +29,8 @@
 #include <senf/Packets/Packets.hh>
 #include "IPv6Packet.hh"
 #include "ICMPv6Packet.hh"
+#include "ListOptionTypeParser.hh"
+#include "NDPOptions.hh"
 
 namespace senf {
 
@@ -428,8 +430,231 @@ namespace senf {
         
         static void dump(packet p, std::ostream & os);
     };
-        
     typedef ConcretePacket<MLDv2ListenerReportType> MLDv2ListenerReport;
+
+    //#############################################################
+    //ICMPv6 Router Solicitation (RFC 4861) Message
+    //#############################################################
+    struct NDPRouterSolicitationParser : public PacketParserBase
+    {
+#      include SENF_PARSER()
+        SENF_PARSER_FIELD    ( reserved, UInt32Parser );// set to zero by default
+        SENF_PARSER_LIST     ( options, packetSize(), senf::NDPGenericOptionParser );
+        SENF_PARSER_FINALIZE ( NDPRouterSolicitationParser );
+
+        SENF_PARSER_INIT() {
+            reserved() = 0;
+        }
+    };
+
+    /** \brief Router Solicitation Message
+
+        \par Packet type (typedef):
+            \ref NDPRouterSolicitationMessage
+
+        \par Fields:
+            \ref NDPRouterSolicitationParser
+            \image html NDPRouterSolicitationMessage.png
+
+        \ingroup protocolbundle_default
+     */
+    struct NDPRouterSolicitationMessageType
+        : public PacketTypeBase,
+          public PacketTypeMixin<NDPRouterSolicitationMessageType>
+    {
+        typedef PacketTypeMixin<NDPRouterSolicitationMessageType> mixin;
+        typedef ConcretePacket<NDPRouterSolicitationMessageType> packet;
+        typedef NDPRouterSolicitationParser parser;
+
+        using mixin::nextPacketRange;
+        using mixin::init;
+        using mixin::initSize;
+
+        static void dump(packet p, std::ostream & os);
+    };
+    typedef ConcretePacket<NDPRouterSolicitationMessageType> NDPRouterSolicitationMessage;
+
+    //#############################################################
+    //ICMPv6 Router Advertisement (RFC 4861) Message
+    //#############################################################
+    struct NDPRouterAdvertisementParser : public PacketParserBase
+    {
+#      include SENF_PARSER()
+        SENF_PARSER_FIELD        ( curHopLimit, UInt8Parser );
+        SENF_PARSER_BITFIELD     ( m, 1, bool);
+        SENF_PARSER_BITFIELD     ( o, 1, bool);
+        SENF_PARSER_BITFIELD     ( reserved, 6, unsigned ); // set to zero by default
+        SENF_PARSER_FIELD        ( routerLifetime, UInt16Parser );
+        SENF_PARSER_FIELD        ( reachableTime, UInt32Parser );
+        SENF_PARSER_FIELD        ( retransTimer, UInt32Parser );
+        SENF_PARSER_LIST         ( options, packetSize(), senf::NDPGenericOptionParser );
+        SENF_PARSER_FINALIZE     ( NDPRouterAdvertisementParser );
+
+        SENF_PARSER_INIT() {
+            reserved() = 0;
+        }
+    };
+
+    /** \brief Router Advertisement Message
+
+        \par Packet type (typedef):
+            \ref NDPRouterAdvertisementMessage
+
+        \par Fields:
+            \ref NDPRouterAdvertisementParser
+            \imageMessage html NDPRouterAdvertisementMessage.png
+
+        \ingroup protocolbundle_default
+     */
+    struct NDPRouterAdvertisementMessageType
+        : public PacketTypeBase,
+          public PacketTypeMixin<NDPRouterAdvertisementMessageType>
+    {
+        typedef PacketTypeMixin<NDPRouterAdvertisementMessageType> mixin;
+        typedef ConcretePacket<NDPRouterAdvertisementMessageType> packet;
+        typedef NDPRouterAdvertisementParser parser;
+
+        using mixin::nextPacketRange;
+        using mixin::init;
+        using mixin::initSize;
+
+        static void dump(packet p, std::ostream & os);
+    };
+    typedef ConcretePacket<NDPRouterAdvertisementMessageType> NDPRouterAdvertisementMessage;
+
+    //#############################################################
+    //ICMPv6 Neighbor Solicitation (RFC 4861) Message
+    //#############################################################
+    struct NDPNeighborSolicitationParser : public PacketParserBase
+    {
+#      include SENF_PARSER()
+        SENF_PARSER_BITFIELD  ( reserved, 32, unsigned ); // set to zero by default
+        SENF_PARSER_FIELD     ( target, INet6AddressParser );
+        SENF_PARSER_LIST      ( options, packetSize(), senf::NDPGenericOptionParser );
+        SENF_PARSER_FINALIZE  ( NDPNeighborSolicitationParser );
+
+        SENF_PARSER_INIT() {
+            reserved() = 0;
+        }
+    };
+
+    /** \brief Neighbor Solicitation Message
+
+        \par Packet type (typedef):
+            \ref NDPNeighborSolicitationMessage
+
+        \par Fields:
+            \ref NDPNeighborSolicitationParser
+            \imageMessage html NDPNeighborSolicitationMessage.png
+
+        \ingroup protocolbundle_default
+     */
+    struct NDPNeighborSolicitationMessageType
+        : public PacketTypeBase,
+          public PacketTypeMixin<NDPNeighborSolicitationMessageType>
+    {
+        typedef PacketTypeMixin<NDPNeighborSolicitationMessageType> mixin;
+        typedef ConcretePacket<NDPNeighborSolicitationMessageType> packet;
+        typedef NDPNeighborSolicitationParser parser;
+
+        using mixin::nextPacketRange;
+        using mixin::init;
+        using mixin::initSize;
+
+        static void dump(packet p, std::ostream & os);
+    };
+    typedef ConcretePacket<NDPNeighborSolicitationMessageType> NDPNeighborSolicitationMessage;
+
+    //#############################################################
+    //ICMPv6 Neighbor Advertisement (RFC 4861) Message
+    //#############################################################
+    struct NDPNeighborAdvertisementParser : public PacketParserBase
+    {
+#      include SENF_PARSER()
+        SENF_PARSER_BITFIELD  ( r, 1, bool );
+        SENF_PARSER_BITFIELD  ( s, 1, bool );
+        SENF_PARSER_BITFIELD  ( o, 1, bool );
+        SENF_PARSER_BITFIELD  ( reserved, 29, unsigned ); // set to zero by default
+        SENF_PARSER_FIELD     ( target, INet6AddressParser );
+        SENF_PARSER_LIST      ( options, packetSize(), senf::NDPGenericOptionParser );
+        SENF_PARSER_FINALIZE  ( NDPNeighborAdvertisementParser );
+
+        SENF_PARSER_INIT() {
+            reserved() = 0;
+        }
+    };
+
+    /** \brief Neighbor Advertisement Message
+
+        \par Packet type (typedef):
+            \ref NDPNeighborAdvertisementParser
+
+        \par Fields:
+            \ref NDPNeighborAdvertisementParser
+            \imageMessage html NDPNeighborAdvertisementMessage.png
+
+        \ingroup protocolbundle_default
+     */
+    struct NDPNeighborAdvertisementMessageType
+        : public PacketTypeBase,
+          public PacketTypeMixin<NDPNeighborAdvertisementMessageType>
+    {
+        typedef PacketTypeMixin<NDPNeighborAdvertisementMessageType> mixin;
+        typedef ConcretePacket<NDPNeighborAdvertisementMessageType> packet;
+        typedef NDPNeighborAdvertisementParser parser;
+
+        using mixin::nextPacketRange;
+        using mixin::init;
+        using mixin::initSize;
+
+        static void dump(packet p, std::ostream & os);
+    };
+    typedef ConcretePacket<NDPNeighborAdvertisementMessageType> NDPNeighborAdvertisementMessage;
+
+    //#############################################################
+    //ICMPv6 Redirect (RFC 4861) Message
+    //#############################################################
+    struct  NDPRedirectParser : public PacketParserBase
+    {
+#      include SENF_PARSER()
+        SENF_PARSER_BITFIELD  ( reserved, 32, unsigned ); // set to zero by default
+        SENF_PARSER_FIELD     ( target, INet6AddressParser );
+        SENF_PARSER_FIELD     ( destination, INet6AddressParser );
+        SENF_PARSER_LIST      ( options, packetSize(), senf::NDPGenericOptionParser );
+        SENF_PARSER_FINALIZE  ( NDPRedirectParser );
+
+        SENF_PARSER_INIT() {
+            reserved() = 0;
+
+        }
+    };
+
+    /** \brief Redirect Message
+
+        \par Packet type (typedef):
+            \ref NDPRedirectParser
+
+        \par Fields:
+            \ref NDPRedirectParser
+            \imageMessage html NDPRedirectMessage.png
+
+        \ingroup protocolbundle_default
+     */
+    struct NDPRedirectMessageType
+        : public PacketTypeBase,
+          public PacketTypeMixin<NDPRedirectMessageType>
+    {
+        typedef PacketTypeMixin<NDPRedirectMessageType> mixin;
+        typedef ConcretePacket<NDPRedirectMessageType> packet;
+        typedef NDPRedirectParser parser;
+
+        using mixin::nextPacketRange;
+        using mixin::init;
+        using mixin::initSize;
+
+        static void dump(packet p, std::ostream & os);
+    };
+    typedef ConcretePacket<NDPRedirectMessageType> NDPRedirectMessage;
 }
 
 #endif
diff --git a/senf/Packets/DefaultBundle/NDPMessage.test.cc b/senf/Packets/DefaultBundle/NDPMessage.test.cc
new file mode 100644 (file)
index 0000000..5c99be8
--- /dev/null
@@ -0,0 +1,89 @@
+// $Id: ICMPv6Packet.test.cc 1550 2010-01-26 09:34:24Z tho $
+//
+// Copyright (C) 2010
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Sauer <ssauer@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 ICMPv6Packet unit tests */
+
+// Custom includes
+#include "ICMPv6Packet.hh"
+#include "ICMPv6TypePacket.hh"
+#include "NDPOptions.hh"
+
+#include <senf/Utils/auto_unit_test.hh>
+#include <boost/test/test_tools.hpp>
+
+///////////////////////////////cc.p////////////////////////////////////////
+SENF_AUTO_UNIT_TEST(NDPMessage_create)
+{
+    senf::ICMPv6Packet icmp (senf::ICMPv6Packet::create());
+    icmp->code() = 0;
+
+    senf::NDPNeighborAdvertisementMessage nadm (senf::NDPNeighborAdvertisementMessage::createAfter(icmp));
+    nadm->r() = true;
+    nadm->s() = true;
+    nadm->o() = false;
+    nadm->target() = senf::INet6Address::Loopback;
+
+    senf::NDPNeighborAdvertisementMessage::Parser::options_t::container optC(nadm->options());
+    senf::NDPMTUTLVParser opt(
+            optC.push_back_space().init<senf::NDPMTUTLVParser> ());
+    senf::NDPTargetLLAddressTLVParser opt2(
+            optC.push_back_space().init<senf::NDPTargetLLAddressTLVParser> ());
+    opt.mtu() = 1234u;
+    opt2.target() = senf::MACAddress::Broadcast;
+
+    icmp.finalizeAll();
+
+    BOOST_CHECK_EQUAL(icmp->type(), 0x88 );
+    BOOST_CHECK( icmp.next() );
+    BOOST_CHECK( icmp.next().is<senf::NDPNeighborAdvertisementMessage>() );
+    senf::NDPNeighborAdvertisementMessage rnadm (icmp.next().as<senf::NDPNeighborAdvertisementMessage>());
+
+    BOOST_CHECK_EQUAL( rnadm->r(), true  );
+    BOOST_CHECK_EQUAL( rnadm->s(), true  );
+    BOOST_CHECK_EQUAL( rnadm->o(), false );
+
+    senf::NDPNeighborAdvertisementMessage::Parser::options_t::container roptC(rnadm->options() );
+    senf::NDPNeighborAdvertisementMessage::Parser::options_t::container::iterator listIter (roptC.begin());
+    BOOST_CHECK( listIter->is<senf::NDPMTUTLVParser>() );
+    BOOST_CHECK_EQUAL( listIter->type(), 5u );
+    BOOST_CHECK_EQUAL( listIter->length(), 1u );
+    senf::NDPMTUTLVParser mtuopt (listIter->as<senf::NDPMTUTLVParser>());
+    BOOST_CHECK_EQUAL( mtuopt.mtu(), 1234u );
+    listIter++;
+    BOOST_CHECK( listIter->is<senf::NDPTargetLLAddressTLVParser>() );
+    BOOST_CHECK_EQUAL( listIter->type(), 2u );
+    BOOST_CHECK_EQUAL( listIter->length(), 1u );
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+
+
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// comment-column: 40
+// End:
diff --git a/senf/Packets/DefaultBundle/NDPOptions.cc b/senf/Packets/DefaultBundle/NDPOptions.cc
new file mode 100644 (file)
index 0000000..88a0a36
--- /dev/null
@@ -0,0 +1,75 @@
+// $Id: ICMPv6TypePacket.cc 1450 2009-09-28 09:39:01Z tho $
+//
+// Copyright (C) 2008
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Sauer <ssauer@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.
+
+// Definition of non-inline non-template functions
+
+// Custom includes
+#include <senf/Packets/Packets.hh>
+#include "ICMPv6Packet.hh"
+#include "ICMPv6TypePacket.hh"
+#include "NDPOptions.hh"
+
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace {
+    SENF_PACKET_TLV_REGISTRY_REGISTER( senf::NDPSourceLLAddressTLVParser );
+    SENF_PACKET_TLV_REGISTRY_REGISTER( senf::NDPTargetLLAddressTLVParser );
+    SENF_PACKET_TLV_REGISTRY_REGISTER( senf::NDPPrefixInformationTLVParser );
+    SENF_PACKET_TLV_REGISTRY_REGISTER( senf::NDPMTUTLVParser );
+}
+
+prefix_ void senf::NDPSourceLLAddressTLVParser::dump(std::ostream & os) const
+{
+    os << senf::fieldName("    Source Link-layer Address") << "\n";
+    os << senf::fieldName("      Link-layer Address")      << source() << "\n";
+}
+
+prefix_ void senf::NDPTargetLLAddressTLVParser::dump(std::ostream & os) const
+{
+    os << senf::fieldName("    Target Link-layer Address") << "\n";
+    os << senf::fieldName("      Link-layer Address")      << target() << "\n";
+}
+
+prefix_ void senf::NDPPrefixInformationTLVParser::dump(std::ostream & os) const
+{
+    os << senf::fieldName("    Prefix Information") << "\n";
+    os << senf::fieldName("      Prefix Length")                         << unsigned(prefixLength()) << "\n";
+    os << senf::fieldName("      On-link Flag")                          << unsigned(l()) << "\n";
+    os << senf::fieldName("      Autonomous Address-configuration Flag") << unsigned(a()) << "\n";
+    os << senf::fieldName("      Reserved(6Bit)")                        << unsigned(reserved1()) << "\n";
+    os << senf::fieldName("      Valid Lifetime")                        << unsigned(validLifetime()) << "\n";
+    os << senf::fieldName("      Preferred Lifetime")                    << unsigned(preferredLifetime()) << "\n";
+    os << senf::fieldName("      Reserved(32Bit)")                       << unsigned(reserved2()) << "\n";
+    os << senf::fieldName("      Prefix")                                << prefix() << "\n";
+
+}
+
+prefix_ void senf::NDPMTUTLVParser::dump(std::ostream & os) const
+{
+    os << senf::fieldName("    MTU Information") << "\n";
+    os << senf::fieldName("      MTU")      << unsigned(mtu()) << "\n";
+}
+
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
diff --git a/senf/Packets/DefaultBundle/NDPOptions.hh b/senf/Packets/DefaultBundle/NDPOptions.hh
new file mode 100644 (file)
index 0000000..cefce55
--- /dev/null
@@ -0,0 +1,137 @@
+// $Id: ICMPv6TypePacket.hh 1449 2009-09-25 23:03:48Z g0dil $
+//
+// Copyright (C) 2010
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Stefan Sauer <ssauer@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.
+
+// Definition of non-inline non-template functions
+
+#ifndef HH_SENF_Packets_DefaultBundle_NDPOptions_
+#define HH_SENF_Packets_DefaultBundle_NDPOptions_ 1
+
+// Custom includes
+#include <senf/Packets/Packets.hh>
+#include <senf/Packets/DefaultBundle/EthernetPacket.hh>
+#include <senf/Packets/DefaultBundle/ListOptionTypeParser.hh>
+
+namespace senf {
+    //#############################################################
+    //ICMPv6 Neighbor Discovery (RFC 4861) Options
+    //#############################################################
+    struct NDPOptionParser : public PacketParserBase
+    {
+    public:
+#       include SENF_PARSER()
+        SENF_PARSER_FIELD    ( type, UInt8Parser );
+        SENF_PARSER_FIELD    ( length, UInt8Parser );
+        SENF_PARSER_FINALIZE ( NDPOptionParser );
+
+        typedef GenericTLVParserRegistry<NDPOptionParser> Registry;
+    };
+    typedef GenericTLVParserBase<NDPOptionParser> NDPGenericOptionParser;
+
+    struct NDPSourceLLAddressTLVParser : public NDPOptionParser
+    {
+#      include SENF_PARSER()
+        SENF_PARSER_INHERIT  ( NDPOptionParser );
+        SENF_PARSER_FIELD    ( source, MACAddressParser);
+        SENF_PARSER_FINALIZE ( NDPSourceLLAddressTLVParser);
+
+        SENF_PARSER_INIT() {
+            defaultInit();
+            type() = typeId;
+            length() = 1;
+        }
+        static const type_t::value_type typeId = 0x01;
+        void dump(std::ostream & os) const;
+    };
+
+    struct NDPTargetLLAddressTLVParser : public NDPOptionParser
+    {
+#      include SENF_PARSER()
+        SENF_PARSER_INHERIT  ( NDPOptionParser );
+        SENF_PARSER_FIELD    ( target, MACAddressParser );
+        SENF_PARSER_FINALIZE ( NDPTargetLLAddressTLVParser );
+
+        SENF_PARSER_INIT() {
+            defaultInit();
+            type() = typeId;
+            length() = 1;
+        }
+        static const UInt8Parser::value_type typeId = 0x02;
+        void dump(std::ostream & os) const;
+    };
+
+    struct NDPPrefixInformationTLVParser : public NDPOptionParser
+    {
+#      include SENF_PARSER()
+        SENF_PARSER_INHERIT          ( NDPOptionParser );
+        SENF_PARSER_FIELD            ( prefixLength, UInt8Parser );
+        SENF_PARSER_BITFIELD         ( l, 1, bool );
+        SENF_PARSER_BITFIELD         ( a, 1, bool );
+        SENF_PARSER_PRIVATE_BITFIELD ( reserved1, 6, unsigned );
+        SENF_PARSER_FIELD            ( validLifetime, UInt32Parser );
+        SENF_PARSER_FIELD            ( preferredLifetime, UInt32Parser );
+        SENF_PARSER_PRIVATE_BITFIELD ( reserved2, 32, unsigned );
+        SENF_PARSER_FIELD            ( prefix, INet6AddressParser );
+        SENF_PARSER_FINALIZE         ( NDPPrefixInformationTLVParser );
+
+        SENF_PARSER_INIT() {
+            defaultInit();
+            type() = typeId;
+            length() = 4;
+            reserved1() = 0;
+            reserved2() = 0;
+        }
+        static const UInt8Parser::value_type typeId = 0x03;
+        void dump(std::ostream & os) const;
+    };
+
+    struct NDPMTUTLVParser : public NDPOptionParser
+    {
+#      include SENF_PARSER()
+        SENF_PARSER_INHERIT          ( NDPOptionParser );
+        SENF_PARSER_PRIVATE_BITFIELD ( reserved, 16, unsigned );
+        SENF_PARSER_FIELD            ( mtu, UInt32Parser );
+        SENF_PARSER_FINALIZE         ( NDPMTUTLVParser );
+
+        SENF_PARSER_INIT() {
+            defaultInit();
+            type() = typeId;
+            length() = 1;
+            reserved() = 0;
+        }
+        static const UInt8Parser::value_type typeId = 0x05;
+        void dump(std::ostream & os) const;
+    };
+}
+
+#endif
+
+
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// comment-column: 40
+// End:
+