locate_mac à jour

This commit is contained in:
Pierre-Elliott Bécue 2015-08-22 05:15:34 +02:00
parent 36a299caa8
commit cc4c7c68c8

View file

@ -1,86 +1,83 @@
#! /usr/bin/env python #!/bin/bash /usr/scripts/python.sh
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
#
# locate_mac.py - permet de tracer une mac sur le réseau.
# Ignore les switches spéciaux et cachés, ainsi que les ports
# d'uplink.
#
# Pierre-Elliott Bécue <becue@crans.org>
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
import sys, re import sys
from time import sleep
from os import system
import threading
if '/usr/scripts' not in sys.path: from lc_ldap import shortcuts, printing
sys.path.append('/usr/scripts') from gestion.config.encoding import out_encoding
from gestion.ldap_crans import crans_ldap from gestion.hptools2 import tools
from gestion import whos from gestion import annuaires_pg
from gestion.annuaires_pg import all_switchs
from gestion.hptools import hpswitch
# mise en forme d'une adresse mac def get_chambres(mac):
def format_mac(unformated_mac): """Récupère la liste des chambres dans lesquelles mac se trouve"""
return str(":".join([i.zfill(2) for i in unformated_mac.split(":")]).lower()) # hptools2 retourne un tuple avec en premier élément la mac
# et en second élément la liste des ports sur lesquels la mac
# est vue. trace_mac appelle annuaires_pg.all_switchs(), qui
# ignore les switches spéciaux et cachés. De plus, on ignore
# les prises uplink
mac_ports_tuple = tools.trace_mac(mac, in_all_switches=True)
ports = mac_ports_tuple[1]
chambres = []
# classe d'interrogation des switchs for port in ports:
class interroge_switch (threading.Thread) : bat = port.name()[0]
def __init__ (self, switch, mac=None, affiche_uplinks=False): prise_num = port.name()[1:]
threading.Thread.__init__(self)
self.switch = switch
self.mac = mac
self.reponse = None
self.affiche_uplinks = affiche_uplinks
self.start()
def run (self) : # Ne retourne que la chambre, pas le bâtiment.
sw = hpswitch(self.switch) chbre_locale = annuaires_pg.reverse(bat, prise_num)[0]
prise = None
iteration = 3
while (prise==None) & (iteration > 0):
prise = sw.where_is_mac(self.mac)
iteration = iteration-1
if (prise != None):
nom=sw.nom(None,prise)
if self.affiche_uplinks or "uplink" not in nom:
self.reponse = ("%-10s => prise %-2s : %s" % (self.switch.encode('utf-8').replace('.adm.crans.org',''), str(prise), nom))
# Donc on ajoute le bâtiment
chambres.append("%s%s" % (bat.upper(), chbre_locale))
# Retourne les infos sur la machine (l'équivalent d'un whos, mais renvoie la return chambres
# chaîne de caractères)
def info_machine(mac):
s = []
db = crans_ldap()
machines = db.search("mac=%s" % mac)['machine']
for m in machines:
r = whos.machine_details(m)
# On supprime les couleurs
r = re.sub('\x1b\[1;([0-9]|[0-9][0-9])m', '', r)
s.append(r)
if len(machines) == 0:
s.append(u"Recherche LDAP de la MAC %s : aucune machine trouvée\n" % mac)
return u"\n".join(s)
def fetch_db(chambres):
"""Récupère dans la base LDAP les infos sur les proprios des
chambres"""
# interrogation des switchs en parallele ldap_conn = shortcuts.lc_ldap_readonly()
def trace_machine(mac, affiche_uplinks=False):
tableau = []
# ce code ne fork plus rien du tout depuis e05c4be14c86da88413c598e4c
for switch in all_switchs(hide=[]):
tableau.append(interroge_switch(switch, mac, affiche_uplinks))
for t in tableau: # On évite de multiplier les requêtes à LDAP
t.join() ldap_filter = u""
for chambre in chambres:
ldap_filter += u"(chbre=%s)" % (chambre,)
resultat = u'Traçage de %s...\n' % mac ldap_filter = u"(|%s)" % (ldap_filter,)
tracage = u'' results = ldap_conn.search(ldap_filter)
for t in tableau:
if t.reponse:
tracage += t.reponse + u"\n"
if tracage == u'':
tracage = u"Adresse MAC inconnue des switchs\n"
return (resultat + tracage) return results
# on interroge les switchs et on fait un whos sur la mac
if __name__ == '__main__': if __name__ == '__main__':
mac = format_mac(sys.argv[1]) MAC = tools.format_mac(sys.argv[1])
affiche_uplinks = len(sys.argv) > 2 and bool(sys.argv[2])
print trace_machine(mac, affiche_uplinks).encode('utf-8') # On trace la MAC et récupère les chambres
CHAMBRES = get_chambres(MAC)
# Via LDAP, on trouve les propriétaires
PROPRIOS = fetch_db(CHAMBRES)
# On se fiche des détails, on veut juste savoir chez qui on tombe
# sprint affiche entre autres la chambre du priorio
print printing.sprint_list(PROPRIOS).encode(out_encoding)