AntiGuide: ArduinoEthernetBridgeIpFixeHubNonSwitch



PagePrincipale :: DerniersChangements :: ParametresUtilisateur :: Vous êtes 216.73.216.92 :: Signaler un abus :: le: 20250720 07:52:59

20140201
ArduiNo, ArduiNoEthernet

pour cet essai, échec aussi, le diuino disatt voit bien les paquets, mai sne sait as les empècher de suivre leut vie normale!

dans cette variante:

page e limitant à un/es client distants en IP FIE: le gadget a une seule interface ethernet!
en cours de nettoyage
GAFFE déjà écrit une page similaire plus ambitieuse: ArduinoBridgeOverCloud

feuille de route: un ersatz dOpenVpn mettant en communication deux machines/sous réseaux (sur un réseau appelé "zombie" dans la suite de la page).
Les deux mondes sont appelés "dessus" et "dessous" (cosmographie shadock)
RAPPEL: si vous n'êtes pas bricoleur, un couple de LinkSys? Wrt54Gl? en DdWrt fait ça très bien (50 € pièce) donner liens

La solution est fondée sur des boitiers (ci après nommés "gadget") à DEUX prises ethernet (voire à deux adreses sur une prise), je vous laisse les placer entre les couches OSI.

Contraintes sur la prise zombie



configuration "frustre" entre deux machines


variante switch
pareil sauf que le gadget opposé doit intercepter plusieurs adresses mac

variante "routeur": (permet plusieurs machines sur un Switch) de chaque côté



montage deuxième Enc28J60?
selon: http://nathanhein.com/2013/02/getting-arduino-online-with-an-enc28j60/
sous les pattes de l'ada^tateur ethernet plugged

soft "bifide" a l'air de fonctionner, dison, le peuxavec l'ENC28J60 pugged utilier ether ou ethes sur la patte D10
mais le deuxcième(bof, un temps en 6V, peut être grillé!)
en cours


configuration amicale: pour UN invité distant tout se joue sur LE seul LAN du réseau central, la situation est asymétrique

  • machine distante du monde du dessous (isolée de ce monde):
    configuration pour plusieurs machines distantes (isolées d'internet) sur un routeur (PAS UN SWITCH)
    a priori identique au cas précédent, le gadget du dessus prend l'adresse mac de la porte Wan du routeur du dessous
    le routeur est serveur Dhcp piur le sous réseau


    et si les machines de dessous auraient accès à leur réseau local (du dessous)


    et en rêve:
    machine(s) distantes non isolées ?
    pas encore réfléchi!


    emballage des paquets
    voir ArduinoBridgeOverCloud

    les deux gadgets échangent des paquets (TCP ou UDP) qui "emballent" le paquet reçu sur la prise zombie

    SOIT MAXXPKT la longueur maximum d'un paquet .
    SOIT LONTETE: la longueur de l'en-tête du protocole utilisé entre les deux gadgets (54 ?)
    SOIT LONEXTRA: la longueur des information complémentaires , disons 1 octet

    l'emballage contient:
    • un flag disant:
      0: paquet "COURT" (paquet origine de longueur < MAXPKT - LONTETE - LONEXTRA)
      1: réservé pour je ne sais quoi
      2 (ou2, 4, ..., 254): paquet d'en-tête suivi du premier octet du paquet origine)
      3 (ou3, 5, 7, ... 255) paquet "suite" suivi de: des octets 2 à la fin du paquet origine

    chaque arduino
    • connait l'IP de son alter-ego (éventuellement via un service de Dns dynamique )
    • a un port d'accès depuis internet sur la box/routeur
    • aura donc 2 prises ethernet,
      • la première relie au réseau local, RAS
      • la seconde, reliée à la machine/réseau Zombie
        • IP fixe, peut être en 10.... pour bien la différencier de l'habituel 192.168...
        • aucun service asocié

    • à l'arrivé d'un paquet QUELCONQUE sur la prise du réseau ZOMBIE
      • NE REPOND RIEN (même en TCP!) ,
      • l'envoie à homologue dans un paquet TCP ou UDP
        • si le paquet fait moins de MAXPKT - LONTETE - LONEXTRA octets, il est simplement emballé dans un plus gros, avec un drapeau "0"
        • si le paquet fait plus de MAXPKT - LONTETE - LONEXTRA, il est envoyé sous forme de DEUX paqurts
          • l'entête dans un premier paquet , drapeau "2" ou numéro pair
          • le contenu dans un second , drapeau "3" ou numéro impair suivant

    • à la réception d'un paquet sur le port "wan":
      • si drapeau "0": écrit le contenu sur la proe zombie
      • si pair mémorise
      • si impair recrée le paquet avec l'en tête mémorisée

    NOTE:
    • pas de souci de désynchronisation des paquets, en cas de perte, etc..., les couches TCP des machines extrêmes ré-émettront le paquet.

    -

    matériels (du plus timide au moins cher):
    • arduino avec un Enc28J60? et un W5100 (20 €)
    • arduino avec DEUX Ebc28J60? (16 €)
      • consiérant que la librairie de Enc28J60? ne permet pas de créer deux instances, j'étais sur le point d'investir 15 € pour uen carte W5100 ,

    • arduinp avec UN Enc28J60? (13 €)
      • basculer à chaque paquet les IP ?

  • ArduinoProMini ou ArdujinoNanoV3? avec deux Enc28J60?: 11 € (si onpeut traiter directement les paquets dans es mémoires internes de l'Env=c28j-à) ....

    en fait, il doit suffire de DUPPLIQUER la librairie en renommant la seconde.



    brouillon:
    // Simple demo tcpdump http://anntguide.free.fr
    
    #include <EtherCard.h>
    #define Ethernet ENC28J60 
    
    // ethernet interface mac address, must be unique on the LAN
    byte mymac[] = { 0,1,2,3,4,5 };
    //byte PEERIP[4]={81,57,148,97};
    byte PEERIP[4]={192,168,0,235};
    //byte MACCLIENT[6]={3,4,5,6,7,8};
    byte MACCLIENT[6]={0,36,33,7,142,37};  // acer m1641
    byte tampon[2000];
    #define PORT 1000
    #define LAGMACFROM 6
    #define LAGIPFROM 30
    #define MAXLOAD 1300 
    //#define LONPREMS 1300
    #define LONTETEUDP 40 // ntete UDP
    #define PINCS 10
    
    byte ENC28J60::buffer[500];
    uint32_t timer;
    static int biglen;
    int ICMP=1;
    int TCP=0;
    int okmac=0 ; // passe a true si recu un paquet du client
    int okpeer=0; // passe a 1 si pauet (udp, recu de peer)
    int okreste=0 ; // paquet bifide
    int numin=0;
    int numout=0;
    void setup () {
      Serial.begin(9600);
      Serial.println("[Gadget]");
      digitalWrite(10,HIGH);
        Serial.print( "Aaccess Ethernet controller...");
      if (ether.begin(sizeof Ethernet::buffer, mymac,53) == 0) {
        Serial.println( "Failed!");
        return;
      }
        Serial.println( "Succes.!");
      if (!ether.dhcpSetup())
        Serial.println("DHCP failed");
    
      ether.printIp("IP:  ", ether.myip);
      ether.printIp("GW:  ", ether.gwip);  
      ether.printIp("DNS: ", ether.dnsip);  
        
     
     // prtdump("andiamo",10);
     testsendudp();
    }
    
    void testsendudp (){
      tampon[0]=44;
      
         ether.sendUdp((char*)tampon,1,PORT,PEERIP,PORT);
    
    }
    void prhexa(int base,int nb, char *t){
      for (int iii=0;iii<nb;iii=iii+1) {
          Serial.print((byte) ether.buffer[base+iii]);
          Serial.print(" ");
      }
      Serial.print("<-- ");
      Serial.println(t);
    }
    
    void dump (int deb, int fin){
      Serial.print("dump buffer a partir de " );
      Serial.print(deb);
      Serial.print(" à ");
      Serial.println(fin);
      for (int iii=deb;iii<fin;iii=iii+1) Serial.print ((char)ether.buffer[iii]);
      Serial.println("");
       Serial.println("------------------");
      for (int iii=deb;iii<fin;iii=iii+1) { 
           Serial.print (ether.buffer[iii]);
           Serial.print(" ");
      }
       Serial.println("------------------");
    }
    void prtdump(char *tt,int tout){
    Serial.println("------------------");
    Serial.println(tt);
    Serial.println("------------------");
      prhexa(0,6,"to mac ");
      prhexa(6,6,"from mac ");
      prhexa(12,2,"ehr type (8) ");
      prhexa(14,1," version ");
      prhexa(15,1," service ");
      prhexa(16,2," big len ");
     biglen=ether.buffer[16]*256+ether.buffer[17];
     Serial.print("           ");  Serial.print(biglen);Serial.println(" decimal ");
      prhexa(18,2," id ");
      prhexa(20,2," flag ");
      prhexa(22,1," ttl ");
      prhexa(23,1," next ");
      if (ether.buffer[23]==1){ ICMP=1;Serial.println("ICMP");}
      if (ether.buffer[23]==6) {TCP=1;Serial.println("TCP");}
      prhexa(24,2," chk ");
      prhexa(26,4," source ip ");
      prhexa(30,4," dest ip ");
      if (ICMP) {
      prhexa(34,1," type 8 ");
      prhexa(35,1," code 0 ");
      prhexa(36,2," chk ");
      prhexa(38,2," id 4019 ");
      prhexa(40,2," seq num ");
      dump (42,biglen);
      }
      if (TCP) {
      prhexa(34,2," source port ");
      prhexa(36,2," dest port ");
      prhexa(38,4," seq num ");
      prhexa(42,4," ack num ");
      prhexa(46,2," hdr len ");
      prhexa(48,2," reserved ");
      dump (50,biglen);
      }
      
      Serial.println("");
    Serial.println("------------------");
    }
    
    void loop () {
      if (okmac>0) {
      Serial.println("envoyer a peer en 1 ou deux bouts du paquet reçu du clientt");
       // evoyer tout le début
        // void EtherCard::sendUdp (char *data,byte datalen,word sport, byte *dip, word dport) {
          int londeb=okmac;
          int lonsup=-1;
          if (okmac<=MAXLOAD) { 
         }else{
           londeb=MAXLOAD;
           lonsup=okmac-MAXLOAD ; // may be 0!
         }
         
         ether.sendUdp((char*)tampon,londeb,PORT,PEERIP,PORT);
        if (lonsup>=0)  ether.sendUdp((char*)tampon+MAXLOAD,lonsup,PORT,PEERIP,PORT);
         okmac=0;
    //    is il en reste   okreste=1;
        return;
      }
      
     if (okreste) {
      Serial.println("envoyer a peer le este (eventuellement vide) du  paquet client");
        // evoyer le reste
         okreste=0;
    //    is il en reste   okreste=1;
        return;
      }
      
    word q=  ether.packetReceive();
    
     if (q>64) {  prtdump("recu",q);}
    
    if (q>0) {
    Serial.print("recu paquet de lon=");Serial.println(q);
    // tester from mac
    okmac=1;
     for (int imac=0;imac<6;imac=imac+1) if (ether.buffer[LAGMACFROM+imac]!=MACCLIENT[imac])  {
        Serial.print("different a ");Serial.print(ether.buffer[LAGMACFROM+imac]);
        Serial.print("<>"); Serial.print(MACCLIENT[imac]);Serial.print(" at ");Serial.println(imac) ;
        okmac=0;
     }
    if (okmac) { // mettre de côté lepaqut 
     Serial.println("recu paquet de client");
    
     for (int imac=0;imac<q;imac=imac+1) tampon[imac]=ether.buffer[imac];
     okmac=q;
      return;
    }else Serial.println("pas du client");
    
    // tester si paquet vient de peer ?
    okpeer=1;
    for (int iip=0;iip<4;iip=iip+1)    if (ether.buffer[LAGIPFROM+iip]!=PEERIP[iip]) okpeer=0; 
    
    if (okpeer) {
     numin=numin+1;
     Serial.print (numin);
     Serial.print(" recu paquet de peer lon= ");
     Serial.println(q);
    // gaffe si plusieurs
     if (q==MAXLOAD) {
       // conserver 
       for (int iprem=0;iprem<q;iprem=iprem+1) tampon[iprem]=ether.buffer[LONTETEUDP+iprem];
     Serial.println("memorise paquet ==  mMAXLOAD ");
       
       return;
     }
       // copier au bout
     // envoyer tout
    Serial.println("envoyer contenu du paquet  ");
          ether.sendEthernet((char*)tampon+LONTETEUDP,okmac-LONTETEUDP,PORT);
    }
      
    }
    word resu=  ether.packetLoop(q);
    if (resu>0){ Serial.print(resu);
     Serial.println("");}
     }