yartempion | Bonjour,
Et oui merevoila avec mon client telnet.
Il fonctionne mais a quelques imperfections.
Je vous fournis mon code source.
Code :
- #include<stdio.h>
- #include<sys/socket.h>
- #include<sys/types.h>
- #include<netinet/in.h>
- #include<netdb.h>
- #include<arpa/inet.h>
- #include<unistd.h>
- #include<termios.h>
- #include<sys/time.h>
- #include<stdlib.h>
- #include<fcntl.h>
- #include <errno.h>
- #include<signal.h>
- #include<term.h>
- #include<ctype.h>
- #define LG_BUFFER=1
- /*#define ETIMEDOUT=30*/
- /*negociation de depart*/
- MSG_DE_NEGO(socket1)
- {
- unsigned char mesg_nego[7];
- printf("\ndemande des negos initiales\n\n" );
- printf("\nDO ECHO" );
- mesg_nego[0]=255;
- mesg_nego[1]=253;/*DO*/
- mesg_nego[2]=1;/*ECHO*/
- mesg_nego[3]=0;
- write(socket1,mesg_nego,3);
- printf("\nDO SUPPRESS GO AHEAD" );
- mesg_nego[2]=3;/*SUPPRESS GO AHEAD*/
- write(socket1,mesg_nego,3);
- mesg_nego[1]=251;/*WILL*/
- printf("\nWILL TERMINAL TYPE" );
- mesg_nego[2]=24;/*TERMINAL TYPE*/
- write(socket1,mesg_nego,3);
- printf("\nWILL NAWS" );
- mesg_nego[2]=31;/*TAILLE TERMINAL NAWS*/
- write(socket1,mesg_nego,3);
- mesg_nego[2]=32;/*TERMINAL SPEED*/
- /*write(socket1,mesg_nego,3);*/
- mesg_nego[2]=33;/* REMOTE FLOW CONTROL */
- /*write(socket1,mesg_nego,3);*/
- /*mesg_nego[1]=250;*/
- /*mesg_nego[3]=1;*/
- /*mesg_nego[4]=255;*/
- /*mesg_nego[5]=240;*/
- /*write(socket1,mesg_nego,3);*/
- printf("\n\n" );
- }
- /*lancement des options de session*/
- LANCEMENT (socket1)
- {
- }
- /*procedure de negociation d'option telnet*/
- NEGOCIATION (buffer_RX,socket1,i)
- {
- unsigned char *mess_nego11,*rep_mess_nego1;
- int socket11,j,k;
- /*int socket1;*/
- socket11=socket1;
- j=i;
- rep_mess_nego1=mess_nego11=buffer_RX;
- printf("\n\n\nDebut de nego" );
- printf("\nvaleur de j=%d \n valeur des octets reçus: ",j);
- for(k=0;k<j+1;k++)
- printf("\noctet %d= %d ",k,*(mess_nego11+k));
- /*printf("\nN° traitement des types de message %d %d %d valeur de la socket %d",*mess_nego11,*(mess_nego11+1),*(mess_nego11+2),socket1);*/
- switch(*(mess_nego11+1))
- {
- case 250:
- printf("\nSB %d demande de sous negociation",*(mess_nego11+1));
- SOUS_OPTION_NEGOCIEE(mess_nego11,socket11);
- break;
- case 251:
- printf("\nWILL %d demande de negociation",*(mess_nego11+1));
- OPTION_NEGOCIEE(mess_nego11,socket11);
- break;
- case 252:
- printf("\nWONT %d refus de negociation",*(mess_nego11+1));
- OPTION_NEGOCIEE(mess_nego11,socket11);
- *(rep_mess_nego1+1)=254;
- write(socket1,rep_mess_nego1,3);
- printf("\nReponse a WONT = %d",*(rep_mess_nego1+1));
- break;
- case 253: printf("\nDO %d demande de negociation",*(mess_nego11+1));
- OPTION_NEGOCIEE(mess_nego11,socket11);
- break;
- case 254: printf("\nDONT %d refus de negociation",*(mess_nego11+1));
- OPTION_NEGOCIEE(mess_nego11,socket11);
- *(rep_mess_nego1+1)=252;
- write(socket1,rep_mess_nego1,3);
- printf("\nReponse a WONT = %d",*(rep_mess_nego1+1));
- break;
- default: printf("\nErreur de traitement sur negociation N° option %d",*(mess_nego11+1));
- break;
- }
- }
- /*N° d'option a negocier*/
- OPTION_NEGOCIEE(mess_nego11,socket11)
- {
- struct termios terminal_out;
- speed_t speed_o,speed_i;
- int socket12,i;
- unsigned char *mess_nego12;
- socket12=socket11;
- mess_nego12=mess_nego11;
- printf("\nProcedure OPTION_NEGOCIEE" );
- switch (*(mess_nego12+2))
- {
- case 1:
- {
- printf ("\n Option ECHO" );
- if (*(mess_nego12+1)==253)
- {
- printf("\nreponse %d %d %d %d",*(mess_nego12+0),*(mess_nego12+1)=252,*(mess_nego12+2),*(mess_nego12+3));
- i=write(socket11,mess_nego12,4);
- }
- }
- break;
- case 3: {
- printf ("\n Option GA" );
- }
- break;
- case 24:
- {
- printf ("\n Option Terminal type" );
- /*printf ("\n Option Terminal type sens de requet %d %d %d %d",*(mess_nego12+0),*(mess_nego12+1),*(mess_nego12+2),*(mess_nego12+3));*/
- *(mess_nego12+1)=251;
- i=write(socket11,mess_nego12,3);
- /*printf("\nReponse envoyee i= %d, %d %d %d %d",i,*(mess_nego12+0),*(mess_nego12+1),*(mess_nego12+2),*(mess_nego12+3));*/
- }
- break;
- case 31: {
- printf("\nOption NAWS" );
- /*printf("\nEnvoie de la sous option direct" );*/
- if((mess_nego12=realloc(mess_nego12,10*sizeof(unsigned char)))==NULL)
- printf("\nrealloc echouee sur SB 31" );
- *(mess_nego12+0)=255;
- *(mess_nego12+1)=250;
- *(mess_nego12+2)=31;
- *(mess_nego12+3)=0;
- *(mess_nego12+4)=80;
- *(mess_nego12+5)=0;
- *(mess_nego12+6)=24;
- *(mess_nego12+7)=255;
- *(mess_nego12+8)=240;
- /*printf("\nmessage a envoye %d %d %d %d %d %d %d %d",*(mess_nego12+0),*(mess_nego12+1),*(mess_nego12+2),*(mess_nego12+3),*(mess_nego12+4),*(mess_nego12+5),*(mess_nego12+6),*(mess_nego12+7));*/
- i=write(socket11,mess_nego12,9);
- /*printf("\nReponse NAWS envoyee" );*/
- }
- break;
- /*case 32:
- {
- printf("\nOption Terminal speed" );*/
- /*printf("\nSous option Terminal speed N° 32" );*/
- /*printf ("\n Option Terminal speed sens de requet %d",*(mess_nego12+3));*/
- /*}*/
- /*break;*/
- case 33: {
- printf ("\nOption LFLOW" );
- if (*(mess_nego12+1)==253)
- {
- if((mess_nego12=realloc(mess_nego12,6*sizeof(unsigned char)))==NULL)
- printf("\n Erreur fatal reallocation de memoire OPTION_NEGOCIEE N° 33" );
- *(mess_nego12+0)=255;
- *(mess_nego12+1)=250;
- *(mess_nego12+2)=33;
- *(mess_nego12+3)=1;
- *(mess_nego12+4)=255;
- *(mess_nego12+5)=240;
- /*printf("\nReponse %d %d %d ",*(mess_nego12+0),*(mess_nego12+1),*(mess_nego12+2));*/
- i=write(socket12,mess_nego12,6);
- printf("\nMessage reponse envoyé %d %d %d %d %d %d ",*(mess_nego12+0),*(mess_nego12+1),*(mess_nego12+2),*(mess_nego12+3),*(mess_nego12+4),*(mess_nego12+5));
- }
- }
- break;
- /*case 36: printf("\nOption d'environnement" );*/
- /*break;*/
- default:
- {
- printf("\noption inconnue ou non negociee\nnombre de carateres de mess_nego recu %d:",sizeof(mess_nego12));
- for(i=0;i<sizeof(mess_nego12);i++)
- printf(" i=%d mess_nego= %d",i,*(mess_nego12+i));
- if (*(mess_nego12+1)==251)
- *(mess_nego12+1)=254;
- else
- *(mess_nego12+1)=252;
- printf("\nreponse envoyee: " );
- for(i=0;i<sizeof(mess_nego12);i++)
- printf(" i=%d mess_nego= %d",i,*(mess_nego12+i));
- write(socket12,mess_nego12,sizeof(mess_nego12));
- printf("\nwrite passe" );
- }
- break;
- free(mess_nego12);
- }
- }
- /*Sous option negociee*/
- SOUS_OPTION_NEGOCIEE(mess_nego11,socket11)
- {
- int i,j;
- unsigned char *terminal,*mess_nego13,*rep_mess_nego,*vitesse,DEB_SB,FIN_SB,donnee[4];
- struct termios terminal_out;
- speed_t speed_o,speed_i;
- mess_nego13=mess_nego11;
- DEB_SB=250;
- FIN_SB=240;
- donnee[0]="9";
- donnee[1]="6";
- donnee[2]="0";
- donnee[3]="0";
- printf("\nProcedure SOUS_OPTION_NEGOCIEE sous option a negocier valeur de la SB %d",*(mess_nego13+2));
- switch (*(mess_nego13+2))
- {
- case 24:{
- /*Recuperation d'info sur le treminal*/
- printf("\nSous option Type de terminal actuel: %s,\nlongueur de la chaine terminal %d,\nsizeof de messnego13 %d,\nstrlen+sizeof %d,\nstrlen de messnogo13 %d",terminal=getenv("TERM" ),strlen(terminal),sizeof(mess_nego13),i=(strlen(terminal)+strlen(mess_nego13)),strlen(mess_nego13));
- printf("\nsequence recue taille du message %d %d %d %d %d %d",*(mess_nego13+0),*(mess_nego13+1),*(mess_nego13+2),*(mess_nego13+3),*(mess_nego13+4),*(mess_nego13+5));
- if((mess_nego13=realloc(mess_nego13,(i+1)*sizeof(unsigned char)))==NULL)
- printf("\nrealloc echouee sur SB 24" );
- printf("\ntaille de mess_nego13 %d",strlen(mess_nego13));
- if((terminal=(char*) calloc (strlen(getenv("TERM" )),sizeof (char)))==NULL)
- printf("\nImpossible d'allouer la memoire terminal" );
- terminal=getenv("TERM" );
- *terminal=toupper(*terminal);
- printf("\nterminal =%s",terminal);
- /*strcpy(terminal,getenv("TERM" );*/
- toupper(*terminal);
- printf("\nContenu de terminal :%s",*terminal);
- printf("\nen majuscule" );
- for(j=0;j<(strlen(getenv("TERM" )));j++)
- {
- *(terminal+j)=toupper(*(terminal+j));
- printf("%d %c",j,*(terminal+j));
- }
- strcat(mess_nego13,terminal);
- printf("\nsequence du message modifié %d %d %d %d %d %d ",*(mess_nego13+0),*(mess_nego13+1),*(mess_nego13+2),*(mess_nego13+3)=0,*(mess_nego13+4),*(mess_nego13+5));
- printf("\nchaine de terminal %s",terminal);
- memmove((mess_nego13+4),terminal,strlen(terminal)+1);
- printf("\nsequence recue modifiee %d %d %d %d %c%c%c%c%c%c %d %d %d",*(mess_nego13+0),*(mess_nego13+1),*(mess_nego13+2),*(mess_nego13+3)=0,*(mess_nego13+4),*(mess_nego13+5),*(mess_nego13+6),*(mess_nego13+7),*(mess_nego13+8),*(mess_nego13+9),*(mess_nego13+10)=255,*(mess_nego13+11)=240,*(mess_nego13+12)=0);
- i=write(socket11,mess_nego13,13);
- printf("\nnombre de caracteres ecris= %d\n",i);
- i=write(1,"mess_nego13",13);
- printf("\ndeuxieme valeur de i=%d",i);
- free (mess_nego13);
- }
- break;
- case 32:{
- /*printf("\nSous option Terminal speed" );
- printf("\nsequence recue taille du message %d %d %d %d %d %d %d %d",*(mess_nego13+0),*(mess_nego13+1),*(mess_nego13+2),*(mess_nego13+3),*(mess_nego13+4),*(mess_nego13+5),*(mess_nego13+6),strlen(mess_nego13));
- printf("\nRecuperation de la vitesse du terminal" );*/
- tcgetattr(STDIN_FILENO,&terminal_out);
- speed_o=cfgetospeed(&terminal_out);
- /*printf("\nvitesse du terminal en out %d",speed_o);*/
- if((mess_nego13=realloc(mess_nego13,(strlen(mess_nego13)+11)*sizeof(unsigned char)))==NULL)
- printf("\nrealloc echouee sur SB 32" );
- /*printf("\nmodification du *(mess_nego13+3) %d",*(mess_nego13+3)=0);*/
- i=write(1,"mess_nego13",13);
- free (mess_nego13);
- }
- break;
- case 33:{
- printf("\nSous option LFLOW" );
- printf("\nsequence recue taille du message %d %d %d %d %d %d\n",*(mess_nego13+0),*(mess_nego13+1),*(mess_nego13+2),*(mess_nego13+3),*(mess_nego13+4),*(mess_nego13+5));
- }
- break;
- case 36: printf("\nSous option environnement" );
- break;
- default: printf("\nSous option non negociee" );
- break;
- }
- }
- /*timeout sur connect*/
- TIMEOUT()
- {
- printf("\nDelai d'attente depasse 30s d'ecoule\n\n" );
- raise(SIGTERM);
- }
- extern int errno;
- /*DEBUT DE LA ROUTINE PRINCIPALE*/
- main(argc,argv)
- int argc;
- char **argv;
- {/*Debut du main*/
- unsigned char *buffer_RX,*buffer_TX;
- unsigned char *mess_nego;
- int socket1,connection,deblocage,nb_lu,nb_ec,i,j,k,flag_nego_option,fdisset,verif_select;
- int var_etat,etat;
- struct sockaddr_in addr_distant;
- struct servent *service_distant;
- struct termios term_initial,term_com,sock_ini,sock_com;
- struct timeval delai;
- struct sigaction delai_av,delai_ap,act_time;
- fd_set set;
- flag_nego_option=0;
- /*Preparation des parametres de connection*/
- printf("\nadresse %s",argv[1]);
- service_distant=getservbyname("telnet","tcp" );
- memset(&addr_distant,0,sizeof(struct sockaddr_in));
- addr_distant.sin_family=PF_INET;
- addr_distant.sin_port=htons(service_distant->s_port);
- if((inet_aton(argv[1],&addr_distant.sin_addr.s_addr))==0)
- printf("\nimpossible de remplir le champ s_addr" );
- printf("\nvaleur apres inet_aton() \t%08X",ntohl(addr_distant.sin_addr.s_addr));
- /*Creation du point de communicatio*/
- printf("\ncration de la socket" );
- if((socket1=socket(AF_INET,SOCK_STREAM,0))<0)
- printf("\nCreation de socket echouee" );
- printf("\nNumero de socket \t%d",socket1);
- /*Mis en place du mode non bloquant pour la socket*/
- printf("\nDeblocage de la socket" );
- if((fcntl(socket1,F_SETFL,O_NONBLOCK))<0)
- printf("\nProbleme sur fcntl" );
- printf("\naddr_distant.sin_family \t%d",addr_distant.sin_family);
- printf("\naddr_distant.sin_port\t%d",addr_distant.sin_port);
- printf("\naddr_distant.sin_addr.s_addr\t%s\n",inet_ntoa(addr_distant.sin_addr.s_addr));
- /*Procedure de mis en place du mode non bloquant sur stdin*/
- tcgetattr(STDIN_FILENO,&term_initial);
- tcgetattr(STDIN_FILENO,&term_com);
- term_com.c_iflag &=ICRNL;
- term_com.c_lflag &=~ICANON;/*,ECHONL,ICANON,IEXTEN);*/
- term_com.c_lflag &=~ECHO;
- term_com.c_cc[VTIME]=0;
- term_com.c_cc[VMIN]=0;
- if(tcsetattr(STDIN_FILENO,TCSANOW,&term_com)!=0)
- printf("\ntransformation du terminal echoue" );
- printf("\nPasssage du terminal en mode brut OK" );
- /*Preparation du timer de connexion echouee*/
- printf("\ntentative de connection %d etat = %d",connection=-1,var_etat=0);
- act_time.sa_handler=TIMEOUT;
- act_time.sa_flags=0;
- deblocage=sigaction(SIGALRM,&act_time,0);
- var_etat=alarm(10);
- printf("\nDelai d'attente fixe a %d",var_etat);
- /*Connection au point distant avec 30 secs de delai max*/
- etat=-1;
- while(connection!=0)
- {
- connection=connect(socket1,(struct sockaddr*)&addr_distant,sizeof(addr_distant));
- if (errno==EINPROGRESS&&etat!=1)
- printf("\nDemande de connection Changement de var_etat=%d\n",etat=1);
- if (errno==EALREADY&&etat!=2)
- printf("\nDemande de connection en cours connect %d valeur de errno %s %d de etat=%d",connection,strerror(errno),errno,etat=2);
- if(errno==234)
- {
- var_etat=alarm(0);
- printf("\nconnection OK=%d valeur etat %d",connection=0,etat=3);
- }
- if(connection==0&&etat!=3)
- {
- var_etat=alarm(0);
- printf("\nconnection OK=%d valeur du timeout %d",connection=0,ETIMEDOUT);
- }
- }/*fin de tentative de Connection au point distant*/
- MSG_DE_NEGO(socket1);
- /*on ebtre dans la boucle de communication*/
- while(connection ==0)
- {/*Debut du while 1*/
- /*Initialisation de l'ensemble des descripteurs a multiplexer*/
- FD_ZERO (&set);
- FD_SET (socket1,&set);
- FD_SET (STDIN_FILENO,&set);
- /*Selection de l'ensemble des descripteurs a multiplexer en reception*/
- if((verif_select=select(socket1+1,&set,&set,NULL,&delai))<0)
- break;
- if(verif_select>3)
- printf("\nvaleur de verif_select = % d",verif_select);
- if(FD_ISSET(STDIN_FILENO,&set))
-
- {/*Debut du if*/
- /*Initialisation d un bloc memoire pour un caractere*/
- if((buffer_RX=(char*) calloc (LG_BUFFER,sizeof (char)))==NULL)
- printf("\nImpossible d'allouer la memoire buffer_RX STDIN_FILENO" );
- else memset(buffer_RX,NULL,sizeof (char));
- nb_lu=0;
- if((nb_lu=read(STDIN_FILENO,buffer_RX,LG_BUFFER))<0)
- printf("\nerreur sur lecture d'entree ou rien a ecrire retour de nb_lu %d",nb_lu);
- if(nb_ec=write(socket1,buffer_RX,nb_lu))
- printf ("\nun caractere ecrit sur socket %d",*buffer_RX);
- free(buffer_RX);
- }/*Fin du if*/
- if(FD_ISSET(socket1,&set))
- {/*Debut du if*/
- if((buffer_RX=(unsigned char*) calloc (LG_BUFFER,sizeof (unsigned char)))==NULL)
- printf("\nImpossible d'allouer la memoire buffer_RX pour socket1" );
- nb_lu=0;
- i=0;
- while((nb_lu=recv(socket1,buffer_RX,LG_BUFFER))>=0)
- {/*Debut du while*/
- if(nb_lu==0)
- printf("\nValeur de connection = %d connection fermee par le distant",connection=1);
- if(buffer_RX[0]==255)
- {/*Un caractere IAC est arrive*/
- i=1;
- flag_nego_option=1;
- /**mess_nego=*buffer_RX;*/
- while(flag_nego_option==1)
- {/*debut du while*/
- /*printf ("\nvaleur de i=%d",i);*/
- if((buffer_RX=realloc(buffer_RX,(i+1)*sizeof(unsigned char)))==NULL)
- printf("\nErreur sur attribution memoire" );
- nb_lu=read(socket1,buffer_RX+i,LG_BUFFER);
- if(*(buffer_RX+i)>=236 && *(buffer_RX+i)<255)
- { /*Phase de test 250>IAC<255*/
- ++i;
- if((buffer_RX=realloc(buffer_RX,(i+1)*sizeof(unsigned char)))==NULL)
- printf("\nErreur sur attribution memoire" );
- nb_lu=read(socket1,buffer_RX+i,LG_BUFFER);
- if(buffer_RX[i-1]==250)/*detection de SB*/
- {
- do/*lecture jusqu'a SE*/
- {
- ++i;
- if((buffer_RX=realloc(buffer_RX,(i+1)*sizeof(unsigned char)))==NULL)
- printf("\nErreur sur attribution memoire" );
- nb_lu=read(socket1,buffer_RX+i,LG_BUFFER);
- }while(buffer_RX[i]!=240);
- }
- *(buffer_RX+(i+1))=0;
- NEGOCIATION(buffer_RX,socket1,i);
- }
- flag_nego_option=0;
- free(buffer_RX);
- /*printf("\nle free(mes_nego) est ok valeur de l'adresse mess_nego %d %d\n",mess_nego,*mess_nego);*/
- memset(buffer_RX,0,strlen(buffer_RX));
- ++i;
- } /*fin de while(flag_nego_option)*/
- /*printf("\nfin du if(buffer_RX[0]==255)" );*/
- } /*fin de if(buffer_RX[0]==255)*/
- else
- {/*Debut du else*/
- printf(
- write(STDOUT_FILENO,buffer_RX,nb_lu);
- } /*Fin du else*/
- nb_lu=0;
- }/*fin du while((nb_lu=recv(socket1,buffer_RX,LG_BUFFER))>0)*/
- free(buffer_RX);
- memset(buffer_RX,0,strlen(buffer_RX));
- }/*Fin du if*/
- }/*Fin du while connection*/
- printf("\nSortie de boucle sans raison nb_lu = %d",nb_lu);
- close(socket1);
- if((tcsetattr(STDIN_FILENO,TCSANOW,&term_initial))!=0)
- printf("\nremeise en etat du stdin echoue\n" );
- printf ("\nSortie du prog\n" );
- }/*fin du main*/
|
Quand je le lance ce client telnet je constate des defaut et je ne comprends pas pourquoi.
login: ^@^@^@^@^@^@^@^@
pourquoi au momment de demander le login une suite de caracters est envoyé ce qui m'oblige a taper deux fois le login password?
|