|
//
********************************************
// Nom : TcpPing.cpp
// Auteur : sebastien.fontaine@frameIP.com.pas.de.spam
// Date de création : 02 août 2004
// version : 2.2.3.10
// Licence : Cette executable est libre de toute utilisation.
// La seule condition existante est de faire référence
// au site http://www.frameip.com afin de respecter le travail
d'autrui.
// ********************************************
// ********************************************************
// Les includes
// ********************************************************
// Il faut ajouter dans les proprités du projet => C++ => Command Line :
// /I "C:\RepPerso\Personnel\Developpement\Projets\LibrairiePcap\Include"
// /I "C:\RepPerso\Personnel\Developpement\Projets\LibrairieSocket"
#include "LibrairieSocket.h"
#include "pcap.h"
// ********************************************************
// Les Librairies
// ********************************************************
// Il faut ajouter dans les proprités du projet => Linker => Command
Line :
// /NODEFAULTLIB:libcd.lib
// /LIBPATH:"C:\RepPerso\Personnel\Developpement\Projets\LibrairiePcap\Lib"
// /NODEFAULTLIB:LIBCMTD.lib
#pragma comment(lib,"Packet.lib")
#pragma comment(lib,"wpcap.lib")
// ********************************************************
// Les procédures
// ********************************************************
void initiation_des_variables(void);
void gestion_des_arguments(int argc, char* argv[]);
void Changement_aleatoire_des_valeurs(void);
void initiation_des_variables_automatiques(void);
void envoi_de_la_trame_winsock(void);
void envoi_de_la_trame_pcap(void);
void reception_de_la_trame(void);
// ********************************************************
// Les variables
// ********************************************************
struct mac entete_mac; // Entête
Ethernet
struct ipv4 entete_ipv4; // Entete IP
struct ipv4 *entete_ipv4_reception; // Entete IP receptionnée
struct tcp entete_tcp; // Entete
TCP
struct tcp *entete_tcp_reception; // Entete TCP receptionnée
char data_a_envoyer[65535]; // Data
unsigned int longueur_de_data_a_envoyer; // Longueur du char *, je
n'utilise pas strlen car il peux y avoir des 0
unsigned char trame_a_envoyer[65535]; // Entete IP +
data
int nombre_de_caractere_emis; // Variable
récupérant le nombre de caractères émis
unsigned long loops;
// Compteur permettant de lancer x fois les trames
char ip_source[16]; // Adresse IP Source permettant
d'initier entete_ipv4.ip_source
char ip_destination[16]; // Adresse IP Destination permettant
d'initier entete_ipv4.ip_destination
bool bouclage_infinie; // Variable
permettant de définir le mode de boucle infinie (quand loops=0)
bool ip_source_aleatoire; // Acive ou
désactive le mode IP Source Aléatoire
bool port_source_aleatoire; // Acive ou
désactive le mode Port Source Aléatoire
unsigned int pause_entre_chaque_frame;
unsigned int timeout; // Temps
d'attente maximum en cas de non réponse
unsigned int choix_mode_d_envoi;
// Variable définissant le mode d'envoi (0=Soket - 1=Libpcap)
unsigned char numero_de_l_interface;
// Numéro de l'interface qui sera utilisée
struct gestion_des_interfaces liste_des_interfaces; // structure
possédant les informations des intefaces
struct adresse_mac adresse_mac_tampon;
// Adresse MAC
bool mac_destination_auto;
// Variable permettant de savoir si l'adresse MAC de destination doit
être résolu en ARP
bool mac_source_auto;
// Variable permettant de savoir si l'adresse MAC source doit être prise
à partir de l'interface
LARGE_INTEGER cpu_frequence;
LARGE_INTEGER temps_de_reponse1;
LARGE_INTEGER temps_de_reponse2;
int main (int argc, char* argv[])
{
initiation_des_variables();
gestion_des_arguments(argc,argv);
initiation_des_variables_automatiques();
printf("\n");
while ( (loops!=0)||(bouclage_infinie==TRUE) )
{
loops--;
Changement_aleatoire_des_valeurs();
//
********************************************************
// Envoi de la trame
//
********************************************************
if (choix_mode_d_envoi==0)
envoi_de_la_trame_winsock();
else
envoi_de_la_trame_pcap();
//
********************************************************
// Reception de la trame
//
********************************************************
reception_de_la_trame();
Sleep(pause_entre_chaque_frame);
}
printf("\n");
return(1);
}
void initiation_des_variables(void)
{
structure_ip_local reception_des_ip_locales;
// ********************************************************
// Affichage de la banniere
// ********************************************************
printf("\nTcpPing - Send SYN TCP and display the answer
time - Version 2.2.3.10");
printf("\nCreate on August 02, 2004, Last compilation on
October 28, 2006");
printf("\nCreated by Sebastien FONTAINE - http://www.frameip.com");
printf("\nYour firewall must not be activated");
printf("\n");
// ********************************************************
// Initiation diverse
// ********************************************************
srand(GetTickCount()); //
Initialise le Random
QueryPerformanceFrequency((LARGE_INTEGER *)&cpu_frequence);
// Initialisation de la fréquence pour le compteur
pause_entre_chaque_frame=1000;
timeout=2;
choix_mode_d_envoi=1;
numero_de_l_interface=0;
liste_des_interfaces=recuperation_des_interfaces();
// ********************************************************
// Initiation des arguments
// ********************************************************
port_source_aleatoire=true;
ip_source_aleatoire=false;
loops=1;
bouclage_infinie=false;
// ********************************************************
// Options de la couche DATA
// ********************************************************
strcpy(data_a_envoyer,"www.frameip.com");
longueur_de_data_a_envoyer=(unsigned int)strlen(data_a_envoyer);
// ********************************************************
// Options de l'entête MAC
// ********************************************************
mac_source_auto=true;
mac_destination_auto=true;
entete_mac.type=htons(2048); // 08 00 indiquant un
datagramme IP
// ********************************************************
// Initialisation de l'entete Ip
// ********************************************************
entete_ipv4.ihl=5;
entete_ipv4.version=4;
entete_ipv4.tos=0;
entete_ipv4.length=0;
entete_ipv4.id=0;
// Il est initialisé plutard
entete_ipv4.offset=0;
entete_ipv4.ttl=100;
entete_ipv4.type=6;
reception_des_ip_locales=recuperation_ip_local(false);
strcpy(ip_source,reception_des_ip_locales.adresse_ip_local[0]);
entete_ipv4.ip_source=resolution_de_nom(false,ip_source);
strcpy(ip_destination,"192.168.101.254");
entete_ipv4.ip_destination=resolution_de_nom(FALSE,ip_destination);
// ********************************************************
// Initialisation de l'entete TCP
// ********************************************************
entete_tcp.port_source=0; // Il
est initialisé plutard
entete_tcp.port_destination=htons(23);
entete_tcp.sequence=0;
// Il est initialisé plutard
entete_tcp.accuse=0;
entete_tcp.reserved=0;
entete_tcp.offset=5; // taille de l'entête Tcp
entete_tcp.flag_fin=0;
entete_tcp.flag_syn=1;
entete_tcp.flag_rst=0;
entete_tcp.flag_psh=0;
entete_tcp.flag_ack=0;
entete_tcp.flag_urg=0;
entete_tcp.reserved2=0;
entete_tcp.window=htons(16384); // Valeur
relevée dans un Netmon après un "Telnet IP port"
entete_tcp.checksum=0;
entete_tcp.pointeur=0;
}
void gestion_des_arguments(int argc,char* argv[])
{
char *caractere_non_convertit;
unsigned int i;
// ********************************************************
// Affichage de l'aide
// ********************************************************
if ( (argc>1) && (strcmp(argv[1],"-?")==0) || (argc==1) )
{
printf("\n");
printf("\n\nGENERAL OPTIONS");
printf("\n-? This help");
printf("\n-send_mode 0=Soket 1=Libpcap
Default: %d",choix_mode_d_envoi);
printf("\n-loops Number of loops
Default: %d (0 => no stop)",loops);
printf("\n-wait Wait after frame
Default: %d ms",pause_entre_chaque_frame);
printf("\n-timeout Maximum wait
Default: %d s",timeout);
printf("\n\nFREE INTERFACES");
for(i=0;i<(signed)liste_des_interfaces.nombre;i++)
printf("\n%d - %s",i,liste_des_interfaces.description[i]);
printf("\n-interface Interface choice
Default: %d",numero_de_l_interface);
printf("\n\nIP HEADER OPTIONS (-mac_type
2048)");
printf("\n-ip_source @Ip or host name
Default: %s (0 => random)",ip_source);
printf("\n-ip_destination @Ip or host name
Default: %s (0 => random)",ip_destination);
printf("\n\nTCP HEADER OPTIONS (-ip_type 6)");
printf("\n-tcp_port_source Between 0 &
65535 Default: %d (0 => random)",htons(entete_tcp.port_source));
printf("\n-tcp_port_destination Between 0 &
65535 Default: %d (0 => random)",htons(entete_tcp.port_destination));
printf("\n\nOPTIONS OF THE DATA LAYER");
printf("\n-data_size data
size Default: %d",longueur_de_data_a_envoyer);
printf("\n");
printf("\nsample :\ntcpping -interface 2 -ip_destination
smtp.laposte.net -tcp_port_destination 25");
printf("\n\n");
exit(0);
}
// ********************************************************
// Récupération des arguments
// ********************************************************
for (i=1;i<(unsigned int)argc;i=i+1)
{
//
********************************************************
// Options Générales
//
********************************************************
if (stricmp(argv[i],"-send_mode")==0)
{
choix_mode_d_envoi=(unsigned char)strtod(argv[i+1],&caractere_non_convertit);
if (choix_mode_d_envoi!=1)
choix_mode_d_envoi=0;
}
if ( (stricmp(argv[i],"-loops")==0) || (stricmp(argv[i],"/loops")==0)
)
{
loops=(unsigned long)strtod(argv[i+1],&caractere_non_convertit);
if (loops==0)
bouclage_infinie=TRUE;
else
bouclage_infinie=FALSE;
}
if ( (stricmp(argv[i],"-wait")==0) || (stricmp(argv[i],"/wait")==0)
)
pause_entre_chaque_frame=(unsigned
int)strtod(argv[i+1],&caractere_non_convertit);
if ( (stricmp(argv[i],"-timeout")==0) || (stricmp(argv[i],"/timeout")==0)
)
timeout=(unsigned int)strtod(argv[i+1],&caractere_non_convertit);
//
********************************************************
// Choix de l'interface
//
********************************************************
if (stricmp(argv[i],"-interface")==0)
numero_de_l_interface=(unsigned char)strtod(argv[i+1],&caractere_non_convertit);
//
********************************************************
// Options de l'entête IP
//
********************************************************
if ( (stricmp(argv[i],"-ip_source")==0) || (stricmp(argv[i],"/ip_source")==0)
)
if (argv[i+1]==0)
ip_source_aleatoire=TRUE;
else
{
ip_source_aleatoire=FALSE;
entete_ipv4.ip_source=(unsigned
long)resolution_de_nom(FALSE,argv[i+1]);
}
if ( (stricmp(argv[i],"-ip_destination")==0) ||
(stricmp(argv[i],"/ip_destination")==0) )
{
entete_ipv4.ip_destination=(unsigned
long)resolution_de_nom(FALSE,argv[i+1]);
strcpy(ip_destination,convertion_ip(entete_ipv4.ip_destination));
}
//
********************************************************
// Options de l'entête TCP
//
********************************************************
if ( (stricmp(argv[i],"-tcp_port_source")==0) ||
(stricmp(argv[i],"/tcp_port_source")==0) )
if (argv[i+1]==0)
port_source_aleatoire=TRUE;
else
{
port_source_aleatoire=FALSE;
entete_tcp.port_source=htons((unsigned
short)strtod(argv[i+1],&caractere_non_convertit));
}
if ( (stricmp(argv[i],"-tcp_port_destination")==0)
|| (stricmp(argv[i],"/tcp_port_destination")==0) )
entete_tcp.port_destination=htons((unsigned
short)strtod(argv[i+1],&caractere_non_convertit));
//
********************************************************
// Options des Datas
//
********************************************************
if ( (stricmp(argv[i],"-data_size")==0) || (stricmp(argv[i],"/data_size")==0)
)
{
longueur_de_data_a_envoyer=(unsigned
int)strtod(argv[i+1],&caractere_non_convertit);
memcpy(data_a_envoyer,dimensionnement_de_data_a_envoyer(false,
data_a_envoyer, longueur_de_data_a_envoyer, longueur_de_data_a_envoyer),
longueur_de_data_a_envoyer);
}
}
}
void Changement_aleatoire_des_valeurs()
{
// ********************************************************
// Random de l'IP Source
// ********************************************************
if (ip_source_aleatoire==TRUE)
entete_ipv4.ip_source=generation_d_une_adresse_ip_aleatoire(0);
// ********************************************************
// Random de l'ID IP
// ********************************************************
entete_ipv4.id=(unsigned
short)(rand()%65536);
// Tire entre 0 et 65535
// ********************************************************
// Random du Port Source
// ************************************************* *******
if (port_source_aleatoire==TRUE)
entete_tcp.port_source=(unsigned
short)(rand()%64511+1+1024); // Tire entre 1025 et 65535
// ********************************************************
// Random de la séquence TCP
// ********************************************************
entete_tcp.sequence=(unsigned
long)((rand()%65536)*(rand()%65536)); // Tire entre 0
et 4294967295
}
void initiation_des_variables_automatiques(void)
{
unsigned int
i;
// Pour les boucles for
// ********************************************************
// Préparation des adresses MAC
// ********************************************************
if (mac_source_auto==true)
{
adresse_mac_tampon=recuperation_de_l_adresse_mac( liste_des_interfaces.nom[numero_de_l_interface]);
for (i=0;i<6;i++)
entete_mac.source[i]=adresse_mac_tampon.adresse[i];
}
if (mac_destination_auto==true)
{
adresse_mac_tampon=resolution_arp( liste_des_interfaces.nom[numero_de_l_interface],0,ip_destination,3);
for (i=0;i<6;i++)
entete_mac.destination[i]=adresse_mac_tampon.adresse[i];
}
}
void envoi_de_la_trame_winsock(void)
{
WSADATA initialisation_win32;
SOCKADDR_IN information_sur_la_destination;
SOCKET id_de_la_socket;
int on;
// ********************************************************
// Initialisation de la Socket
// ********************************************************
if (WSAStartup(MAKEWORD(2,2),&initialisation_win32)!=0)
gestion_des_erreurs(1,"WSAStartup",1,1);
// ********************************************************
// Ouverture d'une Socket
// ********************************************************
id_de_la_socket=socket(AF_INET,SOCK_RAW,IPPROTO_RAW);
if (id_de_la_socket==INVALID_SOCKET)
gestion_des_erreurs(1,"socket",1,1);
// ********************************************************
// Activation de l'option permettant d'inclure l'entete IP
lors de l'emission
// ********************************************************
if (setsockopt(id_de_la_socket,IPPROTO_IP,IP_HDRINCL,(char
*)&on,sizeof(on))!=0)
gestion_des_erreurs(1,"setsockopt",1,1);
// ********************************************************
// Calcul du checksum TCP
// ********************************************************
entete_tcp.checksum=calcul_du_checksum_tcp(false,
entete_ipv4.ip_source, entete_ipv4.ip_destination, entete_tcp,data_a_envoyer,
longueur_de_data_a_envoyer);
// ********************************************************
// Préparation de la trame à envoyé
// ********************************************************
memcpy(trame_a_envoyer,(unsigned short *)&entete_ipv4,sizeof(struct
ipv4));
memcpy(trame_a_envoyer+sizeof(struct ipv4),(unsigned short
*)&entete_tcp,sizeof(struct tcp));
memcpy(trame_a_envoyer+sizeof(struct ipv4)+sizeof(struct tcp),data_a_envoyer,longueur_de_data_a_envoyer);
// ********************************************************
// Paramètre nécessaire au sendto
// ********************************************************
information_sur_la_destination.sin_family=AF_INET;
information_sur_la_destination.sin_addr.s_addr=entete_ipv4.ip_destination;
// ********************************************************
// Démarrage du chrono
// ********************************************************
QueryPerformanceCounter((LARGE_INTEGER *)
&temps_de_reponse1);
// ********************************************************
// Envoi de la trame en winsock
// ********************************************************
nombre_de_caractere_emis=sendto(id_de_la_socket, (char *)trame_a_envoyer,sizeof(struct
ipv4)+sizeof(struct tcp)+ longueur_de_data_a_envoyer,0,(struct sockaddr*)&information_sur_la_destination, sizeof(information_sur_la_destination));
if (nombre_de_caractere_emis==-1)
gestion_des_erreurs(1,"sendto",1,1);
// ********************************************************
// Fermeture de la socket correspondant à la commande socket()
// ********************************************************
closesocket(id_de_la_socket);
// ********************************************************
// quite propement le winsock ouvert avec la commande
WSAStartup
// ********************************************************
WSACleanup(); // (A appeller autant de fois qu'il a été
ouvert)
}
void envoi_de_la_trame_pcap(void)
{
pcap_t *pointeur_interface;
char buffer_d_erreur[PCAP_ERRBUF_SIZE];
// ********************************************************
// Accède à l'interface
// ********************************************************
if ((pointeur_interface=pcap_open_live( liste_des_interfaces.nom[numero_de_l_interface],65536, 0,1000,buffer_d_erreur))==NULL)
gestion_des_erreurs(1,"pcap_open_live",1,1);
// ********************************************************
// Calcul du checksum TCP
// ********************************************************
entete_tcp.checksum=calcul_du_checksum_tcp(false,
entete_ipv4.ip_source, entete_ipv4.ip_destination, entete_tcp,data_a_envoyer,
longueur_de_data_a_envoyer);
// ********************************************************
// Calcul de la longueur totale
// ********************************************************
entete_ipv4.length=htons((unsigned short)(sizeof(struct
ipv4)+sizeof(struct tcp)+longueur_de_data_a_envoyer));
// ********************************************************
// Calcul du checksum IP
// ********************************************************
entete_ipv4.checksum=calcul_du_checksum_ip(false,entete_ipv4);
// ********************************************************
// Préparation de la trame à envoyé
// ********************************************************
memcpy(trame_a_envoyer,(unsigned short *)&entete_mac,sizeof(struct
mac));
memcpy(trame_a_envoyer+sizeof(struct mac),(unsigned short
*)&entete_ipv4,sizeof(struct ipv4));
memcpy(trame_a_envoyer+sizeof(struct mac)+sizeof(struct
ipv4),(unsigned short *)&entete_tcp,sizeof(struct tcp));
memcpy(trame_a_envoyer+sizeof(struct mac)+sizeof(struct
ipv4)+sizeof(struct tcp),data_a_envoyer,longueur_de_data_a_envoyer);
// ********************************************************
// Démarrage du chrono
// ********************************************************
QueryPerformanceCounter((LARGE_INTEGER *)
&temps_de_reponse1);
// ********************************************************
// Envoi de la trame
// ********************************************************
if(pcap_sendpacket(pointeur_interface,trame_a_envoyer,sizeof(struct
mac)+sizeof(struct ipv4)+sizeof(struct tcp)+longueur_de_data_a_envoyer)!=0)
gestion_des_erreurs(1,"pcap_sendpacket",1,1);
// ********************************************************
// Fermeture de l'accès à l'interface
// ********************************************************
pcap_close(pointeur_interface);
}
void reception_de_la_trame()
{
WSADATA initialisation_win32;
SOCKADDR_IN information_sur_la_source;
SOCKET id_de_la_socket_ecoute;
DWORD lpcbBytesReturned;
int tampon; // Variable temporaire
int duree_de_la_boucle;
BOOL sortie_de_la_boucle;
int nombre_de_caractere_recu;
char buffer_de_reception[65535];
double temps_de_reponse; // Variable indiquant le temps
écoulé entre l'envoi et la reception
// ********************************************************
// Initialisation de la Socket
// ********************************************************
if (WSAStartup(MAKEWORD(2,2),&initialisation_win32)!=0)
gestion_des_erreurs(1,"WSAStartup",1,1);
// ********************************************************
// Ouverture d'une Socket
// ********************************************************
id_de_la_socket_ecoute=socket(AF_INET,SOCK_RAW,IPPROTO_IP);
if (id_de_la_socket_ecoute==INVALID_SOCKET)
gestion_des_erreurs(1,"socket",1,1);
// ********************************************************
// Lien entre la socket et l'IP d'écoute
// ********************************************************
information_sur_la_source.sin_family=AF_INET;
information_sur_la_source.sin_addr.S_un.S_addr=entete_ipv4.ip_source;
if (bind( id_de_la_socket_ecoute,(SOCKADDR *)&information_sur_la_source,
sizeof(information_sur_la_source))==SOCKET_ERROR)
gestion_des_erreurs(1,"bind",1,1);
// ********************************************************
// Choix du mode de la socket
// ********************************************************
tampon=1;
// if (WSAIoctl(id_de_la_socket_ecoute, SIO_RCVALL,&tampon,sizeof(tampon),NULL,0, &lpcbBytesReturned,NULL,NULL)==SOCKET_ERROR)
// gestion_des_erreurs(1,"wsaioctl",1,1);
// ********************************************************
// Passage de la socket en mode non bloquant
// ********************************************************
tampon=1;
// La commande recv attend 1 (on) ms avant de rendre la main
if (setsockopt(id_de_la_socket_ecoute,SOL_SOCKET,SO_RCVTIMEO,(char
*)&tampon,sizeof(tampon))!=0)
gestion_des_erreurs(1,"setsockopt",1,1);
// ********************************************************
// Création de la boucle d'attente
// ********************************************************
QueryPerformanceFrequency((LARGE_INTEGER *)&cpu_frequence);
duree_de_la_boucle=GetTickCount();
sortie_de_la_boucle=FALSE;
while (sortie_de_la_boucle==false)
{
nombre_de_caractere_recu=recv(id_de_la_socket_ecoute,buffer_de_reception,65535,0);
if (GetTickCount()-duree_de_la_boucle>(unsigned)(timeout*1000))
{
sortie_de_la_boucle=TRUE;
printf("Timeout, sorry, but I didn't
receive the answer SYN/ACK or RST/ACK.\n");
}
else if (nombre_de_caractere_recu!=-1)
{
//
********************************************************
// Extraction et des valeurs recues
//
********************************************************
entete_ipv4_reception=(struct ipv4 *)buffer_de_reception;
entete_tcp_reception=(struct tcp *)(buffer_de_reception+20);
if (entete_ipv4_reception->ip_source==entete_ipv4.ip_destination)
if (entete_ipv4_reception->ip_destination==entete_ipv4.ip_source)
if (entete_ipv4_reception->type==6)
if (entete_tcp_reception->port_source==entete_tcp.port_destination)
if (entete_tcp_reception->port_destination==entete_tcp.port_source)
if (entete_tcp_reception->flag_ack==1)
if ( (entete_tcp_reception->flag_syn==1)
|| (entete_tcp_reception->flag_rst==1) )
{
sortie_de_la_boucle=TRUE;
//
********************************************************
// Arrêt du chrono
//
********************************************************
QueryPerformanceCounter((LARGE_INTEGER
*)&temps_de_reponse2);
//
********************************************************
// Calcul du temps de
réponse
//
********************************************************
temps_de_reponse=(
(double) ( (temps_de_reponse2.QuadPart - temps_de_reponse1.QuadPart) *
(double) 1000.0 / (double) cpu_frequence.QuadPart) );
//
********************************************************
// Affichage du résultat
//
********************************************************
printf("Time : %.2f ms",temps_de_reponse);
if (entete_tcp_reception->flag_syn==1)
printf(" -
SYN ACK received from %s",convertion_ip(entete_ipv4_reception->ip_source));
else
printf(" -
RST ACK received from %s",convertion_ip(entete_ipv4_reception->ip_source));
printf(" to %s",convertion_ip(entete_ipv4_reception->ip_destination));
printf("\n");
// printf(" %d
Octets",nombre_de_caractere_recu-40);
// printf(" ttl :
%d\n",entete_ipv4_reception->ttl);
}
}
}
} |