Packet parsers are only used within the packet framework. You should never allocate a new parser instance directly, you should the Packet library let that do for you (either by having the parser as a packet parser in a packet type or by having a member in the packet parser which allocates the parser as a sub-parser).
Parsers are built hierarchically. A high-level parser will return other parsers when accessing an element (Example: Asking an EthernetParser for the ethertype field by calling the parsers type()
member will return an UInt16
parser). The lowest level building blocks then return the values. This hierarchical structure greatly simplifies building complex parsers.
Since parsers are very lightweight and are passed by value, packet fields are accessed using the corresponding accessor method:
SomePacket p (...) SomePacket q (...) // Assign new value to an integer parser p->someField() = 10; // Write out above value std::cerr << p->someField() << "\n"; // Use the generic parser-assignment operator '<<' to copy field values p->someVector()[1].someOtherField() << q->someField(); p->someVector() << q->someVector()
Here someField()
, someOtherField()
and someVector()
are accessor methods named after the field name. Each returns a parser object. Simple parsers can be used like their corresponding basic type (e.g. a UInt16Parser field can be used like an unsigned integer), more complex parsers provide type specific access members. Assigning a value to a parser will change the underlying representation (the packet data).
Parsers can be grouped into several categories. These categories are not all defined rigorously but are nevertheless helpful when working with the parsers:
i()
and with a size of senf::bytes() bytes).
Each parser type has specific features
// SomeParser must have a 'value_type', The 'value_type' must be default constructible, copy // constructible and assignable SomeParser::value_type v; // An instance of 'SomeParser' must have a 'value' member which returns a value which may be // assigned to a variable of type 'value_type' v = p.someParserField().value() // It must be possible to assign a new value using the 'value' member p.someParserField().value(v)
If at all possible, the 'value_type' should not reference the packet data using iterators or pointers, it should hold a copy of the value (it's Ok for value()
to return such a reference as long as assigning it to a value_type
variable will copy the value).
collection
member which is a wrapper providing the full interface.
SomeParser::container c (p.someParserField());
You will probably only very seldom need to implement a completely new collection parser. Instead, you can rely on senf::VectorParser or senf::ListParser and implement new policies.
_t
is a typedef for the fields parser and fieldname_offset
is the offset of the field in bytes from the beginning of the parser (either a constant for fixed size parsers or a member function for dynamically sized parsers). When defining composite parsers without the help of the Helper macros for defining new packet parsers, you should provide those same members.
Classes |
|
class | senf::PacketParserBase |
Parser Base class. More... |
|
struct | senf::init_bytes< Parser > |
Return number of bytes to allocate to new object of given type. More... |
|
struct | senf::is_fixed< Parser > |
Test, whether a parser is a fixed-size parser. More... |
|
class | senf::SafePacketParserWrapper< Parser > |
Iterator re-validating Parser wrapper. More... |
|
Modules |
|
Collection parsers | |
Integer parsers | |
Helper macros for defining new packet parsers | |
Functions |
|
template<class Parser > | |
PacketParserBase::size_type | senf::bytes (Parser p) |
Return raw size parsed by the given parser object. |
|
template<class Parser > | |
Parser | senf::operator<< (Parser target, Parser source) |
Generic parser copying. |
|
template<class Parser , class Value > | |
Parser | senf::operator<< (Parser target, Value const &value) |
Generic parser value assignment. |
|
template<class Parser , class Value > | |
Parser | senf::operator<< (Parser target, boost::optional< Value > const &value) |
Generic parser value assignment. |
senf::PacketParserBase::size_type senf:: | ||||
bytes | ( | Parser | p | ) |
Return raw size parsed by the given parser object.
This function will either call p.bytes()
or return Parser::fixed_bytes
depending on the type of parser.
The value returned does not take into account the amount of data actually available. So you always need to validate this value against the packet size if you directly access the data. The standard low-level parses all do this check automatically to guard against malformed packets.
[in] | p | Parser object to check |
Definition at line 68 of file PacketParser.cti.
Parser senf:: | ||||
operator<< | ( | Parser | target, | |
boost::optional< Value > const & | value | ) | ||
Generic parser value assignment.
This operator allows to assign a value to parsers which implement a value(
value)
member. This special version allows to assign optional values: IF the optional value is not set, the assignment will be skipped.
This operator allows to use a common syntax for assigning values or parsers to a parser.
Parser senf:: | ||||
operator<< | ( | Parser | target, | |
Value const & | value | ) | ||
Generic parser value assignment.
This operator allows to assign a value to parsers which implement a value(
value)
member. This operator allows to use a common syntax for assigning values or parsers to a parser.
Definition at line 85 of file PacketParser.cti.
Parser senf:: | ||||
operator<< | ( | Parser | target, | |
Parser | source | ) | ||
Generic parser copying.
This operator allows to copy the values of identical parsers. This operation does not depend on the parsers detailed implementation, it will just replace the data bytes of the target parser with those from the source parser. This allows to easily copy around complex packet substructures.
This operation is different from the ordinary assignment operator: It does not change the target parser, it changes the data referenced by the target parser.
Definition at line 53 of file PacketParser.ct.