owlps/loc-mobile/mobile/mobile.c

275 lines
9.4 KiB
C

/*
* This is the rtapanalyser library, Wi-Fi packet sniffer and analyser,
* thanks to the radiotap header of each packet.
*/
#include "../librtapscanmob/rtapscanmob.h"
/* Options du programme */
#define DEFAULT_IFACE "rtap0" // Interface de capture par défaut.
#define DEFAULT_CAPTURE_TIME 5000 // Temps de capture par défaut en milli-secondes.
#define MAX_FILENAME_LENGTH 500 // Longueur maximale du nom des fichiers.
#define MAX_OPT_LENGTH 6 // Longueur maximale des options sur la ligne de commandes.
#define NB_OPTIONS 11 // Nombre d'options.
enum {NUM_OPT_HELP, NUM_OPT_IFACE, NUM_OPT_CAPTURE_TIME, NUM_OPT_OUTPUT, NUM_OPT_INPUT, NUM_OPT_VERB, NUM_OPT_VERB2, NUM_OPT_DIRECTION, NUM_OPT_POSX, NUM_OPT_POSY, NUM_OPT_POSZ} ; // Liste des numéros d'options.
#define OPT_HELP "-h" // Option d'affichage de l'aide.
#define OPT_OUTPUT "-o" // Option d'enregistrement des résultats dans un fichier.
#define OPT_INPUT "-i" // Option de lecture des trames enregistrées avec -o.
#define OPT_IFACE "-d" // Option de spécification de l'interface de capture.
#define OPT_CAPTURE_TIME "-t" // Option de spécification du temps de capture.
#define OPT_VERB "-v" // Option de verbosité.
#define OPT_VERB2 "-vv" // Option de verbosité maximale.
#define OPT_DIRECTION "-dir" // Option de calibration (direction).
#define OPT_POSX "-posx" // Option de calibration (position en X).
#define OPT_POSY "-posy" // Option de calibration (position en Y).
#define OPT_POSZ "-posz" // Option de calibration (position en Z).
#define ERR_BAD_OPTION 50 // Code d'erreur en cas de mauvaise option de ligne de commande.
#define ERR_OPT_INPUT_OUTPUT 51 // Erreur d'incompatibilité entre les deux options entrée et sortie de/vers fichier.
#define ERR_OPT_CALIBRATION 52 // Erreur si toutes les options de calibration ne sont pas présentes.
/* Affiche la syntaxe du programme */
void print_usage(char *prog)
{
printf("Usage :\n\
\t%s -h\n\
\t%s [ -v ] [ -i fichier ]\n\
\t%s [ -v | -vv ] [ -d interface ] [ -t temps ] [ -o fichier ] [ -dir direction -posx x -posy y -posz z ]\n\
", prog, prog, prog) ;
}
/* Affiche la syntaxe du programme */
void print_usage_only(char *prog)
{
putchar('\n') ;
print_usage(prog) ;
printf("\nPour afficher l'aide, tapez « %s -h ».\n", prog) ;
}
/* Affiche l'aide complète du programme */
void print_help(char *prog)
{
print_usage(prog) ;
printf("\n\
Options :\n\
\t-h : affiche cette aide.\n\
\t-v : affichage détaillé.\n\
\t-vv : affichage très détaillé.\n\
\t-i fichier : lit les informations depuis le fichier « fichier » plutôt que de tenter de capturer des paquets.\n\
\t-o fichier : enregistre les informations capturées dans le fichier « fichier ».\n\
\t-d interface : les paquets sont capturés sur l'interface réseau « interface ». Par défaut, « %s » est utilisée.\n\
\t-t temps : les paquets sont capturés pendant « temps » millisecondes. Par défaut, « temps » vaut %d.\n\
\t-dir direction : dans le cas de la calibration, indique que la mesure est effectuée vers « direction » (entier de 1 à 4).\n\
\t-posx x : dans le cas de la calibration, indique que la position en X du mobile est « x » (flottant).\n\
\t-posy y : dans le cas de la calibration, indique que la position en Y du mobile est « y » (flottant).\n\
\t-posz z : dans le cas de la calibration, indique que la position en Z du mobile est « z » (flottant).\n\
\n\
Note : votre interface de capture doit être en mode « monitor », et supporter radiotap.\n\
", DEFAULT_IFACE, DEFAULT_CAPTURE_TIME) ;
}
/* Analyse les options de la ligne de commandes */
void read_options(int argc, char **argv, BOOL *options, char *capture_iface, int *capture_time, char *file, char *direction, float *pos_x, float *pos_y, float *pos_z)
{
int i ; // Compteur.
char num_prev_opt = -1 ; // Numéro de la dernière option lue, si elle prend un argument. Ne doit pas être positionné lors de la lecture des options ne prenant pas d'argument ; doit être repositionnée à -1 après le traitement de l'option.
/* Initialisation du tableau d'options à FALSE */
for (i = 0 ; i < NB_OPTIONS ; i++)
options[i] = FALSE ;
/* Lecture des options */
for (i = 1 ; i < argc ; i++)
{
if (num_prev_opt != -1)
{
/* Cas des options suivies d'un argument (exemple : « -o fichier ») */
switch (num_prev_opt)
{
case NUM_OPT_OUTPUT :
case NUM_OPT_INPUT :
strncpy(file, argv[i], MAX_FILENAME_LENGTH) ;
break ;
case NUM_OPT_IFACE :
strncpy(capture_iface, argv[i], IFNAMSIZ) ;
break ;
case NUM_OPT_CAPTURE_TIME :
*capture_time = atoi(argv[i]) ;
break ;
case NUM_OPT_DIRECTION :
*direction = atoi(argv[i]) ;
break ;
case NUM_OPT_POSX :
*pos_x = atof(argv[i]) ;
break ;
case NUM_OPT_POSY :
*pos_y = atof(argv[i]) ;
break ;
case NUM_OPT_POSZ :
*pos_z = atof(argv[i]) ;
break ;
}
num_prev_opt = -1 ;
}
else if (strncmp(argv[i], OPT_HELP, MAX_OPT_LENGTH) == 0)
{
print_help(argv[0]) ;
exit(0) ;
}
else if (strncmp(argv[i], OPT_IFACE, MAX_OPT_LENGTH) == 0)
{
options[NUM_OPT_IFACE] = TRUE ;
num_prev_opt = NUM_OPT_IFACE ;
}
else if (strncmp(argv[i], OPT_CAPTURE_TIME, MAX_OPT_LENGTH) == 0)
{
options[NUM_OPT_CAPTURE_TIME] = TRUE ;
num_prev_opt = NUM_OPT_CAPTURE_TIME ;
}
else if (strncmp(argv[i], OPT_OUTPUT, MAX_OPT_LENGTH) == 0)
{
options[NUM_OPT_OUTPUT] = TRUE ;
num_prev_opt = NUM_OPT_OUTPUT ;
}
else if (strncmp(argv[i], OPT_INPUT, MAX_OPT_LENGTH) == 0)
{
options[NUM_OPT_INPUT] = TRUE ;
num_prev_opt = NUM_OPT_INPUT ;
}
else if (strncmp(argv[i], OPT_VERB, MAX_OPT_LENGTH) == 0)
{
if (options[NUM_OPT_VERB] == TRUE) // Si l'option est déjà présente,
options[NUM_OPT_VERB2] = TRUE ; // on active le deuxième niveau de verbosité.
else
options[NUM_OPT_VERB] = TRUE ;
}
else if (strncmp(argv[i], OPT_VERB2, MAX_OPT_LENGTH) == 0)
{
options[NUM_OPT_VERB] = TRUE ;
options[NUM_OPT_VERB2] = TRUE ;
}
else if (strncmp(argv[i], OPT_DIRECTION, MAX_OPT_LENGTH) == 0)
{
options[NUM_OPT_DIRECTION] = TRUE ;
num_prev_opt = NUM_OPT_DIRECTION ;
}
else if (strncmp(argv[i], OPT_POSX, MAX_OPT_LENGTH) == 0)
{
options[NUM_OPT_POSX] = TRUE ;
num_prev_opt = NUM_OPT_POSX ;
}
else if (strncmp(argv[i], OPT_POSY, MAX_OPT_LENGTH) == 0)
{
options[NUM_OPT_POSY] = TRUE ;
num_prev_opt = NUM_OPT_POSY ;
}
else if (strncmp(argv[i], OPT_POSZ, MAX_OPT_LENGTH) == 0)
{
options[NUM_OPT_POSZ] = TRUE ;
num_prev_opt = NUM_OPT_POSZ ;
}
else
{
print_usage_only(argv[0]) ;
fprintf(stderr, "Option inconnue « %s » !\n\n", argv[i]) ;
exit(ERR_BAD_OPTION) ;
}
}
/* Vérifications des options */
if (options[NUM_OPT_OUTPUT] == TRUE || options[NUM_OPT_INPUT] == TRUE)
if (file[0] == '\0')
{
fprintf(stderr, "Vous devez spécifier un nom de fichier après les options -i et -o !\n") ;
print_usage_only(argv[0]) ;
exit(ERR_FILENAME) ;
}
if (options[NUM_OPT_OUTPUT] == TRUE && options[NUM_OPT_INPUT] == TRUE)
{
fprintf(stderr, "Les options -i et -o sont incompatibles !\n") ;
print_usage_only(argv[0]) ;
exit(ERR_OPT_INPUT_OUTPUT) ;
}
if ((options[NUM_OPT_DIRECTION] || options[NUM_OPT_POSX] || options[NUM_OPT_POSY] || options[NUM_OPT_POSZ]) && ! (options[NUM_OPT_DIRECTION] && options[NUM_OPT_POSX] && options[NUM_OPT_POSY] && options[NUM_OPT_POSZ]))
{
fprintf(stderr, "Vous devez spécifier toutes les options de calibration ou aucune !\n") ;
print_usage_only(argv[0]) ;
exit(ERR_OPT_CALIBRATION) ;
}
}
int main(int argc, char **argv)
{
BOOL options[NB_OPTIONS] ; // Tableau des options présentes.
char capture_iface[IFNAMSIZ] = DEFAULT_IFACE ; // Interface d'entrée
int capture_time = DEFAULT_CAPTURE_TIME ; // Temps de capture
char file[MAX_FILENAME_LENGTH] = "\0" ; // Nom du fichier à lire ou écrire.
char direction = 0 ; // Direction de la calibration.
float pos_x = 0, pos_y = 0, pos_z = 0 ; // Positions de la calibration.
mac_list *results = NULL ;
int ret = 0 ; // Valeur de retour des fonctions appelées.
/* Lecture des options de la ligne de commande */
read_options(argc, argv, options, capture_iface, &capture_time, file, &direction, &pos_x, &pos_y, &pos_z) ;
if (options[NUM_OPT_INPUT] == TRUE) // Si l'option INPUT est présente,
{
if ((ret = read_mac_list_from_file(file, &results)) != 0) // Lecture du fichier.
return ret ;
print_mac_list(results, options[NUM_OPT_VERB]) ; // Affichage.
free_mac_list(&results) ; // Nettoyage
return 0 ;
}
printf("Interface de capture : %s\nTemps de capture : %d\n\n", capture_iface, capture_time) ;
iface_mode_monitor("eth2") ; // Passage de l'interface Wi-Fi en mode Monitor. FIXME ! mettre l'interface Wi-Fi en paramètre du programme (wifi_iface != capture_iface, cf. apd.c).
/**** THREAAAAAAAAAD !!!!!!!! ****/
if ((ret = capture(capture_iface, capture_time, &results, options[NUM_OPT_VERB])) != 0) // Capture de paquets.
return ret ; // On quitte avec le code d'erreur si la capture a mal fini.
print_mac_list(results, options[NUM_OPT_VERB2]) ; // Affichage des paquets capturés.
if (options[NUM_OPT_OUTPUT] == TRUE) // Si l'option OUTPUT est présente,
// ret = write_mac_list_to_file(file, results) ;
ret = write_mac_list_to_text_file(file, results, direction, pos_x, pos_y, pos_z) ;
free_mac_list(&results) ; // Nettoyage
return ret ;
}