             Bibliotheque reseau de Laurent Constantin (lcrzo)

              ----------------------------------------------
              |         BUGS ET LIMITATIONS CONNUS         |
              ----------------------------------------------

 1: Lors de "genemake", affichage de :
     " exec ether_hostton ko
       Warning: vous etes sur une machine avec ether_hostton bogue.
                La bibliotheque lcrzo fonctionnera quand meme, mais
                lisez ../doc/knownproblems_us.txt si vous voulez utiliser le
                contenu de /etc/ethers."
    -- OU --
    "segmentation fault" lors de la conversion d'adresse IP vers
    adresse Ethernet.
 2: Lorsque l'on spoofe au niveau IP, certains paquets refusent de 
    partir sur le reseau.
    -- OU --
    Lorsque l'on spoofe au niveau IP, certains paquets partant sur le 
    reseau ont des valeurs differentes de celles que l'on specifie.
    -- OU --
    Lorsque l'on spoofe au niveau IP, l'adresse ethernet source n'est
    pas affectee correctement (FreeBSD).
 3: Affichage de "linux socket: Too many open files" lors de l'exit().
 4: Affichage de "kernel: programme uses obsolete (PF_INET,SOCK_PACKET)"
    dans "/var/log/messages". Ceci est un message de warning seulement.
 5: Lorsque l'on envoie de tres nombreux paquets au niveau ip
    (c'est a dire par le biais des fonctions lcrzo_sendraw_ip, 
    lcrzo_sendpacket_ipxxx, etc.), le systeme sature.
 6: Erreur a l'ouverture de /dev/bpf0
 7: Les paquets spoofes ethernet ont toujours l'adresse de la carte
    reseau, et non celle que l'on met dans la structure lcrzo_hdrleth.
 8: Ajout de l'adresse de la machine locale a la fin de la liste d'une 
    option IP "record route" ou "timestamp".
 9: Le sniff ne marche pas.
    -- OU --
    Affichage d'une erreur de module net-pf-17 dans /var/log/messages
10: lcrzo est lente



-------------------------------------------------------------------------------
Probleme 1 :
  Synthese du probleme :
    Lors de "genemake", affichage de :
     " exec ether_hostton ko
       Warning: vous etes sur une machine avec ether_hostton bogue.
                La bibliotheque lcrzo fonctionnera quand meme, mais
                lisez ../doc/knownproblems_us.txt si vous voulez utiliser le
                contenu de /etc/ethers."
    -- OU --
    "segmentation fault" lors de la conversion d'adresse IP vers
    adresse Ethernet.
  Environnement concerne par le probleme :
    A- Glibc-2.?? (<2.2.1) avec  "nisplus" dans /etc/nsswitch.conf ou
    B- /etc/ethers existant, mais vide
  Description du probleme :
    A- Le probleme se situe lors de l'appel systeme ether_hostton, lorsque
    l'entree "nisplus" est dans /etc/nsswitch.conf.
    Apres avoir regarde le source de la glibc (2.1.3), j'y ai trouve 
    deux erreurs :
      nis/nss_nisplus/nisplus-ethers.c, ligne 234 : 
        Il y a "if (name != NULL)" au lieu de "if (name == NULL)"
      inet/ether_hton.c, ligne 76 :
        fct a seulement 4 parametres au lieu de 5.
    Note : les developpeurs de glibc ont ete informes de ce bug. Ils ont 
           integre le patch dans la glibc 2.2.1.
    B- Glibc provoque une erreur si /etc/ethers existe, mais ne contient 
    aucune ligne.
  Solution 1 :
    A- Editer /etc/nsswitch.conf afin de mettre la ligne :
         ethers: files
    au lieu de :
         ethers: nisplus [NOTFOUND=return] files
    En effet, le probleme disparait en supprimant "nisplus" de
    /etc/nsswitch.conf.
    Vous pouvez ensuite refaire un genemake (puis recompiler et 
    reinstaller) afin de prendre en compte le fait que ce bug
    soit corrige.
  Solution 2 :
    A- Installez la glibc >2.2.1
  Solution 3 :
    B- Effacer le fichier /etc/ethers si il ne sert a rien

-------------------------------------------------------------------------------
Probleme 2 :
  Synthese du probleme :
    Lorsque l'on spoofe au niveau IP, certains paquets refusent de 
    partir sur le reseau.
    -- OU --
    Lorsque l'on spoofe au niveau IP, certains paquets partant sur le 
    reseau ont des valeurs differentes de celles que l'on specifie.
    -- OU --
    Lorsque l'on spoofe au niveau IP, l'adresse ethernet source n'est
    pas affectee correctement (FreeBSD).
  Environnement concerne par le probleme :
    Linux avec IP firewalling
    Solaris
    FreeBSD
    [je suppose que tous les environnements sont plus ou moins sensibles]
  Description du probleme :
    D'une maniere generale, il y a deux niveaux auxquels on peut
    spoofer :
     - niveau ethernet : on specifie les adresses ethernet, ip, etc.
     - niveau ip : on specifie les adresses ip, etc., et la pile IP 
                   du systeme se charge de trouver les adresses ethernet
    Le probleme reside dans le fait que certains systemes d'exploitation
    cherchent a verifier la legitimite du paquet que l'on desire envoyer.
    Lorsque le paquet est incorrect, il est alors jete par le systeme.
    Certains systemes changent meme les valeurs que l'on desire (par 
    exemple, Solaris change hdrlip.id, hdrlip.dontfrag, etc.).
    D'autres, ne mettent pas a jour correctement l'adresse ethernet
    source (FreeBSD).
  Solution 1 :
    La solution generique consiste a spoofer au niveau ethernet
    afin de contourner la pile IP du systeme :
     -en utilisant : lcrzo_spoof_set_useethforip(&spoof, LCRZO_TRUE);
     -ou en utilisant lcrzo_sendraw_eth, et toutes les fonctions en
      dependant (lcrzo_sendpacket_ethipoptdata, 
      lcrzo_sendpacket_ethipoptudpdata, etc.).
  Solution 2 :
    Sous Linux, il faut compiler le noyau sans l'IP firewalling 
    pour pouvoir emettre des paquets malformes. Sinon, le message
    d'erreur suivant apparait : "erreur lors de l'appel a la fonction
    sendto()"

-------------------------------------------------------------------------------
Probleme 3 :
  Synthese du probleme :
    Affichage de "linux socket: Too many open files" lors de l'exit().
  Environnement concerne par le probleme :
    Linux avec libpcap 0.5
  Description du probleme :
    La fonction "linux_restore_ifr" de "pcap-linux.c" est appelee
    lors de la terminaison du programme (programmation par "atexit()").
    Cette fonction utilise un descripteur de fichier, mais ne le ferme
    jamais.
    Note : les developpeurs de libpcap ont ete informes de ce bug.
  Solution 1 :
    Installez une version > 0.6 disponible a l'adresse 
    http://www.tcpdump.org/
  Solution 2 :
    Si vous utilisez libpcap<0.6, il faut modifier la fonction 
    "linux_restore_ifr" de "pcap-linux.c" :
      void linux_restore_ifr(void)
      { register int fd;
        fd = socket(PF_INET, SOCK_PACKET, htons(0x0003));
        if (fd < 0)
          fprintf(stderr, "linux socket: %s", pcap_strerror(errno));
        else if (ioctl(fd, SIOCSIFFLAGS, &saved_ifr) < 0)
          fprintf(stderr, "linux SIOCSIFFLAGS: %s", pcap_strerror(errno));
        /*et ici, il n'y avait pas de close*/
        close(fd); /*rajoute par Laurent dans libpcap.*/
      }
    Puis il faut recompiler et reinstaller libpcap.

-------------------------------------------------------------------------------
Probleme 4 :
  Synthese du probleme :
    Affichage de "kernel: programme uses obsolete (PF_INET,SOCK_PACKET)"
    dans "/var/log/messages". Ceci est un message de warning seulement.
  Environnement concerne par le probleme :
    Linux noyau superieur a 2.1
    libpcap jusqu'a 0.5rel2.
  Description du probleme :
    La bibliotheque libpcap utilise une socket {PF_INET,SOCK_PACKET}
    du noyau, et c'est cette interface qui est obsolete.
    Note : les developpeurs de libpcap ont ete informes de ce bug.
  Solution 1 :
    Installez une version > 0.6 disponible a l'adresse 
    http://www.tcpdump.org/
  Solution 2 :
    Le message etant un warning, il peut etre ignore.

-------------------------------------------------------------------------------
Probleme 5 :
  Synthese du probleme :
    Lorsque l'on envoie de tres nombreux paquets au niveau ip
    (c'est a dire par le biais des fonctions lcrzo_sendraw_ip, 
    lcrzo_sendpacket_ipxxx, etc.), le systeme sature.
  Environnement concerne par le probleme :
    Linux
    probablement d'autres systemes
  Description du probleme :
    Pour la fonction lcrzo_sendraw_ip, on passe le paquet au systeme
    et on le laisse se debrouiller.
    Si l'adresse ethernet de la machine destination (ou du routeur
    correspondant) ne peut pas etre determinee, le systeme stocke
    les paquets passes a lcrzo_sendraw_ip. Ces paquets, que le systeme
    espere pouvoir envoyer ulterieurement, sont gardes pendant
    quelques dizaines de secondes. Cependant, si l'on mene une 
    attaque de style deni de service, la memoire occupee par ces
    paquets peut rapidement (5 secondes) saturer. Il faut donc
    s'assurer que les paquets utilises dans le cas d'un deni de service
    partent reellement sur le reseau (c'est a dire que la destination
    soit joignable), sinon on fait un deni de service sur la machine
    locale ;).
    En synthese, lorsque l'on envoie au niveau IP, comme c'est le systeme
    qui gere, il faut que le systeme soit bien configure, sinon les paquets
    ne partent pas sur le reseau.
    Un autre cas a ete identifie sur les machines tres puissantes :
    le systeme accepte de traiter plus de paquets qu'il ne le peut
    reellement. Le systeme se met alors aussi a saturer.
  Solution 1 :
    (machine destination sur le LAN)
     - Si l'adresse destination est une machine qui existe 
       sur le LAN, il faut verifier qu'elle soit dans le cache
       ARP ("arp -an"). Dans le cas contraire, faire un ping 
       vers cette machine pour s'assurer qu'elle existe.
     - Si l'adresse destination est une machine inexistante, il faut
       lui affecter une fausse entree dans la table arp 
       ("arp -s machine a:a:a:a:a:a").
  Solution 2 :
    (machine destination derriere un routeur)
     - D'abord, il faut verifier que le routeur soit dans le cache
       ARP ("arp -an"). Dans le cas contraire, faire un ping 
       vers le routeur pour s'assurer qu'il existe.
     - Puis, s'assurer que les routes soient correctes, en faisant
       par exemple un ping vers la machine destination.
  Solution 3 :
    (configuration OK, mais machine puissante)
    Le probleme principal est qu'il n'y a pas de moyen de voir
    que le noyau est en train de se saturer. Quand on s'en rend compte
    (errno==ENOBUFS), il est deja trop tard.
    Une solution est de ralentir la cadence d'emission en utilisant
    lcrzo_time_sleep. Par exemple, on peut faire une pause tous les
    1000 paquets envoyes. Le souci est que le temps de pause est 
    fonction du systeme (cpu, memoire, carte reseau, etc.).
    Si vous avez une bonne solution a ce probleme, n'hesitez pas a
    me contacter.

-------------------------------------------------------------------------------
Probleme 6 :
  Synthese du probleme :
    Erreur a l'ouverture de /dev/bpf0
  Environnement concerne par le probleme :
    FreeBSD 3.1
  Description du probleme :
    Par defaut, bpf n'est pas compile dans le noyau. On ne peut donc
    pas sniffer les paquets du reseau.
  Solution :
    Il faut compiler le noyau avec bpf en mettant dans le 
        fichier /usr/src/sys/i386/NOYAU :
             "pseudo-device bpfilter 4"
    Puis, il faut creer les devices (en creer autant que specifie
    ci-dessus : 4 ; on peut en mettre plus):
        cd /dev
        sh MAKEDEV bpf0    (si il n'existe pas deja)
        sh MAKEDEV bpf1
        sh MAKEDEV bpf2
        sh MAKEDEV bpf3

-------------------------------------------------------------------------------
Probleme 7 :
  Synthese du probleme :
    Les paquets spoofes ethernet ont toujours l'adresse de la carte
    reseau, et non celle que l'on met dans la structure lcrzo_hdrleth.
  Environnement concerne par le probleme :
    FreeBSD 3.1
  Description du probleme :
    Le noyau BSD qui ne permet pas de spoofer au niveau ethernet.
  Solution :
    Il faut modifier le source du noyau et le recompiler. Le repertoire
    "./port/FreeBSD/patchkernelspoofethernet" contient le patch
    necessaire. [je n'ai teste ce patch qu'avec FreeBSD 3.1]

-------------------------------------------------------------------------------
Probleme 8 :
  Synthese du probleme :
    Ajout de l'adresse de la machine locale a la fin de la liste d'une 
    option IP "record route" ou "timestamp".
  Environnement concerne par le probleme :
    Linux noyau inferieur a 2.1
  Description du probleme :
    Lors du sniff des options de type "record route" et "timestamp",
    mene par l'intermediaire de la bibliotheque libpcap, la machine qui
    sniffe rajoute son adresse en fin de liste.
    Cela semblerait logique, mais quand on sniffe, on desire voir
    ce qui passe sur le reseau, et non des paquets modifies par le systeme
    de la machine locale (le pire, c'est que le checksum n'est pas
    recalcule par le systeme).
    La bibliotheque libpcap utilise une socket {PF_INET,SOCK_PACKET}
    du noyau, et c'est cette interface qui est erronee.
  Solution :
    La version 2.1 du noyau corrige ce probleme.

-------------------------------------------------------------------------------
Probleme 9 :
  Synthese du probleme :
    Le sniff ne marche pas.
    -- OU --
    Affichage d'une erreur de module net-pf-17 dans /var/log/messages
  Environnement concerne par le probleme :
    Linux
  Description du probleme :
    Le noyau doit etre compile avec le support de "packet socket" 
    (CONFIG_PACKET) pour pouvoir sniffer.
  Solution :
    Vous devez compiler votre noyau avec "packet socket" :
     - cocher la case 'Packet socket' du menu 'Networking options'
       de l'interface graphique de configuration du noyau (make xconfig), ou
     - editer /usr/src/linux/.config afin d'y mettre :
       CONFIG_PACKET=y
    Le noyau doit ensuite etre recompile et installe.

-------------------------------------------------------------------------------
Probleme 10 :
  Synthese du probleme :
    lcrzo est lente
  Environnement concerne par le probleme :
    Tous
  Description du probleme :
    J'ai choisi de creer une bibliotheque tres modulaire et simple
    a maintenir. L'une des consequenses est le nombre important de
    fonctions imbriquees. Lorsque l'on desire gerer un flux de donnees
    important, la machine est surchargee.
  Solution 1 :
    lcrzo propose des fonctionnalites permettant de preconstruire
    les paquets a envoyer sur le reseau, puis de les sauvegarder
    dans des fichiers (cf. lcrzo_record.h).
  Solution 2 :
    Vous pouvez aussi n'utiliser que les fonctions de tres bas niveau
    et construire votre code specifique autour de ces fonctions.
    Si c'est toujours trop lent, alors il faut que vous utilisiez
    directement les fonctions systeme, ou que vous achetiez
    une plus grosse machine ;-)


***************************************************************************
                            BUGS NON IDENTIFIES
                            *******************

Si vous trouvez des erreurs, merci de me prevenir. 
Pour chaque rapport d'anomalie, indiquez si possible :
 - version de lcrzo (tapez lcrzoex sans parametre)
 - systeme d'exploitation (uname -a)
 - commande/contexte de l'erreur
 - comment reproduire l'erreur
 - autres informations que vous jugez utile

Mon adresse figure sur mon site web :
  http://www.laurentconstantin.com/     (serveur principal)
  http://go.to/laurentconstantin/       (serveur de secours)
  http://laurentconstantin.est-la.com/  (serveur de secours)
