00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef PCAP_DESCRIPTOR_HXX_
00023 # define PCAP_DESCRIPTOR_HXX_
00024
00025 # include <stdexcept>
00026
00027 # include "descriptor.hh"
00028
00029 namespace pcapxx
00030 {
00031
00032 template <class B>
00033 descriptor<B>::descriptor(const std::string& dev,
00034 int snaplen,
00035 int promisc,
00036 int to_ms)
00037 {
00038 char errbuf[PCAP_ERRBUF_SIZE];
00039
00040
00041 if (pcap_t* const d = pcap_open_live(const_cast<char*> (dev.c_str()),
00042 snaplen, promisc, to_ms, errbuf))
00043 d_.reset(new shared_data (d));
00044 else
00045 throw std::invalid_argument (errbuf);
00046 }
00047
00048 template <class B>
00049 descriptor<B>::descriptor(const std::string& fname)
00050 {
00051 char errbuf[PCAP_ERRBUF_SIZE];
00052
00053 if (pcap_t* const d = pcap_open_offline(fname.c_str(), errbuf))
00054 d_.reset(new shared_data (d));
00055 else
00056 throw std::invalid_argument (errbuf);
00057 }
00058
00059 template <class B>
00060 descriptor<B>::descriptor(int linktype, int snaplen)
00061 {
00062 if (pcap_t* const d = pcap_open_dead(linktype, snaplen))
00063 d_.reset(new shared_data (d));
00064 else
00065 throw std::runtime_error ("unknown libpcap error");
00066 }
00067
00068 template <class B>
00069 int
00070 descriptor<B>::datalink() const
00071 {
00072 return pcap_datalink(d_->desc);
00073 }
00074
00075 template <class B>
00076 bool
00077 descriptor<B>::is_swapped() const
00078 {
00079 return pcap_is_swapped(d_->desc);
00080 }
00081
00082 template <class B>
00083 std::string
00084 descriptor<B>::error() const
00085 {
00086 return pcap_geterr(d_->desc);
00087 }
00088
00089 template <class B>
00090 pcapxx::dumper
00091 descriptor<B>::dumper(const std::string& filename) const
00092 {
00093 if (pcap_dumper_t* r = pcap_dump_open(d_->desc, filename.c_str()))
00094 return pcapxx::dumper (r);
00095 else
00096 throw std::runtime_error (error());
00097 }
00098
00099 template <class B>
00100 template <handler Callback>
00101 int
00102 descriptor<B>::loop(void* user, int cnt)
00103 {
00104 wrapper_data d;
00105
00106 d.desc = this;
00107 d.user = user;
00108
00109 int r = pcap_loop(d_->desc, cnt,
00110 handler_wrapper<Callback>,
00111 reinterpret_cast<u_char*> (&d));
00112
00113 if (r == -1)
00114 throw std::runtime_error (error());
00115 return r;
00116 }
00117
00118 template <class B>
00119 descriptor<B>::shared_data::shared_data(pcap_t* d): desc (d), curr (0)
00120 {
00121 }
00122
00123 template <class B>
00124 descriptor<B>::shared_data::~shared_data()
00125 {
00126 if (desc)
00127 pcap_close(desc);
00128 }
00129
00130 template <class B>
00131 template <handler H>
00132 void
00133 descriptor<B>::handler_wrapper(u_char* user,
00134 const pcap_pkthdr* h,
00135 const u_char* bytes)
00136 {
00137 wrapper_data& d = *reinterpret_cast<wrapper_data*> (user);
00138 pkthdr h_;
00139
00140 h_.id = ++(d.desc->d_->curr);
00141 h_.ts = h->ts;
00142 h_.caplen = h->caplen;
00143 h_.len = h->len;
00144
00145 return H(d.user, &h_, bytes);
00146 }
00147
00148 }
00149
00150 #endif // ! PCAP_DESCRIPTOR_HXX_