Salut à tous,
Voici le code d'un programme qui envoye un ping (ici à Google), mais ne reçoit aucune réponse.
La socket utilisée est du type :
socket(AF_INET,SOCK_RAW,IPPROTO_RAW).
Le même programme marche très bien avec une socket du type :
socket(AF_INET,SOCK_RAW,IPPROTO_ICMP)
Il semblerait donc qu'il y ait un problème dans l'entête IP (peut-être 1 pb de checksum, Network Bytes Order ou firewall).
Si quelqu'un pouvait m'apporter une explication je lui serais très reconnaissant.
=====================================================
#include <stdio.h>
#include <windows.h>
// ------- Structures ip et icmp ----------------------------
typedef struct _IP_HEADER {
unsigned char VS_LET;
unsigned char TOS;
unsigned short Size;
unsigned short ID;
unsigned Flags :3;
unsigned Offset :13;
unsigned char TTL;
unsigned char Proto;
unsigned short Checksum;
unsigned int IP_S;
unsigned int IP_D;
char IP_DATA[1];
} IPHEADER;
typedef struct _ICMP_HEADER{
unsigned char Type;
unsigned char Code;
unsigned short Checksum;
unsigned short ID;
unsigned short SEQ;
char ICMP_DATA[1];
} ICMPHEADER;
// ------- Déclarations ----------------------------
ICMPHEADER * ICMP_HEADER;
IPHEADER * IP_HEADER;
char ip_buf[100],icmp_buf[100],rcv_buf[100];
int Socket_IP;
struct sockaddr_in ip_sock_info;
int lsock=sizeof(struct sockaddr_in);
void START_WS(void); // ---- WSACleanup()
void CLEAR_WS(void); // ---- WSAStartup()
// ----- Calcule le checksum, Nb_S : nombre de Short
unsigned short CALCUL_CHECKSUM(unsigned short * ptr, int Nb_S);
// ------- Main ----------------------------
int main(){
CLEAR_WS();
START_WS();
(char*)ICMP_HEADER=&icmp_buf[0];
(char*)IP_HEADER=&ip_buf[0];
if((Socket_IP=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))==-1)
{printf("[Erreur] Création Socket_IP");getchar(); return;}
ip_sock_info.sin_family=AF_INET;
ip_sock_info.sin_addr.s_addr=inet_addr("216.239.59.99");
// ------ Initialisation de la partie ICMP
ICMP_HEADER->Type=8;
ICMP_HEADER->Code=0;
ICMP_HEADER->ID=1;
ICMP_HEADER->SEQ=1;
ICMP_HEADER->Checksum=0;
memcpy(&ICMP_HEADER->ICMP_DATA,"12345678",8);
ICMP_HEADER->Checksum=htons(CALCUL_CHECKSUM((unsigned short *)ICMP_HEADER,8));
// ------ Initialisation de la partie IP
IP_HEADER->VS_LET=69; // --- (ip_version << 4) | ip_len;
IP_HEADER->TOS=0;
IP_HEADER->Size=htons(36);
IP_HEADER->ID=htons(16);
IP_HEADER->Flags=2;
IP_HEADER->Offset=0;
IP_HEADER->TTL=100;
IP_HEADER->Proto=1;
IP_HEADER->Checksum=0;
IP_HEADER->IP_S=inet_addr("82.65.1.50"); // --- mon ip lors des essais
IP_HEADER->IP_D=inet_addr("216.239.59.99");
IP_HEADER->Checksum=htons(CALCUL_CHECKSUM((unsigned short *)IP_HEADER,10));
memcpy(&IP_HEADER->IP_DATA,&ICMP_HEADER,16);
// --- Envoit de la requète
if(sendto(Socket_IP,(char*)IP_HEADER_X,36,0,(struct sockaddr *)&ip_sock_info,lsock)==-1)
{ printf("[Erreur] sendto socket_ip"); getchar(); return;}
else printf("Sendto socket_ip[ok]\n");
// --- Attente de la réponse
do{
if(recvfrom(Socket_IP,rcv_buf,100,0,NULL,NULL)==-1)
{printf("[Erreur] receivefrom\n"); getchar(); }
else printf("recvfrom [ok]\n");
memcpy(IP_HEADER,&rcv_buf[0],36); // --- on récupère le datagramme ip en entier
memcpy(ICMP_HEADER,&rcv_buf[20],16); // --- on récupère la partie icmp
}
while(ICMP_HEADER->Type!=0);
printf("Session ICMP terminée\n");
getchar();
}