diff --git a/infrastructure-centred/owlps-listener/owlps-listener.h b/infrastructure-centred/owlps-listener/owlps-listener.h index 7eeb7a5..8b38a2d 100644 --- a/infrastructure-centred/owlps-listener/owlps-listener.h +++ b/infrastructure-centred/owlps-listener/owlps-listener.h @@ -36,16 +36,16 @@ /* Arguments & configuration du programme */ -#define OPTIONS "d:f:kl:p:r:w:" // Chaîne pour getopt +#define OPTIONS "m:d:f:kl:p:r:w:v" // Chaîne pour getopt #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 */ #ifdef USE_PTHREAD void* keep_mode_monitor(char *iface) ; #endif // USE_PTHREAD -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) ; +int capture(void) ; +void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet, int sockfd, struct sockaddr_in *server) ; void get_mac_addr(char *eth, unsigned char mac_bytes[6]) ; void print_usage(char *prog) ; @@ -56,6 +56,8 @@ void print_usage(char *prog) ; */ /* Macros utilisant libconfuse : */ #ifdef USE_CONFIG_FILE +#define SET_MODE(MODE) (cfg_setint(cfg, "mode", (MODE))) +#define GET_MODE() (cfg_getint(cfg, "mode")) #define SET_AGGREGATION_IP(IP) (cfg_setstr(cfg, "aggregation_ip", (IP))) #define GET_AGGREGATION_IP() (cfg_getstr(cfg, "aggregation_ip")) #ifdef USE_PTHREAD @@ -70,9 +72,14 @@ void print_usage(char *prog) ; #define GET_RTAP_IFACE() (cfg_getstr(cfg, "rtap_iface")) #define SET_WIFI_IFACE(IFACE) (cfg_setstr(cfg, "wifi_iface", (IFACE))) #define GET_WIFI_IFACE() (cfg_getstr(cfg, "wifi_iface")) +#define SET_VERBOSE() (cfg_setbool(cfg, "verbose", cfg_true)) +#define UNSET_VERBOSE() (cfg_setbool(cfg, "verbose", cfg_false)) +#define GET_VERBOSE() (cfg_getbool(cfg, "verbose")) /* Macros utilisant la structure maison : */ #else // USE_CONFIG_FILE +#define SET_MODE(MODE) (options.mode = (MODE)) +#define GET_MODE() (options.mode) #define SET_AGGREGATION_IP(IP) (strncpy(options.aggregation_ip, (IP), 16)) #define GET_AGGREGATION_IP() (options.aggregation_ip) #ifdef USE_PTHREAD @@ -87,6 +94,9 @@ void print_usage(char *prog) ; #define GET_RTAP_IFACE() (options.rtap_iface) #define SET_WIFI_IFACE(IFACE) (strncpy(options.wifi_iface, (IFACE), IFNAMSIZ+1)) #define GET_WIFI_IFACE() (options.wifi_iface) +#define SET_VERBOSE() (options.verbose = TRUE) +#define UNSET_VERBOSE() (options.verbose = FALSE) +#define GET_VERBOSE() (options.verbose) #endif // USE_CONFIG_FILE diff --git a/infrastructure-centred/owlps-listener/owlps-listenerd.c b/infrastructure-centred/owlps-listener/owlps-listenerd.c index 35a610e..892922b 100644 --- a/infrastructure-centred/owlps-listener/owlps-listenerd.c +++ b/infrastructure-centred/owlps-listener/owlps-listenerd.c @@ -14,6 +14,7 @@ cfg_t *cfg ; // Structure contenant la configuration #else // USE_CONFIG_FILE // Si on n'utilise pas libconfuse, on déclare une struct { // structure qui servira à stocker les options getopt : + char mode ; char aggregation_ip[16] ; long aggregation_port ; long listening_port ; @@ -22,14 +23,17 @@ struct { // structure qui servira à stocker les options getopt #endif // USE_PTHREAD char rtap_iface[IFNAMSIZ + 1] ; char wifi_iface[IFNAMSIZ + 1] ; + BOOL verbose ; } options = { // et on initalise les options par défaut : + MODE_ACTIVE, "127.0.0.1", AGGREGATE_DEFAULT_PORT, #ifdef USE_PTHREAD FALSE, #endif // USE_PTHREAD "", - "" + "", + FALSE } ; #endif // USE_CONFIG_FILE @@ -45,6 +49,7 @@ int main(int argc, char *argv[]) #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 @@ -53,6 +58,7 @@ int main(int argc, char *argv[]) #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() } ; char *config_file ; // Nom du fichier de configuration @@ -84,8 +90,13 @@ int main(int argc, char *argv[]) /* Lecture du fichier de configuration */ cfg = cfg_init(opts, CFGF_NONE) ; // Initialisation des options - if (cfg_parse(cfg, config_file) == CFG_PARSE_ERROR) + 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)) ; + break ; + case CFG_PARSE_ERROR : + fprintf(stderr, "Erreur lors de la lecture du fichier de configuration « %s » !\n", config_file) ; free(config_file) ; return ERR_PARSING_CONFIG_FILE ; } @@ -115,12 +126,21 @@ int main(int argc, char *argv[]) case 'l' : SET_LISTENING_PORT(strtol(optarg, NULL, 0)) ; break ; + case 'm' : + SET_MODE(optarg[0]) ; + break ; case 'p' : SET_AGGREGATION_PORT(strtol(optarg, NULL, 0)) ; break ; + case 'q' : + UNSET_VERBOSE() ; + break ; case 'r' : SET_RTAP_IFACE(optarg) ; break ; + case 'v' : + SET_VERBOSE() ; + break ; case 'w' : SET_WIFI_IFACE(optarg) ; break ; @@ -131,6 +151,17 @@ int main(int argc, char *argv[]) } /* Vérification des arguments */ + switch (GET_MODE()) + { + case MODE_ACTIVE : + case MODE_MIXED : + case MODE_PASSIVE : + break ; + default : + fprintf(stderr, "Erreur ! Mode « %c » inconnu.\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") ; @@ -192,7 +223,7 @@ wifi_iface = \"%s\"\n\ printf("Ma mac est : %s\n", mac_string) ; free(mac_string) ; - ret = capture(GET_RTAP_IFACE(), GET_AGGREGATION_IP(), GET_AGGREGATION_PORT(), TRUE) ; + ret = capture() ; #ifdef USE_CONFIG_FILE cfg_free(cfg) ; // Nettoyage de la configuration @@ -222,10 +253,11 @@ void* keep_mode_monitor(char *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". +/* 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. */ -int capture(char *capture_iface, char *aggregation_ip, unsigned int aggregation_port, BOOL print_values) +int capture() { pcap_t *handle ; // Descripteur de capture de paquets char errbuf[PCAP_ERRBUF_SIZE] ; // Message d'erreur @@ -236,19 +268,21 @@ int capture(char *capture_iface, char *aggregation_ip, unsigned int aggregation_ /* Sous-fonction de traitement des paquets capturés */ void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) { - read_packet(args, header, packet, sockfd, &server, print_values) ; // On appelle la fonction read_packet() avec les mêmes arguments, plus "print_values" qui indique si on doit afficher le paquet. + // On appelle la fonction read_packet() avec les mêmes arguments, + // plus les informations concernant le serveur : + read_packet(args, header, packet, sockfd, &server) ; } - handle = pcap_open_live(capture_iface, BUFSIZ, 1, 1000, errbuf) ; // Début de la capture + 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é ? { - fprintf(stderr, "Impossible d'ouvrir l'interface « %s » : %s\n", capture_iface, errbuf) ; + fprintf(stderr, "Impossible d'ouvrir l'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(aggregation_ip, aggregation_port, &server, &client); + 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"); @@ -270,7 +304,7 @@ int capture(char *capture_iface, char *aggregation_ip, unsigned int aggregation_ /* 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, BOOL print_values) +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 @@ -311,7 +345,9 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p } #endif // DEBUG - if (raw_packet_type == RAW_PACKET_TYPE_DATA // Si le paquet est de type data, + /* Mode actif */ + if ((GET_MODE() == MODE_ACTIVE || GET_MODE() == MODE_MIXED) + && 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), && dst_port == LOC_REQUEST_DEFAULT_PORT // et le port de destination est le bon, && ! IS_RETRY(raw_packet_flags)) // et ce n'est pas un Retry. @@ -329,7 +365,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p switch(packet_type) { case PACKET_TYPE_NORMAL : - if (print_values) + if (GET_VERBOSE()) printf("\nPaquet normal reçu.\n") ; couple.direction = 0 ; couple.x_position = 0 ; @@ -338,7 +374,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p break ; case PACKET_TYPE_CALIBRATION : - if (print_values) + if (GET_VERBOSE()) printf("\nPaquet de calibration reçu.\n") ; couple.direction = data[rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + IP_HEADER_SIZE + UDP_HEADER_SIZE + 9]; memcpy(&couple.x_position, &data[rtap_bytes + IEEE80211_HEADER_SIZE + LLC_HEADER_SIZE + IP_HEADER_SIZE + UDP_HEADER_SIZE + 10], sizeof(float)); @@ -347,7 +383,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p break ; default : - if (print_values) + if (GET_VERBOSE()) printf("\nPaquet bizarre reçu.\n") ; fprintf(stderr, "Erreur ! Type de paquet inconnu (%d).\n", packet_type) ; return ; @@ -392,7 +428,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p case RTAP_ANTENNASIGNALDBM: memcpy(&(couple.antenna_signal_dbm), &data[rtap_position], RTAP_L_ANTENNASIGNALDBM) ; check[RTAP_ANTENNASIGNALDBM] = TRUE; - if (print_values) + if (GET_VERBOSE()) printf("Antenna Signal : %d dBm\n", couple.antenna_signal_dbm - 0x100); rtap_position += RTAP_L_ANTENNASIGNALDBM ; break ; @@ -437,7 +473,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p rtap_presentflags /= 2 ; } - if (print_values) + 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) ; @@ -475,6 +511,12 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *p return ; } } + + /* Mode passif */ + else if (GET_MODE() == MODE_PASSIVE || GET_MODE() == MODE_MIXED) + { + /* TODO */ + } } @@ -510,12 +552,18 @@ void get_mac_addr(char *eth, unsigned char mac_bytes[6]) void print_usage(char *prog) { printf("Usage :\n\ -\t%s [-f config_file] [-d ip_agrégation] [-l listening_port] [-p port_agrégation] -r rtap_iface [-w wifi_iface] [-k]\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\ -", prog, AGGREGATE_DEFAULT_PORT, DEFAULT_CONFIG_FILE) ; +", + prog, + AGGREGATE_DEFAULT_PORT, + DEFAULT_CONFIG_FILE + ) ; }