-
-
Save joshschmelzle/ca60cc1e16176798dfba7a49d814614a to your computer and use it in GitHub Desktop.
Handy OUI lookup script for Python 3+. Tested on Windows 10.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# Who owns the OUI? IEEE knows. | |
# | |
# Auto-refreshes once a month. | |
# Run with -u to force update. | |
from urllib.request import urlopen | |
from getpass import getuser | |
import codecs | |
import sys | |
import time | |
import os | |
import re | |
USER_HOME = "~" | |
OUI_FILE_STORE = os.path.join(os.path.expanduser(USER_HOME), ".oui-cache") | |
CACHE_TIME = 2592000 # 30 days should be fine | |
IEEE_URL = "http://standards.ieee.org/develop/regauth/oui/oui.txt" | |
def clean_input(user_input): | |
# """ | |
# Strip colons | |
# """ | |
return "".join(user_input.split('-')[:3]) | |
def update_cache(): | |
# """ | |
# Update our local file from the IEEE OUI | |
# list | |
# """ | |
print(">>> Updating Cache") | |
try: | |
with open(OUI_FILE_STORE, 'r') as outfile: | |
for lne in urlopen(IEEE_URL).readlines(): | |
outfile.write(lne) | |
except FileNotFoundError: | |
with open(OUI_FILE_STORE, 'wb') as outfile: | |
for lne in urlopen(IEEE_URL).readlines(): | |
outfile.write(lne) | |
print(">>> Done") | |
def process_args(): | |
# """ | |
# Parse our args | |
# """ | |
if sys.argv[1] == "-u": | |
update_cache() | |
if len(sys.argv) > 2: | |
user_input = sys.argv[2] | |
else: | |
sys.exit(0) | |
else: | |
user_input = sys.argv[1] | |
return clean_input(user_input) | |
def get_manufacturer(raw_mac): | |
# """ | |
# Return manufacturer from cached file | |
# """ | |
clean_mac = clean_input(raw_mac) | |
try: | |
if time.time() - os.stat(OUI_FILE_STORE).st_ctime > CACHE_TIME: | |
update_cache() | |
except OSError as err: | |
if err.errno == 2: | |
update_cache() | |
with codecs.open(OUI_FILE_STORE,'r',encoding='utf8') as oui_list: | |
for line in iter(oui_list): | |
if re.search(clean_mac, line, re.IGNORECASE): | |
return line.split("\t")[-1].strip() | |
return "unknown" | |
if __name__ == "__main__": | |
print(get_manufacturer(process_args())) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi, thank you for this, I have adapted it and use it. I found the following changes were needed for me with Python 3.10. Thought I'd share in case you'd like to reconsider your code (I am new to code, so feel free to tell me I am wrong).
Line 36 "with open(OUI_FILE_STORE, 'r') as outfile:" - needed 'wb' instead of 'r' to avoid an error - "argument must be str, not bytes"
Line 68 "if time.time() - os.stat(OUI_FILE_STORE).st_ctime > CACHE_TIME:" - changed ctime to mtime. For me, without this it didn't detect the last updated date of the local file correctly, and tried to update the file on every mac address that it ran, in my case, I pushing a heap of MACs from a different script, which meant it updated the oui file everytime a MAC came to it.