author | mickeyl <mickeyl> | 2003-04-08 14:15:35 (UTC) |
---|---|---|
committer | mickeyl <mickeyl> | 2003-04-08 14:15:35 (UTC) |
commit | 1af4ae3d621d63c82f7d78efda05218a3457981f (patch) (side-by-side diff) | |
tree | 99423ee25f8bf9d008d8e990725c4ecefc864ecd /libopie2 | |
parent | 77b1330ad7380ac87db4ab532acec7ae11c3bd3a (diff) | |
download | opie-1af4ae3d621d63c82f7d78efda05218a3457981f.zip opie-1af4ae3d621d63c82f7d78efda05218a3457981f.tar.gz opie-1af4ae3d621d63c82f7d78efda05218a3457981f.tar.bz2 |
- add skeleton for the last missing parts in the 802.11 decoding framework
- fix huge memory leak in packet capturer
- add more fine granular 802.11 subtype handling
-rw-r--r-- | libopie2/opienet/802_11_user.h | 16 | ||||
-rw-r--r-- | libopie2/opienet/opcap.cpp | 103 | ||||
-rw-r--r-- | libopie2/opienet/opcap.h | 22 |
3 files changed, 108 insertions, 33 deletions
diff --git a/libopie2/opienet/802_11_user.h b/libopie2/opienet/802_11_user.h index ffdcb93..f596bd8 100644 --- a/libopie2/opienet/802_11_user.h +++ b/libopie2/opienet/802_11_user.h @@ -250,16 +250,28 @@ struct ieee_802_11_data_header { u_int8_t mac2[6]; u_int8_t mac3[6]; u_int16_t SeqCtl; u_int8_t mac4[6]; // u_int16_t gapLen; // u_int8_t gap[8]; }; +struct ieee_802_11_control_header { + u_int16_t frame_control; + u_int16_t duration; + u_int8_t mac1[6]; + u_int8_t mac2[6]; + u_int8_t mac3[6]; + u_int16_t SeqCtl; + u_int8_t mac4[6]; +// u_int16_t gapLen; +// u_int8_t gap[8]; +}; + #define CAPABILITY_ESS(cap) ((cap) & 0x0001) #define CAPABILITY_IBSS(cap) ((cap) & 0x0002) #define CAPABILITY_CFP(cap) ((cap) & 0x0004) #define CAPABILITY_CFP_REQ(cap) ((cap) & 0x0008) #define CAPABILITY_PRIVACY(cap) ((cap) & 0x0010) struct ssid_t { u_int8_t element_id; @@ -357,16 +369,20 @@ struct ieee_802_11_mgmt_body { // struct tim_t tim; }; struct ieee_802_11_data_body { //FIXME }; +struct ieee_802_11_control_body { +//FIXME +}; + struct ctrl_rts_t { u_int16_t fc; u_int16_t duration; u_int8_t ra[6]; u_int8_t ta[6]; u_int8_t fcs[4]; }; diff --git a/libopie2/opienet/opcap.cpp b/libopie2/opienet/opcap.cpp index 40aac2c..5c464cf 100644 --- a/libopie2/opienet/opcap.cpp +++ b/libopie2/opienet/opcap.cpp @@ -39,48 +39,47 @@ #include <qapplication.h> // don't use oapplication here (will decrease reusability in other projects) #include <qsocketnotifier.h> /*====================================================================================== * OPacket *======================================================================================*/ -OPacket::OPacket( packetheaderstruct header, const unsigned char* data, QObject* parent ) +OPacket::OPacket( int datalink, packetheaderstruct header, const unsigned char* data, QObject* parent ) :QObject( parent, "Generic" ), _hdr( header ), _data( data ) { - qDebug( "OPacket::OPacket(): (Len %d, CapLen %d)" /*, ctime((const time_t*) header.ts.tv_sec)*/, header.len, header.caplen ); + //qDebug( "OPacket::OPacket(): (Len %d, CapLen %d)" /*, ctime((const time_t*) header.ts.tv_sec)*/, header.len, header.caplen ); _end = (unsigned char*) data + header.len; - qDebug( "OPacket::data @ %0x, end @ %0x", data, _end ); + //qDebug( "OPacket::data @ %0x, end @ %0x", data, _end ); - if ( packetCapturer()->dataLink() == DLT_EN10MB ) + switch ( datalink ) { - qDebug( "OPacket::OPacket(): Received Packet. Datalink = ETHERNET" ); - new OEthernetPacket( _end, (const struct ether_header*) data, this ); - } - else - { - qDebug( "OPacket::OPacket(): Received Packet. Datalink = IEEE802.11" ); - new OWaveLanPacket( _end, (const struct ieee_802_11_header*) data, this ); + case DLT_EN10MB: + qDebug( "OPacket::OPacket(): Received Packet. Datalink = ETHERNET" ); + new OEthernetPacket( _end, (const struct ether_header*) data, this ); + break; + + case DLT_IEEE802_11: + qDebug( "OPacket::OPacket(): Received Packet. Datalink = IEEE802.11" ); + new OWaveLanPacket( _end, (const struct ieee_802_11_header*) data, this ); + break; + + default: + qWarning( "OPacket::OPacket(): Received Packet over unsupported datalink '%s'!", datalink ); } } OPacket::~OPacket() { } -OPacketCapturer* OPacket::packetCapturer() const -{ - return parent()->inherits( "OPacketCapturer" ) ? static_cast<OPacketCapturer*>( parent() ) : 0; -} - - timevalstruct OPacket::timeval() const { return _hdr.ts; } int OPacket::caplen() const { @@ -311,28 +310,28 @@ OWaveLanPacket::OWaveLanPacket( const unsigned char* end, const struct ieee_802_ :QObject( parent, "802.11" ), _wlanhdr( data ) { qDebug( "OWaveLanPacket::OWaveLanPacket(): decoding IEEE 802.11 header..." ); qDebug( "type: %0X", type() ); qDebug( "subType: %0X", subType() ); qDebug( "duration: %d", duration() ); qDebug( "powermanagement: %d", usesPowerManagement() ); - qDebug( "wep: %d", usesWep() ); + qDebug( "payload is encrypted: %s", usesWep() ? "yes" : "no" ); qDebug( "MAC1: %s", (const char*) macAddress1().toString() ); qDebug( "MAC2: %s", (const char*) macAddress2().toString() ); qDebug( "MAC3: %s", (const char*) macAddress3().toString() ); qDebug( "MAC4: %s", (const char*) macAddress4().toString() ); switch ( type() ) { case T_MGMT: new OWaveLanManagementPacket( end, (const struct ieee_802_11_mgmt_header*) data, this ); break; case T_DATA: new OWaveLanDataPacket( end, (const struct ieee_802_11_data_header*) data, this ); break; - //case T_CTRL: new OWaveLanControlPacket( end, (const struct ieee_802_11_ctrl_header*) data, this ); break; - default: qDebug( "OWaveLanPacket::OWaveLanPacket(): Warning: Unknown type!" ); + case T_CTRL: new OWaveLanControlPacket( end, (const struct ieee_802_11_control_header*) data, this ); break; + default: qDebug( "OWaveLanPacket::OWaveLanPacket(): Warning: Unknown major type '%d'!", type() ); } } OWaveLanPacket::~OWaveLanPacket() { } @@ -412,24 +411,17 @@ bool OWaveLanPacket::usesWep() const * OWaveLanManagementPacket *======================================================================================*/ OWaveLanManagementPacket::OWaveLanManagementPacket( const unsigned char* end, const struct ieee_802_11_mgmt_header* data, OWaveLanPacket* parent ) :QObject( parent, "802.11 Management" ), _header( data ), _body( (const struct ieee_802_11_mgmt_body*) (data+1) ) { qDebug( "OWaveLanManagementPacket::OWaveLanManagementPacket(): decoding frame..." ); - - switch ( ((OWaveLanPacket*) this->parent() )->subType() ) - { - case ST_BEACON: - { - // nice, received a beacon... - } - } + qDebug( "Detected subtype is '%s'", (const char*) managementType() ); // grab tagged values const unsigned char* ptr = (const unsigned char*) (_body+1); while (ptr < end) { switch ( *ptr ) { case E_SSID: new OWaveLanManagementSSID( end, (struct ssid_t*) ptr, this ); break; @@ -447,16 +439,38 @@ OWaveLanManagementPacket::OWaveLanManagementPacket( const unsigned char* end, co } OWaveLanManagementPacket::~OWaveLanManagementPacket() { } +QString OWaveLanManagementPacket::managementType() const +{ + switch ( FC_SUBTYPE( EXTRACT_LE_16BITS( &_header->fc ) ) ) + { + case ST_ASSOC_REQUEST: return "AssociationRequest"; break; + case ST_ASSOC_RESPONSE: return "AssociationResponse"; break; + case ST_REASSOC_REQUEST: return "ReassociationRequest"; break; + case ST_REASSOC_RESPONSE: return "ReassociationResponse"; break; + case ST_PROBE_REQUEST: return "ProbeRequest"; break; + case ST_PROBE_RESPONSE: return "ProbeResponse"; break; + case ST_BEACON: return "Beacon"; break; + case ST_ATIM: return "Atim"; break; + case ST_DISASSOC: return "Disassociation"; break; + case ST_AUTH: return "Authentication"; break; + case ST_DEAUTH: return "Deathentication"; break; + default: + qWarning( "OWaveLanManagementPacket::managementType(): unhandled subtype %d", FC_SUBTYPE( EXTRACT_LE_16BITS( &_header->fc ) ) ); + return "Unknown"; + } +} + + int OWaveLanManagementPacket::beaconInterval() const { return EXTRACT_LE_16BITS( &_body->beacon_interval ); } int OWaveLanManagementPacket::capabilities() const { @@ -677,16 +691,34 @@ OLLCPacket::OLLCPacket( const unsigned char* end, const struct ieee_802_11_802_2 } } OLLCPacket::~OLLCPacket() { } + +/*====================================================================================== + * OWaveLanControlPacket + *======================================================================================*/ + +OWaveLanControlPacket::OWaveLanControlPacket( const unsigned char* end, const struct ieee_802_11_control_header* data, OWaveLanPacket* parent ) + :QObject( parent, "802.11 Data" ), _header( data ) +{ + qDebug( "OWaveLanControlPacket::OWaveLanDataControl(): decoding frame..." ); + //TODO: Implement this +} + + +OWaveLanControlPacket::~OWaveLanControlPacket() +{ +} + + /*====================================================================================== * OPacketCapturer *======================================================================================*/ OPacketCapturer::OPacketCapturer( QObject* parent, const char* name ) :QObject( parent, name ), _name( QString::null ), _open( false ), _pch( 0 ), _sn( 0 ) { @@ -765,19 +797,27 @@ int OPacketCapturer::fileno() const OPacket* OPacketCapturer::next() { packetheaderstruct header; qDebug( "==> OPacketCapturer::next()" ); const unsigned char* pdata = pcap_next( _pch, &header ); qDebug( "<== OPacketCapturer::next()" ); if ( header.len ) - return new OPacket( header, pdata, this ); + { + return new OPacket( dataLink(), header, pdata, 0 ); + // packets shouldn't be inserted in the QObject child-parent hierarchy, + // because due to memory constraints they will be deleted as soon + // as possible - that is right after they have been processed + // by emit() [ see below ] + } else + { return 0; + } } bool OPacketCapturer::open( const QString& name ) { if ( _open ) { if ( name == _name ) // ignore opening an already openend device @@ -822,11 +862,14 @@ bool OPacketCapturer::isOpen() const { return _open; } void OPacketCapturer::readyToReceive() { qDebug( "OPacketCapturer::readyToReceive(): about to emit 'receivePacket(...)'" ); - emit receivedPacket( next() ); + OPacket* p = next(); + emit receivedPacket( p ); + // emit is synchronous - packet has been dealt with, now it's safe to delete + delete p; } diff --git a/libopie2/opienet/opcap.h b/libopie2/opienet/opcap.h index 04d22ff..ddef278 100644 --- a/libopie2/opienet/opcap.h +++ b/libopie2/opienet/opcap.h @@ -66,23 +66,21 @@ class QSocketNotifier; * OPacket - A frame on the wire *======================================================================================*/ class OPacket : public QObject { Q_OBJECT public: - OPacket( packetheaderstruct, const unsigned char*, QObject* parent ); + OPacket( int datalink, packetheaderstruct, const unsigned char*, QObject* parent ); virtual ~OPacket(); timevalstruct timeval() const; - OPacketCapturer* packetCapturer() const; - int caplen() const; int len() const; QString dump( int = 32 ) const; private: const packetheaderstruct _hdr; // pcap packet header const unsigned char* _data; // pcap packet data const unsigned char* _end; // end of pcap packet data @@ -146,16 +144,18 @@ class OWaveLanPacket : public QObject class OWaveLanManagementPacket : public QObject { Q_OBJECT public: OWaveLanManagementPacket( const unsigned char*, const struct ieee_802_11_mgmt_header*, OWaveLanPacket* parent = 0 ); virtual ~OWaveLanManagementPacket(); + QString managementType() const; + int beaconInterval() const; int capabilities() const; // generic bool canESS() const; bool canIBSS() const; bool canCFP() const; bool canCFP_REQ() const; bool canPrivacy() const; @@ -310,16 +310,32 @@ class OWaveLanDataPacket : public QObject OWaveLanDataPacket( const unsigned char*, const struct ieee_802_11_data_header*, OWaveLanPacket* parent = 0 ); virtual ~OWaveLanDataPacket(); private: const struct ieee_802_11_data_header* _header; }; /*====================================================================================== + * OWaveLanControlPacket - type: control (T_CTRL) + *======================================================================================*/ + +class OWaveLanControlPacket : public QObject +{ + Q_OBJECT + + public: + OWaveLanControlPacket( const unsigned char*, const struct ieee_802_11_control_header*, OWaveLanPacket* parent = 0 ); + virtual ~OWaveLanControlPacket(); + + private: + const struct ieee_802_11_control_header* _header; +}; + +/*====================================================================================== * OLLCPacket - IEEE 802.2 Link Level Control *======================================================================================*/ class OLLCPacket : public QObject { Q_OBJECT public: |