SPUG: Anyone used Net::Telnet perl module to interact with NT??

William Julien moonbeam at catmanor.com
Thu Nov 29 23:26:23 CST 2001


>
>I'm looking for some off-line help in implementing
>a telnet (or like) tcp/ip port interaction script. I'm
>not having difficulty implementing this to work against
>a unix box, I'm struggling to get this to work w/NT.
>I need to be able to "query" file status on the NT box
>and the only service running is "telnet". This will
>be run from a Unix server on our VPN network.
>Thanks in advance...
>
>				---  Hailing frequencies closed
>----------------------------------------------------------------------------
>Bob Brockhausen                        Phone:  206-318-6413

A fun program to write. Can't say if it will work on NT, I don't do
windows. But I tested the following on linux and irix.  But it is all
"standard" perl, so I would should work anywhere.

Here is the server code...

#!/usr/bin/perl -Tw
#
# server to listen on port 1999 and return a stat of a file
#
###

#
# modules
#
use strict;
use IO::Socket;

#
# secure environment
#
$ENV{PATH}="";

#
# declare variables
#
my ($socket,    # client socket connection
    $client,    # client handle
    @stat,      # file stat data
    );

#
# make a socket connection to port 1999
#
$socket = IO::Socket::INET->new(Proto=>"tcp", 
                                LocalPort=>"1999",
                                Listen=>1
                                )
    or die "Cannot create server socket: $!\n";

#
# loop forever for client connections
#
while (1) {
    $client = $socket->accept;
    $client->autoflush(1);

    while (<$client>) {
        chomp;
        s/\r//;
        # client is done
        if ( "$_" eq "." ) {
            close $client;
            last;
        }
        # say hello (we are a friendly server)
        if ( "$_" eq "hello" ) {
            print $client "Hello. Nice to meet you.\n";
            print $client "Please enter a file name.\n";
            next;
        }
        # server kill command
        if ( "$_" eq "kill" ) {
            close $client;
            close $socket;
            exit;
        }
        # stat a file
        if ( -f "$_" ) {
            @stat = stat("$_");
            print $client "$_: @stat\n";
        } else {
            print $client "File Not Found: $_\n";
        }
        next;
    }
}

***
It works well with telnet. Here is a sample.

(start the server)

-->stat_server.pl &
[1]     37230

(telnet to the deamon)
-->telnet localhost 1999
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
hello
Hello. Nice to meet you.
Please enter a file name.
c:/command.com
File Not Found: c:/command.com
/usr/bin/perl
/usr/bin/perl: 90 25217292 33261 1 0 0 0 19180 1007095503 1004175156 1004582967 65536 40
/unix
/unix: 90 51240 33256 1 0 0 0 7120528 1006242696 1005722055 1005722471 65536 13912
.
Connection closed by foreign host.

(do a remote server shutdown)

-->telnet localhost 1999
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
kill
Connection closed by foreign host.
[1] +  Done                    stat_server.pl &

Well... That was fun! I suspect that you might want to not use the 
"kill" server command. I did it only to see if it would work.

Using telnet on the remote side is not very useful, and very
interactive. It would be much better if the client could batch a set of
requests to the server. The following perl client will take whatever is
on STDIN and send that to the server and copy the output to STDOUT. To
handle bi-directional interaction, the parent process handles the sending
of the data and a child process handles the server responses.

-->cat biclient.pl
#!/usr/bin/perl -w
#
# biclient - bidirectional forking client

use strict;
use IO::Socket;
my($port, $host, $handle, $line, $kidpid);

$port = "1999";
$host = "localhost";

# create a tcp connection to the specified host and port
$handle = IO::Socket::INET->new(Proto     => "tcp",
                                PeerAddr  => $host,
                                PeerPort  => $port)
       or die "can't connect to port $port on $host: $!";

$handle->autoflush(1);              # so output gets there right away
print "[Connected to $host:$port]\n";

# split the program into two processes, identical twins
die "can't fork: $!" unless defined($kidpid = fork());

if ($kidpid) {
# parent copies the socket to standard output
    while (defined ($line =  <$handle>)) {
        print $line;
    } 
    kill("TERM" => $kidpid);        # send SIGTERM to child
}
else {
  # child copies standard input to the socket
    while (defined ($line = <>)) {
        print $handle $line;
    }
}

***
Note -- The remote host is hardcoded in the client code! It is left
for the reader to getopt this parameter.

Here is an "interactive" sample run...

-->biclient.pl     
[Connected to localhost:1999]
hello
Hello. Nice to meet you.
Please enter a file name.
/bin/sh
/bin/sh: 90 25182522 33261 1 0 0 0 606808 1007095506 1004173275 1004173275 65536 1192
.

This works just like telnet!. But the fun part is that the input can
be now batched and can be embedded in a shell script, client code,
or available for automation via cron. For example...

-->cat tt
/unix
/bin/sh
/command.com
/usr/bin/perl
.

note - the trailing "." is important. Otherwise, the server hold
onto the client connection.

-->cat tt | biclient.pl 
[Connected to localhost:1999]
/unix: 90 51240 33256 1 0 0 0 7120528 1006242696 1005722055 1005722471 65536 13912
/bin/sh: 90 25182522 33261 1 0 0 0 606808 1007096586 1004173275 1004173275 65536 1192
File Not Found: /command.com
/usr/bin/perl: 90 25217292 33261 1 0 0 0 19180 1007096609 1004175156 1004582967 65536 40

Have Fun.
---
   William Julien           _,'|            _.-''``-...___..--';
moonbeam at catmanor.com      /, \'.      _..-' ,      ,--...--'''
 vi is my shepherd;       < \   .`--'''      `     /| 
 i shall not font.         `-,;'              ;   ; ;  
                     __...--''     __...--_..'  .;.'  
                    (,__....----'''      (,..--''     
perl -e 'print $i=pack(c5,(41*2),sqrt(7056),(unpack(c,H)-2),oct(115),10);'
perl -e '( $ ,, $ ")=("a".."z")[0,-1]; print "sh", $ ","m\n";;";;"'

 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     POST TO: spug-list at pm.org       PROBLEMS: owner-spug-list at pm.org
      Subscriptions; Email to majordomo at pm.org:  ACTION  LIST  EMAIL
  Replace ACTION by subscribe or unsubscribe, EMAIL by your Email-address
 For daily traffic, use spug-list for LIST ;  for weekly, spug-list-digest
     Seattle Perl Users Group (SPUG) Home Page: http://zipcon.net/spug/





More information about the spug-list mailing list