Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

RAW sockets en C++ sous Windows XP

1 réponse
Avatar
Guillaume Kaddouch
Bonjour,

je me casse les dents depuis qqes jours sur un pb insoluble.
Insoluble ? oui en effet car le meme code en C sous Linux fonctionne a
merveille, et le portage sous Windows pose pb sans que je vois pkoi.

Le but pour l'instant est de creer une RAW socket et de creer une entete
IP, et enfin d'envoyer ce paquet IP vers une IP de mon LAN.
Voisi le code de l'appli win32 console :

#################################
#include <stdio.h>
#include <winsock2.h>

/* definition of IP header version 4 as per RFC 791 */
#define IPVERSION 4

typedef struct IP_HDR
{
unsigned char VerIHL; //Version and IP Header Length
unsigned char Tos;
unsigned short Total_len;
unsigned short ID;
unsigned short off; //Flags 3 bits and Fragment offset 13 bits
unsigned char TTL;
unsigned char Protocol;
unsigned short Checksum;
unsigned long SrcIP;
unsigned long DstIP;
//unsigned long Options_and_Padding;
} IP_HDR;

#define IP_HDR_LEN sizeof(IP_HDR)



void InitWinsock()
{
// variables
WSADATA WSAptr;

// Initialisation
if (WSAStartup(MAKEWORD(2,2), &WSAptr) != 0)
{
MessageBox(0, "initialisation echouée", "erreur", MB_ICONERROR);

}

}


void TerminateWinsock()
{
int res;
res = WSACleanup();
if (res != 0)
{
// ERROR
}
}

int main()
{
// Variables
SOCKET fd;
SOCKADDR_IN dest;
IP_HDR *pckt;
int res;
char * Buffer;

InitWinsock();


//IP header
pckt = (struct IP_HDR *)malloc(sizeof(struct IP_HDR));

pckt->VerIHL = 0x45;
pckt->Tos = 0x00;
pckt->Total_len = 0x05DC;
pckt->ID = 0x78BB;
pckt->off = 0x4000;
pckt->TTL = 0x6C;
pckt->Protocol = 0x00;
pckt->Checksum = 0x45BA;
pckt->SrcIP = inet_addr("192.168.0.1");
pckt->DstIP = inet_addr("192.168.0.2");
printf("paquet rempli\n\n");



// # création du socket #
fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (fd == INVALID_SOCKET)
{
MessageBox(0, "creation du socket echouée", "erreur",
MB_ICONERROR);
}
printf("socket créé\n\n");


// # options du socket #
unsigned int bOpt=1; //debug RAW
if(setsockopt(fd, IPPROTO_IP, 2,(char *)&bOpt,
sizeof(bOpt))==SOCKET_ERROR)
{
MessageBox(0, "options du socket echouée", "erreur", MB_ICONERROR);
}
printf("options appliquées\n\n");


dest.sin_family = AF_INET;
dest.sin_addr.s_addr = INADDR_ANY; //inet_addr("192.168.0.2");
dest.sin_port = 0;

res = bind(fd, (sockaddr *)&dest, sizeof(dest));
if (res == SOCKET_ERROR)
{
res = WSAGetLastError();
printf("bind -> %i\n\n", res);

MessageBox(0, "envois du paquet échoué", "erreur", MB_ICONERROR);
}
printf("bind OK\n\n");






//
//** L'erreur est ICI **//
//


// # envois du paquet #
res = sendto(fd, (const char *)pckt, sizeof(pckt), 0, (sockaddr
*)&dest, sizeof(dest));
if (res == SOCKET_ERROR)
{
res = WSAGetLastError();
printf("sendto -> %i\n\n", res);

MessageBox(0, "envois du paquet échoué", "erreur", MB_ICONERROR);
}
printf("envoi éffectué\n\n");


// # fermeture du socket #
closesocket(fd);
return 0;
}

##################################

Lors du "sendto" j'obtient l'erreur documentée sur MSDN suivante :

WSAEADDRNOTAVAIL
10049

Cannot assign requested address.
The requested address is not valid in its context. This normally
results from an attempt to bind to an address that is not valid for the
local computer. This can also result from connect, sendto, WSAConnect,
WSAJoinLeaf, or WSASendTo when the remote address or port is not valid
for a remote computer (for example, address or port 0).


J'ai beau essayé de 36 façon differentes je retombe tjs sur ce message.
Un ami m'as suggéré que l'entete etait pt etre mal construite, est ce
que ca pourrait etre le pb ?
(le checksum est deliberemment faux, je n'ai pas encore pris le tps de
faire une fonction pour).

Je rappele, le but est just d'envoyer un paquet IP a un poste du meme LAN.

Quelqu'un à t il une idée ?

Merci.

Guillaume.

1 réponse

Avatar
laurent
J'avais cherché des infos sur les raw sockets de windows il y a un moment.
Je crois avoir vu que ces raw sockets n'ont pas un controle absolu des
entetes et ne peuvent manipuler que au delà de l'entête IP. Je n'ai pas
personnellement vérifié, pour les besoins de mon programme j'avais profité
de la déception pour me motiver à tester winpcap. Mais si c'est le cas, ca a
certainement à voir avec tes erreurs.