Perl script fails to open port number on modem fails - perl

I have a perl script to telnet to particular IP and port number. However, if i print the result after establishing connection, the port number is 23 (default). As a result, at commands triggered from script are not encouraged by modem.
Below is my script. Please advise.
Script:
#!/usr/bin/perl -w
use lib ("/u/dclement/lib/perl");
use Net::Telnet ();
$HOSTNAME = "192.168.xx.xx";
$HOSTPORT = "9998";
$conn = new Net::Telnet (Timeout => "1");
$conn->binmode(1); # don't translate CRLF
$conn->errmode("return"); # enable error trapping
$conn->telnetmode(0); # turn off telnet mode
$conn->dump_log("LOGFILE"); # output log file filehandle
$conn->output_record_separator("");
print "CONNECTING TO $HOSTNAME and $HOSTPORT\n";
# open connection to host $HOSTNAME and port $HOSTPORT
# and die if there is a problem
unless ($conn->open(Host => $HOSTNAME, Port => $HOSTPORT))
{
die "Error opening socket:: ".$conn->errmsg();
}
print "CONNECTED TO ".$conn->host().", PORT ".$conn->port()."\n";
OUTPUT
CONNECTING TO 192.168.xx.xx and 9998
CONNECTED TO 192.168.xx.xx, PORT 23

Can you try below code and see if any connectivity issue 9998 port:
$telnetOutput =telnet 192.168.xx.xx 9998;
print "\n telnet command output1: $telnetOutput \n";
$telnetOutput =telnet 192.168.xx.xx 23;
print "\n telnet command output2: $telnetOutput \n";

Related

Using telnet with pipe with backticks in perl

I am trying to test a specific server is up and running on a certain port so I am using
$result = `echo exit | telnet 127.0.0.1 9443`; print $result;
Here I am using localhost for privacy issues
The expected behavior is that it should print "...Could not open connection to the host, on port 9443: Connect failed", this way I know that the server is not running. but it prints an empty string
Any help on this
The failure message is printed to STDERR, while backticks return only what goes to STDOUT.
You can redirect the STDERR stream to the STDOUT stream
$result = `echo exit | telnet 127.0.0.1 9443 2>&1`;
See I/O redirection.
There are more rounded ways to do this, using various forms of open. See it in perlfaq8. There are also various modules for this. The Capture::Tiny makes it rather easy.
use warnings 'all';
use strict;
use Capture::Tiny qw(capture);
my $cmd = 'echo exit | telnet 127.0.0.1 9443';
my ($stdout, $stderr) = capture {
system ( $cmd );
};
print "STDOUT: $stdout";
print "STDERR: $stderr";
This prints for me
STDOUT: Trying 127.0.0.1...
STDERR: telnet: connect to address 127.0.0.1: Connection refused
The module has many more capabilities. From the docs
Capture::Tiny provides a simple, portable way to capture almost anything sent to STDOUT or STDERR, regardless of whether it comes from Perl, from XS code or from an external program.

Perl socket, HP comware router

I'm trying to create a script in Perl that does the following
On a Windows 2008 R2 server, connects to a local OpenWRT router.
Send some commands to the router and save the output (interface brief)on a varaible
Edit the content of the variable (to keep the IP only)
Send the variable again to the router withinin another command
I created a socket but i dont seem to get any luck sending commands to the router. I'm not even sure if I'm logging in.
Here is my code:
use IO::Socket;
use strinct;
use warnings;
$iaddr = gethostbyname("192.168.1.237");
$ssh_port = 22;
$sin = sockaddr_in($ssh_port, $iaddr);
socket(DEV, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
connect(DEV, $sin) || die "Can't connect to EN4000: $!\n";
print DEV "user\n";
print DEV "password\n";
print DEV "echo test >> /etc/config/networkTest \n";
I run it, check the file /etc/config/networkTest but no modification is made
Have a look at Net::SSH::W32Perl
Here's a quick example;
#!/usr/bin/env perl
use strict;
use warnings;
use Net::SSH::W32Perl;
my $host='example.com';
my $user='john';
my $pass="pass";
# Connect
my $ssh = Net::SSH::W32Perl->new($host);
$ssh->login($user, $pass);
# Run command
my $cmd = q(echo test >> /etc/config/networkTest);
my($stdout, $stderr, $exit) = $ssh->cmd($cmd);

Perl read line string without trailing newline

Very new to perl and have been stuck for quite awhile on this.
If I change the variable from READSTDIN to google.com, it says google.com is online as it should. If I use the STDIN and input google.com and print $host it prints google.com, however in the ping it doesn't work.
Sample output:
perl perl.pl
What is the website that is offline or displaying an error?google.com
Warning: google.com
appears to be down or icmp packets are blocked by their server
Code:
use strict;
use warnings;
use Net::Ping;
#optionally specify a timeout in seconds (Defaults to 5 if not set)
my $timeout = 10;
# Create a new ping object
my $p = Net::Ping->new("icmp");
#Domain variable
print "What is the website that is offline or displaying an error?";
my $host = readline STDIN;
# perform the ping
if ( $p->ping( $host, $timeout ) ) {
print "Host $host is alive\n";
} else {
print "Warning: $host appears to be down or icmp packets are blocked by their server\n";
}
# close our ping handle
$p->close();
If I change the variable from READSTDIN to google.com, it says google.com is online as it should. If I use the STDIN and input google.com and print $host it prints google.com, however in the ping it doesn't work. I appreciate anyone who can help me at all!
Note the newline in your input:
perl perl.pl
What is the website that is offline or displaying an error?google.com
Warning: google.com <--- newline after google.com puts the rest of the output on the next line...
appears to be down or icmp packets are blocked by their server
You should be using chomp to remove the newline from your input:
chomp( my $host = readline STDIN );
Or more simply:
chomp( my $host = <STDIN> ); # same thing as above

Simple perl program failing to execute

Here is a sample that fails:
#!/usr/bin/perl -w
# client.pl
#----------------
use strict;
use Socket;
# initialize host and port
my $host = shift || 'localhost';
my $port = shift || 55555;
my $server = "10.126.142.22";
# create the socket, connect to the port
socket(SOCKET,PF_INET,SOCK_STREAM,(getprotobyname('tcp'))[2])
or die "Can't create a socket $!\n";
connect( SOCKET, pack( 'Sn4x8', AF_INET, $port, $server ))
or die "Can't connect to port $port! \n";
my $line;
while ($line = <SOCKET>) {
print "$line\n";
}
close SOCKET or die "close: $!";
with the error:
Argument "10.126.142.22" isn't numeric in pack at D:\send.pl line 16.
Can't connect to port 55555!
I am using this version of Perl:
This is perl, v5.10.1 built for MSWin32-x86-multi-thread
(with 2 registered patches, see perl -V for more detail)
Copyright 1987-2009, Larry Wall
Binary build 1006 [291086] provided by ActiveState http://www.ActiveState.com
Built Aug 24 2009 13:48:26
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
While I am running the netcat command on the server side. Telnet does work.
The problem is that the pack template Sn4x8 is in error — and shouldn't be used in the first place. Something like pack_sockaddr_in($port, inet_aton($server)) as documented in Socket would be more likely to work.
But ideally, you wouldn't use the low-level Socket code at all. Here's a nicer bit of code that does it using IO::Socket, which is also a core part of perl for the past 15 years:
use strict;
use IO::Socket::INET;
my $host = shift || 'localhost'; # What is this here for? It's not used
my $port = shift || 55555;
my $server = "10.126.142.22";
my $socket = IO::Socket::INET->new(
PeerAddr => $server,
PeerPort => $port,
Proto => 'tcp',
) or die "Can't connect to $server: $#";
while (my $line = <$socket>) {
print $line; # No need to add \n, it will already have one
}
close $socket or die "Close: $!";
Works like this for me:
connect( SOCKET, pack( 'S n a4 x8', AF_INET, $port, $server))
or die "Can't connect to port $port! \n";
I think your original script AF_INET is unicode or something. If you delete the A and write again it works.
This is the line that make the packing work:
connect( SOCKET, pack( 'SnC4x8', AF_INET, $port, split /\./,$server ))
or die "Can't connect to port $port! \n";

Whilst using Perl::FTP, What shall I put in the host field for connecting to a Local computer connected on the network

I am using the Net::FTP in perl to do some file transfers. when I run the following code :-
Are there any issues with using the IP address ? Am I correct in providing this in the host field ?
use strict;
use Net::FTP;
my $host = "10.77.69.124";
my $user = "administrator";
my $password = "Password";
my $f = Net::FTP->new($host, Debug =>0) or die "Can't open $host\n";
$f->login($user, $password) or die "Can't log $user in\n";
The code is not able to connect to the remote host. Why is this happening ? Shouldn't this work with the IP address provided in the $host ?
The constructor of Net::FTP allows you to pass a single scalar value or an array of hosts to try. The value of this field should be the same as the PeerAddr from IO::Socket::INET (either a hostname or an ip address).
Have a closer look at what is happening by specifying Debug. If you are behind a firewall or a NAT setup, you should probably also set Passive to a non-zero value and make sure to check if the constructor failed by printing out $#.
my $ftp = Net::FTP->new(Host=>$host, Debug=>1, Passive=>1) || die $#;
If the constructor succeeded, you might want to check if any of the other methods fail:
$ftp->login($user, $pass) || die $ftp->message;
$ftp->cwd($path) || die $ftp->message;
By the way: If you are unsure if you've used the correct host parameter, you can ask Net::FTP which host it tried to connect to:
print $ftp->host, "\n";
If this still doesn't work, please provide a detailed output of your application.
Hope this helps.
First be sure that you can reach the remote side:
From command line use telnet (available on linux and windows too, a it different in syntax)
telnet host 21
If you are not able to connect the from commandline, check for firewall rules or maybe your FTP server running on different port?
If you are able to connect try out login with plain FTP commands:
USER user#remote.host
PASS yourpassword
This will use ACTIVE ftp connection to the remote. This is the old way.
Nowadays most ftp server use PASSIVE ftp. To test try this command out (from linux commandline)
ftp -v -p host
In perl you could use passive mode this way:
my $f = Net::FTP->new($host, Debug =>1, Passive => 1) or die "Can't open $host\n";
I hope this will help you.