2008-02-14 08:54:51 +01:00
/*
* This file is part of the rtap localisation project .
*/
# include "rtaputil.h"
BOOL run = TRUE ;
/* Convertit une adresse MAC en octets en une chaîne de caractères.
* ¡ Il est nécessaire de libérer manuellement le retour de cette fonction !
*/
char * mac_bytes_to_string ( unsigned char * mac_binary )
{
char * ret = malloc ( sizeof ( char ) * 18 ) ;
sprintf ( ret , " %02x:%02x:%02x:%02x:%02x:%02x " , mac_binary [ 0 ] , mac_binary [ 1 ] , mac_binary [ 2 ] , mac_binary [ 3 ] , mac_binary [ 4 ] , mac_binary [ 5 ] ) ;
ret [ 17 ] = ' \0 ' ;
return ret ;
}
/* Convertit un identifiant de canal en son numéro (0 si la fréquence est erronée) */
char frequency_to_channel ( unsigned short channel )
{
char c = 0 ; // Résultat
switch ( channel )
{
2008-02-26 16:51:49 +01:00
case CHANNEL_1 :
2008-02-14 08:54:51 +01:00
c = 1 ;
break ;
2008-02-26 16:51:49 +01:00
case CHANNEL_2 :
2008-02-14 08:54:51 +01:00
c = 2 ;
break ;
2008-02-26 16:51:49 +01:00
case CHANNEL_3 :
2008-02-14 08:54:51 +01:00
c = 3 ;
break ;
2008-02-26 16:51:49 +01:00
case CHANNEL_4 :
2008-02-14 08:54:51 +01:00
c = 4 ;
break ;
2008-02-26 16:51:49 +01:00
case CHANNEL_5 :
2008-02-14 08:54:51 +01:00
c = 5 ;
break ;
2008-02-26 16:51:49 +01:00
case CHANNEL_6 :
2008-02-14 08:54:51 +01:00
c = 6 ;
break ;
2008-02-26 16:51:49 +01:00
case CHANNEL_7 :
2008-02-14 08:54:51 +01:00
c = 7 ;
break ;
2008-02-26 16:51:49 +01:00
case CHANNEL_8 :
2008-02-14 08:54:51 +01:00
c = 8 ;
break ;
2008-02-26 16:51:49 +01:00
case CHANNEL_9 :
2008-02-14 08:54:51 +01:00
c = 9 ;
break ;
2008-02-26 16:51:49 +01:00
case CHANNEL_10 :
2008-02-14 08:54:51 +01:00
c = 10 ;
break ;
2008-02-26 16:51:49 +01:00
case CHANNEL_11 :
2008-02-14 08:54:51 +01:00
c = 11 ;
break ;
2008-02-26 16:51:49 +01:00
case CHANNEL_12 :
2008-02-14 08:54:51 +01:00
c = 12 ;
break ;
2008-02-26 16:51:49 +01:00
case CHANNEL_13 :
2008-02-14 08:54:51 +01:00
c = 13 ;
break ;
2008-02-26 16:51:49 +01:00
case CHANNEL_14 :
2008-02-14 08:54:51 +01:00
c = 14 ;
break ;
}
return c ;
}
/* Retourne une date au format struct timeval en mili-secondes */
unsigned long timeval_to_ms ( struct timeval d )
{
return d . tv_sec * 1000 + d . tv_usec / 1000 ;
}
2008-02-22 16:04:49 +01:00
/* Retourne le temps (en millisecondes) écoulé entre deux dates */
2008-02-14 08:54:51 +01:00
unsigned long sub_date ( struct timeval sup , struct timeval inf )
{
unsigned long sup_ms = sup . tv_sec * 1000 + sup . tv_usec / 1000 ;
unsigned long inf_ms = inf . tv_sec * 1000 + inf . tv_usec / 1000 ;
return abs ( sup_ms - inf_ms ) ;
}
/* Compare deux adresses MAC : retourne TRUE si elles sont égales, FALSE sinon */
BOOL mac_cmp ( unsigned char * mac1 , unsigned char * mac2 )
{
int i ;
for ( i = 0 ; i < 6 ; i + + )
if ( mac1 [ i ] ! = mac2 [ i ] )
return FALSE ;
return TRUE ;
}
/* Crée une socket d'envoi UDP et retourne son descripteur.
* Paramètres :
* - server_address : l ' adresse IP du serveur .
* - server_port : le port d ' é coute du serveur .
* - server_description ( paramètre résultat ) : la structure dans laquelle sera enregistrée la description du serveur .
* - client_description ( paramètre résultat ) : la structure dans laquelle sera enregistrée la description du client .
*/
int create_udp_sending_socket ( char * server_address , int server_port , struct sockaddr_in * server_description , struct sockaddr_in * client_description )
{
int sockfd ; // Descripteur de la socket
/* Ceation de la socket UDP */
sockfd = socket ( AF_INET , SOCK_DGRAM , 0 ) ;
if ( sockfd < 0 )
{
perror ( " Échec de la création de la socket " ) ;
2008-02-26 16:51:49 +01:00
return sockfd ;
2008-02-14 08:54:51 +01:00
}
/* Remise à zéro et initialisation de la structure du client */
bzero ( ( char * ) client_description , sizeof ( * client_description ) ) ;
client_description - > sin_family = AF_INET ; // Socket INET
client_description - > sin_addr . s_addr = htonl ( INADDR_ANY ) ; // Toutes les connexions
2008-02-16 10:58:12 +01:00
// client_description->sin_port = htons(0) ; // N'importe quel port (ne sert à rien a priori)
2008-02-14 08:54:51 +01:00
/* Remise à zéro et initialisation de la structure du serveur */
bzero ( ( char * ) server_description , sizeof ( * server_description ) ) ; // RÀZ
server_description - > sin_family = AF_INET ; // Socket INET
server_description - > sin_addr . s_addr = inet_addr ( server_address ) ; // Adresse du serveur
server_description - > sin_port = htons ( server_port ) ; // Port d'écoute du serveur
2008-02-26 16:51:49 +01:00
return sockfd ; // On retourne le descripteur de la socket créée
2008-02-14 08:54:51 +01:00
}
/* Crée une socket d'écoute UDP et retourne son descripteur.
* Paramètres :
* - port est le port sur lequel é couter .
*/
int create_udp_listening_socket ( int port )
{
int sockfd ; // Descripteur de la socket
struct sockaddr_in server_description ; // Structure du serveur
int ret = 0 ; // Valeur de retour
/* Création d'une socket UDP */
sockfd = socket ( AF_INET , SOCK_DGRAM , 0 ) ;
if ( sockfd < 0 )
{
perror ( " Échec de la création de la socket " ) ;
2008-02-26 16:51:49 +01:00
return sockfd ;
2008-02-14 08:54:51 +01:00
}
/* Remise à zéro et initialisation de la structure du serveur */
bzero ( ( char * ) & server_description , sizeof ( server_description ) ) ; // RÀZ
server_description . sin_family = AF_INET ; // Socket INET
server_description . sin_addr . s_addr = htonl ( INADDR_ANY ) ; // Toutes les connexions sont acceptées
server_description . sin_port = htons ( port ) ; // Port d'écoute
/* Réservation du port */
ret = bind ( sockfd , ( struct sockaddr * ) & server_description , sizeof ( server_description ) ) ;
if ( ret < 0 )
{
perror ( " Impossible de créer la socket (bind) " ) ;
( void ) close ( sockfd ) ;
return ret ;
}
return sockfd ; // On retourne le descripteur de la socket créée
}
2008-02-27 17:37:08 +01:00
/* Bascule l'interface Wi-Fi "iface" en mode Monitor si elle n'y est pas déjà */
2008-02-26 16:51:49 +01:00
int iface_mode_monitor ( char * iface )
{
struct iwreq wrq ;
int sockfd = iw_sockets_open ( ) ;
2008-02-27 17:37:08 +01:00
2008-02-26 16:51:49 +01:00
strncpy ( ( & wrq ) - > ifr_name , iface , IFNAMSIZ ) ;
2008-02-27 17:37:08 +01:00
if ( ioctl ( sockfd , SIOCGIWMODE , & wrq ) = = - 1 ) // Récupération du mode actuel
{
perror ( " Erreur lors de la lecture du mode " ) ;
return ERR_READING_MODE ;
}
if ( wrq . u . mode ! = IW_MODE_MONITOR ) // Si on n'est pas déjà en mode Monitor
2008-02-26 16:51:49 +01:00
{
2008-02-27 17:37:08 +01:00
wrq . u . mode = IW_MODE_MONITOR ;
if ( ioctl ( sockfd , SIOCSIWMODE , & wrq ) = = - 1 ) // on y passe.
{
perror ( " Erreur lors du passage en mode Monitor " ) ;
return ERR_SETTING_MONITOR_MODE ;
}
2008-02-26 16:51:49 +01:00
}
return 0 ;
}
/* Change le canal de l'interface Wi-Fi "iface" avec la valeur "channel" */
int iface_set_channel ( char * iface , int channel )
{
struct iwreq wrq ;
int sockfd = iw_sockets_open ( ) ;
strncpy ( ( & wrq ) - > ifr_name , iface , IFNAMSIZ ) ;
iw_float2freq ( channel , & ( wrq . u . freq ) ) ;
wrq . u . freq . flags = IW_FREQ_FIXED ;
if ( ioctl ( sockfd , SIOCSIWFREQ , & wrq ) = = - 1 )
{
perror ( " Erreur lors du changement de canal " ) ;
return ERR_SETTING_CHANNEL ;
}
return 0 ;
}
/* Fait varier le canal de l'interface Wi-Fi "iface" entre les canaux 4 et 11 */
int iface_channel_hop ( char * iface )
{
unsigned short channel ;
struct iwreq wrq ;
int sockfd = iw_sockets_open ( ) ;
strncpy ( ( & wrq ) - > ifr_name , iface , IFNAMSIZ ) ;
if ( ioctl ( sockfd , SIOCGIWFREQ , & wrq ) = = - 1 )
{
perror ( " Erreur lors de la lecture de la fréquence " ) ;
return ERR_READING_CHANNEL ;
}
channel = wrq . u . freq . m / 100000 ; // Un peu gruik : il vaudrait mieux utiliser iw_freq2float(), iw_freq_to_channel() et compagnie (cf. /usr/include/{iwlib.h,wireless.h}).
if ( channel > 1000 ) // Si la valeur est en Hz,
channel = frequency_to_channel ( channel ) ; // on la convertit en numéro de canal (avec notre fonction maison, toujours un peu gruik).
/* Changement de canal */
if ( channel = = 4 ) // Si le canal est déjà à 4,
return iface_set_channel ( iface , 11 ) ; // on le passe à 11 ;
else
return iface_set_channel ( iface , 4 ) ; // sinon on le met à 4.
}
2008-02-14 08:54:51 +01:00
void sigint_handler ( int num )
{
if ( num ! = SIGINT )
{
fprintf ( stderr , " Erreur ! Gestionnaire de SIGINT appelé mais le signal n'est pas SIGINT. \n " ) ;
2008-02-26 16:51:49 +01:00
exit ( ERR_BAD_SIGNAL ) ;
2008-02-14 08:54:51 +01:00
}
run = FALSE ;
printf ( " \n Signal reçu : fin du programme. \n " ) ;
fflush ( NULL ) ;
}
void sigterm_handler ( int num )
{
if ( num ! = SIGTERM )
{
fprintf ( stderr , " Erreur ! Gestionnaire de SIGTERM appelé mais le signal n'est pas SIGINT. \n " ) ;
2008-02-26 16:51:49 +01:00
exit ( ERR_BAD_SIGNAL ) ;
2008-02-14 08:54:51 +01:00
}
sigint_handler ( SIGINT ) ;
}