From a8fe3ba1544ca2a2ad2559e3094acbb284cc7783 Mon Sep 17 00:00:00 2001 From: mickeyl Date: Sat, 11 Oct 2003 23:54:03 +0000 Subject: add scanning skeleton (wip) --- (limited to 'libopie2') diff --git a/libopie2/examples/opienet/onetworkdemo/onetworkdemo.cpp b/libopie2/examples/opienet/onetworkdemo/onetworkdemo.cpp index 607d8f1..fc2026f 100644 --- a/libopie2/examples/opienet/onetworkdemo/onetworkdemo.cpp +++ b/libopie2/examples/opienet/onetworkdemo/onetworkdemo.cpp @@ -56,6 +56,18 @@ int main( int argc, char** argv ) iface->setMode( "managed" ); + // network scan + + int stations = iface->scanNetwork(); + if ( stations != -1 ) + { + qDebug( "DEMO: # of stations around = %d", stations ); + } + else + { + qDebug( "DEMO: Warning! Scan didn't work!" ); + } + /* // first some wrong calls to check if this is working diff --git a/libopie2/opienet/onetwork.cpp b/libopie2/opienet/onetwork.cpp index dc2e388..be45924 100644 --- a/libopie2/opienet/onetwork.cpp +++ b/libopie2/opienet/onetwork.cpp @@ -76,6 +76,7 @@ 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; @@ -188,9 +189,9 @@ bool ONetworkInterface::ioctl( int call, struct ifreq& ifreq ) const { int result = ::ioctl( _sfd, call, &ifreq ); if ( result == -1 ) - qDebug( "ONetworkInterface::ioctl (%s) call %d - Status: Failed: %d (%s)", name(), call, result, strerror( errno ) ); + qDebug( "ONetworkInterface::ioctl (%s) call %d (0x%04X) - Status: Failed: %d (%s)", name(), call, call, result, strerror( errno ) ); else - qDebug( "ONetworkInterface::ioctl (%s) call %d - Status: Ok.", name(), call ); + qDebug( "ONetworkInterface::ioctl (%s) call %d (0x%04X) - Status: Ok.", name(), call, call ); return ( result != -1 ); } @@ -454,8 +455,16 @@ void OWirelessNetworkInterface::init() { qDebug( "OWirelessNetworkInterface::init()" ); memset( &_iwr, 0, sizeof( struct iwreq ) ); - buildChannelList(); + buildInformation(); buildPrivateList(); + dumpInformation(); +} + + +bool OWirelessNetworkInterface::isAssociated() const +{ + //FIXME: handle different modes + return associatedAP() != "44:44:44:44:44:44"; } @@ -482,7 +491,7 @@ QString OWirelessNetworkInterface::associatedAP() const } -void OWirelessNetworkInterface::buildChannelList() +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 @@ -505,7 +514,7 @@ void OWirelessNetworkInterface::buildChannelList() if ( ::ioctl( _sfd, SIOCGIWRANGE, &wrq ) == -1 ) { - qDebug( "OWirelessNetworkInterface::buildChannelList(): SIOCGIWRANGE failed (%s) - defaulting to 11 channels", strerror( errno ) ); + qDebug( "OWirelessNetworkInterface::buildInformation(): SIOCGIWRANGE failed (%s) - using default values.", strerror( errno ) ); _channels.insert( 2412, 1 ); // 2.412 GHz _channels.insert( 2417, 2 ); // 2.417 GHz _channels.insert( 2422, 3 ); // 2.422 GHz @@ -517,6 +526,8 @@ void OWirelessNetworkInterface::buildChannelList() _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 { @@ -527,15 +538,15 @@ void OWirelessNetworkInterface::buildChannelList() max = r; if (max > 0) { - qWarning( "OWirelessNetworkInterface::buildChannelList(): Driver for wireless interface '%s'" - "overwrote buffer end with at least %i bytes!\n", name(), max - sizeof( struct iw_range ) ); + qWarning( "OWirelessNetworkInterface::buildInformation(): Driver for wireless interface '%s' sucks!\n" + "It overwrote the buffer end with at least %i bytes!\n", name(), max - sizeof( struct iw_range ) ); } // struct iw_range range; memcpy( &range, buffer, sizeof range ); - qDebug( "OWirelessNetworkInterface::buildChannelList(): Interface %s reported to have %d channels.", name(), range.num_frequency ); + qDebug( "OWirelessNetworkInterface::buildInformation(): 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 ); @@ -543,7 +554,8 @@ void OWirelessNetworkInterface::buildChannelList() } } - qDebug( "OWirelessNetworkInterface::buildChannelList(): Channel list constructed." ); + memcpy( &_range, buffer, sizeof( struct iw_range ) ); + qDebug( "OWirelessNetworkInterface::buildInformation(): Information block constructed." ); free(buffer); } @@ -572,6 +584,17 @@ void OWirelessNetworkInterface::buildPrivateList() } +void OWirelessNetworkInterface::dumpInformation() const +{ + qDebug( "OWirelessNetworkInterface::() -------------- dumping information block ----------------" ); + + qDebug( " - driver's idea of maximum throughput is %d bps = %d byte/s = %d Kb/s = %f.2 Mb/s", _range.throughput, _range.throughput / 8, _range.throughput / 8 / 1024, float( _range.throughput ) / 8.0 / 1024.0 / 1024.0 ); + qDebug( " - driver for '%s' has been compiled against WE V%d (source=V%d)", name(), _range.we_version_compiled, _range.we_version_source ); + + qDebug( "OWirelessNetworkInterface::() ---------------------------------------------------------" ); +} + + int OWirelessNetworkInterface::channel() const { //FIXME: When monitoring enabled, then use it @@ -661,9 +684,7 @@ void OWirelessNetworkInterface::setMode( const QString& mode ) else if ( mode == "master" ) _iwr.u.mode = IW_MODE_MASTER; else if ( mode == "repeater" ) _iwr.u.mode = IW_MODE_REPEAT; else if ( mode == "secondary" ) _iwr.u.mode = IW_MODE_SECOND; - #if WIRELESS_EXT > 14 else if ( mode == "monitor" ) _iwr.u.mode = IW_MODE_MONITOR; - #endif else { qDebug( "ONetwork: Warning! Invalid IEEE 802.11 mode '%s' specified.", (const char*) mode ); @@ -687,9 +708,7 @@ QString OWirelessNetworkInterface::mode() const case IW_MODE_MASTER: return "master"; case IW_MODE_REPEAT: return "repeater"; case IW_MODE_SECOND: return "secondary"; - #if WIRELESS_EXT > 14 case IW_MODE_MONITOR: return "monitor"; - #endif default: assert( 0 ); // shouldn't happen } } @@ -708,7 +727,8 @@ bool OWirelessNetworkInterface::monitorMode() const { qDebug( "dataLinkType = %d", dataLinkType() ); return ( dataLinkType() == ARPHRD_IEEE80211 || dataLinkType() == 802 ); - // 802 is the header type for PRISM - Linux support for this is pending... + //FIXME: 802 is the header type for PRISM - Linux support for this is pending... + //FIXME: What is 119, by the way? } @@ -800,13 +820,74 @@ void OWirelessNetworkInterface::setSSID( const QString& ssid ) } +int OWirelessNetworkInterface::scanNetwork() +{ + _iwr.u.param.flags = IW_SCAN_DEFAULT; + _iwr.u.param.value = 0; + if ( !wioctl( SIOCSIWSCAN ) ) + { + return -1; + } + + int timeout = 1000000; + + qDebug( "ONetworkInterface::scanNetwork() - scan started." ); + + bool results = false; + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 250000; // initial timeout ~ 250ms + char buffer[IW_SCAN_MAX_DATA]; + + while ( !results && timeout > 0 ) + { + timeout -= tv.tv_usec; + select( 0, 0, 0, 0, &tv ); + + _iwr.u.data.pointer = &buffer[0]; + _iwr.u.data.flags = 0; + _iwr.u.data.length = sizeof buffer; + if ( wioctl( SIOCGIWSCAN ) ) + { + results = true; + continue; + } + else if ( errno == EAGAIN) + { + qDebug( "ONetworkInterface::scanNetwork() - scan in progress..." ); + #if 0 + if ( qApp ) + { + qApp->processEvents( 100 ); + continue; + } + #endif + tv.tv_sec = 0; + tv.tv_usec = 100000; + continue; + } + } + + qDebug( "ONetworkInterface::scanNetwork() - scan finished." ); + + if ( results ) + { + qDebug( " - results are in!" ); + } + else + { + qDebug( " - no results :(" ); + } +} + + 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 ) ); + qDebug( "ONetworkInterface::wioctl (%s) call %d (0x%04X) - Status: Failed: %d (%s)", name(), call, call, result, strerror( errno ) ); else - qDebug( "ONetworkInterface::wioctl (%s) call %d - Status: Ok.", name(), call ); + qDebug( "ONetworkInterface::wioctl (%s) call %d (0x%04X) - Status: Ok.", name(), call, call ); return ( result != -1 ); } diff --git a/libopie2/opienet/onetwork.h b/libopie2/opienet/onetwork.h index b170ea2..e1545dd 100644 --- a/libopie2/opienet/onetwork.h +++ b/libopie2/opienet/onetwork.h @@ -361,7 +361,7 @@ class OWirelessNetworkInterface : public ONetworkInterface * the proper @ref OMonitoringInterface to be associated with the interface. * @see OMonitoringInterface */ - virtual void setMonitorMode( bool ); //FIXME: ==> setMode( "monitor" ); + virtual void setMonitorMode( bool ); //FIXME: ==> setMode( "monitor" ); Use IW_MONITOR first, if this doesn't work, then use iwpriv! /** * @returns true if the device is listening in IEEE 802.11 monitor mode */ @@ -397,12 +397,14 @@ class OWirelessNetworkInterface : public ONetworkInterface */ 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. + * @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; + /** + * @returns the MAC address of the Access Point if the device is in infrastructure mode. + * @returns a (more or less random) cell ID address if the device is in adhoc mode. */ virtual QString associatedAP() const; /** @@ -414,10 +416,16 @@ class OWirelessNetworkInterface : public ONetworkInterface * @returns the current SSID (Service Set ID). */ virtual QString SSID() const; + /** + * Perform scanning the wireless network neighbourhood. + * @note: UNSTABLE API - UNDER CONSTRUCTION - DON'T USE! + */ + virtual int scanNetwork(); protected: - void buildChannelList(); + void buildInformation(); void buildPrivateList(); + void dumpInformation() const; virtual void init(); struct iwreq& iwr() const; bool wioctl( int call ) const; @@ -426,6 +434,7 @@ class OWirelessNetworkInterface : public ONetworkInterface protected: mutable struct iwreq _iwr; QMap _channels; + struct iw_range _range; private: OChannelHopper* _hopper; @@ -475,10 +484,12 @@ class OCiscoMonitoringInterface : public OMonitoringInterface }; + /*====================================================================================== * OWlanNGMonitoringInterface *======================================================================================*/ + class OWlanNGMonitoringInterface : public OMonitoringInterface { public: @@ -492,10 +503,12 @@ class OWlanNGMonitoringInterface : public OMonitoringInterface }; + /*====================================================================================== * OHostAPMonitoringInterface *======================================================================================*/ + class OHostAPMonitoringInterface : public OMonitoringInterface { public: @@ -507,10 +520,12 @@ class OHostAPMonitoringInterface : public OMonitoringInterface virtual QString name() const; }; + /*====================================================================================== * OOrinocoMonitoringInterface *======================================================================================*/ + class OOrinocoMonitoringInterface : public OMonitoringInterface { public: -- cgit v0.9.0.2