}
///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_DataPacket_impl_)
+#define HH_DataPacket_impl_
//#include "DataPacket.cci"
//#include "DataPacket.ct"
//#include "DataPacket.cti"
///////////////////////////////cc.p////////////////////////////////////////
namespace {
- senf::PacketRegistry<senf::EtherTypes>::RegistrationProxy<senf::EthVLanPacketType>
+ senf::PacketRegistry<senf::EtherTypes>::RegistrationProxy<senf::EthVLanPacket>
registerEthVLanPacket(0x8100);
}
// Custom includes
#include <algorithm>
#include <boost/array.hpp>
-#include "Packets/PacketType.hh"
-#include "Packets/ParseInt.hh"
-#include "Packets/PacketRegistry.hh"
-#include "Packets/PacketParser.hh"
+#include "Packets/Packets.hh"
//#include "EthernetPacket.mpp"
///////////////////////////////hh.p////////////////////////////////////////
///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#ifndef SENF_PACKETS_DECL_ONLY
//#include "EthernetPacket.cci"
#include "EthernetPacket.ct"
//#include "EthernetPacket.cti"
// Custom includes
#include "EthernetPacket.hh"
-#include "Packets/DataPacket.hh"
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/test_tools.hpp>
///////////////////////////////cc.p////////////////////////////////////////
namespace {
- senf::PacketRegistry<senf::EtherTypes>::RegistrationProxy<senf::IpV4PacketType>
+ senf::PacketRegistry<senf::EtherTypes>::RegistrationProxy<senf::IpV4Packet>
registerIpV4Packet (0x0800);
- senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::IpV4PacketType>
+ senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::IpV4Packet>
regsiterIpV4Packet2 (4); // IP-in-IP encapsulation
}
-// $Id: IpV4Packet.hh 307 2007-07-14 21:31:12Z g0dil $
+// $Id$
//
// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
#define HH_IpV4Packet_ 1
// Custom includes
-#include "Packets/PacketType.hh"
-#include "Packets/ParseInt.hh"
-#include "Packets/PacketRegistry.hh"
-#include "Packets/PacketParser.hh"
+#include "Packets/Packets.hh"
//#include "IpV4Packet.mpp"
///////////////////////////////hh.p////////////////////////////////////////
///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#ifndef SENF_PACKETS_DECL_ONLY
//#include IpV4Packet.cci"
//#include "IpV4Packet.ct"
//#include "IpV4Packet.cti"
///////////////////////////////cc.p////////////////////////////////////////
namespace {
- senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::IpV6ExtensionType_Fragment>
+ senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::IpV6Extension_Fragment>
registerIpV6ExtensionType_Fragment (44);
}
}
///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#ifndef SENF_PACKETS_DECL_ONLY
//#include "IpV6Extensions.cci"
//#include "IpV6Extensions.ct"
//#include "IpV6Extensions.cti"
#include "IpV6Extensions.hh"
#include "IpV6Packet.hh"
#include "UDPPacket.hh"
-#include "Packets/DataPacket.hh"
#include "Socket/INetAddressing.hh"
#include <boost/test/auto_unit_test.hpp>
// Custom includes
#include "EthernetPacket.hh"
-#include "Packets/DataPacket.hh"
#include "Socket/INetAddressing.hh"
//#include "IpV6Packet.mpp"
///////////////////////////////cc.p////////////////////////////////////////
namespace {
- senf::PacketRegistry<senf::EtherTypes>::RegistrationProxy<senf::IpV6PacketType>
+ senf::PacketRegistry<senf::EtherTypes>::RegistrationProxy<senf::IpV6Packet>
registerIpV6Packet (0x86dd);
- senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::IpV6PacketType>
+ senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::IpV6Packet>
registerIpV6Packet2 (41); // IP6-in-IP(6) encapsulation
- senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::DataPacketType>
+ senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::DataPacket>
registerNoNextHeader (59);
}
#define HH_IpV6Packet_ 1
// Custom includes
-#include "Packets/PacketType.hh"
-#include "Packets/ParseInt.hh"
-#include "Packets/PacketRegistry.hh"
-#include "Packets/PacketParser.hh"
-#include "Packets/ParseArray.hh"
+#include "Packets/Packets.hh"
#include "IpV4Packet.hh"
//#include "IpV6Packet.mpp"
}
///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#ifndef SENF_PACKETS_DECL_ONLY
//#include "IpV6Packet.cci"
//#include "IpV6Packet.ct"
//#include "IpV6Packet.cti"
#include "IpV4Packet.hh"
// Custom includes
-#include "Packets/DataPacket.hh"
+#include "Packets/Packets.hh"
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
namespace {
- senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::UDPPacketType>
+ senf::PacketRegistry<senf::IpTypes>::RegistrationProxy<senf::UDPPacket>
registerUDPPacket (17);
}
-// $Id: UDPPacket.hh 308 2007-07-14 22:31:20Z g0dil $
+// $Id$
//
// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
#define HH_UDPPacket_ 1
// Custom includes
-#include "Packets/PacketType.hh"
-#include "Packets/ParseInt.hh"
-#include "Packets/PacketRegistry.hh"
-#include "Packets/PacketParser.hh"
+#include "Packets/Packets.hh"
//#include "UDPPacket.mpp"
///////////////////////////////hh.p////////////////////////////////////////
///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#ifndef SENF_PACKETS_DECL_ONLY
//#include UDPPacket.cci"
//#include "UDPPacket.ct"
//#include "UDPPacket.cti"
packet parsing and creation.
\section intro Introduction
+
+ Whenever using the library, you will probably need to \c \#include it's header:
+
+ \code
+ #include "Packets/Packets.hh"
+ \endcode
+
+ \warning Never include any other Packets library header directly, always include \c
+ Packets/Packets.hh.
+
+ Additionally you will have to include the header files for the packet types you use, e.g. \c
+ Packets/DefaultBundle/EthernetPacket.hh etc.
Most every use of the packet library starts with some concrete packet typedef. Some fundamental
- packet typedefs are provided by \ref protocolbundle_default. The first example will build a
- complex packet: This will be an Ethernet packet containing an IPv4 UDP packet. We begin by
- building the raw packet skeleton:
+ packet types are provided by \ref protocolbundle_default. Building on those packet types, this
+ example will build a complex packet: This will be an Ethernet packet containing an IPv4 UDP
+ packet. We begin by building the raw packet skeleton:
\code
- senf::EthernetPacket eth (senf::EthernetPacket::create());
- senf::IpV4Packet ip (senf::IpV4Packet::createAfter(ethernet));
- senf::UDPPacket udp (senf::UDPPacket::createAfter(ip));
- senf::DataPacket payload (senf::DataPacket::createAfter(udp,
- std::string("Hello, world!")));
+ senf::EthernetPacket eth (senf::EthernetPacket::create());
+ senf::IpV4Packet ip (senf::IpV4Packet ::createAfter(ethernet));
+ senf::UDPPacket udp (senf::UDPPacket ::createAfter(ip));
+ senf::DataPacket payload (senf::DataPacket ::createAfter(udp,
+ std::string("Hello, world!")));
\endcode
These commands create what is called an interpreter chain. This chain consists of four
empty. We need to set those protocol fields:
\code
- udp->source() = 2000u;
- udp->destination() = 2001u;
- ip->ttl() = 255u;
- ip->source() = senf::INet4Address("192.168.0.1"); // (*)
- ip->destination() = senf::INet4Address("192.168.0.2"); // (*)
- eth->source() = senf::MACAddress("00:11:22:33:44:55");
- eth->destination() = senf::MACAddress("00:11:22:33:44:66");
+ udp->source() = 2000u;
+ udp->destination() = 2001u;
+ ip->ttl() = 255u;
+ ip->source() = senf::INet4Address("192.168.0.1"); // (*)
+ ip->destination() = senf::INet4Address("192.168.0.2"); // (*)
+ eth->source() = senf::MACAddress("00:11:22:33:44:55");
+ eth->destination() = senf::MACAddress("00:11:22:33:44:66");
- eth.finalize(); // (*)
+ eth.finalize(); // (*)
\endcode
As seen above, packet fields are accessed using the <tt>-></tt> operator whereas other packet
checksums etc). Now the packet is ready. We may now send it out using a packet socket
\code
- senf::PacketSocketHandle sock ("eth0");
- sock.write(eth.data());
+ senf::PacketSocketHandle sock ("eth0");
+ sock.write(eth.data());
\endcode
The packet library also provides lot's of facilities to navigate the packet chain:
\code
- eth.next() == ip; // true
- eth.next().is<IpV4Packet>(); // true
- eth.next().next() == udp; // true
- eth.next().is<UDPPacket>(); // false
- eth.next<UDPPacket>() == udp; // true
-
- udp.next<UDPPacket>(); // throws InvalidPacketChainException
- udp.next<UDPPacket>(senf::nothrow); // a senf::Packet testing as false
- udp.findNext<UDPPacket()> == udp; // true
- udp.first<IpV4Packet>() == ip; // true
-
- udp.prev() == ip; // true
- udp.prev<EthernetPacket>() == eth // true
+ eth.next() == ip; // true
+ eth.next().is<IpV4Packet>(); // true
+ eth.next().next() == udp; // true
+ eth.next().is<UDPPacket>(); // false
+ eth.next<UDPPacket>() == udp; // true
+
+ udp.next<UDPPacket>(); // throws InvalidPacketChainException
+ udp.next<UDPPacket>(senf::nothrow); // a senf::Packet testing as false
+ udp.findNext<UDPPacket()> == udp; // true
+ udp.first<IpV4Packet>() == ip; // true
+
+ udp.prev() == ip; // true
+ udp.prev<EthernetPacket>() == eth // true
\endcode
... and so on. It is therefore not necessary to stash away a reference for every interpreter (as
from a packet socket handle:
\code
- senf::PacketSocketHandle sock ("eth0");
- senf::EthernetPacket packet (senf::EthernetPacket::create(senf::Packet::noinit));
- sock.read(packet.data(),0u);
+ senf::PacketSocketHandle sock ("eth0");
+ senf::EthernetPacket packet (senf::EthernetPacket::create(senf::Packet::noinit));
+ sock.read(packet.data(),0u);
\endcode
This first creates an uninitialized Ethernet packet and then reads into this packet. We can now
parse this packet. Let's find out, whether this is a UDP packet destined to port 2001:
\code
- try {
- senf::UDPPacket udp (packet.findNext<UDPPacket>(senf::nothrow));
- if (udp && udp->destination() == 2001u) {
- // Voila ...
- }
- } catch (senf::TruncatedPacketException const &) {
- std::cerr << "Ooops !! Broken packet received ...\n"
- }
+ try {
+ senf::UDPPacket udp (packet.findNext<UDPPacket>(senf::nothrow));
+ if (udp && udp->destination() == 2001u) {
+ // Voila ...
+ }
+ } catch (senf::TruncatedPacketException const &) {
+ std::cerr << "Ooops !! Broken packet received ...\n"
+ }
\endcode
TruncatedPacketException is thrown by <tt>udp->destination()</tt> if that field cannot be
// LocalWords: udp endcode li senf EthernetPacket eth IpV createAfter ip std
// LocalWords: ethernet UDPPacket DataPacket ttl INet MACAddress nothrow prev
// LocalWords: PacketSocketHandle InvalidPacketChainException findNext noinit
-// LocalWords: tt TruncatedPacketException const cerr Ooops
+// LocalWords: tt TruncatedPacketException const cerr Ooops hh
/** \file
\brief Packet non-inline non-template implementation */
-#include "PacketInterpreter.hh"
-#include "Packet.hh"
//#include "Packet.ih"
// Custom includes
-#include "DataPacket.hh"
+#include "Packets.hh"
//#include "Packet.mpp"
#define prefix_
}
///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_Packet_i_)
+#define HH_Packet_i_
#include "Packet.cci"
#include "Packet.ct"
#include "Packet.cti"
// LocalWords: PacketTypeBase TruncatedPacketException http www org Institut
// LocalWords: Fraunhofer fuer offene Kommunikationssysteme FOKUS SatCom Bund
// LocalWords: Kompetenzzentrum Satelitenkommunikation berlios de hh
-// LocalWords: addtogroup Structors PacketType dil
+// LocalWords: addtogroup Structors PacketType dil PacketType's
// Custom includes
#include <sstream>
-#include "PacketType.hh"
-#include "PacketRegistry.hh"
-#include "Packet.hh"
-#include "ParseInt.hh"
-#include "PacketParser.hh"
-#include "DataPacket.hh"
+#include "Packets.hh"
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/test_tools.hpp>
typedef BarPacketType::packet BarPacket;
namespace reg {
- senf::PacketRegistry<RegTag>::RegistrationProxy<FooPacketType> registerFoo(1u);
- senf::PacketRegistry<RegTag>::RegistrationProxy<BarPacketType> registerBar(2u);
+ senf::PacketRegistry<RegTag>::RegistrationProxy<FooPacket> registerFoo(1u);
+ senf::PacketRegistry<RegTag>::RegistrationProxy<BarPacket> registerBar(2u);
}
}
/** \file
\brief PacketData non-inline non-template implementation */
-#include "PacketData.hh"
//#include "PacketData.ih"
// Custom includes
-#include "PacketImpl.hh"
+#include "Packets.hh"
//#include "PacketData.mpp"
#define prefix_
///////////////////////////////hh.e////////////////////////////////////////
#endif
-#if !defined(HH_PacketData_DeclOnly) &&!defined(HH_PacketData_def)
-#define HH_PacketData_def
+#if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_PacketData_i_)
+#define HH_PacketData_i_
#include "PacketData.cci"
//#include "PacketData.ct"
#include "PacketData.cti"
//#include "PacketData.test.ih"
// Custom includes
-#include "PacketData.hh"
-#include "PacketType.hh"
+#include "Packets.hh"
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/test_tools.hpp>
/** \file
\brief PacketImpl non-inline non-template implementation */
-#include "PacketImpl.hh"
//#include "PacketImpl.ih"
// Custom includes
#include <iterator>
-#include "PacketInterpreter.hh"
+#include "Packets.hh"
//#include "PacketImpl.mpp"
#define prefix_
}}
///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_PacketImpl_i_)
+#define HH_PacketImpl_i_
#include "PacketImpl.cci"
//#include "PacketImpl.ct"
#include "PacketImpl.cti"
//#include "PacketImpl.test.ih"
// Custom includes
-#include "PacketImpl.hh"
-#include "PacketInterpreter.hh"
-#include "PacketType.hh"
+#include "Packets.hh"
#include "main.test.hh"
#include <boost/test/auto_unit_test.hpp>
/** \file
\brief PacketInterpreter non-inline non-template implementation */
-#include "PacketInterpreter.hh"
//#include "PacketInterpreter.ih"
// Custom includes
+#include "Packets.hh"
//#include "PacketInterpreter.mpp"
#define prefix_
template <class PacketType>
prefix_ senf::TypeIdValue senf::PacketInterpreter<PacketType>::v_type()
{
- return typeIdValue<PacketType>();
+ return typeIdValue< ConcretePacket<PacketType> >();
}
template <class PacketType>
}
///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_PacketInterpreter_i_)
+#define HH_PacketInterpreter_i_
#include "PacketInterpreter.cci"
#include "PacketInterpreter.ct"
#include "PacketInterpreter.cti"
//#include "PacketInterpreter.test.ih"
// Custom includes
-#include "PacketImpl.hh"
-#include "PacketInterpreter.hh"
-#include "PacketType.hh"
+#include "Packets.hh"
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/optional.hpp>
#include "Utils/SafeBool.hh"
#include "PacketTypes.hh"
-#define HH_PacketData_DeclOnly
#include "PacketData.hh"
-#undef HH_PacketData_DeclOnly
#include "PacketParser.mpp"
///////////////////////////////hh.p////////////////////////////////////////
\code
struct ExtendedParser : public BaseParser
{
- SENF_PACKET_PARSER_NO_INIT(ExtendedParser);
+ ExtendedParser(data_iterator i, state_type s) : BaseParser(i,s) {}
SENF_PACKET_PARSER_DEFINE_FIELDS_OFFSET(senf::bytes(BaseParser(*this)),
( ... fields ... ) );
\code
struct ExtendedParser : public BaseParser
{
- SENF_PACKET_PARSER_NO_INIT(ExtendedParser);
+ ExtendedParser(data_iterator i, state_type s) : BaseParser(i,s) {}
SENF_PACKET_PARSER_DEFINE_FIXED_FIELDS_OFFSET(BaseParser::fixed_bytes,
( ... fields ... ) );
}
///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_PacketParser_i_)
+#define HH_PacketParser_i_
#include "PacketParser.cci"
#include "PacketParser.ct"
#include "PacketParser.cti"
//#include "PacketParser.test.ih"
// Custom includes
-#include "PacketParser.hh"
-#include "PacketInterpreter.hh"
-#include "PacketType.hh"
-#include "ParseInt.hh"
+#include "Packets.hh"
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/test_tools.hpp>
/** \file
\brief PacketRegistry non-inline non-template implementation */
-#include "PacketRegistry.hh"
-#include "PacketRegistry.ih"
// Custom includes
+#include "Packets.hh"
//#include "PacketRegistry.mpp"
#define prefix_
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-// Definition of non-inline template funPacketRegistry.ons
+/** \file
+ \brief PacketRegistry non-inline template implementation */
#include "PacketRegistry.ih"
prefix_ senf::PacketInterpreterBase::factory_t senf::detail::PkReg_EntryImpl<PacketType>::factory()
const
{
- return PacketInterpreter<PacketType>::factory();
+ return PacketType::factory();
}
template <class KeyType>
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-// Definition of inline template funPacketRegistry.ons
+/** \file
+ \brief PacketRegistry inline template implementation */
#include "PacketRegistry.ih"
}
template <class Tag>
-prefix_ typename Tag::key_t senf::PacketRegistry<Tag>::key(Packet packet, NoThrow_t)
+prefix_ typename boost::optional<typename Tag::key_t>
+senf::PacketRegistry<Tag>::key(Packet packet, NoThrow_t)
{
return registry().key(packet.typeId(),true);
}
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+/** \file
+ \brief PacketRegistry public header */
#ifndef HH_PacketRegistryImpl_
#define HH_PacketRegistryImpl_ 1
#include <boost/utility.hpp> // for boost::noncopyable
#include <boost/optional.hpp>
#include "Utils/Exception.hh"
-#include "PacketInterpreter.hh"
#include "Packet.hh"
//#include "PacketRegistry.mpp"
namespace senf {
+ /** \brief Registry entry
+
+ Value returned by a registry lookup
+ */
struct PkReg_Entry
: public intrusive_refcount
{
virtual ~PkReg_Entry();
- virtual PacketInterpreterBase::factory_t factory() const = 0;
+ virtual Packet::factory_t factory() const = 0;
+ ///< Get factory of the registered packet type
};
namespace detail { template <class Key> class PacketRegistryImpl; }
/** \brief Packet registration facility
- The PacketRegistry provides a generic facility to associate an
- arbitrary key with Packets. Example keys are Ethertype or IP
- protocols.
+ The PacketRegistry provides a generic facility to associate an arbitrary key with
+ Packets. Example keys are Ethertype or IP protocols.
Every PacketRegistry is identified by a type tag:
\code
- struct SomeTag {
- typedef some_key_type key_t;
- };
+ struct SomeTag {
+ typedef some_key_type key_t;
+ };
\endcode
- The key type can be an arbitrary value type. The PacketRegistry
- for this Tag can then be accessed using
- <code>PacketRegistry<SomeTag>::</code>.
+ The key type can be an arbitrary value type. The PacketRegistry for this Tag can then be
+ accessed using <code>senf::PacketRegistry<SomeTag>::</code>.
- The PacketRegistry class has only static members and provides
- access to the packet registry. It allows to register Packet
- classes and to create new Packets given a key. Methods are
- also provided to find the key of a Packet type.
+ The PacketRegistry class has only static members and provides access to the packet
+ registry. It allows two-way lookup either by key or by packet type.
\code
- PacketRegistry<SomeTag>::registerPacket<SomePacket>(key_of_somePacket);
- p = PacketRegistry<SomeTag>::create(some_key,begin,end);
- SomeTag::key_t key = PacketRegistry<SomeTag>::key<SomePacket>();
+ senf::Packet::factory_t factory (senf::PacketRegistry<SomeTag>::lookup(some_key).factory());
+ SomeTag::key_t key = PacketRegistry<SomeTag>::key<SomePacket>();
\endcode
- Normally, packet classes are registered statically and not
- procedurally. To this end, the RegistrationProxy is provided:
+ Packets can be registered either dynamically or statically. Dynamic:
\code
- PacketRegistry<SomeTag>::RegistrationProxy<SomePacket>
- registerSomePacket (key_of_somePacket);
+ // dynamic registration
+ senf::PacketRegistry<SomeTag>::registerPacket<SomePacket>(key_of_somePacket);
+
+ // static registration. 'registerSomePacket' is an arbitrary symbol name
+ senf::PacketRegistry<SomeTag>::RegistrationProxy<SomePacket>
+ registerSomePacket (key_of_somePacket);
\endcode
- This global variable declaration will register \c SomePacket
- with the \c SomeTag registry under the key \c
- key_of_somePacket. The variable \c registerSomePacket is a
- dummy. It's only function is to force the call of it's
- constructor during global construction time.
-
- The PacketRegistry's purpose is mostly to assist in
- implementing the v_nextInterpreter() member of packet
- facades. This is further supported by the PacketRegistryMixin
- class.
-
- \todo Add parameterless create() method
+
+ This global variable declaration will register \a SomePacket with the \a SomeTag registry
+ under the key \a key_of_somePacket. The variable \a registerSomePacket is a dummy. It's only
+ function is to force the call of it's constructor during global construction time. This
+ static registration only works when the symbol is included into the final binary. To force
+ this inclusion, you should not put packet registrations into a library but into an object
+ file.
+
+ \ingroup packet_module
*/
template <class Tag>
class PacketRegistry
{
public:
/** \brief Statically register a packet type in a PacketRegistry
+
+ To use this class, define a global symbol in the following way:
+ \code
+ namespace {
+ senf::PacketRegistry<Tag>::RegistrationProxy<PacketType>
+ registerPacketType (key);
+ }
+ \endcode Here \a Tag is the type tag of the registry to register the packet in, \a
+ PacketType is the packet to register (this is the ConcretePacket of that packet) and \a
+ key is the key of type \c Tag::key_t under which the packet is to be registered. \a
+ registerPacketType is an arbitrary name for the global symbol.
*/
template <class PacketType>
struct RegistrationProxy
/** \brief Register new packet type
- Register \c PacketType in the packet registry \c Tag
- under the given \c key.
+ Register \a PacketType in the packet registry \a Tag under the given \a key.
- \par Preconditions:
- The given \c key must be unique and not be assigned to
- any other packet class in this registry.
- The Packet must not already be registered in the registry.
+ \par Preconditions: The given \a key must be unique and not be assigned to any other
+ packet class in this registry. The Packet must not already be registered in the
+ registry.
- \param PacketType packet to register
- \param key key of the packet
+ \param PacketType ConcretePacket instantiation of packet to register
+ \param key The key of the packet
*/
template <class PacketType>
static void registerPacket(typename Tag::key_t key);
- /** \brief Find key of a packet
+ /** \brief Find key of a packet type
- Return the key of \c PacketType as registered in the \c
- Tag registry
+ Return the key of \a PacketType as registered in the \a Tag registry
\param PacketType packet of which the key is requested
\returns key of the packet
- \throws PacketTypeNotRegistered if the packet type is not
- found in the registry.
+ \throws PacketTypeNotRegistered if the packet type is not found in the registry.
*/
template <class PacketType>
static typename Tag::key_t key();
+ /** \brief Find key of a packet type
+
+ Return the key of \a PacketType as registered in the \a Tag registry
+
+ \param PacketType packet of which the key is requested
+ \returns key of the packet wrapped in a <a
+ href="http://www.boost.org/libs/optional/doc/optional.html">boost::optional</a> or
+ an unbound optional, if the key is not found.
+ */
template <class PacketType>
static typename boost::optional<typename Tag::key_t> key(NoThrow_t);
+ /** \brief Find key of a packet
+
+ Return the key of \a packet, an arbitrary packet, as registered in the \a Tag registry.
+
+ \param packet The packet of which the key is requested
+ \returns key of the packet
+ \throws PacketTypeNotRegistered if the packet type is not found in the registry.
+ */
static typename Tag::key_t key(Packet packet);
- static typename Tag::key_t key(Packet packet, NoThrow_t);
- /** \brief Lookup a packet by it's key
+ /** \brief Find key of a packet
+
+ Return the key of \a packet, an arbitrary packet, as registered in the \a Tag registry.
- Returns the packet registration registered under \a key in the \a Tag registry
+ \param packet The
+packet of which the key is requested
+ \returns key of the packet wrapped in a <a
+ href="http://www.boost.org/libs/optional/doc/optional.html">boost::optional</a> or
+ an unbound optional, if the key is not found.
+ */
+ static typename boost::optional<typename Tag::key_t> key(Packet packet, NoThrow_t);
- \param key Key of the packet registered
- \returns Registration entry of the packet
- \throws PacketTypeNotRegistered if the packet type is not found in the registry
+ /** \brief Lookup a packet by it's key
+
+ \throws PacketTypeNotRegistered if the \a key is not found in the registry
+ \return Packet entry for given \a key
*/
static PkReg_Entry const & lookup(typename Tag::key_t key);
+ /** \brief Lookup a packet by it's key
+ \return Pointer to packet entry for given \a key or 0, if the key is not found in the
+ registry.
+ */
static PkReg_Entry const * lookup(typename Tag::key_t key, NoThrow_t);
private:
}
///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_PacketRegistryImpl_i_)
+#define HH_PacketRegistryImpl_i_
//#include "PacketRegistry.cci"
#include "PacketRegistry.ct"
#include "PacketRegistry.cti"
// compile-command: "scons -u test"
// comment-column: 40
// End:
+
+// LocalWords: PacketRegistry hh dil Fraunhofer Institut fuer offene FOKUS de
+// LocalWords: Kommunikationssysteme Kompetenzzentrum Satelitenkommunikation
+// LocalWords: SatCom Bund stefan bund fokus fraunhofer Ethertype IP struct
+// LocalWords: SomeTag endcode senf SomePacket registerPacket ingroup param
+// LocalWords: registerSomePacket RegistrationProxy namespace PacketType key
+// LocalWords: registerPacketType ConcretePacket PacketTypeNotRegistered href
+// LocalWords: http www org html
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+/** \file
+ \brief PacketRegistry internal header */
+
#ifndef IH_PacketRegistryImpl_
#define IH_PacketRegistryImpl_ 1
namespace senf {
namespace detail {
-
+
+ ///\internal
template <class PacketType>
struct PkReg_EntryImpl
: public PkReg_Entry
{
- virtual PacketInterpreterBase::factory_t factory() const;
+ virtual Packet::factory_t factory() const;
};
+ ///\internal
template <class KeyType>
class PacketRegistryImpl
: private boost::noncopyable
// Custom includes
#include <string>
-#include "PacketRegistry.hh"
-#include "PacketType.hh"
-#include "ParseInt.hh"
+#include "Packets.hh"
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/test_tools.hpp>
};
struct FooPacketType : public PacketTypeBase {};
+ typedef senf::ConcretePacket<FooPacketType> FooPacket;
struct BarPacketType : public PacketTypeBase {};
+ typedef senf::ConcretePacket<BarPacketType> BarPacket;
struct OtherPacketType : public PacketTypeBase {};
+ typedef senf::ConcretePacket<OtherPacketType> OtherPacket;
namespace reg {
- PacketRegistry<StringTag>::RegistrationProxy<FooPacketType> registerFoo ("foo");
- PacketRegistry<StringTag>::RegistrationProxy<BarPacketType> registerBar ("bar");
+ PacketRegistry<StringTag>::RegistrationProxy<FooPacket> registerFoo ("foo");
+ PacketRegistry<StringTag>::RegistrationProxy<BarPacket> registerBar ("bar");
}
}
BOOST_AUTO_UNIT_TEST(packetRegistry_test)
{
- PacketRegistry<BaseTag>::registerPacket<FooPacketType>(1u);
- PacketRegistry<BaseTag>::registerPacket<BarPacketType>(2u);
+ PacketRegistry<BaseTag>::registerPacket<FooPacket>(1u);
+ PacketRegistry<BaseTag>::registerPacket<BarPacket>(2u);
- BOOST_CHECK_EQUAL( PacketRegistry<BaseTag>::key<FooPacketType>(), 1u );
- BOOST_CHECK_EQUAL( PacketRegistry<BaseTag>::key<BarPacketType>(), 2u );
- BOOST_CHECK_THROW( PacketRegistry<BaseTag>::key<OtherPacketType>(),
+ BOOST_CHECK_EQUAL( PacketRegistry<BaseTag>::key<FooPacket>(), 1u );
+ BOOST_CHECK_EQUAL( PacketRegistry<BaseTag>::key<BarPacket>(), 2u );
+ BOOST_CHECK_THROW( PacketRegistry<BaseTag>::key<OtherPacket>(),
PacketTypeNotRegisteredException );
- BOOST_CHECK_EQUAL( PacketRegistry<StringTag>::key<FooPacketType>(), "foo" );
+ BOOST_CHECK_EQUAL( PacketRegistry<StringTag>::key<FooPacket>(), "foo" );
BOOST_CHECK( ! PacketRegistry<StringTag>::lookup("blub", senf::nothrow) );
BOOST_CHECK( PacketRegistry<BaseTag>::lookup(1u, senf::nothrow) );
-
}
///////////////////////////////cc.e////////////////////////////////////////
namespace senf {
- /** \brief Helper baseclass implementing the PacketType interface
+ /** \brief Helper base-class implementing the PacketType interface
This helper class maybe used when building a new PacketType. It provides a complete default
implementations of this interface. To define a new PacketType, derive from this class and
static void finalize(packet p)
{
- // optionally complete the packet by generating autogenerated information
+ // optionally complete the packet by generating auto-generated information
// (like checksums)
}
You may leave out any one of the members (you should however always define the \c
interpreter typedef member)
+
+ \ingroup packet_module
*/
struct PacketTypeBase
{
///< Parser to parser packet fields
/**< This typedef has to be set to the parser of the packet
- The default is a VoidPacketParser which does not parser
+ The default is a VoidPacketParser which does not parse
any field. */
static size_type initSize();
static size_type initHeadSize();
///< Get size of new (empty) packet header
/**< This function gives the index within a newly created,
- empty packet where a subpacket is to be placed.
+ empty packet where a sub-packet is to be placed.
The default implementation returns initSize().
packet. The new packet will have a size of at least
initSize() but the size may well be larger. It is also
possible for the packet to already have further
- subpackets.
+ sub-packets.
The default implementation does nothing. */
static void dump(packet p, std::ostream & os);
///< Dump packet data in readable form
/**< The dump() function writes out a complete
- representation of the packet. This is used formost for
- debugging purposes.
+ representation of the packet. This is used for most for
+ debugging purposes.
The default implementation does nothing. */
};
/** \brief Mixin to provide standard implementations for nextPacketRange and nextPacketType
This mixin class simplifies the definition of simple packets with fixed-size headers and/or
- trailers. For this type of Packet, this mixin provides the nextPacketRange() and
- nextPacketType() members:
+ trailers. For this type of Packet, this mixin provides the nextPacketRange() member. If you
+ additionally provide the optional \a Registry argument, PacketTypeMixin provides a simple
+ implementation of nextPacketType. When using the PacketTypeMixin, the implementation of a
+ packet is simplified to:
\code
+ // Here 'SomeRegistryTag' is optional
struct SimplePacketType
: public senf::PacketTypeBase
- pyblic senf:PacketTypeMixin<SimplePacketType, SomeRegistryTag>
+ public senf:PacketTypeMixin<SimplePacketType, SomeRegistryTag>
{
+ typedef senf::PacketTypeMixin<SimplePacketType, SomeRegistryTag> mixin;
+ typedef senf::ConcretePacket<SimplePacketType> packet;
+ typedef SomePacketParser parser;
+
+ using mixin::nextPacketRange;
+ // Only if the optional 'Registry' argument is provided
+ using mixin::nextPacketType;
+ // Only if using the default implementation
+ using mixin::initSize;
+ // Only if using the default implementation
+ using mixin::init;
+
static interpreter::size_type initSize()
{
// This member is optional. If it is not defined, 'senf::init_size<parser>::value'
return header_size;
}
+ static void init(packet p)
+ {
+ // This member is optional. The default implementation calls the parsers init()
+ // member.
+ }
+
static registry_key_t nextPacketKey(packet p)
{
// Return the key in the registry under which the next packet
// passed to the PacketTypeMixin template.
return i.fields().typeField();
}
+
+ static void finalize(packet p)
+ {
+ // optionally complete the packet by generating auto-generated information
+ // (like checksums)
+ }
+
+ static void dump(packet p, std::ostream & os)
+ {
+ // Write out a readable representation of the packet for debug purposes
+ }
};
\endcode
+
+ Most of the members are optional, which reduces the implementation of a fixed-sized header
+ packet with no trailer and a simple next-packet header to
+
+ \code
+ struct SimplePacketType
+ : public senf::PacketTypeBase
+ public senf:PacketTypeMixin<SimplePacketType, SomeRegistryTag>
+ {
+ typedef senf::PacketTypeMixin<SimplePacketType, SomeRegistryTag> mixin;
+ typedef senf::ConcretePacket<SimplePacketType> packet;
+ typedef SomePacketParser parser;
+
+ using mixin::nextPacketRange;
+ using mixin::nextPacketType;
+ using mixin::initSize;
+ using mixin::init;
+
+ static registry_key_t nextPacketKey(packet p)
+ { return i.fields().typeField(); }
+ };
+ \endcode
+
+ If needed, you may additionally add a \c finalize() member. You also should add a \c dump()
+ member to help debugging but both members are optional.
+
+ \ingroup packet_module
*/
template <class Self, class Registry=void>
class PacketTypeMixin
}
///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_PacketType_i_)
+#define HH_PacketType_i_
#include "PacketType.cci"
//#include "PacketType.ct"
#include "PacketType.cti"
// compile-command: "scons -u test"
// comment-column: 40
// End:
+
+// LocalWords: Fraunhofer Institut fuer offene Kommunikationssysteme FOKUS de
+// LocalWords: Kompetenzzentrum Satelitenkommunikation SatCom Bund berlios dil
+// LocalWords: PacketType struct SomePacketType senf PacketTypeBase initSize
+// LocalWords: ConcretePacket init initHeadSize nextPacketRange NextPacket os
+// LocalWords: nextPacketType std ostream endcode ingroup VoidPacketParser Ok
+// LocalWords: tt li OtherPacketType Mixin mixin SimplePacketType typeField
+// LocalWords: PacketTypeMixin SomeRegistryTag SomePacketParser nextPacketKey
+// LocalWords: hh
}}}}
///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_PacketTypes_i_)
+#define HH_PacketTypes_i_
//#include "PacketTypes.cci"
//#include "PacketTypes.ct"
//#include "PacketTypes.cti"
--- /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 Packets public header */
+
+#ifndef HH_Packets_
+#define HH_Packets_ 1
+
+#define SENF_PACKETS_DECL_ONLY
+
+#include "all_includes.hh"
+
+#undef SENF_PACKETS_DECL_ONLY
+
+#include "all_includes.hh"
+
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
}
///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_ParseArray_i_)
+#define HH_ParseArray_i_
//#include "ParseArray.cci"
//#include "ParseArray.ct"
#include "ParseArray.cti"
//#include "ParseArray.test.ih"
// Custom includes
-#include "PacketInterpreter.hh"
-#include "ParseArray.hh"
-#include "ParseInt.hh"
-#include "PacketType.hh"
+#include "Packets.hh"
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/test_tools.hpp>
}
///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_ParseInt_i_)
+#define HH_ParseInt_i_
//#include "ParseInt.cci"
//#include "ParseInt.ct"
//#include "ParseInt.cti"
//#include "ParseInt.test.ih"
// Custom includes
-#include "ParseInt.hh"
-#include "PacketInterpreter.hh"
-#include "PacketType.hh"
+#include "Packets.hh"
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/test_tools.hpp>
}
///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_ParseList_i_)
+#define HH_ParseList_i_
//#include "ParseList.cci"
#include "ParseList.ct"
#include "ParseList.cti"
//#include "ParseList.test.ih"
// Custom includes
-#include "ParseList.hh"
+#include "Packets.hh"
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/test_tools.hpp>
}
///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_ParseListB_i_)
+#define HH_ParseListB_i_
//#include "ParseListB.cci"
//#include "ParseListB.ct"
#include "ParseListB.cti"
//#include "ParseListB.test.ih"
// Custom includes
-#include "ParseListB.hh"
-#include "ParseVec.hh"
-#include "PacketType.hh"
-#include "ParseInt.hh"
+#include "Packets.hh"
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/test_tools.hpp>
}
///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_ParseListN_i_)
+#define HH_ParseListN_i_
//#include "ParseListN.cci"
#include "ParseListN.ct"
#include "ParseListN.cti"
//#include "ParseListN.test.ih"
// Custom includes
-#include "ParseListN.hh"
-#include "ParseVec.hh"
-#include "ParseInt.hh"
-#include "PacketType.hh"
-#include "Packet.hh"
+#include "Packets.hh"
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/test_tools.hpp>
}
///////////////////////////////hh.e////////////////////////////////////////
+#endif
+#if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_ParseVec_i_)
+#define HH_ParseVec_i_
//#include "ParseVec.cci"
#include "ParseVec.ct"
#include "ParseVec.cti"
//#include "ParseVec.test.ih"
// Custom includes
-#include "ParseVec.hh"
-#include "ParseInt.hh"
-#include "PacketType.hh"
+#include "Packets.hh"
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/test_tools.hpp>
###########################################################################
+def makeAllIncludesHH(target = None, source = None, env = None):
+ file(target[0].abspath,"w").write("".join([ '#include "%s"\n' % f
+ for f in env['SOURCE_HEADERS']]))
+makeAllIncludesHH = env.Action(makeAllIncludesHH, varlist=['SOURCE_HEADERS'])
+
+###########################################################################
+
sources = SENFSCons.GlobSources()
SENFSCons.StandardTargets(env)
+env.Command('all_includes.hh', 'SConscript', makeAllIncludesHH,
+ SOURCE_HEADERS = [ f for f in glob.glob("*.hh")
+ if 'defined(SENF_PACKETS_DECL_ONLY)' in file(f).read() ])
+
SENFSCons.Lib(env,
library = 'Packets',
sources = sources,
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/test_tools.hpp>
+#include "Packets.hh"
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
cond='( -name *.h -o -name *.hh -o -name *.ih -o -name *.c -o -name *.cc -o -name *.cci -o -name *.ct -o -name *.cti )'
fi
+set -f
+
find . \
-name .svn -prune -o \
-name doc -prune -o \