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 :

checksum icmp et ip !


Sujet :

Réseau C

  1. #1
    Membre du Club
    Étudiant
    Inscrit en
    Juin 2010
    Messages
    82
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2010
    Messages : 82
    Points : 57
    Points
    57
    Par défaut checksum icmp et ip !
    salut a tous j'ai un soucis avec le calcul du checksum .

    j'utilise une fonction checksum() pour le calcule de cette somme , pour lentete IP la somme est bien correcte mais cette meme fonction , la somme ICMP est pas correcte je comprend pas pourquoi .

    puis je avoir un peu d'aide ? ( jutilise winpcap sous vc++ 06 )

    ou savoir si avec cette libcat (winpcap) y'a une fonction pour calculer ce checksum .

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Avec si peu d'infos, c'est difficile.

    Toutefois, on peut quand même signaler que si ces deux checksums se calculent de la même façon, les longueurs des entêtes sur lesquels elles portent ne sont pas les mêmes. Est-ce que passe bien la longueur des données à balayer à ta fonction checksum() ?

  3. #3
    Membre du Club
    Étudiant
    Inscrit en
    Juin 2010
    Messages
    82
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2010
    Messages : 82
    Points : 57
    Points
    57
    Par défaut
    merci pour ta reponse .

    voila la fonction que j'utilise

    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
     
    USHORT checksum(void * lpData, size_t size)
    {
        USHORT * t = lpData;
        DWORD somme = 0;
        size_t i, n = size / sizeof(USHORT);
     
        for(i = 0; i < n; i++)
            somme += t[i];
     
        if (size % 2)
        {
            UCHAR * u = lpData;
            somme += u[size - 1];
        }
     
        while (HIWORD(somme))
            somme = HIWORD(somme) + LOWORD(somme);
     
        return LOWORD(~somme); 
    }

    appeler de cette facon

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ip.somme      = checksum( &ip, sizeof(ip) );
    et en utilisant pour ICMP

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    icmp.Sommecontrole      =checksum( (&icmp, sizeof(icmp));
    j'obtiens bien une somme mais wireshark (en sniffant mon packet) me donne valeur incorrect ce qui empeche lenvoi reel de mon packet a destination .

    donc je me demandais peut etre qu'il fallait inclure d'autre element aux 2eme argument de la fonction checksum .

    enfin je suis perdu, sur ce site http://www.frameip.com/entete-icmp/ , l'exemple donné je vois pas comment l'appeler dans mon code (enfin les arguments a lui donné ) .

  4. #4
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 193
    Points : 28 077
    Points
    28 077
    Par défaut
    Ton code me semble correct.

    Le code de l'exemple traduit dans ton code donne ceci :
    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
    unsigned short checksum(unsigned short *lpData, int size)
        {
        unsigned long somme=0;
        // ********************************************************
        // Complément à 1 de la somme des complément à 1 sur 16 bits
        // ********************************************************
        while(size>1)
            {
            somme = somme + *lpData++;
            size = size - sizeof(unsigned short);
            }
     
        if(size)
            somme = somme + *(unsigned char*)lpData;
     
        somme = (somme >> 16)+(somme & 0xffff);
        somme = somme + (somme >> 16);
     
        return (unsigned short)(~somme);
        }
    NOTA : La RFC indique "Complément à 1 de la somme des complément à 1 sur 16 bits" mais il semble que c'est plutôt "Complément à 1 sur 16 bits de la somme mots de 16 bits"


    On va voir sur un exemple :
    Soit la trame ICMP suivante (uniquement la partie ICMP, pas la partie IP) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    08 00 ?? ??  00 01 00 01 61 62 63 64 65 66 67 68
    69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 61
    62 63 64 65 66 67 68 69
    on va donc faire la somme de 0800+0000+0001+0001+6162+....
    Ce qui va nous donner : 6B29F
    On travaille sur 16 bits mais on conserve la retenue, donc on fait B29F+6 = B2A5 (si cette comme génère à nouveau une retenue faut recommencer jusqu'à tenir sur uniquement 16 bits)

    Ensuite on fait le complément à 1 de B2A5 ==> 4D5A, qui était bien le checksum attendu.
    --- Sevyc64 ---

    Parce que le partage est notre force, la connaissance sera notre victoire

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Citation Envoyé par sevyc64 Voir le message
    NOTA : La RFC indique "Complément à 1 de la somme des complément à 1 sur 16 bits" mais il semble que c'est plutôt "Complément à 1 sur 16 bits de la somme mots de 16 bits"

    On travaille sur 16 bits mais on conserve la retenue, donc on fait B29F+6 = B2A5 (si cette comme génère à nouveau une retenue faut recommencer jusqu'à tenir sur uniquement 16 bits)
    C'est plus subtil encore : c'est le complément à 1 de la somme des « nombres de 16 bits en représentation complément à 1 ».

    Je ne m'étais jamais réellement penché sur le cas et ça m'a donné l'occasion de me replonger dans la lecture desdites RFC, notamment la RFC 1071 ainsi que ceci.

    En gros, on considère que l'on change de signe en inversant tous les bits mais sans ajouter le +1 qui suit. Ce qui fait que « -1 » est représenté par « FFFE » plutôt que par « FFFF ». Ça, d'accord. La difficulté consiste à faire les calculs en tenant compte de ces signes et à rendre un résultat correct selon les mêmes règles. Et il est précisé notamment dans la RFC que sur les machines à complément à 2 (les additions binaires ordinaires que l'on connaît), cela se fait en additionnant tous les mots puis en ajoutant la retenue, soit la partie qui déborde, au résultat.

    Citation Envoyé par Shark9 Voir le message
    merci pour ta reponse .

    j'obtiens bien une somme mais wireshark (en sniffant mon packet) me donne valeur incorrect ce qui empeche lenvoi reel de mon packet a destination .

    donc je me demandais peut etre qu'il fallait inclure d'autre element aux 2eme argument de la fonction checksum .
    Deux remarques :

    • Quand tu calcules un checksum Internet, tu passes en revue l'entête entière qui contient justement le checksum que tu cherches à calculer. Il est précisé dans la RFC que ce champ « checksum » doit être mis à zéro avant les calculs. Est-ce que tu as bien pris soin de le faire, dans un cas comme dans l'autre ?
    • Un datagramme ICMP est encapsulé dans un paquet IP (même si ces deux protocoles sont censés être au même niveau du point de vue OSI). Or, le checksum ICMP ne s'appuie que sur l'entête ICMP et pas sur l'entête IP qui le précède. Est-ce que, là encore, cette condition est vérifiée chez toi ?

  6. #6
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 193
    Points : 28 077
    Points
    28 077
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    C'est plus subtil encore : c'est le complément à 1 de la somme des « nombres de 16 bits en représentation complément à 1 ».
    Oui c'est ce que dit la RFC mais lorsque tu regarde les bouts de code parfois fournis ou que tu calcule toi même le checksum à partir d'une trame correcte interceptée (dont tu connais donc le checksum à obtenir) tu te rend compte qu'il ne faut pas faire la somme des « nombres de 16 bits en représentation complément à 1 » mais bien la somme « nombres de 16 bits » directs.

    Citation Envoyé par Obsidian Voir le message
    En gros, on considère que l'on change de signe en inversant tous les bits mais sans ajouter le +1 qui suit. Ce qui fait que « -1 » est représenté par « FFFE » plutôt que par « FFFF ».
    Oui, c'est la définition même du complément à 1. On inverse les bits, 0 devient 1 et 1 devient 0.
    --- Sevyc64 ---

    Parce que le partage est notre force, la connaissance sera notre victoire

  7. #7
    Membre du Club
    Étudiant
    Inscrit en
    Juin 2010
    Messages
    82
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2010
    Messages : 82
    Points : 57
    Points
    57
    Par défaut
    e checksum ICMP ne s'appuie que sur l'entête ICMP et pas sur l'entête IP qui le précède. Est-ce que, là encore, cette condition est vérifiée chez toi ?

    - oui la fonction est parametrer pour calculer que le checksum de lentete icmp comme dans le code plus haut .



    doit être mis à zéro avant les calculs. Est-ce que tu as bien pris soin de le faire, dans un cas comme dans l'autre ?


    - oui je prend le soin de bien le mettre a 0 avant le calcul et pourtant le checksum eu en resultat est incorrecte , donc est pour cela que j'aurai aimé savoir comment faut faire le calcule pour obtenir le checksum que wireshark conseil .


    merci de vos reponses

  8. #8
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par sevyc64 Voir le message
    Oui c'est ce que dit la RFC mais lorsque tu regarde les bouts de code parfois fournis ou que tu calcule toi même le checksum à partir d'une trame correcte interceptée (dont tu connais donc le checksum à obtenir) tu te rend compte qu'il ne faut pas faire la somme des « nombres de 16 bits en représentation complément à 1 » mais bien la somme « nombres de 16 bits » directs.
    Non. On fait bien la "somme complément aux uns" des nombres de 16 bits. Autrement dit, la somme en considérant que les nombres de 16 bits sont des entiers signés en représentation en complément aux uns et en représentant le résultat en complément aux uns. Quand on ne dispose qu'une somme non signée (ou en complément à deux, le fait que ce soit la même est une des raisons qui ont fait du complément à deux la représentation dominante, un ordinateur fonctionnant en complément aux 1 a deux instructions d'addition -- s'il fournit une somme non signée, tous ne l'ont pas fait -- tout comme un ordinateur fonctionnant en complément à 2 a deux instructions de multiplication) une telle somme se fait en ajoutant le report sortant.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  9. #9
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 193
    Points : 28 077
    Points
    28 077
    Par défaut
    Donc dans l'exemple que je donne, il ne faudrait pas faire 0800+0000+0001+0001+6162+.... mais F7FF+FFFF+FFFE+FFFE+9E9D+....
    C'est bien ça ?

    Or, j'ai fait les 2 calculs sur la trame interceptée que je donne. Et pour retrouver par le calcul, le checksum intercepté qui était 4D5A, c'est bien la somme 0800+0000+0001+0001+6162+.... qu'il faut faire, somme que fait d'ailleurs les 2 codes donnés dans cette discussion et que l'on retrouve partout sur le web.

    Sauf à considérer que 0800... est déjà le complément à 1 d'une données que l'on ignore et dont on se moque puisque l'on ne s'en sert pas (ce qui est finalement totalement inutile et idiot), je ne comprend définitivement plus rien.


    Shark9> quand tu fais tes calculs, le size de ta trame fait bien au minimum 40 octets comme l'impose le protocole IP ? Tu as bien remplie les octets de bourrages ?
    --- Sevyc64 ---

    Parce que le partage est notre force, la connaissance sera notre victoire

  10. #10
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par sevyc64 Voir le message
    on va donc faire la somme de 0800+0000+0001+0001+6162+....
    Ce qui va nous donner : 6B29F
    On travaille sur 16 bits mais on conserve la retenue, donc on fait B29F+6 = B2A5 (si cette comme génère à nouveau une retenue faut recommencer jusqu'à tenir sur uniquement 16 bits)
    C'est ce processus de faire la somme des retenues jusqu'à ce qu'il n'y en ait plus qui est la "somme en complément aux 1" alias "complément à la base - 1", autrement dit c'est faire la somme modulo 0xFFFF (sauf qu'on se permet d'avoir 0xFFFF aussi comme synonyme de 0). Tandis que la somme en complément à 2, alias complément à la base, c'est faire la somme modulo 0x10000.

    Faisont -4 + 6 en complément à 1.
    0xFFFB + 0x0006 = 0x10001, il y a une retenue, on l'ajoute donc 0x0002 = 2

    En passant, on fait la même chose quand on fait la preuve par 9 (mais en base 10 plutot que 65536).

    Un des intérêts à faire la somme modulo 0xFFFF par rapport à faire une somme modulo 0x10000 c'est qu'elle est indépendante du boutisme. Si j'ai bonne mémoire, elle est aussi plus robuste à certains type d'erreur (mais je ne sais plus lesquels).
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  11. #11
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Citation Envoyé par sevyc64 Voir le message
    Donc dans l'exemple que je donne, il ne faudrait pas faire 0800+0000+0001+0001+6162+.... mais F7FF+FFFF+FFFE+FFFE+9E9D+....
    C'est bien ça ?
    Non, l'idée générale est que lorsque tu utilises la représentation en complément à un, trouver l'opposé d'un nombre revient à inverser ses bits et à s'en tenir là, ce que l'on sait déjà. Cela dit, ça veut dire qu'il y a déjà deux façons de coder le zéro : « +0 » qui donne « 0000 » et « -0 » qui correspond à « FFFF ».

    La difficulté réside dans le fait d'effectuer ces calculs et de conserver ce format. Par exemple : « -1 + 2 » vaut « 1 » et s'écrit, toujours sur 16 bits en représentation complément à 1 :

    « FFFE + 0002 = 0001 »

    … alors qu'avec une addition habituelle, on obtiendrait « 0000 ». De là, ce qui est rappelé dans la RFC, c'est que :
    • Soit tu utilises une machine nativement câblée pour travailler en complément à 1 ;
    • Soit tu utilises une machine travaillant en complément à 2 (celles dont on a l'habitude) et pour obtenir le bon résultat, tu additionnes normalement tes valeurs et tu rajoutes à la fin la partie qui déborde.


    Vérifions avec l'équation du dessus :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    — « FFFE + 0002 = 10000, soit 00010000 »
    — « 0000 + 0001 = 0001 ».

    Ça marche.

    Hors,
    « Or ». ;-)

    j'ai fait les 2 calculs sur la trame interceptée que je donne. Et pour retrouver par le calcul, le checksum intercepté qui était 4D5A, c'est bien la somme 0800+0000+0001+0001+6162+.... qu'il faut faire, somme que fait d'ailleurs les 2 codes donnés dans cette discussion et que l'on retrouve partout sur le web.
    Le rapport avec les commentaires du dessus, donc, c'est que :

    • Le fait de faire des additions normales est une partie du calcul, et pas le calcul entier ;
    • L'ajout supplémentaire de la retenue fait partie du processus pour revenir à une représentation en complément à 1, et ne sert pas uniquement à faire tenir le tout sur 16 bits.

  12. #12
    Membre du Club
    Étudiant
    Inscrit en
    Juin 2010
    Messages
    82
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2010
    Messages : 82
    Points : 57
    Points
    57
    Par défaut
    re salut alors voila une grosse partie de 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
    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
    116
    117
    118
    119
    120
    121
     
    ...
     
    #pragma pack(1)
    struct IPHEADER
    {
    	unsigned char  version;       
    	unsigned char  typServ;
    	unsigned short int tot_len;
    	unsigned short int id;
    	unsigned short int offset ; 
    	unsigned char  ttl;
    	unsigned char  protocol;
    	unsigned short int somme;         //modded
    	unsigned long  int ip_source;
    	unsigned long  int ip_dest;
     
     
    };	
    #pragma pack()	   
     
     
    #pragma pack(1)
    struct enteteICMP
    {
    	unsigned char TypeMsg;
        unsigned char CodeMsg;
        unsigned short int Sommecontrole;
        unsigned short int idMsg;
        unsigned short int Numseq;
     
    };
    #pragma pack()	
     
     
     
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_if_t * alldevs;
    pcap_t *adhandle;
     
    EthernetHeader ethernet;
    IPHEADER ip;
    enteteICMP icmp;
     
    ...
     
    char DATA[32] = "abcdefghijklmnopqrstuvwabcdefghi";
     
    		unsigned short int global_size = 0;
     
    		void RemplissageChar( char * var1 , char * var2 );
    		USHORT checksum(void * lpData, size_t size);
     
    int main(void)
     {
     
        global_size = sizeof(EthernetHeader) + sizeof(IPHEADER) + sizeof(enteteICMP )+ sizeof(DATA);  
     
    	buffer = malloc(global_size);
     
    	if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING , NULL , &alldevs , errbuf) == -1 )
    	{
    		printf(" \n error de recherche de la liste des DEVICES ..." );
    		return -1;
    	}
     
     
    	if( ( adhandle = pcap_open( alldevs->name, 65536, PCAP_OPENFLAG_PROMISCUOUS, -1, NULL, errbuf ))  == NULL )
    	{
    		printf(" \n error pcap_open() ..." );
    		return -1;
    	}
    ...
     
     
    	ip.version    = 69;                     
        ip.typServ    = 0;
        ip.tot_len    = htons(sizeof(IPHEADER) + sizeof(enteteICMP )+ sizeof(DATA));     
        ip.id         = htons(52);              
        ip.offset     = 0;                       
        ip.ttl        = 128;
        ip.protocol   = 1;
        ip.somme      = 0x0000;                    //modded
        ip.ip_source  = inet_addr("x.x.x.x");   
        ip.ip_dest    = inet_addr("192.168.0.1");
     
     
    	ip.somme      = checksum( &ip, sizeof(ip) );  //correcte 
     
    	icmp.TypeMsg            = 8;          
        icmp.CodeMsg            = 0;
    	icmp.Sommecontrole      = 0;
    	icmp.Sommecontrole      = checksum( &icmp, sizeof(icmp) ); //donne 0xf7ff et wireshark me conseil  ===> htons(0x335c);
        icmp.idMsg              = 14;          
        icmp.Numseq             = 12;           
     
      ..... 	
     
     
    USHORT checksum(void * lpData, size_t size)
    {
        USHORT * t = lpData;
        DWORD somme = 0;
        size_t i, n = size / sizeof(USHORT);
     
        for(i = 0; i < n; i++)
            somme += t[i];
     
        if (size % 2)
        {
            UCHAR * u = lpData;
            somme += u[size - 1];
        }
     
        while (HIWORD(somme))
            somme = HIWORD(somme) + LOWORD(somme);
     
        return LOWORD(~somme); 
    }
     
    ...

    voila si sa peut vous aidez .

    //donne 0xf7ff et wireshark me conseil ===> htons(0x335c);

    voila mon soucis comment wireshark arrive a me donné se resultat . alors que IP le checksum est correcte

  13. #13
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Citation Envoyé par Shark9 Voir le message
    re salut alors voila une grosse partie de mon code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    	icmp.TypeMsg            = 8;          
        icmp.CodeMsg            = 0;
    	icmp.Sommecontrole      = 0;
    	icmp.Sommecontrole      = checksum( &icmp, sizeof(icmp) ); //donne 0xf7ff et wireshark me conseil  ===> htons(0x335c);
        icmp.idMsg              = 14;          
        icmp.Numseq             = 12;
    Est-ce que c'est bien ce que je pense, là ?
    Tu modifies tes champs « idMsg » et « Numseq » APRÈS avoir calculé ta somme ?

  14. #14
    Membre du Club
    Étudiant
    Inscrit en
    Juin 2010
    Messages
    82
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2010
    Messages : 82
    Points : 57
    Points
    57
    Par défaut
    je viens de modifier et malheureusement placer apres c est toujours incorrecte , le checksum est pas bon et wireshark me conseil une autre valeur ... que faire .


    avec le checksum deplacer wireshark conseil ==> htons(0x4d42);

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    	icmp.TypeMsg            = 8;          
        icmp.CodeMsg            = 0;
    	icmp.Sommecontrole      = 0;
    	//icmp.Sommecontrole      = checksum( &icmp, sizeof(icmp) );//wireshark me conseil  ===> htons(0x335c);
        icmp.idMsg              =  htons(14);          
        icmp.Numseq             =  htons(12);           
     
    	icmp.Sommecontrole      = checksum( &icmp, sizeof(icmp)  );   // htons(0x4d42);

  15. #15
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 193
    Points : 28 077
    Points
    28 077
    Par défaut
    Obsidian >> Ok, j'ai compris le principe. Le titre de la RFc est un peu confu donc et prête à mauvaise interprétation.

    Shark9 >> Que vaut tes octets de bourrage ? L’entête de la trame ICMP fait 8 octets, il te faut donc 32 octets de bourrage au minimum
    --- Sevyc64 ---

    Parce que le partage est notre force, la connaissance sera notre victoire

  16. #16
    Membre du Club
    Étudiant
    Inscrit en
    Juin 2010
    Messages
    82
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2010
    Messages : 82
    Points : 57
    Points
    57
    Par défaut
    Que vaut tes octets de bourrage ?
    - comment faire pour les voir ? les affichés ? ils consistent en quoi ces octets de bourrages en me fiant a mon wireshark je vois pas ces octets de bourrages dans une requete icmp normal :s:s .


    lentete icmp ne doit pas faire que 8 octets ?

  17. #17
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 193
    Points : 28 077
    Points
    28 077
    Par défaut
    En regardant ton code, tes octets de bourrage sont en fait ton tableau DATA[] que tu inclus, je suppose à ta trame complète (tu donne pas la totalité du code)

    Ce tableau DATA[] fait parti de la trame ICMP, il doit suivre l’entête et doit être inclu dans le calcul du checksum.

    Regarde l'exemple de trame que j'ai donné plus haut, tu va l'y retrouver dedans.
    --- Sevyc64 ---

    Parce que le partage est notre force, la connaissance sera notre victoire

  18. #18
    Membre du Club
    Étudiant
    Inscrit en
    Juin 2010
    Messages
    82
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2010
    Messages : 82
    Points : 57
    Points
    57
    Par défaut
    voila tout le 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
    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
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
     
    #include <stdio.h>			 
    #include <stdlib.h>			 
    #include <string.h>	
     
    #include <winsock2.h>	//		
     
    #include <ws2tcpip.h>		
     
    #pragma comment(lib, "ws2_32.lib") 
     
     
    #include <pcap.h>
     
    #pragma comment(lib, "wpcap.lib") 	
     
     
     
    typedef struct EthernetHeader EthernetHeader;
    typedef struct IPHEADER IPHEADER;
    typedef struct enteteICMP enteteICMP;
     
    #pragma pack(1)
    struct EthernetHeader
    {
     
    	  unsigned char  Mac_destin1[2];
    	  unsigned char  Mac_destin2[2];
    	  unsigned char  Mac_destin3[2];
     
    	  unsigned char  Mac_source1[2];
          unsigned char  Mac_source2[2]; 
          unsigned char  Mac_source3[2];
     
    	  unsigned short int type_Ether;    
    };
    #pragma pack()
     
     
    #pragma pack(1)
    struct IPHEADER
    {
    	unsigned char  version;       
    	unsigned char  typServ;
    	unsigned short int tot_len;
    	unsigned short int id;
    	unsigned short int offset ; 
    	unsigned char  ttl;
    	unsigned char  protocol;
    	unsigned short int somme;         //modded
    	unsigned long  int ip_source;
    	unsigned long  int ip_dest;
     
     
    };	
    #pragma pack()	   
     
     
    #pragma pack(1)
    struct enteteICMP
    {
    	unsigned char TypeMsg;
        unsigned char CodeMsg;
        unsigned short int Sommecontrole;
        unsigned short int idMsg;
        unsigned short int Numseq;
     
    };
    #pragma pack()	
     
     
     
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_if_t * alldevs;
    pcap_t *adhandle;
     
    EthernetHeader ethernet;
    IPHEADER ip;
    enteteICMP icmp;
     
    char * buffer= NULL;
     
    char Mac_destin01[2] = { '\x52', '\x54' } ;  
    char Mac_destin02[2] = { '\x00', '\x12' } ;      // 52:54:00:12:35:02
    char Mac_destin03[2] = { '\x35', '\x02' } ;    
     
    char Mac_source01[2] = { '\x08', '\x00' } ;
    char Mac_source02[2] = { '\x27', '\xa6' } ;          // 08:00:27:A6:12:9D
    char Mac_source03[2] = { '\x12', '\x9D' } ;          
     
    char DATA[32] = "abcdefghijklmnopqrstuvwabcdefghi";
     
    		unsigned short int global_size = 0;
     
    		void RemplissageChar( char * var1 , char * var2 );
    		USHORT checksum(void * lpData, size_t size);
     
    int main(void)
     {
     
        global_size = sizeof(EthernetHeader) + sizeof(IPHEADER) + sizeof(enteteICMP )+ sizeof(DATA);  
     
    	buffer = malloc(global_size);
     
    	if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING , NULL , &alldevs , errbuf) == -1 )
    	{
    		printf(" \n error de recherche de la liste des DEVICES ..." );
    		return -1;
    	}
     
     
    	if( ( adhandle = pcap_open( alldevs->name, 65536, PCAP_OPENFLAG_PROMISCUOUS, -1, NULL, errbuf ))  == NULL )
    	{
    		printf(" \n error pcap_open() ..." );
    		return -1;
    	}
     
     
    	RemplissageChar( Mac_destin01 , ethernet.Mac_destin1);
    	RemplissageChar( Mac_destin02 , ethernet.Mac_destin2);
    	RemplissageChar( Mac_destin03 , ethernet.Mac_destin3);   
     
    	RemplissageChar( Mac_source01 , ethernet.Mac_source1);
    	RemplissageChar( Mac_source02 , ethernet.Mac_source2);
    	RemplissageChar( Mac_source03 , ethernet.Mac_source3);
     
        ethernet.type_Ether =  htons(0x0800) ;
     
    	ip.version    = 69;                     
        ip.typServ    = 0;
        ip.tot_len    = htons(sizeof(IPHEADER) + sizeof(enteteICMP )+ sizeof(DATA));     
        ip.id         = htons(52);              
        ip.offset     = 0;                       
        ip.ttl        = 128;
        ip.protocol   = 1;
        ip.somme      = 0x0000;                    //modded
        ip.ip_source  = inet_addr("10.0.2.15");   
        ip.ip_dest    = inet_addr("192.168.0.1");
     
     
    	ip.somme      = checksum( &ip, sizeof(ip) );
     
    	icmp.TypeMsg            = 8;          
        icmp.CodeMsg            = 0;
    	icmp.Sommecontrole      = 0;
    	//icmp.Sommecontrole      = checksum( &icmp, sizeof(icmp) );//wireshark me conseil  ===> htons(0x335c);
        icmp.idMsg              =  htons(14);          
        icmp.Numseq             =  htons(12);           
     
    	icmp.Sommecontrole      = checksum( &icmp, sizeof(icmp) );   // htons(0x4d42);
     
     
    	  memcpy(buffer, &ethernet, sizeof(ethernet));
    	  memcpy(buffer + sizeof(ethernet), &ip , sizeof(ip) );
    	  memcpy(buffer + sizeof(ethernet) +  sizeof(ip) , &icmp , sizeof(icmp) );
    	  memcpy(buffer + sizeof(ethernet) +  sizeof(ip) + sizeof(icmp) , DATA , strlen(DATA) );
     
     
    	if ( pcap_sendpacket(adhandle , buffer, global_size )  == -1 )
    	{
    		printf(" \n error pcap_sendpacket ..." );
    		return -1;
    	}
     
    	free(buffer);    
    	pcap_freealldevs(alldevs);
     
      return 0;
     }
     
     
    void RemplissageChar( char * var1 , char * var2 )
    {
    			int i = 0;
    			int Longueur = 0;
     
    			Longueur = sizeof(var1);
     
    			for ( i = 0 ; i < Longueur ; i++ )
    				{
    				var2[i] =  var1[i] ;
    				} 
     
    }
     
     
    USHORT checksum(void * lpData, size_t size)
    {
        USHORT * t = lpData;
        DWORD somme = 0;
        size_t i, n = size / sizeof(USHORT);
     
        for(i = 0; i < n; i++)
            somme += t[i];
     
        if (size % 2)
        {
            UCHAR * u = lpData;
            somme += u[size - 1];
        }
     
        while (HIWORD(somme))
            somme = HIWORD(somme) + LOWORD(somme);
     
        return LOWORD(~somme); 
    }

  19. #19
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Comme on vient de te le dire, le checksum de l'entête ICMP, contrairement à celui de l'entête IP, s'applique sur le message entier et pas seulement sur les données du header. Il faut inclure le contenu de data, dedans.

    Deux remarques au passage :
    — Il est inutile de passer des parenthèses au paramètre de sizeof, sauf si c'est un type que tu mesures (auquel cas il s'écrit comme lors d'un cast) ;
    — Il est dangereux de s'appuyer sur « unsigned char » et « unsigned short » pour définir des entiers 8 et 16 bits. À la place, utilise plutôt les entiers normalisés dans « #include <stdint.h> » ou bien directement ceux que tu utilises dans ta routine de checksum puisque ton compilateur a l'air de les reconnaître.

  20. #20
    Membre du Club
    Étudiant
    Inscrit en
    Juin 2010
    Messages
    82
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2010
    Messages : 82
    Points : 57
    Points
    57
    Par défaut
    Comme on vient de te le dire, le checksum de l'entête ICMP, contrairement à celui de l'entête IP, s'applique sur le message entier et pas seulement sur les données du header. Il faut inclure le contenu de data, dedans.

    - l'inclure de quel maniere ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    checksum( &icmp, sizeof(icmp) + sizeof(DATA) );
    ou inclure un char dans ma structure icmp et faire le remplissage avec les bits de mon data vers le char ?

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 15
    Dernier message: 04/01/2007, 11h15
  2. checksum d'une entête ICMP
    Par poporiding dans le forum C++
    Réponses: 6
    Dernier message: 20/01/2006, 14h19
  3. CMOS checksum error
    Par Hakim dans le forum Ordinateurs
    Réponses: 3
    Dernier message: 28/10/2003, 09h33
  4. Envoyer un message icmp (Echo Request)
    Par ovdz dans le forum Développement
    Réponses: 5
    Dernier message: 19/06/2003, 14h14
  5. Différence entre TCP, UDP, ICMP
    Par GliGli dans le forum Développement
    Réponses: 1
    Dernier message: 13/09/2002, 08h25

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