From 6ea849625cefe4e4a8f2f3be9381121e891f9d8f Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Tue, 23 Apr 2013 17:18:41 -0400 Subject: [PATCH] [Listener] Add -R option (read from pcap file) The new -R option allows one to read packets from a pcap file instead of capturing from a network interface. --- owlps-listener/owlps-listener.h | 36 +++++++++++- owlps-listener/owlps-listenerd.c | 99 ++++++++++++++++++++++++++------ 2 files changed, 117 insertions(+), 18 deletions(-) diff --git a/owlps-listener/owlps-listener.h b/owlps-listener/owlps-listener.h index bc1cf18..2e1c55b 100644 --- a/owlps-listener/owlps-listener.h +++ b/owlps-listener/owlps-listener.h @@ -99,7 +99,7 @@ /* Arguments & program configuration */ -#define OPTIONS "ADf:hH:i:I:Kl:m:n:O:p:P:qr:t:T:vVw:" // getopt string +#define OPTIONS "ADf:hH:i:I:Kl:m:n:O:p:P:qr:R:t:T:vVw:" // getopt string #define DEFAULT_CONFIG_FILE "/usr/local/etc/owlps/owlps-listener.conf" enum {MODE_ACTIVE = 'a', MODE_PASSIVE = 'p', MODE_MIXED = 'm'} ; #define DEFAULT_AUTOCALIBRATION_HELLO_DELAY 15 // seconds @@ -254,6 +254,8 @@ void print_version(void) ; (cfg_getint(cfg, "mode")) #define SET_DAEMON() \ (cfg_setbool(cfg, "daemon", cfg_true)) +#define UNSET_DAEMON() \ + (cfg_setbool(cfg, "daemon", cfg_false)) #define GET_DAEMON() \ (cfg_getbool(cfg, "daemon")) #define SET_AGGREGATION_IP(IP) \ @@ -263,6 +265,8 @@ void print_version(void) ; #ifdef ENABLE_KEEP_MONITOR #define SET_KEEP_MONITOR() \ (cfg_setbool(cfg, "keep_monitor", cfg_true)) +#define UNSET_KEEP_MONITOR() \ + (cfg_setbool(cfg, "keep_monitor", cfg_false)) #define GET_KEEP_MONITOR() \ (cfg_getbool(cfg, "keep_monitor")) #endif // ENABLE_KEEP_MONITOR @@ -278,6 +282,10 @@ void print_version(void) ; (cfg_setstr(cfg, "rtap_iface", (IFACE))) #define GET_RTAP_IFACE() \ (cfg_getstr(cfg, "rtap_iface")) +#define SET_PCAP_FILE(PATH) \ + (cfg_setstr(cfg, "pcap_file", (PATH))) +#define GET_PCAP_FILE() \ + (cfg_getstr(cfg, "pcap_file")) #define SET_WIFI_IFACE(IFACE) \ (cfg_setstr(cfg, "wifi_iface", (IFACE))) #define GET_WIFI_IFACE() \ @@ -286,6 +294,8 @@ void print_version(void) ; #ifdef USE_PTHREAD #define SET_AUTOCALIBRATION() \ (cfg_setbool(cfg, "autocalibration", cfg_true)) +#define UNSET_AUTOCALIBRATION() \ + (cfg_setbool(cfg, "autocalibration", cfg_false)) #define GET_AUTOCALIBRATION() \ (cfg_getbool(cfg, "autocalibration")) #define SET_AUTOCALIBRATION_IP(IP) \ @@ -345,6 +355,8 @@ void print_version(void) ; #else // USE_CONFIG_FILE #define SET_DAEMON() \ (options.daemon = owl_true) +#define UNSET_DAEMON() \ + (options.daemon = owl_false) #define GET_DAEMON() \ (options.daemon) #define SET_MODE(MODE) \ @@ -358,6 +370,8 @@ void print_version(void) ; #ifdef ENABLE_KEEP_MONITOR #define SET_KEEP_MONITOR() \ (options.keep_monitor = owl_true) +#define UNSET_KEEP_MONITOR() \ + (options.keep_monitor = owl_false) #define GET_KEEP_MONITOR() \ (options.keep_monitor) #endif // ENABLE_KEEP_MONITOR @@ -373,6 +387,17 @@ void print_version(void) ; (strncpy(options.rtap_iface, (IFACE), IFNAMSIZ+1)) #define GET_RTAP_IFACE() \ (options.rtap_iface) +#define SET_PCAP_FILE(PATH) \ + do { \ + char *path = (PATH) ; \ + size_t path_len = strlen(path) ; \ + free(options.pcap_file) ; \ + options.pcap_file = malloc(path_len + 1) ; \ + assert(options.pcap_file) ; \ + strncpy(options.pcap_file, path, path_len) ; \ + } while (0) +#define GET_PCAP_FILE() \ + (options.pcap_file) #define SET_WIFI_IFACE(IFACE) \ (strncpy(options.wifi_iface, (IFACE), IFNAMSIZ+1)) #define GET_WIFI_IFACE() \ @@ -381,6 +406,8 @@ void print_version(void) ; #ifdef USE_PTHREAD #define SET_AUTOCALIBRATION() \ (options.autocalibration = owl_true) +#define UNSET_AUTOCALIBRATION() \ + (options.autocalibration = owl_false) #define GET_AUTOCALIBRATION() \ (options.autocalibration) #define SET_AUTOCALIBRATION_IP(IP) \ @@ -438,4 +465,11 @@ void print_version(void) ; #endif // USE_CONFIG_FILE +/* Returns true if we are capturing packet from a network interface, or + * false if we are reading from a pcap file. + */ +#define LIVE_CAPTURING \ + (! GET_PCAP_FILE()) + + #endif // _OWLPS_LISTENER_H_ diff --git a/owlps-listener/owlps-listenerd.c b/owlps-listener/owlps-listenerd.c index 53a707d..f11cf84 100644 --- a/owlps-listener/owlps-listenerd.c +++ b/owlps-listener/owlps-listenerd.c @@ -109,6 +109,7 @@ struct { owl_bool keep_monitor ; #endif // ENABLE_KEEP_MONITOR char rtap_iface[IFNAMSIZ + 1] ; + char *pcap_file ; char wifi_iface[IFNAMSIZ + 1] ; #ifdef USE_PTHREAD owl_bool autocalibration ; @@ -135,6 +136,7 @@ struct { owl_false, // keep_monitor #endif // ENABLE_KEEP_MONITOR "", // rtap_iface + NULL, // pcap_file "", // wifi_iface #ifdef USE_PTHREAD owl_false, // autocalibration @@ -189,13 +191,16 @@ int main(int argc, char *argv[]) action.sa_handler = sigterm_handler ; sigaction(SIGTERM, &action, NULL) ; - get_mac_addr(GET_WIFI_IFACE(), my_mac_bytes) ; - get_ip_addr(GET_WIFI_IFACE(), my_ip) ; - if (VERBOSE_INFO) - printf("My MAC address is: %s\n" - "My IP address is: %s\n", - owl_mac_bytes_to_string(my_mac_bytes), - my_ip) ; + if (LIVE_CAPTURING) + { + get_mac_addr(GET_WIFI_IFACE(), my_mac_bytes) ; + get_ip_addr(GET_WIFI_IFACE(), my_ip) ; + if (VERBOSE_INFO) + printf("My MAC address is: %s\n" + "My IP address is: %s\n", + owl_mac_bytes_to_string(my_mac_bytes), + my_ip) ; + } #ifdef USE_PTHREAD /* Set up threads */ @@ -358,8 +363,10 @@ int parse_config_file(int argc, char **argv) // you do not understand what I mean): CFG_BOOL("keep_monitor", cfg_false, CFGF_NONE), #endif // ENABLE_KEEP_MONITOR - // Radiotap interface, used to capture: + // Radiotap interface to capture from: CFG_STR("rtap_iface", "", CFGF_NONE), + // Pcap file to read packets from: + CFG_STR("pcap_file", "", CFGF_NONE), // Physical interface corresponding to the radiotap interface (used // to get the MAC address): CFG_STR("wifi_iface", "", CFGF_NONE), @@ -577,6 +584,9 @@ int parse_main_options(int argc, char **argv) case 'r' : SET_RTAP_IFACE(optarg) ; break ; + case 'R' : + SET_PCAP_FILE(optarg) ; + break ; case 't' : #ifdef USE_PTHREAD SET_AUTOCALIBRATION_DELAY(strtol(optarg, NULL, 0)) ; @@ -635,6 +645,7 @@ int parse_calibration_data(int argc, char **argv) int check_configuration() { + // Capture mode // switch (GET_MODE()) { case MODE_ACTIVE : @@ -648,16 +659,56 @@ int check_configuration() return OWL_ERR_BAD_USAGE ; } - if (GET_RTAP_IFACE()[0] == '\0') + // Packet source // + if (GET_PCAP_FILE()) { - fprintf(stderr, "Error! You must specify a radiotap interface" - " for the capture.\n") ; + if (GET_RTAP_IFACE()[0] != '\0') + { + if (VERBOSE_WARNING) + fprintf(stderr, "Warning! Cannot read both from a pcap file" + " and a capture interface: ignoring network-related" + " options.\n") ; + GET_RTAP_IFACE()[0] = '\0' ; + } + + // Ignoring the Wi-Fi interface too: + GET_WIFI_IFACE()[0] = '\0' ; + +#ifdef USE_PTHREAD + if (GET_AUTOCALIBRATION()) + { + if (VERBOSE_WARNING) + fprintf(stderr, "Warning! Cannot send autocalibration" + " requests when reading from a pcap file: disabling" + " autocalibration.\n") ; + UNSET_AUTOCALIBRATION() ; + } + +# ifdef ENABLE_KEEP_MONITOR + UNSET_KEEP_MONITOR() ; +# endif // ENABLE_KEEP_MONITOR +#endif // USE_PTHREAD + + if (GET_DAEMON()) + { + if (VERBOSE_WARNING) + fprintf(stderr, "Warning! Reading from a pcap file: will" + " stay in foreground.\n") ; + UNSET_DAEMON() ; + } + } + + // pcap_file is empty + else if (GET_RTAP_IFACE()[0] == '\0') + { + fprintf(stderr, "Error! You must specify either a radiotap" + " interface or a pcap file to read packets from.\n") ; print_usage() ; owl_run = owl_false ; return OWL_ERR_BAD_USAGE ; } - if (GET_WIFI_IFACE()[0] == '\0') + else if (GET_WIFI_IFACE()[0] == '\0') { if (VERBOSE_WARNING) fprintf(stderr, "No Wi-Fi interface was specified. Failing back" @@ -862,13 +913,26 @@ int iface_mode_monitor(const char *const iface) int capture() { char errbuf[PCAP_ERRBUF_SIZE] ; // Error message + char *source ; + struct pcap_pkthdr *pkt_header ; + const u_char *pkt_data ; + + // Open the capture handler: + if (LIVE_CAPTURING) + { + source = GET_RTAP_IFACE() ; + capture_handler = pcap_open_live(source, BUFSIZ, 1, 1000, errbuf) ; + } + else + { + source = GET_PCAP_FILE() ; + capture_handler = pcap_open_offline(source, errbuf) ; + } - // Start capture: - capture_handler = - pcap_open_live(GET_RTAP_IFACE(), BUFSIZ, 1, 1000, errbuf) ; if (capture_handler == NULL) // Capture starting failed { - fprintf(stderr, "Cannot open capture interface %s\n", errbuf) ; + fprintf(stderr, "Cannot create capture handler on '%s'%s\n", + source, errbuf) ; // Note: errbuf starts with ": " return OWL_ERR_IFACE_PCAP_OPEN ; } @@ -1586,7 +1650,7 @@ void print_usage() " [-D]" " [-v[v[v[v]]] | -q]" "\n\t" - " -r rtap_iface" + " <-r rtap_iface | -R pcap_file>" " [-w wifi_iface]" " [-K]" " [-m mode]" @@ -1632,6 +1696,7 @@ void print_usage() "\t-p aggregation_port\tRequests are transmitted to the" " aggregation\n\t\t\t\tserver on this port (default: %d).\n" "\t-r rtap_iface\t\tRadiotap capture interface.\n" + "\t-R pcap_file\t\tPcap file to read packets from.\n" "\t-w wifi_iface\t\tPhysical interface behind rtap_iface" " (default:\n\t\t\t\trtap_iface).\n"