summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--libopie2/opienet/opcap.cpp21
-rw-r--r--libopie2/opienet/opcap.h16
2 files changed, 31 insertions, 6 deletions
diff --git a/libopie2/opienet/opcap.cpp b/libopie2/opienet/opcap.cpp
index 4081d4f..c5df041 100644
--- a/libopie2/opienet/opcap.cpp
+++ b/libopie2/opienet/opcap.cpp
@@ -36,78 +36,79 @@
#include <qapplication.h> // don't use oapplication here (will decrease reusability in other projects)
#include <qsocketnotifier.h>
#include <qobjectlist.h>
/* SYSTEM */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
/* LOCAL */
#include "udp_ports.h"
using namespace Opie::Core;
namespace Opie {
namespace Net {
/*======================================================================================
* 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 );
+ 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 );
switch ( datalink )
{
case DLT_EN10MB:
odebug << "OPacket::OPacket(): Received Packet. Datalink = ETHERNET" << oendl;
new OEthernetPacket( _end, (const struct ether_header*) data, this );
break;
case DLT_IEEE802_11:
odebug << "OPacket::OPacket(): Received Packet. Datalink = IEEE802.11" << oendl;
new OWaveLanPacket( _end, (const struct ieee_802_11_header*) data, this );
break;
case DLT_PRISM_HEADER:
odebug << "OPacket::OPacket(): Received Packet. Datalink = PRISM_HEADER" << oendl;
new OPrismHeaderPacket( _end, (const struct prism_hdr*) (unsigned char*) data, this );
break;
default:
owarn << "OPacket::OPacket(): Received Packet over unsupported datalink, type " << datalink << "!" << oendl;
}
}
OPacket::~OPacket()
{
+ qDebug( "OPacket::~OPacket( %s )", name() );
}
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();
@@ -1042,63 +1043,75 @@ OWaveLanControlPacket::~OWaveLanControlPacket()
QString OWaveLanControlPacket::controlType() const
{
switch ( FC_SUBTYPE( EXTRACT_LE_16BITS( &_header->fc ) ) )
{
case CTRL_PS_POLL: return "PowerSavePoll"; break;
case CTRL_RTS: return "RequestToSend"; break;
case CTRL_CTS: return "ClearToSend"; break;
case CTRL_ACK: return "Acknowledge"; break;
case CTRL_CF_END: return "ContentionFreeEnd"; break;
case CTRL_END_ACK: return "AcknowledgeEnd"; break;
default:
owarn << "OWaveLanControlPacket::managementType(): unhandled subtype " << FC_SUBTYPE( EXTRACT_LE_16BITS( &_header->fc ) ) << oendl;
return "Unknown";
}
}
/*======================================================================================
* OPacketCapturer
*======================================================================================*/
OPacketCapturer::OPacketCapturer( QObject* parent, const char* name )
- :QObject( parent, name ), _name( QString::null ), _open( false ), _pch( 0 ), _pcd( 0 ), _sn( 0 )
+ :QObject( parent, name ), _name( QString::null ), _open( false ), _pch( 0 ), _pcd( 0 ), _sn( 0 ), _autodelete( true )
{
}
OPacketCapturer::~OPacketCapturer()
{
if ( _open )
{
odebug << "OPacketCapturer::~OPacketCapturer(): pcap still open, autoclosing." << oendl;
close();
}
}
+void OPacketCapturer::setAutoDelete( bool b )
+{
+ _autodelete = b;
+}
+
+
+bool OPacketCapturer::autoDelete() const
+{
+ return _autodelete;
+}
+
+
void OPacketCapturer::setBlocking( bool b )
{
if ( pcap_setnonblock( _pch, 1-b, _errbuf ) != -1 )
{
odebug << "OPacketCapturer::setBlocking(): blocking mode changed successfully." << oendl;
}
else
{
odebug << "OPacketCapturer::setBlocking(): can't change blocking mode: " << _errbuf << oendl;
}
}
bool OPacketCapturer::blocking() const
{
int b = pcap_getnonblock( _pch, _errbuf );
if ( b == -1 )
{
odebug << "OPacketCapturer::blocking(): can't get blocking mode: " << _errbuf << oendl;
return -1;
}
return !b;
}
@@ -1300,50 +1313,50 @@ bool OPacketCapturer::open( const QFile& file )
}
return true;
}
else
{
odebug << "OPacketCapturer::open(): can't open libpcap with '" << name << "': " << _errbuf << oendl;
return false;
}
}
bool OPacketCapturer::isOpen() const
{
return _open;
}
void OPacketCapturer::readyToReceive()
{
odebug << "OPacketCapturer::readyToReceive(): about to emit 'receivePacket(p)'" << oendl;
OPacket* p = next();
emit receivedPacket( p );
- // emit is synchronous - packet has been dealt with, now it's safe to delete
- delete p;
+ // emit is synchronous - packet has been dealt with, now it's safe to delete (if enabled)
+ if ( _autodelete ) delete p;
}
const QMap<QString,int>& OPacketCapturer::statistics() const
{
return _stats;
}
int OPacketCapturer::snapShot() const
{
return pcap_snapshot( _pch );
}
bool OPacketCapturer::swapped() const
{
return pcap_is_swapped( _pch );
}
QString OPacketCapturer::version() const
{
return QString().sprintf( "%d.%d", pcap_major_version( _pch ), pcap_minor_version( _pch ) );
diff --git a/libopie2/opienet/opcap.h b/libopie2/opienet/opcap.h
index 72a78de..4ff8495 100644
--- a/libopie2/opienet/opcap.h
+++ b/libopie2/opienet/opcap.h
@@ -113,51 +113,50 @@ class OPacketCapturer;
* OIPPacket* ip = (OIPPacket*) p->child( "IP" ); // returns 0, if no such child exists
* odebug << "got ip packet from " << ip->fromIPAddress().toString() << " to " << ip->toIPAddress().toString() << oendl;
*
*/
class OPacket : public QObject
{
Q_OBJECT
friend class OPacketCapturer;
friend QTextStream& operator<<( QTextStream& s, const OPacket& p );
public:
OPacket( int datalink, packetheaderstruct, const unsigned char*, QObject* parent );
virtual ~OPacket();
timevalstruct timeval() const;
int caplen() const;
int len() const;
QString dump( int = 32 ) const;
void updateStats( QMap<QString,int>&, QObjectList* );
- private:
-
QString dumpStructure() const;
+ private:
QString _dumpStructure( QObjectList* ) const;
private:
const packetheaderstruct _hdr; // pcap packet header
const unsigned char* _data; // pcap packet data
const unsigned char* _end; // end of pcap packet data
private:
class Private;
Private *d;
};
QTextStream& operator<<( QTextStream& s, const OPacket& p );
/*======================================================================================
* OEthernetPacket - DLT_EN10MB frame
*======================================================================================*/
class OEthernetPacket : public QObject
{
Q_OBJECT
public:
OEthernetPacket( const unsigned char*, const struct ether_header*, QObject* parent = 0 );
virtual ~OEthernetPacket();
@@ -672,50 +671,63 @@ class OPacketCapturer : public QObject
*/
bool openDumpFile( const QString& filename );
/**
* @returns true if the packet capturer is open
*/
bool isOpen() const;
/**
* @returns the snapshot length of this packet capturer
*/
int snapShot() const;
/**
* @returns true if the input capture file has a different byte-order
* than the byte-order of the running system.
*/
bool swapped() const;
/**
* @returns the libpcap version string used to write the input capture file.
*/
QString version() const;
/**
* @returns the packet statistic database.
* @see QMap
*/
const QMap<QString,int>& statistics() const;
+ /**
+ * Enable or disable the auto-delete option.
+ * If auto-delete is enabled, then the packet capturer will delete a packet right
+ * after it has been emit'ted. This is the default, which is useful if the packet
+ * capturer has the only reference to the packets. If you pass the packet for adding
+ * into a collection or do processing after the SLOT, the auto delete must be disabled.
+ */
+ void setAutoDelete( bool enable );
+ /**
+ * @returns the auto-delete value.
+ */
+ bool autoDelete() const;
signals:
/**
* This signal is emitted, when a packet has been received.
*/
void receivedPacket( Opie::Net::OPacket* );
protected slots:
void readyToReceive();
protected:
QString _name; // devicename
bool _open; // check this before doing pcap calls
pcap_t* _pch; // pcap library handle
pcap_dumper_t* _pcd; // pcap dumper handle
QSocketNotifier* _sn; // socket notifier for main loop
mutable char _errbuf[PCAP_ERRBUF_SIZE]; // holds error strings from libpcap
QMap<QString, int> _stats; // statistics;
+ bool _autodelete; // if we auto delete packets after emit
class Private; // Private Forward declaration
Private *d; // if we need to add data
};
}
}
#endif // OPCAP_H