[Listener] Add -v -q -m + other modifications
owlps-listener : * Détail des erreurs d'ouverture / parcours du fichier de configuration. * Ajout des option -v et -q permettant de choisir si le programme doit être verbeux ou silencieux. * Modification des en-têtes de capture() et read_packet() pour utiliser la structure de configuration plutôt que des passages d'arguments. Note : peut-être serait-il bien de déplacer read_packet() dans capture() (à la place de got_packet) pour éviter le passage incessant des arguments sockfd et server. * Ajout de l'option -m permettant de choisir le mode (actif, passif, mixte). * Préparation de l'implantation du mode passif (dans read_packet). git-svn-id: https://pif.pu-pm.univ-fcomte.fr/svn/loc@106 785a6c6c-259e-4ff1-8b91-dc31627914f0
This commit is contained in:
parent
c2f18d715e
commit
24fef29457
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
) ;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue