00001 #include "wlanimp2.h"
00002 #include "keyedit.h"
00003 #include "interfacesetupimp.h"
00004 #include "../interfaces/interface.h"
00005
00006 #include <assert.h>
00007 #include <errno.h>
00008 #include <string.h>
00009
00010
00011 #include <opie2/odebug.h>
00012 #include <opie2/oprocess.h>
00013 #include <opie2/onetwork.h>
00014 #include <opie2/opcap.h>
00015 #include <opie2/oresource.h>
00016 using namespace Opie::Core;
00017 using namespace Opie::Net;
00018
00019
00020 #include <qapplication.h>
00021 #include <qfile.h>
00022 #include <qdir.h>
00023 #include <qdialog.h>
00024 #include <qtextstream.h>
00025 #include <qmessagebox.h>
00026 #include <qlineedit.h>
00027 #include <qlabel.h>
00028 #include <qspinbox.h>
00029 #include <qradiobutton.h>
00030 #include <qpushbutton.h>
00031 #include <qcheckbox.h>
00032 #include <qtabwidget.h>
00033 #include <qcombobox.h>
00034 #include <qlistview.h>
00035 #include <qvbox.h>
00036 #include <qprogressbar.h>
00037
00038
00039 #include <assert.h>
00040 #include <errno.h>
00041 #include <string.h>
00042
00043 #define WIRELESS_OPTS "/etc/pcmcia/wireless.opts"
00044 #define PREUP "/etc/network/if-pre-up.d/wireless-tools"
00045
00049 WLANImp::WLANImp( QWidget* parent, const char* name, Interface *i, bool modal, WFlags fl) : WLAN(parent, name, modal, fl), interface(i), currentProfile("*") {
00050 interfaces = new Interfaces();
00051 interfaceSetup = new InterfaceSetupImp(tabWidget, "InterfaceSetupImp", i, interfaces);
00052 tabWidget->insertTab(interfaceSetup, "TCP/IP");
00053
00054
00055 QFile file(QString(PREUP));
00056 if (file.exists()) {
00057 owarn << QString("WLANImp: Unable to open /etc/network/if-pre-up.d/wireless-tools") << oendl;
00058 }
00059
00060 connect( rescanButton, SIGNAL( clicked() ), this, SLOT( rescanNeighbourhood() ) );
00061 connect( netView, SIGNAL( clicked(QListViewItem*) ), this, SLOT( selectNetwork(QListViewItem*) ) );
00062 netView->setColumnAlignment( col_chn, AlignCenter );
00063 netView->setItemMargin( 3 );
00064 netView->setAllColumnsShowFocus( true );
00065
00066 }
00067
00068 WLANImp::~WLANImp() {
00069
00070 }
00071
00075 void WLANImp::setProfile(const QString &profile){
00076 interfaceSetup->setProfile(profile);
00077 parseOpts();
00078 }
00079
00080 void WLANImp::parseOpts() {
00081 bool error;
00082 QString opt,key;
00083
00084 if (! interfaces->isInterfaceSet())
00085 return;
00086
00087 opt = interfaces->getInterfaceOption("wireless_essid", error);
00088 if(opt == "any" || opt == "off" || opt.isNull()){
00089 essid->setEditText("any");
00090 } else {
00091 essid->setEditText(opt);
00092 }
00093
00094 opt = interfaces->getInterfaceOption("wireless_mode", error).simplifyWhiteSpace();
00095
00096 for ( int i = 0; i < mode->count(); i++)
00097 if ( mode->text( i ) == opt ) mode->setCurrentItem( i );
00098
00099 opt = interfaces->getInterfaceOption("wireless_ap", error).simplifyWhiteSpace();
00100 if (! opt.isNull()) {
00101 specifyAp->setChecked(true);
00102 macEdit->setText(opt);
00103 }
00104
00105 opt = interfaces->getInterfaceOption("wireless_channel", error).simplifyWhiteSpace();
00106 if (! opt.isNull()) {
00107 specifyChan->setChecked(true);
00108 networkChannel->setValue(opt.toInt());
00109 }
00110
00111 opt = interfaces->getInterfaceOption("wireless_type", error).simplifyWhiteSpace();
00112
00113 if ( opt == "wlan-ng") {
00114
00115
00116
00117
00118 opt = interfaces->getInterfaceOption("wlan_ng_default_key_id", error).simplifyWhiteSpace();
00119
00120 if (opt == "0")
00121 keyRadio0->setChecked(true);
00122 if (opt == "1")
00123 keyRadio1->setChecked(true);
00124 if (opt == "2")
00125 keyRadio2->setChecked(true);
00126 if (opt == "3")
00127 keyRadio3->setChecked(true);
00128
00129
00130 key = interfaces->getInterfaceOption("wlan_ng_key0", error).simplifyWhiteSpace();
00131 key.replace(QString(":"),QString(""));
00132 keyLineEdit0->setText(key);
00133
00134
00135 key = interfaces->getInterfaceOption("wlan_ng_key1", error).simplifyWhiteSpace();
00136 key.replace(QString(":"),QString(""));
00137 keyLineEdit1->setText(key);
00138
00139
00140 key = interfaces->getInterfaceOption("wlan_ng_key2", error).simplifyWhiteSpace();
00141 key.replace(QString(":"),QString(""));
00142 keyLineEdit2->setText(key);
00143
00144
00145 key = interfaces->getInterfaceOption("wlan_ng_key3", error).simplifyWhiteSpace();
00146 key.replace(QString(":"),QString(""));
00147 keyLineEdit3->setText(key);
00148
00149 opt = interfaces->getInterfaceOption("wireless_enc", error).simplifyWhiteSpace();
00150
00151
00152 if(opt == "on"){
00153 wepEnabled->setChecked(true);
00154 } else {
00155 wepEnabled->setChecked(false);
00156 }
00157
00158 opt = interfaces->getInterfaceOption("wireless_keymode", error).simplifyWhiteSpace();
00159
00160 if(opt == "restricted"){
00161
00162 rejectNonEnc->setChecked(true);
00163 }
00164 }
00165 else {
00166 opt = interfaces->getInterfaceOption("wireless_key", error).simplifyWhiteSpace();
00167
00168 parseKeyStr(opt);
00169 }
00170 }
00171
00172 void WLANImp::parseKeyStr(QString keystr) {
00173 int index = 1;
00174 QString key;
00175 QStringList keys = QStringList::split(QRegExp("\\s+"), keystr);
00176 int enc = -1;
00177
00178 for (QStringList::Iterator it = keys.begin(); it != keys.end(); ++it) {
00179 if ((*it).left(3) == "off") {
00180
00181 enc = 0;
00182 } else if ((*it).left(2) == "on") {
00183
00184 enc = 1;
00185 } else if ((*it).left(4) == "open") {
00186
00187 acceptNonEnc->setChecked(true);
00188 } else if ((*it).left(10) == "restricted") {
00189
00190 rejectNonEnc->setChecked(true);
00191 } else if ((*it).left(3) == "key") {
00192
00193 } else if ((*it).left(1) == "[") {
00194 index = (*it).mid(1, 1).toInt();
00195
00196 switch (index) {
00197 case 1:
00198 keyRadio0->setChecked(true);
00199 break;
00200 case 2:
00201 keyRadio1->setChecked(true);
00202 break;
00203 case 3:
00204 keyRadio2->setChecked(true);
00205 break;
00206 case 4:
00207 keyRadio3->setChecked(true);
00208 break;
00209 }
00210 } else {
00211
00212 key = (*it);
00213 }
00214 if (! key.isNull()) {
00215 if (enc == -1)
00216 enc = 1;
00217 QStringList::Iterator next = ++it;
00218 if (it == keys.end()) {
00219 break;
00220 }
00221 if ((*(next)).left(1) == "[") {
00222
00223 index = (*(next)).mid(1, 1).toInt();
00224 } else {
00225 index = 1;
00226 }
00227 switch (index) {
00228 case 1:
00229 keyLineEdit0->setText(key);
00230 break;
00231 case 2:
00232 keyLineEdit1->setText(key);
00233 break;
00234 case 3:
00235 keyLineEdit2->setText(key);
00236 break;
00237 case 4:
00238 keyLineEdit3->setText(key);
00239 break;
00240 }
00241 key = QString::null;
00242 }
00243 }
00244 if (enc == 1) {
00245 wepEnabled->setChecked(true);
00246 } else {
00247 wepEnabled->setChecked(false);
00248 }
00249 }
00250
00255 void WLANImp::accept() {
00256 if (wepEnabled->isChecked()) {
00257 if ((keyRadio0->isChecked() && keyLineEdit0->text().isEmpty()) ||
00258 (keyRadio1->isChecked() && keyLineEdit1->text().isEmpty()) ||
00259 (keyRadio2->isChecked() && keyLineEdit2->text().isEmpty()) ||
00260 (keyRadio3->isChecked() && keyLineEdit3->text().isEmpty())) {
00261 QMessageBox::information(this, "Error", "Please enter a WEP key.", QMessageBox::Ok);
00262 return;
00263 }
00264 }
00265
00266 if (essid->currentText().isEmpty()) {
00267 QMessageBox::information(this, "Error", "Please select/enter an ESSID.", QMessageBox::Ok);
00268 return;
00269 }
00270
00271 if (specifyAp->isChecked() && macEdit->text().isEmpty()) {
00272 QMessageBox::information(this, "Error", "Please enter the MAC address of the Access Point.", QMessageBox::Ok);
00273 return;
00274 }
00275
00276
00277 writeOpts();
00278
00279
00280
00281 }
00282
00283 QString WLANImp::formatKey(QString input)
00284 {
00285 int len,r=0;
00286
00287 len = input.length();
00288
00289 if (!len)
00290 return input;
00291
00292 for(int i=1;i<len/2;i++)
00293 {
00294 input.insert(r+i*2,QString(":"));
00295 r++;
00296 }
00297
00298 return input;
00299 }
00300
00301 void WLANImp::writeOpts() {
00302 QString para, devicetype;
00303
00304
00305 if(!interfaces->isInterfaceSet()){
00306 QMessageBox::warning(0,"Inface not set","should not happen!!!");
00307 return;
00308 }
00309 bool error = false;
00310
00311 odebug << "setting wlan interface " << interfaces->getInterfaceName( error ).latin1() << "" << oendl;
00312
00313 if (error) QMessageBox::warning(0,"Inface not set","should not happen!!!");
00314
00315 interfaces->setInterfaceOption(QString("wireless_mode"), mode->currentText());
00316 interfaces->setInterfaceOption(QString("wireless_essid"), essid->currentText());
00317
00318 if (specifyAp->isChecked()) {
00319 interfaces->setInterfaceOption(QString("wireless_ap"), macEdit->text());
00320 } else {
00321 interfaces->removeInterfaceOption(QString("wireless_ap"));
00322 }
00323
00324 if (specifyChan->isChecked()) {
00325 interfaces->setInterfaceOption(QString("wireless_channel"), networkChannel->text());
00326 } else {
00327 interfaces->removeInterfaceOption(QString("wireless_channel"));
00328 }
00329
00330 devicetype = interfaces->getInterfaceOption("wireless_type", error).simplifyWhiteSpace();
00331
00332 if ( devicetype == "wlan-ng") {
00333
00334
00335 interfaces->removeInterfaceOption(QString("wireless_key"));
00336
00337 if (wepEnabled->isChecked()) {
00338
00339 interfaces->setInterfaceOption(QString("wireless_enc"),"on");
00340
00341 if (! keyLineEdit0->text().isNull()) {
00342 interfaces->setInterfaceOption(QString("wlan_ng_key0"), formatKey(keyLineEdit0->text()));
00343 } else
00344 interfaces->removeInterfaceOption(QString("wlan_ng_key0"));
00345 if (! keyLineEdit1->text().isNull()) {
00346 interfaces->setInterfaceOption(QString("wlan_ng_key1"), formatKey(keyLineEdit1->text()));
00347 } else
00348 interfaces->removeInterfaceOption(QString("wlan_ng_key1"));
00349 if (! keyLineEdit2->text().isNull()) {
00350 interfaces->setInterfaceOption(QString("wlan_ng_key2"), formatKey(keyLineEdit2->text()));
00351 } else
00352 interfaces->removeInterfaceOption(QString("wlan_ng_key2"));
00353 if (! keyLineEdit3->text().isNull()) {
00354 interfaces->setInterfaceOption(QString("wlan_ng_key3"), formatKey(keyLineEdit3->text()));
00355 } else
00356 interfaces->removeInterfaceOption(QString("wlan_ng_key3"));
00357
00358 if (acceptNonEnc->isChecked())
00359 interfaces->removeInterfaceOption(QString("wireless_keymode"));
00360 else
00361 interfaces->setInterfaceOption(QString("wireless_keymode"),"restricted");
00362
00363 para = "";
00364 if (keyRadio0->isChecked()) {
00365 para = "0";
00366 } else if (keyRadio1->isChecked()) {
00367 para = "1";
00368 } else if (keyRadio2->isChecked()) {
00369 para = "2";
00370 } else if (keyRadio3->isChecked()) {
00371 para = "3";
00372 }
00373
00374 interfaces->setInterfaceOption(QString("wlan_ng_default_key_id"), para);
00375
00376 } else {
00377
00378 interfaces->removeInterfaceOption(QString("wireless_enc"));
00379 interfaces->removeInterfaceOption(QString("wlan_ng_default_key_id"));
00380 interfaces->removeInterfaceOption(QString("wlan_ng_key0"));
00381 interfaces->removeInterfaceOption(QString("wlan_ng_key1"));
00382 interfaces->removeInterfaceOption(QString("wlan_ng_key2"));
00383 interfaces->removeInterfaceOption(QString("wlan_ng_key3"));
00384 }
00385
00386 } else {
00387
00388 if (wepEnabled->isChecked()) {
00389 QStringList keyList;
00390
00391 if (! keyLineEdit0->text().isNull()) {
00392 keyList += keyLineEdit0->text();
00393 keyList += "[1]";
00394 }
00395 if (! keyLineEdit1->text().isNull()) {
00396 keyList += keyLineEdit1->text();
00397 keyList += "[2]";
00398 }
00399 if (! keyLineEdit2->text().isNull()) {
00400 keyList += keyLineEdit2->text();
00401 keyList += "[3]";
00402 }
00403 if (! keyLineEdit3->text().isNull()) {
00404 keyList += keyLineEdit3->text();
00405 keyList += "[4]";
00406 }
00407 if (acceptNonEnc->isChecked()) {
00408 keyList += "open";
00409 } else {
00410 keyList += "restricted";
00411 }
00412
00413 keyList += "key";
00414 if (keyRadio0->isChecked()) {
00415 keyList += "[1]";
00416 } else if (keyRadio1->isChecked()) {
00417 keyList += "[2]";
00418 } else if (keyRadio2->isChecked()) {
00419 keyList += "[3]";
00420 } else if (keyRadio3->isChecked()) {
00421 keyList += "[4]";
00422 }
00423 interfaces->setInterfaceOption(QString("wireless_key"), keyList.join(QString(" ")));
00424 } else {
00425 interfaces->removeInterfaceOption(QString("wireless_key"));
00426 }
00427 interfaces->removeInterfaceOption(QString("wireless_enc"));
00428 }
00429
00430 if(!interfaceSetup->saveChanges())
00431 return;
00432
00433 QDialog::accept();
00434 }
00435
00436
00437
00438
00439
00440
00441 void WLANImp::rescanNeighbourhood()
00442 {
00443 QString name = interface->getInterfaceName();
00444 odebug << "rescanNeighbourhood via '" << name << "'" << oendl;
00445
00446 OWirelessNetworkInterface* wiface = static_cast<OWirelessNetworkInterface*>( ONetwork::instance()->interface( name ) );
00447 assert( wiface );
00448
00449
00450 QString devicetype;
00451 QFile m( "/proc/modules" );
00452 if ( m.open( IO_ReadOnly ) )
00453 {
00454 QString line;
00455 QTextStream modules( &m );
00456 while( !modules.atEnd() && !devicetype )
00457 {
00458 modules >> line;
00459 if ( line.contains( "cisco" ) ) devicetype = "cisco";
00460 else if ( line.contains( "hostap" ) ) devicetype = "hostap";
00461 else if ( line.contains( "prism" ) ) devicetype = "wlan-ng";
00462 else if ( line.contains( "orinoco" ) ) devicetype = "orinoco";
00463 }
00464 }
00465 if ( devicetype.isEmpty() )
00466 {
00467 owarn << "rescanNeighbourhood(): couldn't guess device type :(" << oendl;
00468 return;
00469 }
00470 else
00471 {
00472 odebug << "rescanNeighbourhood(): device type seems to be '" << devicetype << "'" << oendl;
00473 }
00474
00475
00476
00477 wiface->setUp( true );
00478 wiface->setPromiscuousMode( true );
00479
00480 if ( devicetype == "cisco" ) wiface->setMonitoring( new OCiscoMonitoringInterface( wiface, false ) );
00481 else if ( devicetype == "hostap" ) wiface->setMonitoring( new OHostAPMonitoringInterface( wiface, false ) );
00482 else if ( devicetype == "wlan-ng" ) wiface->setMonitoring( new OWlanNGMonitoringInterface( wiface, false ) );
00483 else if ( devicetype == "orinoco" ) wiface->setMonitoring( new OOrinocoMonitoringInterface( wiface, false ) );
00484 else
00485 {
00486 odebug << "rescanNeighbourhood(): unsupported device type for monitoring :(" << oendl;
00487 return;
00488 }
00489
00490 wiface->setMode( "monitor" );
00491 if ( wiface->mode() != "monitor" )
00492 {
00493 owarn << "rescanNeighbourhood(): Unable to bring device into monitor mode (" << strerror( errno ) << ")." << oendl;
00494 return;
00495 }
00496
00497
00498 OPacketCapturer* cap = new OPacketCapturer();
00499 cap->open( name );
00500 if ( !cap->isOpen() )
00501 {
00502 owarn << "rescanNeighbourhood(): Unable to open libpcap (" << strerror( errno ) << ")." << oendl;
00503 return;
00504 }
00505
00506
00507 rescanButton->setEnabled( false );
00508 QFrame* splash = new QFrame( this, "splash", false, WStyle_StaysOnTop | WStyle_DialogBorder | WStyle_Customize );
00509 splash->setLineWidth( 2 );
00510 splash->setFrameStyle( QFrame::Panel | QFrame::Raised );
00511 QVBoxLayout* vbox = new QVBoxLayout( splash, 4, 4 );
00512 QLabel* lab = new QLabel( "<center><b>Scanning...</b><br>Please Wait...</center>", splash );
00513 QProgressBar* pb = new QProgressBar( wiface->channels(), splash );
00514 vbox->addWidget( lab );
00515 vbox->addWidget( pb );
00516 pb->setCenterIndicator( true );
00517 pb->setFixedHeight( pb->sizeHint().height() );
00518 QWidget* widgetDesktop = qApp->desktop();
00519 int dw = widgetDesktop->width();
00520 int dh = widgetDesktop->height();
00521 int pw = vbox->sizeHint().width();
00522 int ph = vbox->sizeHint().height();
00523 splash->setGeometry((dw-pw)/2,(dh-ph)/2,pw,ph);
00524 splash->show();
00525 splash->raise();
00526 qApp->processEvents();
00527
00528
00529 cap->setBlocking( false );
00530
00531 for ( int i = 1; i <= wiface->channels(); ++i )
00532 {
00533 wiface->setChannel( i );
00534 pb->setProgress( i );
00535 qApp->processEvents();
00536 odebug << "rescanNeighbourhood(): listening on channel " << i << "..." << oendl;
00537 OPacket* p = cap->next( 1000 );
00538 if ( !p )
00539 {
00540 odebug << "rescanNeighbourhood(): nothing received on channel " << i << "" << oendl;
00541 }
00542 else
00543 {
00544 odebug << "rescanNeighbourhood(): TADAA - something came in on channel " << i << "" << oendl;
00545 handlePacket( p );
00546 }
00547 }
00548
00549 cap->close();
00550 wiface->setMode( "managed" );
00551 wiface->setPromiscuousMode( false );
00552
00553
00554 splash->hide();
00555 delete splash;
00556 rescanButton->setEnabled( true );
00557 }
00558
00559 void WLANImp::handlePacket( OPacket* p )
00560 {
00561
00562
00563 OWaveLanManagementPacket* beacon = static_cast<OWaveLanManagementPacket*>( p->child( "802.11 Management" ) );
00564 if ( beacon && beacon->managementType() == "Beacon" )
00565 {
00566
00567 QString type;
00568 if ( beacon->canIBSS() )
00569 {
00570 type = "adhoc";
00571 }
00572 else if ( beacon->canESS() )
00573 {
00574 type = "managed";
00575 }
00576 else
00577 {
00578 owarn << "handlePacket(): invalid frame [possibly noise] detected!" << oendl;
00579 return;
00580 }
00581
00582 OWaveLanManagementSSID* ssid = static_cast<OWaveLanManagementSSID*>( p->child( "802.11 SSID" ) );
00583 QString essid = ssid ? ssid->ID() : QString("<unknown>");
00584 OWaveLanManagementDS* ds = static_cast<OWaveLanManagementDS*>( p->child( "802.11 DS" ) );
00585 int channel = ds ? ds->channel() : -1;
00586 OWaveLanPacket* header = static_cast<OWaveLanPacket*>( p->child( "802.11" ) );
00587 displayFoundNetwork( type, channel, essid, header->macAddress2() );
00588 }
00589 }
00590
00591
00592 void WLANImp::displayFoundNetwork( const QString& mode, int channel, const QString& ssid, const OMacAddress& mac )
00593 {
00594
00595 odebug << "found network: <" << (const char*) mode << ">, chn " << channel
00596 << ", ssid '" << (const char*) ssid << "', mac '" << (const char*) mac.toString() << "'" << oendl;
00597
00598 QListViewItemIterator it( netView );
00599 while ( it.current() && it.current()->text( col_ssid ) != ssid ) ++it;
00600 if ( !it.current() )
00601 {
00602 QListViewItem* item = new QListViewItem( netView, mode.left( 1 ).upper(), ssid, QString::number( channel ), mac.toString() );
00603 QString name;
00604 name.sprintf( "networksettings/%s", (const char*) mode );
00605 item->setPixmap( col_mode, Opie::Core::OResource::loadPixmap( name, Opie::Core::OResource::SmallIcon ) );
00606 qApp->processEvents();
00607 }
00608
00609 }
00610
00611
00612 void WLANImp::selectNetwork( QListViewItem* item )
00613 {
00614 bool ok;
00615 if ( item )
00616 {
00617 specifyAp->setChecked(true);
00618 macEdit->setText( item->text( col_mac ) );
00619 specifyChan->setChecked( item->text( col_mode ) == "A" );
00620 networkChannel->setValue( item->text( col_chn ).toInt( &ok ) );
00621 essid->setEditText( item->text( col_ssid ) );
00622 if ( item->text( col_mode ) == "A" )
00623 mode->setCurrentItem( 3 );
00624 else
00625 mode->setCurrentItem( 2 );
00626 }
00627 }