Class: Packetman::Filter
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
#config, included, #protocols
Constructor Details
#initialize(input) {|config| ... } ⇒ Filter
Returns a new instance of Filter.
7
8
9
10
|
# File 'lib/packetman/filter.rb', line 7
def initialize(input)
self.input = input
yield config if block_given?
end
|
Instance Attribute Details
Returns the value of attribute input.
5
6
7
|
# File 'lib/packetman/filter.rb', line 5
def input
@input
end
|
Class Method Details
.bit_density(radix = config.radix) ⇒ Object
21
22
23
|
# File 'lib/packetman/filter.rb', line 21
def self.bit_density(radix=config.radix)
(radix.nil?) ? 8 : Math.log2(radix).ceil
end
|
.bit_length(num) ⇒ Object
12
13
14
15
16
17
18
19
|
# File 'lib/packetman/filter.rb', line 12
def self.bit_length(num)
case num
when /^0x/
$'.length * bit_density(16)
else
nil
end
end
|
Instance Method Details
#bin_chr(chr) ⇒ String
Converts the chr from config.radix to binary, substituting wildcards as necessary
58
59
60
61
62
63
64
65
66
67
68
69
70
|
# File 'lib/packetman/filter.rb', line 58
def bin_chr(chr)
if config.radix
chr = '0' if chr == config.wildcard
raise "invalid character '#{chr}' for radix=#{config.radix}" if chr.downcase != chr.to_i(config.radix).to_s(config.radix).downcase
chr.to_i(config.radix)
else
if chr == config.wildcard
0
else
chr.ord
end
end.to_s(2).rjust(self.class.bit_density, '0')
end
|
#clauses ⇒ Object
89
90
91
92
93
94
95
96
97
|
# File 'lib/packetman/filter.rb', line 89
def clauses
start_bit = 0
[].tap do |filter|
search_hex.zip(mask_hex).each do |search, mask|
filter << Packetman::Clause.new(search, mask, start_bit)
start_bit += self.class.bit_length(search)
end
end
end
|
#hex_encode(bin_str) ⇒ Object
Transform bin_str to array of 32, 16, and 8 bit hex encoded strings
81
82
83
84
85
86
87
|
# File 'lib/packetman/filter.rb', line 81
def hex_encode(bin_str)
bin_str.reverse.scan(/.{1,4}/).map{ |chunk|
chunk.reverse.to_i(2).to_s(16)
}.reverse.join.scan(/.{8}|.{4}|.{2}/).map{ |hex|
hex.prepend('0x')
}
end
|
#map_chr ⇒ Object
25
26
27
|
# File 'lib/packetman/filter.rb', line 25
def map_chr
shift_and_pad(input.scan(/./).map{ |chr| yield chr }.join)
end
|
#mask_chr(chr) ⇒ Object
Mask string for chr substituting wildcards as necessary
46
47
48
49
50
51
52
|
# File 'lib/packetman/filter.rb', line 46
def mask_chr(chr)
if chr == config.wildcard
0
else
radix_mask
end.to_s(2).rjust(self.class.bit_density, '0')
end
|
#mask_hex ⇒ Object
72
73
74
|
# File 'lib/packetman/filter.rb', line 72
def mask_hex
hex_encode(map_chr{ |c| mask_chr(c) })
end
|
#radix_mask ⇒ Object
Mask for 1 character of current radix
41
42
43
|
# File 'lib/packetman/filter.rb', line 41
def radix_mask
("1"*self.class.bit_density).to_i(2)
end
|
#search_hex ⇒ Object
76
77
78
|
# File 'lib/packetman/filter.rb', line 76
def search_hex
hex_encode(map_chr{ |c| bin_chr(c) })
end
|
#shift_and_pad(bin_str) ⇒ Object
29
30
31
32
33
34
|
# File 'lib/packetman/filter.rb', line 29
def shift_and_pad(bin_str)
bin_str.ljust(target_bit_length, '0').
rjust(target_bit_length + config.offset_bits % 8, '0')
end
|
#target_bit_length ⇒ Object
36
37
38
|
# File 'lib/packetman/filter.rb', line 36
def target_bit_length
((input.length*self.class.bit_density + config.offset_bits)/8.to_f).ceil*8 - config.offset_bits
end
|
#to_s ⇒ Object
99
100
101
|
# File 'lib/packetman/filter.rb', line 99
def to_s
clauses.map{ |clause| clause.to_s }.join(' && ')
end
|