sniffer.c 4.02 KB
#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define SZ_DEV_PCAP 10


// Fonction lors de la detection d'un paquet
void arp_detect(/*u_char *args, const struct pcap_pkthdr *header, const u_char *packet*/)
{
	static int num=0, loop=1;
	num++;
	printf("Voici le paquet arp numéro : %d\n", num);
	
	if(num==10) { loop++; num=0; printf("10 paquets ARP ont été reçus pour la boucle %d !\n", loop);}
}

int initialize_sniffer(pcap_t** dev_handle, char dev[])
{
	bpf_u_int32 mask; // Masque de l'adresse réseau de l'interface à sniffer
	bpf_u_int32 net; // Adresse réseau de l'interface à sniffer

	char ip[18]="null";

	struct bpf_program filter; // Filtre défini par une structure
	char buf_err[PCAP_ERRBUF_SIZE]; // Buffer qui stockera les erreurs rencontrées le cas échéant
	int status; 




	// Permet d'obtenir l'adresse ip de l'interface demandée*/
	/* pcap permet de lister les interfaces et obtenir les adresses ip de ces dernières
	 * On utilise la fonction pcap_findalldevs 
	 */



	pcap_if_t* interfaces;

	if(pcap_findalldevs(&interfaces, buf_err)!=0) { printf("%s\n", buf_err); return(EXIT_FAILURE); }
	
	for(pcap_if_t* i=interfaces; i!=NULL; i=i->next) 
	{
        	if(strcmp(i->name, dev)==0)
		{
			for(pcap_addr_t* a=i->addresses; a!=NULL; a=a->next) 
			{
				if(a->addr->sa_family == AF_INET) 
				{
					strcpy( ip , inet_ntoa(((struct sockaddr_in*)a->addr)->sin_addr) ); 
					printf("IP: %s\n", ip);
				}
			}		
		}
    	}



		
	// Création du handle du device
	if ((*dev_handle=pcap_create(dev, buf_err))==NULL)
	{
		//printf("%s\n", buf_err);
		fprintf(stderr, "Le handle n'a pas pu être créé sur le device %s. Vérifiez s'il est bien existant.\n", dev);
		return(EXIT_FAILURE);
	}
	
	
	// Activation du device
	if ((status=pcap_activate(*dev_handle))!=0)
	{
		fprintf(stderr, "Le sniffer ne peut être activé sur le device %s\n Code d'erreur : %d \n", dev, status);

		return(EXIT_FAILURE);
	}	
	

	// Vérification de l'adresse réseau
	if (pcap_lookupnet(dev, &net, &mask, buf_err) == -1)
	{
		fprintf(stderr, "L'adresse ip n'a pas pu être obtenue %s\n", dev);
		net=0;
		mask=0;
	}

	printf("Adresse du réseau : %d.%d.%d.%d \n", net & 0xff, (net >> 8) & 0xff, (net >> 16) & 0xff, (net >> 24) & 0xff);
	printf("Masque : %d.%d.%d.%d \n", mask & 0xff, (mask >> 8) & 0xff, (mask >> 16) & 0xff, (mask >> 24) & 0xff);


	// Conception du filtre (on vérifie si on a la bonne ip)
	char filter_str[50]="arp";
	if( strcmp(ip,"null")!=0 )
	{
		strcat(filter_str," and dst host ");
		strcat(filter_str, ip);
	}


	// "Analyse" du filtre de paquets de type arp 
	if(pcap_compile(*dev_handle, &filter, filter_str, 0, net)==-1)
	{
		fprintf(stderr, "Le filtre n'a pas pu être analysé : %s\n", pcap_geterr(*dev_handle));
		return(EXIT_FAILURE);
	}


	// Installation du filtre de paquets
	if(pcap_setfilter(*dev_handle, &filter) == -1)
	{
		fprintf(stderr, "Impossible d'installer le filtre : %s\n", pcap_geterr(*dev_handle));
		return(EXIT_FAILURE);
	}

	return 0;


}

int ecouteReseau(int argc, char* argv[])
{
	int cnt=10; // Correspond au nombre de paquets arp	

	char dev[SZ_DEV_PCAP]; // Nom de l'interface à sniffer
	pcap_t *dev_handle; // Handle vers le device (correspondant à l'interface à sniffer)
	


	// Vérifie si le device a été donné
	// ------------------------

	int dev_donne=0;  

	for(int i=1; i<argc-1; i++)
	{
		if(strcmp(argv[i], "-dev")==0 || strcmp(argv[i], "-d")==0)
		{
			strcpy(dev, argv[i+1]);
			dev_donne=1;
		}
	}

	if(!dev_donne)
		strcpy(dev, "eth0");

	printf("Device: %s\n", dev);

	// ------------------------




	// struct pcap_pkthdr packet_header; // Header du paquet comportant des informations sur la réception du paquet (temps de reception etc...)
	// const u_char *packet; // Contenant du paquet
	
	if(initialize_sniffer(&dev_handle, dev)!=0) return(-1);

	pcap_loop(dev_handle, cnt, arp_detect, NULL); // Boucle jusque 10 paquets arp reçus
	
	return 0;
}

/*

int main(int argc, char *argv[])
{	
	ecouteReseau(argc, argv);

	return(0);
}

*/