summaryrefslogtreecommitdiff
path: root/libopie2/opienet/opcap.cpp
Side-by-side diff
Diffstat (limited to 'libopie2/opienet/opcap.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opienet/opcap.cpp40
1 files changed, 36 insertions, 4 deletions
diff --git a/libopie2/opienet/opcap.cpp b/libopie2/opienet/opcap.cpp
index 5c464cf..6a3dc26 100644
--- a/libopie2/opienet/opcap.cpp
+++ b/libopie2/opienet/opcap.cpp
@@ -30,24 +30,25 @@
Boston, MA 02111-1307, USA.
*/
/* OPIE */
#include <opie2/opcap.h>
/* QT */
#include <qapplication.h> // don't use oapplication here (will decrease reusability in other projects)
#include <qsocketnotifier.h>
+#include <qobjectlist.h>
/*======================================================================================
* OPacket
*======================================================================================*/
OPacket::OPacket( int datalink, packetheaderstruct header, const unsigned char* data, QObject* parent )
:QObject( parent, "Generic" ), _hdr( header ), _data( data )
{
//qDebug( "OPacket::OPacket(): (Len %d, CapLen %d)" /*, ctime((const time_t*) header.ts.tv_sec)*/, header.len, header.caplen );
_end = (unsigned char*) data + header.len;
//qDebug( "OPacket::data @ %0x, end @ %0x", data, _end );
@@ -78,24 +79,37 @@ OPacket::~OPacket()
timevalstruct OPacket::timeval() const
{
return _hdr.ts;
}
int OPacket::caplen() const
{
return _hdr.caplen;
}
+void OPacket::updateStats( QMap<QString,int>& stats, QObjectList* l )
+{
+ if (!l) return;
+ QObject* o = l->first();
+ while ( o )
+ {
+ stats[o->name()]++;
+ updateStats( stats, const_cast<QObjectList*>( o->children() ) );
+ o = l->next();
+ }
+}
+
+
QString OPacket::dump( int bpl ) const
{
static int index = 0;
index++;
int len = _hdr.caplen;
QString str;
str.sprintf( "\n<----- Packet #%04d Len = 0x%X (%d) ----->\n\n", index, len, len );
str.append( "0000: " );
QString tmp;
QString bytes;
QString chars;
@@ -118,30 +132,30 @@ QString OPacket::dump( int bpl ) const
}
if ( (len % bpl) )
{
str.append( bytes.leftJustify( 1 + 3*bpl ) );
str.append( chars );
}
str.append( '\n' );
return str;
}
-
int OPacket::len() const
{
return _hdr.len;
}
+
/*======================================================================================
* OEthernetPacket
*======================================================================================*/
OEthernetPacket::OEthernetPacket( const unsigned char* end, const struct ether_header* data, QObject* parent )
:QObject( parent, "Ethernet" ), _ether( data )
{
qDebug( "Source = %s", (const char*) sourceAddress().toString() );
qDebug( "Destination = %s", (const char*) destinationAddress().toString() );
@@ -763,60 +777,71 @@ bool OPacketCapturer::blocking() const
void OPacketCapturer::close()
{
if ( _open )
{
if ( _sn )
{
_sn->disconnect( SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) );
delete _sn;
}
pcap_close( _pch );
_open = false;
}
+
+ qDebug( "OPacketCapturer::close() --- dumping capturing statistics..." );
+ qDebug( "--------------------------------------------------" );
+ for( QMap<QString,int>::Iterator it = _stats.begin(); it != _stats.end(); ++it )
+ qDebug( "%s : %d", (const char*) it.key(), it.data() );
+ qDebug( "--------------------------------------------------" );
+
}
int OPacketCapturer::dataLink() const
{
return pcap_datalink( _pch );
}
int OPacketCapturer::fileno() const
{
if ( _open )
{
return pcap_fileno( _pch );
}
else
{
return -1;
}
}
-
OPacket* OPacketCapturer::next()
{
packetheaderstruct header;
qDebug( "==> OPacketCapturer::next()" );
const unsigned char* pdata = pcap_next( _pch, &header );
qDebug( "<== OPacketCapturer::next()" );
if ( header.len )
{
- return new OPacket( dataLink(), header, pdata, 0 );
+ OPacket* p = new OPacket( dataLink(), header, pdata, 0 );
// packets shouldn't be inserted in the QObject child-parent hierarchy,
// because due to memory constraints they will be deleted as soon
// as possible - that is right after they have been processed
// by emit() [ see below ]
+
+ //TODO: make gathering statistics optional, because it takes time
+ p->updateStats( _stats, const_cast<QObjectList*>( p->children() ) );
+
+ return p;
}
else
{
return 0;
}
}
bool OPacketCapturer::open( const QString& name )
{
if ( _open )
{
@@ -830,24 +855,25 @@ bool OPacketCapturer::open( const QString& name )
}
}
_name = name;
pcap_t* handle = pcap_open_live( const_cast<char*>( (const char*) name ), 1024, 0, 0, &_errbuf[0] );
if ( handle )
{
qDebug( "OPacketCapturer::open(): libpcap opened successfully." );
_pch = handle;
_open = true;
+ _stats.clear();
// in case we have an application object, create a socket notifier
if ( qApp )
{
_sn = new QSocketNotifier( fileno(), QSocketNotifier::Read );
connect( _sn, SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) );
}
return true;
}
else
{
@@ -857,19 +883,25 @@ bool OPacketCapturer::open( const QString& name )
}
bool OPacketCapturer::isOpen() const
{
return _open;
}
void OPacketCapturer::readyToReceive()
{
- qDebug( "OPacketCapturer::readyToReceive(): about to emit 'receivePacket(...)'" );
+ qDebug( "OPacketCapturer::readyToReceive(): about to emit 'receivePacket(p)'" );
OPacket* p = next();
emit receivedPacket( p );
// emit is synchronous - packet has been dealt with, now it's safe to delete
delete p;
}
+
+const QMap<QString,int>& OPacketCapturer::statistics() const
+{
+ return _stats;
+}
+