diff --git a/infrastructure-centred/owlps-listener/owlps-listener.h b/infrastructure-centred/owlps-listener/owlps-listener.h index af61ddd..394d1c0 100644 --- a/infrastructure-centred/owlps-listener/owlps-listener.h +++ b/infrastructure-centred/owlps-listener/owlps-listener.h @@ -2,8 +2,8 @@ * This file is part of the rtap localisation project. */ -#ifndef _AP_H -#define _AP_H +#ifndef _OWLPS_LISTENER_H_ +#define _OWLPS_LISTENER_H_ /* Compilation-time options: to activate, uncomment or compile with -D * option. @@ -39,26 +39,26 @@ # endif // __BYTE_ORDER == __LITTLE_ENDIAN #endif // le32toh -// Pour la fonction get_mac_addr() : +// Used by get_mac_addr(): #include #include #include -/* Codes d'erreurs */ -#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_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 */ -#define OPTIONS "d:f:kl:m:p:qr:vw:" // Chaîne pour getopt +/* Arguments & program configuration */ +#define OPTIONS "d:f:kl:m:p:qr:vw:" // getopt string #define DEFAULT_CONFIG_FILE "/usr/local/etc/owlps/owlps-listener.conf" enum {MODE_ACTIVE = 'a', MODE_PASSIVE = 'p', MODE_MIXED = 'm'} ; -/* En-têtes des fonctions */ +/* Error codes */ +#define ERR_CREATING_SOCKET 1 // Error when creating output socket +#define ERR_OPENING_IFACE 2 // Error when opening capture interface +#define ERR_BAD_USAGE 3 // Bad program call +#define ERR_PARSING_CONFIG_FILE 4 // Error reading the configuration file + + +/* Function headers */ #ifdef USE_PTHREAD void* keep_mode_monitor(char *iface) ; #endif // USE_PTHREAD @@ -68,11 +68,11 @@ void get_mac_addr(char *eth, unsigned char mac_bytes[6]) ; void print_usage(char *prog) ; -/* Macros permettant de jongler entre la gestion des options via la - * structure offerte par libconfuse, et une structure maison si cette - * dernière est désactivée. +/* Macros to allow switching option handling with the libconfuse + * structure and a home-made structure (if program is not compiled + * with libconfuse support). */ -/* Macros utilisant libconfuse : */ +/* libconfuse macros */ #ifdef USE_CONFIG_FILE #define SET_MODE(MODE) (cfg_setint(cfg, "mode", (MODE))) #define GET_MODE() (cfg_getint(cfg, "mode")) @@ -94,7 +94,7 @@ void print_usage(char *prog) ; #define UNSET_VERBOSE() (cfg_setbool(cfg, "verbose", cfg_false)) #define GET_VERBOSE() (cfg_getbool(cfg, "verbose")) -/* Macros utilisant la structure maison : */ +/* Home-made structure macros */ #else // USE_CONFIG_FILE #define SET_MODE(MODE) (options.mode = (MODE)) #define GET_MODE() (options.mode) @@ -118,4 +118,4 @@ void print_usage(char *prog) ; #endif // USE_CONFIG_FILE -#endif // _AP_H +#endif // _OWLPS_LISTENER_H_ diff --git a/infrastructure-centred/owlps-listener/owlps-listenerd.c b/infrastructure-centred/owlps-listener/owlps-listenerd.c index 1461750..47b0023 100644 --- a/infrastructure-centred/owlps-listener/owlps-listenerd.c +++ b/infrastructure-centred/owlps-listener/owlps-listenerd.c @@ -7,13 +7,16 @@ -unsigned char mac[6] ; // Adresse MAC de l'AP +unsigned char mac[6] ; // AP MAC address #ifdef USE_CONFIG_FILE -cfg_t *cfg ; // Structure contenant la configuration +cfg_t *cfg ; // Configuration structure -#else // USE_CONFIG_FILE // Si on n'utilise pas libconfuse, on déclare une -struct { // structure qui servira à stocker les options getopt : +#else // USE_CONFIG_FILE +/* If we do not use libconfuse, we declare a structure to store getopt + * options. + */ +struct { char mode ; char aggregation_ip[16] ; long aggregation_port ; @@ -24,7 +27,7 @@ struct { // structure qui servira à stocker les options getopt char rtap_iface[IFNAMSIZ + 1] ; char wifi_iface[IFNAMSIZ + 1] ; BOOL verbose ; -} options = { // et on initalise les options par défaut : +} options = { // Initalise default options: MODE_ACTIVE, "127.0.0.1", AGGREGATE_DEFAULT_PORT, @@ -39,37 +42,50 @@ struct { // structure qui servira à stocker les options getopt #endif // USE_CONFIG_FILE + int main(int argc, char *argv[]) { - struct sigaction action ; // Structure de mise en place des gestionnaires de signaux - char *mac_string ; // MAC de l'AP sous forme de chaîne - int ret ; // Code de retour du programme + struct sigaction action ; // Signal handler structure + char *mac_string ; // AP MAC (string value) + int ret ; // Program return value #ifdef USE_PTHREAD pthread_t thread ; // Thread pour le repassage en mode monitor #endif // USE_PTHREAD -#ifdef USE_CONFIG_FILE // Si on utilise libconfuse, on déclare les options : - cfg_opt_t opts[] = { // Options reconnues par confuse dans le fichier de config - CFG_INT("mode", MODE_ACTIVE, CFGF_NONE), // Mode d'écoute : a pour actif, p pour passif, m pour mixte (défaut : a) - 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 d'envoi sur le serveur d'agrégation - CFG_INT("listening_port", LOC_REQUEST_DEFAULT_PORT, CFGF_NONE), // Port d'écoute des demandes des mobiles +#ifdef USE_CONFIG_FILE + // If we use libconfuse, we declare options: + cfg_opt_t opts[] = + { + // Listening mode: a for active, p for passive, m for mixed + // (default: a): + CFG_INT("mode", MODE_ACTIVE, CFGF_NONE), + // IP address of the aggregator (default: loopback): + CFG_STR("aggregation_ip", "127.0.0.1", CFGF_NONE), + // Port on which the aggregator listens: + CFG_INT("aggregation_port", AGGREGATE_DEFAULT_PORT, CFGF_NONE), + // Port on which mobiles send active requests: + CFG_INT("listening_port", LOC_REQUEST_DEFAULT_PORT, CFGF_NONE), #ifdef USE_PTHREAD - CFG_BOOL("keep_monitor", cfg_false, CFGF_NONE), // Active le maintien actif du mode monitor + // Activate the active monitor mode keeping-up (read the code if + // you do not understand what I mean): + CFG_BOOL("keep_monitor", cfg_false, CFGF_NONE), #endif // USE_PTHREAD - 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_BOOL("verbose", cfg_false, CFGF_NONE), // Afficher les paquets capturés ou pas - CFG_END() } ; + // Radiotap interface, used to capture: + CFG_STR("rtap_iface", "", CFGF_NONE), + // Physical interface corresponding to the radiotap interface (used + // to get the MAC address): + CFG_STR("wifi_iface", "", CFGF_NONE), + // Display capture packets, or not: + CFG_BOOL("verbose", cfg_false, CFGF_NONE), + CFG_END() + } ; - char *config_file ; // Nom du fichier de configuration + char *config_file ; // Configuration file name #endif // USE_CONFIG_FILE - int opt ; // Retour de getopt + int opt ; // getopt return value - - /* L'option -f sert à spécifier un fichier de configuration alternatif, - * on regarde en premier si elle est présente */ + // Option -f specifies a config file, so we search for it first do opt = getopt(argc, argv, OPTIONS) ; while (opt != 'f' && opt != -1) ; @@ -79,34 +95,42 @@ int main(int argc, char *argv[]) config_file = malloc((strlen(optarg) + 1) * sizeof(char)) ; strcpy(config_file, optarg) ; #else // USE_CONFIG_FILE - fprintf(stderr, "Attention ! Le programme a été compilé sans le support des fichiers de configuration, l'option -f n'est donc pas disponible. Vous devez passer toutes les options sur la ligne de commandes, sans quoi les valeurs par défaut seront utilisées.\n") ; + fprintf(stderr, "Warning! Program was not compiled with" + " configuration file support, so -f is not available. You" + " must specify all options on the command line, or default" + " value will be used.\n") ; #endif // USE_CONFIG_FILE } #ifdef USE_CONFIG_FILE - else // Si -f n'est pas présente, on utilise le fichier de config par défaut + else // If -f isn't found, we use the default config file { - config_file = malloc((strlen(DEFAULT_CONFIG_FILE) + 1) * sizeof(char)) ; + 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 + /* Parse config file */ + cfg = cfg_init(opts, CFGF_NONE) ; // Initialise options switch (cfg_parse(cfg, config_file)) { case CFG_FILE_ERROR : - fprintf(stderr, "Erreur lors de l'ouverture du fichier de configuration « %s » : %s.\n", config_file, strerror(errno)) ; + fprintf(stderr, + "Error! Cannot open configuration file « %s »: %s.\n", + config_file, strerror(errno)) ; break ; case CFG_PARSE_ERROR : - fprintf(stderr, "Erreur lors de la lecture du fichier de configuration « %s » !\n", config_file) ; + fprintf(stderr, + "Error! Parsing of configuration file « %s » failed!\n", + config_file) ; free(config_file) ; - return ERR_PARSING_CONFIG_FILE ; + exit(ERR_PARSING_CONFIG_FILE) ; } free(config_file) ; #endif // USE_CONFIG_FILE - /* Lecture des arguments de la ligne de commandes */ - optind = 1 ; // On reprend l'analyse des arguments au début + /* Parse command line */ + optind = 1 ; // Rewind argument parsing while ((opt = getopt(argc, argv, OPTIONS)) != -1) { switch (opt) @@ -114,14 +138,16 @@ int main(int argc, char *argv[]) case 'd' : SET_AGGREGATION_IP(optarg) ; break ; - case 'f' : // Fichier de configuration - // Déjà traité. - break ; + case 'f' : // Config file + break ; // (already parsed) case 'k' : #ifdef USE_PTHREAD SET_KEEP_MONITOR() ; #else // USE_PTHREAD - fprintf(stderr, "Attention ! Le programme a été compilé sans le support des threads POSIX, l'option -k (maintien du mode monitor) n'est donc pas disponible et sera ignorée.\n") ; + fprintf(stderr, "Warning! The program was compiled without" + " support of POSIX threads, so -k (monitor mode" + " keeping-up) is not available and will be ignored." + "\n") ; #endif // USE_PTHREAD break ; case 'l' : @@ -151,7 +177,7 @@ int main(int argc, char *argv[]) } } - /* Vérification des arguments */ + /* Check arguments */ switch (GET_MODE()) { case MODE_ACTIVE : @@ -159,37 +185,40 @@ int main(int argc, char *argv[]) case MODE_PASSIVE : break ; default : - fprintf(stderr, "Erreur ! Mode « %c » inconnu.\n", (char) GET_MODE()) ; + fprintf(stderr, "Error! Unknown mode « %c ».\n", (char) GET_MODE()) ; print_usage(argv[0]) ; return ERR_BAD_USAGE ; } if (GET_RTAP_IFACE()[0] == '\0') { - fprintf(stderr, "Erreur ! Vous devez spécifier une interface radiotap pour la capture.\n") ; + fprintf(stderr, "Error! You must specify a radiotap interface" + " for the capture.\n") ; print_usage(argv[0]) ; return ERR_BAD_USAGE ; } if (GET_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", GET_RTAP_IFACE()) ; + fprintf(stderr, "Warning! No Wi-Fi was specified. Failing back to" + " the radiotap interface (%s) instead.\n", + GET_RTAP_IFACE()) ; #endif // DEBUG SET_WIFI_IFACE(GET_RTAP_IFACE()) ; } #ifdef DEBUG - /* Affichage de la configuration */ - fprintf(stderr, "Configuration :\n") ; + /* Print configuration */ + fprintf(stderr, "Configuration:\n") ; #ifdef USE_CONFIG_FILE cfg_print(cfg, stderr) ; #else // USE_CONFIG_FILE - fprintf(stderr, "\ -aggregation_ip = \"%s\"\n\ -aggregation_port = %ld\n\ -listening_port = %ld\n\ -rtap_iface = \"%s\"\n\ -wifi_iface = \"%s\"\n\ -", + fprintf(stderr, + "aggregation_ip = \"%s\"\n" + "aggregation_port = %ld\n" + "listening_port = %ld\n" + "rtap_iface = \"%s\"\n" + "wifi_iface = \"%s\"\n" + , GET_AGGREGATION_IP(), GET_AGGREGATION_PORT(), GET_LISTENING_PORT(), @@ -206,7 +235,7 @@ wifi_iface = \"%s\"\n\ run = TRUE ; - /* Mise en place des gestionnaires de signaux */ + /* Set up signal handlers */ sigemptyset(&action.sa_mask) ; action.sa_handler = sigint_handler ; sigaction(SIGINT, &action, NULL) ; @@ -214,37 +243,40 @@ wifi_iface = \"%s\"\n\ sigaction(SIGTERM, &action, NULL) ; #ifdef USE_PTHREAD - /* Création du thread */ + /* Set up thread */ if (GET_KEEP_MONITOR()) - pthread_create(&thread, NULL, (void *) &keep_mode_monitor, GET_WIFI_IFACE()) ; + pthread_create(&thread, NULL, + (void *) &keep_mode_monitor, GET_WIFI_IFACE()) ; #endif // USE_PTHREAD get_mac_addr(GET_WIFI_IFACE(), mac) ; mac_string = mac_bytes_to_string(mac) ; - printf("Ma mac est : %s\n", mac_string) ; + printf("My MAC address is: %s\n", mac_string) ; free(mac_string) ; ret = capture() ; #ifdef USE_CONFIG_FILE - cfg_free(cfg) ; // Nettoyage de la configuration + cfg_free(cfg) ; // Clean configuration #endif // USE_CONFIG_FILE - printf("%s : fin.\n", argv[0]) ; + printf("%s: end.\n", argv[0]) ; return ret ; } - #ifdef USE_PTHREAD -/* Fonction du thread, qui surveille la liste et envoie les infos au serveur de localisation au bout du timeout */ +/* + * Thread function. Switches interface 'iface' to monitor mode every + * second. + */ void* keep_mode_monitor(char *iface) { while (run) { - iface_mode_monitor(iface) ; // Passage de l'interface en mode Monitor. - sleep(1) ; // Pause de 1 secondes. + iface_mode_monitor(iface) ; // Switch the interface to monitor mode + sleep(1) ; // Wait for 1 second } pthread_exit(NULL) ; @@ -253,99 +285,123 @@ void* keep_mode_monitor(char *iface) - -/* Capture des paquets en utilisant l'interface RTAP figurant dans les options. - * Les données capturées sont envoyées au serveur d'aggrégation dont l'IP - * figure également dans les options. +/* + * Captures packets using the radiotap interface. + * Captured data is transmitted to the aggregator. */ int capture() { - 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 + pcap_t *handle ; // Packet capture descriptor + char errbuf[PCAP_ERRBUF_SIZE] ; // Error message + int sockfd ; // Output socket descriptor struct sockaddr_in server, client ; - /* Sous-fonction de traitement des paquets capturés */ - void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) + /* Sub-function that treats captured packets */ + void got_packet(u_char *args, const struct pcap_pkthdr *header, + const u_char *packet) { - // On appelle la fonction read_packet() avec les mêmes arguments, - // plus les informations concernant le serveur : + // Call function read_packet() with the same arguments, plus server + // information: read_packet(args, header, packet, sockfd, &server) ; } - handle = pcap_open_live(GET_RTAP_IFACE(), BUFSIZ, 1, 1000, errbuf) ; // Début de la capture - if (handle == NULL) // Le lancement de la capture a-t-il échoué ? + // Start capture: + handle = pcap_open_live(GET_RTAP_IFACE(), BUFSIZ, 1, 1000, errbuf) ; + if (handle == NULL) // Capture starting failed { - fprintf(stderr, "Impossible d'ouvrir l'interface « %s » : %s\n", GET_RTAP_IFACE(), errbuf) ; + fprintf(stderr, "Cannot open interface « %s »: %s\n", + GET_RTAP_IFACE(), errbuf) ; return ERR_OPENING_IFACE ; } - /* Ouverture de la socket UDP vers le serveur d'aggrégation */ - sockfd = create_udp_sending_socket(GET_AGGREGATION_IP(), GET_AGGREGATION_PORT(), &server, &client); + /* Open UDP socket to the aggregator */ + sockfd = create_udp_sending_socket(GET_AGGREGATION_IP(), + GET_AGGREGATION_PORT(), + &server, &client) ; if (sockfd < 0) { - perror("Erreur ! Impossible de créer la socket vers le serveur d'aggrégation \n"); + perror("Error! Cannot create socket to the aggregation server"); return ERR_CREATING_SOCKET ; } 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 - } + // Capture one packet at time, and call got_packet() on it: + pcap_loop(handle, 1, got_packet, NULL) ; - pcap_close(handle) ; // Arrêt de la capture. - (void) close(sockfd) ; // Fermeture de la socket + pcap_close(handle) ; // Stop capture + (void) close(sockfd) ; // Close socket return 0 ; } - -/* 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) +/* + * Treats a packet and sends it to the aggregator (on the UDP socket + * 'sockfd', to the server 'server'). + */ +void read_packet(u_char *args, const struct pcap_pkthdr *header, + const u_char *packet, int sockfd, + struct sockaddr_in *server) { - 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 ; - couple_message couple ; // Message à envoyer à l'agrégateur - ssize_t nsent ; // Retour de sendto - BOOL check[15] ; // Champs présents - unsigned char raw_packet_type ; // Type du packet reçu (beacon, data...) - unsigned char raw_packet_flags ; // Flags de l'en-tête IEEE 802.11 + // Copy packet address into data: + unsigned char *data = (unsigned char *) packet ; + unsigned short rtap_bytes ; // Received data size + unsigned int + rtap_presentflags, + rtap_position ; + couple_message couple ; // Message to send to the aggregator + ssize_t nsent ; // sendto return value + BOOL check[15] ; // Present flags + unsigned char raw_packet_type ; // Received packet type (beacon, data…) + unsigned char raw_packet_flags ; // IEEE 802.11 header flags unsigned short llc_packet_type = 0 ; - struct iphdr *packet_ip_header = NULL ; // Pointeur sur l'éventuel en-tête IP du paquet - struct udphdr *packet_udp_header = NULL ; // Pointeur sur l'éventuel en-tête UDP du paquet - char packet_type ; // Type de demande de localisation (demande, calibration) - BOOL is_explicit_packet = TRUE ; // Le paquet constitue-t-il une demande ? - int i ; // Compteur + // Pointer to the (possible) IP header of the packet: + struct iphdr *packet_ip_header = NULL ; + // Pointer to the (possible) UDP header of the packet: + struct udphdr *packet_udp_header = NULL ; + char packet_type ; // Localisation request type (request, calibration) + BOOL is_explicit_packet = TRUE ; // Is the packet an explicit request? + int i ; // Iterator - /* Traitements communs */ + /* Common treatements */ - 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) + // Copy 2 bytes from the 3rd data byte, that is the size of the rtap + // header (changes with the flags): + memcpy(&rtap_bytes, &data[2], sizeof(unsigned short)) ; rtap_bytes = ntohs(rtap_bytes) ; - 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) + // After the rtap header, there is the 802.11 header; the first byte + // is the packet type (beacon or not): + raw_packet_type = data[rtap_bytes] ; - if (raw_packet_type == RAW_PACKET_TYPE_DATA) // Si le paquet est de type data, - { // on récupère le type de paquet (protocole, sur 2 octets) dans l'en-tête LLC : - memcpy((unsigned char*) &llc_packet_type, &data[rtap_bytes + IEEE80211_HEADER_SIZE + 6], 2) ; + if (raw_packet_type == RAW_PACKET_TYPE_DATA) // Data packet + { + // Get the packet type (protocol, 2 bytes) from the LLC header: + memcpy((unsigned char*) &llc_packet_type, + &data[rtap_bytes + IEEE80211_HEADER_SIZE + 6], 2) ; llc_packet_type = ntohs(llc_packet_type) ; - if (llc_packet_type == ETH_P_IP) // Si c'est un paquet IP on récupère l'IP source + if (llc_packet_type == ETH_P_IP) // IP packet { - packet_ip_header = (struct iphdr *) &data[rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE] ; + packet_ip_header = (struct iphdr *) + &data[rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE] ; + // Get the source IP: memcpy(couple.mobile_ip_addr_bytes, &packet_ip_header->saddr, 4) ; - if (GET_MODE() != MODE_PASSIVE) // Si on est en mode actif ou mixte + if (GET_MODE() != MODE_PASSIVE) // If mode is active or mixed { - if (packet_ip_header->protocol == IPPROTO_UDP) // Le protocole du paquet est UDP pour une demande explicite - { // On teste le port de destination : - packet_udp_header = (struct udphdr *) &data[rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + sizeof(struct iphdr)] ; - if (ntohs(packet_udp_header->dest) != GET_LISTENING_PORT()) + // Protocol for an explicit request is UDP + if (packet_ip_header->protocol == IPPROTO_UDP) + { // Check destination port: + packet_udp_header = (struct udphdr *) + &data[rtap_bytes + IEEE80211_HEADER_SIZE + + LLC_HEADER_SIZE + sizeof(struct iphdr)] ; + if (ntohs(packet_udp_header->dest) != + GET_LISTENING_PORT()) { if (GET_MODE() == MODE_ACTIVE) return ; @@ -354,47 +410,54 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p } } } - else if (GET_MODE() != MODE_ACTIVE) // Mode passif ou mixte + else if (GET_MODE() != MODE_ACTIVE) // Passive or mixed mode { is_explicit_packet = FALSE ; - bzero(couple.mobile_ip_addr_bytes, 4) ; // On positionne l'IP à zéro + bzero(couple.mobile_ip_addr_bytes, 4) ; // Blank the IP } - else // On est en mode actif et le paquet n'est pas IP donc pas une demande + else // Active mode and not an IP packet, so it is not a request return ; } - else - { // Le paquet n'est pas de la donnée donc pas une demande + + else // Packet is not data, so it is not a localisation request + { if (GET_MODE() == MODE_ACTIVE) return ; is_explicit_packet = FALSE ; } - raw_packet_flags = data[rtap_bytes+1] ; // On récupère les flags 802.11, qui sont dans l'en-tête 802.11. + // Get 802.11 flags from the 802.11 header: + raw_packet_flags = data[rtap_bytes+1] ; #ifdef DEBUG - printf("raw_packet_flags : %02x\n", raw_packet_flags) ; + printf("raw_packet_flags: %02x\n", raw_packet_flags) ; if (IS_RETRY(raw_packet_flags)) - printf("Ce paquet est un Retry.\n") ; + printf("This packet is a Retry.\n") ; #endif // DEBUG - 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); // L'adresse MAC source est 10 octets plus loin que le type de paquet 802.11 - couple.start_time = header->ts ; // L'heure de capture du paquet est contenue dans l'en-tête pcap - couple.request_time.tv_sec = 0 ; // L'heure d'envoi par le mobile est inconnue (à moins qu'il ne s'agisse d'un paquet explicite) + memcpy(couple.ap_mac_addr_bytes, mac, 6) ; // Copy AP MAC + // Source MAC address is 10 bytes after the 802.11 packet type: + memcpy(couple.mobile_mac_addr_bytes, &data[rtap_bytes+10], 6) ; + couple.start_time = header->ts ; // Capture time is in the pcap header + // Transmission time on the mobile is unknown (unless the packet is + // an explicit request): + couple.request_time.tv_sec = 0 ; couple.request_time.tv_usec = 0 ; - /* Mode actif */ + /* Active mode */ if (is_explicit_packet && (GET_MODE() == MODE_ACTIVE || GET_MODE() == MODE_MIXED) - // FIXME : faut-il toujours ignorer les retry ? - && ! IS_RETRY(raw_packet_flags)) // et ce n'est pas un Retry. + // FIXME: should we really ignore Retries? + && ! IS_RETRY(raw_packet_flags)) { - packet_type = data[rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + sizeof(struct iphdr) + sizeof(struct udphdr)] ; + packet_type = + data[rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + + sizeof(struct iphdr) + sizeof(struct udphdr)] ; switch(packet_type) { case PACKET_TYPE_NORMAL : if (GET_VERBOSE()) - printf("\nPaquet explicite normal reçu.\n") ; + printf("\nExplicit packet received.\n") ; couple.direction = 0 ; couple.x_position = 0 ; couple.y_position = 0 ; @@ -403,17 +466,29 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p case PACKET_TYPE_CALIBRATION : if (GET_VERBOSE()) - printf("\nPaquet explicite de calibration reçu.\n") ; - couple.direction = data[rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + sizeof(struct iphdr) + sizeof(struct udphdr) + 9]; - memcpy(&couple.x_position, &data[rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + sizeof(struct iphdr) + sizeof(struct udphdr) + 10], sizeof(float)); - memcpy(&couple.y_position, &data[rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + sizeof(struct iphdr) + sizeof(struct udphdr) + 14], sizeof(float)); - memcpy(&couple.z_position, &data[rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + sizeof(struct iphdr) + sizeof(struct udphdr) + 18], sizeof(float)); + printf("\nExplicite calibration packet received.\n") ; + couple.direction = + data[rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + + sizeof(struct iphdr) + sizeof(struct udphdr) + 9]; + memcpy(&couple.x_position, + &data[rtap_bytes + IEEE80211_HEADER_SIZE + + LLC_HEADER_SIZE + sizeof(struct iphdr) + + sizeof(struct udphdr) + 10], sizeof(float)) ; + memcpy(&couple.y_position, + &data[rtap_bytes + IEEE80211_HEADER_SIZE + + LLC_HEADER_SIZE + sizeof(struct iphdr) + + sizeof(struct udphdr) + 14], sizeof(float)) ; + memcpy(&couple.z_position, + &data[rtap_bytes + IEEE80211_HEADER_SIZE + + LLC_HEADER_SIZE + sizeof(struct iphdr) + + sizeof(struct udphdr) + 18], sizeof(float)) ; break ; default : if (GET_VERBOSE()) - printf("\nPaquet explicite bizarre reçu.\n") ; - fprintf(stderr, "Erreur ! Type de paquet explicite inconnu (%d).\n", packet_type) ; + printf("\nStrange explicit packet received\n") ; + fprintf(stderr, + "Error! Unknown packet type (%d).\n", packet_type) ; is_explicit_packet = FALSE ; } @@ -422,39 +497,47 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p if (GET_MODE() == MODE_ACTIVE) return ; else if (GET_VERBOSE()) - printf("\nCe paquet explicite bizarre sera traité comme implicite.\n") ; + printf("\nThis strange explicit packet will be handled as" + " an implicit one.\n") ; } else - memcpy(&couple.request_time, &data[rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + sizeof(struct iphdr) + sizeof(struct udphdr) + 1], sizeof(struct timeval)); + memcpy(&couple.request_time, + &data[rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + + sizeof(struct iphdr) + sizeof(struct udphdr) + 1], + sizeof(struct timeval)) ; } else if (GET_MODE() == MODE_PASSIVE || GET_MODE() == MODE_MIXED) { if (GET_VERBOSE()) - printf("\nPaquet implicite reçu.\n") ; + printf("\nImplicit packet received.\n") ; } - else // Mode actif uniquement, le paquet n'étant pas une demande explicite + else // Active mode, packet was not an explicit request return ; - /* Traitement de l'en-tête Radiotap */ + /* Radiotap header handling */ - memcpy(&rtap_presentflags, &data[RTAP_P_PRESENTFLAGS], RTAP_L_PRESENTFLAGS) ; // Récupère les flags de l'en-tête rtap - // Note : on récupère les flags en big-endian (net-endianess), mais on - // travaille dessus comme si c'était du little-endian. Cela nous permet - // de déclarer un tableau de seulement 15 bits (au lieu de 32) car ce - // sont ces bits (de poids faible) qui nous intéressent. C'est un peu de - // la triche :-) - // Du coup, sur les architectures big-endian, il faut retourner les bits - // en faisant comme si on avait récupéré les flags en little-endian : + // Get rtap flags: + memcpy(&rtap_presentflags, + &data[RTAP_P_PRESENTFLAGS], RTAP_L_PRESENTFLAGS) ; + /* We get the flags in big-endian (net-endianess), but we work on them + * as if it was in little-endian. This allows to declare an array of 15 + * bits (instead of 32), because we work only on the least significant + * bits (and so we do not reserve space for most significant bits that + * are useless). It's kind of cheat :-) + * So, on big-endian architectures, we must inverse bits as if we had + * got flags in little-endian: */ rtap_presentflags = le32toh(rtap_presentflags) ; - for (i = 0 ; i < 15 ; i++) // Initialisation de la structure des champs présents + for (i = 0 ; i < 15 ; i++) // Initialise present flags structure check[i] = FALSE ; - rtap_position = 8 ; // Début des champs déterminés par le present flag + rtap_position = 8 ; // Begining of the present flags determined fields - 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 + // Test the first 15 bits of the flag field in order to check their + // presence and to copy them: + for (i = 0 ; i < 15 ; i++) { if ((rtap_presentflags % 2) == 1) { @@ -481,10 +564,12 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p rtap_position += RTAP_L_FHSS ; break ; case RTAP_ANTENNASIGNALDBM: - memcpy(&(couple.antenna_signal_dbm), &data[rtap_position], RTAP_L_ANTENNASIGNALDBM) ; + memcpy(&(couple.antenna_signal_dbm), + &data[rtap_position], RTAP_L_ANTENNASIGNALDBM) ; check[RTAP_ANTENNASIGNALDBM] = TRUE; if (GET_VERBOSE()) - printf("Antenna Signal : %d dBm\n", couple.antenna_signal_dbm - 0x100); + printf("Antenna signal: %d dBm\n", + couple.antenna_signal_dbm - 0x100); rtap_position += RTAP_L_ANTENNASIGNALDBM ; break ; case RTAP_ANTENNANOISEDBM: @@ -530,20 +615,21 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p if (GET_VERBOSE()) { - char *ap_mac_string = mac_bytes_to_string(couple.ap_mac_addr_bytes) ; - char *mobile_mac_string = mac_bytes_to_string(couple.mobile_mac_addr_bytes) ; - printf("\ -*** Couple à envoyer ***\n\ -\tMAC AP : %s\n\ -\tMAC mobile : %s\n\ -\tNuméro de séquence (heure de la demande) : %llu\n\ -\tHeure d'arrivée de la demande de localisation sur l'AP : %llu\n\ -\tSignal : %d dBm\n\ -\tPosition X : %f\n\ -\tPosition Y : %f\n\ -\tPosition Z : %f\n\ -\tDirection : %hhd\n\ -", + char *ap_mac_string = + mac_bytes_to_string(couple.ap_mac_addr_bytes) ; + char *mobile_mac_string = + mac_bytes_to_string(couple.mobile_mac_addr_bytes) ; + printf("*** Couple to send ***\n" + "\tMAC AP: %s\n" + "\tMobile MAC: %s\n" + "\tSequence number (request time): %llu\n" + "\tRequest arrival time on the AP: %llu\n" + "\tSignal: %d dBm\n" + "\tPosition X: %f\n" + "\tPosition Y: %f\n" + "\tPosition Z: %f\n" + "\tDirection: %hhd\n" + , ap_mac_string, mobile_mac_string, timeval_to_ms(couple.request_time), @@ -558,29 +644,32 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p free(mobile_mac_string) ; } - /* Envoi du couple au serveur d'aggrégation */ - nsent = sendto(sockfd, (void *) &couple, sizeof(couple), 0, (struct sockaddr *) server, (socklen_t) sizeof(*server)) ; + /* Send couple to the aggregator */ + nsent = + sendto(sockfd, (void *) &couple, sizeof(couple), 0, + (struct sockaddr *) server, (socklen_t) sizeof(*server)) ; if (nsent != (ssize_t) sizeof(couple)) { - perror("Erreur lors de l'envoi du couple au serveur ") ; + perror("Error sending couple to the aggregation server") ; return ; } } - -/* Fonction permettant de récupérer sa propre adresse MAC (interface 'eth') dans le tableau 'mac_bytes' */ +/* + * Get our own MAC address and copy it to 'mac_bytes'. + */ void get_mac_addr(char *eth, unsigned char mac_bytes[6]) { struct ifreq ifr; int sockfd ; - bzero(mac_bytes, sizeof(unsigned char) * 6) ; // RàZ + bzero(mac_bytes, sizeof(unsigned char) * 6) ; // Empty mac_bytes sockfd = socket(AF_INET, SOCK_DGRAM, 0) ; if(sockfd < 0) - perror("Impossible d'ouvrir la socket pour récupérer l'adresse MAC ") ; + perror("Cannot open socket to read MAC address") ; strncpy(ifr.ifr_name, eth, IFNAMSIZ) ; @@ -595,23 +684,39 @@ void get_mac_addr(char *eth, unsigned char mac_bytes[6]) - -/* Affiche le mode d'emploi du programme */ void print_usage(char *prog) { - printf("Usage :\n\ -\t%s [-f config_file] [-m mode] [-d ip_agrégation] [-l listening_port] [-p port_agrégation] -r rtap_iface [-w wifi_iface] [-k] [-v|-q]\n\ -- L'option -f permet de spécifier un fichier de configuration alternatif (le fichier de configuration par défaut ne sera pas lu). Disponible uniquement si le programme a été compilé avec le support de libconfuse.\n\ -- mode est le mode de fonctionnement : a(ctif), p(assif), m(ixte) (par défaut : a).\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\ -- wifi_iface est l'interface physique correspondant à rtap_iface (par défaut : rtap_iface).\n\ -- L'option -k active le maintien actif du mode monitor. À utiliser avec des pilotes bogués. Disponible uniquement si le programme a été compilé avec le support des threads POSIX.\n\ -- L'option -v rend le programme bavard (affichage des paquets capturés) ; l'option -q annule le bavardage s'il est activé par ailleurs (e.g. fichier de configuration). Par défaut le mode verbeux est désactivé.\n\ -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\ -", + printf("Usage :\n" + "\t%s [-f config_file] [-m mode] [-d aggregation_ip]" + " [-l listening_port] [-p aggregation_port] -r rtap_iface" + " [-w wifi_iface] [-k] [-v | -q]\n" + + "Main options:\n" + "\t-f config_file\tUse 'config_file' instead of the default" + " configuration file (%s). Available only if program was" + " compiled with libconfuse.\n" + + "Capture options:\n" + "\t-m mode\t\t\tCapture mode: a(ctive), p(assive), m(ixed)" + " (default: a).\n" + "\t-d aggregation_ip\tIP address of the aggregation server" + " (default: 127.0.0.1)\n" + "\t-l aggregation_port\tListening port on the aggregation server" + " (default: %d).\n" + "\t-r rtap_iface\t\tRadiotap capture interface.\n" + "\t-w wifi_iface\t\tPhysical interface behind rtap_iface" + " (default: rtap_iface).\n" + + "Other options:\n" + "\t-k\tKeep the monitor mode up on wifi_iface. Use it with buggy" + " drivers that disable monitor mode periodically. Available" + " only if the program was compiled with support of POSIX" + " threads.\n" + "\t-v\tVerbose mode (display captured packets).\n" + "\t-q\tQuiet mode (default).\n" + , prog, - AGGREGATE_DEFAULT_PORT, - DEFAULT_CONFIG_FILE + DEFAULT_CONFIG_FILE, + AGGREGATE_DEFAULT_PORT ) ; }