module Louis

Constants

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.

LOCALLY_ADMINISTERED_BIT

Flag to indicate that this address is generated versus one assigned by a manufacturer.

LOOKUP_TABLE

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

MULTICAST_BIT

Bit flag indicating that the address is directed at more than one recipient.

ORIGINAL_OUI_FILE
OUI_FORMAT_REGEX
PARSED_DATA_FILE
VERSION

Public Class Methods

lookup(mac) click to toggle source

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

@param [String] mac @return [String]

# File lib/louis.rb, line 37
def self.lookup(mac)
  numeric_mac = Louis::Helpers.mac_to_num(mac)
  masked_mac = numeric_mac & IGNORED_BITS_MASK

  address_flags = []
  address_flags << (numeric_mac & MULTICAST_BIT > 0 ? :multicast : :unicast)
  address_flags << (numeric_mac & LOCALLY_ADMINISTERED_BIT > 0 ? :locally_generated : :manufacturer_generated)

  if (vendor = search_table(masked_mac))
    return {
      'flags' => address_flags,
      '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 {
      'flags' => address_flags,
      'long_vendor' => vendor['l'],
      'short_vendor' => vendor['s'],
    }.compact
  end

  {'flags' => address_flags, 'long_vendor' => 'Unknown', 'short_vendor' => 'Unknown'}
end
mask_keys() click to toggle source

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

@param [Array<Fixnum>]

# File lib/louis.rb, line 28
def self.mask_keys
  @mask_keys ||= LOOKUP_TABLE.keys.map(&:to_i).sort.reverse
end
search_table(encoded_mac) click to toggle source
# File lib/louis.rb, line 66
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