Pingicmp.exe
par _SebF

1 - Définition de l'exécutable
2 - Screen shot
        2.1 - Version console
        2.2 - Version graphique
3 - Download
4 - Suivi du développement de la version console
        4.1 - Problème restant
        4.2 - RoadMap
        4.3 - Suivi du projet
5 - Suivi du développement de la version Graphique
        5.1 - Problème restant
        5.2 - RoadMap
        5.3 - Suivi du projet
6 - Code source de la version console
        6.1 - pingicmp.cpp
7 - Code source de la version graphique
        7.1 - PingIcmp.h
        7.2 - PingIcmp.cpp
        7.3 - PingIcmpDlg.h
        7.4 - PingIcmpDlg.cpp
        7.5 - class_ip_address.h
        7.6 - class_ip_address.cpp
        7.7 - resource.h

1 - Définition de l'exécutable

L'utilitaire Ping permet à la base de  tester la présence d'un hôte distant via une trame de type ICMP. PingIcmp apporte les trois avantages suivants :

- Mesure du temps de réponse inférieur à la milliseconde.
- Changement d'adresse IP source.
- Envoi massif permettant d'atteindre des débits élevés tel que ~65 Mbps sur une carte 100 Mbps.

Posez vos questions, remarques, demande d'évolution et retour d'expérience sur le Forum dédié aux outils

2 - Screen shot

2.1 - Version console

TCPIP IPV6 VOIP VPN IP IPV4

2.2 - Version graphique

TCPIP IPV6 VOIP VPN IP IPV4

3 - Download

Nom : PingIcmp_gui.exe
Mode : Graphique
Version : 2.5
Librairie : Spécifique à PingIcmp
Taille : 1.456 Mo
Auteur : _SebF
Date de création : 29 Mars 2003
Dernière compilation : 08 Février 2004

Nom : PingIcmp.exe
Mode : Console
Version : 3.9
Librairie : Spécifique à PingIcmp
Taille : 0.132 Mo
Auteur : _SebF@FrameIP.com.pas.de.spam
Date de création : 21 Janvier 2003
Dernière compilation : 08 Février 2004

4 - Suivi du développement de la version console

4.1 - Problème restant

- Finir la traduction us.
- PingIcmp.exe /? émet un ping au lieu d'afficher l'exemple.

4.2 - RoadMap

- Intégration à la librairie commune.

4.3 - Suivi du projet

2004.02.08

V3.9

 - Séparation du suivit mode console et mode graphique. Recompilation avec le nouveau numéro de version.

2003.11.16

V3.9

 - Changement de l'email dans l'aide.
 - Remplacement de l'email par l'url www.frameip.com dans les data.
 - Changement de l'icône.

2003.05.08

V3.8

 - Migration du projet sur VC++ .net.
 - Desactivation de la librairie libcd grâce à la commande /NODEFAULTLIB:libcd.lib.
 - Changement des chemains statiques de la librairie socket.

2003.04.21

V3.8

 - Comparaison des arguments indépendamment des minuscules et majuscules grâce à la fonction strlwr.

2003.04.16

V3.7

 - Transformation du numéro de séquence avec htons() pour faire circuler dans les trames un numéro 1 2 3 4 ... au lieu de 256 512 768 1024 ...

2003.04.16

V3.7

 - Migration du projet en intégrant le pingicmp.h comme fichier de liaison.
 - Insertion du numéro de sequence.

2003.04.13

V3.6

 - Passage du retour de la fonction resolution_de_nom en unsigned long au lieu de int pour garder la compatibilité avec inet_addr.

2003.04.12

V3.6

 - Suppression de sous repertoire Debug afin que le resultat des compilations se trouve à la racine (Project - Setting - General).

2003.04.08

V3.5

 - Passage du debug en Level 4 et resolution des Warning de compilation C++.
 - Remplacement de clrscr par system("cls");
 - Rajout de (unsigned int) sur 5 strtod qui générés des warning.
 - Passage du mode Cmd de la valeur par defaut de la taille à 32.

2003.04.08

V3.4

 - Renomage de tous les .c en .cpp et recompilation de tous les modules en VC++ 6.0.

2003.03.30

V3.3

 - Modification de la fonction recuperation_ip_local() pour permettre de retourner la liste de toutes les ip locales.

2003.03.29

V3.2

 - Refonte de la procedure DNS afin d'intégrer le cas ou l'host demandé n'existe pas.
 - Modification des Data par mon adresse Email.

2003.03.19

V2.4

 - Modification de la fonction recuperation_ip_local pour lui intégrer le Return.

2003.01.30

V2.4

 - Intégration du numéro du process dans l'Id Icmp afin de le rendre unique sur cette machine.
Incrémentation de Séquence Icmp afin de différentier chaque paquet.

2003.01.29

V2.3

 - Résolution du problème de la perte de ping du au décalage dans le buffer. Pour cela j'ai crée la boucle sur un durée de timeout qui lit plusieurs fois le buffer afin de vérifier si la trame attendu n'est pas en seconde position voir plus.
 - Récupération de l'ip local dans la procédure initiation permettant de faire apparaître l'ip source par défaut qui sera utilisée.

2003.01.27

V2.2

 - Avancement de la documentation Icmp (inclus aux document IP).
 - Vérification que le paquet retour et bien pour celui attendu. Evitant le problème ou un retour de type host unresearchable était interprété comme le retour au ping.

2003.01.25

V2.1

 - Résolution du problème de temps de réponse. GetTickCount est approximatif de 10ms sous NT et 55 ms sous 9.x. J'ai inséré la fonction QueryPerformanceCounter qui se base sur le cycle du cpu.
 - Avancement de la documentation Icmp (inclus aux document IP).

2003.01.24

V2.0

 - Résolution du problème de la taille maximum de réception. 65000 maximum maintenant. Le problème été la valeur de 1024 dans la fonction RECV. Je l'ai passé à 65535.
 - 28 à l'affichage du nombre d'octets reçu afin d'indiquer la taille réel des data sans les entêtes.
 - Résolution du problème de RECV bloquant avec l'option SetSockOpt(...,SOL_SOCKET,SO_RCVTIMEO,...,...).
 - Ajout du paramètre timeout.
 - Le problème du temps de réponse vient du fait que la commande GetTickCount est approximative. Sous NT à 10 Ms et sous Win9x à 55 ms. Il ne reste plus qu'à trouver une solution.

2003.01.24

V1.3

 - Change de la boucle for en while.
 - Ajout du paramètre -t pour un bouclage bouclage_infinie.
 - Découverte d'un nouveau problème. Le ping ne fonctionne plus si un autre est en parallèle.
 - Essai d'incrémentation de id et seq dans l'entête ICMP, mais cela ne résout pas le problème.
 - Changement des array de 65000 à 65535 pour prendre le maximum de 2 octets.

2003.01.23

V1.2

 - Résolution du problème de montée en charge de la mémoire et du temps de réponse. En sortant la préparation des entêtes de la boucles.
 - Utilisation de la fonction inet_ntoa afin de transformer le numéro IP au format xxx.xxx.xxx.xxx.
 - Récupération de l'Ip source, attention sur un pc multi carte!
 - Avancement de la documentation Icmp (inclus aux document IP)

2003.01.22

V1.1

 - Dépannage de la réception de trame qui ne fonctionnait pas.
 - Ajout des options Nombre de fois et temps entre chaque ping.
 - Création de la documentation Icmp (inclus aux document IP).

2003.01.22

V1.0

 - Début du développement afin de créer un ping permettant de choisir l'ip source.
 - Copie du programme "Générateur de trames".
 - Mon arrière idée est de refaire le ping sans le nouveau bridage Microsoft -w 1.
 - Mon choix du compilateur s'est porté sur LCC 3.3 du au faite qu'il soit Light à installer.

5 - Suivi du développement de la version graphique

5.1 - Problème restant

- 2004.02.20 - Plantage de l'application lorsque le champs reception dépasse la déclaration de la variable char [100000], le mettre en cyclique.

5.2 - RoadMap

- Intégration à la librairie commune.

5.3 - Suivi du projet

2004.02.08

V2.5

 - Séparation du suivit mode console et mode graphique. Recompilation avec le nouveau numéro de version.

2003.11.16

V2.4

 - Changement de l'email dans l'aide.
 - Remplacement de l'email par l'url www.frameip.com dans les data.
 - Changement de l'icône.

2003.05.18

V2.3

 - Suppression de toutes les variables de types Values.
 - Passage de la compilation en mode Release.
 - Passage du SetSockOpt Recv dans la boucle.
 - Ajout des unités de mesures dans l'affichage de la fenêtres.

2003.05.17

V2.3

 - Passage de la procédure du PID parent dans la librairie.
 - Découverte que l'exe rend instantanément la main à la console permettant à l'utilisateur d'intéragir avec le cmd pendant l'execution de l'exe.
 - Suppression de la variable mode_windows qui n'a plus lieu d'être.

2003.05.14

V2.3

 - Ajout du readonly de timeout lors de la deselction de reception.
 - Test de performance à 45 Mps (P4 1,8Ghz).
 - Résolution du problème du pid de la console grâce aux commande FindWindow et GetWindowThreadProcessId.
 - Cela fonctionne même avec plusieurs cmd actifs. Le problème restant est l'attente de l'appuis d'une touche par l'utilisateur pour rendre la main..

2003.05.12

V2.3

 - J'ai réussit à écrire dans la console en l'attachant grâce à la commande AttachConsole(pid). Le problème est que j'ai pris le pid dans le gestionnaire des tâche!

2003.05.11

V2.3

 - Traduction en anglais des champs et de l'About.
 - Redimentionnement de la taille des objets et de la fanêtre.
 - Sélection par défaut des champs ip local et host name en fonction du Get appelant.
 - Affichage du TTL dans le milieu au lieu de la fin.

2003.05.11

V2.2

 - Ajout du champ IpAddressCtrl.
 - Déplacement du combobox dans la fenêtre ip_address.
 - Résolution du problème du champ Combobox qui ne s'ouvrait plus. Pour cela deux opérations. Le nettoyage des doublons de ressouce.h et l'edition notepad de PingIcmp.rc et remplacement des deux lignes du Combobox (attention aux coordonnées ???).
 - Création d'une variable externe permetant le dialogue entre deux ccp via la commande extern.

2003.05.10

V2.2

 - Création de la fenêtre ip_address afin de demander la saisie de l'adresse ip.

2003.05.08

V2.1

 - Migration du projet sur VC++ .net.
 - Desactivation de la librairie libcd grâce à la commande /NODEFAULTLIB:libcd.lib.
 - Changement des chemains statiques de la librairie socket.

2003.05.02

V2.0

 - Désactivation du spin nfois quand l'on passe en boucle infine.
 - Suppression de tous les répertoires et bascule de tous les fichiers dans le répertoire racine PingIcmp.
 - Renommage du fichier de suivi de projet avec un _ devant.

2003.05.01

V2.0

 - Intégration du modules gestion_des_arguments.

2003.05.01

V2.0

 - Refonte complète du programme pour n'intégrer qu'un seul Exe.
 - Convertion des sprintf en memcpy.
 - Intégration du module Pause afin de permettre de rendre la main à la fenetre principale pendant l'attente.

2003.04.27

V1.3

 - Remplacement des fonctions SetRange par SetRange32 afin de supporter 65535.

2003.04.26

V1.3

 - Déplacement des fichiers icône de /res à la racine.

2003.04.26

V1.3

 - Activation du menu about.
 - Création du bouton About.
 - Affichage de la fenetre About avec réccupération des informations dans la librairie.

2003.04.25

V1.2

 - Affectation des raccourcits clavier.

2003.04.25

V1.1

 - Réglage du problème des nouveaux Spins dont leurs valeurs ne varié que de -1 à 1. Pour cela passage de la limite max de 65535 à 10000.

2003.04.24

V1.1

 - Resolution du problème des Spins qui ne marchaient plus. Pour les associer à au champ désirer, il faut qu'ils se suivent dans l'ordre des tabulations.

2003.04.23

V1.1

 - Ajout de la procédure liberation_du_jeton qui permet de continuer à gérer la fenêtre principale pendant la boucle Ping.
 - Ajout du bouton Stop afin de pouvoir stoper la boucle.
 - Desactivation du bouton Ping pendant l'execution afin de marquer si l'on se trouve dans la boucle ou pas.
 - Activation de la procédure OnClose afin de fermer la boucle pour éviter que le process tourne en mémoire sans interface graphique.

2003.04.23

V1.0

 - Erreur docteur waston lors de la fermeture de la fenetre. Passage de la commande exit(0) en //.

2003.04.16

V1.0

 - Transformation du numéro de séquence avec htons() pour faire circuler dans les trames un numéro 1 2 3 4 ... au lieu de 256 512 768 1024 ...

2003.04.13

V1.0

 - Passage du retour de la fonction resolution_de_nom en unsigned long au lieu de int pour garder la compatibilité avec inet_addr.

2003.04.12

V1.0

 - Suppression de sous repertoire Debug afin que le resultat des compilations se trouve à la racine (Project - Setting - General).

2003.04.11

V1.0

 - Acivation de l'icône dans la fenetre minimize et dans le haut à gauche. Pour ce dernier, l'objet de l'icône doit s'appeler IDR_MAINFRAME.
 - Gestion de l'ordre des tabulation grace au menu Layout -> Tab order (Il faut au préalable avoir la Form).
 - Activation du bouton Ping comme bouton par defaut (dans les properties du bouton).

2003.04.08

V1.0

 - Passage du debug en Level 4 et resolution des Warning de compilation C++.
 - Remplacement de #include <tcconio.h> par #include <windows.h>.
 - Rajout de (unsigned int) sur 5 strtod qui générés des warning.
 - Passage de la decente du croll de 100 à 100000.

2003.04.08

V1.0

 - Renomage de tous les .c en .cpp et recompilation de tous les modules en VC++ 6.0.

2003.03.29

V1.0

 - J'ai séparé le programme en deux parties. L'une pour le coeur et l'autre pour l'intérface.
 - Intégration d'un frontal graphique à l'aide de VC++ 6.0.

6 - Code source de la version console

6.1 - pingicmp.cpp

// ********************************************************
// Les includes
// ********************************************************
#include <stdio.h>
//#include <tcconio.h>  // Pour Lcc
#include <windows.h> // Pour VC++
//#include <C:\\lcc\\projects\\PingIcmp\\Lib\\pingicmp.h>
#include <C:\\RepPerso\\Personnel\\Developpement\\Projets\\PingIcmp\\Lib\\pingicmp.h>


// ********************************************************
// Les procédures
// ********************************************************
void initiation_des_variables(void);
void gestion_des_arguments(int argc, char* argv[]);
void affichage_du_resultat();

// ********************************************************
// Les variables
// ********************************************************
struct echange echange_reception;
char ip_source[1000];
char ip_destination[1000];
unsigned char valeur_du_ttl;
unsigned int taille;
unsigned int nombre_de_ping;
bool bouclage_infinie;
unsigned int pause_entre_chaque_ping;
unsigned int timeout;
unsigned short sequence;







int main (int argc, char* argv[])
            {
            // system("cls");
            initiation_des_variables();
            gestion_des_arguments(argc,argv);
            while (nombre_de_ping>0) // Boucle du nombre de ping à envoyer
                        {
                        echange_reception=pingicmp_main(resolution_de_nom(ip_source), resolution_de_nom(ip_destination),valeur_du_ttl, taille,timeout,sequence);
                        if (sequence==65535) // Incrémente le champ sequence         
                                   sequence=0;
                        else
                                   sequence++;
                        affichage_du_resultat();
                        if (bouclage_infinie==TRUE)
                                   nombre_de_ping=1;
                        else
                                   nombre_de_ping--;
                        if (nombre_de_ping>0)
                                   Sleep(pause_entre_chaque_ping);
                        }
            printf("\n");
            return(1);
            }












void initiation_des_variables(void)
            {
            struct structure_ip_local reception_des_ip_locales;
            struct structure_version version_reception;
            int i;

            reception_des_ip_locales=recuperation_ip_local();
            strcpy(ip_source,reception_des_ip_locales.adresse_ip_local[0]);
            strcpy(ip_destination,"217.12.3.11");
            valeur_du_ttl=100;
            taille=32;
            nombre_de_ping=1;
            bouclage_infinie=FALSE;
            pause_entre_chaque_ping=1000;
            timeout=2;
            sequence=1;

            // ********************************************************
            // Affichage de la banniere
            // ********************************************************
            version_reception=version();
            printf("\n");
            for (i=0;i<version_reception.nombre_d_element;i++)
                        printf("\n%s",version_reception.tableau[i]);
            printf("\n\n");
            }












void gestion_des_arguments(int argc,char* argv[])
            {
            char * caractere_non_convertit;
            int i;

            if ( (argc>1) && (strcmp(argv[1],"-?")==0) || (argc==1) )
                        {
                        printf("\nParametres        Descriptions                  Valeurs par defaut");
                        printf("\n");
                        printf("\n-?                Aide");
                        printf("\n-ip_source        @Ip ou nom d'hote.            %s",ip_source);
                        printf("\n-ip_destination   @Ip ou nom d'hote.            %s",ip_destination);
                        printf("\n-ttl              Entre 0 et 255.               %d",valeur_du_ttl);
                        printf("\n-taille           Entre 0 et 65535.             %d",taille);
                        printf("\n-nfois            Entre 1 et 65535.             %d",nombre_de_ping);
                        printf("\n-t                Bouclage inifie");
                        printf("\n-pause            Temps entre les ping (ms).    %d",pause_entre_chaque_ping);
                        printf("\n-timeout          Temps d'attente max (s).      %d (0 supprime la reception)",timeout);
                        printf("\n\nExemple           pingicmp -ip_destination www.cisco.com -nfois 3");
                        printf("\n\n");
                        exit(0);
                        }
            for (i=1;i<argc;i=i+1)
                        {
                        if (strcmp(strlwr(argv[i]),"-ip_source")==0)
                                   strcpy(ip_source,argv[i+1]);
                        if (strcmp(strlwr(argv[i]),"-ip_destination")==0)
                                   strcpy(ip_destination,argv[i+1]);
                        if (strcmp(strlwr(argv[i]),"-ttl")==0)
                                   valeur_du_ttl=(unsigned char)strtod(argv[i+1],&caractere_non_convertit);
                        if (strcmp(strlwr(argv[i]),"-taille")==0)
                                   taille=(unsigned int)strtod(argv[i+1],&caractere_non_convertit);
                        if (strcmp(strlwr(argv[i]),"-nfois")==0)
                                   nombre_de_ping=(unsigned int)strtod(argv[i+1],&caractere_non_convertit);
                        if (strcmp(strlwr(argv[i]),"-t")==0)
                                   bouclage_infinie=1;
                        if (strcmp(strlwr(argv[i]),"-pause")==0)
                                   pause_entre_chaque_ping=(unsigned int)strtod(argv[i+1],&caractere_non_convertit);
                        if (strcmp(strlwr(argv[i]),"-timeout")==0)
                                   timeout=(unsigned int)strtod(argv[i+1],&caractere_non_convertit);
                        }
            }










void affichage_du_resultat(void)
            {
            if (echange_reception.nombre_de_caractere_emis==-1)
                        printf("\nLa trame n'a pas pu etre emise");
            else
                        {
                        if (echange_reception.nombre_de_caractere_recu==-1)
                                   printf("\nLa trame retour attendu n'a pas ete receptionnee");
                        if (echange_reception.nombre_de_caractere_recu>0)
                                   {
                                   printf("\n");
                                   if (sequence==0)
                                               printf("65535");
                                   else
                                               printf("%d",sequence-1);
                                   printf("   %s",echange_reception.ip_source);
                                   printf("   %s",echange_reception.ip_destination);
                                   printf("   %d Octets",echange_reception.nombre_de_caractere_recu-28);
                                   printf("   %.2f ms",echange_reception.temps_de_reponse);
                                   printf("   ttl : %d",echange_reception.ttl);
                                   }
                        }
            }

7 - Code source de la version graphique

7.1 - PingIcmp.h

// PingIcmp.h : main header file for the PINGICMP application
//

#if !defined(AFX_PINGICMP_H__591893E0_9BC7_4367_B6AF_F50CF282FA4C__INCLUDED_)
#define AFX_PINGICMP_H__591893E0_9BC7_4367_B6AF_F50CF282FA4C__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifndef __AFXWIN_H__
            #error include 'stdafx.h' before including this file for PCH
#endif

#include "resource.h"               // main symbols

/////////////////////////////////////////////////////////////////////////////
// CPingIcmpApp:
// See PingIcmp.cpp for the implementation of this class
//

class CPingIcmpApp : public CWinApp
{
public:
            CPingIcmpApp();

// Overrides
            // ClassWizard generated virtual function overrides
            //{{AFX_VIRTUAL(CPingIcmpApp)
            public:
            virtual BOOL InitInstance();
            //}}AFX_VIRTUAL

// Implementation

            //{{AFX_MSG(CPingIcmpApp)
            //}}AFX_MSG
            DECLARE_MESSAGE_MAP()
};


/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_PINGICMP_H__591893E0_9BC7_4367_B6AF_F50CF282FA4C__INCLUDED_)

7.2 - PingIcmp.cpp

#include "stdafx.h"
#include "PingIcmp.h"
#include "PingIcmpDlg.h"
#include "class_ip_address.h"
#include <C:\\RepPerso\\Personnel\\Developpement\\Projets\\LibrairieSocket\\LibrairieSocket.h>

// **************************************************
// CPingIcmpApp
// **************************************************
BEGIN_MESSAGE_MAP(CPingIcmpApp, CWinApp)
            ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()

// **************************************************
// CPingIcmpApp construction
// **************************************************
CPingIcmpApp::CPingIcmpApp()
            {
            }

// **************************************************
// The one and only CPingIcmpApp object
// **************************************************
CPingIcmpApp theApp;

// **************************************************
// CPingIcmpApp initialization
// **************************************************
BOOL CPingIcmpApp::InitInstance()
            {
/*         struct gestion_des_arguments arguments;
 
            // **************************************************
            // Récupération des arguments
            // **************************************************
            arguments=recuperation_des_arguments(TRUE);

            if(arguments.argc==1)
            // **************************************************
            // Gestion en mode graphique
            // **************************************************
                        {
*/                     CPingIcmpDlg application;
                        m_pMainWnd = &application;
                        application.DoModal();
/*                     }
            else
            // **************************************************
            // Gestion en mode console
            // **************************************************
                        {
                        FILE *console_canal;

                        // **************************************************
                        // S'attache à la console qui a lancé le programme
                        // **************************************************
                        AttachConsole(pid_de_la_console_parente(FALSE));

                        // **************************************************
                        // Ouverture d'un canal vers cette console
                        // **************************************************
                        console_canal=_tfreopen(_T("CONOUT$"),"a",stdout);
                        _tfreopen(_T("CONIN$"),"r",stdin);
                        _tfreopen(_T("CONERR$"),"a",stderr);

// *************************
// Lecture du buffer
// *************************
INPUT_RECORD irInBuf[128];
DWORD cNumRead;
int error=999;
HANDLE hStdin,hStdin_flush;

hStdin_flush = GetStdHandle(STD_INPUT_HANDLE);
hStdin = GetStdHandle(STD_OUTPUT_HANDLE);
// printf("\nflush : %d",FlushConsoleInputBuffer(hStdin_flush));

// error=ReadConsoleInput(hStdin,irInBuf,128,&cNumRead);
error=ReadConsole(hStdin,irInBuf,2,NULL,NULL);

printf("\nerreur : %d",error);
printf("\nflush : %d",FlushConsoleInputBuffer(hStdin_flush));

                        // **************************************************
                        // Affichage
                        // **************************************************
                        printf("\nMode Console - Fontaine Sébastien");
                        printf("\n");


                        printf("\ntoto");
                        pause(true,5000);
                        printf("\ntiti");

//Vide le buffer avant de rendre la main
printf("\nflush : %d",FlushConsoleInputBuffer(hStdin_flush));
// lancer l'exe avec cmd /c pingicmp -t fonctionne bien surtout associé au dernier Flush

                        // **************************************************
                        // Fermeture du canal vers la console
                        // **************************************************
                        fclose(console_canal);

                        // **************************************************
                        // Détache la console
                        // **************************************************
                        FreeConsole();
                        }
*/
            return FALSE;
            }

7.3 - PingIcmpDlg.h

// PingIcmpDlg.h : header file
//

#include "afxwin.h"
#if !defined(AFX_PINGICMPDLG_H__894CE67F_4DDD_43D4_89DB_96DC735CC734__INCLUDED_)
#define AFX_PINGICMPDLG_H__894CE67F_4DDD_43D4_89DB_96DC735CC734__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

// ********************************************************
// Définition de la class CPingIcmpDlg
// ********************************************************
class CPingIcmpDlg : public CDialog
            {
            // standard constructor
            public : CPingIcmpDlg(CWnd* pParent = NULL);

            // Dialog Data
            //{{AFX_DATA(CPingIcmpDlg)
            enum { IDD = IDD_PINGICMP_DIALOG };
            CSpinButtonCtrl          m_spin_taille_control;
            CSpinButtonCtrl          m_spin_pause_control;
            CSpinButtonCtrl          m_spin_timeout_control;
            CSpinButtonCtrl          m_spin_nombre_de_fois_control;
            CSpinButtonCtrl          m_spin_ttl_control;
            CButton           m_button_ping_control;
            CEdit   m_edit_nombre_de_fois_control;
            CButton           m_check_boucle_control;
            CButton           m_check_reception_control;
            CEdit   m_edit_reception_control;
            //}}AFX_DATA

            // ClassWizard generated virtual function overrides
            // DDX/DDV support
            protected :       virtual void DoDataExchange(CDataExchange* pDX);
           
            // Implementation
            protected :       HICON m_hIcon;

            // **************************************************
            // Les fonctions
            // **************************************************
            void CPingIcmpDlg::fermeture_de_la_socket(void);
            void CPingIcmpDlg::recpetion(void);

            // Generated message map functions
            virtual BOOL OnInitDialog();
            afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
            afx_msg void OnPaint();
            afx_msg HCURSOR OnQueryDragIcon();
            afx_msg void On_check_boucle();
            afx_msg void On_button_ping();
            afx_msg void On_button_clear();
            afx_msg void On_button_stop();
            afx_msg void OnClose();
            afx_msg void On_button_about();
            afx_msg void On_Change_edit_ttl();
            afx_msg void On_Change_edit_nombre_de_fois();
            afx_msg void On_Change_edit_taille();
            afx_msg void On_Change_edit_ip_destination();
            afx_msg void On_Edit_change_combobox_ip_source();
            //}}AFX_MSG
            DECLARE_MESSAGE_MAP()
                        public : afx_msg void OnBn_Clicked_button_get_source();
                        public : afx_msg void OnBn_Clicked_button_get_destination();
           
                                  
                                                afx_msg void OnBn_Clicked_check_reception();
                                                CEdit m_edit_timeout_control;
                                                afx_msg void On_En_Change_edit_pause();
                                                afx_msg void OnEn_Change_edit_timeout();
                                                CEdit m_edit_ip_source_control;
                                                CEdit m_edit_ip_destination_control;
                                                CEdit m_edit_pause_control;
                                                CEdit m_edit_taille_control;
                                                CEdit m_edit_ttl_control;
                                                int m_edit_taille_range;
                                                int m_edit_ttl_range;
                                                int m_edit_pause_range;
                                                int m_edit_timeout_range;
                                                int m_edit_nombre_de_fois_range;
            };

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_PINGICMPDLG_H__894CE67F_4DDD_43D4_89DB_96DC735CC734__INCLUDED_)

7.4 - PingIcmpDlg.cpp

// 2003.03.01 - Fermer proprement les socket

// **************************************************
// Les include
// **************************************************
#include "stdafx.h"
#include "PingIcmp.h"
#include "PingIcmpDlg.h"
#include "class_ip_address.h"
#include "windows.h"
#include <C:\\RepPerso\\Personnel\\Developpement\\Projets\\LibrairieSocket\\LibrairieSocket.h>

// **************************************************
// Les variables
// **************************************************
struct ipv4 entete_ipv4_emission;         // Entête ip à émettre
struct icmp entete_icmp_emission;       // Entête icmp à émettre
struct ipv4 *entete_ipv4_reception;      // Entête ip recu
struct icmp *entete_icmp_reception;    // Entête icmp recu
LARGE_INTEGER cpu_frequence;                // Fréquence du CPU
LARGE_INTEGER temps_de_reponse1;       // Nombre de clock CPU avant l'envoi
LARGE_INTEGER temps_de_reponse2;       // Nombre de clock CPU après la reception
double temps_de_reponse;                  // Temps en ms entre réponse 1 et réponse 2
int nombre_de_caractere_emis;                       // Nombre de caracteres qui a été emis. -1 égale erreur
int nombre_de_caractere_recu;                       // Nombre de caracteres qui a été recus. -1 égale erreur
char data_reference[65535];               // Data de référence. Les data_a_envoye sera dimentionné par rapport à cette référence
char data_a_envoyer[65535];              // Les data qui seront emis
SOCKET id_de_la_socket;                            // Numéro de la socket obtenu
int numero_d_erreur;                           // Récuppère le numéro d'erreur WSAGetLastError();
//unsigned short m_edit_timeout;
unsigned short m_edit_timeout;
unsigned short m_edit_nombre_de_fois;
unsigned short nfois;                            // Permet de décompter la boucle sans modifer l'affichage de m_edit_nombre_de_fois
unsigned short m_edit_pause;
unsigned short m_edit_taille;
bool initialisation=FALSE;                   // Permet de savoir si la fenetre est présente ou pas

// **************************************************
// Les variables temporaires
// **************************************************
char tampon_char[65535];
int tampon_int;

// **************************************************
// Les variables externes permetant le dialogue entre les différents cpp
// **************************************************
extern DWORD class_ip_address_retour_de_fenetre; // Nombre Inet_addr retourné par l'utilisateur
extern BOOL class_ip_address_selection;                                          // Permet de choisir la selection par defaut à l'ouverture de la fenetre

void CPingIcmpDlg::On_button_about()
            {
            // ********************************************************
            // Concatenation de l'affichage
            // ********************************************************
            sprintf(tampon_char,"                                    PingIcmp Version 2.5");
            sprintf(tampon_char,"%s\n",tampon_char);
            sprintf(tampon_char,"%s\nCreate on March 29, 2003",tampon_char);
            sprintf(tampon_char,"%s\nLast compilation on February 08, 2004",tampon_char);
            sprintf(tampon_char,"%s\nSebF@FrameIP.com",tampon_char);
            sprintf(tampon_char,"%s\nwww.frameip.com",tampon_char);
            sprintf(tampon_char,"%s\n\n",tampon_char);
            sprintf(tampon_char,"%s\n3 advantages of PingIcmp",tampon_char);
            sprintf(tampon_char,"%s\n",tampon_char);
            sprintf(tampon_char,"%s\n        - Measure response time lower than the millisecond",tampon_char);
            sprintf(tampon_char,"%s\n        - Hacking if you change your IP source",tampon_char);
            sprintf(tampon_char,"%s\n        - Flood the bandwidth to 65 Mbps with a 100Mbps card",tampon_char);

            // ********************************************************
            // Affichage de l'About en mode fenêtre
            // ********************************************************
            MessageBox(tampon_char,"About",0);           
            }

// ********************************************************
// Déclaration de la DialogBox CPingIcmpDlg - DEBUT -
// ********************************************************
CPingIcmpDlg::CPingIcmpDlg(CWnd* pParent ) : CDialog(CPingIcmpDlg::IDD, pParent)
, m_edit_taille_range(0)
, m_edit_ttl_range(0)
, m_edit_pause_range(0)
, m_edit_timeout_range(0)
, m_edit_nombre_de_fois_range(0)
{
            //{{AFX_DATA_INIT(CPingIcmpDlg)
            //}}AFX_DATA_INIT
            m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
            }

void CPingIcmpDlg::DoDataExchange(CDataExchange* pDX)
            {
                        CDialog::DoDataExchange(pDX);
                        //{{AFX_DATA_MAP(CPingIcmpDlg)
                        DDX_Control(pDX, IDC_spin_taille, m_spin_taille_control);
                        DDX_Control(pDX, IDC_spin_pause, m_spin_pause_control);
                        DDX_Control(pDX, IDC_spin_timeout, m_spin_timeout_control);
                        DDX_Control(pDX, IDC_spin_nombre_de_fois, m_spin_nombre_de_fois_control);
                        DDX_Control(pDX, IDC_spin_ttl, m_spin_ttl_control);
                        DDX_Control(pDX, IDC_button_ping, m_button_ping_control);
                        DDX_Control(pDX, IDC_edit_nombre_de_fois, m_edit_nombre_de_fois_control);
                        DDX_Control(pDX, IDC_check_boucle, m_check_boucle_control);
                        DDX_Control(pDX, IDC_check_reception, m_check_reception_control);
                        DDX_Control(pDX, IDC_edit_reception, m_edit_reception_control);
                        //}}AFX_DATA_MAP
                        DDX_Control(pDX, IDC_edit_timeout, m_edit_timeout_control);
                        DDX_Control(pDX, IDC_edit_ip_source, m_edit_ip_source_control);
                        DDX_Control(pDX, IDC_edit_ip_destination, m_edit_ip_destination_control);
                        DDX_Control(pDX, IDC_edit_pause, m_edit_pause_control);
                        DDX_Control(pDX, IDC_edit_taille, m_edit_taille_control);
                        DDX_Control(pDX, IDC_edit_ttl, m_edit_ttl_control);
                        DDX_Text(pDX, IDC_edit_taille, m_edit_taille_range);
                        DDV_MinMaxInt(pDX, m_edit_taille_range, 0, 65535);
                        DDX_Text(pDX, IDC_edit_ttl, m_edit_ttl_range);
                        DDV_MinMaxInt(pDX, m_edit_ttl_range, 0, 255);
                        DDX_Text(pDX, IDC_edit_pause, m_edit_pause_range);
                        DDV_MinMaxInt(pDX, m_edit_pause_range, 1, 65535);
                        DDX_Text(pDX, IDC_edit_timeout, m_edit_timeout_range);
                        DDV_MinMaxInt(pDX, m_edit_timeout_range, 1, 65535);
                        DDX_Text(pDX, IDC_edit_nombre_de_fois, m_edit_nombre_de_fois_range);
                        DDV_MinMaxInt(pDX, m_edit_nombre_de_fois_range, 1, 65535);
}

BEGIN_MESSAGE_MAP(CPingIcmpDlg, CDialog)
            // **************************************************
            // Liste des fonctions tournant en boucle en tâche de fond
            // **************************************************
            ON_WM_SYSCOMMAND() // Attente d'une interaction avec la fenêtre principale du type menu, croix pour fermer. Si il detect une action, alors il appel la fonction void CPingIcmpDlg::OnSysCommand(UINT nID, LPARAM lParam)
            ON_WM_PAINT()
            ON_WM_QUERYDRAGICON()
            ON_BN_CLICKED(IDC_check_boucle, On_check_boucle)
            ON_BN_CLICKED(IDC_button_ping, On_button_ping)
            ON_BN_CLICKED(IDC_button_clear, On_button_clear)
            ON_BN_CLICKED(IDC_button_stop, On_button_stop)
            ON_WM_CLOSE()
            ON_BN_CLICKED(IDC_button_about, On_button_about)
            ON_EN_CHANGE(IDC_edit_ttl, On_Change_edit_ttl)
            ON_EN_CHANGE(IDC_edit_nombre_de_fois, On_Change_edit_nombre_de_fois)
            ON_EN_CHANGE(IDC_edit_taille, On_Change_edit_taille)
            ON_BN_CLICKED(IDC_button_source, OnBn_Clicked_button_get_source)
            ON_BN_CLICKED(IDC_button_destination, OnBn_Clicked_button_get_destination)
            ON_BN_CLICKED(IDC_check_reception, OnBn_Clicked_check_reception)
            ON_EN_CHANGE(IDC_edit_pause, On_En_Change_edit_pause)
            ON_EN_CHANGE(IDC_edit_timeout, OnEn_Change_edit_timeout)
END_MESSAGE_MAP()
// ********************************************************
// Déclaration de la DialogBox CPingIcmpDlg - FIN -
// ********************************************************

BOOL CPingIcmpDlg::OnInitDialog()
            {
            struct structure_ip_local reception_des_ip_locales;

            // **************************************************
            // Orginie VC++
            // **************************************************
            CDialog::OnInitDialog();
            SetIcon(m_hIcon, TRUE);                              // Set big icon
            SetIcon(m_hIcon, FALSE);                 // Set small icon

            // **************************************************
            // Insert le "String Table" dans le menu
            // **************************************************
            ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
            ASSERT(IDM_ABOUTBOX < 0xF000);

            CMenu* pSysMenu = GetSystemMenu(FALSE);
            if (pSysMenu != NULL)
                        {
                        CString strAboutMenu;
                        strAboutMenu.LoadString(IDS_ABOUTBOX);
                        if (!strAboutMenu.IsEmpty())
                                   {
                                   pSysMenu->AppendMenu(MF_SEPARATOR);
                                   pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
                                   }
                        }

            // ********************************************************
            // Initiation diverse
            // ********************************************************
            QueryPerformanceFrequency((LARGE_INTEGER *)&cpu_frequence);
            m_edit_pause=1000;
            m_edit_timeout=1000;
            m_edit_nombre_de_fois=1;
           
            // ********************************************************
            // Initialisation des data
            // ********************************************************
            strcpy(data_reference,"www.frameip.com www.frameip.com ");
            strcpy(data_a_envoyer,data_reference);
            m_edit_taille=32;

            // ********************************************************
            // Initialisation de l'entete Icmp
            // ********************************************************
            entete_icmp_emission.type=8;
            entete_icmp_emission.code=0;
            entete_icmp_emission.checksum=0;
            entete_icmp_emission.id=(unsigned short)GetCurrentProcessId();
            entete_icmp_emission.sequence=1;

            // ********************************************************
            // Initialisation de l'entete Ip
            // ********************************************************
            entete_ipv4_emission.ihl=5;
            entete_ipv4_emission.version=4;
            entete_ipv4_emission.tos=0;
            entete_ipv4_emission.length=htons((unsigned short)(20+strlen(data_a_envoyer)));
            entete_ipv4_emission.id=(unsigned short)htonl(67);
            entete_ipv4_emission.offset=0;
            entete_ipv4_emission.ttl=100;
            entete_ipv4_emission.type=1;
            entete_ipv4_emission.checksum=0;
            reception_des_ip_locales=recuperation_ip_local(TRUE);
            entete_ipv4_emission.ip_source=resolution_de_nom(TRUE,reception_des_ip_locales.adresse_ip_local[0]);
            entete_ipv4_emission.ip_destination=resolution_de_nom(TRUE,"www.yahoo.fr");

            // **************************************************
            // Initialisation de la reception
            // **************************************************
            m_check_reception_control.SetCheck(1);
            m_edit_reception_control.SetReadOnly(1);
            CPingIcmpDlg::OnBn_Clicked_check_reception();
           
            // **************************************************
            // Initialisation des Range
            // **************************************************
            m_spin_ttl_control.SetRange32(0,255);
            m_spin_nombre_de_fois_control.SetRange32(1,65535);
            m_spin_taille_control.SetRange32(0,65535);
            m_spin_pause_control.SetRange32(1,65535);
            m_spin_timeout_control.SetRange32(1,65535);

            // **************************************************
            // Mise à jour des champs
            // **************************************************
            sprintf(tampon_char,"%d",m_edit_timeout);
            m_edit_timeout_control.SetWindowText(tampon_char);
            sprintf(tampon_char,"%d",m_edit_nombre_de_fois);
            m_edit_nombre_de_fois_control.SetWindowText(tampon_char);
            sprintf(tampon_char,"%d",entete_ipv4_emission.ttl);
            m_edit_ttl_control.SetWindowText(tampon_char);
            m_edit_ip_source_control.SetWindowText(reception_des_ip_locales.adresse_ip_local[0]);
            m_edit_ip_destination_control.SetWindowText("www.yahoo.fr");
            sprintf(tampon_char,"%d",m_edit_pause);
            m_edit_pause_control.SetWindowText(tampon_char);
            sprintf(tampon_char,"%d",m_edit_taille);
            m_edit_taille_control.SetWindowText(tampon_char);

            // ********************************************************
            // Je concidère à ce niveau que la fenêtre est affichée
            // ********************************************************
            initialisation=TRUE;

            return TRUE;  // return TRUE  unless you set the focus to a control
            }

void CPingIcmpDlg::OnSysCommand(UINT nID, LPARAM lParam)
            {
            // **************************************************
            // Si l'utilisateur selectionne le menu About
            // **************************************************
            if ((nID & 0xFFF0) == IDM_ABOUTBOX)
                        On_button_about();
            else
                        CDialog::OnSysCommand(nID, lParam);
            }

void CPingIcmpDlg::OnPaint()
{
            if (IsIconic())
            {
                        CPaintDC dc(this); // device context for painting

                        SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

                        // Center icon in client rectangle
                        int cxIcon = GetSystemMetrics(SM_CXICON);
                        int cyIcon = GetSystemMetrics(SM_CYICON);
                        CRect rect;
                        GetClientRect(&rect);
                        int x = (rect.Width() - cxIcon + 1) / 2;
                        int y = (rect.Height() - cyIcon + 1) / 2;

                        // Draw the icon
                        dc.DrawIcon(x, y, m_hIcon);
            }
            else
            {
                        CDialog::OnPaint();
            }
}

HCURSOR CPingIcmpDlg::OnQueryDragIcon()
{
            return (HCURSOR) m_hIcon;
}

void CPingIcmpDlg::recpetion(void)
            {
            int compteur=0;
            SOCKADDR_IN translation;
            char buffer_de_reception[65535];
            char ip_source_reception[15];
            char ip_destination_reception[15];
            char resultat[100000];
            int duree_de_la_boucle;
            BOOL sortie_de_la_boucle;
            CString conversion;

            // ********************************************************
            // Initialisation
            // ********************************************************
            duree_de_la_boucle=GetTickCount();
            sortie_de_la_boucle=FALSE;

            // ********************************************************
            // Boucle d'attente de la trame retour
            // ********************************************************
            liberation_du_jeton();
            while ((m_edit_pause!=0)&&(sortie_de_la_boucle==FALSE))
                        {
                        liberation_du_jeton();
                        nombre_de_caractere_recu=recv(id_de_la_socket,buffer_de_reception,65535,0);

                        // ********************************************************
                        // Vérifie si la durée de la boucle est suppérieur au temps d'attente demandé par l'utilisateur
                        // ********************************************************
                        liberation_du_jeton();
                        if (GetTickCount()-duree_de_la_boucle>(unsigned)(m_edit_pause))
                                   sortie_de_la_boucle=TRUE;

                        // ********************************************************
                        // Si une trame est receptionnée
                        // ********************************************************
                        if (nombre_de_caractere_recu!=-1)
                                   {
                                   // ********************************************************
                                   // Transformation en IP de type xxx.xxx.xxx.xxx
                                   // ********************************************************
                                   liberation_du_jeton();
                                   entete_ipv4_reception=(struct ipv4 *)buffer_de_reception;
                                   translation.sin_addr.s_addr=entete_ipv4_reception->ip_source;
                                   strcpy(ip_source_reception,inet_ntoa(translation.sin_addr));
                                   translation.sin_addr.s_addr=entete_ipv4_reception->ip_destination;
                                   strcpy(ip_destination_reception,inet_ntoa(translation.sin_addr));

                                   // ********************************************************
                                   // Vérification de la conformité dela trame réçu
                                   // ********************************************************
                                   liberation_du_jeton();
                                   entete_icmp_reception=(struct icmp *)(buffer_de_reception+20);
                                   if (entete_ipv4_reception->ip_source==entete_ipv4_emission.ip_destination)
                                               compteur++;
                                   if (entete_ipv4_reception->ip_destination==entete_ipv4_emission.ip_source)
                                               compteur++;
                                   if (entete_icmp_reception->type==0)
                                               compteur++;
                               &nbs