include/wipal/pcap/frame_descriptor.hxx

00001 /*
00002  * WiPal - 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_FRAME_DESCRIPTOR_HXX_
00023 # define PCAP_FRAME_DESCRIPTOR_HXX_
00024 
00025 # include <cstring>
00026 
00027 # include "frame_descriptor.hh"
00028 # include <wipal/tool/exceptions.hh>
00029 # include <wipal/tool/endianness.hh>
00030 
00031 namespace pcapxx
00032 {
00033 
00034   inline
00035   frame_descriptor::frame_descriptor(const pkthdr* h, const void* b):
00036     pcap_header_ (new pkthdr (*h)),
00037     bytes_ (new uint8_t [h->caplen])
00038   {
00039     memcpy(bytes_.get(), b, pcap_header()->caplen);
00040   }
00041 
00042   inline
00043   frame_descriptor::frame_descriptor(const pkthdr_ptr h, const bytes_ptr b):
00044     pcap_header_ (h),
00045     bytes_ (b)
00046   {
00047   }
00048 
00049   inline
00050   frame_descriptor::frame_descriptor(std::istream&      stream,
00051                                      unsigned           idx,
00052                                      bool               swap,
00053                                      int32_t            zone,
00054                                      std::streampos*    pos)
00055   {
00056     // PCAP header.
00057     {
00058       internals::file_frame_header h;
00059 
00060       if (not stream.read(reinterpret_cast<char*> (&h), sizeof (h)) or
00061           stream.gcount() != sizeof (h))
00062         throw tool::read_error ("Unreadable packet header");
00063       if (pos)
00064         *pos += sizeof (h);
00065 
00066       pkthdr* const             p = new pkthdr;
00067 
00068       // Clear padding.  Allows further use of memcmp() to test
00069       // equality between PCAP headers.
00070       memset(p, 0, sizeof (*p));
00071 
00072       p->id             = idx;
00073       p->swapped        = swap;
00074       p->ts.tv_sec      = tool::extract_long_s(h.ts.tv_sec, swap) + zone;
00075       p->ts.tv_usec     = tool::extract_long_s(h.ts.tv_usec, swap);
00076       p->caplen         = tool::extract_long_u(h.caplen, swap);
00077       p->len            = tool::extract_long_u(h.len, swap);
00078       pcap_header_.reset(p);
00079     }
00080 
00081     // Frame body.
00082     {
00083       const size_t      caplen = pcap_header()->caplen;
00084       uint8_t* const    tmp = new uint8_t[caplen];
00085 
00086       if (not stream.read(reinterpret_cast<char*> (tmp), caplen) or
00087           stream.gcount() != std::streampos (caplen))
00088         throw tool::read_error ("Unreadable packet data");
00089       if (pos)
00090         *pos += caplen;
00091       bytes_.reset(tmp);
00092     }
00093   }
00094 
00095   inline
00096   const frame_descriptor::pkthdr_ptr&
00097   frame_descriptor::pcap_header() const
00098   {
00099     return pcap_header_;
00100   }
00101 
00102   inline
00103   const frame_descriptor::bytes_ptr&
00104   frame_descriptor::bytes() const
00105   {
00106     return bytes_;
00107   }
00108 
00109   inline
00110   std::ostream&
00111   frame_descriptor::print(std::ostream& os) const
00112   {
00113     return os << pcap_header()->id;
00114   }
00115 
00116   inline
00117   bool
00118   frame_descriptor::operator == (const frame_descriptor& rhs) const
00119   {
00120     return
00121       0 == memcmp(pcap_header().get(), rhs.pcap_header().get(), sizeof (pkthdr))
00122       and
00123       0 == memcmp(bytes().get(), rhs.bytes().get(), pcap_header()->caplen);
00124   }
00125 
00126   inline
00127   bool
00128   frame_descriptor::operator != (const frame_descriptor& rhs) const
00129   {
00130     return not (*this == rhs);
00131   }
00132 
00133   inline
00134   std::ostream&
00135   operator << (std::ostream& os, const frame_descriptor& fd)
00136   {
00137     return fd.print(os);
00138   }
00139 
00140 } // End of namespace pcapxx.
00141 
00142 #endif // ! PCAP_FRAME_DESCRIPTOR_HXX_

Generated on Wed Jan 16 16:15:14 2008 for wipal by  doxygen 1.5.4