Class: PacketFu::TcpOption

Inherits:
Struct
  • Object
show all
Includes:
StructFu
Defined in:
lib/packetfu/protos/tcp/option.rb

Overview

TcpOption is the base class for all TCP options. Note that TcpOption#len returns the size of the entire option, while TcpOption#optlen is the struct for the TCP Option Length field.

Subclassed options should set the correct TcpOption#kind by redefining initialize. They should also deal with various value types there by setting them explicitly with an accompanying StructFu#typecast for the setter.

By default, values are presumed to be strings, unless they are Numeric, in which case a guess is made to the width of the Numeric based on the given optlen.

Note that normally, optlen is /not/ enforced for directly setting values, so the user is perfectly capable of setting incorrect lengths.

Direct Known Subclasses

ECHO, ECHOREPLY, EOL, MSS, NOP, SACK, SACKOK, TS, WS

Defined Under Namespace

Classes: ECHO, ECHOREPLY, EOL, MSS, NOP, SACK, SACKOK, TS, WS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from StructFu

#body=, #clone, #set_endianness, #sz, #typecast

Methods inherited from Struct

#force_binary

Constructor Details

#initialize(args = {}) ⇒ TcpOption

Returns a new instance of TcpOption


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/packetfu/protos/tcp/option.rb', line 21

def initialize(args={})
  super(
    Int8.new(args[:kind]),
    Int8.new(args[:optlen])
  )
  if args[:value].kind_of? Numeric
    self[:value] = case args[:optlen]
                   when 3; Int8.new(args[:value])
                   when 4; Int16.new(args[:value])
                   when 6; Int32.new(args[:value])
                   else; StructFu::String.new.read(args[:value])
                   end
  else
    self[:value] = StructFu::String.new.read(args[:value])
  end
end

Instance Attribute Details

#kindObject

Returns the value of attribute kind

Returns:

  • (Object)

    the current value of kind


17
18
19
# File 'lib/packetfu/protos/tcp/option.rb', line 17

def kind
  @kind
end

#optlenObject

Returns the value of attribute optlen

Returns:

  • (Object)

    the current value of optlen


17
18
19
# File 'lib/packetfu/protos/tcp/option.rb', line 17

def optlen
  @optlen
end

#valueObject

Returns the value of attribute value

Returns:

  • (Object)

    the current value of value


17
18
19
# File 'lib/packetfu/protos/tcp/option.rb', line 17

def value
  @value
end

Instance Method Details

#decodeObject

The default decode for an unknown option. Known options should redefine this.


60
61
62
63
# File 'lib/packetfu/protos/tcp/option.rb', line 60

def decode
  unk = "unk-#{self.kind.to_i}"
  (self[:optlen].to_i > 2 && self[:value].to_s.size > 1) ? [unk,self[:value]].join(":") : unk
end

#encode(str) ⇒ Object

Generally, encoding a value is going to be just a read. Some options will treat things a little differently; TS for example, takes two values and concatenates them.


84
85
86
# File 'lib/packetfu/protos/tcp/option.rb', line 84

def encode(str)
  self[:value] = self.class.new(:value => str).value
end

#has_optlen?Boolean

Returns true if this option has an optlen. Some don't.

Returns:

  • (Boolean)

89
90
91
# File 'lib/packetfu/protos/tcp/option.rb', line 89

def has_optlen?
  (kind.value && kind.value < 2) ? false : true
end

#has_value?Boolean

Returns true if this option has a value. Some don't.

Returns:

  • (Boolean)

94
95
96
# File 'lib/packetfu/protos/tcp/option.rb', line 94

def has_value?
  (value.respond_to? :to_s && value.to_s.size > 0) ? false : true
end

#read(str) ⇒ Object

Reads a string to populate the object.


46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/packetfu/protos/tcp/option.rb', line 46

def read(str)
  force_binary(str)
  return self if str.nil?
  self[:kind].read(str[0,1])
  if str[1,1]
    self[:optlen].read(str[1,1])
    if str[2,1] && optlen.value > 2
      self[:value].read(str[2,optlen.value-2])
    end
  end
  self
end

#to_sObject

Returns the object in string form.


39
40
41
42
43
# File 'lib/packetfu/protos/tcp/option.rb', line 39

def to_s
  self[:kind].to_s + 
  (self[:optlen].value.nil? ? nil : self[:optlen]).to_s +
  (self[:value].nil? ? nil : self[:value]).to_s
end