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
This message is in MIME format. Since your mail reader does not understand this format, some or all of this message may not be legible. ------_=_NextPart_001_01C1A254.3A470510 Content-Type: text/plain; charset="iso-8859-2" 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); } ------_=_NextPart_001_01C1A254.3A470510 Content-Type: text/html; charset="iso-8859-2" Content-Transfer-Encoding: quoted-printable <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> <HTML> <HEAD> <META HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; = charset=3Diso-8859-2"> <META NAME=3D"Generator" CONTENT=3D"MS Exchange Server version = 5.5.2654.19"> <TITLE>Telnet option negotiation</TITLE> </HEAD> <BODY> <P><FONT SIZE=3D2>Hi FreeBSD experts,</FONT> <BR><FONT SIZE=3D2>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=3D2>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=3D2>Telnet</FONT> <BR><FONT SIZE=3D2> Command: Do Authentication = Option</FONT> </P> <P><FONT SIZE=3D2>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=3D2>Telnet</FONT> <BR><FONT SIZE=3D2> Command: Do Echo</FONT> <BR><FONT SIZE=3D2> Command: Won't Authentication = Option</FONT> </P> <P><FONT SIZE=3D2>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=3D2>Telnet</FONT> <BR><FONT SIZE=3D2> Command: Will Echo</FONT> <BR><FONT SIZE=3D2> Command: Will Encryption = Option</FONT> <BR><FONT SIZE=3D2> Command: Do Terminal Type</FONT> <BR><FONT SIZE=3D2> Command: Do Terminal Speed</FONT> <BR><FONT SIZE=3D2> Command: Do X Display = Location</FONT> <BR><FONT SIZE=3D2> Command: Do New Environment = Option</FONT> <BR><FONT SIZE=3D2> Command: Do Environment = Option</FONT> </P> <P><FONT SIZE=3D2>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=3D2>Telnet</FONT> <BR><FONT SIZE=3D2> Command: Won't Terminal = Type</FONT> <BR><FONT SIZE=3D2> Command: Won't Terminal = Speed</FONT> <BR><FONT SIZE=3D2> Command: Won't X Display = Location</FONT> <BR><FONT SIZE=3D2> Command: Won't New Environment = Option</FONT> <BR><FONT SIZE=3D2> Command: Won't Environment = Option</FONT> <BR><FONT SIZE=3D2>Can you tell me why it does not work, and what can I = do to make it work?</FONT> <BR><FONT SIZE=3D2>Thank you for all hints!</FONT> <BR><FONT SIZE=3D2>Regards,</FONT> <BR><FONT SIZE=3D2>Zacco</FONT> </P> <P><FONT SIZE=3D2>----------</FONT> </P> <P><FONT SIZE=3D2>This is the very first experimental code:</FONT> </P> <P><FONT SIZE=3D2>#include <sys/types.h></FONT> <BR><FONT SIZE=3D2>#include <sys/socket.h> </FONT> <BR><FONT SIZE=3D2>#include <stdio.h></FONT> <BR><FONT SIZE=3D2>#include <errno.h></FONT> <BR><FONT SIZE=3D2>#include <unistd.h></FONT> <BR><FONT SIZE=3D2>#include <netdb.h></FONT> <BR><FONT SIZE=3D2>#include <string.h></FONT> <BR><FONT SIZE=3D2>#include <netinet/in.h></FONT> <BR><FONT SIZE=3D2>#include <stdlib.h></FONT> </P> <BR> <P><FONT SIZE=3D2>char* hostname =3D "hostname";</FONT> <BR><FONT SIZE=3D2>char* pwd =3D "password\r\n";</FONT> <BR><FONT SIZE=3D2>char* usr =3D "username\r\n";</FONT> <BR><FONT SIZE=3D2>bool opt0 =3D true;</FONT> <BR><FONT SIZE=3D2>bool isLogged =3D false;</FONT> </P> <P><FONT SIZE=3D2>void SndMsg( int sd, const char* mp )</FONT> <BR><FONT SIZE=3D2>{</FONT> <BR> <FONT SIZE=3D2>send( sd, = mp, strlen(mp), 0 );</FONT> <BR> <FONT SIZE=3D2>printf( = "\nsend msg: %s\n", mp );</FONT> <BR><FONT SIZE=3D2>}</FONT> </P> <P><FONT SIZE=3D2>bool Telnet_recv( int socket_desc )</FONT> <BR><FONT SIZE=3D2>{</FONT> <BR> <FONT SIZE=3D2>unsigned = char optmsg[100];</FONT> <BR> <FONT SIZE=3D2>int = bufsize =3D 1024;</FONT> <BR> <FONT SIZE=3D2>unsigned = char buffer[bufsize];</FONT> <BR> <FONT SIZE=3D2>int = length =3D recv(socket_desc, buffer, bufsize, 0);</FONT> <BR> <FONT SIZE=3D2>int = optmsglen =3D 0;</FONT> </P> <P> <FONT SIZE=3D2>if( opt0 = )</FONT> <BR> <FONT SIZE=3D2>{</FONT> <BR> = <FONT = SIZE=3D2>optmsg[optmsglen] =3D 255;</FONT> <BR> = <FONT = SIZE=3D2>optmsg[optmsglen+1] =3D 253;</FONT> <BR> = <FONT = SIZE=3D2>optmsg[optmsglen+2] =3D 1;</FONT> <BR> = <FONT SIZE=3D2>optmsglen = +=3D 3;</FONT> <BR> = <FONT SIZE=3D2>opt0 =3D = false;</FONT> <BR> <FONT SIZE=3D2>}</FONT> <BR> <FONT SIZE=3D2>for (int = i =3D 0; i < length; i +=3D 3 )</FONT> <BR> <FONT SIZE=3D2>{</FONT> <BR> = <FONT SIZE=3D2>if( buffer[i] = =3D=3D 255 ) // IAC</FONT> <BR> = <FONT SIZE=3D2>{</FONT> <BR> = = <FONT SIZE=3D2>if( = buffer[i+1] =3D=3D 253 )</FONT> <BR> = = <FONT SIZE=3D2>{</FONT> <BR> = = = <FONT = SIZE=3D2>optmsg[optmsglen] =3D 255;</FONT> <BR> = = = <FONT = SIZE=3D2>optmsg[optmsglen+1] =3D 252;</FONT> <BR> = = = <FONT = SIZE=3D2>optmsg[optmsglen+2] =3D buffer[i+2];</FONT> <BR> = = = <FONT SIZE=3D2>optmsglen = +=3D 3;</FONT> <BR> = = <FONT SIZE=3D2>}</FONT> <BR> = <FONT SIZE=3D2>}</FONT> <BR> = <FONT SIZE=3D2>else</FONT> <BR> = <FONT SIZE=3D2>{</FONT> <BR> = = <FONT SIZE=3D2>if( (strstr( = (const char*)buffer, "ogin" ) !=3D NULL) && = (!isLogged) ) { isLogged=3Dtrue; SndMsg( socket_desc, usr ); = }</FONT></P> <P> = = <FONT SIZE=3D2>if( strstr( = (const char*)buffer, "assword") !=3D NULL ) { isLogged = =3D true; SndMsg( socket_desc, pwd );}</FONT></P> <P> = <FONT SIZE=3D2>}</FONT> <BR> <FONT SIZE=3D2>}</FONT> <BR> <FONT SIZE=3D2>if( = optmsglen > 0 ) send( socket_desc, optmsg, optmsglen, 0 );</FONT> <BR> <FONT SIZE=3D2>if( = buffer[length-1] =3D=3D '>' || buffer[length-2] =3D=3D '>' || = buffer[length-2] =3D=3D '#' || buffer[length-2] =3D=3D '$' ) return = true;</FONT></P> <P> <FONT SIZE=3D2>else = return false;</FONT> <BR><FONT SIZE=3D2>}</FONT> </P> <BR> <P><FONT SIZE=3D2>int main()</FONT> <BR><FONT SIZE=3D2>{</FONT> <BR> <FONT SIZE=3D2>int = socket_desc;</FONT> <BR> <FONT SIZE=3D2>struct = hostent *he;</FONT> <BR> <FONT SIZE=3D2>struct = sockaddr_in address;</FONT> </P> <P> <FONT SIZE=3D2>if( ( = socket_desc=3Dsocket(AF_INET,SOCK_STREAM,0) ) =3D=3D 0 ) perror( = "Create socket" );</FONT> </P> <P> <FONT SIZE=3D2>if ((he = =3D gethostbyname( hostname )) =3D=3D NULL)</FONT> <BR> <FONT SIZE=3D2>{</FONT> <BR> = <FONT = SIZE=3D2>puts("error resolving hostname..");</FONT> <BR> = <FONT = SIZE=3D2>exit(1);</FONT> <BR> <FONT SIZE=3D2>}</FONT> <BR> <FONT = SIZE=3D2>memcpy(&address.sin_addr, he->h_addr_list[0], = he->h_length);</FONT> <BR> <FONT = SIZE=3D2>address.sin_family =3D AF_INET;</FONT> <BR> <FONT = SIZE=3D2>address.sin_port =3D htons(23);</FONT> </P> <P> <FONT SIZE=3D2>if( = connect(socket_desc, (struct sockaddr *)&address, sizeof(address)) = =3D=3D -1 )</FONT> <BR> <FONT SIZE=3D2>{</FONT> <BR> = <FONT = SIZE=3D2>puts("error connecting..");</FONT> <BR> = <FONT = SIZE=3D2>exit(1);</FONT> <BR> <FONT SIZE=3D2>}</FONT> </P> <P> <FONT SIZE=3D2>int = length, x =3D 0;</FONT> <BR> <FONT SIZE=3D2>do{ = printf( "\n%d. message\n", ++x ); } while( Telnet_recv( = socket_desc ) ); </FONT> <BR> <FONT SIZE=3D2>printf( = "--- Successful Login ---\n" );</FONT> </P> <P> <FONT = SIZE=3D2>close(socket_desc);</FONT> <BR><FONT SIZE=3D2>}</FONT> </P> </BODY> </HTML> ------_=_NextPart_001_01C1A254.3A470510-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?F005CD411D18D3119C8F00508B08748005CC79E1>