author | mickeyl <mickeyl> | 2003-04-22 22:11:28 (UTC) |
---|---|---|
committer | mickeyl <mickeyl> | 2003-04-22 22:11:28 (UTC) |
commit | a0ffe9079338a8b870de5267a22ddbb01cb1cc27 (patch) (side-by-side diff) | |
tree | fe240ab38bd11cd32d51674e4f79a465092476e5 /libopie2/opienet/onetwork.cpp | |
parent | bb8965d31b06ec122a0916d8c5bc4c4b68873a14 (diff) | |
download | opie-a0ffe9079338a8b870de5267a22ddbb01cb1cc27.zip opie-a0ffe9079338a8b870de5267a22ddbb01cb1cc27.tar.gz opie-a0ffe9079338a8b870de5267a22ddbb01cb1cc27.tar.bz2 |
add prism header parsing capability!
Diffstat (limited to 'libopie2/opienet/onetwork.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | libopie2/opienet/onetwork.cpp | 5 |
1 files changed, 3 insertions, 2 deletions
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 @@ -398,559 +398,560 @@ void OChannelHopper::timerEvent( QTimerEvent* ) 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 ) { qDebug( "OWirelessNetworkInterface::OWirelessNetworkInterface()" ); init(); } OWirelessNetworkInterface::~OWirelessNetworkInterface() { } struct iwreq& OWirelessNetworkInterface::iwr() const { return _iwr; } void OWirelessNetworkInterface::init() { qDebug( "OWirelessNetworkInterface::init()" ); memset( &_iwr, 0, sizeof( struct iwreq ) ); buildChannelList(); buildPrivateList(); } QString OWirelessNetworkInterface::associatedAP() const { //FIXME: use OMacAddress QString mac; if ( ioctl( SIOCGIWAP ) ) { mac.sprintf( "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X", _ifr.ifr_hwaddr.sa_data[0]&0xff, _ifr.ifr_hwaddr.sa_data[1]&0xff, _ifr.ifr_hwaddr.sa_data[2]&0xff, _ifr.ifr_hwaddr.sa_data[3]&0xff, _ifr.ifr_hwaddr.sa_data[4]&0xff, _ifr.ifr_hwaddr.sa_data[5]&0xff ); } else { mac = "<Unknown>"; } return mac; } void OWirelessNetworkInterface::buildChannelList() { //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 memset( buffer, 0, len ); memcpy( wrq.ifr_name, name(), IFNAMSIZ); wrq.u.data.pointer = (caddr_t) buffer; wrq.u.data.length = sizeof( struct iw_range ); wrq.u.data.flags = 0; if ( ::ioctl( _sfd, SIOCGIWRANGE, &wrq ) == -1 ) { qDebug( "OWirelessNetworkInterface::buildChannelList(): SIOCGIWRANGE failed (%s) - defaulting to 11 channels", strerror( errno ) ); _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 } 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) { qWarning( "OWirelessNetworkInterface::buildChannelList(): Driver for wireless interface '%s'" "overwrote buffer end with at least %i bytes!\n", name(), max - sizeof( struct iw_range ) ); } // </check if the driver overwrites stuff> 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 { return _if->monitorMode(); } void OMonitoringInterface::setEnabled( bool b ) { } /*====================================================================================== * OCiscoMonitoringInterface *======================================================================================*/ OCiscoMonitoringInterface::OCiscoMonitoringInterface( ONetworkInterface* iface ) :OMonitoringInterface( iface ) { 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 ) { 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"; } |