2008-02-14 08:54:51 +01:00
/*
* This file is part of the rtap localisation project .
*/
2008-10-06 17:27:33 +02:00
# include "owlps-listener.h"
2008-02-14 08:54:51 +01:00
2008-03-14 11:31:04 +01:00
# define DEBUG
2008-02-14 08:54:51 +01:00
unsigned char mac [ 6 ] ; // Adresse MAC de l'AP
2009-07-02 13:12:51 +02:00
# ifdef USE_CONFIG_FILE
cfg_t * cfg ; // Structure contenant la configuration
# else // USE_CONFIG_FILE // Si on n'utilise pas libconfuse, on déclare une
struct { // structure qui servira à stocker les options getopt :
2009-08-04 12:02:52 +02:00
char mode ;
2009-07-02 13:12:51 +02:00
char aggregation_ip [ 16 ] ;
long aggregation_port ;
long listening_port ;
# ifdef USE_PTHREAD
BOOL keep_monitor ;
# endif // USE_PTHREAD
char rtap_iface [ IFNAMSIZ + 1 ] ;
char wifi_iface [ IFNAMSIZ + 1 ] ;
2009-08-04 12:02:52 +02:00
BOOL verbose ;
2009-07-02 13:12:51 +02:00
} options = { // et on initalise les options par défaut :
2009-08-04 12:02:52 +02:00
MODE_ACTIVE ,
2009-07-02 13:12:51 +02:00
" 127.0.0.1 " ,
AGGREGATE_DEFAULT_PORT ,
# ifdef USE_PTHREAD
FALSE ,
# endif // USE_PTHREAD
" " ,
2009-08-04 12:02:52 +02:00
" " ,
FALSE
2009-07-02 13:12:51 +02:00
} ;
# endif // USE_CONFIG_FILE
2008-02-14 08:54:51 +01:00
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
2009-07-02 09:42:15 +02:00
# ifdef USE_PTHREAD
2008-02-27 17:37:08 +01:00
pthread_t thread ; // Thread pour le repassage en mode monitor
2009-07-02 09:42:15 +02:00
# endif // USE_PTHREAD
2008-02-14 08:54:51 +01:00
2009-07-02 13:12:51 +02:00
# ifdef USE_CONFIG_FILE // Si on utilise libconfuse, on déclare les options :
2009-04-15 14:15:49 +02:00
cfg_opt_t opts [ ] = { // Options reconnues par confuse dans le fichier de config
2009-08-04 12:02:52 +02:00
CFG_INT ( " mode " , MODE_ACTIVE , CFGF_NONE ) , // Mode d'écoute : a pour actif, p pour passif, m pour mixte (défaut : a)
2009-04-15 14:15:49 +02:00
CFG_STR ( " aggregation_ip " , " 127.0.0.1 " , CFGF_NONE ) , // Adresse IP du serveur d'agrégation (défaut : boucle locale)
2009-07-02 13:12:51 +02:00
CFG_INT ( " aggregation_port " , AGGREGATE_DEFAULT_PORT , CFGF_NONE ) , // Port d'envoi sur le serveur d'agrégation
CFG_INT ( " listening_port " , LOC_REQUEST_DEFAULT_PORT , CFGF_NONE ) , // Port d'écoute des demandes des mobiles
2009-07-02 09:42:15 +02:00
# ifdef USE_PTHREAD
CFG_BOOL ( " keep_monitor " , cfg_false , CFGF_NONE ) , // Active le maintien actif du mode monitor
# endif // USE_PTHREAD
2009-04-15 14:15:49 +02:00
CFG_STR ( " rtap_iface " , " " , CFGF_NONE ) , // Interface radiotap utilisée pour la capture
CFG_STR ( " wifi_iface " , " " , CFGF_NONE ) , // Interface physique correspondante (utilisée pour récupérer l'adresse MAC)
2009-08-04 12:02:52 +02:00
CFG_BOOL ( " verbose " , cfg_false , CFGF_NONE ) , // Afficher les paquets capturés ou pas
2009-04-15 14:15:49 +02:00
CFG_END ( ) } ;
2009-07-02 13:12:51 +02:00
2009-04-15 14:15:49 +02:00
char * config_file ; // Nom du fichier de configuration
2009-07-02 09:42:15 +02:00
# endif // USE_CONFIG_FILE
2009-04-15 14:15:49 +02:00
int opt ; // Retour de getopt
/* L'option -f sert à spécifier un fichier de configuration alternatif,
* on regarde en premier si elle est présente */
do
opt = getopt ( argc , argv , OPTIONS ) ;
while ( opt ! = ' f ' & & opt ! = - 1 ) ;
if ( opt = = ' f ' )
2008-02-14 08:54:51 +01:00
{
2009-07-02 09:42:15 +02:00
# ifdef USE_CONFIG_FILE
2009-04-15 14:15:49 +02:00
config_file = malloc ( ( strlen ( optarg ) + 1 ) * sizeof ( char ) ) ;
strcpy ( config_file , optarg ) ;
2009-07-02 09:42:15 +02:00
# else // USE_CONFIG_FILE
fprintf ( stderr , " Attention ! Le programme a été compilé sans le support des fichiers de configuration, l'option -f n'est donc pas disponible. Vous devez passer toutes les options sur la ligne de commandes, sans quoi les valeurs par défaut seront utilisées. \n " ) ;
# endif // USE_CONFIG_FILE
2009-04-15 14:15:49 +02:00
}
2009-07-02 09:42:15 +02:00
# ifdef USE_CONFIG_FILE
2009-04-15 14:15:49 +02:00
else // Si -f n'est pas présente, on utilise le fichier de config par défaut
{
config_file = malloc ( ( strlen ( DEFAULT_CONFIG_FILE ) + 1 ) * sizeof ( char ) ) ;
strcpy ( config_file , DEFAULT_CONFIG_FILE ) ;
}
/* Lecture du fichier de configuration */
cfg = cfg_init ( opts , CFGF_NONE ) ; // Initialisation des options
2009-08-04 12:02:52 +02:00
switch ( cfg_parse ( cfg , config_file ) )
2009-04-15 14:15:49 +02:00
{
2009-08-04 12:02:52 +02:00
case CFG_FILE_ERROR :
fprintf ( stderr , " Erreur lors de l'ouverture du fichier de configuration « %s » : %s. \n " , config_file , strerror ( errno ) ) ;
break ;
case CFG_PARSE_ERROR :
fprintf ( stderr , " Erreur lors de la lecture du fichier de configuration « %s » ! \n " , config_file ) ;
2009-04-15 14:15:49 +02:00
free ( config_file ) ;
return ERR_PARSING_CONFIG_FILE ;
}
free ( config_file ) ;
2009-07-02 09:42:15 +02:00
# endif // USE_CONFIG_FILE
2009-04-15 14:15:49 +02:00
/* Lecture des arguments de la ligne de commandes */
optind = 1 ; // On reprend l'analyse des arguments au début
while ( ( opt = getopt ( argc , argv , OPTIONS ) ) ! = - 1 )
{
switch ( opt )
{
case ' d ' :
2009-07-02 09:42:15 +02:00
SET_AGGREGATION_IP ( optarg ) ;
break ;
2009-07-02 13:12:51 +02:00
case ' f ' : // Fichier de configuration
// Déjà traité.
break ;
2009-07-02 09:42:15 +02:00
case ' k ' :
# ifdef USE_PTHREAD
SET_KEEP_MONITOR ( ) ;
# else // USE_PTHREAD
fprintf ( stderr , " Attention ! Le programme a été compilé sans le support des threads POSIX, l'option -k (maintien du mode monitor) n'est donc pas disponible et sera ignorée. \n " ) ;
# endif // USE_PTHREAD
2009-04-15 14:15:49 +02:00
break ;
2009-07-02 13:12:51 +02:00
case ' l ' :
SET_LISTENING_PORT ( strtol ( optarg , NULL , 0 ) ) ;
break ;
2009-08-04 12:02:52 +02:00
case ' m ' :
SET_MODE ( optarg [ 0 ] ) ;
break ;
2009-04-15 14:15:49 +02:00
case ' p ' :
2009-07-02 09:42:15 +02:00
SET_AGGREGATION_PORT ( strtol ( optarg , NULL , 0 ) ) ;
2009-04-15 14:15:49 +02:00
break ;
2009-08-04 12:02:52 +02:00
case ' q ' :
UNSET_VERBOSE ( ) ;
break ;
2009-04-15 14:15:49 +02:00
case ' r ' :
2009-07-02 09:42:15 +02:00
SET_RTAP_IFACE ( optarg ) ;
2009-04-15 14:15:49 +02:00
break ;
2009-08-04 12:02:52 +02:00
case ' v ' :
SET_VERBOSE ( ) ;
break ;
2009-04-15 14:15:49 +02:00
case ' w ' :
2009-07-02 09:42:15 +02:00
SET_WIFI_IFACE ( optarg ) ;
2009-04-15 14:15:49 +02:00
break ;
default :
print_usage ( argv [ 0 ] ) ;
return ERR_BAD_USAGE ;
}
}
/* Vérification des arguments */
2009-08-04 12:02:52 +02:00
switch ( GET_MODE ( ) )
{
case MODE_ACTIVE :
case MODE_MIXED :
case MODE_PASSIVE :
break ;
default :
fprintf ( stderr , " Erreur ! Mode « %c » inconnu. \n " , ( char ) GET_MODE ( ) ) ;
print_usage ( argv [ 0 ] ) ;
return ERR_BAD_USAGE ;
}
2009-07-02 09:42:15 +02:00
if ( GET_RTAP_IFACE ( ) [ 0 ] = = ' \0 ' )
2009-04-15 14:15:49 +02:00
{
fprintf ( stderr , " Erreur ! Vous devez spécifier une interface radiotap pour la capture. \n " ) ;
2008-02-14 08:54:51 +01:00
print_usage ( argv [ 0 ] ) ;
return ERR_BAD_USAGE ;
}
2009-07-02 09:42:15 +02:00
if ( GET_WIFI_IFACE ( ) [ 0 ] = = ' \0 ' )
2009-04-15 14:15:49 +02:00
{
# ifdef DEBUG
2009-07-02 09:42:15 +02:00
fprintf ( stderr , " Attention ! Aucune interface Wi-Fi spécifiée. Utilisation de l'interface radiotap (%s) à la place. \n " , GET_RTAP_IFACE ( ) ) ;
2009-04-15 14:15:49 +02:00
# endif // DEBUG
2009-07-02 09:42:15 +02:00
SET_WIFI_IFACE ( GET_RTAP_IFACE ( ) ) ;
2009-04-15 14:15:49 +02:00
}
# ifdef DEBUG
/* Affichage de la configuration */
fprintf ( stderr , " Configuration : \n " ) ;
2009-07-02 09:42:15 +02:00
# ifdef USE_CONFIG_FILE
2009-04-15 14:15:49 +02:00
cfg_print ( cfg , stderr ) ;
2009-07-02 09:42:15 +02:00
# else // USE_CONFIG_FILE
fprintf ( stderr , " \
aggregation_ip = \ " %s \" \n \
2009-07-02 13:12:51 +02:00
aggregation_port = % ld \ n \
listening_port = % ld \ n \
2009-07-02 09:42:15 +02:00
rtap_iface = \ " %s \" \n \
wifi_iface = \ " %s \" \n \
" ,
GET_AGGREGATION_IP ( ) ,
GET_AGGREGATION_PORT ( ) ,
2009-07-02 13:12:51 +02:00
GET_LISTENING_PORT ( ) ,
2009-07-02 09:42:15 +02:00
GET_RTAP_IFACE ( ) ,
GET_WIFI_IFACE ( )
) ;
# ifdef USE_PTHREAD
fprintf ( stderr , " keep_monitor = %s \n " ,
GET_KEEP_MONITOR ( ) ? " true " : " false "
) ;
# endif // USE_PTHREAD
# endif // USE_CONFIG_FILE
2009-04-15 14:15:49 +02:00
# endif // DEBUG
2008-02-14 08:54:51 +01:00
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 ) ;
2009-07-02 09:42:15 +02:00
# ifdef USE_PTHREAD
2008-02-27 17:37:08 +01:00
/* Création du thread */
2009-07-02 09:42:15 +02:00
if ( GET_KEEP_MONITOR ( ) )
pthread_create ( & thread , NULL , ( void * ) & keep_mode_monitor , GET_WIFI_IFACE ( ) ) ;
# endif // USE_PTHREAD
2008-02-27 17:37:08 +01:00
2009-07-02 09:42:15 +02:00
get_mac_addr ( GET_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 ) ;
2009-08-04 12:02:52 +02:00
ret = capture ( ) ;
2009-04-15 14:15:49 +02:00
2009-07-02 09:42:15 +02:00
# ifdef USE_CONFIG_FILE
2009-04-15 14:15:49 +02:00
cfg_free ( cfg ) ; // Nettoyage de la configuration
2009-07-02 09:42:15 +02:00
# endif // USE_CONFIG_FILE
2008-02-14 08:54:51 +01:00
printf ( " %s : fin. \n " , argv [ 0 ] ) ;
return ret ;
}
2008-03-14 11:31:04 +01:00
2009-07-02 09:42:15 +02:00
# ifdef USE_PTHREAD
2008-02-27 17:37:08 +01:00
/* Fonction du thread, qui surveille la liste et envoie les infos au serveur de localisation au bout du timeout */
void * keep_mode_monitor ( char * iface )
{
while ( run )
{
iface_mode_monitor ( iface ) ; // Passage de l'interface en mode Monitor.
2008-03-14 11:31:04 +01:00
sleep ( 1 ) ; // Pause de 1 secondes.
2008-02-27 17:37:08 +01:00
}
2009-07-02 09:42:15 +02:00
pthread_exit ( NULL ) ;
2008-02-27 17:37:08 +01:00
}
2009-07-02 09:42:15 +02:00
# endif // USE_PTHREAD
2008-02-27 17:37:08 +01:00
2008-02-14 08:54:51 +01:00
2009-08-04 12:02:52 +02:00
/* Capture des paquets en utilisant l'interface RTAP figurant dans les options.
* Les données capturées sont envoyées au serveur d ' aggrégation dont l ' IP
* figure é galement dans les options .
2008-02-22 16:04:49 +01:00
*/
2009-08-04 12:02:52 +02:00
int capture ( )
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 )
{
2009-08-04 12:02:52 +02:00
// On appelle la fonction read_packet() avec les mêmes arguments,
// plus les informations concernant le serveur :
read_packet ( args , header , packet , sockfd , & server ) ;
2008-02-14 08:54:51 +01:00
}
2009-08-04 12:02:52 +02:00
handle = pcap_open_live ( GET_RTAP_IFACE ( ) , BUFSIZ , 1 , 1000 , errbuf ) ; // Début de la capture
2008-02-14 08:54:51 +01:00
if ( handle = = NULL ) // Le lancement de la capture a-t-il échoué ?
{
2009-08-04 12:02:52 +02:00
fprintf ( stderr , " Impossible d'ouvrir l'interface « %s » : %s \n " , GET_RTAP_IFACE ( ) , errbuf ) ;
2008-02-14 08:54:51 +01:00
return ERR_OPENING_IFACE ;
}
/* Ouverture de la socket UDP vers le serveur d'aggrégation */
2009-08-04 12:02:52 +02:00
sockfd = create_udp_sending_socket ( GET_AGGREGATION_IP ( ) , GET_AGGREGATION_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". */
2009-08-04 12:02:52 +02:00
void read_packet ( u_char * args , const struct pcap_pkthdr * header , const u_char * packet , int sockfd , struct sockaddr_in * server )
2008-02-14 08:54:51 +01:00
{
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...)
2008-03-14 11:31:04 +01:00
unsigned char raw_packet_flags ; // Flags de l'en-tête IEEE 802.11
2008-02-20 16:36:44 +01:00
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)
2009-07-02 11:10:22 +02:00
# ifdef PLATFORM_ATHEROS
rtap_bytes = ( ( rtap_bytes & 0xff00 ) > > 8 ) + ( ( rtap_bytes & 0xff ) < < 8 ) ;
# endif // PLATFORM_ATHEROS
2008-02-20 16:36:44 +01:00
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)
2009-07-02 11:10:22 +02:00
# ifdef PLATFORM_ATHEROS
memcpy ( ( unsigned char * ) & dst_port , & data [ rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + IP_HEADER_SIZE + 2 ] , 2 ) ; // On récupère le port de destination
# else // PLATFORM_ATHEROS
2008-11-06 08:41:32 +01:00
memcpy ( ( unsigned char * ) & dst_port , & data [ rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + IP_HEADER_SIZE + 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 + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + IP_HEADER_SIZE + 2 ] , 1 ) ; // Port de destination = troisième et quatrième octets suivant l'en-tête IP.
2009-07-02 11:10:22 +02:00
# endif // PLATFORM_ATHEROS
2008-03-14 11:31:04 +01:00
raw_packet_flags = data [ rtap_bytes + 1 ] ; // On récupère les flags 802.11, qui sont dans l'en-tête 802.11.
# ifdef DEBUG
if ( raw_packet_type = = RAW_PACKET_TYPE_DATA
& & data [ rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + 9 ] = = RAW_PACKET_PROTO_UDP
2009-07-02 13:12:51 +02:00
& & dst_port = = GET_LISTENING_PORT ( ) )
2008-03-14 11:31:04 +01:00
{
printf ( " raw_packet_flags : %02x \n " , raw_packet_flags ) ;
if ( IS_RETRY ( raw_packet_flags ) )
printf ( " Retry : pas à traiter \n " ) ;
}
2009-04-15 14:15:49 +02:00
# endif // DEBUG
2008-02-20 16:36:44 +01:00
2009-08-04 12:02:52 +02:00
/* Mode actif */
if ( ( GET_MODE ( ) = = MODE_ACTIVE | | GET_MODE ( ) = = MODE_MIXED )
& & raw_packet_type = = RAW_PACKET_TYPE_DATA // Si le paquet est de type data,
2008-03-14 11:31:04 +01:00
& & data [ rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + 9 ] = = RAW_PACKET_PROTO_UDP // et de protocole UDP (9 : position du champ "Protocol" de l'en-tête IP),
& & dst_port = = LOC_REQUEST_DEFAULT_PORT // et le port de destination est le bon,
& & ! IS_RETRY ( raw_packet_flags ) ) // et ce n'est pas un Retry.
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
2009-05-29 17:02:20 +02:00
memcpy ( couple . mobile_ip_addr_bytes , & data [ rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + 12 ] , 4 ) ; // L'adresse IP source est à la position 12 de l'en-tête IP
2008-02-14 08:54:51 +01:00
gettimeofday ( & couple . start_time , NULL ) ;
2008-03-14 11:31:04 +01:00
packet_type = data [ rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + IP_HEADER_SIZE + UDP_HEADER_SIZE ] ;
2008-02-14 08:54:51 +01:00
2008-03-14 11:31:04 +01:00
memcpy ( & couple . request_time , & data [ rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + IP_HEADER_SIZE + UDP_HEADER_SIZE + 1 ] , sizeof ( struct timeval ) ) ;
2008-02-14 08:54:51 +01:00
switch ( packet_type )
{
case PACKET_TYPE_NORMAL :
2009-08-04 12:02:52 +02:00
if ( GET_VERBOSE ( ) )
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 :
2009-08-04 12:02:52 +02:00
if ( GET_VERBOSE ( ) )
2008-02-20 16:36:44 +01:00
printf ( " \n Paquet de calibration reçu. \n " ) ;
2008-03-14 11:31:04 +01:00
couple . direction = data [ rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + IP_HEADER_SIZE + UDP_HEADER_SIZE + 9 ] ;
memcpy ( & couple . x_position , & data [ rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + IP_HEADER_SIZE + UDP_HEADER_SIZE + 10 ] , sizeof ( float ) ) ;
memcpy ( & couple . y_position , & data [ rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + IP_HEADER_SIZE + UDP_HEADER_SIZE + 14 ] , sizeof ( float ) ) ;
memcpy ( & couple . z_position , & data [ rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + IP_HEADER_SIZE + UDP_HEADER_SIZE + 18 ] , sizeof ( float ) ) ;
2008-02-14 08:54:51 +01:00
break ;
default :
2009-08-04 12:02:52 +02:00
if ( GET_VERBOSE ( ) )
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
2009-07-02 11:10:22 +02:00
# ifdef PLATFORM_ATHEROS
rtap_presentflags = ( ( rtap_presentflags & 0xff000000 ) > > 24 ) + ( ( rtap_presentflags & 0xff0000 ) > > 8 ) + ( ( rtap_presentflags & 0xff00 ) < < 8 ) + ( ( rtap_presentflags & 0xff ) < < 24 ) ;
# endif // PLATFORM_ATHEROS
2008-02-14 08:54:51 +01:00
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 ;
2009-08-04 12:02:52 +02:00
if ( GET_VERBOSE ( ) )
2008-02-14 08:54:51 +01:00
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 ;
}
2009-08-04 12:02:52 +02:00
if ( GET_VERBOSE ( ) )
2008-02-14 08:54:51 +01:00
{
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 \
2008-03-14 11:31:04 +01:00
\ tNuméro de séquence ( heure de la demande ) : % llu \ n \
\ tHeure d ' arrivée de la demande de localisation sur l ' AP : % llu \ n \
2008-02-14 08:54:51 +01:00
\ 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 ;
}
}
2009-08-04 12:02:52 +02:00
/* Mode passif */
else if ( GET_MODE ( ) = = MODE_PASSIVE | | GET_MODE ( ) = = MODE_MIXED )
{
/* TODO */
}
2008-02-14 08:54:51 +01:00
}
/* 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 )
2008-02-27 17:37:08 +01:00
perror ( " Impossible d'ouvrir la socket pour récupérer l'adresse MAC " ) ;
2008-02-14 08:54:51 +01:00
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 \
2009-08-04 12:02:52 +02:00
\ t % s [ - f config_file ] [ - m mode ] [ - d ip_agrégation ] [ - l listening_port ] [ - p port_agrégation ] - r rtap_iface [ - w wifi_iface ] [ - k ] [ - v | - q ] \ n \
2009-07-02 09:42:15 +02:00
- L ' option - f permet de spécifier un fichier de configuration alternatif ( le fichier de configuration par défaut ne sera pas lu ) . Disponible uniquement si le programme a é té compilé avec le support de libconfuse . \ n \
2009-08-04 12:02:52 +02:00
- mode est le mode de fonctionnement : a ( ctif ) , p ( assif ) , m ( ixte ) ( par défaut : a ) . \ n \
2009-04-15 14:15:49 +02:00
- ip_agrégation est l ' adresse IP du serveur d ' agrégation ( par défaut : 127.0 .0 .1 ) , et port_agrégation le port sur lequel il é coute ( par défaut : % d ) . \ n \
2008-02-14 08:54:51 +01:00
- rtap_iface est l ' interface de capture radiotap . \ n \
2009-04-15 14:15:49 +02:00
- wifi_iface est l ' interface physique correspondant à rtap_iface ( par défaut : rtap_iface ) . \ n \
2009-07-02 09:42:15 +02:00
- L ' option - k active le maintien actif du mode monitor . À utiliser avec des pilotes bogués . Disponible uniquement si le programme a é té compilé avec le support des threads POSIX . \ n \
2009-08-04 12:02:52 +02:00
- L ' option - v rend le programme bavard ( affichage des paquets capturés ) ; l ' option - q annule le bavardage s ' il est activé par ailleurs ( e . g . fichier de configuration ) . Par défaut le mode verbeux est désactivé . \ n \
2009-04-15 14:15:49 +02:00
Note : tous les paramètres sont facultatifs si les options correspondantes sont renseignées dans un fichier de configuration . L ' option - f permet de spécifier un fichier de configuration alternatif ( par défaut : % s ) . \ n \
2009-08-04 12:02:52 +02:00
" ,
prog ,
AGGREGATE_DEFAULT_PORT ,
DEFAULT_CONFIG_FILE
) ;
2008-02-14 08:54:51 +01:00
}