Salut,
depuis peu je regarde les RAW socket via ce tutoriel que j'ai trouvé :
http://mixter.void.ru/rawip.html#3

Et la fonction sendto() me renvoie l'erreur 10022 (argument invalid) et je comprend pas pourquoi.
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
#ifndef IPHEADER
#define IPHEADER
 
typedef struct ipheader
{
    UCHAR ip_hl, ip_v;
    UCHAR ip_tos;
    USHORT ip_len;
    USHORT ip_id;
    USHORT ip_off, ip_flags;
    UCHAR ip_ttl;
    UCHAR ip_p;
    USHORT ip_sum;
    ULONG ip_src;
    ULONG ip_dst;
} IPHEAD;
 
 
typedef struct tcpheader
{
    USHORT th_sport;
    USHORT th_dport;
    UINT th_seq;
    UINT th_ack;
    USHORT th_x2;
    USHORT th_off;
    USHORT th_flags;
    USHORT th_win;
    USHORT th_sum;
    USHORT th_urp;
} TCPHEAD;
 
#define TH_SYN  0x02
 
#endif
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>
 
#include "ipheader.h"
 
#define PORT    25
 
typedef int socklent_t;
 
unsigned short csum(unsigned short *buffer, int nwords)
{
    unsigned long sum;
 
    for(sum = 0; nwords > 0; nwords--)
        sum += *buffer++;
 
    sum = (sum >> 16) + (sum & 0Xffff);
 
    sum += (sum >> 16);
 
    return ~sum;
}
 
int main(void)
{
    WSADATA WSAData;
    int error=  WSAStartup(MAKEWORD(2,2), &WSAData);
 
    if(!error)
    {
        SOCKET sock = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);
        if(sock == INVALID_SOCKET)
            printf("socket() failed \n");
        else
        {
            char datagram[4096];
 
            IPHEAD *iph = (IPHEAD *)datagram;
            TCPHEAD *tcph = (TCPHEAD *)datagram + sizeof(IPHEAD);
 
            SOCKADDR_IN sin;
 
            sin.sin_family      = AF_INET;
            sin.sin_port        = htons(PORT);
            sin.sin_addr.s_addr = inet_addr("127.0.0.1");
 
            memset(datagram, 0, 4096);
 
            /** Remplissage du header ip **/
 
            iph->ip_hl  = 5;                                        /* ip header Len */
            iph->ip_v   = 4;                                        /* ip version (v4) */
            iph->ip_tos = 0;                                        /* ip_ type of service */
            iph->ip_len = sizeof(IPHEAD) + sizeof(TCPHEAD);         /* taille totale du header (ip + tcp) */
            iph->ip_id  = htonl(54321);                             /* ID sequence pour réassembler les datagrams (pou 1 datagrms L'ID pas important) */
            iph->ip_off = 0;                                        /* Pour réasembler les fragments, le 1er fragments tjrs  == 0 */
            iph->ip_ttl = 255;                                      /* ttl = time to live, nombre de router traverser avant abandon (255 val max) */
            iph->ip_p   = 6;                                        /* protocole utilisé dans la couche transport (6 == tcp) **/
            iph->ip_sum = 0;                                        /* checksum, mit a 0 avant l'apel de la fonction csum() */
            iph->ip_src = inet_addr("1.2.3.4");                     /*Addr source.RQ : SYN requete peut etre aveugle (blindly spoofed) */
            iph->ip_dst = sin.sin_addr.s_addr;                      /* ADDR de destination */
 
            printf("iph->ip_len == %d\n", iph->ip_len);
            /** Remplissage du header tcp **/
            tcph->th_sport  = htons(1234);      /*Port source (abitraire) */
            tcph->th_dport  = htons(PORT);      /* destination port */
            tcph->th_seq    = rand();           /* dans u  paquet SYN la sequence est au hzard */
            tcph->th_ack    = 0;                /* N°du ack, les paquet suivant continne le N° précédent.Le 1er paquet est tjrs 0 */
            tcph->th_x2     = 0;                /* Unused, contien des 0 binaire */
            tcph->th_off    = 0;                /* Longeur de l'entête tcp */
            tcph->th_flags  = TH_SYN;           /* Signifie que le client veut initier une connection avec le port de destination */
            tcph->th_win    = htonl(65535);     /* (65535 == max) quantité de bytes envoyer avant que les données soit accépter (ack), et avant envoies d'autres données */
            tcph->th_sum    = 0;                /* si on met a 0 le kernel remplit avec le cheksum correct durant la transmission */
            tcph->th_urp    = 0;                /* si paquet est urgent */
 
            iph->ip_sum = csum((unsigned short*)datagram, iph->ip_len >> 1);
 
            /** verificatioon de l'option IP_HDRINCL (ip_headerinclude), afin d'etre sur que le kernel
                connait le header inclus ds les donnée.ET n'ajoute pas le sien **/
            /** apparement façon pas tres élégante **/
            {
                int one = 1;
                const int *val = &one;
 
                if(setsockopt(sock, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) == SOCKET_ERROR)
                    printf("Warning can't set IP_HDRINCL option\n\n");
            }
 
            /** send data */
            while(1)
            {
                if(sendto ( sock,
                            datagram,
                            iph->ip_len,
                            0,
                            (SOCKADDR*)&sin,
                            sizeof(sin)) < 0)
                {
                    printf("error : %d", WSAGetLastError());
                    exit(1);
                }
                else
                    printf("WONGA !!! ");
            }
        }
 
        closesocket(sock);
    }
 
    WSACleanup();
 
    return 0;
}
Voila un peu d'aide serai la bien venue, car c'est un peu en train de me rendre fou.
Au passage pourquoi dans le tuto il utilise la fonction sendto(), alors qu'il utilise le protocole TCP ?

Merci bien.