Skip to content
Snippets Groups Projects
Commit dceb083f authored by g0dil's avatar g0dil
Browse files

Add additional IpTypes for Ip-in-IP etc.

Implemented IPv6 fragment extension
Add output streaming (operator<<) for ParseInt parsers
parent 108742cb
No related branches found
No related tags found
No related merge requests found
...@@ -36,7 +36,10 @@ ...@@ -36,7 +36,10 @@
namespace { namespace {
senf::PacketRegistry<senf::EtherTypes>::RegistrationProxy<senf::IpV4Packet> 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() prefix_ void senf::IpV4Packet::v_nextInterpreter()
......
// 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"
// Local Variables:
// mode: c++
// fill-column: 100
// c-file-style: "senf"
// ispell-local-dictionary: "american"
// End:
// 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_
// Local Variables:
// mode: c++
// fill-column: 100
// c-file-style: "senf"
// ispell-local-dictionary: "american"
// End:
// 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
// Local Variables:
// mode: c++
// fill-column: 100
// c-file-style: "senf"
// ispell-local-dictionary: "american"
// End:
// 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_
// Local Variables:
// mode: c++
// fill-column: 100
// c-file-style: "senf"
// ispell-local-dictionary: "american"
// End:
...@@ -34,7 +34,13 @@ ...@@ -34,7 +34,13 @@
namespace { namespace {
senf::PacketRegistry<senf::EtherTypes>::RegistrationProxy<senf::IpV6Packet> 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() prefix_ void senf::IpV6Packet::v_nextInterpreter()
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
namespace senf { namespace senf {
// See RFC2460
template <class Iterator=nil, class IpV6Packet=nil> template <class Iterator=nil, class IpV6Packet=nil>
struct Parse_IpV6 : public ParserBase<Iterator,IpV6Packet> struct Parse_IpV6 : public ParserBase<Iterator,IpV6Packet>
{ {
......
...@@ -46,7 +46,7 @@ BOOST_AUTO_UNIT_TEST(ipV6Packet_parser) ...@@ -46,7 +46,7 @@ BOOST_AUTO_UNIT_TEST(ipV6Packet_parser)
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f }; 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f };
typedef unsigned char * iterator; 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.version()), 0x06u );
BOOST_CHECK_EQUAL( unsigned(p.trafficClass()), 0x01u ); BOOST_CHECK_EQUAL( unsigned(p.trafficClass()), 0x01u );
...@@ -60,6 +60,34 @@ BOOST_AUTO_UNIT_TEST(ipV6Packet_parser) ...@@ -60,6 +60,34 @@ BOOST_AUTO_UNIT_TEST(ipV6Packet_parser)
"2021:2223:2425:2627:2829:2a2b:2c2d:2e2f" ); "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//////////////////////////////////////// ///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_ #undef prefix_
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#define HH_ParseInt_ 1 #define HH_ParseInt_ 1
// Custom includes // Custom includes
#include <iostream>
#include "ParserBase.hh" #include "ParserBase.hh"
#include <boost/cstdint.hpp> #include <boost/cstdint.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
...@@ -58,6 +59,9 @@ namespace senf { ...@@ -58,6 +59,9 @@ namespace senf {
void value(value_type v) { this->i()[0] = v; } void value(value_type v) { this->i()[0] = v; }
Parse_Int8 const & operator= (value_type other) { value(other); return *this; } 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> template <class Iterator=nil, class IPacket=nil>
struct Parse_UInt8 struct Parse_UInt8
...@@ -81,6 +85,9 @@ namespace senf { ...@@ -81,6 +85,9 @@ namespace senf {
void value(value_type v) { this->i()[0] = v; } void value(value_type v) { this->i()[0] = v; }
Parse_UInt8 const & operator= (value_type other) { value(other); return *this; } 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> template <class Iterator=nil, class IPacket=nil>
struct Parse_Int16 struct Parse_Int16
...@@ -104,6 +111,9 @@ namespace senf { ...@@ -104,6 +111,9 @@ namespace senf {
void value(value_type v) { impl::write_uint16(this->i(),v); } void value(value_type v) { impl::write_uint16(this->i(),v); }
Parse_Int16 const & operator= (value_type other) { value(other); return *this; } 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> template <class Iterator=nil, class IPacket=nil>
struct Parse_UInt16 struct Parse_UInt16
...@@ -127,6 +137,9 @@ namespace senf { ...@@ -127,6 +137,9 @@ namespace senf {
void value(value_type v) { impl::write_uint16(this->i(),v); } void value(value_type v) { impl::write_uint16(this->i(),v); }
Parse_UInt16 const & operator= (value_type other) { value(other); return *this; } 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> template <class Iterator=nil, class IPacket=nil>
struct Parse_Int24 struct Parse_Int24
...@@ -151,6 +164,9 @@ namespace senf { ...@@ -151,6 +164,9 @@ namespace senf {
void value(value_type v) { impl::write_uint24(this->i(),v); } void value(value_type v) { impl::write_uint24(this->i(),v); }
Parse_Int24 const & operator= (value_type other) { value(other); return *this; } 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> template <class Iterator=nil, class IPacket=nil>
struct Parse_UInt24 struct Parse_UInt24
...@@ -174,6 +190,9 @@ namespace senf { ...@@ -174,6 +190,9 @@ namespace senf {
void value(value_type v) { impl::write_uint24(this->i(),v); } void value(value_type v) { impl::write_uint24(this->i(),v); }
Parse_UInt24 const & operator= (value_type other) { value(other); return *this; } 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> template <class Iterator=nil, class IPacket=nil>
struct Parse_Int32 struct Parse_Int32
...@@ -197,6 +216,9 @@ namespace senf { ...@@ -197,6 +216,9 @@ namespace senf {
void value(value_type v) { impl::write_uint32(this->i(),v); } void value(value_type v) { impl::write_uint32(this->i(),v); }
Parse_Int32 const & operator= (value_type other) { value(other); return *this; } 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> template <class Iterator=nil, class IPacket=nil>
struct Parse_UInt32 struct Parse_UInt32
...@@ -220,6 +242,9 @@ namespace senf { ...@@ -220,6 +242,9 @@ namespace senf {
void value(value_type v) { impl::write_uint32(this->i(),v); } void value(value_type v) { impl::write_uint32(this->i(),v); }
Parse_UInt32 const & operator= (value_type other) { value(other); return *this; } 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> template <unsigned start, unsigned end, class Iterator=nil, class IPacket=nil>
struct Parse_IntField struct Parse_IntField
...@@ -251,6 +276,9 @@ namespace senf { ...@@ -251,6 +276,9 @@ namespace senf {
BOOST_STATIC_ASSERT( start<end ); BOOST_STATIC_ASSERT( start<end );
BOOST_STATIC_ASSERT( end-start<=32 ); 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> template <unsigned start, unsigned end, class Iterator=nil, class IPacket=nil>
struct Parse_UIntField struct Parse_UIntField
...@@ -278,6 +306,9 @@ namespace senf { ...@@ -278,6 +306,9 @@ namespace senf {
BOOST_STATIC_ASSERT( start<end ); BOOST_STATIC_ASSERT( start<end );
BOOST_STATIC_ASSERT( end-start<=32 ); 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> template <unsigned bit, class Iterator=nil, class IPacket=nil>
struct Parse_Flag struct Parse_Flag
...@@ -304,6 +335,9 @@ namespace senf { ...@@ -304,6 +335,9 @@ namespace senf {
} }
Parse_Flag const & operator= (value_type other) { value(other); return *this; } 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; }
} }
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
namespace { namespace {
senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::UDPPacket> senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::UDPPacket>
registerUDPPacket(17); registerUDPPacket (17);
} }
prefix_ void senf::UDPPacket::v_nextInterpreter() prefix_ void senf::UDPPacket::v_nextInterpreter()
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
namespace senf { namespace senf {
// See RFC768
template <class Iterator=nil, class IPacket=nil> template <class Iterator=nil, class IPacket=nil>
struct Parse_UDP : public ParserBase<Iterator,IPacket> struct Parse_UDP : public ParserBase<Iterator,IPacket>
{ {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment