summaryrefslogtreecommitdiff
path: root/libopie2
Unidiff
Diffstat (limited to 'libopie2') (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
@@ -771,304 +771,324 @@ OWaveLanDataPacket::~OWaveLanDataPacket()
771{ 771{
772} 772}
773 773
774 774
775/*====================================================================================== 775/*======================================================================================
776 * OLLCPacket 776 * OLLCPacket
777 *======================================================================================*/ 777 *======================================================================================*/
778 778
779OLLCPacket::OLLCPacket( const unsigned char* end, const struct ieee_802_11_802_2_header* data, QObject* parent ) 779OLLCPacket::OLLCPacket( const unsigned char* end, const struct ieee_802_11_802_2_header* data, QObject* parent )
780 :QObject( parent, "802.11 LLC" ), _header( data ) 780 :QObject( parent, "802.11 LLC" ), _header( data )
781{ 781{
782 qDebug( "OLLCPacket::OLLCPacket(): decoding frame..." ); 782 qDebug( "OLLCPacket::OLLCPacket(): decoding frame..." );
783 783
784 if ( !(_header->oui[0] || _header->oui[1] || _header->oui[2]) ) 784 if ( !(_header->oui[0] || _header->oui[1] || _header->oui[2]) )
785 { 785 {
786 qDebug( "OLLCPacket::OLLCPacket(): contains an encapsulated Ethernet frame (type=%04X)", EXTRACT_16BITS( &_header->type ) ); 786 qDebug( "OLLCPacket::OLLCPacket(): contains an encapsulated Ethernet frame (type=%04X)", EXTRACT_16BITS( &_header->type ) );
787 787
788 switch ( EXTRACT_16BITS( &_header->type ) ) // defined in linux/if_ether.h 788 switch ( EXTRACT_16BITS( &_header->type ) ) // defined in linux/if_ether.h
789 { 789 {
790 case ETH_P_IP: new OIPPacket( end, (const struct iphdr*) (data+1), this ); break; 790 case ETH_P_IP: new OIPPacket( end, (const struct iphdr*) (data+1), this ); break;
791 case ETH_P_ARP: new OARPPacket( end, (const struct myarphdr*) (data+1), this ); break; 791 case ETH_P_ARP: new OARPPacket( end, (const struct myarphdr*) (data+1), this ); break;
792 default: qWarning( "OLLCPacket::OLLCPacket(): Unknown Encapsulation (type=%04X)", EXTRACT_16BITS( &_header->type ) ); 792 default: qWarning( "OLLCPacket::OLLCPacket(): Unknown Encapsulation (type=%04X)", EXTRACT_16BITS( &_header->type ) );
793 } 793 }
794 794
795 } 795 }
796} 796}
797 797
798 798
799OLLCPacket::~OLLCPacket() 799OLLCPacket::~OLLCPacket()
800{ 800{
801} 801}
802 802
803 803
804/*====================================================================================== 804/*======================================================================================
805 * OWaveLanControlPacket 805 * OWaveLanControlPacket
806 *======================================================================================*/ 806 *======================================================================================*/
807 807
808OWaveLanControlPacket::OWaveLanControlPacket( const unsigned char* end, const struct ieee_802_11_control_header* data, OWaveLanPacket* parent ) 808OWaveLanControlPacket::OWaveLanControlPacket( const unsigned char* end, const struct ieee_802_11_control_header* data, OWaveLanPacket* parent )
809 :QObject( parent, "802.11 Control" ), _header( data ) 809 :QObject( parent, "802.11 Control" ), _header( data )
810{ 810{
811 qDebug( "OWaveLanControlPacket::OWaveLanDataControl(): decoding frame..." ); 811 qDebug( "OWaveLanControlPacket::OWaveLanDataControl(): decoding frame..." );
812 //TODO: Implement this 812 //TODO: Implement this
813} 813}
814 814
815 815
816OWaveLanControlPacket::~OWaveLanControlPacket() 816OWaveLanControlPacket::~OWaveLanControlPacket()
817{ 817{
818} 818}
819 819
820 820
821/*====================================================================================== 821/*======================================================================================
822 * OPacketCapturer 822 * OPacketCapturer
823 *======================================================================================*/ 823 *======================================================================================*/
824 824
825OPacketCapturer::OPacketCapturer( QObject* parent, const char* name ) 825OPacketCapturer::OPacketCapturer( QObject* parent, const char* name )
826 :QObject( parent, name ), _name( QString::null ), _open( false ), 826 :QObject( parent, name ), _name( QString::null ), _open( false ),
827 _pch( 0 ), _pcd( 0 ), _sn( 0 ) 827 _pch( 0 ), _pcd( 0 ), _sn( 0 )
828{ 828{
829} 829}
830 830
831 831
832OPacketCapturer::~OPacketCapturer() 832OPacketCapturer::~OPacketCapturer()
833{ 833{
834 if ( _open ) 834 if ( _open )
835 { 835 {
836 qDebug( "OPacketCapturer::~OPacketCapturer(): pcap still open, autoclosing." ); 836 qDebug( "OPacketCapturer::~OPacketCapturer(): pcap still open, autoclosing." );
837 close(); 837 close();
838 } 838 }
839} 839}
840 840
841 841
842void OPacketCapturer::setBlocking( bool b ) 842void OPacketCapturer::setBlocking( bool b )
843{ 843{
844 if ( pcap_setnonblock( _pch, 1-b, _errbuf ) != -1 ) 844 if ( pcap_setnonblock( _pch, 1-b, _errbuf ) != -1 )
845 { 845 {
846 qDebug( "OPacketCapturer::setBlocking(): blocking mode changed successfully." ); 846 qDebug( "OPacketCapturer::setBlocking(): blocking mode changed successfully." );
847 } 847 }
848 else 848 else
849 { 849 {
850 qDebug( "OPacketCapturer::setBlocking(): can't change blocking mode: %s", _errbuf ); 850 qDebug( "OPacketCapturer::setBlocking(): can't change blocking mode: %s", _errbuf );
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
958 pcap_t* handle = pcap_open_live( const_cast<char*>( (const char*) name ), 1024, 0, 0, &_errbuf[0] ); 973 pcap_t* handle = pcap_open_live( const_cast<char*>( (const char*) name ), 1024, 0, 0, &_errbuf[0] );
959 974
960 if ( !handle ) 975 if ( !handle )
961 { 976 {
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();
995 1015
996 if ( _open ) 1016 if ( _open )
997 { 1017 {
998 close(); 1018 close();
999 if ( name == _name ) // ignore opening an already openend device 1019 if ( name == _name ) // ignore opening an already openend device
1000 { 1020 {
1001 return true; 1021 return true;
1002 } 1022 }
1003 else // close the last opened device 1023 else // close the last opened device
1004 { 1024 {
1005 close(); 1025 close();
1006 } 1026 }
1007 } 1027 }
1008 1028
1009 _name = name; 1029 _name = name;
1010 1030
1011 pcap_t* handle = pcap_open_offline( const_cast<char*>( (const char*) name ), &_errbuf[0] ); 1031 pcap_t* handle = pcap_open_offline( const_cast<char*>( (const char*) name ), &_errbuf[0] );
1012 1032
1013 if ( handle ) 1033 if ( handle )
1014 { 1034 {
1015 qDebug( "OPacketCapturer::open(): libpcap opened successfully." ); 1035 qDebug( "OPacketCapturer::open(): libpcap opened successfully." );
1016 _pch = handle; 1036 _pch = handle;
1017 _open = true; 1037 _open = true;
1018 1038
1019 // in case we have an application object, create a socket notifier 1039 // in case we have an application object, create a socket notifier
1020 if ( qApp ) 1040 if ( qApp )
1021 { 1041 {
1022 _sn = new QSocketNotifier( fileno(), QSocketNotifier::Read ); 1042 _sn = new QSocketNotifier( fileno(), QSocketNotifier::Read );
1023 connect( _sn, SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) ); 1043 connect( _sn, SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) );
1024 } 1044 }
1025 1045
1026 return true; 1046 return true;
1027 } 1047 }
1028 else 1048 else
1029 { 1049 {
1030 qDebug( "OPacketCapturer::open(): can't open libpcap with '%s': %s", (const char*) name, _errbuf ); 1050 qDebug( "OPacketCapturer::open(): can't open libpcap with '%s': %s", (const char*) name, _errbuf );
1031 return false; 1051 return false;
1032 } 1052 }
1033 1053
1034} 1054}
1035 1055
1036 1056
1037bool OPacketCapturer::isOpen() const 1057bool OPacketCapturer::isOpen() const
1038{ 1058{
1039 return _open; 1059 return _open;
1040} 1060}
1041 1061
1042 1062
1043void OPacketCapturer::readyToReceive() 1063void OPacketCapturer::readyToReceive()
1044{ 1064{
1045 qDebug( "OPacketCapturer::readyToReceive(): about to emit 'receivePacket(p)'" ); 1065 qDebug( "OPacketCapturer::readyToReceive(): about to emit 'receivePacket(p)'" );
1046 OPacket* p = next(); 1066 OPacket* p = next();
1047 emit receivedPacket( p ); 1067 emit receivedPacket( p );
1048 // emit is synchronous - packet has been dealt with, now it's safe to delete 1068 // emit is synchronous - packet has been dealt with, now it's safe to delete
1049 delete p; 1069 delete p;
1050} 1070}
1051 1071
1052 1072
1053const QMap<QString,int>& OPacketCapturer::statistics() const 1073const QMap<QString,int>& OPacketCapturer::statistics() const
1054{ 1074{
1055 return _stats; 1075 return _stats;
1056} 1076}
1057 1077
1058 1078
1059int OPacketCapturer::snapShot() const 1079int OPacketCapturer::snapShot() const
1060{ 1080{
1061 return pcap_snapshot( _pch ); 1081 return pcap_snapshot( _pch );
1062} 1082}
1063 1083
1064 1084
1065bool OPacketCapturer::swapped() const 1085bool OPacketCapturer::swapped() const
1066{ 1086{
1067 return pcap_is_swapped( _pch ); 1087 return pcap_is_swapped( _pch );
1068} 1088}
1069 1089
1070 1090
1071QString OPacketCapturer::version() const 1091QString OPacketCapturer::version() const
1072{ 1092{
1073 return QString().sprintf( "%s.%s", pcap_major_version( _pch ), pcap_minor_version( _pch ) ); 1093 return QString().sprintf( "%s.%s", pcap_major_version( _pch ), pcap_minor_version( _pch ) );
1074} 1094}
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
@@ -22,192 +22,194 @@
22..}^=.=       =       ; Library General Public License for more 22..}^=.=       =       ; Library General Public License for more
23++=   -.     .`     .: details. 23++=   -.     .`     .: details.
24 :     =  ...= . :.=- 24 :     =  ...= . :.=-
25 -.   .:....=;==+<; You should have received a copy of the GNU 25 -.   .:....=;==+<; You should have received a copy of the GNU
26  -_. . .   )=.  = Library General Public License along with 26  -_. . .   )=.  = Library General Public License along with
27    --        :-=` this library; see the file COPYING.LIB. 27    --        :-=` this library; see the file COPYING.LIB.
28 If not, write to the Free Software Foundation, 28 If not, write to the Free Software Foundation,
29 Inc., 59 Temple Place - Suite 330, 29 Inc., 59 Temple Place - Suite 330,
30 Boston, MA 02111-1307, USA. 30 Boston, MA 02111-1307, USA.
31 31
32*/ 32*/
33 33
34#ifndef OPCAP_H 34#ifndef OPCAP_H
35#define OPCAP_H 35#define OPCAP_H
36 36
37/* LINUX */ 37/* LINUX */
38extern "C" // work around a bpf/pcap conflict in recent headers 38extern "C" // work around a bpf/pcap conflict in recent headers
39{ 39{
40 #include <pcap.h> 40 #include <pcap.h>
41} 41}
42#include <netinet/ether.h> 42#include <netinet/ether.h>
43#include <netinet/ip.h> 43#include <netinet/ip.h>
44#include <netinet/udp.h> 44#include <netinet/udp.h>
45#include <netinet/tcp.h> 45#include <netinet/tcp.h>
46#include <time.h> 46#include <time.h>
47 47
48/* QT */ 48/* QT */
49#include <qevent.h> 49#include <qevent.h>
50#include <qfile.h> 50#include <qfile.h>
51#include <qhostaddress.h> 51#include <qhostaddress.h>
52#include <qobject.h> 52#include <qobject.h>
53#include <qstring.h> 53#include <qstring.h>
54#include <qmap.h> 54#include <qmap.h>
55 55
56/* OPIE */ 56/* OPIE */
57#include <opie2/onetutils.h> 57#include <opie2/onetutils.h>
58#include "802_11_user.h" 58#include "802_11_user.h"
59 59
60/* TYPEDEFS */ 60/* TYPEDEFS */
61typedef struct timeval timevalstruct; 61typedef struct timeval timevalstruct;
62typedef struct pcap_pkthdr packetheaderstruct; 62typedef struct pcap_pkthdr packetheaderstruct;
63 63
64/* FORWARDS */ 64/* FORWARDS */
65class OPacketCapturer; 65class OPacketCapturer;
66class QSocketNotifier; 66class QSocketNotifier;
67 67
68/*====================================================================================== 68/*======================================================================================
69 * OPacket - A frame on the wire 69 * OPacket - A frame on the wire
70 *======================================================================================*/ 70 *======================================================================================*/
71 71
72/** @brief A class representing a data frame on the wire. 72/** @brief A class representing a data frame on the wire.
73 * 73 *
74 * The whole family of the packet classes are used when capturing frames from a network. 74 * The whole family of the packet classes are used when capturing frames from a network.
75 * Most standard network protocols in use share a common architecture, which mostly is 75 * Most standard network protocols in use share a common architecture, which mostly is
76 * a packet header and then the packet payload. In layered architectures, each lower layer 76 * a packet header and then the packet payload. In layered architectures, each lower layer
77 * encapsulates data from its upper layer - that is it 77 * encapsulates data from its upper layer - that is it
78 * treats the data from its upper layer as payload and prepends an own header to the packet, 78 * treats the data from its upper layer as payload and prepends an own header to the packet,
79 * which - again - is treated as the payload for the layer below. The figure below is an 79 * which - again - is treated as the payload for the layer below. The figure below is an
80 * example for how such a data frame is composed out of packets, e.g. when sending a mail. 80 * example for how such a data frame is composed out of packets, e.g. when sending a mail.
81 * 81 *
82 * <pre> 82 * <pre>
83 * | User Data | == Mail Data 83 * | User Data | == Mail Data
84 * | SMTP Header | User Data | == SMTP 84 * | SMTP Header | User Data | == SMTP
85 * | TCP Header | SMTP Header | User Data | == TCP 85 * | TCP Header | SMTP Header | User Data | == TCP
86 * | IP Header | TCP Header | SMTP Header | User Data | == IP 86 * | IP Header | TCP Header | SMTP Header | User Data | == IP
87 * | MAC Header | IP Header | TCP Header | SMTP Header | User Data | == MAC 87 * | MAC Header | IP Header | TCP Header | SMTP Header | User Data | == MAC
88 * 88 *
89 * </pre> 89 * </pre>
90 * 90 *
91 * The example is trimmed for simplicity, because the MAC (Medium Access Control) layer 91 * The example is trimmed for simplicity, because the MAC (Medium Access Control) layer
92 * also contains a few more levels of encapsulation. 92 * also contains a few more levels of encapsulation.
93 * Since the type of the payload is more or less independent from the encapsulating protocol, 93 * Since the type of the payload is more or less independent from the encapsulating protocol,
94 * the header must be inspected before attempting to decode the payload. Hence, the 94 * the header must be inspected before attempting to decode the payload. Hence, the
95 * encapsulation level varies and can't be deduced without actually looking into the packets. 95 * encapsulation level varies and can't be deduced without actually looking into the packets.
96 * 96 *
97 * For actually working with captured frames, it's useful to identify the packets via names and 97 * For actually working with captured frames, it's useful to identify the packets via names and
98 * insert them into a parent/child - relationship based on the encapsulation. This is why 98 * insert them into a parent/child - relationship based on the encapsulation. This is why
99 * all packet classes derive from QObject. The amount of overhead caused by the QObject is 99 * all packet classes derive from QObject. The amount of overhead caused by the QObject is
100 * not a problem in this case, because we're talking about a theoratical maximum of about 100 * not a problem in this case, because we're talking about a theoratical maximum of about
101 * 10 packets per captured frame. We need to stuff them into a searchable list anyway and the 101 * 10 packets per captured frame. We need to stuff them into a searchable list anyway and the
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
134}; 136};
135 137
136/*====================================================================================== 138/*======================================================================================
137 * OEthernetPacket - DLT_EN10MB frame 139 * OEthernetPacket - DLT_EN10MB frame
138 *======================================================================================*/ 140 *======================================================================================*/
139 141
140class OEthernetPacket : public QObject 142class OEthernetPacket : public QObject
141{ 143{
142 Q_OBJECT 144 Q_OBJECT
143 145
144 public: 146 public:
145 OEthernetPacket( const unsigned char*, const struct ether_header*, QObject* parent = 0 ); 147 OEthernetPacket( const unsigned char*, const struct ether_header*, QObject* parent = 0 );
146 virtual ~OEthernetPacket(); 148 virtual ~OEthernetPacket();
147 149
148 OMacAddress sourceAddress() const; 150 OMacAddress sourceAddress() const;
149 OMacAddress destinationAddress() const; 151 OMacAddress destinationAddress() const;
150 int type() const; 152 int type() const;
151 153
152 private: 154 private:
153 const struct ether_header* _ether; 155 const struct ether_header* _ether;
154}; 156};
155 157
156/*====================================================================================== 158/*======================================================================================
157 * OPrismHeaderPacket - DLT_PRISM_HEADER frame 159 * OPrismHeaderPacket - DLT_PRISM_HEADER frame
158 *======================================================================================*/ 160 *======================================================================================*/
159 161
160class OPrismHeaderPacket : public QObject 162class OPrismHeaderPacket : public QObject
161{ 163{
162 Q_OBJECT 164 Q_OBJECT
163 165
164 public: 166 public:
165 OPrismHeaderPacket( const unsigned char*, const struct prism_hdr*, QObject* parent = 0 ); 167 OPrismHeaderPacket( const unsigned char*, const struct prism_hdr*, QObject* parent = 0 );
166 virtual ~OPrismHeaderPacket(); 168 virtual ~OPrismHeaderPacket();
167 169
168 unsigned int signalStrength() const; 170 unsigned int signalStrength() const;
169 171
170 private: 172 private:
171 const struct prism_hdr* _header; 173 const struct prism_hdr* _header;
172}; 174};
173 175
174/*====================================================================================== 176/*======================================================================================
175 * OWaveLanPacket - DLT_IEEE802_11 frame 177 * OWaveLanPacket - DLT_IEEE802_11 frame
176 *======================================================================================*/ 178 *======================================================================================*/
177 179
178class OWaveLanPacket : public QObject 180class OWaveLanPacket : public QObject
179{ 181{
180 Q_OBJECT 182 Q_OBJECT
181 183
182 public: 184 public:
183 OWaveLanPacket( const unsigned char*, const struct ieee_802_11_header*, QObject* parent = 0 ); 185 OWaveLanPacket( const unsigned char*, const struct ieee_802_11_header*, QObject* parent = 0 );
184 virtual ~OWaveLanPacket(); 186 virtual ~OWaveLanPacket();
185 187
186 int duration() const; 188 int duration() const;
187 bool fromDS() const; 189 bool fromDS() const;
188 bool toDS() const; 190 bool toDS() const;
189 virtual OMacAddress macAddress1() const; 191 virtual OMacAddress macAddress1() const;
190 virtual OMacAddress macAddress2() const; 192 virtual OMacAddress macAddress2() const;
191 virtual OMacAddress macAddress3() const; 193 virtual OMacAddress macAddress3() const;
192 virtual OMacAddress macAddress4() const; 194 virtual OMacAddress macAddress4() const;
193 bool usesPowerManagement() const; 195 bool usesPowerManagement() const;
194 int type() const; 196 int type() const;
195 int subType() const; 197 int subType() const;
196 int version() const; 198 int version() const;
197 bool usesWep() const; 199 bool usesWep() const;
198 200
199 private: 201 private:
200 const struct ieee_802_11_header* _wlanhdr; 202 const struct ieee_802_11_header* _wlanhdr;
201}; 203};
202 204
203 205
204/*====================================================================================== 206/*======================================================================================
205 * OWaveLanManagementPacket - type: management (T_MGMT) 207 * OWaveLanManagementPacket - type: management (T_MGMT)
206 *======================================================================================*/ 208 *======================================================================================*/
207 209
208class OWaveLanManagementPacket : public QObject 210class OWaveLanManagementPacket : public QObject
209{ 211{
210 Q_OBJECT 212 Q_OBJECT
211 213
212 public: 214 public:
213 OWaveLanManagementPacket( const unsigned char*, const struct ieee_802_11_mgmt_header*, OWaveLanPacket* parent = 0 ); 215 OWaveLanManagementPacket( const unsigned char*, const struct ieee_802_11_mgmt_header*, OWaveLanPacket* parent = 0 );
@@ -431,176 +433,187 @@ class OIPPacket : public QObject
431 int offset() const; 433 int offset() const;
432 int ttl() const; 434 int ttl() const;
433 int protocol() const; 435 int protocol() const;
434 int checksum() const; 436 int checksum() const;
435 437
436 private: 438 private:
437 const struct iphdr* _iphdr; 439 const struct iphdr* _iphdr;
438}; 440};
439 441
440/*====================================================================================== 442/*======================================================================================
441 * OARPPacket 443 * OARPPacket
442 *======================================================================================*/ 444 *======================================================================================*/
443 445
444class OARPPacket : public QObject 446class OARPPacket : public QObject
445{ 447{
446 Q_OBJECT 448 Q_OBJECT
447 449
448 public: 450 public:
449 OARPPacket( const unsigned char*, const struct myarphdr*, QObject* parent = 0 ); 451 OARPPacket( const unsigned char*, const struct myarphdr*, QObject* parent = 0 );
450 virtual ~OARPPacket(); 452 virtual ~OARPPacket();
451 453
452 QHostAddress senderIPV4Address() const; 454 QHostAddress senderIPV4Address() const;
453 OMacAddress senderMacAddress() const; 455 OMacAddress senderMacAddress() const;
454 QHostAddress targetIPV4Address() const; 456 QHostAddress targetIPV4Address() const;
455 OMacAddress targetMacAddress() const; 457 OMacAddress targetMacAddress() const;
456 458
457 //int type() const; 459 //int type() const;
458 QString type() const; 460 QString type() const;
459 461
460 private: 462 private:
461 const struct myarphdr* _arphdr; 463 const struct myarphdr* _arphdr;
462}; 464};
463 465
464/*====================================================================================== 466/*======================================================================================
465 * OUDPPacket 467 * OUDPPacket
466 *======================================================================================*/ 468 *======================================================================================*/
467 469
468class OUDPPacket : public QObject 470class OUDPPacket : public QObject
469{ 471{
470 Q_OBJECT 472 Q_OBJECT
471 473
472 public: 474 public:
473 OUDPPacket( const unsigned char*, const struct udphdr*, QObject* parent = 0 ); 475 OUDPPacket( const unsigned char*, const struct udphdr*, QObject* parent = 0 );
474 virtual ~OUDPPacket(); 476 virtual ~OUDPPacket();
475 477
476 int fromPort() const; 478 int fromPort() const;
477 int toPort() const; 479 int toPort() const;
478 480
479 private: 481 private:
480 const struct udphdr* _udphdr; 482 const struct udphdr* _udphdr;
481}; 483};
482 484
483/*====================================================================================== 485/*======================================================================================
484 * OTCPPacket 486 * OTCPPacket
485 *======================================================================================*/ 487 *======================================================================================*/
486 488
487class OTCPPacket : public QObject 489class OTCPPacket : public QObject
488{ 490{
489 Q_OBJECT 491 Q_OBJECT
490 492
491 public: 493 public:
492 OTCPPacket( const unsigned char*, const struct tcphdr*, QObject* parent = 0 ); 494 OTCPPacket( const unsigned char*, const struct tcphdr*, QObject* parent = 0 );
493 virtual ~OTCPPacket(); 495 virtual ~OTCPPacket();
494 496
495 int fromPort() const; 497 int fromPort() const;
496 int toPort() const; 498 int toPort() const;
497 499
498 private: 500 private:
499 const struct tcphdr* _tcphdr; 501 const struct tcphdr* _tcphdr;
500}; 502};
501 503
502 504
503/*====================================================================================== 505/*======================================================================================
504 * OPacketCapturer 506 * OPacketCapturer
505 *======================================================================================*/ 507 *======================================================================================*/
506 508
507/** 509/**
508 * @brief A class based wrapper for network packet capturing. 510 * @brief A class based wrapper for network packet capturing.
509 * 511 *
510 * This class is the base of a high-level interface to the well known packet capturing 512 * This class is the base of a high-level interface to the well known packet capturing
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;
580 /** 593 /**
581 * @returns the packet statistic database. 594 * @returns the packet statistic database.
582 * @see QMap 595 * @see QMap
583 */ 596 */
584 const QMap<QString,int>& statistics() const; 597 const QMap<QString,int>& statistics() const;
585 598
586 signals: 599 signals:
587 /** 600 /**
588 * This signal is emitted, when a packet has been received. 601 * This signal is emitted, when a packet has been received.
589 */ 602 */
590 void receivedPacket( OPacket* ); 603 void receivedPacket( OPacket* );
591 604
592 protected slots: 605 protected slots:
593 void readyToReceive(); 606 void readyToReceive();
594 607
595 protected: 608 protected:
596 QString _name; // devicename 609 QString _name; // devicename
597 bool _open; // check this before doing pcap calls 610 bool _open; // check this before doing pcap calls
598 pcap_t* _pch; // pcap library handle 611 pcap_t* _pch; // pcap library handle
599 pcap_dumper_t* _pcd; // pcap dumper handle 612 pcap_dumper_t* _pcd; // pcap dumper handle
600 QSocketNotifier* _sn; // socket notifier for main loop 613 QSocketNotifier* _sn; // socket notifier for main loop
601 mutable char _errbuf[PCAP_ERRBUF_SIZE]; // holds error strings from libpcap 614 mutable char _errbuf[PCAP_ERRBUF_SIZE]; // holds error strings from libpcap
602 QMap<QString, int> _stats; // statistics; 615 QMap<QString, int> _stats; // statistics;
603}; 616};
604 617
605#endif // OPCAP_H 618#endif // OPCAP_H
606 619