summaryrefslogtreecommitdiff
authormickeyl <mickeyl>2003-05-08 08:16:14 (UTC)
committer mickeyl <mickeyl>2003-05-08 08:16:14 (UTC)
commiteb1dba5550e63ab7b915d55048175e2992ab5447 (patch) (side-by-side diff)
tree52b37945352c56effd58cacac071cba4f410bef2
parent0950f27fa7136eb59f7e259cb4477ca10c89640d (diff)
downloadopie-eb1dba5550e63ab7b915d55048175e2992ab5447.zip
opie-eb1dba5550e63ab7b915d55048175e2992ab5447.tar.gz
opie-eb1dba5550e63ab7b915d55048175e2992ab5447.tar.bz2
decouple dump files from live capture to shift control over 'what' is dumped to applications
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--libopie2/opienet/opcap.cpp40
-rw-r--r--libopie2/opienet/opcap.h21
2 files changed, 47 insertions, 14 deletions
diff --git a/libopie2/opienet/opcap.cpp b/libopie2/opienet/opcap.cpp
index bef9182..1de7124 100644
--- a/libopie2/opienet/opcap.cpp
+++ b/libopie2/opienet/opcap.cpp
@@ -851,107 +851,122 @@ void OPacketCapturer::setBlocking( bool b )
}
}
bool OPacketCapturer::blocking() const
{
int b = pcap_getnonblock( _pch, _errbuf );
if ( b == -1 )
{
qDebug( "OPacketCapturer::blocking(): can't get blocking mode: %s", _errbuf );
return -1;
}
return !b;
}
+void OPacketCapturer::closeDumpFile()
+{
+ if ( _pcd )
+ {
+ pcap_dump_close( _pcd );
+ _pcd = 0;
+ }
+ pcap_close( _pch );
+}
+
+
void OPacketCapturer::close()
{
if ( _open )
{
if ( _sn )
{
_sn->disconnect( SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) );
delete _sn;
}
- if ( _pcd )
- {
- pcap_dump_close( _pcd );
- _pcd = 0;
- }
- pcap_close( _pch );
+ closeDumpFile();
_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 );
}
+void OPacketCapturer::dump( OPacket* p )
+{
+ if ( !_pcd )
+ {
+ qWarning( "OPacketCapturer::dump() - cannot dump without open capture file!" );
+ return;
+ }
+ pcap_dump( (u_char*) _pcd, &p->_hdr, p->_data );
+}
+
+
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 ( _pcd )
- pcap_dump( (u_char*) _pcd, &header, pdata );
if ( pdata && header.len )
{
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
{
qWarning( "OPacketCapturer::next() - no packet received!" );
return 0;
}
}
-bool OPacketCapturer::open( const QString& name, const QString& filename )
+bool OPacketCapturer::open( const QString& name )
{
if ( _open )
{
if ( name == _name ) // ignore opening an already openend device
{
return true;
}
else // close the last opened device
{
close();
}
}
_name = name;
// open libpcap
@@ -962,33 +977,38 @@ bool OPacketCapturer::open( const QString& name, const QString& filename )
qWarning( "OPacketCapturer::open(): can't open libpcap with '%s': %s", (const char*) name, _errbuf );
return false;
}
qDebug( "OPacketCapturer::open(): libpcap [%s] opened successfully.", (const char*) name );
_pch = handle;
_open = true;
_stats.clear();
// in case we have an application object, create a socket notifier
if ( qApp ) //TODO: I don't like this here...
{
_sn = new QSocketNotifier( fileno(), QSocketNotifier::Read );
connect( _sn, SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) );
}
- // if requested, open a dump
+ return true;
+}
+
+
+bool OPacketCapturer::openDumpFile( const QString& filename )
+{
pcap_dumper_t* dump = pcap_dump_open( _pch, const_cast<char*>( (const char*) filename ) );
if ( !dump )
{
qWarning( "OPacketCapturer::open(): can't open dump with '%s': %s", (const char*) filename, _errbuf );
return false;
}
qDebug( "OPacketCapturer::open(): dump [%s] opened successfully.", (const char*) filename );
_pcd = dump;
return true;
}
bool OPacketCapturer::open( const QFile& file )
{
QString name = file.name();
diff --git a/libopie2/opienet/opcap.h b/libopie2/opienet/opcap.h
index ad5b07c..9119972 100644
--- a/libopie2/opienet/opcap.h
+++ b/libopie2/opienet/opcap.h
@@ -102,32 +102,34 @@ class QSocketNotifier;
* QObject also cares about destroying the sub-, (child-) packets.
*
* This enables us to perform a simple look for packets of a certain type:
* @code
* OPacketCapturer* pcap = new OPacketCapturer();
* pcap->open( "eth0" );
* OPacket* p = pcap->next();
* 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;
+
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:
const packetheaderstruct _hdr; // pcap packet header
const unsigned char* _data; // pcap packet data
const unsigned char* _end; // end of pcap packet data
@@ -511,69 +513,80 @@ class OTCPPacket : public QObject
* library libpcap. ...
*/
class OPacketCapturer : public QObject
{
Q_OBJECT
public:
/**
* Constructor.
*/
OPacketCapturer( QObject* parent = 0, const char* name = 0 );
/**
* Destructor.
*/
~OPacketCapturer();
/**
- * Setting the packet capturer to use blocking IO calls can be useful when
+ * Set the packet capturer to use blocking or non-blocking IO. This can be useful when
* not using the socket notifier, e.g. without an application object.
*/
void setBlocking( bool );
/**
* @returns true if the packet capturer uses blocking IO calls.
*/
bool blocking() const;
/**
- * Closes the packet capturer. This is automatically done in the destructor.
+ * Close the packet capturer. This is automatically done in the destructor.
*/
void close();
/**
+ * Close the output capture file.
+ */
+ void closeDumpFile();
+ /**
* @returns the data link type.
* @see <pcap.h> for possible values.
*/
int dataLink() const;
/**
+ * Dump a packet to the output capture file.
+ */
+ void dump( OPacket* );
+ /**
* @returns the file descriptor of the packet capturer. This is only useful, if
* not using the socket notifier, e.g. without an application object.
*/
int fileno() const;
/**
* @returns the next @ref OPacket from the packet capturer.
* @note If blocking mode is true then this call might block.
*/
OPacket* next();
/**
* Open the packet capturer to capture packets in live-mode from @a interface.
- * If a @a filename is given, all captured packets are output to a tcpdump-compatible capture file.
*/
- bool open( const QString& interface, const QString& filename = QString::null );
+ bool open( const QString& interface );
/**
* Open the packet capturer to capture packets in offline-mode from @a file.
*/
bool open( const QFile& file );
/**
+ * Open a prerecorded tcpdump compatible capture file for use with @ref dump()
+ */
+ 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;