Packets: Extend collection parser documentation
[senf.git] / Packets / Mainpage.dox
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \mainpage The SENF Packet Library
24
25     The SENF Packet library provides facilities to analyze, manipulate and create structured packet
26     oriented data (e.g. network packets).
27
28     \autotoc
29
30     
31     \section packet_intro_arch Overall Architecture
32
33     The Packet library consists of several components:
34     
35     \li The \ref packet_module manages the packet data and provides the framework for handling the
36         chain of packet headers. The visible interface is provided by the Packet class.
37     \li \ref packetparser provides the framework for interpreting packet data. It handles
38         parsing the packet information into meaningful values.
39     \li The \ref protocolbundles provide concrete implementations for interpreting packets of
40         some protocol. The Protocol Bundles are built on top of the basic packet library.
41
42     All these components work together to provide a hopefully simple and intuitive interface to
43     packet parsing and creation.
44
45     \see \ref packet_arch
46
47
48     \section packet_intro_usage Using the packet library
49
50     This chapter discusses the usage of the packet library from a high level view. 
51
52     \see \ref packet_usage 
53
54     
55     \section packet_intro_parser Parsing packet data
56
57     This chapter goes into more detail discussing the usage of packet parsers. 
58     
59     \li categorizing packet parsers
60     \li reading and writing values
61     \li using complex parsers
62
63     \see \ref packetparser
64
65     
66     \section protocolbundles Supported packet types (protocols)
67
68     Each protocol bundle provides a collection of related concrete packet classes for a group of
69     related protocols:
70
71     \li \ref protocolbundle_default : Some basic default protocols: Ethernet, Ip, TCP, UDP
72     \li \ref protocolbundle_mpegdvb : MPEG and DVB protocols
73
74     There are two ways to link with a bundle
75     
76     \li If you only work with known packets which you explicitly reference you may just link with
77         the corresponding library.
78     \li If you need to parse unknown packets and want those to be parsed as complete as possible
79         without explicitly referencing the packet type, you will need to link against the combined
80         object file built for every bundle. This way, all packets defined in the bundle will be
81         included whether they are explicitly referenced or not (and they will all automatically be
82         registered).
83
84     
85     \section packet_intro_new Defining new packet types
86
87     The packet library provides the framework which allows to define arbitrary packet types. There
88     is quite some information needed to completely specify a specific type of paceket.
89
90     \see \ref packet_new
91  */
92
93 /** \page packet_arch Overall Packet library Architecture
94
95     The packet library handles network packets of a large number of protocols. We work with a packet
96     on three levels
97
98     \autotoc
99
100     
101     \section packet_arch_handle The Packet handle
102
103     Whenever we are using a Packet, we are talking about a senf::Packet (or a
104     senf::ConcretePacket). This class is a \e handle referencing an internally managed packet data
105     structure. So even though we pass senf::Packet instances around by value, they work like
106     references. The packet library automatically manages all required memory resources using
107     reference counting. 
108
109     Different Packet handles may really internally share one Packet data structure if they both
110     point to the same packet.
111
112    
113     \section packet_arch_data The Packet as a 'bunch of bytes'
114
115     From the outside, a packet is just a bunch of bytes just as it is read from (or will be
116     written to) the wire. At this low-level view, we can access the data in it's raw form but
117     have no further information about what kind of packet we have.
118
119     The packet library provides a consistent container interface for this representation.
120
121     \code
122     Packet p = ...;
123
124     // Change first byte of packet to 0
125     p.data()[0] = 1u; 
126
127     // Copy packet data into a vector
128     std::vector<char> data (p.data().size());
129     std::copy(p.data().begin(), p.data().end(), data.begin());
130     \endcode
131
132     This type of access is primarily needed when reading or writing packets (e.g. to/from the
133     network).
134
135     \see senf::Packet::data() \n
136         senf::PacketData
137
138     
139     \section packet_arch_chain The Interpreter Chain
140
141     On the next level, the packet is divided into a nested list of sub-packets (or headers) called
142     interpreters. Each senf::Packet handle internally points to an interpreter or header. This
143     allows us to access one and the same packet in different ways. 
144
145     Consider an Ethernet Packet with an IP payload holding a UDP packet. We may reference either the
146     Ethernet packet as a whole or we may reference the IP or UDP interpreters (sub-packets or
147     headers). All handles really refer to the \e same data structure but provide access to a
148     different (sub-)range of the data in the packet.
149
150     We can navigate around this chained structure using appropriate members:
151
152     \code
153     // eth, ip and udp all reference the same internal packet data albeit at different data ranges
154     Packet eth = ...;
155     Packet ip = eth.next();
156     Packet udp = ip.next();
157
158     eth.next() == ip                   // true
159     eth.next().is<IPv4Packet>()        // true
160     eth.next().next() == udp           // true
161     eth.next().is<UDPPacket>()         // false
162     eth.find<UDPPacket>() == udp       // true
163
164     udp.find<EthernetPacket>()         // throws InvalidPacketChainException
165     udp.find<EthernetPacket>(senf::nothrow) // An in-valid() senf::Packet which tests as 'false'
166     udp.find<UDPPacket> == udp         // true
167     udp.first<IPv4Packet>()            // throws InvalidPacketChainException
168
169     udp.prev() == ip                   // true
170     udp.prev<EthernetPacket>()         // throws Inv
171     \endcode
172     
173     \see \ref packet_module
174
175
176     \section packet_arch_parser Parsing specific Protocols
177
178     On the next level, the packet library allows us to parse the individual protocols. This gives us
179     access to the protocol specific data members of a packet and allows us to access or manipulate a
180     packet in a protocol specific way.
181
182     To access this information, we need to use a protocol specific handle, the senf::ConcretePacket
183     which takes as a template argument the specific type of packet to be interpreted. This allows us
184     to easily interpret or create packets. Here an example on how to create a new Etheret / IP / UDP
185     / Payload packet interpreter chain:
186
187     \code
188     // EthernetPacket, IPv4Packet, UDPPacket and DataPacket are typedefs for corresponding
189     // ConcretePacket instantiations
190     senf::EthernetPacket eth      (senf::EthernetPacket::create());
191     senf::IPv4Packet     ip       (senf::IPv4Packet    ::createAfter(eth));
192     senf::UDPPacket      udp      (senf::UDPPacket     ::createAfter(ip));
193     senf::DataPacket     payload  (senf::DataPacket    ::createAfter(udp, 
194                                                                      std::string("Hello, world!")));
195
196     udp->source()      = 2000u;
197     udp->destination() = 2001u;
198     ip->ttl()          = 255u;
199     ip->source()       = senf::INet4Address::from_string("192.168.0.1");
200     ip->destination()  = senf::INet4Address::from_string("192.168.0.2");
201     eth->source()      = senf::MACAddress::from_string("00:11:22:33:44:55");
202     eth->destination() = senf::MACAddress::from_string("00:11:22:33:44:66");
203     
204     eth.finalize();
205     \endcode
206
207     Again, realize, that \a eth, \a ip, \a udp and \a payload share the same internal packet
208     data structure (the respective \c data() members all provide access to the same underlying
209     container however at different byte ranges): The complete packet can be accessed at
210     <tt>eth.data()</tt> whereas <tt>payload.data()</tt> only holds UDP payload (in this case the
211     string "Hello, world!").
212
213     \see \ref packetparser \n
214         \ref protocolbundles
215  */
216
217 /** \page packet_usage Using the packet library
218
219     \autotoc
220
221     \section packet_usage_intro Includes
222
223     To use the library, you need to include the appropriate header files. This will probably happen
224     automatically when including the specific protocol headers. If needed, you may explicitly use
225
226     \code
227     #include "Packets.hh"
228     \endcode
229     
230     explicitly.
231
232     \warning Never include any other Packets library header directly, only include \c
233     Packets.hh or one (or several) protocol headers from the protocol bundles.
234
235     Most every use of the packet library starts with some concrete packet typedef. Some fundamental
236     packet types are provided by \ref protocolbundle_default. 
237
238
239     \section packet_usage_create Creating a new packet
240
241     Building on those packet types, this example will build a complex packet: This will be an
242     Ethernet packet containing an IPv4 UDP packet. We begin by building the raw packet skeleton:
243
244     \code
245     #include "Packets/DefaultBundle/EthernetPacket.hh"
246     #include "Packets/DefaultBundle/IPv4Packet.hh"
247     #include "Packets/DefaultBundle/UDPPacket.hh"
248
249     senf::EthernetPacket eth      (senf::EthernetPacket::create());
250     senf::IPv4Packet     ip       (senf::IPv4Packet    ::createAfter(eth));
251     senf::UDPPacket      udp      (senf::UDPPacket     ::createAfter(ip));
252     senf::DataPacket     payload  (senf::DataPacket    ::createAfter(udp, 
253                                                                      std::string("Hello, world!")));
254     \endcode
255
256     These commands create what is called an interpreter chain. This chain consists of four
257     interpreters. All interpreters reference the same data storage. This data storage is a random
258     access sequence which contains the data bytes of the packet.
259
260     \note The data structures allocated are automatically managed using reference counting. In this
261         example we have four packet references each referencing the same underlying data
262         structure. This data structure will be freed when the last reference to it goes out of
263         scope.
264
265     The packet created above already has the correct UDP payload (The string "Hello, world!")
266     however all protocol fields are empty. We need to set those protocol fields:
267
268     \code
269     udp->source()      = 2000u;
270     udp->destination() = 2001u;
271     ip->ttl()          = 255u;
272     ip->source()       = senf::INet4Address::from_string("192.168.0.1");
273     ip->destination()  = senf::INet4Address::from_string("192.168.0.2");
274     eth->source()      = senf::MACAddress::from_string("00:11:22:33:44:55");
275     eth->destination() = senf::MACAddress::from_string("00:11:22:33:44:66");
276     
277     eth.finalize();
278     \endcode
279
280     As seen above, packet fields are accessed using the <tt>-></tt> operator whereas other packet
281     facilities (like \c finalize()) are directly accessed using the member operator. The field
282     values are simply set using appropriately named accessors. As a last step, the \c finalize()
283     call will update all calculated fields (fields like next-protocol, header or payload length,
284     checksums etc). Now the packet is ready. We may now send it out using a packet socket
285
286     \code
287     senf::PacketSocketHandle sock ("eth0");
288     sock.write(eth.data());
289     \endcode
290
291
292     \section packet_usage_read Reading and parsing packets
293
294     The chain navigation functions are also used to parse a packet. Let's read an Ethernet packet
295     from a packet socket handle:
296     
297     \code
298     senf::PacketSocketHandle sock ("eth0");
299     senf::EthernetPacket packet (senf::EthernetPacket::create(senf::noinit));
300     sock.read(packet.data(),0u);
301     \endcode
302
303     This first creates an uninitialized Ethernet packet and then reads into this packet. We can now
304     parse this packet. Let's find out, whether this is a UDP packet destined to port 2001:
305
306     \code
307     try {
308         senf::UDPPacket udp (packet.find<UDPPacket>());
309         if (udp->destination() == 2001u) {
310             // Voila ...
311         }
312     } catch (senf::TruncatedPacketException &) {
313         std::cerr << "Ooops !! Broken packet received\n";
314     } catch (senf::InvalidPacketChainException &) {
315         std::cerr << "Not a udp packet\n";
316     }
317     \endcode
318
319     TruncatedPacketException is thrown by <tt>udp->destination()</tt> if that field cannot be
320     accessed (that is it would be beyond the data read which means we have read a truncated
321     packet). More generally, whenever a field cannot be accessed because it would be out of bounds
322     of the data read, this exception is generated.
323
324
325     \section packet_usage_container The raw data container
326     
327     Every packet is based internally on a raw data container holding the packet data. This container
328     is accessed via senf::Packet::data() member.
329     
330     This container is a random access container. It can be used like an ordinary STL container and
331     supports all the standard container members.
332
333     \code
334     Packet p = ...;
335
336     // Insert 5 0x01 bytes
337     p.data().insert(p.data().begin()+5, 5, 0x01);
338
339     // Insert data from another container
340     p.data().insert(p.data().end(), other.begin(), other.end());
341
342     // Erase a single byte
343     p.data().erase(p.data().begin()+5);
344
345     // XOR byte 5 with 0xAA
346     p.data()[5] ^= 0xAA;
347     \endcode
348
349     A packet consists of a list of interpreters (packet headers or protocols) which all reference
350     the same data container at different byte ranges. Each packet consists of the protocol header \e
351     plus the packets payload. This means, that the data container ranges of successive packets from
352     a single interpreter chain are nested.
353
354     Example: The packet created above (the Ethernet-IP-UDP packet with payload "Hello, world!") has
355     4 Interpreters: Ethernet, IPv4, UDP and the UDP payload data. The nested data containers lead to
356     the following structure
357
358     \code
359     // The ethernet header has a size of 14 bytes
360     eth.data().begin() + 14 == ip.data().begin()
361     eth.data().end()        == ip.data().end()
362
363     // The IP header has a size of 20 bytes and therefore
364     ip.data().begin()  + 20 == udp.data().begin()
365     ip.data().end()         == udp.data().end()
366
367     // The UDP header has a size of 8 bytes and thus
368     udp.data().begin() +  8 == payload.data().begin()
369     udp.data().end()        == payload.data().end()
370     \endcode
371
372     This nesting will (and must) always hold: The data range of a subsequent packet will always be
373     within the range of it's preceding packet.
374
375     \warning It is forbidden to change the data of a subsequent packet interpreter from the
376         preceding packet even if the data container includes this data. If you do so, you may
377         corrupt the data structure (especially when changing it's size).
378
379     Every operation on a packet is considered to be \e within this packet and \e without and
380     following packet. When inserting or erasing data, the data ranges are all adjusted
381     accordingly. So the following are \e not the same even though \c eth.end(), \c ip.end() and \c
382     udp.end() are identical.
383
384     \code
385     eth.data().insert(eth.data().end(), 5, 0x01);
386     assert(    eth.data().end() == ip.data().end() + 5 
387             && ip.data().end()  == udp.data().end() );
388
389     // Or alternatively: (You could even use eth.data().end() here ... it's the same)
390     ip.data().insert(ip.data().end(), 5, 0x01);
391     assert(    eth.data().end() == ip.data().end()
392             && ip.data().end()  == udp.data().end() + 5 );
393     \endcode
394
395     \warning When accessing the packet data via the container interface, you may easily build
396         invalid packets since the packet will not be validated against it's protocol.
397
398
399     \section packet_usage_fields Field access
400
401     When working with concrete protocols, the packet library provides direct access to all the
402     protocol information.
403
404     \code
405     udp->source()      = 2000u;
406     udp->destination() = 2001u;
407     ip->ttl()          = 255u;
408     ip->source()       = senf::INet4Address::from_string("192.168.0.1");
409     ip->destination()  = senf::INet4Address::from_string("192.168.0.2");
410     eth->source()      = senf::MACAddress::from_string("00:11:22:33:44:55");
411     eth->destination() = senf::MACAddress::from_string("00:11:22:33:44:66");
412     \endcode
413
414     The protocol field members above do \e not return references, they return parser instances.
415     Protocol fields are accessed via parsers. A parser is a very lightweight class which points into
416     the raw packet data and converts between raw data bytes and it's interpreted value: For example
417     a senf::UInt16Parser accesses 2 bytes (in network byte order) and converts them to or from a 16
418     bit integer. There are a few properties about parsers which need to be understood:
419
420     \li Parsers are created only temporarily when needed. They are created when accessing a protocol
421         field and are returned by value.
422
423     \li A parser never contains a value itself, it just references a packets data container.
424
425     \li Parsers can be built using other parsers and may have members which return further parsers.
426
427     The top-level interface to a packets protocol fields is provided by a protocol parser. This
428     protocol parser is a composite parser which has members to access the protocol fields (compare
429     with the example code above). Some protocol fields may be more complex than a simple value. In
430     this case, those accessors may return other composite parsers or collection parsers. Ultimately,
431     a value parser will be returned.
432
433     The simple value parsers which return plain values (integer numbers, network addresses etc) can
434     be used like those values and can also be assigned corresponding values. More complex parsers
435     don't allow simple assignment. However, they can always be copied from another parser <em>of the
436     same type</em> using the generalized parser assignment. This type of assignment also works for
437     simple parsers and is then identical to a normal assignment.
438
439     \code
440     // Copy the complete udp parser from udp packet 2 to packet 1
441     udp1.parser() << udp2.parser();
442     \endcode
443
444     Additionally, the parsers have a parser specific API which allows to manipulate or query the
445     value. 
446
447     This is a very abstract description of the parser structure. For a more concrete description, we
448     need to differentiate between the different parser types
449
450     \subsection packet_usage_fields_value Simple fields (Value parsers)
451
452     We have already seen value parsers: These are the lowest level building blocks witch parse
453     numbers, addresses etc. They return some type of value and can be assigned such a value. More
454     formally, they have a \c value_type typedef member which gives the type of value they accept and
455     they have an overloaded \c value() member which is used to read or set the value. Some parsers
456     have additional functionality: The numeric parser for Example provide conversion and arithmetic
457     operators so they can be used like a numeric value.
458
459     If you have a value parser \c valueParser with type \c ValueParser, the following will always be
460     valid:
461     \code
462     // You can read the value and assign it to a variable of the corresponding value_type
463     ValueParser::value_type v (valueParser.value());
464
465     // You can assign that value to the parser
466     valueParser.value(v);
467
468     // The assignment can also be done using the generic parser assignment
469     valueParser << v;
470     \endcode
471
472
473     \subsection packet_usage_fields_composite Composite and protocol parsers
474
475     A composite parser is a parser which just combines several other parsers into a structure: For
476     example, the senf::EthernetPacketParser has members \c destination(), \c source() and \c
477     type_length(). Those members return parsers again (in this case value parsers) to access the
478     protocol fields.
479
480     Composite parsers can be nested; A composite parser may be returned by another composite
481     parser. The protocol parser is a composite parser which defines the field for a specific
482     protocol header like Ethernet.
483
484     \subsection packet_usage_fields_collection Collection parsers
485
486     Besides simple composites, the packet library has support for more complex collections. 
487
488     \li The senf::ArrayParser allows to repeat an arbitrary parser a fixed number of times.
489     \li senf::VectorParser and senf::ListParser are two different types of lists with variable
490         number of elements
491     \li The senf::VariantParser is a discriminated union: It will select one of several parsers
492         depending on the value of a discriminant.
493
494
495     \subsubsection packet_usage_collection_vector Vector and List Parsers
496
497     Remember, that a parser does \e not contain any data: It only points into the raw data
498     container. This is also true for the collection parsers. VectorParser and ListParser provide an
499     interface which looks like an STL container to access a sequence of elements.
500
501     We will use an \c MLDv2QueryPacket as an example (see <a
502     href="http://tools.ietf.org/html/rfc3810#section-5">RFC 3810</a>). Here an excerpt of the
503     relevant fields:
504
505     <table class="fields">
506     <tr><td>nrOfSources</td><td>Integer</td><td>Number of multicast sources in this packet</td></tr>
507     <tr><td>sources</td><td>Vector of IPv6 Addresses</td><td>Multicast sources</td></tr>
508     </table>
509
510     To demonstrate nested collections, we use the \c MLDv2ReportPacket as an example. The relevant
511     fields of this packet are;
512     
513     <table class="fields">
514     <tr><td>nrOfRecords</td><td>Integer</td><td>Number of multicast address records</td></tr>
515     <tr><td>records</td><td>List of Records</td><td>List of multicast groups and sources</td></tr>
516     </table>
517
518     Each Record is a composite with the following relevant fields:
519
520     <table class="fields">
521     <tr><td>nrSources</td><td>Integer</td><td>Number of sources in this record</td></tr>
522     <tr><td>sources</td><td>Vector of IPv6 Addresses</td><td>Multicast sources</td></tr>
523     </table>
524     
525     The first example will iterate over the sources in a \c MLDv2QueryPacket:
526
527     \code
528     MLDv2QueryPacket mld = ...;
529
530     // Instantiate a collection wrapper for the source list
531     MLDv2QueryPacket::Parser::sources_t::container sources (mld->sources());
532
533     // Iterate over all the addresses in that list
534     for (MLDv2QueryPacket::Parser::sources_t::container::iterator i (sources.begin()); 
535          i != sources.end(); ++i)
536         std::cout << *i << std::endl;
537     \endcode
538
539     Beside other fields, the MLDv2Query consists of a list of source addresses. The \c sources()
540     member returns a VectorParser for these addresses. The collection parsers can only be accessed
541     completely using a container wrapper. The container wrapper type is available as the \c
542     container member of the collection parser, here it is \c
543     MLDv2QueryPacket::Parser::sources_t::container.
544
545     Using this wrapper, we can not only read the data, we can also manipulate the source list. Here
546     we copy a list of addresses from an \c std::vector into the packet:
547
548     \code
549     std::vector<senf::INet6Address> addrs (...);
550
551     sources.resize(addrs.size());
552     std::copy(addrs.begin(), addrs.end(), sources.begin())
553     \endcode
554
555     Collection parsers may be nested. To access a nested collection parser, a container wrapper must
556     be allocated for each level. An MLD Report (which is a composite parser) includes a list of
557     multicast address records called \c records(). Each record is again a composite which contains a
558     list of sources called \c sources():
559
560     \code
561     MLDv2ReportPacket report = ...;
562
563     // Instantiate a collection wrapper for the list of records:
564     MLDv2ReportPacket::Parser::records_t::container records (report->records());
565
566     // Iterate over the multicast address records
567     for (MLDv2ReportPacket::Parser::records_t::container::iterator i (records.begin());
568          i != records.end(); ++i) {
569         // Allocate a collection wrapper for the multicast address record
570         typedef MLDv2ReportPackte::Parser::records_t::value_type::sources_t Sources;
571         Sources::container sources (i->sources());
572         
573         // Iterate over the sources in this record
574         for (Sources::container::iterator i (sources.begin());
575              i != sources.end(); ++i)
576             std::cout << *i << std::endl;
577     }
578     \endcode
579
580     In this example we also see how to find the type of a parser or container wrapper.
581     \li Composite parsers have typedefs for each their fields with a \c _t postfix
582     \li The vector or list parsers have a \c value_type typedef which gives the type of the
583         element.
584
585     By traversing this hierarchical structure, the types of all the fields can be found.
586
587     The container wrapper is only temporary (even though it has a longer lifetime than a
588     parser). Any change made to the packet not via the collection wrapper has the potential to
589     invalidate the wrapper if it changes the packets size.
590
591     \see 
592         senf::VectorParser_Container Interface of the vector parser container wrapper \n
593         senf::ListParser_Container Interface of the list parser container wrapper
594     
595
596     \subsubsection packet_usage_collection_variant The Variant Parser
597
598     The senf::VariantParser is a discriminated union of parsers. It is also used for optional fields
599     (using senf::VoidPacketParser as one possible variant which is a parser parsing nothing).  A
600     senf::VariantParser is not really a collection in the strict sense: It only ever contains one
601     element, the \e type of which is determined by the discriminant.
602
603     For Example, we look at the DTCP HELLO Packet as defined in the UDLR Protocol (see <a
604     href="http://tools.ietf.org/html/rfc3077">RFC 3077</a>)
605
606     \code
607     DTCPHelloPacket hello (...);
608
609     if (hello->ipVersion() == 4) {
610         typedef DTCPHelloPacket::Parser::v4fbipList_t FBIPList;
611         FBIPList::container fbips (hello->v4fbipList());
612         for (FBIPList::container::iterator i (fbips.begin()); i != fbips.end(); ++i)
613             std::cout << *i << std::endl;
614     }
615     else { // if (hello->ipVersion() == 6)
616         typedef DTCPHelloPacket::Parser::v6fbipList_t FBIPList;
617         FBIPList::container fbips (hello->v6fbipList());
618         for (FBIPList::container::iterator i (fbips.begin()); i != fbips.end(); ++i)
619             std::cout << *i << std::endl;
620     }
621     \endcode
622
623     This packet has a field \c ipVersion() which has a value of 4 or 6. Depending on the version,
624     the packet contains a list of IPv4 or IPv6 addresses. Only one of the fields \c v4fbipList() and
625     \c v6fbipList() is available at a time. Which one is decided by the value of \c
626     ipVersion(). Trying to access the wrong one will provoke undefined behavior.
627
628     Here we have used the variants discriminant (the \c ipVersion() field) to select, which field to
629     parse. More generically, every variant field should have a corresponding member to test for it's
630     existence:
631     \code
632     if (hello->has_v4fbipList()) {
633         ...
634     }
635     else { // if (hello->has_v6fbipList())
636         ...
637     }
638     \endcode
639
640     A variant can have more than 2 possible types and you can be sure, that exactly one type will be
641     accessible at any time.
642
643     It is not possible to change a variant by simply changing the discriminant:
644     \code
645     // INVALID CODE:
646     hello->ipVersion() = 6;
647     \endcode
648     Instead, for each variant field there is a special member which switches the variant to that
649     type. After switching the type, the field will be in it's initialized (that is mostly zero)
650     state.
651     \code
652     std::vector<senf::INet6Address> addrs (...);
653
654     // Initialize the IPv6 list
655     hello->init_v6fbipList();
656
657     // Copy values into that list
658     DTCPHelloPacket::Parser::v6fbipList_t::container fbips (hello->v6fbipList());
659     fbips.resize(addrs.size());
660     std::copy(addrs.begin(), addrs.end(), fbips.begin());
661     \endcode
662     
663     \note Here we have documented the default variant interface as it is preferred. It is possible
664         to define variants in a different way giving other names to the special members (\c has_\e
665         name or \c init_\e name etc.). This must be documented with the composite or protocol parser
666         which defines the variant.
667  */
668
669 /** \page packet_new Defining new Packet types
670
671     Each packet is specified by the following two components:
672
673     \li A protocol parser which defines the protocol specific fields
674     \li A packet type class which is a policy class defining the packet
675
676     \autotoc
677
678     \see <a href="../../../HowTos/NewPacket/doc/html/index.html">NewPacket HowTo</a>
679
680     \section packet_new_parser The protocol parser
681
682     The protocol parser is simply a composite parser. It defines all the protocol
683     fields. Additionally, the protocol parser may have additional members which will then be
684     accessible via the \c -> operator of the packet. Possibilities here are e.g. checksum
685     calculation and validation, packet validation as a whole and so on.
686
687     Defining a protocol parser is quite simple:
688     \code
689     struct EthernetPacketParser : public PacketParserBase
690     {
691     #   include SENF_FIXED_PARSER()
692
693         SENF_PARSER_FIELD( destination, MACAddressParser    );
694         SENF_PARSER_FIELD( source,      MACAddressParser    );
695         SENF_PARSER_FIELD( type_length, UInt16Parser );
696
697         SENF_PARSER_FINALIZE(EthernetPacketParser);
698     };
699     \endcode
700     
701     There are a lot of other possibilities to define fields. See \ref packetparsermacros for a
702     detailed description of the macro language which is used to define composite parsers.
703
704     \see 
705         \ref packetparsermacros
706
707     \section packet_new_type The packet type policy class
708
709     This is a class which provides all the information needed to integrate the new packet type into
710     the packet library:
711
712     \li It provides the type of the protocol parser to use
713     \li It provides information on how the next protocol can be found and where the payload resides
714         in this packet
715     \li It provides methods to initialize a new packet and get information about the packet size
716
717     All this information is provided via static or typedef members. 
718
719     \code
720     struct EthernetPacketType
721         : public PacketTypeBase,
722           public PacketTypeMixin<EthernetPacketType, EtherTypes>
723     {
724         typedef PacketTypeMixin<EthernetPacketType, EtherTypes> mixin;
725         typedef ConcretePacket<EthernetPacketType> packet;
726         typedef EthernetPacketParser parser;
727
728         using mixin::nextPacketRange;
729         using mixin::initSize;
730         using mixin::init;
731
732         static factory_t nextPacketType(packet p);
733         static void dump(packet p, std::ostream & os);
734         static void finalize(packet p);
735     };
736
737     typedef EthernetPacketType::packet EthernetPacket;
738     \endcode
739
740     The definition of senf::EthernetPacket is quite straight forward. This template works for most
741     simple packet types.
742
743     \see \ref senf::PacketTypeMixin \n
744         \ref senf::PacketTypeBase \n
745         \ref senf::PacketRegistry
746  */
747
748 \f
749 // Local Variables:
750 // mode: c++
751 // fill-column: 100
752 // c-file-style: "senf"
753 // indent-tabs-mode: nil
754 // ispell-local-dictionary: "american"
755 // mode: auto-fill
756 // compile-command: "scons -u doc"
757 // End:
758