Citation :
 
 #include <winsock2.h>
 #include <ws2tcpip.h>
 #include <iostream.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 //#include <sconio.h>
 #include "Fingerprint.h"
 #include "ip_checksum.h"
   #define MAX_PING_PACKET_SIZE (1024 + sizeof(IPHeader))
     //////////////////////////// setup_for_ping /////////////////////////////////////////
 //   // Crée la structure Winsock nécessaire pour envoyer et recevoir des paquets ping.
 // l'hôte peut être soit une adresse IP soit un nom de machine.
 // ttl c'est le time to live (càd le nombre de rebonds) du paquet.
 // Les deux autres paramètres sont les sorties de la fonction.
 // Elle renvoie -1 si il y a une erreur.
 //
 /////////////////////////////////////////////////////////////////////////////////////
 int setup_tcp(char* host, SOCKET& sd, sockaddr_in& dest)
 {
  
  // Créer la socket
  sd = WSASocket(AF_INET, SOCK_RAW, IPPROTO_TCP, 0, 0, 0);
     if (sd == INVALID_SOCKET)    {
         printf("Erreur pendant la création d'un Rawsocket" );
         return -1;
     }
         // Initialise le bloc d'infos pour la machine destinataire
     memset(&dest, 0, sizeof(dest));
       // Place le premier paramètre passé dans une adresse IP à pinger
     unsigned int addr = inet_addr(host);
     if (addr != INADDR_NONE)    {
         // C'était en IPv4 donc on sauve le résultat
         dest.sin_addr.s_addr = addr;
         dest.sin_family = AF_INET;
     }
     else    {
         // C'est pas un IPv4, donc c'est un nom de machine et on le cherche
         hostent* hp = gethostbyname(host);
         if (hp != 0)    	{
             // Trouvé un nom de machine correspndant donc on sauve l adresse
             memcpy(&(dest.sin_addr), hp->h_addr, hp->h_length);
             dest.sin_family = hp->h_addrtype;
         }
         else    	{
             // Le nom de machine n'est pas reconnu
             printf("Machine introuvable" );
             return -1;
         }
     }
     return 0;
 }
       /////////////////////////// init_ping_packet ///////////////////////////
 //
 // Remplit les champs et les zones de données d'un paquet ICMP, le
 // remplissant au maximum avec des zéros pour s'adapter avec la taille
 // du paquet, en lui donnant la séquence passée en paramètre.   // Ceci complète le paquet, ainsi nous pouvons calculer le checksum du
 // paquet etle mettre dans le champ approprié.
 //
 ////////////////////////////////////////////////////////////////////////
 void init_tcp(TCPHeader* tcp_hdr, int packet_size)
 {
  tcp_hdr->th_dport=htons(1234);
  tcp_hdr->th_sport=htons(1234);
  tcp_hdr->th_seq=31337;    tcp_hdr->th_ack=0;    tcp_hdr->th_lenres=(sizeof(TCPHeader)/4<<4|0);    tcp_hdr->th_flag=2;
  tcp_hdr->th_win=htons(65535);
  tcp_hdr->th_urp=0;    tcp_hdr->th_sum=0;      
    
  // on remplit le champ de données avec 0xCAFEDECA
     const unsigned long int cafedeca = 0xCAFEDECA;
     char* datapart = (char*)tcp_hdr + sizeof(TCPHeader);
     int bytes_left = packet_size - sizeof(TCPHeader);
     while (bytes_left > 0)    {
         memcpy(datapart, &cafedeca, min(int(sizeof(cafedeca)), bytes_left));
         bytes_left -= sizeof(cafedeca);
         datapart += sizeof(cafedeca);
     }
   }
     //////////////////////// Envoi de paquet ICMP /////////////////////////////
 //
 // Envoi un paquet ICMP à l'ordi distant avec la socket sd d'une taille de
 // packet_size octets. Ce n'est pas vérifié pour l'authenticité du paquet,
 // donc il faut vérifier que la taille est d'au moins sizeof(ICMPHeader).
 // Cette fonction retourne  -1 si une erreur apparait.
 //
 ///////////////////////////////////////////////////////////////////////////
 int send_tcp(SOCKET sd, const sockaddr_in& dest, TCPHeader* send_buf, int packet_size)
 {
       // Envoi le paquet par le buffer send_buf
       int bwrote;
  bwrote = sendto(sd, (char*)send_buf, packet_size, 0, (sockaddr*)&dest, sizeof(dest));
     if (bwrote == SOCKET_ERROR)    {
         cerr << "Envoi impossible : " << WSAGetLastError() << endl;
         return -1;
     }
  else    	printf("PAQUET ENVOYE" );
  
     return 0;
 }
     /////////////////////////////// Reception paquet ICMP/////////////////////
 //
 // Reçoit une réponse ICMP sur la socket sd dans le buffer recv_buf et stocke les infos
 // de l'envoyeur dans la source.
 // Retourne -1 sur erreur ou 0 sinon.
 // Notons que le buffer de réception recv_buf doit être plus grand que celui d'émission send_buf
 // parce que le paquet incident possède l'entête IP.
 // Il peut aussi y avoir des options IP ; donc ça n'est pas suffisant de mettre
 // une taille de "sizeof(send_buf) + sizeof(IPHeader)" octets.
 // On a réservé une place beaucoup plus large mais c'est pas grave de perdre de la place.
 //
 ///////////////////////////////////////////////////////////////////////////
 int recv_tcp(SOCKET sd, sockaddr_in& source, IPHeader* recv_buf, int packet_size, char * host)
 {
  int df,fromlen,bread;
       // On attend la réponse à notre requête
     fromlen = sizeof(source);
 /*	bread = recvfrom(sd,(char*)recv_buf,packet_size + sizeof(IPHeader),0,(sockaddr*)&source, &fromlen);
     if (bread == SOCKET_ERROR)    {
         cerr << "Lecture échouée: ";
         if (WSAGetLastError() == WSAEMSGSIZE)    	{
             printf("Tampon trop petit" );
         }
         else    	{
             cerr << "Erreur #" << WSAGetLastError() << endl;
         }
         return -1;
     }*/
    bread = recvfrom(sd, (char*)recv_buf, sizeof(recv_buf), 0, (sockaddr*)&source, &fromlen);      
  
  printf("\n==============================================\n" );
  printf("==Paquet IP/TCP recu de la machine distante==\n" );
  printf("==============================================\n" );
  printf("Version         : %d\n",recv_buf->version);
  printf("Longueur entête : %d\n",recv_buf->h_len);
  printf("Type de service : %d\n",recv_buf->tos);
  if(recv_buf->flags == 0x40)
  	df=1;
  else
  	df=0;
  printf("DF              : %d\n",df);
  printf("Protocole       : %d\n",recv_buf->proto);
  printf("IP SOURCE       : %d.%d.%d.%d\n",*(&recv_buf->ttl + 4),*(&recv_buf->ttl + 5),*(&recv_buf->ttl + 6),*(&recv_buf->ttl + 7));
  printf("IP DEST         : %d.%d.%d.%d",*(&recv_buf->ttl + 8),*(&recv_buf->ttl + 9),*(&recv_buf->ttl + 10),*(&recv_buf->ttl + 11));
  
  
  return 0;
 }
     ///////////////////////////// Decodade de la réponse /////////////////////////////
 //
 // Analyse le paquet reçu. Retourne -1 sur une erreur, -2 si l'on doit réessayer
 // et 0 si pas de problème
 //
 //////////////////////////////////////////////////////////////////////////////////
 int decode_tcp(IPHeader* reply, int bytes, sockaddr_in* from)   {
  // Passe directement à l'entête ICMP en zappant l'entête IP
     unsigned short header_len = reply->h_len * 4;
     TCPHeader* icmphdr = (TCPHeader*)((char*)reply + header_len);
  printf("La fenetre TCP est de : %d\n",icmphdr->th_win);
  printf("Port source : %d\n",icmphdr->th_sport);
  printf("Port dest : %d\n",icmphdr->th_dport);
    return 0;
 }
   /////////////////////////////////////Envoi des paquets/////////////////////
 //
 // envoie un paquet, le recoit et vérifie sa validité, on lui passe en paramètres les
 //paramètres du paquet à envoyer
 //retourne 1 si tout s'est bien passé et -1 si il y a un problème
 //
 ///////////////////////////////////////////////////////////////////////////
 int test_tcp(char* host, int packet_size, SOCKET& sd, sockaddr_in& dest, sockaddr_in& source,
    TCPHeader* send_buf, IPHeader* recv_buf)
 {
  int i=1,delai=0;
  
  if (setup_tcp(host, sd, dest) < 0) //df et tos variables
  {
         delete[]send_buf;
  	delete[]recv_buf;
  	WSACleanup();
  	return -1;
     }
    init_tcp(send_buf, packet_size);
         // Envoi le paquet et reçoit la réponse
     if (send_tcp(sd, dest, send_buf, packet_size) >= 0)
  {
             // Boucle de reception jusqu'à avoir une réponse ou une erreur
             if (recv_tcp(sd, source, recv_buf, MAX_PING_PACKET_SIZE, host) < 0)
    {
                 // On extrait le numéro de séquence de l'entête ICMP. Si c'est mauvais
    	// on en tient compte, sinon on abandonne.
    	unsigned short header_len = recv_buf->h_len * 4;
                 TCPHeader* icmphdr = (TCPHeader*)
      ((char*)recv_buf + header_len);
    }
                              
    if ( (decode_tcp(recv_buf, packet_size, &source) != -2)&&(i))
    {
                 // Réussite ou erreur fatale
                 i = 0;
             }
     }
  else
  	printf("Erreur d'envoi du paquet TCP" );
    return 1;
 }
   |