00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef PCAP_OSTREAM_HXX_
00023 # define PCAP_OSTREAM_HXX_
00024
00025 # include <wipal/pcap/base.hh>
00026
00027 # include "ostream.hh"
00028
00029 namespace wpl
00030 {
00031
00032 namespace pcap
00033 {
00034
00035 inline
00036 ostream::ostream(const std::string& filename,
00037 const pkt::type type,
00038 const int32_t zone,
00039 const int32_t snaplen):
00040 filename_ (filename),
00041 size_ (0)
00042 {
00043 setup(type, zone, snaplen);
00044 }
00045
00046 template <class B>
00047 ostream::ostream(const std::string& filename,
00048 const stream<B>& stream):
00049 filename_ (filename),
00050 size_ (0)
00051 {
00052 setup(stream.type(), stream.zone(), stream.snaplen());
00053 }
00054
00055 template <class S>
00056 ostream::ostream(const std::string& filename,
00057 const list<S>& list):
00058 filename_ (filename),
00059 size_ (0)
00060 {
00061 if (list.empty())
00062 {
00063 std::ostringstream os;
00064
00065 os << list << " is empty";
00066 throw std::invalid_argument (os.str());
00067 }
00068
00069 const S& stream = list.get(0);
00070
00071 setup(stream.type(), stream.zone(), stream.snaplen());
00072 }
00073
00074 inline
00075 ostream&
00076 ostream::write(const pkt::metadata& meta, const void* bytes)
00077 {
00078
00079 {
00080 internals::file_frame_header h;
00081
00082 h.ts.tv_sec = meta.ts.tv_sec;
00083 h.ts.tv_usec = meta.ts.tv_usec;
00084 h.caplen = meta.caplen;
00085 h.len = meta.len;
00086
00087 if (not output_->write(reinterpret_cast<char*> (&h), sizeof (h)))
00088 throw tool::write_error("Could not write PCAP packet header");
00089 }
00090
00091
00092 if (not output_->write(static_cast<const char*> (bytes), meta.caplen))
00093 throw tool::write_error("Could not write packet data");
00094
00095 if (++size_ % pcap::indexed_file<>::mark_step == 0)
00096 marks_.push_back(output_->tellp());
00097
00098 return *this;
00099 }
00100
00101 template <class S>
00102 ostream&
00103 ostream::operator << (const pkt::packet<S>& p)
00104 {
00105 return write(p.meta(), p.bytes());
00106 }
00107
00108 template <class S>
00109 ostream&
00110 ostream::operator () (const pkt::packet<S>& p)
00111 {
00112 return operator << (p);
00113 }
00114
00115 inline
00116 pcap::indexed_file<>
00117 ostream::file() const
00118 {
00119 return pcap::indexed_file<> (filename_, marks_, size_);
00120 }
00121
00122 inline
00123 void
00124 ostream::setup(const pkt::type type,
00125 const int32_t zone,
00126 const int32_t snaplen)
00127 {
00128 output_.reset(new std::ofstream (filename_.c_str(), (std::ios::out |
00129 std::ios::trunc |
00130 std::ios::binary)));
00131 internals::file_header h;
00132
00133 h.magic = 0xa1b2c3d4;
00134 h.version_major = internals::version_major;
00135 h.version_minor = internals::version_minor;
00136 h.thiszone = zone;
00137 h.sigfigs = 0;
00138 h.snaplen = snaplen;
00139 h.linktype = type;
00140
00141 if (not *output_)
00142 throw tool::file_error("Could not open " + filename_ + " for writing");
00143 if (not output_->write(reinterpret_cast<char*> (&h), sizeof (h)))
00144 throw tool::write_error(filename_ +
00145 ": Could not write PCAP file header");
00146
00147 marks_.push_back(output_->tellp());
00148 }
00149
00150 }
00151
00152 }
00153
00154 #endif // ! PCAP_OSTREAM_HH_