320 lines
8.0 KiB
C
320 lines
8.0 KiB
C
/*
|
|
* This file is part of the rtap localisation project.
|
|
*/
|
|
|
|
|
|
#include "owlps.h"
|
|
|
|
|
|
#define DEBUG
|
|
|
|
|
|
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)
|
|
{
|
|
case CHANNEL_1 :
|
|
c = 1 ;
|
|
break ;
|
|
case CHANNEL_2 :
|
|
c = 2 ;
|
|
break ;
|
|
case CHANNEL_3 :
|
|
c = 3 ;
|
|
break ;
|
|
case CHANNEL_4 :
|
|
c = 4 ;
|
|
break ;
|
|
case CHANNEL_5 :
|
|
c = 5 ;
|
|
break ;
|
|
case CHANNEL_6 :
|
|
c = 6 ;
|
|
break ;
|
|
case CHANNEL_7 :
|
|
c = 7 ;
|
|
break ;
|
|
case CHANNEL_8 :
|
|
c = 8 ;
|
|
break ;
|
|
case CHANNEL_9 :
|
|
c = 9 ;
|
|
break ;
|
|
case CHANNEL_10 :
|
|
c = 10 ;
|
|
break ;
|
|
case CHANNEL_11 :
|
|
c = 11 ;
|
|
break ;
|
|
case CHANNEL_12 :
|
|
c = 12 ;
|
|
break ;
|
|
case CHANNEL_13 :
|
|
c = 13 ;
|
|
break ;
|
|
case CHANNEL_14 :
|
|
c = 14 ;
|
|
break ;
|
|
}
|
|
|
|
return c ;
|
|
}
|
|
|
|
|
|
|
|
/* Convertit une date au format struct timeval en une valeur entière en millisecondes, et retourne le résultat */
|
|
unsigned long long timeval_to_ms(struct timeval d)
|
|
{
|
|
return d.tv_sec * 1000 + d.tv_usec / 1000 ;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Convertit une date sous forme de valeur entière en millisecondes,
|
|
* en une struct timeval, et retourne cette structure.
|
|
struct timeval ms_to_timeval(unsigned long long tms)
|
|
{
|
|
struct timeval d ;
|
|
d.tv_sec = tms / 1000 ;
|
|
d.tv_usec = (tms - d.tv_sec * 1000) * 1000 ;
|
|
return d ;
|
|
}
|
|
*/
|
|
|
|
|
|
|
|
/* Retourne le temps (en millisecondes) écoulé entre deux dates */
|
|
unsigned long sub_date(struct timeval sup, struct timeval inf)
|
|
{
|
|
unsigned long sub = abs(timeval_to_ms(sup) - timeval_to_ms(inf)) ;
|
|
#ifdef DEBUG
|
|
printf("sub_date() : sub=%lu\n", sub) ;
|
|
#endif
|
|
return sub ;
|
|
}
|
|
|
|
|
|
|
|
/* 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 ") ;
|
|
return sockfd ;
|
|
}
|
|
|
|
/* 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
|
|
// client_description->sin_port = htons(0) ; // N'importe quel port (ne sert à rien a priori)
|
|
|
|
/* 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
|
|
|
|
return sockfd ; // On retourne le descripteur de la socket créée
|
|
}
|
|
|
|
|
|
|
|
/* 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 ") ;
|
|
return sockfd ;
|
|
}
|
|
|
|
/* 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
|
|
}
|
|
|
|
|
|
|
|
/* Bascule l'interface Wi-Fi "iface" en mode Monitor si elle n'y est pas déjà */
|
|
int iface_mode_monitor(char *iface)
|
|
{
|
|
struct iwreq wrq ;
|
|
int sockfd = iw_sockets_open() ;
|
|
|
|
|
|
strncpy((&wrq)->ifr_name, iface, IFNAMSIZ) ;
|
|
|
|
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
|
|
{
|
|
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 ;
|
|
}
|
|
}
|
|
|
|
close(sockfd) ;
|
|
|
|
return 0 ;
|
|
}
|
|
|
|
|
|
|
|
/* Change le canal de l'interface Wi-Fi "iface" avec la valeur "channel" (numéro de 1 à 14) */
|
|
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 ;
|
|
}
|
|
|
|
close(sockfd) ;
|
|
|
|
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).
|
|
|
|
close(sockfd) ;
|
|
|
|
/* 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.
|
|
}
|
|
|
|
|
|
|
|
/* Gestionnaire de signal générique pour SIGINT */
|
|
void sigint_handler(int num)
|
|
{
|
|
if (num != SIGINT)
|
|
{
|
|
fprintf(stderr, "Erreur ! Gestionnaire de SIGINT appelé mais le signal n'est pas SIGINT.\n") ;
|
|
exit(ERR_BAD_SIGNAL) ;
|
|
}
|
|
|
|
run = FALSE ;
|
|
|
|
printf("\nSignal reçu : fin du programme.\n");
|
|
fflush(NULL) ;
|
|
}
|
|
|
|
|
|
|
|
/* Gestionnaire de signal générique pour SIGTERM */
|
|
void sigterm_handler(int num)
|
|
{
|
|
if (num != SIGTERM)
|
|
{
|
|
fprintf(stderr, "Erreur ! Gestionnaire de SIGTERM appelé mais le signal n'est pas SIGINT.\n") ;
|
|
exit(ERR_BAD_SIGNAL) ;
|
|
}
|
|
|
|
sigint_handler(SIGINT) ;
|
|
}
|