package nmap;

use warnings;
use strict;

use XML::Simple;
use Data::Dump qw/dump/;
use store;

use client;

sub scan {
	my $what = shift;

	my $path = $what;
	$path =~ s{[^\w\d\.]+}{_}g;
	$path = "/tmp/nmap.$path";

	warn "# scan $what";

	unlink $path if -f $path;

	system("nmap -O -oX $path $what");

	my $nmap = XMLin(
		"$path",
		KeyAttr => { address => 'addrtype' },
		ForceArray => [ 'host', 'address', 'osmatch', 'port' ],
	);

	store::audit( $what, $nmap );

	my $count = 0;

	my $port_name = {
		16992 => 'amt',
		4445  => 'asterisk',
		7777  => 'pxelator',
	};

	while ( my $host = shift @{ $nmap->{host} } ) {

		warn '# host ',dump( $host );

		my $ip  = $host->{address}->{ipv4}->{addr} || die "ipv4";

		if ( my $mac = $host->{address}->{mac}->{addr} ) {
			print "$ip\t$mac\n";
			client::save_ip_mac( $ip, $mac );
		}

		if ( my $os = $host->{os}->{osmatch}->[0]->{name} ) {
			client::conf( $ip, 'os' => $os );
		}

		my @ports = map { [ $_->{portid}, $_->{protocol}, $port_name->{$_->{portid}} || $_->{service}->{name} ] } @{ $host->{ports}->{port} };
		client::conf( $ip, 'ports' => join("\n", map { join("\t", @$_) } @ports) ) if @ports;

		$count++;
	}

	warn "# finish $count hosts";

	return $count;
}

1;
