diff --git a/common/abstractprotocolconfig.h b/common/abstractprotocolconfig.h
index a65c959..3e87aeb 100644
--- a/common/abstractprotocolconfig.h
+++ b/common/abstractprotocolconfig.h
@@ -63,7 +63,8 @@ public:
/*!
Loads data from the protocol using it's fieldData() method into this
- widget
+ widget. Any conversion to user friendly display/editing formats (e.g.
+ hex format) SHOULD be done by this method.
Subclasses MUST implement this function. See the SampleProtocol for
an example
@@ -75,7 +76,9 @@ public:
/*!
Stores data from this widget into the protocol using the protocol's
- setFieldData() method
+ setFieldData() method. Field values MUST be converted from any
+ user friendly display/editing formats (e.g. hex format) to simple
+ Qt-style integers/strings before passing to setFieldData()
Subclasses MUST implement this function. See the SampleProtocol for
an example
diff --git a/common/ostprotogui.pro b/common/ostprotogui.pro
index 0bf1c3f..b075046 100644
--- a/common/ostprotogui.pro
+++ b/common/ostprotogui.pro
@@ -121,7 +121,8 @@ SOURCES += \
mldpdml.cpp \
tcppdml.cpp \
udppdml.cpp \
- textprotopdml.cpp
+ textprotopdml.cpp \
+ samplepdml.cpp
QMAKE_DISTCLEAN += object_script.*
diff --git a/common/pdmlprotocol.cpp b/common/pdmlprotocol.cpp
index 2be78ab..a682aeb 100644
--- a/common/pdmlprotocol.cpp
+++ b/common/pdmlprotocol.cpp
@@ -19,35 +19,97 @@ along with this program. If not, see
#include "pdmlprotocol.h"
+/*!
+ \class PdmlProtocol
+
+ PdmlProtocol is the base class which provides the interface for all
+ PDML decode helper protocols
+
+ All Pdml helper classes derived from PdmlProtocol MUST register
+ themselves with PdmlReader. When PdmlReader encounters a 'proto' tag
+ in the PDML during parsing, it instantiates the corresponding helper
+ PdmlProtocol class and calls its methods to decode the protocol.
+
+ A subclass MUST initialize the following inherited protected variables
+ in its constructor -
+ - ostProtoId_
+ - fieldMap_
+
+ A subclass typically needs to reimplement the following methods -
+ - createInstance()
+
+ Depending on certain conditions, subclasses may need to reimplement
+ the following additional methods -
+ - unknownFieldHandler()
+ - preProtocolHandler()
+ - postProtocolHandler()
+
+ See the description of the methods for more information.
+
+ Use the SamplePdmlProtocol implementation as boilerplate code and
+ for guidelines and tips
+*/
+
+/*!
+ Constructs the PdmlProtocol
+*/
PdmlProtocol::PdmlProtocol()
{
ostProtoId_ = -1;
}
+/*!
+ Destroys the PdmlProtocol
+*/
PdmlProtocol::~PdmlProtocol()
{
}
+/*!
+ Allocates and returns a new instance of the class
+
+ Caller is responsible for freeing up after use. Subclasses MUST implement
+ this function and register it with PdmlReader
+*/
PdmlProtocol* PdmlProtocol::createInstance()
{
return new PdmlProtocol();
}
+/*!
+ Returns the protocol's field number as defined in message 'Protocol', enum 'k'
+ (file: protocol.proto)
+*/
int PdmlProtocol::ostProtoId() const
{
return ostProtoId_;
}
+/*!
+ Returns true if name is a 'known' field that can be directly mapped
+ to the protobuf field
+*/
bool PdmlProtocol::hasField(QString name) const
{
return fieldMap_.contains(name);
}
+/*!
+ Returns the protocol's protobuf field number corresponding to name
+*/
int PdmlProtocol::fieldId(QString name) const
{
return fieldMap_.value(name);
}
+/*!
+ This method is called by PdmlReader before any fields within the protocol
+ are processed. All attributes associated with the 'proto' tag in the PDML
+ are passed to this method
+
+ Use this method to do any special handling that may be required for
+ preprocessing
+*/
void PdmlProtocol::preProtocolHandler(QString /*name*/,
const QXmlStreamAttributes& /*attributes*/,
int /*expectedPos*/, OstProto::Protocol* /*pbProto*/,
@@ -56,18 +118,41 @@ void PdmlProtocol::preProtocolHandler(QString /*name*/,
return; // do nothing!
}
+/*!
+ This method is called by PdmlReader when it encounters a nested
+ protocol in the PDML i.e. a protocol within a protocol or a protocol
+ within a field
+
+ This is a notification to the protocol that protocol processing will
+ be ending prematurely. postProtocolHandler() will still be called in
+ such cases.
+*/
void PdmlProtocol::prematureEndHandler(int /*pos*/,
OstProto::Protocol* /*pbProto*/, OstProto::Stream* /*stream*/)
{
return; // do nothing!
}
+/*!
+ This method is called by PdmlReader after all fields within the protocol
+ are processed.
+
+ Use this method to do any special handling that may be required for
+ postprocessing
+*/
void PdmlProtocol::postProtocolHandler(OstProto::Protocol* /*pbProto*/,
OstProto::Stream* /*stream*/)
{
return; // do nothing!
}
+
+/*!
+ This method is called by PdmlReader for each field in the protocol
+
+ Depending on whether it is a known or unknown field, the virtual methods
+ knownFieldHandler() and unknownFieldHandler() are invoked
+*/
void PdmlProtocol::fieldHandler(QString name,
const QXmlStreamAttributes &attributes,
OstProto::Protocol *pbProto, OstProto::Stream *stream)
@@ -99,6 +184,12 @@ void PdmlProtocol::fieldHandler(QString name,
}
}
+/*!
+ Handles a 'known' field
+
+ Uses protobuf reflection interface to set the protobuf field name to
+ valueHexStr as per the field's datatype
+*/
void PdmlProtocol::knownFieldHandler(QString name, QString valueHexStr,
OstProto::Protocol *pbProto)
{
@@ -143,6 +234,12 @@ void PdmlProtocol::knownFieldHandler(QString name, QString valueHexStr,
}
}
+/*!
+ Handles a 'unknown' field
+
+ The default implementation does nothing. Subclasses may need to implement
+ this if the protocol contains 'unknown' fields.
+*/
void PdmlProtocol::unknownFieldHandler(QString /*name*/,
int /*pos*/, int /*size*/, const QXmlStreamAttributes& /*attributes*/,
OstProto::Protocol* /*pbProto*/, OstProto::Stream* /*stream*/)
diff --git a/common/pdmlprotocol.h b/common/pdmlprotocol.h
index 7f23524..011fcb6 100644
--- a/common/pdmlprotocol.h
+++ b/common/pdmlprotocol.h
@@ -59,7 +59,9 @@ public:
protected:
PdmlProtocol();
+ //!< Protocol's field number as defined in message 'Protocol', enum 'k'
int ostProtoId_;
+ //!< Map of PDML field names to protobuf field numbers for 'known' fields
QMap fieldMap_;
};
diff --git a/common/samplepdml.cpp b/common/samplepdml.cpp
new file mode 100644
index 0000000..99b671b
--- /dev/null
+++ b/common/samplepdml.cpp
@@ -0,0 +1,118 @@
+/*
+Copyright (C) 2014 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
+*/
+
+#include "samplepdml.h"
+
+#include "sample.pb.h"
+
+/*!
+ TODO : Initialize the following inherited protected members -
+ - ostProtoId_
+ - fieldMap_
+
+ ostProtoId_ is the protocol's protobuf field number as defined in
+ message 'Protocol' enum 'k' in file protocol.proto
+
+ fieldMap_ is a mapping of the protocol's field names as they appear
+ in the PDML to the protobuf field numbers for the protocol. All such
+ fields are classified as 'known' fields and the base class will take care
+ of decoding these without any help from the subclass.
+
+ Note that the PDML field names are same as the field names used in Wireshark
+ display filters. The full reference for these is available at -
+ http://www.wireshark.org/docs/dfref/
+*/
+PdmlSampleProtocol::PdmlSampleProtocol()
+{
+ ostProtoId_ = OstProto::Protocol::kSampleFieldNumber;
+
+ fieldMap_.insert("sample.checksum", OstProto::Sample::kChecksumFieldNumber);
+ fieldMap_.insert("sample.x", OstProto::Sample::kXFieldNumber);
+ fieldMap_.insert("sample.y", OstProto::Sample::kYFieldNumber);
+}
+
+PdmlSampleProtocol::~PdmlSampleProtocol()
+{
+}
+
+PdmlSampleProtocol* PdmlSampleProtocol::createInstance()
+{
+ return new PdmlSampleProtocol();
+}
+
+/*!
+ TODO: Use this method to do any special handling that may be required for
+ preprocessing a protocol before parsing/decoding the protocol's fields
+*/
+void PdmlSampleProtocol::preProtocolHandler(QString /*name*/,
+ const QXmlStreamAttributes& /*attributes*/,
+ int /*expectedPos*/, OstProto::Protocol* /*pbProto*/,
+ OstProto::Stream* /*stream*/)
+{
+ return;
+}
+
+/*!
+ TODO: Use this method to do any special handling or cleanup that may be
+ required when a protocol decode is ending prematurely
+*/
+void PdmlSampleProtocol::prematureEndHandler(int /*pos*/,
+ OstProto::Protocol* /*pbProto*/, OstProto::Stream* /*stream*/)
+{
+ return;
+}
+
+/*!
+ TODO: Use this method to do any special handling that may be required for
+ postprocessing a protocol after parsing/decoding all the protocol fields
+
+ If your protocol's protobuf has some meta-fields that should be set to
+ their non default values, this is a good place to do that. e.g. derived
+ fields such as length, checksum etc. may be correct or incorrect in the
+ PCAP/PDML - to retain the same value as in the PCAP/PDML and not let
+ Ostinato recalculate these, you can set the is_override_length,
+ is_override_cksum meta-fields to true here
+*/
+void PdmlSampleProtocol::postProtocolHandler(OstProto::Protocol* /*pbProto*/,
+ OstProto::Stream* /*stream*/)
+{
+ return;
+}
+
+/*!
+ TODO: Handle all 'unknown' fields using this method
+
+ You need to typically only handle frame fields or fields actually present
+ in the protocol on the wire. So you can safely ignore meta-fields such as
+ Good/Bad Checksum.
+
+ Some fields may not have a 'name' attribute, so cannot be classified as
+ a 'known' field. Use this method to identify such fields using other
+ attributes such as 'show' or 'showname' and populate the corresponding
+ protobuf field.
+
+ If the PDML protocol contains some fields that are not supported by Ostinato,
+ use a HexDump protocol as a replacement to store these bytes
+*/
+void PdmlSampleProtocol::unknownFieldHandler(QString /*name*/,
+ int /*pos*/, int /*size*/, const QXmlStreamAttributes& /*attributes*/,
+ OstProto::Protocol* /*pbProto*/, OstProto::Stream* /*stream*/)
+{
+ return;
+}
diff --git a/common/samplepdml.h b/common/samplepdml.h
new file mode 100644
index 0000000..a07965b
--- /dev/null
+++ b/common/samplepdml.h
@@ -0,0 +1,50 @@
+/*
+Copyright (C) 2014 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
+*/
+
+#ifndef _SAMPLE_PDML_H
+#define _SAMPLE_PDML_H
+
+#include "pdmlprotocol.h"
+
+class PdmlSampleProtocol : public PdmlProtocol
+{
+public:
+ virtual ~PdmlSampleProtocol();
+
+ static PdmlSampleProtocol* createInstance();
+
+ virtual void preProtocolHandler(QString name,
+ const QXmlStreamAttributes &attributes, int expectedPos,
+ OstProto::Protocol *pbProto, OstProto::Stream *stream);
+ virtual void prematureEndHandler(int pos, OstProto::Protocol *pbProto,
+ OstProto::Stream *stream);
+ virtual void postProtocolHandler(OstProto::Protocol *pbProto,
+ OstProto::Stream *stream);
+
+ void fieldHandler(QString name, const QXmlStreamAttributes &attributes,
+ OstProto::Protocol *pbProto, OstProto::Stream *stream);
+ virtual void unknownFieldHandler(QString name, int pos, int size,
+ const QXmlStreamAttributes &attributes,
+ OstProto::Protocol *pbProto, OstProto::Stream *stream);
+
+protected:
+ PdmlSampleProtocol();
+};
+
+#endif