Forum Programmation.c Gestion des erreurs de connection UDP

Posté par  .
Étiquettes : aucune
0
11
mar.
2005
Bonjour,

J'écris un programme en C permettant de vérifier si un port est ouvert en TCP ou UDP. Un gros un scanner.

La partie TCP fonctionne parfaitement mais pas pour l'UDP.

voici comment je fais :

value = sendto( sock , bufreq , strlen(bufreq) +1 , 0 , (struct sockaddr *)&server_in , sizeof( server_in ) );
if( value == -1 ){
printf("port fermé\n");
return -1;
}


En fait le port est toujours ouvert même quand il est fermé..
Bref, je dois mal m'y prendre, donc si vous avez un moyen pour savoir si un port UDP est ouvert ou fermé, je vous invite à me le faire connaître s'il vous plaît :)

Merci d'avance
  • # re :scanner

    Posté par  . Évalué à 1.

    utilise connect et selon la valeur de errno tu pouras savoir si le port est fermée ou pas :
    http://www710.univ-lyon1.fr/~jciehl/Public/MAN/man2/connect.2.html
    • [^] # Re: re :scanner

      Posté par  . Évalué à 1.


      if(connect(sock,(struct sockaddr *)&server_in ,sizeof( server_in ))==-1)
      {
      if (perror("connect")==EACESS) fprintf(stderr,le firewall bloque");
      }
  • # Un port doit être ouvert, ou bleu

    Posté par  . Évalué à 6.

    [verbeux]
    Il faut bien distinguer le fonctionnement de TCP, de celui d'UDP. TCP est en mode connecté, ça tout le monde le sait je pense, et c'est le kernel qui s'occupe de la connexion avec l'hôte distant quand on fait un connect().
    En cas de port fermé, il recevera un paquet ICMP d'erreur, ou un timeout, et le signalera au processus appelant en code de retour de connect()
    TCP est aussi en mode "stream", donc a priori les données qu'on envoit avec sendto() peuvent être bufferisées en local, et envoyé en 1 ou plusieurs paquets, restransmises s'il n'y a pas d'acquittement... tout ça est géré par le kernel.
    UDP par contre c'est du bête et méchant: pas de connexion, par de stream, pas de buffer, pas de retransmission. Quand le programme fait un sendto(), ça envoie le paquet tel quel, point barre. Le noyau s'occupe juste de rajouter les entêtes IP et d'envoyer ça sur l'interface réseau qui va bien. Apres c'est plus son problème; si on veut savoir si le paquet est bien arrivé, ou attendre une réponse, c'est au programme de le faire lui-même (avec un select() à timeout suivi d'un recvfrom())

    Le problème c'est que si l'API socket est capable de gérer ces deux protocoles avec les mêmes fonctions, c'est au prix de grande variations sémantiques. Ça peut t'induire en erreur si tu as l'habitude de TCP et que tu continues à raisonner "en TCP"
    connect() par example (pour contredir le post précédent), établit une vraie connexion, gérée par le noyau, si c'est une socket TCP, et renvoie une erreur en cas d'eche. En UDP par contre, c'est juste un raccourci pour éviter de redonner continuellement à sendto() l'adresse du destinataire, aucun échange de paquet ne se fait à ce moment-là et donc connect() marche TOUJOURS.
    sendto() de même va gueuler si la socket TCP n'a pas été connect()ée avant ou a été "reset by peer"; par contre, pour de l'UDP, sendto() marchera TOUJOURS (moyennant peut-etre assez de mémoire kernel pour les buffer et l'existence d'une interface réseau).
    [/verbeux]

    Regarde la page de man de "nmap" '-sU UDP scans', et les sources correspondantes :)

    Résultat: alors que le kernel gere tout en TCP, en UDP il faut tout faire soi-même. En particulier, quand un port destination est fermé, il faut
    récupérer le paquet ICMP d'erreur de retour. Et pour ça, il faut être root...
    (car il faut ouvrir une socket raw pour acceder à ce type de protocole).

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.