-rw-r--r-- | libopie2/opienet/opcap.cpp | 253 |
1 files changed, 225 insertions, 28 deletions
diff --git a/libopie2/opienet/opcap.cpp b/libopie2/opienet/opcap.cpp index 48f874f..913d42e 100644 --- a/libopie2/opienet/opcap.cpp +++ b/libopie2/opienet/opcap.cpp @@ -40,33 +40,36 @@ #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 ) :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 ); + _end = (unsigned char*) data + header.len; + qDebug( "OPacket::data @ %0x, end @ %0x", data, _end ); + if ( packetCapturer()->dataLink() == DLT_EN10MB ) { qDebug( "OPacket::OPacket(): Received Packet. Datalink = ETHERNET" ); - new OEthernetPacket( (const struct ether_header*) data, this ); + new OEthernetPacket( _end, (const struct ether_header*) data, this ); } else { qDebug( "OPacket::OPacket(): Received Packet. Datalink = IEEE802.11" ); - new OWaveLanPacket( (const struct ieee_802_11_header*) data, this ); + new OWaveLanPacket( _end, (const struct ieee_802_11_header*) data, this ); } } OPacket::~OPacket() { } OPacketCapturer* OPacket::packetCapturer() const { return parent()->inherits( "OPacketCapturer" ) ? static_cast<OPacketCapturer*>( parent() ) : 0; @@ -100,40 +103,40 @@ void OPacket::dump() const int OPacket::len() const { return _hdr.len; } /*====================================================================================== * OEthernetPacket *======================================================================================*/ -OEthernetPacket::OEthernetPacket( const struct ether_header* data, QObject* parent ) +OEthernetPacket::OEthernetPacket( const unsigned char* end, const struct ether_header* data, QObject* parent ) :QObject( parent, "Ethernet" ), _ether( data ) { qDebug( "Source = %s", (const char*) sourceAddress().toString() ); qDebug( "Destination = %s", (const char*) destinationAddress().toString() ); if ( sourceAddress() == OMacAddress::broadcast ) qDebug( "Source is broadcast address" ); if ( destinationAddress() == OMacAddress::broadcast ) qDebug( "Destination is broadcast address" ); switch ( type() ) { - case ETHERTYPE_IP: new OIPPacket( (const struct iphdr*) (data+1), this ); break; + case ETHERTYPE_IP: new OIPPacket( end, (const struct iphdr*) (data+1), this ); break; case ETHERTYPE_ARP: { qDebug( "OPacket::OPacket(): Received Ethernet Packet : Type = ARP" ); break; } case ETHERTYPE_REVARP: { qDebug( "OPacket::OPacket(): Received Ethernet Packet : Type = RARP" ); break; } default: qDebug( "OPacket::OPacket(): Received Ethernet Packet : Type = UNKNOWN" ); } } OEthernetPacket::~OEthernetPacket() { } @@ -151,40 +154,40 @@ OMacAddress OEthernetPacket::destinationAddress() const int OEthernetPacket::type() const { return ntohs( _ether->ether_type ); } /*====================================================================================== * OIPPacket *======================================================================================*/ -OIPPacket::OIPPacket( const struct iphdr* data, QObject* parent ) +OIPPacket::OIPPacket( const unsigned char* end, const struct iphdr* data, QObject* parent ) :QObject( parent, "IP" ), _iphdr( data ) { qDebug( "OIPPacket::OIPPacket(): decoding IP header..." ); //qDebug( "FromAddress: %s", (const char*) inet_ntoa( *src ) ); //qDebug( " ToAddress: %s", (const char*) inet_ntoa( *dst ) ); qDebug( "FromAddress: %s", (const char*) fromIPAddress().toString() ); qDebug( " toAddress: %s", (const char*) toIPAddress().toString() ); switch ( protocol() ) { - case IPPROTO_UDP: new OUDPPacket( (const struct udphdr*) (data+1), this ); break; - case IPPROTO_TCP: new OTCPPacket( (const struct tcphdr*) (data+1), this ); break; + case IPPROTO_UDP: new OUDPPacket( end, (const struct udphdr*) (data+1), this ); break; + case IPPROTO_TCP: new OTCPPacket( end, (const struct tcphdr*) (data+1), this ); break; default: qDebug( "OIPPacket::OIPPacket(): unknown IP protocol type = %d", protocol() ); } } OIPPacket::~OIPPacket() { } QHostAddress OIPPacket::fromIPAddress() const { @@ -235,78 +238,78 @@ int OIPPacket::protocol() const int OIPPacket::checksum() const { return EXTRACT_16BITS( &_iphdr->check ); } /*====================================================================================== * OUDPPacket *======================================================================================*/ -OUDPPacket::OUDPPacket( const struct udphdr* data, QObject* parent ) +OUDPPacket::OUDPPacket( const unsigned char* end, const struct udphdr* data, QObject* parent ) :QObject( parent, "UDP" ), _udphdr( data ) { qDebug( "OUDPPacket::OUDPPacket(): decoding UDP header..." ); } OUDPPacket::~OUDPPacket() { } /*====================================================================================== * OTCPPacket *======================================================================================*/ -OTCPPacket::OTCPPacket( const struct tcphdr* data, QObject* parent ) +OTCPPacket::OTCPPacket( const unsigned char* end, const struct tcphdr* data, QObject* parent ) :QObject( parent, "TCP" ), _tcphdr( data ) { qDebug( "OTCPPacket::OTCPPacket(): decoding TCP header..." ); } OTCPPacket::~OTCPPacket() { } /*====================================================================================== * OWaveLanPacket *======================================================================================*/ -OWaveLanPacket::OWaveLanPacket( const struct ieee_802_11_header* data, QObject* parent ) +OWaveLanPacket::OWaveLanPacket( const unsigned char* end, const struct ieee_802_11_header* data, QObject* parent ) :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( "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( (const struct ieee_802_11_mgmt_header*) data, this ); break; - case T_DATA: new OWaveLanDataPacket( (const struct ieee_802_11_data_header*) data, this ); break; - //case T_CTRL: new OWaveLanControlPacket( (const struct ieee_802_11_ctrl_header*) data, this ); break; + 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!" ); } } OWaveLanPacket::~OWaveLanPacket() { } int OWaveLanPacket::duration() const { return _wlanhdr->duration; @@ -374,115 +377,301 @@ bool OWaveLanPacket::usesPowerManagement() const bool OWaveLanPacket::usesWep() const { return FC_WEP( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) ); } /*====================================================================================== * OWaveLanManagementPacket *======================================================================================*/ -OWaveLanManagementPacket::OWaveLanManagementPacket( const struct ieee_802_11_mgmt_header* data, OWaveLanPacket* parent ) +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: { - qDebug( "TYPE: BEACON FRAME" ); - qDebug( "ESSID: %s", (const char*) SSID() ); - break; + // nice, received a beacon... + } + } + + // 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; + case E_FH: new OWaveLanManagementFH( end, (struct fh_t*) ptr, this ); break; + case E_DS: new OWaveLanManagementDS( end, (struct ds_t*) ptr, this ); break; + case E_RATES: new OWaveLanManagementRates( end, (struct rates_t*) ptr, this ); break; + case E_CF: new OWaveLanManagementCF( end, (struct cf_t*) ptr, this ); break; + case E_TIM: new OWaveLanManagementTim( end, (struct tim_t*) ptr, this ); break; + case E_IBSS: new OWaveLanManagementIBSS( end, (struct ibss_t*) ptr, this ); break; + case E_CHALLENGE: new OWaveLanManagementChallenge( end, (struct challenge_t*) ptr, this ); break; } + ptr+= ( ( struct ssid_t* ) ptr )->length; // skip length of tagged value + ptr+= 2; // skip tag ID and length } } OWaveLanManagementPacket::~OWaveLanManagementPacket() { } -QString OWaveLanManagementPacket::SSID() const +int OWaveLanManagementPacket::beaconInterval() const +{ + return EXTRACT_LE_16BITS( &_body->beacon_interval ); +} + + +int OWaveLanManagementPacket::capabilities() const +{ + return EXTRACT_LE_16BITS( &_body->capability_info ); +} + + +bool OWaveLanManagementPacket::canESS() const { - int length = _body->ssid.length; + return CAPABILITY_ESS( EXTRACT_LE_16BITS( &_body->capability_info ) ); +} + + +bool OWaveLanManagementPacket::canIBSS() const +{ + return CAPABILITY_IBSS( EXTRACT_LE_16BITS( &_body->capability_info ) ); +} + + +bool OWaveLanManagementPacket::canCFP() const +{ + return CAPABILITY_CFP( EXTRACT_LE_16BITS( &_body->capability_info ) ); +} + + +bool OWaveLanManagementPacket::canCFP_REQ() const +{ + return CAPABILITY_CFP_REQ( EXTRACT_LE_16BITS( &_body->capability_info ) ); +} + + +bool OWaveLanManagementPacket::canPrivacy() const +{ + return CAPABILITY_PRIVACY( EXTRACT_LE_16BITS( &_body->capability_info ) ); +} + + +/*====================================================================================== + * OWaveLanManagementSSID + *======================================================================================*/ + +OWaveLanManagementSSID::OWaveLanManagementSSID( const unsigned char* end, const struct ssid_t* data, QObject* parent ) + :QObject( parent, "802.11 SSID" ), _data( data ) +{ + qDebug( "OWaveLanManagementSSID()" ); +} + + +OWaveLanManagementSSID::~OWaveLanManagementSSID() +{ +} + + +QString OWaveLanManagementSSID::ID() const +{ + int length = _data->length; if ( length > 32 ) length = 32; char essid[length+1]; - memcpy( &essid, _body->ssid.ssid, length ); + memcpy( &essid, &_data->ssid, length ); essid[length] = 0x0; return essid; } /*====================================================================================== + * OWaveLanManagementRates + *======================================================================================*/ + +OWaveLanManagementRates::OWaveLanManagementRates( const unsigned char* end, const struct rates_t* data, QObject* parent ) + :QObject( parent, "802.11 Rates" ), _data( data ) +{ + qDebug( "OWaveLanManagementRates()" ); +} + + +OWaveLanManagementRates::~OWaveLanManagementRates() +{ +} + +/*====================================================================================== + * OWaveLanManagementCF + *======================================================================================*/ + +OWaveLanManagementCF::OWaveLanManagementCF( const unsigned char* end, const struct cf_t* data, QObject* parent ) + :QObject( parent, "802.11 CF" ), _data( data ) +{ + qDebug( "OWaveLanManagementCF()" ); +} + + +OWaveLanManagementCF::~OWaveLanManagementCF() +{ +} + +/*====================================================================================== + * OWaveLanManagementFH + *======================================================================================*/ + +OWaveLanManagementFH::OWaveLanManagementFH( const unsigned char* end, const struct fh_t* data, QObject* parent ) + :QObject( parent, "802.11 FH" ), _data( data ) +{ + qDebug( "OWaveLanManagementFH()" ); +} + + +OWaveLanManagementFH::~OWaveLanManagementFH() +{ +} + +/*====================================================================================== + * OWaveLanManagementDS + *======================================================================================*/ + +OWaveLanManagementDS::OWaveLanManagementDS( const unsigned char* end, const struct ds_t* data, QObject* parent ) + :QObject( parent, "802.11 DS" ), _data( data ) +{ + qDebug( "OWaveLanManagementDS()" ); +} + + +OWaveLanManagementDS::~OWaveLanManagementDS() +{ +} + + +int OWaveLanManagementDS::channel() const +{ + return _data->channel; +} + +/*====================================================================================== + * OWaveLanManagementTim + *======================================================================================*/ + +OWaveLanManagementTim::OWaveLanManagementTim( const unsigned char* end, const struct tim_t* data, QObject* parent ) + :QObject( parent, "802.11 Tim" ), _data( data ) +{ + qDebug( "OWaveLanManagementTim()" ); +} + + +OWaveLanManagementTim::~OWaveLanManagementTim() +{ +} + +/*====================================================================================== + * OWaveLanManagementIBSS + *======================================================================================*/ + +OWaveLanManagementIBSS::OWaveLanManagementIBSS( const unsigned char* end, const struct ibss_t* data, QObject* parent ) + :QObject( parent, "802.11 IBSS" ), _data( data ) +{ + qDebug( "OWaveLanManagementIBSS()" ); +} + + +OWaveLanManagementIBSS::~OWaveLanManagementIBSS() +{ +} + +/*====================================================================================== + * OWaveLanManagementChallenge + *======================================================================================*/ + +OWaveLanManagementChallenge::OWaveLanManagementChallenge( const unsigned char* end, const struct challenge_t* data, QObject* parent ) + :QObject( parent, "802.11 Challenge" ), _data( data ) +{ + qDebug( "OWaveLanManagementChallenge()" ); +} + + +OWaveLanManagementChallenge::~OWaveLanManagementChallenge() +{ +} + +/*====================================================================================== * OWaveLanDataPacket *======================================================================================*/ -OWaveLanDataPacket::OWaveLanDataPacket( const struct ieee_802_11_data_header* data, OWaveLanPacket* parent ) +OWaveLanDataPacket::OWaveLanDataPacket( const unsigned char* end, const struct ieee_802_11_data_header* data, OWaveLanPacket* parent ) :QObject( parent, "802.11 Data" ), _header( data ) { //qDebug( "size of header = %d", sizeof( struct ieee_802_11_data_header ) ); //qDebug( "header: %0x", data ); const unsigned char* payload = (const unsigned char*) data + sizeof( struct ieee_802_11_data_header ); //qDebug( "payload: %0x", payload ); if (!( ( (OWaveLanPacket*) this->parent())->duration() )) payload -= 6; // compensation for missing last address - new OLLCPacket( (const struct ieee_802_11_802_2_header*) payload, this ); + new OLLCPacket( end, (const struct ieee_802_11_802_2_header*) payload, this ); } OWaveLanDataPacket::~OWaveLanDataPacket() { } /*====================================================================================== * OLLCPacket *======================================================================================*/ -OLLCPacket::OLLCPacket( const struct ieee_802_11_802_2_header* data, QObject* parent ) +OLLCPacket::OLLCPacket( const unsigned char* end, const struct ieee_802_11_802_2_header* data, QObject* parent ) :QObject( parent, "802.11 802_2" ), _header( data ) { qDebug( "OLLCPacket::OLLCPacket(): decoding frame..." ); if ( !(_header->oui[0] || _header->oui[1] || _header->oui[2]) ) { qDebug( "OLLCPacket::OLLCPacket(): contains an encapsulated Ethernet frame (type=%04X)", EXTRACT_16BITS( &_header->type ) ); switch ( EXTRACT_16BITS( &_header->type ) ) // defined in linux/if_ether.h { - case ETH_P_IP: new OIPPacket( (const struct iphdr*) (data+1), this ); break; + case ETH_P_IP: new OIPPacket( end, (const struct iphdr*) (data+1), this ); break; default: qDebug( "OLLCPacket::OLLCPacket(): Unknown Encapsulation Type" ); } } } OLLCPacket::~OLLCPacket() { } /*====================================================================================== * OPacketCapturer *======================================================================================*/ OPacketCapturer::OPacketCapturer( QObject* parent, const char* name ) :QObject( parent, name ), _name( QString::null ), _open( false ), - _pch( 0 ) + _pch( 0 ), _sn( 0 ) { } OPacketCapturer::~OPacketCapturer() { if ( _open ) { qDebug( "OPacketCapturer::~OPacketCapturer(): pcap still open, autoclosing." ); close(); } } @@ -508,24 +697,29 @@ bool OPacketCapturer::blocking() const { qDebug( "OPacketCapturer::blocking(): can't get blocking mode: %s", _errbuf ); return -1; } return !b; } void OPacketCapturer::close() { if ( _open ) { + if ( _sn ) + { + _sn->disconnect( SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) ); + delete _sn; + } pcap_close( _pch ); _open = false; } } int OPacketCapturer::dataLink() const { return pcap_datalink( _pch ); } @@ -536,25 +730,28 @@ int OPacketCapturer::fileno() const return pcap_fileno( _pch ); } else { return -1; } } 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 ); else return 0; } bool OPacketCapturer::open( const QString& name ) { if ( _open ) { if ( name == _name ) // ignore opening an already openend device @@ -568,29 +765,29 @@ bool OPacketCapturer::open( const QString& name ) } _name = name; pcap_t* handle = pcap_open_live( const_cast<char*>( (const char*) name ), 1024, 0, 0, &_errbuf[0] ); if ( handle ) { qDebug( "OPacketCapturer::open(): libpcap opened successfully." ); _pch = handle; _open = true; - // in case we have a qapp, create a socket notifier + // in case we have an application object, create a socket notifier if ( qApp ) { - QSocketNotifier* sn = new QSocketNotifier( fileno(), QSocketNotifier::Read, this ); - connect( sn, SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) ); + _sn = new QSocketNotifier( fileno(), QSocketNotifier::Read ); + connect( _sn, SIGNAL( activated(int) ), this, SLOT( readyToReceive() ) ); } return true; } else { qDebug( "OPacketCapturer::open(): can't open libpcap: %s", _errbuf ); return false; } } |