[Listener] Translation of comments, 72 col.

This commit is contained in:
Matteo Cypriani 2010-07-13 14:39:03 +02:00
parent 7f262a8573
commit 5eb11af87f
2 changed files with 314 additions and 209 deletions

View File

@ -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 <netinet/if_ether.h>
#include <netinet/udp.h>
#include <netinet/ip.h>
/* 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_

View File

@ -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 é 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 é 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
) ;
}