added some documentation
[senf.git] / Packets / Mainpage.dox
index 9eaad45..7482b9f 100644 (file)
@@ -28,7 +28,8 @@
     \autotoc
 
     
-    \section packet_intro_arch Overall Architecture
+    \section packet_intro_arch Introduction
+    \seechapter \ref packet_arch
 
     The Packet library consists of several components:
     
     All these components work together to provide a hopefully simple and intuitive interface to
     packet parsing and creation.
 
-    \see \ref packet_arch
 
-
-    \section packet_intro_usage Using the packet library
+    \section packet_intro_usage Tutorial
+    \seechapter \ref packet_usage 
 
     This chapter discusses the usage of the packet library from a high level view. 
 
-    \see \ref packet_usage 
-
     
-    \section packet_intro_parser Parsing packet data
+    \section packet_intro_api The packet API
 
-    This chapter goes into more detail discussing the usage of packet parsers. 
-    
-    \li categorizing packet parsers
-    \li reading and writing values
-    \li using complex parsers
+    The packet library API is divided into three areas
 
-    \see \ref packetparser
+    \li the \ref senf::PacketData API for accessing the raw data container
+    \li the packet interpreter chain providing \ref packet_module
+    \li and \ref packetparser which provides access to protocol specific packet fields.
 
-    
+   
     \section protocolbundles Supported packet types (protocols)
 
     Each protocol bundle provides a collection of related concrete packet classes for a group of
@@ -70,6 +66,7 @@
 
     \li \ref protocolbundle_default : Some basic default protocols: Ethernet, Ip, TCP, UDP
     \li \ref protocolbundle_mpegdvb : MPEG and DVB protocols
+    \li \ref protocolbundle_80211 : 802.11 protocols
 
     There are two ways to link with a bundle
     
 
     
     \section packet_intro_new Defining new packet types
+    \seechapter \ref packet_new
 
     The packet library provides the framework which allows to define arbitrary packet types. There
-    is quite some information needed to completely specify a specific type of paceket.
+    is quite some information needed to completely specify a specific type of packet.
 
-    \see \ref packet_new
  */
 
 /** \page packet_arch Overall Packet library Architecture
     udp.first<IPv4Packet>()            // throws InvalidPacketChainException
 
     udp.prev() == ip                   // true
-    udp.prev<EthernetPacket>()         // throws Inv
+    udp.prev<EthernetPacket>()         // throws InvalidPacketChainException
     \endcode
     
     \see \ref packet_module
 
     To access this information, we need to use a protocol specific handle, the senf::ConcretePacket
     which takes as a template argument the specific type of packet to be interpreted. This allows us
-    to easily interpret or create packets. Here an example on how to create a new Etheret / IP / UDP
+    to easily interpret or create packets. Here an example on how to create a new Ethernet / IP / UDP
     / Payload packet interpreter chain:
 
     \code
     eth->source()      = senf::MACAddress::from_string("00:11:22:33:44:55");
     eth->destination() = senf::MACAddress::from_string("00:11:22:33:44:66");
     
-    eth.finalize();
+    eth.finalizeAll();
     \endcode
 
     Again, realize, that \a eth, \a ip, \a udp and \a payload share the same internal packet
     eth->source()      = senf::MACAddress::from_string("00:11:22:33:44:55");
     eth->destination() = senf::MACAddress::from_string("00:11:22:33:44:66");
     
-    eth.finalize();
+    eth.finalizeAll();
     \endcode
 
     As seen above, packet fields are accessed using the <tt>-></tt> operator whereas other packet
-    facilities (like \c finalize()) are directly accessed using the member operator. The field
-    values are simply set using appropriately named accessors. As a last step, the \c finalize()
+    facilities (like \c finalizeAll()) are directly accessed using the member operator. The field
+    values are simply set using appropriately named accessors. As a last step, the \c finalizeAll()
     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
 
         invalid packets since the packet will not be validated against it's protocol.
 
 
-    \section packet_usage_fields Protocol fields
+    \section packet_usage_fields Field access
 
     When working with concrete protocols, the packet library provides direct access to all the
     protocol information.
     This is a very abstract description of the parser structure. For a more concrete description, we
     need to differentiate between the different parser types
 
-    \subsection packet_usage_fields_value Value parsers
+    \subsection packet_usage_fields_value Simple fields (Value parsers)
 
     We have already seen value parsers: These are the lowest level building blocks witch parse
     numbers, addresses etc. They return some type of value and can be assigned such a value. More
 
     Remember, that a parser does \e not contain any data: It only points into the raw data
     container. This is also true for the collection parsers. VectorParser and ListParser provide an
-    interface which looks like an STL container to access the elements.
+    interface which looks like an STL container to access a sequence of elements.
+
+    We will use an \c MLDv2QueryPacket as an example (see <a
+    href="http://tools.ietf.org/html/rfc3810#section-5">RFC 3810</a>). Here an excerpt of the
+    relevant fields:
 
-    We will use an MLDv2 Query as an example (see <a
-    href="http://tools.ietf.org/html/rfc3810#section-5">RFC 3810</a>).
+    <table class="fields">
+    <tr><td>nrOfSources</td><td>Integer</td><td>Number of multicast sources in this packet</td></tr>
+    <tr><td>sources</td><td>Vector of IPv6 Addresses</td><td>Multicast sources</td></tr>
+    </table>
+
+    To demonstrate nested collections, we use the \c MLDv2ReportPacket as an example. The relevant
+    fields of this packet are;
+    
+    <table class="fields">
+    <tr><td>nrOfRecords</td><td>Integer</td><td>Number of multicast address records</td></tr>
+    <tr><td>records</td><td>List of Records</td><td>List of multicast groups and sources</td></tr>
+    </table>
+
+    Each Record is a composite with the following relevant fields:
+
+    <table class="fields">
+    <tr><td>nrOfSources</td><td>Integer</td><td>Number of sources in this record</td></tr>
+    <tr><td>sources</td><td>Vector of IPv6 Addresses</td><td>Multicast sources</td></tr>
+    </table>
+    
+    The first example will iterate over the sources in a \c MLDv2QueryPacket:
 
     \code
     MLDv2QueryPacket mld = ...;
 
     Beside other fields, the MLDv2Query consists of a list of source addresses. The \c sources()
     member returns a VectorParser for these addresses. The collection parsers can only be accessed
-    completely using a container wrapper. This is, what we do in above example.
+    completely using a container wrapper. The container wrapper type is available as the \c
+    container member of the collection parser, here it is \c
+    MLDv2QueryPacket::Parser::sources_t::container.
 
-    The wrapper can also be used to manipulate that list. Here we copy a list of addresses from an
-    \c std::vector into the packet:
+    Using this wrapper, we can not only read the data, we can also manipulate the source list. Here
+    we copy a list of addresses from an \c std::vector into the packet:
 
     \code
     std::vector<senf::INet6Address> addrs (...);
     std::copy(addrs.begin(), addrs.end(), sources.begin())
     \endcode
 
-    Collection parsers may also be nested. To access a nested collection parser, such a container
-    wrapper should be allocated for each level. An MLD Report (which is a composite parser) includes
-    a list of multicast address records called \c records(). Each record is again a composite which
-    contains a list of sources called \c sources():
+    Collection parsers may be nested. To access a nested collection parser, a container wrapper must
+    be allocated for each level. An MLD Report (which is a composite parser) includes a list of
+    multicast address records called \c records(). Each record is again a composite which contains a
+    list of sources called \c sources():
 
     \code
     MLDv2ReportPacket report = ...;
     for (MLDv2ReportPacket::Parser::records_t::container::iterator i (records.begin());
          i != records.end(); ++i) {
         // Allocate a collection wrapper for the multicast address record
-        typedef MLDv2ReportPackte::Parser::records_t::value_type::sources_t Sources;
+        typedef MLDv2ReportPacket::Parser::records_t::value_type::sources_t Sources;
         Sources::container sources (i->sources());
         
         // Iterate over the sources in this record
         to define variants in a different way giving other names to the special members (\c has_\e
         name or \c init_\e name etc.). This must be documented with the composite or protocol parser
         which defines the variant.
+
+    \section packet_usage_annotation Annotations
+
+    Sometimes we need to store additional data with a packet. Data, which is not part of the packet
+    itself but gives us some information about the packet: A timestamp, the interface the packet was
+    received on or other processing related information.
+
+    This type of information can be stored using the annotation interface. The following example
+    will read packet data and will store the read timestamp as a packet annotation.
+
+    \code
+    struct Timestamp {
+        senf::ClockService::clock_t value;
+    };
+
+    senf::EthernetPacket packet (senf::EthernetPacket::create(senf::noinit));
+    sock.read(packet.data(), 0u);
+    packet.annotation<Timestamp>().value = senf::ClockService::now();
+    \endcode
+
+    In the same way, the annotation can be used later
+
+    \code
+    if (senf::ClockService::now() - packet.annotation<Timestamp>().value 
+            > senf::ClockService::seconds(1)) {
+        // Ouch ... this packet is to old
+        // ...
+    }
+    \endcode
+
+    It is very important to define a specific structure (or class or enum) type for each type of
+    annotation. \e Never directly store a fundamental type as an annotation: The name of the type is
+    used to look up the annotation, so you can store only one annotation for each built-in type. \c
+    typedef does not help since \c typedef does not introduce new type names, it only defines an
+    alias.
+
+    Of course, the annotation structure can be arbitrary. However, one very important caveat: If the
+    annotation is not a POD type, it needs to inherit from senf::ComplexAnnotation. A type is POD,
+    if it is really just a bunch of bytes: No (non-static) members, no constructor or destructor and
+    no base classes and all it's members must be POD too. So the following annotation is complex
+    since \c std::string is not POD
+
+    \code
+    struct ReadInfo : senf::ComplexAnnotation
+    {
+        std::string interface;
+        senf::ClockService::clock_t timestamp;
+    };
+
+    // ...
+
+    packet.annotation<ReadInfo>().interface = "eth0";
+    packet.annotation<ReadInfo>().timestamp = senf::ClockService::now();
+
+    // Or store a reference to the annotation for easier access
+
+    ReadInfo & info (packet.annotation<ReadInfo>());
+    
+    if (info.interface == "eth0") {
+        // ...
+    }
+    \endcode
+
+    Every annotation is automatically default-initialized, there is no way to query, whether a
+    packet holds a specific annotation -- every packet conceptually always holds all annotations.
+
+    You should use annotations economically: Every annotation type used in your program will
+    allocate an annotation slot in \e all packet data structures. So don't use hundreds of different
+    annotation types if this is not really necessary: Reuse annotation types where possible or
+    aggregate data into larger annotation structures. The best solution is to use annotations only
+    for a small number of packet specific informations. If you really need to manage a train-load of
+    data together with the packet consider some other way (e.g. place the packet into another class
+    which holds that data).
+
+    \see senf::Packet::annotation()
  */
 
 /** \page packet_new Defining new Packet types
     The definition of senf::EthernetPacket is quite straight forward. This template works for most
     simple packet types.
 
-    \see \ref senf::PacletTypeMixin
-        \ref senf::PacketTypeBase
+    \see \ref senf::PacketTypeMixin \n
+        \ref senf::PacketTypeBase \n
         \ref senf::PacketRegistry
  */