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 d_.reset(new shared_data (pcap_open_live(const_cast<char*> (dev.c_str()),
00042 snaplen, promisc, to_ms, errbuf)));
00043 if (not d_->desc)
00044 throw std::invalid_argument (errbuf);
00045 }
00046
00047 template <class B>
00048 descriptor<B>::descriptor(const std::string& fname)
00049 {
00050 char errbuf[PCAP_ERRBUF_SIZE];
00051
00052 d_.reset(new shared_data (pcap_open_offline(fname.c_str(), errbuf)));
00053 if (not d_->desc)
00054 throw std::invalid_argument (errbuf);
00055 }
00056
00057 template <class B>
00058 descriptor<B>::descriptor(int linktype, int snaplen)
00059 {
00060 d_.reset(new shared_data (pcap_open_dead(linktype, snaplen)));
00061 if (not d_->desc)
00062 throw std::runtime_error ("unknown libpcap error");
00063 }
00064
00065 template <class B>
00066 int
00067 descriptor<B>::datalink() const
00068 {
00069 return pcap_datalink(d_->desc);
00070 }
00071
00072 template <class B>
00073 bool
00074 descriptor<B>::is_swapped() const
00075 {
00076 return pcap_is_swapped(d_->desc);
00077 }
00078
00079 template <class B>
00080 std::string
00081 descriptor<B>::error() const
00082 {
00083 return pcap_geterr(d_->desc);
00084 }
00085
00086 template <class B>
00087 pcapxx::dumper
00088 descriptor<B>::dumper(const std::string& filename) const
00089 {
00090 if (pcap_dumper_t* r = pcap_dump_open(d_->desc, filename.c_str()))
00091 return pcapxx::dumper (r);
00092 else
00093 throw std::runtime_error (error());
00094 }
00095
00096 template <class B>
00097 template <handler Callback>
00098 int
00099 descriptor<B>::loop(void* user, int cnt)
00100 {
00101 wrapper_data d;
00102
00103 d.desc = this;
00104 d.user = user;
00105
00106 int r = pcap_loop(d_->desc, cnt,
00107 handler_wrapper<Callback>,
00108 reinterpret_cast<u_char*> (&d));
00109
00110 if (r == -1)
00111 throw std::runtime_error (error());
00112 return r;
00113 }
00114
00115 template <class B>
00116 descriptor<B>::shared_data::shared_data(pcap_t* d): desc (d), curr (0)
00117 {
00118 }
00119
00120 template <class B>
00121 descriptor<B>::shared_data::~shared_data()
00122 {
00123 pcap_close(desc);
00124 }
00125
00126 template <class B>
00127 template <handler H>
00128 void
00129 descriptor<B>::handler_wrapper(u_char* user,
00130 const pcap_pkthdr* h,
00131 const u_char* bytes)
00132 {
00133 wrapper_data& d = *reinterpret_cast<wrapper_data*> (user);
00134 pkthdr h_;
00135
00136 h_.id = ++(d.desc->d_->curr);
00137 h_.ts = h->ts;
00138 h_.caplen = h->caplen;
00139 h_.len = h->len;
00140
00141 return H(d.user, &h_, bytes);
00142 }
00143
00144 }
00145
00146 #endif // ! PCAP_DESCRIPTOR_HXX_