Diffstat (limited to 'libopie2/opienet/onetwork.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | libopie2/opienet/onetwork.cpp | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/libopie2/opienet/onetwork.cpp b/libopie2/opienet/onetwork.cpp index 546be9e..0a74019 100644 --- a/libopie2/opienet/onetwork.cpp +++ b/libopie2/opienet/onetwork.cpp @@ -17,63 +17,65 @@ =_ + =;=|` 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> /* QT */ #include <qfile.h> #include <qtextstream.h> +#include <qapplication.h> /* UNIX */ #include <assert.h> #include <arpa/inet.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <sys/types.h> #include <unistd.h> #include <linux/sockios.h> #include <net/if_arp.h> +#include <net/ethernet.h> #include <stdarg.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(); } @@ -470,48 +472,56 @@ 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 = (char*) malloc( len ); //FIXME: Validate if we actually got the memory block @@ -885,55 +895,53 @@ OStationList* OWirelessNetworkInterface::scanNetwork() odebug << "ONetworkInterface::scanNetwork() - scan started." << oendl; 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) { odebug << "ONetworkInterface::scanNetwork() - scan in progress..." << oendl; - #if 0 if ( qApp ) { qApp->processEvents( 100 ); continue; } - #endif tv.tv_sec = 0; tv.tv_usec = 100000; continue; } } odebug << "ONetworkInterface::scanNetwork() - scan finished." << oendl; if ( results ) { odebug << " - result length = " << _iwr.u.data.length << oendl; if ( !_iwr.u.data.length ) { odebug << " - no results (empty neighbourhood)" << oendl; return stations; } odebug << " - results are in!" << oendl; dumpBytes( (const unsigned char*) &buffer[0], _iwr.u.data.length ); // parse results struct iw_event iwe; struct iw_stream_descr stream; unsigned int cmd_index, event_type, event_len; @@ -1106,63 +1114,83 @@ OStationList* OWirelessNetworkInterface::scanNetwork() } } struct iw_event *we = &iwe; //------ odebug << " - reading next event... cmd=" << we->cmd << ", len=" << we->len << oendl; switch (we->cmd) { case SIOCGIWAP: { odebug << "SIOCGIWAP" << oendl; stations->append( new OStation() ); stations->last()->macAddress = (const unsigned char*) &we->u.ap_addr.sa_data[0]; break; } case SIOCGIWMODE: { odebug << "SIOCGIWMODE" << oendl; stations->last()->type = modeToString( we->u.mode ); break; } case SIOCGIWFREQ: { odebug << "SIOCGIWFREQ" << oendl; - stations->last()->channel = _channels[ static_cast<int>(double( we->u.freq.m ) * pow( 10.0, we->u.freq.e ) / 1000000) ]; + if ( we->u.freq.m > 1000 ) + stations->last()->channel = _channels[ static_cast<int>(double( we->u.freq.m ) * pow( 10.0, we->u.freq.e ) / 1000000) ]; + else + stations->last()->channel = static_cast<int>(((double) we->u.freq.m) * pow( 10.0, we->u.freq.e )); break; } case SIOCGIWESSID: { odebug << "SIOCGIWESSID" << oendl; we->u.essid.length = '\0'; // make sure it is zero terminated stations->last()->ssid = static_cast<const char*> (we->u.essid.pointer); odebug << "ESSID: " << stations->last()->ssid << oendl; break; } + case IWEVQUAL: + { + odebug << "IWEVQUAL" << oendl; + stations->last()->level = static_cast<int>(we->u.qual.level); + break; /* Quality part of statistics (scan) */ + } + case SIOCGIWENCODE: + { + odebug << "SIOCGIWENCODE" << oendl; + stations->last()->encrypted = !(we->u.data.flags & IW_ENCODE_DISABLED); + break; + } + + case SIOCGIWRATE: + { + odebug << "SIOCGIWRATE" << oendl; + stations->last()->rates.append(we->u.bitrate.value); + break; + } case SIOCGIWSENS: odebug << "SIOCGIWSENS" << oendl; break; - case SIOCGIWENCODE: odebug << "SIOCGIWENCODE" << oendl; break; case IWEVTXDROP: odebug << "IWEVTXDROP" << oendl; break; /* Packet dropped to excessive retry */ - case IWEVQUAL: odebug << "IWEVQUAL" << oendl; break; /* Quality part of statistics (scan) */ case IWEVCUSTOM: odebug << "IWEVCUSTOM" << oendl; break; /* Driver specific ascii string */ case IWEVREGISTERED: odebug << "IWEVREGISTERED" << oendl; break; /* Discovered a new node (AP mode) */ case IWEVEXPIRED: odebug << "IWEVEXPIRED" << oendl; break; /* Expired a node (AP mode) */ default: odebug << "unhandled event" << oendl; } } while (true); } else { odebug << " - no results (timeout) :(" << oendl; } return stations; } int OWirelessNetworkInterface::signalStrength() const { iw_statistics stat; ::memset( &stat, 0, sizeof stat ); _iwr.u.data.pointer = (char*) &stat; _iwr.u.data.flags = 0; _iwr.u.data.length = sizeof stat; |