summaryrefslogtreecommitdiff
path: root/libopie2/opienet/opcap.cpp
authormickeyl <mickeyl>2004-05-02 19:17:27 (UTC)
committer mickeyl <mickeyl>2004-05-02 19:17:27 (UTC)
commit8602449caa5a055bd5f033e3792d0a59a0b41bfa (patch) (side-by-side diff)
tree17f60677ff09e89eb270f1e6cc837687b0eab871 /libopie2/opienet/opcap.cpp
parent3e8fab5fddb3a38d93eaca1a8d69d8f668c7cd99 (diff)
downloadopie-8602449caa5a055bd5f033e3792d0a59a0b41bfa.zip
opie-8602449caa5a055bd5f033e3792d0a59a0b41bfa.tar.gz
opie-8602449caa5a055bd5f033e3792d0a59a0b41bfa.tar.bz2
dump takes less space now
NOTE: I think dump really doesn't belong here
Diffstat (limited to 'libopie2/opienet/opcap.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opienet/opcap.cpp6
1 files changed, 2 insertions, 4 deletions
diff --git a/libopie2/opienet/opcap.cpp b/libopie2/opienet/opcap.cpp
index 8ec4f47..8184f21 100644
--- a/libopie2/opienet/opcap.cpp
+++ b/libopie2/opienet/opcap.cpp
@@ -1,682 +1,680 @@
/*
                This file is part of the Opie Project
              Copyright (C) 2003-2004 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.
*/
#include "udp_ports.h"
#include "opcap.h"
/* OPIE */
#include <opie2/odebug.h>
using namespace Opie::Core;
/* QT */
#include <qapplication.h> // don't use oapplication here (will decrease reusability in other projects)
#include <qsocketnotifier.h>
#include <qobjectlist.h>
/* STD */
#include <sys/time.h>
#include <sys/types.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
namespace Opie {
namespace Net {
/*======================================================================================
* OPacket
*======================================================================================*/
OPacket::OPacket( int datalink, packetheaderstruct header, const unsigned char* data, QObject* parent )
:QObject( parent, "Generic" ), _hdr( header ), _data( 0 )
{
_data = new unsigned char[ header.len ];
assert( _data );
memcpy( const_cast<unsigned char*>(_data), data, header.len );
// We have to copy the data structure here, because the 'data' pointer handed by libpcap
// points to an internal region which is reused by lipcap.
odebug << "OPacket: Length = " << header.len << ", Caplen = " << header.caplen << oendl;
_end = (unsigned char*) _data + header.len;
switch ( datalink )
{
case DLT_EN10MB:
odebug << "OPacket::OPacket(): Received Packet. Datalink = ETHERNET" << oendl;
new OEthernetPacket( _end, (const struct ether_header*) _data, this );
break;
case DLT_IEEE802_11:
odebug << "OPacket::OPacket(): Received Packet. Datalink = IEEE802.11" << oendl;
new OWaveLanPacket( _end, (const struct ieee_802_11_header*) _data, this );
break;
case DLT_PRISM_HEADER:
odebug << "OPacket::OPacket(): Received Packet. Datalink = PRISM_HEADER" << oendl;
new OPrismHeaderPacket( _end, (const struct prism_hdr*) (unsigned char*) _data, this );
break;
default:
owarn << "OPacket::OPacket(): Received Packet over unsupported datalink, type " << datalink << "!" << oendl;
}
}
OPacket::~OPacket()
{
odebug << "~OPacket( " << name() << " )" << oendl;
delete _data;
}
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();
}
}
QString OPacket::dumpStructure() const
{
return "[ |" + _dumpStructure( const_cast<QObjectList*>( this->children() ) ) + " ]";
}
QString OPacket::_dumpStructure( QObjectList* l ) const
{
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 str( "000:" );
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 );
+ tmp.sprintf( "%03X:", 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;
}
QTextStream& operator<<( QTextStream& s, const OPacket& p )
{
s << p.dumpStructure();
}
/*======================================================================================
* OEthernetPacket
*======================================================================================*/
OEthernetPacket::OEthernetPacket( const unsigned char* end, const struct ether_header* data, QObject* parent )
:QObject( parent, "Ethernet" ), _ether( data )
{
odebug << "Source = " << sourceAddress().toString() << oendl;
odebug << "Destination = " << destinationAddress().toString() << oendl;
if ( sourceAddress() == OMacAddress::broadcast )
odebug << "Source is broadcast address" << oendl;
if ( destinationAddress() == OMacAddress::broadcast )
odebug << "Destination is broadcast address" << oendl;
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: { odebug << "OPacket::OPacket(): Received Ethernet Packet : Type = RARP" << oendl; break; }
default: odebug << "OPacket::OPacket(): Received Ethernet Packet : Type = UNKNOWN" << oendl;
}
}
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 )
{
odebug << "OIPPacket::OIPPacket(): decoding IP header..." << oendl;
odebug << "FromAddress = " << fromIPAddress().toString() << oendl;
odebug << " toAddress = " << toIPAddress().toString() << oendl;
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: odebug << "OIPPacket::OIPPacket(): unknown IP protocol, type = " << protocol() << oendl;
}
}
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 )
{
odebug << "OARPPacket::OARPPacket(): decoding ARP header..." << oendl;
odebug << "ARP type seems to be " << EXTRACT_16BITS( &_arphdr->ar_op ) << " = " << type() << oendl;
odebug << "Sender: MAC " << senderMacAddress().toString() << " = IP " << senderIPV4Address().toString() << oendl;
odebug << "Target: MAC " << targetMacAddress().toString() << " = IP " << targetIPV4Address().toString() << oendl;
}
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: owarn << "OARPPacket::type(): invalid ARP type!" << oendl; 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 )
{
odebug << "OUDPPacket::OUDPPacket(): decoding UDP header..." << oendl;
odebug << "fromPort = " << fromPort() << oendl;
odebug << " toPort = " << toPort() << oendl;
// 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 )
{
odebug << "seems to be part of a DHCP conversation => creating DHCP packet." << oendl;
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 )
{
odebug << "ODHCPPacket::ODHCPPacket(): decoding DHCP information..." << oendl;
odebug << "DHCP opcode seems to be " << _dhcphdr->op << ": " << ( isRequest() ? "REQUEST" : "REPLY" ) << oendl;
odebug << "clientAddress = " << clientAddress().toString() << oendl;
odebug << " yourAddress = " << yourAddress().toString() << oendl;
odebug << "serverAddress = " << serverAddress().toString() << oendl;
odebug << " relayAddress = " << relayAddress().toString() << oendl;
odebug << "parsing DHCP options..." << oendl;
_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++;
odebug << "recognized DHCP option #" << tag << ", length " << len << oendl;
if ( tag == DHO_DHCP_MESSAGE_TYPE )
_type = *option;
option += len;
if ( option >= end )
{
owarn << "DHCP parsing ERROR: sanity check says the packet is at its end!" << oendl;
break;
}
}
odebug << "DHCP type seems to be << " << type() << oendl;
}
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: owarn << "ODHCPPacket::type(): invalid DHCP type " << _dhcphdr->op << oendl; 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 )
{
odebug << "OTCPPacket::OTCPPacket(): decoding TCP header..." << oendl;
}
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 )
{
odebug << "OPrismHeaderPacket::OPrismHeaderPacket(): decoding PRISM header..." << oendl;
odebug << "Signal Strength = " << data->signal.data << oendl;
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 )
{
odebug << "OWaveLanPacket::OWaveLanPacket(): decoding IEEE 802.11 header..." << oendl;
odebug << "type = " << type() << oendl;
odebug << "subType = " << subType() << oendl;
odebug << "duration = " << duration() << oendl;
odebug << "powermanagement = " << usesPowerManagement() << oendl;
odebug << "payload is encrypted = " << ( usesWep() ? "yes" : "no" ) << oendl;
odebug << "MAC1 = " << macAddress1().toString() << oendl;
odebug << "MAC2 = " << macAddress2().toString() << oendl;
odebug << "MAC3 = " << macAddress3().toString() << oendl;
odebug << "MAC4 = " << macAddress4().toString() << oendl;
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: odebug << "OWaveLanPacket::OWaveLanPacket(): Warning: Unknown major type = " << type() << oendl;
}
}
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 );
}