summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opienet/opcap.cpp42
-rw-r--r--libopie2/opienet/opcap.h21
2 files changed, 48 insertions, 15 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 )
851 } 851 }
852} 852}
853 853
854 854
855bool OPacketCapturer::blocking() const 855bool OPacketCapturer::blocking() const
856{ 856{
857 int b = pcap_getnonblock( _pch, _errbuf ); 857 int b = pcap_getnonblock( _pch, _errbuf );
858 if ( b == -1 ) 858 if ( b == -1 )
859 { 859 {
860 qDebug( "OPacketCapturer::blocking(): can't get blocking mode: %s", _errbuf ); 860 qDebug( "OPacketCapturer::blocking(): can't get blocking mode: %s", _errbuf );
861 return -1; 861 return -1;
862 } 862 }
863 return !b; 863 return !b;
864} 864}
865 865
866 866
867void OPacketCapturer::closeDumpFile()
868{
869 if ( _pcd )
870 {
871 pcap_dump_close( _pcd );
872 _pcd = 0;
873 }
874 pcap_close( _pch );
875}
876
877
867void OPacketCapturer::close() 878void OPacketCapturer::close()
868{ 879{
869 if ( _open ) 880 if ( _open )
870 { 881 {
871 if ( _sn ) 882 if ( _sn )
872 { 883 {
873 _sn->disconnect( SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) ); 884 _sn->disconnect( SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) );
874 delete _sn; 885 delete _sn;
875 } 886 }
876 if ( _pcd ) 887 closeDumpFile();
877 { 888 _open = false;
878 pcap_dump_close( _pcd );
879 _pcd = 0;
880 }
881 pcap_close( _pch );
882 _open = false;
883 } 889 }
884 890
885 qDebug( "OPacketCapturer::close() --- dumping capturing statistics..." ); 891 qDebug( "OPacketCapturer::close() --- dumping capturing statistics..." );
886 qDebug( "--------------------------------------------------" ); 892 qDebug( "--------------------------------------------------" );
887 for( QMap<QString,int>::Iterator it = _stats.begin(); it != _stats.end(); ++it ) 893 for( QMap<QString,int>::Iterator it = _stats.begin(); it != _stats.end(); ++it )
888 qDebug( "%s : %d", (const char*) it.key(), it.data() ); 894 qDebug( "%s : %d", (const char*) it.key(), it.data() );
889 qDebug( "--------------------------------------------------" ); 895 qDebug( "--------------------------------------------------" );
890 896
891} 897}
892 898
893 899
894int OPacketCapturer::dataLink() const 900int OPacketCapturer::dataLink() const
895{ 901{
896 return pcap_datalink( _pch ); 902 return pcap_datalink( _pch );
897} 903}
898 904
899 905
906void OPacketCapturer::dump( OPacket* p )
907{
908 if ( !_pcd )
909 {
910 qWarning( "OPacketCapturer::dump() - cannot dump without open capture file!" );
911 return;
912 }
913 pcap_dump( (u_char*) _pcd, &p->_hdr, p->_data );
914}
915
916
900int OPacketCapturer::fileno() const 917int OPacketCapturer::fileno() const
901{ 918{
902 if ( _open ) 919 if ( _open )
903 { 920 {
904 return pcap_fileno( _pch ); 921 return pcap_fileno( _pch );
905 } 922 }
906 else 923 else
907 { 924 {
908 return -1; 925 return -1;
909 } 926 }
910} 927}
911 928
912OPacket* OPacketCapturer::next() 929OPacket* OPacketCapturer::next()
913{ 930{
914 packetheaderstruct header; 931 packetheaderstruct header;
915 qDebug( "==> OPacketCapturer::next()" ); 932 qDebug( "==> OPacketCapturer::next()" );
916 const unsigned char* pdata = pcap_next( _pch, &header ); 933 const unsigned char* pdata = pcap_next( _pch, &header );
917 qDebug( "<== OPacketCapturer::next()" ); 934 qDebug( "<== OPacketCapturer::next()" );
918 if ( _pcd )
919 pcap_dump( (u_char*) _pcd, &header, pdata );
920 935
921 if ( pdata && header.len ) 936 if ( pdata && header.len )
922 { 937 {
923 OPacket* p = new OPacket( dataLink(), header, pdata, 0 ); 938 OPacket* p = new OPacket( dataLink(), header, pdata, 0 );
924 // packets shouldn't be inserted in the QObject child-parent hierarchy, 939 // packets shouldn't be inserted in the QObject child-parent hierarchy,
925 // because due to memory constraints they will be deleted as soon 940 // because due to memory constraints they will be deleted as soon
926 // as possible - that is right after they have been processed 941 // as possible - that is right after they have been processed
927 // by emit() [ see below ] 942 // by emit() [ see below ]
928 //TODO: make gathering statistics optional, because it takes time 943 //TODO: make gathering statistics optional, because it takes time
929 p->updateStats( _stats, const_cast<QObjectList*>( p->children() ) ); 944 p->updateStats( _stats, const_cast<QObjectList*>( p->children() ) );
930 945
931 return p; 946 return p;
932 } 947 }
933 else 948 else
934 { 949 {
935 qWarning( "OPacketCapturer::next() - no packet received!" ); 950 qWarning( "OPacketCapturer::next() - no packet received!" );
936 return 0; 951 return 0;
937 } 952 }
938} 953}
939 954
940 955
941bool OPacketCapturer::open( const QString& name, const QString& filename ) 956bool OPacketCapturer::open( const QString& name )
942{ 957{
943 if ( _open ) 958 if ( _open )
944 { 959 {
945 if ( name == _name ) // ignore opening an already openend device 960 if ( name == _name ) // ignore opening an already openend device
946 { 961 {
947 return true; 962 return true;
948 } 963 }
949 else // close the last opened device 964 else // close the last opened device
950 { 965 {
951 close(); 966 close();
952 } 967 }
953 } 968 }
954 969
955 _name = name; 970 _name = name;
956 971
957 // open libpcap 972 // open libpcap
@@ -962,33 +977,38 @@ bool OPacketCapturer::open( const QString& name, const QString& filename )
962 qWarning( "OPacketCapturer::open(): can't open libpcap with '%s': %s", (const char*) name, _errbuf ); 977 qWarning( "OPacketCapturer::open(): can't open libpcap with '%s': %s", (const char*) name, _errbuf );
963 return false; 978 return false;
964 } 979 }
965 980
966 qDebug( "OPacketCapturer::open(): libpcap [%s] opened successfully.", (const char*) name ); 981 qDebug( "OPacketCapturer::open(): libpcap [%s] opened successfully.", (const char*) name );
967 _pch = handle; 982 _pch = handle;
968 _open = true; 983 _open = true;
969 _stats.clear(); 984 _stats.clear();
970 985
971 // in case we have an application object, create a socket notifier 986 // in case we have an application object, create a socket notifier
972 if ( qApp ) //TODO: I don't like this here... 987 if ( qApp ) //TODO: I don't like this here...
973 { 988 {
974 _sn = new QSocketNotifier( fileno(), QSocketNotifier::Read ); 989 _sn = new QSocketNotifier( fileno(), QSocketNotifier::Read );
975 connect( _sn, SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) ); 990 connect( _sn, SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) );
976 } 991 }
977 992
978 // if requested, open a dump 993 return true;
994}
995
996
997bool OPacketCapturer::openDumpFile( const QString& filename )
998{
979 pcap_dumper_t* dump = pcap_dump_open( _pch, const_cast<char*>( (const char*) filename ) ); 999 pcap_dumper_t* dump = pcap_dump_open( _pch, const_cast<char*>( (const char*) filename ) );
980 if ( !dump ) 1000 if ( !dump )
981 { 1001 {
982 qWarning( "OPacketCapturer::open(): can't open dump with '%s': %s", (const char*) filename, _errbuf ); 1002 qWarning( "OPacketCapturer::open(): can't open dump with '%s': %s", (const char*) filename, _errbuf );
983 return false; 1003 return false;
984 } 1004 }
985 qDebug( "OPacketCapturer::open(): dump [%s] opened successfully.", (const char*) filename ); 1005 qDebug( "OPacketCapturer::open(): dump [%s] opened successfully.", (const char*) filename );
986 _pcd = dump; 1006 _pcd = dump;
987 1007
988 return true; 1008 return true;
989} 1009}
990 1010
991 1011
992bool OPacketCapturer::open( const QFile& file ) 1012bool OPacketCapturer::open( const QFile& file )
993{ 1013{
994 QString name = file.name(); 1014 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;
102 * QObject also cares about destroying the sub-, (child-) packets. 102 * QObject also cares about destroying the sub-, (child-) packets.
103 * 103 *
104 * This enables us to perform a simple look for packets of a certain type: 104 * This enables us to perform a simple look for packets of a certain type:
105 * @code 105 * @code
106 * OPacketCapturer* pcap = new OPacketCapturer(); 106 * OPacketCapturer* pcap = new OPacketCapturer();
107 * pcap->open( "eth0" ); 107 * pcap->open( "eth0" );
108 * OPacket* p = pcap->next(); 108 * OPacket* p = pcap->next();
109 * OIPPacket* ip = (OIPPacket*) p->child( "IP" ); // returns 0, if no such child exists 109 * OIPPacket* ip = (OIPPacket*) p->child( "IP" ); // returns 0, if no such child exists
110 * odebug << "got ip packet from " << ip->fromIPAddress().toString() << " to " << ip->toIPAddress().toString() << oendl; 110 * odebug << "got ip packet from " << ip->fromIPAddress().toString() << " to " << ip->toIPAddress().toString() << oendl;
111 * 111 *
112 */ 112 */
113 113
114class OPacket : public QObject 114class OPacket : public QObject
115{ 115{
116 Q_OBJECT 116 Q_OBJECT
117 117
118 friend class OPacketCapturer;
119
118 public: 120 public:
119 OPacket( int datalink, packetheaderstruct, const unsigned char*, QObject* parent ); 121 OPacket( int datalink, packetheaderstruct, const unsigned char*, QObject* parent );
120 virtual ~OPacket(); 122 virtual ~OPacket();
121 123
122 timevalstruct timeval() const; 124 timevalstruct timeval() const;
123 125
124 int caplen() const; 126 int caplen() const;
125 int len() const; 127 int len() const;
126 QString dump( int = 32 ) const; 128 QString dump( int = 32 ) const;
127 129
128 void updateStats( QMap<QString,int>&, QObjectList* ); 130 void updateStats( QMap<QString,int>&, QObjectList* );
129 131
130 private: 132 private:
131 const packetheaderstruct _hdr; // pcap packet header 133 const packetheaderstruct _hdr; // pcap packet header
132 const unsigned char* _data; // pcap packet data 134 const unsigned char* _data; // pcap packet data
133 const unsigned char* _end; // end of pcap packet data 135 const unsigned char* _end; // end of pcap packet data
@@ -511,69 +513,80 @@ class OTCPPacket : public QObject
511 * library libpcap. ... 513 * library libpcap. ...
512 */ 514 */
513class OPacketCapturer : public QObject 515class OPacketCapturer : public QObject
514{ 516{
515 Q_OBJECT 517 Q_OBJECT
516 518
517 public: 519 public:
518 /** 520 /**
519 * Constructor. 521 * Constructor.
520 */ 522 */
521 OPacketCapturer( QObject* parent = 0, const char* name = 0 ); 523 OPacketCapturer( QObject* parent = 0, const char* name = 0 );
522 /** 524 /**
523 * Destructor. 525 * Destructor.
524 */ 526 */
525 ~OPacketCapturer(); 527 ~OPacketCapturer();
526 /** 528 /**
527 * Setting the packet capturer to use blocking IO calls can be useful when 529 * Set the packet capturer to use blocking or non-blocking IO. This can be useful when
528 * not using the socket notifier, e.g. without an application object. 530 * not using the socket notifier, e.g. without an application object.
529 */ 531 */
530 void setBlocking( bool ); 532 void setBlocking( bool );
531 /** 533 /**
532 * @returns true if the packet capturer uses blocking IO calls. 534 * @returns true if the packet capturer uses blocking IO calls.
533 */ 535 */
534 bool blocking() const; 536 bool blocking() const;
535 /** 537 /**
536 * Closes the packet capturer. This is automatically done in the destructor. 538 * Close the packet capturer. This is automatically done in the destructor.
537 */ 539 */
538 void close(); 540 void close();
539 /** 541 /**
542 * Close the output capture file.
543 */
544 void closeDumpFile();
545 /**
540 * @returns the data link type. 546 * @returns the data link type.
541 * @see <pcap.h> for possible values. 547 * @see <pcap.h> for possible values.
542 */ 548 */
543 int dataLink() const; 549 int dataLink() const;
544 /** 550 /**
551 * Dump a packet to the output capture file.
552 */
553 void dump( OPacket* );
554 /**
545 * @returns the file descriptor of the packet capturer. This is only useful, if 555 * @returns the file descriptor of the packet capturer. This is only useful, if
546 * not using the socket notifier, e.g. without an application object. 556 * not using the socket notifier, e.g. without an application object.
547 */ 557 */
548 int fileno() const; 558 int fileno() const;
549 /** 559 /**
550 * @returns the next @ref OPacket from the packet capturer. 560 * @returns the next @ref OPacket from the packet capturer.
551 * @note If blocking mode is true then this call might block. 561 * @note If blocking mode is true then this call might block.
552 */ 562 */
553 OPacket* next(); 563 OPacket* next();
554 /** 564 /**
555 * Open the packet capturer to capture packets in live-mode from @a interface. 565 * Open the packet capturer to capture packets in live-mode from @a interface.
556 * If a @a filename is given, all captured packets are output to a tcpdump-compatible capture file.
557 */ 566 */
558 bool open( const QString& interface, const QString& filename = QString::null ); 567 bool open( const QString& interface );
559 /** 568 /**
560 * Open the packet capturer to capture packets in offline-mode from @a file. 569 * Open the packet capturer to capture packets in offline-mode from @a file.
561 */ 570 */
562 bool open( const QFile& file ); 571 bool open( const QFile& file );
563 /** 572 /**
573 * Open a prerecorded tcpdump compatible capture file for use with @ref dump()
574 */
575 bool openDumpFile( const QString& filename );
576 /**
564 * @returns true if the packet capturer is open 577 * @returns true if the packet capturer is open
565 */ 578 */
566 bool isOpen() const; 579 bool isOpen() const;
567 /** 580 /**
568 * @returns the snapshot length of this packet capturer 581 * @returns the snapshot length of this packet capturer
569 */ 582 */
570 int snapShot() const; 583 int snapShot() const;
571 /** 584 /**
572 * @returns true if the input capture file has a different byte-order 585 * @returns true if the input capture file has a different byte-order
573 * than the byte-order of the running system. 586 * than the byte-order of the running system.
574 */ 587 */
575 bool swapped() const; 588 bool swapped() const;
576 /** 589 /**
577 * @returns the libpcap version string used to write the input capture file. 590 * @returns the libpcap version string used to write the input capture file.
578 */ 591 */
579 QString version() const; 592 QString version() const;