// Fraunhofer Institute for Open Communication Systems (FOKUS)
// Competence Center NETwork research (NET), St. Augustin, GERMANY
// Stefan Bund <g0dil@berlios.de>
-//
+// Philipp Batroff <philipp.batroff@fokus.fraunhofer.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
namespace {
senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::IPv6Extension_Fragment>
registerIPv6ExtensionType_Fragment (44);
+ senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::IPv6Extension_Routing>
+ registerIPv6ExtensionType_Routing (43);
}
prefix_ void senf::IPv6ExtensionType_Fragment::dump(packet p, std::ostream & os)
<< " id : " << std::hex << unsigned(p->id()) << "\n";
}
+prefix_ void senf::IPv6ExtensionType_Routing::dump(packet p, std::ostream & os)
+{
+ os << "Internet protocol Version 6 routing extension:\n"
+ << " next header : " << unsigned (p->nextHeader()) << "\n"
+ << " header length : " << unsigned (p->headerLength()) << "\n"
+ << " routing type : " << unsigned (p->routingType()) << "\n"
+ << " segments left : " << unsigned (p->segmentsLeft()) << "\n";
+ IPv6Extension_Routing::Parser::hopAddresses_t::container hopAddresses (p->hopAddresses());
+ os << " further Hop Addresses : \n";
+ if ( p->segmentsLeft() != 0 ){
+ for (IPv6Extension_Routing::Parser::hopAddresses_t::container::iterator i (hopAddresses.begin()); i != hopAddresses.end(); ++i)
+ os << *i << "\n";
+ }
+}
+
+prefix_ void senf::IPv6ExtensionType_HopByHop::dump(packet p, std::ostream & os)
+{
+ os << "Internet protocol Version 6 Hop-By-Hop extension:\n"
+ << " next header : " << unsigned (p->nextHeader()) << "\n"
+ << " header length : " << unsigned (p->headerLength()) << "\n";
+}
+
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "IPv6Extensions.mpp"
// Fraunhofer Institute for Open Communication Systems (FOKUS)
// Competence Center NETwork research (NET), St. Augustin, GERMANY
// Stefan Bund <g0dil@berlios.de>
-//
+// Philipp Batroff <philipp.batroff@fokus.fraunhofer.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
/** \brief IPv6 fragment extension packet typedef */
typedef ConcretePacket<IPv6ExtensionType_Fragment> IPv6Extension_Fragment;
-}
+// =====================================================================================================
+
+ /** \brief Parse in IPv6 routing extension header
+
+ Parser implementing the IPv6 routing Header extension. The fields implemented are:
+ \image html IPv6Extensions_Routing.png
+
+ \see IPv6ExtensionType_Routing \n
+ <a href="http://tools.ietf.org/html/rfc2460">RFC 2460</a>
+ */
+
+//Routing Header Extension (type 0 only)
+ struct IPv6PacketParserExtension_Routing : public PacketParserBase
+ {
+/*
+The Type 0 Routing header has the following format: (RFC 2460)
+
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Next Header | Hdr Ext Len | Routing Type=0| Segments Left |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Reserved |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | |
+ + +
+ | |
+ + Address[1] +
+ | |
+ + +
+ | |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ . . .
+ . . .
+ . . .
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | |
+ + +
+ | |
+ + Address[n] +
+ | |
+ + +
+ | |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+*/
+# include SENF_PARSER()
+
+ SENF_PARSER_FIELD ( nextHeader, UInt8Parser );
+ SENF_PARSER_FIELD ( headerLength, UInt8Parser );
+ SENF_PARSER_FIELD ( routingType, UInt8Parser ); //set to Zero for minimal implementation
+ SENF_PARSER_FIELD_RO ( segmentsLeft, UInt8Parser );
+ SENF_PARSER_FIELD ( reserved, UInt32Parser ); //set to zero by RFC
+ SENF_PARSER_VECTOR ( hopAddresses, segmentsLeft, INet6AddressParser );
+
+ SENF_PARSER_FINALIZE ( IPv6PacketParserExtension_Routing );
+
+ //provisionary, since only type 0 is implemented
+ SENF_PARSER_INIT() {
+ routingType() = 0u;
+ reserved() = 0u;
+ }
+ };
+
+ /** \brief IPv6 routing extension
+
+ \par Packet type (typedef):
+ \ref IPv6Extension_Routing
+
+ \par Fields:
+ \ref IPv6PacketParserExtension_Routing
+
+ \par Associated registries:
+ \ref IpTypes
+
+ \par Finalize action:
+ Set \a nextHeader from type of next packet if found in \ref IpTypes
+
+ \ingroup protocolbundle_default
+ */
+
+ struct IPv6ExtensionType_Routing
+ : public PacketTypeBase,
+ public PacketTypeMixin<IPv6ExtensionType_Routing, IpTypes>
+
+ {
+#ifndef DOXYGEN
+ typedef PacketTypeMixin<IPv6ExtensionType_Routing, IpTypes> mixin;
+#endif
+ /** \brief IPv6 routing extension packet typedef */
+ typedef ConcretePacket<IPv6ExtensionType_Routing> packet;
+ /** \brief typedef to the parser of IPv6 routing extension packet */
+ typedef IPv6PacketParserExtension_Routing parser;
+
+ using mixin::nextPacketRange;
+ using mixin::nextPacketType;
+ using mixin::init;
+ using mixin::initSize;
+
+ static key_t nextPacketKey(packet p)
+ { return p->nextHeader(); }
+ /** \brief Dump given IPv6Extension_Routing in readable form to given output stream */
+ static void dump(packet p, std::ostream & os);
+
+ static void finalize(packet p) {
+ p->nextHeader() << key(p.next(nothrow)); }
+ };
+
+ /** \brief IPv6 routing extension packet typedef */
+ typedef ConcretePacket<IPv6ExtensionType_Routing> IPv6Extension_Routing;
+
+
+// =====================================================================================================
+
+ /** \brief Parse in IPv6 Hop-By-Hop extension header
+
+ Parser implementing the IPv6 routing Header extension. The fields implemented are:
+ \image html IPv6Extensions_HopByHop.png
+
+ \see IPv6ExtensionType_HopByHop \n
+ <a href="http://tools.ietf.org/html/rfc2460">RFC 2460</a>
+ */
+
+// Hop-By-Hop skeleton without Options
+
+ struct IPv6PacketParserExtension_HopByHop : public PacketParserBase {
+# include SENF_PARSER()
+ SENF_PARSER_FIELD ( nextHeader, UInt8Parser );
+ SENF_PARSER_FIELD ( headerLength, UInt8Parser );
+
+ SENF_PARSER_FINALIZE ( IPv6PacketParserExtension_HopByHop );
+ };
+
+ /** \brief IPv6 Hop-By-Hop extension
+
+ \par Packet type (typedef):
+ \ref IPv6Extension_HopByHop
+
+ \par Fields:
+ \ref IPv6PacketParserExtension_HopByHop
+
+ \par Associated registries:
+ \ref IpTypes
+
+ \par Finalize action:
+ Set \a nextHeader from type of next packet if found in \ref IpTypes
+
+ \ingroup protocolbundle_default
+ */
+
+ struct IPv6ExtensionType_HopByHop
+ : public PacketTypeBase,
+ public PacketTypeMixin<IPv6ExtensionType_HopByHop, IpTypes>
+ {
+#ifndef DOXYGEN
+ typedef PacketTypeMixin<IPv6ExtensionType_HopByHop, IpTypes> mixin;
+#endif
+ /** \brief IPv6 Hop-By-Hop extension packet typedef */
+ typedef ConcretePacket<IPv6ExtensionType_HopByHop> packet;
+ /** \brief typedef to the parser of IPv6 Hop-By-Hop extension packet */
+ typedef IPv6PacketParserExtension_HopByHop parser;
+
+ using mixin::nextPacketRange;
+ using mixin::nextPacketType;
+ using mixin::init;
+ using mixin::initSize;
+
+ static key_t nextPacketKey(packet p)
+ { return p->nextHeader(); }
+ /** \brief Dump given IPv6Extension_HopByHop in readable form to given output stream */
+ static void dump(packet p, std::ostream & os);
+
+ static void finalize(packet p) {
+ p->nextHeader() << key(p.next(nothrow)); }
+ };
+
+ /** \brief IPv6 routing Hop-By-Hop packet typedef */
+ typedef ConcretePacket<IPv6ExtensionType_Routing> IPv6Extension_HopByHop;
+
+} //namespace senf
///////////////////////////////hh.e////////////////////////////////////////
#endif
#ifndef SENF_PACKETS_DECL_ONLY
// Fraunhofer Institute for Open Communication Systems (FOKUS)
// Competence Center NETwork research (NET), St. Augustin, GERMANY
// Stefan Bund <g0dil@berlios.de>
-//
+// Philipp Batroff <philipp.batroff@fokus.fraunhofer.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
#include "IPv6Extensions.hh"
#include "IPv6Packet.hh"
#include "UDPPacket.hh"
+#include "ICMPv6Packet.hh"
#include "../../Utils/auto_unit_test.hh"
#include <boost/test/test_tools.hpp>
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
-BOOST_AUTO_UNIT_TEST(ipv6Extension_Fragment_packet)
+BOOST_AUTO_UNIT_TEST(ipv6Extensions)
{
// Just for the fun of it, we test a nice chain: A fragment of a fragmented UDP packet
- unsigned char data[] = {
+ unsigned char Fragment_packetData[] = {
// IP header
0x60, 0x00, 0x00, 0x00, // IP Version, class, flow label
0, 20, // payload length
0x11, 0x12, 0x13, 0x14
};
- senf::IPv6Packet p (senf::IPv6Packet::create(data));
+ senf::IPv6Packet pFragment_packet (senf::IPv6Packet::create(Fragment_packetData));
- BOOST_CHECK_EQUAL( p->version(), 6u );
- BOOST_CHECK_EQUAL( p->length(), 20u );
- BOOST_CHECK_EQUAL( p->nextHeader(), 44u );
- BOOST_CHECK_EQUAL( p->source().value(), senf::INet6Address::from_string("2001::1") );
- BOOST_CHECK_EQUAL( p->destination().value(), senf::INet6Address::from_string("2001::2") );
+ BOOST_CHECK_EQUAL( pFragment_packet->version(), 6u );
+ BOOST_CHECK_EQUAL( pFragment_packet->length(), 20u );
+ BOOST_CHECK_EQUAL( pFragment_packet->nextHeader(), 44u );
+ BOOST_CHECK_EQUAL( pFragment_packet->source().value(), senf::INet6Address::from_string("2001::1") );
+ BOOST_CHECK_EQUAL( pFragment_packet->destination().value(), senf::INet6Address::from_string("2001::2") );
std::ostringstream oss (std::ostringstream::out);
- SENF_CHECK_NO_THROW( p.dump( oss));
+ SENF_CHECK_NO_THROW( pFragment_packet.dump( oss));
+
+ BOOST_CHECK( pFragment_packet.next().is<senf::IPv6Extension_Fragment>() );
- BOOST_CHECK( p.next().is<senf::IPv6Extension_Fragment>() );
+ senf::IPv6Extension_Fragment fFragment_packet (pFragment_packet.next().as<senf::IPv6Extension_Fragment>());
- senf::IPv6Extension_Fragment f (p.next().as<senf::IPv6Extension_Fragment>());
+ BOOST_CHECK_EQUAL( fFragment_packet->nextHeader(), 17u );
+ BOOST_CHECK_EQUAL( fFragment_packet->fragmentOffset(), 160u );
+ BOOST_CHECK_EQUAL( fFragment_packet->id(), 0x01020304u );
+ BOOST_CHECK( fFragment_packet.next().is<senf::UDPPacket>() );
- BOOST_CHECK_EQUAL( f->nextHeader(), 17u );
- BOOST_CHECK_EQUAL( f->fragmentOffset(), 160u );
- BOOST_CHECK_EQUAL( f->id(), 0x01020304u );
- BOOST_CHECK( f.next().is<senf::UDPPacket>() );
+ senf::UDPPacket uFragment_packet (fFragment_packet.next().as<senf::UDPPacket>());
- senf::UDPPacket u (f.next().as<senf::UDPPacket>());
+ BOOST_CHECK_EQUAL( uFragment_packet->source(), 0x1000u );
+ BOOST_CHECK_EQUAL( uFragment_packet->destination(), 0x2000u );
+ BOOST_CHECK_EQUAL( uFragment_packet->length(), 12u );
+ BOOST_CHECK( uFragment_packet.next().is<senf::DataPacket>() );
- BOOST_CHECK_EQUAL( u->source(), 0x1000u );
- BOOST_CHECK_EQUAL( u->destination(), 0x2000u );
- BOOST_CHECK_EQUAL( u->length(), 12u );
- BOOST_CHECK( u.next().is<senf::DataPacket>() );
+ senf::DataPacket dFragment_packet (uFragment_packet.next().as<senf::DataPacket>());
+ senf::PacketData::iterator i (uFragment_packet.next().data().begin());
+ BOOST_CHECK_EQUAL( dFragment_packet.size(), 4u );
+ BOOST_CHECK_EQUAL( dFragment_packet.data()[0], 0x11 );
- senf::DataPacket d (u.next().as<senf::DataPacket>());
- senf::PacketData::iterator i (u.next().data().begin());
- BOOST_CHECK_EQUAL( d.size(), 4u );
- BOOST_CHECK_EQUAL( d.data()[0], 0x11 );
+ //==============================================================================================
+
+ unsigned char Routing_packetData[] = {
+ // IP header
+ 0x60, 0x30, 0x00, 0x00,
+ 0x00, 0x10, //payload Length
+ 0x2b, //next Header (43 = Routing Header)
+ 0xff, //Hop Limit
+ 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x02, 0xff, 0xfe, 0x00, 0x02, 0x00, //Src Addr
+ 0x35, 0x55, 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, 0x77, 0x77, 0x88, 0x88, 0x88, 0x88, //Dest. Addr
+ //Routing Header
+ 0x3a, //nextHeader (58)
+ 0x00, //Length ( 0 )
+ 0x00, //routing type ( 0 )
+ 0x00, //Left Segments ( 0 )
+ 0x00, 0x00, 0x00, 0x00, //reserved
+ //ICMPv6
+ 0x01, //type: 1 (unreachable )
+ 0x00, //code: 0 (route unreachable)
+ 0xa3, 0xd3, //checksum (incorrect in wireshark capture file, should be 0xa3c4)
+ 0x00, 0x00, 0x00, 0x00
+ };
+
+ senf::IPv6Packet pRouting_packet (senf::IPv6Packet::create(Routing_packetData));
+
+ BOOST_CHECK_EQUAL( pRouting_packet->version(), 6u );
+ BOOST_CHECK_EQUAL( pRouting_packet->length(), 16u );
+ BOOST_CHECK_EQUAL( pRouting_packet->nextHeader(), 43u );
+ BOOST_CHECK_EQUAL( pRouting_packet->source().value(), senf::INet6Address::from_string("fe80::201:2ff:fe00:200") );
+ BOOST_CHECK_EQUAL( pRouting_packet->destination().value(), senf::INet6Address::from_string("3555:5555:6666:6666:7777:7777:8888:8888"));
+ SENF_CHECK_NO_THROW( pRouting_packet.dump( oss));
+
+ BOOST_REQUIRE( pRouting_packet.next().is<senf::IPv6Extension_Routing>() );
+
+ senf::IPv6Extension_Routing pRouting_extension (pRouting_packet.next().as<senf::IPv6Extension_Routing>());
+
+ BOOST_CHECK_EQUAL( pRouting_extension->nextHeader(), 58u );
+ BOOST_CHECK_EQUAL( pRouting_extension->headerLength(), 0x00 );
+ BOOST_CHECK_EQUAL( pRouting_extension->routingType(), 0x00 );
+ BOOST_CHECK_EQUAL( pRouting_extension->segmentsLeft(), 0x00);
+
+ BOOST_CHECK_EQUAL( pRouting_extension->reserved(), 0u);
+
+ BOOST_REQUIRE( pRouting_extension.next().is<senf::ICMPv6Packet>() );
+ senf::ICMPv6Packet pICMPv6 (pRouting_extension.next().as<senf::ICMPv6Packet>());
+ BOOST_CHECK_EQUAL( pICMPv6->type(), 1u);
+ BOOST_CHECK_EQUAL( pICMPv6->code(), 0u);
+ BOOST_CHECK_EQUAL( pICMPv6->checksum(), 0xa3d3);
}
///////////////////////////////cc.e////////////////////////////////////////