oui

package module
v0.0.0-...-35b4deb Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 25, 2015 License: MIT Imports: 11 Imported by: 3

README

OUI Library

Library and microservice for looking up manufacturers from MAC addresses, written in Go.

This library is a in-memory database that allows to look up manufacturer information based on a MAC address. The library is very lightweight, and allows for million of lookups per second. You can add the database by specifying a file or a URL where the data can be downloaded from. The server support non-interuptible updates and can update the database while the server is running.

An Organizationally Unique Identifier (OUI) is a 24-bit number that uniquely identifies a vendor, manufacturer, or other organization globally or worldwide.

These are purchased from the Institute of Electrical and Electronics Engineers, Incorporated (IEEE) Registration Authority by the "assignee" (IEEE term for the vendor, manufacturer, or other organization). They are used as the first portion of derivative identifiers to uniquely identify a particular piece of equipment as Ethernet MAC addresses, Subnetwork Access Protocol protocol identifiers, World Wide Names for Fibre Channel host bus adapters, and other Fibre Channel and Serial Attached SCSI devices.

In MAC addresses, the OUI is combined with a 24-bit number (assigned by the owner or 'assignee' of the OUI) to form the address. The first three octets of the address are the OUI. See full article on Wikipedia.

Documentation

[![GoDoc][1]][2] [![Build Status][3]][4] [1]: https://godoc.org/github.com/klauspost/oui?status.svg [2]: https://godoc.org/github.com/klauspost/oui [3]: https://travis-ci.org/klauspost/oui.svg [4]: https://travis-ci.org/klauspost/oui

Click here for Godoc reference, or see below for usage examples.

Usage

Using the library

This shows the basic usage if the library. Opening a database and querying.

import "github.com/klauspost/oui"

func main() {
    // Load the content from "oui.txt" into a static database
	db, err = oui.OpenStaticFile("oui.txt")

	// Query a mac address
	entry, err := db.Query("D0-DF-9A-D8-44-4B")

	// If error is nil, we have a result in "entry"
}

Note that only the D0-DF-9A part of the MAC address is used. The parser is flexible, and will allow colons instead of dashes, or even no separator at all, so these strings will return the same results: D0-DF-9A, D0:DF:9A & D0DF9A. The only thing to note is that you cannot omit zeros, so 00-00-00 must be fully filled.

When you initially load the database, you can specify that you want to be able to update it. Therefore this is safe:

import "github.com/klauspost/oui"

func main() {
	// Load the database from "oui.txt" into an updateable database.
	db, err = oui.OpenFile("oui.txt")

	go func() {
		for {
			// It is safe to keep querying the database while it is being updated.
			entry, err := db.Query("D0-DF-9A-D8-44-4B")
		}
	}()
	
	// Update the database while it is being queried.
	UpdateFile(db, "oui-newer.txt")
}

There are several advanced features, that allow you to specify the MAC address as byte values, and you can even request the raw static database for even faster lookups if you are doing many millions lookups per second. See the Godoc reference for more information on this.

Using the server

Downloading and build:

This method requires a Go installation.

go get github.com/klauspost/oui/ouiserver/...
go install github.com/klauspost/oui/ouiserver

This should build a "ouiserver" executable in your gopath.

###Service Options

Usage of ouiserver:
  -listen=":5000": Listen address and port, for instance 127.0.0.1:5000
  -open="oui.txt": File name with oui.txt to open. Set to 'http' to download
  -origin="*": Value sent in the "Access-Control-Allow-Origin" header.
  -pretty: Will output be formatted with newlines and intentation
  -threads=4: Number of threads to use. Defaults to number of detected cores
  -update-every="": Duration between reloading the database as 'cronexpr'. 
                    Examples are '@daily', '@weekly', '@monthly'

The open parameter accepts files or a http URL. If you specify http, the server will attempt to download the latest version from IEEE.

The update-every expression is a 'cronexpr', that allow you to precisely give update intervals. For more information on the syntax, see the Golang Cron expression parser documentation.

Querying the Server

Once the service is running, point your browser to http://localhost:5000/D0-DF-9A-D8-44-4B. You can replace "D0-DF-9A-D8-44-4B" with the Mac Address you would like to look up. You can also specify the MAC address as a parameter named "mac".

Note hat only the D0-DF-9A part of the MAC address is used. The parser is flexible, and will allow colons instead of dashes, or even no separator at all, so these strings will return the same results: D0-DF-9A, D0:DF:9A & D0DF9A. The only thing to note is that you cannot omit zeros, so 00-00-00 must be fully filled.

Currently looking up the address above yields:

{
  "data": {
    "manufacturer": "Liteon Technology Corporation",
    "address": [
      "Taipei  23585",
      "TAIWAN, PROVINCE OF CHINA"
    ],
    "prefix": "d0:df:9a",
    "country": "TAIWAN, PROVINCE OF CHINA"
  }
}

If you query a OUI that doesn't exist in the database, you will get a returncode 404 with this message:

{
  "error": "not found in db"
}

If any error occurs you will get a status 400 with an error message, for instance:

{
  "error": "invalid mac address '54-CD-': Address element 3 () is not 2 characters"
}

The time specified in the database as the generation time is sent as "Last-Modified" header.

Appengine

A special version of the server has been built for app-engine. It can be found in the appengine folder.

This version operates entirely from memory, and updates itself every 24 hours. To see a live running version of it you can go here: http://mac-oui.appspot.com/00-00-00

Docker

A docker repositry with the server can be found here: https://registry.hub.docker.com/u/klauspost/oui/

To fetch the docker image, run: docker pull klauspost/oui To run the server with default options and expose it to port 5000, run:

docker run -p 5000:5000 --rm klauspost/oui

License

This code is published under an MIT license. See LICENSE file for more information.

Documentation

Overview

Oui Lookup Library

This package allows lookin up manufacturer information from MAC addresses.

Package home: http://github.com/klauspost/oui

Index

Constants

This section is empty.

Variables

View Source
var ErrNotFound = errors.New("not found")

ErrNotFound will be returned when LookUp function fails to find the entry in the database.

Functions

func PrintDb

func PrintDb(db OuiDB)

PrintDb the entire database to stdout.

func Update

func Update(db DynamicDB, r io.Reader) error

Update will read and replace the content of the database. The database will remain usable while the update/parsing is taking place. If an error occurs during read or parsing, the database will not be replaced and the previous version will continue to be served.

func UpdateFile

func UpdateFile(db DynamicDB, name string) error

UpdateFile will read a file and replace the content of the database. The database will remain usable while the update/parsing is taking place. If an error occurs during read or parsing, the database will not be replaced and the previous version will continue to be served.

func UpdateHttp

func UpdateHttp(db DynamicDB, url string) error

UpdateHttp will download from a URL and replace the content of the database. The database will remain usable while the updating/parsing is taking place. If an error occurs during read or parsing, the database will not be replaced and the previous version will continue to be served.

Types

type DynamicDB

type DynamicDB interface {
	OuiDB
	Updater
}

DynamicDB is a database containing OUI entries that can be safely updated while queries are running. See the OuiDB interface for query functions.

func Open

func Open(in io.Reader) (DynamicDB, error)

Open will read the content of the given reader and return a database with the content. You can update the returned database using the Update/UpdateFile/UpdateHttp functions.

func OpenFile

func OpenFile(name string) (DynamicDB, error)

OpenFile will read the content of a oui.txt file and return a database with the content. You can update the returned database using the Update/UpdateFile/UpdateHttp functions.

func OpenHttp

func OpenHttp(url string) (DynamicDB, error)

OpenHttp will request the content of the URL given, parse it as a oui.txt file and return a database with the content. You can update the returned database using the Update/UpdateFile/UpdateHttp functions.

type Entry

type Entry struct {
	Manufacturer string       `json:"manufacturer"`
	Address      []string     `json:"address"`
	Prefix       HardwareAddr `json:"prefix"`
	Country      string       `json:"country,omitempty"`
	Local        bool         `json:"local,omitempty"`
	Multicast    bool         `json:"multicast,omitempty"`
}

A database Entry the represents the data in the oui database. Local and Multicast

func (*Entry) MarshalJSON

func (mj *Entry) MarshalJSON() ([]byte, error)

func (*Entry) MarshalJSONBuf

func (mj *Entry) MarshalJSONBuf(buf fflib.EncodingBuffer) error

func (Entry) String

func (e Entry) String() string

Returns a formatted string representation of the entry

type ErrInvalidMac

type ErrInvalidMac struct {
	Reason string
	Mac    string
}

This error will be returned by ParseMac if the Mac address cannot be decoded.

func (ErrInvalidMac) Error

func (e ErrInvalidMac) Error() string

Error returns a string representation of the error.

type HardwareAddr

type HardwareAddr [3]byte

HardwareAddr is the OUI part of a mac address. An easy way to get a hardware address is to use the ParseMac function The hardware address is in transmission bit order.

func ParseMac

func ParseMac(mac string) (*HardwareAddr, error)

ParseMac will parse a string Mac address and return the first 3 entries. It will attempt to find a separator, ':' and '-' supported. If none of these are matched, it will assume there is none.

func (HardwareAddr) Local

func (h HardwareAddr) Local() bool

Local returns true if the address is in the "locally administered" segment.

func (HardwareAddr) MarshalJSON

func (h HardwareAddr) MarshalJSON() ([]byte, error)

This function will return the address as a quoted hex string.

func (HardwareAddr) Multicast

func (h HardwareAddr) Multicast() bool

Multicast returns true if the address is in the multicast segment.

func (HardwareAddr) String

func (h HardwareAddr) String() string

String returns a hex string identifying the OUI. This will be as "xx:yy:zz" where elements are separated by ':' and written in transmission bit order

func (*HardwareAddr) UnmarshalJSON

func (h *HardwareAddr) UnmarshalJSON(in []byte) error

This function will return the address as a quoted hex string.

type OuiDB

type OuiDB interface {
	// Query the database for an entry based on the mac address
	// If none are found ErrNotFound will be returned.
	Query(string) (*Entry, error)

	// Look up a hardware address and return the entry if any are found.
	// If none are found ErrNotFound will be returned.
	LookUp(HardwareAddr) (*Entry, error)

	// Returns the generation time of the database
	// May return the zero time if unparsable
	Generated() time.Time
	// contains filtered or unexported methods
}

OuiDB represents a database that allow you to look up Hardware Addresses

type RawGetter

type RawGetter interface {
	RawDB() map[[3]byte]Entry
}

This interface can be used to access the raw database. This interface is available on Static databases.

type StaticDB

type StaticDB interface {
	OuiDB
	RawGetter
}

StaticDB is a database containing OUI entries that doesn't allow updates, but on the other hand allows access to the underlying data structure. See the OuiDB interface for query functions.

func OpenStatic

func OpenStatic(in io.Reader) (StaticDB, error)

OpenStatic will read the content of the given reader and return a database with the content. You will not be able to update this database, but you can request the raw database with the RawDB() function.

func OpenStaticFile

func OpenStaticFile(name string) (StaticDB, error)

OpenStaticFile will read the content of a oui.txt file and return a database with the content. You will not be able to update this database, but you can request the raw database with the RawDB() function.

func OpenStaticHttp

func OpenStaticHttp(url string) (StaticDB, error)

OpenStaticHttp will request the content of the URL given, parse it as a oui.txt file and return a database with the content. You will not be able to update this database, but you can request the raw database with the RawDB() function.

type Updater

type Updater interface {
	// UpdateEntry will update/add a single entry to the database.
	UpdateEntry(HardwareAddr, Entry)

	// DeleteEntry will remove an entry from the database. If the element does not exist, nothing should happen
	DeleteEntry(HardwareAddr)
	// contains filtered or unexported methods
}

The Updater interface will be satisfied if the database was opened as a dynamic database. This can be used to safely update the database, even while queries are running.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL