Na rede local, muitas vezes você precisa descobrir em qual porta do switch o endereço MAC específico do dispositivo está localizado. O problema é facilmente resolvido se houver vários comutadores na rede, mas quando houver mais de 30 deles, tudo se tornará muito mais complicado. Quero compartilhar um pequeno script Python que procure o endereço MAC desejado na rede e retorne o nome e a porta do switch no qual esse MAC está registrado.

Críticas construtivas são bem-vindas. Detalhes sob o corte.
Se o design da rede for feito corretamente, ou seja, o comutador raiz
CORE , ao qual os comutadores de distribuição
DS (Switch de distribuição) estão conectados e a eles, por sua vez, os comutadores de nível
AS (comutador de acesso). Essa regra nem sempre é verdadeira; os comutadores de acesso podem ser conectados em série. De qualquer forma, a porta do switch upstream contém todos os endereços MAC dos dispositivos conectados ao switch downstream.
Por exemplo, se o dispositivo de nosso interesse estiver conectado ao comutador
AS3 , iniciando a pesquisa com
CORE , encontraremos esse endereço na porta que leva ao
DS1 . Indo para o
DS1 , encontraremos esse MAC na porta que leva ao
AS2 , ao
AS2 , veremos que ele nos leva ao
AS3 , e somente no
AS3 encontraremos a porta específica à qual o dispositivo de interesse está conectado.
Eu não queria fazer tudo manualmente, classificar todos os comutadores em um loop e determinar onde fica o uplink e onde não está, então nasceu a próxima solução, que eu quero compartilhar.
Um pouco de teoria.
Para localizar o MAC
08: 62: 66: c7: b3: 45 no switch Juniper, execute o seguinte comando:
show ethernet-switching table | match 08:62:66:c7:b3:45
Se houver esse MAC, a resposta será a seguinte:
vlan151 08:62:66:c7:b3:45 D - xe-0/0/23.0
A última coluna será o nome da interface do switch no qual o MAC está registrado. Mas como entender para onde essa interface leva? E aqui as
descrições de interface são úteis. Essas são linhas no arquivo de configuração do comutador que permitem atribuir rótulos de texto às interfaces.
A equipe
show interfaces xe-0/0/23 descriptions
mostrará o seguinte:
Interface Admin Link Description xe-0/0/23 up up SW>DS1
Na configuração, indicamos que essa interface leva ao switch downstream:
set interfaces xe-0/0/23 description SW>DS1
Implementação
O script proposto fará o seguinte:
- Conecte-se via SSH ao switch raiz
- verifique em qual interface o endereço MAC passado nos parâmetros está localizado;
- Marque Descrição desta interface;
- se a interface levar ao comutador, acesse o próximo comutador na cadeia recursivamente.
Assim, o script passará por todos os comutadores de rede, iniciando no kernel, e tentará encontrar o MAC desejado. Para uma operação bem-sucedida, basta manter as descrições das interfaces atualizadas, e a topologia pode ter quase qualquer complexidade.
Um exemplo de script:
python findmac.py 00:17:fc:21:e8:f9 {"host": "CORE", "iface": "xe-0/0/23.0", "description": "SW>DS1"} {"host": "DS1", "iface": "xe-0/0/11.0", "description": "SW>AS2"} {"host": "AS2", "iface": "xe-1/0/1.0", "description": "SW>AS3"} {"host": "AS3", "iface": "ge-0/0/26.0", "description": "none"}
Se não houver MAC, obtemos
{"host": "CORE", "iface": "none"}
A última linha é o switch e a porta que nos interessam, mas, ao mesmo tempo, podemos rastrear todo o caminho de pesquisa.
O código completo está sob o spoiler, obrigado por sua atenção.
findmac.py import paramiko import time import sys import json import threading import logging login = 'user1' password = 'pass1234' searchpass = [] port = 22 class LogPipe(threading.Thread): def __init__(self, level): threading.Thread.__init__(self) self.daemon = False self.level = level self.fdRead, self.fdWrite = os.pipe() self.pipeReader = os.fdopen(self.fdRead) self.start() def fileno(self): return self.fdWrite def run(self): for line in iter(self.pipeReader.readline, ''): logging.log(self.level, line.strip('\n')) self.pipeReader.close() def close(self): os.close(self.fdWrite) def execute_ssh_command(host, port, username, password, command): try: