Class: Libnet::Header

Inherits:
Object
  • Object
show all
Includes:
Helpers
Defined in:
lib/libnet4r/header.rb

Overview

:nodoc:

Direct Known Subclasses

ARP, Ethernet, IPv4, IPv6, UDP, VLAN

Constant Summary collapse

HWADDR_RE =
/^[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}$/
IPADDR_RE =
/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/
DEFAULT_OPTS =
{
  :units     => :bytes,
  :read_only => false,
  :optional  => false,
  :aliases   => []
}
UNIT_MULTIPLIERS =
{
  :bits  => 1,
  :bytes => 8,
  :words => 16,
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Helpers

#check_integer, #check_string

Constructor Details

#initialize(bytes = nil) ⇒ Header

Returns a new instance of Header.



155
156
157
158
159
160
161
162
# File 'lib/libnet4r/header.rb', line 155

def initialize(bytes = nil)
  self.class.decode(bytes) if bytes

  # only used if class has a checksum field
  @auto_checksum = true

  self
end

Instance Attribute Details

#ptagObject (readonly)

Returns the value of attribute ptag.



153
154
155
# File 'lib/libnet4r/header.rb', line 153

def ptag
  @ptag
end

Class Method Details

.assignment_filter(*fields, &blk) ⇒ Object



91
92
93
94
95
# File 'lib/libnet4r/header.rb', line 91

def assignment_filter(*fields, &blk)
  fields.each do |f|
    self.assignment_filters[f] = blk
  end
end

.decode(bytes) ⇒ Object

Raises:

  • (NotImplementedError)


97
98
99
# File 'lib/libnet4r/header.rb', line 97

def decode(bytes)
  raise NotImplementedError, "class #{self} has not implemented a decode method"
end

.fieldsObject



101
102
103
# File 'lib/libnet4r/header.rb', line 101

def fields
  self.required_fields + self.optional_fields + self.read_only_fields
end

.inherited(cl) ⇒ Object



27
28
29
30
31
32
# File 'lib/libnet4r/header.rb', line 27

def inherited(cl)
  cl.assignment_filters = {}
  cl.required_fields    = []
  cl.optional_fields    = []
  cl.read_only_fields   = []
end

.octets_field(name, size = nil, opts = {}) ⇒ Object



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
# File 'lib/libnet4r/header.rb', line 63

def octets_field(name, size = nil, opts = {})
  opts = DEFAULT_OPTS.merge opts
  ivar = "@#{name}".to_sym

  unless opts[:read_only]
    self.class_eval do
      define_method("#{name}=") do |v|
        value = v.dup
        if self.assignment_filters.has_key? name
          value = self.assignment_filters[name].call(v)
        end

        check_string(value)

        if size && value.length != size
          raise ArgumentError, "value must be #{size} bytes long for field '#{name}'"
        end

        instance_variable_set(ivar, value)
      end
    end
  end

  add_field(name, opts)

  nil
end

.unsigned_field(name, size, opts = {}) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/libnet4r/header.rb', line 34

def unsigned_field(name, size, opts = {})
  opts  = DEFAULT_OPTS.merge opts
  size  = size * UNIT_MULTIPLIERS[opts[:units]]
  ivar  = "@#{name}".to_sym
  range = 0..2**size-1

  unless opts[:read_only]
    self.class_eval do
      define_method("#{name}=") do |v|
        if self.assignment_filters.has_key? name
          v = self.assignment_filters[name].call(v)
        end

        check_integer(v)

        unless range.include? v
          raise ArgumentError, "value #{v} is out of range for field '#{name}'"
        end

        instance_variable_set(ivar, v)
      end
    end
  end

  add_field(name, opts)

  nil
end