Script Perl pour vérifier le réseau

Je suis nouveau sur Perl et pour la pratique, j’écris un simple script perl pour vérifier les adresses IP disponibles sur mon réseau domestique et vérifier leur adresse Mac, leur fournisseur et les ports ouverts pour chacun d’eux. Toutes ces informations que je veux mettre dans mysql db. Voici mon code:

#!/usr/local/bin/perl use ssortingct; use warnings; use Net::Ping; use Net::ARP; use DBI; use IO::Socket::PortState qw(check_ports); require config; my $proto = 'tcp'; my @ports = (21,22,23,80,8080); my $address; my $ping_timeout = 1; my $host; for my $i (18..21) { $host = "10.20.1.$i"; my $timeout = 1; my $pinger = Net::Ping->new('icmp', $timeout); print "$host "; if ($pinger->ping($host)) { my $mac = Net::ARP::arp_lookup("em0","$host"); my $vendor = vendor_lookup($mac); $vendor=~ s/^\s+|\s+$//g; print "$mac $vendor "; foreach my $port (@ports) { my($section, $ping_timeout, %porthash); $porthash{$proto}{$port}{'name'} = $section; check_ports($host, $ping_timeout, \%porthash); my $open = $porthash{$proto}{$port}{'open'}; if ($open) { print "$port "; } } print "\n"; } } 

Si je lance le script, je recevrai quelque chose comme ça:

 10.20.1.18 38:ea:a7:6f:d9:05 Hewlett Packard 80 8080 10.20.1.19 fc:15:b4:31:77:76 Hewlett Packard 80 8080 10.20.1.20 e8:39:35:25:dd:36 Hewlett Packard 22 80 

Mon problème est que je ne trouve pas de réponse pour combiner toutes ces informations ($ host, $ mac, $ vendor, $ port) et les mettre dans la firebase database si nous mettons la variable $ port dans @array it aura une taille différente des autres tableaux.

Ma structure de firebase database ressemble à ça:

 +----+------------+-------------------+--------------+-----------------+---------------------+ | id | ip | mac | opened_ports | vendor | date | +----+------------+-------------------+--------------+-----------------+---------------------+ | 1 | 10.20.1.19 | fc:15:b4:31:77:76 | NULL | Hewlett Packard | 2016-02-15 15:50:19 | | 2 | 10.20.1.20 | e8:39:35:25:dd:36 | NULL | Hewlett Packard | 2016-02-15 15:50:19 | | 3 | 10.20.1.21 | 8c:dc:d4:5d:21:7b | NULL | Hewlett Packard | 2016-02-15 15:50:19 | | 4 | 10.20.1.18 | 38:ea:a7:6f:d9:05 | NULL | Hewlett Packard | 2016-02-15 16:02:09 | | 5 | 10.20.1.19 | fc:15:b4:31:77:76 | NULL | Hewlett Packard | 2016-02-15 16:02:09 | | 6 | 10.20.1.20 | e8:39:35:25:dd:36 | NULL | Hewlett Packard | 2016-02-15 16:02:10 | | 7 | 10.20.1.21 | 8c:dc:d4:5d:21:7b | NULL | Hewlett Packard | 2016-02-15 16:02:10 | +----+------------+-------------------+--------------+-----------------+---------------------+ 

Ceci est une information imscope sans les informations pour les ports ouverts.

Votre firebase database n’est pas normalisée . Vous avez une relation de base 1: N où chaque ligne peut avoir zéro ou plusieurs opened_ports .

La manière correcte de gérer cela est de créer une seconde table et d’avoir N lignes par id . Cela ressemblerait à ceci:

 +-------+--------------+ | id_fk | opened_ports | +-------+--------------+ | 1 | 22 | | 1 | 80 | | 3 | 22 | +-------+--------------+ 

Ensuite, vous supprimez la colonne opened_ports votre table principale et vous les liez via l’ id .

Dans votre programme Perl, vous devez maintenant faire deux insertions. Le premier sera pour la grande table, qui créera également votre id (probablement auto_increment). Vous pouvez récupérer cela en appelant $dbh->last_insert_id . Après cela, vous l’utilisez pour effectuer les deuxièmes instructions d’insertion suivantes (ou une instruction combinée) sur la petite table contenant les ports.

En-dessous de l’instruction d’ print "$mac $vendor "; initiale, print "$mac $vendor "; vous connaissez l’hôte du fournisseur mac et la date à ce stade, alors prepare une instruction d’insertion avec un espace réservé (?) pour le numéro de port

Ensuite, à la ligne pour imprimer le numéro de port, ajoutez une instruction d’exécution avec le port dans la position d’espace réservé

Pour faire le rapport, utilisez un schéma comme celui-ci

 create table scan ( id int, ip char(15), mac char(20), opened_ports int, vendor varchar(255), d datetime ); 

voici des données de test basées sur vos exemples ci-dessus

 INSERT INTO SCAN (Id,IP,MAC,OPENED_PORTS,VENDOR,D) VALUES(1,'10.20.1.19','fc:15:b4:31:77:76',25,'Hewlett Packard','2016-02-15 15:50:19'); INSERT INTO SCAN (Id,IP,MAC,OPENED_PORTS,VENDOR,D) VALUES(2,'10.20.1.20','e8:39:35:25:dd:36',80,'Hewlett Packard','2016-02-15 15:50:19'); INSERT INTO SCAN (Id,IP,MAC,OPENED_PORTS,VENDOR,D) VALUES(3,'10.20.1.21','8c:dc:d4:5d:21:7b',8080,'Hewlett Packard','2016-02-15 15:50:19'); INSERT INTO SCAN (Id,IP,MAC,OPENED_PORTS,VENDOR,D) VALUES(4,'10.20.1.18','38:ea:a7:6f:d9:05',137,'Hewlett Packard','2016-02-15 16:02:09'); INSERT INTO SCAN (Id,IP,MAC,OPENED_PORTS,VENDOR,D) VALUES(5,'10.20.1.19','fc:15:b4:31:77:76',443,'Hewlett Packard','2016-02-15 16:02:09'); INSERT INTO SCAN (Id,IP,MAC,OPENED_PORTS,VENDOR,D) VALUES(6,'10.20.1.20','e8:39:35:25:dd:36',8080,'Hewlett Packard','2016-02-15 16:02:10'); INSERT INTO SCAN (Id,IP,MAC,OPENED_PORTS,VENDOR,D) VALUES(7,'10.20.1.21','8c:dc:d4:5d:21:7b',22,'Hewlett Packard','2016-02-15 16:02:10'); 

et voici une requête qui rend la sortie nécessaire

 select ip,mac,GROUP_CONCAT(opened_ports) as port,vendor, d from scan group by ip;