author | mickeyl <mickeyl> | 2005-05-15 13:41:19 (UTC) |
---|---|---|
committer | mickeyl <mickeyl> | 2005-05-15 13:41:19 (UTC) |
commit | 1de015fb8f267f2451dd26d992cc713e6e02af79 (patch) (side-by-side diff) | |
tree | a82bcaf6bce0b713910de85450a83862b2d0a73a | |
parent | 4451abf402aa1dd967ef8b70a7eba1192f13afb0 (diff) | |
download | opie-1de015fb8f267f2451dd26d992cc713e6e02af79.zip opie-1de015fb8f267f2451dd26d992cc713e6e02af79.tar.gz opie-1de015fb8f267f2451dd26d992cc713e6e02af79.tar.bz2 |
submit iw_range*2 as argument to SIOCGIWRANGE.length to make it work on newer hostap drivers
let's see if this breaks it at another end again :/
-rw-r--r-- | libopie2/opienet/onetwork.cpp | 14 |
1 files changed, 6 insertions, 8 deletions
diff --git a/libopie2/opienet/onetwork.cpp b/libopie2/opienet/onetwork.cpp index f4bdbe0..05513f8 100644 --- a/libopie2/opienet/onetwork.cpp +++ b/libopie2/opienet/onetwork.cpp @@ -508,124 +508,122 @@ void OWirelessNetworkInterface::setAssociatedAP( const OMacAddress& mac ) const 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 + 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( struct iw_range ); + wrq.u.data.length = sizeof buffer; wrq.u.data.flags = 0; if ( ::ioctl( _sfd, SIOCGIWRANGE, &wrq ) == -1 ) { - owarn << "OWirelessNetworkInterface::buildInformation(): Can't get channel information - using default values." << oendl; + 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; - free(buffer); } 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; _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 ) ) { - owarn << "OWirelessNetworkInterface::buildPrivateList(): Can't get private ioctl information." << oendl; + owarn << "OWirelessNetworkInterface::buildPrivateList(): Can't get private ioctl information (" << strerror( errno ) << ")." << oendl; 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 ); } odebug << "OWirelessNetworkInterface::buildPrivateList(): Private ioctl list constructed." << oendl; } void OWirelessNetworkInterface::dumpInformation() const { odebug << "OWirelessNetworkInterface::() -------------- dumping information block ----------------" << oendl; odebug << " - driver's idea of maximum throughput is " << _range.throughput << " bps = " << ( _range.throughput / 8 ) << " byte/s = " << ( _range.throughput / 8 / 1024 ) << " Kb/s = " << QString().sprintf("%f.2", float( _range.throughput ) / 8.0 / 1024.0 / 1024.0 ) << " Mb/s" << oendl; odebug << " - driver for '" << name() << "' (V" << _range.we_version_source << ") has been compiled against WE V" << _range.we_version_compiled << oendl; if ( _range.we_version_compiled != WIRELESS_EXT ) @@ -1137,55 +1135,55 @@ OStationList* OWirelessNetworkInterface::scanNetwork() { odebug << "SIOCGIWMODE" << oendl; stations->last()->type = modeToString( we->u.mode ); break; } case SIOCGIWFREQ: { odebug << "SIOCGIWFREQ" << oendl; 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; + odebug << "IWEVQUAL" << oendl; stations->last()->level = static_cast<int>(we->u.qual.level); break; /* Quality part of statistics (scan) */ } case SIOCGIWENCODE: { - odebug << "SIOCGIWENCODE" << oendl; + 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 IWEVTXDROP: odebug << "IWEVTXDROP" << oendl; break; /* Packet dropped to excessive retry */ 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; } |