HowTows/NewPacket: Fix howto to be less focused on GRE
[senf.git] / HowTos / NewPacket / Mainpage.dox
1 // $Id$
2 //
3 // Copyright (C) 2008
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 Defining and using a new 'libPacket' Packet Type 
24
25     This howto will introduce the facilities needed to define a new packet type. As example, the
26     \c GREPacket type is defined. 
27
28     \autotoc
29
30
31     \section howto_newpacket_overview Overview
32
33     How is a new packet type defined? Or more basically: How are packets defined in the packet
34     library at all?
35
36     In the packet library, there are two basic packet representations: There is the generic packet
37     senf::Packet. This representation does not know anything about the type of packet or any fields
38     or properties. It really only is a bunch of bytes. Possibly there is a preceding packet (header)
39     or a following one, but that is all, a senf::Packet knows.
40
41     However, this is not all. There is a second representation: senf::ConcretePacket. This
42     representation derives from senf::Packet and adds information about the packet type: Which
43     fields it has, maybe some invariants or packet specific operations and so on. This howto is
44     concerned with this representation.
45
46     A concrete packet type in senf provides a lot of detailed information about a specific type of
47     packet:
48     \li It provides access to the packets fields
49     \li It may provide additional packet specific functions (e.g. calculating or validating a
50         checksum)
51     \li It provides information on the nesting of packets
52     \li It implements packet invariants
53
54     To define a new packet type, we need to implement to classes which together provide all this
55     information: 
56     \li a \e parser (a class derived from senf::PacketParserBase). This class defines the data
57         fields of the packet header and may provide also additional packet specific functionality.
58     \li a \e packet \e type (a class derived from senf::PacketTypeBase). This class defines, how
59         packets are nested and how to initialize and maintain invariants.
60
61     This howto will introduce how to define these classes using GRE as an example.
62
63     \section howto_newpacket_gre GRE Introduction
64
65     Before we start with the implementation, we begin with introducing the GRE packet. We will need
66     this information later in the implementation. Some decisions can also be taken now by just
67     looking at the packet specification:
68     \li What kind of parser is needed for this packet type (fixed size or variable sized).
69     \li Whether the packet has another packet as payload (a nested packet) and how the type of this
70         payload is found (whether a registry is used and if yes, which).
71
72     The GRE packet is defined in <a href="http://tools.ietf.org/html/rfc2784">RFC 2784</a>. In
73     Section 2.1 we find the header layout:
74
75     <pre>
76      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
77     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
78     |C|       Reserved0       | Ver |         Protocol Type         |
79     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
80     |      Checksum (optional)      |       Reserved1 (Optional)    |
81     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
82     </pre>
83
84     This header is followed by the payload data.
85
86     Using this protocol definition, we can decide the first important question: Whether the packet
87     header is fixed size or dynamically sized. As we see above, the header incorporates optional
88     fields. Therefore it must be dynamically sized. The RFC further details, that if the \a Checksum
89     \a Present bit \a C is set, both \a Checksum and \a Reserved1 are present, otherwise they must
90     both be omitted.
91
92     Another information we take from the RFC is, that the \a Protocol \a Type is used to define the
93     type of payload which directly follows the GRE header. This value is an <a
94     href="http://www.iana.org/assignments/ethernet-numbers">ETHERTYPE</a> value. To allow the packet
95     library to automatically parse the GRE payload data, we need to tell the packet library which
96     ETHERTYPE represents which packet type. This association already exists in form of the
97     senf::EtherTypes registry. Our GRE packet will therefore utilize this registry.
98
99     To summarize, we have gathered the following information:
100
101     \li The GRE packet header is a dynamically sized header.
102     \li The GRE packet header utilizes the senf::EtherTypes registry for next-header selection
103
104
105     \section howto_newpacket_parser Implementing the packet parser
106
107     The next step in creating a new packet type is to implement the parser. The parser is
108     responsible for turning a bunch of bytes into an interpreted header with specific fields.  A
109     parser instance is constructed with an iterator (pointer) to the first byte to be interpreted
110     (the first byte of the packet data) and provides member functions to access the header
111     fields. You can implement these members manually but the SENF library provides a large set of
112     helper macros which simplify this task considerably.
113
114     \subsection howto_newpacket_parser_skeleton The PacketParser skeleton
115
116     \code
117     #include <senf/Packets.hh>
118
119     struct GREPacketParser : public senf::PacketParserBase
120     {
121     #   include SENF_PARSER()
122
123         // Define fields
124
125         SENF_PARSER_FINALIZE(GREPacketParser);
126     };
127     \endcode
128
129     This is the standard skeleton of any parser class: We need to inherit senf::PacketParserBase and
130     start out by including either \ref SENF_PARSER() or \ref SENF_FIXED_PARSER(). Which, depends on
131     whether we define a fixed size or a dynamically sized parser. As \c GREPacketParser is
132     dynamically sized, we include \ref SENF_PARSER().
133
134     The following section will define all the fields. We will come back to this later.
135
136     After the fields are defined, we need to call the \ref SENF_PARSER_FINALIZE() macro to close of
137     the parser definition. This call takes the name of the parser being defined as it's sole
138     argument.
139
140     This is already a valid parser, albeit not a very usable one since it defines no fields. We now
141     go back to define the parser fields and begin with the simple part: Those fields which are
142     always present.
143
144
145     \subsection howto_newpacket_parser_simple Simple field definitions
146
147     Packet parser fields are defined utilizing special \ref packetpasermacros. We take the fields
148     directly from the definition of the packet type we want to implement (here the GRE RFC). In the
149     case of GRE we might come up with:
150
151     \code
152     SENF_PARSER_BITFIELD  ( checksumPresent, 1, bool     );
153     SENF_PARSER_SKIP_BITS (                 12           );
154     SENF_PARSER_BITFIELD  ( version,         3, unsigned );
155     SENF_PARSER_BITFIELD  ( protocolType,   16, unsigned );
156     \endcode
157     
158     This is a correct \c GREPacket header definition but we can optimize a little bit: Since the \a
159     protocolType field is aligned on a byte boundary, instead of defining it as a bitfield, we can
160     define it as a UInt16 field:
161     
162     \code
163     SENF_PARSER_BITFIELD  ( checksumPresent,  1, bool     );
164     SENF_PARSER_SKIP_BITS (                  12           );
165     SENF_PARSER_BITFIELD  ( version,          3, unsigned );
166     SENF_PARSER_FIELD     ( protocolType,    senf::UInt16Parser );
167     \endcode
168
169     Whereas \ref SENF_PARSER_BITFIELD can define only bit-fields, \ref SENF_PARSER_FIELD can define
170     almost arbitrary field types. The type is specified by passing the name of another parser to
171     \ref SENF_PARSER_FIELD.
172
173     It is important to understand, that the accessors do \e not return the parsed field value. They
174     return another \e parser which is used to further interpret the value. This is the inherent
175     recursive nature of the SENF packet parsers. This allows to define wildly complex header formats
176     if needed. Of course, at some point we need the real value. This is, what the so called
177     <em>value parsers</em> do: They interpret some bytes or bits and return the value of that field
178     (not a parser). Examples are the bitfield parsers returned by the accessors generated by
179     SENF_PARSER_BITFIELD (like senf::UIntFieldParser) or the senf::UInt16Parser.
180
181     What happens in the above macros? Most of the macros define an accessor for a specific field: \a
182     checksumPresent() or \a protocolType(). They also manage a <em>current Offset</em>. This value
183     is advanced according to the field size whenever a new field is defined (and since this parser
184     is defined as a dynamically sized parser, this offset is not a constant, it is an expression
185     which calculates the offset of a field depending on the preceding data).
186
187
188     \subsection howto_newpacket_parser_variant Defining optional fields: The 'variant' parser
189
190     Until now, the parser is very simple, it could have been defined as a fixed size parser. Here we
191     will now explain, how to define optional fields. The same facilities are used to define
192     either/or fields or field collections.
193
194     In the special case of GRE< there are two fields which need to be disabled/enabled together. We
195     first define an additional sub-parser which combines those two fields. After this parser is
196     defined, we can use \ref SENF_PARSER_VARIANT() to add this parser as an optional parser to the
197     GRE header.
198     
199     \code
200     struct GREPacketParser_OptFields : public senf::PacketParserBase
201     {
202     #   include SENF_FIXED_PARSER()
203
204         SENF_PARSER_FIELD ( checksum, senf::UInt16Parser );
205         SENF_PARSER_SKIP  (           2                  );
206
207         SENF_PARSER_FINALIZE(GREPacketParser_OptFields);
208     };
209     \endcode
210
211     This parser only parses the two optional fields of which the reserved field is just skipped. The
212     parser this time is a fixed size parser. We can now use this parser to continue the \c
213     GREPacketParser implementation:
214
215     \code
216     SENF_PARSER_BITFIELD  ( checksumPresent,  1, bool     );
217     SENF_PARSER_SKIP_BITS (                  12           );
218     SENF_PARSER_BITFIELD  ( version,          3, unsigned );
219
220     SENF_PARSER_FIELD     ( protocolType,    senf::UInt16Parser );
221
222     SENF_PARSER_VARIANT   ( optionalFields,  checksumPresent,
223                                              (senf::VoidPacketParser)
224                                              (GREPacketParser_OptFields) );
225     \endcode
226
227     For a variant parser, two things need to be specified: A selector and a list of variant
228     parsers. The selector is another parser field which is used to decide, which variant to
229     choose. In this simple case, the field must be an unsigned integer (more precisely a value
230     parser which returns a value which is implicitly convertible to \c unsigned). This value is used
231     as index into the list of variant types. So in our case, 0 is associated with
232     senf::VoidPacketParser whereas 1 is associated with \c
233     GREPacketParser_OptFields. (senf::VoidPacketParser is a special empty parser which is used in a
234     Variant to denote cases in which the variant parser should not parse anything)
235
236     This parser will work, it is however not very safe and not very usable. If \a p is a
237     GREPacketParser instance, than we would access the fields via:
238     \code
239     p.checksumPresent()                    = true;
240     p.version()                            = 4u;
241     p.protocolType()                       = 0x86dd;
242     p.optionalFields().get<1>().checksum() = 12345u;
243     \endcode
244     
245     This code has two problems:
246     \li accessing the checksum field is quite unwieldy
247     \li changing the checksumPresent() value will break the parser
248
249     The reason for the second problem lies in the fact, that the variant parser needs to be informed
250     whenever the selector (here \a checksumPresent) is changed since the variant parser must ensure,
251     that the header data stays consistent. In this example, whenever the checksumPresent field is
252     enabled, the variant parser needs to insert additional 4 bytes of data and remove those bytes,
253     when the checksumPresent field is disabled. 
254
255
256     \subsection howto_newpacket_parser_fixvariant Fixing access by providing custom accessor members
257
258     The problems found above will happen whenever we use variant parsers and will often occur with
259     other complex parsers too (most \ref parsercollection reference some field external to
260     themselves and don't like it at all, if that value is changed without them knowing about
261     it). There may often also be other reasons to restrict access to a field: The field may be set
262     automatically or may be calculated from other values (how to do this, we'll see later).
263
264     In all these cases we will want to disallow the user of the packet to change the value while
265     still allowing him to read the value. To do this, we can mark \e value fields as read-only:
266
267     \code
268     SENF_PARSER_BITFIELD_RO ( checksumPresent,  1, bool     );
269     \endcode
270
271     Value fields are fields, which return a simple value and not a complex sub-parser (this are
272     bit-fields, the integer parsers and also some additional parsers like those parsing network
273     addresses).
274
275     In this case however, we still want to allow the user to change the field value, albeit not
276     directly. We will need to go through the collection parser, in this case the variant. Since the
277     variant syntax to change the currently active variant is not very favorable, we provide nice
278     helper members for this:
279
280     \code
281     void enableChecksum()  const { optionalFields_().init<1>(); }
282     void disableChecksum() const { optionalFields_().init<0>(); }
283     \endcode
284
285     By changing the collection we automatically change the field, this collection references. Now we
286     only need to provide an additional \a checksum member to hide the complex variant access syntax
287     from the user. And since now all variant access is via specialized members, we can hide the
288     variant field completely from the user:
289     
290     \code
291     SENF_PARSER_PRIVATE_VARIANT ( optionalFields_, checksumPresent,
292                                                      (senf::VoidPacketParser)
293                                                      (GREPacketParser_OptFields)    );
294
295     GREPacketParser_OptFields::checksum_t checksum() const
296         { return optionalFields_().get<1>().checksum(); }
297     \endcode
298
299     As we can see here, we have used the <em>name</em><code>_t</code> typedef which is available for
300     all fields to provide the return value for our accessor member.
301
302     The \c GREPacketParser is now simple and safe to use. The only responsibility of the user now is to
303     only access \a checksum() if the \a checksumPresent() field is set. Otherwise, the behavior is
304     undefined (in debug builds, the parser will terminate the application with an assert).
305
306     
307     \subsection howto_newpacket_parser_add Providing additional functionality
308
309     We have now implemented parsing all the header fields. However, often packets would benefit from
310     additional functionality. In the case of GRE, this could be a function to calculate the checksum
311     value if it is enabled. Defining this member will also show, how to safely access the raw packet
312     data from a parser member.
313
314     \code
315     #include <senf/Utils/IpChecksum.hh>
316
317     checksum_t::value_type calculateChecksum() const 
318     {
319         if (!checksumEnabled()) 
320             return 0;
321
322         senf::IpChecksum cs;
323         cs.feed( i(), i(4) );
324         // Skip even number of 0 bytes (the 2 bytes checksum field)
325         // cs.feed(0); cs.feed(0);
326         cs.feed( i(6), data().end() );
327
328         return cs.sum()
329     }
330     \endcode
331
332     This code just implements what is defined in the RFC: The checksum covers the complete GRE
333     packet including it's header with the checksum field temporarily set to 0. Instead of really
334     changing the checksum field we manually pass the correct data to \a cs. 
335
336     We use the special <tt>i(</tt><i>offset</i><tt>)</tt> helper to get iterators \a offset number
337     of bytes into the data. This helper has the additional benefit of range-checking the returned
338     iterator and is thereby safe from errors due to truncated packets: If the offset is out of
339     range, a TruncatedPacketException will be thrown.
340
341     The \a data() function on the other hand returns a reference to the complete data container of
342     the packet under inspection (the GRE packet in this case). Access to \a data() should be
343     restricted as much as possible. It is safe when defining new packet parsers (parsers, which
344     parser a complete packet like GREPacketParser). It's usage from sub parsers (like
345     GREPacketParser_OptFields or even senf::UInt16Parser) would be much more arcane and should be
346     avoided.
347
348
349     \subsection howto_newpacket_parser_final The complete GREPacketParser implementation
350
351     So this is now the complete implementation of the \c GREPacketParser:
352
353     \code
354     #include <senf/Packets.hh>
355     
356     struct GREPacketParser_OptFields : public senf::PacketParserBase
357     {
358     #   include SENF_FIXED_PARSER()
359
360         SENF_PARSER_FIELD           ( checksum,        senf::UInt16Parser            );
361         SENF_PARSER_SKIP            (                   2                            );
362
363         SENF_PARSER_FINALIZE(GREPacketParser_OptFields);
364     };
365
366     struct GREPacketParser : public senf::PacketParserBase
367     {
368     #   include SENF_PARSER()
369
370         SENF_PARSER_BITFIELD_RO     ( checksumPresent,  1, bool                      );
371         SENF_PARSER_SKIP_BITS       (                  12                            );
372         SENF_PARSER_BITFIELD        ( version,          3, unsigned                  );
373
374         SENF_PARSER_FIELD           ( protocolType,    senf::UInt16Parser            );
375
376         SENF_PARSER_PRIVATE_VARIANT ( optionalFields_, checksumPresent,
377                                                          (senf::VoidPacketParser)
378                                                          (GREPacketParser_OptFields) );
379
380         GREPacketParser_OptFields::checksum_t checksum() const
381             { return optionalFields_().get<1>().checksum(); }
382
383         void enableChecksum()  const { optionalFields_().init<1>(); }
384         void disableChecksum() const { optionalFields_().init<0>(); }
385     
386         SENF_PARSER_FINALIZE(GREPacketParser);
387
388         checksum_t::value_type calculateChecksum() const;
389     };
390
391     // In the implementation (.cc) file:
392
393     #include <senf/Utils/IpChecksum.hh>
394     
395     GREPacketParser::checksum_t::value_type GREPacketParser::calculateChecksum() const
396     {
397         if (!checksumEnabled()) 
398             return 0;
399
400         validate(6);
401         senf::IpChecksum cs;
402         cs.feed( i(), i()+4 );
403         // Skip even number of 0 bytes (the 2 bytes checksum field)
404         // cs.feed(0); cs.feed(0);
405         cs.feed( i()+6, data().end() );
406
407         return cs.sum()
408     }
409     \endcode
410
411
412     \section howto_newpacket_type Defining the packet type
413
414     After defining the packet parser, the <em>packet type</em> must be defined. This class is used
415     as a policy and collects all the information necessary to be known about the packet type.
416
417     The <em>packet type</em> class is \e never instantiated. It has only typedef, constants or
418     static members.
419
420     \subsection howto_newpacket_type_skeleton The packet type skeleton
421
422     For every type of packet, the <em>packet type</em> class will look roughly the same. If the
423     packet utilizes a registry and is not hopelessly complex, the packet type will almost always
424     look like this:
425
426     \code
427     #include <senf/Packets.hh>
428
429     struct GREPacketType
430         : public senf::PacketTypeBase,
431           public senf::PacketTypeMixin<GREPacketType, EtherTypes>
432     {
433         typedef senf::PacketTypeMixin<GREPacketType, EtherTypes> mixin;
434         typedef senf::ConcretePacket<GREPacketType> packet;
435         typedef senf::GREPacketParser parser;
436     
437         using mixin::nextPacketRange;
438         using mixin::nextPacketType;
439         using mixin::init;
440         using mixin::initSize;
441
442         // Define members here
443     };
444     \endcode
445
446     We note, that it derives from two classes: senf::PacketTypeBase and
447     senf::PacketTypeMixin. senf::PacketTypeBase must be inherited by every packet type class. the
448     senf::PacketTypeMixin provides default implementations for some members which are useful for
449     most kinds of packets. If a packet type is very complex and these defaults don't work, the mixin
450     class can and should be left out. More on this (what the default members do exactly and when the
451     mixin can be used) can be found in the senf::PacketTypeMixin documentation.
452
453     Of the typedefs, only \a parser is mandatory. It defines the packet parser to use to interpret
454     this type of packet. \a mixin and \a packet are defined to simplify the following
455     definitions (More on \a packet and senf::ConcretePacket later).
456
457     The next block of statements imports all the default implementations provided by the mixin
458     class:
459     
460     \li \a nextPacketRange provides information about where the next packet lives within the GRE
461         packet.
462     \li \a nextPacketType provides the type of the next packet from information in the GRE packet.
463     \li \a init is called to initialize a new GRE packet. This call is forwarded to \c
464         GREPacketParser::init.
465     \li \a initSize is called to find the size of an empty (newly create) GRE packet. This is also
466         provided by GREPacketParser.
467     
468     With these default implementations provided by the mixin, only a few additional members are
469     needed to complete the \c GREPacketType: \a nextPacketKey, \a finalize, and \a dump.
470
471
472     \subsection howto_newpacket_type_registry Utilizing the packet registry
473
474     A packet registry maps an arbitrary key value to a type of packet represented by a packet
475     factory instance. There may be any number of packet registries. When working with packet
476     registries, there are three separate steps:
477     \li Using the registry to tell the packet library, what type of packet to instantiate for the
478         payload.
479     \li Given a payload packet of some type, set the appropriate payload type field in the packet
480         header to the correct value (inverse of above).
481     \li Adding packets to the registry.
482
483     We want the GRE packet to utilize the senf::EtherTypes registry to find the type of packet
484     contained in the GRE payload.  The details have already been taken care of by the
485     senf::PacketTypeMixin (it provides the \a nextPacketType member). However, to lookup the packet
486     in the registry, the mixin needs to know the key value. To this end, we implement \a
487     nextPacketKey(), which is very simple:
488
489     \code
490     static key_t nextPacketKey(packet p) { return p->protocolType(); }
491     \endcode
492
493     Since all \c GREPacketType members are static, they are passed the packet in question as an
494     argument. \a nextPacketKey() just needs to return the value of the correct packet field. And
495     since the \c packet type (as defined as a typedef) allows direct access to the packet parser
496     using the <tt>-></tt> operator, we can simply access that value.
497
498     The \c key_t return type is a typedef provided by the mixin class. It is taken from the type of
499     registry, in this case it is senf::EtherTypes::key_t (which is defined as a 16 bit unsigned
500     integer value).
501
502     With this information, the packet library can now find out the type of packet needed to parse
503     the GRE payload -- as long as the \a protocolType() is registered with the senf::EtherTypes
504     registry. If this is not the case, the packet library will not try to interpret the payload, it
505     will return a senf::DataPacket.
506
507     One special case of GRE encapsulation occurs when layer 2 frames and especially ethernet frames
508     are carried in the GRE payload. The ETHERTYPE registry normally only contains layer 3 protocols
509     (like IP or IPX) however for this special case, the value 0x6558 has been added to the ETHERTYPE
510     registry. So we need to add this value to inform the packet library to parse the payload as an
511     ethernet packet if the \a protocolType() is 0x6558. This happens in the implementation file (the
512     \c .cc file):
513
514     \code
515     #include <senf/Packets/DefaultBundle/EthernetPacket.hh>
516
517     SENF_PACKET_REGISTRY_REGISTER( senf::EtherTypes, 0x6558, senf::EthernetPacket );
518     \endcode
519
520     This macro registers the value 0x6558 in the senf::EtherTypes registry and associates it with
521     the packet type senf::EthernetPacket. This macro declares an anonymous static variable, it
522     therefore must always be placed in the implementation file and \e never in an include file.
523
524     Additionally, we want the GRE packet to be parsed when present as an IP payload. Therefore we
525     additionally need to register GRE in the senf::IpTypes registry. Looking at the <a
526     href="http://www.iana.org/assignments/protocol-numbers">IP protocol numbers</a>, we find that
527     GRE has been assigned the value 47:
528
529     \code
530     #include <senf/Packets/DefaultBundle/IPv4Packet.hh>
531
532     SENF_PACKET_REGISTRY_REGISTER( senf::IpTypes, 47, GREPacket );
533     \endcode
534
535     But wait -- what is \c GREPacket ? This question is answered a few section further down.
536     
537     The last thing we need to do is, we need to set the \a protocolType() field to the correct value
538     when packets are newly created or changed. This is done within \a finalize:
539
540     \code
541     static void finalize(packet p) { p->protocolType() << key(p.next(senf::nothrow)); }
542     \endcode
543
544     The \c key() function is provided by the mixin class: It will lookup the \e type of a packet in
545     the registry and return that packets key in the registry. If the key cannot be found, the return
546     value is such that the assignment is effectively skipped.
547
548
549     \subsection howto_newpacket_type_invariants Providing packet invariants
550
551     Many packets have some invariants that must hold: The payload size must be equal to some field,
552     a checksum must match and so on. When packets are newly created or changed, these invariants
553     have to be updated to be correct. This is the responsibility of the \a finalize() member.
554
555     \code
556     static void finalize(packet p) 
557     {
558         p->protocolType() << key(p.next(senf::nothrow));
559         if (p->checksumPresent())
560             p->checksum() << p->calculateChecksum();
561     }
562     \endcode
563
564     We already used finalize above to set the \a protocolType() field. Now we add code to update the
565     \a checksum() field if present (this always needs to be done last since the checksum depends on
566     the other field values).
567
568     Here we are using the more generic parser assignment expressed using the \c << operator. This
569     operator in the most cases works like an ordinary assignment, however it can also be used to
570     assign parsers to each other efficiently and it supports 'optional values' (as provided by <a
571     href="http://www.boost.org/libs/optional/doc/optional.html">Boost.Optional</a> and as returned
572     by \c key()).
573
574
575     \subsection howto_newpacket_type_dump Writing out a complete packet: The 'dump()' member
576
577     For diagnostic purposes, every packet should provide a meaningful \a dump() member which writes
578     out the complete packet. This member is simple to implement and is often very helpful when
579     tracking down problems.
580     
581     \code
582     #include <boost/io/ios_state.hpp>
583
584     static void dump(packet p, std::ostream & os)
585     {
586         boost::io::ios_all_saver ias(os);
587         os << "General Routing Encapsulation:\n"
588            << "  checksum present              : " << p->checksumPresent() ? "true" : "false" << "\n"
589            << "  version                       : " << p->version() << "\n"
590            << "  protocol type                 : 0x" << std::hex << std::setw(4) << std::setfill('0')
591                                                      << p->protocolType() << "\n";
592         if (p->checksumPresent())
593             os << "  checksum                     : 0x" << std::hex << std::setw(4)
594                                                         << std::setfill('0') << p->checksum() << "\n"; 
595     }
596     \endcode
597     
598     This member is quite straight forward. We should try to adhere to the formating standard shown
599     above: The first line should be the type of packet/header being dumped followed by one line for
600     each protocol field. The colon's should be aligned at column 33 with the field name indented by
601     2 spaces. 
602
603     The \c boost::ios_all_saver is just used to ensure, that the stream formatting state is restored
604     correctly at the end of the method. An instance of this type will save the stream state when
605     constructed and will restore that state when destructed.
606
607     \subsection howto_newpacket_type_final Final touches
608
609     The \c GREPacket implementation is now almost complete. The only thing missing is the \c
610     GREPacket itself. \c GREPacket is just a typedef for a specific senf::ConcretePacket template
611     instantiation. Here the complete GREPacket definition:
612
613     \code
614     #include <senf/Packets.hh>
615
616     struct GREPacketType
617         : public senf::PacketTypeBase,
618           public senf::PacketTypeMixin<GREPacketType, EtherTypes>
619     {
620         typedef senf::PacketTypeMixin<GREPacketType, EtherTypes> mixin;
621         typedef senf::ConcretePacket<GREPacketType> packet;
622         typedef senf::GREPacketParser parser;
623     
624         using mixin::nextPacketRange;
625         using mixin::nextPacketType;
626         using mixin::init;
627         using mixin::initSize;
628
629         static key_t nextPacketKey(packet p) { return p->protocolType(); }
630     
631         static void finalize(packet p) {
632             p->protocolType() << key(p.next(senf::nothrow)); 
633             if (p->checksumPresent()) p->checksum() << p->calculateChecksum();
634        }
635     
636         static void dump(packet p, std::ostream & os);
637     };
638
639     typedef GREPacketType::packet GREPacket;
640     
641     // In the implementation (.cc) file:
642
643     #include <senf/Packets/DefaultBundle/EthernetPacket.hh>
644     #include <senf/Packets/DefaultBundle/IPv4Packet.hh>
645
646     SENF_PACKET_REGISTRY_REGISTER( senf::EtherTypes, 0x6558, senf::EthernetPacket );
647     SENF_PACKET_REGISTRY_REGISTER( senf::IpTypes, 47, GREPacket );
648
649     void GREPacketType::dump(packet p, std::ostream & os)
650     {
651         boost::io::ios_all_saver ias(os);
652         os << "General Routing Encapsulation:\n"
653            << "  checksum present              : " << p->checksumPresent() ? "true" : "false" << "\n"
654            << "  version                       : " << p->version() << "\n"
655            << "  protocol type                 : 0x" << std::hex << std::setw(4) << std::setfill('0')
656                                                      << p->protocolType() << "\n";
657         if (p->checksumPresent())
658             os << "  checksum                     : 0x" << std::hex << std::setw(4)
659                                                         << std::setfill('0') << p->checksum() << "\n"; 
660     }
661     \endcode
662
663
664     \section howto_newpacket_advanced Going further
665
666     \subsection howto_newpacket_advanced_valid Checking the GRE packet for validity
667
668     We now know how to define packets, but there is more. In this section we will explore the
669     features available to make the packet chaining more flexible. We will show, how to implement
670     more complex logic than simple registry lookup to find the nested packet (the payload) type.
671
672     In our concrete example, reading the RFC we find there are some restrictions which a GRE packet
673     needs to obey to be considered valid. If the packet is not valid it cannot be parsed and should
674     be dropped. We can't drop it here but if the packet is invalid, we certainly must refrain from
675     trying to parser any payload since we cannot assume the packet to have the format we assume our
676     GRE packet to have. 
677
678     There are two conditions defined in the RFC which render a GRE packet invalid: If one of the \a
679     reserved0() fields first 5 bits is set or if the version is not 0. We will add a \a valid()
680     check to the parser and utilize this check in the packet type.
681
682     So first lets update the parser. We will need to change the fields a little bit so we have
683     access to the first 5 bits of \a reserved0. We therefore replace the first three field
684     statements with
685
686     \code
687     SENF_PARSER_BITFIELD_RO      ( checksumPresent,  1, bool                      );
688     SENF_PARSER_PRIVATE_BITFIELD ( reserved0_5bits_, 5, unsigned                  );
689     SENF_PARSER_SKIP_BITS        (                   7                            );
690     SENF_PARSER_BITFIELD_RO      ( version,          3, unsigned                  );
691     \endcode
692
693     We have added an additional private bitfield \a reserved0_5bits_() and we made the \a version()
694     field read-only.
695
696     We will now add a simple additional member to the parser:
697
698     \code
699     bool valid() const { return version() == 0 && reserved0_5bits_() == 0; }
700     \endcode
701
702     I think, this is quite straight forward: \a valid() will just check the restrictions as defined
703     in the RFC.
704
705     Now to the packet type. We want to refrain from parsing the payload if the packet is
706     invalid. This is important: If the packet is not valid, we have no idea, whether the payload is
707     what we surmise it to be (if any of the \a reserved0_5bits_() are set, the packet is from an
708     older GRE RFC and the header is quite a bit longer so the payload will be incorrect).
709
710     So we need to change the logic which is used by the packet library to find the type of the next
711     packet. We have two ways to do this: We keep using the default \c nextPacketType()
712     implementation as provided by the senf::PacketTypeMixin and have our \a nextPacketKey()
713     implementation return a key value which is guaranteed never to be registered in the registry.
714
715     The more flexible possibility is implementing \c nextPacketType() ourselves. In this case, the
716     first method would suffice, but we will choose to go the second route to show how to write the
717     \c nextPacketType() member. We therefore remove the \c using declaration of \c nextPacketType()
718     and also remove the \a nextPacketKey() implementation. Instead we add the following to the
719     packet type
720
721     \code
722     // disabled: using mixin::nextPacketType;
723
724     factory_t nextPacketType(packet p) { return p->valid() ? lookup(p->protocolType()) : no_factory(); }
725     \endcode
726     
727     As we see, this is still quite simple. \c factory_t is provided by senf::PacketTypeBase. For our
728     purpose it is an opaque type which somehow enables the packet library to create a new packet of
729     a specified packet type. The \c factory_t has a special value, \c no_factory() which stands for
730     the absence of any concrete factory. In a boolean context this (and only this) \c factory_t
731     value tests \c false.
732
733     The \c lookup() member is provided by the senf::PacketTypeMixin. It looks up the key passed as
734     argument in the registry and returns the factory or \c no_factory(), if the key was not found in
735     the registry.
736
737     In this case this is all. But let's elaborate on this example. What if we need to return some
738     specific factory from \a nextPacketType(), e.g. what, if we want to handle the case of
739     transparent ethernet bridging explicitly instead of registering the value in the
740     senf::EtherTypes registry ? Here one way to do this:
741
742     \code
743     factory_t nextPacketType(packet p) { 
744         if (p->valid()) {
745             if (p->protocolType() == 0x6558)  return senf::EthernetPacket::factory();
746             else                              return lookup(p->protocolType());
747         }
748         else                                  return no_factory();
749     }
750     \endcode
751
752     As can be seen above, every packet type has a (static) \a factory() member which returns the
753     factory for this type of packet.
754
755
756     \subsection howto_newpacket_advanced_init Non-trivial packet initialization
757
758     Every packet when created is automatically initialized with 0 bytes (all data bytes will be
759     0). In the case of GRE this is enough. But other packets will need other more complex
760     initialization to be performed.
761
762     Lets just for the sake of experiment assume, the GRE packet would have to set \a version() to 1
763     not 0. In this case, the default initialization would not suffice. It is however very simple to
764     explicitly initialize the packet. The initialization happens within the parser. We just add
765
766     \code
767     SENF_PARSER_INIT() { version_() << 1u; }
768     \endcode
769
770     to \c GREPacketParser. For every read-only defined field, the macros automatically define a \e
771     private read-write accessor which may be used internally. This read-write accessor is used here
772     to initialize the value.
773
774
775     \section howto_newpacket_final The ultimate GRE packet implementation completed
776
777     So here we now have \c GREPacket finally complete in all it's glory. First the header file \c
778     GREPacket.hh:
779
780     \code
781     #ifndef HH_GREPacket_
782     #define HH_GREPacket_
783
784     #include <senf/Packets.hh>
785     
786     struct GREPacketParser_OptFields : public senf::PacketParserBase
787     {
788     #   include SENF_FIXED_PARSER()
789
790         SENF_PARSER_FIELD           ( checksum,        senf::UInt16Parser            );
791         SENF_PARSER_SKIP            (                   2                            );
792
793         SENF_PARSER_FINALIZE(GREPacketParser_OptFields);
794     };
795
796     struct GREPacketParser : public senf::PacketParserBase
797     {
798     #   include SENF_PARSER()
799
800         SENF_PARSER_BITFIELD_RO      ( checksumPresent,  1, bool                      );
801         SENF_PARSER_PRIVATE_BITFIELD ( reserved0_5bits_, 5, unsigned                  );
802         SENF_PARSER_SKIP_BITS        (                   7                            );
803         SENF_PARSER_BITFIELD_RO      ( version,          3, unsigned                  );
804
805         SENF_PARSER_FIELD            ( protocolType,    senf::UInt16Parser            );
806
807         SENF_PARSER_PRIVATE_VARIANT  ( optionalFields_, checksumPresent,
808                                                           (senf::VoidPacketParser)
809                                                           (GREPacketParser_OptFields) );
810
811         typedef version__t version_t;
812         version_t::value_type version() const { return version_(); }
813
814         bool valid() const { return version() == 0 && reserved0_5bits_() == 0; }
815
816         typedef GREPacketParser_OptFields::checksum_t checksum_t;
817         checksum_t checksum() const
818             { return optionalFields_().get<1>().checksum(); }
819
820         void enableChecksum()  const { optionalFields_().init<1>(); }
821         void disableChecksum() const { optionalFields_().init<0>(); }
822     
823         SENF_PARSER_FINALIZE(GREPacketParser);
824
825         checksum_t::value_type calculateChecksum() const;
826     };
827
828     struct GREPacketType
829         : public senf::PacketTypeBase,
830           public senf::PacketTypeMixin<GREPacketType, EtherTypes>
831     {
832         typedef senf::PacketTypeMixin<GREPacketType, EtherTypes> mixin;
833         typedef senf::ConcretePacket<GREPacketType> packet;
834         typedef senf::GREPacketParser parser;
835     
836         using mixin::nextPacketRange;
837         using mixin::init;
838         using mixin::initSize;
839
840         factory_t nextPacketType(packet p) 
841             { return p->valid() ? lookup(p->protocolType()) : no_factory(); }
842     
843         static void finalize(packet p) {
844             p->protocolType() << key(p.next(senf::nothrow));
845             if (p->checksumPresent()) p->checksum() << p->calculateChecksum();
846         }
847     
848         static void dump(packet p, std::ostream & os);
849     };
850
851     typedef GREPacketType::packet GREPacket;
852     
853     #endif
854     \endcode
855
856     And the implementation file \c GREPacket.cc:
857
858     \code
859     #include "GREPacket.hh"
860     #include <senf/Utils/IpChecksum.hh>
861     #include <senf/Packets/DefaultBundle/EthernetPacket.hh>
862     #include <senf/Packets/DefaultBundle/IPv4Packet.hh>
863
864     SENF_PACKET_REGISTRY_REGISTER( senf::EtherTypes, 0x6558, senf::EthernetPacket );
865     SENF_PACKET_REGISTRY_REGISTER( senf::IpTypes, 47, GREPacket );
866
867     GREPacketParser::checksum_t::value_type GREPacketParser::calculateChecksum() const
868     {
869         if (!checksumEnabled()) 
870             return 0;
871
872         validate(6);
873         senf::IpChecksum cs;
874         cs.feed( i(), i()+4 );
875         // Skip even number of 0 bytes (the 2 bytes checksum field)
876         // cs.feed(0); cs.feed(0);
877         cs.feed( i()+6, data().end() );
878
879         return cs.sum()
880     }
881
882     void GREPacketType::dump(packet p, std::ostream & os)
883     {
884         boost::io::ios_all_saver ias(os);
885         os << "General Routing Encapsulation:\n"
886            << "  checksum present              : " << p->checksumPresent() ? "true" : "false" << "\n"
887            << "  version                       : " << p->version() << "\n"
888            << "  protocol type                 : 0x" << std::hex << std::setw(4) << std::setfill('0')
889                                                      << p->protocolType() << "\n";
890         if (p->checksumPresent())
891             os << "  checksum                     : 0x" << std::hex << std::setw(4)
892                                                         << std::setfill('0') << p->checksum() << "\n"; 
893     }
894     \endcode
895
896
897     \section howto_newpacket_using Using the newly created GRE packet type
898
899     The GRE packet is now fully integrated into the packet library framework. For example, we can
900     read GRE packets from a raw INet socket and forward decapsulated Ethernet frames to a packet
901     socket.
902
903     \code
904     #include <iostream>
905     #include <senf/Packets.hh>
906     #include <senf/Packets/DefaultBundle/EthernetPacket.hh>
907     #include <senf/Socket/Protocols/INet/RawINetProtocol.hh>
908     #include <senf/Socket/Protocols/Raw/PacketSocketHandle.hh>
909     #include "GREPacket.hh"
910
911     int main(int, char const **)
912     {
913         senf::RawV6ClientSocketHandle isock (47u); // 47 = Read GRE packets
914         senf::PacketSocketHandle osock;
915
916         while (true) {
917             try {
918                 GREPacket gre (GREPacket::create(senf::noinit));
919                 isock.read(gre.data(),0u);
920                 if (gre->checksumPresent() && gre->checksum() != gre->calculateChecksum())
921                     throw InvalidPacketChainException();
922                 osock.write(gre.next<EthernetPacket>().data())
923             }
924             catch (senf::TruncatedPacketException & ex) {
925                 std::cerr << "Malformed packet dropped\n";
926             }
927             catch (senf::InvalidPacketChainException & ex) {
928                 std::cerr << "Invalid GRE packet dropped\n";
929             }
930         }
931     }
932     \endcode
933
934     Or we can do the opposite: Read ethernet packets from a \c tap device and send them out GRE
935     encapsulated.
936
937     \code
938     #include <iostream>
939     #include <senf/Packets.hh>
940     #include <senf/Packets/DefaultBundle/EthernetPacket.hh>
941     #include <senf/Socket/Protocols/INet/RawINetProtocol.hh>
942     #include <senf/Socket/Protocols/Raw/TunTapSocketHandle.hh>
943     #include "GREPacket.hh"
944
945     int main(int argc, char const ** argv)
946     {
947         if (argc != 2) {
948             std::cerr << "Usage: " << argv[0] << " <tunnel endpoint>\n";
949             return 1;
950         }
951
952         senf::TapSocketHandle tap ("tap0");
953         senf::ConnectedRawV6ClientSocketHandle osock (47u, senf::INet6SocketAddress(argv[1]));
954     
955         while (true) {
956             senf::EthernetPacket eth (senf::EthernetPacket::create(senf::noinit));
957             isock.read(eth.data(),0u);
958             GREPacket gre (senf::GREPacket::createBefore(eth));
959             gre.finalize();
960             osock.write(gre.data());
961         }
962     }
963     \endcode
964
965     
966     \section howto_newpacket_further Further reading
967
968     Lets start with references to the important API's (Use the <i>List of all members</i> link to
969     get the complete API of one of the classes and templates):
970
971     <table class="senf fixedcolumn">
972
973     <tr><td>senf::ConcretePacket</td> <td>this is the API provided by the packet handles.</td></tr>
974
975     <tr><td>senf::PacketData</td> <td>this API provides raw data access accessible via the handles
976     'data' member.</td></tr>
977
978     <tr><td>senf::PacketParserBase</td> <td>this is the generic parser API. This API is accessible
979     via the packets \c -> operator or via the sub-parsers returned by the field accessors.</td></tr>
980
981     </table>
982
983     When implementing new packet's, the following information will be helpful:
984
985     <table class="senf fixedcolumn">
986     
987     <tr><td>senf::PacketTypeBase</td> <td>here you find a description of the members which need to
988     be implemented to provide a 'packet type'. Most of these members will normally be provided by
989     the mixin helper.</td></tr>
990
991     <tr><td>senf::PacketTypeMixin</td> <td>here you find all about the packet type mixin and how to
992     use it.</td></tr>
993
994     <tr><td>\ref packetparser</td> <td>This section describes the packet parser facility.</td></tr>
995     
996     <tr><td>\link packetparsermacros Packet parser macros\endlink</td> <td>A complete list and
997     documentation of all the packet parser macros.</td></tr>
998     
999     <tr><td>\ref parseint, \n \ref parsecollection</td> <td>There are several lists of available
1000     reusable packet parsers. However, these lists are not complete as there are other protocol
1001     specific reusable parsers (without claiming to be exhaustive: senf::INet4AddressParser,
1002     senf::INet6AddressParser, senf::MACAddressParser)</td></tr>
1003
1004     </table>
1005
1006  */
1007
1008 \f
1009 // Local Variables:
1010 // mode: c++
1011 // fill-column: 100
1012 // comment-column: 40
1013 // c-file-style: "senf"
1014 // indent-tabs-mode: nil
1015 // ispell-local-dictionary: "american"
1016 // compile-command: "scons -u doc"
1017 // mode: auto-fill
1018 // End: