00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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 template <class PCAPDescriptor>
00035 frame_descriptor<PCAPDescriptor>::frame_descriptor(const pkthdr_ptr& h,
00036 const bytes_ptr& b,
00037 unsigned i,
00038 const PCAPDescriptor* d):
00039 data_ (new shared_data (d, i, h, b))
00040 {
00041 }
00042
00043 template <class PCAPDescriptor>
00044 template <class D>
00045 frame_descriptor<PCAPDescriptor>::
00046 frame_descriptor(const descriptor<D>& desc,
00047 std::istream& stream,
00048 unsigned idx,
00049 std::streampos* pos)
00050 {
00051 pkthdr_ptr pcap_header;
00052 bytes_ptr bytes;
00053
00054
00055 {
00056 internals::file_frame_header h;
00057
00058 if (not stream.read(reinterpret_cast<char*> (&h), sizeof (h)) or
00059 stream.gcount() != sizeof (h))
00060 throw tool::read_error ("Unreadable packet header");
00061 if (pos)
00062 *pos += sizeof (h);
00063
00064 const bool s = desc.swapped();
00065 pkthdr* const p = new pkthdr;
00066
00067
00068
00069 memset(p, 0, sizeof (*p));
00070
00071 p->ts.tv_sec = tool::extract_long_s(h.ts.tv_sec, s) + desc.zone();
00072 p->ts.tv_usec = tool::extract_long_s(h.ts.tv_usec, s);
00073 p->caplen = tool::extract_long_u(h.caplen, s);
00074 p->len = tool::extract_long_u(h.len, s);
00075 pcap_header.reset(p);
00076 }
00077
00078
00079 {
00080 const size_t caplen = pcap_header->caplen;
00081 uint8_t* const tmp = new uint8_t[caplen];
00082
00083 if (not stream.read(reinterpret_cast<char*> (tmp), caplen) or
00084 stream.gcount() != std::streampos (caplen))
00085 {
00086 delete tmp;
00087 throw tool::read_error ("Unreadable packet data");
00088 }
00089 if (pos)
00090 *pos += caplen;
00091 bytes.reset(tmp);
00092 }
00093
00094 data_.reset(new shared_data (desc.exact_ptr(), idx, pcap_header, bytes));
00095 }
00096
00097 namespace internals
00098 {
00099
00100 template <class D1, class D2>
00101 struct fd_ctor_helper
00102 {
00103 typedef typename frame_descriptor<D1>::shared_data shared_data1;
00104 typedef typename frame_descriptor<D2>::shared_data shared_data2;
00105 typedef boost::shared_ptr<shared_data1> shared_ptr1;
00106 typedef boost::shared_ptr<shared_data2> shared_ptr2;
00107
00108
00109 static void set(shared_ptr1& d1, const shared_ptr2& d2)
00110 {
00111 assert(d2);
00112
00113 d1.reset(new shared_data1 (0, 0, d2->pcap_header, d2->bytes));
00114 }
00115 };
00116
00117 template <class D>
00118 struct fd_ctor_helper<D, D>
00119 {
00120 typedef typename frame_descriptor<D>::shared_data shared_data;
00121 typedef boost::shared_ptr<shared_data> shared_ptr;
00122
00123 static void set(shared_ptr& d1, const shared_ptr& d2)
00124 {
00125 d1 = d2;
00126 }
00127 };
00128
00129 }
00130
00131 template <class PCAPDescriptor>
00132 template <class OtherDescriptor>
00133 frame_descriptor<PCAPDescriptor>::
00134 frame_descriptor(const frame_descriptor<OtherDescriptor>& fd)
00135 {
00136 typedef internals::fd_ctor_helper<PCAPDescriptor, OtherDescriptor> helper;
00137
00138 helper::set(data_, fd.data());
00139 }
00140
00141 template <class PCAPDescriptor>
00142 unsigned
00143 frame_descriptor<PCAPDescriptor>::id() const
00144 {
00145 assert(data_);
00146
00147 return data_->id;
00148 }
00149
00150 namespace internals
00151 {
00152 template <class D>
00153 bool
00154 fd_swapped_helper(const D*)
00155 {
00156 throw std::logic_error ("This code should be unreachable. "
00157 "Please fill a bug report");
00158 }
00159
00160 template <class D>
00161 bool
00162 fd_swapped_helper(const descriptor<D>* d)
00163 {
00164 return d ? d->swapped() : false;
00165 }
00166
00167 template <>
00168 inline
00169 bool
00170 fd_swapped_helper<tool::undefined_type>(const tool::undefined_type* d)
00171 {
00172 assert(not d);
00173
00174 return false;
00175 }
00176
00177 }
00178
00179 template <class PCAPDescriptor>
00180 bool
00181 frame_descriptor<PCAPDescriptor>::swapped() const
00182 {
00183 return internals::fd_swapped_helper(desc_ptr());
00184 }
00185
00186 template <class PCAPDescriptor>
00187 const PCAPDescriptor*
00188 frame_descriptor<PCAPDescriptor>::desc_ptr() const
00189 {
00190 assert(data_);
00191
00192 return data_->desc;
00193 }
00194
00195 template <class PCAPDescriptor>
00196 const PCAPDescriptor&
00197 frame_descriptor<PCAPDescriptor>::desc() const
00198 {
00199 assert(data_);
00200
00201 if (not data_->desc)
00202 throw std::runtime_error ("Frame has no refering PCAP descriptor");
00203 return *data_->desc;
00204 }
00205
00206 template <class PCAPDescriptor>
00207 const typename frame_descriptor<PCAPDescriptor>::pkthdr_ptr&
00208 frame_descriptor<PCAPDescriptor>::pcap_header() const
00209 {
00210 assert(data_);
00211
00212 return data_->pcap_header;
00213 }
00214
00215 template <class PCAPDescriptor>
00216 const typename frame_descriptor<PCAPDescriptor>::bytes_ptr&
00217 frame_descriptor<PCAPDescriptor>::bytes() const
00218 {
00219 assert(data_);
00220
00221 return data_->bytes;
00222 }
00223
00224 namespace internals
00225 {
00226
00227 template <class D>
00228 std::ostream&
00229 fd_print_helper(std::ostream& o, const D*)
00230 {
00231 throw std::logic_error ("This code should be unreachable. "
00232 "Please fill a bug report");
00233 }
00234
00235 template <class D>
00236 std::ostream&
00237 fd_print_helper(std::ostream& o, const descriptor<D>* d)
00238 {
00239 if (d)
00240 o << d->file_name() << ':';
00241 return o;
00242 }
00243
00244 template <>
00245 inline
00246 std::ostream&
00247 fd_print_helper<tool::undefined_type>
00248 (std::ostream& o, const tool::undefined_type* d)
00249 {
00250 assert(not d);
00251
00252 return o;
00253 }
00254
00255 }
00256
00257 template <class PCAPDescriptor>
00258 std::ostream&
00259 frame_descriptor<PCAPDescriptor>::print(std::ostream& os) const
00260 {
00261 return internals::fd_print_helper(os, desc_ptr()) << data_->id;
00262 }
00263
00264 template <class PCAPDescriptor>
00265 bool
00266 frame_descriptor<PCAPDescriptor>::
00267 operator == (const frame_descriptor& rhs) const
00268 {
00269 return
00270 0 == memcmp(pcap_header().get(), rhs.pcap_header().get(), sizeof (pkthdr))
00271 and
00272 0 == memcmp(bytes().get(), rhs.bytes().get(), pcap_header()->caplen);
00273 }
00274
00275 template <class PCAPDescriptor>
00276 bool
00277 frame_descriptor<PCAPDescriptor>::
00278 operator != (const frame_descriptor& rhs) const
00279 {
00280 return not (*this == rhs);
00281 }
00282
00283 template <class PCAPDescriptor>
00284 frame_descriptor<PCAPDescriptor>::
00285 shared_data::shared_data(const PCAPDescriptor* desc,
00286 unsigned id,
00287 const pkthdr_ptr& pcap_header,
00288 const bytes_ptr& bytes):
00289 desc (desc),
00290 id (id),
00291 pcap_header (pcap_header),
00292 bytes (bytes)
00293 {
00294 }
00295
00296 template <class PCAPDescriptor>
00297 const
00298 boost::shared_ptr<typename frame_descriptor<PCAPDescriptor>::shared_data>&
00299 frame_descriptor<PCAPDescriptor>::data() const
00300 {
00301 assert(data_);
00302
00303 return data_;
00304 }
00305
00306 template <class PCAPDescriptor>
00307 std::ostream&
00308 operator << (std::ostream& os, const frame_descriptor<PCAPDescriptor>& fd)
00309 {
00310 return fd.print(os);
00311 }
00312
00313 }
00314
00315 #endif // ! PCAP_FRAME_DESCRIPTOR_HXX_