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

C++ Discussion :

[réseau] erreur création paquet ip


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    309
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 309
    Par défaut [réseau] erreur création paquet ip
    Grâce à un article internet, je me suis lancé dans l'envoi d'un paquet IP/ICMP.
    Voilà que j'ai construit (fortement inspiré du fameux article) :
    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
    struct iphdr *Create_IP4(unsigned char life_time, string ip_source, string ip_dest, link_proto proto){
     
        struct iphdr *ip;
        ip = (struct iphdr *)malloc(sizeof(struct iphdr)); //allocation de l'espace mémoire pour la structure ip
        memset(ip, 0x0, sizeof(struct iphdr)); //on initialise à zéro
     
        unsigned short ip_version = 4;
        unsigned short ip_len = sizeof(struct iphdr) / sizeof(unsigned long);
     
        ip->verlen = (ip_version << 4)| ip_len;
        ip->tos = 0;
        ip->tot_len = htons(sizeof(struct iphdr) + sizeof(struct icmphdr));
        ip->id = 1;
        ip->offset = 0;
        ip->ttl = life_time;
        ip->saddr = inet_addr(ip_source.c_str());
        ip->daddr = inet_addr(ip_dest.c_str());
        ip->checksum = 0;
     
        if(proto == icmp){
            ip->protocol = IPPROTO_ICMP;
        }
     
        ip->checksum = checksum((unsigned short *)ip, sizeof(struct iphdr));
        return ip;
    }
     
     
    unsigned short checksum(unsigned short *buffer, int taille){
     
        unsigned long cksum = 0;
        while(taille < 1){
            cksum += *buffer++;
            taille -= sizeof(unsigned short);
        }
     
        if(taille) cksum += (unsigned char *)buffer;
     
        cksum = (cksum >> 16) + (cksum & 0xffff);
        cksum += (cksum >> 16);
     
        return (unsigned short *)(~cksum);
    }
    J'ai deux problèmes de conversion : dans la fonction checksum
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cksum += (unsigned char *)buffer;
    invalid conversion from `unsigned char*' to `long unsigned int'
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return (unsigned short *)(~cksum);
    invalid conversion from `short unsigned int*' to `short unsigned int'
    Je comprends bien le problème du compilateur mais si je converti comme il veut est-ce que mon code restera valable (pas de problème de dimension lorsqu'il faudra envoyer le paquet)

    J'avoue que je ne comprends pas vraiment le code du calcul de la checksum. Si quelqu'un peux me l'expliquer en détail. (surtout le "cksum += *buffer++;" et le "(cksum >> 16) + (cksum & 0xffff);")
    Je sais que c'est pas très professionnel de demander ce que fait mon propre code mais je débute avec les raw socket.

  2. #2
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Par défaut
    Les problèmes de conversion semblent assez clair :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        unsigned long cksum = 0;
    cksum += (unsigned char *)buffer;
     
     
    unsigned short checksum(....)
    return (unsigned short *)(~cksum);
    Les types ne correspondent pas du tout.

  3. #3
    Membre habitué
    Inscrit en
    Décembre 2006
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 12
    Par défaut
    Déjà pour le calcul du checksum, ça devrais mieux fonctionner comme ça:
    Ensuite pour les problèmes de conversions c'est assez clair non ? Les type de données ne correspondent pas. Il te suffit de caster tes données vers le bon type.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    cksum += *buffer;
    return (unsigned short)(~cksum);
    Après pour les problèmes de dimension, à toi d'adapter tes types en fonction de la taille des données que tu manipules.

    Pour "cksum += *buffer++;" et "(cksum >> 16) + (cksum & 0xffff);" tu devrais revoir les pointeurs et les opérateurs binaires.
    La première ligne réalise la somme de ton buffer : Tant que la taille est supérieure à 1, tu additionne la valeur pointée par buffer puis tu décale ton pointeur sur la valeur suivante.
    Quand à la deuxième elle réalise juste un décalage et un "et" binaire sur ton cksum.

    Et pour ~cksum ça effectue juste un complément binaire.

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Certains casts sont inutiles.
    Il ne faut pas caster inutilement. Je rappelle que caster est une opération dangereuse.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    309
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 309
    Par défaut
    Daccord mais il reste un point que je ne comprends pas. Qu'elle est l'intéret de faire un ET binaire sur le cksum avec un masque 0xffff ? 0xffff correspond à 1111 1111 1111 1111. Donc, soit A n'importe quel bit : AAAA & 1111 = AAAA

    Sinon l'explication du "pourquoi on opère des décalages ?" doit trouver son explication dans la section algorithmique ou la section Google, je m'y intéresserai plus tard.

    Autre petite question comment je peux connaître la dimension en bit d'un type pour mon architecture 32 bits ? (Pour l'heure j'ai juste besoin de savoir si un short int non-signé est codé sur 16 bit mais ça m'intéresserais de connaître les dimensions de tous les types)

    Edit : Est-ce intéressant d'écrire mes paquets directement en hexadécimal ? (pour un gain de temps à l'envoi, pour éviter les casts, pour ma culture personnelle, ...)

  6. #6
    Membre habitué
    Inscrit en
    Décembre 2006
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 12
    Par défaut
    Faire un ET binaire avec le masque 0xffff sur la variable cksum permet de récupérer les 16 bits de poids faible de la variable et de les sommer avec les 16 bits de poids fort obtenus grâce a l'opération de décalage. Si tu te documente sur l'algorithme de calcul du checksum tu verras l'utilité de cette opération.

    Pour la taille d'un unsigned short int, il est probable qu'il soit stocker sur 16 bits mais cela peut varier en fonction des architectures. Pour connaitre la taille exacte sur ton architecture tu peut utiliser "sizeof()" qui te donneras la taille en octets de nimporte quel type de données sur ton architecture.

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

Discussions similaires

  1. Création d'un service réseau : Erreur 1053
    Par eracius dans le forum Windows Serveur
    Réponses: 1
    Dernier message: 22/08/2008, 15h05
  2. Erreur création dynamique de contrôle
    Par thierrybatlle dans le forum Access
    Réponses: 1
    Dernier message: 10/02/2006, 11h00
  3. [SOAP][Web Service] erreur création d'une référence Web
    Par Maximil ian dans le forum XML/XSL et SOAP
    Réponses: 6
    Dernier message: 20/06/2005, 13h29
  4. [Firebird - D7] Erreur - Création dynamique d'une base
    Par EGI dans le forum Bases de données
    Réponses: 5
    Dernier message: 29/03/2005, 14h26
  5. FOXPRO 2.6 : erreur créations du /des fichiers CAB
    Par breihtiti dans le forum Autres SGBD
    Réponses: 2
    Dernier message: 16/11/2002, 11h28

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