[i-c] Support fichiers config listener/aggregator

Ajout du support des fichiers de configuration et des arguments
(libconfuse / getopt) pour les modules aggregator et listener.
Corrections pour le module client.

git-svn-id: https://pif.pu-pm.univ-fcomte.fr/svn/loc@88 785a6c6c-259e-4ff1-8b91-dc31627914f0
This commit is contained in:
Matteo Cypriani 2009-04-15 12:15:49 +00:00
parent 0d7946e3db
commit f1791d816a
10 changed files with 240 additions and 54 deletions

View File

@ -67,6 +67,7 @@ purge :
help : help :
@echo -e "Bibliothèques nécessaires à la compilation :\n\ @echo -e "Bibliothèques nécessaires à la compilation :\n\
libpcap0.8-dev\n\ libpcap0.8-dev\n\
libconfuse-dev\n\
libiw-dev\n\ libiw-dev\n\
\n\ \n\
Cibles possibles :\n\ Cibles possibles :\n\

View File

@ -56,6 +56,7 @@ purge :
help : help :
@echo -e "Bibliothèques nécessaires à la compilation :\n\ @echo -e "Bibliothèques nécessaires à la compilation :\n\
libpcap0.8-dev\n\ libpcap0.8-dev\n\
libconfuse-dev\n\
libowlps1.0 (fournie)\n\ libowlps1.0 (fournie)\n\
\n\ \n\
Cibles possibles :\n\ Cibles possibles :\n\

View File

@ -9,3 +9,4 @@
* apd : permettre d'utiliser un nom d'hôte putôt qu'une IP pour le serveur d'agrégation. * 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. * 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.
→ Fait pour le port d'agrégation, dans owlps-listener et owlps-aggregator.

View File

@ -21,7 +21,7 @@ CFLAGS=-O2 -W -Wall -Wstrict-prototypes -O -I.
DEPFLAGS=-MMD DEPFLAGS=-MMD
XCFLAGS=$(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) XCFLAGS=$(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS)
PICFLAG=-fPIC PICFLAG=-fPIC
LIBS=-lpthread ../../libowlps/libowlps.so.1.0 LIBS=-lpthread -lconfuse ../../libowlps/libowlps.so.1.0
## Cibles de compilation standard ## ## Cibles de compilation standard ##
@ -62,6 +62,7 @@ purge : clean
help : help :
@echo -e "Bibliothèques nécessaires à la compilation :\n\ @echo -e "Bibliothèques nécessaires à la compilation :\n\
libconfuse-dev\n\
libowlps1.0 (fournie)\n\ libowlps1.0 (fournie)\n\
\n\ \n\
Cibles possibles :\n\ Cibles possibles :\n\

View File

@ -7,25 +7,25 @@
#include "../../libowlps/owlps.h" #include "../../libowlps/owlps.h"
#include <confuse.h>
//#define TIMESTAMP // Décommenter pour afficher le timestamp à chaque ligne du fichier de sortie. //#define TIMESTAMP // Décommenter pour afficher le timestamp à chaque ligne du fichier de sortie.
#define AGGREGATE_TIMEOUT 1500 // Timeout d'agrégation (en millisecondes) /* Arguments & configuration du programme */
#define KEEP_TIMEOUT 3000 // Temps que l'on conserve les données dans la liste (en millisecondes) #define OPTIONS "f:l:o:a:k:c:" // Chaîne pour getopt
#define CHECK_INTERVAL 500000 // Temps entre deux vérifications de la liste (en micro-secondes) #define DEFAULT_CONFIG_FILE "/usr/local/etc/owlps/owlps-aggregator.conf"
#define DEFAULT_AGGREGATE_TIMEOUT 1500 // Timeout d'agrégation (en millisecondes)
#define DEFAULT_KEEP_TIMEOUT 3000 // Temps que l'on conserve les données dans la liste (en millisecondes)
/* Arguments du programme */ #define DEFAULT_CHECK_INTERVAL 500000 // Temps entre deux vérifications de la liste (en micro-secondes)
#define ARGC 2
#define ARGV_OUTPUT_FILE 1
/* Codes d'erreur */ /* Codes d'erreur */
#define ERR_NO_MESSAGE_RECEIVED 1 // Erreur lors de la lecture sur la socket #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 #define ERR_CREATING_SOCKET 2 // Erreur lors de la création de la socket d'écoute
#define ERR_BAD_USAGE 3 // Mauvais appel au programme #define ERR_BAD_USAGE 3 // Mauvais appel au programme
#define ERR_PARSING_CONFIG_FILE 4 // Erreur lors de la lecture du fichier de configuration
/* Liste chaînée des informations concernant un couple MAC / séquence */ /* Liste chaînée des informations concernant un couple MAC / séquence */

View File

@ -8,7 +8,7 @@
#define DEBUG #define DEBUG
char *out_file ; cfg_t *cfg ; // Structure contenant la configuration
int main(int argc, char **argv) int main(int argc, char **argv)
@ -24,18 +24,113 @@ int main(int argc, char **argv)
pthread_t thread ; // Thread pour la fonction de surveillance de la liste d'informations agrégées 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() char *ap_mac_string, *mobile_mac_string ; // Pointeurs pour retour de mac_bytes_to_string()
if (argc != ARGC) cfg_opt_t opts[] = { // Options reconnues par confuse dans le fichier de config
CFG_INT("listening_port", AGGREGATE_DEFAULT_PORT, CFGF_NONE), // Port d'écoute
CFG_STR("output_file", "", CFGF_NONE), // Fichier de sortie
CFG_INT("aggregate_timeout", DEFAULT_AGGREGATE_TIMEOUT, CFGF_NONE), // Timeout d'agrégation (en millisecondes)
CFG_INT("keep_timeout", DEFAULT_KEEP_TIMEOUT, CFGF_NONE), // Temps que l'on conserve les données dans la liste (en millisecondes)
CFG_INT("check_interval", DEFAULT_CHECK_INTERVAL, CFGF_NONE), // Temps entre deux vérifications de la liste (en micro-secondes)
CFG_END() } ;
char *config_file ; // Nom du fichier de configuration
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')
{ {
config_file = malloc((strlen(optarg) + 1) * sizeof(char)) ;
strcpy(config_file, optarg) ;
}
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
if (cfg_parse(cfg, config_file) == CFG_PARSE_ERROR)
{
free(config_file) ;
return ERR_PARSING_CONFIG_FILE ;
}
free(config_file) ;
/* 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 'f' : // Fichier de configuration
// Déjà traité.
break ;
case 'l' :
cfg_setint(cfg, "listening_port", strtol(optarg, NULL, 0)) ;
break ;
case 'o' :
cfg_setstr(cfg, "output_file", optarg) ;
break ;
case 'a' :
cfg_setint(cfg, "aggregate_timeout", strtol(optarg, NULL, 0)) ;
break ;
case 'k' :
cfg_setint(cfg, "keep_timeout", strtol(optarg, NULL, 0)) ;
break ;
case 'c' :
cfg_setint(cfg, "check_interval", strtol(optarg, NULL, 0)) ;
break ;
default :
print_usage(argv[0]) ;
return ERR_BAD_USAGE ;
}
}
/* Vérification des arguments */
// output_file //
if (cfg_getstr(cfg, "output_file")[0] == '\0')
{
fprintf(stderr, "Erreur ! Vous devez spécifier un fichier de sortie.\n") ;
print_usage(argv[0]) ; print_usage(argv[0]) ;
return ERR_BAD_USAGE ; return ERR_BAD_USAGE ;
} }
// aggregate_timeout //
if (cfg_getint(cfg, "aggregate_timeout") < 0)
{
#ifdef DEBUG
fprintf(stderr, "Attention ! aggregate_timeout n'admet pas de valeur négative : application de la valeur par défaut.\n") ;
#endif // DEBUG
cfg_setint(cfg, "aggregate_timeout", DEFAULT_AGGREGATE_TIMEOUT) ;
}
// keep_timeout //
if (cfg_getint(cfg, "keep_timeout") < 0)
{
#ifdef DEBUG
fprintf(stderr, "Attention ! keep_timeout n'admet pas de valeur négative : application de la valeur par défaut.\n") ;
#endif // DEBUG
cfg_setint(cfg, "keep_timeout", DEFAULT_KEEP_TIMEOUT) ;
}
// check_interval //
if (cfg_getint(cfg, "check_interval") < 0)
{
#ifdef DEBUG
fprintf(stderr, "Attention ! check_interval n'admet pas de valeur négative : application de la valeur par défaut.\n") ;
#endif // DEBUG
cfg_setint(cfg, "check_interval", DEFAULT_CHECK_INTERVAL) ;
}
#ifdef DEBUG
/* Affichage de la configuration */
fprintf(stderr, "Configuration :\n") ;
cfg_print(cfg, stderr) ;
#endif // DEBUG
run = TRUE ; run = TRUE ;
/* Fichier de sortie */
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 */ /* Mise en place des gestionnaires de signaux */
sigemptyset(&action.sa_mask) ; sigemptyset(&action.sa_mask) ;
action.sa_handler = sigint_handler ; action.sa_handler = sigint_handler ;
@ -44,10 +139,10 @@ int main(int argc, char **argv)
sigaction(SIGTERM, &action, NULL) ; sigaction(SIGTERM, &action, NULL) ;
/* Création de la socket UDP */ /* Création de la socket UDP */
if ((sockfd = create_udp_listening_socket(AGGREGATE_DEFAULT_PORT)) < 0) if ((sockfd = create_udp_listening_socket(cfg_getint(cfg, "listening_port"))) < 0)
{ {
fprintf(stderr, "Erreur ! Impossible d'écouter sur le port %d.\n", AGGREGATE_DEFAULT_PORT) ; fprintf(stderr, "Erreur ! Impossible d'écouter sur le port %ld.\n", cfg_getint(cfg, "listening_port")) ;
exit(ERR_CREATING_SOCKET) ; return ERR_CREATING_SOCKET ;
} }
/* Création du thread */ /* Création du thread */
@ -98,8 +193,8 @@ int main(int argc, char **argv)
} }
(void) close(sockfd) ; // Fermeture de la socket (void) close(sockfd) ; // Fermeture de la socket
free_couple_list(&couples) ; // Nettoyage free_couple_list(&couples) ; // Nettoyage de la liste
free(out_file) ; cfg_free(cfg) ; // Nettoyage de la configuration
printf("%s : fin.\n", argv[0]) ; printf("%s : fin.\n", argv[0]) ;
return ret ; return ret ;
@ -118,7 +213,7 @@ void* monitor_couple_list(couple_list **couples)
char *ap_mac_string ; char *ap_mac_string ;
unsigned long sub ; // Résultat de sub_date(). unsigned long sub ; // Résultat de sub_date().
fd = fopen(out_file, "a") ; // Ouverture du fichier de sortie en ajout fd = fopen(cfg_getstr(cfg, "output_file"), "a") ; // Ouverture du fichier de sortie en ajout
if (fd == NULL) // Si ouverture échouée, if (fd == NULL) // Si ouverture échouée,
{ {
perror("Impossible d'ouvrir le fichier de sortie ") ; perror("Impossible d'ouvrir le fichier de sortie ") ;
@ -139,14 +234,14 @@ void* monitor_couple_list(couple_list **couples)
if (couple_ptr->info != NULL) // Si le couple atteint n'a pas déjà été traité if (couple_ptr->info != NULL) // Si le couple atteint n'a pas déjà été traité
{ {
if (sub > AGGREGATE_TIMEOUT) // Si le timeout est atteint, if (sub > (unsigned long) cfg_getint(cfg, "aggregate_timeout")) // Si le timeout est atteint,
{ {
printf("* Timeout dépassé.") ; printf("* Timeout dépassé.") ;
#ifdef DEBUG #ifdef DEBUG
printf(" sub=%lu > AGGREGATE_TIMEOUT=%d\n", sub, AGGREGATE_TIMEOUT) ; printf(" sub=%lu > aggregate_timeout=%ld\n", sub, cfg_getint(cfg, "aggregate_timeout")) ;
#else #else // DEBUG
putchar('\n') ; putchar('\n') ;
#endif #endif // DEBUG
#ifdef TIMESTAMP #ifdef TIMESTAMP
fprintf(fd, "%llu;", timeval_to_ms(couple_ptr->request_time)) ; // Inscription de la date de la demande (sur le mobile) dans le fichier fprintf(fd, "%llu;", timeval_to_ms(couple_ptr->request_time)) ; // Inscription de la date de la demande (sur le mobile) dans le fichier
@ -171,16 +266,16 @@ void* monitor_couple_list(couple_list **couples)
} }
} }
else if (sub > KEEP_TIMEOUT) // Si le couple a été traité et que le temps de garde est écoulé else if (sub > (unsigned long) cfg_getint(cfg, "keep_timeout")) // Si le couple a été traité et que le temps de garde est écoulé
{ {
couple_list *couple_tmp = couple_ptr ; couple_list *couple_tmp = couple_ptr ;
printf("* Délai de garde dépassé.") ; printf("* Délai de garde dépassé.") ;
#ifdef DEBUG #ifdef DEBUG
printf(" sub=%lu > KEEP_TIMEOUT=%d\n", sub, KEEP_TIMEOUT) ; printf(" sub=%lu > keep_timeout=%ld\n", sub, cfg_getint(cfg, "keep_timeout")) ;
#else #else // DEBUG
putchar('\n') ; putchar('\n') ;
#endif #endif // DEBUG
couple_ptr = couple_ptr->next ; couple_ptr = couple_ptr->next ;
@ -200,7 +295,7 @@ void* monitor_couple_list(couple_list **couples)
} }
fflush(NULL) ; fflush(NULL) ;
usleep(CHECK_INTERVAL) ; // On attend avant de vérifier à nouveau usleep(cfg_getint(cfg, "check_interval")) ; // On attend avant de vérifier à nouveau
} }
/* Fermeture du fichier */ /* Fermeture du fichier */
@ -379,6 +474,6 @@ void print_couple_info(couple_info_list *info)
void print_usage(char *prog) void print_usage(char *prog)
{ {
printf("Usage :\n\ printf("Usage :\n\
\t%s fichier_sortie\n\ \t%s [-f config_file] [-l listening_port] [-a aggregate_timeout] [-k keep_timeout] [-c check_interval] -o output_file\n\
", prog) ; ", prog) ;
} }

View File

@ -2,7 +2,6 @@
* This file is part of the rtap localisation project. * This file is part of the rtap localisation project.
*/ */
#include <stdlib.h>
#include "../../libowlps/owlps.h" #include "../../libowlps/owlps.h"
#define DEBUG #define DEBUG
@ -20,6 +19,7 @@
#define DEFAULT_DELAY_CALIB 50000 // Délai entre chaque émission de paquet lors de la calibration (en microsecondes) #define DEFAULT_DELAY_CALIB 50000 // Délai entre chaque émission de paquet lors de la calibration (en microsecondes)
#define DEFAULT_DELAY_NORMAL 25000 // Délai entre chaque émission de paquet dans le cas d'une demande de localisation (en microsecondes) #define DEFAULT_DELAY_NORMAL 25000 // Délai entre chaque émission de paquet dans le cas d'une demande de localisation (en microsecondes)
/* Arguments du programme */
#define OPTIONS "d:i:t:n:" #define OPTIONS "d:i:t:n:"
@ -82,8 +82,7 @@ int main(int argc, char *argv[])
options.delay = strtol(optarg, NULL, 0) ; options.delay = strtol(optarg, NULL, 0) ;
break ; break ;
case 'n' : case 'n' :
// options.nb_pkt = strtol(optarg, NULL, 0) ; options.nb_pkt = strtol(optarg, NULL, 0) ;
options.nb_pkt = atoi(optarg) ;
break ; break ;
default : default :
print_usage(argv[0]) ; print_usage(argv[0]) ;
@ -117,15 +116,21 @@ int main(int argc, char *argv[])
} }
/* Vérifications des arguments et initialisation des données non initialisées */ /* Vérifications des arguments et initialisation des données non initialisées */
if (options.delay == -1) // Délai non spécifié, application des valeurs par défaut if (options.delay < 0) // Délai non spécifié ou mauvais, application des valeurs par défaut
{ {
#ifdef DEBUG
fprintf(stderr, "Attention ! delay : application de la valeur par défaut.\n") ;
#endif // DEBUG
if (is_calibration_request) if (is_calibration_request)
options.delay = DEFAULT_DELAY_CALIB ; options.delay = DEFAULT_DELAY_CALIB ;
else else
options.delay = DEFAULT_DELAY_NORMAL ; options.delay = DEFAULT_DELAY_NORMAL ;
} }
if (options.nb_pkt == -1) // Nombre de paquets non spécifié, application des valeurs par défaut if (options.nb_pkt < 1) // Nombre de paquets non spécifié ou mauvais, application des valeurs par défaut
{ {
#ifdef DEBUG
fprintf(stderr, "Attention ! nb_pkt : application de la valeur par défaut.\n") ;
#endif // DEBUG
if (is_calibration_request) if (is_calibration_request)
options.nb_pkt = DEFAULT_NBPKT_CALIB ; options.nb_pkt = DEFAULT_NBPKT_CALIB ;
else else

View File

@ -21,7 +21,7 @@ CFLAGS=-O2 -W -Wall -Wstrict-prototypes -O -I.
DEPFLAGS=-MMD DEPFLAGS=-MMD
XCFLAGS=$(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS) XCFLAGS=$(CFLAGS) $(DEPFLAGS) $(WARN) $(HEADERS)
PICFLAG=-fPIC PICFLAG=-fPIC
LIBS=-lm -lpcap -lpthread ../../libowlps/libowlps.so.1.0 LIBS=-lm -lpcap -lpthread -lconfuse ../../libowlps/libowlps.so.1.0
## Cibles de compilation standard ## ## Cibles de compilation standard ##
@ -63,6 +63,7 @@ purge : clean
help : help :
@echo -e "Bibliothèques nécessaires à la compilation :\n\ @echo -e "Bibliothèques nécessaires à la compilation :\n\
libpcap0.8-dev\n\ libpcap0.8-dev\n\
libconfuse-dev\n\
libowlps1.0 (fournie)\n\ libowlps1.0 (fournie)\n\
\n\ \n\
Cibles possibles :\n\ Cibles possibles :\n\

View File

@ -8,6 +8,7 @@
#include "../../libowlps/owlps.h" #include "../../libowlps/owlps.h"
#include <pcap.h> #include <pcap.h>
#include <confuse.h>
// Pour la fonction get_mac_addr() : // Pour la fonction get_mac_addr() :
#include <netinet/if_ether.h> #include <netinet/if_ether.h>
@ -19,16 +20,15 @@
#define ERR_CREATING_SOCKET 1 // Erreur lors de la création de la socket d'envoi #define ERR_CREATING_SOCKET 1 // Erreur lors de la création de la socket d'envoi
#define ERR_OPENING_IFACE 2 // Erreur lors de l'ouverture de l'interface de capture #define ERR_OPENING_IFACE 2 // Erreur lors de l'ouverture de l'interface de capture
#define ERR_BAD_USAGE 3 // Mauvais appel au programme #define ERR_BAD_USAGE 3 // Mauvais appel au programme
#define ERR_PARSING_CONFIG_FILE 4 // Erreur lors de la lecture du fichier de configuration
/* Arguments & configuration du programme */
/* Arguments du programme */ #define OPTIONS "f:d:r:w:" // Chaîne pour getopt
#define ARGC 4 #define DEFAULT_CONFIG_FILE "/usr/local/etc/owlps/owlps-listener.conf"
enum {ARGV_AGGREG_IP=1, ARGV_RTAP_IFACE, ARGV_WIFI_IFACE} ;
/* En-têtes des fonctions */ /* En-têtes des fonctions */
void* keep_mode_monitor(char *iface) ; void* keep_mode_monitor(char *iface) ;
int capture(char *capture_iface, char *aggregated_ip, BOOL print_values) ; int capture(char *capture_iface, char *aggregation_ip, unsigned int aggregation_port, 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 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 get_mac_addr(char *eth, unsigned char mac_bytes[6]) ;
void print_usage(char *prog) ; void print_usage(char *prog) ;

View File

@ -18,11 +18,89 @@ int main(int argc, char *argv[])
int ret ; // Code de retour du programme int ret ; // Code de retour du programme
pthread_t thread ; // Thread pour le repassage en mode monitor pthread_t thread ; // Thread pour le repassage en mode monitor
if (argc != ARGC) cfg_opt_t opts[] = { // Options reconnues par confuse dans le fichier de config
CFG_STR("aggregation_ip", "127.0.0.1", CFGF_NONE), // Adresse IP du serveur d'agrégation (défaut : boucle locale)
CFG_INT("aggregation_port", AGGREGATE_DEFAULT_PORT, CFGF_NONE), // Port sur le serveur d'agrégation
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)
CFG_END() } ;
cfg_t *cfg ; // Structure contenant la configuration
char *config_file ; // Nom du fichier de configuration
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')
{ {
config_file = malloc((strlen(optarg) + 1) * sizeof(char)) ;
strcpy(config_file, optarg) ;
}
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
if (cfg_parse(cfg, config_file) == CFG_PARSE_ERROR)
{
free(config_file) ;
return ERR_PARSING_CONFIG_FILE ;
}
free(config_file) ;
/* 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 'f' : // Fichier de configuration
// Déjà traité.
break ;
case 'd' :
cfg_setstr(cfg, "aggregation_ip", optarg) ;
break ;
case 'p' :
cfg_setint(cfg, "aggregation_port", strtol(optarg, NULL, 0)) ;
break ;
case 'r' :
cfg_setstr(cfg, "rtap_iface", optarg) ;
break ;
case 'w' :
cfg_setstr(cfg, "wifi_iface", optarg) ;
break ;
default :
print_usage(argv[0]) ;
return ERR_BAD_USAGE ;
}
}
/* Vérification des arguments */
if (cfg_getstr(cfg, "rtap_iface")[0] == '\0')
{
fprintf(stderr, "Erreur ! Vous devez spécifier une interface radiotap pour la capture.\n") ;
print_usage(argv[0]) ; print_usage(argv[0]) ;
return ERR_BAD_USAGE ; return ERR_BAD_USAGE ;
} }
if (cfg_getstr(cfg, "wifi_iface")[0] == '\0')
{
#ifdef DEBUG
fprintf(stderr, "Attention ! Aucune interface Wi-Fi spécifiée. Utilisation de l'interface radiotap (%s) à la place.\n", cfg_getstr(cfg, "rtap_iface")) ;
#endif // DEBUG
cfg_setstr(cfg, "wifi_iface", cfg_getstr(cfg, "rtap_iface")) ;
}
#ifdef DEBUG
/* Affichage de la configuration */
fprintf(stderr, "Configuration :\n") ;
cfg_print(cfg, stderr) ;
#endif // DEBUG
run = TRUE ; run = TRUE ;
@ -34,14 +112,16 @@ int main(int argc, char *argv[])
sigaction(SIGTERM, &action, NULL) ; sigaction(SIGTERM, &action, NULL) ;
/* Création du thread */ /* Création du thread */
pthread_create(&thread, NULL, (void *) &keep_mode_monitor, argv[ARGV_WIFI_IFACE]) ; pthread_create(&thread, NULL, (void *) &keep_mode_monitor, cfg_getstr(cfg, "wifi_iface")) ;
get_mac_addr(argv[ARGV_WIFI_IFACE], mac) ; get_mac_addr(cfg_getstr(cfg, "wifi_iface"), mac) ;
mac_string = mac_bytes_to_string(mac) ; mac_string = mac_bytes_to_string(mac) ;
printf("Ma mac est : %s\n", mac_string) ; printf("Ma mac est : %s\n", mac_string) ;
free(mac_string) ; free(mac_string) ;
ret = capture(argv[ARGV_RTAP_IFACE], argv[ARGV_AGGREG_IP], TRUE) ; ret = capture(cfg_getstr(cfg, "rtap_iface"), cfg_getstr(cfg, "aggregation_ip"), cfg_getint(cfg, "aggregation_port"), TRUE) ;
cfg_free(cfg) ; // Nettoyage de la configuration
printf("%s : fin.\n", argv[0]) ; printf("%s : fin.\n", argv[0]) ;
return ret ; return ret ;
@ -68,7 +148,7 @@ void* keep_mode_monitor(char *iface)
/* Capture des paquets en utilisant l'interface "capture_iface". /* 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". * 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) int capture(char *capture_iface, char *aggregation_ip, unsigned int aggregation_port, BOOL print_values)
{ {
pcap_t *handle ; // Descripteur de capture de paquets pcap_t *handle ; // Descripteur de capture de paquets
char errbuf[PCAP_ERRBUF_SIZE] ; // Message d'erreur char errbuf[PCAP_ERRBUF_SIZE] ; // Message d'erreur
@ -91,7 +171,7 @@ int capture(char *capture_iface, char *aggregated_ip, BOOL print_values)
} }
/* Ouverture de la socket UDP vers le serveur d'aggrégation */ /* Ouverture de la socket UDP vers le serveur d'aggrégation */
sockfd = create_udp_sending_socket(aggregated_ip, AGGREGATE_DEFAULT_PORT, &server, &client); sockfd = create_udp_sending_socket(aggregation_ip, aggregation_port, &server, &client);
if (sockfd < 0) if (sockfd < 0)
{ {
perror("Erreur ! Impossible de créer la socket vers le serveur d'aggrégation \n"); perror("Erreur ! Impossible de créer la socket vers le serveur d'aggrégation \n");
@ -142,7 +222,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p
if (IS_RETRY(raw_packet_flags)) if (IS_RETRY(raw_packet_flags))
printf("Retry : pas à traiter\n") ; printf("Retry : pas à traiter\n") ;
} }
#endif #endif // DEBUG
if (raw_packet_type == RAW_PACKET_TYPE_DATA // Si le paquet est de type data, if (raw_packet_type == RAW_PACKET_TYPE_DATA // Si le paquet est de type data,
&& 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), && 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),
@ -339,9 +419,10 @@ void get_mac_addr(char *eth, unsigned char mac_bytes[6])
void print_usage(char *prog) void print_usage(char *prog)
{ {
printf("Usage :\n\ printf("Usage :\n\
\t%s ip_agrégation rtap_iface wifi_iface\n\ \t%s [-f config_file] [-d ip_agrégation] [-p port_agrégation] -r rtap_iface [-w wifi_iface]\n\
- ip_agrégation est l'adresse IP du serveur d'agrégation.\n\ - 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\
- rtap_iface est l'interface de capture radiotap.\n\ - rtap_iface est l'interface de capture radiotap.\n\
- wifi_iface est l'interface physique correspondant à rtap_iface.\n\ - wifi_iface est l'interface physique correspondant à rtap_iface (par défaut : rtap_iface).\n\
", prog) ; 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\
", prog, AGGREGATE_DEFAULT_PORT, DEFAULT_CONFIG_FILE) ;
} }