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     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 } // End of namespace pcapxx.
00149 
00150 #endif // ! PCAP_DESCRIPTOR_HXX_

Generated on Mon Sep 24 18:13:48 2007 for trace-tools by  doxygen 1.5.3