--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+<capabilities>
+<capability>http://org/openroadm/device?module=org-openroadm-device&revision=2017-02-06</capability>
+<capability>http://org/openroadm/rstp?module=org-openroadm-rstp&revision=2016-10-14</capability>
+<capability>http://org/openroadm/alarm?module=org-openroadm-alarm&revision=2016-10-14</capability>
+<capability>http://org/openroadm/service?module=org-openroadm-service&revision=2016-10-14</capability>
+<capability>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04</capability>
+<capability>http://org/openroadm/lldp?module=org-openroadm-lldp&revision=2016-10-14</capability>
+<capability>http://org/openroadm/common/service/types?module=org-openroadm-common-service-types&revision=2016-10-14</capability>
+<capability>http://org/openroadm/user-mgmt?module=org-openroadm-user-mgmt&revision=2016-10-14</capability>
+<capability>http://org/openroadm/layerRate?module=org-openroadm-layerRate&revision=2016-10-14</capability>
+<capability>urn:ietf:params:xml:ns:yang:ietf-netconf-notifications?module=ietf-netconf-notifications&revision=2012-02-06</capability>
+<capability>http://org/openroadm/port/types?module=org-openroadm-port-types&revision=2016-10-14</capability>
+<capability>urn:ietf:params:xml:ns:netconf:base:1.0?module=ietf-netconf&revision=2011-06-01</capability>
+<capability>http://org/openroadm/probableCause?module=org-openroadm-probable-cause&revision=2016-10-14</capability>
+<capability>http://org/openroadm/de/swdl?module=org-openroadm-swdl&revision=2016-10-14</capability>
+<capability>urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&revision=2013-07-15</capability>
+<capability>http://org/openroadm/interfaces?module=org-openroadm-interfaces&revision=2016-10-14</capability>
+<capability>http://org/openroadm/otn-otu-interfaces?module=org-openroadm-otn-otu-interfaces&revision=2016-10-14</capability>
+<capability>http://org/openroadm/optical-multiplex-interfaces?module=org-openroadm-optical-multiplex-interfaces&revision=2016-10-14</capability>
+<capability>http://org/openroadm/common-types?module=org-openroadm-common-types&revision=2016-10-14</capability>
+<capability>http://org/openroadm/topology?module=org-openroadm-topology&revision=2016-10-14</capability>
+<capability>urn:ietf:params:netconf:capability:candidate:1.0</capability>
+<capability>http://org/openroadm/resource/types?module=org-openroadm-resource-types&revision=2016-10-14</capability>
+<capability>http://org/openroadm/pm-types?module=org-openroadm-pm-types&revision=2016-10-14</capability>
+<capability>http://org/openroadm/wavelength-map?module=org-openroadm-wavelength-map&revision=2016-10-14</capability>
+<capability>http://org/openroadm/maintenance-testsignal?module=org-openroadm-maintenance-testsignal&revision=2016-10-14</capability>
+<capability>http://org/openroadm/otn-odu-interfaces?module=org-openroadm-otn-odu-interfaces&revision=2016-10-14</capability>
+<capability>http://org/openroadm/optical-transport-interfaces?module=org-openroadm-optical-transport-interfaces&revision=2016-10-14</capability>
+<capability>http://org/openroadm/optical-channel-interfaces?module=org-openroadm-optical-channel-interfaces&revision=2016-10-14</capability>
+<capability>http://org/openroadm/fwdl?module=org-openroadm-fwdl&revision=2016-10-14</capability>
+<capability>http://org/openroadm/syslog?module=org-openroadm-syslog&revision=2016-10-14</capability>
+<capability>http://org/openroadm/routing/constrains?module=org-openroadm-routing-constraints&revision=2016-10-14</capability>
+<capability>http://org/openroadm/maintenance?module=org-openroadm-maintenance&revision=2016-10-14</capability>
+<capability>urn:ietf:params:xml:ns:netconf:notification:1.0?module=notifications&revision=2008-07-14</capability>
+<capability>http://org/openroadm/de/device-resource-types?module=org-openroadm-device-resource-types&revision=2016-10-14</capability>
+<capability>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring-extension?module=ietf-netconf-monitoring-extension&revision=2013-12-10</capability>
+<capability>http://org/openroadm/pm?module=org-openroadm-pm&revision=2016-10-14</capability>
+<capability>http://org/openroadm/tca?module=org-openroadm-tca&revision=2016-10-14</capability>
+<capability>urn:ietf:params:netconf:base:1.0</capability>
+<capability>http://org/openroadm/physical/types?module=org-openroadm-physical-types&revision=2016-10-14</capability>
+<capability>http://org/openroadm/database?module=org-openroadm-database&revision=2016-10-14</capability>
+<capability>http://org/openroadm/ethernet-interfaces?module=org-openroadm-ethernet-interfaces&revision=2016-10-14</capability>
+<capability>urn:ietf:params:xml:ns:yang:iana-afn-safi?module=iana-afn-safi&revision=2013-07-04</capability>
+<capability>http://org/openroadm/file-transfer?module=org-openroadm-file-transfer&revision=2016-10-14</capability>
+<capability>http://org/openroadm/resource?module=org-openroadm-resource&revision=2016-10-14</capability>
+<capability>http://org/openroadm/equipment/states/types?module=org-openroadm-equipment-states-types&revision=2016-10-14</capability>
+<capability>urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&revision=2013-07-15</capability>
+<capability>http://org/openroadm/de/operations?module=org-openroadm-de-operations&revision=2016-10-14</capability>
+<capability>http://org/openroadm/maintenance-loopback?module=org-openroadm-maintenance-loopback&revision=2016-10-14</capability>
+</capabilities>
+</hello>
--- /dev/null
+#!/usr/bin/env perl
+##############################################################################
+#Copyright (c) 2017 Orange, Inc. and others. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v1.0 which accompanies this distribution,
+# and is available at http://www.eclipse.org/legal/epl-v10.html
+##############################################################################
+#
+# debian dependecies: apt-get install libnet-openssh-perl libio-pty-perl
+#
+
+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);
+
+use IO::Socket;
+use Net::hostent;
+
+my ($host, $help, $usage, $proxy_port, $login, $password, $kidpid, $ssh_subsocket, $simpleproxy,
+ $pid, $ssh_handle, $client, $server, $capabilities, $hello_message, $verbose);
+
+GetOptions (
+ "h|help" =>\$help,
+ "p|port=i"=>\$proxy_port,
+ "s|simpleproxy" =>\$simpleproxy,
+ "v|verbose" =>\$verbose,
+ "C|capabilities=s"=>\$capabilities
+);
+$usage = "
+USAGE: netconf_TCP_SSH_hijackproxy.pl [-h|--help] [-p|--port <port_number>] [-s|--simpleproxy] [-v|--verbose] [-C|--capabilities <custom_hello_file.xml>] <[login[:password]@]host[:port]> [login] [password]
+
+Netconf SSH to TCP proxy to debug netconf exchanges.
+It listens to connections in clear TCP to the given port. When a TCP connection demand is received,
+it establishes a netconf SSH encrypted connection to the host in argument. Netconf rpcs and replies
+are then proxified between both ends.
+By default, exchanges are altered according to the rules specified inside this script and easily
+modifiable. This behaviour can be disabled with the '-s' option.
+For more convenience, the server hello handshake can also alternatively be replaced by the content
+of an external file rather instead of writing specific rules.
+
+OPTIONS :
+
+ -h or --help print this help
+ -p or --port use the given port number for listening TCP clients, default=9000
+ -s or --simpleproxy simple proxy mode, do not alter any exchanges
+ -v or --verbose display exchanges to STDOUT
+ -C or --capabilities do not relay the real server hello message to the client
+ but replace it by the one provided in the following file
+
+
+";
+
+if ($help) {
+ print $usage;
+ exit(0);
+}
+
+unless (@ARGV >= 1) {
+ print $usage;
+ exit(0);
+}
+
+($host, $login, $password) = @ARGV;
+
+#netconf default port is no 22 but 830
+if ($host !~ /:[0-9]+$/) { $host.=':830'; }
+
+if (!defined($proxy_port)) { $proxy_port = 9000; }
+
+my $connection_string=$host;
+if ($password) {
+ $connection_string=$login.":".$password."@".$connection_string;
+} elsif ($login) {
+ $connection_string=$login."@".$connection_string;
+}
+
+#retrieving hello custom file if any
+if ((!defined ($simpleproxy))&&(defined ($capabilities))) {
+ open(CAPABILITIES,'<',$capabilities) or die ("can not open $capabilities") ;
+ while (<CAPABILITIES>) {
+ $hello_message .= $_;
+ }
+ chop $hello_message; # removing EOF
+ $hello_message.="]]>]]>";
+ close(CAPABILITIES);
+}
+
+# the following regex are used to modify some part of the server messages relayed to the client
+# you can adapt it to your needs, some examples have been commented.
+my %regex_hash=(
+# replace oo-device v1.2 by v1.2.1
+# 'module=org-openroadm-device&revision=2016-10-14.*<\/capability>'=>'s/&revision=2016-10-14/&revision=2017-02-06/',
+# '<schema><identifier>org-openroadm-device<\/identifier><version>2016-10-14'=>'s@<schema><identifier>org-openroadm-device</identifier><version>2016-10-14@<schema><identifier>org-openroadm-device</identifier><version>2017-02-06@',
+# remove all deviations found
+# '&deviations=.*<\/capability>'=>'s@&deviations=.*</capability>@</capability>@',
+# add the ietf-netconf capability to the hello handshake - without it, ODL netconf mountpoints can not work
+# '<\/capabilities>'=>'s@</capabilities>@\n<capability>urn:ietf:params:xml:ns:yang:ietf-netconf?module=ietf-netconf&revision=2011-06-01</capability>\n</capabilities>@',
+# add the right notifications capabilities to the hello handshake + provide another solution for the ietf-netconf capability
+ '<\/capabilities>'=>'s@</capabilities>@\n<capability>urn:ietf:params:xml:ns:netmod:notification?module=nc-notifications&revision=2008-07-14</capability>\n<capability>urn:ietf:params:xml:ns:netconf:notification:1.0?module=notifications&revision=2008-07-14</capability>\n<capability>urn:ietf:params:xml:ns:netconf:base:1.0?module=ietf-netconf&revision=2011-06-01</capability>\n</capabilities>@'
+);
+
+if (defined ($simpleproxy)) { %regex_hash=(); }
+
+my %compiled_regex_hash;
+foreach my $keyword (keys %regex_hash){
+ eval ('$compiled_regex_hash{$keyword}= qr/'.$keyword.'/;');
+}
+
+$server = IO::Socket::INET->new( Proto => 'tcp',
+ LocalPort => $proxy_port,
+ Listen => SOMAXCONN,
+ Reuse => 1);
+die "can't setup server" unless $server;
+print STDERR "[Proxy server $0 accepting clients: Ctrl-C to stop]\n";
+
+
+while ($client = $server->accept()) {
+ $client->autoflush(1);
+ my $hostinfo = gethostbyaddr($client->peeraddr);
+ printf STDERR "[Incoming connection from %s]\n", $hostinfo->name || $client->peerhost;
+
+
+print STDERR "[relaying to ".$connection_string."]\n";
+
+$ssh_handle = Net::OpenSSH->new($connection_string,
+ master_opts => [-o => 'StrictHostKeyChecking=no'],
+ timeout => 500, kill_ssh_on_timeout => 500);
+
+#netconf requires a specific socket
+($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());
+
+$|=1;
+
+# the if{} block runs only in the parent process (server output relayed to the client)
+if (!$kidpid) {
+
+ # copy the socket to standard output
+ my $buf;
+
+ if (defined ($hello_message)) {
+ #retrieve the server hello but do not relay it
+ while (my $nread = sysread($ssh_subsocket,$buf,400)) {
+ $ssh_subsocket->flush();
+ if ($buf =~ /]]>]]>/) { last };
+ };
+ #send a custom hello message instead
+ print $client $hello_message;
+ if (defined($verbose)) { print STDOUT $hello_message; }
+ }
+
+ #while (<$ssh_subsocket>) {
+ #buffer seems not totally flushed when using the usual syntax above (nor when using autoflush)
+ while (my $nread = sysread($ssh_subsocket,$buf,400)) {
+ foreach my $keyword (keys %regex_hash){
+ if($buf =~ $compiled_regex_hash{$keyword}){
+ print STDERR 'found regex '.$keyword.": replacing '\n".$buf."\n' by '\n";
+ eval ('$buf =~ '.$regex_hash{$keyword}.';');
+ print STDERR $buf."\n'\n";
+ }
+ }
+ print $client $buf;
+ $ssh_subsocket->flush();
+ if (defined($verbose)) { print STDOUT $buf; }
+
+ };
+
+ kill("TERM", $kidpid); # send SIGTERM to child
+}
+# the else{} block runs only in the child process (client input relayed to the server)
+else {
+
+ $ssh_subsocket->autoflush(1);
+ sleep 1; # wait needed for ensuring STDOUT buffer is not melt
+ my $buf;
+
+ #while (defined (my $buf = <$client>)) {
+ #usual syntax above used in verbose mode results into flush problems
+ while (my $nread = sysread($client,$buf,400)) {
+ print $ssh_subsocket $buf;
+ $client->flush();
+ if (defined($verbose)) { print STDOUT $buf; }
+ }continue {}
+
+ close $client;
+
+}
+
+$|=0;
+
+sleep 2;
+kill("TERM", $kidpid); # send SIGTERM to child
+
+}
+
+exit;
--- /dev/null
+#!/usr/bin/env perl
+##############################################################################
+#Copyright (c) 2017 Orange, Inc. and others. All rights reserved.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License v1.0 which accompanies this distribution,
+# and is available at http://www.eclipse.org/legal/epl-v10.html
+##############################################################################
+#
+# debian dependecies: apt-get install libnet-openssh-perl libio-pty-perl
+#
+
+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);
+
+
+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]
+
+Simple netconf terminal client that can be used as an alternative to 'openssh [-p port] <[login@]host> -s netconf'.
+The main difference is the built-in handshake phase with hello capabilties that can be loaded from an external file.
+This is particularly useful to avoid timeouts.
+
+OPTIONS :
+
+ -C or --capabilities use the given file to advertise a hello message with customized capabilities
+ -h or --help print this help
+
+";
+
+if ($help) {
+ print $usage;
+ exit(0);
+}
+
+unless (@ARGV >= 1) {
+ print $usage;
+ exit(0);
+}
+
+($host, $login, $password) = @ARGV;
+
+#netconf default port is no 22 but 830
+if ($host !~ /:[0-9]+$/) {
+ $host.=':830';
+}
+
+my $connection_string=$host;
+if ($password) {
+ $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") ;
+ while (<CAPABILITIES>) {
+ $hello_message .= $_;
+ }
+ 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"?>
+<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-netconf-notifications?module=ietf-netconf-notifications&revision=2012-02-06</capability>
+<capability>urn:ietf:params:xml:ns:netconf:base:1.0?module=ietf-netconf&revision=2011-06-01</capability>
+<capability>urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&revision=2013-07-15</capability>
+<capability>urn:ietf:params:netconf:capability:candidate:1.0</capability>
+<capability>urn:ietf:params:xml:ns:netconf:notification:1.0?module=notifications&revision=2008-07-14</capability>
+<capability>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring-extension?module=ietf-netconf-monitoring-extension&revision=2013-12-10</capability>
+<capability>urn:ietf:params:netconf:base:1.0</capability>
+<capability>urn:ietf:params:xml:ns:yang:iana-afn-safi?module=iana-afn-safi&revision=2013-07-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";
+}
+
+
+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);
+
+#netconf requires a specific socket
+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());
+
+
+# the if{} block runs only in the parent process (terminal output)
+if (!$kidpid) {
+
+ $|=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)) {
+ print $buf;
+ $ssh_subsocket->flush();
+ };
+
+ print;
+ 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
+
+ if (defined ($hello_message)) {
+ print $ssh_subsocket $hello_message;
+ sleep 1;
+ }
+
+ while (defined (my $line = <STDIN>)) {
+ print $ssh_subsocket $line;
+ }
+
+}
+
+sleep 2;
+kill("TERM", $kidpid); # send SIGTERM to child
+exit;