Rewrote DumpView as a subclass of QAbstractItemView (as it should be). Correspondingly reworked PacketModel to work with DumpView. Added Dot3Protocol and PayloadProtocol to Stream class
This commit is contained in:
parent
c7f4c1dec9
commit
9e7b323973
@ -1,11 +1,10 @@
|
||||
#include "dumpview.h"
|
||||
|
||||
//public:
|
||||
DumpView::DumpView(QWidget *parent)
|
||||
{
|
||||
int w, h;
|
||||
|
||||
data.resize(73);
|
||||
|
||||
// NOTE: Monospaced fonts only !!!!!!!!!!!
|
||||
setFont(QFont("Courier"));
|
||||
w = fontMetrics().width('X');
|
||||
@ -17,6 +16,7 @@ DumpView::DumpView(QWidget *parent)
|
||||
mSelectedRow = mSelectedCol = -1;
|
||||
|
||||
// calculate width for offset column and the whitespace that follows it
|
||||
// 0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........
|
||||
mOffsetPaneTopRect = QRect(0, 0, w*4, h);
|
||||
mDumpPaneTopRect = QRect(mOffsetPaneTopRect.right()+w*3, 0,
|
||||
w*((8*3-1)+2+(8*3-1)), h);
|
||||
@ -25,15 +25,10 @@ DumpView::DumpView(QWidget *parent)
|
||||
qDebug("DumpView::DumpView");
|
||||
}
|
||||
|
||||
QModelIndex DumpView::indexAt( const QPoint &point ) const
|
||||
{
|
||||
#if 0
|
||||
QSize DumpView::sizeHint() const
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
void DumpView::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
int x = event->x();
|
||||
int x = point.x();
|
||||
int row, col;
|
||||
|
||||
if (x > mAsciiPaneTopRect.left())
|
||||
@ -48,12 +43,12 @@ void DumpView::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
col = (x - mDumpPaneTopRect.left()) / (mCharWidth*3);
|
||||
}
|
||||
row = event->y()/mLineHeight;
|
||||
row = point.y()/mLineHeight;
|
||||
|
||||
if ((col < 16) && (row < ((data.size()+16)/16)))
|
||||
{
|
||||
mSelectedRow = row;
|
||||
mSelectedCol = col;
|
||||
selrow = row;
|
||||
selcol = col;
|
||||
}
|
||||
else
|
||||
goto _exit;
|
||||
@ -62,26 +57,163 @@ void DumpView::mousePressEvent(QMouseEvent *event)
|
||||
if ((row == (((data.size()+16)/16) - 1)) && (col >= (data.size() % 16)))
|
||||
goto _exit;
|
||||
|
||||
qDebug("dumpview::selection(%d, %d)", mSelectedRow, mSelectedCol);
|
||||
update();
|
||||
return;
|
||||
qDebug("dumpview::selection(%d, %d)", selrow, selcol);
|
||||
|
||||
offset = selrow * 16 + selcol;
|
||||
#if 0
|
||||
for(int i = 0; i < model()->rowCount(parent); i++)
|
||||
{
|
||||
QModelIndex index = model()->index(i, 0, parent);
|
||||
|
||||
if (model()->hasChildren(index))
|
||||
indexAtOffset(offset, index); // Non Leaf
|
||||
else
|
||||
if (
|
||||
dump.append(model()->data(index, Qt::UserRole).toByteArray()); // Leaf
|
||||
// FIXME: Use RawValueRole instead of UserRole
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
_exit:
|
||||
// Clear existing selection
|
||||
mSelectedRow = -1;
|
||||
selrow = -1;
|
||||
#endif
|
||||
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
void DumpView::scrollTo( const QModelIndex &index, ScrollHint hint )
|
||||
{
|
||||
// FIXME: implement scrolling
|
||||
}
|
||||
|
||||
QRect DumpView::visualRect( const QModelIndex &index ) const
|
||||
{
|
||||
// FIXME: calculate actual rect
|
||||
return rect();
|
||||
}
|
||||
|
||||
//protected:
|
||||
int DumpView::horizontalOffset() const
|
||||
{
|
||||
return horizontalScrollBar()->value();
|
||||
}
|
||||
|
||||
bool DumpView::isIndexHidden( const QModelIndex &index ) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QModelIndex DumpView::moveCursor( CursorAction cursorAction,
|
||||
Qt::KeyboardModifiers modifiers )
|
||||
{
|
||||
// FIXME(MED): need to implement movement using cursor
|
||||
return currentIndex();
|
||||
}
|
||||
|
||||
void DumpView::setSelection( const QRect &rect,
|
||||
QItemSelectionModel::SelectionFlags flags )
|
||||
{
|
||||
// FIXME(HI): calculate indexes using rect
|
||||
selectionModel()->select(QModelIndex(), flags);
|
||||
}
|
||||
|
||||
int DumpView::verticalOffset() const
|
||||
{
|
||||
return verticalScrollBar()->value();
|
||||
}
|
||||
|
||||
QRegion DumpView::visualRegionForSelection( const QItemSelection &selection ) const
|
||||
{
|
||||
// FIXME(HI)
|
||||
return QRegion(rect());
|
||||
}
|
||||
|
||||
//protected slots:
|
||||
void DumpView::dataChanged( const QModelIndex &topLeft,
|
||||
const QModelIndex &bottomRight )
|
||||
{
|
||||
// FIXME(HI)
|
||||
update();
|
||||
}
|
||||
|
||||
void DumpView::selectionChanged( const QItemSelection &selected,
|
||||
const QItemSelection &deselected )
|
||||
{
|
||||
// FIXME(HI)
|
||||
update();
|
||||
}
|
||||
|
||||
void DumpView::populateDump(QByteArray &dump, int &selOfs, int &selSize,
|
||||
QModelIndex parent)
|
||||
{
|
||||
// TODO(LOW): Assumption - only single selection - enforce/ensure this
|
||||
|
||||
for(int i = 0; i < model()->rowCount(parent); i++)
|
||||
{
|
||||
QModelIndex index = model()->index(i, 0, parent);
|
||||
|
||||
if (model()->hasChildren(index))
|
||||
{
|
||||
// Non Leaf
|
||||
|
||||
// A non-leaf has no dump data of its own but is rather a
|
||||
// container for its children. So we calculate ofs/size based
|
||||
// on this fact
|
||||
if (selectionModel()->isSelected(index))
|
||||
{
|
||||
selOfs = dump.size();
|
||||
populateDump(dump, selOfs, selSize, index);
|
||||
selSize = dump.size() - selOfs;
|
||||
}
|
||||
else
|
||||
{
|
||||
populateDump(dump, selOfs, selSize, index);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Leaf
|
||||
if (selectionModel()->isSelected(index))
|
||||
{
|
||||
int size, j;
|
||||
|
||||
selOfs = dump.size();
|
||||
size = model()->data(index, Qt::UserRole).toByteArray().size();
|
||||
|
||||
// Take care of multiple indexes (2 or more) mapping onto
|
||||
// same dump byte(s)
|
||||
j = i-1;
|
||||
while ((size == 0) && (j >= 0))
|
||||
{
|
||||
size = model()->data(index.sibling(j,0), Qt::UserRole).
|
||||
toByteArray().size();
|
||||
selOfs -= size;
|
||||
j++;
|
||||
}
|
||||
selSize = size;
|
||||
}
|
||||
dump.append(model()->data(index, Qt::UserRole).toByteArray());
|
||||
}
|
||||
// FIXME: Use RawValueRole instead of UserRole
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(LOW): rewrite this function - it's a mess!
|
||||
void DumpView::paintEvent(QPaintEvent* event)
|
||||
{
|
||||
QStylePainter painter(this);
|
||||
QStylePainter painter(viewport());
|
||||
QRect offsetRect = mOffsetPaneTopRect;
|
||||
QRect dumpRect = mDumpPaneTopRect;
|
||||
QRect asciiRect = mAsciiPaneTopRect;
|
||||
QPalette pal = palette();
|
||||
QByteArray ba;
|
||||
QByteArray data;
|
||||
//QByteArray ba;
|
||||
int selOfs = -1, selSize;
|
||||
int curSelOfs, curSelSize;
|
||||
|
||||
//qDebug("dumpview::paintEvent");
|
||||
qDebug("dumpview::paintEvent");
|
||||
|
||||
// FIXME(LOW): unable to set the self widget's font in constructor
|
||||
painter.setFont(QFont("Courier"));
|
||||
@ -89,12 +221,15 @@ void DumpView::paintEvent(QPaintEvent* event)
|
||||
// set a white background
|
||||
painter.fillRect(rect(), QBrush(QColor(Qt::white)));
|
||||
|
||||
if (model())
|
||||
populateDump(data, selOfs, selSize);
|
||||
|
||||
// display the offset, dump and ascii panes 8 + 8 bytes on a line
|
||||
for (int i = 0; i < data.size(); i+=16)
|
||||
{
|
||||
{
|
||||
QString dumpStr, asciiStr;
|
||||
|
||||
ba = data.mid(i, 16);
|
||||
//ba = data.mid(i, 16);
|
||||
|
||||
// display offset
|
||||
painter.drawItemText(offsetRect, Qt::AlignLeft | Qt::AlignTop, pal,
|
||||
@ -128,48 +263,102 @@ void DumpView::paintEvent(QPaintEvent* event)
|
||||
painter.drawItemText(asciiRect, Qt::AlignLeft | Qt::AlignTop, pal,
|
||||
true, asciiStr, QPalette::WindowText);
|
||||
|
||||
// overpaint selection (if any)
|
||||
if ((i/16) == mSelectedRow)
|
||||
// if no selection, skip selection painting
|
||||
if (selOfs < 0)
|
||||
goto _next;
|
||||
|
||||
// Check overlap between current row and selection
|
||||
{
|
||||
QRect r1(i, 0, qMin(16, data.size()-i), 8);
|
||||
QRect s1(selOfs, 0, selSize, 8);
|
||||
if (r1.intersects(s1))
|
||||
{
|
||||
QRect t = r1.intersected(s1);
|
||||
|
||||
curSelOfs = t.x();
|
||||
curSelSize = t.width();
|
||||
}
|
||||
else
|
||||
curSelSize = 0;
|
||||
|
||||
}
|
||||
|
||||
// overpaint selection on current row (if any)
|
||||
if (curSelSize > 0)
|
||||
{
|
||||
QRect r;
|
||||
unsigned char c = data.at(mSelectedRow*16+mSelectedCol);
|
||||
QString selectedAsciiStr, selectedDumpStr;
|
||||
|
||||
qDebug("dumpview::paintEvent - Highlighted");
|
||||
|
||||
selectedDumpStr.append(QString("%1").arg((uint) c, 2, 16, QChar('0')).toUpper());
|
||||
// construct the dumpStr and asciiStr
|
||||
for (int k = curSelOfs; (k < (curSelOfs + curSelSize)); k++)
|
||||
{
|
||||
unsigned char c = data.at(k);
|
||||
|
||||
if (isPrintable(c))
|
||||
selectedAsciiStr.append(QChar(c));
|
||||
else
|
||||
selectedAsciiStr.append(QChar('.'));
|
||||
// extra space after 8 bytes
|
||||
if (((k+8) % 16) == 0)
|
||||
{
|
||||
// Avoid adding space at the start for fields starting
|
||||
// at second column 8 byte boundary
|
||||
if (k!=curSelOfs)
|
||||
{
|
||||
selectedDumpStr.append(" ");
|
||||
selectedAsciiStr.append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
selectedDumpStr.append(QString("%1").arg((uint)c, 2, 16,
|
||||
QChar('0')).toUpper()).append(" ");
|
||||
|
||||
if (isPrintable(c))
|
||||
selectedAsciiStr.append(QChar(c));
|
||||
else
|
||||
selectedAsciiStr.append(QChar('.'));
|
||||
}
|
||||
|
||||
// display dump
|
||||
r = dumpRect;
|
||||
if (mSelectedCol < 8)
|
||||
r.translate(mCharWidth*(mSelectedCol*3), 0);
|
||||
if ((curSelOfs - i) < 8)
|
||||
r.translate(mCharWidth*(curSelOfs-i)*3, 0);
|
||||
else
|
||||
r.translate(mCharWidth*(mSelectedCol*3+1), 0);
|
||||
r.setWidth(mCharWidth*2);
|
||||
r.translate(mCharWidth*((curSelOfs-i)*3+1), 0);
|
||||
|
||||
// adjust width taking care of selection stretching between
|
||||
// the two 8byte columns
|
||||
if (( (curSelOfs-i) < 8 ) && ( (curSelOfs-i+curSelSize) > 8 ))
|
||||
r.setWidth((curSelSize * 3 + 1) * mCharWidth);
|
||||
else
|
||||
r.setWidth((curSelSize * 3) * mCharWidth);
|
||||
|
||||
painter.fillRect(r, pal.highlight());
|
||||
painter.drawItemText(r, Qt::AlignLeft | Qt::AlignTop, pal,
|
||||
true, selectedDumpStr, QPalette::HighlightedText);
|
||||
|
||||
// display ascii
|
||||
r = asciiRect;
|
||||
if (mSelectedCol < 8)
|
||||
r.translate(mCharWidth*(mSelectedCol), 0);
|
||||
if ((curSelOfs - i) < 8)
|
||||
r.translate(mCharWidth*(curSelOfs-i)*1, 0);
|
||||
else
|
||||
r.translate(mCharWidth*(mSelectedCol+1), 0);
|
||||
r.setWidth(mCharWidth);
|
||||
r.translate(mCharWidth*((curSelOfs-i)*1+1), 0);
|
||||
|
||||
// adjust width taking care of selection stretching between
|
||||
// the two 8byte columns
|
||||
if (( (curSelOfs-i) < 8 ) && ( (curSelOfs-i+curSelSize) > 8 ))
|
||||
r.setWidth((curSelSize * 1 + 1) * mCharWidth);
|
||||
else
|
||||
r.setWidth((curSelSize * 1) * mCharWidth);
|
||||
|
||||
painter.fillRect(r, pal.highlight());
|
||||
painter.drawItemText(r, Qt::AlignLeft | Qt::AlignTop, pal,
|
||||
true, selectedAsciiStr, QPalette::HighlightedText);
|
||||
}
|
||||
|
||||
_next:
|
||||
// move the rects down
|
||||
offsetRect.translate(0, mLineHeight);
|
||||
dumpRect.translate(0, mLineHeight);
|
||||
asciiRect.translate(0, mLineHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,25 +1,33 @@
|
||||
#include <QtGui> // FIXME: High
|
||||
|
||||
class DumpView: public QWidget // QAbstractItemView // FIXME
|
||||
|
||||
class DumpView: public QAbstractItemView
|
||||
{
|
||||
public:
|
||||
public:
|
||||
DumpView(QWidget *parent=0);
|
||||
// bool setBase(uint base); // valid values: 16, 8, 10, 2 etc.
|
||||
// void hideAsciiPane(void);
|
||||
// void showAsciiPane(void);
|
||||
// void hideOffsetPane(void);
|
||||
// void showOffsetPane(void);
|
||||
|
||||
|
||||
//QSize sizeHint() const;
|
||||
QModelIndex indexAt( const QPoint &point ) const;
|
||||
void scrollTo( const QModelIndex &index, ScrollHint hint = EnsureVisible );
|
||||
QRect visualRect( const QModelIndex &index ) const;
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
//void mouseMoveEvent(QMouseEvent *event);
|
||||
int horizontalOffset() const;
|
||||
bool isIndexHidden( const QModelIndex &index ) const;
|
||||
QModelIndex moveCursor( CursorAction cursorAction,
|
||||
Qt::KeyboardModifiers modifiers );
|
||||
void setSelection( const QRect &rect, QItemSelectionModel::SelectionFlags flags );
|
||||
int verticalOffset() const;
|
||||
QRegion visualRegionForSelection( const QItemSelection &selection ) const;
|
||||
protected slots:
|
||||
void dataChanged( const QModelIndex &topLeft,
|
||||
const QModelIndex &bottomRight );
|
||||
void selectionChanged( const QItemSelection &selected,
|
||||
const QItemSelection &deselected );
|
||||
void paintEvent(QPaintEvent *event);
|
||||
|
||||
private:
|
||||
QString toAscii(QByteArray ba);
|
||||
void DumpView::populateDump(QByteArray &dump, int &selOfs, int &selSize,
|
||||
QModelIndex parent = QModelIndex());
|
||||
bool inline isPrintable(char c)
|
||||
{if ((c > 48) && (c < 126)) return true; else return false; }
|
||||
|
||||
@ -27,8 +35,8 @@ private:
|
||||
QRect mOffsetPaneTopRect;
|
||||
QRect mDumpPaneTopRect;
|
||||
QRect mAsciiPaneTopRect;
|
||||
QByteArray data;
|
||||
int mSelectedRow, mSelectedCol;
|
||||
int mLineHeight;
|
||||
int mCharWidth;
|
||||
};
|
||||
|
||||
|
@ -4,22 +4,6 @@
|
||||
PacketModel::PacketModel(Stream *pStream, QObject *parent)
|
||||
{
|
||||
mpStream = pStream;
|
||||
#ifdef NEW_IMPL
|
||||
// Nothing else
|
||||
#else
|
||||
populatePacketProtocols();
|
||||
|
||||
registerFrameTypeProto();
|
||||
registerVlanProto();
|
||||
registerIpProto();
|
||||
registerArpProto();
|
||||
registerTcpProto();
|
||||
registerUdpProto();
|
||||
registerIcmpProto();
|
||||
registerIgmpProto();
|
||||
registerData();
|
||||
registerInvalidProto();
|
||||
#endif
|
||||
}
|
||||
|
||||
int PacketModel::rowCount(const QModelIndex &parent) const
|
||||
@ -29,22 +13,14 @@ int PacketModel::rowCount(const QModelIndex &parent) const
|
||||
// Parent == Invalid i.e. Invisible Root.
|
||||
// ==> Children are Protocol (Top Level) Items
|
||||
if (!parent.isValid())
|
||||
#ifdef NEW_IMPL
|
||||
return mpStream->numProtocols();
|
||||
#else
|
||||
return protoCount();
|
||||
#endif
|
||||
|
||||
// Parent - Valid Item
|
||||
parentId.w = parent.internalId();
|
||||
switch(parentId.ws.type)
|
||||
{
|
||||
case ITYP_PROTOCOL:
|
||||
#ifdef NEW_IMPL
|
||||
return mpStream->protocol(parentId.ws.protocol)->numFields();
|
||||
#else
|
||||
return fieldCount(parentId.ws.protocol);
|
||||
#endif
|
||||
case ITYP_FIELD:
|
||||
return 0;
|
||||
default:
|
||||
@ -137,40 +113,44 @@ _exit:
|
||||
QVariant PacketModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
IndexId id;
|
||||
#ifdef NEW_IMPL
|
||||
// Nothing
|
||||
#else
|
||||
ProtocolInfo proto;
|
||||
#endif
|
||||
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
id.w = index.internalId();
|
||||
|
||||
// FIXME(HI): Relook at this completely
|
||||
if (role == Qt::UserRole)
|
||||
{
|
||||
switch(id.ws.type)
|
||||
{
|
||||
case ITYP_PROTOCOL:
|
||||
return QByteArray();
|
||||
|
||||
case ITYP_FIELD:
|
||||
return mpStream->protocol(id.ws.protocol)->fieldRawValue(
|
||||
index.row());
|
||||
|
||||
default:
|
||||
qWarning("%s: Unhandled ItemType", __FUNCTION__);
|
||||
}
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
id.w = index.internalId();
|
||||
switch(id.ws.type)
|
||||
{
|
||||
case ITYP_PROTOCOL:
|
||||
#ifdef NEW_IMPL
|
||||
return QString("%1 (%2)")
|
||||
.arg(mpStream->protocol(id.ws.protocol)->protocolShortName())
|
||||
.arg(mpStream->protocol(id.ws.protocol)->protocolName());
|
||||
#else
|
||||
return protoName(id.ws.protocol);
|
||||
#endif
|
||||
|
||||
case ITYP_FIELD:
|
||||
#ifdef NEW_IMPL
|
||||
return mpStream->protocol(id.ws.protocol)->fieldName(index.row()) +
|
||||
QString(" : ") +
|
||||
mpStream->protocol(id.ws.protocol)->fieldTextValue(index.row());
|
||||
#else
|
||||
return fieldName(id.ws.protocol, index.row()) +
|
||||
QString(" : ") +
|
||||
fieldTextValue(id.ws.protocol, index.row()).toString();
|
||||
#endif
|
||||
|
||||
default:
|
||||
qWarning("%s: Unhandled ItemType", __FUNCTION__);
|
||||
@ -180,759 +160,3 @@ QVariant PacketModel::data(const QModelIndex &index, int role) const
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
#ifdef NEW_IMPL
|
||||
// required methods all part of the Stream class
|
||||
#else
|
||||
/*
|
||||
** --------------- Private Stuff -----------------
|
||||
** FIXME(MED): Move these to the Stream Class
|
||||
**
|
||||
*/
|
||||
|
||||
/*!
|
||||
Looking at the stream's protocols and populate an ordered list of
|
||||
protocols accordingly. The order of protocols will be in the order of
|
||||
protocol headers viz.
|
||||
|
||||
- None/Eth2/802.3 (Mac Addr)
|
||||
- LLC
|
||||
- SNAP
|
||||
- SVLAN
|
||||
- CVLAN
|
||||
- L3 (IP/ARP)
|
||||
- L4 (TCP/UDP/ICMP/IGMP)
|
||||
|
||||
*/
|
||||
void PacketModel::populatePacketProtocols()
|
||||
{
|
||||
int proto;
|
||||
|
||||
// Clear the protocols list
|
||||
mPacketProtocols.clear();
|
||||
|
||||
// Check and populate L2 Protocol
|
||||
switch(mpStream->frameType())
|
||||
{
|
||||
case Stream::e_ft_none:
|
||||
proto = PTYP_L2_NONE;
|
||||
break;
|
||||
|
||||
case Stream::e_ft_eth_2:
|
||||
proto = PTYP_L2_ETH_2;
|
||||
break;
|
||||
|
||||
case Stream::e_ft_802_3_raw:
|
||||
proto = PTYP_L2_802_3_RAW;
|
||||
break;
|
||||
|
||||
case Stream::e_ft_802_3_llc:
|
||||
mPacketProtocols.append(PTYP_L2_NONE);
|
||||
proto = PTYP_L2_802_3_LLC;
|
||||
break;
|
||||
|
||||
case Stream::e_ft_snap:
|
||||
mPacketProtocols.append(PTYP_L2_NONE);
|
||||
mPacketProtocols.append(PTYP_L2_802_3_LLC);
|
||||
proto = PTYP_L2_SNAP;
|
||||
break;
|
||||
|
||||
default:
|
||||
qDebug("%s: Unsupported frametype %d", __FUNCTION__,
|
||||
mpStream->frameType());
|
||||
proto = PTYP_INVALID;
|
||||
}
|
||||
mPacketProtocols.append(proto);
|
||||
|
||||
// Check and populate VLANs, if present
|
||||
if (mpStream->vlan()->vlanFlags().testFlag(VlanProtocol::VlanSvlanTagged))
|
||||
mPacketProtocols.append(PTYP_SVLAN);
|
||||
|
||||
if (mpStream->vlan()->vlanFlags().testFlag(VlanProtocol::VlanCvlanTagged))
|
||||
mPacketProtocols.append(PTYP_CVLAN);
|
||||
|
||||
// Check and populate L3 protocols
|
||||
switch (mpStream->l3Proto())
|
||||
{
|
||||
case Stream::e_l3_none :
|
||||
goto _data;
|
||||
break;
|
||||
|
||||
case Stream::e_l3_ip :
|
||||
proto = PTYP_L3_IP;
|
||||
break;
|
||||
|
||||
case Stream::e_l3_arp:
|
||||
proto = PTYP_L3_ARP;
|
||||
break;
|
||||
|
||||
default:
|
||||
qDebug("%s: Unsupported L3 Proto %d", __FUNCTION__,
|
||||
mpStream->l3Proto());
|
||||
proto = PTYP_INVALID;
|
||||
}
|
||||
mPacketProtocols.append(proto);
|
||||
|
||||
// Check and populate L4 protocol
|
||||
switch(mpStream->l4Proto())
|
||||
{
|
||||
case Stream::e_l4_none:
|
||||
goto _data;
|
||||
break;
|
||||
case Stream::e_l4_tcp:
|
||||
proto = PTYP_L4_TCP;
|
||||
break;
|
||||
case Stream::e_l4_udp:
|
||||
proto = PTYP_L4_UDP;
|
||||
break;
|
||||
case Stream::e_l4_icmp:
|
||||
proto = PTYP_L4_ICMP;
|
||||
break;
|
||||
case Stream::e_l4_igmp:
|
||||
proto = PTYP_L4_IGMP;
|
||||
break;
|
||||
default:
|
||||
qDebug("%s: Unsupported L4 Proto %d", __FUNCTION__,
|
||||
mpStream->l4Proto());
|
||||
proto = PTYP_INVALID;
|
||||
};
|
||||
mPacketProtocols.append(proto);
|
||||
|
||||
_data:
|
||||
mPacketProtocols.append(PTYP_DATA);
|
||||
}
|
||||
/*!
|
||||
Returns the count of protocols in the current stream
|
||||
*/
|
||||
int PacketModel::protoCount() const
|
||||
{
|
||||
return mPacketProtocols.count();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the count of fields in the given protocol
|
||||
*/
|
||||
int PacketModel::fieldCount(int protocol) const
|
||||
{
|
||||
ProtocolInfo proto;
|
||||
|
||||
if (protocol >= mPacketProtocols.count())
|
||||
return 0;
|
||||
|
||||
foreach(proto, mProtocols)
|
||||
{
|
||||
if (proto.handle == mPacketProtocols.at(protocol))
|
||||
{
|
||||
qDebug("proto=%d, name=%s",protocol,proto.name.toAscii().data());
|
||||
qDebug("fieldcount = %d", proto.fieldList.size());
|
||||
return proto.fieldList.count();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString PacketModel::protoName(int protocol) const
|
||||
{
|
||||
ProtocolInfo proto;
|
||||
|
||||
if (protocol >= mPacketProtocols.count())
|
||||
return 0;
|
||||
|
||||
foreach(proto, mProtocols)
|
||||
{
|
||||
if (proto.handle == mPacketProtocols.at(protocol))
|
||||
{
|
||||
qDebug("proto=%d, name=%s",protocol,proto.name.toAscii().data());
|
||||
qDebug("fieldcount = %d", proto.fieldList.size());
|
||||
return proto.name;
|
||||
}
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString PacketModel::fieldName(int protocol, int field) const
|
||||
{
|
||||
ProtocolInfo proto;
|
||||
|
||||
if (protocol >= mPacketProtocols.count())
|
||||
return 0;
|
||||
|
||||
foreach(proto, mProtocols)
|
||||
{
|
||||
if (proto.handle == mPacketProtocols.at(protocol))
|
||||
{
|
||||
qDebug("proto=%d, name=%s",protocol,proto.name.toAscii().data());
|
||||
qDebug("fieldcount = %d", proto.fieldList.size());
|
||||
if (field >= proto.fieldList.count())
|
||||
return QString();
|
||||
|
||||
return proto.fieldList.at(field).name;
|
||||
}
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
QVariant PacketModel::fieldTextValue(int protocol, int field) const
|
||||
{
|
||||
if (protocol >= mPacketProtocols.count())
|
||||
return QVariant();
|
||||
|
||||
switch(mPacketProtocols.at(protocol))
|
||||
{
|
||||
case PTYP_L2_NONE:
|
||||
case PTYP_L2_ETH_2:
|
||||
return ethField(field, FROL_TEXT_VALUE);
|
||||
case PTYP_L2_802_3_RAW:
|
||||
//return dot3Field(field, FROL_TEXT_VALUE); // FIXME(HIGH)
|
||||
return ethField(field, FROL_TEXT_VALUE);
|
||||
case PTYP_L2_802_3_LLC:
|
||||
return llcField(field, FROL_TEXT_VALUE);
|
||||
case PTYP_L2_SNAP:
|
||||
return snapField(field, FROL_TEXT_VALUE);
|
||||
|
||||
case PTYP_SVLAN:
|
||||
return svlanField(field, FROL_TEXT_VALUE);
|
||||
case PTYP_CVLAN:
|
||||
// return cvlanField(field, FROL_TEXT_VALUE); // FIXME(HIGH)
|
||||
return svlanField(field, FROL_TEXT_VALUE);
|
||||
|
||||
case PTYP_L3_IP:
|
||||
return ipField(field, FROL_TEXT_VALUE);
|
||||
case PTYP_L3_ARP:
|
||||
return QString(); // FIXME(HIGH)
|
||||
|
||||
case PTYP_L4_TCP:
|
||||
return tcpField(field, FROL_TEXT_VALUE);
|
||||
case PTYP_L4_UDP:
|
||||
return udpField(field, FROL_TEXT_VALUE);
|
||||
case PTYP_L4_ICMP:
|
||||
return QString(); // FIXME(HIGH)
|
||||
case PTYP_L4_IGMP:
|
||||
return QString(); // FIXME(HIGH)
|
||||
|
||||
case PTYP_INVALID:
|
||||
return QString(); // FIXME(HIGH)
|
||||
case PTYP_DATA:
|
||||
return QString(); // FIXME(HIGH)
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
QVariant PacketModel::ethField(int field, int role) const
|
||||
{
|
||||
FieldInfo info;
|
||||
|
||||
// FIXME(MED): Mac Addr formatting
|
||||
switch(field)
|
||||
{
|
||||
case 0:
|
||||
info.name = QString("Destination Mac Address");
|
||||
info.textValue = QString("%1").
|
||||
arg(mpStream->mac()->dstMac(), 12, BASE_HEX, QChar('0'));
|
||||
break;
|
||||
case 1:
|
||||
info.name = QString("Source Mac Address");
|
||||
info.textValue = QString("%1").
|
||||
arg(mpStream->mac()->srcMac(), 12, BASE_HEX, QChar('0'));
|
||||
break;
|
||||
case 2:
|
||||
info.name = QString("Type");
|
||||
info.textValue = QString("0x%1").
|
||||
arg(mpStream->eth2()->type(), 4, BASE_HEX, QChar('0'));
|
||||
break;
|
||||
default:
|
||||
info.name = QString();
|
||||
info.textValue = QString();
|
||||
}
|
||||
|
||||
switch(role)
|
||||
{
|
||||
case FROL_NAME:
|
||||
return info.name;
|
||||
case FROL_TEXT_VALUE:
|
||||
return info.textValue;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
Q_ASSERT(1 == 1); // Unreachable code
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant PacketModel::llcField(int field, int role) const
|
||||
{
|
||||
FieldInfo info;
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case 0:
|
||||
info.name = QString("DSAP");
|
||||
info.textValue = QString("0x%1").
|
||||
arg(mpStream->llc()->dsap(), 2, BASE_HEX, QChar('0'));
|
||||
break;
|
||||
case 1:
|
||||
info.name = QString("SSAP");
|
||||
info.textValue = QString("0x%1").
|
||||
arg(mpStream->llc()->ssap(), 2, BASE_HEX, QChar('0'));
|
||||
break;
|
||||
case 2:
|
||||
info.name = QString("Control");
|
||||
info.textValue = QString("0x%1").
|
||||
arg(mpStream->llc()->ctl(), 2, BASE_HEX, QChar('0'));
|
||||
break;
|
||||
default:
|
||||
info.name = QString();
|
||||
info.textValue = QString();
|
||||
}
|
||||
|
||||
switch(role)
|
||||
{
|
||||
case FROL_NAME:
|
||||
return info.name;
|
||||
case FROL_TEXT_VALUE:
|
||||
return info.textValue;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
Q_ASSERT(1 == 1); // Unreachable code
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant PacketModel::snapField(int field, int role) const
|
||||
{
|
||||
FieldInfo info;
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case 0:
|
||||
info.name = QString("OUI");
|
||||
info.textValue = QString("0x%1").
|
||||
arg(mpStream->snap()->oui(), 6, BASE_HEX, QChar('0'));
|
||||
break;
|
||||
case 1:
|
||||
info.name = QString("Type");
|
||||
info.textValue = QString("0x%1").
|
||||
arg(mpStream->eth2()->type(), 4, BASE_HEX, QChar('0'));
|
||||
break;
|
||||
default:
|
||||
info.name = QString();
|
||||
info.textValue = QString();
|
||||
}
|
||||
|
||||
switch(role)
|
||||
{
|
||||
case FROL_NAME:
|
||||
return info.name;
|
||||
case FROL_TEXT_VALUE:
|
||||
return info.textValue;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
Q_ASSERT(1 == 1); // Unreachable code
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant PacketModel::svlanField(int field, int role) const
|
||||
{
|
||||
FieldInfo info;
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case 0:
|
||||
info.name = QString("TPID");
|
||||
info.textValue = QString("0x%1").
|
||||
arg(mpStream->vlan()->stpid(), 4, BASE_HEX, QChar('0'));
|
||||
break;
|
||||
case 1:
|
||||
info.name = QString("PCP");
|
||||
info.textValue = QString("%1").
|
||||
arg(mpStream->vlan()->svlanPrio());
|
||||
break;
|
||||
case 2:
|
||||
info.name = QString("DE");
|
||||
info.textValue = QString("%1").
|
||||
arg(mpStream->vlan()->svlanCfi());
|
||||
break;
|
||||
case 3:
|
||||
info.name = QString("VlanId");
|
||||
info.textValue = QString("%1").
|
||||
arg(mpStream->vlan()->svlanId());
|
||||
break;
|
||||
default:
|
||||
info.name = QString();
|
||||
info.textValue = QString();
|
||||
}
|
||||
|
||||
switch(role)
|
||||
{
|
||||
case FROL_NAME:
|
||||
return info.name;
|
||||
case FROL_TEXT_VALUE:
|
||||
return info.textValue;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
Q_ASSERT(1 == 1); // Unreachable code
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
||||
QVariant PacketModel::ipField(int field, int role) const
|
||||
{
|
||||
FieldInfo info;
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case 0:
|
||||
info.name = QString("Version");
|
||||
info.textValue = QString("%1").
|
||||
arg(mpStream->ip()->ver());
|
||||
break;
|
||||
case 1:
|
||||
info.name = QString("Header Length");
|
||||
info.textValue = QString("%1").
|
||||
arg(mpStream->ip()->hdrLen());
|
||||
break;
|
||||
case 2:
|
||||
info.name = QString("TOS/DSCP");
|
||||
info.textValue = QString("0x%1").
|
||||
arg(mpStream->ip()->tos(), 2, BASE_HEX, QChar('0'));
|
||||
break;
|
||||
case 3:
|
||||
info.name = QString("Total Length");
|
||||
info.textValue = QString("%1").
|
||||
arg(mpStream->ip()->totLen());
|
||||
break;
|
||||
case 4:
|
||||
info.name = QString("ID");
|
||||
info.textValue = QString("0x%1").
|
||||
arg(mpStream->ip()->id(), 2, BASE_HEX, QChar('0'));
|
||||
break;
|
||||
case 5:
|
||||
info.name = QString("Flags");
|
||||
info.textValue = QString("0x%1").
|
||||
arg(mpStream->ip()->flags(), 2, BASE_HEX, QChar('0')); // FIXME(HIGH)
|
||||
break;
|
||||
case 6:
|
||||
info.name = QString("Fragment Offset");
|
||||
info.textValue = QString("%1").
|
||||
arg(mpStream->ip()->fragOfs());
|
||||
break;
|
||||
case 7:
|
||||
info.name = QString("TTL");
|
||||
info.textValue = QString("%1").
|
||||
arg(mpStream->ip()->ttl());
|
||||
break;
|
||||
case 8:
|
||||
info.name = QString("Protocol Type");
|
||||
info.textValue = QString("0x%1").
|
||||
arg(mpStream->ip()->proto(), 2, BASE_HEX, QChar('0'));
|
||||
break;
|
||||
case 9:
|
||||
info.name = QString("Checksum");
|
||||
info.textValue = QString("0x%1").
|
||||
arg(mpStream->ip()->cksum(), 4, BASE_HEX, QChar('0'));
|
||||
break;
|
||||
case 10:
|
||||
info.name = QString("Source IP");
|
||||
info.textValue = QHostAddress(mpStream->ip()->srcIp()).toString();
|
||||
break;
|
||||
case 11:
|
||||
info.name = QString("Destination IP");
|
||||
info.textValue = QHostAddress(mpStream->ip()->dstIp()).toString();
|
||||
break;
|
||||
default:
|
||||
info.name = QString();
|
||||
info.textValue = QString();
|
||||
}
|
||||
|
||||
switch(role)
|
||||
{
|
||||
case FROL_NAME:
|
||||
return info.name;
|
||||
case FROL_TEXT_VALUE:
|
||||
return info.textValue;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
Q_ASSERT(1 == 1); // Unreachable code
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
||||
QVariant PacketModel::tcpField(int field, int role) const
|
||||
{
|
||||
FieldInfo info;
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case 0:
|
||||
info.name = QString("Source Port");
|
||||
info.textValue = QString("%1").
|
||||
arg(mpStream->tcp()->srcPort());
|
||||
break;
|
||||
case 1:
|
||||
info.name = QString("Destination Port");
|
||||
info.textValue = QString("%1").
|
||||
arg(mpStream->tcp()->dstPort());
|
||||
break;
|
||||
case 2:
|
||||
info.name = QString("Seq Number");
|
||||
info.textValue = QString("%1").
|
||||
arg(mpStream->tcp()->seqNum());
|
||||
break;
|
||||
case 3:
|
||||
info.name = QString("Ack Number");
|
||||
info.textValue = QString("%1").
|
||||
arg(mpStream->tcp()->ackNum());
|
||||
break;
|
||||
case 4:
|
||||
info.name = QString("Header Length");
|
||||
info.textValue = QString("%1").
|
||||
arg(mpStream->tcp()->hdrLen());
|
||||
break;
|
||||
case 5:
|
||||
info.name = QString("Reserved");
|
||||
info.textValue = QString("%1").
|
||||
arg(mpStream->tcp()->rsvd());
|
||||
break;
|
||||
case 6:
|
||||
info.name = QString("Flags");
|
||||
info.textValue = QString("0x%1").
|
||||
arg(mpStream->tcp()->flags(), 2, BASE_HEX, QChar('0'));
|
||||
break;
|
||||
case 7:
|
||||
info.name = QString("Window");
|
||||
info.textValue = QString("%1").
|
||||
arg(mpStream->tcp()->flags());
|
||||
break;
|
||||
case 8:
|
||||
info.name = QString("Checksum");
|
||||
info.textValue = QString("0x%1").
|
||||
arg(mpStream->tcp()->cksum(), 4, BASE_HEX, QChar('0'));
|
||||
break;
|
||||
case 9:
|
||||
info.name = QString("Urgent Pointer");
|
||||
info.textValue = QString("%1").
|
||||
arg(mpStream->tcp()->urgPtr());
|
||||
break;
|
||||
default:
|
||||
info.name = QString();
|
||||
info.textValue = QString();
|
||||
}
|
||||
|
||||
switch(role)
|
||||
{
|
||||
case FROL_NAME:
|
||||
return info.name;
|
||||
case FROL_TEXT_VALUE:
|
||||
return info.textValue;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
Q_ASSERT(1 == 1); // Unreachable code
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
||||
QVariant PacketModel::udpField(int field, int role) const
|
||||
{
|
||||
FieldInfo info;
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case 0:
|
||||
info.name = QString("Source Port");
|
||||
info.textValue = QString("%1").
|
||||
arg(mpStream->udp()->srcPort());
|
||||
break;
|
||||
case 1:
|
||||
info.name = QString("Destination Port");
|
||||
info.textValue = QString("%1").
|
||||
arg(mpStream->udp()->dstPort());
|
||||
break;
|
||||
case 2:
|
||||
info.name = QString("Total Length");
|
||||
info.textValue = QString("%1").
|
||||
arg(mpStream->udp()->totLen());
|
||||
break;
|
||||
case 3:
|
||||
info.name = QString("Checksum");
|
||||
info.textValue = QString("0x%1").
|
||||
arg(mpStream->udp()->cksum(), 4, BASE_HEX, QChar('0'));
|
||||
break;
|
||||
default:
|
||||
info.name = QString();
|
||||
info.textValue = QString();
|
||||
}
|
||||
|
||||
switch(role)
|
||||
{
|
||||
case FROL_NAME:
|
||||
return info.name;
|
||||
case FROL_TEXT_VALUE:
|
||||
return info.textValue;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
Q_ASSERT(1 == 1); // Unreachable code
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** ------------- Registration Functions ---------------
|
||||
*/
|
||||
|
||||
void PacketModel::registerProto(uint handle, char *name, char *abbr)
|
||||
{
|
||||
ProtocolInfo proto;
|
||||
|
||||
proto.handle = handle;
|
||||
proto.name = QString(name);
|
||||
proto.abbr = QString(abbr);
|
||||
mProtocols.append(proto);
|
||||
}
|
||||
|
||||
void PacketModel::registerField(uint protoHandle, char *name, char *abbr)
|
||||
{
|
||||
for (int i = 0; i < mProtocols.size(); i++)
|
||||
{
|
||||
if (mProtocols.at(i).handle == protoHandle)
|
||||
{
|
||||
FieldInfo field;
|
||||
|
||||
field.name = QString(name);
|
||||
field.abbr = QString(abbr);
|
||||
mProtocols[i].fieldList.append(field);
|
||||
qDebug("proto = %d, name = %s", protoHandle, name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PacketModel::registerFrameTypeProto()
|
||||
{
|
||||
registerProto(PTYP_L2_NONE, "None", "");
|
||||
registerField(PTYP_L2_NONE, "Destination Mac", "dstMac");
|
||||
registerField(PTYP_L2_NONE, "Source Mac", "srcMac");
|
||||
|
||||
registerProto(PTYP_L2_ETH_2, "Ethernet II", "eth");
|
||||
registerField(PTYP_L2_ETH_2, "Destination Mac", "dstMac");
|
||||
registerField(PTYP_L2_ETH_2, "Source Mac", "srcMac");
|
||||
registerField(PTYP_L2_ETH_2, "Ethernet Type", "type");
|
||||
|
||||
registerProto(PTYP_L2_802_3_RAW, "IEEE 802.3 Raw", "dot3raw");
|
||||
registerField(PTYP_L2_802_3_RAW, "Destination Mac", "dstMac");
|
||||
registerField(PTYP_L2_802_3_RAW, "Source Mac", "srcMac");
|
||||
registerField(PTYP_L2_802_3_RAW, "Length", "len");
|
||||
|
||||
registerProto(PTYP_L2_802_3_LLC, "802.3 LLC", "dot3llc");
|
||||
registerField(PTYP_L2_802_3_LLC, "Destination Service Acces Point", "dsap");
|
||||
registerField(PTYP_L2_802_3_LLC, "Source Service Acces Point", "ssap");
|
||||
registerField(PTYP_L2_802_3_LLC, "Control", "ctl");
|
||||
|
||||
registerProto(PTYP_L2_SNAP, "SNAP", "dot3snap");
|
||||
registerField(PTYP_L2_SNAP, "Organisationally Unique Identifier", "oui");
|
||||
registerField(PTYP_L2_SNAP, "Type", "type");
|
||||
|
||||
}
|
||||
|
||||
void PacketModel::registerVlanProto()
|
||||
{
|
||||
registerProto(PTYP_SVLAN, "IEEE 802.1ad Service VLAN", "SVLAN");
|
||||
|
||||
registerField(PTYP_SVLAN, "Tag Protocol Identifier", "tpid");
|
||||
registerField(PTYP_SVLAN, "Priority Code Point", "pcp");
|
||||
registerField(PTYP_SVLAN, "Drop Eligible", "de");
|
||||
registerField(PTYP_SVLAN, "VLAN Identifier", "vlan");
|
||||
|
||||
registerProto(PTYP_CVLAN, "IEEE 802.1Q VLAN/CVLAN", "VLAN");
|
||||
|
||||
registerField(PTYP_CVLAN, "Tag Protocol Identifier", "tpid");
|
||||
registerField(PTYP_CVLAN, "Priority", "prio");
|
||||
registerField(PTYP_CVLAN, "Canonical Format Indicator", "cfi");
|
||||
registerField(PTYP_CVLAN, "VLAN Identifier", "vlan");
|
||||
}
|
||||
|
||||
void PacketModel::registerIpProto()
|
||||
{
|
||||
registerProto(PTYP_L3_IP, "Internet Protocol version 4", "IPv4");
|
||||
|
||||
registerField(PTYP_L3_IP, "Version", "ver");
|
||||
registerField(PTYP_L3_IP, "Header Length", "hdrlen");
|
||||
registerField(PTYP_L3_IP, "Type of Service/DiffServ Code Point", "tos");
|
||||
registerField(PTYP_L3_IP, "Total Length", "len");
|
||||
registerField(PTYP_L3_IP, "Identification", "id");
|
||||
registerField(PTYP_L3_IP, "Flags", "flags");
|
||||
registerField(PTYP_L3_IP, "Fragment Offset", "fragofs");
|
||||
registerField(PTYP_L3_IP, "Time to Live", "ttl");
|
||||
registerField(PTYP_L3_IP, "Protocol Id", "proto");
|
||||
registerField(PTYP_L3_IP, "Checksum", "cksum");
|
||||
registerField(PTYP_L3_IP, "Source IP", "srcip");
|
||||
registerField(PTYP_L3_IP, "Destination IP", "dstip");
|
||||
}
|
||||
|
||||
void PacketModel::registerArpProto()
|
||||
{
|
||||
// TODO (LOW)
|
||||
}
|
||||
|
||||
void PacketModel::registerTcpProto()
|
||||
{
|
||||
registerProto(PTYP_L4_TCP, "Transmission Control Protocol", "TCP");
|
||||
|
||||
registerField(PTYP_L4_TCP, "Source Port", "srcport");
|
||||
registerField(PTYP_L4_TCP, "Destination Port", "dstport");
|
||||
registerField(PTYP_L4_TCP, "Sequence Number", "seqnum");
|
||||
registerField(PTYP_L4_TCP, "Acknowledgement Number", "acknum");
|
||||
registerField(PTYP_L4_TCP, "Header Length", "hdrlen");
|
||||
registerField(PTYP_L4_TCP, "Reserved", "rsvd");
|
||||
registerField(PTYP_L4_TCP, "Flags", "flags");
|
||||
registerField(PTYP_L4_TCP, "Window", "win");
|
||||
registerField(PTYP_L4_TCP, "Checksum", "cksum");
|
||||
registerField(PTYP_L4_TCP, "Urgent Pointer", "urgptr");
|
||||
}
|
||||
|
||||
void PacketModel::registerUdpProto()
|
||||
{
|
||||
registerProto(PTYP_L4_UDP, "User Datagram Protocol", "UDP");
|
||||
|
||||
registerField(PTYP_L4_UDP, "Source Port", "srcport");
|
||||
registerField(PTYP_L4_UDP, "Destination Port", "dstport");
|
||||
registerField(PTYP_L4_UDP, "Length", "len");
|
||||
registerField(PTYP_L4_UDP, "Checksum", "cksum");
|
||||
}
|
||||
|
||||
void PacketModel::registerIcmpProto()
|
||||
{
|
||||
// TODO (LOW)
|
||||
}
|
||||
|
||||
void PacketModel::registerIgmpProto()
|
||||
{
|
||||
// TODO (LOW)
|
||||
}
|
||||
|
||||
void PacketModel::registerInvalidProto()
|
||||
{
|
||||
registerProto(PTYP_INVALID, "Invalid Protocol (bug in code)", "invalid");
|
||||
}
|
||||
|
||||
void PacketModel::registerData()
|
||||
{
|
||||
registerProto(PTYP_DATA, "Data", "data");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <qendian.h>
|
||||
#include <QHostAddress>
|
||||
|
||||
#include "stream.h"
|
||||
@ -6,6 +7,72 @@
|
||||
|
||||
#define BASE_HEX 16
|
||||
|
||||
QString PayloadProtocol::fieldTextValue(int index)
|
||||
{
|
||||
int len;
|
||||
quint32 pat;
|
||||
QString textValue;
|
||||
|
||||
if (parentStream)
|
||||
{
|
||||
len = parentStream->frameLen() - parentStream->protocolHeaderSize();
|
||||
pat = parentStream->pattern();
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 1500; // FIXME(HI): testing only
|
||||
pat = 0x0a0b0c0d;
|
||||
}
|
||||
|
||||
// Make a larger string and then resize to the correct size to
|
||||
// take care of the case where len is not a multiple of pattern size
|
||||
if (len > 0)
|
||||
{
|
||||
// TODO(LOW): allow non-4byte patterns!!!
|
||||
int w = 4; // data pattern size
|
||||
|
||||
for (int i = 0; i < (len/w + 1); i++)
|
||||
textValue.append(QString("%1").arg(
|
||||
pat, w*2, BASE_HEX, QChar('0')));
|
||||
textValue.resize(len);
|
||||
}
|
||||
|
||||
return textValue;
|
||||
}
|
||||
|
||||
QByteArray PayloadProtocol::fieldRawValue(int index)
|
||||
{
|
||||
int len;
|
||||
quint32 pat;
|
||||
QByteArray rawValue;
|
||||
|
||||
if (parentStream)
|
||||
{
|
||||
len = parentStream->frameLen() - parentStream->protocolHeaderSize();
|
||||
pat = parentStream->pattern();
|
||||
}
|
||||
else
|
||||
{
|
||||
len = 1500; // FIXME(HI): testing only
|
||||
pat = 0x0a0b0c0d;
|
||||
}
|
||||
|
||||
// Make a larger byteArray and then resize to the correct size to
|
||||
// take care of the case where len is not a multiple of pattern size
|
||||
if (len > 0)
|
||||
{
|
||||
// TODO(LOW): allow non-4byte patterns!!!
|
||||
int w = 4; // data pattern size
|
||||
|
||||
rawValue.resize(len + 4);
|
||||
for (int i = 0; i < (len/w + 1); i++)
|
||||
qToBigEndian(pat, (uchar*) (rawValue.data() + i*sizeof(pat)));
|
||||
rawValue.resize(len);
|
||||
}
|
||||
|
||||
return rawValue;
|
||||
}
|
||||
|
||||
QString MacProtocol::fieldName(int index)
|
||||
{
|
||||
QString name;
|
||||
@ -53,6 +120,24 @@ QByteArray MacProtocol::fieldRawValue(int index)
|
||||
{
|
||||
QByteArray rawValue;
|
||||
|
||||
switch(index)
|
||||
{
|
||||
case 0:
|
||||
rawValue.resize(8);
|
||||
qToBigEndian(dstMac(), (uchar *) rawValue.data());
|
||||
rawValue.remove(0, 2);
|
||||
qDebug("dstMac(%d): %s", rawValue.size(), rawValue.toHex().constData());
|
||||
break;
|
||||
case 1:
|
||||
rawValue.resize(8);
|
||||
qToBigEndian(srcMac(), (uchar *) rawValue.data());
|
||||
rawValue.remove(0, 2);
|
||||
qDebug("srcMac(%d): %s", rawValue.size(), rawValue.toHex().constData());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return rawValue;
|
||||
}
|
||||
|
||||
@ -109,6 +194,24 @@ QByteArray LlcProtocol::fieldRawValue(int index)
|
||||
{
|
||||
QByteArray rawValue;
|
||||
|
||||
switch(index)
|
||||
{
|
||||
case 0:
|
||||
rawValue.resize(1);
|
||||
rawValue[0] = dsap();
|
||||
break;
|
||||
case 1:
|
||||
rawValue.resize(1);
|
||||
rawValue[0] = ssap();
|
||||
break;
|
||||
case 2:
|
||||
rawValue.resize(1);
|
||||
rawValue[0] = ctl();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return rawValue;
|
||||
}
|
||||
|
||||
@ -151,6 +254,17 @@ QByteArray SnapProtocol::fieldRawValue(int index)
|
||||
{
|
||||
QByteArray rawValue;
|
||||
|
||||
switch(index)
|
||||
{
|
||||
case 0:
|
||||
rawValue.resize(4);
|
||||
qToBigEndian(oui(), (uchar *) rawValue.data());
|
||||
rawValue.remove(0, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return rawValue;
|
||||
}
|
||||
|
||||
@ -191,9 +305,58 @@ QByteArray Eth2Protocol::fieldRawValue(int index)
|
||||
{
|
||||
QByteArray rawValue;
|
||||
|
||||
switch(index)
|
||||
{
|
||||
case 0:
|
||||
rawValue.resize(2);
|
||||
qToBigEndian(type(), (uchar*) rawValue.data());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return rawValue;
|
||||
}
|
||||
|
||||
QString Dot3Protocol::fieldName(int index)
|
||||
{
|
||||
QString name;
|
||||
|
||||
switch(index)
|
||||
{
|
||||
case 0:
|
||||
name = QString("Length");
|
||||
break;
|
||||
default:
|
||||
name = QString();
|
||||
break;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
QString Dot3Protocol::fieldTextValue(int index)
|
||||
{
|
||||
if (parentStream)
|
||||
return QString("%1").arg(parentStream->frameLen());
|
||||
else
|
||||
return QString("00");
|
||||
}
|
||||
|
||||
QByteArray Dot3Protocol::fieldRawValue(int index)
|
||||
{
|
||||
QByteArray ba;
|
||||
|
||||
if (parentStream)
|
||||
qToBigEndian((quint16) parentStream->frameLen(), (uchar*) ba.data());
|
||||
else
|
||||
{
|
||||
ba.resize(2);
|
||||
ba[0] = ba[1] = 0;
|
||||
}
|
||||
|
||||
return ba;
|
||||
}
|
||||
|
||||
int VlanProtocol::numFields()
|
||||
{
|
||||
if (isSingleTagged())
|
||||
@ -323,6 +486,56 @@ QByteArray VlanProtocol::fieldRawValue(int index)
|
||||
{
|
||||
QByteArray rawValue;
|
||||
|
||||
if (isDoubleTagged())
|
||||
{
|
||||
switch(index)
|
||||
{
|
||||
case 0:
|
||||
rawValue.resize(2);
|
||||
qToBigEndian(stpid(), (uchar*) rawValue.data());
|
||||
break;
|
||||
case 1:
|
||||
rawValue.resize(2);
|
||||
qToBigEndian((svlanPrio() << 13) | (svlanCfi() < 12) | svlanId(),
|
||||
(uchar*) rawValue.data());
|
||||
break;
|
||||
case 2:
|
||||
// Combined with prio above
|
||||
break;
|
||||
case 3:
|
||||
// Combined with prio above
|
||||
break;
|
||||
default:
|
||||
index -= 4;
|
||||
goto _single_tag;
|
||||
}
|
||||
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
_single_tag:
|
||||
switch(index)
|
||||
{
|
||||
case 0:
|
||||
rawValue.resize(2);
|
||||
qToBigEndian(ctpid(), (uchar*) rawValue.data());
|
||||
break;
|
||||
case 1:
|
||||
rawValue.resize(2);
|
||||
qToBigEndian((cvlanPrio() << 13) | (cvlanCfi() < 12) | cvlanId(),
|
||||
(uchar*) rawValue.data());
|
||||
break;
|
||||
case 2:
|
||||
// Combined with prio above
|
||||
break;
|
||||
case 3:
|
||||
// Combined with prio above
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_exit:
|
||||
return rawValue;
|
||||
}
|
||||
|
||||
@ -438,6 +651,60 @@ QByteArray IpProtocol::fieldRawValue(int index)
|
||||
{
|
||||
QByteArray rawValue;
|
||||
|
||||
switch(index)
|
||||
{
|
||||
case 0:
|
||||
rawValue.resize(1);
|
||||
//qToBigEndian((ver() << 4) | hdrLen(), (uchar*) rawValue.data());
|
||||
rawValue[0]=(ver() << 4) | hdrLen();
|
||||
break;
|
||||
case 1:
|
||||
// Combined with previous 4 bits of ver!!
|
||||
break;
|
||||
case 2:
|
||||
rawValue.resize(1);
|
||||
qToBigEndian(tos(), (uchar*) rawValue.data());
|
||||
break;
|
||||
case 3:
|
||||
rawValue.resize(2);
|
||||
qToBigEndian(totLen(), (uchar*) rawValue.data());
|
||||
break;
|
||||
case 4:
|
||||
rawValue.resize(2);
|
||||
qToBigEndian(id(), (uchar*) rawValue.data());
|
||||
break;
|
||||
case 5:
|
||||
rawValue.resize(2);
|
||||
qToBigEndian((quint16)((flags() << 13) | fragOfs()),
|
||||
(uchar*) rawValue.data());
|
||||
break;
|
||||
case 6:
|
||||
// Combined with previous 3 bits of flags!!
|
||||
break;
|
||||
case 7:
|
||||
rawValue.resize(1);
|
||||
qToBigEndian(ttl(), (uchar*) rawValue.data());
|
||||
break;
|
||||
case 8:
|
||||
rawValue.resize(1);
|
||||
qToBigEndian(proto(), (uchar*) rawValue.data());
|
||||
break;
|
||||
case 9:
|
||||
rawValue.resize(2);
|
||||
qToBigEndian(cksum(), (uchar*) rawValue.data());
|
||||
break;
|
||||
case 10:
|
||||
rawValue.resize(4);
|
||||
qToBigEndian(srcIp(), (uchar*) rawValue.data());
|
||||
break;
|
||||
case 11:
|
||||
rawValue.resize(4);
|
||||
qToBigEndian(dstIp(), (uchar*) rawValue.data());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return rawValue;
|
||||
}
|
||||
|
||||
@ -520,7 +787,7 @@ QString TcpProtocol::fieldTextValue(int index)
|
||||
break;
|
||||
case 7:
|
||||
textValue = QString("%1").
|
||||
arg(flags());
|
||||
arg(window(), 2, BASE_HEX, QChar('0'));
|
||||
break;
|
||||
case 8:
|
||||
textValue = QString("0x%1").
|
||||
@ -541,6 +808,51 @@ QByteArray TcpProtocol::fieldRawValue(int index)
|
||||
{
|
||||
QByteArray rawValue;
|
||||
|
||||
switch(index)
|
||||
{
|
||||
case 0:
|
||||
rawValue.resize(2);
|
||||
qToBigEndian(srcPort(), (uchar*) rawValue.data());
|
||||
break;
|
||||
case 1:
|
||||
rawValue.resize(2);
|
||||
qToBigEndian(dstPort(), (uchar*) rawValue.data());
|
||||
break;
|
||||
case 2:
|
||||
rawValue.resize(4);
|
||||
qToBigEndian(seqNum(), (uchar*) rawValue.data());
|
||||
break;
|
||||
case 3:
|
||||
rawValue.resize(4);
|
||||
qToBigEndian(ackNum(), (uchar*) rawValue.data());
|
||||
break;
|
||||
case 4:
|
||||
rawValue.resize(1);
|
||||
rawValue[0] = (hdrLen() << 4) | rsvd();
|
||||
break;
|
||||
case 5:
|
||||
// Combined with hdrLen above
|
||||
break;
|
||||
case 6:
|
||||
rawValue.resize(1);
|
||||
rawValue[0] = flags();
|
||||
break;
|
||||
case 7:
|
||||
rawValue.resize(2);
|
||||
qToBigEndian(window(), (uchar*) rawValue.data());
|
||||
break;
|
||||
case 8:
|
||||
rawValue.resize(2);
|
||||
qToBigEndian(cksum(), (uchar*) rawValue.data());
|
||||
break;
|
||||
case 9:
|
||||
rawValue.resize(2);
|
||||
qToBigEndian(urgPtr(), (uchar*) rawValue.data());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return rawValue;
|
||||
}
|
||||
|
||||
@ -602,6 +914,28 @@ QByteArray UdpProtocol::fieldRawValue(int index)
|
||||
{
|
||||
QByteArray rawValue;
|
||||
|
||||
switch(index)
|
||||
{
|
||||
case 0:
|
||||
rawValue.resize(2);
|
||||
qToBigEndian(srcPort(), (uchar*) rawValue.data());
|
||||
break;
|
||||
case 1:
|
||||
rawValue.resize(2);
|
||||
qToBigEndian(dstPort(), (uchar*) rawValue.data());
|
||||
break;
|
||||
case 2:
|
||||
rawValue.resize(2);
|
||||
qToBigEndian(totLen(), (uchar*) rawValue.data());
|
||||
break;
|
||||
case 3:
|
||||
rawValue.resize(2);
|
||||
qToBigEndian(cksum(), (uchar*) rawValue.data());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return rawValue;
|
||||
}
|
||||
|
||||
@ -622,12 +956,14 @@ Stream::Stream()
|
||||
// mCore->set_stream_id(mId);
|
||||
|
||||
mUnknown = new UnknownProtocol;
|
||||
mPayload = new PayloadProtocol(); //FIXME(MED): need to pass parent stream
|
||||
|
||||
mMac = new MacProtocol;
|
||||
|
||||
mLlc = new LlcProtocol;
|
||||
mSnap = new SnapProtocol;
|
||||
mEth2 = new Eth2Protocol;
|
||||
mDot3 = new Dot3Protocol(); // FIXME(MED): need to pass parent stream
|
||||
mVlan = new VlanProtocol;
|
||||
|
||||
mIp = new IpProtocol;
|
||||
@ -776,9 +1112,23 @@ void Stream::updateSelectedProtocols()
|
||||
selectedProtocols.append(proto);
|
||||
|
||||
_data:
|
||||
|
||||
mProtocolHeaderSize = 0;
|
||||
#ifndef SRIVATSP
|
||||
#if 0
|
||||
for (int i = 0; i < selectedProtocols.size(); i++)
|
||||
mProtocolHeaderSize += protocol(i)->protocolRawValue().size();
|
||||
#endif
|
||||
#endif
|
||||
selectedProtocols.append(PTYP_DATA);
|
||||
}
|
||||
|
||||
int Stream::protocolHeaderSize()
|
||||
{
|
||||
updateSelectedProtocols(); // FIXME(HI): shd not happen everytime
|
||||
return mProtocolHeaderSize;
|
||||
}
|
||||
|
||||
int Stream::numProtocols()
|
||||
{
|
||||
updateSelectedProtocols(); // FIXME(HI): shd not happen everytime
|
||||
@ -815,7 +1165,7 @@ AbstractProtocol* Stream::protocol(int index)
|
||||
case PTYP_L2_ETH_2:
|
||||
return eth2();
|
||||
case PTYP_L2_802_3_RAW:
|
||||
return eth2(); // FIXME(HI): define a dot3 protocol?
|
||||
return dot3();
|
||||
|
||||
case PTYP_L2_802_3_LLC:
|
||||
return llc();
|
||||
@ -843,7 +1193,7 @@ AbstractProtocol* Stream::protocol(int index)
|
||||
case PTYP_INVALID:
|
||||
return mUnknown;
|
||||
case PTYP_DATA:
|
||||
return mUnknown; // FIXME(MED) define a "data" protocol?
|
||||
return mPayload;
|
||||
default:
|
||||
return mUnknown;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define _STREAM_H
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
#include "../common/protocol.pb.h"
|
||||
@ -17,6 +18,8 @@ class PacketModel;
|
||||
#define IP_PROTO_UDP 0x11
|
||||
|
||||
|
||||
class Stream;
|
||||
|
||||
class AbstractProtocol
|
||||
{
|
||||
// TODO(LOW)
|
||||
@ -36,6 +39,16 @@ public:
|
||||
{ return QString("AbsProto"); }
|
||||
virtual int numFields()
|
||||
{ return 1; }
|
||||
QByteArray protocolRawValue()
|
||||
{
|
||||
QByteArray ba;
|
||||
#ifndef SRIVATSP
|
||||
#else
|
||||
for (int i=0; i < numFields(); i++)
|
||||
ba.append(fieldRawValue(i));
|
||||
#endif
|
||||
return ba;
|
||||
}
|
||||
virtual QString fieldName(int index)
|
||||
{ return QString("AbstractField"); }
|
||||
virtual QString fieldTextValue(int index)
|
||||
@ -64,7 +77,31 @@ public:
|
||||
QString fieldTextValue(int index)
|
||||
{ return QString("UnknownFieldValue"); }
|
||||
QByteArray fieldRawValue(int index)
|
||||
{ return QByteArray(4, '\0'); }
|
||||
{ return QByteArray(); }
|
||||
};
|
||||
|
||||
class PayloadProtocol: public AbstractProtocol
|
||||
{
|
||||
Stream *parentStream;
|
||||
OstProto::Ack d; // FIXME(HI): move payload related vars from
|
||||
// stream into here
|
||||
|
||||
public:
|
||||
PayloadProtocol (Stream *stream = NULL) { parentStream = stream; }
|
||||
virtual ~PayloadProtocol() {}
|
||||
|
||||
virtual ::google::protobuf::Message& data() { return d; }
|
||||
|
||||
virtual QString protocolName()
|
||||
{ return QString("Payload Data"); }
|
||||
QString protocolShortName()
|
||||
{ return QString("DATA"); }
|
||||
int numFields()
|
||||
{ return 1; }
|
||||
QString fieldName(int index)
|
||||
{ return QString("Data"); }
|
||||
QString fieldTextValue(int index);
|
||||
QByteArray fieldRawValue(int index);
|
||||
};
|
||||
|
||||
class MacProtocol : public AbstractProtocol
|
||||
@ -238,6 +275,37 @@ public:
|
||||
QByteArray fieldRawValue(int index);
|
||||
};
|
||||
|
||||
|
||||
class Dot3Protocol : public AbstractProtocol
|
||||
{
|
||||
private:
|
||||
Stream *parentStream;
|
||||
OstProto::Ack d; // FIXME(HI): replace 'ack' with somehting else
|
||||
|
||||
public:
|
||||
Dot3Protocol(Stream *stream = NULL)
|
||||
{ parentStream = stream; qDebug("parentStream = %p", stream); }
|
||||
virtual ~Dot3Protocol() {}
|
||||
virtual ::google::protobuf::Message& data() {return d;}
|
||||
|
||||
#if 0 // FIXME(HI): remove?
|
||||
quint16 length()
|
||||
{ return d.length(); }
|
||||
bool setLength(quint16 length)
|
||||
{ return true; }
|
||||
#endif
|
||||
|
||||
virtual QString protocolName()
|
||||
{ return QString("802.3 Length"); }
|
||||
QString protocolShortName()
|
||||
{ return QString("LEN"); }
|
||||
int numFields()
|
||||
{ return 1; }
|
||||
QString fieldName(int index);
|
||||
QString fieldTextValue(int index);
|
||||
QByteArray fieldRawValue(int index);
|
||||
};
|
||||
|
||||
class VlanProtocol : public AbstractProtocol
|
||||
{
|
||||
OstProto::Vlan d;
|
||||
@ -765,11 +833,14 @@ class Stream {
|
||||
OstProto::StreamCore *mCore;
|
||||
|
||||
UnknownProtocol *mUnknown;
|
||||
PayloadProtocol *mPayload;
|
||||
MacProtocol *mMac;
|
||||
|
||||
LlcProtocol *mLlc;
|
||||
SnapProtocol *mSnap;
|
||||
Eth2Protocol *mEth2;
|
||||
Dot3Protocol *mDot3;
|
||||
|
||||
VlanProtocol *mVlan;
|
||||
|
||||
IpProtocol *mIp;
|
||||
@ -781,11 +852,15 @@ class Stream {
|
||||
IgmpProtocol *mIgmp;
|
||||
|
||||
public:
|
||||
//PayloadProtocol* Payload() { return mPayload; }
|
||||
MacProtocol* mac() { return mMac; }
|
||||
|
||||
void* core() { return mCore; } // FIXME(HI): Debug ONLY
|
||||
|
||||
LlcProtocol* llc() { return mLlc; }
|
||||
SnapProtocol* snap() { return mSnap; }
|
||||
Eth2Protocol* eth2() { return mEth2; }
|
||||
Dot3Protocol* dot3() { return mDot3; }
|
||||
VlanProtocol* vlan() { return mVlan; }
|
||||
|
||||
IpProtocol* ip() { return mIp; }
|
||||
@ -954,15 +1029,19 @@ public:
|
||||
//---------------------------------------------------------------
|
||||
// Methods for use by Packet Model
|
||||
//---------------------------------------------------------------
|
||||
QList<int> selectedProtocols;
|
||||
|
||||
int numProtocols();
|
||||
|
||||
//! Includes ALL protocol headers excluding payload data
|
||||
int protocolHeaderSize();
|
||||
#if 0
|
||||
int protocolId(int index);
|
||||
int protocolIndex(int id);
|
||||
#endif
|
||||
AbstractProtocol* protocol(int index);
|
||||
private:
|
||||
QList<int> selectedProtocols;
|
||||
int mProtocolHeaderSize;
|
||||
void updateSelectedProtocols();
|
||||
|
||||
};
|
||||
|
@ -16,13 +16,13 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
|
||||
//mpStreamList = streamList;
|
||||
mCurrentStreamIndex = streamIndex;
|
||||
LoadCurrentStream();
|
||||
|
||||
mpPacketModel = new PacketModel(&mPort.streamByIndex(mCurrentStreamIndex),
|
||||
this);
|
||||
tvPacketTree->setModel(mpPacketModel);
|
||||
mpPacketModelTester = new ModelTest(mpPacketModel);
|
||||
tvPacketTree->header()->hide();
|
||||
|
||||
vwPacketDump->setModel(mpPacketModel);
|
||||
vwPacketDump->setSelectionModel(tvPacketTree->selectionModel());
|
||||
|
||||
// FIXME(MED): Enable this navigation
|
||||
pbPrev->setDisabled(true);
|
||||
@ -625,6 +625,11 @@ void StreamConfigDialog::StoreCurrentStream()
|
||||
{
|
||||
pStream->mac()->setDstMac(
|
||||
leDstMac->text().remove(QChar(' ')).toULongLong(&isOk, 16));
|
||||
#if 1
|
||||
qDebug("%s: dstMac = %llx [%s] %d", __FUNCTION__,
|
||||
pStream->mac()->dstMac(),
|
||||
leDstMac->text().toAscii().constData(), isOk);
|
||||
#endif
|
||||
pStream->mac()->setDstMacMode(
|
||||
(MacProtocol::MacAddrMode) cmbDstMacMode->currentIndex());
|
||||
pStream->mac()->setDstMacCount(
|
||||
@ -634,6 +639,9 @@ void StreamConfigDialog::StoreCurrentStream()
|
||||
|
||||
pStream->mac()->setSrcMac(
|
||||
leSrcMac->text().remove(QChar(' ')).toULongLong(&isOk, 16));
|
||||
qDebug("%s: srcMac = %llx [%s] %d", __FUNCTION__,
|
||||
pStream->mac()->srcMac(),
|
||||
leSrcMac->text().toAscii().constData(), isOk);
|
||||
pStream->mac()->setSrcMacMode(
|
||||
(MacProtocol::MacAddrMode) cmbSrcMacMode->currentIndex());
|
||||
pStream->mac()->setSrcMacCount(
|
||||
|
@ -33,7 +33,7 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
<string/>
|
||||
</property>
|
||||
<property name="currentIndex" >
|
||||
<number>0</number>
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="widget" >
|
||||
<attribute name="title" >
|
||||
@ -2036,6 +2036,9 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
||||
<property name="selectionBehavior" >
|
||||
<enum>QAbstractItemView::SelectItems</enum>
|
||||
</property>
|
||||
<property name="wordWrap" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="DumpView" native="1" name="vwPacketDump" />
|
||||
</widget>
|
||||
|
@ -190,8 +190,8 @@ message StreamCore {
|
||||
optional uint32 data_start_ofs = 13;
|
||||
|
||||
// Frame Length (includes CRC)
|
||||
optional FrameLengthMode len_mode = 14;
|
||||
optional uint32 frame_len = 15;
|
||||
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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user