LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Need script to monitor port for active, then send command (https://www.linuxquestions.org/questions/linux-newbie-8/need-script-to-monitor-port-for-active-then-send-command-798523/)

bulgin 03-28-2010 09:43 PM

Need script to monitor port for active, then send command
 
I need a script that would continuously monitor one port and when it is active (not listening or waiting) execute a series of commands to standard output.

I am familiar with netstat but am not good with scripting so I could use some help.

Thanks.

troop 03-28-2010 10:12 PM

My very old script on perl
Code:

#!/usr/bin/perl -w
use Socket;

#net - netstat
#tcp - socket
#udp - deprecated, don't work
my %serv=(8031=>'net', 8041=>'net',8051=>'net',8000=>'net');

sub restart {
    my ($port)=@_;
    if($port eq 8031) {system("/home/kernel/run_vlc_yamal start");}
    if($port eq 8041) {system("/home/kernel/run_vlc_eam22 start");}
    if($port eq 8051) {system("/home/kernel/run_vlc_yamal_c start");}
    if($port eq 8000) {system("rc-config restart icecast");}
    if($port eq 9001) {system("/home/kernel/run_flv2");}
}

sub check {
    my ($port,$prot,$du)=@_;
    if($prot ne 'net')
    {
        if($prot eq 'tcp') {socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp'));}
        else {socket(SOCK, PF_INET, SOCK_DGRAM, getprotobyname('udp'));}
        my $paddr = sockaddr_in($port, inet_aton("127.0.0.1"));

        $con=0;
        if($prot eq 'udp')
        {
            send(SOCK, 0, 0, $paddr);
            eval {
                local $SIG{ALRM} = sub { die "alarm time out" };
                alarm 5;
                recv(SOCK, $con, 4, 0);
                alarm 0;
                1;
            } or $con=0;
        }
        else
        {
            $con=connect(SOCK, $paddr);
        }
        close SOCK;
    }
    else
    {
        $con=0;
        open(GREP,"-|") || exec "netstat -ln|grep .".$port;
        while (<GREP>){
            if($_=~/.$port /){$con++;}
        }
        close GREP;
    }
    if($port eq 67 && !$con && !$du){
        sleep(10);
        $con=check($port,$prot,$du+1);
    }
    if(!$con)
    {
        restart($port);
    }
    return $con;
}

my %work;
open (F1,"</home/kernel/sock.log");
while(<F1>)
{
    chomp;
    my @F=split / /;
    $work[$F[0]]=$F[1];
}
close(F1);
open (F1,">/home/kernel/sock.log");
while(($port,$prot) = each(%serv))
{
    $con=check($port,$prot,0);
    if($con){
        print F1 "$port 1\n";
        if($work[$port] eq "0"){
            system("/usr/bin/snmptrap -v 1 -c public $host .1.1 `hostname` 51 0 '' .1 s '$port up'");
        }
    }
    else {
        print F1 "$port 0\n";
        if($work[$port] eq "1"){
            system("/usr/bin/snmptrap -v 1 -c public $host .1.1 `hostname` 51 0 '' .1 s '$port down'");
        }
    }
   

close(F1);


bulgin 03-29-2010 11:36 PM

Thanks Troop. Do you think you could provide me with the littlest of notations, like what each section does so I don't blow out my server? It looks like this is checking to see if a service is up and if not, restart it, but I cannot be sure. I only need to check one port number and see if it's active, if so, execute a script.

troop 03-30-2010 04:57 AM

You should change
Code:

my %serv=(8031=>'net', 8041=>'net',8051=>'net',8000=>'net');

sub restart {
    my ($port)=@_;
    if($port eq 8031) {system("/home/kernel/run_vlc_yamal start");}
    if($port eq 8041) {system("/home/kernel/run_vlc_eam22 start");}
    if($port eq 8051) {system("/home/kernel/run_vlc_yamal_c start");}
    if($port eq 8000) {system("rc-config restart icecast");}
    if($port eq 9001) {system("/home/kernel/run_flv2");}
}
...
    if(!$con)
    {
        restart($port);
    }

to
Code:

my %serv=(your_port=>'net');

sub restart {
    my ($port)=@_;
    if($port eq your_port) {system("your_command");}
}
...
    if($con) { restart($port); }

if a service on port your_port is active then execute your_command.

or you can just simplify to
Code:

#!/usr/bin/perl -w

my $port=your_port;
$con=0;
open(GREP,"-|") || exec "netstat -ln|grep .".$port;
while (<GREP>){
  if($_=~/.$port /){$con++;}
}
close GREP;
if($con) { execute your command } #if port is up


bulgin 03-30-2010 10:34 AM

thank you Troop.

When I run it as:

#!/usr/bin/perl -w

my $port=21;
$con=0;
open(GREP,"-|") || exec "netstat -ln|grep .".$port;
while (<GREP>){
if($_=~/.$port /){$con++;}
}
close GREP;
if($con) { print "hello world 21 is in use!" } #if port is up

I receive the error:
Use of uninitialized value $_ in pattern match (m//) at ./check.pl line 7.

troop 03-30-2010 11:31 PM

Quote:

Use of uninitialized value $_ in pattern match (m//) at ./check.pl line 7.
it's just a warning so code is running

Code:

# cat test.pl
#!/usr/bin/perl -w

my $port=21;
my $con=0;
open(GREP,"-|") || exec "netstat -ln|grep .".$port;
while (<GREP>){
if(defined $_ && $_=~/.$port /){$con++;}
}
close GREP;
if($con) { print "hello world 21 is in use!"; }

# ./test.pl
hello world 21 is in use!
# killall vsftpd
# ./test.pl
#


bulgin 04-01-2010 09:42 PM

Thank you so much for your help, Troop. I think that'll do it!

bulgin 04-01-2010 10:31 PM

I may have spoken too soon. I startup my tftpd and see that port 69 is listening. I run this script:

#!/usr/bin/perl -w

my $port=69;
my $con=0;
open(GREP,"-|") || exec "netstat -ln|grep .".$port;
while (<GREP>){
if(defined $_ && $_=~/.$port /){$con++;}
}
close GREP;
if($con) { print "hello world 69 is in use!"; }

I then tftp into the server and GET a file.

The script is still just sitting there, nothing happens

bulgin 04-01-2010 10:45 PM

I think I may have spoken too soon.

I fire up the tftpd daemon on port 69, then run the script indicating my $port=69;

Then I tftp and GET a file, and the script just sits there... nothing happens.

Thanks.

troop 04-02-2010 01:26 AM

post output
Code:

netstat -ln|grep :69

bulgin 04-02-2010 09:01 AM

netstat -ln|grep :69

udp 0 0 0.0.0.0:69 0.0.0.0:*

Thanks for your help, Troop. I really appreciate it!

troop 04-04-2010 02:52 AM

strange
Code:

# cat test.pl
#!/usr/bin/perl -w
my $port=69;
my $con=0;
#open(GREP,"-|") || exec "netstat -ln|grep :".$port;
open(GREP,"-|") || exec "echo 'udp 0 0 0.0.0.0:69 0.0.0.0:*'";
while (<GREP>){
if($_=~/:$port /){$con++;}
}
close GREP;
if($con) { print "hello world 69 is in use!"; }
# ./1.pl
hello world 69 is in use!

Your perl works differently?
try
Code:

# cat test.sh
#!/bin/sh
PORT=69;
CON=`netstat -ln|grep -c :$PORT`
if [ $CON -gt 0 ]; then
    echo "$PORT is in use";
fi


bulgin 04-05-2010 04:58 PM

Thank you! the following does work:

#!/usr/bin/perl -w
my $port=69;
my $con=0;
open(GREP,"-|") || exec "netstat -ln|grep :".$port;
while (<GREP>){
if($_=~/:$port /){$con++;}
}
close GREP;
if($con) { print "hello world 69 is in use!"; }

For my own education can you tell me what $con does, is about? I'm trying to learn. I've got the rest of it.

chrism01 04-05-2010 06:36 PM

$con counts cxns. Set to zero initially, (= false in an if() ). If $con gets incremented, a cxn was found, therefore its 'true' in the final if() .

bulgin 04-06-2010 10:12 PM

Now using a variation of what works I tried, using ngrep, but it doesn't work.:

#!/usr/bin/perl -w
my $port=69;
my $con=0;
open(NGREP,"-|") || exec "ngrep|grep :".$port;
while (<NGREP>){
if($_=~/:$port /){$con++;}
}
close NGREP;
if($con) { print "Alert! Transfer on port 69!"; }


if I:
ngrep | grep 69

and then GET a file with tftp

I see output so I know ngrep with grep is working....


All times are GMT -5. The time now is 01:50 AM.