Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

wlanimp2.cpp

Go to the documentation of this file.
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 /* OPIE */
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 /* QT */
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 /* STD */
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   // Check sanity - the existance of the wireless-tools if-pre-up script
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 //FIXME:  delete interfaces;
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      //FIXME:Handle wlan_ng_priv_genstr
00116 
00117     // get default key_id
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     // get key0
00130     key = interfaces->getInterfaceOption("wlan_ng_key0", error).simplifyWhiteSpace();
00131     key.replace(QString(":"),QString(""));
00132     keyLineEdit0->setText(key);
00133 
00134     // get key1
00135     key = interfaces->getInterfaceOption("wlan_ng_key1", error).simplifyWhiteSpace();
00136     key.replace(QString(":"),QString(""));
00137     keyLineEdit1->setText(key);
00138 
00139     // get key2
00140     key = interfaces->getInterfaceOption("wlan_ng_key2", error).simplifyWhiteSpace();
00141     key.replace(QString(":"),QString(""));
00142     keyLineEdit2->setText(key);
00143 
00144     // get key3
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     // encryption on?
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       // restricted mode, only accept encrypted packets
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; // encryption state
00177 
00178   for (QStringList::Iterator it = keys.begin(); it != keys.end(); ++it) {
00179     if ((*it).left(3) == "off") {
00180       // encryption disabled
00181       enc = 0;
00182     } else if ((*it).left(2) == "on") {
00183       // encryption enabled
00184       enc = 1;
00185     } else if ((*it).left(4) == "open") {
00186       // open mode, accept non encrypted packets
00187       acceptNonEnc->setChecked(true);
00188     } else if ((*it).left(10) == "restricted") {
00189       // restricted mode, only accept encrypted packets
00190       rejectNonEnc->setChecked(true);
00191     } else if ((*it).left(3) == "key") {
00192       // new set of options
00193     } else if ((*it).left(1) == "[") {
00194       index = (*it).mid(1, 1).toInt();
00195       // switch current key to index
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       // key
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         // set key at index
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   // Try to save the interfaces settings.
00277   writeOpts();
00278 
00279   // Close out the dialog
00280 // FIXME:  QDialog::accept();
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   // eh can't really do anything about it other then return. :-D
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     // wlan-ng style
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       // No wep, remove all previous keys
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     // This is the old style
00388     if (wepEnabled->isChecked()) {
00389       QStringList keyList;
00390 
00391       if (! keyLineEdit0->text().isNull()) {
00392         keyList += keyLineEdit0->text();
00393         keyList += "[1]";
00394       } //else
00395       if (! keyLineEdit1->text().isNull()) {
00396         keyList += keyLineEdit1->text();
00397         keyList += "[2]";
00398       } //else
00399       if (! keyLineEdit2->text().isNull()) {
00400         keyList += keyLineEdit2->text();
00401         keyList += "[3]";
00402       } //else
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  * Scan for possible wireless networks around...
00438  * ... powered by Wellenreiter II technology (C) Michael 'Mickey' Lauer <mickeyl@handhelds.org>
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     // try to guess device type
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"; /* puke */
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     // configure interface to receive 802.11 management frames
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     // open a packet capturer
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     // disable button and display splash screen
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     // set capturer to non-blocking mode
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" ); // TODO: use previous mode
00551     wiface->setPromiscuousMode( false );
00552 
00553     // hide splash screen and reenable button
00554     splash->hide();
00555     delete splash;
00556     rescanButton->setEnabled( true );
00557 }
00558 
00559 void WLANImp::handlePacket( OPacket* p )
00560 {
00561 
00562     // check if we received a beacon frame
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() ) // ssid didn't show up yet
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 }

Generated on Sat Nov 5 16:17:52 2005 for OPIE by  doxygen 1.4.2