From 5fe4ab0de8bb94bcdb84a958eb0cd39bbc43686c Mon Sep 17 00:00:00 2001 From: Kyle McDonald Date: Sat, 3 May 2014 12:48:35 -0400 Subject: [PATCH] added pcap_open_live_extended() shim to sniffer.cpp and set rfmon to true in beacon capture example --- examples/beacon_display.cpp | 2 +- include/sniffer.h | 14 +++++++--- src/sniffer.cpp | 56 ++++++++++++++++++++++++++++++++----- 3 files changed, 60 insertions(+), 12 deletions(-) diff --git a/examples/beacon_display.cpp b/examples/beacon_display.cpp index dd9d782..2682860 100644 --- a/examples/beacon_display.cpp +++ b/examples/beacon_display.cpp @@ -47,7 +47,7 @@ private: }; void BeaconSniffer::run(const std::string &iface) { - Sniffer sniffer(iface, 1500, true, "type mgt subtype beacon"); + Sniffer sniffer(iface, 1500, true, "type mgt subtype beacon", true); sniffer.sniff_loop(make_sniffer_handler(this, &BeaconSniffer::callback)); } diff --git a/include/sniffer.h b/include/sniffer.h index b588ac6..d1d1db2 100644 --- a/include/sniffer.h +++ b/include/sniffer.h @@ -254,29 +254,35 @@ namespace Tins { /** * Constructs an instance of Sniffer. + * + * By default the interface won't be put into promiscuous mode, and won't + * be put into monitor mode. + * * \param device The device which will be sniffed. * \param max_packet_size The maximum packet size to be read. * \param promisc bool indicating wether to put the interface in promiscuous mode.(optional) * \param filter A capture filter to be used on the sniffing session.(optional); + * \param rfmon Indicates if the interface should be put in monitor mode.(optional); */ Sniffer(const std::string &device, unsigned max_packet_size, - bool promisc = false, const std::string &filter = ""); + bool promisc = false, const std::string &filter = "", bool rfmon = false); /** * \brief Constructs an instance of Sniffer. * * The maximum capture size is set to 65535. By default the interface won't - * be put into promiscuous mode. + * be put into promiscuous mode, and won't be put into monitor mode. * * \param device The device which will be sniffed. * \param promisc Indicates if the interface should be put in promiscuous mode. * \param filter A capture filter to be used on the sniffing session.(optional); + * \param rfmon Indicates if the interface should be put in monitor mode.(optional); */ Sniffer(const std::string &device, promisc_type promisc = NON_PROMISC, - const std::string &filter = ""); + const std::string &filter = "", bool rfmon = false); private: void init_sniffer(const std::string &device, unsigned max_packet_size, - bool promisc = false, const std::string &filter = ""); + bool promisc = false, const std::string &filter = "", bool rfmon = false); }; /** diff --git a/src/sniffer.cpp b/src/sniffer.cpp index 7895293..d384ed7 100644 --- a/src/sniffer.cpp +++ b/src/sniffer.cpp @@ -184,20 +184,62 @@ void BaseSniffer::set_timeout(int ms) { // ****************************** Sniffer ****************************** -Sniffer::Sniffer(const string &device, unsigned max_packet_size, - bool promisc, const string &filter) +pcap_t * +pcap_open_live_extended(const char *source, int snaplen, int promisc, int to_ms, int rfmon, char *errbuf) { - init_sniffer(device, max_packet_size, promisc, filter); + pcap_t *p; + int status; + + p = pcap_create(source, errbuf); + if (p == NULL) + return (NULL); + status = pcap_set_snaplen(p, snaplen); + if (status < 0) + goto fail; + status = pcap_set_promisc(p, promisc); + if (status < 0) + goto fail; + status = pcap_set_timeout(p, to_ms); + if (status < 0) + goto fail; + status = pcap_set_rfmon(p, rfmon); + if (status < 0) + goto fail; + status = pcap_activate(p); + if (status < 0) + goto fail; + return (p); + +fail: + if (status == PCAP_ERROR) + snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source, + pcap_geterr(p)); + else if (status == PCAP_ERROR_NO_SUCH_DEVICE || + status == PCAP_ERROR_PERM_DENIED || + status == PCAP_ERROR_PROMISC_PERM_DENIED) + snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", source, + pcap_statustostr(status), pcap_geterr(p)); + else + snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source, + pcap_statustostr(status)); + pcap_close(p); + return (NULL); +} + +Sniffer::Sniffer(const string &device, unsigned max_packet_size, + bool promisc, const string &filter, bool rfmon) +{ + init_sniffer(device, max_packet_size, promisc, filter, rfmon); } Sniffer::Sniffer(const std::string &device, promisc_type promisc, - const std::string &filter) + const std::string &filter, bool rfmon) { - init_sniffer(device, 65535, promisc == PROMISC, filter); + init_sniffer(device, 65535, promisc == PROMISC, filter, rfmon); } void Sniffer::init_sniffer(const std::string &device, unsigned max_packet_size, - bool promisc, const std::string &filter) + bool promisc, const std::string &filter, bool rfmon) { char error[PCAP_ERRBUF_SIZE]; bpf_u_int32 ip, if_mask; @@ -205,7 +247,7 @@ void Sniffer::init_sniffer(const std::string &device, unsigned max_packet_size, ip = 0; if_mask = 0; } - pcap_t *phandle = pcap_open_live(device.c_str(), max_packet_size, promisc, 1000, error); + pcap_t *phandle = pcap_open_live_extended(device.c_str(), max_packet_size, promisc, 1000, rfmon, error); if(!phandle) throw runtime_error(error);