Class: PacketGen::Types::AbstractTLV
- Defined in:
- lib/packetgen/types/abstract_tlv.rb
Overview
This class is an abstract class to define type-length-value data.
This class supersede TLV class, which is not well defined on some corner cases.
Usage
To simply define a new TLV class, do:
MyTLV = PacketGen::Types::AbstractTLV.create
MyTLV.define_type_enum 'one' => 1, 'two' => 2
This will define a new MyTLV class, subclass of Fields. This class will define 3 fields:
.define_type_enum is, here, necessary to define enum hash to be used for #type accessor, as this one is defined as an Enum.
This class may then be used as older TLV class:
tlv = MyTLV.new(type: 1, value: 'abcd') # automagically set #length from value
tlv.type #=> 1
tlv.human_type #=> 'one'
tlv.length #=> 4
tlv.value #=> "abcd"
Advanced usage
Each field’s type may be change at generating TLV class:
MyTLV = PacketGen::Types::AbstractTLV.create(type_class: PacketGen::Types::Int16,
length_class: PacketGen::Types::Int16,
value_class: PacketGen::Header::IP::Addr)
tlv = MyTLV.new(type: 1, value: '1.2.3.4')
tlv.type #=> 1
tlv.length #=> 4
tlv.value #=> '1.2.3.4'
tlv.to_s #=> "\x00\x01\x00\x04\x01\x02\x03\x04"
Some aliases may also be defined. For example, to create a TLV type whose type field should be named code:
MyTLV = PacketGen::Types::AbstractTLV.create(type_class: PacketGen::Types::Int16,
length_class: PacketGen::Types::Int16,
aliases: { code: :type })
tlv = MyTLV.new(code: 1, value: 'abcd')
tlv.code #=> 1
tlv.type #=> 1
tlv.length #=> 4
tlv.value #=> 'abcd'
Direct Known Subclasses
Header::DHCP::IPAddrOption, Header::DHCP::Int16Option, Header::DHCP::Int32Option, Header::DHCP::Int8Option, Header::DHCP::Option, Header::DNS::Option, Header::Dot11::Element
Class Attribute Summary collapse
Instance Attribute Summary collapse
- #length ⇒ Integer abstract
- #type ⇒ Integer abstract
- #value ⇒ Object abstract
Class Method Summary collapse
-
.create(type_class: Int8Enum, length_class: Int8, value_class: String, aliases: {}) ⇒ Class
Generate a TLV class.
-
.define_type_enum(hsh) ⇒ void
abstract
Set enum hash for #type field.
Instance Method Summary collapse
-
#human_type ⇒ String
abstract
Get human-readable type.
-
#initialize(options = {}) ⇒ AbstractTLV
constructor
abstract
A new instance of AbstractTLV.
-
#read(str) ⇒ Fields
abstract
Populate object from a binary string.
- #to_human ⇒ String abstract
Methods inherited from Fields
#[], #[]=, #bits_on, define_bit_fields_on, define_field, define_field_after, define_field_before, #fields, fields, inherited, #inspect, #offset_of, #optional?, #optional_fields, #present?, remove_bit_fields_on, remove_field, #sz, #to_h, #to_s, update_field
Constructor Details
#initialize(options = {}) ⇒ AbstractTLV
Should only be called on real TLV classes, created by create.
Returns a new instance of AbstractTLV.
119 120 121 122 123 124 125 126 127 |
# File 'lib/packetgen/types/abstract_tlv.rb', line 119 def initialize(={}) self.class.aliases.each do |al, orig| [orig] = [al] if .key?(al) end super # used #value= defined below, which set length if needed self.value = [:value] if [:value] end |
Class Attribute Details
.aliases ⇒ Hash
63 64 65 |
# File 'lib/packetgen/types/abstract_tlv.rb', line 63 def aliases @aliases end |
Instance Attribute Details
#length ⇒ Integer
Length attribute for real TLV class
|
|
# File 'lib/packetgen/types/abstract_tlv.rb', line 95
|
#type ⇒ Integer
Type attribute for real TLV class
|
|
# File 'lib/packetgen/types/abstract_tlv.rb', line 95
|
#value ⇒ Object
Value attribute for real TLV class
|
|
# File 'lib/packetgen/types/abstract_tlv.rb', line 95
|
Class Method Details
.create(type_class: Int8Enum, length_class: Int8, value_class: String, aliases: {}) ⇒ Class
Generate a TLV class
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/packetgen/types/abstract_tlv.rb', line 72 def self.create(type_class: Int8Enum, length_class: Int8, value_class: String, aliases: {}) raise Error, '.create cannot be called on a subclass of PacketGen::Types::AbstractTLV' unless self.equal? AbstractTLV klass = Class.new(self) klass.aliases = aliases if type_class < Enum klass.define_field :type, type_class, enum: {} else klass.define_field :type, type_class end klass.define_field :length, length_class klass.define_field :value, value_class aliases.each do |al, orig| klass.instance_eval do alias_method al, orig if klass.method_defined?(orig) alias_method :"#{al}=", :"#{orig}=" if klass.method_defined?(:"#{orig}=") end end klass end |
.define_type_enum(hsh) ⇒ void
109 110 111 112 |
# File 'lib/packetgen/types/abstract_tlv.rb', line 109 def self.define_type_enum(hsh) field_defs[:type][:enum].clear field_defs[:type][:enum].merge!(hsh) end |
Instance Method Details
#human_type ⇒ String
Should only be called on real TLV class instances.
Get human-readable type
156 157 158 |
# File 'lib/packetgen/types/abstract_tlv.rb', line 156 def human_type self[:type].to_human.to_s end |
#read(str) ⇒ Fields
Should only be called on real TLV class instances.
Populate object from a binary string
133 134 135 136 137 138 139 140 141 |
# File 'lib/packetgen/types/abstract_tlv.rb', line 133 def read(str) idx = 0 self[:type].read str[idx, self[:type].sz] idx += self[:type].sz self[:length].read str[idx, self[:length].sz] idx += self[:length].sz self[:value].read str[idx, self.length] self end |
#to_human ⇒ String
Should only be called on real TLV class instances.
162 163 164 165 |
# File 'lib/packetgen/types/abstract_tlv.rb', line 162 def to_human my_value = self[:value].is_a?(String) ? value.inspect : value.to_human "type:%s,length:%u,value:#{my_value}" % [human_type, length] end |