Class: PacketGen::Header::IP

Inherits:
Struct
  • Object
show all
Extended by:
HeaderClassMethods
Includes:
HeaderMethods, StructFu
Defined in:
lib/packetgen/header/ip.rb

Overview

IP header class

Author:

  • Sylvain Daubert

Defined Under Namespace

Classes: Addr

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from HeaderClassMethods

bind_header, known_headers

Methods included from HeaderMethods

#header_id, #ip_header, #packet, #packet=

Methods included from StructFu

#clone, #set_endianness, #sz, #typecast

Methods inherited from Struct

#force_binary

Constructor Details

#initialize(options = {}) ⇒ IP

Returns a new instance of IP.

Parameters:

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

Options Hash (options):

  • :version (Integer)
  • :ihl (Integer)

    this header size in 4-byte words

  • :tos (Integer)
  • :length (Integer)

    IP packet length, including this header

  • :id (Integer)
  • :frag (Integer)
  • :ttl (Integer)
  • :proto (Integer)
  • :sum (Integer)

    IP header checksum

  • :src (String)

    IP source dotted address

  • :dst (String)

    IP destination dotted address



92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/packetgen/header/ip.rb', line 92

def initialize(options={})
  super options[:version] || 4,
        options[:ihl] || 5,
        Int8.new(options[:tos] || 0),
        Int16.new(options[:length] || 20),
        Int16.new(options[:id] || rand(65535)),
        Int16.new(options[:frag] || 0),
        Int8.new(options[:ttl] || 64),
        Int8.new(options[:proto]),
        Int16.new(options[:sum] || 0),
        Addr.new.parse(options[:src] || '127.0.0.1'),
        Addr.new.parse(options[:dst] || '127.0.0.1'),
        StructFu::String.new.read(options[:body])
end

Instance Attribute Details

#bodyObject

Returns the value of attribute body

Returns:

  • (Object)

    the current value of body



8
9
10
# File 'lib/packetgen/header/ip.rb', line 8

def body
  @body
end

#dstString Also known as: destination

Get IP destination address

Returns:



8
9
10
# File 'lib/packetgen/header/ip.rb', line 8

def dst
  @dst
end

#fragInteger

Getter for frag attribute

Returns:

  • (Integer)


8
9
10
# File 'lib/packetgen/header/ip.rb', line 8

def frag
  @frag
end

#idInteger

Getter for id attribute

Returns:

  • (Integer)


8
9
10
# File 'lib/packetgen/header/ip.rb', line 8

def id
  @id
end

#ihlObject

Returns the value of attribute ihl

Returns:

  • (Object)

    the current value of ihl



8
9
10
# File 'lib/packetgen/header/ip.rb', line 8

def ihl
  @ihl
end

#lengthInteger

Getter for length attribute

Returns:

  • (Integer)


8
9
10
# File 'lib/packetgen/header/ip.rb', line 8

def length
  @length
end

#protoInteger

Getter for proto attribute

Returns:

  • (Integer)


8
9
10
# File 'lib/packetgen/header/ip.rb', line 8

def proto
  @proto
end

#srcString Also known as: source

Get IP source address

Returns:



8
9
10
# File 'lib/packetgen/header/ip.rb', line 8

def src
  @src
end

#sumInteger

Getter for sum attribute

Returns:

  • (Integer)


8
9
10
# File 'lib/packetgen/header/ip.rb', line 8

def sum
  @sum
end

#tosInteger

Getter for TOS attribute

Returns:

  • (Integer)


8
9
10
# File 'lib/packetgen/header/ip.rb', line 8

def tos
  @tos
end

#ttlInteger

Getter for ttl attribute

Returns:

  • (Integer)


8
9
10
# File 'lib/packetgen/header/ip.rb', line 8

def ttl
  @ttl
end

#versionObject

Returns the value of attribute version

Returns:

  • (Object)

    the current value of version



8
9
10
# File 'lib/packetgen/header/ip.rb', line 8

def version
  @version
end

Instance Method Details

#calc_lengthInteger

Compute length and set length field

Returns:

  • (Integer)


149
150
151
# File 'lib/packetgen/header/ip.rb', line 149

def calc_length
  self[:length].value = self.sz
end

#calc_sumInteger

Returns:

  • (Integer)


132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/packetgen/header/ip.rb', line 132

def calc_sum
  checksum = (self.version << 12) | (self.ihl << 8) | self.tos
  checksum += self.length
  checksum += self.id
  checksum += self.frag
  checksum += (self.ttl << 8) | self.proto
  checksum += (self[:src].to_i >> 16)
  checksum += (self[:src].to_i & 0xffff)
  checksum += self[:dst].to_i >> 16
  checksum += self[:dst].to_i & 0xffff
  checksum = (checksum & 0xffff) + (checksum >> 16)
  checksum = ~(checksum % 0xffff ) & 0xffff
  self[:sum].value = (checksum == 0) ? 0xffff : checksum
end

#pseudo_header_sumInteger

Get IP part of pseudo header sum.

Returns:

  • (Integer)


283
284
285
286
# File 'lib/packetgen/header/ip.rb', line 283

def pseudo_header_sum
  sum = self[:src].to_i + self[:dst].to_i
  (sum >> 16) + (sum & 0xffff)
end

#read(str) ⇒ self

Read a IP header from a string

Parameters:

  • str (String)

    binary string

Returns:

  • (self)

Raises:



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/packetgen/header/ip.rb', line 110

def read(str)
  return self if str.nil?
  raise ParseError, 'string too short for Eth' if str.size < self.sz
  force_binary str
  vihl = str[0, 1].unpack('C').first
  self[:version] = vihl >> 4
  self[:ihl] = vihl & 0x0f
  self[:tos].read str[1, 1]
  self[:length].read str[2, 2]
  self[:id].read str[4, 2]
  self[:frag].read str[6, 2]
  self[:ttl].read str[8, 1]
  self[:proto].read str[9, 1]
  self[:sum].read str[10, 2]
  self[:src].read str[12, 4]
  self[:dst].read str[16, 4]
  self[:body].read str[20..-1]
  self
end

#to_sString

Get binary string

Returns:



276
277
278
279
# File 'lib/packetgen/header/ip.rb', line 276

def to_s
  first_byte = [(version << 4) | ihl].pack('C')
  first_byte << to_a[2..-1].map { |field| field.to_s }.join
end

#to_w(iface = nil) ⇒ void

This method returns an undefined value.

Send IP packet on wire.

When sending packet at IP level, sum and length fields are set by kernel, so bad IP packets cannot be sent this way. To do so, use Eth#to_w.

Parameters:

  • iface (String, nil) (defaults to: nil)

    interface name. Not used



294
295
296
297
298
# File 'lib/packetgen/header/ip.rb', line 294

def to_w(iface=nil)
  sock = Socket.new(Socket::AF_INET, Socket::SOCK_RAW, Socket::IPPROTO_RAW)
  sockaddrin = Socket.sockaddr_in(0, dst)
  sock.send to_s, 0, sockaddrin
end