summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opienet/opcap.cpp21
-rw-r--r--libopie2/opienet/opcap.h35
2 files changed, 32 insertions, 24 deletions
diff --git a/libopie2/opienet/opcap.cpp b/libopie2/opienet/opcap.cpp
index 7463320..fdd519c 100644
--- a/libopie2/opienet/opcap.cpp
+++ b/libopie2/opienet/opcap.cpp
@@ -81,133 +81,138 @@ OPacket::OPacket( int datalink, packetheaderstruct header, const unsigned char*
81 81
82 82
83OPacket::~OPacket() 83OPacket::~OPacket()
84{ 84{
85} 85}
86 86
87 87
88timevalstruct OPacket::timeval() const 88timevalstruct OPacket::timeval() const
89{ 89{
90 return _hdr.ts; 90 return _hdr.ts;
91} 91}
92 92
93 93
94int OPacket::caplen() const 94int OPacket::caplen() const
95{ 95{
96 return _hdr.caplen; 96 return _hdr.caplen;
97} 97}
98 98
99 99
100void OPacket::updateStats( QMap<QString,int>& stats, QObjectList* l ) 100void OPacket::updateStats( QMap<QString,int>& stats, QObjectList* l )
101{ 101{
102 if (!l) return; 102 if (!l) return;
103 QObject* o = l->first(); 103 QObject* o = l->first();
104 while ( o ) 104 while ( o )
105 { 105 {
106 stats[o->name()]++; 106 stats[o->name()]++;
107 updateStats( stats, const_cast<QObjectList*>( o->children() ) ); 107 updateStats( stats, const_cast<QObjectList*>( o->children() ) );
108 o = l->next(); 108 o = l->next();
109 } 109 }
110} 110}
111 111
112 112
113void OPacket::dumpStructure( QObjectList* l ) 113QString OPacket::dumpStructure() const
114{ 114{
115 QString packetString( "[ |" + _dumpStructure( l ) + " ]" ); 115 return "[ |" + _dumpStructure( const_cast<QObjectList*>( this->children() ) ) + " ]";
116 odebug << "OPacket::dumpStructure: " << packetString << oendl;
117} 116}
118 117
119 118
120QString OPacket::_dumpStructure( QObjectList* l ) 119QString OPacket::_dumpStructure( QObjectList* l ) const
121{ 120{
122 if (!l) return QString::null; 121 if (!l) return QString::null;
123 QObject* o = l->first(); 122 QObject* o = l->first();
124 QString str(" "); 123 QString str(" ");
125 124
126 while ( o ) 125 while ( o )
127 { 126 {
128 str.append( o->name() ); 127 str.append( o->name() );
129 str.append( " |" ); 128 str.append( " |" );
130 str += _dumpStructure( const_cast<QObjectList*>( o->children() ) ); 129 str += _dumpStructure( const_cast<QObjectList*>( o->children() ) );
131 o = l->next(); 130 o = l->next();
132 } 131 }
133 return str; 132 return str;
134} 133}
135 134
136QString OPacket::dump( int bpl ) const 135QString OPacket::dump( int bpl ) const
137{ 136{
138 static int index = 0; 137 static int index = 0;
139 index++; 138 index++;
140 int len = _hdr.caplen; 139 int len = _hdr.caplen;
141 QString str; 140 QString str;
142 str.sprintf( "\n<----- Packet #%04d Len = 0x%X (%d) ----->\n\n", index, len, len ); 141 str.sprintf( "\n<----- Packet #%04d Len = 0x%X (%d) ----->\n\n", index, len, len );
143 str.append( "0000: " ); 142 str.append( "0000: " );
144 QString tmp; 143 QString tmp;
145 QString bytes; 144 QString bytes;
146 QString chars; 145 QString chars;
147 146
148 for ( int i = 0; i < len; ++i ) 147 for ( int i = 0; i < len; ++i )
149 { 148 {
150 tmp.sprintf( "%02X ", _data[i] ); bytes.append( tmp ); 149 tmp.sprintf( "%02X ", _data[i] ); bytes.append( tmp );
151 if ( (_data[i] > 31) && (_data[i]<128) ) chars.append( _data[i] ); 150 if ( (_data[i] > 31) && (_data[i]<128) ) chars.append( _data[i] );
152 else chars.append( '.' ); 151 else chars.append( '.' );
153 152
154 if ( !((i+1) % bpl) ) 153 if ( !((i+1) % bpl) )
155 { 154 {
156 str.append( bytes ); 155 str.append( bytes );
157 str.append( ' ' ); 156 str.append( ' ' );
158 str.append( chars ); 157 str.append( chars );
159 str.append( '\n' ); 158 str.append( '\n' );
160 tmp.sprintf( "%04X: ", i+1 ); str.append( tmp ); 159 tmp.sprintf( "%04X: ", i+1 ); str.append( tmp );
161 bytes = ""; 160 bytes = "";
162 chars = ""; 161 chars = "";
163 } 162 }
164 163
165 } 164 }
166 if ( (len % bpl) ) 165 if ( (len % bpl) )
167 { 166 {
168 str.append( bytes.leftJustify( 1 + 3*bpl ) ); 167 str.append( bytes.leftJustify( 1 + 3*bpl ) );
169 str.append( chars ); 168 str.append( chars );
170 } 169 }
171 str.append( '\n' ); 170 str.append( '\n' );
172 return str; 171 return str;
173} 172}
174 173
175 174
176int OPacket::len() const 175int OPacket::len() const
177{ 176{
178 return _hdr.len; 177 return _hdr.len;
179} 178}
180 179
181 180
181QTextStream& operator<<( QTextStream& s, const OPacket& p )
182{
183 s << p.dumpStructure();
184}
185
186
182/*====================================================================================== 187/*======================================================================================
183 * OEthernetPacket 188 * OEthernetPacket
184 *======================================================================================*/ 189 *======================================================================================*/
185 190
186OEthernetPacket::OEthernetPacket( const unsigned char* end, const struct ether_header* data, QObject* parent ) 191OEthernetPacket::OEthernetPacket( const unsigned char* end, const struct ether_header* data, QObject* parent )
187 :QObject( parent, "Ethernet" ), _ether( data ) 192 :QObject( parent, "Ethernet" ), _ether( data )
188{ 193{
189 194
190 odebug << "Source = " << sourceAddress().toString(); 195 odebug << "Source = " << sourceAddress().toString();
191 odebug << "Destination = " << destinationAddress().toString(); 196 odebug << "Destination = " << destinationAddress().toString();
192 197
193 if ( sourceAddress() == OMacAddress::broadcast ) 198 if ( sourceAddress() == OMacAddress::broadcast )
194 odebug << "Source is broadcast address" << oendl; 199 odebug << "Source is broadcast address" << oendl;
195 if ( destinationAddress() == OMacAddress::broadcast ) 200 if ( destinationAddress() == OMacAddress::broadcast )
196 odebug << "Destination is broadcast address" << oendl; 201 odebug << "Destination is broadcast address" << oendl;
197 202
198 switch ( type() ) 203 switch ( type() )
199 { 204 {
200 case ETHERTYPE_IP: new OIPPacket( end, (const struct iphdr*) (data+1), this ); break; 205 case ETHERTYPE_IP: new OIPPacket( end, (const struct iphdr*) (data+1), this ); break;
201 case ETHERTYPE_ARP: new OARPPacket( end, (const struct myarphdr*) (data+1), this ); break; 206 case ETHERTYPE_ARP: new OARPPacket( end, (const struct myarphdr*) (data+1), this ); break;
202 case ETHERTYPE_REVARP: { odebug << "OPacket::OPacket(): Received Ethernet Packet : Type = RARP" << oendl; break; } 207 case ETHERTYPE_REVARP: { odebug << "OPacket::OPacket(): Received Ethernet Packet : Type = RARP" << oendl; break; }
203 default: odebug << "OPacket::OPacket(): Received Ethernet Packet : Type = UNKNOWN" << oendl; 208 default: odebug << "OPacket::OPacket(): Received Ethernet Packet : Type = UNKNOWN" << oendl;
204 } 209 }
205 210
206} 211}
207 212
208 213
209OEthernetPacket::~OEthernetPacket() 214OEthernetPacket::~OEthernetPacket()
210{ 215{
211} 216}
212 217
213 218
@@ -700,65 +705,65 @@ bool OWaveLanPacket::toDS() const
700 return FC_TO_DS( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) ); 705 return FC_TO_DS( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) );
701} 706}
702 707
703 708
704bool OWaveLanPacket::usesPowerManagement() const 709bool OWaveLanPacket::usesPowerManagement() const
705{ 710{
706 return FC_POWER_MGMT( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) ); 711 return FC_POWER_MGMT( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) );
707} 712}
708 713
709 714
710bool OWaveLanPacket::usesWep() const 715bool OWaveLanPacket::usesWep() const
711{ 716{
712 return FC_WEP( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) ); 717 return FC_WEP( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) );
713} 718}
714 719
715 720
716/*====================================================================================== 721/*======================================================================================
717 * OWaveLanManagementPacket 722 * OWaveLanManagementPacket
718 *======================================================================================*/ 723 *======================================================================================*/
719 724
720OWaveLanManagementPacket::OWaveLanManagementPacket( const unsigned char* end, const struct ieee_802_11_mgmt_header* data, OWaveLanPacket* parent ) 725OWaveLanManagementPacket::OWaveLanManagementPacket( const unsigned char* end, const struct ieee_802_11_mgmt_header* data, OWaveLanPacket* parent )
721 :QObject( parent, "802.11 Management" ), _header( data ), 726 :QObject( parent, "802.11 Management" ), _header( data ),
722 _body( (const struct ieee_802_11_mgmt_body*) (data+1) ) 727 _body( (const struct ieee_802_11_mgmt_body*) (data+1) )
723{ 728{
724 odebug << "OWaveLanManagementPacket::OWaveLanManagementPacket(): decoding frame..." << oendl; 729 odebug << "OWaveLanManagementPacket::OWaveLanManagementPacket(): decoding frame..." << oendl;
725 odebug << "Detected subtype is " << managementType() << oendl; 730 odebug << "Detected subtype is " << managementType() << oendl;
726 731
727 // Grab tagged values. 732 // Grab tagged values.
728 // Beacons contain a 12 byte long fixed parameters set before the tagged parameters come, 733 // Beacons contain a 12 byte long fixed parameters set before the tagged parameters come,
729 // Other management frames don't - which is why we have to inspect the subtype here. 734 // Other management frames don't - which is why we have to inspect the subtype here.
730 735
731 const unsigned char* ptr = managementType() == "Beacon" ? (const unsigned char*) (_body+1) : (const unsigned char*) (_header+1); 736 const unsigned char* ptr = managementType() == "Beacon" ? (const unsigned char*) (_body+1) : (const unsigned char*) (_header+1);
732 737
733 while (ptr < end) 738 while (ptr < end)
734 { 739 {
735 switch ( *ptr ) 740 switch ( *ptr )
736 { 741 {
737 case E_SSID: new OWaveLanManagementSSID( end, (struct ssid_t*) ptr, this ); break; 742 case E_SSID: new OWaveLanManagementSSID( end, (struct ssid_t*) ptr, this ); break;
738 case E_FH: new OWaveLanManagementFH( end, (struct fh_t*) ptr, this ); break; 743 case E_FH: new OWaveLanManagementFH( end, (struct fh_t*) ptr, this ); break;
739 case E_DS: new OWaveLanManagementDS( end, (struct ds_t*) ptr, this ); break; 744 case E_DS: new OWaveLanManagementDS( end, (struct ds_t*) ptr, this ); break;
740 case E_RATES: new OWaveLanManagementRates( end, (struct rates_t*) ptr, this ); break; 745 case E_RATES: new OWaveLanManagementRates( end, (struct rates_t*) ptr, this ); break;
741 case E_CF: new OWaveLanManagementCF( end, (struct cf_t*) ptr, this ); break; 746 case E_CF: new OWaveLanManagementCF( end, (struct cf_t*) ptr, this ); break;
742 case E_TIM: new OWaveLanManagementTim( end, (struct tim_t*) ptr, this ); break; 747 case E_TIM: new OWaveLanManagementTim( end, (struct tim_t*) ptr, this ); break;
743 case E_IBSS: new OWaveLanManagementIBSS( end, (struct ibss_t*) ptr, this ); break; 748 case E_IBSS: new OWaveLanManagementIBSS( end, (struct ibss_t*) ptr, this ); break;
744 case E_CHALLENGE: new OWaveLanManagementChallenge( end, (struct challenge_t*) ptr, this ); break; 749 case E_CHALLENGE: new OWaveLanManagementChallenge( end, (struct challenge_t*) ptr, this ); break;
745 } 750 }
746 ptr+= ( ( struct ssid_t* ) ptr )->length; // skip length of tagged value 751 ptr+= ( ( struct ssid_t* ) ptr )->length; // skip length of tagged value
747 ptr+= 2; // skip tag ID and length 752 ptr+= 2; // skip tag ID and length
748 } 753 }
749} 754}
750 755
751 756
752OWaveLanManagementPacket::~OWaveLanManagementPacket() 757OWaveLanManagementPacket::~OWaveLanManagementPacket()
753{ 758{
754} 759}
755 760
756 761
757QString OWaveLanManagementPacket::managementType() const 762QString OWaveLanManagementPacket::managementType() const
758{ 763{
759 switch ( FC_SUBTYPE( EXTRACT_LE_16BITS( &_header->fc ) ) ) 764 switch ( FC_SUBTYPE( EXTRACT_LE_16BITS( &_header->fc ) ) )
760 { 765 {
761 case ST_ASSOC_REQUEST: return "AssociationRequest"; break; 766 case ST_ASSOC_REQUEST: return "AssociationRequest"; break;
762 case ST_ASSOC_RESPONSE: return "AssociationResponse"; break; 767 case ST_ASSOC_RESPONSE: return "AssociationResponse"; break;
763 case ST_REASSOC_REQUEST: return "ReassociationRequest"; break; 768 case ST_REASSOC_REQUEST: return "ReassociationRequest"; break;
764 case ST_REASSOC_RESPONSE: return "ReassociationResponse"; break; 769 case ST_REASSOC_RESPONSE: return "ReassociationResponse"; break;
@@ -1159,67 +1164,65 @@ int OPacketCapturer::fileno() const
1159OPacket* OPacketCapturer::next( int time ) 1164OPacket* OPacketCapturer::next( int time )
1160{ 1165{
1161 fd_set fds; 1166 fd_set fds;
1162 struct timeval tv; 1167 struct timeval tv;
1163 FD_ZERO( &fds ); 1168 FD_ZERO( &fds );
1164 FD_SET( pcap_fileno( _pch ), &fds ); 1169 FD_SET( pcap_fileno( _pch ), &fds );
1165 tv.tv_sec = time / 1000; 1170 tv.tv_sec = time / 1000;
1166 tv.tv_usec = time % 1000; 1171 tv.tv_usec = time % 1000;
1167 int retval = select( pcap_fileno( _pch )+1, &fds, NULL, NULL, &tv); 1172 int retval = select( pcap_fileno( _pch )+1, &fds, NULL, NULL, &tv);
1168 if ( retval > 0 ) // clear to read! 1173 if ( retval > 0 ) // clear to read!
1169 return next(); 1174 return next();
1170 else 1175 else
1171 return 0; 1176 return 0;
1172} 1177}
1173 1178
1174 1179
1175OPacket* OPacketCapturer::next() 1180OPacket* OPacketCapturer::next()
1176{ 1181{
1177 packetheaderstruct header; 1182 packetheaderstruct header;
1178 odebug << "==> OPacketCapturer::next()" << oendl; 1183 odebug << "==> OPacketCapturer::next()" << oendl;
1179 const unsigned char* pdata = pcap_next( _pch, &header ); 1184 const unsigned char* pdata = pcap_next( _pch, &header );
1180 odebug << "<== OPacketCapturer::next()" << oendl; 1185 odebug << "<== OPacketCapturer::next()" << oendl;
1181 1186
1182 if ( pdata && header.len ) 1187 if ( pdata && header.len )
1183 { 1188 {
1184 OPacket* p = new OPacket( dataLink(), header, pdata, 0 ); 1189 OPacket* p = new OPacket( dataLink(), header, pdata, 0 );
1185 // packets shouldn't be inserted in the QObject child-parent hierarchy, 1190 // packets shouldn't be inserted in the QObject child-parent hierarchy,
1186 // because due to memory constraints they will be deleted as soon 1191 // because due to memory constraints they will be deleted as soon
1187 // as possible - that is right after they have been processed 1192 // as possible - that is right after they have been processed
1188 // by emit() [ see below ] 1193 // by emit() [ see below ]
1189 //TODO: make gathering statistics optional, because it takes time 1194 //TODO: make gathering statistics optional, because it takes time
1190 p->updateStats( _stats, const_cast<QObjectList*>( p->children() ) ); 1195 p->updateStats( _stats, const_cast<QObjectList*>( p->children() ) );
1191 #ifndef NODEBUG 1196 odebug << "OPacket::dumpStructure: " << p->dumpStructure() << oendl;
1192 p->dumpStructure( const_cast<QObjectList*>( p->children() ) );
1193 #endif
1194 return p; 1197 return p;
1195 } 1198 }
1196 else 1199 else
1197 { 1200 {
1198 owarn << "OPacketCapturer::next() - no packet received!" << oendl; 1201 owarn << "OPacketCapturer::next() - no packet received!" << oendl;
1199 return 0; 1202 return 0;
1200 } 1203 }
1201} 1204}
1202 1205
1203 1206
1204bool OPacketCapturer::open( const QString& name ) 1207bool OPacketCapturer::open( const QString& name )
1205{ 1208{
1206 if ( _open ) 1209 if ( _open )
1207 { 1210 {
1208 if ( name == _name ) // ignore opening an already openend device 1211 if ( name == _name ) // ignore opening an already openend device
1209 { 1212 {
1210 return true; 1213 return true;
1211 } 1214 }
1212 else // close the last opened device 1215 else // close the last opened device
1213 { 1216 {
1214 close(); 1217 close();
1215 } 1218 }
1216 } 1219 }
1217 1220
1218 _name = name; 1221 _name = name;
1219 1222
1220 // open libpcap 1223 // open libpcap
1221 pcap_t* handle = pcap_open_live( const_cast<char*>( (const char*) name ), 1024, 0, 0, &_errbuf[0] ); 1224 pcap_t* handle = pcap_open_live( const_cast<char*>( (const char*) name ), 1024, 0, 0, &_errbuf[0] );
1222 1225
1223 if ( !handle ) 1226 if ( !handle )
1224 { 1227 {
1225 owarn << "OPacketCapturer::open(): can't open libpcap with '" << name << "': " << _errbuf << oendl; 1228 owarn << "OPacketCapturer::open(): can't open libpcap with '" << name << "': " << _errbuf << oendl;
@@ -1309,36 +1312,36 @@ bool OPacketCapturer::isOpen() const
1309 1312
1310 1313
1311void OPacketCapturer::readyToReceive() 1314void OPacketCapturer::readyToReceive()
1312{ 1315{
1313 odebug << "OPacketCapturer::readyToReceive(): about to emit 'receivePacket(p)'" << oendl; 1316 odebug << "OPacketCapturer::readyToReceive(): about to emit 'receivePacket(p)'" << oendl;
1314 OPacket* p = next(); 1317 OPacket* p = next();
1315 emit receivedPacket( p ); 1318 emit receivedPacket( p );
1316 // emit is synchronous - packet has been dealt with, now it's safe to delete 1319 // emit is synchronous - packet has been dealt with, now it's safe to delete
1317 delete p; 1320 delete p;
1318} 1321}
1319 1322
1320 1323
1321const QMap<QString,int>& OPacketCapturer::statistics() const 1324const QMap<QString,int>& OPacketCapturer::statistics() const
1322{ 1325{
1323 return _stats; 1326 return _stats;
1324} 1327}
1325 1328
1326 1329
1327int OPacketCapturer::snapShot() const 1330int OPacketCapturer::snapShot() const
1328{ 1331{
1329 return pcap_snapshot( _pch ); 1332 return pcap_snapshot( _pch );
1330} 1333}
1331 1334
1332 1335
1333bool OPacketCapturer::swapped() const 1336bool OPacketCapturer::swapped() const
1334{ 1337{
1335 return pcap_is_swapped( _pch ); 1338 return pcap_is_swapped( _pch );
1336} 1339}
1337 1340
1338 1341
1339QString OPacketCapturer::version() const 1342QString OPacketCapturer::version() const
1340{ 1343{
1341 return QString().sprintf( "%s.%s", pcap_major_version( _pch ), pcap_minor_version( _pch ) ); 1344 return QString().sprintf( "%d.%d", pcap_major_version( _pch ), pcap_minor_version( _pch ) );
1342} 1345}
1343 1346
1344 1347
diff --git a/libopie2/opienet/opcap.h b/libopie2/opienet/opcap.h
index f5dc5c0..b873b49 100644
--- a/libopie2/opienet/opcap.h
+++ b/libopie2/opienet/opcap.h
@@ -2,173 +2,178 @@
2                 This file is part of the Opie Project 2                 This file is part of the Opie Project
3              Copyright (C) 2003 by Michael 'Mickey' Lauer <mickey@Vanille.de> 3              Copyright (C) 2003 by Michael 'Mickey' Lauer <mickey@Vanille.de>
4 =. 4 =.
5 .=l. 5 .=l.
6           .>+-= 6           .>+-=
7 _;:,     .>    :=|. This program is free software; you can 7 _;:,     .>    :=|. This program is free software; you can
8.> <`_,   >  .   <= redistribute it and/or modify it under 8.> <`_,   >  .   <= redistribute it and/or modify it under
9:`=1 )Y*s>-.--   : the terms of the GNU Library General Public 9:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
10.="- .-=="i,     .._ License as published by the Free Software 10.="- .-=="i,     .._ License as published by the Free Software
11 - .   .-<_>     .<> Foundation; either version 2 of the License, 11 - .   .-<_>     .<> Foundation; either version 2 of the License,
12     ._= =}       : or (at your option) any later version. 12     ._= =}       : or (at your option) any later version.
13    .%`+i>       _;_. 13    .%`+i>       _;_.
14    .i_,=:_.      -<s. This program is distributed in the hope that 14    .i_,=:_.      -<s. This program is distributed in the hope that
15     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY; 15     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
16    : ..    .:,     . . . without even the implied warranty of 16    : ..    .:,     . . . without even the implied warranty of
17    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A 17    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
18  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU 18  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.=       =       ; Library General Public License for more 19..}^=.=       =       ; Library General Public License for more
20++=   -.     .`     .: details. 20++=   -.     .`     .: details.
21 :     =  ...= . :.=- 21 :     =  ...= . :.=-
22 -.   .:....=;==+<; You should have received a copy of the GNU 22 -.   .:....=;==+<; You should have received a copy of the GNU
23  -_. . .   )=.  = Library General Public License along with 23  -_. . .   )=.  = Library General Public License along with
24    --        :-=` this library; see the file COPYING.LIB. 24    --        :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28 28
29*/ 29*/
30 30
31#ifndef OPCAP_H 31#ifndef OPCAP_H
32#define OPCAP_H 32#define OPCAP_H
33 33
34/* LINUX */ 34/* OPIE */
35extern "C" // work around a bpf/pcap conflict in recent headers 35#include <opie2/onetutils.h>
36{
37 #include <pcap.h>
38}
39#include <netinet/ether.h>
40#include <netinet/ip.h>
41#include <netinet/udp.h>
42#include <netinet/tcp.h>
43#include <time.h>
44 36
45/* QT */ 37/* QT */
46#include <qevent.h> 38#include <qevent.h>
47#include <qfile.h> 39#include <qfile.h>
48#include <qhostaddress.h> 40#include <qhostaddress.h>
49#include <qobject.h> 41#include <qobject.h>
50#include <qstring.h> 42#include <qstring.h>
43#include <qtextstream.h>
51#include <qmap.h> 44#include <qmap.h>
52 45
53/* OPIE */ 46/* STD */
54#include <opie2/onetutils.h> 47extern "C" // work around a bpf/pcap conflict in recent headers
48{
49 #include <pcap.h>
50}
51#include <netinet/ether.h>
52#include <netinet/ip.h>
53#include <netinet/udp.h>
54#include <netinet/tcp.h>
55#include <time.h>
55 56
56/* Custom Network Includes */ 57/* Custom Network Includes (must go here, don't reorder!) */
57#include "802_11_user.h" 58#include "802_11_user.h"
58#include "dhcp.h" 59#include "dhcp.h"
59 60
61
60/* TYPEDEFS */ 62/* TYPEDEFS */
61typedef struct timeval timevalstruct; 63typedef struct timeval timevalstruct;
62typedef struct pcap_pkthdr packetheaderstruct; 64typedef struct pcap_pkthdr packetheaderstruct;
63 65
64/* FORWARDS */ 66/* FORWARDS */
65class OPacketCapturer; 67class OPacketCapturer;
66class QSocketNotifier; 68class QSocketNotifier;
67 69
68/*====================================================================================== 70/*======================================================================================
69 * OPacket - A frame on the wire 71 * OPacket - A frame on the wire
70 *======================================================================================*/ 72 *======================================================================================*/
71 73
72/** @brief A class representing a data frame on the wire. 74/** @brief A class representing a data frame on the wire.
73 * 75 *
74 * The whole family of the packet classes are used when capturing frames from a network. 76 * 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 77 * 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 78 * a packet header and then the packet payload. In layered architectures, each lower layer
77 * encapsulates data from its upper layer - that is it 79 * 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, 80 * 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 81 * 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. 82 * example for how such a data frame is composed out of packets, e.g. when sending a mail.
81 * 83 *
82 * <pre> 84 * <pre>
83 * | User Data | == Mail Data 85 * | User Data | == Mail Data
84 * | SMTP Header | User Data | == SMTP 86 * | SMTP Header | User Data | == SMTP
85 * | TCP Header | SMTP Header | User Data | == TCP 87 * | TCP Header | SMTP Header | User Data | == TCP
86 * | IP Header | TCP Header | SMTP Header | User Data | == IP 88 * | IP Header | TCP Header | SMTP Header | User Data | == IP
87 * | MAC Header | IP Header | TCP Header | SMTP Header | User Data | == MAC 89 * | MAC Header | IP Header | TCP Header | SMTP Header | User Data | == MAC
88 * 90 *
89 * </pre> 91 * </pre>
90 * 92 *
91 * The example is trimmed for simplicity, because the MAC (Medium Access Control) layer 93 * The example is trimmed for simplicity, because the MAC (Medium Access Control) layer
92 * also contains a few more levels of encapsulation. 94 * also contains a few more levels of encapsulation.
93 * Since the type of the payload is more or less independent from the encapsulating protocol, 95 * 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 96 * 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. 97 * encapsulation level varies and can't be deduced without actually looking into the packets.
96 * 98 *
97 * For actually working with captured frames, it's useful to identify the packets via names and 99 * 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 100 * 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 101 * 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 102 * 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 103 * 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. 104 * QObject also cares about destroying the sub-, (child-) packets.
103 * 105 *
104 * This enables us to perform a simple look for packets of a certain type: 106 * This enables us to perform a simple look for packets of a certain type:
105 * @code 107 * @code
106 * OPacketCapturer* pcap = new OPacketCapturer(); 108 * OPacketCapturer* pcap = new OPacketCapturer();
107 * pcap->open( "eth0" ); 109 * pcap->open( "eth0" );
108 * OPacket* p = pcap->next(); 110 * OPacket* p = pcap->next();
109 * OIPPacket* ip = (OIPPacket*) p->child( "IP" ); // returns 0, if no such child exists 111 * 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; 112 * odebug << "got ip packet from " << ip->fromIPAddress().toString() << " to " << ip->toIPAddress().toString() << oendl;
111 * 113 *
112 */ 114 */
113 115
114class OPacket : public QObject 116class OPacket : public QObject
115{ 117{
116 Q_OBJECT 118 Q_OBJECT
117 119
118 friend class OPacketCapturer; 120 friend class OPacketCapturer;
121 friend QTextStream& operator<<( QTextStream& s, const OPacket& p );
119 122
120 public: 123 public:
121 OPacket( int datalink, packetheaderstruct, const unsigned char*, QObject* parent ); 124 OPacket( int datalink, packetheaderstruct, const unsigned char*, QObject* parent );
122 virtual ~OPacket(); 125 virtual ~OPacket();
123 126
124 timevalstruct timeval() const; 127 timevalstruct timeval() const;
125 128
126 int caplen() const; 129 int caplen() const;
127 int len() const; 130 int len() const;
128 QString dump( int = 32 ) const; 131 QString dump( int = 32 ) const;
129 132
130 void updateStats( QMap<QString,int>&, QObjectList* ); 133 void updateStats( QMap<QString,int>&, QObjectList* );
131 134
132 private: 135 private:
133 136
134 void dumpStructure( QObjectList* ); 137 QString dumpStructure() const;
135 QString _dumpStructure( QObjectList* ); 138 QString _dumpStructure( QObjectList* ) const;
136 139
137 private: 140 private:
138 const packetheaderstruct _hdr; // pcap packet header 141 const packetheaderstruct _hdr; // pcap packet header
139 const unsigned char* _data; // pcap packet data 142 const unsigned char* _data; // pcap packet data
140 const unsigned char* _end; // end of pcap packet data 143 const unsigned char* _end; // end of pcap packet data
141}; 144};
142 145
146QTextStream& operator<<( QTextStream& s, const OPacket& p );
147
143/*====================================================================================== 148/*======================================================================================
144 * OEthernetPacket - DLT_EN10MB frame 149 * OEthernetPacket - DLT_EN10MB frame
145 *======================================================================================*/ 150 *======================================================================================*/
146 151
147class OEthernetPacket : public QObject 152class OEthernetPacket : public QObject
148{ 153{
149 Q_OBJECT 154 Q_OBJECT
150 155
151 public: 156 public:
152 OEthernetPacket( const unsigned char*, const struct ether_header*, QObject* parent = 0 ); 157 OEthernetPacket( const unsigned char*, const struct ether_header*, QObject* parent = 0 );
153 virtual ~OEthernetPacket(); 158 virtual ~OEthernetPacket();
154 159
155 OMacAddress sourceAddress() const; 160 OMacAddress sourceAddress() const;
156 OMacAddress destinationAddress() const; 161 OMacAddress destinationAddress() const;
157 int type() const; 162 int type() const;
158 163
159 private: 164 private:
160 const struct ether_header* _ether; 165 const struct ether_header* _ether;
161}; 166};
162 167
163/*====================================================================================== 168/*======================================================================================
164 * OPrismHeaderPacket - DLT_PRISM_HEADER frame 169 * OPrismHeaderPacket - DLT_PRISM_HEADER frame
165 *======================================================================================*/ 170 *======================================================================================*/
166 171
167class OPrismHeaderPacket : public QObject 172class OPrismHeaderPacket : public QObject
168{ 173{
169 Q_OBJECT 174 Q_OBJECT
170 175
171 public: 176 public:
172 OPrismHeaderPacket( const unsigned char*, const struct prism_hdr*, QObject* parent = 0 ); 177 OPrismHeaderPacket( const unsigned char*, const struct prism_hdr*, QObject* parent = 0 );
173 virtual ~OPrismHeaderPacket(); 178 virtual ~OPrismHeaderPacket();
174 179