ruckus 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.gitignore +22 -0
- data/README +0 -0
- data/README.markdown +51 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/lib/ruckus.rb +70 -0
- data/lib/ruckus/blob.rb +113 -0
- data/lib/ruckus/choice.rb +55 -0
- data/lib/ruckus/dfuzz.rb +231 -0
- data/lib/ruckus/dictionary.rb +119 -0
- data/lib/ruckus/enum.rb +39 -0
- data/lib/ruckus/extensions/array.rb +33 -0
- data/lib/ruckus/extensions/class.rb +168 -0
- data/lib/ruckus/extensions/duplicable.rb +37 -0
- data/lib/ruckus/extensions/file.rb +24 -0
- data/lib/ruckus/extensions/fixnum.rb +26 -0
- data/lib/ruckus/extensions/hash.rb +10 -0
- data/lib/ruckus/extensions/integer.rb +26 -0
- data/lib/ruckus/extensions/ipaddr.rb +155 -0
- data/lib/ruckus/extensions/irb.rb +30 -0
- data/lib/ruckus/extensions/math.rb +6 -0
- data/lib/ruckus/extensions/module.rb +37 -0
- data/lib/ruckus/extensions/numeric.rb +117 -0
- data/lib/ruckus/extensions/object.rb +22 -0
- data/lib/ruckus/extensions/range.rb +16 -0
- data/lib/ruckus/extensions/socket.rb +20 -0
- data/lib/ruckus/extensions/string.rb +327 -0
- data/lib/ruckus/filter.rb +16 -0
- data/lib/ruckus/human_display.rb +79 -0
- data/lib/ruckus/ip.rb +38 -0
- data/lib/ruckus/mac_addr.rb +31 -0
- data/lib/ruckus/mutator.rb +318 -0
- data/lib/ruckus/null.rb +24 -0
- data/lib/ruckus/number.rb +360 -0
- data/lib/ruckus/parsel.rb +363 -0
- data/lib/ruckus/selector.rb +92 -0
- data/lib/ruckus/str.rb +164 -0
- data/lib/ruckus/structure.rb +263 -0
- data/lib/ruckus/structure/atcreate.rb +23 -0
- data/lib/ruckus/structure/beforebacks.rb +28 -0
- data/lib/ruckus/structure/defaults.rb +57 -0
- data/lib/ruckus/structure/factory.rb +42 -0
- data/lib/ruckus/structure/fixupfields.rb +16 -0
- data/lib/ruckus/structure/initializers.rb +14 -0
- data/lib/ruckus/structure/relate.rb +34 -0
- data/lib/ruckus/structure/replacement.rb +30 -0
- data/lib/ruckus/structure/searchmods.rb +33 -0
- data/lib/ruckus/structure/structureproxies.rb +28 -0
- data/lib/ruckus/structure/validate.rb +12 -0
- data/lib/ruckus/structure_shortcuts.rb +109 -0
- data/lib/ruckus/time_t.rb +26 -0
- data/lib/ruckus/vector.rb +97 -0
- data/ruckus.gemspec +104 -0
- data/test/test_decides.rb +61 -0
- data/test/test_mutator.rb +29 -0
- data/test/test_override.rb +23 -0
- data/test/test_replace.rb +39 -0
- metadata +138 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
class Integer
|
2
|
+
module IntegerExtensions
|
3
|
+
# Convert integers to binary strings
|
4
|
+
def to_l32; [self].pack "L"; end
|
5
|
+
def to_b32; [self].pack "N"; end
|
6
|
+
def to_l16; [self].pack "v"; end
|
7
|
+
def to_b16; [self].pack "n"; end
|
8
|
+
def to_u8; [self].pack "C"; end
|
9
|
+
|
10
|
+
# Print a number in hex
|
11
|
+
def to_hex(pre="0x"); pre + to_s(16); end
|
12
|
+
|
13
|
+
# Print a number in binary
|
14
|
+
def to_b(pre=""); pre + to_s(2); end
|
15
|
+
|
16
|
+
def ffs
|
17
|
+
i = 0
|
18
|
+
v = self
|
19
|
+
while((v >>= 1) != 0)
|
20
|
+
i += 1
|
21
|
+
end
|
22
|
+
return i
|
23
|
+
end
|
24
|
+
end
|
25
|
+
include IntegerExtensions
|
26
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'ipaddr'
|
2
|
+
|
3
|
+
class IPAddr
|
4
|
+
attr_reader :mask_addr
|
5
|
+
|
6
|
+
module IPAddrExtensions
|
7
|
+
|
8
|
+
# ---------------------------------------------------------
|
9
|
+
|
10
|
+
# make an IP address take the int32 value provided
|
11
|
+
|
12
|
+
def set_int(ip)
|
13
|
+
set(ip, Socket::AF_INET)
|
14
|
+
end
|
15
|
+
|
16
|
+
# ---------------------------------------------------------
|
17
|
+
|
18
|
+
# randomize the "host" part of the IP address (destructive)
|
19
|
+
|
20
|
+
def random(mask=0xFFFFFFFF)
|
21
|
+
r = rand(0xFFFFFFFF) & mask
|
22
|
+
i = self.to_i & (~mask)
|
23
|
+
self.set_int(i | r)
|
24
|
+
end
|
25
|
+
|
26
|
+
alias_method :random!, :random
|
27
|
+
|
28
|
+
# ---------------------------------------------------------
|
29
|
+
|
30
|
+
# convert a string to IP
|
31
|
+
|
32
|
+
def inet_addr(str)
|
33
|
+
in_addr(str)
|
34
|
+
end
|
35
|
+
|
36
|
+
module ClassMethods
|
37
|
+
# ---------------------------------------------------------
|
38
|
+
|
39
|
+
# construct an IPAddr from a dotted quad string or integer
|
40
|
+
|
41
|
+
def inet_addr(str)
|
42
|
+
if str.kind_of? String
|
43
|
+
IPAddr.lite(str).to_i
|
44
|
+
else
|
45
|
+
i = IPAddr.new(0, Socket::AF_INET)
|
46
|
+
i.set_int(str)
|
47
|
+
return i
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# ---------------------------------------------------------
|
52
|
+
# Convert 255.255.255.0 to 24
|
53
|
+
def mask2mlen(mask)
|
54
|
+
len = 0
|
55
|
+
while len < 32 && mask & 0x80000000 != 0
|
56
|
+
mask <<= 1
|
57
|
+
mask &= 0xFFFFFFFF
|
58
|
+
len += 1
|
59
|
+
end
|
60
|
+
return len
|
61
|
+
end
|
62
|
+
|
63
|
+
# ---------------------------------------------------------
|
64
|
+
|
65
|
+
# construct an IPAddr from a dotted quad string without
|
66
|
+
# incurring a reverse lookup.
|
67
|
+
|
68
|
+
def lite(str)
|
69
|
+
# XXX self.new(0, Socket::AF_Inet, *args) instead?
|
70
|
+
ip = IPAddr.new(0, Socket::AF_INET)
|
71
|
+
|
72
|
+
parts = str.split "/"
|
73
|
+
|
74
|
+
ip.set_int(ip.inet_addr(parts[0]))
|
75
|
+
ip = ip.mask parts[1] if parts[1]
|
76
|
+
return ip
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.included(klass)
|
81
|
+
klass.extend(ClassMethods)
|
82
|
+
end
|
83
|
+
# ---------------------------------------------------------
|
84
|
+
|
85
|
+
# to_s with a cidr prefix at the end
|
86
|
+
|
87
|
+
def to_cidr_s
|
88
|
+
# XXX not used
|
89
|
+
"#{ to_s }/#{ self.class.mask2mlen(@mask_addr) }"
|
90
|
+
end
|
91
|
+
|
92
|
+
# ---------------------------------------------------------
|
93
|
+
|
94
|
+
# get the mask length
|
95
|
+
|
96
|
+
def to_mlen
|
97
|
+
# XXX not used
|
98
|
+
mask = self.to_i
|
99
|
+
self.class.mask2mlen(mask)
|
100
|
+
end
|
101
|
+
|
102
|
+
# ---------------------------------------------------------
|
103
|
+
|
104
|
+
# get the highest address in the range defined by the netmask
|
105
|
+
|
106
|
+
def top
|
107
|
+
# XXX not used
|
108
|
+
# XXX should use self.class.inet_addr instead?
|
109
|
+
IPAddr.inet_addr(self.to_i | (0xFFFFFFFF & (~self.mask_addr)))
|
110
|
+
end
|
111
|
+
|
112
|
+
# ---------------------------------------------------------
|
113
|
+
|
114
|
+
# get the lowest address in the range defined by the netmask
|
115
|
+
|
116
|
+
def bottom
|
117
|
+
# XXX not used
|
118
|
+
# XXX should use self.class instead of IPAddr
|
119
|
+
IPAddr.inet_addr(self.to_i & self.mask_addr)
|
120
|
+
end
|
121
|
+
|
122
|
+
# ---------------------------------------------------------
|
123
|
+
|
124
|
+
# get a random address from within the range defined by the
|
125
|
+
# netmask.
|
126
|
+
|
127
|
+
def choice
|
128
|
+
# XXX not used
|
129
|
+
return self.clone if self.mask_addr == 0xFFFFFFFF
|
130
|
+
|
131
|
+
span = self.top.to_i - self.bottom.to_i
|
132
|
+
x = self.clone
|
133
|
+
x.set_int(self.bottom.to_i + rand(span))
|
134
|
+
return x
|
135
|
+
end
|
136
|
+
|
137
|
+
# ---------------------------------------------------------
|
138
|
+
|
139
|
+
# test if the address provided is in the range defined by the
|
140
|
+
# netmask
|
141
|
+
|
142
|
+
def contains(i)
|
143
|
+
# XXX not used
|
144
|
+
# XXX should use self.class instead of IPAddr
|
145
|
+
if not i.kind_of? IPAddr
|
146
|
+
i = IPAddr.inet_addr i
|
147
|
+
end
|
148
|
+
|
149
|
+
i.to_i >= self.bottom.to_i and i.to_i <= self.top.to_i
|
150
|
+
end
|
151
|
+
|
152
|
+
alias_method :contains?, :contains
|
153
|
+
end
|
154
|
+
include IPAddrExtensions
|
155
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'irb'
|
2
|
+
|
3
|
+
module IRB
|
4
|
+
# Lifted from http://errtheblog.com/posts/9-drop-to-irb
|
5
|
+
# Starts an IRB session with a specific binding. To use type:
|
6
|
+
# IRB.start_session(binding)
|
7
|
+
def self.start_session(binding)
|
8
|
+
# XXX not used
|
9
|
+
IRB.setup(nil)
|
10
|
+
|
11
|
+
workspace = WorkSpace.new(binding)
|
12
|
+
|
13
|
+
if @CONF[:SCRIPT]
|
14
|
+
irb = Irb.new(workspace, @CONF[:SCRIPT])
|
15
|
+
else
|
16
|
+
irb = Irb.new(workspace)
|
17
|
+
end
|
18
|
+
|
19
|
+
@CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
|
20
|
+
@CONF[:MAIN_CONTEXT] = irb.context
|
21
|
+
|
22
|
+
trap("SIGINT") do
|
23
|
+
irb.signal_handle
|
24
|
+
end
|
25
|
+
|
26
|
+
catch(:IRB_EXIT) do
|
27
|
+
irb.eval_input
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class Module
|
2
|
+
module ModuleExtensions
|
3
|
+
def to_name_hash
|
4
|
+
# XXX not used
|
5
|
+
@name_hash ||= constants.map {|k| [k.intern, const_get(k.intern)]}.to_hash
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_key_hash
|
9
|
+
# XXX not used
|
10
|
+
@key_hash ||= constants.map {|k| [const_get(k.intern), k.intern]}.to_hash
|
11
|
+
end
|
12
|
+
|
13
|
+
def flag_dump(i)
|
14
|
+
# XXX not used
|
15
|
+
@bit_map ||= constants.map do |k|
|
16
|
+
[k, const_get(k.intern).ffs]
|
17
|
+
end.sort {|x, y| x[1] <=> y[1]}
|
18
|
+
|
19
|
+
last = 0
|
20
|
+
r = ""
|
21
|
+
@bit_map.each do |tup|
|
22
|
+
if((v = (tup[1] - last)) > 1)
|
23
|
+
r << ("." * (v-1))
|
24
|
+
end
|
25
|
+
|
26
|
+
if((i & (1 << tup[1])) != 0)
|
27
|
+
r << tup[0][0].chr
|
28
|
+
else
|
29
|
+
r << tup[0][0].chr.downcase
|
30
|
+
end
|
31
|
+
last = tup[1]
|
32
|
+
end
|
33
|
+
return r.reverse
|
34
|
+
end
|
35
|
+
end
|
36
|
+
include ModuleExtensions
|
37
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
class Numeric
|
2
|
+
module NumericExtensions
|
3
|
+
# XXX likely these should be moved to Integer
|
4
|
+
|
5
|
+
# This HAS TO BE in the library somewhere already, but: give a fixnum,
|
6
|
+
# cap it at some number (ie, max(x, y) -> x). 10.cap(9) => 9.
|
7
|
+
def cap(limit); self > limit ? limit : self; end
|
8
|
+
|
9
|
+
def to_x; to_s(16).rjust(8, "0"); end
|
10
|
+
|
11
|
+
def to_l32
|
12
|
+
[self].pack("L")
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_l16
|
16
|
+
[self].pack("v")
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_l8
|
20
|
+
(self&0xFF).chr
|
21
|
+
end
|
22
|
+
|
23
|
+
# sign extend
|
24
|
+
def sx8; ([self].pack "c").unpack("C").first; end
|
25
|
+
def sx16; ([self].pack "s").unpack("S").first; end
|
26
|
+
def sx32; ([self].pack "l").unpack("L").first; end
|
27
|
+
|
28
|
+
module ClassMethods
|
29
|
+
# Make a bitmask with m-many bits, as an Integer
|
30
|
+
def mask_for(m)
|
31
|
+
# This is just table lookup for values less than 65
|
32
|
+
|
33
|
+
@@mask ||= {
|
34
|
+
1 => 0x1,
|
35
|
+
2 => 0x3,
|
36
|
+
3 => 0x7,
|
37
|
+
4 => 0xf,
|
38
|
+
5 => 0x1f,
|
39
|
+
6 => 0x3f,
|
40
|
+
7 => 0x7f,
|
41
|
+
8 => 0xff,
|
42
|
+
9 => 0x1ff,
|
43
|
+
10 => 0x3ff,
|
44
|
+
11 => 0x7ff,
|
45
|
+
12 => 0xfff,
|
46
|
+
13 => 0x1fff,
|
47
|
+
14 => 0x3fff,
|
48
|
+
15 => 0x7fff,
|
49
|
+
16 => 0xffff,
|
50
|
+
17 => 0x1ffff,
|
51
|
+
18 => 0x3ffff,
|
52
|
+
19 => 0x7ffff,
|
53
|
+
20 => 0xfffff,
|
54
|
+
21 => 0x1fffff,
|
55
|
+
22 => 0x3fffff,
|
56
|
+
23 => 0x7fffff,
|
57
|
+
24 => 0xffffff,
|
58
|
+
25 => 0x1ffffff,
|
59
|
+
26 => 0x3ffffff,
|
60
|
+
27 => 0x7ffffff,
|
61
|
+
28 => 0xfffffff,
|
62
|
+
29 => 0x1fffffff,
|
63
|
+
30 => 0x3fffffff,
|
64
|
+
31 => 0x7fffffff,
|
65
|
+
32 => 0xffffffff,
|
66
|
+
33 => 0x1ffffffff,
|
67
|
+
34 => 0x3ffffffff,
|
68
|
+
35 => 0x7ffffffff,
|
69
|
+
36 => 0xfffffffff,
|
70
|
+
37 => 0x1fffffffff,
|
71
|
+
38 => 0x3fffffffff,
|
72
|
+
39 => 0x7fffffffff,
|
73
|
+
40 => 0xffffffffff,
|
74
|
+
41 => 0x1ffffffffff,
|
75
|
+
42 => 0x3ffffffffff,
|
76
|
+
43 => 0x7ffffffffff,
|
77
|
+
44 => 0xfffffffffff,
|
78
|
+
45 => 0x1fffffffffff,
|
79
|
+
46 => 0x3fffffffffff,
|
80
|
+
47 => 0x7fffffffffff,
|
81
|
+
48 => 0xffffffffffff,
|
82
|
+
49 => 0x1ffffffffffff,
|
83
|
+
50 => 0x3ffffffffffff,
|
84
|
+
51 => 0x7ffffffffffff,
|
85
|
+
52 => 0xfffffffffffff,
|
86
|
+
53 => 0x1fffffffffffff,
|
87
|
+
54 => 0x3fffffffffffff,
|
88
|
+
55 => 0x7fffffffffffff,
|
89
|
+
56 => 0xffffffffffffff,
|
90
|
+
57 => 0x1ffffffffffffff,
|
91
|
+
58 => 0x3ffffffffffffff,
|
92
|
+
59 => 0x7ffffffffffffff,
|
93
|
+
60 => 0xfffffffffffffff,
|
94
|
+
61 => 0x1fffffffffffffff,
|
95
|
+
62 => 0x3fffffffffffffff,
|
96
|
+
63 => 0x7fffffffffffffff,
|
97
|
+
64 => 0xffffffffffffffff
|
98
|
+
}
|
99
|
+
|
100
|
+
if (v = @@mask[m])
|
101
|
+
return v
|
102
|
+
end
|
103
|
+
|
104
|
+
# Compute it for crazy values.
|
105
|
+
|
106
|
+
r = 0
|
107
|
+
0.upto(m-1) {|q| r |= (1 << q)}
|
108
|
+
return r
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.included(klass)
|
113
|
+
klass.extend(ClassMethods)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
include NumericExtensions
|
117
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Object
|
2
|
+
module ObjectExtensions
|
3
|
+
# Every object has a "singleton" class, which you can think
|
4
|
+
# of as the class (ie, 1.metaclass =~ Fixnum) --- but that you
|
5
|
+
# can modify and extend without fucking up the actual class.
|
6
|
+
|
7
|
+
def metaclass; class << self; self; end; end
|
8
|
+
def meta_eval(&blk) metaclass.instance_eval &blk; end
|
9
|
+
def meta_def(name, &blk) meta_eval { define_method name, &blk }; end
|
10
|
+
def try(meth, *args); send(meth, *args) if respond_to? meth; end
|
11
|
+
|
12
|
+
def through(meth, *args)
|
13
|
+
if respond_to? meth
|
14
|
+
send(meth, *args)
|
15
|
+
else
|
16
|
+
self
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
include ObjectExtensions
|
21
|
+
end
|
22
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Range
|
2
|
+
module RangeExtensions
|
3
|
+
# again, surprised this isn't in the library
|
4
|
+
def each_backwards
|
5
|
+
max.to_i.downto(min) {|i| yield i}
|
6
|
+
end
|
7
|
+
|
8
|
+
# Take a random number out of a range
|
9
|
+
#
|
10
|
+
def choice
|
11
|
+
rand(self.last - self.first) + self.first
|
12
|
+
end
|
13
|
+
alias_method :choose, :choice
|
14
|
+
end
|
15
|
+
include RangeExtensions
|
16
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Socket
|
2
|
+
module SocketExtensions
|
3
|
+
module ClassMethods
|
4
|
+
def addr(host, port=nil)
|
5
|
+
if not port
|
6
|
+
raise "bad!" if not host =~ /(.*):(.*)/
|
7
|
+
host = $1
|
8
|
+
port = $2
|
9
|
+
end
|
10
|
+
port = port.to_i
|
11
|
+
Socket.pack_sockaddr_in(port, host)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.included(klass)
|
16
|
+
klass.extend(ClassMethods)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
include SocketExtensions
|
20
|
+
end
|