*BSD News Article 53090


Return to BSD News archive

#! rnews 2907 bsd
Path: euryale.cc.adfa.oz.au!newshost.anu.edu.au!harbinger.cc.monash.edu.au!simtel!news.kei.com!eff!news.umbc.edu!cs.umd.edu!news.coop.net!hops.entertain.com!usenet
From: Darryl Watson <dwatson>
Newsgroups: comp.unix.bsd.bsdi.misc
Subject: Trying to simulate a telnet session with PERL
Date: 14 Oct 1995 22:18:05 GMT
Organization: ABWAM, Inc., full service ISP, voice: 1+ 303 730-6050
Lines: 98
Message-ID: <45pcut$kcm@hops.entertain.com>
NNTP-Posting-Host: stout.entertain.com
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
X-Mailer: Mozilla 1.1N (X11; I; BSD/386 uname failed)
X-URL: news:comp.unix.bsd.bsdi.misc

..and having trouble.  I've got BSDi 2.0 with patches.

I am trying to open a socket on port 23 of my system using
PERL, but am not getting a login prompt in the resulting
stream.  I would expect TELNETD to respond with a login,
but it isn't happening.  Maybe I am specifying the wrong
type of service?  When I go to other ports, such as daytime,
this script works fine.

When I do a telnet -d and 'set netdata', then 'open <hostname>',
I see lots of telnet control data fly back and forth, just as
specified in the RFCs listed in the TELNETD man page.

Any help or suggestions appreciated!

Here is a copy of the PERL script I am using:

----------------------------------------------------------

#!/usr/bin/perl

($them, $port) = @ARGV;
$port = 7 unless $port;
$them = 'localhost' unless $them;

$AF_INET = 2;
$SOCK_STREAM = 1;

# telnet control codes and options (see RFCs)
$IAC = '\xff';
$GA = '\xf9';
$WILL = '\xfb';
$WONT = '\xfc';
$DO = '\xfd';
$DONT = '\xfe';

$SIG{'INT'} = 'dokill';
sub dokill {
    kill $9, $child if $child;
}

$sockaddr = 'S n a4 x8';

chop($hostname = `hostname`);

($name, $aliases, $proto) = getprotobyname('tcp');
($name, $aliases, $port) = getservbyname($port, 'tcp')
    unless $port =~ /^\d+$/;;
($name, $aliases, $type, $len, $thisaddr) =
    gethostbyname($hostname);
($name, $aliases, $type, $len, $thataddr) = gethostbyname($them);

$this = pack($sockaddr, $AF_INET, 0, $thisaddr);
$that = pack($sockaddr, $AF_INET, $port, $thataddr);

# make the socket filehandle
if (socket(S, $AF_INET, $SOCK_STREAM, $proto)) {
    print "socket OK\n";
}
else {
    die $!;
}

# give the socket an address
if (bind(S, $this)) {
    print "bind OK\n";
}
else {
    die $!;
}

# call the server
if (connect(S, $that)) {
    print "connect OK\n";
}
else {
    die $!;
}

# set socket to be command buffered
select(S);  $| = 1;  select(STDOUT);

# get the remote daemon's attention
print S "${IAC}${DO}\x03${IAC}${WONT}\x18";
print S "${IAC}${WONT}\x1f${IAC}${WONT}\x20";
print S "${IAC}${WONT}\x21${IAC}${WONT}\x22";
print S "${IAC}${WONT}\x27${IAC}${WONT}\x05";
print S "${IAC}${WONT}\x23\n";

# avoid deadlock by forking
if ($child = fork) {
    while(<STDIN>) {
        print S;
    }
    sleep 3;
    do dokill();
}