Date: Mon, 21 Jan 2002 09:18:38 +0100 From: "Lajos Zaccomer (ETH)" <Lajos.Zaccomer@eth.ericsson.se> To: "'freebsd-hackers@FreeBSD.org'" <freebsd-hackers@FreeBSD.org> Subject: Telnet option negotiation Message-ID: <F005CD411D18D3119C8F00508B08748005CC79E1@ehubunt100.eth.ericsson.se>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
Hi FreeBSD experts,
I wrote a VERY simple telnet program that actually works as a Network Virtual Terminal. It is achieved by sending "WON'T XXX" to all "DO XXX" server requests. It should work according to RFC-854, page 4: "Since the NVT is what is left when no options are enabled, the DON'T and WON'T responses are guaranteed to leave the connection in a state which both ends can handle." It works with Unix, Linux, Windows, Cisco, but not with my FreeBSD: after a while it stops sending anything. This is the attempt trace:
Internet Protocol, Src Addr: 10.1.1.223 (10.1.1.223), Dst Addr: 10.1.1.222 (10.1.1.222)
Telnet
Command: Do Authentication Option
Internet Protocol, Src Addr: 10.1.1.222 (10.1.1.222), Dst Addr: 10.1.1.223 (10.1.1.223)
Telnet
Command: Do Echo
Command: Won't Authentication Option
Internet Protocol, Src Addr: 10.1.1.223 (10.1.1.223), Dst Addr: 10.1.1.222 (10.1.1.222)
Telnet
Command: Will Echo
Command: Will Encryption Option
Command: Do Terminal Type
Command: Do Terminal Speed
Command: Do X Display Location
Command: Do New Environment Option
Command: Do Environment Option
Internet Protocol, Src Addr: 10.1.1.222 (10.1.1.222), Dst Addr: 10.1.1.223 (10.1.1.223)
Telnet
Command: Won't Terminal Type
Command: Won't Terminal Speed
Command: Won't X Display Location
Command: Won't New Environment Option
Command: Won't Environment Option
Can you tell me why it does not work, and what can I do to make it work?
Thank you for all hints!
Regards,
Zacco
----------
This is the very first experimental code:
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#include <string.h>
#include <netinet/in.h>
#include <stdlib.h>
char* hostname = "hostname";
char* pwd = "password\r\n";
char* usr = "username\r\n";
bool opt0 = true;
bool isLogged = false;
void SndMsg( int sd, const char* mp )
{
send( sd, mp, strlen(mp), 0 );
printf( "\nsend msg: %s\n", mp );
}
bool Telnet_recv( int socket_desc )
{
unsigned char optmsg[100];
int bufsize = 1024;
unsigned char buffer[bufsize];
int length = recv(socket_desc, buffer, bufsize, 0);
int optmsglen = 0;
if( opt0 )
{
optmsg[optmsglen] = 255;
optmsg[optmsglen+1] = 253;
optmsg[optmsglen+2] = 1;
optmsglen += 3;
opt0 = false;
}
for (int i = 0; i < length; i += 3 )
{
if( buffer[i] == 255 ) // IAC
{
if( buffer[i+1] == 253 )
{
optmsg[optmsglen] = 255;
optmsg[optmsglen+1] = 252;
optmsg[optmsglen+2] = buffer[i+2];
optmsglen += 3;
}
}
else
{
if( (strstr( (const char*)buffer, "ogin" ) != NULL) && (!isLogged) ) { isLogged=true; SndMsg( socket_desc, usr ); }
if( strstr( (const char*)buffer, "assword") != NULL ) { isLogged = true; SndMsg( socket_desc, pwd );}
}
}
if( optmsglen > 0 ) send( socket_desc, optmsg, optmsglen, 0 );
if( buffer[length-1] == '>' || buffer[length-2] == '>' || buffer[length-2] == '#' || buffer[length-2] == '$' ) return true;
else return false;
}
int main()
{
int socket_desc;
struct hostent *he;
struct sockaddr_in address;
if( ( socket_desc=socket(AF_INET,SOCK_STREAM,0) ) == 0 ) perror( "Create socket" );
if ((he = gethostbyname( hostname )) == NULL)
{
puts("error resolving hostname..");
exit(1);
}
memcpy(&address.sin_addr, he->h_addr_list[0], he->h_length);
address.sin_family = AF_INET;
address.sin_port = htons(23);
if( connect(socket_desc, (struct sockaddr *)&address, sizeof(address)) == -1 )
{
puts("error connecting..");
exit(1);
}
int length, x = 0;
do{ printf( "\n%d. message\n", ++x ); } while( Telnet_recv( socket_desc ) );
printf( "--- Successful Login ---\n" );
close(socket_desc);
}
[-- Attachment #2 --]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-2">
<META NAME="Generator" CONTENT="MS Exchange Server version 5.5.2654.19">
<TITLE>Telnet option negotiation</TITLE>
</HEAD>
<BODY>
<P><FONT SIZE=2>Hi FreeBSD experts,</FONT>
<BR><FONT SIZE=2>I wrote a VERY simple telnet program that actually works as a Network Virtual Terminal. It is achieved by sending "WON'T XXX" to all "DO XXX" server requests. It should work according to RFC-854, page 4: "Since the NVT is what is left when no options are enabled, the DON'T and WON'T responses are guaranteed to leave the connection in a state which both ends can handle." It works with Unix, Linux, Windows, Cisco, but not with my FreeBSD: after a while it stops sending anything. This is the attempt trace:</FONT></P>
<P><FONT SIZE=2>Internet Protocol, Src Addr: 10.1.1.223 (10.1.1.223), Dst Addr: 10.1.1.222 (10.1.1.222)</FONT>
<BR><FONT SIZE=2>Telnet</FONT>
<BR><FONT SIZE=2> Command: Do Authentication Option</FONT>
</P>
<P><FONT SIZE=2>Internet Protocol, Src Addr: 10.1.1.222 (10.1.1.222), Dst Addr: 10.1.1.223 (10.1.1.223)</FONT>
<BR><FONT SIZE=2>Telnet</FONT>
<BR><FONT SIZE=2> Command: Do Echo</FONT>
<BR><FONT SIZE=2> Command: Won't Authentication Option</FONT>
</P>
<P><FONT SIZE=2>Internet Protocol, Src Addr: 10.1.1.223 (10.1.1.223), Dst Addr: 10.1.1.222 (10.1.1.222)</FONT>
<BR><FONT SIZE=2>Telnet</FONT>
<BR><FONT SIZE=2> Command: Will Echo</FONT>
<BR><FONT SIZE=2> Command: Will Encryption Option</FONT>
<BR><FONT SIZE=2> Command: Do Terminal Type</FONT>
<BR><FONT SIZE=2> Command: Do Terminal Speed</FONT>
<BR><FONT SIZE=2> Command: Do X Display Location</FONT>
<BR><FONT SIZE=2> Command: Do New Environment Option</FONT>
<BR><FONT SIZE=2> Command: Do Environment Option</FONT>
</P>
<P><FONT SIZE=2>Internet Protocol, Src Addr: 10.1.1.222 (10.1.1.222), Dst Addr: 10.1.1.223 (10.1.1.223)</FONT>
<BR><FONT SIZE=2>Telnet</FONT>
<BR><FONT SIZE=2> Command: Won't Terminal Type</FONT>
<BR><FONT SIZE=2> Command: Won't Terminal Speed</FONT>
<BR><FONT SIZE=2> Command: Won't X Display Location</FONT>
<BR><FONT SIZE=2> Command: Won't New Environment Option</FONT>
<BR><FONT SIZE=2> Command: Won't Environment Option</FONT>
<BR><FONT SIZE=2>Can you tell me why it does not work, and what can I do to make it work?</FONT>
<BR><FONT SIZE=2>Thank you for all hints!</FONT>
<BR><FONT SIZE=2>Regards,</FONT>
<BR><FONT SIZE=2>Zacco</FONT>
</P>
<P><FONT SIZE=2>----------</FONT>
</P>
<P><FONT SIZE=2>This is the very first experimental code:</FONT>
</P>
<P><FONT SIZE=2>#include <sys/types.h></FONT>
<BR><FONT SIZE=2>#include <sys/socket.h> </FONT>
<BR><FONT SIZE=2>#include <stdio.h></FONT>
<BR><FONT SIZE=2>#include <errno.h></FONT>
<BR><FONT SIZE=2>#include <unistd.h></FONT>
<BR><FONT SIZE=2>#include <netdb.h></FONT>
<BR><FONT SIZE=2>#include <string.h></FONT>
<BR><FONT SIZE=2>#include <netinet/in.h></FONT>
<BR><FONT SIZE=2>#include <stdlib.h></FONT>
</P>
<BR>
<P><FONT SIZE=2>char* hostname = "hostname";</FONT>
<BR><FONT SIZE=2>char* pwd = "password\r\n";</FONT>
<BR><FONT SIZE=2>char* usr = "username\r\n";</FONT>
<BR><FONT SIZE=2>bool opt0 = true;</FONT>
<BR><FONT SIZE=2>bool isLogged = false;</FONT>
</P>
<P><FONT SIZE=2>void SndMsg( int sd, const char* mp )</FONT>
<BR><FONT SIZE=2>{</FONT>
<BR> <FONT SIZE=2>send( sd, mp, strlen(mp), 0 );</FONT>
<BR> <FONT SIZE=2>printf( "\nsend msg: %s\n", mp );</FONT>
<BR><FONT SIZE=2>}</FONT>
</P>
<P><FONT SIZE=2>bool Telnet_recv( int socket_desc )</FONT>
<BR><FONT SIZE=2>{</FONT>
<BR> <FONT SIZE=2>unsigned char optmsg[100];</FONT>
<BR> <FONT SIZE=2>int bufsize = 1024;</FONT>
<BR> <FONT SIZE=2>unsigned char buffer[bufsize];</FONT>
<BR> <FONT SIZE=2>int length = recv(socket_desc, buffer, bufsize, 0);</FONT>
<BR> <FONT SIZE=2>int optmsglen = 0;</FONT>
</P>
<P> <FONT SIZE=2>if( opt0 )</FONT>
<BR> <FONT SIZE=2>{</FONT>
<BR> <FONT SIZE=2>optmsg[optmsglen] = 255;</FONT>
<BR> <FONT SIZE=2>optmsg[optmsglen+1] = 253;</FONT>
<BR> <FONT SIZE=2>optmsg[optmsglen+2] = 1;</FONT>
<BR> <FONT SIZE=2>optmsglen += 3;</FONT>
<BR> <FONT SIZE=2>opt0 = false;</FONT>
<BR> <FONT SIZE=2>}</FONT>
<BR> <FONT SIZE=2>for (int i = 0; i < length; i += 3 )</FONT>
<BR> <FONT SIZE=2>{</FONT>
<BR> <FONT SIZE=2>if( buffer[i] == 255 ) // IAC</FONT>
<BR> <FONT SIZE=2>{</FONT>
<BR> <FONT SIZE=2>if( buffer[i+1] == 253 )</FONT>
<BR> <FONT SIZE=2>{</FONT>
<BR> <FONT SIZE=2>optmsg[optmsglen] = 255;</FONT>
<BR> <FONT SIZE=2>optmsg[optmsglen+1] = 252;</FONT>
<BR> <FONT SIZE=2>optmsg[optmsglen+2] = buffer[i+2];</FONT>
<BR> <FONT SIZE=2>optmsglen += 3;</FONT>
<BR> <FONT SIZE=2>}</FONT>
<BR> <FONT SIZE=2>}</FONT>
<BR> <FONT SIZE=2>else</FONT>
<BR> <FONT SIZE=2>{</FONT>
<BR> <FONT SIZE=2>if( (strstr( (const char*)buffer, "ogin" ) != NULL) && (!isLogged) ) { isLogged=true; SndMsg( socket_desc, usr ); }</FONT></P>
<P> <FONT SIZE=2>if( strstr( (const char*)buffer, "assword") != NULL ) { isLogged = true; SndMsg( socket_desc, pwd );}</FONT></P>
<P> <FONT SIZE=2>}</FONT>
<BR> <FONT SIZE=2>}</FONT>
<BR> <FONT SIZE=2>if( optmsglen > 0 ) send( socket_desc, optmsg, optmsglen, 0 );</FONT>
<BR> <FONT SIZE=2>if( buffer[length-1] == '>' || buffer[length-2] == '>' || buffer[length-2] == '#' || buffer[length-2] == '$' ) return true;</FONT></P>
<P> <FONT SIZE=2>else return false;</FONT>
<BR><FONT SIZE=2>}</FONT>
</P>
<BR>
<P><FONT SIZE=2>int main()</FONT>
<BR><FONT SIZE=2>{</FONT>
<BR> <FONT SIZE=2>int socket_desc;</FONT>
<BR> <FONT SIZE=2>struct hostent *he;</FONT>
<BR> <FONT SIZE=2>struct sockaddr_in address;</FONT>
</P>
<P> <FONT SIZE=2>if( ( socket_desc=socket(AF_INET,SOCK_STREAM,0) ) == 0 ) perror( "Create socket" );</FONT>
</P>
<P> <FONT SIZE=2>if ((he = gethostbyname( hostname )) == NULL)</FONT>
<BR> <FONT SIZE=2>{</FONT>
<BR> <FONT SIZE=2>puts("error resolving hostname..");</FONT>
<BR> <FONT SIZE=2>exit(1);</FONT>
<BR> <FONT SIZE=2>}</FONT>
<BR> <FONT SIZE=2>memcpy(&address.sin_addr, he->h_addr_list[0], he->h_length);</FONT>
<BR> <FONT SIZE=2>address.sin_family = AF_INET;</FONT>
<BR> <FONT SIZE=2>address.sin_port = htons(23);</FONT>
</P>
<P> <FONT SIZE=2>if( connect(socket_desc, (struct sockaddr *)&address, sizeof(address)) == -1 )</FONT>
<BR> <FONT SIZE=2>{</FONT>
<BR> <FONT SIZE=2>puts("error connecting..");</FONT>
<BR> <FONT SIZE=2>exit(1);</FONT>
<BR> <FONT SIZE=2>}</FONT>
</P>
<P> <FONT SIZE=2>int length, x = 0;</FONT>
<BR> <FONT SIZE=2>do{ printf( "\n%d. message\n", ++x ); } while( Telnet_recv( socket_desc ) ); </FONT>
<BR> <FONT SIZE=2>printf( "--- Successful Login ---\n" );</FONT>
</P>
<P> <FONT SIZE=2>close(socket_desc);</FONT>
<BR><FONT SIZE=2>}</FONT>
</P>
</BODY>
</HTML>
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?F005CD411D18D3119C8F00508B08748005CC79E1>
