report error without nmap output
[pxelator] / lib / PXElator / nmap.pm
1 package nmap;
2
3 use warnings;
4 use strict;
5
6 use XML::Simple;
7 use Data::Dump qw/dump/;
8 use store;
9
10 use client;
11
12 sub scan {
13         my $what = shift;
14
15         my $path = $what;
16         $path =~ s{[^\w\d\.]+}{_}g;
17         $path = "/tmp/nmap.$path";
18
19         warn "# scan $what";
20
21         unlink $path if -f $path;
22
23         system("nmap -O -oX $path $what");
24
25         if ( ! -e $path ) {
26                 warn "ERROR running nmap: $!";
27                 return;
28         }
29
30         my $nmap = XMLin(
31                 "$path",
32                 KeyAttr => { address => 'addrtype' },
33                 ForceArray => [ 'host', 'address', 'osmatch', 'port' ],
34         );
35
36         store::audit( $what, $nmap );
37
38         my $count = 0;
39
40         my $port_name = {
41                 16992 => 'amt',
42                 4445  => 'asterisk',
43                 7777  => 'pxelator',
44         };
45
46         while ( my $host = shift @{ $nmap->{host} } ) {
47
48                 warn '# host ',dump( $host );
49
50                 my $ip  = $host->{address}->{ipv4}->{addr} || die "ipv4";
51
52                 if ( my $mac = $host->{address}->{mac}->{addr} ) {
53                         print "$ip\t$mac\n";
54                         client::save_ip_mac( $ip, $mac );
55                 }
56
57                 if ( my $os = $host->{os}->{osmatch}->[0]->{name} ) {
58                         client::conf( $ip, 'os' => $os );
59                 }
60
61                 my @ports = map { [ $_->{portid}, $_->{protocol}, $port_name->{$_->{portid}} || $_->{service}->{name} ] } @{ $host->{ports}->{port} };
62                 client::conf( $ip, 'ports' => join("\n", map { join("\t", @$_) } @ports) ) if @ports;
63
64                 $count++;
65         }
66
67         warn "# finish $count hosts";
68
69         return $count;
70 }
71
72 1;