use strict;
use warnings;
+
#use diagnostics; #uncomment this line for more details when encountering warnings
use Net::OpenSSH;
use FileHandle;
use Getopt::Long qw(:config no_ignore_case bundling);
-my ($host, $help, $usage, $capabilities, $login, $password, $kidpid, $hello_message);
-
+my ( $host, $help, $usage, $capabilities, $login, $password, $kidpid,
+ $hello_message );
-GetOptions (
- "h|help" =>\$help,
- "C|capabilities=s"=>\$capabilities
+GetOptions(
+ "h|help" => \$help,
+ "C|capabilities=s" => \$capabilities
);
$usage = "
USAGE: netconf_terminal.pl [-h|--help] [-C|--capabilities <custom_hello_file.xml>] <[login[:password]@]host[:port]> [login] [password]
exit(0);
}
-unless (@ARGV >= 1) {
+unless ( @ARGV >= 1 ) {
print $usage;
exit(0);
}
-($host, $login, $password) = @ARGV;
+( $host, $login, $password ) = @ARGV;
#netconf default port is no 22 but 830
-if ($host !~ /:[0-9]+$/) {
- $host.=':830';
+if ( $host !~ /:[0-9]+$/ ) {
+ $host .= ':830';
}
-my $connection_string=$host;
+my $connection_string = $host;
if ($password) {
- $connection_string=$login.":".$password."@".$connection_string;
-} elsif ($login) {
- $connection_string=$login."@".$connection_string;
+ $connection_string = $login . ":" . $password . "@" . $connection_string;
+}
+elsif ($login) {
+ $connection_string = $login . "@" . $connection_string;
}
#retrieving hello custom file if any
-if (defined ($capabilities)) {
- open(CAPABILITIES,'<',$capabilities) or die ("can not open $capabilities") ;
+if ( defined($capabilities) ) {
+ open( CAPABILITIES, '<', $capabilities )
+ or die("can not open $capabilities");
while (<CAPABILITIES>) {
$hello_message .= $_;
}
- chop $hello_message; # removing EOF
- $hello_message.="\n]]>]]>\n";
+ chop $hello_message; # removing EOF
+ $hello_message .= "\n]]>]]>\n";
close(CAPABILITIES);
}
+
#otherwise using a basic hello message
#EXI extension is not advertised by default since difficult to handle manually
-else{
- $hello_message='<?xml version="1.0" encoding="utf-8"?>
+else {
+ $hello_message = '<?xml version="1.0" encoding="utf-8"?>
<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<capabilities>
<capability>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04</capability>
<capability>urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&revision=2013-07-15</capability>
</capabilities>
</hello>';
- $hello_message.="\n]]>]]>\n";
+ $hello_message .= "\n]]>]]>\n";
}
+print STDERR "connecting to " . $connection_string . "\n";
-print STDERR "connecting to ".$connection_string."\n";
-
-my $ssh_handle= Net::OpenSSH->new($connection_string,
- master_opts => [-o => 'StrictHostKeyChecking=no'],
- timeout => 500, kill_ssh_on_timeout => 500);
+my $ssh_handle = Net::OpenSSH->new(
+ $connection_string,
+ master_opts => [ -o => 'StrictHostKeyChecking=no' ],
+ timeout => 500,
+ kill_ssh_on_timeout => 500
+);
#netconf requires a specific socket
-my ($ssh_subsocket, $pid) = $ssh_handle->open2socket({ssh_opts => '-s'}, 'netconf');
+my ( $ssh_subsocket, $pid ) =
+ $ssh_handle->open2socket( { ssh_opts => '-s' }, 'netconf' );
die "can't establish connection: exiting\n" unless defined($ssh_subsocket);
print STDERR "[Connected]\n";
# split the program into two processes, identical twins
-die "can't fork: $!" unless defined($kidpid = fork());
-
+die "can't fork: $!" unless defined( $kidpid = fork() );
# the if{} block runs only in the parent process (terminal output)
-if (!$kidpid) {
+if ( !$kidpid ) {
- $|=1;
+ $| = 1;
# copy the socket to standard output
my $buf;
my $nread;
- #while (<$ssh_subsocket>) {
- #buffer seems not totally flushed when using the syntax above (nor when using autoflush)
- while ($nread = sysread($ssh_subsocket,$buf,150)) {
+
+#while (<$ssh_subsocket>) {
+#buffer seems not totally flushed when using the syntax above (nor when using autoflush)
+ while ( $nread = sysread( $ssh_subsocket, $buf, 150 ) ) {
print $buf;
$ssh_subsocket->flush();
- };
+ }
print;
- kill("TERM", $kidpid); # send SIGTERM to child
+ kill( "TERM", $kidpid ); # send SIGTERM to child
}
+
# the else{} block runs only in the child process (terminal input)
else {
- $ssh_subsocket->autoflush(1);
- sleep 1; # wait needed for ensuring STDOUT buffer is not melt
+ $ssh_subsocket->autoflush(1);
+ sleep 1; # wait needed for ensuring STDOUT buffer is not melt
- if (defined ($hello_message)) {
- print $ssh_subsocket $hello_message;
- sleep 1;
- }
+ if ( defined($hello_message) ) {
+ print $ssh_subsocket $hello_message;
+ sleep 1;
+ }
- while (defined (my $line = <STDIN>)) {
- print $ssh_subsocket $line;
- }
+ while ( defined( my $line = <STDIN> ) ) {
+ print $ssh_subsocket $line;
+ }
}
sleep 2;
-kill("TERM", $kidpid); # send SIGTERM to child
+kill( "TERM", $kidpid ); # send SIGTERM to child
exit;