Create Custom Protocol
PacketGen allows you adding your own header classes.
Quick start
To add a new/custom header, you first have to define the new header class. For example:
Then, class must be declared to PacketGen:
Finally, bindings must be declared:
And use it:
Add a new header type, in more detail
Define a header class
A new header class should inherit from PacketGen::Header::Base
class (or from PacketGen::Header::ASN1Base
, see below). This base class implements minimal API (see below) to parse a header from binary string, or to generate binary string from a header class.
PacketGen::Header::Base
inherits from PacketGen::Types::Fields
, which is a class to define headers or anything else with a binary format containing multiple fields.
Here, magical method is define_field
. This method define a field and its name. You may set as fields as you need. A type may be a predefined type from PacketGen::Types
, or any other PacketGen::Types::Fields
subclass:
Here, some example to access these fields:
Builtin Types
All builtin types are listed here.
Add some methods to a header class
By default, all fields will have accessors with the good type. By example, a Types::Int32
field may be accessed as an Integer, a Types::String
may be accessed as a String, etc.
But, for some reason, you may need to add another accessor, or a method to compute some protocol data.
To do that, you have to understand Fields model. A field may be accessed through its accessor, as already seen. But it may also be accessed through Fields' hash.
Fields class defines #[]
method to access to field object by its name. By example, with our previously defined ExampleHeader:
Sometimes, you will need to access real field object. All field objects have common methods:
#read
reads a binary string to set object,#to_s
gives binary string from object,#sz
gives binary size.
As an example of method in a header class, we will define one to calculate first
field, which value should be size of custom field:
Add a new ASN.1 header
Some header may be defined using ASN.1 notation, like SNMP.
To define such a header, use PacketGen::Header::ASN1Base
as base class:
This definition uses lots of stuffs from rasn1
gem:
sequence
defines a ASN.1 Sequence namedmessage
. This sequence contains:an Enumerated named
version
,an Octet String named
community
,and a PDUClass (subclass of
RASN1::Model
) nameddata
and not defined here.
define_attributes
is a helper method to declare attributes from some ASN.1 fields. This helps to mimic standard header behavior.
Packet magics
PacketGen::Packet
defines some magics using specific header methods.
If your header class has a checksum field and/or a length field, Packet
provides magic for them. You have to define a #calc_checksum
and/or a calc_length
which appropriately set checksum and/or length fields respectively. Then Packet#calc_checksum
and Packet#calc_length
will calculate all checksum and length fields in all headers, including yours.
If your header class is not an application layer one, you should define a body
field of type PacketGen::Types::String
. This will allow Packet#parse
to automagically parse headers embedded in yours. Same magic will happen for Packet#to_s
, Packet#encapsulate
, Packet#decapsulate
and Packet#add
.
Header minimal API
PacketGen::Header::Base
and PacketGen::Header::ASN1Base
are provided to simplify writing of new headers. But they may not be so useful for some protocol types.
So, here is minimal API needed by PacketGen to handle a header class.
A header MUST have accessors:
#packet
: get/set packet to which header belongs.
A header MUST respond to:
#protocol_name
: get protocol name, usually class name as a String, withoutmodule path,
#method_name
: get method name, usually same as protocol name but downcase.This name is used as accessor from packet to access header object,
#read
: method to parse binary string and decode header,#to_s
: method to generate binary data of header to send on wire,#parse?
: returntrue
if decoded header is correct. Used when guessing ifheader may be decoded from binary string. An example of use if checking first
4-bit field for IP version in a IP/IPv6 header.
Last updated