00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "udp_ports.h"
00032 #include "opcap.h"
00033
00034
00035 #include <opie2/odebug.h>
00036 using namespace Opie::Core;
00037
00038
00039 #include <qapplication.h>
00040 #include <qsocketnotifier.h>
00041 #include <qobjectlist.h>
00042
00043
00044 #include <sys/time.h>
00045 #include <sys/types.h>
00046 #include <assert.h>
00047 #include <unistd.h>
00048 #include <string.h>
00049
00050 namespace Opie {
00051 namespace Net {
00052
00053
00054
00055
00056
00057 OPacket::OPacket( int datalink, packetheaderstruct header, const unsigned char* data, QObject* parent )
00058 :QObject( parent, "Generic" ), _hdr( header ), _data( 0 )
00059 {
00060
00061 _data = new unsigned char[ header.len ];
00062 assert( _data );
00063 memcpy( const_cast<unsigned char*>(_data), data, header.len );
00064
00065
00066 odebug << "OPacket: Length = " << header.len << ", Caplen = " << header.caplen << oendl;
00067 _end = (unsigned char*) _data + header.len;
00068
00069 switch ( datalink )
00070 {
00071 case DLT_EN10MB:
00072 odebug << "OPacket::OPacket(): Received Packet. Datalink = ETHERNET" << oendl;
00073 new OEthernetPacket( _end, (const struct ether_header*) _data, this );
00074 break;
00075
00076 case DLT_IEEE802_11:
00077 odebug << "OPacket::OPacket(): Received Packet. Datalink = IEEE802.11" << oendl;
00078 new OWaveLanPacket( _end, (const struct ieee_802_11_header*) _data, this );
00079 break;
00080
00081 case DLT_PRISM_HEADER:
00082 odebug << "OPacket::OPacket(): Received Packet. Datalink = PRISM_HEADER" << oendl;
00083 new OPrismHeaderPacket( _end, (const struct prism_hdr*) (unsigned char*) _data, this );
00084 break;
00085
00086 default:
00087 owarn << "OPacket::OPacket(): Received Packet over unsupported datalink, type " << datalink << "!" << oendl;
00088 }
00089 }
00090
00091
00092 OPacket::~OPacket()
00093 {
00094 odebug << "~OPacket( " << name() << " )" << oendl;
00095 delete [] _data;
00096 }
00097
00098
00099 timevalstruct OPacket::timeval() const
00100 {
00101 return _hdr.ts;
00102 }
00103
00104
00105 int OPacket::caplen() const
00106 {
00107 return _hdr.caplen;
00108 }
00109
00110
00111 void OPacket::updateStats( QMap<QString,int>& stats, QObjectList* l )
00112 {
00113 if (!l) return;
00114 QObject* o = l->first();
00115 while ( o )
00116 {
00117 stats[o->name()]++;
00118 updateStats( stats, const_cast<QObjectList*>( o->children() ) );
00119 o = l->next();
00120 }
00121 }
00122
00123
00124 QString OPacket::dumpStructure() const
00125 {
00126 return "[ |" + _dumpStructure( const_cast<QObjectList*>( this->children() ) ) + " ]";
00127 }
00128
00129
00130 QString OPacket::_dumpStructure( QObjectList* l ) const
00131 {
00132 if (!l) return QString::null;
00133 QObject* o = l->first();
00134 QString str(" ");
00135
00136 while ( o )
00137 {
00138 str.append( o->name() );
00139 str.append( " |" );
00140 str += _dumpStructure( const_cast<QObjectList*>( o->children() ) );
00141 o = l->next();
00142 }
00143 return str;
00144 }
00145
00146 QString OPacket::dump( int bpl ) const
00147 {
00148 static int index = 0;
00149 index++;
00150 int len = _hdr.caplen;
00151 QString str( "000:" );
00152 QString tmp;
00153 QString bytes;
00154 QString chars;
00155
00156 for ( int i = 0; i < len; ++i )
00157 {
00158 tmp.sprintf( "%02X ", _data[i] ); bytes.append( tmp );
00159 if ( (_data[i] > 31) && (_data[i]<128) ) chars.append( _data[i] );
00160 else chars.append( '.' );
00161
00162 if ( !((i+1) % bpl) )
00163 {
00164 str.append( bytes );
00165 str.append( ' ' );
00166 str.append( chars );
00167 str.append( '\n' );
00168 tmp.sprintf( "%03X:", i+1 ); str.append( tmp );
00169 bytes = "";
00170 chars = "";
00171 }
00172
00173 }
00174 if ( (len % bpl) )
00175 {
00176 str.append( bytes.leftJustify( 1 + 3*bpl ) );
00177 str.append( chars );
00178 }
00179 str.append( '\n' );
00180 return str;
00181 }
00182
00183
00184 int OPacket::len() const
00185 {
00186 return _hdr.len;
00187 }
00188
00189
00190 QTextStream& operator<<( QTextStream& s, const OPacket& p )
00191 {
00192 s << p.dumpStructure();
00193 return s;
00194 }
00195
00196
00197
00198
00199
00200
00201 OEthernetPacket::OEthernetPacket( const unsigned char* end, const struct ether_header* data, QObject* parent )
00202 :QObject( parent, "Ethernet" ), _ether( data )
00203 {
00204
00205 odebug << "Source = " << sourceAddress().toString() << oendl;
00206 odebug << "Destination = " << destinationAddress().toString() << oendl;
00207
00208 if ( sourceAddress() == OMacAddress::broadcast )
00209 odebug << "Source is broadcast address" << oendl;
00210 if ( destinationAddress() == OMacAddress::broadcast )
00211 odebug << "Destination is broadcast address" << oendl;
00212
00213 switch ( type() )
00214 {
00215 case ETHERTYPE_IP: new OIPPacket( end, (const struct iphdr*) (data+1), this ); break;
00216 case ETHERTYPE_ARP: new OARPPacket( end, (const struct myarphdr*) (data+1), this ); break;
00217 case ETHERTYPE_REVARP: { odebug << "OPacket::OPacket(): Received Ethernet Packet : Type = RARP" << oendl; break; }
00218 default: odebug << "OPacket::OPacket(): Received Ethernet Packet : Type = UNKNOWN" << oendl;
00219 }
00220
00221 }
00222
00223
00224 OEthernetPacket::~OEthernetPacket()
00225 {
00226 }
00227
00228
00229 OMacAddress OEthernetPacket::sourceAddress() const
00230 {
00231 return OMacAddress( _ether->ether_shost );
00232 }
00233
00234
00235 OMacAddress OEthernetPacket::destinationAddress() const
00236 {
00237 return OMacAddress( _ether->ether_dhost );
00238 }
00239
00240 int OEthernetPacket::type() const
00241 {
00242 return ntohs( _ether->ether_type );
00243 }
00244
00245
00246
00247
00248
00249
00250
00251 OIPPacket::OIPPacket( const unsigned char* end, const struct iphdr* data, QObject* parent )
00252 :QObject( parent, "IP" ), _iphdr( data )
00253 {
00254 odebug << "OIPPacket::OIPPacket(): decoding IP header..." << oendl;
00255
00256 odebug << "FromAddress = " << fromIPAddress().toString() << oendl;
00257 odebug << " toAddress = " << toIPAddress().toString() << oendl;
00258
00259 switch ( protocol() )
00260 {
00261 case IPPROTO_UDP: new OUDPPacket( end, (const struct udphdr*) (data+1), this ); break;
00262 case IPPROTO_TCP: new OTCPPacket( end, (const struct tcphdr*) (data+1), this ); break;
00263 default: odebug << "OIPPacket::OIPPacket(): unknown IP protocol, type = " << protocol() << oendl;
00264 }
00265
00266 }
00267
00268 OIPPacket::~OIPPacket()
00269 {
00270 }
00271
00272
00273 QHostAddress OIPPacket::fromIPAddress() const
00274 {
00275 return EXTRACT_32BITS( &_iphdr->saddr );
00276 }
00277
00278
00279 QHostAddress OIPPacket::toIPAddress() const
00280 {
00281 return EXTRACT_32BITS( &_iphdr->saddr );
00282 }
00283
00284
00285 int OIPPacket::tos() const
00286 {
00287 return _iphdr->tos;
00288 }
00289
00290
00291 int OIPPacket::len() const
00292 {
00293 return EXTRACT_16BITS( &_iphdr->tot_len );
00294 }
00295
00296
00297 int OIPPacket::id() const
00298 {
00299 return EXTRACT_16BITS( &_iphdr->id );
00300 }
00301
00302
00303 int OIPPacket::offset() const
00304 {
00305 return EXTRACT_16BITS( &_iphdr->frag_off );
00306 }
00307
00308
00309 int OIPPacket::ttl() const
00310 {
00311 return _iphdr->ttl;
00312 }
00313
00314
00315 int OIPPacket::protocol() const
00316 {
00317 return _iphdr->protocol;
00318 }
00319
00320
00321 int OIPPacket::checksum() const
00322 {
00323 return EXTRACT_16BITS( &_iphdr->check );
00324 }
00325
00326
00327
00328
00329
00330
00331 OARPPacket::OARPPacket( const unsigned char* , const struct myarphdr* data, QObject* parent )
00332 :QObject( parent, "ARP" ), _arphdr( data )
00333 {
00334 odebug << "OARPPacket::OARPPacket(): decoding ARP header..." << oendl;
00335 odebug << "ARP type seems to be " << EXTRACT_16BITS( &_arphdr->ar_op ) << " = " << type() << oendl;
00336 odebug << "Sender: MAC " << senderMacAddress().toString() << " = IP " << senderIPV4Address().toString() << oendl;
00337 odebug << "Target: MAC " << targetMacAddress().toString() << " = IP " << targetIPV4Address().toString() << oendl;
00338 }
00339
00340
00341 OARPPacket::~OARPPacket()
00342 {
00343 }
00344
00345
00346 QString OARPPacket::type() const
00347 {
00348 switch ( EXTRACT_16BITS( &_arphdr->ar_op ) )
00349 {
00350 case 1: return "REQUEST";
00351 case 2: return "REPLY";
00352 case 3: return "RREQUEST";
00353 case 4: return "RREPLY";
00354 case 8: return "InREQUEST";
00355 case 9: return "InREPLY";
00356 case 10: return "NAK";
00357 default: owarn << "OARPPacket::type(): invalid ARP type!" << oendl; return "<unknown>";
00358 }
00359 }
00360
00361
00362 QHostAddress OARPPacket::senderIPV4Address() const
00363 {
00364 return EXTRACT_32BITS( &_arphdr->ar_sip );
00365 }
00366
00367
00368 QHostAddress OARPPacket::targetIPV4Address() const
00369 {
00370 return EXTRACT_32BITS( &_arphdr->ar_tip );
00371 }
00372
00373
00374 OMacAddress OARPPacket::senderMacAddress() const
00375 {
00376 return OMacAddress( _arphdr->ar_sha );
00377 }
00378
00379
00380 OMacAddress OARPPacket::targetMacAddress() const
00381 {
00382 return OMacAddress( _arphdr->ar_tha );
00383 }
00384
00385
00386
00387
00388
00389
00390
00391 OUDPPacket::OUDPPacket( const unsigned char* end, const struct udphdr* data, QObject* parent )
00392 :QObject( parent, "UDP" ), _udphdr( data )
00393
00394 {
00395 odebug << "OUDPPacket::OUDPPacket(): decoding UDP header..." << oendl;
00396 odebug << "fromPort = " << fromPort() << oendl;
00397 odebug << " toPort = " << toPort() << oendl;
00398
00399
00400
00401 if ( fromPort() == UDP_PORT_BOOTPS || fromPort() == UDP_PORT_BOOTPC ||
00402 toPort() == UDP_PORT_BOOTPS || toPort() == UDP_PORT_BOOTPC )
00403 {
00404 odebug << "seems to be part of a DHCP conversation => creating DHCP packet." << oendl;
00405 new ODHCPPacket( end, (const struct dhcp_packet*) (data+1), this );
00406 }
00407 }
00408
00409
00410 OUDPPacket::~OUDPPacket()
00411 {
00412 }
00413
00414
00415 int OUDPPacket::fromPort() const
00416 {
00417 return EXTRACT_16BITS( &_udphdr->source );
00418 }
00419
00420
00421 int OUDPPacket::toPort() const
00422 {
00423 return EXTRACT_16BITS( &_udphdr->dest );
00424 }
00425
00426
00427 int OUDPPacket::length() const
00428 {
00429 return EXTRACT_16BITS( &_udphdr->len );
00430 }
00431
00432
00433 int OUDPPacket::checksum() const
00434 {
00435 return EXTRACT_16BITS( &_udphdr->check );
00436 }
00437
00438
00439
00440
00441
00442
00443
00444 ODHCPPacket::ODHCPPacket( const unsigned char* end, const struct dhcp_packet* data, QObject* parent )
00445 :QObject( parent, "DHCP" ), _dhcphdr( data )
00446
00447 {
00448 odebug << "ODHCPPacket::ODHCPPacket(): decoding DHCP information..." << oendl;
00449 odebug << "DHCP opcode seems to be " << _dhcphdr->op << ": " << ( isRequest() ? "REQUEST" : "REPLY" ) << oendl;
00450 odebug << "clientAddress = " << clientAddress().toString() << oendl;
00451 odebug << " yourAddress = " << yourAddress().toString() << oendl;
00452 odebug << "serverAddress = " << serverAddress().toString() << oendl;
00453 odebug << " relayAddress = " << relayAddress().toString() << oendl;
00454 odebug << "parsing DHCP options..." << oendl;
00455
00456 _type = 0;
00457
00458 const unsigned char* option = &_dhcphdr->options[4];
00459 char tag = -1;
00460 char len = -1;
00461
00462 while ( ( tag = *option++ ) != -1 )
00463 {
00464 len = *option++;
00465 odebug << "recognized DHCP option #" << tag << ", length " << len << oendl;
00466
00467 if ( tag == DHO_DHCP_MESSAGE_TYPE )
00468 _type = *option;
00469
00470 option += len;
00471 if ( option >= end )
00472 {
00473 owarn << "DHCP parsing ERROR: sanity check says the packet is at its end!" << oendl;
00474 break;
00475 }
00476 }
00477
00478 odebug << "DHCP type seems to be << " << type() << oendl;
00479 }
00480
00481
00482 ODHCPPacket::~ODHCPPacket()
00483 {
00484 }
00485
00486
00487 bool ODHCPPacket::isRequest() const
00488 {
00489 return ( _dhcphdr->op == 01 );
00490 }
00491
00492
00493 bool ODHCPPacket::isReply() const
00494 {
00495 return ( _dhcphdr->op == 02 );
00496 }
00497
00498
00499 QString ODHCPPacket::type() const
00500 {
00501 switch ( _type )
00502 {
00503 case 1: return "DISCOVER";
00504 case 2: return "OFFER";
00505 case 3: return "REQUEST";
00506 case 4: return "DECLINE";
00507 case 5: return "ACK";
00508 case 6: return "NAK";
00509 case 7: return "RELEASE";
00510 case 8: return "INFORM";
00511 default: owarn << "ODHCPPacket::type(): invalid DHCP type " << _dhcphdr->op << oendl; return "<unknown>";
00512 }
00513 }
00514
00515
00516 QHostAddress ODHCPPacket::clientAddress() const
00517 {
00518 return EXTRACT_32BITS( &_dhcphdr->ciaddr );
00519 }
00520
00521
00522 QHostAddress ODHCPPacket::yourAddress() const
00523 {
00524 return EXTRACT_32BITS( &_dhcphdr->yiaddr );
00525 }
00526
00527
00528 QHostAddress ODHCPPacket::serverAddress() const
00529 {
00530 return EXTRACT_32BITS( &_dhcphdr->siaddr );
00531 }
00532
00533
00534 QHostAddress ODHCPPacket::relayAddress() const
00535 {
00536 return EXTRACT_32BITS( &_dhcphdr->giaddr );
00537 }
00538
00539
00540 OMacAddress ODHCPPacket::clientMacAddress() const
00541 {
00542 return OMacAddress( _dhcphdr->chaddr );
00543 }
00544
00545
00546
00547
00548
00549
00550
00551 OTCPPacket::OTCPPacket( const unsigned char* , const struct tcphdr* data, QObject* parent )
00552 :QObject( parent, "TCP" ), _tcphdr( data )
00553
00554 {
00555 odebug << "OTCPPacket::OTCPPacket(): decoding TCP header..." << oendl;
00556 }
00557
00558
00559 OTCPPacket::~OTCPPacket()
00560 {
00561 }
00562
00563
00564 int OTCPPacket::fromPort() const
00565 {
00566 return EXTRACT_16BITS( &_tcphdr->source );
00567 }
00568
00569
00570 int OTCPPacket::toPort() const
00571 {
00572 return EXTRACT_16BITS( &_tcphdr->dest );
00573 }
00574
00575
00576 int OTCPPacket::seq() const
00577 {
00578 return EXTRACT_16BITS( &_tcphdr->seq );
00579 }
00580
00581
00582 int OTCPPacket::ack() const
00583 {
00584 return EXTRACT_16BITS( &_tcphdr->ack_seq );
00585 }
00586
00587
00588 int OTCPPacket::window() const
00589 {
00590 return EXTRACT_16BITS( &_tcphdr->window );
00591 }
00592
00593
00594 int OTCPPacket::checksum() const
00595 {
00596 return EXTRACT_16BITS( &_tcphdr->check );
00597 }
00598
00599
00600
00601
00602
00603
00604 OPrismHeaderPacket::OPrismHeaderPacket( const unsigned char* end, const struct prism_hdr* data, QObject* parent )
00605 :QObject( parent, "Prism" ), _header( data )
00606
00607 {
00608 odebug << "OPrismHeaderPacket::OPrismHeaderPacket(): decoding PRISM header..." << oendl;
00609
00610 odebug << "Signal Strength = " << data->signal.data << oendl;
00611
00612 new OWaveLanPacket( end, (const struct ieee_802_11_header*) (data+1), this );
00613 }
00614
00615 OPrismHeaderPacket::~OPrismHeaderPacket()
00616 {
00617 }
00618
00619
00620 unsigned int OPrismHeaderPacket::signalStrength() const
00621 {
00622 return _header->signal.data;
00623 }
00624
00625
00626
00627
00628
00629
00630 OWaveLanPacket::OWaveLanPacket( const unsigned char* end, const struct ieee_802_11_header* data, QObject* parent )
00631 :QObject( parent, "802.11" ), _wlanhdr( data )
00632
00633 {
00634 odebug << "OWaveLanPacket::OWaveLanPacket(): decoding IEEE 802.11 header..." << oendl;
00635 odebug << "type = " << type() << oendl;
00636 odebug << "subType = " << subType() << oendl;
00637 odebug << "duration = " << duration() << oendl;
00638 odebug << "powermanagement = " << usesPowerManagement() << oendl;
00639 odebug << "payload is encrypted = " << ( usesWep() ? "yes" : "no" ) << oendl;
00640 odebug << "MAC1 = " << macAddress1().toString() << oendl;
00641 odebug << "MAC2 = " << macAddress2().toString() << oendl;
00642 odebug << "MAC3 = " << macAddress3().toString() << oendl;
00643 odebug << "MAC4 = " << macAddress4().toString() << oendl;
00644
00645 switch ( type() )
00646 {
00647 case T_MGMT: new OWaveLanManagementPacket( end, (const struct ieee_802_11_mgmt_header*) data, this ); break;
00648 case T_DATA: new OWaveLanDataPacket( end, (const struct ieee_802_11_data_header*) data, this ); break;
00649 case T_CTRL: new OWaveLanControlPacket( end, (const struct ieee_802_11_control_header*) data, this ); break;
00650 default: odebug << "OWaveLanPacket::OWaveLanPacket(): Warning: Unknown major type = " << type() << oendl;
00651 }
00652 }
00653
00654 OWaveLanPacket::~OWaveLanPacket()
00655 {
00656 }
00657
00658
00659 int OWaveLanPacket::duration() const
00660 {
00661 return _wlanhdr->duration;
00662 }
00663
00664
00665 OMacAddress OWaveLanPacket::macAddress1() const
00666 {
00667 return OMacAddress( _wlanhdr->mac1 );
00668 }
00669
00670
00671 OMacAddress OWaveLanPacket::macAddress2() const
00672 {
00673 return OMacAddress( _wlanhdr->mac2 );
00674 }
00675
00676
00677 OMacAddress OWaveLanPacket::macAddress3() const
00678 {
00679 return OMacAddress( _wlanhdr->mac3 );
00680 }
00681
00682
00683 OMacAddress OWaveLanPacket::macAddress4() const
00684 {
00685 return OMacAddress( _wlanhdr->mac4 );
00686 }
00687
00688
00689 int OWaveLanPacket::subType() const
00690 {
00691 return FC_SUBTYPE( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) );
00692 }
00693
00694
00695 int OWaveLanPacket::type() const
00696 {
00697 return FC_TYPE( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) );
00698 }
00699
00700
00701 int OWaveLanPacket::version() const
00702 {
00703 return FC_VERSION( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) );
00704 }
00705
00706
00707 bool OWaveLanPacket::fromDS() const
00708 {
00709 return FC_FROM_DS( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) );
00710 }
00711
00712
00713 bool OWaveLanPacket::toDS() const
00714 {
00715 return FC_TO_DS( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) );
00716 }
00717
00718
00719 bool OWaveLanPacket::usesPowerManagement() const
00720 {
00721 return FC_POWER_MGMT( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) );
00722 }
00723
00724
00725 bool OWaveLanPacket::usesWep() const
00726 {
00727 return FC_WEP( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) );
00728 }
00729
00730
00731
00732
00733
00734
00735 OWaveLanManagementPacket::OWaveLanManagementPacket( const unsigned char* end, const struct ieee_802_11_mgmt_header* data, OWaveLanPacket* parent )
00736 :QObject( parent, "802.11 Management" ), _header( data ),
00737 _body( (const struct ieee_802_11_mgmt_body*) (data+1) )
00738 {
00739 odebug << "OWaveLanManagementPacket::OWaveLanManagementPacket(): decoding frame..." << oendl;
00740 odebug << "Detected subtype is " << managementType() << oendl;
00741
00742
00743
00744
00745
00746 const unsigned char* ptr = managementType() == "Beacon" ? (const unsigned char*) (_body+1) : (const unsigned char*) (_header+1);
00747
00748 while (ptr < end)
00749 {
00750 switch ( *ptr )
00751 {
00752 case E_SSID: new OWaveLanManagementSSID( end, (struct ssid_t*) ptr, this ); break;
00753 case E_FH: new OWaveLanManagementFH( end, (struct fh_t*) ptr, this ); break;
00754 case E_DS: new OWaveLanManagementDS( end, (struct ds_t*) ptr, this ); break;
00755 case E_RATES: new OWaveLanManagementRates( end, (struct rates_t*) ptr, this ); break;
00756 case E_CF: new OWaveLanManagementCF( end, (struct cf_t*) ptr, this ); break;
00757 case E_TIM: new OWaveLanManagementTim( end, (struct tim_t*) ptr, this ); break;
00758 case E_IBSS: new OWaveLanManagementIBSS( end, (struct ibss_t*) ptr, this ); break;
00759 case E_CHALLENGE: new OWaveLanManagementChallenge( end, (struct challenge_t*) ptr, this ); break;
00760 }
00761 ptr+= ( ( struct ssid_t* ) ptr )->length;
00762 ptr+= 2;
00763 }
00764 }
00765
00766
00767 OWaveLanManagementPacket::~OWaveLanManagementPacket()
00768 {
00769 }
00770
00771
00772 QString OWaveLanManagementPacket::managementType() const
00773 {
00774 switch ( FC_SUBTYPE( EXTRACT_LE_16BITS( &_header->fc ) ) )
00775 {
00776 case ST_ASSOC_REQUEST: return "AssociationRequest"; break;
00777 case ST_ASSOC_RESPONSE: return "AssociationResponse"; break;
00778 case ST_REASSOC_REQUEST: return "ReassociationRequest"; break;
00779 case ST_REASSOC_RESPONSE: return "ReassociationResponse"; break;
00780 case ST_PROBE_REQUEST: return "ProbeRequest"; break;
00781 case ST_PROBE_RESPONSE: return "ProbeResponse"; break;
00782 case ST_BEACON: return "Beacon"; break;
00783 case ST_ATIM: return "Atim"; break;
00784 case ST_DISASSOC: return "Disassociation"; break;
00785 case ST_AUTH: return "Authentication"; break;
00786 case ST_DEAUTH: return "Deathentication"; break;
00787 default: owarn << "OWaveLanManagementPacket::managementType(): unhandled subtype " << FC_SUBTYPE( EXTRACT_LE_16BITS( &_header->fc ) ) << oendl; return "Unknown";
00788 }
00789 }
00790
00791
00792 int OWaveLanManagementPacket::beaconInterval() const
00793 {
00794 return EXTRACT_LE_16BITS( &_body->beacon_interval );
00795 }
00796
00797
00798 int OWaveLanManagementPacket::capabilities() const
00799 {
00800 return EXTRACT_LE_16BITS( &_body->capability_info );
00801 }
00802
00803
00804 bool OWaveLanManagementPacket::canESS() const
00805 {
00806 return CAPABILITY_ESS( EXTRACT_LE_16BITS( &_body->capability_info ) );
00807 }
00808
00809
00810 bool OWaveLanManagementPacket::canIBSS() const
00811 {
00812 return CAPABILITY_IBSS( EXTRACT_LE_16BITS( &_body->capability_info ) );
00813 }
00814
00815
00816 bool OWaveLanManagementPacket::canCFP() const
00817 {
00818 return CAPABILITY_CFP( EXTRACT_LE_16BITS( &_body->capability_info ) );
00819 }
00820
00821
00822 bool OWaveLanManagementPacket::canCFP_REQ() const
00823 {
00824 return CAPABILITY_CFP_REQ( EXTRACT_LE_16BITS( &_body->capability_info ) );
00825 }
00826
00827
00828 bool OWaveLanManagementPacket::canPrivacy() const
00829 {
00830 return CAPABILITY_PRIVACY( EXTRACT_LE_16BITS( &_body->capability_info ) );
00831 }
00832
00833
00834
00835
00836
00837
00838 OWaveLanManagementSSID::OWaveLanManagementSSID( const unsigned char* , const struct ssid_t* data, QObject* parent )
00839 :QObject( parent, "802.11 SSID" ), _data( data )
00840 {
00841 odebug << "OWaveLanManagementSSID()" << oendl;
00842 }
00843
00844
00845 OWaveLanManagementSSID::~OWaveLanManagementSSID()
00846 {
00847 }
00848
00849
00850 QString OWaveLanManagementSSID::ID( bool decloak ) const
00851 {
00852 int length = _data->length;
00853 if ( length > 32 ) length = 32;
00854 char essid[length+1];
00855 memcpy( &essid, &_data->ssid, length );
00856 essid[length] = 0x0;
00857 if ( !decloak || length < 2 || essid[0] != '\0' ) return essid;
00858 odebug << "OWaveLanManagementSSID:ID(): SSID is cloaked - decloaking..." << oendl;
00859
00860 QString decloakedID;
00861 for ( int i = 1; i < length; ++i )
00862 {
00863 if ( essid[i] >= 32 && essid[i] <= 126 ) decloakedID.append( essid[i] );
00864 else decloakedID.append( '.' );
00865 }
00866 return decloakedID;
00867 }
00868
00869
00870
00871
00872
00873
00874 OWaveLanManagementRates::OWaveLanManagementRates( const unsigned char* , const struct rates_t* data, QObject* parent )
00875 :QObject( parent, "802.11 Rates" ), _data( data )
00876 {
00877 odebug << "OWaveLanManagementRates()" << oendl;
00878 }
00879
00880
00881 OWaveLanManagementRates::~OWaveLanManagementRates()
00882 {
00883 }
00884
00885
00886
00887
00888
00889 OWaveLanManagementCF::OWaveLanManagementCF( const unsigned char* , const struct cf_t* data, QObject* parent )
00890 :QObject( parent, "802.11 CF" ), _data( data )
00891 {
00892 odebug << "OWaveLanManagementCF()" << oendl;
00893 }
00894
00895
00896 OWaveLanManagementCF::~OWaveLanManagementCF()
00897 {
00898 }
00899
00900
00901
00902
00903
00904 OWaveLanManagementFH::OWaveLanManagementFH( const unsigned char* , const struct fh_t* data, QObject* parent )
00905 :QObject( parent, "802.11 FH" ), _data( data )
00906 {
00907 odebug << "OWaveLanManagementFH()" << oendl;
00908 }
00909
00910
00911 OWaveLanManagementFH::~OWaveLanManagementFH()
00912 {
00913 }
00914
00915
00916
00917
00918
00919 OWaveLanManagementDS::OWaveLanManagementDS( const unsigned char* , const struct ds_t* data, QObject* parent )
00920 :QObject( parent, "802.11 DS" ), _data( data )
00921 {
00922 odebug << "OWaveLanManagementDS()" << oendl;
00923 }
00924
00925
00926 OWaveLanManagementDS::~OWaveLanManagementDS()
00927 {
00928 }
00929
00930
00931 int OWaveLanManagementDS::channel() const
00932 {
00933 return _data->channel;
00934 }
00935
00936
00937
00938
00939
00940 OWaveLanManagementTim::OWaveLanManagementTim( const unsigned char* , const struct tim_t* data, QObject* parent )
00941 :QObject( parent, "802.11 Tim" ), _data( data )
00942 {
00943 odebug << "OWaveLanManagementTim()" << oendl;
00944 }
00945
00946
00947 OWaveLanManagementTim::~OWaveLanManagementTim()
00948 {
00949 }
00950
00951
00952
00953
00954
00955 OWaveLanManagementIBSS::OWaveLanManagementIBSS( const unsigned char* , const struct ibss_t* data, QObject* parent )
00956 :QObject( parent, "802.11 IBSS" ), _data( data )
00957 {
00958 odebug << "OWaveLanManagementIBSS()" << oendl;
00959 }
00960
00961
00962 OWaveLanManagementIBSS::~OWaveLanManagementIBSS()
00963 {
00964 }
00965
00966
00967
00968
00969
00970 OWaveLanManagementChallenge::OWaveLanManagementChallenge( const unsigned char* , const struct challenge_t* data, QObject* parent )
00971 :QObject( parent, "802.11 Challenge" ), _data( data )
00972 {
00973 odebug << "OWaveLanManagementChallenge()" << oendl;
00974 }
00975
00976
00977 OWaveLanManagementChallenge::~OWaveLanManagementChallenge()
00978 {
00979 }
00980
00981
00982
00983
00984
00985 OWaveLanDataPacket::OWaveLanDataPacket( const unsigned char* end, const struct ieee_802_11_data_header* data, OWaveLanPacket* parent )
00986 :QObject( parent, "802.11 Data" ), _header( data )
00987 {
00988 odebug << "OWaveLanDataPacket::OWaveLanDataPacket(): decoding frame..." << oendl;
00989
00990 const unsigned char* payload = (const unsigned char*) data + sizeof( struct ieee_802_11_data_header );
00991
00992 #warning The next line works for most cases, but can not be correct generally!
00993 if (!( ( (OWaveLanPacket*) this->parent())->duration() )) payload -= 6;
00994
00995 new OLLCPacket( end, (const struct ieee_802_11_802_2_header*) payload, this );
00996 }
00997
00998
00999 OWaveLanDataPacket::~OWaveLanDataPacket()
01000 {
01001 }
01002
01003
01004
01005
01006
01007
01008 OLLCPacket::OLLCPacket( const unsigned char* end, const struct ieee_802_11_802_2_header* data, QObject* parent )
01009 :QObject( parent, "802.11 LLC" ), _header( data )
01010 {
01011 odebug << "OLLCPacket::OLLCPacket(): decoding frame..." << oendl;
01012
01013 if ( !(_header->oui[0] || _header->oui[1] || _header->oui[2]) )
01014 {
01015 owarn << "OLLCPacket::OLLCPacket(): contains an encapsulated Ethernet frame (type = " << EXTRACT_16BITS( &_header->type ) << ")" << oendl;
01016
01017 switch ( EXTRACT_16BITS( &_header->type ) )
01018 {
01019 case ETH_P_IP: new OIPPacket( end, (const struct iphdr*) (data+1), this ); break;
01020 case ETH_P_ARP: new OARPPacket( end, (const struct myarphdr*) (data+1), this ); break;
01021 default: owarn << "OLLCPacket::OLLCPacket(): Unknown Encapsulation type = " << EXTRACT_16BITS( &_header->type ) << oendl;
01022 }
01023 }
01024 }
01025
01026
01027 OLLCPacket::~OLLCPacket()
01028 {
01029 }
01030
01031
01032
01033
01034
01035
01036 OWaveLanControlPacket::OWaveLanControlPacket( const unsigned char* , const struct ieee_802_11_control_header* data, OWaveLanPacket* parent )
01037 :QObject( parent, "802.11 Control" ), _header( data )
01038 {
01039 odebug << "OWaveLanControlPacket::OWaveLanDataControl(): decoding frame..." << oendl;
01040 odebug << "Detected subtype is " << controlType() << oendl;
01041 }
01042
01043
01044 OWaveLanControlPacket::~OWaveLanControlPacket()
01045 {
01046 }
01047
01048
01049 QString OWaveLanControlPacket::controlType() const
01050 {
01051 switch ( FC_SUBTYPE( EXTRACT_LE_16BITS( &_header->fc ) ) )
01052 {
01053 case CTRL_PS_POLL: return "PowerSavePoll"; break;
01054 case CTRL_RTS: return "RequestToSend"; break;
01055 case CTRL_CTS: return "ClearToSend"; break;
01056 case CTRL_ACK: return "Acknowledge"; break;
01057 case CTRL_CF_END: return "ContentionFreeEnd"; break;
01058 case CTRL_END_ACK: return "AcknowledgeEnd"; break;
01059 default:
01060 owarn << "OWaveLanControlPacket::managementType(): unhandled subtype " << FC_SUBTYPE( EXTRACT_LE_16BITS( &_header->fc ) ) << oendl;
01061 return "Unknown";
01062 }
01063 }
01064
01065
01066
01067
01068
01069
01070 OPacketCapturer::OPacketCapturer( QObject* parent, const char* name )
01071 :QObject( parent, name ), _name( QString::null ), _open( false ), _pch( 0 ), _pcd( 0 ), _sn( 0 ), _autodelete( true )
01072 {
01073 }
01074
01075
01076 OPacketCapturer::~OPacketCapturer()
01077 {
01078 if ( _open )
01079 {
01080 odebug << "OPacketCapturer::~OPacketCapturer(): pcap still open, autoclosing." << oendl;
01081 close();
01082 }
01083 }
01084
01085
01086 void OPacketCapturer::setAutoDelete( bool b )
01087 {
01088 _autodelete = b;
01089 }
01090
01091
01092 bool OPacketCapturer::autoDelete() const
01093 {
01094 return _autodelete;
01095 }
01096
01097
01098 void OPacketCapturer::setBlocking( bool b )
01099 {
01100 if ( pcap_setnonblock( _pch, 1-b, _errbuf ) != -1 )
01101 {
01102 odebug << "OPacketCapturer::setBlocking(): blocking mode changed successfully." << oendl;
01103 }
01104 else
01105 {
01106 odebug << "OPacketCapturer::setBlocking(): can't change blocking mode: " << _errbuf << oendl;
01107 }
01108 }
01109
01110
01111 bool OPacketCapturer::blocking() const
01112 {
01113 int b = pcap_getnonblock( _pch, _errbuf );
01114 if ( b == -1 )
01115 {
01116 odebug << "OPacketCapturer::blocking(): can't get blocking mode: " << _errbuf << oendl;
01117 return -1;
01118 }
01119 return !b;
01120 }
01121
01122
01123 void OPacketCapturer::closeDumpFile()
01124 {
01125 if ( _pcd )
01126 {
01127 pcap_dump_close( _pcd );
01128 _pcd = 0;
01129 }
01130 pcap_close( _pch );
01131 }
01132
01133
01134 void OPacketCapturer::close()
01135 {
01136 if ( _open )
01137 {
01138 if ( _sn )
01139 {
01140 _sn->disconnect( SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) );
01141 delete _sn;
01142 }
01143 closeDumpFile();
01144 _open = false;
01145 }
01146
01147 odebug << "OPacketCapturer::close() --- dumping capturing statistics..." << oendl;
01148 odebug << "--------------------------------------------------" << oendl;
01149 for( QMap<QString,int>::Iterator it = _stats.begin(); it != _stats.end(); ++it )
01150 odebug << it.key() << " = " << it.data() << oendl;
01151 odebug << "--------------------------------------------------" << oendl;
01152
01153 }
01154
01155
01156 int OPacketCapturer::dataLink() const
01157 {
01158 return pcap_datalink( _pch );
01159 }
01160
01161
01162 void OPacketCapturer::dump( OPacket* p )
01163 {
01164 if ( !_pcd )
01165 {
01166 owarn << "OPacketCapturer::dump() - cannot dump without open capture file!" << oendl;
01167 return;
01168 }
01169 pcap_dump( (u_char*) _pcd, &p->_hdr, p->_data );
01170 }
01171
01172
01173 int OPacketCapturer::fileno() const
01174 {
01175 if ( _open )
01176 {
01177 return pcap_fileno( _pch );
01178 }
01179 else
01180 {
01181 return -1;
01182 }
01183 }
01184
01185
01186 OPacket* OPacketCapturer::next( int time )
01187 {
01188 fd_set fds;
01189 struct timeval tv;
01190 FD_ZERO( &fds );
01191 FD_SET( pcap_fileno( _pch ), &fds );
01192 tv.tv_sec = time / 1000;
01193 tv.tv_usec = time % 1000;
01194 int retval = select( pcap_fileno( _pch )+1, &fds, NULL, NULL, &tv);
01195 if ( retval > 0 )
01196 return next();
01197 else
01198 return 0;
01199 }
01200
01201
01202 OPacket* OPacketCapturer::next()
01203 {
01204 packetheaderstruct header;
01205 odebug << "==> OPacketCapturer::next()" << oendl;
01206 const unsigned char* pdata = pcap_next( _pch, &header );
01207 odebug << "<== OPacketCapturer::next()" << oendl;
01208
01209 if ( pdata && header.len )
01210 {
01211 OPacket* p = new OPacket( dataLink(), header, pdata, 0 );
01212
01213
01214
01215
01216
01217 p->updateStats( _stats, const_cast<QObjectList*>( p->children() ) );
01218 odebug << "OPacket::dumpStructure: " << p->dumpStructure() << oendl;
01219 return p;
01220 }
01221 else
01222 {
01223 owarn << "OPacketCapturer::next() - no packet received!" << oendl;
01224 return 0;
01225 }
01226 }
01227
01228
01229 bool OPacketCapturer::open( const QString& name )
01230 {
01231 if ( _open )
01232 {
01233 if ( name == _name )
01234 {
01235 return true;
01236 }
01237 else
01238 {
01239 close();
01240 }
01241 }
01242
01243 _name = name;
01244
01245
01246 pcap_t* handle = pcap_open_live( const_cast<char*>( (const char*) name ), 1024, 0, 0, &_errbuf[0] );
01247
01248 if ( !handle )
01249 {
01250 owarn << "OPacketCapturer::open(): can't open libpcap with '" << name << "': " << _errbuf << oendl;
01251 return false;
01252 }
01253
01254 odebug << "OPacketCapturer::open(): libpcap [" << name << "] opened successfully." << oendl;
01255 _pch = handle;
01256 _open = true;
01257 _stats.clear();
01258
01259
01260 if ( qApp )
01261 {
01262 _sn = new QSocketNotifier( fileno(), QSocketNotifier::Read );
01263 connect( _sn, SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) );
01264 }
01265
01266 return true;
01267 }
01268
01269
01270 bool OPacketCapturer::openDumpFile( const QString& filename )
01271 {
01272 pcap_dumper_t* dump = pcap_dump_open( _pch, const_cast<char*>( (const char*) filename ) );
01273 if ( !dump )
01274 {
01275 owarn << "OPacketCapturer::open(): can't open dump with '" << filename << "': " << _errbuf << oendl;
01276 return false;
01277 }
01278 odebug << "OPacketCapturer::open(): dump [" << filename << "] opened successfully." << oendl;
01279 _pcd = dump;
01280
01281 return true;
01282 }
01283
01284
01285 bool OPacketCapturer::openCaptureFile( const QString& name )
01286 {
01287 if ( _open )
01288 {
01289 close();
01290 if ( name == _name )
01291 {
01292 return true;
01293 }
01294 else
01295 {
01296 close();
01297 }
01298 }
01299
01300 _name = name;
01301
01302 pcap_t* handle = pcap_open_offline( const_cast<char*>( (const char*) name ), &_errbuf[0] );
01303
01304 if ( handle )
01305 {
01306 odebug << "OPacketCapturer::open(): libpcap opened successfully." << oendl;
01307 _pch = handle;
01308 _open = true;
01309
01310
01311 if ( qApp )
01312 {
01313 _sn = new QSocketNotifier( fileno(), QSocketNotifier::Read );
01314 connect( _sn, SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) );
01315 }
01316
01317 return true;
01318 }
01319 else
01320 {
01321 odebug << "OPacketCapturer::open(): can't open libpcap with '" << name << "': " << _errbuf << oendl;
01322 return false;
01323 }
01324
01325 }
01326
01327
01328 bool OPacketCapturer::isOpen() const
01329 {
01330 return _open;
01331 }
01332
01333
01334 void OPacketCapturer::readyToReceive()
01335 {
01336 odebug << "OPacketCapturer::readyToReceive(): about to emit 'receivePacket(p)'" << oendl;
01337 OPacket* p = next();
01338 emit receivedPacket( p );
01339
01340 if ( _autodelete ) delete p;
01341 }
01342
01343
01344 const QMap<QString,int>& OPacketCapturer::statistics() const
01345 {
01346 return _stats;
01347 }
01348
01349
01350 int OPacketCapturer::snapShot() const
01351 {
01352 return pcap_snapshot( _pch );
01353 }
01354
01355
01356 bool OPacketCapturer::swapped() const
01357 {
01358 return pcap_is_swapped( _pch );
01359 }
01360
01361
01362 QString OPacketCapturer::version() const
01363 {
01364 return QString().sprintf( "%d.%d", pcap_major_version( _pch ), pcap_minor_version( _pch ) );
01365 }
01366
01367 }
01368 }