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:
Srivats P. 2008-08-30 08:49:08 +00:00
parent c7f4c1dec9
commit 9e7b323973
8 changed files with 718 additions and 857 deletions

View File

@ -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);
}
}

View File

@ -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;
};

View File

@ -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

View File

@ -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;
}

View File

@ -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();
};

View File

@ -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(

View File

@ -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>

View File

@ -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;