Module: Louis

Defined in:
lib/louis.rb,
lib/louis/const.rb,
lib/louis/helpers.rb,
lib/louis/version.rb

Defined Under Namespace

Modules: Helpers

Constant Summary collapse

IGNORED_BITS_MASK =

This masks out both the ‘universal/local’ bit as well as the ‘unicast/multicast’ bit which is the first and second least significant bit of the first byte in a vendor prefix.

0xfcffffffffff
LOOKUP_TABLE =

Loads the lookup table, parsing out the uncommented non-blank lines into objects we can compare MACs against to find their vendor.

JSON.parse(File.read(Louis::PARSED_DATA_FILE))
ORIGINAL_OUI_FILE =
File.expand_path(File.join(File.dirname(__FILE__), \
'..', '..', 'data', 'mac_oui_manuf.txt')).freeze
PARSED_DATA_FILE =
File.expand_path(File.join(File.dirname(__FILE__), \
'..', '..', 'data', 'processed_data.json')).freeze
OUI_FORMAT_REGEX =
/^(?<prefix>[0-9a-fA-F:\-.]+)(\/(?<mask>(\d+)))?\s+(?<short_vendor>\S+)(\s+(?<long_vendor>.+))?$/.freeze
VERSION =
'2.2.5'

Class Method Summary collapse

Class Method Details

.lookup(mac) ⇒ String

Returns the name of the vendor that has the most specific prefix available in the OUI table or failing any matches will return “Unknown”.

Parameters:

  • mac (String)

Returns:

  • (String)


30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/louis.rb', line 30

def self.lookup(mac)
  numeric_mac = Louis::Helpers.mac_to_num(mac)
  masked_mac = numeric_mac & IGNORED_BITS_MASK

  if (vendor = search_table(masked_mac))
    return {
      'long_vendor' => vendor['l'],
      'short_vendor' => vendor['s']
    }.compact
  end

  # Try again, but this time don't ignore any bits (Looking at you
  # Google... with your 'da' prefix...)
  if (vendor = search_table(numeric_mac))
    return {
      'long_vendor' => vendor['l'],
      'short_vendor' => vendor['s']
    }.compact
  end

  {'long_vendor' => 'Unknown', 'short_vendor' => 'Unknown'}
end

.mask_keysvoid

Collect the recorded mask and order it appropriately from most specific to least.

Parameters:

  • (Array<Fixnum>)


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

def self.mask_keys
  @mask_keys ||= LOOKUP_TABLE.keys.map(&:to_i).sort.reverse
end

.search_table(encoded_mac) ⇒ void



53
54
55
56
57
58
59
60
61
# File 'lib/louis.rb', line 53

def self.search_table(encoded_mac)
  mask_keys.each do |mask|
    table = LOOKUP_TABLE[mask.to_s]
    prefix = (encoded_mac & Louis::Helpers.calculate_mask(nil, mask)).to_s
    return table[prefix] if table.include?(prefix)
  end

  nil
end