Protocol Framework Change: FieldFlags - FrameField and MetaField are no longer exclusive. A field can be neither. Also frameFieldCount() now actually counts the number of frameFields instead of deriving it from metaFieldCount() - these changes allow protocols to export different sets of fields based on a opcode/type field.

This commit is contained in:
Srivats P. 2010-06-07 20:52:50 +05:30
parent 710eb7f836
commit 069cc16279
15 changed files with 79 additions and 38 deletions

View File

@ -172,8 +172,7 @@ QVariant PacketModel::data(const QModelIndex &index, int role) const
while (n) while (n)
{ {
if (!(p->fieldFlags(fieldIdx).testFlag( if (p->fieldFlags(fieldIdx).testFlag(AbstractProtocol::FrameField))
AbstractProtocol::FieldIsMeta)))
n--; n--;
fieldIdx++; fieldIdx++;
} }

View File

@ -76,7 +76,8 @@ AbstractProtocol::AbstractProtocol(StreamBase *stream, AbstractProtocol *parent)
mpStream = stream; mpStream = stream;
this->parent = parent; this->parent = parent;
prev = next = NULL; prev = next = NULL;
metaCount = -1; _metaFieldCount = -1;
_frameFieldCount = -1;
protoSize = -1; protoSize = -1;
} }
@ -184,45 +185,59 @@ int AbstractProtocol::fieldCount() const
Returns the number of meta fields Returns the number of meta fields
The default implementation counts and returns the number of fields for which The default implementation counts and returns the number of fields for which
the FieldIsMeta flag is set\n the MetaField flag is set\n
The default implementation caches the count on its first invocation The default implementation caches the count on its first invocation
and subsequently returns the cached count and subsequently returns the cached count
*/ */
int AbstractProtocol::metaFieldCount() const int AbstractProtocol::metaFieldCount() const
{ {
if (metaCount < 0) if (_metaFieldCount < 0)
{ {
int c = 0; int c = 0;
for (int i = 0; i < fieldCount() ; i++) for (int i = 0; i < fieldCount() ; i++)
if (fieldFlags(i).testFlag(FieldIsMeta)) if (fieldFlags(i).testFlag(MetaField))
c++; c++;
metaCount = c; _metaFieldCount = c;
} }
return metaCount; return _metaFieldCount;
} }
/*! /*!
Returns the number of frame fields Returns the number of frame fields
Convenience method - same as fieldCount() minus metaFieldCount() The default implementation counts and returns the number of fields for which
the FrameField flag is set\n
The default implementation caches the count on its first invocation
and subsequently returns the cached count
Subclasses which export different sets of fields based on a opcode/type
(e.g. icmp) should re-implement this function
*/ */
int AbstractProtocol::frameFieldCount() const int AbstractProtocol::frameFieldCount() const
{ {
//qDebug("%s:%d, %d", __FUNCTION__, fieldCount(), metaFieldCount()); if (_frameFieldCount < 0)
return (fieldCount() - metaFieldCount()); {
int c = 0;
for (int i = 0; i < fieldCount() ; i++)
if (fieldFlags(i).testFlag(FrameField))
c++;
_frameFieldCount = c;
}
return _frameFieldCount;
} }
/*! /*!
Returns the field flags for the passed in field index Returns the field flags for the passed in field index
The default implementation assumes all fields to be frame fields and returns The default implementation assumes all fields to be frame fields and returns
'FieldIsNormal'. Subclasses must reimplement this method if they have any 'FrameField'. Subclasses must reimplement this method if they have any
meta fields or checksum fields. See the SampleProtocol for an example. meta fields or checksum fields. See the SampleProtocol for an example.
*/ */
AbstractProtocol::FieldFlags AbstractProtocol::fieldFlags(int /*index*/) const AbstractProtocol::FieldFlags AbstractProtocol::fieldFlags(int /*index*/) const
{ {
return FieldIsNormal; return FrameField;
} }
/*! /*!
@ -261,7 +276,7 @@ QVariant AbstractProtocol::fieldData(int index, FieldAttrib attrib,
case FieldName: case FieldName:
return QString(); return QString();
case FieldBitSize: case FieldBitSize:
Q_ASSERT_X(!fieldFlags(index).testFlag(FieldIsCksum), Q_ASSERT_X(!fieldFlags(index).testFlag(CksumField),
"AbstractProtocol::fieldData()", "AbstractProtocol::fieldData()",
"FieldBitSize for checksum fields need to be handled by the subclass"); "FieldBitSize for checksum fields need to be handled by the subclass");
return fieldData(index, FieldFrameValue, streamIndex). return fieldData(index, FieldFrameValue, streamIndex).
@ -366,7 +381,7 @@ int AbstractProtocol::protocolFrameSize(int streamIndex) const
for (int i = 0; i < fieldCount(); i++) for (int i = 0; i < fieldCount(); i++)
{ {
if (!fieldFlags(i).testFlag(FieldIsMeta)) if (fieldFlags(i).testFlag(FrameField))
bitsize += fieldData(i, FieldBitSize, streamIndex).toUInt(); bitsize += fieldData(i, FieldBitSize, streamIndex).toUInt();
} }
protoSize = (bitsize+7)/8; protoSize = (bitsize+7)/8;
@ -440,14 +455,14 @@ QByteArray AbstractProtocol::protocolFrameValue(int streamIndex, bool forCksum)
for (int i=0; i < fieldCount() ; i++) for (int i=0; i < fieldCount() ; i++)
{ {
flags = fieldFlags(i); flags = fieldFlags(i);
if (!flags.testFlag(FieldIsMeta)) if (flags.testFlag(FrameField))
{ {
bits = fieldData(i, FieldBitSize, streamIndex).toUInt(); bits = fieldData(i, FieldBitSize, streamIndex).toUInt();
if (bits == 0) if (bits == 0)
continue; continue;
Q_ASSERT(bits > 0); Q_ASSERT(bits > 0);
if (forCksum && flags.testFlag(FieldIsCksum)) if (forCksum && flags.testFlag(CksumField))
{ {
field.resize((bits+7)/8); field.resize((bits+7)/8);
field.fill('\0'); field.fill('\0');

View File

@ -48,7 +48,8 @@ class AbstractProtocol
friend class ProtocolListIterator; friend class ProtocolListIterator;
private: private:
mutable int metaCount; mutable int _metaFieldCount;
mutable int _frameFieldCount;
mutable int protoSize; mutable int protoSize;
mutable QString protoAbbr; mutable QString protoAbbr;
@ -61,9 +62,9 @@ protected:
public: public:
//! Properties of a field, can be OR'd //! Properties of a field, can be OR'd
enum FieldFlag { enum FieldFlag {
FieldIsNormal = 0x0, //!< field appears in frame content FrameField = 0x1, //!< field appears in frame content
FieldIsMeta = 0x1, //!< field does not appear in frame, is meta data MetaField = 0x2, //!< field does not appear in frame, is meta data
FieldIsCksum = 0x2 //!< field is a checksum, appears in frame content CksumField = 0x4 //!< field is a checksum and appears in frame content
}; };
Q_DECLARE_FLAGS(FieldFlags, FieldFlag); //!< \private abcd Q_DECLARE_FLAGS(FieldFlags, FieldFlag); //!< \private abcd

View File

@ -203,7 +203,8 @@ AbstractProtocol::FieldFlags ArpProtocol::fieldFlags(int index) const
case arp_targetProtoAddrMode: case arp_targetProtoAddrMode:
case arp_targetProtoAddrCount: case arp_targetProtoAddrCount:
case arp_targetProtoAddrMask: case arp_targetProtoAddrMask:
flags |= FieldIsMeta; flags &= ~FrameField;
flags |= MetaField;
break; break;
default: default:

View File

@ -159,17 +159,18 @@ AbstractProtocol::FieldFlags IcmpProtocol::fieldFlags(int index) const
break; break;
case icmp_checksum: case icmp_checksum:
flags |= FieldIsCksum; flags |= CksumField;
break; break;
case icmp_identifier: case icmp_identifier:
case icmp_sequence: case icmp_sequence:
if (!idSeqSet.contains(fieldData(icmp_type, FieldValue).toUInt())) if (!idSeqSet.contains(fieldData(icmp_type, FieldValue).toUInt()))
flags |= FieldIsMeta; flags &= ~FrameField;
break; break;
case icmp_is_override_checksum: case icmp_is_override_checksum:
flags |= FieldIsMeta; flags &= ~FrameField;
flags |= MetaField;
break; break;
default: default:

View File

@ -156,7 +156,7 @@ AbstractProtocol::FieldFlags Ip4Protocol::fieldFlags(int index) const
break; break;
case ip4_cksum: case ip4_cksum:
flags |= FieldIsCksum; flags |= CksumField;
break; break;
case ip4_srcAddr: case ip4_srcAddr:
@ -173,7 +173,8 @@ AbstractProtocol::FieldFlags Ip4Protocol::fieldFlags(int index) const
case ip4_dstAddrMode: case ip4_dstAddrMode:
case ip4_dstAddrCount: case ip4_dstAddrCount:
case ip4_dstAddrMask: case ip4_dstAddrMask:
flags |= FieldIsMeta; flags &= ~FrameField;
flags |= MetaField;
break; break;
default: default:

View File

@ -165,7 +165,8 @@ AbstractProtocol::FieldFlags Ip6Protocol::fieldFlags(int index) const
case ip6_dstAddrMode: case ip6_dstAddrMode:
case ip6_dstAddrCount: case ip6_dstAddrCount:
case ip6_dstAddrPrefix: case ip6_dstAddrPrefix:
flags |= FieldIsMeta; flags &= ~FrameField;
flags |= MetaField;
break; break;
default: default:

View File

@ -136,7 +136,8 @@ AbstractProtocol::FieldFlags MacProtocol::fieldFlags(int index) const
case mac_srcMacMode: case mac_srcMacMode:
case mac_srcMacCount: case mac_srcMacCount:
case mac_srcMacStep: case mac_srcMacStep:
flags |= FieldIsMeta; flags &= ~FrameField;
flags |= MetaField;
break; break;
} }

View File

@ -126,7 +126,8 @@ AbstractProtocol::FieldFlags PayloadProtocol::fieldFlags(int index) const
// Meta fields // Meta fields
case payload_dataPatternMode: case payload_dataPatternMode:
flags |= FieldIsMeta; flags &= ~FrameField;
flags |= MetaField;
break; break;
} }

View File

@ -109,6 +109,20 @@ int SampleProtocol::fieldCount() const
return sample_fieldCount; return sample_fieldCount;
} }
/*!
TODO Return the number of frame fields for your protocol. A frame field
is a field which has the FrameField flag set \n
If your protocol has different sets of fields based on a OpCode/Type field
(e.g. icmp), you MUST re-implement this function; however, if your protocol
has a fixed set of frame fields always, you don't need to reimplement this
method - the base class implementation will do the right thing
*/
int SampleProtocol::frameFieldCount() const
{
return 0;
}
/*! /*!
TODO Edit this function to return the appropriate flags for each field \n TODO Edit this function to return the appropriate flags for each field \n
@ -128,7 +142,7 @@ AbstractProtocol::FieldFlags SampleProtocol::fieldFlags(int index) const
break; break;
case sample_checksum: case sample_checksum:
flags |= FieldIsCksum; flags |= CksumField;
break; break;
case sample_x: case sample_x:
@ -136,7 +150,8 @@ AbstractProtocol::FieldFlags SampleProtocol::fieldFlags(int index) const
break; break;
case sample_is_override_checksum: case sample_is_override_checksum:
flags |= FieldIsMeta; flags &= ~FrameField;
flags |= MetaField;
break; break;
default: default:

View File

@ -81,6 +81,7 @@ public:
virtual QString shortName() const; virtual QString shortName() const;
virtual int fieldCount() const; virtual int fieldCount() const;
virtual int frameFieldCount() const;
virtual AbstractProtocol::FieldFlags fieldFlags(int index) const; virtual AbstractProtocol::FieldFlags fieldFlags(int index) const;
virtual QVariant fieldData(int index, FieldAttrib attrib, virtual QVariant fieldData(int index, FieldAttrib attrib,

View File

@ -113,7 +113,7 @@ AbstractProtocol::FieldFlags TcpProtocol::fieldFlags(int index) const
break; break;
case tcp_cksum: case tcp_cksum:
flags |= FieldIsCksum; flags |= CksumField;
break; break;
case tcp_urg_ptr: case tcp_urg_ptr:
@ -123,7 +123,8 @@ AbstractProtocol::FieldFlags TcpProtocol::fieldFlags(int index) const
case tcp_is_override_dst_port: case tcp_is_override_dst_port:
case tcp_is_override_hdrlen: case tcp_is_override_hdrlen:
case tcp_is_override_cksum: case tcp_is_override_cksum:
flags |= FieldIsMeta; flags &= ~FrameField;
flags |= MetaField;
break; break;
default: default:

View File

@ -108,7 +108,8 @@ AbstractProtocol::FieldFlags TextProtocol::fieldFlags(int index) const
case textProto_portNum: case textProto_portNum:
case textProto_encoding: case textProto_encoding:
flags |= FieldIsMeta; flags &= ~FrameField;
flags |= MetaField;
break; break;
default: default:

View File

@ -108,14 +108,15 @@ AbstractProtocol::FieldFlags UdpProtocol::fieldFlags(int index) const
break; break;
case udp_cksum: case udp_cksum:
flags |= FieldIsCksum; flags |= CksumField;
break; break;
case udp_isOverrideSrcPort: case udp_isOverrideSrcPort:
case udp_isOverrideDstPort: case udp_isOverrideDstPort:
case udp_isOverrideTotLen: case udp_isOverrideTotLen:
case udp_isOverrideCksum: case udp_isOverrideCksum:
flags |= FieldIsMeta; flags &= ~FrameField;
flags |= MetaField;
break; break;
default: default:

View File

@ -93,7 +93,8 @@ AbstractProtocol::FieldFlags VlanProtocol::fieldFlags(int index) const
// meta-fields // meta-fields
case vlan_isOverrideTpid: case vlan_isOverrideTpid:
flags |= FieldIsMeta; flags &= ~FrameField;
flags |= MetaField;
break; break;
} }