Bonjour,

Je suis actuellement en train de faire un scanner de port TCP.
Pour cela j'envoie des paquets SYN, mais la checksum que je créé malgré avoir suivi toutes les info de la rfc1071 - TCP n'est pas bonne et Wireshark me le confirme.

J'ai essayé d'envoyer un paquet avec la checksum de Wireshark en dur et ça passe, j'ai une réponse ACK.
Mais là je n'ai pas de réponse car le unsigned short n'a pas la bonne valeur.

Voici mon code:
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
 
unsigned short ComputeChecksum(unsigned char *data, int len)
{
    long sum = 0;  /* assume 32 bit long, 16 bit short */
    unsigned short *temp = (unsigned short *)data;
 
    while(len > 1)
    {
        sum += *temp++;
        if(sum & 0x80000000)   /* if high order bit set, fold */
            sum = (sum & 0xFFFF) + (sum >> 16);
        len -= 2;
    }
 
    if(len)       /* take care of left over byte */
        sum += (unsigned short) *((unsigned char *)temp);
 
    while(sum>>16)
        sum = (sum & 0xFFFF) + (sum >> 16);
 
    return ~sum;
}
 
// Structure du pseudo-en-tête TCP
struct pseudo_header {
    uint32_t source_address;  // Adresse IP source
    uint32_t dest_address;    // Adresse IP destination
    uint8_t placeholder;       // Zéro
    uint8_t protocol;         // Protocole (TCP = 6)
    uint16_t tcp_length;      // Longueur de l'en-tête TCP + données
};
 
// Fonction pour construire un paquet TCP SYN
uint create_syn_packet(char *packet, void *dest, int port, int ipversion, struct in_addr dest_ip, struct in_addr src_ip) {
    if (ipversion == 4) {
        struct tcphdr *tcp_header = (struct tcphdr *)packet;
        struct sockaddr_in *dest_4 = (struct sockaddr_in *)dest;
 
        // Remplir l'en-tête TCP
        memset(tcp_header, 0, sizeof(struct tcphdr));
        ///memcpy(tcp_header, tcp_syn, sizeof(struct tcphdr));
        tcp_header->source = htons(12345);
        tcp_header->dest = htons(port);
        tcp_header->seq = 3093775308;
        tcp_header->ack_seq = 0;
        tcp_header->doff = 5; // 5 * 4 = 20 octets
        tcp_header->syn = 1;
        tcp_header->window = htons(64240);
 
        uint optionlen;
        optionlen = add_tcp_options(packet + sizeof(struct tcphdr));
        tcp_header->doff += (optionlen + 3) / 4;
 
        // Calculer la somme de contrôle
        tcp_header->check = 0;
 
        // Remplir le pseudo-en-tête
        struct pseudo_header psh;
        psh.source_address = *((uint32_t *)&src_ip);
        psh.dest_address = *((uint32_t *)&dest_ip);
        psh.placeholder = 0;
        psh.protocol = IPPROTO_TCP;
        psh.tcp_length = htons(sizeof(struct tcphdr));
 
        // Calculer la somme de contrôle
        int psize;
        psize = sizeof(struct pseudo_header) + sizeof(struct tcphdr) + optionlen;
        char *pseudogram = ALLOC(psize);
 
        // Copier le pseudo-en-tête et l'en-tête TCP dans le tampon
        memcpy(pseudogram, (char *)&psh, sizeof(struct pseudo_header));
        memcpy(pseudogram + sizeof(struct pseudo_header), (char *)tcp_header, sizeof(struct tcphdr) + optionlen);
        // Pas de data
 
        // Calculer la somme de contrôle et l'insérer dans l'en-tête TCP
        tcp_header->check = ComputeChecksum((unsigned char *)pseudogram, psize);
 
        // Libérer la mémoire allouée
        FREE(pseudogram);
        printf("checksum: %u\n", tcp_header->check); ///
 
        return (optionlen);
 
    }
}
Exemple:
Pour le paquet envoyé au port 22 j'ai 0x3dcb alors que Wireshark attend 0x5c62

Avez vous spot une erreur dans mon code?
Merci de m'avoir lu <3