Module: PacketGen::Header::HeaderClassMethods
- Defined in:
- lib/packetgen/header/header_class_methods.rb
Defined Under Namespace
Classes: Binding
Instance Method Summary collapse
-
#bind_header(header_klass, args = {}) ⇒ void
Bind a upper header to current class.
-
#define_bit_fields_on(attr, *args) ⇒ void
Define a bitfield on given attribute class MyHeader < Struct.new(:flags) def initialize(options={}) super Int16.new(options) end # define a bit field on :flag attribute: # flag1, flag2 and flag3 are 1-bit fields # type and stype are 3-bit fields.
-
#known_headers ⇒ Hash
private
Get knwon headers.
Instance Method Details
#bind_header(header_klass, args = {}) ⇒ void
This method returns an undefined value.
Bind a upper header to current class
20 21 22 23 24 25 26 |
# File 'lib/packetgen/header/header_class_methods.rb', line 20 def bind_header(header_klass, args={}) @known_headers ||= {} @known_headers[header_klass] ||= [] args.each do |key, value| @known_headers[header_klass] << Binding.new(key, value) end end |
#define_bit_fields_on(attr, *args) ⇒ void
This method returns an undefined value.
Define a bitfield on given attribute
class MyHeader < Struct.new(:flags)
def initialize(options={})
super Int16.new(options[:flags])
end
# define a bit field on :flag attribute:
# flag1, flag2 and flag3 are 1-bit fields
# type and stype are 3-bit fields. reserved is a 6-bit field
define_bit_fields_on :flags, :flag1, :flag2, :flag3, :type, 3, :stype, 3, :reserved: 6
end
A bitfield of size 1 bit defines 2 methods:
-
#field?which returns a Boolean, -
#field=which takes and returns a Boolean.
A bitfield of more bits defines 2 methods:
-
#fieldwhich returns an Integer, -
#field=which takes and returns an Integer.
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/packetgen/header/header_class_methods.rb', line 58 def define_bit_fields_on(attr, *args) total_size = self.new[attr].width * 8 idx = total_size - 1 field = args.shift while field next unless field.is_a? Symbol size = if args.first.is_a? Integer args.shift else 1 end unless field == :_ shift = idx - (size - 1) field_mask = (2**size - 1) << shift clear_mask = (2**total_size - 1) & (~field_mask & (2**total_size - 1)) if size == 1 class_eval <<-EOM def #{field}? val = (self[:#{attr}].to_i & #{field_mask}) >> #{shift} val != 0 end def #{field}=(v) val = v ? 1 : 0 self[:#{attr}].value = self[:#{attr}].to_i & #{clear_mask} self[:#{attr}].value |= val << #{shift} end EOM else class_eval <<-EOM def #{field} (self[:#{attr}].to_i & #{field_mask}) >> #{shift} end def #{field}=(v) self[:#{attr}].value = self[:#{attr}].to_i & #{clear_mask} self[:#{attr}].value |= (v & #{2**size - 1}) << #{shift} end EOM end end idx -= size field = args.shift end end |
#known_headers ⇒ Hash
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Get knwon headers
31 32 33 |
# File 'lib/packetgen/header/header_class_methods.rb', line 31 def known_headers @known_headers ||= {} end |