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