X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Packets%2FMainpage.dox;h=308d9ac404c9f28f29e1e90c5dcc2b24546180b5;hb=5443435c4c2b6e4386c5334b5b8358273f2bae93;hp=9eaad455170935eac25062a3f74868142c525074;hpb=7baaacae27c02c86ceda5c7ee41d3172d1e23ffa;p=senf.git diff --git a/Packets/Mainpage.dox b/Packets/Mainpage.dox index 9eaad45..308d9ac 100644 --- a/Packets/Mainpage.dox +++ b/Packets/Mainpage.dox @@ -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: @@ -42,27 +43,22 @@ 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,8 @@ \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 + \li \ref protocolbundle_80221 : 802.21 protocols There are two ways to link with a bundle @@ -83,11 +81,11 @@ \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 @@ -121,7 +119,7 @@ \code Packet p = ...; - // Change first byte of packet to 0 + // Change first byte of packet to 1 p.data()[0] = 1u; // Copy packet data into a vector @@ -167,7 +165,7 @@ udp.first() // throws InvalidPacketChainException udp.prev() == ip // true - udp.prev() // throws Inv + udp.prev() // throws InvalidPacketChainException \endcode \see \ref packet_module @@ -181,7 +179,7 @@ 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 @@ -201,7 +199,7 @@ 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 @@ -274,12 +272,12 @@ 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 -> 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 @@ -396,7 +394,7 @@ 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. @@ -447,7 +445,7 @@ 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 @@ -496,10 +494,33 @@ 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 RFC 3810). Here an excerpt of the + relevant fields: - We will use an MLDv2 Query as an example (see RFC 3810). + + + +
nrOfSourcesIntegerNumber of multicast sources in this packet
sourcesVector of IPv6 AddressesMulticast sources
+ + To demonstrate nested collections, we use the \c MLDv2ReportPacket as an example. The relevant + fields of this packet are; + + + + +
nrOfRecordsIntegerNumber of multicast address records
recordsList of RecordsList of multicast groups and sources
+ + Each Record is a composite with the following relevant fields: + + + + +
nrOfSourcesIntegerNumber of sources in this record
sourcesVector of IPv6 AddressesMulticast sources
+ + The first example will iterate over the sources in a \c MLDv2QueryPacket: \code MLDv2QueryPacket mld = ...; @@ -515,10 +536,12 @@ 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 addrs (...); @@ -527,10 +550,10 @@ 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 = ...; @@ -542,7 +565,7 @@ 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 @@ -564,8 +587,8 @@ invalidate the wrapper if it changes the packets size. \see - senf::VectorParser_Container Interface of the vector parser container wrapper \n - senf::ListParser_Container Interface of the list parser container wrapper + senf::VectorParser / senf::VectorParser_Container Interface of the vector parser \n + senf::ListParser / senf::ListParser_Container Interface of the list parser \subsubsection packet_usage_collection_variant The Variant Parser @@ -639,6 +662,81 @@ 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().value = senf::ClockService::now(); + \endcode + + In the same way, the annotation can be used later + + \code + if (senf::ClockService::now() - packet.annotation().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().interface = "eth0"; + packet.annotation().timestamp = senf::ClockService::now(); + + // Or store a reference to the annotation for easier access + + ReadInfo & info (packet.annotation()); + + 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 @@ -715,8 +813,8 @@ 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 */