b1cf6a650fceea243a6cf4913dea0f7f13cf7463
[senf.git] / senf / Packets / PacketParser.hh
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.be>
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 /** \file
24     \brief PacketParser public header */
25
26 /** \defgroup packetparser The PacketParser facility
27
28     The PacketParser facility provides a framework to implement very lightweight classes which parse
29     the raw content of a packet into meaningful values. PacketParsers are always passed around
30     <em>by value</em>, they can be understood as pointers into the packet data with added type
31     information providing parsing functions.
32
33     Packet parsers are \e only used within the packet framework. You should never allocate a new
34     parser instance directly, you should the Packet library let that do for you (either by having
35     the parser as a packet parser in a packet type or by having a member in the packet parser which
36     allocates the parser as a sub-parser).
37
38     Parsers are built hierarchically. A high-level parser will return other parsers when accessing
39     an element (Example: Asking an EthernetParser for the ethertype field by calling the parsers \c
40     type() member will return an \c UInt16 parser). The lowest level building blocks then return the
41     values. This hierarchical structure greatly simplifies building complex parsers.
42
43     Since parsers are very lightweight and are passed by value, packet fields are accessed using the
44     corresponding accessor method:
45     \code
46       SomePacket p (...)
47       SomePacket q (...)
48
49       // Assign new value to an integer parser
50       p->someField() = 10;
51
52       // Write out above value
53       std::cerr << p->someField() << "\n";
54
55       // Use the generic parser-assignment operator '<<' to copy field values
56       p->someVector()[1].someOtherField() << q->someField();
57       p->someVector() << q->someVector()
58     \endcode
59
60     Here \c someField(), \c someOtherField() and \c someVector() are accessor methods named after
61     the field name. Each returns a parser object. Simple parsers can be used like their
62     corresponding basic type (e.g. a UInt16Parser field can be used like an unsigned integer), more
63     complex parsers provide type specific access members. Assigning a value to a parser will change
64     the underlying representation (the packet data).
65
66     Parsers can be grouped into several categories. These categories are not all defined rigorously
67     but are nevertheless helpful when working with the parsers:
68     \li <em>\ref parserimpl_value</em> provide the lowest level parsers (e.g. senf::UInt16Parser which
69         returns an integer value).
70     \li <em>\ref parserimpl_collection</em> are parsers which model a collection of sub-elements like
71         senf::ListParser or senf::VectorParser.
72     \li <em>\ref parserimpl_composite</em> collect several fields of arbitrary type into a new
73         parser. Parsers defined using the \ref packetparsermacros fall under this category.
74     \li <em>\ref parserimpl_packet</em> are used to define a packet type.
75
76     \warning Parsers are like iterators: They are invalidated <em>whenever the size of the packet's
77     data is changed</em>. You should not store a parser anywhere. If you want to keep a parser
78     reference, use the senf::SafePacketParserWrapper wrapper. You still will need to take extra care to
79     ensure the parser is not invalidated.
80
81     \section parserimpl Packet parser categories
82
83     Every parser is derived from senf::PacketParserBase. This class provides the necessary
84     housekeeping information and provides the parsers with access to the data. You may in principle
85     define arbitrary methods as parser members (e.g. methods to calculate a checksum, methods
86     processing fields in some way and so on). You should however be very wary to access data outside
87     the range assigned to the packet (the range starting at \c i() and with a size of senf::bytes()
88     bytes).
89
90     Each parser type has specific features
91
92     \subsection parserimpl_value Value parsers
93
94     For a parser \a SomeParser to be a value parser, the following expressions must be valid:
95     \code
96     // SomeParser must have a 'value_type', The 'value_type' must be default constructible, copy
97     // constructible and assignable
98     SomeParser::value_type v;
99
100     // An instance of 'SomeParser' must have a 'value' member which returns a value which may be
101     // assigned to a variable of type 'value_type'
102     v = p.someParserField().value()
103
104     // It must be possible to assign a new value using the 'value' member
105     p.someParserField().value(v)
106     \endcode
107
108     If at all possible, the 'value_type' should not reference the packet data using iterators or
109     pointers, it should hold a copy of the value (it's Ok for \c value() to return such a reference
110     as long as assigning it to a \c value_type variable will copy the value).
111
112     \see parseint
113
114     \subsection parserimpl_collection Collection parsers
115
116     A collection parser \a SomeParser should model STL containers. The parsers themselves will
117     probably only // provide a reduced interface, but the collection parser should have a \c
118     collection member which is a wrapper providing the full interface.
119     \code
120     SomeParser::container c (p.someParserField());
121     \endcode
122
123     You will probably only very seldom need to implement a completely new collection
124     parser. Instead, you can rely on senf::VectorParser or senf::ListParser and implement new
125     policies.
126
127     \see parsecollection
128
129     \subsection parserimpl_composite Composite parsers
130
131     If possible, composite parsers should be implemented using the \ref packetparsermacros. In
132     addition to the normal parser requirements, these macros ensure, that for each field,
133     <em>fieldname</em><tt>_t</tt> is a typedef for the fields parser and
134     <em>fieldname</em><tt>_offset</tt> is the offset of the field in bytes from the beginning of the
135     parser (either a constant for fixed size parsers or a member function for dynamically sized
136     parsers). When defining composite parsers without the help of the \ref packetparsermacros, you
137     should provide those same members.
138
139     \subsection parserimpl_packet Protocol parsers
140
141     Protocol parsers are composite parsers with relaxed requirements. Since a Protocol parser will
142     never be used as a sub-parser (it will not be used within another composite parser or as value
143     type in a collection parser), the value returned by senf::bytes for this parser must not
144     necessarily cover the complete packet (e.g. if the packet has a trailer, the trailer will live
145     outside the range given by senf::bytes). You may define any member you want to have in your
146     packets field interface. These members may access the packet data in any way. You just need to
147     ensure, that the integration into the packet-type is correct (the senf::PacketTypeMixin will by
148     default use senf::bytes() to find the end of the header).
149
150     <hr>
151  */
152
153 #ifndef HH_SENF_Packets_PacketParser_
154 #define HH_SENF_Packets_PacketParser_ 1
155
156 // Custom includes
157 #include <boost/utility/enable_if.hpp>
158 #include <boost/type_traits.hpp>
159 #include <boost/optional.hpp>
160 #include <senf/Utils/safe_bool.hh>
161 #include "PacketTypes.hh"
162 #include "PacketData.hh"
163 #include "ParseHelpers.hh"
164 #include "SafeIterator.hh"
165
166 //#include "PacketParser.mpp"
167 //-/////////////////////////////////////////////////////////////////////////////////////////////////
168
169 namespace senf {
170
171     class Packet;
172
173     /** \brief Parser Base class
174
175         Parsers come in two flavors: fixed and dynamically sized parsers. A <em>fixed size
176         parser</em> has a constant size, it will always parse a fixed number of bytes. The low-level
177         'final'  parsers (like the integer parsers) are fixed size parsers as are composite parsers
178         built up only of fixed-size fields.
179
180         A <em>dynamically sized</em> parser on the other hand infers it's size from the contents of
181         the data parsed. Any parser containing at least one dynamically sized sub-parser will itself
182         be dynamically sized.
183
184         Both kinds of parser need to derive from PacketParserBase and implement several required
185         members. Which members to implement depends on the parsers flavor. There are two ways how to
186         do this.
187         \li If the parser just consists of sequence of consecutive fields (sub-parsers), the \ref
188             packetparsermacros provide a simple yet flexible way to define a packet parser.
189         \li In more complex cases, you need to implement the necessary members manually.
190
191         This documentation is about the manual implementation. You should nevertheless read through
192         this to understand, what above macros are doing.
193
194         The following example documents the interface (which must be) provided by a parser:
195         \code
196           struct FooParser : public PacketParserBase
197           {
198               FooParser(data_iterator i, state_type s) : PacketParserBase(i,s) {}
199
200               // If this parser has a fixed size, you must define this size here This definition
201               // allows the parser to be used within the list, vector and array parsers static
202               static const size_type fixed_bytes = some_constant_size;
203
204               // If the parser does not have a fixed size, you must implement the bytes() member to
205               // return the size. ONLY EVER DEFINE ONE OF fixed_bytes OR bytes().
206               size_type bytes() const;
207
208               // If you define bytes(), you also need to define the init_bytes. This is the number
209               // of bytes to allocate when creating a new object
210               static const size_type init_bytes = some_constant_size;
211
212               // You also may define an init() member. This will be called to initialize a newly
213               // created data object. The default implementation just does nothing.
214               void init() const;
215
216               //-////////////////////////////////////////////////////////////////////////
217
218               // Add here members returning (sub-)parsers for the fields. The 'parse' member is
219               // used to construct the sub-parsers. This member either takes an iterator to the
220               // data to be parsed or just an offset in bytes.
221
222               senf::UInt16Parser type() const { return parse<UInt16Parser>( 0 ); }
223               senf::UInt16Parser size() const { return parse<UInt16Parser>( 2 ); }
224           };
225         \endcode
226
227         You should never call the \c bytes() member of a parser directly. Instead you should use the
228         freestanding senf::bytes() function. This function will return the correct size irrespective
229         of the parsers flavor. You may access \c fixed_bytes directly, however be aware that this
230         will restrict your code to fixed size parsers (which depending on the circumstances may be
231         exactly what you want).
232
233         In the same way, don't access \c init_bytes directly, always use the senf::init_bytes
234         meta-function class which correctly supports fixed size parsers.
235
236         \ingroup packetparser
237       */
238     class PacketParserBase
239     {
240     public:
241         //-////////////////////////////////////////////////////////////////////////
242         // Types
243
244         typedef detail::packet::iterator data_iterator; ///< Raw data iterator type
245         typedef detail::packet::size_type size_type; ///< Unsigned integral type
246         typedef detail::packet::difference_type difference_type; ///< Signed integral type
247         typedef detail::packet::byte byte; ///< Unsigned 8bit value, the raw value type
248         typedef PacketData * state_type; ///< Type of the 'state' parameter
249         typedef PacketParserBase parser_base_type; ///< Base type of the next parser
250
251         //-////////////////////////////////////////////////////////////////////////
252         ///\name Structors and default members
253         //\{
254
255         // no default constructor
256         // default copy
257         // default destructor
258         // no conversion constructors
259
260         //\}
261         //-////////////////////////////////////////////////////////////////////////
262
263         data_iterator i() const;        ///< Return beginning of data to parse
264                                         /**< The parser is expected to interpret the data beginning
265                                              here. The size of the interpreted is given by
266                                              <tt>senf::bytes(</tt><em>parser
267                                              instance</em><tt>)</tt>. */
268
269         data_iterator i(size_type offset) const; ///< Return iterator \a offset bytes from the start
270                                         /**< The return value is the same as i() + \a
271                                              offset. However, the parser checks, that the iterator is
272                                              still within range of the raw data
273                                              container. Otherwise a TruncatedPacketException is
274                                              thrown.
275
276                                              \throws TruncatedPacketException if the raw data
277                                                  container does not hold at least \a offset bytes
278                                                  starting at i(). */
279
280         state_type state() const;       ///< Return state of this parser
281                                         /**< The value returned should be interpreted as an opaque
282                                              value provided just to be forwarded to other
283                                              parsers. */
284
285         PacketData & data() const;      ///< Access the packets raw data container
286                                         /**< This member will return the raw data container holding
287                                              the data which is parsed by \c this parser. */
288
289         void init() const;              ///< Default implementation
290                                         /**< This is just an empty default
291                                              implementation. Re-implement this member in your own
292                                              parsers if needed. */
293
294     private:
295         struct ParserProtector {
296             senf::safe_data_iterator safe_i_;
297             mutable PacketParserBase const * parser_;
298
299             ParserProtector(PacketParserBase const * parser);
300             ParserProtector(ParserProtector const & other_);
301             ~ParserProtector();
302         };
303     protected:
304         ParserProtector protect() const;
305
306         PacketParserBase(data_iterator i, state_type s); ///< Standard constructor
307                                         /**< This is the constructor used by most parsers. The
308                                              parameters are just forwarded from the derived classes
309                                              constructor parameters. */
310
311         PacketParserBase(data_iterator i, state_type s, size_type size);
312                                         ///< Size checking constructor
313                                         /**< In addition to the standard constructor, this
314                                              constructor will validate, that there is enough data in
315                                              the raw data container to parse \a size bytes after \a
316                                              i.
317
318                                              This constructor is called by all 'final' parsers
319                                              (e.g. the integer parsers) and \e only by those
320                                              parsers. Most parsers do \e not check the validity of
321                                              the iterator, this is delayed until the very last
322                                              parser. This allows to partial parse truncated
323                                              packets.
324
325                                              \throw TruncatedPacketException if the raw data
326                                                  container does not hold at least \a size bytes
327                                                  beginning at \a i. */
328
329         bool check(size_type size) const; ///< Check size of data container
330                                         /**< \returns \c true, if the data container holds at least
331                                              \a size beginning at i(), \c false otherwise. */
332
333         void validate(size_type size) const; ///< Validate size of data container
334                                         /**< \throws TruncatedPacketException if the raw data
335                                              container does not hold at least \a size bytes
336                                              beginning at i(). */
337
338         template <class Parser> Parser parse(data_iterator i) const; ///< Create sub-parser
339                                         /**< Creates a new instance of \a Parser to parse data
340                                              beginning at \a i. Automatically passes \a state() to
341                                              the new parser. */
342
343         template <class Parser, class Arg> Parser parse(Arg const & arg, data_iterator i) const;
344                                         ///< Create sub-parser
345                                         /**< This is like parse(data_iterator), however it passes
346                                              the extra argument \a arg to the \a Parser
347                                              constructor. */
348
349         template <class Parser> Parser parse(size_type n) const; ///< Create sub-parser
350                                         /**< Creates a new instance of \a Parser to parse data
351                                          * beginning at i()<tt> + </tt>\a n. Automatically passes \a
352                                              state() to the new parser. */
353
354         template <class Parser, class Arg> Parser parse(Arg const & arg, size_type n) const;
355                                         ///< Create sub-parser
356                                         /**< This is like parse(size_type), however it passes the
357                                              extra argument \a arg to the \a Parser constructor. */
358
359         void defaultInit() const;       ///< Default implementation
360                                         /**< This is just an empty default
361                                              implementation. Re-implement this member in your own
362                                              parsers if needed. */
363
364         Packet packet() const;          ///< Get packet this parser is parsing from
365                                         /**< \note This member should only be used from packet
366                                              parsers when access to previous or following packets is
367                                              needed e.g. for calculating checksums etc. */
368
369         void resize(size_type oldSize, size_type newSize); ///< Resize data container
370                                         /**< This command will erase or insert bytes from/into the
371                                              data container at the end of the parser (at i() + \a
372                                              newSize). If \a oldSize is > \a newSize, bytes will be
373                                              removed, otherwise bytes will be inserted.
374
375                                              \warning This may invalidate iterators and other
376                                                  parsers. The current parser itself is automatically
377                                                  updated */
378
379     private:
380         data_iterator end() const;
381
382         data_iterator i_;
383         PacketData * data_;
384
385         template <class Parser> friend class SafePacketParserWrapper;
386         friend class ParserProtector;
387     };
388
389     /** \brief Return raw size parsed by the given parser object
390
391         This function will either call <tt>p.bytes()</tt> or return <tt>Parser::fixed_bytes</tt>
392         depending on the type of parser.
393
394         The value returned does \e not take into account the amount of data actually available. So
395         you always need to validate this value against the packet size if you directly access the
396         data. The standard low-level parses all do this check automatically to guard against
397         malformed packets.
398
399         \param[in] p Parser object to check
400         \returns number of bytes this parser expects to parser
401         \ingroup packetparser
402      */
403     template <class Parser>
404     PacketParserBase::size_type bytes(Parser p);
405
406     namespace detail { template <class Parser> class ParserInitBytes; }
407     namespace detail { template <class Parser> class ParserIsFixed; }
408
409     /** \brief Return number of bytes to allocate to new object of given type
410
411         This meta-function is called like
412         \code
413             senf::init_bytes<SomeParser>::value
414         \endcode
415
416         This expression evaluates to a compile-time constant integral expression of type
417         senf::PacketParserBase::size_type. This meta-function will return \c Parser::fixed_bytes or
418         \c Parser::init_bytes depending on the type of parser.
419
420         \param[in] Parser The Parser to return init_bytes for
421         \returns Number of bytes to allocate to the new object
422         \ingroup packetparser
423      */
424     template <class Parser>
425     struct init_bytes : public detail::ParserInitBytes<Parser>
426     {};
427
428     /** \brief Test, whether a parser is a fixed-size parser
429
430         This meta-function is called like
431         \code
432             senf::is_fixed<SomeParser>::value
433         \endcode
434
435         This expression evaluates to a compile-time constant boolean expression which is \c true, if
436         \a SomeParser is a fixed size parser, \c false otherwise
437
438         \param[in] Parser The Parser to test
439         \returns \c true, if \a Parser is fixed size, \c false otherwise
440         \ingroup packetparser
441      */
442     template <class Parser>
443     struct is_fixed : public detail::ParserIsFixed<Parser>
444     {};
445
446 #   ifndef DOXYGEN
447     template <class Parser>
448     typename boost::enable_if<
449         boost::is_base_of<PacketParserBase, Parser>,
450         Parser >::type
451     operator<<(Parser target, Parser source);
452 #   else
453     /** \brief Generic parser copying
454
455
456         This operator allows to copy the values of identical parsers. This operation does \e not
457         depend on the parsers detailed implementation, it will just replace the data bytes of the
458         target parser with those from the source parser. This allows to easily copy around complex
459         packet substructures.
460
461         This operation is different from the ordinary assignment operator: It does not change the \a
462         target parser, it changes the data referenced by the \a target parser.
463
464         \ingroup packetparser
465      */
466     template <class Parser>
467     Parser operator<<(Parser target, Parser source);
468 #   endif
469
470 #   ifndef DOXYGEN
471     template <class Parser, class Value>
472     typename boost::enable_if_c <
473         boost::is_base_of<PacketParserBase, Parser>::value
474             && ! boost::is_base_of<PacketParserBase, Value>::value,
475         Parser >::type
476     operator<<(Parser target, Value const & value);
477 #   else
478     /** \brief Generic parser value assignment
479
480         This operator allows to assign a value to parsers which implement a <tt>value(</tt>\a
481         value<tt>)</tt> member. This operator allows to use a common syntax for assigning values or
482         parsers to a parser.
483
484         \ingroup packetparser
485      */
486     template <class Parser, class Value>
487     Parser operator<<(Parser target, Value const & value);
488 #   endif
489
490 #   ifndef DOXYGEN
491     template <class Parser, class Value>
492     typename boost::enable_if_c <
493         boost::is_base_of<PacketParserBase, Parser>::value
494             && ! boost::is_base_of<PacketParserBase, Value>::value,
495         Parser >::type
496     operator<<(Parser target, boost::optional<Value> const & value);
497 #   else
498     /** \brief Generic parser value assignment
499
500         This operator allows to assign a value to parsers which implement a <tt>value(</tt>\a
501         value<tt>)</tt> member. This special version allows to assign optional values: IF the
502         optional value is not set, the assignment will be skipped.
503
504         This operator allows to use a common syntax for assigning values or parsers to a parser.
505
506         \ingroup packetparser
507      */
508     template <class Parser, class Value>
509     Parser operator<<(Parser target, boost::optional<Value> const & value);
510 #   endif
511
512     /** \brief Default parser parsing nothing
513      */
514     struct VoidPacketParser
515         : public PacketParserBase
516     {
517 #       include SENF_FIXED_PARSER()
518         SENF_PARSER_FINALIZE(VoidPacketParser);
519     };
520
521
522     template <class Parser, typename ValueType, PacketParserBase::size_type FixedBytes>
523     struct ValueParserBase : public PacketParserBase
524     {
525         typedef ValueParserBase<Parser, ValueType, FixedBytes> Base;
526
527         static size_type const fixed_bytes = FixedBytes;
528         typedef ValueType value_type;
529
530         ValueParserBase(data_iterator i, state_type s);
531
532         operator value_type () const;
533         byte & operator[](size_type index);
534         Parser const & operator= (value_type const & other);
535     };
536
537 }
538
539 //-/////////////////////////////////////////////////////////////////////////////////////////////////
540 #endif
541 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_PacketParser_i_)
542 #define HH_SENF_Packets_PacketParser_i_
543 #include "PacketParser.cci"
544 #include "PacketParser.ct"
545 #include "PacketParser.cti"
546 #endif
547
548 \f
549 // Local Variables:
550 // mode: c++
551 // fill-column: 100
552 // c-file-style: "senf"
553 // indent-tabs-mode: nil
554 // ispell-local-dictionary: "american"
555 // compile-command: "scons -u test"
556 // comment-column: 40
557 // End:
558