Title: Telnet option negotiation

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);
}

Reply via email to