summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opienet/802_11_user.h14
-rw-r--r--libopie2/opienet/onetwork.cpp5
-rw-r--r--libopie2/opienet/opcap.cpp31
-rw-r--r--libopie2/opienet/opcap.h19
4 files changed, 67 insertions, 2 deletions
diff --git a/libopie2/opienet/802_11_user.h b/libopie2/opienet/802_11_user.h
index f596bd8..cd98503 100644
--- a/libopie2/opienet/802_11_user.h
+++ b/libopie2/opienet/802_11_user.h
@@ -244,200 +244,214 @@ struct ieee_802_11_mgmt_header {
struct ieee_802_11_data_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];
};
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;
u_int8_t length;
u_char ssid[33]; /* 32 + 1 for null */
};
struct rates_t {
u_int8_t element_id;
u_int8_t length;
u_int8_t rate[8];
};
struct challenge_t {
u_int8_t element_id;
u_int8_t length;
u_int8_t text[254]; /* 1-253 + 1 for null */
};
struct fh_t {
u_int8_t element_id;
u_int8_t length;
u_int16_t dwell_time;
u_int8_t hop_set;
u_int8_t hop_pattern;
u_int8_t hop_index;
};
struct ds_t {
u_int8_t element_id;
u_int8_t length;
u_int8_t channel;
};
struct cf_t {
u_int8_t element_id;
u_int8_t length;
u_int8_t count;
u_int8_t period;
u_int16_t max_duration;
u_int16_t dur_remaing;
};
struct tim_t {
u_int8_t element_id;
u_int8_t length;
u_int8_t count;
u_int8_t period;
u_int8_t bitmap_control;
u_int8_t bitmap[251];
};
struct ibss_t {
u_int8_t element_id;
u_int8_t length;
u_int16_t atim_window;
};
#define E_SSID 0
#define E_RATES 1
#define E_FH 2
#define E_DS 3
#define E_CF 4
#define E_TIM 5
#define E_IBSS 6
#define E_CHALLENGE 16
#define E_CISCO 133
struct ieee_802_11_mgmt_body {
u_int8_t timestamp[8];
u_int16_t beacon_interval;
// u_int16_t listen_interval;
// u_int16_t status_code;
// u_int16_t aid;
// u_char ap[6];
// u_int16_t reason_code;
// u_int16_t auth_alg;
// u_int16_t auth_trans_seq_num;
// struct challenge_t challenge;
u_int16_t capability_info;
// struct ssid_t ssid;
// struct rates_t rates;
// struct ds_t ds;
// struct cf_t cf;
// struct fh_t fh;
// struct tim_t tim;
};
+/* a 802.11 value */
+struct val_80211 {
+ unsigned int did;
+ unsigned short status, len;
+ unsigned int data;
+};
+
+/* header attached during prism monitor mode */
+struct prism_hdr {
+ unsigned int msgcode, msglen;
+ char devname[16];
+ struct val_80211 hosttime, mactime, channel, rssi, sq, signal,
+ noise, rate, istx, frmlen;
+};
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];
};
#define CTRL_RTS_LEN (2+2+6+6+4)
struct ctrl_cts_t {
u_int16_t fc;
u_int16_t duration;
u_int8_t ra[6];
u_int8_t fcs[4];
};
#define CTRL_CTS_LEN (2+2+6+4)
struct ctrl_ack_t {
u_int16_t fc;
u_int16_t duration;
u_int8_t ra[6];
u_int8_t fcs[4];
};
#define CTRL_ACK_LEN (2+2+6+4)
struct ctrl_ps_poll_t {
u_int16_t fc;
u_int16_t aid;
u_int8_t bssid[6];
u_int8_t ta[6];
u_int8_t fcs[4];
};
#define CTRL_PS_POLL_LEN (2+2+6+6+4)
struct ctrl_end_t {
u_int16_t fc;
u_int16_t duration;
u_int8_t ra[6];
u_int8_t bssid[6];
u_int8_t fcs[4];
};
#define CTRL_END_LEN (2+2+6+6+4)
struct ctrl_end_ack_t {
u_int16_t fc;
u_int16_t duration;
u_int8_t ra[6];
u_int8_t bssid[6];
u_int8_t fcs[4];
};
#define CTRL_END_ACK_LEN (2+2+6+6+4)
#define IV_IV(iv) ((iv) & 0xFFFFFF)
#define IV_PAD(iv) (((iv) >> 24) & 0x3F)
#define IV_KEYID(iv) (((iv) >> 30) & 0x03)
#endif
diff --git a/libopie2/opienet/onetwork.cpp b/libopie2/opienet/onetwork.cpp
index be2736a..95e7043 100644
--- a/libopie2/opienet/onetwork.cpp
+++ b/libopie2/opienet/onetwork.cpp
@@ -526,257 +526,258 @@ void OWirelessNetworkInterface::buildChannelList()
struct iw_range range;
memcpy( &range, buffer, sizeof range );
qDebug( "OWirelessNetworkInterface::buildChannelList(): Interface %s reported to have %d channels.", name(), range.num_frequency );
for ( int i = 0; i < range.num_frequency; ++i )
{
int freq = (int) ( double( range.freq[i].m ) * pow( 10.0, range.freq[i].e ) / 1000000.0 );
_channels.insert( freq, i+1 );
}
}
qDebug( "OWirelessNetworkInterface::buildChannelList(): Channel list constructed." );
free(buffer);
}
void OWirelessNetworkInterface::buildPrivateList()
{
qDebug( "OWirelessNetworkInterface::buildPrivateList()" );
struct iw_priv_args priv[IW_MAX_PRIV_DEF];
_iwr.u.data.pointer = (char*) &priv;
_iwr.u.data.length = IW_MAX_PRIV_DEF; // length in terms of number of (sizeof iw_priv_args), not (sizeof iw_priv_args) itself
_iwr.u.data.flags = 0;
if ( !wioctl( SIOCGIWPRIV ) )
{
qDebug( "OWirelessNetworkInterface::buildPrivateList(): SIOCGIWPRIV failed (%s) - can't get private ioctl information.", strerror( errno ) );
return;
}
for ( int i = 0; i < _iwr.u.data.length; ++i )
{
new OPrivateIOCTL( this, priv[i].name, priv[i].cmd, priv[i].get_args, priv[i].set_args );
}
qDebug( "OWirelessNetworkInterface::buildPrivateList(): Private IOCTL list constructed." );
}
int OWirelessNetworkInterface::channel() const
{
//FIXME: When monitoring enabled, then use it
//FIXME: to gather the current RF channel
//FIXME: Until then, get active channel from hopper.
if ( _hopper && _hopper->isActive() )
return _hopper->channel();
if ( !wioctl( SIOCGIWFREQ ) )
{
return -1;
}
else
{
return _channels[ static_cast<int>(double( _iwr.u.freq.m ) * pow( 10.0, _iwr.u.freq.e ) / 1000000) ];
}
}
void OWirelessNetworkInterface::setChannel( int c ) const
{
if ( !_mon )
{
memset( &_iwr, 0, sizeof( struct iwreq ) );
_iwr.u.freq.m = c;
_iwr.u.freq.e = 0;
wioctl( SIOCSIWFREQ );
}
else
{
_mon->setChannel( c );
}
}
double OWirelessNetworkInterface::frequency() const
{
if ( !wioctl( SIOCGIWFREQ ) )
{
return -1.0;
}
else
{
return double( _iwr.u.freq.m ) * pow( 10.0, _iwr.u.freq.e ) / 1000000000.0;
}
}
int OWirelessNetworkInterface::channels() const
{
return _channels.count();
}
void OWirelessNetworkInterface::setChannelHopping( int interval )
{
if ( !_hopper ) _hopper = new OChannelHopper( this );
_hopper->setInterval( interval );
//FIXME: When and by whom will the channel hopper be deleted?
//TODO: rely on QObject hierarchy
}
int OWirelessNetworkInterface::channelHopping() const
{
return _hopper->interval();
}
OChannelHopper* OWirelessNetworkInterface::channelHopper() const
{
return _hopper;
}
void OWirelessNetworkInterface::setMonitorMode( bool b )
{
if ( _mon )
_mon->setEnabled( b );
else
qDebug( "ONetwork(): can't switch monitor mode without installed monitoring interface" );
}
bool OWirelessNetworkInterface::monitorMode() const
{
qDebug( "dataLinkType = %d", dataLinkType() );
- return dataLinkType() == ARPHRD_IEEE80211;
+ return ( dataLinkType() == ARPHRD_IEEE80211 || dataLinkType() == 802 );
+ // 802 is the header type for PRISM - Linux support for this is pending...
}
QString OWirelessNetworkInterface::nickName() const
{
char str[IW_ESSID_MAX_SIZE];
_iwr.u.data.pointer = &str[0];
_iwr.u.data.length = IW_ESSID_MAX_SIZE;
if ( !wioctl( SIOCGIWNICKN ) )
{
return "<unknown>";
}
else
{
str[_iwr.u.data.length] = 0x0; // some drivers (e.g. wlan-ng) don't zero-terminate the string
return str;
}
}
void OWirelessNetworkInterface::setPrivate( const QString& call, int numargs, ... )
{
OPrivateIOCTL* priv = static_cast<OPrivateIOCTL*>( child( (const char*) call ) );
if ( !priv )
{
qDebug( "OWirelessNetworkInterface::setPrivate(): interface '%s' does not support private ioctl '%s'", name(), (const char*) call );
return;
}
if ( priv->numberSetArgs() != numargs )
{
qDebug( "OWirelessNetworkInterface::setPrivate(): parameter count not matching. '%s' expects %d arguments, but got %d", (const char*) call, priv->numberSetArgs(), numargs );
return;
}
qDebug( "OWirelessNetworkInterface::setPrivate(): about to call '%s' on interface '%s'", (const char*) call, name() );
memset( &_iwr, 0, sizeof _iwr );
va_list argp;
va_start( argp, numargs );
for ( int i = 0; i < numargs; ++i )
{
priv->setParameter( i, va_arg( argp, int ) );
}
va_end( argp );
priv->invoke();
}
void OWirelessNetworkInterface::getPrivate( const QString& call )
{
qWarning( "OWirelessNetworkInterface::getPrivate() is not implemented yet." );
}
bool OWirelessNetworkInterface::hasPrivate( const QString& call )
{
return child( (const char*) call );
}
QString OWirelessNetworkInterface::SSID() const
{
char str[IW_ESSID_MAX_SIZE];
_iwr.u.essid.pointer = &str[0];
_iwr.u.essid.length = IW_ESSID_MAX_SIZE;
if ( !wioctl( SIOCGIWESSID ) )
{
return "<unknown>";
}
else
{
return str;
}
}
void OWirelessNetworkInterface::setSSID( const QString& ssid )
{
_iwr.u.essid.pointer = const_cast<char*>( (const char*) ssid );
_iwr.u.essid.length = ssid.length();
wioctl( SIOCSIWESSID );
}
bool OWirelessNetworkInterface::wioctl( int call, struct iwreq& iwreq ) const
{
int result = ::ioctl( _sfd, call, &iwreq );
if ( result == -1 )
qDebug( "ONetworkInterface::wioctl (%s) call %d - Status: Failed: %d (%s)", name(), call, result, strerror( errno ) );
else
qDebug( "ONetworkInterface::wioctl (%s) call %d - Status: Ok.", name(), call );
return ( result != -1 );
}
bool OWirelessNetworkInterface::wioctl( int call ) const
{
strcpy( _iwr.ifr_name, name() );
return wioctl( call, _iwr );
}
/*======================================================================================
* OMonitoringInterface
*======================================================================================*/
OMonitoringInterface::OMonitoringInterface( ONetworkInterface* iface )
:_if( static_cast<OWirelessNetworkInterface*>( iface ) )
{
}
OMonitoringInterface::~OMonitoringInterface()
{
}
void OMonitoringInterface::setChannel( int c )
{
// use standard WE channel switching protocol
memset( &_if->_iwr, 0, sizeof( struct iwreq ) );
_if->_iwr.u.freq.m = c;
_if->_iwr.u.freq.e = 0;
_if->wioctl( SIOCSIWFREQ );
}
bool OMonitoringInterface::enabled() const
{
@@ -808,149 +809,149 @@ OCiscoMonitoringInterface::~OCiscoMonitoringInterface()
void OCiscoMonitoringInterface::setEnabled( bool b )
{
QString fname;
fname.sprintf( "/proc/driver/aironet/%s", (const char*) _if->name() );
QFile f( fname );
if ( !f.exists() ) return;
if ( f.open( IO_WriteOnly ) )
{
QTextStream s( &f );
s << "Mode: r";
s << "Mode: y";
s << "XmitPower: 1";
}
// flushing and closing will be done automatically when f goes out of scope
}
QString OCiscoMonitoringInterface::name() const
{
return "cisco";
}
void OCiscoMonitoringInterface::setChannel( int )
{
// cisco devices automatically switch channels when in monitor mode
}
/*======================================================================================
* OWlanNGMonitoringInterface
*======================================================================================*/
OWlanNGMonitoringInterface::OWlanNGMonitoringInterface( ONetworkInterface* iface )
:OMonitoringInterface( iface )
{
iface->setMonitoring( this );
}
OWlanNGMonitoringInterface::~OWlanNGMonitoringInterface()
{
}
void OWlanNGMonitoringInterface::setEnabled( bool b )
{
//FIXME: do nothing if its already in the same mode
QString enable = b ? "true" : "false";
QString cmd;
cmd.sprintf( "$(which wlanctl-ng) %s lnxreq_wlansniff channel=%d enable=%s", (const char*) _if->name(), 1, (const char*) enable );
system( cmd );
}
QString OWlanNGMonitoringInterface::name() const
{
return "wlan-ng";
}
void OWlanNGMonitoringInterface::setChannel( int )
{
// wlan-ng devices automatically switch channels when in monitor mode
}
/*======================================================================================
* OHostAPMonitoringInterface
*======================================================================================*/
OHostAPMonitoringInterface::OHostAPMonitoringInterface( ONetworkInterface* iface )
:OMonitoringInterface( iface )
{
iface->setMonitoring( this );
}
OHostAPMonitoringInterface::~OHostAPMonitoringInterface()
{
}
void OHostAPMonitoringInterface::setEnabled( bool b )
{
// IW_MODE_MONITOR was introduced in Wireless Extensions Version 15
// Wireless Extensions < Version 15 need iwpriv commandos for monitoring
//TODO: check wireless extensions version on runtime and use
//TODO: SIOCSIWMODE( IW_MODE_MONITOR ) if running on WE >= 15
if ( b )
{
_if->setPrivate( "monitor", 1, 2 );
}
else
{
_if->setPrivate( "monitor", 1, 0 );
}
}
QString OHostAPMonitoringInterface::name() const
{
return "hostap";
}
/*======================================================================================
* OOrinocoNetworkInterface
*======================================================================================*/
OOrinocoMonitoringInterface::OOrinocoMonitoringInterface( ONetworkInterface* iface )
:OMonitoringInterface( iface )
{
iface->setMonitoring( this );
}
OOrinocoMonitoringInterface::~OOrinocoMonitoringInterface()
{
}
void OOrinocoMonitoringInterface::setChannel( int c )
{
- _if->setPrivate( "monitor", 2, 2, c );
+ _if->setPrivate( "monitor", 2, 1, c );
}
void OOrinocoMonitoringInterface::setEnabled( bool b )
{
if ( b )
{
setChannel( 1 );
}
else
{
_if->setPrivate( "monitor", 2, 0, 0 );
}
}
QString OOrinocoMonitoringInterface::name() const
{
return "orinoco";
}
diff --git a/libopie2/opienet/opcap.cpp b/libopie2/opienet/opcap.cpp
index e362883..675818e 100644
--- a/libopie2/opienet/opcap.cpp
+++ b/libopie2/opienet/opcap.cpp
@@ -1,446 +1,477 @@
/*
                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>
=.
.=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>
/*======================================================================================
* 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 '%s'!", 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();
}
}
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: { 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()
{
}
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 );
}
/*======================================================================================
* OUDPPacket
*======================================================================================*/
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 unsigned char* end, const struct tcphdr* data, QObject* parent )
:QObject( parent, "TCP" ), _tcphdr( data )
{
qDebug( "OTCPPacket::OTCPPacket(): decoding TCP header..." );
}
OTCPPacket::~OTCPPacket()
{
}
/*======================================================================================
+ * 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;
diff --git a/libopie2/opienet/opcap.h b/libopie2/opienet/opcap.h
index fe88e68..83f7115 100644
--- a/libopie2/opienet/opcap.h
+++ b/libopie2/opienet/opcap.h
@@ -30,256 +30,275 @@
Boston, MA 02111-1307, USA.
*/
#ifndef OPCAP_H
#define OPCAP_H
/* LINUX */
extern "C" // work around a bpf/pcap conflict in recent headers
{
#include <pcap.h>
}
#include <netinet/ether.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <time.h>
/* QT */
#include <qevent.h>
#include <qfile.h>
#include <qhostaddress.h>
#include <qobject.h>
#include <qstring.h>
#include <qmap.h>
/* OPIE */
#include <opie2/onetutils.h>
#include "802_11_user.h"
/* TYPEDEFS */
typedef struct timeval timevalstruct;
typedef struct pcap_pkthdr packetheaderstruct;
/* FORWARDS */
class OPacketCapturer;
class QSocketNotifier;
/*======================================================================================
* OPacket - A frame on the wire
*======================================================================================*/
/** @brief A class representing a data frame on the wire.
*
* The whole family of the packet classes are used when capturing frames from a network.
* Most standard network protocols in use share a common architecture, which mostly is
* a packet header and then the packet payload. In layered architectures, each lower layer
* encapsulates data from its upper layer - that is it
* treats the data from its upper layer as payload and prepends an own header to the packet,
* which - again - is treated as the payload for the layer below. The figure below is an
* example for how such a data frame is composed out of packets, e.g. when sending a mail.
*
* <pre>
* | User Data | == Mail Data
* | SMTP Header | User Data | == SMTP
* | TCP Header | SMTP Header | User Data | == TCP
* | IP Header | TCP Header | SMTP Header | User Data | == IP
* | MAC Header | IP Header | TCP Header | SMTP Header | User Data | == MAC
*
* </pre>
*
* The example is trimmed for simplicity, because the MAC (Medium Access Control) layer
* also contains a few more levels of encapsulation.
* Since the type of the payload is more or less independent from the encapsulating protocol,
* the header must be inspected before attempting to decode the payload. Hence, the
* encapsulation level varies and can't be deduced without actually looking into the packets.
*
* For actually working with captured frames, it's useful to identify the packets via names and
* insert them into a parent/child - relationship based on the encapsulation. This is why
* all packet classes derive from QObject. The amount of overhead caused by the QObject is
* not a problem in this case, because we're talking about a theoratical maximum of about
* 10 packets per captured frame. We need to stuff them into a searchable list anyway and the
* QObject also cares about destroying the sub-, (child-) packets.
*
* This enables us to perform a simple look for packets of a certain type:
* @code
* OPacketCapturer* pcap = new OPacketCapturer();
* pcap->open( "eth0" );
* OPacket* p = pcap->next();
* OIPPacket* ip = (OIPPacket*) p->child( "IP" ); // returns 0, if no such child exists
* odebug << "got ip packet from " << ip->fromIPAddress().toString() << " to " << ip->toIPAddress().toString() << oendl;
*
*/
class OPacket : public QObject
{
Q_OBJECT
public:
OPacket( int datalink, packetheaderstruct, const unsigned char*, QObject* parent );
virtual ~OPacket();
timevalstruct timeval() const;
int caplen() const;
int len() const;
QString dump( int = 32 ) const;
void updateStats( QMap<QString,int>&, QObjectList* );
private:
const packetheaderstruct _hdr; // pcap packet header
const unsigned char* _data; // pcap packet data
const unsigned char* _end; // end of pcap packet data
};
/*======================================================================================
* OEthernetPacket - DLT_EN10MB frame
*======================================================================================*/
class OEthernetPacket : public QObject
{
Q_OBJECT
public:
OEthernetPacket( const unsigned char*, const struct ether_header*, QObject* parent = 0 );
virtual ~OEthernetPacket();
OMacAddress sourceAddress() const;
OMacAddress destinationAddress() const;
int type() const;
private:
const struct ether_header* _ether;
};
/*======================================================================================
+ * OPrismHeaderPacket - DLT_PRISM_HEADER frame
+ *======================================================================================*/
+
+class OPrismHeaderPacket : public QObject
+{
+ Q_OBJECT
+
+ public:
+ OPrismHeaderPacket( const unsigned char*, const struct prism_hdr*, QObject* parent = 0 );
+ virtual ~OPrismHeaderPacket();
+
+ unsigned int signalStrength() const;
+
+ private:
+ const struct prism_hdr* _header;
+};
+
+
+/*======================================================================================
* OWaveLanPacket - DLT_IEEE802_11 frame
*======================================================================================*/
class OWaveLanPacket : public QObject
{
Q_OBJECT
public:
OWaveLanPacket( const unsigned char*, const struct ieee_802_11_header*, QObject* parent = 0 );
virtual ~OWaveLanPacket();
int duration() const;
bool fromDS() const;
bool toDS() const;
virtual OMacAddress macAddress1() const;
virtual OMacAddress macAddress2() const;
virtual OMacAddress macAddress3() const;
virtual OMacAddress macAddress4() const;
bool usesPowerManagement() const;
int type() const;
int subType() const;
int version() const;
bool usesWep() const;
private:
const struct ieee_802_11_header* _wlanhdr;
};
/*======================================================================================
* OWaveLanManagementPacket - type: management (T_MGMT)
*======================================================================================*/
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;
private:
const struct ieee_802_11_mgmt_header* _header;
const struct ieee_802_11_mgmt_body* _body;
};
/*======================================================================================
* OWaveLanManagementSSID
*======================================================================================*/
class OWaveLanManagementSSID : public QObject
{
Q_OBJECT
public:
OWaveLanManagementSSID( const unsigned char*, const struct ssid_t*, QObject* parent = 0 );
virtual ~OWaveLanManagementSSID();
QString ID() const;
private:
const struct ssid_t* _data;
};
/*======================================================================================
* OWaveLanManagementRates
*======================================================================================*/
class OWaveLanManagementRates : public QObject
{
Q_OBJECT
public:
OWaveLanManagementRates( const unsigned char*, const struct rates_t*, QObject* parent = 0 );
virtual ~OWaveLanManagementRates();
private:
const struct rates_t* _data;
};
/*======================================================================================
* OWaveLanManagementCF
*======================================================================================*/
class OWaveLanManagementCF : public QObject
{
Q_OBJECT
public:
OWaveLanManagementCF( const unsigned char*, const struct cf_t*, QObject* parent = 0 );
virtual ~OWaveLanManagementCF();
private:
const struct cf_t* _data;
};
/*======================================================================================
* OWaveLanManagementFH
*======================================================================================*/
class OWaveLanManagementFH : public QObject
{
Q_OBJECT
public:
OWaveLanManagementFH( const unsigned char*, const struct fh_t*, QObject* parent = 0 );
virtual ~OWaveLanManagementFH();
private:
const struct fh_t* _data;
};
/*======================================================================================
* OWaveLanManagementDS
*======================================================================================*/