Class: Scriptroute::IPv4

Inherits:
IP
  • Object
show all
Defined in:
lib/scriptroute/packets.rb,
lib/scriptroute/packets.rb

Direct Known Subclasses

ICMP, TCP, UDP

Constant Summary collapse

IPPROTO_ICMP =
1
@@creators =

a by-ip_p table of packet instantiators.

Hash.new

Constants inherited from IP

Scriptroute::IP::IPPROTO_TCP, Scriptroute::IP::IPPROTO_UDP

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from IP

#to_bytes

Instance Attribute Details

#ip_dstIPaddress

Returns:



282
283
284
# File 'lib/scriptroute/packets.rb', line 282

def ip_dst
  @ip_dst
end

#ip_hlFixnum (readonly)

Returns:

  • (Fixnum)


279
280
281
# File 'lib/scriptroute/packets.rb', line 279

def ip_hl
  @ip_hl
end

#ip_idFixnum

Returns:

  • (Fixnum)


279
280
281
# File 'lib/scriptroute/packets.rb', line 279

def ip_id
  @ip_id
end

#ip_lenFixnum (readonly)

Returns:

  • (Fixnum)


279
280
281
# File 'lib/scriptroute/packets.rb', line 279

def ip_len
  @ip_len
end

#ip_offFixnum

Returns:

  • (Fixnum)


279
280
281
# File 'lib/scriptroute/packets.rb', line 279

def ip_off
  @ip_off
end

#ip_optionsArray<IPv4option>

Returns:



284
285
286
# File 'lib/scriptroute/packets.rb', line 284

def ip_options
  @ip_options
end

#ip_pFixnum (readonly)

Returns:

  • (Fixnum)


279
280
281
# File 'lib/scriptroute/packets.rb', line 279

def ip_p
  @ip_p
end

#ip_srcIPaddress (readonly)

Returns:



282
283
284
# File 'lib/scriptroute/packets.rb', line 282

def ip_src
  @ip_src
end

#ip_sumFixnum

Returns:

  • (Fixnum)


279
280
281
# File 'lib/scriptroute/packets.rb', line 279

def ip_sum
  @ip_sum
end

#ip_tosFixnum

Returns:

  • (Fixnum)


279
280
281
# File 'lib/scriptroute/packets.rb', line 279

def ip_tos
  @ip_tos
end

#ip_ttlFixnum

Returns:

  • (Fixnum)


279
280
281
# File 'lib/scriptroute/packets.rb', line 279

def ip_ttl
  @ip_ttl
end

#ip_vFixnum (readonly)

Returns:

  • (Fixnum)


279
280
281
# File 'lib/scriptroute/packets.rb', line 279

def ip_v
  @ip_v
end

Class Method Details

.creator(str) ⇒ Object

invoke a factory(?) to create a TCP/UDP/ICMP as appropriate, then unmarshal the IPv4 header contents.

Parameters:

  • str (String)

    the bytes of the packet to unpack.



355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
# File 'lib/scriptroute/packets.rb', line 355

def IPv4.creator(str) 
  ip_vhl, ip_tos, ip_len,
    ip_id, ip_off,
    ip_ttl, ip_p, ip_sum,
    ip_src, ip_dst = str.unpack("ccn" + "nn" + "ccn" + "N" + "N");
  ip_v = ((ip_vhl & 0xf0) >> 4)
  if(ip_v == 4) then
    ip_hl = ip_vhl & 0xf;
    if(@@creators[ip_p]) then
      pkt = (@@creators[ip_p]).call(str[(ip_hl * 4) .. ip_len])
      pkt.ipv4_unmarshal(str)
      pkt
    else
      raise "unknown IPv4 protocol #%d in %s" % [ ip_p, str.unpack("C*").map { |c| "%x" % c }.join(' ') ]
    end
  elsif(ip_v == 6) then
    # probably should do this someplace above IPv4 creator.
    puts "received v6 packet %s" % [ str.unpack("H*") ]
    str
  else
    raise "unknown IP version #%d in %s" % [ ip_v, str.unpack("C*").map { |c| "%x" % c }.join(' ') ]
  end
end

Instance Method Details

#add_option(opt) ⇒ void

This method returns an undefined value.

Parameters:

  • opt (IPv4option)

    add a record route or timestamp option.



324
325
326
327
328
# File 'lib/scriptroute/packets.rb', line 324

def add_option(opt)
  opt.is_a?(IPv4option) or raise "can add only IPv4options"
  @ip_options.push(opt)
  calculate_header_len
end

#calculate_header_lenvoid

This method returns an undefined value.

sets ip_hl, should not be necessary to call this explicitly.



313
314
315
# File 'lib/scriptroute/packets.rb', line 313

def calculate_header_len 
  @ip_hl = [ 5 + ((ip_options.map { |o| o.ipt_len }.sum)/4.0).ceil, 15 ].min # at most 15
end

#calculate_packet_lenvoid

This method returns an undefined value.



317
318
319
320
321
# File 'lib/scriptroute/packets.rb', line 317

def calculate_packet_len 
  calculate_header_len # ensures @ip_hl is set properly
  raise "ip_payload_len not calculated" unless ip_payload_len
  @ip_len = ip_payload_len + (@ip_hl * 4)
end

#ip_payload_lenFixnum

Returns the length of the payload, intended to be implemented by subclasses.

Returns:

  • (Fixnum)

    the length of the payload, intended to be implemented by subclasses.

Raises:

  • (RuntimeError)

    if invoked directly instead of being overloaded.



308
309
310
# File 'lib/scriptroute/packets.rb', line 308

def ip_payload_len
  raise  "ip_payload_len is a pure virtual function in IPv4"
end

#ipv4_unmarshal(str) ⇒ void

This method returns an undefined value.

unpack the ipv4 component of the packet, even if we’re unmarshaling an instance of a subclass.

Parameters:

  • str (String)

    The string from which to unpack.



383
384
385
386
387
388
389
390
391
392
393
394
395
# File 'lib/scriptroute/packets.rb', line 383

def ipv4_unmarshal(str)
  ip_vhl, @ip_tos, @ip_len,
    @ip_id, @ip_off,
    @ip_ttl, @ip_p, @ip_sum,
    ip_src, ip_dst = str.unpack("CCn" + "nn" + "CCn" + "N" + "N");
  @ip_src, @ip_dst = [ip_src, ip_dst].map { |addr| IPaddress.new(addr) }
  @ip_hl = ip_vhl & 0xf;
  @ip_v = (ip_vhl & 0xf0) >> 4;
  @ip_options = Array.new
  if(@ip_hl > 5) then
    add_option(IPv4option.creator(str[20 .. (@ip_hl*4)]))
  end
end

#to_sString

Returns:

  • (String)


398
399
400
401
# File 'lib/scriptroute/packets.rb', line 398

def to_s
  "%s > %s ttl%d" % [ @ip_src, @ip_dst, @ip_ttl ] + 
    @ip_options.map { |o| o.to_s }.join(", ")
end