libtins  3.4
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
sniffer.h
1 /*
2  * Copyright (c) 2016, Matias Fontanini
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 
30 
31 #ifndef TINS_SNIFFER_H
32 #define TINS_SNIFFER_H
33 
34 
35 #include <pcap.h>
36 #include <string>
37 #include <memory>
38 #include <stdexcept>
39 #include <iterator>
40 #include "pdu.h"
41 #include "packet.h"
42 #include "cxxstd.h"
43 #include "macros.h"
44 #include "exceptions.h"
45 #include "internals.h"
46 
47 namespace Tins {
48 class SnifferIterator;
49 class SnifferConfiguration;
50 
61 class TINS_API BaseSniffer {
62 public:
67 
68  #if TINS_IS_CXX11
69 
73  BaseSniffer(BaseSniffer &&rhs) TINS_NOEXCEPT
74  : handle_(0), mask_(), extract_raw_(false) {
75  *this = std::move(rhs);
76  }
77 
82  BaseSniffer& operator=(BaseSniffer &&rhs) TINS_NOEXCEPT {
83  using std::swap;
84  swap(handle_, rhs.handle_);
85  swap(mask_, rhs.mask_);
86  swap(extract_raw_, rhs.extract_raw_);
87  return* this;
88  }
89  #endif
90 
95  virtual ~BaseSniffer();
96 
130  PtrPacket next_packet();
131 
184  template <typename Functor>
185  void sniff_loop(Functor function, uint32_t max_packets = 0);
186 
192  bool set_filter(const std::string& filter);
193 
200  void stop_sniff();
201 
205  int get_fd();
206 
213  bool set_direction(pcap_direction_t d);
214 
221  void set_timeout(int ms);
222 
237  void set_extract_raw_pdus(bool value);
238 
245  int link_type() const;
246 
250  iterator begin();
251 
255  iterator end();
256 
260  pcap_t* get_pcap_handle();
261 
265  const pcap_t* get_pcap_handle() const;
266 protected:
270  BaseSniffer();
271 
272  void set_pcap_handle(pcap_t* pcap_handle);
273 
274  void set_if_mask(bpf_u_int32 if_mask);
275 
276  bpf_u_int32 get_if_mask() const;
277 private:
278  BaseSniffer(const BaseSniffer&);
279  BaseSniffer& operator=(const BaseSniffer&);
280 
281  pcap_t* handle_;
282  bpf_u_int32 mask_;
283  bool extract_raw_;
284 };
285 
290 class TINS_API Sniffer : public BaseSniffer {
291 public:
297  NON_PROMISC,
298  PROMISC
299  };
300 
314  Sniffer(const std::string& device, const SnifferConfiguration& configuration);
315 
330  Sniffer(const std::string& device, unsigned max_packet_size,
331  bool promisc = false, const std::string& filter = "", bool rfmon = false);
332 
346  Sniffer(const std::string& device, promisc_type promisc = NON_PROMISC,
347  const std::string& filter = "", bool rfmon = false);
348 
349 private:
350  friend class SnifferConfiguration;
351 
352  void set_snap_len(unsigned snap_len);
353 
354  void set_buffer_size(unsigned buffer_size);
355 
356  void set_promisc_mode(bool promisc_enabled);
357 
358  void set_rfmon(bool rfmon_enabled);
359 
360  void set_immediate_mode(bool enabled);
361 };
362 
370 class TINS_API FileSniffer : public BaseSniffer {
371 public:
377  FileSniffer(const std::string& file_name, const SnifferConfiguration& configuration);
378 
386  FileSniffer(const std::string& file_name, const std::string& filter = "");
387 };
388 
389 template <typename T>
391 public:
392  typedef T* ptr_type;
393  typedef bool (T::*fun_type)(PDU&) ;
394 
395  HandlerProxy(ptr_type ptr, fun_type function)
396  : object_(ptr), fun_(function) {}
397 
398  bool operator()(PDU& pdu) {
399  return (object_->*fun_)(pdu);
400  }
401 private:
402  ptr_type object_;
403  fun_type fun_;
404 };
405 
406 template <typename T>
407 HandlerProxy<T> make_sniffer_handler(T* ptr,
408  typename HandlerProxy<T>::fun_type function) {
409  return HandlerProxy<T>(ptr, function);
410 }
411 
415 class SnifferIterator : public std::iterator<std::forward_iterator_tag, Packet> {
416 public:
422  : sniffer_(sniffer) {
423  if (sniffer_) {
424  advance();
425  }
426  }
427 
432  advance();
433  return* this;
434  }
435 
440  SnifferIterator other(*this);
441  advance();
442  return other;
443  }
444 
450  return pkt_;
451  }
452 
458  return &(**this);
459  }
460 
465  bool operator==(const SnifferIterator& rhs) const {
466  return sniffer_ == rhs.sniffer_;
467  }
468 
473  bool operator!=(const SnifferIterator& rhs) const {
474  return !(*this == rhs);
475  }
476 private:
477  void advance() {
478  pkt_ = sniffer_->next_packet();
479  if (!pkt_) {
480  sniffer_ = 0;
481  }
482  }
483 
484  BaseSniffer* sniffer_;
485  Packet pkt_;
486 };
487 
521 class TINS_API SnifferConfiguration {
522 public:
528  static const unsigned DEFAULT_SNAP_LEN;
529 
535  static const unsigned DEFAULT_TIMEOUT;
536 
541 
546  void set_snap_len(unsigned snap_len);
547 
552  void set_buffer_size(unsigned buffer_size);
553 
558  void set_promisc_mode(bool enabled);
559 
564  void set_filter(const std::string& filter);
565 
570  void set_rfmon(bool enabled);
571 
576  void set_timeout(unsigned timeout);
577 
582  void set_direction(pcap_direction_t direction);
583 
588  void set_immediate_mode(bool enabled);
589 protected:
590  friend class Sniffer;
591  friend class FileSniffer;
592 
593  enum Flags {
594  BUFFER_SIZE = 1,
595  PROMISCUOUS = 2,
596  RFMON = 4,
597  PACKET_FILTER = 8,
598  IMMEDIATE_MODE = 16,
599  DIRECTION = 32
600  };
601 
602  void configure_sniffer_pre_activation(Sniffer& sniffer) const;
603  void configure_sniffer_pre_activation(FileSniffer& sniffer) const;
604 
605  void configure_sniffer_post_activation(Sniffer& sniffer) const;
606 
607  uint32_t flags_;
608  unsigned snap_len_;
609  unsigned buffer_size_;
610  std::string filter_;
611  unsigned timeout_;
612  bool promisc_;
613  bool rfmon_;
614  bool immediate_mode_;
615  pcap_direction_t direction_;
616 };
617 
618 template <typename Functor>
619 void Tins::BaseSniffer::sniff_loop(Functor function, uint32_t max_packets) {
620  for(iterator it = begin(); it != end(); ++it) {
621  try {
622  // If the functor returns false, we're done
623  #if TINS_IS_CXX11 && !defined(_MSC_VER)
624  if (!Tins::Internals::invoke_loop_cb(function, *it)) {
625  return;
626  }
627  #else
628  if (!function(*it->pdu())) {
629  return;
630  }
631  #endif
632  }
633  catch(malformed_packet&) { }
634  catch(pdu_not_found&) { }
635  if (max_packets && --max_packets == 0) {
636  return;
637  }
638  }
639 }
640 
641 } // Tins
642 
643 #endif // TINS_SNIFFER_H
promisc_type
Definition: sniffer.h:296
Definition: packet.h:131
Represents the configuration of a BaseSniffer object.
Definition: sniffer.h:521
Exception thrown when a PDU is not found when using PDU::rfind_pdu.
Definition: exceptions.h:84
Base class for sniffers.
Definition: sniffer.h:61
SnifferIterator operator++(int)
Definition: sniffer.h:439
Sniffs packets from a network interface.
Definition: sniffer.h:290
Iterates over packets sniffed by a BaseSniffer.
Definition: sniffer.h:415
BaseSniffer(BaseSniffer &&rhs) TINS_NOEXCEPT
Move constructor. This constructor is available only in C++11.
Definition: sniffer.h:73
Packet & operator*()
Definition: sniffer.h:449
static const unsigned DEFAULT_SNAP_LEN
The default snapshot length.
Definition: sniffer.h:528
static const unsigned DEFAULT_TIMEOUT
The default timeout.
Definition: sniffer.h:535
Exception thrown when a malformed packet is parsed.
Definition: exceptions.h:64
bool operator==(const SnifferIterator &rhs) const
Definition: sniffer.h:465
Reads pcap files and interprets the packets in it.
Definition: sniffer.h:370
BaseSniffer & operator=(BaseSniffer &&rhs) TINS_NOEXCEPT
Move assignment operator. This operator is available only in C++11.
Definition: sniffer.h:82
Packet * operator->()
Definition: sniffer.h:457
SnifferIterator(BaseSniffer *sniffer=0)
Definition: sniffer.h:421
void sniff_loop(Functor function, uint32_t max_packets=0)
Starts a sniffing loop, using a callback functor for every sniffed packet.
Definition: sniffer.h:619
SnifferIterator iterator
Definition: sniffer.h:66
bool operator!=(const SnifferIterator &rhs) const
Definition: sniffer.h:473
SnifferIterator & operator++()
Definition: sniffer.h:431
Definition: sniffer.h:390
PtrPacket next_packet()
Compiles a filter and uses it to capture one packet.
Definition: sniffer.cpp:137
Base class for protocol data units.
Definition: pdu.h:108
Represents a sniffed packet.
Definition: packet.h:44