snapshot
This commit is contained in:
parent
a70a6c5350
commit
5ab89bba29
@ -20,7 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
|||||||
#include "port.h"
|
#include "port.h"
|
||||||
|
|
||||||
#include "fileformat.h"
|
#include "fileformat.h"
|
||||||
#include "pdmlfileformat.h"
|
#include "pcapfileformat.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
@ -229,7 +229,7 @@ bool Port::openStreams(QString fileName, bool append, QString &error)
|
|||||||
OstProto::StreamConfigList streams;
|
OstProto::StreamConfigList streams;
|
||||||
|
|
||||||
//if (!fileFormat.openStreams(fileName, streams, error))
|
//if (!fileFormat.openStreams(fileName, streams, error))
|
||||||
if (!pdmlFileFormat.openStreams(fileName, streams, error))
|
if (!pcapFileFormat.openStreams(fileName, streams, error))
|
||||||
goto _fail;
|
goto _fail;
|
||||||
|
|
||||||
if (!append)
|
if (!append)
|
||||||
@ -262,5 +262,6 @@ bool Port::saveStreams(QString fileName, QString &error)
|
|||||||
mStreams[i]->protoDataCopyInto(*s);
|
mStreams[i]->protoDataCopyInto(*s);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fileFormat.saveStreams(streams, fileName, error);
|
//return fileFormat.saveStreams(streams, fileName, error);
|
||||||
|
return pcapFileFormat.saveStreams(streams, fileName, error);
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ HEADERS += \
|
|||||||
abstractprotocol.h \
|
abstractprotocol.h \
|
||||||
comboprotocol.h \
|
comboprotocol.h \
|
||||||
fileformat.h \
|
fileformat.h \
|
||||||
|
pcapfileformat.h \
|
||||||
pdmlfileformat.h \
|
pdmlfileformat.h \
|
||||||
pdml_p.h \
|
pdml_p.h \
|
||||||
protocolmanager.h \
|
protocolmanager.h \
|
||||||
@ -98,6 +99,7 @@ SOURCES += \
|
|||||||
abstractprotocol.cpp \
|
abstractprotocol.cpp \
|
||||||
crc32c.cpp \
|
crc32c.cpp \
|
||||||
fileformat.cpp \
|
fileformat.cpp \
|
||||||
|
pcapfileformat.cpp \
|
||||||
pdmlfileformat.cpp \
|
pdmlfileformat.cpp \
|
||||||
pdml_p.cpp \
|
pdml_p.cpp \
|
||||||
protocolmanager.cpp \
|
protocolmanager.cpp \
|
||||||
|
252
common/pcapfileformat.cpp
Normal file
252
common/pcapfileformat.cpp
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2010 Srivats P.
|
||||||
|
|
||||||
|
This file is part of "Ostinato"
|
||||||
|
|
||||||
|
This is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pcapfileformat.h"
|
||||||
|
#include "streambase.h"
|
||||||
|
#include "hexdump.pb.h"
|
||||||
|
|
||||||
|
#include <QDataStream>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
static inline quint32 swap32(quint32 val)
|
||||||
|
{
|
||||||
|
return (((val >> 24) && 0x000000FF) |
|
||||||
|
((val >> 16) && 0x0000FF00) |
|
||||||
|
((val << 16) && 0x00FF0000) |
|
||||||
|
((val << 24) && 0xFF000000));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline quint16 swap16(quint16 val)
|
||||||
|
{
|
||||||
|
return (((val >> 8) && 0x00FF) |
|
||||||
|
((val << 8) && 0xFF00));
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
quint32 magicNumber; /* magic number */
|
||||||
|
quint16 versionMajor; /* major version number */
|
||||||
|
quint16 versionMinor; /* minor version number */
|
||||||
|
qint32 thisZone; /* GMT to local correction */
|
||||||
|
quint32 sigfigs; /* accuracy of timestamps */
|
||||||
|
quint32 snapLen; /* max length of captured packets, in octets */
|
||||||
|
quint32 network; /* data link type */
|
||||||
|
} PcapFileHeader;
|
||||||
|
|
||||||
|
const quint32 kPcapFileMagic = 0xa1b2c3d4;
|
||||||
|
const quint32 kPcapFileMagicSwapped = 0xd4c3b2a1;
|
||||||
|
const quint16 kPcapFileVersionMajor = 2;
|
||||||
|
const quint16 kPcapFileVersionMinor = 4;
|
||||||
|
const quint32 kMaxSnapLen = 65535;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
quint32 tsSec; /* timestamp seconds */
|
||||||
|
quint32 tsUsec; /* timestamp microseconds */
|
||||||
|
quint32 inclLen; /* number of octets of packet saved in file */
|
||||||
|
quint32 origLen; /* actual length of packet */
|
||||||
|
} PcapPacketHeader;
|
||||||
|
|
||||||
|
PcapFileFormat pcapFileFormat;
|
||||||
|
|
||||||
|
PcapFileFormat::PcapFileFormat()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PcapFileFormat::~PcapFileFormat()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PcapFileFormat::openStreams(const QString fileName,
|
||||||
|
OstProto::StreamConfigList &streams, QString &error)
|
||||||
|
{
|
||||||
|
bool isOk = false;
|
||||||
|
QFile file(fileName);
|
||||||
|
QDataStream fd;
|
||||||
|
quint32 magic;
|
||||||
|
PcapFileHeader fileHdr;
|
||||||
|
PcapPacketHeader pktHdr;
|
||||||
|
quint32 len;
|
||||||
|
int pktCount = 1;
|
||||||
|
QByteArray pktBuf;
|
||||||
|
|
||||||
|
if (!file.open(QIODevice::ReadOnly))
|
||||||
|
goto _err_open;
|
||||||
|
|
||||||
|
if (file.size() < sizeof(fileHdr))
|
||||||
|
goto _err_truncated;
|
||||||
|
|
||||||
|
fd.setDevice(&file);
|
||||||
|
|
||||||
|
fd >> magic;
|
||||||
|
|
||||||
|
|
||||||
|
if (magic == kPcapFileMagicSwapped)
|
||||||
|
{
|
||||||
|
// Toggle Byte order
|
||||||
|
if (fd.byteOrder() == QDataStream::BigEndian)
|
||||||
|
fd.setByteOrder(QDataStream::LittleEndian);
|
||||||
|
else
|
||||||
|
fd.setByteOrder(QDataStream::BigEndian);
|
||||||
|
}
|
||||||
|
else if (magic != kPcapFileMagic)
|
||||||
|
goto _err_bad_magic;
|
||||||
|
|
||||||
|
fd >> fileHdr.versionMajor;
|
||||||
|
fd >> fileHdr.versionMinor;
|
||||||
|
fd >> fileHdr.thisZone;
|
||||||
|
fd >> fileHdr.sigfigs;
|
||||||
|
fd >> fileHdr.snapLen;
|
||||||
|
fd >> fileHdr.network;
|
||||||
|
|
||||||
|
if ((fileHdr.versionMajor != kPcapFileVersionMajor) ||
|
||||||
|
(fileHdr.versionMinor != kPcapFileVersionMinor))
|
||||||
|
goto _err_unsupported_version;
|
||||||
|
|
||||||
|
// TODO: what do we do about non-ethernet networks?
|
||||||
|
|
||||||
|
pktBuf.resize(fileHdr.snapLen);
|
||||||
|
|
||||||
|
while (!fd.atEnd())
|
||||||
|
{
|
||||||
|
OstProto::Stream *stream = streams.add_stream();
|
||||||
|
OstProto::Protocol *proto = stream->add_protocol();
|
||||||
|
OstProto::HexDump *hexDump = proto->MutableExtension(OstProto::hexDump);
|
||||||
|
|
||||||
|
stream->mutable_stream_id()->set_id(pktCount);
|
||||||
|
stream->mutable_core()->set_is_enabled(true);
|
||||||
|
proto->mutable_protocol_id()->set_id(
|
||||||
|
OstProto::Protocol::kHexDumpFieldNumber);
|
||||||
|
|
||||||
|
// read PcapPacketHeader
|
||||||
|
fd >> pktHdr.tsSec;
|
||||||
|
fd >> pktHdr.tsUsec;
|
||||||
|
fd >> pktHdr.inclLen;
|
||||||
|
fd >> pktHdr.origLen;
|
||||||
|
|
||||||
|
// TODO: chk fd.status()
|
||||||
|
|
||||||
|
// validations on inclLen <= origLen && inclLen <= snapLen
|
||||||
|
Q_ASSERT(pktHdr.inclLen <= fileHdr.snapLen); // TODO: convert to if
|
||||||
|
|
||||||
|
// read Pkt contents
|
||||||
|
len = fd.readRawData(pktBuf.data(), pktHdr.inclLen); // TODO: use while?
|
||||||
|
Q_ASSERT(len == pktHdr.inclLen); // TODO: remove assert
|
||||||
|
|
||||||
|
hexDump->set_content(pktBuf.data(), pktHdr.inclLen);
|
||||||
|
hexDump->set_pad_until_end(false);
|
||||||
|
|
||||||
|
stream->mutable_core()->set_frame_len(pktHdr.inclLen+4); // FCS
|
||||||
|
|
||||||
|
pktCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
isOk = true;
|
||||||
|
goto _exit;
|
||||||
|
|
||||||
|
_err_unsupported_version:
|
||||||
|
error = QString(tr("%1 is in PCAP version %2.%3 format which is "
|
||||||
|
"not supported - Sorry!"))
|
||||||
|
.arg(fileName).arg(fileHdr.versionMajor).arg(fileHdr.versionMinor);
|
||||||
|
goto _exit;
|
||||||
|
|
||||||
|
_err_bad_magic:
|
||||||
|
error = QString(tr("%1 is not a valid PCAP file")).arg(fileName);
|
||||||
|
goto _exit;
|
||||||
|
|
||||||
|
_err_truncated:
|
||||||
|
error = QString(tr("%1 is too short")).arg(fileName);
|
||||||
|
goto _exit;
|
||||||
|
|
||||||
|
_err_open:
|
||||||
|
error = QString(tr("Unable to open file: %1")).arg(fileName);
|
||||||
|
goto _exit;
|
||||||
|
|
||||||
|
_exit:
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PcapFileFormat::saveStreams(const OstProto::StreamConfigList streams,
|
||||||
|
const QString fileName, QString &error)
|
||||||
|
{
|
||||||
|
bool isOk = false;
|
||||||
|
QFile file(fileName);
|
||||||
|
QDataStream fd;
|
||||||
|
PcapFileHeader fileHdr;
|
||||||
|
PcapPacketHeader pktHdr;
|
||||||
|
QByteArray pktBuf;
|
||||||
|
|
||||||
|
if (!file.open(QIODevice::WriteOnly))
|
||||||
|
goto _err_open;
|
||||||
|
|
||||||
|
fd.setDevice(&file);
|
||||||
|
|
||||||
|
fileHdr.magicNumber = kPcapFileMagic;
|
||||||
|
fileHdr.versionMajor = kPcapFileVersionMajor;
|
||||||
|
fileHdr.versionMinor = kPcapFileVersionMinor;
|
||||||
|
fileHdr.thisZone = 0;
|
||||||
|
fileHdr.sigfigs = 0;
|
||||||
|
fileHdr.snapLen = kMaxSnapLen;
|
||||||
|
fileHdr.network = 1; // Ethernet; FIXME: Hardcoding
|
||||||
|
|
||||||
|
fd << fileHdr.magicNumber;
|
||||||
|
fd << fileHdr.versionMajor;
|
||||||
|
fd << fileHdr.versionMinor;
|
||||||
|
fd << fileHdr.thisZone;
|
||||||
|
fd << fileHdr.sigfigs;
|
||||||
|
fd << fileHdr.snapLen;
|
||||||
|
fd << fileHdr.network;
|
||||||
|
|
||||||
|
pktBuf.resize(kMaxSnapLen);
|
||||||
|
|
||||||
|
for (int i = 0; i < streams.stream_size(); i++)
|
||||||
|
{
|
||||||
|
StreamBase s;
|
||||||
|
|
||||||
|
s.setId(i);
|
||||||
|
s.protoDataCopyFrom(streams.stream(i));
|
||||||
|
// TODO: expand frameIndex for each stream
|
||||||
|
s.frameValue((uchar*)pktBuf.data(), pktBuf.size(), 0);
|
||||||
|
|
||||||
|
// TODO: write actual timing!?!?
|
||||||
|
pktHdr.tsSec = 0;
|
||||||
|
pktHdr.tsUsec = 0;
|
||||||
|
pktHdr.inclLen = pktHdr.origLen = s.frameLen() - 4; // FCS; FIXME: Hardcoding
|
||||||
|
if (pktHdr.inclLen > fileHdr.snapLen)
|
||||||
|
pktHdr.inclLen = fileHdr.snapLen;
|
||||||
|
|
||||||
|
fd << pktHdr.tsSec;
|
||||||
|
fd << pktHdr.tsUsec;
|
||||||
|
fd << pktHdr.inclLen;
|
||||||
|
fd << pktHdr.origLen;
|
||||||
|
fd.writeRawData(pktBuf.data(), pktHdr.inclLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
isOk = true;
|
||||||
|
goto _exit;
|
||||||
|
|
||||||
|
_err_open:
|
||||||
|
error = QString(tr("Unable to open file: %1")).arg(fileName);
|
||||||
|
goto _exit;
|
||||||
|
|
||||||
|
_exit:
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
|
42
common/pcapfileformat.h
Normal file
42
common/pcapfileformat.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2010 Srivats P.
|
||||||
|
|
||||||
|
This file is part of "Ostinato"
|
||||||
|
|
||||||
|
This is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
#ifndef _PCAP_FILE_FORMAT_H
|
||||||
|
#define _PCAP_FILE_FORMAT_H
|
||||||
|
|
||||||
|
#include "protocol.pb.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class PcapFileFormat : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
PcapFileFormat();
|
||||||
|
~PcapFileFormat();
|
||||||
|
|
||||||
|
bool openStreams(const QString fileName,
|
||||||
|
OstProto::StreamConfigList &streams, QString &error);
|
||||||
|
bool saveStreams(const OstProto::StreamConfigList streams,
|
||||||
|
const QString fileName, QString &error);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern PcapFileFormat pcapFileFormat;
|
||||||
|
|
||||||
|
#endif
|
@ -43,6 +43,11 @@ PdmlDefaultProtocol::~PdmlDefaultProtocol()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PdmlDefaultProtocol* PdmlDefaultProtocol::createInstance()
|
||||||
|
{
|
||||||
|
return new PdmlDefaultProtocol();
|
||||||
|
}
|
||||||
|
|
||||||
QString PdmlDefaultProtocol::pdmlProtoName() const
|
QString PdmlDefaultProtocol::pdmlProtoName() const
|
||||||
{
|
{
|
||||||
return pdmlProtoName_;
|
return pdmlProtoName_;
|
||||||
@ -64,7 +69,12 @@ int PdmlDefaultProtocol::fieldId(QString name) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PdmlDefaultProtocol::preProtocolHandler(QString name,
|
void PdmlDefaultProtocol::preProtocolHandler(QString name,
|
||||||
const QXmlAttributes &attributes, OstProto::Stream *stream)
|
const QXmlStreamAttributes &attributes, OstProto::Stream *stream)
|
||||||
|
{
|
||||||
|
return; // do nothing!
|
||||||
|
}
|
||||||
|
|
||||||
|
void PdmlDefaultProtocol::prematureEndHandler(int pos, OstProto::Stream *stream)
|
||||||
{
|
{
|
||||||
return; // do nothing!
|
return; // do nothing!
|
||||||
}
|
}
|
||||||
@ -75,13 +85,14 @@ void PdmlDefaultProtocol::postProtocolHandler(OstProto::Stream *stream)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PdmlDefaultProtocol::unknownFieldHandler(QString name,
|
void PdmlDefaultProtocol::unknownFieldHandler(QString name,
|
||||||
int pos, int size, const QXmlAttributes &attributes,
|
int pos, int size, const QXmlStreamAttributes &attributes,
|
||||||
OstProto::Stream *stream)
|
OstProto::Stream *stream)
|
||||||
{
|
{
|
||||||
return; // do nothing!
|
return; // do nothing!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
// ---------------------------------------------------------- //
|
// ---------------------------------------------------------- //
|
||||||
// PdmlParser
|
// PdmlParser
|
||||||
// ---------------------------------------------------------- //
|
// ---------------------------------------------------------- //
|
||||||
@ -328,6 +339,392 @@ bool PdmlParser::fatalError(const QXmlParseException &exception)
|
|||||||
.arg(extra));
|
.arg(extra));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ---------------------------------------------------------- //
|
||||||
|
// PdmlReader //
|
||||||
|
// ---------------------------------------------------------- //
|
||||||
|
PdmlReader::PdmlReader(OstProto::StreamConfigList *streams)
|
||||||
|
{
|
||||||
|
streams_ = streams;
|
||||||
|
|
||||||
|
factory_.insert("hexdump", PdmlUnknownProtocol::createInstance);
|
||||||
|
factory_.insert("geninfo", PdmlGenInfoProtocol::createInstance);
|
||||||
|
factory_.insert("frame", PdmlFrameProtocol::createInstance);
|
||||||
|
#if 0
|
||||||
|
factory_.insert("fake-field-wrapper",
|
||||||
|
new PdmlFakeFieldWrapperProtocol());
|
||||||
|
#endif
|
||||||
|
factory_.insert("eth",PdmlEthProtocol::createInstance);
|
||||||
|
factory_.insert("ip",PdmlIp4Protocol::createInstance);
|
||||||
|
factory_.insert("ipv6",PdmlIp6Protocol::createInstance);
|
||||||
|
factory_.insert("tcp",PdmlTcpProtocol::createInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
PdmlReader::~PdmlReader()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PdmlReader::read(QIODevice *device)
|
||||||
|
{
|
||||||
|
setDevice(device);
|
||||||
|
packetCount_ = 0;
|
||||||
|
|
||||||
|
while (!atEnd())
|
||||||
|
{
|
||||||
|
readNext();
|
||||||
|
if (isStartElement())
|
||||||
|
{
|
||||||
|
if (name() == "pdml")
|
||||||
|
readPdml();
|
||||||
|
else
|
||||||
|
raiseError("Not a pdml file!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return !error();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: use a temp pool to avoid a lot of new/delete
|
||||||
|
PdmlDefaultProtocol* PdmlReader::allocPdmlProtocol(QString protoName)
|
||||||
|
{
|
||||||
|
if (!factory_.contains(protoName))
|
||||||
|
protoName = "hexdump";
|
||||||
|
|
||||||
|
return (*(factory_.value(protoName)))();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PdmlReader::freePdmlProtocol(PdmlDefaultProtocol *proto)
|
||||||
|
{
|
||||||
|
delete proto;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PdmlReader::isDontCareProto()
|
||||||
|
{
|
||||||
|
Q_ASSERT(isStartElement() && name() == "proto");
|
||||||
|
|
||||||
|
QString protoName = attributes().value("name").toString();
|
||||||
|
|
||||||
|
if (protoName.isEmpty() || (protoName == "expert"))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PdmlReader::readUnexpectedElement()
|
||||||
|
{
|
||||||
|
Q_ASSERT(isStartElement());
|
||||||
|
|
||||||
|
// XXX: add to 'log'
|
||||||
|
qDebug("unexpected element - <%s>; skipping ...",
|
||||||
|
name().toString().toAscii().constData());
|
||||||
|
while (!atEnd())
|
||||||
|
{
|
||||||
|
readNext();
|
||||||
|
if (isEndElement())
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (isStartElement())
|
||||||
|
readUnexpectedElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PdmlReader::skipElement()
|
||||||
|
{
|
||||||
|
Q_ASSERT(isStartElement());
|
||||||
|
|
||||||
|
// XXX: add to 'log'
|
||||||
|
qDebug("skipping element - <%s>",
|
||||||
|
name().toString().toAscii().constData());
|
||||||
|
while (!atEnd())
|
||||||
|
{
|
||||||
|
readNext();
|
||||||
|
if (isEndElement())
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (isStartElement())
|
||||||
|
skipElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PdmlReader::readPdml()
|
||||||
|
{
|
||||||
|
Q_ASSERT(isStartElement() && name() == "pdml");
|
||||||
|
|
||||||
|
packetCount_ = 0;
|
||||||
|
|
||||||
|
while (!atEnd())
|
||||||
|
{
|
||||||
|
readNext();
|
||||||
|
if (isEndElement())
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (isStartElement())
|
||||||
|
{
|
||||||
|
if (name() == "packet")
|
||||||
|
readPacket();
|
||||||
|
else
|
||||||
|
readUnexpectedElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PdmlReader::readPacket()
|
||||||
|
{
|
||||||
|
Q_ASSERT(isStartElement() && name() == "packet");
|
||||||
|
|
||||||
|
packetCount_++;
|
||||||
|
qDebug("packetNum = %d", packetCount_);
|
||||||
|
|
||||||
|
// XXX: For now, each packet is converted to a stream
|
||||||
|
currentStream_ = streams_->add_stream();
|
||||||
|
currentStream_->mutable_stream_id()->set_id(packetCount_);
|
||||||
|
currentStream_->mutable_core()->set_is_enabled(true);
|
||||||
|
|
||||||
|
while (!atEnd())
|
||||||
|
{
|
||||||
|
readNext();
|
||||||
|
|
||||||
|
if (isEndElement())
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (isStartElement())
|
||||||
|
{
|
||||||
|
if (name() == "proto")
|
||||||
|
readProto();
|
||||||
|
else if (name() == "field")
|
||||||
|
readField(NULL, NULL); // TODO: top level field!!!!
|
||||||
|
else
|
||||||
|
readUnexpectedElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PdmlReader::readProto()
|
||||||
|
{
|
||||||
|
PdmlDefaultProtocol *pdmlProto = NULL;
|
||||||
|
google::protobuf::Message *pbProto = NULL;
|
||||||
|
|
||||||
|
Q_ASSERT(isStartElement() && name() == "proto");
|
||||||
|
|
||||||
|
QString protoName = attributes().value("name").toString();
|
||||||
|
qDebug("proto: %s", protoName.toAscii().constData());
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (protoName.isEmpty() || (protoName == "expert"))
|
||||||
|
{
|
||||||
|
skipElement();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pdmlProto = allocPdmlProtocol(protoName);
|
||||||
|
Q_ASSERT(pdmlProto != NULL);
|
||||||
|
|
||||||
|
int protoId = pdmlProto->ostProtoId();
|
||||||
|
|
||||||
|
// Non PdmlDefaultProtocol
|
||||||
|
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 *fieldDesc =
|
||||||
|
msgRefl->FindKnownExtensionByNumber(protoId);
|
||||||
|
|
||||||
|
// TODO: if !fDesc
|
||||||
|
// init default values of all fields in protocol
|
||||||
|
pbProto = msgRefl->MutableMessage(proto, fieldDesc);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pdmlProto->preProtocolHandler(protoName, attributes(), currentStream_);
|
||||||
|
|
||||||
|
while (!atEnd())
|
||||||
|
{
|
||||||
|
readNext();
|
||||||
|
|
||||||
|
if (isEndElement())
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (isStartElement())
|
||||||
|
{
|
||||||
|
if (name() == "proto")
|
||||||
|
{
|
||||||
|
int endPos = -1;
|
||||||
|
// an embedded proto
|
||||||
|
qDebug("embedded proto: %s\n", attributes().value("name")
|
||||||
|
.toString().toAscii().constData());
|
||||||
|
if (isDontCareProto())
|
||||||
|
{
|
||||||
|
skipElement();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!attributes().value("pos").isEmpty())
|
||||||
|
endPos = attributes().value("pos").toString().toInt();
|
||||||
|
|
||||||
|
|
||||||
|
// pdmlProto may be NULL for a sequence of embedded protos
|
||||||
|
if (pdmlProto)
|
||||||
|
{
|
||||||
|
pdmlProto->prematureEndHandler(endPos, currentStream_);
|
||||||
|
pdmlProto->postProtocolHandler(currentStream_);
|
||||||
|
}
|
||||||
|
readProto();
|
||||||
|
pdmlProto = NULL;
|
||||||
|
pbProto = NULL;
|
||||||
|
}
|
||||||
|
else if (name() == "field")
|
||||||
|
{
|
||||||
|
if (pdmlProto == NULL)
|
||||||
|
{
|
||||||
|
pdmlProto = allocPdmlProtocol(protoName);
|
||||||
|
protoId = pdmlProto->ostProtoId();
|
||||||
|
|
||||||
|
// Non PdmlDefaultProtocol
|
||||||
|
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 *fieldDesc =
|
||||||
|
msgRefl->FindKnownExtensionByNumber(protoId);
|
||||||
|
|
||||||
|
// TODO: if !fDesc
|
||||||
|
// init default values of all fields in protocol
|
||||||
|
pbProto = msgRefl->MutableMessage(proto, fieldDesc);
|
||||||
|
|
||||||
|
}
|
||||||
|
pdmlProto->preProtocolHandler(protoName, attributes(), currentStream_);
|
||||||
|
}
|
||||||
|
readField(pdmlProto, pbProto);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
readUnexpectedElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pdmlProto)
|
||||||
|
{
|
||||||
|
pdmlProto->postProtocolHandler(currentStream_);
|
||||||
|
freePdmlProtocol(pdmlProto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PdmlReader::readField(PdmlDefaultProtocol *pdmlProto,
|
||||||
|
google::protobuf::Message *pbProto)
|
||||||
|
{
|
||||||
|
Q_ASSERT(isStartElement() && name() == "field");
|
||||||
|
|
||||||
|
// fields with "hide='yes'" are informational and should be skipped
|
||||||
|
if (attributes().value("hide") == "yes")
|
||||||
|
{
|
||||||
|
skipElement();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString fieldName = attributes().value("name").toString();
|
||||||
|
QString valueHexStr = attributes().value("value").toString();
|
||||||
|
int pos = -1;
|
||||||
|
int size = -1;
|
||||||
|
|
||||||
|
if (!attributes().value("pos").isEmpty())
|
||||||
|
pos = attributes().value("pos").toString().toInt();
|
||||||
|
if (!attributes().value("size").isEmpty())
|
||||||
|
size = attributes().value("size").toString().toInt();
|
||||||
|
|
||||||
|
qDebug("\tfieldName:%s, pos:%d, size:%d value:%s",
|
||||||
|
fieldName.toAscii().constData(),
|
||||||
|
pos,
|
||||||
|
size,
|
||||||
|
valueHexStr.toAscii().constData());
|
||||||
|
|
||||||
|
if (pdmlProto->hasField(fieldName))
|
||||||
|
{
|
||||||
|
int fieldId = pdmlProto->fieldId(fieldName);
|
||||||
|
const google::protobuf::Descriptor *msgDesc =
|
||||||
|
pbProto->GetDescriptor();
|
||||||
|
const google::protobuf::FieldDescriptor *fieldDesc =
|
||||||
|
msgDesc->FindFieldByNumber(fieldId);
|
||||||
|
const google::protobuf::Reflection *msgRefl =
|
||||||
|
pbProto->GetReflection();
|
||||||
|
|
||||||
|
bool isOk;
|
||||||
|
|
||||||
|
switch(fieldDesc->cpp_type())
|
||||||
|
{
|
||||||
|
case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: // TODO
|
||||||
|
case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
|
||||||
|
msgRefl->SetUInt32(pbProto, fieldDesc,
|
||||||
|
valueHexStr.toUInt(&isOk, kBaseHex));
|
||||||
|
break;
|
||||||
|
case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
|
||||||
|
msgRefl->SetUInt64(pbProto, fieldDesc,
|
||||||
|
valueHexStr.toULongLong(&isOk, kBaseHex));
|
||||||
|
break;
|
||||||
|
case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
|
||||||
|
{
|
||||||
|
QByteArray hexVal = QByteArray::fromHex(valueHexStr.toUtf8());
|
||||||
|
std::string str(hexVal.constData(), hexVal.size());
|
||||||
|
msgRefl->SetString(pbProto, fieldDesc, str);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
qDebug("%s: unhandled cpptype = %d", __FUNCTION__,
|
||||||
|
fieldDesc->cpp_type());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pdmlProto->unknownFieldHandler(fieldName, pos, size, attributes(),
|
||||||
|
currentStream_);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!atEnd())
|
||||||
|
{
|
||||||
|
readNext();
|
||||||
|
|
||||||
|
if (isEndElement())
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (isStartElement())
|
||||||
|
{
|
||||||
|
if (name() == "proto")
|
||||||
|
{
|
||||||
|
if (isDontCareProto())
|
||||||
|
{
|
||||||
|
skipElement();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
readProto();
|
||||||
|
}
|
||||||
|
else if (name() == "field")
|
||||||
|
readField(pdmlProto, pbProto);
|
||||||
|
else
|
||||||
|
readUnexpectedElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------- //
|
// ---------------------------------------------------------- //
|
||||||
@ -336,22 +733,27 @@ bool PdmlParser::fatalError(const QXmlParseException &exception)
|
|||||||
|
|
||||||
PdmlUnknownProtocol::PdmlUnknownProtocol()
|
PdmlUnknownProtocol::PdmlUnknownProtocol()
|
||||||
{
|
{
|
||||||
pdmlProtoName_ = "OST:HexDump";
|
pdmlProtoName_ = "";
|
||||||
ostProtoId_ = OstProto::Protocol::kHexDumpFieldNumber;
|
ostProtoId_ = OstProto::Protocol::kHexDumpFieldNumber;
|
||||||
|
|
||||||
endPos_ = expPos_ = -1;
|
endPos_ = expPos_ = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PdmlDefaultProtocol* PdmlUnknownProtocol::createInstance()
|
||||||
|
{
|
||||||
|
return new PdmlUnknownProtocol();
|
||||||
|
}
|
||||||
|
|
||||||
void PdmlUnknownProtocol::preProtocolHandler(QString name,
|
void PdmlUnknownProtocol::preProtocolHandler(QString name,
|
||||||
const QXmlAttributes &attributes, OstProto::Stream *stream)
|
const QXmlStreamAttributes &attributes, OstProto::Stream *stream)
|
||||||
{
|
{
|
||||||
bool isOk;
|
bool isOk;
|
||||||
int size;
|
int size;
|
||||||
int pos = attributes.value("pos").toUInt(&isOk);
|
int pos = attributes.value("pos").toString().toUInt(&isOk);
|
||||||
if (!isOk)
|
if (!isOk)
|
||||||
goto _skip_pos_size_proc;
|
goto _skip_pos_size_proc;
|
||||||
|
|
||||||
size = attributes.value("size").toUInt(&isOk);
|
size = attributes.value("size").toString().toUInt(&isOk);
|
||||||
if (!isOk)
|
if (!isOk)
|
||||||
goto _skip_pos_size_proc;
|
goto _skip_pos_size_proc;
|
||||||
|
|
||||||
@ -364,6 +766,11 @@ _skip_pos_size_proc:
|
|||||||
hexDump->set_pad_until_end(false);
|
hexDump->set_pad_until_end(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PdmlUnknownProtocol::prematureEndHandler(int pos, OstProto::Stream *stream)
|
||||||
|
{
|
||||||
|
endPos_ = pos;
|
||||||
|
}
|
||||||
|
|
||||||
void PdmlUnknownProtocol::postProtocolHandler(OstProto::Stream *stream)
|
void PdmlUnknownProtocol::postProtocolHandler(OstProto::Stream *stream)
|
||||||
{
|
{
|
||||||
OstProto::HexDump *hexDump = stream->mutable_protocol(
|
OstProto::HexDump *hexDump = stream->mutable_protocol(
|
||||||
@ -378,7 +785,7 @@ void PdmlUnknownProtocol::postProtocolHandler(OstProto::Stream *stream)
|
|||||||
expPos_ += hexVal.size();
|
expPos_ += hexVal.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug("%s: expPos_ = %d, endPos_ = %d\n", __FUNCTION__, expPos_, endPos_);
|
qDebug(" hexdump: expPos_ = %d, endPos_ = %d\n", expPos_, endPos_);
|
||||||
//Q_ASSERT(expPos_ == endPos_);
|
//Q_ASSERT(expPos_ == endPos_);
|
||||||
|
|
||||||
hexDump->set_pad_until_end(false);
|
hexDump->set_pad_until_end(false);
|
||||||
@ -386,13 +793,13 @@ void PdmlUnknownProtocol::postProtocolHandler(OstProto::Stream *stream)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PdmlUnknownProtocol::unknownFieldHandler(QString name, int pos, int size,
|
void PdmlUnknownProtocol::unknownFieldHandler(QString name, int pos, int size,
|
||||||
const QXmlAttributes &attributes, OstProto::Stream *stream)
|
const QXmlStreamAttributes &attributes, OstProto::Stream *stream)
|
||||||
{
|
{
|
||||||
OstProto::HexDump *hexDump = stream->mutable_protocol(
|
OstProto::HexDump *hexDump = stream->mutable_protocol(
|
||||||
stream->protocol_size()-1)->MutableExtension(OstProto::hexDump);
|
stream->protocol_size()-1)->MutableExtension(OstProto::hexDump);
|
||||||
|
|
||||||
qDebug("%s: %s, pos = %d, expPos_ = %d, endPos_ = %d\n",
|
qDebug(" hexdump: %s, pos = %d, expPos_ = %d, endPos_ = %d\n",
|
||||||
__PRETTY_FUNCTION__, name.toAscii().constData(),
|
name.toAscii().constData(),
|
||||||
pos, expPos_, endPos_);
|
pos, expPos_, endPos_);
|
||||||
|
|
||||||
// Skipped field? Pad with zero!
|
// Skipped field? Pad with zero!
|
||||||
@ -407,8 +814,8 @@ void PdmlUnknownProtocol::unknownFieldHandler(QString name, int pos, int size,
|
|||||||
if ((pos == expPos_) /*&& (pos < endPos_)*/)
|
if ((pos == expPos_) /*&& (pos < endPos_)*/)
|
||||||
{
|
{
|
||||||
QByteArray hexVal = attributes.value("unmaskedvalue").isEmpty() ?
|
QByteArray hexVal = attributes.value("unmaskedvalue").isEmpty() ?
|
||||||
QByteArray::fromHex(attributes.value("value").toUtf8()) :
|
QByteArray::fromHex(attributes.value("value").toString().toUtf8()) :
|
||||||
QByteArray::fromHex(attributes.value("unmaskedvalue").toUtf8());
|
QByteArray::fromHex(attributes.value("unmaskedvalue").toString().toUtf8());
|
||||||
|
|
||||||
hexDump->mutable_content()->append(hexVal.constData(), hexVal.size());
|
hexDump->mutable_content()->append(hexVal.constData(), hexVal.size());
|
||||||
expPos_ += hexVal.size();
|
expPos_ += hexVal.size();
|
||||||
@ -425,8 +832,13 @@ PdmlGenInfoProtocol::PdmlGenInfoProtocol()
|
|||||||
pdmlProtoName_ = "geninfo";
|
pdmlProtoName_ = "geninfo";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PdmlDefaultProtocol* PdmlGenInfoProtocol::createInstance()
|
||||||
|
{
|
||||||
|
return new PdmlGenInfoProtocol();
|
||||||
|
}
|
||||||
|
|
||||||
void PdmlGenInfoProtocol::unknownFieldHandler(QString name, int pos,
|
void PdmlGenInfoProtocol::unknownFieldHandler(QString name, int pos,
|
||||||
int size, const QXmlAttributes &attributes, OstProto::Stream *stream)
|
int size, const QXmlStreamAttributes &attributes, OstProto::Stream *stream)
|
||||||
{
|
{
|
||||||
stream->mutable_core()->set_frame_len(size+4); // TODO:check FCS
|
stream->mutable_core()->set_frame_len(size+4); // TODO:check FCS
|
||||||
}
|
}
|
||||||
@ -440,6 +852,11 @@ PdmlFrameProtocol::PdmlFrameProtocol()
|
|||||||
pdmlProtoName_ = "frame";
|
pdmlProtoName_ = "frame";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PdmlDefaultProtocol* PdmlFrameProtocol::createInstance()
|
||||||
|
{
|
||||||
|
return new PdmlFrameProtocol();
|
||||||
|
}
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
// ---------------------------------------------------------- //
|
// ---------------------------------------------------------- //
|
||||||
// PdmlFakeFieldWrapperProtocol //
|
// PdmlFakeFieldWrapperProtocol //
|
||||||
@ -453,8 +870,13 @@ PdmlFakeFieldWrapperProtocol::PdmlFakeFieldWrapperProtocol()
|
|||||||
expPos_ = -1;
|
expPos_ = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PdmlDefaultProtocol* PdmlFakeFieldWrapperProtocol::createInstance()
|
||||||
|
{
|
||||||
|
return new PdmlFakeFieldWrapperProtocol();
|
||||||
|
}
|
||||||
|
|
||||||
void PdmlFakeFieldWrapperProtocol::preProtocolHandler(QString name,
|
void PdmlFakeFieldWrapperProtocol::preProtocolHandler(QString name,
|
||||||
const QXmlAttributes &attributes, OstProto::Stream *stream)
|
const QXmlStreamAttributes &attributes, OstProto::Stream *stream)
|
||||||
{
|
{
|
||||||
expPos_ = 0;
|
expPos_ = 0;
|
||||||
OstProto::HexDump *hexDump = stream->mutable_protocol(
|
OstProto::HexDump *hexDump = stream->mutable_protocol(
|
||||||
@ -474,7 +896,7 @@ void PdmlFakeFieldWrapperProtocol::postProtocolHandler(OstProto::Stream *stream)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PdmlFakeFieldWrapperProtocol::unknownFieldHandler(QString name, int pos,
|
void PdmlFakeFieldWrapperProtocol::unknownFieldHandler(QString name, int pos,
|
||||||
int size, const QXmlAttributes &attributes, OstProto::Stream *stream)
|
int size, const QXmlStreamAttributes &attributes, OstProto::Stream *stream)
|
||||||
{
|
{
|
||||||
OstProto::HexDump *hexDump = stream->mutable_protocol(
|
OstProto::HexDump *hexDump = stream->mutable_protocol(
|
||||||
stream->protocol_size()-1)->MutableExtension(OstProto::hexDump);
|
stream->protocol_size()-1)->MutableExtension(OstProto::hexDump);
|
||||||
@ -484,8 +906,8 @@ void PdmlFakeFieldWrapperProtocol::unknownFieldHandler(QString name, int pos,
|
|||||||
!attributes.value("value").isEmpty()))
|
!attributes.value("value").isEmpty()))
|
||||||
{
|
{
|
||||||
QByteArray hexVal = attributes.value("unmaskedvalue").isEmpty() ?
|
QByteArray hexVal = attributes.value("unmaskedvalue").isEmpty() ?
|
||||||
QByteArray::fromHex(attributes.value("value").toUtf8()) :
|
QByteArray::fromHex(attributes.value("value").toString().toUtf8()) :
|
||||||
QByteArray::fromHex(attributes.value("unmaskedvalue").toUtf8());
|
QByteArray::fromHex(attributes.value("unmaskedvalue").toString().toUtf8());
|
||||||
|
|
||||||
hexDump->mutable_content()->append(hexVal.constData(), hexVal.size());
|
hexDump->mutable_content()->append(hexVal.constData(), hexVal.size());
|
||||||
expPos_ += hexVal.size();
|
expPos_ += hexVal.size();
|
||||||
@ -506,8 +928,13 @@ PdmlEthProtocol::PdmlEthProtocol()
|
|||||||
fieldMap_.insert("eth.src", OstProto::Mac::kSrcMacFieldNumber);
|
fieldMap_.insert("eth.src", OstProto::Mac::kSrcMacFieldNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PdmlDefaultProtocol* PdmlEthProtocol::createInstance()
|
||||||
|
{
|
||||||
|
return new PdmlEthProtocol();
|
||||||
|
}
|
||||||
|
|
||||||
void PdmlEthProtocol::unknownFieldHandler(QString name, int pos, int size,
|
void PdmlEthProtocol::unknownFieldHandler(QString name, int pos, int size,
|
||||||
const QXmlAttributes &attributes, OstProto::Stream *stream)
|
const QXmlStreamAttributes &attributes, OstProto::Stream *stream)
|
||||||
{
|
{
|
||||||
if (name == "eth.type")
|
if (name == "eth.type")
|
||||||
{
|
{
|
||||||
@ -519,7 +946,7 @@ void PdmlEthProtocol::unknownFieldHandler(QString name, int pos, int size,
|
|||||||
OstProto::Eth2 *eth2 = proto->MutableExtension(OstProto::eth2);
|
OstProto::Eth2 *eth2 = proto->MutableExtension(OstProto::eth2);
|
||||||
|
|
||||||
bool isOk;
|
bool isOk;
|
||||||
eth2->set_type(attributes.value("value").toUInt(&isOk, kBaseHex));
|
eth2->set_type(attributes.value("value").toString().toUInt(&isOk, kBaseHex));
|
||||||
eth2->set_is_override_type(true);
|
eth2->set_is_override_type(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -547,8 +974,13 @@ PdmlIp4Protocol::PdmlIp4Protocol()
|
|||||||
fieldMap_.insert("ip.dst", 18);
|
fieldMap_.insert("ip.dst", 18);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PdmlDefaultProtocol* PdmlIp4Protocol::createInstance()
|
||||||
|
{
|
||||||
|
return new PdmlIp4Protocol();
|
||||||
|
}
|
||||||
|
|
||||||
void PdmlIp4Protocol::unknownFieldHandler(QString name, int pos, int size,
|
void PdmlIp4Protocol::unknownFieldHandler(QString name, int pos, int size,
|
||||||
const QXmlAttributes &attributes, OstProto::Stream *stream)
|
const QXmlStreamAttributes &attributes, OstProto::Stream *stream)
|
||||||
{
|
{
|
||||||
bool isOk;
|
bool isOk;
|
||||||
|
|
||||||
@ -557,7 +989,7 @@ void PdmlIp4Protocol::unknownFieldHandler(QString name, int pos, int size,
|
|||||||
OstProto::Ip4 *ip4 = stream->mutable_protocol(
|
OstProto::Ip4 *ip4 = stream->mutable_protocol(
|
||||||
stream->protocol_size()-1)->MutableExtension(OstProto::ip4);
|
stream->protocol_size()-1)->MutableExtension(OstProto::ip4);
|
||||||
|
|
||||||
ip4->set_flags(attributes.value("value").toUInt(&isOk, kBaseHex) >> 5);
|
ip4->set_flags(attributes.value("value").toString().toUInt(&isOk, kBaseHex) >> 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -592,8 +1024,13 @@ PdmlIp6Protocol::PdmlIp6Protocol()
|
|||||||
// ipv6.src and ipv6.dst handled as unknown fields
|
// ipv6.src and ipv6.dst handled as unknown fields
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PdmlDefaultProtocol* PdmlIp6Protocol::createInstance()
|
||||||
|
{
|
||||||
|
return new PdmlIp6Protocol();
|
||||||
|
}
|
||||||
|
|
||||||
void PdmlIp6Protocol::unknownFieldHandler(QString name, int pos, int size,
|
void PdmlIp6Protocol::unknownFieldHandler(QString name, int pos, int size,
|
||||||
const QXmlAttributes &attributes, OstProto::Stream *stream)
|
const QXmlStreamAttributes &attributes, OstProto::Stream *stream)
|
||||||
{
|
{
|
||||||
bool isOk;
|
bool isOk;
|
||||||
|
|
||||||
@ -601,7 +1038,7 @@ void PdmlIp6Protocol::unknownFieldHandler(QString name, int pos, int size,
|
|||||||
{
|
{
|
||||||
OstProto::Ip6 *ip6 = stream->mutable_protocol(
|
OstProto::Ip6 *ip6 = stream->mutable_protocol(
|
||||||
stream->protocol_size()-1)->MutableExtension(OstProto::ip6);
|
stream->protocol_size()-1)->MutableExtension(OstProto::ip6);
|
||||||
QString addrHexStr = attributes.value("value");
|
QString addrHexStr = attributes.value("value").toString();
|
||||||
|
|
||||||
ip6->set_src_addr_hi(addrHexStr.left(16).toULongLong(&isOk, kBaseHex));
|
ip6->set_src_addr_hi(addrHexStr.left(16).toULongLong(&isOk, kBaseHex));
|
||||||
ip6->set_src_addr_lo(addrHexStr.right(16).toULongLong(&isOk, kBaseHex));
|
ip6->set_src_addr_lo(addrHexStr.right(16).toULongLong(&isOk, kBaseHex));
|
||||||
@ -610,7 +1047,7 @@ void PdmlIp6Protocol::unknownFieldHandler(QString name, int pos, int size,
|
|||||||
{
|
{
|
||||||
OstProto::Ip6 *ip6 = stream->mutable_protocol(
|
OstProto::Ip6 *ip6 = stream->mutable_protocol(
|
||||||
stream->protocol_size()-1)->MutableExtension(OstProto::ip6);
|
stream->protocol_size()-1)->MutableExtension(OstProto::ip6);
|
||||||
QString addrHexStr = attributes.value("value");
|
QString addrHexStr = attributes.value("value").toString();
|
||||||
|
|
||||||
ip6->set_dst_addr_hi(addrHexStr.left(16).toULongLong(&isOk, kBaseHex));
|
ip6->set_dst_addr_hi(addrHexStr.left(16).toULongLong(&isOk, kBaseHex));
|
||||||
ip6->set_dst_addr_lo(addrHexStr.right(16).toULongLong(&isOk, kBaseHex));
|
ip6->set_dst_addr_lo(addrHexStr.right(16).toULongLong(&isOk, kBaseHex));
|
||||||
@ -647,15 +1084,20 @@ PdmlTcpProtocol::PdmlTcpProtocol()
|
|||||||
fieldMap_.insert("tcp.urgent_pointer", OstProto::Tcp::kUrgPtrFieldNumber);
|
fieldMap_.insert("tcp.urgent_pointer", OstProto::Tcp::kUrgPtrFieldNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PdmlDefaultProtocol* PdmlTcpProtocol::createInstance()
|
||||||
|
{
|
||||||
|
return new PdmlTcpProtocol();
|
||||||
|
}
|
||||||
|
|
||||||
void PdmlTcpProtocol::unknownFieldHandler(QString name, int pos, int size,
|
void PdmlTcpProtocol::unknownFieldHandler(QString name, int pos, int size,
|
||||||
const QXmlAttributes &attributes, OstProto::Stream *stream)
|
const QXmlStreamAttributes &attributes, OstProto::Stream *stream)
|
||||||
{
|
{
|
||||||
if (name == "tcp.options")
|
if (name == "tcp.options")
|
||||||
options_ = QByteArray::fromHex(attributes.value("value").toUtf8());
|
options_ = QByteArray::fromHex(attributes.value("value").toString().toUtf8());
|
||||||
else if (name == ""
|
else if (name == ""
|
||||||
&& attributes.value("show").startsWith("TCP segment data"))
|
&& attributes.value("show").toString().startsWith("TCP segment data"))
|
||||||
{
|
{
|
||||||
segmentData_ = QByteArray::fromHex(attributes.value("value").toUtf8());
|
segmentData_ = QByteArray::fromHex(attributes.value("value").toString().toUtf8());
|
||||||
stream->mutable_core()->mutable_name()->append(segmentData_.constData(),
|
stream->mutable_core()->mutable_name()->append(segmentData_.constData(),
|
||||||
segmentData_.size());
|
segmentData_.size());
|
||||||
}
|
}
|
||||||
@ -666,6 +1108,8 @@ void PdmlTcpProtocol::postProtocolHandler(OstProto::Stream *stream)
|
|||||||
OstProto::Tcp *tcp = stream->mutable_protocol(
|
OstProto::Tcp *tcp = stream->mutable_protocol(
|
||||||
stream->protocol_size()-1)->MutableExtension(OstProto::tcp);
|
stream->protocol_size()-1)->MutableExtension(OstProto::tcp);
|
||||||
|
|
||||||
|
qDebug("Tcp: post\n");
|
||||||
|
|
||||||
tcp->set_is_override_src_port(true); // FIXME
|
tcp->set_is_override_src_port(true); // FIXME
|
||||||
tcp->set_is_override_dst_port(true); // FIXME
|
tcp->set_is_override_dst_port(true); // FIXME
|
||||||
tcp->set_is_override_hdrlen(true); // FIXME
|
tcp->set_is_override_hdrlen(true); // FIXME
|
||||||
|
@ -26,6 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QXmlDefaultHandler>
|
#include <QXmlDefaultHandler>
|
||||||
|
#include <QXmlStreamReader>
|
||||||
|
|
||||||
// TODO: add const where possible
|
// TODO: add const where possible
|
||||||
|
|
||||||
@ -35,19 +36,22 @@ class QXmlInputSource;
|
|||||||
class PdmlDefaultProtocol
|
class PdmlDefaultProtocol
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PdmlDefaultProtocol();
|
PdmlDefaultProtocol(); // TODO: make private
|
||||||
virtual ~PdmlDefaultProtocol();
|
virtual ~PdmlDefaultProtocol();
|
||||||
|
|
||||||
|
static PdmlDefaultProtocol* createInstance();
|
||||||
|
|
||||||
QString pdmlProtoName() const;
|
QString pdmlProtoName() const;
|
||||||
int ostProtoId() const;
|
int ostProtoId() const;
|
||||||
bool hasField(QString name) const;
|
bool hasField(QString name) const;
|
||||||
int fieldId(QString name) const;
|
int fieldId(QString name) const;
|
||||||
|
|
||||||
virtual void preProtocolHandler(QString name,
|
virtual void preProtocolHandler(QString name,
|
||||||
const QXmlAttributes &attributes, OstProto::Stream *stream);
|
const QXmlStreamAttributes &attributes, OstProto::Stream *stream);
|
||||||
|
virtual void prematureEndHandler(int pos, OstProto::Stream *stream);
|
||||||
virtual void postProtocolHandler(OstProto::Stream *stream);
|
virtual void postProtocolHandler(OstProto::Stream *stream);
|
||||||
virtual void unknownFieldHandler(QString name, int pos, int size,
|
virtual void unknownFieldHandler(QString name, int pos, int size,
|
||||||
const QXmlAttributes &attributes, OstProto::Stream *stream);
|
const QXmlStreamAttributes &attributes, OstProto::Stream *stream);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QString pdmlProtoName_; // TODO: needed? duplicated in protocolMap_
|
QString pdmlProtoName_; // TODO: needed? duplicated in protocolMap_
|
||||||
@ -55,6 +59,7 @@ protected:
|
|||||||
QMap<QString, int> fieldMap_;
|
QMap<QString, int> fieldMap_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
class PdmlParser : public QXmlDefaultHandler
|
class PdmlParser : public QXmlDefaultHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -83,17 +88,53 @@ private:
|
|||||||
OstProto::Stream *currentStream_;
|
OstProto::Stream *currentStream_;
|
||||||
google::protobuf::Message *currentProtocolMsg_;
|
google::protobuf::Message *currentProtocolMsg_;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class PdmlReader : public QXmlStreamReader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PdmlReader(OstProto::StreamConfigList *streams);
|
||||||
|
~PdmlReader();
|
||||||
|
|
||||||
|
bool read(QIODevice *device);
|
||||||
|
|
||||||
|
private:
|
||||||
|
PdmlDefaultProtocol* allocPdmlProtocol(QString protoName);
|
||||||
|
void freePdmlProtocol(PdmlDefaultProtocol *proto);
|
||||||
|
|
||||||
|
bool isDontCareProto();
|
||||||
|
void readPdml();
|
||||||
|
void skipElement();
|
||||||
|
void readUnexpectedElement();
|
||||||
|
void readPacket();
|
||||||
|
void readProto();
|
||||||
|
void readField(PdmlDefaultProtocol *pdmlProto,
|
||||||
|
google::protobuf::Message *pbProto);
|
||||||
|
|
||||||
|
typedef PdmlDefaultProtocol* (*FactoryMethod)();
|
||||||
|
QMap<QString, FactoryMethod> factory_;
|
||||||
|
|
||||||
|
OstProto::StreamConfigList *streams_;
|
||||||
|
|
||||||
|
int packetCount_;
|
||||||
|
OstProto::Stream *currentStream_;
|
||||||
|
//PdmlDefaultProtocol *currentPdmlProtocol_;
|
||||||
|
//google::protobuf::Message *currentProtocolMsg_;
|
||||||
|
};
|
||||||
|
|
||||||
class PdmlUnknownProtocol : public PdmlDefaultProtocol
|
class PdmlUnknownProtocol : public PdmlDefaultProtocol
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PdmlUnknownProtocol();
|
PdmlUnknownProtocol();
|
||||||
|
|
||||||
|
static PdmlDefaultProtocol* createInstance();
|
||||||
|
|
||||||
virtual void preProtocolHandler(QString name,
|
virtual void preProtocolHandler(QString name,
|
||||||
const QXmlAttributes &attributes, OstProto::Stream *stream);
|
const QXmlStreamAttributes &attributes, OstProto::Stream *stream);
|
||||||
|
virtual void prematureEndHandler(int pos, OstProto::Stream *stream);
|
||||||
virtual void postProtocolHandler(OstProto::Stream *stream);
|
virtual void postProtocolHandler(OstProto::Stream *stream);
|
||||||
virtual void unknownFieldHandler(QString name, int pos, int size,
|
virtual void unknownFieldHandler(QString name, int pos, int size,
|
||||||
const QXmlAttributes &attributes, OstProto::Stream *stream);
|
const QXmlStreamAttributes &attributes, OstProto::Stream *stream);
|
||||||
private:
|
private:
|
||||||
int endPos_;
|
int endPos_;
|
||||||
int expPos_;
|
int expPos_;
|
||||||
@ -104,14 +145,18 @@ class PdmlGenInfoProtocol : public PdmlDefaultProtocol
|
|||||||
public:
|
public:
|
||||||
PdmlGenInfoProtocol();
|
PdmlGenInfoProtocol();
|
||||||
|
|
||||||
|
static PdmlDefaultProtocol* createInstance();
|
||||||
|
|
||||||
virtual void unknownFieldHandler(QString name, int pos, int size,
|
virtual void unknownFieldHandler(QString name, int pos, int size,
|
||||||
const QXmlAttributes &attributes, OstProto::Stream *stream);
|
const QXmlStreamAttributes &attributes, OstProto::Stream *stream);
|
||||||
};
|
};
|
||||||
|
|
||||||
class PdmlFrameProtocol : public PdmlDefaultProtocol
|
class PdmlFrameProtocol : public PdmlDefaultProtocol
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PdmlFrameProtocol();
|
PdmlFrameProtocol();
|
||||||
|
|
||||||
|
static PdmlDefaultProtocol* createInstance();
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
@ -120,11 +165,13 @@ class PdmlFakeFieldWrapperProtocol : public PdmlDefaultProtocol
|
|||||||
public:
|
public:
|
||||||
PdmlFakeFieldWrapperProtocol();
|
PdmlFakeFieldWrapperProtocol();
|
||||||
|
|
||||||
|
static PdmlDefaultProtocol* createInstance();
|
||||||
|
|
||||||
virtual void preProtocolHandler(QString name,
|
virtual void preProtocolHandler(QString name,
|
||||||
const QXmlAttributes &attributes, OstProto::Stream *stream);
|
const QXmlStreamAttributes &attributes, OstProto::Stream *stream);
|
||||||
virtual void postProtocolHandler(OstProto::Stream *stream);
|
virtual void postProtocolHandler(OstProto::Stream *stream);
|
||||||
virtual void unknownFieldHandler(QString name, int pos, int size,
|
virtual void unknownFieldHandler(QString name, int pos, int size,
|
||||||
const QXmlAttributes &attributes, OstProto::Stream *stream);
|
const QXmlStreamAttributes &attributes, OstProto::Stream *stream);
|
||||||
private:
|
private:
|
||||||
int expPos_;
|
int expPos_;
|
||||||
};
|
};
|
||||||
@ -135,16 +182,21 @@ class PdmlEthProtocol : public PdmlDefaultProtocol
|
|||||||
public:
|
public:
|
||||||
PdmlEthProtocol();
|
PdmlEthProtocol();
|
||||||
|
|
||||||
|
static PdmlDefaultProtocol* createInstance();
|
||||||
|
|
||||||
virtual void unknownFieldHandler(QString name, int pos, int size,
|
virtual void unknownFieldHandler(QString name, int pos, int size,
|
||||||
const QXmlAttributes &attributes, OstProto::Stream *stream);
|
const QXmlStreamAttributes &attributes, OstProto::Stream *stream);
|
||||||
};
|
};
|
||||||
|
|
||||||
class PdmlIp4Protocol : public PdmlDefaultProtocol
|
class PdmlIp4Protocol : public PdmlDefaultProtocol
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PdmlIp4Protocol();
|
PdmlIp4Protocol();
|
||||||
|
|
||||||
|
static PdmlDefaultProtocol* createInstance();
|
||||||
|
|
||||||
virtual void unknownFieldHandler(QString name, int pos, int size,
|
virtual void unknownFieldHandler(QString name, int pos, int size,
|
||||||
const QXmlAttributes &attributes, OstProto::Stream *stream);
|
const QXmlStreamAttributes &attributes, OstProto::Stream *stream);
|
||||||
virtual void postProtocolHandler(OstProto::Stream *stream);
|
virtual void postProtocolHandler(OstProto::Stream *stream);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -152,8 +204,11 @@ class PdmlIp6Protocol : public PdmlDefaultProtocol
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PdmlIp6Protocol();
|
PdmlIp6Protocol();
|
||||||
|
|
||||||
|
static PdmlDefaultProtocol* createInstance();
|
||||||
|
|
||||||
virtual void unknownFieldHandler(QString name, int pos, int size,
|
virtual void unknownFieldHandler(QString name, int pos, int size,
|
||||||
const QXmlAttributes &attributes, OstProto::Stream *stream);
|
const QXmlStreamAttributes &attributes, OstProto::Stream *stream);
|
||||||
virtual void postProtocolHandler(OstProto::Stream *stream);
|
virtual void postProtocolHandler(OstProto::Stream *stream);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -161,8 +216,11 @@ class PdmlTcpProtocol : public PdmlDefaultProtocol
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PdmlTcpProtocol();
|
PdmlTcpProtocol();
|
||||||
|
|
||||||
|
static PdmlDefaultProtocol* createInstance();
|
||||||
|
|
||||||
virtual void unknownFieldHandler(QString name, int pos, int size,
|
virtual void unknownFieldHandler(QString name, int pos, int size,
|
||||||
const QXmlAttributes &attributes, OstProto::Stream *stream);
|
const QXmlStreamAttributes &attributes, OstProto::Stream *stream);
|
||||||
virtual void postProtocolHandler(OstProto::Stream *stream);
|
virtual void postProtocolHandler(OstProto::Stream *stream);
|
||||||
private:
|
private:
|
||||||
QByteArray options_;
|
QByteArray options_;
|
||||||
|
@ -30,6 +30,7 @@ PdmlFileFormat::~PdmlFileFormat()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
bool PdmlFileFormat::openStreams(const QString fileName,
|
bool PdmlFileFormat::openStreams(const QString fileName,
|
||||||
OstProto::StreamConfigList &streams, QString &error)
|
OstProto::StreamConfigList &streams, QString &error)
|
||||||
{
|
{
|
||||||
@ -61,6 +62,32 @@ _exit:
|
|||||||
|
|
||||||
return isOk;
|
return isOk;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
bool PdmlFileFormat::openStreams(const QString fileName,
|
||||||
|
OstProto::StreamConfigList &streams, QString &error)
|
||||||
|
{
|
||||||
|
bool isOk = false;
|
||||||
|
QFile file(fileName);
|
||||||
|
PdmlReader *reader = new PdmlReader(&streams);
|
||||||
|
|
||||||
|
if (!file.open(QIODevice::ReadOnly))
|
||||||
|
goto _open_fail;
|
||||||
|
|
||||||
|
// TODO: fill in error string
|
||||||
|
|
||||||
|
isOk = reader->read(&file);
|
||||||
|
|
||||||
|
goto _exit;
|
||||||
|
|
||||||
|
_open_fail:
|
||||||
|
isOk = false;
|
||||||
|
|
||||||
|
_exit:
|
||||||
|
delete reader;
|
||||||
|
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool PdmlFileFormat::saveStreams(const OstProto::StreamConfigList streams,
|
bool PdmlFileFormat::saveStreams(const OstProto::StreamConfigList streams,
|
||||||
const QString fileName, QString &error)
|
const QString fileName, QString &error)
|
||||||
|
Loading…
Reference in New Issue
Block a user