[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.
This commit is contained in:
Matteo Cypriani 2013-04-23 17:18:41 -04:00
parent c95257f26a
commit 6ea849625c
2 changed files with 117 additions and 18 deletions

View File

@ -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_

View File

@ -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"