Class: PacketGen::Header::IP

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

Overview

A IP header consists of:

Create a IP header

# standalone
ip = PacketGen::Header::IP.new
# in a packet
pkt = PacketGen.gen('IP')
# access to IP header
pkt.ip   # => PacketGen::Header::IP

IP attributes

ip.u8 = 0x45
# the same as
ip.version = 4
ip.ihl = 5

ip.length = 0x43
ip.id = 0x1234

ip.frag = 0x2031
# the same as:
ip.flag_mf = true
ip.fragment_offset = 0x31

ip.flag_rsv?  # => Boolean
ip.flag_df?   # => Boolean
ip.flag_mf?   # => Boolean

ip.ttl = 0x40
ip.protocol = 6
ip.checksum = 0xffff
ip.src = '127.0.0.1'
ip.src                # => "127.0.0.1"
ip[:src]              # => PacketGen::Header::IP::Addr
ip.dst = '127.0.0.2'
ip.body.read 'this is a body'

Author:

  • Sylvain Daubert

Defined Under Namespace

Classes: Addr

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from HeaderClassMethods

bind_header, define_bit_fields_on, known_headers

Methods included from HeaderMethods

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

Methods included from StructFu

#clone, #set_endianness, #sz, #to_s, #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)
  • :protocol (Integer)
  • :checksum (Integer)

    IP header checksum

  • :src (String)

    IP source dotted address

  • :dst (String)

    IP destination dotted address



145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/packetgen/header/ip.rb', line 145

def initialize(options={})
  super Int8.new(((options[:version] || 4) << 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[:protocol]),
        Int16.new(options[:checksum] || 0),
        Addr.new.from_human(options[:src] || '127.0.0.1'),
        Addr.new.from_human(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



61
62
63
# File 'lib/packetgen/header/ip.rb', line 61

def body
  @body
end

#checksumInteger

Getter for checksum attribute

Returns:

  • (Integer)


61
62
63
# File 'lib/packetgen/header/ip.rb', line 61

def checksum
  @checksum
end

#dstString Also known as: destination

Get IP destination address

Returns:



61
62
63
# File 'lib/packetgen/header/ip.rb', line 61

def dst
  @dst
end

#flag_dfBoolean

Returns Don’t Fragment flag.

Returns:

  • (Boolean)

    Don’t Fragment flag



173
# File 'lib/packetgen/header/ip.rb', line 173

define_bit_fields_on :frag, :flag_rsv, :flag_df, :flag_mf, :fragment_offset, 13

#flag_mfBoolena

Returns More Fragment flags.

Returns:

  • (Boolena)

    More Fragment flags



173
# File 'lib/packetgen/header/ip.rb', line 173

define_bit_fields_on :frag, :flag_rsv, :flag_df, :flag_mf, :fragment_offset, 13

#flag_rsvBoolean

Returns reserved bit from flags.

Returns:

  • (Boolean)

    reserved bit from flags



173
# File 'lib/packetgen/header/ip.rb', line 173

define_bit_fields_on :frag, :flag_rsv, :flag_df, :flag_mf, :fragment_offset, 13

#fragInteger

Getter for frag attribute

Returns:

  • (Integer)


61
62
63
# File 'lib/packetgen/header/ip.rb', line 61

def frag
  @frag
end

#fragment_offsetInteger

Returns 13-bit fragment offset.

Returns:

  • (Integer)

    13-bit fragment offset



173
# File 'lib/packetgen/header/ip.rb', line 173

define_bit_fields_on :frag, :flag_rsv, :flag_df, :flag_mf, :fragment_offset, 13

#idInteger

Getter for id attribute

Returns:

  • (Integer)


61
62
63
# File 'lib/packetgen/header/ip.rb', line 61

def id
  @id
end

#ihlInteger

Returns 4-bit IP header length attribute.

Returns:

  • (Integer)

    4-bit IP header length attribute



163
# File 'lib/packetgen/header/ip.rb', line 163

define_bit_fields_on :u8, :version, 4, :ihl, 4

#lengthInteger

Getter for length attribute

Returns:

  • (Integer)


61
62
63
# File 'lib/packetgen/header/ip.rb', line 61

def length
  @length
end

#protocolInteger

Getter for protocol attribute

Returns:

  • (Integer)


61
62
63
# File 'lib/packetgen/header/ip.rb', line 61

def protocol
  @protocol
end

#srcString Also known as: source

Get IP source address

Returns:



61
62
63
# File 'lib/packetgen/header/ip.rb', line 61

def src
  @src
end

#tosInteger

Getter for TOS attribute

Returns:

  • (Integer)


61
62
63
# File 'lib/packetgen/header/ip.rb', line 61

def tos
  @tos
end

#ttlInteger

Getter for ttl attribute

Returns:

  • (Integer)


61
62
63
# File 'lib/packetgen/header/ip.rb', line 61

def ttl
  @ttl
end

#u8Object

Returns the value of attribute u8

Returns:

  • (Object)

    the current value of u8



61
62
63
# File 'lib/packetgen/header/ip.rb', line 61

def u8
  @u8
end

#versionInteger

Returns 4-bit version attribute.

Returns:

  • (Integer)

    4-bit version attribute



163
# File 'lib/packetgen/header/ip.rb', line 163

define_bit_fields_on :u8, :version, 4, :ihl, 4

Instance Method Details

#calc_checksumInteger

Returns:

  • (Integer)


198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/packetgen/header/ip.rb', line 198

def calc_checksum
  checksum = (self[:u8].to_i << 8) | self.tos
  checksum += self.length
  checksum += self.id
  checksum += self.frag
  checksum += (self.ttl << 8) | self.protocol
  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[:checksum].value = (checksum == 0) ? 0xffff : checksum
end

#calc_lengthInteger

Compute length and set length field

Returns:

  • (Integer)


215
216
217
# File 'lib/packetgen/header/ip.rb', line 215

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

#inspectString

Returns:



360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
# File 'lib/packetgen/header/ip.rb', line 360

def inspect
  str = Inspect.dashed_line(self.class, 2)
  shift = Inspect.shift_level(2)
  to_h.each do |attr, value|
    next if attr == :body
    str << Inspect.inspect_attribute(attr, value, 2)
    if attr == :u8
      str << shift + Inspect::INSPECT_FMT_ATTR % ['', 'version', version]
      str << shift + Inspect::INSPECT_FMT_ATTR % ['', 'ihl', ihl]
    elsif attr == :frag
      flags = flag_rsv? ? %w(RSV) : []
      flags << 'DF' if flag_df?
      flags << 'MF' if flag_mf?
      flags_str = flags.empty? ? 'none' : flags.join(',')
      str << shift + Inspect::INSPECT_FMT_ATTR % ['', 'flags', flags_str]
      foff = Inspect.int_dec_hex(fragment_offset, 4)
      str << shift + Inspect::INSPECT_FMT_ATTR % ['', 'frag_offset', foff]
    end
  end
  str
end

#pseudo_header_checksumInteger

Get IP part of pseudo header checksum.

Returns:

  • (Integer)


342
343
344
345
# File 'lib/packetgen/header/ip.rb', line 342

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

#read(str) ⇒ self

Read a IP header from a string

Parameters:

  • str (String)

    binary string

Returns:

  • (self)

Raises:



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/packetgen/header/ip.rb', line 178

def read(str)
  return self if str.nil?
  raise ParseError, 'string too short for IP' if str.size < self.sz
  force_binary str
  self[:u8].read str[0, 1]
  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[:protocol].read str[9, 1]
  self[:checksum].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_w(iface = nil) ⇒ void

This method returns an undefined value.

Send IP packet on wire.

When sending packet at IP level, checksum 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



353
354
355
356
357
# File 'lib/packetgen/header/ip.rb', line 353

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