login et password avec Telnet....

J'ai modifié un bout de code pour essayer de me connecter en Telnet sur un PC....

J'y arrive.... des fois :grin:

Mon soucis est que je n'arrive pas à synchroniser la réponse du login et du password avec leurs demande respective, la plupart du temps, le password est écrit avant que la demande en soit faite, ce qui me donne :

connecting to server...
connected
ÿýÿýÿûÿû

login: root
root
Password:

et avec d'autres essais (en changeant le code) :

connecting to server...
connected
ÿýÿýÿûÿû

login: root
root
Password:

root

BusyBox v1.21.0.git (2012-09-09 13:41:47 CEST) built-in shell (ash)
Enter 'help' for a list of built-in commands.

J'ai passé la matinée à essayer de différente manière de faire tomber juste le password, en mettant des if, des flags, en testant le dernier char dans le buffer.... mais le résultat est toujours foireux :grin:

Voici le code expurgé de mes essais:

void loop(){
  if (client.connected()) {  
    checke_page();
   client.println("root");
  }
  else if (millis() - lastAttemptTime > requestInterval) {
    // if you're not connected, and two minutes have passed since
    // your last connection, then attempt to connect again:
    connectToServer();
  }

}

// lit ce qui se trouve sur la page
void checke_page(){ 
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  }
}

// connection au serveur
void connectToServer() {
  flag=0;
  // attempt to connect, and wait a millisecond:
  Serial.println("connecting to server...");
  if (client.connect(server, 23)) {
    Serial.println("connected"); 
  }
  // remettre le compteur a zero pour la prochaine connexion:
  lastAttemptTime = millis();
}

Comment pourrais je attendre l'invitation du login et du password pour remplir les champs, en cas d'interruption de la connection la relancer avec le login et tout le baratin ?
Il faut qu'un fois logguer, je puisse envoyer des commandes prédéfinies ou lire le contenu d'un fichier.

  1. il ne me semble pas que dans ton code tu attende les invites "login:" et "password:"
    Du doit pouvoir utiliser les methods findXxxx() ou readXxxUntil() :
  bool find(char *target);   // reads data from the stream until the target string is found
  // returns true if target string is found, false if timed out (see setTimeout)

  bool find(char *target, size_t length);   // reads data from the stream until the target string of given length is found
  // returns true if target string is found, false if timed out

  bool findUntil(char *target, char *terminator);   // as find but search ends if the terminator string is found

  bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen);   // as above but search ends if the terminate string is found

  size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
  // terminates if length characters have been read, timeout, or if the terminator character  detected
  // returns the number of characters placed in the buffer (0 means no valid data found)

Si tu veux être sûr de ce qu'elles font, le code est dans Stream.cpp

  1. utilise un automate

Effectivement, ce code n'attend rien.... :grin:, mais j'avais fait des essais dans ce sens :grin:

un automate,... comme ceux d'infobarquee ?

XD XD

Appelé aussi "Machine d'état"

enum { WAIT_CONNECT, WAIT_LOGIN, WAIT_PASSWORD, RUNNING } Etat;

void loop()
{
  switch( Etat )
  {
  case WAIT_CONNECT:
    //... ici le code pour se connecter au serveur telnet
    // et quand connecté :
    Etat = WAIT_LOGIN;
    break;
  case WAIT_LOGIN:
    // ... ici le code pour attendre "login:"
    // et quand reçu "login:"
    // envoyer le login puis
    Etat = WAIT_PASSWORD;
    break
... etc , je suis trop fainéant pour continuer
}

Sans oublier la gestion des cas d'erreurs tels que timeout, deconnection, etc ....

Bien la machine d'état XD, mais avant de l'utiliser, il faut que je puisse me connecter cerrectement.... :grin:

Un nouvel essai avec une librairie qui était en .pde :grin: :

/*
 * SimpleClientTextFinder
 *
 */

#include <SPI.h>     
#include <Ethernet.h>
#include <TextFinder.h>

byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,3);
IPAddress server(192,168,1,64);

EthernetClient client;
TextFinder finder( client);

const unsigned long requestInterval = 15000;  // delay between requests
unsigned long lastAttemptTime = 0;   // last time you connected to the server, in milliseconds

void setup()
{
  Ethernet.begin(mac, ip); 
  Serial.begin(9600);
  Serial.println("connecting...");  
  Serial.println(Ethernet.localIP());
  delay(2000);  
}

void loop()
{
  if (client.connected()) {
   // checke_page();
    if(finder.find("login: ")){    
      client.println("root");  
    }
    if(finder.find("Password: ")){    
      client.println("root");       
    }
    checke_page();
  }
  else if (millis() - lastAttemptTime > requestInterval) {
    // if you're not connected, and two minutes have passed since
    // your last connection, then attempt to connect again:
    connectToServer();
  }
}

// lit ce qui se trouve sur la page
void checke_page(){ 
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }
  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  }
}

void connectToServer() {
  // attempt to connect, and wait a millisecond:
  Serial.println("connecting to server...");
  if (client.connect(server, 23)) {
    Serial.println("connected");    
  }
  // remettre le compteur a zero pour la prochaine connexion:
  lastAttemptTime = millis();
}

Essai qui ne fonctionne pô :sweat_smile:

bonjour,
ca y est il copie mes coincs :slight_smile:
sinon tu peux faire une chose comme ca

ouverture connexion
delay(2000);
inscription du login
delay(2000);
inscription du mdp
delay(2000);

J'ai déjà essayé ta solution infobarquee et c'est pas un problème de tempo, mais plus "d'étape".

Jean-François:
J'ai déjà essayé ta solution infobarquee et c'est pas un problème de tempo, mais plus "d'étape".

déjà, est ce qu'en manuel ca fonctionne?
car la solution de find est bonne, expect en bash de mémoire.
as tu vérifié les ports et les logs sur ton server?

EDIT :
ton server est sous quel OS?
si linux, telnet-server est il installé?

En manuel ça fonctionne... c'est le premier truc que j'essaye afin de bien comprendre la cinématique et l'enchainement des commandes.

J'ai fait une machine d'état (merci barbudor) et ça fonctionne jusqu'à un certain point.

enum { WAIT_CONNECT, WAIT_LOGIN, WAIT_PASSWORD, WAIT_INVIT, RUNNING } 
Etat = WAIT_CONNECT;

void loop()
{
  switch( Etat )
  {
  case WAIT_CONNECT:
    //... ici le code pour se connecter au serveur telnet
    Serial.println("connection au serveur telnet...");
    if (client.connect(server, 23)) {
      Serial.println("connecté..."); 
      Etat = WAIT_LOGIN;   
    }
    // remettre le compteur a zero pour la prochaine connexion:
    lastAttemptTime = millis();
    break;
  case WAIT_LOGIN:
    if (client.available()) {
      char c = client.read();
      Serial.print(c);
      stringOne+=c;
    }
    if (!client.connected()) {
      Serial.println();
      Serial.println("déconnecté....");
      client.stop();
      Etat = WAIT_CONNECT;
    }
    // ... ici le code pour attendre "login:"
    if(stringOne.endsWith("login: ")){    
      client.print("root\n");  
      Etat = WAIT_PASSWORD;
    }
    break;
  case WAIT_PASSWORD:
    if (client.available()) {
      char c = client.read();
      Serial.print(c);
      stringOne+=c;
    }
    if (!client.connected()) {
      Serial.println();
      Serial.println("déconnecté....");
      client.stop();
      Etat = WAIT_CONNECT;
    }
    // ... ici le code pour attendre "login:"
    if(stringOne.endsWith("Password:")){    
      client.print("root\n");  
      Etat = WAIT_INVIT;
    }
    break;
  case WAIT_INVIT:
    if (client.available()) {
      char c = client.read();
      Serial.print(c);
      stringOne+=c;
    }
    if (!client.connected()) {
      Serial.println();
      Serial.println("déconnecté....");
      client.stop();
      Etat = WAIT_CONNECT;
    }
    // ... ici le code pour attendre l'invit de commande"
    if(stringOne.endsWith("# ")){    
      Etat = RUNNING; 
      delay(100);
    }
    break;
  case RUNNING:
    // ... ici le code pour faire la commande 
    client.print("date\n");
    delay(100);
    Etat = WAIT_INVIT;
    break;    
  }
}

Je vais jusqu'à l'invitation de commande symbolisée par "#", la commande passe plusieurs fois puis l'affichage se bloque sur "#"

Attente de l'attribution de l'adresse IP:
Mon IP:192.168.1.105
connection au serveur telnet...
connecté...
ÿýÿýÿûÿû

login: root
Password:

BusyBox v1.21.0.git (2012-09-09 13:41:47 CEST) built-in shell (ash)
Enter 'help' for a list of built-in commands.

date

Mon Jan 21 11:15:04 UTC 2013

date

Mon Jan 21 11:15:04 UTC 2013

date

Mon Jan 21 11:15:05 UTC 2013

date

Mon Jan 21 11:15:05 UTC 2013

date

Mon Jan 21 11:15:05 UTC 2013

date

Mon Jan 21 11:15:06 UTC 2013

date

Mon Jan 21 11:15:06 UTC 2013

hummmm,
ca ressemble à un ban.
trop de commandes rapprochées et ton ip est blacklistée.
tu as quoi dans le syslog? peut être la solution.
sinon trouves tu l'ip du nono dans iptables -l ou -l n (j'ai un doute).

Avec #netstat

netstat

Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
...
tcp 0 134 192.168.1.64:23 192.168.1.105:1025 ESTABLISHED
...

La commande netstat ne fait qu'un renvoi puis elle s'arrête, avec ls ça faisait environ 30 renvoi

Si j'utilise netstat depuis une console distante, je peux faire une répétition manuellement toutes les 1/2 seconde, voir plus rapide, et je n'ai pas de problème d'arrêt.
Avec l'arduino, même en mettant des delay() de 3-5 secondes, cela ne change rien.

Jean-François:
Avec #netstat

netstat

Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
...
tcp 0 134 192.168.1.64:23 192.168.1.105:1025 ESTABLISHED
...

La commande netstat ne fait qu'un renvoi puis elle s'arrête, avec ls ça faisait environ 30 renvoi

Si j'utilise netstat depuis une console distante, je peux faire une répétition manuellement toutes les 1/2 seconde, voir plus rapide, et je n'ai pas de problème d'arrêt.
Avec l'arduino, même en mettant des delay() de 3-5 secondes, cela ne change rien.

Salut JF
juste en passant, parce que ce n'est pas ma specialité les reseaux :grin:
mais tu utilise quoi sur l'arduino ? un shield ethernet w1500 ?
si oui, peut etre voir du coté du nombre de sessions ouvertes et/ou de debit, j'avais fait un test (faut que je retrouve le topic) ça ne volait pas tres haut ! 8)

J'utilise le truc officiel... :grin: je crois que c'est le machin "Wquelquechose" en effet XD

4 connexions simultanées, je crois.

dans ce cas de figure, je n'ai qu'une connexion active avec le serveur.

juste en passant comme ca, telnet est un peu désuet face à ssh. :grin:
mais la connexion avec le wtrucmush n'est elle pas en udp au départ?
aucune trace udp avec netstat, mais tcp oui.

vide ton syslog et lance la commande à nouveau et montre le résultat.

Le problème est que le système que j'ai n'a pas de serveur SSH :grin:

Et je ne sais pas où se trouve mon syslog.... va falloir que je cherche :grin: :grin:

si c'est du linux
cat /var/log/syslog
pour installer ssh
sudo apt-get install ssh

Sauf que faut pas compter sur l'Arduino pour faire du crypté.
Donc prendre SSH comme serveur telnet ca n'apporte pas grand chose, à part être à la mode ;).

barbudor:
Sauf que faut pas compter sur l'Arduino pour faire du crypté.
Donc prendre SSH comme serveur telnet ca n'apporte pas grand chose, à part être à la mode ;).

j'aurais appris un truc en plus aujourd'hui sur le nono. :blush: