Module: Louis::Helpers

Defined in:
lib/louis/helpers.rb

Class Method Summary collapse

Class Method Details

.calculate_mask(prefix, mask) ⇒ Fixnum

Calculate the bit mask for testing whether or not a mac_prefix matches. This returns an integer with the upper X bits set where X is the mask length.

Parameters:

  • prefix (String)
  • mask (String)

Returns:

  • (Fixnum)


10
11
12
13
# File 'lib/louis/helpers.rb', line 10

def self.calculate_mask(prefix, mask)
  mask_base = mask.nil? ? (clean_mac(prefix).length * 4) : mask.to_i
  (2 ** 48 - 1) - (2 ** (48 - mask_base) - 1)
end

.clean_mac(mac) ⇒ String

Returns the hex representing a full or partial MAC address with the ‘connecting’ characters removed. Does nothing to ensure length.

Parameters:

  • mac (String)

Returns:

  • (String)


20
21
22
# File 'lib/louis/helpers.rb', line 20

def self.clean_mac(mac)
  mac.tr(':\.-', '')
end

.count_bits(num) ⇒ Fixnum

Count the number of bits set in an integer. This likely could use an improved algorithm but this is fast and effective enough.

Parameters:

  • num (Fixnum)

Returns:

  • (Fixnum)


29
30
31
# File 'lib/louis/helpers.rb', line 29

def self.count_bits(num)
  num.to_s(2).count('1')
end

.line_parser(line) ⇒ Hash<String=>Object>

Handle parsing a line from the raw OUI file into it’s associated lookup table format. This will return nil if the line is poorly formatted, empty or a comment.

Parameters:

  • (String)

Returns:

  • (Hash<String=>Object>)


47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/louis/helpers.rb', line 47

def self.line_parser(line)
  return unless (matches = OUI_FORMAT_REGEX.match(line))
  result = Hash[matches.names.zip(matches.captures)]

  mask = calculate_mask(result['prefix'], result['mask'])
  prefix = mac_to_num(result['prefix']) & mask

  {
    'mask'         => count_bits(mask),
    'prefix'       => prefix,
    'long_vendor'  => result['long_vendor'],
    'short_vendor' => result['short_vendor']
  }.reject { |_, v| v.nil? }
end

.mac_to_num(mac) ⇒ void

Converts a hexidecimal version of a full or partial (prefix) MAC address into it’s integer representation.

Parameters:

  • mac (String)


37
38
39
# File 'lib/louis/helpers.rb', line 37

def self.mac_to_num(mac)
  clean_mac(mac).ljust(12, '0').to_i(16)
end