#!/usr/bin/perl
#
# bin/tcpscan.saint
# Report TCP services (banners where possible).
#
require 'config/saint.cf';
require 'config/paths.pl';
require 'perl/misc.pl';
require 'perllib/getopts.pl';

print "BEGIN\n";
$usage = "usage $0 [-v] ports target";
 
&Getopts("v") || die $usage;
die $usage unless ($#ARGV <= 2);

($services = $ARGV[0]) =~ tr /,/ /;
$target = $ARGV[1];
if ($ARGV[2] =~ "FW") {
$firewall_flag=1;
}
if ($ARGV[2] =~ "PLUS") {
  $input_tcp_scan = 'USER saint\\r\\nNICK q\\r\\nQUIT\\r\\n\\r\\n';
} else {
  $input_tcp_scan = 'QUIT\\r\\n\\r\\n';
}
$status = "a";

$| = 1; 

open(SERVICES, $SERVICES) || die "$0: cannot open $SERVICES: $!\n";
while (<SERVICES>) {
	$service_name{$2} = $1 if /(\S+)\s+([0-9]+)\/tcp/;
}
close(SERVICES);
if ($firewall_flag) {
  $command = "$TCP_SCAN -f $fw_timeout -l $fw_loadlimit -bs \"$input_tcp_scan\" $target $services";
} else { 
  $command = "$TCP_SCAN -bs \"$input_tcp_scan\" $target $services";
}
print "$command\n" if $opt_v;

open(TCP_SCAN, "$command|")
	|| die "$0: cannot run $TCP_SCAN";

while(<TCP_SCAN>) {
	if (defined($opt_v)) {
	    print;
	}
	chop;
	($port, $port_service, $flag, $service_output) = split(/:/, $_, 4);
	$service = $service_name{$port};
	$service = "X-$1" if $port =~ /600(\d)/;
	$service = "X-$1" if $port =~ /60([1-9]\d)/;
	if ($flag =~ /t/ && $port != 23 && $service_output) {
		$service = "telnet on port $port";
		$text = "offers $service";
	} elsif ($service) {
		$text = "offers $service ($port:TCP)";
	} else { 
		$service = "$port:TCP"; 
		$text = "offers $service";
	}
	$service_output =~ y/|/?/;
	&saint_print();
}
