include/trace-tools/pcap/descriptor.hxx

00001 /*
00002  * trace-tools - A library and a set of tools to manipulate wireless traces.
00003  * Copyright (C) 2007  Universite Pierre et Marie Curie - Paris 6
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00018  * MA  02110-1301  USA
00019  *
00020  * Author: Thomas Claveirole <thomas.claveirole@lip6.fr>
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     // FIXME: Why does libpcap need a *non-const* char *dev?
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 } // End of namespace pcapxx.
00145 
00146 #endif // ! PCAP_DESCRIPTOR_HXX_

Generated on Wed Sep 12 16:02:46 2007 for trace-tools by  doxygen 1.5.3