manuf2


Namemanuf2 JSON
Version 2.0.0 PyPI version JSON
download
home_pagehttps://github.com/joshschmelzle/manuf2
SummaryParser library for Wireshark's OUI database
upload_time2024-02-16 15:11:45
maintainer
docs_urlNone
authorJosh Schmelzle, Michael Huang
requires_python
licenseApache License 2.0 or GPLv3
keywords manuf2 mac address networking
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            manuf2
======

[![Build Status](https://github.com/coolbho3k/manuf/workflows/test/badge.svg)](https://github.com/coolbho3k/manuf/actions)
[![Build Status](https://badge.fury.io/py/manuf.svg)](https://pypi.org/project/manuf/)

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](https://www.wireshark.org/tools/oui-lookup.html).

This is a fork of manuf 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('BC:EE:7B:00:00:00')
    Vendor(manuf='AsustekC', comment='ASUSTek COMPUTER INC.')
    >>> p.get_manuf('BC:EE:7B:00:00:00')
    'AsustekC'
    >>> p.get_comment('BC:EE:7B:00:00:00')
    'ASUSTek COMPUTER INC.'

#### As a command line:

    $ manuf2 BC:EE:7B:00:00:00
    Vendor(manuf='AsustekC', comment='ASUSTek COMPUTER INC.')
    
Use a manuf file in a custom location:

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

Automatically update the manuf file from Wireshark's git:

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

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='AsustekC', comment='ASUSTek COMPUTER INC.')

Alternatively you can call the program with:

    python -m manuf2
or by executing the `manuf.py` script directly

```bash
./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](https://www.wireshark.org/download/automated/data/manuf").
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

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/joshschmelzle/manuf2",
    "name": "manuf2",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "manuf2,mac address,networking",
    "author": "Josh Schmelzle, Michael Huang",
    "author_email": "",
    "download_url": "https://files.pythonhosted.org/packages/0c/5a/0703c8fb82bc340ca4cf8c2eea5cd00cc1486d52680097c35b6db759557b/manuf2-2.0.0.tar.gz",
    "platform": null,
    "description": "manuf2\r\n======\r\n\r\n[![Build Status](https://github.com/coolbho3k/manuf/workflows/test/badge.svg)](https://github.com/coolbho3k/manuf/actions)\r\n[![Build Status](https://badge.fury.io/py/manuf.svg)](https://pypi.org/project/manuf/)\r\n\r\nParser library for Wireshark's OUI database.\r\n---\r\n\r\nConverts MAC addresses into a manufacturer using Wireshark's OUI database.\r\n\r\nOptimized for quick lookup performance by reading the entire file into memory\r\non initialization. Maps ranges of MAC addresses to manufacturers and comments\r\n(descriptions). Contains full support for netmasks and other strange things in\r\nthe database.\r\n\r\nSee [Wireshark's OUI lookup tool](https://www.wireshark.org/tools/oui-lookup.html).\r\n\r\nThis is a fork of manuf written by Michael Huang (coolbho3k).\r\n\r\nInstall\r\n---\r\n\r\n#### With PyPi\r\n\r\n    pip install manuf2\r\n\r\n#### Or Manually\r\n\r\n    git clone https://github.com/joshschmelzle/manuf2\r\n    cd manuf2\r\n    python setup.py install\r\n\r\nUsage\r\n---\r\n\r\n#### As a library:\r\n\r\n    >>> from manuf2 import manuf\r\n    >>> p = manuf.MacParser(update=True)\r\n    >>> p.get_all('BC:EE:7B:00:00:00')\r\n    Vendor(manuf='AsustekC', comment='ASUSTek COMPUTER INC.')\r\n    >>> p.get_manuf('BC:EE:7B:00:00:00')\r\n    'AsustekC'\r\n    >>> p.get_comment('BC:EE:7B:00:00:00')\r\n    'ASUSTek COMPUTER INC.'\r\n\r\n#### As a command line:\r\n\r\n    $ manuf2 BC:EE:7B:00:00:00\r\n    Vendor(manuf='AsustekC', comment='ASUSTek COMPUTER INC.')\r\n    \r\nUse a manuf file in a custom location:\r\n\r\n    $ manuf2 --manuf ~/manuf BC:EE:7B:00:00:00\r\n    Vendor(manuf='AsustekC', comment='ASUSTek COMPUTER INC.')\r\n\r\nAutomatically update the manuf file from Wireshark's git:\r\n\r\n    $ manuf2 --update BC:EE:7B:00:00:00\r\n    Vendor(manuf='AsustekC', comment='ASUSTek COMPUTER INC.')\r\n\r\nNote, that this command will update the manuf file bundled with this package. If you do not wish to \r\nmodify this, or do not have permissions to do so, you must specify a custom manuf file to perform an update.\r\n\r\n    $ manuf2 --update --manuf ~/manuf BC:EE:7B:00:00:00\r\n    Vendor(manuf='AsustekC', comment='ASUSTek COMPUTER INC.')\r\n\r\nAlternatively you can call the program with:\r\n\r\n    python -m manuf2\r\nor by executing the `manuf.py` script directly\r\n\r\n```bash\r\n./manuf2/manuf.py # From the install folder\r\n```\r\n\r\nFeatures and advantages of manuf\r\n---\r\n\r\nNote: the examples use the manuf file provided in the first commit, 9a180b5.\r\n\r\nmanuf.py is more accurate than more naive scripts that parse the manuf file.\r\nCritically, it contains support for netmasks.\r\n\r\nFor a usual entry, such as BC:EE:7B (AsustekC), the manufacturer \"owns\" the\r\nlast half (24 bits) of the MAC address and is free to assign the addresses\r\nBC:EE:7B:00:00:00 through BC:EE:7B:FF:FF:FF, inclusive, to its devices.\r\n\r\nHowever, entries like the following also appear commonly in the file:\r\n\r\n    00:1B:C5:00:00:00/36\tConvergi               # Converging Systems Inc.\r\n    00:1B:C5:00:10:00/36\tOpenrbCo               # OpenRB.com, Direct SIA\r\n\r\n/36 is a netmask, which means that the listed manufacturer \"owns\" only the last\r\n12 bits of the MAC address instead of the usual 24 bits (since MAC addresses\r\nare 48 bits long, and 48 bits - 36 bits = 12 bits).\r\n\r\nThis means that Converging Systems is only free to assign the addresss block\r\n00:1B:C5:00:00:00 through 00:1B:C5:00:0F:FF. Anything after that belongs to\r\nother manufacturers. manuf.py takes this fact into account:\r\n\r\n    >>> p.get_manuf('00:1B:C5:00:00:00')\r\n    'Convergi'\r\n    >>> p.get_manuf('00:1B:C5:00:0F:FF')\r\n    'Convergi'\r\n    >>> p.get_manuf('00:1B:C5:00:10:00')\r\n    'OpenrbCo'\r\n\r\nEven Wireshark's web lookup tool fails here. \"00:1B:C5:00:0F:FF\" returns only\r\n\"IEEE REGISTRATION AUTHORITY\" while it should instead return \"Converging\r\nSystems Inc.\" If a netmask is not explicitly specified, a netmask of /24 is\r\nimplied. Since this covers most of the entries, most tools only parse the first\r\n24 bits.\r\n\r\nmanuf.py fully supports even more esoteric entries in the database. For example,\r\nconsider these two entries:\r\n\r\n    01-80-C2-00-00-30/45\tOAM-Multicast-DA-Class-1\r\n    01-80-C2-00-00-38/45\tOAM-Multicast-DA-Class-2\r\n\r\nWith a netmask of /45, only the last 3 bits of the address are significant.\r\nThis means that a device is considered \"OAM-Multicast-DA-Class-1\" only if the\r\nlast digit falls between 0x0 and 0x7 and \"OAM-Multicast-DA-Class-2\" only if the\r\nlast digit falls between 0x8 and 0xF.\r\n\r\nIf the last octet is 0x40 or over, or 0x2F or under, the address doesn't belong\r\nto any manufacturer.\r\n\r\n    >>> p.get_manuf('01:80:C2:00:00:2F')\r\n    >>> p.get_manuf('01:80:C2:00:00:30')\r\n    'OAM-Multicast-DA-Class-1'\r\n    >>> p.get_manuf('01:80:C2:00:00:37')\r\n    'OAM-Multicast-DA-Class-1'\r\n    >>> p.get_manuf('01:80:C2:00:00:38')\r\n    'OAM-Multicast-DA-Class-2'\r\n    >>> p.get_manuf('01:80:C2:00:00:3F')\r\n    'OAM-Multicast-DA-Class-2'\r\n    >>> p.get_manuf('01:80:C2:00:00:40')\r\n\r\nAgain, the official lookup tool fails here as well, with \"01:80:C2:00:00:31\"\r\nreturning no results.\r\n\r\nAlgorithm\r\n---\r\n\r\nAlthough optimized for correctness, manuf.py is also quite fast, with average\r\nO(1) lookup time, O(n) setup time, and O(n) memory footprint.\r\n\r\nFirst, the entire manuf file is read into memory. Each manuf line is stored in\r\na dict mapping a tuple calculated from the MAC address and netmask to each\r\nmanuf:\r\n\r\n    ((48 - netmask), macaddress >> (48 - netmask))\r\n\r\nThe (48 - netmask) value is called the \"bits left\" value in the code.\r\n\r\nFor example, Converging Systems' MAC is 0x001BC5000000 and its netmask is 36,\r\nso its key in the dict is this:\r\n\r\n    (12, 0x001BC5000000 >> 12)\r\n\r\nTo lookup \"00:1B:C5:00:0F:FF\" we will check the dict beginning with a \"bits\r\nleft\" value of 0, incrementing until we find a match or go over 47 (which means\r\nwe have no match):\r\n\r\n    (0, 0x001BC5000FFF >> 0)\r\n    (1, 0x001BC5000FFF >> 1)\r\n    (2, 0x001BC5000FFF >> 2)\r\n    ...\r\n    (12, 0x001BC5000FFF >> 12)\r\n\r\nSince (12, 0x001BC5000FFF >> 12) equals (12, 0x001BC5000000 >> 12), we have a\r\nmatch on the 13th iteration of the loop.\r\n\r\nCopying\r\n---\r\n\r\nThis library does not link to Wireshark's manuf database; it merely parses it,\r\nso I have chosen to publish it under the LGPLv3 and Apache License 2.0\r\ninstead of the GPLv2. The manuf database is provided for your convenience in\r\nthis repository, but will not be updated.\r\n\r\n* License for Python library: LGPLv3 and Apache License 2.0 (dual licensed)\r\n* License for manuf database: GPLv2\r\n\r\nThe latest version of the manuf database can be found in the\r\n[Wireshark automated data](https://www.wireshark.org/download/automated/data/manuf\").\r\nThe database there is updated about once a week, so you may want to grab the\r\nlatest version to use instead of using the one provided here by using the\r\n--update flag on the command line:\r\n\r\n    manuf2 --update\r\n\r\nRun tests\r\n---\r\n\r\n    python -m unittest manuf2.test.test_manuf\r\n",
    "bugtrack_url": null,
    "license": "Apache License 2.0 or GPLv3",
    "summary": "Parser library for Wireshark's OUI database",
    "version": "2.0.0",
    "project_urls": {
        "Homepage": "https://github.com/joshschmelzle/manuf2"
    },
    "split_keywords": [
        "manuf2",
        "mac address",
        "networking"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "0c5a0703c8fb82bc340ca4cf8c2eea5cd00cc1486d52680097c35b6db759557b",
                "md5": "03e6832ba8589f52c0b0425e502e95b8",
                "sha256": "1425db18cfa7c5523a82d185869d8a530bc2d6041ee43bd6acba2ed3e225d362"
            },
            "downloads": -1,
            "filename": "manuf2-2.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "03e6832ba8589f52c0b0425e502e95b8",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 722512,
            "upload_time": "2024-02-16T15:11:45",
            "upload_time_iso_8601": "2024-02-16T15:11:45.794574Z",
            "url": "https://files.pythonhosted.org/packages/0c/5a/0703c8fb82bc340ca4cf8c2eea5cd00cc1486d52680097c35b6db759557b/manuf2-2.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-02-16 15:11:45",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "joshschmelzle",
    "github_project": "manuf2",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "manuf2"
}
        
Elapsed time: 0.20484s