/* * This file is part of the rtap localisation project. */ #include "owlps.h" #define DEBUG BOOL run = TRUE ; /* Convertit une adresse MAC en octets en une chaîne de caractères. * ¡ Il est nécessaire de libérer manuellement le retour de cette fonction ! */ 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 ; } /* 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 CHANNEL_1 : c = 1 ; break ; case CHANNEL_2 : c = 2 ; break ; case CHANNEL_3 : c = 3 ; break ; case CHANNEL_4 : c = 4 ; break ; case CHANNEL_5 : c = 5 ; break ; case CHANNEL_6 : c = 6 ; break ; case CHANNEL_7 : c = 7 ; break ; case CHANNEL_8 : c = 8 ; break ; case CHANNEL_9 : c = 9 ; break ; case CHANNEL_10 : c = 10 ; break ; case CHANNEL_11 : c = 11 ; break ; case CHANNEL_12 : c = 12 ; break ; case CHANNEL_13 : c = 13 ; break ; case CHANNEL_14 : c = 14 ; break ; } return c ; } /* Convertit une date au format struct timeval en une valeur entière en millisecondes, et retourne le résultat */ unsigned long long timeval_to_ms(struct timeval d) { return d.tv_sec * 1000 + d.tv_usec / 1000 ; } /* * Convertit une date sous forme de valeur entière en millisecondes, * en une struct timeval, et retourne cette structure. struct timeval ms_to_timeval(unsigned long long tms) { struct timeval d ; d.tv_sec = tms / 1000 ; d.tv_usec = (tms - d.tv_sec * 1000) * 1000 ; return d ; } */ /* Retourne le temps (en millisecondes) écoulé entre deux dates */ unsigned long sub_date(struct timeval sup, struct timeval inf) { unsigned long sub = abs(timeval_to_ms(sup) - timeval_to_ms(inf)) ; #ifdef DEBUG printf("sub_date() : sub=%lu\n", sub) ; #endif return sub ; } /* 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 ; } /* Crée une socket d'envoi UDP et retourne son descripteur. * Paramètres : * - server_address : l'adresse IP du serveur. * - server_port : le port d'écoute du serveur. * - server_description (paramètre résultat) : la structure dans laquelle sera enregistrée la description du serveur. * - client_description (paramètre résultat) : la structure dans laquelle sera enregistrée la description du client. */ int create_udp_sending_socket(char *server_address, int server_port, struct sockaddr_in *server_description, struct sockaddr_in * client_description) { int sockfd ; // Descripteur de la socket /* Ceation de la socket UDP */ sockfd = socket(AF_INET, SOCK_DGRAM, 0) ; if (sockfd < 0) { perror("Échec de la création de la socket ") ; return sockfd ; } /* Remise à zéro et initialisation de la structure du client */ bzero((char *) client_description, sizeof(*client_description)) ; client_description->sin_family = AF_INET ; // Socket INET client_description->sin_addr.s_addr = htonl(INADDR_ANY) ; // Toutes les connexions // client_description->sin_port = htons(0) ; // N'importe quel port (ne sert à rien a priori) /* Remise à zéro et initialisation de la structure du serveur */ bzero((char *) server_description, sizeof(*server_description)) ; // RÀZ server_description->sin_family = AF_INET ; // Socket INET server_description->sin_addr.s_addr = inet_addr(server_address) ; // Adresse du serveur server_description->sin_port = htons(server_port) ; // Port d'écoute du serveur return sockfd ; // On retourne le descripteur de la socket créée } /* Crée une socket d'écoute UDP et retourne son descripteur. * Paramètres : * - port est le port sur lequel écouter. */ int create_udp_listening_socket(int port) { int sockfd ; // Descripteur de la socket struct sockaddr_in server_description ; // Structure du serveur int ret = 0 ; // Valeur de retour /* Création d'une socket UDP */ sockfd = socket(AF_INET, SOCK_DGRAM, 0) ; if (sockfd < 0) { perror("Échec de la création de la socket ") ; return sockfd ; } /* Remise à zéro et initialisation de la structure du serveur */ bzero((char *) &server_description, sizeof(server_description)) ; // RÀZ server_description.sin_family = AF_INET ; // Socket INET server_description.sin_addr.s_addr = htonl(INADDR_ANY) ; // Toutes les connexions sont acceptées server_description.sin_port = htons(port) ; // Port d'écoute /* Réservation du port */ ret = bind(sockfd, (struct sockaddr*) &server_description, sizeof(server_description)) ; if (ret < 0) { perror("Impossible de créer la socket (bind) ") ; (void) close(sockfd) ; return ret ; } return sockfd ; // On retourne le descripteur de la socket créée } /* Bascule l'interface Wi-Fi "iface" en mode Monitor si elle n'y est pas déjà */ int iface_mode_monitor(char *iface) { struct iwreq wrq ; int sockfd = iw_sockets_open() ; strncpy((&wrq)->ifr_name, iface, IFNAMSIZ) ; if (ioctl(sockfd, SIOCGIWMODE, &wrq) == -1) // Get current mode { perror("Error reading interface mode") ; return ERR_READING_MODE ; } // If interface is not yet in Monitor mode if (wrq.u.mode != IW_MODE_MONITOR) { wrq.u.mode = IW_MODE_MONITOR ; if (ioctl(sockfd, SIOCSIWMODE, &wrq) == -1) // Set up Monitor mode { perror("Error setting up Monitor mode") ; return ERR_SETTING_MODE ; } } close(sockfd) ; return 0 ; } /* Change le canal de l'interface Wi-Fi "iface" avec la valeur "channel" (numéro de 1 à 14) */ int iface_set_channel(char *iface, int channel) { struct iwreq wrq ; int sockfd = iw_sockets_open() ; strncpy((&wrq)->ifr_name, iface, IFNAMSIZ) ; iw_float2freq(channel, &(wrq.u.freq)) ; wrq.u.freq.flags = IW_FREQ_FIXED ; if (ioctl(sockfd, SIOCSIWFREQ, &wrq) == -1) { perror("Erreur lors du changement de canal ") ; return ERR_SETTING_CHANNEL ; } close(sockfd) ; return 0 ; } /* Fait varier le canal de l'interface Wi-Fi "iface" entre les canaux 4 et 11 */ int iface_channel_hop(char *iface) { unsigned short channel ; struct iwreq wrq ; int sockfd = iw_sockets_open() ; strncpy((&wrq)->ifr_name, iface, IFNAMSIZ) ; if (ioctl(sockfd, SIOCGIWFREQ, &wrq) == -1) { perror("Erreur lors de la lecture de la fréquence ") ; return ERR_READING_CHANNEL ; } channel = wrq.u.freq.m / 100000 ; // Un peu gruik : il vaudrait mieux utiliser iw_freq2float(), iw_freq_to_channel() et compagnie (cf. /usr/include/{iwlib.h,wireless.h}). if (channel > 1000) // Si la valeur est en Hz, channel = frequency_to_channel(channel) ; // on la convertit en numéro de canal (avec notre fonction maison, toujours un peu gruik). close(sockfd) ; /* Changement de canal */ if (channel == 4) // Si le canal est déjà à 4, return iface_set_channel(iface, 11) ; // on le passe à 11 ; else return iface_set_channel(iface, 4) ; // sinon on le met à 4. } /* Gestionnaire de signal générique pour SIGINT */ void sigint_handler(int num) { if (num != SIGINT) { fprintf(stderr, "Erreur ! Gestionnaire de SIGINT appelé mais le signal n'est pas SIGINT.\n") ; exit(ERR_BAD_SIGNAL) ; } run = FALSE ; printf("\nSignal reçu : fin du programme.\n"); fflush(NULL) ; } /* Gestionnaire de signal générique pour SIGTERM */ void sigterm_handler(int num) { if (num != SIGTERM) { fprintf(stderr, "Erreur ! Gestionnaire de SIGTERM appelé mais le signal n'est pas SIGINT.\n") ; exit(ERR_BAD_SIGNAL) ; } sigint_handler(SIGINT) ; }