用于检查网络的Perl脚本

时间:2016-02-16 15:39:02

标签: mysql perl unix

我是Perl的新手,为了练习我正在编写一个简单的perl脚本来检查我的家庭网络是否有可用的ip地址,并检查他们的mac地址,供应商和打开的端口。 我想把所有那些信息都放在mysql db中。 这是我的代码:

#!/usr/local/bin/perl
use strict;
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";
        }
}

如果我运行脚本,我将收到类似的内容:

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 

我的问题是,我似乎没有找到答案如何将所有信息($ host,$ mac,$ vendor,$ port)组合并将其放入数据库中,如果我们将$ port变量放入@array它将具有与其他数组不同的大小。

我的数据库结构如下:

+----+------------+-------------------+--------------+-----------------+---------------------+
| 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 |
+----+------------+-------------------+--------------+-----------------+---------------------+

这是导入的信息,没有打开端口的信息。

2 个答案:

答案 0 :(得分:1)

Your database is not normalized。您有一个基本的1:N关系,其中每行可以有零个或多个opened_ports

正确的处理方法是创建第二个表,每id个N行。它看起来像这样:

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

然后从主表中删除opened_ports列,并通过id链接它们。

在Perl程序中,您现在需要执行两次插入操作。第一个将用于大表,它也将创建您的(可能是auto_increment)id。你可以通过拨打$dbh->last_insert_id来获取它。之后,使用它在保存端口的小型表上执行后续的第二个插入语句(或组合的语句)。

答案 1 :(得分:0)

在初始打印语句print "$mac $vendor ";下面,您知道此时的mac供应商主机和日期,因此prepare一个插入语句,其中包含占位符(?)的端口号

然后在打印端口号的行处添加一个执行语句,其中端口位于占位符位置

要进行报告,请使用这样的模式

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

这是基于上述示例的测试数据

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');

这是一个根据需要输出的查询

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