diff --git a/include/sniffer.h b/include/sniffer.h index 84f77d2..c683d4e 100644 --- a/include/sniffer.h +++ b/include/sniffer.h @@ -52,6 +52,12 @@ namespace Tins { /** * \brief Sniffer class can be used to sniff packets using filters. + * + * This class uses a given filter to sniff packets and allow the user + * to handle them. Each time a filter is set, it's used until a new one + * is set. Both Sniffer::next_packet and Sniffer::sniff_loop have an + * optional filter parameter. If a filter is set using those parameter, + * the previously set filter is freed and the new one is used. */ class Sniffer { public: @@ -71,15 +77,15 @@ namespace Tins { /** * \brief Compiles a filter and uses it to capture one packet. * - * This method should be used only when expecting few packets. - * It's innefficient since it recompiles the filter every time it - * is called. To reuse a filter and sniff more efficiently, use - * Sniffer::sniff_loop. + * This method returns the first sniffed PDU that matches the given + * filter. If no filter is given, the previously set filter will be used. + * If no filter has been set, then no filtering is applied to sniffed + * packets. * \param filter The filter which will be used while sniffing. * \return The captured packet, matching the given filter, 0 if an * error occured(probably compiling the filter). */ - PDU *next_pdu(const std::string &filter = ""); + PDU *next_packet(const std::string &filter = ""); /** * \brief Starts a sniffing loop, using a callback object for every @@ -89,10 +95,17 @@ namespace Tins { * or it could be a specific SnifferHandler specialization. This method deletes * packets after they are handled, therefore the handlers MUST NOT delete them. * \param cback_handler The callback handler object which should process packets. - * \param filter The filter to use when sniffing. + * \param filter The filter to use when sniffing(optional). * \param max_packets The maximum amount of packets to sniff. 0 == infinite. */ - void sniff_loop(AbstractSnifferHandler *cback_handler, const std::string &filter, uint32_t max_packets = 0); + void sniff_loop(AbstractSnifferHandler *cback_handler, const std::string &filter = "", uint32_t max_packets = 0); + + /** + * \brief Sets a filter on this sniffer. + * \param filter The filter to be set. + * \return True iif it was possible to apply the filter. + */ + bool set_filter(const std::string &filter); /** * \brief Stops sniffing loops. diff --git a/src/sniffer.cpp b/src/sniffer.cpp index f31abd6..eb66844 100644 --- a/src/sniffer.cpp +++ b/src/sniffer.cpp @@ -60,13 +60,9 @@ bool Tins::Sniffer::compile_set_filter(const string &filter, bpf_program &prog) return (pcap_compile(handle, &prog, filter.c_str(), 0, ip) != -1 && pcap_setfilter(handle, &prog) != -1); } -Tins::PDU *Tins::Sniffer::next_pdu(const string &filter) { - if(filter.size()) { - if(actual_filter.bf_insns) - pcap_freecode(&actual_filter); - if(!compile_set_filter(filter, actual_filter)) - return 0; - } +Tins::PDU *Tins::Sniffer::next_packet(const string &filter) { + if(filter.size()) + set_filter(filter); pcap_pkthdr header; PDU *ret = 0; while(!ret) { @@ -86,16 +82,18 @@ void Tins::Sniffer::stop_sniff() { } void Tins::Sniffer::sniff_loop(AbstractSnifferHandler *cback_handler, const string &filter, uint32_t max_packets) { - if(filter.size()) { - if(actual_filter.bf_insns) - pcap_freecode(&actual_filter); - if(!compile_set_filter(filter, actual_filter)) - return; - } + if(filter.size()) + set_filter(filter); LoopData data(handle, cback_handler); pcap_loop(handle, max_packets, Sniffer::callback_handler, (u_char*)&data); } +bool Tins::Sniffer::set_filter(const std::string &filter) { + if(actual_filter.bf_insns) + pcap_freecode(&actual_filter); + return compile_set_filter(filter, actual_filter); +} + // Static void Tins::Sniffer::callback_handler(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) { try {