2008-02-14 08:54:51 +01:00
/*
* This file is part of the rtap localisation project .
*/
# include "ap.h"
unsigned char mac [ 6 ] ; // Adresse MAC de l'AP
2008-02-22 16:04:49 +01:00
2008-02-14 08:54:51 +01:00
int main ( int argc , char * argv [ ] )
{
struct sigaction action ; // Structure de mise en place des gestionnaires de signaux
2008-02-19 11:59:22 +01:00
char * mac_string ; // MAC de l'AP sous forme de chaîne
int ret ; // Code de retour du programme
2008-02-14 08:54:51 +01:00
2008-02-19 11:59:22 +01:00
if ( argc ! = ARGC )
2008-02-14 08:54:51 +01:00
{
print_usage ( argv [ 0 ] ) ;
return ERR_BAD_USAGE ;
}
run = TRUE ;
/* Mise en place des gestionnaires de signaux */
sigemptyset ( & action . sa_mask ) ;
action . sa_handler = sigint_handler ;
sigaction ( SIGINT , & action , NULL ) ;
action . sa_handler = sigterm_handler ;
sigaction ( SIGTERM , & action , NULL ) ;
2008-02-19 11:59:22 +01:00
get_mac_addr ( argv [ ARGV_WIFI_IFACE ] , mac ) ;
2008-02-14 08:54:51 +01:00
mac_string = mac_bytes_to_string ( mac ) ;
printf ( " Ma mac est : %s \n " , mac_string ) ;
free ( mac_string ) ;
2008-02-19 11:59:22 +01:00
ret = capture ( argv [ ARGV_RTAP_IFACE ] , argv [ ARGV_AGGREG_IP ] , TRUE ) ;
2008-02-14 08:54:51 +01:00
printf ( " %s : fin. \n " , argv [ 0 ] ) ;
return ret ;
}
2008-02-22 16:04:49 +01:00
/* Capture des paquets en utilisant l'interface "capture_iface".
* Les données capturées sont envoyées au serveur d ' aggrégation dont l ' IP est " aggregated_ip " .
*/
2008-02-19 11:59:22 +01:00
int capture ( char * capture_iface , char * aggregated_ip , BOOL print_values )
2008-02-14 08:54:51 +01:00
{
2008-02-22 16:04:49 +01:00
pcap_t * handle ; // Descripteur de capture de paquets
char errbuf [ PCAP_ERRBUF_SIZE ] ; // Message d'erreur
2008-02-14 08:54:51 +01:00
int sockfd ; // Descripteur de la socket vers le serveur d'aggrégation
struct sockaddr_in server , client ;
/* Sous-fonction de traitement des paquets capturés */
void got_packet ( u_char * args , const struct pcap_pkthdr * header , const u_char * packet )
{
read_packet ( args , header , packet , sockfd , & server , print_values ) ; // On appelle la fonction read_packet() avec les mêmes arguments, plus "print_values" qui indique si on doit afficher le paquet.
}
handle = pcap_open_live ( capture_iface , BUFSIZ , 1 , 1000 , errbuf ) ; // Début de la capture
if ( handle = = NULL ) // Le lancement de la capture a-t-il échoué ?
{
fprintf ( stderr , " Impossible d'ouvrir l'interface « %s » : %s \n " , capture_iface , errbuf ) ;
return ERR_OPENING_IFACE ;
}
/* Ouverture de la socket UDP vers le serveur d'aggrégation */
2008-02-19 11:59:22 +01:00
sockfd = create_udp_sending_socket ( aggregated_ip , AGGREGATE_DEFAULT_PORT , & server , & client ) ;
2008-02-14 08:54:51 +01:00
if ( sockfd < 0 )
{
perror ( " Erreur ! Impossible de créer la socket vers le serveur d'aggrégation \n " ) ;
return ERR_CREATING_SOCKET ;
}
while ( run )
{
pcap_loop ( handle , 1 , got_packet , NULL ) ; // Collecte 1 paquet et appelle la fonction got_packet quand pcaploop a recupéré des paquets
}
pcap_close ( handle ) ; // Arrêt de la capture.
( void ) close ( sockfd ) ; // Fermeture de la socket
return 0 ;
}
2008-02-22 16:04:49 +01:00
/* Traite un paquet et l'envoie au serveur d'agrégation sur la socket UDP "sockfd", au serveur "server". */
2008-02-14 08:54:51 +01:00
void read_packet ( u_char * args , const struct pcap_pkthdr * header , const u_char * packet , int sockfd , struct sockaddr_in * server , BOOL print_values )
{
unsigned char * data = ( unsigned char * ) packet ; // Recopie dans data l'adresse du paquet capturé
2008-02-20 16:36:44 +01:00
unsigned short rtap_bytes ; // Taille des données reçues
2008-02-14 08:54:51 +01:00
unsigned int rtap_presentflags , rtap_position ;
2008-02-20 16:36:44 +01:00
couple_message couple ; // Message à envoyer à l'agrégateur
2008-02-14 08:54:51 +01:00
ssize_t nsent ; // Retour de sendto
BOOL check [ 15 ] ; // Champs présents
2008-02-20 16:36:44 +01:00
unsigned char raw_packet_type ; // Type du packet reçu (beacon, data...)
char packet_type ; // Type de demande de localisation (demande, calibration)
unsigned short dst_port ; // Port destination du paquet capturé
int i ; // Compteur
2008-02-14 08:54:51 +01:00
2008-02-20 16:36:44 +01:00
memcpy ( & rtap_bytes , & data [ 2 ] , sizeof ( unsigned short ) ) ; // Recopie les deux octets à partir du troisième octet de donnée qui est la taille de l'en-tête rtap (change avec des flags)
raw_packet_type = data [ rtap_bytes ] ; // Au bout de l'en-tête rtap il y a celle du 802.11 dont le premier determine le type (beacon ou pas)
memcpy ( ( unsigned char * ) & dst_port , & data [ rtap_bytes + 24 + 8 + 20 + 3 ] , 1 ) ; // On récupère le port de destination (mais il faut retourner les deux octets)
memcpy ( & ( ( unsigned char * ) & dst_port ) [ 1 ] , & data [ rtap_bytes + 24 + 8 + 20 + 2 ] , 1 ) ; // (20 : longueur de l'en-tête IP, le port de destination étant les troisièmes et quatrièmes octet suivant).
2008-02-22 16:04:49 +01:00
if ( raw_packet_type = = RAW_PACKET_TYPE_DATA // Si le paquet est de type data,
& & data [ rtap_bytes + 24 + 8 + 9 ] = = RAW_PACKET_PROTO_UDP // et de protocole UDP (24 : en-tête 802.11, 8 : en-tête LLC, 9 : position du champ "Protocol" de l'en-tête IP),
2008-02-20 16:36:44 +01:00
& & dst_port = = LOC_REQUEST_DEFAULT_PORT ) // et le port de destination est le bon.
2008-02-14 08:54:51 +01:00
{
memcpy ( couple . ap_mac_addr_bytes , mac , 6 ) ; // On copie la MAC de l'AP
2008-02-22 16:04:49 +01:00
memcpy ( couple . mobile_mac_addr_bytes , & data [ rtap_bytes + 10 ] , 6 ) ; // L'adresse MAC source est 10 octets plus loin que le type de paquet
2008-02-14 08:54:51 +01:00
gettimeofday ( & couple . start_time , NULL ) ;
packet_type = data [ rtap_bytes + 24 + 8 + 20 + 8 ] ;
memcpy ( & couple . request_time , & data [ rtap_bytes + 24 + 8 + 20 + 8 + 1 ] , sizeof ( struct timeval ) ) ;
switch ( packet_type )
{
case PACKET_TYPE_NORMAL :
if ( print_values )
2008-02-20 16:36:44 +01:00
printf ( " \n Paquet normal reçu. \n " ) ;
2008-02-14 08:54:51 +01:00
couple . direction = 0 ;
couple . x_position = 0 ;
couple . y_position = 0 ;
couple . z_position = 0 ;
break ;
case PACKET_TYPE_CALIBRATION :
if ( print_values )
2008-02-20 16:36:44 +01:00
printf ( " \n Paquet de calibration reçu. \n " ) ;
2008-02-14 08:54:51 +01:00
couple . direction = data [ rtap_bytes + 24 + 8 + 20 + 8 + 9 ] ;
memcpy ( & couple . x_position , & data [ rtap_bytes + 24 + 8 + 20 + 8 + 10 ] , sizeof ( float ) ) ;
memcpy ( & couple . y_position , & data [ rtap_bytes + 24 + 8 + 20 + 8 + 14 ] , sizeof ( float ) ) ;
memcpy ( & couple . z_position , & data [ rtap_bytes + 24 + 8 + 20 + 8 + 18 ] , sizeof ( float ) ) ;
break ;
default :
if ( print_values )
2008-02-20 16:36:44 +01:00
printf ( " \n Paquet bizarre reçu. \n " ) ;
2008-02-14 08:54:51 +01:00
fprintf ( stderr , " Erreur ! Type de paquet inconnu (%d). \n " , packet_type ) ;
return ;
}
memcpy ( & rtap_presentflags , & data [ RTAP_P_PRESENTFLAGS ] , RTAP_L_PRESENTFLAGS ) ; // Récupère les flags de l'en-tête rtap
2008-02-22 16:04:49 +01:00
for ( i = 0 ; i < 15 ; i + + ) // Initialisation de la structure des champs présents
2008-02-14 08:54:51 +01:00
check [ i ] = FALSE ;
2008-02-22 16:04:49 +01:00
rtap_position = 8 ; // Début des champs déterminés par le present flag
2008-02-14 08:54:51 +01:00
2008-02-22 16:04:49 +01:00
for ( i = 0 ; i < 15 ; i + + ) // on teste les 15 premiers bits du champ flag afin de valider la présence et de les copier
2008-02-14 08:54:51 +01:00
{
if ( ( rtap_presentflags % 2 ) = = 1 )
{
switch ( i )
{
case RTAP_MACTS :
check [ RTAP_MACTS ] = TRUE ;
rtap_position + = RTAP_L_MACTS ;
break ;
case RTAP_FLAGS :
check [ RTAP_FLAGS ] = TRUE ;
rtap_position + = RTAP_L_FLAGS ;
break ;
case RTAP_RATE :
check [ RTAP_RATE ] = TRUE ;
rtap_position + = RTAP_L_RATE ;
break ;
case RTAP_CHANNEL :
rtap_position + = RTAP_L_CHANNEL ;
rtap_position + = RTAP_L_CHANNELTYPE ;
break ;
case RTAP_FHSS :
check [ RTAP_FHSS ] = TRUE ;
rtap_position + = RTAP_L_FHSS ;
break ;
case RTAP_ANTENNASIGNALDBM :
memcpy ( & ( couple . antenna_signal_dbm ) , & data [ rtap_position ] , RTAP_L_ANTENNASIGNALDBM ) ;
check [ RTAP_ANTENNASIGNALDBM ] = TRUE ;
if ( print_values )
printf ( " Antenna Signal : %d dBm \n " , couple . antenna_signal_dbm - 0x100 ) ;
rtap_position + = RTAP_L_ANTENNASIGNALDBM ;
break ;
case RTAP_ANTENNANOISEDBM :
check [ RTAP_ANTENNANOISEDBM ] = TRUE ;
rtap_position + = RTAP_L_ANTENNANOISEDBM ;
break ;
case RTAP_LOCKQUALITY :
check [ RTAP_LOCKQUALITY ] = TRUE ;
rtap_position + = RTAP_L_LOCKQUALITY ;
break ;
case RTAP_TXATTENUATION :
check [ RTAP_TXATTENUATION ] = TRUE ;
rtap_position + = RTAP_L_TXATTENUATION ;
break ;
case RTAP_TXATTENUATIONDB :
check [ RTAP_TXATTENUATIONDB ] = TRUE ;
rtap_position + = RTAP_L_TXATTENUATIONDB ;
break ;
case RTAP_TXATTENUATIONDBM :
check [ RTAP_TXATTENUATIONDBM ] = TRUE ;
rtap_position + = RTAP_L_TXATTENUATIONDBM ;
break ;
case RTAP_ANTENNA :
check [ RTAP_ANTENNA ] = TRUE ;
rtap_position + = RTAP_L_ANTENNA ;
break ;
case RTAP_ANTENNASIGNALDB :
check [ RTAP_ANTENNASIGNALDB ] = TRUE ;
rtap_position + = RTAP_L_ANTENNASIGNALDB ;
break ;
case RTAP_ANTENNANOISEDB :
check [ RTAP_ANTENNANOISEDB ] = TRUE ;
rtap_position + = RTAP_L_ANTENNANOISEDB ;
break ;
case RTAP_FCS :
check [ RTAP_FCS ] = TRUE ;
rtap_position + = RTAP_L_FCS ;
break ;
}
}
rtap_presentflags / = 2 ;
}
if ( print_values )
{
char * ap_mac_string = mac_bytes_to_string ( couple . ap_mac_addr_bytes ) ;
char * mobile_mac_string = mac_bytes_to_string ( couple . mobile_mac_addr_bytes ) ;
2008-02-20 16:36:44 +01:00
printf ( " \
2008-02-14 08:54:51 +01:00
* * * Couple à envoyer * * * \ n \
\ tMAC AP : % s \ n \
\ tMAC mobile : % s \ n \
\ tNuméro de séquence ( heure de la demande ) : % lu \ n \
\ tHeure d ' arrivée de la demande de localisation sur l ' AP : % lu \ n \
\ tSignal : % d dBm \ n \
\ tPosition X : % f \ n \
\ tPosition Y : % f \ n \
\ tPosition Z : % f \ n \
\ tDirection : % hhd \ n \
" ,
ap_mac_string ,
mobile_mac_string ,
timeval_to_ms ( couple . request_time ) ,
timeval_to_ms ( couple . start_time ) ,
couple . antenna_signal_dbm - 0x100 ,
couple . x_position ,
couple . y_position ,
couple . z_position ,
couple . direction
) ;
free ( ap_mac_string ) ;
free ( mobile_mac_string ) ;
}
/* Envoi du couple au serveur d'aggrégation */
nsent = sendto ( sockfd , ( void * ) & couple , sizeof ( couple ) , 0 , ( struct sockaddr * ) server , ( socklen_t ) sizeof ( * server ) ) ;
if ( nsent ! = ( ssize_t ) sizeof ( couple ) )
{
perror ( " Erreur lors de l'envoi du couple au serveur " ) ;
return ;
}
}
}
/* Fonction permettant de récupérer sa propre adresse MAC (interface 'eth') dans le tableau 'mac_bytes' */
void get_mac_addr ( char * eth , unsigned char mac_bytes [ 6 ] )
{
struct ifreq ifr ;
int sockfd ;
bzero ( mac_bytes , sizeof ( unsigned char ) * 6 ) ; // RàZ
sockfd = socket ( AF_INET , SOCK_DGRAM , 0 ) ;
if ( sockfd < 0 )
printf ( " Can't open socket \n " ) ;
strncpy ( ifr . ifr_name , eth , IFNAMSIZ ) ;
if ( ioctl ( sockfd , SIOCGIFFLAGS , & ifr ) < 0 )
return ;
if ( ioctl ( sockfd , SIOCGIFHWADDR , & ifr ) < 0 )
return ;
memcpy ( mac_bytes , ifr . ifr_hwaddr . sa_data , 6 ) ;
}
/* Affiche le mode d'emploi du programme */
void print_usage ( char * prog )
{
printf ( " Usage : \n \
2008-02-19 11:59:22 +01:00
\ t % s ip_agrégation rtap_iface wifi_iface \ n \
- ip_agrégation est l ' adresse IP du serveur d ' agrégation . \ n \
2008-02-14 08:54:51 +01:00
- rtap_iface est l ' interface de capture radiotap . \ n \
- wifi_iface est l ' interface physique correspondant à rtap_iface . \ n \
" , prog) ;
}