Added a generic TextProtocol that can be used for any text based protocol such as HTTP, SIP, RTSP, NNTP etc. Also - fixed a bug in ARP; IntComboBox sets itself as 'editable'

This commit is contained in:
Srivats P. 2010-05-06 20:39:29 +05:30
parent d9f788e93d
commit 3defe905e5
9 changed files with 486 additions and 2 deletions

View File

@ -722,6 +722,8 @@ bool ArpProtocol::setFieldData(int index, const QVariant &value,
uint mode = value.toUInt(&isOk);
if (isOk && data.HwAddrMode_IsValid(mode))
data.set_sender_hw_addr_mode((OstProto::Arp::HwAddrMode) mode);
else
isOk = false;
break;
}
case arp_senderHwAddrCount:
@ -745,6 +747,8 @@ bool ArpProtocol::setFieldData(int index, const QVariant &value,
if (isOk && data.ProtoAddrMode_IsValid(mode))
data.set_sender_proto_addr_mode(
(OstProto::Arp::ProtoAddrMode)mode);
else
isOk = false;
break;
}
case arp_senderProtoAddrCount:
@ -774,6 +778,8 @@ bool ArpProtocol::setFieldData(int index, const QVariant &value,
uint mode = value.toUInt(&isOk);
if (isOk && data.HwAddrMode_IsValid(mode))
data.set_target_hw_addr_mode((OstProto::Arp::HwAddrMode)mode);
else
isOk = false;
break;
}
case arp_targetHwAddrCount:
@ -797,6 +803,8 @@ bool ArpProtocol::setFieldData(int index, const QVariant &value,
if (isOk && data.ProtoAddrMode_IsValid(mode))
data.set_target_proto_addr_mode(
(OstProto::Arp::ProtoAddrMode)mode);
else
isOk = false;
break;
}
case arp_targetProtoAddrCount:

View File

@ -28,6 +28,7 @@ public:
IntComboBox(QWidget *parent = 0)
: QComboBox(parent)
{
setEditable(true);
}
void addItem(int value, const QString &text)
{

View File

@ -16,6 +16,7 @@ FORMS += \
icmp.ui \
tcp.ui \
udp.ui \
textproto.ui \
userscript.ui \
sample.ui
PROTOS += \
@ -36,6 +37,7 @@ PROTOS += \
icmp.proto \
tcp.proto \
udp.proto \
textproto.proto \
userscript.proto \
sample.proto
HEADERS += \
@ -61,6 +63,7 @@ HEADERS += \
icmp.h \
tcp.h \
udp.h \
textproto.h \
userscript.h \
sample.h
SOURCES += \
@ -82,6 +85,7 @@ SOURCES += \
icmp.cpp \
tcp.cpp \
udp.cpp \
textproto.cpp \
userscript.cpp \
sample.cpp

View File

@ -106,6 +106,8 @@ message Protocol {
kUdpFieldNumber = 141;
kIcmpFieldNumber = 142;
kIgmpFieldNumber = 143;
kTextProtocolFieldNumber = 150;
}
}

View File

@ -36,6 +36,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "icmp.h"
#include "tcp.h"
#include "udp.h"
#include "textproto.h"
#include "userscript.h"
#include "sample.h"
@ -48,8 +49,6 @@ ProtocolManager::ProtocolManager()
*/
registerProtocol(OstProto::Protocol::kMacFieldNumber,
(void*) MacProtocol::createInstance);
registerProtocol(OstProto::Protocol::kPayloadFieldNumber,
(void*) PayloadProtocol::createInstance);
registerProtocol(OstProto::Protocol::kEth2FieldNumber,
(void*) Eth2Protocol::createInstance);
registerProtocol(OstProto::Protocol::kDot3FieldNumber,
@ -79,6 +78,12 @@ ProtocolManager::ProtocolManager()
registerProtocol(OstProto::Protocol::kUdpFieldNumber,
(void*) UdpProtocol::createInstance);
registerProtocol(OstProto::Protocol::kTextProtocolFieldNumber,
(void*) TextProtocol::createInstance);
registerProtocol(OstProto::Protocol::kPayloadFieldNumber,
(void*) PayloadProtocol::createInstance);
registerProtocol(OstProto::Protocol::kUserScriptFieldNumber,
(void*) UserScriptProtocol::createInstance);
registerProtocol(OstProto::Protocol::kSampleFieldNumber,

259
common/textproto.cpp Normal file
View File

@ -0,0 +1,259 @@
/*
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 <qendian.h>
#include "textproto.h"
TextProtocolConfigForm::TextProtocolConfigForm(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
portNumCombo->setValidator(new QIntValidator(0, 0xFFFF, this));
portNumCombo->addItem(0, "Reserved");
portNumCombo->addItem(80, "HTTP");
portNumCombo->addItem(554, "RTSP");
portNumCombo->addItem(5060, "SIP");
}
TextProtocol::TextProtocol(StreamBase *stream, AbstractProtocol *parent)
: AbstractProtocol(stream, parent)
{
/* The configWidget is created lazily */
configForm = NULL;
}
TextProtocol::~TextProtocol()
{
delete configForm;
}
AbstractProtocol* TextProtocol::createInstance(StreamBase *stream,
AbstractProtocol *parent)
{
return new TextProtocol(stream, parent);
}
quint32 TextProtocol::protocolNumber() const
{
return OstProto::Protocol::kTextProtocolFieldNumber;
}
void TextProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const
{
protocol.MutableExtension(OstProto::textProtocol)->CopyFrom(data);
protocol.mutable_protocol_id()->set_id(protocolNumber());
}
void TextProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol)
{
if (protocol.protocol_id().id() == protocolNumber() &&
protocol.HasExtension(OstProto::textProtocol))
data.MergeFrom(protocol.GetExtension(OstProto::textProtocol));
}
QString TextProtocol::name() const
{
return QString("Text Protocol");
}
QString TextProtocol::shortName() const
{
return QString("TEXT");
}
quint32 TextProtocol::protocolId(ProtocolIdType type) const
{
switch(type)
{
//case ProtocolIdTcpUdp: return data.port_num();
default:break;
}
return AbstractProtocol::protocolId(type);
}
int TextProtocol::fieldCount() const
{
return textProto_fieldCount;
}
AbstractProtocol::FieldFlags TextProtocol::fieldFlags(int index) const
{
AbstractProtocol::FieldFlags flags;
flags = AbstractProtocol::fieldFlags(index);
switch (index)
{
case textProto_text:
break;
case textProto_portNum:
case textProto_encoding:
flags |= FieldIsMeta;
break;
default:
qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__,
index);
break;
}
return flags;
}
QVariant TextProtocol::fieldData(int index, FieldAttrib attrib,
int streamIndex) const
{
switch (index)
{
case textProto_text:
{
switch(attrib)
{
case FieldName:
return QString("Text");
case FieldValue:
case FieldTextValue:
return QString().fromStdString(data.text());
case FieldFrameValue:
Q_ASSERT(data.encoding() == OstProto::TextProtocol::kUtf8);
return QString().fromStdString(data.text()).toUtf8();
default:
break;
}
break;
}
// Meta fields
case textProto_portNum:
{
switch(attrib)
{
case FieldValue:
return data.port_num();
default:
break;
}
break;
}
case textProto_encoding:
{
switch(attrib)
{
case FieldValue:
return data.encoding();
default:
break;
}
break;
}
default:
qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__,
index);
break;
}
return AbstractProtocol::fieldData(index, attrib, streamIndex);
}
bool TextProtocol::setFieldData(int index, const QVariant &value,
FieldAttrib attrib)
{
bool isOk = false;
if (attrib != FieldValue)
goto _exit;
switch (index)
{
case textProto_text:
{
data.set_text(value.toString().toUtf8());
isOk = true;
break;
}
case textProto_portNum:
{
uint portNum = value.toUInt(&isOk);
if (isOk)
data.set_port_num(portNum);
break;
}
case textProto_encoding:
{
uint enc = value.toUInt(&isOk);
if (isOk && data.TextEncoding_IsValid(enc))
data.set_encoding((OstProto::TextProtocol::TextEncoding) enc);
else
isOk = false;
break;
}
default:
qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__,
index);
break;
}
_exit:
return isOk;
}
int TextProtocol::protocolFrameSize(int streamIndex) const
{
return fieldData(textProto_text, FieldFrameValue).toByteArray().size() ;
}
QWidget* TextProtocol::configWidget()
{
/* Lazy creation of the configWidget */
if (configForm == NULL)
{
configForm = new TextProtocolConfigForm;
loadConfigWidget();
}
return configForm;
}
void TextProtocol::loadConfigWidget()
{
configWidget();
configForm->portNumCombo->setValue(
fieldData(textProto_portNum, FieldValue).toUInt());
configForm->encodingCombo->setCurrentIndex(
fieldData(textProto_encoding, FieldValue).toUInt());
configForm->protoText->setText(
fieldData(textProto_text, FieldValue).toString());
}
void TextProtocol::storeConfigWidget()
{
configWidget();
setFieldData(textProto_portNum, configForm->portNumCombo->currentValue());
setFieldData(textProto_encoding, configForm->encodingCombo->currentIndex());
setFieldData(textProto_text, configForm->protoText->toPlainText());
}

89
common/textproto.h Normal file
View File

@ -0,0 +1,89 @@
/*
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 _TEXT_PROTOCOL_H
#define _TEXT_PROTOCOL_H
#include "textproto.pb.h"
#include "ui_textproto.h"
#include "abstractprotocol.h"
/*
TextProtocol Protocol Frame Format -
specified text encoded with the specified encoding
*/
class TextProtocolConfigForm : public QWidget, public Ui::TextProtocol
{
Q_OBJECT
public:
TextProtocolConfigForm(QWidget *parent = 0);
private slots:
};
class TextProtocol : public AbstractProtocol
{
private:
OstProto::TextProtocol data;
TextProtocolConfigForm *configForm;
enum textProtocolField
{
// Frame Fields
textProto_text = 0,
// Meta Fields
textProto_portNum,
textProto_encoding,
textProto_fieldCount
};
public:
TextProtocol(StreamBase *stream, AbstractProtocol *parent = 0);
virtual ~TextProtocol();
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 quint32 protocolId(ProtocolIdType type) const;
virtual QString name() const;
virtual QString shortName() const;
virtual int fieldCount() 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;
virtual QWidget* configWidget();
virtual void loadConfigWidget();
virtual void storeConfigWidget();
};
#endif

37
common/textproto.proto Normal file
View File

@ -0,0 +1,37 @@
/*
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/>
*/
import "protocol.proto";
package OstProto;
// Any Text based protocol
message TextProtocol {
enum TextEncoding {
kUtf8 = 0;
}
optional uint32 port_num = 1 [default = 0];
optional TextEncoding encoding = 2 [default = kUtf8];
optional string text = 3;
}
extend Protocol {
optional TextProtocol textProtocol = 150;
}

79
common/textproto.ui Normal file
View File

@ -0,0 +1,79 @@
<ui version="4.0" >
<class>TextProtocol</class>
<widget class="QWidget" name="TextProtocol" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>493</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="label_2" >
<property name="text" >
<string>TCP/UDP Port Number (Protocol)</string>
</property>
<property name="buddy" >
<cstring>portNumCombo</cstring>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="IntComboBox" name="portNumCombo" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
<horstretch>2</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="3" >
<widget class="QLabel" name="label" >
<property name="text" >
<string>Encode as</string>
</property>
<property name="buddy" >
<cstring>encodingCombo</cstring>
</property>
</widget>
</item>
<item row="0" column="4" >
<widget class="QComboBox" name="encodingCombo" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text" >
<string>UTF-8</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0" colspan="5" >
<widget class="QTextEdit" name="protoText" >
<property name="acceptRichText" >
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>IntComboBox</class>
<extends>QComboBox</extends>
<header>intcombobox.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>