author | mickeyl <mickeyl> | 2003-05-05 14:57:27 (UTC) |
---|---|---|
committer | mickeyl <mickeyl> | 2003-05-05 14:57:27 (UTC) |
commit | 29f5c6e6bcb8db0f0e26da25dbf34b2685c01526 (patch) (side-by-side diff) | |
tree | a05e296ff11d532fd3d5fd092aade07474d1ba95 | |
parent | a5818261bec2d0a6d903fef9baeed1a7abc85275 (diff) | |
download | opie-29f5c6e6bcb8db0f0e26da25dbf34b2685c01526.zip opie-29f5c6e6bcb8db0f0e26da25dbf34b2685c01526.tar.gz opie-29f5c6e6bcb8db0f0e26da25dbf34b2685c01526.tar.bz2 |
- fix segfault on unknown linktype (thanks groucho)
- make capturing using PRISM headers optional
-rw-r--r-- | libopie2/opienet/onetwork.cpp | 31 | ||||
-rw-r--r-- | libopie2/opienet/onetwork.h | 11 | ||||
-rw-r--r-- | libopie2/opienet/opcap.cpp | 2 |
3 files changed, 25 insertions, 19 deletions
diff --git a/libopie2/opienet/onetwork.cpp b/libopie2/opienet/onetwork.cpp index 2dfff1d..6cef5cf 100644 --- a/libopie2/opienet/onetwork.cpp +++ b/libopie2/opienet/onetwork.cpp @@ -716,293 +716,298 @@ QString OWirelessNetworkInterface::nickName() const { 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( ONetworkInterface* iface, bool prismHeader ) + :_if( static_cast<OWirelessNetworkInterface*>( iface ) ), _prismHeader( prismHeader ) { } 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 { return _if->monitorMode(); } void OMonitoringInterface::setEnabled( bool b ) { } /*====================================================================================== * OCiscoMonitoringInterface *======================================================================================*/ -OCiscoMonitoringInterface::OCiscoMonitoringInterface( ONetworkInterface* iface ) - :OMonitoringInterface( iface ) +OCiscoMonitoringInterface::OCiscoMonitoringInterface( ONetworkInterface* iface, bool prismHeader ) + :OMonitoringInterface( iface, prismHeader ) { iface->setMonitoring( this ); } 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 ) +OWlanNGMonitoringInterface::OWlanNGMonitoringInterface( ONetworkInterface* iface, bool prismHeader ) + :OMonitoringInterface( iface, prismHeader ) { 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 prism = _prismHeader ? "true" : "false"; QString cmd; - cmd.sprintf( "$(which wlanctl-ng) %s lnxreq_wlansniff channel=%d enable=%s", (const char*) _if->name(), 1, (const char*) enable ); + cmd.sprintf( "$(which wlanctl-ng) %s lnxreq_wlansniff channel=%d enable=%s prismheader=%s", + (const char*) _if->name(), 1, (const char*) enable, (const char*) prism ); 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 ) +OHostAPMonitoringInterface::OHostAPMonitoringInterface( ONetworkInterface* iface, bool prismHeader ) + :OMonitoringInterface( iface, prismHeader ) { 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 + int monitorCode = _prismHeader ? 1 : 2; + if ( b ) { - _if->setPrivate( "monitor", 1, 2 ); + _if->setPrivate( "monitor", 1, monitorCode ); } else { _if->setPrivate( "monitor", 1, 0 ); } } QString OHostAPMonitoringInterface::name() const { return "hostap"; } /*====================================================================================== * OOrinocoNetworkInterface *======================================================================================*/ -OOrinocoMonitoringInterface::OOrinocoMonitoringInterface( ONetworkInterface* iface ) - :OMonitoringInterface( iface ) +OOrinocoMonitoringInterface::OOrinocoMonitoringInterface( ONetworkInterface* iface, bool prismHeader ) + :OMonitoringInterface( iface, prismHeader ) { iface->setMonitoring( this ); } OOrinocoMonitoringInterface::~OOrinocoMonitoringInterface() { } void OOrinocoMonitoringInterface::setChannel( int c ) { - _if->setPrivate( "monitor", 2, 1, c ); + int monitorCode = _prismHeader ? 1 : 2; + _if->setPrivate( "monitor", 2, monitorCode, 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/onetwork.h b/libopie2/opienet/onetwork.h index 1b38d02..eb9d506 100644 --- a/libopie2/opienet/onetwork.h +++ b/libopie2/opienet/onetwork.h @@ -359,180 +359,181 @@ class OWirelessNetworkInterface : public ONetworkInterface /** * @returns the current IEEE 802.11 operation mode. * Possible values are <ul><li>adhoc<li>managed<li>monitor<li>master or <li>unknown */ virtual QString mode() const; /** * Setting the monitor mode on a wireless network interface enables * listening to IEEE 802.11 data and management frames which normally * are handled by the device firmware. This can be used to detect * other wireless network devices, e.g. Access Points or Ad-hoc stations. * @warning Standard wireless network drives don't support the monitor mode. * @warning You need a patched driver for this to work. * @note Enabling the monitor mode is highly driver dependent and requires * the proper @ref OMonitoringInterface to be associated with the interface. * @see OMonitoringInterface */ virtual void setMonitorMode( bool ); //FIXME: ==> setMode( "monitor" ); /** * @returns true if the device is listening in IEEE 802.11 monitor mode */ virtual bool monitorMode() const; //FIXME: ==> mode() /** * Set the channel hopping @a interval. An @a interval of 0 disables channel hopping. * @see OChannelHopper */ virtual void setChannelHopping( int interval = 0 ); /** * @returns the channel hopping interval or 0, if channel hopping is disabled. */ virtual int channelHopping() const; /** * @returns the @ref OChannelHopper of this interface or 0, if channel hopping has not been activated before */ virtual OChannelHopper* channelHopper() const; /** * Set the station @a nickname. */ virtual void setNickName( const QString& nickname ); /** * @returns the current station nickname. */ virtual QString nickName() const; /** * Invoke the private IOCTL @a command with a @number of parameters on the network interface. * @see OPrivateIOCTL */ virtual void setPrivate( const QString& command, int number, ... ); /** * @returns true if the interface is featuring the private IOCTL @command. */ virtual bool hasPrivate( const QString& command ); virtual void getPrivate( const QString& command ); //FIXME: Implement and document this virtual bool isAssociated() const {}; //FIXME: Implement and document this /** * @returns the MAC address of the Access Point if the * device is in infrastructure mode. @returns a (more or less random) CELL * address if the device is in adhoc mode. */ virtual QString associatedAP() const; /** * Set the @a ssid (Service Set ID) string. This is used to decide * which network to associate with (use "any" to let the driver decide). */ virtual void setSSID( const QString& ssid ); /** * @returns the current SSID (Service Set ID). */ virtual QString SSID() const; protected: void buildChannelList(); void buildPrivateList(); virtual void init(); struct iwreq& iwr() const; bool wioctl( int call ) const; bool wioctl( int call, struct iwreq& ) const; protected: mutable struct iwreq _iwr; QMap<int,int> _channels; private: OChannelHopper* _hopper; }; /*====================================================================================== * OMonitoringInterface *======================================================================================*/ class OMonitoringInterface { public: OMonitoringInterface(); - OMonitoringInterface( ONetworkInterface* ); + OMonitoringInterface( ONetworkInterface*, bool _prismHeader ); virtual ~OMonitoringInterface(); public: virtual void setEnabled( bool ); virtual bool enabled() const; virtual void setChannel( int ); virtual QString name() const = 0; protected: OWirelessNetworkInterface* _if; + bool _prismHeader; }; /*====================================================================================== * OCiscoMonitoring *======================================================================================*/ class OCiscoMonitoringInterface : public OMonitoringInterface { public: - OCiscoMonitoringInterface( ONetworkInterface* ); + OCiscoMonitoringInterface( ONetworkInterface*, bool _prismHeader ); virtual ~OCiscoMonitoringInterface(); virtual void setEnabled( bool ); virtual QString name() const; virtual void setChannel( int ); }; /*====================================================================================== * OWlanNGMonitoringInterface *======================================================================================*/ class OWlanNGMonitoringInterface : public OMonitoringInterface { public: - OWlanNGMonitoringInterface( ONetworkInterface* ); + OWlanNGMonitoringInterface( ONetworkInterface*, bool _prismHeader ); virtual ~OWlanNGMonitoringInterface(); public: virtual void setEnabled( bool ); virtual QString name() const; virtual void setChannel( int ); }; /*====================================================================================== * OHostAPMonitoringInterface *======================================================================================*/ class OHostAPMonitoringInterface : public OMonitoringInterface { public: - OHostAPMonitoringInterface( ONetworkInterface* ); + OHostAPMonitoringInterface( ONetworkInterface*, bool _prismHeader ); virtual ~OHostAPMonitoringInterface(); public: virtual void setEnabled( bool ); virtual QString name() const; }; /*====================================================================================== * OOrinocoMonitoringInterface *======================================================================================*/ class OOrinocoMonitoringInterface : public OMonitoringInterface { public: - OOrinocoMonitoringInterface( ONetworkInterface* ); + OOrinocoMonitoringInterface( ONetworkInterface*, bool _prismHeader ); virtual ~OOrinocoMonitoringInterface(); public: virtual void setChannel( int ); virtual void setEnabled( bool ); virtual QString name() const; }; #endif // ONETWORK_H diff --git a/libopie2/opienet/opcap.cpp b/libopie2/opienet/opcap.cpp index e2ab6d7..f6d05ea 100644 --- a/libopie2/opienet/opcap.cpp +++ b/libopie2/opienet/opcap.cpp @@ -1,170 +1,170 @@ /* 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 ); + 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(); } } 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" ); |