Vous êtes sur la page 1sur 4

31/03/2010

Document réalisé par :


ABDELLI Samir

SNMP, interrogation de base d'un commutateur


par un script Python

Énoncé:

On vous demande de faire en sorte que l'on puisse obtenir sous une forme propre et
lisible des informations de base d'un commutateur géré par SNMP. Le choix des éléments et
leur présentation est laissé à votre initiative. On souhaite cependant pouvoir utiliser votre
programme pour savoir sur quel port d'un commutateur est reliée une machine ayant une
adresse Mac donnée. Votre programme devra permettre de réaliser deux types de sorties : une
sortie texte structurée pour être lisible par un être humain mais aussi parsable par les outils
standard UNIX et une sortie HTML affichable dans un navigateur Web.
Le langage support sera de préférence python.

Introduction:

Le script en python joint à ce document interroge un commutateur à l'adresse IP


192.168.195.11. La communauté SNMP « asr » (en minuscule) à un accès en lecture. Notre
script n'utilise pas les fonctions de Python pour interagir avec le commutateur mais utilise un
outils (package UNIX) pour cela. Ce package et le « Net-SNMP ».
Pour le télécharger, faire: apt-get install python-pynetsnmp (installer aussi netsnmp-utils).
De ce package on utilisera la commande « snmpwalk » et la commande « snmptable ».

La commande « snmpwalk »
Cette commande permet de balayer complètement une branche de la MIB d’un agent
SNMP distant et retourne le résultat.
• ex: snmpwalk -v 2c - c public localhost system
récupère le informations « system » de l'agent SNMP de version « 2c » en « localhost »
de la communauté « public »

La commande « snmptable »
Cette commande permet de récupérer le contenu d'une table de la MIB d’un agent
SNMP distant. Elle affiche le résultat dans des colonnes.
• ex: snmpwalk -v 2c - c public -Cf '~' localhost ifTable
récupère le informations de la table «ifTable» en mettant un séparateur « ~ » de l'agent
SNMP de version « 2c » en « localhost » de la communauté « public »

La Script:

Les classes:

class SNMPWalkTable(Popen):
Cette classe contient toutes les fonctions. Elle utilise « Popen » elle renvoie un flux
d'entrée/sortie

Les variables d'entrées:


• agent: adresse IP du communauté
• oid:(Object Identifier) qui permet aux commande snmpwalk ou snmptable d'accéder à
des informations
• mac: adresse mac donnée en entrée par l'utilisateur

Les fonctions:
• def __init__(self, **kwds):
Cette fonction est la fonction principale dans la classe « SNMPWalkTable ». Elle permet
de lancer les commande « snmpwalk » et « snmptable ». Elle fait appel à d'autres fonctions
selon les paramètres d'entrées

•def __macIp_show(self, agent):


Cette fonction permet d'afficher l'adresse MAC des machines et l'adresse IP
correspondante à chaque machine

•def __get_interfaceName(self, agent, ifName):


Cette fonction est appelée par la fonction « __macIp_show ». Son but et de récupérer
le nom de l'interface afin de trouver l'adresse mac de port sur le commutateur et l'adresse IP
de la machine connectée à ce port ( ou interface). Cette fonction n'est pas encore
opérationnelle.

•def __sys_Info(self, agent, oid):


Cette fonction génère un fichier l'entête d'un fichier « html » qui contient des
informations de base sur le commutateur. Ce fichier sera modifié par la fonction
« __make_html ». L'objectif de cette fonction est d'ajouter des détails aux fichiers html
généré.

•def __simple_Print(self, agent, mac):


Cette fonction prend en entrée une adresse mac pour trouver le port auquel elle est
connectée. Cette fonction applique une conversion. Elle prend l'adresse mac en format
hexadécimal pour la convertir en format décimal dans le but de trouver une correspondance
dans le OID « 1.3.6.1.2.1.17.4.3.1.2 » ou « dot1dTpFdbPort » et si c'est le cas elle récupère le
numéro de port. Dans notre cas, elle procède comme suit:

1- macSave = mac 1- Enregistrer l'adresse mac


2- mac = mac.split(':') 2- Créer un tableau mac qui contient les élément
3- macDec = [] d'une adresse mac
4- macPointDecList = [] 3- Créer une tableau macDec qui contiendra les
5- for macSplit in mac: élément de l'adresse mac en décimal
macDec.append(str(int(macSplit, 16))) 4- Créer un tableau macPointDecList qui contient les
élément de l'adresse mac en décimal
6- for macPointDecList in macDec: 5- Pour chaque élément de tableau mac faire
macPointDecList = '.'.join(macDec) Convertir cet élément en entier puis en string et
insérer le dans le tableau macDec
7- MAC_found = 'no' 6- Pour chaque élément de macDec
8- while True: Insérer le dans le tableau macDecList en ajoutant un
line = self.stdout.readline() point « . »(pour avoir en sortie par exemple
if not line: macDecList=3.34.45.66.130)
break 7- Variable booléenne « MAC_found » initialisée à
« no » (adresse non trouvée)
line = line.split('INTEGER:') 8- La boucle « while » boucle tant que y a toujours
if macPointDecList in line[0]: de données à lire
print port %s" %(macSave, line[1]) Lecture d'une ligne et le mettre dans la variable
MAC_found = 'yes' « line »
Si plus de ligne à lire
Arrêt de la boucle « while »
Convertir line en un tableau qui contient forcement
deux colonnes(line[0] et line[1]) car la ligne est de
la forme suivante:
1.3.6.1.2.1.17.4.3.1.2.macPointDecList = INTEGER:
N° du port et comme le « «Split » appliqué est le
mot « «INTEGER: », on aura donc le port de
l'adresse mac donnée dans « line[1] ».

La technique ici consiste non pas à utiliser « snmpwalk » pour trouver le port avec une
commande de telle que: « snmpwalk -v 2c -c asr 192.168.195.11
1.3.6.1.2.1.17.4.3.1.2.macPointDecList » puis récupère le port ce qui est plus rapide et encore
plus simple à programmer le script car là c'est la commande « snmpwalk » qui accède
directement à ce « OID » mais notre technique permet en plus de ça de vérifier la présence
de l'adresse mac dan la table avec un test puis d'afficher le résultat. EN sortie elle génère trois
type de fichier « html » , « txt » et « xml ».

• def __all_Print(self):
Cette fonction permet d'afficher toutes les adresse mac et les ports de connexion sur le
commutateur(utilisée par l'option « -showall »)

• def __make_html(self, agent, oid):


Cette fonction génère un fichier de type html qui contient la date et l'heure de création
et des informations de base sur le commutateur et une table contenant les adresses mac des
machines et les ports de connexion su le commutateur

• def __make_txt(self, agent, oid):


Cette fonction génère un fichier de type texte qui contient la date et l'heure de création
ainsi que les adresses mac des machines et les ports de connexion su le commutateur

• def __make_xml(self, agent, oid):


Cette fonction génère un fichier de type xml qui contient la date et l'heure de création
et les balises suivantes

<SNMPQUERY>
<SNMPAGENT agent="adresse IP du commutateur">
<MACADDRESS>adresse MAC de la machine</MACADDRESS>
<MACPORT>port sur le commutateur</MACPORT>
</SNMPAGENT>
</SNMPQUERY>

Ce format de fichier peut être très utile dans le cas où on a plusieurs commutateurs et
on voulait voir les postes connectés sur chaque commutateur ou encore un format d'échange
de données. Cela nous permettra dans différents cas d'appliquer une analyse de texte, en effet
ce format est supporté par la plupart des langages de programmation modernes et comme ce
fichier est parsable, la récupération automatique des adresses mac des machines connectées
aux commutateurs et les ports associes sera possible.

• def __colon_Chooser(self, fileParse, separator, colonNumber):


Cette fonction prend en entrées un fichier « fileParse » à analyser. Elle consiste à
afficher une colonne « colonNumber » en appliquant un séparateur « separator ». Cette
fonction est prévue pour la deuxième partie du TP non traitée dans ce script.

• def __help_use(self):
Cette fonction montre l'aide en cas de faute

• if __name__ == '__main__':
Lancement du script

➢ SNMPWalkTable(snmp_command='snmpwalk', community='', agent='',


oid='system', sep='~'):
Cette instruction permet de générer le fichier d'entête de fichier « html »
contenant les informations de base du commutateur

➢ SNMPWalkTable(snmp_command='snmpwalk', community='', agent='',


oid='1.3.6.1.2.1.17.4.3.1.2', sep='~'):
Cette instruction permet d'accéder à la table qui contient les ports de
commutateur
➢ snmp_command : ce paramètre permet de choisir entre « snmpwalk » ou
« snmptable »
➢ community: permet de choisir la communauté
➢ Ces deux paramètres sont vides parce que la commande de lancement de script
prend leurs valeurs en entrée.

Exemple de commande:

• Recherche de port d'une adresse MAC donnée et génération de trois type de fichier
« html », « txt » et « xml » :
./mac_snmp.py -agent 192.168.195.11 -community asr -mac 0:c:29:a2:bc:13

• Génération de toute les informations sur toutes les machines et leur ports sur le
commutateur sous différents formats « html », « txt » ou « xml »
./mac_snmp.py -agent 192.168.195.11 -community asr -all -html
./mac_snmp.py -agent 192.168.195.11 -community asr -all -txt
./mac_snmp.py -agent 192.168.195.11 -community asr -all -xml

Cette commande ne renvoie les résultats souhaités

• Affichage de toute les adresses MAC des machines sur le commutateur et leurs
adresses IP associées:
./mac_snmp.py -agent 192.168.195.11 -community asr -showall

Note:
Le script python a réutilisé des fonctions déjà existantes dans le script réalisé dans le cours de « Administration plate
forme hétérogène » avec Monsieur Yves LEGRANDGERARD