#!/usr/bin/python3 # # Script by Wouter Barendsen # Created : 2017-10-30 # modified: 2024-02-11 11:42:42 # # Module: netmiko import subprocess, sys, time, datetime, re, os import netmiko from operator import itemgetter ### Editable variables ###################### # IP of naam van de core router Device="192.168.2.254" # credentials User="user" Pass="password" # script directory ProgDir="/home/sjaak/scripts/macinvent/" # dir waar html files moeten komen ExportDir="/home/sjaak/public_html/macinvent/" # Namen van bestanden hoeven niet gewijzigd te worden Csv=ProgDir+"mac-invent.csv" Export=ExportDir+"mac-invent.html" Export2=ExportDir+"mac-invent-date.html" IpArp="shiparp.txt" # html kleuren evt aan te passen ColorLine="#ffe300" ColorBg="#fefecc" ### Variables ############################### SecsStart=time.time() Epoch=int(time.time()) MacInvent=[] LineCnt=0 Appended=0 Updated=0 Secs=0 def help(): print("mac-invent2.py by Wouter Barendsen 2017-2024") print(" -h, --help help") print(" ") print(" Doet een ssh naar een (core) router/L3-switch en doet 'sh ip arp',") print(" de output gaat door grep zodat alleen de mac adres regels erin staan.") print(" Dit bestand wordt doorlopen en vergeleken met het bestaande CSV bestand.") print(" Nieuwe mac adressen worden toegevoegd en bestaande mac adressen worden ") print(" geupdate met het laatst gezien ip adres, vlan en datum.") print(" ") exit(1) if len(sys.argv) >1: if sys.argv[1]=="-h" or sys.argv[1]=="--help": help() def getIpArp(Ip,Dest): if Ip == "none": exit ssh_connection = netmiko.ConnectHandler(device_type='cisco_ios',ip=Ip,username=User,password=Pass) result = ssh_connection.send_command("sh ip arp", delay_factor=1) ssh_connection.disconnect() resultList=result.split('\n') try: with open(Dest,'w') as F: for line in resultList: if "Vlan" in line: F.write(line+'\n') except IOError as E: print("Error writing",Dest,"!!") sys.exit(1) getIpArp(Device,ProgDir+IpArp) # lees de csv-file in een list of lists with open(Csv) as f: for Line in f: Line=Line.strip() Record=Line.split(sep=";") MacInvent.append(Record) LineCnt+=1 TotalRec=len(MacInvent) with open(ProgDir+IpArp) as f: for Line in f: # ontleed ip,vlan en mac Match=re.search(r'[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}',Line) if Match: Ip=Match.group() Match=re.search(r'Vlan([0-9]*)',Line) if Match: Vlan=Match.group(1) Match=re.search(r'[0-9a-z]{4}\.[0-9a-z]{4}\.[0-9a-z]{4}',Line) if Match: Mac=Match.group() #print("DEBUG: ",Ip,Vlan,Mac) # check of mac in list Index=0 Found=False for Effe in MacInvent: if Effe[0]==Mac: # ja: edit die regel met nieuwe ip, vlan en Epoch Found=True MacInvent[Index][1]=Vlan MacInvent[Index][2]=Ip MacInvent[Index][4]=str(Epoch) Updated+=1 Index=Index+1 if Found==False: # nee: append list met [mac,vlan,ip,Epoch,Epoch] MacInvent.append([Mac,Vlan,Ip,str(Epoch),str(Epoch)]) Appended+=1 print("Toegevoegd: "+Mac+" "+Vlan+" "+Ip) # sorteer list op vlan MacInvent2=sorted(MacInvent, key=itemgetter(1,2)) # sorteer op epoch laatste gezien MacInvent3=sorted(MacInvent, key=itemgetter(4)) # mv csv naar backup os.rename(Csv,Csv+".backup") # schrijf csv weg with open(Csv,'w') as f: for Effe in MacInvent2: f.write(Effe[0]+";"+Effe[1]+";"+Effe[2]+";"+Effe[3]+";"+Effe[4]+"\n") # Schrijf html export weg met dattime ipv epoch gesorteerd op mac adres Fseen="" Lseen="" Class="een" with open(Export,'w') as f: f.write("") f.write("") f.write("

mac-invent

") f.write("Deze export van mac-invent laat alle mac adressen zien die op het netwerk zijn geweest (gerouteerd!).
Het vlan en ip adres zijn de laatste waarmee dit mac adres gezien is op datum en tijd in de laatste kolom.
Bijzondere mac adressen die dubbel voorkomen (L3 switches) worden maar een keer getoond.

") for Effe in MacInvent2: Fs=datetime.datetime.fromtimestamp(int(Effe[3])) Ls=datetime.datetime.fromtimestamp(int(Effe[4])) Fseen=str.format("%04d-%02d-%02d_%02d:%02d" % (Fs.year,Fs.month,Fs.day,Fs.hour,Fs.minute)) Lseen=str.format("%04d-%02d-%02d_%02d:%02d" % (Ls.year,Ls.month,Ls.day,Ls.hour,Ls.minute)) Line="\n" f.write(Line) if Class=="een": Class="twee" else: Class="een" f.write("") # schrijf html export weg van op date_last_seen gesorteerde list with open(Export2,'w') as f: f.write("
Mac-addressvlanIPFirst seenLast seen
"+Effe[0]+""+Effe[1]+""+Effe[2]+""+Fseen+""+Lseen+"
") f.write("") f.write("

mac-invent

") f.write("Deze export van mac-invent laat alle mac adressen zien die op het netwerk zijn geweest (gerouteerd!).
Het vlan en ip adres zijn de laatste waarmee dit mac adres gezien is op datum en tijd in de laatste kolom.
Bijzondere mac adressen die dubbel voorkomen (L3 switches) worden maar een keer getoond.

") for Effe in MacInvent3: Fs=datetime.datetime.fromtimestamp(int(Effe[3])) Ls=datetime.datetime.fromtimestamp(int(Effe[4])) Fseen=str.format("%04d-%02d-%02d_%02d:%02d" % (Fs.year,Fs.month,Fs.day,Fs.hour,Fs.minute)) Lseen=str.format("%04d-%02d-%02d_%02d:%02d" % (Ls.year,Ls.month,Ls.day,Ls.hour,Ls.minute)) Line="\n" f.write(Line) if Class=="een": Class="twee" else: Class="een" f.write("") # Rapport, hoeveel updated, hoeveel nieuwe. SecsStop=time.time() print("Timestamp : "+Lseen) print("Records updated: "+str(Updated)) print("Records added : "+str(Appended)) print("Total records : "+str(TotalRec)) print("total time : %-.2f" % (SecsStop-SecsStart)) print("")
Mac-addressvlanIPFirst seenLast seen
"+Effe[0]+""+Effe[1]+""+Effe[2]+""+Fseen+""+Lseen+"