4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at
9 // http://senf.berlios.de/license.html
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on,
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
15 // Software distributed under the License is distributed on an "AS IS" basis,
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
17 // for the specific language governing rights and limitations under the License.
19 // The Original Code is Fraunhofer FOKUS code.
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V.
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
26 // Stefan Bund <g0dil@berlios.be>
29 \brief PacketParser public header */
31 /** \defgroup packetparser The PacketParser facility
33 The PacketParser facility provides a framework to implement very lightweight classes which parse
34 the raw content of a packet into meaningful values. PacketParsers are always passed around
35 <em>by value</em>, they can be understood as pointers into the packet data with added type
36 information providing parsing functions.
38 Packet parsers are \e only used within the packet framework. You should never allocate a new
39 parser instance directly, you should the Packet library let that do for you (either by having
40 the parser as a packet parser in a packet type or by having a member in the packet parser which
41 allocates the parser as a sub-parser).
43 Parsers are built hierarchically. A high-level parser will return other parsers when accessing
44 an element (Example: Asking an EthernetParser for the ethertype field by calling the parsers \c
45 type() member will return an \c UInt16 parser). The lowest level building blocks then return the
46 values. This hierarchical structure greatly simplifies building complex parsers.
48 Since parsers are very lightweight and are passed by value, packet fields are accessed using the
49 corresponding accessor method:
54 // Assign new value to an integer parser
57 // Write out above value
58 std::cerr << p->someField() << "\n";
60 // Use the generic parser-assignment operator '<<' to copy field values
61 p->someVector()[1].someOtherField() << q->someField();
62 p->someVector() << q->someVector()
65 Here \c someField(), \c someOtherField() and \c someVector() are accessor methods named after
66 the field name. Each returns a parser object. Simple parsers can be used like their
67 corresponding basic type (e.g. a UInt16Parser field can be used like an unsigned integer), more
68 complex parsers provide type specific access members. Assigning a value to a parser will change
69 the underlying representation (the packet data).
71 Parsers can be grouped into several categories. These categories are not all defined rigorously
72 but are nevertheless helpful when working with the parsers:
73 \li <em>\ref parserimpl_value</em> provide the lowest level parsers (e.g. senf::UInt16Parser which
74 returns an integer value).
75 \li <em>\ref parserimpl_collection</em> are parsers which model a collection of sub-elements like
76 senf::ListParser or senf::VectorParser.
77 \li <em>\ref parserimpl_composite</em> collect several fields of arbitrary type into a new
78 parser. Parsers defined using the \ref packetparsermacros fall under this category.
79 \li <em>\ref parserimpl_packet</em> are used to define a packet type.
81 \warning Parsers are like iterators: They are invalidated <em>whenever the size of the packet's
82 data is changed</em>. You should not store a parser anywhere. If you want to keep a parser
83 reference, use the senf::SafePacketParserWrapper wrapper. You still will need to take extra care to
84 ensure the parser is not invalidated.
86 \section parserimpl Packet parser categories
88 Every parser is derived from senf::PacketParserBase. This class provides the necessary
89 housekeeping information and provides the parsers with access to the data. You may in principle
90 define arbitrary methods as parser members (e.g. methods to calculate a checksum, methods
91 processing fields in some way and so on). You should however be very wary to access data outside
92 the range assigned to the packet (the range starting at \c i() and with a size of senf::bytes()
95 Each parser type has specific features
97 \subsection parserimpl_value Value parsers
99 For a parser \a SomeParser to be a value parser, the following expressions must be valid:
101 // SomeParser must have a 'value_type', The 'value_type' must be default constructible, copy
102 // constructible and assignable
103 SomeParser::value_type v;
105 // An instance of 'SomeParser' must have a 'value' member which returns a value which may be
106 // assigned to a variable of type 'value_type'
107 v = p.someParserField().value()
109 // It must be possible to assign a new value using the 'value' member
110 p.someParserField().value(v)
113 If at all possible, the 'value_type' should not reference the packet data using iterators or
114 pointers, it should hold a copy of the value (it's Ok for \c value() to return such a reference
115 as long as assigning it to a \c value_type variable will copy the value).
119 \subsection parserimpl_collection Collection parsers
121 A collection parser \a SomeParser should model STL containers. The parsers themselves will
122 probably only // provide a reduced interface, but the collection parser should have a \c
123 collection member which is a wrapper providing the full interface.
125 SomeParser::container c (p.someParserField());
128 You will probably only very seldom need to implement a completely new collection
129 parser. Instead, you can rely on senf::VectorParser or senf::ListParser and implement new
134 \subsection parserimpl_composite Composite parsers
136 If possible, composite parsers should be implemented using the \ref packetparsermacros. In
137 addition to the normal parser requirements, these macros ensure, that for each field,
138 <em>fieldname</em><tt>_t</tt> is a typedef for the fields parser and
139 <em>fieldname</em><tt>_offset</tt> is the offset of the field in bytes from the beginning of the
140 parser (either a constant for fixed size parsers or a member function for dynamically sized
141 parsers). When defining composite parsers without the help of the \ref packetparsermacros, you
142 should provide those same members.
144 \subsection parserimpl_packet Protocol parsers
146 Protocol parsers are composite parsers with relaxed requirements. Since a Protocol parser will
147 never be used as a sub-parser (it will not be used within another composite parser or as value
148 type in a collection parser), the value returned by senf::bytes for this parser must not
149 necessarily cover the complete packet (e.g. if the packet has a trailer, the trailer will live
150 outside the range given by senf::bytes). You may define any member you want to have in your
151 packets field interface. These members may access the packet data in any way. You just need to
152 ensure, that the integration into the packet-type is correct (the senf::PacketTypeMixin will by
153 default use senf::bytes() to find the end of the header).
158 #ifndef HH_SENF_Packets_PacketParser_
159 #define HH_SENF_Packets_PacketParser_ 1
162 #include <boost/utility/enable_if.hpp>
163 #include <boost/type_traits.hpp>
164 #include <boost/optional.hpp>
165 #include <senf/Utils/safe_bool.hh>
166 #include "PacketTypes.hh"
167 #include "PacketData.hh"
168 #include "ParseHelpers.hh"
169 #include "SafeIterator.hh"
171 //#include "PacketParser.mpp"
172 //-/////////////////////////////////////////////////////////////////////////////////////////////////
178 /** \brief Parser Base class
180 Parsers come in two flavors: fixed and dynamically sized parsers. A <em>fixed size
181 parser</em> has a constant size, it will always parse a fixed number of bytes. The low-level
182 'final' parsers (like the integer parsers) are fixed size parsers as are composite parsers
183 built up only of fixed-size fields.
185 A <em>dynamically sized</em> parser on the other hand infers it's size from the contents of
186 the data parsed. Any parser containing at least one dynamically sized sub-parser will itself
187 be dynamically sized.
189 Both kinds of parser need to derive from PacketParserBase and implement several required
190 members. Which members to implement depends on the parsers flavor. There are two ways how to
192 \li If the parser just consists of sequence of consecutive fields (sub-parsers), the \ref
193 packetparsermacros provide a simple yet flexible way to define a packet parser.
194 \li In more complex cases, you need to implement the necessary members manually.
196 This documentation is about the manual implementation. You should nevertheless read through
197 this to understand, what above macros are doing.
199 The following example documents the interface (which must be) provided by a parser:
201 struct FooParser : public PacketParserBase
203 FooParser(data_iterator i, state_type s) : PacketParserBase(i,s) {}
205 // If this parser has a fixed size, you must define this size here This definition
206 // allows the parser to be used within the list, vector and array parsers static
207 static const size_type fixed_bytes = some_constant_size;
209 // If the parser does not have a fixed size, you must implement the bytes() member to
210 // return the size. ONLY EVER DEFINE ONE OF fixed_bytes OR bytes().
211 size_type bytes() const;
213 // If you define bytes(), you also need to define the init_bytes. This is the number
214 // of bytes to allocate when creating a new object
215 static const size_type init_bytes = some_constant_size;
217 // You also may define an init() member. This will be called to initialize a newly
218 // created data object. The default implementation just does nothing.
221 //-////////////////////////////////////////////////////////////////////////
223 // Add here members returning (sub-)parsers for the fields. The 'parse' member is
224 // used to construct the sub-parsers. This member either takes an iterator to the
225 // data to be parsed or just an offset in bytes.
227 senf::UInt16Parser type() const { return parse<UInt16Parser>( 0 ); }
228 senf::UInt16Parser size() const { return parse<UInt16Parser>( 2 ); }
232 You should never call the \c bytes() member of a parser directly. Instead you should use the
233 freestanding senf::bytes() function. This function will return the correct size irrespective
234 of the parsers flavor. You may access \c fixed_bytes directly, however be aware that this
235 will restrict your code to fixed size parsers (which depending on the circumstances may be
236 exactly what you want).
238 In the same way, don't access \c init_bytes directly, always use the senf::init_bytes
239 meta-function class which correctly supports fixed size parsers.
241 \ingroup packetparser
243 class PacketParserBase
246 //-////////////////////////////////////////////////////////////////////////
249 typedef detail::packet::iterator data_iterator; ///< Raw data iterator type
250 typedef detail::packet::size_type size_type; ///< Unsigned integral type
251 typedef detail::packet::difference_type difference_type; ///< Signed integral type
252 typedef detail::packet::byte byte; ///< Unsigned 8bit value, the raw value type
253 typedef PacketData * state_type; ///< Type of the 'state' parameter
254 typedef PacketParserBase parser_base_type; ///< Base type of the next parser
256 //-////////////////////////////////////////////////////////////////////////
257 ///\name Structors and default members
260 // no default constructor
262 // default destructor
263 // no conversion constructors
266 //-////////////////////////////////////////////////////////////////////////
268 data_iterator i() const; ///< Return beginning of data to parse
269 /**< The parser is expected to interpret the data beginning
270 here. The size of the interpreted is given by
271 <tt>senf::bytes(</tt><em>parser
272 instance</em><tt>)</tt>. */
274 data_iterator i(size_type offset) const; ///< Return iterator \a offset bytes from the start
275 /**< The return value is the same as i() + \a
276 offset. However, the parser checks, that the iterator is
277 still within range of the raw data
278 container. Otherwise a TruncatedPacketException is
281 \throws TruncatedPacketException if the raw data
282 container does not hold at least \a offset bytes
285 state_type state() const; ///< Return state of this parser
286 /**< The value returned should be interpreted as an opaque
287 value provided just to be forwarded to other
290 PacketData & data() const; ///< Access the packets raw data container
291 /**< This member will return the raw data container holding
292 the data which is parsed by \c this parser. */
294 void init() const; ///< Default implementation
295 /**< This is just an empty default
296 implementation. Re-implement this member in your own
297 parsers if needed. */
300 struct ParserProtector {
301 senf::safe_data_iterator safe_i_;
302 mutable PacketParserBase const * parser_;
304 ParserProtector(PacketParserBase const * parser);
305 ParserProtector(ParserProtector const & other_);
309 ParserProtector protect() const;
311 PacketParserBase(data_iterator i, state_type s); ///< Standard constructor
312 /**< This is the constructor used by most parsers. The
313 parameters are just forwarded from the derived classes
314 constructor parameters. */
316 PacketParserBase(data_iterator i, state_type s, size_type size);
317 ///< Size checking constructor
318 /**< In addition to the standard constructor, this
319 constructor will validate, that there is enough data in
320 the raw data container to parse \a size bytes after \a
323 This constructor is called by all 'final' parsers
324 (e.g. the integer parsers) and \e only by those
325 parsers. Most parsers do \e not check the validity of
326 the iterator, this is delayed until the very last
327 parser. This allows to partial parse truncated
330 \throw TruncatedPacketException if the raw data
331 container does not hold at least \a size bytes
332 beginning at \a i. */
334 bool check(size_type size) const; ///< Check size of data container
335 /**< \returns \c true, if the data container holds at least
336 \a size beginning at i(), \c false otherwise. */
338 void validate(size_type size) const; ///< Validate size of data container
339 /**< \throws TruncatedPacketException if the raw data
340 container does not hold at least \a size bytes
343 template <class Parser> Parser parse(data_iterator i) const; ///< Create sub-parser
344 /**< Creates a new instance of \a Parser to parse data
345 beginning at \a i. Automatically passes \a state() to
348 template <class Parser, class Arg> Parser parse(Arg const & arg, data_iterator i) const;
349 ///< Create sub-parser
350 /**< This is like parse(data_iterator), however it passes
351 the extra argument \a arg to the \a Parser
354 template <class Parser> Parser parse(size_type n) const; ///< Create sub-parser
355 /**< Creates a new instance of \a Parser to parse data
356 * beginning at i()<tt> + </tt>\a n. Automatically passes \a
357 state() to the new parser. */
359 template <class Parser, class Arg> Parser parse(Arg const & arg, size_type n) const;
360 ///< Create sub-parser
361 /**< This is like parse(size_type), however it passes the
362 extra argument \a arg to the \a Parser constructor. */
364 void defaultInit() const; ///< Default implementation
365 /**< This is just an empty default
366 implementation. Re-implement this member in your own
367 parsers if needed. */
369 Packet packet() const; ///< Get packet this parser is parsing from
370 /**< \note This member should only be used from packet
371 parsers when access to previous or following packets is
372 needed e.g. for calculating checksums etc. */
374 void resize(size_type oldSize, size_type newSize); ///< Resize data container
375 /**< This command will erase or insert bytes from/into the
376 data container at the end of the parser (at i() + \a
377 newSize). If \a oldSize is > \a newSize, bytes will be
378 removed, otherwise bytes will be inserted.
380 \warning This may invalidate iterators and other
381 parsers. The current parser itself is automatically
385 data_iterator end() const;
390 template <class Parser> friend class SafePacketParserWrapper;
391 friend struct ParserProtector;
394 /** \brief Return raw size parsed by the given parser object
396 This function will either call <tt>p.bytes()</tt> or return <tt>Parser::fixed_bytes</tt>
397 depending on the type of parser.
399 The value returned does \e not take into account the amount of data actually available. So
400 you always need to validate this value against the packet size if you directly access the
401 data. The standard low-level parses all do this check automatically to guard against
404 \param[in] p Parser object to check
405 \returns number of bytes this parser expects to parser
406 \ingroup packetparser
408 template <class Parser>
409 PacketParserBase::size_type bytes(Parser const & p);
411 namespace detail { template <class Parser> struct ParserInitBytes; }
412 namespace detail { template <class Parser> struct ParserIsFixed; }
414 /** \brief Return number of bytes to allocate to new object of given type
416 This meta-function is called like
418 senf::init_bytes<SomeParser>::value
421 This expression evaluates to a compile-time constant integral expression of type
422 senf::PacketParserBase::size_type. This meta-function will return \c Parser::fixed_bytes or
423 \c Parser::init_bytes depending on the type of parser.
425 \param[in] Parser The Parser to return init_bytes for
426 \returns Number of bytes to allocate to the new object
427 \ingroup packetparser
429 template <class Parser>
430 struct init_bytes : public detail::ParserInitBytes<Parser>
433 /** \brief Test, whether a parser is a fixed-size parser
435 This meta-function is called like
437 senf::is_fixed<SomeParser>::value
440 This expression evaluates to a compile-time constant boolean expression which is \c true, if
441 \a SomeParser is a fixed size parser, \c false otherwise
443 \param[in] Parser The Parser to test
444 \returns \c true, if \a Parser is fixed size, \c false otherwise
445 \ingroup packetparser
447 template <class Parser>
448 struct is_fixed : public detail::ParserIsFixed<Parser>
452 template <class Parser>
453 typename boost::enable_if<
454 boost::is_base_of<PacketParserBase, Parser>,
456 operator<<(Parser target, Parser source);
458 /** \brief Generic parser copying
461 This operator allows to copy the values of identical parsers. This operation does \e not
462 depend on the parsers detailed implementation, it will just replace the data bytes of the
463 target parser with those from the source parser. This allows to easily copy around complex
464 packet substructures.
466 This operation is different from the ordinary assignment operator: It does not change the \a
467 target parser, it changes the data referenced by the \a target parser.
469 \ingroup packetparser
471 template <class Parser>
472 Parser operator<<(Parser target, Parser source);
476 template <class Parser, class Value>
477 typename boost::enable_if_c <
478 boost::is_base_of<PacketParserBase, Parser>::value
479 && ! boost::is_base_of<PacketParserBase, Value>::value,
481 operator<<(Parser target, Value const & value);
483 /** \brief Generic parser value assignment
485 This operator allows to assign a value to parsers which implement a <tt>value(</tt>\a
486 value<tt>)</tt> member. This operator allows to use a common syntax for assigning values or
489 \ingroup packetparser
491 template <class Parser, class Value>
492 Parser operator<<(Parser target, Value const & value);
496 template <class Parser, class Value>
497 typename boost::enable_if_c <
498 boost::is_base_of<PacketParserBase, Parser>::value
499 && ! boost::is_base_of<PacketParserBase, Value>::value,
501 operator<<(Parser target, boost::optional<Value> const & value);
503 /** \brief Generic parser value assignment
505 This operator allows to assign a value to parsers which implement a <tt>value(</tt>\a
506 value<tt>)</tt> member. This special version allows to assign optional values: IF the
507 optional value is not set, the assignment will be skipped.
509 This operator allows to use a common syntax for assigning values or parsers to a parser.
511 \ingroup packetparser
513 template <class Parser, class Value>
514 Parser operator<<(Parser target, boost::optional<Value> const & value);
517 /** \brief Default parser parsing nothing
519 struct VoidPacketParser
520 : public PacketParserBase
522 # include SENF_FIXED_PARSER()
523 SENF_PARSER_FINALIZE(VoidPacketParser);
527 template <class Parser, typename ValueType, PacketParserBase::size_type FixedBytes>
528 struct ValueParserBase : public PacketParserBase
530 typedef ValueParserBase<Parser, ValueType, FixedBytes> Base;
532 static size_type const fixed_bytes = FixedBytes;
533 typedef ValueType value_type;
535 ValueParserBase(data_iterator i, state_type s);
537 operator value_type () const;
538 byte & operator[](size_type index);
539 Parser const & operator= (value_type const & other);
544 //-/////////////////////////////////////////////////////////////////////////////////////////////////
546 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_PacketParser_i_)
547 #define HH_SENF_Packets_PacketParser_i_
548 #include "PacketParser.cci"
549 #include "PacketParser.ct"
550 #include "PacketParser.cti"
557 // c-file-style: "senf"
558 // indent-tabs-mode: nil
559 // ispell-local-dictionary: "american"
560 // compile-command: "scons -u test"
561 // comment-column: 40