#
# Copyright (c) 2002, 2009, Oracle and/or its affiliates.All rights reserved. 
#
#    NAME
#      openports.pl
#
#    DESCRIPTION
#      List of all open ports
#
#    MODIFIED   (MM/DD/YY)
#      manosing  03/11/09 - bug 8311130
#      dkjain    05/11/05 - 
#      rmadampa  09/03/04 - Mac OS X Porting 
#      hmulling  03/16/04 - replace uname with perl command for windows 
#      hmulling  03/16/04 - replace uname with perl command for windows 
#      mbhoopat  03/10/04 - linux port 
#      hmulling  02/21/04 - prevent null values 
#      hmulling  09/24/03 - added windows nt support
#      eujang    09/04/03 - eujang_esm_init_no_intgr 
#      leo  	 07/30/03 - created
#
#
#
# Summary
#
#       Print out UDP or TCP ports which are open (idle or listen) and not just local
#
# Implementation
#
#       1. Go through netsat -an narrowed for idle or listen and non-localhost
#          collecting open ports in the lookup table %openports
#          Lookup table %openports : <port number> => <number of instances>
#       3. Print %openports : "em_result=port=<port number>"


$ENV{PATH} = "$ENV{PATH}:/usr/bin:/usr/sbin:/usr/ucb:/bin";
#require "$ENV{EMDROOT}/sysman/admin/scripts/esa_config.pl";
my $targetType = "host" ;
my $limit = 0 ;
my $maxCount ;
my $all = $ENV{MAXCOUNT};
if($all != -1){
  $maxCount = $all ;
}

chomp($os = $^O);
if (($os ne "MSWin32") && ($os ne "MSWin64")) 
{
	chomp($os = `uname -s`);
}


@NETSTAT = `netstat -an `;
LINE: for $userline (@NETSTAT) 
{
        if (index($userline, "127.0.0.1") >= 0) { next LINE; }

        if (index($userline, "LISTEN") < 0 && index($userline, "IDLE") < 0) { 
	    next LINE; 
        }

        # for unix  domain sockets $userline has LISTENING, skip those lines
        #unix  3      [ ]         STREAM     CONNECTED     30797360 /var/tmp/.oracle/sLISTENER_SCAN1
        # above line caused bug 8311130. 
        if ($os eq "Linux" && ((index($userline, "LISTENING") >= 0) || (index($userline, "unix")>=0))) {
	    next LINE; 
        }
#	print "NETSTAT: $userline\n";

	# $userline looks like on solaris:
	#	*.*                  *.*                0      0 24576      0 IDLE
	#	*.7000               *.*                0      0 24576      0 LISTEN
	#	*.3201               *.*                0      0 24576      0 LISTEN
	#	130.35.38.158.3101   *.*                0      0 24576      0 LISTEN
	#	*.*                  *.*                0      0 24576      0 IDLE
	# $userline looks like on windows:
	#	(udp|tcp) [0-9\.]*:port                  *.*                IDLE

	@points = split(/[\t\ ]+/, $userline);

        
	# window windows there is a : in the  line
	if (index($userline, ":") > 0) 
        {
            if ($os eq "Linux") {
	      $p1 = $points[3];
            } else {
	      $p1 = $points[2];  # windows
            }

	    @point = split(/:/, $p1);

	    $p = $point[$#point];	# last item within <numeric ip>:<port number>, i.e. port
	    $openports{$p} += 1;	# add <port> as a key to the lookup table
        } 
        else 
        {
	    if ($os eq "HP-UX" || $os eq "OSF1" || $os eq "AIX" || $os eq "Darwin") {
	        $p1 = $points[3];
            } else {
	        $i = index($userline, " ");
	        if ($i > 0)
	        {
		    $p1 = $points[0];
	        }
	        else
	        {
		    $p1 = $points[1];
	        }
            }
#    print "NETSTAT[1] : $i \"$p1\" of \"$userline\"\n";

	    if ($p1 ne "*\.*")
	    {
		    @point = split(/\.+/, $p1);

		    $pl = @point;
		    $p = $point[$pl - 1];	# last item within <numeric ip>.<port number>, i.e. port
		    $openports{$p} += 1;	# add <port> as a key to the lookup table
	    }
        }
}

sub numerically { $a <=> $b }
foreach $p (sort numerically keys (%openports)) 
{
    if ($p ne "")
    {

        if($all == -1){
	 print "em_result=port=$p\n";
        }
        else{
         if($limit >= $maxCount){
         last ;
         }
	 print "em_result=port=$p\n";
         $limit++;
        }
    }
}
