Add GRE protocol

This commit is contained in:
Srivats P 2021-01-09 13:15:26 +05:30
parent bcc21ccded
commit 73dd198069
14 changed files with 1110 additions and 0 deletions

463
common/gre.cpp Normal file
View File

@ -0,0 +1,463 @@
/*
Copyright (C) 2021 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 "gre.h"
GreProtocol::GreProtocol(StreamBase *stream, AbstractProtocol *parent)
: AbstractProtocol(stream, parent)
{
}
GreProtocol::~GreProtocol()
{
}
AbstractProtocol* GreProtocol::createInstance(StreamBase *stream,
AbstractProtocol *parent)
{
return new GreProtocol(stream, parent);
}
quint32 GreProtocol::protocolNumber() const
{
return OstProto::Protocol::kGreFieldNumber;
}
void GreProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const
{
protocol.MutableExtension(OstProto::gre)->CopyFrom(data);
protocol.mutable_protocol_id()->set_id(protocolNumber());
}
void GreProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol)
{
if (protocol.protocol_id().id() == protocolNumber() &&
protocol.HasExtension(OstProto::gre))
data.MergeFrom(protocol.GetExtension(OstProto::gre));
}
QString GreProtocol::name() const
{
return QString("General Routing Encapsulation Protocol");
}
QString GreProtocol::shortName() const
{
return QString("GRE");
}
AbstractProtocol::ProtocolIdType GreProtocol::protocolIdType() const
{
return ProtocolIdEth;
}
quint32 GreProtocol::protocolId(ProtocolIdType type) const
{
switch(type)
{
case ProtocolIdIp: return 47;
default:break;
}
return AbstractProtocol::protocolId(type);
}
int GreProtocol::fieldCount() const
{
return gre_fieldCount;
}
/*!
TODO Return the number of frame fields for your protocol. A frame field
is a field which has the FrameField flag set \n
If your protocol has different sets of fields based on a OpCode/Type field
(e.g. icmp), you MUST re-implement this function; however, if your protocol
has a fixed set of frame fields always, you don't need to reimplement this
method - the base class implementation will do the right thing
*/
int GreProtocol::frameFieldCount() const
{
int count = 4; // mandatory fields - flags, rsvd0, version, protocol
if (data.flags() & GRE_FLAG_CKSUM)
count += 2; // checksum, rsvd1
if (data.flags() & GRE_FLAG_KEY)
count++;
if (data.flags() & GRE_FLAG_SEQ)
count++;
return count;
}
AbstractProtocol::FieldFlags GreProtocol::fieldFlags(int index) const
{
AbstractProtocol::FieldFlags flags;
flags = AbstractProtocol::fieldFlags(index);
if (index == gre_checksum)
flags |= CksumField;
return flags;
}
/*!
TODO: Edit this function to return the data for each field
See AbstractProtocol::fieldData() for more info
*/
QVariant GreProtocol::fieldData(int index, FieldAttrib attrib,
int streamIndex) const
{
switch (index)
{
case gre_flags:
{
switch(attrib)
{
case FieldName:
return QString("Flags");
case FieldValue:
return data.flags();
case FieldTextValue:
{
QString fstr;
fstr.append("Cksum:");
fstr.append(data.flags() & GRE_FLAG_CKSUM ? "Y" : "N");
fstr.append(" Key:");
fstr.append(data.flags() & GRE_FLAG_KEY ? "Y" : "N");
fstr.append(" Seq:");
fstr.append(data.flags() & GRE_FLAG_SEQ ? "Y" : "N");
return fstr;
}
case FieldFrameValue:
return QByteArray(1, char(data.flags()));
case FieldBitSize:
return 4;
default:
break;
}
break;
}
case gre_rsvd0:
{
switch(attrib)
{
case FieldName:
return QString("Reserved0");
case FieldValue:
return data.rsvd0();
case FieldTextValue:
return QString("%1").arg(data.rsvd0());
case FieldFrameValue:
{
QByteArray fv;
fv.resize(2);
qToBigEndian(quint16(data.rsvd0()), (uchar*)fv.data());
return fv;
}
case FieldBitSize:
return 9;
default:
break;
}
break;
}
case gre_version:
{
switch(attrib)
{
case FieldName:
return QString("Version");
case FieldValue:
return data.version();
case FieldFrameValue:
return QByteArray(1, char(data.version()));
case FieldTextValue:
return QString("%1").arg(data.version());
case FieldBitSize:
return 3;
default:
break;
}
break;
}
case gre_protocol:
{
quint16 protocol = payloadProtocolId(ProtocolIdEth);
switch(attrib)
{
case FieldName:
return QString("Protocol");
case FieldValue:
return protocol;
case FieldFrameValue:
{
QByteArray fv;
fv.resize(2);
qToBigEndian(protocol, (uchar*) fv.data());
return fv;
}
case FieldTextValue:
return QString("0x%1").arg(
protocol, 4, BASE_HEX, QChar('0'));;
default:
break;
}
break;
}
case gre_checksum:
{
if ((data.flags() & GRE_FLAG_CKSUM) == 0)
return QVariant();
switch(attrib)
{
case FieldName:
return QString("Checksum");
case FieldBitSize:
return 16;
default:
break;
}
quint16 cksum = 0;
if (data.flags() & GRE_FLAG_CKSUM) {
quint32 sum = 0;
cksum = protocolFrameCksum(streamIndex, CksumIp);
sum += (quint16) ~cksum;
cksum = protocolFramePayloadCksum(streamIndex, CksumIp);
sum += (quint16) ~cksum;
while (sum >> 16)
sum = (sum & 0xFFFF) + (sum >> 16);
cksum = (~sum) & 0xFFFF;
}
switch(attrib)
{
case FieldValue:
return cksum;
case FieldFrameValue:
{
QByteArray fv;
fv.resize(2);
qToBigEndian(cksum, (uchar*) fv.data());
return fv;
}
case FieldTextValue:
return QString("0x%1").arg(
cksum, 4, BASE_HEX, QChar('0'));;
default:
break;
}
break;
}
case gre_rsvd1:
{
if ((data.flags() & GRE_FLAG_CKSUM) == 0)
return QVariant();
switch(attrib)
{
case FieldName:
return QString("Reserved1");
case FieldValue:
return data.rsvd1();
case FieldTextValue:
return QString("%1").arg(data.rsvd1());
case FieldFrameValue:
{
QByteArray fv;
fv.resize(2);
qToBigEndian((quint16) data.rsvd1(), (uchar*) fv.data());
return fv;
}
default:
break;
}
break;
}
case gre_key:
{
if ((data.flags() & GRE_FLAG_KEY) == 0)
return QVariant();
switch(attrib)
{
case FieldName:
return QString("Key");
case FieldValue:
return data.key();
case FieldTextValue:
return QString("0x%1").arg(data.key(), 8, BASE_HEX, QChar('0'));
case FieldFrameValue:
{
QByteArray fv;
fv.resize(4);
qToBigEndian((quint32) data.key(), (uchar*) fv.data());
return fv;
}
default:
break;
}
break;
}
case gre_sequence:
{
if ((data.flags() & GRE_FLAG_SEQ) == 0)
return QVariant();
switch(attrib)
{
case FieldName:
return QString("Sequence Number");
case FieldValue:
return data.sequence_num();
case FieldTextValue:
return QString("%1").arg(data.sequence_num());
case FieldFrameValue:
{
QByteArray fv;
fv.resize(4);
qToBigEndian((quint32) data.sequence_num(), (uchar*) fv.data());
return fv;
}
default:
break;
}
break;
}
default:
qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__,
index);
break;
}
return AbstractProtocol::fieldData(index, attrib, streamIndex);
}
/*!
TODO: Edit this function to set the data for each field
See AbstractProtocol::setFieldData() for more info
*/
bool GreProtocol::setFieldData(int index, const QVariant &value,
FieldAttrib attrib)
{
bool isOk = false;
if (attrib != FieldValue)
goto _exit;
switch (index)
{
case gre_flags:
{
uint flags = value.toUInt(&isOk);
if (isOk)
data.set_flags(flags);
break;
}
case gre_rsvd0:
{
uint rsvd0 = value.toUInt(&isOk);
if (isOk)
data.set_rsvd0(rsvd0);
break;
}
case gre_version:
{
uint ver = value.toUInt(&isOk);
if (isOk)
data.set_version(ver);
break;
}
case gre_protocol:
{
uint proto = value.toUInt(&isOk);
if (isOk)
data.set_protocol_type(proto);
break;
}
case gre_checksum:
{
uint csum = value.toUInt(&isOk);
if (isOk)
data.set_checksum(csum);
break;
}
case gre_rsvd1:
{
uint rsvd1 = value.toUInt(&isOk);
if (isOk)
data.set_rsvd1(rsvd1);
break;
}
case gre_key:
{
uint key = value.toUInt(&isOk);
if (isOk)
data.set_key(key);
break;
}
case gre_sequence:
{
uint seq = value.toUInt(&isOk);
if (isOk)
data.set_sequence_num(seq);
break;
}
default:
qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__,
index);
break;
}
_exit:
return isOk;
}
/*!
TODO: Return the protocol frame size in bytes\n
If your protocol has a fixed size - you don't need to reimplement this; the
base class implementation is good enough
*/
int GreProtocol::protocolFrameSize(int /*streamIndex*/) const
{
int size = 4; // mandatory fields - flags, rsvd0, version, protocol
if (data.flags() & GRE_FLAG_CKSUM)
size += 4;
if (data.flags() & GRE_FLAG_KEY)
size += 4;
if (data.flags() & GRE_FLAG_SEQ)
size += 4;
return size;
}

95
common/gre.h Normal file
View File

@ -0,0 +1,95 @@
/*
Copyright (C) 2021 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 _GRE_H
#define _GRE_H
#include "abstractprotocol.h"
#include "gre.pb.h"
/*
GRE Protocol Frame Format (RFC2890)-
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|C| |K|S| Reserved0 | Ver | Protocol Type |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum (optional) | Reserved1 (Optional) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Key (optional) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number (Optional) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figures in brackets represent field width in bits
*/
#define GRE_FLAG_CKSUM 0x8
#define GRE_FLAG_KEY 0x2
#define GRE_FLAG_SEQ 0x1
class GreProtocol : public AbstractProtocol
{
public:
enum grefield
{
// Frame Fields
gre_flags = 0,
gre_rsvd0,
gre_version,
gre_protocol,
gre_checksum,
gre_rsvd1,
gre_key,
gre_sequence,
gre_fieldCount
};
GreProtocol(StreamBase *stream, AbstractProtocol *parent = 0);
virtual ~GreProtocol();
static AbstractProtocol* createInstance(StreamBase *stream,
AbstractProtocol *parent = 0);
virtual quint32 protocolNumber() const;
virtual void protoDataCopyInto(OstProto::Protocol &protocol) const;
virtual void protoDataCopyFrom(const OstProto::Protocol &protocol);
virtual ProtocolIdType protocolIdType() const;
virtual quint32 protocolId(ProtocolIdType type) const;
virtual QString name() const;
virtual QString shortName() const;
virtual int fieldCount() const;
virtual int frameFieldCount() const;
virtual AbstractProtocol::FieldFlags fieldFlags(int index) const;
virtual QVariant fieldData(int index, FieldAttrib attrib,
int streamIndex = 0) const;
virtual bool setFieldData(int index, const QVariant &value,
FieldAttrib attrib = FieldValue);
virtual int protocolFrameSize(int streamIndex = 0) const;
private:
OstProto::Gre data;
};
#endif

38
common/gre.proto Normal file
View File

@ -0,0 +1,38 @@
/*
Copyright (C) 2021 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/>
*/
import "protocol.proto";
package OstProto;
// GRE Protocol
message Gre {
optional uint32 flags = 1 [default = 0xa];
optional uint32 rsvd0 = 2;
optional uint32 version = 3;
optional uint32 protocol_type = 4;
optional uint32 checksum = 5;
optional uint32 rsvd1 = 6;
optional uint32 key = 7 [default = 0x2020bad7];
optional uint32 sequence_num = 8;
}
extend Protocol {
optional Gre gre = 405;
}

172
common/gre.ui Normal file
View File

@ -0,0 +1,172 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Gre</class>
<widget class="QWidget" name="Gre">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>264</width>
<height>140</height>
</rect>
</property>
<property name="windowTitle">
<string>Gre</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Version</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="version">
<property name="specialValueText">
<string>0 (RFC2784)</string>
</property>
<property name="maximum">
<number>7</number>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="hasChecksum">
<property name="text">
<string>Checksum</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="IntEdit" name="checksum">
<property name="enabled">
<bool>false</bool>
</property>
<property name="specialValueText">
<string>&lt;auto&gt;</string>
</property>
<property name="prefix">
<string>0x</string>
</property>
<property name="maximum">
<number>65535</number>
</property>
<property name="displayIntegerBase">
<number>16</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="hasKey">
<property name="text">
<string>Key</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="IntEdit" name="key">
<property name="enabled">
<bool>false</bool>
</property>
<property name="prefix">
<string>0x</string>
</property>
<property name="displayIntegerBase">
<number>16</number>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="hasSequence">
<property name="text">
<string>Sequence No</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="IntEdit" name="sequence">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="4" column="1">
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>IntEdit</class>
<extends>QSpinBox</extends>
<header>intedit.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>hasChecksum</tabstop>
<tabstop>checksum</tabstop>
<tabstop>hasKey</tabstop>
<tabstop>key</tabstop>
<tabstop>hasSequence</tabstop>
<tabstop>sequence</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>hasKey</sender>
<signal>toggled(bool)</signal>
<receiver>key</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>32</x>
<y>69</y>
</hint>
<hint type="destinationlabel">
<x>107</x>
<y>71</y>
</hint>
</hints>
</connection>
<connection>
<sender>hasSequence</sender>
<signal>toggled(bool)</signal>
<receiver>sequence</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>75</x>
<y>99</y>
</hint>
<hint type="destinationlabel">
<x>125</x>
<y>97</y>
</hint>
</hints>
</connection>
</connections>
</ui>

105
common/greconfig.cpp Normal file
View File

@ -0,0 +1,105 @@
/*
Copyright (C) 2021 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 "greconfig.h"
#include "gre.h"
GreConfigForm::GreConfigForm(QWidget *parent)
: AbstractProtocolConfigForm(parent)
{
setupUi(this);
}
GreConfigForm::~GreConfigForm()
{
}
GreConfigForm* GreConfigForm::createInstance()
{
return new GreConfigForm;
}
// Load widget contents from proto
void GreConfigForm::loadWidget(AbstractProtocol *proto)
{
uint flags = proto->fieldData(GreProtocol::gre_flags,
AbstractProtocol::FieldValue)
.toUInt();
version->setValue(
proto->fieldData(
GreProtocol::gre_version,
AbstractProtocol::FieldValue
).toUInt());
hasChecksum->setChecked(flags & GRE_FLAG_CKSUM);
checksum->setValue(
proto->fieldData(
GreProtocol::gre_checksum,
AbstractProtocol::FieldValue
).toUInt());
hasKey->setChecked(flags & GRE_FLAG_KEY);
key->setValue(
proto->fieldData(
GreProtocol::gre_key,
AbstractProtocol::FieldValue
).toUInt());
hasSequence->setChecked(flags & GRE_FLAG_SEQ);
sequence->setValue(
proto->fieldData(
GreProtocol::gre_sequence,
AbstractProtocol::FieldValue
).toUInt());
}
// Store widget contents into proto
void GreConfigForm::storeWidget(AbstractProtocol *proto)
{
uint flags = 0;
if (hasChecksum->isChecked())
flags |= GRE_FLAG_CKSUM;
if (hasKey->isChecked())
flags |= GRE_FLAG_KEY;
if (hasSequence->isChecked())
flags |= GRE_FLAG_SEQ;
proto->setFieldData(
GreProtocol::gre_flags,
flags);
proto->setFieldData(
GreProtocol::gre_version,
version->value());
proto->setFieldData(
GreProtocol::gre_checksum,
checksum->value());
proto->setFieldData(
GreProtocol::gre_key,
key->value());
proto->setFieldData(
GreProtocol::gre_sequence,
sequence->value());
}

41
common/greconfig.h Normal file
View File

@ -0,0 +1,41 @@
/*
Copyright (C) 2010, 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 <http://www.gnu.org/licenses/>
*/
#ifndef _GRE_CONFIG_H
#define _GRE_CONFIG_H
#include "abstractprotocolconfig.h"
#include "ui_gre.h"
class GreConfigForm :
public AbstractProtocolConfigForm,
private Ui::Gre
{
Q_OBJECT
public:
GreConfigForm(QWidget *parent = 0);
virtual ~GreConfigForm();
static GreConfigForm* createInstance();
virtual void loadWidget(AbstractProtocol *proto);
virtual void storeWidget(AbstractProtocol *proto);
};
#endif

129
common/grepdml.cpp Normal file
View File

@ -0,0 +1,129 @@
/*
Copyright (C) 2021 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 "grepdml.h"
#include "gre.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/
*/
PdmlGreProtocol::PdmlGreProtocol()
{
ostProtoId_ = OstProto::Protocol::kGreFieldNumber;
fieldMap_.insert("gre.proto", OstProto::Gre::kProtocolTypeFieldNumber);
fieldMap_.insert("gre.checksum", OstProto::Gre::kChecksumFieldNumber);
fieldMap_.insert("gre.offset", OstProto::Gre::kRsvd1FieldNumber);
fieldMap_.insert("gre.key", OstProto::Gre::kKeyFieldNumber);
fieldMap_.insert("gre.sequence_number", OstProto::Gre::kSequenceNumFieldNumber);
}
PdmlGreProtocol::~PdmlGreProtocol()
{
}
PdmlProtocol* PdmlGreProtocol::createInstance()
{
return new PdmlGreProtocol();
}
/*!
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 PdmlGreProtocol::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 PdmlGreProtocol::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 PdmlGreProtocol::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 PdmlGreProtocol::unknownFieldHandler(QString name,
int /*pos*/, int /*size*/, const QXmlStreamAttributes& attributes,
OstProto::Protocol* proto, OstProto::Stream* /*stream*/)
{
if (name == "gre.flags_and_version") {
bool isOk;
OstProto::Gre *gre = proto->MutableExtension(OstProto::gre);
quint16 flagsAndVersion = attributes.value("value")
.toUInt(&isOk, kBaseHex);
gre->set_flags(flagsAndVersion >> 12);
gre->set_rsvd0((flagsAndVersion & 0x0FFF) >> 3);
gre->set_version(flagsAndVersion & 0x0007);
}
}

50
common/grepdml.h Normal file
View File

@ -0,0 +1,50 @@
/*
Copyright (C) 2021 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 _GRE_PDML_H
#define _GRE_PDML_H
#include "pdmlprotocol.h"
class PdmlGreProtocol : public PdmlProtocol
{
public:
virtual ~PdmlGreProtocol();
static PdmlProtocol* 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:
PdmlGreProtocol();
};
#endif

View File

@ -29,6 +29,7 @@ PROTOS += \
ip4over6.proto \
ip4over4.proto \
ip6over6.proto \
gre.proto \
icmp.proto \
gmp.proto \
igmp.proto \
@ -69,6 +70,7 @@ HEADERS += \
ip6over4.h \
ip6over6.h \
gmp.h \
gre.h \
icmp.h \
igmp.h \
mld.h \
@ -103,6 +105,7 @@ SOURCES += \
ip4.cpp \
ip6.cpp \
gmp.cpp \
gre.cpp \
icmp.cpp \
igmp.cpp \
mld.cpp \

View File

@ -20,6 +20,7 @@ FORMS += \
ip4.ui \
ip6.ui \
gmp.ui \
gre.ui \
icmp.ui \
tcp.ui \
udp.ui \
@ -75,6 +76,7 @@ HEADERS += \
ip6config.h \
ip4over4config.h \
gmpconfig.h \
greconfig.h \
icmpconfig.h \
igmpconfig.h \
mldconfig.h \
@ -118,6 +120,7 @@ SOURCES += \
ip4config.cpp \
ip6config.cpp \
gmpconfig.cpp \
greconfig.cpp \
icmpconfig.cpp \
igmpconfig.cpp \
mldconfig.cpp \
@ -139,6 +142,7 @@ SOURCES += \
arppdml.cpp \
ip4pdml.cpp \
ip6pdml.cpp \
grepdml.cpp \
icmppdml.cpp \
icmp6pdml.cpp \
igmppdml.cpp \

View File

@ -28,6 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "arppdml.h"
#include "eth2pdml.h"
#include "grepdml.h"
#include "llcpdml.h"
#include "icmppdml.h"
#include "icmp6pdml.h"
@ -59,6 +60,7 @@ PdmlReader::PdmlReader(OstProto::StreamConfigList *streams)
factory_.insert("arp", PdmlArpProtocol::createInstance);
factory_.insert("eth", PdmlEthProtocol::createInstance);
factory_.insert("gre", PdmlGreProtocol::createInstance);
factory_.insert("http", PdmlTextProtocol::createInstance);
factory_.insert("icmp", PdmlIcmpProtocol::createInstance);
factory_.insert("icmpv6", PdmlIcmp6Protocol::createInstance);

View File

@ -156,6 +156,7 @@ message Protocol {
kIcmpFieldNumber = 402;
kIgmpFieldNumber = 403;
kMldFieldNumber = 404;
kGreFieldNumber = 405;
kTextProtocolFieldNumber = 500;
}

View File

@ -46,6 +46,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "ip6over6.h"
// L4 Protos
#include "gre.h"
#include "icmp.h"
#include "igmp.h"
#include "mld.h"
@ -112,6 +113,8 @@ ProtocolManager::ProtocolManager()
(void*) Ip6over6Protocol::createInstance);
// Layer 4 Protocols
registerProtocol(OstProto::Protocol::kGreFieldNumber,
(void*) GreProtocol::createInstance);
registerProtocol(OstProto::Protocol::kIcmpFieldNumber,
(void*) IcmpProtocol::createInstance);
registerProtocol(OstProto::Protocol::kIgmpFieldNumber,

View File

@ -40,6 +40,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "ip6over4config.h"
#include "ip6over6config.h"
// L4 Protocol Widgets
#include "greconfig.h"
#include "icmpconfig.h"
#include "igmpconfig.h"
#include "mldconfig.h"
@ -124,6 +125,9 @@ ProtocolWidgetFactory::ProtocolWidgetFactory()
(void*) Ip6over6ConfigForm::createInstance);
// Layer 4 Protocols
OstProtocolWidgetFactory->registerProtocolConfigWidget(
OstProto::Protocol::kGreFieldNumber,
(void*) GreConfigForm::createInstance);
OstProtocolWidgetFactory->registerProtocolConfigWidget(
OstProto::Protocol::kIcmpFieldNumber,
(void*) IcmpConfigForm::createInstance);