sniffer.c 4.22 KB
#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include "libnet.h"

#define ADRESSE "172.26.145.205"
#define SZ_DEV_PCAP 10


// Fonction lors de la detection d'un paquet
void arp_detect()
{
  printf("Paquet ARP\n");
}


// Issue du dépassement de seuil de paquets, gère en fonction du débit moyen de reception de paquets arp
void reponseSonde(time_t last_time, time_t seuil_temps)
{
  time_t ecart = time(NULL) - last_time;
  char msg0[2] = {0xA0,0x00}; // 0%
  char msg1[2] = {0xB0,0x00}; // 50%
  char msg2[2] = {0xBF,0xFF}; // 100%

  if (ecart > 2*seuil_temps)
    {
      sendUDPUnicast(ADRESSE, msg0, 2020);
    }
  else if(ecart > seuil_temps)
    {
      sendUDPUnicast(ADRESSE, msg1, 2020);
    }
  else
    {
      sendUDPBroadcast(msg2,2020);
    }
}

// La fonction va initialiser la sonde réseau
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(char* dev)
{
  int cnt=10; // Correspond au seuil de paquets arp à compter

  int seuil=10; // Seuil de temps

  time_t last_time_reponse; // Correspond au moment du démarrage du cycle de la sonde

  pcap_t *dev_handle; // Handle vers le device (correspondant à l'interface à sniffer)

  printf("Device: %s\n", dev);
	
  if(initialize_sniffer(&dev_handle, dev)!=0) return(-1); // Initialisation du sniffer

  while(1)
    {
      last_time_reponse = time(NULL);
      pcap_loop(dev_handle, cnt, arp_detect, NULL); // Boucle jusque [cnt] paquets arp reçus
      reponseSonde(last_time_reponse, seuil); // Une fois que le seuil de temps est passé
    }
	
  return 0;
}