summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--examples/opienet/onetworkdemo/onetworkdemo.cpp5
-rw-r--r--libopie2/opienet/onetutils.h26
-rw-r--r--libopie2/opienet/onetwork.cpp31
-rw-r--r--libopie2/opienet/onetwork.h7
-rw-r--r--libopie2/opienet/opienet.pro2
5 files changed, 60 insertions, 11 deletions
diff --git a/examples/opienet/onetworkdemo/onetworkdemo.cpp b/examples/opienet/onetworkdemo/onetworkdemo.cpp
index e0c93a2..b3a1115 100644
--- a/examples/opienet/onetworkdemo/onetworkdemo.cpp
+++ b/examples/opienet/onetworkdemo/onetworkdemo.cpp
@@ -1,176 +1,181 @@
/*
=. This file is part of the Opie Project
.=l. Copyright (C) 2004 Opie Team <opie-devel@handhelds.org>
.>+-=
_;:, .> :=|. This library 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 library 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/onetwork.h>
#include <opie2/ostation.h>
#include <opie2/omanufacturerdb.h>
#include <opie2/odebug.h>
/* STD */
#include <unistd.h>
using namespace Opie::Net;
int main( int argc, char** argv )
{
odebug << "OPIE Network Demo" << oendl;
ONetwork* net = ONetwork::instance();
ONetwork::InterfaceIterator it = net->iterator();
while ( it.current() )
{
odebug << "DEMO: ONetwork contains Interface '" << it.current()->name() << "'" << oendl;
+ ONetworkInterfaceDriverInfo info = it.current()->driverInfo();
+ odebug << "DEMO: DriverName reported as '" << info.name() << "'" << oendl;
+ odebug << "DEMO: DriverVersion reported as '" << info.version() << "'" << oendl;
+ odebug << "DEMO: DriverFirmware reported as '" << info.firmware() << "'" << oendl;
+ odebug << "DEMO: DriverBus reported as '" << info.bus() << "'" << oendl;
odebug << "DEMO: Datalink code is '" << it.current()->dataLinkType() << "'" << oendl;
odebug << "DEMO: MAC Address is '" << it.current()->macAddress().toString() << "'" << oendl;
odebug << "DEMO: MAC Address is '" << it.current()->macAddress().toString(true) << "'" << oendl;
odebug << "DEMO: MAC Manufacturer seems to be '" << it.current()->macAddress().manufacturer() << "'" << oendl;
odebug << "DEMO: Manufacturertest1 = '" << OManufacturerDB::instance()->lookupExt( "08:00:87" ) << "'" << oendl;
odebug << "DEMO: Manufacturertest2 = '" << OManufacturerDB::instance()->lookupExt( "E2:0C:0F" ) << "'" << oendl;
odebug << "Demo: IPv4 Address is '" << it.current()->ipV4Address() << "'" << oendl;
if ( it.current()->isWireless() )
{
OWirelessNetworkInterface* iface = static_cast<OWirelessNetworkInterface*>( it.current() );
odebug << "DEMO: '" << iface->name() << "' seems to feature the wireless extensions." << oendl;
odebug << "DEMO: Current SSID is '" << iface->SSID() << "'" << oendl;
odebug << "DEMO: Antenna is tuned to '" << iface->frequency() << "', that is channel " << iface->channel() << "" << oendl;
//if ( iface->mode() == OWirelessNetworkInterface::adhoc )
//{
//odebug << "DEMO: Associated AP has MAC Address '" << iface->associatedAP().toString() << "'" << oendl;
//}
/*
// nickname
odebug << "DEMO: Current NickName is '" << iface->nickName() << "'" << oendl;
iface->setNickName( "MyNickName" );
if ( iface->nickName() != "MyNickName" )
odebug << "DEMO: Warning! Can't change nickname" << oendl;
else
odebug << "DEMO: Nickname change successful." << oendl;
/*
// operation mode
odebug << "DEMO: Current OperationMode is '" << iface->mode() << "'" << oendl;
iface->setMode( "adhoc" );
if ( iface->mode() != "adhoc" )
odebug << "DEMO: Warning! Can't change operation mode" << oendl;
else
odebug << "DEMO: Operation Mode change successful." << oendl;
// RF channel
odebug << "DEMO: Current Channel is '" << iface->channel() << "'" << oendl;
iface->setChannel( 1 );
if ( iface->channel() != 1 )
odebug << "DEMO: Warning! Can't change RF channel" << oendl;
else
odebug << "DEMO: RF channel change successful." << oendl;
iface->setMode( "managed" );
*/
/*
// network scan
OStationList* stations = iface->scanNetwork();
if ( stations )
{
odebug << "DEMO: # of stations around = " << stations->count() << "" << oendl;
OStation* station;
for ( station = stations->first(); station != 0; station = stations->next() )
{
odebug << "DEMO: station dump following..." << oendl;
station->dump();
}
}
else
{
odebug << "DEMO: Warning! Scan didn't work!" << oendl;
}
/*
// first some wrong calls to check if this is working
iface->setPrivate( "seppel", 10 );
iface->setPrivate( "monitor", 0 );
// now the real deal
iface->setPrivate( "monitor", 2, 2, 3 );
// trying to set hw address to 12:34:56:AB:CD:EF
/*
OMacAddress addr = OMacAddress::fromString( "12:34:56:AB:CD:EF" );
iface->setUp( false );
iface->setMacAddress( addr );
iface->setUp( true );
odebug << "DEMO: MAC Address now is '" << iface->macAddress().toString() << "'" << oendl;
*/
// monitor test
odebug << "DEMO: current interface mode is '" << iface->mode() << "'" << oendl;
iface->setMode( "monitor" );
odebug << "DEMO: current interface mode is '" << iface->mode() << "'" << oendl;
sleep( 1 );
iface->setChannel( 1 );
iface->setMode( "managed" );
//sleep( 1 );
odebug << "DEMO: current interface mode is '" << iface->mode() << "'" << oendl;
/*iface->setMode( "adhoc" );
sleep( 1 );
odebug << "DEMO: current interface mode is '" << iface->mode() << "'" << oendl;
iface->setMode( "managed" );
sleep( 1 );
odebug << "DEMO: current interface mode is '" << iface->mode() << "'" << oendl;
iface->setMode( "master" );
sleep( 1 );
odebug << "DEMO: current interface mode is '" << iface->mode() << "'" << oendl; */
}
++it;
}
return 0;
}
diff --git a/libopie2/opienet/onetutils.h b/libopie2/opienet/onetutils.h
index 32f5355..25c9238 100644
--- a/libopie2/opienet/onetutils.h
+++ b/libopie2/opienet/onetutils.h
@@ -1,215 +1,241 @@
/*
                This file is part of the Opie Project
              (C) 2003-2005 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; version 2 of the License.
     ._= =}       :
    .%`+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.
*/
#ifndef ONETUTILS_H
#define ONETUTILS_H
#include <qdict.h>
#include <qmap.h>
#include <qstring.h>
#include <qhostaddress.h>
#include <qobject.h>
#include <sys/types.h>
struct ifreq;
namespace Opie {
namespace Net {
class OWirelessNetworkInterface;
/*======================================================================================
* OMacAddress
*======================================================================================*/
class OMacAddress
{
public:
// QString c'tor? -zecke
OMacAddress();
OMacAddress( unsigned char* );
OMacAddress( const unsigned char* );
OMacAddress( struct ifreq& );
~OMacAddress();
QString manufacturer() const;
QString toString( bool substitute = false ) const;
const unsigned char* native() const;
// no c'tor but this one why not make it a c'tor. it could also replace the others or is this the problem?
static OMacAddress fromString( const QString& );
public:
static const OMacAddress& broadcast; // ff:ff:ff:ff:ff:ff
static const OMacAddress& unknown; // 44:44:44:44:44:44
private:
unsigned char _bytes[6];
friend bool operator==( const OMacAddress &m1, const OMacAddress &m2 );
class Private;
Private *d;
};
bool operator==( const OMacAddress &m1, const OMacAddress &m2 );
/*======================================================================================
* OHostAddress
*======================================================================================*/
class OHostAddress : public QHostAddress
{
/*public:
OHostAddress();
~OHostAddress();
*/
private:
class Private;
Private *d;
};
/*======================================================================================
+ * ONetworkInterfaceDriverInfo
+ *======================================================================================*/
+
+class ONetworkInterfaceDriverInfo
+{
+ public:
+ ONetworkInterfaceDriverInfo( const QString& name = "<unknown>",
+ const QString& version = "<unknown>",
+ const QString& firmware = "<unknown>",
+ const QString& bus = "<unknown>" ) :
+ _name( name ), _version( version ), _firmware( firmware ), _bus( bus ) { };
+ ~ONetworkInterfaceDriverInfo() { };
+
+ QString name() const { return _name; };
+ QString version() const { return _version; };
+ QString firmware() const { return _firmware; };
+ QString bus() const { return _bus; };
+
+ private:
+ const QString _name;
+ const QString _version;
+ const QString _firmware;
+ const QString _bus;
+};
+
+/*======================================================================================
* OPrivateIOCTL
*======================================================================================*/
class OPrivateIOCTL : public QObject
{
public:
OPrivateIOCTL( QObject* parent, const char* name, int cmd, int getargs, int setargs );
~OPrivateIOCTL();
int numberGetArgs() const;
int typeGetArgs() const;
int numberSetArgs() const;
int typeSetArgs() const;
// FIXME return int? as ::ioctl does? -zecke
void invoke() const;
void setParameter( int, u_int32_t );
private:
u_int32_t _ioctl;
u_int16_t _getargs;
u_int16_t _setargs;
class Private;
Private *d;
};
/*======================================================================================
* Miscellaneous
*======================================================================================*/
namespace Internal {
void dumpBytes( const unsigned char* data, int num );
QString modeToString( int );
int stringToMode( const QString& );
}
}
}
#define IW_PRIV_TYPE_MASK 0x7000
#define IW_PRIV_TYPE_NONE 0x0000
#define IW_PRIV_TYPE_BYTE 0x1000
#define IW_PRIV_TYPE_CHAR 0x2000
#define IW_PRIV_TYPE_INT 0x4000
#define IW_PRIV_TYPE_FLOAT 0x5000
#define IW_PRIV_TYPE_ADDR 0x6000
#define IW_PRIV_SIZE_FIXED 0x0800
#define IW_PRIV_SIZE_MASK 0x07FF
#define IW_HEADER_TYPE_NULL 0 /* Not available */
#define IW_HEADER_TYPE_CHAR 2 /* char [IFNAMSIZ] */
#define IW_HEADER_TYPE_UINT 4 /* __u32 */
#define IW_HEADER_TYPE_FREQ 5 /* struct iw_freq */
#define IW_HEADER_TYPE_ADDR 6 /* struct sockaddr */
#define IW_HEADER_TYPE_POINT 8 /* struct iw_point */
#define IW_HEADER_TYPE_PARAM 9 /* struct iw_param */
#define IW_HEADER_TYPE_QUAL 10 /* struct iw_quality */
#define IW_EV_POINT_OFF (((char *) &(((struct iw_point *) NULL)->length)) - \
(char *) NULL)
#ifndef ARPHRD_IEEE80211
#define ARPHRD_IEEE80211 801
#endif
#ifndef ARPHRD_IEEE80211_PRISM
#define ARPHRD_IEEE80211_PRISM 802
#endif
/* Wireless Extension Scanning Stuff */
struct iw_stream_descr
{
char * end; /* End of the stream */
char * current; /* Current event in stream of events */
char * value; /* Current value in event */
};
/* Network to host order macros */
#ifdef LBL_ALIGN
#define EXTRACT_16BITS(p) \
((u_int16_t)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | \
(u_int16_t)*((const u_int8_t *)(p) + 1)))
#define EXTRACT_32BITS(p) \
((u_int32_t)((u_int32_t)*((const u_int8_t *)(p) + 0) << 24 | \
(u_int32_t)*((const u_int8_t *)(p) + 1) << 16 | \
(u_int32_t)*((const u_int8_t *)(p) + 2) << 8 | \
(u_int32_t)*((const u_int8_t *)(p) + 3)))
#else
#define EXTRACT_16BITS(p) \
((u_int16_t)ntohs(*(const u_int16_t *)(p)))
#define EXTRACT_32BITS(p) \
((u_int32_t)ntohl(*(const u_int32_t *)(p)))
#endif
#define EXTRACT_24BITS(p) \
((u_int32_t)((u_int32_t)*((const u_int8_t *)(p) + 0) << 16 | \
(u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \
(u_int32_t)*((const u_int8_t *)(p) + 2)))
/* Little endian protocol host order macros */
#define EXTRACT_LE_8BITS(p) (*(p))
#define EXTRACT_LE_16BITS(p) \
((u_int16_t)((u_int16_t)*((const u_int8_t *)(p) + 1) << 8 | \
(u_int16_t)*((const u_int8_t *)(p) + 0)))
#define EXTRACT_LE_32BITS(p) \
((u_int32_t)((u_int32_t)*((const u_int8_t *)(p) + 3) << 24 | \
(u_int32_t)*((const u_int8_t *)(p) + 2) << 16 | \
(u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \
(u_int32_t)*((const u_int8_t *)(p) + 0)))
#endif // ONETUTILS_H
diff --git a/libopie2/opienet/onetwork.cpp b/libopie2/opienet/onetwork.cpp
index 05513f8..1deb051 100644
--- a/libopie2/opienet/onetwork.cpp
+++ b/libopie2/opienet/onetwork.cpp
@@ -1,599 +1,610 @@
/*
                This file is part of the Opie Project
              Copyright (C) 2003-2005 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; version 2 of the License.
     ._= =}       :
    .%`+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/onetwork.h>
#include <opie2/ostation.h>
#include <opie2/odebug.h>
+using namespace Opie::Core;
/* QT */
-
#include <qfile.h>
#include <qtextstream.h>
#include <qapplication.h>
-/* UNIX */
-
+/* STD */
#include <assert.h>
#include <arpa/inet.h>
#include <errno.h>
+#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
+#include <unistd.h>
+#include <net/if_arp.h>
+#include <net/ethernet.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
-#include <unistd.h>
+#include <linux/types.h>
#include <linux/sockios.h>
-#include <net/if_arp.h>
-#include <net/ethernet.h>
-#include <stdarg.h>
+#define u64 __u64
+#define u32 __u32
+#define u16 __u16
+#define u8 __u8
+#include <linux/ethtool.h>
#ifndef NODEBUG
#include <opie2/odebugmapper.h>
-
-using namespace Opie::Core;
using namespace Opie::Net::Internal;
DebugMapper* debugmapper = new DebugMapper();
#endif
/*======================================================================================
* ONetwork
*======================================================================================*/
namespace Opie {
namespace Net {
ONetwork* ONetwork::_instance = 0;
ONetwork::ONetwork()
{
odebug << "ONetwork::ONetwork()" << oendl;
odebug << "ONetwork: This code has been compiled against Wireless Extensions V" << WIRELESS_EXT << oendl;
synchronize();
}
void ONetwork::synchronize()
{
// gather available interfaces by inspecting /proc/net/dev
//FIXME: we could use SIOCGIFCONF here, but we aren't interested in virtual (e.g. eth0:0) devices
//FIXME: Use SIOCGIFCONF anway, because we can disable listing of aliased devices
//FIXME: Best is use SIOCGIFCONF and if this doesn't work (result=-1), then fallback to parsing /proc/net/dev
_interfaces.clear();
QString str;
QFile f( "/proc/net/dev" );
bool hasFile = f.open( IO_ReadOnly );
if ( !hasFile )
{
odebug << "ONetwork: /proc/net/dev not existing. No network devices available" << oendl;
return;
}
QTextStream s( &f );
s.readLine();
s.readLine();
while ( !s.atEnd() )
{
s >> str;
str.truncate( str.find( ':' ) );
odebug << "ONetwork: found interface '" << str << "'" << oendl;
if ( str.startsWith( "wifi" ) )
{
odebug << "ONetwork: ignoring hostap control interface" << oendl;
s.readLine();
continue;
}
ONetworkInterface* iface = 0;
if ( isWirelessInterface( str ) )
{
iface = new OWirelessNetworkInterface( this, (const char*) str );
odebug << "ONetwork: interface '" << str << "' has Wireless Extensions" << oendl;
}
else
{
iface = new ONetworkInterface( this, (const char*) str );
}
_interfaces.insert( str, iface );
s.readLine();
}
}
short ONetwork::wirelessExtensionCompileVersion()
{
return WIRELESS_EXT;
}
int ONetwork::count() const
{
return _interfaces.count();
}
ONetworkInterface* ONetwork::interface( const QString& iface ) const
{
return _interfaces[iface];
}
ONetwork* ONetwork::instance()
{
if ( !_instance ) _instance = new ONetwork();
return _instance;
}
ONetwork::InterfaceIterator ONetwork::iterator() const
{
return ONetwork::InterfaceIterator( _interfaces );
}
bool ONetwork::isPresent( const char* name ) const
{
int sfd = socket( AF_INET, SOCK_STREAM, 0 );
struct ifreq ifr;
memset( &ifr, 0, sizeof( struct ifreq ) );
strcpy( (char*) &ifr.ifr_name, name );
int result = ::ioctl( sfd, SIOCGIFFLAGS, &ifr );
return result != -1;
}
bool ONetwork::isWirelessInterface( const char* name ) const
{
int sfd = socket( AF_INET, SOCK_STREAM, 0 );
struct iwreq iwr;
memset( &iwr, 0, sizeof( struct iwreq ) );
strcpy( (char*) &iwr.ifr_name, name );
int result = ::ioctl( sfd, SIOCGIWNAME, &iwr );
return result != -1;
}
/*======================================================================================
* ONetworkInterface
*======================================================================================*/
ONetworkInterface::ONetworkInterface( QObject* parent, const char* name )
:QObject( parent, name ),
_sfd( socket( AF_INET, SOCK_DGRAM, 0 ) ), _mon( 0 )
{
odebug << "ONetworkInterface::ONetworkInterface()" << oendl;
init();
}
struct ifreq& ONetworkInterface::ifr() const
{
return _ifr;
}
void ONetworkInterface::init()
{
odebug << "ONetworkInterface::init()" << oendl;
memset( &_ifr, 0, sizeof( struct ifreq ) );
if ( _sfd == -1 )
{
odebug << "ONetworkInterface::init(): Warning - can't get socket for device '" << name() << "'" << oendl;
return;
}
}
bool ONetworkInterface::ioctl( int call, struct ifreq& ifreq ) const
{
#ifndef NODEBUG
int result = ::ioctl( _sfd, call, &ifreq );
if ( result == -1 )
odebug << "ONetworkInterface::ioctl (" << name() << ") call '" << debugmapper->map( call )
<< "' FAILED! " << result << " (" << strerror( errno ) << ")" << oendl;
else
odebug << "ONetworkInterface::ioctl (" << name() << ") call '" << debugmapper->map( call )
<< "' - Status: Ok." << oendl;
return ( result != -1 );
#else
return ::ioctl( _sfd, call, &ifreq ) != -1;
#endif
}
bool ONetworkInterface::ioctl( int call ) const
{
strcpy( _ifr.ifr_name, name() );
return ioctl( call, _ifr );
}
bool ONetworkInterface::isLoopback() const
{
ioctl( SIOCGIFFLAGS );
return _ifr.ifr_flags & IFF_LOOPBACK;
}
bool ONetworkInterface::setUp( bool b )
{
ioctl( SIOCGIFFLAGS );
if ( b ) _ifr.ifr_flags |= IFF_UP;
else _ifr.ifr_flags &= (~IFF_UP);
return ioctl( SIOCSIFFLAGS );
}
bool ONetworkInterface::isUp() const
{
ioctl( SIOCGIFFLAGS );
return _ifr.ifr_flags & IFF_UP;
}
void ONetworkInterface::setIPV4Address( const QHostAddress& addr )
{
struct sockaddr_in *sa = (struct sockaddr_in *) &_ifr.ifr_addr;
sa->sin_family = AF_INET;
sa->sin_port = 0;
sa->sin_addr.s_addr = htonl( addr.ip4Addr() );
ioctl( SIOCSIFADDR );
}
QString ONetworkInterface::ipV4Address() const
{
if ( ioctl( SIOCGIFADDR ) )
{
struct sockaddr_in* sa = (struct sockaddr_in *) &_ifr.ifr_addr;
//FIXME: Use QHostAddress here
return QString( inet_ntoa( sa->sin_addr ) );
}
else
return "<unknown>";
}
void ONetworkInterface::setMacAddress( const OMacAddress& addr )
{
_ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
memcpy( &_ifr.ifr_hwaddr.sa_data, addr.native(), 6 );
ioctl( SIOCSIFHWADDR );
}
OMacAddress ONetworkInterface::macAddress() const
{
if ( ioctl( SIOCGIFHWADDR ) )
{
return OMacAddress( _ifr );
}
else
{
return OMacAddress::unknown;
}
}
void ONetworkInterface::setIPV4Netmask( const QHostAddress& addr )
{
struct sockaddr_in *sa = (struct sockaddr_in *) &_ifr.ifr_addr;
sa->sin_family = AF_INET;
sa->sin_port = 0;
sa->sin_addr.s_addr = htonl( addr.ip4Addr() );
ioctl( SIOCSIFNETMASK );
}
QString ONetworkInterface::ipV4Netmask() const
{
if ( ioctl( SIOCGIFNETMASK ) )
{
struct sockaddr_in* sa = (struct sockaddr_in *) &_ifr.ifr_addr;
//FIXME: Use QHostAddress here
return QString( inet_ntoa( sa->sin_addr ) );
}
else
return "<unknown>";
}
int ONetworkInterface::dataLinkType() const
{
if ( ioctl( SIOCGIFHWADDR ) )
{
return _ifr.ifr_hwaddr.sa_family;
}
else
{
return -1;
}
}
void ONetworkInterface::setMonitoring( OMonitoringInterface* m )
{
_mon = m;
odebug << "ONetwork::setMonitoring(): Installed monitoring driver '" << m->name() << "' on interface '" << name() << "'" << oendl;
}
OMonitoringInterface* ONetworkInterface::monitoring() const
{
return _mon;
}
ONetworkInterface::~ONetworkInterface()
{
odebug << "ONetworkInterface::~ONetworkInterface()" << oendl;
if ( _sfd != -1 ) ::close( _sfd );
}
bool ONetworkInterface::setPromiscuousMode( bool b )
{
ioctl( SIOCGIFFLAGS );
if ( b ) _ifr.ifr_flags |= IFF_PROMISC;
else _ifr.ifr_flags &= (~IFF_PROMISC);
return ioctl( SIOCSIFFLAGS );
}
bool ONetworkInterface::promiscuousMode() const
{
ioctl( SIOCGIFFLAGS );
return _ifr.ifr_flags & IFF_PROMISC;
}
bool ONetworkInterface::isWireless() const
{
return ioctl( SIOCGIWNAME );
}
+ONetworkInterfaceDriverInfo ONetworkInterface::driverInfo() const
+{
+ struct ethtool_drvinfo info;
+ info.cmd = ETHTOOL_GDRVINFO;
+ _ifr.ifr_data = (caddr_t) &info;
+ return ioctl( SIOCETHTOOL ) ? ONetworkInterfaceDriverInfo( info.driver, info.version, info.fw_version, info.bus_info) : ONetworkInterfaceDriverInfo();
+}
+
/*======================================================================================
* OChannelHopper
*======================================================================================*/
OChannelHopper::OChannelHopper( OWirelessNetworkInterface* iface )
:QObject( 0, "Mickey's funky hopper" ),
_iface( iface ), _interval( 0 ), _tid( 0 )
{
int _maxChannel = iface->channels();
// generate fancy hopping sequence honoring the device capabilities
if ( _maxChannel >= 1 ) _channels.append( 1 );
if ( _maxChannel >= 7 ) _channels.append( 7 );
if ( _maxChannel >= 13 ) _channels.append( 13 );
if ( _maxChannel >= 2 ) _channels.append( 2 );
if ( _maxChannel >= 8 ) _channels.append( 8 );
if ( _maxChannel >= 3 ) _channels.append( 3 );
if ( _maxChannel >= 14 ) _channels.append( 14 );
if ( _maxChannel >= 9 ) _channels.append( 9 );
if ( _maxChannel >= 4 ) _channels.append( 4 );
if ( _maxChannel >= 10 ) _channels.append( 10 );
if ( _maxChannel >= 5 ) _channels.append( 5 );
if ( _maxChannel >= 11 ) _channels.append( 11 );
if ( _maxChannel >= 6 ) _channels.append( 6 );
if ( _maxChannel >= 12 ) _channels.append( 12 );
+ //FIXME: Add 802.11a/g channels
_channel = _channels.begin();
}
OChannelHopper::~OChannelHopper()
{
}
bool OChannelHopper::isActive() const
{
return _tid;
}
int OChannelHopper::channel() const
{
return *_channel;
}
void OChannelHopper::timerEvent( QTimerEvent* )
{
_iface->setChannel( *_channel );
emit( hopped( *_channel ) );
odebug << "OChannelHopper::timerEvent(): set channel " << *_channel << " on interface '" << _iface->name() << "'" << oendl;
if ( ++_channel == _channels.end() ) _channel = _channels.begin();
}
void OChannelHopper::setInterval( int interval )
{
if ( interval == _interval )
return;
if ( _interval )
killTimer( _tid );
_tid = 0;
_interval = interval;
if ( _interval )
{
_tid = startTimer( interval );
}
}
int OChannelHopper::interval() const
{
return _interval;
}
/*======================================================================================
* OWirelessNetworkInterface
*======================================================================================*/
OWirelessNetworkInterface::OWirelessNetworkInterface( QObject* parent, const char* name )
:ONetworkInterface( parent, name ), _hopper( 0 )
{
odebug << "OWirelessNetworkInterface::OWirelessNetworkInterface()" << oendl;
init();
}
OWirelessNetworkInterface::~OWirelessNetworkInterface()
{
}
struct iwreq& OWirelessNetworkInterface::iwr() const
{
return _iwr;
}
void OWirelessNetworkInterface::init()
{
odebug << "OWirelessNetworkInterface::init()" << oendl;
memset( &_iwr, 0, sizeof( struct iwreq ) );
buildInformation();
buildPrivateList();
dumpInformation();
}
bool OWirelessNetworkInterface::isAssociated() const
{
//FIXME: handle different modes
return !(associatedAP() == OMacAddress::unknown);
}
void OWirelessNetworkInterface::setAssociatedAP( const OMacAddress& mac ) const
{
_iwr.u.ap_addr.sa_family = ARPHRD_ETHER;
::memcpy(_iwr.u.ap_addr.sa_data, mac.native(), ETH_ALEN);
wioctl( SIOCSIWAP );
}
OMacAddress OWirelessNetworkInterface::associatedAP() const
{
if ( ioctl( SIOCGIWAP ) )
return (const unsigned char*) &_ifr.ifr_hwaddr.sa_data[0];
else
return OMacAddress::unknown;
}
void OWirelessNetworkInterface::buildInformation()
{
//ML: If you listen carefully enough, you can hear lots of WLAN drivers suck
//ML: The HostAP drivers need more than sizeof struct_iw range to complete
//ML: SIOCGIWRANGE otherwise they fail with "Invalid Argument Length".
//ML: The Wlan-NG drivers on the otherside fail (segfault!) if you allocate
//ML: _too much_ space. This is damn shitty crap *sigh*
//ML: We allocate a large memory region in RAM and check whether the
//ML: driver pollutes this extra space. The complaint will be made on stdout,
//ML: so please forward this...
struct iwreq wrq;
int len = sizeof( struct iw_range )*2;
char buffer[len];
memset( buffer, 0, len );
memcpy( wrq.ifr_name, name(), IFNAMSIZ);
wrq.u.data.pointer = (caddr_t) buffer;
wrq.u.data.length = sizeof buffer;
wrq.u.data.flags = 0;
if ( ::ioctl( _sfd, SIOCGIWRANGE, &wrq ) == -1 )
{
owarn << "OWirelessNetworkInterface::buildInformation(): Can't get driver information (" << strerror( errno ) << ") - using default values." << oendl;
_channels.insert( 2412, 1 ); // 2.412 GHz
_channels.insert( 2417, 2 ); // 2.417 GHz
_channels.insert( 2422, 3 ); // 2.422 GHz
_channels.insert( 2427, 4 ); // 2.427 GHz
_channels.insert( 2432, 5 ); // 2.432 GHz
_channels.insert( 2437, 6 ); // 2.437 GHz
_channels.insert( 2442, 7 ); // 2.442 GHz
_channels.insert( 2447, 8 ); // 2.447 GHz
_channels.insert( 2452, 9 ); // 2.452 GHz
_channels.insert( 2457, 10 ); // 2.457 GHz
_channels.insert( 2462, 11 ); // 2.462 GHz
memset( &_range, 0, sizeof( struct iw_range ) );
}
else
{
// <check if the driver overwrites stuff>
int max = 0;
for ( int r = sizeof( struct iw_range ); r < len; r++ )
if (buffer[r] != 0)
max = r;
if (max > 0)
{
owarn << "OWirelessNetworkInterface::buildInformation(): Driver for wireless interface '" << name()
<< "' sucks! It overwrote the buffer end with at least " << max - sizeof( struct iw_range ) << " bytes!" << oendl;
}
// </check if the driver overwrites stuff>
struct iw_range range;
memcpy( &range, buffer, sizeof range );
odebug << "OWirelessNetworkInterface::buildInformation(): Interface reported to have " << (int) range.num_frequency << " channels." << oendl;
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 );
odebug << "OWirelessNetworkInterface::buildInformation: Adding frequency " << freq << " as channel " << i+1 << oendl;
_channels.insert( freq, i+1 );
}
}
memcpy( &_range, buffer, sizeof( struct iw_range ) );
odebug << "OWirelessNetworkInterface::buildInformation(): Information block constructed." << oendl;
}
short OWirelessNetworkInterface::wirelessExtensionDriverVersion() const
{
return _range.we_version_compiled;
}
void OWirelessNetworkInterface::buildPrivateList()
{
odebug << "OWirelessNetworkInterface::buildPrivateList()" << oendl;
struct iw_priv_args priv[IW_MAX_PRIV_DEF];
_iwr.u.data.pointer = (char*) &priv;
diff --git a/libopie2/opienet/onetwork.h b/libopie2/opienet/onetwork.h
index fa9f39f..f0c4450 100644
--- a/libopie2/opienet/onetwork.h
+++ b/libopie2/opienet/onetwork.h
@@ -13,404 +13,411 @@
    .%`+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.
*/
#ifndef ONETWORK_H
#define ONETWORK_H
/* OPIE */
#include <opie2/onetutils.h>
#include <opie2/ostation.h>
/* QT */
#include <qvaluelist.h>
#include <qdict.h>
#include <qmap.h>
#include <qobject.h>
#include <qhostaddress.h>
/* STD */
// hacky workarounds until we have a true user space wireless.h
#include <net/if.h>
#define _LINUX_IF_H
#include <linux/wireless.h>
#ifndef IW_MAX_PRIV_DEF
#define IW_MAX_PRIV_DEF 128
#endif
namespace Opie {
namespace Net {
class ONetworkInterface;
class OWirelessNetworkInterface;
class OChannelHopper;
class OMonitoringInterface;
/*======================================================================================
* ONetwork
*======================================================================================*/
/**
* @brief A container class for all network interfaces
*
* This class provides access to all available network interfaces of your computer.
*
* @author Michael 'Mickey' Lauer <mickey@vanille.de>
*/
class ONetwork : public QObject
{
Q_OBJECT
public:
typedef QDict<ONetworkInterface> InterfaceMap;
typedef QDictIterator<ONetworkInterface> InterfaceIterator;
public:
/**
* @returns the number of available interfaces
*/
int count() const;
/**
* @returns a pointer to the (one and only) @ref ONetwork instance.
*/
static ONetwork* instance();
/**
* @returns an iterator usable for iterating through all network interfaces.
*/
InterfaceIterator iterator() const;
/**
* @returns true, if the @a interface is present.
*/
bool isPresent( const char* interface ) const;
/**
* @returns true, if the @a interface supports the wireless extension protocol.
*/
bool isWirelessInterface( const char* interface ) const;
/**
* @returns a pointer to the @ref ONetworkInterface object for the specified @a interface or 0, if not found.
* @see ONetworkInterface
*/
ONetworkInterface* interface( const QString& interface ) const;
/**
* @internal Rebuild the internal interface database
* @note Sometimes it might be useful to call this from client code,
* e.g. after issuing a cardctl insert
*/
void synchronize();
/**
* @returns the wireless extension version used at compile time.
**/
static short wirelessExtensionCompileVersion();
protected:
ONetwork();
private:
static ONetwork* _instance;
InterfaceMap _interfaces;
class Private;
Private *d;
};
/*======================================================================================
* ONetworkInterface
*======================================================================================*/
/**
* @brief A network interface wrapper.
*
* This class provides a wrapper for a network interface. All the cumbersume details of
* Linux ioctls are hidden under a convenient high-level interface.
* @warning Most of the setting methods contained in this class require the appropriate
* process permissions to work.
*
* @author Michael 'Mickey' Lauer <mickey@vanille.de>
*/
class ONetworkInterface : public QObject
{
friend class OMonitoringInterface;
friend class OCiscoMonitoringInterface;
friend class OWlanNGMonitoringInterface;
friend class OHostAPMonitoringInterface;
friend class OOrinocoMonitoringInterface;
public:
/**
* Constructor. Normally you don't create @ref ONetworkInterface objects yourself,
* but access them via @ref ONetwork::interface().
*/
ONetworkInterface( QObject* parent, const char* name );
/**
* Destructor.
*/
virtual ~ONetworkInterface();
/**
* Associates a @a monitoring interface with this network interface.
* @note This is currently only useful with @ref OWirelessNetworkInterface objects.
*/
void setMonitoring( OMonitoringInterface* monitoring );
/**
* @returns the currently associated monitoring interface or 0, if no monitoring is associated.
*/
OMonitoringInterface* monitoring() const;
/**
* Setting an interface to promiscuous mode enables the device to receive
* all packets on the shared medium - as opposed to packets which are addressed to this interface.
*/
bool setPromiscuousMode( bool );
/**
* @returns true if the interface is set to promiscuous mode.
*/
bool promiscuousMode() const;
/**
* Setting an interface to up enables it to receive packets.
*/
bool setUp( bool );
/**
* @returns true if the interface is up.
*/
bool isUp() const;
/**
* @returns true if the interface is a loopback interface.
*/
bool isLoopback() const;
/**
* @returns true if the interface is featuring supports the wireless extension protocol.
*/
bool isWireless() const;
/**
* Associate the IP address @ addr with the interface.
*/
void setIPV4Address( const QHostAddress& addr );
/**
* @returns the IPv4 address associated with the interface.
*/
QString ipV4Address() const; //TODO: make this return an OHostAddress
/**
* Associate the MAC address @a addr with the interface.
* @note It can be necessary to shut down the interface prior to calling this method.
+ * @note This operation needs root privileges
* @warning This is not supported by all drivers.
*/
void setMacAddress( const OMacAddress& addr );
/**
* @returns the MAC address associated with the interface.
*/
OMacAddress macAddress() const;
/**
* Associate the IPv4 @a netmask with the interface.
*/
void setIPV4Netmask( const QHostAddress& netmask );
/**
* @returns the IPv4 netmask associated with the interface.
*/
QString ipV4Netmask() const; //TODO: make this return an OHostAddress
/**
* @returns the data link type currently associated with the interface.
* @see #include <net/if_arp.h> for possible values.
*/
int dataLinkType() const;
+ /**
+ * @returns a ONetworkInterfaceDriverInfo driver information block
+ * @note This operation needs root privileges
+ * @warning This is not supported by all drivers
+ */
+ ONetworkInterfaceDriverInfo driverInfo() const;
protected:
const int _sfd;
mutable ifreq _ifr;
OMonitoringInterface* _mon;
protected:
struct ifreq& ifr() const;
virtual void init();
bool ioctl( int call ) const;
bool ioctl( int call, struct ifreq& ) const;
private:
class Private;
Private *d;
};
/*======================================================================================
* OChannelHopper
*======================================================================================*/
/**
* @brief A radio frequency channel hopper.
*
* This class provides a channel hopper for radio frequencies. A channel hopper frequently
* changes the radio frequency channel of its associated @ref OWirelessNetworkInterface.
* This is necessary when in monitoring mode and scanning for other devices, because
* the radio frequency hardware can only detect packets sent on the same frequency.
*
* @author Michael 'Mickey' Lauer <mickey@vanille.de>
*/
class OChannelHopper : public QObject
{
Q_OBJECT
public:
/**
* Constructor.
*/
OChannelHopper( OWirelessNetworkInterface* );
/**
* Destructor.
*/
virtual ~OChannelHopper();
/**
* @returns true, if the channel hopper is hopping channels
*/
bool isActive() const;
/**
* @returns the last hopped channel
*/
int channel() const;
/**
* Set the channel hopping @a interval.
* An interval of 0 deactivates the channel hopper.
*/
void setInterval( int interval );
/**
* @returns the channel hopping interval
*/
int interval() const;
signals:
/**
* This signal is emitted right after the channel hopper performed a hop
*/
void hopped( int );
protected:
virtual void timerEvent( QTimerEvent* );
private:
OWirelessNetworkInterface* _iface;
int _interval;
int _tid;
QValueList<int> _channels;
QValueList<int>::Iterator _channel;
class Private;
Private *d;
};
/*======================================================================================
* OWirelessNetworkInterface
*======================================================================================*/
/**
* @brief A network interface wrapper for interfaces supporting the wireless extensions protocol.
*
* This class provides a high-level encapsulation of the Linux wireless extension API.
*
* @author Michael 'Mickey' Lauer <mickey@vanille.de>
*/
class OWirelessNetworkInterface : public ONetworkInterface
{
friend class OMonitoringInterface;
friend class OCiscoMonitoringInterface;
friend class OWlanNGMonitoringInterface;
friend class OHostAPMonitoringInterface;
friend class OOrinocoMonitoringInterface;
friend class OPrivateIOCTL;
public:
/**
* Constructor.
*/
OWirelessNetworkInterface( QObject* parent, const char* name );
/**
* Destructor.
*/
virtual ~OWirelessNetworkInterface();
/**
* Setting the @a channel of the interface changes the radio frequency (RF)
* of the corresponding wireless network device.
* @note Common channel range is within [1-14]. A value of 0 is not allowed.
* @see channels()
*/
virtual void setChannel( int channel ) const;
/**
* @returns the channel index of the current radio frequency.
*/
virtual int channel() const;
/**
* @returns the current radio frequency (in MHz).
*/
virtual double frequency() const;
/**
* @returns the number of radio frequency channels for the
* corresponding wireless network device.
* @note European devices usually have 14 channels, while American typically feature 11 channels.
*/
virtual int channels() const;
/**
* Set the IEEE 802.11 operation @a mode.
* Valid values are <ul><li>adhoc<li>managed<li>monitor<li>master
* @warning Not all drivers support the all modes.
* @note You might have to change the SSID to get the operation mode change into effect.
*/
virtual void setMode( const QString& mode );
/**
* @returns the current IEEE 802.11 operation mode.
* Possible values are <ul><li>adhoc<li>managed<li>monitor<li>master or <li>unknown
*
* @note: Important note concerning the 'monitor' mode:
* 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 QString mode() const;
/**
* 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
/**
* @returns true if the interface is associated to an access point
* @note: This information is only valid if the interface is in managed mode.
*/
virtual bool isAssociated() const;
/** Set the @a mac associated AP address.
diff --git a/libopie2/opienet/opienet.pro b/libopie2/opienet/opienet.pro
index 460de0a..854e5ff 100644
--- a/libopie2/opienet/opienet.pro
+++ b/libopie2/opienet/opienet.pro
@@ -1,40 +1,40 @@
TEMPLATE = lib
CONFIG += qt warn_on
DESTDIR = $(OPIEDIR)/lib
HEADERS = 802_11_user.h \
dhcp.h \
udp_ports.h \
odebugmapper.h \
omanufacturerdb.h \
onetutils.h \
onetwork.h \
opcap.h \
ostation.h
SOURCES = odebugmapper.cpp \
omanufacturerdb.cpp \
onetutils.cpp \
onetwork.cpp \
opcap.cpp \
ostation.cpp
INTERFACES =
TARGET = opienet2
-VERSION = 1.8.6
+VERSION = 1.8.7
INCLUDEPATH += $(OPIEDIR)/include
DEPENDPATH += $(OPIEDIR)/include
LIBS += -lpcap
!contains( platform, x11 ) {
include( $(OPIEDIR)/include.pro )
}
contains( platform, x11 ) {
LIBS += -L$(OPIEDIR)/lib -Wl,-rpath,$(OPIEDIR)/lib
}
!isEmpty( LIBPCAP_INC_DIR ) {
INCLUDEPATH = $$LIBPCAP_INC_DIR $$INCLUDEPATH
}
!isEmpty( LIBPCAP_LIB_DIR ) {
LIBS = -L$$LIBPCAP_LIB_DIR $$LIBS
}