Bonjour tout le monde,

J'ai codé en C, un programme qui forge un paquet TCP avec le flag SYN activé. Mais lorsque je sniffe le paquet avec Wireshark, il me dit que le checksum est invalide, qu'aucun flag n'est activé et il me sort un port de destination/source bidon. Je ne vois pas d'ou cela peut venir ni comment résoudre ça. J'ai essayé d'enlever le define __FAVOR_BSD pour voir si cela changeait et que nenni. J'ai fais des recherches et j'ai vu que soi disant il n'y avait pas besoin de faire un checksum du paquet TCP, il sera fait automatiquement par le kernel. J'ai vu aussi une option HDRINCL, mais ça ne change rien, au contraire ça envoi un paquet TCP mais entièrement vide, sans aucune information.

Voici une capture d'écran : Wireshark.
Et voici le code source :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <arpa/inet.h>
#include <string.h>
#include <netinet/ip.h>
#define __FAVOR_BSD
#include <netinet/tcp.h>
 
unsigned short int checksum (unsigned short int *buffer, int size);
 
int main (void) {
	srand(time(NULL));
	int sock = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);
 
	struct sockaddr_in sin;
	sin.sin_addr.s_addr = inet_addr("127.0.0.1");
	sin.sin_family = AF_INET;
	sin.sin_port = htons(80);
	memset(&(sin.sin_zero), 0, 8);
 
	char datagram[4096];
	struct ip* iph = (struct ip*) datagram;
	struct tcphdr* tcph = (struct tcphdr*) datagram + sizeof(struct ip);
	memset(datagram, 0, 4096);
 
	iph->ip_hl = 5;
	iph->ip_v = 4;
	iph->ip_tos = 0;
	iph->ip_len = sizeof(struct ip) + sizeof(struct tcphdr);
	iph->ip_id = htonl(54321);
	iph->ip_off = 0;
	iph->ip_ttl = 255;
	iph->ip_p = 6;
	iph->ip_sum = 0;
	iph->ip_src.s_addr = inet_addr("127.0.0.1");
	iph->ip_dst.s_addr = inet_addr("127.0.0.1");
 
	tcph->th_sport = htons(80);
	tcph->th_dport = htons(80);
	tcph->th_seq = random();
	tcph->th_ack = 0;
	tcph->th_x2 = 0;
	tcph->th_off = 0;
	tcph->th_flags = TH_SYN;
	tcph->th_win = htonl(65535);
	tcph->th_sum = 0;
 
	iph->ip_sum = checksum((unsigned short int*) datagram, iph->ip_len >> 1);
	sendto(sock, datagram, iph->ip_len, 0, (struct sockaddr*)&sin, sizeof(sin));
 
	return 0;
}
 
unsigned short int checksum (unsigned short int *buffer, int size) {
	unsigned long int sum = 0;
 
	while (size > 1) {
		sum += *buffer++;
		size -= sizeof(unsigned short int);
	}
 
	if (size) {
		sum += *(char*)buffer;
	}
 
	sum  = (sum >> 16) + (sum & 0xffff);
	sum += (sum >> 16);
 
	return (unsigned short int)(~sum);
}
Merci par avance de votre aide.