-rw-r--r-- | libopie2/opienet/opcap.cpp | 5 |
1 files changed, 1 insertions, 4 deletions
diff --git a/libopie2/opienet/opcap.cpp b/libopie2/opienet/opcap.cpp index 6331b2d..635224c 100644 --- a/libopie2/opienet/opcap.cpp +++ b/libopie2/opienet/opcap.cpp @@ -1,774 +1,771 @@ /* This file is part of the Opie Project - Copyright (C) 2003 by the Wellenreiter team: - Martin J. Muench <mjm@remote-exploit.org> - Max Moser <mmo@remote-exploit.org - Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de> + Copyright (C) 2003 by Michael 'Mickey' Lauer <mickey@Vanille.de> =. .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* OPIE */ #include <opie2/opcap.h> /* QT */ #include <qapplication.h> // don't use oapplication here (will decrease reusability in other projects) #include <qsocketnotifier.h> #include <qobjectlist.h> /* SYSTEM */ #include <sys/time.h> #include <sys/types.h> #include <unistd.h> /* LOCAL */ #include "udp_ports.h" /*====================================================================================== * OPacket *======================================================================================*/ 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 ); _end = (unsigned char*) data + header.len; //qDebug( "OPacket::data @ %0x, end @ %0x", data, _end ); switch ( datalink ) { 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; case DLT_PRISM_HEADER: qDebug( "OPacket::OPacket(): Received Packet. Datalink = PRISM_HEADER" ); new OPrismHeaderPacket( _end, (const struct prism_hdr*) (unsigned char*) data, this ); break; default: qWarning( "OPacket::OPacket(): Received Packet over unsupported datalink (type %d)!", datalink ); } } OPacket::~OPacket() { } timevalstruct OPacket::timeval() const { return _hdr.ts; } int OPacket::caplen() const { return _hdr.caplen; } void OPacket::updateStats( QMap<QString,int>& stats, QObjectList* l ) { if (!l) return; QObject* o = l->first(); while ( o ) { stats[o->name()]++; updateStats( stats, const_cast<QObjectList*>( o->children() ) ); o = l->next(); } } void OPacket::dumpStructure( QObjectList* l ) { QString packetString( "[ |" + _dumpStructure( l ) + " ]" ); qDebug( "OPacket::dumpStructure: %s", (const char*) packetString ); } QString OPacket::_dumpStructure( QObjectList* l ) { if (!l) return QString::null; QObject* o = l->first(); QString str(" "); while ( o ) { str.append( o->name() ); str.append( " |" ); str += _dumpStructure( const_cast<QObjectList*>( o->children() ) ); o = l->next(); } return str; } QString OPacket::dump( int bpl ) const { static int index = 0; index++; int len = _hdr.caplen; QString str; str.sprintf( "\n<----- Packet #%04d Len = 0x%X (%d) ----->\n\n", index, len, len ); str.append( "0000: " ); QString tmp; QString bytes; QString chars; for ( int i = 0; i < len; ++i ) { tmp.sprintf( "%02X ", _data[i] ); bytes.append( tmp ); if ( (_data[i] > 31) && (_data[i]<128) ) chars.append( _data[i] ); else chars.append( '.' ); if ( !((i+1) % bpl) ) { str.append( bytes ); str.append( ' ' ); str.append( chars ); str.append( '\n' ); tmp.sprintf( "%04X: ", i+1 ); str.append( tmp ); bytes = ""; chars = ""; } } if ( (len % bpl) ) { str.append( bytes.leftJustify( 1 + 3*bpl ) ); str.append( chars ); } str.append( '\n' ); return str; } int OPacket::len() const { return _hdr.len; } /*====================================================================================== * OEthernetPacket *======================================================================================*/ 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( end, (const struct iphdr*) (data+1), this ); break; case ETHERTYPE_ARP: new OARPPacket( end, (const struct myarphdr*) (data+1), this ); break; case ETHERTYPE_REVARP: { qDebug( "OPacket::OPacket(): Received Ethernet Packet : Type = RARP" ); break; } default: qDebug( "OPacket::OPacket(): Received Ethernet Packet : Type = UNKNOWN" ); } } OEthernetPacket::~OEthernetPacket() { } OMacAddress OEthernetPacket::sourceAddress() const { return OMacAddress( _ether->ether_shost ); } OMacAddress OEthernetPacket::destinationAddress() const { return OMacAddress( _ether->ether_dhost ); } int OEthernetPacket::type() const { return ntohs( _ether->ether_type ); } /*====================================================================================== * OIPPacket *======================================================================================*/ 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( 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 { return EXTRACT_32BITS( &_iphdr->saddr ); } QHostAddress OIPPacket::toIPAddress() const { return EXTRACT_32BITS( &_iphdr->saddr ); } int OIPPacket::tos() const { return _iphdr->tos; } int OIPPacket::len() const { return EXTRACT_16BITS( &_iphdr->tot_len ); } int OIPPacket::id() const { return EXTRACT_16BITS( &_iphdr->id ); } int OIPPacket::offset() const { return EXTRACT_16BITS( &_iphdr->frag_off ); } int OIPPacket::ttl() const { return _iphdr->ttl; } int OIPPacket::protocol() const { return _iphdr->protocol; } int OIPPacket::checksum() const { return EXTRACT_16BITS( &_iphdr->check ); } /*====================================================================================== * OARPPacket *======================================================================================*/ OARPPacket::OARPPacket( const unsigned char* end, const struct myarphdr* data, QObject* parent ) :QObject( parent, "ARP" ), _arphdr( data ) { qDebug( "OARPPacket::OARPPacket(): decoding ARP header..." ); qDebug( "ARP type seems to be %02d - '%s'", EXTRACT_16BITS( &_arphdr->ar_op ), (const char*) type() ); qDebug( "Sender: MAC %s = IP %s", (const char*) senderMacAddress().toString(), (const char*) senderIPV4Address().toString() ); qDebug( "Target: MAC %s = IP %s", (const char*) targetMacAddress().toString(), (const char*) targetIPV4Address().toString() ); } OARPPacket::~OARPPacket() { } QString OARPPacket::type() const { switch ( EXTRACT_16BITS( &_arphdr->ar_op ) ) { case 1: return "REQUEST"; case 2: return "REPLY"; case 3: return "RREQUEST"; case 4: return "RREPLY"; case 8: return "InREQUEST"; case 9: return "InREPLY"; case 10: return "NAK"; default: qWarning( "OARPPacket::type(): invalid ARP type!" ); return "<unknown>"; } } QHostAddress OARPPacket::senderIPV4Address() const { return EXTRACT_32BITS( &_arphdr->ar_sip ); } QHostAddress OARPPacket::targetIPV4Address() const { return EXTRACT_32BITS( &_arphdr->ar_tip ); } OMacAddress OARPPacket::senderMacAddress() const { return OMacAddress( _arphdr->ar_sha ); } OMacAddress OARPPacket::targetMacAddress() const { return OMacAddress( _arphdr->ar_tha ); } /*====================================================================================== * OUDPPacket *======================================================================================*/ OUDPPacket::OUDPPacket( const unsigned char* end, const struct udphdr* data, QObject* parent ) :QObject( parent, "UDP" ), _udphdr( data ) { qDebug( "OUDPPacket::OUDPPacket(): decoding UDP header..." ); qDebug( "fromPort = %d", fromPort() ); qDebug( " toPort = %d", toPort() ); // TODO: Make this a case or a hash if we know more udp protocols if ( fromPort() == UDP_PORT_BOOTPS || fromPort() == UDP_PORT_BOOTPC || toPort() == UDP_PORT_BOOTPS || toPort() == UDP_PORT_BOOTPC ) { qDebug( "seems to be part of a DHCP conversation => creating DHCP packet." ); new ODHCPPacket( end, (const struct dhcp_packet*) (data+1), this ); } } OUDPPacket::~OUDPPacket() { } int OUDPPacket::fromPort() const { return EXTRACT_16BITS( &_udphdr->source ); } int OUDPPacket::toPort() const { return EXTRACT_16BITS( &_udphdr->dest ); } int OUDPPacket::length() const { return EXTRACT_16BITS( &_udphdr->len ); } int OUDPPacket::checksum() const { return EXTRACT_16BITS( &_udphdr->check ); } /*====================================================================================== * ODHCPPacket *======================================================================================*/ ODHCPPacket::ODHCPPacket( const unsigned char* end, const struct dhcp_packet* data, QObject* parent ) :QObject( parent, "DHCP" ), _dhcphdr( data ) { qDebug( "ODHCPPacket::ODHCPPacket(): decoding DHCP information..." ); qDebug( "DHCP opcode seems to be %02d - '%s'", _dhcphdr->op, isRequest() ? "REQUEST" : "REPLY" ); qDebug( "clientAddress: %s", (const char*) clientAddress().toString() ); qDebug( " yourAddress: %s", (const char*) yourAddress().toString() ); qDebug( "serverAddress: %s", (const char*) serverAddress().toString() ); qDebug( " relayAddress: %s", (const char*) relayAddress().toString() ); qDebug( "parsing DHCP options..." ); _type = 0; const unsigned char* option = &_dhcphdr->options[4]; char tag = -1; char len = -1; while ( ( tag = *option++ ) != -1 /* end of option field */ ) { len = *option++; qDebug( "recognized DHCP option #%d, length %d", tag, len ); if ( tag == DHO_DHCP_MESSAGE_TYPE ) _type = *option; option += len; if ( option >= end ) { qWarning( "DHCP parsing ERROR: sanity check says the packet is at its end!" ); break; } } qDebug( "DHCP type seems to be '%s'", (const char*) type() ); } ODHCPPacket::~ODHCPPacket() { } bool ODHCPPacket::isRequest() const { return ( _dhcphdr->op == 01 ); } bool ODHCPPacket::isReply() const { return ( _dhcphdr->op == 02 ); } QString ODHCPPacket::type() const { switch ( _type ) { case 1: return "DISCOVER"; case 2: return "OFFER"; case 3: return "REQUEST"; case 4: return "DECLINE"; case 5: return "ACK"; case 6: return "NAK"; case 7: return "RELEASE"; case 8: return "INFORM"; default: qWarning( "ODHCPPacket::type(): invalid DHCP type (%d) !", _dhcphdr->op ); return "<unknown>"; } } QHostAddress ODHCPPacket::clientAddress() const { return EXTRACT_32BITS( &_dhcphdr->ciaddr ); } QHostAddress ODHCPPacket::yourAddress() const { return EXTRACT_32BITS( &_dhcphdr->yiaddr ); } QHostAddress ODHCPPacket::serverAddress() const { return EXTRACT_32BITS( &_dhcphdr->siaddr ); } QHostAddress ODHCPPacket::relayAddress() const { return EXTRACT_32BITS( &_dhcphdr->giaddr ); } OMacAddress ODHCPPacket::clientMacAddress() const { return OMacAddress( _dhcphdr->chaddr ); } /*====================================================================================== * OTCPPacket *======================================================================================*/ 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() { } int OTCPPacket::fromPort() const { return EXTRACT_16BITS( &_tcphdr->source ); } int OTCPPacket::toPort() const { return EXTRACT_16BITS( &_tcphdr->dest ); } int OTCPPacket::seq() const { return EXTRACT_16BITS( &_tcphdr->seq ); } int OTCPPacket::ack() const { return EXTRACT_16BITS( &_tcphdr->ack_seq ); } int OTCPPacket::window() const { return EXTRACT_16BITS( &_tcphdr->window ); } int OTCPPacket::checksum() const { return EXTRACT_16BITS( &_tcphdr->check ); } /*====================================================================================== * OPrismHeaderPacket *======================================================================================*/ OPrismHeaderPacket::OPrismHeaderPacket( const unsigned char* end, const struct prism_hdr* data, QObject* parent ) :QObject( parent, "Prism" ), _header( data ) { qDebug( "OPrismHeaderPacket::OPrismHeaderPacket(): decoding PRISM header..." ); qDebug( "Signal Strength = %d", data->signal.data ); new OWaveLanPacket( end, (const struct ieee_802_11_header*) (data+1), this ); } OPrismHeaderPacket::~OPrismHeaderPacket() { } unsigned int OPrismHeaderPacket::signalStrength() const { return _header->signal.data; } /*====================================================================================== * OWaveLanPacket *======================================================================================*/ 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( "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_control_header*) data, this ); break; default: qDebug( "OWaveLanPacket::OWaveLanPacket(): Warning: Unknown major type '%d'!", type() ); } } OWaveLanPacket::~OWaveLanPacket() { } int OWaveLanPacket::duration() const { return _wlanhdr->duration; } OMacAddress OWaveLanPacket::macAddress1() const { return OMacAddress( _wlanhdr->mac1 ); } OMacAddress OWaveLanPacket::macAddress2() const { return OMacAddress( _wlanhdr->mac2 ); } OMacAddress OWaveLanPacket::macAddress3() const { return OMacAddress( _wlanhdr->mac3 ); } OMacAddress OWaveLanPacket::macAddress4() const { return OMacAddress( _wlanhdr->mac4 ); } int OWaveLanPacket::subType() const { return FC_SUBTYPE( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) ); } int OWaveLanPacket::type() const { return FC_TYPE( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) ); } int OWaveLanPacket::version() const { return FC_VERSION( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) ); } bool OWaveLanPacket::fromDS() const { return FC_FROM_DS( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) ); } bool OWaveLanPacket::toDS() const { return FC_TO_DS( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) ); } bool OWaveLanPacket::usesPowerManagement() const { return FC_POWER_MGMT( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) ); } bool OWaveLanPacket::usesWep() const { return FC_WEP( EXTRACT_LE_16BITS( &_wlanhdr->frame_control ) ); } /*====================================================================================== * 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..." ); 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; 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::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 ) ) ); |