Files
metasploit-gs/lib/bit-struct/vector-field.rb
T
Tod Beardsley f1950c2fe1 Adding back bitstruct (current upstream) and dns_fuzzer module
Fixes #3289.

This commit adds back the bit-struct library because in the end,
it is useful for some modules, especially pello's. It's small
and it has a nice license, so why not. After all, it /is/
useful for quicky application headers. Eventually, should
be replaced by StructFu, but that requires some doc work
on my part to get that transition in place.

This also adds pello's DNS fuzzer module which makes use of
BitStruct to create sometimes malformed-on-purpose DNS headers.

Tested against 3 different DNS servers, caused one to reboot,
so I'd say it works.
2011-12-06 17:03:36 -06:00

78 lines
2.2 KiB
Ruby

require 'bit-struct/vector'
class BitStruct
# Class for embedding a BitStruct::Vector as a field within a BitStruct.
# Declared with BitStruct.vector.
class VectorField < Field
# Used in describe.
def self.class_name
@class_name ||= "vector"
end
# Used in describe.
def class_name
@class_name ||= vector_class.name[/\w+$/]
end
# Returns the subclass of Vector that is used to manage the value of this
# field. If the class was specified in the BitStruct.vector declaration,
# #vector_class will return it, otherwise it will be an anonymous class
# (which you can assign to a constant to make nonymous ;).
def vector_class
@vector_class ||= options[:vector_class] || options["vector_class"]
end
def describe opts # :nodoc:
if opts[:expand]
opts = opts.dup
opts[:byte_offset] = offset / 8
opts[:omit_header] = opts[:omit_footer] = true
vector_class.describe(nil, opts) {|desc| yield desc}
else
super
end
end
def add_accessors_to(cl, attr = name) # :nodoc:
unless offset % 8 == 0
raise ArgumentError,
"Bad offset, #{offset}, for vector field #{name}." +
" Must be multiple of 8."
end
unless length % 8 == 0
raise ArgumentError,
"Bad length, #{length}, for vector field #{name}." +
" Must be multiple of 8."
end
offset_byte = offset / 8
length_byte = length / 8
last_byte = offset_byte + length_byte - 1
byte_range = offset_byte..last_byte
vc = vector_class
cl.class_eval do
define_method attr do ||
vc.new(self[byte_range])
end
define_method "#{attr}=" do |val|
if val.length != length_byte
raise ArgumentError, "Size mismatch in vector field assignment " +
"to #{attr} with value #{val.inspect}"
end
if val.class != vc
warn "Type mismatch in vector field assignment " +
"to #{attr} with value #{val.inspect}"
end
self[byte_range] = val
end
end
end
end
end