namespace {
senf::PacketRegistry<senf::EtherTypes>::RegistrationProxy<senf::IpV4Packet>
- registerIpV4Packet(0x0800);
+ registerIpV4Packet (0x0800);
+
+ senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::IpV4Packet>
+ regsiterIpV4Packet2 (4); // IP-in-IP encapsulation
}
prefix_ void senf::IpV4Packet::v_nextInterpreter()
--- /dev/null
+// 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 IpV6Extensions non-inline non-template implementation */
+
+#include "IpV6Extensions.hh"
+//#include "IpV6Extensions.ih"
+
+// Custom includes
+
+//#include "IpV6Extensions.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+namespace {
+ senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::IpV6Extension_Fragment>
+ registerIpV6Extension_Fragment (44);
+}
+
+prefix_ void senf::IpV6Extension_Fragment::v_nextInterpreter()
+ const
+{
+ registerInterpreter(nextHeader(),begin()+bytes(),end());
+}
+
+prefix_ void senf::IpV6Extension_Fragment::v_finalize()
+{}
+
+prefix_ void senf::IpV6Extension_Fragment::v_dump(std::ostream & os)
+ const
+{
+ os << "Internet protocol Version 6 fragment extension:\n"
+ << " next header : " << unsigned(nextHeader()) << "\n"
+ << " fragment offset: " << std::hex << unsigned(fragmentOffset()) << "\n"
+ << " more fragments : " << (moreFragments()?"yes":"no") << "\n"
+ << " id : " << std::hex << unsigned(id()) << "\n";
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "IpV6Extensions.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// ispell-local-dictionary: "american"
+// End:
--- /dev/null
+// 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 IpV6Extensions non-inline template implementation */
+
+//#include "IpV6Extensions.ih"
+
+// Custom includes
+
+#define prefix_
+///////////////////////////////ct.p////////////////////////////////////////
+
+template <class Arg>
+prefix_ senf::IpV6Extension_Fragment::IpV6Extension_Fragment(Arg const & arg)
+ : Packet(arg)
+{}
+
+///////////////////////////////ct.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// ispell-local-dictionary: "american"
+// End:
--- /dev/null
+// 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 IpV6Extensions public header */
+
+#ifndef HH_IpV6Extensions_
+#define HH_IpV6Extensions_ 1
+
+// Custom includes
+#include "IpV6Packet.hh"
+
+//#include "IpV6Extensions.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+
+ // See RFC2460
+ template <class Iterator=nil, class IPacket=nil>
+ struct Parse_IpV6Extension_Fragment
+ : public ParserBase<Iterator,IPacket>
+ {
+ template <class I, class P=nil>
+ struct rebind { typedef Parse_IpV6Extension_Fragment<I,P> parser; };
+ typedef Iterator byte_iterator;
+
+ Parse_IpV6Extension_Fragment() {}
+ Parse_IpV6Extension_Fragment(Iterator const & i) : ParserBase<Iterator,IPacket>(i) {}
+
+ static unsigned bytes() { return 8; }
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ typedef Parse_UInt8 < Iterator > Parse_8bit;
+ typedef Parse_UIntField < 0, 13, Iterator > Parse_Offset;
+ typedef Parse_UIntField < 13, 15, Iterator > Parse_Reserved;
+ typedef Parse_Flag < 15, Iterator > Parse_More;
+ typedef Parse_UInt32 < Iterator > Parse_32bit;
+
+ Parse_8bit nextHeader() const { return Parse_8bit (this->i() ); }
+ Parse_8bit reserved1() const { return Parse_8bit (this->i() + 1 ); }
+ Parse_Offset fragmentOffset() const { return Parse_Offset (this->i() + 2 ); }
+ Parse_Reserved reserved2() const { return Parse_Reserved (this->i() + 2 ); }
+ Parse_More moreFragments() const { return Parse_More (this->i() + 2 ); }
+ Parse_32bit id() const { return Parse_32bit (this->i() + 4 ); }
+ };
+
+ class IpV6Extension_Fragment
+ : public Packet,
+ public Parse_IpV6Extension_Fragment<Packet::iterator, IpV6Extension_Fragment>,
+ public PacketRegistryMixin<IpTypes, IpV6Extension_Fragment>
+ {
+ using PacketRegistryMixin<IpTypes,IpV6Extension_Fragment>::registerInterpreter;
+ public:
+ ///////////////////////////////////////////////////////////////////////////
+ // Types
+
+ typedef ptr_t<IpV6Extension_Fragment>::ptr ptr;
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ private:
+ template <class Arg>
+ IpV6Extension_Fragment(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 "IpV6Extensions.cci"
+#include "IpV6Extensions.ct"
+//#include "IpV6Extensions.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// ispell-local-dictionary: "american"
+// End:
--- /dev/null
+// 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 IpV6Extensions.test unit tests */
+
+//#include "IpV6Extensions.test.hh"
+//#include "IpV6Extensions.test.ih"
+
+// Custom includes
+#include "IpV6Extensions.hh"
+#include "IpV6Packet.hh"
+#include "UDPPacket.hh"
+#include "DataPacket.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(ipv6Extension_Fragment_parser)
+{
+ unsigned char data[] = { 59, 0, 0x10, 0x20,
+ 0x01, 0x02, 0x03, 0x04 };
+
+ typedef unsigned char * iterator;
+ Parse_IpV6Extension_Fragment<iterator> p (data);
+
+ BOOST_CHECK_EQUAL( unsigned(p.nextHeader()), 59u );
+ BOOST_CHECK_EQUAL( unsigned(p.fragmentOffset()), 0x1020u >> 3 );
+ BOOST_CHECK ( ! p.moreFragments() );
+ BOOST_CHECK_EQUAL( unsigned(p.id()), 0x01020304u );
+}
+
+BOOST_AUTO_UNIT_TEST(ipv6Extension_Fragment_packet)
+{
+ // Just for the fun of it, we test a nice chain: A fragment of a fragmented UDP packet
+
+ unsigned char data[] = {
+ // IP header
+ 0x60, 0x00, 0x00, 0x00, // IP Version, class, flow label
+ 0, 20, // payload length
+ 44, // next header (IPv6 Fragment)
+ 32, // hop limit
+ 0x20, 0x01, 0, 0, 0, 0, 0, 0, // source ip = 2001::1
+ 0, 0, 0, 0, 0, 0, 0, 0x01,
+ 0x20, 0x01, 0, 0, 0, 0, 0, 0, // destination ip = 2001::2
+ 0, 0, 0, 0, 0, 0, 0, 0x02,
+ // IPv6 Fragment header
+ 17, // next header (UDP)
+ 0, // reserved
+ 0x05, 0x00, // fragment offset, last fragment
+ 0x01, 0x02, 0x03, 0x04, // id
+ // UDP header
+ 0x10, 0x00, // source port
+ 0x20, 0x00, // destination port
+ 0, 12, // length
+ 0x00, 0x00, // CRC (no, I won't calculate this one ...)
+ // Payload data
+ 0x11, 0x12, 0x13, 0x14
+ };
+
+ IpV6Packet::ptr p (Packet::create<IpV6Packet>(data, data + sizeof(data)));
+
+ BOOST_CHECK_EQUAL( p->version(), 6u );
+ BOOST_CHECK_EQUAL( p->length(), 20u );
+ BOOST_CHECK_EQUAL( p->nextHeader(), 44u );
+ BOOST_CHECK_EQUAL( INet6Address(p->source().range()), "2001::1" );
+ BOOST_CHECK_EQUAL( INet6Address(p->destination().range()), "2001::2" );
+ BOOST_CHECK( p->next()->is<IpV6Extension_Fragment>() );
+
+ IpV6Extension_Fragment::ptr f (p->next()->as<IpV6Extension_Fragment>());
+
+ BOOST_CHECK_EQUAL( f->nextHeader(), 17u );
+ BOOST_CHECK_EQUAL( f->fragmentOffset(), 160u );
+ BOOST_CHECK_EQUAL( f->id(), 0x01020304u );
+ BOOST_CHECK( f->next()->is<UDPPacket>() );
+
+ UDPPacket::ptr u (f->next()->as<UDPPacket>());
+
+ BOOST_CHECK_EQUAL( u->source(), 0x1000u );
+ BOOST_CHECK_EQUAL( u->destination(), 0x2000u );
+ BOOST_CHECK_EQUAL( u->length(), 12u );
+ BOOST_CHECK( u->next()->is<DataPacket>() );
+
+ Packet::iterator i (u->next()->begin());
+ BOOST_CHECK_EQUAL( Parse_UInt32<Packet::iterator>(i).value(), 0x11121314u );
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// c-file-style: "senf"
+// ispell-local-dictionary: "american"
+// End:
namespace {
senf::PacketRegistry<senf::EtherTypes>::RegistrationProxy<senf::IpV6Packet>
- registerIpV6Packet(0x86dd);
+ registerIpV6Packet (0x86dd);
+
+ senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::IpV6Packet>
+ registerIpV6Packet2 (41); // IP6-in-IP(6) encapsulation
+
+ senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::DataPacket>
+ registerNoNextHeader (59);
}
prefix_ void senf::IpV6Packet::v_nextInterpreter()
namespace senf {
+ // See RFC2460
template <class Iterator=nil, class IpV6Packet=nil>
struct Parse_IpV6 : public ParserBase<Iterator,IpV6Packet>
{
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f };
typedef unsigned char * iterator;
- Parse_IpV6<iterator> p(data);
+ Parse_IpV6<iterator> p (data);
BOOST_CHECK_EQUAL( unsigned(p.version()), 0x06u );
BOOST_CHECK_EQUAL( unsigned(p.trafficClass()), 0x01u );
"2021:2223:2425:2627:2829:2a2b:2c2d:2e2f" );
}
+BOOST_AUTO_UNIT_TEST(ipV6Packet_packet)
+{
+ 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 };
+
+ IpV6Packet::ptr p (Packet::create<IpV6Packet>(data, data+sizeof(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" );
+
+ BOOST_CHECK( p->next() );
+ BOOST_CHECK( p->next()->is<DataPacket>() );
+ BOOST_CHECK_EQUAL( p->next()->size(), 0u );
+}
+
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
#define HH_ParseInt_ 1
// Custom includes
+#include <iostream>
#include "ParserBase.hh"
#include <boost/cstdint.hpp>
#include <boost/static_assert.hpp>
void value(value_type v) { this->i()[0] = v; }
Parse_Int8 const & operator= (value_type other) { value(other); return *this; }
};
+ template <class Iterator, class IPacket>
+ std::ostream & operator<<(std::ostream & os, Parse_Int8<Iterator,IPacket> const & i)
+ { os << i.value(); return os; }
template <class Iterator=nil, class IPacket=nil>
struct Parse_UInt8
void value(value_type v) { this->i()[0] = v; }
Parse_UInt8 const & operator= (value_type other) { value(other); return *this; }
};
+ template <class Iterator, class IPacket>
+ std::ostream & operator<<(std::ostream & os, Parse_UInt8<Iterator,IPacket> const & i)
+ { os << i.value(); return os; }
template <class Iterator=nil, class IPacket=nil>
struct Parse_Int16
void value(value_type v) { impl::write_uint16(this->i(),v); }
Parse_Int16 const & operator= (value_type other) { value(other); return *this; }
};
+ template <class Iterator, class IPacket>
+ std::ostream & operator<<(std::ostream & os, Parse_Int16<Iterator,IPacket> const & i)
+ { os << i.value(); return os; }
template <class Iterator=nil, class IPacket=nil>
struct Parse_UInt16
void value(value_type v) { impl::write_uint16(this->i(),v); }
Parse_UInt16 const & operator= (value_type other) { value(other); return *this; }
};
+ template <class Iterator, class IPacket>
+ std::ostream & operator<<(std::ostream & os, Parse_UInt16<Iterator,IPacket> const & i)
+ { os << i.value(); return os; }
template <class Iterator=nil, class IPacket=nil>
struct Parse_Int24
void value(value_type v) { impl::write_uint24(this->i(),v); }
Parse_Int24 const & operator= (value_type other) { value(other); return *this; }
};
+ template <class Iterator, class IPacket>
+ std::ostream & operator<<(std::ostream & os, Parse_Int24<Iterator,IPacket> const & i)
+ { os << i.value(); return os; }
template <class Iterator=nil, class IPacket=nil>
struct Parse_UInt24
void value(value_type v) { impl::write_uint24(this->i(),v); }
Parse_UInt24 const & operator= (value_type other) { value(other); return *this; }
};
+ template <class Iterator, class IPacket>
+ std::ostream & operator<<(std::ostream & os, Parse_UInt24<Iterator,IPacket> const & i)
+ { os << i.value(); return os; }
template <class Iterator=nil, class IPacket=nil>
struct Parse_Int32
void value(value_type v) { impl::write_uint32(this->i(),v); }
Parse_Int32 const & operator= (value_type other) { value(other); return *this; }
};
+ template <class Iterator, class IPacket>
+ std::ostream & operator<<(std::ostream & os, Parse_Int32<Iterator,IPacket> const & i)
+ { os << i.value(); return os; }
template <class Iterator=nil, class IPacket=nil>
struct Parse_UInt32
void value(value_type v) { impl::write_uint32(this->i(),v); }
Parse_UInt32 const & operator= (value_type other) { value(other); return *this; }
};
+ template <class Iterator, class IPacket>
+ std::ostream & operator<<(std::ostream & os, Parse_UInt32<Iterator,IPacket> const & i)
+ { os << i.value(); return os; }
template <unsigned start, unsigned end, class Iterator=nil, class IPacket=nil>
struct Parse_IntField
BOOST_STATIC_ASSERT( start<end );
BOOST_STATIC_ASSERT( end-start<=32 );
};
+ template <unsigned start, unsigned end, class Iterator, class IPacket>
+ std::ostream & operator<<(std::ostream & os, Parse_IntField<start,end,Iterator,IPacket> const & i)
+ { os << i.value(); return os; }
template <unsigned start, unsigned end, class Iterator=nil, class IPacket=nil>
struct Parse_UIntField
BOOST_STATIC_ASSERT( start<end );
BOOST_STATIC_ASSERT( end-start<=32 );
};
+ template <unsigned start, unsigned end, class Iterator, class IPacket>
+ std::ostream & operator<<(std::ostream & os, Parse_UIntField<start,end,Iterator,IPacket> const & i)
+ { os << i.value(); return os; }
template <unsigned bit, class Iterator=nil, class IPacket=nil>
struct Parse_Flag
}
Parse_Flag const & operator= (value_type other) { value(other); return *this; }
};
+ template <unsigned bit, class Iterator, class IPacket>
+ std::ostream & operator<<(std::ostream & os, Parse_Flag<bit,Iterator,IPacket> const & i)
+ { os << i.value(); return os; }
}
namespace {
senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::UDPPacket>
- registerUDPPacket(17);
+ registerUDPPacket (17);
}
prefix_ void senf::UDPPacket::v_nextInterpreter()
namespace senf {
+ // See RFC768
template <class Iterator=nil, class IPacket=nil>
struct Parse_UDP : public ParserBase<Iterator,IPacket>
{