--- /dev/null
+// Copyright (c) 2003-2010 Christopher M. Kohlhoff
+// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#include "icmp/icmpv6header.h"
+
+#include "icmp/icmpdestinationunreachablemessage.h"
+#include "icmp/icmpechoreplymessage.h"
+#include "icmp/icmpechorequestmessage.h"
+#include "icmp/icmpgenericmessage.h"
+
+using namespace std;
+using boost::shared_ptr;
+
+//-----------------------------------------------------------------------------
+// Icmpv6Header
+//-----------------------------------------------------------------------------
+
+Icmpv6Header::Icmpv6Header() :
+ MessageFormat()
+{
+}
+
+Icmpv6Header::Icmpv6Header(
+ Icmpv6Type type,
+ uint8_t code,
+ uint16_t checksum,
+ uint16_t identifier,
+ uint16_t sequence_number
+) :
+ MessageFormat()
+{
+ set_icmp_message_format( type );
+
+ set_type( type );
+ set_code( code );
+ set_checksum( checksum );
+ set_identifier( identifier );
+ set_sequence_number( sequence_number );
+}
+
+Icmpv6Type Icmpv6Header::get_type() const
+{
+ return get_icmp_message_format()->get_type_v6();
+}
+
+void Icmpv6Header::set_type( Icmpv6Type type )
+{
+ get_icmp_message_format()->set_type_v6( type );
+}
+
+uint8_t Icmpv6Header::get_code() const
+{
+ return get_icmp_message_format()->get_code();
+}
+
+void Icmpv6Header::set_code( uint8_t code )
+{
+ get_icmp_message_format()->set_code( code );
+}
+
+uint16_t Icmpv6Header::get_checksum() const
+{
+ return get_icmp_message_format()->get_checksum();
+}
+
+void Icmpv6Header::set_checksum( uint16_t checksum )
+{
+ get_icmp_message_format()->set_checksum( checksum );
+}
+
+uint16_t Icmpv6Header::get_identifier() const
+{
+ return get_icmp_message_format()->get_identifier();
+}
+
+void Icmpv6Header::set_identifier( uint16_t identifier )
+{
+ get_icmp_message_format()->set_identifier( identifier );
+}
+
+uint16_t Icmpv6Header::get_sequence_number() const
+{
+ return get_icmp_message_format()->get_sequence_number();
+}
+
+void Icmpv6Header::set_sequence_number( uint16_t sequence_number )
+{
+ get_icmp_message_format()->set_sequence_number( sequence_number );
+}
+
+shared_ptr<IcmpMessage> Icmpv6Header::get_icmp_message_format() const
+{
+ BOOST_ASSERT( MessageFormat.get() != NULL );
+
+ return MessageFormat;
+}
+
+void Icmpv6Header::set_icmp_message_format( const Icmpv6Type type )
+{
+ BOOST_ASSERT( MessageFormat.get() == NULL );
+
+ if ( MessageFormat.get() == NULL )
+ {
+ switch ( type )
+ {
+ case Icmpv6Type_EchoReply:
+ MessageFormat.reset( new IcmpEchoReplyMessage );
+ break;
+ case Icmpv6Type_EchoRequest:
+ MessageFormat.reset( new IcmpEchoRequestMessage );
+ break;
+ case Icmpv6Type_DestinationUnreachable:
+ MessageFormat.reset(
+ new IcmpDestinationUnreachableMessage
+ );
+ break;
+ case Icmpv6Type_PacketTooBig:
+ case Icmpv6Type_TimeExceeded:
+ case Icmpv6Type_ParameterProblem:
+ case Icmpv6Type_RouterSolicitation:
+ case Icmpv6Type_RouterAdvertisement:
+ case Icmpv6Type_NeighborSolicitation:
+ case Icmpv6Type_NeighborAdvertisement:
+ case Icmpv6Type_RedirectMessage:
+ case Icmpv6Type_RouterRenumbering:
+ case Icmpv6Type_ICMPNodeInformationQuery:
+ case Icmpv6Type_ICMPNodeInformationResponse:
+ case Icmpv6Type_InverseNeighborDiscoverySolicitationMessage:
+ case Icmpv6Type_InverseNeighborDiscoveryAdvertisementMessage:
+ case Icmpv6Type_MulticastListenerDiscovery:
+ case Icmpv6Type_HomeAgentAddressDiscoveryRequestMessage:
+ case Icmpv6Type_HomeAgentAddressDiscoveryReplyMessage:
+ case Icmpv6Type_MobilePrefixSolicitation:
+ case Icmpv6Type_MobilePrefixAdvertisement:
+ case Icmpv6Type_CertificationPathSolicitation:
+ case Icmpv6Type_CertificationPathAdvertisement:
+ case Icmpv6Type_MulticastRouterAdvertisement:
+ case Icmpv6Type_MulticastRouterSolicitation:
+ case Icmpv6Type_MulticastRouterTermination:
+ case Icmpv6Type_Generic:
+ MessageFormat.reset( new IcmpGenericMessage );
+ break;
+ case Icmpv6Type_InvalidLast:
+ default:
+ BOOST_ASSERT( false );
+ break;
+ }
+
+ MessageFormat->init( type );
+ }
+
+ BOOST_ASSERT( MessageFormat.get() != NULL );
+ BOOST_ASSERT( MessageFormat->get_type_v6() != Icmpv6Type_InvalidLast );
+}
+
+void Icmpv6Header::set_icmp_message_format( std::istream &is )
+{
+ // read the first byte, which contains the type of the ICMP message
+ uint8_t first_byte = 0;
+ (void) is.read( reinterpret_cast<char *>(&first_byte), 1 );
+
+ // must keep the stream intact, so place the read byte back
+ (void) is.putback( first_byte );
+
+ // now select the message format for the given type
+ Icmpv6Type header_type = static_cast<Icmpv6Type>( first_byte );
+ set_icmp_message_format( header_type );
+}
+
+std::istream& operator>>(
+ std::istream &is,
+ Icmpv6Header &header
+)
+{
+ // select the message format which will parse the fields
+ header.set_icmp_message_format( is );
+
+ // delegate the parsing of the fields to a specialized decoder
+ return header.get_icmp_message_format()->read( is );
+}
+
+std::ostream& operator<<(
+ std::ostream &os,
+ const Icmpv6Header &header
+)
+{
+ // delegate the writing of the fields to a specialized encoder
+ return header.get_icmp_message_format()->write( os );
+}
--- /dev/null
+// Copyright (c) 2003-2010 Christopher M. Kohlhoff
+// Modifications (c) 2011 by Guilherme Maciel Ferreira / Intra2net AG
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#ifndef ICMPV6_HEADER_H
+#define ICMPV6_HEADER_H
+
+#include <stdint.h>
+
+#include <istream>
+#include <ostream>
+
+#include <boost/shared_ptr.hpp>
+
+#include "icmp/icmpmessage.h"
+#include "icmp/icmptype.h"
+
+//-----------------------------------------------------------------------------
+// Icmpv6Header
+//-----------------------------------------------------------------------------
+
+/**
+ * @brief This class represents the ICMP version 6 Header.
+ *
+ * The ICMP Generic Header Format is:
+ *
+ * @code
+ * 0 8 16 31
+ * +---------------+---------------+------------------------------+ ---
+ * | | | | ^
+ * | type | code | checksum | 4 bytes
+ * | | | | v
+ * +---------------+---------------+------------------------------+ ---
+ * | |
+ * | specific to each message |
+ * | |
+ * +-------------------------------+------------------------------+
+ * @endcode
+ */
+class Icmpv6Header
+{
+public:
+ Icmpv6Header();
+ Icmpv6Header(
+ Icmpv6Type type,
+ uint8_t code,
+ uint16_t checksum,
+ uint16_t identifier,
+ uint16_t sequence_number
+ );
+
+ Icmpv6Type get_type() const;
+ void set_type( const Icmpv6Type type );
+
+ uint8_t get_code() const;
+ void set_code( const uint8_t code );
+
+ uint16_t get_checksum() const;
+ void set_checksum( const uint16_t checksum );
+
+ uint16_t get_identifier() const;
+ void set_identifier( const uint16_t identifier );
+
+ uint16_t get_sequence_number() const;
+ void set_sequence_number( const uint16_t sequence_number );
+
+ boost::shared_ptr<IcmpMessage> get_icmp_message_format() const;
+ void set_icmp_message_format( const Icmpv6Type type );
+ void set_icmp_message_format( std::istream &is );
+
+ friend std::istream& operator>>(
+ std::istream &is,
+ Icmpv6Header &header
+ );
+ friend std::ostream& operator<<(
+ std::ostream &os,
+ const Icmpv6Header &header
+ );
+
+private:
+ /// Changeable pointer to different ICMP messages types.
+ boost::shared_ptr<IcmpMessage> MessageFormat;
+
+};
+
+#endif // ICMPV6_HEADER_H