From: g0dil Date: Tue, 20 Feb 2007 08:59:31 +0000 (+0000) Subject: Add additional IpTypes for Ip-in-IP etc. X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=5d62f84a80b2c72cc0aa5cabc3ddad752e87fcc8;hp=33157146abaca548e145c577a0840cd1bd427789;p=senf.git Add additional IpTypes for Ip-in-IP etc. Implemented IPv6 fragment extension Add output streaming (operator<<) for ParseInt parsers git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@203 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Packets/IpV4Packet.cc b/Packets/IpV4Packet.cc index fd04025..46b925c 100644 --- a/Packets/IpV4Packet.cc +++ b/Packets/IpV4Packet.cc @@ -36,7 +36,10 @@ namespace { senf::PacketRegistry::RegistrationProxy - registerIpV4Packet(0x0800); + registerIpV4Packet (0x0800); + + senf::PacketRegistry::RegistrationProxy + regsiterIpV4Packet2 (4); // IP-in-IP encapsulation } prefix_ void senf::IpV4Packet::v_nextInterpreter() diff --git a/Packets/IpV6Extensions.cc b/Packets/IpV6Extensions.cc new file mode 100644 index 0000000..30f4dd4 --- /dev/null +++ b/Packets/IpV6Extensions.cc @@ -0,0 +1,67 @@ +// Copyright (C) 2007 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund +// +// 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::RegistrationProxy + 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" + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// c-file-style: "senf" +// ispell-local-dictionary: "american" +// End: diff --git a/Packets/IpV6Extensions.ct b/Packets/IpV6Extensions.ct new file mode 100644 index 0000000..1f0873e --- /dev/null +++ b/Packets/IpV6Extensions.ct @@ -0,0 +1,45 @@ +// Copyright (C) 2007 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund +// +// 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 +prefix_ senf::IpV6Extension_Fragment::IpV6Extension_Fragment(Arg const & arg) + : Packet(arg) +{} + +///////////////////////////////ct.e//////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// c-file-style: "senf" +// ispell-local-dictionary: "american" +// End: diff --git a/Packets/IpV6Extensions.hh b/Packets/IpV6Extensions.hh new file mode 100644 index 0000000..cc6581a --- /dev/null +++ b/Packets/IpV6Extensions.hh @@ -0,0 +1,103 @@ +// Copyright (C) 2007 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund +// +// 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 + struct Parse_IpV6Extension_Fragment + : public ParserBase + { + template + struct rebind { typedef Parse_IpV6Extension_Fragment parser; }; + typedef Iterator byte_iterator; + + Parse_IpV6Extension_Fragment() {} + Parse_IpV6Extension_Fragment(Iterator const & i) : ParserBase(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, + public PacketRegistryMixin + { + using PacketRegistryMixin::registerInterpreter; + public: + /////////////////////////////////////////////////////////////////////////// + // Types + + typedef ptr_t::ptr ptr; + + /////////////////////////////////////////////////////////////////////////// + + private: + template + 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 + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// c-file-style: "senf" +// ispell-local-dictionary: "american" +// End: diff --git a/Packets/IpV6Extensions.test.cc b/Packets/IpV6Extensions.test.cc new file mode 100644 index 0000000..1d56ee2 --- /dev/null +++ b/Packets/IpV6Extensions.test.cc @@ -0,0 +1,120 @@ +// Copyright (C) 2007 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund +// +// 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 +#include + +#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 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(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::ptr f (p->next()->as()); + + BOOST_CHECK_EQUAL( f->nextHeader(), 17u ); + BOOST_CHECK_EQUAL( f->fragmentOffset(), 160u ); + BOOST_CHECK_EQUAL( f->id(), 0x01020304u ); + BOOST_CHECK( f->next()->is() ); + + UDPPacket::ptr u (f->next()->as()); + + BOOST_CHECK_EQUAL( u->source(), 0x1000u ); + BOOST_CHECK_EQUAL( u->destination(), 0x2000u ); + BOOST_CHECK_EQUAL( u->length(), 12u ); + BOOST_CHECK( u->next()->is() ); + + Packet::iterator i (u->next()->begin()); + BOOST_CHECK_EQUAL( Parse_UInt32(i).value(), 0x11121314u ); +} + +///////////////////////////////cc.e//////////////////////////////////////// +#undef prefix_ + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// c-file-style: "senf" +// ispell-local-dictionary: "american" +// End: diff --git a/Packets/IpV6Packet.cc b/Packets/IpV6Packet.cc index b511d02..ba2f389 100644 --- a/Packets/IpV6Packet.cc +++ b/Packets/IpV6Packet.cc @@ -34,7 +34,13 @@ namespace { senf::PacketRegistry::RegistrationProxy - registerIpV6Packet(0x86dd); + registerIpV6Packet (0x86dd); + + senf::PacketRegistry::RegistrationProxy + registerIpV6Packet2 (41); // IP6-in-IP(6) encapsulation + + senf::PacketRegistry::RegistrationProxy + registerNoNextHeader (59); } prefix_ void senf::IpV6Packet::v_nextInterpreter() diff --git a/Packets/IpV6Packet.hh b/Packets/IpV6Packet.hh index 99d2476..693d260 100644 --- a/Packets/IpV6Packet.hh +++ b/Packets/IpV6Packet.hh @@ -36,6 +36,7 @@ namespace senf { + // See RFC2460 template struct Parse_IpV6 : public ParserBase { diff --git a/Packets/IpV6Packet.test.cc b/Packets/IpV6Packet.test.cc index 70008a4..41fdcb2 100644 --- a/Packets/IpV6Packet.test.cc +++ b/Packets/IpV6Packet.test.cc @@ -46,7 +46,7 @@ BOOST_AUTO_UNIT_TEST(ipV6Packet_parser) 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f }; typedef unsigned char * iterator; - Parse_IpV6 p(data); + Parse_IpV6 p (data); BOOST_CHECK_EQUAL( unsigned(p.version()), 0x06u ); BOOST_CHECK_EQUAL( unsigned(p.trafficClass()), 0x01u ); @@ -60,6 +60,34 @@ BOOST_AUTO_UNIT_TEST(ipV6Packet_parser) "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(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() ); + BOOST_CHECK_EQUAL( p->next()->size(), 0u ); +} + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ diff --git a/Packets/ParseInt.hh b/Packets/ParseInt.hh index ba13aaf..3f35b93 100644 --- a/Packets/ParseInt.hh +++ b/Packets/ParseInt.hh @@ -24,6 +24,7 @@ #define HH_ParseInt_ 1 // Custom includes +#include #include "ParserBase.hh" #include #include @@ -58,6 +59,9 @@ namespace senf { void value(value_type v) { this->i()[0] = v; } Parse_Int8 const & operator= (value_type other) { value(other); return *this; } }; + template + std::ostream & operator<<(std::ostream & os, Parse_Int8 const & i) + { os << i.value(); return os; } template struct Parse_UInt8 @@ -81,6 +85,9 @@ namespace senf { void value(value_type v) { this->i()[0] = v; } Parse_UInt8 const & operator= (value_type other) { value(other); return *this; } }; + template + std::ostream & operator<<(std::ostream & os, Parse_UInt8 const & i) + { os << i.value(); return os; } template struct Parse_Int16 @@ -104,6 +111,9 @@ namespace senf { void value(value_type v) { impl::write_uint16(this->i(),v); } Parse_Int16 const & operator= (value_type other) { value(other); return *this; } }; + template + std::ostream & operator<<(std::ostream & os, Parse_Int16 const & i) + { os << i.value(); return os; } template struct Parse_UInt16 @@ -127,6 +137,9 @@ namespace senf { void value(value_type v) { impl::write_uint16(this->i(),v); } Parse_UInt16 const & operator= (value_type other) { value(other); return *this; } }; + template + std::ostream & operator<<(std::ostream & os, Parse_UInt16 const & i) + { os << i.value(); return os; } template struct Parse_Int24 @@ -151,6 +164,9 @@ namespace senf { void value(value_type v) { impl::write_uint24(this->i(),v); } Parse_Int24 const & operator= (value_type other) { value(other); return *this; } }; + template + std::ostream & operator<<(std::ostream & os, Parse_Int24 const & i) + { os << i.value(); return os; } template struct Parse_UInt24 @@ -174,6 +190,9 @@ namespace senf { void value(value_type v) { impl::write_uint24(this->i(),v); } Parse_UInt24 const & operator= (value_type other) { value(other); return *this; } }; + template + std::ostream & operator<<(std::ostream & os, Parse_UInt24 const & i) + { os << i.value(); return os; } template struct Parse_Int32 @@ -197,6 +216,9 @@ namespace senf { void value(value_type v) { impl::write_uint32(this->i(),v); } Parse_Int32 const & operator= (value_type other) { value(other); return *this; } }; + template + std::ostream & operator<<(std::ostream & os, Parse_Int32 const & i) + { os << i.value(); return os; } template struct Parse_UInt32 @@ -220,6 +242,9 @@ namespace senf { void value(value_type v) { impl::write_uint32(this->i(),v); } Parse_UInt32 const & operator= (value_type other) { value(other); return *this; } }; + template + std::ostream & operator<<(std::ostream & os, Parse_UInt32 const & i) + { os << i.value(); return os; } template struct Parse_IntField @@ -251,6 +276,9 @@ namespace senf { BOOST_STATIC_ASSERT( start + std::ostream & operator<<(std::ostream & os, Parse_IntField const & i) + { os << i.value(); return os; } template struct Parse_UIntField @@ -278,6 +306,9 @@ namespace senf { BOOST_STATIC_ASSERT( start + std::ostream & operator<<(std::ostream & os, Parse_UIntField const & i) + { os << i.value(); return os; } template struct Parse_Flag @@ -304,6 +335,9 @@ namespace senf { } Parse_Flag const & operator= (value_type other) { value(other); return *this; } }; + template + std::ostream & operator<<(std::ostream & os, Parse_Flag const & i) + { os << i.value(); return os; } } diff --git a/Packets/UDPPacket.cc b/Packets/UDPPacket.cc index c9c2a22..e3ef329 100644 --- a/Packets/UDPPacket.cc +++ b/Packets/UDPPacket.cc @@ -34,7 +34,7 @@ namespace { senf::PacketRegistry::RegistrationProxy - registerUDPPacket(17); + registerUDPPacket (17); } prefix_ void senf::UDPPacket::v_nextInterpreter() diff --git a/Packets/UDPPacket.hh b/Packets/UDPPacket.hh index e94f9c4..078a424 100644 --- a/Packets/UDPPacket.hh +++ b/Packets/UDPPacket.hh @@ -34,6 +34,7 @@ namespace senf { + // See RFC768 template struct Parse_UDP : public ParserBase {