bonjour,
j'ai repris un code source en c pour faire un un ping icmp en utilisant les raw sockets sous windows (XP). L'envoie du ping fontionne bien par contre je n'arrive pas à obtenir le retour. Le problème vient surement de l'utilisation de la fonction recv mais je ne vois pas le pb. Si quelqu'un veut bien m'éclairer

le code source compte 2 parties prog.c et packets .h :
prog.c :
/*
/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/
/- Nom : prog.exe -/
/- Auteur : 4aBestWorld -/
/- Date : 25/01/2007 -/
/- Description : essai ping -/
/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/-/
*/
/*
Les Includes standards
*/
#include <stdio.h>
#include <winsock2.h>
/*
Les Includes de ce programme
*/
#include "packets.h"
/*
directives du PreProcesseur
*/
#pragma comment(lib, "ws2_32.lib")
/*
fonction checksum
*/
unsigned short in_cksum(u_short * addr, int len)
{
register int nleft = len;
register u_short *w = addr;
register int sum = 0;
u_short answer = 0;
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
if (nleft == 1) {
*(u_char *) (&answer) = *(u_char *) w;
sum += answer;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
return (answer);
}
/*
Fonction Main
*/
int main(int argc, char *argv[])
{
WORD wVersionRequested;
WSADATA WSAData;
unsigned short packet_size, ip_version, ip_len; /* Taille de notre paquet, ip version, longueur */
int retour;
int socket; /* Notre Socket */
int optval = 1; /* Pour les options */
struct sockaddr_in sin; /* Notre structure sockaddr_in */
struct iphdr *ip; /* Notre structure ip */
struct icmphdr *icmp; /* Notre structure icmp */
char *ptr = NULL, packet[32]; /* Notre paquet, 32 = sizeof(struct icmphdr) + sizeof(struct iphdr) */
char buffer[2];
if (argc < 3) {
//fprintf(stderr, "Usage: %s <source host> <destination host>\n",argv[0]);
printf("Usage: %s <source host> <destination host>\n",argv[0]);
exit(-5);
}
/* On initialise Winsock 2 */
wVersionRequested = MAKEWORD(2, 2);
if (WSAStartup(wVersionRequested, &WSAData) != 0) {
perror("WSAStartup");
exit(-2);
}
/* Création de notre Raw socket */
socket = WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW, NULL, 0, 0);
if (socket == INVALID_SOCKET) {
perror("WSASocket");
WSACleanup();
exit(-3);
}
/* On assigne les bonnes options à notre Raw socket */
if (setsockopt(socket, IPPROTO_IP, 2, (char *) &optval, sizeof(optval))
== SOCKET_ERROR) {
perror("setsockopt");
WSACleanup();
exit(-4);
}
/* On initialise toutes les données nécéssaires pour la structure IP */
/* Taille de notre paquet */
packet_size = sizeof(struct iphdr) + sizeof(struct icmphdr);
/* On alloue un espace mémoire pour notre structure IP */
ip = (struct iphdr *) malloc(sizeof(struct iphdr));
memset(ip, 0x0, sizeof(struct iphdr));
/* Longueur de l'en tête IP */
ip_len = sizeof(struct iphdr) / sizeof(unsigned long);
/* IP Version */
ip_version = 4;
/* On remplie la structure IP */
ip->ip_verlen = (ip_version << 4) | ip_len;
ip->ip_tos = 0;
ip->ip_tot_len = htons(sizeof(struct iphdr) + sizeof(struct icmphdr));
ip->ip_id = 1;
ip->ip_offset = 0;
ip->ip_ttl = 255;
ip->ip_protocol = IPPROTO_ICMP;
ip->ip_saddr = inet_addr(argv[1]);
ip->ip_daddr = inet_addr(argv[2]);
ip->ip_checksum = 0;
ip->ip_checksum = in_cksum((unsigned short *) ip, sizeof(struct iphdr)); /* Calcul du checksum avec la fonction
déja connu */
/* Maintenant passons à la structure ICMP */
/* On alloue de la mémoire pour celle ci */
icmp = (struct icmphdr *) malloc(sizeof(struct icmphdr));
memset(icmp, 0x0, sizeof(struct icmphdr));
/* On la remplie */
icmp->icmp_type = 8; /* Type ICMP ECHO REQUEST */
icmp->icmp_code = 0;
icmp->icmp_id = (USHORT) GetCurrentProcessId();
icmp->icmp_seq = (USHORT) GetCurrentProcessId();
icmp->icmp_checksum = 0;
icmp->icmp_checksum = in_cksum((unsigned short *) icmp, sizeof(struct icmphdr));
/* Maintenant on créé notre paquet */
ZeroMemory(packet, sizeof(packet));
ptr = packet;
memcpy(ptr, ip, sizeof(struct iphdr));
ptr += sizeof(struct iphdr);
memcpy(ptr, icmp, sizeof(struct icmphdr));
ptr += sizeof(struct icmphdr);
/* On rempli notre structure sockaddr_in */
sin.sin_family = AF_INET;
sin.sin_addr.S_un.S_addr = inet_addr(argv[2]);
/* Envoye du paquet à destination */
if (sendto
(socket, packet, sizeof(packet), 0x0, (struct sockaddr *) &sin,
sizeof(struct sockaddr_in)) == SOCKET_ERROR) {
perror("sendto");
}
/* reception du paquet retour */
else {
retour = recv(socket,buffer,sizeof(buffer),0);
if ( retour == SOCKET_ERROR){
printf("recv : %d",WSAGetLastError());
}//finduif
}//finduelse
system("PAUSE");
free(ip);
free(icmp);
WSACleanup();
return 0;
}
packets.h :
typedef struct iphdr
{
unsigned char ip_verlen;
unsigned char ip_tos;
unsigned short ip_tot_len;
unsigned short ip_id;
unsigned short ip_offset;
unsigned char ip_ttl;
unsigned char ip_protocol;
unsigned short ip_checksum;
unsigned int ip_saddr;
unsigned int ip_daddr;
} IPHDR;
typedef struct icmphdr
{
unsigned char icmp_type;
unsigned char icmp_code;
unsigned short icmp_checksum;
unsigned short icmp_id;
unsigned short icmp_seq;
unsigned long timestamp;
} ICMPHDR;
typedef struct opt_packet
{
char *saddr;
char *daddr;
unsigned int icmp_type;
unsigned int icmp_code;
unsigned int ttl;
int nbpackets;
unsigned int interval;
} OPT_PACKET;
Merci pour votre temps.