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
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
19 20 21 22 23 |
# File 'lib/packetgen/header/header_class_methods.rb', line 19 def bind_header(header_klass, args={}) @known_headers ||= {} key = args.keys.first @known_headers[header_klass] = Binding.new(key, args[key]) 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.
54 55 56 57 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 |
# File 'lib/packetgen/header/header_class_methods.rb', line 54 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
Get knwon headers
27 28 29 |
# File 'lib/packetgen/header/header_class_methods.rb', line 27 def known_headers @known_headers ||= {} end |