Class: Packetman::Filter

Inherits:
Object
  • Object
show all
Includes:
ConfigMethods
Defined in:
lib/packetman/filter.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ConfigMethods

#config, included, #protocols

Constructor Details

#initialize(input) {|config| ... } ⇒ Filter

Returns a new instance of Filter.

Yields:



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

#inputObject

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) ⇒ Object

Binary string for chr substituting wildcards as necessary



55
56
57
58
59
60
61
62
63
64
# File 'lib/packetman/filter.rb', line 55

def bin_chr(chr)
  chr = 0 if chr == config.wildcard

  if config.radix
    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
    chr.ord
  end.to_s(2).rjust(self.class.bit_density, '0')
end

#clausesObject



83
84
85
86
87
88
89
90
91
# File 'lib/packetman/filter.rb', line 83

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



75
76
77
78
79
80
81
# File 'lib/packetman/filter.rb', line 75

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_chrObject



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_hexObject



66
67
68
# File 'lib/packetman/filter.rb', line 66

def mask_hex
  hex_encode(map_chr{ |c| mask_chr(c) })
end

#radix_maskObject

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_hexObject



70
71
72
# File 'lib/packetman/filter.rb', line 70

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)
  #shift
  bin_str.ljust(target_bit_length, '0').
  #pad
    rjust(target_bit_length + config.offset_bits % 8, '0')
end

#target_bit_lengthObject



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_sObject



93
94
95
# File 'lib/packetman/filter.rb', line 93

def to_s
  clauses.map{ |clause| clause.to_s }.join(' && ')
end