#!/usr/bin/perl -w
# lslan Version 0.2
# This script is free and comes with absoluetly no warranty


require 5.6.0;

use strict;
use Socket;

my $Version = "0.2";

#Test wheather a port is open
sub test_port # $server $port $service_name 
	{
	my $server = gethostbyname($_[0]);
	my $port = $_[1];
	my $service_name = $_[2];

	my $tmp_addr = sockaddr_in($port, $server);
	socket ( TMPSOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp')) or die "Socket ERROR :$!\n";
	if (connect ( TMPSOCK , $tmp_addr))
		{
		print " $service_name";
		}
	close ( TMPSOCK );
	}

sub print_help {
	print "\nlslan $Version\t2001 by Marcus Thiesen (marcus\@thiesenweb.de)\n";
	print "\nCommand line arguments:\n";
	print "\n\t-h\t\t--help\t\tprints this help!\n";
#	print "\t-c <file>\t--config <file>\tUses <file> as config file\n";
	print "\t-v\t\t--verbose\tshows what is beeing done\n";
	print "\t-d\t\t--debug\t\tfor debugging reasons\n";
	print "\nFiles:\n";
	print "\n\t\$HOME/.lslanrc\tYour personal config file.\n";
	print "\t/etc/lslanrc\tThe system wide config file.\n\n";
	print "If you have a personal config file the system wide file will not\n";
	print "be used.\n";
	print "\n\tHave a lot of fun!\n\n";
	exit 1;
}

my ($server, $port);

my $configfile = "";
my $verbose = 0;
my $DEBUG = 0;

# Command line parsing
foreach my $cmdlnparam (@ARGV)
	{
	if ($cmdlnparam =~ /-h/) {print_help; next;}
	if ($cmdlnparam =~ /-v/) {print "Verbose mode\n"; $verbose = 1; next;}
	if ($cmdlnparam =~ /-d/) {print "Debug mode\n"; $DEBUG = 1; next;}
	print "Error: Unknown parameter $cmdlnparam!\n";
	print_help;
	}

# Setting the right config file
if ( -e "$ENV{'HOME'}/.lslanrc" )
	{
	print "Using $ENV{'HOME'}/.lslanrc!\n" if ($DEBUG);
	$configfile = "$ENV{'HOME'}/.lslanrc";
	}
elsif ( -e "/etc/lslanrc" )
	{
	print "Using /etc/lslanrc!\n" if ($DEBUG);
	$configfile = "$ENV{'HOME'}/lslanrc";
	}
else  {
	print "Error: Can't find config file!\n";
	print_help;
	}



$server = 'localhost';
$port = 7741; 

my $proto = getprotobyname('tcp');

my $iaddr = inet_aton($server) or die "no host: $server\n";
my $paddr = sockaddr_in($port, $iaddr);

socket( SOCK , PF_INET, SOCK_STREAM, $proto ) or die "Socket ERROR: $!\n";
connect( SOCK, $paddr) or die "Connect ERROR, maybe LISa is not running: $!\n";
while (my $line = <SOCK>)
	{
	if ($line !~ /0 succeeded/)
		{
		if ( $line =~ /(\d+) (.+)\n/ ) 
			{
			my $current_server = $2;
			my $srv_addr = gethostbyname ($current_server);
			my $ip =  inet_ntoa($srv_addr);
			print "$current_server\t$ip\t[";

		# Config file
			my $inall = 0;
			my $nw_addres = "300.300.300";
			my $cnf_ip = "300.300.300.300";
			my $cnf_hostname = " ";
			open CONFIGFILE, $configfile or die "Can't open lslanrc: $!\n";
			while (my $cnfline = <CONFIGFILE>)
				{
				chomp $cnfline;
				if ($cnfline eq "") {next;}
				if ($cnfline !~ /^\#/)
					{
					if ($cnfline =~ /\[all\]/)
						{
						$inall = 1;
						}
					elsif ($cnfline =~ /\[\d+\.\d+\.\d+\.(\d+)\]/)
						{
						$inall = 0;
						$cnf_hostname = " ";
						$cnf_ip = "300.300.300.300";
						$nw_addres = "300.300.300";
						if ($1 == 0)
							{
							$cnfline =~  /\[(\d+\.\d+\.\d+)\.\d+\]/;
							$nw_addres = $1;
							}
						else
							{
							$cnfline =~ /\[(.+)\]/;
							$cnf_ip = $1;
							}
						}
					elsif ($cnfline =~ /\[([\w\.\-]+)\]/)
						{
						$cnf_ip = "300.300.300.300";
						$nw_addres = "300.300.300";
						$inall = 0;
						$cnf_hostname = $1;
						}
					if (($inall) ||
					    ($cnf_ip eq $ip) ||
					    ($cnf_hostname eq $current_server) ||
					    ($ip =~ /$nw_addres/))
						{
						if ($cnfline =~ /(\w+):(\d+)/)	{test_port($current_server,$2,$1);}
						}
					print "\n-------------------------------------\n" if ($DEBUG);
					print "Line:\t$cnfline\n" if ($DEBUG);
					print "\$inall:\t$inall\n" if ($DEBUG);
					print "\$nw_addres:\t$nw_addres\n" if ($DEBUG);
					print "\$cnf_ip:\t$cnf_ip\n" if ($DEBUG);
					print "\$cnf_hostname:\t$cnf_hostname\n" if ($DEBUG);
					print "-------------------------------------\n" if ($DEBUG);
					}
				}
		
			print " ]\n";
			close CONFIGFILE;

			}
		}
	}

close ( SOCK ) or die "Couldn't close socket to LISa: $!\n";
exit;

