// ------- Initialisation/Creation de la socket -------
InitWinsock(); // WinSock
int sock=CreateSocket(); // Raw Socket
// ------- En-tete IP ---------------------------------
// malloc pour la structure IP
ip = (struct iphdr *)malloc(sizeof(struct iphdr));
// mise à 0
memset(ip, 0x0, sizeof(struct iphdr));
// longueur de l'en tête IP
ip_len 5; // Par défaut, il est égal à 5 (20 octets), cependant, avec les options de l'entête IP, il peut être compris entre 6 et 15.> sizeof(struct iphdr) / sizeof(unsigned long);
// version d'IPv4
ip_v = 4;
// remplissage de la structure IP
ip->ver_len = (ip_v << 4) | ip_len;
ip->tos = 0; // -> calculé par windows
ip->tot_len = htons (sizeof (struct iphdr) + sizeof (struct tcphdr)); // taille du paquet -> calculé par windows
ip->id = 1;
ip->offset = 0;
ip->ttl = 255; // time to live
ip->protocol = IPPROTO_TCP; // Proto TCP
ip->source = inet_addr("80.119.222.105"); // adresse IP source
ip->destination = inet_addr("66.102.11.104"); // adresse IP de destination
ip->checksum = 0; // on met le champ checksum à 0 avant l'appel de la fonction calculant le checksum
ip->checksum = in_cksum((unsigned short *)ip, sizeof(struct iphdr)); // calcul du checksum avec la fonction
int InitWinsock(void){
WSADATA WSAData; // structure WSADATA définie dans winsock.h
int err;
// Initialise winsock
// Permet à notre application de spécifier la version de Winsock requise et de recevoir les détails des ces spécifications.
// Version : 2.0
if((err = WSAStartup(MAKEWORD(2,0), &WSAData)) != 0) {
// Si la valeur retournée est différente de zéro c'est qu'il y a un problème.
printf("Impossible d'initialiser l'API Winsock\n");
return(-1); // on quitte
}
return(0); // on quitte
}
// Function : Creation de la Raw Socket
SOCKET CreateSocket(void){
int optval = 1;
SOCKET socket; // déclaration de notre socket
// Protocol IP en mode RAW
if ((socket WSASocket(AF_INET, SOCK_RAW, IPPROTO_RAW, NULL, 0,0)) INVALID_SOCKET){
printf("[Error] . Function() Raw Socket : %d\n", WSAGetLastError());
WSACleanup();
exit(-1);
}
// Specification de la socket
if (setsockopt(socket, IPPROTO_IP, 2, (char *)&optval, sizeof(optval)) == SOCKET_ERROR) {
printf("[Error] . Function setsockopt() : %d\n", WSAGetLastError());
WSACleanup();
exit(-1);
}
return(socket); // retourne la socket prête à l'emploi
}
// Function : Calcul de checksum
// -> Pas de moi cette function, glané sur le net - pas d'auteur
// Explication de la rfc :
// Complément à un sur 16 bits de la somme des compléments à un du message ICMP
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);
}
###code
Voilà, quand je lance, ça me donne : "[Error] . Function() Raw Socket : 10004".
A savoir que je compile sous dev-c++, que j'ai bien inclu la librairie libws2_32.a et que 80.119.222.105 était mon ip lors de mes test et 66.102.11.104 une ip prise au harsard.
Chose currieuse, si l'on remplace tous le IPPROTO_TCP par des IPPROTO_ICMP ou IPPROTO_UDP ça marche (mais avec un packet corrompu bien sûr).
Meci.
M.H.