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