IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

Erreur 10022 RAW Socket


Sujet :

Réseau C

  1. #1
    Membre habitué

    Profil pro
    Inscrit en
    Juin 2009
    Messages
    102
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 102
    Points : 126
    Points
    126
    Par défaut Erreur 10022 RAW Socket
    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.

  2. #2
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Tu utilises sûrement une version de Windows qui n'accepte pas l'envoi de paquets TCP via raw sockets (Windows XP SP2/SP3, Windows Vista, Windows 7). Les seules versions de Windows permettant d'envoyer des paquets TCP via raw sockets sont celles qui sont antérieures à Windows XP SP2 et les éditions "Serveur" (sauf Windows Server 2008 R2). Ex : Windows XP sans service pack, Windows Server 2003, Windows Server 2008.

    [MSDN] TCP/IP Raw Sockets

    Au passage pourquoi dans le tuto il utilise la fonction sendto(), alors qu'il utilise le protocole TCP ?
    D'une part, c'est toujours sendto qu'on utilise lorsqu'on travaille avec les raw sockets et d'autre part, sendto peut être aussi bien utilisé avec des sockets SOCK_STREAM (utilisant TCP par exemple) qu'avec des sockets SOCK_DGRAM par contre send ne peut être utilisé QUE sur des sockets SOCK_STREAM. Lire doc de ces fonctions.

  3. #3
    Membre habitué

    Profil pro
    Inscrit en
    Juin 2009
    Messages
    102
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 102
    Points : 126
    Points
    126
    Par défaut
    Effectivement Melem je me suis rendu compte de cela cette aprem en lisant ton tutoriel d'ailleurs.

    Finalement toutes les réponses a mes questions étaient dedans

    Merci bien.

    A+++.

    EDIT : ha pardon j'oubliais.Il y a t-il des erreurs dans mon code ? Une rapide correction m'aiderais bien.

  4. #4
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    ha pardon j'oubliais. Y a t-il des erreurs dans mon code ? Une rapide correction m'aiderait bien.
    La fonction checksum ne retourne un résultat correct que si l'en-tête pour lequel il est calculé a une taille multiple de 2, ce qui fait l'affaire pour la présente application, mais pas pour toutes les applications. Je crois que c'est tout.

  5. #5
    Membre habitué

    Profil pro
    Inscrit en
    Juin 2009
    Messages
    102
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 102
    Points : 126
    Points
    126
    Par défaut
    Re,

    j'ai de nouveau un problème.En suivant le tutoriel de Melem j'essaye d'envoyer une chaine en utilisant les RAW Socket.

    Sous windows j'y suis arrivé, mais sous Ubuntu j'ai un segment fault au niveau de la 1ere ligne du remplissage de l'entête ip.
    Je pense que cela vient de la fonction checksum, car j'ai repris la fonction de mon 1er post (qui renvois un checksum correct que si la taille de l'entête est multiple de 2).

    Je voudrais donc adapter la fonction checksum du tutoriel de Melem, mais comment adapter les macro HIWORD et LOWORD sous linux ?

  6. #6
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    LOWORD et HIWORD sont des macros qui permettent respectivement d'extraire le mot de poids faible et le mot de poids fort d'une valeur 32 bits. Un mot = 16 bits.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define LOWORD(x) ((unsigned short)((unsigned)(x)))
    #define HIWORD(x) ((unsigned short)(((unsigned)(x)) >> 16))

  7. #7
    Membre habitué

    Profil pro
    Inscrit en
    Juin 2009
    Messages
    102
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 102
    Points : 126
    Points
    126
    Par défaut
    Merci pour ton aide.

    A+++

  8. #8
    Membre habitué
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    289
    Détails du profil
    Informations personnelles :
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2008
    Messages : 289
    Points : 151
    Points
    151
    Par défaut
    bonjour,
    je reprend la discussion en voulant faire un simple écouteur de paquets. Je suis sous XP SP3, de tout ce que j'ai pu lire, la simple écoute est possible.

    J'ai écrit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    sock = gcnew Socket( AddressFamily::InterNetwork,SocketType::Raw,ProtocolType::IP );
    sock->IOControl( IOControlCode::ReceiveAll, inValue, outValue);
    nb = sock->Receive(bytes, bytes->Length, SocketFlags::None);
    J'ai systématiquement l'erreur: "Un argument non alide a été fourni" sur le IOControl et le Receive.

    Une idée? Merci.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. RAW Socket : erreur 10022
    Par Tarnyko dans le forum Réseau
    Réponses: 3
    Dernier message: 05/01/2010, 01h21
  2. Réponses: 15
    Dernier message: 04/01/2007, 11h15
  3. [C#] raw socket?
    Par Blo0d4x3 dans le forum Windows Forms
    Réponses: 2
    Dernier message: 29/12/2004, 12h20
  4. Raw socket
    Par trax44 dans le forum Assembleur
    Réponses: 2
    Dernier message: 24/11/2004, 18h26
  5. raw socket et langage c
    Par SlayDave dans le forum Développement
    Réponses: 2
    Dernier message: 29/08/2002, 19h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo