Module: StructFu

Overview

StructFu, a nifty way to leverage Ruby’s built in Struct class to create meaningful binary data.

Defined Under Namespace

Classes: Int, Int16, Int16be, Int16le, Int32, Int32be, Int32le, Int64, Int64be, Int64le, Int8, IntString, String

Instance Method Summary collapse

Instance Method Details

#body=(i) ⇒ Object

Used like typecast(), but specifically for casting Strings to StructFu::Strings.



25
26
27
28
29
30
31
32
33
34
35
# File 'lib/packetfu/structfu.rb', line 25

def body=(i)
  if i.kind_of? ::String
    typecast(i)
  elsif i.kind_of? StructFu
    self[:body] = i
  elsif i.nil?
    self[:body] = StructFu::String.new.read("")
  else
    raise ArgumentError, "Can't cram a #{i.class} into a StructFu :body"
  end
end

#cloneObject

Handle deep copies correctly. Marshal in 1.9, re-read myself on 1.8



38
39
40
41
42
43
44
# File 'lib/packetfu/structfu.rb', line 38

def clone
  begin
    Marshal.load(Marshal.dump(self))
  rescue
    self.class.new.read(self.to_s)
  end
end

#set_endianness(e = nil) ⇒ Object

Set the endianness for the various Int classes. Takes either :little or :big.



7
8
9
10
11
12
13
14
15
# File 'lib/packetfu/pcap.rb', line 7

def set_endianness(e=nil)
  unless [:little, :big].include? e
    raise ArgumentError, "Unknown endianness for #{self.class}"
  end
  @int64 = e == :little ? Int64le : Int64be
  @int32 = e == :little ? Int32le : Int32be
  @int16 = e == :little ? Int16le : Int16be
  return e
end

#szObject Also known as: len

Normally, self.size and self.length will refer to the Struct size as an array. It’s a hassle to redefine, so this introduces some shorthand to get at the size of the resultant string.



20
21
22
# File 'lib/packetfu/pcap.rb', line 20

def sz
  self.to_s.size
end

#typecast(i) ⇒ Object

Typecast is used mostly by packet header classes, such as IPHeader, TCPHeader, and the like. It takes an argument, and casts it to the expected type for that element.



19
20
21
22
# File 'lib/packetfu/structfu.rb', line 19

def typecast(i)
  c = caller[0].match(/.*`([^']+)='/)[1]
  self[c.to_sym].read i
end