X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Packets%2FMainpage.dox;h=f5416601f96483ab6af6cdb1fb1d1cd605095219;hb=81ffa1c459b96dd44472bcef37e1e373934ee138;hp=44ba81f4586e3a3216f0505e10efe4e3f93747d7;hpb=85ab07d100a382467a42e19d741d403a7a96c951;p=senf.git diff --git a/Packets/Mainpage.dox b/Packets/Mainpage.dox index 44ba81f..f541660 100644 --- a/Packets/Mainpage.dox +++ b/Packets/Mainpage.dox @@ -2,104 +2,151 @@ \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 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. - - - 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). - - 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. - - \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 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. + + All these components work together to provide a hopefully simple and intuitive interface to + 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 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!"))); + \endcode + + These commands create what is called an interpreter chain. This chain consists of four + interpreters. All interpreters reference the same data storage. This data storage is a random + access sequence which contains the data bytes of the packet. + + \note The data structures allocated are automatically managed using reference counting. In this + example we have four packet references each referencing the same underlying data + structure. This data structure will be freed when the last reference to it goes out of + scope. + + The packet created above already has the correct payload however all protocol fields are + 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"); + + eth.finalize(); // (*) + \endcode + + As seen above, packet fields are accessed using the -> operator whereas other packet + facilities (like \c finalize()) are directly accessed using the member operator. The field + values are simple set using appropriately named accessors. As a last step, the \c finalize() + call will update all calculated fields (fields like next-protocol, header or payload length, + 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()); + \endcode + + The packet library also provides lot's of facilities to navigate the packet chain: + + \code + eth.next() == ip; // true + eth.next().is(); // true + eth.next().next() == udp; // true + eth.next().is(); // false + eth.next() == udp; // true + + udp.next(); // throws InvalidPacketChainException + udp.next(senf::nothrow); // a senf::Packet testing as false + udp.findNext == udp; // true + udp.first() == ip; // true + + udp.prev() == ip; // true + udp.prev() == eth // true + \endcode + + ... and so on. It is therefore not necessary to stash away a reference for every interpreter (as + each of the sub-packets are called) as long as at least one reference is available. + + These chain navigation functions are also used to parse a packet. Let's read an Ethernet packet + from a packet socket handle: + + \code + 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(senf::nothrow)); + if (udp && udp->destination() == 2001u) { + // Voila ... + } + } catch (senf::TruncatedPacketException const &) { + std::cerr << "Ooops !! Broken packet received ...\n" + } + \endcode + + TruncatedPacketException is thrown by udp->destination() if that field cannot be + accessed. More generally, whenever a field cannot be accessed because it would be out of bounds + of the data read, this exception is generated. + + This is only a very short introduction to the library to give a feel for the implementation. For + a detailed discussion see the respective reference documentation. + */ + +/** \defgroup protocolbundles Protocol Bundles + + Each protocol bundle provides a collection of related concrete packet classes for a group of + related protocols: + + \li DefaultBundle: Some basic + default protocols: Ethernet, Ip, TCP, UDP + \li MPEGDVBBundle: MPEG and DVB + protocols + + There are two ways to link with a bundle + + \li If you only work with known packets which you explicitly reference you may just link with + the corresponding library. + \li If you need to parse unknown packets and want those to be parsed as complete as possible + without explicitly referencing the packet type, you will need to link against the combined + object file built for every bundle. This way, all packets defined in the bundle will be + included whether they are explicitly referenced or not (and they will all automatically be + registered). */ @@ -109,6 +156,7 @@ // c-file-style: "senf" // indent-tabs-mode: nil // ispell-local-dictionary: "american" -// mode: flyspell // mode: auto-fill +// compile-command: "scons -u doc" // End: +