4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.be>
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.
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.
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.
24 \brief PacketParser public header */
26 /** \defgroup packetparser The PacketParser facility
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.
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).
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.
43 Since parsers are very lightweight and are passed by value, packet fields are accessed using the
44 corresponding accessor method:
49 // Assign new value to an integer parser
52 // Write out above value
53 std::cerr << p->someField() << "\n";
55 // Use the generic parser-assignment operator '<<' to copy field values
56 p->someVector()[1].someOtherField() << q->someField();
57 p->someVector() << q->someVector()
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).
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.
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.
81 \section parserimpl Packet parser categories
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()
90 Each parser type has specific features
92 \subsection parserimpl_value Value parsers
94 For a parser \a SomeParser to be a value parser, the following expressions must be valid:
96 // SomeParser must have a 'value_type', The 'value_type' must be default constructible, copy
97 // constructible and assignable
98 SomeParser::value_type v;
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()
104 // It must be possible to assign a new value using the 'value' member
105 p.someParserField().value(v)
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).
114 \subsection parserimpl_collection Collection parsers
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.
120 SomeParser::container c (p.someParserField());
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
129 \subsection parserimpl_composite Composite parsers
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.
139 \subsection parserimpl_packet Packet parsers
141 Packet parsers are composite parsers with relaxed requirements. Since a packet parser will never
142 be used as a sub-parser (it will not be used within another composite parser or as value type in
143 a collection parser), the value returned by senf::bytes for this parser must not necessarily
144 cover the complete packet (e.g. if the packet has a trailer, the trailer will live outside the
145 range given by senf::bytes). You may define any member you want to have in your packets field
146 interface. These members may access the packet data in any way. You just need to ensure, that
147 the integration into the packet-type is correct (the senf::PacketTypeMixin will by default use
148 senf::bytes() to find the end of the header).
153 #ifndef HH_PacketParser_
154 #define HH_PacketParser_ 1
157 #include <boost/utility/enable_if.hpp>
158 #include <boost/type_traits.hpp>
159 #include <boost/optional.hpp>
160 #include "../Utils/safe_bool.hh"
161 #include "PacketTypes.hh"
162 #include "PacketData.hh"
163 #include "ParseHelpers.hh"
165 //#include "PacketParser.mpp"
166 ///////////////////////////////hh.p////////////////////////////////////////
172 /** \brief Parser Base class
174 Parsers come in two flavors: fixed and dynamically sized parsers. A <em>fixed size
175 parser</em> has a constant size, it will always parse a fixed number of bytes. The low-level
176 'final' parsers (like the integer parsers) are fixed size parsers as are composite parsers
177 built up only of fixed-size fields.
179 A <em>dynamically sized</em> parser on the other hand infers it's size from the contents of
180 the data parsed. Any parser containing at least one dynamically sized sub-parser will itself
181 be dynamically sized.
183 Both kinds of parser need to derive from PacketParserBase and implement several required
184 members. Which members to implement depends on the parsers flavor. There are two ways how to
186 \li If the parser just consists of sequence of consecutive fields (sub-parsers), the \ref
187 packetparsermacros provide a simple yet flexible way to define a packet parser.
188 \li In more complex cases, you need to implement the necessary members manually.
190 This documentation is about the manual implementation. You should nevertheless read through
191 this to understand, what above macros are doing.
193 The following example documents the interface (which must be) provided by a parser:
195 struct FooParser : public PacketParserBase
197 FooParser(data_iterator i, state_type s) : PacketParserBase(i,s) {}
199 // If this parser has a fixed size, you must define this size here This definition
200 // allows the parser to be used within the list, vector and array parsers static
201 static const size_type fixed_bytes = some_constant_size;
203 // If the parser does not have a fixed size, you must implement the bytes() member to
204 // return the size. ONLY EVER DEFINE ONE OF fixed_bytes OR bytes().
205 size_type bytes() const;
207 // If you define bytes(), you also need to define the init_bytes. This is the number
208 // of bytes to allocate when creating a new object
209 static const size_type init_bytes = some_constant_size;
211 // You also may define an init() member. This will be called to initialize a newly
212 // created data object. The default implementation just does nothing.
215 // ////////////////////////////////////////////////////////////////////////
217 // Add here members returning (sub-)parsers for the fields. The 'parse' member is
218 // used to construct the sub-parsers. This member either takes an iterator to the
219 // data to be parsed or just an offset in bytes.
221 senf::UInt16Parser type() const { return parse<UInt16Parser>( 0 ); }
222 senf::UInt16Parser size() const { return parse<UInt16Parser>( 2 ); }
226 You should never call the \c bytes() member of a parser directly. Instead you should use the
227 freestanding senf::bytes() function. This function will return the correct size irrespective
228 of the parsers flavor. You may access \c fixed_bytes directly, however be aware that this
229 will restrict your code to fixed size parsers (which depending on the circumstances may be
230 exactly what you want).
232 In the same way, don't access \c init_bytes directly, always use the senf::init_bytes
233 meta-function class which correctly supports fixed size parsers.
235 \ingroup packetparser
237 class PacketParserBase
240 ///////////////////////////////////////////////////////////////////////////
243 typedef detail::packet::iterator data_iterator; ///< Raw data iterator type
244 typedef detail::packet::size_type size_type; ///< Unsigned integral type
245 typedef detail::packet::difference_type difference_type; ///< Signed integral type
246 typedef detail::packet::byte byte; ///< Unsigned 8bit value, the raw value type
247 typedef PacketData * state_type; ///< Type of the 'state' parameter
248 typedef PacketParserBase parser_base_type; ///< Base type of the next parser
250 ///////////////////////////////////////////////////////////////////////////
251 ///\name Structors and default members
254 // no default constructor
256 // default destructor
257 // no conversion constructors
260 ///////////////////////////////////////////////////////////////////////////
262 data_iterator i() const; ///< Return beginning of data to parse
263 /**< The parser is expected to interpret the data beginning
264 here. The size of the interpreted is given by
265 <tt>senf::bytes(</tt><em>parser
266 instance</em><tt>)</tt>. */
268 data_iterator i(size_type offset) const; ///< Return iterator \a offset bytes from the start
269 /**< The return value is the same as i() + \a
270 offset. However, the parser checks, that the iterator is
271 still within range of the raw data
272 container. Otherwise a TruncatedPacketException is
275 \throws TruncatedPacketException if the raw data
276 container does not hold at least \a offset bytes
279 state_type state() const; ///< Return state of this parser
280 /**< The value returned should be interpreted as an opaque
281 value provided just to be forwarded to other
284 PacketData & data() const; ///< Access the packets raw data container
285 /**< This member will return the raw data container holding
286 the data which is parsed by \c this parser. */
288 void init() const; ///< Default implementation
289 /**< This is just an empty default
290 implementation. Re-implement this member in your own
291 parsers if needed. */
294 PacketParserBase(data_iterator i, state_type s); ///< Standard constructor
295 /**< This is the constructor used by most parsers. The
296 parameters are just forwarded from the derived classes
297 constructor parameters. */
299 PacketParserBase(data_iterator i, state_type s, size_type size);
300 ///< Size checking constructor
301 /**< In addition to the standard constructor, this
302 constructor will validate, that there is enough data in
303 the raw data container to parse \a size bytes after \a
306 This constructor is called by all 'final' parsers
307 (e.g. the integer parsers) and \e only by those
308 parsers. Most parsers do \e not check the validity of
309 the iterator, this is delayed until the very last
310 parser. This allows to partial parse truncated
313 \throw TruncatedPacketException if the raw data
314 container does not hold at least \a size bytes
315 beginning at \a i. */
317 bool check(size_type size) const; ///< Check size of data container
318 /**< \returns \c true, if the data container holds at least
319 \a size beginning at i(), \c false otherwise. */
321 void validate(size_type size) const; ///< Validate size of data container
322 /**< \throws TruncatedPacketException if the raw data
323 container does not hold at least \a size bytes
326 template <class Parser> Parser parse(data_iterator i) const; ///< Create sub-parser
327 /**< Creates a new instance of \a Parser to parse data
328 beginning at \a i. Automatically passes \a state() to
331 template <class Parser> Parser parse(size_type n) const; ///< Create sub-parser
332 /**< Creates a new instance of \a Parser to parse data
333 * beginning at i()<tt> + </tt>\a n. Automatically passes \a
334 state() to the new parser. */
336 void defaultInit() const; ///< Default implementation
337 /**< This is just an empty default
338 implementation. Re-implement this member in your own
339 parsers if needed. */
341 Packet packet() const; ///< Get packet this parser is parsing from
342 /**< \note This member should only be used from packet
343 parsers when access to previous or following packets is
344 needed e.g. for calculating checksums etc. */
347 data_iterator end() const;
352 template <class Parser> friend class SafePacketParserWrapper;
355 /** \brief Return raw size parsed by the given parser object
357 This function will either call <tt>p.bytes()</tt> or return <tt>Parser::fixed_bytes</tt>
358 depending on the type of parser.
360 The value returned does \e not take into account the amount of data actually available. So
361 you always need to validate this value against the packet size if you directly access the
362 data. The standard low-level parses all do this check automatically to guard against
365 \param[in] p Parser object to check
366 \returns number of bytes this parser expects to parser
367 \ingroup packetparser
369 template <class Parser>
370 PacketParserBase::size_type bytes(Parser p);
372 namespace detail { template <class Parser> class ParserInitBytes; }
374 /** \brief Return number of bytes to allocate to new object of given type
376 This meta-function is called like
378 senf::init_bytes<SomeParser>::value
381 This expression evaluates to a compile-time constant integral expression of type
382 senf::PacketParserBase::size_type. This meta-function will return \c Parser::fixed_bytes or
383 \c Parser::init_bytes depending on the type of parser.
385 \param[in] Parser The Parser to return init_bytes for
386 \returns Number of bytes to allocate to the new object
387 \ingroup packetparser
389 template <class Parser>
390 struct init_bytes : public detail::ParserInitBytes<Parser>
394 template <class Parser>
395 typename boost::enable_if<
396 boost::is_base_of<PacketParserBase, Parser>,
398 operator<<(Parser target, Parser source);
400 /** \brief Generic parser copying
403 This operator allows to copy the values of identical parsers. This operation does \e not
404 depend on the parsers detailed implementation, it will just replace the data bytes of the
405 target parser with those from the source parser. This allows to easily copy around complex
406 packet substructures.
408 This operation is different from the ordinary assignment operator: It does not change the \a
409 target parser, it changes the data referenced by the \a target parser.
411 \ingroup packetparser
413 template <class Parser>
414 Parser operator<<(Parser target, Parser source);
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,
423 operator<<(Parser target, Value const & value);
425 /** \brief Generic parser value assignment
427 This operator allows to assign a value to parsers which implement a <tt>value(</tt>\a
428 value<tt>)</tt> member. This operator allows to use a common syntax for assigning values or
431 \ingroup packetparser
433 template <class Parser, class Value>
434 Parser operator<<(Parser target, Value const & value);
438 template <class Parser, class Value>
439 typename boost::enable_if_c <
440 boost::is_base_of<PacketParserBase, Parser>::value
441 && ! boost::is_base_of<PacketParserBase, Value>::value,
443 operator<<(Parser target, boost::optional<Value> const & value);
445 /** \brief Generic parser value assignment
447 This operator allows to assign a value to parsers which implement a <tt>value(</tt>\a
448 value<tt>)</tt> member. This special version allows to assign optional values: IF the
449 optional value is not set, the assignment will be skipped.
451 This operator allows to use a common syntax for assigning values or parsers to a parser.
453 \ingroup packetparser
455 template <class Parser, class Value>
456 Parser operator<<(Parser target, boost::optional<Value> const & value);
459 /** \brief Default parser parsing nothing
461 struct VoidPacketParser
462 : public PacketParserBase
464 # include SENF_FIXED_PARSER()
465 SENF_PARSER_FINALIZE(VoidPacketParser);
470 ///////////////////////////////hh.e////////////////////////////////////////
472 #if !defined(HH_Packets__decls_) && !defined(HH_PacketParser_i_)
473 #define HH_PacketParser_i_
474 #include "PacketParser.cci"
475 #include "PacketParser.ct"
476 #include "PacketParser.cti"
483 // c-file-style: "senf"
484 // indent-tabs-mode: nil
485 // ispell-local-dictionary: "american"
486 // compile-command: "scons -u test"
487 // comment-column: 40