diff --git a/client/mainwindow.cpp b/client/mainwindow.cpp
index 7eef2f3..d86b01f 100644
--- a/client/mainwindow.cpp
+++ b/client/mainwindow.cpp
@@ -18,10 +18,10 @@ MainWindow::MainWindow(QWidget *parent)
setupUi(this);
- dock->setWidget(portsWindow);
- addDockWidget(Qt::TopDockWidgetArea, dock);
dock2->setWidget(statsWindow);
addDockWidget(Qt::BottomDockWidgetArea, dock2);
+ dock->setWidget(portsWindow);
+ addDockWidget(Qt::TopDockWidgetArea, dock);
}
void MainWindow::on_actionPreferences_triggered()
diff --git a/client/mainwindow.ui b/client/mainwindow.ui
index 5d43edb..98ab4c2 100644
--- a/client/mainwindow.ui
+++ b/client/mainwindow.ui
@@ -1,159 +1,159 @@
-
- MainWindow
-
-
-
- 0
- 0
- 800
- 600
-
-
-
- MainWindow
-
-
-
-
-
-
- Open Config
-
-
-
-
- Save Config
-
-
-
-
- Save Config As ...
-
-
-
-
- Open Capture
-
-
-
-
- Save Capture
-
-
-
-
- Save Capture As ...
-
-
-
-
- E&xit
-
-
-
-
- Copy Port Config
-
-
-
-
- Paste Port Config
-
-
-
-
- Preferences
-
-
-
-
- Minimize
-
-
-
-
- Maximize/Restore
-
-
-
-
- Minimize All
-
-
-
-
- Maximize/Restoe All
-
-
-
-
- Arrange All - Cascade
-
-
-
-
- Arrange All - Tile
-
-
-
-
- Dock
-
-
-
-
- Help
-
-
-
-
- About
-
-
-
-
-
-
+
+ MainWindow
+
+
+
+ 0
+ 0
+ 800
+ 650
+
+
+
+ MainWindow
+
+
+
+
+
+
+ Open Config
+
+
+
+
+ Save Config
+
+
+
+
+ Save Config As ...
+
+
+
+
+ Open Capture
+
+
+
+
+ Save Capture
+
+
+
+
+ Save Capture As ...
+
+
+
+
+ E&xit
+
+
+
+
+ Copy Port Config
+
+
+
+
+ Paste Port Config
+
+
+
+
+ Preferences
+
+
+
+
+ Minimize
+
+
+
+
+ Maximize/Restore
+
+
+
+
+ Minimize All
+
+
+
+
+ Maximize/Restoe All
+
+
+
+
+ Arrange All - Cascade
+
+
+
+
+ Arrange All - Tile
+
+
+
+
+ Dock
+
+
+
+
+ Help
+
+
+
+
+ About
+
+
+
+
+
+
diff --git a/client/port.cpp b/client/port.cpp
index 06f40ae..3ee571e 100644
--- a/client/port.cpp
+++ b/client/port.cpp
@@ -20,6 +20,10 @@ Port::Port(quint32 id, quint32 portGroupId)
mPortGroupId = portGroupId;
}
+Port::~Port()
+{
+}
+
void Port::updatePortConfig(OstProto::Port *port)
{
d.MergeFrom(*port);
diff --git a/client/port.h b/client/port.h
index b16d680..c10eeb3 100644
--- a/client/port.h
+++ b/client/port.h
@@ -35,6 +35,7 @@ public:
// FIXME(HIGH): default args is a hack for QList operations on Port
Port(quint32 id = 0xFFFFFFFF, quint32 pgId = 0xFFFFFFFF);
+ ~Port();
quint32 portGroupId() const { return mPortGroupId; }
const QString& userAlias() const { return mUserAlias; }
diff --git a/client/portgroup.cpp b/client/portgroup.cpp
index 70cb66e..686b436 100644
--- a/client/portgroup.cpp
+++ b/client/portgroup.cpp
@@ -82,6 +82,13 @@ void PortGroup::when_configApply(int portIndex, uint *cookie)
Q_ASSERT(portIndex < mPorts.size());
+ if (state() != QAbstractSocket::ConnectedState)
+ {
+ if (cookie != NULL)
+ delete cookie;
+ return;
+ }
+
if (cookie == NULL)
{
// cookie[0]: op [0 - delete, 1 - add, 2 - modify, 3 - Done!]
@@ -414,22 +421,62 @@ void PortGroup::processModifyStreamAck(OstProto::Ack *ack)
// TODO(HI): Apply Button should now be disabled???!!!!???
}
-void PortGroup::startTx(QList portList)
+void PortGroup::startTx(QList *portList)
{
OstProto::PortIdList portIdList;
- OstProto::Ack *ack = new OstProto::Ack;
+ OstProto::Ack *ack;
qDebug("In %s", __FUNCTION__);
- for (int i = 0; i < portList.size(); i++)
+ if (state() != QAbstractSocket::ConnectedState)
+ return;
+
+ ack = new OstProto::Ack;
+ if (portList == NULL)
+ goto _exit;
+ else
{
- OstProto::PortId *portId;
- portId = portIdList.add_port_id();
- portId->set_id(portList.at(i));
+ for (int i = 0; i < portList->size(); i++)
+ {
+ OstProto::PortId *portId;
+ portId = portIdList.add_port_id();
+ portId->set_id(portList->at(i));
+ }
}
serviceStub->startTx(rpcController, &portIdList, ack,
NewCallback(this, &PortGroup::processStartTxAck, ack));
+_exit:
+ return;
+}
+
+void PortGroup::stopTx(QList *portList)
+{
+ OstProto::PortIdList portIdList;
+ OstProto::Ack *ack;
+
+ qDebug("In %s", __FUNCTION__);
+
+ if (state() != QAbstractSocket::ConnectedState)
+ return;
+
+ ack = new OstProto::Ack;
+ if (portList == NULL)
+ goto _exit;
+ else
+ {
+ for (int i = 0; i < portList->size(); i++)
+ {
+ OstProto::PortId *portId;
+ portId = portIdList.add_port_id();
+ portId->set_id(portList->at(i));
+ }
+ }
+
+ serviceStub->stopTx(rpcController, &portIdList, ack,
+ NewCallback(this, &PortGroup::processStopTxAck, ack));
+_exit:
+ return;
}
void PortGroup::processStartTxAck(OstProto::Ack *ack)
@@ -439,19 +486,30 @@ void PortGroup::processStartTxAck(OstProto::Ack *ack)
delete ack;
}
-void PortGroup::getPortStats()
+void PortGroup::processStopTxAck(OstProto::Ack *ack)
{
- OstProto::PortStatsList *portStatsList = new OstProto::PortStatsList;
-
qDebug("In %s", __FUNCTION__);
+ delete ack;
+}
+
+void PortGroup::getPortStats()
+{
+ OstProto::PortStatsList *portStatsList;
+
+ //qDebug("In %s", __FUNCTION__);
+
+ if (state() != QAbstractSocket::ConnectedState)
+ return;
+
+ portStatsList = new OstProto::PortStatsList;
serviceStub->getStats(rpcController, &portIdList, portStatsList,
NewCallback(this, &PortGroup::processPortStatsList, portStatsList));
}
void PortGroup::processPortStatsList(OstProto::PortStatsList *portStatsList)
{
- qDebug("In %s", __FUNCTION__);
+ //qDebug("In %s", __FUNCTION__);
if (rpcController->Failed())
{
@@ -474,12 +532,30 @@ _error_exit:
delete portStatsList;
}
-void PortGroup::clearPortStats()
+void PortGroup::clearPortStats(QList *portList)
{
- OstProto::Ack *ack = new OstProto::Ack;
+ OstProto::PortIdList portIdList;
+ OstProto::Ack *ack;
qDebug("In %s", __FUNCTION__);
+ if (state() != QAbstractSocket::ConnectedState)
+ return;
+
+ ack = new OstProto::Ack;
+ if (portList == NULL)
+ portIdList.CopyFrom(this->portIdList);
+ else
+ {
+ for (int i = 0; i < portList->size(); i++)
+ {
+ OstProto::PortId *portId;
+
+ portId = portIdList.add_port_id();
+ portId->set_id(portList->at(i));
+ }
+ }
+
serviceStub->clearStats(rpcController, &portIdList, ack,
NewCallback(this, &PortGroup::processClearStatsAck, ack));
}
@@ -488,6 +564,9 @@ void PortGroup::processClearStatsAck(OstProto::Ack *ack)
{
qDebug("In %s", __FUNCTION__);
+ // Refresh stats immediately after a stats clear/reset
+ getPortStats();
+
delete ack;
}
diff --git a/client/portgroup.h b/client/portgroup.h
index e2b5317..2ffcbaf 100644
--- a/client/portgroup.h
+++ b/client/portgroup.h
@@ -70,12 +70,14 @@ public:
void processModifyStreamAck(OstProto::Ack *ack);
- void startTx(QList portList);
+ void startTx(QList *portList = NULL);
void processStartTxAck(OstProto::Ack *ack);
+ void stopTx(QList *portList = NULL);
+ void processStopTxAck(OstProto::Ack *ack);
void getPortStats();
void processPortStatsList(OstProto::PortStatsList *portStatsList);
- void clearPortStats();
+ void clearPortStats(QList *portList = NULL);
void processClearStatsAck(OstProto::Ack *ack);
signals:
diff --git a/client/portstatsfilter.ui b/client/portstatsfilter.ui
index 8220436..e34fde2 100644
--- a/client/portstatsfilter.ui
+++ b/client/portstatsfilter.ui
@@ -5,8 +5,8 @@
0
0
- 402
- 275
+ 588
+ 298
@@ -71,8 +71,55 @@
QAbstractItemView::ExtendedSelection
+
+ QListView::Free
+
+ -
+
+
-
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ U
+
+
+
+ -
+
+
+ D
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
-
diff --git a/client/portstatsmodel.cpp b/client/portstatsmodel.cpp
index d8b40e6..b3fae30 100644
--- a/client/portstatsmodel.cpp
+++ b/client/portstatsmodel.cpp
@@ -105,6 +105,12 @@ QVariant PortStatsModel::data(const QModelIndex &index, int role) const
case e_STAT_FRAME_RECV_RATE:
return stats.rx_pps();
+ case e_STAT_FRAMES_RCVD_NIC:
+ return stats.rx_pkts_nic();
+
+ case e_STAT_FRAMES_SENT_NIC:
+ return stats.tx_pkts_nic();
+
case e_STAT_BYTES_RCVD:
return stats.rx_bytes();
@@ -117,7 +123,15 @@ QVariant PortStatsModel::data(const QModelIndex &index, int role) const
case e_STAT_BYTE_RECV_RATE:
return stats.rx_bps();
+ case e_STAT_BYTES_RCVD_NIC:
+ return stats.rx_bytes_nic();
+
+ case e_STAT_BYTES_SENT_NIC:
+ return stats.tx_bytes_nic();
+
default:
+ qWarning("%s: Unhandled stats id %d\n", __FUNCTION__,
+ index.row());
return 0;
}
}
@@ -140,15 +154,38 @@ QVariant PortStatsModel::headerData(int section, Qt::Orientation orientation, in
void PortStatsModel::portListFromIndex(QModelIndexList indices,
QList &portList)
{
+ int i, j;
+ QModelIndexList selectedCols(indices);
+
portList.clear();
- for (int i = 0; i < indices.size(); i++)
+ //selectedCols = indices.selectedColumns();
+ for (i = 0; i < selectedCols.size(); i++)
{
- //getDomainIndexes(indices.at(i), portGroupIdx, portIdx);
+ uint portGroupIdx, portIdx;
- for (int j = 0; j < portList.size(); j++)
+ getDomainIndexes(selectedCols.at(i), portGroupIdx, portIdx);
+ for (j = 0; j < portList.size(); j++)
{
- // FIXME(HI): Incomplete!!!!
+ if (portList[j].portGroupId == portGroupIdx)
+ break;
+ }
+
+ if (j >= portList.size())
+ {
+ // PortGroup Not found
+ PortGroupAndPortList p;
+
+ p.portGroupId = portGroupIdx;
+ p.portList.append(portIdx);
+
+ portList.append(p);
+ }
+ else
+ {
+ // PortGroup found
+
+ portList[j].portList.append(portIdx);
}
}
}
@@ -193,5 +230,9 @@ void PortStatsModel::updateStats()
void PortStatsModel::when_portGroup_stats_update(quint32 portGroupId)
{
// FIXME(MED): update only the changed ports, not all
- reset();
+
+ QModelIndex topLeft = index(0, 0, QModelIndex());
+ QModelIndex bottomRight = index(rowCount(), columnCount(), QModelIndex());
+
+ emit dataChanged(topLeft, bottomRight);
}
diff --git a/client/portstatsmodel.h b/client/portstatsmodel.h
index 6dc4693..1825524 100644
--- a/client/portstatsmodel.h
+++ b/client/portstatsmodel.h
@@ -9,10 +9,14 @@ typedef enum {
e_STAT_FRAMES_SENT,
e_STAT_FRAME_SEND_RATE,
e_STAT_FRAME_RECV_RATE,
+ e_STAT_FRAMES_RCVD_NIC,
+ e_STAT_FRAMES_SENT_NIC,
e_STAT_BYTES_RCVD,
e_STAT_BYTES_SENT,
e_STAT_BYTE_SEND_RATE,
e_STAT_BYTE_RECV_RATE,
+ e_STAT_BYTES_RCVD_NIC,
+ e_STAT_BYTES_SENT_NIC,
e_STAT_MAX
} PortStat;
@@ -21,10 +25,14 @@ static QStringList PortStatName = (QStringList()
<< "Frames Sent"
<< "Frame Send Rate (fps)"
<< "Frame Receive Rate (fps)"
+ << "Frames Received (NIC)"
+ << "Frames Sent (NIC)"
<< "Bytes Received"
<< "Bytes Sent"
<< "Byte Send Rate (Bps)"
<< "Byte Receive Rate (Bps)"
+ << "Bytes Received (NIC)"
+ << "Bytes Sent (NIC)"
);
class PortGroupList;
@@ -44,6 +52,7 @@ class PortStatsModel : public QAbstractTableModel
int role = Qt::DisplayRole) const;
class PortGroupAndPortList {
+ public:
uint portGroupId;
QList portList;
};
diff --git a/client/portstatswindow.cpp b/client/portstatswindow.cpp
index 28b8f88..5f4ff6b 100644
--- a/client/portstatswindow.cpp
+++ b/client/portstatswindow.cpp
@@ -14,7 +14,10 @@ PortStatsWindow::PortStatsWindow(PortGroupList *pgl, QWidget *parent)
model = pgl->getPortStatsModel();
tvPortStats->setModel(model);
tvPortStats->horizontalHeader()->setMovable(true);
- tvPortStats->verticalHeader()->resizeSections(QHeaderView::ResizeToContents);
+
+ tvPortStats->verticalHeader()->setHighlightSections(false);
+ tvPortStats->verticalHeader()->setDefaultSectionSize(
+ tvPortStats->verticalHeader()->minimumSectionSize());
}
PortStatsWindow::~PortStatsWindow()
@@ -25,21 +28,34 @@ PortStatsWindow::~PortStatsWindow()
void PortStatsWindow::on_tbStartTransmit_clicked()
{
- // TODO(MED): get selected ports
+ QList pgpl;
- if (pgl->numPortGroups())
+ // Get selected ports
+ model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(),
+ pgpl);
+
+ // Clear selected ports, portgroup by portgroup
+ for (int i = 0; i < pgpl.size(); i++)
{
- QList portIdList;
-
- // FIXME(HI): Testing only!!!
- portIdList.append(1); // MS Loopback adapter
- pgl->portGroupByIndex(0).startTx(portIdList);
+ pgl->portGroupByIndex(pgpl.at(i).portGroupId).
+ startTx(&pgpl[i].portList);
}
}
void PortStatsWindow::on_tbStopTransmit_clicked()
{
- // TODO(MED)
+ QList pgpl;
+
+ // Get selected ports
+ model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(),
+ pgpl);
+
+ // Clear selected ports, portgroup by portgroup
+ for (int i = 0; i < pgpl.size(); i++)
+ {
+ pgl->portGroupByIndex(pgpl.at(i).portGroupId).
+ startTx(&pgpl[i].portList);
+ }
}
void PortStatsWindow::on_tbStartCapture_clicked()
@@ -59,7 +75,18 @@ void PortStatsWindow::on_tbViewCapture_clicked()
void PortStatsWindow::on_tbClear_clicked()
{
- // TODO(MED)
+ QList portList;
+
+ // Get selected ports
+ model->portListFromIndex(tvPortStats->selectionModel()->selectedColumns(),
+ portList);
+
+ // Clear selected ports, portgroup by portgroup
+ for (int i = 0; i < portList.size(); i++)
+ {
+ pgl->portGroupByIndex(portList.at(i).portGroupId).
+ clearPortStats(&portList[i].portList);
+ }
}
void PortStatsWindow::on_tbClearAll_clicked()
diff --git a/client/portstatswindow.h b/client/portstatswindow.h
index 98642c1..c1d581f 100644
--- a/client/portstatswindow.h
+++ b/client/portstatswindow.h
@@ -5,6 +5,7 @@
#include
#include "ui_portstatswindow.h"
#include "portgrouplist.h"
+#include "portstatsmodel.h"
class PortStatsWindow : public QWidget, public Ui::PortStatsWindow
{
@@ -16,7 +17,7 @@ public:
private:
PortGroupList *pgl;
- QAbstractItemModel *model;
+ PortStatsModel *model;
private slots:
void on_tbStartTransmit_clicked();
diff --git a/client/portswindow.cpp b/client/portswindow.cpp
index f711f55..645bd1b 100644
--- a/client/portswindow.cpp
+++ b/client/portswindow.cpp
@@ -11,6 +11,12 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent)
setupUi(this);
+ tvStreamList->horizontalHeader()->resizeSections(
+ QHeaderView::ResizeToContents);
+ tvStreamList->verticalHeader()->setDefaultSectionSize(
+ tvStreamList->verticalHeader()->minimumSectionSize());
+
+ // Populate Context Menu Actions
tvPortList->addAction(actionNew_Port_Group);
tvPortList->addAction(actionDelete_Port_Group);
tvPortList->addAction(actionConnect_Port_Group);
@@ -40,6 +46,10 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent)
connect( tvPortList->selectionModel(),
SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)),
plm->getStreamModel(), SLOT(setCurrentPortIndex(const QModelIndex&)));
+
+ // Initially we don't have any ports - so trigger selection of
+ // portgroup detail page
+ when_portView_currentChanged(QModelIndex(), QModelIndex());
}
PortsWindow::~PortsWindow()
diff --git a/client/stream.cpp b/client/stream.cpp
index 653859c..2d82040 100644
--- a/client/stream.cpp
+++ b/client/stream.cpp
@@ -951,6 +951,7 @@ Stream::Stream()
mId = 0xFFFFFFFF;
mCore = new OstProto::StreamCore;
+ mControl = new OstProto::StreamControl;
// mCore->set_port_id(0xFFFFFFFF);
// mCore->set_stream_id(mId);
@@ -973,6 +974,8 @@ Stream::Stream()
mUdp = new UdpProtocol;
mIcmp = new IcmpProtocol;
mIgmp = new IgmpProtocol;
+
+ mCore->set_is_enabled(true);
}
void Stream::getConfig(uint portId, OstProto::Stream *s)
@@ -980,6 +983,7 @@ void Stream::getConfig(uint portId, OstProto::Stream *s)
s->mutable_stream_id()->set_id(mId);
s->mutable_core()->CopyFrom(*mCore);
+ s->mutable_control()->CopyFrom(*mControl);
mMac->getConfig(s->mutable_mac());
mMac->getConfig(s->mutable_mac());
@@ -997,6 +1001,29 @@ void Stream::getConfig(uint portId, OstProto::Stream *s)
mIgmp->getConfig(s->mutable_igmp());
}
+bool Stream::update(OstProto::Stream *stream)
+ {
+ mCore->MergeFrom(stream->core());
+ mControl->MergeFrom(stream->control());
+ mMac->update(stream->mac());
+
+ mLlc->update(stream->llc());
+ mSnap->update(stream->snap());
+ mEth2->update(stream->eth2());
+ mVlan->update(stream->vlan());
+
+ mIp->update(stream->ip());
+ mArp->update(stream->arp());
+
+ mTcp->update(stream->tcp());
+ mUdp->update(stream->udp());
+ mIcmp->update(stream->icmp());
+ mIgmp->update(stream->igmp());
+
+ // FIXME(MED): Re-eval why not store complete OstProto::Stream
+ // instead of components
+ return true;
+ }
// FIXME(HIGH): Replace this by some Protocol Registration mechanism at Init
#define PTYP_L2_NONE 1
#define PTYP_L2_ETH_2 2
diff --git a/client/stream.h b/client/stream.h
index 9500064..42f74ff 100644
--- a/client/stream.h
+++ b/client/stream.h
@@ -831,6 +831,7 @@ class Stream {
quint32 mId;
OstProto::StreamCore *mCore;
+ OstProto::StreamControl *mControl;
UnknownProtocol *mUnknown;
PayloadProtocol *mPayload;
@@ -909,6 +910,22 @@ public:
e_l4_igmp,
};
+ enum SendUnit {
+ e_su_packets,
+ e_su_bursts
+ };
+
+ enum SendMode {
+ e_sm_fixed,
+ e_sm_continuous
+ };
+
+ enum NextWhat {
+ e_nw_stop,
+ e_nw_goto_next,
+ e_nw_goto_id
+ };
+
// -------------------------------------------------------
// Methods
// -------------------------------------------------------
@@ -917,30 +934,9 @@ public:
bool operator < (const Stream &s) const
{ return(mCore->ordinal() < s.mCore->ordinal()); }
- bool update(OstProto::Stream *stream)
- {
- mCore->MergeFrom(stream->core());
- mMac->update(stream->mac());
-
- mLlc->update(stream->llc());
- mSnap->update(stream->snap());
- mEth2->update(stream->eth2());
- mVlan->update(stream->vlan());
-
- mIp->update(stream->ip());
- mArp->update(stream->arp());
-
- mTcp->update(stream->tcp());
- mUdp->update(stream->udp());
- mIcmp->update(stream->icmp());
- mIgmp->update(stream->igmp());
-
- // FIXME(MED): Re-eval why not store complete OstProto::Stream
- // instead of components
- return true;
- }
void getConfig(uint portId, OstProto::Stream *s);
+ bool update(OstProto::Stream *stream);
quint32 id()
{ return mId;}
@@ -1025,6 +1021,48 @@ public:
{ mCore->set_l4_proto((OstProto::StreamCore::L4Proto) l4Proto);
return true; }
+ SendUnit sendUnit()
+ { return (SendUnit) mControl->unit(); }
+ bool setSendUnit(SendUnit sendUnit)
+ { mControl->set_unit(
+ (OstProto::StreamControl::SendUnit) sendUnit); return true; }
+
+ SendMode sendMode()
+ { return (SendMode) mControl->mode(); }
+ bool setSendMode(SendMode sendMode)
+ { mControl->set_mode(
+ (OstProto::StreamControl::SendMode) sendMode); return true; }
+
+ NextWhat nextWhat()
+ { return (NextWhat) mControl->next(); }
+ bool setNextWhat(NextWhat nextWhat)
+ { mControl->set_next(
+ (OstProto::StreamControl::NextWhat) nextWhat); return true; }
+
+ quint32 numPackets()
+ { return (quint32) mControl->num_packets(); }
+ bool setNumPackets(quint32 numPackets)
+ { mControl->set_num_packets(numPackets); return true; }
+
+ quint32 numBursts()
+ { return (quint32) mControl->num_bursts(); }
+ bool setNumBursts(quint32 numBursts)
+ { mControl->set_num_bursts(numBursts); return true; }
+
+ quint32 burstSize()
+ { return (quint32) mControl->packets_per_burst(); }
+ bool setBurstSize(quint32 packetsPerBurst)
+ { mControl->set_packets_per_burst(packetsPerBurst); return true; }
+
+ quint32 packetRate()
+ { return (quint32) mControl->packets_per_sec(); }
+ bool setPacketRate(quint32 packetsPerSec)
+ { mControl->set_packets_per_sec(packetsPerSec); return true; }
+
+ quint32 burstRate()
+ { return (quint32) mControl->bursts_per_sec(); }
+ bool setBurstRate(quint32 burstsPerSec)
+ { mControl->set_bursts_per_sec(burstsPerSec); return true; }
//---------------------------------------------------------------
// Methods for use by Packet Model
diff --git a/client/streamconfigdialog.cpp b/client/streamconfigdialog.cpp
index 0202825..cef9771 100644
--- a/client/streamconfigdialog.cpp
+++ b/client/streamconfigdialog.cpp
@@ -13,6 +13,112 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
setupUi(this);
setupUiExtra();
+ // Time to play match the signals and slots!
+ connect(rbFtNone, SIGNAL(toggled(bool)), rbL3None, SLOT(setChecked(bool)));
+
+ // Show/Hide FrameType related inputs for FT None
+ connect(rbFtNone, SIGNAL(toggled(bool)), lblDsap, SLOT(setHidden(bool)));
+ connect(rbFtNone, SIGNAL(toggled(bool)), leDsap, SLOT(setHidden(bool)));
+ connect(rbFtNone, SIGNAL(toggled(bool)), lblSsap, SLOT(setHidden(bool)));
+ connect(rbFtNone, SIGNAL(toggled(bool)), leSsap, SLOT(setHidden(bool)));
+ connect(rbFtNone, SIGNAL(toggled(bool)), lblControl, SLOT(setHidden(bool)));
+ connect(rbFtNone, SIGNAL(toggled(bool)), leControl, SLOT(setHidden(bool)));
+ connect(rbFtNone, SIGNAL(toggled(bool)), lblOui, SLOT(setHidden(bool)));
+ connect(rbFtNone, SIGNAL(toggled(bool)), leOui, SLOT(setHidden(bool)));
+ connect(rbFtNone, SIGNAL(toggled(bool)), lblType, SLOT(setHidden(bool)));
+ connect(rbFtNone, SIGNAL(toggled(bool)), leType, SLOT(setHidden(bool)));
+
+ // Show/Hide FrameType related inputs for FT Ethernet2
+ connect(rbFtEthernet2, SIGNAL(toggled(bool)), lblDsap, SLOT(setHidden(bool)));
+ connect(rbFtEthernet2, SIGNAL(toggled(bool)), leDsap, SLOT(setHidden(bool)));
+ connect(rbFtEthernet2, SIGNAL(toggled(bool)), lblSsap, SLOT(setHidden(bool)));
+ connect(rbFtEthernet2, SIGNAL(toggled(bool)), leSsap, SLOT(setHidden(bool)));
+ connect(rbFtEthernet2, SIGNAL(toggled(bool)), lblControl, SLOT(setHidden(bool)));
+ connect(rbFtEthernet2, SIGNAL(toggled(bool)), leControl, SLOT(setHidden(bool)));
+ connect(rbFtEthernet2, SIGNAL(toggled(bool)), lblOui, SLOT(setHidden(bool)));
+ connect(rbFtEthernet2, SIGNAL(toggled(bool)), leOui, SLOT(setHidden(bool)));
+ connect(rbFtEthernet2, SIGNAL(toggled(bool)), lblType, SLOT(setVisible(bool)));
+ connect(rbFtEthernet2, SIGNAL(toggled(bool)), leType, SLOT(setVisible(bool)));
+
+ // Show/Hide FrameType related inputs for FT 802.3 Raw
+ connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), lblDsap, SLOT(setHidden(bool)));
+ connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), leDsap, SLOT(setHidden(bool)));
+ connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), lblSsap, SLOT(setHidden(bool)));
+ connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), leSsap, SLOT(setHidden(bool)));
+ connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), lblControl, SLOT(setHidden(bool)));
+ connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), leControl, SLOT(setHidden(bool)));
+ connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), lblOui, SLOT(setHidden(bool)));
+ connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), leOui, SLOT(setHidden(bool)));
+ connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), lblType, SLOT(setHidden(bool)));
+ connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), leType, SLOT(setHidden(bool)));
+
+ // Show/Hide FrameType related inputs for FT 802.3 LLC
+ connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), lblDsap, SLOT(setVisible(bool)));
+ connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), leDsap, SLOT(setVisible(bool)));
+ connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), lblSsap, SLOT(setVisible(bool)));
+ connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), leSsap, SLOT(setVisible(bool)));
+ connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), lblControl, SLOT(setVisible(bool)));
+ connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), leControl, SLOT(setVisible(bool)));
+ connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), lblOui, SLOT(setHidden(bool)));
+ connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), leOui, SLOT(setHidden(bool)));
+ connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), lblType, SLOT(setHidden(bool)));
+ connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), leType, SLOT(setHidden(bool)));
+
+ // Show/Hide FrameType related inputs for FT 802.3 LLC SNAP
+ connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblDsap, SLOT(setVisible(bool)));
+ connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leDsap, SLOT(setVisible(bool)));
+ connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblSsap, SLOT(setVisible(bool)));
+ connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leSsap, SLOT(setVisible(bool)));
+ connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblControl, SLOT(setVisible(bool)));
+ connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leControl, SLOT(setVisible(bool)));
+ connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblOui, SLOT(setVisible(bool)));
+ connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leOui, SLOT(setVisible(bool)));
+ connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblType, SLOT(setVisible(bool)));
+ connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leType, SLOT(setVisible(bool)));
+
+ // Enable/Disable FrameType related inputs for FT 802.3 LLC SNAP
+ connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblDsap, SLOT(setDisabled(bool)));
+ connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leDsap, SLOT(setDisabled(bool)));
+ connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblSsap, SLOT(setDisabled(bool)));
+ connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leSsap, SLOT(setDisabled(bool)));
+ connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblControl, SLOT(setDisabled(bool)));
+ connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leControl, SLOT(setDisabled(bool)));
+
+ // Enable/Disable L4 Protocol Choices for L3 Protocol None
+ connect(rbL3None, SIGNAL(toggled(bool)), rbL4None, SLOT(setEnabled(bool)));
+ connect(rbL3None, SIGNAL(toggled(bool)), rbL4Icmp, SLOT(setDisabled(bool)));
+ connect(rbL3None, SIGNAL(toggled(bool)), rbL4Igmp, SLOT(setDisabled(bool)));
+ connect(rbL3None, SIGNAL(toggled(bool)), rbL4Tcp, SLOT(setDisabled(bool)));
+ connect(rbL3None, SIGNAL(toggled(bool)), rbL4Udp, SLOT(setDisabled(bool)));
+ connect(rbL3None, SIGNAL(toggled(bool)), rbL4Other, SLOT(setDisabled(bool)));
+
+ // Force L4 Protocol = None if L3 Protocol is set to None
+ connect(rbL3None, SIGNAL(toggled(bool)), rbL4None, SLOT(setChecked(bool)));
+
+ // Enable/Disable L4 Protocol Choices for L3 Protocol IPv4
+ connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4None, SLOT(setEnabled(bool)));
+ connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Icmp, SLOT(setEnabled(bool)));
+ connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Igmp, SLOT(setEnabled(bool)));
+ connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Tcp, SLOT(setEnabled(bool)));
+ connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Udp, SLOT(setEnabled(bool)));
+ connect(rbL3Ipv4, SIGNAL(toggled(bool)), rbL4Other, SLOT(setEnabled(bool)));
+
+ // Enable/Disable L4 Protocol Choices for L3 Protocol ARP
+ connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4None, SLOT(setEnabled(bool)));
+ connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Icmp, SLOT(setDisabled(bool)));
+ connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Igmp, SLOT(setDisabled(bool)));
+ connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Tcp, SLOT(setDisabled(bool)));
+ connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Udp, SLOT(setDisabled(bool)));
+ connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4Other, SLOT(setDisabled(bool)));
+
+ // Force L4 Protocol = None if L3 Protocol is set to ARP
+ connect(rbL3Arp, SIGNAL(toggled(bool)), rbL4None, SLOT(setChecked(bool)));
+
+ // Init with FT=Eth2 to trigger signals; actual value will be
+ // initialized by LoadCurrentStream()
+ rbFtEthernet2->click();
+ rbFtNone->click();
+
//mpStreamList = streamList;
mCurrentStreamIndex = streamIndex;
LoadCurrentStream();
@@ -24,9 +130,16 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
vwPacketDump->setModel(mpPacketModel);
vwPacketDump->setSelectionModel(tvPacketTree->selectionModel());
- // FIXME(MED): Enable this navigation
+
+
+ // TODO(MED):
+ //! \todo Enable navigation of streams
pbPrev->setDisabled(true);
pbNext->setDisabled(true);
+ //! \todo Support Goto Stream Id
+ rbActionGotoStream->setDisabled(true);
+ //! \todo Support Continuous Mode
+ rbModeContinuous->setDisabled(true);
}
void StreamConfigDialog::setupUiExtra()
@@ -128,6 +241,22 @@ void StreamConfigDialog::on_pbNext_clicked()
#endif
}
+void StreamConfigDialog::on_rbFtNone_toggled(bool checked)
+{
+}
+
+void StreamConfigDialog::on_rbFtEthernet2_toggled(bool checked)
+{
+}
+
+void StreamConfigDialog::on_rbFt802Dot3Raw_toggled(bool checked)
+{
+}
+
+void StreamConfigDialog::on_rbFt802Dot3Llc_toggled(bool checked)
+{
+}
+
void StreamConfigDialog::on_rbFtLlcSnap_toggled(bool checked)
{
if (checked)
@@ -551,6 +680,55 @@ void StreamConfigDialog::LoadCurrentStream()
// TODO(LOW)
}
}
+
+ // Stream Control
+ {
+ switch (pStream->sendUnit())
+ {
+ case Stream::e_su_packets:
+ rbSendPackets->setChecked(true);
+ break;
+ case Stream::e_su_bursts:
+ rbSendBursts->setChecked(true);
+ break;
+ default:
+ qWarning("Unhandled sendUnit = %d\n", pStream->sendUnit());
+ }
+
+ switch (pStream->sendMode())
+ {
+ case Stream::e_sm_fixed:
+ rbModeFixed->setChecked(true);
+ break;
+ case Stream::e_sm_continuous:
+ rbModeContinuous->setChecked(true);
+ break;
+ default:
+ qWarning("Unhandled sendMode = %d\n", pStream->sendMode());
+ }
+
+ switch(pStream->nextWhat())
+ {
+ case Stream::e_nw_stop:
+ rbActionStop->setChecked(true);
+ break;
+ case Stream::e_nw_goto_next:
+ rbActionGotoNext->setChecked(true);
+ break;
+ case Stream::e_nw_goto_id:
+ rbActionGotoStream->setChecked(true);
+ break;
+ default:
+ qWarning("Unhandled nextAction = %d\n", pStream->nextWhat());
+ }
+
+ leNumPackets->setText(QString().setNum(pStream->numPackets()));
+ leNumBursts->setText(QString().setNum(pStream->numBursts()));
+ lePacketsPerBurst->setText(QString().setNum(
+ pStream->burstSize()));
+ lePacketsPerSec->setText(QString().setNum(pStream->packetRate()));
+ leBurstsPerSec->setText(QString().setNum(pStream->burstRate()));
+ }
}
void StreamConfigDialog::StoreCurrentStream()
@@ -623,11 +801,14 @@ void StreamConfigDialog::StoreCurrentStream()
{
// L2 | Ethernet
{
+ qDebug("%s: LL dstMac = %llx", __FUNCTION__,
+ leDstMac->text().remove(QChar(' ')).toULongLong(&isOk, 16));
pStream->mac()->setDstMac(
leDstMac->text().remove(QChar(' ')).toULongLong(&isOk, 16));
#if 1
- qDebug("%s: dstMac = %llx [%s] %d", __FUNCTION__,
- pStream->mac()->dstMac(),
+ qDebug("%s: dstMac = %llx", __FUNCTION__,
+ pStream->mac()->dstMac());
+ qDebug("%s: dstMac = [%s] %d", __FUNCTION__,
leDstMac->text().toAscii().constData(), isOk);
#endif
pStream->mac()->setDstMacMode(
@@ -639,8 +820,9 @@ void StreamConfigDialog::StoreCurrentStream()
pStream->mac()->setSrcMac(
leSrcMac->text().remove(QChar(' ')).toULongLong(&isOk, 16));
- qDebug("%s: srcMac = %llx [%s] %d", __FUNCTION__,
- pStream->mac()->srcMac(),
+ qDebug("%s: srcMac = %llx", __FUNCTION__,
+ pStream->mac()->srcMac());
+ qDebug("%s: srcMac = [%s] %d", __FUNCTION__,
leSrcMac->text().toAscii().constData(), isOk);
pStream->mac()->setSrcMacMode(
(MacProtocol::MacAddrMode) cmbSrcMacMode->currentIndex());
@@ -657,7 +839,7 @@ void StreamConfigDialog::StoreCurrentStream()
vlan->setCvlanPrio(cmbCvlanPrio->currentIndex());
vlan->setCvlanCfi(cmbCvlanCfi->currentIndex());
vlan->setCvlanId(leCvlanId->text().toULong(&isOk));
- vlan->setCtpid(leCvlanTpid->text().remove(QChar(' ')).toULong(&isOk));
+ vlan->setCtpid(leCvlanTpid->text().remove(QChar(' ')).toULong(&isOk, 16));
if (cbCvlanTpidOverride->isChecked())
f |= VlanProtocol::VlanCtpidOverride;
if (gbCvlan->isChecked())
@@ -666,7 +848,7 @@ void StreamConfigDialog::StoreCurrentStream()
vlan->setSvlanPrio(cmbSvlanPrio->currentIndex());
vlan->setSvlanCfi(cmbSvlanCfi->currentIndex());
vlan->setSvlanId(leSvlanId->text().toULong(&isOk));
- vlan->setStpid(leSvlanTpid->text().remove(QChar(' ')).toULong(&isOk));
+ vlan->setStpid(leSvlanTpid->text().remove(QChar(' ')).toULong(&isOk, 16));
if (cbSvlanTpidOverride->isChecked())
f |= VlanProtocol::VlanStpidOverride;
if (gbSvlan->isChecked())
@@ -798,6 +980,32 @@ void StreamConfigDialog::StoreCurrentStream()
// TODO(LOW)
}
}
+
+ // Stream Control
+ {
+ if (rbSendPackets->isChecked())
+ pStream->setSendUnit(Stream::e_su_packets);
+ if (rbSendBursts->isChecked())
+ pStream->setSendUnit(Stream::e_su_bursts);
+
+ if (rbModeFixed->isChecked())
+ pStream->setSendMode(Stream::e_sm_fixed);
+ if (rbModeContinuous->isChecked())
+ pStream->setSendMode(Stream::e_sm_continuous);
+
+ if (rbActionStop->isChecked())
+ pStream->setNextWhat(Stream::e_nw_stop);
+ if (rbActionGotoNext->isChecked())
+ pStream->setNextWhat(Stream::e_nw_goto_next);
+ if (rbActionGotoStream->isChecked())
+ pStream->setNextWhat(Stream::e_nw_goto_id);
+
+ pStream->setNumPackets(leNumPackets->text().toULong(&isOk));
+ pStream->setNumBursts(leNumBursts->text().toULong(&isOk));
+ pStream->setBurstSize(lePacketsPerBurst->text().toULong(&isOk));
+ pStream->setPacketRate(lePacketsPerSec->text().toULong(&isOk));
+ pStream->setBurstRate(leBurstsPerSec->text().toULong(&isOk));
+ }
}
void StreamConfigDialog::on_pbOk_clicked()
diff --git a/client/streamconfigdialog.h b/client/streamconfigdialog.h
index 2485011..f95205d 100644
--- a/client/streamconfigdialog.h
+++ b/client/streamconfigdialog.h
@@ -44,6 +44,10 @@ private slots:
void on_pbPrev_clicked();
void on_pbNext_clicked();
+ void on_rbFtNone_toggled(bool checked);
+ void on_rbFtEthernet2_toggled(bool checked);
+ void on_rbFt802Dot3Raw_toggled(bool checked);
+ void on_rbFt802Dot3Llc_toggled(bool checked);
void on_rbFtLlcSnap_toggled(bool checked);
void on_rbL3Ipv4_toggled(bool checked);
diff --git a/client/streamconfigdialog.ui b/client/streamconfigdialog.ui
index 503eb27..f3ed791 100644
--- a/client/streamconfigdialog.ui
+++ b/client/streamconfigdialog.ui
@@ -33,7 +33,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
- 2
+ 0
@@ -214,7 +214,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
None
- false
+ true
@@ -241,7 +241,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
802.3 LLC
- true
+ false
@@ -332,7 +332,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
-
-
+
Type
@@ -420,7 +420,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
-
- false
+ true
ICMP
@@ -430,7 +430,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
-
- false
+ true
IGMP
@@ -440,7 +440,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
-
- false
+ true
TCP
@@ -450,7 +450,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
-
- false
+ true
UDP
@@ -2151,12 +2151,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
setEnabled(bool)
- 252
- 288
+ 112
+ 267
- 252
- 317
+ 112
+ 267
@@ -2167,12 +2167,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
setEnabled(bool)
- 252
- 388
+ 112
+ 267
- 252
- 417
+ 112
+ 267
@@ -2183,12 +2183,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
setEnabled(bool)
- 31
- 259
+ 92
+ 267
- 41
- 317
+ 92
+ 267
@@ -2199,12 +2199,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
setEnabled(bool)
- 31
- 259
+ 92
+ 267
- 81
- 317
+ 92
+ 267
@@ -2215,12 +2215,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
setEnabled(bool)
- 31
- 259
+ 92
+ 267
- 120
- 317
+ 92
+ 267
@@ -2231,12 +2231,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
setEnabled(bool)
- 31
- 259
+ 92
+ 267
- 252
- 288
+ 112
+ 267
@@ -2247,12 +2247,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
setEnabled(bool)
- 31
- 359
+ 92
+ 267
- 41
- 417
+ 92
+ 267
@@ -2263,12 +2263,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
setEnabled(bool)
- 31
- 359
+ 92
+ 267
- 120
- 417
+ 92
+ 267
@@ -2279,12 +2279,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
setEnabled(bool)
- 31
- 359
+ 92
+ 267
- 252
- 388
+ 112
+ 267
@@ -2295,12 +2295,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
setEnabled(bool)
- 31
- 359
+ 92
+ 267
- 81
- 417
+ 92
+ 267
@@ -2311,12 +2311,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
setEnabled(bool)
- 123
- 305
+ 145
+ 334
- 123
- 305
+ 145
+ 334
@@ -2327,12 +2327,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
setEnabled(bool)
- 123
- 305
+ 145
+ 334
- 123
- 305
+ 145
+ 334
@@ -2343,12 +2343,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
setEnabled(bool)
- 42
- 171
+ 123
+ 305
- 232
- 170
+ 123
+ 305
@@ -2359,12 +2359,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
setEnabled(bool)
- 42
- 197
+ 123
+ 305
- 232
- 196
+ 123
+ 305
@@ -2375,12 +2375,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
setEnabled(bool)
- 42
- 252
+ 123
+ 305
- 232
- 251
+ 123
+ 305
@@ -2391,12 +2391,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
setEnabled(bool)
- 383
- 274
+ 192
+ 305
- 506
- 274
+ 192
+ 305
@@ -2407,12 +2407,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
setEnabled(bool)
- 123
- 305
+ 145
+ 334
- 123
- 305
+ 145
+ 334
@@ -2423,492 +2423,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
setEnabled(bool)
- 123
- 305
+ 145
+ 334
- 123
- 305
-
-
-
-
- rbFtNone
- toggled(bool)
- lblDsap
- setHidden(bool)
-
-
- 57
- 218
-
-
- 58
- 218
-
-
-
-
- rbFtNone
- toggled(bool)
- leDsap
- setHidden(bool)
-
-
- 57
- 218
-
-
- 99
- 218
-
-
-
-
- rbFtNone
- toggled(bool)
- lblSsap
- setHidden(bool)
-
-
- 57
- 218
-
-
- 58
- 218
-
-
-
-
- rbFtNone
- toggled(bool)
- leSsap
- setHidden(bool)
-
-
- 57
- 218
-
-
- 99
- 218
-
-
-
-
- rbFtNone
- toggled(bool)
- lblControl
- setHidden(bool)
-
-
- 57
- 218
-
-
- 137
- 237
-
-
-
-
- rbFtNone
- toggled(bool)
- leControl
- setHidden(bool)
-
-
- 57
- 218
-
-
- 99
- 218
-
-
-
-
- rbFtNone
- toggled(bool)
- lblOui
- setHidden(bool)
-
-
- 57
- 218
-
-
- 58
- 218
-
-
-
-
- rbFtNone
- toggled(bool)
- leOui
- setHidden(bool)
-
-
- 57
- 218
-
-
- 99
- 218
-
-
-
-
- rbFtNone
- toggled(bool)
- lblTpe
- setHidden(bool)
-
-
- 57
- 218
-
-
- 58
- 218
-
-
-
-
- rbFtNone
- toggled(bool)
- leType
- setHidden(bool)
-
-
- 57
- 218
-
-
- 99
- 218
-
-
-
-
- rbFtEthernet2
- toggled(bool)
- lblDsap
- setHidden(bool)
-
-
- 57
- 218
-
-
- 58
- 218
-
-
-
-
- rbFtEthernet2
- toggled(bool)
- leDsap
- setHidden(bool)
-
-
- 57
- 218
-
-
- 99
- 218
-
-
-
-
- rbFtEthernet2
- toggled(bool)
- lblSsap
- setHidden(bool)
-
-
- 57
- 218
-
-
- 58
- 218
-
-
-
-
- rbFtEthernet2
- toggled(bool)
- leSsap
- setHidden(bool)
-
-
- 57
- 218
-
-
- 99
- 218
-
-
-
-
- rbFt802Dot3Raw
- toggled(bool)
- lblControl
- setHidden(bool)
-
-
- 57
- 218
-
-
- 137
- 237
-
-
-
-
- rbFt802Dot3Raw
- toggled(bool)
- leControl
- setHidden(bool)
-
-
- 57
- 218
-
-
- 99
- 218
-
-
-
-
- rbFtEthernet2
- toggled(bool)
- lblControl
- setHidden(bool)
-
-
- 57
- 218
-
-
- 137
- 237
-
-
-
-
- rbFtEthernet2
- toggled(bool)
- leControl
- setHidden(bool)
-
-
- 57
- 218
-
-
- 99
- 218
-
-
-
-
- rbFtEthernet2
- toggled(bool)
- lblOui
- setHidden(bool)
-
-
- 57
- 218
-
-
- 58
- 218
-
-
-
-
- rbFtEthernet2
- toggled(bool)
- leOui
- setHidden(bool)
-
-
- 57
- 218
-
-
- 99
- 218
-
-
-
-
- rbFt802Dot3Raw
- toggled(bool)
- lblDsap
- setHidden(bool)
-
-
- 57
- 218
-
-
- 58
- 218
-
-
-
-
- rbFt802Dot3Raw
- toggled(bool)
- leDsap
- setHidden(bool)
-
-
- 57
- 218
-
-
- 99
- 218
-
-
-
-
- rbFt802Dot3Raw
- toggled(bool)
- lblSsap
- setHidden(bool)
-
-
- 57
- 218
-
-
- 58
- 218
-
-
-
-
- rbFt802Dot3Raw
- toggled(bool)
- leSsap
- setHidden(bool)
-
-
- 57
- 218
-
-
- 99
- 218
-
-
-
-
- rbFt802Dot3Raw
- toggled(bool)
- lblControl
- setHidden(bool)
-
-
- 57
- 218
-
-
- 137
- 237
-
-
-
-
- rbFt802Dot3Raw
- toggled(bool)
- leControl
- setHidden(bool)
-
-
- 57
- 218
-
-
- 99
- 218
-
-
-
-
- rbFt802Dot3Raw
- toggled(bool)
- lblOui
- setHidden(bool)
-
-
- 57
- 218
-
-
- 58
- 218
-
-
-
-
- rbFt802Dot3Raw
- toggled(bool)
- leOui
- setHidden(bool)
-
-
- 57
- 218
-
-
- 99
- 218
-
-
-
-
- rbFt802Dot3Raw
- toggled(bool)
- lblTpe
- setHidden(bool)
-
-
- 57
- 218
-
-
- 58
- 218
-
-
-
-
- rbFt802Dot3Raw
- toggled(bool)
- leType
- setHidden(bool)
-
-
- 57
- 218
-
-
- 99
- 218
+ 145
+ 334
@@ -2944,182 +2464,6 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
-
- rbFtLlcSnap
- toggled(bool)
- leDsap
- setDisabled(bool)
-
-
- 57
- 218
-
-
- 99
- 218
-
-
-
-
- rbFtLlcSnap
- toggled(bool)
- leSsap
- setDisabled(bool)
-
-
- 57
- 218
-
-
- 99
- 218
-
-
-
-
- rbFtLlcSnap
- toggled(bool)
- leControl
- setDisabled(bool)
-
-
- 57
- 218
-
-
- 99
- 218
-
-
-
-
- rbL3Ipv4
- toggled(bool)
- rbL4Tcp
- setEnabled(bool)
-
-
- 570
- 218
-
-
- 570
- 302
-
-
-
-
- rbL3Ipv4
- toggled(bool)
- rbL4Udp
- setEnabled(bool)
-
-
- 570
- 218
-
-
- 570
- 302
-
-
-
-
- rbL3Ipv4
- toggled(bool)
- rbL4Other
- setEnabled(bool)
-
-
- 570
- 218
-
-
- 570
- 302
-
-
-
-
- rbL3Ipv4
- toggled(bool)
- rbL4Icmp
- setEnabled(bool)
-
-
- 570
- 218
-
-
- 570
- 302
-
-
-
-
- rbL3Ipv4
- toggled(bool)
- rbL4Igmp
- setEnabled(bool)
-
-
- 570
- 218
-
-
- 570
- 302
-
-
-
-
- rbL3None
- clicked()
- rbL4None
- click()
-
-
- 570
- 218
-
-
- 570
- 302
-
-
-
-
- rbL3Arp
- clicked()
- rbL4None
- click()
-
-
- 570
- 218
-
-
- 570
- 302
-
-
-
-
- rbL3Other
- clicked()
- rbL4None
- click()
-
-
- 570
- 218
-
-
- 570
- 302
-
-
-
rbActionGotoStream
toggled(bool)
@@ -3127,12 +2471,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
setEnabled(bool)
- 381
- 140
+ 136
+ 120
- 381
- 174
+ 136
+ 120
@@ -3143,12 +2487,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
setEnabled(bool)
- 30
- 69
+ 41
+ 101
- 85
- 285
+ 96
+ 120
@@ -3159,12 +2503,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
setEnabled(bool)
- 30
- 94
+ 41
+ 120
- 67
- 331
+ 78
+ 120
@@ -3175,12 +2519,12 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
setEnabled(bool)
- 30
- 94
+ 41
+ 120
- 222
- 189
+ 136
+ 120
diff --git a/client/streammodel.cpp b/client/streammodel.cpp
index 3ee9136..32dce31 100644
--- a/client/streammodel.cpp
+++ b/client/streammodel.cpp
@@ -38,7 +38,10 @@ Qt::ItemFlags StreamModel::flags(const QModelIndex &index) const
flags |= Qt::ItemIsEditable;
break;
case StreamStatus:
+#if 0
flags |= Qt::ItemIsUserCheckable | Qt::ItemIsEditable;
+#endif
+ flags |= Qt::ItemIsEditable;
break;
default:
break;
@@ -87,11 +90,11 @@ QVariant StreamModel::data(const QModelIndex &index, int role) const
}
case StreamStatus:
{
- #if 0
if ((role == Qt::DisplayRole) || (role == Qt::EditRole))
- return streamList[index.row()].isEnabled;
- if ((role == Qt::DisplayRole) || (role == Qt::CheckStateRole) ||
- #endif
+ return mCurrentPort->streamByIndex(index.row()).isEnabled();
+ else
+ return QVariant();
+ #if 0
if ((role == Qt::CheckStateRole) || (role == Qt::EditRole))
{
if (mCurrentPort->streamByIndex(index.row()).isEnabled())
@@ -101,6 +104,7 @@ QVariant StreamModel::data(const QModelIndex &index, int role) const
}
else
return QVariant();
+ #endif
break;
}
default:
diff --git a/common/protocol.proto b/common/protocol.proto
index 7ffd54f..fee57b9 100644
--- a/common/protocol.proto
+++ b/common/protocol.proto
@@ -109,7 +109,7 @@ message Tcp {
optional uint32 dst_port = 4 [default = 80];
optional uint32 seq_num = 5 [default = 129018];
- optional uint32 ack_num = 6 [default = 98223];
+ optional uint32 ack_num = 6;
optional uint32 hdrlen_rsvd = 7 [default = 0x50];
optional uint32 flags = 8;
@@ -138,6 +138,9 @@ message Icmp {
message Igmp {
}
+message StreamId {
+ required uint32 id = 1;
+}
message StreamCore {
@@ -201,14 +204,41 @@ message StreamCore {
optional L4Proto l4_proto = 23;
}
-message StreamId {
- required uint32 id = 1;
+message StreamControl {
+ enum SendUnit {
+ e_su_packets = 0;
+ e_su_bursts = 1;
+ }
+
+ enum SendMode {
+ e_sm_fixed = 0;
+ e_sm_continuous = 1;
+ }
+
+ enum NextWhat {
+ e_nw_stop = 0;
+ e_nw_goto_next = 1;
+ e_nw_goto_id = 2;
+ }
+
+ optional SendUnit unit = 1 [default = e_su_packets];
+ optional SendMode mode = 2 [default = e_sm_fixed];
+ optional uint32 num_packets = 3 [default = 1];
+ optional uint32 num_bursts = 4 [default = 1];
+ optional uint32 packets_per_burst = 5 [default = 10];
+ optional NextWhat next = 6 [default = e_nw_goto_next];
+ optional uint32 packets_per_sec = 7;
+ optional uint32 bursts_per_sec = 8;
+
+ // TODO: Gaps?
+
}
message Stream {
required StreamId stream_id = 1;
optional StreamCore core = 2;
+ optional StreamControl control = 3;
// Protocol data - L2
optional Mac mac = 51;
@@ -283,13 +313,17 @@ message PortStats {
optional uint64 rx_pkts = 11;
optional uint64 rx_bytes = 12;
- optional uint64 rx_pps = 13;
- optional uint64 rx_bps = 14;
+ optional uint64 rx_pkts_nic = 13;
+ optional uint64 rx_bytes_nic = 14;
+ optional uint64 rx_pps = 15;
+ optional uint64 rx_bps = 16;
optional uint64 tx_pkts = 21;
optional uint64 tx_bytes = 22;
- optional uint64 tx_pps = 23;
- optional uint64 tx_bps = 24;
+ optional uint64 tx_pkts_nic = 23;
+ optional uint64 tx_bytes_nic = 24;
+ optional uint64 tx_pps = 25;
+ optional uint64 tx_bps = 26;
}
message PortStatsList {
diff --git a/rpc/pbrpcchannel.cpp b/rpc/pbrpcchannel.cpp
index 366ca6f..ed60d2f 100644
--- a/rpc/pbrpcchannel.cpp
+++ b/rpc/pbrpcchannel.cpp
@@ -69,7 +69,7 @@ void PbRpcChannel::CallMethod(
char *p = (char *)&msg;
int len;
- qDebug("In %s", __FUNCTION__);
+ //qDebug("In %s", __FUNCTION__);
if (!req->IsInitialized())
{
@@ -88,8 +88,8 @@ void PbRpcChannel::CallMethod(
isPending = true;
*((quint16*)(p+0)) = HTONS(PB_MSG_TYPE_REQUEST); // type
- qDebug("CLi:GET16 = %d/%d, type = %d", GET16(p+0), NTOHS(GET16(p+0)),
- PB_MSG_TYPE_REQUEST);
+ //qDebug("CLi:GET16 = %d/%d, type = %d", GET16(p+0), NTOHS(GET16(p+0)),
+ //PB_MSG_TYPE_REQUEST);
*((quint16*)(p+2)) = HTONS(method->index()); // method id
// (p+4) len later after serialization
*((quint16*)(p+6)) = HTONS(0); // rsvd
@@ -100,9 +100,13 @@ void PbRpcChannel::CallMethod(
len = req->ByteSize();
*((quint16*)(p+4)) = HTONS(len); // len
- qDebug("client(%s) sending %d bytes encoding <%s>", __FUNCTION__, len+8,
- req->DebugString().c_str());
- BUFDUMP(msg, len+8);
+ // Avoid printing stats since it happens every couple of seconds
+ if (pendingMethodId != 12)
+ {
+ qDebug("client(%s) sending %d bytes encoding <%s>", __FUNCTION__, len+8,
+ req->DebugString().c_str());
+ BUFDUMP(msg, len+8);
+ }
mpSocket->write(msg, len + 8);
}
@@ -115,12 +119,12 @@ void PbRpcChannel::on_mpSocket_readyRead()
quint16 type, method, len, rsvd;
PbRpcController *controller;
- qDebug("In %s", __FUNCTION__);
+ //qDebug("In %s", __FUNCTION__);
msgLen = mpSocket->read(msg, sizeof(msg));
- qDebug("client(%s) rcvd %d bytes", __FUNCTION__, msgLen);
- BUFDUMP(msg, msgLen);
+ //qDebug("client(%s) rcvd %d bytes", __FUNCTION__, msgLen);
+ //BUFDUMP(msg, msgLen);
type = NTOHS(GET16(p+0));
method = NTOHS(GET16(p+2));
@@ -153,8 +157,13 @@ void PbRpcChannel::on_mpSocket_readyRead()
// Serialized data starts from offset 8
response->ParseFromArray((void*) &msg[8], len);
- qDebug("client(%s): Parsed as %s", __FUNCTION__,
- response->DebugString().c_str());
+
+ // Avoid printing stats
+ if (method != 12)
+ {
+ qDebug("client(%s): Parsed as %s", __FUNCTION__,
+ response->DebugString().c_str());
+ }
if (!response->IsInitialized())
{
diff --git a/rpc/rpcserver.cpp b/rpc/rpcserver.cpp
index 7b6335b..a3978cb 100644
--- a/rpc/rpcserver.cpp
+++ b/rpc/rpcserver.cpp
@@ -41,7 +41,7 @@ void RpcServer::done(::google::protobuf::Message *resp, PbRpcController *PbRpcCo
char *p = (char *)&msg;
int len;
- qDebug("In RpcServer::done");
+ //qDebug("In RpcServer::done");
// TODO: check PbRpcController to see if method failed
if (PbRpcController->Failed())
@@ -67,9 +67,13 @@ void RpcServer::done(::google::protobuf::Message *resp, PbRpcController *PbRpcCo
len = resp->ByteSize();
(*(quint16*)(p+4)) = HTONS(len); // len
- qDebug("Server(%s): sending %d bytes to client encoding <%s>",
- __FUNCTION__, len + 8, resp->DebugString().c_str());
- //BUFDUMP(msg, len + 8);
+ // Avoid printing stats since it happens once every couple of seconds
+ if (pendingMethodId != 12)
+ {
+ qDebug("Server(%s): sending %d bytes to client encoding <%s>",
+ __FUNCTION__, len + 8, resp->DebugString().c_str());
+ //BUFDUMP(msg, len + 8);
+ }
clientSock->write(msg, len + 8);
@@ -132,17 +136,17 @@ void RpcServer::when_dataAvail()
PbRpcController *controller;
msgLen = clientSock->read(msg, sizeof(msg));
- LogInt(QString(QByteArray(msg, msgLen).toHex()));
+ //LogInt(QString(QByteArray(msg, msgLen).toHex()));
- qDebug("Server %s: rcvd %d bytes", __FUNCTION__, msgLen);
+ //qDebug("Server %s: rcvd %d bytes", __FUNCTION__, msgLen);
//BUFDUMP(msg, msgLen);
type = NTOHS(GET16(p+0));
method = NTOHS(GET16(p+2));
len = NTOHS(GET16(p+4));
rsvd = NTOHS(GET16(p+6));
- qDebug("type = %d, method = %d, len = %d, rsvd = %d",
- type, method, len, rsvd);
+ //qDebug("type = %d, method = %d, len = %d, rsvd = %d",
+ //type, method, len, rsvd);
if (type != PB_MSG_TYPE_REQUEST)
{
@@ -182,12 +186,12 @@ void RpcServer::when_dataAvail()
goto _error_exit;
}
- qDebug("Server(%s): successfully parsed as <%s>", __FUNCTION__,
- resp->DebugString().c_str());
+ //qDebug("Server(%s): successfully parsed as <%s>", __FUNCTION__,
+ //resp->DebugString().c_str());
controller = new PbRpcController;
- qDebug("before service->callmethod()");
+ //qDebug("before service->callmethod()");
service->CallMethod(methodDesc, controller, req, resp,
NewCallback(this, &RpcServer::done, resp, controller));
diff --git a/server/drone.pro b/server/drone.pro
index 79cbd1a..3642823 100644
--- a/server/drone.pro
+++ b/server/drone.pro
@@ -5,7 +5,7 @@ DEFINES += HAVE_REMOTE WPCAP
INCLUDEPATH += "c:\msys\1.0\local\include"
INCLUDEPATH += "C:\DevelLibs\WpdPack\Include"
INCLUDEPATH += "..\rpc"
-LIBS += -L"C:\DevelLibs\WpdPack\Lib" -lwpcap
+LIBS += -L"C:\DevelLibs\WpdPack\Lib" -lwpcap -lpacket
LIBS += -L"..\rpc\debug" -lpbrpc
HEADERS += drone.h
FORMS += drone.ui
diff --git a/server/myservice.cpp b/server/myservice.cpp
index 79db27b..b21310d 100644
--- a/server/myservice.cpp
+++ b/server/myservice.cpp
@@ -1,30 +1,177 @@
#include "myservice.h"
#include "qdebug.h"
+#include
#include
+#ifdef Q_OS_WIN32
+#include
+#include
+#endif
+
#define LOG(...) {sprintf(logStr, __VA_ARGS__); host->Log(logStr);}
#define MB (1024*1024)
-int StreamInfo::makePacket(uchar *buf, int bufMaxSize)
+#if 0
+quint16 StreamInfo::ipv4Cksum(quint16 ipHdrLen, quint16 buff[])
{
- int pktLen, len = 0;
+ quint16 word16;
+ quint32 sum=0;
+ quint16 i;
+
+ // make 16 bit words out of every two adjacent 8 bit words in the packet
+ // and add them up
+ for (i = 0; i < ipHdrLen ;i += 2)
+ {
+ word16 =((buff[i]<<8)&0xFF00)+(buff[i+1]&0xFF);
+ sum = sum + (quint32) word16;
+ }
+
+ // take only 16 bits out of the 32 bit sum and add up the carries
+ while (sum>>16)
+ sum = (sum & 0xFFFF)+(sum >> 16);
+
+ // one's complement the result
+ sum = ~sum;
+
+ return (quint16) sum;
+}
+#endif
+
+quint16 StreamInfo::ipv4Cksum(uchar *buf, int len)
+{
+ quint32 sum = 0; /* assume 32 bit long, 16 bit short */
+ quint16 *ip = (quint16*) buf;
+
+ while(len > 1)
+ {
+ sum += *ip;
+ if(sum & 0x80000000) /* if high order bit set, fold */
+ sum = (sum & 0xFFFF) + (sum >> 16);
+ ip++;
+ len -= 2;
+ }
+
+ if(len) /* take care of left over byte */
+ sum += (unsigned short) *(unsigned char *)ip;
+
+ while(sum>>16)
+ sum = (sum & 0xFFFF) + (sum >> 16);
+
+ qDebug("cksum = %x", ~sum);
+ return (quint16) ~sum;
+}
+
+int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n)
+{
+ int u, pktLen, len = 0;
uchar scratch[8];
// TODO(HI): use FrameLengthMode - don't assume fixed
- pktLen = d.core().frame_len();
+ // pktLen is adjusted for CRC/FCS which will be added by the NIC
+ pktLen = d.core().frame_len() - 4;
if (bufMaxSize < pktLen)
return 0;
// We always have a Mac Header!
- // TODO(HI): use MacMode - don't assume fixed
- qToBigEndian((quint64) d.mac().dst_mac(), scratch);
+ switch (d.mac().dst_mac_mode())
+ {
+ case OstProto::Mac::e_mm_fixed:
+ qToBigEndian((quint64) d.mac().dst_mac(), scratch);
+ break;
+ case OstProto::Mac::e_mm_inc:
+ u = (n % d.mac().dst_mac_count()) * d.mac().dst_mac_step();
+ qToBigEndian((quint64) d.mac().dst_mac() + u, scratch);
+ break;
+ case OstProto::Mac::e_mm_dec:
+ u = (n % d.mac().dst_mac_count()) * d.mac().dst_mac_step();
+ qToBigEndian((quint64) d.mac().dst_mac() - u, scratch);
+ break;
+ default:
+ qWarning("Unhandled dstMac_mode %d", d.mac().dst_mac_mode());
+ }
memcpy((buf + len), scratch + 2, 6);
len += 6;
- qToBigEndian((quint64) d.mac().src_mac(), scratch);
- memcpy((buf + len), &scratch + 2, 6);
+
+ switch (d.mac().src_mac_mode())
+ {
+ case OstProto::Mac::e_mm_fixed:
+ qToBigEndian((quint64) d.mac().src_mac(), scratch);
+ break;
+ case OstProto::Mac::e_mm_inc:
+ u = (n % d.mac().src_mac_count()) * d.mac().src_mac_step();
+ qToBigEndian((quint64) d.mac().src_mac() + u, scratch);
+ break;
+ case OstProto::Mac::e_mm_dec:
+ u = (n % d.mac().src_mac_count()) * d.mac().src_mac_step();
+ qToBigEndian((quint64) d.mac().src_mac() - u, scratch);
+ break;
+ default:
+ qWarning("Unhandled srcMac_mode %d", d.mac().src_mac_mode());
+ }
+ memcpy((buf + len), scratch + 2, 6);
len += 6;
+
+ // Frame Type - Part 1 (pre VLAN info)
+ switch(d.core().ft())
+ {
+ case OstProto::StreamCore::e_ft_none:
+ case OstProto::StreamCore::e_ft_eth_2:
+ break;
+ case OstProto::StreamCore::e_ft_802_3_raw:
+ qToBigEndian((quint16) pktLen, buf+len);
+ len += 2;
+ break;
+ case OstProto::StreamCore::e_ft_802_3_llc:
+ qToBigEndian((quint16) pktLen, buf+len);
+ len += 2;
+ buf[len+0] = (quint8) d.llc().dsap();
+ buf[len+1] = (quint8) d.llc().ssap();
+ buf[len+2] = (quint8) d.llc().ctl();
+ len +=3;
+ break;
+ case OstProto::StreamCore::e_ft_snap:
+ qToBigEndian((quint16) pktLen, buf+len);
+ len += 2;
+ buf[len+0] = (quint8) d.llc().dsap();
+ buf[len+1] = (quint8) d.llc().ssap();
+ buf[len+2] = (quint8) d.llc().ctl();
+ len +=3;
+ qToBigEndian((quint32) d.snap().oui(), scratch);
+ memcpy((buf + len), scratch + 2, 3);
+ len += 3;
+ break;
+ default:
+ qWarning("Unhandled frame type %d\n", d.core().ft());
+ }
+
+ // VLAN
+ if (d.vlan().is_svlan_tagged())
+ {
+ if (d.vlan().is_stpid_override())
+ qToBigEndian((quint16) d.vlan().stpid(), buf+len);
+ else
+ qToBigEndian((quint16) 0x88a8, buf+len);
+ len += 2 ;
+
+ qToBigEndian((quint16) d.vlan().svlan_tag(), buf+len);
+ len += 2 ;
+ }
+
+ if (d.vlan().is_cvlan_tagged())
+ {
+ if (d.vlan().is_ctpid_override())
+ qToBigEndian((quint16) d.vlan().ctpid(), buf+len);
+ else
+ qToBigEndian((quint16) 0x8100, buf+len);
+ len += 2 ;
+
+ qToBigEndian((quint16) d.vlan().cvlan_tag(), buf+len);
+ len += 2 ;
+ }
+
+ // Frame Type - Part 2 (post VLAN info)
switch(d.core().ft())
{
case OstProto::StreamCore::e_ft_none:
@@ -34,23 +181,9 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize)
len += 2;
break;
case OstProto::StreamCore::e_ft_802_3_raw:
- qToBigEndian((quint16) pktLen, buf+len);
- len += 2;
- break;
case OstProto::StreamCore::e_ft_802_3_llc:
- buf[len+0] = (quint8) d.llc().dsap();
- buf[len+1] = (quint8) d.llc().ssap();
- buf[len+2] = (quint8) d.llc().ctl();
- len +=3;
break;
case OstProto::StreamCore::e_ft_snap:
- buf[len+0] = (quint8) d.llc().dsap();
- buf[len+1] = (quint8) d.llc().ssap();
- buf[len+2] = (quint8) d.llc().ctl();
- len +=3;
- qToBigEndian((quint32) d.snap().oui(), scratch);
- memcpy((buf + len), scratch + 2, 3);
- len += 3;
qToBigEndian((quint16) d.eth2().type(), buf+len);
len += 2;
break;
@@ -58,32 +191,107 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize)
qWarning("Unhandled frame type %d\n", d.core().ft());
}
+ // L3
switch (d.core().l3_proto())
{
case OstProto::StreamCore::e_l3_none:
break;
case OstProto::StreamCore::e_l3_ip:
+ {
+ quint32 subnet, host;
+ int ipOfs = len;
+
buf[len+0] = (quint8) (d.ip().ver_hdrlen());
buf[len+1] = (quint8) (d.ip().tos());
len += 2;
- qToBigEndian((quint16) d.ip().tot_len(), buf+len);
+
+ if (d.ip().is_override_totlen())
+ qToBigEndian((quint16) d.ip().tot_len(), buf+len);
+ else
+ qToBigEndian((quint16) (pktLen - ipOfs), buf+len);
len += 2;
+
qToBigEndian((quint16) d.ip().id(), buf+len);
len += 2;
+
qToBigEndian((quint16) (( (d.ip().flags() & 0x3) << 13) |
(d.ip().frag_ofs() & 0x1FFF)), buf+len);
len += 2;
+
buf[len+0] = (quint8) (d.ip().ttl());
buf[len+1] = (quint8) (d.ip().proto());
len += 2;
- qToBigEndian((quint16) d.ip().cksum(), buf+len);
+
+ // cksum calculated after filling in the rest
+ qToBigEndian((quint16) 0, buf+len);
len += 2;
+
// TODO(HI): Use IpMode - don't assume fixed
- qToBigEndian((quint32) d.ip().src_ip(), buf+len);
+ switch(d.ip().src_ip_mode())
+ {
+ case OstProto::Ip::e_im_fixed:
+ qToBigEndian((quint32) d.ip().src_ip(), buf+len);
+ break;
+ case OstProto::Ip::e_im_inc_host:
+ u = n % d.ip().src_ip_count();
+ subnet = d.ip().src_ip() & d.ip().src_ip_mask();
+ host = (((d.ip().src_ip() & ~d.ip().src_ip_mask()) + u) &
+ ~d.ip().src_ip_mask());
+ qToBigEndian((quint32) (subnet | host), buf+len);
+ break;
+ case OstProto::Ip::e_im_dec_host:
+ u = n % d.ip().src_ip_count();
+ subnet = d.ip().src_ip() & d.ip().src_ip_mask();
+ host = (((d.ip().src_ip() & ~d.ip().src_ip_mask()) - u) &
+ ~d.ip().src_ip_mask());
+ qToBigEndian((quint32) (subnet | host), buf+len);
+ break;
+ case OstProto::Ip::e_im_random_host:
+ subnet = d.ip().src_ip() & d.ip().src_ip_mask();
+ host = (qrand() & ~d.ip().src_ip_mask());
+ qToBigEndian((quint32) (subnet | host), buf+len);
+ break;
+ default:
+ qWarning("Unhandled src_ip_mode = %d", d.ip().src_ip_mode());
+ }
len +=4;
- qToBigEndian((quint32) d.ip().dst_ip(), buf+len);
+
+ switch(d.ip().dst_ip_mode())
+ {
+ case OstProto::Ip::e_im_fixed:
+ qToBigEndian((quint32) d.ip().dst_ip(), buf+len);
+ break;
+ case OstProto::Ip::e_im_inc_host:
+ u = n % d.ip().dst_ip_count();
+ subnet = d.ip().dst_ip() & d.ip().dst_ip_mask();
+ host = (((d.ip().dst_ip() & ~d.ip().dst_ip_mask()) + u) &
+ ~d.ip().dst_ip_mask());
+ qToBigEndian((quint32) (subnet | host), buf+len);
+ break;
+ case OstProto::Ip::e_im_dec_host:
+ u = n % d.ip().dst_ip_count();
+ subnet = d.ip().dst_ip() & d.ip().dst_ip_mask();
+ host = (((d.ip().dst_ip() & ~d.ip().dst_ip_mask()) - u) &
+ ~d.ip().dst_ip_mask());
+ qToBigEndian((quint32) (subnet | host), buf+len);
+ break;
+ case OstProto::Ip::e_im_random_host:
+ subnet = d.ip().dst_ip() & d.ip().dst_ip_mask();
+ host = (qrand() & ~d.ip().dst_ip_mask());
+ qToBigEndian((quint32) (subnet | host), buf+len);
+ break;
+ default:
+ qWarning("Unhandled dst_ip_mode = %d", d.ip().dst_ip_mode());
+ }
len +=4;
+
+ // Calculate and fill in cksum (unless overridden)
+ if (d.ip().is_override_cksum())
+ qToBigEndian((quint16) d.ip().cksum(), buf+ipOfs+10);
+ else
+ *((quint16*)(buf + ipOfs + 10)) = ipv4Cksum(buf + ipOfs, len-ipOfs);
break;
+ }
case OstProto::StreamCore::e_l3_arp:
// TODO(LOW)
break;
@@ -96,34 +304,59 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize)
case OstProto::StreamCore::e_l4_none:
break;
case OstProto::StreamCore::e_l4_tcp:
+ {
qToBigEndian((quint16) d.tcp().src_port(), buf+len);
len += 2;
qToBigEndian((quint16) d.tcp().dst_port(), buf+len);
len += 2;
- qToBigEndian((quint16) d.tcp().seq_num(), buf+len);
- len += 2;
- qToBigEndian((quint16) d.tcp().ack_num(), buf+len);
- len += 2;
- buf[len+0] = (quint8) d.tcp().hdrlen_rsvd();
+
+ qToBigEndian((quint32) d.tcp().seq_num(), buf+len);
+ len += 4;
+ qToBigEndian((quint32) d.tcp().ack_num(), buf+len);
+ len += 4;
+
+ if (d.tcp().is_override_hdrlen())
+ buf[len+0] = (quint8) d.tcp().hdrlen_rsvd();
+ else
+ buf[len+0] = (quint8) 0x50; // FIXME(LOW)
buf[len+1] = (quint8) d.tcp().flags();
len += 2;
+
qToBigEndian((quint16) d.tcp().window(), buf+len);
len +=2;
- qToBigEndian((quint16) d.tcp().cksum(), buf+len);
+
+ if (d.tcp().is_override_cksum())
+ qToBigEndian((quint16) d.tcp().cksum(), buf+len);
+ else
+ qToBigEndian((quint16) 0, buf+len); // FIXME(HI)
len +=2;
+
qToBigEndian((quint16) d.tcp().urg_ptr(), buf+len);
len +=2;
break;
+ }
case OstProto::StreamCore::e_l4_udp:
+ {
+ int udpLen = pktLen - len;
+
qToBigEndian((quint16) d.udp().src_port(), buf+len);
len += 2;
qToBigEndian((quint16) d.udp().dst_port(), buf+len);
len += 2;
- qToBigEndian((quint16) d.udp().totlen(), buf+len);
+
+ if (d.udp().is_override_totlen())
+ qToBigEndian((quint16) d.udp().totlen(), buf+len);
+ else
+ qToBigEndian((quint16) udpLen, buf+len);
len +=2;
- qToBigEndian((quint16) d.udp().cksum(), buf+len);
+
+ if (d.udp().is_override_cksum())
+ qToBigEndian((quint16) d.udp().cksum(), buf+len);
+ else
+ qToBigEndian((quint16) 0, buf+len); // FIXME(HI)
len +=2;
break;
+ }
case OstProto::StreamCore::e_l4_icmp:
// TODO(LOW)
break;
@@ -149,6 +382,7 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize)
return pktLen;
}
+
//
// ------------------ PortInfo --------------------
//
@@ -166,6 +400,13 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev)
dev->name, pcap_geterr(devHandle));
}
+#if 0
+ if (pcap_setdirection(devHandle, PCAP_D_IN)<0)
+ {
+ qDebug("[%s] Error setting direction inbound only\n", dev->name);
+ }
+#endif
+
/* By default, put the interface in statistics mode */
if (pcap_setmode(devHandle, MODE_STAT)<0)
{
@@ -179,10 +420,14 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev)
d.set_is_oper_up(true); // FIXME(MED):check
d.set_is_exclusive_control(false); // FIXME(MED): check
+ memset((void*) &stats, 0, sizeof(stats));
resetStats();
// We'll create sendqueue later when required
sendQueue = NULL;
+ pcapExtra.sendQueueNumPkts = 0;
+ pcapExtra.txPkts = 0;
+ pcapExtra.txBytes = 0;
isSendQueueDirty=true;
// Start the monitor thread
@@ -201,21 +446,47 @@ void PortInfo::update()
// TODO(LOW): calculate sendqueue size
sendQueue = pcap_sendqueue_alloc(1*MB);
+ pcapExtra.sendQueueNumPkts = 0;
+
+ // First sort the streams by ordinalValue
+ qSort(streamList);
for (int i = 0; i < streamList.size(); i++)
{
- // FIXME(HI): Testing only
- //if (streamList[i].d.core().is_enabled())
+ if (streamList[i].d.core().is_enabled())
{
- pktHdr.len = streamList[i].makePacket(pktBuf, sizeof(pktBuf));
- pktHdr.caplen = pktHdr.len;
- pktHdr.ts.tv_sec = pktHdr.ts.tv_usec = 0; // FIXME(HI)
+ int numPackets, numBursts;
- if (-1 == pcap_sendqueue_queue(sendQueue, &pktHdr,
- (u_char*) pktBuf))
+ if (streamList[i].d.control().unit() ==
+ OstProto::StreamControl::e_su_bursts)
{
- qDebug("[port %d] sendqueue_queue() failed for streamidx %d\n",
- id(), i);
+ numBursts = streamList[i].d.control().num_bursts();
+ numPackets = streamList[i].d.control().packets_per_burst();
+ }
+ else
+ {
+ numBursts = 1;
+ numPackets = streamList[i].d.control().num_packets();
+ }
+
+ for (int j = 0; j < numBursts; j++)
+ {
+ for (int k = 0; k < numPackets; k++)
+ {
+ pktHdr.len = streamList[i].makePacket(
+ pktBuf, sizeof(pktBuf), j * numPackets + k);
+ pktHdr.caplen = pktHdr.len;
+ pktHdr.ts.tv_sec = pktHdr.ts.tv_usec = 0; // FIXME(HI)
+
+ if (-1 == pcap_sendqueue_queue(sendQueue, &pktHdr,
+ (u_char*) pktBuf))
+ {
+ qDebug("[port %d] sendqueue_queue() failed for "
+ "streamidx %d\n", id(), i);
+ }
+ else
+ pcapExtra.sendQueueNumPkts++;
+ }
}
}
}
@@ -225,14 +496,29 @@ void PortInfo::update()
void PortInfo::startTransmit()
{
- int n;
+ uint bytes;
// TODO(HI): Stream Mode - one pass/continuous
- n = pcap_sendqueue_transmit(devHandle, sendQueue, false);
- if (n == 0)
- qDebug("port %d: send error %s\n", id(), pcap_geterr(devHandle));
+ bytes = pcap_sendqueue_transmit(devHandle, sendQueue, false);
+ if (bytes < sendQueue->len)
+ {
+ qDebug("port %d: sent (%d/%d) error %s. TxStats may be inconsistent",
+ id(), bytes, sendQueue->len, pcap_geterr(devHandle));
+ //! \TODO parse sendqueue using 'bytes' to get actual pkts sent
+ pcapExtra.txPkts += pcapExtra.sendQueueNumPkts;
+ pcapExtra.txBytes += bytes;
+ }
else
- qDebug("port %d: sent %d bytes\n", id(), n);
+ {
+ qDebug("port %d: sent (%d/%d) bytes\n", id(), bytes, sendQueue->len);
+ pcapExtra.txPkts += pcapExtra.sendQueueNumPkts;
+ pcapExtra.txBytes += bytes;
+ }
+
+ // pcap_sendqueue_transmit() returned 'bytes' includes size of pcap_pkthdr
+ // - adjust for it
+ pcapExtra.txBytes -= pcapExtra.sendQueueNumPkts * sizeof(pcap_pkthdr);
+
}
void PortInfo::stopTransmit()
@@ -241,7 +527,7 @@ void PortInfo::stopTransmit()
void PortInfo::resetStats()
{
- memset((void*) &stats, 0, sizeof(stats));
+ memcpy((void*) &epochStats, (void*) &stats, sizeof(stats));
}
//
@@ -251,21 +537,57 @@ void PortInfo::resetStats()
PortInfo::PortMonitor::PortMonitor(PortInfo *port)
{
this->port = port;
+#ifdef Q_OS_WIN32
+ {
+ int sz = sizeof(PACKET_OID_DATA) + sizeof(quint64) + 4;
+ //oidData = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT,
+ //sizeof(PACKET_OID_DATA) + sizeof(quint64) - 1);
+ oidData = (PPACKET_OID_DATA) malloc(sz);
+ if (oidData)
+ {
+ memset(oidData, 0, sz);
+ oidData->Length=sizeof(quint64);
+ }
+ else
+ qFatal("failed to alloc oidData");
+ }
+#endif
}
void PortInfo::PortMonitor::callback(u_char *state,
const struct pcap_pkthdr *header, const u_char *pkt_data)
{
+ uint usec;
PortInfo *port = (PortInfo*) state;
+
quint64 pkts;
quint64 bytes;
- pkts = *((quint64*)(pkt_data + 0));
- bytes = *((quint64*)(pkt_data + 8));
+ // Update RxStats and RxRates using PCAP data
+ pkts = *((quint64*)(pkt_data + 0));
+ bytes = *((quint64*)(pkt_data + 8));
+
+ // Note: PCAP reported bytes includes ETH_FRAME_HDR_SIZE - adjust for it
+ bytes -= pkts * ETH_FRAME_HDR_SIZE;
+
+ usec = (header->ts.tv_sec - port->lastTs.tv_sec) * 1000000 +
+ (header->ts.tv_usec - port->lastTs.tv_usec);
+ port->stats.rxPps = (pkts * 1000000) / usec;
+ port->stats.rxBps = (bytes * 1000000) / usec;
port->stats.rxPkts += pkts;
port->stats.rxBytes += bytes;
+ // Update TxStats from PcapExtra
+ port->stats.txPkts = port->pcapExtra.txPkts;
+ port->stats.txBytes = port->pcapExtra.txBytes;
+
+ //! \TODO TxRates
+
+ // Store curr timestamp as last timestamp
+ port->lastTs.tv_sec = header->ts.tv_sec;
+ port->lastTs.tv_usec = header->ts.tv_usec;
+
#if 0
for (int i=0; i < 16; i++)
{
@@ -276,6 +598,26 @@ void PortInfo::PortMonitor::callback(u_char *state,
qDebug("[%d: pkts : %llu]\n", port->id(), port->stats.rxPkts);
qDebug("[%d: bytes: %llu]\n", port->id(), port->stats.rxBytes);
#endif
+
+ // Retreive NIC stats
+#ifdef Q_OS_WIN32
+ port->monitor.oidData->Oid = OID_GEN_RCV_OK;
+ if (PacketRequest(port->devHandle->adapter, 0, port->monitor.oidData))
+ {
+ if (port->monitor.oidData->Length <= sizeof(port->stats.txPkts))
+ memcpy((void*)&port->stats.rxPktsNic,
+ (void*)port->monitor.oidData->Data,
+ port->monitor.oidData->Length);
+ }
+ port->monitor.oidData->Oid = OID_GEN_XMIT_OK;
+ if (PacketRequest(port->devHandle->adapter, 0, port->monitor.oidData))
+ {
+ if (port->monitor.oidData->Length <= sizeof(port->stats.txPkts))
+ memcpy((void*)&port->stats.txPktsNic,
+ (void*)port->monitor.oidData->Data,
+ port->monitor.oidData->Length);
+ }
+#endif
}
void PortInfo::PortMonitor::run()
@@ -687,7 +1029,7 @@ const ::OstProto::PortIdList* request,
::OstProto::PortStatsList* response,
::google::protobuf::Closure* done)
{
- qDebug("In %s", __PRETTY_FUNCTION__);
+ //qDebug("In %s", __PRETTY_FUNCTION__);
for (int i=0; i < request->port_id_size(); i++)
{
@@ -701,13 +1043,25 @@ const ::OstProto::PortIdList* request,
s = response->add_port_stats();
s->mutable_port_id()->set_id(request->port_id(i).id());
- s->set_rx_pkts(portInfo[portidx]->stats.rxPkts);
- s->set_rx_bytes(portInfo[portidx]->stats.rxBytes);
+ s->set_rx_pkts(portInfo[portidx]->stats.rxPkts -
+ portInfo[portidx]->epochStats.rxPkts);
+ s->set_rx_bytes(portInfo[portidx]->stats.rxBytes -
+ portInfo[portidx]->epochStats.rxBytes);
+ s->set_rx_pkts_nic(portInfo[portidx]->stats.rxPktsNic -
+ portInfo[portidx]->epochStats.rxPktsNic);
+ s->set_rx_bytes_nic(portInfo[portidx]->stats.rxBytesNic -
+ portInfo[portidx]->epochStats.rxBytesNic);
s->set_rx_pps(portInfo[portidx]->stats.rxPps);
s->set_rx_bps(portInfo[portidx]->stats.rxBps);
- s->set_tx_pkts(portInfo[portidx]->stats.txPkts);
- s->set_tx_bytes(portInfo[portidx]->stats.txBytes);
+ s->set_tx_pkts(portInfo[portidx]->stats.txPkts -
+ portInfo[portidx]->epochStats.txPkts);
+ s->set_tx_bytes(portInfo[portidx]->stats.txBytes -
+ portInfo[portidx]->epochStats.txBytes);
+ s->set_tx_pkts_nic(portInfo[portidx]->stats.txPktsNic -
+ portInfo[portidx]->epochStats.txPktsNic);
+ s->set_tx_bytes_nic(portInfo[portidx]->stats.txBytesNic -
+ portInfo[portidx]->epochStats.txBytesNic);
s->set_tx_pps(portInfo[portidx]->stats.txPps);
s->set_tx_bps(portInfo[portidx]->stats.txBps);
}
diff --git a/server/myservice.h b/server/myservice.h
index 69e2f71..ecb474e 100644
--- a/server/myservice.h
+++ b/server/myservice.h
@@ -16,9 +16,16 @@
#include "../rpc/pbhelper.h"
+#ifdef Q_OS_WIN32
+#include
+#endif
+
#define MAX_PKT_HDR_SIZE 1536
#define MAX_STREAM_NAME_SIZE 64
+//! 7 byte Preamble + 1 byte SFD + 4 byte FCS
+#define ETH_FRAME_HDR_SIZE 12
+
class MyService;
class StreamInfo
@@ -29,7 +36,13 @@ class StreamInfo
OstProto::Stream d;
StreamInfo() { PbHelper pbh; pbh.ForceSetSingularDefault(&d); }
- int StreamInfo::makePacket(uchar *buf, int bufMaxSize);
+
+ //quint16 ipv4Cksum(quint16 ipHdrLen, quint16 buff[]);
+ quint16 ipv4Cksum(uchar *buf, int len);
+ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n);
+public:
+ bool operator < (const StreamInfo &s) const
+ { return(d.core().ordinal() < s.d.core().ordinal()); }
};
@@ -41,7 +54,10 @@ class PortInfo
{
friend class PortInfo;
- PortInfo *port;
+ PortInfo *port;
+#ifdef Q_OS_WIN32
+ PPACKET_OID_DATA oidData;
+#endif
public:
PortMonitor(PortInfo *port);
static void callback(u_char *state,
@@ -51,26 +67,47 @@ class PortInfo
OstProto::Port d;
- pcap_if_t *dev;
- pcap_t *devHandle;
- pcap_send_queue *sendQueue;
- bool isSendQueueDirty;
- PortMonitor monitor;
-
struct PortStats
{
quint64 rxPkts;
quint64 rxBytes;
+ quint64 rxPktsNic;
+ quint64 rxBytesNic;
quint64 rxPps;
quint64 rxBps;
quint64 txPkts;
quint64 txBytes;
+ quint64 txPktsNic;
+ quint64 txBytesNic;
quint64 txPps;
quint64 txBps;
};
+ //! \todo Need lock for stats access/update
+
+ //! Stuff we need to maintain since PCAP doesn't as of now. As and when
+ // PCAP supports it, we'll remove from here
+ struct PcapExtra
+ {
+ //! pcap_sendqueue_transmit() only returns 'bytes' sent
+ uint sendQueueNumPkts;
+
+ //! PCAP doesn't do any tx stats
+ quint64 txPkts;
+ quint64 txBytes;
+ };
+
+ pcap_if_t *dev;
+ pcap_t *devHandle;
+ pcap_send_queue *sendQueue;
+ bool isSendQueueDirty;
+ PcapExtra pcapExtra;
+ PortMonitor monitor;
+
+ struct PortStats epochStats;
struct PortStats stats;
+ struct timeval lastTs; //! used for Rate Stats calculations
/*! StreamInfo::d::stream_id and index into streamList[] are NOT same! */
QList streamList;