Tcp/Udp checksums done.
Frame Length Modes done. Data Pattern Modes done. Some minor fixes/enhancements in streamconfigdialog. Added a "Edit Stream" action in StreamList context menu
This commit is contained in:
parent
62a82dfb80
commit
bfc0e8d4c8
@ -159,6 +159,7 @@ void PortGroup::when_configApply(int portIndex, uint *cookie)
|
||||
|
||||
case 3:
|
||||
qDebug("apply completed");
|
||||
mPorts[portIndex].when_syncComplete();
|
||||
delete cookie;
|
||||
break;
|
||||
|
||||
|
@ -12,7 +12,7 @@ PortStatsModel::PortStatsModel(PortGroupList *p, QObject *parent)
|
||||
|
||||
timer = new QTimer();
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(updateStats()));
|
||||
timer->start(5000);
|
||||
timer->start(2000);
|
||||
}
|
||||
|
||||
int PortStatsModel::rowCount(const QModelIndex &parent) const
|
||||
|
@ -23,6 +23,7 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent)
|
||||
tvPortList->addAction(actionDisconnect_Port_Group);
|
||||
|
||||
tvStreamList->addAction(actionNew_Stream);
|
||||
tvStreamList->addAction(actionEdit_Stream);
|
||||
tvStreamList->addAction(actionDelete_Stream);
|
||||
|
||||
tvStreamList->setModel(plm->getStreamModel());
|
||||
@ -32,10 +33,12 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent)
|
||||
SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)),
|
||||
this, SLOT(when_portModel_dataChanged(const QModelIndex&,
|
||||
const QModelIndex&)));
|
||||
|
||||
connect( tvPortList->selectionModel(),
|
||||
SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)),
|
||||
this, SLOT(when_portView_currentChanged(const QModelIndex&,
|
||||
const QModelIndex&)));
|
||||
|
||||
connect( tvStreamList->selectionModel(),
|
||||
SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)),
|
||||
this, SLOT(when_streamView_currentChanged(const QModelIndex&,
|
||||
@ -43,13 +46,16 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent)
|
||||
connect( tvStreamList->selectionModel(),
|
||||
SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
|
||||
this, SLOT(when_streamView_selectionChanged()));
|
||||
|
||||
#if 0
|
||||
connect( tvPortList->selectionModel(),
|
||||
SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)),
|
||||
plm->getStreamModel(), SLOT(setCurrentPortIndex(const QModelIndex&)));
|
||||
#endif
|
||||
|
||||
// Initially we don't have any ports - so trigger selection of
|
||||
// portgroup detail page
|
||||
// Initially we don't have any ports/streams - so send signal triggers
|
||||
when_portView_currentChanged(QModelIndex(), QModelIndex());
|
||||
when_streamView_currentChanged(QModelIndex(), QModelIndex());
|
||||
}
|
||||
|
||||
PortsWindow::~PortsWindow()
|
||||
@ -66,11 +72,6 @@ void PortsWindow::on_tvStreamList_activated(const QModelIndex & index)
|
||||
qDebug("%s: invalid index", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
#if 0 // CleanedUp!
|
||||
// FIXME(MED): This way of passing params must be changed
|
||||
scd = new StreamConfigDialog(plm->getStreamModel()->currentPortStreamList(),
|
||||
(uint) index.row(), this);
|
||||
#endif
|
||||
scd = new StreamConfigDialog(plm->port(tvPortList->currentIndex()),
|
||||
index.row(), this);
|
||||
qDebug("stream list activated\n");
|
||||
@ -81,7 +82,9 @@ void PortsWindow::on_tvStreamList_activated(const QModelIndex & index)
|
||||
void PortsWindow::when_portView_currentChanged(const QModelIndex& current,
|
||||
const QModelIndex& previous)
|
||||
{
|
||||
plm->getStreamModel()->setCurrentPortIndex(current);
|
||||
updatePortViewActions(current);
|
||||
updateStreamViewActions();
|
||||
|
||||
if (!current.isValid())
|
||||
{
|
||||
@ -143,16 +146,32 @@ void PortsWindow::updateStreamViewActions(const QModelIndex& current)
|
||||
|
||||
void PortsWindow::updateStreamViewActions()
|
||||
{
|
||||
if (tvStreamList->selectionModel()->hasSelection())
|
||||
// For some reason hasSelection() returns true even if selection size is 0
|
||||
// so additional check for size introduced
|
||||
if (tvStreamList->selectionModel()->hasSelection() &&
|
||||
(tvStreamList->selectionModel()->selection().size() > 0))
|
||||
{
|
||||
qDebug("Has selection %d",
|
||||
tvStreamList->selectionModel()->selection().size());
|
||||
// If more than one non-contiguous ranges selected, disable "New"
|
||||
|
||||
// If more than one non-contiguous ranges selected,
|
||||
// disable "New" and "Edit"
|
||||
if (tvStreamList->selectionModel()->selection().size() > 1)
|
||||
{
|
||||
actionNew_Stream->setDisabled(true);
|
||||
actionEdit_Stream->setDisabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
actionNew_Stream->setEnabled(true);
|
||||
|
||||
// Enable "Edit" only if the single range has a single row
|
||||
if (tvStreamList->selectionModel()->selection().at(0).height() > 1)
|
||||
actionEdit_Stream->setDisabled(true);
|
||||
else
|
||||
actionEdit_Stream->setEnabled(true);
|
||||
}
|
||||
|
||||
// Delete is always enabled as long as we have a selection
|
||||
actionDelete_Stream->setEnabled(true);
|
||||
}
|
||||
@ -160,6 +179,7 @@ void PortsWindow::updateStreamViewActions()
|
||||
{
|
||||
qDebug("No selection");
|
||||
actionNew_Stream->setEnabled(true);
|
||||
actionEdit_Stream->setDisabled(true);
|
||||
actionDelete_Stream->setDisabled(true);
|
||||
}
|
||||
}
|
||||
@ -346,6 +366,19 @@ void PortsWindow::on_actionNew_Stream_triggered()
|
||||
plm->getStreamModel()->insertRows(row, count);
|
||||
}
|
||||
|
||||
void PortsWindow::on_actionEdit_Stream_triggered()
|
||||
{
|
||||
qDebug("Edit Stream Action");
|
||||
|
||||
// Ensure we have only one range selected which contains only one row
|
||||
if ((tvStreamList->selectionModel()->selection().size() == 1) &&
|
||||
(tvStreamList->selectionModel()->selection().at(0).height() == 1))
|
||||
{
|
||||
on_tvStreamList_activated(tvStreamList->selectionModel()->
|
||||
selection().at(0).topLeft());
|
||||
}
|
||||
}
|
||||
|
||||
void PortsWindow::on_actionDelete_Stream_triggered()
|
||||
{
|
||||
qDebug("Delete Stream Action");
|
||||
|
@ -49,6 +49,7 @@ private slots:
|
||||
void on_actionDisconnect_Port_Group_triggered();
|
||||
|
||||
void on_actionNew_Stream_triggered();
|
||||
void on_actionEdit_Stream_triggered();
|
||||
void on_actionDelete_Stream_triggered();
|
||||
};
|
||||
|
||||
|
@ -206,6 +206,14 @@
|
||||
<string>Delete Stream</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEdit_Stream" >
|
||||
<property name="icon" >
|
||||
<iconset resource="ostinato.qrc" >:/icons/stream_edit.png</iconset>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Edit Stream</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="ostinato.qrc" />
|
||||
|
@ -883,9 +883,9 @@ public:
|
||||
};
|
||||
|
||||
enum DataPatternMode {
|
||||
e_dp_fixed,
|
||||
e_dp_inc,
|
||||
e_dp_dec,
|
||||
e_dp_fixed_word,
|
||||
e_dp_inc_byte,
|
||||
e_dp_dec_byte,
|
||||
e_dp_random
|
||||
};
|
||||
|
||||
|
@ -13,6 +13,8 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
|
||||
setupUi(this);
|
||||
setupUiExtra();
|
||||
|
||||
// setupUi
|
||||
|
||||
// Time to play match the signals and slots!
|
||||
connect(rbFtNone, SIGNAL(toggled(bool)), rbL3None, SLOT(setChecked(bool)));
|
||||
|
||||
@ -28,6 +30,11 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
|
||||
connect(rbFtNone, SIGNAL(toggled(bool)), lblType, SLOT(setHidden(bool)));
|
||||
connect(rbFtNone, SIGNAL(toggled(bool)), leType, SLOT(setHidden(bool)));
|
||||
|
||||
// Enable/Disable L3 Protocol Choices for FT None
|
||||
connect(rbFtNone, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool)));
|
||||
connect(rbFtNone, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setDisabled(bool)));
|
||||
connect(rbFtNone, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setDisabled(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)));
|
||||
@ -40,6 +47,11 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
|
||||
connect(rbFtEthernet2, SIGNAL(toggled(bool)), lblType, SLOT(setVisible(bool)));
|
||||
connect(rbFtEthernet2, SIGNAL(toggled(bool)), leType, SLOT(setVisible(bool)));
|
||||
|
||||
// Enable/Disable L3 Protocol Choices for FT Ethernet2
|
||||
connect(rbFtEthernet2, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool)));
|
||||
connect(rbFtEthernet2, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setEnabled(bool)));
|
||||
connect(rbFtEthernet2, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setEnabled(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)));
|
||||
@ -52,6 +64,14 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
|
||||
connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), lblType, SLOT(setHidden(bool)));
|
||||
connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), leType, SLOT(setHidden(bool)));
|
||||
|
||||
// Force L3 = None if FT = 802.3 Raw
|
||||
connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3None, SLOT(setChecked(bool)));
|
||||
|
||||
// Enable/Disable L3 Protocol Choices for FT 802Dot3Raw
|
||||
connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool)));
|
||||
connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setDisabled(bool)));
|
||||
connect(rbFt802Dot3Raw, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setDisabled(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)));
|
||||
@ -64,6 +84,14 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
|
||||
connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), lblType, SLOT(setHidden(bool)));
|
||||
connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), leType, SLOT(setHidden(bool)));
|
||||
|
||||
// Force L3 = None if FT = 802.3 LLC (to ensure a valid L3 is selected)
|
||||
connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3None, SLOT(setChecked(bool)));
|
||||
|
||||
// Enable/Disable L3 Protocol Choices for FT 802Dot3Llc
|
||||
connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool)));
|
||||
connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setEnabled(bool)));
|
||||
connect(rbFt802Dot3Llc, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setDisabled(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)));
|
||||
@ -76,6 +104,11 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
|
||||
connect(rbFtLlcSnap, SIGNAL(toggled(bool)), lblType, SLOT(setVisible(bool)));
|
||||
connect(rbFtLlcSnap, SIGNAL(toggled(bool)), leType, SLOT(setVisible(bool)));
|
||||
|
||||
// Enable/Disable L3 Protocol Choices for FT 802.3 LLC SNAP
|
||||
connect(rbFtLlcSnap, SIGNAL(toggled(bool)), rbL3None, SLOT(setEnabled(bool)));
|
||||
connect(rbFtLlcSnap, SIGNAL(toggled(bool)), rbL3Ipv4, SLOT(setEnabled(bool)));
|
||||
connect(rbFtLlcSnap, SIGNAL(toggled(bool)), rbL3Arp, SLOT(setEnabled(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)));
|
||||
@ -90,7 +123,6 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
|
||||
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)));
|
||||
@ -101,7 +133,6 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
|
||||
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)));
|
||||
@ -109,15 +140,20 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
|
||||
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()
|
||||
//TODO: remove if not needed
|
||||
#if 0
|
||||
// This set of 'clicks' is a hack to trigger signals at dialog creation
|
||||
// time so that a coherent 'set' is initialized
|
||||
// Actual stream values will be initialized by LoadCurrentStream()
|
||||
rbL3Ipv4->click();
|
||||
rbL3None->click();
|
||||
rbFtEthernet2->click();
|
||||
rbFtNone->click();
|
||||
#endif
|
||||
|
||||
//mpStreamList = streamList;
|
||||
mCurrentStreamIndex = streamIndex;
|
||||
@ -148,7 +184,21 @@ void StreamConfigDialog::setupUiExtra()
|
||||
QRegExp reHex4B("[0-9,a-f,A-F]{1,8}");
|
||||
QRegExp reMac("([0-9,a-f,A-F]{2,2}[:-]){5,5}[0-9,a-f,A-F]{2,2}");
|
||||
|
||||
// Setup default stuff that cannot be done in designer
|
||||
// ---- Setup default stuff that cannot be done in designer ----
|
||||
|
||||
// Since the dialog defaults are FT = None, L3 = None, L4 = None;
|
||||
// hide associated input fields since it can't be done in Designer
|
||||
lblDsap->setHidden(true);
|
||||
leDsap->setHidden(true);
|
||||
lblSsap->setHidden(true);
|
||||
leSsap->setHidden(true);
|
||||
lblControl->setHidden(true);
|
||||
leControl->setHidden(true);
|
||||
lblOui->setHidden(true);
|
||||
leOui->setHidden(true);
|
||||
lblType->setHidden(true);
|
||||
leType->setHidden(true);
|
||||
|
||||
twProto->setTabEnabled(2, FALSE);
|
||||
twProto->setTabEnabled(3, FALSE);
|
||||
|
||||
@ -189,17 +239,73 @@ StreamConfigDialog::~StreamConfigDialog()
|
||||
delete mpPacketModel;
|
||||
}
|
||||
|
||||
void StreamConfigDialog::on_cmbPatternMode_currentIndexChanged(QString mode)
|
||||
{
|
||||
if (mode == "Fixed Word")
|
||||
{
|
||||
lePattern->setEnabled(true);
|
||||
}
|
||||
else if (mode == "Increment Byte")
|
||||
{
|
||||
lePattern->setDisabled(true);
|
||||
}
|
||||
else if (mode == "Decrement Byte")
|
||||
{
|
||||
lePattern->setDisabled(true);
|
||||
}
|
||||
if (mode == "Random")
|
||||
{
|
||||
lePattern->setDisabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning("Unhandled/Unknown PatternMode = %s", mode.toAscii().data());
|
||||
}
|
||||
}
|
||||
void StreamConfigDialog::on_cmbPktLenMode_currentIndexChanged(QString mode)
|
||||
{
|
||||
if (mode == "Fixed")
|
||||
{
|
||||
lePktLen->setEnabled(true);
|
||||
lePktLenMin->setDisabled(true);
|
||||
lePktLenMax->setDisabled(true);
|
||||
}
|
||||
else if (mode == "Increment")
|
||||
{
|
||||
lePktLen->setDisabled(true);
|
||||
lePktLenMin->setEnabled(true);
|
||||
lePktLenMax->setEnabled(true);
|
||||
}
|
||||
else if (mode == "Decrement")
|
||||
{
|
||||
lePktLen->setDisabled(true);
|
||||
lePktLenMin->setEnabled(true);
|
||||
lePktLenMax->setEnabled(true);
|
||||
}
|
||||
else if (mode == "Random")
|
||||
{
|
||||
lePktLen->setDisabled(true);
|
||||
lePktLenMin->setEnabled(true);
|
||||
lePktLenMax->setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning("Unhandled/Unknown PktLenMode = %s", mode.toAscii().data());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void StreamConfigDialog::on_cmbDstMacMode_currentIndexChanged(QString mode)
|
||||
{
|
||||
if (mode == "Fixed")
|
||||
{
|
||||
leDstMacCount->setEnabled(FALSE);
|
||||
leDstMacStep->setEnabled(FALSE);
|
||||
leDstMacCount->setEnabled(false);
|
||||
leDstMacStep->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
leDstMacCount->setEnabled(TRUE);
|
||||
leDstMacStep->setEnabled(TRUE);
|
||||
leDstMacCount->setEnabled(true);
|
||||
leDstMacStep->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,13 +313,41 @@ void StreamConfigDialog::on_cmbSrcMacMode_currentIndexChanged(QString mode)
|
||||
{
|
||||
if (mode == "Fixed")
|
||||
{
|
||||
leSrcMacCount->setEnabled(FALSE);
|
||||
leSrcMacStep->setEnabled(FALSE);
|
||||
leSrcMacCount->setEnabled(false);
|
||||
leSrcMacStep->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
leSrcMacCount->setEnabled(TRUE);
|
||||
leSrcMacStep->setEnabled(TRUE);
|
||||
leSrcMacCount->setEnabled(true);
|
||||
leSrcMacStep->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void StreamConfigDialog::on_cmbIpSrcAddrMode_currentIndexChanged(QString mode)
|
||||
{
|
||||
if (mode == "Fixed")
|
||||
{
|
||||
leIpSrcAddrCount->setDisabled(true);
|
||||
leIpSrcAddrMask->setDisabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
leIpSrcAddrCount->setEnabled(true);
|
||||
leIpSrcAddrMask->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void StreamConfigDialog::on_cmbIpDstAddrMode_currentIndexChanged(QString mode)
|
||||
{
|
||||
if (mode == "Fixed")
|
||||
{
|
||||
leIpDstAddrCount->setDisabled(true);
|
||||
leIpDstAddrMask->setDisabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
leIpDstAddrCount->setEnabled(true);
|
||||
leIpDstAddrMask->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -371,14 +505,6 @@ void StreamConfigDialog::on_rbL4Udp_toggled(bool checked)
|
||||
}
|
||||
}
|
||||
|
||||
void StreamConfigDialog::on_rbL4Other_toggled(bool checked)
|
||||
{
|
||||
if (checked)
|
||||
leIpProto->setEnabled(true);
|
||||
else
|
||||
leIpProto->setEnabled(false);
|
||||
}
|
||||
|
||||
void StreamConfigDialog::update_NumPacketsAndNumBursts()
|
||||
{
|
||||
if (rbSendPackets->isChecked() && rbModeFixed->isChecked())
|
||||
@ -512,32 +638,6 @@ void StreamConfigDialog::LoadCurrentStream()
|
||||
qDebug("%s: unknown l4 Protocol %d", __FUNCTION__,
|
||||
pStream->l4Proto());
|
||||
}
|
||||
// PB (not needed anymore?)
|
||||
#if 0
|
||||
// Check for specific supported protocols first ...
|
||||
if (pStream->eth2()->type() == ETH_TYP_IP)
|
||||
rbL3Ipv4->setChecked(TRUE);
|
||||
else if (pStream->eth2()->type() == ETH_TYP_ARP)
|
||||
rbL3Arp->setChecked(TRUE);
|
||||
|
||||
// ... then for None/Other
|
||||
rbL3None->setChecked((pStream->proto.protoMask & PM_L3_PROTO_NONE) > 0);
|
||||
rbL3Other->setChecked((pStream->proto.protoMask & PM_L3_PROTO_OTHER) > 0);
|
||||
|
||||
// Check for specific supported protocols first ...
|
||||
if (pStream->proto.ipProto == IP_PROTO_ICMP)
|
||||
rbL4Icmp->setChecked(TRUE);
|
||||
else if (pStream->proto.ipProto == IP_PROTO_IGMP)
|
||||
rbL4Igmp->setChecked(TRUE);
|
||||
else if (pStream->proto.ipProto == IP_PROTO_TCP)
|
||||
rbL4Tcp->setChecked(TRUE);
|
||||
else if (pStream->proto.ipProto == IP_PROTO_UDP)
|
||||
rbL4Udp->setChecked(TRUE);
|
||||
|
||||
// ... then for None/Other
|
||||
rbL4None->setChecked((pStream->proto.protoMask & PM_L4_PROTO_NONE) > 0);
|
||||
rbL4Other->setChecked((pStream->proto.protoMask & PM_L4_PROTO_OTHER) > 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
// L2
|
||||
|
@ -39,8 +39,12 @@ private:
|
||||
void StoreCurrentStream();
|
||||
|
||||
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();
|
||||
|
||||
@ -57,7 +61,6 @@ private slots:
|
||||
void on_rbL4Igmp_toggled(bool checked);
|
||||
void on_rbL4Tcp_toggled(bool checked);
|
||||
void on_rbL4Udp_toggled(bool checked);
|
||||
void on_rbL4Other_toggled(bool checked);
|
||||
|
||||
void update_NumPacketsAndNumBursts();
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>554</width>
|
||||
<width>534</width>
|
||||
<height>521</height>
|
||||
</rect>
|
||||
</property>
|
||||
@ -63,17 +63,17 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
<widget class="QComboBox" name="cmbPatternMode" >
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Fixed</string>
|
||||
<string>Fixed Word</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Increment</string>
|
||||
<string>Increment Byte</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Decrement</string>
|
||||
<string>Decrement Byte</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
@ -141,6 +141,9 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
</item>
|
||||
<item row="0" column="2" >
|
||||
<widget class="QLineEdit" name="lePktLenMin" >
|
||||
<property name="enabled" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>64</string>
|
||||
</property>
|
||||
@ -174,6 +177,9 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
</item>
|
||||
<item row="1" column="2" >
|
||||
<widget class="QLineEdit" name="lePktLenMax" >
|
||||
<property name="enabled" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>64</string>
|
||||
</property>
|
||||
@ -373,6 +379,9 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbL3Ipv4" >
|
||||
<property name="enabled" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>IPv4</string>
|
||||
</property>
|
||||
@ -383,18 +392,11 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbL3Arp" >
|
||||
<property name="text" >
|
||||
<string>ARP</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbL3Other" >
|
||||
<property name="enabled" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Other</string>
|
||||
<string>ARP</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -420,7 +422,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
<item row="0" column="1" >
|
||||
<widget class="QRadioButton" name="rbL4Icmp" >
|
||||
<property name="enabled" >
|
||||
<bool>true</bool>
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>ICMP</string>
|
||||
@ -430,7 +432,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
<item row="0" column="2" >
|
||||
<widget class="QRadioButton" name="rbL4Igmp" >
|
||||
<property name="enabled" >
|
||||
<bool>true</bool>
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>IGMP</string>
|
||||
@ -440,7 +442,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
<item row="1" column="0" >
|
||||
<widget class="QRadioButton" name="rbL4Tcp" >
|
||||
<property name="enabled" >
|
||||
<bool>true</bool>
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>TCP</string>
|
||||
@ -449,21 +451,11 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
</item>
|
||||
<item row="1" column="1" >
|
||||
<widget class="QRadioButton" name="rbL4Udp" >
|
||||
<property name="enabled" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>UDP</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2" >
|
||||
<widget class="QRadioButton" name="rbL4Other" >
|
||||
<property name="enabled" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Other</string>
|
||||
<string>UDP</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -483,6 +475,19 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="2" >
|
||||
<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>
|
||||
<widget class="QWidget" name="tab_4" >
|
||||
@ -1054,7 +1059,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" >
|
||||
<item row="0" column="3" >
|
||||
<layout class="QGridLayout" >
|
||||
<item row="0" column="0" >
|
||||
<widget class="QLabel" name="label_25" >
|
||||
@ -1130,7 +1135,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="3" >
|
||||
<item row="1" column="0" colspan="4" >
|
||||
<widget class="QGroupBox" name="groupBox_7" >
|
||||
<property name="title" >
|
||||
<string/>
|
||||
@ -1206,6 +1211,9 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
</item>
|
||||
<item row="1" column="3" >
|
||||
<widget class="QLineEdit" name="leIpSrcAddrCount" >
|
||||
<property name="enabled" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string/>
|
||||
</property>
|
||||
@ -1213,6 +1221,9 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
</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>
|
||||
@ -1264,6 +1275,9 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
</item>
|
||||
<item row="2" column="3" >
|
||||
<widget class="QLineEdit" name="leIpDstAddrCount" >
|
||||
<property name="enabled" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string/>
|
||||
</property>
|
||||
@ -1271,6 +1285,9 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
</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>
|
||||
@ -1279,7 +1296,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="3" >
|
||||
<item row="2" column="0" colspan="4" >
|
||||
<layout class="QHBoxLayout" >
|
||||
<item>
|
||||
<widget class="QLabel" name="label_29" >
|
||||
@ -1310,14 +1327,14 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="3" >
|
||||
<item row="3" column="0" colspan="4" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>470</width>
|
||||
<width>469</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -1355,7 +1372,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="swL4Proto" >
|
||||
<property name="currentIndex" >
|
||||
<number>1</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page" >
|
||||
<layout class="QGridLayout" >
|
||||
|
@ -169,9 +169,9 @@ message StreamCore {
|
||||
}
|
||||
|
||||
enum DataPatternMode {
|
||||
e_dp_fixed = 0;
|
||||
e_dp_inc = 1;
|
||||
e_dp_dec = 2;
|
||||
e_dp_fixed_word = 0;
|
||||
e_dp_inc_byte = 1;
|
||||
e_dp_dec_byte = 2;
|
||||
e_dp_random = 3;
|
||||
}
|
||||
|
||||
@ -195,8 +195,8 @@ message StreamCore {
|
||||
// Frame Length (includes CRC)
|
||||
optional FrameLengthMode len_mode = 14 [default = e_fl_fixed];
|
||||
optional uint32 frame_len = 15 [default = 64];
|
||||
optional uint32 frame_len_min = 16;
|
||||
optional uint32 frame_len_max = 17;
|
||||
optional uint32 frame_len_min = 16 [default = 64];
|
||||
optional uint32 frame_len_max = 17 [default = 1518];
|
||||
|
||||
// Currently Selected Protocols
|
||||
optional FrameType ft = 21 [default = e_ft_none];
|
||||
|
@ -12,65 +12,105 @@
|
||||
#define LOG(...) {sprintf(logStr, __VA_ARGS__); host->Log(logStr);}
|
||||
#define MB (1024*1024)
|
||||
|
||||
#if 0
|
||||
quint16 StreamInfo::ipv4Cksum(quint16 ipHdrLen, quint16 buff[])
|
||||
quint32 StreamInfo::pseudoHdrCksumPartial(quint32 srcIp, quint32 dstIp,
|
||||
quint8 protocol, quint16 len)
|
||||
{
|
||||
quint32 sum;
|
||||
|
||||
sum = srcIp >> 16;
|
||||
sum += srcIp & 0xFFFF;
|
||||
sum += dstIp >> 16;
|
||||
sum += dstIp & 0xFFFF;
|
||||
sum += (quint16) (protocol);
|
||||
sum += len;
|
||||
|
||||
// Above calculation done assuming 'big endian' - so convert to host order
|
||||
return qFromBigEndian(sum);
|
||||
}
|
||||
|
||||
quint32 StreamInfo::ipv4CksumPartial(uchar *buf, int len)
|
||||
{
|
||||
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)
|
||||
if (len & 0x0001)
|
||||
{
|
||||
qFatal("Cannot calculate partial checksum on non multiple of 2 length");
|
||||
return 0;
|
||||
}
|
||||
|
||||
while(len)
|
||||
{
|
||||
sum += *ip;
|
||||
if(sum & 0x80000000) /* if high order bit set, fold */
|
||||
if(sum & 0x80000000)
|
||||
sum = (sum & 0xFFFF) + (sum >> 16);
|
||||
ip++;
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
if(len) /* take care of left over byte */
|
||||
return sum;
|
||||
}
|
||||
|
||||
quint16 StreamInfo::ipv4Cksum(uchar *buf, int len, quint32 partialSum)
|
||||
{
|
||||
quint32 sum = partialSum;
|
||||
quint16 *ip = (quint16*) buf;
|
||||
|
||||
while(len > 1)
|
||||
{
|
||||
sum += *ip;
|
||||
if(sum & 0x80000000)
|
||||
sum = (sum & 0xFFFF) + (sum >> 16);
|
||||
ip++;
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
if (len)
|
||||
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;
|
||||
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];
|
||||
|
||||
// TODO(HI): use FrameLengthMode - don't assume fixed
|
||||
// Decide a frame length based on length mode
|
||||
switch(d.core().len_mode())
|
||||
{
|
||||
case OstProto::StreamCore::e_fl_fixed:
|
||||
pktLen = d.core().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));
|
||||
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));
|
||||
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));
|
||||
break;
|
||||
default:
|
||||
qWarning("Unhandled len mode %d. Using default 64",
|
||||
d.core().len_mode());
|
||||
pktLen = 64;
|
||||
break;
|
||||
}
|
||||
|
||||
// pktLen is adjusted for CRC/FCS which will be added by the NIC
|
||||
pktLen = d.core().frame_len() - 4;
|
||||
if (bufMaxSize < pktLen)
|
||||
pktLen -= 4;
|
||||
|
||||
if ((pktLen < 0) || (pktLen > bufMaxSize))
|
||||
return 0;
|
||||
|
||||
// We always have a Mac Header!
|
||||
@ -226,30 +266,34 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n)
|
||||
qToBigEndian((quint16) 0, buf+len);
|
||||
len += 2;
|
||||
|
||||
// TODO(HI): Use IpMode - don't assume fixed
|
||||
// Get Src/Dst IP for this packet using respective IpMode
|
||||
switch(d.ip().src_ip_mode())
|
||||
{
|
||||
case OstProto::Ip::e_im_fixed:
|
||||
qToBigEndian((quint32) d.ip().src_ip(), buf+len);
|
||||
srcIp = (quint32) d.ip().src_ip();
|
||||
qToBigEndian(srcIp, 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);
|
||||
srcIp = (quint32) (subnet | host);
|
||||
qToBigEndian(srcIp, 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);
|
||||
srcIp = (quint32) (subnet | host);
|
||||
qToBigEndian(srcIp, 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);
|
||||
srcIp = (quint32) (subnet | host);
|
||||
qToBigEndian(srcIp, buf+len);
|
||||
break;
|
||||
default:
|
||||
qWarning("Unhandled src_ip_mode = %d", d.ip().src_ip_mode());
|
||||
@ -259,26 +303,30 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n)
|
||||
switch(d.ip().dst_ip_mode())
|
||||
{
|
||||
case OstProto::Ip::e_im_fixed:
|
||||
qToBigEndian((quint32) d.ip().dst_ip(), buf+len);
|
||||
dstIp = (quint32) d.ip().dst_ip();
|
||||
qToBigEndian(dstIp, 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);
|
||||
dstIp = (quint32) (subnet | host);
|
||||
qToBigEndian(dstIp, 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);
|
||||
dstIp = (quint32) (subnet | host);
|
||||
qToBigEndian(dstIp, 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);
|
||||
dstIp = (quint32) (subnet | host);
|
||||
qToBigEndian(dstIp, buf+len);
|
||||
break;
|
||||
default:
|
||||
qWarning("Unhandled dst_ip_mode = %d", d.ip().dst_ip_mode());
|
||||
@ -291,6 +339,7 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n)
|
||||
else
|
||||
*((quint16*)(buf + ipOfs + 10)) = ipv4Cksum(buf + ipOfs, len-ipOfs);
|
||||
break;
|
||||
|
||||
}
|
||||
case OstProto::StreamCore::e_l3_arp:
|
||||
// TODO(LOW)
|
||||
@ -305,6 +354,10 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n)
|
||||
break;
|
||||
case OstProto::StreamCore::e_l4_tcp:
|
||||
{
|
||||
tcpOfs = len;
|
||||
|
||||
cumCksum = pseudoHdrCksumPartial(srcIp, dstIp, 6, pktLen - len);
|
||||
|
||||
qToBigEndian((quint16) d.tcp().src_port(), buf+len);
|
||||
len += 2;
|
||||
qToBigEndian((quint16) d.tcp().dst_port(), buf+len);
|
||||
@ -318,26 +371,30 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n)
|
||||
if (d.tcp().is_override_hdrlen())
|
||||
buf[len+0] = (quint8) d.tcp().hdrlen_rsvd();
|
||||
else
|
||||
buf[len+0] = (quint8) 0x50; // FIXME(LOW)
|
||||
buf[len+0] = (quint8) 0x50; // FIXME(LOW): Hardcoding
|
||||
buf[len+1] = (quint8) d.tcp().flags();
|
||||
len += 2;
|
||||
|
||||
qToBigEndian((quint16) d.tcp().window(), buf+len);
|
||||
len +=2;
|
||||
|
||||
if (d.tcp().is_override_cksum())
|
||||
qToBigEndian((quint16) d.tcp().cksum(), buf+len);
|
||||
else
|
||||
qToBigEndian((quint16) 0, buf+len); // FIXME(HI)
|
||||
// Fill in cksum as 0 for cksum calculation, actual cksum filled later
|
||||
qToBigEndian((quint16) 0, buf+len);
|
||||
len +=2;
|
||||
|
||||
qToBigEndian((quint16) d.tcp().urg_ptr(), buf+len);
|
||||
len +=2;
|
||||
|
||||
// Accumulate cumulative cksum
|
||||
cumCksum += ipv4CksumPartial(buf + tcpOfs, len - tcpOfs);
|
||||
|
||||
break;
|
||||
}
|
||||
case OstProto::StreamCore::e_l4_udp:
|
||||
{
|
||||
int udpLen = pktLen - len;
|
||||
udpOfs = len;
|
||||
|
||||
cumCksum = pseudoHdrCksumPartial(srcIp, dstIp, 17, pktLen - len);
|
||||
|
||||
qToBigEndian((quint16) d.udp().src_port(), buf+len);
|
||||
len += 2;
|
||||
@ -347,14 +404,16 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n)
|
||||
if (d.udp().is_override_totlen())
|
||||
qToBigEndian((quint16) d.udp().totlen(), buf+len);
|
||||
else
|
||||
qToBigEndian((quint16) udpLen, buf+len);
|
||||
qToBigEndian((quint16) (pktLen - udpOfs), buf+len);
|
||||
len +=2;
|
||||
|
||||
if (d.udp().is_override_cksum())
|
||||
qToBigEndian((quint16) d.udp().cksum(), buf+len);
|
||||
else
|
||||
qToBigEndian((quint16) 0, buf+len); // FIXME(HI)
|
||||
// Fill in cksum as 0 for cksum calculation, actual cksum filled later
|
||||
qToBigEndian((quint16) 0, buf+len);
|
||||
len +=2;
|
||||
|
||||
// Accumulate cumulative cksum
|
||||
cumCksum += ipv4CksumPartial(buf + udpOfs, len - udpOfs);
|
||||
|
||||
break;
|
||||
}
|
||||
case OstProto::StreamCore::e_l4_icmp:
|
||||
@ -368,15 +427,51 @@ int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n)
|
||||
}
|
||||
|
||||
// Fill-in the data pattern
|
||||
{
|
||||
int dataLen;
|
||||
|
||||
dataLen = pktLen - len;
|
||||
for (int i = 0; i < (dataLen/4)+1; i++)
|
||||
switch(d.core().pattern_mode())
|
||||
{
|
||||
// TODO(HI): Use patternMode
|
||||
case OstProto::StreamCore::e_dp_fixed_word:
|
||||
for (int i = 0; i < (dataLen/4)+1; i++)
|
||||
qToBigEndian((quint32) d.core().pattern(), buf+len+(i*4));
|
||||
break;
|
||||
case OstProto::StreamCore::e_dp_inc_byte:
|
||||
for (int i = 0; i < dataLen; i++)
|
||||
buf[len + i] = i % (0xFF + 1);
|
||||
break;
|
||||
case OstProto::StreamCore::e_dp_dec_byte:
|
||||
for (int i = 0; i < dataLen; i++)
|
||||
buf[len + i] = 0xFF - (i % (0xFF + 1));
|
||||
break;
|
||||
case OstProto::StreamCore::e_dp_random:
|
||||
for (int i = 0; i < dataLen; i++)
|
||||
buf[len + i] = qrand() % (0xFF + 1);
|
||||
break;
|
||||
default:
|
||||
qWarning("Unhandled data pattern %d", d.core().pattern_mode());
|
||||
}
|
||||
|
||||
// Calculate TCP/UDP checksum over the data pattern/payload and fill in
|
||||
switch (d.core().l4_proto())
|
||||
{
|
||||
case OstProto::StreamCore::e_l4_tcp:
|
||||
if (d.tcp().is_override_cksum())
|
||||
qToBigEndian((quint16) d.tcp().cksum(), buf + tcpOfs + 16);
|
||||
else
|
||||
*((quint16*)(buf + tcpOfs + 16)) =
|
||||
ipv4Cksum(buf + len, dataLen, cumCksum);
|
||||
break;
|
||||
case OstProto::StreamCore::e_l4_udp:
|
||||
if (d.udp().is_override_cksum())
|
||||
qToBigEndian((quint16) d.udp().cksum(), buf + udpOfs + 6);
|
||||
else
|
||||
*((quint16*)(buf + udpOfs + 6)) =
|
||||
ipv4Cksum(buf + len, dataLen, cumCksum);
|
||||
break;
|
||||
case OstProto::StreamCore::e_l4_none:
|
||||
case OstProto::StreamCore::e_l4_icmp:
|
||||
case OstProto::StreamCore::e_l4_igmp:
|
||||
// No cksum processing required
|
||||
break;
|
||||
}
|
||||
|
||||
return pktLen;
|
||||
@ -414,7 +509,7 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev)
|
||||
}
|
||||
|
||||
d.mutable_port_id()->set_id(id);
|
||||
d.set_name("eth"); // FIXME(MED): suffix portid
|
||||
d.set_name(QString("eth%1").arg(id).toAscii().constData());
|
||||
d.set_description(dev->description);
|
||||
d.set_is_enabled(true); // FIXME(MED):check
|
||||
d.set_is_oper_up(true); // FIXME(MED):check
|
||||
@ -425,7 +520,7 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev)
|
||||
|
||||
// We'll create sendqueue later when required
|
||||
sendQueue = NULL;
|
||||
pcapExtra.sendQueueNumPkts = 0;
|
||||
pcapExtra.sendQueueCumLen.clear();
|
||||
pcapExtra.txPkts = 0;
|
||||
pcapExtra.txBytes = 0;
|
||||
isSendQueueDirty=true;
|
||||
@ -446,7 +541,7 @@ void PortInfo::update()
|
||||
|
||||
// TODO(LOW): calculate sendqueue size
|
||||
sendQueue = pcap_sendqueue_alloc(1*MB);
|
||||
pcapExtra.sendQueueNumPkts = 0;
|
||||
pcapExtra.sendQueueCumLen.clear();
|
||||
|
||||
// First sort the streams by ordinalValue
|
||||
qSort(streamList);
|
||||
@ -457,25 +552,34 @@ void PortInfo::update()
|
||||
{
|
||||
int numPackets, numBursts;
|
||||
|
||||
if (streamList[i].d.control().unit() ==
|
||||
OstProto::StreamControl::e_su_bursts)
|
||||
switch (streamList[i].d.control().unit())
|
||||
{
|
||||
case OstProto::StreamControl::e_su_bursts:
|
||||
numBursts = streamList[i].d.control().num_bursts();
|
||||
numPackets = streamList[i].d.control().packets_per_burst();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
case OstProto::StreamControl::e_su_packets:
|
||||
numBursts = 1;
|
||||
numPackets = streamList[i].d.control().num_packets();
|
||||
break;
|
||||
default:
|
||||
qWarning("Unhandled stream control unit %d",
|
||||
streamList[i].d.control().unit());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
int len;
|
||||
|
||||
len = streamList[i].makePacket(pktBuf, sizeof(pktBuf),
|
||||
j * numPackets + k);
|
||||
if (len > 0)
|
||||
{
|
||||
pktHdr.caplen = pktHdr.len = len;
|
||||
pktHdr.ts.tv_sec = pktHdr.ts.tv_usec = 0; // FIXME(HI)
|
||||
|
||||
if (-1 == pcap_sendqueue_queue(sendQueue, &pktHdr,
|
||||
@ -485,7 +589,8 @@ void PortInfo::update()
|
||||
"streamidx %d\n", id(), i);
|
||||
}
|
||||
else
|
||||
pcapExtra.sendQueueNumPkts++;
|
||||
pcapExtra.sendQueueCumLen.append(sendQueue->len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -496,7 +601,7 @@ void PortInfo::update()
|
||||
|
||||
void PortInfo::startTransmit()
|
||||
{
|
||||
uint bytes;
|
||||
uint bytes, pkts;
|
||||
|
||||
// TODO(HI): Stream Mode - one pass/continuous
|
||||
bytes = pcap_sendqueue_transmit(devHandle, sendQueue, false);
|
||||
@ -504,21 +609,35 @@ void PortInfo::startTransmit()
|
||||
{
|
||||
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;
|
||||
|
||||
// parse sendqueue using 'bytes' to get actual pkts sent
|
||||
#if 0
|
||||
// FIXME(LOW): Get this working
|
||||
pkts = qUpperBound(pcapExtra.sendQueueCumLen, bytes);
|
||||
#else
|
||||
for (int i = 0; i < pcapExtra.sendQueueCumLen.size(); i++)
|
||||
{
|
||||
if (pcapExtra.sendQueueCumLen.at(i) > bytes)
|
||||
{
|
||||
pkts = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug("port %d: sent (%d/%d) bytes\n", id(), bytes, sendQueue->len);
|
||||
pcapExtra.txPkts += pcapExtra.sendQueueNumPkts;
|
||||
pcapExtra.txBytes += bytes;
|
||||
pkts = pcapExtra.sendQueueCumLen.size();
|
||||
}
|
||||
|
||||
// pcap_sendqueue_transmit() returned 'bytes' includes size of pcap_pkthdr
|
||||
// - adjust for it
|
||||
pcapExtra.txBytes -= pcapExtra.sendQueueNumPkts * sizeof(pcap_pkthdr);
|
||||
if (bytes)
|
||||
bytes -= pkts * sizeof(pcap_pkthdr);
|
||||
|
||||
pcapExtra.txPkts += pkts;
|
||||
pcapExtra.txBytes += bytes;
|
||||
}
|
||||
|
||||
void PortInfo::stopTransmit()
|
||||
@ -951,7 +1070,7 @@ const ::OstProto::PortIdList* request,
|
||||
|
||||
portIdx = request->port_id(i).id();
|
||||
if (portIdx >= numPorts)
|
||||
continue; // FIXME(MED): partial RPC?
|
||||
continue; // TODO(LOW): partial RPC?
|
||||
|
||||
if (portInfo[portIdx]->isDirty())
|
||||
portInfo[portIdx]->update();
|
||||
@ -963,7 +1082,7 @@ const ::OstProto::PortIdList* request,
|
||||
|
||||
portIdx = request->port_id(i).id();
|
||||
if (portIdx >= numPorts)
|
||||
continue; // FIXME(MED): partial RPC?
|
||||
continue; // TODO(LOW): partial RPC?
|
||||
|
||||
portInfo[portIdx]->startTransmit();
|
||||
}
|
||||
@ -986,7 +1105,7 @@ const ::OstProto::PortIdList* request,
|
||||
|
||||
portIdx = request->port_id(i).id();
|
||||
if (portIdx >= numPorts)
|
||||
continue; // FIXME(MED): partial RPC?
|
||||
continue; // TODO(LOW): partial RPC?
|
||||
|
||||
portInfo[portIdx]->stopTransmit();
|
||||
}
|
||||
@ -1038,7 +1157,7 @@ const ::OstProto::PortIdList* request,
|
||||
|
||||
portidx = request->port_id(i).id();
|
||||
if (portidx >= numPorts)
|
||||
continue; // FIXME(med): partial rpc?
|
||||
continue; // TODO(LOW): partial rpc?
|
||||
|
||||
s = response->add_port_stats();
|
||||
s->mutable_port_id()->set_id(request->port_id(i).id());
|
||||
@ -1082,7 +1201,7 @@ const ::OstProto::PortIdList* request,
|
||||
|
||||
portIdx = request->port_id(i).id();
|
||||
if (portIdx >= numPorts)
|
||||
continue; // FIXME(MED): partial RPC?
|
||||
continue; // TODO(LOW): partial RPC?
|
||||
|
||||
portInfo[portIdx]->resetStats();
|
||||
}
|
||||
|
@ -37,8 +37,10 @@ class StreamInfo
|
||||
|
||||
StreamInfo() { PbHelper pbh; pbh.ForceSetSingularDefault(&d); }
|
||||
|
||||
//quint16 ipv4Cksum(quint16 ipHdrLen, quint16 buff[]);
|
||||
quint16 ipv4Cksum(uchar *buf, int len);
|
||||
quint32 pseudoHdrCksumPartial(quint32 srcIp, quint32 dstIp,
|
||||
quint8 protocol, quint16 len);
|
||||
quint32 ipv4CksumPartial(uchar *buf, int len);
|
||||
quint16 ipv4Cksum(uchar *buf, int len, quint32 partialSum = 0);
|
||||
int StreamInfo::makePacket(uchar *buf, int bufMaxSize, int n);
|
||||
public:
|
||||
bool operator < (const StreamInfo &s) const
|
||||
@ -90,8 +92,10 @@ class PortInfo
|
||||
// PCAP supports it, we'll remove from here
|
||||
struct PcapExtra
|
||||
{
|
||||
//! pcap_sendqueue_transmit() only returns 'bytes' sent
|
||||
uint sendQueueNumPkts;
|
||||
//! Used to track num of packets (and their sizes) in the
|
||||
// send queue. Also used to find out actual num of pkts sent
|
||||
// in case of partial send in pcap_sendqueue_transmit()
|
||||
QList<uint> sendQueueCumLen;
|
||||
|
||||
//! PCAP doesn't do any tx stats
|
||||
quint64 txPkts;
|
||||
|
Loading…
Reference in New Issue
Block a user