Class: PacketFu::ICMPHeader

Inherits:
Struct
  • Object
show all
Includes:
StructFu
Defined in:
lib/packetfu/protos/icmp.rb

Overview

ICMPHeader is a complete ICMP struct, used in ICMPPacket. ICMP is typically used for network administration and connectivity testing.

For more on ICMP packets, see www.networksorcery.com/enp/protocol/icmp.htm

Header Definition

Int8    :icmp_type                        # Type
Int8    :icmp_code                        # Code
Int16   :icmp_sum    Default: calculated  # Checksum
String  :body

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from StructFu

#clone, #set_endianness, #sz, #typecast

Methods inherited from Struct

#force_binary

Constructor Details

#initialize(args = {}) ⇒ ICMPHeader

Returns a new instance of ICMPHeader.



19
20
21
22
23
24
25
26
# File 'lib/packetfu/protos/icmp.rb', line 19

def initialize(args={})
	super(
		Int8.new(args[:icmp_type]),
		Int8.new(args[:icmp_code]),
		Int16.new(args[:icmp_sum] || icmp_calc_sum),
		StructFu::String.new.read(args[:body])
	)
end

Instance Attribute Details

#bodyObject

Returns the value of attribute body

Returns:

  • (Object)

    the current value of body



15
16
17
# File 'lib/packetfu/protos/icmp.rb', line 15

def body
  @body
end

#icmp_codeObject

Getter for the code.



15
16
17
# File 'lib/packetfu/protos/icmp.rb', line 15

def icmp_code
  @icmp_code
end

#icmp_sumObject

Getter for the checksum.



15
16
17
# File 'lib/packetfu/protos/icmp.rb', line 15

def icmp_sum
  @icmp_sum
end

#icmp_typeObject

Getter for the type.



15
16
17
# File 'lib/packetfu/protos/icmp.rb', line 15

def icmp_type
  @icmp_type
end

Instance Method Details

#icmp_calc_sumObject

Calculates and sets the checksum for the object.



59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/packetfu/protos/icmp.rb', line 59

def icmp_calc_sum
	checksum = (icmp_type.to_i << 8)	+ icmp_code.to_i
	chk_body = (body.to_s.size % 2 == 0 ? body.to_s : body.to_s + "\x00")
	if 1.respond_to? :ord
		chk_body.scan(/../).map { |x| (x[0].ord << 8) + x[1].ord }.each { |y| checksum += y }
	else
		chk_body.scan(/../).map { |x| (x[0] << 8) + x[1] }.each { |y| checksum += y }
	end
	checksum = checksum % 0xffff
	checksum = 0xffff - checksum
	checksum == 0 ? 0xffff : checksum
end

#icmp_recalc(arg = :all) ⇒ Object

Recalculates the calculatable fields for ICMP.



73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/packetfu/protos/icmp.rb', line 73

def icmp_recalc(arg=:all)
	# How silly is this, you can't intern a symbol in ruby 1.8.7pl72?
	# I'm this close to monkey patching Symbol so you can force it...
	arg = arg.intern if arg.respond_to? :intern
	case arg
	when :icmp_sum
		self.icmp_sum=icmp_calc_sum
	when :all
		self.icmp_sum=icmp_calc_sum
	else
		raise ArgumentError, "No such field `#{arg}'"
	end
end

#icmp_sum_readableObject

Readability aliases



89
90
91
# File 'lib/packetfu/protos/icmp.rb', line 89

def icmp_sum_readable
	"0x%04x" % icmp_sum
end

#read(str) ⇒ Object

Reads a string to populate the object.



34
35
36
37
38
39
40
41
42
# File 'lib/packetfu/protos/icmp.rb', line 34

def read(str)
	force_binary(str)
	return self if str.nil?
	self[:icmp_type].read(str[0,1])
	self[:icmp_code].read(str[1,1])
	self[:icmp_sum].read(str[2,2])
	self[:body].read(str[4,str.size])
	self
end

#to_sObject

Returns the object in string form.



29
30
31
# File 'lib/packetfu/protos/icmp.rb', line 29

def to_s
	self.to_a.map {|x| x.to_s}.join
end