author | mickeyl <mickeyl> | 2003-10-10 02:24:48 (UTC) |
---|---|---|
committer | mickeyl <mickeyl> | 2003-10-10 02:24:48 (UTC) |
commit | 2b2620fee2bbd6f7045b237aa33c277c47512345 (patch) (unidiff) | |
tree | 31f92a166da4ae596d55fe5079f058dd4a16fce4 /noncore/settings/networksettings/wlan/wlanimp2.cpp | |
parent | c1a897e63513c9647666970794c1684b2439501e (diff) | |
download | opie-2b2620fee2bbd6f7045b237aa33c277c47512345.zip opie-2b2620fee2bbd6f7045b237aa33c277c47512345.tar.gz opie-2b2620fee2bbd6f7045b237aa33c277c47512345.tar.bz2 |
This patch adds scanning the "network neighbourhood" in networksettings-wlan
(powered by the Wellenreiter II scanning engine found in libopienet2).
Detected networks are put in a list and you can select parameters by clicking
on an entry in the list. See http://opie.net.wox.org/images/wlanplugin.png
Two inherent drawbacks:
1.) networksettingsplugin-wlan now needs libopienet2. Well, my library work pays
off. If you like to rewrite the stuff so that libopienet2 is not needed, then just
go ahead ;)
2.) Scanning won't work on linux distributions without patched monitor mode drivers.
I think we can live with these two "issues". Feel free to revert, if you don't like
my work :D
Diffstat (limited to 'noncore/settings/networksettings/wlan/wlanimp2.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/settings/networksettings/wlan/wlanimp2.cpp | 216 |
1 files changed, 215 insertions, 1 deletions
diff --git a/noncore/settings/networksettings/wlan/wlanimp2.cpp b/noncore/settings/networksettings/wlan/wlanimp2.cpp index 26e3aa9..7ce096f 100644 --- a/noncore/settings/networksettings/wlan/wlanimp2.cpp +++ b/noncore/settings/networksettings/wlan/wlanimp2.cpp | |||
@@ -2,27 +2,42 @@ | |||
2 | #include "keyedit.h" | 2 | #include "keyedit.h" |
3 | #include "interfacesetupimp.h" | 3 | #include "interfacesetupimp.h" |
4 | 4 | ||
5 | #include "../interfaces/interface.h" | ||
6 | |||
7 | #include <assert.h> | ||
8 | #include <errno.h> | ||
9 | #include <string.h> | ||
10 | |||
11 | #include <qapplication.h> | ||
5 | #include <qfile.h> | 12 | #include <qfile.h> |
6 | #include <qdir.h> | 13 | #include <qdir.h> |
14 | #include <qdialog.h> | ||
7 | #include <qtextstream.h> | 15 | #include <qtextstream.h> |
8 | #include <qmessagebox.h> | 16 | #include <qmessagebox.h> |
9 | #include <qlineedit.h> | 17 | #include <qlineedit.h> |
10 | #include <qlabel.h> | 18 | #include <qlabel.h> |
11 | #include <qspinbox.h> | 19 | #include <qspinbox.h> |
12 | #include <qradiobutton.h> | 20 | #include <qradiobutton.h> |
21 | #include <qpushbutton.h> | ||
13 | #include <qcheckbox.h> | 22 | #include <qcheckbox.h> |
14 | #include <qtabwidget.h> | 23 | #include <qtabwidget.h> |
15 | #include <qcombobox.h> | 24 | #include <qcombobox.h> |
25 | #include <qlistview.h> | ||
26 | #include <qvbox.h> | ||
27 | #include <qprogressbar.h> | ||
16 | 28 | ||
17 | #ifdef QWS | 29 | #ifdef QWS |
30 | #include <qpe/resource.h> | ||
18 | #include <opie/oprocess.h> | 31 | #include <opie/oprocess.h> |
32 | #include <opie2/onetwork.h> | ||
33 | #include <opie2/opcap.h> | ||
19 | #else | 34 | #else |
20 | #define OProcess KProcess | 35 | #define OProcess KProcess |
21 | #include <kprocess.h> | 36 | #include <kprocess.h> |
22 | #endif | 37 | #endif |
23 | 38 | ||
24 | #define WIRELESS_OPTS "/etc/pcmcia/wireless.opts" | 39 | #define WIRELESS_OPTS "/etc/pcmcia/wireless.opts" |
25 | #define PREUP "/etc/netwrok/if-pre-up.d/wireless-tools" | 40 | #define PREUP "/etc/network/if-pre-up.d/wireless-tools" |
26 | 41 | ||
27 | /** | 42 | /** |
28 | * Constructor, read in the wireless.opts file for parsing later. | 43 | * Constructor, read in the wireless.opts file for parsing later. |
@@ -37,6 +52,13 @@ WLANImp::WLANImp( QWidget* parent, const char* name, Interface *i, bool modal, W | |||
37 | if (file.exists()) { | 52 | if (file.exists()) { |
38 | qWarning(QString("WLANImp: Unable to open /etc/network/if-pre-up.d/wireless-tools")); | 53 | qWarning(QString("WLANImp: Unable to open /etc/network/if-pre-up.d/wireless-tools")); |
39 | } | 54 | } |
55 | |||
56 | connect( rescanButton, SIGNAL( clicked() ), this, SLOT( rescanNeighbourhood() ) ); | ||
57 | connect( netView, SIGNAL( clicked( QListViewItem* ) ), this, SLOT( selectNetwork( QListViewItem* ) ) ); | ||
58 | netView->setColumnAlignment( col_chn, AlignCenter ); | ||
59 | netView->setItemMargin( 3 ); | ||
60 | netView->setAllColumnsShowFocus( true ); | ||
61 | |||
40 | } | 62 | } |
41 | 63 | ||
42 | WLANImp::~WLANImp() { | 64 | WLANImp::~WLANImp() { |
@@ -274,3 +296,195 @@ void WLANImp::writeOpts() { | |||
274 | 296 | ||
275 | QDialog::accept(); | 297 | QDialog::accept(); |
276 | } | 298 | } |
299 | |||
300 | /* | ||
301 | * Scan for possible wireless networks around... | ||
302 | * ... powered by Wellenreiter II technology (C) Michael 'Mickey' Lauer <mickeyl@handhelds.org> | ||
303 | */ | ||
304 | |||
305 | void WLANImp::rescanNeighbourhood() | ||
306 | { | ||
307 | QString name = interface->getInterfaceName(); | ||
308 | qDebug( "rescanNeighbourhood via '%s'", (const char*) name ); | ||
309 | |||
310 | OWirelessNetworkInterface* wiface = static_cast<OWirelessNetworkInterface*>( ONetwork::instance()->interface( name ) ); | ||
311 | assert( wiface ); | ||
312 | |||
313 | // try to guess device type | ||
314 | QString devicetype; | ||
315 | QFile m( "/proc/modules" ); | ||
316 | if ( m.open( IO_ReadOnly ) ) | ||
317 | { | ||
318 | QString line; | ||
319 | QTextStream modules( &m ); | ||
320 | while( !modules.atEnd() && !devicetype ) | ||
321 | { | ||
322 | modules >> line; | ||
323 | if ( line.contains( "cisco" ) ) devicetype = "cisco"; | ||
324 | else if ( line.contains( "hostap" ) ) devicetype = "hostap"; | ||
325 | else if ( line.contains( "prism" ) ) devicetype = "wlan-ng"; /* puke */ | ||
326 | else if ( line.contains( "orinoco" ) ) devicetype = "orinoco"; | ||
327 | } | ||
328 | } | ||
329 | if ( devicetype.isEmpty() ) | ||
330 | { | ||
331 | qWarning( "rescanNeighbourhood(): couldn't guess device type :(" ); | ||
332 | return; | ||
333 | } | ||
334 | else | ||
335 | { | ||
336 | qDebug( "rescanNeighbourhood(): device type seems to be '%s'", (const char*) devicetype ); | ||
337 | } | ||
338 | |||
339 | // configure interface to receive 802.11 management frames | ||
340 | |||
341 | wiface->setUp( true ); | ||
342 | wiface->setPromiscuousMode( true ); | ||
343 | |||
344 | if ( devicetype == "cisco" ) wiface->setMonitoring( new OCiscoMonitoringInterface( wiface, false ) ); | ||
345 | else if ( devicetype == "hostap" ) wiface->setMonitoring( new OHostAPMonitoringInterface( wiface, false ) ); | ||
346 | else if ( devicetype == "wlan-ng" ) wiface->setMonitoring( new OWlanNGMonitoringInterface( wiface, false ) ); | ||
347 | else if ( devicetype == "orinoco" ) wiface->setMonitoring( new OOrinocoMonitoringInterface( wiface, false ) ); | ||
348 | else | ||
349 | { | ||
350 | qDebug( "rescanNeighbourhood(): unsupported device type for monitoring :(" ); | ||
351 | return; | ||
352 | } | ||
353 | |||
354 | wiface->setMonitorMode( true ); | ||
355 | if ( !wiface->monitorMode() ) | ||
356 | { | ||
357 | qWarning( "rescanNeighbourhood(): Unable to bring device into monitor mode (%s).", strerror( errno ) ); | ||
358 | return; | ||
359 | } | ||
360 | |||
361 | // open a packet capturer | ||
362 | OPacketCapturer* cap = new OPacketCapturer(); | ||
363 | cap->open( name ); | ||
364 | if ( !cap->isOpen() ) | ||
365 | { | ||
366 | qWarning( "rescanNeighbourhood(): Unable to open libpcap (%s).", strerror( errno ) ); | ||
367 | return; | ||
368 | } | ||
369 | |||
370 | // display splash screen | ||
371 | QFrame* splash = new QFrame( this, "splash", false, WStyle_StaysOnTop | WStyle_DialogBorder | WStyle_Customize ); | ||
372 | splash->setLineWidth( 2 ); | ||
373 | splash->setFrameStyle( QFrame::Panel | QFrame::Raised ); | ||
374 | QVBoxLayout* vbox = new QVBoxLayout( splash, 4, 4 ); | ||
375 | QLabel* lab = new QLabel( "<center><b>Scanning...</b><br>Please Wait...</center>", splash ); | ||
376 | QProgressBar* pb = new QProgressBar( wiface->channels(), splash ); | ||
377 | vbox->addWidget( lab ); | ||
378 | vbox->addWidget( pb ); | ||
379 | pb->setCenterIndicator( true ); | ||
380 | pb->setFixedHeight( pb->sizeHint().height() ); | ||
381 | QWidget* widgetDesktop = qApp->desktop(); | ||
382 | int dw = widgetDesktop->width(); | ||
383 | int dh = widgetDesktop->height(); | ||
384 | int pw = vbox->sizeHint().width(); | ||
385 | int ph = vbox->sizeHint().height(); | ||
386 | splash->setGeometry((dw-pw)/2,(dh-ph)/2,pw,ph); | ||
387 | splash->show(); | ||
388 | splash->raise(); | ||
389 | qApp->processEvents(); | ||
390 | |||
391 | // set capturer to non-blocking mode | ||
392 | cap->setBlocking( false ); | ||
393 | |||
394 | for ( int i = 1; i <= wiface->channels(); ++i ) | ||
395 | { | ||
396 | wiface->setChannel( i ); | ||
397 | pb->setProgress( i ); | ||
398 | qApp->processEvents(); | ||
399 | qDebug( "rescanNeighbourhood(): listening on channel %d...", i ); | ||
400 | OPacket* p = cap->next( 1000 ); | ||
401 | if ( !p ) | ||
402 | { | ||
403 | qDebug( "rescanNeighbourhood(): nothing received on channel %d", i ); | ||
404 | } | ||
405 | else | ||
406 | { | ||
407 | qDebug( "rescanNeighbourhood(): TADAA - something came in on channel %d", i ); | ||
408 | handlePacket( p ); | ||
409 | } | ||
410 | } | ||
411 | |||
412 | cap->close(); | ||
413 | wiface->setMonitorMode( false ); | ||
414 | wiface->setPromiscuousMode( true ); | ||
415 | |||
416 | splash->hide(); | ||
417 | delete splash; | ||
418 | |||
419 | } | ||
420 | |||
421 | void WLANImp::handlePacket( OPacket* p ) | ||
422 | { | ||
423 | |||
424 | // check if we received a beacon frame | ||
425 | OWaveLanManagementPacket* beacon = static_cast<OWaveLanManagementPacket*>( p->child( "802.11 Management" ) ); | ||
426 | if ( beacon && beacon->managementType() == "Beacon" ) | ||
427 | { | ||
428 | |||
429 | QString type; | ||
430 | if ( beacon->canIBSS() ) | ||
431 | { | ||
432 | type = "adhoc"; | ||
433 | } | ||
434 | else if ( beacon->canESS() ) | ||
435 | { | ||
436 | type = "managed"; | ||
437 | } | ||
438 | else | ||
439 | { | ||
440 | qWarning( "handlePacket(): invalid frame [possibly noise] detected!" ); | ||
441 | return; | ||
442 | } | ||
443 | |||
444 | OWaveLanManagementSSID* ssid = static_cast<OWaveLanManagementSSID*>( p->child( "802.11 SSID" ) ); | ||
445 | QString essid = ssid ? ssid->ID() : QString("<unknown>"); | ||
446 | OWaveLanManagementDS* ds = static_cast<OWaveLanManagementDS*>( p->child( "802.11 DS" ) ); | ||
447 | int channel = ds ? ds->channel() : -1; | ||
448 | OWaveLanPacket* header = static_cast<OWaveLanPacket*>( p->child( "802.11" ) ); | ||
449 | displayFoundNetwork( type, channel, essid, header->macAddress2() ); | ||
450 | } | ||
451 | } | ||
452 | |||
453 | |||
454 | void WLANImp::displayFoundNetwork( const QString& mode, int channel, const QString& ssid, const OMacAddress& mac ) | ||
455 | { | ||
456 | |||
457 | qDebug( "found network: <%s>, chn %d, ssid '%s', mac '%s'", (const char*) mode, channel, | ||
458 | (const char*) ssid, | ||
459 | (const char*) mac.toString() ); | ||
460 | |||
461 | QListViewItemIterator it( netView ); | ||
462 | while ( it.current() && it.current()->text( col_ssid ) != ssid ) ++it; | ||
463 | if ( !it.current() ) // ssid didn't show up yet | ||
464 | { | ||
465 | QListViewItem* item = new QListViewItem( netView, mode.left( 1 ).upper(), ssid, QString::number( channel ), mac.toString() ); | ||
466 | QString name; | ||
467 | name.sprintf( "networksettings/%s", (const char*) mode ); | ||
468 | item->setPixmap( col_mode, Resource::loadPixmap( name ) ); | ||
469 | qApp->processEvents(); | ||
470 | } | ||
471 | |||
472 | } | ||
473 | |||
474 | |||
475 | void WLANImp::selectNetwork( QListViewItem* item ) | ||
476 | { | ||
477 | bool ok; | ||
478 | if ( item ) | ||
479 | { | ||
480 | specifyAp->setChecked(true); | ||
481 | macEdit->setText( item->text( col_mac ) ); | ||
482 | specifyChan->setChecked( item->text( col_mode ) == "A" ); | ||
483 | networkChannel->setValue( item->text( col_chn ).toInt( &ok ) ); | ||
484 | essid->setEditText( item->text( col_ssid ) ); | ||
485 | if ( item->text( col_mode ) == "A" ) | ||
486 | mode->setCurrentItem( 3 ); | ||
487 | else | ||
488 | mode->setCurrentItem( 2 ); | ||
489 | } | ||
490 | } | ||