Back to the main page

Search for duplicated MAC (hardware address)

Intro

This is python script to search for duplicated MAC in clients' config files. It's requirement that each DHCP client has its own config file. The script argument is directory path with clients' configs. This can be run as cronjob. It's written in python 3.5.
If there are duplicates, it sends email about that.

Script

#!/import/bin/python3 # look for duplicate MAC in -p path # hopefully client's config is not in one line, # otherwise the script may show 'funny' results # -------------------------------------------- import os import socket import sys import fileinput import re import subprocess import smtplib from email.mime.text import MIMEText import argparse parser = argparse.ArgumentParser( description="Search for duplicated MAC in DHCP reservation", epilog='Brought to you by Zarko') parser.add_argument("-p", "--path", help="Path of clients' configs, example /etc/dhcp/clients", required=True) args = parser.parse_args() CLNTDIR=args.path # tmp files ALLMAC = "/tmp/allmac" UNIQMAC = "/tmp/uniqmac" DPLMAC = "/tmp/dplmac" MSGTXT = "/tmp/body" if not os.path.exists(CLNTDIR): sys.exit("ERROR: " + CLNTDIR + " does not exist.") def remove_tmp_files(): """ Remove tmep files """ if os.path.exists(ALLMAC): os.remove(ALLMAC) if os.path.exists(UNIQMAC): os.remove(UNIQMAC) if os.path.exists(DPLMAC): os.remove(DPLMAC) if os.path.exists(MSGTXT): os.remove(MSGTXT) def send_email(): """ Send email with info about duplicates """ with open(MSGTXT, "r") as fm: message = MIMEText( fm.read() ) message['Subject'] = "WARNING, %s duplicated MAC in " % duplicate_number + socket.gethostname() fromaddr = 'labops-support@dom.com' toaddr = 'zarko@dom.com' try: email_object = smtplib.SMTP(host="mail-router.dom.com") email_object.sendmail(fromaddr, toaddr, message.as_string()) except: sys.exit("Error: can't send email") def find_duplicates(): """ Find duplicated and its number """ global duplicate_number global duplicate_mac macregex = re.compile('([0-9a-fA-F]{1,2}[:]){5}([0-9a-fA-F]{1,2})') try: for root, dirs, files in os.walk(CLNTDIR): for clientname in files: try: with open(CLNTDIR + "/" + clientname, "r") as f: allmac = open(ALLMAC, "a+") for line in f: if macregex.search(line): allmac.write(line.lower().strip().replace("hardware ethernet", "").replace(";", "") + "\n") allmac.close() except IOError as err: sys.exit("IOError: {0}".format(err)) except Exception as err: # general exception sys.exit("Error: {0}".format(err)) subprocess.check_output(["cat %s | sed 's/[ ]*$//g' |sort -f | uniq -i| tee %s " % (ALLMAC, UNIQMAC)], shell=True) # sed removes any space subprocess.check_output(["cat %s | sed 's/[ ]*$//g' |sort -f | uniq -id | tee %s" % (ALLMAC, DPLMAC)], shell=True) duplicate_mac = subprocess.check_output(["cat %s" % DPLMAC], shell=True).decode('ASCII').strip() duplicate_number = subprocess.check_output(["cat %s | wc -l" % DPLMAC], shell=True).decode('ASCII').strip() if __name__ == '__main__': remove_tmp_files() find_duplicates() if int(duplicate_number) > 0: for mac in duplicate_mac.split(): with open(MSGTXT, "a+") as msg: msg.write("\n" + mac + " is owned by:\n") pattern = re.compile(mac, re.IGNORECASE) try: for root, dirs, files in os.walk(CLNTDIR): for clientname in files: with open(CLNTDIR + "/" + clientname, "r") as f: for line in f: if pattern.search(line): msg.write(clientname + "\n") except Exception as err: # general exception sys.exit("Error: {0}".format(err)) send_email() remove_tmp_files() sys.exit(0)

If there are duplicates, email subject and body is like:

Subject: WARNING, 1 duplicated MAC in dhcp-server.dom.com

00:11:e0:c3:b7:fc is owned by:
install-test-1.dom.com
x7-2.dom.com



Back to the main page