/* * 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 ; }