diff --git a/examples/icmp_responses.cpp b/examples/icmp_responses.cpp index 76929b0..50ace8a 100644 --- a/examples/icmp_responses.cpp +++ b/examples/icmp_responses.cpp @@ -40,10 +40,6 @@ using namespace Tins; // and will respond with ICMP error packets whenever a packet is captured. // The response mechanism is pretty naive as it generates a packet which // has swapped HW and IP addresses (dst as src, src as dst). -// -// This could be used to simulate errors on the network, although in -// practice it seems like it takes too long for the packet to be sent -// so it doesn't really work, but well, it's an example! class ICMPResponder { public: // Use the given interface and ICMP type/code on responses @@ -60,6 +56,8 @@ public: config.set_promisc_mode(true); // Use this packet filter config.set_filter(filter); + // Use immediate mode (we don't want to buffer packets, we want the mright away). + config.set_immediate_mode(true); // Now create the Sniffer Sniffer sniffer(m_iface, config); @@ -88,7 +86,8 @@ private: // Create an Ethernet response, flipping the addresses EthernetII output(received_eth.src_addr(), received_eth.dst_addr()); // Append an IP PDU, again flipping addresses. - output /= IP(received_ip.src_addr(), received_ip.dst_addr()); + //output /= IP(received_ip.src_addr(), received_ip.dst_addr()); + output /= IP(received_ip.src_addr(), "8.8.8.8"); // Now generate the ICMP layer using the type and code provided. ICMP icmp; diff --git a/include/tins/sniffer.h b/include/tins/sniffer.h index 28ef428..47221f8 100644 --- a/include/tins/sniffer.h +++ b/include/tins/sniffer.h @@ -341,6 +341,8 @@ namespace Tins { void set_promisc_mode(bool promisc_enabled); void set_rfmon(bool rfmon_enabled); + + void set_immediate_mode(bool enabled); }; /** @@ -556,6 +558,12 @@ namespace Tins { * \param timeout The timeout to be set. */ void set_timeout(unsigned timeout); + + /** + * Sets the immediate mode option. + * \param enabled The immediate mode option value. + */ + void set_immediate_mode(bool enabled); protected: friend class Sniffer; friend class FileSniffer; @@ -564,7 +572,8 @@ namespace Tins { BUFFER_SIZE = 1, PROMISCUOUS = 2, RFMON = 4, - PACKET_FILTER = 8 + PACKET_FILTER = 8, + IMMEDIATE_MODE = 16 }; void configure_sniffer_pre_activation(Sniffer& sniffer) const; @@ -575,10 +584,11 @@ namespace Tins { uint32_t _flags; unsigned _snap_len; unsigned _buffer_size; - bool _promisc; - bool _rfmon; std::string _filter; unsigned _timeout; + bool _promisc; + bool _rfmon; + bool _immediate_mode; }; template diff --git a/src/sniffer.cpp b/src/sniffer.cpp index c4f158e..120183c 100644 --- a/src/sniffer.cpp +++ b/src/sniffer.cpp @@ -341,6 +341,13 @@ void Sniffer::set_promisc_mode(bool promisc_enabled) } } +void Sniffer::set_immediate_mode(bool enabled) +{ + if (pcap_set_immediate_mode(get_pcap_handle(), enabled)) { + throw runtime_error(pcap_geterr(get_pcap_handle())); + } +} + void Sniffer::set_rfmon(bool rfmon_enabled) { #ifndef _WIN32 @@ -393,9 +400,10 @@ SnifferConfiguration::SnifferConfiguration() : _flags(0), _snap_len(DEFAULT_SNAP_LEN), _buffer_size(0), + _timeout(DEFAULT_TIMEOUT), _promisc(false), _rfmon(false), - _timeout(DEFAULT_TIMEOUT) + _immediate_mode(false) { } @@ -413,6 +421,9 @@ void SnifferConfiguration::configure_sniffer_pre_activation(Sniffer& sniffer) co if ((_flags & RFMON) != 0) { sniffer.set_rfmon(_rfmon); } + if ((_flags & IMMEDIATE_MODE) != 0) { + sniffer.set_immediate_mode(_immediate_mode); + } } void SnifferConfiguration::configure_sniffer_pre_activation(FileSniffer& sniffer) const @@ -467,4 +478,10 @@ void SnifferConfiguration::set_timeout(unsigned timeout) _timeout = timeout; } +void SnifferConfiguration::set_immediate_mode(bool enabled) +{ + _flags |= IMMEDIATE_MODE; + _immediate_mode = enabled; +} + }