Class: PacketGen::Header::TCP::Option

Inherits:
Base show all
Defined in:
lib/packetgen/header/tcp/option.rb

Overview

Base class to describe a TCP option

Author:

  • Sylvain Daubert

Direct Known Subclasses

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

Constant Summary collapse

EOL_KIND =

EOL option value

0
NOP_KIND =

NOP option value

1
MSS_KIND =

MSS option value

2
WS_KIND =

WS option value

3
SACKOK_KIND =

SACKOK option value

4
SACK_KIND =

SACK option value

5
ECHO_KIND =

ECHO option value

6
ECHOREPLY_KIND =

ECHOREPLY option value

7
TS_KIND =

TS option value

8

Instance Attribute Summary collapse

Attributes inherited from Base

#packet

Instance Method Summary collapse

Methods inherited from Base

bind_header, #header_id, inherited, #ip_header, known_headers, #parse?, #protocol_name

Methods inherited from Types::Fields

#[], #[]=, #body=, define_bit_fields_on, define_field, define_field_after, define_field_before, #fields, #force_binary, inherited, #sz, #to_h

Constructor Details

#initialize(options = {}) ⇒ Option

Returns a new instance of Option.

Parameters:

  • options (hash) (defaults to: {})

Options Hash (options):

  • :kind (Integer)
  • :length (Integer)
  • :value (Integer, String)


44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/packetgen/header/tcp/option.rb', line 44

def initialize(options={})
  super
  case options[:value]
  when Integer
    klass = case self[:length].to_i
            when 3; Types::Int8
            when 4; Types::Int16
            when 6; Types::Int32
            else
              raise ArgumentError, 'impossible length'
            end
    self[:value] = klass.new(options[:value])
  when NilClass
    self[:value] = Types::String.new
  else
    self[:value] = Types::String.new.read(options[:value])
    self[:length].read(self[:value].sz + 2) unless options[:length]
  end
end

Instance Attribute Details

#kindInteger

Option kind

Returns:

  • (Integer)

    8-bit option kind



31
# File 'lib/packetgen/header/tcp/option.rb', line 31

define_field :kind, Types::Int8

#lengthInteger

Option length

Returns:

  • (Integer)

    8-bit option length



35
# File 'lib/packetgen/header/tcp/option.rb', line 35

define_field :length, Types::Int8

#valueString, Integer

Getter for value attribute

Returns:

  • (String, Integer)


38
# File 'lib/packetgen/header/tcp/option.rb', line 38

define_field :value, Types::String

Instance Method Details

#has_length?Boolean

Returns:

  • (Boolean)


81
82
83
# File 'lib/packetgen/header/tcp/option.rb', line 81

def has_length?
  self[:kind].value && kind >= 2
end

#inspectString

Returns:

  • (String)


116
117
118
119
120
# File 'lib/packetgen/header/tcp/option.rb', line 116

def inspect
  str = "#<#{self.class} kind=#{self[:kind].value.inspect} "
  str << "length=#{self[:length].value.inspect} " if self[:length].value
  str << "value=#{self[:value].inspect}>"
end

#read(str) ⇒ self

Read a TCP option from a string

Parameters:

  • str (String)

    binary string

Returns:

  • (self)


67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/packetgen/header/tcp/option.rb', line 67

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

#to_humanString

Get option as a human readable string

Returns:

  • (String)


107
108
109
110
111
112
113
# File 'lib/packetgen/header/tcp/option.rb', line 107

def to_human
  str = self.class == Option ? "unk-#{kind}" : self.class.to_s.sub(/.*::/, '')
  if length > 2 and self[:value].to_s.size > 0
    str << ":#{self[:value].to_s.inspect}"
  end
  str
end

#to_sString

Get binary string

Returns:

  • (String)


98
99
100
101
102
103
# File 'lib/packetgen/header/tcp/option.rb', line 98

def to_s
  str = self[:kind].to_s
  str << self[:length].to_s unless self[:length].value.nil?
  str << self[:value].to_s if length > 2
  str
end