Skip to main content

manuf2

Build Status Build Status

Parser library for Wireshark's OUI database.

Converts MAC addresses into a manufacturer using Wireshark's OUI database.

Optimized for quick lookup performance by reading the entire file into memory on initialization. Maps ranges of MAC addresses to manufacturers and comments (descriptions). Contains full support for netmasks and other strange things in the database.

See Wireshark's OUI lookup tool.

This is a fork of manuf maintained by Josh Schmelzle (jsz) originally written by Michael Huang (coolbho3k).

Install

With PyPi

pip install manuf2

Or Manually

git clone https://github.com/joshschmelzle/manuf2
cd manuf2
python setup.py install

Usage

As a library:

>>> from manuf2 import manuf
>>> p = manuf.MacParser(update=True)
>>> p.get_all('04:D3:95:00:00:00')
Vendor(manuf='ASUSTekCOMPU', manuf_long='ASUSTek COMPUTER INC.', comment=None)
>>> p.get_manuf('04:D3:95:00:00:00')
'ASUSTekCOMPU'
>>> p.get_comment('04:D3:95:00:00:00')
>>>

As a command line:

$ manuf2 BC:EE:7B:00:00:00
Vendor(manuf='ASUSTekCOMPU', manuf_long='ASUSTek COMPUTER INC.', comment=None)

Use a manuf file in a custom location:

$ manuf2 --manuf ~/manuf BC:EE:7B:00:00:00
Vendor(manuf='ASUSTekCOMPU', manuf_long='ASUSTek COMPUTER INC.', comment=None)

Automatically update the manuf file from Wireshark's git:

$ manuf2 --update BC:EE:7B:00:00:00
Vendor(manuf='ASUSTekCOMPU', manuf_long='ASUSTek COMPUTER INC.', comment=None)

Note, that this command will update the manuf file bundled with this package. If you do not wish to modify this, or do not have permissions to do so, you must specify a custom manuf file to perform an update.

$ manuf2 --update --manuf ~/manuf BC:EE:7B:00:00:00
Vendor(manuf='ASUSTekCOMPU', manuf_long='ASUSTek COMPUTER INC.', comment=None)

Alternatively you can call the program with:

python -m manuf2

or by executing the manuf.py script directly

./manuf2/manuf.py # From the install folder

Features and advantages of manuf

Note: the examples use the manuf file provided in the first commit, 9a180b5.

manuf.py is more accurate than more naive scripts that parse the manuf file. Critically, it contains support for netmasks.

For a usual entry, such as BC:EE:7B (AsustekC), the manufacturer "owns" the last half (24 bits) of the MAC address and is free to assign the addresses BC:EE:7B:00:00:00 through BC:EE:7B:FF:FF:FF, inclusive, to its devices.

However, entries like the following also appear commonly in the file:

00:1B:C5:00:00:00/36	Convergi               # Converging Systems Inc.
00:1B:C5:00:10:00/36	OpenrbCo               # OpenRB.com, Direct SIA

/36 is a netmask, which means that the listed manufacturer "owns" only the last 12 bits of the MAC address instead of the usual 24 bits (since MAC addresses are 48 bits long, and 48 bits - 36 bits = 12 bits).

This means that Converging Systems is only free to assign the addresss block 00:1B:C5:00:00:00 through 00:1B:C5:00:0F:FF. Anything after that belongs to other manufacturers. manuf.py takes this fact into account:

>>> p.get_manuf('00:1B:C5:00:00:00')
'Convergi'
>>> p.get_manuf('00:1B:C5:00:0F:FF')
'Convergi'
>>> p.get_manuf('00:1B:C5:00:10:00')
'OpenrbCo'

Even Wireshark's web lookup tool fails here. "00:1B:C5:00:0F:FF" returns only "IEEE REGISTRATION AUTHORITY" while it should instead return "Converging Systems Inc." If a netmask is not explicitly specified, a netmask of /24 is implied. Since this covers most of the entries, most tools only parse the first 24 bits.

manuf.py fully supports even more esoteric entries in the database. For example, consider these two entries:

01-80-C2-00-00-30/45	OAM-Multicast-DA-Class-1
01-80-C2-00-00-38/45	OAM-Multicast-DA-Class-2

With a netmask of /45, only the last 3 bits of the address are significant. This means that a device is considered "OAM-Multicast-DA-Class-1" only if the last digit falls between 0x0 and 0x7 and "OAM-Multicast-DA-Class-2" only if the last digit falls between 0x8 and 0xF.

If the last octet is 0x40 or over, or 0x2F or under, the address doesn't belong to any manufacturer.

>>> p.get_manuf('01:80:C2:00:00:2F')
>>> p.get_manuf('01:80:C2:00:00:30')
'OAM-Multicast-DA-Class-1'
>>> p.get_manuf('01:80:C2:00:00:37')
'OAM-Multicast-DA-Class-1'
>>> p.get_manuf('01:80:C2:00:00:38')
'OAM-Multicast-DA-Class-2'
>>> p.get_manuf('01:80:C2:00:00:3F')
'OAM-Multicast-DA-Class-2'
>>> p.get_manuf('01:80:C2:00:00:40')

Again, the official lookup tool fails here as well, with "01:80:C2:00:00:31" returning no results.

Algorithm

Although optimized for correctness, manuf.py is also quite fast, with average O(1) lookup time, O(n) setup time, and O(n) memory footprint.

First, the entire manuf file is read into memory. Each manuf line is stored in a dict mapping a tuple calculated from the MAC address and netmask to each manuf:

((48 - netmask), macaddress >> (48 - netmask))

The (48 - netmask) value is called the "bits left" value in the code.

For example, Converging Systems' MAC is 0x001BC5000000 and its netmask is 36, so its key in the dict is this:

(12, 0x001BC5000000 >> 12)

To lookup "00:1B:C5:00:0F:FF" we will check the dict beginning with a "bits left" value of 0, incrementing until we find a match or go over 47 (which means we have no match):

(0, 0x001BC5000FFF >> 0)
(1, 0x001BC5000FFF >> 1)
(2, 0x001BC5000FFF >> 2)
...
(12, 0x001BC5000FFF >> 12)

Since (12, 0x001BC5000FFF >> 12) equals (12, 0x001BC5000000 >> 12), we have a match on the 13th iteration of the loop.

Copying

This library does not link to Wireshark's manuf database; it merely parses it, so I have chosen to publish it under the LGPLv3 and Apache License 2.0 instead of the GPLv2. The manuf database is provided for your convenience in this repository, but will not be updated.

  • License for Python library: LGPLv3 and Apache License 2.0 (dual licensed)
  • License for manuf database: GPLv2

The latest version of the manuf database can be found in the Wireshark automated data. The database there is updated about once a week, so you may want to grab the latest version to use instead of using the one provided here by using the --update flag on the command line:

manuf2 --update

Run tests

python -m unittest manuf2.test.test_manuf

Metadata

Release files for manuf2 2.0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for manuf2 2.0.3
File Size Uploaded Provenance
manuf2-2.0.3.tar.gz 827.6 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for manuf2 2.0.3
File Interpreter ABI Platform
manuf2-2.0.3-py3-none-any.whl Python 3 none any Details

Total release size: 1.7 MB

Release files / manuf2-2.0.3.tar.gz

Download URL manuf2-2.0.3.tar.gz
Size 827.6 kB
Tags Source
SHA-256 checksum
How to use checksums
13b2a86ceba6311b3b4cbe713506af3234c838a02d6f8d723939aab85924d32f
BLAKE2b-256 checksum
How to use checksums
33e54f4faf198bbc7acdc50050addcf365750de77878e01df60046bba377c850
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / manuf2-2.0.3-py3-none-any.whl

Download URL manuf2-2.0.3-py3-none-any.whl
Size 832.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
98e1a06db5a684f4c7346a4189b1e2c2f6d3aa1089bf14febab7902744ea1ca3
BLAKE2b-256 checksum
How to use checksums
1630e168816bccf05913ae7ace756a147a5ec7e0552493f38412fb00a8f0349d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Security for manuf2 2.0.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for manuf2-2.0.3.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page