// $Id$
//
-// Copyright (C) 2006
+// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
// Stefan Bund <stefan.bund@fokus.fraunhofer.de>
// Free Software Foundation, Inc.,
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-// TODO: Implement assign() method akin to reinterpret(). However,
-// instead of using the data already present, assign() will replace
-// the date of the current packet with the given Packet.
-
-// TODO: Implement wrapping-constructor. Somehow we want to have a
-// constructor, which allows creating a chain of packet interpreters
-// with as little overhead as possible.
-
-// TODO: Document the additional concrete Packet facade requirements
-// explicitly and not only within the Parser requirements (check(),
-// bytes() and min_bytes() members ...)
-
-// TODO: Implement special container replacing vector which manages
-// some headroom to allow efficient insertion of elements at the
-// beginning. This really is just another type of deque
-// implementation.
-
-
-/** \mainpage The SatCom Packet Framework
-
- \section arch Overall Architecture
-
- The general Architecture of the Packet Framework (pkf for short)
- is seperated into two components: The basic packet handling and
- the parser framework.
-
- The basic packet handling implements a packet interpreter
- chain. Every packet is represented as a chain of interpreters
- where each interpreter is a facade looking into the same
- packet. Each interpreter will interpret a specific header of a
- packet. For example, an ethernet frame might have an interpreter
- chain consisting of EthernetPacket, IPPacket, UDPPacket and
- DataPacket. Each of these interpreters will interpret a section of
- the raw data bytes. The interpreter ranges overlap since every
- packet also includes it's payload.
-
- The parser framework is used to interpret the raw bytes of a
- specific packet and parse the values present in that packet. For
- example, Parse_Ethernet will parse the ethernet source MAC,
- destination MAC and ethertype given any random access iterator to
- the first byte of the ethernet frame. Parsers are extremely light
- classes. They are temporary classes passed around by value. In
- most cases, they are just comprised of a single pointer adorned
- with type information.
-
- \section handling Packet Handling
-
- The packet handling is implemented within
- satcom::pkf::Packet. This class is the baseclass to all packet
- interpreter facades. To implement a new packet type, publically
- derive from satcom::pkf::Packet and implement the virtual
- interface (see the class documentation for details).
-
- \section framework Parser Framework
-
- The parser framework provides an abstract framwork to parse packet
- oriented data. A Parser is a template class taking an arbitrary
- iterator as input and allowing random access to data elements of
- the interpreted type, like source and destination MAC of an
- ethernet frame. The parser framework is to be used hierarchically
- and recursively, the parser methods should return further parsers
- which can return further parsers and so on.
-
- The parser framework contains some basic parsers to be used to
- build up more complex parsers:
-
- - ParseInt.hh: Lots of parsers for integer numbers like
- satcom::pkf::Parse_UInt8, for integer bitfields like
- satcom::pkf::Parse_UIntField and satcom::pkf::Parse_Flag to
- parse boolean flags.
-
- - ParseArray.hh: The satcom::pkf::Parse_Array parser to parse
- arbitrary fixed-size arrays of fixed-size elements (that is
- sub-parsers).
-
- - ParseVec.hh: The satcom::pkf::Parse_Vector parser to parse
- dynamically sized arrays of fixed-size elements (that is
- sub-parsers).
-
- See satcom::pkf::ParserBase for further information.
-
- \section stuff Other Utilities
-
- The pkf also comprises some additional utilities to support the
- development of packet classes.
-
- The satcom::pkf::PacketRegistry implements a registry of packets
- keyed by an arbitrary type. The registry is used to find a packet
- type given some kind of id (like the ethertype value from the
- ethernet header). Together with it's support classes (especially
- satcom::pkf::PacketRegistryMixin) this class greatly simplifies
- implementing the needed table lookups.
- */
-
/** \file
\brief Main packet interface
+
+ \todo Implement assign() method akin to reinterpret(). However,
+ instead of using the data already present, assign() will replace
+ the date of the current packet with the given Packet.
+
+ \todo Implement wrapping-constructor. Somehow we want to have a
+ constructor, which allows creating a chain of packet interpreters
+ with as little overhead as possible.
+
+ \todo Document the additional concrete Packet facade requirements
+ explicitly and not only within the Parser requirements (check(),
+ bytes() and min_bytes() members ...)
+
+ \todo Implement special container replacing vector which manages
+ some headroom to allow efficient insertion of elements at the
+ beginning. This really is just another type of deque
+ implementation.
*/
#ifndef HH_Packet_
#include "Packet.mpp"
// ////////////////////////////hh.p////////////////////////////////////////
-namespace satcom {
-namespace pkf {
-
+namespace senf {
+
namespace impl { template <class OtherPacket> class PkReg_EntryImpl; }
namespace impl { class PacketImpl; }
/** \brief Basic interface to all packet facades
\section packet_overview Overview
-
+
This class is the base class of all Packets. It implements the
generic Packet interface and provides the packet management
- framework. satcom::pkf::Packet manages the necessary memory
+ framework. senf::Packet manages the necessary memory
resources and controlls the chain of packet interpreters.
The Packet user always interfaces with the pkf via a Packet
counted smart pointer, so resource management is quasi
automatic.
- \image html "../../structure.png" Overview
-
+ \image html structure.png Overview
+
Internally, every Packet references a PacketImpl instance which
manages the raw packet data and the interpreter list. This raw
data is interpreted by the concrete Packet derived class
type (i.e. EthernetPacket or UDPPacket).
Packet provides several interfaces:
-
+
- Creation of Packet instances: create()
- Access to the chain of interpreters: next(), prev(), head(),
- You must implement a static check() method which validates
a byte region as your new Packet
- \code
- class ExamplePacket
- : public satcom::pkf::Packet
+ \code
+ class ExamplePacket
+ : public senf::Packet
{
public:
typedef ptr_t<ExamplePacket>::ptr ptr;
private:
template <class Arg>
ExamplePacket(Arg arg [, other args ... ])
- : satcom::pkf::Packet(arg)
+ : senf::Packet(arg)
{}
virtual void v_nextInterpreter() const
// calculate checksum etc
}
- friend class satcom::pkf::Packet;
+ friend class senf::Packet;
};
\endcode
Please do not implement the methods inline to not clutter up
the header file. This is done here in the example to simplify
it. If a class is to be registered in some
- satcom:pkf::PacketRegistry, it must not take any additional
+ senf:PacketRegistry, it must not take any additional
constructor parameters.
After having implemented the bare framework, the most comman
\code
class ExamplePacket
- : public satcom::pkf::Packet,
- public Parse_Example<satcom::pkf::Packet::iterator,
+ : public senf::Packet,
+ public Parse_Example<senf::Packet::iterator,
ExamplePacket>
{
// check does not need to be implemented here, it is
- // inherited from the parser
+ // inherited from the parser
private:
template <class InputIterator>
ExamplePacket(InputIterator begin, InputIterator end)
- : satcom::pkf::Packet(begin,end)
+ : senf::Packet(begin,end)
{}
};
\endcode
- See the satcom::pkf::ParserBase Documentation for how to
+ See the senf::ParserBase Documentation for how to
implement Parse_Example.
The implementation of v_nextInterpreter most of the time
relies on some packet registry. This is simplified using the
- satcom::pkf::PacketRegistryMixin class as follows. Again, we
+ senf::PacketRegistryMixin class as follows. Again, we
only show the differences from the preceding Example:
\code
};
class ExamplePacket
- : public satcom::pkf::Packet,
- public Parse_Example<satcom::pkf::Packet::iterator,
+ : public senf::Packet,
+ public Parse_Example<senf::Packet::iterator,
ExamplePacket>,
- public satcom::pkf::PacketRegistryMixin<ExampleRegistry,
+ public senf::PacketRegistryMixin<ExampleRegistry,
ExamplePacket>
{
- using satcom::pkf::Packet::registerInterpreter;
- using satcom::pkf::PacketRegsitryMixin<ExampleRegistry,ExamplePacket>::registerInterpreter;
+ using senf::Packet::registerInterpreter;
+ using senf::PacketRegsitryMixin<ExampleRegistry,ExamplePacket>::registerInterpreter;
private:
virtual void v_nextInterpreter() const
{
\endcode
For further details on the packet registry, see
- satcom::pkf::PacketRegistry.
+ senf::PacketRegistry.
\section packet_impl Implementation details
imporved by either allocating some headroom/tailroom in the
vector and using this when inserting data at the beginning or
end. Alternatively, a new container class (like the
- satcom::lib::deque_list) could be used to support zero-copy
+ senf::deque_list) could be used to support zero-copy
semantics.
At the moment, we leave the implementation at
intrusive_ptr is only the size of an ordinary pointer, a
smart_ptr has the size of two pointers).
+ \fixme Make all data mutators protected
+
\nosubgrouping
*/
class Packet : boost::noncopyable
typedef std::vector<byte> raw_container;
typedef boost::shared_ptr<Packet> interpreter_list_ptr;
- typedef std::list<satcom::pkf::Packet::interpreter_list_ptr> interpreter_list;
+ typedef std::list<senf::Packet::interpreter_list_ptr> interpreter_list;
typedef unsigned refcount_t;
///@}
///////////////////////////////////////////////////////////////////////////
///\name Types
///@{
-
+
/** \brief smart pointer template for all Packet classes
-
+
This struct is just a template typedef. It defines the
smart pointer used for all Packet classes.
*/
Every derived class \e must redeclare this member for it's
derived type:
- \code
+ \code
typedef ptr_t<DerivedClass>::ptr ptr
\endcode
*/
- typedef ptr_t<Packet>::ptr ptr;
+ typedef ptr_t<Packet>::ptr ptr;
typedef raw_container::iterator iterator; //!< raw data iterator
typedef raw_container::size_type size_type;
typedef raw_container::difference_type difference_type;
///@{
/** \brief create new Packet
-
+
This method is used to create a new Packet. All Packet
instances are created via this method, they are \e never
created directly from the Packet derived class.
///\name Interpreter chain
///@{
-
+
/** \brief get next packet from the interpreter chain
\return smart pointer to next packet or 0 if last packet */
ptr next() const;
/** \brief get last packet of the interpreter chain
\return smart pointer to last packet */
ptr last() const;
-
+
/** \brief first packet of given type after the current packet
\return smart pointer to first following packet of type \a
OtherPacket or 0, if no such packet exists */
/** \brief check, wether the packet is of the given type
\return true, if packt is of type \a OtherPacket, false
otherwise */
- template <class OtherPacket> bool is() const;
+ template <class OtherPacket> bool is() const;
/** \brief cast packet pointer to the given type
\return a properly cast smart pointer if packet is of type
\a OtherPacket. Otherwise return 0 */
- template <class OtherPacket> typename ptr_t<OtherPacket>::ptr as();
+ template <class OtherPacket> typename ptr_t<OtherPacket>::ptr as();
/** \brief replace current packet interpreter
This method will \e replace the current packet facade in
the interpreter list with a new interpreter given by \a
- OtherPacket.
+ OtherPacket.
\attention This invalidates the packet instance \e
- this</b>. You must ensure, not to use the Packet instance
- any further after this call
+ this. You must ensure, not to use the Packet instance any
+ further after this call
\return smart pointer to a \e new packet facade
\throws TruncatedPacketException there is not enough data
///@{
/** \brief begin interator of raw packet data
-
+
This iterator allows access to the raw data interpreted by
the packet facade. This \e includes any header possibly
interpreted by the derived packet instance. To access the
data */
iterator begin() const;
/** \brief past-the-end iterator of raw packet data
-
+
This iterator allows access to the raw data interpreted by
the packet facade. This \e includes any header possibly
interpreted by the derived packet instance. To access the
// Modifying the raw packet data
- // FIXME: Make all data mutators protected
-
typedef enum { AUTO, BEFORE, INSIDE, OUTSIDE, AFTER } Whence;
/** \brief insert single byte \a v before pos
derived packet instance. This method is mostly to be used
by the derived class implementation and their helper
classes. */
- template <class InputIterator>
+ template <class InputIterator>
void insert(iterator pos, InputIterator f, InputIterator l, Whence whence = AUTO);
/** \brief erase single byte
///@{
/** \brief create new interpreter facade for an existing packet
-
+
This constructor is called, when a new interpreter is to
be added to the interpreter chain. The constructor is
called indirectly from registerInterpreter() or
template <class Operation>
Packet(Operation const & arg);
virtual ~Packet();
-
+
private:
/** \brief create next packet interpreter
instance. The new instance is automatically added to the
interpreter chain after the current interpreter.
- See also satcom::pkf::PacketRegistryMixin on how to
+ See also senf::PacketRegistryMixin on how to
use a Registry to find the next interpreters implementing
class.
*/
bool release();
bool unlink();
- struct PacketOp_register;
- friend class PacketOp_register;
+ struct PacketOp_register;
+ friend class PacketOp_register;
void i_registerInterpreter(Packet * p) const;
- struct PacketOp_replace;
- friend class PacketOp_replace;
+ struct PacketOp_replace;
+ friend class PacketOp_replace;
void i_replaceInterpreter(Packet * p);
- struct PacketOp_set;
- friend class PacketOp_set;
+ struct PacketOp_set;
+ friend class PacketOp_set;
void i_setInterpreter(impl::PacketImpl * i);
private:
struct TruncatedPacketException : public std::exception
{ virtual char const * what() const throw() { return "truncated packet"; } };
-}}
+}
// ////////////////////////////hh.e////////////////////////////////////////
#include "Packet.cci"
\f
// Local Variables:
// mode: c++
-// c-file-style: "satcom"
+// fill-column: 100
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
// End: