Bonjour à tous,
Je suis confronté à un pb relatif à l'utilisation des socket en mode SOCK_RAW pour forger et envoyer mes propres paquets suivant un protocole donné.
Mon programme compile correctement mais à l'éxécution j'ai un code d'erreur lors de l'utilisation de la fonction "sendto" de winsock2.h: voici mon code

mon message sera certainement long mais c'est pour que vous ayez le max d'infos sur mon code.

Je commence par créer une fonction d'initialisation (sous windows)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
#include <winsock2.h>
#include "structureIP.h" // j'y ai défini les structure IP_HDR et ICMP_HDR
 
int initWinsock2(){
  WORD version;
  WSADATA wsdata;
  int err;
 
  version = MAKEWORD(2, 2);
  err = WSAStartup(version, &wsdata);
  if(err != 0) {
    printf("Erreur d'initialisation");
    return (-1);
  }
  return (0);
}
puis une fonction de création de socket de type raw
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
SOCKET createRawSocket(){
   SOCKET s;
   int optval = 1;
 
   s = WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW, NULL, 0, 0);
   if(s == INVALID_SOCKET){
     printf("Erreur de création de la socket");
     WSACleanup();
     return (-1);
   }
   if(setsockopt(s, IPPROTO_IP, 2, (char*)&optval, sizeof(int)) == SOCKET_ERREOR){
     printf("erreur setsockopt");
     WSACleanup();
     return (-1);
   }
   return s
}
Puis j'ai une fonction d'initialisation du paquet IP et une fonction d'initialisation du paquet ICMP

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 
void initIP_HDR(IP_HDR** p, char* source, char* dest){
    IP_HDR* ip;
    unsigned short packet_size, ip_version, ip_len;
 
    paquet_size = sizeof(ICMP_HDR) + sizeof(IP_HDR);
    ip = (IP_HDR* )malloc(sizeof(IP_HDR));
    memset(ip, 0x0, sizeof(IP_HDR));
    ip_len = sizeof(IP_HDR)/sizeof(unsigned long);
    ip_version = 4;
    ip->tos = 0;
    ip->id = 1
    ...
    ...
 
    (*p) = ip;
}
 
 
void initICMP_HDR(ICMP_HDR** picmp){
    ICMP_HDR* icmp = (ICMP_HDR*)malloc(sizeof(ICMP_HDR));
    memset(icmp, 0x0, sizeof(ICMP_HDR));
    icmp->type = 8;
    icmp->code = 0;
    icmp->id = (unsigned short)GetCurrentProcessId();
    ...
    ...
   (*picmp) = icmp;
}
une fonction d'empaquetage du header IP et ICMP dans un char* de taille 32 octets pour envoyer un message de type ICMP
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
 
char* Empaquetage(IP_HDR* ip, ICMP_HDR* icmp){
    char* ptr, *paquet = (char*)malloc(32 * sizeof(char));
 
    zeromemory(paquet, 32 * sizeof(char));
    ptr = paquet;
    memcpy(ptr, ip, sizeof(IP_HDR));
    ptr += sizeof(IP_HDR); // pour décaller
    memcpy(ptr, icmp, sizeof(ICMP_HDR));
    return ptr;
}
Enfin une fonction pour envoyer le paquet sur le réseau

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
 
void sendmsg(SOCKET s, char* paquet, sockaddr_in* pdest){
    if(sendto(socket, paquet, 32 * sizeof(char), 0x0, (struct sockaddr_in*)pdest, sizeof(struct sockaddr_in)) == SOCKET_ERROR){
    printf("sendto error, Error number: %d\n", WSAGetLastError());
    WSACleanup();
    }
}
et dans le main j'appelle simplement ces fonctions
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 
int main(int argc, char* argv[]){
  initWinsock2(); // Initialisation
  IPHDR* ip; // en-tête ip
  ICMP_HDR icmp; // en-tête icmp
  char* source = "192.168.1.3"; // Adresse source
  char* dest = "192.168.1.4"; // adresse destination
  sockaddr_in sin;
  SOCKET s = createRawSocket();
 
  // initialisation de l'adresse
  memset(&sin, 0x0, sizeof(struct sockaddr_in));
  // Mise en place des paramètres
  sin.sin_familly = AF_INET;
  sin.sin_addr.s_addr = inet(dest);
 
  // Initialisation de l'en-tête ip
  initIP_HDR(&ip, source, dest);
  // Initialisation de l'en-tête icmp
  initICMP_HDR(&icmp);
  // Empaquetage
  paquet = Empaquetage(ip, icmp);
  // Envoi
  sendmsg(s, paquet, &sin);
  free(ip);
  free(icmp);
  system("pause");
  return EXIT_SUCCESS;
}
lorsque je compile il n'ya pas de pb car j'inclu la librairie "libsw2_32.a", mais lorsque j'éxécute le code, j'ai une erreur dans la fonction sendmsg, venant de l'utilisation de sendto qui retourne un SOCKET_ERROR avec le code 10004.Et dans la msdn, la cause est qu'un appel à une fonction bloquante a été supprimée. bref ce code d'erreur 10004 je sais pas comment y remédié.
je travaille avec dev-cpp sous windows XP sp2.