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

Packets: BUGFIX: ensure complete interpreter chain in finalize()

Packets: documentation: Mainpage, Packet, ConcretePacket
Packets: Remove uneeded typedefs from public interface
Packets/DefaultBundle: Move all documentation into special group
doclib: Add special formating for implementation notes
parent 59da2a0c
No related branches found
No related tags found
No related merge requests found
// 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.
/** \defgroup protocolbundles Protocol Bundles
Each protocol bundle provides a collection of related concrete packet classes for a group of
related protocols.
*/
/** \defgroup protocolbundle_default The Default Bundle
The default bundle combines a set of basic low level protocols like Ethernet or IP.
\ingroup protocolbundles
*/
// 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"
// mode: flyspell
// mode: auto-fill
// ispell-local-dictionary: "american"
// End:
......@@ -36,6 +36,9 @@
namespace senf {
///\addtogroup protocolbundle_default
///@{
struct MACAddress
: boost::array<PacketParserBase::byte,6>
{
......@@ -146,6 +149,8 @@ namespace senf {
};
typedef EthVLanPacketType::packet EthVLanPacket;
///@}
}
......
// $Id$
// $Id: IpV4Packet.hh 307 2007-07-14 21:31:12Z g0dil $
//
// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
......@@ -34,6 +34,9 @@
namespace senf {
///\addtogroup protocolbundle_default
///@{
struct Parse_IpV4 : public PacketParserBase
{
SENF_PACKET_PARSER_NO_INIT(Parse_IpV4);
......@@ -98,6 +101,7 @@ namespace senf {
typedef IpV4PacketType::packet IpV4Packet;
///@}
}
......
......@@ -32,6 +32,9 @@
namespace senf {
///\addtogroup protocolbundle_default
///@{
// See RFC2460
struct Parse_IpV6Extension_Fragment : public PacketParserBase
{
......@@ -74,6 +77,8 @@ namespace senf {
};
typedef IpV6ExtensionType_Fragment::packet IpV6Extension_Fragment;
///@}
}
///////////////////////////////hh.e////////////////////////////////////////
......
......@@ -37,6 +37,9 @@
namespace senf {
///\addtogroup protocolbundle_default
///@{
// See RFC2460
struct Parse_IpV6 : public PacketParserBase
{
......@@ -88,6 +91,7 @@ namespace senf {
typedef IpV6PacketType::packet IpV6Packet;
///@}
}
///////////////////////////////hh.e////////////////////////////////////////
......
// $Id$
// $Id: UDPPacket.hh 308 2007-07-14 22:31:20Z g0dil $
//
// Copyright (C) 2006
// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
......@@ -34,6 +34,9 @@
namespace senf {
///\addtogroup protocolbundle_default
///@{
// See RFC768
struct Parse_UDP : public PacketParserBase
{
......@@ -66,6 +69,8 @@ namespace senf {
};
typedef UDPPacketType::packet UDPPacket;
///@}
}
......
......@@ -3,5 +3,4 @@
PROJECT_NAME = libPackets
TAGFILES = "$(TOPDIR)/Utils/doc/Utils.tag"
GENERATE_TAGFILE = doc/Packets.tag
#INPUT = . DefaultBundle RTPBundle
INPUT = .
\ No newline at end of file
INPUT = . DefaultBundle
......@@ -2,104 +2,37 @@
\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
senf::Packet. This class is the baseclass to all packet
interpreter facades. To implement a new packet type, publically
derive from senf::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 Packet library consists of several components:
\li The \ref packet_module manages the packet data and provides the framework for handling the
chain of packet headers. The visible interface is provided by the Packet class.
\li \ref packetparser provides the framework for interpreting packet data. It handles
parsing the packet information into meaningful values.
\li The \ref protocolbundles provide concrete implementations for interpreting packets of
some protocol. The Protocol Bundles are built on top of the basic packet library.
*/
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
senf::Parse_UInt8, for integer bitfields like
senf::Parse_UIntField and senf::Parse_Flag to
parse boolean flags.
- ParseInt.hh: Lots of parsers for integer numbers like senf::Parse_UInt8, for integer
bitfields like senf::Parse_UIntField and senf::Parse_Flag to parse boolean flags.
- ParseArray.hh: The senf::Parse_Array parser to parse
arbitrary fixed-size arrays of fixed-size elements (that is
sub-parsers).
- ParseArray.hh: The senf::Parse_Array parser to parse arbitrary fixed-size arrays of
fixed-size elements (that is sub-parsers).
- ParseVec.hh: The senf::Parse_Vector parser to parse
dynamically sized arrays of fixed-size elements (that is
sub-parsers).
- ParseVec.hh: The senf::Parse_Vector parser to parse dynamically sized arrays of fixed-size
elements (that is sub-parsers).
See senf::ParserBase for further information.
\section stuff Other Utilities
The pkf also comprises some additional utilities to support the
development of packet classes.
The senf::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
senf::PacketRegistryMixin) this class greatly simplifies
implementing the needed table lookups.
\todo The Packet Libarary really needs a refactoring of the public
interfaface ...
\idea Add the Handle-Body idiom to the mix with a PacketRef (or
HeaderRef or InterpreterRef or whatever class). This would
have members for all the API defined in Packet now. \c
operator-> would return a parser object to interpret the
data. This would make awayy with the inheritance relationship
...
\idea Templating the parsers on the iterator type does not
introduce additional coupling (because of the inlining) but
looking at it after the fact it looks like severe overdesign
and it does introduce some problems (e.g. rebind and all this
entails). If we just implement all parsers for
Packet::byte_iterator they are no tmplates any more which
should simplify things a log.
The pkf also comprises some additional utilities to support the development of packet classes.
\idea we need some better and automatic checking on data access
especially after data has changed. Idea 1: give the parser the
end iterator as additional member. Enforce, that all parsers
must ultimately be based on ParseInt and have ParseInt check
against end() at construction time. Idea 2: add a dirty flag
to the interpreters. Set this flag whenever the packet is
changed and recall check() in operator-> of the PacketRef
object if the packet is dirty. Maybe we need both and make
them tunable.
The senf::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 senf::PacketRegistryMixin) this
class greatly simplifies implementing the needed table lookups.
*/
......
......@@ -106,6 +106,7 @@ prefix_ bool senf::Packet::operator==(Packet other)
prefix_ void senf::Packet::finalize()
const
{
last(); // Make sure the packet is complete
ptr()->finalize();
}
......
......@@ -263,7 +263,7 @@ senf::ConcretePacket<PacketType>::clone()
// Field access
template <class PacketType>
prefix_ typename senf::ConcretePacket<PacketType>::interpreter::parser *
prefix_ typename senf::ConcretePacket<PacketType>::type::parser *
senf::ConcretePacket<PacketType>::operator->()
const
{
......
This diff is collapsed.
......@@ -164,8 +164,8 @@ BOOST_AUTO_UNIT_TEST(packet)
BOOST_CHECK( packet.factory() == FooPacket::factory() );
senf::Packet::byte data[] = { 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x81, 0x82, 0x83 };
senf::PacketData::byte data[] = { 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x81, 0x82, 0x83 };
BarPacket::createAfter(packet,data);
BOOST_REQUIRE( packet.next() );
......@@ -194,7 +194,7 @@ BOOST_AUTO_UNIT_TEST(packet)
BOOST_AUTO_UNIT_TEST(concretePacket)
{
FooPacket::byte data[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
senf::PacketData::byte data[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
BOOST_CHECK_EQUAL( FooPacket::create().size(), 4u );
BOOST_CHECK_EQUAL( FooPacket::create(FooPacket::noinit).size(), 0u );
......
No preview for this file type
......@@ -85,6 +85,12 @@
</xsl:call-template>
</xsl:template>
<xsl:template match="dl[dt/b/text()='Implementation note:']">
<xsl:call-template name="add-class">
<xsl:with-param name="class">implementation</xsl:with-param>
</xsl:call-template>
</xsl:template>
<xsl:template match="table[descendant::td[@class='memItemLeft']]">
<xsl:call-template name="add-class">
<xsl:with-param name="class">members</xsl:with-param>
......@@ -108,7 +114,7 @@
<xsl:with-param name="class">anchor</xsl:with-param>
</xsl:call-template>
</xsl:template>
<!-- Remove [external] references from the modules page -->
<xsl:template match="div[@id='content2']/ul/li[a/@class='elRef'][a/@doxygen][code/text()='[external]'][not(ul)]">
</xsl:template>
......
......@@ -2,7 +2,7 @@ body {
padding: 0;
margin: 0;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10pt;
font-size: 10pt;
}
#head {
......@@ -21,8 +21,8 @@ body {
}
#title2 {
padding: 0 0 0 42px;
max-width: 62em;
padding: 0 0 0 42px;
max-width: 62em;
margin: 0 10px 0 0;
}
......@@ -40,49 +40,49 @@ body {
margin: 0 10px 0 100px;
padding: 4px 0 0 42px;
height: 18px;
max-width: 62em;
max-width: 62em;
background-color: #EDE497;
color: #726921;
}
#head h2 {
margin: 0;
padding: 0;
font-size: 13px;
margin: 0;
padding: 0;
font-size: 13px;
font-weight: normal;
white-space: nowrap;
}
#head ul {
display: inline; /* fr IE ... */
font-size: 13px;
height: 0px;
margin: 0;
padding: 0;
display: inline; /* fr IE ... */
font-size: 13px;
height: 0px;
margin: 0;
padding: 0;
}
#head li {
list-style-type: none;
margin: 0 0 0 10px;
padding: 0 10px 0 0;
float: right;
border-right: 1px solid #726921;
height: 14px;
list-style-type: none;
margin: 0 0 0 10px;
padding: 0 10px 0 0;
float: right;
border-right: 1px solid #726921;
height: 14px;
}
#head li:first-child {
border-right: none;
padding: 0;
border-right: none;
padding: 0;
}
#head a {
font-weight: normal;
font-weight: normal;
color: #726921;
}
#head a:hover {
background-color: #EDE497;
text-decoration: underline;
background-color: #EDE497;
text-decoration: underline;
}
#search {
......@@ -308,6 +308,11 @@ div.idea {
border-left: 10px solid #AAAAAA;
}
dl.implementation {
color: #666666;
font-size: 9px;
}
table {
width: 100%;
}
......
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