diff --git a/common/pdml_p.cpp b/common/pdml_p.cpp
index 4d8eee7..e887f33 100644
--- a/common/pdml_p.cpp
+++ b/common/pdml_p.cpp
@@ -21,8 +21,10 @@ along with this program. If not, see
#include "mac.pb.h"
#include "eth2.pb.h"
-#include "ip4.pb.h"
#include "hexdump.pb.h"
+#include "ip4.pb.h"
+#include "ip6.pb.h"
+#include "tcp.pb.h"
#include
@@ -85,16 +87,24 @@ void PdmlDefaultProtocol::unknownFieldHandler(QString name,
// ---------------------------------------------------------- //
PdmlParser::PdmlParser(OstProto::StreamConfigList *streams)
{
- skipUntilEndOfPacket_ = false;
skipCount_ = 0;
+ currentPdmlProtocol_ = NULL;
streams_ = streams;
protocolMap_.insert("unknown", new PdmlUnknownProtocol());
protocolMap_.insert("geninfo", new PdmlGenInfoProtocol());
protocolMap_.insert("frame", new PdmlFrameProtocol());
+#if 0
+ protocolMap_.insert("fake-field-wrapper",
+ new PdmlFakeFieldWrapperProtocol());
+#endif
+#if 0
protocolMap_.insert("eth", new PdmlEthProtocol());
protocolMap_.insert("ip", new PdmlIp4Protocol());
+ protocolMap_.insert("ipv6", new PdmlIp6Protocol());
+ protocolMap_.insert("tcp", new PdmlTcpProtocol());
+#endif
}
PdmlParser::~PdmlParser()
@@ -109,12 +119,6 @@ bool PdmlParser::startElement(const QString & /* namespaceURI */,
{
qDebug("%s (%s)", __FUNCTION__, qName.toAscii().constData());
- if (skipUntilEndOfPacket_)
- {
- Q_ASSERT(skipCount_ == 0);
- goto _exit;
- }
-
if (skipCount_)
{
skipCount_++;
@@ -127,8 +131,6 @@ bool PdmlParser::startElement(const QString & /* namespaceURI */,
}
else if (qName == "packet")
{
- Q_ASSERT(skipUntilEndOfPacket_ == false);
-
// XXX: For now, each packet is converted to a stream
currentStream_ = streams_->add_stream();
currentStream_->mutable_stream_id()->set_id(packetCount_);
@@ -146,11 +148,11 @@ bool PdmlParser::startElement(const QString & /* namespaceURI */,
goto _exit;
}
- if (protoName == "fake-field-wrapper")
- {
- skipUntilEndOfPacket_ = true;
- goto _exit;
- }
+ // HACK HACK HACK
+ if (currentPdmlProtocol_ && (currentPdmlProtocol_->ostProtoId()
+ == OstProto::Protocol::kHexDumpFieldNumber))
+ currentPdmlProtocol_->postProtocolHandler(currentStream_);
+
if (!protocolMap_.contains(protoName))
protoName = "unknown"; // FIXME: change to Ost:Hexdump
@@ -161,25 +163,26 @@ bool PdmlParser::startElement(const QString & /* namespaceURI */,
int protoId = currentPdmlProtocol_->ostProtoId();
+ // PdmlDefaultProtocol =>
+ if (protoId <= 0)
+ goto _exit;
+
+ OstProto::Protocol *proto = currentStream_->add_protocol();
+
+ proto->mutable_protocol_id()->set_id(protoId);
+
+ const google::protobuf::Reflection *msgRefl =
+ proto->GetReflection();
+ const google::protobuf::FieldDescriptor *fDesc =
+ msgRefl->FindKnownExtensionByNumber(protoId);
+
+ // TODO: if !fDesc
+ // init default values of all fields in protocol
+ currentProtocolMsg_ = msgRefl->MutableMessage(proto, fDesc);
+
currentPdmlProtocol_->preProtocolHandler(protoName, attributes,
currentStream_);
- if (protoId > 0)
- {
- OstProto::Protocol *proto = currentStream_->add_protocol();
-
- proto->mutable_protocol_id()->set_id(protoId);
-
- const google::protobuf::Reflection *msgRefl =
- proto->GetReflection();
-
- const google::protobuf::FieldDescriptor *fDesc =
- msgRefl->FindKnownExtensionByNumber(protoId);
-
- // TODO: if !fDesc
- // init default values of all fields in protocol
- currentProtocolMsg_ = msgRefl->MutableMessage(proto, fDesc);
- }
}
else if (qName == "field")
{
@@ -191,16 +194,14 @@ bool PdmlParser::startElement(const QString & /* namespaceURI */,
}
QString name = attributes.value("name");
- int pos = attributes.value("pos").toInt();
- int size = attributes.value("size").toInt();
QString valueStr = attributes.value("value");
+ int pos = -1;
+ int size = -1;
- // fields with no name are analysis and should be skipped
- if (name.isEmpty())
- {
- skipCount_++;
- goto _exit;
- }
+ if (!attributes.value("pos").isEmpty())
+ pos = attributes.value("pos").toInt();
+ if (!attributes.value("size").isEmpty())
+ size = attributes.value("size").toInt();
qDebug("\tname:%s, pos:%d, size:%d value:%s",
name.toAscii().constData(),
@@ -236,6 +237,14 @@ bool PdmlParser::startElement(const QString & /* namespaceURI */,
case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
msgRefl->SetUInt64(currentProtocolMsg_, fDesc,
valueStr.toULongLong(&isOk, kBaseHex));
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
+ {
+ QByteArray hexVal = QByteArray::fromHex(valueStr.toUtf8());
+ std::string str(hexVal.constData(), hexVal.size());
+ msgRefl->SetString(currentProtocolMsg_, fDesc, str);
+ break;
+ }
default:
qDebug("%s: unhandled cpptype = %d", __FUNCTION__,
fDesc->cpp_type());
@@ -262,16 +271,21 @@ bool PdmlParser::endElement(const QString & /* namespaceURI */,
if (qName == "packet")
{
+ if (currentStream_->core().name().size())
+ {
+ OstProto::Protocol *proto = currentStream_->add_protocol();
+
+ proto->mutable_protocol_id()->set_id(
+ OstProto::Protocol::kHexDumpFieldNumber);
+
+ OstProto::HexDump *hexDump = proto->MutableExtension(OstProto::hexDump);
+
+ hexDump->set_content(currentStream_->core().name());
+ hexDump->set_pad_until_end(false);
+ currentStream_->mutable_core()->set_name("");
+ }
packetCount_++;
- if (skipUntilEndOfPacket_)
- skipUntilEndOfPacket_ = false;
-
- goto _exit;
- }
-
- if (skipUntilEndOfPacket_)
- {
- Q_ASSERT(skipCount_ == 0);
+ currentPdmlProtocol_ = NULL;
goto _exit;
}
@@ -284,6 +298,7 @@ bool PdmlParser::endElement(const QString & /* namespaceURI */,
if (qName == "proto")
{
currentPdmlProtocol_->postProtocolHandler(currentStream_);
+ //currentPdmlProtocol_ = NULL;
}
else if (qName == "field")
{
@@ -331,14 +346,22 @@ void PdmlUnknownProtocol::preProtocolHandler(QString name,
const QXmlAttributes &attributes, OstProto::Stream *stream)
{
bool isOk;
+ int size;
int pos = attributes.value("pos").toUInt(&isOk);
- Q_ASSERT(isOk);
+ if (!isOk)
+ goto _skip_pos_size_proc;
- int size = attributes.value("size").toUInt(&isOk);
- Q_ASSERT(isOk);
+ size = attributes.value("size").toUInt(&isOk);
+ if (!isOk)
+ goto _skip_pos_size_proc;
expPos_ = pos;
endPos_ = expPos_ + size;
+
+_skip_pos_size_proc:
+ OstProto::HexDump *hexDump = stream->mutable_protocol(
+ stream->protocol_size()-1)->MutableExtension(OstProto::hexDump);
+ hexDump->set_pad_until_end(false);
}
void PdmlUnknownProtocol::postProtocolHandler(OstProto::Stream *stream)
@@ -346,7 +369,7 @@ void PdmlUnknownProtocol::postProtocolHandler(OstProto::Stream *stream)
OstProto::HexDump *hexDump = stream->mutable_protocol(
stream->protocol_size()-1)->MutableExtension(OstProto::hexDump);
- // Skipped field? Pad with zero!
+ // Skipped field(s) at end? Pad with zero!
if (endPos_ > expPos_)
{
QByteArray hexVal(endPos_ - expPos_, char(0));
@@ -355,10 +378,11 @@ void PdmlUnknownProtocol::postProtocolHandler(OstProto::Stream *stream)
expPos_ += hexVal.size();
}
- Q_ASSERT(expPos_ == endPos_);
+ qDebug("%s: expPos_ = %d, endPos_ = %d\n", __FUNCTION__, expPos_, endPos_);
+ //Q_ASSERT(expPos_ == endPos_);
hexDump->set_pad_until_end(false);
- expPos_ = -1;
+ endPos_ = expPos_ = -1;
}
void PdmlUnknownProtocol::unknownFieldHandler(QString name, int pos, int size,
@@ -367,11 +391,12 @@ void PdmlUnknownProtocol::unknownFieldHandler(QString name, int pos, int size,
OstProto::HexDump *hexDump = stream->mutable_protocol(
stream->protocol_size()-1)->MutableExtension(OstProto::hexDump);
- qDebug("%s: %s, pos = %d, expPos_ = %d\n", __FUNCTION__,
- name.toAscii().constData(), pos, expPos_);
+ qDebug("%s: %s, pos = %d, expPos_ = %d, endPos_ = %d\n",
+ __PRETTY_FUNCTION__, name.toAscii().constData(),
+ pos, expPos_, endPos_);
// Skipped field? Pad with zero!
- if (pos > expPos_)
+ if ((pos > expPos_) && (expPos_ < endPos_))
{
QByteArray hexVal(pos - expPos_, char(0));
@@ -379,10 +404,11 @@ void PdmlUnknownProtocol::unknownFieldHandler(QString name, int pos, int size,
expPos_ += hexVal.size();
}
- if (pos == expPos_)
+ if ((pos == expPos_) /*&& (pos < endPos_)*/)
{
- QByteArray hexVal =
- QByteArray::fromHex(attributes.value("value").toUtf8());
+ QByteArray hexVal = attributes.value("unmaskedvalue").isEmpty() ?
+ QByteArray::fromHex(attributes.value("value").toUtf8()) :
+ QByteArray::fromHex(attributes.value("unmaskedvalue").toUtf8());
hexDump->mutable_content()->append(hexVal.constData(), hexVal.size());
expPos_ += hexVal.size();
@@ -414,7 +440,59 @@ PdmlFrameProtocol::PdmlFrameProtocol()
pdmlProtoName_ = "frame";
}
+#if 1
+// ---------------------------------------------------------- //
+// PdmlFakeFieldWrapperProtocol //
+// ---------------------------------------------------------- //
+PdmlFakeFieldWrapperProtocol::PdmlFakeFieldWrapperProtocol()
+{
+ pdmlProtoName_ = "OST:HexDump";
+ ostProtoId_ = OstProto::Protocol::kHexDumpFieldNumber;
+
+ expPos_ = -1;
+}
+
+void PdmlFakeFieldWrapperProtocol::preProtocolHandler(QString name,
+ const QXmlAttributes &attributes, OstProto::Stream *stream)
+{
+ expPos_ = 0;
+ OstProto::HexDump *hexDump = stream->mutable_protocol(
+ stream->protocol_size()-1)->MutableExtension(OstProto::hexDump);
+ hexDump->set_pad_until_end(false);
+}
+
+void PdmlFakeFieldWrapperProtocol::postProtocolHandler(OstProto::Stream *stream)
+{
+ OstProto::HexDump *hexDump = stream->mutable_protocol(
+ stream->protocol_size()-1)->MutableExtension(OstProto::hexDump);
+
+ qDebug("%s: expPos_ = %d\n", __FUNCTION__, expPos_);
+
+ hexDump->set_pad_until_end(false);
+ expPos_ = -1;
+}
+
+void PdmlFakeFieldWrapperProtocol::unknownFieldHandler(QString name, int pos,
+ int size, const QXmlAttributes &attributes, OstProto::Stream *stream)
+{
+ OstProto::HexDump *hexDump = stream->mutable_protocol(
+ stream->protocol_size()-1)->MutableExtension(OstProto::hexDump);
+
+ if ((pos == expPos_) && (size >= 0) &&
+ (!attributes.value("unmaskedvalue").isEmpty() ||
+ !attributes.value("value").isEmpty()))
+ {
+ QByteArray hexVal = attributes.value("unmaskedvalue").isEmpty() ?
+ QByteArray::fromHex(attributes.value("value").toUtf8()) :
+ QByteArray::fromHex(attributes.value("unmaskedvalue").toUtf8());
+
+ hexDump->mutable_content()->append(hexVal.constData(), hexVal.size());
+ expPos_ += hexVal.size();
+ }
+}
+
+#endif
// ---------------------------------------------------------- //
// PdmlEthProtocol //
// ---------------------------------------------------------- //
@@ -495,3 +573,134 @@ void PdmlIp4Protocol::postProtocolHandler(OstProto::Stream *stream)
ip4->set_is_override_cksum(true); // FIXME
}
+// ---------------------------------------------------------- //
+// PdmlIp6Protocol //
+// ---------------------------------------------------------- //
+
+PdmlIp6Protocol::PdmlIp6Protocol()
+{
+ pdmlProtoName_ = "ipv6";
+ ostProtoId_ = OstProto::Protocol::kIp6FieldNumber;
+
+ fieldMap_.insert("ipv6.version", OstProto::Ip6::kVersionFieldNumber);
+ fieldMap_.insert("ipv6.class", OstProto::Ip6::kTrafficClassFieldNumber);
+ fieldMap_.insert("ipv6.flow", OstProto::Ip6::kFlowLabelFieldNumber);
+ fieldMap_.insert("ipv6.plen", OstProto::Ip6::kPayloadLengthFieldNumber);
+ fieldMap_.insert("ipv6.nxt", OstProto::Ip6::kNextHeaderFieldNumber);
+ fieldMap_.insert("ipv6.hlim", OstProto::Ip6::kHopLimitFieldNumber);
+
+ // ipv6.src and ipv6.dst handled as unknown fields
+}
+
+void PdmlIp6Protocol::unknownFieldHandler(QString name, int pos, int size,
+ const QXmlAttributes &attributes, OstProto::Stream *stream)
+{
+ bool isOk;
+
+ if (name == "ipv6.src")
+ {
+ OstProto::Ip6 *ip6 = stream->mutable_protocol(
+ stream->protocol_size()-1)->MutableExtension(OstProto::ip6);
+ QString addrHexStr = attributes.value("value");
+
+ ip6->set_src_addr_hi(addrHexStr.left(16).toULongLong(&isOk, kBaseHex));
+ ip6->set_src_addr_lo(addrHexStr.right(16).toULongLong(&isOk, kBaseHex));
+ }
+ else if (name == "ipv6.dst")
+ {
+ OstProto::Ip6 *ip6 = stream->mutable_protocol(
+ stream->protocol_size()-1)->MutableExtension(OstProto::ip6);
+ QString addrHexStr = attributes.value("value");
+
+ ip6->set_dst_addr_hi(addrHexStr.left(16).toULongLong(&isOk, kBaseHex));
+ ip6->set_dst_addr_lo(addrHexStr.right(16).toULongLong(&isOk, kBaseHex));
+ }
+}
+
+void PdmlIp6Protocol::postProtocolHandler(OstProto::Stream *stream)
+{
+ OstProto::Ip6 *ip6 = stream->mutable_protocol(
+ stream->protocol_size()-1)->MutableExtension(OstProto::ip6);
+
+ ip6->set_is_override_version(true); // FIXME
+ ip6->set_is_override_payload_length(true); // FIXME
+ ip6->set_is_override_next_header(true); // FIXME
+}
+
+// ---------------------------------------------------------- //
+// PdmlTcpProtocol //
+// ---------------------------------------------------------- //
+
+PdmlTcpProtocol::PdmlTcpProtocol()
+{
+ pdmlProtoName_ = "tcp";
+ ostProtoId_ = OstProto::Protocol::kTcpFieldNumber;
+
+ fieldMap_.insert("tcp.srcport", OstProto::Tcp::kSrcPortFieldNumber);
+ fieldMap_.insert("tcp.dstport", OstProto::Tcp::kDstPortFieldNumber);
+ fieldMap_.insert("tcp.seq", OstProto::Tcp::kSeqNumFieldNumber);
+ fieldMap_.insert("tcp.ack", OstProto::Tcp::kAckNumFieldNumber);
+ fieldMap_.insert("tcp.hdr_len", OstProto::Tcp::kHdrlenRsvdFieldNumber);
+ fieldMap_.insert("tcp.flags", OstProto::Tcp::kFlagsFieldNumber);
+ fieldMap_.insert("tcp.window_size", OstProto::Tcp::kWindowFieldNumber);
+ fieldMap_.insert("tcp.checksum", OstProto::Tcp::kCksumFieldNumber);
+ fieldMap_.insert("tcp.urgent_pointer", OstProto::Tcp::kUrgPtrFieldNumber);
+}
+
+void PdmlTcpProtocol::unknownFieldHandler(QString name, int pos, int size,
+ const QXmlAttributes &attributes, OstProto::Stream *stream)
+{
+ if (name == "tcp.options")
+ options_ = QByteArray::fromHex(attributes.value("value").toUtf8());
+ else if (name == ""
+ && attributes.value("show").startsWith("TCP segment data"))
+ {
+ segmentData_ = QByteArray::fromHex(attributes.value("value").toUtf8());
+ stream->mutable_core()->mutable_name()->append(segmentData_.constData(),
+ segmentData_.size());
+ }
+}
+
+void PdmlTcpProtocol::postProtocolHandler(OstProto::Stream *stream)
+{
+ OstProto::Tcp *tcp = stream->mutable_protocol(
+ stream->protocol_size()-1)->MutableExtension(OstProto::tcp);
+
+ tcp->set_is_override_src_port(true); // FIXME
+ tcp->set_is_override_dst_port(true); // FIXME
+ tcp->set_is_override_hdrlen(true); // FIXME
+ tcp->set_is_override_cksum(true); // FIXME
+
+ if (options_.size())
+ {
+ OstProto::Protocol *proto = stream->add_protocol();
+
+ proto->mutable_protocol_id()->set_id(
+ OstProto::Protocol::kHexDumpFieldNumber);
+
+ OstProto::HexDump *hexDump = proto->MutableExtension(OstProto::hexDump);
+
+ hexDump->mutable_content()->append(options_.constData(),
+ options_.size());
+ hexDump->set_pad_until_end(false);
+ options_.resize(0);
+ }
+
+#if 0
+ if (segmentData_.size())
+ {
+ OstProto::Protocol *proto = stream->add_protocol();
+
+ proto->mutable_protocol_id()->set_id(
+ OstProto::Protocol::kHexDumpFieldNumber);
+
+ OstProto::HexDump *hexDump = proto->MutableExtension(OstProto::hexDump);
+
+ hexDump->mutable_content()->append(segmentData_.constData(),
+ segmentData_.size());
+ hexDump->set_pad_until_end(false);
+ segmentData_.resize(0);
+ }
+#endif
+}
+
diff --git a/common/pdml_p.h b/common/pdml_p.h
index bfa7a01..e125dd6 100644
--- a/common/pdml_p.h
+++ b/common/pdml_p.h
@@ -21,11 +21,14 @@ along with this program. If not, see
#include "protocol.pb.h"
+#include
#include
#include
#include
#include
+// TODO: add const where possible
+
class QXmlSimpleReader;
class QXmlInputSource;
@@ -73,7 +76,6 @@ private:
QMap protocolMap_;
PdmlDefaultProtocol *currentPdmlProtocol_;
- bool skipUntilEndOfPacket_;
int skipCount_;
int packetCount_;
OstProto::StreamConfigList *streams_;
@@ -112,6 +114,22 @@ public:
PdmlFrameProtocol();
};
+#if 1
+class PdmlFakeFieldWrapperProtocol : public PdmlDefaultProtocol
+{
+public:
+ PdmlFakeFieldWrapperProtocol();
+
+ virtual void preProtocolHandler(QString name,
+ const QXmlAttributes &attributes, OstProto::Stream *stream);
+ virtual void postProtocolHandler(OstProto::Stream *stream);
+ virtual void unknownFieldHandler(QString name, int pos, int size,
+ const QXmlAttributes &attributes, OstProto::Stream *stream);
+private:
+ int expPos_;
+};
+#endif
+
class PdmlEthProtocol : public PdmlDefaultProtocol
{
public:
@@ -129,4 +147,26 @@ public:
const QXmlAttributes &attributes, OstProto::Stream *stream);
virtual void postProtocolHandler(OstProto::Stream *stream);
};
+
+class PdmlIp6Protocol : public PdmlDefaultProtocol
+{
+public:
+ PdmlIp6Protocol();
+ virtual void unknownFieldHandler(QString name, int pos, int size,
+ const QXmlAttributes &attributes, OstProto::Stream *stream);
+ virtual void postProtocolHandler(OstProto::Stream *stream);
+};
+
+class PdmlTcpProtocol : public PdmlDefaultProtocol
+{
+public:
+ PdmlTcpProtocol();
+ virtual void unknownFieldHandler(QString name, int pos, int size,
+ const QXmlAttributes &attributes, OstProto::Stream *stream);
+ virtual void postProtocolHandler(OstProto::Stream *stream);
+private:
+ QByteArray options_;
+ QByteArray segmentData_;
+};
+
#endif
diff --git a/server/pcapport.cpp b/server/pcapport.cpp
index d4d1223..0c283c0 100644
--- a/server/pcapport.cpp
+++ b/server/pcapport.cpp
@@ -311,7 +311,7 @@ void PcapPort::PortTransmitter::run()
// 'stats callback' function so that both Rx and Tx stats are updated
// together
- const int kSyncTransmit = 1;
+ const int kSyncTransmit = 0; // temp mask, shd be 1;
int i;
qDebug("sendQueueList_.size = %d", sendQueueList_.size());