Plusieurs corrections, surtout librtapanalyser

librtapanalyser :
	- Suppression des fonctions redondantes avec librtaputil.
	- Correction du code, utilisation des fonctions de librtaputil.
	- Préparation du renommage en librtapscanmob.
M    loc-mobile/code/librtapanalyser/rtapanalyser.h
M    loc-mobile/code/librtapanalyser/tx.c
M    loc-mobile/code/librtapanalyser/Makefile
M    loc-mobile/code/librtapanalyser/librtapanalyser.c

Modifications et corrections mineures :
M    loc-bts/code/ap/apd.c
M    loc-bts/code/ap/ap.h
M    loc-bts/code/librtaputil/rtaputil.h
M    loc-bts/code/librtaputil/librtaputil.c
M    loc-bts/code/rtapaggregate/rtapaggregated.c
M    loc-bts/code/rtapaggregate/rtapaggregate.h

A    loc-bts/TODO : Ajout d'une liste des choses à faire.

git-svn-id: https://pif.pu-pm.univ-fcomte.fr/svn/loc@16 785a6c6c-259e-4ff1-8b91-dc31627914f0
This commit is contained in:
Matteo Cypriani 2008-02-22 15:04:49 +00:00
parent 2751fd7905
commit 8781613d97
11 changed files with 391 additions and 498 deletions

3
loc-bts/TODO Normal file
View File

@ -0,0 +1,3 @@
* apd : permettre d'utiliser un nom d'hôte putôt qu'une IP pour le serveur d'agrégation.
* Permettre de choisir soi-même le port des communications, aussi bien sur le mobile (demande de localisation), que sur les AP et le serveur d'agrégation. Pour l'instant, les ports sont gérés grâce aux constantes AGGREGATE_DEFAULT_PORT et LOC_REQUEST_DEFAULT_PORT.

View File

@ -2,17 +2,18 @@
* This file is part of the rtap localisation project.
*/
#ifndef _AP_H
#define _AP_H
#include "../librtaputil/rtaputil.h"
#include <pcap.h>
#include <fcntl.h>
// Pour la fonction get_mac_addr() :
#include <netinet/if_ether.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <sys/ioctl.h>
//#include <net/if.h>
/* Codes d'erreurs */
@ -31,3 +32,6 @@ int capture(char *capture_iface, char *aggregated_ip, BOOL print_values) ;
void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet, int sockfd, struct sockaddr_in *server, BOOL print_values) ;
void get_mac_addr(char *eth, unsigned char mac_bytes[6]) ;
void print_usage(char *prog) ;
#endif

View File

@ -9,6 +9,7 @@
unsigned char mac[6] ; // Adresse MAC de l'AP
int main(int argc, char *argv[])
{
struct sigaction action ; // Structure de mise en place des gestionnaires de signaux
@ -44,15 +45,13 @@ int main(int argc, char *argv[])
/* Capture des paquets en utilisant l'interface "capture_iface" pendant "capture_time" mili-secondes.
Les informations concernant les mobiles effectuant des requêtes sont conservées dans la liste "known_mobiles".
Les données capturées sont envoyées au serveur d'aggrégation dont l'IP est "aggregated_ip" à travers la socket UDP "socket".
*/
/* 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".
*/
int capture(char *capture_iface, char *aggregated_ip, BOOL print_values)
{
pcap_t *handle ; // Descripteur de capture de paquets
char errbuf[PCAP_ERRBUF_SIZE] ;// Message d'erreur
// struct timeval tbegin, tcurrent ;
pcap_t *handle ; // Descripteur de capture de paquets
char errbuf[PCAP_ERRBUF_SIZE] ; // Message d'erreur
int sockfd ; // Descripteur de la socket vers le serveur d'aggrégation
struct sockaddr_in server, client ;
@ -92,7 +91,8 @@ int capture(char *capture_iface, char *aggregated_ip, BOOL print_values)
/* Traite un paquet et l'envoie au serveur d'agrégation */
/* Traite un paquet et l'envoie au serveur d'agrégation sur la socket UDP "sockfd", au serveur "server". */
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é
@ -111,12 +111,12 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p
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).
if (raw_packet_type == 0x08 // Si le paquet est de type data,
&& data[rtap_bytes+24+8+9] == 0x11 // 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),
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),
&& dst_port == LOC_REQUEST_DEFAULT_PORT) // et le port de destination est le bon.
{
memcpy(couple.ap_mac_addr_bytes, mac, 6); // On copie la MAC de l'AP
memcpy(couple.mobile_mac_addr_bytes, &data[rtap_bytes+10], 6); // Dans le cas du beacon, l'adresse MAC est 10 octets plus loin
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
gettimeofday(&couple.start_time, NULL) ;
packet_type = data[rtap_bytes+24+8+20+8] ;
@ -154,11 +154,11 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p
memcpy(&rtap_presentflags, &data[RTAP_P_PRESENTFLAGS], RTAP_L_PRESENTFLAGS); // Récupère les flags de l'en-tête rtap
for (i = 0 ; i < 15 ; i++)
for (i = 0 ; i < 15 ; i++) // Initialisation de la structure des champs présents
check[i] = FALSE ;
rtap_position = 8 ; // début des champs déterminés par le present flag
rtap_position = 8 ; // Début des champs déterminés par le present flag
for(i=0 ; i < 14 ; i++) // on teste les 15 premiers bits du champ flag afin de valider la présence et de les copier
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
{
if ((rtap_presentflags % 2) == 1)
{

View File

@ -89,7 +89,7 @@ unsigned long timeval_to_ms(struct timeval d)
/* Retourne le temps (en mili-secondes) écoulé entre deux dates */
/* Retourne le temps (en millisecondes) écoulé entre deux dates */
unsigned long sub_date(struct timeval sup, struct timeval inf)
{
unsigned long sup_ms = sup.tv_sec * 1000 + sup.tv_usec / 1000 ;

View File

@ -2,6 +2,9 @@
* This file is part of the rtap localisation project.
*/
#ifndef _LIB_RTAPUTIL_H
#define _LIB_RTAPUTIL_H
#include <stdio.h>
#include <unistd.h>
@ -18,6 +21,8 @@
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@ -53,7 +58,19 @@ typedef struct _couple_message
} couple_message ;
/* Types de paquets */
/* Types des paquets capturés (data[rtap_bytes]) */
#define RAW_PACKET_TYPE_BEACON 0x80
#define RAW_PACKET_TYPE_DATA 0x08
/* Protocoles des paquets capturés (data[rtap_bytes+24+8+9]) */
#define RAW_PACKET_PROTO_UDP 0x11
#define RAW_PACKET_PROTO_ICMP 0x01
/* Type de paquet ICMP : octet suivant la fin de l'en-tête IP (data[rtap_bytes+24+8+20]) */
#define RAW_PACKET_ICMP_ECHO 0x08
/* Types de demandes de localisation */
#define PACKET_TYPE_NORMAL 0
#define PACKET_TYPE_CALIBRATION 1
@ -126,3 +143,6 @@ void sigterm_handler(int num) ;
// Réseau
int create_udp_listening_socket(int port) ;
int create_udp_sending_socket(char *server_address, int server_port, struct sockaddr_in *server_description, struct sockaddr_in * client_description) ;
#endif

View File

@ -2,6 +2,9 @@
* This file is part of the rtap localisation project.
*/
#ifndef _RTAPAGGREGATE_H
#define _RTAPAGGREGATE_H
#include "../librtaputil/rtaputil.h"
#include <signal.h>
@ -21,6 +24,12 @@
#define KEEP_TIMEOUT 2000 // Temps que l'on conserve les données dans la liste (en mili-secondes)
#define CHECK_INTERVAL 500000 // Temps entre deux vérifications de la liste (en micro-secondes)
/* Arguments du programme */
#define ARGC 2
#define ARGV_OUTPUT_FILE 1
/* Codes d'erreur */
#define ERR_NO_MESSAGE_RECEIVED 1 // Erreur lors de la lecture sur la socket
#define ERR_CREATING_SOCKET 2 // Erreur lors de la création de la socket d'écoute
@ -59,3 +68,6 @@ void print_couple_list(couple_list *couples) ;
void print_couple_info(couple_info_list *info) ;
void* monitor_couple_list(couple_list **couples) ;
void print_usage(char *prog) ;
#endif

View File

@ -22,7 +22,7 @@ int main(int argc, char **argv)
pthread_t thread ; // Thread pour la fonction de surveillance de la liste d'informations agrégées
char *ap_mac_string, *mobile_mac_string ; // Pointeurs pour retour de mac_bytes_to_string()
if (argc != 2)
if (argc != ARGC)
{
print_usage(argv[0]) ;
return ERR_BAD_USAGE ;
@ -32,8 +32,8 @@ int main(int argc, char **argv)
/* Fichier de sortie */
out_file = malloc((strlen(argv[1]) + 1) * sizeof(char)) ;
strcpy(out_file, argv[1]) ;
out_file = malloc((strlen(argv[ARGV_OUTPUT_FILE]) + 1) * sizeof(char)) ;
strcpy(out_file, argv[ARGV_OUTPUT_FILE]) ;
/* Mise en place des gestionnaires de signaux */
@ -185,7 +185,9 @@ void* monitor_couple_list(couple_list **couples)
usleep(CHECK_INTERVAL) ; // On attend avant de vérifier à nouveau
}
fclose(fd) ;
/* Fermeture du fichier */
if (fclose(fd) != 0)
perror("Erreur lors de la fermeture du fichier de sortie ") ;
return NULL ;
}

View File

@ -17,14 +17,14 @@ RM=rm -fv
CP=cp -v
# Variables générales
LIB_CIBLE=librtapanalyser
LIB_CIBLE=librtapscanmob
VERSION=1.0
# Cibles à construire
STATIC=$(LIB_CIBLE).a
DYNAMIC=$(LIB_CIBLE).so.$(VERSION)
PROGS=tx
HEADER=rtapanalyser.h
HEADER=rtapscanmob.h
#HEADERS=
# Composition de la bibliothèque
@ -35,7 +35,7 @@ CFLAGS=-O2 -W -Wall -Wstrict-prototypes -I.
DEPFLAGS=-MMD
XCFLAGS=$(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS)
PICFLAG=-fPIC
LIBS=-lm -lpcap
LIBS=-lm -lpcap ../../../loc-bts/code/librtaputil/librtaputil.so.1.0
#STRIPFLAGS= -Wl,-s

View File

@ -4,386 +4,22 @@
*/
#include "rtapanalyser.h"
#include "rtapscanmob.h"
/* Convertit une adresse MAC en octets en une chaîne de caractères */
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 ;
}
BOOL run = TRUE ;
/* 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 2412 :
c = 1 ;
break ;
case 2417 :
c = 2 ;
break ;
case 2422 :
c = 3 ;
break ;
case 2427 :
c = 4 ;
break ;
case 2432 :
c = 5 ;
break ;
case 2437 :
c = 6 ;
break ;
case 2442 :
c = 7 ;
break ;
case 2447 :
c = 8 ;
break ;
case 2452 :
c = 9 ;
break ;
case 2457 :
c = 10 ;
break ;
case 2462 :
c = 11 ;
break ;
case 2467 :
c = 12 ;
break ;
case 2472 :
c = 13 ;
break ;
case 2477 :
c = 14 ;
break ;
}
return c ;
}
/* Retourne le temps écoulé entre deux dates */
unsigned int sub_date(struct timeb sup, struct timeb inf)
{
unsigned int ret = 0 ;
unsigned int sec_sup = sup.time ;
unsigned int sec_inf = inf.time ;
if(sup.millitm < inf.millitm)
{
ret = 1000 + sup.millitm - inf.millitm ;
sec_sup-- ;
}
else
ret = sup.millitm - inf.millitm ;
ret += (sec_sup - sec_inf) * 1000 ;
return ret ;
}
/* 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 ;
}
/* Affiche la liste chaînée des résultats */
void print_mac_list(mac_list *results, BOOL verbose)
{
mac_list *mac_ptr = results ; // Récupère la liste d'adresse MAC en entrée
ss_list *ss_ptr = NULL ; // Initialise la sous-liste
double antenna_signal_average = 0 ; // Moyenne des valeurs récupérées de antenna signal en dBm
double antenna_noise_average = 0; // Moyenne des valeurs récupérées de antenna noise en dBm
double data_rate_average = 0; // Moyenne du débit
unsigned short channel = -1 ; // Canal utilisé pour la MAC courante
unsigned short channel_type = -1 ; // Type de liaison utilisée pour la MAC courante
if (results == NULL) // Si la liste est vide
{
printf("Aucun résultat.\n") ; // on l'affiche.
return ;
}
while (mac_ptr != NULL)
{
//printf("%s\n", mac_bytes_to_string(mac_ptr->mac_addr_bytes)) ; // On convertit l'adresse MAC en chaîne de caractères pour l'afficher
ss_ptr = mac_ptr->samples_list ; // On récupère le pointeur de la sous-liste
antenna_signal_average = 0 ;
antenna_noise_average = 0 ;
data_rate_average = 0 ;
while (ss_ptr != NULL) // On parcourt toutes les valeurs de l'affaiblissement en dB et on en fait la moyenne.
{
antenna_signal_average += pow((double)10, ((double)(ss_ptr->antenna_signal_dbm - 0x100) / 10)) ; // Il faut le minorer de 256 pour avoir la vrai puissance car sinon codage serai sur plus d'un octet.
antenna_noise_average += pow((double)10, ((double)(ss_ptr->antenna_noise_dbm - 0x100) / 10)) ;
data_rate_average += ((ss_ptr->data_rate) / 2);
channel = ss_ptr->channel ;
channel_type = ss_ptr->channel_type ;
if (verbose) // Affichage du maillon si on est en mode verbeux.
{
printf("[%s]\n", mac_bytes_to_string(mac_ptr->mac_addr_bytes)) ;
print_ss_list(ss_ptr) ;
putchar('\n') ;
}
ss_ptr = ss_ptr->next ;
}
/* Calcul des moyennes */
antenna_signal_average = 10 * log10((double)(antenna_signal_average / mac_ptr->nb_samples)) ;
antenna_noise_average = 10 * log10((double)(antenna_noise_average / mac_ptr->nb_samples)) ;
data_rate_average /= (double)mac_ptr->nb_samples ;
/* Affichage */
printf("[%s] [Canal : %hhd] [Fréquence : %hu MHz] [Type de liaison : %#06x] [Moyenne du débit : %0.1f Mo/s] [Moyenne du signal : %0.1f dBm] [Moyenne du bruit : %0.1f dBm]\n", mac_bytes_to_string(mac_ptr->mac_addr_bytes), frequency_to_channel(channel), channel, channel_type, data_rate_average, antenna_signal_average, antenna_noise_average) ;
if (verbose)
printf("\n\n") ;
mac_ptr = mac_ptr->next ;
}
}
/* Affiche un maillon d'une sous-liste de résultats */
void print_ss_list(ss_list *ss)
{
if (ss == NULL)
return ;
/* Champs statiques */
printf("Header revision : %hhu\n", ss->header_revision) ;
printf("Header Pad : %hhu\n", ss->header_pad) ;
printf("Header Length : %hu\n", ss->header_length) ;
printf("Present flags : %#010lx\n", ss->present_flags) ; // Largeur de champ 10 : 2 pour "0x" et 8 pour la valeur.
/* Champs dynamiques */
if (ss->check[RTAP_MACTS])
printf("Mac timestamp : %llu\n", ss->mac_timestamp) ;
if (ss->check[RTAP_FLAGS])
printf("Flags : %hu\n", ss->flags) ;
if (ss->check[RTAP_RATE])
printf("Data rate : %hhd MB/s\n", ss->data_rate / 2) ;
if (ss->check[RTAP_CHANNEL])
printf("Channel : %hu MHz\nChannel Type : %#06x\n", ss->channel, ss->channel_type) ;
if (ss->check[RTAP_FHSS])
printf("FHSS : %hu\n", ss->fhss) ;
if (ss->check[RTAP_ANTENNASIGNALDBM])
printf("Antenna Signal : %d dBm\n", ss->antenna_signal_dbm - 0x100) ;
if (ss->check[RTAP_ANTENNANOISEDBM])
printf("Antenna Noise : %d dBm\n", ss->antenna_noise_dbm - 0x100) ;
if (ss->check[RTAP_LOCKQUALITY])
printf("Lock Quality : %hu\n", ss->lock_quality) ;
if (ss->check[RTAP_TXATTENUATION])
printf("Taux Attenuation : %hu\n", ss->tx_attenuation) ;
if (ss->check[RTAP_TXATTENUATIONDB])
printf("Atténuation : %hu dB\n", ss->tx_attenuation_db) ;
if (ss->check[RTAP_TXATTENUATIONDBM])
printf("Atténuation : %hu dBm\n", ss->tx_attenuation_dbm) ;
if (ss->check[RTAP_ANTENNA])
printf("Antenna : %hhu\n", ss->antenna) ;
if (ss->check[RTAP_ANTENNASIGNALDB])
printf("Antenna Signal : %hhu dB\n", ss->antenna_signal_db) ;
if (ss->check[RTAP_ANTENNANOISEDB])
printf("Antenna Noise : %hhu dB\n", ss->antenna_noise_db) ;
if (ss->check[RTAP_FCS])
printf("FCS : %lu\n", ss->fcs) ;
}
/* Vide la liste chaînée d'adresse MAC */
void free_mac_list(mac_list **results)
{
mac_list *mac_ptr = *results ;
ss_list *ss_ptr = NULL ;
if (*results != NULL)
{
while(mac_ptr != NULL)
{
ss_ptr = mac_ptr->samples_list ;
while (ss_ptr != NULL)
{
ss_ptr = ss_ptr->next ;
free(mac_ptr->samples_list) ;
mac_ptr->samples_list = ss_ptr ;
}
mac_ptr = mac_ptr->next ;
free(*results) ;
*results = mac_ptr ;
}
}
}
/* Enregistre la liste "results" dans le fichier "file" */
int write_mac_list_to_file(char *file, mac_list *results)
{
int fd = 0 ; // Descripteur de fichier.
mac_list *ptr ; // Tête de lecture de la liste chaînée.
ss_list *ss_ptr ; // Tête de lecture de la sous-liste.
int mac_list_size = sizeof(mac_list) ;
int ss_list_size = sizeof(ss_list) ;
//printf("Début de l'enregistrement des résulats dans le fichier « %s »...\n", file) ;
/* Ouverture du fichier */
fd = open(file, O_WRONLY | O_CREAT) ;
if (fd < 0)
{
perror("Impossible d'ouvrir le fichier de sortie ") ;
return ERR_OPENING_FILE ;
}
/* Écriture des données */
ptr = results ; // On commence par la tête de la liste (forcément...).
while (ptr != NULL)
{
//printf("Enregistrement (%s)...\n", mac_bytes_to_string(ptr->mac_addr_bytes)) ;
/* Enregistrement du maillon de la liste principale */
if (write(fd, ptr, mac_list_size) != mac_list_size)
perror("Erreur d'écriture (mac_list) ") ;
/* Enregistrement de la sous-liste */
ss_ptr = ptr->samples_list ;
while (ss_ptr != NULL)
{
if (write(fd, ss_ptr, ss_list_size) != ss_list_size) // Écriture du maillon courant.
perror("Erreur d'écriture (ss_list) ") ;
ss_ptr = ss_ptr->next ;
}
ptr = ptr->next ;
}
/* Fermeture du fichier */
if (close(fd) != 0)
perror("Erreur lors de la fermeture du fichier de sortie ") ;
return 0 ;
}
/* Lit le fichier "file" et enregistre la liste lue dans "results" */
int read_mac_list_from_file(char *file, mac_list **results)
{
int fd = 0 ; // Descripteur de fichier.
mac_list *ptr = NULL ; // Tête de lecture de la liste chaînée.
ss_list *ss_ptr ; // Tête de lecture de la sous-liste.
ss_list *ss_prev ; // Maillon précédent lors de la lecture.
int mac_list_size = sizeof(mac_list) ;
int ss_list_size = sizeof(ss_list) ;
mac_list mac_list_lu ;
ss_list ss_list_lu ;
//printf("Début de la lecture du fichier « %s »...\n", file) ;
/* Ouverture du fichier */
fd = open(file, O_RDONLY) ;
if (fd < 0)
{
perror("Impossible d'ouvrir le fichier d'entrée ") ;
return ERR_OPENING_FILE ;
}
/* Lecture des données */
while (read(fd, &mac_list_lu, mac_list_size) == mac_list_size) // Lecture du premier champ
{
//printf("Lecture (%s)...\n", mac_bytes_to_string(mac_list_lu.mac_addr_bytes)) ; // Affichage de la MAC actuelle.
/* Allocation du maillon courant */
if (*results == NULL)
{
*results = malloc(mac_list_size) ; // Création de la liste
ptr = *results ;
}
else
{
ptr->next = malloc(mac_list_size) ; // Création du maillon suivant
ptr = ptr->next ;
}
*ptr = mac_list_lu ;
/* Lecture de la sous-liste */
ss_prev = NULL ;
ss_ptr = ptr->samples_list ;
while (ss_ptr != NULL)
{
if (read(fd, &ss_list_lu, ss_list_size) != ss_list_size) // Lecture d'un maillon ss_list.
perror("Erreur de lecture (ss_list) ") ;
else // Si on a bien lu un maillon entier :
{
if (ss_prev == NULL) // Si c'est le premier maillon,
{
ptr->samples_list = malloc(ss_list_size) ; // allocation du premier maillon.
ss_ptr = ptr->samples_list ;
}
else // Si ce n'est pas le premier maillon,
{
ss_prev->next = malloc(ss_list_size) ; // allocation d'un nouveau maillon.
ss_ptr = ss_prev->next ;
}
*ss_ptr = ss_list_lu ;
ss_prev = ss_ptr ;
ss_ptr = ss_ptr->next ;
}
}
if (ss_prev != NULL)
ss_prev->next = NULL ;
}
//printf("Fin de la lecture.\n") ;
if (ptr != NULL)
ptr->next = NULL ;
/* Fermeture du fichier */
if (close(fd) != 0)
perror("Erreur lors de la fermeture du fichier de sortie ") ;
return 0 ;
}
/* Capture des paquets en utilisant l'interface "capture_iface" pendant "capture_time" mili-secondes, et enregistre les paquets lus dans "results" */
/* Capture des paquets en utilisant l'interface "capture_iface" pendant "capture_time" millisecondes,
* et enregistre les paquets lus dans "results" */
int capture(char *capture_iface, unsigned long capture_time, mac_list **results, BOOL print_values)
{
pcap_t *handle ; // Descripteur de capture de paquets
char errbuf[PCAP_ERRBUF_SIZE] ;// Message d'erreur
struct timeb tbegin, tcurrent ;
pcap_t *handle ; // Descripteur de capture de paquets
char errbuf[PCAP_ERRBUF_SIZE] ; // Message d'erreur
struct timeval tbegin, tcurrent ;
/* Sous-fonction de traitement des paquets capturés */
@ -393,30 +29,34 @@ int capture(char *capture_iface, unsigned long capture_time, mac_list **results,
}
if (capture_time < 1) // Le temps de capture doit être d'au moins 1 ms.
{
fprintf(stderr, "Durée de capture incorrecte !\n") ;
return ERR_CAPTURE_TIME_FORMAT ;
}
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) ;
return ERR_OPENING_IFACE ;
}
ftime(&tbegin) ; // Récupère l'heure courante (heure du lancement de la capture)
while(1)
if (capture_time > 0) // Si le temps de capture est positif
{
pcap_loop(handle, 1, got_packet, NULL) ; // Collecte 1 paquet et appelle la fonction got_packet quand pcaploop a recupéré des paquets
ftime(&tcurrent) ; // Récupère l'heure courante
if(sub_date(tcurrent, tbegin) > capture_time) // Si le temps de capture est écoulé
break ; // on arrête la collecte.
gettimeofday(&tbegin, NULL) ; // Récupère l'heure courante (heure du lancement de la capture)
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
gettimeofday(&tcurrent, NULL) ; // Récupère l'heure courante
if(sub_date(tcurrent, tbegin) > capture_time) // Si le temps de capture est écoulé
break ; // on arrête la collecte.
}
}
else // On fonctionne en mode démon (tant que run est vrai)
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.
return 0 ;
@ -424,27 +64,26 @@ int capture(char *capture_iface, unsigned long capture_time, mac_list **results,
/* Traite un paquet et enregistre les valeurs dans la liste des résultats (results) */
void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet, mac_list **results, BOOL print_values)
{
unsigned char *data = (unsigned char *) packet ; // Recopie dans data l'adresse du paquet capturé
unsigned short rtap_bytes ; // Taille des données reçues
unsigned int rtap_presentflags, rtap_position ;
BOOL check[15] ; // Champs présents
unsigned char raw_packet_type ; // Type du packet reçu (beacon, data...)
unsigned char mac_addr_bytes[6] ;
mac_list *tmp_mac = NULL ;
ss_list *tmp_ss = NULL ;
unsigned char *data = (unsigned char *) packet ; // Recopie dans data l'adresse du paquet capturé
unsigned short int rtap_bytes ; // Taille des données reçues
unsigned char c ;
int i ;
unsigned int rtap_presentflags, rtap_position ;
// unsigned int ss_position = 0 ;
unsigned char mac_addr_binary[6] ;
// unsigned char *mac_addr_string ;
// int rtap_data_size[15] = {8,1,1,4,2,1,1,2,2,2,1,1,1,1,4} ;
int k=0;
int i ; // Compteur
memcpy(&rtap_bytes, &data[2], sizeof(unsigned short int)) ; // 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)
c = 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)
if(c == 0x80) // Si c'est un beacon on le traite
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)
if (raw_packet_type == RAW_PACKET_TYPE_BEACON) // Si le paquet est de type beacon, on le traite
{
memcpy(mac_addr_binary, &data[rtap_bytes+10], 6); // Dans le cas du beacon, l'adresse MAC est 10 octets plus loin
memcpy(mac_addr_bytes, &data[rtap_bytes+10], 6); // Dans le cas du beacon, l'adresse MAC est 10 octets plus loin que le type de paquet
memcpy(&rtap_presentflags, &data[RTAP_P_PRESENTFLAGS], RTAP_L_PRESENTFLAGS); // Récupère les flags de l'en-tête rtap
/* Ajout du résultat du scan à la structure */
@ -455,20 +94,23 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p
memcpy(&(tmp_ss->header_length), &data[RTAP_P_HLENGTH], RTAP_L_HLENGTH) ;
memcpy(&(tmp_ss->present_flags), &data[RTAP_P_PRESENTFLAGS], RTAP_L_PRESENTFLAGS) ;
for(k=0 ; k < 15 ; k++)
tmp_ss->check[k] = FALSE ;
for(i = 0 ; i < 15 ; i++) // Initialisation de la structure des champs présents
tmp_ss->check[i] = FALSE ;
rtap_position = 8 ; // début des champs déterminés par le present flag
if (print_values)
{
printf("[%s]\n", mac_bytes_to_string(mac_addr_binary)) ;
char *mac_string = mac_bytes_to_string(mac_addr_bytes) ;
printf("[%s]\n", mac_string) ;
printf("Header revision : %hhu\n", tmp_ss->header_revision) ;
printf("Header Pad : %hhu\n", tmp_ss->header_pad) ;
printf("Header Length : %hu\n", tmp_ss->header_length) ;
printf("Present flags : %#010lx\n", tmp_ss->present_flags) ;
free(mac_string) ;
}
for(i=0 ; i < 14 ; i++) // on teste les 15 premiers bits du champ flag afin de valider la présence et de les copier
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
{
if((rtap_presentflags % 2) == 1)
{
@ -595,7 +237,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p
if(*results == NULL) // Si la liste de résultats n'existe pas encore,
{
tmp_mac = malloc(sizeof(mac_list)) ; // on la crée.
memcpy(tmp_mac->mac_addr_bytes, mac_addr_binary, 6) ;
memcpy(tmp_mac->mac_addr_bytes, mac_addr_bytes, 6) ;
tmp_mac->nb_samples = 1 ;
tmp_mac->next = NULL ;
tmp_mac->samples_list = tmp_ss ;
@ -605,14 +247,14 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p
{
while(tmp_mac != NULL)
{
if(mac_cmp(mac_addr_binary, tmp_mac->mac_addr_bytes) == 1)
if(mac_cmp(mac_addr_bytes, tmp_mac->mac_addr_bytes) == 1)
break ;
tmp_mac = tmp_mac->next ;
}
if(tmp_mac == NULL)
{
tmp_mac = malloc(sizeof(mac_list)) ;
memcpy(tmp_mac->mac_addr_bytes, mac_addr_binary, 6) ;
memcpy(tmp_mac->mac_addr_bytes, mac_addr_bytes, 6) ;
tmp_mac->nb_samples = 1 ;
tmp_mac->next = *results ;
tmp_mac->samples_list = tmp_ss ;
@ -627,3 +269,272 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p
}
}
}
/* Affiche la liste chaînée des résultats */
void print_mac_list(mac_list *results, BOOL verbose)
{
mac_list *mac_ptr = results ; // Récupère la liste d'adresse MAC en entrée
ss_list *ss_ptr = NULL ; // Initialise la sous-liste
char *mac_string ;
double antenna_signal_average = 0 ; // Moyenne des valeurs récupérées de antenna signal en dBm
double antenna_noise_average = 0; // Moyenne des valeurs récupérées de antenna noise en dBm
double data_rate_average = 0; // Moyenne du débit
unsigned short channel = -1 ; // Canal utilisé pour la MAC courante
unsigned short channel_type = -1 ; // Type de liaison utilisée pour la MAC courante
if (results == NULL) // Si la liste est vide
{
printf("Aucun résultat.\n") ; // on l'affiche.
return ;
}
while (mac_ptr != NULL)
{
mac_string = mac_bytes_to_string(mac_ptr->mac_addr_bytes) ;
ss_ptr = mac_ptr->samples_list ; // On récupère le pointeur de la sous-liste
antenna_signal_average = 0 ;
antenna_noise_average = 0 ;
data_rate_average = 0 ;
while (ss_ptr != NULL) // On parcourt toutes les valeurs de l'affaiblissement en dB et on en fait la moyenne.
{
antenna_signal_average += pow((double)10, ((double)(ss_ptr->antenna_signal_dbm - 0x100) / 10)) ; // Il faut le minorer de 256 pour avoir la vrai puissance car sinon codage serai sur plus d'un octet.
antenna_noise_average += pow((double)10, ((double)(ss_ptr->antenna_noise_dbm - 0x100) / 10)) ;
data_rate_average += ((ss_ptr->data_rate) / 2);
channel = ss_ptr->channel ;
channel_type = ss_ptr->channel_type ;
if (verbose) // Affichage du maillon si on est en mode verbeux.
{
printf("[%s]\n", mac_string) ;
print_ss_list(ss_ptr) ;
putchar('\n') ;
}
ss_ptr = ss_ptr->next ;
}
/* Calcul des moyennes */
antenna_signal_average = 10 * log10((double)(antenna_signal_average / mac_ptr->nb_samples)) ;
antenna_noise_average = 10 * log10((double)(antenna_noise_average / mac_ptr->nb_samples)) ;
data_rate_average /= (double)mac_ptr->nb_samples ;
/* Affichage */
printf("[%s] [Canal : %hhd] [Fréquence : %hu MHz] [Type de liaison : %#06x] [Moyenne du débit : %0.1f Mo/s] [Moyenne du signal : %0.1f dBm] [Moyenne du bruit : %0.1f dBm]\n", mac_string, frequency_to_channel(channel), channel, channel_type, data_rate_average, antenna_signal_average, antenna_noise_average) ;
if (verbose)
printf("\n\n") ;
free(mac_string) ;
mac_ptr = mac_ptr->next ;
}
}
/* Affiche un maillon d'une sous-liste de résultats */
void print_ss_list(ss_list *ss)
{
if (ss == NULL)
return ;
/* Champs statiques */
printf("Header revision : %hhu\n", ss->header_revision) ;
printf("Header Pad : %hhu\n", ss->header_pad) ;
printf("Header Length : %hu\n", ss->header_length) ;
printf("Present flags : %#010lx\n", ss->present_flags) ; // Largeur de champ 10 : 2 pour "0x" et 8 pour la valeur.
/* Champs dynamiques */
if (ss->check[RTAP_MACTS])
printf("Mac timestamp : %llu\n", ss->mac_timestamp) ;
if (ss->check[RTAP_FLAGS])
printf("Flags : %hu\n", ss->flags) ;
if (ss->check[RTAP_RATE])
printf("Data rate : %hhd MB/s\n", ss->data_rate / 2) ;
if (ss->check[RTAP_CHANNEL])
printf("Channel : %hu MHz\nChannel Type : %#06x\n", ss->channel, ss->channel_type) ;
if (ss->check[RTAP_FHSS])
printf("FHSS : %hu\n", ss->fhss) ;
if (ss->check[RTAP_ANTENNASIGNALDBM])
printf("Antenna Signal : %d dBm\n", ss->antenna_signal_dbm - 0x100) ;
if (ss->check[RTAP_ANTENNANOISEDBM])
printf("Antenna Noise : %d dBm\n", ss->antenna_noise_dbm - 0x100) ;
if (ss->check[RTAP_LOCKQUALITY])
printf("Lock Quality : %hu\n", ss->lock_quality) ;
if (ss->check[RTAP_TXATTENUATION])
printf("Taux Attenuation : %hu\n", ss->tx_attenuation) ;
if (ss->check[RTAP_TXATTENUATIONDB])
printf("Atténuation : %hu dB\n", ss->tx_attenuation_db) ;
if (ss->check[RTAP_TXATTENUATIONDBM])
printf("Atténuation : %hu dBm\n", ss->tx_attenuation_dbm) ;
if (ss->check[RTAP_ANTENNA])
printf("Antenna : %hhu\n", ss->antenna) ;
if (ss->check[RTAP_ANTENNASIGNALDB])
printf("Antenna Signal : %hhu dB\n", ss->antenna_signal_db) ;
if (ss->check[RTAP_ANTENNANOISEDB])
printf("Antenna Noise : %hhu dB\n", ss->antenna_noise_db) ;
if (ss->check[RTAP_FCS])
printf("FCS : %lu\n", ss->fcs) ;
}
/* Vide la liste chaînée d'adresse MAC */
void free_mac_list(mac_list **results)
{
mac_list *mac_ptr = *results ;
ss_list *ss_ptr = NULL ;
if (*results != NULL)
{
while(mac_ptr != NULL)
{
ss_ptr = mac_ptr->samples_list ;
while (ss_ptr != NULL)
{
ss_ptr = ss_ptr->next ;
free(mac_ptr->samples_list) ;
mac_ptr->samples_list = ss_ptr ;
}
mac_ptr = mac_ptr->next ;
free(*results) ;
*results = mac_ptr ;
}
}
}
/* Enregistre la liste "results" dans le fichier "file" */
int write_mac_list_to_file(char *file, mac_list *results)
{
int fd = 0 ; // Descripteur de fichier.
mac_list *ptr ; // Tête de lecture de la liste chaînée.
ss_list *ss_ptr ; // Tête de lecture de la sous-liste.
int mac_list_size = sizeof(mac_list) ;
int ss_list_size = sizeof(ss_list) ;
/* Ouverture du fichier */
fd = open(file, O_WRONLY | O_CREAT) ;
if (fd < 0)
{
perror("Impossible d'ouvrir le fichier de sortie ") ;
return ERR_OPENING_FILE ;
}
/* Écriture des données */
ptr = results ; // On commence par la tête de la liste (forcément...).
while (ptr != NULL)
{
/* Enregistrement du maillon de la liste principale */
if (write(fd, ptr, mac_list_size) != mac_list_size)
perror("Erreur d'écriture (mac_list) ") ;
/* Enregistrement de la sous-liste */
ss_ptr = ptr->samples_list ;
while (ss_ptr != NULL)
{
if (write(fd, ss_ptr, ss_list_size) != ss_list_size) // Écriture du maillon courant.
perror("Erreur d'écriture (ss_list) ") ;
ss_ptr = ss_ptr->next ;
}
ptr = ptr->next ;
}
/* Fermeture du fichier */
if (close(fd) != 0)
perror("Erreur lors de la fermeture du fichier de sortie ") ;
return 0 ;
}
/* Lit le fichier "file" et enregistre la liste lue dans "results" */
int read_mac_list_from_file(char *file, mac_list **results)
{
int fd = 0 ; // Descripteur de fichier.
mac_list *ptr = NULL ; // Tête de lecture de la liste chaînée.
ss_list *ss_ptr ; // Tête de lecture de la sous-liste.
ss_list *ss_prev ; // Maillon précédent lors de la lecture.
int mac_list_size = sizeof(mac_list) ;
int ss_list_size = sizeof(ss_list) ;
mac_list mac_list_lu ;
ss_list ss_list_lu ;
/* Ouverture du fichier */
fd = open(file, O_RDONLY) ;
if (fd < 0)
{
perror("Impossible d'ouvrir le fichier d'entrée ") ;
return ERR_OPENING_FILE ;
}
/* Lecture des données */
while (read(fd, &mac_list_lu, mac_list_size) == mac_list_size) // Lecture du premier champ
{
/* Allocation du maillon courant */
if (*results == NULL)
{
*results = malloc(mac_list_size) ; // Création de la liste
ptr = *results ;
}
else
{
ptr->next = malloc(mac_list_size) ; // Création du maillon suivant
ptr = ptr->next ;
}
*ptr = mac_list_lu ;
/* Lecture de la sous-liste */
ss_prev = NULL ;
ss_ptr = ptr->samples_list ;
while (ss_ptr != NULL)
{
if (read(fd, &ss_list_lu, ss_list_size) != ss_list_size) // Lecture d'un maillon ss_list.
perror("Erreur de lecture (ss_list) ") ;
else // Si on a bien lu un maillon entier :
{
if (ss_prev == NULL) // Si c'est le premier maillon,
{
ptr->samples_list = malloc(ss_list_size) ; // allocation du premier maillon.
ss_ptr = ptr->samples_list ;
}
else // Si ce n'est pas le premier maillon,
{
ss_prev->next = malloc(ss_list_size) ; // allocation d'un nouveau maillon.
ss_ptr = ss_prev->next ;
}
*ss_ptr = ss_list_lu ;
ss_prev = ss_ptr ;
ss_ptr = ss_ptr->next ;
}
}
if (ss_prev != NULL)
ss_prev->next = NULL ;
}
if (ptr != NULL)
ptr->next = NULL ;
/* Fermeture du fichier */
if (close(fd) != 0)
perror("Erreur lors de la fermeture du fichier de sortie ") ;
return 0 ;
}

View File

@ -3,22 +3,14 @@
* thanks to the radiotap header of each packet.
*/
#ifndef _LIB_RTAPSCANMOB_H
#define _LIB_RTAPSCANMOB_H
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <pcap.h>
#include <sys/timeb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <math.h>
#include "../../../loc-bts/code/librtaputil/rtaputil.h"
/* Type booléen */
typedef enum {FALSE, TRUE} BOOL ;
/* Liste chaînée des valeurs des champs rtap */
@ -59,55 +51,6 @@ typedef struct _mac_list
} mac_list ;
/* Position des champs fixes de l'en-tête rtap (octets) */
#define RTAP_P_HREVISION 0 // Header revision
#define RTAP_P_HPAD 1 // Header pad
#define RTAP_P_HLENGTH 2 // Header length
#define RTAP_P_PRESENTFLAGS 4 // Present flags
/* Longueur des champs de l'en-tête rtap (octets) */
#define RTAP_L_HREVISION 1 // Header revision
#define RTAP_L_HPAD 1 // Header pad
#define RTAP_L_HLENGTH 2 // Header length
#define RTAP_L_PRESENTFLAGS 4 // Present flags
#define RTAP_L_MACTS 8 // MAC timestamp
#define RTAP_L_FLAGS 1 // autre champ de flags
#define RTAP_L_RATE 1 // Data rate
#define RTAP_L_CHANNEL 2 // Channel
#define RTAP_L_CHANNELTYPE 2 // Channel type
#define RTAP_L_ANTENNASIGNALDBM 1 // SSI signal dBm
#define RTAP_L_ANTENNANOISEDBM 1 // SSI noise dBm
#define RTAP_L_ANTENNA 1 // Antenna
#define RTAP_L_FHSS 2
#define RTAP_L_LOCKQUALITY 2
#define RTAP_L_TXATTENUATION 2
#define RTAP_L_TXATTENUATIONDB 2
#define RTAP_L_TXATTENUATIONDBM 1
#define RTAP_L_ANTENNASIGNALDB 1 // en dB
#define RTAP_L_ANTENNANOISEDB 1 // en dB
#define RTAP_L_FCS 4
#define RTAP_L_EXT // Non implémenté
/* Positions pour affichage (tableau check de ss_list) */
#define RTAP_MACTS 0
#define RTAP_FLAGS 1
#define RTAP_RATE 2
#define RTAP_CHANNEL 3 // ainsi que RTAP_CHANNELTYPE
#define RTAP_FHSS 4
#define RTAP_ANTENNASIGNALDBM 5
#define RTAP_ANTENNANOISEDBM 6
#define RTAP_LOCKQUALITY 7
#define RTAP_TXATTENUATION 8
#define RTAP_TXATTENUATIONDB 9
#define RTAP_TXATTENUATIONDBM 10
#define RTAP_ANTENNA 11
#define RTAP_ANTENNASIGNALDB 12
#define RTAP_ANTENNANOISEDB 13
#define RTAP_FCS 14
/* Codes d'erreurs */
#define ERR_FILENAME 1 // Erreur dans le nom du fichier d'entrée ou de sortie
#define ERR_OPENING_FILE 2 // Erreur lors de l'ouverture du fichier d'entrée ou de sortie
@ -117,14 +60,12 @@ typedef struct _mac_list
/* En-têtes des fonctions */
int capture(char *capture_iface, unsigned long capture_time, mac_list **results, BOOL print_values) ;
void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet, mac_list **results, BOOL print_values) ;
void print_mac_list(mac_list *results, BOOL verbose) ;
void print_ss_list(ss_list *ss) ;
void free_mac_list(mac_list **results) ;
int write_mac_list_to_file(char *file, mac_list *results) ;
int read_mac_list_from_file(char *file, mac_list **results) ;
void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet, mac_list **results, BOOL print_values) ;
char* mac_bytes_to_string(unsigned char *mac_binary) ;
char frequency_to_channel(unsigned short channel) ;
unsigned int sub_date(struct timeb sup, struct timeb inf) ;
BOOL mac_cmp(unsigned char *mac1, unsigned char *mac2) ;
#endif

View File

@ -4,7 +4,7 @@
*/
#include "rtapanalyser.h"
#include "rtapscanmob.h"