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:



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

def ip_hl
  @ip_hl
end

#ip_idFixnum

Returns:



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

def ip_id
  @ip_id
end

#ip_lenFixnum (readonly)

Returns:



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

def ip_len
  @ip_len
end

#ip_offFixnum

Returns:



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:



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:



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

def ip_sum
  @ip_sum
end

#ip_tosFixnum

Returns:



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

def ip_tos
  @ip_tos
end

#ip_ttlFixnum

Returns:



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

def ip_ttl
  @ip_ttl
end

#ip_vFixnum (readonly)

Returns:



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:

  • 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:

  • 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:

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

Raises:

  • 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:

  • 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:



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