f1950c2fe1
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.
70 lines
1.6 KiB
Ruby
70 lines
1.6 KiB
Ruby
require 'yaml'
|
|
|
|
class BitStruct
|
|
if RUBY_VERSION == "1.8.2"
|
|
def is_complex_yaml? # :nodoc:
|
|
true
|
|
end
|
|
|
|
YAML.add_ruby_type(/^bitstruct/) do |type, val|
|
|
subtype, subclass = YAML.read_type_class(type, Object)
|
|
subclass.new(val)
|
|
end
|
|
|
|
def to_yaml_type # :nodoc:
|
|
"!ruby/bitstruct:#{self.class}"
|
|
end
|
|
|
|
def to_yaml( opts = {} ) # :nodoc:
|
|
opts[:DocType] = self.class if Hash === opts
|
|
YAML.quick_emit(self.object_id, opts) do |out|
|
|
out.map(to_yaml_type) do |map|
|
|
fields.each do |field|
|
|
fn = field.name
|
|
map.add(fn, send(fn))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
else
|
|
yaml_as "tag:path.berkeley.edu,2006:bitstruct"
|
|
|
|
def to_yaml_properties # :nodoc:
|
|
yaml_fields = fields.select {|field| field.inspectable?}
|
|
props = yaml_fields.map {|f| f.name.to_s}
|
|
if (rest_field = self.class.rest_field)
|
|
props << rest_field.name.to_s
|
|
end
|
|
props
|
|
end
|
|
|
|
# Return YAML representation of the BitStruct.
|
|
def to_yaml( opts = {} )
|
|
YAML::quick_emit( object_id, opts ) do |out|
|
|
out.map( taguri, to_yaml_style ) do |map|
|
|
to_yaml_properties.each do |m|
|
|
map.add( m, send( m ) )
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def self.yaml_new( klass, tag, val ) # :nodoc:
|
|
unless Hash === val
|
|
raise YAML::TypeError, "Invalid BitStruct: " + val.inspect
|
|
end
|
|
|
|
bitstruct_name, bitstruct_type = YAML.read_type_class( tag, BitStruct )
|
|
|
|
st = bitstruct_type.new
|
|
|
|
val.each do |k,v|
|
|
st.send( "#{k}=", v )
|
|
end
|
|
|
|
st
|
|
end
|
|
end
|
|
end
|