2 // Copyright (c) 2010-2017 Intel Corporation
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
19 #include <arpa/inet.h>
21 #include "pcapwriter.hpp"
24 Stream::Stream(uint32_t id, uint32_t sizeHint)
25 : m_id(id), m_prevPktIsClient(false)
27 m_client.pkts.reserve(sizeHint / 2);
28 m_server.pkts.reserve(sizeHint / 2);
29 m_pkts.reserve(sizeHint);
32 bool Stream::isClient(const PcapPkt &pkt) const
34 return m_pt == pkt.parsePkt();
37 size_t Stream::pktCount() const
39 return m_client.pkts.size() + m_server.pkts.size();
42 void Stream::setTupleFromPkt(const PcapPkt &pkt)
44 m_pt = pkt.parsePkt();
47 void Stream::addPkt(const PcapPkt &pkt)
52 bool isClientPkt = isClient(pkt);
60 HalfStream::Action::Part p = half->addPkt(pkt);
63 addAction(half, p, isClientPkt);
66 m_pkts.push_back(pkt);
69 void Stream::addAction(HalfStream *half, HalfStream::Action::Part p, bool isClientPkt)
71 if (m_actions.empty() || m_prevPktIsClient != isClientPkt || m_pt.proto_id == IPPROTO_UDP)
72 m_actions.push_back(HalfStream::Action(half, p, isClientPkt));
74 m_actions.back().addPart(p);
75 m_prevPktIsClient = isClientPkt;
78 Stream::Header Stream::getHeader() const
83 h.clientHdrLen = m_client.hdrLen;
84 h.clientContentLen = m_client.contentLen;
85 h.serverHdrLen = m_server.hdrLen;
86 h.serverContentLen = m_server.contentLen;
87 h.actionCount = m_actions.size();
88 h.clientIP = m_pt.src_addr;
89 h.clientPort = m_pt.src_port;
90 h.serverIP = m_pt.dst_addr;
91 h.serverPort = m_pt.dst_port;
92 h.upRate = m_client.getRate();
93 h.dnRate = m_server.getRate();
94 h.protocol = m_pt.proto_id;
95 h.completedTCP = (m_client.tcpOpen && m_client.tcpClose && m_server.tcpOpen && m_server.tcpClose) ||
96 (!m_client.tcpOpen && !m_client.tcpClose && !m_server.tcpOpen && !m_server.tcpClose);
101 void Stream::Header::toFile(ofstream *f) const
103 f->write((const char *)this, sizeof(*this));
106 int Stream::Header::fromFile(ifstream *f)
108 const size_t readSize = sizeof(*this);
110 f->read((char *)this, readSize);
111 return f->gcount() == readSize? 0 : -1;
114 size_t Stream::Header::getStreamLen() const
116 return actionCount * sizeof(ActionEntry)
117 + clientHdrLen + clientContentLen
118 + serverHdrLen + serverContentLen;
121 void Stream::actionsToFile(ofstream *f) const
123 ActionEntry actionEntry;
124 uint32_t runningTotalLen[2] = {0};
126 for (size_t i = 0; i < m_actions.size(); ++i) {
127 actionEntry.peer = m_actions[i].isClient()? 0 : 1;
128 actionEntry.beg = runningTotalLen[actionEntry.peer];
129 actionEntry.len = m_actions[i].totLen();
131 runningTotalLen[actionEntry.peer] += actionEntry.len;
132 f->write((const char *)&actionEntry, sizeof(actionEntry));
136 void Stream::clientHdrToFile(ofstream *f) const
138 f->write((const char *)m_client.hdr, m_client.hdrLen);
141 void Stream::serverHdrToFile(ofstream *f) const
143 f->write((const char *)m_server.hdr, m_server.hdrLen);
146 void Stream::contentsToFile(ofstream *f, bool isClient) const
148 for (size_t i = 0; i < m_actions.size(); ++i)
149 if (m_actions[i].isClient() == isClient)
150 m_actions[i].toFile(f);
153 void Stream::toFile(ofstream *f)
155 getHeader().toFile(f);
159 contentsToFile(f, true);
160 contentsToFile(f, false);
163 void Stream::toPcap(const string& outFile)
168 for (size_t i = 0; i < m_pkts.size(); ++i)