New Protocol Framework - initial checkin; not yet complete

This commit is contained in:
Srivats P. 2009-04-27 16:51:44 +00:00
parent 238f332ac4
commit 2d856012cb
65 changed files with 5349 additions and 4806 deletions

View File

@ -1,5 +1,5 @@
all:
$(MAKE) -C rpc install
$(MAKE) -C rpc
$(MAKE) -C common
$(MAKE) -C server
$(MAKE) -C client
@ -11,4 +11,7 @@ clean:
$(MAKE) -C client $@
qmake:
for %%d in (rpc common server client) cd %%d; qmake; cd..;
cd rpc && qmake && cd ..
cd common && qmake && cd ..
cd server && qmake && cd ..
cd client && qmake && cd ..

View File

@ -1,6 +1,7 @@
#include "dumpview.h"
//public:
//! \todo Enable Scrollbars
DumpView::DumpView(QWidget *parent)
{
int w, h;
@ -78,8 +79,8 @@ QModelIndex DumpView::indexAt( const QPoint &point ) const
_exit:
// Clear existing selection
selrow = -1;
#endif
#endif
return QModelIndex();
}
@ -148,55 +149,73 @@ void DumpView::selectionChanged( const QItemSelection &selected,
void DumpView::populateDump(QByteArray &dump, int &selOfs, int &selSize,
QModelIndex parent)
{
// TODO(LOW): Assumption - only single selection - enforce/ensure this
// FIXME: Use new enum instead of Qt::UserRole
//! \todo (low): generalize this for any model not just our pkt model
Q_ASSERT(!parent.isValid());
qDebug("!!!! %d $$$$", dump.size());
for(int i = 0; i < model()->rowCount(parent); i++)
{
QModelIndex index = model()->index(i, 0, parent);
if (model()->hasChildren(index))
{
// Non Leaf
Q_ASSERT(index.isValid());
// A non-leaf has no dump data of its own but is rather a
// container for its children. So we calculate ofs/size based
// on this fact
if (selectionModel()->isSelected(index))
// Assumption: protocol data is in bytes (not bits)
qDebug("%d: %d bytes", i, model()->data(index, Qt::UserRole).toByteArray().size());
dump.append(model()->data(index, Qt::UserRole).toByteArray());
}
if (selectionModel()->selectedIndexes().size())
{
int j, bits;
QModelIndex index;
Q_ASSERT(selectionModel()->selectedIndexes().size() == 1);
index = selectionModel()->selectedIndexes().at(0);
if (index.parent().isValid())
{
// Field
// SelOfs = SUM(protocol sizes before selected field's protocol) +
// SUM(field sizes before selected field)
selOfs = 0;
j = index.parent().row() - 1;
while (j >= 0)
{
selOfs = dump.size();
populateDump(dump, selOfs, selSize, index);
selSize = dump.size() - selOfs;
selOfs += model()->data(index.parent().sibling(j,0),
Qt::UserRole).toByteArray().size();
j--;
}
else
bits = 0;
j = index.row() - 1;
while (j >= 0)
{
populateDump(dump, selOfs, selSize, index);
bits += model()->data(index.sibling(j,0), Qt::UserRole+1).
toInt();
j--;
}
selOfs += bits/8;
selSize = model()->data(index, Qt::UserRole).toByteArray().size();
}
else
{
// Leaf
if (selectionModel()->isSelected(index))
// Protocol
selOfs = 0;
j = index.row() - 1;
while (j >= 0)
{
int size, j;
selOfs = dump.size();
size = model()->data(index, Qt::UserRole).toByteArray().size();
// Take care of multiple indexes (2 or more) mapping onto
// same dump byte(s)
j = i-1;
while ((size == 0) && (j >= 0))
{
size = model()->data(index.sibling(j,0), Qt::UserRole).
toByteArray().size();
selOfs -= size;
j++;
}
selSize = size;
selOfs += model()->data(index.sibling(j,0), Qt::UserRole).
toByteArray().size();
j--;
}
dump.append(model()->data(index, Qt::UserRole).toByteArray());
selSize = model()->data(index, Qt::UserRole).toByteArray().size();
}
// FIXME: Use RawValueRole instead of UserRole
}
}
@ -208,7 +227,7 @@ void DumpView::paintEvent(QPaintEvent* event)
QRect dumpRect = mDumpPaneTopRect;
QRect asciiRect = mAsciiPaneTopRect;
QPalette pal = palette();
QByteArray data;
static QByteArray data;
//QByteArray ba;
int selOfs = -1, selSize;
int curSelOfs, curSelSize;
@ -222,7 +241,10 @@ void DumpView::paintEvent(QPaintEvent* event)
painter.fillRect(rect(), QBrush(QColor(Qt::white)));
if (model())
{
data.clear();
populateDump(data, selOfs, selSize);
}
// display the offset, dump and ascii panes 8 + 8 bytes on a line
for (int i = 0; i < data.size(); i+=16)
@ -289,7 +311,8 @@ void DumpView::paintEvent(QPaintEvent* event)
QRect r;
QString selectedAsciiStr, selectedDumpStr;
qDebug("dumpview::paintEvent - Highlighted");
qDebug("dumpview::paintEvent - Highlighted (%d, %d)",
curSelOfs, curSelSize);
// construct the dumpStr and asciiStr
for (int k = curSelOfs; (k < (curSelOfs + curSelSize)); k++)

View File

@ -39,15 +39,17 @@ void HexLineEdit::focusOutEvent( QFocusEvent *e )
QLineEdit::focusOutEvent( e );
emit focusOut();
#else
#define uintToHexStr(num, bytesize) \
QString("%1").arg((num), (bytesize)*2 , 16, QChar('0'))
bool isOk;
ulong num;
QString str;
qDebug("before = %s\n", text().toAscii().data());
num = text().remove(QChar(' ')).toULong(&isOk, 16);
setText(uintToHexStr(num, str, 4));
setText(uintToHexStr(num, 4));
qDebug("after = %s\n", text().toAscii().data());
qDebug("after2 = %s\n", str.toAscii().data());
#undef uintToHexStr
#endif
}

View File

@ -1,6 +1,10 @@
#include "mainwindow.h"
#include "portgrouplist.h"
#if 0
#include "dbgthread.h"
#endif
#include "ui_about.h"
PortGroupList *pgl;
@ -23,14 +27,16 @@ MainWindow::MainWindow(QWidget *parent)
addDockWidget(Qt::TopDockWidgetArea, portsDock);
connect(actionFileExit, SIGNAL(triggered()), this, SLOT(close()));
#if 0
{
DbgThread *dbg = new DbgThread(pgl);
dbg->start();
}
#endif
}
MainWindow::~MainWindow()
{
delete statsDock;
delete portsDock;
delete statsWindow;
delete portsWindow;
}
void MainWindow::on_actionHelpAbout_triggered()

View File

@ -1,10 +1,13 @@
TEMPLATE = app
CONFIG += qt debug
QT += network
INCLUDEPATH += "../rpc/"
INCLUDEPATH += "../rpc/" "../common/"
LIBS += -lprotobuf
win32:LIBS += -L"../common/debug" -lostproto
unix: LIBS += -L"../common" -lostproto
win32:LIBS += -L"../rpc/debug" -lpbrpc
unix:LIBS += -L"../rpc" -lpbrpc
POST_TARGETDEPS += "../common/debug/libostproto.a" "../rpc/debug/libpbrpc.a"
RESOURCES += ostinato.qrc
HEADERS += \
dumpview.h \
@ -50,10 +53,5 @@ SOURCES += \
streamlistdelegate.cpp \
streammodel.cpp
# Protocol Buffer Sources
SOURCES += \
..\common\protocol.pb.cc
# TODO(LOW): Test only
include(modeltest.pri)

View File

@ -1,26 +1,36 @@
#include <QHostAddress>
#include "packetmodel.h"
PacketModel::PacketModel(Stream *pStream, QObject *parent)
PacketModel::PacketModel(const QList<AbstractProtocol*> &selectedProtocols,
QObject *parent)
{
mpStream = pStream;
mSelectedProtocols = selectedProtocols;
}
void PacketModel::setSelectedProtocols(
const QList<AbstractProtocol*> &selectedProtocols)
{
mSelectedProtocols = selectedProtocols;
reset();
}
int PacketModel::rowCount(const QModelIndex &parent) const
{
IndexId parentId;
// qDebug("in %s", __FUNCTION__);
// Parent == Invalid i.e. Invisible Root.
// ==> Children are Protocol (Top Level) Items
if (!parent.isValid())
return mpStream->numProtocols();
return mSelectedProtocols.size();
// Parent - Valid Item
parentId.w = parent.internalId();
switch(parentId.ws.type)
{
case ITYP_PROTOCOL:
return mpStream->protocol(parentId.ws.protocol)->numFields();
return mSelectedProtocols.at(parentId.ws.protocol)->frameFieldCount();
case ITYP_FIELD:
return 0;
default:
@ -125,11 +135,13 @@ QVariant PacketModel::data(const QModelIndex &index, int role) const
switch(id.ws.type)
{
case ITYP_PROTOCOL:
return QByteArray();
qDebug("*** %d/%d", id.ws.protocol, mSelectedProtocols.size());
return mSelectedProtocols.at(id.ws.protocol)->
protocolFrameValue();
case ITYP_FIELD:
return mpStream->protocol(id.ws.protocol)->fieldRawValue(
index.row());
return mSelectedProtocols.at(id.ws.protocol)->fieldData(
index.row(), AbstractProtocol::FieldFrameValue);
default:
qWarning("%s: Unhandled ItemType", __FUNCTION__);
@ -137,6 +149,25 @@ QVariant PacketModel::data(const QModelIndex &index, int role) const
return QByteArray();
}
// FIXME: Use a new enum here instead of UserRole
if (role == (Qt::UserRole+1))
{
switch(id.ws.type)
{
case ITYP_PROTOCOL:
return mSelectedProtocols.at(id.ws.protocol)->
protocolFrameValue().size();
case ITYP_FIELD:
return mSelectedProtocols.at(id.ws.protocol)->fieldData(
index.row(), AbstractProtocol::FieldBitSize);
default:
qWarning("%s: Unhandled ItemType", __FUNCTION__);
}
return QVariant();
}
if (role != Qt::DisplayRole)
return QVariant();
@ -144,13 +175,14 @@ QVariant PacketModel::data(const QModelIndex &index, int role) const
{
case ITYP_PROTOCOL:
return QString("%1 (%2)")
.arg(mpStream->protocol(id.ws.protocol)->protocolShortName())
.arg(mpStream->protocol(id.ws.protocol)->protocolName());
.arg(mSelectedProtocols.at(id.ws.protocol)->shortName())
.arg(mSelectedProtocols.at(id.ws.protocol)->name());
case ITYP_FIELD:
return mpStream->protocol(id.ws.protocol)->fieldName(index.row()) +
QString(" : ") +
mpStream->protocol(id.ws.protocol)->fieldTextValue(index.row());
return mSelectedProtocols.at(id.ws.protocol)->fieldData(index.row(),
AbstractProtocol::FieldName).toString() + QString(" : ") +
mSelectedProtocols.at(id.ws.protocol)->fieldData(index.row(),
AbstractProtocol::FieldTextValue).toString();
default:
qWarning("%s: Unhandled ItemType", __FUNCTION__);

View File

@ -2,15 +2,16 @@
#define _PACKET_MODEL_H
#include <QAbstractItemModel>
#include "stream.h"
#define NEW_IMPL // FIXME(HI) - Use this and remove old one
#include "abstractprotocol.h"
class PacketModel: public QAbstractItemModel
{
public:
PacketModel(Stream *pStream, QObject *parent = 0);
PacketModel(const QList<AbstractProtocol*> &selectedProtocols,
QObject *parent = 0);
void setSelectedProtocols(
const QList<AbstractProtocol*> &selectedProtocols);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
@ -33,89 +34,7 @@ private:
} ws;
} IndexId;
Stream *mpStream;
#ifdef NEW_IMPL
// Nothing - required stuff is part of Stream Class
#else
QList<uint> mPacketProtocols;
typedef struct
{
QString name;
QString abbr;
QString textValue;
} FieldInfo;
typedef struct
{
uint handle;
QString name;
QString abbr;
QList<FieldInfo> fieldList;
} ProtocolInfo;
//! Contains registration info (name, size etc) for all protocols
// and fields within the protocol
QList<ProtocolInfo> mProtocols;
void registerProto(uint handle, char *name, char *abbr);
void registerField(uint protoHandle, char *name, char *abbr);
void registerFrameTypeProto();
void registerVlanProto();
void registerIpProto();
void registerArpProto();
void registerTcpProto();
void registerUdpProto();
void registerIcmpProto();
void registerIgmpProto();
void registerData();
void registerInvalidProto();
void populatePacketProtocols();
int protoCount() const;
int fieldCount(int protocol) const;
QString protoName(int protocol) const;
QString fieldName(int protocol, int field) const;
QVariant fieldTextValue(int protocol, int field) const;
QVariant ethField(int field, int role) const;
QVariant llcField(int field, int role) const;
QVariant snapField(int field, int role) const;
QVariant svlanField(int field, int role) const;
QVariant ipField(int field, int role) const;
QVariant tcpField(int field, int role) const;
QVariant udpField(int field, int role) const;
// FIXME(HIGH): Is this how I want this?
#define PTYP_L2_NONE 1
#define PTYP_L2_ETH_2 2
#define PTYP_L2_802_3_RAW 3
#define PTYP_L2_802_3_LLC 4
#define PTYP_L2_SNAP 5
#define PTYP_SVLAN 10
#define PTYP_CVLAN 11
#define PTYP_L3_IP 30
#define PTYP_L3_ARP 31
#define PTYP_L4_TCP 40
#define PTYP_L4_UDP 41
#define PTYP_L4_ICMP 42
#define PTYP_L4_IGMP 43
#define PTYP_INVALID 0
#define PTYP_DATA 0xFF
#endif // NEW_IMPL
#define FROL_NAME 1
#define FROL_TEXT_VALUE 2
#define BASE_HEX 16
QList<AbstractProtocol*> mSelectedProtocols;
};
#endif

View File

@ -32,7 +32,7 @@ void Port::updatePortConfig(OstProto::Port *port)
void Port::updateStreamOrdinalsFromIndex()
{
for (int i=0; i < mStreams.size(); i++)
mStreams[i].setOrdinal(i);
mStreams[i]->setOrdinal(i);
}
void Port::reorderStreamsByOrdinals()
@ -42,12 +42,12 @@ void Port::reorderStreamsByOrdinals()
bool Port::newStreamAt(int index)
{
Stream s;
Stream *s = new Stream;
if (index > mStreams.size())
return false;
s.setId(newStreamId());
s->setId(newStreamId());
mStreams.insert(index, s);
updateStreamOrdinalsFromIndex();
@ -59,7 +59,7 @@ bool Port::deleteStreamAt(int index)
if (index >= mStreams.size())
return false;
mStreams.removeAt(index);
delete mStreams.takeAt(index);
updateStreamOrdinalsFromIndex();
return true;
@ -67,9 +67,9 @@ bool Port::deleteStreamAt(int index)
bool Port::insertStream(uint streamId)
{
Stream s;
Stream *s = new Stream;
s.setId(streamId);
s->setId(streamId);
// FIXME(MED): If a stream with id already exists, what do we do?
mStreams.append(s);
@ -88,7 +88,7 @@ bool Port::updateStream(uint streamId, OstProto::Stream *stream)
for (i = 0; i < mStreams.size(); i++)
{
if (streamId == mStreams[i].id())
if (streamId == mStreams[i]->id())
goto _found;
}
@ -98,7 +98,7 @@ bool Port::updateStream(uint streamId, OstProto::Stream *stream)
_found:
streamIndex = i;
mStreams[streamIndex].update(stream);
mStreams[streamIndex]->update(stream);
reorderStreamsByOrdinals();
return true;
@ -114,7 +114,7 @@ void Port::getDeletedStreamsSinceLastSync(
for (j = 0; j < mStreams.size(); j++)
{
if (mLastSyncStreamList[i] == mStreams[j].id())
if (mLastSyncStreamList[i] == mStreams[j]->id())
break;
}
@ -140,7 +140,7 @@ void Port::getNewStreamsSinceLastSync(
streamIdList.clear_stream_id();
for (int i = 0; i < mStreams.size(); i++)
{
if (mLastSyncStreamList.contains(mStreams[i].id()))
if (mLastSyncStreamList.contains(mStreams[i]->id()))
{
// existing stream!
continue;
@ -151,7 +151,7 @@ void Port::getNewStreamsSinceLastSync(
OstProto::StreamId *s;
s = streamIdList.add_stream_id();
s->set_id(mStreams[i].id());
s->set_id(mStreams[i]->id());
}
}
}
@ -167,8 +167,9 @@ void Port::getModifiedStreamsSinceLastSync(
OstProto::Stream *s;
s = streamConfigList.add_stream();
mStreams[i].getConfig(mPortId, s);
mStreams[i]->getConfig(mPortId, *s);
}
qDebug("Done %s", __FUNCTION__);
}
void Port::when_syncComplete()
@ -177,7 +178,7 @@ void Port::when_syncComplete()
mLastSyncStreamList.clear();
for (int i=0; i<mStreams.size(); i++)
mLastSyncStreamList.append(mStreams[i].id());
mLastSyncStreamList.append(mStreams[i]->id());
}
void Port::updateStats(OstProto::PortStats *portStats)

View File

@ -23,7 +23,7 @@ private:
QString mUserAlias; // user defined
QList<quint32> mLastSyncStreamList;
QList<Stream> mStreams; // sorted by stream's ordinal value
QList<Stream*> mStreams; // sorted by stream's ordinal value
uint newStreamId();
void updateStreamOrdinalsFromIndex();
@ -65,7 +65,7 @@ public:
//void setExclusive(bool flag);
int numStreams() { return mStreams.size(); }
Stream& streamByIndex(int index)
Stream* streamByIndex(int index)
{
Q_ASSERT(index < mStreams.size());
return mStreams[index];

View File

@ -1,5 +1,4 @@
#include "portgroup.h"
#include "../common/protocol.h"
#include <vector>
@ -400,7 +399,7 @@ _request:
OstProto::StreamId *s;
s = streamIdList.add_stream_id();
s->set_id(mPorts[portIndex].streamByIndex(j).id());
s->set_id(mPorts[portIndex].streamByIndex(j)->id());
}
streamConfigList->Clear();

View File

@ -12,6 +12,9 @@
<property name="windowTitle" >
<string>Select Ports</string>
</property>
<property name="windowIcon" >
<iconset resource="ostinato.qrc" >:/icons/portstats_filter.png</iconset>
</property>
<layout class="QVBoxLayout" >
<item>
<layout class="QHBoxLayout" >
@ -121,7 +124,9 @@
<tabstop>lvSelected</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<resources>
<include location="ostinato.qrc" />
</resources>
<connections>
<connection>
<sender>buttonBox</sender>

File diff suppressed because it is too large Load Diff

View File

@ -6,10 +6,7 @@
#include <QString>
#include <QList>
#include "../common/protocol.pb.h"
class StreamConfigDialog;
class StreamModel;
class PacketModel;
#include "../common/abstractprotocol.h"
// Convenience Defines FIXME
#define IP_PROTO_ICMP 0x01
@ -17,864 +14,19 @@ class PacketModel;
#define IP_PROTO_TCP 0x06
#define IP_PROTO_UDP 0x11
class Stream;
class AbstractProtocol
{
// TODO(LOW)
public:
/*!
Subclasses should return reference to their protocol specific
::google::protobuf::Message
*/
virtual ::google::protobuf::Message& data() = 0;
/*! Subclasses can directly use this method. No need for overload */
void getConfig(::google::protobuf::Message *msg)
{ msg->CopyFrom(data()); }
bool setProtoData(::google::protobuf::Message *msg)
{ data().MergeFrom(*msg); return true; }
virtual QString protocolName()
{ return QString("AbstractProtocol"); }
virtual QString protocolShortName()
{ return QString("AbsProto"); }
virtual int numFields()
{ return 1; }
QByteArray protocolRawValue()
{
QByteArray ba;
#ifndef SRIVATSP
#else
for (int i=0; i < numFields(); i++)
ba.append(fieldRawValue(i));
#endif
return ba;
}
virtual QString fieldName(int index)
{ return QString("AbstractField"); }
virtual QString fieldTextValue(int index)
{ return QString("AbstractFieldValue"); }
virtual QByteArray fieldRawValue(int index)
{ return QByteArray(4, '\0'); }
};
class UnknownProtocol: public AbstractProtocol
{
OstProto::Ack d; // FIXME(HI): replace 'Ack' with something else
public:
virtual ~UnknownProtocol() {}
virtual ::google::protobuf::Message& data() { return d; }
virtual QString protocolName()
{ return QString("UnknownProtocol"); }
QString protocolShortName()
{ return QString("???Proto"); }
int numFields()
{ return 1; }
QString fieldName(int index)
{ return QString("UnknownField"); }
QString fieldTextValue(int index)
{ return QString("UnknownFieldValue"); }
QByteArray fieldRawValue(int index)
{ return QByteArray(); }
};
class PayloadProtocol: public AbstractProtocol
{
Stream *parentStream;
OstProto::Ack d; // FIXME(HI): move payload related vars from
// stream into here
public:
PayloadProtocol (Stream *stream = NULL) { parentStream = stream; }
virtual ~PayloadProtocol() {}
virtual ::google::protobuf::Message& data() { return d; }
virtual QString protocolName()
{ return QString("Payload Data"); }
QString protocolShortName()
{ return QString("DATA"); }
int numFields()
{ return 1; }
QString fieldName(int index)
{ return QString("Data"); }
QString fieldTextValue(int index);
QByteArray fieldRawValue(int index);
};
class MacProtocol : public AbstractProtocol
{
private:
OstProto::Mac d;
public:
enum MacAddrMode {
MacAddrFixed,
MacAddrInc,
MacAddrDec
};
virtual ~MacProtocol() {}
virtual ::google::protobuf::Message& data() {return d;}
bool update(OstProto::Mac mac) { d.MergeFrom(mac); return true; }
// Dst Mac
quint64 dstMac()
{ return d.dst_mac(); }
bool setDstMac(quint64 dstMac)
{ d.set_dst_mac(dstMac); return true; }
MacAddrMode dstMacMode()
{ return (MacAddrMode) d.dst_mac_mode(); }
bool setDstMacMode(MacAddrMode dstMacMode)
{ d.set_dst_mac_mode((OstProto::Mac::MacAddrMode)dstMacMode); return true; }
quint16 dstMacCount()
{ return d.dst_mac_count(); }
bool setDstMacCount(quint16 dstMacCount)
{ d.set_dst_mac_count(dstMacCount); return true; }
quint16 dstMacStep()
{ return d.dst_mac_step(); }
bool setDstMacStep(quint16 dstMacStep)
{ d.set_dst_mac_step(dstMacStep); return true; }
// Src Mac
quint64 srcMac()
{ return d.src_mac(); }
bool setSrcMac(quint64 srcMac)
{ d.set_src_mac(srcMac); return true; }
MacAddrMode srcMacMode()
{ return (MacAddrMode) d.src_mac_mode(); }
bool setSrcMacMode(MacAddrMode srcMacMode)
{ d.set_src_mac_mode((OstProto::Mac::MacAddrMode)srcMacMode); return true; }
quint16 srcMacCount()
{ return d.src_mac_count(); }
bool setSrcMacCount(quint16 srcMacCount)
{ d.set_src_mac_count(srcMacCount); return true; }
quint16 srcMacStep()
{ return d.src_mac_step(); }
bool setSrcMacStep(quint16 srcMacStep)
{ d.set_src_mac_step(srcMacStep); return true; }
virtual QString protocolName()
{ return QString("Media Access Control"); }
QString protocolShortName()
{ return QString("MAC"); }
int numFields()
{ return 2; }
QString fieldName(int index);
QString fieldTextValue(int index);
QByteArray fieldRawValue(int index);
};
class LlcProtocol : public AbstractProtocol
{
private:
OstProto::Llc d;
public:
virtual ~LlcProtocol() {}
virtual ::google::protobuf::Message& data() {return d;}
bool update(OstProto::Llc llc) { d.MergeFrom(llc); return true; }
quint8 dsap()
{ return d.dsap(); }
bool setDsap(quint8 dsap)
{ d.set_dsap(dsap); return true; }
quint8 ssap()
{ return d.ssap(); }
bool setSsap(quint8 ssap)
{ d.set_ssap(ssap); return true; }
quint8 ctl()
{ return d.ctl(); }
bool setCtl(quint8 ctl)
{ d.set_ctl(ctl); return true; }
virtual QString protocolName()
{ return QString("802.3 Logical Link Control"); }
QString protocolShortName()
{ return QString("LLC"); }
int numFields()
{ return 3; }
QString fieldName(int index);
QString fieldTextValue(int index);
QByteArray fieldRawValue(int index);
};
class SnapProtocol : public AbstractProtocol
{
private:
OstProto::Snap d;
public:
virtual ~SnapProtocol() {}
virtual ::google::protobuf::Message& data() {return d;}
bool update(OstProto::Snap snap) { d.MergeFrom(snap); return true; }
quint32 oui()
{ return d.oui(); }
bool setOui(quint32 oui)
{ d.set_oui(oui); return true; }
// "Type" field: use from eth2
#if 0
quint16 type()
{ return d.type(); }
bool setType(quint16 type)
{ d.set_type(type); return true; }
#endif
virtual QString protocolName()
{ return QString("SubNetwork Access Protocol"); }
QString protocolShortName()
{ return QString("SNAP"); }
int numFields()
{ return 1; }
QString fieldName(int index);
QString fieldTextValue(int index);
QByteArray fieldRawValue(int index);
};
class Eth2Protocol : public AbstractProtocol
{
private:
OstProto::Eth2 d;
public:
virtual ~Eth2Protocol() {}
virtual ::google::protobuf::Message& data() {return d;}
bool update(OstProto::Eth2 eth2) { d.MergeFrom(eth2); return true; }
quint16 type()
{ return d.type(); }
bool setType(quint16 type)
{ d.set_type(type); return true; }
virtual QString protocolName()
{ return QString("Protocol Type"); }
QString protocolShortName()
{ return QString("TYPE"); }
int numFields()
{ return 1; }
QString fieldName(int index);
QString fieldTextValue(int index);
QByteArray fieldRawValue(int index);
};
class Dot3Protocol : public AbstractProtocol
{
private:
Stream *parentStream;
OstProto::Ack d; // FIXME(HI): replace 'ack' with somehting else
public:
Dot3Protocol(Stream *stream = NULL)
{ parentStream = stream; qDebug("parentStream = %p", stream); }
virtual ~Dot3Protocol() {}
virtual ::google::protobuf::Message& data() {return d;}
#if 0 // FIXME(HI): remove?
quint16 length()
{ return d.length(); }
bool setLength(quint16 length)
{ return true; }
#endif
virtual QString protocolName()
{ return QString("802.3 Length"); }
QString protocolShortName()
{ return QString("LEN"); }
int numFields()
{ return 1; }
QString fieldName(int index);
QString fieldTextValue(int index);
QByteArray fieldRawValue(int index);
};
class VlanProtocol : public AbstractProtocol
{
OstProto::Vlan d;
public:
virtual ~VlanProtocol() {}
virtual ::google::protobuf::Message& data() {return d;}
bool update(OstProto::Vlan vlan) { d.MergeFrom(vlan); return true; }
enum VlanFlag {
VlanCvlanTagged = 0x01,
VlanCtpidOverride = 0x02,
VlanSvlanTagged = 0x04,
VlanStpidOverride = 0x08,
};
Q_DECLARE_FLAGS(VlanFlags, VlanFlag);
VlanFlags vlanFlags()
{
VlanFlags f;
if (d.is_cvlan_tagged()) f|= VlanCvlanTagged;
if (d.is_ctpid_override()) f|= VlanCtpidOverride;
if (d.is_svlan_tagged()) f|= VlanSvlanTagged;
if (d.is_stpid_override()) f|= VlanStpidOverride;
return f;
}
bool setVlanFlags(VlanFlags vlanFlags)
{
d.set_is_cvlan_tagged(vlanFlags.testFlag(VlanCvlanTagged));
d.set_is_ctpid_override(vlanFlags.testFlag(VlanCtpidOverride));
d.set_is_svlan_tagged(vlanFlags.testFlag(VlanSvlanTagged));
d.set_is_stpid_override(vlanFlags.testFlag(VlanStpidOverride));
return true;
}
bool isUntagged()
{
if (!d.is_cvlan_tagged() && !d.is_svlan_tagged())
return true;
else
return false;
}
bool isSingleTagged()
{
if (( d.is_cvlan_tagged() && !d.is_svlan_tagged()) ||
(!d.is_cvlan_tagged() && d.is_svlan_tagged()) )
return true;
else
return false;
}
bool isDoubleTagged()
{
if (d.is_cvlan_tagged() && d.is_svlan_tagged())
return true;
else
return false;
}
// CVLAN
quint16 ctpid()
{ return d.ctpid(); }
bool setCtpid(quint16 ctpid)
{ d.set_ctpid(ctpid); return true; }
quint8 cvlanPrio()
{ return (d.cvlan_tag() >> 13); }
bool setCvlanPrio(quint8 cvlanPrio)
{ d.set_cvlan_tag((d.cvlan_tag() & 0x1FFF) | ((cvlanPrio & 0x3) << 13));
return true; }
quint8 cvlanCfi()
{ return ((d.cvlan_tag() & 0x1000) >> 12); }
bool setCvlanCfi(quint8 cvlanCfi)
{ d.set_cvlan_tag((d.cvlan_tag() & 0xEFFF) | ((cvlanCfi & 0x01) << 12));
return true; }
quint16 cvlanId()
{ return (d.cvlan_tag() & 0x0FFF); }
bool setCvlanId(quint16 cvlanId)
{ d.set_cvlan_tag((d.cvlan_tag() & 0xF000) | ((cvlanId & 0x0FFF)));
return true; }
// SVLAN
quint16 stpid()
{ return d.stpid(); }
bool setStpid(quint16 stpid)
{ d.set_stpid(stpid); return true; }
quint8 svlanPrio()
{ return (d.svlan_tag() >> 13); }
bool setSvlanPrio(quint8 svlanPrio)
{ d.set_svlan_tag((d.svlan_tag() & 0x1FFF) | ((svlanPrio & 0x3) << 13));
return true; }
quint8 svlanCfi()
{ return ((d.svlan_tag() & 0x1000) >> 12); }
bool setSvlanCfi(quint8 svlanCfi)
{ d.set_svlan_tag((d.svlan_tag() & 0xEFFF) | ((svlanCfi & 0x01) << 12));
return true; }
quint16 svlanId()
{ return (d.svlan_tag() & 0x0FFF); }
bool setSvlanId(quint16 svlanId)
{ d.set_svlan_tag((d.svlan_tag() & 0xF000) | ((svlanId & 0x0FFF)));
return true; }
virtual QString protocolName()
{ return QString("Virtual Local Access Network"); }
QString protocolShortName()
{ return QString("VLAN"); }
int numFields();
QString fieldName(int index);
QString fieldTextValue(int index);
QByteArray fieldRawValue(int index);
};
// IP
class IpProtocol : public AbstractProtocol
{
private:
OstProto::Ip d;
public:
virtual ~IpProtocol() {}
virtual ::google::protobuf::Message& data() {return d;}
bool update(OstProto::Ip ip) { d.MergeFrom(ip); return true; }
enum IpAddrMode {
IpAddrFixed,
IpAddrIncHost,
IpAddrDecHost,
IpAddrRandomHost
};
enum IpFlag {
IpOverrideVersion = 0x01,
IpOverrideHdrLen = 0x02,
IpOverrideTotLen = 0x04,
IpOverrideCksum = 0x08
};
Q_DECLARE_FLAGS(IpFlags, IpFlag);
IpFlags ipFlags()
{
IpFlags f;
if (d.is_override_ver()) f|= IpOverrideVersion;
if (d.is_override_hdrlen()) f|= IpOverrideHdrLen;
if (d.is_override_totlen()) f|= IpOverrideTotLen;
if (d.is_override_cksum()) f|= IpOverrideCksum;
return f;
}
bool setIpFlags(IpFlags ipFlags)
{
if (ipFlags.testFlag(IpOverrideVersion))
d.set_is_override_ver(true);
else
d.set_is_override_ver(false);
if (ipFlags.testFlag(IpOverrideHdrLen))
d.set_is_override_hdrlen(true);
else
d.set_is_override_hdrlen(false);
if (ipFlags.testFlag(IpOverrideTotLen))
d.set_is_override_totlen(true);
else
d.set_is_override_totlen(false);
if (ipFlags.testFlag(IpOverrideCksum))
d.set_is_override_cksum(true);
else
d.set_is_override_cksum(false);
return true;
}
quint8 ver()
{ return (d.ver_hdrlen() >> 4); }
bool setVer(quint8 ver)
{ d.set_ver_hdrlen((d.ver_hdrlen() & 0x0F) | (ver << 4)); return true; }
quint8 hdrLen()
{ return (d.ver_hdrlen() & 0xF); }
bool setHdrLen(quint8 hdrLen)
{ d.set_ver_hdrlen((d.ver_hdrlen() & 0xF0) | hdrLen); return true; }
quint8 tos()
{ return d.tos(); }
bool setTos(quint8 tos)
{ d.set_tos(tos); return true; }
quint16 totLen()
{ return d.tot_len(); }
bool setTotLen(quint16 totLen)
{ d.set_tot_len(totLen); return true; }
quint16 id()
{ return d.id(); }
bool setId(quint16 id)
{ d.set_id(id); return true; }
quint16 flags()
{ return d.flags(); }
bool setFlags(quint16 flags)
{ d.set_flags(flags); return true; }
#define IP_FLAG_UNUSED 0x1
#define IP_FLAG_DF 0x2
#define IP_FLAG_MF 0x4
quint16 fragOfs()
{ return d.frag_ofs(); }
bool setFragOfs(quint16 fragOfs)
{ d.set_frag_ofs(fragOfs); return true; }
quint8 ttl()
{ return d.ttl(); }
bool setTtl(quint8 ttl)
{ d.set_ttl(ttl); return true; }
quint8 proto()
{ return d.proto(); }
bool setProto(quint8 proto)
{ d.set_proto(proto); return true; }
quint16 cksum()
{ return d.cksum(); }
bool setCksum(quint16 cksum)
{ d.set_cksum(cksum); return true; }
// Source IP
quint32 srcIp()
{ return d.src_ip(); }
bool setSrcIp(quint32 srcIp)
{ d.set_src_ip(srcIp); return true; }
IpAddrMode srcIpMode()
{ return (IpAddrMode) d.src_ip_mode(); }
bool setSrcIpMode(IpAddrMode srcIpMode)
{ d.set_src_ip_mode((OstProto::Ip::IpAddrMode)srcIpMode); return true; }
quint16 srcIpCount()
{ return d.src_ip_count(); }
bool setSrcIpCount(quint16 srcIpCount)
{ d.set_src_ip_count(srcIpCount); return true; }
quint32 srcIpMask()
{ return d.src_ip_mask(); }
bool setSrcIpMask(quint32 srcIpMask)
{ d.set_src_ip_mask(srcIpMask); return true; }
// Destination IP
quint32 dstIp()
{ return d.dst_ip(); }
bool setDstIp(quint32 dstIp)
{ d.set_dst_ip(dstIp); return true; }
IpAddrMode dstIpMode()
{ return (IpAddrMode) d.dst_ip_mode(); }
bool setDstIpMode(IpAddrMode dstIpMode)
{ d.set_dst_ip_mode((OstProto::Ip::IpAddrMode)dstIpMode); return true; }
quint16 dstIpCount()
{ return d.dst_ip_count(); }
bool setDstIpCount(quint16 dstIpCount)
{ d.set_dst_ip_count(dstIpCount); return true; }
quint32 dstIpMask()
{ return d.dst_ip_mask(); }
bool setDstIpMask(quint32 dstIpMask)
{ d.set_dst_ip_mask(dstIpMask); return true; }
// TODO(LOW): Options
virtual QString protocolName()
{ return QString("Internet Protocol version 4"); }
QString protocolShortName()
{ return QString("IPv4"); }
int numFields()
{ return 12; }
QString fieldName(int index);
QString fieldTextValue(int index);
QByteArray fieldRawValue(int index);
};
Q_DECLARE_OPERATORS_FOR_FLAGS(IpProtocol::IpFlags)
class ArpProtocol: public AbstractProtocol
{
// TODO(LOW): ARP
OstProto::Arp d;
public:
virtual ~ArpProtocol() {}
virtual ::google::protobuf::Message& data() {return d;}
bool update(OstProto::Arp arp) { d.MergeFrom(arp); return true; }
};
// TCP
class TcpProtocol : public AbstractProtocol
{
private:
OstProto::Tcp d;
public:
virtual ~TcpProtocol() {}
virtual ::google::protobuf::Message& data() {return d;}
bool update(OstProto::Tcp tcp) { d.MergeFrom(tcp); return true; }
enum TcpFlag
{
TcpOverrideHdrLen = 0x01,
TcpOverrideCksum = 0x02
};
Q_DECLARE_FLAGS(TcpFlags, TcpFlag);
TcpFlags tcpFlags()
{
TcpFlags f;
if (d.is_override_hdrlen()) f|= TcpOverrideHdrLen;
if (d.is_override_cksum()) f|= TcpOverrideCksum;
return f;
}
bool setTcpFlags(TcpFlags tcpFlags)
{
if (tcpFlags.testFlag(TcpOverrideHdrLen))
d.set_is_override_hdrlen(true);
else
d.set_is_override_hdrlen(false);
if (tcpFlags.testFlag(TcpOverrideCksum))
d.set_is_override_cksum(true);
else
d.set_is_override_cksum(false);
return true;
}
quint16 srcPort()
{ return d.src_port(); }
bool setSrcPort(quint16 srcPort)
{ d.set_src_port(srcPort); return true; }
quint16 dstPort()
{ return d.dst_port(); }
bool setDstPort(quint16 dstPort)
{ d.set_dst_port(dstPort); return true; }
quint32 seqNum()
{ return d.seq_num(); }
bool setSeqNum(quint32 seqNum)
{ d.set_seq_num(seqNum); return true;}
quint32 ackNum()
{ return d.ack_num(); }
bool setAckNum(quint32 ackNum)
{ d.set_ack_num(ackNum); return true;}
quint8 hdrLen()
{ return (d.hdrlen_rsvd() >> 4); }
bool setHdrLen(quint8 hdrLen)
{ d.set_hdrlen_rsvd((d.hdrlen_rsvd() & 0x0F) | (hdrLen << 4)); return true; }
quint8 rsvd()
{ return (d.hdrlen_rsvd() & 0xF); }
bool setRsvd(quint8 rsvd)
{ d.set_hdrlen_rsvd((d.hdrlen_rsvd() & 0xF0) | rsvd); return true; }
// TODO(MED): convert to enum maybe?
quint8 flags()
{ return d.flags(); }
bool setFlags(quint8 flags)
{ d.set_flags(flags); return true; }
#define TCP_FLAG_URG 0x01
#define TCP_FLAG_ACK 0x02
#define TCP_FLAG_PSH 0x04
#define TCP_FLAG_RST 0x08
#define TCP_FLAG_SYN 0x10
#define TCP_FLAG_FIN 0x20
quint16 window()
{ return d.window(); }
bool setWindow(quint16 window)
{ d.set_window(window); return true; }
quint16 cksum()
{ return d.cksum(); }
bool setCksum(quint16 cksum)
{ d.set_cksum(cksum); return true; }
quint16 urgPtr()
{ return d.urg_ptr(); }
bool setUrgPtr(quint16 urg_ptr)
{ d.set_urg_ptr(urg_ptr); return true; }
virtual QString protocolName()
{ return QString("Transmission Control Protocol"); }
QString protocolShortName()
{ return QString("TCP"); }
int numFields()
{ return 10; }
QString fieldName(int index);
QString fieldTextValue(int index);
QByteArray fieldRawValue(int index);
};
Q_DECLARE_OPERATORS_FOR_FLAGS(TcpProtocol::TcpFlags)
// UDP
class UdpProtocol : public AbstractProtocol
{
private:
OstProto::Udp d;
public:
virtual ~UdpProtocol() {}
virtual ::google::protobuf::Message& data() {return d;}
bool update(OstProto::Udp udp) { d.MergeFrom(udp); return true; }
enum UdpFlag
{
UdpOverrideTotLen = 0x01,
UdpOverrideCksum = 0x02
};
Q_DECLARE_FLAGS(UdpFlags, UdpFlag);
UdpFlags udpFlags()
{
UdpFlags f;
if (d.is_override_totlen()) f|= UdpOverrideTotLen;
if (d.is_override_cksum()) f|= UdpOverrideCksum;
return f;
}
bool setUdpFlags(UdpFlags udpFlags)
{
if (udpFlags.testFlag(UdpOverrideTotLen))
d.set_is_override_totlen(true);
else
d.set_is_override_totlen(false);
if (udpFlags.testFlag(UdpOverrideCksum))
d.set_is_override_cksum(true);
else
d.set_is_override_cksum(false);
return true;
}
quint16 srcPort()
{ return d.src_port(); }
bool setSrcPort(quint16 srcPort)
{ d.set_src_port(srcPort); return true; }
quint16 dstPort()
{ return d.dst_port(); }
bool setDstPort(quint16 dstPort)
{ d.set_dst_port(dstPort); return true; }
quint16 totLen()
{ return d.totlen(); }
bool setTotLen(quint16 totLen)
{ d.set_totlen(totLen); return true; }
quint16 cksum()
{ return d.cksum(); }
bool setCksum(quint16 cksum)
{ d.set_cksum(cksum); return true; }
virtual QString protocolName()
{ return QString("User Datagram Protocol"); }
QString protocolShortName()
{ return QString("UDP"); }
int numFields()
{ return 4; }
QString fieldName(int index);
QString fieldTextValue(int index);
QByteArray fieldRawValue(int index);
};
class IcmpProtocol : public AbstractProtocol
{
// TODO(LOW): ICMP
OstProto::Icmp d;
public:
virtual ~IcmpProtocol() {}
virtual ::google::protobuf::Message& data() {return d;}
bool update(OstProto::Icmp icmp) { d.MergeFrom(icmp); return true; }
};
class IgmpProtocol : public AbstractProtocol
{
// TODO(LOW): IGMP
OstProto::Igmp d;
public:
virtual ~IgmpProtocol() {}
virtual ::google::protobuf::Message& data() {return d;}
bool update(OstProto::Igmp igmp) { d.MergeFrom(igmp); return true; }
};
class Stream {
quint32 mId;
OstProto::StreamCore *mCore;
OstProto::StreamControl *mControl;
UnknownProtocol *mUnknown;
PayloadProtocol *mPayload;
MacProtocol *mMac;
LlcProtocol *mLlc;
SnapProtocol *mSnap;
Eth2Protocol *mEth2;
Dot3Protocol *mDot3;
VlanProtocol *mVlan;
IpProtocol *mIp;
ArpProtocol *mArp;
TcpProtocol *mTcp;
UdpProtocol *mUdp;
IcmpProtocol *mIcmp;
IgmpProtocol *mIgmp;
QList<AbstractProtocol*> mProtocolList;
public:
//PayloadProtocol* Payload() { return mPayload; }
MacProtocol* mac() { return mMac; }
void* core() { return mCore; } // FIXME(HI): Debug ONLY
LlcProtocol* llc() { return mLlc; }
SnapProtocol* snap() { return mSnap; }
Eth2Protocol* eth2() { return mEth2; }
Dot3Protocol* dot3() { return mDot3; }
VlanProtocol* vlan() { return mVlan; }
IpProtocol* ip() { return mIp; }
ArpProtocol* arp() { return mArp; }
TcpProtocol* tcp() { return mTcp; }
UdpProtocol* udp() { return mUdp; }
IcmpProtocol* icmp() { return mIcmp; }
IgmpProtocol* igmp() { return mIgmp; }
void loadProtocolWidgets();
void storeProtocolWidgets();
public:
enum FrameType {
@ -933,12 +85,15 @@ public:
// Methods
// -------------------------------------------------------
Stream();
~Stream();
void protoDataCopyFrom(Stream& stream);
bool operator < (const Stream &s) const
{ return(mCore->ordinal() < s.mCore->ordinal()); }
void getConfig(uint portId, OstProto::Stream *s);
void getConfig(uint portId, OstProto::Stream &s);
bool update(OstProto::Stream *stream);
quint32 id()
@ -968,23 +123,6 @@ public:
bool setName(QString name)
{ mCore->set_name(name.toStdString()); return true; }
FrameType frameType()
{ return (FrameType) mCore->ft(); }
bool setFrameType(FrameType frameType)
{ mCore->set_ft((OstProto::StreamCore::FrameType) frameType); return true; }
// Data Pattern
DataPatternMode patternMode()
{ return (DataPatternMode) mCore->pattern_mode(); }
bool setPatternMode(DataPatternMode patternMode)
{ mCore->set_pattern_mode(
(OstProto::StreamCore::DataPatternMode) patternMode); return true; }
quint32 pattern()
{ return mCore->pattern(); }
bool setPattern(quint32 pattern)
{ mCore->set_pattern(pattern); return true; }
// TODO(HI) : ?????
#if 0
quint16 dataStartOfs;
@ -1012,18 +150,6 @@ public:
bool setFrameLenMax(quint16 frameLenMax)
{ mCore->set_frame_len_max(frameLenMax); return true; }
L3Proto l3Proto()
{ return (L3Proto) mCore->l3_proto(); }
bool setL3Proto(L3Proto l3Proto)
{ mCore->set_l3_proto((OstProto::StreamCore::L3Proto) l3Proto);
return true; }
L4Proto l4Proto()
{ return (L4Proto) mCore->l4_proto(); }
bool setL4Proto(L4Proto l4Proto)
{ mCore->set_l4_proto((OstProto::StreamCore::L4Proto) l4Proto);
return true; }
SendUnit sendUnit()
{ return (SendUnit) mControl->unit(); }
bool setSendUnit(SendUnit sendUnit)
@ -1070,21 +196,12 @@ public:
//---------------------------------------------------------------
// Methods for use by Packet Model
//---------------------------------------------------------------
int numProtocols();
QList<int> frameProtocol();
void setFrameProtocol(QList<int> protocolList);
//! Includes ALL protocol headers excluding payload data
int protocolHeaderSize();
#if 0
int protocolId(int index);
int protocolIndex(int id);
#endif
AbstractProtocol* protocol(int index);
private:
QList<int> selectedProtocols;
int mProtocolHeaderSize;
void updateSelectedProtocols();
AbstractProtocol* protocolById(int id);
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@
/*
** TODO
** - Improve HexStr handling
** \todo Improve HexStr handling
**
*/
@ -31,9 +31,13 @@ private:
Port& mPort;
uint mCurrentStreamIndex;
Stream *mpStream;
QList<int> mSelectedProtocols;
PacketModel *mpPacketModel;
ModelTest *mpPacketModelTester;
// The following static variables are used to track the "selected" tab
// for the various tab widgets so that it can be restored when the dialog
// is opened the next time
@ -41,16 +45,12 @@ private:
static int lastProtoTabIndex;
void setupUiExtra();
void updateSelectedProtocols();
void LoadCurrentStream();
void StoreCurrentStream();
void StoreCurrentStream(Stream *pStream);
private slots:
void on_cmbPatternMode_currentIndexChanged(QString mode);
void on_cmbPktLenMode_currentIndexChanged(QString mode);
void on_cmbDstMacMode_currentIndexChanged(QString mode);
void on_cmbSrcMacMode_currentIndexChanged(QString mode);
void on_cmbIpSrcAddrMode_currentIndexChanged(QString mode);
void on_cmbIpDstAddrMode_currentIndexChanged(QString mode);
void on_pbPrev_clicked();
void on_pbNext_clicked();
@ -59,21 +59,20 @@ private slots:
void on_rbFt802Dot3Raw_toggled(bool checked);
void on_rbFt802Dot3Llc_toggled(bool checked);
void on_rbFtLlcSnap_toggled(bool checked);
void on_rbL3Ipv4_toggled(bool checked);
void on_rbL3Arp_toggled(bool checked);
void on_rbL4Icmp_toggled(bool checked);
void on_rbL4Igmp_toggled(bool checked);
void on_rbL4Tcp_toggled(bool checked);
void on_rbL4Udp_toggled(bool checked);
void on_twTopLevel_currentChanged(int index);
void on_twProto_currentChanged(int index);
void update_NumPacketsAndNumBursts();
void on_pbOk_clicked();
};
QString & uintToHexStr(quint64 num, QString &hexStr, quint8 octets);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -82,7 +82,7 @@ QVariant StreamModel::data(const QModelIndex &index, int role) const
case StreamName:
{
if ((role == Qt::DisplayRole) || (role == Qt::EditRole))
return mCurrentPort->streamByIndex(index.row()).name();
return mCurrentPort->streamByIndex(index.row())->name();
else
return QVariant();
break;
@ -91,7 +91,7 @@ QVariant StreamModel::data(const QModelIndex &index, int role) const
{
if ((role == Qt::CheckStateRole))
{
if (mCurrentPort->streamByIndex(index.row()).isEnabled())
if (mCurrentPort->streamByIndex(index.row())->isEnabled())
return Qt::Checked;
else
return Qt::Unchecked;
@ -102,7 +102,7 @@ QVariant StreamModel::data(const QModelIndex &index, int role) const
}
case StreamNextWhat:
{
int val = mCurrentPort->streamByIndex(index.row()).nextWhat();
int val = mCurrentPort->streamByIndex(index.row())->nextWhat();
if (role == Qt::DisplayRole)
return nextWhatOptionList().at(val);
@ -131,19 +131,19 @@ bool StreamModel::setData(const QModelIndex &index, const QVariant &value, int r
{
// Edit Supported Fields
case StreamName:
mCurrentPort->streamByIndex(index.row()).setName(value.toString());
mCurrentPort->streamByIndex(index.row())->setName(value.toString());
emit(dataChanged(index, index));
return true;
case StreamStatus:
mCurrentPort->streamByIndex(index.row()).setIsEnabled(value.toBool());
mCurrentPort->streamByIndex(index.row())->setIsEnabled(value.toBool());
emit(dataChanged(index, index));
return true;
case StreamNextWhat:
if (role == Qt::EditRole)
{
mCurrentPort->streamByIndex(index.row()).setNextWhat(
mCurrentPort->streamByIndex(index.row())->setNextWhat(
(Stream::NextWhat)value.toInt());
emit(dataChanged(index, index));
return true;

View File

@ -1,14 +0,0 @@
RM=del
PROTOC=protoc
#-#-#
all: protocol.pb.cc
protocol.pb.cc: protocol.proto
$(PROTOC) --cpp_out=. $<
clean:
$(RM) *.pb.h *.pb.cc
distclean: clean

225
common/abstractprotocol.cpp Normal file
View File

@ -0,0 +1,225 @@
#include "abstractprotocol.h"
/*!
\class AbstractProtocol
// FIXME - update this text
Bare Minimum set of methods that a subclass needs to reimplement
- protoDataCopyInto() [pure virtual]
- protoDataCopyFrom() [pure virtual]
- fieldCount()
Any useful protocol should also provide implementations for
- name()
- shortName()
- fieldName()
Protocols with meta fields should additionally implement
- metaFieldCount()
- isMetaField()
*/
AbstractProtocol::AbstractProtocol(Stream *parent)
{
stream = parent;
metaCount = -1;
}
AbstractProtocol::~AbstractProtocol()
{
}
/*!
\fn virtual void protoDataCopyInto(OstProto::Stream &stream) = 0;
Copy the protocol's protobuf into the passed in stream \n
In the base class this is a pure virtual function. Subclasses should
implement this function by using - \n
stream.AddExtension(<ExtId>)->CopyFrom(<protobuf_data>) */
/*
\fn virtual void protoDataCopyFrom(const OstProto::Stream &stream) = 0;
FIXME */
/*! Returns the full name of the protocol \n
The default implementation returns a null string */
QString AbstractProtocol::name() const
{
return QString();
}
/*! Returns the short name or abbreviation of the protocol \n
The default implementation forms and returns a abbreviation composed
of all the upper case chars in name() \n
The default implementation caches the abbreviation on its first invocation
and subsequently returns the cached abbreviation */
QString AbstractProtocol::shortName() const
{
if (protoAbbr.isNull())
{
QString abbr;
for (int i = 0; i < name().size(); i++)
if (name().at(i).isUpper()) abbr.append(name().at(i));
if (abbr.size())
protoAbbr = abbr;
else
protoAbbr = QString("");
}
return protoAbbr;
}
/*! Returns the number of fields (both Frame and Meta fields) \n
The default implementation returns zero */
int AbstractProtocol::fieldCount() const
{
return 0;
}
/*! Returns the number of meta fields \n
The default implementation counts and returns the number of fields for which
fieldData(index, FieldIsMeta) return true\n
The default implementation caches the count on its first invocation
and subsequently returns the cached count */
int AbstractProtocol::metaFieldCount() const
{
if (metaCount < 0)
{
int c = 0;
for (int i = 0; i < fieldCount() ; i++)
if (fieldData(i, FieldIsMeta).toBool())
c++;
metaCount = c;
}
return metaCount;
}
/*! Returns the number of frame fields \n
Convenience method - same as fieldCount() minus metaFieldCount() */
int AbstractProtocol::frameFieldCount() const
{
//qDebug("%s:%d, %d", __FUNCTION__, fieldCount(), metaFieldCount());
return (fieldCount() - metaFieldCount());
}
/*! Returns the requested field attribute data \n
Protocols which have meta fields that vary a frame field across
streams may use the streamIndex to return the appropriate field value \n
Some field attriubutes e.g. FieldName may be invariant across streams\n
The default implementation returns the fieldValue() converted to string
The FieldTextValue attribute may include additional information about
the field's value e.g. a checksum field may include "(correct)" or
"(incorrect)" alongwith the actual checksum value. \n
The default implementation returns FIXME
*/
QVariant AbstractProtocol::fieldData(int index, FieldAttrib attrib,
int streamIndex) const
{
switch (attrib)
{
case FieldName:
return QString();
case FieldBitSize:
return fieldData(index, FieldFrameValue, streamIndex).
toByteArray().size() * 8;
case FieldValue:
return 0;
case FieldFrameValue:
return QByteArray();
case FieldTextValue:
return QString();
case FieldIsMeta:
return false;
default:
qFatal("%s:%d: unhandled case %d\n", __FUNCTION__, __LINE__,
attrib);
}
return QVariant();
}
/*! Sets the value of a field corresponding to index \n
Returns true if field is successfully set, false otherwise \n
The default implementation always returns false */
bool AbstractProtocol::setFieldData(int index, const QVariant &value,
FieldAttrib attrib)
{
return false;
}
/*! Returns a byte array encoding the protocol (and its fields) which can be
inserted into the stream's frame
The default implementation forms and returns an ordered concatenation of
the FrameValue of all the 'frame' fields of the protocol taking care of fields
which are not an integral number of bytes\n */
QByteArray AbstractProtocol::protocolFrameValue(int streamIndex) const
{
QByteArray proto, field;
int bits, lastbitpos = 0;
for (int i=0; i < fieldCount() ; i++)
{
if (!fieldData(i, FieldIsMeta).toBool())
{
field = fieldData(i, FieldFrameValue, streamIndex).toByteArray();
bits = fieldData(i, FieldBitSize, streamIndex).toUInt();
if (bits == 0)
continue;
qDebug("<<< %d, %d >>>>", proto.size(), field.size());
if (bits == field.size() * 8)
{
if (lastbitpos == 0)
proto.append(field);
else
{
Q_ASSERT(field.size() > 0);
char c = proto[proto.size() - 1];
proto[proto.size() - 1] = c | (field.at(0) >> lastbitpos);
for (int j = 0; j < field.size() - 1; j++)
proto.append(field.at(j) << lastbitpos |
field.at(j+1) >> lastbitpos);
}
}
else if (bits < field.size() * 8)
{
int u, v;
u = bits / 8;
v = bits % 8;
if (lastbitpos == 0)
{
proto.append(field.left(u+1));
char c = proto[proto.size() - 1];
proto[proto.size() - 1] = c & (0xFF << (8 - v));
lastbitpos = v;
}
else
{
char c = proto[proto.size() - 1];
proto[proto.size() - 1] = c | (field.at(0) >> lastbitpos);
for (int j = 0; j < (u - 1); j++)
proto.append(field.at(j) << lastbitpos |
field.at(j+1) >> lastbitpos);
if (u)
proto.append( field.at(u) & (0xFF << (8 - v)) );
lastbitpos = (lastbitpos + bits) % 8;
}
}
else // if (bits > field.size() * 8)
{
qFatal("bitsize more than FrameValue size. skipping...");
continue;
}
}
}
return proto;
}

62
common/abstractprotocol.h Normal file
View File

@ -0,0 +1,62 @@
#ifndef _ABSTRACT_PROTOCOL_H
#define _ABSTRACT_PROTOCOL_H
#include <QString>
#include <QVariant>
#include <QByteArray>
#include <QWidget>
#include "../common/protocol.pb.h"
#define BASE_BIN (2)
#define BASE_OCT (8)
#define BASE_DEC (10)
#define BASE_HEX (16)
class Stream;
class AbstractProtocol
{
private:
mutable int metaCount;
mutable QString protoAbbr;
protected:
Stream *stream;
public:
enum FieldAttrib {
FieldName, //! name
FieldValue, //! value in host byte order (user editable)
FieldTextValue, //! value as text
FieldFrameValue, //! frame encoded value in network byte order
FieldBitSize, //! size in bits
FieldIsMeta //! bool indicating if field is meta
};
AbstractProtocol(Stream *parent = 0);
virtual ~AbstractProtocol();
virtual void protoDataCopyInto(OstProto::Stream &stream) = 0;
virtual void protoDataCopyFrom(const OstProto::Stream &stream) = 0;
virtual QString name() const;
virtual QString shortName() const;
virtual int fieldCount() const;
virtual int metaFieldCount() const;
int frameFieldCount() const;
virtual QVariant fieldData(int index, FieldAttrib attrib,
int streamIndex = 0) const;
virtual bool setFieldData(int index, const QVariant &value,
FieldAttrib attrib = FieldValue);
QByteArray protocolFrameValue(int streamIndex = 0) const;
virtual QWidget* configWidget() = 0;
virtual void loadConfigWidget() = 0;
virtual void storeConfigWidget() = 0;
};
#endif

110
common/dot3.cpp Normal file
View File

@ -0,0 +1,110 @@
#include <qendian.h>
#include <QHostAddress>
#include "Dot3.h"
Dot3ConfigForm *Dot3Protocol::configForm = NULL;
Dot3ConfigForm::Dot3ConfigForm(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
}
Dot3Protocol::Dot3Protocol(Stream *parent)
: AbstractProtocol(parent)
{
if (configForm == NULL)
configForm = new Dot3ConfigForm;
}
Dot3Protocol::~Dot3Protocol()
{
}
void Dot3Protocol::protoDataCopyInto(OstProto::Stream &stream)
{
// FIXME: multiple headers
stream.MutableExtension(OstProto::dot3)->CopyFrom(data);
}
void Dot3Protocol::protoDataCopyFrom(const OstProto::Stream &stream)
{
// FIXME: multiple headers
if (stream.HasExtension(OstProto::dot3))
data.MergeFrom(stream.GetExtension(OstProto::dot3));
}
QString Dot3Protocol::name() const
{
return QString("802.3");
}
QString Dot3Protocol::shortName() const
{
return QString("802.3");
}
int Dot3Protocol::fieldCount() const
{
return dot3_fieldCount;
}
QVariant Dot3Protocol::fieldData(int index, FieldAttrib attrib,
int streamIndex) const
{
switch (index)
{
case dot3_length:
switch(attrib)
{
case FieldName:
return QString("Length");
case FieldValue:
return data.length();
case FieldTextValue:
return QString("%1").arg(data.length());
case FieldFrameValue:
{
QByteArray fv;
fv.resize(2);
qToBigEndian((quint16) data.length(), (uchar*) fv.data());
return fv;
}
default:
break;
}
break;
default:
break;
}
return AbstractProtocol::fieldData(index, attrib, streamIndex);
}
bool Dot3Protocol::setFieldData(int index, const QVariant &value,
FieldAttrib attrib)
{
// FIXME
return false;
}
QWidget* Dot3Protocol::configWidget()
{
return configForm;
}
void Dot3Protocol::loadConfigWidget()
{
configForm->leLength->setText(QString().setNum(data.length()));
}
void Dot3Protocol::storeConfigWidget()
{
bool isOk;
data.set_length(configForm->leLength->text().toULong(&isOk));
}

50
common/dot3.h Normal file
View File

@ -0,0 +1,50 @@
#ifndef _DOT3_H
#define _DOT3_H
#include "abstractprotocol.h"
#include "dot3.pb.h"
#include "ui_Dot3.h"
class Dot3ConfigForm : public QWidget, public Ui::dot3
{
Q_OBJECT
public:
Dot3ConfigForm(QWidget *parent = 0);
};
class Dot3Protocol : public AbstractProtocol
{
private:
OstProto::Dot3 data;
static Dot3ConfigForm *configForm;
enum Dot3field
{
dot3_length,
dot3_fieldCount
};
public:
Dot3Protocol(Stream *parent = 0);
virtual ~Dot3Protocol();
virtual void protoDataCopyInto(OstProto::Stream &stream);
virtual void protoDataCopyFrom(const OstProto::Stream &stream);
virtual QString name() const;
virtual QString shortName() const;
virtual int fieldCount() const;
virtual QVariant fieldData(int index, FieldAttrib attrib,
int streamIndex = 0) const;
virtual bool setFieldData(int index, const QVariant &value,
FieldAttrib attrib = FieldValue);
virtual QWidget* configWidget();
virtual void loadConfigWidget();
virtual void storeConfigWidget();
};
#endif

12
common/dot3.proto Normal file
View File

@ -0,0 +1,12 @@
import "protocol.proto";
package OstProto;
// 802.3
message Dot3 {
optional uint32 length = 1;
}
extend Stream {
optional Dot3 dot3 = 122;
}

59
common/dot3.ui Normal file
View File

@ -0,0 +1,59 @@
<ui version="4.0" >
<class>dot3</class>
<widget class="QWidget" name="dot3" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>131</width>
<height>72</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
<layout class="QHBoxLayout" >
<item>
<widget class="QGroupBox" name="groupBox" >
<property name="title" >
<string>802.3</string>
</property>
<layout class="QHBoxLayout" >
<item>
<widget class="QLabel" name="lblLength" >
<property name="text" >
<string>Length</string>
</property>
<property name="buddy" >
<cstring>leLength</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="leLength" >
<property name="enabled" >
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

129
common/eth2.cpp Normal file
View File

@ -0,0 +1,129 @@
#include <qendian.h>
#include <QHostAddress>
#include "eth2.h"
Eth2ConfigForm *Eth2Protocol::configForm = NULL;
Eth2ConfigForm::Eth2ConfigForm(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
}
Eth2Protocol::Eth2Protocol(Stream *parent)
: AbstractProtocol(parent)
{
if (configForm == NULL)
configForm = new Eth2ConfigForm;
}
Eth2Protocol::~Eth2Protocol()
{
}
void Eth2Protocol::protoDataCopyInto(OstProto::Stream &stream)
{
// FIXME: multiple headers
stream.MutableExtension(OstProto::eth2)->CopyFrom(data);
}
void Eth2Protocol::protoDataCopyFrom(const OstProto::Stream &stream)
{
// FIXME: multiple headers
if (stream.HasExtension(OstProto::eth2))
data.MergeFrom(stream.GetExtension(OstProto::eth2));
}
QString Eth2Protocol::name() const
{
return QString("Ethernet II");
}
QString Eth2Protocol::shortName() const
{
return QString("Eth II");
}
int Eth2Protocol::fieldCount() const
{
return eth2_fieldCount;
}
QVariant Eth2Protocol::fieldData(int index, FieldAttrib attrib,
int streamIndex) const
{
switch (index)
{
case eth2_type:
switch(attrib)
{
case FieldName:
return QString("Type");
case FieldValue:
return data.type();
case FieldTextValue:
return QString("%1").arg(data.type(), 16);
case FieldFrameValue:
{
QByteArray fv;
fv.resize(2);
qToBigEndian((quint16) data.type(), (uchar*) fv.data());
return fv;
}
default:
break;
}
break;
default:
break;
}
return AbstractProtocol::fieldData(index, attrib, streamIndex);
}
bool Eth2Protocol::setFieldData(int index, const QVariant &value,
FieldAttrib attrib)
{
bool isOk = false;
if (attrib != FieldValue)
return false;
switch (index)
{
case eth2_type:
{
uint type = value.toUInt(&isOk);
if (isOk)
data.set_type(type);
}
default:
break;
}
return isOk;
}
QWidget* Eth2Protocol::configWidget()
{
return configForm;
}
void Eth2Protocol::loadConfigWidget()
{
#define uintToHexStr(num, bytesize) \
QString("%1").arg((num), (bytesize)*2 , 16, QChar('0'))
configForm->leType->setText(uintToHexStr(data.type(), 2));
#undef uintToHexStr
}
void Eth2Protocol::storeConfigWidget()
{
bool isOk;
data.set_type(configForm->leType->text().remove(QChar(' ')).toULong(&isOk, 16));
}

50
common/eth2.h Normal file
View File

@ -0,0 +1,50 @@
#ifndef _ETH2_H
#define _ETH2_H
#include "abstractprotocol.h"
#include "eth2.pb.h"
#include "ui_eth2.h"
class Eth2ConfigForm : public QWidget, public Ui::eth2
{
Q_OBJECT
public:
Eth2ConfigForm(QWidget *parent = 0);
};
class Eth2Protocol : public AbstractProtocol
{
private:
OstProto::Eth2 data;
static Eth2ConfigForm *configForm;
enum eth2field
{
eth2_type = 0,
eth2_fieldCount
};
public:
Eth2Protocol(Stream *parent = 0);
virtual ~Eth2Protocol();
virtual void protoDataCopyInto(OstProto::Stream &stream);
virtual void protoDataCopyFrom(const OstProto::Stream &stream);
virtual QString name() const;
virtual QString shortName() const;
virtual int fieldCount() const;
virtual QVariant fieldData(int index, FieldAttrib attrib,
int streamIndex = 0) const;
virtual bool setFieldData(int index, const QVariant &value,
FieldAttrib attrib = FieldValue);
virtual QWidget* configWidget();
virtual void loadConfigWidget();
virtual void storeConfigWidget();
};
#endif

12
common/eth2.proto Normal file
View File

@ -0,0 +1,12 @@
import "protocol.proto";
package OstProto;
// Ethernet II
message Eth2 {
optional uint32 type = 1;
}
extend Stream {
optional Eth2 eth2 = 121;
}

62
common/eth2.ui Normal file
View File

@ -0,0 +1,62 @@
<ui version="4.0" >
<class>eth2</class>
<widget class="QWidget" name="eth2" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>166</width>
<height>72</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
<layout class="QHBoxLayout" >
<item>
<widget class="QGroupBox" name="groupBox" >
<property name="title" >
<string>Ethernet II</string>
</property>
<layout class="QHBoxLayout" >
<item>
<widget class="QLabel" name="lblType" >
<property name="text" >
<string>Ethernet Type</string>
</property>
<property name="buddy" >
<cstring>leType</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="leType" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="inputMask" >
<string>HH HH; </string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

455
common/ip4.cpp Normal file
View File

@ -0,0 +1,455 @@
#include <qendian.h>
#include <QHostAddress>
#include "ip4.h"
Ip4ConfigForm *Ip4Protocol::configForm = NULL;
Ip4ConfigForm::Ip4ConfigForm(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
connect(cmbIpSrcAddrMode, SIGNAL(currentIndexChanged(int)),
this, SLOT(on_cmbIpSrcAddrMode_currentIndexChanged(int)));
connect(cmbIpDstAddrMode, SIGNAL(currentIndexChanged(int)),
this, SLOT(on_cmbIpDstAddrMode_currentIndexChanged(int)));
}
void Ip4ConfigForm::on_cmbIpSrcAddrMode_currentIndexChanged(int index)
{
if (index == OstProto::Ip4::e_im_fixed)
{
leIpSrcAddrCount->setDisabled(true);
leIpSrcAddrMask->setDisabled(true);
}
else
{
leIpSrcAddrCount->setEnabled(true);
leIpSrcAddrMask->setEnabled(true);
}
}
void Ip4ConfigForm::on_cmbIpDstAddrMode_currentIndexChanged(int index)
{
if (index == OstProto::Ip4::e_im_fixed)
{
leIpDstAddrCount->setDisabled(true);
leIpDstAddrMask->setDisabled(true);
}
else
{
leIpDstAddrCount->setEnabled(true);
leIpDstAddrMask->setEnabled(true);
}
}
Ip4Protocol::Ip4Protocol(Stream *parent)
: AbstractProtocol(parent)
{
if (configForm == NULL)
configForm = new Ip4ConfigForm;
}
Ip4Protocol::~Ip4Protocol()
{
}
void Ip4Protocol::protoDataCopyInto(OstProto::Stream &stream)
{
// FIXME: multiple headers
stream.MutableExtension(OstProto::ip4)->CopyFrom(data);
}
void Ip4Protocol::protoDataCopyFrom(const OstProto::Stream &stream)
{
// FIXME: multiple headers
if (stream.HasExtension(OstProto::ip4))
data.MergeFrom(stream.GetExtension(OstProto::ip4));
}
QString Ip4Protocol::name() const
{
return QString("Internet Protocol ver 4");
}
QString Ip4Protocol::shortName() const
{
return QString("IPv4");
}
int Ip4Protocol::fieldCount() const
{
return ip4_fieldCount;
}
QVariant Ip4Protocol::fieldData(int index, FieldAttrib attrib,
int streamIndex) const
{
switch (index)
{
case ip4_ver:
switch(attrib)
{
case FieldName:
return QString("Version");
case FieldValue:
return (data.ver_hdrlen() >> 4) & 0x0F;
case FieldTextValue:
return QString("%1").arg((data.ver_hdrlen() >> 4) & 0x0F);
case FieldFrameValue:
return QByteArray(1, (char)(data.ver_hdrlen() & 0xF0));
case FieldBitSize:
return 4;
default:
break;
}
break;
case ip4_hdrLen:
switch(attrib)
{
case FieldName:
return QString("Header Length");
case FieldValue:
return data.ver_hdrlen() & 0x0F;
case FieldTextValue:
return QString("%1").arg(data.ver_hdrlen() & 0x0F);
case FieldFrameValue:
return QByteArray(1, (char)(data.ver_hdrlen() << 4));
case FieldBitSize:
return 4;
default:
break;
}
break;
case ip4_tos:
switch(attrib)
{
case FieldName:
return QString("TOS/DSCP");
case FieldValue:
return data.tos();
case FieldFrameValue:
return QByteArray(1, (char) data.tos());
case FieldTextValue:
return QString("0x%1").
arg(data.tos(), 2, BASE_HEX, QChar('0'));;
default:
break;
}
break;
case ip4_totLen:
switch(attrib)
{
case FieldName:
return QString("Total Length");
case FieldValue:
return data.totlen();
case FieldFrameValue:
{
QByteArray fv;
fv.resize(2);
qToBigEndian((quint16) data.totlen(), (uchar*) fv.data());
return fv;
}
case FieldTextValue:
return QString("%1").arg(data.totlen());
default:
break;
}
break;
case ip4_id:
switch(attrib)
{
case FieldName:
return QString("Identification");
case FieldValue:
return data.id();
case FieldFrameValue:
{
QByteArray fv;
fv.resize(2);
qToBigEndian((quint16) data.id(), (uchar*)fv.data());
return fv;
}
case FieldTextValue:
return QString("0x%1").
arg(data.id(), 2, BASE_HEX, QChar('0'));;
default:
break;
}
break;
case ip4_flags:
switch(attrib)
{
case FieldName:
return QString("Flags");
case FieldValue:
return data.flags();
case FieldFrameValue:
return QByteArray(1, (char) data.flags());
case FieldTextValue:
{
QString s;
s.append("Unused:");
s.append(data.flags() & IP_FLAG_UNUSED ? "1" : "0");
s.append(" Don't Fragment:");
s.append(data.flags() & IP_FLAG_DF ? "1" : "0");
s.append(" More Fragments:");
s.append(data.flags() & IP_FLAG_MF ? "1" : "0");
return s;
}
case FieldBitSize:
return 3;
default:
break;
}
break;
case ip4_fragOfs:
switch(attrib)
{
case FieldName:
return QString("Fragment Offset");
case FieldValue:
return data.frag_ofs();
case FieldFrameValue:
{
QByteArray fv;
// FIXME need to shift for 13 bits
fv.resize(2);
qToBigEndian((quint16) data.frag_ofs(), (uchar*) fv.data());
return fv;
}
case FieldTextValue:
return QString("%1").arg(data.frag_ofs());
case FieldBitSize:
return 13;
default:
break;
}
break;
case ip4_ttl:
switch(attrib)
{
case FieldName:
return QString("Time to Live");
case FieldValue:
return data.ttl();
case FieldFrameValue:
return QByteArray(1, (char)data.ttl());
case FieldTextValue:
return QString("%1").arg(data.ttl());
default:
break;
}
break;
case ip4_proto:
switch(attrib)
{
case FieldName:
return QString("Protocol");
case FieldValue:
return data.proto();
case FieldFrameValue:
return QByteArray(1, (char)data.proto());
case FieldTextValue:
return QString("0x%1").
arg(data.proto(), 2, BASE_HEX, QChar('0'));
default:
break;
}
break;
case ip4_cksum:
switch(attrib)
{
case FieldName:
return QString("Header Checksum");
case FieldValue:
return data.cksum();
case FieldFrameValue:
{
QByteArray fv;
fv.resize(2);
qToBigEndian((quint16) data.cksum(), (uchar*) fv.data());
return fv;
}
case FieldTextValue:
return QString("0x%1").
arg(data.cksum(), 4, BASE_HEX, QChar('0'));;
default:
break;
}
break;
case ip4_srcAddr:
switch(attrib)
{
case FieldName:
return QString("Source");
case FieldValue:
return data.src_ip();
case FieldFrameValue:
{
QByteArray fv;
fv.resize(4);
qToBigEndian((quint32) data.src_ip(), (uchar*) fv.data());
return fv;
}
case FieldTextValue:
return QHostAddress(data.src_ip()).toString();
default:
break;
}
break;
case ip4_dstAddr:
switch(attrib)
{
case FieldName:
return QString("Destination");
case FieldValue:
return data.dst_ip();
case FieldFrameValue:
{
QByteArray fv;
fv.resize(4);
qToBigEndian((quint32) data.dst_ip(), (uchar*) fv.data());
return fv;
}
case FieldTextValue:
return QHostAddress(data.dst_ip()).toString();
default:
break;
}
break;
// Meta fields
case ip4_isOverrideVer:
case ip4_isOverrideHdrLen:
case ip4_isOverrideTotLen:
case ip4_isOverrideCksum:
case ip4_srcAddrMode:
case ip4_srcAddrCount:
case ip4_srcAddrMask:
case ip4_dstAddrMode:
case ip4_dstAddrCount:
case ip4_dstAddrMask:
switch(attrib)
{
case FieldIsMeta:
return true;
default:
break;
}
break;
default:
break;
}
return AbstractProtocol::fieldData(index, attrib, streamIndex);
}
bool Ip4Protocol::setFieldData(int index, const QVariant &value,
FieldAttrib attrib)
{
bool isOk = false;
if (attrib != FieldValue)
return false;
switch (index)
{
case ip4_proto:
{
uint proto = value.toUInt(&isOk);
if (isOk)
data.set_proto(proto);
}
default:
break;
}
return isOk;
}
QWidget* Ip4Protocol::configWidget()
{
return configForm;
}
void Ip4Protocol::loadConfigWidget()
{
#define uintToHexStr(num, str, size) QString().setNum(num, 16)
configForm->leIpVersion->setText(QString().setNum(data.ver_hdrlen() >> 4));
configForm->cbIpVersionOverride->setChecked(data.is_override_ver());
configForm->leIpHdrLen->setText(QString().setNum(data.ver_hdrlen() & 0x0F));
configForm->cbIpHdrLenOverride->setChecked(data.is_override_hdrlen());
configForm->leIpTos->setText(uintToHexStr(data.tos(), QString(), 1));
configForm->leIpLength->setText(QString().setNum(data.totlen()));
configForm->cbIpLengthOverride->setChecked(data.is_override_totlen());
configForm->leIpId->setText(uintToHexStr(data.id(), QString(), 2));
configForm->leIpFragOfs->setText(QString().setNum(data.frag_ofs()));
configForm->cbIpFlagsDf->setChecked((data.flags() & IP_FLAG_DF) > 0);
configForm->cbIpFlagsMf->setChecked((data.flags() & IP_FLAG_MF) > 0);
configForm->leIpTtl->setText(QString().setNum(data.ttl()));
configForm->leIpProto->setText(uintToHexStr(data.proto(), QString(), 1));
configForm->leIpCksum->setText(uintToHexStr(data.cksum(), QString(), 2));
configForm->cbIpCksumOverride->setChecked(data.is_override_cksum());
configForm->leIpSrcAddr->setText(QHostAddress(data.src_ip()).toString());
configForm->cmbIpSrcAddrMode->setCurrentIndex(data.src_ip_mode());
configForm->leIpSrcAddrCount->setText(QString().setNum(data.src_ip_count()));
configForm->leIpSrcAddrMask->setText(QHostAddress(data.src_ip_mask()).toString());
configForm->leIpDstAddr->setText(QHostAddress(data.dst_ip()).toString());
configForm->cmbIpDstAddrMode->setCurrentIndex(data.dst_ip_mode());
configForm->leIpDstAddrCount->setText(QString().setNum(data.dst_ip_count()));
configForm->leIpDstAddrMask->setText(QHostAddress(data.dst_ip_mask()).toString());
}
void Ip4Protocol::storeConfigWidget()
{
uint ff = 0;
bool isOk;
data.set_is_override_ver(configForm->cbIpVersionOverride->isChecked());
data.set_ver_hdrlen(((configForm->leIpVersion->text().toULong(&isOk) & 0x0F) << 4) |
(configForm->leIpHdrLen->text().toULong(&isOk) & 0x0F));
data.set_is_override_hdrlen(configForm->cbIpHdrLenOverride->isChecked());
data.set_tos(configForm->leIpTos->text().toULong(&isOk, 16));
data.set_totlen(configForm->leIpLength->text().toULong(&isOk));
data.set_is_override_totlen(configForm->cbIpLengthOverride->isChecked());
data.set_id(configForm->leIpId->text().remove(QChar(' ')).toULong(&isOk, 16));
data.set_frag_ofs(configForm->leIpFragOfs->text().toULong(&isOk));
if (configForm->cbIpFlagsDf->isChecked()) ff |= IP_FLAG_DF;
if (configForm->cbIpFlagsMf->isChecked()) ff |= IP_FLAG_MF;
data.set_flags(ff);
data.set_ttl(configForm->leIpTtl->text().toULong(&isOk));
data.set_proto(configForm->leIpProto->text().remove(QChar(' ')).toULong(&isOk, 16));
data.set_cksum(configForm->leIpCksum->text().remove(QChar(' ')).toULong(&isOk));
data.set_is_override_cksum(configForm->cbIpCksumOverride->isChecked());
data.set_src_ip(QHostAddress(configForm->leIpSrcAddr->text()).toIPv4Address());
data.set_src_ip_mode((OstProto::Ip4_IpAddrMode)configForm->cmbIpSrcAddrMode->currentIndex());
data.set_src_ip_count(configForm->leIpSrcAddrCount->text().toULong(&isOk));
data.set_src_ip_mask(QHostAddress(configForm->leIpSrcAddrMask->text()).toIPv4Address());
data.set_dst_ip(QHostAddress(configForm->leIpDstAddr->text()).toIPv4Address());
data.set_dst_ip_mode((OstProto::Ip4_IpAddrMode)configForm->cmbIpDstAddrMode->currentIndex());
data.set_dst_ip_count(configForm->leIpDstAddrCount->text().toULong(&isOk));
}

83
common/ip4.h Normal file
View File

@ -0,0 +1,83 @@
#ifndef _IPV4_H
#define _IPV4_H
#include "abstractprotocol.h"
#include "ip4.pb.h"
#include "ui_ip4.h"
#define IP_FLAG_UNUSED 0x1
#define IP_FLAG_DF 0x2
#define IP_FLAG_MF 0x4
class Ip4ConfigForm : public QWidget, public Ui::ip4
{
Q_OBJECT
public:
Ip4ConfigForm(QWidget *parent = 0);
private slots:
void on_cmbIpSrcAddrMode_currentIndexChanged(int index);
void on_cmbIpDstAddrMode_currentIndexChanged(int index);
};
class Ip4Protocol : public AbstractProtocol
{
private:
OstProto::Ip4 data;
static Ip4ConfigForm *configForm;
enum ip4field
{
ip4_ver = 0,
ip4_hdrLen,
ip4_tos,
ip4_totLen,
ip4_id,
ip4_flags,
ip4_fragOfs,
ip4_ttl,
ip4_proto,
ip4_cksum,
ip4_srcAddr,
ip4_dstAddr,
ip4_isOverrideVer,
ip4_isOverrideHdrLen,
ip4_isOverrideTotLen,
ip4_isOverrideCksum,
ip4_srcAddrMode,
ip4_srcAddrCount,
ip4_srcAddrMask,
ip4_dstAddrMode,
ip4_dstAddrCount,
ip4_dstAddrMask,
ip4_fieldCount
};
public:
Ip4Protocol(Stream *parent = 0);
virtual ~Ip4Protocol();
virtual void protoDataCopyInto(OstProto::Stream &stream);
virtual void protoDataCopyFrom(const OstProto::Stream &stream);
virtual QString name() const;
virtual QString shortName() const;
virtual int fieldCount() const;
virtual QVariant fieldData(int index, FieldAttrib attrib,
int streamIndex = 0) const;
virtual bool setFieldData(int index, const QVariant &value,
FieldAttrib attrib = FieldValue);
virtual QWidget* configWidget();
virtual void loadConfigWidget();
virtual void storeConfigWidget();
};
#endif

47
common/ip4.proto Normal file
View File

@ -0,0 +1,47 @@
import "protocol.proto";
package OstProto;
// IPv4
message Ip4 {
enum IpAddrMode {
e_im_fixed = 0;
e_im_inc_host = 1;
e_im_dec_host = 2;
e_im_random_host = 3;
}
optional bool is_override_ver = 1;
optional bool is_override_hdrlen = 2;
optional bool is_override_totlen = 3;
optional bool is_override_cksum = 4;
optional uint32 ver_hdrlen = 5 [default = 0x45];
optional uint32 tos = 6;
optional uint32 totlen = 7;
optional uint32 id = 8 [default = 1234];
// TODO: rename flags to frag_flags
optional uint32 flags = 9;
optional uint32 frag_ofs = 10;
optional uint32 ttl = 11 [default = 127];
optional uint32 proto = 12;
optional uint32 cksum = 13;
// Source IP
optional fixed32 src_ip = 14;
optional IpAddrMode src_ip_mode = 15 [default = e_im_fixed];
optional uint32 src_ip_count = 16 [default = 16];
optional fixed32 src_ip_mask = 17 [default = 0xFFFFFFFF];
// Destination IP
optional fixed32 dst_ip = 18;
optional IpAddrMode dst_ip_mode = 19 [default = e_im_fixed];
optional uint32 dst_ip_count = 20 [default = 16];
optional fixed32 dst_ip_mask = 21 [default = 0xFFFFFFFF];
// TODO: Options
}
extend Stream {
optional Ip4 ip4 = 130;
}

479
common/ip4.ui Normal file
View File

@ -0,0 +1,479 @@
<ui version="4.0" >
<class>ip4</class>
<widget class="QWidget" name="ip4" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>504</width>
<height>296</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" >
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QCheckBox" name="cbIpVersionOverride" >
<property name="text" >
<string>Override Version</string>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QLineEdit" name="leIpVersion" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>4</string>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QCheckBox" name="cbIpHdrLenOverride" >
<property name="text" >
<string>Override Header Length</string>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QLineEdit" name="leIpHdrLen" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>5</string>
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QLabel" name="label_22" >
<property name="text" >
<string>TOS/DSCP</string>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QLineEdit" name="leIpTos" >
<property name="inputMask" >
<string>HH; </string>
</property>
<property name="text" >
<string/>
</property>
</widget>
</item>
<item row="2" column="2" >
<widget class="QToolButton" name="toolButton" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>...</string>
</property>
</widget>
</item>
<item row="3" column="0" >
<widget class="QCheckBox" name="cbIpLengthOverride" >
<property name="text" >
<string>Override Length</string>
</property>
</widget>
</item>
<item row="3" column="1" >
<widget class="QLineEdit" name="leIpLength" >
<property name="enabled" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="4" column="0" >
<widget class="QLabel" name="label_24" >
<property name="text" >
<string>Identification</string>
</property>
</widget>
</item>
<item row="4" column="1" >
<widget class="QLineEdit" name="leIpId" >
<property name="inputMask" >
<string>HH HH; </string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1" >
<widget class="Line" name="line_2" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item row="0" column="2" >
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="label_25" >
<property name="text" >
<string>Fragment Offset</string>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QLineEdit" name="leIpFragOfs" />
</item>
<item row="1" column="0" >
<widget class="QCheckBox" name="cbIpFlagsDf" >
<property name="text" >
<string>Don't Fragment</string>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QCheckBox" name="cbIpFlagsMf" >
<property name="text" >
<string>More Fragments</string>
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QLabel" name="label_26" >
<property name="text" >
<string>Time To Live (TTL)</string>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QLineEdit" name="leIpTtl" >
<property name="text" >
<string>64</string>
</property>
</widget>
</item>
<item row="3" column="0" >
<widget class="QLabel" name="label_27" >
<property name="text" >
<string>Protocol</string>
</property>
</widget>
</item>
<item row="3" column="1" >
<widget class="QLineEdit" name="leIpProto" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string/>
</property>
</widget>
</item>
<item row="4" column="0" >
<widget class="QCheckBox" name="cbIpCksumOverride" >
<property name="text" >
<string>Override Checksum</string>
</property>
</widget>
</item>
<item row="4" column="1" >
<widget class="QLineEdit" name="leIpCksum" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="inputMask" >
<string>HH HH; </string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0" colspan="3" >
<widget class="QGroupBox" name="groupBox_7" >
<property name="title" >
<string/>
</property>
<property name="flat" >
<bool>false</bool>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" colspan="2" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>101</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="2" >
<widget class="QLabel" name="label_31" >
<property name="text" >
<string>Mode</string>
</property>
</widget>
</item>
<item row="0" column="3" >
<widget class="QLabel" name="label_23" >
<property name="text" >
<string>Count</string>
</property>
</widget>
</item>
<item row="0" column="4" >
<widget class="QLabel" name="label_30" >
<property name="text" >
<string>Mask</string>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="label_20" >
<property name="text" >
<string>Source</string>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QLineEdit" name="leIpSrcAddr" >
<property name="inputMask" >
<string>009.009.009.009; </string>
</property>
<property name="text" >
<string>...</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="2" >
<widget class="QComboBox" name="cmbIpSrcAddrMode" >
<item>
<property name="text" >
<string>Fixed</string>
</property>
</item>
<item>
<property name="text" >
<string>Increment Host</string>
</property>
</item>
<item>
<property name="text" >
<string>Decrement Host</string>
</property>
</item>
<item>
<property name="text" >
<string>Random Host</string>
</property>
</item>
</widget>
</item>
<item row="1" column="3" >
<widget class="QLineEdit" name="leIpSrcAddrCount" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string/>
</property>
</widget>
</item>
<item row="1" column="4" >
<widget class="QLineEdit" name="leIpSrcAddrMask" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>255.255.255.255</string>
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QLabel" name="label_21" >
<property name="text" >
<string>Destination</string>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QLineEdit" name="leIpDstAddr" >
<property name="inputMask" >
<string>000.000.000.000; </string>
</property>
<property name="text" >
<string>...</string>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="2" >
<widget class="QComboBox" name="cmbIpDstAddrMode" >
<item>
<property name="text" >
<string>Fixed</string>
</property>
</item>
<item>
<property name="text" >
<string>Increment Host</string>
</property>
</item>
<item>
<property name="text" >
<string>Decrement Host</string>
</property>
</item>
<item>
<property name="text" >
<string>Random Host</string>
</property>
</item>
</widget>
</item>
<item row="2" column="3" >
<widget class="QLineEdit" name="leIpDstAddrCount" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string/>
</property>
</widget>
</item>
<item row="2" column="4" >
<widget class="QLineEdit" name="leIpDstAddrMask" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>255.255.255.255</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0" colspan="3" >
<layout class="QHBoxLayout" >
<item>
<widget class="QLabel" name="label_29" >
<property name="text" >
<string>Options</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="leIpOptions" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>TODO</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="tbIpOptionsEdit" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="1" >
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>cbIpVersionOverride</sender>
<signal>toggled(bool)</signal>
<receiver>leIpVersion</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>108</x>
<y>11</y>
</hint>
<hint type="destinationlabel" >
<x>195</x>
<y>11</y>
</hint>
</hints>
</connection>
<connection>
<sender>cbIpHdrLenOverride</sender>
<signal>toggled(bool)</signal>
<receiver>leIpHdrLen</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>118</x>
<y>43</y>
</hint>
<hint type="destinationlabel" >
<x>166</x>
<y>43</y>
</hint>
</hints>
</connection>
<connection>
<sender>cbIpLengthOverride</sender>
<signal>toggled(bool)</signal>
<receiver>leIpLength</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>79</x>
<y>97</y>
</hint>
<hint type="destinationlabel" >
<x>172</x>
<y>97</y>
</hint>
</hints>
</connection>
<connection>
<sender>cbIpCksumOverride</sender>
<signal>toggled(bool)</signal>
<receiver>leIpCksum</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>345</x>
<y>122</y>
</hint>
<hint type="destinationlabel" >
<x>406</x>
<y>122</y>
</hint>
</hints>
</connection>
</connections>
</ui>

139
common/llc.cpp Normal file
View File

@ -0,0 +1,139 @@
#include <qendian.h>
#include <QHostAddress>
#include "llc.h"
LlcConfigForm *LlcProtocol::configForm = NULL;
LlcConfigForm::LlcConfigForm(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
}
LlcProtocol::LlcProtocol(Stream *parent)
: AbstractProtocol(parent)
{
if (configForm == NULL)
configForm = new LlcConfigForm;
}
LlcProtocol::~LlcProtocol()
{
}
void LlcProtocol::protoDataCopyInto(OstProto::Stream &stream)
{
// FIXME: multiple headers
stream.MutableExtension(OstProto::llc)->CopyFrom(data);
}
void LlcProtocol::protoDataCopyFrom(const OstProto::Stream &stream)
{
// FIXME: multiple headers
if (stream.HasExtension(OstProto::llc))
data.MergeFrom(stream.GetExtension(OstProto::llc));
}
QString LlcProtocol::name() const
{
return QString("802.3 Logical Link Control");
}
QString LlcProtocol::shortName() const
{
return QString("LLC");
}
int LlcProtocol::fieldCount() const
{
return llc_fieldCount;
}
QVariant LlcProtocol::fieldData(int index, FieldAttrib attrib,
int streamIndex) const
{
switch (index)
{
case llc_dsap:
switch(attrib)
{
case FieldName:
return QString("DSAP");
case FieldValue:
return data.dsap();
case FieldTextValue:
return QString("%1").arg(data.dsap(), BASE_HEX);
case FieldFrameValue:
return QByteArray(1, (char)(data.dsap()));
default:
break;
}
break;
case llc_ssap:
switch(attrib)
{
case FieldName:
return QString("DSAP");
case FieldValue:
return data.ssap();
case FieldTextValue:
return QString("%1").arg(data.ssap(), BASE_HEX);
case FieldFrameValue:
return QByteArray(1, (char)(data.ssap()));
default:
break;
}
break;
case llc_ctl:
switch(attrib)
{
case FieldName:
return QString("DSAP");
case FieldValue:
return data.ctl();
case FieldTextValue:
return QString("%1").arg(data.ctl(), BASE_HEX);
case FieldFrameValue:
return QByteArray(1, (char)(data.ctl()));
default:
break;
}
break;
default:
break;
}
return AbstractProtocol::fieldData(index, attrib, streamIndex);
}
bool LlcProtocol::setFieldData(int index, const QVariant &value,
FieldAttrib attrib)
{
// FIXME
return false;
}
QWidget* LlcProtocol::configWidget()
{
return configForm;
}
void LlcProtocol::loadConfigWidget()
{
configForm->leDsap->setText(QString("%1").arg(data.dsap(), 2, BASE_HEX, QChar('0')));
configForm->leSsap->setText(QString("%1").arg(data.ssap(), 2, BASE_HEX, QChar('0')));
configForm->leControl->setText(QString("%1").arg(data.ctl(), 2, BASE_HEX, QChar('0')));
}
void LlcProtocol::storeConfigWidget()
{
bool isOk;
data.set_dsap(configForm->leDsap->text().toULong(&isOk, BASE_HEX));
data.set_ssap(configForm->leSsap->text().toULong(&isOk, BASE_HEX));
data.set_ctl(configForm->leControl->text().toULong(&isOk, BASE_HEX));
}

55
common/llc.h Normal file
View File

@ -0,0 +1,55 @@
#ifndef _LLC_H
#define _LLC_H
#include <QSize>
#include <qdebug.h>
#include "abstractprotocol.h"
#include "llc.pb.h"
#include "ui_llc.h"
class LlcConfigForm : public QWidget, public Ui::llc
{
Q_OBJECT
public:
LlcConfigForm(QWidget *parent = 0);
};
class LlcProtocol : public AbstractProtocol
{
private:
OstProto::Llc data;
static LlcConfigForm *configForm;
enum llcfield
{
llc_dsap = 0,
llc_ssap,
llc_ctl,
llc_fieldCount
};
public:
LlcProtocol(Stream *parent = 0);
virtual ~LlcProtocol();
virtual void protoDataCopyInto(OstProto::Stream &stream);
virtual void protoDataCopyFrom(const OstProto::Stream &stream);
virtual QString name() const;
virtual QString shortName() const;
virtual int fieldCount() const;
virtual QVariant fieldData(int index, FieldAttrib attrib,
int streamIndex = 0) const;
virtual bool setFieldData(int index, const QVariant &value,
FieldAttrib attrib = FieldValue);
virtual QWidget* configWidget();
virtual void loadConfigWidget();
virtual void storeConfigWidget();
};
#endif

13
common/llc.proto Normal file
View File

@ -0,0 +1,13 @@
import "protocol.proto";
package OstProto;
message Llc {
optional uint32 dsap = 1;
optional uint32 ssap = 2;
optional uint32 ctl = 3;
}
extend Stream {
optional Llc llc = 123;
}

108
common/llc.ui Normal file
View File

@ -0,0 +1,108 @@
<ui version="4.0" >
<class>llc</class>
<widget class="QWidget" name="llc" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>304</width>
<height>72</height>
</rect>
</property>
<property name="sizePolicy" >
<sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
<layout class="QHBoxLayout" >
<item>
<widget class="QGroupBox" name="groupBox" >
<property name="title" >
<string>LLC</string>
</property>
<layout class="QHBoxLayout" >
<item>
<widget class="QLabel" name="lblDsap" >
<property name="text" >
<string>DSAP</string>
</property>
<property name="buddy" >
<cstring>leDsap</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="leDsap" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="inputMask" >
<string>HH; </string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblSsap" >
<property name="text" >
<string>SSAP</string>
</property>
<property name="buddy" >
<cstring>leSsap</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="leSsap" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="inputMask" >
<string>HH; </string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblControl" >
<property name="text" >
<string>Control</string>
</property>
<property name="buddy" >
<cstring>leControl</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="leControl" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="inputMask" >
<string>HH; </string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

207
common/mac.cpp Normal file
View File

@ -0,0 +1,207 @@
#include <qendian.h>
#include <QHostAddress>
#include "mac.h"
MacConfigForm *MacProtocol::configForm = NULL;
MacConfigForm::MacConfigForm(QWidget *parent)
: QWidget(parent)
{
QRegExp reMac("([0-9,a-f,A-F]{2,2}[:-]){5,5}[0-9,a-f,A-F]{2,2}");
setupUi(this);
leDstMac->setValidator(new QRegExpValidator(reMac, this));
leSrcMac->setValidator(new QRegExpValidator(reMac, this));
leDstMacCount->setValidator(new QIntValidator(1, MAX_MAC_ITER_COUNT, this));
leSrcMacCount->setValidator(new QIntValidator(1, MAX_MAC_ITER_COUNT, this));
}
void MacConfigForm::on_cmbDstMacMode_currentIndexChanged(int index)
{
if (index == OstProto::Mac::e_mm_fixed)
{
leDstMacCount->setEnabled(false);
leDstMacStep->setEnabled(false);
}
else
{
leDstMacCount->setEnabled(true);
leDstMacStep->setEnabled(true);
}
}
void MacConfigForm::on_cmbSrcMacMode_currentIndexChanged(int index)
{
if (index == OstProto::Mac::e_mm_fixed)
{
leSrcMacCount->setEnabled(false);
leSrcMacStep->setEnabled(false);
}
else
{
leSrcMacCount->setEnabled(true);
leSrcMacStep->setEnabled(true);
}
}
MacProtocol::MacProtocol(Stream *parent)
: AbstractProtocol(parent)
{
if (configForm == NULL)
configForm = new MacConfigForm;
}
MacProtocol::~MacProtocol()
{
}
void MacProtocol::protoDataCopyInto(OstProto::Stream &stream)
{
// FIXME: multiple headers
stream.MutableExtension(OstProto::mac)->CopyFrom(data);
}
void MacProtocol::protoDataCopyFrom(const OstProto::Stream &stream)
{
// FIXME: multiple headers
if (stream.HasExtension(OstProto::mac))
data.MergeFrom(stream.GetExtension(OstProto::mac));
}
QString MacProtocol::name() const
{
return QString("Media Access Protocol");
}
QString MacProtocol::shortName() const
{
return QString("MAC");
}
int MacProtocol::fieldCount() const
{
return mac_fieldCount;
}
QVariant MacProtocol::fieldData(int index, FieldAttrib attrib,
int streamIndex) const
{
switch (index)
{
case mac_dstAddr:
switch(attrib)
{
case FieldName:
return QString("Desination");
case FieldValue:
return data.dst_mac();
case FieldTextValue:
return QString("%1").arg(data.dst_mac(), 12, BASE_HEX,
QChar('0'));
case FieldFrameValue:
{
QByteArray fv;
fv.resize(8);
qToBigEndian((quint64) data.dst_mac(), (uchar*) fv.data());
fv.remove(0, 2);
return fv;
}
default:
break;
}
break;
case mac_srcAddr:
switch(attrib)
{
case FieldName:
return QString("Source");
case FieldValue:
return data.src_mac();
case FieldTextValue:
return QString("%1").arg(data.src_mac(), 12, BASE_HEX,
QChar('0'));
case FieldFrameValue:
{
QByteArray fv;
fv.resize(8);
qToBigEndian((quint64) data.src_mac(), (uchar*) fv.data());
fv.remove(0, 2);
return fv;
}
default:
break;
}
break;
// Meta fields
case mac_dstMacMode:
case mac_dstMacCount:
case mac_dstMacStep:
case mac_srcMacMode:
case mac_srcMacCount:
case mac_srcMacStep:
switch(attrib)
{
case FieldIsMeta:
return true;
default:
break;
}
break;
default:
break;
}
return AbstractProtocol::fieldData(index, attrib, streamIndex);
}
bool MacProtocol::setFieldData(int index, const QVariant &value,
FieldAttrib attrib)
{
// FIXME
return false;
}
QWidget* MacProtocol::configWidget()
{
return configForm;
}
void MacProtocol::loadConfigWidget()
{
#define uintToHexStr(num, str, size) QString().setNum(num, 16)
configForm->leDstMac->setText(uintToHexStr(data.dst_mac(), str, 6));
configForm->cmbDstMacMode->setCurrentIndex(data.dst_mac_mode());
configForm->leDstMacCount->setText(QString().setNum(data.dst_mac_count()));
configForm->leDstMacStep->setText(QString().setNum(data.dst_mac_step()));
configForm->leSrcMac->setText(uintToHexStr(data.src_mac(), QString(), 6));
configForm->cmbSrcMacMode->setCurrentIndex(data.src_mac_mode());
configForm->leSrcMacCount->setText(QString().setNum(data.src_mac_count()));
configForm->leSrcMacStep->setText(QString().setNum(data.src_mac_step()));
}
void MacProtocol::storeConfigWidget()
{
bool isOk;
data.set_dst_mac(configForm->leDstMac->text().remove(QChar(' ')).
toULongLong(&isOk, 16));
data.set_dst_mac_mode((OstProto::Mac::MacAddrMode) configForm->
cmbDstMacMode->currentIndex());
data.set_dst_mac_count(configForm->leDstMacCount->text().toULong(&isOk));
data.set_dst_mac_step(configForm->leDstMacStep->text().toULong(&isOk));
data.set_src_mac(configForm->leSrcMac->text().remove(QChar(' ')).
toULongLong(&isOk, 16));
data.set_src_mac_mode((OstProto::Mac::MacAddrMode) configForm->
cmbSrcMacMode->currentIndex());
data.set_src_mac_count(configForm->leSrcMacCount->text().toULong(&isOk));
data.set_src_mac_step(configForm->leSrcMacStep->text().toULong(&isOk));
}

63
common/mac.h Normal file
View File

@ -0,0 +1,63 @@
#ifndef _MAC_H
#define _MAC_H
#include "abstractprotocol.h"
#include "mac.pb.h"
#include "ui_mac.h"
#define MAX_MAC_ITER_COUNT 256
class MacConfigForm : public QWidget, public Ui::mac
{
Q_OBJECT
public:
MacConfigForm(QWidget *parent = 0);
private slots:
void on_cmbDstMacMode_currentIndexChanged(int index);
void on_cmbSrcMacMode_currentIndexChanged(int index);
};
class MacProtocol : public AbstractProtocol
{
private:
OstProto::Mac data;
static MacConfigForm *configForm;
enum macfield
{
mac_dstAddr = 0,
mac_srcAddr,
mac_dstMacMode,
mac_dstMacCount,
mac_dstMacStep,
mac_srcMacMode,
mac_srcMacCount,
mac_srcMacStep,
mac_fieldCount
};
public:
MacProtocol(Stream *parent = 0);
virtual ~MacProtocol();
virtual void protoDataCopyInto(OstProto::Stream &stream);
virtual void protoDataCopyFrom(const OstProto::Stream &stream);
virtual QString name() const;
virtual QString shortName() const;
virtual int fieldCount() const;
virtual QVariant fieldData(int index, FieldAttrib attrib,
int streamIndex = 0) const;
virtual bool setFieldData(int index, const QVariant &value,
FieldAttrib attrib = FieldValue);
virtual QWidget* configWidget();
virtual void loadConfigWidget();
virtual void storeConfigWidget();
};
#endif

29
common/mac.proto Normal file
View File

@ -0,0 +1,29 @@
import "protocol.proto";
package OstProto;
// Ethernet
message Mac {
enum MacAddrMode {
e_mm_fixed = 0;
e_mm_inc = 1;
e_mm_dec = 2;
}
// Dst Mac
optional uint64 dst_mac = 1;
optional MacAddrMode dst_mac_mode = 2 [default = e_mm_fixed];
optional uint32 dst_mac_count = 3 [default = 16];
optional uint32 dst_mac_step = 4 [default = 1];
// Src Mac
optional uint32 src_mac = 5;
optional MacAddrMode src_mac_mode = 6 [default = e_mm_fixed];
optional uint32 src_mac_count = 7 [default = 16];
optional uint32 src_mac_step = 8 [default = 1];
}
extend Stream {
optional Mac mac = 51;
}

190
common/mac.ui Normal file
View File

@ -0,0 +1,190 @@
<ui version="4.0" >
<class>mac</class>
<widget class="QWidget" name="mac" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>423</width>
<height>144</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
<layout class="QHBoxLayout" >
<item>
<widget class="QGroupBox" name="groupBox" >
<property name="title" >
<string>MAC</string>
</property>
<layout class="QGridLayout" >
<item row="0" column="2" >
<widget class="QLabel" name="label_2" >
<property name="text" >
<string>Mode</string>
</property>
</widget>
</item>
<item row="0" column="4" >
<widget class="QLabel" name="label_5" >
<property name="text" >
<string>Step</string>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="label" >
<property name="text" >
<string>Destination</string>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QLineEdit" name="leDstMac" >
<property name="minimumSize" >
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<property name="inputMask" >
<string>HH HH HH HH HH HH; </string>
</property>
<property name="text" >
<string> </string>
</property>
</widget>
</item>
<item row="1" column="2" >
<widget class="QComboBox" name="cmbDstMacMode" >
<item>
<property name="text" >
<string>Fixed</string>
</property>
</item>
<item>
<property name="text" >
<string>Increment</string>
</property>
</item>
<item>
<property name="text" >
<string>Decrement</string>
</property>
</item>
</widget>
</item>
<item row="1" column="3" >
<widget class="QLineEdit" name="leDstMacCount" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>1</string>
</property>
<property name="cursorPosition" >
<number>1</number>
</property>
</widget>
</item>
<item row="1" column="4" >
<widget class="QLineEdit" name="leDstMacStep" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>1</string>
</property>
<property name="cursorPosition" >
<number>1</number>
</property>
</widget>
</item>
<item row="2" column="0" >
<widget class="QLabel" name="label_3" >
<property name="text" >
<string>Source </string>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QLineEdit" name="leSrcMac" >
<property name="inputMask" >
<string>HH HH HH HH HH HH; </string>
</property>
<property name="text" >
<string> </string>
</property>
</widget>
</item>
<item row="2" column="2" >
<widget class="QComboBox" name="cmbSrcMacMode" >
<item>
<property name="text" >
<string>Fixed</string>
</property>
</item>
<item>
<property name="text" >
<string>Increment</string>
</property>
</item>
<item>
<property name="text" >
<string>Decrement</string>
</property>
</item>
</widget>
</item>
<item row="2" column="3" >
<widget class="QLineEdit" name="leSrcMacCount" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>1</string>
</property>
</widget>
</item>
<item row="2" column="4" >
<widget class="QLineEdit" name="leSrcMacStep" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="text" >
<string>1</string>
</property>
<property name="cursorPosition" >
<number>1</number>
</property>
</widget>
</item>
<item row="0" column="3" >
<widget class="QLabel" name="label_4" >
<property name="text" >
<string>Count</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

63
common/ostproto.pro Normal file
View File

@ -0,0 +1,63 @@
TEMPLATE = lib
CONFIG += qt staticlib
QT += network
LIBS += \
-lprotobuf
FORMS += \
mac.ui \
payload.ui \
eth2.ui \
dot3.ui \
llc.ui \
snap.ui \
ip4.ui \
tcp.ui \
udp.ui
PROTOS += \
protocol.proto \
mac.proto \
payload.proto \
eth2.proto \
dot3.proto \
llc.proto \
snap.proto \
ip4.proto \
tcp.proto \
udp.proto
HEADERS += \
abstractprotocol.h \
mac.h \
payload.h \
eth2.h \
dot3.h \
llc.h \
snap.h \
ip4.h \
tcp.h \
udp.h
SOURCES += \
abstractprotocol.cpp \
mac.cpp \
payload.cpp \
eth2.cpp \
dot3.cpp \
llc.cpp \
snap.cpp \
ip4.cpp \
tcp.cpp \
udp.cpp
protobuf_decl.name = protobuf header
protobuf_decl.input = PROTOS
protobuf_decl.output = ${QMAKE_FILE_BASE}.pb.h
protobuf_decl.commands = protoc --cpp_out="." ${QMAKE_FILE_NAME}
protobuf_decl.variable_out = GENERATED_FILES
QMAKE_EXTRA_COMPILERS += protobuf_decl
protobuf_impl.name = protobuf implementation
protobuf_impl.input = PROTOS
protobuf_impl.output = ${QMAKE_FILE_BASE}.pb.cc
protobuf_impl.depends = ${QMAKE_FILE_BASE}.pb.h
protobuf_impl.commands = $$escape_expand(\n)
protobuf_impl.variable_out = GENERATED_SOURCES
QMAKE_EXTRA_COMPILERS += protobuf_impl

176
common/payload.cpp Normal file
View File

@ -0,0 +1,176 @@
#include <qendian.h>
#include <QHostAddress>
#include "../client/stream.h"
#include "payload.h"
PayloadConfigForm *PayloadProtocol::configForm = NULL;
PayloadConfigForm::PayloadConfigForm(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
}
void PayloadConfigForm::on_cmbPatternMode_currentIndexChanged(int index)
{
switch(index)
{
case OstProto::Payload::e_dp_fixed_word:
lePattern->setEnabled(true);
break;
case OstProto::Payload::e_dp_inc_byte:
case OstProto::Payload::e_dp_dec_byte:
case OstProto::Payload::e_dp_random:
lePattern->setDisabled(true);
break;
default:
qWarning("Unhandled/Unknown PatternMode = %d",index);
}
}
PayloadProtocol::PayloadProtocol(Stream *parent)
: AbstractProtocol(parent)
{
if (configForm == NULL)
configForm = new PayloadConfigForm;
}
PayloadProtocol::~PayloadProtocol()
{
}
void PayloadProtocol::protoDataCopyInto(OstProto::Stream &stream)
{
// FIXME: multiple headers
stream.MutableExtension(OstProto::payload)->CopyFrom(data);
}
void PayloadProtocol::protoDataCopyFrom(const OstProto::Stream &stream)
{
// FIXME: multiple headers
if (stream.HasExtension(OstProto::payload))
data.MergeFrom(stream.GetExtension(OstProto::payload));
}
QString PayloadProtocol::name() const
{
return QString("Payload Data");
}
QString PayloadProtocol::shortName() const
{
return QString("DATA");
}
int PayloadProtocol::fieldCount() const
{
return payload_fieldCount;
}
QVariant PayloadProtocol::fieldData(int index, FieldAttrib attrib,
int streamIndex) const
{
switch (index)
{
case payload_dataPattern:
switch(attrib)
{
case FieldName:
return QString("Data");
case FieldValue:
return data.pattern();
case FieldTextValue:
return QString(fieldData(index, FieldFrameValue,
streamIndex).toByteArray().toHex());
case FieldFrameValue:
{
QByteArray fv;
int dataLen;
// FIXME: cannot use stream since it is only on client not
// on server
//dataLen = stream->frameLen() - stream->protocolHeaderSize();
dataLen = 64;
fv.resize(dataLen+4);
switch(data.pattern_mode())
{
case OstProto::Payload::e_dp_fixed_word:
for (int i = 0; i < (dataLen/4)+1; i++)
qToBigEndian((quint32) data.pattern(),
(uchar*)(fv.data()+(i*4)) );
break;
case OstProto::Payload::e_dp_inc_byte:
for (int i = 0; i < dataLen; i++)
fv[i] = i % (0xFF + 1);
break;
case OstProto::Payload::e_dp_dec_byte:
for (int i = 0; i < dataLen; i++)
fv[i] = 0xFF - (i % (0xFF + 1));
break;
case OstProto::Payload::e_dp_random:
for (int i = 0; i < dataLen; i++)
fv[i] = qrand() % (0xFF + 1);
break;
default:
qWarning("Unhandled data pattern %d",
data.pattern_mode());
}
fv.resize(dataLen);
return fv;
}
default:
break;
}
break;
// Meta fields
case payload_dataPatternMode:
switch(attrib)
{
case FieldIsMeta:
return true;
default:
break;
}
break;
default:
break;
}
return AbstractProtocol::fieldData(index, attrib, streamIndex);
}
bool PayloadProtocol::setFieldData(int index, const QVariant &value,
FieldAttrib attrib)
{
// FIXME
return false;
}
QWidget* PayloadProtocol::configWidget()
{
return configForm;
//return new PayloadConfigForm;
}
void PayloadProtocol::loadConfigWidget()
{
#define uintToHexStr(num, str, size) QString().setNum(num, 16)
configForm->cmbPatternMode->setCurrentIndex(data.pattern_mode());
configForm->lePattern->setText(uintToHexStr(data.pattern(), QString(), 4));
}
void PayloadProtocol::storeConfigWidget()
{
bool isOk;
data.set_pattern_mode((OstProto::Payload::DataPatternMode)
configForm->cmbPatternMode->currentIndex());
data.set_pattern(configForm->lePattern->text().remove(QChar(' ')).toULong(&isOk, 16));
}

55
common/payload.h Normal file
View File

@ -0,0 +1,55 @@
#ifndef _PAYLOAD_H
#define _PAYLOAD_H
#include "abstractprotocol.h"
#include "payload.pb.h"
#include "ui_payload.h"
class PayloadConfigForm : public QWidget, public Ui::payload
{
Q_OBJECT
public:
PayloadConfigForm(QWidget *parent = 0);
private slots:
void on_cmbPatternMode_currentIndexChanged(int index);
};
class PayloadProtocol : public AbstractProtocol
{
private:
OstProto::Payload data;
static PayloadConfigForm *configForm;
enum payloadfield
{
payload_dataPattern,
// Meta fields
payload_dataPatternMode,
payload_fieldCount
};
public:
PayloadProtocol(Stream *parent = 0);
virtual ~PayloadProtocol();
virtual void protoDataCopyInto(OstProto::Stream &stream);
virtual void protoDataCopyFrom(const OstProto::Stream &stream);
virtual QString name() const;
virtual QString shortName() const;
virtual int fieldCount() const;
virtual QVariant fieldData(int index, FieldAttrib attrib,
int streamIndex = 0) const;
virtual bool setFieldData(int index, const QVariant &value,
FieldAttrib attrib = FieldValue);
virtual QWidget* configWidget();
virtual void loadConfigWidget();
virtual void storeConfigWidget();
};
#endif

22
common/payload.proto Normal file
View File

@ -0,0 +1,22 @@
import "protocol.proto";
package OstProto;
message Payload {
enum DataPatternMode {
e_dp_fixed_word = 0;
e_dp_inc_byte = 1;
e_dp_dec_byte = 2;
e_dp_random = 3;
}
// Data Pattern
optional DataPatternMode pattern_mode = 1;
optional uint32 pattern = 2;
//optional uint32 data_start_ofs = 13;
}
extend Stream {
optional Payload payload = 52;
}

69
common/payload.ui Normal file
View File

@ -0,0 +1,69 @@
<ui version="4.0" >
<class>payload</class>
<widget class="QWidget" name="payload" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>142</width>
<height>98</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
<layout class="QHBoxLayout" >
<item>
<widget class="QGroupBox" name="groupBox_6" >
<property name="title" >
<string>Data Pattern</string>
</property>
<layout class="QVBoxLayout" >
<item>
<widget class="QComboBox" name="cmbPatternMode" >
<item>
<property name="text" >
<string>Fixed Word</string>
</property>
</item>
<item>
<property name="text" >
<string>Increment Byte</string>
</property>
</item>
<item>
<property name="text" >
<string>Decrement Byte</string>
</property>
</item>
<item>
<property name="text" >
<string>Random</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lePattern" >
<property name="inputMask" >
<string>HH HH HH HH; </string>
</property>
<property name="text" >
<string> </string>
</property>
<property name="maxLength" >
<number>11</number>
</property>
<property name="alignment" >
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -1,169 +0,0 @@
#ifndef _PROTOCOL_H
#define _PROTOCOL_H
#define UINT8 unsigned char
#define UINT16 unsigned short
#define UINT32 unsigned int
#define BYTESWAP4(x) \
(((x & 0xFF000000) >> 24) | \
((x & 0x00FF0000) >> 8) | \
((x & 0x0000FF00) << 8) | \
((x & 0x000000FF) << 24))
#define BYTESWAP2(x) \
(((x & 0xFF00) >> 8) | \
((x & 0x00FF) << 8))
// TODO: portability
#define HTONL(x) BYTESWAP4(x)
#define NTOHL(x) BYTESWAP4(x)
#define HTONS(x) BYTESWAP2(x)
#define NTOHS(x) BYTESWAP2(x)
typedef struct {
UINT8 ver;
UINT8 resv1;
UINT16 resv2;
UINT16 msgType;
UINT16 msgLen;
} tCommHdr;
typedef enum {
e_MT_GetCapability=1, // C-->S
e_MT_CapabilityInfo, // C<--S
e_MT_ChangePortConfig, // C-->S
e_MT_GetPortConfig, // C-->S
e_MT_PortInfo, // C<--S
e_MT_StartTx, // C-->S
e_MT_StopTx, // C-->S
e_MT_StartCapture, // C-->S
e_MT_StopCapture, // C-->S
e_MT_GetCaptureBuffer, // C-->S
e_MT_CaptureBufferInfo, // C-->S
e_MT_GetStats, // C-->S
e_MT_StatsInfo, // C<--S
e_MT_ClearStats, // C-->S
} eMsgType;
typedef enum {
e_TT_PortCapability=0x0000,
e_TT_StreamOper = 0x0100,
e_TT_StreamName,
e_TT_StreamStatus,
e_TT_StreamFrameLength,
e_TT_StreamDataPattern,
e_TT_StreamHeaderData,
} eTlvType;
typedef struct {
UINT16 tlvType;
UINT16 tlvLen;
} tTlv;
typedef struct {
UINT16 tlvType;
UINT16 tlvLen;
UINT32 portId;
UINT32 portSpeed;
#define TLV_MAX_PORT_NAME 64
#define TLV_MAX_PORT_DESC 64
char portName[TLV_MAX_PORT_NAME];
char portDesc[TLV_MAX_PORT_DESC];
} tTlvPortCapability;
typedef struct {
UINT16 tlvType;
UINT16 tlvLen;
UINT32 portId;
UINT32 streamId;
} tTlvStream;
typedef struct {
UINT16 tlvType;
UINT16 tlvLen;
UINT32 portId;
UINT32 streamId;
UINT16 rsvd;
UINT16 streamOper;
#define TLV_STREAM_OPER_INSERT_HEAD 0x0001
#define TLV_STREAM_OPER_INSERT_TAIL 0x0002
#define TLV_STREAM_OPER_INSERT_BEFORE 0x0003
#define TLV_STREAM_OPER_DELETE 0x0010
UINT32 StreamId;
} tTlvStreamOper;
typedef struct {
UINT16 tlvType;
UINT16 tlvLen;
UINT32 portId;
UINT32 streamId;
char streamName[0];
} tTlvStreamName;
typedef struct {
UINT16 tlvType;
UINT16 tlvLen;
UINT32 portId;
UINT32 streamId;
UINT32 streamStatus;
#define TLV_STREAM_STATUS_DISABLED 0
#define TLV_STREAM_STATUS_ENABLED 1
} tTlvStreamStatus;
typedef struct {
UINT16 tlvType;
UINT16 tlvLen;
UINT32 portId;
UINT32 streamId;
UINT16 frameLenMode;
#define TLV_STREAM_FRAME_LEN_MODE_FIXED 0x0000
#define TLV_STREAM_FRAME_LEN_MODE_RANDOM 0x0001
#define TLV_STREAM_FRAME_LEN_MODE_INCREMENT 0x0002
#define TLV_STREAM_FRAME_LEN_MODE_DECREMENT 0x0003
UINT16 frameLen;
UINT16 frameLenMin;
UINT16 frameLenMax;
} tTlvStreamFrameLength;
typedef struct {
UINT16 tlvType;
UINT16 tlvLen;
UINT32 portId;
UINT32 streamId;
UINT16 dataPatternMode;
#define TLV_STREAM_DATA_PATTERN_MODE_FIXED 0x0000
#define TLV_STREAM_DATA_PATTERN_MODE_RANDOM 0x0001
#define TLV_STREAM_DATA_PATTERN_MODE_INCREMENT 0x0002
#define TLV_STREAM_DATA_PATTERN_MODE_DECREMENT 0x0003
UINT16 rsvd;
UINT32 dataPattern;
} tTlvStreamDataPattern;
typedef struct {
UINT16 tlvType;
UINT16 tlvLen;
UINT32 portId;
UINT32 streamId;
UINT16 rsvd;
UINT16 headerLen;
UINT8 header[0];
} tTlvStreamHeaderData;
typedef union {
tTlvStream tlv;
tTlvStreamOper oper;
tTlvStreamName name;
tTlvStreamStatus status;
tTlvStreamFrameLength frameLen;
tTlvStreamDataPattern dataPattern;
tTlvStreamHeaderData headerData;
} uTlvStream;
#endif

View File

@ -4,177 +4,11 @@
package OstProto;
// Ethernet
message Mac {
enum MacAddrMode {
e_mm_fixed = 0;
e_mm_inc = 1;
e_mm_dec = 2;
}
// Dst Mac
optional uint64 dst_mac = 1;
optional MacAddrMode dst_mac_mode = 2 [default = e_mm_fixed];
optional uint32 dst_mac_count = 3 [default = 16];
optional uint32 dst_mac_step = 4 [default = 1];
// Src Mac
optional uint32 src_mac = 5;
optional MacAddrMode src_mac_mode = 6 [default = e_mm_fixed];
optional uint32 src_mac_count = 7 [default = 16];
optional uint32 src_mac_step = 8 [default = 1];
}
message Llc {
optional uint32 dsap = 1;
optional uint32 ssap = 2;
optional uint32 ctl = 3;
}
message Snap {
optional uint32 oui = 1;
//optional uint32 type = 2;
}
message Eth2 {
optional uint32 type = 1;
}
message Vlan {
// VLAN presence/absence
optional bool is_cvlan_tagged = 9;
optional bool is_ctpid_override = 10;
optional bool is_svlan_tagged = 11;
optional bool is_stpid_override = 12;
// VLAN values
optional uint32 ctpid = 13;
optional uint32 cvlan_tag = 14; // includes prio, cfi and cvlanid
optional uint32 stpid = 15;
optional uint32 svlan_tag = 16; // includes pcp, de and svlanid
}
// IP
message Ip {
enum IpAddrMode {
e_im_fixed = 0;
e_im_inc_host = 1;
e_im_dec_host = 2;
e_im_random_host = 3;
}
optional bool is_override_ver = 1;
optional bool is_override_hdrlen = 2;
optional bool is_override_totlen = 3;
optional bool is_override_cksum = 4;
optional uint32 ver_hdrlen = 5 [default = 0x45];
optional uint32 tos = 6;
optional uint32 tot_len = 7;
optional uint32 id = 8 [default = 1234];
// TODO: rename flags to frag_flags
optional uint32 flags = 9;
optional uint32 frag_ofs = 10;
optional uint32 ttl = 11 [default = 127];
optional uint32 proto = 12;
optional uint32 cksum = 13;
// Source IP
optional fixed32 src_ip = 14;
optional IpAddrMode src_ip_mode = 15 [default = e_im_fixed];
optional uint32 src_ip_count = 16 [default = 16];
optional fixed32 src_ip_mask = 17 [default = 0xFFFFFFFF];
// Destination IP
optional fixed32 dst_ip = 18;
optional IpAddrMode dst_ip_mode = 19 [default = e_im_fixed];
optional uint32 dst_ip_count = 20 [default = 16];
optional fixed32 dst_ip_mask = 21 [default = 0xFFFFFFFF];
// TODO: Options
}
message Arp {
// TODO: ARP
}
message Tcp {
optional bool is_override_hdrlen = 1;
optional bool is_override_cksum = 2;
optional uint32 src_port = 3 [default = 8902];
optional uint32 dst_port = 4 [default = 80];
optional uint32 seq_num = 5 [default = 129018];
optional uint32 ack_num = 6;
optional uint32 hdrlen_rsvd = 7 [default = 0x50];
optional uint32 flags = 8;
optional uint32 window = 9 [default = 1024];
optional uint32 cksum = 10;
optional uint32 urg_ptr = 11;
}
// UDP
message Udp {
optional bool is_override_totlen = 1;
optional bool is_override_cksum = 2;
optional uint32 src_port = 3 [default = 8902];
optional uint32 dst_port = 4 [default = 80];
optional uint32 totlen = 5;
optional uint32 cksum = 6;
}
// TODO: ICMP
message Icmp {
}
// TODO: IGMP
message Igmp {
}
message StreamId {
required uint32 id = 1;
}
message StreamCore {
enum FrameType {
e_ft_none = 0;
e_ft_eth_2 = 1;
e_ft_802_3_raw = 2;
e_ft_802_3_llc = 3;
e_ft_snap = 4;
}
enum L3Proto {
e_l3_none = 0;
e_l3_ip = 1;
e_l3_arp = 2;
//e_l3_other = 3;
}
enum L4Proto {
e_l4_none = 0;
e_l4_tcp = 1;
e_l4_udp = 2;
e_l4_icmp = 3;
e_l4_igmp = 4;
//e_l4_other = 5;
}
enum DataPatternMode {
e_dp_fixed_word = 0;
e_dp_inc_byte = 1;
e_dp_dec_byte = 2;
e_dp_random = 3;
}
enum FrameLengthMode {
e_fl_fixed = 0;
e_fl_inc = 1;
@ -187,11 +21,6 @@ message StreamCore {
optional bool is_enabled = 2;
optional uint32 ordinal = 3;
// Data Pattern
optional DataPatternMode pattern_mode = 11;
optional uint32 pattern = 12;
optional uint32 data_start_ofs = 13;
// Frame Length (includes CRC)
optional FrameLengthMode len_mode = 14 [default = e_fl_fixed];
optional uint32 frame_len = 15 [default = 64];
@ -199,9 +28,7 @@ message StreamCore {
optional uint32 frame_len_max = 17 [default = 1518];
// Currently Selected Protocols
optional FrameType ft = 21 [default = e_ft_none];
optional L3Proto l3_proto = 22;
optional L4Proto l4_proto = 23;
repeated uint32 frame_proto = 20;
}
message StreamControl {
@ -240,24 +67,8 @@ message Stream {
optional StreamCore core = 2;
optional StreamControl control = 3;
// Protocol data - L2
optional Mac mac = 51;
optional Llc llc = 52;
optional Snap snap = 53;
optional Eth2 eth2 = 54;
optional Vlan vlan = 55;
// Protocol data - L3
optional Ip ip = 61;
optional Arp arp = 62;
// Protocol data - L4
optional Tcp tcp = 71;
optional Udp udp = 72;
optional Icmp icmp = 73;
optional Igmp igmp = 74;
extensions 51 to 100; // Reserved for Ostinato Use
extensions 101 to 200; // Available for use by protocols
}
message Void {
@ -281,7 +92,6 @@ message StreamIdList {
repeated StreamId stream_id = 2;
}
message Port {
required PortId port_id = 1;
optional string name = 2;

112
common/snap.cpp Normal file
View File

@ -0,0 +1,112 @@
#include <qendian.h>
#include <QHostAddress>
#include "snap.h"
SnapConfigForm *SnapProtocol::configForm = NULL;
SnapConfigForm::SnapConfigForm(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
}
SnapProtocol::SnapProtocol(Stream *parent)
: AbstractProtocol(parent)
{
if (configForm == NULL)
configForm = new SnapConfigForm;
}
SnapProtocol::~SnapProtocol()
{
}
void SnapProtocol::protoDataCopyInto(OstProto::Stream &stream)
{
// FIXME: multiple headers
stream.MutableExtension(OstProto::snap)->CopyFrom(data);
}
void SnapProtocol::protoDataCopyFrom(const OstProto::Stream &stream)
{
// FIXME: multiple headers
if (stream.HasExtension(OstProto::snap))
data.MergeFrom(stream.GetExtension(OstProto::snap));
}
QString SnapProtocol::name() const
{
return QString("SubNetwork Access Protocol");
}
QString SnapProtocol::shortName() const
{
return QString("SNAP");
}
int SnapProtocol::fieldCount() const
{
return snap_fieldCount;
}
QVariant SnapProtocol::fieldData(int index, FieldAttrib attrib,
int streamIndex) const
{
switch (index)
{
case snap_oui:
switch(attrib)
{
case FieldName:
return QString("OUI");
case FieldValue:
return data.oui();
case FieldTextValue:
return QString("%1").arg(data.oui(), 6, BASE_HEX, QChar('0'));
case FieldFrameValue:
{
QByteArray fv;
fv.resize(4);
qToBigEndian((quint32) data.oui(), (uchar*) fv.data());
fv.remove(0, 1);
return fv;
}
default:
break;
}
break;
default:
break;
}
return AbstractProtocol::fieldData(index, attrib, streamIndex);
}
bool SnapProtocol::setFieldData(int index, const QVariant &value,
FieldAttrib attrib)
{
// FIXME
return false;
}
QWidget* SnapProtocol::configWidget()
{
return configForm;
}
void SnapProtocol::loadConfigWidget()
{
#define uintToHexStr(num, str, size) QString().setNum(num, 16)
configForm->leOui->setText(uintToHexStr(data.oui(), str, 3));
}
void SnapProtocol::storeConfigWidget()
{
bool isOk;
data.set_oui(configForm->leOui->text().remove(QChar(' ')).toULong(&isOk, 16));
}

50
common/snap.h Normal file
View File

@ -0,0 +1,50 @@
#ifndef _SNAP_H
#define _SNAP_H
#include "abstractprotocol.h"
#include "snap.pb.h"
#include "ui_snap.h"
class SnapConfigForm : public QWidget, public Ui::snap
{
Q_OBJECT
public:
SnapConfigForm(QWidget *parent = 0);
};
class SnapProtocol : public AbstractProtocol
{
private:
OstProto::Snap data;
static SnapConfigForm *configForm;
enum snapfield
{
snap_oui = 0,
snap_fieldCount
};
public:
SnapProtocol(Stream *parent = 0);
virtual ~SnapProtocol();
virtual void protoDataCopyInto(OstProto::Stream &stream);
virtual void protoDataCopyFrom(const OstProto::Stream &stream);
virtual QString name() const;
virtual QString shortName() const;
virtual int fieldCount() const;
virtual QVariant fieldData(int index, FieldAttrib attrib,
int streamIndex = 0) const;
virtual bool setFieldData(int index, const QVariant &value,
FieldAttrib attrib = FieldValue);
virtual QWidget* configWidget();
virtual void loadConfigWidget();
virtual void storeConfigWidget();
};
#endif

12
common/snap.proto Normal file
View File

@ -0,0 +1,12 @@
import "protocol.proto";
package OstProto;
message Snap {
optional uint32 oui = 1;
//optional uint32 type = 2;
}
extend Stream {
optional Snap snap = 124;
}

89
common/snap.ui Normal file
View File

@ -0,0 +1,89 @@
<ui version="4.0" >
<class>snap</class>
<widget class="QWidget" name="snap" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>293</width>
<height>98</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QGroupBox" name="groupBox" >
<property name="title" >
<string>SNAP</string>
</property>
<layout class="QHBoxLayout" >
<item>
<widget class="QLabel" name="lblOui" >
<property name="text" >
<string>OUI</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="leOui" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="inputMask" >
<string>HH HH HH; </string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblType" >
<property name="text" >
<string>Type</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="leType" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="inputMask" >
<string>HH HH; </string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" >
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

360
common/tcp.cpp Normal file
View File

@ -0,0 +1,360 @@
#include <qendian.h>
#include <QHostAddress>
#include "tcp.h"
TcpConfigForm *TcpProtocol::configForm = NULL;
TcpConfigForm::TcpConfigForm(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
}
TcpProtocol::TcpProtocol(Stream *parent)
: AbstractProtocol(parent)
{
if (configForm == NULL)
configForm = new TcpConfigForm;
}
TcpProtocol::~TcpProtocol()
{
}
void TcpProtocol::protoDataCopyInto(OstProto::Stream &stream)
{
// FIXME: multiple headers
stream.MutableExtension(OstProto::tcp)->CopyFrom(data);
}
void TcpProtocol::protoDataCopyFrom(const OstProto::Stream &stream)
{
// FIXME: multiple headers
if (stream.HasExtension(OstProto::tcp))
data.MergeFrom(stream.GetExtension(OstProto::tcp));
}
QString TcpProtocol::name() const
{
return QString("Transmission Control Protocol");
}
QString TcpProtocol::shortName() const
{
return QString("TCP");
}
int TcpProtocol::fieldCount() const
{
return tcp_fieldCount;
}
QVariant TcpProtocol::fieldData(int index, FieldAttrib attrib,
int streamIndex) const
{
switch (index)
{
case tcp_src_port:
switch(attrib)
{
case FieldName:
return QString("Source Port");
case FieldValue:
return data.src_port();
case FieldTextValue:
return QString("%1").arg(data.src_port());
case FieldFrameValue:
{
QByteArray fv;
fv.resize(2);
qToBigEndian((quint16) data.src_port(), (uchar*) fv.data());
return fv;
}
default:
break;
}
break;
case tcp_dst_port:
switch(attrib)
{
case FieldName:
return QString("Destination Port");
case FieldValue:
return data.dst_port();
case FieldTextValue:
return QString("%1").arg(data.dst_port());
case FieldFrameValue:
{
QByteArray fv;
fv.resize(2);
qToBigEndian((quint16) data.dst_port(), (uchar*) fv.data());
return fv;
}
default:
break;
}
break;
case tcp_seq_num:
switch(attrib)
{
case FieldName:
return QString("Sequence Number");
case FieldValue:
return data.seq_num();
case FieldTextValue:
return QString("%1").arg(data.seq_num());
case FieldFrameValue:
{
QByteArray fv;
fv.resize(4);
qToBigEndian((quint32) data.seq_num(), (uchar*) fv.data());
return fv;
}
default:
break;
}
break;
case tcp_ack_num:
switch(attrib)
{
case FieldName:
return QString("Sequence Number");
case FieldValue:
return data.ack_num();
case FieldTextValue:
return QString("%1").arg(data.ack_num());
case FieldFrameValue:
{
QByteArray fv;
fv.resize(4);
qToBigEndian((quint32) data.ack_num(), (uchar*) fv.data());
return fv;
}
default:
break;
}
break;
case tcp_hdrlen:
switch(attrib)
{
case FieldName:
return QString("Header Length");
case FieldValue:
return ((data.hdrlen_rsvd() >> 4) & 0x0F);
case FieldTextValue:
return QString("%1").arg((data.hdrlen_rsvd() >> 4) & 0x0F);
case FieldFrameValue:
return QByteArray(1, (char)((data.hdrlen_rsvd() >> 4) & 0x0F));
case FieldBitSize:
return 4;
default:
break;
}
break;
case tcp_rsvd:
switch(attrib)
{
case FieldName:
return QString("Reserved");
case FieldValue:
return (data.hdrlen_rsvd() & 0x0F);
case FieldTextValue:
return QString("%1").arg(data.hdrlen_rsvd() & 0x0F);
case FieldFrameValue:
return QByteArray(1, (char)(data.hdrlen_rsvd() & 0x0F));
case FieldBitSize:
return 4;
default:
break;
}
break;
case tcp_flags:
switch(attrib)
{
case FieldName:
return QString("Flags");
case FieldValue:
return (data.flags());
case FieldTextValue:
{
QString s;
s.append("URG: ");
s.append(data.flags() & TCP_FLAG_URG ? "1" : "0");
s.append(" ACK: ");
s.append(data.flags() & TCP_FLAG_ACK ? "1" : "0");
s.append(" PSH: ");
s.append(data.flags() & TCP_FLAG_PSH ? "1" : "0");
s.append(" RST: ");
s.append(data.flags() & TCP_FLAG_RST ? "1" : "0");
s.append(" SYN: ");
s.append(data.flags() & TCP_FLAG_SYN ? "1" : "0");
s.append(" FIN: ");
s.append(data.flags() & TCP_FLAG_FIN ? "1" : "0");
return s;
}
case FieldFrameValue:
return QByteArray(1, (char)(data.flags() & 0x3F));
default:
break;
}
break;
case tcp_window:
switch(attrib)
{
case FieldName:
return QString("Window Size");
case FieldValue:
return data.window();
case FieldTextValue:
return QString("%1").arg(data.window());
case FieldFrameValue:
{
QByteArray fv;
fv.resize(2);
qToBigEndian((quint16) data.window(), (uchar*) fv.data());
return fv;
}
default:
break;
}
break;
case tcp_cksum:
switch(attrib)
{
case FieldName:
return QString("Checksum");
case FieldValue:
return data.cksum();
case FieldTextValue:
return QString("%1").arg(data.cksum());
case FieldFrameValue:
{
QByteArray fv;
fv.resize(2);
qToBigEndian((quint16) data.cksum(), (uchar*) fv.data());
return fv;
}
default:
break;
}
break;
case tcp_urg_ptr:
switch(attrib)
{
case FieldName:
return QString("Urgent Pointer");
case FieldValue:
return data.urg_ptr();
case FieldTextValue:
return QString("%1").arg(data.urg_ptr());
case FieldFrameValue:
{
QByteArray fv;
fv.resize(2);
qToBigEndian((quint16) data.urg_ptr(), (uchar*) fv.data());
return fv;
}
default:
break;
}
break;
// Meta fields
case tcp_is_override_hdrlen:
case tcp_is_override_cksum:
switch(attrib)
{
case FieldIsMeta:
return true;
default:
break;
}
break;
default:
break;
}
return AbstractProtocol::fieldData(index, attrib, streamIndex);
}
bool TcpProtocol::setFieldData(int index, const QVariant &value,
FieldAttrib attrib)
{
// FIXME
return false;
}
QWidget* TcpProtocol::configWidget()
{
return configForm;
}
void TcpProtocol::loadConfigWidget()
{
#define uintToHexStr(num, str, size) QString().setNum(num, 16)
configForm->leTcpSrcPort->setText(QString().setNum(data.src_port()));
configForm->leTcpDstPort->setText(QString().setNum(data.dst_port()));
configForm->leTcpSeqNum->setText(QString().setNum(data.seq_num()));
configForm->leTcpAckNum->setText(QString().setNum(data.ack_num()));
configForm->leTcpHdrLen->setText(QString().setNum((data.hdrlen_rsvd() >> 4) & 0x0F));
configForm->cbTcpHdrLenOverride->setChecked(data.is_override_hdrlen());
configForm->leTcpWindow->setText(QString().setNum(data.window()));
configForm->leTcpCksum->setText(QString().setNum(data.cksum()));
configForm->cbTcpCksumOverride->setChecked(data.is_override_cksum());
configForm->leTcpUrgentPointer->setText(QString().setNum(data.urg_ptr()));
configForm->cbTcpFlagsUrg->setChecked((data.flags() & TCP_FLAG_URG) > 0);
configForm->cbTcpFlagsAck->setChecked((data.flags() & TCP_FLAG_ACK) > 0);
configForm->cbTcpFlagsPsh->setChecked((data.flags() & TCP_FLAG_PSH) > 0);
configForm->cbTcpFlagsRst->setChecked((data.flags() & TCP_FLAG_RST) > 0);
configForm->cbTcpFlagsSyn->setChecked((data.flags() & TCP_FLAG_SYN) > 0);
configForm->cbTcpFlagsFin->setChecked((data.flags() & TCP_FLAG_FIN) > 0);
}
void TcpProtocol::storeConfigWidget()
{
bool isOk;
int ff = 0;
data.set_src_port(configForm->leTcpSrcPort->text().toULong(&isOk));
data.set_dst_port(configForm->leTcpDstPort->text().toULong(&isOk));
data.set_seq_num(configForm->leTcpSeqNum->text().toULong(&isOk));
data.set_ack_num(configForm->leTcpAckNum->text().toULong(&isOk));
data.set_hdrlen_rsvd((configForm->leTcpHdrLen->text().toULong(&isOk) << 4) & 0xF0);
data.set_is_override_hdrlen(configForm->cbTcpHdrLenOverride->isChecked());
data.set_window(configForm->leTcpWindow->text().toULong(&isOk));
data.set_cksum(configForm->leTcpCksum->text().remove(QChar(' ')).toULong(&isOk));
data.set_is_override_cksum(configForm->cbTcpCksumOverride->isChecked());
data.set_urg_ptr(configForm->leTcpUrgentPointer->text().toULong(&isOk));
if (configForm->cbTcpFlagsUrg->isChecked()) ff |= TCP_FLAG_URG;
if (configForm->cbTcpFlagsAck->isChecked()) ff |= TCP_FLAG_ACK;
if (configForm->cbTcpFlagsPsh->isChecked()) ff |= TCP_FLAG_PSH;
if (configForm->cbTcpFlagsRst->isChecked()) ff |= TCP_FLAG_RST;
if (configForm->cbTcpFlagsSyn->isChecked()) ff |= TCP_FLAG_SYN;
if (configForm->cbTcpFlagsFin->isChecked()) ff |= TCP_FLAG_FIN;
data.set_flags(ff);
}

69
common/tcp.h Normal file
View File

@ -0,0 +1,69 @@
#ifndef _TCP_H
#define _TCP_H
#include "abstractprotocol.h"
#include "tcp.pb.h"
#include "ui_tcp.h"
#define TCP_FLAG_URG 0x01
#define TCP_FLAG_ACK 0x02
#define TCP_FLAG_PSH 0x04
#define TCP_FLAG_RST 0x08
#define TCP_FLAG_SYN 0x10
#define TCP_FLAG_FIN 0x20
class TcpConfigForm : public QWidget, public Ui::tcp
{
Q_OBJECT
public:
TcpConfigForm(QWidget *parent = 0);
};
class TcpProtocol : public AbstractProtocol
{
private:
OstProto::Tcp data;
static TcpConfigForm *configForm;
enum tcpfield
{
tcp_src_port = 0,
tcp_dst_port,
tcp_seq_num,
tcp_ack_num,
tcp_hdrlen,
tcp_rsvd,
tcp_flags,
tcp_window,
tcp_cksum,
tcp_urg_ptr,
tcp_is_override_hdrlen,
tcp_is_override_cksum,
tcp_fieldCount
};
public:
TcpProtocol(Stream *parent = 0);
virtual ~TcpProtocol();
virtual void protoDataCopyInto(OstProto::Stream &stream);
virtual void protoDataCopyFrom(const OstProto::Stream &stream);
virtual QString name() const;
virtual QString shortName() const;
virtual int fieldCount() const;
virtual QVariant fieldData(int index, FieldAttrib attrib,
int streamIndex = 0) const;
virtual bool setFieldData(int index, const QVariant &value,
FieldAttrib attrib = FieldValue);
virtual QWidget* configWidget();
virtual void loadConfigWidget();
virtual void storeConfigWidget();
};
#endif

27
common/tcp.proto Normal file
View File

@ -0,0 +1,27 @@
import "protocol.proto";
package OstProto;
// Tcp
message Tcp {
optional bool is_override_hdrlen = 1;
optional bool is_override_cksum = 2;
optional uint32 src_port = 3 [default = 8902];
optional uint32 dst_port = 4 [default = 80];
optional uint32 seq_num = 5 [default = 129018];
optional uint32 ack_num = 6;
optional uint32 hdrlen_rsvd = 7 [default = 0x50];
optional uint32 flags = 8;
optional uint32 window = 9 [default = 1024];
optional uint32 cksum = 10;
optional uint32 urg_ptr = 11;
}
extend Stream {
optional Tcp tcp = 140;
}

228
common/tcp.ui Normal file
View File

@ -0,0 +1,228 @@
<ui version="4.0" >
<class>tcp</class>
<widget class="QWidget" name="tcp" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>447</width>
<height>194</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="label_28" >
<property name="text" >
<string>Source Port</string>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QLineEdit" name="leTcpSrcPort" />
</item>
<item rowspan="6" row="0" column="2" >
<widget class="Line" name="line_3" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item row="0" column="3" >
<widget class="QCheckBox" name="cbTcpCksumOverride" >
<property name="text" >
<string>Override Checksum</string>
</property>
</widget>
</item>
<item row="0" column="4" >
<widget class="QLineEdit" name="leTcpCksum" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="inputMask" >
<string>HH HH; </string>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QLabel" name="label_32" >
<property name="text" >
<string>Destination Port</string>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QLineEdit" name="leTcpDstPort" />
</item>
<item row="1" column="3" >
<widget class="QLabel" name="label_37" >
<property name="text" >
<string>Urgent Pointer</string>
</property>
</widget>
</item>
<item row="1" column="4" >
<widget class="QLineEdit" name="leTcpUrgentPointer" />
</item>
<item row="2" column="0" >
<widget class="QLabel" name="label_33" >
<property name="text" >
<string>Sequence Number</string>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QLineEdit" name="leTcpSeqNum" />
</item>
<item rowspan="4" row="2" column="3" colspan="2" >
<widget class="QGroupBox" name="groupBox_10" >
<property name="title" >
<string>Flags</string>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QCheckBox" name="cbTcpFlagsUrg" >
<property name="text" >
<string>URG</string>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QCheckBox" name="cbTcpFlagsAck" >
<property name="text" >
<string>ACK</string>
</property>
</widget>
</item>
<item row="0" column="2" >
<widget class="QCheckBox" name="cbTcpFlagsPsh" >
<property name="text" >
<string>PSH</string>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QCheckBox" name="cbTcpFlagsRst" >
<property name="text" >
<string>RST</string>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QCheckBox" name="cbTcpFlagsSyn" >
<property name="text" >
<string>SYN</string>
</property>
</widget>
</item>
<item row="1" column="2" >
<widget class="QCheckBox" name="cbTcpFlagsFin" >
<property name="text" >
<string>FIN</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item rowspan="2" row="2" column="5" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>21</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0" >
<widget class="QLabel" name="label_34" >
<property name="text" >
<string>Acknowledgement Number</string>
</property>
</widget>
</item>
<item row="3" column="1" >
<widget class="QLineEdit" name="leTcpAckNum" />
</item>
<item row="4" column="0" >
<widget class="QCheckBox" name="cbTcpHdrLenOverride" >
<property name="text" >
<string>Override Header Length (x4)</string>
</property>
</widget>
</item>
<item row="4" column="1" >
<widget class="QLineEdit" name="leTcpHdrLen" >
<property name="enabled" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="5" column="0" >
<widget class="QLabel" name="label_36" >
<property name="text" >
<string>Window</string>
</property>
</widget>
</item>
<item row="5" column="1" >
<widget class="QLineEdit" name="leTcpWindow" />
</item>
<item row="6" column="2" colspan="2" >
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>cbTcpHdrLenOverride</sender>
<signal>toggled(bool)</signal>
<receiver>leTcpHdrLen</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>141</x>
<y>123</y>
</hint>
<hint type="destinationlabel" >
<x>187</x>
<y>123</y>
</hint>
</hints>
</connection>
<connection>
<sender>cbTcpCksumOverride</sender>
<signal>toggled(bool)</signal>
<receiver>leTcpCksum</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel" >
<x>316</x>
<y>14</y>
</hint>
<hint type="destinationlabel" >
<x>384</x>
<y>17</y>
</hint>
</hints>
</connection>
</connections>
</ui>

200
common/udp.cpp Normal file
View File

@ -0,0 +1,200 @@
#include <qendian.h>
#include <QHostAddress>
#include "udp.h"
UdpConfigForm *UdpProtocol::configForm = NULL;
UdpConfigForm::UdpConfigForm(QWidget *parent)
: QWidget(parent)
{
setupUi(this);
}
UdpProtocol::UdpProtocol(Stream *parent)
: AbstractProtocol(parent)
{
if (configForm == NULL)
configForm = new UdpConfigForm;
}
UdpProtocol::~UdpProtocol()
{
}
void UdpProtocol::protoDataCopyInto(OstProto::Stream &stream)
{
// FIXME: multiple headers
stream.MutableExtension(OstProto::udp)->CopyFrom(data);
}
void UdpProtocol::protoDataCopyFrom(const OstProto::Stream &stream)
{
// FIXME: multiple headers
if (stream.HasExtension(OstProto::udp))
data.MergeFrom(stream.GetExtension(OstProto::udp));
}
QString UdpProtocol::name() const
{
return QString("User Datagram Protocol");
}
QString UdpProtocol::shortName() const
{
return QString("UDP");
}
int UdpProtocol::fieldCount() const
{
return udp_fieldCount;
}
QVariant UdpProtocol::fieldData(int index, FieldAttrib attrib,
int streamIndex) const
{
switch (index)
{
case udp_srcPort:
switch(attrib)
{
case FieldName:
return QString("Source Port");
case FieldValue:
return data.src_port();
case FieldTextValue:
return QString("%1").arg(data.src_port());
case FieldFrameValue:
{
QByteArray fv;
fv.resize(2);
qToBigEndian((quint16) data.src_port(), (uchar*) fv.data());
return fv;
}
default:
break;
}
break;
case udp_dstPort:
switch(attrib)
{
case FieldName:
return QString("Destination Port");
case FieldValue:
return data.dst_port();
case FieldTextValue:
return QString("%1").arg(data.dst_port());
case FieldFrameValue:
{
QByteArray fv;
fv.resize(2);
qToBigEndian((quint16) data.dst_port(), (uchar*) fv.data());
return fv;
}
default:
break;
}
break;
case udp_totLen:
switch(attrib)
{
case FieldName:
return QString("Datagram Length");
case FieldValue:
return data.totlen();
case FieldTextValue:
return QString("%1").arg(data.totlen());
case FieldFrameValue:
{
QByteArray fv;
fv.resize(2);
qToBigEndian((quint16) data.totlen(), (uchar*) fv.data());
return fv;
}
default:
break;
}
break;
case udp_cksum:
switch(attrib)
{
case FieldName:
return QString("Checksum");
case FieldValue:
return data.cksum();
case FieldTextValue:
return QString("%1").arg(data.cksum());
case FieldFrameValue:
{
QByteArray fv;
fv.resize(2);
qToBigEndian((quint16) data.cksum(), (uchar*) fv.data());
return fv;
}
default:
break;
}
break;
// Meta fields
case udp_isOverrideTotLen:
case udp_isOverrideCksum:
switch(attrib)
{
case FieldIsMeta:
return true;
default:
break;
}
break;
default:
break;
}
return AbstractProtocol::fieldData(index, attrib, streamIndex);
}
bool UdpProtocol::setFieldData(int index, const QVariant &value,
FieldAttrib attrib)
{
// FIXME
return false;
}
QWidget* UdpProtocol::configWidget()
{
return configForm;
}
void UdpProtocol::loadConfigWidget()
{
#define uintToHexStr(num, str, size) QString().setNum(num, 16)
configForm->leUdpSrcPort->setText(QString().setNum(data.src_port()));
configForm->leUdpDstPort->setText(QString().setNum(data.dst_port()));
configForm->leUdpLength->setText(QString().setNum(data.totlen()));
configForm->cbUdpLengthOverride->setChecked(data.is_override_totlen());
configForm->leUdpCksum->setText(QString().setNum(data.cksum()));
configForm->cbUdpCksumOverride->setChecked(data.is_override_cksum());
}
void UdpProtocol::storeConfigWidget()
{
bool isOk;
data.set_src_port(configForm->leUdpSrcPort->text().toULong(&isOk));
data.set_dst_port(configForm->leUdpDstPort->text().toULong(&isOk));
data.set_totlen(configForm->leUdpLength->text().toULong(&isOk));
data.set_is_override_totlen(configForm->cbUdpLengthOverride->isChecked());
data.set_cksum(configForm->leUdpCksum->text().remove(QChar(' ')).toULong(&isOk));
data.set_is_override_cksum(configForm->cbUdpCksumOverride->isChecked());
}

56
common/udp.h Normal file
View File

@ -0,0 +1,56 @@
#ifndef _UDP_H
#define _UDP_H
#include "abstractprotocol.h"
#include "udp.pb.h"
#include "ui_udp.h"
class UdpConfigForm : public QWidget, public Ui::udp
{
Q_OBJECT
public:
UdpConfigForm(QWidget *parent = 0);
};
class UdpProtocol : public AbstractProtocol
{
private:
OstProto::Udp data;
static UdpConfigForm *configForm;
enum udpfield
{
udp_srcPort = 0,
udp_dstPort,
udp_totLen,
udp_cksum,
udp_isOverrideTotLen,
udp_isOverrideCksum,
udp_fieldCount
};
public:
UdpProtocol(Stream *parent = 0);
virtual ~UdpProtocol();
virtual void protoDataCopyInto(OstProto::Stream &stream);
virtual void protoDataCopyFrom(const OstProto::Stream &stream);
virtual QString name() const;
virtual QString shortName() const;
virtual int fieldCount() const;
virtual QVariant fieldData(int index, FieldAttrib attrib,
int streamIndex = 0) const;
virtual bool setFieldData(int index, const QVariant &value,
FieldAttrib attrib = FieldValue);
virtual QWidget* configWidget();
virtual void loadConfigWidget();
virtual void storeConfigWidget();
};
#endif

18
common/udp.proto Normal file
View File

@ -0,0 +1,18 @@
import "protocol.proto";
package OstProto;
// UDP
message Udp {
optional bool is_override_totlen = 1;
optional bool is_override_cksum = 2;
optional uint32 src_port = 3 [default = 8902];
optional uint32 dst_port = 4 [default = 80];
optional uint32 totlen = 5;
optional uint32 cksum = 6;
}
extend Stream {
optional Udp udp = 141;
}

101
common/udp.ui Normal file
View File

@ -0,0 +1,101 @@
<ui version="4.0" >
<class>udp</class>
<widget class="QWidget" name="udp" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>217</width>
<height>144</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" >
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="label_35" >
<property name="text" >
<string>Source Port</string>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QLineEdit" name="leUdpSrcPort" />
</item>
<item row="1" column="0" >
<widget class="QLabel" name="label_38" >
<property name="text" >
<string>Destination Port</string>
</property>
</widget>
</item>
<item row="1" column="1" >
<widget class="QLineEdit" name="leUdpDstPort" />
</item>
<item row="2" column="0" >
<widget class="QCheckBox" name="cbUdpLengthOverride" >
<property name="text" >
<string>Override Length</string>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QLineEdit" name="leUdpLength" >
<property name="enabled" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="0" >
<widget class="QCheckBox" name="cbUdpCksumOverride" >
<property name="text" >
<string>Override Checksum</string>
</property>
</widget>
</item>
<item row="3" column="1" >
<widget class="QLineEdit" name="leUdpCksum" >
<property name="enabled" >
<bool>false</bool>
</property>
<property name="inputMask" >
<string>HH HH; </string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" >
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

17
common/vlan.proto Normal file
View File

@ -0,0 +1,17 @@
import "protocol.proto";
package OstProto;
message Vlan {
// VLAN presence/absence
optional bool is_tpid_override = 10;
// VLAN values
optional uint32 ctpid = 13;
optional uint32 cvlan_tag = 14; // includes prio, cfi and cvlanid
optional uint32 stpid = 15;
optional uint32 svlan_tag = 16; // includes pcp, de and svlanid
}
extend Stream {
optional Vlan vlan = 126;
}

168
common/vlan.ui Normal file
View File

@ -0,0 +1,168 @@
<ui version="4.0" >
<class>Form</class>
<widget class="QWidget" name="Form" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>271</width>
<height>90</height>
</rect>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
<layout class="QGridLayout" >
<item row="0" column="0" >
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QLabel" name="label_9" >
<property name="text" >
<string>Priority</string>
</property>
</widget>
</item>
<item row="0" column="1" >
<widget class="QLabel" name="label_8" >
<property name="text" >
<string>CFI</string>
</property>
</widget>
</item>
<item row="0" column="2" >
<widget class="QLabel" name="label_10" >
<property name="text" >
<string>VLAN</string>
</property>
</widget>
</item>
<item row="0" column="3" >
<widget class="QCheckBox" name="cbCvlanTpidOverride" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="text" >
<string>Override TPID</string>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QComboBox" name="cmbCvlanPrio" >
<property name="enabled" >
<bool>true</bool>
</property>
<item>
<property name="text" >
<string>0</string>
</property>
</item>
<item>
<property name="text" >
<string>1</string>
</property>
</item>
<item>
<property name="text" >
<string>2</string>
</property>
</item>
<item>
<property name="text" >
<string>3</string>
</property>
</item>
<item>
<property name="text" >
<string>4</string>
</property>
</item>
<item>
<property name="text" >
<string>5</string>
</property>
</item>
<item>
<property name="text" >
<string>6</string>
</property>
</item>
<item>
<property name="text" >
<string>7</string>
</property>
</item>
</widget>
</item>
<item row="1" column="1" >
<widget class="QComboBox" name="cmbCvlanCfi" >
<property name="enabled" >
<bool>true</bool>
</property>
<item>
<property name="text" >
<string>0</string>
</property>
</item>
<item>
<property name="text" >
<string>1</string>
</property>
</item>
</widget>
</item>
<item row="1" column="2" >
<widget class="QLineEdit" name="leCvlanId" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="text" >
<string>0</string>
</property>
</widget>
</item>
<item row="1" column="3" >
<widget class="QLineEdit" name="leCvlanTpid" >
<property name="enabled" >
<bool>true</bool>
</property>
<property name="inputMask" >
<string>HH HH; </string>
</property>
<property name="text" >
<string> </string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" >
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -1,13 +1,8 @@
TEMPLATE = lib
CONFIG += qt
CONFIG += qt staticlib
QT += network
DEFINES += HAVE_REMOTE
INCLUDEPATH += "c:\msys\1.0\local\include"
LIBS += -L"C:\msys\1.0\local\lib" -lprotobuf
HEADERS += rpcserver.h pbrpccontroller.h pbrpcchannel.h
SOURCES += rpcserver.cpp pbrpcchannel.cpp
client.path = ..\client\debug
client.files = debug\libpbrpc.a debug\pbrpc.dll
server.path = ..\server\debug
server.files = debug\libpbrpc.a debug\pbrpc.dll
INSTALLS += client server

View File

@ -3,15 +3,17 @@ CONFIG += qt debug
QT += network
DEFINES += HAVE_REMOTE WPCAP
INCLUDEPATH += "../rpc"
LIBS += -lprotobuf
win32:LIBS += -lwpcap -lpacket
unix:LIBS += -lpcap
win32:LIBS += -L"../common/debug" -lostproto
unix:LIBS += -L"../common" -lostproto
win32:LIBS += -L"../rpc/debug" -lpbrpc
unix:LIBS += -L"../rpc" -lpbrpc
POST_TARGETDEPS += "../common/debug/libostproto.a" "../rpc/debug/libpbrpc.a"
HEADERS += drone.h
FORMS += drone.ui
SOURCES += drone_main.cpp drone.cpp
SOURCES += myservice.cpp
SOURCES += pcapextra.cpp
SOURCES += "..\common\protocol.pb.cc"

View File

@ -4,6 +4,17 @@
#include <qglobal.h>
#include <qendian.h>
#include "../common/mac.h"
#include "../common/payload.h"
#include "../common/eth2.h" // FIXME: proto DB
#include "../common/dot3.h" // FIXME: proto DB
#include "../common/llc.h" // FIXME: proto DB
#include "../common/snap.h" // FIXME: proto DB
#include "../common/ip4.h" // FIXME: proto DB
#include "../common/tcp.h" // FIXME: proto DB
#include "../common/udp.h" // FIXME: proto DB
#if 0
#include <pcap-int.h>
#include <Ntddndis.h>
@ -12,6 +23,64 @@
#define LOG(...) {sprintf(logStr, __VA_ARGS__); host->Log(logStr);}
#define MB (1024*1024)
StreamInfo::StreamInfo()
{
PbHelper pbh;
pbh.ForceSetSingularDefault(&mCore);
pbh.ForceSetSingularDefault(&mControl);
mProtocolList.append(new MacProtocol);
mProtocolList.append(new PayloadProtocol());
// FIXME: proto DB
mProtocolList.append(new Eth2Protocol);
mProtocolList.append(new Dot3Protocol);
mProtocolList.append(new LlcProtocol);
mProtocolList.append(new SnapProtocol);
mProtocolList.append(new Ip4Protocol);
mProtocolList.append(new TcpProtocol);
mProtocolList.append(new UdpProtocol);
}
StreamInfo::~StreamInfo()
{
for (int i = 0; i < mProtocolList.size(); i++)
delete mProtocolList.at(i);
}
AbstractProtocol* StreamInfo::protocolById(int id)
{
// FIXME BAD BAD VERY BAD!
switch(id) {
case 51:
return mProtocolList.at(0);
case 52:
return mProtocolList.at(1);
case 121:
return mProtocolList.at(2);
case 122:
return mProtocolList.at(3);
case 123:
return mProtocolList.at(4);
case 124:
return mProtocolList.at(5);
// case 125 (unused)
#if 0 // todo VLAN
case 126:
return mProtocolList.at(x);
#endif
case 130:
return mProtocolList.at(6);
case 140:
return mProtocolList.at(7);
case 141:
return mProtocolList.at(8);
default:
return NULL;
}
}
quint32 StreamInfo::pseudoHdrCksumPartial(quint32 srcIp, quint32 dstIp,
quint8 protocol, quint16 len)
{
@ -76,33 +145,29 @@ quint16 StreamInfo::ipv4Cksum(uchar *buf, int len, quint32 partialSum)
int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n)
{
int u, pktLen, dataLen, len = 0;
quint32 srcIp, dstIp; // need it later for TCP/UDP cksum calculation
quint32 cumCksum = 0; // cumulative cksum used to combine partial cksums
int tcpOfs, udpOfs; // needed to fill in cksum later
uchar scratch[8];
int pktLen, len = 0;
// Decide a frame length based on length mode
switch(d.core().len_mode())
switch(mCore.len_mode())
{
case OstProto::StreamCore::e_fl_fixed:
pktLen = d.core().frame_len();
pktLen = mCore.frame_len();
break;
case OstProto::StreamCore::e_fl_inc:
pktLen = d.core().frame_len_min() + (n %
(d.core().frame_len_max() - d.core().frame_len_min() + 1));
pktLen = mCore.frame_len_min() + (n %
(mCore.frame_len_max() - mCore.frame_len_min() + 1));
break;
case OstProto::StreamCore::e_fl_dec:
pktLen = d.core().frame_len_max() - (n %
(d.core().frame_len_max() - d.core().frame_len_min() + 1));
pktLen = mCore.frame_len_max() - (n %
(mCore.frame_len_max() - mCore.frame_len_min() + 1));
break;
case OstProto::StreamCore::e_fl_random:
pktLen = d.core().frame_len_min() + (qrand() %
(d.core().frame_len_max() - d.core().frame_len_min() + 1));
pktLen = mCore.frame_len_min() + (qrand() %
(mCore.frame_len_max() - mCore.frame_len_min() + 1));
break;
default:
qWarning("Unhandled len mode %d. Using default 64",
d.core().len_mode());
mCore.len_mode());
pktLen = 64;
break;
}
@ -113,6 +178,31 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n)
if ((pktLen < 0) || (pktLen > bufMaxSize))
return 0;
// FIXME: Calculated pktLen is an input to Payload Protocol
// FIXME: checksums!!!
for (int i = 0; i < mCore.frame_proto_size(); i++)
{
QByteArray ba;
ba = protocolById(mCore.frame_proto(i))->protocolFrameValue(n);
if (len + ba.size() < bufMaxSize)
{
memcpy(buf+len, ba.constData(), ba.size());
}
len += ba.size();
}
return pktLen;
#if 0 // Proto FW
int u, pktLen, dataLen, len = 0;
quint32 srcIp, dstIp; // need it later for TCP/UDP cksum calculation
quint32 cumCksum = 0; // cumulative cksum used to combine partial cksums
int tcpOfs, udpOfs; // needed to fill in cksum later
uchar scratch[8];
// We always have a Mac Header!
switch (d.mac().dst_mac_mode())
{
@ -449,7 +539,9 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n)
default:
qWarning("Unhandled data pattern %d", d.core().pattern_mode());
}
#endif
#if 0 // Proto FW
// Calculate TCP/UDP checksum over the data pattern/payload and fill in
switch (d.core().l4_proto())
{
@ -473,8 +565,9 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n)
// No cksum processing required
break;
}
return pktLen;
#endif
}
@ -597,28 +690,28 @@ void PortInfo::update()
for (int i = 0; i < streamList.size(); i++)
{
//_restart:
if (streamList[i].d.core().is_enabled())
if (streamList[i]->mCore.is_enabled())
{
long numPackets, numBursts;
long ibg, ipg;
switch (streamList[i].d.control().unit())
switch (streamList[i]->mControl.unit())
{
case OstProto::StreamControl::e_su_bursts:
numBursts = streamList[i].d.control().num_bursts();
numPackets = streamList[i].d.control().packets_per_burst();
ibg = 1000000/streamList[i].d.control().bursts_per_sec();
numBursts = streamList[i]->mControl.num_bursts();
numPackets = streamList[i]->mControl.packets_per_burst();
ibg = 1000000/streamList[i]->mControl.bursts_per_sec();
ipg = 0;
break;
case OstProto::StreamControl::e_su_packets:
numBursts = 1;
numPackets = streamList[i].d.control().num_packets();
numPackets = streamList[i]->mControl.num_packets();
ibg = 0;
ipg = 1000000/streamList[i].d.control().packets_per_sec();
ipg = 1000000/streamList[i]->mControl.packets_per_sec();
break;
default:
qWarning("Unhandled stream control unit %d",
streamList[i].d.control().unit());
streamList[i]->mControl.unit());
continue;
}
qDebug("numBursts = %ld, numPackets = %ld\n",
@ -631,7 +724,7 @@ void PortInfo::update()
{
int len;
len = streamList[i].makePacket(pktBuf, sizeof(pktBuf),
len = streamList[i]->makePacket(pktBuf, sizeof(pktBuf),
j * numPackets + k);
if (len > 0)
{
@ -680,7 +773,7 @@ void PortInfo::update()
}
} // for (numBursts)
switch(streamList[i].d.control().next())
switch(streamList[i]->mControl.next())
{
case ::OstProto::StreamControl::e_nw_stop:
goto _stop_no_more_pkts;
@ -705,7 +798,7 @@ void PortInfo::update()
default:
qFatal("---------- %s: Unhandled case (%d) -----------",
__FUNCTION__, streamList[i].d.control().next() );
__FUNCTION__, streamList[i]->mControl.next() );
break;
}
@ -1124,7 +1217,7 @@ int MyService::getStreamIndex(unsigned int portIdx,
for (i = 0; i < portInfo[portIdx]->streamList.size(); i++)
{
if (streamId == portInfo[portIdx]->streamList.at(i).d.stream_id().id())
if (streamId == portInfo[portIdx]->streamList.at(i)->mStreamId.id())
goto _found;
}
@ -1247,12 +1340,10 @@ const ::OstProto::PortId* request,
response->mutable_port_id()->set_id(portIdx);
for (int j = 0; j < portInfo[portIdx]->streamList.size(); j++)
{
OstProto::StreamId *s, *q;
q = portInfo[portIdx]->streamList[j].d.mutable_stream_id();
OstProto::StreamId *s;
s = response->add_stream_id();
s->CopyFrom(*q);
s->CopyFrom(portInfo[portIdx]->streamList[j]->mStreamId);
}
_exit:
@ -1286,7 +1377,19 @@ const ::OstProto::StreamIdList* request,
continue; // TODO(LOW): Partial status of RPC
s = response->add_stream();
s->CopyFrom(portInfo[portIdx]->streamList[streamIndex].d);
s->mutable_stream_id()->CopyFrom(
portInfo[portIdx]->streamList[streamIndex]->mStreamId);
s->mutable_core()->CopyFrom(
portInfo[portIdx]->streamList[streamIndex]->mCore);
s->mutable_control()->CopyFrom(
portInfo[portIdx]->streamList[streamIndex]->mControl);
for (int j=0; j < portInfo[portIdx]->streamList[streamIndex]->
mProtocolList.size(); j++)
{
portInfo[portIdx]->streamList[streamIndex]->
mProtocolList[j]->protoDataCopyInto(*s);
}
}
_exit:
@ -1312,7 +1415,7 @@ const ::OstProto::StreamIdList* request,
for (int i = 0; i < request->stream_id_size(); i++)
{
int streamIndex;
StreamInfo s;
StreamInfo *s = new StreamInfo;
// If stream with same id as in request exists already ==> error!!
streamIndex = getStreamIndex(portIdx, request->stream_id(i).id());
@ -1322,7 +1425,7 @@ const ::OstProto::StreamIdList* request,
// Append a new "default" stream - actual contents of the new stream is
// expected in a subsequent "modifyStream" request - set the stream id
// now itself however!!!
s.d.mutable_stream_id()->CopyFrom(request->stream_id(i));
s->mStreamId.CopyFrom(request->stream_id(i));
portInfo[portIdx]->streamList.append(s);
// TODO(LOW): fill-in response "Ack"????
@ -1357,7 +1460,7 @@ const ::OstProto::StreamIdList* request,
if (streamIndex < 0)
continue; // TODO(LOW): Partial status of RPC
portInfo[portIdx]->streamList.removeAt(streamIndex);
delete portInfo[portIdx]->streamList.takeAt(streamIndex);
// TODO(LOW): fill-in response "Ack"????
}
@ -1391,8 +1494,17 @@ const ::OstProto::StreamConfigList* request,
if (streamIndex < 0)
continue; // TODO(LOW): Partial status of RPC
portInfo[portIdx]->streamList[streamIndex].d.MergeFrom(
request->stream(i));
portInfo[portIdx]->streamList[streamIndex]->mCore.clear_frame_proto();
portInfo[portIdx]->streamList[streamIndex]->mCore.MergeFrom(
request->stream(i).core());
portInfo[portIdx]->streamList[streamIndex]->mControl.MergeFrom(
request->stream(i).control());
for (int j=0; j < portInfo[portIdx]->streamList[streamIndex]->
mProtocolList.size(); j++)
{
portInfo[portIdx]->streamList[streamIndex]->
mProtocolList[j]->protoDataCopyFrom(request->stream(i));
}
// TODO(LOW): fill-in response "Ack"????
}

View File

@ -8,6 +8,7 @@
#endif
#include "../common/protocol.pb.h"
#include "../common/abstractprotocol.h"
#include "abstracthost.h"
#include <pcap.h>
#include <QtGlobal>
@ -34,9 +35,17 @@ class StreamInfo
friend class MyService;
friend class PortInfo;
OstProto::Stream d;
OstProto::StreamId mStreamId;
OstProto::StreamCore mCore;
OstProto::StreamControl mControl;
QList<AbstractProtocol*> mProtocolList;
StreamInfo() { PbHelper pbh; pbh.ForceSetSingularDefault(&d); }
public:
StreamInfo();
~StreamInfo();
private:
AbstractProtocol* protocolById(int id);
quint32 pseudoHdrCksumPartial(quint32 srcIp, quint32 dstIp,
quint8 protocol, quint16 len);
@ -45,7 +54,7 @@ class StreamInfo
int makePacket(uchar *buf, int bufMaxSize, int n);
public:
bool operator < (const StreamInfo &s) const
{ return(d.core().ordinal() < s.d.core().ordinal()); }
{ return(mCore.ordinal() < s.mCore.ordinal()); }
};
@ -146,7 +155,7 @@ class PortInfo
struct timeval lastTsTx; //! used for Rate Stats calculations
/*! StreamInfo::d::stream_id and index into streamList[] are NOT same! */
QList<StreamInfo> streamList;
QList<StreamInfo*> streamList;
public:
PortInfo(uint id, pcap_if_t *dev);